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