1 // Copyright 2017 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 "fxjs/xfa/cjx_hostpseudomodel.h"
8 
9 #include <memory>
10 #include <vector>
11 
12 #include "fxjs/js_resources.h"
13 #include "fxjs/xfa/cfxjse_engine.h"
14 #include "fxjs/xfa/cfxjse_value.h"
15 #include "xfa/fxfa/cxfa_ffdoc.h"
16 #include "xfa/fxfa/cxfa_ffnotify.h"
17 #include "xfa/fxfa/parser/cscript_hostpseudomodel.h"
18 #include "xfa/fxfa/parser/cxfa_node.h"
19 #include "xfa/fxfa/parser/xfa_resolvenode_rs.h"
20 
21 namespace {
22 
FilterName(WideStringView wsExpression,int32_t nStart,WideString & wsFilter)23 int32_t FilterName(WideStringView wsExpression,
24                    int32_t nStart,
25                    WideString& wsFilter) {
26   ASSERT(nStart > -1);
27   int32_t iLength = wsExpression.GetLength();
28   if (nStart >= iLength)
29     return iLength;
30 
31   int32_t nCount = 0;
32   {
33     // Span's lifetime must end before ReleaseBuffer() below.
34     pdfium::span<wchar_t> pBuf = wsFilter.GetBuffer(iLength - nStart);
35     const wchar_t* pSrc = wsExpression.unterminated_c_str();
36     while (nStart < iLength) {
37       wchar_t wCur = pSrc[nStart++];
38       if (wCur == ',')
39         break;
40 
41       pBuf[nCount++] = wCur;
42     }
43   }
44   wsFilter.ReleaseBuffer(nCount);
45   wsFilter.Trim();
46   return nStart;
47 }
48 
49 }  // namespace
50 
51 const CJX_MethodSpec CJX_HostPseudoModel::MethodSpecs[] = {
52     {"beep", beep_static},
53     {"documentCountInBatch", documentCountInBatch_static},
54     {"documentInBatch", documentInBatch_static},
55     {"exportData", exportData_static},
56     {"getFocus", getFocus_static},
57     {"gotoURL", gotoURL_static},
58     {"importData", importData_static},
59     {"messageBox", messageBox_static},
60     {"openList", openList_static},
61     {"pageDown", pageDown_static},
62     {"pageUp", pageUp_static},
63     {"print", print_static},
64     {"resetData", resetData_static},
65     {"response", response_static},
66     {"setFocus", setFocus_static}};
67 
CJX_HostPseudoModel(CScript_HostPseudoModel * model)68 CJX_HostPseudoModel::CJX_HostPseudoModel(CScript_HostPseudoModel* model)
69     : CJX_Object(model) {
70   DefineMethods(MethodSpecs);
71 }
72 
~CJX_HostPseudoModel()73 CJX_HostPseudoModel::~CJX_HostPseudoModel() {}
74 
DynamicTypeIs(TypeTag eType) const75 bool CJX_HostPseudoModel::DynamicTypeIs(TypeTag eType) const {
76   return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
77 }
78 
appType(CFXJSE_Value * pValue,bool bSetting,XFA_Attribute eAttribute)79 void CJX_HostPseudoModel::appType(CFXJSE_Value* pValue,
80                                   bool bSetting,
81                                   XFA_Attribute eAttribute) {
82   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
83   if (!pNotify)
84     return;
85 
86   if (bSetting) {
87     ThrowInvalidPropertyException();
88     return;
89   }
90   pValue->SetString("Exchange");
91 }
92 
calculationsEnabled(CFXJSE_Value * pValue,bool bSetting,XFA_Attribute eAttribute)93 void CJX_HostPseudoModel::calculationsEnabled(CFXJSE_Value* pValue,
94                                               bool bSetting,
95                                               XFA_Attribute eAttribute) {
96   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
97   if (!pNotify)
98     return;
99 
100   CXFA_FFDoc* hDoc = pNotify->GetHDOC();
101   if (bSetting) {
102     hDoc->GetDocEnvironment()->SetCalculationsEnabled(hDoc,
103                                                       pValue->ToBoolean());
104     return;
105   }
106   pValue->SetBoolean(hDoc->GetDocEnvironment()->IsCalculationsEnabled(hDoc));
107 }
108 
currentPage(CFXJSE_Value * pValue,bool bSetting,XFA_Attribute eAttribute)109 void CJX_HostPseudoModel::currentPage(CFXJSE_Value* pValue,
110                                       bool bSetting,
111                                       XFA_Attribute eAttribute) {
112   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
113   if (!pNotify)
114     return;
115 
116   CXFA_FFDoc* hDoc = pNotify->GetHDOC();
117   if (bSetting) {
118     hDoc->GetDocEnvironment()->SetCurrentPage(hDoc, pValue->ToInteger());
119     return;
120   }
121   pValue->SetInteger(hDoc->GetDocEnvironment()->GetCurrentPage(hDoc));
122 }
123 
language(CFXJSE_Value * pValue,bool bSetting,XFA_Attribute eAttribute)124 void CJX_HostPseudoModel::language(CFXJSE_Value* pValue,
125                                    bool bSetting,
126                                    XFA_Attribute eAttribute) {
127   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
128   if (!pNotify)
129     return;
130 
131   if (bSetting) {
132     ThrowException(WideString::FromASCII("Unable to set language value."));
133     return;
134   }
135   pValue->SetString(
136       pNotify->GetAppProvider()->GetLanguage().ToUTF8().AsStringView());
137 }
138 
numPages(CFXJSE_Value * pValue,bool bSetting,XFA_Attribute eAttribute)139 void CJX_HostPseudoModel::numPages(CFXJSE_Value* pValue,
140                                    bool bSetting,
141                                    XFA_Attribute eAttribute) {
142   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
143   if (!pNotify)
144     return;
145 
146   CXFA_FFDoc* hDoc = pNotify->GetHDOC();
147   if (bSetting) {
148     ThrowException(WideString::FromASCII("Unable to set numPages value."));
149     return;
150   }
151   pValue->SetInteger(hDoc->GetDocEnvironment()->CountPages(hDoc));
152 }
153 
platform(CFXJSE_Value * pValue,bool bSetting,XFA_Attribute eAttribute)154 void CJX_HostPseudoModel::platform(CFXJSE_Value* pValue,
155                                    bool bSetting,
156                                    XFA_Attribute eAttribute) {
157   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
158   if (!pNotify)
159     return;
160 
161   if (bSetting) {
162     ThrowException(WideString::FromASCII("Unable to set platform value."));
163     return;
164   }
165   pValue->SetString(
166       pNotify->GetAppProvider()->GetPlatform().ToUTF8().AsStringView());
167 }
168 
title(CFXJSE_Value * pValue,bool bSetting,XFA_Attribute eAttribute)169 void CJX_HostPseudoModel::title(CFXJSE_Value* pValue,
170                                 bool bSetting,
171                                 XFA_Attribute eAttribute) {
172   if (!GetDocument()->GetScriptContext()->IsRunAtClient())
173     return;
174 
175   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
176   if (!pNotify)
177     return;
178 
179   CXFA_FFDoc* hDoc = pNotify->GetHDOC();
180   if (bSetting) {
181     hDoc->GetDocEnvironment()->SetTitle(hDoc, pValue->ToWideString());
182     return;
183   }
184 
185   WideString wsTitle;
186   hDoc->GetDocEnvironment()->GetTitle(hDoc, wsTitle);
187   pValue->SetString(wsTitle.ToUTF8().AsStringView());
188 }
189 
validationsEnabled(CFXJSE_Value * pValue,bool bSetting,XFA_Attribute eAttribute)190 void CJX_HostPseudoModel::validationsEnabled(CFXJSE_Value* pValue,
191                                              bool bSetting,
192                                              XFA_Attribute eAttribute) {
193   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
194   if (!pNotify)
195     return;
196 
197   CXFA_FFDoc* hDoc = pNotify->GetHDOC();
198   if (bSetting) {
199     hDoc->GetDocEnvironment()->SetValidationsEnabled(hDoc, pValue->ToBoolean());
200     return;
201   }
202 
203   bool bEnabled = hDoc->GetDocEnvironment()->IsValidationsEnabled(hDoc);
204   pValue->SetBoolean(bEnabled);
205 }
206 
variation(CFXJSE_Value * pValue,bool bSetting,XFA_Attribute eAttribute)207 void CJX_HostPseudoModel::variation(CFXJSE_Value* pValue,
208                                     bool bSetting,
209                                     XFA_Attribute eAttribute) {
210   if (!GetDocument()->GetScriptContext()->IsRunAtClient())
211     return;
212 
213   if (bSetting) {
214     ThrowException(WideString::FromASCII("Unable to set variation value."));
215     return;
216   }
217   pValue->SetString("Full");
218 }
219 
version(CFXJSE_Value * pValue,bool bSetting,XFA_Attribute eAttribute)220 void CJX_HostPseudoModel::version(CFXJSE_Value* pValue,
221                                   bool bSetting,
222                                   XFA_Attribute eAttribute) {
223   if (bSetting) {
224     ThrowException(WideString::FromASCII("Unable to set version value."));
225     return;
226   }
227   pValue->SetString("11");
228 }
229 
name(CFXJSE_Value * pValue,bool bSetting,XFA_Attribute eAttribute)230 void CJX_HostPseudoModel::name(CFXJSE_Value* pValue,
231                                bool bSetting,
232                                XFA_Attribute eAttribute) {
233   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
234   if (!pNotify)
235     return;
236 
237   if (bSetting) {
238     ThrowInvalidPropertyException();
239     return;
240   }
241   pValue->SetString(
242       pNotify->GetAppProvider()->GetAppName().ToUTF8().AsStringView());
243 }
244 
gotoURL(CFX_V8 * runtime,const std::vector<v8::Local<v8::Value>> & params)245 CJS_Result CJX_HostPseudoModel::gotoURL(
246     CFX_V8* runtime,
247     const std::vector<v8::Local<v8::Value>>& params) {
248   if (!GetDocument()->GetScriptContext()->IsRunAtClient())
249     return CJS_Result::Success();
250 
251   if (params.size() != 1)
252     return CJS_Result::Failure(JSMessage::kParamError);
253 
254   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
255   if (!pNotify)
256     return CJS_Result::Success();
257 
258   CXFA_FFDoc* hDoc = pNotify->GetHDOC();
259   WideString URL = runtime->ToWideString(params[0]);
260   hDoc->GetDocEnvironment()->GotoURL(hDoc, URL);
261   return CJS_Result::Success();
262 }
263 
openList(CFX_V8 * runtime,const std::vector<v8::Local<v8::Value>> & params)264 CJS_Result CJX_HostPseudoModel::openList(
265     CFX_V8* runtime,
266     const std::vector<v8::Local<v8::Value>>& params) {
267   if (!GetDocument()->GetScriptContext()->IsRunAtClient())
268     return CJS_Result::Success();
269 
270   if (params.size() != 1)
271     return CJS_Result::Failure(JSMessage::kParamError);
272 
273   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
274   if (!pNotify)
275     return CJS_Result::Success();
276 
277   CXFA_Node* pNode = nullptr;
278   if (params[0]->IsObject()) {
279     pNode =
280         ToNode(static_cast<CFXJSE_Engine*>(runtime)->ToXFAObject(params[0]));
281   } else if (params[0]->IsString()) {
282     CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext();
283     CXFA_Object* pObject = pScriptContext->GetThisObject();
284     if (!pObject)
285       return CJS_Result::Success();
286 
287     uint32_t dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Parent |
288                       XFA_RESOLVENODE_Siblings;
289     XFA_RESOLVENODE_RS resolveNodeRS;
290     bool bRet = pScriptContext->ResolveObjects(
291         pObject, runtime->ToWideString(params[0]).AsStringView(),
292         &resolveNodeRS, dwFlag, nullptr);
293     if (!bRet || !resolveNodeRS.objects.front()->IsNode())
294       return CJS_Result::Success();
295 
296     pNode = resolveNodeRS.objects.front()->AsNode();
297   }
298 
299   if (pNode)
300     pNotify->OpenDropDownList(pNode);
301 
302   return CJS_Result::Success();
303 }
304 
response(CFX_V8 * runtime,const std::vector<v8::Local<v8::Value>> & params)305 CJS_Result CJX_HostPseudoModel::response(
306     CFX_V8* runtime,
307     const std::vector<v8::Local<v8::Value>>& params) {
308   if (params.empty() || params.size() > 4)
309     return CJS_Result::Failure(JSMessage::kParamError);
310 
311   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
312   if (!pNotify)
313     return CJS_Result::Success();
314 
315   WideString question;
316   if (params.size() >= 1)
317     question = runtime->ToWideString(params[0]);
318 
319   WideString title;
320   if (params.size() >= 2)
321     title = runtime->ToWideString(params[1]);
322 
323   WideString defaultAnswer;
324   if (params.size() >= 3)
325     defaultAnswer = runtime->ToWideString(params[2]);
326 
327   bool mark = false;
328   if (params.size() >= 4)
329     mark = runtime->ToInt32(params[3]) != 0;
330 
331   WideString answer =
332       pNotify->GetAppProvider()->Response(question, title, defaultAnswer, mark);
333   return CJS_Result::Success(
334       runtime->NewString(answer.ToUTF8().AsStringView()));
335 }
336 
documentInBatch(CFX_V8 * runtime,const std::vector<v8::Local<v8::Value>> & params)337 CJS_Result CJX_HostPseudoModel::documentInBatch(
338     CFX_V8* runtime,
339     const std::vector<v8::Local<v8::Value>>& params) {
340   return CJS_Result::Success(runtime->NewNumber(0));
341 }
342 
resetData(CFX_V8 * runtime,const std::vector<v8::Local<v8::Value>> & params)343 CJS_Result CJX_HostPseudoModel::resetData(
344     CFX_V8* runtime,
345     const std::vector<v8::Local<v8::Value>>& params) {
346   if (params.size() > 1)
347     return CJS_Result::Failure(JSMessage::kParamError);
348 
349   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
350   if (!pNotify)
351     return CJS_Result::Success();
352 
353   WideString expression;
354   if (params.size() >= 1)
355     expression = runtime->ToWideString(params[0]);
356 
357   if (expression.IsEmpty()) {
358     pNotify->ResetData(nullptr);
359     return CJS_Result::Success();
360   }
361 
362   int32_t iStart = 0;
363   WideString wsName;
364   CXFA_Node* pNode = nullptr;
365   int32_t iExpLength = expression.GetLength();
366   while (iStart < iExpLength) {
367     iStart = FilterName(expression.AsStringView(), iStart, wsName);
368     CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext();
369     CXFA_Object* pObject = pScriptContext->GetThisObject();
370     if (!pObject)
371       return CJS_Result::Success();
372 
373     uint32_t dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Parent |
374                       XFA_RESOLVENODE_Siblings;
375     XFA_RESOLVENODE_RS resolveNodeRS;
376     bool bRet = pScriptContext->ResolveObjects(pObject, wsName.AsStringView(),
377                                                &resolveNodeRS, dwFlag, nullptr);
378     if (!bRet || !resolveNodeRS.objects.front()->IsNode())
379       continue;
380 
381     pNode = resolveNodeRS.objects.front()->AsNode();
382     pNotify->ResetData(pNode->IsWidgetReady() ? pNode : nullptr);
383   }
384   if (!pNode)
385     pNotify->ResetData(nullptr);
386 
387   return CJS_Result::Success();
388 }
389 
beep(CFX_V8 * runtime,const std::vector<v8::Local<v8::Value>> & params)390 CJS_Result CJX_HostPseudoModel::beep(
391     CFX_V8* runtime,
392     const std::vector<v8::Local<v8::Value>>& params) {
393   if (!GetDocument()->GetScriptContext()->IsRunAtClient())
394     return CJS_Result::Success();
395 
396   if (params.size() > 1)
397     return CJS_Result::Failure(JSMessage::kParamError);
398 
399   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
400   if (!pNotify)
401     return CJS_Result::Success();
402 
403   uint32_t dwType = 4;
404   if (params.size() >= 1)
405     dwType = runtime->ToInt32(params[0]);
406 
407   pNotify->GetAppProvider()->Beep(dwType);
408   return CJS_Result::Success();
409 }
410 
setFocus(CFX_V8 * runtime,const std::vector<v8::Local<v8::Value>> & params)411 CJS_Result CJX_HostPseudoModel::setFocus(
412     CFX_V8* runtime,
413     const std::vector<v8::Local<v8::Value>>& params) {
414   if (!GetDocument()->GetScriptContext()->IsRunAtClient())
415     return CJS_Result::Success();
416 
417   if (params.size() != 1)
418     return CJS_Result::Failure(JSMessage::kParamError);
419 
420   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
421   if (!pNotify)
422     return CJS_Result::Success();
423 
424   CXFA_Node* pNode = nullptr;
425   if (params.size() >= 1) {
426     if (params[0]->IsObject()) {
427       pNode =
428           ToNode(static_cast<CFXJSE_Engine*>(runtime)->ToXFAObject(params[0]));
429     } else if (params[0]->IsString()) {
430       CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext();
431       CXFA_Object* pObject = pScriptContext->GetThisObject();
432       if (!pObject)
433         return CJS_Result::Success();
434 
435       uint32_t dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Parent |
436                         XFA_RESOLVENODE_Siblings;
437       XFA_RESOLVENODE_RS resolveNodeRS;
438       bool bRet = pScriptContext->ResolveObjects(
439           pObject, runtime->ToWideString(params[0]).AsStringView(),
440           &resolveNodeRS, dwFlag, nullptr);
441       if (!bRet || !resolveNodeRS.objects.front()->IsNode())
442         return CJS_Result::Success();
443 
444       pNode = resolveNodeRS.objects.front()->AsNode();
445     }
446   }
447   pNotify->SetFocusWidgetNode(pNode);
448   return CJS_Result::Success();
449 }
450 
getFocus(CFX_V8 * runtime,const std::vector<v8::Local<v8::Value>> & params)451 CJS_Result CJX_HostPseudoModel::getFocus(
452     CFX_V8* runtime,
453     const std::vector<v8::Local<v8::Value>>& params) {
454   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
455   if (!pNotify)
456     return CJS_Result::Success();
457 
458   CXFA_Node* pNode = pNotify->GetFocusWidgetNode();
459   if (!pNode)
460     return CJS_Result::Success();
461 
462   CFXJSE_Value* value =
463       GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(pNode);
464 
465   return CJS_Result::Success(
466       value->DirectGetValue().Get(runtime->GetIsolate()));
467 }
468 
messageBox(CFX_V8 * runtime,const std::vector<v8::Local<v8::Value>> & params)469 CJS_Result CJX_HostPseudoModel::messageBox(
470     CFX_V8* runtime,
471     const std::vector<v8::Local<v8::Value>>& params) {
472   if (!GetDocument()->GetScriptContext()->IsRunAtClient())
473     return CJS_Result::Success();
474 
475   if (params.empty() || params.size() > 4)
476     return CJS_Result::Failure(JSMessage::kParamError);
477 
478   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
479   if (!pNotify)
480     return CJS_Result::Success();
481 
482   WideString message;
483   if (params.size() >= 1)
484     message = runtime->ToWideString(params[0]);
485 
486   WideString title;
487   if (params.size() >= 2)
488     title = runtime->ToWideString(params[1]);
489 
490   uint32_t messageType = static_cast<uint32_t>(AlertIcon::kDefault);
491   if (params.size() >= 3) {
492     messageType = runtime->ToInt32(params[2]);
493     if (messageType > static_cast<uint32_t>(AlertIcon::kStatus))
494       messageType = static_cast<uint32_t>(AlertIcon::kDefault);
495   }
496 
497   uint32_t buttonType = static_cast<uint32_t>(AlertButton::kDefault);
498   if (params.size() >= 4) {
499     buttonType = runtime->ToInt32(params[3]);
500     if (buttonType > static_cast<uint32_t>(AlertButton::kYesNoCancel))
501       buttonType = static_cast<uint32_t>(AlertButton::kDefault);
502   }
503 
504   int32_t iValue = pNotify->GetAppProvider()->MsgBox(message, title,
505                                                      messageType, buttonType);
506   return CJS_Result::Success(runtime->NewNumber(iValue));
507 }
508 
documentCountInBatch(CFX_V8 * runtime,const std::vector<v8::Local<v8::Value>> & params)509 CJS_Result CJX_HostPseudoModel::documentCountInBatch(
510     CFX_V8* runtime,
511     const std::vector<v8::Local<v8::Value>>& params) {
512   return CJS_Result::Success(runtime->NewNumber(0));
513 }
514 
print(CFX_V8 * runtime,const std::vector<v8::Local<v8::Value>> & params)515 CJS_Result CJX_HostPseudoModel::print(
516     CFX_V8* runtime,
517     const std::vector<v8::Local<v8::Value>>& params) {
518   if (!GetDocument()->GetScriptContext()->IsRunAtClient())
519     return CJS_Result::Success();
520 
521   if (params.size() != 8)
522     return CJS_Result::Failure(JSMessage::kParamError);
523 
524   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
525   if (!pNotify)
526     return CJS_Result::Success();
527 
528   uint32_t dwOptions = 0;
529   if (runtime->ToBoolean(params[0]))
530     dwOptions |= XFA_PRINTOPT_ShowDialog;
531   if (runtime->ToBoolean(params[3]))
532     dwOptions |= XFA_PRINTOPT_CanCancel;
533   if (runtime->ToBoolean(params[4]))
534     dwOptions |= XFA_PRINTOPT_ShrinkPage;
535   if (runtime->ToBoolean(params[5]))
536     dwOptions |= XFA_PRINTOPT_AsImage;
537   if (runtime->ToBoolean(params[6]))
538     dwOptions |= XFA_PRINTOPT_ReverseOrder;
539   if (runtime->ToBoolean(params[7]))
540     dwOptions |= XFA_PRINTOPT_PrintAnnot;
541 
542   int32_t nStartPage = runtime->ToInt32(params[1]);
543   int32_t nEndPage = runtime->ToInt32(params[2]);
544 
545   CXFA_FFDoc* hDoc = pNotify->GetHDOC();
546   hDoc->GetDocEnvironment()->Print(hDoc, nStartPage, nEndPage, dwOptions);
547   return CJS_Result::Success();
548 }
549 
importData(CFX_V8 * runtime,const std::vector<v8::Local<v8::Value>> & params)550 CJS_Result CJX_HostPseudoModel::importData(
551     CFX_V8* runtime,
552     const std::vector<v8::Local<v8::Value>>& params) {
553   if (params.empty() || params.size() > 1)
554     return CJS_Result::Failure(JSMessage::kParamError);
555 
556   return CJS_Result::Success();
557 }
558 
exportData(CFX_V8 * runtime,const std::vector<v8::Local<v8::Value>> & params)559 CJS_Result CJX_HostPseudoModel::exportData(
560     CFX_V8* runtime,
561     const std::vector<v8::Local<v8::Value>>& params) {
562   if (params.empty() || params.size() > 2)
563     return CJS_Result::Failure(JSMessage::kParamError);
564 
565   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
566   if (!pNotify)
567     return CJS_Result::Success();
568 
569   WideString filePath;
570   if (params.size() >= 1)
571     filePath = runtime->ToWideString(params[0]);
572 
573   bool XDP = true;
574   if (params.size() >= 2)
575     XDP = runtime->ToBoolean(params[1]);
576 
577   CXFA_FFDoc* hDoc = pNotify->GetHDOC();
578   hDoc->GetDocEnvironment()->ExportData(hDoc, filePath, XDP);
579   return CJS_Result::Success();
580 }
581 
pageUp(CFX_V8 * runtime,const std::vector<v8::Local<v8::Value>> & params)582 CJS_Result CJX_HostPseudoModel::pageUp(
583     CFX_V8* runtime,
584     const std::vector<v8::Local<v8::Value>>& params) {
585   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
586   if (!pNotify)
587     return CJS_Result::Success();
588 
589   CXFA_FFDoc* hDoc = pNotify->GetHDOC();
590   int32_t nCurPage = hDoc->GetDocEnvironment()->GetCurrentPage(hDoc);
591   int32_t nNewPage = 0;
592   if (nCurPage <= 1)
593     return CJS_Result::Success();
594 
595   nNewPage = nCurPage - 1;
596   hDoc->GetDocEnvironment()->SetCurrentPage(hDoc, nNewPage);
597   return CJS_Result::Success();
598 }
599 
pageDown(CFX_V8 * runtime,const std::vector<v8::Local<v8::Value>> & params)600 CJS_Result CJX_HostPseudoModel::pageDown(
601     CFX_V8* runtime,
602     const std::vector<v8::Local<v8::Value>>& params) {
603   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
604   if (!pNotify)
605     return CJS_Result::Success();
606 
607   CXFA_FFDoc* hDoc = pNotify->GetHDOC();
608   int32_t nCurPage = hDoc->GetDocEnvironment()->GetCurrentPage(hDoc);
609   int32_t nPageCount = hDoc->GetDocEnvironment()->CountPages(hDoc);
610   if (!nPageCount || nCurPage == nPageCount)
611     return CJS_Result::Success();
612 
613   int32_t nNewPage = 0;
614   if (nCurPage >= nPageCount)
615     nNewPage = nPageCount - 1;
616   else
617     nNewPage = nCurPage + 1;
618 
619   hDoc->GetDocEnvironment()->SetCurrentPage(hDoc, nNewPage);
620   return CJS_Result::Success();
621 }
622