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