Move some parser-tree node traversals from layout/ to parser/

Avoid more parse tree vs. layout tree confusion.

-- move one non-trivial function from .h to .cpp while at it.

Change-Id: I8cbbfd765d57c7dc20de17c13a59d236117cf9f0
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/56298
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/xfa/fxfa/layout/cxfa_layoutpagemgr.cpp b/xfa/fxfa/layout/cxfa_layoutpagemgr.cpp
index 5c3c385..a09b0cd 100644
--- a/xfa/fxfa/layout/cxfa_layoutpagemgr.cpp
+++ b/xfa/fxfa/layout/cxfa_layoutpagemgr.cpp
@@ -1600,27 +1600,20 @@
 
 void CXFA_LayoutPageMgr::SaveLayoutItemChildren(
     CXFA_LayoutItem* pParentLayoutItem) {
+  CXFA_Document* pDocument = m_pTemplatePageSetRoot->GetDocument();
+  CXFA_FFNotify* pNotify = pDocument->GetNotify();
+  auto* pDocLayout = CXFA_LayoutProcessor::FromDocument(pDocument);
   CXFA_LayoutItem* pCurLayoutItem = pParentLayoutItem->GetFirstChild();
   while (pCurLayoutItem) {
     CXFA_LayoutItem* pNextLayoutItem = pCurLayoutItem->GetNextSibling();
     if (pCurLayoutItem->IsContentLayoutItem()) {
       if (pCurLayoutItem->GetFormNode()->HasRemovedChildren()) {
-        CXFA_FFNotify* pNotify =
-            m_pTemplatePageSetRoot->GetDocument()->GetNotify();
-        auto* pDocLayout = CXFA_LayoutProcessor::FromDocument(
-            m_pTemplatePageSetRoot->GetDocument());
         SyncRemoveLayoutItem(pCurLayoutItem, pNotify, pDocLayout);
         pCurLayoutItem = pNextLayoutItem;
         continue;
       }
-      if (pCurLayoutItem->GetFormNode()->IsLayoutGeneratedNode()) {
-        CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode>
-            sIterator(pCurLayoutItem->GetFormNode());
-        for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
-             pNode = sIterator.MoveToNext()) {
-          pNode->SetFlag(XFA_NodeFlag_UnusedNode);
-        }
-      }
+      if (pCurLayoutItem->GetFormNode()->IsLayoutGeneratedNode())
+        pCurLayoutItem->GetFormNode()->SetNodeAndDescendantsUnused();
     }
     SaveLayoutItemChildren(pCurLayoutItem);
     pCurLayoutItem->RemoveSelfIfParented();
@@ -1658,24 +1651,11 @@
 
 void CXFA_LayoutPageMgr::MergePageSetContents() {
   CXFA_Document* pDocument = m_pTemplatePageSetRoot->GetDocument();
+  pDocument->SetPendingNodesUnusedAndUnbound();
+
   CXFA_FFNotify* pNotify = pDocument->GetNotify();
   auto* pDocLayout = CXFA_LayoutProcessor::FromDocument(pDocument);
   CXFA_ViewLayoutItem* pRootLayout = GetRootLayoutItem();
-  for (CXFA_Node* pPageNode : pDocument->m_pPendingPageSet) {
-    CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode>
-        sIterator(pPageNode);
-    for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
-         pNode = sIterator.MoveToNext()) {
-      if (pNode->IsContainerNode()) {
-        CXFA_Node* pBindNode = pNode->GetBindData();
-        if (pBindNode) {
-          pBindNode->RemoveBindItem(pNode);
-          pNode->SetBindingNode(nullptr);
-        }
-      }
-      pNode->SetFlag(XFA_NodeFlag_UnusedNode);
-    }
-  }
 
   int32_t iIndex = 0;
   for (; pRootLayout;
diff --git a/xfa/fxfa/parser/cxfa_document.cpp b/xfa/fxfa/parser/cxfa_document.cpp
index 7a2b579..9ad84bd 100644
--- a/xfa/fxfa/parser/cxfa_document.cpp
+++ b/xfa/fxfa/parser/cxfa_document.cpp
@@ -1818,6 +1818,23 @@
   m_rgGlobalBinding[dwNameHash] = pDataNode;
 }
 
+void CXFA_Document::SetPendingNodesUnusedAndUnbound() {
+  for (CXFA_Node* pPageNode : m_pPendingPageSet) {
+    CXFA_NodeIterator sIterator(pPageNode);
+    for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
+         pNode = sIterator.MoveToNext()) {
+      if (pNode->IsContainerNode()) {
+        CXFA_Node* pBindNode = pNode->GetBindData();
+        if (pBindNode) {
+          pBindNode->RemoveBindItem(pNode);
+          pNode->SetBindingNode(nullptr);
+        }
+      }
+      pNode->SetFlag(XFA_NodeFlag_UnusedNode);
+    }
+  }
+}
+
 CXFA_Document::LayoutProcessorIface::LayoutProcessorIface() = default;
 
 CXFA_Document::LayoutProcessorIface::~LayoutProcessorIface() = default;
diff --git a/xfa/fxfa/parser/cxfa_document.h b/xfa/fxfa/parser/cxfa_document.h
index b8fce80..ca40234 100644
--- a/xfa/fxfa/parser/cxfa_document.h
+++ b/xfa/fxfa/parser/cxfa_document.h
@@ -122,6 +122,7 @@
 
   CXFA_Node* GetGlobalBinding(uint32_t dwNameHash);
   void RegisterGlobalBinding(uint32_t dwNameHash, CXFA_Node* pDataNode);
+  void SetPendingNodesUnusedAndUnbound();
 
   std::vector<CXFA_Node*> m_pPendingPageSet;
 
diff --git a/xfa/fxfa/parser/cxfa_node.cpp b/xfa/fxfa/parser/cxfa_node.cpp
index a0a1e53..ecd0264 100644
--- a/xfa/fxfa/parser/cxfa_node.cpp
+++ b/xfa/fxfa/parser/cxfa_node.cpp
@@ -329,6 +329,7 @@
 #include "xfa/fxfa/parser/cxfa_traversal.h"
 #include "xfa/fxfa/parser/cxfa_traverse.h"
 #include "xfa/fxfa/parser/cxfa_traversestrategy_xfacontainernode.h"
+#include "xfa/fxfa/parser/cxfa_traversestrategy_xfanode.h"
 #include "xfa/fxfa/parser/cxfa_type.h"
 #include "xfa/fxfa/parser/cxfa_typeface.h"
 #include "xfa/fxfa/parser/cxfa_typefaces.h"
@@ -5009,6 +5010,20 @@
          ePresence == XFA_AttributeValue::Invisible;
 }
 
+void CXFA_Node::SetBindingNode(CXFA_Node* node) {
+  binding_nodes_.clear();
+  if (node)
+    binding_nodes_.emplace_back(node);
+}
+
+void CXFA_Node::SetNodeAndDescendantsUnused() {
+  CXFA_NodeIterator sIterator(this);
+  for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
+       pNode = sIterator.MoveToNext()) {
+    pNode->SetFlag(XFA_NodeFlag_UnusedNode);
+  }
+}
+
 void CXFA_Node::SetToXML(const WideString& value) {
   auto* pNode = GetXMLMappingNode();
   switch (pNode->GetType()) {
diff --git a/xfa/fxfa/parser/cxfa_node.h b/xfa/fxfa/parser/cxfa_node.h
index 1f70d60..b4466db 100644
--- a/xfa/fxfa/parser/cxfa_node.h
+++ b/xfa/fxfa/parser/cxfa_node.h
@@ -130,12 +130,8 @@
   }
 
   bool PresenceRequiresSpace() const;
-
-  void SetBindingNode(CXFA_Node* node) {
-    binding_nodes_.clear();
-    if (node)
-      binding_nodes_.emplace_back(node);
-  }
+  void SetBindingNode(CXFA_Node* node);
+  void SetNodeAndDescendantsUnused();
 
   bool HasRemovedChildren() const {
     return HasFlag(XFA_NodeFlag_HasRemovedChildren);