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