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