From 84bfb83b16ae6aabdead731bb33c6e430f319608 Mon Sep 17 00:00:00 2001 From: Cameron Kaiser Date: Mon, 16 Oct 2017 21:35:53 -0700 Subject: [PATCH] #438: M1375599 --- dom/base/Element.h | 10 +++++ dom/events/EventStates.h | 3 ++ dom/html/HTMLButtonElement.cpp | 13 +++++- dom/html/HTMLFieldSetElement.cpp | 25 ++++++----- dom/html/HTMLInputElement.cpp | 15 ++++++- dom/html/HTMLLabelElement.h | 2 - dom/html/HTMLOptGroupElement.cpp | 44 +++++++++--------- dom/html/HTMLOptGroupElement.h | 4 +- dom/html/HTMLOptionElement.cpp | 75 ++++++++++++++++++++----------- dom/html/HTMLOptionElement.h | 15 ++++++- dom/html/HTMLSelectElement.cpp | 15 ++++++- dom/html/HTMLTextAreaElement.cpp | 15 ++++++- dom/html/nsGenericHTMLElement.cpp | 43 ++++++++++++------ dom/html/nsGenericHTMLElement.h | 6 +++ 14 files changed, 198 insertions(+), 87 deletions(-) diff --git a/dom/base/Element.h b/dom/base/Element.h index 2665686b4..f0c431c36 100644 --- a/dom/base/Element.h +++ b/dom/base/Element.h @@ -451,6 +451,16 @@ protected: RemoveStatesSilently(aStates); NotifyStateChange(aStates); } + virtual void ToggleStates(EventStates aStates, bool aNotify) + { + NS_PRECONDITION(!aStates.HasAtLeastOneOfStates(INTRINSIC_STATES), + "Should only be removing ESM-managed states here"); + mState ^= aStates; + if (aNotify) { + NotifyStateChange(aStates); + } + } + public: virtual void UpdateEditableState(bool aNotify) override; diff --git a/dom/events/EventStates.h b/dom/events/EventStates.h index 3fc72cd34..fe8f0315b 100644 --- a/dom/events/EventStates.h +++ b/dom/events/EventStates.h @@ -276,10 +276,13 @@ private: #define DIRECTION_STATES (NS_EVENT_STATE_LTR | NS_EVENT_STATE_RTL) +#define DISABLED_STATES (NS_EVENT_STATE_DISABLED | NS_EVENT_STATE_ENABLED) + #define ESM_MANAGED_STATES (NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_FOCUS | \ NS_EVENT_STATE_HOVER | NS_EVENT_STATE_DRAGOVER | \ NS_EVENT_STATE_URLTARGET | NS_EVENT_STATE_FOCUSRING | \ NS_EVENT_STATE_FULL_SCREEN | NS_EVENT_STATE_FULL_SCREEN_ANCESTOR | \ + DISABLED_STATES | \ NS_EVENT_STATE_UNRESOLVED) #define INTRINSIC_STATES (~ESM_MANAGED_STATES) diff --git a/dom/html/HTMLButtonElement.cpp b/dom/html/HTMLButtonElement.cpp index 8cb878161..ddcc7dd22 100644 --- a/dom/html/HTMLButtonElement.cpp +++ b/dom/html/HTMLButtonElement.cpp @@ -113,9 +113,14 @@ HTMLButtonElement::UpdateBarredFromConstraintValidation() void HTMLButtonElement::FieldSetDisabledChanged(bool aNotify) { - UpdateBarredFromConstraintValidation(); + // FieldSetDisabledChanged *has* to be called *before* + // UpdateBarredFromConstraintValidation, because the latter depends on our + // disabled state. nsGenericHTMLFormElementWithState::FieldSetDisabledChanged(aNotify); + + UpdateBarredFromConstraintValidation(); + UpdateState(aNotify); } // nsIDOMHTMLButtonElement @@ -522,6 +527,12 @@ HTMLButtonElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, } if (aName == nsGkAtoms::type || aName == nsGkAtoms::disabled) { + if (aName == nsGkAtoms::disabled) { + // This *has* to be called *before* validity state check because + // UpdateBarredFromConstraintValidation depends on our disabled state. + UpdateDisabledState(aNotify); + } + UpdateBarredFromConstraintValidation(); UpdateState(aNotify); } diff --git a/dom/html/HTMLFieldSetElement.cpp b/dom/html/HTMLFieldSetElement.cpp index 771aedf29..41462b73a 100644 --- a/dom/html/HTMLFieldSetElement.cpp +++ b/dom/html/HTMLFieldSetElement.cpp @@ -85,17 +85,22 @@ nsresult HTMLFieldSetElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, const nsAttrValue* aValue, bool aNotify) { - if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::disabled && - nsINode::GetFirstChild()) { - if (!mElements) { - mElements = new nsContentList(this, MatchListedElements, nullptr, nullptr, - true); - } + if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::disabled) { + // This *has* to be called *before* calling FieldSetDisabledChanged on our + // controls, as they may depend on our disabled state. + UpdateDisabledState(aNotify); - uint32_t length = mElements->Length(true); - for (uint32_t i=0; i(mElements->Item(i)) - ->FieldSetDisabledChanged(aNotify); + if (nsINode::GetFirstChild()) { + if (!mElements) { + mElements = new nsContentList(this, MatchListedElements, nullptr, nullptr, + true); + } + + uint32_t length = mElements->Length(true); + for (uint32_t i=0; i(mElements->Item(i)) + ->FieldSetDisabledChanged(aNotify); + } } } diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp index efad22107..24a88ce53 100644 --- a/dom/html/HTMLInputElement.cpp +++ b/dom/html/HTMLInputElement.cpp @@ -1142,6 +1142,13 @@ HTMLInputElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, if (aName == nsGkAtoms::required || aName == nsGkAtoms::disabled || aName == nsGkAtoms::readonly) { + if (aName == nsGkAtoms::disabled) { + // This *has* to be called *before* validity state check because + // UpdateBarredFromConstraintValidation and + // UpdateValueMissingValidityState depend on our disabled state. + UpdateDisabledState(aNotify); + } + UpdateValueMissingValidityState(); // This *has* to be called *after* validity has changed. @@ -7192,10 +7199,14 @@ HTMLInputElement::HasCachedSelection() void HTMLInputElement::FieldSetDisabledChanged(bool aNotify) { + // This *has* to be called *before* UpdateBarredFromConstraintValidation and + // UpdateValueMissingValidityState because these two functions depend on our + // disabled state. + nsGenericHTMLFormElementWithState::FieldSetDisabledChanged(aNotify); + UpdateValueMissingValidityState(); UpdateBarredFromConstraintValidation(); - - nsGenericHTMLFormElementWithState::FieldSetDisabledChanged(aNotify); + UpdateState(aNotify); } void diff --git a/dom/html/HTMLLabelElement.h b/dom/html/HTMLLabelElement.h index 81aaae1a7..12cfa2d46 100644 --- a/dom/html/HTMLLabelElement.h +++ b/dom/html/HTMLLabelElement.h @@ -64,8 +64,6 @@ public: NS_IMETHOD Reset() override; NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission) override; - virtual bool IsDisabled() const override { return false; } - // nsIContent virtual nsresult PostHandleEvent( EventChainPostVisitor& aVisitor) override; diff --git a/dom/html/HTMLOptGroupElement.cpp b/dom/html/HTMLOptGroupElement.cpp index 8e5232019..f8ed4c9bc 100644 --- a/dom/html/HTMLOptGroupElement.cpp +++ b/dom/html/HTMLOptGroupElement.cpp @@ -105,13 +105,27 @@ HTMLOptGroupElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, const nsAttrValue* aValue, bool aNotify) { if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::disabled) { - // All our children