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