tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

HTMLInputElement.h (58336B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef mozilla_dom_HTMLInputElement_h
      8 #define mozilla_dom_HTMLInputElement_h
      9 
     10 #include "mozilla/Attributes.h"
     11 #include "mozilla/Decimal.h"
     12 #include "mozilla/Maybe.h"
     13 #include "mozilla/TextControlElement.h"
     14 #include "mozilla/TextControlState.h"
     15 #include "mozilla/UniquePtr.h"
     16 #include "mozilla/Variant.h"
     17 #include "mozilla/dom/BindingDeclarations.h"
     18 #include "mozilla/dom/ButtonInputTypes.h"
     19 #include "mozilla/dom/CheckableInputTypes.h"
     20 #include "mozilla/dom/ColorInputType.h"
     21 #include "mozilla/dom/ConstraintValidation.h"
     22 #include "mozilla/dom/DateTimeInputTypes.h"
     23 #include "mozilla/dom/FileInputType.h"
     24 #include "mozilla/dom/HTMLInputElementBinding.h"
     25 #include "mozilla/dom/HiddenInputType.h"
     26 #include "mozilla/dom/NumericInputTypes.h"
     27 #include "mozilla/dom/Promise.h"
     28 #include "mozilla/dom/RadioGroupContainer.h"
     29 #include "mozilla/dom/SingleLineTextInputTypes.h"
     30 #include "nsCOMPtr.h"
     31 #include "nsContentUtils.h"
     32 #include "nsGenericHTMLElement.h"
     33 #include "nsIContentPrefService2.h"
     34 #include "nsIFilePicker.h"
     35 #include "nsImageLoadingContent.h"
     36 
     37 class nsIEditor;
     38 
     39 namespace mozilla {
     40 
     41 class EventChainPostVisitor;
     42 class EventChainPreVisitor;
     43 
     44 namespace dom {
     45 
     46 class AfterSetFilesOrDirectoriesRunnable;
     47 class Date;
     48 class DispatchChangeEventCallback;
     49 class File;
     50 class FileList;
     51 class FileSystemEntry;
     52 class FormData;
     53 class GetFilesHelper;
     54 class InputType;
     55 class OwningFileOrDirectory;
     56 
     57 /**
     58 * A class we use to create a singleton object that is used to keep track of
     59 * the last directory from which the user has picked files (via
     60 * <input type=file>) on a per-domain basis. The implementation uses
     61 * nsIContentPrefService2/NS_CONTENT_PREF_SERVICE_CONTRACTID to store the last
     62 * directory per-domain, and to ensure that whether the directories are
     63 * persistently saved (saved across sessions) or not honors whether or not the
     64 * page is being viewed in private browsing.
     65 */
     66 class UploadLastDir final : public nsIObserver, public nsSupportsWeakReference {
     67  ~UploadLastDir() = default;
     68 
     69 public:
     70  NS_DECL_ISUPPORTS
     71  NS_DECL_NSIOBSERVER
     72 
     73  /**
     74   * Fetch the last used directory for this location from the content
     75   * pref service, and display the file picker opened in that directory.
     76   *
     77   * @param aDoc          current document
     78   * @param aFilePicker   the file picker to open
     79   * @param aFpCallback   the callback object to be run when the file is shown.
     80   */
     81  nsresult FetchDirectoryAndDisplayPicker(
     82      Document* aDoc, nsIFilePicker* aFilePicker,
     83      nsIFilePickerShownCallback* aFpCallback);
     84 
     85  /**
     86   * Store the last used directory for this location using the
     87   * content pref service, if it is available
     88   * @param aURI URI of the current page
     89   * @param aDir Parent directory of the file(s)/directory chosen by the user
     90   */
     91  nsresult StoreLastUsedDirectory(Document* aDoc, nsIFile* aDir);
     92 
     93  class ContentPrefCallback final : public nsIContentPrefCallback2 {
     94    virtual ~ContentPrefCallback() = default;
     95 
     96   public:
     97    ContentPrefCallback(nsIFilePicker* aFilePicker,
     98                        nsIFilePickerShownCallback* aFpCallback)
     99        : mFilePicker(aFilePicker), mFpCallback(aFpCallback) {}
    100 
    101    NS_DECL_ISUPPORTS
    102    NS_DECL_NSICONTENTPREFCALLBACK2
    103 
    104    nsCOMPtr<nsIFilePicker> mFilePicker;
    105    nsCOMPtr<nsIFilePickerShownCallback> mFpCallback;
    106    nsCOMPtr<nsIContentPref> mResult;
    107  };
    108 };
    109 
    110 class HTMLInputElement final : public TextControlElement,
    111                               public nsImageLoadingContent,
    112                               public ConstraintValidation {
    113  friend class AfterSetFilesOrDirectoriesCallback;
    114  friend class DispatchChangeEventCallback;
    115  friend class InputType;
    116 
    117 public:
    118  using ConstraintValidation::GetValidationMessage;
    119  using nsGenericHTMLFormControlElementWithState::GetForm;
    120  using nsGenericHTMLFormControlElementWithState::GetFormAction;
    121  using ValueSetterOption = TextControlState::ValueSetterOption;
    122  using ValueSetterOptions = TextControlState::ValueSetterOptions;
    123 
    124  enum class FromClone { No, Yes };
    125 
    126  HTMLInputElement(already_AddRefed<dom::NodeInfo>&& aNodeInfo,
    127                   FromParser aFromParser,
    128                   FromClone aFromClone = FromClone::No);
    129 
    130  NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLInputElement, input)
    131 
    132  // nsISupports
    133  NS_DECL_ISUPPORTS_INHERITED
    134 
    135  int32_t TabIndexDefault() override;
    136  using nsGenericHTMLElement::Focus;
    137 
    138  // nsINode
    139 #if !defined(ANDROID) && !defined(XP_MACOSX)
    140  bool IsNodeApzAwareInternal() const override;
    141 #endif
    142 
    143  // Element
    144  bool IsInteractiveHTMLContent() const override;
    145 
    146  // nsGenericHTMLElement
    147  bool IsDisabledForEvents(WidgetEvent* aEvent) override;
    148 
    149  // nsGenericHTMLFormElement
    150  void SaveState() override;
    151  MOZ_CAN_RUN_SCRIPT_BOUNDARY bool RestoreState(PresState* aState) override;
    152 
    153  // EventTarget
    154  void AsyncEventRunning(AsyncEventDispatcher* aEvent) override;
    155 
    156  // Overriden nsIFormControl methods
    157  MOZ_CAN_RUN_SCRIPT_BOUNDARY
    158  NS_IMETHOD Reset() override;
    159  NS_IMETHOD SubmitNamesValues(FormData* aFormData) override;
    160 
    161  void FieldSetDisabledChanged(bool aNotify) override;
    162 
    163  // nsIContent
    164  bool IsHTMLFocusable(IsFocusableFlags, bool* aIsFocusable,
    165                       int32_t* aTabIndex) override;
    166 
    167  bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
    168                      const nsAString& aValue,
    169                      nsIPrincipal* aMaybeScriptedPrincipal,
    170                      nsAttrValue& aResult) override;
    171 
    172  // Note: if this returns false, then attributes may not yet be sanitized
    173  // (per SetValueInternal's dependence on mDoneCreating).
    174  bool IsDoneCreating() const { return mDoneCreating; }
    175 
    176  bool LastValueChangeWasInteractive() const {
    177    return mLastValueChangeWasInteractive;
    178  }
    179 
    180  void GetLastInteractiveValue(nsAString&);
    181 
    182  nsChangeHint GetAttributeChangeHint(const nsAtom* aAttribute,
    183                                      AttrModType aModType) const override;
    184  NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
    185  nsMapRuleToAttributesFunc GetAttributeMappingFunction() const override;
    186 
    187  void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
    188  void LegacyPreActivationBehavior(EventChainVisitor& aVisitor) override;
    189  MOZ_CAN_RUN_SCRIPT
    190  void ActivationBehavior(EventChainPostVisitor& aVisitor) override;
    191  void LegacyCanceledActivationBehavior(
    192      EventChainPostVisitor& aVisitor) override;
    193  MOZ_CAN_RUN_SCRIPT_BOUNDARY
    194  nsresult PreHandleEvent(EventChainVisitor& aVisitor) override;
    195  MOZ_CAN_RUN_SCRIPT_BOUNDARY
    196  nsresult PostHandleEvent(EventChainPostVisitor& aVisitor) override;
    197  MOZ_CAN_RUN_SCRIPT
    198  nsresult MaybeHandleRadioButtonNavigation(EventChainPostVisitor&,
    199                                            uint32_t aKeyCode);
    200  MOZ_CAN_RUN_SCRIPT_BOUNDARY
    201  void PostHandleEventForRangeThumb(EventChainPostVisitor& aVisitor);
    202  MOZ_CAN_RUN_SCRIPT
    203  void StartRangeThumbDrag(WidgetGUIEvent* aEvent);
    204  MOZ_CAN_RUN_SCRIPT
    205  void FinishRangeThumbDrag(WidgetGUIEvent* aEvent = nullptr);
    206  MOZ_CAN_RUN_SCRIPT
    207  void CancelRangeThumbDrag(bool aIsForUserEvent = true);
    208  MOZ_CAN_RUN_SCRIPT
    209  void MaybeDispatchWillBlur(EventChainVisitor&);
    210 
    211  enum class SnapToTickMarks : bool { No, Yes };
    212  MOZ_CAN_RUN_SCRIPT
    213  void SetValueOfRangeForUserEvent(Decimal aValue,
    214                                   SnapToTickMarks = SnapToTickMarks::No);
    215 
    216  nsresult BindToTree(BindContext&, nsINode& aParent) override;
    217  void UnbindFromTree(UnbindContext&) override;
    218 
    219  MOZ_CAN_RUN_SCRIPT_BOUNDARY
    220  void DoneCreatingElement() override;
    221 
    222  void DestroyContent() override;
    223 
    224  void SetLastValueChangeWasInteractive(bool);
    225 
    226  // TextControlElement
    227  bool IsSingleLineTextControlOrTextArea() const override {
    228    return IsSingleLineTextControl(false);
    229  }
    230  void SetValueChanged(bool aValueChanged) override;
    231  bool IsSingleLineTextControl() const override;
    232  bool IsTextArea() const override;
    233  bool IsPasswordTextControl() const override;
    234  Maybe<int32_t> GetCols() override;
    235  int32_t GetWrapCols() override;
    236  int32_t GetRows() override;
    237  void GetDefaultValueFromContent(nsAString& aValue, bool aForDisplay) override;
    238  bool ValueChanged() const override;
    239  void GetTextEditorValue(nsAString& aValue) const override;
    240  MOZ_CAN_RUN_SCRIPT TextEditor* GetTextEditor() override;
    241  TextEditor* GetExtantTextEditor() const override;
    242  nsISelectionController* GetSelectionController() override;
    243  nsFrameSelection* GetIndependentFrameSelection() const override;
    244  TextControlState* GetTextControlState() const override {
    245    return GetEditorState();
    246  }
    247  nsresult BindToFrame(nsTextControlFrame* aFrame) override;
    248  MOZ_CAN_RUN_SCRIPT void UnbindFromFrame(nsTextControlFrame* aFrame) override;
    249  MOZ_CAN_RUN_SCRIPT nsresult CreateEditor() override;
    250  void SetPreviewValue(const nsAString& aValue) override;
    251  void GetPreviewValue(nsAString& aValue) override;
    252  void SetAutofillState(const nsAString& aState) override {
    253    SetFormAutofillState(aState);
    254  }
    255  void GetAutofillState(nsAString& aState) override {
    256    GetFormAutofillState(aState);
    257  }
    258  void EnablePreview() override;
    259  bool IsPreviewEnabled() override;
    260  void InitializeKeyboardEventListeners() override;
    261  void OnValueChanged(ValueChangeKind, bool aNewValueEmpty,
    262                      const nsAString* aKnownNewValue) override;
    263  void GetValueFromSetRangeText(nsAString& aValue) override;
    264  MOZ_CAN_RUN_SCRIPT nsresult
    265  SetValueFromSetRangeText(const nsAString& aValue) override;
    266  bool HasCachedSelection() override;
    267  MOZ_CAN_RUN_SCRIPT void SetRevealPassword(bool aValue);
    268  bool RevealPassword() const;
    269 
    270  // Methods for nsFormFillController so it can do selection operations on input
    271  // types the HTML spec doesn't support them on, like "email".
    272  uint32_t GetSelectionStartIgnoringType(ErrorResult& aRv);
    273  uint32_t GetSelectionEndIgnoringType(ErrorResult& aRv);
    274 
    275  void GetDisplayFileName(nsAString& aFileName) const;
    276 
    277  const nsTArray<OwningFileOrDirectory>& GetFilesOrDirectoriesInternal() const;
    278 
    279  void SetFilesOrDirectories(
    280      const nsTArray<OwningFileOrDirectory>& aFilesOrDirectories,
    281      bool aSetValueChanged);
    282  void SetFiles(FileList* aFiles, bool aSetValueChanged);
    283 
    284  // This method is used for test only. Onces the data is set, a 'change' event
    285  // is dispatched.
    286  void MozSetDndFilesAndDirectories(
    287      const nsTArray<OwningFileOrDirectory>& aSequence);
    288 
    289  // Called when a nsIFilePicker or a nsIColorPicker terminate.
    290  void PickerClosed();
    291 
    292  void SetCheckedChangedInternal(bool aCheckedChanged);
    293  bool GetCheckedChanged() const { return mCheckedChanged; }
    294  void AddToRadioGroup();
    295  void RemoveFromRadioGroup();
    296  void DisconnectRadioGroupContainer();
    297  void UpdateRadioGroupState();
    298 
    299  /**
    300   * Helper function returning the currently selected button in the radio group.
    301   * Returning null if the element is not a button or if there is no selectied
    302   * button in the group.
    303   *
    304   * @return the selected button (or null).
    305   */
    306  HTMLInputElement* GetSelectedRadioButton() const;
    307 
    308  MOZ_CAN_RUN_SCRIPT_BOUNDARY
    309  nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
    310 
    311  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLInputElement, TextControlElement)
    312 
    313  static UploadLastDir* gUploadLastDir;
    314  // create and destroy the static UploadLastDir object for remembering
    315  // which directory was last used on a site-by-site basis
    316  static void InitUploadLastDir();
    317  static void DestroyUploadLastDir();
    318 
    319  // If the valueAsDate attribute should be enabled in webIDL
    320  static bool ValueAsDateEnabled(JSContext* cx, JSObject* obj);
    321 
    322  void MaybeLoadImage();
    323 
    324  bool HasPatternAttribute() const { return mHasPatternAttribute; }
    325 
    326  // nsIConstraintValidation
    327  bool IsTooLong();
    328  bool IsTooShort();
    329  bool IsValueMissing() const;
    330  bool HasTypeMismatch() const;
    331  Maybe<bool> HasPatternMismatch() const;
    332  bool IsRangeOverflow() const;
    333  bool IsRangeUnderflow() const;
    334  bool ValueIsStepMismatch(const Decimal& aValue) const;
    335  bool HasStepMismatch() const;
    336  bool HasBadInput() const;
    337  void UpdateTooLongValidityState();
    338  void UpdateTooShortValidityState();
    339  void UpdateValueMissingValidityState();
    340  void UpdateTypeMismatchValidityState();
    341  void UpdatePatternMismatchValidityState();
    342  void UpdateRangeOverflowValidityState();
    343  void UpdateRangeUnderflowValidityState();
    344  void UpdateStepMismatchValidityState();
    345  void UpdateBadInputValidityState();
    346  void UpdatePlaceholderShownState();
    347  void UpdateCheckedState(bool aNotify);
    348  void UpdateIndeterminateState(bool aNotify);
    349  // Update all our validity states and then update our element state
    350  // as needed.  aNotify controls whether the element state update
    351  // needs to notify.
    352  void UpdateAllValidityStates(bool aNotify);
    353  void UpdateValidityElementStates(bool aNotify);
    354  MOZ_CAN_RUN_SCRIPT
    355  void MaybeUpdateAllValidityStates(bool aNotify) {
    356    // If you need to add new type which supports validationMessage, you should
    357    // add test cases into test_MozEditableElement_setUserInput.html.
    358    if (mType == FormControlType::InputEmail) {
    359      UpdateAllValidityStates(aNotify);
    360    }
    361  }
    362 
    363  // Update all our validity states without updating element state.
    364  // This should be called instead of UpdateAllValidityStates any time
    365  // we're guaranteed that element state will be updated anyway.
    366  void UpdateAllValidityStatesButNotElementState();
    367  void UpdateBarredFromConstraintValidation();
    368  nsresult GetValidationMessage(nsAString& aValidationMessage,
    369                                ValidityStateType aType) override;
    370 
    371  // Override SetCustomValidity so we update our state properly when it's called
    372  // via bindings.
    373  void SetCustomValidity(const nsAString& aError);
    374 
    375  /**
    376   * Update the value missing validity state for radio elements when they have
    377   * a group.
    378   *
    379   * @param aIgnoreSelf Whether the required attribute and the checked state
    380   * of the current radio should be ignored.
    381   * @note This method shouldn't be called if the radio element hasn't a group.
    382   */
    383  void UpdateValueMissingValidityStateForRadio(bool aIgnoreSelf);
    384 
    385  /**
    386   * Set filters to the filePicker according to the accept attribute value.
    387   *
    388   * See:
    389   * http://dev.w3.org/html5/spec/forms.html#attr-input-accept
    390   *
    391   * @note You should not call this function if the element has no @accept.
    392   * @note "All Files" filter is always set, no matter if there is a valid
    393   * filter specified or not.
    394   * @note If more than one valid filter is found, the "All Supported Types"
    395   * filter is added, which is the concatenation of all valid filters.
    396   * @note Duplicate filters and similar filters (i.e. filters whose file
    397   * extensions already exist in another filter) are ignored.
    398   * @note "All Files" filter will be selected by default if unknown mime types
    399   * have been specified and no file extension filter has been specified.
    400   * Otherwise, specified filter or "All Supported Types" filter will be
    401   * selected by default.
    402   * The logic behind is that having unknown mime type means we might restrict
    403   * user's input too much, as some filters will be missing.
    404   * However, if author has also specified some file extension filters, it's
    405   * likely those are fallback for the unusual mime type we haven't been able
    406   * to resolve; so it's better to select author specified filters in that case.
    407   */
    408  void SetFilePickerFiltersFromAccept(nsIFilePicker* filePicker);
    409 
    410  void SetUserInteracted(bool) final;
    411 
    412  /**
    413   * Fires change event if mFocusedValue and current value held are unequal and
    414   * if a change event may be fired on bluring.
    415   * Sets mFocusedValue to value, if a change event is fired.
    416   */
    417  void FireChangeEventIfNeeded();
    418 
    419  /**
    420   * Returns the input element's value as a Decimal.
    421   * Returns NaN if the current element's value is not a floating point number.
    422   *
    423   * @return the input element's value as a Decimal.
    424   */
    425  Decimal GetValueAsDecimal() const;
    426 
    427  /**
    428   * Returns the input's "minimum" (as defined by the HTML5 spec) as a double.
    429   * Note this takes account of any default minimum that the type may have.
    430   * Returns NaN if the min attribute isn't a valid floating point number and
    431   * the input's type does not have a default minimum.
    432   *
    433   * NOTE: Only call this if you know DoesMinMaxApply() returns true.
    434   */
    435  Decimal GetMinimum() const;
    436 
    437  /**
    438   * Returns the input's "maximum" (as defined by the HTML5 spec) as a double.
    439   * Note this takes account of any default maximum that the type may have.
    440   * Returns NaN if the max attribute isn't a valid floating point number and
    441   * the input's type does not have a default maximum.
    442   *
    443   * NOTE:Only call this if you know DoesMinMaxApply() returns true.
    444   */
    445  Decimal GetMaximum() const;
    446 
    447  // WebIDL
    448 
    449  void GetAccept(nsAString& aValue) { GetHTMLAttr(nsGkAtoms::accept, aValue); }
    450  void SetAccept(const nsAString& aValue, ErrorResult& aRv) {
    451    SetHTMLAttr(nsGkAtoms::accept, aValue, aRv);
    452  }
    453 
    454  void GetAlt(nsAString& aValue) { GetHTMLAttr(nsGkAtoms::alt, aValue); }
    455  void SetAlt(const nsAString& aValue, ErrorResult& aRv) {
    456    SetHTMLAttr(nsGkAtoms::alt, aValue, aRv);
    457  }
    458 
    459  void GetAutocomplete(nsAString& aValue);
    460  void SetAutocomplete(const nsAString& aValue, ErrorResult& aRv) {
    461    SetHTMLAttr(nsGkAtoms::autocomplete, aValue, aRv);
    462  }
    463 
    464  void GetAutocompleteInfo(Nullable<AutocompleteInfo>& aInfo);
    465 
    466  void GetCapture(nsAString& aValue);
    467  void SetCapture(const nsAString& aValue, ErrorResult& aRv) {
    468    SetHTMLAttr(nsGkAtoms::capture, aValue, aRv);
    469  }
    470 
    471  bool DefaultChecked() const { return HasAttr(nsGkAtoms::checked); }
    472 
    473  void SetDefaultChecked(bool aValue, ErrorResult& aRv) {
    474    SetHTMLBoolAttr(nsGkAtoms::checked, aValue, aRv);
    475  }
    476 
    477  bool Checked() const { return mChecked; }
    478  void SetChecked(bool aChecked);
    479 
    480  bool IsRadioOrCheckbox() const {
    481    return mType == FormControlType::InputCheckbox ||
    482           mType == FormControlType::InputRadio;
    483  }
    484 
    485  bool IsInputColor() const { return mType == FormControlType::InputColor; }
    486 
    487  bool Disabled() const { return GetBoolAttr(nsGkAtoms::disabled); }
    488 
    489  void SetDisabled(bool aValue, ErrorResult& aRv) {
    490    SetHTMLBoolAttr(nsGkAtoms::disabled, aValue, aRv);
    491  }
    492 
    493  FileList* GetFiles();
    494  void SetFiles(FileList* aFiles);
    495 
    496  void SetFormAction(const nsAString& aValue, ErrorResult& aRv) {
    497    SetHTMLAttr(nsGkAtoms::formaction, aValue, aRv);
    498  }
    499 
    500  void GetFormEnctype(nsAString& aValue);
    501  void SetFormEnctype(const nsAString& aValue, ErrorResult& aRv) {
    502    SetHTMLAttr(nsGkAtoms::formenctype, aValue, aRv);
    503  }
    504 
    505  void GetFormMethod(nsAString& aValue);
    506  void SetFormMethod(const nsAString& aValue, ErrorResult& aRv) {
    507    SetHTMLAttr(nsGkAtoms::formmethod, aValue, aRv);
    508  }
    509 
    510  bool FormNoValidate() const { return GetBoolAttr(nsGkAtoms::formnovalidate); }
    511 
    512  void SetFormNoValidate(bool aValue, ErrorResult& aRv) {
    513    SetHTMLBoolAttr(nsGkAtoms::formnovalidate, aValue, aRv);
    514  }
    515 
    516  void GetFormTarget(nsAString& aValue) {
    517    GetHTMLAttr(nsGkAtoms::formtarget, aValue);
    518  }
    519  void SetFormTarget(const nsAString& aValue, ErrorResult& aRv) {
    520    SetHTMLAttr(nsGkAtoms::formtarget, aValue, aRv);
    521  }
    522 
    523  MOZ_CAN_RUN_SCRIPT uint32_t Height();
    524 
    525  void SetHeight(uint32_t aValue, ErrorResult& aRv) {
    526    SetUnsignedIntAttr(nsGkAtoms::height, aValue, 0, aRv);
    527  }
    528 
    529  bool Indeterminate() const { return mIndeterminate; }
    530 
    531  bool IsDraggingRange() const { return mIsDraggingRange; }
    532  void SetIndeterminate(bool aValue);
    533 
    534  HTMLDataListElement* GetList() const;
    535 
    536  void GetMax(nsAString& aValue) { GetHTMLAttr(nsGkAtoms::max, aValue); }
    537  void SetMax(const nsAString& aValue, ErrorResult& aRv) {
    538    SetHTMLAttr(nsGkAtoms::max, aValue, aRv);
    539  }
    540 
    541  int32_t MaxLength() const { return GetIntAttr(nsGkAtoms::maxlength, -1); }
    542 
    543  int32_t UsedMaxLength() const final {
    544    if (!mInputType->MinAndMaxLengthApply()) {
    545      return -1;
    546    }
    547    return MaxLength();
    548  }
    549 
    550  void SetMaxLength(int32_t aValue, ErrorResult& aRv) {
    551    int32_t minLength = MinLength();
    552    if (aValue < 0 || (minLength >= 0 && aValue < minLength)) {
    553      aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
    554      return;
    555    }
    556 
    557    SetHTMLIntAttr(nsGkAtoms::maxlength, aValue, aRv);
    558  }
    559 
    560  int32_t MinLength() const { return GetIntAttr(nsGkAtoms::minlength, -1); }
    561 
    562  void SetMinLength(int32_t aValue, ErrorResult& aRv) {
    563    int32_t maxLength = MaxLength();
    564    if (aValue < 0 || (maxLength >= 0 && aValue > maxLength)) {
    565      aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
    566      return;
    567    }
    568 
    569    SetHTMLIntAttr(nsGkAtoms::minlength, aValue, aRv);
    570  }
    571 
    572  void GetMin(nsAString& aValue) { GetHTMLAttr(nsGkAtoms::min, aValue); }
    573  void SetMin(const nsAString& aValue, ErrorResult& aRv) {
    574    SetHTMLAttr(nsGkAtoms::min, aValue, aRv);
    575  }
    576 
    577  bool Multiple() const { return GetBoolAttr(nsGkAtoms::multiple); }
    578 
    579  void SetMultiple(bool aValue, ErrorResult& aRv) {
    580    SetHTMLBoolAttr(nsGkAtoms::multiple, aValue, aRv);
    581  }
    582 
    583  void GetName(nsAString& aValue) { GetHTMLAttr(nsGkAtoms::name, aValue); }
    584  void SetName(const nsAString& aValue, ErrorResult& aRv) {
    585    SetHTMLAttr(nsGkAtoms::name, aValue, aRv);
    586  }
    587 
    588  void GetPattern(nsAString& aValue) {
    589    GetHTMLAttr(nsGkAtoms::pattern, aValue);
    590  }
    591  void SetPattern(const nsAString& aValue, ErrorResult& aRv) {
    592    SetHTMLAttr(nsGkAtoms::pattern, aValue, aRv);
    593  }
    594 
    595  void GetPlaceholder(nsAString& aValue) {
    596    GetHTMLAttr(nsGkAtoms::placeholder, aValue);
    597  }
    598  void SetPlaceholder(const nsAString& aValue, ErrorResult& aRv) {
    599    SetHTMLAttr(nsGkAtoms::placeholder, aValue, aRv);
    600  }
    601 
    602  bool ReadOnly() const { return GetBoolAttr(nsGkAtoms::readonly); }
    603 
    604  void SetReadOnly(bool aValue, ErrorResult& aRv) {
    605    SetHTMLBoolAttr(nsGkAtoms::readonly, aValue, aRv);
    606  }
    607 
    608  bool Required() const { return GetBoolAttr(nsGkAtoms::required); }
    609 
    610  void SetRequired(bool aValue, ErrorResult& aRv) {
    611    SetHTMLBoolAttr(nsGkAtoms::required, aValue, aRv);
    612  }
    613 
    614  uint32_t Size() const {
    615    return GetUnsignedIntAttr(nsGkAtoms::size, DEFAULT_COLS);
    616  }
    617 
    618  void SetSize(uint32_t aValue, ErrorResult& aRv) {
    619    if (aValue == 0) {
    620      aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
    621      return;
    622    }
    623 
    624    SetUnsignedIntAttr(nsGkAtoms::size, aValue, DEFAULT_COLS, aRv);
    625  }
    626 
    627  void GetSrc(nsAString& aValue) {
    628    GetURIAttr(nsGkAtoms::src, nullptr, aValue);
    629  }
    630  void SetSrc(const nsAString& aValue, nsIPrincipal* aTriggeringPrincipal,
    631              ErrorResult& aRv) {
    632    SetHTMLAttr(nsGkAtoms::src, aValue, aTriggeringPrincipal, aRv);
    633  }
    634 
    635  void GetStep(nsAString& aValue) { GetHTMLAttr(nsGkAtoms::step, aValue); }
    636  void SetStep(const nsAString& aValue, ErrorResult& aRv) {
    637    SetHTMLAttr(nsGkAtoms::step, aValue, aRv);
    638  }
    639 
    640  void GetType(nsAString& aValue) const;
    641  void SetType(const nsAString& aValue, ErrorResult& aRv) {
    642    SetHTMLAttr(nsGkAtoms::type, aValue, aRv);
    643  }
    644 
    645  void GetDefaultValue(nsAString& aValue) {
    646    GetHTMLAttr(nsGkAtoms::value, aValue);
    647  }
    648  void SetDefaultValue(const nsAString& aValue, ErrorResult& aRv) {
    649    SetHTMLAttr(nsGkAtoms::value, aValue, aRv);
    650  }
    651 
    652  MOZ_CAN_RUN_SCRIPT_BOUNDARY
    653  void SetValue(const nsAString& aValue, CallerType aCallerType,
    654                ErrorResult& aRv);
    655  void GetValue(nsAString& aValue, CallerType aCallerType);
    656 
    657  // Generic getter for the value that doesn't do experimental control type
    658  // sanitization.
    659  void GetValueInternal(nsAString& aValue, CallerType aCallerType) const;
    660 
    661  void GetValueAsDate(JSContext* aCx, JS::MutableHandle<JSObject*> aObj,
    662                      ErrorResult& aRv);
    663 
    664  void SetValueAsDate(JSContext* aCx, JS::Handle<JSObject*> aObj,
    665                      ErrorResult& aRv);
    666 
    667  double ValueAsNumber() const {
    668    return DoesValueAsNumberApply() ? GetValueAsDecimal().toDouble()
    669                                    : UnspecifiedNaN<double>();
    670  }
    671 
    672  void SetValueAsNumber(double aValue, ErrorResult& aRv);
    673 
    674  MOZ_CAN_RUN_SCRIPT uint32_t Width();
    675 
    676  void SetWidth(uint32_t aValue, ErrorResult& aRv) {
    677    SetUnsignedIntAttr(nsGkAtoms::width, aValue, 0, aRv);
    678  }
    679 
    680  void StepUp(int32_t aN, ErrorResult& aRv) { ApplyStep(aN, aRv); }
    681  void StepDown(int32_t aN, ErrorResult& aRv) { ApplyStep(-aN, aRv); }
    682 
    683  /**
    684   * Returns the current step value.
    685   * Returns kStepAny if the current step is "any" string.
    686   *
    687   * @return the current step value.
    688   */
    689  Decimal GetStep() const;
    690 
    691  // Returns whether the given keyboard event steps up or down the value of an
    692  // <input> element.
    693  bool StepsInputValue(const WidgetKeyboardEvent&) const;
    694 
    695  already_AddRefed<nsINodeList> GetLabels();
    696 
    697  MOZ_CAN_RUN_SCRIPT void Select();
    698 
    699  Nullable<uint32_t> GetSelectionStart(ErrorResult& aRv);
    700  MOZ_CAN_RUN_SCRIPT void SetSelectionStart(const Nullable<uint32_t>& aValue,
    701                                            ErrorResult& aRv);
    702 
    703  Nullable<uint32_t> GetSelectionEnd(ErrorResult& aRv);
    704  MOZ_CAN_RUN_SCRIPT void SetSelectionEnd(const Nullable<uint32_t>& aValue,
    705                                          ErrorResult& aRv);
    706 
    707  void GetSelectionDirection(nsAString& aValue, ErrorResult& aRv);
    708  MOZ_CAN_RUN_SCRIPT void SetSelectionDirection(const nsAString& aValue,
    709                                                ErrorResult& aRv);
    710 
    711  MOZ_CAN_RUN_SCRIPT void SetSelectionRange(
    712      uint32_t aStart, uint32_t aEnd, const Optional<nsAString>& direction,
    713      ErrorResult& aRv);
    714 
    715  MOZ_CAN_RUN_SCRIPT void SetRangeText(const nsAString& aReplacement,
    716                                       ErrorResult& aRv);
    717 
    718  MOZ_CAN_RUN_SCRIPT void SetRangeText(const nsAString& aReplacement,
    719                                       uint32_t aStart, uint32_t aEnd,
    720                                       SelectionMode aSelectMode,
    721                                       ErrorResult& aRv);
    722 
    723  MOZ_CAN_RUN_SCRIPT void ShowPicker(ErrorResult& aRv);
    724 
    725  bool WebkitDirectoryAttr() const {
    726    return HasAttr(nsGkAtoms::webkitdirectory);
    727  }
    728 
    729  void SetWebkitDirectoryAttr(bool aValue, ErrorResult& aRv) {
    730    SetHTMLBoolAttr(nsGkAtoms::webkitdirectory, aValue, aRv);
    731  }
    732 
    733  void GetWebkitEntries(nsTArray<RefPtr<FileSystemEntry>>& aSequence);
    734 
    735  already_AddRefed<Promise> GetFilesAndDirectories(ErrorResult& aRv);
    736 
    737  void GetAlign(nsAString& aValue) { GetHTMLAttr(nsGkAtoms::align, aValue); }
    738  void SetAlign(const nsAString& aValue, ErrorResult& aRv) {
    739    SetHTMLAttr(nsGkAtoms::align, aValue, aRv);
    740  }
    741 
    742  void GetUseMap(nsAString& aValue) { GetHTMLAttr(nsGkAtoms::usemap, aValue); }
    743  void SetUseMap(const nsAString& aValue, ErrorResult& aRv) {
    744    SetHTMLAttr(nsGkAtoms::usemap, aValue, aRv);
    745  }
    746 
    747  void GetDirName(nsAString& aValue) {
    748    GetHTMLAttr(nsGkAtoms::dirname, aValue);
    749  }
    750  void SetDirName(const nsAString& aValue, ErrorResult& aRv) {
    751    SetHTMLAttr(nsGkAtoms::dirname, aValue, aRv);
    752  }
    753 
    754  nsIControllers* GetControllers(ErrorResult& aRv);
    755  nsIControllers* GetExtantControllers() const { return mControllers; }
    756  // XPCOM adapter function widely used throughout code, leaving it as is.
    757  nsresult GetControllers(nsIControllers** aResult);
    758 
    759  int32_t InputTextLength(CallerType aCallerType);
    760 
    761  void MozGetFileNameArray(nsTArray<nsString>& aFileNames, ErrorResult& aRv);
    762 
    763  void MozSetFileNameArray(const Sequence<nsString>& aFileNames,
    764                           ErrorResult& aRv);
    765  void MozSetFileArray(const Sequence<OwningNonNull<File>>& aFiles);
    766  void MozSetDirectory(const nsAString& aDirectoryPath, ErrorResult& aRv);
    767 
    768  /*
    769   * The following functions are called from datetime picker to let input box
    770   * know the current state of the picker or to update the input box on changes.
    771   */
    772  void GetDateTimeInputBoxValue(DateTimeValue& aValue);
    773 
    774  /*
    775   * This allows chrome JavaScript to dispatch event to the inner datetimebox
    776   * anonymous or UA Widget element.
    777   */
    778  Element* GetDateTimeBoxElement();
    779 
    780  /*
    781   * The following functions are called from the datetimebox element to control
    782   * and update the picker.
    783   */
    784  void OpenDateTimePicker(const DateTimeValue& aInitialValue);
    785  void CloseDateTimePicker();
    786 
    787  /**
    788   * Sets open state for the input element, depending on whether the picker is
    789   * open or closed.
    790   */
    791  void SetOpenState(bool aIsOpen);
    792 
    793  void OpenColorPicker();
    794 
    795  /*
    796   * Called from datetime input box binding when inner text fields are focused
    797   * or blurred.
    798   */
    799  void SetFocusState(bool aIsFocused);
    800 
    801  /*
    802   * Called from datetime input box binding when the the user entered value
    803   * becomes valid/invalid.
    804   */
    805  void UpdateValidityState();
    806 
    807  /*
    808   * The following are called from datetime input box binding to get the
    809   * corresponding computed values.
    810   */
    811  double GetStepAsDouble() { return GetStep().toDouble(); }
    812  double GetStepBaseAsDouble() { return GetStepBase().toDouble(); }
    813  double GetMinimumAsDouble() { return GetMinimum().toDouble(); }
    814  double GetMaximumAsDouble() { return GetMaximum().toDouble(); }
    815 
    816  /**
    817   * Return the current value as InputPickerColor.
    818   */
    819  void GetColor(InputPickerColor& aValue);
    820 
    821  /**
    822   * Converts the InputPickerColor into a string and set it as user input.
    823   */
    824  void SetUserInputColor(const InputPickerColor& aValue);
    825 
    826  void StartNumberControlSpinnerSpin();
    827  enum SpinnerStopState { eAllowDispatchingEvents, eDisallowDispatchingEvents };
    828  void StopNumberControlSpinnerSpin(
    829      SpinnerStopState aState = eAllowDispatchingEvents);
    830  MOZ_CAN_RUN_SCRIPT
    831  void StepNumberControlForUserEvent(int32_t aDirection);
    832 
    833  /**
    834   * The callback function used by the nsRepeatService that we use to spin the
    835   * spinner for <input type=number>.
    836   */
    837  MOZ_CAN_RUN_SCRIPT_BOUNDARY
    838  static void HandleNumberControlSpin(void* aData);
    839 
    840  bool NumberSpinnerUpButtonIsDepressed() const {
    841    return mNumberControlSpinnerIsSpinning && mNumberControlSpinnerSpinsUp;
    842  }
    843 
    844  bool NumberSpinnerDownButtonIsDepressed() const {
    845    return mNumberControlSpinnerIsSpinning && !mNumberControlSpinnerSpinsUp;
    846  }
    847 
    848  bool MozIsTextField(bool aExcludePassword);
    849 
    850  MOZ_CAN_RUN_SCRIPT nsIEditor* GetEditorForBindings();
    851  // For WebIDL bindings.
    852  bool HasEditor() const;
    853 
    854  bool IsInputEventTarget() const { return IsSingleLineTextControl(false); }
    855 
    856  MOZ_CAN_RUN_SCRIPT_BOUNDARY
    857  void SetUserInput(const nsAString& aInput, nsIPrincipal& aSubjectPrincipal);
    858 
    859  /**
    860   * If aValue contains a valid floating-point number in the format specified
    861   * by the HTML 5 spec:
    862   *
    863   *   http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#floating-point-numbers
    864   *
    865   * then this function will return the number parsed as a Decimal, otherwise
    866   * it will return a Decimal for which Decimal::isFinite() will return false.
    867   */
    868  static Decimal StringToDecimal(const nsAString& aValue);
    869 
    870  void UpdateEntries(
    871      const nsTArray<OwningFileOrDirectory>& aFilesOrDirectories);
    872 
    873  /**
    874   * Returns if the required attribute applies for the current type.
    875   */
    876  bool DoesRequiredApply() const;
    877 
    878  /**
    879   * Returns the current required state of the element. This function differs
    880   * from Required() in that this function only returns true for input types
    881   * that @required attribute applies and the attribute is set; in contrast,
    882   * Required() returns true whenever @required attribute is set.
    883   */
    884  bool IsRequired() const { return State().HasState(ElementState::REQUIRED); }
    885 
    886  bool HasBeenTypePassword() const { return mHasBeenTypePassword; }
    887 
    888  /**
    889   * Returns whether the current value is the empty string.  This only makes
    890   * sense for some input types; does NOT make sense for file inputs.
    891   *
    892   * @return whether the current value is the empty string.
    893   */
    894  bool IsValueEmpty() const {
    895    return State().HasState(ElementState::VALUE_EMPTY);
    896  }
    897 
    898  // Parse a simple (hex) color.
    899  static mozilla::Maybe<nscolor> ParseSimpleColor(const nsAString& aColor);
    900 
    901  /**
    902   * https://html.spec.whatwg.org/#auto-directionality-form-associated-elements
    903   */
    904  bool IsAutoDirectionalityAssociated() const {
    905    return IsAutoDirectionalityAssociated(mType);
    906  }
    907 
    908 protected:
    909  MOZ_CAN_RUN_SCRIPT_BOUNDARY virtual ~HTMLInputElement();
    910 
    911  JSObject* WrapNode(JSContext* aCx,
    912                     JS::Handle<JSObject*> aGivenProto) override;
    913 
    914  // Pull IsSingleLineTextControl into our scope, otherwise it'd be hidden
    915  // by the TextControlElement version.
    916  using nsGenericHTMLFormControlElementWithState::IsSingleLineTextControl;
    917 
    918  /**
    919   * The ValueModeType specifies how the value IDL attribute should behave.
    920   *
    921   * See: http://dev.w3.org/html5/spec/forms.html#dom-input-value
    922   */
    923  enum ValueModeType {
    924    // On getting, returns the value.
    925    // On setting, sets value.
    926    VALUE_MODE_VALUE,
    927    // On getting, returns the value if present or the empty string.
    928    // On setting, sets the value.
    929    VALUE_MODE_DEFAULT,
    930    // On getting, returns the value if present or "on".
    931    // On setting, sets the value.
    932    VALUE_MODE_DEFAULT_ON,
    933    // On getting, returns "C:\fakepath\" followed by the file name of the
    934    // first file of the selected files if any.
    935    // On setting the empty string, empties the selected files list, otherwise
    936    // throw the INVALID_STATE_ERR exception.
    937    VALUE_MODE_FILENAME
    938  };
    939 
    940  /**
    941   * This helper method convert a sub-string that contains only digits to a
    942   * number (unsigned int given that it can't contain a minus sign).
    943   * This method will return whether the sub-string is correctly formatted
    944   * (ie. contains only digit) and it can be successfuly parsed to generate a
    945   * number).
    946   * If the method returns true, |aResult| will contained the parsed number.
    947   *
    948   * @param aValue  the string on which the sub-string will be extracted and
    949   * parsed.
    950   * @param aStart  the beginning of the sub-string in aValue.
    951   * @param aLen    the length of the sub-string.
    952   * @param aResult the parsed number.
    953   * @return whether the sub-string has been parsed successfully.
    954   */
    955  static bool DigitSubStringToNumber(const nsAString& aValue, uint32_t aStart,
    956                                     uint32_t aLen, uint32_t* aResult);
    957 
    958  // Helper method
    959 
    960  /**
    961   * Setting the value.
    962   *
    963   * @param aValue      String to set.
    964   * @param aOldValue   Previous value before setting aValue.
    965                        If previous value is unknown, aOldValue can be nullptr.
    966   * @param aOptions    See TextControlState::ValueSetterOption.
    967   */
    968  MOZ_CAN_RUN_SCRIPT nsresult
    969  SetValueInternal(const nsAString& aValue, const nsAString* aOldValue,
    970                   const ValueSetterOptions& aOptions);
    971  MOZ_CAN_RUN_SCRIPT nsresult SetValueInternal(
    972      const nsAString& aValue, const ValueSetterOptions& aOptions) {
    973    return SetValueInternal(aValue, nullptr, aOptions);
    974  }
    975 
    976  // A getter for callers that know we're not dealing with a file input, so they
    977  // don't have to think about the caller type.
    978  void GetNonFileValueInternal(nsAString& aValue) const;
    979 
    980  void ClearFiles(bool aSetValueChanged);
    981 
    982  void SetIndeterminateInternal(bool aValue, bool aShouldInvalidate);
    983 
    984  /**
    985   * Called when an attribute is about to be changed
    986   */
    987  void BeforeSetAttr(int32_t aNameSpaceID, nsAtom* aName,
    988                     const nsAttrValue* aValue, bool aNotify) override;
    989  /**
    990   * Called when an attribute has just been changed
    991   */
    992  MOZ_CAN_RUN_SCRIPT_BOUNDARY
    993  void AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
    994                    const nsAttrValue* aValue, const nsAttrValue* aOldValue,
    995                    nsIPrincipal* aSubjectPrincipal, bool aNotify) override;
    996 
    997  void BeforeSetForm(HTMLFormElement* aForm, bool aBindToTree) override;
    998 
    999  void AfterClearForm(bool aUnbindOrDelete) override;
   1000 
   1001  void ResultForDialogSubmit(nsAString& aResult) override;
   1002 
   1003  MOZ_CAN_RUN_SCRIPT void SelectAll();
   1004  bool IsImage() const {
   1005    return AttrValueIs(kNameSpaceID_None, nsGkAtoms::type, nsGkAtoms::image,
   1006                       eIgnoreCase);
   1007  }
   1008 
   1009  /**
   1010   * Visit the group of radio buttons this radio belongs to
   1011   * @param aCallback the callback function to visit the node
   1012   */
   1013  template <typename VisitCallback>
   1014  void VisitGroup(VisitCallback&& aCallback, bool aSkipThis = true);
   1015 
   1016  /**
   1017   * Do all the work that |SetChecked| does (radio button handling, etc.), but
   1018   * take an |aNotify| parameter.
   1019   */
   1020  void DoSetChecked(bool aValue, bool aNotify, bool aSetValueChanged,
   1021                    bool aUpdateOtherElement = true);
   1022 
   1023  /**
   1024   * Actually set checked and notify the frame of the change.
   1025   * @param aValue the value of checked to set
   1026   */
   1027  void SetCheckedInternal(bool aValue, bool aNotify);
   1028 
   1029  void RadioSetChecked(bool aNotify, bool aUpdateOtherElement);
   1030  void SetCheckedChanged(bool aCheckedChanged);
   1031 
   1032  /**
   1033   * MaybeSubmitForm looks for a submit input or a single text control
   1034   * and submits the form if either is present.
   1035   */
   1036  MOZ_CAN_RUN_SCRIPT void MaybeSubmitForm(nsPresContext* aPresContext);
   1037 
   1038  /**
   1039   * Called after calling one of the SetFilesOrDirectories() functions.
   1040   * This method can explore the directory recursively if needed.
   1041   */
   1042  void AfterSetFilesOrDirectories(bool aSetValueChanged);
   1043 
   1044  /**
   1045   * Recursively explore the directory and populate mFileOrDirectories correctly
   1046   * for webkitdirectory.
   1047   */
   1048  void ExploreDirectoryRecursively(bool aSetValuechanged);
   1049 
   1050  /**
   1051   * Determine whether the editor needs to be initialized explicitly for
   1052   * a particular event.
   1053   */
   1054  bool NeedToInitializeEditorForEvent(EventChainPreVisitor& aVisitor) const;
   1055 
   1056  /**
   1057   * Get the value mode of the element, depending of the type.
   1058   */
   1059  ValueModeType GetValueMode() const;
   1060 
   1061  /**
   1062   * Get the mutable state of the element.
   1063   * When the element isn't mutable (immutable), the value or checkedness
   1064   * should not be changed by the user.
   1065   *
   1066   * See: https://html.spec.whatwg.org/#concept-fe-mutable
   1067   */
   1068  bool IsMutable() const;
   1069 
   1070  /**
   1071   * Returns if the min and max attributes apply for the current type.
   1072   */
   1073  bool DoesMinMaxApply() const;
   1074 
   1075  /**
   1076   * Returns if the step attribute apply for the current type.
   1077   */
   1078  bool DoesStepApply() const { return DoesMinMaxApply(); }
   1079 
   1080  /**
   1081   * Returns if stepDown and stepUp methods apply for the current type.
   1082   */
   1083  bool DoStepDownStepUpApply() const { return DoesStepApply(); }
   1084 
   1085  /**
   1086   * Returns if valueAsNumber attribute applies for the current type.
   1087   */
   1088  bool DoesValueAsNumberApply() const { return DoesMinMaxApply(); }
   1089 
   1090  /**
   1091   * Returns if autocomplete attribute applies for the current type.
   1092   */
   1093  bool DoesAutocompleteApply() const;
   1094 
   1095  MOZ_CAN_RUN_SCRIPT void FreeData();
   1096  TextControlState* GetEditorState() const;
   1097  void EnsureEditorState();
   1098 
   1099  MOZ_CAN_RUN_SCRIPT TextEditor* GetTextEditorFromState();
   1100 
   1101  /**
   1102   * Manages the internal data storage across type changes.
   1103   */
   1104  MOZ_CAN_RUN_SCRIPT
   1105  void HandleTypeChange(FormControlType aNewType, bool aNotify);
   1106 
   1107  /**
   1108   * If the input range has a list, this function will snap the given value to
   1109   * the nearest tick mark, but only if the given value is close enough to that
   1110   * tick mark.
   1111   */
   1112  void MaybeSnapToTickMark(Decimal& aValue);
   1113 
   1114  enum class SanitizationKind { ForValueGetter, ForValueSetter, ForDisplay };
   1115  /**
   1116   * Sanitize the value of the element depending of its current type.
   1117   * See:
   1118   * http://www.whatwg.org/specs/web-apps/current-work/#value-sanitization-algorithm
   1119   */
   1120  void SanitizeValue(nsAString& aValue, SanitizationKind) const;
   1121 
   1122  /**
   1123   * Returns whether the placeholder attribute applies for the current type.
   1124   */
   1125  bool PlaceholderApplies() const;
   1126 
   1127  /**
   1128   * Set the current default value to the value of the input element.
   1129   * @note You should not call this method if GetValueMode() doesn't return
   1130   * VALUE_MODE_VALUE.
   1131   */
   1132  MOZ_CAN_RUN_SCRIPT
   1133  nsresult SetDefaultValueAsValue();
   1134 
   1135  /**
   1136   * Returns the radio group container within the DOM tree that the element
   1137   * is currently a member of, if one exists.
   1138   */
   1139  RadioGroupContainer* GetCurrentRadioGroupContainer() const;
   1140  /**
   1141   * Returns the radio group container within the DOM tree that the element
   1142   * should be added into, if one exists.
   1143   */
   1144  RadioGroupContainer* FindTreeRadioGroupContainer() const;
   1145 
   1146  /**
   1147   * Parse a week string of the form yyyy-Www
   1148   * @param the string to be parsed.
   1149   * @return whether the string is a valid week.
   1150   * Note : this function does not consider the empty string as valid.
   1151   */
   1152  bool IsValidWeek(const nsAString& aValue) const;
   1153 
   1154  /**
   1155   * Parse a month string of the form yyyy-mm
   1156   * @param the string to be parsed.
   1157   * @return whether the string is a valid month.
   1158   * Note : this function does not consider the empty string as valid.
   1159   */
   1160  bool IsValidMonth(const nsAString& aValue) const;
   1161 
   1162  /**
   1163   * Parse a date string of the form yyyy-mm-dd
   1164   * @param the string to be parsed.
   1165   * @return whether the string is a valid date.
   1166   * Note : this function does not consider the empty string as valid.
   1167   */
   1168  bool IsValidDate(const nsAString& aValue) const;
   1169 
   1170  /**
   1171   * Parse a datetime-local string of the form yyyy-mm-ddThh:mm[:ss.s] or
   1172   * yyyy-mm-dd hh:mm[:ss.s], where fractions of seconds can be 1 to 3 digits.
   1173   *
   1174   * @param the string to be parsed.
   1175   * @return whether the string is a valid datetime-local string.
   1176   * Note : this function does not consider the empty string as valid.
   1177   */
   1178  bool IsValidDateTimeLocal(const nsAString& aValue) const;
   1179 
   1180  /**
   1181   * Parse a year string of the form yyyy
   1182   *
   1183   * @param the string to be parsed.
   1184   *
   1185   * @return the year in aYear.
   1186   * @return whether the parsing was successful.
   1187   */
   1188  bool ParseYear(const nsAString& aValue, uint32_t* aYear) const;
   1189 
   1190  /**
   1191   * Parse a month string of the form yyyy-mm
   1192   *
   1193   * @param the string to be parsed.
   1194   * @return the year and month in aYear and aMonth.
   1195   * @return whether the parsing was successful.
   1196   */
   1197  bool ParseMonth(const nsAString& aValue, uint32_t* aYear,
   1198                  uint32_t* aMonth) const;
   1199 
   1200  /**
   1201   * Parse a week string of the form yyyy-Www
   1202   *
   1203   * @param the string to be parsed.
   1204   * @return the year and week in aYear and aWeek.
   1205   * @return whether the parsing was successful.
   1206   */
   1207  bool ParseWeek(const nsAString& aValue, uint32_t* aYear,
   1208                 uint32_t* aWeek) const;
   1209  /**
   1210   * Parse a date string of the form yyyy-mm-dd
   1211   *
   1212   * @param the string to be parsed.
   1213   * @return the date in aYear, aMonth, aDay.
   1214   * @return whether the parsing was successful.
   1215   */
   1216  bool ParseDate(const nsAString& aValue, uint32_t* aYear, uint32_t* aMonth,
   1217                 uint32_t* aDay) const;
   1218 
   1219  /**
   1220   * Parse a datetime-local string of the form yyyy-mm-ddThh:mm[:ss.s] or
   1221   * yyyy-mm-dd hh:mm[:ss.s], where fractions of seconds can be 1 to 3 digits.
   1222   *
   1223   * @param the string to be parsed.
   1224   * @return the date in aYear, aMonth, aDay and time expressed in milliseconds
   1225   *         in aTime.
   1226   * @return whether the parsing was successful.
   1227   */
   1228  bool ParseDateTimeLocal(const nsAString& aValue, uint32_t* aYear,
   1229                          uint32_t* aMonth, uint32_t* aDay,
   1230                          uint32_t* aTime) const;
   1231 
   1232  /**
   1233   * Normalize the datetime-local string following the HTML specifications:
   1234   * https://html.spec.whatwg.org/multipage/infrastructure.html#valid-normalised-local-date-and-time-string
   1235   */
   1236  void NormalizeDateTimeLocal(nsAString& aValue) const;
   1237 
   1238  /**
   1239   * This methods returns the number of days since epoch for a given year and
   1240   * week.
   1241   */
   1242  double DaysSinceEpochFromWeek(uint32_t aYear, uint32_t aWeek) const;
   1243 
   1244  /**
   1245   * This methods returns the number of days in a given month, for a given year.
   1246   */
   1247  uint32_t NumberOfDaysInMonth(uint32_t aMonth, uint32_t aYear) const;
   1248 
   1249  /**
   1250   * This methods returns the number of months between January 1970 and the
   1251   * given year and month.
   1252   */
   1253  int32_t MonthsSinceJan1970(uint32_t aYear, uint32_t aMonth) const;
   1254 
   1255  /**
   1256   * This methods returns the day of the week given a date. If @isoWeek is true,
   1257   * 7=Sunday, otherwise, 0=Sunday.
   1258   */
   1259  uint32_t DayOfWeek(uint32_t aYear, uint32_t aMonth, uint32_t aDay,
   1260                     bool isoWeek) const;
   1261 
   1262  /**
   1263   * This methods returns the maximum number of week in a given year, the
   1264   * result is either 52 or 53.
   1265   */
   1266  uint32_t MaximumWeekInYear(uint32_t aYear) const;
   1267 
   1268  /**
   1269   * This methods returns true if it's a leap year.
   1270   */
   1271  bool IsLeapYear(uint32_t aYear) const;
   1272 
   1273  /**
   1274   * Returns whether aValue is a valid time as described by HTML specifications:
   1275   * http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#valid-time-string
   1276   *
   1277   * @param aValue the string to be tested.
   1278   * @return Whether the string is a valid time per HTML specifications.
   1279   */
   1280  bool IsValidTime(const nsAString& aValue) const;
   1281 
   1282  /**
   1283   * Returns the time expressed in milliseconds of |aValue| being parsed as a
   1284   * time following the HTML specifications:
   1285   * http://www.whatwg.org/specs/web-apps/current-work/#parse-a-time-string
   1286   *
   1287   * Note: |aResult| can be null.
   1288   *
   1289   * @param aValue  the string to be parsed.
   1290   * @param aResult the time expressed in milliseconds representing the time
   1291   * [out]
   1292   * @return Whether the parsing was successful.
   1293   */
   1294  static bool ParseTime(const nsAString& aValue, uint32_t* aResult);
   1295 
   1296  /**
   1297   * Sets the value of the element to the string representation of the Decimal.
   1298   *
   1299   * @param aValue The Decimal that will be used to set the value.
   1300   */
   1301  void SetValue(Decimal aValue, CallerType aCallerType);
   1302 
   1303  void UpdateHasRange(bool aNotify);
   1304  // Updates the :in-range / :out-of-range states.
   1305  void UpdateInRange(bool aNotify);
   1306 
   1307  /**
   1308   * Get the step scale value for the current type.
   1309   * See:
   1310   * http://www.whatwg.org/specs/web-apps/current-work/multipage/common-input-element-attributes.html#concept-input-step-scale
   1311   */
   1312  Decimal GetStepScaleFactor() const;
   1313 
   1314  /**
   1315   * Return the base used to compute if a value matches step.
   1316   * Basically, it's the min attribute if present and a default value otherwise.
   1317   *
   1318   * @return The step base.
   1319   */
   1320  Decimal GetStepBase() const;
   1321 
   1322  /**
   1323   * Returns the default step for the current type.
   1324   * @return the default step for the current type.
   1325   */
   1326  Decimal GetDefaultStep() const;
   1327 
   1328  enum class StepCallerType { ForUserEvent, ForScript };
   1329 
   1330  /**
   1331   * Returns the value that this input would take if someone tries to step
   1332   * aStepCount steps and this input's value would change as a result, or
   1333   * Decimal::nan() otherwise (e.g., if this inputs value would not change due
   1334   * to it being already at max, and asking for the next step up).
   1335   *
   1336   * Negative aStep means step down, positive means step up.
   1337   */
   1338  Decimal GetValueIfStepped(int32_t aStepCount, StepCallerType, ErrorResult&);
   1339 
   1340  /**
   1341   * Apply a step change from stepUp or stepDown by multiplying aStep by the
   1342   * current step value.
   1343   *
   1344   * @param aStep The value used to be multiplied against the step value.
   1345   */
   1346  void ApplyStep(int32_t aStep, ErrorResult&);
   1347 
   1348  /*
   1349   * Returns if the current type is one of the date/time input types: date,
   1350   * time, month, week and datetime-local.
   1351   */
   1352  static bool IsDateTimeInputType(FormControlType);
   1353 
   1354  /**
   1355   * Returns whether getting `.value` as a string should sanitize the value.
   1356   *
   1357   * See SanitizeValue.
   1358   */
   1359  bool SanitizesOnValueGetter() const;
   1360 
   1361  /**
   1362   * Returns true if the element should prevent dispatching another DOMActivate.
   1363   * This is used in situations where the anonymous subtree should already have
   1364   * sent a DOMActivate and prevents firing more than once.
   1365   */
   1366  bool ShouldPreventDOMActivateDispatch(EventTarget* aOriginalTarget);
   1367 
   1368  /**
   1369   * Some input type (color and file) let user choose a value using a picker:
   1370   * this function checks if it is needed, and if so, open the corresponding
   1371   * picker (color picker or file picker).
   1372   */
   1373  nsresult MaybeInitPickers(EventChainPostVisitor& aVisitor);
   1374 
   1375  /**
   1376   * Returns all valid colors in the <datalist> for the input with type=color.
   1377   */
   1378  nsTArray<nsString> GetColorsFromList();
   1379 
   1380  enum FilePickerType { FILE_PICKER_FILE, FILE_PICKER_DIRECTORY };
   1381  nsresult InitFilePicker(FilePickerType aType);
   1382  nsresult InitColorPicker();
   1383 
   1384  GetFilesHelper* GetOrCreateGetFilesHelper(bool aRecursiveFlag,
   1385                                            ErrorResult& aRv);
   1386 
   1387  void ClearGetFilesHelpers();
   1388 
   1389  /**
   1390   * nsINode::SetMayBeApzAware() will be invoked in this function if necessary
   1391   * to prevent default action of APZC so that we can increase/decrease the
   1392   * value of this InputElement when mouse wheel event comes without scrolling
   1393   * the page.
   1394   *
   1395   * SetMayBeApzAware() will set flag MayBeApzAware which is checked by apzc to
   1396   * decide whether to add this element into its dispatch-to-content region.
   1397   */
   1398  void UpdateApzAwareFlag();
   1399 
   1400  /**
   1401   * A helper to get the current selection range.  Will throw on the ErrorResult
   1402   * if we have no editor state.
   1403   */
   1404  void GetSelectionRange(uint32_t* aSelectionStart, uint32_t* aSelectionEnd,
   1405                         ErrorResult& aRv);
   1406 
   1407  /**
   1408   * Override for nsImageLoadingContent.
   1409   */
   1410  nsIContent* AsContent() override { return this; }
   1411 
   1412  void LoadSelectedImage(bool aAlwaysLoad, bool aStopLazyLoading) override {
   1413    MOZ_ASSERT_UNREACHABLE("LoadSelectedImage not implemented");
   1414  }
   1415 
   1416  nsCOMPtr<nsIControllers> mControllers;
   1417 
   1418  /*
   1419   * In mInputData, the mState field is used if IsSingleLineTextControl returns
   1420   * true and mValue is used otherwise.  We have to be careful when handling it
   1421   * on a type change.
   1422   *
   1423   * Accessing the mState member should be done using the GetEditorState
   1424   * function, which returns null if the state is not present.
   1425   */
   1426  union InputData {
   1427    /**
   1428     * The current value of the input if it has been changed from the default
   1429     */
   1430    char16_t* mValue;
   1431    /**
   1432     * The state of the text editor associated with the text/password input
   1433     */
   1434    TextControlState* mState;
   1435  } mInputData;
   1436 
   1437  struct FileData;
   1438  UniquePtr<FileData> mFileData;
   1439 
   1440  /**
   1441   * The value of the input element when first initialized and it is updated
   1442   * when the element is either changed through a script, focused or dispatches
   1443   * a change event. This is to ensure correct future change event firing.
   1444   * NB: This is ONLY applicable where the element is a text control. ie,
   1445   * where type= "date", "time", "text", "email", "search", "tel", "url" or
   1446   * "password".
   1447   */
   1448  nsString mFocusedValue;
   1449 
   1450  /**
   1451   * If mIsDraggingRange is true, this is the value that the input had before
   1452   * the drag started. Used to reset the input to its old value if the drag is
   1453   * canceled.
   1454   */
   1455  Decimal mRangeThumbDragStartValue;
   1456 
   1457  /**
   1458   * Current value in the input box, in DateTimeValue dictionary format, see
   1459   * HTMLInputElement.webidl for details.
   1460   */
   1461  UniquePtr<DateTimeValue> mDateTimeInputBoxValue;
   1462 
   1463  /**
   1464   * The triggering principal for the src attribute.
   1465   */
   1466  nsCOMPtr<nsIPrincipal> mSrcTriggeringPrincipal;
   1467 
   1468  /*
   1469   * InputType object created based on input type.
   1470   */
   1471  UniquePtr<InputType, InputType::DoNotDelete> mInputType;
   1472 
   1473  static constexpr size_t INPUT_TYPE_SIZE =
   1474      sizeof(Variant<TextInputType, SearchInputType, TelInputType, URLInputType,
   1475                     EmailInputType, PasswordInputType, NumberInputType,
   1476                     RangeInputType, RadioInputType, CheckboxInputType,
   1477                     ButtonInputType, ImageInputType, ResetInputType,
   1478                     SubmitInputType, DateInputType, TimeInputType,
   1479                     WeekInputType, MonthInputType, DateTimeLocalInputType,
   1480                     FileInputType, ColorInputType, HiddenInputType>);
   1481 
   1482  // Memory allocated for mInputType, reused when type changes.
   1483  char mInputTypeMem[INPUT_TYPE_SIZE];
   1484 
   1485  // Step scale factor values, for input types that have one.
   1486  static const Decimal kStepScaleFactorDate;
   1487  static const Decimal kStepScaleFactorNumberRange;
   1488  static const Decimal kStepScaleFactorTime;
   1489  static const Decimal kStepScaleFactorMonth;
   1490  static const Decimal kStepScaleFactorWeek;
   1491 
   1492  // Default step base value when a type do not have specific one.
   1493  static const Decimal kDefaultStepBase;
   1494  // Default step base value when type=week does not not have a specific one,
   1495  // which is −259200000, the start of week 1970-W01.
   1496  static const Decimal kDefaultStepBaseWeek;
   1497 
   1498  // Default step used when there is no specified step.
   1499  static const Decimal kDefaultStep;
   1500  static const Decimal kDefaultStepTime;
   1501 
   1502  // Float value returned by GetStep() when the step attribute is set to 'any'.
   1503  static const Decimal kStepAny;
   1504 
   1505  // Minimum year limited by HTML standard, year >= 1.
   1506  static const double kMinimumYear;
   1507  // Maximum year limited by ECMAScript date object range, year <= 275760.
   1508  static const double kMaximumYear;
   1509  // Maximum valid week is 275760-W37.
   1510  static const double kMaximumWeekInMaximumYear;
   1511  // Maximum valid day is 275760-09-13.
   1512  static const double kMaximumDayInMaximumYear;
   1513  // Maximum valid month is 275760-09.
   1514  static const double kMaximumMonthInMaximumYear;
   1515  // Long years in a ISO calendar have 53 weeks in them.
   1516  static const double kMaximumWeekInYear;
   1517  // Milliseconds in a day.
   1518  static const double kMsPerDay;
   1519 
   1520  nsContentUtils::AutocompleteAttrState mAutocompleteAttrState;
   1521  nsContentUtils::AutocompleteAttrState mAutocompleteInfoState;
   1522  bool mDisabledChanged : 1;
   1523  // https://html.spec.whatwg.org/#concept-fe-dirty
   1524  // TODO: Maybe rename to match the spec?
   1525  bool mValueChanged : 1;
   1526  // https://html.spec.whatwg.org/#user-interacted
   1527  bool mUserInteracted : 1;
   1528  bool mLastValueChangeWasInteractive : 1;
   1529  bool mCheckedChanged : 1;
   1530  bool mChecked : 1;
   1531  bool mShouldInitChecked : 1;
   1532  bool mDoneCreating : 1;
   1533  bool mInInternalActivate : 1;
   1534  bool mCheckedIsToggled : 1;
   1535  bool mIndeterminate : 1;
   1536  bool mInhibitRestoration : 1;
   1537  bool mHasRange : 1;
   1538  bool mIsDraggingRange : 1;
   1539  bool mNumberControlSpinnerIsSpinning : 1;
   1540  bool mNumberControlSpinnerSpinsUp : 1;
   1541  bool mPickerRunning : 1;
   1542  bool mIsPreviewEnabled : 1;
   1543  bool mHasBeenTypePassword : 1;
   1544  bool mHasPatternAttribute : 1;
   1545 
   1546 private:
   1547  Maybe<int32_t> GetNumberInputCols() const;
   1548  static void ImageInputMapAttributesIntoRule(MappedDeclarationsBuilder&);
   1549 
   1550  /**
   1551   * Returns true if this input's type will fire a DOM "change" event when it
   1552   * loses focus if its value has changed since it gained focus.
   1553   */
   1554  bool MayFireChangeOnBlur() const { return MayFireChangeOnBlur(mType); }
   1555 
   1556  /**
   1557   * Returns true if selection methods can be called on element
   1558   */
   1559  bool SupportsTextSelection() const {
   1560    switch (mType) {
   1561      case FormControlType::InputText:
   1562      case FormControlType::InputSearch:
   1563      case FormControlType::InputUrl:
   1564      case FormControlType::InputTel:
   1565      case FormControlType::InputPassword:
   1566        return true;
   1567      default:
   1568        return false;
   1569    }
   1570  }
   1571 
   1572  /**
   1573   * https://html.spec.whatwg.org/#auto-directionality-form-associated-elements
   1574   */
   1575  static bool IsAutoDirectionalityAssociated(FormControlType aType) {
   1576    switch (aType) {
   1577      case FormControlType::InputHidden:
   1578      case FormControlType::InputText:
   1579      case FormControlType::InputSearch:
   1580      case FormControlType::InputTel:
   1581      case FormControlType::InputUrl:
   1582      case FormControlType::InputEmail:
   1583      case FormControlType::InputPassword:
   1584      case FormControlType::InputSubmit:
   1585      case FormControlType::InputReset:
   1586      case FormControlType::InputButton:
   1587        return true;
   1588      default:
   1589        return false;
   1590    }
   1591  }
   1592 
   1593  static bool CreatesDateTimeWidget(FormControlType aType) {
   1594    return aType == FormControlType::InputDate ||
   1595           aType == FormControlType::InputTime ||
   1596           aType == FormControlType::InputDatetimeLocal;
   1597  }
   1598 
   1599  bool CreatesDateTimeWidget() const { return CreatesDateTimeWidget(mType); }
   1600 
   1601  static bool MayFireChangeOnBlur(FormControlType aType) {
   1602    return IsSingleLineTextControl(false, aType) ||
   1603           CreatesDateTimeWidget(aType) ||
   1604           aType == FormControlType::InputRange ||
   1605           aType == FormControlType::InputNumber;
   1606  }
   1607 
   1608  bool CheckActivationBehaviorPreconditions(EventChainVisitor& aVisitor) const;
   1609 
   1610  /**
   1611   * Call MaybeDispatchPasswordEvent or MaybeDispatchUsernameEvent
   1612   * in order to dispatch LoginManager events.
   1613   */
   1614  void MaybeDispatchLoginManagerEvents(HTMLFormElement* aForm);
   1615 
   1616  /**
   1617   * Fire an event when the password input field is removed from the DOM tree.
   1618   * This is now only used by the password manager and formautofill.
   1619   */
   1620  void MaybeFireInputPasswordRemoved();
   1621 
   1622  /**
   1623   * Checks if aDateTimeInputType should be supported.
   1624   */
   1625  static bool IsDateTimeTypeSupported(FormControlType);
   1626 
   1627  /**
   1628   * The radio group container containing the group the element is a part of.
   1629   * This allows the element to only access a container it has been added to.
   1630   */
   1631  RadioGroupContainer* mRadioGroupContainer;
   1632 
   1633  struct nsFilePickerFilter {
   1634    nsFilePickerFilter() : mFilterMask(0) {}
   1635 
   1636    explicit nsFilePickerFilter(int32_t aFilterMask)
   1637        : mFilterMask(aFilterMask) {}
   1638 
   1639    nsFilePickerFilter(const nsString& aTitle, const nsString& aFilter)
   1640        : mFilterMask(0), mTitle(aTitle), mFilter(aFilter) {}
   1641 
   1642    nsFilePickerFilter(const nsFilePickerFilter& other) {
   1643      mFilterMask = other.mFilterMask;
   1644      mTitle = other.mTitle;
   1645      mFilter = other.mFilter;
   1646    }
   1647 
   1648    bool operator==(const nsFilePickerFilter& other) const {
   1649      if ((mFilter == other.mFilter) && (mFilterMask == other.mFilterMask)) {
   1650        return true;
   1651      } else {
   1652        return false;
   1653      }
   1654    }
   1655 
   1656    // Filter mask, using values defined in nsIFilePicker
   1657    int32_t mFilterMask;
   1658    // If mFilterMask is defined, mTitle and mFilter are useless and should be
   1659    // ignored
   1660    nsString mTitle;
   1661    nsString mFilter;
   1662  };
   1663 
   1664  class nsFilePickerShownCallback : public nsIFilePickerShownCallback {
   1665    virtual ~nsFilePickerShownCallback() = default;
   1666 
   1667   public:
   1668    nsFilePickerShownCallback(HTMLInputElement* aInput,
   1669                              nsIFilePicker* aFilePicker);
   1670    NS_DECL_ISUPPORTS
   1671 
   1672    NS_IMETHOD Done(nsIFilePicker::ResultCode aResult) override;
   1673 
   1674   private:
   1675    nsCOMPtr<nsIFilePicker> mFilePicker;
   1676    const RefPtr<HTMLInputElement> mInput;
   1677  };
   1678 };
   1679 
   1680 }  // namespace dom
   1681 }  // namespace mozilla
   1682 
   1683 #endif