summaryrefslogtreecommitdiffstats
path: root/dom/html/nsIFormControl.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/html/nsIFormControl.h')
-rw-r--r--dom/html/nsIFormControl.h290
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___ */