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