Use CXFA_Subform subclass argument in IndexChangedSubform().

Replace a DCHECK() with type-safe implementation.

In turn, add helper method so that all callers have checked element
type before casting to sub-class.

Change-Id: I99e25088255aa0a9a2d12955e75d5abb40a2f9f2
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/94012
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/fxjs/xfa/cjx_instancemanager.cpp b/fxjs/xfa/cjx_instancemanager.cpp
index 23feab7..dc8ce3e 100644
--- a/fxjs/xfa/cjx_instancemanager.cpp
+++ b/fxjs/xfa/cjx_instancemanager.cpp
@@ -20,6 +20,7 @@
 #include "xfa/fxfa/parser/cxfa_document.h"
 #include "xfa/fxfa/parser/cxfa_instancemanager.h"
 #include "xfa/fxfa/parser/cxfa_occur.h"
+#include "xfa/fxfa/parser/cxfa_subform.h"
 
 const CJX_MethodSpec CJX_InstanceManager::MethodSpecs[] = {
     {"addInstance", addInstance_static},
@@ -151,15 +152,14 @@
   if (!pNotify)
     return CJS_Result::Success();
 
-  CXFA_Node* pToInstance = GetXFANode()->GetItemIfExists(iTo);
-  if (pToInstance && pToInstance->GetElementType() == XFA_Element::Subform)
+  CXFA_Node* pXFA = GetXFANode();
+  auto* pToInstance = CXFA_Subform::FromNode(pXFA->GetItemIfExists(iTo));
+  if (pToInstance)
     pNotify->RunSubformIndexChange(pToInstance);
 
-  CXFA_Node* pFromInstance = GetXFANode()->GetItemIfExists(iFrom);
-  if (pFromInstance &&
-      pFromInstance->GetElementType() == XFA_Element::Subform) {
+  auto* pFromInstance = CXFA_Subform::FromNode(pXFA->GetItemIfExists(iFrom));
+  if (pFromInstance)
     pNotify->RunSubformIndexChange(pFromInstance);
-  }
 
   return CJS_Result::Success();
 }
@@ -192,12 +192,11 @@
 
   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
   if (pNotify) {
+    CXFA_Node* pXFA = GetXFANode();
     for (int32_t i = iIndex; i < iCount - 1; i++) {
-      CXFA_Node* pSubformInstance = GetXFANode()->GetItemIfExists(i);
-      if (pSubformInstance &&
-          pSubformInstance->GetElementType() == XFA_Element::Subform) {
+      auto* pSubformInstance = CXFA_Subform::FromNode(pXFA->GetItemIfExists(i));
+      if (pSubformInstance)
         pNotify->RunSubformIndexChange(pSubformInstance);
-      }
     }
   }
   GetDocument()->GetLayoutProcessor()->SetHasChangedContainer();
diff --git a/fxjs/xfa/cjx_object.cpp b/fxjs/xfa/cjx_object.cpp
index f06fe1b..1449cab 100644
--- a/fxjs/xfa/cjx_object.cpp
+++ b/fxjs/xfa/cjx_object.cpp
@@ -1425,16 +1425,15 @@
   if (!pNotify)
     return;
 
-  CXFA_Node* pToInstance = pManagerNode->GetItemIfExists(iTo);
-  if (pToInstance && pToInstance->GetElementType() == XFA_Element::Subform) {
+  auto* pToInstance =
+      CXFA_Subform::FromNode(pManagerNode->GetItemIfExists(iTo));
+  if (pToInstance)
     pNotify->RunSubformIndexChange(pToInstance);
-  }
 
-  CXFA_Node* pFromInstance = pManagerNode->GetItemIfExists(iFrom);
-  if (pFromInstance &&
-      pFromInstance->GetElementType() == XFA_Element::Subform) {
+  auto* pFromInstance =
+      CXFA_Subform::FromNode(pManagerNode->GetItemIfExists(iFrom));
+  if (pFromInstance)
     pNotify->RunSubformIndexChange(pFromInstance);
-  }
 }
 
 void CJX_Object::ScriptSubmitFormatMode(v8::Isolate* pIsolate,
diff --git a/xfa/fxfa/cxfa_ffdocview.cpp b/xfa/fxfa/cxfa_ffdocview.cpp
index ae6eaca..480bc72 100644
--- a/xfa/fxfa/cxfa_ffdocview.cpp
+++ b/xfa/fxfa/cxfa_ffdocview.cpp
@@ -520,8 +520,7 @@
   InitLayout(pNode);
 }
 
-void CXFA_FFDocView::AddIndexChangedSubform(CXFA_Node* pNode) {
-  DCHECK_EQ(pNode->GetElementType(), XFA_Element::Subform);
+void CXFA_FFDocView::AddIndexChangedSubform(CXFA_Subform* pNode) {
   if (!pdfium::Contains(m_IndexChangedSubforms, pNode))
     m_IndexChangedSubforms.push_back(pNode);
 }
diff --git a/xfa/fxfa/cxfa_ffdocview.h b/xfa/fxfa/cxfa_ffdocview.h
index a10e2c4..d4cbd34 100644
--- a/xfa/fxfa/cxfa_ffdocview.h
+++ b/xfa/fxfa/cxfa_ffdocview.h
@@ -23,6 +23,7 @@
 class CXFA_FFDoc;
 class CXFA_FFWidgetHandler;
 class CXFA_Node;
+class CXFA_Subform;
 class CXFA_ViewLayoutItem;
 
 extern const XFA_AttributeValue kXFAEventActivity[];
@@ -88,7 +89,7 @@
 
   bool RunLayout();
   void AddNewFormNode(CXFA_Node* pNode);
-  void AddIndexChangedSubform(CXFA_Node* pNode);
+  void AddIndexChangedSubform(CXFA_Subform* pNode);
   CXFA_Node* GetFocusNode() const { return m_pFocusNode; }
   void SetFocusNode(CXFA_Node* pNode);
   void DeleteLayoutItem(CXFA_FFWidget* pWidget);
@@ -125,7 +126,7 @@
   std::vector<cppgc::Member<CXFA_Node>> m_CalculateNodes;
   std::list<cppgc::Member<CXFA_BindItems>> m_BindItems;
   std::list<cppgc::Member<CXFA_Node>> m_NewAddedNodes;
-  std::list<cppgc::Member<CXFA_Node>> m_IndexChangedSubforms;
+  std::list<cppgc::Member<CXFA_Subform>> m_IndexChangedSubforms;
   std::vector<WideString> m_NullTestMsgArray;
   bool m_bLayoutEvent = false;
   bool m_bInLayoutStatus = false;
diff --git a/xfa/fxfa/cxfa_ffnotify.cpp b/xfa/fxfa/cxfa_ffnotify.cpp
index 7c24967..e12c5cb 100644
--- a/xfa/fxfa/cxfa_ffnotify.cpp
+++ b/xfa/fxfa/cxfa_ffnotify.cpp
@@ -307,7 +307,7 @@
   pDocView->AddNewFormNode(pNode);
 }
 
-void CXFA_FFNotify::RunSubformIndexChange(CXFA_Node* pSubformNode) {
+void CXFA_FFNotify::RunSubformIndexChange(CXFA_Subform* pSubformNode) {
   CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
   if (!pDocView)
     return;
diff --git a/xfa/fxfa/cxfa_ffnotify.h b/xfa/fxfa/cxfa_ffnotify.h
index 51d9fa5..5483b6e 100644
--- a/xfa/fxfa/cxfa_ffnotify.h
+++ b/xfa/fxfa/cxfa_ffnotify.h
@@ -76,7 +76,7 @@
   void ResetData(CXFA_Node* pNode);
   CXFA_FFDocView::LayoutStatus GetLayoutStatus();
   void RunNodeInitialize(CXFA_Node* pNode);
-  void RunSubformIndexChange(CXFA_Node* pSubformNode);
+  void RunSubformIndexChange(CXFA_Subform* pSubformNode);
   CXFA_Node* GetFocusWidgetNode();
   void SetFocusWidgetNode(CXFA_Node* pNode);
 
diff --git a/xfa/fxfa/parser/cxfa_subform.cpp b/xfa/fxfa/parser/cxfa_subform.cpp
index 8260c15..b91af63 100644
--- a/xfa/fxfa/parser/cxfa_subform.cpp
+++ b/xfa/fxfa/parser/cxfa_subform.cpp
@@ -63,6 +63,13 @@
 
 }  // namespace
 
+// static
+CXFA_Subform* CXFA_Subform::FromNode(CXFA_Node* pNode) {
+  return pNode && pNode->GetElementType() == XFA_Element::Subform
+             ? static_cast<CXFA_Subform*>(pNode)
+             : nullptr;
+}
+
 CXFA_Subform::CXFA_Subform(CXFA_Document* doc, XFA_PacketType packet)
     : CXFA_Node(doc,
                 packet,
diff --git a/xfa/fxfa/parser/cxfa_subform.h b/xfa/fxfa/parser/cxfa_subform.h
index 8b43fca..cd6687d 100644
--- a/xfa/fxfa/parser/cxfa_subform.h
+++ b/xfa/fxfa/parser/cxfa_subform.h
@@ -11,6 +11,8 @@
 
 class CXFA_Subform final : public CXFA_Node {
  public:
+  static CXFA_Subform* FromNode(CXFA_Node* pNode);
+
   CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_Subform() override;