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