Fix an out-of-boundary issue for wide string
[pdfium.git] / fpdfsdk / src / javascript / app.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4  
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "../../include/javascript/JavaScript.h"
8 #include "../../include/javascript/IJavaScript.h"
9 #include "../../include/javascript/JS_Define.h"
10 #include "../../include/javascript/JS_Object.h"
11 #include "../../include/javascript/JS_Value.h"
12 #include "../../include/javascript/app.h"
13 #include "../../include/javascript/JS_EventHandler.h"
14 #include "../../include/javascript/resource.h"
15 #include "../../include/javascript/JS_Context.h"
16 #include "../../include/javascript/JS_Runtime.h"
17 #include "../../include/javascript/Document.h"
18
19
20 static v8::Isolate* GetIsolate(IFXJS_Context* cc)
21 {
22         CJS_Context* pContext = (CJS_Context *)cc;
23         ASSERT(pContext != NULL);
24
25         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
26         ASSERT(pRuntime != NULL);
27
28         return pRuntime->GetIsolate();
29 }
30
31 /* ---------------------------- TimerObj ---------------------------- */
32
33 BEGIN_JS_STATIC_CONST(CJS_TimerObj)
34 END_JS_STATIC_CONST()
35
36 BEGIN_JS_STATIC_PROP(CJS_TimerObj)
37 END_JS_STATIC_PROP()
38
39 BEGIN_JS_STATIC_METHOD(CJS_TimerObj)
40 END_JS_STATIC_METHOD()
41
42 IMPLEMENT_JS_CLASS(CJS_TimerObj, TimerObj)
43
44 TimerObj::TimerObj(CJS_Object* pJSObject)
45 : CJS_EmbedObj(pJSObject),
46 m_pTimer(NULL)
47 {
48         
49 }
50
51 TimerObj::~TimerObj()
52 {
53 }
54
55 void TimerObj::SetTimer(CJS_Timer* pTimer)
56 {
57         m_pTimer = pTimer;
58 }
59
60 CJS_Timer* TimerObj::GetTimer() const
61 {
62         return m_pTimer;
63 }
64
65 #define JS_STR_VIEWERTYPE_READER                L"Reader"
66 #define JS_STR_VIEWERTYPE_STANDARD              L"Exchange"
67 #define JS_STR_VIEWERVARIATION                  L"Full"
68 #define JS_STR_PLATFORM                                 L"WIN"
69 #define JS_STR_LANGUANGE                                L"ENU"
70 #define JS_STR_VIEWERVERSION                    8
71 #define JS_NUM_FORMSVERSION                             7
72
73 #define JS_FILEPATH_MAXLEN                              2000
74
75 /* ---------------------------- app ---------------------------- */
76
77 BEGIN_JS_STATIC_CONST(CJS_App)
78 END_JS_STATIC_CONST()
79
80 BEGIN_JS_STATIC_PROP(CJS_App)
81         JS_STATIC_PROP_ENTRY(activeDocs)
82         JS_STATIC_PROP_ENTRY(calculate)
83         JS_STATIC_PROP_ENTRY(formsVersion)
84         JS_STATIC_PROP_ENTRY(fs)
85         JS_STATIC_PROP_ENTRY(fullscreen)
86         JS_STATIC_PROP_ENTRY(language)
87         JS_STATIC_PROP_ENTRY(media)
88         JS_STATIC_PROP_ENTRY(platform)
89         JS_STATIC_PROP_ENTRY(runtimeHighlight)
90         JS_STATIC_PROP_ENTRY(viewerType)
91         JS_STATIC_PROP_ENTRY(viewerVariation)
92         JS_STATIC_PROP_ENTRY(viewerVersion)     
93 END_JS_STATIC_PROP()
94
95 BEGIN_JS_STATIC_METHOD(CJS_App)
96         JS_STATIC_METHOD_ENTRY(alert, 6)
97         JS_STATIC_METHOD_ENTRY(beep, 1)
98         JS_STATIC_METHOD_ENTRY(browseForDoc, 0)
99         JS_STATIC_METHOD_ENTRY(clearInterval, 1)
100         JS_STATIC_METHOD_ENTRY(clearTimeOut, 1)
101         JS_STATIC_METHOD_ENTRY(execDialog, 3)
102         JS_STATIC_METHOD_ENTRY(execMenuItem,  1)
103         JS_STATIC_METHOD_ENTRY(findComponent, 1)
104         JS_STATIC_METHOD_ENTRY(goBack, 0)
105         JS_STATIC_METHOD_ENTRY(goForward, 0)
106         JS_STATIC_METHOD_ENTRY(launchURL, 0)
107         JS_STATIC_METHOD_ENTRY(mailMsg, 0)      
108         JS_STATIC_METHOD_ENTRY(newFDF, 0)
109         JS_STATIC_METHOD_ENTRY(newDoc, 0)
110         JS_STATIC_METHOD_ENTRY(openDoc, 0)
111         JS_STATIC_METHOD_ENTRY(openFDF, 5)
112         JS_STATIC_METHOD_ENTRY(popUpMenuEx, 0)
113         JS_STATIC_METHOD_ENTRY(popUpMenu, 0)
114         JS_STATIC_METHOD_ENTRY(response, 0)
115         JS_STATIC_METHOD_ENTRY(setInterval, 2)
116         JS_STATIC_METHOD_ENTRY(setTimeOut, 2)
117 END_JS_STATIC_METHOD()
118
119 IMPLEMENT_JS_CLASS(CJS_App,app)
120
121 app::app(CJS_Object * pJSObject) : CJS_EmbedObj(pJSObject) ,
122         m_bCalculate(true),
123         m_pRuntime(NULL),
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                 vp << JS_STR_VIEWERVERSION;
283                 return TRUE;
284         }
285         
286         return FALSE;
287 }
288
289 FX_BOOL app::platform(OBJ_PROP_PARAMS)
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(OBJ_PROP_PARAMS)
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(OBJ_METHOD_PARAMS)
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(OBJ_METHOD_PARAMS)
325 {
326         return TRUE;
327 }
328
329 FX_BOOL app::alert(OBJ_METHOD_PARAMS)
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(OBJ_METHOD_PARAMS)
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(OBJ_METHOD_PARAMS)
473 {
474         return TRUE;
475 }
476
477 FX_BOOL app::popUpMenuEx(OBJ_METHOD_PARAMS)
478 {       
479         return FALSE;
480 }
481
482 FX_BOOL app::fs(OBJ_PROP_PARAMS)
483 {
484 #ifdef FOXIT_CHROME_BUILD
485         return FALSE;
486 #else
487         CJS_Context* pContext = (CJS_Context*)cc;
488         ASSERT(pContext != NULL);
489         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
490         ASSERT(pRuntime != NULL);
491
492         if (vp.IsGetting())
493         {
494                 return TRUE;
495         }
496         else
497         {
498                 return TRUE;
499         }
500 #endif
501 }
502
503 FX_BOOL app::setInterval(OBJ_METHOD_PARAMS)
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 ?  (FX_LPCWSTR)(params[0].operator CFX_WideString()) : (FX_LPCWSTR)L"";
517         if (script.IsEmpty()) 
518         {
519                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSAFNUMBER_KEYSTROKE);
520                 return TRUE;
521         }
522
523         FX_DWORD dwInterval = params.size() > 1 ? (int)params[1] : 1000;
524         
525         CPDFDoc_Environment* pApp = pRuntime->GetReaderApp();
526         ASSERT(pApp);
527         CJS_Timer* pTimer = new CJS_Timer(this, pApp);
528         m_aTimer.Add(pTimer);
529
530         pTimer->SetType(0);
531         pTimer->SetRuntime(pRuntime);
532         pTimer->SetJScript(script);
533         pTimer->SetTimeOut(0);
534 //      pTimer->SetStartTime(GetTickCount());
535         pTimer->SetJSTimer(dwInterval);
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::setTimeOut(OBJ_METHOD_PARAMS)
553 {
554         if (params.size() > 2 || params.size() == 0)
555         {
556                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);  
557                 return FALSE;
558         }
559         
560         CJS_Context* pContext = (CJS_Context*)cc;
561         ASSERT(pContext != NULL);
562         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
563         ASSERT(pRuntime != NULL);
564         
565         CFX_WideString script = params.size() > 0 ?  (FX_LPCWSTR)(params[0].operator CFX_WideString()) : (FX_LPCWSTR)L"";
566         if (script.IsEmpty()) 
567         {
568                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSAFNUMBER_KEYSTROKE);
569                 return TRUE;
570         }
571         
572         FX_DWORD dwTimeOut = params.size() > 1 ? (int)params[1] : 1000;
573         
574         CPDFDoc_Environment* pApp = pRuntime->GetReaderApp();
575         ASSERT(pApp);
576         CJS_Timer* pTimer = new CJS_Timer(this, pApp);
577         m_aTimer.Add(pTimer);
578         
579         pTimer->SetType(1);
580         pTimer->SetRuntime(pRuntime);
581         pTimer->SetJScript(script);
582         pTimer->SetTimeOut(dwTimeOut);
583 //      pTimer->SetStartTime(GetTickCount());
584 //      pTimer->SetJSTimer(1000);
585         pTimer->SetJSTimer(dwTimeOut);
586         
587         JSFXObject pRetObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"TimerObj"));
588 //      ASSERT(pRetObj != NULL);
589         
590         CJS_TimerObj* pJS_TimerObj = (CJS_TimerObj*)JS_GetPrivate(pRuntime->GetIsolate(),pRetObj);
591         ASSERT(pJS_TimerObj != NULL);
592         
593         TimerObj* pTimerObj = (TimerObj*)pJS_TimerObj->GetEmbedObject();
594         ASSERT(pTimerObj != NULL);
595         
596         pTimerObj->SetTimer(pTimer); 
597         
598         vRet = pRetObj;
599         
600         return TRUE;
601 }
602
603 FX_BOOL app::clearTimeOut(OBJ_METHOD_PARAMS)
604 {
605         CJS_Context* pContext = (CJS_Context*)cc;
606         ASSERT(pContext != NULL);
607         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
608         ASSERT(pRuntime != NULL);
609         
610         if (params.size() != 1)
611         {
612                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);  
613                 return FALSE;
614         }
615         
616         if (params[0].GetType() == VT_fxobject)
617         {
618                 JSFXObject pObj = (JSFXObject)params[0];
619                 {
620                         if (JS_GetObjDefnID(pObj) == JS_GetObjDefnID(*pRuntime, L"TimerObj"))
621                         {
622                                 if (CJS_Object* pJSObj = (CJS_Object*)params[0])
623                                 {
624                                         if (TimerObj* pTimerObj = (TimerObj*)pJSObj->GetEmbedObject())
625                                         {
626                                                 if (CJS_Timer* pTimer = pTimerObj->GetTimer())
627                                                 {
628                                                         pTimer->KillJSTimer();
629                                                         
630                                                         for (int i=0,sz=m_aTimer.GetSize(); i<sz; i++)
631                                                         {
632                                                                 if (m_aTimer[i] == pTimer)
633                                                                 {
634                                                                         m_aTimer.RemoveAt(i);
635                                                                         break;
636                                                                 }
637                                                         }
638                                                         
639                                                         delete pTimer;
640                                                         pTimerObj->SetTimer(NULL);
641                                                 }
642                                         }
643                                 }
644                         }
645                 }
646         }
647         
648         return TRUE;
649 }
650
651 FX_BOOL app::clearInterval(OBJ_METHOD_PARAMS)
652 {
653         CJS_Context* pContext = (CJS_Context*)cc;
654         ASSERT(pContext != NULL);
655         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
656         ASSERT(pRuntime != NULL);
657
658         if (params.size() != 1)
659         {
660                 sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);  
661                 return FALSE;
662         }
663         
664         if (params[0].GetType() == VT_fxobject)
665         {
666                 JSFXObject pObj = (JSFXObject)params[0];
667                 {
668                         if (JS_GetObjDefnID(pObj) == JS_GetObjDefnID(*pRuntime, L"TimerObj"))
669                         {
670                                 if (CJS_Object* pJSObj = (CJS_Object*)params[0])
671                                 {
672                                         if (TimerObj* pTimerObj = (TimerObj*)pJSObj->GetEmbedObject())
673                                         {
674                                                 if (CJS_Timer* pTimer = pTimerObj->GetTimer())
675                                                 {
676                                                         pTimer->KillJSTimer();
677                                                         
678                                                         for (int i=0,sz=m_aTimer.GetSize(); i<sz; i++)
679                                                         {
680                                                                 if (m_aTimer[i] == pTimer)
681                                                                 {
682                                                                         m_aTimer.RemoveAt(i);
683                                                                         break;
684                                                                 }
685                                                         }
686                                                         
687                                                         delete pTimer;
688                                                         pTimerObj->SetTimer(NULL);
689                                                 }
690                                         }
691                                 }
692                         }
693                 }
694         }
695         
696         return TRUE;
697 }
698
699 FX_BOOL app::execMenuItem(OBJ_METHOD_PARAMS)
700 {       
701         return FALSE;
702 }
703
704 void app::TimerProc(CJS_Timer* pTimer)
705 {
706         ASSERT(pTimer != NULL);
707
708         switch (pTimer->GetType())
709         {
710         case 0: //interval
711                 RunJsScript(pTimer->GetRuntime(), pTimer->GetJScript());
712                 break;
713         case 1:
714                 if (pTimer->GetTimeOut() > 0)
715                 {
716                         RunJsScript(pTimer->GetRuntime(), pTimer->GetJScript());
717                         pTimer->KillJSTimer();
718                 }
719                 break;
720         }
721         
722 }
723
724 void app::RunJsScript(CJS_Runtime* pRuntime,const CFX_WideString& wsScript)
725 {
726         ASSERT(pRuntime != NULL);
727
728         if (!pRuntime->IsBlocking())
729         {
730                 IFXJS_Context* pContext = pRuntime->NewContext();
731                 ASSERT(pContext != NULL);
732                 pContext->OnExternal_Exec();
733                 CFX_WideString wtInfo;
734                 pContext->RunScript(wsScript,wtInfo);
735                 pRuntime->ReleaseContext(pContext);
736         }
737 }
738
739 FX_BOOL app::goBack(OBJ_METHOD_PARAMS)
740 {
741
742
743         
744         
745         
746         
747         return TRUE;
748 }
749
750 FX_BOOL app::goForward(OBJ_METHOD_PARAMS)
751 {       
752
753
754
755
756
757
758         return TRUE;
759 }
760
761 FX_BOOL app::mailMsg(OBJ_METHOD_PARAMS)
762 {
763         CJS_Context* pContext = (CJS_Context*)cc;
764         ASSERT(pContext != NULL);
765
766         v8::Isolate* isolate = GetIsolate(cc);
767
768         FX_BOOL bUI = TRUE;
769         CFX_WideString cTo = L"";
770         CFX_WideString cCc = L"";
771         CFX_WideString cBcc = L"";
772         CFX_WideString cSubject = L"";
773         CFX_WideString cMsg = L"";
774         if(params.size() < 2)
775                 return FALSE;
776
777         bUI = params.size()>=1?(int)params[0]:TRUE;
778         cTo = params.size()>=2?(const wchar_t*)(FX_LPCWSTR)params[1].operator CFX_WideString():L"";
779         cCc = params.size()>=3?(const wchar_t*)(FX_LPCWSTR)params[2].operator CFX_WideString():L"";
780         cBcc = params.size()>=4?(const wchar_t*)(FX_LPCWSTR)params[3].operator CFX_WideString():L"";
781         cSubject = params.size()>=5?(const wchar_t*)(FX_LPCWSTR)params[4].operator CFX_WideString():L"";
782         cMsg = params.size()>=6?(const wchar_t*)(FX_LPCWSTR)params[5].operator CFX_WideString():L"";            
783
784
785         if (params[0].GetType() == VT_object)
786         {
787                 JSObject pObj = (JSObject)params[0];
788
789                 v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj, L"bUI");
790                         bUI = (int)CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue));
791
792                 pValue = JS_GetObjectElement(isolate, pObj, L"cTo");
793                         cTo = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
794
795                 pValue = JS_GetObjectElement(isolate,pObj, L"cCc");
796                         cCc = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
797
798                 pValue = JS_GetObjectElement(isolate,pObj, L"cBcc");
799                         cBcc = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
800
801                 pValue = JS_GetObjectElement(isolate,pObj, L"cSubject");
802                         cSubject = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
803
804                 pValue = JS_GetObjectElement(isolate,pObj, L"cMsg");
805                         cMsg = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
806         }
807         
808         
809
810         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
811         ASSERT(pRuntime != NULL);
812
813         CPDFDoc_Environment* pApp = pContext->GetReaderApp();
814         ASSERT(pApp != NULL);
815
816         pRuntime->BeginBlock();
817         pApp->JS_docmailForm(NULL, 0, bUI, (FX_LPCWSTR)cTo, (FX_LPCWSTR)cSubject, (FX_LPCWSTR)cCc, (FX_LPCWSTR)cBcc, (FX_LPCWSTR)cMsg);
818         ///////////////////////////////////////////////////////////////////////////////////////////////
819         pRuntime->EndBlock();
820
821         //return bRet;
822         return FALSE;
823 }
824
825 FX_BOOL app::launchURL(OBJ_METHOD_PARAMS)
826 {
827         if (IsSafeMode(cc)) return TRUE;
828
829         CJS_Context* pContext = (CJS_Context*)cc;
830         ASSERT(pContext != NULL);
831
832         
833
834
835         CFX_WideString swURL = params[0].operator CFX_WideString();
836
837         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
838         ASSERT(pRuntime != NULL);
839
840         pRuntime->BeginBlock();
841 //      FX_BOOL bRet = pApp->OpenURL(swURL);
842         pRuntime->EndBlock();
843
844 //      return bRet;
845         return FALSE;
846 }
847
848 FX_BOOL app::runtimeHighlight(OBJ_PROP_PARAMS)
849 {
850         if (vp.IsSetting())
851         {
852                 vp>>m_bRuntimeHighLight;
853         }
854         else
855         {
856                 vp<<m_bRuntimeHighLight;
857         }
858
859         return TRUE;
860 }
861
862 FX_BOOL app::fullscreen(OBJ_PROP_PARAMS)
863 {
864         return FALSE;
865 }
866
867 FX_BOOL app::popUpMenu(OBJ_METHOD_PARAMS)
868 {
869         return FALSE;
870 }
871
872
873 FX_BOOL app::browseForDoc(OBJ_METHOD_PARAMS)
874 {
875         //This method may trigger a "file save" dialog,while enable user to save contents of the document.
876         //Such action is considered to be unsafe.
877         if (IsSafeMode(cc)) return TRUE;
878
879         v8::Isolate* isolate = GetIsolate(cc);
880
881         bool bSave = false;
882         CFX_ByteString cFilenameInit = CFX_ByteString();
883         CFX_ByteString cFSInit = CFX_ByteString();
884
885         if(params.size()>0 && (params[0].GetType() == VT_object))
886         {
887                 JSObject pObj = (JSObject )params[0];
888
889                 v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj,L"bSave");
890                         bSave = (bool)CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue));
891                 
892                 pValue = JS_GetObjectElement(isolate, pObj,L"cFilenameInit");
893                 {
894                         CJS_Value t = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue));
895                         cFilenameInit = t.operator CFX_ByteString();
896                 }
897                 
898                 pValue = JS_GetObjectElement(isolate,pObj,L"cFSInit");
899                 {
900                         CJS_Value t = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue));
901                         cFSInit = t.operator CFX_ByteString();
902                 }
903         }
904         else
905         {
906                 if(params.size() >= 1)
907                 {
908                         bSave = (bool)params[0];
909                 }
910                 if(params.size() >= 2)
911                 {
912                         CJS_Value t = params[1];
913                         cFilenameInit = t.operator CFX_ByteString();
914                 }
915                 if(params.size() >= 3)
916                 {
917                         CJS_Value t = params[2];
918                         cFSInit = t.operator CFX_ByteString();
919                 }
920         }
921         CJS_Context* pContext = (CJS_Context *)cc;
922         ASSERT(pContext != NULL);
923         
924         CPDFDoc_Environment* pApp = pContext->GetReaderApp();
925         ASSERT(pApp != NULL);
926
927         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
928         ASSERT(pRuntime != NULL);
929
930         CFX_WideString wsFileNameInit = CFX_WideString::FromLocal(cFilenameInit);
931         CFX_WideString wsFSInit = CFX_WideString::FromLocal(cFSInit);
932         CFX_WideString wsFilePath = pApp->JS_appbrowseForDoc(bSave, wsFileNameInit);
933         if(wsFilePath.IsEmpty())
934                 return FALSE;
935
936         JSFXObject pRetObj = JS_NewFxDynamicObj(*pRuntime, pContext, -1);
937
938         JS_PutObjectString(isolate,pRetObj, L"cPath", SysPathToPDFPath(wsFilePath));    
939         JS_PutObjectString(isolate,pRetObj, L"cURL", SysPathToPDFPath(wsFilePath));
940
941         if (!cFSInit.IsEmpty())
942         {
943                 JS_PutObjectString(isolate,pRetObj, L"cFS", CFX_WideString::FromLocal(cFSInit.GetBuffer(cFSInit.GetLength())));
944         }
945         else
946         {
947                 JS_PutObjectString(isolate,pRetObj, L"cFS", CFX_WideString::FromLocal("DOS"));
948         }
949         
950         vRet =  pRetObj;
951
952         return TRUE;
953 }
954
955 CFX_WideString app::SysPathToPDFPath(const CFX_WideString& sOldPath)
956 {
957         CFX_WideString sRet = L"/";
958         
959         for (int i=0,sz=sOldPath.GetLength(); i<sz; i++)
960         {
961                 wchar_t c = sOldPath.GetAt(i);
962                 if (c == L':')
963                 {
964                 }
965                 else
966                 {
967                         if (c == L'\\')
968                         {
969                                 sRet += L"/";
970                         }
971                         else
972                         {
973                                 sRet += c;
974                         }
975                 }
976         }
977         
978         return sRet;
979 }
980
981 CFX_WideString app::PDFPathToSysPath(const CFX_WideString& sOldPath)
982 {
983         //strLPath = "D:\temporay.fdf";
984         CFX_WideString strOPath = sOldPath;
985         strOPath.TrimLeft();
986         strOPath.TrimRight();
987         
988         if (strOPath.GetAt(0) == L'/' && strOPath.GetAt(2) == L'/')
989         {
990                 wchar_t c_Drive = strOPath.GetAt(1);
991                 if ((c_Drive >= L'a' && c_Drive <= L'z' )||( c_Drive >= L'A' && c_Drive <= L'Z'))
992                 {
993                         strOPath.Replace((FX_LPCWSTR)L"/",(FX_LPCWSTR)L"\\");
994                         //strOPath.SetAt(0,'');
995                         strOPath.Insert(2,':');
996                         strOPath.Delete(0);
997                 }
998         }
999         
1000         return strOPath;
1001 }
1002
1003 CFX_WideString app::RelativePathToSysPath(const CFX_WideString& sOldPath, const CFX_WideString& sFilePath)
1004 {
1005 //      if (!PathIsRelative(sOldPath)) return sOldPath;
1006         
1007         int nSplit = 0;
1008         for (int i=sFilePath.GetLength()-1; i>=0; i--)
1009         {
1010                 if (sFilePath[i] == '\\' || sFilePath[i] == '/')
1011                 {
1012                         nSplit = i;
1013                         break;
1014                 }
1015         }
1016         
1017         return sFilePath.Left(nSplit+1) + sOldPath;
1018 }
1019
1020 FX_BOOL app::newDoc(OBJ_METHOD_PARAMS)
1021 {
1022         return FALSE;
1023 }
1024
1025 FX_BOOL app::openDoc(OBJ_METHOD_PARAMS)
1026 {
1027         return FALSE;
1028 }
1029
1030 FX_BOOL app::response(OBJ_METHOD_PARAMS)
1031 {
1032         CFX_WideString swQuestion = L"";
1033         CFX_WideString swLabel = L"";
1034 #ifndef FOXIT_CHROME_BUILD
1035         CFX_WideString swTitle = L"Foxit";
1036 #else
1037         CFX_WideString swTitle = L"PDF";
1038 #endif
1039         CFX_WideString swDefault = L"";
1040         CFX_WideString swResponse = L"";
1041         bool bPassWord = false;
1042         
1043         v8::Isolate* isolate = GetIsolate(cc);
1044         
1045         int iLength = params.size();    
1046         if (iLength > 0 && params[0].GetType() == VT_object)
1047         {
1048                 
1049                 JSObject pObj = (JSObject )params[0];
1050                 v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj,L"cQuestion");
1051                         swQuestion = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
1052
1053                 pValue = JS_GetObjectElement(isolate,pObj,L"cTitle");
1054                         swTitle = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
1055
1056                 pValue = JS_GetObjectElement(isolate,pObj,L"cDefault");
1057                         swDefault = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
1058
1059                 pValue = JS_GetObjectElement(isolate,pObj,L"cLabel");
1060                         swLabel = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
1061
1062                 pValue = JS_GetObjectElement(isolate,pObj,L"bPassword");
1063                         bPassWord = (bool)CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue));
1064         }
1065         else
1066         {
1067                 switch(iLength)
1068                 {
1069                 case 1:
1070                         swQuestion = params[0];
1071                         break;
1072                 case 2:
1073                         swQuestion = params[0];
1074                         swTitle = params[1];
1075                         break;
1076                 case 3:
1077                         swQuestion = params[0];
1078                         swTitle = params[1];
1079                         swDefault = params[2];
1080                         break;
1081                 case 4:
1082                         swQuestion = params[0];
1083                         swTitle = params[1];
1084                         swDefault = params[2];
1085                         bPassWord = params[3];
1086                         break;
1087                 case 5:
1088                         swQuestion = params[0];
1089                         swTitle = params[1];
1090                         swDefault = params[2];
1091                         bPassWord = params[3];
1092                         swLabel = params[4];
1093                         break;
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         int nLength = 2048;
1105         char* pBuff = new char[nLength];
1106         nLength = pApp->JS_appResponse(swQuestion, swTitle, swDefault, swLabel, bPassWord, pBuff, nLength);
1107         if(nLength<=0)
1108         {
1109                 delete[] pBuff;
1110                 vRet.SetNull();
1111                 return FALSE;
1112         }
1113         else
1114         {
1115                 nLength = nLength > sizeof(pBuff) ? sizeof(pBuff) : nLength;
1116         vRet = swResponse = CFX_WideString::FromUTF16LE((unsigned short*)pBuff, nLength / 2);
1117         }
1118         delete[] pBuff;
1119
1120         return TRUE;
1121 }
1122
1123 FX_BOOL app::media(OBJ_PROP_PARAMS)
1124 {
1125         return FALSE;
1126 }
1127
1128 FX_BOOL app::execDialog(OBJ_METHOD_PARAMS)
1129 {
1130         return TRUE;
1131 }
1132