blob: b7908dc99320cb1e9a800cb1e4b88c1cce3dc0a3 [file] [log] [blame]
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001// 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
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07007#include "../../include/javascript/IJavaScript.h"
Tom Sepez3a832662015-03-02 12:59:05 -08008#include "../../include/javascript/JS_Context.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07009#include "../../include/javascript/JS_Define.h"
Tom Sepez3a832662015-03-02 12:59:05 -080010#include "../../include/javascript/JS_EventHandler.h"
11#include "../../include/javascript/JS_GlobalData.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070012#include "../../include/javascript/JS_Object.h"
13#include "../../include/javascript/JS_Value.h"
Tom Sepez3a832662015-03-02 12:59:05 -080014#include "../../include/javascript/JavaScript.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070015#include "../../include/javascript/global.h"
Bo Xufdc00a72014-10-28 23:03:33 -070016#include "../../include/fpdfxfa/fpdfxfa_app.h"
Tom Sepez3a832662015-03-02 12:59:05 -080017#include "../../include/javascript/resource.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070018
19/* ---------------------------- global ---------------------------- */
20
Bruce Dawsone68d6242015-01-05 15:18:21 -080021// Helper class for compile-time calculation of hash values in order to
22// avoid having global object initializers.
Lei Zhang659b8d32015-02-27 19:49:57 -080023template <unsigned ACC, wchar_t... Ns>
24struct CHash;
25
26// Only needed to hash single-character strings.
27template <wchar_t N>
28struct CHash<N> {
29 static const unsigned value = N;
30};
31
32template <unsigned ACC, wchar_t N>
33struct CHash<ACC, N> {
34 static const unsigned value = (ACC * 1313LLU + N) & 0xFFFFFFFF;
35};
36
37template <unsigned ACC, wchar_t N, wchar_t... Ns>
38struct CHash<ACC, N, Ns...> {
39 static const unsigned value = CHash<CHash<ACC, N>::value, Ns...>::value;
40};
Bruce Dawsone68d6242015-01-05 15:18:21 -080041
42extern const unsigned int JSCONST_nStringHash =
43 CHash<'s','t','r','i','n','g'>::value;
44extern const unsigned int JSCONST_nNumberHash =
45 CHash<'n','u','m','b','e','r'>::value;
46extern const unsigned int JSCONST_nBoolHash =
47 CHash<'b','o','o','l','e','a','n'>::value;
48extern const unsigned int JSCONST_nDateHash =
49 CHash<'d','a','t','e'>::value;
50extern const unsigned int JSCONST_nObjectHash =
51 CHash<'o','b','j','e','c','t'>::value;
52extern const unsigned int JSCONST_nFXobjHash =
53 CHash<'f','x','o','b','j'>::value;
54extern const unsigned int JSCONST_nNullHash =
55 CHash<'n','u','l','l'>::value;
56extern const unsigned int JSCONST_nUndefHash =
57 CHash<'u','n','d','e','f','i','n','e','d'>::value;
58
59#ifdef _DEBUG
60class HashVerify
61{
62public:
63 HashVerify();
64} g_hashVerify;
65
66HashVerify::HashVerify()
67{
68 ASSERT(JSCONST_nStringHash ==
69 JS_CalcHash(VALUE_NAME_STRING,wcslen(VALUE_NAME_STRING)));
70 ASSERT(JSCONST_nNumberHash ==
71 JS_CalcHash(VALUE_NAME_NUMBER,wcslen(VALUE_NAME_NUMBER)));
72 ASSERT(JSCONST_nBoolHash ==
73 JS_CalcHash(VALUE_NAME_BOOLEAN,wcslen(VALUE_NAME_BOOLEAN)));
74 ASSERT(JSCONST_nDateHash ==
75 JS_CalcHash(VALUE_NAME_DATE,wcslen(VALUE_NAME_DATE)));
76 ASSERT(JSCONST_nObjectHash ==
77 JS_CalcHash(VALUE_NAME_OBJECT,wcslen(VALUE_NAME_OBJECT)));
78 ASSERT(JSCONST_nFXobjHash ==
79 JS_CalcHash(VALUE_NAME_FXOBJ,wcslen(VALUE_NAME_FXOBJ)));
80 ASSERT(JSCONST_nNullHash ==
81 JS_CalcHash(VALUE_NAME_NULL,wcslen(VALUE_NAME_NULL)));
82 ASSERT(JSCONST_nUndefHash ==
83 JS_CalcHash(VALUE_NAME_UNDEFINED,wcslen(VALUE_NAME_UNDEFINED)));
84}
85#endif
86
Bruce Dawsonc674af42014-12-12 21:30:37 -080087
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070088BEGIN_JS_STATIC_CONST(CJS_Global)
89END_JS_STATIC_CONST()
90
91BEGIN_JS_STATIC_PROP(CJS_Global)
92END_JS_STATIC_PROP()
93
94BEGIN_JS_STATIC_METHOD(CJS_Global)
Tom Sepeze5350ef2015-04-23 18:14:26 -070095 JS_STATIC_METHOD_ENTRY(setPersistent)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070096END_JS_STATIC_METHOD()
97
98IMPLEMENT_SPECIAL_JS_CLASS(CJS_Global, global_alternate, global);
99
100FX_BOOL CJS_Global::InitInstance(IFXJS_Context* cc)
101{
102 CJS_Context* pContext = (CJS_Context*)cc;
103 ASSERT(pContext != NULL);
104
105 global_alternate* pGlobal = (global_alternate*)GetEmbedObject();
106 ASSERT(pGlobal != NULL);
107
108 pGlobal->Initial(pContext->GetReaderApp());
109
110 return TRUE;
111};
112
113global_alternate::global_alternate(CJS_Object* pJSObject)
114 : CJS_EmbedObj(pJSObject),
115 m_pApp(NULL)
116{
117}
118
119global_alternate::~global_alternate(void)
120{
121 ASSERT(m_pApp != NULL);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700122 DestroyGlobalPersisitentVariables();
123
Tom Sepezbdeeb8a2015-05-27 12:25:00 -0700124 CJS_RuntimeFactory* pFactory = CPDFXFA_App::GetInstance()->GetRuntimeFactory();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700125 pFactory->ReleaseGlobalData();
126}
Tom Sepezbdeeb8a2015-05-27 12:25:00 -0700127
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700128void global_alternate::Initial(CPDFDoc_Environment* pApp)
129{
130 m_pApp = pApp;
131
Tom Sepezbdeeb8a2015-05-27 12:25:00 -0700132 CJS_RuntimeFactory* pFactory = CPDFXFA_App::GetInstance()->GetRuntimeFactory();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700133 m_pGlobalData = pFactory->NewGlobalData(pApp);
134 UpdateGlobalPersistentVariables();
135}
136
Tom Sepezd7e5cc72015-06-10 14:33:37 -0700137FX_BOOL global_alternate::QueryProperty(const FX_WCHAR* propname)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700138{
139 return CFX_WideString(propname) != L"setPersistent";
140}
141
Tom Sepezd7e5cc72015-06-10 14:33:37 -0700142FX_BOOL global_alternate::DelProperty(IFXJS_Context* cc, const FX_WCHAR* propname, CFX_WideString& sError)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700143{
144 js_global_data* pData = NULL;
145 CFX_ByteString sPropName = CFX_ByteString::FromUnicode(propname);
146
Tom Sepezd7e5cc72015-06-10 14:33:37 -0700147 if (m_mapGlobal.Lookup(sPropName, (void*&)pData))
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700148 {
149 pData->bDeleted = TRUE;
150 return TRUE;
151 }
152
153 return FALSE;
154}
155
Tom Sepezd7e5cc72015-06-10 14:33:37 -0700156FX_BOOL global_alternate::DoProperty(IFXJS_Context* cc, const FX_WCHAR* propname, CJS_PropValue& vp, CFX_WideString& sError)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700157{
158 if (vp.IsSetting())
159 {
160 CFX_ByteString sPropName = CFX_ByteString::FromUnicode(propname);
161 switch (vp.GetType())
162 {
163 case VT_number:
164 {
165 double dData;
166 vp >> dData;
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200167 return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_NUMBER, dData, false, "", v8::Local<v8::Object>(), FALSE);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700168 }
169 case VT_boolean:
170 {
171 bool bData;
172 vp >> bData;
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200173 return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_BOOLEAN, 0, bData, "", v8::Local<v8::Object>(), FALSE);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700174 }
175 case VT_string:
176 {
177 CFX_ByteString sData;
178 vp >> sData;
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200179 return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_STRING, 0, false, sData, v8::Local<v8::Object>(), FALSE);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700180 }
181 case VT_object:
182 {
Tom Sepezf4ef3f92015-04-23 11:31:31 -0700183 JSObject pData;
184 vp >> pData;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700185 return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_OBJECT, 0, false, "", pData, FALSE);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700186 }
187 case VT_null:
188 {
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200189 return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_NULL, 0, false, "", v8::Local<v8::Object>(), FALSE);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700190 }
191 case VT_undefined:
192 {
193 DelProperty(cc, propname, sError);
194 return TRUE;
195 }
196 default:
197 return FALSE;
198 }
199 }
200 else
201 {
202 js_global_data* pData = NULL;
203 CFX_ByteString sPropName = CFX_ByteString::FromUnicode(propname);
204
Tom Sepezd7e5cc72015-06-10 14:33:37 -0700205 if (m_mapGlobal.Lookup(sPropName, (void*&)pData))
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700206 {
207 if (pData)
208 {
209 if (!pData->bDeleted)
210 {
211 switch (pData->nType)
212 {
213 case JS_GLOBALDATA_TYPE_NUMBER:
214 vp << pData->dData;
215 break;
216 case JS_GLOBALDATA_TYPE_BOOLEAN:
217 vp << pData->bData;
218 break;
219 case JS_GLOBALDATA_TYPE_STRING:
220 vp << pData->sData;
221 break;
222 case JS_GLOBALDATA_TYPE_OBJECT:
223 {
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200224 v8::Local<v8::Object> obj = v8::Local<v8::Object>::New(vp.GetIsolate(),pData->pData);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700225 vp << obj;
226 break;
227 }
228 case JS_GLOBALDATA_TYPE_NULL:
229 vp.SetNull();
230 break;
231 default:
232 return FALSE;
233 }
234 return TRUE;
235 }
236 else
237 {
238 return TRUE;
239 }
240 }
241 else
242 {
243 vp.SetNull();
244 return TRUE;
245 }
246 }
247 else
248 {
249 vp.SetNull();
250 return TRUE;
251 }
252 }
253
254 return FALSE;
255}
256
Tom Sepez2f3dfef2015-03-02 15:35:26 -0800257FX_BOOL global_alternate::setPersistent(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700258{
Tom Sepez3a832662015-03-02 12:59:05 -0800259 CJS_Context* pContext = static_cast<CJS_Context*>(cc);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700260 if (params.size() != 2)
261 {
Tom Sepez3a832662015-03-02 12:59:05 -0800262 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700263 return FALSE;
264 }
265
Tom Sepezf4ef3f92015-04-23 11:31:31 -0700266 CFX_ByteString sName = params[0].ToCFXByteString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700267
268 js_global_data* pData = NULL;
Tom Sepezd7e5cc72015-06-10 14:33:37 -0700269 if (m_mapGlobal.Lookup(sName, (void*&)pData))
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700270 {
271 if (pData && !pData->bDeleted)
272 {
Tom Sepezf4ef3f92015-04-23 11:31:31 -0700273 pData->bPersistent = params[1].ToBool();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700274 return TRUE;
275 }
276 }
277
Tom Sepez3a832662015-03-02 12:59:05 -0800278 sError = JSGetStringFromID(pContext, IDS_STRING_JSNOGLOBAL);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700279 return FALSE;
280}
281
282void global_alternate::UpdateGlobalPersistentVariables()
283{
284 ASSERT(m_pGlobalData != NULL);
285
286 for (int i=0,sz=m_pGlobalData->GetSize(); i<sz; i++)
287 {
288 CJS_GlobalData_Element* pData = m_pGlobalData->GetAt(i);
289 ASSERT(pData != NULL);
290
291 switch (pData->data.nType)
292 {
293 case JS_GLOBALDATA_TYPE_NUMBER:
Lei Zhang60f507b2015-06-13 00:41:00 -0700294 SetGlobalVariables(pData->data.sKey, JS_GLOBALDATA_TYPE_NUMBER, pData->data.dData, false, "", v8::Local<v8::Object>(), pData->bPersistent == 1);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700295 JS_PutObjectNumber(NULL,(JSFXObject)(*m_pJSObject),
Tom Sepez4f7bc042015-04-27 12:06:58 -0700296 pData->data.sKey.UTF8Decode().c_str(), pData->data.dData);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700297 break;
298 case JS_GLOBALDATA_TYPE_BOOLEAN:
Lei Zhang60f507b2015-06-13 00:41:00 -0700299 SetGlobalVariables(pData->data.sKey, JS_GLOBALDATA_TYPE_BOOLEAN, 0, (bool)(pData->data.bData == 1), "", v8::Local<v8::Object>(), pData->bPersistent == 1);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700300 JS_PutObjectBoolean(NULL,(JSFXObject)(*m_pJSObject),
Tom Sepez4f7bc042015-04-27 12:06:58 -0700301 pData->data.sKey.UTF8Decode().c_str(), (bool)(pData->data.bData == 1));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700302 break;
303 case JS_GLOBALDATA_TYPE_STRING:
Lei Zhang60f507b2015-06-13 00:41:00 -0700304 SetGlobalVariables(pData->data.sKey, JS_GLOBALDATA_TYPE_STRING, 0, false, pData->data.sData, v8::Local<v8::Object>(), pData->bPersistent == 1);
Tom Sepez4f7bc042015-04-27 12:06:58 -0700305 JS_PutObjectString(NULL, (JSFXObject)(*m_pJSObject),
306 pData->data.sKey.UTF8Decode().c_str(),
307 pData->data.sData.UTF8Decode().c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700308 break;
309 case JS_GLOBALDATA_TYPE_OBJECT:
310 {
311 IJS_Runtime* pRuntime = JS_GetRuntime((JSFXObject)(*m_pJSObject));
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200312 v8::Local<v8::Object> pObj = JS_NewFxDynamicObj(pRuntime, NULL, -1);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700313
314 PutObjectProperty(pObj, &pData->data);
315
Lei Zhang60f507b2015-06-13 00:41:00 -0700316 SetGlobalVariables(pData->data.sKey, JS_GLOBALDATA_TYPE_OBJECT, 0, false, "",
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700317 (JSObject)pObj, pData->bPersistent == 1);
318 JS_PutObjectObject(NULL,(JSFXObject)(*m_pJSObject),
Tom Sepez4f7bc042015-04-27 12:06:58 -0700319 pData->data.sKey.UTF8Decode().c_str(), (JSObject)pObj);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700320 }
321 break;
322 case JS_GLOBALDATA_TYPE_NULL:
Lei Zhang60f507b2015-06-13 00:41:00 -0700323 SetGlobalVariables(pData->data.sKey, JS_GLOBALDATA_TYPE_NULL, 0, false, "", v8::Local<v8::Object>(), pData->bPersistent == 1);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700324 JS_PutObjectNull(NULL,(JSFXObject)(*m_pJSObject),
Tom Sepez4f7bc042015-04-27 12:06:58 -0700325 pData->data.sKey.UTF8Decode().c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700326 break;
327 }
328 }
329}
330
331void global_alternate::CommitGlobalPersisitentVariables()
332{
333 ASSERT(m_pGlobalData != NULL);
334
335 FX_POSITION pos = m_mapGlobal.GetStartPosition();
336 while (pos)
337 {
338 CFX_ByteString name;
339 js_global_data* pData = NULL;
Tom Sepezd7e5cc72015-06-10 14:33:37 -0700340 m_mapGlobal.GetNextAssoc(pos, name, (void*&)pData);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700341
342 if (pData)
343 {
344 if (pData->bDeleted)
345 {
346 m_pGlobalData->DeleteGlobalVariable(name);
347 }
348 else
349 {
350 switch (pData->nType)
351 {
352 case JS_GLOBALDATA_TYPE_NUMBER:
353 m_pGlobalData->SetGlobalVariableNumber(name, pData->dData);
354 m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
355 break;
356 case JS_GLOBALDATA_TYPE_BOOLEAN:
357 m_pGlobalData->SetGlobalVariableBoolean(name, pData->bData);
358 m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
359 break;
360 case JS_GLOBALDATA_TYPE_STRING:
361 m_pGlobalData->SetGlobalVariableString(name, pData->sData);
362 m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
363 break;
364 case JS_GLOBALDATA_TYPE_OBJECT:
365 //if (pData->pData)
366 {
367 CJS_GlobalVariableArray array;
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200368 v8::Local<v8::Object> obj = v8::Local<v8::Object>::New(GetJSObject()->GetIsolate(),pData->pData);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700369 ObjectToArray(obj, array);
370 m_pGlobalData->SetGlobalVariableObject(name, array);
371 m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
372 }
373 break;
374 case JS_GLOBALDATA_TYPE_NULL:
375 m_pGlobalData->SetGlobalVariableNull(name);
376 m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
377 break;
378 }
379 }
380 }
381 }
382}
383
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200384void global_alternate::ObjectToArray(v8::Local<v8::Object> pObj, CJS_GlobalVariableArray& array)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700385{
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700386 v8::Local<v8::Context> context = pObj->CreationContext();
387 v8::Isolate* isolate = context->GetIsolate();
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200388 v8::Local<v8::Array> pKeyList = JS_GetObjectElementNames(isolate, pObj);
389 int nObjElements = pKeyList->Length();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700390
391 for (int i=0; i<nObjElements; i++)
392 {
393
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200394 CFX_WideString ws = JS_ToString(isolate, JS_GetArrayElement(isolate, pKeyList, i));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700395 CFX_ByteString sKey = ws.UTF8Encode();
396
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200397 v8::Local<v8::Value> v = JS_GetObjectElement(isolate, pObj, ws.c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700398 FXJSVALUETYPE vt = GET_VALUE_TYPE(v);
399 switch (vt)
400 {
401 case VT_number:
402 {
403 CJS_KeyValue* pObjElement = new CJS_KeyValue;
404 pObjElement->nType = JS_GLOBALDATA_TYPE_NUMBER;
405 pObjElement->sKey = sKey;
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200406 pObjElement->dData = JS_ToNumber(isolate, v);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700407 array.Add(pObjElement);
408 }
409 break;
410 case VT_boolean:
411 {
412 CJS_KeyValue* pObjElement = new CJS_KeyValue;
413 pObjElement->nType = JS_GLOBALDATA_TYPE_BOOLEAN;
414 pObjElement->sKey = sKey;
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200415 pObjElement->dData = JS_ToBoolean(isolate, v);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700416 array.Add(pObjElement);
417 }
418 break;
419 case VT_string:
420 {
Tom Sepezf4ef3f92015-04-23 11:31:31 -0700421 CFX_ByteString sValue = CJS_Value(isolate, v, VT_string).ToCFXByteString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700422 CJS_KeyValue* pObjElement = new CJS_KeyValue;
423 pObjElement->nType = JS_GLOBALDATA_TYPE_STRING;
424 pObjElement->sKey = sKey;
425 pObjElement->sData = sValue;
426 array.Add(pObjElement);
427 }
428 break;
429 case VT_object:
430 {
431 CJS_KeyValue* pObjElement = new CJS_KeyValue;
432 pObjElement->nType = JS_GLOBALDATA_TYPE_OBJECT;
433 pObjElement->sKey = sKey;
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200434 ObjectToArray(JS_ToObject(isolate, v), pObjElement->objData);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700435 array.Add(pObjElement);
436 }
437 break;
438 case VT_null:
439 {
440 CJS_KeyValue* pObjElement = new CJS_KeyValue;
441 pObjElement->nType = JS_GLOBALDATA_TYPE_NULL;
442 pObjElement->sKey = sKey;
443 array.Add(pObjElement);
444 }
445 break;
446 default:
447 break;
448 }
449 }
450}
451
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200452void global_alternate::PutObjectProperty(v8::Local<v8::Object> pObj, CJS_KeyValue* pData)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700453{
454 ASSERT(pData != NULL);
455
456 for (int i=0,sz=pData->objData.Count(); i<sz; i++)
457 {
458 CJS_KeyValue* pObjData = pData->objData.GetAt(i);
459 ASSERT(pObjData != NULL);
460
461 switch (pObjData->nType)
462 {
463 case JS_GLOBALDATA_TYPE_NUMBER:
Tom Sepez4f7bc042015-04-27 12:06:58 -0700464 JS_PutObjectNumber(NULL,(JSObject)pObj, pObjData->sKey.UTF8Decode().c_str(), pObjData->dData);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700465 break;
466 case JS_GLOBALDATA_TYPE_BOOLEAN:
Tom Sepez4f7bc042015-04-27 12:06:58 -0700467 JS_PutObjectBoolean(NULL,(JSObject)pObj, pObjData->sKey.UTF8Decode().c_str(), (bool)(pObjData->bData == 1));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700468 break;
469 case JS_GLOBALDATA_TYPE_STRING:
Tom Sepez4f7bc042015-04-27 12:06:58 -0700470 JS_PutObjectString(NULL,(JSObject)pObj, pObjData->sKey.UTF8Decode().c_str(), pObjData->sData.UTF8Decode().c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700471 break;
472 case JS_GLOBALDATA_TYPE_OBJECT:
473 {
474 IJS_Runtime* pRuntime = JS_GetRuntime((JSFXObject)(*m_pJSObject));
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200475 v8::Local<v8::Object> pNewObj = JS_NewFxDynamicObj(pRuntime, NULL, -1);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700476 PutObjectProperty(pNewObj, pObjData);
Tom Sepez4f7bc042015-04-27 12:06:58 -0700477 JS_PutObjectObject(NULL, (JSObject)pObj, pObjData->sKey.UTF8Decode().c_str(), (JSObject)pNewObj);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700478 }
479 break;
480 case JS_GLOBALDATA_TYPE_NULL:
Tom Sepez4f7bc042015-04-27 12:06:58 -0700481 JS_PutObjectNull(NULL,(JSObject)pObj, pObjData->sKey.UTF8Decode().c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700482 break;
483 }
484 }
485}
486
487void global_alternate::DestroyGlobalPersisitentVariables()
488{
489 FX_POSITION pos = m_mapGlobal.GetStartPosition();
490 while (pos)
491 {
492 CFX_ByteString name;
493 js_global_data* pData = NULL;
Tom Sepezd7e5cc72015-06-10 14:33:37 -0700494 m_mapGlobal.GetNextAssoc(pos, name, (void*&)pData);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700495 delete pData;
496 }
497
498 m_mapGlobal.RemoveAll();
499}
500
501
Tom Sepezd7e5cc72015-06-10 14:33:37 -0700502FX_BOOL global_alternate::SetGlobalVariables(const FX_CHAR* propname, int nType,
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700503 double dData, bool bData, const CFX_ByteString& sData, JSObject pData, bool bDefaultPersistent)
504{
505 if (propname == NULL) return FALSE;
506
507 js_global_data* pTemp = NULL;
Tom Sepezd7e5cc72015-06-10 14:33:37 -0700508 m_mapGlobal.Lookup(propname, (void*&)pTemp);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700509
510 if (pTemp)
511 {
512 if (pTemp->bDeleted || pTemp->nType != nType)
513 {
514 pTemp->dData = 0;
515 pTemp->bData = 0;
516 pTemp->sData = "";
517 pTemp->nType = nType;
518 }
519
520 pTemp->bDeleted = FALSE;
521
522 switch (nType)
523 {
524 case JS_GLOBALDATA_TYPE_NUMBER:
525 {
526 pTemp->dData = dData;
527 }
528 break;
529 case JS_GLOBALDATA_TYPE_BOOLEAN:
530 {
531 pTemp->bData = bData;
532 }
533 break;
534 case JS_GLOBALDATA_TYPE_STRING:
535 {
536 pTemp->sData = sData;
537 }
538 break;
539 case JS_GLOBALDATA_TYPE_OBJECT:
540 {
541 pTemp->pData.Reset(JS_GetRuntime(pData), pData);
542 }
543 break;
544 case JS_GLOBALDATA_TYPE_NULL:
545 break;
546 default:
547 return FALSE;
548 }
549
550 return TRUE;
551 }
552
553 js_global_data* pNewData = NULL;
554
555 switch (nType)
556 {
557 case JS_GLOBALDATA_TYPE_NUMBER:
558 {
559 pNewData = new js_global_data;
560 pNewData->nType = JS_GLOBALDATA_TYPE_NUMBER;
561 pNewData->dData = dData;
562 pNewData->bPersistent = bDefaultPersistent;
563 }
564 break;
565 case JS_GLOBALDATA_TYPE_BOOLEAN:
566 {
567 pNewData = new js_global_data;
568 pNewData->nType = JS_GLOBALDATA_TYPE_BOOLEAN;
569 pNewData->bData = bData;
570 pNewData->bPersistent = bDefaultPersistent;
571 }
572 break;
573 case JS_GLOBALDATA_TYPE_STRING:
574 {
575 pNewData = new js_global_data;
576 pNewData->nType = JS_GLOBALDATA_TYPE_STRING;
577 pNewData->sData = sData;
578 pNewData->bPersistent = bDefaultPersistent;
579 }
580 break;
581 case JS_GLOBALDATA_TYPE_OBJECT:
582 {
583 pNewData = new js_global_data;
584 pNewData->nType = JS_GLOBALDATA_TYPE_OBJECT;
585 pNewData->pData.Reset(JS_GetRuntime(pData), pData);
586 pNewData->bPersistent = bDefaultPersistent;
587 }
588 break;
589 case JS_GLOBALDATA_TYPE_NULL:
590 {
591 pNewData = new js_global_data;
592 pNewData->nType = JS_GLOBALDATA_TYPE_NULL;
593 pNewData->bPersistent = bDefaultPersistent;
594 }
595 break;
596 default:
597 return FALSE;
598 }
599
Tom Sepezd7e5cc72015-06-10 14:33:37 -0700600 m_mapGlobal.SetAt(propname, (void*)pNewData);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700601
602 return TRUE;
603}
Tom Sepezccc94832015-02-17 13:30:23 -0800604
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200605FXJSVALUETYPE GET_VALUE_TYPE(v8::Local<v8::Value> p)
Tom Sepezccc94832015-02-17 13:30:23 -0800606{
607 const unsigned int nHash = JS_CalcHash(JS_GetTypeof(p));
608
609 if (nHash == JSCONST_nUndefHash)
610 return VT_undefined;
611 if (nHash == JSCONST_nNullHash)
612 return VT_null;
613 if (nHash == JSCONST_nStringHash)
614 return VT_string;
615 if (nHash == JSCONST_nNumberHash)
616 return VT_number;
617 if (nHash == JSCONST_nBoolHash)
618 return VT_boolean;
619 if (nHash == JSCONST_nDateHash)
620 return VT_date;
621 if (nHash == JSCONST_nObjectHash)
622 return VT_object;
623 if (nHash == JSCONST_nFXobjHash)
624 return VT_fxobject;
625
626 return VT_unknown;
627}
628