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 "JS_Object.h" 8 9#include "JS_Context.h" 10#include "JS_Define.h" 11#include "fpdfsdk/include/fsdk_mgr.h" // For CPDFDoc_Environment. 12#include "fpdfsdk/include/javascript/IJavaScript.h" 13 14namespace { 15 16int FXJS_MsgBox(CPDFDoc_Environment* pApp, 17 const FX_WCHAR* swMsg, 18 const FX_WCHAR* swTitle, 19 FX_UINT nType, 20 FX_UINT nIcon) { 21 if (!pApp) 22 return 0; 23 24 if (CPDFSDK_Document* pDoc = pApp->GetSDKDocument()) 25 pDoc->KillFocusAnnot(); 26 27 return pApp->JS_appAlert(swMsg, swTitle, nType, nIcon); 28} 29 30} // namespace 31 32CJS_EmbedObj::CJS_EmbedObj(CJS_Object* pJSObject) : m_pJSObject(pJSObject) {} 33 34CJS_EmbedObj::~CJS_EmbedObj() { 35 m_pJSObject = NULL; 36} 37 38int CJS_EmbedObj::MsgBox(CPDFDoc_Environment* pApp, 39 const FX_WCHAR* swMsg, 40 const FX_WCHAR* swTitle, 41 FX_UINT nType, 42 FX_UINT nIcon) { 43 return FXJS_MsgBox(pApp, swMsg, swTitle, nType, nIcon); 44} 45 46void CJS_EmbedObj::Alert(CJS_Context* pContext, const FX_WCHAR* swMsg) { 47 CJS_Object::Alert(pContext, swMsg); 48} 49 50void FreeObject(const v8::WeakCallbackInfo<CJS_Object>& data) { 51 CJS_Object* pJSObj = data.GetParameter(); 52 pJSObj->ExitInstance(); 53 delete pJSObj; 54 FXJS_FreePrivate(data.GetInternalField(0)); 55} 56 57void DisposeObject(const v8::WeakCallbackInfo<CJS_Object>& data) { 58 CJS_Object* pJSObj = data.GetParameter(); 59 pJSObj->Dispose(); 60 data.SetSecondPassCallback(FreeObject); 61} 62 63CJS_Object::CJS_Object(v8::Local<v8::Object> pObject) { 64 m_pIsolate = pObject->GetIsolate(); 65 m_pV8Object.Reset(m_pIsolate, pObject); 66} 67 68CJS_Object::~CJS_Object() { 69} 70 71void CJS_Object::MakeWeak() { 72 m_pV8Object.SetWeak(this, DisposeObject, 73 v8::WeakCallbackType::kInternalFields); 74} 75 76void CJS_Object::Dispose() { 77 m_pV8Object.Reset(); 78} 79 80int CJS_Object::MsgBox(CPDFDoc_Environment* pApp, 81 const FX_WCHAR* swMsg, 82 const FX_WCHAR* swTitle, 83 FX_UINT nType, 84 FX_UINT nIcon) { 85 return FXJS_MsgBox(pApp, swMsg, swTitle, nType, nIcon); 86} 87 88void CJS_Object::Alert(CJS_Context* pContext, const FX_WCHAR* swMsg) { 89 if (pContext->IsMsgBoxEnabled()) { 90 CPDFDoc_Environment* pApp = pContext->GetReaderApp(); 91 if (pApp) 92 pApp->JS_appAlert(swMsg, NULL, 0, 3); 93 } 94} 95 96CJS_Timer::CJS_Timer(CJS_EmbedObj* pObj, 97 CPDFDoc_Environment* pApp, 98 CJS_Runtime* pRuntime, 99 int nType, 100 const CFX_WideString& script, 101 FX_DWORD dwElapse, 102 FX_DWORD dwTimeOut) 103 : m_nTimerID(0), 104 m_pEmbedObj(pObj), 105 m_bProcessing(false), 106 m_bValid(true), 107 m_nType(nType), 108 m_dwTimeOut(dwTimeOut), 109 m_swJScript(script), 110 m_pRuntime(pRuntime), 111 m_pApp(pApp) { 112 IFX_SystemHandler* pHandler = m_pApp->GetSysHandler(); 113 m_nTimerID = pHandler->SetTimer(dwElapse, TimerProc); 114 (*GetGlobalTimerMap())[m_nTimerID] = this; 115 m_pRuntime->AddObserver(this); 116} 117 118CJS_Timer::~CJS_Timer() { 119 CJS_Runtime* pRuntime = GetRuntime(); 120 if (pRuntime) 121 pRuntime->RemoveObserver(this); 122 KillJSTimer(); 123} 124 125void CJS_Timer::KillJSTimer() { 126 if (m_nTimerID) { 127 if (m_bValid) { 128 IFX_SystemHandler* pHandler = m_pApp->GetSysHandler(); 129 pHandler->KillTimer(m_nTimerID); 130 } 131 GetGlobalTimerMap()->erase(m_nTimerID); 132 m_nTimerID = 0; 133 } 134} 135 136// static 137void CJS_Timer::TimerProc(int idEvent) { 138 const auto it = GetGlobalTimerMap()->find(idEvent); 139 if (it != GetGlobalTimerMap()->end()) { 140 CJS_Timer* pTimer = it->second; 141 if (!pTimer->m_bProcessing) { 142 CFX_AutoRestorer<bool> scoped_processing(&pTimer->m_bProcessing); 143 pTimer->m_bProcessing = true; 144 if (pTimer->m_pEmbedObj) 145 pTimer->m_pEmbedObj->TimerProc(pTimer); 146 } 147 } 148} 149 150// static 151CJS_Timer::TimerMap* CJS_Timer::GetGlobalTimerMap() { 152 // Leak the timer array at shutdown. 153 static auto* s_TimerMap = new TimerMap; 154 return s_TimerMap; 155} 156 157void CJS_Timer::OnDestroyed() { 158 m_bValid = false; 159} 160