Revert "Remove -moz-user-input disabled to improve event handling."
This reverts commit 0c209bc59c0a7f85c39cc657d17d812894156108.
This commit is contained in:
parent
b1b822ad39
commit
e2b2bd0a7c
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
a {
|
a {
|
||||||
-moz-user-focus: normal;
|
-moz-user-focus: normal;
|
||||||
|
-moz-user-input: enabled;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1440,6 +1440,8 @@ exports.CSS_PROPERTIES = {
|
||||||
"supports": [],
|
"supports": [],
|
||||||
"values": [
|
"values": [
|
||||||
"auto",
|
"auto",
|
||||||
|
"disabled",
|
||||||
|
"enabled",
|
||||||
"inherit",
|
"inherit",
|
||||||
"initial",
|
"initial",
|
||||||
"none",
|
"none",
|
||||||
|
|
|
@ -59,6 +59,8 @@ public:
|
||||||
using nsGenericHTMLElement::Focus;
|
using nsGenericHTMLElement::Focus;
|
||||||
virtual void Focus(mozilla::ErrorResult& aError) override;
|
virtual void Focus(mozilla::ErrorResult& aError) override;
|
||||||
|
|
||||||
|
virtual bool IsDisabled() const override { return false; }
|
||||||
|
|
||||||
// nsIContent
|
// nsIContent
|
||||||
virtual nsresult PostHandleEvent(
|
virtual nsresult PostHandleEvent(
|
||||||
EventChainPostVisitor& aVisitor) override;
|
EventChainPostVisitor& aVisitor) override;
|
||||||
|
|
|
@ -72,6 +72,8 @@ public:
|
||||||
NS_IMETHOD Reset() override;
|
NS_IMETHOD Reset() override;
|
||||||
NS_IMETHOD SubmitNamesValues(HTMLFormSubmission *aFormSubmission) override;
|
NS_IMETHOD SubmitNamesValues(HTMLFormSubmission *aFormSubmission) override;
|
||||||
|
|
||||||
|
virtual bool IsDisabled() const override { return false; }
|
||||||
|
|
||||||
virtual void DoneAddingChildren(bool aHaveNotified) override;
|
virtual void DoneAddingChildren(bool aHaveNotified) override;
|
||||||
virtual bool IsDoneAddingChildren() override;
|
virtual bool IsDoneAddingChildren() override;
|
||||||
|
|
||||||
|
|
|
@ -53,14 +53,15 @@ HTMLOptGroupElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
|
||||||
aVisitor.mCanHandle = false;
|
aVisitor.mCanHandle = false;
|
||||||
// Do not process any DOM events if the element is disabled
|
// Do not process any DOM events if the element is disabled
|
||||||
// XXXsmaug This is not the right thing to do. But what is?
|
// XXXsmaug This is not the right thing to do. But what is?
|
||||||
if (IsDisabled()) {
|
if (HasAttr(kNameSpaceID_None, nsGkAtoms::disabled)) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nsIFrame* frame = GetPrimaryFrame()) {
|
nsIFrame* frame = GetPrimaryFrame();
|
||||||
// FIXME(emilio): This poking at the style of the frame is broken unless we
|
if (frame) {
|
||||||
// flush before every event handling, which we don't really want to.
|
const nsStyleUserInterface* uiStyle = frame->StyleUserInterface();
|
||||||
if (frame->StyleUserInterface()->mUserInput == StyleUserInput::None) {
|
if (uiStyle->mUserInput == StyleUserInput::None ||
|
||||||
|
uiStyle->mUserInput == StyleUserInput::Disabled) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,10 @@ public:
|
||||||
|
|
||||||
virtual nsIDOMNode* AsDOMNode() override { return this; }
|
virtual nsIDOMNode* AsDOMNode() override { return this; }
|
||||||
|
|
||||||
|
virtual bool IsDisabled() const override {
|
||||||
|
return HasAttr(kNameSpaceID_None, nsGkAtoms::disabled);
|
||||||
|
}
|
||||||
|
|
||||||
bool Disabled() const
|
bool Disabled() const
|
||||||
{
|
{
|
||||||
return GetBoolAttr(nsGkAtoms::disabled);
|
return GetBoolAttr(nsGkAtoms::disabled);
|
||||||
|
|
|
@ -69,6 +69,10 @@ public:
|
||||||
|
|
||||||
nsresult CopyInnerTo(mozilla::dom::Element* aDest);
|
nsresult CopyInnerTo(mozilla::dom::Element* aDest);
|
||||||
|
|
||||||
|
virtual bool IsDisabled() const override {
|
||||||
|
return HasAttr(kNameSpaceID_None, nsGkAtoms::disabled);
|
||||||
|
}
|
||||||
|
|
||||||
bool Disabled() const
|
bool Disabled() const
|
||||||
{
|
{
|
||||||
return GetBoolAttr(nsGkAtoms::disabled);
|
return GetBoolAttr(nsGkAtoms::disabled);
|
||||||
|
|
|
@ -35,6 +35,8 @@ public:
|
||||||
NS_IMETHOD Reset() override;
|
NS_IMETHOD Reset() override;
|
||||||
NS_IMETHOD SubmitNamesValues(HTMLFormSubmission* aFormSubmission) override;
|
NS_IMETHOD SubmitNamesValues(HTMLFormSubmission* aFormSubmission) override;
|
||||||
|
|
||||||
|
virtual bool IsDisabled() const override { return false; }
|
||||||
|
|
||||||
nsresult Clone(mozilla::dom::NodeInfo* aNodeInfo, nsINode** aResult) const override;
|
nsresult Clone(mozilla::dom::NodeInfo* aNodeInfo, nsINode** aResult) const override;
|
||||||
|
|
||||||
bool ParseAttribute(int32_t aNamespaceID, nsIAtom* aAttribute,
|
bool ParseAttribute(int32_t aNamespaceID, nsIAtom* aAttribute,
|
||||||
|
|
|
@ -2108,6 +2108,14 @@ nsGenericHTMLFormElement::PreHandleEvent(EventChainVisitor& aVisitor)
|
||||||
return nsGenericHTMLElement::PreHandleEvent(aVisitor);
|
return nsGenericHTMLElement::PreHandleEvent(aVisitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* virtual */
|
||||||
|
bool
|
||||||
|
nsGenericHTMLFormElement::IsDisabled() const
|
||||||
|
{
|
||||||
|
return HasAttr(kNameSpaceID_None, nsGkAtoms::disabled) ||
|
||||||
|
(mFieldSet && mFieldSet->IsDisabled());
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsGenericHTMLFormElement::ForgetFieldSet(nsIContent* aFieldset)
|
nsGenericHTMLFormElement::ForgetFieldSet(nsIContent* aFieldset)
|
||||||
{
|
{
|
||||||
|
@ -2299,13 +2307,14 @@ nsGenericHTMLFormElement::IsElementDisabledForEvents(EventMessage aMessage,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(emilio): This poking at the style of the frame is slightly bogus
|
bool disabled = IsDisabled();
|
||||||
// unless we flush before every event, which we don't really want to do.
|
if (!disabled && aFrame) {
|
||||||
if (aFrame &&
|
const nsStyleUserInterface* uiStyle = aFrame->StyleUserInterface();
|
||||||
aFrame->StyleUserInterface()->mUserInput == StyleUserInput::None) {
|
disabled = uiStyle->mUserInput == StyleUserInput::None ||
|
||||||
return true;
|
uiStyle->mUserInput == StyleUserInput::Disabled;
|
||||||
|
|
||||||
}
|
}
|
||||||
return IsDisabled();
|
return disabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -807,8 +807,8 @@ public:
|
||||||
/**
|
/**
|
||||||
* Returns the current disabled state of the element.
|
* Returns the current disabled state of the element.
|
||||||
*/
|
*/
|
||||||
bool IsDisabled() const {
|
virtual bool IsDisabled() const {
|
||||||
return HasAttr(kNameSpaceID_None, nsGkAtoms::disabled);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsHidden() const
|
bool IsHidden() const
|
||||||
|
@ -1219,6 +1219,8 @@ public:
|
||||||
virtual nsresult PreHandleEvent(
|
virtual nsresult PreHandleEvent(
|
||||||
mozilla::EventChainVisitor& aVisitor) override;
|
mozilla::EventChainVisitor& aVisitor) override;
|
||||||
|
|
||||||
|
virtual bool IsDisabled() const override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This callback is called by a fieldest on all its elements whenever its
|
* This callback is called by a fieldest on all its elements whenever its
|
||||||
* disabled attribute is changed so the element knows its disabled state
|
* disabled attribute is changed so the element knows its disabled state
|
||||||
|
|
|
@ -1786,7 +1786,7 @@ interface nsIDOMWindowUtils : nsISupports {
|
||||||
/**
|
/**
|
||||||
* In certain cases the event handling of nodes, form controls in practice,
|
* In certain cases the event handling of nodes, form controls in practice,
|
||||||
* may be disabled. Such cases are for example the existence of disabled
|
* 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);
|
boolean isNodeDisabledForEvents(in nsIDOMNode aNode);
|
||||||
|
|
||||||
|
|
|
@ -511,7 +511,7 @@ nsCaret::GetPaintGeometry(nsRect* aRect)
|
||||||
CheckSelectionLanguageChange();
|
CheckSelectionLanguageChange();
|
||||||
|
|
||||||
int32_t frameOffset;
|
int32_t frameOffset;
|
||||||
nsIFrame* frame = GetFrameAndOffset(GetSelectionInternal(),
|
nsIFrame *frame = GetFrameAndOffset(GetSelectionInternal(),
|
||||||
mOverrideContent, mOverrideOffset, &frameOffset);
|
mOverrideContent, mOverrideOffset, &frameOffset);
|
||||||
if (!frame) {
|
if (!frame) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -521,7 +521,8 @@ nsCaret::GetPaintGeometry(nsRect* aRect)
|
||||||
const nsStyleUserInterface* userinterface = frame->StyleUserInterface();
|
const nsStyleUserInterface* userinterface = frame->StyleUserInterface();
|
||||||
if ((!mIgnoreUserModify &&
|
if ((!mIgnoreUserModify &&
|
||||||
userinterface->mUserModify == StyleUserModify::ReadOnly) ||
|
userinterface->mUserModify == StyleUserModify::ReadOnly) ||
|
||||||
frame->IsContentDisabled()){
|
userinterface->mUserInput == StyleUserInput::None ||
|
||||||
|
userinterface->mUserInput == StyleUserInput::Disabled) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1166,7 +1166,9 @@ nsComboboxControlFrame::HandleEvent(nsPresContext* aPresContext,
|
||||||
|
|
||||||
// If we have style that affects how we are selected, feed event down to
|
// If we have style that affects how we are selected, feed event down to
|
||||||
// nsFrame::HandleEvent so that selection takes place when appropriate.
|
// 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 nsBlockFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
|
@ -183,8 +183,10 @@ nsFormControlFrame::HandleEvent(nsPresContext* aPresContext,
|
||||||
WidgetGUIEvent* aEvent,
|
WidgetGUIEvent* aEvent,
|
||||||
nsEventStatus* aEventStatus)
|
nsEventStatus* aEventStatus)
|
||||||
{
|
{
|
||||||
// Check for disabled content so that selection works properly (?).
|
// Check for user-input:none style
|
||||||
if (IsContentDisabled()) {
|
const nsStyleUserInterface* uiStyle = StyleUserInterface();
|
||||||
|
if (uiStyle->mUserInput == StyleUserInput::None ||
|
||||||
|
uiStyle->mUserInput == StyleUserInput::Disabled) {
|
||||||
return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
|
return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
|
@ -203,7 +203,10 @@ nsGfxButtonControlFrame::HandleEvent(nsPresContext* aPresContext,
|
||||||
// from being called. The nsFrame::HandleEvent causes the button label
|
// from being called. The nsFrame::HandleEvent causes the button label
|
||||||
// to be selected (Drawn with an XOR rectangle over the 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 nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
|
@ -150,9 +150,15 @@ nsImageControlFrame::HandleEvent(nsPresContext* aPresContext,
|
||||||
return NS_OK;
|
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);
|
return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
|
||||||
}
|
}
|
||||||
|
if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::disabled)) { // XXX cache disabled
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
*aEventStatus = nsEventStatus_eIgnore;
|
*aEventStatus = nsEventStatus_eIgnore;
|
||||||
|
|
||||||
|
|
|
@ -919,11 +919,16 @@ nsListControlFrame::HandleEvent(nsPresContext* aPresContext,
|
||||||
if (nsEventStatus_eConsumeNoDefault == *aEventStatus)
|
if (nsEventStatus_eConsumeNoDefault == *aEventStatus)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
// disabled state affects how we're selected, but we don't want to go through
|
// do we have style that affects how we are selected?
|
||||||
// nsHTMLScrollFrame if we're disabled.
|
// do we have user-input style?
|
||||||
if (IsContentDisabled()) {
|
const nsStyleUserInterface* uiStyle = StyleUserInterface();
|
||||||
|
if (uiStyle->mUserInput == StyleUserInput::None ||
|
||||||
|
uiStyle->mUserInput == StyleUserInput::Disabled) {
|
||||||
return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
|
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);
|
return nsHTMLScrollFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5596,19 +5596,6 @@ nsFrame::Reflow(nsPresContext* aPresContext,
|
||||||
NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize);
|
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
|
nsresult
|
||||||
nsFrame::CharacterDataChanged(CharacterDataChangeInfo* aInfo)
|
nsFrame::CharacterDataChanged(CharacterDataChangeInfo* aInfo)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2440,11 +2440,6 @@ public:
|
||||||
*/
|
*/
|
||||||
nsIWidget* GetNearestWidget(nsPoint& aOffset) const;
|
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.
|
* Get the "type" of the frame. May return nullptr.
|
||||||
*
|
*
|
||||||
|
|
|
@ -2189,6 +2189,8 @@ const KTableEntry nsCSSProps::kUserFocusKTable[] = {
|
||||||
|
|
||||||
const KTableEntry nsCSSProps::kUserInputKTable[] = {
|
const KTableEntry nsCSSProps::kUserInputKTable[] = {
|
||||||
{ eCSSKeyword_none, StyleUserInput::None },
|
{ eCSSKeyword_none, StyleUserInput::None },
|
||||||
|
{ eCSSKeyword_enabled, StyleUserInput::Enabled },
|
||||||
|
{ eCSSKeyword_disabled, StyleUserInput::Disabled },
|
||||||
{ eCSSKeyword_auto, StyleUserInput::Auto },
|
{ eCSSKeyword_auto, StyleUserInput::Auto },
|
||||||
{ eCSSKeyword_UNKNOWN, -1 }
|
{ eCSSKeyword_UNKNOWN, -1 }
|
||||||
};
|
};
|
||||||
|
|
|
@ -241,6 +241,8 @@ enum class StyleUserSelect : uint8_t {
|
||||||
// user-input
|
// user-input
|
||||||
enum class StyleUserInput : uint8_t {
|
enum class StyleUserInput : uint8_t {
|
||||||
None,
|
None,
|
||||||
|
Enabled,
|
||||||
|
Disabled,
|
||||||
Auto,
|
Auto,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -425,6 +425,7 @@ optgroup:disabled,
|
||||||
select:disabled:disabled /* Need the pseudo-class twice to have the specificity
|
select:disabled:disabled /* Need the pseudo-class twice to have the specificity
|
||||||
be at least the same as select[size][multiple] above */
|
be at least the same as select[size][multiple] above */
|
||||||
{
|
{
|
||||||
|
-moz-user-input: disabled;
|
||||||
color: GrayText;
|
color: GrayText;
|
||||||
background-color: ThreeDLightShadow;
|
background-color: ThreeDLightShadow;
|
||||||
cursor: inherit;
|
cursor: inherit;
|
||||||
|
|
|
@ -2203,7 +2203,7 @@ var gCSSProperties = {
|
||||||
inherited: true,
|
inherited: true,
|
||||||
type: CSS_TYPE_LONGHAND,
|
type: CSS_TYPE_LONGHAND,
|
||||||
initial_values: [ "auto" ],
|
initial_values: [ "auto" ],
|
||||||
other_values: [ "none" ],
|
other_values: [ "none", "enabled", "disabled" ],
|
||||||
invalid_values: []
|
invalid_values: []
|
||||||
},
|
},
|
||||||
"-moz-user-modify": {
|
"-moz-user-modify": {
|
||||||
|
|
|
@ -15393,10 +15393,6 @@
|
||||||
"path": "dom/events/EventTarget-removeEventListener.html",
|
"path": "dom/events/EventTarget-removeEventListener.html",
|
||||||
"url": "/dom/events/EventTarget-removeEventListener.html"
|
"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",
|
"path": "dom/events/ProgressEvent.html",
|
||||||
"url": "/dom/events/ProgressEvent.html"
|
"url": "/dom/events/ProgressEvent.html"
|
||||||
|
|
|
@ -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>
|
|
Loading…
Reference in New Issue