OLD | NEW |
| (Empty) |
1 // Copyright 2014 PDFium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | |
6 | |
7 #include "xfa/fxfa/parser/xfa_script_resolveprocessor.h" | |
8 | |
9 #include "core/fxcrt/include/fx_ext.h" | |
10 #include "xfa/fxfa/parser/xfa_doclayout.h" | |
11 #include "xfa/fxfa/parser/xfa_document.h" | |
12 #include "xfa/fxfa/parser/xfa_localemgr.h" | |
13 #include "xfa/fxfa/parser/xfa_object.h" | |
14 #include "xfa/fxfa/parser/xfa_script.h" | |
15 #include "xfa/fxfa/parser/xfa_script_imp.h" | |
16 #include "xfa/fxfa/parser/xfa_script_nodehelper.h" | |
17 #include "xfa/fxfa/parser/xfa_utils.h" | |
18 | |
19 CXFA_ResolveProcessor::CXFA_ResolveProcessor() | |
20 : m_iCurStart(0), m_pNodeHelper(new CXFA_NodeHelper) {} | |
21 | |
22 CXFA_ResolveProcessor::~CXFA_ResolveProcessor() { | |
23 delete m_pNodeHelper; | |
24 } | |
25 | |
26 int32_t CXFA_ResolveProcessor::Resolve(CXFA_ResolveNodesData& rnd) { | |
27 if (!rnd.m_CurNode) { | |
28 return -1; | |
29 } | |
30 if (!rnd.m_CurNode->IsNode()) { | |
31 if (rnd.m_dwStyles & XFA_RESOLVENODE_Attributes) { | |
32 return ResolveForAttributeRs(rnd.m_CurNode, rnd, | |
33 rnd.m_wsName.AsStringC()); | |
34 } | |
35 return 0; | |
36 } | |
37 if (rnd.m_dwStyles & XFA_RESOLVENODE_AnyChild) { | |
38 return ResolveAnyChild(rnd); | |
39 } | |
40 FX_WCHAR wch = rnd.m_wsName.GetAt(0); | |
41 switch (wch) { | |
42 case '$': | |
43 return ResolveDollar(rnd); | |
44 case '!': | |
45 return ResolveExcalmatory(rnd); | |
46 case '#': | |
47 return ResolveNumberSign(rnd); | |
48 case '*': | |
49 return ResolveAsterisk(rnd); | |
50 // TODO(dsinclair): We could probably remove this. | |
51 case '.': | |
52 return ResolveAnyChild(rnd); | |
53 default: | |
54 break; | |
55 } | |
56 if (rnd.m_uHashName == XFA_HASHCODE_This && rnd.m_nLevel == 0) { | |
57 rnd.m_Nodes.Add(rnd.m_pSC->GetThisObject()); | |
58 return 1; | |
59 } else if (rnd.m_CurNode->GetElementType() == XFA_Element::Xfa) { | |
60 CXFA_Object* pObjNode = | |
61 rnd.m_pSC->GetDocument()->GetXFAObject(rnd.m_uHashName); | |
62 if (pObjNode) { | |
63 rnd.m_Nodes.Add(pObjNode); | |
64 } else if (rnd.m_uHashName == XFA_HASHCODE_Xfa) { | |
65 rnd.m_Nodes.Add(rnd.m_CurNode); | |
66 } else if ((rnd.m_dwStyles & XFA_RESOLVENODE_Attributes) && | |
67 ResolveForAttributeRs(rnd.m_CurNode, rnd, | |
68 rnd.m_wsName.AsStringC())) { | |
69 return 1; | |
70 } | |
71 if (rnd.m_Nodes.GetSize() > 0) { | |
72 FilterCondition(rnd, rnd.m_wsCondition); | |
73 } | |
74 return rnd.m_Nodes.GetSize(); | |
75 } | |
76 int32_t nRet = ResolveNormal(rnd); | |
77 if (nRet < 1 && rnd.m_uHashName == XFA_HASHCODE_Xfa) { | |
78 rnd.m_Nodes.Add(rnd.m_pSC->GetDocument()->GetRoot()); | |
79 } | |
80 return rnd.m_Nodes.GetSize(); | |
81 } | |
82 int32_t CXFA_ResolveProcessor::ResolveAnyChild(CXFA_ResolveNodesData& rnd) { | |
83 CFX_WideString wsName = rnd.m_wsName; | |
84 CFX_WideString wsCondition = rnd.m_wsCondition; | |
85 CXFA_Node* findNode = nullptr; | |
86 CXFA_NodeArray siblings; | |
87 FX_BOOL bClassName = FALSE; | |
88 if (wsName.GetAt(0) == '#') { | |
89 bClassName = TRUE; | |
90 wsName = wsName.Right(wsName.GetLength() - 1); | |
91 } | |
92 findNode = m_pNodeHelper->ResolveNodes_GetOneChild( | |
93 ToNode(rnd.m_CurNode), wsName.c_str(), bClassName); | |
94 if (!findNode) { | |
95 return 0; | |
96 } | |
97 if (wsCondition.IsEmpty()) { | |
98 rnd.m_Nodes.Add(findNode); | |
99 return rnd.m_Nodes.GetSize(); | |
100 } | |
101 m_pNodeHelper->CountSiblings(findNode, XFA_LOGIC_Transparent, | |
102 (CXFA_NodeArray*)&rnd.m_Nodes, bClassName); | |
103 FilterCondition(rnd, wsCondition); | |
104 return rnd.m_Nodes.GetSize(); | |
105 } | |
106 int32_t CXFA_ResolveProcessor::ResolveDollar(CXFA_ResolveNodesData& rnd) { | |
107 CXFA_ObjArray& nodes = rnd.m_Nodes; | |
108 CFX_WideString wsName = rnd.m_wsName; | |
109 CFX_WideString wsCondition = rnd.m_wsCondition; | |
110 int32_t iNameLen = wsName.GetLength(); | |
111 if (iNameLen == 1) { | |
112 nodes.Add(rnd.m_CurNode); | |
113 return 1; | |
114 } | |
115 if (rnd.m_nLevel > 0) { | |
116 return -1; | |
117 } | |
118 XFA_HashCode dwNameHash = static_cast<XFA_HashCode>(FX_HashCode_GetW( | |
119 CFX_WideStringC(wsName.c_str() + 1, iNameLen - 1), false)); | |
120 if (dwNameHash == XFA_HASHCODE_Xfa) { | |
121 nodes.Add(rnd.m_pSC->GetDocument()->GetRoot()); | |
122 } else { | |
123 CXFA_Object* pObjNode = rnd.m_pSC->GetDocument()->GetXFAObject(dwNameHash); | |
124 if (pObjNode) { | |
125 rnd.m_Nodes.Add(pObjNode); | |
126 } | |
127 } | |
128 if (rnd.m_Nodes.GetSize() > 0) { | |
129 FilterCondition(rnd, wsCondition); | |
130 } | |
131 return rnd.m_Nodes.GetSize(); | |
132 } | |
133 int32_t CXFA_ResolveProcessor::ResolveExcalmatory(CXFA_ResolveNodesData& rnd) { | |
134 if (rnd.m_nLevel > 0) { | |
135 return 0; | |
136 } | |
137 CXFA_Node* datasets = | |
138 ToNode(rnd.m_pSC->GetDocument()->GetXFAObject(XFA_HASHCODE_Datasets)); | |
139 if (!datasets) { | |
140 return 0; | |
141 } | |
142 CXFA_ResolveNodesData rndFind; | |
143 rndFind.m_pSC = rnd.m_pSC; | |
144 rndFind.m_CurNode = datasets; | |
145 rndFind.m_wsName = rnd.m_wsName.Right(rnd.m_wsName.GetLength() - 1); | |
146 rndFind.m_uHashName = static_cast<XFA_HashCode>( | |
147 FX_HashCode_GetW(rndFind.m_wsName.AsStringC(), false)); | |
148 rndFind.m_nLevel = rnd.m_nLevel + 1; | |
149 rndFind.m_dwStyles = XFA_RESOLVENODE_Children; | |
150 rndFind.m_wsCondition = rnd.m_wsCondition; | |
151 Resolve(rndFind); | |
152 if (rndFind.m_Nodes.GetSize() > 0) { | |
153 rnd.m_Nodes.Append(rndFind.m_Nodes); | |
154 rndFind.m_Nodes.RemoveAll(); | |
155 } | |
156 return rnd.m_Nodes.GetSize(); | |
157 } | |
158 int32_t CXFA_ResolveProcessor::ResolveNumberSign(CXFA_ResolveNodesData& rnd) { | |
159 CFX_WideString wsName = rnd.m_wsName.Right(rnd.m_wsName.GetLength() - 1); | |
160 CFX_WideString wsCondition = rnd.m_wsCondition; | |
161 CXFA_Node* curNode = ToNode(rnd.m_CurNode); | |
162 if (ResolveForAttributeRs(curNode, rnd, wsName.AsStringC())) { | |
163 return 1; | |
164 } | |
165 CXFA_ResolveNodesData rndFind; | |
166 rndFind.m_pSC = rnd.m_pSC; | |
167 rndFind.m_nLevel = rnd.m_nLevel + 1; | |
168 rndFind.m_dwStyles = rnd.m_dwStyles; | |
169 rndFind.m_dwStyles |= XFA_RESOLVENODE_TagName; | |
170 rndFind.m_dwStyles &= ~XFA_RESOLVENODE_Attributes; | |
171 rndFind.m_wsName = wsName; | |
172 rndFind.m_uHashName = static_cast<XFA_HashCode>( | |
173 FX_HashCode_GetW(rndFind.m_wsName.AsStringC(), false)); | |
174 rndFind.m_wsCondition = wsCondition; | |
175 rndFind.m_CurNode = curNode; | |
176 ResolveNormal(rndFind); | |
177 if (rndFind.m_Nodes.GetSize() > 0) { | |
178 if (wsCondition.GetLength() == 0 && rndFind.m_Nodes.Find(curNode) >= 0) { | |
179 rnd.m_Nodes.Add(curNode); | |
180 } else { | |
181 rnd.m_Nodes.Append(rndFind.m_Nodes); | |
182 rndFind.m_Nodes.RemoveAll(); | |
183 } | |
184 } | |
185 return rnd.m_Nodes.GetSize(); | |
186 } | |
187 int32_t CXFA_ResolveProcessor::ResolveForAttributeRs( | |
188 CXFA_Object* curNode, | |
189 CXFA_ResolveNodesData& rnd, | |
190 const CFX_WideStringC& strAttr) { | |
191 const XFA_SCRIPTATTRIBUTEINFO* lpScriptAttribute = | |
192 XFA_GetScriptAttributeByName(curNode->GetElementType(), strAttr); | |
193 if (lpScriptAttribute) { | |
194 rnd.m_pScriptAttribute = lpScriptAttribute; | |
195 rnd.m_Nodes.Add(curNode); | |
196 rnd.m_dwFlag = XFA_RESOVENODE_RSTYPE_Attribute; | |
197 return 1; | |
198 } | |
199 return 0; | |
200 } | |
201 int32_t CXFA_ResolveProcessor::ResolveNormal(CXFA_ResolveNodesData& rnd) { | |
202 if (rnd.m_nLevel > 32) { | |
203 return 0; | |
204 } | |
205 if (!rnd.m_CurNode->IsNode()) { | |
206 return 0; | |
207 } | |
208 CXFA_Node* curNode = ToNode(rnd.m_CurNode); | |
209 CXFA_ObjArray& nodes = rnd.m_Nodes; | |
210 int32_t nNum = nodes.GetSize(); | |
211 uint32_t dwStyles = rnd.m_dwStyles; | |
212 CFX_WideString& wsName = rnd.m_wsName; | |
213 XFA_HashCode uNameHash = rnd.m_uHashName; | |
214 CFX_WideString& wsCondition = rnd.m_wsCondition; | |
215 CXFA_ResolveNodesData rndFind; | |
216 rndFind.m_wsName = rnd.m_wsName; | |
217 rndFind.m_wsCondition = rnd.m_wsCondition; | |
218 rndFind.m_pSC = rnd.m_pSC; | |
219 rndFind.m_nLevel = rnd.m_nLevel + 1; | |
220 rndFind.m_uHashName = uNameHash; | |
221 CXFA_NodeArray children; | |
222 CXFA_NodeArray properties; | |
223 CXFA_Node* pVariablesNode = nullptr; | |
224 CXFA_Node* pPageSetNode = nullptr; | |
225 CXFA_Node* pChild = curNode->GetNodeItem(XFA_NODEITEM_FirstChild); | |
226 while (pChild) { | |
227 if (pChild->GetElementType() == XFA_Element::Variables) { | |
228 pVariablesNode = pChild; | |
229 pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling); | |
230 continue; | |
231 } else if (pChild->GetElementType() == XFA_Element::PageSet) { | |
232 pPageSetNode = pChild; | |
233 pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling); | |
234 continue; | |
235 } else { | |
236 const XFA_PROPERTY* pPropert = XFA_GetPropertyOfElement( | |
237 curNode->GetElementType(), pChild->GetElementType(), | |
238 XFA_XDPPACKET_UNKNOWN); | |
239 if (pPropert) { | |
240 properties.Add(pChild); | |
241 } else { | |
242 children.Add(pChild); | |
243 } | |
244 } | |
245 pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling); | |
246 } | |
247 if ((dwStyles & XFA_RESOLVENODE_Properties) && pVariablesNode) { | |
248 uint32_t uPropHash = pVariablesNode->GetClassHashCode(); | |
249 if (uPropHash == uNameHash) { | |
250 nodes.Add(pVariablesNode); | |
251 } else { | |
252 rndFind.m_CurNode = pVariablesNode; | |
253 SetStylesForChild(dwStyles, rndFind); | |
254 CFX_WideString wsSaveCondition = rndFind.m_wsCondition; | |
255 rndFind.m_wsCondition.clear(); | |
256 ResolveNormal(rndFind); | |
257 rndFind.m_wsCondition = wsSaveCondition; | |
258 if (rndFind.m_Nodes.GetSize() > 0) { | |
259 nodes.Append(rndFind.m_Nodes); | |
260 rndFind.m_Nodes.RemoveAll(); | |
261 } | |
262 } | |
263 if (nodes.GetSize() > nNum) { | |
264 FilterCondition(rnd, wsCondition); | |
265 if (nodes.GetSize() > 0) { | |
266 return 1; | |
267 } | |
268 return 0; | |
269 } | |
270 } | |
271 if (dwStyles & XFA_RESOLVENODE_Children) { | |
272 FX_BOOL bSetFlag = FALSE; | |
273 if (pPageSetNode && (dwStyles & XFA_RESOLVENODE_Properties)) { | |
274 children.Add(pPageSetNode); | |
275 } | |
276 for (int32_t i = 0; i < children.GetSize(); i++) { | |
277 CXFA_Node* child = children[i]; | |
278 if (dwStyles & XFA_RESOLVENODE_TagName) { | |
279 if (child->GetClassHashCode() == uNameHash) { | |
280 nodes.Add(child); | |
281 } | |
282 } else if (child->GetNameHash() == uNameHash) { | |
283 nodes.Add(child); | |
284 } | |
285 if (m_pNodeHelper->NodeIsTransparent(child) && | |
286 child->GetElementType() != XFA_Element::PageSet) { | |
287 if (!bSetFlag) { | |
288 SetStylesForChild(dwStyles, rndFind); | |
289 bSetFlag = TRUE; | |
290 } | |
291 rndFind.m_CurNode = child; | |
292 CFX_WideString wsSaveCondition = rndFind.m_wsCondition; | |
293 rndFind.m_wsCondition.clear(); | |
294 ResolveNormal(rndFind); | |
295 rndFind.m_wsCondition = wsSaveCondition; | |
296 if (rndFind.m_Nodes.GetSize() > 0) { | |
297 nodes.Append(rndFind.m_Nodes); | |
298 rndFind.m_Nodes.RemoveAll(); | |
299 } | |
300 } | |
301 } | |
302 if (nodes.GetSize() > nNum) { | |
303 if (!(dwStyles & XFA_RESOLVENODE_ALL)) { | |
304 CXFA_NodeArray upArrayNodes; | |
305 if (m_pNodeHelper->NodeIsTransparent(ToNode(curNode))) { | |
306 m_pNodeHelper->CountSiblings(ToNode(nodes[0]), XFA_LOGIC_Transparent, | |
307 &upArrayNodes, | |
308 !!(dwStyles & XFA_RESOLVENODE_TagName)); | |
309 } | |
310 if (upArrayNodes.GetSize() > nodes.GetSize()) { | |
311 upArrayNodes[0] = ToNode(nodes[0]); | |
312 nodes.RemoveAll(); | |
313 nodes.Append((CXFA_ObjArray&)upArrayNodes); | |
314 upArrayNodes.RemoveAll(); | |
315 } | |
316 } | |
317 FilterCondition(rnd, wsCondition); | |
318 if (nodes.GetSize() > 0) { | |
319 return 1; | |
320 } | |
321 return 0; | |
322 } | |
323 } | |
324 if (dwStyles & XFA_RESOLVENODE_Attributes) { | |
325 if (ResolveForAttributeRs(curNode, rnd, wsName.AsStringC())) { | |
326 return 1; | |
327 } | |
328 } | |
329 if (dwStyles & XFA_RESOLVENODE_Properties) { | |
330 for (int32_t i = 0; i < properties.GetSize(); i++) { | |
331 CXFA_Node* childProperty = properties[i]; | |
332 if (childProperty->IsUnnamed()) { | |
333 uint32_t uPropHash = childProperty->GetClassHashCode(); | |
334 if (uPropHash == uNameHash) { | |
335 nodes.Add(childProperty); | |
336 } | |
337 } else if (childProperty->GetNameHash() == uNameHash && | |
338 childProperty->GetElementType() != XFA_Element::Extras && | |
339 childProperty->GetElementType() != XFA_Element::Items) { | |
340 nodes.Add(childProperty); | |
341 } | |
342 } | |
343 if (nodes.GetSize() > nNum) { | |
344 FilterCondition(rnd, wsCondition); | |
345 if (nodes.GetSize() > 0) { | |
346 return 1; | |
347 } | |
348 return 0; | |
349 } | |
350 CXFA_Node* pProp = nullptr; | |
351 if (XFA_Element::Subform == curNode->GetElementType() && | |
352 XFA_HASHCODE_Occur == uNameHash) { | |
353 CXFA_Node* pInstanceManager = | |
354 curNode->AsNode()->GetInstanceMgrOfSubform(); | |
355 if (pInstanceManager) { | |
356 pProp = pInstanceManager->GetProperty(0, XFA_Element::Occur, TRUE); | |
357 } | |
358 } else { | |
359 XFA_Element eType = XFA_GetElementTypeForName(wsName.AsStringC()); | |
360 if (eType != XFA_Element::Unknown) { | |
361 pProp = curNode->AsNode()->GetProperty(0, eType, | |
362 eType != XFA_Element::PageSet); | |
363 } | |
364 } | |
365 if (pProp) { | |
366 nodes.Add(pProp); | |
367 return nodes.GetSize(); | |
368 } | |
369 } | |
370 CXFA_Node* parentNode = m_pNodeHelper->ResolveNodes_GetParent( | |
371 curNode->AsNode(), XFA_LOGIC_NoTransparent); | |
372 uint32_t uCurClassHash = curNode->GetClassHashCode(); | |
373 if (!parentNode) { | |
374 if (uCurClassHash == uNameHash) { | |
375 nodes.Add(curNode->AsNode()); | |
376 FilterCondition(rnd, wsCondition); | |
377 if (nodes.GetSize() > 0) { | |
378 return 1; | |
379 } | |
380 } | |
381 return 0; | |
382 } | |
383 if (dwStyles & XFA_RESOLVENODE_Siblings) { | |
384 CXFA_Node* child = parentNode->GetNodeItem(XFA_NODEITEM_FirstChild); | |
385 uint32_t dwSubStyles = | |
386 XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties; | |
387 if (dwStyles & XFA_RESOLVENODE_TagName) { | |
388 dwSubStyles |= XFA_RESOLVENODE_TagName; | |
389 } | |
390 if (dwStyles & XFA_RESOLVENODE_ALL) { | |
391 dwSubStyles |= XFA_RESOLVENODE_ALL; | |
392 } | |
393 rndFind.m_dwStyles = dwSubStyles; | |
394 while (child) { | |
395 if (child == curNode) { | |
396 if (dwStyles & XFA_RESOLVENODE_TagName) { | |
397 if (uCurClassHash == uNameHash) { | |
398 nodes.Add(curNode); | |
399 } | |
400 } else { | |
401 if (child->GetNameHash() == uNameHash) { | |
402 nodes.Add(curNode); | |
403 if (rnd.m_nLevel == 0 && wsCondition.GetLength() == 0) { | |
404 nodes.RemoveAll(); | |
405 nodes.Add(curNode); | |
406 return 1; | |
407 } | |
408 } | |
409 } | |
410 child = child->GetNodeItem(XFA_NODEITEM_NextSibling); | |
411 continue; | |
412 } | |
413 if (dwStyles & XFA_RESOLVENODE_TagName) { | |
414 if (child->GetClassHashCode() == uNameHash) { | |
415 nodes.Add(child); | |
416 } | |
417 } else if (child->GetNameHash() == uNameHash) { | |
418 nodes.Add(child); | |
419 } | |
420 const XFA_PROPERTY* pPropert = XFA_GetPropertyOfElement( | |
421 parentNode->GetElementType(), child->GetElementType(), | |
422 XFA_XDPPACKET_UNKNOWN); | |
423 FX_BOOL bInnerSearch = FALSE; | |
424 if (pPropert) { | |
425 if ((child->GetElementType() == XFA_Element::Variables || | |
426 child->GetElementType() == XFA_Element::PageSet)) { | |
427 bInnerSearch = TRUE; | |
428 } | |
429 } else { | |
430 if (m_pNodeHelper->NodeIsTransparent(child)) { | |
431 bInnerSearch = TRUE; | |
432 } | |
433 } | |
434 if (bInnerSearch) { | |
435 rndFind.m_CurNode = child; | |
436 CFX_WideString wsOriginCondition = rndFind.m_wsCondition; | |
437 rndFind.m_wsCondition.clear(); | |
438 uint32_t dwOriginStyle = rndFind.m_dwStyles; | |
439 rndFind.m_dwStyles = dwOriginStyle | XFA_RESOLVENODE_ALL; | |
440 ResolveNormal(rndFind); | |
441 rndFind.m_dwStyles = dwOriginStyle; | |
442 rndFind.m_wsCondition = wsOriginCondition; | |
443 if (rndFind.m_Nodes.GetSize() > 0) { | |
444 nodes.Append(rndFind.m_Nodes); | |
445 rndFind.m_Nodes.RemoveAll(); | |
446 } | |
447 } | |
448 child = child->GetNodeItem(XFA_NODEITEM_NextSibling); | |
449 } | |
450 if (nodes.GetSize() > nNum) { | |
451 if (m_pNodeHelper->NodeIsTransparent(parentNode)) { | |
452 CXFA_NodeArray upArrayNodes; | |
453 m_pNodeHelper->CountSiblings(ToNode(nodes[0]), XFA_LOGIC_Transparent, | |
454 &upArrayNodes, | |
455 !!(dwStyles & XFA_RESOLVENODE_TagName)); | |
456 if (upArrayNodes.GetSize() > nodes.GetSize()) { | |
457 upArrayNodes[0] = ToNode(nodes[0]); | |
458 nodes.RemoveAll(); | |
459 nodes.Append((CXFA_ObjArray&)upArrayNodes); | |
460 upArrayNodes.RemoveAll(); | |
461 } | |
462 } | |
463 FilterCondition(rnd, wsCondition); | |
464 if (nodes.GetSize() > 0) { | |
465 return 1; | |
466 } | |
467 return 0; | |
468 } | |
469 } | |
470 if (dwStyles & XFA_RESOLVENODE_Parent) { | |
471 uint32_t dwSubStyles = XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent | | |
472 XFA_RESOLVENODE_Properties; | |
473 if (dwStyles & XFA_RESOLVENODE_TagName) { | |
474 dwSubStyles |= XFA_RESOLVENODE_TagName; | |
475 } | |
476 if (dwStyles & XFA_RESOLVENODE_ALL) { | |
477 dwSubStyles |= XFA_RESOLVENODE_ALL; | |
478 } | |
479 rndFind.m_dwStyles = dwSubStyles; | |
480 rndFind.m_CurNode = parentNode; | |
481 CXFA_NodeArray& array = rnd.m_pSC->GetUpObjectArray(); | |
482 array.Add(parentNode); | |
483 ResolveNormal(rndFind); | |
484 if (rndFind.m_Nodes.GetSize() > 0) { | |
485 nodes.Append(rndFind.m_Nodes); | |
486 rndFind.m_Nodes.RemoveAll(); | |
487 } | |
488 if (nodes.GetSize() > nNum) { | |
489 return 1; | |
490 } | |
491 } | |
492 return 0; | |
493 } | |
494 int32_t CXFA_ResolveProcessor::ResolveAsterisk(CXFA_ResolveNodesData& rnd) { | |
495 CXFA_Node* curNode = ToNode(rnd.m_CurNode); | |
496 CXFA_ObjArray& nodes = rnd.m_Nodes; | |
497 CXFA_NodeArray array; | |
498 curNode->GetNodeList(array, | |
499 XFA_NODEFILTER_Children | XFA_NODEFILTER_Properties); | |
500 nodes.Append((CXFA_ObjArray&)array); | |
501 return nodes.GetSize(); | |
502 } | |
503 int32_t CXFA_ResolveProcessor::ResolvePopStack(CFX_Int32Array& stack) { | |
504 int32_t nType = -1; | |
505 int32_t iSize = stack.GetSize() - 1; | |
506 if (iSize > -1) { | |
507 nType = stack[iSize]; | |
508 stack.RemoveAt(iSize, 1); | |
509 } | |
510 return nType; | |
511 } | |
512 int32_t CXFA_ResolveProcessor::GetFilter(const CFX_WideStringC& wsExpression, | |
513 int32_t nStart, | |
514 CXFA_ResolveNodesData& rnd) { | |
515 ASSERT(nStart > -1); | |
516 int32_t iLength = wsExpression.GetLength(); | |
517 if (nStart >= iLength) { | |
518 return 0; | |
519 } | |
520 CFX_WideString& wsName = rnd.m_wsName; | |
521 CFX_WideString& wsCondition = rnd.m_wsCondition; | |
522 FX_WCHAR* pNameBuf = wsName.GetBuffer(iLength - nStart); | |
523 FX_WCHAR* pConditionBuf = wsCondition.GetBuffer(iLength - nStart); | |
524 int32_t nNameCount = 0; | |
525 int32_t nConditionCount = 0; | |
526 CFX_Int32Array stack; | |
527 int32_t nType = -1; | |
528 const FX_WCHAR* pSrc = wsExpression.c_str(); | |
529 FX_WCHAR wPrev = 0, wCur; | |
530 FX_BOOL bIsCondition = FALSE; | |
531 while (nStart < iLength) { | |
532 wCur = pSrc[nStart++]; | |
533 if (wCur == '.') { | |
534 if (wPrev == '\\') { | |
535 pNameBuf[nNameCount - 1] = wPrev = '.'; | |
536 continue; | |
537 } | |
538 if (nNameCount == 0) { | |
539 rnd.m_dwStyles |= XFA_RESOLVENODE_AnyChild; | |
540 continue; | |
541 } | |
542 FX_WCHAR wLookahead = nStart < iLength ? pSrc[nStart] : 0; | |
543 if (wLookahead != '[' && wLookahead != '(') { | |
544 if (nType < 0) { | |
545 break; | |
546 } | |
547 } | |
548 } | |
549 if (wCur == '[' || wCur == '(') { | |
550 bIsCondition = TRUE; | |
551 } else if (wCur == '.' && nStart < iLength && | |
552 (pSrc[nStart] == '[' || pSrc[nStart] == '(')) { | |
553 bIsCondition = TRUE; | |
554 } | |
555 if (bIsCondition) { | |
556 pConditionBuf[nConditionCount++] = wCur; | |
557 } else { | |
558 pNameBuf[nNameCount++] = wCur; | |
559 } | |
560 FX_BOOL bRecursive = TRUE; | |
561 switch (nType) { | |
562 case 0: | |
563 if (wCur == ']') { | |
564 nType = ResolvePopStack(stack); | |
565 bRecursive = FALSE; | |
566 } | |
567 break; | |
568 case 1: | |
569 if (wCur == ')') { | |
570 nType = ResolvePopStack(stack); | |
571 bRecursive = FALSE; | |
572 } | |
573 break; | |
574 case 2: | |
575 if (wCur == '"') { | |
576 nType = ResolvePopStack(stack); | |
577 bRecursive = FALSE; | |
578 } | |
579 break; | |
580 } | |
581 if (bRecursive) { | |
582 switch (wCur) { | |
583 case '[': | |
584 stack.Add(nType); | |
585 nType = 0; | |
586 break; | |
587 case '(': | |
588 stack.Add(nType); | |
589 nType = 1; | |
590 break; | |
591 case '"': | |
592 stack.Add(nType); | |
593 nType = 2; | |
594 break; | |
595 } | |
596 } | |
597 wPrev = wCur; | |
598 } | |
599 if (stack.GetSize() > 0) { | |
600 return -1; | |
601 } | |
602 wsName.ReleaseBuffer(nNameCount); | |
603 wsName.TrimLeft(); | |
604 wsName.TrimRight(); | |
605 wsCondition.ReleaseBuffer(nConditionCount); | |
606 wsCondition.TrimLeft(); | |
607 wsCondition.TrimRight(); | |
608 rnd.m_uHashName = | |
609 static_cast<XFA_HashCode>(FX_HashCode_GetW(wsName.AsStringC(), false)); | |
610 return nStart; | |
611 } | |
612 void CXFA_ResolveProcessor::ConditionArray(int32_t iCurIndex, | |
613 CFX_WideString wsCondition, | |
614 int32_t iFoundCount, | |
615 CXFA_ResolveNodesData& rnd) { | |
616 CXFA_NodeArray& findNodes = (CXFA_NodeArray&)rnd.m_Nodes; | |
617 int32_t iLen = wsCondition.GetLength(); | |
618 FX_BOOL bRelative = FALSE; | |
619 FX_BOOL bAll = FALSE; | |
620 int32_t i = 1; | |
621 for (; i < iLen; ++i) { | |
622 FX_WCHAR ch = wsCondition[i]; | |
623 if (ch == ' ') { | |
624 continue; | |
625 } | |
626 if (ch == '+' || ch == '-') { | |
627 bRelative = TRUE; | |
628 break; | |
629 } else if (ch == '*') { | |
630 bAll = TRUE; | |
631 break; | |
632 } else { | |
633 break; | |
634 } | |
635 } | |
636 if (bAll) { | |
637 if (rnd.m_dwStyles & XFA_RESOLVENODE_CreateNode) { | |
638 if (rnd.m_dwStyles & XFA_RESOLVENODE_Bind) { | |
639 m_pNodeHelper->m_pCreateParent = ToNode(rnd.m_CurNode); | |
640 m_pNodeHelper->m_iCreateCount = 1; | |
641 findNodes.RemoveAll(); | |
642 m_pNodeHelper->m_iCurAllStart = -1; | |
643 m_pNodeHelper->m_pAllStartParent = nullptr; | |
644 } else { | |
645 if (m_pNodeHelper->m_iCurAllStart == -1) { | |
646 m_pNodeHelper->m_iCurAllStart = m_iCurStart; | |
647 m_pNodeHelper->m_pAllStartParent = ToNode(rnd.m_CurNode); | |
648 } | |
649 } | |
650 } else if (rnd.m_dwStyles & XFA_RESOLVENODE_BindNew) { | |
651 if (m_pNodeHelper->m_iCurAllStart == -1) { | |
652 m_pNodeHelper->m_iCurAllStart = m_iCurStart; | |
653 } | |
654 } | |
655 return; | |
656 } | |
657 if (iFoundCount == 1 && !iLen) { | |
658 return; | |
659 } | |
660 CFX_WideString wsIndex; | |
661 wsIndex = wsCondition.Mid(i, iLen - 1 - i); | |
662 int32_t iIndex = wsIndex.GetInteger(); | |
663 if (bRelative) { | |
664 iIndex += iCurIndex; | |
665 } | |
666 if (iFoundCount <= iIndex || iIndex < 0) { | |
667 if (rnd.m_dwStyles & XFA_RESOLVENODE_CreateNode) { | |
668 m_pNodeHelper->m_pCreateParent = ToNode(rnd.m_CurNode); | |
669 m_pNodeHelper->m_iCreateCount = iIndex - iFoundCount + 1; | |
670 } | |
671 findNodes.RemoveAll(); | |
672 } else { | |
673 CXFA_Node* ret = findNodes[iIndex]; | |
674 findNodes.RemoveAll(); | |
675 findNodes.Add(ret); | |
676 } | |
677 } | |
678 void CXFA_ResolveProcessor::DoPredicateFilter(int32_t iCurIndex, | |
679 CFX_WideString wsCondition, | |
680 int32_t iFoundCount, | |
681 CXFA_ResolveNodesData& rnd) { | |
682 CXFA_NodeArray& findNodes = (CXFA_NodeArray&)rnd.m_Nodes; | |
683 ASSERT(iFoundCount == findNodes.GetSize()); | |
684 CFX_WideString wsExpression; | |
685 XFA_SCRIPTLANGTYPE eLangType = XFA_SCRIPTLANGTYPE_Unkown; | |
686 if (wsCondition.Left(2) == FX_WSTRC(L".[") && | |
687 wsCondition.Right(1) == FX_WSTRC(L"]")) { | |
688 eLangType = XFA_SCRIPTLANGTYPE_Formcalc; | |
689 } else if (wsCondition.Left(2) == FX_WSTRC(L".(") && | |
690 wsCondition.Right(1) == FX_WSTRC(L")")) { | |
691 eLangType = XFA_SCRIPTLANGTYPE_Javascript; | |
692 } else { | |
693 return; | |
694 } | |
695 | |
696 CXFA_ScriptContext* pContext = rnd.m_pSC; | |
697 wsExpression = wsCondition.Mid(2, wsCondition.GetLength() - 3); | |
698 for (int32_t i = iFoundCount - 1; i >= 0; i--) { | |
699 CXFA_Object* node = findNodes[i]; | |
700 FX_BOOL bRet = FALSE; | |
701 std::unique_ptr<CFXJSE_Value> pRetValue( | |
702 new CFXJSE_Value(rnd.m_pSC->GetRuntime())); | |
703 bRet = pContext->RunScript(eLangType, wsExpression.AsStringC(), | |
704 pRetValue.get(), node); | |
705 if (!bRet || !pRetValue->ToBoolean()) | |
706 findNodes.RemoveAt(i); | |
707 } | |
708 } | |
709 | |
710 void CXFA_ResolveProcessor::FilterCondition(CXFA_ResolveNodesData& rnd, | |
711 CFX_WideString wsCondition) { | |
712 CXFA_NodeArray& findNodes = (CXFA_NodeArray&)rnd.m_Nodes; | |
713 int32_t iCurrIndex = 0; | |
714 const CXFA_NodeArray& array = rnd.m_pSC->GetUpObjectArray(); | |
715 int32_t iSize = array.GetSize(); | |
716 if (iSize) { | |
717 CXFA_Node* curNode = array[iSize - 1]; | |
718 FX_BOOL bIsProperty = m_pNodeHelper->NodeIsProperty(curNode); | |
719 if (curNode->IsUnnamed() || | |
720 (bIsProperty && curNode->GetElementType() != XFA_Element::PageSet)) { | |
721 iCurrIndex = m_pNodeHelper->GetIndex(curNode, XFA_LOGIC_Transparent, | |
722 bIsProperty, TRUE); | |
723 } else { | |
724 iCurrIndex = m_pNodeHelper->GetIndex(curNode, XFA_LOGIC_Transparent, | |
725 bIsProperty, FALSE); | |
726 } | |
727 } | |
728 int32_t iFoundCount = findNodes.GetSize(); | |
729 wsCondition.TrimLeft(); | |
730 wsCondition.TrimRight(); | |
731 int32_t iLen = wsCondition.GetLength(); | |
732 if (!iLen) { | |
733 if (rnd.m_dwStyles & XFA_RESOLVENODE_ALL) { | |
734 return; | |
735 } | |
736 if (iFoundCount == 1) { | |
737 return; | |
738 } | |
739 if (iFoundCount <= iCurrIndex) { | |
740 if (rnd.m_dwStyles & XFA_RESOLVENODE_CreateNode) { | |
741 m_pNodeHelper->m_pCreateParent = ToNode(rnd.m_CurNode); | |
742 m_pNodeHelper->m_iCreateCount = iCurrIndex - iFoundCount + 1; | |
743 } | |
744 findNodes.RemoveAll(); | |
745 return; | |
746 } else { | |
747 CXFA_Node* ret = findNodes[iCurrIndex]; | |
748 findNodes.RemoveAll(); | |
749 findNodes.Add(ret); | |
750 return; | |
751 } | |
752 } | |
753 FX_WCHAR wTypeChar = wsCondition[0]; | |
754 switch (wTypeChar) { | |
755 case '[': | |
756 ConditionArray(iCurrIndex, wsCondition, iFoundCount, rnd); | |
757 return; | |
758 case '(': | |
759 return; | |
760 case '"': | |
761 return; | |
762 case '.': | |
763 if (iLen > 1 && (wsCondition[1] == '[' || wsCondition[1] == '(')) { | |
764 DoPredicateFilter(iCurrIndex, wsCondition, iFoundCount, rnd); | |
765 } | |
766 default: | |
767 return; | |
768 } | |
769 } | |
770 void CXFA_ResolveProcessor::SetStylesForChild(uint32_t dwParentStyles, | |
771 CXFA_ResolveNodesData& rnd) { | |
772 uint32_t dwSubStyles = XFA_RESOLVENODE_Children; | |
773 if (dwParentStyles & XFA_RESOLVENODE_TagName) { | |
774 dwSubStyles |= XFA_RESOLVENODE_TagName; | |
775 } | |
776 dwSubStyles &= ~XFA_RESOLVENODE_Parent; | |
777 dwSubStyles &= ~XFA_RESOLVENODE_Siblings; | |
778 dwSubStyles &= ~XFA_RESOLVENODE_Properties; | |
779 dwSubStyles |= XFA_RESOLVENODE_ALL; | |
780 rnd.m_dwStyles = dwSubStyles; | |
781 } | |
782 int32_t CXFA_ResolveProcessor::SetResultCreateNode( | |
783 XFA_RESOLVENODE_RS& resolveNodeRS, | |
784 CFX_WideString& wsLastCondition) { | |
785 if (m_pNodeHelper->m_pCreateParent) { | |
786 resolveNodeRS.nodes.Add(m_pNodeHelper->m_pCreateParent); | |
787 } else { | |
788 m_pNodeHelper->CreateNode_ForCondition(wsLastCondition); | |
789 } | |
790 resolveNodeRS.dwFlags = m_pNodeHelper->m_iCreateFlag; | |
791 if (resolveNodeRS.dwFlags == XFA_RESOLVENODE_RSTYPE_CreateNodeOne) { | |
792 if (m_pNodeHelper->m_iCurAllStart != -1) { | |
793 resolveNodeRS.dwFlags = XFA_RESOLVENODE_RSTYPE_CreateNodeMidAll; | |
794 } | |
795 } | |
796 return resolveNodeRS.nodes.GetSize(); | |
797 } | |
798 void CXFA_ResolveProcessor::SetIndexDataBind(CFX_WideString& wsNextCondition, | |
799 int32_t& iIndex, | |
800 int32_t iCount) { | |
801 if (m_pNodeHelper->CreateNode_ForCondition(wsNextCondition)) { | |
802 if (m_pNodeHelper->m_eLastCreateType == XFA_Element::DataGroup) { | |
803 iIndex = 0; | |
804 } else { | |
805 iIndex = iCount - 1; | |
806 } | |
807 } else { | |
808 iIndex = iCount - 1; | |
809 } | |
810 } | |
811 | |
812 CXFA_ResolveNodesData::CXFA_ResolveNodesData(CXFA_ScriptContext* pSC) | |
813 : m_pSC(pSC), | |
814 m_CurNode(nullptr), | |
815 m_wsName(), | |
816 m_uHashName(XFA_HASHCODE_None), | |
817 m_wsCondition(), | |
818 m_nLevel(0), | |
819 m_Nodes(), | |
820 m_dwStyles(XFA_RESOLVENODE_Children), | |
821 m_pScriptAttribute(nullptr), | |
822 m_dwFlag(XFA_RESOVENODE_RSTYPE_Nodes) {} | |
823 | |
824 CXFA_ResolveNodesData::~CXFA_ResolveNodesData() { | |
825 m_Nodes.RemoveAll(); | |
826 } | |
OLD | NEW |