1// Copyright 2016 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_object.h"
8
9#include <map>
10#include <memory>
11#include <utility>
12#include <vector>
13
14#include "core/fxcrt/fx_ext.h"
15#include "fxjs/cfxjse_value.h"
16#include "third_party/base/ptr_util.h"
17#include "third_party/base/stl_util.h"
18#include "xfa/fde/xml/fde_xml_imp.h"
19#include "xfa/fgas/crt/fgas_codepage.h"
20#include "xfa/fxfa/app/xfa_ffnotify.h"
21#include "xfa/fxfa/cxfa_eventparam.h"
22#include "xfa/fxfa/parser/cxfa_document.h"
23#include "xfa/fxfa/parser/cxfa_layoutprocessor.h"
24#include "xfa/fxfa/parser/cxfa_measurement.h"
25#include "xfa/fxfa/parser/cxfa_occur.h"
26#include "xfa/fxfa/parser/cxfa_scriptcontext.h"
27#include "xfa/fxfa/parser/cxfa_simple_parser.h"
28#include "xfa/fxfa/parser/xfa_basic_data.h"
29
30namespace {
31
32void XFA_DeleteWideString(void* pData) {
33  delete static_cast<CFX_WideString*>(pData);
34}
35
36void XFA_CopyWideString(void*& pData) {
37  if (pData) {
38    CFX_WideString* pNewData = new CFX_WideString(*(CFX_WideString*)pData);
39    pData = pNewData;
40  }
41}
42
43XFA_MAPDATABLOCKCALLBACKINFO deleteWideStringCallBack = {XFA_DeleteWideString,
44                                                         XFA_CopyWideString};
45
46void XFA_DataNodeDeleteBindItem(void* pData) {
47  delete static_cast<CXFA_NodeArray*>(pData);
48}
49
50XFA_MAPDATABLOCKCALLBACKINFO deleteBindItemCallBack = {
51    XFA_DataNodeDeleteBindItem, nullptr};
52
53int32_t GetCount(CXFA_Node* pInstMgrNode) {
54  ASSERT(pInstMgrNode);
55  int32_t iCount = 0;
56  uint32_t dwNameHash = 0;
57  for (CXFA_Node* pNode = pInstMgrNode->GetNodeItem(XFA_NODEITEM_NextSibling);
58       pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
59    XFA_Element eCurType = pNode->GetElementType();
60    if (eCurType == XFA_Element::InstanceManager)
61      break;
62    if ((eCurType != XFA_Element::Subform) &&
63        (eCurType != XFA_Element::SubformSet)) {
64      continue;
65    }
66    if (iCount == 0) {
67      CFX_WideStringC wsName = pNode->GetCData(XFA_ATTRIBUTE_Name);
68      CFX_WideStringC wsInstName = pInstMgrNode->GetCData(XFA_ATTRIBUTE_Name);
69      if (wsInstName.GetLength() < 1 || wsInstName.GetAt(0) != '_' ||
70          wsInstName.Mid(1) != wsName) {
71        return iCount;
72      }
73      dwNameHash = pNode->GetNameHash();
74    }
75    if (dwNameHash != pNode->GetNameHash())
76      break;
77
78    iCount++;
79  }
80  return iCount;
81}
82
83void SortNodeArrayByDocumentIdx(const CXFA_NodeSet& rgNodeSet,
84                                CXFA_NodeArray& rgNodeArray,
85                                CFX_ArrayTemplate<int32_t>& rgIdxArray) {
86  int32_t iCount = pdfium::CollectionSize<int32_t>(rgNodeSet);
87  rgNodeArray.SetSize(iCount);
88  rgIdxArray.SetSize(iCount);
89  if (iCount == 0)
90    return;
91
92  int32_t iIndex = -1;
93  int32_t iTotalIndex = -1;
94  CXFA_Node* pCommonParent =
95      (*rgNodeSet.begin())->GetNodeItem(XFA_NODEITEM_Parent);
96  for (CXFA_Node* pNode = pCommonParent->GetNodeItem(XFA_NODEITEM_FirstChild);
97       pNode && iIndex < iCount;
98       pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
99    iTotalIndex++;
100    if (pdfium::ContainsValue(rgNodeSet, pNode)) {
101      iIndex++;
102      rgNodeArray[iIndex] = pNode;
103      rgIdxArray[iIndex] = iTotalIndex;
104    }
105  }
106}
107
108using CXFA_NodeSetPair = std::pair<CXFA_NodeSet, CXFA_NodeSet>;
109using CXFA_NodeSetPairMap =
110    std::map<uint32_t, std::unique_ptr<CXFA_NodeSetPair>>;
111using CXFA_NodeSetPairMapMap =
112    std::map<CXFA_Node*, std::unique_ptr<CXFA_NodeSetPairMap>>;
113
114CXFA_NodeSetPair* NodeSetPairForNode(CXFA_Node* pNode,
115                                     CXFA_NodeSetPairMapMap* pMap) {
116  CXFA_Node* pParentNode = pNode->GetNodeItem(XFA_NODEITEM_Parent);
117  uint32_t dwNameHash = pNode->GetNameHash();
118  if (!pParentNode || !dwNameHash)
119    return nullptr;
120
121  if (!(*pMap)[pParentNode])
122    (*pMap)[pParentNode] = pdfium::MakeUnique<CXFA_NodeSetPairMap>();
123
124  CXFA_NodeSetPairMap* pNodeSetPairMap = (*pMap)[pParentNode].get();
125  if (!(*pNodeSetPairMap)[dwNameHash])
126    (*pNodeSetPairMap)[dwNameHash] = pdfium::MakeUnique<CXFA_NodeSetPair>();
127
128  return (*pNodeSetPairMap)[dwNameHash].get();
129}
130
131void ReorderDataNodes(const CXFA_NodeSet& sSet1,
132                      const CXFA_NodeSet& sSet2,
133                      bool bInsertBefore) {
134  CXFA_NodeSetPairMapMap rgMap;
135  for (CXFA_Node* pNode : sSet1) {
136    CXFA_NodeSetPair* pNodeSetPair = NodeSetPairForNode(pNode, &rgMap);
137    if (pNodeSetPair)
138      pNodeSetPair->first.insert(pNode);
139  }
140  for (CXFA_Node* pNode : sSet2) {
141    CXFA_NodeSetPair* pNodeSetPair = NodeSetPairForNode(pNode, &rgMap);
142    if (pNodeSetPair) {
143      if (pdfium::ContainsValue(pNodeSetPair->first, pNode))
144        pNodeSetPair->first.erase(pNode);
145      else
146        pNodeSetPair->second.insert(pNode);
147    }
148  }
149  for (const auto& iter1 : rgMap) {
150    CXFA_NodeSetPairMap* pNodeSetPairMap = iter1.second.get();
151    if (!pNodeSetPairMap)
152      continue;
153
154    for (const auto& iter2 : *pNodeSetPairMap) {
155      CXFA_NodeSetPair* pNodeSetPair = iter2.second.get();
156      if (!pNodeSetPair)
157        continue;
158      if (!pNodeSetPair->first.empty() && !pNodeSetPair->second.empty()) {
159        CXFA_NodeArray rgNodeArray1;
160        CXFA_NodeArray rgNodeArray2;
161        CFX_ArrayTemplate<int32_t> rgIdxArray1;
162        CFX_ArrayTemplate<int32_t> rgIdxArray2;
163        SortNodeArrayByDocumentIdx(pNodeSetPair->first, rgNodeArray1,
164                                   rgIdxArray1);
165        SortNodeArrayByDocumentIdx(pNodeSetPair->second, rgNodeArray2,
166                                   rgIdxArray2);
167        CXFA_Node* pParentNode = nullptr;
168        CXFA_Node* pBeforeNode = nullptr;
169        if (bInsertBefore) {
170          pBeforeNode = rgNodeArray2[0];
171          pParentNode = pBeforeNode->GetNodeItem(XFA_NODEITEM_Parent);
172        } else {
173          CXFA_Node* pLastNode = rgNodeArray2[rgIdxArray2.GetSize() - 1];
174          pParentNode = pLastNode->GetNodeItem(XFA_NODEITEM_Parent);
175          pBeforeNode = pLastNode->GetNodeItem(XFA_NODEITEM_NextSibling);
176        }
177        for (int32_t iIdx = 0; iIdx < rgIdxArray1.GetSize(); iIdx++) {
178          CXFA_Node* pCurNode = rgNodeArray1[iIdx];
179          pParentNode->RemoveChild(pCurNode);
180          pParentNode->InsertChild(pCurNode, pBeforeNode);
181        }
182      }
183    }
184    pNodeSetPairMap->clear();
185  }
186}
187
188CXFA_Node* GetItem(CXFA_Node* pInstMgrNode, int32_t iIndex) {
189  ASSERT(pInstMgrNode);
190  int32_t iCount = 0;
191  uint32_t dwNameHash = 0;
192  for (CXFA_Node* pNode = pInstMgrNode->GetNodeItem(XFA_NODEITEM_NextSibling);
193       pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
194    XFA_Element eCurType = pNode->GetElementType();
195    if (eCurType == XFA_Element::InstanceManager)
196      break;
197    if ((eCurType != XFA_Element::Subform) &&
198        (eCurType != XFA_Element::SubformSet)) {
199      continue;
200    }
201    if (iCount == 0) {
202      CFX_WideStringC wsName = pNode->GetCData(XFA_ATTRIBUTE_Name);
203      CFX_WideStringC wsInstName = pInstMgrNode->GetCData(XFA_ATTRIBUTE_Name);
204      if (wsInstName.GetLength() < 1 || wsInstName.GetAt(0) != '_' ||
205          wsInstName.Mid(1) != wsName) {
206        return nullptr;
207      }
208      dwNameHash = pNode->GetNameHash();
209    }
210    if (dwNameHash != pNode->GetNameHash())
211      break;
212
213    iCount++;
214    if (iCount > iIndex)
215      return pNode;
216  }
217  return nullptr;
218}
219
220void InsertItem(CXFA_Node* pInstMgrNode,
221                CXFA_Node* pNewInstance,
222                int32_t iPos,
223                int32_t iCount = -1,
224                bool bMoveDataBindingNodes = true) {
225  if (iCount < 0)
226    iCount = GetCount(pInstMgrNode);
227  if (iPos < 0)
228    iPos = iCount;
229  if (iPos == iCount) {
230    CXFA_Node* pNextSibling =
231        iCount > 0
232            ? GetItem(pInstMgrNode, iCount - 1)
233                  ->GetNodeItem(XFA_NODEITEM_NextSibling)
234            : pInstMgrNode->GetNodeItem(XFA_NODEITEM_NextSibling);
235    pInstMgrNode->GetNodeItem(XFA_NODEITEM_Parent)
236        ->InsertChild(pNewInstance, pNextSibling);
237    if (bMoveDataBindingNodes) {
238      CXFA_NodeSet sNew;
239      CXFA_NodeSet sAfter;
240      CXFA_NodeIteratorTemplate<CXFA_Node,
241                                CXFA_TraverseStrategy_XFAContainerNode>
242          sIteratorNew(pNewInstance);
243      for (CXFA_Node* pNode = sIteratorNew.GetCurrent(); pNode;
244           pNode = sIteratorNew.MoveToNext()) {
245        CXFA_Node* pDataNode = pNode->GetBindData();
246        if (!pDataNode)
247          continue;
248
249        sNew.insert(pDataNode);
250      }
251      CXFA_NodeIteratorTemplate<CXFA_Node,
252                                CXFA_TraverseStrategy_XFAContainerNode>
253          sIteratorAfter(pNextSibling);
254      for (CXFA_Node* pNode = sIteratorAfter.GetCurrent(); pNode;
255           pNode = sIteratorAfter.MoveToNext()) {
256        CXFA_Node* pDataNode = pNode->GetBindData();
257        if (!pDataNode)
258          continue;
259
260        sAfter.insert(pDataNode);
261      }
262      ReorderDataNodes(sNew, sAfter, false);
263    }
264  } else {
265    CXFA_Node* pBeforeInstance = GetItem(pInstMgrNode, iPos);
266    pInstMgrNode->GetNodeItem(XFA_NODEITEM_Parent)
267        ->InsertChild(pNewInstance, pBeforeInstance);
268    if (bMoveDataBindingNodes) {
269      CXFA_NodeSet sNew;
270      CXFA_NodeSet sBefore;
271      CXFA_NodeIteratorTemplate<CXFA_Node,
272                                CXFA_TraverseStrategy_XFAContainerNode>
273          sIteratorNew(pNewInstance);
274      for (CXFA_Node* pNode = sIteratorNew.GetCurrent(); pNode;
275           pNode = sIteratorNew.MoveToNext()) {
276        CXFA_Node* pDataNode = pNode->GetBindData();
277        if (!pDataNode)
278          continue;
279
280        sNew.insert(pDataNode);
281      }
282      CXFA_NodeIteratorTemplate<CXFA_Node,
283                                CXFA_TraverseStrategy_XFAContainerNode>
284          sIteratorBefore(pBeforeInstance);
285      for (CXFA_Node* pNode = sIteratorBefore.GetCurrent(); pNode;
286           pNode = sIteratorBefore.MoveToNext()) {
287        CXFA_Node* pDataNode = pNode->GetBindData();
288        if (!pDataNode)
289          continue;
290
291        sBefore.insert(pDataNode);
292      }
293      ReorderDataNodes(sNew, sBefore, true);
294    }
295  }
296}
297
298void RemoveItem(CXFA_Node* pInstMgrNode,
299                CXFA_Node* pRemoveInstance,
300                bool bRemoveDataBinding = true) {
301  pInstMgrNode->GetNodeItem(XFA_NODEITEM_Parent)->RemoveChild(pRemoveInstance);
302  if (!bRemoveDataBinding)
303    return;
304
305  CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFAContainerNode>
306      sIterator(pRemoveInstance);
307  for (CXFA_Node* pFormNode = sIterator.GetCurrent(); pFormNode;
308       pFormNode = sIterator.MoveToNext()) {
309    CXFA_Node* pDataNode = pFormNode->GetBindData();
310    if (!pDataNode)
311      continue;
312
313    if (pDataNode->RemoveBindItem(pFormNode) == 0) {
314      if (CXFA_Node* pDataParent =
315              pDataNode->GetNodeItem(XFA_NODEITEM_Parent)) {
316        pDataParent->RemoveChild(pDataNode);
317      }
318    }
319    pFormNode->SetObject(XFA_ATTRIBUTE_BindingNode, nullptr);
320  }
321}
322
323CXFA_Node* CreateInstance(CXFA_Node* pInstMgrNode, bool bDataMerge) {
324  CXFA_Document* pDocument = pInstMgrNode->GetDocument();
325  CXFA_Node* pTemplateNode = pInstMgrNode->GetTemplateNode();
326  CXFA_Node* pFormParent = pInstMgrNode->GetNodeItem(XFA_NODEITEM_Parent);
327  CXFA_Node* pDataScope = nullptr;
328  for (CXFA_Node* pRootBoundNode = pFormParent;
329       pRootBoundNode && pRootBoundNode->IsContainerNode();
330       pRootBoundNode = pRootBoundNode->GetNodeItem(XFA_NODEITEM_Parent)) {
331    pDataScope = pRootBoundNode->GetBindData();
332    if (pDataScope)
333      break;
334  }
335  if (!pDataScope) {
336    pDataScope = ToNode(pDocument->GetXFAObject(XFA_HASHCODE_Record));
337    ASSERT(pDataScope);
338  }
339  CXFA_Node* pInstance = pDocument->DataMerge_CopyContainer(
340      pTemplateNode, pFormParent, pDataScope, true, bDataMerge, true);
341  if (pInstance) {
342    pDocument->DataMerge_UpdateBindingRelations(pInstance);
343    pFormParent->RemoveChild(pInstance);
344  }
345  return pInstance;
346}
347
348struct XFA_ExecEventParaInfo {
349 public:
350  uint32_t m_uHash;
351  const FX_WCHAR* m_lpcEventName;
352  XFA_EVENTTYPE m_eventType;
353  uint32_t m_validFlags;
354};
355static const XFA_ExecEventParaInfo gs_eventParaInfos[] = {
356    {0x02a6c55a, L"postSubmit", XFA_EVENT_PostSubmit, 0},
357    {0x0ab466bb, L"preSubmit", XFA_EVENT_PreSubmit, 0},
358    {0x109d7ce7, L"mouseEnter", XFA_EVENT_MouseEnter, 5},
359    {0x17fad373, L"postPrint", XFA_EVENT_PostPrint, 0},
360    {0x1bfc72d9, L"preOpen", XFA_EVENT_PreOpen, 7},
361    {0x2196a452, L"initialize", XFA_EVENT_Initialize, 1},
362    {0x27410f03, L"mouseExit", XFA_EVENT_MouseExit, 5},
363    {0x33c43dec, L"docClose", XFA_EVENT_DocClose, 0},
364    {0x361fa1b6, L"preSave", XFA_EVENT_PreSave, 0},
365    {0x36f1c6d8, L"preSign", XFA_EVENT_PreSign, 6},
366    {0x4731d6ba, L"exit", XFA_EVENT_Exit, 2},
367    {0x56bf456b, L"docReady", XFA_EVENT_DocReady, 0},
368    {0x7233018a, L"validate", XFA_EVENT_Validate, 1},
369    {0x8808385e, L"indexChange", XFA_EVENT_IndexChange, 3},
370    {0x891f4606, L"change", XFA_EVENT_Change, 4},
371    {0x9528a7b4, L"prePrint", XFA_EVENT_PrePrint, 0},
372    {0x9f693b21, L"mouseDown", XFA_EVENT_MouseDown, 5},
373    {0xcdce56b3, L"full", XFA_EVENT_Full, 4},
374    {0xd576d08e, L"mouseUp", XFA_EVENT_MouseUp, 5},
375    {0xd95657a6, L"click", XFA_EVENT_Click, 4},
376    {0xdbfbe02e, L"calculate", XFA_EVENT_Calculate, 1},
377    {0xe25fa7b8, L"postOpen", XFA_EVENT_PostOpen, 7},
378    {0xe28dce7e, L"enter", XFA_EVENT_Enter, 2},
379    {0xfc82d695, L"postSave", XFA_EVENT_PostSave, 0},
380    {0xfd54fbb7, L"postSign", XFA_EVENT_PostSign, 6},
381};
382
383const XFA_ExecEventParaInfo* GetEventParaInfoByName(
384    const CFX_WideStringC& wsEventName) {
385  uint32_t uHash = FX_HashCode_GetW(wsEventName, false);
386  int32_t iStart = 0;
387  int32_t iEnd = (sizeof(gs_eventParaInfos) / sizeof(gs_eventParaInfos[0])) - 1;
388  do {
389    int32_t iMid = (iStart + iEnd) / 2;
390    const XFA_ExecEventParaInfo* eventParaInfo = &gs_eventParaInfos[iMid];
391    if (uHash == eventParaInfo->m_uHash)
392      return eventParaInfo;
393    if (uHash < eventParaInfo->m_uHash)
394      iEnd = iMid - 1;
395    else
396      iStart = iMid + 1;
397  } while (iStart <= iEnd);
398  return nullptr;
399}
400
401void StrToRGB(const CFX_WideString& strRGB,
402              int32_t& r,
403              int32_t& g,
404              int32_t& b) {
405  r = 0;
406  g = 0;
407  b = 0;
408
409  FX_WCHAR zero = '0';
410  int32_t iIndex = 0;
411  int32_t iLen = strRGB.GetLength();
412  for (int32_t i = 0; i < iLen; ++i) {
413    FX_WCHAR ch = strRGB.GetAt(i);
414    if (ch == L',')
415      ++iIndex;
416    if (iIndex > 2)
417      break;
418
419    int32_t iValue = ch - zero;
420    if (iValue >= 0 && iValue <= 9) {
421      switch (iIndex) {
422        case 0:
423          r = r * 10 + iValue;
424          break;
425        case 1:
426          g = g * 10 + iValue;
427          break;
428        default:
429          b = b * 10 + iValue;
430          break;
431      }
432    }
433  }
434}
435
436enum XFA_KEYTYPE {
437  XFA_KEYTYPE_Custom,
438  XFA_KEYTYPE_Element,
439};
440
441void* GetMapKey_Custom(const CFX_WideStringC& wsKey) {
442  uint32_t dwKey = FX_HashCode_GetW(wsKey, false);
443  return (void*)(uintptr_t)((dwKey << 1) | XFA_KEYTYPE_Custom);
444}
445
446void* GetMapKey_Element(XFA_Element eType, XFA_ATTRIBUTE eAttribute) {
447  return (void*)(uintptr_t)((static_cast<int32_t>(eType) << 16) |
448                            (eAttribute << 8) | XFA_KEYTYPE_Element);
449}
450
451const XFA_ATTRIBUTEINFO* GetAttributeOfElement(XFA_Element eElement,
452                                               XFA_ATTRIBUTE eAttribute,
453                                               uint32_t dwPacket) {
454  int32_t iCount = 0;
455  const uint8_t* pAttr = XFA_GetElementAttributes(eElement, iCount);
456  if (!pAttr || iCount < 1)
457    return nullptr;
458
459  if (!std::binary_search(pAttr, pAttr + iCount, eAttribute))
460    return nullptr;
461
462  const XFA_ATTRIBUTEINFO* pInfo = XFA_GetAttributeByID(eAttribute);
463  ASSERT(pInfo);
464  if (dwPacket == XFA_XDPPACKET_UNKNOWN)
465    return pInfo;
466  return (dwPacket & pInfo->dwPackets) ? pInfo : nullptr;
467}
468
469const XFA_ATTRIBUTEENUMINFO* GetAttributeEnumByID(XFA_ATTRIBUTEENUM eName) {
470  return g_XFAEnumData + eName;
471}
472
473}  // namespace
474
475static void XFA_DefaultFreeData(void* pData) {}
476
477static XFA_MAPDATABLOCKCALLBACKINFO gs_XFADefaultFreeData = {
478    XFA_DefaultFreeData, nullptr};
479
480XFA_MAPMODULEDATA::XFA_MAPMODULEDATA() {}
481
482XFA_MAPMODULEDATA::~XFA_MAPMODULEDATA() {}
483
484CXFA_Node::CXFA_Node(CXFA_Document* pDoc,
485                     uint16_t ePacket,
486                     XFA_ObjectType oType,
487                     XFA_Element eType,
488                     const CFX_WideStringC& elementName)
489    : CXFA_Object(pDoc, oType, eType, elementName),
490      m_pNext(nullptr),
491      m_pChild(nullptr),
492      m_pLastChild(nullptr),
493      m_pParent(nullptr),
494      m_pXMLNode(nullptr),
495      m_ePacket(ePacket),
496      m_uNodeFlags(XFA_NodeFlag_None),
497      m_dwNameHash(0),
498      m_pAuxNode(nullptr),
499      m_pMapModuleData(nullptr) {
500  ASSERT(m_pDocument);
501}
502
503CXFA_Node::~CXFA_Node() {
504  ASSERT(!m_pParent);
505  RemoveMapModuleKey();
506  CXFA_Node* pNode = m_pChild;
507  while (pNode) {
508    CXFA_Node* pNext = pNode->m_pNext;
509    pNode->m_pParent = nullptr;
510    delete pNode;
511    pNode = pNext;
512  }
513  if (m_pXMLNode && IsOwnXMLNode())
514    delete m_pXMLNode;
515}
516
517CXFA_Node* CXFA_Node::Clone(bool bRecursive) {
518  CXFA_Node* pClone = m_pDocument->CreateNode(m_ePacket, m_elementType);
519  if (!pClone)
520    return nullptr;
521
522  MergeAllData(pClone);
523  pClone->UpdateNameHash();
524  if (IsNeedSavingXMLNode()) {
525    CFDE_XMLNode* pCloneXML = nullptr;
526    if (IsAttributeInXML()) {
527      CFX_WideString wsName;
528      GetAttribute(XFA_ATTRIBUTE_Name, wsName, false);
529      CFDE_XMLElement* pCloneXMLElement = new CFDE_XMLElement(wsName);
530      CFX_WideStringC wsValue = GetCData(XFA_ATTRIBUTE_Value);
531      if (!wsValue.IsEmpty()) {
532        pCloneXMLElement->SetTextData(CFX_WideString(wsValue));
533      }
534      pCloneXML = pCloneXMLElement;
535      pCloneXMLElement = nullptr;
536      pClone->SetEnum(XFA_ATTRIBUTE_Contains, XFA_ATTRIBUTEENUM_Unknown);
537    } else {
538      pCloneXML = m_pXMLNode->Clone(false);
539    }
540    pClone->SetXMLMappingNode(pCloneXML);
541    pClone->SetFlag(XFA_NodeFlag_OwnXMLNode, false);
542  }
543  if (bRecursive) {
544    for (CXFA_Node* pChild = GetNodeItem(XFA_NODEITEM_FirstChild); pChild;
545         pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
546      pClone->InsertChild(pChild->Clone(bRecursive));
547    }
548  }
549  pClone->SetFlag(XFA_NodeFlag_Initialized, true);
550  pClone->SetObject(XFA_ATTRIBUTE_BindingNode, nullptr);
551  return pClone;
552}
553
554CXFA_Node* CXFA_Node::GetNodeItem(XFA_NODEITEM eItem) const {
555  switch (eItem) {
556    case XFA_NODEITEM_NextSibling:
557      return m_pNext;
558    case XFA_NODEITEM_FirstChild:
559      return m_pChild;
560    case XFA_NODEITEM_Parent:
561      return m_pParent;
562    case XFA_NODEITEM_PrevSibling:
563      if (m_pParent) {
564        CXFA_Node* pSibling = m_pParent->m_pChild;
565        CXFA_Node* pPrev = nullptr;
566        while (pSibling && pSibling != this) {
567          pPrev = pSibling;
568          pSibling = pSibling->m_pNext;
569        }
570        return pPrev;
571      }
572      return nullptr;
573    default:
574      break;
575  }
576  return nullptr;
577}
578
579CXFA_Node* CXFA_Node::GetNodeItem(XFA_NODEITEM eItem,
580                                  XFA_ObjectType eType) const {
581  CXFA_Node* pNode = nullptr;
582  switch (eItem) {
583    case XFA_NODEITEM_NextSibling:
584      pNode = m_pNext;
585      while (pNode && pNode->GetObjectType() != eType)
586        pNode = pNode->m_pNext;
587      break;
588    case XFA_NODEITEM_FirstChild:
589      pNode = m_pChild;
590      while (pNode && pNode->GetObjectType() != eType)
591        pNode = pNode->m_pNext;
592      break;
593    case XFA_NODEITEM_Parent:
594      pNode = m_pParent;
595      while (pNode && pNode->GetObjectType() != eType)
596        pNode = pNode->m_pParent;
597      break;
598    case XFA_NODEITEM_PrevSibling:
599      if (m_pParent) {
600        CXFA_Node* pSibling = m_pParent->m_pChild;
601        while (pSibling && pSibling != this) {
602          if (eType == pSibling->GetObjectType())
603            pNode = pSibling;
604
605          pSibling = pSibling->m_pNext;
606        }
607      }
608      break;
609    default:
610      break;
611  }
612  return pNode;
613}
614
615int32_t CXFA_Node::GetNodeList(CXFA_NodeArray& nodes,
616                               uint32_t dwTypeFilter,
617                               XFA_Element eTypeFilter,
618                               int32_t iLevel) {
619  if (--iLevel < 0) {
620    return nodes.GetSize();
621  }
622  if (eTypeFilter != XFA_Element::Unknown) {
623    CXFA_Node* pChild = m_pChild;
624    while (pChild) {
625      if (pChild->GetElementType() == eTypeFilter) {
626        nodes.Add(pChild);
627        if (iLevel > 0) {
628          GetNodeList(nodes, dwTypeFilter, eTypeFilter, iLevel);
629        }
630      }
631      pChild = pChild->m_pNext;
632    }
633  } else if (dwTypeFilter ==
634             (XFA_NODEFILTER_Children | XFA_NODEFILTER_Properties)) {
635    CXFA_Node* pChild = m_pChild;
636    while (pChild) {
637      nodes.Add(pChild);
638      if (iLevel > 0) {
639        GetNodeList(nodes, dwTypeFilter, eTypeFilter, iLevel);
640      }
641      pChild = pChild->m_pNext;
642    }
643  } else if (dwTypeFilter != 0) {
644    bool bFilterChildren = !!(dwTypeFilter & XFA_NODEFILTER_Children);
645    bool bFilterProperties = !!(dwTypeFilter & XFA_NODEFILTER_Properties);
646    bool bFilterOneOfProperties =
647        !!(dwTypeFilter & XFA_NODEFILTER_OneOfProperty);
648    CXFA_Node* pChild = m_pChild;
649    while (pChild) {
650      const XFA_PROPERTY* pProperty = XFA_GetPropertyOfElement(
651          GetElementType(), pChild->GetElementType(), XFA_XDPPACKET_UNKNOWN);
652      if (pProperty) {
653        if (bFilterProperties) {
654          nodes.Add(pChild);
655        } else if (bFilterOneOfProperties &&
656                   (pProperty->uFlags & XFA_PROPERTYFLAG_OneOf)) {
657          nodes.Add(pChild);
658        } else if (bFilterChildren &&
659                   (pChild->GetElementType() == XFA_Element::Variables ||
660                    pChild->GetElementType() == XFA_Element::PageSet)) {
661          nodes.Add(pChild);
662        }
663      } else if (bFilterChildren) {
664        nodes.Add(pChild);
665      }
666      pChild = pChild->m_pNext;
667    }
668    if (bFilterOneOfProperties && nodes.GetSize() < 1) {
669      int32_t iProperties = 0;
670      const XFA_PROPERTY* pProperty =
671          XFA_GetElementProperties(GetElementType(), iProperties);
672      if (!pProperty || iProperties < 1)
673        return 0;
674      for (int32_t i = 0; i < iProperties; i++) {
675        if (pProperty[i].uFlags & XFA_PROPERTYFLAG_DefaultOneOf) {
676          const XFA_PACKETINFO* pPacket = XFA_GetPacketByID(GetPacketID());
677          CXFA_Node* pNewNode =
678              m_pDocument->CreateNode(pPacket, pProperty[i].eName);
679          if (!pNewNode)
680            break;
681          InsertChild(pNewNode, nullptr);
682          pNewNode->SetFlag(XFA_NodeFlag_Initialized, true);
683          nodes.Add(pNewNode);
684          break;
685        }
686      }
687    }
688  }
689  return nodes.GetSize();
690}
691
692CXFA_Node* CXFA_Node::CreateSamePacketNode(XFA_Element eType,
693                                           uint32_t dwFlags) {
694  CXFA_Node* pNode = m_pDocument->CreateNode(m_ePacket, eType);
695  pNode->SetFlag(dwFlags, true);
696  return pNode;
697}
698
699CXFA_Node* CXFA_Node::CloneTemplateToForm(bool bRecursive) {
700  ASSERT(m_ePacket == XFA_XDPPACKET_Template);
701  CXFA_Node* pClone =
702      m_pDocument->CreateNode(XFA_XDPPACKET_Form, m_elementType);
703  if (!pClone)
704    return nullptr;
705
706  pClone->SetTemplateNode(this);
707  pClone->UpdateNameHash();
708  pClone->SetXMLMappingNode(GetXMLMappingNode());
709  if (bRecursive) {
710    for (CXFA_Node* pChild = GetNodeItem(XFA_NODEITEM_FirstChild); pChild;
711         pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
712      pClone->InsertChild(pChild->CloneTemplateToForm(bRecursive));
713    }
714  }
715  pClone->SetFlag(XFA_NodeFlag_Initialized, true);
716  return pClone;
717}
718
719CXFA_Node* CXFA_Node::GetTemplateNode() const {
720  return m_pAuxNode;
721}
722
723void CXFA_Node::SetTemplateNode(CXFA_Node* pTemplateNode) {
724  m_pAuxNode = pTemplateNode;
725}
726
727CXFA_Node* CXFA_Node::GetBindData() {
728  ASSERT(GetPacketID() == XFA_XDPPACKET_Form);
729  return static_cast<CXFA_Node*>(GetObject(XFA_ATTRIBUTE_BindingNode));
730}
731
732int32_t CXFA_Node::GetBindItems(CXFA_NodeArray& formItems) {
733  if (BindsFormItems()) {
734    CXFA_NodeArray* pItems = nullptr;
735    TryObject(XFA_ATTRIBUTE_BindingNode, (void*&)pItems);
736    formItems.Copy(*pItems);
737    return formItems.GetSize();
738  }
739  CXFA_Node* pFormNode =
740      static_cast<CXFA_Node*>(GetObject(XFA_ATTRIBUTE_BindingNode));
741  if (pFormNode)
742    formItems.Add(pFormNode);
743  return formItems.GetSize();
744}
745
746int32_t CXFA_Node::AddBindItem(CXFA_Node* pFormNode) {
747  ASSERT(pFormNode);
748  if (BindsFormItems()) {
749    CXFA_NodeArray* pItems = nullptr;
750    TryObject(XFA_ATTRIBUTE_BindingNode, (void*&)pItems);
751    ASSERT(pItems);
752    if (pItems->Find(pFormNode) < 0) {
753      pItems->Add(pFormNode);
754    }
755    return pItems->GetSize();
756  }
757  CXFA_Node* pOldFormItem =
758      static_cast<CXFA_Node*>(GetObject(XFA_ATTRIBUTE_BindingNode));
759  if (!pOldFormItem) {
760    SetObject(XFA_ATTRIBUTE_BindingNode, pFormNode);
761    return 1;
762  } else if (pOldFormItem == pFormNode) {
763    return 1;
764  }
765  CXFA_NodeArray* pItems = new CXFA_NodeArray;
766  SetObject(XFA_ATTRIBUTE_BindingNode, pItems, &deleteBindItemCallBack);
767  pItems->Add(pOldFormItem);
768  pItems->Add(pFormNode);
769  m_uNodeFlags |= XFA_NodeFlag_BindFormItems;
770  return 2;
771}
772
773int32_t CXFA_Node::RemoveBindItem(CXFA_Node* pFormNode) {
774  if (BindsFormItems()) {
775    CXFA_NodeArray* pItems = nullptr;
776    TryObject(XFA_ATTRIBUTE_BindingNode, (void*&)pItems);
777    ASSERT(pItems);
778    int32_t iIndex = pItems->Find(pFormNode);
779    int32_t iCount = pItems->GetSize();
780    if (iIndex >= 0) {
781      if (iIndex != iCount - 1)
782        pItems->SetAt(iIndex, pItems->GetAt(iCount - 1));
783      pItems->RemoveAt(iCount - 1);
784      if (iCount == 2) {
785        CXFA_Node* pLastFormNode = pItems->GetAt(0);
786        SetObject(XFA_ATTRIBUTE_BindingNode, pLastFormNode);
787        m_uNodeFlags &= ~XFA_NodeFlag_BindFormItems;
788      }
789      iCount--;
790    }
791    return iCount;
792  }
793  CXFA_Node* pOldFormItem =
794      static_cast<CXFA_Node*>(GetObject(XFA_ATTRIBUTE_BindingNode));
795  if (pOldFormItem == pFormNode) {
796    SetObject(XFA_ATTRIBUTE_BindingNode, nullptr);
797    pOldFormItem = nullptr;
798  }
799  return pOldFormItem ? 1 : 0;
800}
801
802bool CXFA_Node::HasBindItem() {
803  return GetPacketID() == XFA_XDPPACKET_Datasets &&
804         GetObject(XFA_ATTRIBUTE_BindingNode);
805}
806
807CXFA_WidgetData* CXFA_Node::GetWidgetData() {
808  return (CXFA_WidgetData*)GetObject(XFA_ATTRIBUTE_WidgetData);
809}
810
811CXFA_WidgetData* CXFA_Node::GetContainerWidgetData() {
812  if (GetPacketID() != XFA_XDPPACKET_Form)
813    return nullptr;
814  XFA_Element eType = GetElementType();
815  if (eType == XFA_Element::ExclGroup)
816    return nullptr;
817  CXFA_Node* pParentNode = GetNodeItem(XFA_NODEITEM_Parent);
818  if (pParentNode && pParentNode->GetElementType() == XFA_Element::ExclGroup)
819    return nullptr;
820
821  if (eType == XFA_Element::Field) {
822    CXFA_WidgetData* pFieldWidgetData = GetWidgetData();
823    if (pFieldWidgetData &&
824        pFieldWidgetData->GetChoiceListOpen() ==
825            XFA_ATTRIBUTEENUM_MultiSelect) {
826      return nullptr;
827    } else {
828      CFX_WideString wsPicture;
829      if (pFieldWidgetData) {
830        pFieldWidgetData->GetPictureContent(wsPicture,
831                                            XFA_VALUEPICTURE_DataBind);
832      }
833      if (!wsPicture.IsEmpty())
834        return pFieldWidgetData;
835      CXFA_Node* pDataNode = GetBindData();
836      if (!pDataNode)
837        return nullptr;
838      pFieldWidgetData = nullptr;
839      CXFA_NodeArray formNodes;
840      pDataNode->GetBindItems(formNodes);
841      for (int32_t i = 0; i < formNodes.GetSize(); i++) {
842        CXFA_Node* pFormNode = formNodes.GetAt(i);
843        if (!pFormNode || pFormNode->HasRemovedChildren())
844          continue;
845        pFieldWidgetData = pFormNode->GetWidgetData();
846        if (pFieldWidgetData) {
847          pFieldWidgetData->GetPictureContent(wsPicture,
848                                              XFA_VALUEPICTURE_DataBind);
849        }
850        if (!wsPicture.IsEmpty())
851          break;
852        pFieldWidgetData = nullptr;
853      }
854      return pFieldWidgetData;
855    }
856  }
857  CXFA_Node* pGrandNode =
858      pParentNode ? pParentNode->GetNodeItem(XFA_NODEITEM_Parent) : nullptr;
859  CXFA_Node* pValueNode =
860      (pParentNode && pParentNode->GetElementType() == XFA_Element::Value)
861          ? pParentNode
862          : nullptr;
863  if (!pValueNode) {
864    pValueNode =
865        (pGrandNode && pGrandNode->GetElementType() == XFA_Element::Value)
866            ? pGrandNode
867            : nullptr;
868  }
869  CXFA_Node* pParentOfValueNode =
870      pValueNode ? pValueNode->GetNodeItem(XFA_NODEITEM_Parent) : nullptr;
871  return pParentOfValueNode ? pParentOfValueNode->GetContainerWidgetData()
872                            : nullptr;
873}
874
875bool CXFA_Node::GetLocaleName(CFX_WideString& wsLocaleName) {
876  CXFA_Node* pForm = GetDocument()->GetXFAObject(XFA_HASHCODE_Form)->AsNode();
877  CXFA_Node* pTopSubform = pForm->GetFirstChildByClass(XFA_Element::Subform);
878  ASSERT(pTopSubform);
879  CXFA_Node* pLocaleNode = this;
880  bool bLocale = false;
881  do {
882    bLocale = pLocaleNode->TryCData(XFA_ATTRIBUTE_Locale, wsLocaleName, false);
883    if (!bLocale) {
884      pLocaleNode = pLocaleNode->GetNodeItem(XFA_NODEITEM_Parent);
885    }
886  } while (pLocaleNode && pLocaleNode != pTopSubform && !bLocale);
887  if (bLocale)
888    return true;
889  CXFA_Node* pConfig = ToNode(GetDocument()->GetXFAObject(XFA_HASHCODE_Config));
890  wsLocaleName = GetDocument()->GetLocalMgr()->GetConfigLocaleName(pConfig);
891  if (!wsLocaleName.IsEmpty())
892    return true;
893  if (pTopSubform &&
894      pTopSubform->TryCData(XFA_ATTRIBUTE_Locale, wsLocaleName, false)) {
895    return true;
896  }
897  IFX_Locale* pLocale = GetDocument()->GetLocalMgr()->GetDefLocale();
898  if (pLocale) {
899    wsLocaleName = pLocale->GetName();
900    return true;
901  }
902  return false;
903}
904
905XFA_ATTRIBUTEENUM CXFA_Node::GetIntact() {
906  CXFA_Node* pKeep = GetFirstChildByClass(XFA_Element::Keep);
907  XFA_ATTRIBUTEENUM eLayoutType = GetEnum(XFA_ATTRIBUTE_Layout);
908  if (pKeep) {
909    XFA_ATTRIBUTEENUM eIntact;
910    if (pKeep->TryEnum(XFA_ATTRIBUTE_Intact, eIntact, false)) {
911      if (eIntact == XFA_ATTRIBUTEENUM_None &&
912          eLayoutType == XFA_ATTRIBUTEENUM_Row &&
913          m_pDocument->GetCurVersionMode() < XFA_VERSION_208) {
914        CXFA_Node* pPreviewRow = GetNodeItem(XFA_NODEITEM_PrevSibling,
915                                             XFA_ObjectType::ContainerNode);
916        if (pPreviewRow &&
917            pPreviewRow->GetEnum(XFA_ATTRIBUTE_Layout) ==
918                XFA_ATTRIBUTEENUM_Row) {
919          XFA_ATTRIBUTEENUM eValue;
920          if (pKeep->TryEnum(XFA_ATTRIBUTE_Previous, eValue, false) &&
921              (eValue == XFA_ATTRIBUTEENUM_ContentArea ||
922               eValue == XFA_ATTRIBUTEENUM_PageArea)) {
923            return XFA_ATTRIBUTEENUM_ContentArea;
924          }
925          CXFA_Node* pNode =
926              pPreviewRow->GetFirstChildByClass(XFA_Element::Keep);
927          if (pNode && pNode->TryEnum(XFA_ATTRIBUTE_Next, eValue, false) &&
928              (eValue == XFA_ATTRIBUTEENUM_ContentArea ||
929               eValue == XFA_ATTRIBUTEENUM_PageArea)) {
930            return XFA_ATTRIBUTEENUM_ContentArea;
931          }
932        }
933      }
934      return eIntact;
935    }
936  }
937  switch (GetElementType()) {
938    case XFA_Element::Subform:
939      switch (eLayoutType) {
940        case XFA_ATTRIBUTEENUM_Position:
941        case XFA_ATTRIBUTEENUM_Row:
942          return XFA_ATTRIBUTEENUM_ContentArea;
943        case XFA_ATTRIBUTEENUM_Tb:
944        case XFA_ATTRIBUTEENUM_Table:
945        case XFA_ATTRIBUTEENUM_Lr_tb:
946        case XFA_ATTRIBUTEENUM_Rl_tb:
947          return XFA_ATTRIBUTEENUM_None;
948        default:
949          break;
950      }
951      break;
952    case XFA_Element::Field: {
953      CXFA_Node* pParentNode = GetNodeItem(XFA_NODEITEM_Parent);
954      if (!pParentNode ||
955          pParentNode->GetElementType() == XFA_Element::PageArea)
956        return XFA_ATTRIBUTEENUM_ContentArea;
957      if (pParentNode->GetIntact() == XFA_ATTRIBUTEENUM_None) {
958        XFA_ATTRIBUTEENUM eParLayout =
959            pParentNode->GetEnum(XFA_ATTRIBUTE_Layout);
960        if (eParLayout == XFA_ATTRIBUTEENUM_Position ||
961            eParLayout == XFA_ATTRIBUTEENUM_Row ||
962            eParLayout == XFA_ATTRIBUTEENUM_Table) {
963          return XFA_ATTRIBUTEENUM_None;
964        }
965        XFA_VERSION version = m_pDocument->GetCurVersionMode();
966        if (eParLayout == XFA_ATTRIBUTEENUM_Tb && version < XFA_VERSION_208) {
967          CXFA_Measurement measureH;
968          if (TryMeasure(XFA_ATTRIBUTE_H, measureH, false))
969            return XFA_ATTRIBUTEENUM_ContentArea;
970        }
971        return XFA_ATTRIBUTEENUM_None;
972      }
973      return XFA_ATTRIBUTEENUM_ContentArea;
974    }
975    case XFA_Element::Draw:
976      return XFA_ATTRIBUTEENUM_ContentArea;
977    default:
978      break;
979  }
980  return XFA_ATTRIBUTEENUM_None;
981}
982
983CXFA_Node* CXFA_Node::GetDataDescriptionNode() {
984  if (m_ePacket == XFA_XDPPACKET_Datasets)
985    return m_pAuxNode;
986  return nullptr;
987}
988
989void CXFA_Node::SetDataDescriptionNode(CXFA_Node* pDataDescriptionNode) {
990  ASSERT(m_ePacket == XFA_XDPPACKET_Datasets);
991  m_pAuxNode = pDataDescriptionNode;
992}
993
994void CXFA_Node::Script_TreeClass_ResolveNode(CFXJSE_Arguments* pArguments) {
995  int32_t iLength = pArguments->GetLength();
996  if (iLength != 1) {
997    ThrowParamCountMismatchException(L"resolveNode");
998    return;
999  }
1000  CFX_WideString wsExpression =
1001      CFX_WideString::FromUTF8(pArguments->GetUTF8String(0).AsStringC());
1002  CXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
1003  if (!pScriptContext)
1004    return;
1005  CXFA_Node* refNode = this;
1006  if (refNode->GetElementType() == XFA_Element::Xfa)
1007    refNode = ToNode(pScriptContext->GetThisObject());
1008  uint32_t dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes |
1009                    XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Parent |
1010                    XFA_RESOLVENODE_Siblings;
1011  XFA_RESOLVENODE_RS resoveNodeRS;
1012  int32_t iRet = pScriptContext->ResolveObjects(
1013      refNode, wsExpression.AsStringC(), resoveNodeRS, dwFlag);
1014  if (iRet < 1) {
1015    pArguments->GetReturnValue()->SetNull();
1016    return;
1017  }
1018  if (resoveNodeRS.dwFlags == XFA_RESOVENODE_RSTYPE_Nodes) {
1019    CXFA_Object* pNode = resoveNodeRS.nodes[0];
1020    pArguments->GetReturnValue()->Assign(
1021        pScriptContext->GetJSValueFromMap(pNode));
1022  } else {
1023    const XFA_SCRIPTATTRIBUTEINFO* lpAttributeInfo =
1024        resoveNodeRS.pScriptAttribute;
1025    if (lpAttributeInfo && lpAttributeInfo->eValueType == XFA_SCRIPT_Object) {
1026      std::unique_ptr<CFXJSE_Value> pValue(
1027          new CFXJSE_Value(pScriptContext->GetRuntime()));
1028      (resoveNodeRS.nodes[0]->*(lpAttributeInfo->lpfnCallback))(
1029          pValue.get(), false, (XFA_ATTRIBUTE)lpAttributeInfo->eAttribute);
1030      pArguments->GetReturnValue()->Assign(pValue.get());
1031    } else {
1032      pArguments->GetReturnValue()->SetNull();
1033    }
1034  }
1035}
1036
1037void CXFA_Node::Script_TreeClass_ResolveNodes(CFXJSE_Arguments* pArguments) {
1038  int32_t iLength = pArguments->GetLength();
1039  if (iLength != 1) {
1040    ThrowParamCountMismatchException(L"resolveNodes");
1041    return;
1042  }
1043  CFX_WideString wsExpression =
1044      CFX_WideString::FromUTF8(pArguments->GetUTF8String(0).AsStringC());
1045  CFXJSE_Value* pValue = pArguments->GetReturnValue();
1046  if (!pValue)
1047    return;
1048  uint32_t dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes |
1049                    XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Parent |
1050                    XFA_RESOLVENODE_Siblings;
1051  CXFA_Node* refNode = this;
1052  if (refNode->GetElementType() == XFA_Element::Xfa)
1053    refNode = ToNode(m_pDocument->GetScriptContext()->GetThisObject());
1054  Script_Som_ResolveNodeList(pValue, wsExpression, dwFlag, refNode);
1055}
1056
1057void CXFA_Node::Script_Som_ResolveNodeList(CFXJSE_Value* pValue,
1058                                           CFX_WideString wsExpression,
1059                                           uint32_t dwFlag,
1060                                           CXFA_Node* refNode) {
1061  CXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
1062  if (!pScriptContext)
1063    return;
1064  XFA_RESOLVENODE_RS resoveNodeRS;
1065  if (!refNode)
1066    refNode = this;
1067  pScriptContext->ResolveObjects(refNode, wsExpression.AsStringC(),
1068                                 resoveNodeRS, dwFlag);
1069  CXFA_ArrayNodeList* pNodeList = new CXFA_ArrayNodeList(m_pDocument);
1070  if (resoveNodeRS.dwFlags == XFA_RESOVENODE_RSTYPE_Nodes) {
1071    for (int32_t i = 0; i < resoveNodeRS.nodes.GetSize(); i++) {
1072      if (resoveNodeRS.nodes[i]->IsNode())
1073        pNodeList->Append(resoveNodeRS.nodes[i]->AsNode());
1074    }
1075  } else {
1076    CXFA_ValueArray valueArray(pScriptContext->GetRuntime());
1077    if (resoveNodeRS.GetAttributeResult(valueArray) > 0) {
1078      CXFA_ObjArray objectArray;
1079      valueArray.GetAttributeObject(objectArray);
1080      for (int32_t i = 0; i < objectArray.GetSize(); i++) {
1081        if (objectArray[i]->IsNode())
1082          pNodeList->Append(objectArray[i]->AsNode());
1083      }
1084    }
1085  }
1086  pValue->SetObject(pNodeList, pScriptContext->GetJseNormalClass());
1087}
1088
1089void CXFA_Node::Script_TreeClass_All(CFXJSE_Value* pValue,
1090                                     bool bSetting,
1091                                     XFA_ATTRIBUTE eAttribute) {
1092  if (bSetting) {
1093    ThrowInvalidPropertyException();
1094    return;
1095  }
1096
1097  uint32_t dwFlag = XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_ALL;
1098  CFX_WideString wsName;
1099  GetAttribute(XFA_ATTRIBUTE_Name, wsName);
1100  CFX_WideString wsExpression = wsName + L"[*]";
1101  Script_Som_ResolveNodeList(pValue, wsExpression, dwFlag);
1102}
1103
1104void CXFA_Node::Script_TreeClass_Nodes(CFXJSE_Value* pValue,
1105                                       bool bSetting,
1106                                       XFA_ATTRIBUTE eAttribute) {
1107  CXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
1108  if (!pScriptContext)
1109    return;
1110  if (bSetting) {
1111    CFX_WideString wsMessage = L"Unable to set ";
1112    FXJSE_ThrowMessage(wsMessage.UTF8Encode().AsStringC());
1113  } else {
1114    CXFA_AttachNodeList* pNodeList = new CXFA_AttachNodeList(m_pDocument, this);
1115    pValue->SetObject(pNodeList, pScriptContext->GetJseNormalClass());
1116  }
1117}
1118
1119void CXFA_Node::Script_TreeClass_ClassAll(CFXJSE_Value* pValue,
1120                                          bool bSetting,
1121                                          XFA_ATTRIBUTE eAttribute) {
1122  if (bSetting) {
1123    ThrowInvalidPropertyException();
1124    return;
1125  }
1126  uint32_t dwFlag = XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_ALL;
1127  CFX_WideString wsExpression = L"#" + GetClassName() + L"[*]";
1128  Script_Som_ResolveNodeList(pValue, wsExpression, dwFlag);
1129}
1130
1131void CXFA_Node::Script_TreeClass_Parent(CFXJSE_Value* pValue,
1132                                        bool bSetting,
1133                                        XFA_ATTRIBUTE eAttribute) {
1134  if (bSetting) {
1135    ThrowInvalidPropertyException();
1136    return;
1137  }
1138  CXFA_Node* pParent = GetNodeItem(XFA_NODEITEM_Parent);
1139  if (pParent) {
1140    pValue->Assign(m_pDocument->GetScriptContext()->GetJSValueFromMap(pParent));
1141  } else {
1142    pValue->SetNull();
1143  }
1144}
1145
1146void CXFA_Node::Script_TreeClass_Index(CFXJSE_Value* pValue,
1147                                       bool bSetting,
1148                                       XFA_ATTRIBUTE eAttribute) {
1149  if (bSetting) {
1150    ThrowInvalidPropertyException();
1151    return;
1152  }
1153  pValue->SetInteger(GetNodeSameNameIndex());
1154}
1155
1156void CXFA_Node::Script_TreeClass_ClassIndex(CFXJSE_Value* pValue,
1157                                            bool bSetting,
1158                                            XFA_ATTRIBUTE eAttribute) {
1159  if (bSetting) {
1160    ThrowInvalidPropertyException();
1161    return;
1162  }
1163  pValue->SetInteger(GetNodeSameClassIndex());
1164}
1165
1166void CXFA_Node::Script_TreeClass_SomExpression(CFXJSE_Value* pValue,
1167                                               bool bSetting,
1168                                               XFA_ATTRIBUTE eAttribute) {
1169  if (bSetting) {
1170    ThrowInvalidPropertyException();
1171    return;
1172  }
1173  CFX_WideString wsSOMExpression;
1174  GetSOMExpression(wsSOMExpression);
1175  pValue->SetString(wsSOMExpression.UTF8Encode().AsStringC());
1176}
1177
1178void CXFA_Node::Script_NodeClass_ApplyXSL(CFXJSE_Arguments* pArguments) {
1179  int32_t iLength = pArguments->GetLength();
1180  if (iLength != 1) {
1181    ThrowParamCountMismatchException(L"applyXSL");
1182    return;
1183  }
1184  CFX_WideString wsExpression =
1185      CFX_WideString::FromUTF8(pArguments->GetUTF8String(0).AsStringC());
1186  // TODO(weili): check whether we need to implement this, pdfium:501.
1187  // For now, just put the variables here to avoid unused variable warning.
1188  (void)wsExpression;
1189}
1190
1191void CXFA_Node::Script_NodeClass_AssignNode(CFXJSE_Arguments* pArguments) {
1192  int32_t iLength = pArguments->GetLength();
1193  if (iLength < 1 || iLength > 3) {
1194    ThrowParamCountMismatchException(L"assignNode");
1195    return;
1196  }
1197  CFX_WideString wsExpression;
1198  CFX_WideString wsValue;
1199  int32_t iAction = 0;
1200  wsExpression =
1201      CFX_WideString::FromUTF8(pArguments->GetUTF8String(0).AsStringC());
1202  if (iLength >= 2) {
1203    wsValue =
1204        CFX_WideString::FromUTF8(pArguments->GetUTF8String(1).AsStringC());
1205  }
1206  if (iLength >= 3)
1207    iAction = pArguments->GetInt32(2);
1208  // TODO(weili): check whether we need to implement this, pdfium:501.
1209  // For now, just put the variables here to avoid unused variable warning.
1210  (void)wsExpression;
1211  (void)wsValue;
1212  (void)iAction;
1213}
1214
1215void CXFA_Node::Script_NodeClass_Clone(CFXJSE_Arguments* pArguments) {
1216  int32_t iLength = pArguments->GetLength();
1217  if (iLength != 1) {
1218    ThrowParamCountMismatchException(L"clone");
1219    return;
1220  }
1221  bool bClone = !!pArguments->GetInt32(0);
1222  CXFA_Node* pCloneNode = Clone(bClone);
1223  pArguments->GetReturnValue()->Assign(
1224      m_pDocument->GetScriptContext()->GetJSValueFromMap(pCloneNode));
1225}
1226
1227void CXFA_Node::Script_NodeClass_GetAttribute(CFXJSE_Arguments* pArguments) {
1228  int32_t iLength = pArguments->GetLength();
1229  if (iLength != 1) {
1230    ThrowParamCountMismatchException(L"getAttribute");
1231    return;
1232  }
1233  CFX_WideString wsExpression =
1234      CFX_WideString::FromUTF8(pArguments->GetUTF8String(0).AsStringC());
1235  CFX_WideString wsValue;
1236  GetAttribute(wsExpression.AsStringC(), wsValue);
1237  CFXJSE_Value* pValue = pArguments->GetReturnValue();
1238  if (pValue)
1239    pValue->SetString(wsValue.UTF8Encode().AsStringC());
1240}
1241
1242void CXFA_Node::Script_NodeClass_GetElement(CFXJSE_Arguments* pArguments) {
1243  int32_t iLength = pArguments->GetLength();
1244  if (iLength < 1 || iLength > 2) {
1245    ThrowParamCountMismatchException(L"getElement");
1246    return;
1247  }
1248  CFX_WideString wsExpression;
1249  int32_t iValue = 0;
1250  wsExpression =
1251      CFX_WideString::FromUTF8(pArguments->GetUTF8String(0).AsStringC());
1252  if (iLength >= 2)
1253    iValue = pArguments->GetInt32(1);
1254  CXFA_Node* pNode =
1255      GetProperty(iValue, XFA_GetElementTypeForName(wsExpression.AsStringC()));
1256  pArguments->GetReturnValue()->Assign(
1257      m_pDocument->GetScriptContext()->GetJSValueFromMap(pNode));
1258}
1259
1260void CXFA_Node::Script_NodeClass_IsPropertySpecified(
1261    CFXJSE_Arguments* pArguments) {
1262  int32_t iLength = pArguments->GetLength();
1263  if (iLength < 1 || iLength > 3) {
1264    ThrowParamCountMismatchException(L"isPropertySpecified");
1265    return;
1266  }
1267  CFX_WideString wsExpression;
1268  bool bParent = true;
1269  int32_t iIndex = 0;
1270  wsExpression =
1271      CFX_WideString::FromUTF8(pArguments->GetUTF8String(0).AsStringC());
1272  if (iLength >= 2)
1273    bParent = !!pArguments->GetInt32(1);
1274  if (iLength >= 3)
1275    iIndex = pArguments->GetInt32(2);
1276  bool bHas = false;
1277  const XFA_ATTRIBUTEINFO* pAttributeInfo =
1278      XFA_GetAttributeByName(wsExpression.AsStringC());
1279  CFX_WideString wsValue;
1280  if (pAttributeInfo)
1281    bHas = HasAttribute(pAttributeInfo->eName);
1282  if (!bHas) {
1283    XFA_Element eType = XFA_GetElementTypeForName(wsExpression.AsStringC());
1284    bHas = !!GetProperty(iIndex, eType);
1285    if (!bHas && bParent && m_pParent) {
1286      // Also check on the parent.
1287      bHas = m_pParent->HasAttribute(pAttributeInfo->eName);
1288      if (!bHas)
1289        bHas = !!m_pParent->GetProperty(iIndex, eType);
1290    }
1291  }
1292  CFXJSE_Value* pValue = pArguments->GetReturnValue();
1293  if (pValue)
1294    pValue->SetBoolean(bHas);
1295}
1296
1297void CXFA_Node::Script_NodeClass_LoadXML(CFXJSE_Arguments* pArguments) {
1298  int32_t iLength = pArguments->GetLength();
1299  if (iLength < 1 || iLength > 3) {
1300    ThrowParamCountMismatchException(L"loadXML");
1301    return;
1302  }
1303  CFX_WideString wsExpression;
1304  bool bIgnoreRoot = true;
1305  bool bOverwrite = 0;
1306  wsExpression =
1307      CFX_WideString::FromUTF8(pArguments->GetUTF8String(0).AsStringC());
1308  if (wsExpression.IsEmpty())
1309    return;
1310  if (iLength >= 2)
1311    bIgnoreRoot = !!pArguments->GetInt32(1);
1312  if (iLength >= 3)
1313    bOverwrite = !!pArguments->GetInt32(2);
1314  std::unique_ptr<CXFA_SimpleParser> pParser(
1315      new CXFA_SimpleParser(m_pDocument, false));
1316  if (!pParser)
1317    return;
1318  CFDE_XMLNode* pXMLNode = nullptr;
1319  int32_t iParserStatus =
1320      pParser->ParseXMLData(wsExpression, pXMLNode, nullptr);
1321  if (iParserStatus != XFA_PARSESTATUS_Done || !pXMLNode)
1322    return;
1323  if (bIgnoreRoot &&
1324      (pXMLNode->GetType() != FDE_XMLNODE_Element ||
1325       XFA_RecognizeRichText(static_cast<CFDE_XMLElement*>(pXMLNode)))) {
1326    bIgnoreRoot = false;
1327  }
1328  CXFA_Node* pFakeRoot = Clone(false);
1329  CFX_WideStringC wsContentType = GetCData(XFA_ATTRIBUTE_ContentType);
1330  if (!wsContentType.IsEmpty()) {
1331    pFakeRoot->SetCData(XFA_ATTRIBUTE_ContentType,
1332                        CFX_WideString(wsContentType));
1333  }
1334  CFDE_XMLNode* pFakeXMLRoot = pFakeRoot->GetXMLMappingNode();
1335  if (!pFakeXMLRoot) {
1336    CFDE_XMLNode* pThisXMLRoot = GetXMLMappingNode();
1337    pFakeXMLRoot = pThisXMLRoot ? pThisXMLRoot->Clone(false) : nullptr;
1338  }
1339  if (!pFakeXMLRoot)
1340    pFakeXMLRoot = new CFDE_XMLElement(CFX_WideString(GetClassName()));
1341
1342  if (bIgnoreRoot) {
1343    CFDE_XMLNode* pXMLChild = pXMLNode->GetNodeItem(CFDE_XMLNode::FirstChild);
1344    while (pXMLChild) {
1345      CFDE_XMLNode* pXMLSibling =
1346          pXMLChild->GetNodeItem(CFDE_XMLNode::NextSibling);
1347      pXMLNode->RemoveChildNode(pXMLChild);
1348      pFakeXMLRoot->InsertChildNode(pXMLChild);
1349      pXMLChild = pXMLSibling;
1350    }
1351  } else {
1352    CFDE_XMLNode* pXMLParent = pXMLNode->GetNodeItem(CFDE_XMLNode::Parent);
1353    if (pXMLParent) {
1354      pXMLParent->RemoveChildNode(pXMLNode);
1355    }
1356    pFakeXMLRoot->InsertChildNode(pXMLNode);
1357  }
1358  pParser->ConstructXFANode(pFakeRoot, pFakeXMLRoot);
1359  pFakeRoot = pParser->GetRootNode();
1360  if (pFakeRoot) {
1361    if (bOverwrite) {
1362      CXFA_Node* pChild = GetNodeItem(XFA_NODEITEM_FirstChild);
1363      CXFA_Node* pNewChild = pFakeRoot->GetNodeItem(XFA_NODEITEM_FirstChild);
1364      int32_t index = 0;
1365      while (pNewChild) {
1366        CXFA_Node* pItem = pNewChild->GetNodeItem(XFA_NODEITEM_NextSibling);
1367        pFakeRoot->RemoveChild(pNewChild);
1368        InsertChild(index++, pNewChild);
1369        pNewChild->SetFlag(XFA_NodeFlag_Initialized, true);
1370        pNewChild = pItem;
1371      }
1372      while (pChild) {
1373        CXFA_Node* pItem = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
1374        RemoveChild(pChild);
1375        pFakeRoot->InsertChild(pChild);
1376        pChild = pItem;
1377      }
1378      if (GetPacketID() == XFA_XDPPACKET_Form &&
1379          GetElementType() == XFA_Element::ExData) {
1380        CFDE_XMLNode* pTempXMLNode = GetXMLMappingNode();
1381        SetXMLMappingNode(pFakeXMLRoot);
1382        SetFlag(XFA_NodeFlag_OwnXMLNode, false);
1383        if (pTempXMLNode && !pTempXMLNode->GetNodeItem(CFDE_XMLNode::Parent)) {
1384          pFakeXMLRoot = pTempXMLNode;
1385        } else {
1386          pFakeXMLRoot = nullptr;
1387        }
1388      }
1389      MoveBufferMapData(pFakeRoot, this, XFA_CalcData, true);
1390    } else {
1391      CXFA_Node* pChild = pFakeRoot->GetNodeItem(XFA_NODEITEM_FirstChild);
1392      while (pChild) {
1393        CXFA_Node* pItem = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
1394        pFakeRoot->RemoveChild(pChild);
1395        InsertChild(pChild);
1396        pChild->SetFlag(XFA_NodeFlag_Initialized, true);
1397        pChild = pItem;
1398      }
1399    }
1400    if (pFakeXMLRoot) {
1401      pFakeRoot->SetXMLMappingNode(pFakeXMLRoot);
1402      pFakeRoot->SetFlag(XFA_NodeFlag_OwnXMLNode, false);
1403    }
1404    pFakeRoot->SetFlag(XFA_NodeFlag_HasRemovedChildren, false);
1405  } else {
1406    delete pFakeXMLRoot;
1407    pFakeXMLRoot = nullptr;
1408  }
1409}
1410
1411void CXFA_Node::Script_NodeClass_SaveFilteredXML(CFXJSE_Arguments* pArguments) {
1412  // TODO(weili): Check whether we need to implement this, pdfium:501.
1413}
1414
1415void CXFA_Node::Script_NodeClass_SaveXML(CFXJSE_Arguments* pArguments) {
1416  int32_t iLength = pArguments->GetLength();
1417  if (iLength < 0 || iLength > 1) {
1418    ThrowParamCountMismatchException(L"saveXML");
1419    return;
1420  }
1421  bool bPrettyMode = false;
1422  if (iLength == 1) {
1423    if (pArguments->GetUTF8String(0) != "pretty") {
1424      ThrowArgumentMismatchException();
1425      return;
1426    }
1427    bPrettyMode = true;
1428  }
1429  CFX_ByteStringC bsXMLHeader = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
1430  if (GetPacketID() == XFA_XDPPACKET_Form ||
1431      GetPacketID() == XFA_XDPPACKET_Datasets) {
1432    CFDE_XMLNode* pElement = nullptr;
1433    if (GetPacketID() == XFA_XDPPACKET_Datasets) {
1434      pElement = GetXMLMappingNode();
1435      if (!pElement || pElement->GetType() != FDE_XMLNODE_Element) {
1436        pArguments->GetReturnValue()->SetString(bsXMLHeader);
1437        return;
1438      }
1439      XFA_DataExporter_DealWithDataGroupNode(this);
1440    }
1441    CFX_RetainPtr<IFX_MemoryStream> pMemoryStream =
1442        IFX_MemoryStream::Create(true);
1443
1444    // Note: ambiguious below without static_cast.
1445    CFX_RetainPtr<IFGAS_Stream> pStream = IFGAS_Stream::CreateStream(
1446        CFX_RetainPtr<IFX_SeekableWriteStream>(pMemoryStream),
1447        FX_STREAMACCESS_Text | FX_STREAMACCESS_Write | FX_STREAMACCESS_Append);
1448
1449    if (!pStream) {
1450      pArguments->GetReturnValue()->SetString(bsXMLHeader);
1451      return;
1452    }
1453    pStream->SetCodePage(FX_CODEPAGE_UTF8);
1454    pStream->WriteData(bsXMLHeader.raw_str(), bsXMLHeader.GetLength());
1455    if (GetPacketID() == XFA_XDPPACKET_Form)
1456      XFA_DataExporter_RegenerateFormFile(this, pStream, nullptr, true);
1457    else
1458      pElement->SaveXMLNode(pStream);
1459    // TODO(weili): Check whether we need to save pretty print XML, pdfium:501.
1460    // For now, just put it here to avoid unused variable warning.
1461    (void)bPrettyMode;
1462    pArguments->GetReturnValue()->SetString(
1463        CFX_ByteStringC(pMemoryStream->GetBuffer(), pMemoryStream->GetSize()));
1464    return;
1465  }
1466  pArguments->GetReturnValue()->SetString("");
1467}
1468
1469void CXFA_Node::Script_NodeClass_SetAttribute(CFXJSE_Arguments* pArguments) {
1470  int32_t iLength = pArguments->GetLength();
1471  if (iLength != 2) {
1472    ThrowParamCountMismatchException(L"setAttribute");
1473    return;
1474  }
1475  CFX_WideString wsAttributeValue =
1476      CFX_WideString::FromUTF8(pArguments->GetUTF8String(0).AsStringC());
1477  CFX_WideString wsAttribute =
1478      CFX_WideString::FromUTF8(pArguments->GetUTF8String(1).AsStringC());
1479  SetAttribute(wsAttribute.AsStringC(), wsAttributeValue.AsStringC(), true);
1480}
1481
1482void CXFA_Node::Script_NodeClass_SetElement(CFXJSE_Arguments* pArguments) {
1483  int32_t iLength = pArguments->GetLength();
1484  if (iLength != 1 && iLength != 2) {
1485    ThrowParamCountMismatchException(L"setElement");
1486    return;
1487  }
1488  CXFA_Node* pNode = nullptr;
1489  CFX_WideString wsName;
1490  pNode = static_cast<CXFA_Node*>(pArguments->GetObject(0));
1491  if (iLength == 2)
1492    wsName = CFX_WideString::FromUTF8(pArguments->GetUTF8String(1).AsStringC());
1493  // TODO(weili): check whether we need to implement this, pdfium:501.
1494  // For now, just put the variables here to avoid unused variable warning.
1495  (void)pNode;
1496  (void)wsName;
1497}
1498
1499void CXFA_Node::Script_NodeClass_Ns(CFXJSE_Value* pValue,
1500                                    bool bSetting,
1501                                    XFA_ATTRIBUTE eAttribute) {
1502  if (bSetting) {
1503    ThrowInvalidPropertyException();
1504    return;
1505  }
1506
1507  CFX_WideString wsNameSpace;
1508  TryNamespace(wsNameSpace);
1509  pValue->SetString(wsNameSpace.UTF8Encode().AsStringC());
1510}
1511
1512void CXFA_Node::Script_NodeClass_Model(CFXJSE_Value* pValue,
1513                                       bool bSetting,
1514                                       XFA_ATTRIBUTE eAttribute) {
1515  if (bSetting) {
1516    ThrowInvalidPropertyException();
1517    return;
1518  }
1519  pValue->Assign(
1520      m_pDocument->GetScriptContext()->GetJSValueFromMap(GetModelNode()));
1521}
1522
1523void CXFA_Node::Script_NodeClass_IsContainer(CFXJSE_Value* pValue,
1524                                             bool bSetting,
1525                                             XFA_ATTRIBUTE eAttribute) {
1526  if (bSetting) {
1527    ThrowInvalidPropertyException();
1528    return;
1529  }
1530  pValue->SetBoolean(IsContainerNode());
1531}
1532
1533void CXFA_Node::Script_NodeClass_IsNull(CFXJSE_Value* pValue,
1534                                        bool bSetting,
1535                                        XFA_ATTRIBUTE eAttribute) {
1536  if (bSetting) {
1537    ThrowInvalidPropertyException();
1538    return;
1539  }
1540  if (GetElementType() == XFA_Element::Subform) {
1541    pValue->SetBoolean(false);
1542    return;
1543  }
1544  CFX_WideString strValue;
1545  pValue->SetBoolean(!TryContent(strValue) || strValue.IsEmpty());
1546}
1547
1548void CXFA_Node::Script_NodeClass_OneOfChild(CFXJSE_Value* pValue,
1549                                            bool bSetting,
1550                                            XFA_ATTRIBUTE eAttribute) {
1551  if (bSetting) {
1552    ThrowInvalidPropertyException();
1553    return;
1554  }
1555
1556  CXFA_NodeArray properts;
1557  int32_t iSize = GetNodeList(properts, XFA_NODEFILTER_OneOfProperty);
1558  if (iSize > 0) {
1559    pValue->Assign(
1560        m_pDocument->GetScriptContext()->GetJSValueFromMap(properts[0]));
1561  }
1562}
1563
1564void CXFA_Node::Script_ContainerClass_GetDelta(CFXJSE_Arguments* pArguments) {}
1565
1566void CXFA_Node::Script_ContainerClass_GetDeltas(CFXJSE_Arguments* pArguments) {
1567  CXFA_ArrayNodeList* pFormNodes = new CXFA_ArrayNodeList(m_pDocument);
1568  pArguments->GetReturnValue()->SetObject(
1569      pFormNodes, m_pDocument->GetScriptContext()->GetJseNormalClass());
1570}
1571void CXFA_Node::Script_ModelClass_ClearErrorList(CFXJSE_Arguments* pArguments) {
1572}
1573
1574void CXFA_Node::Script_ModelClass_CreateNode(CFXJSE_Arguments* pArguments) {
1575  Script_Template_CreateNode(pArguments);
1576}
1577
1578void CXFA_Node::Script_ModelClass_IsCompatibleNS(CFXJSE_Arguments* pArguments) {
1579  int32_t iLength = pArguments->GetLength();
1580  if (iLength < 1) {
1581    ThrowParamCountMismatchException(L"isCompatibleNS");
1582    return;
1583  }
1584  CFX_WideString wsNameSpace;
1585  if (iLength >= 1) {
1586    CFX_ByteString bsNameSpace = pArguments->GetUTF8String(0);
1587    wsNameSpace = CFX_WideString::FromUTF8(bsNameSpace.AsStringC());
1588  }
1589  CFX_WideString wsNodeNameSpace;
1590  TryNamespace(wsNodeNameSpace);
1591  CFXJSE_Value* pValue = pArguments->GetReturnValue();
1592  if (pValue)
1593    pValue->SetBoolean(wsNodeNameSpace == wsNameSpace);
1594}
1595
1596void CXFA_Node::Script_ModelClass_Context(CFXJSE_Value* pValue,
1597                                          bool bSetting,
1598                                          XFA_ATTRIBUTE eAttribute) {}
1599
1600void CXFA_Node::Script_ModelClass_AliasNode(CFXJSE_Value* pValue,
1601                                            bool bSetting,
1602                                            XFA_ATTRIBUTE eAttribute) {}
1603
1604void CXFA_Node::Script_Attribute_Integer(CFXJSE_Value* pValue,
1605                                         bool bSetting,
1606                                         XFA_ATTRIBUTE eAttribute) {
1607  if (bSetting) {
1608    SetInteger(eAttribute, pValue->ToInteger(), true);
1609  } else {
1610    pValue->SetInteger(GetInteger(eAttribute));
1611  }
1612}
1613
1614void CXFA_Node::Script_Attribute_IntegerRead(CFXJSE_Value* pValue,
1615                                             bool bSetting,
1616                                             XFA_ATTRIBUTE eAttribute) {
1617  if (bSetting) {
1618    ThrowInvalidPropertyException();
1619    return;
1620  }
1621  pValue->SetInteger(GetInteger(eAttribute));
1622}
1623
1624void CXFA_Node::Script_Attribute_BOOL(CFXJSE_Value* pValue,
1625                                      bool bSetting,
1626                                      XFA_ATTRIBUTE eAttribute) {
1627  if (bSetting) {
1628    SetBoolean(eAttribute, pValue->ToBoolean(), true);
1629  } else {
1630    pValue->SetString(GetBoolean(eAttribute) ? "1" : "0");
1631  }
1632}
1633
1634void CXFA_Node::Script_Attribute_BOOLRead(CFXJSE_Value* pValue,
1635                                          bool bSetting,
1636                                          XFA_ATTRIBUTE eAttribute) {
1637  if (bSetting) {
1638    ThrowInvalidPropertyException();
1639    return;
1640  }
1641  pValue->SetString(GetBoolean(eAttribute) ? "1" : "0");
1642}
1643
1644void CXFA_Node::Script_Attribute_SendAttributeChangeMessage(
1645    XFA_ATTRIBUTE eAttribute,
1646    bool bScriptModify) {
1647  CXFA_LayoutProcessor* pLayoutPro = m_pDocument->GetLayoutProcessor();
1648  if (!pLayoutPro)
1649    return;
1650
1651  CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
1652  if (!pNotify)
1653    return;
1654
1655  uint32_t dwPacket = GetPacketID();
1656  if (!(dwPacket & XFA_XDPPACKET_Form)) {
1657    pNotify->OnValueChanged(this, eAttribute, this, this);
1658    return;
1659  }
1660
1661  bool bNeedFindContainer = false;
1662  switch (GetElementType()) {
1663    case XFA_Element::Caption:
1664      bNeedFindContainer = true;
1665      pNotify->OnValueChanged(this, eAttribute, this,
1666                              GetNodeItem(XFA_NODEITEM_Parent));
1667      break;
1668    case XFA_Element::Font:
1669    case XFA_Element::Para: {
1670      bNeedFindContainer = true;
1671      CXFA_Node* pParentNode = GetNodeItem(XFA_NODEITEM_Parent);
1672      if (pParentNode->GetElementType() == XFA_Element::Caption) {
1673        pNotify->OnValueChanged(this, eAttribute, pParentNode,
1674                                pParentNode->GetNodeItem(XFA_NODEITEM_Parent));
1675      } else {
1676        pNotify->OnValueChanged(this, eAttribute, this, pParentNode);
1677      }
1678    } break;
1679    case XFA_Element::Margin: {
1680      bNeedFindContainer = true;
1681      CXFA_Node* pParentNode = GetNodeItem(XFA_NODEITEM_Parent);
1682      XFA_Element eParentType = pParentNode->GetElementType();
1683      if (pParentNode->IsContainerNode()) {
1684        pNotify->OnValueChanged(this, eAttribute, this, pParentNode);
1685      } else if (eParentType == XFA_Element::Caption) {
1686        pNotify->OnValueChanged(this, eAttribute, pParentNode,
1687                                pParentNode->GetNodeItem(XFA_NODEITEM_Parent));
1688      } else {
1689        CXFA_Node* pNode = pParentNode->GetNodeItem(XFA_NODEITEM_Parent);
1690        if (pNode && pNode->GetElementType() == XFA_Element::Ui) {
1691          pNotify->OnValueChanged(this, eAttribute, pNode,
1692                                  pNode->GetNodeItem(XFA_NODEITEM_Parent));
1693        }
1694      }
1695    } break;
1696    case XFA_Element::Comb: {
1697      CXFA_Node* pEditNode = GetNodeItem(XFA_NODEITEM_Parent);
1698      XFA_Element eUIType = pEditNode->GetElementType();
1699      if (pEditNode && (eUIType == XFA_Element::DateTimeEdit ||
1700                        eUIType == XFA_Element::NumericEdit ||
1701                        eUIType == XFA_Element::TextEdit)) {
1702        CXFA_Node* pUINode = pEditNode->GetNodeItem(XFA_NODEITEM_Parent);
1703        if (pUINode) {
1704          pNotify->OnValueChanged(this, eAttribute, pUINode,
1705                                  pUINode->GetNodeItem(XFA_NODEITEM_Parent));
1706        }
1707      }
1708    } break;
1709    case XFA_Element::Button:
1710    case XFA_Element::Barcode:
1711    case XFA_Element::ChoiceList:
1712    case XFA_Element::DateTimeEdit:
1713    case XFA_Element::NumericEdit:
1714    case XFA_Element::PasswordEdit:
1715    case XFA_Element::TextEdit: {
1716      CXFA_Node* pUINode = GetNodeItem(XFA_NODEITEM_Parent);
1717      if (pUINode) {
1718        pNotify->OnValueChanged(this, eAttribute, pUINode,
1719                                pUINode->GetNodeItem(XFA_NODEITEM_Parent));
1720      }
1721    } break;
1722    case XFA_Element::CheckButton: {
1723      bNeedFindContainer = true;
1724      CXFA_Node* pUINode = GetNodeItem(XFA_NODEITEM_Parent);
1725      if (pUINode) {
1726        pNotify->OnValueChanged(this, eAttribute, pUINode,
1727                                pUINode->GetNodeItem(XFA_NODEITEM_Parent));
1728      }
1729    } break;
1730    case XFA_Element::Keep:
1731    case XFA_Element::Bookend:
1732    case XFA_Element::Break:
1733    case XFA_Element::BreakAfter:
1734    case XFA_Element::BreakBefore:
1735    case XFA_Element::Overflow:
1736      bNeedFindContainer = true;
1737      break;
1738    case XFA_Element::Area:
1739    case XFA_Element::Draw:
1740    case XFA_Element::ExclGroup:
1741    case XFA_Element::Field:
1742    case XFA_Element::Subform:
1743    case XFA_Element::SubformSet:
1744      pLayoutPro->AddChangedContainer(this);
1745      pNotify->OnValueChanged(this, eAttribute, this, this);
1746      break;
1747    case XFA_Element::Sharptext:
1748    case XFA_Element::Sharpxml:
1749    case XFA_Element::SharpxHTML: {
1750      CXFA_Node* pTextNode = GetNodeItem(XFA_NODEITEM_Parent);
1751      if (!pTextNode) {
1752        return;
1753      }
1754      CXFA_Node* pValueNode = pTextNode->GetNodeItem(XFA_NODEITEM_Parent);
1755      if (!pValueNode) {
1756        return;
1757      }
1758      XFA_Element eType = pValueNode->GetElementType();
1759      if (eType == XFA_Element::Value) {
1760        bNeedFindContainer = true;
1761        CXFA_Node* pNode = pValueNode->GetNodeItem(XFA_NODEITEM_Parent);
1762        if (pNode && pNode->IsContainerNode()) {
1763          if (bScriptModify) {
1764            pValueNode = pNode;
1765          }
1766          pNotify->OnValueChanged(this, eAttribute, pValueNode, pNode);
1767        } else {
1768          pNotify->OnValueChanged(this, eAttribute, pNode,
1769                                  pNode->GetNodeItem(XFA_NODEITEM_Parent));
1770        }
1771      } else {
1772        if (eType == XFA_Element::Items) {
1773          CXFA_Node* pNode = pValueNode->GetNodeItem(XFA_NODEITEM_Parent);
1774          if (pNode && pNode->IsContainerNode()) {
1775            pNotify->OnValueChanged(this, eAttribute, pValueNode, pNode);
1776          }
1777        }
1778      }
1779    } break;
1780    default:
1781      break;
1782  }
1783  if (bNeedFindContainer) {
1784    CXFA_Node* pParent = this;
1785    while (pParent) {
1786      if (pParent->IsContainerNode())
1787        break;
1788
1789      pParent = pParent->GetNodeItem(XFA_NODEITEM_Parent);
1790    }
1791    if (pParent) {
1792      pLayoutPro->AddChangedContainer(pParent);
1793    }
1794  }
1795}
1796
1797void CXFA_Node::Script_Attribute_String(CFXJSE_Value* pValue,
1798                                        bool bSetting,
1799                                        XFA_ATTRIBUTE eAttribute) {
1800  if (bSetting) {
1801    CFX_WideString wsValue = pValue->ToWideString();
1802    SetAttribute(eAttribute, wsValue.AsStringC(), true);
1803    if (eAttribute == XFA_ATTRIBUTE_Use &&
1804        GetElementType() == XFA_Element::Desc) {
1805      CXFA_Node* pTemplateNode =
1806          ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Template));
1807      CXFA_Node* pProtoRoot =
1808          pTemplateNode->GetFirstChildByClass(XFA_Element::Subform)
1809              ->GetFirstChildByClass(XFA_Element::Proto);
1810
1811      CFX_WideString wsID;
1812      CFX_WideString wsSOM;
1813      if (!wsValue.IsEmpty()) {
1814        if (wsValue[0] == '#') {
1815          wsID = CFX_WideString(wsValue.c_str() + 1, wsValue.GetLength() - 1);
1816        } else {
1817          wsSOM = wsValue;
1818        }
1819      }
1820      CXFA_Node* pProtoNode = nullptr;
1821      if (!wsSOM.IsEmpty()) {
1822        uint32_t dwFlag = XFA_RESOLVENODE_Children |
1823                          XFA_RESOLVENODE_Attributes |
1824                          XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Parent |
1825                          XFA_RESOLVENODE_Siblings;
1826        XFA_RESOLVENODE_RS resoveNodeRS;
1827        int32_t iRet = m_pDocument->GetScriptContext()->ResolveObjects(
1828            pProtoRoot, wsSOM.AsStringC(), resoveNodeRS, dwFlag);
1829        if (iRet > 0 && resoveNodeRS.nodes[0]->IsNode()) {
1830          pProtoNode = resoveNodeRS.nodes[0]->AsNode();
1831        }
1832      } else if (!wsID.IsEmpty()) {
1833        pProtoNode = m_pDocument->GetNodeByID(pProtoRoot, wsID.AsStringC());
1834      }
1835      if (pProtoNode) {
1836        CXFA_Node* pHeadChild = GetNodeItem(XFA_NODEITEM_FirstChild);
1837        while (pHeadChild) {
1838          CXFA_Node* pSibling =
1839              pHeadChild->GetNodeItem(XFA_NODEITEM_NextSibling);
1840          RemoveChild(pHeadChild);
1841          pHeadChild = pSibling;
1842        }
1843        CXFA_Node* pProtoForm = pProtoNode->CloneTemplateToForm(true);
1844        pHeadChild = pProtoForm->GetNodeItem(XFA_NODEITEM_FirstChild);
1845        while (pHeadChild) {
1846          CXFA_Node* pSibling =
1847              pHeadChild->GetNodeItem(XFA_NODEITEM_NextSibling);
1848          pProtoForm->RemoveChild(pHeadChild);
1849          InsertChild(pHeadChild);
1850          pHeadChild = pSibling;
1851        }
1852        m_pDocument->RemovePurgeNode(pProtoForm);
1853        delete pProtoForm;
1854      }
1855    }
1856  } else {
1857    CFX_WideString wsValue;
1858    GetAttribute(eAttribute, wsValue);
1859    pValue->SetString(wsValue.UTF8Encode().AsStringC());
1860  }
1861}
1862
1863void CXFA_Node::Script_Attribute_StringRead(CFXJSE_Value* pValue,
1864                                            bool bSetting,
1865                                            XFA_ATTRIBUTE eAttribute) {
1866  if (bSetting) {
1867    ThrowInvalidPropertyException();
1868    return;
1869  }
1870
1871  CFX_WideString wsValue;
1872  GetAttribute(eAttribute, wsValue);
1873  pValue->SetString(wsValue.UTF8Encode().AsStringC());
1874}
1875
1876void CXFA_Node::Script_WsdlConnection_Execute(CFXJSE_Arguments* pArguments) {
1877  int32_t argc = pArguments->GetLength();
1878  if (argc != 0 && argc != 1) {
1879    ThrowParamCountMismatchException(L"execute");
1880    return;
1881  }
1882  pArguments->GetReturnValue()->SetBoolean(false);
1883}
1884
1885void CXFA_Node::Script_Delta_Restore(CFXJSE_Arguments* pArguments) {
1886  if (pArguments->GetLength() != 0)
1887    ThrowParamCountMismatchException(L"restore");
1888}
1889
1890void CXFA_Node::Script_Delta_CurrentValue(CFXJSE_Value* pValue,
1891                                          bool bSetting,
1892                                          XFA_ATTRIBUTE eAttribute) {}
1893
1894void CXFA_Node::Script_Delta_SavedValue(CFXJSE_Value* pValue,
1895                                        bool bSetting,
1896                                        XFA_ATTRIBUTE eAttribute) {}
1897
1898void CXFA_Node::Script_Delta_Target(CFXJSE_Value* pValue,
1899                                    bool bSetting,
1900                                    XFA_ATTRIBUTE eAttribute) {}
1901
1902void CXFA_Node::Script_Som_Message(CFXJSE_Value* pValue,
1903                                   bool bSetting,
1904                                   XFA_SOM_MESSAGETYPE iMessageType) {
1905  CXFA_WidgetData* pWidgetData = GetWidgetData();
1906  if (!pWidgetData) {
1907    return;
1908  }
1909  bool bNew = false;
1910  CXFA_Validate validate = pWidgetData->GetValidate();
1911  if (!validate) {
1912    validate = pWidgetData->GetValidate(true);
1913    bNew = true;
1914  }
1915  if (bSetting) {
1916    switch (iMessageType) {
1917      case XFA_SOM_ValidationMessage:
1918        validate.SetScriptMessageText(pValue->ToWideString());
1919        break;
1920      case XFA_SOM_FormatMessage:
1921        validate.SetFormatMessageText(pValue->ToWideString());
1922        break;
1923      case XFA_SOM_MandatoryMessage:
1924        validate.SetNullMessageText(pValue->ToWideString());
1925        break;
1926      default:
1927        break;
1928    }
1929    if (!bNew) {
1930      CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
1931      if (!pNotify) {
1932        return;
1933      }
1934      pNotify->AddCalcValidate(this);
1935    }
1936  } else {
1937    CFX_WideString wsMessage;
1938    switch (iMessageType) {
1939      case XFA_SOM_ValidationMessage:
1940        validate.GetScriptMessageText(wsMessage);
1941        break;
1942      case XFA_SOM_FormatMessage:
1943        validate.GetFormatMessageText(wsMessage);
1944        break;
1945      case XFA_SOM_MandatoryMessage:
1946        validate.GetNullMessageText(wsMessage);
1947        break;
1948      default:
1949        break;
1950    }
1951    pValue->SetString(wsMessage.UTF8Encode().AsStringC());
1952  }
1953}
1954
1955void CXFA_Node::Script_Som_ValidationMessage(CFXJSE_Value* pValue,
1956                                             bool bSetting,
1957                                             XFA_ATTRIBUTE eAttribute) {
1958  Script_Som_Message(pValue, bSetting, XFA_SOM_ValidationMessage);
1959}
1960
1961void CXFA_Node::Script_Field_Length(CFXJSE_Value* pValue,
1962                                    bool bSetting,
1963                                    XFA_ATTRIBUTE eAttribute) {
1964  if (bSetting) {
1965    ThrowInvalidPropertyException();
1966    return;
1967  }
1968
1969  CXFA_WidgetData* pWidgetData = GetWidgetData();
1970  if (!pWidgetData) {
1971    pValue->SetInteger(0);
1972    return;
1973  }
1974  pValue->SetInteger(pWidgetData->CountChoiceListItems(true));
1975}
1976
1977void CXFA_Node::Script_Som_DefaultValue(CFXJSE_Value* pValue,
1978                                        bool bSetting,
1979                                        XFA_ATTRIBUTE eAttribute) {
1980  XFA_Element eType = GetElementType();
1981  if (eType == XFA_Element::Field) {
1982    Script_Field_DefaultValue(pValue, bSetting, eAttribute);
1983    return;
1984  }
1985  if (eType == XFA_Element::Draw) {
1986    Script_Draw_DefaultValue(pValue, bSetting, eAttribute);
1987    return;
1988  }
1989  if (eType == XFA_Element::Boolean) {
1990    Script_Boolean_Value(pValue, bSetting, eAttribute);
1991    return;
1992  }
1993  if (bSetting) {
1994    CFX_WideString wsNewValue;
1995    if (!(pValue && (pValue->IsNull() || pValue->IsUndefined())))
1996      wsNewValue = pValue->ToWideString();
1997
1998    CFX_WideString wsFormatValue(wsNewValue);
1999    CXFA_WidgetData* pContainerWidgetData = nullptr;
2000    if (GetPacketID() == XFA_XDPPACKET_Datasets) {
2001      CXFA_NodeArray formNodes;
2002      GetBindItems(formNodes);
2003      CFX_WideString wsPicture;
2004      for (int32_t i = 0; i < formNodes.GetSize(); i++) {
2005        CXFA_Node* pFormNode = formNodes.GetAt(i);
2006        if (!pFormNode || pFormNode->HasRemovedChildren()) {
2007          continue;
2008        }
2009        pContainerWidgetData = pFormNode->GetContainerWidgetData();
2010        if (pContainerWidgetData) {
2011          pContainerWidgetData->GetPictureContent(wsPicture,
2012                                                  XFA_VALUEPICTURE_DataBind);
2013        }
2014        if (!wsPicture.IsEmpty()) {
2015          break;
2016        }
2017        pContainerWidgetData = nullptr;
2018      }
2019    } else if (GetPacketID() == XFA_XDPPACKET_Form) {
2020      pContainerWidgetData = GetContainerWidgetData();
2021    }
2022    if (pContainerWidgetData) {
2023      pContainerWidgetData->GetFormatDataValue(wsNewValue, wsFormatValue);
2024    }
2025    SetScriptContent(wsNewValue, wsFormatValue, true, true);
2026  } else {
2027    CFX_WideString content = GetScriptContent(true);
2028    if (content.IsEmpty() && eType != XFA_Element::Text &&
2029        eType != XFA_Element::SubmitUrl) {
2030      pValue->SetNull();
2031    } else if (eType == XFA_Element::Integer) {
2032      pValue->SetInteger(FXSYS_wtoi(content.c_str()));
2033    } else if (eType == XFA_Element::Float || eType == XFA_Element::Decimal) {
2034      CFX_Decimal decimal(content.AsStringC());
2035      pValue->SetFloat((FX_FLOAT)(double)decimal);
2036    } else {
2037      pValue->SetString(content.UTF8Encode().AsStringC());
2038    }
2039  }
2040}
2041
2042void CXFA_Node::Script_Som_DefaultValue_Read(CFXJSE_Value* pValue,
2043                                             bool bSetting,
2044                                             XFA_ATTRIBUTE eAttribute) {
2045  if (bSetting) {
2046    ThrowInvalidPropertyException();
2047    return;
2048  }
2049
2050  CFX_WideString content = GetScriptContent(true);
2051  if (content.IsEmpty()) {
2052    pValue->SetNull();
2053    return;
2054  }
2055  pValue->SetString(content.UTF8Encode().AsStringC());
2056}
2057
2058void CXFA_Node::Script_Boolean_Value(CFXJSE_Value* pValue,
2059                                     bool bSetting,
2060                                     XFA_ATTRIBUTE eAttribute) {
2061  if (bSetting) {
2062    CFX_ByteString newValue;
2063    if (!(pValue && (pValue->IsNull() || pValue->IsUndefined())))
2064      newValue = pValue->ToString();
2065
2066    int32_t iValue = FXSYS_atoi(newValue.c_str());
2067    CFX_WideString wsNewValue(iValue == 0 ? L"0" : L"1");
2068    CFX_WideString wsFormatValue(wsNewValue);
2069    CXFA_WidgetData* pContainerWidgetData = GetContainerWidgetData();
2070    if (pContainerWidgetData) {
2071      pContainerWidgetData->GetFormatDataValue(wsNewValue, wsFormatValue);
2072    }
2073    SetScriptContent(wsNewValue, wsFormatValue, true, true);
2074  } else {
2075    CFX_WideString wsValue = GetScriptContent(true);
2076    pValue->SetBoolean(wsValue == L"1");
2077  }
2078}
2079
2080void CXFA_Node::Script_Som_BorderColor(CFXJSE_Value* pValue,
2081                                       bool bSetting,
2082                                       XFA_ATTRIBUTE eAttribute) {
2083  CXFA_WidgetData* pWidgetData = GetWidgetData();
2084  if (!pWidgetData) {
2085    return;
2086  }
2087  CXFA_Border border = pWidgetData->GetBorder(true);
2088  int32_t iSize = border.CountEdges();
2089  if (bSetting) {
2090    int32_t r = 0;
2091    int32_t g = 0;
2092    int32_t b = 0;
2093    StrToRGB(pValue->ToWideString(), r, g, b);
2094    FX_ARGB rgb = ArgbEncode(100, r, g, b);
2095    for (int32_t i = 0; i < iSize; ++i) {
2096      CXFA_Edge edge = border.GetEdge(i);
2097      edge.SetColor(rgb);
2098    }
2099  } else {
2100    CXFA_Edge edge = border.GetEdge(0);
2101    FX_ARGB color = edge.GetColor();
2102    int32_t a, r, g, b;
2103    ArgbDecode(color, a, r, g, b);
2104    CFX_WideString strColor;
2105    strColor.Format(L"%d,%d,%d", r, g, b);
2106    pValue->SetString(strColor.UTF8Encode().AsStringC());
2107  }
2108}
2109
2110void CXFA_Node::Script_Som_BorderWidth(CFXJSE_Value* pValue,
2111                                       bool bSetting,
2112                                       XFA_ATTRIBUTE eAttribute) {
2113  CXFA_WidgetData* pWidgetData = GetWidgetData();
2114  if (!pWidgetData) {
2115    return;
2116  }
2117  CXFA_Border border = pWidgetData->GetBorder(true);
2118  int32_t iSize = border.CountEdges();
2119  CFX_WideString wsThickness;
2120  if (bSetting) {
2121    wsThickness = pValue->ToWideString();
2122    for (int32_t i = 0; i < iSize; ++i) {
2123      CXFA_Edge edge = border.GetEdge(i);
2124      CXFA_Measurement thickness(wsThickness.AsStringC());
2125      edge.SetMSThickness(thickness);
2126    }
2127  } else {
2128    CXFA_Edge edge = border.GetEdge(0);
2129    CXFA_Measurement thickness = edge.GetMSThickness();
2130    thickness.ToString(wsThickness);
2131    pValue->SetString(wsThickness.UTF8Encode().AsStringC());
2132  }
2133}
2134
2135void CXFA_Node::Script_Som_FillColor(CFXJSE_Value* pValue,
2136                                     bool bSetting,
2137                                     XFA_ATTRIBUTE eAttribute) {
2138  CXFA_WidgetData* pWidgetData = GetWidgetData();
2139  if (!pWidgetData) {
2140    return;
2141  }
2142  CXFA_Border border = pWidgetData->GetBorder(true);
2143  CXFA_Fill borderfill = border.GetFill(true);
2144  CXFA_Node* pNode = borderfill.GetNode();
2145  if (!pNode) {
2146    return;
2147  }
2148  if (bSetting) {
2149    int32_t r;
2150    int32_t g;
2151    int32_t b;
2152    StrToRGB(pValue->ToWideString(), r, g, b);
2153    FX_ARGB color = ArgbEncode(0xff, r, g, b);
2154    borderfill.SetColor(color);
2155  } else {
2156    FX_ARGB color = borderfill.GetColor();
2157    int32_t a;
2158    int32_t r;
2159    int32_t g;
2160    int32_t b;
2161    ArgbDecode(color, a, r, g, b);
2162    CFX_WideString wsColor;
2163    wsColor.Format(L"%d,%d,%d", r, g, b);
2164    pValue->SetString(wsColor.UTF8Encode().AsStringC());
2165  }
2166}
2167
2168void CXFA_Node::Script_Som_DataNode(CFXJSE_Value* pValue,
2169                                    bool bSetting,
2170                                    XFA_ATTRIBUTE eAttribute) {
2171  if (bSetting) {
2172    ThrowInvalidPropertyException();
2173    return;
2174  }
2175
2176  CXFA_Node* pDataNode = GetBindData();
2177  if (!pDataNode) {
2178    pValue->SetNull();
2179    return;
2180  }
2181
2182  pValue->Assign(m_pDocument->GetScriptContext()->GetJSValueFromMap(pDataNode));
2183}
2184
2185void CXFA_Node::Script_Draw_DefaultValue(CFXJSE_Value* pValue,
2186                                         bool bSetting,
2187                                         XFA_ATTRIBUTE eAttribute) {
2188  if (bSetting) {
2189    if (pValue && pValue->IsString()) {
2190      CXFA_WidgetData* pWidgetData = GetWidgetData();
2191      ASSERT(pWidgetData);
2192      XFA_Element uiType = pWidgetData->GetUIType();
2193      if (uiType == XFA_Element::Text) {
2194        CFX_WideString wsNewValue = pValue->ToWideString();
2195        CFX_WideString wsFormatValue(wsNewValue);
2196        SetScriptContent(wsNewValue, wsFormatValue, true, true);
2197      }
2198    }
2199  } else {
2200    CFX_WideString content = GetScriptContent(true);
2201    if (content.IsEmpty())
2202      pValue->SetNull();
2203    else
2204      pValue->SetString(content.UTF8Encode().AsStringC());
2205  }
2206}
2207
2208void CXFA_Node::Script_Field_DefaultValue(CFXJSE_Value* pValue,
2209                                          bool bSetting,
2210                                          XFA_ATTRIBUTE eAttribute) {
2211  CXFA_WidgetData* pWidgetData = GetWidgetData();
2212  if (!pWidgetData) {
2213    return;
2214  }
2215  if (bSetting) {
2216    if (pValue && pValue->IsNull()) {
2217      pWidgetData->m_bPreNull = pWidgetData->m_bIsNull;
2218      pWidgetData->m_bIsNull = true;
2219    } else {
2220      pWidgetData->m_bPreNull = pWidgetData->m_bIsNull;
2221      pWidgetData->m_bIsNull = false;
2222    }
2223    CFX_WideString wsNewText;
2224    if (!(pValue && (pValue->IsNull() || pValue->IsUndefined())))
2225      wsNewText = pValue->ToWideString();
2226
2227    CXFA_Node* pUIChild = pWidgetData->GetUIChild();
2228    if (pUIChild->GetElementType() == XFA_Element::NumericEdit) {
2229      int32_t iLeadDigits = 0;
2230      int32_t iFracDigits = 0;
2231      pWidgetData->GetLeadDigits(iLeadDigits);
2232      pWidgetData->GetFracDigits(iFracDigits);
2233      wsNewText =
2234          pWidgetData->NumericLimit(wsNewText, iLeadDigits, iFracDigits);
2235    }
2236    CXFA_WidgetData* pContainerWidgetData = GetContainerWidgetData();
2237    CFX_WideString wsFormatText(wsNewText);
2238    if (pContainerWidgetData) {
2239      pContainerWidgetData->GetFormatDataValue(wsNewText, wsFormatText);
2240    }
2241    SetScriptContent(wsNewText, wsFormatText, true, true);
2242  } else {
2243    CFX_WideString content = GetScriptContent(true);
2244    if (content.IsEmpty()) {
2245      pValue->SetNull();
2246    } else {
2247      CXFA_Node* pUIChild = pWidgetData->GetUIChild();
2248      CXFA_Value defVal = pWidgetData->GetFormValue();
2249      CXFA_Node* pNode = defVal.GetNode()->GetNodeItem(XFA_NODEITEM_FirstChild);
2250      if (pNode && pNode->GetElementType() == XFA_Element::Decimal) {
2251        if (pUIChild->GetElementType() == XFA_Element::NumericEdit &&
2252            (pNode->GetInteger(XFA_ATTRIBUTE_FracDigits) == -1)) {
2253          pValue->SetString(content.UTF8Encode().AsStringC());
2254        } else {
2255          CFX_Decimal decimal(content.AsStringC());
2256          pValue->SetFloat((FX_FLOAT)(double)decimal);
2257        }
2258      } else if (pNode && pNode->GetElementType() == XFA_Element::Integer) {
2259        pValue->SetInteger(FXSYS_wtoi(content.c_str()));
2260      } else if (pNode && pNode->GetElementType() == XFA_Element::Boolean) {
2261        pValue->SetBoolean(FXSYS_wtoi(content.c_str()) == 0 ? false : true);
2262      } else if (pNode && pNode->GetElementType() == XFA_Element::Float) {
2263        CFX_Decimal decimal(content.AsStringC());
2264        pValue->SetFloat((FX_FLOAT)(double)decimal);
2265      } else {
2266        pValue->SetString(content.UTF8Encode().AsStringC());
2267      }
2268    }
2269  }
2270}
2271
2272void CXFA_Node::Script_Field_EditValue(CFXJSE_Value* pValue,
2273                                       bool bSetting,
2274                                       XFA_ATTRIBUTE eAttribute) {
2275  CXFA_WidgetData* pWidgetData = GetWidgetData();
2276  if (!pWidgetData) {
2277    return;
2278  }
2279  if (bSetting) {
2280    pWidgetData->SetValue(pValue->ToWideString(), XFA_VALUEPICTURE_Edit);
2281  } else {
2282    CFX_WideString wsValue;
2283    pWidgetData->GetValue(wsValue, XFA_VALUEPICTURE_Edit);
2284    pValue->SetString(wsValue.UTF8Encode().AsStringC());
2285  }
2286}
2287
2288void CXFA_Node::Script_Som_FontColor(CFXJSE_Value* pValue,
2289                                     bool bSetting,
2290                                     XFA_ATTRIBUTE eAttribute) {
2291  CXFA_WidgetData* pWidgetData = GetWidgetData();
2292  if (!pWidgetData) {
2293    return;
2294  }
2295  CXFA_Font font = pWidgetData->GetFont(true);
2296  CXFA_Node* pNode = font.GetNode();
2297  if (!pNode) {
2298    return;
2299  }
2300  if (bSetting) {
2301    int32_t r;
2302    int32_t g;
2303    int32_t b;
2304    StrToRGB(pValue->ToWideString(), r, g, b);
2305    FX_ARGB color = ArgbEncode(0xff, r, g, b);
2306    font.SetColor(color);
2307  } else {
2308    FX_ARGB color = font.GetColor();
2309    int32_t a;
2310    int32_t r;
2311    int32_t g;
2312    int32_t b;
2313    ArgbDecode(color, a, r, g, b);
2314    CFX_WideString wsColor;
2315    wsColor.Format(L"%d,%d,%d", r, g, b);
2316    pValue->SetString(wsColor.UTF8Encode().AsStringC());
2317  }
2318}
2319
2320void CXFA_Node::Script_Field_FormatMessage(CFXJSE_Value* pValue,
2321                                           bool bSetting,
2322                                           XFA_ATTRIBUTE eAttribute) {
2323  Script_Som_Message(pValue, bSetting, XFA_SOM_FormatMessage);
2324}
2325
2326void CXFA_Node::Script_Field_FormattedValue(CFXJSE_Value* pValue,
2327                                            bool bSetting,
2328                                            XFA_ATTRIBUTE eAttribute) {
2329  CXFA_WidgetData* pWidgetData = GetWidgetData();
2330  if (!pWidgetData) {
2331    return;
2332  }
2333  if (bSetting) {
2334    pWidgetData->SetValue(pValue->ToWideString(), XFA_VALUEPICTURE_Display);
2335  } else {
2336    CFX_WideString wsValue;
2337    pWidgetData->GetValue(wsValue, XFA_VALUEPICTURE_Display);
2338    pValue->SetString(wsValue.UTF8Encode().AsStringC());
2339  }
2340}
2341
2342void CXFA_Node::Script_Som_Mandatory(CFXJSE_Value* pValue,
2343                                     bool bSetting,
2344                                     XFA_ATTRIBUTE eAttribute) {
2345  CXFA_WidgetData* pWidgetData = GetWidgetData();
2346  if (!pWidgetData) {
2347    return;
2348  }
2349  CXFA_Validate validate = pWidgetData->GetValidate(true);
2350  if (bSetting) {
2351    validate.SetNullTest(pValue->ToWideString());
2352  } else {
2353    int32_t iValue = validate.GetNullTest();
2354    const XFA_ATTRIBUTEENUMINFO* pInfo =
2355        GetAttributeEnumByID((XFA_ATTRIBUTEENUM)iValue);
2356    CFX_WideString wsValue;
2357    if (pInfo)
2358      wsValue = pInfo->pName;
2359    pValue->SetString(wsValue.UTF8Encode().AsStringC());
2360  }
2361}
2362
2363void CXFA_Node::Script_Som_MandatoryMessage(CFXJSE_Value* pValue,
2364                                            bool bSetting,
2365                                            XFA_ATTRIBUTE eAttribute) {
2366  Script_Som_Message(pValue, bSetting, XFA_SOM_MandatoryMessage);
2367}
2368
2369void CXFA_Node::Script_Field_ParentSubform(CFXJSE_Value* pValue,
2370                                           bool bSetting,
2371                                           XFA_ATTRIBUTE eAttribute) {
2372  if (bSetting) {
2373    ThrowInvalidPropertyException();
2374    return;
2375  }
2376  pValue->SetNull();
2377}
2378
2379void CXFA_Node::Script_Field_SelectedIndex(CFXJSE_Value* pValue,
2380                                           bool bSetting,
2381                                           XFA_ATTRIBUTE eAttribute) {
2382  CXFA_WidgetData* pWidgetData = GetWidgetData();
2383  if (!pWidgetData) {
2384    return;
2385  }
2386  if (bSetting) {
2387    int32_t iIndex = pValue->ToInteger();
2388    if (iIndex == -1) {
2389      pWidgetData->ClearAllSelections();
2390      return;
2391    }
2392    pWidgetData->SetItemState(iIndex, true, true, true, true);
2393  } else {
2394    pValue->SetInteger(pWidgetData->GetSelectedItem());
2395  }
2396}
2397
2398void CXFA_Node::Script_Field_ClearItems(CFXJSE_Arguments* pArguments) {
2399  CXFA_WidgetData* pWidgetData = GetWidgetData();
2400  if (!pWidgetData) {
2401    return;
2402  }
2403  pWidgetData->DeleteItem(-1, true);
2404}
2405
2406void CXFA_Node::Script_Field_ExecEvent(CFXJSE_Arguments* pArguments) {
2407  if (pArguments->GetLength() != 1) {
2408    ThrowParamCountMismatchException(L"execEvent");
2409    return;
2410  }
2411
2412  CFX_ByteString eventString = pArguments->GetUTF8String(0);
2413  int32_t iRet = execSingleEventByName(
2414      CFX_WideString::FromUTF8(eventString.AsStringC()).AsStringC(),
2415      XFA_Element::Field);
2416  if (eventString != "validate")
2417    return;
2418
2419  pArguments->GetReturnValue()->SetBoolean(
2420      (iRet == XFA_EVENTERROR_Error) ? false : true);
2421}
2422
2423void CXFA_Node::Script_Field_ExecInitialize(CFXJSE_Arguments* pArguments) {
2424  if (pArguments->GetLength() != 0) {
2425    ThrowParamCountMismatchException(L"execInitialize");
2426    return;
2427  }
2428
2429  CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
2430  if (!pNotify)
2431    return;
2432
2433  pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Initialize, false, false);
2434}
2435
2436void CXFA_Node::Script_Field_DeleteItem(CFXJSE_Arguments* pArguments) {
2437  int32_t iLength = pArguments->GetLength();
2438  if (iLength != 1) {
2439    ThrowParamCountMismatchException(L"deleteItem");
2440    return;
2441  }
2442  CXFA_WidgetData* pWidgetData = GetWidgetData();
2443  if (!pWidgetData) {
2444    return;
2445  }
2446  int32_t iIndex = pArguments->GetInt32(0);
2447  bool bValue = pWidgetData->DeleteItem(iIndex, true, true);
2448  CFXJSE_Value* pValue = pArguments->GetReturnValue();
2449  if (pValue)
2450    pValue->SetBoolean(bValue);
2451}
2452
2453void CXFA_Node::Script_Field_GetSaveItem(CFXJSE_Arguments* pArguments) {
2454  int32_t iLength = pArguments->GetLength();
2455  if (iLength != 1) {
2456    ThrowParamCountMismatchException(L"getSaveItem");
2457    return;
2458  }
2459  int32_t iIndex = pArguments->GetInt32(0);
2460  if (iIndex < 0) {
2461    pArguments->GetReturnValue()->SetNull();
2462    return;
2463  }
2464  CXFA_WidgetData* pWidgetData = GetWidgetData();
2465  if (!pWidgetData) {
2466    pArguments->GetReturnValue()->SetNull();
2467    return;
2468  }
2469  CFX_WideString wsValue;
2470  if (!pWidgetData->GetChoiceListItem(wsValue, iIndex, true)) {
2471    pArguments->GetReturnValue()->SetNull();
2472    return;
2473  }
2474  pArguments->GetReturnValue()->SetString(wsValue.UTF8Encode().AsStringC());
2475}
2476
2477void CXFA_Node::Script_Field_BoundItem(CFXJSE_Arguments* pArguments) {
2478  int32_t iLength = pArguments->GetLength();
2479  if (iLength != 1) {
2480    ThrowParamCountMismatchException(L"boundItem");
2481    return;
2482  }
2483  CXFA_WidgetData* pWidgetData = GetWidgetData();
2484  if (!pWidgetData) {
2485    return;
2486  }
2487  CFX_ByteString bsValue = pArguments->GetUTF8String(0);
2488  CFX_WideString wsValue = CFX_WideString::FromUTF8(bsValue.AsStringC());
2489  CFX_WideString wsBoundValue;
2490  pWidgetData->GetItemValue(wsValue.AsStringC(), wsBoundValue);
2491  CFXJSE_Value* pValue = pArguments->GetReturnValue();
2492  if (pValue)
2493    pValue->SetString(wsBoundValue.UTF8Encode().AsStringC());
2494}
2495
2496void CXFA_Node::Script_Field_GetItemState(CFXJSE_Arguments* pArguments) {
2497  int32_t iLength = pArguments->GetLength();
2498  if (iLength != 1) {
2499    ThrowParamCountMismatchException(L"getItemState");
2500    return;
2501  }
2502  CXFA_WidgetData* pWidgetData = GetWidgetData();
2503  if (!pWidgetData) {
2504    return;
2505  }
2506  int32_t iIndex = pArguments->GetInt32(0);
2507  bool bValue = pWidgetData->GetItemState(iIndex);
2508  CFXJSE_Value* pValue = pArguments->GetReturnValue();
2509  if (pValue)
2510    pValue->SetBoolean(bValue);
2511}
2512
2513void CXFA_Node::Script_Field_ExecCalculate(CFXJSE_Arguments* pArguments) {
2514  if (pArguments->GetLength() != 0) {
2515    ThrowParamCountMismatchException(L"execCalculate");
2516    return;
2517  }
2518
2519  CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
2520  if (!pNotify)
2521    return;
2522
2523  pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Calculate, false, false);
2524}
2525
2526void CXFA_Node::Script_Field_SetItems(CFXJSE_Arguments* pArguments) {}
2527
2528void CXFA_Node::Script_Field_GetDisplayItem(CFXJSE_Arguments* pArguments) {
2529  int32_t iLength = pArguments->GetLength();
2530  if (iLength != 1) {
2531    ThrowParamCountMismatchException(L"getDisplayItem");
2532    return;
2533  }
2534  int32_t iIndex = pArguments->GetInt32(0);
2535  if (iIndex < 0) {
2536    pArguments->GetReturnValue()->SetNull();
2537    return;
2538  }
2539  CXFA_WidgetData* pWidgetData = GetWidgetData();
2540  if (!pWidgetData) {
2541    pArguments->GetReturnValue()->SetNull();
2542    return;
2543  }
2544  CFX_WideString wsValue;
2545  if (!pWidgetData->GetChoiceListItem(wsValue, iIndex, false)) {
2546    pArguments->GetReturnValue()->SetNull();
2547    return;
2548  }
2549  pArguments->GetReturnValue()->SetString(wsValue.UTF8Encode().AsStringC());
2550}
2551
2552void CXFA_Node::Script_Field_SetItemState(CFXJSE_Arguments* pArguments) {
2553  int32_t iLength = pArguments->GetLength();
2554  if (iLength != 2) {
2555    ThrowParamCountMismatchException(L"setItemState");
2556    return;
2557  }
2558  CXFA_WidgetData* pWidgetData = GetWidgetData();
2559  if (!pWidgetData)
2560    return;
2561
2562  int32_t iIndex = pArguments->GetInt32(0);
2563  if (pArguments->GetInt32(1) != 0) {
2564    pWidgetData->SetItemState(iIndex, true, true, true, true);
2565  } else {
2566    if (pWidgetData->GetItemState(iIndex))
2567      pWidgetData->SetItemState(iIndex, false, true, true, true);
2568  }
2569}
2570
2571void CXFA_Node::Script_Field_AddItem(CFXJSE_Arguments* pArguments) {
2572  int32_t iLength = pArguments->GetLength();
2573  if (iLength < 1 || iLength > 2) {
2574    ThrowParamCountMismatchException(L"addItem");
2575    return;
2576  }
2577  CXFA_WidgetData* pWidgetData = GetWidgetData();
2578  if (!pWidgetData) {
2579    return;
2580  }
2581  CFX_WideString wsLabel;
2582  CFX_WideString wsValue;
2583  if (iLength >= 1) {
2584    CFX_ByteString bsLabel = pArguments->GetUTF8String(0);
2585    wsLabel = CFX_WideString::FromUTF8(bsLabel.AsStringC());
2586  }
2587  if (iLength >= 2) {
2588    CFX_ByteString bsValue = pArguments->GetUTF8String(1);
2589    wsValue = CFX_WideString::FromUTF8(bsValue.AsStringC());
2590  }
2591  pWidgetData->InsertItem(wsLabel, wsValue, -1, true);
2592}
2593
2594void CXFA_Node::Script_Field_ExecValidate(CFXJSE_Arguments* pArguments) {
2595  if (pArguments->GetLength() != 0) {
2596    ThrowParamCountMismatchException(L"execValidate");
2597    return;
2598  }
2599
2600  CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
2601  if (!pNotify) {
2602    pArguments->GetReturnValue()->SetBoolean(false);
2603    return;
2604  }
2605
2606  int32_t iRet =
2607      pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Validate, false, false);
2608  pArguments->GetReturnValue()->SetBoolean(
2609      (iRet == XFA_EVENTERROR_Error) ? false : true);
2610}
2611
2612void CXFA_Node::Script_ExclGroup_ErrorText(CFXJSE_Value* pValue,
2613                                           bool bSetting,
2614                                           XFA_ATTRIBUTE eAttribute) {
2615  if (bSetting)
2616    ThrowInvalidPropertyException();
2617}
2618
2619void CXFA_Node::Script_ExclGroup_DefaultAndRawValue(CFXJSE_Value* pValue,
2620                                                    bool bSetting,
2621                                                    XFA_ATTRIBUTE eAttribute) {
2622  CXFA_WidgetData* pWidgetData = GetWidgetData();
2623  if (!pWidgetData) {
2624    return;
2625  }
2626  if (bSetting) {
2627    pWidgetData->SetSelectedMemberByValue(pValue->ToWideString().AsStringC(),
2628                                          true, true, true);
2629  } else {
2630    CFX_WideString wsValue = GetScriptContent(true);
2631    XFA_VERSION curVersion = GetDocument()->GetCurVersionMode();
2632    if (wsValue.IsEmpty() && curVersion >= XFA_VERSION_300) {
2633      pValue->SetNull();
2634    } else {
2635      pValue->SetString(wsValue.UTF8Encode().AsStringC());
2636    }
2637  }
2638}
2639
2640void CXFA_Node::Script_ExclGroup_Transient(CFXJSE_Value* pValue,
2641                                           bool bSetting,
2642                                           XFA_ATTRIBUTE eAttribute) {}
2643
2644void CXFA_Node::Script_ExclGroup_ExecEvent(CFXJSE_Arguments* pArguments) {
2645  if (pArguments->GetLength() != 1) {
2646    ThrowParamCountMismatchException(L"execEvent");
2647    return;
2648  }
2649
2650  CFX_ByteString eventString = pArguments->GetUTF8String(0);
2651  execSingleEventByName(
2652      CFX_WideString::FromUTF8(eventString.AsStringC()).AsStringC(),
2653      XFA_Element::ExclGroup);
2654}
2655
2656void CXFA_Node::Script_ExclGroup_SelectedMember(CFXJSE_Arguments* pArguments) {
2657  int32_t argc = pArguments->GetLength();
2658  if (argc < 0 || argc > 1) {
2659    ThrowParamCountMismatchException(L"selectedMember");
2660    return;
2661  }
2662
2663  CXFA_WidgetData* pWidgetData = GetWidgetData();
2664  if (!pWidgetData) {
2665    pArguments->GetReturnValue()->SetNull();
2666    return;
2667  }
2668
2669  CXFA_Node* pReturnNode = nullptr;
2670  if (argc == 0) {
2671    pReturnNode = pWidgetData->GetSelectedMember();
2672  } else {
2673    CFX_ByteString szName;
2674    szName = pArguments->GetUTF8String(0);
2675    pReturnNode = pWidgetData->SetSelectedMember(
2676        CFX_WideString::FromUTF8(szName.AsStringC()).AsStringC(), true);
2677  }
2678  if (!pReturnNode) {
2679    pArguments->GetReturnValue()->SetNull();
2680    return;
2681  }
2682  pArguments->GetReturnValue()->Assign(
2683      m_pDocument->GetScriptContext()->GetJSValueFromMap(pReturnNode));
2684}
2685
2686void CXFA_Node::Script_ExclGroup_ExecInitialize(CFXJSE_Arguments* pArguments) {
2687  if (pArguments->GetLength() != 0) {
2688    ThrowParamCountMismatchException(L"execInitialize");
2689    return;
2690  }
2691
2692  CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
2693  if (!pNotify)
2694    return;
2695
2696  pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Initialize);
2697}
2698
2699void CXFA_Node::Script_ExclGroup_ExecCalculate(CFXJSE_Arguments* pArguments) {
2700  if (pArguments->GetLength() != 0) {
2701    ThrowParamCountMismatchException(L"execCalculate");
2702    return;
2703  }
2704
2705  CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
2706  if (!pNotify)
2707    return;
2708
2709  pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Calculate);
2710}
2711
2712void CXFA_Node::Script_ExclGroup_ExecValidate(CFXJSE_Arguments* pArguments) {
2713  if (pArguments->GetLength() != 0) {
2714    ThrowParamCountMismatchException(L"execValidate");
2715    return;
2716  }
2717
2718  CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
2719  if (!pNotify) {
2720    pArguments->GetReturnValue()->SetBoolean(false);
2721    return;
2722  }
2723
2724  int32_t iRet = pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Validate);
2725  pArguments->GetReturnValue()->SetBoolean(
2726      (iRet == XFA_EVENTERROR_Error) ? false : true);
2727}
2728
2729void CXFA_Node::Script_Som_InstanceIndex(CFXJSE_Value* pValue,
2730                                         bool bSetting,
2731                                         XFA_ATTRIBUTE eAttribute) {
2732  if (bSetting) {
2733    int32_t iTo = pValue->ToInteger();
2734    int32_t iFrom = Subform_and_SubformSet_InstanceIndex();
2735    CXFA_Node* pManagerNode = nullptr;
2736    for (CXFA_Node* pNode = GetNodeItem(XFA_NODEITEM_PrevSibling); pNode;
2737         pNode = pNode->GetNodeItem(XFA_NODEITEM_PrevSibling)) {
2738      if (pNode->GetElementType() == XFA_Element::InstanceManager) {
2739        pManagerNode = pNode;
2740        break;
2741      }
2742    }
2743    if (pManagerNode) {
2744      pManagerNode->InstanceManager_MoveInstance(iTo, iFrom);
2745      CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
2746      if (!pNotify) {
2747        return;
2748      }
2749      CXFA_Node* pToInstance = GetItem(pManagerNode, iTo);
2750      if (pToInstance &&
2751          pToInstance->GetElementType() == XFA_Element::Subform) {
2752        pNotify->RunSubformIndexChange(pToInstance);
2753      }
2754      CXFA_Node* pFromInstance = GetItem(pManagerNode, iFrom);
2755      if (pFromInstance &&
2756          pFromInstance->GetElementType() == XFA_Element::Subform) {
2757        pNotify->RunSubformIndexChange(pFromInstance);
2758      }
2759    }
2760  } else {
2761    pValue->SetInteger(Subform_and_SubformSet_InstanceIndex());
2762  }
2763}
2764
2765void CXFA_Node::Script_Subform_InstanceManager(CFXJSE_Value* pValue,
2766                                               bool bSetting,
2767                                               XFA_ATTRIBUTE eAttribute) {
2768  if (bSetting) {
2769    ThrowInvalidPropertyException();
2770    return;
2771  }
2772
2773  CFX_WideStringC wsName = GetCData(XFA_ATTRIBUTE_Name);
2774  CXFA_Node* pInstanceMgr = nullptr;
2775  for (CXFA_Node* pNode = GetNodeItem(XFA_NODEITEM_PrevSibling); pNode;
2776       pNode = pNode->GetNodeItem(XFA_NODEITEM_PrevSibling)) {
2777    if (pNode->GetElementType() == XFA_Element::InstanceManager) {
2778      CFX_WideStringC wsInstMgrName = pNode->GetCData(XFA_ATTRIBUTE_Name);
2779      if (wsInstMgrName.GetLength() >= 1 && wsInstMgrName.GetAt(0) == '_' &&
2780          wsInstMgrName.Mid(1) == wsName) {
2781        pInstanceMgr = pNode;
2782      }
2783      break;
2784    }
2785  }
2786  if (!pInstanceMgr) {
2787    pValue->SetNull();
2788    return;
2789  }
2790
2791  pValue->Assign(
2792      m_pDocument->GetScriptContext()->GetJSValueFromMap(pInstanceMgr));
2793}
2794
2795void CXFA_Node::Script_Subform_Locale(CFXJSE_Value* pValue,
2796                                      bool bSetting,
2797                                      XFA_ATTRIBUTE eAttribute) {
2798  if (bSetting) {
2799    SetCData(XFA_ATTRIBUTE_Locale, pValue->ToWideString(), true, true);
2800  } else {
2801    CFX_WideString wsLocaleName;
2802    GetLocaleName(wsLocaleName);
2803    pValue->SetString(wsLocaleName.UTF8Encode().AsStringC());
2804  }
2805}
2806
2807void CXFA_Node::Script_Subform_ExecEvent(CFXJSE_Arguments* pArguments) {
2808  if (pArguments->GetLength() != 1) {
2809    ThrowParamCountMismatchException(L"execEvent");
2810    return;
2811  }
2812
2813  CFX_ByteString eventString = pArguments->GetUTF8String(0);
2814  execSingleEventByName(
2815      CFX_WideString::FromUTF8(eventString.AsStringC()).AsStringC(),
2816      XFA_Element::Subform);
2817}
2818
2819void CXFA_Node::Script_Subform_ExecInitialize(CFXJSE_Arguments* pArguments) {
2820  if (pArguments->GetLength() != 0) {
2821    ThrowParamCountMismatchException(L"execInitialize");
2822    return;
2823  }
2824
2825  CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
2826  if (!pNotify)
2827    return;
2828
2829  pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Initialize);
2830}
2831
2832void CXFA_Node::Script_Subform_ExecCalculate(CFXJSE_Arguments* pArguments) {
2833  if (pArguments->GetLength() != 0) {
2834    ThrowParamCountMismatchException(L"execCalculate");
2835    return;
2836  }
2837
2838  CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
2839  if (!pNotify)
2840    return;
2841
2842  pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Calculate);
2843}
2844
2845void CXFA_Node::Script_Subform_ExecValidate(CFXJSE_Arguments* pArguments) {
2846  if (pArguments->GetLength() != 0) {
2847    ThrowParamCountMismatchException(L"execValidate");
2848    return;
2849  }
2850
2851  CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
2852  if (!pNotify) {
2853    pArguments->GetReturnValue()->SetBoolean(false);
2854    return;
2855  }
2856
2857  int32_t iRet = pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Validate);
2858  pArguments->GetReturnValue()->SetBoolean(
2859      (iRet == XFA_EVENTERROR_Error) ? false : true);
2860}
2861
2862void CXFA_Node::Script_Subform_GetInvalidObjects(CFXJSE_Arguments* pArguments) {
2863  if (pArguments->GetLength() != 0)
2864    ThrowParamCountMismatchException(L"getInvalidObjects");
2865}
2866
2867int32_t CXFA_Node::Subform_and_SubformSet_InstanceIndex() {
2868  int32_t index = 0;
2869  for (CXFA_Node* pNode = GetNodeItem(XFA_NODEITEM_PrevSibling); pNode;
2870       pNode = pNode->GetNodeItem(XFA_NODEITEM_PrevSibling)) {
2871    if ((pNode->GetElementType() == XFA_Element::Subform) ||
2872        (pNode->GetElementType() == XFA_Element::SubformSet)) {
2873      index++;
2874    } else {
2875      break;
2876    }
2877  }
2878  return index;
2879}
2880
2881void CXFA_Node::Script_Template_FormNodes(CFXJSE_Arguments* pArguments) {
2882  if (pArguments->GetLength() != 1) {
2883    ThrowParamCountMismatchException(L"formNodes");
2884    return;
2885  }
2886  pArguments->GetReturnValue()->SetBoolean(true);
2887}
2888
2889void CXFA_Node::Script_Template_Remerge(CFXJSE_Arguments* pArguments) {
2890  if (pArguments->GetLength() != 0) {
2891    ThrowParamCountMismatchException(L"remerge");
2892    return;
2893  }
2894  m_pDocument->DoDataRemerge(true);
2895}
2896
2897void CXFA_Node::Script_Template_ExecInitialize(CFXJSE_Arguments* pArguments) {
2898  if (pArguments->GetLength() != 0) {
2899    ThrowParamCountMismatchException(L"execInitialize");
2900    return;
2901  }
2902
2903  CXFA_WidgetData* pWidgetData = GetWidgetData();
2904  if (!pWidgetData) {
2905    pArguments->GetReturnValue()->SetBoolean(false);
2906    return;
2907  }
2908  pArguments->GetReturnValue()->SetBoolean(true);
2909}
2910
2911void CXFA_Node::Script_Template_CreateNode(CFXJSE_Arguments* pArguments) {
2912  int32_t argc = pArguments->GetLength();
2913  if (argc <= 0 || argc >= 4) {
2914    ThrowParamCountMismatchException(L"createNode");
2915    return;
2916  }
2917
2918  CFX_WideString strName;
2919  CFX_WideString strNameSpace;
2920  CFX_ByteString bsTagName = pArguments->GetUTF8String(0);
2921  CFX_WideString strTagName = CFX_WideString::FromUTF8(bsTagName.AsStringC());
2922  if (argc > 1) {
2923    CFX_ByteString bsName = pArguments->GetUTF8String(1);
2924    strName = CFX_WideString::FromUTF8(bsName.AsStringC());
2925    if (argc == 3) {
2926      CFX_ByteString bsNameSpace = pArguments->GetUTF8String(2);
2927      strNameSpace = CFX_WideString::FromUTF8(bsNameSpace.AsStringC());
2928    }
2929  }
2930
2931  XFA_Element eType = XFA_GetElementTypeForName(strTagName.AsStringC());
2932  CXFA_Node* pNewNode = CreateSamePacketNode(eType);
2933  if (!pNewNode) {
2934    pArguments->GetReturnValue()->SetNull();
2935    return;
2936  }
2937
2938  if (strName.IsEmpty()) {
2939    pArguments->GetReturnValue()->Assign(
2940        m_pDocument->GetScriptContext()->GetJSValueFromMap(pNewNode));
2941    return;
2942  }
2943
2944  if (!GetAttributeOfElement(eType, XFA_ATTRIBUTE_Name,
2945                             XFA_XDPPACKET_UNKNOWN)) {
2946    ThrowMissingPropertyException(strTagName, L"name");
2947    return;
2948  }
2949
2950  pNewNode->SetAttribute(XFA_ATTRIBUTE_Name, strName.AsStringC(), true);
2951  if (pNewNode->GetPacketID() == XFA_XDPPACKET_Datasets)
2952    pNewNode->CreateXMLMappingNode();
2953
2954  pArguments->GetReturnValue()->Assign(
2955      m_pDocument->GetScriptContext()->GetJSValueFromMap(pNewNode));
2956}
2957
2958void CXFA_Node::Script_Template_Recalculate(CFXJSE_Arguments* pArguments) {
2959  if (pArguments->GetLength() != 1) {
2960    ThrowParamCountMismatchException(L"recalculate");
2961    return;
2962  }
2963  pArguments->GetReturnValue()->SetBoolean(true);
2964}
2965
2966void CXFA_Node::Script_Template_ExecCalculate(CFXJSE_Arguments* pArguments) {
2967  if (pArguments->GetLength() != 0) {
2968    ThrowParamCountMismatchException(L"execCalculate");
2969    return;
2970  }
2971
2972  CXFA_WidgetData* pWidgetData = GetWidgetData();
2973  if (!pWidgetData) {
2974    pArguments->GetReturnValue()->SetBoolean(false);
2975    return;
2976  }
2977  pArguments->GetReturnValue()->SetBoolean(true);
2978}
2979
2980void CXFA_Node::Script_Template_ExecValidate(CFXJSE_Arguments* pArguments) {
2981  if (pArguments->GetLength() != 0) {
2982    ThrowParamCountMismatchException(L"execValidate");
2983    return;
2984  }
2985  CXFA_WidgetData* pWidgetData = GetWidgetData();
2986  if (!pWidgetData) {
2987    pArguments->GetReturnValue()->SetBoolean(false);
2988    return;
2989  }
2990  pArguments->GetReturnValue()->SetBoolean(true);
2991}
2992
2993void CXFA_Node::Script_Manifest_Evaluate(CFXJSE_Arguments* pArguments) {
2994  if (pArguments->GetLength() != 0) {
2995    ThrowParamCountMismatchException(L"evaluate");
2996    return;
2997  }
2998
2999  CXFA_WidgetData* pWidgetData = GetWidgetData();
3000  if (!pWidgetData) {
3001    pArguments->GetReturnValue()->SetBoolean(false);
3002    return;
3003  }
3004  pArguments->GetReturnValue()->SetBoolean(true);
3005}
3006
3007void CXFA_Node::Script_InstanceManager_Max(CFXJSE_Value* pValue,
3008                                           bool bSetting,
3009                                           XFA_ATTRIBUTE eAttribute) {
3010  if (bSetting) {
3011    ThrowInvalidPropertyException();
3012    return;
3013  }
3014  CXFA_Occur nodeOccur(GetOccurNode());
3015  pValue->SetInteger(nodeOccur.GetMax());
3016}
3017
3018void CXFA_Node::Script_InstanceManager_Min(CFXJSE_Value* pValue,
3019                                           bool bSetting,
3020                                           XFA_ATTRIBUTE eAttribute) {
3021  if (bSetting) {
3022    ThrowInvalidPropertyException();
3023    return;
3024  }
3025  CXFA_Occur nodeOccur(GetOccurNode());
3026  pValue->SetInteger(nodeOccur.GetMin());
3027}
3028
3029void CXFA_Node::Script_InstanceManager_Count(CFXJSE_Value* pValue,
3030                                             bool bSetting,
3031                                             XFA_ATTRIBUTE eAttribute) {
3032  if (bSetting) {
3033    int32_t iDesired = pValue->ToInteger();
3034    InstanceManager_SetInstances(iDesired);
3035  } else {
3036    pValue->SetInteger(GetCount(this));
3037  }
3038}
3039
3040void CXFA_Node::Script_InstanceManager_MoveInstance(
3041    CFXJSE_Arguments* pArguments) {
3042  if (pArguments->GetLength() != 2) {
3043    pArguments->GetReturnValue()->SetUndefined();
3044    return;
3045  }
3046  int32_t iFrom = pArguments->GetInt32(0);
3047  int32_t iTo = pArguments->GetInt32(1);
3048  InstanceManager_MoveInstance(iTo, iFrom);
3049  CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
3050  if (!pNotify) {
3051    return;
3052  }
3053  CXFA_Node* pToInstance = GetItem(this, iTo);
3054  if (pToInstance && pToInstance->GetElementType() == XFA_Element::Subform) {
3055    pNotify->RunSubformIndexChange(pToInstance);
3056  }
3057  CXFA_Node* pFromInstance = GetItem(this, iFrom);
3058  if (pFromInstance &&
3059      pFromInstance->GetElementType() == XFA_Element::Subform) {
3060    pNotify->RunSubformIndexChange(pFromInstance);
3061  }
3062}
3063
3064void CXFA_Node::Script_InstanceManager_RemoveInstance(
3065    CFXJSE_Arguments* pArguments) {
3066  if (pArguments->GetLength() != 1) {
3067    pArguments->GetReturnValue()->SetUndefined();
3068    return;
3069  }
3070  int32_t iIndex = pArguments->GetInt32(0);
3071  int32_t iCount = GetCount(this);
3072  if (iIndex < 0 || iIndex >= iCount) {
3073    ThrowIndexOutOfBoundsException();
3074    return;
3075  }
3076  CXFA_Occur nodeOccur(GetOccurNode());
3077  int32_t iMin = nodeOccur.GetMin();
3078  if (iCount - 1 < iMin) {
3079    ThrowTooManyOccurancesException(L"min");
3080    return;
3081  }
3082  CXFA_Node* pRemoveInstance = GetItem(this, iIndex);
3083  RemoveItem(this, pRemoveInstance);
3084  CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
3085  if (pNotify) {
3086    for (int32_t i = iIndex; i < iCount - 1; i++) {
3087      CXFA_Node* pSubformInstance = GetItem(this, i);
3088      if (pSubformInstance &&
3089          pSubformInstance->GetElementType() == XFA_Element::Subform) {
3090        pNotify->RunSubformIndexChange(pSubformInstance);
3091      }
3092    }
3093  }
3094  CXFA_LayoutProcessor* pLayoutPro = m_pDocument->GetLayoutProcessor();
3095  if (!pLayoutPro) {
3096    return;
3097  }
3098  pLayoutPro->AddChangedContainer(
3099      ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Form)));
3100}
3101
3102void CXFA_Node::Script_InstanceManager_SetInstances(
3103    CFXJSE_Arguments* pArguments) {
3104  if (pArguments->GetLength() != 1) {
3105    pArguments->GetReturnValue()->SetUndefined();
3106    return;
3107  }
3108  int32_t iDesired = pArguments->GetInt32(0);
3109  InstanceManager_SetInstances(iDesired);
3110}
3111
3112void CXFA_Node::Script_InstanceManager_AddInstance(
3113    CFXJSE_Arguments* pArguments) {
3114  int32_t argc = pArguments->GetLength();
3115  if (argc != 0 && argc != 1) {
3116    ThrowParamCountMismatchException(L"addInstance");
3117    return;
3118  }
3119  bool fFlags = true;
3120  if (argc == 1) {
3121    fFlags = pArguments->GetInt32(0) == 0 ? false : true;
3122  }
3123  int32_t iCount = GetCount(this);
3124  CXFA_Occur nodeOccur(GetOccurNode());
3125  int32_t iMax = nodeOccur.GetMax();
3126  if (iMax >= 0 && iCount >= iMax) {
3127    ThrowTooManyOccurancesException(L"max");
3128    return;
3129  }
3130  CXFA_Node* pNewInstance = CreateInstance(this, fFlags);
3131  InsertItem(this, pNewInstance, iCount, iCount, false);
3132  pArguments->GetReturnValue()->Assign(
3133      m_pDocument->GetScriptContext()->GetJSValueFromMap(pNewInstance));
3134  CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
3135  if (!pNotify) {
3136    return;
3137  }
3138  pNotify->RunNodeInitialize(pNewInstance);
3139  CXFA_LayoutProcessor* pLayoutPro = m_pDocument->GetLayoutProcessor();
3140  if (!pLayoutPro) {
3141    return;
3142  }
3143  pLayoutPro->AddChangedContainer(
3144      ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Form)));
3145}
3146
3147void CXFA_Node::Script_InstanceManager_InsertInstance(
3148    CFXJSE_Arguments* pArguments) {
3149  int32_t argc = pArguments->GetLength();
3150  if (argc != 1 && argc != 2) {
3151    ThrowParamCountMismatchException(L"insertInstance");
3152    return;
3153  }
3154  int32_t iIndex = pArguments->GetInt32(0);
3155  bool bBind = false;
3156  if (argc == 2) {
3157    bBind = pArguments->GetInt32(1) == 0 ? false : true;
3158  }
3159  CXFA_Occur nodeOccur(GetOccurNode());
3160  int32_t iCount = GetCount(this);
3161  if (iIndex < 0 || iIndex > iCount) {
3162    ThrowIndexOutOfBoundsException();
3163    return;
3164  }
3165  int32_t iMax = nodeOccur.GetMax();
3166  if (iMax >= 0 && iCount >= iMax) {
3167    ThrowTooManyOccurancesException(L"max");
3168    return;
3169  }
3170  CXFA_Node* pNewInstance = CreateInstance(this, bBind);
3171  InsertItem(this, pNewInstance, iIndex, iCount, true);
3172  pArguments->GetReturnValue()->Assign(
3173      m_pDocument->GetScriptContext()->GetJSValueFromMap(pNewInstance));
3174  CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
3175  if (!pNotify) {
3176    return;
3177  }
3178  pNotify->RunNodeInitialize(pNewInstance);
3179  CXFA_LayoutProcessor* pLayoutPro = m_pDocument->GetLayoutProcessor();
3180  if (!pLayoutPro) {
3181    return;
3182  }
3183  pLayoutPro->AddChangedContainer(
3184      ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Form)));
3185}
3186
3187int32_t CXFA_Node::InstanceManager_SetInstances(int32_t iDesired) {
3188  CXFA_Occur nodeOccur(GetOccurNode());
3189  int32_t iMax = nodeOccur.GetMax();
3190  int32_t iMin = nodeOccur.GetMin();
3191  if (iDesired < iMin) {
3192    ThrowTooManyOccurancesException(L"min");
3193    return 1;
3194  }
3195  if ((iMax >= 0) && (iDesired > iMax)) {
3196    ThrowTooManyOccurancesException(L"max");
3197    return 2;
3198  }
3199  int32_t iCount = GetCount(this);
3200  if (iDesired == iCount) {
3201    return 0;
3202  }
3203  if (iDesired < iCount) {
3204    CFX_WideStringC wsInstManagerName = GetCData(XFA_ATTRIBUTE_Name);
3205    CFX_WideString wsInstanceName =
3206        CFX_WideString(wsInstManagerName.IsEmpty() ? wsInstManagerName
3207                                                   : wsInstManagerName.Mid(1));
3208    uint32_t dInstanceNameHash =
3209        FX_HashCode_GetW(wsInstanceName.AsStringC(), false);
3210    CXFA_Node* pPrevSibling =
3211        (iDesired == 0) ? this : GetItem(this, iDesired - 1);
3212    while (iCount > iDesired) {
3213      CXFA_Node* pRemoveInstance =
3214          pPrevSibling->GetNodeItem(XFA_NODEITEM_NextSibling);
3215      if (pRemoveInstance->GetElementType() != XFA_Element::Subform &&
3216          pRemoveInstance->GetElementType() != XFA_Element::SubformSet) {
3217        continue;
3218      }
3219      if (pRemoveInstance->GetElementType() == XFA_Element::InstanceManager) {
3220        ASSERT(false);
3221        break;
3222      }
3223      if (pRemoveInstance->GetNameHash() == dInstanceNameHash) {
3224        RemoveItem(this, pRemoveInstance);
3225        iCount--;
3226      }
3227    }
3228  } else if (iDesired > iCount) {
3229    while (iCount < iDesired) {
3230      CXFA_Node* pNewInstance = CreateInstance(this, true);
3231      InsertItem(this, pNewInstance, iCount, iCount, false);
3232      iCount++;
3233      CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
3234      if (!pNotify) {
3235        return 0;
3236      }
3237      pNotify->RunNodeInitialize(pNewInstance);
3238    }
3239  }
3240  CXFA_LayoutProcessor* pLayoutPro = m_pDocument->GetLayoutProcessor();
3241  if (pLayoutPro) {
3242    pLayoutPro->AddChangedContainer(
3243        ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Form)));
3244  }
3245  return 0;
3246}
3247
3248int32_t CXFA_Node::InstanceManager_MoveInstance(int32_t iTo, int32_t iFrom) {
3249  int32_t iCount = GetCount(this);
3250  if (iFrom > iCount || iTo > iCount - 1) {
3251    ThrowIndexOutOfBoundsException();
3252    return 1;
3253  }
3254  if (iFrom < 0 || iTo < 0 || iFrom == iTo) {
3255    return 0;
3256  }
3257  CXFA_Node* pMoveInstance = GetItem(this, iFrom);
3258  RemoveItem(this, pMoveInstance, false);
3259  InsertItem(this, pMoveInstance, iTo, iCount - 1, true);
3260  CXFA_LayoutProcessor* pLayoutPro = m_pDocument->GetLayoutProcessor();
3261  if (pLayoutPro) {
3262    pLayoutPro->AddChangedContainer(
3263        ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Form)));
3264  }
3265  return 0;
3266}
3267
3268void CXFA_Node::Script_Occur_Max(CFXJSE_Value* pValue,
3269                                 bool bSetting,
3270                                 XFA_ATTRIBUTE eAttribute) {
3271  CXFA_Occur occur(this);
3272  if (bSetting) {
3273    int32_t iMax = pValue->ToInteger();
3274    occur.SetMax(iMax);
3275  } else {
3276    pValue->SetInteger(occur.GetMax());
3277  }
3278}
3279
3280void CXFA_Node::Script_Occur_Min(CFXJSE_Value* pValue,
3281                                 bool bSetting,
3282                                 XFA_ATTRIBUTE eAttribute) {
3283  CXFA_Occur occur(this);
3284  if (bSetting) {
3285    int32_t iMin = pValue->ToInteger();
3286    occur.SetMin(iMin);
3287  } else {
3288    pValue->SetInteger(occur.GetMin());
3289  }
3290}
3291
3292void CXFA_Node::Script_Desc_Metadata(CFXJSE_Arguments* pArguments) {
3293  int32_t argc = pArguments->GetLength();
3294  if (argc != 0 && argc != 1) {
3295    ThrowParamCountMismatchException(L"metadata");
3296    return;
3297  }
3298  pArguments->GetReturnValue()->SetString("");
3299}
3300
3301void CXFA_Node::Script_Form_FormNodes(CFXJSE_Arguments* pArguments) {
3302  if (pArguments->GetLength() != 1) {
3303    ThrowParamCountMismatchException(L"formNodes");
3304    return;
3305  }
3306
3307  CXFA_Node* pDataNode = static_cast<CXFA_Node*>(pArguments->GetObject(0));
3308  if (!pDataNode) {
3309    ThrowArgumentMismatchException();
3310    return;
3311  }
3312
3313  CXFA_NodeArray formItems;
3314  CXFA_ArrayNodeList* pFormNodes = new CXFA_ArrayNodeList(m_pDocument);
3315  pFormNodes->SetArrayNodeList(formItems);
3316  pArguments->GetReturnValue()->SetObject(
3317      pFormNodes, m_pDocument->GetScriptContext()->GetJseNormalClass());
3318}
3319
3320void CXFA_Node::Script_Form_Remerge(CFXJSE_Arguments* pArguments) {
3321  if (pArguments->GetLength() != 0) {
3322    ThrowParamCountMismatchException(L"remerge");
3323    return;
3324  }
3325
3326  m_pDocument->DoDataRemerge(true);
3327}
3328
3329void CXFA_Node::Script_Form_ExecInitialize(CFXJSE_Arguments* pArguments) {
3330  if (pArguments->GetLength() != 0) {
3331    ThrowParamCountMismatchException(L"execInitialize");
3332    return;
3333  }
3334
3335  CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
3336  if (!pNotify)
3337    return;
3338
3339  pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Initialize);
3340}
3341
3342void CXFA_Node::Script_Form_Recalculate(CFXJSE_Arguments* pArguments) {
3343  CXFA_EventParam* pEventParam =
3344      m_pDocument->GetScriptContext()->GetEventParam();
3345  if (pEventParam->m_eType == XFA_EVENT_Calculate ||
3346      pEventParam->m_eType == XFA_EVENT_InitCalculate) {
3347    return;
3348  }
3349  if (pArguments->GetLength() != 1) {
3350    ThrowParamCountMismatchException(L"recalculate");
3351    return;
3352  }
3353
3354  CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
3355  if (!pNotify)
3356    return;
3357  if (pArguments->GetInt32(0) != 0)
3358    return;
3359
3360  pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Calculate);
3361  pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Validate);
3362  pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Ready, true);
3363}
3364
3365void CXFA_Node::Script_Form_ExecCalculate(CFXJSE_Arguments* pArguments) {
3366  if (pArguments->GetLength() != 0) {
3367    ThrowParamCountMismatchException(L"execCalculate");
3368    return;
3369  }
3370
3371  CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
3372  if (!pNotify)
3373    return;
3374
3375  pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Calculate);
3376}
3377
3378void CXFA_Node::Script_Form_ExecValidate(CFXJSE_Arguments* pArguments) {
3379  if (pArguments->GetLength() != 0) {
3380    ThrowParamCountMismatchException(L"execValidate");
3381    return;
3382  }
3383
3384  CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
3385  if (!pNotify) {
3386    pArguments->GetReturnValue()->SetBoolean(false);
3387    return;
3388  }
3389
3390  int32_t iRet = pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Validate);
3391  pArguments->GetReturnValue()->SetBoolean(
3392      (iRet == XFA_EVENTERROR_Error) ? false : true);
3393}
3394
3395void CXFA_Node::Script_Form_Checksum(CFXJSE_Value* pValue,
3396                                     bool bSetting,
3397                                     XFA_ATTRIBUTE eAttribute) {
3398  if (bSetting) {
3399    SetAttribute(XFA_ATTRIBUTE_Checksum, pValue->ToWideString().AsStringC());
3400    return;
3401  }
3402  CFX_WideString wsChecksum;
3403  GetAttribute(XFA_ATTRIBUTE_Checksum, wsChecksum, false);
3404  pValue->SetString(wsChecksum.UTF8Encode().AsStringC());
3405}
3406
3407void CXFA_Node::Script_Packet_GetAttribute(CFXJSE_Arguments* pArguments) {
3408  if (pArguments->GetLength() != 1) {
3409    ThrowParamCountMismatchException(L"getAttribute");
3410    return;
3411  }
3412  CFX_ByteString bsAttributeName = pArguments->GetUTF8String(0);
3413  CFX_WideString wsAttributeValue;
3414  CFDE_XMLNode* pXMLNode = GetXMLMappingNode();
3415  if (pXMLNode && pXMLNode->GetType() == FDE_XMLNODE_Element) {
3416    static_cast<CFDE_XMLElement*>(pXMLNode)->GetString(
3417        CFX_WideString::FromUTF8(bsAttributeName.AsStringC()).c_str(),
3418        wsAttributeValue);
3419  }
3420  pArguments->GetReturnValue()->SetString(
3421      wsAttributeValue.UTF8Encode().AsStringC());
3422}
3423
3424void CXFA_Node::Script_Packet_SetAttribute(CFXJSE_Arguments* pArguments) {
3425  if (pArguments->GetLength() != 2) {
3426    ThrowParamCountMismatchException(L"setAttribute");
3427    return;
3428  }
3429  CFX_ByteString bsValue = pArguments->GetUTF8String(0);
3430  CFX_ByteString bsName = pArguments->GetUTF8String(1);
3431  CFDE_XMLNode* pXMLNode = GetXMLMappingNode();
3432  if (pXMLNode && pXMLNode->GetType() == FDE_XMLNODE_Element) {
3433    static_cast<CFDE_XMLElement*>(pXMLNode)->SetString(
3434        CFX_WideString::FromUTF8(bsName.AsStringC()),
3435        CFX_WideString::FromUTF8(bsValue.AsStringC()));
3436  }
3437  pArguments->GetReturnValue()->SetNull();
3438}
3439
3440void CXFA_Node::Script_Packet_RemoveAttribute(CFXJSE_Arguments* pArguments) {
3441  if (pArguments->GetLength() != 1) {
3442    ThrowParamCountMismatchException(L"removeAttribute");
3443    return;
3444  }
3445
3446  CFX_ByteString bsName = pArguments->GetUTF8String(0);
3447  CFX_WideString wsName = CFX_WideString::FromUTF8(bsName.AsStringC());
3448  CFDE_XMLNode* pXMLNode = GetXMLMappingNode();
3449  if (pXMLNode && pXMLNode->GetType() == FDE_XMLNODE_Element) {
3450    CFDE_XMLElement* pXMLElement = static_cast<CFDE_XMLElement*>(pXMLNode);
3451    if (pXMLElement->HasAttribute(wsName.c_str())) {
3452      pXMLElement->RemoveAttribute(wsName.c_str());
3453    }
3454  }
3455  pArguments->GetReturnValue()->SetNull();
3456}
3457
3458void CXFA_Node::Script_Packet_Content(CFXJSE_Value* pValue,
3459                                      bool bSetting,
3460                                      XFA_ATTRIBUTE eAttribute) {
3461  if (bSetting) {
3462    CFDE_XMLNode* pXMLNode = GetXMLMappingNode();
3463    if (pXMLNode && pXMLNode->GetType() == FDE_XMLNODE_Element) {
3464      CFDE_XMLElement* pXMLElement = static_cast<CFDE_XMLElement*>(pXMLNode);
3465      pXMLElement->SetTextData(pValue->ToWideString());
3466    }
3467  } else {
3468    CFX_WideString wsTextData;
3469    CFDE_XMLNode* pXMLNode = GetXMLMappingNode();
3470    if (pXMLNode && pXMLNode->GetType() == FDE_XMLNODE_Element) {
3471      CFDE_XMLElement* pXMLElement = static_cast<CFDE_XMLElement*>(pXMLNode);
3472      pXMLElement->GetTextData(wsTextData);
3473    }
3474    pValue->SetString(wsTextData.UTF8Encode().AsStringC());
3475  }
3476}
3477
3478void CXFA_Node::Script_Source_Next(CFXJSE_Arguments* pArguments) {
3479  if (pArguments->GetLength() != 0)
3480    ThrowParamCountMismatchException(L"next");
3481}
3482
3483void CXFA_Node::Script_Source_CancelBatch(CFXJSE_Arguments* pArguments) {
3484  if (pArguments->GetLength() != 0)
3485    ThrowParamCountMismatchException(L"cancelBatch");
3486}
3487
3488void CXFA_Node::Script_Source_First(CFXJSE_Arguments* pArguments) {
3489  if (pArguments->GetLength() != 0)
3490    ThrowParamCountMismatchException(L"first");
3491}
3492
3493void CXFA_Node::Script_Source_UpdateBatch(CFXJSE_Arguments* pArguments) {
3494  if (pArguments->GetLength() != 0)
3495    ThrowParamCountMismatchException(L"updateBatch");
3496}
3497
3498void CXFA_Node::Script_Source_Previous(CFXJSE_Arguments* pArguments) {
3499  if (pArguments->GetLength() != 0)
3500    ThrowParamCountMismatchException(L"previous");
3501}
3502
3503void CXFA_Node::Script_Source_IsBOF(CFXJSE_Arguments* pArguments) {
3504  if (pArguments->GetLength() != 0)
3505    ThrowParamCountMismatchException(L"isBOF");
3506}
3507
3508void CXFA_Node::Script_Source_IsEOF(CFXJSE_Arguments* pArguments) {
3509  if (pArguments->GetLength() != 0)
3510    ThrowParamCountMismatchException(L"isEOF");
3511}
3512
3513void CXFA_Node::Script_Source_Cancel(CFXJSE_Arguments* pArguments) {
3514  if (pArguments->GetLength() != 0)
3515    ThrowParamCountMismatchException(L"cancel");
3516}
3517
3518void CXFA_Node::Script_Source_Update(CFXJSE_Arguments* pArguments) {
3519  if (pArguments->GetLength() != 0)
3520    ThrowParamCountMismatchException(L"update");
3521}
3522
3523void CXFA_Node::Script_Source_Open(CFXJSE_Arguments* pArguments) {
3524  if (pArguments->GetLength() != 0)
3525    ThrowParamCountMismatchException(L"open");
3526}
3527
3528void CXFA_Node::Script_Source_Delete(CFXJSE_Arguments* pArguments) {
3529  if (pArguments->GetLength() != 0)
3530    ThrowParamCountMismatchException(L"delete");
3531}
3532
3533void CXFA_Node::Script_Source_AddNew(CFXJSE_Arguments* pArguments) {
3534  if (pArguments->GetLength() != 0)
3535    ThrowParamCountMismatchException(L"addNew");
3536}
3537
3538void CXFA_Node::Script_Source_Requery(CFXJSE_Arguments* pArguments) {
3539  if (pArguments->GetLength() != 0)
3540    ThrowParamCountMismatchException(L"requery");
3541}
3542
3543void CXFA_Node::Script_Source_Resync(CFXJSE_Arguments* pArguments) {
3544  if (pArguments->GetLength() != 0)
3545    ThrowParamCountMismatchException(L"resync");
3546}
3547
3548void CXFA_Node::Script_Source_Close(CFXJSE_Arguments* pArguments) {
3549  if (pArguments->GetLength() != 0)
3550    ThrowParamCountMismatchException(L"close");
3551}
3552
3553void CXFA_Node::Script_Source_Last(CFXJSE_Arguments* pArguments) {
3554  if (pArguments->GetLength() != 0)
3555    ThrowParamCountMismatchException(L"last");
3556}
3557
3558void CXFA_Node::Script_Source_HasDataChanged(CFXJSE_Arguments* pArguments) {
3559  if (pArguments->GetLength() != 0)
3560    ThrowParamCountMismatchException(L"hasDataChanged");
3561}
3562
3563void CXFA_Node::Script_Source_Db(CFXJSE_Value* pValue,
3564                                 bool bSetting,
3565                                 XFA_ATTRIBUTE eAttribute) {}
3566
3567void CXFA_Node::Script_Xfa_This(CFXJSE_Value* pValue,
3568                                bool bSetting,
3569                                XFA_ATTRIBUTE eAttribute) {
3570  if (!bSetting) {
3571    CXFA_Object* pThis = m_pDocument->GetScriptContext()->GetThisObject();
3572    ASSERT(pThis);
3573    pValue->Assign(m_pDocument->GetScriptContext()->GetJSValueFromMap(pThis));
3574  }
3575}
3576
3577void CXFA_Node::Script_Handler_Version(CFXJSE_Value* pValue,
3578                                       bool bSetting,
3579                                       XFA_ATTRIBUTE eAttribute) {}
3580
3581void CXFA_Node::Script_SubmitFormat_Mode(CFXJSE_Value* pValue,
3582                                         bool bSetting,
3583                                         XFA_ATTRIBUTE eAttribute) {}
3584
3585void CXFA_Node::Script_Extras_Type(CFXJSE_Value* pValue,
3586                                   bool bSetting,
3587                                   XFA_ATTRIBUTE eAttribute) {}
3588
3589void CXFA_Node::Script_Script_Stateless(CFXJSE_Value* pValue,
3590                                        bool bSetting,
3591                                        XFA_ATTRIBUTE eAttribute) {
3592  if (bSetting) {
3593    ThrowInvalidPropertyException();
3594    return;
3595  }
3596  pValue->SetString(FX_UTF8Encode(CFX_WideStringC(L"0", 1)).AsStringC());
3597}
3598
3599void CXFA_Node::Script_Encrypt_Format(CFXJSE_Value* pValue,
3600                                      bool bSetting,
3601                                      XFA_ATTRIBUTE eAttribute) {}
3602
3603bool CXFA_Node::HasAttribute(XFA_ATTRIBUTE eAttr, bool bCanInherit) {
3604  void* pKey = GetMapKey_Element(GetElementType(), eAttr);
3605  return HasMapModuleKey(pKey, bCanInherit);
3606}
3607
3608bool CXFA_Node::SetAttribute(XFA_ATTRIBUTE eAttr,
3609                             const CFX_WideStringC& wsValue,
3610                             bool bNotify) {
3611  const XFA_ATTRIBUTEINFO* pAttr = XFA_GetAttributeByID(eAttr);
3612  if (!pAttr)
3613    return false;
3614
3615  XFA_ATTRIBUTETYPE eType = pAttr->eType;
3616  if (eType == XFA_ATTRIBUTETYPE_NOTSURE) {
3617    const XFA_NOTSUREATTRIBUTE* pNotsure =
3618        XFA_GetNotsureAttribute(GetElementType(), pAttr->eName);
3619    eType = pNotsure ? pNotsure->eType : XFA_ATTRIBUTETYPE_Cdata;
3620  }
3621  switch (eType) {
3622    case XFA_ATTRIBUTETYPE_Enum: {
3623      const XFA_ATTRIBUTEENUMINFO* pEnum = XFA_GetAttributeEnumByName(wsValue);
3624      return SetEnum(pAttr->eName,
3625                     pEnum ? pEnum->eName
3626                           : (XFA_ATTRIBUTEENUM)(intptr_t)(pAttr->pDefValue),
3627                     bNotify);
3628    } break;
3629    case XFA_ATTRIBUTETYPE_Cdata:
3630      return SetCData(pAttr->eName, CFX_WideString(wsValue), bNotify);
3631    case XFA_ATTRIBUTETYPE_Boolean:
3632      return SetBoolean(pAttr->eName, wsValue != L"0", bNotify);
3633    case XFA_ATTRIBUTETYPE_Integer:
3634      return SetInteger(pAttr->eName,
3635                        FXSYS_round(FXSYS_wcstof(wsValue.c_str(),
3636                                                 wsValue.GetLength(), nullptr)),
3637                        bNotify);
3638    case XFA_ATTRIBUTETYPE_Measure:
3639      return SetMeasure(pAttr->eName, CXFA_Measurement(wsValue), bNotify);
3640    default:
3641      break;
3642  }
3643  return false;
3644}
3645
3646bool CXFA_Node::GetAttribute(XFA_ATTRIBUTE eAttr,
3647                             CFX_WideString& wsValue,
3648                             bool bUseDefault) {
3649  const XFA_ATTRIBUTEINFO* pAttr = XFA_GetAttributeByID(eAttr);
3650  if (!pAttr) {
3651    return false;
3652  }
3653  XFA_ATTRIBUTETYPE eType = pAttr->eType;
3654  if (eType == XFA_ATTRIBUTETYPE_NOTSURE) {
3655    const XFA_NOTSUREATTRIBUTE* pNotsure =
3656        XFA_GetNotsureAttribute(GetElementType(), pAttr->eName);
3657    eType = pNotsure ? pNotsure->eType : XFA_ATTRIBUTETYPE_Cdata;
3658  }
3659  switch (eType) {
3660    case XFA_ATTRIBUTETYPE_Enum: {
3661      XFA_ATTRIBUTEENUM eValue;
3662      if (!TryEnum(pAttr->eName, eValue, bUseDefault)) {
3663        return false;
3664      }
3665      wsValue = GetAttributeEnumByID(eValue)->pName;
3666      return true;
3667    } break;
3668    case XFA_ATTRIBUTETYPE_Cdata: {
3669      CFX_WideStringC wsValueC;
3670      if (!TryCData(pAttr->eName, wsValueC, bUseDefault)) {
3671        return false;
3672      }
3673      wsValue = wsValueC;
3674      return true;
3675    } break;
3676    case XFA_ATTRIBUTETYPE_Boolean: {
3677      bool bValue;
3678      if (!TryBoolean(pAttr->eName, bValue, bUseDefault)) {
3679        return false;
3680      }
3681      wsValue = bValue ? L"1" : L"0";
3682      return true;
3683    } break;
3684    case XFA_ATTRIBUTETYPE_Integer: {
3685      int32_t iValue;
3686      if (!TryInteger(pAttr->eName, iValue, bUseDefault)) {
3687        return false;
3688      }
3689      wsValue.Format(L"%d", iValue);
3690      return true;
3691    } break;
3692    case XFA_ATTRIBUTETYPE_Measure: {
3693      CXFA_Measurement mValue;
3694      if (!TryMeasure(pAttr->eName, mValue, bUseDefault)) {
3695        return false;
3696      }
3697      mValue.ToString(wsValue);
3698      return true;
3699    } break;
3700    default:
3701      break;
3702  }
3703  return false;
3704}
3705
3706bool CXFA_Node::SetAttribute(const CFX_WideStringC& wsAttr,
3707                             const CFX_WideStringC& wsValue,
3708                             bool bNotify) {
3709  const XFA_ATTRIBUTEINFO* pAttributeInfo = XFA_GetAttributeByName(wsValue);
3710  if (pAttributeInfo) {
3711    return SetAttribute(pAttributeInfo->eName, wsValue, bNotify);
3712  }
3713  void* pKey = GetMapKey_Custom(wsAttr);
3714  SetMapModuleString(pKey, wsValue);
3715  return true;
3716}
3717
3718bool CXFA_Node::GetAttribute(const CFX_WideStringC& wsAttr,
3719                             CFX_WideString& wsValue,
3720                             bool bUseDefault) {
3721  const XFA_ATTRIBUTEINFO* pAttributeInfo = XFA_GetAttributeByName(wsAttr);
3722  if (pAttributeInfo) {
3723    return GetAttribute(pAttributeInfo->eName, wsValue, bUseDefault);
3724  }
3725  void* pKey = GetMapKey_Custom(wsAttr);
3726  CFX_WideStringC wsValueC;
3727  if (GetMapModuleString(pKey, wsValueC)) {
3728    wsValue = wsValueC;
3729  }
3730  return true;
3731}
3732
3733bool CXFA_Node::RemoveAttribute(const CFX_WideStringC& wsAttr) {
3734  void* pKey = GetMapKey_Custom(wsAttr);
3735  RemoveMapModuleKey(pKey);
3736  return true;
3737}
3738
3739bool CXFA_Node::TryBoolean(XFA_ATTRIBUTE eAttr,
3740                           bool& bValue,
3741                           bool bUseDefault) {
3742  void* pValue = nullptr;
3743  if (!GetValue(eAttr, XFA_ATTRIBUTETYPE_Boolean, bUseDefault, pValue))
3744    return false;
3745  bValue = !!pValue;
3746  return true;
3747}
3748
3749bool CXFA_Node::TryInteger(XFA_ATTRIBUTE eAttr,
3750                           int32_t& iValue,
3751                           bool bUseDefault) {
3752  void* pValue = nullptr;
3753  if (!GetValue(eAttr, XFA_ATTRIBUTETYPE_Integer, bUseDefault, pValue))
3754    return false;
3755  iValue = (int32_t)(uintptr_t)pValue;
3756  return true;
3757}
3758
3759bool CXFA_Node::TryEnum(XFA_ATTRIBUTE eAttr,
3760                        XFA_ATTRIBUTEENUM& eValue,
3761                        bool bUseDefault) {
3762  void* pValue = nullptr;
3763  if (!GetValue(eAttr, XFA_ATTRIBUTETYPE_Enum, bUseDefault, pValue))
3764    return false;
3765  eValue = (XFA_ATTRIBUTEENUM)(uintptr_t)pValue;
3766  return true;
3767}
3768
3769bool CXFA_Node::SetMeasure(XFA_ATTRIBUTE eAttr,
3770                           CXFA_Measurement mValue,
3771                           bool bNotify) {
3772  void* pKey = GetMapKey_Element(GetElementType(), eAttr);
3773  OnChanging(eAttr, bNotify);
3774  SetMapModuleBuffer(pKey, &mValue, sizeof(CXFA_Measurement));
3775  OnChanged(eAttr, bNotify, false);
3776  return true;
3777}
3778
3779bool CXFA_Node::TryMeasure(XFA_ATTRIBUTE eAttr,
3780                           CXFA_Measurement& mValue,
3781                           bool bUseDefault) const {
3782  void* pKey = GetMapKey_Element(GetElementType(), eAttr);
3783  void* pValue;
3784  int32_t iBytes;
3785  if (GetMapModuleBuffer(pKey, pValue, iBytes) && iBytes == sizeof(mValue)) {
3786    FXSYS_memcpy(&mValue, pValue, sizeof(mValue));
3787    return true;
3788  }
3789  if (bUseDefault &&
3790      XFA_GetAttributeDefaultValue(pValue, GetElementType(), eAttr,
3791                                   XFA_ATTRIBUTETYPE_Measure, m_ePacket)) {
3792    FXSYS_memcpy(&mValue, pValue, sizeof(mValue));
3793    return true;
3794  }
3795  return false;
3796}
3797
3798CXFA_Measurement CXFA_Node::GetMeasure(XFA_ATTRIBUTE eAttr) const {
3799  CXFA_Measurement mValue;
3800  return TryMeasure(eAttr, mValue, true) ? mValue : CXFA_Measurement();
3801}
3802
3803bool CXFA_Node::SetCData(XFA_ATTRIBUTE eAttr,
3804                         const CFX_WideString& wsValue,
3805                         bool bNotify,
3806                         bool bScriptModify) {
3807  void* pKey = GetMapKey_Element(GetElementType(), eAttr);
3808  OnChanging(eAttr, bNotify);
3809  if (eAttr == XFA_ATTRIBUTE_Value) {
3810    CFX_WideString* pClone = new CFX_WideString(wsValue);
3811    SetUserData(pKey, pClone, &deleteWideStringCallBack);
3812  } else {
3813    SetMapModuleString(pKey, wsValue.AsStringC());
3814    if (eAttr == XFA_ATTRIBUTE_Name)
3815      UpdateNameHash();
3816  }
3817  OnChanged(eAttr, bNotify, bScriptModify);
3818
3819  if (!IsNeedSavingXMLNode() || eAttr == XFA_ATTRIBUTE_QualifiedName ||
3820      eAttr == XFA_ATTRIBUTE_BindingNode) {
3821    return true;
3822  }
3823
3824  if (eAttr == XFA_ATTRIBUTE_Name &&
3825      (m_elementType == XFA_Element::DataValue ||
3826       m_elementType == XFA_Element::DataGroup)) {
3827    return true;
3828  }
3829
3830  if (eAttr == XFA_ATTRIBUTE_Value) {
3831    FDE_XMLNODETYPE eXMLType = m_pXMLNode->GetType();
3832    switch (eXMLType) {
3833      case FDE_XMLNODE_Element:
3834        if (IsAttributeInXML()) {
3835          static_cast<CFDE_XMLElement*>(m_pXMLNode)
3836              ->SetString(CFX_WideString(GetCData(XFA_ATTRIBUTE_QualifiedName)),
3837                          wsValue);
3838        } else {
3839          bool bDeleteChildren = true;
3840          if (GetPacketID() == XFA_XDPPACKET_Datasets) {
3841            for (CXFA_Node* pChildDataNode =
3842                     GetNodeItem(XFA_NODEITEM_FirstChild);
3843                 pChildDataNode; pChildDataNode = pChildDataNode->GetNodeItem(
3844                                     XFA_NODEITEM_NextSibling)) {
3845              CXFA_NodeArray formNodes;
3846              if (pChildDataNode->GetBindItems(formNodes) > 0) {
3847                bDeleteChildren = false;
3848                break;
3849              }
3850            }
3851          }
3852          if (bDeleteChildren) {
3853            static_cast<CFDE_XMLElement*>(m_pXMLNode)->DeleteChildren();
3854          }
3855          static_cast<CFDE_XMLElement*>(m_pXMLNode)->SetTextData(wsValue);
3856        }
3857        break;
3858      case FDE_XMLNODE_Text:
3859        static_cast<CFDE_XMLText*>(m_pXMLNode)->SetText(wsValue);
3860        break;
3861      default:
3862        ASSERT(0);
3863    }
3864    return true;
3865  }
3866
3867  const XFA_ATTRIBUTEINFO* pInfo = XFA_GetAttributeByID(eAttr);
3868  if (pInfo) {
3869    ASSERT(m_pXMLNode->GetType() == FDE_XMLNODE_Element);
3870    CFX_WideString wsAttrName = pInfo->pName;
3871    if (pInfo->eName == XFA_ATTRIBUTE_ContentType) {
3872      wsAttrName = L"xfa:" + wsAttrName;
3873    }
3874    static_cast<CFDE_XMLElement*>(m_pXMLNode)->SetString(wsAttrName, wsValue);
3875  }
3876  return true;
3877}
3878
3879bool CXFA_Node::SetAttributeValue(const CFX_WideString& wsValue,
3880                                  const CFX_WideString& wsXMLValue,
3881                                  bool bNotify,
3882                                  bool bScriptModify) {
3883  void* pKey = GetMapKey_Element(GetElementType(), XFA_ATTRIBUTE_Value);
3884  OnChanging(XFA_ATTRIBUTE_Value, bNotify);
3885  CFX_WideString* pClone = new CFX_WideString(wsValue);
3886  SetUserData(pKey, pClone, &deleteWideStringCallBack);
3887  OnChanged(XFA_ATTRIBUTE_Value, bNotify, bScriptModify);
3888  if (IsNeedSavingXMLNode()) {
3889    FDE_XMLNODETYPE eXMLType = m_pXMLNode->GetType();
3890    switch (eXMLType) {
3891      case FDE_XMLNODE_Element:
3892        if (IsAttributeInXML()) {
3893          static_cast<CFDE_XMLElement*>(m_pXMLNode)
3894              ->SetString(CFX_WideString(GetCData(XFA_ATTRIBUTE_QualifiedName)),
3895                          wsXMLValue);
3896        } else {
3897          bool bDeleteChildren = true;
3898          if (GetPacketID() == XFA_XDPPACKET_Datasets) {
3899            for (CXFA_Node* pChildDataNode =
3900                     GetNodeItem(XFA_NODEITEM_FirstChild);
3901                 pChildDataNode; pChildDataNode = pChildDataNode->GetNodeItem(
3902                                     XFA_NODEITEM_NextSibling)) {
3903              CXFA_NodeArray formNodes;
3904              if (pChildDataNode->GetBindItems(formNodes) > 0) {
3905                bDeleteChildren = false;
3906                break;
3907              }
3908            }
3909          }
3910          if (bDeleteChildren) {
3911            static_cast<CFDE_XMLElement*>(m_pXMLNode)->DeleteChildren();
3912          }
3913          static_cast<CFDE_XMLElement*>(m_pXMLNode)->SetTextData(wsXMLValue);
3914        }
3915        break;
3916      case FDE_XMLNODE_Text:
3917        static_cast<CFDE_XMLText*>(m_pXMLNode)->SetText(wsXMLValue);
3918        break;
3919      default:
3920        ASSERT(0);
3921    }
3922  }
3923  return true;
3924}
3925
3926bool CXFA_Node::TryCData(XFA_ATTRIBUTE eAttr,
3927                         CFX_WideString& wsValue,
3928                         bool bUseDefault,
3929                         bool bProto) {
3930  void* pKey = GetMapKey_Element(GetElementType(), eAttr);
3931  if (eAttr == XFA_ATTRIBUTE_Value) {
3932    CFX_WideString* pStr = (CFX_WideString*)GetUserData(pKey, bProto);
3933    if (pStr) {
3934      wsValue = *pStr;
3935      return true;
3936    }
3937  } else {
3938    CFX_WideStringC wsValueC;
3939    if (GetMapModuleString(pKey, wsValueC)) {
3940      wsValue = wsValueC;
3941      return true;
3942    }
3943  }
3944  if (!bUseDefault) {
3945    return false;
3946  }
3947  void* pValue = nullptr;
3948  if (XFA_GetAttributeDefaultValue(pValue, GetElementType(), eAttr,
3949                                   XFA_ATTRIBUTETYPE_Cdata, m_ePacket)) {
3950    wsValue = (const FX_WCHAR*)pValue;
3951    return true;
3952  }
3953  return false;
3954}
3955
3956bool CXFA_Node::TryCData(XFA_ATTRIBUTE eAttr,
3957                         CFX_WideStringC& wsValue,
3958                         bool bUseDefault,
3959                         bool bProto) {
3960  void* pKey = GetMapKey_Element(GetElementType(), eAttr);
3961  if (eAttr == XFA_ATTRIBUTE_Value) {
3962    CFX_WideString* pStr = (CFX_WideString*)GetUserData(pKey, bProto);
3963    if (pStr) {
3964      wsValue = pStr->AsStringC();
3965      return true;
3966    }
3967  } else {
3968    if (GetMapModuleString(pKey, wsValue)) {
3969      return true;
3970    }
3971  }
3972  if (!bUseDefault) {
3973    return false;
3974  }
3975  void* pValue = nullptr;
3976  if (XFA_GetAttributeDefaultValue(pValue, GetElementType(), eAttr,
3977                                   XFA_ATTRIBUTETYPE_Cdata, m_ePacket)) {
3978    wsValue = (CFX_WideStringC)(const FX_WCHAR*)pValue;
3979    return true;
3980  }
3981  return false;
3982}
3983
3984bool CXFA_Node::SetObject(XFA_ATTRIBUTE eAttr,
3985                          void* pData,
3986                          XFA_MAPDATABLOCKCALLBACKINFO* pCallbackInfo) {
3987  void* pKey = GetMapKey_Element(GetElementType(), eAttr);
3988  return SetUserData(pKey, pData, pCallbackInfo);
3989}
3990
3991bool CXFA_Node::TryObject(XFA_ATTRIBUTE eAttr, void*& pData) {
3992  void* pKey = GetMapKey_Element(GetElementType(), eAttr);
3993  pData = GetUserData(pKey);
3994  return !!pData;
3995}
3996
3997bool CXFA_Node::SetValue(XFA_ATTRIBUTE eAttr,
3998                         XFA_ATTRIBUTETYPE eType,
3999                         void* pValue,
4000                         bool bNotify) {
4001  void* pKey = GetMapKey_Element(GetElementType(), eAttr);
4002  OnChanging(eAttr, bNotify);
4003  SetMapModuleValue(pKey, pValue);
4004  OnChanged(eAttr, bNotify, false);
4005  if (IsNeedSavingXMLNode()) {
4006    ASSERT(m_pXMLNode->GetType() == FDE_XMLNODE_Element);
4007    const XFA_ATTRIBUTEINFO* pInfo = XFA_GetAttributeByID(eAttr);
4008    if (pInfo) {
4009      switch (eType) {
4010        case XFA_ATTRIBUTETYPE_Enum:
4011          static_cast<CFDE_XMLElement*>(m_pXMLNode)
4012              ->SetString(
4013                  pInfo->pName,
4014                  GetAttributeEnumByID((XFA_ATTRIBUTEENUM)(uintptr_t)pValue)
4015                      ->pName);
4016          break;
4017        case XFA_ATTRIBUTETYPE_Boolean:
4018          static_cast<CFDE_XMLElement*>(m_pXMLNode)
4019              ->SetString(pInfo->pName, pValue ? L"1" : L"0");
4020          break;
4021        case XFA_ATTRIBUTETYPE_Integer:
4022          static_cast<CFDE_XMLElement*>(m_pXMLNode)
4023              ->SetInteger(pInfo->pName, (int32_t)(uintptr_t)pValue);
4024          break;
4025        default:
4026          ASSERT(0);
4027      }
4028    }
4029  }
4030  return true;
4031}
4032
4033bool CXFA_Node::GetValue(XFA_ATTRIBUTE eAttr,
4034                         XFA_ATTRIBUTETYPE eType,
4035                         bool bUseDefault,
4036                         void*& pValue) {
4037  void* pKey = GetMapKey_Element(GetElementType(), eAttr);
4038  if (GetMapModuleValue(pKey, pValue)) {
4039    return true;
4040  }
4041  if (!bUseDefault) {
4042    return false;
4043  }
4044  return XFA_GetAttributeDefaultValue(pValue, GetElementType(), eAttr, eType,
4045                                      m_ePacket);
4046}
4047
4048bool CXFA_Node::SetUserData(void* pKey,
4049                            void* pData,
4050                            XFA_MAPDATABLOCKCALLBACKINFO* pCallbackInfo) {
4051  SetMapModuleBuffer(pKey, &pData, sizeof(void*),
4052                     pCallbackInfo ? pCallbackInfo : &gs_XFADefaultFreeData);
4053  return true;
4054}
4055
4056bool CXFA_Node::TryUserData(void* pKey, void*& pData, bool bProtoAlso) {
4057  int32_t iBytes = 0;
4058  if (!GetMapModuleBuffer(pKey, pData, iBytes, bProtoAlso)) {
4059    return false;
4060  }
4061  return iBytes == sizeof(void*) && FXSYS_memcpy(&pData, pData, iBytes);
4062}
4063
4064bool CXFA_Node::SetScriptContent(const CFX_WideString& wsContent,
4065                                 const CFX_WideString& wsXMLValue,
4066                                 bool bNotify,
4067                                 bool bScriptModify,
4068                                 bool bSyncData) {
4069  CXFA_Node* pNode = nullptr;
4070  CXFA_Node* pBindNode = nullptr;
4071  switch (GetObjectType()) {
4072    case XFA_ObjectType::ContainerNode: {
4073      if (XFA_FieldIsMultiListBox(this)) {
4074        CXFA_Node* pValue = GetProperty(0, XFA_Element::Value);
4075        CXFA_Node* pChildValue = pValue->GetNodeItem(XFA_NODEITEM_FirstChild);
4076        ASSERT(pChildValue);
4077        pChildValue->SetCData(XFA_ATTRIBUTE_ContentType, L"text/xml");
4078        pChildValue->SetScriptContent(wsContent, wsContent, bNotify,
4079                                      bScriptModify, false);
4080        CXFA_Node* pBind = GetBindData();
4081        if (bSyncData && pBind) {
4082          std::vector<CFX_WideString> wsSaveTextArray;
4083          int32_t iSize = 0;
4084          if (!wsContent.IsEmpty()) {
4085            int32_t iStart = 0;
4086            int32_t iLength = wsContent.GetLength();
4087            int32_t iEnd = wsContent.Find(L'\n', iStart);
4088            iEnd = (iEnd == -1) ? iLength : iEnd;
4089            while (iEnd >= iStart) {
4090              wsSaveTextArray.push_back(wsContent.Mid(iStart, iEnd - iStart));
4091              iStart = iEnd + 1;
4092              if (iStart >= iLength) {
4093                break;
4094              }
4095              iEnd = wsContent.Find(L'\n', iStart);
4096              if (iEnd < 0) {
4097                wsSaveTextArray.push_back(
4098                    wsContent.Mid(iStart, iLength - iStart));
4099              }
4100            }
4101            iSize = pdfium::CollectionSize<int32_t>(wsSaveTextArray);
4102          }
4103          if (iSize == 0) {
4104            while (CXFA_Node* pChildNode =
4105                       pBind->GetNodeItem(XFA_NODEITEM_FirstChild)) {
4106              pBind->RemoveChild(pChildNode);
4107            }
4108          } else {
4109            CXFA_NodeArray valueNodes;
4110            int32_t iDatas = pBind->GetNodeList(
4111                valueNodes, XFA_NODEFILTER_Children, XFA_Element::DataValue);
4112            if (iDatas < iSize) {
4113              int32_t iAddNodes = iSize - iDatas;
4114              CXFA_Node* pValueNodes = nullptr;
4115              while (iAddNodes-- > 0) {
4116                pValueNodes =
4117                    pBind->CreateSamePacketNode(XFA_Element::DataValue);
4118                pValueNodes->SetCData(XFA_ATTRIBUTE_Name, L"value");
4119                pValueNodes->CreateXMLMappingNode();
4120                pBind->InsertChild(pValueNodes);
4121              }
4122              pValueNodes = nullptr;
4123            } else if (iDatas > iSize) {
4124              int32_t iDelNodes = iDatas - iSize;
4125              while (iDelNodes-- > 0) {
4126                pBind->RemoveChild(pBind->GetNodeItem(XFA_NODEITEM_FirstChild));
4127              }
4128            }
4129            int32_t i = 0;
4130            for (CXFA_Node* pValueNode =
4131                     pBind->GetNodeItem(XFA_NODEITEM_FirstChild);
4132                 pValueNode; pValueNode = pValueNode->GetNodeItem(
4133                                 XFA_NODEITEM_NextSibling)) {
4134              pValueNode->SetAttributeValue(wsSaveTextArray[i],
4135                                            wsSaveTextArray[i], false);
4136              i++;
4137            }
4138          }
4139          CXFA_NodeArray nodeArray;
4140          pBind->GetBindItems(nodeArray);
4141          for (int32_t i = 0; i < nodeArray.GetSize(); i++) {
4142            if (nodeArray[i] != this) {
4143              nodeArray[i]->SetScriptContent(wsContent, wsContent, bNotify,
4144                                             bScriptModify, false);
4145            }
4146          }
4147        }
4148        break;
4149      } else if (GetElementType() == XFA_Element::ExclGroup) {
4150        pNode = this;
4151      } else {
4152        CXFA_Node* pValue = GetProperty(0, XFA_Element::Value);
4153        CXFA_Node* pChildValue = pValue->GetNodeItem(XFA_NODEITEM_FirstChild);
4154        ASSERT(pChildValue);
4155        pChildValue->SetScriptContent(wsContent, wsContent, bNotify,
4156                                      bScriptModify, false);
4157      }
4158      pBindNode = GetBindData();
4159      if (pBindNode && bSyncData) {
4160        pBindNode->SetScriptContent(wsContent, wsXMLValue, bNotify,
4161                                    bScriptModify, false);
4162        CXFA_NodeArray nodeArray;
4163        pBindNode->GetBindItems(nodeArray);
4164        for (int32_t i = 0; i < nodeArray.GetSize(); i++) {
4165          if (nodeArray[i] != this) {
4166            nodeArray[i]->SetScriptContent(wsContent, wsContent, bNotify, true,
4167                                           false);
4168          }
4169        }
4170      }
4171      pBindNode = nullptr;
4172      break;
4173    }
4174    case XFA_ObjectType::ContentNode: {
4175      CFX_WideString wsContentType;
4176      if (GetElementType() == XFA_Element::ExData) {
4177        GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, false);
4178        if (wsContentType == L"text/html") {
4179          wsContentType = L"";
4180          SetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType.AsStringC());
4181        }
4182      }
4183      CXFA_Node* pContentRawDataNode = GetNodeItem(XFA_NODEITEM_FirstChild);
4184      if (!pContentRawDataNode) {
4185        pContentRawDataNode = CreateSamePacketNode(
4186            (wsContentType == L"text/xml") ? XFA_Element::Sharpxml
4187                                           : XFA_Element::Sharptext);
4188        InsertChild(pContentRawDataNode);
4189      }
4190      return pContentRawDataNode->SetScriptContent(
4191          wsContent, wsXMLValue, bNotify, bScriptModify, bSyncData);
4192    } break;
4193    case XFA_ObjectType::NodeC:
4194    case XFA_ObjectType::TextNode:
4195      pNode = this;
4196      break;
4197    case XFA_ObjectType::NodeV:
4198      pNode = this;
4199      if (bSyncData && GetPacketID() == XFA_XDPPACKET_Form) {
4200        CXFA_Node* pParent = GetNodeItem(XFA_NODEITEM_Parent);
4201        if (pParent) {
4202          pParent = pParent->GetNodeItem(XFA_NODEITEM_Parent);
4203        }
4204        if (pParent && pParent->GetElementType() == XFA_Element::Value) {
4205          pParent = pParent->GetNodeItem(XFA_NODEITEM_Parent);
4206          if (pParent && pParent->IsContainerNode()) {
4207            pBindNode = pParent->GetBindData();
4208            if (pBindNode) {
4209              pBindNode->SetScriptContent(wsContent, wsXMLValue, bNotify,
4210                                          bScriptModify, false);
4211            }
4212          }
4213        }
4214      }
4215      break;
4216    default:
4217      if (GetElementType() == XFA_Element::DataValue) {
4218        pNode = this;
4219        pBindNode = this;
4220      }
4221      break;
4222  }
4223  if (pNode) {
4224    SetAttributeValue(wsContent, wsXMLValue, bNotify, bScriptModify);
4225    if (pBindNode && bSyncData) {
4226      CXFA_NodeArray nodeArray;
4227      pBindNode->GetBindItems(nodeArray);
4228      for (int32_t i = 0; i < nodeArray.GetSize(); i++) {
4229        nodeArray[i]->SetScriptContent(wsContent, wsContent, bNotify,
4230                                       bScriptModify, false);
4231      }
4232    }
4233    return true;
4234  }
4235  return false;
4236}
4237
4238bool CXFA_Node::SetContent(const CFX_WideString& wsContent,
4239                           const CFX_WideString& wsXMLValue,
4240                           bool bNotify,
4241                           bool bScriptModify,
4242                           bool bSyncData) {
4243  return SetScriptContent(wsContent, wsXMLValue, bNotify, bScriptModify,
4244                          bSyncData);
4245}
4246
4247CFX_WideString CXFA_Node::GetScriptContent(bool bScriptModify) {
4248  CFX_WideString wsContent;
4249  return TryContent(wsContent, bScriptModify) ? wsContent : CFX_WideString();
4250}
4251
4252CFX_WideString CXFA_Node::GetContent() {
4253  return GetScriptContent();
4254}
4255
4256bool CXFA_Node::TryContent(CFX_WideString& wsContent,
4257                           bool bScriptModify,
4258                           bool bProto) {
4259  CXFA_Node* pNode = nullptr;
4260  switch (GetObjectType()) {
4261    case XFA_ObjectType::ContainerNode:
4262      if (GetElementType() == XFA_Element::ExclGroup) {
4263        pNode = this;
4264      } else {
4265        CXFA_Node* pValue = GetChild(0, XFA_Element::Value);
4266        if (!pValue) {
4267          return false;
4268        }
4269        CXFA_Node* pChildValue = pValue->GetNodeItem(XFA_NODEITEM_FirstChild);
4270        if (pChildValue && XFA_FieldIsMultiListBox(this)) {
4271          pChildValue->SetAttribute(XFA_ATTRIBUTE_ContentType, L"text/xml");
4272        }
4273        return pChildValue
4274                   ? pChildValue->TryContent(wsContent, bScriptModify, bProto)
4275                   : false;
4276      }
4277      break;
4278    case XFA_ObjectType::ContentNode: {
4279      CXFA_Node* pContentRawDataNode = GetNodeItem(XFA_NODEITEM_FirstChild);
4280      if (!pContentRawDataNode) {
4281        XFA_Element element = XFA_Element::Sharptext;
4282        if (GetElementType() == XFA_Element::ExData) {
4283          CFX_WideString wsContentType;
4284          GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, false);
4285          if (wsContentType == L"text/html") {
4286            element = XFA_Element::SharpxHTML;
4287          } else if (wsContentType == L"text/xml") {
4288            element = XFA_Element::Sharpxml;
4289          }
4290        }
4291        pContentRawDataNode = CreateSamePacketNode(element);
4292        InsertChild(pContentRawDataNode);
4293      }
4294      return pContentRawDataNode->TryContent(wsContent, bScriptModify, bProto);
4295    }
4296    case XFA_ObjectType::NodeC:
4297    case XFA_ObjectType::NodeV:
4298    case XFA_ObjectType::TextNode:
4299      pNode = this;
4300    default:
4301      if (GetElementType() == XFA_Element::DataValue) {
4302        pNode = this;
4303      }
4304      break;
4305  }
4306  if (pNode) {
4307    if (bScriptModify) {
4308      CXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
4309      if (pScriptContext) {
4310        m_pDocument->GetScriptContext()->AddNodesOfRunScript(this);
4311      }
4312    }
4313    return TryCData(XFA_ATTRIBUTE_Value, wsContent, false, bProto);
4314  }
4315  return false;
4316}
4317
4318CXFA_Node* CXFA_Node::GetModelNode() {
4319  switch (GetPacketID()) {
4320    case XFA_XDPPACKET_XDP:
4321      return m_pDocument->GetRoot();
4322    case XFA_XDPPACKET_Config:
4323      return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Config));
4324    case XFA_XDPPACKET_Template:
4325      return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Template));
4326    case XFA_XDPPACKET_Form:
4327      return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Form));
4328    case XFA_XDPPACKET_Datasets:
4329      return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Datasets));
4330    case XFA_XDPPACKET_LocaleSet:
4331      return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_LocaleSet));
4332    case XFA_XDPPACKET_ConnectionSet:
4333      return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_ConnectionSet));
4334    case XFA_XDPPACKET_SourceSet:
4335      return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_SourceSet));
4336    case XFA_XDPPACKET_Xdc:
4337      return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Xdc));
4338    default:
4339      return this;
4340  }
4341}
4342
4343bool CXFA_Node::TryNamespace(CFX_WideString& wsNamespace) {
4344  wsNamespace.clear();
4345  if (IsModelNode() || GetElementType() == XFA_Element::Packet) {
4346    CFDE_XMLNode* pXMLNode = GetXMLMappingNode();
4347    if (!pXMLNode || pXMLNode->GetType() != FDE_XMLNODE_Element) {
4348      return false;
4349    }
4350    static_cast<CFDE_XMLElement*>(pXMLNode)->GetNamespaceURI(wsNamespace);
4351    return true;
4352  } else if (GetPacketID() == XFA_XDPPACKET_Datasets) {
4353    CFDE_XMLNode* pXMLNode = GetXMLMappingNode();
4354    if (!pXMLNode) {
4355      return false;
4356    }
4357    if (pXMLNode->GetType() != FDE_XMLNODE_Element) {
4358      return true;
4359    }
4360    if (GetElementType() == XFA_Element::DataValue &&
4361        GetEnum(XFA_ATTRIBUTE_Contains) == XFA_ATTRIBUTEENUM_MetaData) {
4362      return XFA_FDEExtension_ResolveNamespaceQualifier(
4363          static_cast<CFDE_XMLElement*>(pXMLNode),
4364          GetCData(XFA_ATTRIBUTE_QualifiedName), wsNamespace);
4365    }
4366    static_cast<CFDE_XMLElement*>(pXMLNode)->GetNamespaceURI(wsNamespace);
4367    return true;
4368  } else {
4369    CXFA_Node* pModelNode = GetModelNode();
4370    return pModelNode->TryNamespace(wsNamespace);
4371  }
4372}
4373
4374CXFA_Node* CXFA_Node::GetProperty(int32_t index,
4375                                  XFA_Element eProperty,
4376                                  bool bCreateProperty) {
4377  XFA_Element eType = GetElementType();
4378  uint32_t dwPacket = GetPacketID();
4379  const XFA_PROPERTY* pProperty =
4380      XFA_GetPropertyOfElement(eType, eProperty, dwPacket);
4381  if (!pProperty || index >= pProperty->uOccur)
4382    return nullptr;
4383
4384  CXFA_Node* pNode = m_pChild;
4385  int32_t iCount = 0;
4386  for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
4387    if (pNode->GetElementType() == eProperty) {
4388      iCount++;
4389      if (iCount > index) {
4390        return pNode;
4391      }
4392    }
4393  }
4394  if (!bCreateProperty)
4395    return nullptr;
4396
4397  if (pProperty->uFlags & XFA_PROPERTYFLAG_OneOf) {
4398    pNode = m_pChild;
4399    for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
4400      const XFA_PROPERTY* pExistProperty =
4401          XFA_GetPropertyOfElement(eType, pNode->GetElementType(), dwPacket);
4402      if (pExistProperty && (pExistProperty->uFlags & XFA_PROPERTYFLAG_OneOf))
4403        return nullptr;
4404    }
4405  }
4406
4407  const XFA_PACKETINFO* pPacket = XFA_GetPacketByID(dwPacket);
4408  CXFA_Node* pNewNode = nullptr;
4409  for (; iCount <= index; iCount++) {
4410    pNewNode = m_pDocument->CreateNode(pPacket, eProperty);
4411    if (!pNewNode)
4412      return nullptr;
4413    InsertChild(pNewNode, nullptr);
4414    pNewNode->SetFlag(XFA_NodeFlag_Initialized, true);
4415  }
4416  return pNewNode;
4417}
4418
4419int32_t CXFA_Node::CountChildren(XFA_Element eType, bool bOnlyChild) {
4420  CXFA_Node* pNode = m_pChild;
4421  int32_t iCount = 0;
4422  for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
4423    if (pNode->GetElementType() == eType || eType == XFA_Element::Unknown) {
4424      if (bOnlyChild) {
4425        const XFA_PROPERTY* pProperty = XFA_GetPropertyOfElement(
4426            GetElementType(), pNode->GetElementType(), XFA_XDPPACKET_UNKNOWN);
4427        if (pProperty) {
4428          continue;
4429        }
4430      }
4431      iCount++;
4432    }
4433  }
4434  return iCount;
4435}
4436
4437CXFA_Node* CXFA_Node::GetChild(int32_t index,
4438                               XFA_Element eType,
4439                               bool bOnlyChild) {
4440  ASSERT(index > -1);
4441  CXFA_Node* pNode = m_pChild;
4442  int32_t iCount = 0;
4443  for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
4444    if (pNode->GetElementType() == eType || eType == XFA_Element::Unknown) {
4445      if (bOnlyChild) {
4446        const XFA_PROPERTY* pProperty = XFA_GetPropertyOfElement(
4447            GetElementType(), pNode->GetElementType(), XFA_XDPPACKET_UNKNOWN);
4448        if (pProperty) {
4449          continue;
4450        }
4451      }
4452      iCount++;
4453      if (iCount > index) {
4454        return pNode;
4455      }
4456    }
4457  }
4458  return nullptr;
4459}
4460
4461int32_t CXFA_Node::InsertChild(int32_t index, CXFA_Node* pNode) {
4462  ASSERT(!pNode->m_pNext);
4463  pNode->m_pParent = this;
4464  bool ret = m_pDocument->RemovePurgeNode(pNode);
4465  ASSERT(ret);
4466  (void)ret;  // Avoid unused variable warning.
4467
4468  if (!m_pChild || index == 0) {
4469    if (index > 0) {
4470      return -1;
4471    }
4472    pNode->m_pNext = m_pChild;
4473    m_pChild = pNode;
4474    index = 0;
4475  } else if (index < 0) {
4476    m_pLastChild->m_pNext = pNode;
4477  } else {
4478    CXFA_Node* pPrev = m_pChild;
4479    int32_t iCount = 0;
4480    while (++iCount != index && pPrev->m_pNext) {
4481      pPrev = pPrev->m_pNext;
4482    }
4483    if (index > 0 && index != iCount) {
4484      return -1;
4485    }
4486    pNode->m_pNext = pPrev->m_pNext;
4487    pPrev->m_pNext = pNode;
4488    index = iCount;
4489  }
4490  if (!pNode->m_pNext) {
4491    m_pLastChild = pNode;
4492  }
4493  ASSERT(m_pLastChild);
4494  ASSERT(!m_pLastChild->m_pNext);
4495  pNode->ClearFlag(XFA_NodeFlag_HasRemovedChildren);
4496  CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
4497  if (pNotify)
4498    pNotify->OnChildAdded(this);
4499
4500  if (IsNeedSavingXMLNode() && pNode->m_pXMLNode) {
4501    ASSERT(!pNode->m_pXMLNode->GetNodeItem(CFDE_XMLNode::Parent));
4502    m_pXMLNode->InsertChildNode(pNode->m_pXMLNode, index);
4503    pNode->ClearFlag(XFA_NodeFlag_OwnXMLNode);
4504  }
4505  return index;
4506}
4507
4508bool CXFA_Node::InsertChild(CXFA_Node* pNode, CXFA_Node* pBeforeNode) {
4509  if (!pNode || pNode->m_pParent ||
4510      (pBeforeNode && pBeforeNode->m_pParent != this)) {
4511    ASSERT(false);
4512    return false;
4513  }
4514  bool ret = m_pDocument->RemovePurgeNode(pNode);
4515  ASSERT(ret);
4516  (void)ret;  // Avoid unused variable warning.
4517
4518  int32_t nIndex = -1;
4519  pNode->m_pParent = this;
4520  if (!m_pChild || pBeforeNode == m_pChild) {
4521    pNode->m_pNext = m_pChild;
4522    m_pChild = pNode;
4523    nIndex = 0;
4524  } else if (!pBeforeNode) {
4525    pNode->m_pNext = m_pLastChild->m_pNext;
4526    m_pLastChild->m_pNext = pNode;
4527  } else {
4528    nIndex = 1;
4529    CXFA_Node* pPrev = m_pChild;
4530    while (pPrev->m_pNext != pBeforeNode) {
4531      pPrev = pPrev->m_pNext;
4532      nIndex++;
4533    }
4534    pNode->m_pNext = pPrev->m_pNext;
4535    pPrev->m_pNext = pNode;
4536  }
4537  if (!pNode->m_pNext) {
4538    m_pLastChild = pNode;
4539  }
4540  ASSERT(m_pLastChild);
4541  ASSERT(!m_pLastChild->m_pNext);
4542  pNode->ClearFlag(XFA_NodeFlag_HasRemovedChildren);
4543  CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
4544  if (pNotify)
4545    pNotify->OnChildAdded(this);
4546
4547  if (IsNeedSavingXMLNode() && pNode->m_pXMLNode) {
4548    ASSERT(!pNode->m_pXMLNode->GetNodeItem(CFDE_XMLNode::Parent));
4549    m_pXMLNode->InsertChildNode(pNode->m_pXMLNode, nIndex);
4550    pNode->ClearFlag(XFA_NodeFlag_OwnXMLNode);
4551  }
4552  return true;
4553}
4554
4555CXFA_Node* CXFA_Node::Deprecated_GetPrevSibling() {
4556  if (!m_pParent) {
4557    return nullptr;
4558  }
4559  for (CXFA_Node* pSibling = m_pParent->m_pChild; pSibling;
4560       pSibling = pSibling->m_pNext) {
4561    if (pSibling->m_pNext == this) {
4562      return pSibling;
4563    }
4564  }
4565  return nullptr;
4566}
4567
4568bool CXFA_Node::RemoveChild(CXFA_Node* pNode, bool bNotify) {
4569  if (!pNode || pNode->m_pParent != this) {
4570    ASSERT(false);
4571    return false;
4572  }
4573  if (m_pChild == pNode) {
4574    m_pChild = pNode->m_pNext;
4575    if (m_pLastChild == pNode) {
4576      m_pLastChild = pNode->m_pNext;
4577    }
4578    pNode->m_pNext = nullptr;
4579    pNode->m_pParent = nullptr;
4580  } else {
4581    CXFA_Node* pPrev = pNode->Deprecated_GetPrevSibling();
4582    pPrev->m_pNext = pNode->m_pNext;
4583    if (m_pLastChild == pNode) {
4584      m_pLastChild = pNode->m_pNext ? pNode->m_pNext : pPrev;
4585    }
4586    pNode->m_pNext = nullptr;
4587    pNode->m_pParent = nullptr;
4588  }
4589  ASSERT(!m_pLastChild || !m_pLastChild->m_pNext);
4590  OnRemoved(bNotify);
4591  pNode->SetFlag(XFA_NodeFlag_HasRemovedChildren, true);
4592  m_pDocument->AddPurgeNode(pNode);
4593  if (IsNeedSavingXMLNode() && pNode->m_pXMLNode) {
4594    if (pNode->IsAttributeInXML()) {
4595      ASSERT(pNode->m_pXMLNode == m_pXMLNode &&
4596             m_pXMLNode->GetType() == FDE_XMLNODE_Element);
4597      if (pNode->m_pXMLNode->GetType() == FDE_XMLNODE_Element) {
4598        CFDE_XMLElement* pXMLElement =
4599            static_cast<CFDE_XMLElement*>(pNode->m_pXMLNode);
4600        CFX_WideStringC wsAttributeName =
4601            pNode->GetCData(XFA_ATTRIBUTE_QualifiedName);
4602        pXMLElement->RemoveAttribute(wsAttributeName.c_str());
4603      }
4604      CFX_WideString wsName;
4605      pNode->GetAttribute(XFA_ATTRIBUTE_Name, wsName, false);
4606      CFDE_XMLElement* pNewXMLElement = new CFDE_XMLElement(wsName);
4607      CFX_WideStringC wsValue = GetCData(XFA_ATTRIBUTE_Value);
4608      if (!wsValue.IsEmpty()) {
4609        pNewXMLElement->SetTextData(CFX_WideString(wsValue));
4610      }
4611      pNode->m_pXMLNode = pNewXMLElement;
4612      pNode->SetEnum(XFA_ATTRIBUTE_Contains, XFA_ATTRIBUTEENUM_Unknown);
4613    } else {
4614      m_pXMLNode->RemoveChildNode(pNode->m_pXMLNode);
4615    }
4616    pNode->SetFlag(XFA_NodeFlag_OwnXMLNode, false);
4617  }
4618  return true;
4619}
4620
4621CXFA_Node* CXFA_Node::GetFirstChildByName(const CFX_WideStringC& wsName) const {
4622  return GetFirstChildByName(FX_HashCode_GetW(wsName, false));
4623}
4624
4625CXFA_Node* CXFA_Node::GetFirstChildByName(uint32_t dwNameHash) const {
4626  for (CXFA_Node* pNode = GetNodeItem(XFA_NODEITEM_FirstChild); pNode;
4627       pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
4628    if (pNode->GetNameHash() == dwNameHash) {
4629      return pNode;
4630    }
4631  }
4632  return nullptr;
4633}
4634
4635CXFA_Node* CXFA_Node::GetFirstChildByClass(XFA_Element eType) const {
4636  for (CXFA_Node* pNode = GetNodeItem(XFA_NODEITEM_FirstChild); pNode;
4637       pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
4638    if (pNode->GetElementType() == eType) {
4639      return pNode;
4640    }
4641  }
4642  return nullptr;
4643}
4644
4645CXFA_Node* CXFA_Node::GetNextSameNameSibling(uint32_t dwNameHash) const {
4646  for (CXFA_Node* pNode = GetNodeItem(XFA_NODEITEM_NextSibling); pNode;
4647       pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
4648    if (pNode->GetNameHash() == dwNameHash) {
4649      return pNode;
4650    }
4651  }
4652  return nullptr;
4653}
4654
4655CXFA_Node* CXFA_Node::GetNextSameNameSibling(
4656    const CFX_WideStringC& wsNodeName) const {
4657  return GetNextSameNameSibling(FX_HashCode_GetW(wsNodeName, false));
4658}
4659
4660CXFA_Node* CXFA_Node::GetNextSameClassSibling(XFA_Element eType) const {
4661  for (CXFA_Node* pNode = GetNodeItem(XFA_NODEITEM_NextSibling); pNode;
4662       pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
4663    if (pNode->GetElementType() == eType) {
4664      return pNode;
4665    }
4666  }
4667  return nullptr;
4668}
4669
4670int32_t CXFA_Node::GetNodeSameNameIndex() const {
4671  CXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
4672  if (!pScriptContext) {
4673    return -1;
4674  }
4675  return pScriptContext->GetIndexByName(const_cast<CXFA_Node*>(this));
4676}
4677
4678int32_t CXFA_Node::GetNodeSameClassIndex() const {
4679  CXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
4680  if (!pScriptContext) {
4681    return -1;
4682  }
4683  return pScriptContext->GetIndexByClassName(const_cast<CXFA_Node*>(this));
4684}
4685
4686void CXFA_Node::GetSOMExpression(CFX_WideString& wsSOMExpression) {
4687  CXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
4688  if (!pScriptContext) {
4689    return;
4690  }
4691  pScriptContext->GetSomExpression(this, wsSOMExpression);
4692}
4693
4694CXFA_Node* CXFA_Node::GetInstanceMgrOfSubform() {
4695  CXFA_Node* pInstanceMgr = nullptr;
4696  if (m_ePacket == XFA_XDPPACKET_Form) {
4697    CXFA_Node* pParentNode = GetNodeItem(XFA_NODEITEM_Parent);
4698    if (!pParentNode || pParentNode->GetElementType() == XFA_Element::Area) {
4699      return pInstanceMgr;
4700    }
4701    for (CXFA_Node* pNode = GetNodeItem(XFA_NODEITEM_PrevSibling); pNode;
4702         pNode = pNode->GetNodeItem(XFA_NODEITEM_PrevSibling)) {
4703      XFA_Element eType = pNode->GetElementType();
4704      if ((eType == XFA_Element::Subform || eType == XFA_Element::SubformSet) &&
4705          pNode->m_dwNameHash != m_dwNameHash) {
4706        break;
4707      }
4708      if (eType == XFA_Element::InstanceManager) {
4709        CFX_WideStringC wsName = GetCData(XFA_ATTRIBUTE_Name);
4710        CFX_WideStringC wsInstName = pNode->GetCData(XFA_ATTRIBUTE_Name);
4711        if (wsInstName.GetLength() > 0 && wsInstName.GetAt(0) == '_' &&
4712            wsInstName.Mid(1) == wsName) {
4713          pInstanceMgr = pNode;
4714        }
4715        break;
4716      }
4717    }
4718  }
4719  return pInstanceMgr;
4720}
4721
4722CXFA_Node* CXFA_Node::GetOccurNode() {
4723  return GetFirstChildByClass(XFA_Element::Occur);
4724}
4725
4726bool CXFA_Node::HasFlag(XFA_NodeFlag dwFlag) const {
4727  if (m_uNodeFlags & dwFlag)
4728    return true;
4729  if (dwFlag == XFA_NodeFlag_HasRemovedChildren)
4730    return m_pParent && m_pParent->HasFlag(dwFlag);
4731  return false;
4732}
4733
4734void CXFA_Node::SetFlag(uint32_t dwFlag, bool bNotify) {
4735  if (dwFlag == XFA_NodeFlag_Initialized && bNotify && !IsInitialized()) {
4736    CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
4737    if (pNotify) {
4738      pNotify->OnNodeReady(this);
4739    }
4740  }
4741  m_uNodeFlags |= dwFlag;
4742}
4743
4744void CXFA_Node::ClearFlag(uint32_t dwFlag) {
4745  m_uNodeFlags &= ~dwFlag;
4746}
4747
4748bool CXFA_Node::IsAttributeInXML() {
4749  return GetEnum(XFA_ATTRIBUTE_Contains) == XFA_ATTRIBUTEENUM_MetaData;
4750}
4751
4752void CXFA_Node::OnRemoved(bool bNotify) {
4753  if (!bNotify)
4754    return;
4755
4756  CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
4757  if (pNotify)
4758    pNotify->OnChildRemoved();
4759}
4760
4761void CXFA_Node::OnChanging(XFA_ATTRIBUTE eAttr, bool bNotify) {
4762  if (bNotify && IsInitialized()) {
4763    CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
4764    if (pNotify) {
4765      pNotify->OnValueChanging(this, eAttr);
4766    }
4767  }
4768}
4769
4770void CXFA_Node::OnChanged(XFA_ATTRIBUTE eAttr,
4771                          bool bNotify,
4772                          bool bScriptModify) {
4773  if (bNotify && IsInitialized()) {
4774    Script_Attribute_SendAttributeChangeMessage(eAttr, bScriptModify);
4775  }
4776}
4777
4778int32_t CXFA_Node::execSingleEventByName(const CFX_WideStringC& wsEventName,
4779                                         XFA_Element eType) {
4780  int32_t iRet = XFA_EVENTERROR_NotExist;
4781  const XFA_ExecEventParaInfo* eventParaInfo =
4782      GetEventParaInfoByName(wsEventName);
4783  if (eventParaInfo) {
4784    uint32_t validFlags = eventParaInfo->m_validFlags;
4785    CXFA_FFNotify* pNotify = m_pDocument->GetNotify();
4786    if (!pNotify) {
4787      return iRet;
4788    }
4789    if (validFlags == 1) {
4790      iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType);
4791    } else if (validFlags == 2) {
4792      iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType,
4793                                           false, false);
4794    } else if (validFlags == 3) {
4795      if (eType == XFA_Element::Subform) {
4796        iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType,
4797                                             false, false);
4798      }
4799    } else if (validFlags == 4) {
4800      if (eType == XFA_Element::ExclGroup || eType == XFA_Element::Field) {
4801        CXFA_Node* pParentNode = GetNodeItem(XFA_NODEITEM_Parent);
4802        if (pParentNode &&
4803            pParentNode->GetElementType() == XFA_Element::ExclGroup) {
4804          iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType,
4805                                               false, false);
4806        }
4807        iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType,
4808                                             false, false);
4809      }
4810    } else if (validFlags == 5) {
4811      if (eType == XFA_Element::Field) {
4812        iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType,
4813                                             false, false);
4814      }
4815    } else if (validFlags == 6) {
4816      CXFA_WidgetData* pWidgetData = GetWidgetData();
4817      if (pWidgetData) {
4818        CXFA_Node* pUINode = pWidgetData->GetUIChild();
4819        if (pUINode->m_elementType == XFA_Element::Signature) {
4820          iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType,
4821                                               false, false);
4822        }
4823      }
4824    } else if (validFlags == 7) {
4825      CXFA_WidgetData* pWidgetData = GetWidgetData();
4826      if (pWidgetData) {
4827        CXFA_Node* pUINode = pWidgetData->GetUIChild();
4828        if ((pUINode->m_elementType == XFA_Element::ChoiceList) &&
4829            (!pWidgetData->IsListBox())) {
4830          iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType,
4831                                               false, false);
4832        }
4833      }
4834    }
4835  }
4836  return iRet;
4837}
4838
4839void CXFA_Node::UpdateNameHash() {
4840  const XFA_NOTSUREATTRIBUTE* pNotsure =
4841      XFA_GetNotsureAttribute(GetElementType(), XFA_ATTRIBUTE_Name);
4842  CFX_WideStringC wsName;
4843  if (!pNotsure || pNotsure->eType == XFA_ATTRIBUTETYPE_Cdata) {
4844    wsName = GetCData(XFA_ATTRIBUTE_Name);
4845    m_dwNameHash = FX_HashCode_GetW(wsName, false);
4846  } else if (pNotsure->eType == XFA_ATTRIBUTETYPE_Enum) {
4847    wsName = GetAttributeEnumByID(GetEnum(XFA_ATTRIBUTE_Name))->pName;
4848    m_dwNameHash = FX_HashCode_GetW(wsName, false);
4849  }
4850}
4851
4852CFDE_XMLNode* CXFA_Node::CreateXMLMappingNode() {
4853  if (!m_pXMLNode) {
4854    CFX_WideString wsTag(GetCData(XFA_ATTRIBUTE_Name));
4855    m_pXMLNode = new CFDE_XMLElement(wsTag);
4856    SetFlag(XFA_NodeFlag_OwnXMLNode, false);
4857  }
4858  return m_pXMLNode;
4859}
4860
4861bool CXFA_Node::IsNeedSavingXMLNode() {
4862  return m_pXMLNode && (GetPacketID() == XFA_XDPPACKET_Datasets ||
4863                        GetElementType() == XFA_Element::Xfa);
4864}
4865
4866XFA_MAPMODULEDATA* CXFA_Node::CreateMapModuleData() {
4867  if (!m_pMapModuleData)
4868    m_pMapModuleData = new XFA_MAPMODULEDATA;
4869  return m_pMapModuleData;
4870}
4871
4872XFA_MAPMODULEDATA* CXFA_Node::GetMapModuleData() const {
4873  return m_pMapModuleData;
4874}
4875
4876void CXFA_Node::SetMapModuleValue(void* pKey, void* pValue) {
4877  XFA_MAPMODULEDATA* pModule = CreateMapModuleData();
4878  pModule->m_ValueMap[pKey] = pValue;
4879}
4880
4881bool CXFA_Node::GetMapModuleValue(void* pKey, void*& pValue) {
4882  for (CXFA_Node* pNode = this; pNode; pNode = pNode->GetTemplateNode()) {
4883    XFA_MAPMODULEDATA* pModule = pNode->GetMapModuleData();
4884    if (pModule) {
4885      auto it = pModule->m_ValueMap.find(pKey);
4886      if (it != pModule->m_ValueMap.end()) {
4887        pValue = it->second;
4888        return true;
4889      }
4890    }
4891    if (pNode->GetPacketID() == XFA_XDPPACKET_Datasets)
4892      break;
4893  }
4894  return false;
4895}
4896
4897void CXFA_Node::SetMapModuleString(void* pKey, const CFX_WideStringC& wsValue) {
4898  SetMapModuleBuffer(pKey, (void*)wsValue.c_str(),
4899                     wsValue.GetLength() * sizeof(FX_WCHAR));
4900}
4901
4902bool CXFA_Node::GetMapModuleString(void* pKey, CFX_WideStringC& wsValue) {
4903  void* pValue;
4904  int32_t iBytes;
4905  if (!GetMapModuleBuffer(pKey, pValue, iBytes)) {
4906    return false;
4907  }
4908  wsValue = CFX_WideStringC((const FX_WCHAR*)pValue, iBytes / sizeof(FX_WCHAR));
4909  return true;
4910}
4911
4912void CXFA_Node::SetMapModuleBuffer(
4913    void* pKey,
4914    void* pValue,
4915    int32_t iBytes,
4916    XFA_MAPDATABLOCKCALLBACKINFO* pCallbackInfo) {
4917  XFA_MAPMODULEDATA* pModule = CreateMapModuleData();
4918  XFA_MAPDATABLOCK*& pBuffer = pModule->m_BufferMap[pKey];
4919  if (!pBuffer) {
4920    pBuffer =
4921        (XFA_MAPDATABLOCK*)FX_Alloc(uint8_t, sizeof(XFA_MAPDATABLOCK) + iBytes);
4922  } else if (pBuffer->iBytes != iBytes) {
4923    if (pBuffer->pCallbackInfo && pBuffer->pCallbackInfo->pFree) {
4924      pBuffer->pCallbackInfo->pFree(*(void**)pBuffer->GetData());
4925    }
4926    pBuffer = (XFA_MAPDATABLOCK*)FX_Realloc(uint8_t, pBuffer,
4927                                            sizeof(XFA_MAPDATABLOCK) + iBytes);
4928  } else if (pBuffer->pCallbackInfo && pBuffer->pCallbackInfo->pFree) {
4929    pBuffer->pCallbackInfo->pFree(*(void**)pBuffer->GetData());
4930  }
4931  if (!pBuffer)
4932    return;
4933
4934  pBuffer->pCallbackInfo = pCallbackInfo;
4935  pBuffer->iBytes = iBytes;
4936  FXSYS_memcpy(pBuffer->GetData(), pValue, iBytes);
4937}
4938
4939bool CXFA_Node::GetMapModuleBuffer(void* pKey,
4940                                   void*& pValue,
4941                                   int32_t& iBytes,
4942                                   bool bProtoAlso) const {
4943  XFA_MAPDATABLOCK* pBuffer = nullptr;
4944  for (const CXFA_Node* pNode = this; pNode; pNode = pNode->GetTemplateNode()) {
4945    XFA_MAPMODULEDATA* pModule = pNode->GetMapModuleData();
4946    if (pModule) {
4947      auto it = pModule->m_BufferMap.find(pKey);
4948      if (it != pModule->m_BufferMap.end()) {
4949        pBuffer = it->second;
4950        break;
4951      }
4952    }
4953    if (!bProtoAlso || pNode->GetPacketID() == XFA_XDPPACKET_Datasets)
4954      break;
4955  }
4956  if (!pBuffer)
4957    return false;
4958
4959  pValue = pBuffer->GetData();
4960  iBytes = pBuffer->iBytes;
4961  return true;
4962}
4963
4964bool CXFA_Node::HasMapModuleKey(void* pKey, bool bProtoAlso) {
4965  for (CXFA_Node* pNode = this; pNode; pNode = pNode->GetTemplateNode()) {
4966    XFA_MAPMODULEDATA* pModule = pNode->GetMapModuleData();
4967    if (pModule) {
4968      auto it1 = pModule->m_ValueMap.find(pKey);
4969      if (it1 != pModule->m_ValueMap.end())
4970        return true;
4971
4972      auto it2 = pModule->m_BufferMap.find(pKey);
4973      if (it2 != pModule->m_BufferMap.end())
4974        return true;
4975    }
4976    if (!bProtoAlso || pNode->GetPacketID() == XFA_XDPPACKET_Datasets)
4977      break;
4978  }
4979  return false;
4980}
4981
4982void CXFA_Node::RemoveMapModuleKey(void* pKey) {
4983  XFA_MAPMODULEDATA* pModule = GetMapModuleData();
4984  if (!pModule)
4985    return;
4986
4987  if (pKey) {
4988    auto it = pModule->m_BufferMap.find(pKey);
4989    if (it != pModule->m_BufferMap.end()) {
4990      XFA_MAPDATABLOCK* pBuffer = it->second;
4991      if (pBuffer) {
4992        if (pBuffer->pCallbackInfo && pBuffer->pCallbackInfo->pFree)
4993          pBuffer->pCallbackInfo->pFree(*(void**)pBuffer->GetData());
4994        FX_Free(pBuffer);
4995      }
4996      pModule->m_BufferMap.erase(it);
4997    }
4998    pModule->m_ValueMap.erase(pKey);
4999    return;
5000  }
5001
5002  for (auto& pair : pModule->m_BufferMap) {
5003    XFA_MAPDATABLOCK* pBuffer = pair.second;
5004    if (pBuffer) {
5005      if (pBuffer->pCallbackInfo && pBuffer->pCallbackInfo->pFree)
5006        pBuffer->pCallbackInfo->pFree(*(void**)pBuffer->GetData());
5007      FX_Free(pBuffer);
5008    }
5009  }
5010  pModule->m_BufferMap.clear();
5011  pModule->m_ValueMap.clear();
5012  delete pModule;
5013}
5014
5015void CXFA_Node::MergeAllData(void* pDstModule) {
5016  XFA_MAPMODULEDATA* pDstModuleData =
5017      static_cast<CXFA_Node*>(pDstModule)->CreateMapModuleData();
5018  XFA_MAPMODULEDATA* pSrcModuleData = GetMapModuleData();
5019  if (!pSrcModuleData)
5020    return;
5021
5022  for (const auto& pair : pSrcModuleData->m_ValueMap)
5023    pDstModuleData->m_ValueMap[pair.first] = pair.second;
5024
5025  for (const auto& pair : pSrcModuleData->m_BufferMap) {
5026    XFA_MAPDATABLOCK* pSrcBuffer = pair.second;
5027    XFA_MAPDATABLOCK*& pDstBuffer = pDstModuleData->m_BufferMap[pair.first];
5028    if (pSrcBuffer->pCallbackInfo && pSrcBuffer->pCallbackInfo->pFree &&
5029        !pSrcBuffer->pCallbackInfo->pCopy) {
5030      if (pDstBuffer) {
5031        pDstBuffer->pCallbackInfo->pFree(*(void**)pDstBuffer->GetData());
5032        pDstModuleData->m_BufferMap.erase(pair.first);
5033      }
5034      continue;
5035    }
5036    if (!pDstBuffer) {
5037      pDstBuffer = (XFA_MAPDATABLOCK*)FX_Alloc(
5038          uint8_t, sizeof(XFA_MAPDATABLOCK) + pSrcBuffer->iBytes);
5039    } else if (pDstBuffer->iBytes != pSrcBuffer->iBytes) {
5040      if (pDstBuffer->pCallbackInfo && pDstBuffer->pCallbackInfo->pFree) {
5041        pDstBuffer->pCallbackInfo->pFree(*(void**)pDstBuffer->GetData());
5042      }
5043      pDstBuffer = (XFA_MAPDATABLOCK*)FX_Realloc(
5044          uint8_t, pDstBuffer, sizeof(XFA_MAPDATABLOCK) + pSrcBuffer->iBytes);
5045    } else if (pDstBuffer->pCallbackInfo && pDstBuffer->pCallbackInfo->pFree) {
5046      pDstBuffer->pCallbackInfo->pFree(*(void**)pDstBuffer->GetData());
5047    }
5048    if (!pDstBuffer) {
5049      continue;
5050    }
5051    pDstBuffer->pCallbackInfo = pSrcBuffer->pCallbackInfo;
5052    pDstBuffer->iBytes = pSrcBuffer->iBytes;
5053    FXSYS_memcpy(pDstBuffer->GetData(), pSrcBuffer->GetData(),
5054                 pSrcBuffer->iBytes);
5055    if (pDstBuffer->pCallbackInfo && pDstBuffer->pCallbackInfo->pCopy) {
5056      pDstBuffer->pCallbackInfo->pCopy(*(void**)pDstBuffer->GetData());
5057    }
5058  }
5059}
5060
5061void CXFA_Node::MoveBufferMapData(CXFA_Node* pDstModule, void* pKey) {
5062  if (!pDstModule) {
5063    return;
5064  }
5065  bool bNeedMove = true;
5066  if (!pKey) {
5067    bNeedMove = false;
5068  }
5069  if (pDstModule->GetElementType() != GetElementType()) {
5070    bNeedMove = false;
5071  }
5072  XFA_MAPMODULEDATA* pSrcModuleData = nullptr;
5073  XFA_MAPMODULEDATA* pDstModuleData = nullptr;
5074  if (bNeedMove) {
5075    pSrcModuleData = GetMapModuleData();
5076    if (!pSrcModuleData) {
5077      bNeedMove = false;
5078    }
5079    pDstModuleData = pDstModule->CreateMapModuleData();
5080  }
5081  if (bNeedMove) {
5082    auto it = pSrcModuleData->m_BufferMap.find(pKey);
5083    if (it != pSrcModuleData->m_BufferMap.end()) {
5084      XFA_MAPDATABLOCK* pBufferBlockData = it->second;
5085      if (pBufferBlockData) {
5086        pSrcModuleData->m_BufferMap.erase(pKey);
5087        pDstModuleData->m_BufferMap[pKey] = pBufferBlockData;
5088      }
5089    }
5090  }
5091  if (pDstModule->IsNodeV()) {
5092    CFX_WideString wsValue = pDstModule->GetScriptContent(false);
5093    CFX_WideString wsFormatValue(wsValue);
5094    CXFA_WidgetData* pWidgetData = pDstModule->GetContainerWidgetData();
5095    if (pWidgetData) {
5096      pWidgetData->GetFormatDataValue(wsValue, wsFormatValue);
5097    }
5098    pDstModule->SetScriptContent(wsValue, wsFormatValue, true, true);
5099  }
5100}
5101
5102void CXFA_Node::MoveBufferMapData(CXFA_Node* pSrcModule,
5103                                  CXFA_Node* pDstModule,
5104                                  void* pKey,
5105                                  bool bRecursive) {
5106  if (!pSrcModule || !pDstModule || !pKey) {
5107    return;
5108  }
5109  if (bRecursive) {
5110    CXFA_Node* pSrcChild = pSrcModule->GetNodeItem(XFA_NODEITEM_FirstChild);
5111    CXFA_Node* pDstChild = pDstModule->GetNodeItem(XFA_NODEITEM_FirstChild);
5112    for (; pSrcChild && pDstChild;
5113         pSrcChild = pSrcChild->GetNodeItem(XFA_NODEITEM_NextSibling),
5114         pDstChild = pDstChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
5115      MoveBufferMapData(pSrcChild, pDstChild, pKey, true);
5116    }
5117  }
5118  pSrcModule->MoveBufferMapData(pDstModule, pKey);
5119}
5120
5121void CXFA_Node::ThrowMissingPropertyException(
5122    const CFX_WideString& obj,
5123    const CFX_WideString& prop) const {
5124  ThrowException(L"'%s' doesn't have property '%s'.", obj.c_str(),
5125                 prop.c_str());
5126}
5127
5128void CXFA_Node::ThrowTooManyOccurancesException(
5129    const CFX_WideString& obj) const {
5130  ThrowException(
5131      L"The element [%s] has violated its allowable number of occurrences.",
5132      obj.c_str());
5133}
5134