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