blob: 10bab26dd0b3397c75ad8c233870771635e84212 [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.
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07004
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07005// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
Dan Sinclairf766ad22016-03-14 13:51:24 -04007#include "fpdfsdk/javascript/global.h"
Tom Sepez37458412015-10-06 11:33:46 -07008
Dan Sinclair3ebd1212016-03-09 09:59:23 -05009#include <vector>
10
Dan Sinclaira8a28e02016-03-23 15:41:39 -040011#include "core/fxcrt/include/fx_ext.h"
Dan Sinclairf766ad22016-03-14 13:51:24 -040012#include "fpdfsdk/javascript/JS_Define.h"
13#include "fpdfsdk/javascript/JS_EventHandler.h"
14#include "fpdfsdk/javascript/JS_GlobalData.h"
15#include "fpdfsdk/javascript/JS_Object.h"
16#include "fpdfsdk/javascript/JS_Value.h"
dsinclair64376be2016-03-31 20:03:24 -070017#include "fpdfsdk/javascript/cjs_context.h"
Dan Sinclairf766ad22016-03-14 13:51:24 -040018#include "fpdfsdk/javascript/resource.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070019
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070020BEGIN_JS_STATIC_CONST(CJS_Global)
21END_JS_STATIC_CONST()
22
23BEGIN_JS_STATIC_PROP(CJS_Global)
24END_JS_STATIC_PROP()
25
26BEGIN_JS_STATIC_METHOD(CJS_Global)
Nico Weber9d8ec5a2015-08-04 13:00:21 -070027JS_STATIC_METHOD_ENTRY(setPersistent)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070028END_JS_STATIC_METHOD()
29
Tom Sepez7dc5cc12015-08-17 12:15:26 -070030IMPLEMENT_SPECIAL_JS_CLASS(CJS_Global, JSGlobalAlternate, global);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070031
Tom Sepez33420902015-10-13 15:00:10 -070032void CJS_Global::InitInstance(IJS_Runtime* pIRuntime) {
33 CJS_Runtime* pRuntime = static_cast<CJS_Runtime*>(pIRuntime);
34 JSGlobalAlternate* pGlobal =
35 static_cast<JSGlobalAlternate*>(GetEmbedObject());
36 pGlobal->Initial(pRuntime->GetReaderApp());
37}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070038
weili625ad662016-06-15 11:21:33 -070039JSGlobalData::JSGlobalData()
weili47228ac2016-07-20 10:35:31 -070040 : nType(JS_GlobalDataType::NUMBER),
weili625ad662016-06-15 11:21:33 -070041 dData(0),
42 bData(FALSE),
43 sData(""),
44 bPersistent(FALSE),
45 bDeleted(FALSE) {}
46
47JSGlobalData::~JSGlobalData() {
48 pData.Reset();
49}
50
Tom Sepez7dc5cc12015-08-17 12:15:26 -070051JSGlobalAlternate::JSGlobalAlternate(CJS_Object* pJSObject)
thestig1cd352e2016-06-07 17:53:06 -070052 : CJS_EmbedObj(pJSObject), m_pApp(nullptr) {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -070053
Tom Sepez7dc5cc12015-08-17 12:15:26 -070054JSGlobalAlternate::~JSGlobalAlternate() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070055 DestroyGlobalPersisitentVariables();
Tom Sepezf4583622015-09-14 15:06:53 -070056 m_pGlobalData->Release();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070057}
58
Tom Sepez7dc5cc12015-08-17 12:15:26 -070059void JSGlobalAlternate::Initial(CPDFDoc_Environment* pApp) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070060 m_pApp = pApp;
Tom Sepezf4583622015-09-14 15:06:53 -070061 m_pGlobalData = CJS_GlobalData::GetRetainedInstance(pApp);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070062 UpdateGlobalPersistentVariables();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070063}
Tom Sepezbdeeb8a2015-05-27 12:25:00 -070064
Tom Sepez7dc5cc12015-08-17 12:15:26 -070065FX_BOOL JSGlobalAlternate::QueryProperty(const FX_WCHAR* propname) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070066 return CFX_WideString(propname) != L"setPersistent";
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070067}
68
Tom Sepezba038bc2015-10-08 12:03:00 -070069FX_BOOL JSGlobalAlternate::DelProperty(IJS_Context* cc,
Tom Sepez7dc5cc12015-08-17 12:15:26 -070070 const FX_WCHAR* propname,
71 CFX_WideString& sError) {
Tom Sepez09d33bc2015-08-19 09:49:24 -070072 auto it = m_mapGlobal.find(CFX_ByteString::FromUnicode(propname));
73 if (it == m_mapGlobal.end())
74 return FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070075
Tom Sepez09d33bc2015-08-19 09:49:24 -070076 it->second->bDeleted = TRUE;
77 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070078}
79
Tom Sepezba038bc2015-10-08 12:03:00 -070080FX_BOOL JSGlobalAlternate::DoProperty(IJS_Context* cc,
Tom Sepez7dc5cc12015-08-17 12:15:26 -070081 const FX_WCHAR* propname,
82 CJS_PropValue& vp,
83 CFX_WideString& sError) {
tsepezf3dc8c62016-08-10 06:29:29 -070084 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070085 if (vp.IsSetting()) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -070086 CFX_ByteString sPropName = CFX_ByteString::FromUnicode(propname);
tsepezf3dc8c62016-08-10 06:29:29 -070087 switch (vp.GetJSValue()->GetType()) {
Tom Sepez39bfe122015-09-17 15:25:23 -070088 case CJS_Value::VT_number: {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070089 double dData;
90 vp >> dData;
weili47228ac2016-07-20 10:35:31 -070091 return SetGlobalVariables(sPropName, JS_GlobalDataType::NUMBER, dData,
Nico Weber9d8ec5a2015-08-04 13:00:21 -070092 false, "", v8::Local<v8::Object>(), FALSE);
93 }
Tom Sepez39bfe122015-09-17 15:25:23 -070094 case CJS_Value::VT_boolean: {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070095 bool bData;
96 vp >> bData;
weili47228ac2016-07-20 10:35:31 -070097 return SetGlobalVariables(sPropName, JS_GlobalDataType::BOOLEAN, 0,
Nico Weber9d8ec5a2015-08-04 13:00:21 -070098 bData, "", v8::Local<v8::Object>(), FALSE);
99 }
Tom Sepez39bfe122015-09-17 15:25:23 -0700100 case CJS_Value::VT_string: {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700101 CFX_ByteString sData;
102 vp >> sData;
weili47228ac2016-07-20 10:35:31 -0700103 return SetGlobalVariables(sPropName, JS_GlobalDataType::STRING, 0,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700104 false, sData, v8::Local<v8::Object>(), FALSE);
105 }
Tom Sepez39bfe122015-09-17 15:25:23 -0700106 case CJS_Value::VT_object: {
Tom Sepez808a99e2015-09-10 12:28:37 -0700107 v8::Local<v8::Object> pData;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700108 vp >> pData;
weili47228ac2016-07-20 10:35:31 -0700109 return SetGlobalVariables(sPropName, JS_GlobalDataType::OBJECT, 0,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700110 false, "", pData, FALSE);
111 }
Tom Sepez39bfe122015-09-17 15:25:23 -0700112 case CJS_Value::VT_null: {
weili47228ac2016-07-20 10:35:31 -0700113 return SetGlobalVariables(sPropName, JS_GlobalDataType::NULLOBJ, 0,
114 false, "", v8::Local<v8::Object>(), FALSE);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700115 }
Tom Sepez39bfe122015-09-17 15:25:23 -0700116 case CJS_Value::VT_undefined: {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700117 DelProperty(cc, propname, sError);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700118 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700119 }
120 default:
121 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700122 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700123 } else {
Tom Sepez09d33bc2015-08-19 09:49:24 -0700124 auto it = m_mapGlobal.find(CFX_ByteString::FromUnicode(propname));
125 if (it == m_mapGlobal.end()) {
tsepezf3dc8c62016-08-10 06:29:29 -0700126 vp.GetJSValue()->SetNull(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700127 return TRUE;
128 }
Tom Sepez09d33bc2015-08-19 09:49:24 -0700129 JSGlobalData* pData = it->second;
130 if (pData->bDeleted) {
tsepezf3dc8c62016-08-10 06:29:29 -0700131 vp.GetJSValue()->SetNull(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700132 return TRUE;
133 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700134 switch (pData->nType) {
weili47228ac2016-07-20 10:35:31 -0700135 case JS_GlobalDataType::NUMBER:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700136 vp << pData->dData;
137 return TRUE;
weili47228ac2016-07-20 10:35:31 -0700138 case JS_GlobalDataType::BOOLEAN:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700139 vp << pData->bData;
140 return TRUE;
weili47228ac2016-07-20 10:35:31 -0700141 case JS_GlobalDataType::STRING:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700142 vp << pData->sData;
143 return TRUE;
weili47228ac2016-07-20 10:35:31 -0700144 case JS_GlobalDataType::OBJECT: {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700145 v8::Local<v8::Object> obj = v8::Local<v8::Object>::New(
146 vp.GetJSRuntime()->GetIsolate(), pData->pData);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700147 vp << obj;
148 return TRUE;
149 }
weili47228ac2016-07-20 10:35:31 -0700150 case JS_GlobalDataType::NULLOBJ:
tsepezf3dc8c62016-08-10 06:29:29 -0700151 vp.GetJSValue()->SetNull(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700152 return TRUE;
153 default:
154 break;
155 }
156 }
157 return FALSE;
158}
159
Tom Sepezba038bc2015-10-08 12:03:00 -0700160FX_BOOL JSGlobalAlternate::setPersistent(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -0800161 const std::vector<CJS_Value>& params,
Tom Sepez7dc5cc12015-08-17 12:15:26 -0700162 CJS_Value& vRet,
163 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700164 CJS_Context* pContext = static_cast<CJS_Context*>(cc);
tsepezf3dc8c62016-08-10 06:29:29 -0700165 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700166 if (params.size() != 2) {
167 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700168 return FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700169 }
170
tsepezf3dc8c62016-08-10 06:29:29 -0700171 auto it = m_mapGlobal.find(params[0].ToCFXByteString(pRuntime->GetIsolate()));
Tom Sepez09d33bc2015-08-19 09:49:24 -0700172 if (it != m_mapGlobal.end()) {
173 JSGlobalData* pData = it->second;
174 if (!pData->bDeleted) {
tsepezf3dc8c62016-08-10 06:29:29 -0700175 pData->bPersistent = params[1].ToBool(pRuntime->GetIsolate());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700176 return TRUE;
177 }
178 }
179
180 sError = JSGetStringFromID(pContext, IDS_STRING_JSNOGLOBAL);
181 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700182}
183
Tom Sepez7dc5cc12015-08-17 12:15:26 -0700184void JSGlobalAlternate::UpdateGlobalPersistentVariables() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700185 for (int i = 0, sz = m_pGlobalData->GetSize(); i < sz; i++) {
186 CJS_GlobalData_Element* pData = m_pGlobalData->GetAt(i);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700187 switch (pData->data.nType) {
weili47228ac2016-07-20 10:35:31 -0700188 case JS_GlobalDataType::NUMBER:
189 SetGlobalVariables(pData->data.sKey, JS_GlobalDataType::NUMBER,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700190 pData->data.dData, false, "",
191 v8::Local<v8::Object>(), pData->bPersistent == 1);
thestig1cd352e2016-06-07 17:53:06 -0700192 FXJS_PutObjectNumber(nullptr, m_pJSObject->ToV8Object(),
tsepez018935c2016-04-15 13:15:12 -0700193 pData->data.sKey.UTF8Decode(), pData->data.dData);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700194 break;
weili47228ac2016-07-20 10:35:31 -0700195 case JS_GlobalDataType::BOOLEAN:
196 SetGlobalVariables(pData->data.sKey, JS_GlobalDataType::BOOLEAN, 0,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700197 (bool)(pData->data.bData == 1), "",
198 v8::Local<v8::Object>(), pData->bPersistent == 1);
thestig1cd352e2016-06-07 17:53:06 -0700199 FXJS_PutObjectBoolean(nullptr, m_pJSObject->ToV8Object(),
tsepez018935c2016-04-15 13:15:12 -0700200 pData->data.sKey.UTF8Decode(),
Tom Sepez39bfe122015-09-17 15:25:23 -0700201 (bool)(pData->data.bData == 1));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700202 break;
weili47228ac2016-07-20 10:35:31 -0700203 case JS_GlobalDataType::STRING:
204 SetGlobalVariables(pData->data.sKey, JS_GlobalDataType::STRING, 0,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700205 false, pData->data.sData, v8::Local<v8::Object>(),
206 pData->bPersistent == 1);
thestig1cd352e2016-06-07 17:53:06 -0700207 FXJS_PutObjectString(nullptr, m_pJSObject->ToV8Object(),
tsepez018935c2016-04-15 13:15:12 -0700208 pData->data.sKey.UTF8Decode(),
209 pData->data.sData.UTF8Decode());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700210 break;
weili47228ac2016-07-20 10:35:31 -0700211 case JS_GlobalDataType::OBJECT: {
Tom Sepez371379d2015-11-06 08:29:39 -0800212 v8::Isolate* pRuntime = m_pJSObject->ToV8Object()->GetIsolate();
thestig1cd352e2016-06-07 17:53:06 -0700213 v8::Local<v8::Object> pObj =
214 FXJS_NewFxDynamicObj(pRuntime, nullptr, -1);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700215
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700216 PutObjectProperty(pObj, &pData->data);
217
weili47228ac2016-07-20 10:35:31 -0700218 SetGlobalVariables(pData->data.sKey, JS_GlobalDataType::OBJECT, 0,
Tom Sepez116e4ad2015-09-21 09:22:05 -0700219 false, "", pObj, pData->bPersistent == 1);
thestig1cd352e2016-06-07 17:53:06 -0700220 FXJS_PutObjectObject(nullptr, m_pJSObject->ToV8Object(),
tsepez018935c2016-04-15 13:15:12 -0700221 pData->data.sKey.UTF8Decode(), pObj);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700222 } break;
weili47228ac2016-07-20 10:35:31 -0700223 case JS_GlobalDataType::NULLOBJ:
224 SetGlobalVariables(pData->data.sKey, JS_GlobalDataType::NULLOBJ, 0,
225 false, "", v8::Local<v8::Object>(),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700226 pData->bPersistent == 1);
thestig1cd352e2016-06-07 17:53:06 -0700227 FXJS_PutObjectNull(nullptr, m_pJSObject->ToV8Object(),
tsepez018935c2016-04-15 13:15:12 -0700228 pData->data.sKey.UTF8Decode());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700229 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700230 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700231 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700232}
233
Tom Sepez67fd5df2015-10-08 12:24:19 -0700234void JSGlobalAlternate::CommitGlobalPersisitentVariables(IJS_Context* cc) {
Tom Sepez09d33bc2015-08-19 09:49:24 -0700235 for (auto it = m_mapGlobal.begin(); it != m_mapGlobal.end(); ++it) {
236 CFX_ByteString name = it->first;
237 JSGlobalData* pData = it->second;
238 if (pData->bDeleted) {
239 m_pGlobalData->DeleteGlobalVariable(name);
240 } else {
241 switch (pData->nType) {
weili47228ac2016-07-20 10:35:31 -0700242 case JS_GlobalDataType::NUMBER:
Tom Sepez09d33bc2015-08-19 09:49:24 -0700243 m_pGlobalData->SetGlobalVariableNumber(name, pData->dData);
244 m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
245 break;
weili47228ac2016-07-20 10:35:31 -0700246 case JS_GlobalDataType::BOOLEAN:
Tom Sepez09d33bc2015-08-19 09:49:24 -0700247 m_pGlobalData->SetGlobalVariableBoolean(name, pData->bData);
248 m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
249 break;
weili47228ac2016-07-20 10:35:31 -0700250 case JS_GlobalDataType::STRING:
Tom Sepez09d33bc2015-08-19 09:49:24 -0700251 m_pGlobalData->SetGlobalVariableString(name, pData->sData);
252 m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
253 break;
weili47228ac2016-07-20 10:35:31 -0700254 case JS_GlobalDataType::OBJECT: {
Dan Sinclairf766ad22016-03-14 13:51:24 -0400255 CJS_GlobalVariableArray array;
256 v8::Local<v8::Object> obj = v8::Local<v8::Object>::New(
257 GetJSObject()->GetIsolate(), pData->pData);
258 ObjectToArray(cc, obj, array);
259 m_pGlobalData->SetGlobalVariableObject(name, array);
260 m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
261 } break;
weili47228ac2016-07-20 10:35:31 -0700262 case JS_GlobalDataType::NULLOBJ:
Tom Sepez09d33bc2015-08-19 09:49:24 -0700263 m_pGlobalData->SetGlobalVariableNull(name);
264 m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
265 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700266 }
267 }
268 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700269}
270
Tom Sepez67fd5df2015-10-08 12:24:19 -0700271void JSGlobalAlternate::ObjectToArray(IJS_Context* cc,
272 v8::Local<v8::Object> pObj,
Tom Sepez7dc5cc12015-08-17 12:15:26 -0700273 CJS_GlobalVariableArray& array) {
Tom Sepez371379d2015-11-06 08:29:39 -0800274 v8::Isolate* isolate = pObj->GetIsolate();
Tom Sepez67fd5df2015-10-08 12:24:19 -0700275 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
Tom Sepez39bfe122015-09-17 15:25:23 -0700276 v8::Local<v8::Array> pKeyList = FXJS_GetObjectElementNames(isolate, pObj);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700277 int nObjElements = pKeyList->Length();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700278 for (int i = 0; i < nObjElements; i++) {
279 CFX_WideString ws =
Tom Sepez39bfe122015-09-17 15:25:23 -0700280 FXJS_ToString(isolate, FXJS_GetArrayElement(isolate, pKeyList, i));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700281 CFX_ByteString sKey = ws.UTF8Encode();
tsepez018935c2016-04-15 13:15:12 -0700282 v8::Local<v8::Value> v = FXJS_GetObjectElement(isolate, pObj, ws);
tsepez40faa792016-07-15 17:58:02 -0700283 switch (CJS_Value::GetValueType(v)) {
Tom Sepez39bfe122015-09-17 15:25:23 -0700284 case CJS_Value::VT_number: {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700285 CJS_KeyValue* pObjElement = new CJS_KeyValue;
weili47228ac2016-07-20 10:35:31 -0700286 pObjElement->nType = JS_GlobalDataType::NUMBER;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700287 pObjElement->sKey = sKey;
Tom Sepez39bfe122015-09-17 15:25:23 -0700288 pObjElement->dData = FXJS_ToNumber(isolate, v);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700289 array.Add(pObjElement);
290 } break;
Tom Sepez39bfe122015-09-17 15:25:23 -0700291 case CJS_Value::VT_boolean: {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700292 CJS_KeyValue* pObjElement = new CJS_KeyValue;
weili47228ac2016-07-20 10:35:31 -0700293 pObjElement->nType = JS_GlobalDataType::BOOLEAN;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700294 pObjElement->sKey = sKey;
Tom Sepez39bfe122015-09-17 15:25:23 -0700295 pObjElement->dData = FXJS_ToBoolean(isolate, v);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700296 array.Add(pObjElement);
297 } break;
Tom Sepez39bfe122015-09-17 15:25:23 -0700298 case CJS_Value::VT_string: {
tsepezf3dc8c62016-08-10 06:29:29 -0700299 CFX_ByteString sValue =
300 CJS_Value(pRuntime, v).ToCFXByteString(pRuntime->GetIsolate());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700301 CJS_KeyValue* pObjElement = new CJS_KeyValue;
weili47228ac2016-07-20 10:35:31 -0700302 pObjElement->nType = JS_GlobalDataType::STRING;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700303 pObjElement->sKey = sKey;
304 pObjElement->sData = sValue;
305 array.Add(pObjElement);
306 } break;
Tom Sepez39bfe122015-09-17 15:25:23 -0700307 case CJS_Value::VT_object: {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700308 CJS_KeyValue* pObjElement = new CJS_KeyValue;
weili47228ac2016-07-20 10:35:31 -0700309 pObjElement->nType = JS_GlobalDataType::OBJECT;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700310 pObjElement->sKey = sKey;
Tom Sepez67fd5df2015-10-08 12:24:19 -0700311 ObjectToArray(cc, FXJS_ToObject(isolate, v), pObjElement->objData);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700312 array.Add(pObjElement);
313 } break;
Tom Sepez39bfe122015-09-17 15:25:23 -0700314 case CJS_Value::VT_null: {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700315 CJS_KeyValue* pObjElement = new CJS_KeyValue;
weili47228ac2016-07-20 10:35:31 -0700316 pObjElement->nType = JS_GlobalDataType::NULLOBJ;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700317 pObjElement->sKey = sKey;
318 array.Add(pObjElement);
319 } break;
320 default:
321 break;
322 }
323 }
324}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700325
Tom Sepez7dc5cc12015-08-17 12:15:26 -0700326void JSGlobalAlternate::PutObjectProperty(v8::Local<v8::Object> pObj,
327 CJS_KeyValue* pData) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700328 for (int i = 0, sz = pData->objData.Count(); i < sz; i++) {
329 CJS_KeyValue* pObjData = pData->objData.GetAt(i);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700330 switch (pObjData->nType) {
weili47228ac2016-07-20 10:35:31 -0700331 case JS_GlobalDataType::NUMBER:
thestig1cd352e2016-06-07 17:53:06 -0700332 FXJS_PutObjectNumber(nullptr, pObj, pObjData->sKey.UTF8Decode(),
Tom Sepez39bfe122015-09-17 15:25:23 -0700333 pObjData->dData);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700334 break;
weili47228ac2016-07-20 10:35:31 -0700335 case JS_GlobalDataType::BOOLEAN:
thestig1cd352e2016-06-07 17:53:06 -0700336 FXJS_PutObjectBoolean(nullptr, pObj, pObjData->sKey.UTF8Decode(),
Tom Sepez116e4ad2015-09-21 09:22:05 -0700337 pObjData->bData == 1);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700338 break;
weili47228ac2016-07-20 10:35:31 -0700339 case JS_GlobalDataType::STRING:
thestig1cd352e2016-06-07 17:53:06 -0700340 FXJS_PutObjectString(nullptr, pObj, pObjData->sKey.UTF8Decode(),
tsepez018935c2016-04-15 13:15:12 -0700341 pObjData->sData.UTF8Decode());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700342 break;
weili47228ac2016-07-20 10:35:31 -0700343 case JS_GlobalDataType::OBJECT: {
Tom Sepez371379d2015-11-06 08:29:39 -0800344 v8::Isolate* pRuntime = m_pJSObject->ToV8Object()->GetIsolate();
Tom Sepez39bfe122015-09-17 15:25:23 -0700345 v8::Local<v8::Object> pNewObj =
thestig1cd352e2016-06-07 17:53:06 -0700346 FXJS_NewFxDynamicObj(pRuntime, nullptr, -1);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700347 PutObjectProperty(pNewObj, pObjData);
thestig1cd352e2016-06-07 17:53:06 -0700348 FXJS_PutObjectObject(nullptr, pObj, pObjData->sKey.UTF8Decode(),
349 pNewObj);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700350 } break;
weili47228ac2016-07-20 10:35:31 -0700351 case JS_GlobalDataType::NULLOBJ:
thestig1cd352e2016-06-07 17:53:06 -0700352 FXJS_PutObjectNull(nullptr, pObj, pObjData->sKey.UTF8Decode());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700353 break;
354 }
355 }
356}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700357
Tom Sepez7dc5cc12015-08-17 12:15:26 -0700358void JSGlobalAlternate::DestroyGlobalPersisitentVariables() {
Tom Sepez09d33bc2015-08-19 09:49:24 -0700359 for (const auto& pair : m_mapGlobal) {
360 delete pair.second;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700361 }
Tom Sepez09d33bc2015-08-19 09:49:24 -0700362 m_mapGlobal.clear();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700363}
364
tsepez24a48882016-04-11 15:18:40 -0700365FX_BOOL JSGlobalAlternate::SetGlobalVariables(const CFX_ByteString& propname,
weili47228ac2016-07-20 10:35:31 -0700366 JS_GlobalDataType nType,
Tom Sepez7dc5cc12015-08-17 12:15:26 -0700367 double dData,
368 bool bData,
369 const CFX_ByteString& sData,
Tom Sepez808a99e2015-09-10 12:28:37 -0700370 v8::Local<v8::Object> pData,
Tom Sepez7dc5cc12015-08-17 12:15:26 -0700371 bool bDefaultPersistent) {
tsepezb4c9f3f2016-04-13 15:41:21 -0700372 if (propname.IsEmpty())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700373 return FALSE;
374
Tom Sepez09d33bc2015-08-19 09:49:24 -0700375 auto it = m_mapGlobal.find(propname);
376 if (it != m_mapGlobal.end()) {
377 JSGlobalData* pTemp = it->second;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700378 if (pTemp->bDeleted || pTemp->nType != nType) {
379 pTemp->dData = 0;
380 pTemp->bData = 0;
381 pTemp->sData = "";
382 pTemp->nType = nType;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700383 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700384
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700385 pTemp->bDeleted = FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700386 switch (nType) {
weili47228ac2016-07-20 10:35:31 -0700387 case JS_GlobalDataType::NUMBER: {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700388 pTemp->dData = dData;
389 } break;
weili47228ac2016-07-20 10:35:31 -0700390 case JS_GlobalDataType::BOOLEAN: {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700391 pTemp->bData = bData;
392 } break;
weili47228ac2016-07-20 10:35:31 -0700393 case JS_GlobalDataType::STRING: {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700394 pTemp->sData = sData;
395 } break;
weili47228ac2016-07-20 10:35:31 -0700396 case JS_GlobalDataType::OBJECT: {
Tom Sepez371379d2015-11-06 08:29:39 -0800397 pTemp->pData.Reset(pData->GetIsolate(), pData);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700398 } break;
weili47228ac2016-07-20 10:35:31 -0700399 case JS_GlobalDataType::NULLOBJ:
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700400 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700401 default:
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700402 return FALSE;
403 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700404 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700405 }
406
thestig1cd352e2016-06-07 17:53:06 -0700407 JSGlobalData* pNewData = nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700408
409 switch (nType) {
weili47228ac2016-07-20 10:35:31 -0700410 case JS_GlobalDataType::NUMBER: {
Tom Sepez7dc5cc12015-08-17 12:15:26 -0700411 pNewData = new JSGlobalData;
weili47228ac2016-07-20 10:35:31 -0700412 pNewData->nType = JS_GlobalDataType::NUMBER;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700413 pNewData->dData = dData;
414 pNewData->bPersistent = bDefaultPersistent;
415 } break;
weili47228ac2016-07-20 10:35:31 -0700416 case JS_GlobalDataType::BOOLEAN: {
Tom Sepez7dc5cc12015-08-17 12:15:26 -0700417 pNewData = new JSGlobalData;
weili47228ac2016-07-20 10:35:31 -0700418 pNewData->nType = JS_GlobalDataType::BOOLEAN;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700419 pNewData->bData = bData;
420 pNewData->bPersistent = bDefaultPersistent;
421 } break;
weili47228ac2016-07-20 10:35:31 -0700422 case JS_GlobalDataType::STRING: {
Tom Sepez7dc5cc12015-08-17 12:15:26 -0700423 pNewData = new JSGlobalData;
weili47228ac2016-07-20 10:35:31 -0700424 pNewData->nType = JS_GlobalDataType::STRING;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700425 pNewData->sData = sData;
426 pNewData->bPersistent = bDefaultPersistent;
427 } break;
weili47228ac2016-07-20 10:35:31 -0700428 case JS_GlobalDataType::OBJECT: {
Tom Sepez7dc5cc12015-08-17 12:15:26 -0700429 pNewData = new JSGlobalData;
weili47228ac2016-07-20 10:35:31 -0700430 pNewData->nType = JS_GlobalDataType::OBJECT;
Tom Sepez371379d2015-11-06 08:29:39 -0800431 pNewData->pData.Reset(pData->GetIsolate(), pData);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700432 pNewData->bPersistent = bDefaultPersistent;
433 } break;
weili47228ac2016-07-20 10:35:31 -0700434 case JS_GlobalDataType::NULLOBJ: {
Tom Sepez7dc5cc12015-08-17 12:15:26 -0700435 pNewData = new JSGlobalData;
weili47228ac2016-07-20 10:35:31 -0700436 pNewData->nType = JS_GlobalDataType::NULLOBJ;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700437 pNewData->bPersistent = bDefaultPersistent;
438 } break;
439 default:
440 return FALSE;
441 }
442
Tom Sepez09d33bc2015-08-19 09:49:24 -0700443 m_mapGlobal[propname] = pNewData;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700444 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700445}