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