1 // Copyright 2017 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 #ifndef XFA_FXFA_PARSER_CXFA_NODE_H_ 8 #define XFA_FXFA_PARSER_CXFA_NODE_H_ 9 10 #include <map> 11 #include <memory> 12 #include <utility> 13 #include <vector> 14 15 #include "core/fxcrt/fx_string.h" 16 #include "core/fxge/fx_dib.h" 17 #include "fxbarcode/BC_Library.h" 18 #include "third_party/base/optional.h" 19 #include "xfa/fxfa/parser/cxfa_object.h" 20 21 class CFX_XMLNode; 22 class CXFA_Bind; 23 class CXFA_Border; 24 class CXFA_Calculate; 25 class CXFA_Caption; 26 class CXFA_Event; 27 class CXFA_EventParam; 28 class CXFA_FFDocView; 29 class CXFA_Font; 30 class CXFA_Margin; 31 class CXFA_Occur; 32 class CXFA_Para; 33 class CXFA_Script; 34 class CXFA_Validate; 35 class CXFA_Value; 36 class CXFA_WidgetAcc; 37 class IFX_Locale; 38 39 #define XFA_NODEFILTER_Children 0x01 40 #define XFA_NODEFILTER_Properties 0x02 41 #define XFA_NODEFILTER_OneOfProperty 0x04 42 43 enum XFA_NodeFlag { 44 XFA_NodeFlag_None = 0, 45 XFA_NodeFlag_Initialized = 1 << 0, 46 XFA_NodeFlag_HasRemovedChildren = 1 << 1, 47 XFA_NodeFlag_NeedsInitApp = 1 << 2, 48 XFA_NodeFlag_BindFormItems = 1 << 3, 49 XFA_NodeFlag_UserInteractive = 1 << 4, 50 XFA_NodeFlag_SkipDataBinding = 1 << 5, 51 XFA_NodeFlag_OwnXMLNode = 1 << 6, 52 XFA_NodeFlag_UnusedNode = 1 << 7, 53 XFA_NodeFlag_LayoutGeneratedNode = 1 << 8 54 }; 55 56 class CXFA_Node : public CXFA_Object { 57 public: 58 struct PropertyData { 59 XFA_Element property; 60 uint8_t occurance_count; 61 uint8_t flags; 62 }; 63 64 struct AttributeData { 65 XFA_Attribute attribute; 66 XFA_AttributeType type; 67 void* default_value; 68 }; 69 70 #ifndef NDEBUG 71 static WideString ElementToName(XFA_Element elem); 72 #endif // NDEBUG 73 74 static WideString AttributeEnumToName(XFA_AttributeEnum item); 75 static Optional<XFA_AttributeEnum> NameToAttributeEnum( 76 const WideStringView& name); 77 static XFA_Attribute NameToAttribute(const WideStringView& name); 78 static WideString AttributeToName(XFA_Attribute attr); 79 static XFA_Element NameToElement(const WideString& name); 80 static std::unique_ptr<CXFA_Node> Create(CXFA_Document* doc, 81 XFA_Element element, 82 XFA_PacketType packet); 83 84 ~CXFA_Node() override; 85 86 bool IsValidInPacket(XFA_PacketType packet) const; 87 88 bool HasProperty(XFA_Element property) const; 89 bool HasPropertyFlags(XFA_Element property, uint8_t flags) const; 90 uint8_t PropertyOccuranceCount(XFA_Element property) const; 91 92 void SendAttributeChangeMessage(XFA_Attribute eAttribute, bool bScriptModify); 93 94 bool HasAttribute(XFA_Attribute attr) const; 95 XFA_Attribute GetAttribute(size_t i) const; 96 XFA_AttributeType GetAttributeType(XFA_Attribute type) const; 97 GetPacketType()98 XFA_PacketType GetPacketType() const { return m_ePacket; } 99 100 void SetFlag(uint32_t dwFlag, bool bNotify); 101 void ClearFlag(uint32_t dwFlag); 102 103 CXFA_Node* CreateInstanceIfPossible(bool bDataMerge); 104 int32_t GetCount(); 105 CXFA_Node* GetItemIfExists(int32_t iIndex); 106 void RemoveItem(CXFA_Node* pRemoveInstance, bool bRemoveDataBinding); 107 void InsertItem(CXFA_Node* pNewInstance, 108 int32_t iPos, 109 int32_t iCount, 110 bool bMoveDataBindingNodes); 111 IsInitialized()112 bool IsInitialized() const { return HasFlag(XFA_NodeFlag_Initialized); } IsOwnXMLNode()113 bool IsOwnXMLNode() const { return HasFlag(XFA_NodeFlag_OwnXMLNode); } IsUserInteractive()114 bool IsUserInteractive() const { 115 return HasFlag(XFA_NodeFlag_UserInteractive); 116 } IsUnusedNode()117 bool IsUnusedNode() const { return HasFlag(XFA_NodeFlag_UnusedNode); } IsLayoutGeneratedNode()118 bool IsLayoutGeneratedNode() const { 119 return HasFlag(XFA_NodeFlag_LayoutGeneratedNode); 120 } 121 SetBindingNodes(std::vector<UnownedPtr<CXFA_Node>> nodes)122 void SetBindingNodes(std::vector<UnownedPtr<CXFA_Node>> nodes) { 123 binding_nodes_ = std::move(nodes); 124 } GetBindingNodes()125 std::vector<UnownedPtr<CXFA_Node>>* GetBindingNodes() { 126 return &binding_nodes_; 127 } SetBindingNode(CXFA_Node * node)128 void SetBindingNode(CXFA_Node* node) { 129 binding_nodes_.clear(); 130 if (node) 131 binding_nodes_.emplace_back(node); 132 } GetBindingNode()133 CXFA_Node* GetBindingNode() const { 134 if (binding_nodes_.empty()) 135 return nullptr; 136 return binding_nodes_[0].Get(); 137 } 138 // TODO(dsinclair): This should not be needed. Nodes should get un-bound when 139 // they're deleted instead of us pointing to bad objects. 140 void ReleaseBindingNodes(); 141 BindsFormItems()142 bool BindsFormItems() const { return HasFlag(XFA_NodeFlag_BindFormItems); } HasRemovedChildren()143 bool HasRemovedChildren() const { 144 return HasFlag(XFA_NodeFlag_HasRemovedChildren); 145 } NeedsInitApp()146 bool NeedsInitApp() const { return HasFlag(XFA_NodeFlag_NeedsInitApp); } 147 148 bool IsAttributeInXML(); IsFormContainer()149 bool IsFormContainer() const { 150 return m_ePacket == XFA_PacketType::Form && IsContainerNode(); 151 } SetXMLMappingNode(CFX_XMLNode * pXMLNode)152 void SetXMLMappingNode(CFX_XMLNode* pXMLNode) { m_pXMLNode = pXMLNode; } GetXMLMappingNode()153 CFX_XMLNode* GetXMLMappingNode() const { return m_pXMLNode; } 154 CFX_XMLNode* CreateXMLMappingNode(); 155 bool IsNeedSavingXMLNode(); GetNameHash()156 uint32_t GetNameHash() const { return m_dwNameHash; } IsUnnamed()157 bool IsUnnamed() const { return m_dwNameHash == 0; } 158 CXFA_Node* GetModelNode(); 159 void UpdateNameHash(); 160 161 size_t CountChildren(XFA_Element eType, bool bOnlyChild); 162 163 template <typename T> GetChild(size_t index,XFA_Element eType,bool bOnlyChild)164 T* GetChild(size_t index, XFA_Element eType, bool bOnlyChild) { 165 return static_cast<T*>(GetChildInternal(index, eType, bOnlyChild)); 166 } 167 168 int32_t InsertChild(int32_t index, CXFA_Node* pNode); 169 bool InsertChild(CXFA_Node* pNode, CXFA_Node* pBeforeNode); 170 bool RemoveChild(CXFA_Node* pNode, bool bNotify); 171 172 CXFA_Node* Clone(bool bRecursive); 173 GetNextSibling()174 CXFA_Node* GetNextSibling() const { return m_pNext; } 175 CXFA_Node* GetPrevSibling() const; GetFirstChild()176 CXFA_Node* GetFirstChild() const { return m_pChild; } GetParent()177 CXFA_Node* GetParent() const { return m_pParent; } 178 179 CXFA_Node* GetNextContainerSibling() const; 180 CXFA_Node* GetPrevContainerSibling() const; 181 CXFA_Node* GetFirstContainerChild() const; 182 CXFA_Node* GetContainerParent() const; 183 184 std::vector<CXFA_Node*> GetNodeList(uint32_t dwTypeFilter, 185 XFA_Element eTypeFilter); 186 CXFA_Node* CreateSamePacketNode(XFA_Element eType); 187 CXFA_Node* CloneTemplateToForm(bool bRecursive); 188 CXFA_Node* GetTemplateNodeIfExists() const; 189 void SetTemplateNode(CXFA_Node* pTemplateNode); 190 CXFA_Node* GetDataDescriptionNode(); 191 void SetDataDescriptionNode(CXFA_Node* pDataDescriptionNode); 192 CXFA_Node* GetBindData(); 193 std::vector<UnownedPtr<CXFA_Node>>* GetBindItems(); 194 int32_t AddBindItem(CXFA_Node* pFormNode); 195 int32_t RemoveBindItem(CXFA_Node* pFormNode); 196 bool HasBindItem(); 197 CXFA_WidgetAcc* GetContainerWidgetAcc(); 198 IFX_Locale* GetLocale(); 199 Optional<WideString> GetLocaleName(); 200 XFA_AttributeEnum GetIntact(); 201 202 CXFA_Node* GetFirstChildByName(const WideStringView& wsNodeName) const; 203 CXFA_Node* GetFirstChildByName(uint32_t dwNodeNameHash) const; 204 template <typename T> GetFirstChildByClass(XFA_Element eType)205 T* GetFirstChildByClass(XFA_Element eType) const { 206 return static_cast<T*>(GetFirstChildByClassInternal(eType)); 207 } 208 CXFA_Node* GetNextSameNameSibling(uint32_t dwNodeNameHash) const; 209 template <typename T> GetNextSameNameSibling(const WideStringView & wsNodeName)210 T* GetNextSameNameSibling(const WideStringView& wsNodeName) const { 211 return static_cast<T*>(GetNextSameNameSiblingInternal(wsNodeName)); 212 } 213 template <typename T> GetNextSameClassSibling(XFA_Element eType)214 T* GetNextSameClassSibling(XFA_Element eType) const { 215 return static_cast<T*>(GetNextSameClassSiblingInternal(eType)); 216 } 217 218 int32_t GetNodeSameNameIndex() const; 219 int32_t GetNodeSameClassIndex() const; 220 CXFA_Node* GetInstanceMgrOfSubform(); 221 222 CXFA_Occur* GetOccurIfExists(); 223 224 Optional<bool> GetDefaultBoolean(XFA_Attribute attr) const; 225 Optional<int32_t> GetDefaultInteger(XFA_Attribute attr) const; 226 Optional<CXFA_Measurement> GetDefaultMeasurement(XFA_Attribute attr) const; 227 Optional<WideString> GetDefaultCData(XFA_Attribute attr) const; 228 Optional<XFA_AttributeEnum> GetDefaultEnum(XFA_Attribute attr) const; 229 230 void SyncValue(const WideString& wsValue, bool bNotify); 231 232 bool IsOpenAccess(); 233 234 CXFA_Border* GetBorderIfExists() const; 235 CXFA_Border* GetOrCreateBorderIfPossible(); 236 CXFA_Caption* GetCaptionIfExists() const; 237 238 CXFA_Font* GetFontIfExists() const; 239 CXFA_Font* GetOrCreateFontIfPossible(); 240 float GetFontSize() const; 241 FX_ARGB GetTextColor() const; 242 float GetLineHeight() const; 243 244 CXFA_Margin* GetMarginIfExists() const; 245 CXFA_Para* GetParaIfExists() const; 246 CXFA_Calculate* GetCalculateIfExists() const; 247 CXFA_Validate* GetValidateIfExists() const; 248 CXFA_Validate* GetOrCreateValidateIfPossible(); 249 250 CXFA_Value* GetDefaultValueIfExists(); 251 CXFA_Value* GetFormValueIfExists() const; 252 WideString GetRawValue(); 253 int32_t GetRotate(); 254 255 CXFA_Bind* GetBindIfExists() const; 256 257 Optional<float> TryWidth(); 258 Optional<float> TryHeight(); 259 Optional<float> TryMinWidth(); 260 Optional<float> TryMinHeight(); 261 Optional<float> TryMaxWidth(); 262 Optional<float> TryMaxHeight(); 263 264 CXFA_Node* GetExclGroupIfExists(); 265 266 int32_t ProcessEvent(CXFA_FFDocView* docView, 267 XFA_AttributeEnum iActivity, 268 CXFA_EventParam* pEventParam); 269 int32_t ProcessEvent(CXFA_FFDocView* docView, 270 CXFA_Event* event, 271 CXFA_EventParam* pEventParam); 272 int32_t ProcessCalculate(CXFA_FFDocView* docView); 273 int32_t ProcessValidate(CXFA_FFDocView* docView, int32_t iFlags); 274 275 int32_t ExecuteScript(CXFA_FFDocView* docView, 276 CXFA_Script* script, 277 CXFA_EventParam* pEventParam); 278 std::pair<int32_t, bool> ExecuteBoolScript(CXFA_FFDocView* docView, 279 CXFA_Script* script, 280 CXFA_EventParam* pEventParam); 281 282 // TODO(dsinclair): Figure out how to move this to cxfa_barcode. 283 WideString GetBarcodeType(); 284 Optional<BC_CHAR_ENCODING> GetBarcodeAttribute_CharEncoding(); 285 Optional<bool> GetBarcodeAttribute_Checksum(); 286 Optional<int32_t> GetBarcodeAttribute_DataLength(); 287 Optional<char> GetBarcodeAttribute_StartChar(); 288 Optional<char> GetBarcodeAttribute_EndChar(); 289 Optional<int32_t> GetBarcodeAttribute_ECLevel(); 290 Optional<int32_t> GetBarcodeAttribute_ModuleWidth(); 291 Optional<int32_t> GetBarcodeAttribute_ModuleHeight(); 292 Optional<bool> GetBarcodeAttribute_PrintChecksum(); 293 Optional<BC_TEXT_LOC> GetBarcodeAttribute_TextLocation(); 294 Optional<bool> GetBarcodeAttribute_Truncate(); 295 Optional<int8_t> GetBarcodeAttribute_WideNarrowRatio(); 296 297 protected: 298 CXFA_Node(CXFA_Document* pDoc, 299 XFA_PacketType ePacket, 300 uint32_t validPackets, 301 XFA_ObjectType oType, 302 XFA_Element eType, 303 const PropertyData* properties, 304 const AttributeData* attributes, 305 const WideStringView& elementName, 306 std::unique_ptr<CJX_Object> js_node); 307 CXFA_Node(CXFA_Document* pDoc, 308 XFA_PacketType ePacket, 309 uint32_t validPackets, 310 XFA_ObjectType oType, 311 XFA_Element eType, 312 const PropertyData* properties, 313 const AttributeData* attributes, 314 const WideStringView& elementName); 315 316 private: 317 void ProcessScriptTestValidate(CXFA_FFDocView* docView, 318 CXFA_Validate* validate, 319 int32_t iRet, 320 bool pRetValue, 321 bool bVersionFlag); 322 int32_t ProcessFormatTestValidate(CXFA_FFDocView* docView, 323 CXFA_Validate* validate, 324 bool bVersionFlag); 325 int32_t ProcessNullTestValidate(CXFA_FFDocView* docView, 326 CXFA_Validate* validate, 327 int32_t iFlags, 328 bool bVersionFlag); 329 WideString GetValidateCaptionName(bool bVersionFlag); 330 WideString GetValidateMessage(bool bError, bool bVersionFlag); 331 332 bool HasFlag(XFA_NodeFlag dwFlag) const; 333 CXFA_Node* Deprecated_GetPrevSibling(); 334 const PropertyData* GetPropertyData(XFA_Element property) const; 335 const AttributeData* GetAttributeData(XFA_Attribute attr) const; 336 Optional<XFA_Element> GetFirstPropertyWithFlag(uint8_t flag); 337 void OnRemoved(bool bNotify); 338 Optional<void*> GetDefaultValue(XFA_Attribute attr, 339 XFA_AttributeType eType) const; 340 CXFA_Node* GetChildInternal(size_t index, XFA_Element eType, bool bOnlyChild); 341 CXFA_Node* GetFirstChildByClassInternal(XFA_Element eType) const; 342 CXFA_Node* GetNextSameNameSiblingInternal( 343 const WideStringView& wsNodeName) const; 344 CXFA_Node* GetNextSameClassSiblingInternal(XFA_Element eType) const; 345 346 const PropertyData* const m_Properties; 347 const AttributeData* const m_Attributes; 348 const uint32_t m_ValidPackets; 349 CXFA_Node* m_pNext; 350 CXFA_Node* m_pChild; 351 CXFA_Node* m_pLastChild; 352 CXFA_Node* m_pParent; 353 CFX_XMLNode* m_pXMLNode; 354 const XFA_PacketType m_ePacket; 355 uint8_t m_ExecuteRecursionDepth = 0; 356 uint16_t m_uNodeFlags; 357 uint32_t m_dwNameHash; 358 CXFA_Node* m_pAuxNode; 359 std::vector<UnownedPtr<CXFA_Node>> binding_nodes_; 360 }; 361 362 #endif // XFA_FXFA_PARSER_CXFA_NODE_H_ 363