From 3c34ed2d2f312a08d0bbc3db4e0063647a7e5ab8 Mon Sep 17 00:00:00 2001 From: Jonathan Watt Date: Wed, 11 Dec 2013 02:13:06 +0000 Subject: [PATCH] Bug 948549 - Make behave and look disabled when the 'disabled' attribute is set or it's inside a disabled fieldset. r=smaug --- layout/forms/nsNumberControlFrame.cpp | 24 +++++++++++++++ layout/forms/nsNumberControlFrame.h | 30 ++++++++++++++++++- layout/reftests/bugs/557087-1.html | 1 + layout/reftests/bugs/557087-2.html | 1 + layout/reftests/bugs/557087-ref.html | 1 + .../input/number/number-disabled-ref.html | 8 +++++ .../forms/input/number/number-disabled.html | 8 +++++ .../reftests/forms/input/number/reftest.list | 3 ++ widget/xpwidgets/nsNativeTheme.cpp | 8 +++++ 9 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 layout/reftests/forms/input/number/number-disabled-ref.html create mode 100644 layout/reftests/forms/input/number/number-disabled.html diff --git a/layout/forms/nsNumberControlFrame.cpp b/layout/forms/nsNumberControlFrame.cpp index ef3a85f787fe..8e6efb12d2b8 100644 --- a/layout/forms/nsNumberControlFrame.cpp +++ b/layout/forms/nsNumberControlFrame.cpp @@ -150,11 +150,24 @@ nsNumberControlFrame:: xoffset, yoffset, 0); } +void +nsNumberControlFrame::SyncDisabledState() +{ + nsEventStates eventStates = mContent->AsElement()->State(); + if (eventStates.HasState(NS_EVENT_STATE_DISABLED)) { + mTextField->SetAttr(kNameSpaceID_None, nsGkAtoms::disabled, EmptyString(), + true); + } else { + mTextField->UnsetAttr(kNameSpaceID_None, nsGkAtoms::disabled, true); + } +} + NS_IMETHODIMP nsNumberControlFrame::AttributeChanged(int32_t aNameSpaceID, nsIAtom* aAttribute, int32_t aModType) { + // nsGkAtoms::disabled is handled by SyncDisabledState if (aNameSpaceID == kNameSpaceID_None) { if (aAttribute == nsGkAtoms::placeholder || aAttribute == nsGkAtoms::readonly || @@ -175,6 +188,14 @@ nsNumberControlFrame::AttributeChanged(int32_t aNameSpaceID, aModType); } +void +nsNumberControlFrame::ContentStatesChanged(nsEventStates aStates) +{ + if (aStates.HasState(NS_EVENT_STATE_DISABLED)) { + nsContentUtils::AddScriptRunner(new SyncDisabledStateEvent(this)); + } +} + nsresult nsNumberControlFrame::MakeAnonymousElement(Element** aResult, nsTArray& aElements, @@ -310,6 +331,9 @@ nsNumberControlFrame::CreateAnonymousContent(nsTArray& aElements) nsGkAtoms::div, nsCSSPseudoElements::ePseudo_mozNumberSpinDown, spinBoxCI.mStyleContext); + + SyncDisabledState(); + return rv; } diff --git a/layout/forms/nsNumberControlFrame.h b/layout/forms/nsNumberControlFrame.h index a82c24043e38..407c22d0fcbe 100644 --- a/layout/forms/nsNumberControlFrame.h +++ b/layout/forms/nsNumberControlFrame.h @@ -43,7 +43,7 @@ public: NS_DECL_FRAMEARENA_HELPERS virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; - + virtual void ContentStatesChanged(nsEventStates aStates); virtual bool IsLeaf() const MOZ_OVERRIDE { return false; } NS_IMETHOD Reflow(nsPresContext* aPresContext, @@ -142,6 +142,34 @@ private: const nsHTMLReflowState& aReflowState, nsIFrame* aOuterWrapperFrame); + class SyncDisabledStateEvent; + friend class SyncDisabledStateEvent; + class SyncDisabledStateEvent : public nsRunnable + { + public: + SyncDisabledStateEvent(nsNumberControlFrame* aFrame) + : mFrame(aFrame) + {} + + NS_IMETHOD Run() MOZ_OVERRIDE + { + nsNumberControlFrame* frame = + static_cast(mFrame.GetFrame()); + NS_ENSURE_STATE(frame); + + frame->SyncDisabledState(); + return NS_OK; + } + + private: + nsWeakFrame mFrame; + }; + + /** + * Sync the disabled state of the anonymous children up with our content's. + */ + void SyncDisabledState(); + /** * The text field used to edit and show the number. * @see nsNumberControlFrame::CreateAnonymousContent. diff --git a/layout/reftests/bugs/557087-1.html b/layout/reftests/bugs/557087-1.html index a470c5ba858d..f860dafef7bc 100644 --- a/layout/reftests/bugs/557087-1.html +++ b/layout/reftests/bugs/557087-1.html @@ -5,6 +5,7 @@ + diff --git a/layout/reftests/bugs/557087-2.html b/layout/reftests/bugs/557087-2.html index 6dda210168fd..dfb0eccf9f58 100644 --- a/layout/reftests/bugs/557087-2.html +++ b/layout/reftests/bugs/557087-2.html @@ -6,6 +6,7 @@ + diff --git a/layout/reftests/bugs/557087-ref.html b/layout/reftests/bugs/557087-ref.html index de224af61180..5a60c625d71d 100644 --- a/layout/reftests/bugs/557087-ref.html +++ b/layout/reftests/bugs/557087-ref.html @@ -5,6 +5,7 @@ + diff --git a/layout/reftests/forms/input/number/number-disabled-ref.html b/layout/reftests/forms/input/number/number-disabled-ref.html new file mode 100644 index 000000000000..60c501a86d7f --- /dev/null +++ b/layout/reftests/forms/input/number/number-disabled-ref.html @@ -0,0 +1,8 @@ + + + + + +
+ + diff --git a/layout/reftests/forms/input/number/number-disabled.html b/layout/reftests/forms/input/number/number-disabled.html new file mode 100644 index 000000000000..bd019fc33796 --- /dev/null +++ b/layout/reftests/forms/input/number/number-disabled.html @@ -0,0 +1,8 @@ + + + + + +
+ + diff --git a/layout/reftests/forms/input/number/reftest.list b/layout/reftests/forms/input/number/reftest.list index 2820e5b0bccd..8e75455912d2 100644 --- a/layout/reftests/forms/input/number/reftest.list +++ b/layout/reftests/forms/input/number/reftest.list @@ -17,6 +17,9 @@ fuzzy-if(/^Windows\x20NT\x205\.1/.test(http.oscpu),64,4) fuzzy-if(cocoaWidget,63 # dynamic value changes: == show-value.html show-value-ref.html +# disabled +== number-disabled.html number-disabled-ref.html + # focus needs-focus == focus-handling.html focus-handling-ref.html diff --git a/widget/xpwidgets/nsNativeTheme.cpp b/widget/xpwidgets/nsNativeTheme.cpp index b2848ed01f98..22402b99245c 100644 --- a/widget/xpwidgets/nsNativeTheme.cpp +++ b/widget/xpwidgets/nsNativeTheme.cpp @@ -85,6 +85,14 @@ nsNativeTheme::GetContentState(nsIFrame* aFrame, uint8_t aWidgetType) flags |= NS_EVENT_STATE_FOCUS; } } + + nsNumberControlFrame* numberControlFrame = + nsNumberControlFrame::GetNumberControlFrameForSpinButton(aFrame); + if (numberControlFrame && + numberControlFrame->GetContent()->AsElement()->State(). + HasState(NS_EVENT_STATE_DISABLED)) { + flags |= NS_EVENT_STATE_DISABLED; + } } if (isXULCheckboxRadio && aWidgetType == NS_THEME_RADIO) {