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 {
|
||||
-moz-user-focus: normal;
|
||||
-moz-user-input: enabled;
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
|
|
@ -1440,6 +1440,8 @@ exports.CSS_PROPERTIES = {
|
|||
"supports": [],
|
||||
"values": [
|
||||
"auto",
|
||||
"disabled",
|
||||
"enabled",
|
||||
"inherit",
|
||||
"initial",
|
||||
"none",
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
@ -2299,13 +2307,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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -2440,11 +2440,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.
|
||||
*
|
||||
|
|
|
@ -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 }
|
||||
};
|
||||
|
|
|
@ -241,6 +241,8 @@ enum class StyleUserSelect : uint8_t {
|
|||
// user-input
|
||||
enum class StyleUserInput : uint8_t {
|
||||
None,
|
||||
Enabled,
|
||||
Disabled,
|
||||
Auto,
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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": {
|
||||
|
|
|
@ -15393,10 +15393,6 @@
|
|||
"path": "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",
|
||||
"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