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 FXJS_XFA_CJX_OBJECT_H_
8 #define FXJS_XFA_CJX_OBJECT_H_
9 
10 #include <map>
11 #include <memory>
12 #include <utility>
13 #include <vector>
14 
15 #include "core/fxcrt/unowned_ptr.h"
16 #include "core/fxcrt/widestring.h"
17 #include "fxjs/xfa/jse_define.h"
18 #include "third_party/base/optional.h"
19 #include "third_party/base/span.h"
20 #include "xfa/fxfa/fxfa_basic.h"
21 #include "xfa/fxfa/parser/cxfa_measurement.h"
22 
23 class CFX_XMLElement;
24 class CFXJSE_Value;
25 class CFX_V8;
26 class CJX_Object;
27 class CXFA_CalcData;
28 class CXFA_Document;
29 class CXFA_LayoutItem;
30 class CXFA_Node;
31 class CXFA_Object;
32 struct XFA_MAPMODULEDATA;
33 
34 typedef CJS_Result (*CJX_MethodCall)(
35     CJX_Object* obj,
36     CFX_V8* runtime,
37     const std::vector<v8::Local<v8::Value>>& params);
38 
39 struct CJX_MethodSpec {
40   const char* pName;
41   CJX_MethodCall pMethodCall;
42 };
43 
44 typedef void (*PD_CALLBACK_FREEDATA)(void* pData);
45 typedef void (*PD_CALLBACK_DUPLICATEDATA)(void*& pData);
46 
47 struct XFA_MAPDATABLOCKCALLBACKINFO {
48   PD_CALLBACK_FREEDATA pFree;
49   PD_CALLBACK_DUPLICATEDATA pCopy;
50 };
51 
52 enum XFA_SOM_MESSAGETYPE {
53   XFA_SOM_ValidationMessage,
54   XFA_SOM_FormatMessage,
55   XFA_SOM_MandatoryMessage
56 };
57 
58 class CJX_Object {
59  public:
60   // Corresponds 1:1 with CJX_ subclasses.
61   enum class TypeTag {
62     Boolean,
63     Container,
64     DataWindow,
65     Delta,
66     Desc,
67     Draw,
68     Encrypt,
69     EventPseudoModel,
70     ExclGroup,
71     Extras,
72     Field,
73     Form,
74     Handler,
75     HostPseudoModel,
76     InstanceManager,
77     LayoutPseudoModel,
78     List,
79     LogPseudoModel,
80     Manifest,
81     Model,
82     Node,
83     Object,
84     Occur,
85     Packet,
86     Script,
87     SignaturePesudoModel,
88     Source,
89     Subform,
90     SubformSet,
91     Template,
92     TextNode,
93     Tree,
94     TreeList,
95     WsdlConnection,
96     Xfa,
97   };
98 
99   explicit CJX_Object(CXFA_Object* obj);
100   virtual ~CJX_Object();
101 
102   virtual bool DynamicTypeIs(TypeTag eType) const;
103 
104   JSE_PROP(className);
105 
106   CXFA_Document* GetDocument() const;
GetXFAObject()107   CXFA_Object* GetXFAObject() const { return object_.Get(); }
108 
SetCalcRecursionCount(size_t count)109   void SetCalcRecursionCount(size_t count) { calc_recursion_count_ = count; }
GetCalcRecursionCount()110   size_t GetCalcRecursionCount() const { return calc_recursion_count_; }
111 
SetLayoutItem(CXFA_LayoutItem * item)112   void SetLayoutItem(CXFA_LayoutItem* item) { layout_item_.Reset(item); }
GetLayoutItem()113   CXFA_LayoutItem* GetLayoutItem() const { return layout_item_.Get(); }
114 
115   bool HasMethod(const WideString& func) const;
116   CJS_Result RunMethod(const WideString& func,
117                        const std::vector<v8::Local<v8::Value>>& params);
118 
119   bool HasAttribute(XFA_Attribute eAttr);
120   void SetAttribute(XFA_Attribute eAttr, WideStringView wsValue, bool bNotify);
121   void SetAttribute(WideStringView wsAttr,
122                     WideStringView wsValue,
123                     bool bNotify);
124   void RemoveAttribute(WideStringView wsAttr);
125   WideString GetAttribute(WideStringView attr);
126   WideString GetAttribute(XFA_Attribute attr);
127   Optional<WideString> TryAttribute(WideStringView wsAttr, bool bUseDefault);
128   Optional<WideString> TryAttribute(XFA_Attribute eAttr, bool bUseDefault);
129 
130   Optional<WideString> TryContent(bool bScriptModify, bool bProto);
131   void SetContent(const WideString& wsContent,
132                   const WideString& wsXMLValue,
133                   bool bNotify,
134                   bool bScriptModify,
135                   bool bSyncData);
136   WideString GetContent(bool bScriptModify);
137 
138   template <typename T>
GetProperty(int32_t index,XFA_Element eType)139   T* GetProperty(int32_t index, XFA_Element eType) const {
140     CXFA_Node* node;
141     int32_t count;
142     std::tie(node, count) = GetPropertyInternal(index, eType);
143     return static_cast<T*>(node);
144   }
145   template <typename T>
GetOrCreateProperty(int32_t index,XFA_Element eType)146   T* GetOrCreateProperty(int32_t index, XFA_Element eType) {
147     return static_cast<T*>(GetOrCreatePropertyInternal(index, eType));
148   }
149 
150   void SetAttributeValue(const WideString& wsValue,
151                          const WideString& wsXMLValue,
152                          bool bNotify,
153                          bool bScriptModify);
154 
155   // Not actual properties, but invoked as property handlers to cover
156   // a broad range of underlying properties.
157   JSE_PROP(ScriptAttributeString);
158   JSE_PROP(ScriptAttributeBool);
159   JSE_PROP(ScriptAttributeInteger);
160   JSE_PROP(ScriptSomFontColor);
161   JSE_PROP(ScriptSomFillColor);
162   JSE_PROP(ScriptSomBorderColor);
163   JSE_PROP(ScriptSomBorderWidth);
164   JSE_PROP(ScriptSomValidationMessage);
165   JSE_PROP(ScriptSomMandatoryMessage);
166   JSE_PROP(ScriptSomDefaultValue);
167   JSE_PROP(ScriptSomDefaultValue_Read);
168   JSE_PROP(ScriptSomDataNode);
169   JSE_PROP(ScriptSomMandatory);
170   JSE_PROP(ScriptSomInstanceIndex);
171   JSE_PROP(ScriptSubmitFormatMode);
172 
173   void ScriptSomMessage(CFXJSE_Value* pValue,
174                         bool bSetting,
175                         XFA_SOM_MESSAGETYPE iMessageType);
176 
177   Optional<WideString> TryNamespace();
178 
179   Optional<int32_t> TryInteger(XFA_Attribute eAttr, bool bUseDefault) const;
180   void SetInteger(XFA_Attribute eAttr, int32_t iValue, bool bNotify);
181   int32_t GetInteger(XFA_Attribute eAttr) const;
182 
183   Optional<WideString> TryCData(XFA_Attribute eAttr, bool bUseDefault) const;
184   void SetCData(XFA_Attribute eAttr,
185                 const WideString& wsValue,
186                 bool bNotify,
187                 bool bScriptModify);
188   WideString GetCData(XFA_Attribute eAttr) const;
189 
190   Optional<XFA_AttributeValue> TryEnum(XFA_Attribute eAttr,
191                                        bool bUseDefault) const;
192   void SetEnum(XFA_Attribute eAttr, XFA_AttributeValue eValue, bool bNotify);
193   XFA_AttributeValue GetEnum(XFA_Attribute eAttr) const;
194 
195   Optional<bool> TryBoolean(XFA_Attribute eAttr, bool bUseDefault);
196   void SetBoolean(XFA_Attribute eAttr, bool bValue, bool bNotify);
197   bool GetBoolean(XFA_Attribute eAttr);
198 
199   Optional<CXFA_Measurement> TryMeasure(XFA_Attribute eAttr,
200                                         bool bUseDefault) const;
201   Optional<float> TryMeasureAsFloat(XFA_Attribute attr) const;
202   void SetMeasure(XFA_Attribute eAttr, CXFA_Measurement mValue, bool bNotify);
203   CXFA_Measurement GetMeasure(XFA_Attribute eAttr) const;
204   float GetMeasureInUnit(XFA_Attribute eAttr, XFA_Unit unit) const;
205 
206   void MergeAllData(CXFA_Object* pDstModule);
207 
208   void SetCalcData(std::unique_ptr<CXFA_CalcData> data);
GetCalcData()209   CXFA_CalcData* GetCalcData() const { return calc_data_.get(); }
210   std::unique_ptr<CXFA_CalcData> ReleaseCalcData();
211 
212   int32_t InstanceManager_SetInstances(int32_t iDesired);
213   int32_t InstanceManager_MoveInstance(int32_t iTo, int32_t iFrom);
214 
215   void ThrowInvalidPropertyException() const;
216   void ThrowArgumentMismatchException() const;
217   void ThrowIndexOutOfBoundsException() const;
218   void ThrowParamCountMismatchException(const WideString& method) const;
219   void ThrowTooManyOccurancesException(const WideString& obj) const;
220 
221  protected:
222   void DefineMethods(pdfium::span<const CJX_MethodSpec> methods);
223   void MoveBufferMapData(CXFA_Object* pSrcModule, CXFA_Object* pDstModule);
224   void SetMapModuleString(void* pKey, WideStringView wsValue);
225   void ThrowException(const WideString& str) const;
226 
227  private:
228   using Type__ = CJX_Object;
229   static const TypeTag static_type__ = TypeTag::Object;
230 
231   std::pair<CXFA_Node*, int32_t> GetPropertyInternal(int32_t index,
232                                                      XFA_Element eType) const;
233   CXFA_Node* GetOrCreatePropertyInternal(int32_t index, XFA_Element eType);
234 
235   void OnChanged(XFA_Attribute eAttr, bool bNotify, bool bScriptModify);
236   void OnChanging(XFA_Attribute eAttr, bool bNotify);
237   void SetUserData(void* pKey,
238                    void* pData,
239                    const XFA_MAPDATABLOCKCALLBACKINFO* pCallbackInfo);
240 
241   // Returns a pointer to the XML node that needs to be updated with the new
242   // attribute value. |nullptr| if no update is needed.
243   CFX_XMLElement* SetValue(XFA_Attribute eAttr, void* pValue, bool bNotify);
244   int32_t Subform_and_SubformSet_InstanceIndex();
245 
246   XFA_MAPMODULEDATA* CreateMapModuleData();
247   XFA_MAPMODULEDATA* GetMapModuleData() const;
248   void SetMapModuleValue(void* pKey, void* pValue);
249   Optional<void*> GetMapModuleValue(void* pKey) const;
250   Optional<WideString> GetMapModuleString(void* pKey) const;
251   void SetMapModuleBuffer(void* pKey,
252                           void* pValue,
253                           int32_t iBytes,
254                           const XFA_MAPDATABLOCKCALLBACKINFO* pCallbackInfo);
255   bool GetMapModuleBuffer(void* pKey, void** pValue, int32_t* pBytes) const;
256   bool HasMapModuleKey(void* pKey);
257   void ClearMapModuleBuffer();
258   void RemoveMapModuleKey(void* pKey);
259   void MoveBufferMapData(CXFA_Object* pDstModule);
260 
261   UnownedPtr<CXFA_Object> object_;
262   UnownedPtr<CXFA_LayoutItem> layout_item_;
263   std::unique_ptr<XFA_MAPMODULEDATA> map_module_data_;
264   std::unique_ptr<CXFA_CalcData> calc_data_;
265   std::map<ByteString, CJX_MethodCall> method_specs_;
266   size_t calc_recursion_count_ = 0;
267 };
268 
269 typedef void (*XFA_ATTRIBUTE_CALLBACK)(CJX_Object* pNode,
270                                        CFXJSE_Value* pValue,
271                                        bool bSetting,
272                                        XFA_Attribute eAttribute);
273 
274 #endif  // FXJS_XFA_CJX_OBJECT_H_
275