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