Merge to XFA: Kill overloaded cast operators in CJS_Value.
[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_STR_VIEWERVERSION_XFA                11
72 #define JS_NUM_FORMSVERSION                             7
73
74 #define JS_FILEPATH_MAXLEN                              2000
75
76 /* ---------------------------- app ---------------------------- */
77
78 BEGIN_JS_STATIC_CONST(CJS_App)
79 END_JS_STATIC_CONST()
80
81 BEGIN_JS_STATIC_PROP(CJS_App)
82         JS_STATIC_PROP_ENTRY(activeDocs)
83         JS_STATIC_PROP_ENTRY(calculate)
84         JS_STATIC_PROP_ENTRY(formsVersion)
85         JS_STATIC_PROP_ENTRY(fs)
86         JS_STATIC_PROP_ENTRY(fullscreen)
87         JS_STATIC_PROP_ENTRY(language)
88         JS_STATIC_PROP_ENTRY(media)
89         JS_STATIC_PROP_ENTRY(platform)
90         JS_STATIC_PROP_ENTRY(runtimeHighlight)
91         JS_STATIC_PROP_ENTRY(viewerType)
92         JS_STATIC_PROP_ENTRY(viewerVariation)
93         JS_STATIC_PROP_ENTRY(viewerVersion)
94 END_JS_STATIC_PROP()
95
96 BEGIN_JS_STATIC_METHOD(CJS_App)
97         JS_STATIC_METHOD_ENTRY(alert, 6)
98         JS_STATIC_METHOD_ENTRY(beep, 1)
99         JS_STATIC_METHOD_ENTRY(browseForDoc, 0)
100         JS_STATIC_METHOD_ENTRY(clearInterval, 1)
101         JS_STATIC_METHOD_ENTRY(clearTimeOut, 1)
102         JS_STATIC_METHOD_ENTRY(execDialog, 3)
103         JS_STATIC_METHOD_ENTRY(execMenuItem,  1)
104         JS_STATIC_METHOD_ENTRY(findComponent, 1)
105         JS_STATIC_METHOD_ENTRY(goBack, 0)
106         JS_STATIC_METHOD_ENTRY(goForward, 0)
107         JS_STATIC_METHOD_ENTRY(launchURL, 0)
108         JS_STATIC_METHOD_ENTRY(mailMsg, 0)
109         JS_STATIC_METHOD_ENTRY(newFDF, 0)
110         JS_STATIC_METHOD_ENTRY(newDoc, 0)
111         JS_STATIC_METHOD_ENTRY(openDoc, 0)
112         JS_STATIC_METHOD_ENTRY(openFDF, 5)
113         JS_STATIC_METHOD_ENTRY(popUpMenuEx, 0)
114         JS_STATIC_METHOD_ENTRY(popUpMenu, 0)
115         JS_STATIC_METHOD_ENTRY(response, 0)
116         JS_STATIC_METHOD_ENTRY(setInterval, 2)
117         JS_STATIC_METHOD_ENTRY(setTimeOut, 2)
118 END_JS_STATIC_METHOD()
119
120 IMPLEMENT_JS_CLASS(CJS_App,app)
121
122 app::app(CJS_Object * pJSObject) : CJS_EmbedObj(pJSObject) ,
123         m_bCalculate(true),
124         m_bRuntimeHighLight(false)
125 //      m_pMenuHead(NULL)
126 {
127 }
128
129 app::~app(void)
130 {
131         for (int i=0,sz=m_aTimer.GetSize(); i<sz; i++)
132                 delete m_aTimer[i];
133
134         m_aTimer.RemoveAll();
135 }
136
137 FX_BOOL app::activeDocs(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
138 {
139         if (vp.IsGetting())
140         {
141
142                 CJS_Context* pContext = (CJS_Context *)cc;
143                 ASSERT(pContext != NULL);
144
145                 CPDFDoc_Environment* pApp = pContext->GetReaderApp();
146                 ASSERT(pApp != NULL);
147
148                 CJS_Runtime* pRuntime = pContext->GetJSRuntime();
149                 ASSERT(pRuntime != NULL);
150
151                 CPDFSDK_Document* pCurDoc = pContext->GetReaderDocument();
152
153                 CJS_Array aDocs(pRuntime->GetIsolate());
154 //              int iNumDocs = pApp->CountDocuments();
155
156 //              for(int iIndex = 0; iIndex<iNumDocs; iIndex++)
157 //              {
158                         CPDFSDK_Document* pDoc = pApp->GetCurrentDoc();
159                         if (pDoc)
160                         {
161                                 CJS_Document * pJSDocument = NULL;
162
163                                 if (pDoc == pCurDoc)
164                                 {
165                                         JSFXObject pObj = JS_GetThisObj(*pRuntime);
166
167                                         if (JS_GetObjDefnID(pObj) == JS_GetObjDefnID(*pRuntime, L"Document"))
168                                         {
169                                                 pJSDocument = (CJS_Document*)JS_GetPrivate(pRuntime->GetIsolate(),pObj);
170                                         }
171                                 }
172                                 else
173                                 {
174                                         JSFXObject pObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime,L"Document"));
175                                         pJSDocument = (CJS_Document*)JS_GetPrivate(pRuntime->GetIsolate(),pObj);
176                                         ASSERT(pJSDocument != NULL);
177
178
179                                         //                      pDocument->AttachDoc(pDoc);
180                                 }
181
182                                 aDocs.SetElement(0,CJS_Value(pRuntime->GetIsolate(),pJSDocument));
183                         }
184         //              }
185
186                 if (aDocs.GetLength() > 0)
187                         vp << aDocs;
188                 else
189                         vp.SetNull();
190                 return TRUE;
191         }
192         return FALSE;
193 }
194
195 FX_BOOL app::calculate(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
196 {
197         if (vp.IsSetting())
198         {
199                 bool bVP;
200                 vp >> bVP;
201                 m_bCalculate = (FX_BOOL)bVP;
202
203                 CJS_Context* pContext = (CJS_Context*)cc;
204                 ASSERT(pContext != NULL);
205
206                 CPDFDoc_Environment* pApp = pContext->GetReaderApp();
207                 ASSERT(pApp != NULL);
208
209                 CJS_Runtime* pRuntime = pContext->GetJSRuntime();
210                 ASSERT(pRuntime != NULL);
211
212                 CJS_Array aDocs(pRuntime->GetIsolate());
213                 if (CPDFSDK_Document* pDoc = pApp->GetCurrentDoc())
214                 {
215                         CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)pDoc->GetInterForm();
216                         ASSERT(pInterForm != NULL);
217                         pInterForm->EnableCalculate((FX_BOOL)m_bCalculate);
218                 }
219         }
220         else
221         {
222                 vp << (bool)m_bCalculate;
223         }
224
225         return TRUE;
226 }
227
228 FX_BOOL app::formsVersion(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
229 {
230         if (vp.IsGetting())
231         {
232                 vp << JS_NUM_FORMSVERSION;
233                 return TRUE;
234         }
235
236         return FALSE;
237 }
238
239 FX_BOOL app::viewerType(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
240 {
241         if (vp.IsGetting())
242         {
243                 vp << L"unknown";
244                 return TRUE;
245         }
246
247         return FALSE;
248 }
249
250 FX_BOOL app::viewerVariation(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
251 {
252         if (vp.IsGetting())
253         {
254                 vp << JS_STR_VIEWERVARIATION;
255                 return TRUE;
256         }
257
258         return FALSE;
259 }
260
261 FX_BOOL app::viewerVersion(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
262 {
263         if (vp.IsGetting())
264         {
265                 CJS_Context* pContext = (CJS_Context *)cc;
266                 ASSERT(pContext != NULL);
267
268                 CPDFDoc_Environment* pApp = pContext->GetReaderApp();
269                 ASSERT(pApp != NULL);
270
271                 CPDFSDK_Document* pCurDoc = pContext->GetReaderDocument();
272
273                 CPDFXFA_Document* pDoc = pCurDoc->GetDocument();
274                 if (pDoc->GetDocType() == 1 || pDoc->GetDocType() == 2)
275                         vp << JS_STR_VIEWERVERSION_XFA;
276                 else
277                         vp << JS_STR_VIEWERVERSION;
278                 return TRUE;
279         }
280
281         return FALSE;
282 }
283
284 FX_BOOL app::platform(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
285 {
286         if (vp.IsGetting())
287         {
288                 vp << JS_STR_PLATFORM;
289                 return TRUE;
290         }
291
292         return FALSE;
293 }
294
295 FX_BOOL app::language(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
296 {
297         if (vp.IsGetting())
298         {
299                 vp << JS_STR_LANGUANGE;
300                 return TRUE;
301         }
302
303         return FALSE;
304 }
305
306 //creates a new fdf object that contains no data
307 //comment: need reader support
308 //note:
309 //CFDF_Document * CPDFDoc_Environment::NewFDF();
310 FX_BOOL app::newFDF(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
311 {
312         return TRUE;
313 }
314 //opens a specified pdf document and returns its document object
315 //comment:need reader support
316 //note: as defined in js reference, the proto of this function's fourth parmeters, how old an fdf document while do not show it.
317 //CFDF_Document * CPDFDoc_Environment::OpenFDF(string strPath,bool bUserConv);
318
319 FX_BOOL app::openFDF(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
320 {
321         return TRUE;
322 }
323
324 FX_BOOL app::alert(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
325 {
326         int iSize = params.size();
327         if (iSize < 1)
328                 return FALSE;
329
330         CFX_WideString swMsg = L"";
331         CFX_WideString swTitle = L"";
332         int iIcon = 0;
333         int iType = 0;
334
335         v8::Isolate* isolate = GetIsolate(cc);
336
337         if (iSize == 1)
338         {
339                 if (params[0].GetType() == VT_object)
340                 {
341                         JSObject pObj = params[0].ToV8Object();
342                         {
343                                 v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate, pObj, L"cMsg");
344                                 swMsg = CJS_Value(isolate, pValue, VT_unknown).ToCFXWideString();
345
346                                 pValue = JS_GetObjectElement(isolate, pObj, L"cTitle");
347                                 swTitle = CJS_Value(isolate, pValue, VT_unknown).ToCFXWideString();
348
349                                 pValue = JS_GetObjectElement(isolate, pObj, L"nIcon");
350                                 iIcon = CJS_Value(isolate, pValue, VT_unknown).ToInt();
351
352                                 pValue = JS_GetObjectElement(isolate, pObj, L"nType");
353                                 iType = CJS_Value(isolate, pValue, VT_unknown).ToInt();
354                         }
355
356                         if (swMsg == L"")
357                         {
358                                 CJS_Array carray(isolate);
359                                 if (params[0].ConvertToArray(carray))
360                                 {
361                                         int iLenth = carray.GetLength();
362                                         CJS_Value* pValue = new CJS_Value(isolate);
363 //                                      if (iLenth == 1)
364 //                                              pValue = new CJS_Value(isolate);
365 //                                      else if (iLenth > 1)
366 //                                              pValue = new CJS_Value[iLenth];
367
368                                         for(int i = 0; i < iLenth; i++)
369                                         {
370                                                 carray.GetElement(i, *pValue);
371                                                 swMsg += (*pValue).ToCFXWideString();
372                                                 if (i < iLenth - 1)
373                                                         swMsg += L",  ";
374                                         }
375
376                                         if(pValue) delete pValue;
377                                 }
378                         }
379
380                         if (swTitle == L"")
381                                 swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
382                 }
383                 else if (params[0].GetType() == VT_boolean)
384                 {
385                         FX_BOOL bGet = params[0].ToBool();
386                         if (bGet)
387                                 swMsg = L"true";
388                         else
389                                 swMsg = L"false";
390
391                         swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
392                 }
393                 else
394                 {
395                         swMsg = params[0].ToCFXWideString();
396                         swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
397                 }
398         }
399         else
400         {
401                 if (params[0].GetType() == VT_boolean)
402                 {
403                         FX_BOOL bGet = params[0].ToBool();
404                         if (bGet)
405                                 swMsg = L"true";
406                         else
407                                 swMsg = L"false";
408                 }
409                 else
410                 {
411                         swMsg = params[0].ToCFXWideString();
412                 }
413                 swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
414
415                 for(int i = 1;i<iSize;i++)
416                 {
417                         if (i == 1)
418                                 iIcon = params[i].ToInt();
419                         if (i == 2)
420                                 iType = params[i].ToInt();
421                         if (i == 3)
422                                 swTitle = params[i].ToCFXWideString();
423                 }
424         }
425
426
427         CJS_Context* pContext = (CJS_Context*)cc;
428         ASSERT(pContext != NULL);
429         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
430         ASSERT(pRuntime != NULL);
431         pRuntime->BeginBlock();
432         vRet = MsgBox(pRuntime->GetReaderApp(), JSGetPageView(cc),swMsg,swTitle,iType,iIcon);
433         pRuntime->EndBlock();
434
435         return TRUE;
436 }
437
438
439 FX_BOOL app::beep(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
440 {
441         if (params.size() == 1)
442         {
443                 CJS_Context* pContext = (CJS_Context*)cc;
444                 CJS_Runtime* pRuntime = pContext->GetJSRuntime();
445                 CPDFDoc_Environment * pEnv = pRuntime->GetReaderApp();
446                 pEnv->JS_appBeep(params[0].ToInt());
447                 return TRUE;
448         }
449
450         sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
451         return FALSE;
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].ToCFXWideString()) : 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 ? params[1].ToInt() : 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].ToCFXWideString()) : 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 ? params[1].ToInt() : 1000;
539
540         CPDFDoc_Environment* pApp = pRuntime->GetReaderApp();
541         ASSERT(pApp);
542
543         CJS_Timer* pTimer = new CJS_Timer(this, pApp);
544         m_aTimer.Add(pTimer);
545
546         pTimer->SetType(1);
547         pTimer->SetRuntime(pRuntime);
548         pTimer->SetJScript(script);
549         pTimer->SetTimeOut(dwTimeOut);
550         pTimer->SetJSTimer(dwTimeOut);
551
552         JSFXObject pRetObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"TimerObj"));
553
554         CJS_TimerObj* pJS_TimerObj = (CJS_TimerObj*)JS_GetPrivate(pRuntime->GetIsolate(),pRetObj);
555         ASSERT(pJS_TimerObj != NULL);
556
557         TimerObj* pTimerObj = (TimerObj*)pJS_TimerObj->GetEmbedObject();
558         ASSERT(pTimerObj != NULL);
559
560         pTimerObj->SetTimer(pTimer);
561
562         vRet = pRetObj;
563
564         return TRUE;
565 }
566
567 FX_BOOL app::clearTimeOut(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
568 {
569         CJS_Context* pContext = (CJS_Context*)cc;
570         ASSERT(pContext != NULL);
571         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
572         ASSERT(pRuntime != NULL);
573
574         if (params.size() != 1)
575         {
576                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
577                 return FALSE;
578         }
579
580         if (params[0].GetType() == VT_fxobject)
581         {
582                 JSFXObject pObj = params[0].ToV8Object();
583                 {
584                         if (JS_GetObjDefnID(pObj) == JS_GetObjDefnID(*pRuntime, L"TimerObj"))
585                         {
586                                 if (CJS_Object* pJSObj = params[0].ToCJSObject())
587                                 {
588                                         if (TimerObj* pTimerObj = (TimerObj*)pJSObj->GetEmbedObject())
589                                         {
590                                                 if (CJS_Timer* pTimer = pTimerObj->GetTimer())
591                                                 {
592                                                         pTimer->KillJSTimer();
593
594                                                         for (int i=0,sz=m_aTimer.GetSize(); i<sz; i++)
595                                                         {
596                                                                 if (m_aTimer[i] == pTimer)
597                                                                 {
598                                                                         m_aTimer.RemoveAt(i);
599                                                                         break;
600                                                                 }
601                                                         }
602
603                                                         delete pTimer;
604                                                         pTimerObj->SetTimer(NULL);
605                                                 }
606                                         }
607                                 }
608                         }
609                 }
610         }
611
612         return TRUE;
613 }
614
615 FX_BOOL app::clearInterval(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
616 {
617         CJS_Context* pContext = (CJS_Context*)cc;
618         ASSERT(pContext != NULL);
619         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
620         ASSERT(pRuntime != NULL);
621
622         if (params.size() != 1)
623         {
624                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
625                 return FALSE;
626         }
627
628         if (params[0].GetType() == VT_fxobject)
629         {
630                 JSFXObject pObj = params[0].ToV8Object();
631                 {
632                         if (JS_GetObjDefnID(pObj) == JS_GetObjDefnID(*pRuntime, L"TimerObj"))
633                         {
634                                 if (CJS_Object* pJSObj = params[0].ToCJSObject())
635                                 {
636                                         if (TimerObj* pTimerObj = (TimerObj*)pJSObj->GetEmbedObject())
637                                         {
638                                                 if (CJS_Timer* pTimer = pTimerObj->GetTimer())
639                                                 {
640                                                         pTimer->KillJSTimer();
641
642                                                         for (int i=0,sz=m_aTimer.GetSize(); i<sz; i++)
643                                                         {
644                                                                 if (m_aTimer[i] == pTimer)
645                                                                 {
646                                                                         m_aTimer.RemoveAt(i);
647                                                                         break;
648                                                                 }
649                                                         }
650
651                                                         delete pTimer;
652                                                         pTimerObj->SetTimer(NULL);
653                                                 }
654                                         }
655                                 }
656                         }
657                 }
658         }
659
660         return TRUE;
661 }
662
663 FX_BOOL app::execMenuItem(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
664 {
665         return FALSE;
666 }
667
668 void app::TimerProc(CJS_Timer* pTimer)
669 {
670         ASSERT(pTimer != NULL);
671
672         switch (pTimer->GetType())
673         {
674         case 0: //interval
675                 RunJsScript(pTimer->GetRuntime(), pTimer->GetJScript());
676                 break;
677         case 1:
678                 if (pTimer->GetTimeOut() > 0)
679                 {
680                         RunJsScript(pTimer->GetRuntime(), pTimer->GetJScript());
681                         pTimer->KillJSTimer();
682                 }
683                 break;
684         }
685
686 }
687
688 void app::RunJsScript(CJS_Runtime* pRuntime,const CFX_WideString& wsScript)
689 {
690         ASSERT(pRuntime != NULL);
691
692         if (!pRuntime->IsBlocking())
693         {
694                 IFXJS_Context* pContext = pRuntime->NewContext();
695                 ASSERT(pContext != NULL);
696                 pContext->OnExternal_Exec();
697                 CFX_WideString wtInfo;
698                 pContext->RunScript(wsScript,wtInfo);
699                 pRuntime->ReleaseContext(pContext);
700         }
701 }
702
703 FX_BOOL app::goBack(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
704 {
705   // Not supported.
706   return TRUE;
707 }
708
709 FX_BOOL app::goForward(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
710 {
711   // Not supported.
712   return TRUE;
713 }
714
715 FX_BOOL app::mailMsg(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
716 {
717         CJS_Context* pContext = (CJS_Context*)cc;
718         v8::Isolate* isolate = GetIsolate(cc);
719
720         FX_BOOL bUI = TRUE;
721         CFX_WideString cTo = L"";
722         CFX_WideString cCc = L"";
723         CFX_WideString cBcc = L"";
724         CFX_WideString cSubject = L"";
725         CFX_WideString cMsg = L"";
726
727         if (params.size() < 1)
728                 return FALSE;
729
730         if (params[0].GetType() == VT_object)
731         {
732                 JSObject pObj = params[0].ToV8Object();
733
734                 v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate, pObj, L"bUI");
735                 bUI = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue)).ToBool();
736
737                 pValue = JS_GetObjectElement(isolate, pObj, L"cTo");
738                 cTo = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
739
740                 pValue = JS_GetObjectElement(isolate, pObj, L"cCc");
741                 cCc = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
742
743                 pValue = JS_GetObjectElement(isolate, pObj, L"cBcc");
744                 cBcc = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
745
746                 pValue = JS_GetObjectElement(isolate, pObj, L"cSubject");
747                 cSubject = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
748
749                 pValue = JS_GetObjectElement(isolate, pObj, L"cMsg");
750                 cMsg = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
751         } else {
752                 if (params.size() < 2)
753                         return FALSE;
754
755                 bUI = params[0].ToBool();
756                 cTo = params[1].ToCFXWideString();
757
758                 if (params.size() >= 3)
759                         cCc = params[2].ToCFXWideString();
760                 if (params.size() >= 4)
761                         cBcc = params[3].ToCFXWideString();
762                 if (params.size() >= 5)
763                         cSubject = params[4].ToCFXWideString();
764                 if (params.size() >= 6)
765                         cMsg = params[5].ToCFXWideString();
766         }
767
768         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
769         ASSERT(pRuntime != NULL);
770
771         CPDFDoc_Environment* pApp = pContext->GetReaderApp();
772         ASSERT(pApp != NULL);
773
774         pRuntime->BeginBlock();
775         pApp->JS_docmailForm(NULL, 0, bUI, cTo.c_str(), cSubject.c_str(), cCc.c_str(), cBcc.c_str(), cMsg.c_str());
776         pRuntime->EndBlock();
777
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 = params[0].ToV8Object();
868                 v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj,L"cQuestion");
869                 swQuestion = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).ToCFXWideString();
870
871                 pValue = JS_GetObjectElement(isolate,pObj,L"cTitle");
872                 swTitle = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).ToCFXWideString();
873
874                 pValue = JS_GetObjectElement(isolate,pObj,L"cDefault");
875                 swDefault = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).ToCFXWideString();
876
877                 pValue = JS_GetObjectElement(isolate,pObj,L"cLabel");
878                 swLabel = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).ToCFXWideString();
879
880                 pValue = JS_GetObjectElement(isolate,pObj,L"bPassword");
881                 bPassWord = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).ToBool();
882         }
883         else
884         {
885                 switch(iLength)
886                 {
887                 case 5:
888                         swLabel = params[4].ToCFXWideString();
889                         // FALLTHROUGH
890                 case 4:
891                         bPassWord = params[3].ToBool();
892                         // FALLTHROUGH
893                 case 3:
894                         swDefault = params[2].ToCFXWideString();
895                         // FALLTHROUGH
896                 case 2:
897                         swTitle = params[1].ToCFXWideString();
898                         // FALLTHROUGH
899                 case 1:
900                         swQuestion = params[0].ToCFXWideString();
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 }