1 // Copyright 2014 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/cjs_field.h"
8
9 #include <algorithm>
10 #include <memory>
11 #include <utility>
12
13 #include "constants/access_permissions.h"
14 #include "constants/annotation_flags.h"
15 #include "constants/form_flags.h"
16 #include "core/fpdfapi/parser/cpdf_stream.h"
17 #include "core/fpdfdoc/cpdf_formcontrol.h"
18 #include "core/fpdfdoc/cpdf_formfield.h"
19 #include "core/fpdfdoc/cpdf_interactiveform.h"
20 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
21 #include "fpdfsdk/cpdfsdk_interactiveform.h"
22 #include "fpdfsdk/cpdfsdk_pageview.h"
23 #include "fpdfsdk/cpdfsdk_widget.h"
24 #include "fxjs/cjs_color.h"
25 #include "fxjs/cjs_delaydata.h"
26 #include "fxjs/cjs_document.h"
27 #include "fxjs/cjs_icon.h"
28 #include "fxjs/fxv8.h"
29 #include "fxjs/js_resources.h"
30 #include "third_party/abseil-cpp/absl/types/optional.h"
31 #include "third_party/base/check.h"
32 #include "third_party/base/notreached.h"
33 #include "v8/include/v8-container.h"
34
35 namespace {
36
37 constexpr wchar_t kCheckSelector = L'4';
38 constexpr wchar_t kCircleSelector = L'l';
39 constexpr wchar_t kCrossSelector = L'8';
40 constexpr wchar_t kDiamondSelector = L'u';
41 constexpr wchar_t kSquareSelector = L'n';
42 constexpr wchar_t kStarSelector = L'H';
43
IsCheckBoxOrRadioButton(const CPDF_FormField * pFormField)44 bool IsCheckBoxOrRadioButton(const CPDF_FormField* pFormField) {
45 return pFormField->GetFieldType() == FormFieldType::kCheckBox ||
46 pFormField->GetFieldType() == FormFieldType::kRadioButton;
47 }
48
IsComboBoxOrListBox(const CPDF_FormField * pFormField)49 bool IsComboBoxOrListBox(const CPDF_FormField* pFormField) {
50 return pFormField->GetFieldType() == FormFieldType::kComboBox ||
51 pFormField->GetFieldType() == FormFieldType::kListBox;
52 }
53
IsComboBoxOrTextField(const CPDF_FormField * pFormField)54 bool IsComboBoxOrTextField(const CPDF_FormField* pFormField) {
55 return pFormField->GetFieldType() == FormFieldType::kComboBox ||
56 pFormField->GetFieldType() == FormFieldType::kTextField;
57 }
58
UpdateFormField(CPDFSDK_FormFillEnvironment * pFormFillEnv,CPDF_FormField * pFormField,bool bResetAP)59 void UpdateFormField(CPDFSDK_FormFillEnvironment* pFormFillEnv,
60 CPDF_FormField* pFormField,
61 bool bResetAP) {
62 CPDFSDK_InteractiveForm* pForm = pFormFillEnv->GetInteractiveForm();
63 if (bResetAP) {
64 std::vector<ObservedPtr<CPDFSDK_Widget>> widgets;
65 pForm->GetWidgets(pFormField, &widgets);
66
67 if (IsComboBoxOrTextField(pFormField)) {
68 for (auto& pWidget : widgets) {
69 if (pWidget) {
70 absl::optional<WideString> sValue = pWidget->OnFormat();
71 if (pWidget) { // Not redundant, may be clobbered by OnFormat.
72 pWidget->ResetAppearance(sValue, CPDFSDK_Widget::kValueUnchanged);
73 }
74 }
75 }
76 } else {
77 for (auto& pWidget : widgets) {
78 if (pWidget) {
79 pWidget->ResetAppearance(absl::nullopt,
80 CPDFSDK_Widget::kValueUnchanged);
81 }
82 }
83 }
84 }
85
86 // Refresh the widget list. The calls in |bResetAP| may have caused widgets
87 // to be removed from the list. We need to call |GetWidgets| again to be
88 // sure none of the widgets have been deleted.
89 std::vector<ObservedPtr<CPDFSDK_Widget>> widgets;
90 pForm->GetWidgets(pFormField, &widgets);
91 for (auto& pWidget : widgets) {
92 if (pWidget)
93 pFormFillEnv->UpdateAllViews(pWidget.Get());
94 }
95 pFormFillEnv->SetChangeMark();
96 }
97
UpdateFormControl(CPDFSDK_FormFillEnvironment * pFormFillEnv,CPDF_FormControl * pFormControl,bool bResetAP)98 void UpdateFormControl(CPDFSDK_FormFillEnvironment* pFormFillEnv,
99 CPDF_FormControl* pFormControl,
100 bool bResetAP) {
101 DCHECK(pFormControl);
102 CPDFSDK_InteractiveForm* pForm = pFormFillEnv->GetInteractiveForm();
103 CPDFSDK_Widget* pWidget = pForm->GetWidget(pFormControl);
104 if (pWidget) {
105 ObservedPtr<CPDFSDK_Widget> observed_widget(pWidget);
106 if (bResetAP) {
107 FormFieldType fieldType = pWidget->GetFieldType();
108 if (fieldType == FormFieldType::kComboBox ||
109 fieldType == FormFieldType::kTextField) {
110 absl::optional<WideString> sValue = pWidget->OnFormat();
111 if (!observed_widget)
112 return;
113 pWidget->ResetAppearance(sValue, CPDFSDK_Widget::kValueUnchanged);
114 } else {
115 pWidget->ResetAppearance(absl::nullopt,
116 CPDFSDK_Widget::kValueUnchanged);
117 }
118 if (!observed_widget)
119 return;
120 }
121 pFormFillEnv->UpdateAllViews(pWidget);
122 }
123 pFormFillEnv->SetChangeMark();
124 }
125
126 struct FieldNameData {
FieldNameData__anonb7fd2a390111::FieldNameData127 FieldNameData(WideString field_name_in, int control_index_in)
128 : field_name(field_name_in), control_index(control_index_in) {}
129
130 WideString field_name;
131 int control_index;
132 };
133
ParseFieldName(const WideString & field_name)134 absl::optional<FieldNameData> ParseFieldName(const WideString& field_name) {
135 auto reverse_it = field_name.rbegin();
136 while (reverse_it != field_name.rend()) {
137 if (*reverse_it == L'.')
138 break;
139 ++reverse_it;
140 }
141 if (reverse_it == field_name.rend()) {
142 return absl::nullopt;
143 }
144 WideString suffixal = field_name.Last(reverse_it - field_name.rbegin());
145 int control_index = FXSYS_wtoi(suffixal.c_str());
146 if (control_index == 0) {
147 suffixal.TrimRight(L' ');
148 if (suffixal != L"0") {
149 return absl::nullopt;
150 }
151 }
152 return FieldNameData(field_name.First(field_name.rend() - reverse_it - 1),
153 control_index);
154 }
155
GetFormFieldsForName(CPDFSDK_FormFillEnvironment * pFormFillEnv,const WideString & csFieldName)156 std::vector<CPDF_FormField*> GetFormFieldsForName(
157 CPDFSDK_FormFillEnvironment* pFormFillEnv,
158 const WideString& csFieldName) {
159 std::vector<CPDF_FormField*> fields;
160 CPDFSDK_InteractiveForm* pReaderForm = pFormFillEnv->GetInteractiveForm();
161 CPDF_InteractiveForm* pForm = pReaderForm->GetInteractiveForm();
162 const size_t sz = pForm->CountFields(csFieldName);
163 for (size_t i = 0; i < sz; ++i) {
164 CPDF_FormField* pFormField = pForm->GetField(i, csFieldName);
165 if (pFormField)
166 fields.push_back(pFormField);
167 }
168 return fields;
169 }
170
GetFormControlColor(CPDF_FormControl * pFormControl,const ByteString & entry)171 CFX_Color GetFormControlColor(CPDF_FormControl* pFormControl,
172 const ByteString& entry) {
173 switch (pFormControl->GetColorARGB(entry).color_type) {
174 case CFX_Color::Type::kTransparent:
175 return CFX_Color(CFX_Color::Type::kTransparent);
176 case CFX_Color::Type::kGray:
177 return CFX_Color(CFX_Color::Type::kGray,
178 pFormControl->GetOriginalColorComponent(0, entry));
179 case CFX_Color::Type::kRGB:
180 return CFX_Color(CFX_Color::Type::kRGB,
181 pFormControl->GetOriginalColorComponent(0, entry),
182 pFormControl->GetOriginalColorComponent(1, entry),
183 pFormControl->GetOriginalColorComponent(2, entry));
184 case CFX_Color::Type::kCMYK:
185 return CFX_Color(CFX_Color::Type::kCMYK,
186 pFormControl->GetOriginalColorComponent(0, entry),
187 pFormControl->GetOriginalColorComponent(1, entry),
188 pFormControl->GetOriginalColorComponent(2, entry),
189 pFormControl->GetOriginalColorComponent(3, entry));
190 }
191 }
192
SetWidgetDisplayStatus(CPDFSDK_Widget * pWidget,int value)193 bool SetWidgetDisplayStatus(CPDFSDK_Widget* pWidget, int value) {
194 if (!pWidget)
195 return false;
196
197 uint32_t dwFlag = pWidget->GetFlags();
198 switch (value) {
199 case 0:
200 dwFlag &= ~pdfium::annotation_flags::kInvisible;
201 dwFlag &= ~pdfium::annotation_flags::kHidden;
202 dwFlag &= ~pdfium::annotation_flags::kNoView;
203 dwFlag |= pdfium::annotation_flags::kPrint;
204 break;
205 case 1:
206 dwFlag &= ~pdfium::annotation_flags::kInvisible;
207 dwFlag &= ~pdfium::annotation_flags::kNoView;
208 dwFlag |= (pdfium::annotation_flags::kHidden |
209 pdfium::annotation_flags::kPrint);
210 break;
211 case 2:
212 dwFlag &= ~pdfium::annotation_flags::kInvisible;
213 dwFlag &= ~pdfium::annotation_flags::kPrint;
214 dwFlag &= ~pdfium::annotation_flags::kHidden;
215 dwFlag &= ~pdfium::annotation_flags::kNoView;
216 break;
217 case 3:
218 dwFlag |= pdfium::annotation_flags::kNoView;
219 dwFlag |= pdfium::annotation_flags::kPrint;
220 dwFlag &= ~pdfium::annotation_flags::kHidden;
221 break;
222 }
223
224 if (dwFlag != pWidget->GetFlags()) {
225 pWidget->SetFlags(dwFlag);
226 return true;
227 }
228
229 return false;
230 }
231
SetBorderStyle(CPDFSDK_FormFillEnvironment * pFormFillEnv,const WideString & swFieldName,int nControlIndex,const ByteString & bsString)232 void SetBorderStyle(CPDFSDK_FormFillEnvironment* pFormFillEnv,
233 const WideString& swFieldName,
234 int nControlIndex,
235 const ByteString& bsString) {
236 DCHECK(pFormFillEnv);
237
238 BorderStyle nBorderStyle;
239 if (bsString == "solid")
240 nBorderStyle = BorderStyle::kSolid;
241 else if (bsString == "beveled")
242 nBorderStyle = BorderStyle::kBeveled;
243 else if (bsString == "dashed")
244 nBorderStyle = BorderStyle::kDash;
245 else if (bsString == "inset")
246 nBorderStyle = BorderStyle::kInset;
247 else if (bsString == "underline")
248 nBorderStyle = BorderStyle::kUnderline;
249 else
250 return;
251
252 std::vector<CPDF_FormField*> FieldArray =
253 GetFormFieldsForName(pFormFillEnv, swFieldName);
254 auto* pForm = pFormFillEnv->GetInteractiveForm();
255 for (CPDF_FormField* pFormField : FieldArray) {
256 if (nControlIndex < 0) {
257 bool bSet = false;
258 for (int i = 0, sz = pFormField->CountControls(); i < sz; ++i) {
259 CPDFSDK_Widget* pWidget = pForm->GetWidget(pFormField->GetControl(i));
260 if (pWidget) {
261 if (pWidget->GetBorderStyle() != nBorderStyle) {
262 pWidget->SetBorderStyle(nBorderStyle);
263 bSet = true;
264 }
265 }
266 }
267 if (bSet)
268 UpdateFormField(pFormFillEnv, pFormField, true);
269 } else {
270 if (nControlIndex >= pFormField->CountControls())
271 return;
272 if (CPDF_FormControl* pFormControl =
273 pFormField->GetControl(nControlIndex)) {
274 CPDFSDK_Widget* pWidget = pForm->GetWidget(pFormControl);
275 if (pWidget) {
276 if (pWidget->GetBorderStyle() != nBorderStyle) {
277 pWidget->SetBorderStyle(nBorderStyle);
278 UpdateFormControl(pFormFillEnv, pFormControl, true);
279 }
280 }
281 }
282 }
283 }
284 }
285
SetCurrentValueIndices(CPDFSDK_FormFillEnvironment * pFormFillEnv,const WideString & swFieldName,int nControlIndex,const std::vector<uint32_t> & array)286 void SetCurrentValueIndices(CPDFSDK_FormFillEnvironment* pFormFillEnv,
287 const WideString& swFieldName,
288 int nControlIndex,
289 const std::vector<uint32_t>& array) {
290 DCHECK(pFormFillEnv);
291 std::vector<CPDF_FormField*> FieldArray =
292 GetFormFieldsForName(pFormFillEnv, swFieldName);
293
294 for (CPDF_FormField* pFormField : FieldArray) {
295 if (!IsComboBoxOrListBox(pFormField))
296 continue;
297
298 uint32_t dwFieldFlags = pFormField->GetFieldFlags();
299 pFormField->ClearSelection(NotificationOption::kNotify);
300 for (size_t i = 0; i < array.size(); ++i) {
301 if (i != 0 && !(dwFieldFlags & pdfium::form_flags::kChoiceMultiSelect))
302 break;
303 if (array[i] < static_cast<uint32_t>(pFormField->CountOptions()) &&
304 !pFormField->IsItemSelected(array[i])) {
305 pFormField->SetItemSelection(array[i],
306 NotificationOption::kDoNotNotify);
307 }
308 }
309 UpdateFormField(pFormFillEnv, pFormField, true);
310 }
311 }
312
SetDisplay(CPDFSDK_FormFillEnvironment * pFormFillEnv,const WideString & swFieldName,int nControlIndex,int number)313 void SetDisplay(CPDFSDK_FormFillEnvironment* pFormFillEnv,
314 const WideString& swFieldName,
315 int nControlIndex,
316 int number) {
317 CPDFSDK_InteractiveForm* pForm = pFormFillEnv->GetInteractiveForm();
318 std::vector<CPDF_FormField*> FieldArray =
319 GetFormFieldsForName(pFormFillEnv, swFieldName);
320 for (CPDF_FormField* pFormField : FieldArray) {
321 if (nControlIndex < 0) {
322 bool bAnySet = false;
323 for (int i = 0, sz = pFormField->CountControls(); i < sz; ++i) {
324 CPDF_FormControl* pFormControl = pFormField->GetControl(i);
325 DCHECK(pFormControl);
326
327 CPDFSDK_Widget* pWidget = pForm->GetWidget(pFormControl);
328 if (SetWidgetDisplayStatus(pWidget, number))
329 bAnySet = true;
330 }
331
332 if (bAnySet)
333 UpdateFormField(pFormFillEnv, pFormField, false);
334 } else {
335 if (nControlIndex >= pFormField->CountControls())
336 return;
337
338 CPDF_FormControl* pFormControl = pFormField->GetControl(nControlIndex);
339 if (!pFormControl)
340 return;
341
342 CPDFSDK_Widget* pWidget = pForm->GetWidget(pFormControl);
343 if (SetWidgetDisplayStatus(pWidget, number))
344 UpdateFormControl(pFormFillEnv, pFormControl, false);
345 }
346 }
347 }
348
SetHidden(CPDFSDK_FormFillEnvironment * pFormFillEnv,const WideString & swFieldName,int nControlIndex,bool b)349 void SetHidden(CPDFSDK_FormFillEnvironment* pFormFillEnv,
350 const WideString& swFieldName,
351 int nControlIndex,
352 bool b) {
353 int display = b ? 1 /*Hidden*/ : 0 /*Visible*/;
354 SetDisplay(pFormFillEnv, swFieldName, nControlIndex, display);
355 }
356
SetLineWidth(CPDFSDK_FormFillEnvironment * pFormFillEnv,const WideString & swFieldName,int nControlIndex,int number)357 void SetLineWidth(CPDFSDK_FormFillEnvironment* pFormFillEnv,
358 const WideString& swFieldName,
359 int nControlIndex,
360 int number) {
361 CPDFSDK_InteractiveForm* pForm = pFormFillEnv->GetInteractiveForm();
362 std::vector<CPDF_FormField*> FieldArray =
363 GetFormFieldsForName(pFormFillEnv, swFieldName);
364 for (CPDF_FormField* pFormField : FieldArray) {
365 if (nControlIndex < 0) {
366 bool bSet = false;
367 for (int i = 0, sz = pFormField->CountControls(); i < sz; ++i) {
368 CPDF_FormControl* pFormControl = pFormField->GetControl(i);
369 DCHECK(pFormControl);
370
371 if (CPDFSDK_Widget* pWidget = pForm->GetWidget(pFormControl)) {
372 if (number != pWidget->GetBorderWidth()) {
373 pWidget->SetBorderWidth(number);
374 bSet = true;
375 }
376 }
377 }
378 if (bSet)
379 UpdateFormField(pFormFillEnv, pFormField, true);
380 } else {
381 if (nControlIndex >= pFormField->CountControls())
382 return;
383 if (CPDF_FormControl* pFormControl =
384 pFormField->GetControl(nControlIndex)) {
385 if (CPDFSDK_Widget* pWidget = pForm->GetWidget(pFormControl)) {
386 if (number != pWidget->GetBorderWidth()) {
387 pWidget->SetBorderWidth(number);
388 UpdateFormControl(pFormFillEnv, pFormControl, true);
389 }
390 }
391 }
392 }
393 }
394 }
395
SetRect(CPDFSDK_FormFillEnvironment * pFormFillEnv,const WideString & swFieldName,int nControlIndex,const CFX_FloatRect & rect)396 void SetRect(CPDFSDK_FormFillEnvironment* pFormFillEnv,
397 const WideString& swFieldName,
398 int nControlIndex,
399 const CFX_FloatRect& rect) {
400 CPDFSDK_InteractiveForm* pForm = pFormFillEnv->GetInteractiveForm();
401 std::vector<CPDF_FormField*> FieldArray =
402 GetFormFieldsForName(pFormFillEnv, swFieldName);
403 for (CPDF_FormField* pFormField : FieldArray) {
404 if (nControlIndex < 0) {
405 bool bSet = false;
406 for (int i = 0, sz = pFormField->CountControls(); i < sz; ++i) {
407 CPDF_FormControl* pFormControl = pFormField->GetControl(i);
408 DCHECK(pFormControl);
409
410 if (CPDFSDK_Widget* pWidget = pForm->GetWidget(pFormControl)) {
411 CFX_FloatRect crRect = rect;
412
413 CPDF_Page* pPDFPage = pWidget->GetPDFPage();
414 crRect.Intersect(pPDFPage->GetBBox());
415
416 if (!crRect.IsEmpty()) {
417 CFX_FloatRect rcOld = pWidget->GetRect();
418 if (crRect.left != rcOld.left || crRect.right != rcOld.right ||
419 crRect.top != rcOld.top || crRect.bottom != rcOld.bottom) {
420 pWidget->SetRect(crRect);
421 bSet = true;
422 }
423 }
424 }
425 }
426
427 if (bSet)
428 UpdateFormField(pFormFillEnv, pFormField, true);
429
430 continue;
431 }
432
433 if (nControlIndex >= pFormField->CountControls())
434 return;
435 if (CPDF_FormControl* pFormControl =
436 pFormField->GetControl(nControlIndex)) {
437 if (CPDFSDK_Widget* pWidget = pForm->GetWidget(pFormControl)) {
438 CFX_FloatRect crRect = rect;
439 CPDF_Page* pPDFPage = pWidget->GetPDFPage();
440 crRect.Intersect(pPDFPage->GetBBox());
441 if (!crRect.IsEmpty()) {
442 CFX_FloatRect rcOld = pWidget->GetRect();
443 if (crRect.left != rcOld.left || crRect.right != rcOld.right ||
444 crRect.top != rcOld.top || crRect.bottom != rcOld.bottom) {
445 pWidget->SetRect(crRect);
446 UpdateFormControl(pFormFillEnv, pFormControl, true);
447 }
448 }
449 }
450 }
451 }
452 }
453
SetFieldValue(CPDFSDK_FormFillEnvironment * pFormFillEnv,const WideString & swFieldName,int nControlIndex,const std::vector<WideString> & strArray)454 void SetFieldValue(CPDFSDK_FormFillEnvironment* pFormFillEnv,
455 const WideString& swFieldName,
456 int nControlIndex,
457 const std::vector<WideString>& strArray) {
458 DCHECK(pFormFillEnv);
459 if (strArray.empty())
460 return;
461
462 std::vector<CPDF_FormField*> FieldArray =
463 GetFormFieldsForName(pFormFillEnv, swFieldName);
464
465 for (CPDF_FormField* pFormField : FieldArray) {
466 if (pFormField->GetFullName() != swFieldName)
467 continue;
468
469 switch (pFormField->GetFieldType()) {
470 case FormFieldType::kTextField:
471 case FormFieldType::kComboBox:
472 if (pFormField->GetValue() != strArray[0]) {
473 pFormField->SetValue(strArray[0], NotificationOption::kNotify);
474 UpdateFormField(pFormFillEnv, pFormField, false);
475 }
476 break;
477 case FormFieldType::kCheckBox:
478 case FormFieldType::kRadioButton:
479 if (pFormField->GetValue() != strArray[0]) {
480 pFormField->SetValue(strArray[0], NotificationOption::kNotify);
481 UpdateFormField(pFormFillEnv, pFormField, false);
482 }
483 break;
484 case FormFieldType::kListBox: {
485 bool bModified = false;
486 for (const auto& str : strArray) {
487 if (!pFormField->IsItemSelected(pFormField->FindOption(str))) {
488 bModified = true;
489 break;
490 }
491 }
492 if (bModified) {
493 pFormField->ClearSelection(NotificationOption::kNotify);
494 for (const auto& str : strArray) {
495 int index = pFormField->FindOption(str);
496 if (!pFormField->IsItemSelected(index))
497 pFormField->SetItemSelection(index, NotificationOption::kNotify);
498 }
499 UpdateFormField(pFormFillEnv, pFormField, false);
500 }
501 break;
502 }
503 default:
504 break;
505 }
506 }
507 }
508
GetSelectorFromCaptionForFieldType(const WideString & caption,CPDF_FormField::Type type)509 wchar_t GetSelectorFromCaptionForFieldType(const WideString& caption,
510 CPDF_FormField::Type type) {
511 if (!caption.IsEmpty())
512 return caption[0];
513
514 switch (type) {
515 case CPDF_FormField::kRadioButton:
516 return kCircleSelector;
517 default:
518 return kCheckSelector;
519 }
520 }
521
522 } // namespace
523
524 const JSPropertySpec CJS_Field::PropertySpecs[] = {
525 {"alignment", get_alignment_static, set_alignment_static},
526 {"borderStyle", get_border_style_static, set_border_style_static},
527 {"buttonAlignX", get_button_align_x_static, set_button_align_x_static},
528 {"buttonAlignY", get_button_align_y_static, set_button_align_y_static},
529 {"buttonFitBounds", get_button_fit_bounds_static,
530 set_button_fit_bounds_static},
531 {"buttonPosition", get_button_position_static, set_button_position_static},
532 {"buttonScaleHow", get_button_scale_how_static,
533 set_button_scale_how_static},
534 {"buttonScaleWhen", get_button_scale_when_static,
535 set_button_scale_when_static},
536 {"calcOrderIndex", get_calc_order_index_static,
537 set_calc_order_index_static},
538 {"charLimit", get_char_limit_static, set_char_limit_static},
539 {"comb", get_comb_static, set_comb_static},
540 {"commitOnSelChange", get_commit_on_sel_change_static,
541 set_commit_on_sel_change_static},
542 {"currentValueIndices", get_current_value_indices_static,
543 set_current_value_indices_static},
544 {"defaultStyle", get_default_style_static, set_default_style_static},
545 {"defaultValue", get_default_value_static, set_default_value_static},
546 {"doNotScroll", get_do_not_scroll_static, set_do_not_scroll_static},
547 {"doNotSpellCheck", get_do_not_spell_check_static,
548 set_do_not_spell_check_static},
549 {"delay", get_delay_static, set_delay_static},
550 {"display", get_display_static, set_display_static},
551 {"doc", get_doc_static, set_doc_static},
552 {"editable", get_editable_static, set_editable_static},
553 {"exportValues", get_export_values_static, set_export_values_static},
554 {"hidden", get_hidden_static, set_hidden_static},
555 {"fileSelect", get_file_select_static, set_file_select_static},
556 {"fillColor", get_fill_color_static, set_fill_color_static},
557 {"lineWidth", get_line_width_static, set_line_width_static},
558 {"highlight", get_highlight_static, set_highlight_static},
559 {"multiline", get_multiline_static, set_multiline_static},
560 {"multipleSelection", get_multiple_selection_static,
561 set_multiple_selection_static},
562 {"name", get_name_static, set_name_static},
563 {"numItems", get_num_items_static, set_num_items_static},
564 {"page", get_page_static, set_page_static},
565 {"password", get_password_static, set_password_static},
566 {"print", get_print_static, set_print_static},
567 {"radiosInUnison", get_radios_in_unison_static,
568 set_radios_in_unison_static},
569 {"readonly", get_readonly_static, set_readonly_static},
570 {"rect", get_rect_static, set_rect_static},
571 {"required", get_required_static, set_required_static},
572 {"richText", get_rich_text_static, set_rich_text_static},
573 {"richValue", get_rich_value_static, set_rich_value_static},
574 {"rotation", get_rotation_static, set_rotation_static},
575 {"source", get_source_static, set_source_static},
576 {"strokeColor", get_stroke_color_static, set_stroke_color_static},
577 {"style", get_style_static, set_style_static},
578 {"submitName", get_submit_name_static, set_submit_name_static},
579 {"textColor", get_text_color_static, set_text_color_static},
580 {"textFont", get_text_font_static, set_text_font_static},
581 {"textSize", get_text_size_static, set_text_size_static},
582 {"type", get_type_static, set_type_static},
583 {"userName", get_user_name_static, set_user_name_static},
584 {"value", get_value_static, set_value_static},
585 {"valueAsString", get_value_as_string_static, set_value_as_string_static}};
586
587 const JSMethodSpec CJS_Field::MethodSpecs[] = {
588 {"browseForFileToSubmit", browseForFileToSubmit_static},
589 {"buttonGetCaption", buttonGetCaption_static},
590 {"buttonGetIcon", buttonGetIcon_static},
591 {"buttonImportIcon", buttonImportIcon_static},
592 {"buttonSetCaption", buttonSetCaption_static},
593 {"buttonSetIcon", buttonSetIcon_static},
594 {"checkThisBox", checkThisBox_static},
595 {"clearItems", clearItems_static},
596 {"defaultIsChecked", defaultIsChecked_static},
597 {"deleteItemAt", deleteItemAt_static},
598 {"getArray", getArray_static},
599 {"getItemAt", getItemAt_static},
600 {"getLock", getLock_static},
601 {"insertItemAt", insertItemAt_static},
602 {"isBoxChecked", isBoxChecked_static},
603 {"isDefaultChecked", isDefaultChecked_static},
604 {"setAction", setAction_static},
605 {"setFocus", setFocus_static},
606 {"setItems", setItems_static},
607 {"setLock", setLock_static},
608 {"signatureGetModifications", signatureGetModifications_static},
609 {"signatureGetSeedValue", signatureGetSeedValue_static},
610 {"signatureInfo", signatureInfo_static},
611 {"signatureSetSeedValue", signatureSetSeedValue_static},
612 {"signatureSign", signatureSign_static},
613 {"signatureValidate", signatureValidate_static}};
614
615 uint32_t CJS_Field::ObjDefnID = 0;
616 const char CJS_Field::kName[] = "Field";
617
618 // static
GetObjDefnID()619 uint32_t CJS_Field::GetObjDefnID() {
620 return ObjDefnID;
621 }
622
623 // static
DefineJSObjects(CFXJS_Engine * pEngine)624 void CJS_Field::DefineJSObjects(CFXJS_Engine* pEngine) {
625 ObjDefnID = pEngine->DefineObj(CJS_Field::kName, FXJSOBJTYPE_DYNAMIC,
626 JSConstructor<CJS_Field>, JSDestructor);
627 DefineProps(pEngine, ObjDefnID, PropertySpecs);
628 DefineMethods(pEngine, ObjDefnID, MethodSpecs);
629 }
630
CJS_Field(v8::Local<v8::Object> pObject,CJS_Runtime * pRuntime)631 CJS_Field::CJS_Field(v8::Local<v8::Object> pObject, CJS_Runtime* pRuntime)
632 : CJS_Object(pObject, pRuntime) {}
633
634 CJS_Field::~CJS_Field() = default;
635
AttachField(CJS_Document * pDocument,const WideString & csFieldName)636 bool CJS_Field::AttachField(CJS_Document* pDocument,
637 const WideString& csFieldName) {
638 m_pJSDoc.Reset(pDocument);
639 m_pFormFillEnv.Reset(pDocument->GetFormFillEnv());
640 m_bCanSet = m_pFormFillEnv->HasPermissions(
641 pdfium::access_permissions::kFillForm |
642 pdfium::access_permissions::kModifyAnnotation |
643 pdfium::access_permissions::kModifyContent);
644
645 CPDFSDK_InteractiveForm* pRDForm = m_pFormFillEnv->GetInteractiveForm();
646 CPDF_InteractiveForm* pForm = pRDForm->GetInteractiveForm();
647 WideString swFieldNameTemp = csFieldName;
648 swFieldNameTemp.Replace(L"..", L".");
649
650 if (pForm->CountFields(swFieldNameTemp) <= 0) {
651 absl::optional<FieldNameData> parsed_data = ParseFieldName(swFieldNameTemp);
652 if (!parsed_data.has_value())
653 return false;
654
655 m_FieldName = parsed_data.value().field_name;
656 m_nFormControlIndex = parsed_data.value().control_index;
657 return true;
658 }
659
660 m_FieldName = swFieldNameTemp;
661 m_nFormControlIndex = -1;
662
663 return true;
664 }
665
GetFormFields() const666 std::vector<CPDF_FormField*> CJS_Field::GetFormFields() const {
667 return GetFormFieldsForName(m_pFormFillEnv.Get(), m_FieldName);
668 }
669
GetFirstFormField() const670 CPDF_FormField* CJS_Field::GetFirstFormField() const {
671 std::vector<CPDF_FormField*> fields = GetFormFields();
672 return fields.empty() ? nullptr : fields[0];
673 }
674
GetSmartFieldControl(CPDF_FormField * pFormField)675 CPDF_FormControl* CJS_Field::GetSmartFieldControl(CPDF_FormField* pFormField) {
676 if (!pFormField->CountControls() ||
677 m_nFormControlIndex >= pFormField->CountControls())
678 return nullptr;
679 if (m_nFormControlIndex < 0)
680 return pFormField->GetControl(0);
681 return pFormField->GetControl(m_nFormControlIndex);
682 }
683
get_alignment(CJS_Runtime * pRuntime)684 CJS_Result CJS_Field::get_alignment(CJS_Runtime* pRuntime) {
685 DCHECK(m_pFormFillEnv);
686
687 CPDF_FormField* pFormField = GetFirstFormField();
688 if (!pFormField)
689 return CJS_Result::Failure(JSMessage::kBadObjectError);
690
691 if (pFormField->GetFieldType() != FormFieldType::kTextField)
692 return CJS_Result::Failure(JSMessage::kObjectTypeError);
693
694 CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
695 if (!pFormControl)
696 return CJS_Result::Failure(JSMessage::kBadObjectError);
697
698 switch (pFormControl->GetControlAlignment()) {
699 case 0:
700 return CJS_Result::Success(pRuntime->NewString("left"));
701 case 1:
702 return CJS_Result::Success(pRuntime->NewString("center"));
703 case 2:
704 return CJS_Result::Success(pRuntime->NewString("right"));
705 }
706 return CJS_Result::Success(pRuntime->NewString(""));
707 }
708
set_alignment(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)709 CJS_Result CJS_Field::set_alignment(CJS_Runtime* pRuntime,
710 v8::Local<v8::Value> vp) {
711 DCHECK(m_pFormFillEnv);
712 if (!m_bCanSet)
713 return CJS_Result::Failure(JSMessage::kReadOnlyError);
714
715 return CJS_Result::Success();
716 }
717
get_border_style(CJS_Runtime * pRuntime)718 CJS_Result CJS_Field::get_border_style(CJS_Runtime* pRuntime) {
719 DCHECK(m_pFormFillEnv);
720
721 CPDF_FormField* pFormField = GetFirstFormField();
722 if (!pFormField)
723 return CJS_Result::Failure(JSMessage::kBadObjectError);
724
725 CPDFSDK_Widget* pWidget = m_pFormFillEnv->GetInteractiveForm()->GetWidget(
726 GetSmartFieldControl(pFormField));
727 if (!pWidget)
728 return CJS_Result::Failure(JSMessage::kBadObjectError);
729
730 switch (pWidget->GetBorderStyle()) {
731 case BorderStyle::kSolid:
732 return CJS_Result::Success(pRuntime->NewString("solid"));
733 case BorderStyle::kDash:
734 return CJS_Result::Success(pRuntime->NewString("dashed"));
735 case BorderStyle::kBeveled:
736 return CJS_Result::Success(pRuntime->NewString("beveled"));
737 case BorderStyle::kInset:
738 return CJS_Result::Success(pRuntime->NewString("inset"));
739 case BorderStyle::kUnderline:
740 return CJS_Result::Success(pRuntime->NewString("underline"));
741 }
742 return CJS_Result::Success(pRuntime->NewString(""));
743 }
744
set_border_style(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)745 CJS_Result CJS_Field::set_border_style(CJS_Runtime* pRuntime,
746 v8::Local<v8::Value> vp) {
747 DCHECK(m_pFormFillEnv);
748 if (!m_bCanSet)
749 return CJS_Result::Failure(JSMessage::kReadOnlyError);
750
751 ByteString byte_str = pRuntime->ToByteString(vp);
752 if (m_bDelay) {
753 AddDelay_String(FP_BORDERSTYLE, byte_str);
754 } else {
755 SetBorderStyle(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex,
756 byte_str);
757 }
758 return CJS_Result::Success();
759 }
760
get_button_align_x(CJS_Runtime * pRuntime)761 CJS_Result CJS_Field::get_button_align_x(CJS_Runtime* pRuntime) {
762 DCHECK(m_pFormFillEnv);
763
764 CPDF_FormField* pFormField = GetFirstFormField();
765 if (!pFormField)
766 return CJS_Result::Failure(JSMessage::kBadObjectError);
767
768 if (pFormField->GetFieldType() != FormFieldType::kPushButton)
769 return CJS_Result::Failure(JSMessage::kObjectTypeError);
770
771 CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
772 if (!pFormControl)
773 return CJS_Result::Failure(JSMessage::kBadObjectError);
774
775 CPDF_IconFit IconFit = pFormControl->GetIconFit();
776 CFX_PointF pos = IconFit.GetIconBottomLeftPosition();
777 return CJS_Result::Success(pRuntime->NewNumber(static_cast<int32_t>(pos.x)));
778 }
779
set_button_align_x(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)780 CJS_Result CJS_Field::set_button_align_x(CJS_Runtime* pRuntime,
781 v8::Local<v8::Value> vp) {
782 DCHECK(m_pFormFillEnv);
783 if (!m_bCanSet)
784 return CJS_Result::Failure(JSMessage::kReadOnlyError);
785 return CJS_Result::Success();
786 }
787
get_button_align_y(CJS_Runtime * pRuntime)788 CJS_Result CJS_Field::get_button_align_y(CJS_Runtime* pRuntime) {
789 DCHECK(m_pFormFillEnv);
790
791 CPDF_FormField* pFormField = GetFirstFormField();
792 if (!pFormField)
793 return CJS_Result::Failure(JSMessage::kBadObjectError);
794
795 if (pFormField->GetFieldType() != FormFieldType::kPushButton)
796 return CJS_Result::Failure(JSMessage::kObjectTypeError);
797
798 CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
799 if (!pFormControl)
800 return CJS_Result::Failure(JSMessage::kBadObjectError);
801
802 CPDF_IconFit IconFit = pFormControl->GetIconFit();
803 CFX_PointF pos = IconFit.GetIconBottomLeftPosition();
804 return CJS_Result::Success(pRuntime->NewNumber(static_cast<int32_t>(pos.y)));
805 }
806
set_button_align_y(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)807 CJS_Result CJS_Field::set_button_align_y(CJS_Runtime* pRuntime,
808 v8::Local<v8::Value> vp) {
809 DCHECK(m_pFormFillEnv);
810 if (!m_bCanSet)
811 return CJS_Result::Failure(JSMessage::kReadOnlyError);
812 return CJS_Result::Success();
813 }
814
get_button_fit_bounds(CJS_Runtime * pRuntime)815 CJS_Result CJS_Field::get_button_fit_bounds(CJS_Runtime* pRuntime) {
816 DCHECK(m_pFormFillEnv);
817
818 CPDF_FormField* pFormField = GetFirstFormField();
819 if (!pFormField)
820 return CJS_Result::Failure(JSMessage::kBadObjectError);
821
822 if (pFormField->GetFieldType() != FormFieldType::kPushButton)
823 return CJS_Result::Failure(JSMessage::kObjectTypeError);
824
825 CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
826 if (!pFormControl)
827 return CJS_Result::Failure(JSMessage::kBadObjectError);
828
829 return CJS_Result::Success(
830 pRuntime->NewBoolean(pFormControl->GetIconFit().GetFittingBounds()));
831 }
832
set_button_fit_bounds(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)833 CJS_Result CJS_Field::set_button_fit_bounds(CJS_Runtime* pRuntime,
834 v8::Local<v8::Value> vp) {
835 DCHECK(m_pFormFillEnv);
836 if (!m_bCanSet)
837 return CJS_Result::Failure(JSMessage::kReadOnlyError);
838 return CJS_Result::Success();
839 }
840
get_button_position(CJS_Runtime * pRuntime)841 CJS_Result CJS_Field::get_button_position(CJS_Runtime* pRuntime) {
842 DCHECK(m_pFormFillEnv);
843
844 CPDF_FormField* pFormField = GetFirstFormField();
845 if (!pFormField)
846 return CJS_Result::Failure(JSMessage::kBadObjectError);
847
848 if (pFormField->GetFieldType() != FormFieldType::kPushButton)
849 return CJS_Result::Failure(JSMessage::kObjectTypeError);
850
851 CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
852 if (!pFormControl)
853 return CJS_Result::Failure(JSMessage::kBadObjectError);
854
855 return CJS_Result::Success(
856 pRuntime->NewNumber(pFormControl->GetTextPosition()));
857 }
858
set_button_position(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)859 CJS_Result CJS_Field::set_button_position(CJS_Runtime* pRuntime,
860 v8::Local<v8::Value> vp) {
861 DCHECK(m_pFormFillEnv);
862 if (!m_bCanSet)
863 return CJS_Result::Failure(JSMessage::kBadObjectError);
864 return CJS_Result::Success();
865 }
866
get_button_scale_how(CJS_Runtime * pRuntime)867 CJS_Result CJS_Field::get_button_scale_how(CJS_Runtime* pRuntime) {
868 DCHECK(m_pFormFillEnv);
869
870 CPDF_FormField* pFormField = GetFirstFormField();
871 if (!pFormField)
872 return CJS_Result::Failure(JSMessage::kBadObjectError);
873
874 if (pFormField->GetFieldType() != FormFieldType::kPushButton)
875 return CJS_Result::Failure(JSMessage::kObjectTypeError);
876
877 CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
878 if (!pFormControl)
879 return CJS_Result::Failure(JSMessage::kBadObjectError);
880
881 return CJS_Result::Success(
882 pRuntime->NewBoolean(!pFormControl->GetIconFit().IsProportionalScale()));
883 }
884
set_button_scale_how(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)885 CJS_Result CJS_Field::set_button_scale_how(CJS_Runtime* pRuntime,
886 v8::Local<v8::Value> vp) {
887 DCHECK(m_pFormFillEnv);
888 if (!m_bCanSet)
889 return CJS_Result::Failure(JSMessage::kReadOnlyError);
890 return CJS_Result::Success();
891 }
892
get_button_scale_when(CJS_Runtime * pRuntime)893 CJS_Result CJS_Field::get_button_scale_when(CJS_Runtime* pRuntime) {
894 DCHECK(m_pFormFillEnv);
895
896 CPDF_FormField* pFormField = GetFirstFormField();
897 if (!pFormField)
898 return CJS_Result::Failure(JSMessage::kBadObjectError);
899
900 if (pFormField->GetFieldType() != FormFieldType::kPushButton)
901 return CJS_Result::Failure(JSMessage::kObjectTypeError);
902
903 CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
904 if (!pFormControl)
905 return CJS_Result::Failure(JSMessage::kBadObjectError);
906
907 CPDF_IconFit IconFit = pFormControl->GetIconFit();
908 CPDF_IconFit::ScaleMethod scale_method = IconFit.GetScaleMethod();
909 switch (scale_method) {
910 case CPDF_IconFit::ScaleMethod::kAlways:
911 case CPDF_IconFit::ScaleMethod::kBigger:
912 case CPDF_IconFit::ScaleMethod::kNever:
913 case CPDF_IconFit::ScaleMethod::kSmaller:
914 return CJS_Result::Success(
915 pRuntime->NewNumber(static_cast<int>(scale_method)));
916 }
917 }
918
set_button_scale_when(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)919 CJS_Result CJS_Field::set_button_scale_when(CJS_Runtime* pRuntime,
920 v8::Local<v8::Value> vp) {
921 DCHECK(m_pFormFillEnv);
922 if (!m_bCanSet)
923 return CJS_Result::Failure(JSMessage::kReadOnlyError);
924 return CJS_Result::Success();
925 }
926
get_calc_order_index(CJS_Runtime * pRuntime)927 CJS_Result CJS_Field::get_calc_order_index(CJS_Runtime* pRuntime) {
928 DCHECK(m_pFormFillEnv);
929
930 CPDF_FormField* pFormField = GetFirstFormField();
931 if (!pFormField)
932 return CJS_Result::Failure(JSMessage::kBadObjectError);
933
934 if (!IsComboBoxOrTextField(pFormField))
935 return CJS_Result::Failure(JSMessage::kObjectTypeError);
936
937 CPDFSDK_InteractiveForm* pRDForm = m_pFormFillEnv->GetInteractiveForm();
938 CPDF_InteractiveForm* pForm = pRDForm->GetInteractiveForm();
939 return CJS_Result::Success(
940 pRuntime->NewNumber(pForm->FindFieldInCalculationOrder(pFormField)));
941 }
942
set_calc_order_index(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)943 CJS_Result CJS_Field::set_calc_order_index(CJS_Runtime* pRuntime,
944 v8::Local<v8::Value> vp) {
945 DCHECK(m_pFormFillEnv);
946 if (!m_bCanSet)
947 return CJS_Result::Failure(JSMessage::kReadOnlyError);
948 return CJS_Result::Success();
949 }
950
get_char_limit(CJS_Runtime * pRuntime)951 CJS_Result CJS_Field::get_char_limit(CJS_Runtime* pRuntime) {
952 DCHECK(m_pFormFillEnv);
953
954 CPDF_FormField* pFormField = GetFirstFormField();
955 if (!pFormField)
956 return CJS_Result::Failure(JSMessage::kBadObjectError);
957
958 if (pFormField->GetFieldType() != FormFieldType::kTextField)
959 return CJS_Result::Failure(JSMessage::kObjectTypeError);
960 return CJS_Result::Success(
961 pRuntime->NewNumber(static_cast<int32_t>(pFormField->GetMaxLen())));
962 }
963
set_char_limit(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)964 CJS_Result CJS_Field::set_char_limit(CJS_Runtime* pRuntime,
965 v8::Local<v8::Value> vp) {
966 DCHECK(m_pFormFillEnv);
967 if (!m_bCanSet)
968 return CJS_Result::Failure(JSMessage::kReadOnlyError);
969 return CJS_Result::Success();
970 }
971
get_comb(CJS_Runtime * pRuntime)972 CJS_Result CJS_Field::get_comb(CJS_Runtime* pRuntime) {
973 DCHECK(m_pFormFillEnv);
974
975 CPDF_FormField* pFormField = GetFirstFormField();
976 if (!pFormField)
977 return CJS_Result::Failure(JSMessage::kBadObjectError);
978
979 if (pFormField->GetFieldType() != FormFieldType::kTextField)
980 return CJS_Result::Failure(JSMessage::kObjectTypeError);
981
982 return CJS_Result::Success(pRuntime->NewBoolean(
983 !!(pFormField->GetFieldFlags() & pdfium::form_flags::kTextComb)));
984 }
985
set_comb(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)986 CJS_Result CJS_Field::set_comb(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
987 DCHECK(m_pFormFillEnv);
988 if (!m_bCanSet)
989 return CJS_Result::Failure(JSMessage::kReadOnlyError);
990 return CJS_Result::Success();
991 }
992
get_commit_on_sel_change(CJS_Runtime * pRuntime)993 CJS_Result CJS_Field::get_commit_on_sel_change(CJS_Runtime* pRuntime) {
994 DCHECK(m_pFormFillEnv);
995
996 CPDF_FormField* pFormField = GetFirstFormField();
997 if (!pFormField)
998 return CJS_Result::Failure(JSMessage::kBadObjectError);
999
1000 if (!IsComboBoxOrListBox(pFormField))
1001 return CJS_Result::Failure(JSMessage::kObjectTypeError);
1002
1003 uint32_t dwFieldFlags = pFormField->GetFieldFlags();
1004 return CJS_Result::Success(pRuntime->NewBoolean(
1005 !!(dwFieldFlags & pdfium::form_flags::kChoiceCommitOnSelChange)));
1006 }
1007
set_commit_on_sel_change(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1008 CJS_Result CJS_Field::set_commit_on_sel_change(CJS_Runtime* pRuntime,
1009 v8::Local<v8::Value> vp) {
1010 DCHECK(m_pFormFillEnv);
1011 if (!m_bCanSet)
1012 return CJS_Result::Failure(JSMessage::kReadOnlyError);
1013 return CJS_Result::Success();
1014 }
1015
get_current_value_indices(CJS_Runtime * pRuntime)1016 CJS_Result CJS_Field::get_current_value_indices(CJS_Runtime* pRuntime) {
1017 CPDF_FormField* pFormField = GetFirstFormField();
1018 if (!pFormField)
1019 return CJS_Result::Failure(JSMessage::kBadObjectError);
1020
1021 if (!IsComboBoxOrListBox(pFormField))
1022 return CJS_Result::Failure(JSMessage::kObjectTypeError);
1023
1024 int count = pFormField->CountSelectedItems();
1025 if (count <= 0)
1026 return CJS_Result::Success(pRuntime->NewNumber(-1));
1027 if (count == 1)
1028 return CJS_Result::Success(
1029 pRuntime->NewNumber(pFormField->GetSelectedIndex(0)));
1030
1031 v8::Local<v8::Array> SelArray = pRuntime->NewArray();
1032 for (int i = 0; i < count; i++) {
1033 pRuntime->PutArrayElement(
1034 SelArray, i, pRuntime->NewNumber(pFormField->GetSelectedIndex(i)));
1035 }
1036 if (SelArray.IsEmpty())
1037 return CJS_Result::Success(pRuntime->NewArray());
1038 return CJS_Result::Success(SelArray);
1039 }
1040
set_current_value_indices(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1041 CJS_Result CJS_Field::set_current_value_indices(CJS_Runtime* pRuntime,
1042 v8::Local<v8::Value> vp) {
1043 if (!m_bCanSet)
1044 return CJS_Result::Failure(JSMessage::kReadOnlyError);
1045
1046 std::vector<uint32_t> array;
1047 if (vp->IsNumber()) {
1048 array.push_back(pRuntime->ToInt32(vp));
1049 } else if (fxv8::IsArray(vp)) {
1050 v8::Local<v8::Array> SelArray = pRuntime->ToArray(vp);
1051 for (size_t i = 0; i < pRuntime->GetArrayLength(SelArray); i++) {
1052 array.push_back(
1053 pRuntime->ToInt32(pRuntime->GetArrayElement(SelArray, i)));
1054 }
1055 }
1056
1057 if (m_bDelay) {
1058 AddDelay_WordArray(FP_CURRENTVALUEINDICES, array);
1059 } else {
1060 SetCurrentValueIndices(m_pFormFillEnv.Get(), m_FieldName,
1061 m_nFormControlIndex, array);
1062 }
1063 return CJS_Result::Success();
1064 }
1065
get_default_style(CJS_Runtime * pRuntime)1066 CJS_Result CJS_Field::get_default_style(CJS_Runtime* pRuntime) {
1067 return CJS_Result::Failure(JSMessage::kNotSupportedError);
1068 }
1069
set_default_style(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1070 CJS_Result CJS_Field::set_default_style(CJS_Runtime* pRuntime,
1071 v8::Local<v8::Value> vp) {
1072 return CJS_Result::Failure(JSMessage::kNotSupportedError);
1073 }
1074
get_default_value(CJS_Runtime * pRuntime)1075 CJS_Result CJS_Field::get_default_value(CJS_Runtime* pRuntime) {
1076 DCHECK(m_pFormFillEnv);
1077
1078 CPDF_FormField* pFormField = GetFirstFormField();
1079 if (!pFormField)
1080 return CJS_Result::Failure(JSMessage::kBadObjectError);
1081
1082 if (pFormField->GetFieldType() == FormFieldType::kPushButton ||
1083 pFormField->GetFieldType() == FormFieldType::kSignature) {
1084 return CJS_Result::Failure(JSMessage::kObjectTypeError);
1085 }
1086
1087 return CJS_Result::Success(
1088 pRuntime->NewString(pFormField->GetDefaultValue().AsStringView()));
1089 }
1090
set_default_value(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1091 CJS_Result CJS_Field::set_default_value(CJS_Runtime* pRuntime,
1092 v8::Local<v8::Value> vp) {
1093 DCHECK(m_pFormFillEnv);
1094 if (!m_bCanSet)
1095 return CJS_Result::Failure(JSMessage::kReadOnlyError);
1096 return CJS_Result::Success();
1097 }
1098
get_do_not_scroll(CJS_Runtime * pRuntime)1099 CJS_Result CJS_Field::get_do_not_scroll(CJS_Runtime* pRuntime) {
1100 DCHECK(m_pFormFillEnv);
1101
1102 CPDF_FormField* pFormField = GetFirstFormField();
1103 if (!pFormField)
1104 return CJS_Result::Failure(JSMessage::kBadObjectError);
1105
1106 if (pFormField->GetFieldType() != FormFieldType::kTextField)
1107 return CJS_Result::Failure(JSMessage::kObjectTypeError);
1108
1109 return CJS_Result::Success(pRuntime->NewBoolean(
1110 !!(pFormField->GetFieldFlags() & pdfium::form_flags::kTextDoNotScroll)));
1111 }
1112
set_do_not_scroll(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1113 CJS_Result CJS_Field::set_do_not_scroll(CJS_Runtime* pRuntime,
1114 v8::Local<v8::Value> vp) {
1115 DCHECK(m_pFormFillEnv);
1116 if (!m_bCanSet)
1117 return CJS_Result::Failure(JSMessage::kReadOnlyError);
1118 return CJS_Result::Success();
1119 }
1120
get_do_not_spell_check(CJS_Runtime * pRuntime)1121 CJS_Result CJS_Field::get_do_not_spell_check(CJS_Runtime* pRuntime) {
1122 DCHECK(m_pFormFillEnv);
1123
1124 CPDF_FormField* pFormField = GetFirstFormField();
1125 if (!pFormField)
1126 return CJS_Result::Failure(JSMessage::kBadObjectError);
1127
1128 if (!IsComboBoxOrTextField(pFormField))
1129 return CJS_Result::Failure(JSMessage::kObjectTypeError);
1130
1131 uint32_t dwFieldFlags = pFormField->GetFieldFlags();
1132 return CJS_Result::Success(pRuntime->NewBoolean(
1133 !!(dwFieldFlags & pdfium::form_flags::kTextDoNotSpellCheck)));
1134 }
1135
set_do_not_spell_check(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1136 CJS_Result CJS_Field::set_do_not_spell_check(CJS_Runtime* pRuntime,
1137 v8::Local<v8::Value> vp) {
1138 DCHECK(m_pFormFillEnv);
1139 if (!m_bCanSet)
1140 return CJS_Result::Failure(JSMessage::kReadOnlyError);
1141 return CJS_Result::Success();
1142 }
1143
get_delay(CJS_Runtime * pRuntime)1144 CJS_Result CJS_Field::get_delay(CJS_Runtime* pRuntime) {
1145 return CJS_Result::Success(pRuntime->NewBoolean(m_bDelay));
1146 }
1147
set_delay(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1148 CJS_Result CJS_Field::set_delay(CJS_Runtime* pRuntime,
1149 v8::Local<v8::Value> vp) {
1150 if (!m_bCanSet)
1151 return CJS_Result::Failure(JSMessage::kReadOnlyError);
1152
1153 SetDelay(pRuntime->ToBoolean(vp));
1154 return CJS_Result::Success();
1155 }
1156
get_display(CJS_Runtime * pRuntime)1157 CJS_Result CJS_Field::get_display(CJS_Runtime* pRuntime) {
1158 CPDF_FormField* pFormField = GetFirstFormField();
1159 if (!pFormField)
1160 return CJS_Result::Failure(JSMessage::kBadObjectError);
1161
1162 CPDFSDK_InteractiveForm* pForm = m_pFormFillEnv->GetInteractiveForm();
1163 CPDFSDK_Widget* pWidget = pForm->GetWidget(GetSmartFieldControl(pFormField));
1164 if (!pWidget)
1165 return CJS_Result::Failure(JSMessage::kBadObjectError);
1166
1167 uint32_t dwFlag = pWidget->GetFlags();
1168 if (pdfium::annotation_flags::kInvisible & dwFlag ||
1169 pdfium::annotation_flags::kHidden & dwFlag) {
1170 return CJS_Result::Success(pRuntime->NewNumber(1));
1171 }
1172
1173 if (pdfium::annotation_flags::kPrint & dwFlag) {
1174 if (pdfium::annotation_flags::kNoView & dwFlag)
1175 return CJS_Result::Success(pRuntime->NewNumber(3));
1176 return CJS_Result::Success(pRuntime->NewNumber(0));
1177 }
1178 return CJS_Result::Success(pRuntime->NewNumber(2));
1179 }
1180
set_display(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1181 CJS_Result CJS_Field::set_display(CJS_Runtime* pRuntime,
1182 v8::Local<v8::Value> vp) {
1183 if (!m_bCanSet)
1184 return CJS_Result::Failure(JSMessage::kReadOnlyError);
1185
1186 if (m_bDelay) {
1187 AddDelay_Int(FP_DISPLAY, pRuntime->ToInt32(vp));
1188 } else {
1189 SetDisplay(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex,
1190 pRuntime->ToInt32(vp));
1191 }
1192 return CJS_Result::Success();
1193 }
1194
get_doc(CJS_Runtime * pRuntime)1195 CJS_Result CJS_Field::get_doc(CJS_Runtime* pRuntime) {
1196 return CJS_Result::Success(m_pJSDoc->ToV8Object());
1197 }
1198
set_doc(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1199 CJS_Result CJS_Field::set_doc(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
1200 return CJS_Result::Failure(JSMessage::kNotSupportedError);
1201 }
1202
get_editable(CJS_Runtime * pRuntime)1203 CJS_Result CJS_Field::get_editable(CJS_Runtime* pRuntime) {
1204 CPDF_FormField* pFormField = GetFirstFormField();
1205 if (!pFormField)
1206 return CJS_Result::Failure(JSMessage::kBadObjectError);
1207
1208 if (pFormField->GetFieldType() != FormFieldType::kComboBox)
1209 return CJS_Result::Failure(JSMessage::kObjectTypeError);
1210
1211 return CJS_Result::Success(pRuntime->NewBoolean(
1212 !!(pFormField->GetFieldFlags() & pdfium::form_flags::kChoiceEdit)));
1213 }
1214
set_editable(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1215 CJS_Result CJS_Field::set_editable(CJS_Runtime* pRuntime,
1216 v8::Local<v8::Value> vp) {
1217 if (!m_bCanSet)
1218 return CJS_Result::Failure(JSMessage::kReadOnlyError);
1219 return CJS_Result::Success();
1220 }
1221
get_export_values(CJS_Runtime * pRuntime)1222 CJS_Result CJS_Field::get_export_values(CJS_Runtime* pRuntime) {
1223 CPDF_FormField* pFormField = GetFirstFormField();
1224 if (!pFormField)
1225 return CJS_Result::Failure(JSMessage::kBadObjectError);
1226
1227 if (!IsCheckBoxOrRadioButton(pFormField))
1228 return CJS_Result::Failure(JSMessage::kObjectTypeError);
1229
1230 v8::Local<v8::Array> ExportValuesArray = pRuntime->NewArray();
1231 if (m_nFormControlIndex < 0) {
1232 for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
1233 CPDF_FormControl* pFormControl = pFormField->GetControl(i);
1234 pRuntime->PutArrayElement(
1235 ExportValuesArray, i,
1236 pRuntime->NewString(pFormControl->GetExportValue().AsStringView()));
1237 }
1238 } else {
1239 if (m_nFormControlIndex >= pFormField->CountControls())
1240 return CJS_Result::Failure(JSMessage::kValueError);
1241
1242 CPDF_FormControl* pFormControl =
1243 pFormField->GetControl(m_nFormControlIndex);
1244 if (!pFormControl)
1245 return CJS_Result::Failure(JSMessage::kBadObjectError);
1246
1247 pRuntime->PutArrayElement(
1248 ExportValuesArray, 0,
1249 pRuntime->NewString(pFormControl->GetExportValue().AsStringView()));
1250 }
1251 return CJS_Result::Success(ExportValuesArray);
1252 }
1253
set_export_values(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1254 CJS_Result CJS_Field::set_export_values(CJS_Runtime* pRuntime,
1255 v8::Local<v8::Value> vp) {
1256 CPDF_FormField* pFormField = GetFirstFormField();
1257 if (!pFormField)
1258 return CJS_Result::Failure(JSMessage::kBadObjectError);
1259
1260 if (!IsCheckBoxOrRadioButton(pFormField))
1261 return CJS_Result::Failure(JSMessage::kObjectTypeError);
1262
1263 if (!m_bCanSet)
1264 return CJS_Result::Failure(JSMessage::kReadOnlyError);
1265
1266 if (!fxv8::IsArray(vp))
1267 return CJS_Result::Failure(JSMessage::kBadObjectError);
1268
1269 return CJS_Result::Success();
1270 }
1271
get_file_select(CJS_Runtime * pRuntime)1272 CJS_Result CJS_Field::get_file_select(CJS_Runtime* pRuntime) {
1273 CPDF_FormField* pFormField = GetFirstFormField();
1274 if (!pFormField)
1275 return CJS_Result::Failure(JSMessage::kBadObjectError);
1276
1277 if (pFormField->GetFieldType() != FormFieldType::kTextField)
1278 return CJS_Result::Failure(JSMessage::kObjectTypeError);
1279
1280 return CJS_Result::Success(pRuntime->NewBoolean(
1281 !!(pFormField->GetFieldFlags() & pdfium::form_flags::kTextFileSelect)));
1282 }
1283
set_file_select(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1284 CJS_Result CJS_Field::set_file_select(CJS_Runtime* pRuntime,
1285 v8::Local<v8::Value> vp) {
1286 CPDF_FormField* pFormField = GetFirstFormField();
1287 if (!pFormField)
1288 return CJS_Result::Failure(JSMessage::kBadObjectError);
1289
1290 if (pFormField->GetFieldType() != FormFieldType::kTextField)
1291 return CJS_Result::Failure(JSMessage::kObjectTypeError);
1292
1293 if (!m_bCanSet)
1294 return CJS_Result::Failure(JSMessage::kReadOnlyError);
1295
1296 return CJS_Result::Success();
1297 }
1298
get_fill_color(CJS_Runtime * pRuntime)1299 CJS_Result CJS_Field::get_fill_color(CJS_Runtime* pRuntime) {
1300 CPDF_FormField* pFormField = GetFirstFormField();
1301 if (!pFormField)
1302 return CJS_Result::Failure(JSMessage::kBadObjectError);
1303
1304 CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
1305 if (!pFormControl)
1306 return CJS_Result::Failure(JSMessage::kBadObjectError);
1307
1308 CFX_Color color = GetFormControlColor(pFormControl, pdfium::appearance::kBG);
1309 v8::Local<v8::Value> array =
1310 CJS_Color::ConvertPWLColorToArray(pRuntime, color);
1311 if (array.IsEmpty())
1312 return CJS_Result::Success(pRuntime->NewArray());
1313 return CJS_Result::Success(array);
1314 }
1315
set_fill_color(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1316 CJS_Result CJS_Field::set_fill_color(CJS_Runtime* pRuntime,
1317 v8::Local<v8::Value> vp) {
1318 std::vector<CPDF_FormField*> FieldArray = GetFormFields();
1319 if (FieldArray.empty())
1320 return CJS_Result::Failure(JSMessage::kBadObjectError);
1321 if (!m_bCanSet)
1322 return CJS_Result::Failure(JSMessage::kReadOnlyError);
1323 if (!fxv8::IsArray(vp))
1324 return CJS_Result::Failure(JSMessage::kBadObjectError);
1325 return CJS_Result::Success();
1326 }
1327
get_hidden(CJS_Runtime * pRuntime)1328 CJS_Result CJS_Field::get_hidden(CJS_Runtime* pRuntime) {
1329 CPDF_FormField* pFormField = GetFirstFormField();
1330 if (!pFormField)
1331 return CJS_Result::Failure(JSMessage::kBadObjectError);
1332
1333 CPDFSDK_InteractiveForm* pForm = m_pFormFillEnv->GetInteractiveForm();
1334 CPDFSDK_Widget* pWidget = pForm->GetWidget(GetSmartFieldControl(pFormField));
1335 if (!pWidget)
1336 return CJS_Result::Failure(JSMessage::kBadObjectError);
1337
1338 uint32_t dwFlags = pWidget->GetFlags();
1339 return CJS_Result::Success(
1340 pRuntime->NewBoolean(pdfium::annotation_flags::kInvisible & dwFlags ||
1341 pdfium::annotation_flags::kHidden & dwFlags));
1342 }
1343
set_hidden(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1344 CJS_Result CJS_Field::set_hidden(CJS_Runtime* pRuntime,
1345 v8::Local<v8::Value> vp) {
1346 if (!m_bCanSet)
1347 return CJS_Result::Failure(JSMessage::kReadOnlyError);
1348
1349 if (m_bDelay) {
1350 AddDelay_Bool(FP_HIDDEN, pRuntime->ToBoolean(vp));
1351 } else {
1352 SetHidden(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex,
1353 pRuntime->ToBoolean(vp));
1354 }
1355 return CJS_Result::Success();
1356 }
1357
get_highlight(CJS_Runtime * pRuntime)1358 CJS_Result CJS_Field::get_highlight(CJS_Runtime* pRuntime) {
1359 DCHECK(m_pFormFillEnv);
1360
1361 CPDF_FormField* pFormField = GetFirstFormField();
1362 if (!pFormField)
1363 return CJS_Result::Failure(JSMessage::kBadObjectError);
1364
1365 if (pFormField->GetFieldType() != FormFieldType::kPushButton)
1366 return CJS_Result::Failure(JSMessage::kObjectTypeError);
1367
1368 CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
1369 if (!pFormControl)
1370 return CJS_Result::Failure(JSMessage::kBadObjectError);
1371
1372 int eHM = pFormControl->GetHighlightingMode();
1373 switch (eHM) {
1374 case CPDF_FormControl::kNone:
1375 return CJS_Result::Success(pRuntime->NewString("none"));
1376 case CPDF_FormControl::kPush:
1377 return CJS_Result::Success(pRuntime->NewString("push"));
1378 case CPDF_FormControl::kInvert:
1379 return CJS_Result::Success(pRuntime->NewString("invert"));
1380 case CPDF_FormControl::kOutline:
1381 return CJS_Result::Success(pRuntime->NewString("outline"));
1382 case CPDF_FormControl::kToggle:
1383 return CJS_Result::Success(pRuntime->NewString("toggle"));
1384 }
1385 return CJS_Result::Success();
1386 }
1387
set_highlight(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1388 CJS_Result CJS_Field::set_highlight(CJS_Runtime* pRuntime,
1389 v8::Local<v8::Value> vp) {
1390 DCHECK(m_pFormFillEnv);
1391 if (!m_bCanSet)
1392 return CJS_Result::Failure(JSMessage::kReadOnlyError);
1393 return CJS_Result::Success();
1394 }
1395
get_line_width(CJS_Runtime * pRuntime)1396 CJS_Result CJS_Field::get_line_width(CJS_Runtime* pRuntime) {
1397 CPDF_FormField* pFormField = GetFirstFormField();
1398 if (!pFormField)
1399 return CJS_Result::Failure(JSMessage::kBadObjectError);
1400
1401 CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
1402 if (!pFormControl)
1403 return CJS_Result::Failure(JSMessage::kBadObjectError);
1404
1405 CPDFSDK_InteractiveForm* pForm = m_pFormFillEnv->GetInteractiveForm();
1406 if (!pFormField->CountControls())
1407 return CJS_Result::Failure(JSMessage::kBadObjectError);
1408
1409 CPDFSDK_Widget* pWidget = pForm->GetWidget(pFormField->GetControl(0));
1410 if (!pWidget)
1411 return CJS_Result::Failure(JSMessage::kBadObjectError);
1412
1413 return CJS_Result::Success(pRuntime->NewNumber(pWidget->GetBorderWidth()));
1414 }
1415
set_line_width(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1416 CJS_Result CJS_Field::set_line_width(CJS_Runtime* pRuntime,
1417 v8::Local<v8::Value> vp) {
1418 if (!m_bCanSet)
1419 return CJS_Result::Failure(JSMessage::kReadOnlyError);
1420
1421 if (m_bDelay) {
1422 AddDelay_Int(FP_LINEWIDTH, pRuntime->ToInt32(vp));
1423 } else {
1424 SetLineWidth(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex,
1425 pRuntime->ToInt32(vp));
1426 }
1427 return CJS_Result::Success();
1428 }
1429
get_multiline(CJS_Runtime * pRuntime)1430 CJS_Result CJS_Field::get_multiline(CJS_Runtime* pRuntime) {
1431 DCHECK(m_pFormFillEnv);
1432
1433 CPDF_FormField* pFormField = GetFirstFormField();
1434 if (!pFormField)
1435 return CJS_Result::Failure(JSMessage::kBadObjectError);
1436
1437 if (pFormField->GetFieldType() != FormFieldType::kTextField)
1438 return CJS_Result::Failure(JSMessage::kObjectTypeError);
1439
1440 return CJS_Result::Success(pRuntime->NewBoolean(
1441 !!(pFormField->GetFieldFlags() & pdfium::form_flags::kTextMultiline)));
1442 }
1443
set_multiline(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1444 CJS_Result CJS_Field::set_multiline(CJS_Runtime* pRuntime,
1445 v8::Local<v8::Value> vp) {
1446 DCHECK(m_pFormFillEnv);
1447 if (!m_bCanSet)
1448 return CJS_Result::Failure(JSMessage::kReadOnlyError);
1449 return CJS_Result::Success();
1450 }
1451
get_multiple_selection(CJS_Runtime * pRuntime)1452 CJS_Result CJS_Field::get_multiple_selection(CJS_Runtime* pRuntime) {
1453 DCHECK(m_pFormFillEnv);
1454 CPDF_FormField* pFormField = GetFirstFormField();
1455 if (!pFormField)
1456 return CJS_Result::Failure(JSMessage::kBadObjectError);
1457
1458 if (pFormField->GetFieldType() != FormFieldType::kListBox)
1459 return CJS_Result::Failure(JSMessage::kObjectTypeError);
1460
1461 uint32_t dwFieldFlags = pFormField->GetFieldFlags();
1462 return CJS_Result::Success(pRuntime->NewBoolean(
1463 !!(dwFieldFlags & pdfium::form_flags::kChoiceMultiSelect)));
1464 }
1465
set_multiple_selection(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1466 CJS_Result CJS_Field::set_multiple_selection(CJS_Runtime* pRuntime,
1467 v8::Local<v8::Value> vp) {
1468 DCHECK(m_pFormFillEnv);
1469 if (!m_bCanSet)
1470 return CJS_Result::Failure(JSMessage::kReadOnlyError);
1471 return CJS_Result::Success();
1472 }
1473
get_name(CJS_Runtime * pRuntime)1474 CJS_Result CJS_Field::get_name(CJS_Runtime* pRuntime) {
1475 std::vector<CPDF_FormField*> FieldArray = GetFormFields();
1476 if (FieldArray.empty())
1477 return CJS_Result::Failure(JSMessage::kBadObjectError);
1478
1479 return CJS_Result::Success(pRuntime->NewString(m_FieldName.AsStringView()));
1480 }
1481
set_name(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1482 CJS_Result CJS_Field::set_name(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
1483 return CJS_Result::Failure(JSMessage::kNotSupportedError);
1484 }
1485
get_num_items(CJS_Runtime * pRuntime)1486 CJS_Result CJS_Field::get_num_items(CJS_Runtime* pRuntime) {
1487 CPDF_FormField* pFormField = GetFirstFormField();
1488 if (!pFormField)
1489 return CJS_Result::Failure(JSMessage::kBadObjectError);
1490
1491 if (!IsComboBoxOrListBox(pFormField))
1492 return CJS_Result::Failure(JSMessage::kObjectTypeError);
1493
1494 return CJS_Result::Success(pRuntime->NewNumber(pFormField->CountOptions()));
1495 }
1496
set_num_items(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1497 CJS_Result CJS_Field::set_num_items(CJS_Runtime* pRuntime,
1498 v8::Local<v8::Value> vp) {
1499 return CJS_Result::Failure(JSMessage::kNotSupportedError);
1500 }
1501
get_page(CJS_Runtime * pRuntime)1502 CJS_Result CJS_Field::get_page(CJS_Runtime* pRuntime) {
1503 CPDF_FormField* pFormField = GetFirstFormField();
1504 if (!pFormField)
1505 return CJS_Result::Failure(JSMessage::kBadObjectError);
1506
1507 std::vector<ObservedPtr<CPDFSDK_Widget>> widgets;
1508 m_pFormFillEnv->GetInteractiveForm()->GetWidgets(pFormField, &widgets);
1509 if (widgets.empty())
1510 return CJS_Result::Success(pRuntime->NewNumber(-1));
1511
1512 v8::Local<v8::Array> PageArray = pRuntime->NewArray();
1513 int i = 0;
1514 for (const auto& pWidget : widgets) {
1515 if (!pWidget)
1516 return CJS_Result::Failure(JSMessage::kBadObjectError);
1517
1518 pRuntime->PutArrayElement(
1519 PageArray, i,
1520 pRuntime->NewNumber(pWidget->GetPageView()->GetPageIndex()));
1521 ++i;
1522 }
1523 return CJS_Result::Success(PageArray);
1524 }
1525
set_page(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1526 CJS_Result CJS_Field::set_page(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
1527 return CJS_Result::Failure(JSMessage::kReadOnlyError);
1528 }
1529
get_password(CJS_Runtime * pRuntime)1530 CJS_Result CJS_Field::get_password(CJS_Runtime* pRuntime) {
1531 DCHECK(m_pFormFillEnv);
1532
1533 CPDF_FormField* pFormField = GetFirstFormField();
1534 if (!pFormField)
1535 return CJS_Result::Failure(JSMessage::kBadObjectError);
1536
1537 if (pFormField->GetFieldType() != FormFieldType::kTextField)
1538 return CJS_Result::Failure(JSMessage::kObjectTypeError);
1539
1540 return CJS_Result::Success(pRuntime->NewBoolean(
1541 !!(pFormField->GetFieldFlags() & pdfium::form_flags::kTextPassword)));
1542 }
1543
set_password(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1544 CJS_Result CJS_Field::set_password(CJS_Runtime* pRuntime,
1545 v8::Local<v8::Value> vp) {
1546 DCHECK(m_pFormFillEnv);
1547 if (!m_bCanSet)
1548 return CJS_Result::Failure(JSMessage::kReadOnlyError);
1549 return CJS_Result::Success();
1550 }
1551
get_print(CJS_Runtime * pRuntime)1552 CJS_Result CJS_Field::get_print(CJS_Runtime* pRuntime) {
1553 CPDFSDK_InteractiveForm* pForm = m_pFormFillEnv->GetInteractiveForm();
1554 CPDF_FormField* pFormField = GetFirstFormField();
1555 if (!pFormField)
1556 return CJS_Result::Failure(JSMessage::kBadObjectError);
1557
1558 CPDFSDK_Widget* pWidget = pForm->GetWidget(GetSmartFieldControl(pFormField));
1559 if (!pWidget)
1560 return CJS_Result::Failure(JSMessage::kBadObjectError);
1561
1562 return CJS_Result::Success(pRuntime->NewBoolean(
1563 !!(pWidget->GetFlags() & pdfium::annotation_flags::kPrint)));
1564 }
1565
set_print(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1566 CJS_Result CJS_Field::set_print(CJS_Runtime* pRuntime,
1567 v8::Local<v8::Value> vp) {
1568 CPDFSDK_InteractiveForm* pForm = m_pFormFillEnv->GetInteractiveForm();
1569 std::vector<CPDF_FormField*> FieldArray = GetFormFields();
1570 if (FieldArray.empty())
1571 return CJS_Result::Failure(JSMessage::kBadObjectError);
1572
1573 if (!m_bCanSet)
1574 return CJS_Result::Failure(JSMessage::kReadOnlyError);
1575
1576 for (CPDF_FormField* pFormField : FieldArray) {
1577 if (m_nFormControlIndex < 0) {
1578 bool bSet = false;
1579 for (int i = 0, sz = pFormField->CountControls(); i < sz; ++i) {
1580 if (CPDFSDK_Widget* pWidget =
1581 pForm->GetWidget(pFormField->GetControl(i))) {
1582 uint32_t dwFlags = pWidget->GetFlags();
1583 if (pRuntime->ToBoolean(vp))
1584 dwFlags |= pdfium::annotation_flags::kPrint;
1585 else
1586 dwFlags &= ~pdfium::annotation_flags::kPrint;
1587
1588 if (dwFlags != pWidget->GetFlags()) {
1589 pWidget->SetFlags(dwFlags);
1590 bSet = true;
1591 }
1592 }
1593 }
1594
1595 if (bSet)
1596 UpdateFormField(m_pFormFillEnv.Get(), pFormField, false);
1597
1598 continue;
1599 }
1600
1601 if (m_nFormControlIndex >= pFormField->CountControls())
1602 return CJS_Result::Failure(JSMessage::kValueError);
1603
1604 if (CPDF_FormControl* pFormControl =
1605 pFormField->GetControl(m_nFormControlIndex)) {
1606 if (CPDFSDK_Widget* pWidget = pForm->GetWidget(pFormControl)) {
1607 uint32_t dwFlags = pWidget->GetFlags();
1608 if (pRuntime->ToBoolean(vp))
1609 dwFlags |= pdfium::annotation_flags::kPrint;
1610 else
1611 dwFlags &= ~pdfium::annotation_flags::kPrint;
1612
1613 if (dwFlags != pWidget->GetFlags()) {
1614 pWidget->SetFlags(dwFlags);
1615 UpdateFormControl(m_pFormFillEnv.Get(),
1616 pFormField->GetControl(m_nFormControlIndex), false);
1617 }
1618 }
1619 }
1620 }
1621 return CJS_Result::Success();
1622 }
1623
get_radios_in_unison(CJS_Runtime * pRuntime)1624 CJS_Result CJS_Field::get_radios_in_unison(CJS_Runtime* pRuntime) {
1625 CPDF_FormField* pFormField = GetFirstFormField();
1626 if (!pFormField)
1627 return CJS_Result::Failure(JSMessage::kBadObjectError);
1628
1629 if (pFormField->GetFieldType() != FormFieldType::kRadioButton)
1630 return CJS_Result::Failure(JSMessage::kObjectTypeError);
1631
1632 uint32_t dwFieldFlags = pFormField->GetFieldFlags();
1633 return CJS_Result::Success(pRuntime->NewBoolean(
1634 !!(dwFieldFlags & pdfium::form_flags::kButtonRadiosInUnison)));
1635 }
1636
set_radios_in_unison(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1637 CJS_Result CJS_Field::set_radios_in_unison(CJS_Runtime* pRuntime,
1638 v8::Local<v8::Value> vp) {
1639 std::vector<CPDF_FormField*> FieldArray = GetFormFields();
1640 if (FieldArray.empty())
1641 return CJS_Result::Failure(JSMessage::kBadObjectError);
1642 if (!m_bCanSet)
1643 return CJS_Result::Failure(JSMessage::kReadOnlyError);
1644 return CJS_Result::Success();
1645 }
1646
get_readonly(CJS_Runtime * pRuntime)1647 CJS_Result CJS_Field::get_readonly(CJS_Runtime* pRuntime) {
1648 CPDF_FormField* pFormField = GetFirstFormField();
1649 if (!pFormField)
1650 return CJS_Result::Failure(JSMessage::kBadObjectError);
1651
1652 return CJS_Result::Success(pRuntime->NewBoolean(
1653 !!(pFormField->GetFieldFlags() & pdfium::form_flags::kReadOnly)));
1654 }
1655
set_readonly(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1656 CJS_Result CJS_Field::set_readonly(CJS_Runtime* pRuntime,
1657 v8::Local<v8::Value> vp) {
1658 CPDF_FormField* pFormField = GetFirstFormField();
1659 if (!pFormField)
1660 return CJS_Result::Failure(JSMessage::kBadObjectError);
1661
1662 if (!m_bCanSet)
1663 return CJS_Result::Failure(JSMessage::kReadOnlyError);
1664
1665 const bool bReadOnly = pRuntime->ToBoolean(vp);
1666 const uint32_t dwFlags = pFormField->GetFieldFlags();
1667 const uint32_t dwNewFlags = bReadOnly
1668 ? (dwFlags | pdfium::form_flags::kReadOnly)
1669 : (dwFlags & ~pdfium::form_flags::kReadOnly);
1670 if (dwNewFlags != dwFlags)
1671 pFormField->SetFieldFlags(dwNewFlags);
1672
1673 return CJS_Result::Success();
1674 }
1675
get_rect(CJS_Runtime * pRuntime)1676 CJS_Result CJS_Field::get_rect(CJS_Runtime* pRuntime) {
1677 CPDF_FormField* pFormField = GetFirstFormField();
1678 if (!pFormField)
1679 return CJS_Result::Failure(JSMessage::kBadObjectError);
1680
1681 CPDFSDK_InteractiveForm* pForm = m_pFormFillEnv->GetInteractiveForm();
1682 CPDFSDK_Widget* pWidget = pForm->GetWidget(GetSmartFieldControl(pFormField));
1683 if (!pWidget)
1684 return CJS_Result::Failure(JSMessage::kBadObjectError);
1685
1686 CFX_FloatRect crRect = pWidget->GetRect();
1687 v8::Local<v8::Array> rcArray = pRuntime->NewArray();
1688 pRuntime->PutArrayElement(
1689 rcArray, 0, pRuntime->NewNumber(static_cast<int32_t>(crRect.left)));
1690 pRuntime->PutArrayElement(
1691 rcArray, 1, pRuntime->NewNumber(static_cast<int32_t>(crRect.top)));
1692 pRuntime->PutArrayElement(
1693 rcArray, 2, pRuntime->NewNumber(static_cast<int32_t>(crRect.right)));
1694 pRuntime->PutArrayElement(
1695 rcArray, 3, pRuntime->NewNumber(static_cast<int32_t>(crRect.bottom)));
1696
1697 return CJS_Result::Success(rcArray);
1698 }
1699
set_rect(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1700 CJS_Result CJS_Field::set_rect(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
1701 if (!m_bCanSet)
1702 return CJS_Result::Failure(JSMessage::kReadOnlyError);
1703 if (!fxv8::IsArray(vp))
1704 return CJS_Result::Failure(JSMessage::kValueError);
1705
1706 v8::Local<v8::Array> rcArray = pRuntime->ToArray(vp);
1707 if (pRuntime->GetArrayLength(rcArray) < 4)
1708 return CJS_Result::Failure(JSMessage::kValueError);
1709
1710 float f0 = static_cast<float>(
1711 pRuntime->ToInt32(pRuntime->GetArrayElement(rcArray, 0)));
1712 float f1 = static_cast<float>(
1713 pRuntime->ToInt32(pRuntime->GetArrayElement(rcArray, 1)));
1714 float f2 = static_cast<float>(
1715 pRuntime->ToInt32(pRuntime->GetArrayElement(rcArray, 2)));
1716 float f3 = static_cast<float>(
1717 pRuntime->ToInt32(pRuntime->GetArrayElement(rcArray, 3)));
1718
1719 CFX_FloatRect crRect(f0, f1, f2, f3);
1720 if (m_bDelay) {
1721 AddDelay_Rect(FP_RECT, crRect);
1722 } else {
1723 SetRect(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex, crRect);
1724 }
1725 return CJS_Result::Success();
1726 }
1727
get_required(CJS_Runtime * pRuntime)1728 CJS_Result CJS_Field::get_required(CJS_Runtime* pRuntime) {
1729 CPDF_FormField* pFormField = GetFirstFormField();
1730 if (!pFormField)
1731 return CJS_Result::Failure(JSMessage::kBadObjectError);
1732
1733 if (pFormField->GetFieldType() == FormFieldType::kPushButton)
1734 return CJS_Result::Failure(JSMessage::kObjectTypeError);
1735
1736 return CJS_Result::Success(pRuntime->NewBoolean(
1737 !!(pFormField->GetFieldFlags() & pdfium::form_flags::kRequired)));
1738 }
1739
set_required(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1740 CJS_Result CJS_Field::set_required(CJS_Runtime* pRuntime,
1741 v8::Local<v8::Value> vp) {
1742 std::vector<CPDF_FormField*> FieldArray = GetFormFields();
1743 if (FieldArray.empty())
1744 return CJS_Result::Failure(JSMessage::kBadObjectError);
1745 if (!m_bCanSet)
1746 return CJS_Result::Failure(JSMessage::kReadOnlyError);
1747 return CJS_Result::Success();
1748 }
1749
get_rich_text(CJS_Runtime * pRuntime)1750 CJS_Result CJS_Field::get_rich_text(CJS_Runtime* pRuntime) {
1751 DCHECK(m_pFormFillEnv);
1752
1753 CPDF_FormField* pFormField = GetFirstFormField();
1754 if (!pFormField)
1755 return CJS_Result::Failure(JSMessage::kBadObjectError);
1756
1757 if (pFormField->GetFieldType() != FormFieldType::kTextField)
1758 return CJS_Result::Failure(JSMessage::kObjectTypeError);
1759
1760 return CJS_Result::Success(pRuntime->NewBoolean(
1761 !!(pFormField->GetFieldFlags() & pdfium::form_flags::kTextRichText)));
1762 }
1763
set_rich_text(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1764 CJS_Result CJS_Field::set_rich_text(CJS_Runtime* pRuntime,
1765 v8::Local<v8::Value> vp) {
1766 DCHECK(m_pFormFillEnv);
1767 if (!m_bCanSet)
1768 return CJS_Result::Failure(JSMessage::kReadOnlyError);
1769 return CJS_Result::Success();
1770 }
1771
get_rich_value(CJS_Runtime * pRuntime)1772 CJS_Result CJS_Field::get_rich_value(CJS_Runtime* pRuntime) {
1773 return CJS_Result::Success();
1774 }
1775
set_rich_value(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1776 CJS_Result CJS_Field::set_rich_value(CJS_Runtime* pRuntime,
1777 v8::Local<v8::Value> vp) {
1778 return CJS_Result::Success();
1779 }
1780
get_rotation(CJS_Runtime * pRuntime)1781 CJS_Result CJS_Field::get_rotation(CJS_Runtime* pRuntime) {
1782 DCHECK(m_pFormFillEnv);
1783
1784 CPDF_FormField* pFormField = GetFirstFormField();
1785 if (!pFormField)
1786 return CJS_Result::Failure(JSMessage::kBadObjectError);
1787
1788 CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
1789 if (!pFormControl)
1790 return CJS_Result::Failure(JSMessage::kBadObjectError);
1791
1792 return CJS_Result::Success(pRuntime->NewNumber(pFormControl->GetRotation()));
1793 }
1794
set_rotation(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1795 CJS_Result CJS_Field::set_rotation(CJS_Runtime* pRuntime,
1796 v8::Local<v8::Value> vp) {
1797 DCHECK(m_pFormFillEnv);
1798 if (!m_bCanSet)
1799 return CJS_Result::Failure(JSMessage::kReadOnlyError);
1800 return CJS_Result::Success();
1801 }
1802
get_source(CJS_Runtime * pRuntime)1803 CJS_Result CJS_Field::get_source(CJS_Runtime* pRuntime) {
1804 return CJS_Result::Success();
1805 }
1806
set_source(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1807 CJS_Result CJS_Field::set_source(CJS_Runtime* pRuntime,
1808 v8::Local<v8::Value> vp) {
1809 return CJS_Result::Success();
1810 }
1811
get_stroke_color(CJS_Runtime * pRuntime)1812 CJS_Result CJS_Field::get_stroke_color(CJS_Runtime* pRuntime) {
1813 CPDF_FormField* pFormField = GetFirstFormField();
1814 if (!pFormField)
1815 return CJS_Result::Failure(JSMessage::kBadObjectError);
1816
1817 CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
1818 if (!pFormControl)
1819 return CJS_Result::Failure(JSMessage::kBadObjectError);
1820
1821 CFX_Color color = GetFormControlColor(pFormControl, pdfium::appearance::kBC);
1822 v8::Local<v8::Value> array =
1823 CJS_Color::ConvertPWLColorToArray(pRuntime, color);
1824 if (array.IsEmpty())
1825 return CJS_Result::Success(pRuntime->NewArray());
1826 return CJS_Result::Success(array);
1827 }
1828
set_stroke_color(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1829 CJS_Result CJS_Field::set_stroke_color(CJS_Runtime* pRuntime,
1830 v8::Local<v8::Value> vp) {
1831 if (!m_bCanSet)
1832 return CJS_Result::Failure(JSMessage::kReadOnlyError);
1833 if (!fxv8::IsArray(vp))
1834 return CJS_Result::Failure(JSMessage::kBadObjectError);
1835 return CJS_Result::Success();
1836 }
1837
get_style(CJS_Runtime * pRuntime)1838 CJS_Result CJS_Field::get_style(CJS_Runtime* pRuntime) {
1839 DCHECK(m_pFormFillEnv);
1840
1841 CPDF_FormField* pFormField = GetFirstFormField();
1842 if (!pFormField)
1843 return CJS_Result::Failure(JSMessage::kBadObjectError);
1844
1845 if (!IsCheckBoxOrRadioButton(pFormField))
1846 return CJS_Result::Failure(JSMessage::kObjectTypeError);
1847
1848 CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
1849 if (!pFormControl)
1850 return CJS_Result::Failure(JSMessage::kBadObjectError);
1851
1852 wchar_t selector = GetSelectorFromCaptionForFieldType(
1853 pFormControl->GetNormalCaption(), pFormControl->GetType());
1854
1855 ByteString csBCaption;
1856 switch (selector) {
1857 case kCircleSelector:
1858 csBCaption = "circle";
1859 break;
1860 case kCrossSelector:
1861 csBCaption = "cross";
1862 break;
1863 case kDiamondSelector:
1864 csBCaption = "diamond";
1865 break;
1866 case kSquareSelector:
1867 csBCaption = "square";
1868 break;
1869 case kStarSelector:
1870 csBCaption = "star";
1871 break;
1872 case kCheckSelector:
1873 default:
1874 csBCaption = "check";
1875 break;
1876 }
1877 return CJS_Result::Success(pRuntime->NewString(csBCaption.AsStringView()));
1878 }
1879
set_style(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1880 CJS_Result CJS_Field::set_style(CJS_Runtime* pRuntime,
1881 v8::Local<v8::Value> vp) {
1882 DCHECK(m_pFormFillEnv);
1883 if (!m_bCanSet)
1884 return CJS_Result::Failure(JSMessage::kReadOnlyError);
1885 return CJS_Result::Success();
1886 }
1887
get_submit_name(CJS_Runtime * pRuntime)1888 CJS_Result CJS_Field::get_submit_name(CJS_Runtime* pRuntime) {
1889 return CJS_Result::Success();
1890 }
1891
set_submit_name(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1892 CJS_Result CJS_Field::set_submit_name(CJS_Runtime* pRuntime,
1893 v8::Local<v8::Value> vp) {
1894 return CJS_Result::Success();
1895 }
1896
get_text_color(CJS_Runtime * pRuntime)1897 CJS_Result CJS_Field::get_text_color(CJS_Runtime* pRuntime) {
1898 CPDF_FormField* pFormField = GetFirstFormField();
1899 if (!pFormField)
1900 return CJS_Result::Failure(JSMessage::kBadObjectError);
1901
1902 CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
1903 if (!pFormControl)
1904 return CJS_Result::Failure(JSMessage::kBadObjectError);
1905
1906 CPDF_DefaultAppearance FieldAppearance = pFormControl->GetDefaultAppearance();
1907 absl::optional<CFX_Color::TypeAndARGB> maybe_type_argb_pair =
1908 FieldAppearance.GetColorARGB();
1909
1910 CFX_Color crRet;
1911 if (maybe_type_argb_pair.has_value() &&
1912 maybe_type_argb_pair.value().color_type !=
1913 CFX_Color::Type::kTransparent) {
1914 int32_t a;
1915 int32_t r;
1916 int32_t g;
1917 int32_t b;
1918 std::tie(a, r, g, b) = ArgbDecode(maybe_type_argb_pair.value().argb);
1919 crRet =
1920 CFX_Color(CFX_Color::Type::kRGB, r / 255.0f, g / 255.0f, b / 255.0f);
1921 }
1922
1923 v8::Local<v8::Value> array =
1924 CJS_Color::ConvertPWLColorToArray(pRuntime, crRet);
1925 if (array.IsEmpty())
1926 return CJS_Result::Success(pRuntime->NewArray());
1927 return CJS_Result::Success(array);
1928 }
1929
set_text_color(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1930 CJS_Result CJS_Field::set_text_color(CJS_Runtime* pRuntime,
1931 v8::Local<v8::Value> vp) {
1932 if (!m_bCanSet)
1933 return CJS_Result::Failure(JSMessage::kReadOnlyError);
1934 if (!fxv8::IsArray(vp))
1935 return CJS_Result::Failure(JSMessage::kBadObjectError);
1936 return CJS_Result::Success();
1937 }
1938
get_text_font(CJS_Runtime * pRuntime)1939 CJS_Result CJS_Field::get_text_font(CJS_Runtime* pRuntime) {
1940 DCHECK(m_pFormFillEnv);
1941
1942 CPDF_FormField* pFormField = GetFirstFormField();
1943 if (!pFormField)
1944 return CJS_Result::Failure(JSMessage::kBadObjectError);
1945
1946 CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
1947 if (!pFormControl)
1948 return CJS_Result::Failure(JSMessage::kBadObjectError);
1949
1950 FormFieldType fieldType = pFormField->GetFieldType();
1951 if (fieldType != FormFieldType::kPushButton &&
1952 fieldType != FormFieldType::kComboBox &&
1953 fieldType != FormFieldType::kListBox &&
1954 fieldType != FormFieldType::kTextField) {
1955 return CJS_Result::Failure(JSMessage::kObjectTypeError);
1956 }
1957
1958 absl::optional<WideString> wsFontName =
1959 pFormControl->GetDefaultControlFontName();
1960 if (!wsFontName.has_value())
1961 return CJS_Result::Failure(JSMessage::kBadObjectError);
1962
1963 return CJS_Result::Success(
1964 pRuntime->NewString(wsFontName.value().AsStringView()));
1965 }
1966
set_text_font(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1967 CJS_Result CJS_Field::set_text_font(CJS_Runtime* pRuntime,
1968 v8::Local<v8::Value> vp) {
1969 DCHECK(m_pFormFillEnv);
1970
1971 if (!m_bCanSet)
1972 return CJS_Result::Failure(JSMessage::kReadOnlyError);
1973 if (pRuntime->ToByteString(vp).IsEmpty())
1974 return CJS_Result::Failure(JSMessage::kValueError);
1975 return CJS_Result::Success();
1976 }
1977
get_text_size(CJS_Runtime * pRuntime)1978 CJS_Result CJS_Field::get_text_size(CJS_Runtime* pRuntime) {
1979 DCHECK(m_pFormFillEnv);
1980
1981 CPDF_FormField* pFormField = GetFirstFormField();
1982 if (!pFormField)
1983 return CJS_Result::Failure(JSMessage::kBadObjectError);
1984
1985 CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
1986 if (!pFormControl)
1987 return CJS_Result::Failure(JSMessage::kBadObjectError);
1988
1989 float fFontSize;
1990 CPDF_DefaultAppearance FieldAppearance = pFormControl->GetDefaultAppearance();
1991 FieldAppearance.GetFont(&fFontSize);
1992 return CJS_Result::Success(pRuntime->NewNumber(static_cast<int>(fFontSize)));
1993 }
1994
set_text_size(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)1995 CJS_Result CJS_Field::set_text_size(CJS_Runtime* pRuntime,
1996 v8::Local<v8::Value> vp) {
1997 DCHECK(m_pFormFillEnv);
1998 if (!m_bCanSet)
1999 return CJS_Result::Failure(JSMessage::kReadOnlyError);
2000 return CJS_Result::Success();
2001 }
2002
get_type(CJS_Runtime * pRuntime)2003 CJS_Result CJS_Field::get_type(CJS_Runtime* pRuntime) {
2004 CPDF_FormField* pFormField = GetFirstFormField();
2005 if (!pFormField)
2006 return CJS_Result::Failure(JSMessage::kBadObjectError);
2007
2008 switch (pFormField->GetFieldType()) {
2009 case FormFieldType::kUnknown:
2010 return CJS_Result::Success(pRuntime->NewString("unknown"));
2011 case FormFieldType::kPushButton:
2012 return CJS_Result::Success(pRuntime->NewString("button"));
2013 case FormFieldType::kCheckBox:
2014 return CJS_Result::Success(pRuntime->NewString("checkbox"));
2015 case FormFieldType::kRadioButton:
2016 return CJS_Result::Success(pRuntime->NewString("radiobutton"));
2017 case FormFieldType::kComboBox:
2018 return CJS_Result::Success(pRuntime->NewString("combobox"));
2019 case FormFieldType::kListBox:
2020 return CJS_Result::Success(pRuntime->NewString("listbox"));
2021 case FormFieldType::kTextField:
2022 return CJS_Result::Success(pRuntime->NewString("text"));
2023 case FormFieldType::kSignature:
2024 return CJS_Result::Success(pRuntime->NewString("signature"));
2025 #ifdef PDF_ENABLE_XFA
2026 default:
2027 return CJS_Result::Success(pRuntime->NewString("unknown"));
2028 #endif
2029 }
2030 }
2031
set_type(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)2032 CJS_Result CJS_Field::set_type(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
2033 return CJS_Result::Failure(JSMessage::kNotSupportedError);
2034 }
2035
get_user_name(CJS_Runtime * pRuntime)2036 CJS_Result CJS_Field::get_user_name(CJS_Runtime* pRuntime) {
2037 DCHECK(m_pFormFillEnv);
2038
2039 CPDF_FormField* pFormField = GetFirstFormField();
2040 if (!pFormField)
2041 return CJS_Result::Failure(JSMessage::kBadObjectError);
2042
2043 return CJS_Result::Success(
2044 pRuntime->NewString(pFormField->GetAlternateName().AsStringView()));
2045 }
2046
set_user_name(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)2047 CJS_Result CJS_Field::set_user_name(CJS_Runtime* pRuntime,
2048 v8::Local<v8::Value> vp) {
2049 DCHECK(m_pFormFillEnv);
2050 if (!m_bCanSet)
2051 return CJS_Result::Failure(JSMessage::kReadOnlyError);
2052 return CJS_Result::Success();
2053 }
2054
get_value(CJS_Runtime * pRuntime)2055 CJS_Result CJS_Field::get_value(CJS_Runtime* pRuntime) {
2056 CPDF_FormField* pFormField = GetFirstFormField();
2057 if (!pFormField)
2058 return CJS_Result::Failure(JSMessage::kBadObjectError);
2059
2060 v8::Local<v8::Value> ret;
2061 switch (pFormField->GetFieldType()) {
2062 case FormFieldType::kPushButton:
2063 return CJS_Result::Failure(JSMessage::kObjectTypeError);
2064 case FormFieldType::kComboBox:
2065 case FormFieldType::kTextField:
2066 ret = pRuntime->NewString(pFormField->GetValue().AsStringView());
2067 break;
2068 case FormFieldType::kListBox: {
2069 if (pFormField->CountSelectedItems() > 1) {
2070 v8::Local<v8::Array> ValueArray = pRuntime->NewArray();
2071 v8::Local<v8::Value> ElementValue;
2072 int iIndex;
2073 for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz; i++) {
2074 iIndex = pFormField->GetSelectedIndex(i);
2075 ElementValue = pRuntime->NewString(
2076 pFormField->GetOptionValue(iIndex).AsStringView());
2077 if (pRuntime->ToWideString(ElementValue).IsEmpty()) {
2078 ElementValue = pRuntime->NewString(
2079 pFormField->GetOptionLabel(iIndex).AsStringView());
2080 }
2081 pRuntime->PutArrayElement(ValueArray, i, ElementValue);
2082 }
2083 ret = ValueArray;
2084 } else {
2085 ret = pRuntime->NewString(pFormField->GetValue().AsStringView());
2086 }
2087 break;
2088 }
2089 case FormFieldType::kCheckBox:
2090 case FormFieldType::kRadioButton: {
2091 bool bFind = false;
2092 for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
2093 if (pFormField->GetControl(i)->IsChecked()) {
2094 ret = pRuntime->NewString(
2095 pFormField->GetControl(i)->GetExportValue().AsStringView());
2096 bFind = true;
2097 break;
2098 }
2099 }
2100 if (!bFind)
2101 ret = pRuntime->NewString("Off");
2102
2103 break;
2104 }
2105 default:
2106 ret = pRuntime->NewString(pFormField->GetValue().AsStringView());
2107 break;
2108 }
2109 return CJS_Result::Success(pRuntime->MaybeCoerceToNumber(ret));
2110 }
2111
set_value(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)2112 CJS_Result CJS_Field::set_value(CJS_Runtime* pRuntime,
2113 v8::Local<v8::Value> vp) {
2114 if (!m_bCanSet)
2115 return CJS_Result::Failure(JSMessage::kReadOnlyError);
2116
2117 std::vector<WideString> strArray;
2118 if (fxv8::IsArray(vp)) {
2119 v8::Local<v8::Array> ValueArray = pRuntime->ToArray(vp);
2120 for (size_t i = 0; i < pRuntime->GetArrayLength(ValueArray); i++) {
2121 strArray.push_back(
2122 pRuntime->ToWideString(pRuntime->GetArrayElement(ValueArray, i)));
2123 }
2124 } else {
2125 strArray.push_back(pRuntime->ToWideString(vp));
2126 }
2127
2128 if (m_bDelay) {
2129 AddDelay_WideStringArray(FP_VALUE, strArray);
2130 } else {
2131 SetFieldValue(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex,
2132 strArray);
2133 }
2134 return CJS_Result::Success();
2135 }
2136
get_value_as_string(CJS_Runtime * pRuntime)2137 CJS_Result CJS_Field::get_value_as_string(CJS_Runtime* pRuntime) {
2138 CPDF_FormField* pFormField = GetFirstFormField();
2139 if (!pFormField)
2140 return CJS_Result::Failure(JSMessage::kBadObjectError);
2141
2142 if (pFormField->GetFieldType() == FormFieldType::kPushButton)
2143 return CJS_Result::Failure(JSMessage::kObjectTypeError);
2144
2145 if (pFormField->GetFieldType() == FormFieldType::kCheckBox) {
2146 if (!pFormField->CountControls())
2147 return CJS_Result::Failure(JSMessage::kBadObjectError);
2148 return CJS_Result::Success(pRuntime->NewString(
2149 pFormField->GetControl(0)->IsChecked() ? L"Yes" : L"Off"));
2150 }
2151
2152 if (pFormField->GetFieldType() == FormFieldType::kRadioButton &&
2153 !(pFormField->GetFieldFlags() &
2154 pdfium::form_flags::kButtonRadiosInUnison)) {
2155 for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
2156 if (pFormField->GetControl(i)->IsChecked()) {
2157 return CJS_Result::Success(pRuntime->NewString(
2158 pFormField->GetControl(i)->GetExportValue().AsStringView()));
2159 }
2160 }
2161 return CJS_Result::Success(pRuntime->NewString("Off"));
2162 }
2163
2164 if (pFormField->GetFieldType() == FormFieldType::kListBox &&
2165 (pFormField->CountSelectedItems() > 1)) {
2166 return CJS_Result::Success(pRuntime->NewString(""));
2167 }
2168 return CJS_Result::Success(
2169 pRuntime->NewString(pFormField->GetValue().AsStringView()));
2170 }
2171
set_value_as_string(CJS_Runtime * pRuntime,v8::Local<v8::Value> vp)2172 CJS_Result CJS_Field::set_value_as_string(CJS_Runtime* pRuntime,
2173 v8::Local<v8::Value> vp) {
2174 return CJS_Result::Failure(JSMessage::kNotSupportedError);
2175 }
2176
browseForFileToSubmit(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)2177 CJS_Result CJS_Field::browseForFileToSubmit(
2178 CJS_Runtime* pRuntime,
2179 const std::vector<v8::Local<v8::Value>>& params) {
2180 CPDF_FormField* pFormField = GetFirstFormField();
2181 if (!pFormField)
2182 return CJS_Result::Failure(JSMessage::kBadObjectError);
2183
2184 if ((pFormField->GetFieldFlags() & pdfium::form_flags::kTextFileSelect) &&
2185 (pFormField->GetFieldType() == FormFieldType::kTextField)) {
2186 WideString wsFileName = m_pFormFillEnv->JS_fieldBrowse();
2187 if (!wsFileName.IsEmpty()) {
2188 pFormField->SetValue(wsFileName, NotificationOption::kDoNotNotify);
2189 UpdateFormField(m_pFormFillEnv.Get(), pFormField, true);
2190 }
2191 return CJS_Result::Success();
2192 }
2193 return CJS_Result::Failure(JSMessage::kObjectTypeError);
2194 }
2195
buttonGetCaption(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)2196 CJS_Result CJS_Field::buttonGetCaption(
2197 CJS_Runtime* pRuntime,
2198 const std::vector<v8::Local<v8::Value>>& params) {
2199 int nface = 0;
2200 if (params.size() >= 1)
2201 nface = pRuntime->ToInt32(params[0]);
2202
2203 CPDF_FormField* pFormField = GetFirstFormField();
2204 if (!pFormField)
2205 return CJS_Result::Failure(JSMessage::kBadObjectError);
2206
2207 if (pFormField->GetFieldType() != FormFieldType::kPushButton)
2208 return CJS_Result::Failure(JSMessage::kObjectTypeError);
2209
2210 CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
2211 if (!pFormControl)
2212 return CJS_Result::Failure(JSMessage::kBadObjectError);
2213
2214 if (nface == 0) {
2215 return CJS_Result::Success(
2216 pRuntime->NewString(pFormControl->GetNormalCaption().AsStringView()));
2217 }
2218 if (nface == 1) {
2219 return CJS_Result::Success(
2220 pRuntime->NewString(pFormControl->GetDownCaption().AsStringView()));
2221 }
2222 if (nface == 2) {
2223 return CJS_Result::Success(
2224 pRuntime->NewString(pFormControl->GetRolloverCaption().AsStringView()));
2225 }
2226 return CJS_Result::Failure(JSMessage::kValueError);
2227 }
2228
buttonGetIcon(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)2229 CJS_Result CJS_Field::buttonGetIcon(
2230 CJS_Runtime* pRuntime,
2231 const std::vector<v8::Local<v8::Value>>& params) {
2232 if (params.size() >= 1) {
2233 int nFace = pRuntime->ToInt32(params[0]);
2234 if (nFace < 0 || nFace > 2)
2235 return CJS_Result::Failure(JSMessage::kValueError);
2236 }
2237
2238 CPDF_FormField* pFormField = GetFirstFormField();
2239 if (!pFormField)
2240 return CJS_Result::Failure(JSMessage::kBadObjectError);
2241
2242 if (pFormField->GetFieldType() != FormFieldType::kPushButton)
2243 return CJS_Result::Failure(JSMessage::kObjectTypeError);
2244
2245 CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
2246 if (!pFormControl)
2247 return CJS_Result::Failure(JSMessage::kBadObjectError);
2248
2249 v8::Local<v8::Object> pObj = pRuntime->NewFXJSBoundObject(
2250 CJS_Icon::GetObjDefnID(), FXJSOBJTYPE_DYNAMIC);
2251 if (pObj.IsEmpty())
2252 return CJS_Result::Failure(JSMessage::kBadObjectError);
2253
2254 auto* pJS_Icon = static_cast<CJS_Icon*>(
2255 CFXJS_Engine::GetObjectPrivate(pRuntime->GetIsolate(), pObj));
2256 return pJS_Icon ? CJS_Result::Success(pJS_Icon->ToV8Object())
2257 : CJS_Result::Failure(JSMessage::kBadObjectError);
2258 }
2259
buttonImportIcon(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)2260 CJS_Result CJS_Field::buttonImportIcon(
2261 CJS_Runtime* pRuntime,
2262 const std::vector<v8::Local<v8::Value>>& params) {
2263 return CJS_Result::Success();
2264 }
2265
buttonSetCaption(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)2266 CJS_Result CJS_Field::buttonSetCaption(
2267 CJS_Runtime* pRuntime,
2268 const std::vector<v8::Local<v8::Value>>& params) {
2269 return CJS_Result::Failure(JSMessage::kNotSupportedError);
2270 }
2271
buttonSetIcon(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)2272 CJS_Result CJS_Field::buttonSetIcon(
2273 CJS_Runtime* pRuntime,
2274 const std::vector<v8::Local<v8::Value>>& params) {
2275 return CJS_Result::Failure(JSMessage::kNotSupportedError);
2276 }
2277
checkThisBox(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)2278 CJS_Result CJS_Field::checkThisBox(
2279 CJS_Runtime* pRuntime,
2280 const std::vector<v8::Local<v8::Value>>& params) {
2281 const size_t nSize = params.size();
2282 if (nSize == 0)
2283 return CJS_Result::Failure(JSMessage::kParamError);
2284
2285 if (!m_bCanSet)
2286 return CJS_Result::Failure(JSMessage::kReadOnlyError);
2287
2288 int nWidget = pRuntime->ToInt32(params[0]);
2289 bool bCheckit = true;
2290 if (nSize >= 2)
2291 bCheckit = pRuntime->ToBoolean(params[1]);
2292
2293 CPDF_FormField* pFormField = GetFirstFormField();
2294 if (!pFormField)
2295 return CJS_Result::Failure(JSMessage::kBadObjectError);
2296
2297 if (!IsCheckBoxOrRadioButton(pFormField))
2298 return CJS_Result::Failure(JSMessage::kObjectTypeError);
2299
2300 if (nWidget < 0 || nWidget >= pFormField->CountControls())
2301 return CJS_Result::Failure(JSMessage::kValueError);
2302
2303 // TODO(weili): Check whether anything special needed for radio button.
2304 // (When pFormField->GetFieldType() == FormFieldType::kRadioButton.)
2305 pFormField->CheckControl(nWidget, bCheckit, NotificationOption::kNotify);
2306 UpdateFormField(m_pFormFillEnv.Get(), pFormField, true);
2307 return CJS_Result::Success();
2308 }
2309
clearItems(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)2310 CJS_Result CJS_Field::clearItems(
2311 CJS_Runtime* pRuntime,
2312 const std::vector<v8::Local<v8::Value>>& params) {
2313 return CJS_Result::Success();
2314 }
2315
defaultIsChecked(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)2316 CJS_Result CJS_Field::defaultIsChecked(
2317 CJS_Runtime* pRuntime,
2318 const std::vector<v8::Local<v8::Value>>& params) {
2319 if (!m_bCanSet)
2320 return CJS_Result::Failure(JSMessage::kReadOnlyError);
2321
2322 if (params.empty())
2323 return CJS_Result::Failure(JSMessage::kParamError);
2324
2325 CPDF_FormField* pFormField = GetFirstFormField();
2326 if (!pFormField)
2327 return CJS_Result::Failure(JSMessage::kBadObjectError);
2328
2329 int nWidget = pRuntime->ToInt32(params[0]);
2330 if (nWidget < 0 || nWidget >= pFormField->CountControls())
2331 return CJS_Result::Failure(JSMessage::kValueError);
2332
2333 return CJS_Result::Success(
2334 pRuntime->NewBoolean(IsCheckBoxOrRadioButton(pFormField)));
2335 }
2336
deleteItemAt(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)2337 CJS_Result CJS_Field::deleteItemAt(
2338 CJS_Runtime* pRuntime,
2339 const std::vector<v8::Local<v8::Value>>& params) {
2340 return CJS_Result::Success();
2341 }
2342
getArray(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)2343 CJS_Result CJS_Field::getArray(
2344 CJS_Runtime* pRuntime,
2345 const std::vector<v8::Local<v8::Value>>& params) {
2346 std::vector<CPDF_FormField*> FieldArray = GetFormFields();
2347 if (FieldArray.empty())
2348 return CJS_Result::Failure(JSMessage::kBadObjectError);
2349
2350 std::vector<std::unique_ptr<WideString>> swSort;
2351 for (CPDF_FormField* pFormField : FieldArray) {
2352 swSort.push_back(std::make_unique<WideString>(pFormField->GetFullName()));
2353 }
2354
2355 std::sort(swSort.begin(), swSort.end(),
2356 [](const std::unique_ptr<WideString>& p1,
2357 const std::unique_ptr<WideString>& p2) { return *p1 < *p2; });
2358
2359 v8::Local<v8::Array> FormFieldArray = pRuntime->NewArray();
2360 int j = 0;
2361 for (const auto& pStr : swSort) {
2362 v8::Local<v8::Object> pObj = pRuntime->NewFXJSBoundObject(
2363 CJS_Field::GetObjDefnID(), FXJSOBJTYPE_DYNAMIC);
2364 if (pObj.IsEmpty())
2365 return CJS_Result::Failure(JSMessage::kBadObjectError);
2366
2367 auto* pJSField = static_cast<CJS_Field*>(
2368 CFXJS_Engine::GetObjectPrivate(pRuntime->GetIsolate(), pObj));
2369 pJSField->AttachField(m_pJSDoc.Get(), *pStr);
2370 pRuntime->PutArrayElement(FormFieldArray, j++,
2371 pJSField
2372 ? v8::Local<v8::Value>(pJSField->ToV8Object())
2373 : v8::Local<v8::Value>());
2374 }
2375 return CJS_Result::Success(FormFieldArray);
2376 }
2377
getItemAt(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)2378 CJS_Result CJS_Field::getItemAt(
2379 CJS_Runtime* pRuntime,
2380 const std::vector<v8::Local<v8::Value>>& params) {
2381 const size_t nSize = params.size();
2382 int nIdx = -1;
2383 if (nSize >= 1)
2384 nIdx = pRuntime->ToInt32(params[0]);
2385
2386 bool bExport = true;
2387 if (nSize >= 2)
2388 bExport = pRuntime->ToBoolean(params[1]);
2389
2390 CPDF_FormField* pFormField = GetFirstFormField();
2391 if (!pFormField)
2392 return CJS_Result::Failure(JSMessage::kBadObjectError);
2393
2394 if (!IsComboBoxOrListBox(pFormField))
2395 return CJS_Result::Failure(JSMessage::kObjectTypeError);
2396
2397 if (nIdx == -1 || nIdx > pFormField->CountOptions())
2398 nIdx = pFormField->CountOptions() - 1;
2399 if (!bExport) {
2400 return CJS_Result::Success(
2401 pRuntime->NewString(pFormField->GetOptionLabel(nIdx).AsStringView()));
2402 }
2403
2404 WideString strval = pFormField->GetOptionValue(nIdx);
2405 if (strval.IsEmpty()) {
2406 return CJS_Result::Success(
2407 pRuntime->NewString(pFormField->GetOptionLabel(nIdx).AsStringView()));
2408 }
2409 return CJS_Result::Success(pRuntime->NewString(strval.AsStringView()));
2410 }
2411
getLock(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)2412 CJS_Result CJS_Field::getLock(CJS_Runtime* pRuntime,
2413 const std::vector<v8::Local<v8::Value>>& params) {
2414 return CJS_Result::Failure(JSMessage::kNotSupportedError);
2415 }
2416
insertItemAt(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)2417 CJS_Result CJS_Field::insertItemAt(
2418 CJS_Runtime* pRuntime,
2419 const std::vector<v8::Local<v8::Value>>& params) {
2420 return CJS_Result::Success();
2421 }
2422
isBoxChecked(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)2423 CJS_Result CJS_Field::isBoxChecked(
2424 CJS_Runtime* pRuntime,
2425 const std::vector<v8::Local<v8::Value>>& params) {
2426 int nIndex = -1;
2427 if (params.size() >= 1)
2428 nIndex = pRuntime->ToInt32(params[0]);
2429
2430 CPDF_FormField* pFormField = GetFirstFormField();
2431 if (!pFormField)
2432 return CJS_Result::Failure(JSMessage::kBadObjectError);
2433
2434 if (nIndex < 0 || nIndex >= pFormField->CountControls())
2435 return CJS_Result::Failure(JSMessage::kValueError);
2436
2437 return CJS_Result::Success(
2438 pRuntime->NewBoolean((IsCheckBoxOrRadioButton(pFormField) &&
2439 pFormField->GetControl(nIndex)->IsChecked() != 0)));
2440 }
2441
isDefaultChecked(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)2442 CJS_Result CJS_Field::isDefaultChecked(
2443 CJS_Runtime* pRuntime,
2444 const std::vector<v8::Local<v8::Value>>& params) {
2445 int nIndex = -1;
2446 if (params.size() >= 1)
2447 nIndex = pRuntime->ToInt32(params[0]);
2448
2449 CPDF_FormField* pFormField = GetFirstFormField();
2450 if (!pFormField)
2451 return CJS_Result::Failure(JSMessage::kBadObjectError);
2452
2453 if (nIndex < 0 || nIndex >= pFormField->CountControls())
2454 return CJS_Result::Failure(JSMessage::kValueError);
2455
2456 return CJS_Result::Success(pRuntime->NewBoolean(
2457 (IsCheckBoxOrRadioButton(pFormField) &&
2458 pFormField->GetControl(nIndex)->IsDefaultChecked() != 0)));
2459 }
2460
setAction(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)2461 CJS_Result CJS_Field::setAction(
2462 CJS_Runtime* pRuntime,
2463 const std::vector<v8::Local<v8::Value>>& params) {
2464 return CJS_Result::Success();
2465 }
2466
setFocus(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)2467 CJS_Result CJS_Field::setFocus(
2468 CJS_Runtime* pRuntime,
2469 const std::vector<v8::Local<v8::Value>>& params) {
2470 CPDF_FormField* pFormField = GetFirstFormField();
2471 if (!pFormField)
2472 return CJS_Result::Failure(JSMessage::kBadObjectError);
2473
2474 int32_t nCount = pFormField->CountControls();
2475 if (nCount < 1)
2476 return CJS_Result::Failure(JSMessage::kBadObjectError);
2477
2478 CPDFSDK_InteractiveForm* pForm = m_pFormFillEnv->GetInteractiveForm();
2479 CPDFSDK_Widget* pWidget = nullptr;
2480 if (nCount == 1) {
2481 pWidget = pForm->GetWidget(pFormField->GetControl(0));
2482 } else {
2483 IPDF_Page* pPage = m_pFormFillEnv->GetCurrentPage();
2484 if (!pPage)
2485 return CJS_Result::Failure(JSMessage::kBadObjectError);
2486 CPDFSDK_PageView* pCurPageView = m_pFormFillEnv->GetOrCreatePageView(pPage);
2487 for (int32_t i = 0; i < nCount; i++) {
2488 if (CPDFSDK_Widget* pTempWidget =
2489 pForm->GetWidget(pFormField->GetControl(i))) {
2490 if (pTempWidget->GetPDFPage() == pCurPageView->GetPDFPage()) {
2491 pWidget = pTempWidget;
2492 break;
2493 }
2494 }
2495 }
2496 }
2497
2498 if (pWidget) {
2499 ObservedPtr<CPDFSDK_Annot> pObserved(pWidget);
2500 m_pFormFillEnv->SetFocusAnnot(pObserved);
2501 }
2502
2503 return CJS_Result::Success();
2504 }
2505
setItems(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)2506 CJS_Result CJS_Field::setItems(
2507 CJS_Runtime* pRuntime,
2508 const std::vector<v8::Local<v8::Value>>& params) {
2509 return CJS_Result::Success();
2510 }
2511
setLock(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)2512 CJS_Result CJS_Field::setLock(CJS_Runtime* pRuntime,
2513 const std::vector<v8::Local<v8::Value>>& params) {
2514 return CJS_Result::Failure(JSMessage::kNotSupportedError);
2515 }
2516
signatureGetModifications(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)2517 CJS_Result CJS_Field::signatureGetModifications(
2518 CJS_Runtime* pRuntime,
2519 const std::vector<v8::Local<v8::Value>>& params) {
2520 return CJS_Result::Failure(JSMessage::kNotSupportedError);
2521 }
2522
signatureGetSeedValue(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)2523 CJS_Result CJS_Field::signatureGetSeedValue(
2524 CJS_Runtime* pRuntime,
2525 const std::vector<v8::Local<v8::Value>>& params) {
2526 return CJS_Result::Failure(JSMessage::kNotSupportedError);
2527 }
2528
signatureInfo(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)2529 CJS_Result CJS_Field::signatureInfo(
2530 CJS_Runtime* pRuntime,
2531 const std::vector<v8::Local<v8::Value>>& params) {
2532 return CJS_Result::Failure(JSMessage::kNotSupportedError);
2533 }
2534
signatureSetSeedValue(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)2535 CJS_Result CJS_Field::signatureSetSeedValue(
2536 CJS_Runtime* pRuntime,
2537 const std::vector<v8::Local<v8::Value>>& params) {
2538 return CJS_Result::Failure(JSMessage::kNotSupportedError);
2539 }
2540
signatureSign(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)2541 CJS_Result CJS_Field::signatureSign(
2542 CJS_Runtime* pRuntime,
2543 const std::vector<v8::Local<v8::Value>>& params) {
2544 return CJS_Result::Failure(JSMessage::kNotSupportedError);
2545 }
2546
signatureValidate(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)2547 CJS_Result CJS_Field::signatureValidate(
2548 CJS_Runtime* pRuntime,
2549 const std::vector<v8::Local<v8::Value>>& params) {
2550 return CJS_Result::Failure(JSMessage::kNotSupportedError);
2551 }
2552
SetDelay(bool bDelay)2553 void CJS_Field::SetDelay(bool bDelay) {
2554 m_bDelay = bDelay;
2555 if (m_bDelay)
2556 return;
2557
2558 if (m_pJSDoc)
2559 m_pJSDoc->DoFieldDelay(m_FieldName, m_nFormControlIndex);
2560 }
2561
AddDelay_Int(FIELD_PROP prop,int32_t n)2562 void CJS_Field::AddDelay_Int(FIELD_PROP prop, int32_t n) {
2563 auto pNewData =
2564 std::make_unique<CJS_DelayData>(prop, m_nFormControlIndex, m_FieldName);
2565 pNewData->num = n;
2566 m_pJSDoc->AddDelayData(std::move(pNewData));
2567 }
2568
AddDelay_Bool(FIELD_PROP prop,bool b)2569 void CJS_Field::AddDelay_Bool(FIELD_PROP prop, bool b) {
2570 auto pNewData =
2571 std::make_unique<CJS_DelayData>(prop, m_nFormControlIndex, m_FieldName);
2572 pNewData->b = b;
2573 m_pJSDoc->AddDelayData(std::move(pNewData));
2574 }
2575
AddDelay_String(FIELD_PROP prop,const ByteString & str)2576 void CJS_Field::AddDelay_String(FIELD_PROP prop, const ByteString& str) {
2577 auto pNewData =
2578 std::make_unique<CJS_DelayData>(prop, m_nFormControlIndex, m_FieldName);
2579 pNewData->bytestring = str;
2580 m_pJSDoc->AddDelayData(std::move(pNewData));
2581 }
2582
AddDelay_Rect(FIELD_PROP prop,const CFX_FloatRect & rect)2583 void CJS_Field::AddDelay_Rect(FIELD_PROP prop, const CFX_FloatRect& rect) {
2584 auto pNewData =
2585 std::make_unique<CJS_DelayData>(prop, m_nFormControlIndex, m_FieldName);
2586 pNewData->rect = rect;
2587 m_pJSDoc->AddDelayData(std::move(pNewData));
2588 }
2589
AddDelay_WordArray(FIELD_PROP prop,const std::vector<uint32_t> & array)2590 void CJS_Field::AddDelay_WordArray(FIELD_PROP prop,
2591 const std::vector<uint32_t>& array) {
2592 auto pNewData =
2593 std::make_unique<CJS_DelayData>(prop, m_nFormControlIndex, m_FieldName);
2594 pNewData->wordarray = array;
2595 m_pJSDoc->AddDelayData(std::move(pNewData));
2596 }
2597
AddDelay_WideStringArray(FIELD_PROP prop,const std::vector<WideString> & array)2598 void CJS_Field::AddDelay_WideStringArray(FIELD_PROP prop,
2599 const std::vector<WideString>& array) {
2600 auto pNewData =
2601 std::make_unique<CJS_DelayData>(prop, m_nFormControlIndex, m_FieldName);
2602 pNewData->widestringarray = array;
2603 m_pJSDoc->AddDelayData(std::move(pNewData));
2604 }
2605
DoDelay(CPDFSDK_FormFillEnvironment * pFormFillEnv,CJS_DelayData * pData)2606 void CJS_Field::DoDelay(CPDFSDK_FormFillEnvironment* pFormFillEnv,
2607 CJS_DelayData* pData) {
2608 DCHECK(pFormFillEnv);
2609 switch (pData->eProp) {
2610 case FP_BORDERSTYLE:
2611 SetBorderStyle(pFormFillEnv, pData->sFieldName, pData->nControlIndex,
2612 pData->bytestring);
2613 break;
2614 case FP_CURRENTVALUEINDICES:
2615 SetCurrentValueIndices(pFormFillEnv, pData->sFieldName,
2616 pData->nControlIndex, pData->wordarray);
2617 break;
2618 case FP_DISPLAY:
2619 SetDisplay(pFormFillEnv, pData->sFieldName, pData->nControlIndex,
2620 pData->num);
2621 break;
2622 case FP_HIDDEN:
2623 SetHidden(pFormFillEnv, pData->sFieldName, pData->nControlIndex,
2624 pData->b);
2625 break;
2626 case FP_LINEWIDTH:
2627 SetLineWidth(pFormFillEnv, pData->sFieldName, pData->nControlIndex,
2628 pData->num);
2629 break;
2630 case FP_RECT:
2631 SetRect(pFormFillEnv, pData->sFieldName, pData->nControlIndex,
2632 pData->rect);
2633 break;
2634 case FP_VALUE:
2635 SetFieldValue(pFormFillEnv, pData->sFieldName, pData->nControlIndex,
2636 pData->widestringarray);
2637 break;
2638 }
2639 }
2640