1 // Copyright 2014 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_DOCUMENT_H_
8 #define XFA_FXFA_PARSER_CXFA_DOCUMENT_H_
9 
10 #include <map>
11 #include <memory>
12 #include <vector>
13 
14 #include "core/fxcrt/unowned_ptr.h"
15 #include "third_party/base/optional.h"
16 #include "xfa/fxfa/fxfa.h"
17 #include "xfa/fxfa/parser/cxfa_localemgr.h"
18 #include "xfa/fxfa/parser/cxfa_nodeowner.h"
19 
20 enum XFA_VERSION {
21   XFA_VERSION_UNKNOWN = 0,
22   XFA_VERSION_200 = 200,
23   XFA_VERSION_202 = 202,
24   XFA_VERSION_204 = 204,
25   XFA_VERSION_205 = 205,
26   XFA_VERSION_206 = 206,
27   XFA_VERSION_207 = 207,
28   XFA_VERSION_208 = 208,
29   XFA_VERSION_300 = 300,
30   XFA_VERSION_301 = 301,
31   XFA_VERSION_303 = 303,
32   XFA_VERSION_306 = 306,
33   XFA_VERSION_DEFAULT = XFA_VERSION_303,
34   XFA_VERSION_MIN = 200,
35   XFA_VERSION_MAX = 400,
36 };
37 
38 class CFXJSE_Engine;
39 class CJS_Runtime;
40 class CScript_DataWindow;
41 class CScript_EventPseudoModel;
42 class CScript_HostPseudoModel;
43 class CScript_LayoutPseudoModel;
44 class CScript_LogPseudoModel;
45 class CScript_SignaturePseudoModel;
46 class CXFA_FFNotify;
47 class CXFA_Node;
48 class CXFA_Object;
49 
50 class CXFA_Document final : public CXFA_NodeOwner {
51  public:
52   class LayoutProcessorIface {
53    public:
54     LayoutProcessorIface();
55     virtual ~LayoutProcessorIface();
56     virtual void SetForceRelayout(bool enable) = 0;
57     virtual void AddChangedContainer(CXFA_Node* pContainer) = 0;
58 
SetDocument(CXFA_Document * pDocument)59     void SetDocument(CXFA_Document* pDocument) { m_pDocument = pDocument; }
GetDocument()60     CXFA_Document* GetDocument() const { return m_pDocument.Get(); }
61 
62    private:
63     UnownedPtr<CXFA_Document> m_pDocument;
64   };
65 
66   CXFA_Document(CXFA_FFNotify* notify,
67                 std::unique_ptr<LayoutProcessorIface> pLayout);
68   ~CXFA_Document() override;
69 
HasScriptContext()70   bool HasScriptContext() const { return !!m_pScriptContext; }
71   CFXJSE_Engine* InitScriptContext(CJS_Runtime* fxjs_runtime);
72 
73   // Only safe to call in situations where the context is known to exist,
74   // and always returns non-NULL in those situations. In other words, we have
75   // to call InitScriptContext() first to avoid a situation where the context
76   // won't have an isolate set into it.
77   CFXJSE_Engine* GetScriptContext() const;
78 
GetNotify()79   CXFA_FFNotify* GetNotify() const { return notify_.Get(); }
80   CXFA_LocaleMgr* GetLocaleMgr();
81   CXFA_Object* GetXFAObject(XFA_HashCode wsNodeNameHash);
82   CXFA_Node* GetNodeByID(CXFA_Node* pRoot, WideStringView wsID) const;
83   CXFA_Node* GetNotBindNode(
84       const std::vector<UnownedPtr<CXFA_Object>>& arrayNodes) const;
85 
GetLayoutProcessor()86   LayoutProcessorIface* GetLayoutProcessor() const {
87     return m_pLayoutProcessor.get();
88   }
89 
GetRoot()90   CXFA_Node* GetRoot() const { return m_pRootNode; }
SetRoot(CXFA_Node * pNewRoot)91   void SetRoot(CXFA_Node* pNewRoot) { m_pRootNode = pNewRoot; }
92 
is_strict_scoping()93   bool is_strict_scoping() const { return m_bStrictScoping; }
set_is_strict_scoping()94   void set_is_strict_scoping() { m_bStrictScoping = true; }
95 
is_scripting()96   bool is_scripting() const { return m_bScripting; }
set_is_scripting()97   void set_is_scripting() { m_bScripting = true; }
98 
99   bool IsInteractive();
GetCurVersionMode()100   XFA_VERSION GetCurVersionMode() { return m_eCurVersionMode; }
101   XFA_VERSION RecognizeXFAVersionNumber(const WideString& wsTemplateNS);
102   FormType GetFormType() const;
103 
104   CXFA_Node* CreateNode(XFA_PacketType packet, XFA_Element eElement);
105 
106   void DoProtoMerge();
107   void DoDataMerge();
108   void DoDataRemerge(bool bDoDataMerge);
109   CXFA_Node* DataMerge_CopyContainer(CXFA_Node* pTemplateNode,
110                                      CXFA_Node* pFormNode,
111                                      CXFA_Node* pDataScope,
112                                      bool bOneInstance,
113                                      bool bDataMerge,
114                                      bool bUpLevel);
115   void DataMerge_UpdateBindingRelations(CXFA_Node* pFormUpdateRoot);
116 
117   void ClearLayoutData();
118 
119   CXFA_Node* GetGlobalBinding(uint32_t dwNameHash);
120   void RegisterGlobalBinding(uint32_t dwNameHash, CXFA_Node* pDataNode);
121   void SetPendingNodesUnusedAndUnbound();
122 
123   std::vector<CXFA_Node*> m_pPendingPageSet;
124 
125  private:
126   UnownedPtr<CXFA_FFNotify> const notify_;
127   CXFA_Node* m_pRootNode = nullptr;
128   std::map<uint32_t, CXFA_Node*> m_rgGlobalBinding;
129   std::unique_ptr<CFXJSE_Engine> m_pScriptContext;
130   std::unique_ptr<LayoutProcessorIface> m_pLayoutProcessor;
131   std::unique_ptr<CXFA_LocaleMgr> m_pLocaleMgr;
132   std::unique_ptr<CScript_DataWindow> m_pScriptDataWindow;
133   std::unique_ptr<CScript_EventPseudoModel> m_pScriptEvent;
134   std::unique_ptr<CScript_HostPseudoModel> m_pScriptHost;
135   std::unique_ptr<CScript_LogPseudoModel> m_pScriptLog;
136   std::unique_ptr<CScript_LayoutPseudoModel> m_pScriptLayout;
137   std::unique_ptr<CScript_SignaturePseudoModel> m_pScriptSignature;
138   XFA_VERSION m_eCurVersionMode = XFA_VERSION_DEFAULT;
139   Optional<bool> m_Interactive;
140   bool m_bStrictScoping = false;
141   bool m_bScripting = false;
142 };
143 
144 #endif  // XFA_FXFA_PARSER_CXFA_DOCUMENT_H_
145