Kill operator LPCWSTR from CFX_WideString().
[pdfium.git] / fpdfsdk / src / javascript / Document.cpp
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
23 static 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
34 BEGIN_JS_STATIC_CONST(CJS_PrintParamsObj)
35 END_JS_STATIC_CONST()
36
37 BEGIN_JS_STATIC_PROP(CJS_PrintParamsObj)
38 END_JS_STATIC_PROP()
39
40 BEGIN_JS_STATIC_METHOD(CJS_PrintParamsObj)
41 END_JS_STATIC_METHOD()
42
43 IMPLEMENT_JS_CLASS(CJS_PrintParamsObj, PrintParamsObj)
44
45 PrintParamsObj::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
63 BEGIN_JS_STATIC_CONST(CJS_Document)
64 END_JS_STATIC_CONST()
65
66 BEGIN_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)
98 END_JS_STATIC_PROP()
99
100 BEGIN_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)
141 END_JS_STATIC_METHOD()
142
143 IMPLEMENT_JS_CLASS(CJS_Document, Document)
144
145 FX_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
160 Document::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
169 Document::~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.
193 FX_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
206 FX_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
232 FX_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
247 FX_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
282 FX_BOOL Document::ParserParams(JSObject* pObj,CJS_AnnotObj& annotobj)
283 {
284         // Not supported.
285         return TRUE;
286 }
287
288 FX_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
294 FX_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
300 FX_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
306 FX_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
312 FX_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
322 FX_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
353 FX_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
377 FX_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
383 FX_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
389 FX_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
400 FX_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
435 FX_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
512 FX_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
568 FX_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
629 FX_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
636 FX_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::Handle<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
744 void Document::AttachDoc(CPDFSDK_Document *pDoc)
745 {
746         m_pDocument = pDoc;
747 }
748
749 CPDFSDK_Document * Document::GetReaderDoc()
750 {
751         return m_pDocument;
752 }
753
754 FX_BOOL Document::ExtractFileName(CPDFSDK_Document *pDoc,CFX_ByteString &strFileName)
755 {
756         return FALSE;
757 }
758
759 FX_BOOL Document::ExtractFolderName(CPDFSDK_Document *pDoc,CFX_ByteString &strFolderName)
760 {
761         return FALSE;
762 }
763
764 FX_BOOL Document::bookmarkRoot(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
765 {
766         return TRUE;
767 }
768
769 FX_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::Handle<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
832 FX_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
856 FX_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
915 FX_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
940 FX_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
964 FX_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                         for (int i=0,sz=m_DelayData.GetSize(); i<sz; i++)
992                         {
993                                 if (CJS_DelayData* pData = m_DelayData.GetAt(i))
994                                 {
995                                         Field::DoDelay(m_pDocument, pData);
996                                         delete m_DelayData.GetAt(i);
997                                 }
998                         }
999                         m_DelayData.RemoveAll();
1000                 }
1001
1002                 return TRUE;
1003         }
1004 }
1005
1006 FX_BOOL Document::keywords(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1007 {
1008         ASSERT(m_pDocument != NULL);
1009
1010         CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
1011         if (!pDictionary)return FALSE;
1012
1013         if (vp.IsGetting())
1014         {
1015                 vp << pDictionary->GetUnicodeText("Keywords");
1016                 return TRUE;
1017         }
1018         else
1019         {
1020                 if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE;
1021
1022                 CFX_WideString csKeywords;
1023                 vp >> csKeywords;
1024                 pDictionary->SetAtString("Keywords", PDF_EncodeText(csKeywords));
1025                 m_pDocument->SetChangeMark();
1026                 return TRUE;
1027         }
1028 }
1029
1030 FX_BOOL Document::modDate(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1031 {
1032         ASSERT(m_pDocument != NULL);
1033
1034         CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
1035         if (!pDictionary)return FALSE;
1036
1037         if (vp.IsGetting())
1038         {
1039                 vp << pDictionary->GetUnicodeText("ModDate");
1040                 return TRUE;
1041         }
1042         else
1043         {
1044                 if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE;
1045
1046                 CFX_WideString csmodDate;
1047                 vp >> csmodDate;
1048                 pDictionary->SetAtString("ModDate", PDF_EncodeText(csmodDate));
1049                 m_pDocument->SetChangeMark();
1050                 return TRUE;
1051         }
1052 }
1053
1054 FX_BOOL Document::producer(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1055 {
1056         ASSERT(m_pDocument != NULL);
1057
1058         CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
1059         if (!pDictionary)return FALSE;
1060
1061         if (vp.IsGetting())
1062         {
1063                 vp << pDictionary->GetUnicodeText("Producer");
1064                 return TRUE;
1065         }
1066         else
1067         {
1068                 if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE;
1069
1070                 CFX_WideString csproducer;
1071                 vp >> csproducer;
1072                 pDictionary->SetAtString("Producer", PDF_EncodeText(csproducer));
1073                 m_pDocument->SetChangeMark();
1074                 return TRUE;
1075         }
1076 }
1077
1078 FX_BOOL Document::subject(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1079 {
1080         ASSERT(m_pDocument != NULL);
1081
1082         CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
1083         if (!pDictionary)return FALSE;
1084
1085         if (vp.IsGetting())
1086         {
1087                 vp << pDictionary->GetUnicodeText("Subject");
1088                 return TRUE;
1089         }
1090         else
1091         {
1092                 if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE;
1093
1094                 CFX_WideString cssubject;
1095                 vp >> cssubject;
1096                 pDictionary->SetAtString("Subject", PDF_EncodeText(cssubject));
1097                 m_pDocument->SetChangeMark();
1098                 return TRUE;
1099         }
1100 }
1101
1102 FX_BOOL Document::title(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1103 {
1104         ASSERT(m_pDocument != NULL);
1105
1106         if (m_pDocument == NULL || m_pDocument->GetDocument() == NULL)
1107                 return FALSE;
1108
1109         CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
1110         if (!pDictionary)return FALSE;
1111
1112         if (vp.IsGetting())
1113         {
1114                 vp << pDictionary->GetUnicodeText("Title");
1115                 return TRUE;
1116         }
1117         else
1118         {
1119                 if (!m_pDocument->GetPermissions(FPDFPERM_MODIFY)) return FALSE;
1120
1121                 CFX_WideString cstitle;
1122                 vp >> cstitle;
1123                 pDictionary->SetAtString("Title", PDF_EncodeText(cstitle));
1124                 m_pDocument->SetChangeMark();
1125                 return TRUE;
1126         }
1127 }
1128
1129 FX_BOOL Document::numPages(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1130 {
1131         if (vp.IsSetting()) {
1132                 CJS_Context* pContext = static_cast<CJS_Context*>(cc);
1133                 sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
1134                 return FALSE;
1135         }
1136         vp << m_pDocument->GetPageCount();
1137         return TRUE;
1138 }
1139
1140 FX_BOOL Document::external(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1141 {
1142         //In Chrome case,should always return true.
1143         if (vp.IsGetting()) {
1144                 vp << TRUE;
1145         }
1146         return TRUE;
1147 }
1148
1149 FX_BOOL Document::filesize(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1150 {
1151         if (vp.IsSetting()) {
1152                 CJS_Context* pContext = static_cast<CJS_Context*>(cc);
1153                 sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
1154                 return FALSE;
1155         }
1156         vp << 0;
1157         return TRUE;
1158 }
1159
1160 FX_BOOL Document::mouseX(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1161 {
1162         return TRUE;
1163 }
1164
1165 FX_BOOL Document::mouseY(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1166 {
1167         return TRUE;
1168 }
1169
1170 FX_BOOL Document::baseURL(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1171 {
1172         if (vp.IsGetting())
1173         {
1174                 vp << m_cwBaseURL;
1175         }
1176         else
1177         {
1178                 vp >> m_cwBaseURL;
1179         }
1180         return TRUE;
1181 }
1182
1183 FX_BOOL Document::calculate(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1184 {
1185         ASSERT(m_pDocument != NULL);
1186
1187         CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
1188         ASSERT(pInterForm != NULL);
1189
1190         if (vp.IsGetting())
1191         {
1192                 if (pInterForm->IsCalculateEnabled())
1193                         vp << true;
1194                 else
1195                         vp << false;
1196         }
1197         else
1198         {
1199                 bool bCalculate;
1200                 vp >> bCalculate;
1201
1202                 pInterForm->EnableCalculate(bCalculate);
1203         }
1204
1205         return TRUE;
1206 }
1207
1208 FX_BOOL Document::documentFileName(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1209 {
1210         if (vp.IsSetting()) {
1211                 CJS_Context* pContext = static_cast<CJS_Context*>(cc);
1212                 sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
1213                 return FALSE;
1214         }
1215         CFX_WideString wsFilePath = m_pDocument->GetPath();
1216         FX_INT32 i = wsFilePath.GetLength() - 1;
1217         for ( ; i >= 0; i-- )
1218         {
1219                 if ( wsFilePath.GetAt( i ) == L'\\' || wsFilePath.GetAt( i ) == L'/' )
1220                         break;
1221         }
1222         if ( i >= 0 && i < wsFilePath.GetLength() - 1 )
1223         {
1224                 vp << ( wsFilePath.GetBuffer( wsFilePath.GetLength() ) + i + 1 );
1225         }else{
1226                 vp << L"";
1227         }
1228         return TRUE;
1229 }
1230
1231 CFX_WideString Document::ReversalStr(CFX_WideString cbFrom)
1232 {
1233         size_t iLength = cbFrom.GetLength();
1234         pdfium::base::CheckedNumeric<size_t> iSize = sizeof(wchar_t);
1235         iSize *= (iLength + 1);
1236         wchar_t* pResult = (wchar_t*)malloc(iSize.ValueOrDie());
1237         wchar_t* pFrom = (wchar_t*)cbFrom.GetBuffer(iLength);
1238
1239         for (size_t i = 0; i < iLength; i++)
1240         {
1241                 pResult[i] = *(pFrom + iLength - i - 1);
1242         }
1243         pResult[iLength] = L'\0';
1244
1245         cbFrom.ReleaseBuffer();
1246         CFX_WideString cbRet = CFX_WideString(pResult);
1247         free(pResult);
1248         pResult = NULL;
1249         return cbRet;
1250 }
1251
1252 CFX_WideString Document::CutString(CFX_WideString cbFrom)
1253 {
1254         size_t iLength = cbFrom.GetLength();
1255         pdfium::base::CheckedNumeric<size_t> iSize = sizeof(wchar_t);
1256         iSize *= (iLength + 1);
1257         wchar_t* pResult = (wchar_t*)malloc(iSize.ValueOrDie());
1258         wchar_t* pFrom = (wchar_t*)cbFrom.GetBuffer(iLength);
1259
1260         for (int i = 0; i < iLength; i++)
1261         {
1262                 if (pFrom[i] == L'\\' || pFrom[i] == L'/')
1263                 {
1264                         pResult[i] = L'\0';
1265                         break;
1266                 }
1267                 pResult[i] = pFrom[i];
1268         }
1269         pResult[iLength] = L'\0';
1270
1271         cbFrom.ReleaseBuffer();
1272         CFX_WideString cbRet = CFX_WideString(pResult);
1273         free(pResult);
1274         pResult = NULL;
1275         return cbRet;
1276 }
1277
1278 FX_BOOL Document::path(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1279 {
1280         if (vp.IsSetting()) {
1281                 CJS_Context* pContext = static_cast<CJS_Context*>(cc);
1282                 sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
1283                 return FALSE;
1284         }
1285         vp << app::SysPathToPDFPath(m_pDocument->GetPath());
1286         return TRUE;
1287 }
1288
1289 FX_BOOL Document::pageWindowRect(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1290 {
1291         return TRUE;
1292 }
1293
1294 FX_BOOL Document::layout(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1295 {
1296         return TRUE;
1297 }
1298
1299 FX_BOOL Document::addLink(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1300 {
1301         return TRUE;
1302 }
1303
1304 FX_BOOL Document::closeDoc(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1305 {
1306         ASSERT(m_pDocument != NULL);
1307         return TRUE;
1308 }
1309
1310 FX_BOOL Document::getPageBox(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1311 {
1312         return TRUE;
1313 }
1314
1315 FX_BOOL Document::getAnnot(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1316 {
1317         return TRUE;
1318 }
1319
1320 FX_BOOL Document::getAnnots(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1321 {
1322         vRet.SetNull();
1323         return TRUE;
1324 }
1325
1326 FX_BOOL Document::getAnnot3D(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1327 {
1328         vRet.SetNull();
1329         return TRUE;
1330 }
1331
1332 FX_BOOL Document::getAnnots3D(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1333 {
1334         vRet = VT_undefined;
1335         return TRUE;
1336 }
1337
1338 FX_BOOL Document::getOCGs(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1339 {
1340         return TRUE;
1341 }
1342
1343 FX_BOOL Document::getLinks(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1344 {
1345         return TRUE;
1346 }
1347
1348 bool Document::IsEnclosedInRect(CFX_FloatRect rect, CFX_FloatRect LinkRect)
1349 {
1350         if (rect.left <= LinkRect.left
1351           && rect.top <= LinkRect.top
1352           && rect.right >= LinkRect.right
1353           && rect.bottom >= LinkRect.bottom)
1354                 return true;
1355         else
1356                 return false;
1357 }
1358
1359 void IconTree::InsertIconElement(IconElement* pNewIcon)
1360 {
1361         if (!pNewIcon)return;
1362
1363         if (m_pHead == NULL && m_pEnd == NULL)
1364         {
1365                 m_pHead = m_pEnd = pNewIcon;
1366                 m_iLength++;
1367         }
1368         else
1369         {
1370                 m_pEnd->NextIcon = pNewIcon;
1371                 m_pEnd = pNewIcon;
1372                 m_iLength++;
1373         }
1374 }
1375
1376 void IconTree::DeleteIconTree()
1377 {
1378         if (!m_pHead || !m_pEnd)return;
1379
1380         IconElement* pTemp = NULL;
1381         while(m_pEnd != m_pHead)
1382         {
1383                 pTemp = m_pHead;
1384                 m_pHead = m_pHead->NextIcon;
1385                 delete pTemp;
1386         }
1387
1388         delete m_pEnd;
1389         m_pHead = NULL;
1390         m_pEnd = NULL;
1391 }
1392
1393 int IconTree::GetLength()
1394 {
1395         return m_iLength;
1396 }
1397
1398 IconElement* IconTree::operator [](int iIndex)
1399 {
1400         if (iIndex >= 0 && iIndex <= m_iLength)
1401         {
1402                 IconElement* pTemp = m_pHead;
1403                 for (int i = 0; i < iIndex; i++)
1404                 {
1405                         pTemp = pTemp->NextIcon;
1406                 }
1407                 return pTemp;
1408         }
1409         else
1410                 return NULL;
1411 }
1412
1413 void IconTree::DeleteIconElement(CFX_WideString swIconName)
1414 {
1415         IconElement* pTemp = m_pHead;
1416         int iLoopCount = m_iLength;
1417         for (int i = 0; i < iLoopCount - 1; i++)
1418         {
1419                 if (pTemp == m_pEnd)
1420                         break;
1421
1422                 if (m_pHead->IconName == swIconName)
1423                 {
1424                         m_pHead = m_pHead->NextIcon;
1425                         delete pTemp;
1426                         m_iLength--;
1427                         pTemp = m_pHead;
1428                 }
1429                 if (pTemp->NextIcon->IconName == swIconName)
1430                 {
1431                         if (pTemp->NextIcon == m_pEnd)
1432                         {
1433                                 m_pEnd = pTemp;
1434                                 delete pTemp->NextIcon;
1435                                 m_iLength--;
1436                                 pTemp->NextIcon = NULL;
1437                         }
1438                         else
1439                         {
1440                                 IconElement* pElement = pTemp->NextIcon;
1441                                 pTemp->NextIcon = pTemp->NextIcon->NextIcon;
1442                                 delete pElement;
1443                                 m_iLength--;
1444                                 pElement = NULL;
1445                         }
1446
1447                         continue;
1448                 }
1449
1450                 pTemp = pTemp->NextIcon;
1451         }
1452 }
1453
1454 FX_BOOL Document::addIcon(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1455 {
1456         CJS_Context* pContext = (CJS_Context*)cc;
1457         if (params.size() != 2) {
1458                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1459                 return FALSE;
1460         }
1461
1462         CFX_WideString swIconName = params[0].ToCFXWideString();
1463         JSFXObject pJSIcon = params[1].ToV8Object();
1464
1465         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
1466         if (JS_GetObjDefnID(pJSIcon) != JS_GetObjDefnID(*pRuntime, L"Icon")) {
1467                 sError = JSGetStringFromID(pContext, IDS_STRING_JSTYPEERROR);
1468                 return FALSE;
1469         }
1470
1471         CJS_EmbedObj* pEmbedObj = params[1].ToCJSObject()->GetEmbedObject();
1472         if (!pEmbedObj) {
1473                 sError = JSGetStringFromID(pContext, IDS_STRING_JSTYPEERROR);
1474                 return FALSE;
1475         }
1476
1477         Icon* pIcon = (Icon*)pEmbedObj;
1478         if (!m_pIconTree)
1479                 m_pIconTree = new IconTree();
1480
1481         IconElement* pNewIcon = new IconElement();
1482         pNewIcon->IconName = swIconName;
1483         pNewIcon->NextIcon = NULL;
1484         pNewIcon->IconStream = pIcon;
1485         m_pIconTree->InsertIconElement(pNewIcon);
1486         return TRUE;
1487 }
1488
1489 FX_BOOL Document::icons(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1490 {
1491         if (vp.IsSetting()) {
1492                 CJS_Context* pContext = static_cast<CJS_Context*>(cc);
1493                 sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
1494                 return FALSE;
1495         }
1496
1497         if (!m_pIconTree)
1498         {
1499                 vp.SetNull();
1500                 return TRUE;
1501         }
1502
1503         CJS_Array Icons(m_isolate);
1504         IconElement* pIconElement = NULL;
1505         int iIconTreeLength = m_pIconTree->GetLength();
1506
1507         CJS_Context* pContext = (CJS_Context *)cc;
1508         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
1509
1510         for (int i = 0; i < iIconTreeLength; i++)
1511         {
1512                 pIconElement = (*m_pIconTree)[i];
1513
1514                 JSFXObject  pObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"Icon"));
1515                 if (pObj.IsEmpty()) return FALSE;
1516
1517                 CJS_Icon * pJS_Icon = (CJS_Icon *)JS_GetPrivate(pObj);
1518                 if (!pJS_Icon) return FALSE;
1519
1520                 Icon* pIcon = (Icon*)pJS_Icon->GetEmbedObject();
1521                 if (!pIcon)return FALSE;
1522
1523                 pIcon->SetStream(pIconElement->IconStream->GetStream());
1524                 pIcon->SetIconName(pIconElement->IconName);
1525                 Icons.SetElement(i, CJS_Value(m_isolate,pJS_Icon));
1526         }
1527
1528         vp << Icons;
1529         return TRUE;
1530 }
1531
1532 FX_BOOL Document::getIcon(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1533 {
1534         CJS_Context* pContext = (CJS_Context *)cc;
1535         if (params.size() != 1) {
1536                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1537                 return FALSE;
1538         }
1539
1540         if(!m_pIconTree)
1541                 return FALSE;
1542         CFX_WideString swIconName = params[0].ToCFXWideString();
1543         int iIconCounts = m_pIconTree->GetLength();
1544
1545         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
1546
1547         for (int i = 0; i < iIconCounts; i++)
1548         {
1549                 if ((*m_pIconTree)[i]->IconName == swIconName)
1550                 {
1551                         Icon* pRetIcon = (*m_pIconTree)[i]->IconStream;
1552
1553                         JSFXObject  pObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"Icon"));
1554                         if (pObj.IsEmpty()) return FALSE;
1555
1556                         CJS_Icon * pJS_Icon = (CJS_Icon *)JS_GetPrivate(pObj);
1557                         if (!pJS_Icon) return FALSE;
1558
1559                         Icon* pIcon = (Icon*)pJS_Icon->GetEmbedObject();
1560                         if (!pIcon)return FALSE;
1561
1562                         pIcon->SetIconName(swIconName);
1563                         pIcon->SetStream(pRetIcon->GetStream());
1564                         vRet = pJS_Icon;
1565                         return TRUE;
1566                 }
1567         }
1568
1569         return FALSE;
1570 }
1571
1572 FX_BOOL Document::removeIcon(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1573 {
1574         CJS_Context* pContext = (CJS_Context *)cc;
1575         if (params.size() != 1) {
1576                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1577                 return FALSE;
1578         }
1579
1580         if(!m_pIconTree)
1581                 return FALSE;
1582         CFX_WideString swIconName = params[0].ToCFXWideString();
1583         return TRUE;
1584 }
1585
1586 FX_BOOL Document::createDataObject(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1587 {
1588   // Unsafe, not implemented.
1589   return TRUE;
1590 }
1591
1592 FX_BOOL Document::media(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1593 {
1594         return TRUE;
1595 }
1596
1597 FX_BOOL Document::calculateNow(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1598 {
1599         ASSERT(m_pDocument != NULL);
1600
1601         if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) ||
1602                 m_pDocument->GetPermissions(FPDFPERM_ANNOT_FORM) ||
1603                 m_pDocument->GetPermissions(FPDFPERM_FILL_FORM))) return FALSE;
1604
1605         CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)m_pDocument->GetInterForm();
1606         ASSERT(pInterForm != NULL);
1607         pInterForm->OnCalculate();
1608         return TRUE;
1609 }
1610
1611 FX_BOOL Document::Collab(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1612 {
1613         return TRUE;
1614 }
1615
1616 FX_BOOL Document::getPageNthWord(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1617 {
1618         ASSERT(m_pDocument != NULL);
1619
1620         if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) return FALSE;
1621
1622         int nPageNo = params.GetSize() > 0 ? params[0].ToInt() : 0;
1623         int nWordNo = params.GetSize() > 1 ? params[1].ToInt() : 0;
1624         bool bStrip = params.GetSize() > 2 ? params[2].ToBool() : true;
1625
1626         CPDF_Document* pDocument = m_pDocument->GetDocument();
1627         if (!pDocument) return FALSE;
1628
1629         CJS_Context* pContext = static_cast<CJS_Context*>(cc);
1630         if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount())
1631         {
1632                 sError = JSGetStringFromID(pContext, IDS_STRING_JSVALUEERROR);
1633                 return FALSE;
1634         }
1635
1636         CPDF_Dictionary* pPageDict = pDocument->GetPage(nPageNo);
1637         if (!pPageDict) return FALSE;
1638
1639         CPDF_Page page;
1640         page.Load(pDocument, pPageDict);
1641         page.StartParse();
1642         page.ParseContent();
1643
1644         FX_POSITION pos = page.GetFirstObjectPosition();
1645
1646         int nWords = 0;
1647
1648         CFX_WideString swRet;
1649
1650         while (pos)
1651         {
1652                 if (CPDF_PageObject* pPageObj = page.GetNextObject(pos))
1653                 {
1654                         if (pPageObj->m_Type == PDFPAGE_TEXT)
1655                         {
1656                                 int nObjWords = CountWords((CPDF_TextObject*)pPageObj);
1657
1658                                 if (nWords + nObjWords >= nWordNo)
1659                                 {
1660                                         swRet = GetObjWordStr((CPDF_TextObject*)pPageObj, nWordNo - nWords);
1661                                         break;
1662                                 }
1663
1664                                 nWords += nObjWords;
1665                         }
1666                 }
1667         }
1668
1669         if (bStrip)
1670         {
1671                 swRet.TrimLeft();
1672                 swRet.TrimRight();
1673         }
1674
1675         vRet = swRet.c_str();
1676         return TRUE;
1677 }
1678
1679 FX_BOOL Document::getPageNthWordQuads(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1680 {
1681         ASSERT(m_pDocument != NULL);
1682
1683         if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) return FALSE;
1684
1685         return FALSE;
1686 }
1687
1688 FX_BOOL Document::getPageNumWords(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1689 {
1690         ASSERT(m_pDocument != NULL);
1691
1692         if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) return FALSE;
1693
1694         int nPageNo = params.GetSize() > 0 ? params[0].ToInt() : 0;
1695
1696         CPDF_Document* pDocument = m_pDocument->GetDocument();
1697         ASSERT(pDocument != NULL);
1698
1699         CJS_Context* pContext = static_cast<CJS_Context*>(cc);
1700         if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount())
1701         {
1702                 sError = JSGetStringFromID(pContext, IDS_STRING_JSVALUEERROR);
1703                 return FALSE;
1704         }
1705
1706         CPDF_Dictionary* pPageDict = pDocument->GetPage(nPageNo);
1707         if (!pPageDict) return FALSE;
1708
1709         CPDF_Page page;
1710         page.Load(pDocument, pPageDict);
1711         page.StartParse();
1712         page.ParseContent();
1713
1714         FX_POSITION pos = page.GetFirstObjectPosition();
1715
1716         int nWords = 0;
1717
1718         while (pos)
1719         {
1720                 if (CPDF_PageObject* pPageObj = page.GetNextObject(pos))
1721                 {
1722                         if (pPageObj->m_Type == PDFPAGE_TEXT)
1723                         {
1724                                 CPDF_TextObject* pTextObj = (CPDF_TextObject*)pPageObj;
1725                                 nWords += CountWords(pTextObj);
1726                         }
1727                 }
1728         }
1729
1730         vRet = nWords;
1731
1732         return TRUE;
1733 }
1734
1735 FX_BOOL Document::getPrintParams(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1736 {
1737         CJS_Context* pContext = (CJS_Context*)cc;
1738         CJS_Runtime* pRuntime = pContext->GetJSRuntime();
1739         JSFXObject pRetObj = JS_NewFxDynamicObj(*pRuntime, pContext, JS_GetObjDefnID(*pRuntime, L"PrintParamsObj"));
1740
1741         // Not implemented yet.
1742
1743         vRet = pRetObj;
1744         return TRUE;
1745 }
1746
1747 #define ISLATINWORD(u)  (u != 0x20 && u <= 0x28FF)
1748
1749 int     Document::CountWords(CPDF_TextObject* pTextObj)
1750 {
1751         if (!pTextObj) return 0;
1752
1753         int nWords = 0;
1754
1755         CPDF_Font* pFont = pTextObj->GetFont();
1756         if (!pFont) return 0;
1757
1758         FX_BOOL bIsLatin = FALSE;
1759
1760         for (int i=0, sz=pTextObj->CountChars(); i<sz; i++)
1761         {
1762                 FX_DWORD charcode = -1;
1763                 FX_FLOAT kerning;
1764
1765                 pTextObj->GetCharInfo(i, charcode, kerning);
1766                 CFX_WideString swUnicode = pFont->UnicodeFromCharCode(charcode);
1767
1768                 FX_WORD unicode = 0;
1769                 if (swUnicode.GetLength() > 0)
1770                         unicode = swUnicode[0];
1771
1772                 if (ISLATINWORD(unicode) && bIsLatin)
1773                         continue;
1774
1775                 bIsLatin = ISLATINWORD(unicode);
1776                 if (unicode != 0x20)
1777                         nWords++;
1778         }
1779
1780         return nWords;
1781 }
1782
1783 CFX_WideString Document::GetObjWordStr(CPDF_TextObject* pTextObj, int nWordIndex)
1784 {
1785         ASSERT(pTextObj != NULL);
1786
1787         CFX_WideString swRet;
1788
1789         CPDF_Font* pFont = pTextObj->GetFont();
1790         if (!pFont) return L"";
1791
1792         int nWords = 0;
1793         FX_BOOL bIsLatin = FALSE;
1794
1795         for (int i=0, sz=pTextObj->CountChars(); i<sz; i++)
1796         {
1797                 FX_DWORD charcode = -1;
1798                 FX_FLOAT kerning;
1799
1800                 pTextObj->GetCharInfo(i, charcode, kerning);
1801                 CFX_WideString swUnicode = pFont->UnicodeFromCharCode(charcode);
1802
1803                 FX_WORD unicode = 0;
1804                 if (swUnicode.GetLength() > 0)
1805                         unicode = swUnicode[0];
1806
1807                 if (ISLATINWORD(unicode) && bIsLatin)
1808                 {
1809                 }
1810                 else
1811                 {
1812                         bIsLatin = ISLATINWORD(unicode);
1813                         if (unicode != 0x20)
1814                                 nWords++;
1815                 }
1816
1817                 if (nWords-1 == nWordIndex)
1818                         swRet += unicode;
1819         }
1820
1821         return swRet;
1822 }
1823
1824 FX_BOOL Document::zoom(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1825 {
1826
1827         return TRUE;
1828 }
1829
1830 /**
1831 (none,  NoVary)
1832 (fitP,  FitPage)
1833 (fitW,  FitWidth)
1834 (fitH,  FitHeight)
1835 (fitV,  FitVisibleWidth)
1836 (pref,  Preferred)
1837 (refW,  ReflowWidth)
1838 */
1839
1840 FX_BOOL Document::zoomType(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError)
1841 {
1842         return TRUE;
1843 }
1844
1845 FX_BOOL Document::deletePages(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1846 {
1847         v8::Isolate* isolate = GetIsolate(cc);
1848         ASSERT(m_pDocument != NULL);
1849
1850         if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) ||
1851                 m_pDocument->GetPermissions(FPDFPERM_ASSEMBLE))) return FALSE;
1852
1853         int iSize = params.size();
1854
1855         int nStart = 0;
1856         int nEnd = 0;
1857
1858         if (iSize < 1)
1859         {
1860         }
1861         else if (iSize == 1)
1862         {
1863                 if (params[0].GetType() == VT_object)
1864                 {
1865                         JSObject pObj = params[0].ToV8Object();
1866                         v8::Handle<v8::Value> pValue = JS_GetObjectElement(isolate, pObj, L"nStart");
1867             nStart = CJS_Value(m_isolate, pValue, GET_VALUE_TYPE(pValue)).ToInt();
1868
1869                         pValue = JS_GetObjectElement(isolate, pObj, L"nEnd");
1870                         nEnd = CJS_Value(m_isolate, pValue, GET_VALUE_TYPE(pValue)).ToInt();
1871                 }
1872                 else
1873                 {
1874                         nStart = params[0].ToInt();
1875                 }
1876         }
1877         else
1878         {
1879                 nStart = params[0].ToInt();
1880                 nEnd = params[1].ToInt();
1881         }
1882
1883         int nTotal = m_pDocument->GetPageCount();
1884
1885         if (nStart < 0) nStart = 0;
1886         if (nStart >= nTotal) nStart = nTotal - 1;
1887
1888         if (nEnd < 0) nEnd = 0;
1889         if (nEnd >= nTotal) nEnd = nTotal - 1;
1890
1891         if (nEnd < nStart) nEnd = nStart;
1892
1893
1894
1895         return TRUE;
1896 }
1897
1898 FX_BOOL Document::extractPages(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1899 {
1900   // Unsafe, not supported.
1901   return TRUE;
1902 }
1903
1904 FX_BOOL Document::insertPages(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1905 {
1906   // Unsafe, not supported.
1907   return TRUE;
1908 }
1909
1910 FX_BOOL Document::replacePages(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1911 {
1912   // Unsafe, not supported.
1913   return TRUE;
1914 }
1915
1916 FX_BOOL Document::getURL(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1917 {
1918   // Unsafe, not supported.
1919   return TRUE;
1920 }
1921
1922 void Document::AddDelayData(CJS_DelayData* pData)
1923 {
1924         m_DelayData.Add(pData);
1925 }
1926
1927 void Document::DoFieldDelay(const CFX_WideString& sFieldName, int nControlIndex)
1928 {
1929         CFX_DWordArray DelArray;
1930
1931         for (int i=0,sz=m_DelayData.GetSize(); i<sz; i++)
1932         {
1933                 if (CJS_DelayData* pData = m_DelayData.GetAt(i))
1934                 {
1935                         if (pData->sFieldName == sFieldName && pData->nControlIndex == nControlIndex)
1936                         {
1937                                 Field::DoDelay(m_pDocument, pData);
1938                                 delete pData;
1939                                 m_DelayData.SetAt(i, NULL);
1940                                 DelArray.Add(i);
1941                         }
1942                 }
1943         }
1944
1945         for (int j=DelArray.GetSize()-1; j>=0; j--)
1946         {
1947                 m_DelayData.RemoveAt(DelArray[j]);
1948         }
1949 }
1950
1951 void Document::AddDelayAnnotData(CJS_AnnotObj *pData)
1952 {
1953         m_DelayAnnotData.Add(pData);
1954 }
1955
1956 void Document::DoAnnotDelay()
1957 {
1958         CFX_DWordArray DelArray;
1959
1960         for (int j=DelArray.GetSize()-1; j>=0; j--)
1961         {
1962                 m_DelayData.RemoveAt(DelArray[j]);
1963         }
1964 }
1965
1966 CJS_Document* Document::GetCJSDoc() const 
1967 {
1968         return static_cast<CJS_Document*>(m_pJSObject);
1969 }
1970