• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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