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