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 #ifndef FPDFSDK_INCLUDE_JAVASCRIPT_JS_OBJECT_H_
8 #define FPDFSDK_INCLUDE_JAVASCRIPT_JS_OBJECT_H_
9 
10 #include "../fsdk_define.h"  // For FX_UINT
11 #include "../fsdk_mgr.h"  // For CPDFDoc_Environment
12 #include "../fx_systemhandler.h"  // For IFX_SystemHandler
13 #include "../jsapi/fxjs_v8.h"
14 
15 class CPDFSDK_PageView;
16 class CJS_Object;
17 class CJS_Timer;
18 class CJS_Context;
19 
20 class CJS_EmbedObj
21 {
22 public:
23 	CJS_EmbedObj(CJS_Object* pJSObject);
24 	virtual ~CJS_EmbedObj();
25 
TimerProc(CJS_Timer * pTimer)26 	virtual void				TimerProc(CJS_Timer* pTimer){};
27 
28 	CJS_Timer*					BeginTimer(CPDFDoc_Environment * pApp, FX_UINT nElapse);
29 	void						EndTimer(CJS_Timer* pTimer);
30 
GetJSObject()31 	CJS_Object*					GetJSObject(){return m_pJSObject;};
32 	operator					CJS_Object* (){return m_pJSObject;};
33 
34 	CPDFSDK_PageView *			JSGetPageView(IFXJS_Context* cc);
35 	int							MsgBox(CPDFDoc_Environment* pApp, CPDFSDK_PageView* pPageView, FX_LPCWSTR swMsg, FX_LPCWSTR swTitle = NULL, FX_UINT nType = 0, FX_UINT nIcon = 0);
36 	void						Alert(CJS_Context* pContext, FX_LPCWSTR swMsg);
37 
38 protected:
39 	CJS_Object*					m_pJSObject;
40 };
41 
42 class CJS_Object
43 {
44 public:
45 	CJS_Object(JSFXObject pObject);
46 	virtual ~CJS_Object(void);
47 
48 	void						MakeWeak();
49         void                                            Dispose();
50 
IsType(FX_LPCSTR sClassName)51 	virtual FX_BOOL				IsType(FX_LPCSTR sClassName){return TRUE;};
GetClassName()52 	virtual CFX_ByteString		GetClassName(){return "";};
53 
InitInstance(IFXJS_Context * cc)54 	virtual FX_BOOL				InitInstance(IFXJS_Context* cc){return TRUE;};
ExitInstance()55 	virtual FX_BOOL				ExitInstance(){return TRUE;};
56 
JSFXObject()57 	operator					JSFXObject () {return v8::Local<v8::Object>::New(m_pIsolate, m_pObject);}
58 	operator					CJS_EmbedObj* (){return m_pEmbedObj;};
59 
SetEmbedObject(CJS_EmbedObj * pObj)60 	void						SetEmbedObject(CJS_EmbedObj* pObj){m_pEmbedObj = pObj;};
GetEmbedObject()61 	CJS_EmbedObj *				GetEmbedObject(){return m_pEmbedObj;};
62 
63 	static CPDFSDK_PageView *	JSGetPageView(IFXJS_Context* cc);
64 	static int					MsgBox(CPDFDoc_Environment* pApp, CPDFSDK_PageView* pPageView, FX_LPCWSTR swMsg, FX_LPCWSTR swTitle = NULL, FX_UINT nType = 0,FX_UINT nIcon = 0);
65 	static void					Alert(CJS_Context* pContext, FX_LPCWSTR swMsg);
66 
GetIsolate()67 	v8::Isolate*					GetIsolate() {return m_pIsolate;}
68 protected:
69 	CJS_EmbedObj *				m_pEmbedObj;
70 	v8::Global<v8::Object>			m_pObject;
71 	v8::Isolate*					m_pIsolate;
72 };
73 
74 struct JS_TIMER_MAP
75 {
76 	FX_UINT nID;
77 	CJS_Timer * pTimer;
78 };
79 
80 typedef CFX_ArrayTemplate<JS_TIMER_MAP*>	CTimerMapArray;
81 
82 struct JS_TIMER_MAPARRAY
83 {
84 public:
JS_TIMER_MAPARRAYJS_TIMER_MAPARRAY85 	JS_TIMER_MAPARRAY()
86 	{
87 	}
88 
~JS_TIMER_MAPARRAYJS_TIMER_MAPARRAY89 	~JS_TIMER_MAPARRAY()
90 	{
91 		Reset();
92 	}
93 
ResetJS_TIMER_MAPARRAY94 	void Reset()
95 	{
96 		for (int i=0,sz=m_Array.GetSize(); i<sz; i++)
97 			delete m_Array.GetAt(i);
98 
99 		m_Array.RemoveAll();
100 	}
101 
SetAtJS_TIMER_MAPARRAY102 	void SetAt(FX_UINT nIndex,CJS_Timer * pTimer)
103 	{
104 		int i = Find(nIndex);
105 
106 		if (i>=0)
107 		{
108 			if (JS_TIMER_MAP * pMap = m_Array.GetAt(i))
109 				pMap->pTimer = pTimer;
110 		}
111 		else
112 		{
113 			if (JS_TIMER_MAP * pMap = new JS_TIMER_MAP)
114 			{
115 				pMap->nID = nIndex;
116 				pMap->pTimer = pTimer;
117 				m_Array.Add(pMap);
118 			}
119 		}
120 	}
121 
GetAtJS_TIMER_MAPARRAY122 	CJS_Timer * GetAt(FX_UINT nIndex)
123 	{
124 		int i = Find(nIndex);
125 
126 		if (i>=0)
127 		{
128 			if (JS_TIMER_MAP * pMap = m_Array.GetAt(i))
129 				return pMap->pTimer;
130 		}
131 		return NULL;
132 	}
133 
RemoveAtJS_TIMER_MAPARRAY134 	void RemoveAt(FX_UINT nIndex)
135 	{
136 		int i = Find(nIndex);
137 
138 		if (i>=0)
139 		{
140 			delete m_Array.GetAt(i);
141 			m_Array.RemoveAt(i);
142 		}
143 		//To prevent potential fake memory leak reported by vc6.
144 		if(m_Array.GetSize() == 0)
145 			m_Array.RemoveAll();
146 	}
147 
FindJS_TIMER_MAPARRAY148 	int Find(FX_UINT nIndex)
149 	{
150 		for (int i=0,sz=m_Array.GetSize(); i<sz; i++)
151 		{
152 			if (JS_TIMER_MAP * pMap = m_Array.GetAt(i))
153 			{
154 				if (pMap->nID == nIndex)
155 					return i;
156 			}
157 		}
158 
159 		return -1;
160 	}
161 
162 	CTimerMapArray		m_Array;
163 };
164 
165 JS_TIMER_MAPARRAY& GetTimeMap();
166 
167 class CJS_Runtime;
168 
169 class CJS_Timer
170 {
171 public:
CJS_Timer(CJS_EmbedObj * pObj,CPDFDoc_Environment * pApp)172 	CJS_Timer(CJS_EmbedObj * pObj,CPDFDoc_Environment* pApp):
173 		m_nTimerID(0),
174 		m_pEmbedObj(pObj),
175 		m_bProcessing(FALSE),
176 		m_dwStartTime(0),
177 		m_dwTimeOut(0),
178 		m_dwElapse(0),
179 		m_pRuntime(NULL),
180 		m_nType(0),
181 		m_pApp(pApp)
182 	{
183 	}
184 
~CJS_Timer()185 	virtual ~CJS_Timer()
186 	{
187 		KillJSTimer();
188 	}
189 
190 public:
SetJSTimer(FX_UINT nElapse)191 	FX_UINT SetJSTimer(FX_UINT nElapse)
192 	{
193 		if (m_nTimerID)KillJSTimer();
194 		IFX_SystemHandler* pHandler = m_pApp->GetSysHandler();
195 		m_nTimerID = pHandler->SetTimer(nElapse,TimerProc);
196 		GetTimeMap().SetAt(m_nTimerID,this);
197 		m_dwElapse = nElapse;
198 		return m_nTimerID;
199 	};
200 
KillJSTimer()201 	void KillJSTimer()
202 	{
203 		if (m_nTimerID)
204 		{
205 			IFX_SystemHandler* pHandler = m_pApp->GetSysHandler();
206 			pHandler->KillTimer(m_nTimerID);
207 			GetTimeMap().RemoveAt(m_nTimerID);
208 			m_nTimerID = 0;
209 		}
210 	};
211 
SetType(int nType)212 	void SetType(int nType)
213 	{
214 		m_nType = nType;
215 	}
216 
GetType()217 	int GetType() const
218 	{
219 		return m_nType;
220 	}
221 
SetStartTime(FX_DWORD dwStartTime)222 	void SetStartTime(FX_DWORD dwStartTime)
223 	{
224 		m_dwStartTime = dwStartTime;
225 	}
226 
GetStartTime()227 	FX_DWORD GetStartTime() const
228 	{
229 		return m_dwStartTime;
230 	}
231 
SetTimeOut(FX_DWORD dwTimeOut)232 	void SetTimeOut(FX_DWORD dwTimeOut)
233 	{
234 		m_dwTimeOut = dwTimeOut;
235 	}
236 
GetTimeOut()237 	FX_DWORD GetTimeOut() const
238 	{
239 		return m_dwTimeOut;
240 	}
241 
SetRuntime(CJS_Runtime * pRuntime)242 	void SetRuntime(CJS_Runtime* pRuntime)
243 	{
244 		m_pRuntime = pRuntime;
245 	}
246 
GetRuntime()247 	CJS_Runtime* GetRuntime() const
248 	{
249 		return m_pRuntime;
250 	}
251 
SetJScript(const CFX_WideString & script)252 	void SetJScript(const CFX_WideString& script)
253 	{
254 		m_swJScript = script;
255 	}
256 
GetJScript()257 	CFX_WideString GetJScript() const
258 	{
259 		return m_swJScript;
260 	}
261 
TimerProc(int idEvent)262 	static void TimerProc(int idEvent)
263 	{
264 		if (CJS_Timer * pTimer = GetTimeMap().GetAt(idEvent))
265 		{
266 			if (!pTimer->m_bProcessing)
267 			{
268 				pTimer->m_bProcessing = TRUE;
269 				if (pTimer->m_pEmbedObj) pTimer->m_pEmbedObj->TimerProc(pTimer);
270 				pTimer->m_bProcessing = FALSE;
271 			}
272 			else
273 			{
274 			//	TRACE(L"BUSY!\n");
275 			}
276 		}
277 	};
278 
279 private:
280 	FX_UINT							m_nTimerID;
281 	CJS_EmbedObj*					m_pEmbedObj;
282 	FX_BOOL							m_bProcessing;
283 
284 	//data
285 	FX_DWORD							m_dwStartTime;
286 	FX_DWORD							m_dwTimeOut;
287 	FX_DWORD						m_dwElapse;
288 	CJS_Runtime*					m_pRuntime;
289 	CFX_WideString					m_swJScript;
290 	int								m_nType; //0:Interval; 1:TimeOut
291 
292 	CPDFDoc_Environment*			m_pApp;
293 };
294 
295 #endif  // FPDFSDK_INCLUDE_JAVASCRIPT_JS_OBJECT_H_
296