From c0858354f1e9ce1246b8af9ef2cd11623a1132dd Mon Sep 17 00:00:00 2001 From: Dan Sinclair Date: Mon, 30 Oct 2017 17:49:52 +0000 Subject: Rename app to cjs_app This CL renames the app.{cpp|h} files to cjs_app.{cpp|h}. The CJS_TimerObj and GlobalTimer objects have been moved to their own files. Change-Id: I7a4063b212f1051b1517ec8902a0ee215854feaf Reviewed-on: https://pdfium-review.googlesource.com/17040 Commit-Queue: dsinclair Reviewed-by: Tom Sepez --- BUILD.gn | 8 +- fpdfsdk/javascript/app.cpp | 719 ------------------------------------ fpdfsdk/javascript/app.h | 193 ---------- fpdfsdk/javascript/cjs_app.cpp | 578 +++++++++++++++++++++++++++++ fpdfsdk/javascript/cjs_app.h | 169 +++++++++ fpdfsdk/javascript/cjs_document.cpp | 2 +- fpdfsdk/javascript/cjs_runtime.cpp | 3 +- fpdfsdk/javascript/cjs_timerobj.cpp | 32 ++ fpdfsdk/javascript/cjs_timerobj.h | 38 ++ fpdfsdk/javascript/global_timer.cpp | 80 ++++ fpdfsdk/javascript/global_timer.h | 50 +++ 11 files changed, 956 insertions(+), 916 deletions(-) delete mode 100644 fpdfsdk/javascript/app.cpp delete mode 100644 fpdfsdk/javascript/app.h create mode 100644 fpdfsdk/javascript/cjs_app.cpp create mode 100644 fpdfsdk/javascript/cjs_app.h create mode 100644 fpdfsdk/javascript/cjs_timerobj.cpp create mode 100644 fpdfsdk/javascript/cjs_timerobj.h create mode 100644 fpdfsdk/javascript/global_timer.cpp create mode 100644 fpdfsdk/javascript/global_timer.h diff --git a/BUILD.gn b/BUILD.gn index 5d86038d14..accbd606c9 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1194,10 +1194,10 @@ static_library("javascript") { "fpdfsdk/javascript/JS_GlobalData.h", "fpdfsdk/javascript/JS_KeyValue.cpp", "fpdfsdk/javascript/JS_KeyValue.h", - "fpdfsdk/javascript/app.cpp", - "fpdfsdk/javascript/app.h", "fpdfsdk/javascript/cjs_annot.cpp", "fpdfsdk/javascript/cjs_annot.h", + "fpdfsdk/javascript/cjs_app.cpp", + "fpdfsdk/javascript/cjs_app.h", "fpdfsdk/javascript/cjs_border.cpp", "fpdfsdk/javascript/cjs_border.h", "fpdfsdk/javascript/cjs_delaydata.cpp", @@ -1244,6 +1244,8 @@ static_library("javascript") { "fpdfsdk/javascript/cjs_scalewhen.h", "fpdfsdk/javascript/cjs_style.cpp", "fpdfsdk/javascript/cjs_style.h", + "fpdfsdk/javascript/cjs_timerobj.cpp", + "fpdfsdk/javascript/cjs_timerobj.h", "fpdfsdk/javascript/cjs_zoomtype.cpp", "fpdfsdk/javascript/cjs_zoomtype.h", "fpdfsdk/javascript/color.cpp", @@ -1252,6 +1254,8 @@ static_library("javascript") { "fpdfsdk/javascript/console.h", "fpdfsdk/javascript/event.cpp", "fpdfsdk/javascript/event.h", + "fpdfsdk/javascript/global_timer.cpp", + "fpdfsdk/javascript/global_timer.h", "fpdfsdk/javascript/report.cpp", "fpdfsdk/javascript/report.h", "fpdfsdk/javascript/resource.cpp", diff --git a/fpdfsdk/javascript/app.cpp b/fpdfsdk/javascript/app.cpp deleted file mode 100644 index 3e8ca0bf1a..0000000000 --- a/fpdfsdk/javascript/app.cpp +++ /dev/null @@ -1,719 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "fpdfsdk/javascript/app.h" - -#include -#include -#include - -#include "fpdfsdk/cpdfsdk_formfillenvironment.h" -#include "fpdfsdk/cpdfsdk_interform.h" -#include "fpdfsdk/javascript/JS_Define.h" -#include "fpdfsdk/javascript/cjs_document.h" -#include "fpdfsdk/javascript/cjs_event_context.h" -#include "fpdfsdk/javascript/cjs_eventhandler.h" -#include "fpdfsdk/javascript/cjs_object.h" -#include "fpdfsdk/javascript/cjs_runtime.h" -#include "fpdfsdk/javascript/resource.h" -#include "third_party/base/stl_util.h" - -namespace { - -bool IsTypeKnown(v8::Local value) { - return !value.IsEmpty() && - (value->IsString() || value->IsNumber() || value->IsBoolean() || - value->IsDate() || value->IsObject() || value->IsNull() || - value->IsUndefined()); -} - -} // namespace - -class GlobalTimer { - public: - GlobalTimer(app* pObj, - CPDFSDK_FormFillEnvironment* pFormFillEnv, - CJS_Runtime* pRuntime, - int nType, - const WideString& script, - uint32_t dwElapse, - uint32_t dwTimeOut); - ~GlobalTimer(); - - static void Trigger(int nTimerID); - static void Cancel(int nTimerID); - - bool IsOneShot() const { return m_nType == 1; } - uint32_t GetTimeOut() const { return m_dwTimeOut; } - int GetTimerID() const { return m_nTimerID; } - CJS_Runtime* GetRuntime() const { return m_pRuntime.Get(); } - WideString GetJScript() const { return m_swJScript; } - - private: - using TimerMap = std::map; - static TimerMap* GetGlobalTimerMap(); - - uint32_t m_nTimerID; - app* const m_pEmbedObj; - bool m_bProcessing; - - // data - const int m_nType; // 0:Interval; 1:TimeOut - const uint32_t m_dwTimeOut; - const WideString m_swJScript; - CJS_Runtime::ObservedPtr m_pRuntime; - CPDFSDK_FormFillEnvironment::ObservedPtr m_pFormFillEnv; -}; - -GlobalTimer::GlobalTimer(app* pObj, - CPDFSDK_FormFillEnvironment* pFormFillEnv, - CJS_Runtime* pRuntime, - int nType, - const WideString& script, - uint32_t dwElapse, - uint32_t dwTimeOut) - : m_nTimerID(0), - m_pEmbedObj(pObj), - m_bProcessing(false), - m_nType(nType), - m_dwTimeOut(dwTimeOut), - m_swJScript(script), - m_pRuntime(pRuntime), - m_pFormFillEnv(pFormFillEnv) { - CFX_SystemHandler* pHandler = m_pFormFillEnv->GetSysHandler(); - m_nTimerID = pHandler->SetTimer(dwElapse, Trigger); - if (m_nTimerID) - (*GetGlobalTimerMap())[m_nTimerID] = this; -} - -GlobalTimer::~GlobalTimer() { - if (!m_nTimerID) - return; - - if (GetRuntime()) - m_pFormFillEnv->GetSysHandler()->KillTimer(m_nTimerID); - - GetGlobalTimerMap()->erase(m_nTimerID); -} - -// static -void GlobalTimer::Trigger(int nTimerID) { - auto it = GetGlobalTimerMap()->find(nTimerID); - if (it == GetGlobalTimerMap()->end()) - return; - - GlobalTimer* pTimer = it->second; - if (pTimer->m_bProcessing) - return; - - pTimer->m_bProcessing = true; - if (pTimer->m_pEmbedObj) - pTimer->m_pEmbedObj->TimerProc(pTimer); - - // Timer proc may have destroyed timer, find it again. - it = GetGlobalTimerMap()->find(nTimerID); - if (it == GetGlobalTimerMap()->end()) - return; - - pTimer = it->second; - pTimer->m_bProcessing = false; - if (pTimer->IsOneShot()) - pTimer->m_pEmbedObj->CancelProc(pTimer); -} - -// static -void GlobalTimer::Cancel(int nTimerID) { - auto it = GetGlobalTimerMap()->find(nTimerID); - if (it == GetGlobalTimerMap()->end()) - return; - - GlobalTimer* pTimer = it->second; - pTimer->m_pEmbedObj->CancelProc(pTimer); -} - -// static -GlobalTimer::TimerMap* GlobalTimer::GetGlobalTimerMap() { - // Leak the timer array at shutdown. - static auto* s_TimerMap = new TimerMap; - return s_TimerMap; -} - -int CJS_TimerObj::ObjDefnID = -1; - -// static -int CJS_TimerObj::GetObjDefnID() { - return ObjDefnID; -} - -// static -void CJS_TimerObj::DefineJSObjects(CFXJS_Engine* pEngine) { - ObjDefnID = pEngine->DefineObj("TimerObj", FXJSOBJTYPE_DYNAMIC, - JSConstructor, - JSDestructor); -} - -TimerObj::TimerObj(CJS_Object* pJSObject) - : CJS_EmbedObj(pJSObject), m_nTimerID(0) {} - -TimerObj::~TimerObj() {} - -void TimerObj::SetTimer(GlobalTimer* pTimer) { - m_nTimerID = pTimer->GetTimerID(); -} - -#define JS_STR_VIEWERTYPE L"pdfium" -#define JS_STR_VIEWERVARIATION L"Full" -#define JS_STR_PLATFORM L"WIN" -#define JS_STR_LANGUAGE L"ENU" -#define JS_NUM_VIEWERVERSION 8 -#ifdef PDF_ENABLE_XFA -#define JS_NUM_VIEWERVERSION_XFA 11 -#endif // PDF_ENABLE_XFA -#define JS_NUM_FORMSVERSION 7 - -const JSPropertySpec CJS_App::PropertySpecs[] = { - {"activeDocs", get_active_docs_static, set_active_docs_static}, - {"calculate", get_calculate_static, set_calculate_static}, - {"formsVersion", get_forms_version_static, set_forms_version_static}, - {"fs", get_fs_static, set_fs_static}, - {"fullscreen", get_fullscreen_static, set_fullscreen_static}, - {"language", get_language_static, set_language_static}, - {"media", get_media_static, set_media_static}, - {"platform", get_platform_static, set_platform_static}, - {"runtimeHighlight", get_runtime_highlight_static, - set_runtime_highlight_static}, - {"viewerType", get_viewer_type_static, set_viewer_type_static}, - {"viewerVariation", get_viewer_variation_static, - set_viewer_variation_static}, - {"viewerVersion", get_viewer_version_static, set_viewer_version_static}, - {0, 0, 0}}; - -const JSMethodSpec CJS_App::MethodSpecs[] = { - {"alert", alert_static}, - {"beep", beep_static}, - {"browseForDoc", browseForDoc_static}, - {"clearInterval", clearInterval_static}, - {"clearTimeOut", clearTimeOut_static}, - {"execDialog", execDialog_static}, - {"execMenuItem", execMenuItem_static}, - {"findComponent", findComponent_static}, - {"goBack", goBack_static}, - {"goForward", goForward_static}, - {"launchURL", launchURL_static}, - {"mailMsg", mailMsg_static}, - {"newFDF", newFDF_static}, - {"newDoc", newDoc_static}, - {"openDoc", openDoc_static}, - {"openFDF", openFDF_static}, - {"popUpMenuEx", popUpMenuEx_static}, - {"popUpMenu", popUpMenu_static}, - {"response", response_static}, - {"setInterval", setInterval_static}, - {"setTimeOut", setTimeOut_static}, - {0, 0}}; - -int CJS_App::ObjDefnID = -1; - -// static -void CJS_App::DefineJSObjects(CFXJS_Engine* pEngine) { - ObjDefnID = - pEngine->DefineObj("app", FXJSOBJTYPE_STATIC, JSConstructor, - JSDestructor); - DefineProps(pEngine, ObjDefnID, PropertySpecs); - DefineMethods(pEngine, ObjDefnID, MethodSpecs); -} - -app::app(CJS_Object* pJSObject) - : CJS_EmbedObj(pJSObject), m_bCalculate(true), m_bRuntimeHighLight(false) {} - -app::~app() {} - -CJS_Return app::get_active_docs(CJS_Runtime* pRuntime) { - CJS_Document* pJSDocument = nullptr; - v8::Local pObj = pRuntime->GetThisObj(); - if (CFXJS_Engine::GetObjDefnID(pObj) == CJS_Document::GetObjDefnID()) - pJSDocument = static_cast(pRuntime->GetObjectPrivate(pObj)); - - v8::Local aDocs = pRuntime->NewArray(); - pRuntime->PutArrayElement( - aDocs, 0, - pJSDocument ? v8::Local(pJSDocument->ToV8Object()) - : v8::Local()); - if (pRuntime->GetArrayLength(aDocs) > 0) - return CJS_Return(aDocs); - return CJS_Return(pRuntime->NewUndefined()); -} - -CJS_Return app::set_active_docs(CJS_Runtime* pRuntime, - v8::Local vp) { - return CJS_Return(false); -} - -CJS_Return app::get_calculate(CJS_Runtime* pRuntime) { - return CJS_Return(pRuntime->NewBoolean(m_bCalculate)); -} - -CJS_Return app::set_calculate(CJS_Runtime* pRuntime, v8::Local vp) { - m_bCalculate = pRuntime->ToBoolean(vp); - pRuntime->GetFormFillEnv()->GetInterForm()->EnableCalculate(m_bCalculate); - return CJS_Return(true); -} - -CJS_Return app::get_forms_version(CJS_Runtime* pRuntime) { - return CJS_Return(pRuntime->NewNumber(JS_NUM_FORMSVERSION)); -} - -CJS_Return app::set_forms_version(CJS_Runtime* pRuntime, - v8::Local vp) { - return CJS_Return(false); -} - -CJS_Return app::get_viewer_type(CJS_Runtime* pRuntime) { - return CJS_Return(pRuntime->NewString(JS_STR_VIEWERTYPE)); -} - -CJS_Return app::set_viewer_type(CJS_Runtime* pRuntime, - v8::Local vp) { - return CJS_Return(false); -} - -CJS_Return app::get_viewer_variation(CJS_Runtime* pRuntime) { - return CJS_Return(pRuntime->NewString(JS_STR_VIEWERVARIATION)); -} - -CJS_Return app::set_viewer_variation(CJS_Runtime* pRuntime, - v8::Local vp) { - return CJS_Return(false); -} - -CJS_Return app::get_viewer_version(CJS_Runtime* pRuntime) { -#ifdef PDF_ENABLE_XFA - CPDFXFA_Context* pXFAContext = pRuntime->GetFormFillEnv()->GetXFAContext(); - if (pXFAContext->ContainsXFAForm()) - return CJS_Return(pRuntime->NewNumber(JS_NUM_VIEWERVERSION_XFA)); -#endif // PDF_ENABLE_XFA - return CJS_Return(pRuntime->NewNumber(JS_NUM_VIEWERVERSION)); -} - -CJS_Return app::set_viewer_version(CJS_Runtime* pRuntime, - v8::Local vp) { - return CJS_Return(false); -} - -CJS_Return app::get_platform(CJS_Runtime* pRuntime) { -#ifdef PDF_ENABLE_XFA - CPDFSDK_FormFillEnvironment* pFormFillEnv = pRuntime->GetFormFillEnv(); - if (!pFormFillEnv) - return CJS_Return(false); - - WideString platfrom = pFormFillEnv->GetPlatform(); - if (!platfrom.IsEmpty()) - return CJS_Return(pRuntime->NewString(platfrom.c_str())); -#endif - return CJS_Return(pRuntime->NewString(JS_STR_PLATFORM)); -} - -CJS_Return app::set_platform(CJS_Runtime* pRuntime, v8::Local vp) { - return CJS_Return(false); -} - -CJS_Return app::get_language(CJS_Runtime* pRuntime) { -#ifdef PDF_ENABLE_XFA - CPDFSDK_FormFillEnvironment* pFormFillEnv = pRuntime->GetFormFillEnv(); - if (!pFormFillEnv) - return CJS_Return(false); - - WideString language = pFormFillEnv->GetLanguage(); - if (!language.IsEmpty()) - return CJS_Return(pRuntime->NewString(language.c_str())); -#endif - return CJS_Return(pRuntime->NewString(JS_STR_LANGUAGE)); -} - -CJS_Return app::set_language(CJS_Runtime* pRuntime, v8::Local vp) { - return CJS_Return(false); -} - -// creates a new fdf object that contains no data -// comment: need reader support -// note: -// CFDF_Document * CPDFSDK_FormFillEnvironment::NewFDF(); -CJS_Return app::newFDF(CJS_Runtime* pRuntime, - const std::vector>& params) { - return CJS_Return(true); -} - -// opens a specified pdf document and returns its document object -// comment:need reader support -// note: as defined in js reference, the proto of this function's fourth -// parmeters, how old an fdf document while do not show it. -// CFDF_Document * CPDFSDK_FormFillEnvironment::OpenFDF(string strPath,bool -// bUserConv); - -CJS_Return app::openFDF(CJS_Runtime* pRuntime, - const std::vector>& params) { - return CJS_Return(true); -} - -CJS_Return app::alert(CJS_Runtime* pRuntime, - const std::vector>& params) { - std::vector> newParams = ExpandKeywordParams( - pRuntime, params, 4, L"cMsg", L"nIcon", L"nType", L"cTitle"); - - if (!IsTypeKnown(newParams[0])) - return CJS_Return(JSGetStringFromID(IDS_STRING_JSPARAMERROR)); - - CPDFSDK_FormFillEnvironment* pFormFillEnv = pRuntime->GetFormFillEnv(); - if (!pFormFillEnv) - return CJS_Return(pRuntime->NewNumber(0)); - - WideString swMsg; - if (newParams[0]->IsArray()) { - v8::Local carray = pRuntime->ToArray(newParams[0]); - swMsg = L"["; - for (size_t i = 0; i < pRuntime->GetArrayLength(carray); ++i) { - if (i) - swMsg += L", "; - - swMsg += pRuntime->ToWideString(pRuntime->GetArrayElement(carray, i)); - } - swMsg += L"]"; - } else { - swMsg = pRuntime->ToWideString(newParams[0]); - } - - int iIcon = 0; - if (IsTypeKnown(newParams[1])) - iIcon = pRuntime->ToInt32(newParams[1]); - - int iType = 0; - if (IsTypeKnown(newParams[2])) - iType = pRuntime->ToInt32(newParams[2]); - - WideString swTitle; - if (IsTypeKnown(newParams[3])) - swTitle = pRuntime->ToWideString(newParams[3]); - else - swTitle = JSGetStringFromID(IDS_STRING_JSALERT); - - pRuntime->BeginBlock(); - pFormFillEnv->KillFocusAnnot(0); - - v8::Local ret = pRuntime->NewNumber( - pFormFillEnv->JS_appAlert(swMsg.c_str(), swTitle.c_str(), iType, iIcon)); - pRuntime->EndBlock(); - - return CJS_Return(ret); -} - -CJS_Return app::beep(CJS_Runtime* pRuntime, - const std::vector>& params) { - if (params.size() == 1) { - pRuntime->GetFormFillEnv()->JS_appBeep(pRuntime->ToInt32(params[0])); - return CJS_Return(true); - } - return CJS_Return(JSGetStringFromID(IDS_STRING_JSPARAMERROR)); -} - -CJS_Return app::findComponent(CJS_Runtime* pRuntime, - const std::vector>& params) { - return CJS_Return(true); -} - -CJS_Return app::popUpMenuEx(CJS_Runtime* pRuntime, - const std::vector>& params) { - return CJS_Return(false); -} - -CJS_Return app::get_fs(CJS_Runtime* pRuntime) { - return CJS_Return(false); -} - -CJS_Return app::set_fs(CJS_Runtime* pRuntime, v8::Local vp) { - return CJS_Return(false); -} - -CJS_Return app::setInterval(CJS_Runtime* pRuntime, - const std::vector>& params) { - if (params.size() > 2 || params.size() == 0) - return CJS_Return(JSGetStringFromID(IDS_STRING_JSPARAMERROR)); - - WideString script = - params.size() > 0 ? pRuntime->ToWideString(params[0]) : L""; - if (script.IsEmpty()) - return CJS_Return(JSGetStringFromID(IDS_STRING_JSAFNUMBER_KEYSTROKE)); - - uint32_t dwInterval = params.size() > 1 ? pRuntime->ToInt32(params[1]) : 1000; - GlobalTimer* timerRef = new GlobalTimer(this, pRuntime->GetFormFillEnv(), - pRuntime, 0, script, dwInterval, 0); - m_Timers.insert(std::unique_ptr(timerRef)); - - v8::Local pRetObj = - pRuntime->NewFxDynamicObj(CJS_TimerObj::GetObjDefnID()); - if (pRetObj.IsEmpty()) - return CJS_Return(false); - - CJS_TimerObj* pJS_TimerObj = - static_cast(pRuntime->GetObjectPrivate(pRetObj)); - TimerObj* pTimerObj = static_cast(pJS_TimerObj->GetEmbedObject()); - pTimerObj->SetTimer(timerRef); - - return CJS_Return(pRetObj); -} - -CJS_Return app::setTimeOut(CJS_Runtime* pRuntime, - const std::vector>& params) { - if (params.size() > 2 || params.size() == 0) - return CJS_Return(JSGetStringFromID(IDS_STRING_JSPARAMERROR)); - - WideString script = pRuntime->ToWideString(params[0]); - if (script.IsEmpty()) - return CJS_Return(JSGetStringFromID(IDS_STRING_JSAFNUMBER_KEYSTROKE)); - - uint32_t dwTimeOut = params.size() > 1 ? pRuntime->ToInt32(params[1]) : 1000; - GlobalTimer* timerRef = - new GlobalTimer(this, pRuntime->GetFormFillEnv(), pRuntime, 1, script, - dwTimeOut, dwTimeOut); - m_Timers.insert(std::unique_ptr(timerRef)); - - v8::Local pRetObj = - pRuntime->NewFxDynamicObj(CJS_TimerObj::GetObjDefnID()); - if (pRetObj.IsEmpty()) - return CJS_Return(false); - - CJS_TimerObj* pJS_TimerObj = - static_cast(pRuntime->GetObjectPrivate(pRetObj)); - TimerObj* pTimerObj = static_cast(pJS_TimerObj->GetEmbedObject()); - pTimerObj->SetTimer(timerRef); - - return CJS_Return(pRetObj); -} - -CJS_Return app::clearTimeOut(CJS_Runtime* pRuntime, - const std::vector>& params) { - if (params.size() != 1) - return CJS_Return(JSGetStringFromID(IDS_STRING_JSPARAMERROR)); - - app::ClearTimerCommon(pRuntime, params[0]); - return CJS_Return(true); -} - -CJS_Return app::clearInterval(CJS_Runtime* pRuntime, - const std::vector>& params) { - if (params.size() != 1) - return CJS_Return(JSGetStringFromID(IDS_STRING_JSPARAMERROR)); - - app::ClearTimerCommon(pRuntime, params[0]); - return CJS_Return(true); -} - -void app::ClearTimerCommon(CJS_Runtime* pRuntime, v8::Local param) { - if (!param->IsObject()) - return; - - v8::Local pObj = pRuntime->ToObject(param); - if (CFXJS_Engine::GetObjDefnID(pObj) != CJS_TimerObj::GetObjDefnID()) - return; - - CJS_Object* pJSObj = - static_cast(pRuntime->GetObjectPrivate(pObj)); - if (!pJSObj) - return; - - TimerObj* pTimerObj = static_cast(pJSObj->GetEmbedObject()); - if (!pTimerObj) - return; - - GlobalTimer::Cancel(pTimerObj->GetTimerID()); -} - -CJS_Return app::execMenuItem(CJS_Runtime* pRuntime, - const std::vector>& params) { - return CJS_Return(false); -} - -void app::TimerProc(GlobalTimer* pTimer) { - CJS_Runtime* pRuntime = pTimer->GetRuntime(); - if (pRuntime && (!pTimer->IsOneShot() || pTimer->GetTimeOut() > 0)) - RunJsScript(pRuntime, pTimer->GetJScript()); -} - -void app::CancelProc(GlobalTimer* pTimer) { - m_Timers.erase(pdfium::FakeUniquePtr(pTimer)); -} - -void app::RunJsScript(CJS_Runtime* pRuntime, const WideString& wsScript) { - if (!pRuntime->IsBlocking()) { - IJS_EventContext* pContext = pRuntime->NewEventContext(); - pContext->OnExternal_Exec(); - WideString wtInfo; - pContext->RunScript(wsScript, &wtInfo); - pRuntime->ReleaseEventContext(pContext); - } -} - -CJS_Return app::goBack(CJS_Runtime* pRuntime, - const std::vector>& params) { - // Not supported. - return CJS_Return(true); -} - -CJS_Return app::goForward(CJS_Runtime* pRuntime, - const std::vector>& params) { - // Not supported. - return CJS_Return(true); -} - -CJS_Return app::mailMsg(CJS_Runtime* pRuntime, - const std::vector>& params) { - std::vector> newParams = - ExpandKeywordParams(pRuntime, params, 6, L"bUI", L"cTo", L"cCc", L"cBcc", - L"cSubject", L"cMsg"); - - if (!IsTypeKnown(newParams[0])) - return CJS_Return(JSGetStringFromID(IDS_STRING_JSPARAMERROR)); - - bool bUI = pRuntime->ToBoolean(newParams[0]); - WideString cTo; - if (IsTypeKnown(newParams[1])) { - cTo = pRuntime->ToWideString(newParams[1]); - } else { - // cTo parameter required when UI not invoked. - if (!bUI) - return CJS_Return(JSGetStringFromID(IDS_STRING_JSPARAMERROR)); - } - - WideString cCc; - if (IsTypeKnown(newParams[2])) - cCc = pRuntime->ToWideString(newParams[2]); - - WideString cBcc; - if (IsTypeKnown(newParams[3])) - cBcc = pRuntime->ToWideString(newParams[3]); - - WideString cSubject; - if (IsTypeKnown(newParams[4])) - cSubject = pRuntime->ToWideString(newParams[4]); - - WideString cMsg; - if (IsTypeKnown(newParams[5])) - cMsg = pRuntime->ToWideString(newParams[5]); - - pRuntime->BeginBlock(); - pRuntime->GetFormFillEnv()->JS_docmailForm(nullptr, 0, bUI, cTo.c_str(), - cSubject.c_str(), cCc.c_str(), - cBcc.c_str(), cMsg.c_str()); - pRuntime->EndBlock(); - return CJS_Return(true); -} - -CJS_Return app::launchURL(CJS_Runtime* pRuntime, - const std::vector>& params) { - // Unsafe, not supported. - return CJS_Return(true); -} - -CJS_Return app::get_runtime_highlight(CJS_Runtime* pRuntime) { - return CJS_Return(pRuntime->NewBoolean(m_bRuntimeHighLight)); -} - -CJS_Return app::set_runtime_highlight(CJS_Runtime* pRuntime, - v8::Local vp) { - m_bRuntimeHighLight = pRuntime->ToBoolean(vp); - return CJS_Return(true); -} - -CJS_Return app::get_fullscreen(CJS_Runtime* pRuntime) { - return CJS_Return(false); -} - -CJS_Return app::set_fullscreen(CJS_Runtime* pRuntime, v8::Local vp) { - return CJS_Return(false); -} - -CJS_Return app::popUpMenu(CJS_Runtime* pRuntime, - const std::vector>& params) { - return CJS_Return(false); -} - -CJS_Return app::browseForDoc(CJS_Runtime* pRuntime, - const std::vector>& params) { - // Unsafe, not supported. - return CJS_Return(true); -} - -WideString app::SysPathToPDFPath(const WideString& sOldPath) { - WideString sRet = L"/"; - for (const wchar_t& c : sOldPath) { - if (c != L':') - sRet += (c == L'\\') ? L'/' : c; - } - return sRet; -} - -CJS_Return app::newDoc(CJS_Runtime* pRuntime, - const std::vector>& params) { - return CJS_Return(false); -} - -CJS_Return app::openDoc(CJS_Runtime* pRuntime, - const std::vector>& params) { - return CJS_Return(false); -} - -CJS_Return app::response(CJS_Runtime* pRuntime, - const std::vector>& params) { - std::vector> newParams = - ExpandKeywordParams(pRuntime, params, 5, L"cQuestion", L"cTitle", - L"cDefault", L"bPassword", L"cLabel"); - - if (!IsTypeKnown(newParams[0])) - return CJS_Return(JSGetStringFromID(IDS_STRING_JSPARAMERROR)); - - WideString swQuestion = pRuntime->ToWideString(newParams[0]); - WideString swTitle = L"PDF"; - if (IsTypeKnown(newParams[1])) - swTitle = pRuntime->ToWideString(newParams[1]); - - WideString swDefault; - if (IsTypeKnown(newParams[2])) - swDefault = pRuntime->ToWideString(newParams[2]); - - bool bPassword = false; - if (IsTypeKnown(newParams[3])) - bPassword = pRuntime->ToBoolean(newParams[3]); - - WideString swLabel; - if (IsTypeKnown(newParams[4])) - swLabel = pRuntime->ToWideString(newParams[4]); - - const int MAX_INPUT_BYTES = 2048; - std::vector pBuff(MAX_INPUT_BYTES + 2); - int nLengthBytes = pRuntime->GetFormFillEnv()->JS_appResponse( - swQuestion.c_str(), swTitle.c_str(), swDefault.c_str(), swLabel.c_str(), - bPassword, pBuff.data(), MAX_INPUT_BYTES); - - if (nLengthBytes < 0 || nLengthBytes > MAX_INPUT_BYTES) - return CJS_Return(JSGetStringFromID(IDS_STRING_JSPARAM_TOOLONG)); - - return CJS_Return(pRuntime->NewString( - WideString::FromUTF16LE(reinterpret_cast(pBuff.data()), - nLengthBytes / sizeof(uint16_t)) - .c_str())); -} - -CJS_Return app::get_media(CJS_Runtime* pRuntime) { - return CJS_Return(false); -} - -CJS_Return app::set_media(CJS_Runtime* pRuntime, v8::Local vp) { - return CJS_Return(false); -} - -CJS_Return app::execDialog(CJS_Runtime* pRuntime, - const std::vector>& params) { - return CJS_Return(true); -} diff --git a/fpdfsdk/javascript/app.h b/fpdfsdk/javascript/app.h deleted file mode 100644 index ea95398c80..0000000000 --- a/fpdfsdk/javascript/app.h +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef FPDFSDK_JAVASCRIPT_APP_H_ -#define FPDFSDK_JAVASCRIPT_APP_H_ - -#include -#include -#include - -#include "fpdfsdk/javascript/JS_Define.h" - -class CJS_Runtime; -class GlobalTimer; - -class TimerObj : public CJS_EmbedObj { - public: - explicit TimerObj(CJS_Object* pJSObject); - ~TimerObj() override; - - void SetTimer(GlobalTimer* pTimer); - int GetTimerID() const { return m_nTimerID; } - - private: - int m_nTimerID; // Weak reference to GlobalTimer through global map. -}; - -class CJS_TimerObj : public CJS_Object { - public: - static int GetObjDefnID(); - static void DefineJSObjects(CFXJS_Engine* pEngine); - - explicit CJS_TimerObj(v8::Local pObject) : CJS_Object(pObject) {} - ~CJS_TimerObj() override {} - - private: - static int ObjDefnID; -}; - -class app : public CJS_EmbedObj { - public: - explicit app(CJS_Object* pJSObject); - ~app() override; - - CJS_Return get_active_docs(CJS_Runtime* pRuntime); - CJS_Return set_active_docs(CJS_Runtime* pRuntime, v8::Local vp); - - CJS_Return get_calculate(CJS_Runtime* pRuntime); - CJS_Return set_calculate(CJS_Runtime* pRuntime, v8::Local vp); - - CJS_Return get_forms_version(CJS_Runtime* pRuntime); - CJS_Return set_forms_version(CJS_Runtime* pRuntime, v8::Local vp); - - CJS_Return get_fs(CJS_Runtime* pRuntime); - CJS_Return set_fs(CJS_Runtime* pRuntime, v8::Local vp); - - CJS_Return get_fullscreen(CJS_Runtime* pRuntime); - CJS_Return set_fullscreen(CJS_Runtime* pRuntime, v8::Local vp); - - CJS_Return get_language(CJS_Runtime* pRuntime); - CJS_Return set_language(CJS_Runtime* pRuntime, v8::Local vp); - - CJS_Return get_media(CJS_Runtime* pRuntime); - CJS_Return set_media(CJS_Runtime* pRuntime, v8::Local vp); - - CJS_Return get_platform(CJS_Runtime* pRuntime); - CJS_Return set_platform(CJS_Runtime* pRuntime, v8::Local vp); - - CJS_Return get_runtime_highlight(CJS_Runtime* pRuntime); - CJS_Return set_runtime_highlight(CJS_Runtime* pRuntime, - v8::Local vp); - - CJS_Return get_viewer_type(CJS_Runtime* pRuntime); - CJS_Return set_viewer_type(CJS_Runtime* pRuntime, v8::Local vp); - - CJS_Return get_viewer_variation(CJS_Runtime* pRuntime); - CJS_Return set_viewer_variation(CJS_Runtime* pRuntime, - v8::Local vp); - - CJS_Return get_viewer_version(CJS_Runtime* pRuntime); - CJS_Return set_viewer_version(CJS_Runtime* pRuntime, v8::Local vp); - - CJS_Return alert(CJS_Runtime* pRuntime, - const std::vector>& params); - CJS_Return beep(CJS_Runtime* pRuntime, - const std::vector>& params); - CJS_Return browseForDoc(CJS_Runtime* pRuntime, - const std::vector>& params); - CJS_Return clearInterval(CJS_Runtime* pRuntime, - const std::vector>& params); - CJS_Return clearTimeOut(CJS_Runtime* pRuntime, - const std::vector>& params); - CJS_Return execDialog(CJS_Runtime* pRuntime, - const std::vector>& params); - CJS_Return execMenuItem(CJS_Runtime* pRuntime, - const std::vector>& params); - CJS_Return findComponent(CJS_Runtime* pRuntime, - const std::vector>& params); - CJS_Return goBack(CJS_Runtime* pRuntime, - const std::vector>& params); - CJS_Return goForward(CJS_Runtime* pRuntime, - const std::vector>& params); - CJS_Return launchURL(CJS_Runtime* pRuntime, - const std::vector>& params); - CJS_Return mailMsg(CJS_Runtime* pRuntime, - const std::vector>& params); - CJS_Return newFDF(CJS_Runtime* pRuntime, - const std::vector>& params); - CJS_Return newDoc(CJS_Runtime* pRuntime, - const std::vector>& params); - CJS_Return openDoc(CJS_Runtime* pRuntime, - const std::vector>& params); - CJS_Return openFDF(CJS_Runtime* pRuntime, - const std::vector>& params); - CJS_Return popUpMenuEx(CJS_Runtime* pRuntime, - const std::vector>& params); - CJS_Return popUpMenu(CJS_Runtime* pRuntime, - const std::vector>& params); - CJS_Return response(CJS_Runtime* pRuntime, - const std::vector>& params); - CJS_Return setInterval(CJS_Runtime* pRuntime, - const std::vector>& params); - CJS_Return setTimeOut(CJS_Runtime* pRuntime, - const std::vector>& params); - - void TimerProc(GlobalTimer* pTimer); - void CancelProc(GlobalTimer* pTimer); - - static WideString SysPathToPDFPath(const WideString& sOldPath); - - private: - // CJS_EmbedObj - void RunJsScript(CJS_Runtime* pRuntime, const WideString& wsScript); - - void ClearTimerCommon(CJS_Runtime* pRuntime, v8::Local param); - - bool m_bCalculate; - bool m_bRuntimeHighLight; - std::set> m_Timers; -}; - -class CJS_App : public CJS_Object { - public: - static void DefineJSObjects(CFXJS_Engine* pEngine); - - explicit CJS_App(v8::Local pObject) : CJS_Object(pObject) {} - ~CJS_App() override {} - - JS_STATIC_PROP(activeDocs, active_docs, app); - JS_STATIC_PROP(calculate, calculate, app); - JS_STATIC_PROP(formsVersion, forms_version, app); - JS_STATIC_PROP(fs, fs, app); - JS_STATIC_PROP(fullscreen, fullscreen, app); - JS_STATIC_PROP(language, language, app); - JS_STATIC_PROP(media, media, app); - JS_STATIC_PROP(platform, platform, app); - JS_STATIC_PROP(runtimeHighlight, runtime_highlight, app); - JS_STATIC_PROP(viewerType, viewer_type, app); - JS_STATIC_PROP(viewerVariation, viewer_variation, app); - JS_STATIC_PROP(viewerVersion, viewer_version, app); - - JS_STATIC_METHOD(alert, app); - JS_STATIC_METHOD(beep, app); - JS_STATIC_METHOD(browseForDoc, app); - JS_STATIC_METHOD(clearInterval, app); - JS_STATIC_METHOD(clearTimeOut, app); - JS_STATIC_METHOD(execDialog, app); - JS_STATIC_METHOD(execMenuItem, app); - JS_STATIC_METHOD(findComponent, app); - JS_STATIC_METHOD(goBack, app); - JS_STATIC_METHOD(goForward, app); - JS_STATIC_METHOD(launchURL, app); - JS_STATIC_METHOD(mailMsg, app); - JS_STATIC_METHOD(newFDF, app); - JS_STATIC_METHOD(newDoc, app); - JS_STATIC_METHOD(openDoc, app); - JS_STATIC_METHOD(openFDF, app); - JS_STATIC_METHOD(popUpMenuEx, app); - JS_STATIC_METHOD(popUpMenu, app); - JS_STATIC_METHOD(response, app); - JS_STATIC_METHOD(setInterval, app); - JS_STATIC_METHOD(setTimeOut, app); - - private: - static int ObjDefnID; - static const JSPropertySpec PropertySpecs[]; - static const JSMethodSpec MethodSpecs[]; -}; - -#endif // FPDFSDK_JAVASCRIPT_APP_H_ diff --git a/fpdfsdk/javascript/cjs_app.cpp b/fpdfsdk/javascript/cjs_app.cpp new file mode 100644 index 0000000000..bd28fefc4e --- /dev/null +++ b/fpdfsdk/javascript/cjs_app.cpp @@ -0,0 +1,578 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "fpdfsdk/javascript/cjs_app.h" + +#include "fpdfsdk/cpdfsdk_interform.h" +#include "fpdfsdk/javascript/cjs_document.h" +#include "fpdfsdk/javascript/cjs_timerobj.h" +#include "fpdfsdk/javascript/global_timer.h" +#include "fpdfsdk/javascript/ijs_event_context.h" + +namespace { + +bool IsTypeKnown(v8::Local value) { + return !value.IsEmpty() && + (value->IsString() || value->IsNumber() || value->IsBoolean() || + value->IsDate() || value->IsObject() || value->IsNull() || + value->IsUndefined()); +} + +} // namespace + +#define JS_STR_VIEWERTYPE L"pdfium" +#define JS_STR_VIEWERVARIATION L"Full" +#define JS_STR_PLATFORM L"WIN" +#define JS_STR_LANGUAGE L"ENU" +#define JS_NUM_VIEWERVERSION 8 +#ifdef PDF_ENABLE_XFA +#define JS_NUM_VIEWERVERSION_XFA 11 +#endif // PDF_ENABLE_XFA +#define JS_NUM_FORMSVERSION 7 + +const JSPropertySpec CJS_App::PropertySpecs[] = { + {"activeDocs", get_active_docs_static, set_active_docs_static}, + {"calculate", get_calculate_static, set_calculate_static}, + {"formsVersion", get_forms_version_static, set_forms_version_static}, + {"fs", get_fs_static, set_fs_static}, + {"fullscreen", get_fullscreen_static, set_fullscreen_static}, + {"language", get_language_static, set_language_static}, + {"media", get_media_static, set_media_static}, + {"platform", get_platform_static, set_platform_static}, + {"runtimeHighlight", get_runtime_highlight_static, + set_runtime_highlight_static}, + {"viewerType", get_viewer_type_static, set_viewer_type_static}, + {"viewerVariation", get_viewer_variation_static, + set_viewer_variation_static}, + {"viewerVersion", get_viewer_version_static, set_viewer_version_static}, + {0, 0, 0}}; + +const JSMethodSpec CJS_App::MethodSpecs[] = { + {"alert", alert_static}, + {"beep", beep_static}, + {"browseForDoc", browseForDoc_static}, + {"clearInterval", clearInterval_static}, + {"clearTimeOut", clearTimeOut_static}, + {"execDialog", execDialog_static}, + {"execMenuItem", execMenuItem_static}, + {"findComponent", findComponent_static}, + {"goBack", goBack_static}, + {"goForward", goForward_static}, + {"launchURL", launchURL_static}, + {"mailMsg", mailMsg_static}, + {"newFDF", newFDF_static}, + {"newDoc", newDoc_static}, + {"openDoc", openDoc_static}, + {"openFDF", openFDF_static}, + {"popUpMenuEx", popUpMenuEx_static}, + {"popUpMenu", popUpMenu_static}, + {"response", response_static}, + {"setInterval", setInterval_static}, + {"setTimeOut", setTimeOut_static}, + {0, 0}}; + +int CJS_App::ObjDefnID = -1; + +// static +void CJS_App::DefineJSObjects(CFXJS_Engine* pEngine) { + ObjDefnID = + pEngine->DefineObj("app", FXJSOBJTYPE_STATIC, JSConstructor, + JSDestructor); + DefineProps(pEngine, ObjDefnID, PropertySpecs); + DefineMethods(pEngine, ObjDefnID, MethodSpecs); +} + +app::app(CJS_Object* pJSObject) + : CJS_EmbedObj(pJSObject), m_bCalculate(true), m_bRuntimeHighLight(false) {} + +app::~app() {} + +CJS_Return app::get_active_docs(CJS_Runtime* pRuntime) { + CJS_Document* pJSDocument = nullptr; + v8::Local pObj = pRuntime->GetThisObj(); + if (CFXJS_Engine::GetObjDefnID(pObj) == CJS_Document::GetObjDefnID()) + pJSDocument = static_cast(pRuntime->GetObjectPrivate(pObj)); + + v8::Local aDocs = pRuntime->NewArray(); + pRuntime->PutArrayElement( + aDocs, 0, + pJSDocument ? v8::Local(pJSDocument->ToV8Object()) + : v8::Local()); + if (pRuntime->GetArrayLength(aDocs) > 0) + return CJS_Return(aDocs); + return CJS_Return(pRuntime->NewUndefined()); +} + +CJS_Return app::set_active_docs(CJS_Runtime* pRuntime, + v8::Local vp) { + return CJS_Return(false); +} + +CJS_Return app::get_calculate(CJS_Runtime* pRuntime) { + return CJS_Return(pRuntime->NewBoolean(m_bCalculate)); +} + +CJS_Return app::set_calculate(CJS_Runtime* pRuntime, v8::Local vp) { + m_bCalculate = pRuntime->ToBoolean(vp); + pRuntime->GetFormFillEnv()->GetInterForm()->EnableCalculate(m_bCalculate); + return CJS_Return(true); +} + +CJS_Return app::get_forms_version(CJS_Runtime* pRuntime) { + return CJS_Return(pRuntime->NewNumber(JS_NUM_FORMSVERSION)); +} + +CJS_Return app::set_forms_version(CJS_Runtime* pRuntime, + v8::Local vp) { + return CJS_Return(false); +} + +CJS_Return app::get_viewer_type(CJS_Runtime* pRuntime) { + return CJS_Return(pRuntime->NewString(JS_STR_VIEWERTYPE)); +} + +CJS_Return app::set_viewer_type(CJS_Runtime* pRuntime, + v8::Local vp) { + return CJS_Return(false); +} + +CJS_Return app::get_viewer_variation(CJS_Runtime* pRuntime) { + return CJS_Return(pRuntime->NewString(JS_STR_VIEWERVARIATION)); +} + +CJS_Return app::set_viewer_variation(CJS_Runtime* pRuntime, + v8::Local vp) { + return CJS_Return(false); +} + +CJS_Return app::get_viewer_version(CJS_Runtime* pRuntime) { +#ifdef PDF_ENABLE_XFA + CPDFXFA_Context* pXFAContext = pRuntime->GetFormFillEnv()->GetXFAContext(); + if (pXFAContext->ContainsXFAForm()) + return CJS_Return(pRuntime->NewNumber(JS_NUM_VIEWERVERSION_XFA)); +#endif // PDF_ENABLE_XFA + return CJS_Return(pRuntime->NewNumber(JS_NUM_VIEWERVERSION)); +} + +CJS_Return app::set_viewer_version(CJS_Runtime* pRuntime, + v8::Local vp) { + return CJS_Return(false); +} + +CJS_Return app::get_platform(CJS_Runtime* pRuntime) { +#ifdef PDF_ENABLE_XFA + CPDFSDK_FormFillEnvironment* pFormFillEnv = pRuntime->GetFormFillEnv(); + if (!pFormFillEnv) + return CJS_Return(false); + + WideString platfrom = pFormFillEnv->GetPlatform(); + if (!platfrom.IsEmpty()) + return CJS_Return(pRuntime->NewString(platfrom.c_str())); +#endif + return CJS_Return(pRuntime->NewString(JS_STR_PLATFORM)); +} + +CJS_Return app::set_platform(CJS_Runtime* pRuntime, v8::Local vp) { + return CJS_Return(false); +} + +CJS_Return app::get_language(CJS_Runtime* pRuntime) { +#ifdef PDF_ENABLE_XFA + CPDFSDK_FormFillEnvironment* pFormFillEnv = pRuntime->GetFormFillEnv(); + if (!pFormFillEnv) + return CJS_Return(false); + + WideString language = pFormFillEnv->GetLanguage(); + if (!language.IsEmpty()) + return CJS_Return(pRuntime->NewString(language.c_str())); +#endif + return CJS_Return(pRuntime->NewString(JS_STR_LANGUAGE)); +} + +CJS_Return app::set_language(CJS_Runtime* pRuntime, v8::Local vp) { + return CJS_Return(false); +} + +// creates a new fdf object that contains no data +// comment: need reader support +// note: +// CFDF_Document * CPDFSDK_FormFillEnvironment::NewFDF(); +CJS_Return app::newFDF(CJS_Runtime* pRuntime, + const std::vector>& params) { + return CJS_Return(true); +} + +// opens a specified pdf document and returns its document object +// comment:need reader support +// note: as defined in js reference, the proto of this function's fourth +// parmeters, how old an fdf document while do not show it. +// CFDF_Document * CPDFSDK_FormFillEnvironment::OpenFDF(string strPath,bool +// bUserConv); + +CJS_Return app::openFDF(CJS_Runtime* pRuntime, + const std::vector>& params) { + return CJS_Return(true); +} + +CJS_Return app::alert(CJS_Runtime* pRuntime, + const std::vector>& params) { + std::vector> newParams = ExpandKeywordParams( + pRuntime, params, 4, L"cMsg", L"nIcon", L"nType", L"cTitle"); + + if (!IsTypeKnown(newParams[0])) + return CJS_Return(JSGetStringFromID(IDS_STRING_JSPARAMERROR)); + + CPDFSDK_FormFillEnvironment* pFormFillEnv = pRuntime->GetFormFillEnv(); + if (!pFormFillEnv) + return CJS_Return(pRuntime->NewNumber(0)); + + WideString swMsg; + if (newParams[0]->IsArray()) { + v8::Local carray = pRuntime->ToArray(newParams[0]); + swMsg = L"["; + for (size_t i = 0; i < pRuntime->GetArrayLength(carray); ++i) { + if (i) + swMsg += L", "; + + swMsg += pRuntime->ToWideString(pRuntime->GetArrayElement(carray, i)); + } + swMsg += L"]"; + } else { + swMsg = pRuntime->ToWideString(newParams[0]); + } + + int iIcon = 0; + if (IsTypeKnown(newParams[1])) + iIcon = pRuntime->ToInt32(newParams[1]); + + int iType = 0; + if (IsTypeKnown(newParams[2])) + iType = pRuntime->ToInt32(newParams[2]); + + WideString swTitle; + if (IsTypeKnown(newParams[3])) + swTitle = pRuntime->ToWideString(newParams[3]); + else + swTitle = JSGetStringFromID(IDS_STRING_JSALERT); + + pRuntime->BeginBlock(); + pFormFillEnv->KillFocusAnnot(0); + + v8::Local ret = pRuntime->NewNumber( + pFormFillEnv->JS_appAlert(swMsg.c_str(), swTitle.c_str(), iType, iIcon)); + pRuntime->EndBlock(); + + return CJS_Return(ret); +} + +CJS_Return app::beep(CJS_Runtime* pRuntime, + const std::vector>& params) { + if (params.size() == 1) { + pRuntime->GetFormFillEnv()->JS_appBeep(pRuntime->ToInt32(params[0])); + return CJS_Return(true); + } + return CJS_Return(JSGetStringFromID(IDS_STRING_JSPARAMERROR)); +} + +CJS_Return app::findComponent(CJS_Runtime* pRuntime, + const std::vector>& params) { + return CJS_Return(true); +} + +CJS_Return app::popUpMenuEx(CJS_Runtime* pRuntime, + const std::vector>& params) { + return CJS_Return(false); +} + +CJS_Return app::get_fs(CJS_Runtime* pRuntime) { + return CJS_Return(false); +} + +CJS_Return app::set_fs(CJS_Runtime* pRuntime, v8::Local vp) { + return CJS_Return(false); +} + +CJS_Return app::setInterval(CJS_Runtime* pRuntime, + const std::vector>& params) { + if (params.size() > 2 || params.size() == 0) + return CJS_Return(JSGetStringFromID(IDS_STRING_JSPARAMERROR)); + + WideString script = + params.size() > 0 ? pRuntime->ToWideString(params[0]) : L""; + if (script.IsEmpty()) + return CJS_Return(JSGetStringFromID(IDS_STRING_JSAFNUMBER_KEYSTROKE)); + + uint32_t dwInterval = params.size() > 1 ? pRuntime->ToInt32(params[1]) : 1000; + GlobalTimer* timerRef = new GlobalTimer(this, pRuntime->GetFormFillEnv(), + pRuntime, 0, script, dwInterval, 0); + m_Timers.insert(std::unique_ptr(timerRef)); + + v8::Local pRetObj = + pRuntime->NewFxDynamicObj(CJS_TimerObj::GetObjDefnID()); + if (pRetObj.IsEmpty()) + return CJS_Return(false); + + CJS_TimerObj* pJS_TimerObj = + static_cast(pRuntime->GetObjectPrivate(pRetObj)); + TimerObj* pTimerObj = static_cast(pJS_TimerObj->GetEmbedObject()); + pTimerObj->SetTimer(timerRef); + + return CJS_Return(pRetObj); +} + +CJS_Return app::setTimeOut(CJS_Runtime* pRuntime, + const std::vector>& params) { + if (params.size() > 2 || params.size() == 0) + return CJS_Return(JSGetStringFromID(IDS_STRING_JSPARAMERROR)); + + WideString script = pRuntime->ToWideString(params[0]); + if (script.IsEmpty()) + return CJS_Return(JSGetStringFromID(IDS_STRING_JSAFNUMBER_KEYSTROKE)); + + uint32_t dwTimeOut = params.size() > 1 ? pRuntime->ToInt32(params[1]) : 1000; + GlobalTimer* timerRef = + new GlobalTimer(this, pRuntime->GetFormFillEnv(), pRuntime, 1, script, + dwTimeOut, dwTimeOut); + m_Timers.insert(std::unique_ptr(timerRef)); + + v8::Local pRetObj = + pRuntime->NewFxDynamicObj(CJS_TimerObj::GetObjDefnID()); + if (pRetObj.IsEmpty()) + return CJS_Return(false); + + CJS_TimerObj* pJS_TimerObj = + static_cast(pRuntime->GetObjectPrivate(pRetObj)); + TimerObj* pTimerObj = static_cast(pJS_TimerObj->GetEmbedObject()); + pTimerObj->SetTimer(timerRef); + + return CJS_Return(pRetObj); +} + +CJS_Return app::clearTimeOut(CJS_Runtime* pRuntime, + const std::vector>& params) { + if (params.size() != 1) + return CJS_Return(JSGetStringFromID(IDS_STRING_JSPARAMERROR)); + + app::ClearTimerCommon(pRuntime, params[0]); + return CJS_Return(true); +} + +CJS_Return app::clearInterval(CJS_Runtime* pRuntime, + const std::vector>& params) { + if (params.size() != 1) + return CJS_Return(JSGetStringFromID(IDS_STRING_JSPARAMERROR)); + + app::ClearTimerCommon(pRuntime, params[0]); + return CJS_Return(true); +} + +void app::ClearTimerCommon(CJS_Runtime* pRuntime, v8::Local param) { + if (!param->IsObject()) + return; + + v8::Local pObj = pRuntime->ToObject(param); + if (CFXJS_Engine::GetObjDefnID(pObj) != CJS_TimerObj::GetObjDefnID()) + return; + + CJS_Object* pJSObj = + static_cast(pRuntime->GetObjectPrivate(pObj)); + if (!pJSObj) + return; + + TimerObj* pTimerObj = static_cast(pJSObj->GetEmbedObject()); + if (!pTimerObj) + return; + + GlobalTimer::Cancel(pTimerObj->GetTimerID()); +} + +CJS_Return app::execMenuItem(CJS_Runtime* pRuntime, + const std::vector>& params) { + return CJS_Return(false); +} + +void app::TimerProc(GlobalTimer* pTimer) { + CJS_Runtime* pRuntime = pTimer->GetRuntime(); + if (pRuntime && (!pTimer->IsOneShot() || pTimer->GetTimeOut() > 0)) + RunJsScript(pRuntime, pTimer->GetJScript()); +} + +void app::CancelProc(GlobalTimer* pTimer) { + m_Timers.erase(pdfium::FakeUniquePtr(pTimer)); +} + +void app::RunJsScript(CJS_Runtime* pRuntime, const WideString& wsScript) { + if (!pRuntime->IsBlocking()) { + IJS_EventContext* pContext = pRuntime->NewEventContext(); + pContext->OnExternal_Exec(); + WideString wtInfo; + pContext->RunScript(wsScript, &wtInfo); + pRuntime->ReleaseEventContext(pContext); + } +} + +CJS_Return app::goBack(CJS_Runtime* pRuntime, + const std::vector>& params) { + // Not supported. + return CJS_Return(true); +} + +CJS_Return app::goForward(CJS_Runtime* pRuntime, + const std::vector>& params) { + // Not supported. + return CJS_Return(true); +} + +CJS_Return app::mailMsg(CJS_Runtime* pRuntime, + const std::vector>& params) { + std::vector> newParams = + ExpandKeywordParams(pRuntime, params, 6, L"bUI", L"cTo", L"cCc", L"cBcc", + L"cSubject", L"cMsg"); + + if (!IsTypeKnown(newParams[0])) + return CJS_Return(JSGetStringFromID(IDS_STRING_JSPARAMERROR)); + + bool bUI = pRuntime->ToBoolean(newParams[0]); + WideString cTo; + if (IsTypeKnown(newParams[1])) { + cTo = pRuntime->ToWideString(newParams[1]); + } else { + // cTo parameter required when UI not invoked. + if (!bUI) + return CJS_Return(JSGetStringFromID(IDS_STRING_JSPARAMERROR)); + } + + WideString cCc; + if (IsTypeKnown(newParams[2])) + cCc = pRuntime->ToWideString(newParams[2]); + + WideString cBcc; + if (IsTypeKnown(newParams[3])) + cBcc = pRuntime->ToWideString(newParams[3]); + + WideString cSubject; + if (IsTypeKnown(newParams[4])) + cSubject = pRuntime->ToWideString(newParams[4]); + + WideString cMsg; + if (IsTypeKnown(newParams[5])) + cMsg = pRuntime->ToWideString(newParams[5]); + + pRuntime->BeginBlock(); + pRuntime->GetFormFillEnv()->JS_docmailForm(nullptr, 0, bUI, cTo.c_str(), + cSubject.c_str(), cCc.c_str(), + cBcc.c_str(), cMsg.c_str()); + pRuntime->EndBlock(); + return CJS_Return(true); +} + +CJS_Return app::launchURL(CJS_Runtime* pRuntime, + const std::vector>& params) { + // Unsafe, not supported. + return CJS_Return(true); +} + +CJS_Return app::get_runtime_highlight(CJS_Runtime* pRuntime) { + return CJS_Return(pRuntime->NewBoolean(m_bRuntimeHighLight)); +} + +CJS_Return app::set_runtime_highlight(CJS_Runtime* pRuntime, + v8::Local vp) { + m_bRuntimeHighLight = pRuntime->ToBoolean(vp); + return CJS_Return(true); +} + +CJS_Return app::get_fullscreen(CJS_Runtime* pRuntime) { + return CJS_Return(false); +} + +CJS_Return app::set_fullscreen(CJS_Runtime* pRuntime, v8::Local vp) { + return CJS_Return(false); +} + +CJS_Return app::popUpMenu(CJS_Runtime* pRuntime, + const std::vector>& params) { + return CJS_Return(false); +} + +CJS_Return app::browseForDoc(CJS_Runtime* pRuntime, + const std::vector>& params) { + // Unsafe, not supported. + return CJS_Return(true); +} + +WideString app::SysPathToPDFPath(const WideString& sOldPath) { + WideString sRet = L"/"; + for (const wchar_t& c : sOldPath) { + if (c != L':') + sRet += (c == L'\\') ? L'/' : c; + } + return sRet; +} + +CJS_Return app::newDoc(CJS_Runtime* pRuntime, + const std::vector>& params) { + return CJS_Return(false); +} + +CJS_Return app::openDoc(CJS_Runtime* pRuntime, + const std::vector>& params) { + return CJS_Return(false); +} + +CJS_Return app::response(CJS_Runtime* pRuntime, + const std::vector>& params) { + std::vector> newParams = + ExpandKeywordParams(pRuntime, params, 5, L"cQuestion", L"cTitle", + L"cDefault", L"bPassword", L"cLabel"); + + if (!IsTypeKnown(newParams[0])) + return CJS_Return(JSGetStringFromID(IDS_STRING_JSPARAMERROR)); + + WideString swQuestion = pRuntime->ToWideString(newParams[0]); + WideString swTitle = L"PDF"; + if (IsTypeKnown(newParams[1])) + swTitle = pRuntime->ToWideString(newParams[1]); + + WideString swDefault; + if (IsTypeKnown(newParams[2])) + swDefault = pRuntime->ToWideString(newParams[2]); + + bool bPassword = false; + if (IsTypeKnown(newParams[3])) + bPassword = pRuntime->ToBoolean(newParams[3]); + + WideString swLabel; + if (IsTypeKnown(newParams[4])) + swLabel = pRuntime->ToWideString(newParams[4]); + + const int MAX_INPUT_BYTES = 2048; + std::vector pBuff(MAX_INPUT_BYTES + 2); + int nLengthBytes = pRuntime->GetFormFillEnv()->JS_appResponse( + swQuestion.c_str(), swTitle.c_str(), swDefault.c_str(), swLabel.c_str(), + bPassword, pBuff.data(), MAX_INPUT_BYTES); + + if (nLengthBytes < 0 || nLengthBytes > MAX_INPUT_BYTES) + return CJS_Return(JSGetStringFromID(IDS_STRING_JSPARAM_TOOLONG)); + + return CJS_Return(pRuntime->NewString( + WideString::FromUTF16LE(reinterpret_cast(pBuff.data()), + nLengthBytes / sizeof(uint16_t)) + .c_str())); +} + +CJS_Return app::get_media(CJS_Runtime* pRuntime) { + return CJS_Return(false); +} + +CJS_Return app::set_media(CJS_Runtime* pRuntime, v8::Local vp) { + return CJS_Return(false); +} + +CJS_Return app::execDialog(CJS_Runtime* pRuntime, + const std::vector>& params) { + return CJS_Return(true); +} diff --git a/fpdfsdk/javascript/cjs_app.h b/fpdfsdk/javascript/cjs_app.h new file mode 100644 index 0000000000..b385d66186 --- /dev/null +++ b/fpdfsdk/javascript/cjs_app.h @@ -0,0 +1,169 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef FPDFSDK_JAVASCRIPT_CJS_APP_H_ +#define FPDFSDK_JAVASCRIPT_CJS_APP_H_ + +#include +#include +#include + +#include "fpdfsdk/javascript/JS_Define.h" + +class CJS_Runtime; +class GlobalTimer; + +class app : public CJS_EmbedObj { + public: + explicit app(CJS_Object* pJSObject); + ~app() override; + + CJS_Return get_active_docs(CJS_Runtime* pRuntime); + CJS_Return set_active_docs(CJS_Runtime* pRuntime, v8::Local vp); + + CJS_Return get_calculate(CJS_Runtime* pRuntime); + CJS_Return set_calculate(CJS_Runtime* pRuntime, v8::Local vp); + + CJS_Return get_forms_version(CJS_Runtime* pRuntime); + CJS_Return set_forms_version(CJS_Runtime* pRuntime, v8::Local vp); + + CJS_Return get_fs(CJS_Runtime* pRuntime); + CJS_Return set_fs(CJS_Runtime* pRuntime, v8::Local vp); + + CJS_Return get_fullscreen(CJS_Runtime* pRuntime); + CJS_Return set_fullscreen(CJS_Runtime* pRuntime, v8::Local vp); + + CJS_Return get_language(CJS_Runtime* pRuntime); + CJS_Return set_language(CJS_Runtime* pRuntime, v8::Local vp); + + CJS_Return get_media(CJS_Runtime* pRuntime); + CJS_Return set_media(CJS_Runtime* pRuntime, v8::Local vp); + + CJS_Return get_platform(CJS_Runtime* pRuntime); + CJS_Return set_platform(CJS_Runtime* pRuntime, v8::Local vp); + + CJS_Return get_runtime_highlight(CJS_Runtime* pRuntime); + CJS_Return set_runtime_highlight(CJS_Runtime* pRuntime, + v8::Local vp); + + CJS_Return get_viewer_type(CJS_Runtime* pRuntime); + CJS_Return set_viewer_type(CJS_Runtime* pRuntime, v8::Local vp); + + CJS_Return get_viewer_variation(CJS_Runtime* pRuntime); + CJS_Return set_viewer_variation(CJS_Runtime* pRuntime, + v8::Local vp); + + CJS_Return get_viewer_version(CJS_Runtime* pRuntime); + CJS_Return set_viewer_version(CJS_Runtime* pRuntime, v8::Local vp); + + CJS_Return alert(CJS_Runtime* pRuntime, + const std::vector>& params); + CJS_Return beep(CJS_Runtime* pRuntime, + const std::vector>& params); + CJS_Return browseForDoc(CJS_Runtime* pRuntime, + const std::vector>& params); + CJS_Return clearInterval(CJS_Runtime* pRuntime, + const std::vector>& params); + CJS_Return clearTimeOut(CJS_Runtime* pRuntime, + const std::vector>& params); + CJS_Return execDialog(CJS_Runtime* pRuntime, + const std::vector>& params); + CJS_Return execMenuItem(CJS_Runtime* pRuntime, + const std::vector>& params); + CJS_Return findComponent(CJS_Runtime* pRuntime, + const std::vector>& params); + CJS_Return goBack(CJS_Runtime* pRuntime, + const std::vector>& params); + CJS_Return goForward(CJS_Runtime* pRuntime, + const std::vector>& params); + CJS_Return launchURL(CJS_Runtime* pRuntime, + const std::vector>& params); + CJS_Return mailMsg(CJS_Runtime* pRuntime, + const std::vector>& params); + CJS_Return newFDF(CJS_Runtime* pRuntime, + const std::vector>& params); + CJS_Return newDoc(CJS_Runtime* pRuntime, + const std::vector>& params); + CJS_Return openDoc(CJS_Runtime* pRuntime, + const std::vector>& params); + CJS_Return openFDF(CJS_Runtime* pRuntime, + const std::vector>& params); + CJS_Return popUpMenuEx(CJS_Runtime* pRuntime, + const std::vector>& params); + CJS_Return popUpMenu(CJS_Runtime* pRuntime, + const std::vector>& params); + CJS_Return response(CJS_Runtime* pRuntime, + const std::vector>& params); + CJS_Return setInterval(CJS_Runtime* pRuntime, + const std::vector>& params); + CJS_Return setTimeOut(CJS_Runtime* pRuntime, + const std::vector>& params); + + void TimerProc(GlobalTimer* pTimer); + void CancelProc(GlobalTimer* pTimer); + + static WideString SysPathToPDFPath(const WideString& sOldPath); + + private: + // CJS_EmbedObj + void RunJsScript(CJS_Runtime* pRuntime, const WideString& wsScript); + + void ClearTimerCommon(CJS_Runtime* pRuntime, v8::Local param); + + bool m_bCalculate; + bool m_bRuntimeHighLight; + std::set> m_Timers; +}; + +class CJS_App : public CJS_Object { + public: + static void DefineJSObjects(CFXJS_Engine* pEngine); + + explicit CJS_App(v8::Local pObject) : CJS_Object(pObject) {} + ~CJS_App() override {} + + JS_STATIC_PROP(activeDocs, active_docs, app); + JS_STATIC_PROP(calculate, calculate, app); + JS_STATIC_PROP(formsVersion, forms_version, app); + JS_STATIC_PROP(fs, fs, app); + JS_STATIC_PROP(fullscreen, fullscreen, app); + JS_STATIC_PROP(language, language, app); + JS_STATIC_PROP(media, media, app); + JS_STATIC_PROP(platform, platform, app); + JS_STATIC_PROP(runtimeHighlight, runtime_highlight, app); + JS_STATIC_PROP(viewerType, viewer_type, app); + JS_STATIC_PROP(viewerVariation, viewer_variation, app); + JS_STATIC_PROP(viewerVersion, viewer_version, app); + + JS_STATIC_METHOD(alert, app); + JS_STATIC_METHOD(beep, app); + JS_STATIC_METHOD(browseForDoc, app); + JS_STATIC_METHOD(clearInterval, app); + JS_STATIC_METHOD(clearTimeOut, app); + JS_STATIC_METHOD(execDialog, app); + JS_STATIC_METHOD(execMenuItem, app); + JS_STATIC_METHOD(findComponent, app); + JS_STATIC_METHOD(goBack, app); + JS_STATIC_METHOD(goForward, app); + JS_STATIC_METHOD(launchURL, app); + JS_STATIC_METHOD(mailMsg, app); + JS_STATIC_METHOD(newFDF, app); + JS_STATIC_METHOD(newDoc, app); + JS_STATIC_METHOD(openDoc, app); + JS_STATIC_METHOD(openFDF, app); + JS_STATIC_METHOD(popUpMenuEx, app); + JS_STATIC_METHOD(popUpMenu, app); + JS_STATIC_METHOD(response, app); + JS_STATIC_METHOD(setInterval, app); + JS_STATIC_METHOD(setTimeOut, app); + + private: + static int ObjDefnID; + static const JSPropertySpec PropertySpecs[]; + static const JSMethodSpec MethodSpecs[]; +}; + +#endif // FPDFSDK_JAVASCRIPT_CJS_APP_H_ diff --git a/fpdfsdk/javascript/cjs_document.cpp b/fpdfsdk/javascript/cjs_document.cpp index df7001bd8f..1791db563b 100644 --- a/fpdfsdk/javascript/cjs_document.cpp +++ b/fpdfsdk/javascript/cjs_document.cpp @@ -19,8 +19,8 @@ #include "fpdfsdk/cpdfsdk_annotiteration.h" #include "fpdfsdk/cpdfsdk_interform.h" #include "fpdfsdk/cpdfsdk_pageview.h" -#include "fpdfsdk/javascript/app.h" #include "fpdfsdk/javascript/cjs_annot.h" +#include "fpdfsdk/javascript/cjs_app.h" #include "fpdfsdk/javascript/cjs_delaydata.h" #include "fpdfsdk/javascript/cjs_field.h" #include "fpdfsdk/javascript/cjs_icon.h" diff --git a/fpdfsdk/javascript/cjs_runtime.cpp b/fpdfsdk/javascript/cjs_runtime.cpp index b6b99ca839..d940f082d3 100644 --- a/fpdfsdk/javascript/cjs_runtime.cpp +++ b/fpdfsdk/javascript/cjs_runtime.cpp @@ -11,8 +11,8 @@ #include "fpdfsdk/cpdfsdk_formfillenvironment.h" #include "fpdfsdk/javascript/JS_Define.h" #include "fpdfsdk/javascript/JS_GlobalData.h" -#include "fpdfsdk/javascript/app.h" #include "fpdfsdk/javascript/cjs_annot.h" +#include "fpdfsdk/javascript/cjs_app.h" #include "fpdfsdk/javascript/cjs_border.h" #include "fpdfsdk/javascript/cjs_display.h" #include "fpdfsdk/javascript/cjs_document.h" @@ -32,6 +32,7 @@ #include "fpdfsdk/javascript/cjs_scalehow.h" #include "fpdfsdk/javascript/cjs_scalewhen.h" #include "fpdfsdk/javascript/cjs_style.h" +#include "fpdfsdk/javascript/cjs_timerobj.h" #include "fpdfsdk/javascript/cjs_zoomtype.h" #include "fpdfsdk/javascript/color.h" #include "fpdfsdk/javascript/console.h" diff --git a/fpdfsdk/javascript/cjs_timerobj.cpp b/fpdfsdk/javascript/cjs_timerobj.cpp new file mode 100644 index 0000000000..f0b90292c6 --- /dev/null +++ b/fpdfsdk/javascript/cjs_timerobj.cpp @@ -0,0 +1,32 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "fpdfsdk/javascript/cjs_timerobj.h" + +#include "fpdfsdk/javascript/global_timer.h" + +int CJS_TimerObj::ObjDefnID = -1; + +// static +int CJS_TimerObj::GetObjDefnID() { + return ObjDefnID; +} + +// static +void CJS_TimerObj::DefineJSObjects(CFXJS_Engine* pEngine) { + ObjDefnID = pEngine->DefineObj("TimerObj", FXJSOBJTYPE_DYNAMIC, + JSConstructor, + JSDestructor); +} + +TimerObj::TimerObj(CJS_Object* pJSObject) + : CJS_EmbedObj(pJSObject), m_nTimerID(0) {} + +TimerObj::~TimerObj() {} + +void TimerObj::SetTimer(GlobalTimer* pTimer) { + m_nTimerID = pTimer->GetTimerID(); +} diff --git a/fpdfsdk/javascript/cjs_timerobj.h b/fpdfsdk/javascript/cjs_timerobj.h new file mode 100644 index 0000000000..6ee7758a5c --- /dev/null +++ b/fpdfsdk/javascript/cjs_timerobj.h @@ -0,0 +1,38 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef FPDFSDK_JAVASCRIPT_CJS_TIMEROBJ_H_ +#define FPDFSDK_JAVASCRIPT_CJS_TIMEROBJ_H_ + +#include "fpdfsdk/javascript/JS_Define.h" + +class GlobalTimer; + +class TimerObj : public CJS_EmbedObj { + public: + explicit TimerObj(CJS_Object* pJSObject); + ~TimerObj() override; + + void SetTimer(GlobalTimer* pTimer); + int GetTimerID() const { return m_nTimerID; } + + private: + int m_nTimerID; // Weak reference to GlobalTimer through global map. +}; + +class CJS_TimerObj : public CJS_Object { + public: + static int GetObjDefnID(); + static void DefineJSObjects(CFXJS_Engine* pEngine); + + explicit CJS_TimerObj(v8::Local pObject) : CJS_Object(pObject) {} + ~CJS_TimerObj() override {} + + private: + static int ObjDefnID; +}; + +#endif // FPDFSDK_JAVASCRIPT_CJS_TIMEROBJ_H_ diff --git a/fpdfsdk/javascript/global_timer.cpp b/fpdfsdk/javascript/global_timer.cpp new file mode 100644 index 0000000000..8e30cf92f0 --- /dev/null +++ b/fpdfsdk/javascript/global_timer.cpp @@ -0,0 +1,80 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "fpdfsdk/javascript/global_timer.h" + +GlobalTimer::GlobalTimer(app* pObj, + CPDFSDK_FormFillEnvironment* pFormFillEnv, + CJS_Runtime* pRuntime, + int nType, + const WideString& script, + uint32_t dwElapse, + uint32_t dwTimeOut) + : m_nTimerID(0), + m_pEmbedObj(pObj), + m_bProcessing(false), + m_nType(nType), + m_dwTimeOut(dwTimeOut), + m_swJScript(script), + m_pRuntime(pRuntime), + m_pFormFillEnv(pFormFillEnv) { + CFX_SystemHandler* pHandler = m_pFormFillEnv->GetSysHandler(); + m_nTimerID = pHandler->SetTimer(dwElapse, Trigger); + if (m_nTimerID) + (*GetGlobalTimerMap())[m_nTimerID] = this; +} + +GlobalTimer::~GlobalTimer() { + if (!m_nTimerID) + return; + + if (GetRuntime()) + m_pFormFillEnv->GetSysHandler()->KillTimer(m_nTimerID); + + GetGlobalTimerMap()->erase(m_nTimerID); +} + +// static +void GlobalTimer::Trigger(int nTimerID) { + auto it = GetGlobalTimerMap()->find(nTimerID); + if (it == GetGlobalTimerMap()->end()) + return; + + GlobalTimer* pTimer = it->second; + if (pTimer->m_bProcessing) + return; + + pTimer->m_bProcessing = true; + if (pTimer->m_pEmbedObj) + pTimer->m_pEmbedObj->TimerProc(pTimer); + + // Timer proc may have destroyed timer, find it again. + it = GetGlobalTimerMap()->find(nTimerID); + if (it == GetGlobalTimerMap()->end()) + return; + + pTimer = it->second; + pTimer->m_bProcessing = false; + if (pTimer->IsOneShot()) + pTimer->m_pEmbedObj->CancelProc(pTimer); +} + +// static +void GlobalTimer::Cancel(int nTimerID) { + auto it = GetGlobalTimerMap()->find(nTimerID); + if (it == GetGlobalTimerMap()->end()) + return; + + GlobalTimer* pTimer = it->second; + pTimer->m_pEmbedObj->CancelProc(pTimer); +} + +// static +GlobalTimer::TimerMap* GlobalTimer::GetGlobalTimerMap() { + // Leak the timer array at shutdown. + static auto* s_TimerMap = new TimerMap; + return s_TimerMap; +} diff --git a/fpdfsdk/javascript/global_timer.h b/fpdfsdk/javascript/global_timer.h new file mode 100644 index 0000000000..bc65b976a9 --- /dev/null +++ b/fpdfsdk/javascript/global_timer.h @@ -0,0 +1,50 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef FPDFSDK_JAVASCRIPT_GLOBAL_TIMER_H_ +#define FPDFSDK_JAVASCRIPT_GLOBAL_TIMER_H_ + +#include + +#include "fpdfsdk/javascript/cjs_app.h" + +class GlobalTimer { + public: + GlobalTimer(app* pObj, + CPDFSDK_FormFillEnvironment* pFormFillEnv, + CJS_Runtime* pRuntime, + int nType, + const WideString& script, + uint32_t dwElapse, + uint32_t dwTimeOut); + ~GlobalTimer(); + + static void Trigger(int nTimerID); + static void Cancel(int nTimerID); + + bool IsOneShot() const { return m_nType == 1; } + uint32_t GetTimeOut() const { return m_dwTimeOut; } + int GetTimerID() const { return m_nTimerID; } + CJS_Runtime* GetRuntime() const { return m_pRuntime.Get(); } + WideString GetJScript() const { return m_swJScript; } + + private: + using TimerMap = std::map; + static TimerMap* GetGlobalTimerMap(); + + uint32_t m_nTimerID; + app* const m_pEmbedObj; + bool m_bProcessing; + + // data + const int m_nType; // 0:Interval; 1:TimeOut + const uint32_t m_dwTimeOut; + const WideString m_swJScript; + CJS_Runtime::ObservedPtr m_pRuntime; + CPDFSDK_FormFillEnvironment::ObservedPtr m_pFormFillEnv; +}; + +#endif // FPDFSDK_JAVASCRIPT_GLOBAL_TIMER_H_ -- cgit v1.2.3