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