diff options
author | Dan Sinclair <dsinclair@chromium.org> | 2017-11-20 20:27:43 +0000 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2017-11-20 20:27:43 +0000 |
commit | 68c77592f25f9173d2166fa01fb34b4155f4cfcb (patch) | |
tree | ced2e1308f8b1e6b4c0934dc5f3b1c697223de61 | |
parent | fae5e26d983848089e35e2b53e9da24036661b08 (diff) | |
download | pdfium-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.cpp | 47 | ||||
-rw-r--r-- | fxjs/cjx_node.h | 31 | ||||
-rw-r--r-- | xfa/fxfa/cxfa_ffnotify.cpp | 15 | ||||
-rw-r--r-- | xfa/fxfa/cxfa_widgetacc.h | 2 | ||||
-rw-r--r-- | xfa/fxfa/parser/cxfa_datadata.cpp | 4 | ||||
-rw-r--r-- | xfa/fxfa/parser/cxfa_datadata.h | 3 | ||||
-rw-r--r-- | xfa/fxfa/parser/cxfa_document.cpp | 4 | ||||
-rw-r--r-- | xfa/fxfa/parser/cxfa_filldata.h | 2 | ||||
-rw-r--r-- | xfa/fxfa/parser/cxfa_itemlayoutprocessor.cpp | 3 | ||||
-rw-r--r-- | xfa/fxfa/parser/cxfa_layoutpagemgr.cpp | 3 | ||||
-rw-r--r-- | xfa/fxfa/parser/cxfa_node.cpp | 113 | ||||
-rw-r--r-- | xfa/fxfa/parser/cxfa_node.h | 3 | ||||
-rw-r--r-- | xfa/fxfa/parser/xfa_document_datamerger_imp.cpp | 8 |
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(); |