diff options
Diffstat (limited to 'dom/html/nsIFormControl.h')
-rw-r--r-- | dom/html/nsIFormControl.h | 290 |
1 files changed, 290 insertions, 0 deletions
diff --git a/dom/html/nsIFormControl.h b/dom/html/nsIFormControl.h new file mode 100644 index 0000000000..0ca8169675 --- /dev/null +++ b/dom/html/nsIFormControl.h @@ -0,0 +1,290 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef nsIFormControl_h___ +#define nsIFormControl_h___ + +#include "mozilla/EventForwards.h" +#include "mozilla/StaticPrefs_dom.h" +#include "nsISupports.h" + +namespace mozilla { +class PresState; +namespace dom { +class Element; +class FormData; +class HTMLFieldSetElement; +class HTMLFormElement; +} // namespace dom +} // namespace mozilla + +// Elements with different types, the value is used as a mask. +// When changing the order, adding or removing elements, be sure to update +// the static_assert checks accordingly. +constexpr uint8_t kFormControlButtonElementMask = 0x40; // 0b01000000 +constexpr uint8_t kFormControlInputElementMask = 0x80; // 0b10000000 + +enum class FormControlType : uint8_t { + Fieldset = 1, + Output, + Select, + Textarea, + Object, + FormAssociatedCustomElement, + + LastWithoutSubtypes = FormAssociatedCustomElement, + + ButtonButton = kFormControlButtonElementMask + 1, + ButtonReset, + ButtonSubmit, + LastButtonElement = ButtonSubmit, + + InputButton = kFormControlInputElementMask + 1, + InputCheckbox, + InputColor, + InputDate, + InputEmail, + InputFile, + InputHidden, + InputReset, + InputImage, + InputMonth, + InputNumber, + InputPassword, + InputRadio, + InputSearch, + InputSubmit, + InputTel, + InputText, + InputTime, + InputUrl, + InputRange, + InputWeek, + InputDatetimeLocal, + LastInputElement = InputDatetimeLocal, +}; + +static_assert(uint8_t(FormControlType::LastWithoutSubtypes) < + kFormControlButtonElementMask, + "Too many FormControlsTypes without sub-types"); +static_assert(uint8_t(FormControlType::LastButtonElement) < + kFormControlInputElementMask, + "Too many ButtonElementTypes"); +static_assert(uint32_t(FormControlType::LastInputElement) < (1 << 8), + "Too many form control types"); + +#define NS_IFORMCONTROL_IID \ + { \ + 0x4b89980c, 0x4dcd, 0x428f, { \ + 0xb7, 0xad, 0x43, 0x5b, 0x93, 0x29, 0x79, 0xec \ + } \ + } + +/** + * Interface which all form controls (e.g. buttons, checkboxes, text, + * radio buttons, select, etc) implement in addition to their dom specific + * interface. + */ +class nsIFormControl : public nsISupports { + public: + nsIFormControl(FormControlType aType) : mType(aType) {} + + NS_DECLARE_STATIC_IID_ACCESSOR(NS_IFORMCONTROL_IID) + + /** + * Get the fieldset for this form control. + * @return the fieldset + */ + virtual mozilla::dom::HTMLFieldSetElement* GetFieldSet() = 0; + + /** + * Get the form for this form control. + * @return the form + */ + virtual mozilla::dom::HTMLFormElement* GetForm() const = 0; + + /** + * Set the form for this form control. + * @param aForm the form. This must not be null. + * + * @note that when setting the form the control is not added to the + * form. It adds itself when it gets bound to the tree thereafter, + * so that it can be properly sorted with the other controls in the + * form. + */ + virtual void SetForm(mozilla::dom::HTMLFormElement* aForm) = 0; + + /** + * Tell the control to forget about its form. + * + * @param aRemoveFromForm set false if you do not want this element removed + * from the form. (Used by nsFormControlList::Clear()) + * @param aUnbindOrDelete set true if the element is being deleted or unbound + * from tree. + */ + virtual void ClearForm(bool aRemoveFromForm, bool aUnbindOrDelete) = 0; + + /** + * Get the type of this control as an int (see NS_FORM_* above) + * @return the type of this control + */ + FormControlType ControlType() const { return mType; } + + /** + * Reset this form control (as it should be when the user clicks the Reset + * button) + */ + NS_IMETHOD Reset() = 0; + + /** + * Tells the form control to submit its names and values to the form data + * object + * + * @param aFormData the form data to notify of names/values/files to submit + */ + NS_IMETHOD + SubmitNamesValues(mozilla::dom::FormData* aFormData) = 0; + + virtual bool AllowDrop() = 0; + + /** + * Returns whether this is a control which submits the form when activated by + * the user. + * @return whether this is a submit control. + */ + inline bool IsSubmitControl() const; + + /** + * Returns whether this is a text control. + * @param aExcludePassword to have NS_FORM_INPUT_PASSWORD returning false. + * @return whether this is a text control. + */ + inline bool IsTextControl(bool aExcludePassword) const; + + /** + * Returns whether this is a single line text control. + * @param aExcludePassword to have NS_FORM_INPUT_PASSWORD returning false. + * @return whether this is a single line text control. + */ + inline bool IsSingleLineTextControl(bool aExcludePassword) const; + + /** + * Returns whether this is a submittable form control. + * @return whether this is a submittable form control. + */ + inline bool IsSubmittableControl() const; + + /** + * https://html.spec.whatwg.org/multipage/forms.html#concept-button + */ + inline bool IsConceptButton() const; + + /** + * Returns whether this is an ordinal button or a concept button that has no + * form associated. + */ + inline bool IsButtonControl() const; + + /** + * Returns whether this form control can have draggable children. + * @return whether this form control can have draggable children. + */ + inline bool AllowDraggableChildren() const; + + // Returns a number for this form control that is unique within its + // owner document. This is used by nsContentUtils::GenerateStateKey + // to identify form controls that are inserted into the document by + // the parser. -1 is returned for form controls with no state or + // which were inserted into the document by some other means than + // the parser from the network. + virtual int32_t GetParserInsertedControlNumberForStateKey() const { + return -1; + }; + + protected: + /** + * Returns whether mType corresponds to a single line text control type. + * @param aExcludePassword to have NS_FORM_INPUT_PASSWORD ignored. + * @param aType the type to be tested. + * @return whether mType corresponds to a single line text control type. + */ + inline static bool IsSingleLineTextControl(bool aExcludePassword, + FormControlType); + + inline static bool IsButtonElement(FormControlType aType) { + return uint8_t(aType) & kFormControlButtonElementMask; + } + + inline static bool IsInputElement(FormControlType aType) { + return uint8_t(aType) & kFormControlInputElementMask; + } + + FormControlType mType; +}; + +bool nsIFormControl::IsSubmitControl() const { + FormControlType type = ControlType(); + return type == FormControlType::InputSubmit || + type == FormControlType::InputImage || + type == FormControlType::ButtonSubmit; +} + +bool nsIFormControl::IsTextControl(bool aExcludePassword) const { + FormControlType type = ControlType(); + return type == FormControlType::Textarea || + IsSingleLineTextControl(aExcludePassword, type); +} + +bool nsIFormControl::IsSingleLineTextControl(bool aExcludePassword) const { + return IsSingleLineTextControl(aExcludePassword, ControlType()); +} + +/*static*/ +bool nsIFormControl::IsSingleLineTextControl(bool aExcludePassword, + FormControlType aType) { + switch (aType) { + case FormControlType::InputText: + case FormControlType::InputEmail: + case FormControlType::InputSearch: + case FormControlType::InputTel: + case FormControlType::InputUrl: + case FormControlType::InputNumber: + // TODO: those are temporary until bug 773205 is fixed. + case FormControlType::InputMonth: + case FormControlType::InputWeek: + return true; + case FormControlType::InputPassword: + return !aExcludePassword; + default: + return false; + } +} + +bool nsIFormControl::IsSubmittableControl() const { + auto type = ControlType(); + return type == FormControlType::Object || type == FormControlType::Textarea || + type == FormControlType::Select || IsButtonElement(type) || + IsInputElement(type); +} + +bool nsIFormControl::IsConceptButton() const { + auto type = ControlType(); + return IsSubmitControl() || type == FormControlType::InputReset || + type == FormControlType::InputButton || IsButtonElement(type); +} + +bool nsIFormControl::IsButtonControl() const { + return IsConceptButton() && (!GetForm() || !IsSubmitControl()); +} + +bool nsIFormControl::AllowDraggableChildren() const { + auto type = ControlType(); + return type == FormControlType::Object || type == FormControlType::Fieldset || + type == FormControlType::Output; +} + +NS_DEFINE_STATIC_IID_ACCESSOR(nsIFormControl, NS_IFORMCONTROL_IID) + +#endif /* nsIFormControl_h___ */ |