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.
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
7 #include "../../include/javascript/JavaScript.h"
8 #include "../../include/javascript/IJavaScript.h"
9 #include "../../include/javascript/JS_EventHandler.h"
10 #include "../../include/javascript/JS_Runtime.h"
11 #include "../../include/javascript/JS_Context.h"
12 #include "../../include/javascript/JS_Define.h"
13 #include "../../include/javascript/JS_Object.h"
14 #include "../../include/javascript/JS_Value.h"
15 #include "../../include/javascript/Document.h"
16 #include "../../include/javascript/app.h"
17 #include "../../include/javascript/color.h"
18 #include "../../include/javascript/Consts.h"
19 #include "../../include/javascript/Document.h"
20 #include "../../include/javascript/event.h"
21 #include "../../include/javascript/Field.h"
22 #include "../../include/javascript/Icon.h"
23 #include "../../include/javascript/PublicMethods.h"
24 #include "../../include/javascript/report.h"
25 #include "../../include/javascript/util.h"
26 #include "../../include/javascript/JS_GlobalData.h"
27 #include "../../include/javascript/global.h"
28 #include "../../include/javascript/console.h"
29 #include "../../include/fpdfxfa/fpdfxfa_app.h"
30 #ifndef FOXIT_CHROME_BUILD
31 #include "../../../fxjse/value.h"
33 #include "../../../xfa/src/fxjse/src/value.h"
36 #include <libplatform/libplatform.h>
38 CJS_RuntimeFactory::~CJS_RuntimeFactory()
42 IFXJS_Runtime* CJS_RuntimeFactory::NewJSRuntime(CPDFDoc_Environment* pApp)
47 m_platform = v8::platform::CreateDefaultPlatform();
48 v8::V8::InitializePlatform(m_platform);
53 return new CJS_Runtime(pApp);
55 void CJS_RuntimeFactory::AddRef()
57 //to do.Should be implemented as atom manipulation.
60 void CJS_RuntimeFactory::Release()
64 //to do.Should be implemented as atom manipulation.
69 v8::V8::ShutdownPlatform();
77 void CJS_RuntimeFactory::DeleteJSRuntime(IFXJS_Runtime* pRuntime)
80 delete (CJS_Runtime*)pRuntime;
83 CJS_GlobalData* CJS_RuntimeFactory::NewGlobalData(CPDFDoc_Environment* pApp)
92 m_nGlobalDataCount = 1;
93 m_pGlobalData = new CJS_GlobalData(pApp);
98 void CJS_RuntimeFactory::ReleaseGlobalData()
100 m_nGlobalDataCount--;
102 if (m_nGlobalDataCount <= 0)
104 delete m_pGlobalData;
105 m_pGlobalData = NULL;
109 /* ------------------------------ CJS_Runtime ------------------------------ */
110 extern v8::Persistent<v8::ObjectTemplate>& _getGlobalObjectTemplate(IJS_Runtime* pJSRuntime);
111 CJS_Runtime::CJS_Runtime(CPDFDoc_Environment* pApp) :
115 m_pFieldEventPath(NULL),
118 m_isolate = FPDFXFA_GetApp()->GetJSERuntime()?(v8::Isolate*)FPDFXFA_GetApp()->GetJSERuntime():v8::Isolate::New();
119 //m_isolate->Enter();
120 v8::Isolate* isolate = m_isolate;
121 v8::Isolate::Scope isolate_scope(isolate);
122 v8::Locker locker(isolate);
123 v8::HandleScope handle_scope(isolate);
124 if (FPDFXFA_GetApp()->InitRuntime(FALSE)) {
125 CJS_Context * pContext = (CJS_Context*)NewContext();
126 JS_InitialRuntime(*this, this, pContext, m_context);
127 ReleaseContext(pContext);
133 CJS_Context * pContext = (CJS_Context*)NewContext();
134 JS_InitialRuntime(*this, this, pContext, m_context);
135 ReleaseContext(pContext);
138 CJS_Runtime::~CJS_Runtime()
140 int size = m_ContextArray.GetSize();
141 for (int i=0;i < size; i++)
142 delete m_ContextArray.GetAt(i);
144 m_ContextArray.RemoveAll();
146 //JS_ReleaseRuntime(*this, m_context);
148 RemoveEventsInLoop(m_pFieldEventPath);
152 m_pFieldEventPath = NULL;
156 //m_isolate->Dispose();
160 FX_BOOL CJS_Runtime::InitJSObjects()
162 v8::Isolate::Scope isolate_scope(GetIsolate());
163 v8::Locker locker(GetIsolate());
164 v8::HandleScope handle_scope(GetIsolate());
165 v8::Handle<v8::Context> context = v8::Context::New(GetIsolate());
166 v8::Context::Scope context_scope(context);
168 if (CJS_Border::Init(*this, JS_STATIC) < 0) return FALSE;
169 if (CJS_Display::Init(*this, JS_STATIC) < 0) return FALSE;
170 if (CJS_Font::Init(*this, JS_STATIC) < 0) return FALSE;
171 if (CJS_Highlight::Init(*this, JS_STATIC) < 0) return FALSE;
172 if (CJS_Position::Init(*this, JS_STATIC) < 0) return FALSE;
173 if (CJS_ScaleHow::Init(*this, JS_STATIC) < 0) return FALSE;
174 if (CJS_ScaleWhen::Init(*this, JS_STATIC) < 0) return FALSE;
175 if (CJS_Style::Init(*this, JS_STATIC) < 0) return FALSE;
176 if (CJS_Zoomtype::Init(*this, JS_STATIC) < 0) return FALSE;
179 if (CJS_App::Init(*this, JS_STATIC) < 0) return FALSE;
180 if (CJS_Color::Init(*this, JS_STATIC) < 0) return FALSE;
181 if (CJS_Console::Init(*this, JS_STATIC) < 0) return FALSE;
184 if (CJS_Document::Init(*this, JS_DYNAMIC) < 0) return FALSE;
185 if (CJS_Event::Init(*this, JS_STATIC) < 0) return FALSE;
186 if (CJS_Field::Init(*this, JS_DYNAMIC) < 0) return FALSE;
189 if (CJS_Global::Init(*this, JS_STATIC) < 0) return FALSE;
190 if (CJS_Icon::Init(*this, JS_DYNAMIC) < 0) return FALSE;
191 if (CJS_Util::Init(*this, JS_STATIC) < 0) return FALSE;
193 if (CJS_PublicMethods::Init(*this) < 0) return FALSE;
194 if (CJS_GlobalConsts::Init(*this) < 0) return FALSE;
195 if (CJS_GlobalArrays::Init(*this) < 0) return FALSE;
197 if (CJS_TimerObj::Init(*this, JS_DYNAMIC) < 0) return FALSE;
198 if (CJS_PrintParamsObj::Init(*this, JS_DYNAMIC) <0) return FALSE;
203 IFXJS_Context* CJS_Runtime::NewContext()
205 CJS_Context * p = new CJS_Context(this);
206 m_ContextArray.Add(p);
210 void CJS_Runtime::ReleaseContext(IFXJS_Context * pContext)
212 CJS_Context* pJSContext = (CJS_Context*)pContext;
214 for (int i=0, sz=m_ContextArray.GetSize(); i<sz; i++)
216 if (pJSContext == m_ContextArray.GetAt(i))
219 m_ContextArray.RemoveAt(i);
225 IFXJS_Context* CJS_Runtime::GetCurrentContext()
227 if(!m_ContextArray.GetSize())
229 return m_ContextArray.GetAt(m_ContextArray.GetSize()-1);
232 void CJS_Runtime::SetReaderDocument(CPDFSDK_Document* pReaderDoc)
234 if (m_pDocument != pReaderDoc)
236 v8::Isolate::Scope isolate_scope(m_isolate);
237 v8::Locker locker(m_isolate);
238 v8::HandleScope handle_scope(m_isolate);
239 v8::Local<v8::Context> context =v8::Local<v8::Context>::New(m_isolate, m_context);
240 v8::Context::Scope context_scope(context);
242 m_pDocument = pReaderDoc;
246 JSObject pThis = JS_GetThisObj(*this);
249 if (JS_GetObjDefnID(pThis) == JS_GetObjDefnID(*this, L"Document"))
251 if (CJS_Document* pJSDocument = (CJS_Document*)JS_GetPrivate(pThis))
253 if (Document * pDocument = (Document*)pJSDocument->GetEmbedObject())
254 pDocument->AttachDoc(pReaderDoc);
258 JS_SetThisObj(*this, JS_GetObjDefnID(*this, L"Document"));
262 JS_SetThisObj(*this, JS_GetObjDefnID(*this, L"app"));
267 FX_BOOL CJS_Runtime::AddEventToLoop(const CFX_WideString& sTargetName, JS_EVENT_T eEventType)
269 if (m_pFieldEventPath == NULL)
271 m_pFieldEventPath = new CJS_FieldEvent;
272 m_pFieldEventPath->sTargetName = sTargetName;
273 m_pFieldEventPath->eEventType = eEventType;
274 m_pFieldEventPath->pNext = NULL;
280 CJS_FieldEvent* p = m_pFieldEventPath;
281 CJS_FieldEvent* pLast = m_pFieldEventPath;
284 if (p->eEventType == eEventType && p->sTargetName == sTargetName)
292 CJS_FieldEvent* pNew = new CJS_FieldEvent;
293 pNew->sTargetName = sTargetName;
294 pNew->eEventType = eEventType;
302 void CJS_Runtime::RemoveEventInLoop(const CFX_WideString& sTargetName, JS_EVENT_T eEventType)
304 FX_BOOL bFind = FALSE;
306 CJS_FieldEvent* p = m_pFieldEventPath;
307 CJS_FieldEvent* pLast = NULL;
310 if (p->eEventType == eEventType && p->sTargetName == sTargetName)
322 RemoveEventsInLoop(p);
324 if (p == m_pFieldEventPath)
325 m_pFieldEventPath = NULL;
332 void CJS_Runtime::RemoveEventsInLoop(CJS_FieldEvent* pStart)
334 CJS_FieldEvent* p = pStart;
338 CJS_FieldEvent* pOld = p;
345 v8::Handle<v8::Context> CJS_Runtime::NewJSContext()
347 return v8::Local<v8::Context>::New(m_isolate, m_context);
350 CFX_WideString ChangeObjName(const CFX_WideString& str)
352 CFX_WideString sRet = str;
353 sRet.Replace((FX_LPCWSTR)L"_", (FX_LPCWSTR)L".");
357 void CJS_Runtime::GetObjectNames(CFX_WideStringArray& array)
361 array.Add(CJS_Border::m_pClassName);
362 array.Add(CJS_Display::m_pClassName);
363 array.Add(CJS_Font::m_pClassName);
364 array.Add(CJS_Highlight::m_pClassName);
365 array.Add(CJS_Position::m_pClassName);
366 array.Add(CJS_ScaleHow::m_pClassName);
367 array.Add(CJS_ScaleWhen::m_pClassName);
368 array.Add(CJS_Style::m_pClassName);
369 array.Add(CJS_Zoomtype::m_pClassName);
371 array.Add(CJS_App::m_pClassName);
372 array.Add((FX_LPCWSTR)"this");
373 array.Add(CJS_Event::m_pClassName);
375 array.Add(CJS_Global::m_pClassName);
376 array.Add(CJS_Util::m_pClassName);
379 void CJS_Runtime::GetObjectConsts(const CFX_WideString& sObjName, CFX_WideStringArray& array)
381 JSConstSpec* pConsts = NULL;
384 if (sObjName == CJS_Border::m_pClassName)
385 CJS_Border::GetConsts(pConsts, nSize);
386 else if (sObjName == CJS_Display::m_pClassName)
387 CJS_Display::GetConsts(pConsts, nSize);
388 else if (sObjName == CJS_Font::m_pClassName)
389 CJS_Font::GetConsts(pConsts, nSize);
390 else if (sObjName == CJS_Highlight::m_pClassName)
391 CJS_Highlight::GetConsts(pConsts, nSize);
392 else if (sObjName == CJS_Position::m_pClassName)
393 CJS_Position::GetConsts(pConsts, nSize);
394 else if (sObjName == CJS_ScaleHow::m_pClassName)
395 CJS_ScaleHow::GetConsts(pConsts, nSize);
396 else if (sObjName == CJS_ScaleWhen::m_pClassName)
397 CJS_ScaleWhen::GetConsts(pConsts, nSize);
398 else if (sObjName == CJS_Style::m_pClassName)
399 CJS_Style::GetConsts(pConsts, nSize);
400 else if (sObjName == CJS_Zoomtype::m_pClassName)
401 CJS_Zoomtype::GetConsts(pConsts, nSize);
403 else if (sObjName == CJS_App::m_pClassName)
404 CJS_App::GetConsts(pConsts, nSize);
405 else if (sObjName == CJS_Color::m_pClassName)
406 CJS_Color::GetConsts(pConsts, nSize);
408 else if (sObjName == L"this")
410 if (GetReaderDocument())
411 CJS_Document::GetConsts(pConsts, nSize);
413 CJS_App::GetConsts(pConsts, nSize);
416 if (sObjName == CJS_Event::m_pClassName)
417 CJS_Event::GetConsts(pConsts, nSize);
418 else if (sObjName == CJS_Field::m_pClassName)
419 CJS_Field::GetConsts(pConsts, nSize);
420 else if (sObjName == CJS_Global::m_pClassName)
421 CJS_Global::GetConsts(pConsts, nSize);
422 else if (sObjName == CJS_Util::m_pClassName)
423 CJS_Util::GetConsts(pConsts, nSize);
425 for (int i=0; i<nSize; i++)
426 array.Add(pConsts[i].pName);
429 void CJS_Runtime::GetObjectProps(const CFX_WideString& sObjName, CFX_WideStringArray& array)
431 JSPropertySpec* pProperties = NULL;
434 if (sObjName == CJS_App::m_pClassName)
435 CJS_App::GetProperties(pProperties, nSize);
436 else if (sObjName == CJS_Color::m_pClassName)
437 CJS_Color::GetProperties(pProperties, nSize);
438 else if (sObjName == L"this")
440 if (GetReaderDocument())
441 CJS_Document::GetProperties(pProperties, nSize);
443 CJS_App::GetProperties(pProperties, nSize);
445 else if (sObjName == CJS_Event::m_pClassName)
446 CJS_Event::GetProperties(pProperties, nSize);
447 else if (sObjName == CJS_Field::m_pClassName)
448 CJS_Field::GetProperties(pProperties, nSize);
449 else if (sObjName == CJS_Global::m_pClassName)
450 CJS_Global::GetProperties(pProperties, nSize);
451 else if (sObjName == CJS_Util::m_pClassName)
452 CJS_Util::GetProperties(pProperties, nSize);
454 for (int i=0; i<nSize; i++)
455 array.Add(pProperties[i].pName);
458 void CJS_Runtime::GetObjectMethods(const CFX_WideString& sObjName, CFX_WideStringArray& array)
460 JSMethodSpec* pMethods = NULL;
463 if (sObjName == CJS_App::m_pClassName)
464 CJS_App::GetMethods(pMethods, nSize);
465 else if (sObjName == CJS_Color::m_pClassName)
466 CJS_Color::GetMethods(pMethods, nSize);
467 else if (sObjName == L"this")
469 if (GetReaderDocument())
470 CJS_Document::GetMethods(pMethods, nSize);
472 CJS_App::GetMethods(pMethods, nSize);
474 else if (sObjName == CJS_Event::m_pClassName)
475 CJS_Event::GetMethods(pMethods, nSize);
476 else if (sObjName == CJS_Field::m_pClassName)
477 CJS_Field::GetMethods(pMethods, nSize);
478 else if (sObjName == CJS_Global::m_pClassName)
479 CJS_Global::GetMethods(pMethods, nSize);
480 else if (sObjName == CJS_Util::m_pClassName)
481 CJS_Util::GetMethods(pMethods, nSize);
483 for (int i=0; i<nSize; i++)
484 array.Add(pMethods[i].pName);
487 FX_BOOL CJS_Runtime::IsEntered()
489 return v8::Isolate::GetCurrent() == m_isolate;
491 void CJS_Runtime::Exit()
493 if(m_isolate) m_isolate->Exit();
495 void CJS_Runtime::Enter()
497 if(m_isolate) m_isolate->Enter();
499 FX_BOOL CJS_Runtime::GetHValueByName(FX_BSTR utf8Name, FXJSE_HVALUE hValue)
501 FX_LPCSTR name = utf8Name.GetCStr();
503 v8::Locker lock(GetIsolate());
504 v8::Isolate::Scope isolate_scope(GetIsolate());
505 v8::HandleScope handle_scope(GetIsolate());
506 v8::Local<v8::Context> context =
507 v8::Local<v8::Context>::New(GetIsolate(), m_context);
508 v8::Context::Scope context_scope(context);
511 //v8::Local<v8::Context> tmpCotext = v8::Local<v8::Context>::New(GetIsolate(), m_context);
512 v8::Local<v8::Value> propvalue = context->Global()->Get(v8::String::NewFromUtf8(GetIsolate(), name, v8::String::kNormalString, utf8Name.GetLength()));
514 if (propvalue.IsEmpty()) {
515 FXJSE_Value_SetUndefined(hValue);
518 ((CFXJSE_Value*)hValue)->ForceSetValue(propvalue);
522 FX_BOOL CJS_Runtime::SetHValueByName(FX_BSTR utf8Name, FXJSE_HVALUE hValue)
524 if (utf8Name.IsEmpty() || hValue == NULL)
526 FX_LPCSTR name = utf8Name.GetCStr();
527 v8::Isolate* pIsolate = GetIsolate();
528 v8::Locker lock(pIsolate);
529 v8::Isolate::Scope isolate_scope(pIsolate);
530 v8::HandleScope handle_scope(pIsolate);
531 v8::Local<v8::Context> context =
532 v8::Local<v8::Context>::New(pIsolate, m_context);
533 v8::Context::Scope context_scope(context);
535 //v8::Local<v8::Context> tmpCotext = v8::Local<v8::Context>::New(GetIsolate(), m_context);
536 v8::Local<v8::Value> propvalue = v8::Local<v8::Value>::New(GetIsolate(),((CFXJSE_Value*)hValue)->DirectGetValue());
537 context->Global()->Set(v8::String::NewFromUtf8(pIsolate, name, v8::String::kNormalString, utf8Name.GetLength()), propvalue);