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
15class CPDFSDK_PageView;
16class CJS_Object;
17class CJS_Timer;
18class CJS_Context;
19
20class CJS_EmbedObj
21{
22public:
23	CJS_EmbedObj(CJS_Object* pJSObject);
24	virtual ~CJS_EmbedObj();
25
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
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
38protected:
39	CJS_Object*					m_pJSObject;
40};
41
42class CJS_Object
43{
44public:
45	CJS_Object(JSFXObject pObject);
46	virtual ~CJS_Object(void);
47
48	void						MakeWeak();
49        void                                            Dispose();
50
51	virtual FX_BOOL				IsType(FX_LPCSTR sClassName){return TRUE;};
52	virtual CFX_ByteString		GetClassName(){return "";};
53
54	virtual FX_BOOL				InitInstance(IFXJS_Context* cc){return TRUE;};
55	virtual FX_BOOL				ExitInstance(){return TRUE;};
56
57	operator					JSFXObject () {return v8::Local<v8::Object>::New(m_pIsolate, m_pObject);}
58	operator					CJS_EmbedObj* (){return m_pEmbedObj;};
59
60	void						SetEmbedObject(CJS_EmbedObj* pObj){m_pEmbedObj = pObj;};
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
67	v8::Isolate*					GetIsolate() {return m_pIsolate;}
68protected:
69	CJS_EmbedObj *				m_pEmbedObj;
70	v8::Global<v8::Object>			m_pObject;
71	v8::Isolate*					m_pIsolate;
72};
73
74struct JS_TIMER_MAP
75{
76	FX_UINT nID;
77	CJS_Timer * pTimer;
78};
79
80typedef CFX_ArrayTemplate<JS_TIMER_MAP*>	CTimerMapArray;
81
82struct JS_TIMER_MAPARRAY
83{
84public:
85	JS_TIMER_MAPARRAY()
86	{
87	}
88
89	~JS_TIMER_MAPARRAY()
90	{
91		Reset();
92	}
93
94	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
102	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
122	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
134	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
148	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
165JS_TIMER_MAPARRAY& GetTimeMap();
166
167class CJS_Runtime;
168
169class CJS_Timer
170{
171public:
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
185	virtual ~CJS_Timer()
186	{
187		KillJSTimer();
188	}
189
190public:
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
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
212	void SetType(int nType)
213	{
214		m_nType = nType;
215	}
216
217	int GetType() const
218	{
219		return m_nType;
220	}
221
222	void SetStartTime(FX_DWORD dwStartTime)
223	{
224		m_dwStartTime = dwStartTime;
225	}
226
227	FX_DWORD GetStartTime() const
228	{
229		return m_dwStartTime;
230	}
231
232	void SetTimeOut(FX_DWORD dwTimeOut)
233	{
234		m_dwTimeOut = dwTimeOut;
235	}
236
237	FX_DWORD GetTimeOut() const
238	{
239		return m_dwTimeOut;
240	}
241
242	void SetRuntime(CJS_Runtime* pRuntime)
243	{
244		m_pRuntime = pRuntime;
245	}
246
247	CJS_Runtime* GetRuntime() const
248	{
249		return m_pRuntime;
250	}
251
252	void SetJScript(const CFX_WideString& script)
253	{
254		m_swJScript = script;
255	}
256
257	CFX_WideString GetJScript() const
258	{
259		return m_swJScript;
260	}
261
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
279private:
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