Merge to XFA: Patch from CL 726143002
[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(OBJ_PROP_PARAMS)
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(OBJ_PROP_PARAMS)
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(OBJ_PROP_PARAMS)
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(OBJ_PROP_PARAMS)
245 {
246
247
248         
249         
250         
251
252         if (vp.IsGetting())
253         {
254 //              if (pApp->GetAppName() == PHANTOM)
255 //                      vp << JS_STR_VIEWERTYPE_STANDARD;
256 //              else
257 //                      vp << JS_STR_VIEWERTYPE_READER;
258                 vp << L"unknown";
259
260                 //vp << pApp->GetAppTitle();
261                 return TRUE;
262         }
263         
264         return FALSE;
265 }
266
267 FX_BOOL app::viewerVariation(OBJ_PROP_PARAMS)
268 {
269         if (vp.IsGetting())
270         {
271                 vp << JS_STR_VIEWERVARIATION;
272                 return TRUE;
273         }
274         
275         return FALSE;
276 }
277
278 FX_BOOL app::viewerVersion(OBJ_PROP_PARAMS)
279 {
280         if (vp.IsGetting())
281         {
282                 CJS_Context* pContext = (CJS_Context *)cc;
283                 ASSERT(pContext != NULL);
284                 
285                 CPDFDoc_Environment* pApp = pContext->GetReaderApp();
286                 ASSERT(pApp != NULL);
287                 
288                 CPDFSDK_Document* pCurDoc = pContext->GetReaderDocument();
289
290                 CPDFXFA_Document* pDoc = pCurDoc->GetDocument();
291                 if (pDoc->GetDocType() == 1 || pDoc->GetDocType() == 2)
292                         vp << JS_STR_VIEWERVERSION_XFA;
293                 else
294                         vp << JS_STR_VIEWERVERSION;
295                 return TRUE;
296         }
297         
298         return FALSE;
299 }
300
301 FX_BOOL app::platform(OBJ_PROP_PARAMS)
302 {
303         if (vp.IsGetting())
304         {
305                 vp << JS_STR_PLATFORM;
306                 return TRUE;
307         }
308         
309         return FALSE;
310 }
311
312 FX_BOOL app::language(OBJ_PROP_PARAMS)
313 {
314         if (vp.IsGetting())
315         {
316                 vp << JS_STR_LANGUANGE;
317                 return TRUE;
318         }
319         
320         return FALSE;
321 }
322
323 //creates a new fdf object that contains no data
324 //comment: need reader support
325 //note:
326 //CFDF_Document * CPDFDoc_Environment::NewFDF();
327 FX_BOOL app::newFDF(OBJ_METHOD_PARAMS)
328 {
329         return TRUE;
330 }
331 //opens a specified pdf document and returns its document object
332 //comment:need reader support
333 //note: as defined in js reference, the proto of this function's fourth parmeters, how old an fdf document while do not show it.
334 //CFDF_Document * CPDFDoc_Environment::OpenFDF(string strPath,bool bUserConv);
335
336 FX_BOOL app::openFDF(OBJ_METHOD_PARAMS)
337 {
338         return TRUE;
339 }
340
341 FX_BOOL app::alert(OBJ_METHOD_PARAMS)
342 {
343         int iSize = params.size();
344         if (iSize < 1)
345                 return FALSE;
346
347         CFX_WideString swMsg = L"";
348         CFX_WideString swTitle = L"";
349         int iIcon = 0;
350         int iType = 0;
351
352         v8::Isolate* isolate = GetIsolate(cc);
353
354         if (iSize == 1)
355         {
356                 if (params[0].GetType() == VT_object)
357                 {
358                         JSObject pObj = params[0];
359                         {
360                                 v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate, pObj, L"cMsg");
361                                 swMsg = CJS_Value(isolate,pValue,VT_unknown).operator CFX_WideString();
362
363                                 pValue = JS_GetObjectElement(isolate,pObj,L"cTitle");
364                                 swTitle = CJS_Value(isolate, pValue,VT_unknown).operator CFX_WideString();
365
366                                 pValue = JS_GetObjectElement(isolate,pObj,L"nIcon");
367                                 iIcon = (int)CJS_Value(isolate,pValue,VT_unknown);
368
369                                 pValue = JS_GetObjectElement(isolate,pObj,L"nType");
370                                 iType = (int)CJS_Value(isolate,pValue,VT_unknown);
371                         }
372
373                         if (swMsg == L"")
374                         {
375                                 CJS_Array carray(isolate);
376                                 if (params[0].ConvertToArray(carray))
377                                 {
378                                         int iLenth = carray.GetLength();
379                                         CJS_Value* pValue = new CJS_Value(isolate);
380 //                                      if (iLenth == 1)
381 //                                              pValue = new CJS_Value(isolate);
382 //                                      else if (iLenth > 1)
383 //                                              pValue = new CJS_Value[iLenth];
384
385                                         for(int i = 0; i < iLenth; i++)
386                                         {
387                                                 carray.GetElement(i, *pValue);
388                                                 swMsg += (*pValue).operator CFX_WideString();
389                                                 if (i < iLenth - 1)
390                                                         swMsg += L",  ";
391                                         }
392
393                                         if(pValue) delete pValue;
394 //                                      if ((iLenth > 1) && pValue)
395 //                                      {
396 //                                              delete[]pValue;
397 //                                              pValue = NULL;
398 //                                      }
399 //                                      else if ((iLenth == 1) && pValue)
400 //                                      {
401 //                                              delete pValue;
402 //                                              pValue = NULL;
403 //                                      }
404                                 }
405                         }
406
407                         if (swTitle == L"")
408                                 swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
409                 }
410                 else if (params[0].GetType() == VT_boolean)
411                 {
412                         FX_BOOL bGet = (FX_BOOL)params[0];
413                         if (bGet)
414                                 swMsg = L"true";
415                         else
416                                 swMsg = L"false";
417
418                         swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
419                 }
420                 else
421                 {
422                         swMsg = params[0];
423                         swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
424                 }
425         }
426         else
427         {
428                 if (params[0].GetType() == VT_boolean)
429                 {
430                         FX_BOOL bGet = (FX_BOOL)params[0];
431                         if (bGet)
432                                 swMsg = L"true";
433                         else
434                                 swMsg = L"false";
435                 }
436                 else
437                 {
438                         swMsg = params[0];
439                 }
440                 swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
441                 
442                 for(int i = 1;i<iSize;i++)
443                 {
444                         if (i == 1)
445                                 iIcon = int(params[i]);
446                         if (i == 2)
447                                 iType = int(params[i]);
448                         if (i == 3)
449                                 swTitle = params[i];                    
450                 }
451         }
452
453
454         CJS_Context* pContext = (CJS_Context*)cc;
455         ASSERT(pContext != NULL);
456         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
457         ASSERT(pRuntime != NULL);
458         pRuntime->BeginBlock();
459         vRet = MsgBox(pRuntime->GetReaderApp(), JSGetPageView(cc),swMsg,swTitle,iType,iIcon);
460         pRuntime->EndBlock();
461         
462         return TRUE;
463 }
464
465
466 FX_BOOL app::beep(OBJ_METHOD_PARAMS)
467 {
468         if (params.size() == 1)
469         {
470                 CJS_Context* pContext = (CJS_Context*)cc;
471                 CJS_Runtime* pRuntime = pContext->GetJSRuntime();
472                 CPDFDoc_Environment * pEnv = pRuntime->GetReaderApp();
473                 pEnv->JS_appBeep((int)params[0]);
474
475                 return TRUE;
476         }
477         else
478         {
479                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
480                 return FALSE;
481         }
482 }
483
484 FX_BOOL app::findComponent(OBJ_METHOD_PARAMS)
485 {
486         return TRUE;
487 }
488
489 FX_BOOL app::popUpMenuEx(OBJ_METHOD_PARAMS)
490 {       
491         return FALSE;
492 }
493
494 FX_BOOL app::fs(OBJ_PROP_PARAMS)
495 {
496 #ifdef FOXIT_CHROME_BUILD
497         return FALSE;
498 #else
499         CJS_Context* pContext = (CJS_Context*)cc;
500         ASSERT(pContext != NULL);
501         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
502         ASSERT(pRuntime != NULL);
503
504         if (vp.IsGetting())
505         {
506                 return TRUE;
507         }
508         else
509         {
510                 return TRUE;
511         }
512 #endif
513 }
514
515 FX_BOOL app::setInterval(OBJ_METHOD_PARAMS)
516 {
517         if (params.size() > 2 || params.size() == 0) 
518         {
519                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);  
520                 return FALSE;
521         }
522         
523         CJS_Context* pContext = (CJS_Context*)cc;
524         ASSERT(pContext != NULL);
525         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
526         ASSERT(pRuntime != NULL);
527
528         CFX_WideString script = params.size() > 0 ?  (FX_LPCWSTR)(params[0].operator CFX_WideString()) : L"";
529         if (script.IsEmpty()) 
530         {
531                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSAFNUMBER_KEYSTROKE);
532                 return TRUE;
533         }
534
535         FX_DWORD dwInterval = params.size() > 1 ? (int)params[1] : 1000;
536         
537         CPDFDoc_Environment* pApp = pRuntime->GetReaderApp();
538         ASSERT(pApp);
539         CJS_Timer* pTimer = new CJS_Timer(this, pApp);
540         m_aTimer.Add(pTimer);
541
542         pTimer->SetType(0);
543         pTimer->SetRuntime(pRuntime);
544         pTimer->SetJScript(script);
545         pTimer->SetTimeOut(0);
546 //      pTimer->SetStartTime(GetTickCount());
547         pTimer->SetJSTimer(dwInterval);
548         
549         JSFXObject pRetObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"TimerObj"));
550         
551         CJS_TimerObj* pJS_TimerObj = (CJS_TimerObj*)JS_GetPrivate(pRuntime->GetIsolate(),pRetObj);
552         ASSERT(pJS_TimerObj != NULL);
553         
554         TimerObj* pTimerObj = (TimerObj*)pJS_TimerObj->GetEmbedObject();
555         ASSERT(pTimerObj != NULL);
556         
557         pTimerObj->SetTimer(pTimer); 
558         
559         vRet = pRetObj;
560         
561         return TRUE;
562 }
563
564 FX_BOOL app::setTimeOut(OBJ_METHOD_PARAMS)
565 {
566         if (params.size() > 2 || params.size() == 0)
567         {
568                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);  
569                 return FALSE;
570         }
571         
572         CJS_Context* pContext = (CJS_Context*)cc;
573         ASSERT(pContext != NULL);
574         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
575         ASSERT(pRuntime != NULL);
576         
577         CFX_WideString script = params.size() > 0 ?  (FX_LPCWSTR)(params[0].operator CFX_WideString()) : L"";
578         if (script.IsEmpty()) 
579         {
580                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSAFNUMBER_KEYSTROKE);
581                 return TRUE;
582         }
583         
584         FX_DWORD dwTimeOut = params.size() > 1 ? (int)params[1] : 1000;
585         
586         CPDFDoc_Environment* pApp = pRuntime->GetReaderApp();
587         ASSERT(pApp);
588         CJS_Timer* pTimer = new CJS_Timer(this, pApp);
589         m_aTimer.Add(pTimer);
590         
591         pTimer->SetType(1);
592         pTimer->SetRuntime(pRuntime);
593         pTimer->SetJScript(script);
594         pTimer->SetTimeOut(dwTimeOut);
595 //      pTimer->SetStartTime(GetTickCount());
596 //      pTimer->SetJSTimer(1000);
597         pTimer->SetJSTimer(dwTimeOut);
598         
599         JSFXObject pRetObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"TimerObj"));
600 //      ASSERT(pRetObj != NULL);
601         
602         CJS_TimerObj* pJS_TimerObj = (CJS_TimerObj*)JS_GetPrivate(pRuntime->GetIsolate(),pRetObj);
603         ASSERT(pJS_TimerObj != NULL);
604         
605         TimerObj* pTimerObj = (TimerObj*)pJS_TimerObj->GetEmbedObject();
606         ASSERT(pTimerObj != NULL);
607         
608         pTimerObj->SetTimer(pTimer); 
609         
610         vRet = pRetObj;
611         
612         return TRUE;
613 }
614
615 FX_BOOL app::clearTimeOut(OBJ_METHOD_PARAMS)
616 {
617         CJS_Context* pContext = (CJS_Context*)cc;
618         ASSERT(pContext != NULL);
619         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
620         ASSERT(pRuntime != NULL);
621         
622         if (params.size() != 1)
623         {
624                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);  
625                 return FALSE;
626         }
627         
628         if (params[0].GetType() == VT_fxobject)
629         {
630                 JSFXObject pObj = (JSFXObject)params[0];
631                 {
632                         if (JS_GetObjDefnID(pObj) == JS_GetObjDefnID(*pRuntime, L"TimerObj"))
633                         {
634                                 if (CJS_Object* pJSObj = (CJS_Object*)params[0])
635                                 {
636                                         if (TimerObj* pTimerObj = (TimerObj*)pJSObj->GetEmbedObject())
637                                         {
638                                                 if (CJS_Timer* pTimer = pTimerObj->GetTimer())
639                                                 {
640                                                         pTimer->KillJSTimer();
641                                                         
642                                                         for (int i=0,sz=m_aTimer.GetSize(); i<sz; i++)
643                                                         {
644                                                                 if (m_aTimer[i] == pTimer)
645                                                                 {
646                                                                         m_aTimer.RemoveAt(i);
647                                                                         break;
648                                                                 }
649                                                         }
650                                                         
651                                                         delete pTimer;
652                                                         pTimerObj->SetTimer(NULL);
653                                                 }
654                                         }
655                                 }
656                         }
657                 }
658         }
659         
660         return TRUE;
661 }
662
663 FX_BOOL app::clearInterval(OBJ_METHOD_PARAMS)
664 {
665         CJS_Context* pContext = (CJS_Context*)cc;
666         ASSERT(pContext != NULL);
667         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
668         ASSERT(pRuntime != NULL);
669
670         if (params.size() != 1)
671         {
672                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);  
673                 return FALSE;
674         }
675         
676         if (params[0].GetType() == VT_fxobject)
677         {
678                 JSFXObject pObj = (JSFXObject)params[0];
679                 {
680                         if (JS_GetObjDefnID(pObj) == JS_GetObjDefnID(*pRuntime, L"TimerObj"))
681                         {
682                                 if (CJS_Object* pJSObj = (CJS_Object*)params[0])
683                                 {
684                                         if (TimerObj* pTimerObj = (TimerObj*)pJSObj->GetEmbedObject())
685                                         {
686                                                 if (CJS_Timer* pTimer = pTimerObj->GetTimer())
687                                                 {
688                                                         pTimer->KillJSTimer();
689                                                         
690                                                         for (int i=0,sz=m_aTimer.GetSize(); i<sz; i++)
691                                                         {
692                                                                 if (m_aTimer[i] == pTimer)
693                                                                 {
694                                                                         m_aTimer.RemoveAt(i);
695                                                                         break;
696                                                                 }
697                                                         }
698                                                         
699                                                         delete pTimer;
700                                                         pTimerObj->SetTimer(NULL);
701                                                 }
702                                         }
703                                 }
704                         }
705                 }
706         }
707         
708         return TRUE;
709 }
710
711 FX_BOOL app::execMenuItem(OBJ_METHOD_PARAMS)
712 {       
713         return FALSE;
714 }
715
716 void app::TimerProc(CJS_Timer* pTimer)
717 {
718         ASSERT(pTimer != NULL);
719
720         switch (pTimer->GetType())
721         {
722         case 0: //interval
723                 RunJsScript(pTimer->GetRuntime(), pTimer->GetJScript());
724                 break;
725         case 1:
726                 if (pTimer->GetTimeOut() > 0)
727                 {
728                         RunJsScript(pTimer->GetRuntime(), pTimer->GetJScript());
729                         pTimer->KillJSTimer();
730                 }
731                 break;
732         }
733         
734 }
735
736 void app::RunJsScript(CJS_Runtime* pRuntime,const CFX_WideString& wsScript)
737 {
738         ASSERT(pRuntime != NULL);
739
740         if (!pRuntime->IsBlocking())
741         {
742                 IFXJS_Context* pContext = pRuntime->NewContext();
743                 ASSERT(pContext != NULL);
744                 pContext->OnExternal_Exec();
745                 CFX_WideString wtInfo;
746                 pContext->RunScript(wsScript,wtInfo);
747                 pRuntime->ReleaseContext(pContext);
748         }
749 }
750
751 FX_BOOL app::goBack(OBJ_METHOD_PARAMS)
752 {
753
754
755         
756         
757         
758         
759         return TRUE;
760 }
761
762 FX_BOOL app::goForward(OBJ_METHOD_PARAMS)
763 {       
764
765
766
767
768
769
770         return TRUE;
771 }
772
773 FX_BOOL app::mailMsg(OBJ_METHOD_PARAMS)
774 {
775         CJS_Context* pContext = (CJS_Context*)cc;
776         ASSERT(pContext != NULL);
777
778         v8::Isolate* isolate = GetIsolate(cc);
779
780         FX_BOOL bUI = TRUE;
781         CFX_WideString cTo = L"";
782         CFX_WideString cCc = L"";
783         CFX_WideString cBcc = L"";
784         CFX_WideString cSubject = L"";
785         CFX_WideString cMsg = L"";
786         if(params.size() < 2)
787                 return FALSE;
788
789         bUI = params.size()>=1?(int)params[0]:TRUE;
790         cTo = params.size()>=2?(const wchar_t*)(FX_LPCWSTR)params[1].operator CFX_WideString():L"";
791         cCc = params.size()>=3?(const wchar_t*)(FX_LPCWSTR)params[2].operator CFX_WideString():L"";
792         cBcc = params.size()>=4?(const wchar_t*)(FX_LPCWSTR)params[3].operator CFX_WideString():L"";
793         cSubject = params.size()>=5?(const wchar_t*)(FX_LPCWSTR)params[4].operator CFX_WideString():L"";
794         cMsg = params.size()>=6?(const wchar_t*)(FX_LPCWSTR)params[5].operator CFX_WideString():L"";            
795
796
797         if (params[0].GetType() == VT_object)
798         {
799                 JSObject pObj = (JSObject)params[0];
800
801                 v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj, L"bUI");
802                         bUI = (int)CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue));
803
804                 pValue = JS_GetObjectElement(isolate, pObj, L"cTo");
805                         cTo = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
806
807                 pValue = JS_GetObjectElement(isolate,pObj, L"cCc");
808                         cCc = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
809
810                 pValue = JS_GetObjectElement(isolate,pObj, L"cBcc");
811                         cBcc = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
812
813                 pValue = JS_GetObjectElement(isolate,pObj, L"cSubject");
814                         cSubject = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
815
816                 pValue = JS_GetObjectElement(isolate,pObj, L"cMsg");
817                         cMsg = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
818         }
819         
820         
821
822         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
823         ASSERT(pRuntime != NULL);
824
825         CPDFDoc_Environment* pApp = pContext->GetReaderApp();
826         ASSERT(pApp != NULL);
827
828         pRuntime->BeginBlock();
829         pApp->JS_docmailForm(NULL, 0, bUI, (FX_LPCWSTR)cTo, (FX_LPCWSTR)cSubject, (FX_LPCWSTR)cCc, (FX_LPCWSTR)cBcc, (FX_LPCWSTR)cMsg);
830         ///////////////////////////////////////////////////////////////////////////////////////////////
831         pRuntime->EndBlock();
832
833         //return bRet;
834         return FALSE;
835 }
836
837 FX_BOOL app::launchURL(OBJ_METHOD_PARAMS)
838 {
839         if (IsSafeMode(cc)) return TRUE;
840
841         CJS_Context* pContext = (CJS_Context*)cc;
842         ASSERT(pContext != NULL);
843
844         
845
846
847         CFX_WideString swURL = params[0].operator CFX_WideString();
848
849         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
850         ASSERT(pRuntime != NULL);
851
852         pRuntime->BeginBlock();
853 //      FX_BOOL bRet = pApp->OpenURL(swURL);
854         pRuntime->EndBlock();
855
856 //      return bRet;
857         return FALSE;
858 }
859
860 FX_BOOL app::runtimeHighlight(OBJ_PROP_PARAMS)
861 {
862         if (vp.IsSetting())
863         {
864                 vp>>m_bRuntimeHighLight;
865         }
866         else
867         {
868                 vp<<m_bRuntimeHighLight;
869         }
870
871         return TRUE;
872 }
873
874 FX_BOOL app::fullscreen(OBJ_PROP_PARAMS)
875 {
876         return FALSE;
877 }
878
879 FX_BOOL app::popUpMenu(OBJ_METHOD_PARAMS)
880 {
881         return FALSE;
882 }
883
884
885 FX_BOOL app::browseForDoc(OBJ_METHOD_PARAMS)
886 {
887         //This method may trigger a "file save" dialog,while enable user to save contents of the document.
888         //Such action is considered to be unsafe.
889         if (IsSafeMode(cc)) return TRUE;
890
891         v8::Isolate* isolate = GetIsolate(cc);
892
893         bool bSave = false;
894         CFX_ByteString cFilenameInit = CFX_ByteString();
895         CFX_ByteString cFSInit = CFX_ByteString();
896
897         if(params.size()>0 && (params[0].GetType() == VT_object))
898         {
899                 JSObject pObj = (JSObject )params[0];
900
901                 v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj,L"bSave");
902                         bSave = (bool)CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue));
903                 
904                 pValue = JS_GetObjectElement(isolate, pObj,L"cFilenameInit");
905                 {
906                         CJS_Value t = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue));
907                         cFilenameInit = t.operator CFX_ByteString();
908                 }
909                 
910                 pValue = JS_GetObjectElement(isolate,pObj,L"cFSInit");
911                 {
912                         CJS_Value t = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue));
913                         cFSInit = t.operator CFX_ByteString();
914                 }
915         }
916         else
917         {
918                 if(params.size() >= 1)
919                 {
920                         bSave = (bool)params[0];
921                 }
922                 if(params.size() >= 2)
923                 {
924                         CJS_Value t = params[1];
925                         cFilenameInit = t.operator CFX_ByteString();
926                 }
927                 if(params.size() >= 3)
928                 {
929                         CJS_Value t = params[2];
930                         cFSInit = t.operator CFX_ByteString();
931                 }
932         }
933         CJS_Context* pContext = (CJS_Context *)cc;
934         ASSERT(pContext != NULL);
935         
936         CPDFDoc_Environment* pApp = pContext->GetReaderApp();
937         ASSERT(pApp != NULL);
938
939         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
940         ASSERT(pRuntime != NULL);
941
942         CFX_WideString wsFileNameInit = CFX_WideString::FromLocal(cFilenameInit);
943         CFX_WideString wsFSInit = CFX_WideString::FromLocal(cFSInit);
944         CFX_WideString wsFilePath = pApp->JS_appbrowseForDoc(bSave, wsFileNameInit);
945         if(wsFilePath.IsEmpty())
946                 return FALSE;
947
948         JSFXObject pRetObj = JS_NewFxDynamicObj(*pRuntime, pContext, -1);
949
950         JS_PutObjectString(isolate,pRetObj, L"cPath", SysPathToPDFPath(wsFilePath));    
951         JS_PutObjectString(isolate,pRetObj, L"cURL", SysPathToPDFPath(wsFilePath));
952
953         if (!cFSInit.IsEmpty())
954         {
955                 JS_PutObjectString(isolate,pRetObj, L"cFS", CFX_WideString::FromLocal(cFSInit.GetBuffer(cFSInit.GetLength())));
956         }
957         else
958         {
959                 JS_PutObjectString(isolate,pRetObj, L"cFS", CFX_WideString::FromLocal("DOS"));
960         }
961         
962         vRet =  pRetObj;
963
964         return TRUE;
965 }
966
967 CFX_WideString app::SysPathToPDFPath(const CFX_WideString& sOldPath)
968 {
969         CFX_WideString sRet = L"/";
970         
971         for (int i=0,sz=sOldPath.GetLength(); i<sz; i++)
972         {
973                 wchar_t c = sOldPath.GetAt(i);
974                 if (c == L':')
975                 {
976                 }
977                 else
978                 {
979                         if (c == L'\\')
980                         {
981                                 sRet += L"/";
982                         }
983                         else
984                         {
985                                 sRet += c;
986                         }
987                 }
988         }
989         
990         return sRet;
991 }
992
993 CFX_WideString app::PDFPathToSysPath(const CFX_WideString& sOldPath)
994 {
995         //strLPath = "D:\temporay.fdf";
996         CFX_WideString strOPath = sOldPath;
997         strOPath.TrimLeft();
998         strOPath.TrimRight();
999         
1000         if (strOPath.GetAt(0) == L'/' && strOPath.GetAt(2) == L'/')
1001         {
1002                 wchar_t c_Drive = strOPath.GetAt(1);
1003                 if ((c_Drive >= L'a' && c_Drive <= L'z' )||( c_Drive >= L'A' && c_Drive <= L'Z'))
1004                 {
1005                         strOPath.Replace(L"/",L"\\");
1006                         //strOPath.SetAt(0,'');
1007                         strOPath.Insert(2,':');
1008                         strOPath.Delete(0);
1009                 }
1010         }
1011         
1012         return strOPath;
1013 }
1014
1015 CFX_WideString app::RelativePathToSysPath(const CFX_WideString& sOldPath, const CFX_WideString& sFilePath)
1016 {
1017 //      if (!PathIsRelative(sOldPath)) return sOldPath;
1018         
1019         int nSplit = 0;
1020         for (int i=sFilePath.GetLength()-1; i>=0; i--)
1021         {
1022                 if (sFilePath[i] == '\\' || sFilePath[i] == '/')
1023                 {
1024                         nSplit = i;
1025                         break;
1026                 }
1027         }
1028         
1029         return sFilePath.Left(nSplit+1) + sOldPath;
1030 }
1031
1032 FX_BOOL app::newDoc(OBJ_METHOD_PARAMS)
1033 {
1034         return FALSE;
1035 }
1036
1037 FX_BOOL app::openDoc(OBJ_METHOD_PARAMS)
1038 {
1039         return FALSE;
1040 }
1041
1042 FX_BOOL app::response(OBJ_METHOD_PARAMS)
1043 {
1044         CFX_WideString swQuestion = L"";
1045         CFX_WideString swLabel = L"";
1046 #ifndef FOXIT_CHROME_BUILD
1047         CFX_WideString swTitle = L"Foxit";
1048 #else
1049         CFX_WideString swTitle = L"PDF";
1050 #endif
1051         CFX_WideString swDefault = L"";
1052         bool bPassWord = false;
1053
1054         v8::Isolate* isolate = GetIsolate(cc);
1055
1056         int iLength = params.size();
1057         if (iLength > 0 && params[0].GetType() == VT_object)
1058         {
1059                 JSObject pObj = (JSObject )params[0];
1060                 v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj,L"cQuestion");
1061                 swQuestion = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
1062
1063                 pValue = JS_GetObjectElement(isolate,pObj,L"cTitle");
1064                 swTitle = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
1065
1066                 pValue = JS_GetObjectElement(isolate,pObj,L"cDefault");
1067                 swDefault = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
1068
1069                 pValue = JS_GetObjectElement(isolate,pObj,L"cLabel");
1070                 swLabel = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
1071
1072                 pValue = JS_GetObjectElement(isolate,pObj,L"bPassword");
1073                 bPassWord = (bool)CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue));
1074         }
1075         else
1076         {
1077                 switch(iLength)
1078                 {
1079                 case 5:
1080                         swLabel = params[4];
1081                         // FALLTHROUGH
1082                 case 4:
1083                         bPassWord = params[3];
1084                         // FALLTHROUGH
1085                 case 3:
1086                         swDefault = params[2];
1087                         // FALLTHROUGH
1088                 case 2:
1089                         swTitle = params[1];
1090                         // FALLTHROUGH
1091                 case 1:
1092                         swQuestion = params[0];
1093                         // FALLTHROUGH
1094                 default:
1095                         break;
1096                 }
1097         }
1098
1099         CJS_Context* pContext = (CJS_Context *)cc;
1100         ASSERT(pContext != NULL);
1101
1102         CPDFDoc_Environment* pApp = pContext->GetReaderApp();
1103         ASSERT(pApp != NULL);
1104
1105         const int MAX_INPUT_BYTES = 2048;
1106         char* pBuff = new char[MAX_INPUT_BYTES + 2];
1107         if (!pBuff)
1108                 return FALSE;
1109
1110         memset(pBuff, 0, MAX_INPUT_BYTES + 2);
1111         int nLengthBytes = pApp->JS_appResponse(swQuestion, swTitle, swDefault, swLabel, bPassWord, pBuff, MAX_INPUT_BYTES);
1112         if (nLengthBytes <= 0)
1113         {
1114                 vRet.SetNull();
1115                 delete[] pBuff;
1116                 return FALSE;
1117         }
1118         if (nLengthBytes > MAX_INPUT_BYTES)
1119                 nLengthBytes = MAX_INPUT_BYTES;
1120
1121         vRet = CFX_WideString::FromUTF16LE((unsigned short*)pBuff, nLengthBytes / sizeof(unsigned short));
1122         delete[] pBuff;
1123         return TRUE;
1124 }
1125
1126 FX_BOOL app::media(OBJ_PROP_PARAMS)
1127 {
1128         return FALSE;
1129 }
1130
1131 FX_BOOL app::execDialog(OBJ_METHOD_PARAMS)
1132 {
1133         return TRUE;
1134 }
1135