• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "fpdfsdk/javascript/app.h"
8 
9 #include <map>
10 #include <memory>
11 #include <vector>
12 
13 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
14 #include "fpdfsdk/cpdfsdk_interform.h"
15 #include "fpdfsdk/javascript/Document.h"
16 #include "fpdfsdk/javascript/JS_Define.h"
17 #include "fpdfsdk/javascript/JS_EventHandler.h"
18 #include "fpdfsdk/javascript/JS_Object.h"
19 #include "fpdfsdk/javascript/JS_Value.h"
20 #include "fpdfsdk/javascript/cjs_event_context.h"
21 #include "fpdfsdk/javascript/cjs_runtime.h"
22 #include "fpdfsdk/javascript/resource.h"
23 #include "third_party/base/stl_util.h"
24 
25 class GlobalTimer {
26  public:
27   GlobalTimer(app* pObj,
28               CPDFSDK_FormFillEnvironment* pFormFillEnv,
29               CJS_Runtime* pRuntime,
30               int nType,
31               const CFX_WideString& script,
32               uint32_t dwElapse,
33               uint32_t dwTimeOut);
34   ~GlobalTimer();
35 
36   static void Trigger(int nTimerID);
37   static void Cancel(int nTimerID);
38 
IsOneShot() const39   bool IsOneShot() const { return m_nType == 1; }
GetTimeOut() const40   uint32_t GetTimeOut() const { return m_dwTimeOut; }
GetTimerID() const41   int GetTimerID() const { return m_nTimerID; }
GetRuntime() const42   CJS_Runtime* GetRuntime() const { return m_pRuntime.Get(); }
GetJScript() const43   CFX_WideString GetJScript() const { return m_swJScript; }
44 
45  private:
46   using TimerMap = std::map<uint32_t, GlobalTimer*>;
47   static TimerMap* GetGlobalTimerMap();
48 
49   uint32_t m_nTimerID;
50   app* const m_pEmbedObj;
51   bool m_bProcessing;
52 
53   // data
54   const int m_nType;  // 0:Interval; 1:TimeOut
55   const uint32_t m_dwTimeOut;
56   const CFX_WideString m_swJScript;
57   CJS_Runtime::ObservedPtr m_pRuntime;
58   CPDFSDK_FormFillEnvironment::ObservedPtr m_pFormFillEnv;
59 };
60 
GlobalTimer(app * pObj,CPDFSDK_FormFillEnvironment * pFormFillEnv,CJS_Runtime * pRuntime,int nType,const CFX_WideString & script,uint32_t dwElapse,uint32_t dwTimeOut)61 GlobalTimer::GlobalTimer(app* pObj,
62                          CPDFSDK_FormFillEnvironment* pFormFillEnv,
63                          CJS_Runtime* pRuntime,
64                          int nType,
65                          const CFX_WideString& script,
66                          uint32_t dwElapse,
67                          uint32_t dwTimeOut)
68     : m_nTimerID(0),
69       m_pEmbedObj(pObj),
70       m_bProcessing(false),
71       m_nType(nType),
72       m_dwTimeOut(dwTimeOut),
73       m_swJScript(script),
74       m_pRuntime(pRuntime),
75       m_pFormFillEnv(pFormFillEnv) {
76   CFX_SystemHandler* pHandler = m_pFormFillEnv->GetSysHandler();
77   m_nTimerID = pHandler->SetTimer(dwElapse, Trigger);
78   if (m_nTimerID)
79     (*GetGlobalTimerMap())[m_nTimerID] = this;
80 }
81 
~GlobalTimer()82 GlobalTimer::~GlobalTimer() {
83   if (!m_nTimerID)
84     return;
85 
86   if (GetRuntime())
87     m_pFormFillEnv->GetSysHandler()->KillTimer(m_nTimerID);
88 
89   GetGlobalTimerMap()->erase(m_nTimerID);
90 }
91 
92 // static
Trigger(int nTimerID)93 void GlobalTimer::Trigger(int nTimerID) {
94   auto it = GetGlobalTimerMap()->find(nTimerID);
95   if (it == GetGlobalTimerMap()->end())
96     return;
97 
98   GlobalTimer* pTimer = it->second;
99   if (pTimer->m_bProcessing)
100     return;
101 
102   pTimer->m_bProcessing = true;
103   if (pTimer->m_pEmbedObj)
104     pTimer->m_pEmbedObj->TimerProc(pTimer);
105 
106   // Timer proc may have destroyed timer, find it again.
107   it = GetGlobalTimerMap()->find(nTimerID);
108   if (it == GetGlobalTimerMap()->end())
109     return;
110 
111   pTimer = it->second;
112   pTimer->m_bProcessing = false;
113   if (pTimer->IsOneShot())
114     pTimer->m_pEmbedObj->CancelProc(pTimer);
115 }
116 
117 // static
Cancel(int nTimerID)118 void GlobalTimer::Cancel(int nTimerID) {
119   auto it = GetGlobalTimerMap()->find(nTimerID);
120   if (it == GetGlobalTimerMap()->end())
121     return;
122 
123   GlobalTimer* pTimer = it->second;
124   pTimer->m_pEmbedObj->CancelProc(pTimer);
125 }
126 
127 // static
GetGlobalTimerMap()128 GlobalTimer::TimerMap* GlobalTimer::GetGlobalTimerMap() {
129   // Leak the timer array at shutdown.
130   static auto* s_TimerMap = new TimerMap;
131   return s_TimerMap;
132 }
133 
134 JSConstSpec CJS_TimerObj::ConstSpecs[] = {{0, JSConstSpec::Number, 0, 0}};
135 
136 JSPropertySpec CJS_TimerObj::PropertySpecs[] = {{0, 0, 0}};
137 
138 JSMethodSpec CJS_TimerObj::MethodSpecs[] = {{0, 0}};
139 
IMPLEMENT_JS_CLASS(CJS_TimerObj,TimerObj)140 IMPLEMENT_JS_CLASS(CJS_TimerObj, TimerObj)
141 
142 TimerObj::TimerObj(CJS_Object* pJSObject)
143     : CJS_EmbedObj(pJSObject), m_nTimerID(0) {}
144 
~TimerObj()145 TimerObj::~TimerObj() {}
146 
SetTimer(GlobalTimer * pTimer)147 void TimerObj::SetTimer(GlobalTimer* pTimer) {
148   m_nTimerID = pTimer->GetTimerID();
149 }
150 
151 #define JS_STR_VIEWERTYPE L"pdfium"
152 #define JS_STR_VIEWERVARIATION L"Full"
153 #define JS_STR_PLATFORM L"WIN"
154 #define JS_STR_LANGUAGE L"ENU"
155 #define JS_NUM_VIEWERVERSION 8
156 #ifdef PDF_ENABLE_XFA
157 #define JS_NUM_VIEWERVERSION_XFA 11
158 #endif  // PDF_ENABLE_XFA
159 #define JS_NUM_FORMSVERSION 7
160 
161 JSConstSpec CJS_App::ConstSpecs[] = {{0, JSConstSpec::Number, 0, 0}};
162 
163 JSPropertySpec CJS_App::PropertySpecs[] = {
164     {"activeDocs", get_activeDocs_static, set_activeDocs_static},
165     {"calculate", get_calculate_static, set_calculate_static},
166     {"formsVersion", get_formsVersion_static, set_formsVersion_static},
167     {"fs", get_fs_static, set_fs_static},
168     {"fullscreen", get_fullscreen_static, set_fullscreen_static},
169     {"language", get_language_static, set_language_static},
170     {"media", get_media_static, set_media_static},
171     {"platform", get_platform_static, set_platform_static},
172     {"runtimeHighlight", get_runtimeHighlight_static,
173      set_runtimeHighlight_static},
174     {"viewerType", get_viewerType_static, set_viewerType_static},
175     {"viewerVariation", get_viewerVariation_static, set_viewerVariation_static},
176     {"viewerVersion", get_viewerVersion_static, set_viewerVersion_static},
177     {0, 0, 0}};
178 
179 JSMethodSpec CJS_App::MethodSpecs[] = {{"alert", alert_static},
180                                        {"beep", beep_static},
181                                        {"browseForDoc", browseForDoc_static},
182                                        {"clearInterval", clearInterval_static},
183                                        {"clearTimeOut", clearTimeOut_static},
184                                        {"execDialog", execDialog_static},
185                                        {"execMenuItem", execMenuItem_static},
186                                        {"findComponent", findComponent_static},
187                                        {"goBack", goBack_static},
188                                        {"goForward", goForward_static},
189                                        {"launchURL", launchURL_static},
190                                        {"mailMsg", mailMsg_static},
191                                        {"newFDF", newFDF_static},
192                                        {"newDoc", newDoc_static},
193                                        {"openDoc", openDoc_static},
194                                        {"openFDF", openFDF_static},
195                                        {"popUpMenuEx", popUpMenuEx_static},
196                                        {"popUpMenu", popUpMenu_static},
197                                        {"response", response_static},
198                                        {"setInterval", setInterval_static},
199                                        {"setTimeOut", setTimeOut_static},
200                                        {0, 0}};
201 
IMPLEMENT_JS_CLASS(CJS_App,app)202 IMPLEMENT_JS_CLASS(CJS_App, app)
203 
204 app::app(CJS_Object* pJSObject)
205     : CJS_EmbedObj(pJSObject), m_bCalculate(true), m_bRuntimeHighLight(false) {}
206 
~app()207 app::~app() {
208 }
209 
activeDocs(CJS_Runtime * pRuntime,CJS_PropValue & vp,CFX_WideString & sError)210 bool app::activeDocs(CJS_Runtime* pRuntime,
211                      CJS_PropValue& vp,
212                      CFX_WideString& sError) {
213   if (!vp.IsGetting())
214     return false;
215 
216   CJS_Document* pJSDocument = nullptr;
217   v8::Local<v8::Object> pObj = pRuntime->GetThisObj();
218   if (CFXJS_Engine::GetObjDefnID(pObj) == CJS_Document::g_nObjDefnID)
219     pJSDocument = static_cast<CJS_Document*>(pRuntime->GetObjectPrivate(pObj));
220 
221   CJS_Array aDocs;
222   aDocs.SetElement(pRuntime, 0, CJS_Value(pRuntime, pJSDocument));
223   if (aDocs.GetLength(pRuntime) > 0)
224     vp << aDocs;
225   else
226     vp.GetJSValue()->SetNull(pRuntime);
227 
228   return true;
229 }
230 
calculate(CJS_Runtime * pRuntime,CJS_PropValue & vp,CFX_WideString & sError)231 bool app::calculate(CJS_Runtime* pRuntime,
232                     CJS_PropValue& vp,
233                     CFX_WideString& sError) {
234   if (vp.IsSetting()) {
235     bool bVP;
236     vp >> bVP;
237     m_bCalculate = (bool)bVP;
238     pRuntime->GetFormFillEnv()->GetInterForm()->EnableCalculate(
239         (bool)m_bCalculate);
240   } else {
241     vp << (bool)m_bCalculate;
242   }
243   return true;
244 }
245 
formsVersion(CJS_Runtime * pRuntime,CJS_PropValue & vp,CFX_WideString & sError)246 bool app::formsVersion(CJS_Runtime* pRuntime,
247                        CJS_PropValue& vp,
248                        CFX_WideString& sError) {
249   if (vp.IsGetting()) {
250     vp << JS_NUM_FORMSVERSION;
251     return true;
252   }
253 
254   return false;
255 }
256 
viewerType(CJS_Runtime * pRuntime,CJS_PropValue & vp,CFX_WideString & sError)257 bool app::viewerType(CJS_Runtime* pRuntime,
258                      CJS_PropValue& vp,
259                      CFX_WideString& sError) {
260   if (vp.IsGetting()) {
261     vp << JS_STR_VIEWERTYPE;
262     return true;
263   }
264 
265   return false;
266 }
267 
viewerVariation(CJS_Runtime * pRuntime,CJS_PropValue & vp,CFX_WideString & sError)268 bool app::viewerVariation(CJS_Runtime* pRuntime,
269                           CJS_PropValue& vp,
270                           CFX_WideString& sError) {
271   if (vp.IsGetting()) {
272     vp << JS_STR_VIEWERVARIATION;
273     return true;
274   }
275 
276   return false;
277 }
278 
viewerVersion(CJS_Runtime * pRuntime,CJS_PropValue & vp,CFX_WideString & sError)279 bool app::viewerVersion(CJS_Runtime* pRuntime,
280                         CJS_PropValue& vp,
281                         CFX_WideString& sError) {
282   if (!vp.IsGetting())
283     return false;
284 #ifdef PDF_ENABLE_XFA
285   CPDFXFA_Context* pXFAContext = pRuntime->GetFormFillEnv()->GetXFAContext();
286   if (pXFAContext->GetDocType() == 1 || pXFAContext->GetDocType() == 2) {
287     vp << JS_NUM_VIEWERVERSION_XFA;
288     return true;
289   }
290 #endif  // PDF_ENABLE_XFA
291   vp << JS_NUM_VIEWERVERSION;
292   return true;
293 }
294 
platform(CJS_Runtime * pRuntime,CJS_PropValue & vp,CFX_WideString & sError)295 bool app::platform(CJS_Runtime* pRuntime,
296                    CJS_PropValue& vp,
297                    CFX_WideString& sError) {
298   if (!vp.IsGetting())
299     return false;
300 #ifdef PDF_ENABLE_XFA
301   CPDFSDK_FormFillEnvironment* pFormFillEnv = pRuntime->GetFormFillEnv();
302   if (!pFormFillEnv)
303     return false;
304   CFX_WideString platfrom = pFormFillEnv->GetPlatform();
305   if (!platfrom.IsEmpty()) {
306     vp << platfrom;
307     return true;
308   }
309 #endif
310   vp << JS_STR_PLATFORM;
311   return true;
312 }
313 
language(CJS_Runtime * pRuntime,CJS_PropValue & vp,CFX_WideString & sError)314 bool app::language(CJS_Runtime* pRuntime,
315                    CJS_PropValue& vp,
316                    CFX_WideString& sError) {
317   if (!vp.IsGetting())
318     return false;
319 #ifdef PDF_ENABLE_XFA
320   CPDFSDK_FormFillEnvironment* pFormFillEnv = pRuntime->GetFormFillEnv();
321   if (!pFormFillEnv)
322     return false;
323   CFX_WideString language = pFormFillEnv->GetLanguage();
324   if (!language.IsEmpty()) {
325     vp << language;
326     return true;
327   }
328 #endif
329   vp << JS_STR_LANGUAGE;
330   return true;
331 }
332 
333 // creates a new fdf object that contains no data
334 // comment: need reader support
335 // note:
336 // CFDF_Document * CPDFSDK_FormFillEnvironment::NewFDF();
newFDF(CJS_Runtime * pRuntime,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)337 bool app::newFDF(CJS_Runtime* pRuntime,
338                  const std::vector<CJS_Value>& params,
339                  CJS_Value& vRet,
340                  CFX_WideString& sError) {
341   return true;
342 }
343 // opens a specified pdf document and returns its document object
344 // comment:need reader support
345 // note: as defined in js reference, the proto of this function's fourth
346 // parmeters, how old an fdf document while do not show it.
347 // CFDF_Document * CPDFSDK_FormFillEnvironment::OpenFDF(string strPath,bool
348 // bUserConv);
349 
openFDF(CJS_Runtime * pRuntime,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)350 bool app::openFDF(CJS_Runtime* pRuntime,
351                   const std::vector<CJS_Value>& params,
352                   CJS_Value& vRet,
353                   CFX_WideString& sError) {
354   return true;
355 }
356 
alert(CJS_Runtime * pRuntime,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)357 bool app::alert(CJS_Runtime* pRuntime,
358                 const std::vector<CJS_Value>& params,
359                 CJS_Value& vRet,
360                 CFX_WideString& sError) {
361   std::vector<CJS_Value> newParams = JS_ExpandKeywordParams(
362       pRuntime, params, 4, L"cMsg", L"nIcon", L"nType", L"cTitle");
363 
364   if (newParams[0].GetType() == CJS_Value::VT_unknown) {
365     sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
366     return false;
367   }
368 
369   CPDFSDK_FormFillEnvironment* pFormFillEnv = pRuntime->GetFormFillEnv();
370   if (!pFormFillEnv) {
371     vRet = CJS_Value(pRuntime, 0);
372     return true;
373   }
374 
375   CFX_WideString swMsg;
376   if (newParams[0].GetType() == CJS_Value::VT_object) {
377     CJS_Array carray;
378     if (newParams[0].ConvertToArray(pRuntime, carray)) {
379       swMsg = L"[";
380       CJS_Value element(pRuntime);
381       for (int i = 0; i < carray.GetLength(pRuntime); ++i) {
382         if (i)
383           swMsg += L", ";
384         carray.GetElement(pRuntime, i, element);
385         swMsg += element.ToCFXWideString(pRuntime);
386       }
387       swMsg += L"]";
388     } else {
389       swMsg = newParams[0].ToCFXWideString(pRuntime);
390     }
391   } else {
392     swMsg = newParams[0].ToCFXWideString(pRuntime);
393   }
394 
395   int iIcon = 0;
396   if (newParams[1].GetType() != CJS_Value::VT_unknown)
397     iIcon = newParams[1].ToInt(pRuntime);
398 
399   int iType = 0;
400   if (newParams[2].GetType() != CJS_Value::VT_unknown)
401     iType = newParams[2].ToInt(pRuntime);
402 
403   CFX_WideString swTitle;
404   if (newParams[3].GetType() != CJS_Value::VT_unknown)
405     swTitle = newParams[3].ToCFXWideString(pRuntime);
406   else
407     swTitle = JSGetStringFromID(IDS_STRING_JSALERT);
408 
409   pRuntime->BeginBlock();
410   pFormFillEnv->KillFocusAnnot(0);
411 
412   vRet = CJS_Value(pRuntime, pFormFillEnv->JS_appAlert(
413                                  swMsg.c_str(), swTitle.c_str(), iType, iIcon));
414   pRuntime->EndBlock();
415   return true;
416 }
417 
beep(CJS_Runtime * pRuntime,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)418 bool app::beep(CJS_Runtime* pRuntime,
419                const std::vector<CJS_Value>& params,
420                CJS_Value& vRet,
421                CFX_WideString& sError) {
422   if (params.size() == 1) {
423     pRuntime->GetFormFillEnv()->JS_appBeep(params[0].ToInt(pRuntime));
424     return true;
425   }
426 
427   sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
428   return false;
429 }
430 
findComponent(CJS_Runtime * pRuntime,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)431 bool app::findComponent(CJS_Runtime* pRuntime,
432                         const std::vector<CJS_Value>& params,
433                         CJS_Value& vRet,
434                         CFX_WideString& sError) {
435   return true;
436 }
437 
popUpMenuEx(CJS_Runtime * pRuntime,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)438 bool app::popUpMenuEx(CJS_Runtime* pRuntime,
439                       const std::vector<CJS_Value>& params,
440                       CJS_Value& vRet,
441                       CFX_WideString& sError) {
442   return false;
443 }
444 
fs(CJS_Runtime * pRuntime,CJS_PropValue & vp,CFX_WideString & sError)445 bool app::fs(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) {
446   return false;
447 }
448 
setInterval(CJS_Runtime * pRuntime,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)449 bool app::setInterval(CJS_Runtime* pRuntime,
450                       const std::vector<CJS_Value>& params,
451                       CJS_Value& vRet,
452                       CFX_WideString& sError) {
453   if (params.size() > 2 || params.size() == 0) {
454     sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
455     return false;
456   }
457 
458   CFX_WideString script =
459       params.size() > 0 ? params[0].ToCFXWideString(pRuntime) : L"";
460   if (script.IsEmpty()) {
461     sError = JSGetStringFromID(IDS_STRING_JSAFNUMBER_KEYSTROKE);
462     return true;
463   }
464 
465   uint32_t dwInterval = params.size() > 1 ? params[1].ToInt(pRuntime) : 1000;
466 
467   GlobalTimer* timerRef = new GlobalTimer(this, pRuntime->GetFormFillEnv(),
468                                           pRuntime, 0, script, dwInterval, 0);
469   m_Timers.insert(std::unique_ptr<GlobalTimer>(timerRef));
470 
471   v8::Local<v8::Object> pRetObj =
472       pRuntime->NewFxDynamicObj(CJS_TimerObj::g_nObjDefnID);
473   if (pRetObj.IsEmpty())
474     return false;
475 
476   CJS_TimerObj* pJS_TimerObj =
477       static_cast<CJS_TimerObj*>(pRuntime->GetObjectPrivate(pRetObj));
478   TimerObj* pTimerObj = static_cast<TimerObj*>(pJS_TimerObj->GetEmbedObject());
479   pTimerObj->SetTimer(timerRef);
480 
481   vRet = CJS_Value(pRuntime, pRetObj);
482   return true;
483 }
484 
setTimeOut(CJS_Runtime * pRuntime,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)485 bool app::setTimeOut(CJS_Runtime* pRuntime,
486                      const std::vector<CJS_Value>& params,
487                      CJS_Value& vRet,
488                      CFX_WideString& sError) {
489   if (params.size() > 2 || params.size() == 0) {
490     sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
491     return false;
492   }
493 
494   CFX_WideString script = params[0].ToCFXWideString(pRuntime);
495   if (script.IsEmpty()) {
496     sError = JSGetStringFromID(IDS_STRING_JSAFNUMBER_KEYSTROKE);
497     return true;
498   }
499 
500   uint32_t dwTimeOut = params.size() > 1 ? params[1].ToInt(pRuntime) : 1000;
501   GlobalTimer* timerRef =
502       new GlobalTimer(this, pRuntime->GetFormFillEnv(), pRuntime, 1, script,
503                       dwTimeOut, dwTimeOut);
504   m_Timers.insert(std::unique_ptr<GlobalTimer>(timerRef));
505 
506   v8::Local<v8::Object> pRetObj =
507       pRuntime->NewFxDynamicObj(CJS_TimerObj::g_nObjDefnID);
508   if (pRetObj.IsEmpty())
509     return false;
510 
511   CJS_TimerObj* pJS_TimerObj =
512       static_cast<CJS_TimerObj*>(pRuntime->GetObjectPrivate(pRetObj));
513   TimerObj* pTimerObj = static_cast<TimerObj*>(pJS_TimerObj->GetEmbedObject());
514   pTimerObj->SetTimer(timerRef);
515   vRet = CJS_Value(pRuntime, pRetObj);
516   return true;
517 }
518 
clearTimeOut(CJS_Runtime * pRuntime,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)519 bool app::clearTimeOut(CJS_Runtime* pRuntime,
520                        const std::vector<CJS_Value>& params,
521                        CJS_Value& vRet,
522                        CFX_WideString& sError) {
523   if (params.size() != 1) {
524     sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
525     return false;
526   }
527 
528   app::ClearTimerCommon(pRuntime, params[0]);
529   return true;
530 }
531 
clearInterval(CJS_Runtime * pRuntime,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)532 bool app::clearInterval(CJS_Runtime* pRuntime,
533                         const std::vector<CJS_Value>& params,
534                         CJS_Value& vRet,
535                         CFX_WideString& sError) {
536   if (params.size() != 1) {
537     sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
538     return false;
539   }
540 
541   app::ClearTimerCommon(pRuntime, params[0]);
542   return true;
543 }
544 
ClearTimerCommon(CJS_Runtime * pRuntime,const CJS_Value & param)545 void app::ClearTimerCommon(CJS_Runtime* pRuntime, const CJS_Value& param) {
546   if (param.GetType() != CJS_Value::VT_object)
547     return;
548 
549   v8::Local<v8::Object> pObj = param.ToV8Object(pRuntime);
550   if (CFXJS_Engine::GetObjDefnID(pObj) != CJS_TimerObj::g_nObjDefnID)
551     return;
552 
553   CJS_Object* pJSObj = param.ToCJSObject(pRuntime);
554   if (!pJSObj)
555     return;
556 
557   TimerObj* pTimerObj = static_cast<TimerObj*>(pJSObj->GetEmbedObject());
558   if (!pTimerObj)
559     return;
560 
561   GlobalTimer::Cancel(pTimerObj->GetTimerID());
562 }
563 
execMenuItem(CJS_Runtime * pRuntime,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)564 bool app::execMenuItem(CJS_Runtime* pRuntime,
565                        const std::vector<CJS_Value>& params,
566                        CJS_Value& vRet,
567                        CFX_WideString& sError) {
568   return false;
569 }
570 
TimerProc(GlobalTimer * pTimer)571 void app::TimerProc(GlobalTimer* pTimer) {
572   CJS_Runtime* pRuntime = pTimer->GetRuntime();
573   if (pRuntime && (!pTimer->IsOneShot() || pTimer->GetTimeOut() > 0))
574     RunJsScript(pRuntime, pTimer->GetJScript());
575 }
576 
CancelProc(GlobalTimer * pTimer)577 void app::CancelProc(GlobalTimer* pTimer) {
578   m_Timers.erase(pdfium::FakeUniquePtr<GlobalTimer>(pTimer));
579 }
580 
RunJsScript(CJS_Runtime * pRuntime,const CFX_WideString & wsScript)581 void app::RunJsScript(CJS_Runtime* pRuntime, const CFX_WideString& wsScript) {
582   if (!pRuntime->IsBlocking()) {
583     IJS_EventContext* pContext = pRuntime->NewEventContext();
584     pContext->OnExternal_Exec();
585     CFX_WideString wtInfo;
586     pContext->RunScript(wsScript, &wtInfo);
587     pRuntime->ReleaseEventContext(pContext);
588   }
589 }
590 
goBack(CJS_Runtime * pRuntime,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)591 bool app::goBack(CJS_Runtime* pRuntime,
592                  const std::vector<CJS_Value>& params,
593                  CJS_Value& vRet,
594                  CFX_WideString& sError) {
595   // Not supported.
596   return true;
597 }
598 
goForward(CJS_Runtime * pRuntime,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)599 bool app::goForward(CJS_Runtime* pRuntime,
600                     const std::vector<CJS_Value>& params,
601                     CJS_Value& vRet,
602                     CFX_WideString& sError) {
603   // Not supported.
604   return true;
605 }
606 
mailMsg(CJS_Runtime * pRuntime,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)607 bool app::mailMsg(CJS_Runtime* pRuntime,
608                   const std::vector<CJS_Value>& params,
609                   CJS_Value& vRet,
610                   CFX_WideString& sError) {
611   std::vector<CJS_Value> newParams =
612       JS_ExpandKeywordParams(pRuntime, params, 6, L"bUI", L"cTo", L"cCc",
613                              L"cBcc", L"cSubject", L"cMsg");
614 
615   if (newParams[0].GetType() == CJS_Value::VT_unknown) {
616     sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
617     return false;
618   }
619   bool bUI = newParams[0].ToBool(pRuntime);
620 
621   CFX_WideString cTo;
622   if (newParams[1].GetType() != CJS_Value::VT_unknown) {
623     cTo = newParams[1].ToCFXWideString(pRuntime);
624   } else {
625     if (!bUI) {
626       // cTo parameter required when UI not invoked.
627       sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
628       return false;
629     }
630   }
631 
632   CFX_WideString cCc;
633   if (newParams[2].GetType() != CJS_Value::VT_unknown)
634     cCc = newParams[2].ToCFXWideString(pRuntime);
635 
636   CFX_WideString cBcc;
637   if (newParams[3].GetType() != CJS_Value::VT_unknown)
638     cBcc = newParams[3].ToCFXWideString(pRuntime);
639 
640   CFX_WideString cSubject;
641   if (newParams[4].GetType() != CJS_Value::VT_unknown)
642     cSubject = newParams[4].ToCFXWideString(pRuntime);
643 
644   CFX_WideString cMsg;
645   if (newParams[5].GetType() != CJS_Value::VT_unknown)
646     cMsg = newParams[5].ToCFXWideString(pRuntime);
647 
648   pRuntime->BeginBlock();
649   pRuntime->GetFormFillEnv()->JS_docmailForm(nullptr, 0, bUI, cTo.c_str(),
650                                              cSubject.c_str(), cCc.c_str(),
651                                              cBcc.c_str(), cMsg.c_str());
652   pRuntime->EndBlock();
653   return true;
654 }
655 
launchURL(CJS_Runtime * pRuntime,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)656 bool app::launchURL(CJS_Runtime* pRuntime,
657                     const std::vector<CJS_Value>& params,
658                     CJS_Value& vRet,
659                     CFX_WideString& sError) {
660   // Unsafe, not supported.
661   return true;
662 }
663 
runtimeHighlight(CJS_Runtime * pRuntime,CJS_PropValue & vp,CFX_WideString & sError)664 bool app::runtimeHighlight(CJS_Runtime* pRuntime,
665                            CJS_PropValue& vp,
666                            CFX_WideString& sError) {
667   if (vp.IsSetting()) {
668     vp >> m_bRuntimeHighLight;
669   } else {
670     vp << m_bRuntimeHighLight;
671   }
672   return true;
673 }
674 
fullscreen(CJS_Runtime * pRuntime,CJS_PropValue & vp,CFX_WideString & sError)675 bool app::fullscreen(CJS_Runtime* pRuntime,
676                      CJS_PropValue& vp,
677                      CFX_WideString& sError) {
678   return false;
679 }
680 
popUpMenu(CJS_Runtime * pRuntime,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)681 bool app::popUpMenu(CJS_Runtime* pRuntime,
682                     const std::vector<CJS_Value>& params,
683                     CJS_Value& vRet,
684                     CFX_WideString& sError) {
685   return false;
686 }
687 
browseForDoc(CJS_Runtime * pRuntime,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)688 bool app::browseForDoc(CJS_Runtime* pRuntime,
689                        const std::vector<CJS_Value>& params,
690                        CJS_Value& vRet,
691                        CFX_WideString& sError) {
692   // Unsafe, not supported.
693   return true;
694 }
695 
SysPathToPDFPath(const CFX_WideString & sOldPath)696 CFX_WideString app::SysPathToPDFPath(const CFX_WideString& sOldPath) {
697   CFX_WideString sRet = L"/";
698 
699   for (int i = 0, sz = sOldPath.GetLength(); i < sz; i++) {
700     wchar_t c = sOldPath.GetAt(i);
701     if (c == L':') {
702     } else {
703       if (c == L'\\') {
704         sRet += L"/";
705       } else {
706         sRet += c;
707       }
708     }
709   }
710 
711   return sRet;
712 }
713 
newDoc(CJS_Runtime * pRuntime,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)714 bool app::newDoc(CJS_Runtime* pRuntime,
715                  const std::vector<CJS_Value>& params,
716                  CJS_Value& vRet,
717                  CFX_WideString& sError) {
718   return false;
719 }
720 
openDoc(CJS_Runtime * pRuntime,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)721 bool app::openDoc(CJS_Runtime* pRuntime,
722                   const std::vector<CJS_Value>& params,
723                   CJS_Value& vRet,
724                   CFX_WideString& sError) {
725   return false;
726 }
727 
response(CJS_Runtime * pRuntime,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)728 bool app::response(CJS_Runtime* pRuntime,
729                    const std::vector<CJS_Value>& params,
730                    CJS_Value& vRet,
731                    CFX_WideString& sError) {
732   std::vector<CJS_Value> newParams =
733       JS_ExpandKeywordParams(pRuntime, params, 5, L"cQuestion", L"cTitle",
734                              L"cDefault", L"bPassword", L"cLabel");
735 
736   if (newParams[0].GetType() == CJS_Value::VT_unknown) {
737     sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
738     return false;
739   }
740   CFX_WideString swQuestion = newParams[0].ToCFXWideString(pRuntime);
741 
742   CFX_WideString swTitle = L"PDF";
743   if (newParams[1].GetType() != CJS_Value::VT_unknown)
744     swTitle = newParams[1].ToCFXWideString(pRuntime);
745 
746   CFX_WideString swDefault;
747   if (newParams[2].GetType() != CJS_Value::VT_unknown)
748     swDefault = newParams[2].ToCFXWideString(pRuntime);
749 
750   bool bPassword = false;
751   if (newParams[3].GetType() != CJS_Value::VT_unknown)
752     bPassword = newParams[3].ToBool(pRuntime);
753 
754   CFX_WideString swLabel;
755   if (newParams[4].GetType() != CJS_Value::VT_unknown)
756     swLabel = newParams[4].ToCFXWideString(pRuntime);
757 
758   const int MAX_INPUT_BYTES = 2048;
759   std::unique_ptr<char[]> pBuff(new char[MAX_INPUT_BYTES + 2]);
760   memset(pBuff.get(), 0, MAX_INPUT_BYTES + 2);
761 
762   int nLengthBytes = pRuntime->GetFormFillEnv()->JS_appResponse(
763       swQuestion.c_str(), swTitle.c_str(), swDefault.c_str(), swLabel.c_str(),
764       bPassword, pBuff.get(), MAX_INPUT_BYTES);
765 
766   if (nLengthBytes < 0 || nLengthBytes > MAX_INPUT_BYTES) {
767     sError = JSGetStringFromID(IDS_STRING_JSPARAM_TOOLONG);
768     return false;
769   }
770 
771   vRet = CJS_Value(pRuntime, CFX_WideString::FromUTF16LE(
772                                  reinterpret_cast<uint16_t*>(pBuff.get()),
773                                  nLengthBytes / sizeof(uint16_t))
774                                  .c_str());
775 
776   return true;
777 }
778 
media(CJS_Runtime * pRuntime,CJS_PropValue & vp,CFX_WideString & sError)779 bool app::media(CJS_Runtime* pRuntime,
780                 CJS_PropValue& vp,
781                 CFX_WideString& sError) {
782   return false;
783 }
784 
execDialog(CJS_Runtime * pRuntime,const std::vector<CJS_Value> & params,CJS_Value & vRet,CFX_WideString & sError)785 bool app::execDialog(CJS_Runtime* pRuntime,
786                      const std::vector<CJS_Value>& params,
787                      CJS_Value& vRet,
788                      CFX_WideString& sError) {
789   return true;
790 }
791