diff -r 000000000000 -r 6474c204b198 layout/forms/nsNumberControlFrame.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/layout/forms/nsNumberControlFrame.h Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,242 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nsNumberControlFrame_h__ +#define nsNumberControlFrame_h__ + +#include "mozilla/Attributes.h" +#include "nsContainerFrame.h" +#include "nsIFormControlFrame.h" +#include "nsITextControlFrame.h" +#include "nsIAnonymousContentCreator.h" +#include "nsCOMPtr.h" + +class nsPresContext; + +namespace mozilla { +class WidgetEvent; +class WidgetGUIEvent; +namespace dom { +class HTMLInputElement; +} +} + +/** + * This frame type is used for . + */ +class nsNumberControlFrame MOZ_FINAL : public nsContainerFrame + , public nsIAnonymousContentCreator + , public nsITextControlFrame +{ + friend nsIFrame* + NS_NewNumberControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); + + typedef mozilla::dom::Element Element; + typedef mozilla::dom::HTMLInputElement HTMLInputElement; + typedef mozilla::WidgetEvent WidgetEvent; + typedef mozilla::WidgetGUIEvent WidgetGUIEvent; + + nsNumberControlFrame(nsStyleContext* aContext); + +public: + NS_DECL_QUERYFRAME_TARGET(nsNumberControlFrame) + NS_DECL_QUERYFRAME + NS_DECL_FRAMEARENA_HELPERS + + virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; + virtual void ContentStatesChanged(mozilla::EventStates aStates) MOZ_OVERRIDE; + virtual bool IsLeaf() const MOZ_OVERRIDE { return true; } + +#ifdef ACCESSIBILITY + virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE; +#endif + + virtual nscoord GetMinWidth(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE; + + virtual nscoord GetPrefWidth(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE; + + virtual nsresult Reflow(nsPresContext* aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) MOZ_OVERRIDE; + + virtual nsresult AttributeChanged(int32_t aNameSpaceID, + nsIAtom* aAttribute, + int32_t aModType) MOZ_OVERRIDE; + + // nsIAnonymousContentCreator + virtual nsresult CreateAnonymousContent(nsTArray& aElements) MOZ_OVERRIDE; + virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, + uint32_t aFilter) MOZ_OVERRIDE; + +#ifdef DEBUG_FRAME_DUMP + virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE { + return MakeFrameName(NS_LITERAL_STRING("NumberControl"), aResult); + } +#endif + + virtual nsIAtom* GetType() const MOZ_OVERRIDE; + + virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE + { + return nsContainerFrame::IsFrameOfType(aFlags & + ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock)); + } + + // nsITextControlFrame + NS_IMETHOD GetEditor(nsIEditor **aEditor) MOZ_OVERRIDE; + + NS_IMETHOD SetSelectionStart(int32_t aSelectionStart) MOZ_OVERRIDE; + NS_IMETHOD SetSelectionEnd(int32_t aSelectionEnd) MOZ_OVERRIDE; + + NS_IMETHOD SetSelectionRange(int32_t aSelectionStart, + int32_t aSelectionEnd, + SelectionDirection aDirection = eNone) MOZ_OVERRIDE; + + NS_IMETHOD GetSelectionRange(int32_t* aSelectionStart, + int32_t* aSelectionEnd, + SelectionDirection* aDirection = nullptr) MOZ_OVERRIDE; + + NS_IMETHOD GetOwnedSelectionController(nsISelectionController** aSelCon) MOZ_OVERRIDE; + virtual nsFrameSelection* GetOwnedFrameSelection() MOZ_OVERRIDE; + + virtual nsresult GetPhonetic(nsAString& aPhonetic) MOZ_OVERRIDE; + + /** + * Ensure mEditor is initialized with the proper flags and the default value. + * @throws NS_ERROR_NOT_INITIALIZED if mEditor has not been created + * @throws various and sundry other things + */ + virtual nsresult EnsureEditorInitialized() MOZ_OVERRIDE; + + virtual nsresult ScrollSelectionIntoView() MOZ_OVERRIDE; + + // nsIFormControlFrame + virtual void SetFocus(bool aOn, bool aRepaint) MOZ_OVERRIDE; + virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue) MOZ_OVERRIDE; + + /** + * This method attempts to localizes aValue and then sets the result as the + * value of our anonymous text control. It's called when our + * HTMLInputElement's value changes, when we need to sync up the value + * displayed in our anonymous text control. + */ + void SetValueOfAnonTextControl(const nsAString& aValue); + + /** + * This method gets the string value of our anonymous text control, + * attempts to normalizes (de-localizes) it, then sets the outparam aValue to + * the result. It's called when user input changes the text value of our + * anonymous text control so that we can sync up the internal value of our + * HTMLInputElement. + */ + void GetValueOfAnonTextControl(nsAString& aValue); + + bool AnonTextControlIsEmpty(); + + /** + * Called to notify this frame that its HTMLInputElement is currently + * processing a DOM 'input' event. + */ + void HandlingInputEvent(bool aHandlingEvent) + { + mHandlingInputEvent = aHandlingEvent; + } + + HTMLInputElement* GetAnonTextControl(); + + /** + * If the frame is the frame for an nsNumberControlFrame's anonymous text + * field, returns the nsNumberControlFrame. Else returns nullptr. + */ + static nsNumberControlFrame* GetNumberControlFrameForTextField(nsIFrame* aFrame); + + /** + * If the frame is the frame for an nsNumberControlFrame's up or down spin + * button, returns the nsNumberControlFrame. Else returns nullptr. + */ + static nsNumberControlFrame* GetNumberControlFrameForSpinButton(nsIFrame* aFrame); + + enum SpinButtonEnum { + eSpinButtonNone, + eSpinButtonUp, + eSpinButtonDown + }; + + /** + * Returns one of the SpinButtonEnum values to depending on whether the + * pointer event is over the spin-up button, the spin-down button, or + * neither. + */ + int32_t GetSpinButtonForPointerEvent(WidgetGUIEvent* aEvent) const; + + void SpinnerStateChanged() const; + + bool SpinnerUpButtonIsDepressed() const; + bool SpinnerDownButtonIsDepressed() const; + + bool IsFocused() const; + + void HandleFocusEvent(WidgetEvent* aEvent); + + /** + * Our element had HTMLInputElement::Select() called on it. + */ + nsresult HandleSelectCall(); + + virtual Element* GetPseudoElement(nsCSSPseudoElements::Type aType) MOZ_OVERRIDE; + + bool ShouldUseNativeStyleForSpinner() const; + +private: + + nsITextControlFrame* GetTextFieldFrame(); + nsresult MakeAnonymousElement(Element** aResult, + nsTArray& aElements, + nsIAtom* aTagName, + nsCSSPseudoElements::Type aPseudoType, + nsStyleContext* aParentContext); + + 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. + */ + nsCOMPtr mOuterWrapper; + nsCOMPtr mTextField; + nsCOMPtr mSpinBox; + nsCOMPtr mSpinUp; + nsCOMPtr mSpinDown; + bool mHandlingInputEvent; +}; + +#endif // nsNumberControlFrame_h__