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 "app.h"
8 
9 #include <memory>
10 
11 #include "Document.h"
12 #include "JS_Context.h"
13 #include "JS_Define.h"
14 #include "JS_EventHandler.h"
15 #include "JS_Object.h"
16 #include "JS_Runtime.h"
17 #include "JS_Value.h"
18 #include "fpdfsdk/include/fsdk_mgr.h"  // For CPDFDoc_Environment.
19 #include "fpdfsdk/include/javascript/IJavaScript.h"
20 #include "resource.h"
21 
22 BEGIN_JS_STATIC_CONST(CJS_TimerObj)
END_JS_STATIC_CONST()23 END_JS_STATIC_CONST()
24 
25 BEGIN_JS_STATIC_PROP(CJS_TimerObj)
26 END_JS_STATIC_PROP()
27 
28 BEGIN_JS_STATIC_METHOD(CJS_TimerObj)
29 END_JS_STATIC_METHOD()
30 
31 IMPLEMENT_JS_CLASS(CJS_TimerObj, TimerObj)
32 
33 TimerObj::TimerObj(CJS_Object* pJSObject)
34     : CJS_EmbedObj(pJSObject), m_pTimer(NULL) {}
35 
~TimerObj()36 TimerObj::~TimerObj() {}
37 
SetTimer(CJS_Timer * pTimer)38 void TimerObj::SetTimer(CJS_Timer* pTimer) {
39   m_pTimer = pTimer;
40 }
41 
GetTimer() const42 CJS_Timer* TimerObj::GetTimer() const {
43   return m_pTimer;
44 }
45 
46 #define JS_STR_VIEWERTYPE L"pdfium"
47 #define JS_STR_VIEWERVARIATION L"Full"
48 #define JS_STR_PLATFORM L"WIN"
49 #define JS_STR_LANGUANGE L"ENU"
50 #define JS_NUM_VIEWERVERSION 8
51 #ifdef PDF_ENABLE_XFA
52 #define JS_NUM_VIEWERVERSION_XFA 11
53 #endif  // PDF_ENABLE_XFA
54 #define JS_NUM_FORMSVERSION 7
55 
56 BEGIN_JS_STATIC_CONST(CJS_App)
END_JS_STATIC_CONST()57 END_JS_STATIC_CONST()
58 
59 BEGIN_JS_STATIC_PROP(CJS_App)
60 JS_STATIC_PROP_ENTRY(activeDocs)
61 JS_STATIC_PROP_ENTRY(calculate)
62 JS_STATIC_PROP_ENTRY(formsVersion)
63 JS_STATIC_PROP_ENTRY(fs)
64 JS_STATIC_PROP_ENTRY(fullscreen)
65 JS_STATIC_PROP_ENTRY(language)
66 JS_STATIC_PROP_ENTRY(media)
67 JS_STATIC_PROP_ENTRY(platform)
68 JS_STATIC_PROP_ENTRY(runtimeHighlight)
69 JS_STATIC_PROP_ENTRY(viewerType)
70 JS_STATIC_PROP_ENTRY(viewerVariation)
71 JS_STATIC_PROP_ENTRY(viewerVersion)
72 END_JS_STATIC_PROP()
73 
74 BEGIN_JS_STATIC_METHOD(CJS_App)
75 JS_STATIC_METHOD_ENTRY(alert)
76 JS_STATIC_METHOD_ENTRY(beep)
77 JS_STATIC_METHOD_ENTRY(browseForDoc)
78 JS_STATIC_METHOD_ENTRY(clearInterval)
79 JS_STATIC_METHOD_ENTRY(clearTimeOut)
80 JS_STATIC_METHOD_ENTRY(execDialog)
81 JS_STATIC_METHOD_ENTRY(execMenuItem)
82 JS_STATIC_METHOD_ENTRY(findComponent)
83 JS_STATIC_METHOD_ENTRY(goBack)
84 JS_STATIC_METHOD_ENTRY(goForward)
85 JS_STATIC_METHOD_ENTRY(launchURL)
86 JS_STATIC_METHOD_ENTRY(mailMsg)
87 JS_STATIC_METHOD_ENTRY(newFDF)
88 JS_STATIC_METHOD_ENTRY(newDoc)
89 JS_STATIC_METHOD_ENTRY(openDoc)
90 JS_STATIC_METHOD_ENTRY(openFDF)
91 JS_STATIC_METHOD_ENTRY(popUpMenuEx)
92 JS_STATIC_METHOD_ENTRY(popUpMenu)
93 JS_STATIC_METHOD_ENTRY(response)
94 JS_STATIC_METHOD_ENTRY(setInterval)
95 JS_STATIC_METHOD_ENTRY(setTimeOut)
96 END_JS_STATIC_METHOD()
97 
98 IMPLEMENT_JS_CLASS(CJS_App, app)
99 
100 app::app(CJS_Object* pJSObject)
101     : CJS_EmbedObj(pJSObject), m_bCalculate(true), m_bRuntimeHighLight(false) {}
102 
~app()103 app::~app() {
104   for (int i = 0, sz = m_aTimer.GetSize(); i < sz; i++)
105     delete m_aTimer[i];
106 
107   m_aTimer.RemoveAll();
108 }
109 
activeDocs(IJS_Context * cc,CJS_PropValue & vp,CFX_WideString & sError)110 FX_BOOL app::activeDocs(IJS_Context* cc,
111                         CJS_PropValue& vp,
112                         CFX_WideString& sError) {
113   if (!vp.IsGetting())
114     return FALSE;
115 
116   CJS_Context* pContext = (CJS_Context*)cc;
117   CPDFDoc_Environment* pApp = pContext->GetReaderApp();
118   CJS_Runtime* pRuntime = pContext->GetJSRuntime();
119   CPDFSDK_Document* pCurDoc = pContext->GetReaderDocument();
120   CJS_Array aDocs(pRuntime);
121   if (CPDFSDK_Document* pDoc = pApp->GetSDKDocument()) {
122     CJS_Document* pJSDocument = NULL;
123     if (pDoc == pCurDoc) {
124       v8::Local<v8::Object> pObj = FXJS_GetThisObj(pRuntime->GetIsolate());
125       if (FXJS_GetObjDefnID(pObj) == CJS_Document::g_nObjDefnID)
126         pJSDocument =
127             (CJS_Document*)FXJS_GetPrivate(pRuntime->GetIsolate(), pObj);
128     } else {
129       v8::Local<v8::Object> pObj = FXJS_NewFxDynamicObj(
130           pRuntime->GetIsolate(), pRuntime, CJS_Document::g_nObjDefnID);
131       pJSDocument =
132           (CJS_Document*)FXJS_GetPrivate(pRuntime->GetIsolate(), pObj);
133       ASSERT(pJSDocument);
134     }
135     aDocs.SetElement(0, CJS_Value(pRuntime, pJSDocument));
136   }
137   if (aDocs.GetLength() > 0)
138     vp << aDocs;
139   else
140     vp.SetNull();
141 
142   return TRUE;
143 }
144 
calculate(IJS_Context * cc,CJS_PropValue & vp,CFX_WideString & sError)145 FX_BOOL app::calculate(IJS_Context* cc,
146                        CJS_PropValue& vp,
147                        CFX_WideString& sError) {
148   if (vp.IsSetting()) {
149     bool bVP;
150     vp >> bVP;
151     m_bCalculate = (FX_BOOL)bVP;
152 
153     CJS_Context* pContext = (CJS_Context*)cc;
154     CPDFDoc_Environment* pApp = pContext->GetReaderApp();
155     CJS_Runtime* pRuntime = pContext->GetJSRuntime();
156     CJS_Array aDocs(pRuntime);
157     if (CPDFSDK_Document* pDoc = pApp->GetSDKDocument())
158       pDoc->GetInterForm()->EnableCalculate((FX_BOOL)m_bCalculate);
159   } else {
160     vp << (bool)m_bCalculate;
161   }
162   return TRUE;
163 }
164 
formsVersion(IJS_Context * cc,CJS_PropValue & vp,CFX_WideString & sError)165 FX_BOOL app::formsVersion(IJS_Context* cc,
166                           CJS_PropValue& vp,
167                           CFX_WideString& sError) {
168   if (vp.IsGetting()) {
169     vp << JS_NUM_FORMSVERSION;
170     return TRUE;
171   }
172 
173   return FALSE;
174 }
175 
viewerType(IJS_Context * cc,CJS_PropValue & vp,CFX_WideString & sError)176 FX_BOOL app::viewerType(IJS_Context* cc,
177                         CJS_PropValue& vp,
178                         CFX_WideString& sError) {
179   if (vp.IsGetting()) {
180     vp << JS_STR_VIEWERTYPE;
181     return TRUE;
182   }
183 
184   return FALSE;
185 }
186 
viewerVariation(IJS_Context * cc,CJS_PropValue & vp,CFX_WideString & sError)187 FX_BOOL app::viewerVariation(IJS_Context* cc,
188                              CJS_PropValue& vp,
189                              CFX_WideString& sError) {
190   if (vp.IsGetting()) {
191     vp << JS_STR_VIEWERVARIATION;
192     return TRUE;
193   }
194 
195   return FALSE;
196 }
197 
viewerVersion(IJS_Context * cc,CJS_PropValue & vp,CFX_WideString & sError)198 FX_BOOL app::viewerVersion(IJS_Context* cc,
199                            CJS_PropValue& vp,
200                            CFX_WideString& sError) {
201   if (!vp.IsGetting())
202     return FALSE;
203 #ifdef PDF_ENABLE_XFA
204   CJS_Context* pContext = (CJS_Context*)cc;
205   CPDFSDK_Document* pCurDoc = pContext->GetReaderDocument();
206   CPDFXFA_Document* pDoc = pCurDoc->GetXFADocument();
207   if (pDoc->GetDocType() == 1 || pDoc->GetDocType() == 2) {
208     vp << JS_NUM_VIEWERVERSION_XFA;
209     return TRUE;
210   }
211 #endif  // PDF_ENABLE_XFA
212   vp << JS_NUM_VIEWERVERSION;
213   return TRUE;
214 }
215 
platform(IJS_Context * cc,CJS_PropValue & vp,CFX_WideString & sError)216 FX_BOOL app::platform(IJS_Context* cc,
217                       CJS_PropValue& vp,
218                       CFX_WideString& sError) {
219   if (!vp.IsGetting())
220     return FALSE;
221 #ifdef PDF_ENABLE_XFA
222   CPDFDoc_Environment* pEnv =
223       static_cast<CJS_Context*>(cc)->GetJSRuntime()->GetReaderApp();
224   if (!pEnv)
225     return FALSE;
226   CFX_WideString platfrom = pEnv->FFI_GetPlatform();
227   if (!platfrom.IsEmpty()) {
228     vp << platfrom;
229     return TRUE;
230   }
231 #endif
232   vp << JS_STR_PLATFORM;
233   return TRUE;
234 }
235 
language(IJS_Context * cc,CJS_PropValue & vp,CFX_WideString & sError)236 FX_BOOL app::language(IJS_Context* cc,
237                       CJS_PropValue& vp,
238                       CFX_WideString& sError) {
239   if (!vp.IsGetting())
240     return FALSE;
241 #ifdef PDF_ENABLE_XFA
242   CPDFDoc_Environment* pEnv =
243       static_cast<CJS_Context*>(cc)->GetJSRuntime()->GetReaderApp();
244   if (!pEnv)
245     return FALSE;
246   CFX_WideString language = pEnv->FFI_GetLanguage();
247   if (!language.IsEmpty()) {
248     vp << language;
249     return TRUE;
250   }
251 #endif
252   vp << JS_STR_LANGUANGE;
253   return TRUE;
254 }
255 
256 // creates a new fdf object that contains no data
257 // comment: need reader support
258 // note:
259 // CFDF_Document * CPDFDoc_Environment::NewFDF();
newFDF(IJS_Context * cc,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)260 FX_BOOL app::newFDF(IJS_Context* cc,
261                     const std::vector<CJS_Value>& params,
262                     CJS_Value& vRet,
263                     CFX_WideString& sError) {
264   return TRUE;
265 }
266 // opens a specified pdf document and returns its document object
267 // comment:need reader support
268 // note: as defined in js reference, the proto of this function's fourth
269 // parmeters, how old an fdf document while do not show it.
270 // CFDF_Document * CPDFDoc_Environment::OpenFDF(string strPath,bool bUserConv);
271 
openFDF(IJS_Context * cc,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)272 FX_BOOL app::openFDF(IJS_Context* cc,
273                      const std::vector<CJS_Value>& params,
274                      CJS_Value& vRet,
275                      CFX_WideString& sError) {
276   return TRUE;
277 }
278 
alert(IJS_Context * cc,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)279 FX_BOOL app::alert(IJS_Context* cc,
280                    const std::vector<CJS_Value>& params,
281                    CJS_Value& vRet,
282                    CFX_WideString& sError) {
283   int iSize = params.size();
284   if (iSize < 1)
285     return FALSE;
286 
287   CFX_WideString swMsg = L"";
288   CFX_WideString swTitle = L"";
289   int iIcon = 0;
290   int iType = 0;
291 
292   CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
293   v8::Isolate* isolate = pRuntime->GetIsolate();
294 
295   if (iSize == 1) {
296     if (params[0].GetType() == CJS_Value::VT_object) {
297       v8::Local<v8::Object> pObj = params[0].ToV8Object();
298       {
299         v8::Local<v8::Value> pValue =
300             FXJS_GetObjectElement(isolate, pObj, L"cMsg");
301         swMsg = CJS_Value(pRuntime, pValue, CJS_Value::VT_unknown)
302                     .ToCFXWideString();
303 
304         pValue = FXJS_GetObjectElement(isolate, pObj, L"cTitle");
305         swTitle = CJS_Value(pRuntime, pValue, CJS_Value::VT_unknown)
306                       .ToCFXWideString();
307 
308         pValue = FXJS_GetObjectElement(isolate, pObj, L"nIcon");
309         iIcon = CJS_Value(pRuntime, pValue, CJS_Value::VT_unknown).ToInt();
310 
311         pValue = FXJS_GetObjectElement(isolate, pObj, L"nType");
312         iType = CJS_Value(pRuntime, pValue, CJS_Value::VT_unknown).ToInt();
313       }
314 
315       if (swMsg == L"") {
316         CJS_Array carray(pRuntime);
317         if (params[0].ConvertToArray(carray)) {
318           int iLength = carray.GetLength();
319           CJS_Value* pValue = new CJS_Value(pRuntime);
320           for (int i = 0; i < iLength; ++i) {
321             carray.GetElement(i, *pValue);
322             swMsg += (*pValue).ToCFXWideString();
323             if (i < iLength - 1)
324               swMsg += L",  ";
325           }
326 
327           delete pValue;
328         }
329       }
330 
331       if (swTitle == L"")
332         swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
333     } else if (params[0].GetType() == CJS_Value::VT_boolean) {
334       FX_BOOL bGet = params[0].ToBool();
335       if (bGet)
336         swMsg = L"true";
337       else
338         swMsg = L"false";
339 
340       swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
341     } else {
342       swMsg = params[0].ToCFXWideString();
343       swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
344     }
345   } else {
346     if (params[0].GetType() == CJS_Value::VT_boolean) {
347       FX_BOOL bGet = params[0].ToBool();
348       if (bGet)
349         swMsg = L"true";
350       else
351         swMsg = L"false";
352     } else {
353       swMsg = params[0].ToCFXWideString();
354     }
355     swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
356 
357     for (int i = 1; i < iSize; i++) {
358       if (i == 1)
359         iIcon = params[i].ToInt();
360       if (i == 2)
361         iType = params[i].ToInt();
362       if (i == 3)
363         swTitle = params[i].ToCFXWideString();
364     }
365   }
366 
367   pRuntime->BeginBlock();
368   vRet = MsgBox(pRuntime->GetReaderApp(), swMsg.c_str(), swTitle.c_str(), iType,
369                 iIcon);
370   pRuntime->EndBlock();
371   return TRUE;
372 }
373 
beep(IJS_Context * cc,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)374 FX_BOOL app::beep(IJS_Context* cc,
375                   const std::vector<CJS_Value>& params,
376                   CJS_Value& vRet,
377                   CFX_WideString& sError) {
378   if (params.size() == 1) {
379     CJS_Context* pContext = (CJS_Context*)cc;
380     CJS_Runtime* pRuntime = pContext->GetJSRuntime();
381     CPDFDoc_Environment* pEnv = pRuntime->GetReaderApp();
382     pEnv->JS_appBeep(params[0].ToInt());
383     return TRUE;
384   }
385 
386   sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
387   return FALSE;
388 }
389 
findComponent(IJS_Context * cc,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)390 FX_BOOL app::findComponent(IJS_Context* cc,
391                            const std::vector<CJS_Value>& params,
392                            CJS_Value& vRet,
393                            CFX_WideString& sError) {
394   return TRUE;
395 }
396 
popUpMenuEx(IJS_Context * cc,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)397 FX_BOOL app::popUpMenuEx(IJS_Context* cc,
398                          const std::vector<CJS_Value>& params,
399                          CJS_Value& vRet,
400                          CFX_WideString& sError) {
401   return FALSE;
402 }
403 
fs(IJS_Context * cc,CJS_PropValue & vp,CFX_WideString & sError)404 FX_BOOL app::fs(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
405   return FALSE;
406 }
407 
setInterval(IJS_Context * cc,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)408 FX_BOOL app::setInterval(IJS_Context* cc,
409                          const std::vector<CJS_Value>& params,
410                          CJS_Value& vRet,
411                          CFX_WideString& sError) {
412   CJS_Context* pContext = (CJS_Context*)cc;
413   if (params.size() > 2 || params.size() == 0) {
414     sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
415     return FALSE;
416   }
417 
418   CFX_WideString script = params.size() > 0 ? params[0].ToCFXWideString() : L"";
419   if (script.IsEmpty()) {
420     sError = JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE);
421     return TRUE;
422   }
423 
424   CJS_Runtime* pRuntime = pContext->GetJSRuntime();
425   FX_DWORD dwInterval = params.size() > 1 ? params[1].ToInt() : 1000;
426 
427   CPDFDoc_Environment* pApp = pRuntime->GetReaderApp();
428   ASSERT(pApp);
429   CJS_Timer* pTimer =
430       new CJS_Timer(this, pApp, pRuntime, 0, script, dwInterval, 0);
431   m_aTimer.Add(pTimer);
432 
433   v8::Local<v8::Object> pRetObj = FXJS_NewFxDynamicObj(
434       pRuntime->GetIsolate(), pRuntime, CJS_TimerObj::g_nObjDefnID);
435   CJS_TimerObj* pJS_TimerObj =
436       (CJS_TimerObj*)FXJS_GetPrivate(pRuntime->GetIsolate(), pRetObj);
437   TimerObj* pTimerObj = (TimerObj*)pJS_TimerObj->GetEmbedObject();
438   pTimerObj->SetTimer(pTimer);
439 
440   vRet = pRetObj;
441   return TRUE;
442 }
443 
setTimeOut(IJS_Context * cc,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)444 FX_BOOL app::setTimeOut(IJS_Context* cc,
445                         const std::vector<CJS_Value>& params,
446                         CJS_Value& vRet,
447                         CFX_WideString& sError) {
448   if (params.size() > 2 || params.size() == 0) {
449     sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
450     return FALSE;
451   }
452 
453   CJS_Context* pContext = (CJS_Context*)cc;
454   CJS_Runtime* pRuntime = pContext->GetJSRuntime();
455 
456   CFX_WideString script = params.size() > 0 ? params[0].ToCFXWideString() : L"";
457   if (script.IsEmpty()) {
458     sError =
459         JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSAFNUMBER_KEYSTROKE);
460     return TRUE;
461   }
462 
463   FX_DWORD dwTimeOut = params.size() > 1 ? params[1].ToInt() : 1000;
464 
465   CPDFDoc_Environment* pApp = pRuntime->GetReaderApp();
466   ASSERT(pApp);
467 
468   CJS_Timer* pTimer =
469       new CJS_Timer(this, pApp, pRuntime, 1, script, dwTimeOut, dwTimeOut);
470   m_aTimer.Add(pTimer);
471 
472   v8::Local<v8::Object> pRetObj = FXJS_NewFxDynamicObj(
473       pRuntime->GetIsolate(), pRuntime, CJS_TimerObj::g_nObjDefnID);
474   CJS_TimerObj* pJS_TimerObj =
475       (CJS_TimerObj*)FXJS_GetPrivate(pRuntime->GetIsolate(), pRetObj);
476   TimerObj* pTimerObj = (TimerObj*)pJS_TimerObj->GetEmbedObject();
477   pTimerObj->SetTimer(pTimer);
478 
479   vRet = pRetObj;
480   return TRUE;
481 }
482 
clearTimeOut(IJS_Context * cc,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)483 FX_BOOL app::clearTimeOut(IJS_Context* cc,
484                           const std::vector<CJS_Value>& params,
485                           CJS_Value& vRet,
486                           CFX_WideString& sError) {
487   CJS_Context* pContext = (CJS_Context*)cc;
488   if (params.size() != 1) {
489     sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
490     return FALSE;
491   }
492 
493   if (params[0].GetType() == CJS_Value::VT_fxobject) {
494     v8::Local<v8::Object> pObj = params[0].ToV8Object();
495     if (FXJS_GetObjDefnID(pObj) == CJS_TimerObj::g_nObjDefnID) {
496       if (CJS_Object* pJSObj = params[0].ToCJSObject()) {
497         if (TimerObj* pTimerObj = (TimerObj*)pJSObj->GetEmbedObject()) {
498           if (CJS_Timer* pTimer = pTimerObj->GetTimer()) {
499             pTimer->KillJSTimer();
500 
501             for (int i = 0, sz = m_aTimer.GetSize(); i < sz; i++) {
502               if (m_aTimer[i] == pTimer) {
503                 m_aTimer.RemoveAt(i);
504                 break;
505               }
506             }
507 
508             delete pTimer;
509             pTimerObj->SetTimer(NULL);
510           }
511         }
512       }
513     }
514   }
515 
516   return TRUE;
517 }
518 
clearInterval(IJS_Context * cc,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)519 FX_BOOL app::clearInterval(IJS_Context* cc,
520                            const std::vector<CJS_Value>& params,
521                            CJS_Value& vRet,
522                            CFX_WideString& sError) {
523   CJS_Context* pContext = (CJS_Context*)cc;
524   if (params.size() != 1) {
525     sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
526     return FALSE;
527   }
528 
529   if (params[0].GetType() == CJS_Value::VT_fxobject) {
530     v8::Local<v8::Object> pObj = params[0].ToV8Object();
531     if (FXJS_GetObjDefnID(pObj) == CJS_TimerObj::g_nObjDefnID) {
532       if (CJS_Object* pJSObj = params[0].ToCJSObject()) {
533         if (TimerObj* pTimerObj = (TimerObj*)pJSObj->GetEmbedObject()) {
534           if (CJS_Timer* pTimer = pTimerObj->GetTimer()) {
535             pTimer->KillJSTimer();
536 
537             for (int i = 0, sz = m_aTimer.GetSize(); i < sz; i++) {
538               if (m_aTimer[i] == pTimer) {
539                 m_aTimer.RemoveAt(i);
540                 break;
541               }
542             }
543 
544             delete pTimer;
545             pTimerObj->SetTimer(NULL);
546           }
547         }
548       }
549     }
550   }
551 
552   return TRUE;
553 }
554 
execMenuItem(IJS_Context * cc,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)555 FX_BOOL app::execMenuItem(IJS_Context* cc,
556                           const std::vector<CJS_Value>& params,
557                           CJS_Value& vRet,
558                           CFX_WideString& sError) {
559   return FALSE;
560 }
561 
TimerProc(CJS_Timer * pTimer)562 void app::TimerProc(CJS_Timer* pTimer) {
563   CJS_Runtime* pRuntime = pTimer->GetRuntime();
564 
565   switch (pTimer->GetType()) {
566     case 0:  // interval
567       if (pRuntime)
568         RunJsScript(pRuntime, pTimer->GetJScript());
569       break;
570     case 1:
571       if (pTimer->GetTimeOut() > 0) {
572         if (pRuntime)
573           RunJsScript(pRuntime, pTimer->GetJScript());
574         pTimer->KillJSTimer();
575       }
576       break;
577   }
578 }
579 
RunJsScript(CJS_Runtime * pRuntime,const CFX_WideString & wsScript)580 void app::RunJsScript(CJS_Runtime* pRuntime, const CFX_WideString& wsScript) {
581   if (!pRuntime->IsBlocking()) {
582     IJS_Context* pContext = pRuntime->NewContext();
583     pContext->OnExternal_Exec();
584     CFX_WideString wtInfo;
585     pContext->RunScript(wsScript, &wtInfo);
586     pRuntime->ReleaseContext(pContext);
587   }
588 }
589 
goBack(IJS_Context * cc,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)590 FX_BOOL app::goBack(IJS_Context* cc,
591                     const std::vector<CJS_Value>& params,
592                     CJS_Value& vRet,
593                     CFX_WideString& sError) {
594   // Not supported.
595   return TRUE;
596 }
597 
goForward(IJS_Context * cc,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)598 FX_BOOL app::goForward(IJS_Context* cc,
599                        const std::vector<CJS_Value>& params,
600                        CJS_Value& vRet,
601                        CFX_WideString& sError) {
602   // Not supported.
603   return TRUE;
604 }
605 
mailMsg(IJS_Context * cc,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)606 FX_BOOL app::mailMsg(IJS_Context* cc,
607                      const std::vector<CJS_Value>& params,
608                      CJS_Value& vRet,
609                      CFX_WideString& sError) {
610   if (params.size() < 1)
611     return FALSE;
612 
613   FX_BOOL bUI = TRUE;
614   CFX_WideString cTo = L"";
615   CFX_WideString cCc = L"";
616   CFX_WideString cBcc = L"";
617   CFX_WideString cSubject = L"";
618   CFX_WideString cMsg = L"";
619 
620   CJS_Context* pContext = static_cast<CJS_Context*>(cc);
621   CJS_Runtime* pRuntime = pContext->GetJSRuntime();
622   v8::Isolate* isolate = pRuntime->GetIsolate();
623 
624   if (params[0].GetType() == CJS_Value::VT_object) {
625     v8::Local<v8::Object> pObj = params[0].ToV8Object();
626 
627     v8::Local<v8::Value> pValue = FXJS_GetObjectElement(isolate, pObj, L"bUI");
628     bUI = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToBool();
629 
630     pValue = FXJS_GetObjectElement(isolate, pObj, L"cTo");
631     cTo = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
632 
633     pValue = FXJS_GetObjectElement(isolate, pObj, L"cCc");
634     cCc = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
635 
636     pValue = FXJS_GetObjectElement(isolate, pObj, L"cBcc");
637     cBcc =
638         CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
639 
640     pValue = FXJS_GetObjectElement(isolate, pObj, L"cSubject");
641     cSubject =
642         CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
643 
644     pValue = FXJS_GetObjectElement(isolate, pObj, L"cMsg");
645     cMsg =
646         CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
647   } else {
648     if (params.size() < 2)
649       return FALSE;
650 
651     bUI = params[0].ToBool();
652     cTo = params[1].ToCFXWideString();
653 
654     if (params.size() >= 3)
655       cCc = params[2].ToCFXWideString();
656     if (params.size() >= 4)
657       cBcc = params[3].ToCFXWideString();
658     if (params.size() >= 5)
659       cSubject = params[4].ToCFXWideString();
660     if (params.size() >= 6)
661       cMsg = params[5].ToCFXWideString();
662   }
663 
664   pRuntime->BeginBlock();
665   pContext->GetReaderApp()->JS_docmailForm(NULL, 0, bUI, cTo.c_str(),
666                                            cSubject.c_str(), cCc.c_str(),
667                                            cBcc.c_str(), cMsg.c_str());
668   pRuntime->EndBlock();
669 
670   return FALSE;
671 }
672 
launchURL(IJS_Context * cc,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)673 FX_BOOL app::launchURL(IJS_Context* cc,
674                        const std::vector<CJS_Value>& params,
675                        CJS_Value& vRet,
676                        CFX_WideString& sError) {
677   // Unsafe, not supported.
678   return TRUE;
679 }
680 
runtimeHighlight(IJS_Context * cc,CJS_PropValue & vp,CFX_WideString & sError)681 FX_BOOL app::runtimeHighlight(IJS_Context* cc,
682                               CJS_PropValue& vp,
683                               CFX_WideString& sError) {
684   if (vp.IsSetting()) {
685     vp >> m_bRuntimeHighLight;
686   } else {
687     vp << m_bRuntimeHighLight;
688   }
689 
690   return TRUE;
691 }
692 
fullscreen(IJS_Context * cc,CJS_PropValue & vp,CFX_WideString & sError)693 FX_BOOL app::fullscreen(IJS_Context* cc,
694                         CJS_PropValue& vp,
695                         CFX_WideString& sError) {
696   return FALSE;
697 }
698 
popUpMenu(IJS_Context * cc,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)699 FX_BOOL app::popUpMenu(IJS_Context* cc,
700                        const std::vector<CJS_Value>& params,
701                        CJS_Value& vRet,
702                        CFX_WideString& sError) {
703   return FALSE;
704 }
705 
browseForDoc(IJS_Context * cc,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)706 FX_BOOL app::browseForDoc(IJS_Context* cc,
707                           const std::vector<CJS_Value>& params,
708                           CJS_Value& vRet,
709                           CFX_WideString& sError) {
710   // Unsafe, not supported.
711   return TRUE;
712 }
713 
SysPathToPDFPath(const CFX_WideString & sOldPath)714 CFX_WideString app::SysPathToPDFPath(const CFX_WideString& sOldPath) {
715   CFX_WideString sRet = L"/";
716 
717   for (int i = 0, sz = sOldPath.GetLength(); i < sz; i++) {
718     wchar_t c = sOldPath.GetAt(i);
719     if (c == L':') {
720     } else {
721       if (c == L'\\') {
722         sRet += L"/";
723       } else {
724         sRet += c;
725       }
726     }
727   }
728 
729   return sRet;
730 }
731 
newDoc(IJS_Context * cc,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)732 FX_BOOL app::newDoc(IJS_Context* cc,
733                     const std::vector<CJS_Value>& params,
734                     CJS_Value& vRet,
735                     CFX_WideString& sError) {
736   return FALSE;
737 }
738 
openDoc(IJS_Context * cc,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)739 FX_BOOL app::openDoc(IJS_Context* cc,
740                      const std::vector<CJS_Value>& params,
741                      CJS_Value& vRet,
742                      CFX_WideString& sError) {
743   return FALSE;
744 }
745 
response(IJS_Context * cc,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)746 FX_BOOL app::response(IJS_Context* cc,
747                       const std::vector<CJS_Value>& params,
748                       CJS_Value& vRet,
749                       CFX_WideString& sError) {
750   CFX_WideString swQuestion = L"";
751   CFX_WideString swLabel = L"";
752   CFX_WideString swTitle = L"PDF";
753   CFX_WideString swDefault = L"";
754   bool bPassWord = false;
755 
756   CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
757   v8::Isolate* isolate = pRuntime->GetIsolate();
758 
759   int iLength = params.size();
760   if (iLength > 0 && params[0].GetType() == CJS_Value::VT_object) {
761     v8::Local<v8::Object> pObj = params[0].ToV8Object();
762     v8::Local<v8::Value> pValue =
763         FXJS_GetObjectElement(isolate, pObj, L"cQuestion");
764     swQuestion =
765         CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
766 
767     pValue = FXJS_GetObjectElement(isolate, pObj, L"cTitle");
768     swTitle =
769         CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
770 
771     pValue = FXJS_GetObjectElement(isolate, pObj, L"cDefault");
772     swDefault =
773         CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
774 
775     pValue = FXJS_GetObjectElement(isolate, pObj, L"cLabel");
776     swLabel =
777         CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
778 
779     pValue = FXJS_GetObjectElement(isolate, pObj, L"bPassword");
780     bPassWord = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToBool();
781   } else {
782     switch (iLength) {
783       case 5:
784         swLabel = params[4].ToCFXWideString();
785       // FALLTHROUGH
786       case 4:
787         bPassWord = params[3].ToBool();
788       // FALLTHROUGH
789       case 3:
790         swDefault = params[2].ToCFXWideString();
791       // FALLTHROUGH
792       case 2:
793         swTitle = params[1].ToCFXWideString();
794       // FALLTHROUGH
795       case 1:
796         swQuestion = params[0].ToCFXWideString();
797       // FALLTHROUGH
798       default:
799         break;
800     }
801   }
802 
803   CJS_Context* pContext = (CJS_Context*)cc;
804   CPDFDoc_Environment* pApp = pContext->GetReaderApp();
805 
806   const int MAX_INPUT_BYTES = 2048;
807   std::unique_ptr<char[]> pBuff(new char[MAX_INPUT_BYTES + 2]);
808   memset(pBuff.get(), 0, MAX_INPUT_BYTES + 2);
809   int nLengthBytes = pApp->JS_appResponse(
810       swQuestion.c_str(), swTitle.c_str(), swDefault.c_str(), swLabel.c_str(),
811       bPassWord, pBuff.get(), MAX_INPUT_BYTES);
812   if (nLengthBytes <= 0) {
813     vRet.SetNull();
814     return FALSE;
815   }
816   nLengthBytes = std::min(nLengthBytes, MAX_INPUT_BYTES);
817 
818   CFX_WideString ret_string = CFX_WideString::FromUTF16LE(
819       (unsigned short*)pBuff.get(), nLengthBytes / sizeof(unsigned short));
820   vRet = ret_string.c_str();
821   return TRUE;
822 }
823 
media(IJS_Context * cc,CJS_PropValue & vp,CFX_WideString & sError)824 FX_BOOL app::media(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) {
825   return FALSE;
826 }
827 
execDialog(IJS_Context * cc,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)828 FX_BOOL app::execDialog(IJS_Context* cc,
829                         const std::vector<CJS_Value>& params,
830                         CJS_Value& vRet,
831                         CFX_WideString& sError) {
832   return TRUE;
833 }
834