tor-browser

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

nsIFormControl.h (9456B)


      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 #ifndef nsIFormControl_h___
      7 #define nsIFormControl_h___
      8 
      9 #include "mozilla/EventForwards.h"
     10 #include "mozilla/StaticPrefs_dom.h"
     11 #include "nsISupports.h"
     12 
     13 class nsINode;
     14 namespace mozilla {
     15 class PresState;
     16 namespace dom {
     17 class Element;
     18 class EventTarget;
     19 class FormData;
     20 class HTMLFieldSetElement;
     21 class HTMLFormElement;
     22 }  // namespace dom
     23 }  // namespace mozilla
     24 
     25 // Elements with different types, the value is used as a mask.
     26 // When changing the order, adding or removing elements, be sure to update
     27 // the static_assert checks accordingly.
     28 constexpr uint8_t kFormControlButtonElementMask = 0x40;  // 0b01000000
     29 constexpr uint8_t kFormControlInputElementMask = 0x80;   // 0b10000000
     30 
     31 enum class FormControlType : uint8_t {
     32  Fieldset = 1,
     33  Output,
     34  Select,
     35  Textarea,
     36  Object,
     37  FormAssociatedCustomElement,
     38 
     39  LastWithoutSubtypes = FormAssociatedCustomElement,
     40 
     41  ButtonButton = kFormControlButtonElementMask + 1,
     42  ButtonReset,
     43  ButtonSubmit,
     44  LastButtonElement = ButtonSubmit,
     45 
     46  InputButton = kFormControlInputElementMask + 1,
     47  InputCheckbox,
     48  InputColor,
     49  InputDate,
     50  InputEmail,
     51  InputFile,
     52  InputHidden,
     53  InputReset,
     54  InputImage,
     55  InputMonth,
     56  InputNumber,
     57  InputPassword,
     58  InputRadio,
     59  InputSearch,
     60  InputSubmit,
     61  InputTel,
     62  InputText,
     63  InputTime,
     64  InputUrl,
     65  InputRange,
     66  InputWeek,
     67  InputDatetimeLocal,
     68  LastInputElement = InputDatetimeLocal,
     69 };
     70 
     71 static_assert(uint8_t(FormControlType::LastWithoutSubtypes) <
     72                  kFormControlButtonElementMask,
     73              "Too many FormControlsTypes without sub-types");
     74 static_assert(uint8_t(FormControlType::LastButtonElement) <
     75                  kFormControlInputElementMask,
     76              "Too many ButtonElementTypes");
     77 static_assert(uint32_t(FormControlType::LastInputElement) < (1 << 8),
     78              "Too many form control types");
     79 
     80 #define NS_IFORMCONTROL_IID \
     81  {0x4b89980c, 0x4dcd, 0x428f, {0xb7, 0xad, 0x43, 0x5b, 0x93, 0x29, 0x79, 0xec}}
     82 
     83 /**
     84 * Interface which all form controls (e.g. buttons, checkboxes, text,
     85 * radio buttons, select, etc) implement in addition to their dom specific
     86 * interface.
     87 */
     88 class nsIFormControl : public nsISupports {
     89 public:
     90  nsIFormControl(FormControlType aType) : mType(aType) {}
     91 
     92  NS_INLINE_DECL_STATIC_IID(NS_IFORMCONTROL_IID)
     93 
     94  static nsIFormControl* FromEventTarget(mozilla::dom::EventTarget* aTarget);
     95  static nsIFormControl* FromEventTargetOrNull(
     96      mozilla::dom::EventTarget* aTarget);
     97  static const nsIFormControl* FromEventTarget(
     98      const mozilla::dom::EventTarget* aTarget);
     99  static const nsIFormControl* FromEventTargetOrNull(
    100      const mozilla::dom::EventTarget* aTarget);
    101 
    102  static nsIFormControl* FromNode(nsINode* aNode);
    103  static nsIFormControl* FromNodeOrNull(nsINode* aNode);
    104  static const nsIFormControl* FromNode(const nsINode* aNode);
    105  static const nsIFormControl* FromNodeOrNull(const nsINode* aNode);
    106 
    107  /**
    108   * Get the fieldset for this form control.
    109   * @return the fieldset
    110   */
    111  virtual mozilla::dom::HTMLFieldSetElement* GetFieldSet() = 0;
    112 
    113  /**
    114   * Get the form for this form control.
    115   * @return the form
    116   */
    117  virtual mozilla::dom::HTMLFormElement* GetForm() const = 0;
    118 
    119  /**
    120   * Set the form for this form control.
    121   * @param aForm the form.  This must not be null.
    122   *
    123   * @note that when setting the form the control is not added to the
    124   * form.  It adds itself when it gets bound to the tree thereafter,
    125   * so that it can be properly sorted with the other controls in the
    126   * form.
    127   */
    128  virtual void SetForm(mozilla::dom::HTMLFormElement* aForm) = 0;
    129 
    130  /**
    131   * Tell the control to forget about its form.
    132   *
    133   * @param aRemoveFromForm set false if you do not want this element removed
    134   *        from the form.  (Used by nsFormControlList::Clear())
    135   * @param aUnbindOrDelete set true if the element is being deleted or unbound
    136   *        from tree.
    137   */
    138  virtual void ClearForm(bool aRemoveFromForm, bool aUnbindOrDelete) = 0;
    139 
    140  /**
    141   * Get the type of this control as an int (see NS_FORM_* above)
    142   * @return the type of this control
    143   */
    144  FormControlType ControlType() const { return mType; }
    145 
    146  /**
    147   * Reset this form control (as it should be when the user clicks the Reset
    148   * button)
    149   */
    150  NS_IMETHOD Reset() = 0;
    151 
    152  /**
    153   * Tells the form control to submit its names and values to the form data
    154   * object
    155   *
    156   * @param aFormData the form data to notify of names/values/files to submit
    157   */
    158  NS_IMETHOD
    159  SubmitNamesValues(mozilla::dom::FormData* aFormData) = 0;
    160 
    161  /**
    162   * Returns whether this is a control which submits the form when activated by
    163   * the user.
    164   * @return whether this is a submit control.
    165   */
    166  inline bool IsSubmitControl() const;
    167 
    168  /**
    169   * Returns whether this is a text control.
    170   * @param  aExcludePassword  to have NS_FORM_INPUT_PASSWORD returning false.
    171   * @return whether this is a text control.
    172   */
    173  inline bool IsTextControl(bool aExcludePassword) const;
    174 
    175  /**
    176   * Returns whether this is a single line text control.
    177   * @param  aExcludePassword  to have NS_FORM_INPUT_PASSWORD returning false.
    178   * @return whether this is a single line text control.
    179   */
    180  inline bool IsSingleLineTextControl(bool aExcludePassword) const;
    181 
    182  /**
    183   * Returns whether this is a submittable form control.
    184   * @return whether this is a submittable form control.
    185   */
    186  inline bool IsSubmittableControl() const;
    187 
    188  /**
    189   * https://html.spec.whatwg.org/multipage/forms.html#concept-button
    190   */
    191  inline bool IsConceptButton() const;
    192 
    193  /**
    194   * Returns whether this is an ordinal button or a concept button that has no
    195   * form associated.
    196   */
    197  inline bool IsButtonControl() const;
    198 
    199  /**
    200   * Returns whether this form control can have draggable children.
    201   * @return whether this form control can have draggable children.
    202   */
    203  inline bool AllowDraggableChildren() const;
    204 
    205  // Returns a number for this form control that is unique within its
    206  // owner document.  This is used by nsContentUtils::GenerateStateKey
    207  // to identify form controls that are inserted into the document by
    208  // the parser.  -1 is returned for form controls with no state or
    209  // which were inserted into the document by some other means than
    210  // the parser from the network.
    211  virtual int32_t GetParserInsertedControlNumberForStateKey() const {
    212    return -1;
    213  };
    214 
    215 protected:
    216  /**
    217   * Returns whether mType corresponds to a single line text control type.
    218   * @param aExcludePassword to have NS_FORM_INPUT_PASSWORD ignored.
    219   * @param aType the type to be tested.
    220   * @return whether mType corresponds to a single line text control type.
    221   */
    222  inline static bool IsSingleLineTextControl(bool aExcludePassword,
    223                                             FormControlType);
    224 
    225  inline static bool IsButtonElement(FormControlType aType) {
    226    return uint8_t(aType) & kFormControlButtonElementMask;
    227  }
    228 
    229  inline static bool IsInputElement(FormControlType aType) {
    230    return uint8_t(aType) & kFormControlInputElementMask;
    231  }
    232 
    233  FormControlType mType;
    234 };
    235 
    236 bool nsIFormControl::IsSubmitControl() const {
    237  FormControlType type = ControlType();
    238  return type == FormControlType::InputSubmit ||
    239         type == FormControlType::InputImage ||
    240         type == FormControlType::ButtonSubmit;
    241 }
    242 
    243 bool nsIFormControl::IsTextControl(bool aExcludePassword) const {
    244  FormControlType type = ControlType();
    245  return type == FormControlType::Textarea ||
    246         IsSingleLineTextControl(aExcludePassword, type);
    247 }
    248 
    249 bool nsIFormControl::IsSingleLineTextControl(bool aExcludePassword) const {
    250  return IsSingleLineTextControl(aExcludePassword, ControlType());
    251 }
    252 
    253 /*static*/
    254 bool nsIFormControl::IsSingleLineTextControl(bool aExcludePassword,
    255                                             FormControlType aType) {
    256  switch (aType) {
    257    case FormControlType::InputText:
    258    case FormControlType::InputEmail:
    259    case FormControlType::InputSearch:
    260    case FormControlType::InputTel:
    261    case FormControlType::InputUrl:
    262    case FormControlType::InputNumber:
    263    // TODO: those are temporary until bug 773205 is fixed.
    264    case FormControlType::InputMonth:
    265    case FormControlType::InputWeek:
    266      return true;
    267    case FormControlType::InputPassword:
    268      return !aExcludePassword;
    269    default:
    270      return false;
    271  }
    272 }
    273 
    274 bool nsIFormControl::IsSubmittableControl() const {
    275  auto type = ControlType();
    276  return type == FormControlType::Object || type == FormControlType::Textarea ||
    277         type == FormControlType::Select || IsButtonElement(type) ||
    278         IsInputElement(type);
    279 }
    280 
    281 bool nsIFormControl::IsConceptButton() const {
    282  auto type = ControlType();
    283  return IsSubmitControl() || type == FormControlType::InputReset ||
    284         type == FormControlType::InputButton || IsButtonElement(type);
    285 }
    286 
    287 bool nsIFormControl::IsButtonControl() const {
    288  return IsConceptButton() && (!GetForm() || !IsSubmitControl());
    289 }
    290 
    291 bool nsIFormControl::AllowDraggableChildren() const {
    292  auto type = ControlType();
    293  return type == FormControlType::Object || type == FormControlType::Fieldset ||
    294         type == FormControlType::Output;
    295 }
    296 
    297 #endif /* nsIFormControl_h___ */