summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMoonchild <moonchild@palemoon.org>2020-05-21 15:00:59 +0200
committerGitHub <noreply@github.com>2020-05-21 15:00:59 +0200
commit5d6691e9d08dce30b461fced32ece77fd3ff1933 (patch)
treef91d5ae02b0c2bcc41a08bb1a594c8a2ebe02eef
parent14f6f230d7545d3906a7fd72f3d4677f3b6503d8 (diff)
parent0a19762d3bb5f6bcaa00a8f168e469d9fdda76b9 (diff)
downloadUXP-5d6691e9d08dce30b461fced32ece77fd3ff1933.tar
UXP-5d6691e9d08dce30b461fced32ece77fd3ff1933.tar.gz
UXP-5d6691e9d08dce30b461fced32ece77fd3ff1933.tar.lz
UXP-5d6691e9d08dce30b461fced32ece77fd3ff1933.tar.xz
UXP-5d6691e9d08dce30b461fced32ece77fd3ff1933.zip
Merge pull request #1559 from athenian200/form-disabled-issue
Restore -moz-input-disabled and allow events to target disabled form controls.
-rw-r--r--devtools/client/themes/webconsole.css1
-rw-r--r--devtools/shared/css/generated/properties-db.js2
-rw-r--r--dom/base/nsDOMWindowUtils.cpp3
-rw-r--r--dom/html/HTMLButtonElement.cpp6
-rw-r--r--dom/html/HTMLButtonElement.h2
-rw-r--r--dom/html/HTMLFieldSetElement.cpp6
-rw-r--r--dom/html/HTMLFieldSetElement.h2
-rw-r--r--dom/html/HTMLInputElement.cpp6
-rw-r--r--dom/html/HTMLInputElement.h2
-rw-r--r--dom/html/HTMLLabelElement.h2
-rw-r--r--dom/html/HTMLObjectElement.h2
-rw-r--r--dom/html/HTMLOptGroupElement.cpp11
-rw-r--r--dom/html/HTMLOptGroupElement.h4
-rw-r--r--dom/html/HTMLOptionElement.h4
-rw-r--r--dom/html/HTMLOutputElement.h2
-rw-r--r--dom/html/HTMLSelectElement.cpp6
-rw-r--r--dom/html/HTMLSelectElement.h2
-rw-r--r--dom/html/HTMLTextAreaElement.cpp6
-rw-r--r--dom/html/HTMLTextAreaElement.h2
-rw-r--r--dom/html/nsGenericHTMLElement.cpp35
-rw-r--r--dom/html/nsGenericHTMLElement.h8
-rw-r--r--dom/html/nsIFormControl.h2
-rw-r--r--dom/interfaces/base/nsIDOMWindowUtils.idl2
-rw-r--r--layout/base/nsCaret.cpp5
-rw-r--r--layout/forms/nsComboboxControlFrame.cpp4
-rw-r--r--layout/forms/nsFormControlFrame.cpp6
-rw-r--r--layout/forms/nsGfxButtonControlFrame.cpp5
-rw-r--r--layout/forms/nsImageControlFrame.cpp8
-rw-r--r--layout/forms/nsListControlFrame.cpp11
-rw-r--r--layout/generic/nsFrame.cpp13
-rw-r--r--layout/generic/nsIFrame.h5
-rw-r--r--layout/style/nsCSSProps.cpp2
-rw-r--r--layout/style/nsStyleConsts.h2
-rw-r--r--layout/style/res/forms.css1
-rw-r--r--layout/style/test/property_database.js2
-rw-r--r--testing/web-platform/meta/MANIFEST.json4
-rw-r--r--testing/web-platform/tests/dom/events/event-disabled-dynamic.html21
37 files changed, 113 insertions, 94 deletions
diff --git a/devtools/client/themes/webconsole.css b/devtools/client/themes/webconsole.css
index 85c73264c..89bb38628 100644
--- a/devtools/client/themes/webconsole.css
+++ b/devtools/client/themes/webconsole.css
@@ -14,6 +14,7 @@
a {
-moz-user-focus: normal;
+ -moz-user-input: enabled;
cursor: pointer;
text-decoration: underline;
}
diff --git a/devtools/shared/css/generated/properties-db.js b/devtools/shared/css/generated/properties-db.js
index eda2c7148..25d9e2d33 100644
--- a/devtools/shared/css/generated/properties-db.js
+++ b/devtools/shared/css/generated/properties-db.js
@@ -1440,6 +1440,8 @@ exports.CSS_PROPERTIES = {
"supports": [],
"values": [
"auto",
+ "disabled",
+ "enabled",
"inherit",
"initial",
"none",
diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp
index a923e8f70..5e9235f11 100644
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -3577,7 +3577,8 @@ nsDOMWindowUtils::IsNodeDisabledForEvents(nsIDOMNode* aNode, bool* aRetVal)
while (node) {
if (node->IsNodeOfType(nsINode::eHTML_FORM_CONTROL)) {
nsCOMPtr<nsIFormControl> fc = do_QueryInterface(node);
- if (fc && fc->IsDisabledForEvents(eVoidEvent)) {
+ WidgetEvent event(true, eVoidEvent);
+ if (fc && fc->IsDisabledForEvents(&event)) {
*aRetVal = true;
break;
}
diff --git a/dom/html/HTMLButtonElement.cpp b/dom/html/HTMLButtonElement.cpp
index 1a76aac10..78db27679 100644
--- a/dom/html/HTMLButtonElement.cpp
+++ b/dom/html/HTMLButtonElement.cpp
@@ -199,18 +199,18 @@ HTMLButtonElement::ParseAttribute(int32_t aNamespaceID,
}
bool
-HTMLButtonElement::IsDisabledForEvents(EventMessage aMessage)
+HTMLButtonElement::IsDisabledForEvents(WidgetEvent* aEvent)
{
nsIFormControlFrame* formControlFrame = GetFormControlFrame(false);
nsIFrame* formFrame = do_QueryFrame(formControlFrame);
- return IsElementDisabledForEvents(aMessage, formFrame);
+ return IsElementDisabledForEvents(aEvent, formFrame);
}
nsresult
HTMLButtonElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
{
aVisitor.mCanHandle = false;
- if (IsDisabledForEvents(aVisitor.mEvent->mMessage)) {
+ if (IsDisabledForEvents(aVisitor.mEvent)) {
return NS_OK;
}
diff --git a/dom/html/HTMLButtonElement.h b/dom/html/HTMLButtonElement.h
index 8bab9fd48..34e5fd24d 100644
--- a/dom/html/HTMLButtonElement.h
+++ b/dom/html/HTMLButtonElement.h
@@ -52,7 +52,7 @@ public:
NS_IMETHOD SubmitNamesValues(HTMLFormSubmission* aFormSubmission) override;
NS_IMETHOD SaveState() override;
bool RestoreState(nsPresState* aState) override;
- virtual bool IsDisabledForEvents(EventMessage aMessage) override;
+ virtual bool IsDisabledForEvents(WidgetEvent* aEvent) override;
virtual void FieldSetDisabledChanged(bool aNotify) override;
diff --git a/dom/html/HTMLFieldSetElement.cpp b/dom/html/HTMLFieldSetElement.cpp
index f546cad5b..e7fb124c7 100644
--- a/dom/html/HTMLFieldSetElement.cpp
+++ b/dom/html/HTMLFieldSetElement.cpp
@@ -63,9 +63,9 @@ NS_IMPL_STRING_ATTR(HTMLFieldSetElement, Name, name)
NS_IMPL_NSICONSTRAINTVALIDATION(HTMLFieldSetElement)
bool
-HTMLFieldSetElement::IsDisabledForEvents(EventMessage aMessage)
+HTMLFieldSetElement::IsDisabledForEvents(WidgetEvent* aEvent)
{
- return IsElementDisabledForEvents(aMessage, nullptr);
+ return IsElementDisabledForEvents(aEvent, nullptr);
}
// nsIContent
@@ -74,7 +74,7 @@ HTMLFieldSetElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
{
// Do not process any DOM events if the element is disabled.
aVisitor.mCanHandle = false;
- if (IsDisabledForEvents(aVisitor.mEvent->mMessage)) {
+ if (IsDisabledForEvents(aVisitor.mEvent)) {
return NS_OK;
}
diff --git a/dom/html/HTMLFieldSetElement.h b/dom/html/HTMLFieldSetElement.h
index 2c0e9cc14..7f10e4a5b 100644
--- a/dom/html/HTMLFieldSetElement.h
+++ b/dom/html/HTMLFieldSetElement.h
@@ -55,7 +55,7 @@ public:
NS_IMETHOD_(uint32_t) GetType() const override { return NS_FORM_FIELDSET; }
NS_IMETHOD Reset() override;
NS_IMETHOD SubmitNamesValues(HTMLFormSubmission* aFormSubmission) override;
- virtual bool IsDisabledForEvents(EventMessage aMessage) override;
+ virtual bool IsDisabledForEvents(WidgetEvent* aEvent) override;
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const override;
const nsIContent* GetFirstLegend() const { return mFirstLegend; }
diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp
index 7708a60ac..f2c14ff2d 100644
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -3712,9 +3712,9 @@ HTMLInputElement::NeedToInitializeEditorForEvent(
}
bool
-HTMLInputElement::IsDisabledForEvents(EventMessage aMessage)
+HTMLInputElement::IsDisabledForEvents(WidgetEvent* aEvent)
{
- return IsElementDisabledForEvents(aMessage, GetPrimaryFrame());
+ return IsElementDisabledForEvents(aEvent, GetPrimaryFrame());
}
nsresult
@@ -3722,7 +3722,7 @@ HTMLInputElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
{
// Do not process any DOM events if the element is disabled
aVisitor.mCanHandle = false;
- if (IsDisabledForEvents(aVisitor.mEvent->mMessage)) {
+ if (IsDisabledForEvents(aVisitor.mEvent)) {
return NS_OK;
}
diff --git a/dom/html/HTMLInputElement.h b/dom/html/HTMLInputElement.h
index 55bb59ec9..d2aff5b1c 100644
--- a/dom/html/HTMLInputElement.h
+++ b/dom/html/HTMLInputElement.h
@@ -169,7 +169,7 @@ public:
NS_IMETHOD SaveState() override;
virtual bool RestoreState(nsPresState* aState) override;
virtual bool AllowDrop() override;
- virtual bool IsDisabledForEvents(EventMessage aMessage) override;
+ virtual bool IsDisabledForEvents(WidgetEvent* aEvent) override;
virtual void FieldSetDisabledChanged(bool aNotify) override;
diff --git a/dom/html/HTMLLabelElement.h b/dom/html/HTMLLabelElement.h
index 4057ffef6..c8385fc53 100644
--- a/dom/html/HTMLLabelElement.h
+++ b/dom/html/HTMLLabelElement.h
@@ -59,6 +59,8 @@ public:
using nsGenericHTMLElement::Focus;
virtual void Focus(mozilla::ErrorResult& aError) override;
+ virtual bool IsDisabled() const override { return false; }
+
// nsIContent
virtual nsresult PostHandleEvent(
EventChainPostVisitor& aVisitor) override;
diff --git a/dom/html/HTMLObjectElement.h b/dom/html/HTMLObjectElement.h
index 6ce09e1cc..016743c2c 100644
--- a/dom/html/HTMLObjectElement.h
+++ b/dom/html/HTMLObjectElement.h
@@ -72,6 +72,8 @@ public:
NS_IMETHOD Reset() override;
NS_IMETHOD SubmitNamesValues(HTMLFormSubmission *aFormSubmission) override;
+ virtual bool IsDisabled() const override { return false; }
+
virtual void DoneAddingChildren(bool aHaveNotified) override;
virtual bool IsDoneAddingChildren() override;
diff --git a/dom/html/HTMLOptGroupElement.cpp b/dom/html/HTMLOptGroupElement.cpp
index 63af4e39f..7467c5da3 100644
--- a/dom/html/HTMLOptGroupElement.cpp
+++ b/dom/html/HTMLOptGroupElement.cpp
@@ -53,14 +53,15 @@ HTMLOptGroupElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
aVisitor.mCanHandle = false;
// Do not process any DOM events if the element is disabled
// XXXsmaug This is not the right thing to do. But what is?
- if (IsDisabled()) {
+ if (HasAttr(kNameSpaceID_None, nsGkAtoms::disabled)) {
return NS_OK;
}
- if (nsIFrame* frame = GetPrimaryFrame()) {
- // FIXME(emilio): This poking at the style of the frame is broken unless we
- // flush before every event handling, which we don't really want to.
- if (frame->StyleUserInterface()->mUserInput == StyleUserInput::None) {
+ nsIFrame* frame = GetPrimaryFrame();
+ if (frame) {
+ const nsStyleUserInterface* uiStyle = frame->StyleUserInterface();
+ if (uiStyle->mUserInput == StyleUserInput::None ||
+ uiStyle->mUserInput == StyleUserInput::Disabled) {
return NS_OK;
}
}
diff --git a/dom/html/HTMLOptGroupElement.h b/dom/html/HTMLOptGroupElement.h
index 6853e51ed..d12f1c6d4 100644
--- a/dom/html/HTMLOptGroupElement.h
+++ b/dom/html/HTMLOptGroupElement.h
@@ -49,6 +49,10 @@ public:
virtual nsIDOMNode* AsDOMNode() override { return this; }
+ virtual bool IsDisabled() const override {
+ return HasAttr(kNameSpaceID_None, nsGkAtoms::disabled);
+ }
+
bool Disabled() const
{
return GetBoolAttr(nsGkAtoms::disabled);
diff --git a/dom/html/HTMLOptionElement.h b/dom/html/HTMLOptionElement.h
index 965cdeb8f..de556b645 100644
--- a/dom/html/HTMLOptionElement.h
+++ b/dom/html/HTMLOptionElement.h
@@ -69,6 +69,10 @@ public:
nsresult CopyInnerTo(mozilla::dom::Element* aDest);
+ virtual bool IsDisabled() const override {
+ return HasAttr(kNameSpaceID_None, nsGkAtoms::disabled);
+ }
+
bool Disabled() const
{
return GetBoolAttr(nsGkAtoms::disabled);
diff --git a/dom/html/HTMLOutputElement.h b/dom/html/HTMLOutputElement.h
index 6b6c3f66c..588262480 100644
--- a/dom/html/HTMLOutputElement.h
+++ b/dom/html/HTMLOutputElement.h
@@ -35,6 +35,8 @@ public:
NS_IMETHOD Reset() override;
NS_IMETHOD SubmitNamesValues(HTMLFormSubmission* aFormSubmission) override;
+ virtual bool IsDisabled() const override { return false; }
+
nsresult Clone(mozilla::dom::NodeInfo* aNodeInfo, nsINode** aResult) const override;
bool ParseAttribute(int32_t aNamespaceID, nsIAtom* aAttribute,
diff --git a/dom/html/HTMLSelectElement.cpp b/dom/html/HTMLSelectElement.cpp
index 36dac0852..022232d83 100644
--- a/dom/html/HTMLSelectElement.cpp
+++ b/dom/html/HTMLSelectElement.cpp
@@ -1419,21 +1419,21 @@ HTMLSelectElement::GetAttributeMappingFunction() const
}
bool
-HTMLSelectElement::IsDisabledForEvents(EventMessage aMessage)
+HTMLSelectElement::IsDisabledForEvents(WidgetEvent* aEvent)
{
nsIFormControlFrame* formControlFrame = GetFormControlFrame(false);
nsIFrame* formFrame = nullptr;
if (formControlFrame) {
formFrame = do_QueryFrame(formControlFrame);
}
- return IsElementDisabledForEvents(aMessage, formFrame);
+ return IsElementDisabledForEvents(aEvent, formFrame);
}
nsresult
HTMLSelectElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
{
aVisitor.mCanHandle = false;
- if (IsDisabledForEvents(aVisitor.mEvent->mMessage)) {
+ if (IsDisabledForEvents(aVisitor.mEvent)) {
return NS_OK;
}
diff --git a/dom/html/HTMLSelectElement.h b/dom/html/HTMLSelectElement.h
index 298b1a8d1..0e23f56d4 100644
--- a/dom/html/HTMLSelectElement.h
+++ b/dom/html/HTMLSelectElement.h
@@ -294,7 +294,7 @@ public:
NS_IMETHOD SubmitNamesValues(HTMLFormSubmission* aFormSubmission) override;
NS_IMETHOD SaveState() override;
virtual bool RestoreState(nsPresState* aState) override;
- virtual bool IsDisabledForEvents(EventMessage aMessage) override;
+ virtual bool IsDisabledForEvents(WidgetEvent* aEvent) override;
virtual void FieldSetDisabledChanged(bool aNotify) override;
diff --git a/dom/html/HTMLTextAreaElement.cpp b/dom/html/HTMLTextAreaElement.cpp
index f25241d60..0040f083b 100644
--- a/dom/html/HTMLTextAreaElement.cpp
+++ b/dom/html/HTMLTextAreaElement.cpp
@@ -498,18 +498,18 @@ HTMLTextAreaElement::GetAttributeMappingFunction() const
}
bool
-HTMLTextAreaElement::IsDisabledForEvents(EventMessage aMessage)
+HTMLTextAreaElement::IsDisabledForEvents(WidgetEvent* aEvent)
{
nsIFormControlFrame* formControlFrame = GetFormControlFrame(false);
nsIFrame* formFrame = do_QueryFrame(formControlFrame);
- return IsElementDisabledForEvents(aMessage, formFrame);
+ return IsElementDisabledForEvents(aEvent, formFrame);
}
nsresult
HTMLTextAreaElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
{
aVisitor.mCanHandle = false;
- if (IsDisabledForEvents(aVisitor.mEvent->mMessage)) {
+ if (IsDisabledForEvents(aVisitor.mEvent)) {
return NS_OK;
}
diff --git a/dom/html/HTMLTextAreaElement.h b/dom/html/HTMLTextAreaElement.h
index 5ab58554e..e5fef8263 100644
--- a/dom/html/HTMLTextAreaElement.h
+++ b/dom/html/HTMLTextAreaElement.h
@@ -77,7 +77,7 @@ public:
NS_IMETHOD SubmitNamesValues(HTMLFormSubmission* aFormSubmission) override;
NS_IMETHOD SaveState() override;
virtual bool RestoreState(nsPresState* aState) override;
- virtual bool IsDisabledForEvents(EventMessage aMessage) override;
+ virtual bool IsDisabledForEvents(WidgetEvent* aEvent) override;
virtual void FieldSetDisabledChanged(bool aNotify) override;
diff --git a/dom/html/nsGenericHTMLElement.cpp b/dom/html/nsGenericHTMLElement.cpp
index 3cf19ea8f..17dba6da9 100644
--- a/dom/html/nsGenericHTMLElement.cpp
+++ b/dom/html/nsGenericHTMLElement.cpp
@@ -2108,6 +2108,14 @@ nsGenericHTMLFormElement::PreHandleEvent(EventChainVisitor& aVisitor)
return nsGenericHTMLElement::PreHandleEvent(aVisitor);
}
+/* virtual */
+bool
+nsGenericHTMLFormElement::IsDisabled() const
+{
+ return HasAttr(kNameSpaceID_None, nsGkAtoms::disabled) ||
+ (mFieldSet && mFieldSet->IsDisabled());
+}
+
void
nsGenericHTMLFormElement::ForgetFieldSet(nsIContent* aFieldset)
{
@@ -2277,10 +2285,17 @@ nsGenericHTMLFormElement::FormIdUpdated(Element* aOldElement,
}
bool
-nsGenericHTMLFormElement::IsElementDisabledForEvents(EventMessage aMessage,
+nsGenericHTMLFormElement::IsElementDisabledForEvents(WidgetEvent* aEvent,
nsIFrame* aFrame)
{
- switch (aMessage) {
+ MOZ_ASSERT(aEvent);
+
+ // Allow dispatch of CustomEvent and untrusted Events.
+ if (!aEvent->IsTrusted()) {
+ return false;
+ }
+
+ switch (aEvent->mMessage) {
case eMouseMove:
case eMouseOver:
case eMouseOut:
@@ -2299,13 +2314,14 @@ nsGenericHTMLFormElement::IsElementDisabledForEvents(EventMessage aMessage,
break;
}
- // FIXME(emilio): This poking at the style of the frame is slightly bogus
- // unless we flush before every event, which we don't really want to do.
- if (aFrame &&
- aFrame->StyleUserInterface()->mUserInput == StyleUserInput::None) {
- return true;
+ bool disabled = IsDisabled();
+ if (!disabled && aFrame) {
+ const nsStyleUserInterface* uiStyle = aFrame->StyleUserInterface();
+ disabled = uiStyle->mUserInput == StyleUserInput::None ||
+ uiStyle->mUserInput == StyleUserInput::Disabled;
+
}
- return IsDisabled();
+ return disabled;
}
void
@@ -2445,8 +2461,9 @@ nsGenericHTMLFormElement::IsLabelable() const
void
nsGenericHTMLElement::Click()
{
- if (HandlingClick())
+ if (IsDisabled() || HandlingClick()) {
return;
+ }
// Strong in case the event kills it
nsCOMPtr<nsIDocument> doc = GetComposedDoc();
diff --git a/dom/html/nsGenericHTMLElement.h b/dom/html/nsGenericHTMLElement.h
index 1b0977fa2..c9169df11 100644
--- a/dom/html/nsGenericHTMLElement.h
+++ b/dom/html/nsGenericHTMLElement.h
@@ -807,8 +807,8 @@ public:
/**
* Returns the current disabled state of the element.
*/
- bool IsDisabled() const {
- return HasAttr(kNameSpaceID_None, nsGkAtoms::disabled);
+ virtual bool IsDisabled() const {
+ return false;
}
bool IsHidden() const
@@ -1219,6 +1219,8 @@ public:
virtual nsresult PreHandleEvent(
mozilla::EventChainVisitor& aVisitor) override;
+ virtual bool IsDisabled() const override;
+
/**
* This callback is called by a fieldest on all its elements whenever its
* disabled attribute is changed so the element knows its disabled state
@@ -1305,7 +1307,7 @@ protected:
void* aData);
// Returns true if the event should not be handled from GetEventTargetParent
- bool IsElementDisabledForEvents(mozilla::EventMessage aMessage,
+ bool IsElementDisabledForEvents(mozilla::WidgetEvent* aEvent,
nsIFrame* aFrame);
// The focusability state of this form control. eUnfocusable means that it
diff --git a/dom/html/nsIFormControl.h b/dom/html/nsIFormControl.h
index 34380bc67..22f1d08b3 100644
--- a/dom/html/nsIFormControl.h
+++ b/dom/html/nsIFormControl.h
@@ -207,7 +207,7 @@ public:
*/
inline bool AllowDraggableChildren() const;
- virtual bool IsDisabledForEvents(mozilla::EventMessage aMessage)
+ virtual bool IsDisabledForEvents(mozilla::WidgetEvent* aEvent)
{
return false;
}
diff --git a/dom/interfaces/base/nsIDOMWindowUtils.idl b/dom/interfaces/base/nsIDOMWindowUtils.idl
index fcfe407e8..70ec7e0ae 100644
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -1786,7 +1786,7 @@ interface nsIDOMWindowUtils : nsISupports {
/**
* In certain cases the event handling of nodes, form controls in practice,
* may be disabled. Such cases are for example the existence of disabled
- * attribute or -moz-user-input: none.
+ * attribute or -moz-user-input: none/disabled.
*/
boolean isNodeDisabledForEvents(in nsIDOMNode aNode);
diff --git a/layout/base/nsCaret.cpp b/layout/base/nsCaret.cpp
index 8396726c6..eca22f3ba 100644
--- a/layout/base/nsCaret.cpp
+++ b/layout/base/nsCaret.cpp
@@ -511,7 +511,7 @@ nsCaret::GetPaintGeometry(nsRect* aRect)
CheckSelectionLanguageChange();
int32_t frameOffset;
- nsIFrame* frame = GetFrameAndOffset(GetSelectionInternal(),
+ nsIFrame *frame = GetFrameAndOffset(GetSelectionInternal(),
mOverrideContent, mOverrideOffset, &frameOffset);
if (!frame) {
return nullptr;
@@ -521,7 +521,8 @@ nsCaret::GetPaintGeometry(nsRect* aRect)
const nsStyleUserInterface* userinterface = frame->StyleUserInterface();
if ((!mIgnoreUserModify &&
userinterface->mUserModify == StyleUserModify::ReadOnly) ||
- frame->IsContentDisabled()){
+ userinterface->mUserInput == StyleUserInput::None ||
+ userinterface->mUserInput == StyleUserInput::Disabled) {
return nullptr;
}
diff --git a/layout/forms/nsComboboxControlFrame.cpp b/layout/forms/nsComboboxControlFrame.cpp
index 1064778d6..9db6ae5e4 100644
--- a/layout/forms/nsComboboxControlFrame.cpp
+++ b/layout/forms/nsComboboxControlFrame.cpp
@@ -1166,7 +1166,9 @@ nsComboboxControlFrame::HandleEvent(nsPresContext* aPresContext,
// If we have style that affects how we are selected, feed event down to
// nsFrame::HandleEvent so that selection takes place when appropriate.
- if (IsContentDisabled()) {
+ const nsStyleUserInterface* uiStyle = StyleUserInterface();
+ if (uiStyle->mUserInput == StyleUserInput::None ||
+ uiStyle->mUserInput == StyleUserInput::Disabled) {
return nsBlockFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
}
return NS_OK;
diff --git a/layout/forms/nsFormControlFrame.cpp b/layout/forms/nsFormControlFrame.cpp
index 8dbe564dd..4ee62acbf 100644
--- a/layout/forms/nsFormControlFrame.cpp
+++ b/layout/forms/nsFormControlFrame.cpp
@@ -183,8 +183,10 @@ nsFormControlFrame::HandleEvent(nsPresContext* aPresContext,
WidgetGUIEvent* aEvent,
nsEventStatus* aEventStatus)
{
- // Check for disabled content so that selection works properly (?).
- if (IsContentDisabled()) {
+ // Check for user-input:none style
+ const nsStyleUserInterface* uiStyle = StyleUserInterface();
+ if (uiStyle->mUserInput == StyleUserInput::None ||
+ uiStyle->mUserInput == StyleUserInput::Disabled) {
return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
}
return NS_OK;
diff --git a/layout/forms/nsGfxButtonControlFrame.cpp b/layout/forms/nsGfxButtonControlFrame.cpp
index df729c1aa..768abbc21 100644
--- a/layout/forms/nsGfxButtonControlFrame.cpp
+++ b/layout/forms/nsGfxButtonControlFrame.cpp
@@ -203,7 +203,10 @@ nsGfxButtonControlFrame::HandleEvent(nsPresContext* aPresContext,
// from being called. The nsFrame::HandleEvent causes the button label
// to be selected (Drawn with an XOR rectangle over the label)
- if (IsContentDisabled()) {
+ // do we have user-input style?
+ const nsStyleUserInterface* uiStyle = StyleUserInterface();
+ if (uiStyle->mUserInput == StyleUserInput::None ||
+ uiStyle->mUserInput == StyleUserInput::Disabled) {
return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
}
return NS_OK;
diff --git a/layout/forms/nsImageControlFrame.cpp b/layout/forms/nsImageControlFrame.cpp
index 8aef41538..212fa9356 100644
--- a/layout/forms/nsImageControlFrame.cpp
+++ b/layout/forms/nsImageControlFrame.cpp
@@ -150,9 +150,15 @@ nsImageControlFrame::HandleEvent(nsPresContext* aPresContext,
return NS_OK;
}
- if (IsContentDisabled()) {
+ // do we have user-input style?
+ const nsStyleUserInterface* uiStyle = StyleUserInterface();
+ if (uiStyle->mUserInput == StyleUserInput::None ||
+ uiStyle->mUserInput == StyleUserInput::Disabled) {
return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
}
+ if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::disabled)) { // XXX cache disabled
+ return NS_OK;
+ }
*aEventStatus = nsEventStatus_eIgnore;
diff --git a/layout/forms/nsListControlFrame.cpp b/layout/forms/nsListControlFrame.cpp
index 2233c5996..7bd356a22 100644
--- a/layout/forms/nsListControlFrame.cpp
+++ b/layout/forms/nsListControlFrame.cpp
@@ -919,11 +919,16 @@ nsListControlFrame::HandleEvent(nsPresContext* aPresContext,
if (nsEventStatus_eConsumeNoDefault == *aEventStatus)
return NS_OK;
- // disabled state affects how we're selected, but we don't want to go through
- // nsHTMLScrollFrame if we're disabled.
- if (IsContentDisabled()) {
+ // do we have style that affects how we are selected?
+ // do we have user-input style?
+ const nsStyleUserInterface* uiStyle = StyleUserInterface();
+ if (uiStyle->mUserInput == StyleUserInput::None ||
+ uiStyle->mUserInput == StyleUserInput::Disabled) {
return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
}
+ EventStates eventStates = mContent->AsElement()->State();
+ if (eventStates.HasState(NS_EVENT_STATE_DISABLED))
+ return NS_OK;
return nsHTMLScrollFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
}
diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp
index 1c31f517d..dd7933b03 100644
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -5596,19 +5596,6 @@ nsFrame::Reflow(nsPresContext* aPresContext,
NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize);
}
-bool
-nsIFrame::IsContentDisabled() const
-{
- // FIXME(emilio): Doing this via CSS means callers must ensure the style is up
- // to date, and they don't!
- if (StyleUserInterface()->mUserInput == StyleUserInput::None) {
- return true;
- }
-
- auto* element = nsGenericHTMLElement::FromContentOrNull(GetContent());
- return element && element->IsDisabled();
-}
-
nsresult
nsFrame::CharacterDataChanged(CharacterDataChangeInfo* aInfo)
{
diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h
index 3db18a9a6..dfe83bcbe 100644
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -2441,11 +2441,6 @@ public:
nsIWidget* GetNearestWidget(nsPoint& aOffset) const;
/**
- * Whether the content for this frame is disabled, used for event handling.
- */
- bool IsContentDisabled() const;
-
- /**
* Get the "type" of the frame. May return nullptr.
*
* @see nsGkAtoms
diff --git a/layout/style/nsCSSProps.cpp b/layout/style/nsCSSProps.cpp
index 289a16ecd..ac2978c27 100644
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -2189,6 +2189,8 @@ const KTableEntry nsCSSProps::kUserFocusKTable[] = {
const KTableEntry nsCSSProps::kUserInputKTable[] = {
{ eCSSKeyword_none, StyleUserInput::None },
+ { eCSSKeyword_enabled, StyleUserInput::Enabled },
+ { eCSSKeyword_disabled, StyleUserInput::Disabled },
{ eCSSKeyword_auto, StyleUserInput::Auto },
{ eCSSKeyword_UNKNOWN, -1 }
};
diff --git a/layout/style/nsStyleConsts.h b/layout/style/nsStyleConsts.h
index 5412eed26..6d207aec9 100644
--- a/layout/style/nsStyleConsts.h
+++ b/layout/style/nsStyleConsts.h
@@ -241,6 +241,8 @@ enum class StyleUserSelect : uint8_t {
// user-input
enum class StyleUserInput : uint8_t {
None,
+ Enabled,
+ Disabled,
Auto,
};
diff --git a/layout/style/res/forms.css b/layout/style/res/forms.css
index c91c2f739..db75151d4 100644
--- a/layout/style/res/forms.css
+++ b/layout/style/res/forms.css
@@ -425,6 +425,7 @@ optgroup:disabled,
select:disabled:disabled /* Need the pseudo-class twice to have the specificity
be at least the same as select[size][multiple] above */
{
+ -moz-user-input: disabled;
color: GrayText;
background-color: ThreeDLightShadow;
cursor: inherit;
diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js
index 3486d15d0..c75f7b498 100644
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -2203,7 +2203,7 @@ var gCSSProperties = {
inherited: true,
type: CSS_TYPE_LONGHAND,
initial_values: [ "auto" ],
- other_values: [ "none" ],
+ other_values: [ "none", "enabled", "disabled" ],
invalid_values: []
},
"-moz-user-modify": {
diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json
index 4dbbdf43e..03dda4a1f 100644
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -15394,10 +15394,6 @@
"url": "/dom/events/EventTarget-removeEventListener.html"
},
{
- "path": "dom/events/event-disabled-dynamic.html",
- "url": "/dom/events/event-disabled-dynamic.html"
- },
- {
"path": "dom/events/ProgressEvent.html",
"url": "/dom/events/ProgressEvent.html"
},
diff --git a/testing/web-platform/tests/dom/events/event-disabled-dynamic.html b/testing/web-platform/tests/dom/events/event-disabled-dynamic.html
deleted file mode 100644
index 89a3d3b15..000000000
--- a/testing/web-platform/tests/dom/events/event-disabled-dynamic.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<!doctype html>
-<meta charset=utf-8>
-<title>Test that disabled is honored immediately in presence of dynamic changes</title>
-<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
-<link rel="author" title="Andreas Farre" href="mailto:afarre@mozilla.com">
-<link rel="help" href="https://html.spec.whatwg.org/multipage/#enabling-and-disabling-form-controls:-the-disabled-attribute">
-<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1405087">
-<script src=/resources/testharness.js></script>
-<script src=/resources/testharnessreport.js></script>
-<input type="button" value="Click" disabled>
-<script>
-async_test(t => {
- window.addEventListener('load', t.step_func(() => {
-+
-− let e = document.querySelector('input');
- e.disabled = false;
- e.onclick = t.step_func_done(() => {});
- e.click();
- }));
-}, "disabled is honored properly in presence of dynamic changes");
-</script>