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