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