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 14 namespace { 15 16 int 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 32 CJS_EmbedObj::CJS_EmbedObj(CJS_Object* pJSObject) : m_pJSObject(pJSObject) {} 33 34 CJS_EmbedObj::~CJS_EmbedObj() { 35 m_pJSObject = NULL; 36 } 37 38 int 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 46 void CJS_EmbedObj::Alert(CJS_Context* pContext, const FX_WCHAR* swMsg) { 47 CJS_Object::Alert(pContext, swMsg); 48 } 49 50 void 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 57 void DisposeObject(const v8::WeakCallbackInfo<CJS_Object>& data) { 58 CJS_Object* pJSObj = data.GetParameter(); 59 pJSObj->Dispose(); 60 data.SetSecondPassCallback(FreeObject); 61 } 62 63 CJS_Object::CJS_Object(v8::Local<v8::Object> pObject) { 64 m_pIsolate = pObject->GetIsolate(); 65 m_pV8Object.Reset(m_pIsolate, pObject); 66 } 67 68 CJS_Object::~CJS_Object() { 69 } 70 71 void CJS_Object::MakeWeak() { 72 m_pV8Object.SetWeak(this, DisposeObject, 73 v8::WeakCallbackType::kInternalFields); 74 } 75 76 void CJS_Object::Dispose() { 77 m_pV8Object.Reset(); 78 } 79 80 int 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 88 void 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 96 CJS_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 118 CJS_Timer::~CJS_Timer() { 119 CJS_Runtime* pRuntime = GetRuntime(); 120 if (pRuntime) 121 pRuntime->RemoveObserver(this); 122 KillJSTimer(); 123 } 124 125 void 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 137 void 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 151 CJS_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 157 void CJS_Timer::OnDestroyed() { 158 m_bValid = false; 159 } 160