Kill off JS_ErrorString type.
[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, 6)
97         JS_STATIC_METHOD_ENTRY(beep, 1)
98         JS_STATIC_METHOD_ENTRY(browseForDoc, 0)
99         JS_STATIC_METHOD_ENTRY(clearInterval, 1)
100         JS_STATIC_METHOD_ENTRY(clearTimeOut, 1)
101         JS_STATIC_METHOD_ENTRY(execDialog, 3)
102         JS_STATIC_METHOD_ENTRY(execMenuItem,  1)
103         JS_STATIC_METHOD_ENTRY(findComponent, 1)
104         JS_STATIC_METHOD_ENTRY(goBack, 0)
105         JS_STATIC_METHOD_ENTRY(goForward, 0)
106         JS_STATIC_METHOD_ENTRY(launchURL, 0)
107         JS_STATIC_METHOD_ENTRY(mailMsg, 0)
108         JS_STATIC_METHOD_ENTRY(newFDF, 0)
109         JS_STATIC_METHOD_ENTRY(newDoc, 0)
110         JS_STATIC_METHOD_ENTRY(openDoc, 0)
111         JS_STATIC_METHOD_ENTRY(openFDF, 5)
112         JS_STATIC_METHOD_ENTRY(popUpMenuEx, 0)
113         JS_STATIC_METHOD_ENTRY(popUpMenu, 0)
114         JS_STATIC_METHOD_ENTRY(response, 0)
115         JS_STATIC_METHOD_ENTRY(setInterval, 2)
116         JS_STATIC_METHOD_ENTRY(setTimeOut, 2)
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];
329                         {
330                                 v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate, pObj, L"cMsg");
331                                 swMsg = CJS_Value(isolate,pValue,VT_unknown).operator CFX_WideString();
332
333                                 pValue = JS_GetObjectElement(isolate,pObj,L"cTitle");
334                                 swTitle = CJS_Value(isolate, pValue,VT_unknown).operator CFX_WideString();
335
336                                 pValue = JS_GetObjectElement(isolate,pObj,L"nIcon");
337                                 iIcon = (int)CJS_Value(isolate,pValue,VT_unknown);
338
339                                 pValue = JS_GetObjectElement(isolate,pObj,L"nType");
340                                 iType = (int)CJS_Value(isolate,pValue,VT_unknown);
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).operator CFX_WideString();
359                                                 if (i < iLenth - 1)
360                                                         swMsg += L",  ";
361                                         }
362
363                                         if(pValue) delete pValue;
364 //                                      if ((iLenth > 1) && pValue)
365 //                                      {
366 //                                              delete[]pValue;
367 //                                              pValue = NULL;
368 //                                      }
369 //                                      else if ((iLenth == 1) && pValue)
370 //                                      {
371 //                                              delete pValue;
372 //                                              pValue = NULL;
373 //                                      }
374                                 }
375                         }
376
377                         if (swTitle == L"")
378                                 swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
379                 }
380                 else if (params[0].GetType() == VT_boolean)
381                 {
382                         FX_BOOL bGet = (FX_BOOL)params[0];
383                         if (bGet)
384                                 swMsg = L"true";
385                         else
386                                 swMsg = L"false";
387
388                         swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
389                 }
390                 else
391                 {
392                         swMsg = params[0];
393                         swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
394                 }
395         }
396         else
397         {
398                 if (params[0].GetType() == VT_boolean)
399                 {
400                         FX_BOOL bGet = (FX_BOOL)params[0];
401                         if (bGet)
402                                 swMsg = L"true";
403                         else
404                                 swMsg = L"false";
405                 }
406                 else
407                 {
408                         swMsg = params[0];
409                 }
410                 swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
411
412                 for(int i = 1;i<iSize;i++)
413                 {
414                         if (i == 1)
415                                 iIcon = int(params[i]);
416                         if (i == 2)
417                                 iType = int(params[i]);
418                         if (i == 3)
419                                 swTitle = params[i];
420                 }
421         }
422
423
424         CJS_Context* pContext = (CJS_Context*)cc;
425         ASSERT(pContext != NULL);
426         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
427         ASSERT(pRuntime != NULL);
428         pRuntime->BeginBlock();
429         vRet = MsgBox(pRuntime->GetReaderApp(), JSGetPageView(cc),swMsg,swTitle,iType,iIcon);
430         pRuntime->EndBlock();
431
432         return TRUE;
433 }
434
435
436 FX_BOOL app::beep(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
437 {
438         if (params.size() == 1)
439         {
440                 CJS_Context* pContext = (CJS_Context*)cc;
441                 CJS_Runtime* pRuntime = pContext->GetJSRuntime();
442                 CPDFDoc_Environment * pEnv = pRuntime->GetReaderApp();
443                 pEnv->JS_appBeep((int)params[0]);
444
445                 return TRUE;
446         }
447         else
448         {
449                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
450                 return FALSE;
451         }
452 }
453
454 FX_BOOL app::findComponent(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
455 {
456         return TRUE;
457 }
458
459 FX_BOOL app::popUpMenuEx(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
460 {
461         return FALSE;
462 }
463
464 FX_BOOL app::fs(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
465 {
466         return FALSE;
467 }
468
469 FX_BOOL app::setInterval(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
470 {
471         if (params.size() > 2 || params.size() == 0)
472         {
473                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
474                 return FALSE;
475         }
476
477         CJS_Context* pContext = (CJS_Context*)cc;
478         ASSERT(pContext != NULL);
479         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
480         ASSERT(pRuntime != NULL);
481
482         CFX_WideString script = params.size() > 0 ?  (FX_LPCWSTR)(params[0].operator CFX_WideString()) : L"";
483         if (script.IsEmpty())
484         {
485                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSAFNUMBER_KEYSTROKE);
486                 return TRUE;
487         }
488
489         FX_DWORD dwInterval = params.size() > 1 ? (int)params[1] : 1000;
490
491         CPDFDoc_Environment* pApp = pRuntime->GetReaderApp();
492         ASSERT(pApp);
493         CJS_Timer* pTimer = new CJS_Timer(this, pApp);
494         m_aTimer.Add(pTimer);
495
496         pTimer->SetType(0);
497         pTimer->SetRuntime(pRuntime);
498         pTimer->SetJScript(script);
499         pTimer->SetTimeOut(0);
500 //      pTimer->SetStartTime(GetTickCount());
501         pTimer->SetJSTimer(dwInterval);
502
503         JSFXObject pRetObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"TimerObj"));
504
505         CJS_TimerObj* pJS_TimerObj = (CJS_TimerObj*)JS_GetPrivate(pRuntime->GetIsolate(),pRetObj);
506         ASSERT(pJS_TimerObj != NULL);
507
508         TimerObj* pTimerObj = (TimerObj*)pJS_TimerObj->GetEmbedObject();
509         ASSERT(pTimerObj != NULL);
510
511         pTimerObj->SetTimer(pTimer);
512
513         vRet = pRetObj;
514
515         return TRUE;
516 }
517
518 FX_BOOL app::setTimeOut(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
519 {
520         if (params.size() > 2 || params.size() == 0)
521         {
522                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
523                 return FALSE;
524         }
525
526         CJS_Context* pContext = (CJS_Context*)cc;
527         ASSERT(pContext != NULL);
528         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
529         ASSERT(pRuntime != NULL);
530
531         CFX_WideString script = params.size() > 0 ?  (FX_LPCWSTR)(params[0].operator CFX_WideString()) : L"";
532         if (script.IsEmpty())
533         {
534                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSAFNUMBER_KEYSTROKE);
535                 return TRUE;
536         }
537
538         FX_DWORD dwTimeOut = params.size() > 1 ? (int)params[1] : 1000;
539
540         CPDFDoc_Environment* pApp = pRuntime->GetReaderApp();
541         ASSERT(pApp);
542         CJS_Timer* pTimer = new CJS_Timer(this, pApp);
543         m_aTimer.Add(pTimer);
544
545         pTimer->SetType(1);
546         pTimer->SetRuntime(pRuntime);
547         pTimer->SetJScript(script);
548         pTimer->SetTimeOut(dwTimeOut);
549 //      pTimer->SetStartTime(GetTickCount());
550 //      pTimer->SetJSTimer(1000);
551         pTimer->SetJSTimer(dwTimeOut);
552
553         JSFXObject pRetObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"TimerObj"));
554 //      ASSERT(pRetObj != NULL);
555
556         CJS_TimerObj* pJS_TimerObj = (CJS_TimerObj*)JS_GetPrivate(pRuntime->GetIsolate(),pRetObj);
557         ASSERT(pJS_TimerObj != NULL);
558
559         TimerObj* pTimerObj = (TimerObj*)pJS_TimerObj->GetEmbedObject();
560         ASSERT(pTimerObj != NULL);
561
562         pTimerObj->SetTimer(pTimer);
563
564         vRet = pRetObj;
565
566         return TRUE;
567 }
568
569 FX_BOOL app::clearTimeOut(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
570 {
571         CJS_Context* pContext = (CJS_Context*)cc;
572         ASSERT(pContext != NULL);
573         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
574         ASSERT(pRuntime != NULL);
575
576         if (params.size() != 1)
577         {
578                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
579                 return FALSE;
580         }
581
582         if (params[0].GetType() == VT_fxobject)
583         {
584                 JSFXObject pObj = (JSFXObject)params[0];
585                 {
586                         if (JS_GetObjDefnID(pObj) == JS_GetObjDefnID(*pRuntime, L"TimerObj"))
587                         {
588                                 if (CJS_Object* pJSObj = (CJS_Object*)params[0])
589                                 {
590                                         if (TimerObj* pTimerObj = (TimerObj*)pJSObj->GetEmbedObject())
591                                         {
592                                                 if (CJS_Timer* pTimer = pTimerObj->GetTimer())
593                                                 {
594                                                         pTimer->KillJSTimer();
595
596                                                         for (int i=0,sz=m_aTimer.GetSize(); i<sz; i++)
597                                                         {
598                                                                 if (m_aTimer[i] == pTimer)
599                                                                 {
600                                                                         m_aTimer.RemoveAt(i);
601                                                                         break;
602                                                                 }
603                                                         }
604
605                                                         delete pTimer;
606                                                         pTimerObj->SetTimer(NULL);
607                                                 }
608                                         }
609                                 }
610                         }
611                 }
612         }
613
614         return TRUE;
615 }
616
617 FX_BOOL app::clearInterval(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
618 {
619         CJS_Context* pContext = (CJS_Context*)cc;
620         ASSERT(pContext != NULL);
621         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
622         ASSERT(pRuntime != NULL);
623
624         if (params.size() != 1)
625         {
626                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
627                 return FALSE;
628         }
629
630         if (params[0].GetType() == VT_fxobject)
631         {
632                 JSFXObject pObj = (JSFXObject)params[0];
633                 {
634                         if (JS_GetObjDefnID(pObj) == JS_GetObjDefnID(*pRuntime, L"TimerObj"))
635                         {
636                                 if (CJS_Object* pJSObj = (CJS_Object*)params[0])
637                                 {
638                                         if (TimerObj* pTimerObj = (TimerObj*)pJSObj->GetEmbedObject())
639                                         {
640                                                 if (CJS_Timer* pTimer = pTimerObj->GetTimer())
641                                                 {
642                                                         pTimer->KillJSTimer();
643
644                                                         for (int i=0,sz=m_aTimer.GetSize(); i<sz; i++)
645                                                         {
646                                                                 if (m_aTimer[i] == pTimer)
647                                                                 {
648                                                                         m_aTimer.RemoveAt(i);
649                                                                         break;
650                                                                 }
651                                                         }
652
653                                                         delete pTimer;
654                                                         pTimerObj->SetTimer(NULL);
655                                                 }
656                                         }
657                                 }
658                         }
659                 }
660         }
661
662         return TRUE;
663 }
664
665 FX_BOOL app::execMenuItem(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
666 {
667         return FALSE;
668 }
669
670 void app::TimerProc(CJS_Timer* pTimer)
671 {
672         ASSERT(pTimer != NULL);
673
674         switch (pTimer->GetType())
675         {
676         case 0: //interval
677                 RunJsScript(pTimer->GetRuntime(), pTimer->GetJScript());
678                 break;
679         case 1:
680                 if (pTimer->GetTimeOut() > 0)
681                 {
682                         RunJsScript(pTimer->GetRuntime(), pTimer->GetJScript());
683                         pTimer->KillJSTimer();
684                 }
685                 break;
686         }
687
688 }
689
690 void app::RunJsScript(CJS_Runtime* pRuntime,const CFX_WideString& wsScript)
691 {
692         ASSERT(pRuntime != NULL);
693
694         if (!pRuntime->IsBlocking())
695         {
696                 IFXJS_Context* pContext = pRuntime->NewContext();
697                 ASSERT(pContext != NULL);
698                 pContext->OnExternal_Exec();
699                 CFX_WideString wtInfo;
700                 pContext->RunScript(wsScript,wtInfo);
701                 pRuntime->ReleaseContext(pContext);
702         }
703 }
704
705 FX_BOOL app::goBack(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
706 {
707   // Not supported.
708   return TRUE;
709 }
710
711 FX_BOOL app::goForward(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
712 {
713   // Not supported.
714   return TRUE;
715 }
716
717 FX_BOOL app::mailMsg(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
718 {
719         CJS_Context* pContext = (CJS_Context*)cc;
720         ASSERT(pContext != NULL);
721
722         v8::Isolate* isolate = GetIsolate(cc);
723
724         FX_BOOL bUI = TRUE;
725         CFX_WideString cTo = L"";
726         CFX_WideString cCc = L"";
727         CFX_WideString cBcc = L"";
728         CFX_WideString cSubject = L"";
729         CFX_WideString cMsg = L"";
730         if(params.size() < 2)
731                 return FALSE;
732
733         bUI = params.size()>=1?(int)params[0]:TRUE;
734         cTo = params.size()>=2?(const wchar_t*)(FX_LPCWSTR)params[1].operator CFX_WideString():L"";
735         cCc = params.size()>=3?(const wchar_t*)(FX_LPCWSTR)params[2].operator CFX_WideString():L"";
736         cBcc = params.size()>=4?(const wchar_t*)(FX_LPCWSTR)params[3].operator CFX_WideString():L"";
737         cSubject = params.size()>=5?(const wchar_t*)(FX_LPCWSTR)params[4].operator CFX_WideString():L"";
738         cMsg = params.size()>=6?(const wchar_t*)(FX_LPCWSTR)params[5].operator CFX_WideString():L"";
739
740
741         if (params[0].GetType() == VT_object)
742         {
743                 JSObject pObj = (JSObject)params[0];
744
745                 v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj, L"bUI");
746                         bUI = (int)CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue));
747
748                 pValue = JS_GetObjectElement(isolate, pObj, L"cTo");
749                         cTo = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
750
751                 pValue = JS_GetObjectElement(isolate,pObj, L"cCc");
752                         cCc = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
753
754                 pValue = JS_GetObjectElement(isolate,pObj, L"cBcc");
755                         cBcc = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
756
757                 pValue = JS_GetObjectElement(isolate,pObj, L"cSubject");
758                         cSubject = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
759
760                 pValue = JS_GetObjectElement(isolate,pObj, L"cMsg");
761                         cMsg = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
762         }
763
764
765
766         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
767         ASSERT(pRuntime != NULL);
768
769         CPDFDoc_Environment* pApp = pContext->GetReaderApp();
770         ASSERT(pApp != NULL);
771
772         pRuntime->BeginBlock();
773         pApp->JS_docmailForm(NULL, 0, bUI, cTo.c_str(), cSubject.c_str(), cCc.c_str(), cBcc.c_str(), cMsg.c_str());
774         ///////////////////////////////////////////////////////////////////////////////////////////////
775         pRuntime->EndBlock();
776
777         //return bRet;
778         return FALSE;
779 }
780
781 FX_BOOL app::launchURL(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
782 {
783   // Unsafe, not supported.
784   return TRUE;
785 }
786
787 FX_BOOL app::runtimeHighlight(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
788 {
789         if (vp.IsSetting())
790         {
791                 vp>>m_bRuntimeHighLight;
792         }
793         else
794         {
795                 vp<<m_bRuntimeHighLight;
796         }
797
798         return TRUE;
799 }
800
801 FX_BOOL app::fullscreen(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
802 {
803         return FALSE;
804 }
805
806 FX_BOOL app::popUpMenu(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
807 {
808         return FALSE;
809 }
810
811
812 FX_BOOL app::browseForDoc(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
813 {
814   // Unsafe, not supported.
815   return TRUE;
816 }
817
818 CFX_WideString app::SysPathToPDFPath(const CFX_WideString& sOldPath)
819 {
820         CFX_WideString sRet = L"/";
821
822         for (int i=0,sz=sOldPath.GetLength(); i<sz; i++)
823         {
824                 wchar_t c = sOldPath.GetAt(i);
825                 if (c == L':')
826                 {
827                 }
828                 else
829                 {
830                         if (c == L'\\')
831                         {
832                                 sRet += L"/";
833                         }
834                         else
835                         {
836                                 sRet += c;
837                         }
838                 }
839         }
840
841         return sRet;
842 }
843
844 FX_BOOL app::newDoc(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
845 {
846         return FALSE;
847 }
848
849 FX_BOOL app::openDoc(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
850 {
851         return FALSE;
852 }
853
854 FX_BOOL app::response(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
855 {
856         CFX_WideString swQuestion = L"";
857         CFX_WideString swLabel = L"";
858         CFX_WideString swTitle = L"PDF";
859         CFX_WideString swDefault = L"";
860         bool bPassWord = false;
861
862         v8::Isolate* isolate = GetIsolate(cc);
863
864         int iLength = params.size();
865         if (iLength > 0 && params[0].GetType() == VT_object)
866         {
867                 JSObject pObj = (JSObject )params[0];
868                 v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj,L"cQuestion");
869                 swQuestion = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
870
871                 pValue = JS_GetObjectElement(isolate,pObj,L"cTitle");
872                 swTitle = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
873
874                 pValue = JS_GetObjectElement(isolate,pObj,L"cDefault");
875                 swDefault = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
876
877                 pValue = JS_GetObjectElement(isolate,pObj,L"cLabel");
878                 swLabel = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
879
880                 pValue = JS_GetObjectElement(isolate,pObj,L"bPassword");
881                 bPassWord = (bool)CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue));
882         }
883         else
884         {
885                 switch(iLength)
886                 {
887                 case 5:
888                         swLabel = params[4];
889                         // FALLTHROUGH
890                 case 4:
891                         bPassWord = params[3];
892                         // FALLTHROUGH
893                 case 3:
894                         swDefault = params[2];
895                         // FALLTHROUGH
896                 case 2:
897                         swTitle = params[1];
898                         // FALLTHROUGH
899                 case 1:
900                         swQuestion = params[0];
901                         // FALLTHROUGH
902                 default:
903                         break;
904                 }
905         }
906
907         CJS_Context* pContext = (CJS_Context *)cc;
908         ASSERT(pContext != NULL);
909
910         CPDFDoc_Environment* pApp = pContext->GetReaderApp();
911         ASSERT(pApp != NULL);
912
913         const int MAX_INPUT_BYTES = 2048;
914         char* pBuff = new char[MAX_INPUT_BYTES + 2];
915         if (!pBuff)
916                 return FALSE;
917
918         memset(pBuff, 0, MAX_INPUT_BYTES + 2);
919         int nLengthBytes = pApp->JS_appResponse(swQuestion, swTitle, swDefault, swLabel, bPassWord, pBuff, MAX_INPUT_BYTES);
920         if (nLengthBytes <= 0)
921         {
922                 vRet.SetNull();
923                 delete[] pBuff;
924                 return FALSE;
925         }
926         if (nLengthBytes > MAX_INPUT_BYTES)
927                 nLengthBytes = MAX_INPUT_BYTES;
928
929         vRet = CFX_WideString::FromUTF16LE((unsigned short*)pBuff, nLengthBytes / sizeof(unsigned short));
930         delete[] pBuff;
931         return TRUE;
932 }
933
934 FX_BOOL app::media(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
935 {
936         return FALSE;
937 }
938
939 FX_BOOL app::execDialog(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
940 {
941         return TRUE;
942 }