Better error from pdfium_test when page too big to render.
[pdfium.git] / fpdfsdk / src / javascript / app.cpp
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 #include "../../include/javascript/JavaScript.h"
8 #include "../../include/javascript/IJavaScript.h"
9 #include "../../include/javascript/JS_Define.h"
10 #include "../../include/javascript/JS_Object.h"
11 #include "../../include/javascript/JS_Value.h"
12 #include "../../include/javascript/app.h"
13 #include "../../include/javascript/JS_EventHandler.h"
14 #include "../../include/javascript/resource.h"
15 #include "../../include/javascript/JS_Context.h"
16 #include "../../include/javascript/JS_Runtime.h"
17 #include "../../include/javascript/Document.h"
18
19
20 static v8::Isolate* GetIsolate(IFXJS_Context* cc)
21 {
22         CJS_Context* pContext = (CJS_Context *)cc;
23         ASSERT(pContext != NULL);
24
25         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
26         ASSERT(pRuntime != NULL);
27
28         return pRuntime->GetIsolate();
29 }
30
31 /* ---------------------------- TimerObj ---------------------------- */
32
33 BEGIN_JS_STATIC_CONST(CJS_TimerObj)
34 END_JS_STATIC_CONST()
35
36 BEGIN_JS_STATIC_PROP(CJS_TimerObj)
37 END_JS_STATIC_PROP()
38
39 BEGIN_JS_STATIC_METHOD(CJS_TimerObj)
40 END_JS_STATIC_METHOD()
41
42 IMPLEMENT_JS_CLASS(CJS_TimerObj, TimerObj)
43
44 TimerObj::TimerObj(CJS_Object* pJSObject)
45 : CJS_EmbedObj(pJSObject),
46 m_pTimer(NULL)
47 {
48
49 }
50
51 TimerObj::~TimerObj()
52 {
53 }
54
55 void TimerObj::SetTimer(CJS_Timer* pTimer)
56 {
57         m_pTimer = pTimer;
58 }
59
60 CJS_Timer* TimerObj::GetTimer() const
61 {
62         return m_pTimer;
63 }
64
65 #define JS_STR_VIEWERTYPE_READER                L"Reader"
66 #define JS_STR_VIEWERTYPE_STANDARD              L"Exchange"
67 #define JS_STR_VIEWERVARIATION                  L"Full"
68 #define JS_STR_PLATFORM                                 L"WIN"
69 #define JS_STR_LANGUANGE                                L"ENU"
70 #define JS_STR_VIEWERVERSION                    8
71 #define JS_NUM_FORMSVERSION                             7
72
73 #define JS_FILEPATH_MAXLEN                              2000
74
75 /* ---------------------------- app ---------------------------- */
76
77 BEGIN_JS_STATIC_CONST(CJS_App)
78 END_JS_STATIC_CONST()
79
80 BEGIN_JS_STATIC_PROP(CJS_App)
81         JS_STATIC_PROP_ENTRY(activeDocs)
82         JS_STATIC_PROP_ENTRY(calculate)
83         JS_STATIC_PROP_ENTRY(formsVersion)
84         JS_STATIC_PROP_ENTRY(fs)
85         JS_STATIC_PROP_ENTRY(fullscreen)
86         JS_STATIC_PROP_ENTRY(language)
87         JS_STATIC_PROP_ENTRY(media)
88         JS_STATIC_PROP_ENTRY(platform)
89         JS_STATIC_PROP_ENTRY(runtimeHighlight)
90         JS_STATIC_PROP_ENTRY(viewerType)
91         JS_STATIC_PROP_ENTRY(viewerVariation)
92         JS_STATIC_PROP_ENTRY(viewerVersion)
93 END_JS_STATIC_PROP()
94
95 BEGIN_JS_STATIC_METHOD(CJS_App)
96         JS_STATIC_METHOD_ENTRY(alert)
97         JS_STATIC_METHOD_ENTRY(beep)
98         JS_STATIC_METHOD_ENTRY(browseForDoc)
99         JS_STATIC_METHOD_ENTRY(clearInterval)
100         JS_STATIC_METHOD_ENTRY(clearTimeOut)
101         JS_STATIC_METHOD_ENTRY(execDialog)
102         JS_STATIC_METHOD_ENTRY(execMenuItem)
103         JS_STATIC_METHOD_ENTRY(findComponent)
104         JS_STATIC_METHOD_ENTRY(goBack)
105         JS_STATIC_METHOD_ENTRY(goForward)
106         JS_STATIC_METHOD_ENTRY(launchURL)
107         JS_STATIC_METHOD_ENTRY(mailMsg)
108         JS_STATIC_METHOD_ENTRY(newFDF)
109         JS_STATIC_METHOD_ENTRY(newDoc)
110         JS_STATIC_METHOD_ENTRY(openDoc)
111         JS_STATIC_METHOD_ENTRY(openFDF)
112         JS_STATIC_METHOD_ENTRY(popUpMenuEx)
113         JS_STATIC_METHOD_ENTRY(popUpMenu)
114         JS_STATIC_METHOD_ENTRY(response)
115         JS_STATIC_METHOD_ENTRY(setInterval)
116         JS_STATIC_METHOD_ENTRY(setTimeOut)
117 END_JS_STATIC_METHOD()
118
119 IMPLEMENT_JS_CLASS(CJS_App,app)
120
121 app::app(CJS_Object * pJSObject) : CJS_EmbedObj(pJSObject) ,
122         m_bCalculate(true),
123         m_bRuntimeHighLight(false)
124 //      m_pMenuHead(NULL)
125 {
126 }
127
128 app::~app(void)
129 {
130         for (int i=0,sz=m_aTimer.GetSize(); i<sz; i++)
131                 delete m_aTimer[i];
132
133         m_aTimer.RemoveAll();
134 }
135
136 FX_BOOL app::activeDocs(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
137 {
138         if (vp.IsGetting())
139         {
140
141                 CJS_Context* pContext = (CJS_Context *)cc;
142                 ASSERT(pContext != NULL);
143
144                 CPDFDoc_Environment* pApp = pContext->GetReaderApp();
145                 ASSERT(pApp != NULL);
146
147                 CJS_Runtime* pRuntime = pContext->GetJSRuntime();
148                 ASSERT(pRuntime != NULL);
149
150                 CPDFSDK_Document* pCurDoc = pContext->GetReaderDocument();
151
152                 CJS_Array aDocs(pRuntime->GetIsolate());
153 //              int iNumDocs = pApp->CountDocuments();
154
155 //              for(int iIndex = 0; iIndex<iNumDocs; iIndex++)
156 //              {
157                         CPDFSDK_Document* pDoc = pApp->GetCurrentDoc();
158                         if (pDoc)
159                         {
160                                 CJS_Document * pJSDocument = NULL;
161
162                                 if (pDoc == pCurDoc)
163                                 {
164                                         JSFXObject pObj = JS_GetThisObj(*pRuntime);
165
166                                         if (JS_GetObjDefnID(pObj) == JS_GetObjDefnID(*pRuntime, L"Document"))
167                                         {
168                                                 pJSDocument = (CJS_Document*)JS_GetPrivate(pRuntime->GetIsolate(),pObj);
169                                         }
170                                 }
171                                 else
172                                 {
173                                         JSFXObject pObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime,L"Document"));
174                                         pJSDocument = (CJS_Document*)JS_GetPrivate(pRuntime->GetIsolate(),pObj);
175                                         ASSERT(pJSDocument != NULL);
176
177
178                                         //                      pDocument->AttachDoc(pDoc);
179                                 }
180
181                                 aDocs.SetElement(0,CJS_Value(pRuntime->GetIsolate(),pJSDocument));
182                         }
183         //              }
184
185                 if (aDocs.GetLength() > 0)
186                         vp << aDocs;
187                 else
188                         vp.SetNull();
189                 return TRUE;
190         }
191         return FALSE;
192 }
193
194 FX_BOOL app::calculate(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
195 {
196         if (vp.IsSetting())
197         {
198                 bool bVP;
199                 vp >> bVP;
200                 m_bCalculate = (FX_BOOL)bVP;
201
202                 CJS_Context* pContext = (CJS_Context*)cc;
203                 ASSERT(pContext != NULL);
204
205                 CPDFDoc_Environment* pApp = pContext->GetReaderApp();
206                 ASSERT(pApp != NULL);
207
208                 CJS_Runtime* pRuntime = pContext->GetJSRuntime();
209                 ASSERT(pRuntime != NULL);
210
211                 CJS_Array aDocs(pRuntime->GetIsolate());
212                 if (CPDFSDK_Document* pDoc = pApp->GetCurrentDoc())
213                 {
214                         CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)pDoc->GetInterForm();
215                         ASSERT(pInterForm != NULL);
216                         pInterForm->EnableCalculate((FX_BOOL)m_bCalculate);
217                 }
218         }
219         else
220         {
221                 vp << (bool)m_bCalculate;
222         }
223
224         return TRUE;
225 }
226
227 FX_BOOL app::formsVersion(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
228 {
229         if (vp.IsGetting())
230         {
231                 vp << JS_NUM_FORMSVERSION;
232                 return TRUE;
233         }
234
235         return FALSE;
236 }
237
238 FX_BOOL app::viewerType(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
239 {
240         if (vp.IsGetting())
241         {
242                 vp << L"unknown";
243                 return TRUE;
244         }
245
246         return FALSE;
247 }
248
249 FX_BOOL app::viewerVariation(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
250 {
251         if (vp.IsGetting())
252         {
253                 vp << JS_STR_VIEWERVARIATION;
254                 return TRUE;
255         }
256
257         return FALSE;
258 }
259
260 FX_BOOL app::viewerVersion(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
261 {
262         if (vp.IsGetting())
263         {
264                 vp << JS_STR_VIEWERVERSION;
265                 return TRUE;
266         }
267
268         return FALSE;
269 }
270
271 FX_BOOL app::platform(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
272 {
273         if (vp.IsGetting())
274         {
275                 vp << JS_STR_PLATFORM;
276                 return TRUE;
277         }
278
279         return FALSE;
280 }
281
282 FX_BOOL app::language(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
283 {
284         if (vp.IsGetting())
285         {
286                 vp << JS_STR_LANGUANGE;
287                 return TRUE;
288         }
289
290         return FALSE;
291 }
292
293 //creates a new fdf object that contains no data
294 //comment: need reader support
295 //note:
296 //CFDF_Document * CPDFDoc_Environment::NewFDF();
297 FX_BOOL app::newFDF(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
298 {
299         return TRUE;
300 }
301 //opens a specified pdf document and returns its document object
302 //comment:need reader support
303 //note: as defined in js reference, the proto of this function's fourth parmeters, how old an fdf document while do not show it.
304 //CFDF_Document * CPDFDoc_Environment::OpenFDF(string strPath,bool bUserConv);
305
306 FX_BOOL app::openFDF(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
307 {
308         return TRUE;
309 }
310
311 FX_BOOL app::alert(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
312 {
313         int iSize = params.size();
314         if (iSize < 1)
315                 return FALSE;
316
317         CFX_WideString swMsg = L"";
318         CFX_WideString swTitle = L"";
319         int iIcon = 0;
320         int iType = 0;
321
322         v8::Isolate* isolate = GetIsolate(cc);
323
324         if (iSize == 1)
325         {
326                 if (params[0].GetType() == VT_object)
327                 {
328                         JSObject pObj = params[0].ToV8Object();
329                         {
330                                 v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate, pObj, L"cMsg");
331                                 swMsg = CJS_Value(isolate, pValue, VT_unknown).ToCFXWideString();
332
333                                 pValue = JS_GetObjectElement(isolate, pObj, L"cTitle");
334                                 swTitle = CJS_Value(isolate, pValue, VT_unknown).ToCFXWideString();
335
336                                 pValue = JS_GetObjectElement(isolate, pObj, L"nIcon");
337                                 iIcon = CJS_Value(isolate, pValue, VT_unknown).ToInt();
338
339                                 pValue = JS_GetObjectElement(isolate, pObj, L"nType");
340                                 iType = CJS_Value(isolate, pValue, VT_unknown).ToInt();
341                         }
342
343                         if (swMsg == L"")
344                         {
345                                 CJS_Array carray(isolate);
346                                 if (params[0].ConvertToArray(carray))
347                                 {
348                                         int iLenth = carray.GetLength();
349                                         CJS_Value* pValue = new CJS_Value(isolate);
350 //                                      if (iLenth == 1)
351 //                                              pValue = new CJS_Value(isolate);
352 //                                      else if (iLenth > 1)
353 //                                              pValue = new CJS_Value[iLenth];
354
355                                         for(int i = 0; i < iLenth; i++)
356                                         {
357                                                 carray.GetElement(i, *pValue);
358                                                 swMsg += (*pValue).ToCFXWideString();
359                                                 if (i < iLenth - 1)
360                                                         swMsg += L",  ";
361                                         }
362
363                                         if(pValue) delete pValue;
364                                 }
365                         }
366
367                         if (swTitle == L"")
368                                 swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
369                 }
370                 else if (params[0].GetType() == VT_boolean)
371                 {
372                         FX_BOOL bGet = params[0].ToBool();
373                         if (bGet)
374                                 swMsg = L"true";
375                         else
376                                 swMsg = L"false";
377
378                         swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
379                 }
380                 else
381                 {
382                         swMsg = params[0].ToCFXWideString();
383                         swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
384                 }
385         }
386         else
387         {
388                 if (params[0].GetType() == VT_boolean)
389                 {
390                         FX_BOOL bGet = params[0].ToBool();
391                         if (bGet)
392                                 swMsg = L"true";
393                         else
394                                 swMsg = L"false";
395                 }
396                 else
397                 {
398                         swMsg = params[0].ToCFXWideString();
399                 }
400                 swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
401
402                 for(int i = 1;i<iSize;i++)
403                 {
404                         if (i == 1)
405                                 iIcon = params[i].ToInt();
406                         if (i == 2)
407                                 iType = params[i].ToInt();
408                         if (i == 3)
409                                 swTitle = params[i].ToCFXWideString();
410                 }
411         }
412
413
414         CJS_Context* pContext = (CJS_Context*)cc;
415         ASSERT(pContext != NULL);
416         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
417         ASSERT(pRuntime != NULL);
418         pRuntime->BeginBlock();
419         vRet = MsgBox(pRuntime->GetReaderApp(), JSGetPageView(cc), swMsg.c_str(), swTitle.c_str(), iType, iIcon);
420         pRuntime->EndBlock();
421
422         return TRUE;
423 }
424
425
426 FX_BOOL app::beep(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
427 {
428         if (params.size() == 1)
429         {
430                 CJS_Context* pContext = (CJS_Context*)cc;
431                 CJS_Runtime* pRuntime = pContext->GetJSRuntime();
432                 CPDFDoc_Environment * pEnv = pRuntime->GetReaderApp();
433                 pEnv->JS_appBeep(params[0].ToInt());
434                 return TRUE;
435         }
436
437         sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
438         return FALSE;
439 }
440
441 FX_BOOL app::findComponent(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
442 {
443         return TRUE;
444 }
445
446 FX_BOOL app::popUpMenuEx(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
447 {
448         return FALSE;
449 }
450
451 FX_BOOL app::fs(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
452 {
453         return FALSE;
454 }
455
456 FX_BOOL app::setInterval(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
457 {
458         CJS_Context* pContext = (CJS_Context*)cc;
459         if (params.size() > 2 || params.size() == 0)
460         {
461                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
462                 return FALSE;
463         }
464
465         CFX_WideString script = params.size() > 0 ?  params[0].ToCFXWideString() : L"";
466         if (script.IsEmpty())
467         {
468                 sError = JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE);
469                 return TRUE;
470         }
471
472         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
473         FX_DWORD dwInterval = params.size() > 1 ? params[1].ToInt() : 1000;
474
475         CPDFDoc_Environment* pApp = pRuntime->GetReaderApp();
476         ASSERT(pApp);
477         CJS_Timer* pTimer = new CJS_Timer(this, pApp);
478         m_aTimer.Add(pTimer);
479
480         pTimer->SetType(0);
481         pTimer->SetRuntime(pRuntime);
482         pTimer->SetJScript(script);
483         pTimer->SetTimeOut(0);
484 //      pTimer->SetStartTime(GetTickCount());
485         pTimer->SetJSTimer(dwInterval);
486
487         JSFXObject pRetObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"TimerObj"));
488
489         CJS_TimerObj* pJS_TimerObj = (CJS_TimerObj*)JS_GetPrivate(pRuntime->GetIsolate(),pRetObj);
490         ASSERT(pJS_TimerObj != NULL);
491
492         TimerObj* pTimerObj = (TimerObj*)pJS_TimerObj->GetEmbedObject();
493         ASSERT(pTimerObj != NULL);
494
495         pTimerObj->SetTimer(pTimer);
496
497         vRet = pRetObj;
498
499         return TRUE;
500 }
501
502 FX_BOOL app::setTimeOut(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
503 {
504         if (params.size() > 2 || params.size() == 0)
505         {
506                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
507                 return FALSE;
508         }
509
510         CJS_Context* pContext = (CJS_Context*)cc;
511         ASSERT(pContext != NULL);
512         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
513         ASSERT(pRuntime != NULL);
514
515         CFX_WideString script = params.size() > 0 ? params[0].ToCFXWideString() : L"";
516         if (script.IsEmpty())
517         {
518                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSAFNUMBER_KEYSTROKE);
519                 return TRUE;
520         }
521
522         FX_DWORD dwTimeOut = params.size() > 1 ? params[1].ToInt() : 1000;
523
524         CPDFDoc_Environment* pApp = pRuntime->GetReaderApp();
525         ASSERT(pApp);
526
527         CJS_Timer* pTimer = new CJS_Timer(this, pApp);
528         m_aTimer.Add(pTimer);
529
530         pTimer->SetType(1);
531         pTimer->SetRuntime(pRuntime);
532         pTimer->SetJScript(script);
533         pTimer->SetTimeOut(dwTimeOut);
534         pTimer->SetJSTimer(dwTimeOut);
535
536         JSFXObject pRetObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"TimerObj"));
537
538         CJS_TimerObj* pJS_TimerObj = (CJS_TimerObj*)JS_GetPrivate(pRuntime->GetIsolate(),pRetObj);
539         ASSERT(pJS_TimerObj != NULL);
540
541         TimerObj* pTimerObj = (TimerObj*)pJS_TimerObj->GetEmbedObject();
542         ASSERT(pTimerObj != NULL);
543
544         pTimerObj->SetTimer(pTimer);
545
546         vRet = pRetObj;
547
548         return TRUE;
549 }
550
551 FX_BOOL app::clearTimeOut(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
552 {
553         CJS_Context* pContext = (CJS_Context*)cc;
554         ASSERT(pContext != NULL);
555         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
556         ASSERT(pRuntime != NULL);
557
558         if (params.size() != 1)
559         {
560                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
561                 return FALSE;
562         }
563
564         if (params[0].GetType() == VT_fxobject)
565         {
566                 JSFXObject pObj = params[0].ToV8Object();
567                 {
568                         if (JS_GetObjDefnID(pObj) == JS_GetObjDefnID(*pRuntime, L"TimerObj"))
569                         {
570                                 if (CJS_Object* pJSObj = params[0].ToCJSObject())
571                                 {
572                                         if (TimerObj* pTimerObj = (TimerObj*)pJSObj->GetEmbedObject())
573                                         {
574                                                 if (CJS_Timer* pTimer = pTimerObj->GetTimer())
575                                                 {
576                                                         pTimer->KillJSTimer();
577
578                                                         for (int i=0,sz=m_aTimer.GetSize(); i<sz; i++)
579                                                         {
580                                                                 if (m_aTimer[i] == pTimer)
581                                                                 {
582                                                                         m_aTimer.RemoveAt(i);
583                                                                         break;
584                                                                 }
585                                                         }
586
587                                                         delete pTimer;
588                                                         pTimerObj->SetTimer(NULL);
589                                                 }
590                                         }
591                                 }
592                         }
593                 }
594         }
595
596         return TRUE;
597 }
598
599 FX_BOOL app::clearInterval(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
600 {
601         CJS_Context* pContext = (CJS_Context*)cc;
602         ASSERT(pContext != NULL);
603         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
604         ASSERT(pRuntime != NULL);
605
606         if (params.size() != 1)
607         {
608                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
609                 return FALSE;
610         }
611
612         if (params[0].GetType() == VT_fxobject)
613         {
614                 JSFXObject pObj = params[0].ToV8Object();
615                 {
616                         if (JS_GetObjDefnID(pObj) == JS_GetObjDefnID(*pRuntime, L"TimerObj"))
617                         {
618                                 if (CJS_Object* pJSObj = params[0].ToCJSObject())
619                                 {
620                                         if (TimerObj* pTimerObj = (TimerObj*)pJSObj->GetEmbedObject())
621                                         {
622                                                 if (CJS_Timer* pTimer = pTimerObj->GetTimer())
623                                                 {
624                                                         pTimer->KillJSTimer();
625
626                                                         for (int i=0,sz=m_aTimer.GetSize(); i<sz; i++)
627                                                         {
628                                                                 if (m_aTimer[i] == pTimer)
629                                                                 {
630                                                                         m_aTimer.RemoveAt(i);
631                                                                         break;
632                                                                 }
633                                                         }
634
635                                                         delete pTimer;
636                                                         pTimerObj->SetTimer(NULL);
637                                                 }
638                                         }
639                                 }
640                         }
641                 }
642         }
643
644         return TRUE;
645 }
646
647 FX_BOOL app::execMenuItem(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
648 {
649         return FALSE;
650 }
651
652 void app::TimerProc(CJS_Timer* pTimer)
653 {
654         ASSERT(pTimer != NULL);
655
656         switch (pTimer->GetType())
657         {
658         case 0: //interval
659                 RunJsScript(pTimer->GetRuntime(), pTimer->GetJScript());
660                 break;
661         case 1:
662                 if (pTimer->GetTimeOut() > 0)
663                 {
664                         RunJsScript(pTimer->GetRuntime(), pTimer->GetJScript());
665                         pTimer->KillJSTimer();
666                 }
667                 break;
668         }
669
670 }
671
672 void app::RunJsScript(CJS_Runtime* pRuntime,const CFX_WideString& wsScript)
673 {
674         ASSERT(pRuntime != NULL);
675
676         if (!pRuntime->IsBlocking())
677         {
678                 IFXJS_Context* pContext = pRuntime->NewContext();
679                 ASSERT(pContext != NULL);
680                 pContext->OnExternal_Exec();
681                 CFX_WideString wtInfo;
682                 pContext->RunScript(wsScript,wtInfo);
683                 pRuntime->ReleaseContext(pContext);
684         }
685 }
686
687 FX_BOOL app::goBack(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
688 {
689   // Not supported.
690   return TRUE;
691 }
692
693 FX_BOOL app::goForward(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
694 {
695   // Not supported.
696   return TRUE;
697 }
698
699 FX_BOOL app::mailMsg(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
700 {
701         CJS_Context* pContext = (CJS_Context*)cc;
702         v8::Isolate* isolate = GetIsolate(cc);
703
704         FX_BOOL bUI = TRUE;
705         CFX_WideString cTo = L"";
706         CFX_WideString cCc = L"";
707         CFX_WideString cBcc = L"";
708         CFX_WideString cSubject = L"";
709         CFX_WideString cMsg = L"";
710
711         if (params.size() < 1)
712                 return FALSE;
713
714         if (params[0].GetType() == VT_object)
715         {
716                 JSObject pObj = params[0].ToV8Object();
717
718                 v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate, pObj, L"bUI");
719                 bUI = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue)).ToBool();
720
721                 pValue = JS_GetObjectElement(isolate, pObj, L"cTo");
722                 cTo = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
723
724                 pValue = JS_GetObjectElement(isolate, pObj, L"cCc");
725                 cCc = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
726
727                 pValue = JS_GetObjectElement(isolate, pObj, L"cBcc");
728                 cBcc = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
729
730                 pValue = JS_GetObjectElement(isolate, pObj, L"cSubject");
731                 cSubject = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
732
733                 pValue = JS_GetObjectElement(isolate, pObj, L"cMsg");
734                 cMsg = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
735         } else {
736                 if (params.size() < 2)
737                         return FALSE;
738
739                 bUI = params[0].ToBool();
740                 cTo = params[1].ToCFXWideString();
741
742                 if (params.size() >= 3)
743                         cCc = params[2].ToCFXWideString();
744                 if (params.size() >= 4)
745                         cBcc = params[3].ToCFXWideString();
746                 if (params.size() >= 5)
747                         cSubject = params[4].ToCFXWideString();
748                 if (params.size() >= 6)
749                         cMsg = params[5].ToCFXWideString();
750         }
751
752         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
753         ASSERT(pRuntime != NULL);
754
755         CPDFDoc_Environment* pApp = pContext->GetReaderApp();
756         ASSERT(pApp != NULL);
757
758         pRuntime->BeginBlock();
759         pApp->JS_docmailForm(NULL, 0, bUI, cTo.c_str(), cSubject.c_str(), cCc.c_str(), cBcc.c_str(), cMsg.c_str());
760         pRuntime->EndBlock();
761
762         return FALSE;
763 }
764
765 FX_BOOL app::launchURL(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
766 {
767   // Unsafe, not supported.
768   return TRUE;
769 }
770
771 FX_BOOL app::runtimeHighlight(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
772 {
773         if (vp.IsSetting())
774         {
775                 vp>>m_bRuntimeHighLight;
776         }
777         else
778         {
779                 vp<<m_bRuntimeHighLight;
780         }
781
782         return TRUE;
783 }
784
785 FX_BOOL app::fullscreen(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
786 {
787         return FALSE;
788 }
789
790 FX_BOOL app::popUpMenu(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
791 {
792         return FALSE;
793 }
794
795
796 FX_BOOL app::browseForDoc(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
797 {
798   // Unsafe, not supported.
799   return TRUE;
800 }
801
802 CFX_WideString app::SysPathToPDFPath(const CFX_WideString& sOldPath)
803 {
804         CFX_WideString sRet = L"/";
805
806         for (int i=0,sz=sOldPath.GetLength(); i<sz; i++)
807         {
808                 wchar_t c = sOldPath.GetAt(i);
809                 if (c == L':')
810                 {
811                 }
812                 else
813                 {
814                         if (c == L'\\')
815                         {
816                                 sRet += L"/";
817                         }
818                         else
819                         {
820                                 sRet += c;
821                         }
822                 }
823         }
824
825         return sRet;
826 }
827
828 FX_BOOL app::newDoc(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
829 {
830         return FALSE;
831 }
832
833 FX_BOOL app::openDoc(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
834 {
835         return FALSE;
836 }
837
838 FX_BOOL app::response(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
839 {
840         CFX_WideString swQuestion = L"";
841         CFX_WideString swLabel = L"";
842         CFX_WideString swTitle = L"PDF";
843         CFX_WideString swDefault = L"";
844         bool bPassWord = false;
845
846         v8::Isolate* isolate = GetIsolate(cc);
847
848         int iLength = params.size();
849         if (iLength > 0 && params[0].GetType() == VT_object)
850         {
851                 JSObject pObj = params[0].ToV8Object();
852                 v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj,L"cQuestion");
853                 swQuestion = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).ToCFXWideString();
854
855                 pValue = JS_GetObjectElement(isolate,pObj,L"cTitle");
856                 swTitle = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).ToCFXWideString();
857
858                 pValue = JS_GetObjectElement(isolate,pObj,L"cDefault");
859                 swDefault = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).ToCFXWideString();
860
861                 pValue = JS_GetObjectElement(isolate,pObj,L"cLabel");
862                 swLabel = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).ToCFXWideString();
863
864                 pValue = JS_GetObjectElement(isolate,pObj,L"bPassword");
865                 bPassWord = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).ToBool();
866         }
867         else
868         {
869                 switch(iLength)
870                 {
871                 case 5:
872                         swLabel = params[4].ToCFXWideString();
873                         // FALLTHROUGH
874                 case 4:
875                         bPassWord = params[3].ToBool();
876                         // FALLTHROUGH
877                 case 3:
878                         swDefault = params[2].ToCFXWideString();
879                         // FALLTHROUGH
880                 case 2:
881                         swTitle = params[1].ToCFXWideString();
882                         // FALLTHROUGH
883                 case 1:
884                         swQuestion = params[0].ToCFXWideString();
885                         // FALLTHROUGH
886                 default:
887                         break;
888                 }
889         }
890
891         CJS_Context* pContext = (CJS_Context *)cc;
892         ASSERT(pContext != NULL);
893
894         CPDFDoc_Environment* pApp = pContext->GetReaderApp();
895         ASSERT(pApp != NULL);
896
897         const int MAX_INPUT_BYTES = 2048;
898         char* pBuff = new char[MAX_INPUT_BYTES + 2];
899         if (!pBuff)
900                 return FALSE;
901
902         memset(pBuff, 0, MAX_INPUT_BYTES + 2);
903         int nLengthBytes = pApp->JS_appResponse(swQuestion.c_str(), swTitle.c_str(), swDefault.c_str(),
904                                             swLabel.c_str(), bPassWord, pBuff, MAX_INPUT_BYTES);
905         if (nLengthBytes <= 0)
906         {
907                 vRet.SetNull();
908                 delete[] pBuff;
909                 return FALSE;
910         }
911         if (nLengthBytes > MAX_INPUT_BYTES)
912                 nLengthBytes = MAX_INPUT_BYTES;
913
914         vRet = CFX_WideString::FromUTF16LE((unsigned short*)pBuff, nLengthBytes / sizeof(unsigned short)).c_str();
915         delete[] pBuff;
916         return TRUE;
917 }
918
919 FX_BOOL app::media(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
920 {
921         return FALSE;
922 }
923
924 FX_BOOL app::execDialog(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
925 {
926         return TRUE;
927 }