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