ccdd8ab3dfb63fc811c03baba82bd04d7b72aeca
[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, JS_ErrorString& 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, JS_ErrorString& 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 //              int iNumDocs = pApp->CountDocuments();
213 //
214 //              for (int iIndex = 0;iIndex < iNumDocs; iIndex++)
215 //              {
216                         if (CPDFSDK_Document* pDoc = pApp->GetCurrentDoc())
217                         {
218                                 CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)pDoc->GetInterForm();
219                                 ASSERT(pInterForm != NULL);
220                                 pInterForm->EnableCalculate((FX_BOOL)m_bCalculate);
221                         }
222 //              }
223         }
224         else
225         {
226                 vp << (bool)m_bCalculate;
227         }
228
229         return TRUE;
230 }
231
232 FX_BOOL app::formsVersion(IFXJS_Context* cc, CJS_PropValue& vp, JS_ErrorString& sError)
233 {
234         if (vp.IsGetting())
235         {
236                 vp << JS_NUM_FORMSVERSION;
237                 return TRUE;
238         }
239
240         return FALSE;
241 }
242
243 FX_BOOL app::viewerType(IFXJS_Context* cc, CJS_PropValue& vp, JS_ErrorString& sError)
244 {
245         if (vp.IsGetting())
246         {
247                 vp << L"unknown";
248                 return TRUE;
249         }
250
251         return FALSE;
252 }
253
254 FX_BOOL app::viewerVariation(IFXJS_Context* cc, CJS_PropValue& vp, JS_ErrorString& sError)
255 {
256         if (vp.IsGetting())
257         {
258                 vp << JS_STR_VIEWERVARIATION;
259                 return TRUE;
260         }
261
262         return FALSE;
263 }
264
265 FX_BOOL app::viewerVersion(IFXJS_Context* cc, CJS_PropValue& vp, JS_ErrorString& sError)
266 {
267         if (vp.IsGetting())
268         {
269                 vp << JS_STR_VIEWERVERSION;
270                 return TRUE;
271         }
272
273         return FALSE;
274 }
275
276 FX_BOOL app::platform(IFXJS_Context* cc, CJS_PropValue& vp, JS_ErrorString& sError)
277 {
278         if (vp.IsGetting())
279         {
280                 vp << JS_STR_PLATFORM;
281                 return TRUE;
282         }
283
284         return FALSE;
285 }
286
287 FX_BOOL app::language(IFXJS_Context* cc, CJS_PropValue& vp, JS_ErrorString& sError)
288 {
289         if (vp.IsGetting())
290         {
291                 vp << JS_STR_LANGUANGE;
292                 return TRUE;
293         }
294
295         return FALSE;
296 }
297
298 //creates a new fdf object that contains no data
299 //comment: need reader support
300 //note:
301 //CFDF_Document * CPDFDoc_Environment::NewFDF();
302 FX_BOOL app::newFDF(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, JS_ErrorString& sError)
303 {
304         return TRUE;
305 }
306 //opens a specified pdf document and returns its document object
307 //comment:need reader support
308 //note: as defined in js reference, the proto of this function's fourth parmeters, how old an fdf document while do not show it.
309 //CFDF_Document * CPDFDoc_Environment::OpenFDF(string strPath,bool bUserConv);
310
311 FX_BOOL app::openFDF(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, JS_ErrorString& sError)
312 {
313         return TRUE;
314 }
315
316 FX_BOOL app::alert(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, JS_ErrorString& sError)
317 {
318         int iSize = params.size();
319         if (iSize < 1)
320                 return FALSE;
321
322         CFX_WideString swMsg = L"";
323         CFX_WideString swTitle = L"";
324         int iIcon = 0;
325         int iType = 0;
326
327         v8::Isolate* isolate = GetIsolate(cc);
328
329         if (iSize == 1)
330         {
331                 if (params[0].GetType() == VT_object)
332                 {
333                         JSObject pObj = params[0];
334                         {
335                                 v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate, pObj, L"cMsg");
336                                 swMsg = CJS_Value(isolate,pValue,VT_unknown).operator CFX_WideString();
337
338                                 pValue = JS_GetObjectElement(isolate,pObj,L"cTitle");
339                                 swTitle = CJS_Value(isolate, pValue,VT_unknown).operator CFX_WideString();
340
341                                 pValue = JS_GetObjectElement(isolate,pObj,L"nIcon");
342                                 iIcon = (int)CJS_Value(isolate,pValue,VT_unknown);
343
344                                 pValue = JS_GetObjectElement(isolate,pObj,L"nType");
345                                 iType = (int)CJS_Value(isolate,pValue,VT_unknown);
346                         }
347
348                         if (swMsg == L"")
349                         {
350                                 CJS_Array carray(isolate);
351                                 if (params[0].ConvertToArray(carray))
352                                 {
353                                         int iLenth = carray.GetLength();
354                                         CJS_Value* pValue = new CJS_Value(isolate);
355 //                                      if (iLenth == 1)
356 //                                              pValue = new CJS_Value(isolate);
357 //                                      else if (iLenth > 1)
358 //                                              pValue = new CJS_Value[iLenth];
359
360                                         for(int i = 0; i < iLenth; i++)
361                                         {
362                                                 carray.GetElement(i, *pValue);
363                                                 swMsg += (*pValue).operator CFX_WideString();
364                                                 if (i < iLenth - 1)
365                                                         swMsg += L",  ";
366                                         }
367
368                                         if(pValue) delete pValue;
369 //                                      if ((iLenth > 1) && pValue)
370 //                                      {
371 //                                              delete[]pValue;
372 //                                              pValue = NULL;
373 //                                      }
374 //                                      else if ((iLenth == 1) && pValue)
375 //                                      {
376 //                                              delete pValue;
377 //                                              pValue = NULL;
378 //                                      }
379                                 }
380                         }
381
382                         if (swTitle == L"")
383                                 swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
384                 }
385                 else if (params[0].GetType() == VT_boolean)
386                 {
387                         FX_BOOL bGet = (FX_BOOL)params[0];
388                         if (bGet)
389                                 swMsg = L"true";
390                         else
391                                 swMsg = L"false";
392
393                         swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
394                 }
395                 else
396                 {
397                         swMsg = params[0];
398                         swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
399                 }
400         }
401         else
402         {
403                 if (params[0].GetType() == VT_boolean)
404                 {
405                         FX_BOOL bGet = (FX_BOOL)params[0];
406                         if (bGet)
407                                 swMsg = L"true";
408                         else
409                                 swMsg = L"false";
410                 }
411                 else
412                 {
413                         swMsg = params[0];
414                 }
415                 swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
416
417                 for(int i = 1;i<iSize;i++)
418                 {
419                         if (i == 1)
420                                 iIcon = int(params[i]);
421                         if (i == 2)
422                                 iType = int(params[i]);
423                         if (i == 3)
424                                 swTitle = params[i];
425                 }
426         }
427
428
429         CJS_Context* pContext = (CJS_Context*)cc;
430         ASSERT(pContext != NULL);
431         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
432         ASSERT(pRuntime != NULL);
433         pRuntime->BeginBlock();
434         vRet = MsgBox(pRuntime->GetReaderApp(), JSGetPageView(cc),swMsg,swTitle,iType,iIcon);
435         pRuntime->EndBlock();
436
437         return TRUE;
438 }
439
440
441 FX_BOOL app::beep(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, JS_ErrorString& sError)
442 {
443         if (params.size() == 1)
444         {
445                 CJS_Context* pContext = (CJS_Context*)cc;
446                 CJS_Runtime* pRuntime = pContext->GetJSRuntime();
447                 CPDFDoc_Environment * pEnv = pRuntime->GetReaderApp();
448                 pEnv->JS_appBeep((int)params[0]);
449
450                 return TRUE;
451         }
452         else
453         {
454                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
455                 return FALSE;
456         }
457 }
458
459 FX_BOOL app::findComponent(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, JS_ErrorString& sError)
460 {
461         return TRUE;
462 }
463
464 FX_BOOL app::popUpMenuEx(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, JS_ErrorString& sError)
465 {
466         return FALSE;
467 }
468
469 FX_BOOL app::fs(IFXJS_Context* cc, CJS_PropValue& vp, JS_ErrorString& sError)
470 {
471         return FALSE;
472 }
473
474 FX_BOOL app::setInterval(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, JS_ErrorString& sError)
475 {
476         if (params.size() > 2 || params.size() == 0)
477         {
478                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
479                 return FALSE;
480         }
481
482         CJS_Context* pContext = (CJS_Context*)cc;
483         ASSERT(pContext != NULL);
484         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
485         ASSERT(pRuntime != NULL);
486
487         CFX_WideString script = params.size() > 0 ?  (FX_LPCWSTR)(params[0].operator CFX_WideString()) : L"";
488         if (script.IsEmpty())
489         {
490                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSAFNUMBER_KEYSTROKE);
491                 return TRUE;
492         }
493
494         FX_DWORD dwInterval = params.size() > 1 ? (int)params[1] : 1000;
495
496         CPDFDoc_Environment* pApp = pRuntime->GetReaderApp();
497         ASSERT(pApp);
498         CJS_Timer* pTimer = new CJS_Timer(this, pApp);
499         m_aTimer.Add(pTimer);
500
501         pTimer->SetType(0);
502         pTimer->SetRuntime(pRuntime);
503         pTimer->SetJScript(script);
504         pTimer->SetTimeOut(0);
505 //      pTimer->SetStartTime(GetTickCount());
506         pTimer->SetJSTimer(dwInterval);
507
508         JSFXObject pRetObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"TimerObj"));
509
510         CJS_TimerObj* pJS_TimerObj = (CJS_TimerObj*)JS_GetPrivate(pRuntime->GetIsolate(),pRetObj);
511         ASSERT(pJS_TimerObj != NULL);
512
513         TimerObj* pTimerObj = (TimerObj*)pJS_TimerObj->GetEmbedObject();
514         ASSERT(pTimerObj != NULL);
515
516         pTimerObj->SetTimer(pTimer);
517
518         vRet = pRetObj;
519
520         return TRUE;
521 }
522
523 FX_BOOL app::setTimeOut(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, JS_ErrorString& sError)
524 {
525         if (params.size() > 2 || params.size() == 0)
526         {
527                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
528                 return FALSE;
529         }
530
531         CJS_Context* pContext = (CJS_Context*)cc;
532         ASSERT(pContext != NULL);
533         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
534         ASSERT(pRuntime != NULL);
535
536         CFX_WideString script = params.size() > 0 ?  (FX_LPCWSTR)(params[0].operator CFX_WideString()) : L"";
537         if (script.IsEmpty())
538         {
539                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSAFNUMBER_KEYSTROKE);
540                 return TRUE;
541         }
542
543         FX_DWORD dwTimeOut = params.size() > 1 ? (int)params[1] : 1000;
544
545         CPDFDoc_Environment* pApp = pRuntime->GetReaderApp();
546         ASSERT(pApp);
547         CJS_Timer* pTimer = new CJS_Timer(this, pApp);
548         m_aTimer.Add(pTimer);
549
550         pTimer->SetType(1);
551         pTimer->SetRuntime(pRuntime);
552         pTimer->SetJScript(script);
553         pTimer->SetTimeOut(dwTimeOut);
554 //      pTimer->SetStartTime(GetTickCount());
555 //      pTimer->SetJSTimer(1000);
556         pTimer->SetJSTimer(dwTimeOut);
557
558         JSFXObject pRetObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"TimerObj"));
559 //      ASSERT(pRetObj != NULL);
560
561         CJS_TimerObj* pJS_TimerObj = (CJS_TimerObj*)JS_GetPrivate(pRuntime->GetIsolate(),pRetObj);
562         ASSERT(pJS_TimerObj != NULL);
563
564         TimerObj* pTimerObj = (TimerObj*)pJS_TimerObj->GetEmbedObject();
565         ASSERT(pTimerObj != NULL);
566
567         pTimerObj->SetTimer(pTimer);
568
569         vRet = pRetObj;
570
571         return TRUE;
572 }
573
574 FX_BOOL app::clearTimeOut(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, JS_ErrorString& sError)
575 {
576         CJS_Context* pContext = (CJS_Context*)cc;
577         ASSERT(pContext != NULL);
578         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
579         ASSERT(pRuntime != NULL);
580
581         if (params.size() != 1)
582         {
583                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
584                 return FALSE;
585         }
586
587         if (params[0].GetType() == VT_fxobject)
588         {
589                 JSFXObject pObj = (JSFXObject)params[0];
590                 {
591                         if (JS_GetObjDefnID(pObj) == JS_GetObjDefnID(*pRuntime, L"TimerObj"))
592                         {
593                                 if (CJS_Object* pJSObj = (CJS_Object*)params[0])
594                                 {
595                                         if (TimerObj* pTimerObj = (TimerObj*)pJSObj->GetEmbedObject())
596                                         {
597                                                 if (CJS_Timer* pTimer = pTimerObj->GetTimer())
598                                                 {
599                                                         pTimer->KillJSTimer();
600
601                                                         for (int i=0,sz=m_aTimer.GetSize(); i<sz; i++)
602                                                         {
603                                                                 if (m_aTimer[i] == pTimer)
604                                                                 {
605                                                                         m_aTimer.RemoveAt(i);
606                                                                         break;
607                                                                 }
608                                                         }
609
610                                                         delete pTimer;
611                                                         pTimerObj->SetTimer(NULL);
612                                                 }
613                                         }
614                                 }
615                         }
616                 }
617         }
618
619         return TRUE;
620 }
621
622 FX_BOOL app::clearInterval(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, JS_ErrorString& sError)
623 {
624         CJS_Context* pContext = (CJS_Context*)cc;
625         ASSERT(pContext != NULL);
626         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
627         ASSERT(pRuntime != NULL);
628
629         if (params.size() != 1)
630         {
631                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
632                 return FALSE;
633         }
634
635         if (params[0].GetType() == VT_fxobject)
636         {
637                 JSFXObject pObj = (JSFXObject)params[0];
638                 {
639                         if (JS_GetObjDefnID(pObj) == JS_GetObjDefnID(*pRuntime, L"TimerObj"))
640                         {
641                                 if (CJS_Object* pJSObj = (CJS_Object*)params[0])
642                                 {
643                                         if (TimerObj* pTimerObj = (TimerObj*)pJSObj->GetEmbedObject())
644                                         {
645                                                 if (CJS_Timer* pTimer = pTimerObj->GetTimer())
646                                                 {
647                                                         pTimer->KillJSTimer();
648
649                                                         for (int i=0,sz=m_aTimer.GetSize(); i<sz; i++)
650                                                         {
651                                                                 if (m_aTimer[i] == pTimer)
652                                                                 {
653                                                                         m_aTimer.RemoveAt(i);
654                                                                         break;
655                                                                 }
656                                                         }
657
658                                                         delete pTimer;
659                                                         pTimerObj->SetTimer(NULL);
660                                                 }
661                                         }
662                                 }
663                         }
664                 }
665         }
666
667         return TRUE;
668 }
669
670 FX_BOOL app::execMenuItem(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, JS_ErrorString& sError)
671 {
672         return FALSE;
673 }
674
675 void app::TimerProc(CJS_Timer* pTimer)
676 {
677         ASSERT(pTimer != NULL);
678
679         switch (pTimer->GetType())
680         {
681         case 0: //interval
682                 RunJsScript(pTimer->GetRuntime(), pTimer->GetJScript());
683                 break;
684         case 1:
685                 if (pTimer->GetTimeOut() > 0)
686                 {
687                         RunJsScript(pTimer->GetRuntime(), pTimer->GetJScript());
688                         pTimer->KillJSTimer();
689                 }
690                 break;
691         }
692
693 }
694
695 void app::RunJsScript(CJS_Runtime* pRuntime,const CFX_WideString& wsScript)
696 {
697         ASSERT(pRuntime != NULL);
698
699         if (!pRuntime->IsBlocking())
700         {
701                 IFXJS_Context* pContext = pRuntime->NewContext();
702                 ASSERT(pContext != NULL);
703                 pContext->OnExternal_Exec();
704                 CFX_WideString wtInfo;
705                 pContext->RunScript(wsScript,wtInfo);
706                 pRuntime->ReleaseContext(pContext);
707         }
708 }
709
710 FX_BOOL app::goBack(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, JS_ErrorString& sError)
711 {
712   // Not supported.
713   return TRUE;
714 }
715
716 FX_BOOL app::goForward(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, JS_ErrorString& sError)
717 {
718   // Not supported.
719   return TRUE;
720 }
721
722 FX_BOOL app::mailMsg(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, JS_ErrorString& sError)
723 {
724         CJS_Context* pContext = (CJS_Context*)cc;
725         ASSERT(pContext != NULL);
726
727         v8::Isolate* isolate = GetIsolate(cc);
728
729         FX_BOOL bUI = TRUE;
730         CFX_WideString cTo = L"";
731         CFX_WideString cCc = L"";
732         CFX_WideString cBcc = L"";
733         CFX_WideString cSubject = L"";
734         CFX_WideString cMsg = L"";
735         if(params.size() < 2)
736                 return FALSE;
737
738         bUI = params.size()>=1?(int)params[0]:TRUE;
739         cTo = params.size()>=2?(const wchar_t*)(FX_LPCWSTR)params[1].operator CFX_WideString():L"";
740         cCc = params.size()>=3?(const wchar_t*)(FX_LPCWSTR)params[2].operator CFX_WideString():L"";
741         cBcc = params.size()>=4?(const wchar_t*)(FX_LPCWSTR)params[3].operator CFX_WideString():L"";
742         cSubject = params.size()>=5?(const wchar_t*)(FX_LPCWSTR)params[4].operator CFX_WideString():L"";
743         cMsg = params.size()>=6?(const wchar_t*)(FX_LPCWSTR)params[5].operator CFX_WideString():L"";
744
745
746         if (params[0].GetType() == VT_object)
747         {
748                 JSObject pObj = (JSObject)params[0];
749
750                 v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj, L"bUI");
751                         bUI = (int)CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue));
752
753                 pValue = JS_GetObjectElement(isolate, pObj, L"cTo");
754                         cTo = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
755
756                 pValue = JS_GetObjectElement(isolate,pObj, L"cCc");
757                         cCc = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
758
759                 pValue = JS_GetObjectElement(isolate,pObj, L"cBcc");
760                         cBcc = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
761
762                 pValue = JS_GetObjectElement(isolate,pObj, L"cSubject");
763                         cSubject = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
764
765                 pValue = JS_GetObjectElement(isolate,pObj, L"cMsg");
766                         cMsg = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
767         }
768
769
770
771         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
772         ASSERT(pRuntime != NULL);
773
774         CPDFDoc_Environment* pApp = pContext->GetReaderApp();
775         ASSERT(pApp != NULL);
776
777         pRuntime->BeginBlock();
778         pApp->JS_docmailForm(NULL, 0, bUI, cTo.c_str(), cSubject.c_str(), cCc.c_str(), cBcc.c_str(), cMsg.c_str());
779         ///////////////////////////////////////////////////////////////////////////////////////////////
780         pRuntime->EndBlock();
781
782         //return bRet;
783         return FALSE;
784 }
785
786 FX_BOOL app::launchURL(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, JS_ErrorString& sError)
787 {
788   // Unsafe, not supported.
789   return TRUE;
790 }
791
792 FX_BOOL app::runtimeHighlight(IFXJS_Context* cc, CJS_PropValue& vp, JS_ErrorString& sError)
793 {
794         if (vp.IsSetting())
795         {
796                 vp>>m_bRuntimeHighLight;
797         }
798         else
799         {
800                 vp<<m_bRuntimeHighLight;
801         }
802
803         return TRUE;
804 }
805
806 FX_BOOL app::fullscreen(IFXJS_Context* cc, CJS_PropValue& vp, JS_ErrorString& sError)
807 {
808         return FALSE;
809 }
810
811 FX_BOOL app::popUpMenu(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, JS_ErrorString& sError)
812 {
813         return FALSE;
814 }
815
816
817 FX_BOOL app::browseForDoc(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, JS_ErrorString& sError)
818 {
819   // Unsafe, not supported.
820   return TRUE;
821 }
822
823 CFX_WideString app::SysPathToPDFPath(const CFX_WideString& sOldPath)
824 {
825         CFX_WideString sRet = L"/";
826
827         for (int i=0,sz=sOldPath.GetLength(); i<sz; i++)
828         {
829                 wchar_t c = sOldPath.GetAt(i);
830                 if (c == L':')
831                 {
832                 }
833                 else
834                 {
835                         if (c == L'\\')
836                         {
837                                 sRet += L"/";
838                         }
839                         else
840                         {
841                                 sRet += c;
842                         }
843                 }
844         }
845
846         return sRet;
847 }
848
849 FX_BOOL app::newDoc(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, JS_ErrorString& sError)
850 {
851         return FALSE;
852 }
853
854 FX_BOOL app::openDoc(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, JS_ErrorString& sError)
855 {
856         return FALSE;
857 }
858
859 FX_BOOL app::response(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, JS_ErrorString& sError)
860 {
861         CFX_WideString swQuestion = L"";
862         CFX_WideString swLabel = L"";
863         CFX_WideString swTitle = L"PDF";
864         CFX_WideString swDefault = L"";
865         bool bPassWord = false;
866
867         v8::Isolate* isolate = GetIsolate(cc);
868
869         int iLength = params.size();
870         if (iLength > 0 && params[0].GetType() == VT_object)
871         {
872                 JSObject pObj = (JSObject )params[0];
873                 v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj,L"cQuestion");
874                 swQuestion = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
875
876                 pValue = JS_GetObjectElement(isolate,pObj,L"cTitle");
877                 swTitle = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
878
879                 pValue = JS_GetObjectElement(isolate,pObj,L"cDefault");
880                 swDefault = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
881
882                 pValue = JS_GetObjectElement(isolate,pObj,L"cLabel");
883                 swLabel = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
884
885                 pValue = JS_GetObjectElement(isolate,pObj,L"bPassword");
886                 bPassWord = (bool)CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue));
887         }
888         else
889         {
890                 switch(iLength)
891                 {
892                 case 5:
893                         swLabel = params[4];
894                         // FALLTHROUGH
895                 case 4:
896                         bPassWord = params[3];
897                         // FALLTHROUGH
898                 case 3:
899                         swDefault = params[2];
900                         // FALLTHROUGH
901                 case 2:
902                         swTitle = params[1];
903                         // FALLTHROUGH
904                 case 1:
905                         swQuestion = params[0];
906                         // FALLTHROUGH
907                 default:
908                         break;
909                 }
910         }
911
912         CJS_Context* pContext = (CJS_Context *)cc;
913         ASSERT(pContext != NULL);
914
915         CPDFDoc_Environment* pApp = pContext->GetReaderApp();
916         ASSERT(pApp != NULL);
917
918         const int MAX_INPUT_BYTES = 2048;
919         char* pBuff = new char[MAX_INPUT_BYTES + 2];
920         if (!pBuff)
921                 return FALSE;
922
923         memset(pBuff, 0, MAX_INPUT_BYTES + 2);
924         int nLengthBytes = pApp->JS_appResponse(swQuestion, swTitle, swDefault, swLabel, bPassWord, pBuff, MAX_INPUT_BYTES);
925         if (nLengthBytes <= 0)
926         {
927                 vRet.SetNull();
928                 delete[] pBuff;
929                 return FALSE;
930         }
931         if (nLengthBytes > MAX_INPUT_BYTES)
932                 nLengthBytes = MAX_INPUT_BYTES;
933
934         vRet = CFX_WideString::FromUTF16LE((unsigned short*)pBuff, nLengthBytes / sizeof(unsigned short));
935         delete[] pBuff;
936         return TRUE;
937 }
938
939 FX_BOOL app::media(IFXJS_Context* cc, CJS_PropValue& vp, JS_ErrorString& sError)
940 {
941         return FALSE;
942 }
943
944 FX_BOOL app::execDialog(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, JS_ErrorString& sError)
945 {
946         return TRUE;
947 }