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