Home | History | Annotate | Download | only in parser
      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 
     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 
    112   bool IsInitialized() const { return HasFlag(XFA_NodeFlag_Initialized); }
    113   bool IsOwnXMLNode() const { return HasFlag(XFA_NodeFlag_OwnXMLNode); }
    114   bool IsUserInteractive() const {
    115     return HasFlag(XFA_NodeFlag_UserInteractive);
    116   }
    117   bool IsUnusedNode() const { return HasFlag(XFA_NodeFlag_UnusedNode); }
    118   bool IsLayoutGeneratedNode() const {
    119     return HasFlag(XFA_NodeFlag_LayoutGeneratedNode);
    120   }
    121 
    122   void SetBindingNodes(std::vector<UnownedPtr<CXFA_Node>> nodes) {
    123     binding_nodes_ = std::move(nodes);
    124   }
    125   std::vector<UnownedPtr<CXFA_Node>>* GetBindingNodes() {
    126     return &binding_nodes_;
    127   }
    128   void SetBindingNode(CXFA_Node* node) {
    129     binding_nodes_.clear();
    130     if (node)
    131       binding_nodes_.emplace_back(node);
    132   }
    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 
    142   bool BindsFormItems() const { return HasFlag(XFA_NodeFlag_BindFormItems); }
    143   bool HasRemovedChildren() const {
    144     return HasFlag(XFA_NodeFlag_HasRemovedChildren);
    145   }
    146   bool NeedsInitApp() const { return HasFlag(XFA_NodeFlag_NeedsInitApp); }
    147 
    148   bool IsAttributeInXML();
    149   bool IsFormContainer() const {
    150     return m_ePacket == XFA_PacketType::Form && IsContainerNode();
    151   }
    152   void SetXMLMappingNode(CFX_XMLNode* pXMLNode) { m_pXMLNode = pXMLNode; }
    153   CFX_XMLNode* GetXMLMappingNode() const { return m_pXMLNode; }
    154   CFX_XMLNode* CreateXMLMappingNode();
    155   bool IsNeedSavingXMLNode();
    156   uint32_t GetNameHash() const { return m_dwNameHash; }
    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>
    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 
    174   CXFA_Node* GetNextSibling() const { return m_pNext; }
    175   CXFA_Node* GetPrevSibling() const;
    176   CXFA_Node* GetFirstChild() const { return m_pChild; }
    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>
    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>
    210   T* GetNextSameNameSibling(const WideStringView& wsNodeName) const {
    211     return static_cast<T*>(GetNextSameNameSiblingInternal(wsNodeName));
    212   }
    213   template <typename T>
    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