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
20static 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
33BEGIN_JS_STATIC_CONST(CJS_TimerObj)
34END_JS_STATIC_CONST()
35
36BEGIN_JS_STATIC_PROP(CJS_TimerObj)
37END_JS_STATIC_PROP()
38
39BEGIN_JS_STATIC_METHOD(CJS_TimerObj)
40END_JS_STATIC_METHOD()
41
42IMPLEMENT_JS_CLASS(CJS_TimerObj, TimerObj)
43
44TimerObj::TimerObj(CJS_Object* pJSObject)
45: CJS_EmbedObj(pJSObject),
46m_pTimer(NULL)
47{
48
49}
50
51TimerObj::~TimerObj()
52{
53}
54
55void TimerObj::SetTimer(CJS_Timer* pTimer)
56{
57	m_pTimer = pTimer;
58}
59
60CJS_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
77BEGIN_JS_STATIC_CONST(CJS_App)
78END_JS_STATIC_CONST()
79
80BEGIN_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)
93END_JS_STATIC_PROP()
94
95BEGIN_JS_STATIC_METHOD(CJS_App)
96	JS_STATIC_METHOD_ENTRY(alert, 6)
97	JS_STATIC_METHOD_ENTRY(beep, 1)
98	JS_STATIC_METHOD_ENTRY(browseForDoc, 0)
99	JS_STATIC_METHOD_ENTRY(clearInterval, 1)
100	JS_STATIC_METHOD_ENTRY(clearTimeOut, 1)
101	JS_STATIC_METHOD_ENTRY(execDialog, 3)
102	JS_STATIC_METHOD_ENTRY(execMenuItem,  1)
103	JS_STATIC_METHOD_ENTRY(findComponent, 1)
104	JS_STATIC_METHOD_ENTRY(goBack, 0)
105	JS_STATIC_METHOD_ENTRY(goForward, 0)
106	JS_STATIC_METHOD_ENTRY(launchURL, 0)
107	JS_STATIC_METHOD_ENTRY(mailMsg, 0)
108	JS_STATIC_METHOD_ENTRY(newFDF, 0)
109	JS_STATIC_METHOD_ENTRY(newDoc, 0)
110	JS_STATIC_METHOD_ENTRY(openDoc, 0)
111	JS_STATIC_METHOD_ENTRY(openFDF, 5)
112	JS_STATIC_METHOD_ENTRY(popUpMenuEx, 0)
113	JS_STATIC_METHOD_ENTRY(popUpMenu, 0)
114	JS_STATIC_METHOD_ENTRY(response, 0)
115	JS_STATIC_METHOD_ENTRY(setInterval, 2)
116	JS_STATIC_METHOD_ENTRY(setTimeOut, 2)
117END_JS_STATIC_METHOD()
118
119IMPLEMENT_JS_CLASS(CJS_App,app)
120
121app::app(CJS_Object * pJSObject) : CJS_EmbedObj(pJSObject) ,
122	m_bCalculate(true),
123	m_pRuntime(NULL),
124	m_bRuntimeHighLight(false)
125//	m_pMenuHead(NULL)
126{
127}
128
129app::~app(void)
130{
131	for (int i=0,sz=m_aTimer.GetSize(); i<sz; i++)
132		delete m_aTimer[i];
133
134	m_aTimer.RemoveAll();
135}
136
137FX_BOOL app::activeDocs(OBJ_PROP_PARAMS)
138{
139	if (vp.IsGetting())
140	{
141
142		CJS_Context* pContext = (CJS_Context *)cc;
143		ASSERT(pContext != NULL);
144
145		CPDFDoc_Environment* pApp = pContext->GetReaderApp();
146		ASSERT(pApp != NULL);
147
148		CJS_Runtime* pRuntime = pContext->GetJSRuntime();
149		ASSERT(pRuntime != NULL);
150
151		CPDFSDK_Document* pCurDoc = pContext->GetReaderDocument();
152
153		CJS_Array aDocs(pRuntime->GetIsolate());
154//		int iNumDocs = pApp->CountDocuments();
155
156// 		for(int iIndex = 0; iIndex<iNumDocs; iIndex++)
157// 		{
158			CPDFSDK_Document* pDoc = pApp->GetCurrentDoc();
159			if (pDoc)
160			{
161				CJS_Document * pJSDocument = NULL;
162
163				if (pDoc == pCurDoc)
164				{
165					JSFXObject pObj = JS_GetThisObj(*pRuntime);
166
167					if (JS_GetObjDefnID(pObj) == JS_GetObjDefnID(*pRuntime, L"Document"))
168					{
169						pJSDocument = (CJS_Document*)JS_GetPrivate(pRuntime->GetIsolate(),pObj);
170					}
171				}
172				else
173				{
174					JSFXObject pObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime,L"Document"));
175					pJSDocument = (CJS_Document*)JS_GetPrivate(pRuntime->GetIsolate(),pObj);
176					ASSERT(pJSDocument != NULL);
177
178
179					//			pDocument->AttachDoc(pDoc);
180				}
181
182				aDocs.SetElement(0,CJS_Value(pRuntime->GetIsolate(),pJSDocument));
183			}
184	//		}
185
186		if (aDocs.GetLength() > 0)
187			vp << aDocs;
188		else
189			vp.SetNull();
190		return TRUE;
191	}
192	return FALSE;
193}
194
195FX_BOOL app::calculate(OBJ_PROP_PARAMS)
196{
197	if (vp.IsSetting())
198	{
199		bool bVP;
200		vp >> bVP;
201		m_bCalculate = (FX_BOOL)bVP;
202
203		CJS_Context* pContext = (CJS_Context*)cc;
204		ASSERT(pContext != NULL);
205
206		CPDFDoc_Environment* pApp = pContext->GetReaderApp();
207		ASSERT(pApp != NULL);
208
209		CJS_Runtime* pRuntime = pContext->GetJSRuntime();
210		ASSERT(pRuntime != NULL);
211
212		CJS_Array aDocs(pRuntime->GetIsolate());
213// 		int iNumDocs = pApp->CountDocuments();
214//
215// 		for (int iIndex = 0;iIndex < iNumDocs; iIndex++)
216// 		{
217			if (CPDFSDK_Document* pDoc = pApp->GetCurrentDoc())
218			{
219				CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)pDoc->GetInterForm();
220				ASSERT(pInterForm != NULL);
221				pInterForm->EnableCalculate((FX_BOOL)m_bCalculate);
222			}
223//		}
224	}
225	else
226	{
227		vp << (bool)m_bCalculate;
228	}
229
230	return TRUE;
231}
232
233FX_BOOL app::formsVersion(OBJ_PROP_PARAMS)
234{
235	if (vp.IsGetting())
236	{
237		vp << JS_NUM_FORMSVERSION;
238		return TRUE;
239	}
240
241	return FALSE;
242}
243
244FX_BOOL app::viewerType(OBJ_PROP_PARAMS)
245{
246
247
248
249
250
251
252	if (vp.IsGetting())
253	{
254// 		if (pApp->GetAppName() == PHANTOM)
255// 			vp << JS_STR_VIEWERTYPE_STANDARD;
256// 		else
257// 			vp << JS_STR_VIEWERTYPE_READER;
258		vp << L"unknown";
259
260		//vp << pApp->GetAppTitle();
261		return TRUE;
262	}
263
264	return FALSE;
265}
266
267FX_BOOL app::viewerVariation(OBJ_PROP_PARAMS)
268{
269	if (vp.IsGetting())
270	{
271		vp << JS_STR_VIEWERVARIATION;
272		return TRUE;
273	}
274
275	return FALSE;
276}
277
278FX_BOOL app::viewerVersion(OBJ_PROP_PARAMS)
279{
280	if (vp.IsGetting())
281	{
282		vp << JS_STR_VIEWERVERSION;
283		return TRUE;
284	}
285
286	return FALSE;
287}
288
289FX_BOOL app::platform(OBJ_PROP_PARAMS)
290{
291	if (vp.IsGetting())
292	{
293		vp << JS_STR_PLATFORM;
294		return TRUE;
295	}
296
297	return FALSE;
298}
299
300FX_BOOL app::language(OBJ_PROP_PARAMS)
301{
302	if (vp.IsGetting())
303	{
304		vp << JS_STR_LANGUANGE;
305		return TRUE;
306	}
307
308	return FALSE;
309}
310
311//creates a new fdf object that contains no data
312//comment: need reader support
313//note:
314//CFDF_Document * CPDFDoc_Environment::NewFDF();
315FX_BOOL app::newFDF(OBJ_METHOD_PARAMS)
316{
317	return TRUE;
318}
319//opens a specified pdf document and returns its document object
320//comment:need reader support
321//note: as defined in js reference, the proto of this function's fourth parmeters, how old an fdf document while do not show it.
322//CFDF_Document * CPDFDoc_Environment::OpenFDF(string strPath,bool bUserConv);
323
324FX_BOOL app::openFDF(OBJ_METHOD_PARAMS)
325{
326	return TRUE;
327}
328
329FX_BOOL app::alert(OBJ_METHOD_PARAMS)
330{
331	int iSize = params.size();
332	if (iSize < 1)
333		return FALSE;
334
335	CFX_WideString swMsg = L"";
336	CFX_WideString swTitle = L"";
337	int iIcon = 0;
338	int iType = 0;
339
340	v8::Isolate* isolate = GetIsolate(cc);
341
342	if (iSize == 1)
343	{
344		if (params[0].GetType() == VT_object)
345		{
346			JSObject pObj = params[0];
347			{
348				v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate, pObj, L"cMsg");
349				swMsg = CJS_Value(isolate,pValue,VT_unknown).operator CFX_WideString();
350
351				pValue = JS_GetObjectElement(isolate,pObj,L"cTitle");
352				swTitle = CJS_Value(isolate, pValue,VT_unknown).operator CFX_WideString();
353
354				pValue = JS_GetObjectElement(isolate,pObj,L"nIcon");
355				iIcon = (int)CJS_Value(isolate,pValue,VT_unknown);
356
357				pValue = JS_GetObjectElement(isolate,pObj,L"nType");
358				iType = (int)CJS_Value(isolate,pValue,VT_unknown);
359			}
360
361			if (swMsg == L"")
362			{
363				CJS_Array carray(isolate);
364				if (params[0].ConvertToArray(carray))
365				{
366					int iLenth = carray.GetLength();
367					CJS_Value* pValue = new CJS_Value(isolate);
368//					if (iLenth == 1)
369//						pValue = new CJS_Value(isolate);
370// 					else if (iLenth > 1)
371// 						pValue = new CJS_Value[iLenth];
372
373					for(int i = 0; i < iLenth; i++)
374					{
375						carray.GetElement(i, *pValue);
376						swMsg += (*pValue).operator CFX_WideString();
377						if (i < iLenth - 1)
378							swMsg += L",  ";
379					}
380
381					if(pValue) delete pValue;
382// 					if ((iLenth > 1) && pValue)
383// 					{
384// 						delete[]pValue;
385// 						pValue = NULL;
386// 					}
387// 					else if ((iLenth == 1) && pValue)
388// 					{
389// 						delete pValue;
390// 						pValue = NULL;
391// 					}
392				}
393			}
394
395			if (swTitle == L"")
396				swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
397		}
398		else if (params[0].GetType() == VT_boolean)
399		{
400			FX_BOOL bGet = (FX_BOOL)params[0];
401			if (bGet)
402				swMsg = L"true";
403			else
404				swMsg = L"false";
405
406			swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
407		}
408		else
409		{
410			swMsg = params[0];
411			swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
412		}
413	}
414	else
415	{
416		if (params[0].GetType() == VT_boolean)
417		{
418			FX_BOOL bGet = (FX_BOOL)params[0];
419			if (bGet)
420				swMsg = L"true";
421			else
422				swMsg = L"false";
423		}
424		else
425		{
426			swMsg = params[0];
427		}
428		swTitle = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSALERT);
429
430		for(int i = 1;i<iSize;i++)
431		{
432			if (i == 1)
433				iIcon = int(params[i]);
434			if (i == 2)
435				iType = int(params[i]);
436			if (i == 3)
437				swTitle = params[i];
438		}
439	}
440
441
442	CJS_Context* pContext = (CJS_Context*)cc;
443	ASSERT(pContext != NULL);
444	CJS_Runtime* pRuntime = pContext->GetJSRuntime();
445	ASSERT(pRuntime != NULL);
446	pRuntime->BeginBlock();
447	vRet = MsgBox(pRuntime->GetReaderApp(), JSGetPageView(cc),swMsg,swTitle,iType,iIcon);
448	pRuntime->EndBlock();
449
450	return TRUE;
451}
452
453
454FX_BOOL app::beep(OBJ_METHOD_PARAMS)
455{
456	if (params.size() == 1)
457	{
458		CJS_Context* pContext = (CJS_Context*)cc;
459		CJS_Runtime* pRuntime = pContext->GetJSRuntime();
460		CPDFDoc_Environment * pEnv = pRuntime->GetReaderApp();
461		pEnv->JS_appBeep((int)params[0]);
462
463		return TRUE;
464	}
465	else
466	{
467		sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
468		return FALSE;
469	}
470}
471
472FX_BOOL app::findComponent(OBJ_METHOD_PARAMS)
473{
474	return TRUE;
475}
476
477FX_BOOL app::popUpMenuEx(OBJ_METHOD_PARAMS)
478{
479	return FALSE;
480}
481
482FX_BOOL app::fs(OBJ_PROP_PARAMS)
483{
484#ifdef FOXIT_CHROME_BUILD
485	return FALSE;
486#else
487	CJS_Context* pContext = (CJS_Context*)cc;
488	ASSERT(pContext != NULL);
489	CJS_Runtime* pRuntime = pContext->GetJSRuntime();
490	ASSERT(pRuntime != NULL);
491
492	if (vp.IsGetting())
493	{
494		return TRUE;
495	}
496	else
497	{
498		return TRUE;
499	}
500#endif
501}
502
503FX_BOOL app::setInterval(OBJ_METHOD_PARAMS)
504{
505	if (params.size() > 2 || params.size() == 0)
506	{
507		sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
508		return FALSE;
509	}
510
511	CJS_Context* pContext = (CJS_Context*)cc;
512	ASSERT(pContext != NULL);
513	CJS_Runtime* pRuntime = pContext->GetJSRuntime();
514	ASSERT(pRuntime != NULL);
515
516	CFX_WideString script = params.size() > 0 ?  (FX_LPCWSTR)(params[0].operator CFX_WideString()) : (FX_LPCWSTR)L"";
517	if (script.IsEmpty())
518	{
519		sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSAFNUMBER_KEYSTROKE);
520		return TRUE;
521	}
522
523	FX_DWORD dwInterval = params.size() > 1 ? (int)params[1] : 1000;
524
525	CPDFDoc_Environment* pApp = pRuntime->GetReaderApp();
526	ASSERT(pApp);
527	CJS_Timer* pTimer = new CJS_Timer(this, pApp);
528	m_aTimer.Add(pTimer);
529
530	pTimer->SetType(0);
531	pTimer->SetRuntime(pRuntime);
532	pTimer->SetJScript(script);
533	pTimer->SetTimeOut(0);
534//	pTimer->SetStartTime(GetTickCount());
535	pTimer->SetJSTimer(dwInterval);
536
537	JSFXObject pRetObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"TimerObj"));
538
539	CJS_TimerObj* pJS_TimerObj = (CJS_TimerObj*)JS_GetPrivate(pRuntime->GetIsolate(),pRetObj);
540	ASSERT(pJS_TimerObj != NULL);
541
542	TimerObj* pTimerObj = (TimerObj*)pJS_TimerObj->GetEmbedObject();
543	ASSERT(pTimerObj != NULL);
544
545	pTimerObj->SetTimer(pTimer);
546
547	vRet = pRetObj;
548
549	return TRUE;
550}
551
552FX_BOOL app::setTimeOut(OBJ_METHOD_PARAMS)
553{
554	if (params.size() > 2 || params.size() == 0)
555	{
556		sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
557		return FALSE;
558	}
559
560	CJS_Context* pContext = (CJS_Context*)cc;
561	ASSERT(pContext != NULL);
562	CJS_Runtime* pRuntime = pContext->GetJSRuntime();
563	ASSERT(pRuntime != NULL);
564
565	CFX_WideString script = params.size() > 0 ?  (FX_LPCWSTR)(params[0].operator CFX_WideString()) : (FX_LPCWSTR)L"";
566	if (script.IsEmpty())
567	{
568		sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSAFNUMBER_KEYSTROKE);
569		return TRUE;
570	}
571
572	FX_DWORD dwTimeOut = params.size() > 1 ? (int)params[1] : 1000;
573
574	CPDFDoc_Environment* pApp = pRuntime->GetReaderApp();
575	ASSERT(pApp);
576	CJS_Timer* pTimer = new CJS_Timer(this, pApp);
577	m_aTimer.Add(pTimer);
578
579	pTimer->SetType(1);
580	pTimer->SetRuntime(pRuntime);
581	pTimer->SetJScript(script);
582	pTimer->SetTimeOut(dwTimeOut);
583//	pTimer->SetStartTime(GetTickCount());
584//	pTimer->SetJSTimer(1000);
585	pTimer->SetJSTimer(dwTimeOut);
586
587	JSFXObject pRetObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"TimerObj"));
588//	ASSERT(pRetObj != NULL);
589
590	CJS_TimerObj* pJS_TimerObj = (CJS_TimerObj*)JS_GetPrivate(pRuntime->GetIsolate(),pRetObj);
591	ASSERT(pJS_TimerObj != NULL);
592
593	TimerObj* pTimerObj = (TimerObj*)pJS_TimerObj->GetEmbedObject();
594	ASSERT(pTimerObj != NULL);
595
596	pTimerObj->SetTimer(pTimer);
597
598	vRet = pRetObj;
599
600	return TRUE;
601}
602
603FX_BOOL app::clearTimeOut(OBJ_METHOD_PARAMS)
604{
605	CJS_Context* pContext = (CJS_Context*)cc;
606	ASSERT(pContext != NULL);
607	CJS_Runtime* pRuntime = pContext->GetJSRuntime();
608	ASSERT(pRuntime != NULL);
609
610	if (params.size() != 1)
611	{
612		sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
613		return FALSE;
614	}
615
616	if (params[0].GetType() == VT_fxobject)
617	{
618		JSFXObject pObj = (JSFXObject)params[0];
619		{
620			if (JS_GetObjDefnID(pObj) == JS_GetObjDefnID(*pRuntime, L"TimerObj"))
621			{
622				if (CJS_Object* pJSObj = (CJS_Object*)params[0])
623				{
624					if (TimerObj* pTimerObj = (TimerObj*)pJSObj->GetEmbedObject())
625					{
626						if (CJS_Timer* pTimer = pTimerObj->GetTimer())
627						{
628							pTimer->KillJSTimer();
629
630							for (int i=0,sz=m_aTimer.GetSize(); i<sz; i++)
631							{
632								if (m_aTimer[i] == pTimer)
633								{
634									m_aTimer.RemoveAt(i);
635									break;
636								}
637							}
638
639							delete pTimer;
640							pTimerObj->SetTimer(NULL);
641						}
642					}
643				}
644			}
645		}
646	}
647
648	return TRUE;
649}
650
651FX_BOOL app::clearInterval(OBJ_METHOD_PARAMS)
652{
653	CJS_Context* pContext = (CJS_Context*)cc;
654	ASSERT(pContext != NULL);
655	CJS_Runtime* pRuntime = pContext->GetJSRuntime();
656	ASSERT(pRuntime != NULL);
657
658	if (params.size() != 1)
659	{
660		sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
661		return FALSE;
662	}
663
664	if (params[0].GetType() == VT_fxobject)
665	{
666		JSFXObject pObj = (JSFXObject)params[0];
667		{
668			if (JS_GetObjDefnID(pObj) == JS_GetObjDefnID(*pRuntime, L"TimerObj"))
669			{
670				if (CJS_Object* pJSObj = (CJS_Object*)params[0])
671				{
672					if (TimerObj* pTimerObj = (TimerObj*)pJSObj->GetEmbedObject())
673					{
674						if (CJS_Timer* pTimer = pTimerObj->GetTimer())
675						{
676							pTimer->KillJSTimer();
677
678							for (int i=0,sz=m_aTimer.GetSize(); i<sz; i++)
679							{
680								if (m_aTimer[i] == pTimer)
681								{
682									m_aTimer.RemoveAt(i);
683									break;
684								}
685							}
686
687							delete pTimer;
688							pTimerObj->SetTimer(NULL);
689						}
690					}
691				}
692			}
693		}
694	}
695
696	return TRUE;
697}
698
699FX_BOOL app::execMenuItem(OBJ_METHOD_PARAMS)
700{
701	return FALSE;
702}
703
704void app::TimerProc(CJS_Timer* pTimer)
705{
706	ASSERT(pTimer != NULL);
707
708	switch (pTimer->GetType())
709	{
710	case 0: //interval
711		RunJsScript(pTimer->GetRuntime(), pTimer->GetJScript());
712		break;
713	case 1:
714		if (pTimer->GetTimeOut() > 0)
715		{
716			RunJsScript(pTimer->GetRuntime(), pTimer->GetJScript());
717			pTimer->KillJSTimer();
718		}
719		break;
720	}
721
722}
723
724void app::RunJsScript(CJS_Runtime* pRuntime,const CFX_WideString& wsScript)
725{
726	ASSERT(pRuntime != NULL);
727
728	if (!pRuntime->IsBlocking())
729	{
730		IFXJS_Context* pContext = pRuntime->NewContext();
731		ASSERT(pContext != NULL);
732		pContext->OnExternal_Exec();
733		CFX_WideString wtInfo;
734		pContext->RunScript(wsScript,wtInfo);
735		pRuntime->ReleaseContext(pContext);
736	}
737}
738
739FX_BOOL app::goBack(OBJ_METHOD_PARAMS)
740{
741
742
743
744
745
746
747	return TRUE;
748}
749
750FX_BOOL app::goForward(OBJ_METHOD_PARAMS)
751{
752
753
754
755
756
757
758	return TRUE;
759}
760
761FX_BOOL app::mailMsg(OBJ_METHOD_PARAMS)
762{
763	CJS_Context* pContext = (CJS_Context*)cc;
764	ASSERT(pContext != NULL);
765
766	v8::Isolate* isolate = GetIsolate(cc);
767
768	FX_BOOL bUI = TRUE;
769	CFX_WideString cTo = L"";
770	CFX_WideString cCc = L"";
771	CFX_WideString cBcc = L"";
772	CFX_WideString cSubject = L"";
773	CFX_WideString cMsg = L"";
774	if(params.size() < 2)
775		return FALSE;
776
777	bUI = params.size()>=1?(int)params[0]:TRUE;
778	cTo = params.size()>=2?(const wchar_t*)(FX_LPCWSTR)params[1].operator CFX_WideString():L"";
779	cCc = params.size()>=3?(const wchar_t*)(FX_LPCWSTR)params[2].operator CFX_WideString():L"";
780	cBcc = params.size()>=4?(const wchar_t*)(FX_LPCWSTR)params[3].operator CFX_WideString():L"";
781	cSubject = params.size()>=5?(const wchar_t*)(FX_LPCWSTR)params[4].operator CFX_WideString():L"";
782	cMsg = params.size()>=6?(const wchar_t*)(FX_LPCWSTR)params[5].operator CFX_WideString():L"";
783
784
785	if (params[0].GetType() == VT_object)
786	{
787		JSObject pObj = (JSObject)params[0];
788
789		v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj, L"bUI");
790			bUI = (int)CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue));
791
792		pValue = JS_GetObjectElement(isolate, pObj, L"cTo");
793			cTo = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
794
795		pValue = JS_GetObjectElement(isolate,pObj, L"cCc");
796			cCc = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
797
798		pValue = JS_GetObjectElement(isolate,pObj, L"cBcc");
799			cBcc = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
800
801		pValue = JS_GetObjectElement(isolate,pObj, L"cSubject");
802			cSubject = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
803
804		pValue = JS_GetObjectElement(isolate,pObj, L"cMsg");
805			cMsg = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
806	}
807
808
809
810	CJS_Runtime* pRuntime = pContext->GetJSRuntime();
811	ASSERT(pRuntime != NULL);
812
813	CPDFDoc_Environment* pApp = pContext->GetReaderApp();
814	ASSERT(pApp != NULL);
815
816	pRuntime->BeginBlock();
817	pApp->JS_docmailForm(NULL, 0, bUI, (FX_LPCWSTR)cTo, (FX_LPCWSTR)cSubject, (FX_LPCWSTR)cCc, (FX_LPCWSTR)cBcc, (FX_LPCWSTR)cMsg);
818	///////////////////////////////////////////////////////////////////////////////////////////////
819	pRuntime->EndBlock();
820
821	//return bRet;
822	return FALSE;
823}
824
825FX_BOOL app::launchURL(OBJ_METHOD_PARAMS)
826{
827	if (IsSafeMode(cc)) return TRUE;
828
829	CJS_Context* pContext = (CJS_Context*)cc;
830	ASSERT(pContext != NULL);
831
832
833
834
835	CFX_WideString swURL = params[0].operator CFX_WideString();
836
837	CJS_Runtime* pRuntime = pContext->GetJSRuntime();
838	ASSERT(pRuntime != NULL);
839
840	pRuntime->BeginBlock();
841//	FX_BOOL bRet = pApp->OpenURL(swURL);
842	pRuntime->EndBlock();
843
844//	return bRet;
845	return FALSE;
846}
847
848FX_BOOL app::runtimeHighlight(OBJ_PROP_PARAMS)
849{
850	if (vp.IsSetting())
851	{
852		vp>>m_bRuntimeHighLight;
853	}
854	else
855	{
856		vp<<m_bRuntimeHighLight;
857	}
858
859	return TRUE;
860}
861
862FX_BOOL app::fullscreen(OBJ_PROP_PARAMS)
863{
864	return FALSE;
865}
866
867FX_BOOL app::popUpMenu(OBJ_METHOD_PARAMS)
868{
869	return FALSE;
870}
871
872
873FX_BOOL app::browseForDoc(OBJ_METHOD_PARAMS)
874{
875	//This method may trigger a "file save" dialog,while enable user to save contents of the document.
876	//Such action is considered to be unsafe.
877	if (IsSafeMode(cc)) return TRUE;
878
879	v8::Isolate* isolate = GetIsolate(cc);
880
881	bool bSave = false;
882	CFX_ByteString cFilenameInit = CFX_ByteString();
883	CFX_ByteString cFSInit = CFX_ByteString();
884
885	if(params.size()>0 && (params[0].GetType() == VT_object))
886	{
887		JSObject pObj = (JSObject )params[0];
888
889 		v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj,L"bSave");
890 			bSave = (bool)CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue));
891
892		pValue = JS_GetObjectElement(isolate, pObj,L"cFilenameInit");
893		{
894			CJS_Value t = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue));
895 			cFilenameInit = t.operator CFX_ByteString();
896		}
897
898		pValue = JS_GetObjectElement(isolate,pObj,L"cFSInit");
899		{
900			CJS_Value t = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue));
901			cFSInit = t.operator CFX_ByteString();
902		}
903	}
904	else
905	{
906		if(params.size() >= 1)
907		{
908			bSave = (bool)params[0];
909		}
910		if(params.size() >= 2)
911		{
912			CJS_Value t = params[1];
913			cFilenameInit = t.operator CFX_ByteString();
914		}
915		if(params.size() >= 3)
916		{
917			CJS_Value t = params[2];
918			cFSInit = t.operator CFX_ByteString();
919		}
920	}
921	CJS_Context* pContext = (CJS_Context *)cc;
922	ASSERT(pContext != NULL);
923
924	CPDFDoc_Environment* pApp = pContext->GetReaderApp();
925	ASSERT(pApp != NULL);
926
927	CJS_Runtime* pRuntime = pContext->GetJSRuntime();
928	ASSERT(pRuntime != NULL);
929
930	CFX_WideString wsFileNameInit = CFX_WideString::FromLocal(cFilenameInit);
931	CFX_WideString wsFSInit = CFX_WideString::FromLocal(cFSInit);
932	CFX_WideString wsFilePath = pApp->JS_appbrowseForDoc(bSave, wsFileNameInit);
933	if(wsFilePath.IsEmpty())
934		return FALSE;
935
936	JSFXObject pRetObj = JS_NewFxDynamicObj(*pRuntime, pContext, -1);
937
938	JS_PutObjectString(isolate,pRetObj, L"cPath", SysPathToPDFPath(wsFilePath));
939	JS_PutObjectString(isolate,pRetObj, L"cURL", SysPathToPDFPath(wsFilePath));
940
941	if (!cFSInit.IsEmpty())
942	{
943		JS_PutObjectString(isolate,pRetObj, L"cFS", CFX_WideString::FromLocal(cFSInit.GetBuffer(cFSInit.GetLength())));
944	}
945	else
946	{
947		JS_PutObjectString(isolate,pRetObj, L"cFS", CFX_WideString::FromLocal("DOS"));
948	}
949
950	vRet =  pRetObj;
951
952	return TRUE;
953}
954
955CFX_WideString app::SysPathToPDFPath(const CFX_WideString& sOldPath)
956{
957	CFX_WideString sRet = L"/";
958
959	for (int i=0,sz=sOldPath.GetLength(); i<sz; i++)
960	{
961		wchar_t c = sOldPath.GetAt(i);
962		if (c == L':')
963		{
964		}
965		else
966		{
967			if (c == L'\\')
968			{
969				sRet += L"/";
970			}
971			else
972			{
973				sRet += c;
974			}
975		}
976	}
977
978	return sRet;
979}
980
981CFX_WideString app::PDFPathToSysPath(const CFX_WideString& sOldPath)
982{
983	//strLPath = "D:\temporay.fdf";
984	CFX_WideString strOPath = sOldPath;
985	strOPath.TrimLeft();
986	strOPath.TrimRight();
987
988	if (strOPath.GetAt(0) == L'/' && strOPath.GetAt(2) == L'/')
989	{
990		wchar_t c_Drive = strOPath.GetAt(1);
991		if ((c_Drive >= L'a' && c_Drive <= L'z' )||( c_Drive >= L'A' && c_Drive <= L'Z'))
992		{
993			strOPath.Replace((FX_LPCWSTR)L"/",(FX_LPCWSTR)L"\\");
994			//strOPath.SetAt(0,'');
995			strOPath.Insert(2,':');
996			strOPath.Delete(0);
997		}
998	}
999
1000	return strOPath;
1001}
1002
1003CFX_WideString app::RelativePathToSysPath(const CFX_WideString& sOldPath, const CFX_WideString& sFilePath)
1004{
1005//	if (!PathIsRelative(sOldPath)) return sOldPath;
1006
1007	int nSplit = 0;
1008	for (int i=sFilePath.GetLength()-1; i>=0; i--)
1009	{
1010		if (sFilePath[i] == '\\' || sFilePath[i] == '/')
1011		{
1012			nSplit = i;
1013			break;
1014		}
1015	}
1016
1017	return sFilePath.Left(nSplit+1) + sOldPath;
1018}
1019
1020FX_BOOL app::newDoc(OBJ_METHOD_PARAMS)
1021{
1022	return FALSE;
1023}
1024
1025FX_BOOL app::openDoc(OBJ_METHOD_PARAMS)
1026{
1027	return FALSE;
1028}
1029
1030FX_BOOL app::response(OBJ_METHOD_PARAMS)
1031{
1032	CFX_WideString swQuestion = L"";
1033	CFX_WideString swLabel = L"";
1034#ifndef FOXIT_CHROME_BUILD
1035	CFX_WideString swTitle = L"Foxit";
1036#else
1037	CFX_WideString swTitle = L"PDF";
1038#endif
1039	CFX_WideString swDefault = L"";
1040	CFX_WideString swResponse = L"";
1041	bool bPassWord = false;
1042
1043	v8::Isolate* isolate = GetIsolate(cc);
1044
1045	int iLength = params.size();
1046	if (iLength > 0 && params[0].GetType() == VT_object)
1047	{
1048
1049		JSObject pObj = (JSObject )params[0];
1050		v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate,pObj,L"cQuestion");
1051			swQuestion = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
1052
1053		pValue = JS_GetObjectElement(isolate,pObj,L"cTitle");
1054			swTitle = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
1055
1056		pValue = JS_GetObjectElement(isolate,pObj,L"cDefault");
1057			swDefault = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
1058
1059		pValue = JS_GetObjectElement(isolate,pObj,L"cLabel");
1060			swLabel = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).operator CFX_WideString();
1061
1062		pValue = JS_GetObjectElement(isolate,pObj,L"bPassword");
1063			bPassWord = (bool)CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue));
1064	}
1065	else
1066	{
1067		switch(iLength)
1068		{
1069		case 1:
1070			swQuestion = params[0];
1071			break;
1072		case 2:
1073			swQuestion = params[0];
1074			swTitle = params[1];
1075			break;
1076		case 3:
1077			swQuestion = params[0];
1078			swTitle = params[1];
1079			swDefault = params[2];
1080			break;
1081		case 4:
1082			swQuestion = params[0];
1083			swTitle = params[1];
1084			swDefault = params[2];
1085			bPassWord = params[3];
1086			break;
1087		case 5:
1088			swQuestion = params[0];
1089			swTitle = params[1];
1090			swDefault = params[2];
1091			bPassWord = params[3];
1092			swLabel = params[4];
1093			break;
1094		default:
1095			break;
1096		}
1097	}
1098
1099	CJS_Context* pContext = (CJS_Context *)cc;
1100 	ASSERT(pContext != NULL);
1101
1102	CPDFDoc_Environment* pApp = pContext->GetReaderApp();
1103 	ASSERT(pApp != NULL);
1104	int nLength = 2048;
1105	char* pBuff = new char[nLength];
1106	nLength = pApp->JS_appResponse(swQuestion, swTitle, swDefault, swLabel, bPassWord, pBuff, nLength);
1107	if(nLength<=0)
1108	{
1109		vRet.SetNull();
1110		return FALSE;
1111	}
1112	else
1113	{
1114		nLength = nLength>2046?2046:nLength;
1115    pBuff[nLength] = 0;
1116    pBuff[nLength+1] = 0;
1117		swResponse = CFX_WideString::FromUTF16LE((unsigned short*)pBuff, nLength);
1118		vRet = swResponse;
1119	}
1120	delete[] pBuff;
1121
1122	return TRUE;
1123}
1124
1125FX_BOOL app::media(OBJ_PROP_PARAMS)
1126{
1127	return FALSE;
1128}
1129
1130FX_BOOL app::execDialog(OBJ_METHOD_PARAMS)
1131{
1132	return TRUE;
1133}
1134
1135