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_document_datamerger_imp.h"
8
9 #include <map>
10 #include <vector>
11
12 #include "core/fxcrt/fx_ext.h"
13 #include "third_party/base/stl_util.h"
14 #include "xfa/fde/xml/fde_xml_imp.h"
15 #include "xfa/fxfa/parser/cxfa_document.h"
16 #include "xfa/fxfa/parser/cxfa_layoutprocessor.h"
17 #include "xfa/fxfa/parser/cxfa_occur.h"
18 #include "xfa/fxfa/parser/cxfa_scriptcontext.h"
19 #include "xfa/fxfa/parser/xfa_localemgr.h"
20 #include "xfa/fxfa/parser/xfa_object.h"
21 #include "xfa/fxfa/parser/xfa_resolvenode_rs.h"
22 #include "xfa/fxfa/parser/xfa_utils.h"
23
24 namespace {
25
26 class CXFA_TraverseStrategy_DDGroup {
27 public:
GetFirstChild(CXFA_Node * pDDGroupNode)28 static CXFA_Node* GetFirstChild(CXFA_Node* pDDGroupNode) {
29 return pDDGroupNode->GetFirstChildByName(XFA_HASHCODE_Group);
30 }
GetNextSibling(CXFA_Node * pDDGroupNode)31 static CXFA_Node* GetNextSibling(CXFA_Node* pDDGroupNode) {
32 return pDDGroupNode->GetNextSameNameSibling(XFA_HASHCODE_Group);
33 }
GetParent(CXFA_Node * pDDGroupNode)34 static CXFA_Node* GetParent(CXFA_Node* pDDGroupNode) {
35 return pDDGroupNode->GetNodeItem(XFA_NODEITEM_Parent);
36 }
37 };
38
39 struct RecurseRecord {
40 CXFA_Node* pTemplateChild;
41 CXFA_Node* pDataChild;
42 };
43
GetOccurInfo(CXFA_Node * pOccurNode,int32_t & iMin,int32_t & iMax,int32_t & iInit)44 bool GetOccurInfo(CXFA_Node* pOccurNode,
45 int32_t& iMin,
46 int32_t& iMax,
47 int32_t& iInit) {
48 if (!pOccurNode)
49 return false;
50
51 CXFA_Occur occur(pOccurNode);
52 return occur.GetOccurInfo(iMin, iMax, iInit);
53 }
54
FormValueNode_CreateChild(CXFA_Node * pValueNode,XFA_Element iType)55 CXFA_Node* FormValueNode_CreateChild(CXFA_Node* pValueNode, XFA_Element iType) {
56 CXFA_Node* pChildNode = pValueNode->GetNodeItem(XFA_NODEITEM_FirstChild);
57 if (!pChildNode) {
58 if (iType == XFA_Element::Unknown)
59 return nullptr;
60 pChildNode = pValueNode->GetProperty(0, iType);
61 }
62 return pChildNode;
63 }
64
FormValueNode_MatchNoneCreateChild(CXFA_Node * pFormNode)65 void FormValueNode_MatchNoneCreateChild(CXFA_Node* pFormNode) {
66 CXFA_WidgetData* pWidgetData = pFormNode->GetWidgetData();
67 ASSERT(pWidgetData);
68 pWidgetData->GetUIType();
69 }
70
FormValueNode_SetChildContent(CXFA_Node * pValueNode,const CFX_WideString & wsContent,XFA_Element iType=XFA_Element::Unknown)71 bool FormValueNode_SetChildContent(CXFA_Node* pValueNode,
72 const CFX_WideString& wsContent,
73 XFA_Element iType = XFA_Element::Unknown) {
74 if (!pValueNode)
75 return false;
76
77 ASSERT(pValueNode->GetPacketID() == XFA_XDPPACKET_Form);
78 CXFA_Node* pChildNode = FormValueNode_CreateChild(pValueNode, iType);
79 if (!pChildNode)
80 return false;
81
82 switch (pChildNode->GetObjectType()) {
83 case XFA_ObjectType::ContentNode: {
84 CXFA_Node* pContentRawDataNode =
85 pChildNode->GetNodeItem(XFA_NODEITEM_FirstChild);
86 if (!pContentRawDataNode) {
87 XFA_Element element = XFA_Element::Sharptext;
88 if (pChildNode->GetElementType() == XFA_Element::ExData) {
89 CFX_WideString wsContentType;
90 pChildNode->GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType,
91 false);
92 if (wsContentType == L"text/html")
93 element = XFA_Element::SharpxHTML;
94 else if (wsContentType == L"text/xml")
95 element = XFA_Element::Sharpxml;
96 }
97 pContentRawDataNode = pChildNode->CreateSamePacketNode(element);
98 pChildNode->InsertChild(pContentRawDataNode);
99 }
100 pContentRawDataNode->SetCData(XFA_ATTRIBUTE_Value, wsContent);
101 break;
102 }
103 case XFA_ObjectType::NodeC:
104 case XFA_ObjectType::TextNode:
105 case XFA_ObjectType::NodeV: {
106 pChildNode->SetCData(XFA_ATTRIBUTE_Value, wsContent);
107 break;
108 }
109 default:
110 ASSERT(false);
111 break;
112 }
113 return true;
114 }
115
CreateDataBinding(CXFA_Node * pFormNode,CXFA_Node * pDataNode,bool bDataToForm)116 void CreateDataBinding(CXFA_Node* pFormNode,
117 CXFA_Node* pDataNode,
118 bool bDataToForm) {
119 pFormNode->SetObject(XFA_ATTRIBUTE_BindingNode, pDataNode);
120 pDataNode->AddBindItem(pFormNode);
121 XFA_Element eType = pFormNode->GetElementType();
122 if (eType != XFA_Element::Field && eType != XFA_Element::ExclGroup)
123 return;
124
125 CXFA_WidgetData* pWidgetData = pFormNode->GetWidgetData();
126 ASSERT(pWidgetData);
127 XFA_Element eUIType = pWidgetData->GetUIType();
128 CXFA_Value defValue(pFormNode->GetProperty(0, XFA_Element::Value));
129 if (!bDataToForm) {
130 CFX_WideString wsValue;
131 CFX_WideString wsFormattedValue;
132 switch (eUIType) {
133 case XFA_Element::ImageEdit: {
134 CXFA_Image image = defValue.GetImage();
135 CFX_WideString wsContentType;
136 CFX_WideString wsHref;
137 if (image) {
138 image.GetContent(wsValue);
139 image.GetContentType(wsContentType);
140 image.GetHref(wsHref);
141 }
142 CFDE_XMLElement* pXMLDataElement =
143 static_cast<CFDE_XMLElement*>(pDataNode->GetXMLMappingNode());
144 ASSERT(pXMLDataElement);
145 pWidgetData->GetFormatDataValue(wsValue, wsFormattedValue);
146 pDataNode->SetAttributeValue(wsValue, wsFormattedValue);
147 pDataNode->SetCData(XFA_ATTRIBUTE_ContentType, wsContentType);
148 if (!wsHref.IsEmpty())
149 pXMLDataElement->SetString(L"href", wsHref);
150
151 break;
152 }
153 case XFA_Element::ChoiceList:
154 defValue.GetChildValueContent(wsValue);
155 if (pWidgetData->GetChoiceListOpen() == XFA_ATTRIBUTEENUM_MultiSelect) {
156 std::vector<CFX_WideString> wsSelTextArray;
157 pWidgetData->GetSelectedItemsValue(wsSelTextArray);
158 int32_t iSize = pdfium::CollectionSize<int32_t>(wsSelTextArray);
159 if (iSize >= 1) {
160 CXFA_Node* pValue = nullptr;
161 for (int32_t i = 0; i < iSize; i++) {
162 pValue = pDataNode->CreateSamePacketNode(XFA_Element::DataValue);
163 pValue->SetCData(XFA_ATTRIBUTE_Name, L"value");
164 pValue->CreateXMLMappingNode();
165 pDataNode->InsertChild(pValue);
166 pValue->SetCData(XFA_ATTRIBUTE_Value, wsSelTextArray[i]);
167 }
168 } else {
169 CFDE_XMLNode* pXMLNode = pDataNode->GetXMLMappingNode();
170 ASSERT(pXMLNode->GetType() == FDE_XMLNODE_Element);
171 static_cast<CFDE_XMLElement*>(pXMLNode)->SetString(L"xfa:dataNode",
172 L"dataGroup");
173 }
174 } else if (!wsValue.IsEmpty()) {
175 pWidgetData->GetFormatDataValue(wsValue, wsFormattedValue);
176 pDataNode->SetAttributeValue(wsValue, wsFormattedValue);
177 }
178 break;
179 case XFA_Element::CheckButton:
180 defValue.GetChildValueContent(wsValue);
181 if (wsValue.IsEmpty())
182 break;
183
184 pWidgetData->GetFormatDataValue(wsValue, wsFormattedValue);
185 pDataNode->SetAttributeValue(wsValue, wsFormattedValue);
186 break;
187 case XFA_Element::ExclGroup: {
188 CXFA_Node* pChecked = nullptr;
189 CXFA_Node* pChild = pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild);
190 for (; pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
191 if (pChild->GetElementType() != XFA_Element::Field)
192 continue;
193
194 CXFA_Node* pValue = pChild->GetChild(0, XFA_Element::Value);
195 if (!pValue)
196 continue;
197
198 CXFA_Value valueChild(pValue);
199 valueChild.GetChildValueContent(wsValue);
200 if (wsValue.IsEmpty())
201 continue;
202
203 CXFA_Node* pItems = pChild->GetChild(0, XFA_Element::Items);
204 if (!pItems)
205 continue;
206
207 CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
208 if (!pText)
209 continue;
210
211 CFX_WideString wsContent;
212 if (pText->TryContent(wsContent) && (wsContent == wsValue)) {
213 pChecked = pChild;
214 wsFormattedValue = wsValue;
215 pDataNode->SetAttributeValue(wsValue, wsFormattedValue);
216 pFormNode->SetCData(XFA_ATTRIBUTE_Value, wsContent);
217 break;
218 }
219 }
220 if (!pChecked)
221 break;
222
223 pChild = pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild);
224 for (; pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
225 if (pChild == pChecked)
226 continue;
227 if (pChild->GetElementType() != XFA_Element::Field)
228 continue;
229
230 CXFA_Node* pValue = pChild->GetProperty(0, XFA_Element::Value);
231 CXFA_Node* pItems = pChild->GetChild(0, XFA_Element::Items);
232 CXFA_Node* pText =
233 pItems ? pItems->GetNodeItem(XFA_NODEITEM_FirstChild) : nullptr;
234 if (pText)
235 pText = pText->GetNodeItem(XFA_NODEITEM_NextSibling);
236
237 CFX_WideString wsContent;
238 if (pText)
239 pText->TryContent(wsContent);
240
241 FormValueNode_SetChildContent(pValue, wsContent, XFA_Element::Text);
242 }
243 break;
244 }
245 case XFA_Element::NumericEdit: {
246 defValue.GetChildValueContent(wsValue);
247 if (wsValue.IsEmpty())
248 break;
249
250 CFX_WideString wsOutput;
251 pWidgetData->NormalizeNumStr(wsValue, wsOutput);
252 wsValue = wsOutput;
253 pWidgetData->GetFormatDataValue(wsValue, wsFormattedValue);
254 pDataNode->SetAttributeValue(wsValue, wsFormattedValue);
255 CXFA_Node* pValue = pFormNode->GetProperty(0, XFA_Element::Value);
256 FormValueNode_SetChildContent(pValue, wsValue, XFA_Element::Float);
257 break;
258 }
259 default:
260 defValue.GetChildValueContent(wsValue);
261 if (wsValue.IsEmpty())
262 break;
263
264 pWidgetData->GetFormatDataValue(wsValue, wsFormattedValue);
265 pDataNode->SetAttributeValue(wsValue, wsFormattedValue);
266 break;
267 }
268 return;
269 }
270
271 CFX_WideString wsXMLValue;
272 pDataNode->TryContent(wsXMLValue);
273 CFX_WideString wsNormalizeValue;
274 pWidgetData->GetNormalizeDataValue(wsXMLValue, wsNormalizeValue);
275 pDataNode->SetAttributeValue(wsNormalizeValue, wsXMLValue);
276 switch (eUIType) {
277 case XFA_Element::ImageEdit: {
278 FormValueNode_SetChildContent(defValue.GetNode(), wsNormalizeValue,
279 XFA_Element::Image);
280 CXFA_Image image = defValue.GetImage();
281 if (image) {
282 CFDE_XMLElement* pXMLDataElement =
283 static_cast<CFDE_XMLElement*>(pDataNode->GetXMLMappingNode());
284 ASSERT(pXMLDataElement);
285 CFX_WideString wsContentType;
286 CFX_WideString wsHref;
287 pXMLDataElement->GetString(L"xfa:contentType", wsContentType);
288 if (!wsContentType.IsEmpty()) {
289 pDataNode->SetCData(XFA_ATTRIBUTE_ContentType, wsContentType);
290 image.SetContentType(wsContentType);
291 }
292 pXMLDataElement->GetString(L"href", wsHref);
293 if (!wsHref.IsEmpty())
294 image.SetHref(wsHref);
295 }
296 break;
297 }
298 case XFA_Element::ChoiceList:
299 if (pWidgetData->GetChoiceListOpen() == XFA_ATTRIBUTEENUM_MultiSelect) {
300 CXFA_NodeArray items;
301 pDataNode->GetNodeList(items);
302 int32_t iCounts = items.GetSize();
303 if (iCounts > 0) {
304 wsNormalizeValue.clear();
305 CFX_WideString wsItem;
306 for (int32_t i = 0; i < iCounts; i++) {
307 items[i]->TryContent(wsItem);
308 wsItem = (iCounts == 1) ? wsItem : wsItem + L"\n";
309 wsNormalizeValue += wsItem;
310 }
311 CXFA_ExData exData = defValue.GetExData();
312 ASSERT(exData);
313 exData.SetContentType(iCounts == 1 ? L"text/plain" : L"text/xml");
314 }
315 FormValueNode_SetChildContent(defValue.GetNode(), wsNormalizeValue,
316 XFA_Element::ExData);
317 } else {
318 FormValueNode_SetChildContent(defValue.GetNode(), wsNormalizeValue,
319 XFA_Element::Text);
320 }
321 break;
322 case XFA_Element::CheckButton:
323 FormValueNode_SetChildContent(defValue.GetNode(), wsNormalizeValue,
324 XFA_Element::Text);
325 break;
326 case XFA_Element::ExclGroup: {
327 pWidgetData->SetSelectedMemberByValue(wsNormalizeValue.AsStringC(), false,
328 false, false);
329 break;
330 }
331 case XFA_Element::DateTimeEdit:
332 FormValueNode_SetChildContent(defValue.GetNode(), wsNormalizeValue,
333 XFA_Element::DateTime);
334 break;
335 case XFA_Element::NumericEdit: {
336 CFX_WideString wsPicture;
337 pWidgetData->GetPictureContent(wsPicture, XFA_VALUEPICTURE_DataBind);
338 if (wsPicture.IsEmpty()) {
339 CFX_WideString wsOutput;
340 pWidgetData->NormalizeNumStr(wsNormalizeValue, wsOutput);
341 wsNormalizeValue = wsOutput;
342 }
343 FormValueNode_SetChildContent(defValue.GetNode(), wsNormalizeValue,
344 XFA_Element::Float);
345 break;
346 }
347 case XFA_Element::Barcode:
348 case XFA_Element::Button:
349 case XFA_Element::PasswordEdit:
350 case XFA_Element::Signature:
351 case XFA_Element::TextEdit:
352 default:
353 FormValueNode_SetChildContent(defValue.GetNode(), wsNormalizeValue,
354 XFA_Element::Text);
355 break;
356 }
357 }
358
GetGlobalBinding(CXFA_Document * pDocument,uint32_t dwNameHash)359 CXFA_Node* GetGlobalBinding(CXFA_Document* pDocument, uint32_t dwNameHash) {
360 auto it = pDocument->m_rgGlobalBinding.find(dwNameHash);
361 return it != pDocument->m_rgGlobalBinding.end() ? it->second : nullptr;
362 }
363
RegisterGlobalBinding(CXFA_Document * pDocument,uint32_t dwNameHash,CXFA_Node * pDataNode)364 void RegisterGlobalBinding(CXFA_Document* pDocument,
365 uint32_t dwNameHash,
366 CXFA_Node* pDataNode) {
367 pDocument->m_rgGlobalBinding[dwNameHash] = pDataNode;
368 }
369
ScopeMatchGlobalBinding(CXFA_Node * pDataScope,uint32_t dwNameHash,XFA_Element eMatchDataNodeType,bool bUpLevel)370 CXFA_Node* ScopeMatchGlobalBinding(CXFA_Node* pDataScope,
371 uint32_t dwNameHash,
372 XFA_Element eMatchDataNodeType,
373 bool bUpLevel) {
374 for (CXFA_Node *pCurDataScope = pDataScope, *pLastDataScope = nullptr;
375 pCurDataScope && pCurDataScope->GetPacketID() == XFA_XDPPACKET_Datasets;
376 pLastDataScope = pCurDataScope,
377 pCurDataScope =
378 pCurDataScope->GetNodeItem(XFA_NODEITEM_Parent)) {
379 for (CXFA_Node* pDataChild = pCurDataScope->GetFirstChildByName(dwNameHash);
380 pDataChild;
381 pDataChild = pDataChild->GetNextSameNameSibling(dwNameHash)) {
382 if (pDataChild == pLastDataScope ||
383 (eMatchDataNodeType != XFA_Element::DataModel &&
384 pDataChild->GetElementType() != eMatchDataNodeType) ||
385 pDataChild->HasBindItem()) {
386 continue;
387 }
388 return pDataChild;
389 }
390
391 for (CXFA_Node* pDataChild =
392 pCurDataScope->GetFirstChildByClass(XFA_Element::DataGroup);
393 pDataChild; pDataChild = pDataChild->GetNextSameClassSibling(
394 XFA_Element::DataGroup)) {
395 CXFA_Node* pDataNode = ScopeMatchGlobalBinding(pDataChild, dwNameHash,
396 eMatchDataNodeType, false);
397 if (pDataNode)
398 return pDataNode;
399 }
400 if (!bUpLevel)
401 break;
402 }
403 return nullptr;
404 }
405
FindGlobalDataNode(CXFA_Document * pDocument,CFX_WideStringC wsName,CXFA_Node * pDataScope,XFA_Element eMatchNodeType)406 CXFA_Node* FindGlobalDataNode(CXFA_Document* pDocument,
407 CFX_WideStringC wsName,
408 CXFA_Node* pDataScope,
409 XFA_Element eMatchNodeType) {
410 if (wsName.IsEmpty())
411 return nullptr;
412
413 uint32_t dwNameHash = FX_HashCode_GetW(wsName, false);
414 CXFA_Node* pBounded = GetGlobalBinding(pDocument, dwNameHash);
415 if (!pBounded) {
416 pBounded =
417 ScopeMatchGlobalBinding(pDataScope, dwNameHash, eMatchNodeType, true);
418 if (pBounded)
419 RegisterGlobalBinding(pDocument, dwNameHash, pBounded);
420 }
421 return pBounded;
422 }
423
FindOnceDataNode(CXFA_Document * pDocument,CFX_WideStringC wsName,CXFA_Node * pDataScope,XFA_Element eMatchNodeType)424 CXFA_Node* FindOnceDataNode(CXFA_Document* pDocument,
425 CFX_WideStringC wsName,
426 CXFA_Node* pDataScope,
427 XFA_Element eMatchNodeType) {
428 if (wsName.IsEmpty())
429 return nullptr;
430
431 uint32_t dwNameHash = FX_HashCode_GetW(wsName, false);
432 CXFA_Node* pLastDataScope = nullptr;
433 for (CXFA_Node* pCurDataScope = pDataScope;
434 pCurDataScope && pCurDataScope->GetPacketID() == XFA_XDPPACKET_Datasets;
435 pCurDataScope = pCurDataScope->GetNodeItem(XFA_NODEITEM_Parent)) {
436 for (CXFA_Node* pDataChild = pCurDataScope->GetFirstChildByName(dwNameHash);
437 pDataChild;
438 pDataChild = pDataChild->GetNextSameNameSibling(dwNameHash)) {
439 if (pDataChild == pLastDataScope || pDataChild->HasBindItem() ||
440 (eMatchNodeType != XFA_Element::DataModel &&
441 pDataChild->GetElementType() != eMatchNodeType)) {
442 continue;
443 }
444 return pDataChild;
445 }
446 pLastDataScope = pCurDataScope;
447 }
448 return nullptr;
449 }
450
FindDataRefDataNode(CXFA_Document * pDocument,CFX_WideStringC wsRef,CXFA_Node * pDataScope,XFA_Element eMatchNodeType,CXFA_Node * pTemplateNode,bool bForceBind,bool bUpLevel)451 CXFA_Node* FindDataRefDataNode(CXFA_Document* pDocument,
452 CFX_WideStringC wsRef,
453 CXFA_Node* pDataScope,
454 XFA_Element eMatchNodeType,
455 CXFA_Node* pTemplateNode,
456 bool bForceBind,
457 bool bUpLevel) {
458 uint32_t dFlags = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_BindNew;
459 if (bUpLevel || wsRef != L"name")
460 dFlags |= (XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings);
461
462 XFA_RESOLVENODE_RS rs;
463 pDocument->GetScriptContext()->ResolveObjects(pDataScope, wsRef, rs, dFlags,
464 pTemplateNode);
465 if (rs.dwFlags == XFA_RESOLVENODE_RSTYPE_CreateNodeAll ||
466 rs.dwFlags == XFA_RESOLVENODE_RSTYPE_CreateNodeMidAll ||
467 rs.nodes.GetSize() > 1) {
468 return pDocument->GetNotBindNode(rs.nodes);
469 }
470
471 if (rs.dwFlags == XFA_RESOLVENODE_RSTYPE_CreateNodeOne) {
472 CXFA_Object* pObject = (rs.nodes.GetSize() > 0) ? rs.nodes[0] : nullptr;
473 CXFA_Node* pNode = ToNode(pObject);
474 return (bForceBind || !pNode || !pNode->HasBindItem()) ? pNode : nullptr;
475 }
476 return nullptr;
477 }
478
NeedGenerateForm(CXFA_Node * pTemplateChild,bool bUseInstanceManager)479 bool NeedGenerateForm(CXFA_Node* pTemplateChild, bool bUseInstanceManager) {
480 XFA_Element eType = pTemplateChild->GetElementType();
481 if (eType == XFA_Element::Variables)
482 return true;
483 if (pTemplateChild->IsContainerNode())
484 return false;
485 if (eType == XFA_Element::Proto ||
486 (bUseInstanceManager && eType == XFA_Element::Occur)) {
487 return false;
488 }
489 return true;
490 }
491
CloneOrMergeInstanceManager(CXFA_Document * pDocument,CXFA_Node * pFormParent,CXFA_Node * pTemplateNode,CXFA_NodeArray & subforms)492 CXFA_Node* CloneOrMergeInstanceManager(CXFA_Document* pDocument,
493 CXFA_Node* pFormParent,
494 CXFA_Node* pTemplateNode,
495 CXFA_NodeArray& subforms) {
496 CFX_WideStringC wsSubformName = pTemplateNode->GetCData(XFA_ATTRIBUTE_Name);
497 CFX_WideString wsInstMgrNodeName = L"_" + wsSubformName;
498 uint32_t dwInstNameHash =
499 FX_HashCode_GetW(wsInstMgrNodeName.AsStringC(), false);
500 CXFA_Node* pExistingNode = XFA_DataMerge_FindFormDOMInstance(
501 pDocument, XFA_Element::InstanceManager, dwInstNameHash, pFormParent);
502 if (pExistingNode) {
503 uint32_t dwNameHash = pTemplateNode->GetNameHash();
504 for (CXFA_Node* pNode =
505 pExistingNode->GetNodeItem(XFA_NODEITEM_NextSibling);
506 pNode;) {
507 XFA_Element eCurType = pNode->GetElementType();
508 if (eCurType == XFA_Element::InstanceManager)
509 break;
510
511 if ((eCurType != XFA_Element::Subform) &&
512 (eCurType != XFA_Element::SubformSet)) {
513 pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);
514 continue;
515 }
516 if (dwNameHash != pNode->GetNameHash())
517 break;
518
519 CXFA_Node* pNextNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);
520 pFormParent->RemoveChild(pNode);
521 subforms.Add(pNode);
522 pNode = pNextNode;
523 }
524 pFormParent->RemoveChild(pExistingNode);
525 pFormParent->InsertChild(pExistingNode);
526 pExistingNode->ClearFlag(XFA_NodeFlag_UnusedNode);
527 pExistingNode->SetTemplateNode(pTemplateNode);
528 return pExistingNode;
529 }
530
531 CXFA_Node* pNewNode =
532 pDocument->CreateNode(XFA_XDPPACKET_Form, XFA_Element::InstanceManager);
533 wsInstMgrNodeName = L"_" + pTemplateNode->GetCData(XFA_ATTRIBUTE_Name);
534 pNewNode->SetCData(XFA_ATTRIBUTE_Name, wsInstMgrNodeName);
535 pFormParent->InsertChild(pNewNode, nullptr);
536 pNewNode->SetTemplateNode(pTemplateNode);
537 return pNewNode;
538 }
539
FindMatchingDataNode(CXFA_Document * pDocument,CXFA_Node * pTemplateNode,CXFA_Node * pDataScope,bool & bAccessedDataDOM,bool bForceBind,CXFA_NodeIteratorTemplate<CXFA_Node,CXFA_TraverseStrategy_XFAContainerNode> * pIterator,bool & bSelfMatch,XFA_ATTRIBUTEENUM & eBindMatch,bool bUpLevel)540 CXFA_Node* FindMatchingDataNode(
541 CXFA_Document* pDocument,
542 CXFA_Node* pTemplateNode,
543 CXFA_Node* pDataScope,
544 bool& bAccessedDataDOM,
545 bool bForceBind,
546 CXFA_NodeIteratorTemplate<CXFA_Node,
547 CXFA_TraverseStrategy_XFAContainerNode>*
548 pIterator,
549 bool& bSelfMatch,
550 XFA_ATTRIBUTEENUM& eBindMatch,
551 bool bUpLevel) {
552 bool bOwnIterator = false;
553 if (!pIterator) {
554 bOwnIterator = true;
555 pIterator = new CXFA_NodeIteratorTemplate<
556 CXFA_Node, CXFA_TraverseStrategy_XFAContainerNode>(pTemplateNode);
557 }
558
559 CXFA_Node* pResult = nullptr;
560 for (CXFA_Node* pCurTemplateNode = pIterator->GetCurrent();
561 pCurTemplateNode;) {
562 XFA_Element eMatchNodeType;
563 switch (pCurTemplateNode->GetElementType()) {
564 case XFA_Element::Subform:
565 eMatchNodeType = XFA_Element::DataGroup;
566 break;
567 case XFA_Element::Field: {
568 eMatchNodeType = XFA_FieldIsMultiListBox(pCurTemplateNode)
569 ? XFA_Element::DataGroup
570 : XFA_Element::DataValue;
571 } break;
572 case XFA_Element::ExclGroup:
573 eMatchNodeType = XFA_Element::DataValue;
574 break;
575 default:
576 pCurTemplateNode = pIterator->MoveToNext();
577 continue;
578 }
579 CXFA_Node* pTemplateNodeOccur =
580 pCurTemplateNode->GetFirstChildByClass(XFA_Element::Occur);
581 int32_t iMin, iMax, iInit;
582 if (pTemplateNodeOccur &&
583 GetOccurInfo(pTemplateNodeOccur, iMin, iMax, iInit) && iMax == 0) {
584 pCurTemplateNode = pIterator->MoveToNext();
585 continue;
586 }
587
588 CXFA_Node* pTemplateNodeBind =
589 pCurTemplateNode->GetFirstChildByClass(XFA_Element::Bind);
590 XFA_ATTRIBUTEENUM eMatch =
591 pTemplateNodeBind ? pTemplateNodeBind->GetEnum(XFA_ATTRIBUTE_Match)
592 : XFA_ATTRIBUTEENUM_Once;
593 eBindMatch = eMatch;
594 switch (eMatch) {
595 case XFA_ATTRIBUTEENUM_None:
596 pCurTemplateNode = pIterator->MoveToNext();
597 continue;
598 case XFA_ATTRIBUTEENUM_Global:
599 bAccessedDataDOM = true;
600 if (!bForceBind) {
601 pCurTemplateNode = pIterator->MoveToNext();
602 continue;
603 }
604 if (eMatchNodeType == XFA_Element::DataValue ||
605 (eMatchNodeType == XFA_Element::DataGroup &&
606 XFA_FieldIsMultiListBox(pTemplateNodeBind))) {
607 CXFA_Node* pGlobalBindNode = FindGlobalDataNode(
608 pDocument, pCurTemplateNode->GetCData(XFA_ATTRIBUTE_Name),
609 pDataScope, eMatchNodeType);
610 if (!pGlobalBindNode) {
611 pCurTemplateNode = pIterator->MoveToNext();
612 continue;
613 }
614 pResult = pGlobalBindNode;
615 break;
616 }
617 case XFA_ATTRIBUTEENUM_Once: {
618 bAccessedDataDOM = true;
619 CXFA_Node* pOnceBindNode = FindOnceDataNode(
620 pDocument, pCurTemplateNode->GetCData(XFA_ATTRIBUTE_Name),
621 pDataScope, eMatchNodeType);
622 if (!pOnceBindNode) {
623 pCurTemplateNode = pIterator->MoveToNext();
624 continue;
625 }
626 pResult = pOnceBindNode;
627 break;
628 }
629 case XFA_ATTRIBUTEENUM_DataRef: {
630 bAccessedDataDOM = true;
631 CXFA_Node* pDataRefBindNode = FindDataRefDataNode(
632 pDocument, pTemplateNodeBind->GetCData(XFA_ATTRIBUTE_Ref),
633 pDataScope, eMatchNodeType, pTemplateNode, bForceBind, bUpLevel);
634 if (pDataRefBindNode &&
635 pDataRefBindNode->GetElementType() == eMatchNodeType) {
636 pResult = pDataRefBindNode;
637 }
638 if (!pResult) {
639 pCurTemplateNode = pIterator->SkipChildrenAndMoveToNext();
640 continue;
641 }
642 break;
643 }
644 default:
645 break;
646 }
647 if (pCurTemplateNode == pTemplateNode && pResult)
648 bSelfMatch = true;
649 break;
650 }
651 if (bOwnIterator)
652 delete pIterator;
653 return pResult;
654 }
655
SortRecurseRecord(CFX_ArrayTemplate<RecurseRecord> & rgRecords,CXFA_Node * pDataScope,bool bChoiceMode)656 void SortRecurseRecord(CFX_ArrayTemplate<RecurseRecord>& rgRecords,
657 CXFA_Node* pDataScope,
658 bool bChoiceMode) {
659 int32_t iCount = rgRecords.GetSize();
660 CFX_ArrayTemplate<RecurseRecord> rgResultRecord;
661 for (CXFA_Node* pChildNode = pDataScope->GetNodeItem(XFA_NODEITEM_FirstChild);
662 pChildNode;
663 pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
664 for (int32_t i = 0; i < iCount; i++) {
665 CXFA_Node* pNode = rgRecords[i].pDataChild;
666 if (pChildNode == pNode) {
667 RecurseRecord sNewRecord = {rgRecords[i].pTemplateChild, pNode};
668 rgResultRecord.Add(sNewRecord);
669 rgRecords.RemoveAt(i);
670 iCount--;
671 break;
672 }
673 }
674 if (bChoiceMode && rgResultRecord.GetSize() > 0)
675 break;
676 }
677
678 if (rgResultRecord.GetSize() > 0) {
679 if (!bChoiceMode) {
680 for (int32_t i = 0; i < iCount; i++) {
681 RecurseRecord sNewRecord = {rgRecords[i].pTemplateChild,
682 rgRecords[i].pDataChild};
683 rgResultRecord.Add(sNewRecord);
684 }
685 }
686 rgRecords.RemoveAll();
687 rgRecords.Copy(rgResultRecord);
688 }
689 }
690
CopyContainer_SubformSet(CXFA_Document * pDocument,CXFA_Node * pTemplateNode,CXFA_Node * pFormParentNode,CXFA_Node * pDataScope,bool bOneInstance,bool bDataMerge)691 CXFA_Node* CopyContainer_SubformSet(CXFA_Document* pDocument,
692 CXFA_Node* pTemplateNode,
693 CXFA_Node* pFormParentNode,
694 CXFA_Node* pDataScope,
695 bool bOneInstance,
696 bool bDataMerge) {
697 XFA_Element eType = pTemplateNode->GetElementType();
698 CXFA_Node* pOccurNode = nullptr;
699 CXFA_Node* pFirstInstance = nullptr;
700 bool bUseInstanceManager =
701 pFormParentNode->GetElementType() != XFA_Element::Area;
702 CXFA_Node* pInstMgrNode = nullptr;
703 CXFA_NodeArray subformArray;
704 CXFA_NodeArray* pSearchArray = nullptr;
705 if (!bOneInstance &&
706 (eType == XFA_Element::SubformSet || eType == XFA_Element::Subform)) {
707 pInstMgrNode = bUseInstanceManager ? CloneOrMergeInstanceManager(
708 pDocument, pFormParentNode,
709 pTemplateNode, subformArray)
710 : nullptr;
711 if (CXFA_Node* pOccurTemplateNode =
712 pTemplateNode->GetFirstChildByClass(XFA_Element::Occur)) {
713 pOccurNode = pInstMgrNode ? XFA_NodeMerge_CloneOrMergeContainer(
714 pDocument, pInstMgrNode,
715 pOccurTemplateNode, false, nullptr)
716 : pOccurTemplateNode;
717 } else if (pInstMgrNode) {
718 pOccurNode = pInstMgrNode->GetFirstChildByClass(XFA_Element::Occur);
719 if (pOccurNode)
720 pOccurNode->ClearFlag(XFA_NodeFlag_UnusedNode);
721 }
722 if (pInstMgrNode) {
723 pInstMgrNode->SetFlag(XFA_NodeFlag_Initialized, true);
724 pSearchArray = &subformArray;
725 if (pFormParentNode->GetElementType() == XFA_Element::PageArea) {
726 bOneInstance = true;
727 if (subformArray.GetSize() < 1)
728 pSearchArray = nullptr;
729 } else if ((pTemplateNode->GetNameHash() == 0) &&
730 (subformArray.GetSize() < 1)) {
731 pSearchArray = nullptr;
732 }
733 }
734 }
735
736 int32_t iMax = 1;
737 int32_t iInit = 1;
738 int32_t iMin = 1;
739 if (!bOneInstance)
740 GetOccurInfo(pOccurNode, iMin, iMax, iInit);
741
742 XFA_ATTRIBUTEENUM eRelation =
743 eType == XFA_Element::SubformSet
744 ? pTemplateNode->GetEnum(XFA_ATTRIBUTE_Relation)
745 : XFA_ATTRIBUTEENUM_Ordered;
746 int32_t iCurRepeatIndex = 0;
747 XFA_ATTRIBUTEENUM eParentBindMatch = XFA_ATTRIBUTEENUM_None;
748 if (bDataMerge) {
749 CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFAContainerNode>
750 sNodeIterator(pTemplateNode);
751 bool bAccessedDataDOM = false;
752 if (eType == XFA_Element::SubformSet || eType == XFA_Element::Area) {
753 sNodeIterator.MoveToNext();
754 } else {
755 std::map<CXFA_Node*, CXFA_Node*> subformMapArray;
756 CXFA_NodeArray nodeArray;
757 for (; iMax < 0 || iCurRepeatIndex < iMax; iCurRepeatIndex++) {
758 bool bSelfMatch = false;
759 XFA_ATTRIBUTEENUM eBindMatch = XFA_ATTRIBUTEENUM_None;
760 CXFA_Node* pDataNode = FindMatchingDataNode(
761 pDocument, pTemplateNode, pDataScope, bAccessedDataDOM, false,
762 &sNodeIterator, bSelfMatch, eBindMatch, true);
763 if (!pDataNode || sNodeIterator.GetCurrent() != pTemplateNode)
764 break;
765
766 eParentBindMatch = eBindMatch;
767 CXFA_Node* pSubformNode = XFA_NodeMerge_CloneOrMergeContainer(
768 pDocument, pFormParentNode, pTemplateNode, false, pSearchArray);
769 if (!pFirstInstance)
770 pFirstInstance = pSubformNode;
771
772 CreateDataBinding(pSubformNode, pDataNode, true);
773 ASSERT(pSubformNode);
774 subformMapArray[pSubformNode] = pDataNode;
775 nodeArray.Add(pSubformNode);
776 }
777
778 for (int32_t iIndex = 0; iIndex < nodeArray.GetSize(); iIndex++) {
779 CXFA_Node* pSubform = nodeArray[iIndex];
780 CXFA_Node* pDataNode = nullptr;
781 auto it = subformMapArray.find(pSubform);
782 if (it != subformMapArray.end())
783 pDataNode = it->second;
784 for (CXFA_Node* pTemplateChild =
785 pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild);
786 pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(
787 XFA_NODEITEM_NextSibling)) {
788 if (NeedGenerateForm(pTemplateChild, bUseInstanceManager)) {
789 XFA_NodeMerge_CloneOrMergeContainer(pDocument, pSubform,
790 pTemplateChild, true, nullptr);
791 } else if (pTemplateChild->IsContainerNode()) {
792 pDocument->DataMerge_CopyContainer(pTemplateChild, pSubform,
793 pDataNode, false, true, false);
794 }
795 }
796 }
797 subformMapArray.clear();
798 }
799
800 for (; iMax < 0 || iCurRepeatIndex < iMax; iCurRepeatIndex++) {
801 bool bSelfMatch = false;
802 XFA_ATTRIBUTEENUM eBindMatch = XFA_ATTRIBUTEENUM_None;
803 if (!FindMatchingDataNode(pDocument, pTemplateNode, pDataScope,
804 bAccessedDataDOM, false, &sNodeIterator,
805 bSelfMatch, eBindMatch, true)) {
806 break;
807 }
808 if (eBindMatch == XFA_ATTRIBUTEENUM_DataRef &&
809 eParentBindMatch == XFA_ATTRIBUTEENUM_DataRef) {
810 break;
811 }
812
813 if (eRelation == XFA_ATTRIBUTEENUM_Choice ||
814 eRelation == XFA_ATTRIBUTEENUM_Unordered) {
815 CXFA_Node* pSubformSetNode = XFA_NodeMerge_CloneOrMergeContainer(
816 pDocument, pFormParentNode, pTemplateNode, false, pSearchArray);
817 ASSERT(pSubformSetNode);
818 if (!pFirstInstance)
819 pFirstInstance = pSubformSetNode;
820
821 CFX_ArrayTemplate<RecurseRecord> rgItemMatchList;
822 CFX_ArrayTemplate<CXFA_Node*> rgItemUnmatchList;
823 for (CXFA_Node* pTemplateChild =
824 pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild);
825 pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(
826 XFA_NODEITEM_NextSibling)) {
827 if (NeedGenerateForm(pTemplateChild, bUseInstanceManager)) {
828 XFA_NodeMerge_CloneOrMergeContainer(pDocument, pSubformSetNode,
829 pTemplateChild, true, nullptr);
830 } else if (pTemplateChild->IsContainerNode()) {
831 bSelfMatch = false;
832 eBindMatch = XFA_ATTRIBUTEENUM_None;
833 if (eRelation != XFA_ATTRIBUTEENUM_Ordered) {
834 CXFA_Node* pDataMatch = FindMatchingDataNode(
835 pDocument, pTemplateChild, pDataScope, bAccessedDataDOM,
836 false, nullptr, bSelfMatch, eBindMatch, true);
837 if (pDataMatch) {
838 RecurseRecord sNewRecord = {pTemplateChild, pDataMatch};
839 if (bSelfMatch)
840 rgItemMatchList.InsertAt(0, sNewRecord);
841 else
842 rgItemMatchList.Add(sNewRecord);
843 } else {
844 rgItemUnmatchList.Add(pTemplateChild);
845 }
846 } else {
847 rgItemUnmatchList.Add(pTemplateChild);
848 }
849 }
850 }
851
852 switch (eRelation) {
853 case XFA_ATTRIBUTEENUM_Choice: {
854 ASSERT(rgItemMatchList.GetSize());
855 SortRecurseRecord(rgItemMatchList, pDataScope, true);
856 pDocument->DataMerge_CopyContainer(
857 rgItemMatchList[0].pTemplateChild, pSubformSetNode, pDataScope,
858 false, true, true);
859 break;
860 }
861 case XFA_ATTRIBUTEENUM_Unordered: {
862 if (rgItemMatchList.GetSize()) {
863 SortRecurseRecord(rgItemMatchList, pDataScope, false);
864 for (int32_t i = 0, count = rgItemMatchList.GetSize(); i < count;
865 i++) {
866 pDocument->DataMerge_CopyContainer(
867 rgItemMatchList[i].pTemplateChild, pSubformSetNode,
868 pDataScope, false, true, true);
869 }
870 }
871 for (int32_t i = 0, count = rgItemUnmatchList.GetSize(); i < count;
872 i++) {
873 pDocument->DataMerge_CopyContainer(rgItemUnmatchList[i],
874 pSubformSetNode, pDataScope,
875 false, true, true);
876 }
877 break;
878 }
879 default:
880 break;
881 }
882 } else {
883 CXFA_Node* pSubformSetNode = XFA_NodeMerge_CloneOrMergeContainer(
884 pDocument, pFormParentNode, pTemplateNode, false, pSearchArray);
885 ASSERT(pSubformSetNode);
886 if (!pFirstInstance)
887 pFirstInstance = pSubformSetNode;
888
889 for (CXFA_Node* pTemplateChild =
890 pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild);
891 pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(
892 XFA_NODEITEM_NextSibling)) {
893 if (NeedGenerateForm(pTemplateChild, bUseInstanceManager)) {
894 XFA_NodeMerge_CloneOrMergeContainer(pDocument, pSubformSetNode,
895 pTemplateChild, true, nullptr);
896 } else if (pTemplateChild->IsContainerNode()) {
897 pDocument->DataMerge_CopyContainer(pTemplateChild, pSubformSetNode,
898 pDataScope, false, true, true);
899 }
900 }
901 }
902 }
903
904 if (iCurRepeatIndex == 0 && bAccessedDataDOM == false) {
905 int32_t iLimit = iMax;
906 if (pInstMgrNode && pTemplateNode->GetNameHash() == 0) {
907 iLimit = subformArray.GetSize();
908 if (iLimit < iMin)
909 iLimit = iInit;
910 }
911
912 for (; (iLimit < 0 || iCurRepeatIndex < iLimit); iCurRepeatIndex++) {
913 if (pInstMgrNode) {
914 if (pSearchArray && pSearchArray->GetSize() < 1) {
915 if (pTemplateNode->GetNameHash() != 0)
916 break;
917 pSearchArray = nullptr;
918 }
919 } else if (!XFA_DataMerge_FindFormDOMInstance(
920 pDocument, pTemplateNode->GetElementType(),
921 pTemplateNode->GetNameHash(), pFormParentNode)) {
922 break;
923 }
924 CXFA_Node* pSubformNode = XFA_NodeMerge_CloneOrMergeContainer(
925 pDocument, pFormParentNode, pTemplateNode, false, pSearchArray);
926 ASSERT(pSubformNode);
927 if (!pFirstInstance)
928 pFirstInstance = pSubformNode;
929
930 for (CXFA_Node* pTemplateChild =
931 pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild);
932 pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(
933 XFA_NODEITEM_NextSibling)) {
934 if (NeedGenerateForm(pTemplateChild, bUseInstanceManager)) {
935 XFA_NodeMerge_CloneOrMergeContainer(pDocument, pSubformNode,
936 pTemplateChild, true, nullptr);
937 } else if (pTemplateChild->IsContainerNode()) {
938 pDocument->DataMerge_CopyContainer(pTemplateChild, pSubformNode,
939 pDataScope, false, true, true);
940 }
941 }
942 }
943 }
944 }
945
946 int32_t iMinimalLimit = iCurRepeatIndex == 0 ? iInit : iMin;
947 for (; iCurRepeatIndex < iMinimalLimit; iCurRepeatIndex++) {
948 CXFA_Node* pSubformSetNode = XFA_NodeMerge_CloneOrMergeContainer(
949 pDocument, pFormParentNode, pTemplateNode, false, pSearchArray);
950 ASSERT(pSubformSetNode);
951 if (!pFirstInstance)
952 pFirstInstance = pSubformSetNode;
953
954 bool bFound = false;
955 for (CXFA_Node* pTemplateChild =
956 pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild);
957 pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(
958 XFA_NODEITEM_NextSibling)) {
959 if (NeedGenerateForm(pTemplateChild, bUseInstanceManager)) {
960 XFA_NodeMerge_CloneOrMergeContainer(pDocument, pSubformSetNode,
961 pTemplateChild, true, nullptr);
962 } else if (pTemplateChild->IsContainerNode()) {
963 if (bFound && eRelation == XFA_ATTRIBUTEENUM_Choice)
964 continue;
965
966 pDocument->DataMerge_CopyContainer(pTemplateChild, pSubformSetNode,
967 pDataScope, false, bDataMerge, true);
968 bFound = true;
969 }
970 }
971 }
972 return pFirstInstance;
973 }
974
CopyContainer_Field(CXFA_Document * pDocument,CXFA_Node * pTemplateNode,CXFA_Node * pFormNode,CXFA_Node * pDataScope,bool bDataMerge,bool bUpLevel)975 CXFA_Node* CopyContainer_Field(CXFA_Document* pDocument,
976 CXFA_Node* pTemplateNode,
977 CXFA_Node* pFormNode,
978 CXFA_Node* pDataScope,
979 bool bDataMerge,
980 bool bUpLevel) {
981 CXFA_Node* pFieldNode = XFA_NodeMerge_CloneOrMergeContainer(
982 pDocument, pFormNode, pTemplateNode, false, nullptr);
983 ASSERT(pFieldNode);
984 for (CXFA_Node* pTemplateChildNode =
985 pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild);
986 pTemplateChildNode; pTemplateChildNode = pTemplateChildNode->GetNodeItem(
987 XFA_NODEITEM_NextSibling)) {
988 if (NeedGenerateForm(pTemplateChildNode, true)) {
989 XFA_NodeMerge_CloneOrMergeContainer(pDocument, pFieldNode,
990 pTemplateChildNode, true, nullptr);
991 } else if (pTemplateNode->GetElementType() == XFA_Element::ExclGroup &&
992 pTemplateChildNode->IsContainerNode()) {
993 if (pTemplateChildNode->GetElementType() == XFA_Element::Field) {
994 CopyContainer_Field(pDocument, pTemplateChildNode, pFieldNode, nullptr,
995 false, true);
996 }
997 }
998 }
999 if (bDataMerge) {
1000 bool bAccessedDataDOM = false;
1001 bool bSelfMatch = false;
1002 XFA_ATTRIBUTEENUM eBindMatch;
1003 CXFA_Node* pDataNode = FindMatchingDataNode(
1004 pDocument, pTemplateNode, pDataScope, bAccessedDataDOM, true, nullptr,
1005 bSelfMatch, eBindMatch, bUpLevel);
1006 if (pDataNode)
1007 CreateDataBinding(pFieldNode, pDataNode, true);
1008 } else {
1009 FormValueNode_MatchNoneCreateChild(pFieldNode);
1010 }
1011 return pFieldNode;
1012 }
1013
MaybeCreateDataNode(CXFA_Document * pDocument,CXFA_Node * pDataParent,XFA_Element eNodeType,const CFX_WideString & wsName)1014 CXFA_Node* MaybeCreateDataNode(CXFA_Document* pDocument,
1015 CXFA_Node* pDataParent,
1016 XFA_Element eNodeType,
1017 const CFX_WideString& wsName) {
1018 if (!pDataParent)
1019 return nullptr;
1020
1021 CXFA_Node* pParentDDNode = pDataParent->GetDataDescriptionNode();
1022 if (!pParentDDNode) {
1023 CXFA_Node* pDataNode =
1024 pDocument->CreateNode(XFA_XDPPACKET_Datasets, eNodeType);
1025 pDataNode->SetCData(XFA_ATTRIBUTE_Name, wsName);
1026 pDataNode->CreateXMLMappingNode();
1027 pDataParent->InsertChild(pDataNode);
1028 pDataNode->SetFlag(XFA_NodeFlag_Initialized, false);
1029 return pDataNode;
1030 }
1031
1032 CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_DDGroup> sIterator(
1033 pParentDDNode);
1034 for (CXFA_Node* pDDGroupNode = sIterator.GetCurrent(); pDDGroupNode;
1035 pDDGroupNode = sIterator.MoveToNext()) {
1036 if (pDDGroupNode != pParentDDNode) {
1037 if (pDDGroupNode->GetElementType() != XFA_Element::DataGroup)
1038 continue;
1039
1040 CFX_WideString wsNamespace;
1041 if (!pDDGroupNode->TryNamespace(wsNamespace) ||
1042 wsNamespace != L"http://ns.adobe.com/data-description/") {
1043 continue;
1044 }
1045 }
1046 CXFA_Node* pDDNode = pDDGroupNode->GetFirstChildByName(wsName.AsStringC());
1047 if (!pDDNode)
1048 continue;
1049 if (pDDNode->GetElementType() != eNodeType)
1050 break;
1051
1052 CXFA_Node* pDataNode =
1053 pDocument->CreateNode(XFA_XDPPACKET_Datasets, eNodeType);
1054 pDataNode->SetCData(XFA_ATTRIBUTE_Name, wsName);
1055 pDataNode->CreateXMLMappingNode();
1056 if (eNodeType == XFA_Element::DataValue &&
1057 pDDNode->GetEnum(XFA_ATTRIBUTE_Contains) ==
1058 XFA_ATTRIBUTEENUM_MetaData) {
1059 pDataNode->SetEnum(XFA_ATTRIBUTE_Contains, XFA_ATTRIBUTEENUM_MetaData);
1060 }
1061 pDataParent->InsertChild(pDataNode);
1062 pDataNode->SetDataDescriptionNode(pDDNode);
1063 pDataNode->SetFlag(XFA_NodeFlag_Initialized, false);
1064 return pDataNode;
1065 }
1066 return nullptr;
1067 }
1068
UpdateBindingRelations(CXFA_Document * pDocument,CXFA_Node * pFormNode,CXFA_Node * pDataScope,bool bDataRef,bool bParentDataRef)1069 void UpdateBindingRelations(CXFA_Document* pDocument,
1070 CXFA_Node* pFormNode,
1071 CXFA_Node* pDataScope,
1072 bool bDataRef,
1073 bool bParentDataRef) {
1074 bool bMatchRef = true;
1075 XFA_Element eType = pFormNode->GetElementType();
1076 CXFA_Node* pDataNode = pFormNode->GetBindData();
1077 if (eType == XFA_Element::Subform || eType == XFA_Element::ExclGroup ||
1078 eType == XFA_Element::Field) {
1079 CXFA_Node* pTemplateNode = pFormNode->GetTemplateNode();
1080 CXFA_Node* pTemplateNodeBind =
1081 pTemplateNode ? pTemplateNode->GetFirstChildByClass(XFA_Element::Bind)
1082 : nullptr;
1083 XFA_ATTRIBUTEENUM eMatch =
1084 pTemplateNodeBind ? pTemplateNodeBind->GetEnum(XFA_ATTRIBUTE_Match)
1085 : XFA_ATTRIBUTEENUM_Once;
1086 switch (eMatch) {
1087 case XFA_ATTRIBUTEENUM_None:
1088 if (!bDataRef || bParentDataRef)
1089 FormValueNode_MatchNoneCreateChild(pFormNode);
1090 break;
1091 case XFA_ATTRIBUTEENUM_Once:
1092 if (!bDataRef || bParentDataRef) {
1093 if (!pDataNode) {
1094 if (pFormNode->GetNameHash() != 0 &&
1095 pFormNode->GetEnum(XFA_ATTRIBUTE_Scope) !=
1096 XFA_ATTRIBUTEENUM_None) {
1097 XFA_Element eDataNodeType = (eType == XFA_Element::Subform ||
1098 XFA_FieldIsMultiListBox(pFormNode))
1099 ? XFA_Element::DataGroup
1100 : XFA_Element::DataValue;
1101 pDataNode = MaybeCreateDataNode(
1102 pDocument, pDataScope, eDataNodeType,
1103 CFX_WideString(pFormNode->GetCData(XFA_ATTRIBUTE_Name)));
1104 if (pDataNode)
1105 CreateDataBinding(pFormNode, pDataNode, false);
1106 }
1107 if (!pDataNode)
1108 FormValueNode_MatchNoneCreateChild(pFormNode);
1109
1110 } else {
1111 CXFA_Node* pDataParent =
1112 pDataNode->GetNodeItem(XFA_NODEITEM_Parent);
1113 if (pDataParent != pDataScope) {
1114 ASSERT(pDataParent);
1115 pDataParent->RemoveChild(pDataNode);
1116 pDataScope->InsertChild(pDataNode);
1117 }
1118 }
1119 }
1120 break;
1121 case XFA_ATTRIBUTEENUM_Global:
1122 if (!bDataRef || bParentDataRef) {
1123 uint32_t dwNameHash = pFormNode->GetNameHash();
1124 if (dwNameHash != 0 && !pDataNode) {
1125 pDataNode = GetGlobalBinding(pDocument, dwNameHash);
1126 if (!pDataNode) {
1127 XFA_Element eDataNodeType = (eType == XFA_Element::Subform ||
1128 XFA_FieldIsMultiListBox(pFormNode))
1129 ? XFA_Element::DataGroup
1130 : XFA_Element::DataValue;
1131 CXFA_Node* pRecordNode =
1132 ToNode(pDocument->GetXFAObject(XFA_HASHCODE_Record));
1133 pDataNode = MaybeCreateDataNode(
1134 pDocument, pRecordNode, eDataNodeType,
1135 CFX_WideString(pFormNode->GetCData(XFA_ATTRIBUTE_Name)));
1136 if (pDataNode) {
1137 CreateDataBinding(pFormNode, pDataNode, false);
1138 RegisterGlobalBinding(pDocument, pFormNode->GetNameHash(),
1139 pDataNode);
1140 }
1141 } else {
1142 CreateDataBinding(pFormNode, pDataNode, true);
1143 }
1144 }
1145 if (!pDataNode)
1146 FormValueNode_MatchNoneCreateChild(pFormNode);
1147 }
1148 break;
1149 case XFA_ATTRIBUTEENUM_DataRef: {
1150 bMatchRef = bDataRef;
1151 bParentDataRef = true;
1152 if (!pDataNode && bDataRef) {
1153 CFX_WideStringC wsRef =
1154 pTemplateNodeBind->GetCData(XFA_ATTRIBUTE_Ref);
1155 uint32_t dFlags =
1156 XFA_RESOLVENODE_Children | XFA_RESOLVENODE_CreateNode;
1157 XFA_RESOLVENODE_RS rs;
1158 pDocument->GetScriptContext()->ResolveObjects(pDataScope, wsRef, rs,
1159 dFlags, pTemplateNode);
1160 CXFA_Object* pObject =
1161 (rs.nodes.GetSize() > 0) ? rs.nodes[0] : nullptr;
1162 pDataNode = ToNode(pObject);
1163 if (pDataNode) {
1164 CreateDataBinding(pFormNode, pDataNode,
1165 rs.dwFlags == XFA_RESOVENODE_RSTYPE_ExistNodes);
1166 } else {
1167 FormValueNode_MatchNoneCreateChild(pFormNode);
1168 }
1169 }
1170 break;
1171 }
1172 default:
1173 break;
1174 }
1175 }
1176
1177 if (bMatchRef &&
1178 (eType == XFA_Element::Subform || eType == XFA_Element::SubformSet ||
1179 eType == XFA_Element::Area || eType == XFA_Element::PageArea ||
1180 eType == XFA_Element::PageSet)) {
1181 for (CXFA_Node* pFormChild =
1182 pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild);
1183 pFormChild;
1184 pFormChild = pFormChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
1185 if (!pFormChild->IsContainerNode())
1186 continue;
1187 if (pFormChild->IsUnusedNode())
1188 continue;
1189
1190 UpdateBindingRelations(pDocument, pFormChild,
1191 pDataNode ? pDataNode : pDataScope, bDataRef,
1192 bParentDataRef);
1193 }
1194 }
1195 }
1196
UpdateDataRelation(CXFA_Node * pDataNode,CXFA_Node * pDataDescriptionNode)1197 void UpdateDataRelation(CXFA_Node* pDataNode, CXFA_Node* pDataDescriptionNode) {
1198 ASSERT(pDataDescriptionNode);
1199 for (CXFA_Node* pDataChild = pDataNode->GetNodeItem(XFA_NODEITEM_FirstChild);
1200 pDataChild;
1201 pDataChild = pDataChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
1202 uint32_t dwNameHash = pDataChild->GetNameHash();
1203 if (!dwNameHash)
1204 continue;
1205
1206 CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_DDGroup>
1207 sIterator(pDataDescriptionNode);
1208 for (CXFA_Node* pDDGroupNode = sIterator.GetCurrent(); pDDGroupNode;
1209 pDDGroupNode = sIterator.MoveToNext()) {
1210 if (pDDGroupNode != pDataDescriptionNode) {
1211 if (pDDGroupNode->GetElementType() != XFA_Element::DataGroup)
1212 continue;
1213
1214 CFX_WideString wsNamespace;
1215 if (!pDDGroupNode->TryNamespace(wsNamespace) ||
1216 wsNamespace != L"http://ns.adobe.com/data-description/") {
1217 continue;
1218 }
1219 }
1220 CXFA_Node* pDDNode = pDDGroupNode->GetFirstChildByName(dwNameHash);
1221 if (!pDDNode)
1222 continue;
1223 if (pDDNode->GetElementType() != pDataChild->GetElementType())
1224 break;
1225
1226 pDataChild->SetDataDescriptionNode(pDDNode);
1227 UpdateDataRelation(pDataChild, pDDNode);
1228 break;
1229 }
1230 }
1231 }
1232
1233 } // namespace
1234
XFA_DataMerge_FindFormDOMInstance(CXFA_Document * pDocument,XFA_Element eType,uint32_t dwNameHash,CXFA_Node * pFormParent)1235 CXFA_Node* XFA_DataMerge_FindFormDOMInstance(CXFA_Document* pDocument,
1236 XFA_Element eType,
1237 uint32_t dwNameHash,
1238 CXFA_Node* pFormParent) {
1239 CXFA_Node* pFormChild = pFormParent->GetNodeItem(XFA_NODEITEM_FirstChild);
1240 for (; pFormChild;
1241 pFormChild = pFormChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
1242 if (pFormChild->GetElementType() == eType &&
1243 pFormChild->GetNameHash() == dwNameHash && pFormChild->IsUnusedNode()) {
1244 return pFormChild;
1245 }
1246 }
1247 return nullptr;
1248 }
1249
XFA_NodeMerge_CloneOrMergeContainer(CXFA_Document * pDocument,CXFA_Node * pFormParent,CXFA_Node * pTemplateNode,bool bRecursive,CXFA_NodeArray * pSubformArray)1250 CXFA_Node* XFA_NodeMerge_CloneOrMergeContainer(CXFA_Document* pDocument,
1251 CXFA_Node* pFormParent,
1252 CXFA_Node* pTemplateNode,
1253 bool bRecursive,
1254 CXFA_NodeArray* pSubformArray) {
1255 CXFA_Node* pExistingNode = nullptr;
1256 if (!pSubformArray) {
1257 pExistingNode = XFA_DataMerge_FindFormDOMInstance(
1258 pDocument, pTemplateNode->GetElementType(),
1259 pTemplateNode->GetNameHash(), pFormParent);
1260 } else if (pSubformArray->GetSize() > 0) {
1261 pExistingNode = pSubformArray->GetAt(0);
1262 pSubformArray->RemoveAt(0);
1263 }
1264
1265 if (pExistingNode) {
1266 if (pSubformArray) {
1267 pFormParent->InsertChild(pExistingNode);
1268 } else if (pExistingNode->IsContainerNode()) {
1269 pFormParent->RemoveChild(pExistingNode);
1270 pFormParent->InsertChild(pExistingNode);
1271 }
1272 pExistingNode->ClearFlag(XFA_NodeFlag_UnusedNode);
1273 pExistingNode->SetTemplateNode(pTemplateNode);
1274 if (bRecursive && pExistingNode->GetElementType() != XFA_Element::Items) {
1275 for (CXFA_Node* pTemplateChild =
1276 pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild);
1277 pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(
1278 XFA_NODEITEM_NextSibling)) {
1279 if (NeedGenerateForm(pTemplateChild, true)) {
1280 XFA_NodeMerge_CloneOrMergeContainer(
1281 pDocument, pExistingNode, pTemplateChild, bRecursive, nullptr);
1282 }
1283 }
1284 }
1285 pExistingNode->SetFlag(XFA_NodeFlag_Initialized, true);
1286 return pExistingNode;
1287 }
1288
1289 CXFA_Node* pNewNode = pTemplateNode->CloneTemplateToForm(false);
1290 pFormParent->InsertChild(pNewNode, nullptr);
1291 if (bRecursive) {
1292 for (CXFA_Node* pTemplateChild =
1293 pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild);
1294 pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(
1295 XFA_NODEITEM_NextSibling)) {
1296 if (NeedGenerateForm(pTemplateChild, true)) {
1297 CXFA_Node* pNewChild = pTemplateChild->CloneTemplateToForm(true);
1298 pNewNode->InsertChild(pNewChild, nullptr);
1299 }
1300 }
1301 }
1302 return pNewNode;
1303 }
1304
XFA_DataMerge_FindDataScope(CXFA_Node * pParentFormNode)1305 CXFA_Node* XFA_DataMerge_FindDataScope(CXFA_Node* pParentFormNode) {
1306 for (CXFA_Node* pRootBoundNode = pParentFormNode;
1307 pRootBoundNode && pRootBoundNode->IsContainerNode();
1308 pRootBoundNode = pRootBoundNode->GetNodeItem(XFA_NODEITEM_Parent)) {
1309 CXFA_Node* pDataScope = pRootBoundNode->GetBindData();
1310 if (pDataScope)
1311 return pDataScope;
1312 }
1313 return ToNode(
1314 pParentFormNode->GetDocument()->GetXFAObject(XFA_HASHCODE_Data));
1315 }
1316
DataMerge_CopyContainer(CXFA_Node * pTemplateNode,CXFA_Node * pFormNode,CXFA_Node * pDataScope,bool bOneInstance,bool bDataMerge,bool bUpLevel)1317 CXFA_Node* CXFA_Document::DataMerge_CopyContainer(CXFA_Node* pTemplateNode,
1318 CXFA_Node* pFormNode,
1319 CXFA_Node* pDataScope,
1320 bool bOneInstance,
1321 bool bDataMerge,
1322 bool bUpLevel) {
1323 switch (pTemplateNode->GetElementType()) {
1324 case XFA_Element::SubformSet:
1325 case XFA_Element::Subform:
1326 case XFA_Element::Area:
1327 case XFA_Element::PageArea:
1328 return CopyContainer_SubformSet(this, pTemplateNode, pFormNode,
1329 pDataScope, bOneInstance, bDataMerge);
1330 case XFA_Element::ExclGroup:
1331 case XFA_Element::Field:
1332 case XFA_Element::Draw:
1333 case XFA_Element::ContentArea:
1334 return CopyContainer_Field(this, pTemplateNode, pFormNode, pDataScope,
1335 bDataMerge, bUpLevel);
1336 case XFA_Element::PageSet:
1337 case XFA_Element::Variables:
1338 break;
1339 default:
1340 ASSERT(false);
1341 break;
1342 }
1343 return nullptr;
1344 }
1345
DataMerge_UpdateBindingRelations(CXFA_Node * pFormUpdateRoot)1346 void CXFA_Document::DataMerge_UpdateBindingRelations(
1347 CXFA_Node* pFormUpdateRoot) {
1348 CXFA_Node* pDataScope = XFA_DataMerge_FindDataScope(
1349 pFormUpdateRoot->GetNodeItem(XFA_NODEITEM_Parent));
1350 if (!pDataScope)
1351 return;
1352
1353 UpdateBindingRelations(this, pFormUpdateRoot, pDataScope, false, false);
1354 UpdateBindingRelations(this, pFormUpdateRoot, pDataScope, true, false);
1355 }
1356
GetNotBindNode(CXFA_ObjArray & arrayNodes)1357 CXFA_Node* CXFA_Document::GetNotBindNode(CXFA_ObjArray& arrayNodes) {
1358 for (int32_t i = 0; i < arrayNodes.GetSize(); i++) {
1359 CXFA_Node* pNode = arrayNodes[i]->AsNode();
1360 if (pNode && !pNode->HasBindItem())
1361 return pNode;
1362 }
1363 return nullptr;
1364 }
1365
DoDataMerge()1366 void CXFA_Document::DoDataMerge() {
1367 CXFA_Node* pDatasetsRoot = ToNode(GetXFAObject(XFA_HASHCODE_Datasets));
1368 if (!pDatasetsRoot) {
1369 CFDE_XMLElement* pDatasetsXMLNode = new CFDE_XMLElement(L"xfa:datasets");
1370 pDatasetsXMLNode->SetString(L"xmlns:xfa",
1371 L"http://www.xfa.org/schema/xfa-data/1.0/");
1372 pDatasetsRoot = CreateNode(XFA_XDPPACKET_Datasets, XFA_Element::DataModel);
1373 pDatasetsRoot->SetCData(XFA_ATTRIBUTE_Name, L"datasets");
1374 m_pRootNode->GetXMLMappingNode()->InsertChildNode(pDatasetsXMLNode);
1375 m_pRootNode->InsertChild(pDatasetsRoot);
1376 pDatasetsRoot->SetXMLMappingNode(pDatasetsXMLNode);
1377 }
1378 CXFA_Node *pDataRoot = nullptr, *pDDRoot = nullptr;
1379 CFX_WideString wsDatasetsURI;
1380 pDatasetsRoot->TryNamespace(wsDatasetsURI);
1381 for (CXFA_Node* pChildNode =
1382 pDatasetsRoot->GetNodeItem(XFA_NODEITEM_FirstChild);
1383 pChildNode;
1384 pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
1385 if (pChildNode->GetElementType() != XFA_Element::DataGroup)
1386 continue;
1387
1388 CFX_WideString wsNamespaceURI;
1389 if (!pDDRoot && pChildNode->GetNameHash() == XFA_HASHCODE_DataDescription) {
1390 if (!pChildNode->TryNamespace(wsNamespaceURI))
1391 continue;
1392 if (wsNamespaceURI == L"http://ns.adobe.com/data-description/")
1393 pDDRoot = pChildNode;
1394 } else if (!pDataRoot && pChildNode->GetNameHash() == XFA_HASHCODE_Data) {
1395 if (!pChildNode->TryNamespace(wsNamespaceURI))
1396 continue;
1397 if (wsNamespaceURI == wsDatasetsURI)
1398 pDataRoot = pChildNode;
1399 }
1400 if (pDataRoot && pDDRoot)
1401 break;
1402 }
1403
1404 if (!pDataRoot) {
1405 CFDE_XMLElement* pDataRootXMLNode = new CFDE_XMLElement(L"xfa:data");
1406 pDataRoot = CreateNode(XFA_XDPPACKET_Datasets, XFA_Element::DataGroup);
1407 pDataRoot->SetCData(XFA_ATTRIBUTE_Name, L"data");
1408 pDataRoot->SetXMLMappingNode(pDataRootXMLNode);
1409 pDatasetsRoot->InsertChild(pDataRoot);
1410 }
1411
1412 CXFA_Node* pDataTopLevel =
1413 pDataRoot->GetFirstChildByClass(XFA_Element::DataGroup);
1414 uint32_t dwNameHash = pDataTopLevel ? pDataTopLevel->GetNameHash() : 0;
1415 CXFA_Node* pTemplateRoot =
1416 m_pRootNode->GetFirstChildByClass(XFA_Element::Template);
1417 if (!pTemplateRoot)
1418 return;
1419
1420 CXFA_Node* pTemplateChosen =
1421 dwNameHash != 0 ? pTemplateRoot->GetFirstChildByName(dwNameHash)
1422 : nullptr;
1423 if (!pTemplateChosen ||
1424 pTemplateChosen->GetElementType() != XFA_Element::Subform) {
1425 pTemplateChosen = pTemplateRoot->GetFirstChildByClass(XFA_Element::Subform);
1426 }
1427 if (!pTemplateChosen)
1428 return;
1429
1430 CXFA_Node* pFormRoot = m_pRootNode->GetFirstChildByClass(XFA_Element::Form);
1431 bool bEmptyForm = false;
1432 if (!pFormRoot) {
1433 bEmptyForm = true;
1434 pFormRoot = CreateNode(XFA_XDPPACKET_Form, XFA_Element::Form);
1435 ASSERT(pFormRoot);
1436 pFormRoot->SetCData(XFA_ATTRIBUTE_Name, L"form");
1437 m_pRootNode->InsertChild(pFormRoot, nullptr);
1438 } else {
1439 CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode>
1440 sIterator(pFormRoot);
1441 for (CXFA_Node* pNode = sIterator.MoveToNext(); pNode;
1442 pNode = sIterator.MoveToNext()) {
1443 pNode->SetFlag(XFA_NodeFlag_UnusedNode, true);
1444 }
1445 }
1446
1447 CXFA_Node* pSubformSetNode = XFA_NodeMerge_CloneOrMergeContainer(
1448 this, pFormRoot, pTemplateChosen, false, nullptr);
1449 ASSERT(pSubformSetNode);
1450 if (!pDataTopLevel) {
1451 CFX_WideStringC wsFormName = pSubformSetNode->GetCData(XFA_ATTRIBUTE_Name);
1452 CFX_WideString wsDataTopLevelName(wsFormName.IsEmpty() ? L"form"
1453 : wsFormName);
1454 CFDE_XMLElement* pDataTopLevelXMLNode =
1455 new CFDE_XMLElement(wsDataTopLevelName);
1456
1457 pDataTopLevel = CreateNode(XFA_XDPPACKET_Datasets, XFA_Element::DataGroup);
1458 pDataTopLevel->SetCData(XFA_ATTRIBUTE_Name, wsDataTopLevelName);
1459 pDataTopLevel->SetXMLMappingNode(pDataTopLevelXMLNode);
1460 CXFA_Node* pBeforeNode = pDataRoot->GetNodeItem(XFA_NODEITEM_FirstChild);
1461 pDataRoot->InsertChild(pDataTopLevel, pBeforeNode);
1462 }
1463
1464 ASSERT(pDataTopLevel);
1465 CreateDataBinding(pSubformSetNode, pDataTopLevel, true);
1466 for (CXFA_Node* pTemplateChild =
1467 pTemplateChosen->GetNodeItem(XFA_NODEITEM_FirstChild);
1468 pTemplateChild;
1469 pTemplateChild = pTemplateChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
1470 if (NeedGenerateForm(pTemplateChild, true)) {
1471 XFA_NodeMerge_CloneOrMergeContainer(this, pSubformSetNode, pTemplateChild,
1472 true, nullptr);
1473 } else if (pTemplateChild->IsContainerNode()) {
1474 DataMerge_CopyContainer(pTemplateChild, pSubformSetNode, pDataTopLevel,
1475 false, true, true);
1476 }
1477 }
1478 if (pDDRoot)
1479 UpdateDataRelation(pDataRoot, pDDRoot);
1480
1481 DataMerge_UpdateBindingRelations(pSubformSetNode);
1482 CXFA_Node* pPageSetNode =
1483 pSubformSetNode->GetFirstChildByClass(XFA_Element::PageSet);
1484 while (pPageSetNode) {
1485 m_pPendingPageSet.Add(pPageSetNode);
1486 CXFA_Node* pNextPageSetNode =
1487 pPageSetNode->GetNextSameClassSibling(XFA_Element::PageSet);
1488 pSubformSetNode->RemoveChild(pPageSetNode);
1489 pPageSetNode = pNextPageSetNode;
1490 }
1491
1492 if (bEmptyForm)
1493 return;
1494
1495 CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode> sIterator(
1496 pFormRoot);
1497 CXFA_Node* pNode = sIterator.MoveToNext();
1498 while (pNode) {
1499 if (pNode->IsUnusedNode()) {
1500 if (pNode->IsContainerNode() ||
1501 pNode->GetElementType() == XFA_Element::InstanceManager) {
1502 CXFA_Node* pNext = sIterator.SkipChildrenAndMoveToNext();
1503 pNode->GetNodeItem(XFA_NODEITEM_Parent)->RemoveChild(pNode);
1504 pNode = pNext;
1505 } else {
1506 pNode->ClearFlag(XFA_NodeFlag_UnusedNode);
1507 pNode->SetFlag(XFA_NodeFlag_Initialized, true);
1508 pNode = sIterator.MoveToNext();
1509 }
1510 } else {
1511 pNode->SetFlag(XFA_NodeFlag_Initialized, true);
1512 pNode = sIterator.MoveToNext();
1513 }
1514 }
1515 }
1516
DoDataRemerge(bool bDoDataMerge)1517 void CXFA_Document::DoDataRemerge(bool bDoDataMerge) {
1518 CXFA_Node* pFormRoot = ToNode(GetXFAObject(XFA_HASHCODE_Form));
1519 if (pFormRoot) {
1520 while (CXFA_Node* pNode = pFormRoot->GetNodeItem(XFA_NODEITEM_FirstChild))
1521 pFormRoot->RemoveChild(pNode);
1522 pFormRoot->SetObject(XFA_ATTRIBUTE_BindingNode, nullptr);
1523 }
1524 m_rgGlobalBinding.clear();
1525 if (bDoDataMerge)
1526 DoDataMerge();
1527
1528 CXFA_LayoutProcessor* pLayoutProcessor = GetLayoutProcessor();
1529 pLayoutProcessor->SetForceReLayout(true);
1530 }
1531