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/Document.h"
13#include "../../include/javascript/JS_EventHandler.h"
14#include "../../include/javascript/JS_Context.h"
15#include "../../include/javascript/JS_Runtime.h"
16#include "../../include/javascript/app.h"
17#include "../../include/javascript/Field.h"
18#include "../../include/javascript/Icon.h"
19#include "../../include/javascript/resource.h"
20
21#include "../../../third_party/base/numerics/safe_math.h"
22
23static v8::Isolate* GetIsolate(IFXJS_Context* cc)
24{
25	CJS_Context* pContext = (CJS_Context *)cc;
26	ASSERT(pContext != NULL);
27
28	CJS_Runtime* pRuntime = pContext->GetJSRuntime();
29	ASSERT(pRuntime != NULL);
30
31	return pRuntime->GetIsolate();
32}
33
34BEGIN_JS_STATIC_CONST(CJS_PrintParamsObj)
35END_JS_STATIC_CONST()
36
37BEGIN_JS_STATIC_PROP(CJS_PrintParamsObj)
38END_JS_STATIC_PROP()
39
40BEGIN_JS_STATIC_METHOD(CJS_PrintParamsObj)
41END_JS_STATIC_METHOD()
42
43IMPLEMENT_JS_CLASS(CJS_PrintParamsObj, PrintParamsObj)
44
45PrintParamsObj::PrintParamsObj(CJS_Object* pJSObject)
46: CJS_EmbedObj(pJSObject)
47{
48	bUI = TRUE;
49	nStart = 0;
50	nEnd = 0;
51	bSilent = FALSE;
52	bShrinkToFit = FALSE;
53	bPrintAsImage = FALSE;
54	bReverse = FALSE;
55	bAnnotations = TRUE;
56}
57
58/* ---------------------- Document ---------------------- */
59
60#define MINWIDTH  5.0f
61#define MINHEIGHT 5.0f
62
63BEGIN_JS_STATIC_CONST(CJS_Document)
64END_JS_STATIC_CONST()
65
66BEGIN_JS_STATIC_PROP(CJS_Document)
67	JS_STATIC_PROP_ENTRY(ADBE)
68	JS_STATIC_PROP_ENTRY(author)
69	JS_STATIC_PROP_ENTRY(baseURL)
70	JS_STATIC_PROP_ENTRY(bookmarkRoot)
71	JS_STATIC_PROP_ENTRY(calculate)
72	JS_STATIC_PROP_ENTRY(Collab)
73	JS_STATIC_PROP_ENTRY(creationDate)
74	JS_STATIC_PROP_ENTRY(creator)
75	JS_STATIC_PROP_ENTRY(delay)
76	JS_STATIC_PROP_ENTRY(dirty)
77	JS_STATIC_PROP_ENTRY(documentFileName)
78	JS_STATIC_PROP_ENTRY(external)
79	JS_STATIC_PROP_ENTRY(filesize)
80	JS_STATIC_PROP_ENTRY(icons)
81	JS_STATIC_PROP_ENTRY(info)
82	JS_STATIC_PROP_ENTRY(keywords)
83	JS_STATIC_PROP_ENTRY(layout)
84	JS_STATIC_PROP_ENTRY(media)
85	JS_STATIC_PROP_ENTRY(modDate)
86	JS_STATIC_PROP_ENTRY(mouseX)
87	JS_STATIC_PROP_ENTRY(mouseY)
88	JS_STATIC_PROP_ENTRY(numFields)
89	JS_STATIC_PROP_ENTRY(numPages)
90	JS_STATIC_PROP_ENTRY(pageNum)
91	JS_STATIC_PROP_ENTRY(pageWindowRect)
92	JS_STATIC_PROP_ENTRY(path)
93	JS_STATIC_PROP_ENTRY(producer)
94	JS_STATIC_PROP_ENTRY(subject)
95	JS_STATIC_PROP_ENTRY(title)
96	JS_STATIC_PROP_ENTRY(zoom)
97	JS_STATIC_PROP_ENTRY(zoomType)
98END_JS_STATIC_PROP()
99
100BEGIN_JS_STATIC_METHOD(CJS_Document)
101	JS_STATIC_METHOD_ENTRY(addAnnot)
102	JS_STATIC_METHOD_ENTRY(addField)
103	JS_STATIC_METHOD_ENTRY(addLink)
104	JS_STATIC_METHOD_ENTRY(addIcon)
105	JS_STATIC_METHOD_ENTRY(calculateNow)
106	JS_STATIC_METHOD_ENTRY(closeDoc)
107	JS_STATIC_METHOD_ENTRY(createDataObject)
108	JS_STATIC_METHOD_ENTRY(deletePages)
109	JS_STATIC_METHOD_ENTRY(exportAsText)
110	JS_STATIC_METHOD_ENTRY(exportAsFDF)
111	JS_STATIC_METHOD_ENTRY(exportAsXFDF)
112	JS_STATIC_METHOD_ENTRY(extractPages)
113	JS_STATIC_METHOD_ENTRY(getAnnot)
114	JS_STATIC_METHOD_ENTRY(getAnnots)
115	JS_STATIC_METHOD_ENTRY(getAnnot3D)
116	JS_STATIC_METHOD_ENTRY(getAnnots3D)
117	JS_STATIC_METHOD_ENTRY(getField)
118	JS_STATIC_METHOD_ENTRY(getIcon)
119	JS_STATIC_METHOD_ENTRY(getLinks)
120	JS_STATIC_METHOD_ENTRY(getNthFieldName)
121	JS_STATIC_METHOD_ENTRY(getOCGs)
122	JS_STATIC_METHOD_ENTRY(getPageBox)
123	JS_STATIC_METHOD_ENTRY(getPageNthWord)
124	JS_STATIC_METHOD_ENTRY(getPageNthWordQuads)
125	JS_STATIC_METHOD_ENTRY(getPageNumWords)
126	JS_STATIC_METHOD_ENTRY(getPrintParams)
127	JS_STATIC_METHOD_ENTRY(getURL)
128	JS_STATIC_METHOD_ENTRY(importAnFDF)
129	JS_STATIC_METHOD_ENTRY(importAnXFDF)
130	JS_STATIC_METHOD_ENTRY(importTextData)
131	JS_STATIC_METHOD_ENTRY(insertPages)
132	JS_STATIC_METHOD_ENTRY(mailForm)
133	JS_STATIC_METHOD_ENTRY(print)
134	JS_STATIC_METHOD_ENTRY(removeField)
135	JS_STATIC_METHOD_ENTRY(replacePages)
136	JS_STATIC_METHOD_ENTRY(resetForm)
137	JS_STATIC_METHOD_ENTRY(removeIcon)
138	JS_STATIC_METHOD_ENTRY(saveAs)
139	JS_STATIC_METHOD_ENTRY(submitForm)
140	JS_STATIC_METHOD_ENTRY(mailDoc)
141END_JS_STATIC_METHOD()
142
143IMPLEMENT_JS_CLASS(CJS_Document, Document)
144
145FX_BOOL	CJS_Document::InitInstance(IFXJS_Context* cc)
146{
147	CJS_Context* pContext = (CJS_Context*)cc;
148	ASSERT(pContext != NULL);
149
150	Document* pDoc = (Document*)GetEmbedObject();
151	ASSERT(pDoc != NULL);
152
153	pDoc->AttachDoc(pContext->GetReaderDocument());
154	pDoc->SetIsolate(pContext->GetJSRuntime()->GetIsolate());
155	return TRUE;
156};
157
158/* --------------------------------- Document --------------------------------- */
159
160Document::Document(CJS_Object* pJSObject) : CJS_EmbedObj(pJSObject),
161	m_isolate(NULL),
162	m_pIconTree(NULL),
163	m_pDocument(NULL),
164	m_cwBaseURL(L""),
165	m_bDelay(FALSE)
166{
167}
168
169Document::~Document()
170{
171	if (m_pIconTree)
172	{
173		m_pIconTree->DeleteIconTree();
174		delete m_pIconTree;
175		m_pIconTree = NULL;
176	}
177	for (int i=0; i<m_DelayData.GetSize(); i++)
178	{
179		if (CJS_DelayData* pData = m_DelayData.GetAt(i))
180		{
181			delete pData;
182			pData = NULL;
183			m_DelayData.SetAt(i, NULL);
184
185		}
186	}
187
188	m_DelayData.RemoveAll();
189	m_DelayAnnotData.RemoveAll();
190}
191
192//the total number of fileds in document.
193FX_BOOL Document::numFields(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
194{
195	if (vp.IsSetting()) {
196		CJS_Context* pContext = static_cast<CJS_Context*>(cc);
197		sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
198		return FALSE;
199	}
200	CPDFSDK_InterForm *pInterForm = m_pDocument->GetInterForm();
201	CPDF_InterForm *pPDFForm = pInterForm->GetInterForm();
202	vp << (int)pPDFForm->CountFields();
203	return TRUE;
204}
205
206FX_BOOL Document::dirty(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
207{
208	ASSERT(m_pDocument != NULL);
209
210	if (vp.IsGetting())
211	{
212		if (m_pDocument->GetChangeMark())
213			vp << true;
214		else
215			vp << false;
216	}
217	else
218	{
219		bool bChanged = false;
220
221		vp >> bChanged;
222
223		if (bChanged)
224			m_pDocument->SetChangeMark();
225		else
226			m_pDocument->ClearChangeMark();
227	}
228
229	return TRUE;
230}
231
232FX_BOOL Document::ADBE(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
233{
234	ASSERT(m_pDocument != NULL);
235
236	if (vp.IsGetting())
237	{
238		vp.SetNull();
239	}
240	else
241	{
242	}
243
244	return TRUE;
245}
246
247FX_BOOL Document::pageNum(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
248{
249	ASSERT(m_pDocument != NULL);
250
251	if (vp.IsGetting())
252	{
253		if (CPDFSDK_PageView* pPageView = m_pDocument->GetCurrentView())
254		{
255			vp << pPageView->GetPageIndex();
256		}
257	}
258	else
259	{
260		int iPageCount = m_pDocument->GetPageCount();
261		int iPageNum = 0;
262		vp >> iPageNum;
263
264		CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
265		if (iPageNum >= 0 && iPageNum < iPageCount)
266		{
267			 pEnv->JS_docgotoPage(iPageNum);
268		}
269		else if (iPageNum >= iPageCount)
270		{
271			 pEnv->JS_docgotoPage(iPageCount-1);
272		}
273		else if (iPageNum < 0)
274		{
275			 pEnv->JS_docgotoPage(0);
276		}
277	}
278
279	return TRUE;
280}
281
282FX_BOOL Document::ParserParams(JSObject* pObj,CJS_AnnotObj& annotobj)
283{
284	// Not supported.
285	return TRUE;
286}
287
288FX_BOOL Document::addAnnot(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
289{
290	// Not supported.
291	return TRUE;
292}
293
294FX_BOOL Document::addField(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
295{
296	// Not supported.
297	return TRUE;
298}
299
300FX_BOOL Document::exportAsText(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
301{
302	// Unsafe, not supported.
303	return TRUE;
304}
305
306FX_BOOL Document::exportAsFDF(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
307{
308	// Unsafe, not supported.
309	return TRUE;
310}
311
312FX_BOOL Document::exportAsXFDF(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
313{
314	// Unsafe, not supported.
315	return TRUE;
316}
317
318//Maps a field object in PDF document to a JavaScript variable
319//comment:
320//note: the paremter cName, this is clue how to treat if the cName is not a valiable filed name in this document
321
322FX_BOOL Document::getField(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
323{
324	CJS_Context* pContext = (CJS_Context*)cc;
325	if (params.size() < 1) {
326		sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
327		return FALSE;
328	}
329
330	CFX_WideString wideName = params[0].ToCFXWideString();
331
332	CPDFSDK_InterForm* pInterForm = m_pDocument->GetInterForm();
333	CPDF_InterForm* pPDFForm = pInterForm->GetInterForm();
334	if (pPDFForm->CountFields(wideName) <= 0)
335	{
336		vRet.SetNull();
337		return TRUE;
338	}
339
340	CJS_Runtime* pRuntime = pContext->GetJSRuntime();
341	JSFXObject pFieldObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"Field"));
342
343	v8::Isolate* isolate = GetIsolate(cc);
344	CJS_Field* pJSField = (CJS_Field*)JS_GetPrivate(isolate,pFieldObj);
345	Field* pField = (Field *)pJSField->GetEmbedObject();
346	pField->AttachField(this, wideName);
347
348	vRet = pJSField;
349	return TRUE;
350}
351
352//Gets the name of the nth field in the document
353FX_BOOL Document::getNthFieldName(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
354{
355	CJS_Context* pContext = (CJS_Context*)cc;
356	if (params.size() != 1) {
357		sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
358		return FALSE;
359	}
360
361	int nIndex = params[0].ToInt();
362	if (nIndex < 0) {
363		sError = JSGetStringFromID(pContext, IDS_STRING_JSVALUEERROR);
364		return FALSE;
365	}
366
367	CPDFSDK_InterForm* pInterForm = m_pDocument->GetInterForm();
368	CPDF_InterForm* pPDFForm = pInterForm->GetInterForm();
369	CPDF_FormField* pField = pPDFForm->GetField(nIndex);
370	if (!pField)
371		return FALSE;
372
373	vRet = pField->GetFullName().c_str();
374	return TRUE;
375}
376
377FX_BOOL Document::importAnFDF(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
378{
379	// Unsafe, not supported.
380	return TRUE;
381}
382
383FX_BOOL Document::importAnXFDF(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
384{
385	// Unsafe, not supported.
386	return TRUE;
387}
388
389FX_BOOL Document::importTextData(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
390{
391	// Unsafe, not supported.
392	return TRUE;
393}
394
395//exports the form data and mails the resulting fdf file as an attachment to all recipients.
396//comment: need reader supports
397//note:
398//int CPDFSDK_Document::mailForm(FX_BOOL bUI,String cto,string ccc,string cbcc,string cSubject,string cms);
399
400FX_BOOL Document::mailForm(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
401{
402	ASSERT(m_pDocument != NULL);
403
404	if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) return FALSE;
405
406	int iLength = params.size();
407
408	FX_BOOL bUI = iLength > 0 ? params[0].ToBool() : TRUE;
409	CFX_WideString cTo = iLength > 1 ? params[1].ToCFXWideString() : L"";
410	CFX_WideString cCc = iLength > 2 ? params[2].ToCFXWideString() : L"";
411	CFX_WideString cBcc = iLength > 3 ? params[3].ToCFXWideString() : L"";
412	CFX_WideString cSubject = iLength > 4 ? params[4].ToCFXWideString() : L"";
413	CFX_WideString cMsg = iLength > 5 ? params[5].ToCFXWideString() : L"";
414
415	CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
416	ASSERT(pInterForm != NULL);
417
418	CFX_ByteTextBuf textBuf;
419	if (!pInterForm->ExportFormToFDFTextBuf(textBuf))
420		return FALSE;
421
422	CJS_Context* pContext = (CJS_Context*)cc;
423	ASSERT(pContext != NULL);
424	CPDFDoc_Environment* pEnv = pContext->GetReaderApp();
425	ASSERT(pEnv != NULL);
426	CJS_Runtime* pRuntime = pContext->GetJSRuntime();
427	ASSERT(pRuntime != NULL);
428
429	pRuntime->BeginBlock();
430	pEnv->JS_docmailForm(textBuf.GetBuffer(), textBuf.GetLength(), bUI, cTo.c_str(), cSubject.c_str(), cCc.c_str(), cBcc.c_str(), cMsg.c_str());
431	pRuntime->EndBlock();
432	return TRUE;
433}
434
435FX_BOOL Document::print(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
436{
437	CJS_Context* pContext = (CJS_Context*)cc;
438	ASSERT(pContext != NULL);
439	CJS_Runtime* pRuntime = pContext->GetJSRuntime();
440	ASSERT(pRuntime != NULL);
441
442	FX_BOOL bUI = TRUE;
443	int nStart = 0;
444	int nEnd = 0;
445	FX_BOOL bSilent = FALSE;
446	FX_BOOL bShrinkToFit = FALSE;
447	FX_BOOL bPrintAsImage = FALSE;
448	FX_BOOL bReverse = FALSE;
449	FX_BOOL bAnnotations = FALSE;
450
451	int nlength = params.size();
452	if(nlength ==9)
453	{
454		if (params[8].GetType() == VT_fxobject)
455		{
456			JSFXObject pObj = params[8].ToV8Object();
457			{
458				if (JS_GetObjDefnID(pObj) == JS_GetObjDefnID(*pRuntime, L"PrintParamsObj"))
459				{
460					if (CJS_Object* pJSObj = params[8].ToCJSObject())
461					{
462							if (PrintParamsObj* pprintparamsObj = (PrintParamsObj*)pJSObj->GetEmbedObject())
463							{
464								bUI = pprintparamsObj->bUI;
465								nStart = pprintparamsObj->nStart;
466								nEnd = pprintparamsObj->nEnd;
467								bSilent = pprintparamsObj->bSilent;
468								bShrinkToFit = pprintparamsObj->bShrinkToFit;
469								bPrintAsImage = pprintparamsObj->bPrintAsImage;
470								bReverse = pprintparamsObj->bReverse;
471								bAnnotations = pprintparamsObj->bAnnotations;
472							}
473					}
474				}
475			}
476		}
477	}
478	else
479	{
480		if(nlength >= 1)
481			bUI = params[0].ToBool();
482		if(nlength >= 2)
483			nStart = params[1].ToInt();
484		if(nlength >= 3)
485			nEnd = params[2].ToInt();
486		if(nlength >= 4)
487			bSilent = params[3].ToBool();
488		if(nlength >= 5)
489			bShrinkToFit = params[4].ToBool();
490		if(nlength >= 6)
491			bPrintAsImage = params[5].ToBool();
492		if(nlength >= 7)
493			bReverse = params[6].ToBool();
494		if(nlength >= 8)
495			bAnnotations = params[7].ToBool();
496	}
497
498	ASSERT(m_pDocument != NULL);
499
500	if (CPDFDoc_Environment* pEnv = m_pDocument->GetEnv())
501	{
502		pEnv->JS_docprint(bUI, nStart, nEnd, bSilent, bShrinkToFit, bPrintAsImage, bReverse, bAnnotations);
503		return TRUE;
504	}
505	return FALSE;
506}
507
508//removes the specified field from the document.
509//comment:
510//note: if the filed name is not retional, adobe is dumb for it.
511
512FX_BOOL Document::removeField(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
513{
514	ASSERT(m_pDocument != NULL);
515
516	if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) ||
517		m_pDocument->GetPermissions(FPDFPERM_ANNOT_FORM))) return FALSE;
518
519	CJS_Context* pContext = (CJS_Context*)cc;
520	if (params.size() != 1) {
521		sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
522		return FALSE;
523	}
524
525	CFX_WideString sFieldName = params[0].ToCFXWideString();
526	CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
527	ASSERT(pInterForm != NULL);
528
529	CFX_PtrArray widgets;
530	pInterForm->GetWidgets(sFieldName, widgets);
531
532	int nSize = widgets.GetSize();
533
534	if (nSize > 0)
535	{
536		for (int i=0; i<nSize; i++)
537		{
538			CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)widgets[i];
539			ASSERT(pWidget != NULL);
540
541			CPDF_Rect rcAnnot = pWidget->GetRect();
542			rcAnnot.left -= 1;
543			rcAnnot.bottom -= 1;
544			rcAnnot.right += 1;
545			rcAnnot.top += 1;
546
547			CFX_RectArray aRefresh;
548			aRefresh.Add(rcAnnot);
549
550			CPDF_Page* pPage = pWidget->GetPDFPage();
551			ASSERT(pPage != NULL);
552
553			CPDFSDK_PageView* pPageView = m_pDocument->GetPageView(pPage);
554			pPageView->DeleteAnnot(pWidget);
555
556			pPageView->UpdateRects(aRefresh);
557		}
558		m_pDocument->SetChangeMark();
559	}
560
561	return TRUE;
562}
563
564//reset filed values within a document.
565//comment:
566//note: if the fields names r not rational, aodbe is dumb for it.
567
568FX_BOOL Document::resetForm(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
569{
570	ASSERT(m_pDocument != NULL);
571
572	if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) ||
573		m_pDocument->GetPermissions(FPDFPERM_ANNOT_FORM) ||
574		m_pDocument->GetPermissions(FPDFPERM_FILL_FORM))) return FALSE;
575
576	CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
577	ASSERT(pInterForm != NULL);
578
579	CPDF_InterForm* pPDFForm = pInterForm->GetInterForm();
580	ASSERT(pPDFForm != NULL);
581
582	v8::Isolate* isolate = GetIsolate(cc);
583	CJS_Array aName(isolate);
584
585	if (params.size() > 0)
586	{
587		switch (params[0].GetType())
588		{
589		default:
590			aName.Attach(params[0].ToV8Array());
591			break;
592		case VT_string:
593			aName.SetElement(0,params[0]);
594			break;
595		}
596
597		CFX_PtrArray aFields;
598
599		for (int i=0,isz=aName.GetLength(); i<isz; i++)
600		{
601			CJS_Value valElement(isolate);
602			aName.GetElement(i,valElement);
603			CFX_WideString swVal = valElement.ToCFXWideString();
604
605			for (int j=0,jsz=pPDFForm->CountFields(swVal); j<jsz; j++)
606			{
607				aFields.Add((void*)pPDFForm->GetField(j,swVal));
608			}
609		}
610
611		if (aFields.GetSize() > 0)
612		{
613			pPDFForm->ResetForm(aFields, TRUE, TRUE);
614			m_pDocument->SetChangeMark();
615
616		}
617	}
618	else
619	{
620		pPDFForm->ResetForm(TRUE);
621		m_pDocument->SetChangeMark();
622
623	}
624
625	return TRUE;
626}
627
628
629FX_BOOL Document::saveAs(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
630{
631  // Unsafe, not supported.
632  return TRUE;
633}
634
635
636FX_BOOL Document::submitForm(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
637{
638	ASSERT(m_pDocument != NULL);
639	CJS_Context* pContext = (CJS_Context*)cc;
640	int nSize = params.size();
641	if (nSize < 1) {
642		sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
643		return FALSE;
644	}
645
646	CFX_WideString strURL;
647	FX_BOOL bFDF = TRUE;
648	FX_BOOL bEmpty = FALSE;
649	v8::Isolate* isolate = GetIsolate(cc);
650	CJS_Array aFields(isolate);
651
652	CJS_Value v = params[0];
653	if (v.GetType() == VT_string)
654	{
655		strURL = params[0].ToCFXWideString();
656		if (nSize > 1)
657			bFDF = params[1].ToBool();
658		if (nSize > 2)
659			bEmpty = params[2].ToBool();
660		if (nSize > 3)
661			aFields.Attach(params[3].ToV8Array());
662	}
663	else if (v.GetType() == VT_object)
664	{
665		JSObject pObj = params[0].ToV8Object();
666		v8::Local<v8::Value> pValue = JS_GetObjectElement(isolate, pObj, L"cURL");
667		if (!pValue.IsEmpty())
668			strURL = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
669		pValue = JS_GetObjectElement(isolate, pObj, L"bFDF");
670		bFDF = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue)).ToBool();
671		pValue = JS_GetObjectElement(isolate, pObj, L"bEmpty");
672		bEmpty = CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue)).ToBool();
673		pValue = JS_GetObjectElement(isolate, pObj,L"aFields");
674		aFields.Attach(CJS_Value(isolate, pValue, GET_VALUE_TYPE(pValue)).ToV8Array());
675	}
676
677	CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
678	ASSERT(pInterForm != NULL);
679	CPDF_InterForm* pPDFInterForm = pInterForm->GetInterForm();
680	ASSERT(pPDFInterForm != NULL);
681
682	FX_BOOL bAll = (aFields.GetLength() == 0);
683
684	if (bAll && bEmpty)
685	{
686		CJS_Context* pContext = (CJS_Context*)cc;
687		ASSERT(pContext != NULL);
688		CJS_Runtime* pRuntime = pContext->GetJSRuntime();
689		ASSERT(pRuntime != NULL);
690
691
692		if (pPDFInterForm->CheckRequiredFields())
693		{
694			pRuntime->BeginBlock();
695			pInterForm->SubmitForm(strURL, FALSE);
696			pRuntime->EndBlock();
697		}
698
699		return TRUE;
700	}
701	else
702	{
703		CFX_PtrArray fieldObjects;
704
705		for (int i=0,sz=aFields.GetLength(); i<sz; i++)
706		{
707			CJS_Value valName(isolate);
708			aFields.GetElement(i, valName);
709			CFX_WideString sName = valName.ToCFXWideString();
710
711			CPDF_InterForm* pPDFForm = pInterForm->GetInterForm();
712			ASSERT(pPDFForm != NULL);
713
714			for (int j=0, jsz=pPDFForm->CountFields(sName); j<jsz; j++)
715			{
716				CPDF_FormField* pField = pPDFForm->GetField(j, sName);
717				if (!bEmpty && pField->GetValue().IsEmpty())
718					continue;
719
720				fieldObjects.Add(pField);
721			}
722		}
723
724		CJS_Context* pContext = (CJS_Context*)cc;
725		ASSERT(pContext != NULL);
726		CJS_Runtime* pRuntime = pContext->GetJSRuntime();
727		ASSERT(pRuntime != NULL);
728
729
730		if (pPDFInterForm->CheckRequiredFields(&fieldObjects, TRUE))
731		{
732			pRuntime->BeginBlock();
733			pInterForm->SubmitFields(strURL, fieldObjects, TRUE, !bFDF);
734			pRuntime->EndBlock();
735		}
736
737		return TRUE;
738	}
739
740}
741
742//////////////////////////////////////////////////////////////////////////////////////////////
743
744void Document::AttachDoc(CPDFSDK_Document *pDoc)
745{
746	m_pDocument = pDoc;
747}
748
749CPDFSDK_Document * Document::GetReaderDoc()
750{
751	return m_pDocument;
752}
753
754FX_BOOL Document::ExtractFileName(CPDFSDK_Document *pDoc,CFX_ByteString &strFileName)
755{
756	return FALSE;
757}
758
759FX_BOOL Document::ExtractFolderName(CPDFSDK_Document *pDoc,CFX_ByteString &strFolderName)
760{
761	return FALSE;
762}
763
764FX_BOOL Document::bookmarkRoot(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
765{
766	return TRUE;
767}
768
769FX_BOOL Document::mailDoc(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
770{
771	ASSERT(m_pDocument != NULL);
772
773	FX_BOOL bUI = TRUE;
774	CFX_WideString cTo = L"";
775	CFX_WideString cCc = L"";
776	CFX_WideString cBcc = L"";
777	CFX_WideString cSubject = L"";
778	CFX_WideString cMsg = L"";
779
780	if (params.size() >= 1)
781		bUI = params[0].ToBool();
782	if (params.size() >= 2)
783		cTo = params[1].ToCFXWideString();
784	if (params.size() >= 3)
785		cCc = params[2].ToCFXWideString();
786	if (params.size() >= 4)
787		cBcc = params[3].ToCFXWideString();
788	if (params.size() >= 5)
789		cSubject = params[4].ToCFXWideString();
790	if (params.size() >= 6)
791		cMsg = params[5].ToCFXWideString();
792
793	v8::Isolate* isolate = GetIsolate(cc);
794
795	if(params.size() >= 1 && params[0].GetType() == VT_object)
796	{
797		JSObject pObj = params[0].ToV8Object();
798
799		v8::Local<v8::Value> pValue = JS_GetObjectElement(isolate,pObj, L"bUI");
800		bUI = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).ToInt();
801
802		pValue = JS_GetObjectElement(isolate,pObj, L"cTo");
803		cTo = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).ToCFXWideString();
804
805		pValue = JS_GetObjectElement(isolate,pObj, L"cCc");
806		cCc = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).ToCFXWideString();
807
808		pValue = JS_GetObjectElement(isolate,pObj, L"cBcc");
809		cBcc = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).ToCFXWideString();
810
811		pValue = JS_GetObjectElement(isolate,pObj, L"cSubject");
812		cSubject = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).ToCFXWideString();
813
814		pValue = JS_GetObjectElement(isolate,pObj, L"cMsg");
815		cMsg = CJS_Value(isolate,pValue,GET_VALUE_TYPE(pValue)).ToCFXWideString();
816
817	}
818
819	CJS_Context* pContext = (CJS_Context*)cc;
820	ASSERT(pContext != NULL);
821	CJS_Runtime* pRuntime = pContext->GetJSRuntime();
822	ASSERT(pRuntime != NULL);
823
824	pRuntime->BeginBlock();
825	CPDFDoc_Environment* pEnv = pRuntime->GetReaderApp();
826	pEnv->JS_docmailForm(NULL, 0, bUI, cTo.c_str(), cSubject.c_str(), cCc.c_str(), cBcc.c_str(), cMsg.c_str());
827	pRuntime->EndBlock();
828
829	return TRUE;
830}
831
832FX_BOOL Document::author(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
833{
834	ASSERT(m_pDocument != NULL);
835
836	CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
837	if (!pDictionary)return FALSE;
838
839	if (vp.IsGetting())
840	{
841		vp << pDictionary->GetUnicodeText("Author");
842		return TRUE;
843	}
844	else
845	{
846		if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE;
847
848		CFX_WideString csAuthor;
849		vp >> csAuthor;
850		pDictionary->SetAtString("Author", PDF_EncodeText(csAuthor));
851		m_pDocument->SetChangeMark();
852		return TRUE;
853	}
854}
855
856FX_BOOL Document::info(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
857{
858	ASSERT(m_pDocument != NULL);
859
860	CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
861	if (!pDictionary)return FALSE;
862
863	CFX_WideString cwAuthor			= pDictionary->GetUnicodeText("Author");
864	CFX_WideString cwTitle			= pDictionary->GetUnicodeText("Title");
865	CFX_WideString cwSubject		= pDictionary->GetUnicodeText("Subject");
866	CFX_WideString cwKeywords		= pDictionary->GetUnicodeText("Keywords");
867	CFX_WideString cwCreator		= pDictionary->GetUnicodeText("Creator");
868	CFX_WideString cwProducer		= pDictionary->GetUnicodeText("Producer");
869	CFX_WideString cwCreationDate	= pDictionary->GetUnicodeText("CreationDate");
870	CFX_WideString cwModDate		= pDictionary->GetUnicodeText("ModDate");
871	CFX_WideString cwTrapped		= pDictionary->GetUnicodeText("Trapped");
872
873	v8::Isolate* isolate = GetIsolate(cc);
874	if (vp.IsGetting())
875	{
876		CJS_Context* pContext = (CJS_Context *)cc;
877		CJS_Runtime* pRuntime = pContext->GetJSRuntime();
878
879		JSFXObject  pObj = JS_NewFxDynamicObj(*pRuntime, pContext, -1);
880
881		JS_PutObjectString(isolate, pObj, L"Author", cwAuthor.c_str());
882		JS_PutObjectString(isolate, pObj, L"Title", cwTitle.c_str());
883		JS_PutObjectString(isolate, pObj, L"Subject", cwSubject.c_str());
884		JS_PutObjectString(isolate, pObj, L"Keywords", cwKeywords.c_str());
885		JS_PutObjectString(isolate, pObj, L"Creator", cwCreator.c_str());
886		JS_PutObjectString(isolate, pObj, L"Producer", cwProducer.c_str());
887		JS_PutObjectString(isolate, pObj, L"CreationDate", cwCreationDate.c_str());
888		JS_PutObjectString(isolate, pObj, L"ModDate", cwModDate.c_str());
889		JS_PutObjectString(isolate, pObj, L"Trapped", cwTrapped.c_str());
890
891// It's to be compatible to non-standard info dictionary.
892		FX_POSITION pos = pDictionary->GetStartPos();
893		while(pos)
894		{
895			CFX_ByteString bsKey;
896			CPDF_Object* pValueObj = pDictionary->GetNextElement(pos, bsKey);
897			CFX_WideString wsKey  = CFX_WideString::FromUTF8(bsKey, bsKey.GetLength());
898			if((pValueObj->GetType()==PDFOBJ_STRING) || (pValueObj->GetType()==PDFOBJ_NAME) )
899				JS_PutObjectString(isolate, pObj, wsKey.c_str(), pValueObj->GetUnicodeText().c_str());
900			if(pValueObj->GetType()==PDFOBJ_NUMBER)
901				JS_PutObjectNumber(isolate,pObj, wsKey.c_str(), (float)pValueObj->GetNumber());
902			if(pValueObj->GetType()==PDFOBJ_BOOLEAN)
903				JS_PutObjectBoolean(isolate,pObj, wsKey.c_str(), (bool)pValueObj->GetInteger());
904		}
905
906		vp << pObj;
907		return TRUE;
908	}
909	else
910	{
911		return TRUE;
912	}
913}
914
915FX_BOOL Document::creationDate(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
916{
917	ASSERT(m_pDocument != NULL);
918
919	CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
920	if (!pDictionary)return FALSE;
921
922	if (vp.IsGetting())
923	{
924		vp << pDictionary->GetUnicodeText("CreationDate");
925		return TRUE;
926	}
927	else
928	{
929		if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE;
930
931		CFX_WideString csCreationDate;
932		vp >> csCreationDate;
933		pDictionary->SetAtString("CreationDate", PDF_EncodeText(csCreationDate));
934		m_pDocument->SetChangeMark();
935
936		return TRUE;
937	}
938}
939
940FX_BOOL Document::creator(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
941{
942	ASSERT(m_pDocument != NULL);
943
944	CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
945	if (!pDictionary)return FALSE;
946
947	if (vp.IsGetting())
948	{
949		vp << pDictionary->GetUnicodeText("Creator");
950		return TRUE;
951	}
952	else
953	{
954		if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE;
955
956		CFX_WideString csCreator;
957		vp >> csCreator;
958		pDictionary->SetAtString("Creator", PDF_EncodeText(csCreator));
959		m_pDocument->SetChangeMark();
960		return TRUE;
961	}
962}
963
964FX_BOOL Document::delay(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
965{
966	if (vp.IsGetting())
967	{
968		vp << m_bDelay;
969		return TRUE;
970	}
971	else
972	{
973		ASSERT(m_pDocument != NULL);
974
975		if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE;
976
977		bool b;
978		vp >> b;
979
980		m_bDelay = b;
981
982		if (m_bDelay)
983		{
984			for (int i=0,sz=m_DelayData.GetSize(); i<sz; i++)
985				delete m_DelayData.GetAt(i);
986
987			m_DelayData.RemoveAll();
988		}
989		else
990		{
991			CFX_ArrayTemplate<CJS_DelayData*> DelayDataToProcess;
992
993			for (int i=0,sz=m_DelayData.GetSize(); i < sz; i++)
994			{
995				if (CJS_DelayData* pData = m_DelayData.GetAt(i))
996				{
997					DelayDataToProcess.Add(pData);
998					m_DelayData.SetAt(i, NULL);
999				}
1000			}
1001			m_DelayData.RemoveAll();
1002
1003			for (int i=0,sz=DelayDataToProcess.GetSize(); i < sz; i++)
1004			{
1005				CJS_DelayData* pData = DelayDataToProcess.GetAt(i);
1006				Field::DoDelay(m_pDocument, pData);
1007				DelayDataToProcess.SetAt(i,NULL);
1008				delete pData;
1009			}
1010		}
1011
1012		return TRUE;
1013	}
1014}
1015
1016FX_BOOL Document::keywords(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1017{
1018	ASSERT(m_pDocument != NULL);
1019
1020	CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
1021	if (!pDictionary)return FALSE;
1022
1023	if (vp.IsGetting())
1024	{
1025		vp << pDictionary->GetUnicodeText("Keywords");
1026		return TRUE;
1027	}
1028	else
1029	{
1030		if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE;
1031
1032		CFX_WideString csKeywords;
1033		vp >> csKeywords;
1034		pDictionary->SetAtString("Keywords", PDF_EncodeText(csKeywords));
1035		m_pDocument->SetChangeMark();
1036		return TRUE;
1037	}
1038}
1039
1040FX_BOOL Document::modDate(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1041{
1042	ASSERT(m_pDocument != NULL);
1043
1044	CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
1045	if (!pDictionary)return FALSE;
1046
1047	if (vp.IsGetting())
1048	{
1049		vp << pDictionary->GetUnicodeText("ModDate");
1050		return TRUE;
1051	}
1052	else
1053	{
1054		if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE;
1055
1056		CFX_WideString csmodDate;
1057		vp >> csmodDate;
1058		pDictionary->SetAtString("ModDate", PDF_EncodeText(csmodDate));
1059		m_pDocument->SetChangeMark();
1060		return TRUE;
1061	}
1062}
1063
1064FX_BOOL Document::producer(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1065{
1066	ASSERT(m_pDocument != NULL);
1067
1068	CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
1069	if (!pDictionary)return FALSE;
1070
1071	if (vp.IsGetting())
1072	{
1073		vp << pDictionary->GetUnicodeText("Producer");
1074		return TRUE;
1075	}
1076	else
1077	{
1078		if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE;
1079
1080		CFX_WideString csproducer;
1081		vp >> csproducer;
1082		pDictionary->SetAtString("Producer", PDF_EncodeText(csproducer));
1083		m_pDocument->SetChangeMark();
1084		return TRUE;
1085	}
1086}
1087
1088FX_BOOL Document::subject(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1089{
1090	ASSERT(m_pDocument != NULL);
1091
1092	CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
1093	if (!pDictionary)return FALSE;
1094
1095	if (vp.IsGetting())
1096	{
1097		vp << pDictionary->GetUnicodeText("Subject");
1098		return TRUE;
1099	}
1100	else
1101	{
1102		if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE;
1103
1104		CFX_WideString cssubject;
1105		vp >> cssubject;
1106		pDictionary->SetAtString("Subject", PDF_EncodeText(cssubject));
1107		m_pDocument->SetChangeMark();
1108		return TRUE;
1109	}
1110}
1111
1112FX_BOOL Document::title(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1113{
1114	ASSERT(m_pDocument != NULL);
1115
1116	if (m_pDocument == NULL || m_pDocument->GetDocument() == NULL)
1117		return FALSE;
1118
1119	CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
1120	if (!pDictionary)return FALSE;
1121
1122	if (vp.IsGetting())
1123	{
1124		vp << pDictionary->GetUnicodeText("Title");
1125		return TRUE;
1126	}
1127	else
1128	{
1129		if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE;
1130
1131		CFX_WideString cstitle;
1132		vp >> cstitle;
1133		pDictionary->SetAtString("Title", PDF_EncodeText(cstitle));
1134		m_pDocument->SetChangeMark();
1135		return TRUE;
1136	}
1137}
1138
1139FX_BOOL Document::numPages(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1140{
1141	if (vp.IsSetting()) {
1142		CJS_Context* pContext = static_cast<CJS_Context*>(cc);
1143		sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
1144		return FALSE;
1145	}
1146	vp << m_pDocument->GetPageCount();
1147	return TRUE;
1148}
1149
1150FX_BOOL Document::external(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1151{
1152	//In Chrome case,should always return true.
1153	if (vp.IsGetting()) {
1154		vp << TRUE;
1155	}
1156	return TRUE;
1157}
1158
1159FX_BOOL Document::filesize(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1160{
1161	if (vp.IsSetting()) {
1162		CJS_Context* pContext = static_cast<CJS_Context*>(cc);
1163		sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
1164		return FALSE;
1165	}
1166	vp << 0;
1167	return TRUE;
1168}
1169
1170FX_BOOL Document::mouseX(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1171{
1172	return TRUE;
1173}
1174
1175FX_BOOL Document::mouseY(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1176{
1177	return TRUE;
1178}
1179
1180FX_BOOL Document::baseURL(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1181{
1182	if (vp.IsGetting())
1183	{
1184		vp << m_cwBaseURL;
1185	}
1186	else
1187	{
1188		vp >> m_cwBaseURL;
1189	}
1190	return TRUE;
1191}
1192
1193FX_BOOL Document::calculate(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1194{
1195	ASSERT(m_pDocument != NULL);
1196
1197	CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
1198	ASSERT(pInterForm != NULL);
1199
1200	if (vp.IsGetting())
1201	{
1202		if (pInterForm->IsCalculateEnabled())
1203			vp << true;
1204		else
1205			vp << false;
1206	}
1207	else
1208	{
1209		bool bCalculate;
1210		vp >> bCalculate;
1211
1212		pInterForm->EnableCalculate(bCalculate);
1213	}
1214
1215	return TRUE;
1216}
1217
1218FX_BOOL Document::documentFileName(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1219{
1220	if (vp.IsSetting()) {
1221		CJS_Context* pContext = static_cast<CJS_Context*>(cc);
1222		sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
1223		return FALSE;
1224	}
1225	CFX_WideString wsFilePath = m_pDocument->GetPath();
1226	FX_INT32 i = wsFilePath.GetLength() - 1;
1227	for ( ; i >= 0; i-- )
1228	{
1229		if ( wsFilePath.GetAt( i ) == L'\\' || wsFilePath.GetAt( i ) == L'/' )
1230			break;
1231	}
1232	if ( i >= 0 && i < wsFilePath.GetLength() - 1 )
1233	{
1234		vp << ( wsFilePath.GetBuffer( wsFilePath.GetLength() ) + i + 1 );
1235	}else{
1236		vp << L"";
1237	}
1238	return TRUE;
1239}
1240
1241CFX_WideString Document::ReversalStr(CFX_WideString cbFrom)
1242{
1243	size_t iLength = cbFrom.GetLength();
1244        pdfium::base::CheckedNumeric<size_t> iSize = sizeof(wchar_t);
1245	iSize *= (iLength + 1);
1246	wchar_t* pResult = (wchar_t*)malloc(iSize.ValueOrDie());
1247	wchar_t* pFrom = (wchar_t*)cbFrom.GetBuffer(iLength);
1248
1249	for (size_t i = 0; i < iLength; i++)
1250	{
1251		pResult[i] = *(pFrom + iLength - i - 1);
1252	}
1253	pResult[iLength] = L'\0';
1254
1255	cbFrom.ReleaseBuffer();
1256	CFX_WideString cbRet = CFX_WideString(pResult);
1257	free(pResult);
1258	pResult = NULL;
1259	return cbRet;
1260}
1261
1262CFX_WideString Document::CutString(CFX_WideString cbFrom)
1263{
1264	size_t iLength = cbFrom.GetLength();
1265	pdfium::base::CheckedNumeric<size_t> iSize = sizeof(wchar_t);
1266	iSize *= (iLength + 1);
1267	wchar_t* pResult = (wchar_t*)malloc(iSize.ValueOrDie());
1268	wchar_t* pFrom = (wchar_t*)cbFrom.GetBuffer(iLength);
1269
1270	for (int i = 0; i < iLength; i++)
1271	{
1272		if (pFrom[i] == L'\\' || pFrom[i] == L'/')
1273		{
1274			pResult[i] = L'\0';
1275			break;
1276		}
1277		pResult[i] = pFrom[i];
1278	}
1279	pResult[iLength] = L'\0';
1280
1281	cbFrom.ReleaseBuffer();
1282	CFX_WideString cbRet = CFX_WideString(pResult);
1283	free(pResult);
1284	pResult = NULL;
1285	return cbRet;
1286}
1287
1288FX_BOOL Document::path(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1289{
1290	if (vp.IsSetting()) {
1291		CJS_Context* pContext = static_cast<CJS_Context*>(cc);
1292		sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
1293		return FALSE;
1294	}
1295	vp << app::SysPathToPDFPath(m_pDocument->GetPath());
1296	return TRUE;
1297}
1298
1299FX_BOOL Document::pageWindowRect(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1300{
1301	return TRUE;
1302}
1303
1304FX_BOOL Document::layout(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1305{
1306	return TRUE;
1307}
1308
1309FX_BOOL Document::addLink(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1310{
1311	return TRUE;
1312}
1313
1314FX_BOOL Document::closeDoc(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1315{
1316	ASSERT(m_pDocument != NULL);
1317	return TRUE;
1318}
1319
1320FX_BOOL Document::getPageBox(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1321{
1322	return TRUE;
1323}
1324
1325FX_BOOL Document::getAnnot(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1326{
1327	return TRUE;
1328}
1329
1330FX_BOOL Document::getAnnots(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1331{
1332	vRet.SetNull();
1333	return TRUE;
1334}
1335
1336FX_BOOL Document::getAnnot3D(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1337{
1338	vRet.SetNull();
1339	return TRUE;
1340}
1341
1342FX_BOOL Document::getAnnots3D(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1343{
1344	vRet = VT_undefined;
1345	return TRUE;
1346}
1347
1348FX_BOOL Document::getOCGs(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1349{
1350	return TRUE;
1351}
1352
1353FX_BOOL Document::getLinks(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1354{
1355	return TRUE;
1356}
1357
1358bool Document::IsEnclosedInRect(CFX_FloatRect rect, CFX_FloatRect LinkRect)
1359{
1360	if (rect.left <= LinkRect.left
1361	  && rect.top <= LinkRect.top
1362	  && rect.right >= LinkRect.right
1363	  && rect.bottom >= LinkRect.bottom)
1364		return true;
1365	else
1366		return false;
1367}
1368
1369void IconTree::InsertIconElement(IconElement* pNewIcon)
1370{
1371	if (!pNewIcon)return;
1372
1373	if (m_pHead == NULL && m_pEnd == NULL)
1374	{
1375		m_pHead = m_pEnd = pNewIcon;
1376		m_iLength++;
1377	}
1378	else
1379	{
1380		m_pEnd->NextIcon = pNewIcon;
1381		m_pEnd = pNewIcon;
1382		m_iLength++;
1383	}
1384}
1385
1386void IconTree::DeleteIconTree()
1387{
1388	if (!m_pHead || !m_pEnd)return;
1389
1390	IconElement* pTemp = NULL;
1391	while(m_pEnd != m_pHead)
1392	{
1393		pTemp = m_pHead;
1394		m_pHead = m_pHead->NextIcon;
1395		delete pTemp;
1396	}
1397
1398	delete m_pEnd;
1399	m_pHead = NULL;
1400	m_pEnd = NULL;
1401}
1402
1403int IconTree::GetLength()
1404{
1405	return m_iLength;
1406}
1407
1408IconElement* IconTree::operator [](int iIndex)
1409{
1410	if (iIndex >= 0 && iIndex <= m_iLength)
1411	{
1412		IconElement* pTemp = m_pHead;
1413		for (int i = 0; i < iIndex; i++)
1414		{
1415			pTemp = pTemp->NextIcon;
1416		}
1417		return pTemp;
1418	}
1419	else
1420		return NULL;
1421}
1422
1423void IconTree::DeleteIconElement(CFX_WideString swIconName)
1424{
1425	IconElement* pTemp = m_pHead;
1426	int iLoopCount = m_iLength;
1427	for (int i = 0; i < iLoopCount - 1; i++)
1428	{
1429		if (pTemp == m_pEnd)
1430			break;
1431
1432		if (m_pHead->IconName == swIconName)
1433		{
1434			m_pHead = m_pHead->NextIcon;
1435			delete pTemp;
1436			m_iLength--;
1437			pTemp = m_pHead;
1438		}
1439		if (pTemp->NextIcon->IconName == swIconName)
1440		{
1441			if (pTemp->NextIcon == m_pEnd)
1442			{
1443				m_pEnd = pTemp;
1444				delete pTemp->NextIcon;
1445				m_iLength--;
1446				pTemp->NextIcon = NULL;
1447			}
1448			else
1449			{
1450				IconElement* pElement = pTemp->NextIcon;
1451				pTemp->NextIcon = pTemp->NextIcon->NextIcon;
1452				delete pElement;
1453				m_iLength--;
1454				pElement = NULL;
1455			}
1456
1457			continue;
1458		}
1459
1460		pTemp = pTemp->NextIcon;
1461	}
1462}
1463
1464FX_BOOL Document::addIcon(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1465{
1466	CJS_Context* pContext = (CJS_Context*)cc;
1467	if (params.size() != 2) {
1468		sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1469		return FALSE;
1470	}
1471
1472	CFX_WideString swIconName = params[0].ToCFXWideString();
1473	JSFXObject pJSIcon = params[1].ToV8Object();
1474
1475	CJS_Runtime* pRuntime = pContext->GetJSRuntime();
1476	if (JS_GetObjDefnID(pJSIcon) != JS_GetObjDefnID(*pRuntime, L"Icon")) {
1477		sError = JSGetStringFromID(pContext, IDS_STRING_JSTYPEERROR);
1478		return FALSE;
1479	}
1480
1481	CJS_EmbedObj* pEmbedObj = params[1].ToCJSObject()->GetEmbedObject();
1482	if (!pEmbedObj) {
1483		sError = JSGetStringFromID(pContext, IDS_STRING_JSTYPEERROR);
1484		return FALSE;
1485	}
1486
1487	Icon* pIcon = (Icon*)pEmbedObj;
1488	if (!m_pIconTree)
1489		m_pIconTree = new IconTree();
1490
1491	IconElement* pNewIcon = new IconElement();
1492	pNewIcon->IconName = swIconName;
1493	pNewIcon->NextIcon = NULL;
1494	pNewIcon->IconStream = pIcon;
1495	m_pIconTree->InsertIconElement(pNewIcon);
1496	return TRUE;
1497}
1498
1499FX_BOOL Document::icons(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1500{
1501	if (vp.IsSetting()) {
1502		CJS_Context* pContext = static_cast<CJS_Context*>(cc);
1503		sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
1504		return FALSE;
1505	}
1506
1507	if (!m_pIconTree)
1508	{
1509		vp.SetNull();
1510		return TRUE;
1511	}
1512
1513	CJS_Array Icons(m_isolate);
1514	IconElement* pIconElement = NULL;
1515	int iIconTreeLength = m_pIconTree->GetLength();
1516
1517	CJS_Context* pContext = (CJS_Context *)cc;
1518	CJS_Runtime* pRuntime = pContext->GetJSRuntime();
1519
1520	for (int i = 0; i < iIconTreeLength; i++)
1521	{
1522		pIconElement = (*m_pIconTree)[i];
1523
1524		JSFXObject  pObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"Icon"));
1525		if (pObj.IsEmpty()) return FALSE;
1526
1527		CJS_Icon * pJS_Icon = (CJS_Icon *)JS_GetPrivate(pObj);
1528		if (!pJS_Icon) return FALSE;
1529
1530		Icon* pIcon = (Icon*)pJS_Icon->GetEmbedObject();
1531		if (!pIcon)return FALSE;
1532
1533		pIcon->SetStream(pIconElement->IconStream->GetStream());
1534		pIcon->SetIconName(pIconElement->IconName);
1535		Icons.SetElement(i, CJS_Value(m_isolate,pJS_Icon));
1536	}
1537
1538	vp << Icons;
1539	return TRUE;
1540}
1541
1542FX_BOOL Document::getIcon(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1543{
1544	CJS_Context* pContext = (CJS_Context *)cc;
1545	if (params.size() != 1) {
1546		sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1547		return FALSE;
1548	}
1549
1550	if(!m_pIconTree)
1551		return FALSE;
1552	CFX_WideString swIconName = params[0].ToCFXWideString();
1553	int iIconCounts = m_pIconTree->GetLength();
1554
1555	CJS_Runtime* pRuntime = pContext->GetJSRuntime();
1556
1557	for (int i = 0; i < iIconCounts; i++)
1558	{
1559		if ((*m_pIconTree)[i]->IconName == swIconName)
1560		{
1561			Icon* pRetIcon = (*m_pIconTree)[i]->IconStream;
1562
1563			JSFXObject  pObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"Icon"));
1564			if (pObj.IsEmpty()) return FALSE;
1565
1566			CJS_Icon * pJS_Icon = (CJS_Icon *)JS_GetPrivate(pObj);
1567			if (!pJS_Icon) return FALSE;
1568
1569			Icon* pIcon = (Icon*)pJS_Icon->GetEmbedObject();
1570			if (!pIcon)return FALSE;
1571
1572			pIcon->SetIconName(swIconName);
1573			pIcon->SetStream(pRetIcon->GetStream());
1574			vRet = pJS_Icon;
1575			return TRUE;
1576		}
1577	}
1578
1579	return FALSE;
1580}
1581
1582FX_BOOL Document::removeIcon(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1583{
1584	CJS_Context* pContext = (CJS_Context *)cc;
1585	if (params.size() != 1) {
1586		sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1587		return FALSE;
1588	}
1589
1590	if(!m_pIconTree)
1591		return FALSE;
1592	CFX_WideString swIconName = params[0].ToCFXWideString();
1593	return TRUE;
1594}
1595
1596FX_BOOL Document::createDataObject(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1597{
1598  // Unsafe, not implemented.
1599  return TRUE;
1600}
1601
1602FX_BOOL Document::media(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1603{
1604	return TRUE;
1605}
1606
1607FX_BOOL Document::calculateNow(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1608{
1609	ASSERT(m_pDocument != NULL);
1610
1611	if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) ||
1612		m_pDocument->GetPermissions(FPDFPERM_ANNOT_FORM) ||
1613		m_pDocument->GetPermissions(FPDFPERM_FILL_FORM))) return FALSE;
1614
1615	CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
1616	ASSERT(pInterForm != NULL);
1617	pInterForm->OnCalculate();
1618	return TRUE;
1619}
1620
1621FX_BOOL Document::Collab(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1622{
1623	return TRUE;
1624}
1625
1626FX_BOOL Document::getPageNthWord(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1627{
1628	ASSERT(m_pDocument != NULL);
1629
1630	if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) return FALSE;
1631
1632	int nPageNo = params.GetSize() > 0 ? params[0].ToInt() : 0;
1633	int nWordNo = params.GetSize() > 1 ? params[1].ToInt() : 0;
1634	bool bStrip = params.GetSize() > 2 ? params[2].ToBool() : true;
1635
1636	CPDF_Document* pDocument = m_pDocument->GetDocument();
1637	if (!pDocument) return FALSE;
1638
1639	CJS_Context* pContext = static_cast<CJS_Context*>(cc);
1640	if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount())
1641	{
1642		sError = JSGetStringFromID(pContext, IDS_STRING_JSVALUEERROR);
1643		return FALSE;
1644	}
1645
1646	CPDF_Dictionary* pPageDict = pDocument->GetPage(nPageNo);
1647	if (!pPageDict) return FALSE;
1648
1649	CPDF_Page page;
1650	page.Load(pDocument, pPageDict);
1651	page.StartParse();
1652	page.ParseContent();
1653
1654	FX_POSITION pos = page.GetFirstObjectPosition();
1655
1656	int nWords = 0;
1657
1658	CFX_WideString swRet;
1659
1660	while (pos)
1661	{
1662		if (CPDF_PageObject* pPageObj = page.GetNextObject(pos))
1663		{
1664			if (pPageObj->m_Type == PDFPAGE_TEXT)
1665			{
1666				int nObjWords = CountWords((CPDF_TextObject*)pPageObj);
1667
1668				if (nWords + nObjWords >= nWordNo)
1669				{
1670					swRet = GetObjWordStr((CPDF_TextObject*)pPageObj, nWordNo - nWords);
1671					break;
1672				}
1673
1674				nWords += nObjWords;
1675			}
1676		}
1677	}
1678
1679	if (bStrip)
1680	{
1681		swRet.TrimLeft();
1682		swRet.TrimRight();
1683	}
1684
1685	vRet = swRet.c_str();
1686	return TRUE;
1687}
1688
1689FX_BOOL Document::getPageNthWordQuads(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1690{
1691	ASSERT(m_pDocument != NULL);
1692
1693	if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) return FALSE;
1694
1695	return FALSE;
1696}
1697
1698FX_BOOL Document::getPageNumWords(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1699{
1700	ASSERT(m_pDocument != NULL);
1701
1702	if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) return FALSE;
1703
1704	int nPageNo = params.GetSize() > 0 ? params[0].ToInt() : 0;
1705
1706	CPDF_Document* pDocument = m_pDocument->GetDocument();
1707	ASSERT(pDocument != NULL);
1708
1709	CJS_Context* pContext = static_cast<CJS_Context*>(cc);
1710	if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount())
1711	{
1712		sError = JSGetStringFromID(pContext, IDS_STRING_JSVALUEERROR);
1713		return FALSE;
1714	}
1715
1716	CPDF_Dictionary* pPageDict = pDocument->GetPage(nPageNo);
1717	if (!pPageDict) return FALSE;
1718
1719	CPDF_Page page;
1720	page.Load(pDocument, pPageDict);
1721	page.StartParse();
1722	page.ParseContent();
1723
1724	FX_POSITION pos = page.GetFirstObjectPosition();
1725
1726	int nWords = 0;
1727
1728	while (pos)
1729	{
1730		if (CPDF_PageObject* pPageObj = page.GetNextObject(pos))
1731		{
1732			if (pPageObj->m_Type == PDFPAGE_TEXT)
1733			{
1734				CPDF_TextObject* pTextObj = (CPDF_TextObject*)pPageObj;
1735				nWords += CountWords(pTextObj);
1736			}
1737		}
1738	}
1739
1740	vRet = nWords;
1741
1742	return TRUE;
1743}
1744
1745FX_BOOL Document::getPrintParams(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1746{
1747	CJS_Context* pContext = (CJS_Context*)cc;
1748	CJS_Runtime* pRuntime = pContext->GetJSRuntime();
1749	JSFXObject pRetObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"PrintParamsObj"));
1750
1751	// Not implemented yet.
1752
1753	vRet = pRetObj;
1754	return TRUE;
1755}
1756
1757#define ISLATINWORD(u)	(u != 0x20 && u <= 0x28FF)
1758
1759int	Document::CountWords(CPDF_TextObject* pTextObj)
1760{
1761	if (!pTextObj) return 0;
1762
1763	int nWords = 0;
1764
1765	CPDF_Font* pFont = pTextObj->GetFont();
1766	if (!pFont) return 0;
1767
1768	FX_BOOL bIsLatin = FALSE;
1769
1770	for (int i=0, sz=pTextObj->CountChars(); i<sz; i++)
1771	{
1772		FX_DWORD charcode = -1;
1773		FX_FLOAT kerning;
1774
1775		pTextObj->GetCharInfo(i, charcode, kerning);
1776		CFX_WideString swUnicode = pFont->UnicodeFromCharCode(charcode);
1777
1778		FX_WORD unicode = 0;
1779		if (swUnicode.GetLength() > 0)
1780			unicode = swUnicode[0];
1781
1782		if (ISLATINWORD(unicode) && bIsLatin)
1783			continue;
1784
1785		bIsLatin = ISLATINWORD(unicode);
1786		if (unicode != 0x20)
1787			nWords++;
1788	}
1789
1790	return nWords;
1791}
1792
1793CFX_WideString Document::GetObjWordStr(CPDF_TextObject* pTextObj, int nWordIndex)
1794{
1795	ASSERT(pTextObj != NULL);
1796
1797	CFX_WideString swRet;
1798
1799	CPDF_Font* pFont = pTextObj->GetFont();
1800	if (!pFont) return L"";
1801
1802	int nWords = 0;
1803	FX_BOOL bIsLatin = FALSE;
1804
1805	for (int i=0, sz=pTextObj->CountChars(); i<sz; i++)
1806	{
1807		FX_DWORD charcode = -1;
1808		FX_FLOAT kerning;
1809
1810		pTextObj->GetCharInfo(i, charcode, kerning);
1811		CFX_WideString swUnicode = pFont->UnicodeFromCharCode(charcode);
1812
1813		FX_WORD unicode = 0;
1814		if (swUnicode.GetLength() > 0)
1815			unicode = swUnicode[0];
1816
1817		if (ISLATINWORD(unicode) && bIsLatin)
1818		{
1819		}
1820		else
1821		{
1822			bIsLatin = ISLATINWORD(unicode);
1823			if (unicode != 0x20)
1824				nWords++;
1825		}
1826
1827		if (nWords-1 == nWordIndex)
1828			swRet += unicode;
1829	}
1830
1831	return swRet;
1832}
1833
1834FX_BOOL Document::zoom(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1835{
1836
1837	return TRUE;
1838}
1839
1840/**
1841(none,	NoVary)
1842(fitP,	FitPage)
1843(fitW,	FitWidth)
1844(fitH,	FitHeight)
1845(fitV,	FitVisibleWidth)
1846(pref,	Preferred)
1847(refW,	ReflowWidth)
1848*/
1849
1850FX_BOOL Document::zoomType(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1851{
1852	return TRUE;
1853}
1854
1855FX_BOOL Document::deletePages(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1856{
1857	v8::Isolate* isolate = GetIsolate(cc);
1858	ASSERT(m_pDocument != NULL);
1859
1860	if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) ||
1861		m_pDocument->GetPermissions(FPDFPERM_ASSEMBLE))) return FALSE;
1862
1863	int iSize = params.size();
1864
1865	int nStart = 0;
1866	int nEnd = 0;
1867
1868	if (iSize < 1)
1869	{
1870	}
1871	else if (iSize == 1)
1872	{
1873		if (params[0].GetType() == VT_object)
1874		{
1875			JSObject pObj = params[0].ToV8Object();
1876			v8::Local<v8::Value> pValue = JS_GetObjectElement(isolate, pObj, L"nStart");
1877            nStart = CJS_Value(m_isolate, pValue, GET_VALUE_TYPE(pValue)).ToInt();
1878
1879			pValue = JS_GetObjectElement(isolate, pObj, L"nEnd");
1880			nEnd = CJS_Value(m_isolate, pValue, GET_VALUE_TYPE(pValue)).ToInt();
1881		}
1882		else
1883		{
1884			nStart = params[0].ToInt();
1885		}
1886	}
1887	else
1888	{
1889		nStart = params[0].ToInt();
1890		nEnd = params[1].ToInt();
1891	}
1892
1893	int nTotal = m_pDocument->GetPageCount();
1894
1895	if (nStart < 0)	nStart = 0;
1896	if (nStart >= nTotal) nStart = nTotal - 1;
1897
1898	if (nEnd < 0) nEnd = 0;
1899	if (nEnd >= nTotal) nEnd = nTotal - 1;
1900
1901	if (nEnd < nStart) nEnd = nStart;
1902
1903
1904
1905	return TRUE;
1906}
1907
1908FX_BOOL Document::extractPages(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1909{
1910  // Unsafe, not supported.
1911  return TRUE;
1912}
1913
1914FX_BOOL Document::insertPages(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1915{
1916  // Unsafe, not supported.
1917  return TRUE;
1918}
1919
1920FX_BOOL Document::replacePages(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1921{
1922  // Unsafe, not supported.
1923  return TRUE;
1924}
1925
1926FX_BOOL Document::getURL(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1927{
1928  // Unsafe, not supported.
1929  return TRUE;
1930}
1931
1932void Document::AddDelayData(CJS_DelayData* pData)
1933{
1934	m_DelayData.Add(pData);
1935}
1936
1937void Document::DoFieldDelay(const CFX_WideString& sFieldName, int nControlIndex)
1938{
1939	CFX_DWordArray DelArray;
1940	CFX_ArrayTemplate<CJS_DelayData*> DelayDataForFieldAndControlIndex;
1941
1942	for (int i=0,sz=m_DelayData.GetSize(); i<sz; i++)
1943	{
1944		if (CJS_DelayData* pData = m_DelayData.GetAt(i))
1945		{
1946			if (pData->sFieldName == sFieldName && pData->nControlIndex == nControlIndex)
1947			{
1948				DelayDataForFieldAndControlIndex.Add(pData);
1949				m_DelayData.SetAt(i, NULL);
1950				DelArray.Add(i);
1951			}
1952		}
1953	}
1954
1955	for (int j=DelArray.GetSize()-1; j>=0; j--)
1956	{
1957		m_DelayData.RemoveAt(DelArray[j]);
1958	}
1959
1960	for (int i=0,sz=DelayDataForFieldAndControlIndex.GetSize(); i < sz; i++)
1961	{
1962		CJS_DelayData* pData = DelayDataForFieldAndControlIndex.GetAt(i);
1963		Field::DoDelay(m_pDocument, pData);
1964		DelayDataForFieldAndControlIndex.SetAt(i,NULL);
1965		delete pData;
1966	}
1967}
1968
1969void Document::AddDelayAnnotData(CJS_AnnotObj *pData)
1970{
1971	m_DelayAnnotData.Add(pData);
1972}
1973
1974void Document::DoAnnotDelay()
1975{
1976	CFX_DWordArray DelArray;
1977
1978	for (int j=DelArray.GetSize()-1; j>=0; j--)
1979	{
1980		m_DelayData.RemoveAt(DelArray[j]);
1981	}
1982}
1983
1984CJS_Document* Document::GetCJSDoc() const
1985{
1986	return static_cast<CJS_Document*>(m_pJSObject);
1987}
1988
1989