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