summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fpdfsdk/include/javascript/JS_Object.h63
-rw-r--r--fpdfsdk/include/javascript/JS_Runtime.h14
-rw-r--r--fpdfsdk/src/javascript/JS_Object.cpp58
-rw-r--r--fpdfsdk/src/javascript/JS_Runtime.cpp14
-rw-r--r--fpdfsdk/src/javascript/app.cpp27
5 files changed, 94 insertions, 82 deletions
diff --git a/fpdfsdk/include/javascript/JS_Object.h b/fpdfsdk/include/javascript/JS_Object.h
index 9fd7bff3d4..a2df9ec24b 100644
--- a/fpdfsdk/include/javascript/JS_Object.h
+++ b/fpdfsdk/include/javascript/JS_Object.h
@@ -15,11 +15,11 @@
#include "../fsdk_mgr.h" // For CPDFDoc_Environment
#include "../fx_systemhandler.h" // For IFX_SystemHandler
#include "../jsapi/fxjs_v8.h"
+#include "JS_Runtime.h"
class CPDFSDK_PageView;
class CJS_Context;
class CJS_Object;
-class CJS_Runtime;
class CJS_Timer;
class CJS_EmbedObj {
@@ -28,8 +28,6 @@ class CJS_EmbedObj {
virtual ~CJS_EmbedObj();
virtual void TimerProc(CJS_Timer* pTimer) {}
- CJS_Timer* BeginTimer(CPDFDoc_Environment* pApp, FX_UINT nElapse);
- void EndTimer(CJS_Timer* pTimer);
CJS_Object* GetJSObject() const { return m_pJSObject; }
@@ -85,38 +83,22 @@ class CJS_Object {
v8::Isolate* m_pIsolate;
};
-class CJS_Timer {
+class CJS_Timer : public CJS_Runtime::Observer {
public:
- CJS_Timer(CJS_EmbedObj* pObj, CPDFDoc_Environment* pApp)
- : m_nTimerID(0),
- m_pEmbedObj(pObj),
- m_bProcessing(FALSE),
- m_dwStartTime(0),
- m_dwTimeOut(0),
- m_dwElapse(0),
- m_pRuntime(NULL),
- m_nType(0),
- m_pApp(pApp) {}
-
- virtual ~CJS_Timer() { KillJSTimer(); }
+ CJS_Timer(CJS_EmbedObj* pObj,
+ CPDFDoc_Environment* pApp,
+ CJS_Runtime* pRuntime,
+ int nType,
+ const CFX_WideString& script,
+ FX_DWORD dwElapse,
+ FX_DWORD dwTimeOut);
+ ~CJS_Timer() override;
- public:
- FX_UINT SetJSTimer(FX_UINT nElapse);
void KillJSTimer();
- void SetType(int nType) { m_nType = nType; }
int GetType() const { return m_nType; }
-
- void SetStartTime(FX_DWORD dwStartTime) { m_dwStartTime = dwStartTime; }
- FX_DWORD GetStartTime() const { return m_dwStartTime; }
-
- void SetTimeOut(FX_DWORD dwTimeOut) { m_dwTimeOut = dwTimeOut; }
FX_DWORD GetTimeOut() const { return m_dwTimeOut; }
-
- void SetRuntime(CJS_Runtime* pRuntime) { m_pRuntime = pRuntime; }
- CJS_Runtime* GetRuntime() const { return m_pRuntime; }
-
- void SetJScript(const CFX_WideString& script) { m_swJScript = script; }
+ CJS_Runtime* GetRuntime() const { return m_bValid ? m_pRuntime : nullptr; }
CFX_WideString GetJScript() const { return m_swJScript; }
static void TimerProc(int idEvent);
@@ -125,19 +107,20 @@ class CJS_Timer {
using TimerMap = std::map<FX_UINT, CJS_Timer*>;
static TimerMap* GetGlobalTimerMap();
- FX_UINT m_nTimerID;
- CJS_EmbedObj* m_pEmbedObj;
- FX_BOOL m_bProcessing;
+ // CJS_Runtime::Observer
+ void OnDestroyed() override;
+
+ FX_DWORD m_nTimerID;
+ CJS_EmbedObj* const m_pEmbedObj;
+ bool m_bProcessing;
+ bool m_bValid;
// data
- FX_DWORD m_dwStartTime;
- FX_DWORD m_dwTimeOut;
- FX_DWORD m_dwElapse;
- CJS_Runtime* m_pRuntime;
- CFX_WideString m_swJScript;
- int m_nType; // 0:Interval; 1:TimeOut
-
- CPDFDoc_Environment* m_pApp;
+ const int m_nType; // 0:Interval; 1:TimeOut
+ const FX_DWORD m_dwTimeOut;
+ const CFX_WideString m_swJScript;
+ CJS_Runtime* const m_pRuntime;
+ CPDFDoc_Environment* const m_pApp;
};
#endif // FPDFSDK_INCLUDE_JAVASCRIPT_JS_OBJECT_H_
diff --git a/fpdfsdk/include/javascript/JS_Runtime.h b/fpdfsdk/include/javascript/JS_Runtime.h
index 5a811fca1f..0617597428 100644
--- a/fpdfsdk/include/javascript/JS_Runtime.h
+++ b/fpdfsdk/include/javascript/JS_Runtime.h
@@ -7,6 +7,8 @@
#ifndef FPDFSDK_INCLUDE_JAVASCRIPT_JS_RUNTIME_H_
#define FPDFSDK_INCLUDE_JAVASCRIPT_JS_RUNTIME_H_
+#include <set>
+
#include "../../../third_party/base/nonstd_unique_ptr.h"
#include "../../../core/include/fxcrt/fx_basic.h"
#include "../jsapi/fxjs_v8.h"
@@ -30,6 +32,14 @@ class CJS_FieldEvent {
class CJS_Runtime : public IFXJS_Runtime {
public:
+ class Observer {
+ public:
+ virtual void OnDestroyed() = 0;
+
+ protected:
+ virtual ~Observer() {}
+ };
+
CJS_Runtime(CPDFDoc_Environment* pApp);
~CJS_Runtime() override;
@@ -60,6 +70,9 @@ class CJS_Runtime : public IFXJS_Runtime {
v8::Local<v8::Context> NewJSContext();
+ void AddObserver(Observer* observer);
+ void RemoveObserver(Observer* observer);
+
protected:
CFX_ArrayTemplate<CJS_Context*> m_ContextArray;
CPDFDoc_Environment* m_pApp;
@@ -71,6 +84,7 @@ class CJS_Runtime : public IFXJS_Runtime {
bool m_isolateManaged;
nonstd::unique_ptr<CJS_ArrayBufferAllocator> m_pArrayBufferAllocator;
v8::Global<v8::Context> m_context;
+ std::set<Observer*> m_observers;
};
#endif // FPDFSDK_INCLUDE_JAVASCRIPT_JS_RUNTIME_H_
diff --git a/fpdfsdk/src/javascript/JS_Object.cpp b/fpdfsdk/src/javascript/JS_Object.cpp
index 02978982d8..b3b7bafb21 100644
--- a/fpdfsdk/src/javascript/JS_Object.cpp
+++ b/fpdfsdk/src/javascript/JS_Object.cpp
@@ -56,20 +56,6 @@ void CJS_EmbedObj::Alert(CJS_Context* pContext, const FX_WCHAR* swMsg) {
CJS_Object::Alert(pContext, swMsg);
}
-CJS_Timer* CJS_EmbedObj::BeginTimer(CPDFDoc_Environment* pApp,
- FX_UINT nElapse) {
- CJS_Timer* pTimer = new CJS_Timer(this, pApp);
- pTimer->SetJSTimer(nElapse);
-
- return pTimer;
-}
-
-void CJS_EmbedObj::EndTimer(CJS_Timer* pTimer) {
- ASSERT(pTimer != NULL);
- pTimer->KillJSTimer();
- delete pTimer;
-}
-
void FreeObject(const v8::WeakCallbackInfo<CJS_Object>& data) {
CJS_Object* pJSObj = data.GetParameter();
pJSObj->ExitInstance();
@@ -124,20 +110,40 @@ void CJS_Object::Alert(CJS_Context* pContext, const FX_WCHAR* swMsg) {
}
}
-FX_UINT CJS_Timer::SetJSTimer(FX_UINT nElapse) {
- if (m_nTimerID)
- KillJSTimer();
+CJS_Timer::CJS_Timer(CJS_EmbedObj* pObj,
+ CPDFDoc_Environment* pApp,
+ CJS_Runtime* pRuntime,
+ int nType,
+ const CFX_WideString& script,
+ FX_DWORD dwElapse,
+ FX_DWORD dwTimeOut)
+ : m_nTimerID(0),
+ m_pEmbedObj(pObj),
+ m_bProcessing(false),
+ m_bValid(true),
+ m_nType(nType),
+ m_dwTimeOut(dwTimeOut),
+ m_pRuntime(pRuntime),
+ m_pApp(pApp) {
IFX_SystemHandler* pHandler = m_pApp->GetSysHandler();
- m_nTimerID = pHandler->SetTimer(nElapse, TimerProc);
+ m_nTimerID = pHandler->SetTimer(dwElapse, TimerProc);
(*GetGlobalTimerMap())[m_nTimerID] = this;
- m_dwElapse = nElapse;
- return m_nTimerID;
+ m_pRuntime->AddObserver(this);
+}
+
+CJS_Timer::~CJS_Timer() {
+ CJS_Runtime* pRuntime = GetRuntime();
+ if (pRuntime)
+ pRuntime->RemoveObserver(this);
+ KillJSTimer();
}
void CJS_Timer::KillJSTimer() {
if (m_nTimerID) {
- IFX_SystemHandler* pHandler = m_pApp->GetSysHandler();
- pHandler->KillTimer(m_nTimerID);
+ if (m_bValid) {
+ IFX_SystemHandler* pHandler = m_pApp->GetSysHandler();
+ pHandler->KillTimer(m_nTimerID);
+ }
GetGlobalTimerMap()->erase(m_nTimerID);
m_nTimerID = 0;
}
@@ -149,10 +155,10 @@ void CJS_Timer::TimerProc(int idEvent) {
if (it != GetGlobalTimerMap()->end()) {
CJS_Timer* pTimer = it->second;
if (!pTimer->m_bProcessing) {
- pTimer->m_bProcessing = TRUE;
+ CFX_AutoRestorer<bool> scoped_processing(&pTimer->m_bProcessing);
+ pTimer->m_bProcessing = true;
if (pTimer->m_pEmbedObj)
pTimer->m_pEmbedObj->TimerProc(pTimer);
- pTimer->m_bProcessing = FALSE;
}
}
}
@@ -163,3 +169,7 @@ CJS_Timer::TimerMap* CJS_Timer::GetGlobalTimerMap() {
static auto* s_TimerMap = new TimerMap;
return s_TimerMap;
}
+
+void CJS_Timer::OnDestroyed() {
+ m_bValid = false;
+}
diff --git a/fpdfsdk/src/javascript/JS_Runtime.cpp b/fpdfsdk/src/javascript/JS_Runtime.cpp
index 4ef34a8d20..8efb277dd7 100644
--- a/fpdfsdk/src/javascript/JS_Runtime.cpp
+++ b/fpdfsdk/src/javascript/JS_Runtime.cpp
@@ -12,7 +12,6 @@
#include "../../include/javascript/JS_Define.h"
#include "../../include/javascript/JS_Object.h"
#include "../../include/javascript/JS_Value.h"
-#include "../../include/javascript/Document.h"
#include "../../include/javascript/app.h"
#include "../../include/javascript/color.h"
#include "../../include/javascript/Consts.h"
@@ -121,6 +120,9 @@ CJS_Runtime::CJS_Runtime(CPDFDoc_Environment* pApp)
}
CJS_Runtime::~CJS_Runtime() {
+ for (auto* obs : m_observers)
+ obs->OnDestroyed();
+
for (int i = 0, sz = m_ContextArray.GetSize(); i < sz; i++)
delete m_ContextArray.GetAt(i);
@@ -329,6 +331,16 @@ v8::Local<v8::Context> CJS_Runtime::NewJSContext() {
return v8::Local<v8::Context>::New(m_isolate, m_context);
}
+void CJS_Runtime::AddObserver(Observer* observer) {
+ ASSERT(m_observers.find(observer) == m_observers.end());
+ m_observers.insert(observer);
+}
+
+void CJS_Runtime::RemoveObserver(Observer* observer) {
+ ASSERT(m_observers.find(observer) != m_observers.end());
+ m_observers.erase(observer);
+}
+
CFX_WideString ChangeObjName(const CFX_WideString& str) {
CFX_WideString sRet = str;
sRet.Replace(L"_", L".");
diff --git a/fpdfsdk/src/javascript/app.cpp b/fpdfsdk/src/javascript/app.cpp
index 8d895ab260..b6da00fd69 100644
--- a/fpdfsdk/src/javascript/app.cpp
+++ b/fpdfsdk/src/javascript/app.cpp
@@ -414,16 +414,10 @@ FX_BOOL app::setInterval(IFXJS_Context* cc,
CPDFDoc_Environment* pApp = pRuntime->GetReaderApp();
ASSERT(pApp);
- CJS_Timer* pTimer = new CJS_Timer(this, pApp);
+ CJS_Timer* pTimer =
+ new CJS_Timer(this, pApp, pRuntime, 0, script, dwInterval, 0);
m_aTimer.Add(pTimer);
- pTimer->SetType(0);
- pTimer->SetRuntime(pRuntime);
- pTimer->SetJScript(script);
- pTimer->SetTimeOut(0);
- // pTimer->SetStartTime(GetTickCount());
- pTimer->SetJSTimer(dwInterval);
-
JSFXObject pRetObj = JS_NewFxDynamicObj(
*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"TimerObj"));
@@ -467,15 +461,10 @@ FX_BOOL app::setTimeOut(IFXJS_Context* cc,
CPDFDoc_Environment* pApp = pRuntime->GetReaderApp();
ASSERT(pApp);
- CJS_Timer* pTimer = new CJS_Timer(this, pApp);
+ CJS_Timer* pTimer =
+ new CJS_Timer(this, pApp, pRuntime, 1, script, dwTimeOut, dwTimeOut);
m_aTimer.Add(pTimer);
- pTimer->SetType(1);
- pTimer->SetRuntime(pRuntime);
- pTimer->SetJScript(script);
- pTimer->SetTimeOut(dwTimeOut);
- pTimer->SetJSTimer(dwTimeOut);
-
JSFXObject pRetObj = JS_NewFxDynamicObj(
*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"TimerObj"));
@@ -587,13 +576,17 @@ FX_BOOL app::execMenuItem(IFXJS_Context* cc,
void app::TimerProc(CJS_Timer* pTimer) {
ASSERT(pTimer != NULL);
+ CJS_Runtime* pRuntime = pTimer->GetRuntime();
+
switch (pTimer->GetType()) {
case 0: // interval
- RunJsScript(pTimer->GetRuntime(), pTimer->GetJScript());
+ if (pRuntime)
+ RunJsScript(pRuntime, pTimer->GetJScript());
break;
case 1:
if (pTimer->GetTimeOut() > 0) {
- RunJsScript(pTimer->GetRuntime(), pTimer->GetJScript());
+ if (pRuntime)
+ RunJsScript(pRuntime, pTimer->GetJScript());
pTimer->KillJSTimer();
}
break;