summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Sinclair <dsinclair@chromium.org>2017-11-20 20:27:43 +0000
committerChromium commit bot <commit-bot@chromium.org>2017-11-20 20:27:43 +0000
commit68c77592f25f9173d2166fa01fb34b4155f4cfcb (patch)
treeced2e1308f8b1e6b4c0934dc5f3b1c697223de61
parentfae5e26d983848089e35e2b53e9da24036661b08 (diff)
downloadpdfium-68c77592f25f9173d2166fa01fb34b4155f4cfcb.tar.xz
Remove {Set|Get|Try}Object methods
The CJX_Node::{Set|Get|Try}Object methods are used to set CXFA_WidgetData and CXFA_Node objects into the CJX_Node. This is stored in the node as void* data and custom delete methods are passed when needed. Instead, this CL just stores the two types of things we need on the CJX_Node and returns the correct types. This uses a bit more space on the CJX_Node, but it makes the code a lot clearer and simpler. Change-Id: I8546ea6456a1c1f5f8b602a6a420a0e85f3fac29 Reviewed-on: https://pdfium-review.googlesource.com/18570 Reviewed-by: Tom Sepez <tsepez@chromium.org> Commit-Queue: dsinclair <dsinclair@chromium.org>
-rw-r--r--fxjs/cjx_node.cpp47
-rw-r--r--fxjs/cjx_node.h31
-rw-r--r--xfa/fxfa/cxfa_ffnotify.cpp15
-rw-r--r--xfa/fxfa/cxfa_widgetacc.h2
-rw-r--r--xfa/fxfa/parser/cxfa_datadata.cpp4
-rw-r--r--xfa/fxfa/parser/cxfa_datadata.h3
-rw-r--r--xfa/fxfa/parser/cxfa_document.cpp4
-rw-r--r--xfa/fxfa/parser/cxfa_filldata.h2
-rw-r--r--xfa/fxfa/parser/cxfa_itemlayoutprocessor.cpp3
-rw-r--r--xfa/fxfa/parser/cxfa_layoutpagemgr.cpp3
-rw-r--r--xfa/fxfa/parser/cxfa_node.cpp113
-rw-r--r--xfa/fxfa/parser/cxfa_node.h3
-rw-r--r--xfa/fxfa/parser/xfa_document_datamerger_imp.cpp8
13 files changed, 125 insertions, 113 deletions
diff --git a/fxjs/cjx_node.cpp b/fxjs/cjx_node.cpp
index 07b96b895f..b86c2fa6fb 100644
--- a/fxjs/cjx_node.cpp
+++ b/fxjs/cjx_node.cpp
@@ -1439,14 +1439,14 @@ void CJX_Node::Script_Som_DefaultValue(CFXJSE_Value* pValue,
}
if (bSetting) {
WideString wsNewValue;
- if (!(pValue && (pValue->IsNull() || pValue->IsUndefined())))
+ if (pValue && !(pValue->IsNull() || pValue->IsUndefined()))
wsNewValue = pValue->ToWideString();
WideString wsFormatValue(wsNewValue);
CXFA_WidgetData* pContainerWidgetData = nullptr;
if (GetXFANode()->GetPacketID() == XFA_XDPPACKET_Datasets) {
WideString wsPicture;
- for (CXFA_Node* pFormNode : GetXFANode()->GetBindItems()) {
+ for (const auto& pFormNode : *(GetXFANode()->GetBindItems())) {
if (!pFormNode || pFormNode->HasRemovedChildren())
continue;
@@ -1511,7 +1511,7 @@ void CJX_Node::Script_Boolean_Value(CFXJSE_Value* pValue,
}
ByteString newValue;
- if (!(pValue && (pValue->IsNull() || pValue->IsUndefined())))
+ if (pValue && !(pValue->IsNull() || pValue->IsUndefined()))
newValue = pValue->ToString();
int32_t iValue = FXSYS_atoi(newValue.c_str());
@@ -1670,7 +1670,7 @@ void CJX_Node::Script_Field_DefaultValue(CFXJSE_Value* pValue,
}
WideString wsNewText;
- if (!(pValue && (pValue->IsNull() || pValue->IsUndefined())))
+ if (pValue && !(pValue->IsNull() || pValue->IsUndefined()))
wsNewText = pValue->ToWideString();
CXFA_Node* pUIChild = pWidgetData->GetUIChild();
@@ -3130,7 +3130,7 @@ bool CJX_Node::SetCData(XFA_Attribute eAttr,
GetXFANode()->GetNodeItem(XFA_NODEITEM_FirstChild);
pChildDataNode; pChildDataNode = pChildDataNode->GetNodeItem(
XFA_NODEITEM_NextSibling)) {
- if (!pChildDataNode->GetBindItems().empty()) {
+ if (!pChildDataNode->GetBindItems()->empty()) {
bDeleteChildren = false;
break;
}
@@ -3192,7 +3192,7 @@ bool CJX_Node::SetAttributeValue(const WideString& wsValue,
GetXFANode()->GetNodeItem(XFA_NODEITEM_FirstChild);
pChildDataNode; pChildDataNode = pChildDataNode->GetNodeItem(
XFA_NODEITEM_NextSibling)) {
- if (!pChildDataNode->GetBindItems().empty()) {
+ if (!pChildDataNode->GetBindItems()->empty()) {
bDeleteChildren = false;
break;
}
@@ -3232,24 +3232,6 @@ pdfium::Optional<WideString> CJX_Node::TryCData(XFA_Attribute eAttr,
return GetXFANode()->GetDefaultCData(eAttr);
}
-bool CJX_Node::SetObject(XFA_Attribute eAttr,
- void* pData,
- XFA_MAPDATABLOCKCALLBACKINFO* pCallbackInfo) {
- void* pKey = GetMapKey_Element(GetXFANode()->GetElementType(), eAttr);
- return SetUserData(pKey, pData, pCallbackInfo);
-}
-
-void* CJX_Node::GetObject(XFA_Attribute eAttr) {
- void* pData;
- return TryObject(eAttr, pData) ? pData : nullptr;
-}
-
-bool CJX_Node::TryObject(XFA_Attribute eAttr, void*& pData) {
- void* pKey = GetMapKey_Element(GetXFANode()->GetElementType(), eAttr);
- pData = GetUserData(pKey, false);
- return !!pData;
-}
-
bool CJX_Node::SetValue(XFA_Attribute eAttr,
XFA_AttributeType eType,
void* pValue,
@@ -3289,6 +3271,13 @@ bool CJX_Node::SetValue(XFA_Attribute eAttr,
return true;
}
+// TODO(dsinclair): This should not be needed. Nodes should get un-bound when
+// they're deleted instead of us pointing to bad objects.
+void CJX_Node::ReleaseBindingNodes() {
+ for (auto& node : binding_nodes_)
+ node.Release();
+}
+
void* CJX_Node::GetUserData(void* pKey, bool bProtoAlso) {
void* pData;
return TryUserData(pKey, pData, bProtoAlso) ? pData : nullptr;
@@ -3391,7 +3380,7 @@ bool CJX_Node::SetContent(const WideString& wsContent,
i++;
}
}
- for (CXFA_Node* pArrayNode : pBind->GetBindItems()) {
+ for (const auto& pArrayNode : *(pBind->GetBindItems())) {
if (pArrayNode != GetXFANode()) {
pArrayNode->JSNode()->SetContent(wsContent, wsContent, bNotify,
bScriptModify, false);
@@ -3416,7 +3405,7 @@ bool CJX_Node::SetContent(const WideString& wsContent,
if (pBindNode && bSyncData) {
pBindNode->JSNode()->SetContent(wsContent, wsXMLValue, bNotify,
bScriptModify, false);
- for (CXFA_Node* pArrayNode : pBindNode->GetBindItems()) {
+ for (const auto& pArrayNode : *(pBindNode->GetBindItems())) {
if (pArrayNode != GetXFANode()) {
pArrayNode->JSNode()->SetContent(wsContent, wsContent, bNotify,
true, false);
@@ -3486,7 +3475,7 @@ bool CJX_Node::SetContent(const WideString& wsContent,
SetAttributeValue(wsContent, wsXMLValue, bNotify, bScriptModify);
if (pBindNode && bSyncData) {
- for (CXFA_Node* pArrayNode : pBindNode->GetBindItems()) {
+ for (const auto& pArrayNode : *(pBindNode->GetBindItems())) {
pArrayNode->JSNode()->SetContent(wsContent, wsContent, bNotify,
bScriptModify, false);
}
@@ -3561,6 +3550,10 @@ pdfium::Optional<WideString> CJX_Node::TryContent(bool bScriptModify,
return {};
}
+void CJX_Node::SetWidgetData(std::unique_ptr<CXFA_WidgetData> data) {
+ widget_data_ = std::move(data);
+}
+
pdfium::Optional<WideString> CJX_Node::TryNamespace() {
if (GetXFANode()->IsModelNode() ||
GetXFANode()->GetElementType() == XFA_Element::Packet) {
diff --git a/fxjs/cjx_node.h b/fxjs/cjx_node.h
index 686c54c164..3393a52406 100644
--- a/fxjs/cjx_node.h
+++ b/fxjs/cjx_node.h
@@ -8,6 +8,8 @@
#define FXJS_CJX_NODE_H_
#include <memory>
+#include <utility>
+#include <vector>
#include "core/fxcrt/unowned_ptr.h"
#include "fxjs/cjx_object.h"
@@ -29,6 +31,7 @@ enum XFA_SOM_MESSAGETYPE {
class CFXJSE_Arguments;
class CXFA_Node;
+class CXFA_WidgetData;
struct XFA_MAPMODULEDATA;
@@ -102,11 +105,27 @@ class CJX_Node : public CJX_Object {
XFA_MAPDATABLOCKCALLBACKINFO* pCallbackInfo);
void* GetUserData(void* pKey, bool bProtoAlso);
- bool TryObject(XFA_Attribute eAttr, void*& pData);
- bool SetObject(XFA_Attribute eAttr,
- void* pData,
- XFA_MAPDATABLOCKCALLBACKINFO* pCallbackInfo);
- void* GetObject(XFA_Attribute eAttr);
+ void SetBindingNodes(std::vector<UnownedPtr<CXFA_Node>> nodes) {
+ binding_nodes_ = std::move(nodes);
+ }
+ std::vector<UnownedPtr<CXFA_Node>>* GetBindingNodes() {
+ return &binding_nodes_;
+ }
+ void ReleaseBindingNodes();
+
+ void SetBindingNode(CXFA_Node* node) {
+ binding_nodes_.clear();
+ if (node)
+ binding_nodes_.emplace_back(node);
+ }
+ CXFA_Node* GetBindingNode() const {
+ if (binding_nodes_.empty())
+ return nullptr;
+ return binding_nodes_[0].Get();
+ }
+
+ void SetWidgetData(std::unique_ptr<CXFA_WidgetData> data);
+ CXFA_WidgetData* GetWidgetData() const { return widget_data_.get(); }
pdfium::Optional<WideString> TryNamespace();
@@ -437,6 +456,8 @@ class CJX_Node : public CJX_Object {
XFA_Element eType);
std::unique_ptr<XFA_MAPMODULEDATA> map_module_data_;
+ std::unique_ptr<CXFA_WidgetData> widget_data_;
+ std::vector<UnownedPtr<CXFA_Node>> binding_nodes_;
};
#endif // FXJS_CJX_NODE_H_
diff --git a/xfa/fxfa/cxfa_ffnotify.cpp b/xfa/fxfa/cxfa_ffnotify.cpp
index 068cf70591..7e66e4e888 100644
--- a/xfa/fxfa/cxfa_ffnotify.cpp
+++ b/xfa/fxfa/cxfa_ffnotify.cpp
@@ -6,6 +6,9 @@
#include "xfa/fxfa/cxfa_ffnotify.h"
+#include <memory>
+#include <utility>
+
#include "xfa/fxfa/cxfa_ffapp.h"
#include "xfa/fxfa/cxfa_ffarc.h"
#include "xfa/fxfa/cxfa_ffbarcode.h"
@@ -52,13 +55,6 @@ CXFA_FFComboBox* ToComboBox(CXFA_FFWidget* widget) {
} // namespace
-static void XFA_FFDeleteWidgetAcc(void* pData) {
- delete ToWidgetAcc(pData);
-}
-
-static XFA_MAPDATABLOCKCALLBACKINFO gs_XFADeleteWidgetAcc = {
- XFA_FFDeleteWidgetAcc, nullptr};
-
CXFA_FFNotify::CXFA_FFNotify(CXFA_FFDoc* pDoc) : m_pDoc(pDoc) {}
CXFA_FFNotify::~CXFA_FFNotify() {}
@@ -345,9 +341,8 @@ void CXFA_FFNotify::OnNodeReady(CXFA_Node* pNode) {
XFA_Element eType = pNode->GetElementType();
if (XFA_IsCreateWidget(eType)) {
- CXFA_WidgetAcc* pAcc = new CXFA_WidgetAcc(pDocView, pNode);
- pNode->JSNode()->SetObject(XFA_Attribute::WidgetData, pAcc,
- &gs_XFADeleteWidgetAcc);
+ pNode->JSNode()->SetWidgetData(
+ pdfium::MakeUnique<CXFA_WidgetAcc>(pDocView, pNode));
return;
}
switch (eType) {
diff --git a/xfa/fxfa/cxfa_widgetacc.h b/xfa/fxfa/cxfa_widgetacc.h
index 600cc1afed..6cb2e7f01d 100644
--- a/xfa/fxfa/cxfa_widgetacc.h
+++ b/xfa/fxfa/cxfa_widgetacc.h
@@ -36,7 +36,7 @@ class IXFA_AppProvider;
class CXFA_WidgetAcc : public CXFA_WidgetData {
public:
CXFA_WidgetAcc(CXFA_FFDocView* pDocView, CXFA_Node* pNode);
- ~CXFA_WidgetAcc();
+ ~CXFA_WidgetAcc() override;
void ResetData();
diff --git a/xfa/fxfa/parser/cxfa_datadata.cpp b/xfa/fxfa/parser/cxfa_datadata.cpp
index cf813fc017..b08801a386 100644
--- a/xfa/fxfa/parser/cxfa_datadata.cpp
+++ b/xfa/fxfa/parser/cxfa_datadata.cpp
@@ -61,6 +61,10 @@ FX_ARGB CXFA_DataData::ToColor(const WideStringView& wsValue) {
return (0xff << 24) | (r << 16) | (g << 8) | b;
}
+CXFA_DataData::CXFA_DataData(CXFA_Node* pNode) : m_pNode(pNode) {}
+
+CXFA_DataData::~CXFA_DataData() {}
+
XFA_Element CXFA_DataData::GetElementType() const {
return m_pNode ? m_pNode->GetElementType() : XFA_Element::Unknown;
}
diff --git a/xfa/fxfa/parser/cxfa_datadata.h b/xfa/fxfa/parser/cxfa_datadata.h
index 5be86c28ab..a05b5024fe 100644
--- a/xfa/fxfa/parser/cxfa_datadata.h
+++ b/xfa/fxfa/parser/cxfa_datadata.h
@@ -17,7 +17,8 @@ class CXFA_DataData {
public:
static FX_ARGB ToColor(const WideStringView& wsValue);
- explicit CXFA_DataData(CXFA_Node* pNode) : m_pNode(pNode) {}
+ explicit CXFA_DataData(CXFA_Node* pNode);
+ virtual ~CXFA_DataData();
explicit operator bool() const { return !!m_pNode; }
CXFA_Node* GetNode() const { return m_pNode; }
diff --git a/xfa/fxfa/parser/cxfa_document.cpp b/xfa/fxfa/parser/cxfa_document.cpp
index 44fc9089c1..edae6c3837 100644
--- a/xfa/fxfa/parser/cxfa_document.cpp
+++ b/xfa/fxfa/parser/cxfa_document.cpp
@@ -94,6 +94,10 @@ CXFA_Document::CXFA_Document(CXFA_DocumentParser* pParser)
}
CXFA_Document::~CXFA_Document() {
+ // Remove all the bindings before freeing the node as the ownership is wonky.
+ if (m_pRootNode)
+ m_pRootNode->ReleaseBindingNodes();
+
delete m_pRootNode;
PurgeNodes();
}
diff --git a/xfa/fxfa/parser/cxfa_filldata.h b/xfa/fxfa/parser/cxfa_filldata.h
index 290e0b72e1..7faca4a95a 100644
--- a/xfa/fxfa/parser/cxfa_filldata.h
+++ b/xfa/fxfa/parser/cxfa_filldata.h
@@ -16,7 +16,7 @@ class CXFA_Node;
class CXFA_FillData : public CXFA_DataData {
public:
explicit CXFA_FillData(CXFA_Node* pNode);
- ~CXFA_FillData();
+ ~CXFA_FillData() override;
int32_t GetPresence();
FX_ARGB GetColor(bool bText = false);
diff --git a/xfa/fxfa/parser/cxfa_itemlayoutprocessor.cpp b/xfa/fxfa/parser/cxfa_itemlayoutprocessor.cpp
index cd6e57ce02..bf63a2a56c 100644
--- a/xfa/fxfa/parser/cxfa_itemlayoutprocessor.cpp
+++ b/xfa/fxfa/parser/cxfa_itemlayoutprocessor.cpp
@@ -2106,8 +2106,7 @@ void CXFA_ItemLayoutProcessor::ProcessUnUseBinds(CXFA_Node* pFormNode) {
CXFA_Node* pBindNode = pNode->GetBindData();
if (pBindNode) {
pBindNode->RemoveBindItem(pNode);
- pNode->JSNode()->SetObject(XFA_Attribute::BindingNode, nullptr,
- nullptr);
+ pNode->JSNode()->SetBindingNode(nullptr);
}
}
pNode->SetFlag(XFA_NodeFlag_UnusedNode, true);
diff --git a/xfa/fxfa/parser/cxfa_layoutpagemgr.cpp b/xfa/fxfa/parser/cxfa_layoutpagemgr.cpp
index 72f5594982..7a013a9a9b 100644
--- a/xfa/fxfa/parser/cxfa_layoutpagemgr.cpp
+++ b/xfa/fxfa/parser/cxfa_layoutpagemgr.cpp
@@ -1698,8 +1698,7 @@ void CXFA_LayoutPageMgr::MergePageSetContents() {
CXFA_Node* pBindNode = pNode->GetBindData();
if (pBindNode) {
pBindNode->RemoveBindItem(pNode);
- pNode->JSNode()->SetObject(XFA_Attribute::BindingNode, nullptr,
- nullptr);
+ pNode->JSNode()->SetBindingNode(nullptr);
}
}
pNode->SetFlag(XFA_NodeFlag_UnusedNode, true);
diff --git a/xfa/fxfa/parser/cxfa_node.cpp b/xfa/fxfa/parser/cxfa_node.cpp
index 6ec3b98f7b..c667c08d10 100644
--- a/xfa/fxfa/parser/cxfa_node.cpp
+++ b/xfa/fxfa/parser/cxfa_node.cpp
@@ -41,13 +41,6 @@
namespace {
-void XFA_DataNodeDeleteBindItem(void* pData) {
- delete static_cast<std::vector<CXFA_Node*>*>(pData);
-}
-
-XFA_MAPDATABLOCKCALLBACKINFO deleteBindItemCallBack = {
- XFA_DataNodeDeleteBindItem, nullptr};
-
std::vector<CXFA_Node*> NodesSortedByDocumentIdx(
const std::set<CXFA_Node*>& rgNodeSet) {
if (rgNodeSet.empty())
@@ -177,6 +170,7 @@ CXFA_Node::CXFA_Node(CXFA_Document* pDoc,
CXFA_Node::~CXFA_Node() {
ASSERT(!m_pParent);
+
CXFA_Node* pNode = m_pChild;
while (pNode) {
CXFA_Node* pNext = pNode->m_pNext;
@@ -222,7 +216,7 @@ CXFA_Node* CXFA_Node::Clone(bool bRecursive) {
}
}
pClone->SetFlag(XFA_NodeFlag_Initialized, true);
- pClone->JSNode()->SetObject(XFA_Attribute::BindingNode, nullptr, nullptr);
+ pClone->JSNode()->SetBindingNode(nullptr);
return pClone;
}
@@ -384,86 +378,79 @@ void CXFA_Node::SetTemplateNode(CXFA_Node* pTemplateNode) {
CXFA_Node* CXFA_Node::GetBindData() {
ASSERT(GetPacketID() == XFA_XDPPACKET_Form);
- return static_cast<CXFA_Node*>(
- JSNode()->GetObject(XFA_Attribute::BindingNode));
+ return JSNode()->GetBindingNode();
}
-std::vector<CXFA_Node*> CXFA_Node::GetBindItems() {
- if (BindsFormItems()) {
- void* pBinding = nullptr;
- JSNode()->TryObject(XFA_Attribute::BindingNode, pBinding);
- return *static_cast<std::vector<CXFA_Node*>*>(pBinding);
- }
- std::vector<CXFA_Node*> result;
- CXFA_Node* pFormNode =
- static_cast<CXFA_Node*>(JSNode()->GetObject(XFA_Attribute::BindingNode));
- if (pFormNode)
- result.push_back(pFormNode);
- return result;
+std::vector<UnownedPtr<CXFA_Node>>* CXFA_Node::GetBindItems() {
+ return JSNode()->GetBindingNodes();
}
int32_t CXFA_Node::AddBindItem(CXFA_Node* pFormNode) {
ASSERT(pFormNode);
+
if (BindsFormItems()) {
- void* pBinding = nullptr;
- JSNode()->TryObject(XFA_Attribute::BindingNode, pBinding);
- auto* pItems = static_cast<std::vector<CXFA_Node*>*>(pBinding);
- if (!pdfium::ContainsValue(*pItems, pFormNode))
- pItems->push_back(pFormNode);
- return pdfium::CollectionSize<int32_t>(*pItems);
+ std::vector<UnownedPtr<CXFA_Node>>* nodes = JSNode()->GetBindingNodes();
+ bool found = false;
+ for (auto& v : *nodes) {
+ if (v.Get() == pFormNode) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ nodes->emplace_back(pFormNode);
+ return pdfium::CollectionSize<int32_t>(*nodes);
}
- CXFA_Node* pOldFormItem =
- static_cast<CXFA_Node*>(JSNode()->GetObject(XFA_Attribute::BindingNode));
+
+ CXFA_Node* pOldFormItem = JSNode()->GetBindingNode();
if (!pOldFormItem) {
- JSNode()->SetObject(XFA_Attribute::BindingNode, pFormNode, nullptr);
+ JSNode()->SetBindingNode(pFormNode);
return 1;
}
if (pOldFormItem == pFormNode)
return 1;
- std::vector<CXFA_Node*>* pItems = new std::vector<CXFA_Node*>;
- JSNode()->SetObject(XFA_Attribute::BindingNode, pItems,
- &deleteBindItemCallBack);
- pItems->push_back(pOldFormItem);
- pItems->push_back(pFormNode);
+ std::vector<UnownedPtr<CXFA_Node>> items;
+ items.emplace_back(pOldFormItem);
+ items.emplace_back(pFormNode);
+ JSNode()->SetBindingNodes(std::move(items));
+
m_uNodeFlags |= XFA_NodeFlag_BindFormItems;
return 2;
}
int32_t CXFA_Node::RemoveBindItem(CXFA_Node* pFormNode) {
if (BindsFormItems()) {
- void* pBinding = nullptr;
- JSNode()->TryObject(XFA_Attribute::BindingNode, pBinding);
- auto* pItems = static_cast<std::vector<CXFA_Node*>*>(pBinding);
- auto iter = std::find(pItems->begin(), pItems->end(), pFormNode);
- if (iter != pItems->end()) {
- *iter = pItems->back();
- pItems->pop_back();
- if (pItems->size() == 1) {
- JSNode()->SetObject(XFA_Attribute::BindingNode, (*pItems)[0],
- nullptr); // Invalidates pItems.
- m_uNodeFlags &= ~XFA_NodeFlag_BindFormItems;
- return 1;
- }
+ std::vector<UnownedPtr<CXFA_Node>>* nodes = JSNode()->GetBindingNodes();
+
+ auto it = std::find_if(nodes->begin(), nodes->end(),
+ [&pFormNode](const UnownedPtr<CXFA_Node>& node) {
+ return node.Get() == pFormNode;
+ });
+ if (it != nodes->end())
+ nodes->erase(it);
+
+ if (nodes->size() == 1) {
+ m_uNodeFlags &= ~XFA_NodeFlag_BindFormItems;
+ return 1;
}
- return pdfium::CollectionSize<int32_t>(*pItems);
+ return pdfium::CollectionSize<int32_t>(*nodes);
}
- CXFA_Node* pOldFormItem =
- static_cast<CXFA_Node*>(JSNode()->GetObject(XFA_Attribute::BindingNode));
+
+ CXFA_Node* pOldFormItem = JSNode()->GetBindingNode();
if (pOldFormItem != pFormNode)
return pOldFormItem ? 1 : 0;
- JSNode()->SetObject(XFA_Attribute::BindingNode, nullptr, nullptr);
+ JSNode()->SetBindingNode(nullptr);
return 0;
}
bool CXFA_Node::HasBindItem() {
- return GetPacketID() == XFA_XDPPACKET_Datasets &&
- JSNode()->GetObject(XFA_Attribute::BindingNode);
+ return GetPacketID() == XFA_XDPPACKET_Datasets && JSNode()->GetBindingNode();
}
CXFA_WidgetData* CXFA_Node::GetWidgetData() {
- return (CXFA_WidgetData*)JSNode()->GetObject(XFA_Attribute::WidgetData);
+ return JSNode()->GetWidgetData();
}
CXFA_WidgetData* CXFA_Node::GetContainerWidgetData() {
@@ -494,7 +481,7 @@ CXFA_WidgetData* CXFA_Node::GetContainerWidgetData() {
if (!pDataNode)
return nullptr;
pFieldWidgetData = nullptr;
- for (CXFA_Node* pFormNode : pDataNode->GetBindItems()) {
+ for (const auto& pFormNode : *(pDataNode->GetBindItems())) {
if (!pFormNode || pFormNode->HasRemovedChildren())
continue;
pFieldWidgetData = pFormNode->GetWidgetData();
@@ -1016,6 +1003,15 @@ void CXFA_Node::ClearFlag(uint32_t dwFlag) {
m_uNodeFlags &= ~dwFlag;
}
+void CXFA_Node::ReleaseBindingNodes() {
+ // Clear any binding nodes set on our JS node as we don't necessarily destruct
+ // in an order that makes sense.
+ JSNode()->ReleaseBindingNodes();
+
+ for (CXFA_Node* pNode = m_pChild; pNode; pNode = pNode->m_pNext)
+ pNode->ReleaseBindingNodes();
+}
+
bool CXFA_Node::IsAttributeInXML() {
return JSNode()->GetEnum(XFA_Attribute::Contains) ==
XFA_ATTRIBUTEENUM_MetaData;
@@ -1212,8 +1208,7 @@ void CXFA_Node::RemoveItem(CXFA_Node* pRemoveInstance,
pDataParent->RemoveChild(pDataNode, true);
}
}
- pFormNode->JSNode()->SetObject(XFA_Attribute::BindingNode, nullptr,
- nullptr);
+ pFormNode->JSNode()->SetBindingNode(nullptr);
}
}
diff --git a/xfa/fxfa/parser/cxfa_node.h b/xfa/fxfa/parser/cxfa_node.h
index 66a3174901..dc4710a9c6 100644
--- a/xfa/fxfa/parser/cxfa_node.h
+++ b/xfa/fxfa/parser/cxfa_node.h
@@ -82,6 +82,7 @@ class CXFA_Node : public CXFA_Object {
bool IsLayoutGeneratedNode() const {
return HasFlag(XFA_NodeFlag_LayoutGeneratedNode);
}
+ void ReleaseBindingNodes();
bool BindsFormItems() const { return HasFlag(XFA_NodeFlag_BindFormItems); }
bool HasRemovedChildren() const {
return HasFlag(XFA_NodeFlag_HasRemovedChildren);
@@ -119,7 +120,7 @@ class CXFA_Node : public CXFA_Object {
CXFA_Node* GetDataDescriptionNode();
void SetDataDescriptionNode(CXFA_Node* pDataDescriptionNode);
CXFA_Node* GetBindData();
- std::vector<CXFA_Node*> GetBindItems();
+ std::vector<UnownedPtr<CXFA_Node>>* GetBindItems();
int32_t AddBindItem(CXFA_Node* pFormNode);
int32_t RemoveBindItem(CXFA_Node* pFormNode);
bool HasBindItem();
diff --git a/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp b/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp
index 89a6500fa6..3a70135aea 100644
--- a/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp
+++ b/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp
@@ -122,8 +122,7 @@ bool FormValueNode_SetChildContent(CXFA_Node* pValueNode,
void CreateDataBinding(CXFA_Node* pFormNode,
CXFA_Node* pDataNode,
bool bDataToForm) {
- pFormNode->JSNode()->SetObject(XFA_Attribute::BindingNode, pDataNode,
- nullptr);
+ pFormNode->JSNode()->SetBindingNode(pDataNode);
pDataNode->AddBindItem(pFormNode);
XFA_Element eType = pFormNode->GetElementType();
if (eType != XFA_Element::Field && eType != XFA_Element::ExclGroup)
@@ -1544,10 +1543,11 @@ void CXFA_Document::DoDataRemerge(bool bDoDataMerge) {
if (pFormRoot) {
while (CXFA_Node* pNode = pFormRoot->GetNodeItem(XFA_NODEITEM_FirstChild))
pFormRoot->RemoveChild(pNode, true);
- pFormRoot->JSNode()->SetObject(XFA_Attribute::BindingNode, nullptr,
- nullptr);
+
+ pFormRoot->JSNode()->SetBindingNode(nullptr);
}
m_rgGlobalBinding.clear();
+
if (bDoDataMerge)
DoDataMerge();