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