Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1151)

Side by Side Diff: fpdfsdk/javascript/JS_Runtime.cpp

Issue 1847583004: Move the fpdfsdk/include/javascript folder (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « fpdfsdk/javascript/JS_Runtime.h ('k') | fpdfsdk/javascript/JS_Runtime_Stub.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // 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
7 #include "fpdfsdk/javascript/JS_Runtime.h"
8
9 #include <algorithm>
10
11 #include "fpdfsdk/include/fsdk_mgr.h" // For CPDFDoc_Environment.
12 #include "fpdfsdk/include/javascript/IJavaScript.h"
13 #include "fpdfsdk/javascript/Consts.h"
14 #include "fpdfsdk/javascript/Document.h"
15 #include "fpdfsdk/javascript/Field.h"
16 #include "fpdfsdk/javascript/Icon.h"
17 #include "fpdfsdk/javascript/JS_Context.h"
18 #include "fpdfsdk/javascript/JS_Define.h"
19 #include "fpdfsdk/javascript/JS_EventHandler.h"
20 #include "fpdfsdk/javascript/JS_GlobalData.h"
21 #include "fpdfsdk/javascript/JS_Object.h"
22 #include "fpdfsdk/javascript/JS_Value.h"
23 #include "fpdfsdk/javascript/PublicMethods.h"
24 #include "fpdfsdk/javascript/app.h"
25 #include "fpdfsdk/javascript/color.h"
26 #include "fpdfsdk/javascript/console.h"
27 #include "fpdfsdk/javascript/event.h"
28 #include "fpdfsdk/javascript/global.h"
29 #include "fpdfsdk/javascript/report.h"
30 #include "fpdfsdk/javascript/util.h"
31 #include "third_party/base/stl_util.h"
32
33 #ifdef PDF_ENABLE_XFA
34 #include "fpdfsdk/include/fpdfxfa/fpdfxfa_app.h"
35 #include "xfa/fxjse/value.h"
36 #endif // PDF_ENABLE_XFA
37
38 // static
39 void IJS_Runtime::Initialize(unsigned int slot, void* isolate) {
40 FXJS_Initialize(slot, reinterpret_cast<v8::Isolate*>(isolate));
41 }
42
43 // static
44 IJS_Runtime* IJS_Runtime::Create(CPDFDoc_Environment* pEnv) {
45 return new CJS_Runtime(pEnv);
46 }
47
48 // static
49 CJS_Runtime* CJS_Runtime::FromContext(const IJS_Context* cc) {
50 const CJS_Context* pContext = static_cast<const CJS_Context*>(cc);
51 return pContext->GetJSRuntime();
52 }
53
54 CJS_Runtime::CJS_Runtime(CPDFDoc_Environment* pApp)
55 : m_pApp(pApp),
56 m_pDocument(NULL),
57 m_bBlocking(FALSE),
58 m_isolate(NULL),
59 m_isolateManaged(false) {
60 #ifndef PDF_ENABLE_XFA
61 IPDF_JSPLATFORM* pPlatform = m_pApp->GetFormFillInfo()->m_pJsPlatform;
62 if (pPlatform->version <= 2) {
63 unsigned int embedderDataSlot = 0;
64 v8::Isolate* pExternalIsolate = nullptr;
65 if (pPlatform->version == 2) {
66 pExternalIsolate = reinterpret_cast<v8::Isolate*>(pPlatform->m_isolate);
67 embedderDataSlot = pPlatform->m_v8EmbedderSlot;
68 #else
69 if (CPDFXFA_App::GetInstance()->GetJSERuntime()) {
70 // TODO(tsepez): CPDFXFA_App should also use the embedder provided isolate.
71 m_isolate = (v8::Isolate*)CPDFXFA_App::GetInstance()->GetJSERuntime();
72 } else {
73 IPDF_JSPLATFORM* pPlatform = m_pApp->GetFormFillInfo()->m_pJsPlatform;
74 if (pPlatform->version <= 2) {
75 unsigned int embedderDataSlot = 0;
76 v8::Isolate* pExternalIsolate = nullptr;
77 if (pPlatform->version == 2) {
78 pExternalIsolate = reinterpret_cast<v8::Isolate*>(pPlatform->m_isolate);
79 embedderDataSlot = pPlatform->m_v8EmbedderSlot;
80 }
81 FXJS_Initialize(embedderDataSlot, pExternalIsolate);
82 #endif
83 }
84 #ifndef PDF_ENABLE_XFA
85 FXJS_Initialize(embedderDataSlot, pExternalIsolate);
86 #else
87 m_isolateManaged = FXJS_GetIsolate(&m_isolate);
88 }
89
90 v8::Isolate* isolate = m_isolate;
91 v8::Isolate::Scope isolate_scope(isolate);
92 v8::Locker locker(isolate);
93 v8::HandleScope handle_scope(isolate);
94 if (CPDFXFA_App::GetInstance()->IsJavaScriptInitialized()) {
95 CJS_Context* pContext = (CJS_Context*)NewContext();
96 FXJS_InitializeRuntime(GetIsolate(), this, &m_context, &m_StaticObjects);
97 ReleaseContext(pContext);
98 return;
99 #endif
100 }
101 #ifndef PDF_ENABLE_XFA
102 m_isolateManaged = FXJS_GetIsolate(&m_isolate);
103 #else
104
105 #endif
106 if (m_isolateManaged || FXJS_GlobalIsolateRefCount() == 0)
107 DefineJSObjects();
108
109 #ifdef PDF_ENABLE_XFA
110 CPDFXFA_App::GetInstance()->SetJavaScriptInitialized(TRUE);
111
112 #endif
113 CJS_Context* pContext = (CJS_Context*)NewContext();
114 FXJS_InitializeRuntime(GetIsolate(), this, &m_context, &m_StaticObjects);
115 ReleaseContext(pContext);
116 }
117
118 CJS_Runtime::~CJS_Runtime() {
119 for (auto* obs : m_observers)
120 obs->OnDestroyed();
121
122 m_ContextArray.clear();
123 m_ConstArrays.clear();
124 FXJS_ReleaseRuntime(GetIsolate(), &m_context, &m_StaticObjects);
125 m_context.Reset();
126 if (m_isolateManaged)
127 m_isolate->Dispose();
128 }
129
130 void CJS_Runtime::DefineJSObjects() {
131 v8::Isolate::Scope isolate_scope(GetIsolate());
132 #ifdef PDF_ENABLE_XFA
133 v8::Locker locker(GetIsolate());
134 #endif
135 v8::HandleScope handle_scope(GetIsolate());
136 v8::Local<v8::Context> context = v8::Context::New(GetIsolate());
137 v8::Context::Scope context_scope(context);
138
139 // The call order determines the "ObjDefID" assigned to each class.
140 // ObjDefIDs 0 - 2
141 CJS_Border::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_STATIC);
142 CJS_Display::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_STATIC);
143 CJS_Font::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_STATIC);
144
145 // ObjDefIDs 3 - 5
146 CJS_Highlight::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_STATIC);
147 CJS_Position::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_STATIC);
148 CJS_ScaleHow::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_STATIC);
149
150 // ObjDefIDs 6 - 8
151 CJS_ScaleWhen::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_STATIC);
152 CJS_Style::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_STATIC);
153 CJS_Zoomtype::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_STATIC);
154
155 // ObjDefIDs 9 - 11
156 CJS_App::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_STATIC);
157 CJS_Color::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_STATIC);
158 CJS_Console::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_STATIC);
159
160 // ObjDefIDs 12 - 14
161 CJS_Document::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_GLOBAL);
162 CJS_Event::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_STATIC);
163 CJS_Field::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_DYNAMIC);
164
165 // ObjDefIDs 15 - 17
166 CJS_Global::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_STATIC);
167 CJS_Icon::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_DYNAMIC);
168 CJS_Util::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_STATIC);
169
170 // ObjDefIDs 18 - 20 (these can't fail, return void).
171 CJS_PublicMethods::DefineJSObjects(GetIsolate());
172 CJS_GlobalConsts::DefineJSObjects(this);
173 CJS_GlobalArrays::DefineJSObjects(this);
174
175 // ObjDefIDs 21 - 22.
176 CJS_TimerObj::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_DYNAMIC);
177 CJS_PrintParamsObj::DefineJSObjects(GetIsolate(), FXJSOBJTYPE_DYNAMIC);
178 }
179
180 IJS_Context* CJS_Runtime::NewContext() {
181 m_ContextArray.push_back(std::unique_ptr<CJS_Context>(new CJS_Context(this)));
182 return m_ContextArray.back().get();
183 }
184
185 void CJS_Runtime::ReleaseContext(IJS_Context* pContext) {
186 for (auto it = m_ContextArray.begin(); it != m_ContextArray.end(); ++it) {
187 if (it->get() == static_cast<CJS_Context*>(pContext)) {
188 m_ContextArray.erase(it);
189 return;
190 }
191 }
192 }
193
194 IJS_Context* CJS_Runtime::GetCurrentContext() {
195 return m_ContextArray.empty() ? nullptr : m_ContextArray.back().get();
196 }
197
198 void CJS_Runtime::SetReaderDocument(CPDFSDK_Document* pReaderDoc) {
199 if (m_pDocument != pReaderDoc) {
200 v8::Isolate::Scope isolate_scope(m_isolate);
201 #ifdef PDF_ENABLE_XFA
202 v8::Locker locker(m_isolate);
203 #endif
204 v8::HandleScope handle_scope(m_isolate);
205 v8::Local<v8::Context> context =
206 v8::Local<v8::Context>::New(m_isolate, m_context);
207 v8::Context::Scope context_scope(context);
208
209 m_pDocument = pReaderDoc;
210 if (pReaderDoc) {
211 v8::Local<v8::Object> pThis = FXJS_GetThisObj(GetIsolate());
212 if (!pThis.IsEmpty()) {
213 if (FXJS_GetObjDefnID(pThis) == CJS_Document::g_nObjDefnID) {
214 if (CJS_Document* pJSDocument =
215 (CJS_Document*)FXJS_GetPrivate(GetIsolate(), pThis)) {
216 if (Document* pDocument = (Document*)pJSDocument->GetEmbedObject())
217 pDocument->AttachDoc(pReaderDoc);
218 }
219 }
220 }
221 }
222 }
223 }
224
225 int CJS_Runtime::Execute(IJS_Context* cc,
226 const wchar_t* script,
227 CFX_WideString* info) {
228 FXJSErr error = {};
229 int nRet = FXJS_Execute(m_isolate, cc, script, &error);
230 if (nRet < 0) {
231 info->Format(L"[ Line: %05d { %s } ] : %s", error.linnum - 1, error.srcline,
232 error.message);
233 }
234 return nRet;
235 }
236
237 bool CJS_Runtime::AddEventToSet(const FieldEvent& event) {
238 return m_FieldEventSet.insert(event).second;
239 }
240
241 void CJS_Runtime::RemoveEventFromSet(const FieldEvent& event) {
242 m_FieldEventSet.erase(event);
243 }
244
245 v8::Local<v8::Context> CJS_Runtime::NewJSContext() {
246 return v8::Local<v8::Context>::New(m_isolate, m_context);
247 }
248
249 void CJS_Runtime::SetConstArray(const CFX_WideString& name,
250 v8::Local<v8::Array> array) {
251 m_ConstArrays[name] = v8::Global<v8::Array>(m_isolate, array);
252 }
253
254 v8::Local<v8::Array> CJS_Runtime::GetConstArray(const CFX_WideString& name) {
255 return v8::Local<v8::Array>::New(m_isolate, m_ConstArrays[name]);
256 }
257
258 #ifdef PDF_ENABLE_XFA
259 CFX_WideString ChangeObjName(const CFX_WideString& str) {
260 CFX_WideString sRet = str;
261 sRet.Replace(L"_", L".");
262 return sRet;
263 }
264 FX_BOOL CJS_Runtime::GetHValueByName(const CFX_ByteStringC& utf8Name,
265 FXJSE_HVALUE hValue) {
266 #ifdef PDF_ENABLE_XFA
267 const FX_CHAR* name = utf8Name.GetCStr();
268
269 v8::Locker lock(GetIsolate());
270 v8::Isolate::Scope isolate_scope(GetIsolate());
271 v8::HandleScope handle_scope(GetIsolate());
272 v8::Local<v8::Context> old_context = GetIsolate()->GetCurrentContext();
273 v8::Local<v8::Context> context =
274 v8::Local<v8::Context>::New(GetIsolate(), m_context);
275 v8::Context::Scope context_scope(context);
276
277 // Caution: We're about to hand to XFA an object that in order to invoke
278 // methods will require that the current v8::Context always has a pointer
279 // to a CJS_Runtime in its embedder data slot. Unfortunately, XFA creates
280 // its own v8::Context which has not initialized the embedder data slot.
281 // Do so now.
282 // TODO(tsepez): redesign PDF-side objects to not rely on v8::Context's
283 // embedder data slots, and/or to always use the right context.
284 FXJS_SetRuntimeForV8Context(old_context, this);
285
286 v8::Local<v8::Value> propvalue =
287 context->Global()->Get(v8::String::NewFromUtf8(
288 GetIsolate(), name, v8::String::kNormalString, utf8Name.GetLength()));
289
290 if (propvalue.IsEmpty()) {
291 FXJSE_Value_SetUndefined(hValue);
292 return FALSE;
293 }
294 ((CFXJSE_Value*)hValue)->ForceSetValue(propvalue);
295 #endif
296
297 return TRUE;
298 }
299 FX_BOOL CJS_Runtime::SetHValueByName(const CFX_ByteStringC& utf8Name,
300 FXJSE_HVALUE hValue) {
301 #ifdef PDF_ENABLE_XFA
302 if (utf8Name.IsEmpty() || hValue == NULL)
303 return FALSE;
304 const FX_CHAR* name = utf8Name.GetCStr();
305 v8::Isolate* pIsolate = GetIsolate();
306 v8::Locker lock(pIsolate);
307 v8::Isolate::Scope isolate_scope(pIsolate);
308 v8::HandleScope handle_scope(pIsolate);
309 v8::Local<v8::Context> context =
310 v8::Local<v8::Context>::New(pIsolate, m_context);
311 v8::Context::Scope context_scope(context);
312
313 // v8::Local<v8::Context> tmpCotext =
314 // v8::Local<v8::Context>::New(GetIsolate(), m_context);
315 v8::Local<v8::Value> propvalue = v8::Local<v8::Value>::New(
316 GetIsolate(), ((CFXJSE_Value*)hValue)->DirectGetValue());
317 context->Global()->Set(
318 v8::String::NewFromUtf8(pIsolate, name, v8::String::kNormalString,
319 utf8Name.GetLength()),
320 propvalue);
321 #endif
322 return TRUE;
323 }
324
325 #endif
326 void CJS_Runtime::AddObserver(Observer* observer) {
327 ASSERT(!pdfium::ContainsKey(m_observers, observer));
328 m_observers.insert(observer);
329 }
330
331 void CJS_Runtime::RemoveObserver(Observer* observer) {
332 ASSERT(pdfium::ContainsKey(m_observers, observer));
333 m_observers.erase(observer);
334 }
OLDNEW
« no previous file with comments | « fpdfsdk/javascript/JS_Runtime.h ('k') | fpdfsdk/javascript/JS_Runtime_Stub.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698