blob: daf5a85ffe5eb693a3f3a86a935d4f527bf5796d [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);
122
123// CommitGlobalPersisitentVariables();
124 DestroyGlobalPersisitentVariables();
125
Bo Xufdc00a72014-10-28 23:03:33 -0700126 CJS_RuntimeFactory* pFactory = FPDFXFA_GetApp()->GetRuntimeFactory();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700127 ASSERT(pFactory);
128
129 pFactory->ReleaseGlobalData();
130}
131
132void global_alternate::Initial(CPDFDoc_Environment* pApp)
133{
134 m_pApp = pApp;
135
Bo Xufdc00a72014-10-28 23:03:33 -0700136 CJS_RuntimeFactory* pFactory = FPDFXFA_GetApp()->GetRuntimeFactory();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700137 ASSERT(pFactory);
138 m_pGlobalData = pFactory->NewGlobalData(pApp);
139 UpdateGlobalPersistentVariables();
140}
141
142FX_BOOL global_alternate::QueryProperty(FX_LPCWSTR propname)
143{
144 return CFX_WideString(propname) != L"setPersistent";
145}
146
Tom Sepez2f3dfef2015-03-02 15:35:26 -0800147FX_BOOL global_alternate::DelProperty(IFXJS_Context* cc, FX_LPCWSTR propname, CFX_WideString& sError)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700148{
149 js_global_data* pData = NULL;
150 CFX_ByteString sPropName = CFX_ByteString::FromUnicode(propname);
151
152 if (m_mapGlobal.Lookup(sPropName, (FX_LPVOID&)pData))
153 {
154 pData->bDeleted = TRUE;
155 return TRUE;
156 }
157
158 return FALSE;
159}
160
Tom Sepez2f3dfef2015-03-02 15:35:26 -0800161FX_BOOL global_alternate::DoProperty(IFXJS_Context* cc, FX_LPCWSTR propname, CJS_PropValue& vp, CFX_WideString& sError)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700162{
163 if (vp.IsSetting())
164 {
165 CFX_ByteString sPropName = CFX_ByteString::FromUnicode(propname);
166 switch (vp.GetType())
167 {
168 case VT_number:
169 {
170 double dData;
171 vp >> dData;
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200172 return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_NUMBER, dData, false, "", v8::Local<v8::Object>(), FALSE);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700173 }
174 case VT_boolean:
175 {
176 bool bData;
177 vp >> bData;
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200178 return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_BOOLEAN, 0, bData, "", v8::Local<v8::Object>(), FALSE);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700179 }
180 case VT_string:
181 {
182 CFX_ByteString sData;
183 vp >> sData;
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200184 return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_STRING, 0, false, sData, v8::Local<v8::Object>(), FALSE);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700185 }
186 case VT_object:
187 {
Tom Sepezf4ef3f92015-04-23 11:31:31 -0700188 JSObject pData;
189 vp >> pData;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700190 return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_OBJECT, 0, false, "", pData, FALSE);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700191 }
192 case VT_null:
193 {
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200194 return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_NULL, 0, false, "", v8::Local<v8::Object>(), FALSE);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700195 }
196 case VT_undefined:
197 {
198 DelProperty(cc, propname, sError);
199 return TRUE;
200 }
201 default:
202 return FALSE;
203 }
204 }
205 else
206 {
207 js_global_data* pData = NULL;
208 CFX_ByteString sPropName = CFX_ByteString::FromUnicode(propname);
209
210 if (m_mapGlobal.Lookup(sPropName, (FX_LPVOID&)pData))
211 {
212 if (pData)
213 {
214 if (!pData->bDeleted)
215 {
216 switch (pData->nType)
217 {
218 case JS_GLOBALDATA_TYPE_NUMBER:
219 vp << pData->dData;
220 break;
221 case JS_GLOBALDATA_TYPE_BOOLEAN:
222 vp << pData->bData;
223 break;
224 case JS_GLOBALDATA_TYPE_STRING:
225 vp << pData->sData;
226 break;
227 case JS_GLOBALDATA_TYPE_OBJECT:
228 {
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200229 v8::Local<v8::Object> obj = v8::Local<v8::Object>::New(vp.GetIsolate(),pData->pData);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700230 vp << obj;
231 break;
232 }
233 case JS_GLOBALDATA_TYPE_NULL:
234 vp.SetNull();
235 break;
236 default:
237 return FALSE;
238 }
239 return TRUE;
240 }
241 else
242 {
243 return TRUE;
244 }
245 }
246 else
247 {
248 vp.SetNull();
249 return TRUE;
250 }
251 }
252 else
253 {
254 vp.SetNull();
255 return TRUE;
256 }
257 }
258
259 return FALSE;
260}
261
Tom Sepez2f3dfef2015-03-02 15:35:26 -0800262FX_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 -0700263{
Tom Sepez3a832662015-03-02 12:59:05 -0800264 CJS_Context* pContext = static_cast<CJS_Context*>(cc);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700265 if (params.size() != 2)
266 {
Tom Sepez3a832662015-03-02 12:59:05 -0800267 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700268 return FALSE;
269 }
270
Tom Sepezf4ef3f92015-04-23 11:31:31 -0700271 CFX_ByteString sName = params[0].ToCFXByteString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700272
273 js_global_data* pData = NULL;
274 if (m_mapGlobal.Lookup(sName, (FX_LPVOID&)pData))
275 {
276 if (pData && !pData->bDeleted)
277 {
Tom Sepezf4ef3f92015-04-23 11:31:31 -0700278 pData->bPersistent = params[1].ToBool();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700279 return TRUE;
280 }
281 }
282
Tom Sepez3a832662015-03-02 12:59:05 -0800283 sError = JSGetStringFromID(pContext, IDS_STRING_JSNOGLOBAL);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700284 return FALSE;
285}
286
287void global_alternate::UpdateGlobalPersistentVariables()
288{
289 ASSERT(m_pGlobalData != NULL);
290
291 for (int i=0,sz=m_pGlobalData->GetSize(); i<sz; i++)
292 {
293 CJS_GlobalData_Element* pData = m_pGlobalData->GetAt(i);
294 ASSERT(pData != NULL);
295
296 switch (pData->data.nType)
297 {
298 case JS_GLOBALDATA_TYPE_NUMBER:
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200299 this->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 -0700300 JS_PutObjectNumber(NULL,(JSFXObject)(*m_pJSObject),
Tom Sepez4f7bc042015-04-27 12:06:58 -0700301 pData->data.sKey.UTF8Decode().c_str(), pData->data.dData);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700302 break;
303 case JS_GLOBALDATA_TYPE_BOOLEAN:
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200304 this->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 -0700305 JS_PutObjectBoolean(NULL,(JSFXObject)(*m_pJSObject),
Tom Sepez4f7bc042015-04-27 12:06:58 -0700306 pData->data.sKey.UTF8Decode().c_str(), (bool)(pData->data.bData == 1));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700307 break;
308 case JS_GLOBALDATA_TYPE_STRING:
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200309 this->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 -0700310 JS_PutObjectString(NULL, (JSFXObject)(*m_pJSObject),
311 pData->data.sKey.UTF8Decode().c_str(),
312 pData->data.sData.UTF8Decode().c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700313 break;
314 case JS_GLOBALDATA_TYPE_OBJECT:
315 {
316 IJS_Runtime* pRuntime = JS_GetRuntime((JSFXObject)(*m_pJSObject));
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200317 v8::Local<v8::Object> pObj = JS_NewFxDynamicObj(pRuntime, NULL, -1);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700318
319 PutObjectProperty(pObj, &pData->data);
320
321 this->SetGlobalVariables(pData->data.sKey, JS_GLOBALDATA_TYPE_OBJECT, 0, false, "",
322 (JSObject)pObj, pData->bPersistent == 1);
323 JS_PutObjectObject(NULL,(JSFXObject)(*m_pJSObject),
Tom Sepez4f7bc042015-04-27 12:06:58 -0700324 pData->data.sKey.UTF8Decode().c_str(), (JSObject)pObj);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700325 }
326 break;
327 case JS_GLOBALDATA_TYPE_NULL:
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200328 this->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 -0700329 JS_PutObjectNull(NULL,(JSFXObject)(*m_pJSObject),
Tom Sepez4f7bc042015-04-27 12:06:58 -0700330 pData->data.sKey.UTF8Decode().c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700331 break;
332 }
333 }
334}
335
336void global_alternate::CommitGlobalPersisitentVariables()
337{
338 ASSERT(m_pGlobalData != NULL);
339
340 FX_POSITION pos = m_mapGlobal.GetStartPosition();
341 while (pos)
342 {
343 CFX_ByteString name;
344 js_global_data* pData = NULL;
345 m_mapGlobal.GetNextAssoc(pos, name, (FX_LPVOID&)pData);
346
347 if (pData)
348 {
349 if (pData->bDeleted)
350 {
351 m_pGlobalData->DeleteGlobalVariable(name);
352 }
353 else
354 {
355 switch (pData->nType)
356 {
357 case JS_GLOBALDATA_TYPE_NUMBER:
358 m_pGlobalData->SetGlobalVariableNumber(name, pData->dData);
359 m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
360 break;
361 case JS_GLOBALDATA_TYPE_BOOLEAN:
362 m_pGlobalData->SetGlobalVariableBoolean(name, pData->bData);
363 m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
364 break;
365 case JS_GLOBALDATA_TYPE_STRING:
366 m_pGlobalData->SetGlobalVariableString(name, pData->sData);
367 m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
368 break;
369 case JS_GLOBALDATA_TYPE_OBJECT:
370 //if (pData->pData)
371 {
372 CJS_GlobalVariableArray array;
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200373 v8::Local<v8::Object> obj = v8::Local<v8::Object>::New(GetJSObject()->GetIsolate(),pData->pData);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700374 ObjectToArray(obj, array);
375 m_pGlobalData->SetGlobalVariableObject(name, array);
376 m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
377 }
378 break;
379 case JS_GLOBALDATA_TYPE_NULL:
380 m_pGlobalData->SetGlobalVariableNull(name);
381 m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
382 break;
383 }
384 }
385 }
386 }
387}
388
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200389void global_alternate::ObjectToArray(v8::Local<v8::Object> pObj, CJS_GlobalVariableArray& array)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700390{
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700391 v8::Local<v8::Context> context = pObj->CreationContext();
392 v8::Isolate* isolate = context->GetIsolate();
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200393 v8::Local<v8::Array> pKeyList = JS_GetObjectElementNames(isolate, pObj);
394 int nObjElements = pKeyList->Length();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700395
396 for (int i=0; i<nObjElements; i++)
397 {
398
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200399 CFX_WideString ws = JS_ToString(isolate, JS_GetArrayElement(isolate, pKeyList, i));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700400 CFX_ByteString sKey = ws.UTF8Encode();
401
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200402 v8::Local<v8::Value> v = JS_GetObjectElement(isolate, pObj, ws.c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700403 FXJSVALUETYPE vt = GET_VALUE_TYPE(v);
404 switch (vt)
405 {
406 case VT_number:
407 {
408 CJS_KeyValue* pObjElement = new CJS_KeyValue;
409 pObjElement->nType = JS_GLOBALDATA_TYPE_NUMBER;
410 pObjElement->sKey = sKey;
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200411 pObjElement->dData = JS_ToNumber(isolate, v);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700412 array.Add(pObjElement);
413 }
414 break;
415 case VT_boolean:
416 {
417 CJS_KeyValue* pObjElement = new CJS_KeyValue;
418 pObjElement->nType = JS_GLOBALDATA_TYPE_BOOLEAN;
419 pObjElement->sKey = sKey;
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200420 pObjElement->dData = JS_ToBoolean(isolate, v);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700421 array.Add(pObjElement);
422 }
423 break;
424 case VT_string:
425 {
Tom Sepezf4ef3f92015-04-23 11:31:31 -0700426 CFX_ByteString sValue = CJS_Value(isolate, v, VT_string).ToCFXByteString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700427 CJS_KeyValue* pObjElement = new CJS_KeyValue;
428 pObjElement->nType = JS_GLOBALDATA_TYPE_STRING;
429 pObjElement->sKey = sKey;
430 pObjElement->sData = sValue;
431 array.Add(pObjElement);
432 }
433 break;
434 case VT_object:
435 {
436 CJS_KeyValue* pObjElement = new CJS_KeyValue;
437 pObjElement->nType = JS_GLOBALDATA_TYPE_OBJECT;
438 pObjElement->sKey = sKey;
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200439 ObjectToArray(JS_ToObject(isolate, v), pObjElement->objData);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700440 array.Add(pObjElement);
441 }
442 break;
443 case VT_null:
444 {
445 CJS_KeyValue* pObjElement = new CJS_KeyValue;
446 pObjElement->nType = JS_GLOBALDATA_TYPE_NULL;
447 pObjElement->sKey = sKey;
448 array.Add(pObjElement);
449 }
450 break;
451 default:
452 break;
453 }
454 }
455}
456
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200457void global_alternate::PutObjectProperty(v8::Local<v8::Object> pObj, CJS_KeyValue* pData)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700458{
459 ASSERT(pData != NULL);
460
461 for (int i=0,sz=pData->objData.Count(); i<sz; i++)
462 {
463 CJS_KeyValue* pObjData = pData->objData.GetAt(i);
464 ASSERT(pObjData != NULL);
465
466 switch (pObjData->nType)
467 {
468 case JS_GLOBALDATA_TYPE_NUMBER:
Tom Sepez4f7bc042015-04-27 12:06:58 -0700469 JS_PutObjectNumber(NULL,(JSObject)pObj, pObjData->sKey.UTF8Decode().c_str(), pObjData->dData);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700470 break;
471 case JS_GLOBALDATA_TYPE_BOOLEAN:
Tom Sepez4f7bc042015-04-27 12:06:58 -0700472 JS_PutObjectBoolean(NULL,(JSObject)pObj, pObjData->sKey.UTF8Decode().c_str(), (bool)(pObjData->bData == 1));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700473 break;
474 case JS_GLOBALDATA_TYPE_STRING:
Tom Sepez4f7bc042015-04-27 12:06:58 -0700475 JS_PutObjectString(NULL,(JSObject)pObj, pObjData->sKey.UTF8Decode().c_str(), pObjData->sData.UTF8Decode().c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700476 break;
477 case JS_GLOBALDATA_TYPE_OBJECT:
478 {
479 IJS_Runtime* pRuntime = JS_GetRuntime((JSFXObject)(*m_pJSObject));
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200480 v8::Local<v8::Object> pNewObj = JS_NewFxDynamicObj(pRuntime, NULL, -1);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700481 PutObjectProperty(pNewObj, pObjData);
Tom Sepez4f7bc042015-04-27 12:06:58 -0700482 JS_PutObjectObject(NULL, (JSObject)pObj, pObjData->sKey.UTF8Decode().c_str(), (JSObject)pNewObj);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700483 }
484 break;
485 case JS_GLOBALDATA_TYPE_NULL:
Tom Sepez4f7bc042015-04-27 12:06:58 -0700486 JS_PutObjectNull(NULL,(JSObject)pObj, pObjData->sKey.UTF8Decode().c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700487 break;
488 }
489 }
490}
491
492void global_alternate::DestroyGlobalPersisitentVariables()
493{
494 FX_POSITION pos = m_mapGlobal.GetStartPosition();
495 while (pos)
496 {
497 CFX_ByteString name;
498 js_global_data* pData = NULL;
499 m_mapGlobal.GetNextAssoc(pos, name, (FX_LPVOID&)pData);
500 delete pData;
501 }
502
503 m_mapGlobal.RemoveAll();
504}
505
506
507FX_BOOL global_alternate::SetGlobalVariables(FX_LPCSTR propname, int nType,
508 double dData, bool bData, const CFX_ByteString& sData, JSObject pData, bool bDefaultPersistent)
509{
510 if (propname == NULL) return FALSE;
511
512 js_global_data* pTemp = NULL;
513 m_mapGlobal.Lookup(propname, (FX_LPVOID&)pTemp);
514
515 if (pTemp)
516 {
517 if (pTemp->bDeleted || pTemp->nType != nType)
518 {
519 pTemp->dData = 0;
520 pTemp->bData = 0;
521 pTemp->sData = "";
522 pTemp->nType = nType;
523 }
524
525 pTemp->bDeleted = FALSE;
526
527 switch (nType)
528 {
529 case JS_GLOBALDATA_TYPE_NUMBER:
530 {
531 pTemp->dData = dData;
532 }
533 break;
534 case JS_GLOBALDATA_TYPE_BOOLEAN:
535 {
536 pTemp->bData = bData;
537 }
538 break;
539 case JS_GLOBALDATA_TYPE_STRING:
540 {
541 pTemp->sData = sData;
542 }
543 break;
544 case JS_GLOBALDATA_TYPE_OBJECT:
545 {
546 pTemp->pData.Reset(JS_GetRuntime(pData), pData);
547 }
548 break;
549 case JS_GLOBALDATA_TYPE_NULL:
550 break;
551 default:
552 return FALSE;
553 }
554
555 return TRUE;
556 }
557
558 js_global_data* pNewData = NULL;
559
560 switch (nType)
561 {
562 case JS_GLOBALDATA_TYPE_NUMBER:
563 {
564 pNewData = new js_global_data;
565 pNewData->nType = JS_GLOBALDATA_TYPE_NUMBER;
566 pNewData->dData = dData;
567 pNewData->bPersistent = bDefaultPersistent;
568 }
569 break;
570 case JS_GLOBALDATA_TYPE_BOOLEAN:
571 {
572 pNewData = new js_global_data;
573 pNewData->nType = JS_GLOBALDATA_TYPE_BOOLEAN;
574 pNewData->bData = bData;
575 pNewData->bPersistent = bDefaultPersistent;
576 }
577 break;
578 case JS_GLOBALDATA_TYPE_STRING:
579 {
580 pNewData = new js_global_data;
581 pNewData->nType = JS_GLOBALDATA_TYPE_STRING;
582 pNewData->sData = sData;
583 pNewData->bPersistent = bDefaultPersistent;
584 }
585 break;
586 case JS_GLOBALDATA_TYPE_OBJECT:
587 {
588 pNewData = new js_global_data;
589 pNewData->nType = JS_GLOBALDATA_TYPE_OBJECT;
590 pNewData->pData.Reset(JS_GetRuntime(pData), pData);
591 pNewData->bPersistent = bDefaultPersistent;
592 }
593 break;
594 case JS_GLOBALDATA_TYPE_NULL:
595 {
596 pNewData = new js_global_data;
597 pNewData->nType = JS_GLOBALDATA_TYPE_NULL;
598 pNewData->bPersistent = bDefaultPersistent;
599 }
600 break;
601 default:
602 return FALSE;
603 }
604
605 m_mapGlobal.SetAt(propname, (FX_LPVOID)pNewData);
606
607 return TRUE;
608}
Tom Sepezccc94832015-02-17 13:30:23 -0800609
Jochen Eisingerdfa2c992015-05-19 00:38:00 +0200610FXJSVALUETYPE GET_VALUE_TYPE(v8::Local<v8::Value> p)
Tom Sepezccc94832015-02-17 13:30:23 -0800611{
612 const unsigned int nHash = JS_CalcHash(JS_GetTypeof(p));
613
614 if (nHash == JSCONST_nUndefHash)
615 return VT_undefined;
616 if (nHash == JSCONST_nNullHash)
617 return VT_null;
618 if (nHash == JSCONST_nStringHash)
619 return VT_string;
620 if (nHash == JSCONST_nNumberHash)
621 return VT_number;
622 if (nHash == JSCONST_nBoolHash)
623 return VT_boolean;
624 if (nHash == JSCONST_nDateHash)
625 return VT_date;
626 if (nHash == JSCONST_nObjectHash)
627 return VT_object;
628 if (nHash == JSCONST_nFXobjHash)
629 return VT_fxobject;
630
631 return VT_unknown;
632}
633