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