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