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