• 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 "fxjs/cjs_app.h"
8 
9 #include "fpdfsdk/cpdfsdk_interform.h"
10 #include "fxjs/cjs_document.h"
11 #include "fxjs/cjs_timerobj.h"
12 #include "fxjs/global_timer.h"
13 #include "fxjs/ijs_event_context.h"
14 #include "fxjs/js_resources.h"
15 
16 namespace {
17 
IsTypeKnown(v8::Local<v8::Value> value)18 bool IsTypeKnown(v8::Local<v8::Value> value) {
19   return !value.IsEmpty() &&
20          (value->IsString() || value->IsNumber() || value->IsBoolean() ||
21           value->IsDate() || value->IsObject() || value->IsNull() ||
22           value->IsUndefined());
23 }
24 
25 }  // namespace
26 
27 #define JS_STR_VIEWERTYPE L"pdfium"
28 #define JS_STR_VIEWERVARIATION L"Full"
29 #define JS_STR_PLATFORM L"WIN"
30 #define JS_STR_LANGUAGE L"ENU"
31 #define JS_NUM_VIEWERVERSION 8
32 #ifdef PDF_ENABLE_XFA
33 #define JS_NUM_VIEWERVERSION_XFA 11
34 #endif  // PDF_ENABLE_XFA
35 #define JS_NUM_FORMSVERSION 7
36 
37 const JSPropertySpec CJS_App::PropertySpecs[] = {
38     {"activeDocs", get_active_docs_static, set_active_docs_static},
39     {"calculate", get_calculate_static, set_calculate_static},
40     {"formsVersion", get_forms_version_static, set_forms_version_static},
41     {"fs", get_fs_static, set_fs_static},
42     {"fullscreen", get_fullscreen_static, set_fullscreen_static},
43     {"language", get_language_static, set_language_static},
44     {"media", get_media_static, set_media_static},
45     {"platform", get_platform_static, set_platform_static},
46     {"runtimeHighlight", get_runtime_highlight_static,
47      set_runtime_highlight_static},
48     {"viewerType", get_viewer_type_static, set_viewer_type_static},
49     {"viewerVariation", get_viewer_variation_static,
50      set_viewer_variation_static},
51     {"viewerVersion", get_viewer_version_static, set_viewer_version_static}};
52 
53 const JSMethodSpec CJS_App::MethodSpecs[] = {
54     {"alert", alert_static},
55     {"beep", beep_static},
56     {"browseForDoc", browseForDoc_static},
57     {"clearInterval", clearInterval_static},
58     {"clearTimeOut", clearTimeOut_static},
59     {"execDialog", execDialog_static},
60     {"execMenuItem", execMenuItem_static},
61     {"findComponent", findComponent_static},
62     {"goBack", goBack_static},
63     {"goForward", goForward_static},
64     {"launchURL", launchURL_static},
65     {"mailMsg", mailMsg_static},
66     {"newFDF", newFDF_static},
67     {"newDoc", newDoc_static},
68     {"openDoc", openDoc_static},
69     {"openFDF", openFDF_static},
70     {"popUpMenuEx", popUpMenuEx_static},
71     {"popUpMenu", popUpMenu_static},
72     {"response", response_static},
73     {"setInterval", setInterval_static},
74     {"setTimeOut", setTimeOut_static}};
75 
76 int CJS_App::ObjDefnID = -1;
77 
78 // static
DefineJSObjects(CFXJS_Engine * pEngine)79 void CJS_App::DefineJSObjects(CFXJS_Engine* pEngine) {
80   ObjDefnID =
81       pEngine->DefineObj("app", FXJSOBJTYPE_STATIC, JSConstructor<CJS_App, app>,
82                          JSDestructor<CJS_App>);
83   DefineProps(pEngine, ObjDefnID, PropertySpecs, FX_ArraySize(PropertySpecs));
84   DefineMethods(pEngine, ObjDefnID, MethodSpecs, FX_ArraySize(MethodSpecs));
85 }
86 
app(CJS_Object * pJSObject)87 app::app(CJS_Object* pJSObject)
88     : CJS_EmbedObj(pJSObject), m_bCalculate(true), m_bRuntimeHighLight(false) {}
89 
~app()90 app::~app() {}
91 
get_active_docs(CJS_Runtime * pRuntime)92 CJS_Return app::get_active_docs(CJS_Runtime* pRuntime) {
93   CJS_Document* pJSDocument = nullptr;
94   v8::Local<v8::Object> pObj = pRuntime->GetThisObj();
95   if (CFXJS_Engine::GetObjDefnID(pObj) == CJS_Document::GetObjDefnID())
96     pJSDocument = static_cast<CJS_Document*>(pRuntime->GetObjectPrivate(pObj));
97 
98   v8::Local<v8::Array> aDocs = pRuntime->NewArray();
99   pRuntime->PutArrayElement(
100       aDocs, 0,
101       pJSDocument ? v8::Local<v8::Value>(pJSDocument->ToV8Object())
102                   : v8::Local<v8::Value>());
103   if (pRuntime->GetArrayLength(aDocs) > 0)
104     return CJS_Return(aDocs);
105   return CJS_Return(pRuntime->NewUndefined());
106 }
107 
set_active_docs(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)108 CJS_Return app::set_active_docs(CJS_Runtime* pRuntime,
109                                 v8::Local<v8::Value> vp) {
110   return CJS_Return(false);
111 }
112 
get_calculate(CJS_Runtime * pRuntime)113 CJS_Return app::get_calculate(CJS_Runtime* pRuntime) {
114   return CJS_Return(pRuntime->NewBoolean(m_bCalculate));
115 }
116 
set_calculate(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)117 CJS_Return app::set_calculate(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
118   m_bCalculate = pRuntime->ToBoolean(vp);
119   pRuntime->GetFormFillEnv()->GetInterForm()->EnableCalculate(m_bCalculate);
120   return CJS_Return(true);
121 }
122 
get_forms_version(CJS_Runtime * pRuntime)123 CJS_Return app::get_forms_version(CJS_Runtime* pRuntime) {
124   return CJS_Return(pRuntime->NewNumber(JS_NUM_FORMSVERSION));
125 }
126 
set_forms_version(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)127 CJS_Return app::set_forms_version(CJS_Runtime* pRuntime,
128                                   v8::Local<v8::Value> vp) {
129   return CJS_Return(false);
130 }
131 
get_viewer_type(CJS_Runtime * pRuntime)132 CJS_Return app::get_viewer_type(CJS_Runtime* pRuntime) {
133   return CJS_Return(pRuntime->NewString(JS_STR_VIEWERTYPE));
134 }
135 
set_viewer_type(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)136 CJS_Return app::set_viewer_type(CJS_Runtime* pRuntime,
137                                 v8::Local<v8::Value> vp) {
138   return CJS_Return(false);
139 }
140 
get_viewer_variation(CJS_Runtime * pRuntime)141 CJS_Return app::get_viewer_variation(CJS_Runtime* pRuntime) {
142   return CJS_Return(pRuntime->NewString(JS_STR_VIEWERVARIATION));
143 }
144 
set_viewer_variation(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)145 CJS_Return app::set_viewer_variation(CJS_Runtime* pRuntime,
146                                      v8::Local<v8::Value> vp) {
147   return CJS_Return(false);
148 }
149 
get_viewer_version(CJS_Runtime * pRuntime)150 CJS_Return app::get_viewer_version(CJS_Runtime* pRuntime) {
151 #ifdef PDF_ENABLE_XFA
152   CPDFXFA_Context* pXFAContext = pRuntime->GetFormFillEnv()->GetXFAContext();
153   if (pXFAContext->ContainsXFAForm())
154     return CJS_Return(pRuntime->NewNumber(JS_NUM_VIEWERVERSION_XFA));
155 #endif  // PDF_ENABLE_XFA
156   return CJS_Return(pRuntime->NewNumber(JS_NUM_VIEWERVERSION));
157 }
158 
set_viewer_version(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)159 CJS_Return app::set_viewer_version(CJS_Runtime* pRuntime,
160                                    v8::Local<v8::Value> vp) {
161   return CJS_Return(false);
162 }
163 
get_platform(CJS_Runtime * pRuntime)164 CJS_Return app::get_platform(CJS_Runtime* pRuntime) {
165 #ifdef PDF_ENABLE_XFA
166   CPDFSDK_FormFillEnvironment* pFormFillEnv = pRuntime->GetFormFillEnv();
167   if (!pFormFillEnv)
168     return CJS_Return(false);
169 
170   WideString platfrom = pFormFillEnv->GetPlatform();
171   if (!platfrom.IsEmpty())
172     return CJS_Return(pRuntime->NewString(platfrom.c_str()));
173 #endif
174   return CJS_Return(pRuntime->NewString(JS_STR_PLATFORM));
175 }
176 
set_platform(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)177 CJS_Return app::set_platform(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
178   return CJS_Return(false);
179 }
180 
get_language(CJS_Runtime * pRuntime)181 CJS_Return app::get_language(CJS_Runtime* pRuntime) {
182 #ifdef PDF_ENABLE_XFA
183   CPDFSDK_FormFillEnvironment* pFormFillEnv = pRuntime->GetFormFillEnv();
184   if (!pFormFillEnv)
185     return CJS_Return(false);
186 
187   WideString language = pFormFillEnv->GetLanguage();
188   if (!language.IsEmpty())
189     return CJS_Return(pRuntime->NewString(language.c_str()));
190 #endif
191   return CJS_Return(pRuntime->NewString(JS_STR_LANGUAGE));
192 }
193 
set_language(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)194 CJS_Return app::set_language(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
195   return CJS_Return(false);
196 }
197 
198 // creates a new fdf object that contains no data
199 // comment: need reader support
200 // note:
201 // CFDF_Document * CPDFSDK_FormFillEnvironment::NewFDF();
newFDF(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)202 CJS_Return app::newFDF(CJS_Runtime* pRuntime,
203                        const std::vector<v8::Local<v8::Value>>& params) {
204   return CJS_Return(true);
205 }
206 
207 // opens a specified pdf document and returns its document object
208 // comment:need reader support
209 // note: as defined in js reference, the proto of this function's fourth
210 // parmeters, how old an fdf document while do not show it.
211 // CFDF_Document * CPDFSDK_FormFillEnvironment::OpenFDF(string strPath,bool
212 // bUserConv);
213 
openFDF(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)214 CJS_Return app::openFDF(CJS_Runtime* pRuntime,
215                         const std::vector<v8::Local<v8::Value>>& params) {
216   return CJS_Return(true);
217 }
218 
alert(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)219 CJS_Return app::alert(CJS_Runtime* pRuntime,
220                       const std::vector<v8::Local<v8::Value>>& params) {
221   std::vector<v8::Local<v8::Value>> newParams = ExpandKeywordParams(
222       pRuntime, params, 4, L"cMsg", L"nIcon", L"nType", L"cTitle");
223 
224   if (!IsTypeKnown(newParams[0]))
225     return CJS_Return(JSGetStringFromID(JSMessage::kParamError));
226 
227   CPDFSDK_FormFillEnvironment* pFormFillEnv = pRuntime->GetFormFillEnv();
228   if (!pFormFillEnv)
229     return CJS_Return(pRuntime->NewNumber(0));
230 
231   WideString swMsg;
232   if (newParams[0]->IsArray()) {
233     v8::Local<v8::Array> carray = pRuntime->ToArray(newParams[0]);
234     swMsg = L"[";
235     for (size_t i = 0; i < pRuntime->GetArrayLength(carray); ++i) {
236       if (i)
237         swMsg += L", ";
238 
239       swMsg += pRuntime->ToWideString(pRuntime->GetArrayElement(carray, i));
240     }
241     swMsg += L"]";
242   } else {
243     swMsg = pRuntime->ToWideString(newParams[0]);
244   }
245 
246   int iIcon = 0;
247   if (IsTypeKnown(newParams[1]))
248     iIcon = pRuntime->ToInt32(newParams[1]);
249 
250   int iType = 0;
251   if (IsTypeKnown(newParams[2]))
252     iType = pRuntime->ToInt32(newParams[2]);
253 
254   WideString swTitle;
255   if (IsTypeKnown(newParams[3]))
256     swTitle = pRuntime->ToWideString(newParams[3]);
257   else
258     swTitle = JSGetStringFromID(JSMessage::kAlert);
259 
260   pRuntime->BeginBlock();
261   pFormFillEnv->KillFocusAnnot(0);
262 
263   v8::Local<v8::Value> ret = pRuntime->NewNumber(
264       pFormFillEnv->JS_appAlert(swMsg.c_str(), swTitle.c_str(), iType, iIcon));
265   pRuntime->EndBlock();
266 
267   return CJS_Return(ret);
268 }
269 
beep(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)270 CJS_Return app::beep(CJS_Runtime* pRuntime,
271                      const std::vector<v8::Local<v8::Value>>& params) {
272   if (params.size() == 1) {
273     pRuntime->GetFormFillEnv()->JS_appBeep(pRuntime->ToInt32(params[0]));
274     return CJS_Return(true);
275   }
276   return CJS_Return(JSGetStringFromID(JSMessage::kParamError));
277 }
278 
findComponent(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)279 CJS_Return app::findComponent(CJS_Runtime* pRuntime,
280                               const std::vector<v8::Local<v8::Value>>& params) {
281   return CJS_Return(true);
282 }
283 
popUpMenuEx(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)284 CJS_Return app::popUpMenuEx(CJS_Runtime* pRuntime,
285                             const std::vector<v8::Local<v8::Value>>& params) {
286   return CJS_Return(false);
287 }
288 
get_fs(CJS_Runtime * pRuntime)289 CJS_Return app::get_fs(CJS_Runtime* pRuntime) {
290   return CJS_Return(false);
291 }
292 
set_fs(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)293 CJS_Return app::set_fs(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
294   return CJS_Return(false);
295 }
296 
setInterval(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)297 CJS_Return app::setInterval(CJS_Runtime* pRuntime,
298                             const std::vector<v8::Local<v8::Value>>& params) {
299   if (params.size() > 2 || params.size() == 0)
300     return CJS_Return(JSGetStringFromID(JSMessage::kParamError));
301 
302   WideString script =
303       params.size() > 0 ? pRuntime->ToWideString(params[0]) : L"";
304   if (script.IsEmpty())
305     return CJS_Return(JSGetStringFromID(JSMessage::kInvalidInputError));
306 
307   uint32_t dwInterval = params.size() > 1 ? pRuntime->ToInt32(params[1]) : 1000;
308   GlobalTimer* timerRef = new GlobalTimer(this, pRuntime->GetFormFillEnv(),
309                                           pRuntime, 0, script, dwInterval, 0);
310   m_Timers.insert(std::unique_ptr<GlobalTimer>(timerRef));
311 
312   v8::Local<v8::Object> pRetObj =
313       pRuntime->NewFxDynamicObj(CJS_TimerObj::GetObjDefnID());
314   if (pRetObj.IsEmpty())
315     return CJS_Return(false);
316 
317   CJS_TimerObj* pJS_TimerObj =
318       static_cast<CJS_TimerObj*>(pRuntime->GetObjectPrivate(pRetObj));
319   TimerObj* pTimerObj = static_cast<TimerObj*>(pJS_TimerObj->GetEmbedObject());
320   pTimerObj->SetTimer(timerRef);
321 
322   return CJS_Return(pRetObj);
323 }
324 
setTimeOut(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)325 CJS_Return app::setTimeOut(CJS_Runtime* pRuntime,
326                            const std::vector<v8::Local<v8::Value>>& params) {
327   if (params.size() > 2 || params.size() == 0)
328     return CJS_Return(JSGetStringFromID(JSMessage::kParamError));
329 
330   WideString script = pRuntime->ToWideString(params[0]);
331   if (script.IsEmpty())
332     return CJS_Return(JSGetStringFromID(JSMessage::kInvalidInputError));
333 
334   uint32_t dwTimeOut = params.size() > 1 ? pRuntime->ToInt32(params[1]) : 1000;
335   GlobalTimer* timerRef =
336       new GlobalTimer(this, pRuntime->GetFormFillEnv(), pRuntime, 1, script,
337                       dwTimeOut, dwTimeOut);
338   m_Timers.insert(std::unique_ptr<GlobalTimer>(timerRef));
339 
340   v8::Local<v8::Object> pRetObj =
341       pRuntime->NewFxDynamicObj(CJS_TimerObj::GetObjDefnID());
342   if (pRetObj.IsEmpty())
343     return CJS_Return(false);
344 
345   CJS_TimerObj* pJS_TimerObj =
346       static_cast<CJS_TimerObj*>(pRuntime->GetObjectPrivate(pRetObj));
347   TimerObj* pTimerObj = static_cast<TimerObj*>(pJS_TimerObj->GetEmbedObject());
348   pTimerObj->SetTimer(timerRef);
349 
350   return CJS_Return(pRetObj);
351 }
352 
clearTimeOut(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)353 CJS_Return app::clearTimeOut(CJS_Runtime* pRuntime,
354                              const std::vector<v8::Local<v8::Value>>& params) {
355   if (params.size() != 1)
356     return CJS_Return(JSGetStringFromID(JSMessage::kParamError));
357 
358   app::ClearTimerCommon(pRuntime, params[0]);
359   return CJS_Return(true);
360 }
361 
clearInterval(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)362 CJS_Return app::clearInterval(CJS_Runtime* pRuntime,
363                               const std::vector<v8::Local<v8::Value>>& params) {
364   if (params.size() != 1)
365     return CJS_Return(JSGetStringFromID(JSMessage::kParamError));
366 
367   app::ClearTimerCommon(pRuntime, params[0]);
368   return CJS_Return(true);
369 }
370 
ClearTimerCommon(CJS_Runtime * pRuntime,v8::Local<v8::Value> param)371 void app::ClearTimerCommon(CJS_Runtime* pRuntime, v8::Local<v8::Value> param) {
372   if (!param->IsObject())
373     return;
374 
375   v8::Local<v8::Object> pObj = pRuntime->ToObject(param);
376   if (CFXJS_Engine::GetObjDefnID(pObj) != CJS_TimerObj::GetObjDefnID())
377     return;
378 
379   CJS_Object* pJSObj =
380       static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(pObj));
381   if (!pJSObj)
382     return;
383 
384   TimerObj* pTimerObj = static_cast<TimerObj*>(pJSObj->GetEmbedObject());
385   if (!pTimerObj)
386     return;
387 
388   GlobalTimer::Cancel(pTimerObj->GetTimerID());
389 }
390 
execMenuItem(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)391 CJS_Return app::execMenuItem(CJS_Runtime* pRuntime,
392                              const std::vector<v8::Local<v8::Value>>& params) {
393   return CJS_Return(false);
394 }
395 
TimerProc(GlobalTimer * pTimer)396 void app::TimerProc(GlobalTimer* pTimer) {
397   CJS_Runtime* pRuntime = pTimer->GetRuntime();
398   if (pRuntime && (!pTimer->IsOneShot() || pTimer->GetTimeOut() > 0))
399     RunJsScript(pRuntime, pTimer->GetJScript());
400 }
401 
CancelProc(GlobalTimer * pTimer)402 void app::CancelProc(GlobalTimer* pTimer) {
403   m_Timers.erase(pdfium::FakeUniquePtr<GlobalTimer>(pTimer));
404 }
405 
RunJsScript(CJS_Runtime * pRuntime,const WideString & wsScript)406 void app::RunJsScript(CJS_Runtime* pRuntime, const WideString& wsScript) {
407   if (!pRuntime->IsBlocking()) {
408     IJS_EventContext* pContext = pRuntime->NewEventContext();
409     pContext->OnExternal_Exec();
410     WideString wtInfo;
411     pContext->RunScript(wsScript, &wtInfo);
412     pRuntime->ReleaseEventContext(pContext);
413   }
414 }
415 
goBack(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)416 CJS_Return app::goBack(CJS_Runtime* pRuntime,
417                        const std::vector<v8::Local<v8::Value>>& params) {
418   // Not supported.
419   return CJS_Return(true);
420 }
421 
goForward(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)422 CJS_Return app::goForward(CJS_Runtime* pRuntime,
423                           const std::vector<v8::Local<v8::Value>>& params) {
424   // Not supported.
425   return CJS_Return(true);
426 }
427 
mailMsg(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)428 CJS_Return app::mailMsg(CJS_Runtime* pRuntime,
429                         const std::vector<v8::Local<v8::Value>>& params) {
430   std::vector<v8::Local<v8::Value>> newParams =
431       ExpandKeywordParams(pRuntime, params, 6, L"bUI", L"cTo", L"cCc", L"cBcc",
432                           L"cSubject", L"cMsg");
433 
434   if (!IsTypeKnown(newParams[0]))
435     return CJS_Return(JSGetStringFromID(JSMessage::kParamError));
436 
437   bool bUI = pRuntime->ToBoolean(newParams[0]);
438   WideString cTo;
439   if (IsTypeKnown(newParams[1])) {
440     cTo = pRuntime->ToWideString(newParams[1]);
441   } else {
442     // cTo parameter required when UI not invoked.
443     if (!bUI)
444       return CJS_Return(JSGetStringFromID(JSMessage::kParamError));
445   }
446 
447   WideString cCc;
448   if (IsTypeKnown(newParams[2]))
449     cCc = pRuntime->ToWideString(newParams[2]);
450 
451   WideString cBcc;
452   if (IsTypeKnown(newParams[3]))
453     cBcc = pRuntime->ToWideString(newParams[3]);
454 
455   WideString cSubject;
456   if (IsTypeKnown(newParams[4]))
457     cSubject = pRuntime->ToWideString(newParams[4]);
458 
459   WideString cMsg;
460   if (IsTypeKnown(newParams[5]))
461     cMsg = pRuntime->ToWideString(newParams[5]);
462 
463   pRuntime->BeginBlock();
464   pRuntime->GetFormFillEnv()->JS_docmailForm(nullptr, 0, bUI, cTo.c_str(),
465                                              cSubject.c_str(), cCc.c_str(),
466                                              cBcc.c_str(), cMsg.c_str());
467   pRuntime->EndBlock();
468   return CJS_Return(true);
469 }
470 
launchURL(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)471 CJS_Return app::launchURL(CJS_Runtime* pRuntime,
472                           const std::vector<v8::Local<v8::Value>>& params) {
473   // Unsafe, not supported.
474   return CJS_Return(true);
475 }
476 
get_runtime_highlight(CJS_Runtime * pRuntime)477 CJS_Return app::get_runtime_highlight(CJS_Runtime* pRuntime) {
478   return CJS_Return(pRuntime->NewBoolean(m_bRuntimeHighLight));
479 }
480 
set_runtime_highlight(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)481 CJS_Return app::set_runtime_highlight(CJS_Runtime* pRuntime,
482                                       v8::Local<v8::Value> vp) {
483   m_bRuntimeHighLight = pRuntime->ToBoolean(vp);
484   return CJS_Return(true);
485 }
486 
get_fullscreen(CJS_Runtime * pRuntime)487 CJS_Return app::get_fullscreen(CJS_Runtime* pRuntime) {
488   return CJS_Return(false);
489 }
490 
set_fullscreen(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)491 CJS_Return app::set_fullscreen(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
492   return CJS_Return(false);
493 }
494 
popUpMenu(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)495 CJS_Return app::popUpMenu(CJS_Runtime* pRuntime,
496                           const std::vector<v8::Local<v8::Value>>& params) {
497   return CJS_Return(false);
498 }
499 
browseForDoc(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)500 CJS_Return app::browseForDoc(CJS_Runtime* pRuntime,
501                              const std::vector<v8::Local<v8::Value>>& params) {
502   // Unsafe, not supported.
503   return CJS_Return(true);
504 }
505 
SysPathToPDFPath(const WideString & sOldPath)506 WideString app::SysPathToPDFPath(const WideString& sOldPath) {
507   WideString sRet = L"/";
508   for (const wchar_t& c : sOldPath) {
509     if (c != L':')
510       sRet += (c == L'\\') ? L'/' : c;
511   }
512   return sRet;
513 }
514 
newDoc(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)515 CJS_Return app::newDoc(CJS_Runtime* pRuntime,
516                        const std::vector<v8::Local<v8::Value>>& params) {
517   return CJS_Return(false);
518 }
519 
openDoc(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)520 CJS_Return app::openDoc(CJS_Runtime* pRuntime,
521                         const std::vector<v8::Local<v8::Value>>& params) {
522   return CJS_Return(false);
523 }
524 
response(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)525 CJS_Return app::response(CJS_Runtime* pRuntime,
526                          const std::vector<v8::Local<v8::Value>>& params) {
527   std::vector<v8::Local<v8::Value>> newParams =
528       ExpandKeywordParams(pRuntime, params, 5, L"cQuestion", L"cTitle",
529                           L"cDefault", L"bPassword", L"cLabel");
530 
531   if (!IsTypeKnown(newParams[0]))
532     return CJS_Return(JSGetStringFromID(JSMessage::kParamError));
533 
534   WideString swQuestion = pRuntime->ToWideString(newParams[0]);
535   WideString swTitle = L"PDF";
536   if (IsTypeKnown(newParams[1]))
537     swTitle = pRuntime->ToWideString(newParams[1]);
538 
539   WideString swDefault;
540   if (IsTypeKnown(newParams[2]))
541     swDefault = pRuntime->ToWideString(newParams[2]);
542 
543   bool bPassword = false;
544   if (IsTypeKnown(newParams[3]))
545     bPassword = pRuntime->ToBoolean(newParams[3]);
546 
547   WideString swLabel;
548   if (IsTypeKnown(newParams[4]))
549     swLabel = pRuntime->ToWideString(newParams[4]);
550 
551   const int MAX_INPUT_BYTES = 2048;
552   std::vector<uint8_t> pBuff(MAX_INPUT_BYTES + 2);
553   int nLengthBytes = pRuntime->GetFormFillEnv()->JS_appResponse(
554       swQuestion.c_str(), swTitle.c_str(), swDefault.c_str(), swLabel.c_str(),
555       bPassword, pBuff.data(), MAX_INPUT_BYTES);
556 
557   if (nLengthBytes < 0 || nLengthBytes > MAX_INPUT_BYTES)
558     return CJS_Return(JSGetStringFromID(JSMessage::kParamTooLongError));
559 
560   return CJS_Return(pRuntime->NewString(
561       WideString::FromUTF16LE(reinterpret_cast<uint16_t*>(pBuff.data()),
562                               nLengthBytes / sizeof(uint16_t))
563           .c_str()));
564 }
565 
get_media(CJS_Runtime * pRuntime)566 CJS_Return app::get_media(CJS_Runtime* pRuntime) {
567   return CJS_Return(false);
568 }
569 
set_media(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)570 CJS_Return app::set_media(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
571   return CJS_Return(false);
572 }
573 
execDialog(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)574 CJS_Return app::execDialog(CJS_Runtime* pRuntime,
575                            const std::vector<v8::Local<v8::Value>>& params) {
576   return CJS_Return(true);
577 }
578