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