mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 03:15:11 +00:00
Bug 1556351 - Part 8: Make HTMLElement inherit nsGenericHTMLFormElement; r=smaug
And add checks in form codes to ensure they won't be run on HTMLElement that isn't a FACE. Differential Revision: https://phabricator.services.mozilla.com/D125210
This commit is contained in:
parent
6067012a93
commit
e2e899cd73
@ -11,7 +11,7 @@
|
||||
namespace mozilla::dom {
|
||||
|
||||
HTMLElement::HTMLElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
|
||||
: nsGenericHTMLElement(std::move(aNodeInfo)) {
|
||||
: nsGenericHTMLFormElement(std::move(aNodeInfo)) {
|
||||
if (NodeInfo()->Equals(nsGkAtoms::bdi)) {
|
||||
AddStatesSilently(NS_EVENT_STATE_DIR_ATTR_LIKE_AUTO);
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
class HTMLElement final : public nsGenericHTMLElement {
|
||||
class HTMLElement final : public nsGenericHTMLFormElement {
|
||||
public:
|
||||
explicit HTMLElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
|
||||
virtual ~HTMLElement() = default;
|
||||
|
@ -1659,6 +1659,8 @@ nsGenericHTMLFormElement::nsGenericHTMLFormElement(
|
||||
|
||||
void nsGenericHTMLFormElement::ClearForm(bool aRemoveFromForm,
|
||||
bool aUnbindOrDelete) {
|
||||
MOZ_ASSERT(IsFormAssociatedElement());
|
||||
|
||||
HTMLFormElement* form = GetFormInternal();
|
||||
NS_ASSERTION((form != nullptr) == HasFlag(ADDED_TO_FORM),
|
||||
"Form control should have had flag set correctly");
|
||||
@ -1694,15 +1696,16 @@ nsresult nsGenericHTMLFormElement::BindToTree(BindContext& aContext,
|
||||
nsresult rv = nsGenericHTMLElement::BindToTree(aContext, aParent);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// If @form is set, the element *has* to be in a composed document, otherwise
|
||||
// it wouldn't be possible to find an element with the corresponding id.
|
||||
// If @form isn't set, the element *has* to have a parent, otherwise it
|
||||
// wouldn't be possible to find a form ancestor.
|
||||
// We should not call UpdateFormOwner if none of these conditions are
|
||||
// fulfilled.
|
||||
if (HasAttr(kNameSpaceID_None, nsGkAtoms::form) ? IsInComposedDoc()
|
||||
: aParent.IsContent()) {
|
||||
UpdateFormOwner(true, nullptr);
|
||||
if (IsFormAssociatedElement()) {
|
||||
// If @form is set, the element *has* to be in a composed document,
|
||||
// otherwise it wouldn't be possible to find an element with the
|
||||
// corresponding id. If @form isn't set, the element *has* to have a parent,
|
||||
// otherwise it wouldn't be possible to find a form ancestor. We should not
|
||||
// call UpdateFormOwner if none of these conditions are fulfilled.
|
||||
if (HasAttr(kNameSpaceID_None, nsGkAtoms::form) ? IsInComposedDoc()
|
||||
: aParent.IsContent()) {
|
||||
UpdateFormOwner(true, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
// Set parent fieldset which should be used for the disabled state.
|
||||
@ -1712,34 +1715,36 @@ nsresult nsGenericHTMLFormElement::BindToTree(BindContext& aContext,
|
||||
}
|
||||
|
||||
void nsGenericHTMLFormElement::UnbindFromTree(bool aNullParent) {
|
||||
if (HTMLFormElement* form = GetFormInternal()) {
|
||||
// Might need to unset form
|
||||
if (aNullParent) {
|
||||
// No more parent means no more form
|
||||
ClearForm(true, true);
|
||||
} else {
|
||||
// Recheck whether we should still have an form.
|
||||
if (HasAttr(kNameSpaceID_None, nsGkAtoms::form) ||
|
||||
!FindAncestorForm(form)) {
|
||||
if (IsFormAssociatedElement()) {
|
||||
if (HTMLFormElement* form = GetFormInternal()) {
|
||||
// Might need to unset form
|
||||
if (aNullParent) {
|
||||
// No more parent means no more form
|
||||
ClearForm(true, true);
|
||||
} else {
|
||||
UnsetFlags(MAYBE_ORPHAN_FORM_ELEMENT);
|
||||
// Recheck whether we should still have an form.
|
||||
if (HasAttr(kNameSpaceID_None, nsGkAtoms::form) ||
|
||||
!FindAncestorForm(form)) {
|
||||
ClearForm(true, true);
|
||||
} else {
|
||||
UnsetFlags(MAYBE_ORPHAN_FORM_ELEMENT);
|
||||
}
|
||||
}
|
||||
|
||||
if (!GetFormInternal()) {
|
||||
// Our novalidate state might have changed
|
||||
UpdateState(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (!GetFormInternal()) {
|
||||
// Our novalidate state might have changed
|
||||
UpdateState(false);
|
||||
// We have to remove the form id observer if there was one.
|
||||
// We will re-add one later if needed (during bind to tree).
|
||||
if (nsContentUtils::HasNonEmptyAttr(this, kNameSpaceID_None,
|
||||
nsGkAtoms::form)) {
|
||||
RemoveFormIdObserver();
|
||||
}
|
||||
}
|
||||
|
||||
// We have to remove the form id observer if there was one.
|
||||
// We will re-add one later if needed (during bind to tree).
|
||||
if (nsContentUtils::HasNonEmptyAttr(this, kNameSpaceID_None,
|
||||
nsGkAtoms::form)) {
|
||||
RemoveFormIdObserver();
|
||||
}
|
||||
|
||||
nsGenericHTMLElement::UnbindFromTree(aNullParent);
|
||||
|
||||
// The element might not have a fieldset anymore.
|
||||
@ -1749,7 +1754,7 @@ void nsGenericHTMLFormElement::UnbindFromTree(bool aNullParent) {
|
||||
nsresult nsGenericHTMLFormElement::BeforeSetAttr(
|
||||
int32_t aNameSpaceID, nsAtom* aName, const nsAttrValueOrString* aValue,
|
||||
bool aNotify) {
|
||||
if (aNameSpaceID == kNameSpaceID_None) {
|
||||
if (aNameSpaceID == kNameSpaceID_None && IsFormAssociatedElement()) {
|
||||
nsAutoString tmp;
|
||||
HTMLFormElement* form = GetFormInternal();
|
||||
|
||||
@ -1799,7 +1804,7 @@ nsresult nsGenericHTMLFormElement::AfterSetAttr(
|
||||
int32_t aNameSpaceID, nsAtom* aName, const nsAttrValue* aValue,
|
||||
const nsAttrValue* aOldValue, nsIPrincipal* aMaybeScriptedPrincipal,
|
||||
bool aNotify) {
|
||||
if (aNameSpaceID == kNameSpaceID_None) {
|
||||
if (aNameSpaceID == kNameSpaceID_None && IsFormAssociatedElement()) {
|
||||
HTMLFormElement* form = GetFormInternal();
|
||||
|
||||
// add the control to the hashtable as needed
|
||||
@ -1857,6 +1862,8 @@ void nsGenericHTMLFormElement::ForgetFieldSet(nsIContent* aFieldset) {
|
||||
}
|
||||
|
||||
Element* nsGenericHTMLFormElement::AddFormIdObserver() {
|
||||
MOZ_ASSERT(IsFormAssociatedElement());
|
||||
|
||||
nsAutoString formId;
|
||||
DocumentOrShadowRoot* docOrShadow = GetUncomposedDocOrConnectedShadowRoot();
|
||||
GetAttr(kNameSpaceID_None, nsGkAtoms::form, formId);
|
||||
@ -1868,6 +1875,8 @@ Element* nsGenericHTMLFormElement::AddFormIdObserver() {
|
||||
}
|
||||
|
||||
void nsGenericHTMLFormElement::RemoveFormIdObserver() {
|
||||
MOZ_ASSERT(IsFormAssociatedElement());
|
||||
|
||||
DocumentOrShadowRoot* docOrShadow = GetUncomposedDocOrConnectedShadowRoot();
|
||||
if (!docOrShadow) {
|
||||
return;
|
||||
@ -1948,6 +1957,7 @@ bool nsGenericHTMLFormElement::IsElementDisabledForEvents(WidgetEvent* aEvent,
|
||||
|
||||
void nsGenericHTMLFormElement::UpdateFormOwner(bool aBindToTree,
|
||||
Element* aFormIdElement) {
|
||||
MOZ_ASSERT(IsFormAssociatedElement());
|
||||
MOZ_ASSERT(!aBindToTree || !aFormIdElement,
|
||||
"aFormIdElement shouldn't be set if aBindToTree is true!");
|
||||
|
||||
@ -2023,7 +2033,7 @@ void nsGenericHTMLFormElement::UpdateFormOwner(bool aBindToTree,
|
||||
}
|
||||
|
||||
void nsGenericHTMLFormElement::UpdateFieldSet(bool aNotify) {
|
||||
if (IsInNativeAnonymousSubtree()) {
|
||||
if (IsInNativeAnonymousSubtree() || !IsFormAssociatedElement()) {
|
||||
MOZ_ASSERT(!GetFieldSetInternal());
|
||||
return;
|
||||
}
|
||||
|
@ -1081,6 +1081,12 @@ class nsGenericHTMLFormElement : public nsGenericHTMLElement {
|
||||
* Returns if the readonly attribute applies.
|
||||
*/
|
||||
virtual bool DoesReadOnlyApply() const { return false; }
|
||||
|
||||
/**
|
||||
* Returns true if the element is a form associated element.
|
||||
* See https://html.spec.whatwg.org/#form-associated-element.
|
||||
*/
|
||||
virtual bool IsFormAssociatedElement() const { return false; }
|
||||
};
|
||||
|
||||
class nsGenericHTMLFormControlElement : public nsGenericHTMLFormElement,
|
||||
@ -1140,6 +1146,7 @@ class nsGenericHTMLFormControlElement : public nsGenericHTMLFormElement,
|
||||
mozilla::dom::HTMLFieldSetElement* GetFieldSetInternal() const override;
|
||||
void SetFieldSetInternal(
|
||||
mozilla::dom::HTMLFieldSetElement* aFieldset) override;
|
||||
bool IsFormAssociatedElement() const override { return true; }
|
||||
|
||||
/**
|
||||
* Update our required/optional flags to match the given aIsRequired boolean.
|
||||
|
Loading…
Reference in New Issue
Block a user