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 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 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 87 app::app(CJS_Object* pJSObject) 88 : CJS_EmbedObj(pJSObject), m_bCalculate(true), m_bRuntimeHighLight(false) {} 89 90 app::~app() {} 91 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 108 CJS_Return app::set_active_docs(CJS_Runtime* pRuntime, 109 v8::Local<v8::Value> vp) { 110 return CJS_Return(false); 111 } 112 113 CJS_Return app::get_calculate(CJS_Runtime* pRuntime) { 114 return CJS_Return(pRuntime->NewBoolean(m_bCalculate)); 115 } 116 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 123 CJS_Return app::get_forms_version(CJS_Runtime* pRuntime) { 124 return CJS_Return(pRuntime->NewNumber(JS_NUM_FORMSVERSION)); 125 } 126 127 CJS_Return app::set_forms_version(CJS_Runtime* pRuntime, 128 v8::Local<v8::Value> vp) { 129 return CJS_Return(false); 130 } 131 132 CJS_Return app::get_viewer_type(CJS_Runtime* pRuntime) { 133 return CJS_Return(pRuntime->NewString(JS_STR_VIEWERTYPE)); 134 } 135 136 CJS_Return app::set_viewer_type(CJS_Runtime* pRuntime, 137 v8::Local<v8::Value> vp) { 138 return CJS_Return(false); 139 } 140 141 CJS_Return app::get_viewer_variation(CJS_Runtime* pRuntime) { 142 return CJS_Return(pRuntime->NewString(JS_STR_VIEWERVARIATION)); 143 } 144 145 CJS_Return app::set_viewer_variation(CJS_Runtime* pRuntime, 146 v8::Local<v8::Value> vp) { 147 return CJS_Return(false); 148 } 149 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 159 CJS_Return app::set_viewer_version(CJS_Runtime* pRuntime, 160 v8::Local<v8::Value> vp) { 161 return CJS_Return(false); 162 } 163 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 177 CJS_Return app::set_platform(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) { 178 return CJS_Return(false); 179 } 180 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 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(); 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 214 CJS_Return app::openFDF(CJS_Runtime* pRuntime, 215 const std::vector<v8::Local<v8::Value>>& params) { 216 return CJS_Return(true); 217 } 218 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 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 279 CJS_Return app::findComponent(CJS_Runtime* pRuntime, 280 const std::vector<v8::Local<v8::Value>>& params) { 281 return CJS_Return(true); 282 } 283 284 CJS_Return app::popUpMenuEx(CJS_Runtime* pRuntime, 285 const std::vector<v8::Local<v8::Value>>& params) { 286 return CJS_Return(false); 287 } 288 289 CJS_Return app::get_fs(CJS_Runtime* pRuntime) { 290 return CJS_Return(false); 291 } 292 293 CJS_Return app::set_fs(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) { 294 return CJS_Return(false); 295 } 296 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 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 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 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 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 391 CJS_Return app::execMenuItem(CJS_Runtime* pRuntime, 392 const std::vector<v8::Local<v8::Value>>& params) { 393 return CJS_Return(false); 394 } 395 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 402 void app::CancelProc(GlobalTimer* pTimer) { 403 m_Timers.erase(pdfium::FakeUniquePtr<GlobalTimer>(pTimer)); 404 } 405 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 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 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 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 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 477 CJS_Return app::get_runtime_highlight(CJS_Runtime* pRuntime) { 478 return CJS_Return(pRuntime->NewBoolean(m_bRuntimeHighLight)); 479 } 480 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 487 CJS_Return app::get_fullscreen(CJS_Runtime* pRuntime) { 488 return CJS_Return(false); 489 } 490 491 CJS_Return app::set_fullscreen(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) { 492 return CJS_Return(false); 493 } 494 495 CJS_Return app::popUpMenu(CJS_Runtime* pRuntime, 496 const std::vector<v8::Local<v8::Value>>& params) { 497 return CJS_Return(false); 498 } 499 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 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 515 CJS_Return app::newDoc(CJS_Runtime* pRuntime, 516 const std::vector<v8::Local<v8::Value>>& params) { 517 return CJS_Return(false); 518 } 519 520 CJS_Return app::openDoc(CJS_Runtime* pRuntime, 521 const std::vector<v8::Local<v8::Value>>& params) { 522 return CJS_Return(false); 523 } 524 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 566 CJS_Return app::get_media(CJS_Runtime* pRuntime) { 567 return CJS_Return(false); 568 } 569 570 CJS_Return app::set_media(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) { 571 return CJS_Return(false); 572 } 573 574 CJS_Return app::execDialog(CJS_Runtime* pRuntime, 575 const std::vector<v8::Local<v8::Value>>& params) { 576 return CJS_Return(true); 577 } 578