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