/src/mozilla-central/layout/forms/nsNumberControlFrame.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | #ifndef nsNumberControlFrame_h__ |
8 | | #define nsNumberControlFrame_h__ |
9 | | |
10 | | #include "mozilla/Attributes.h" |
11 | | #include "nsContainerFrame.h" |
12 | | #include "nsIFormControlFrame.h" |
13 | | #include "nsIAnonymousContentCreator.h" |
14 | | #include "nsCOMPtr.h" |
15 | | |
16 | | class nsITextControlFrame; |
17 | | class nsPresContext; |
18 | | |
19 | | namespace mozilla { |
20 | | enum class CSSPseudoElementType : uint8_t; |
21 | | class WidgetEvent; |
22 | | class WidgetGUIEvent; |
23 | | namespace dom { |
24 | | class HTMLInputElement; |
25 | | } // namespace dom |
26 | | } // namespace mozilla |
27 | | |
28 | | /** |
29 | | * This frame type is used for <input type=number>. |
30 | | */ |
31 | | class nsNumberControlFrame final : public nsContainerFrame |
32 | | , public nsIAnonymousContentCreator |
33 | | , public nsIFormControlFrame |
34 | | { |
35 | | friend nsIFrame* |
36 | | NS_NewNumberControlFrame(nsIPresShell* aPresShell, ComputedStyle* aStyle); |
37 | | |
38 | | typedef mozilla::CSSPseudoElementType CSSPseudoElementType; |
39 | | typedef mozilla::dom::Element Element; |
40 | | typedef mozilla::dom::HTMLInputElement HTMLInputElement; |
41 | | typedef mozilla::WidgetEvent WidgetEvent; |
42 | | typedef mozilla::WidgetGUIEvent WidgetGUIEvent; |
43 | | |
44 | | explicit nsNumberControlFrame(ComputedStyle* aStyle); |
45 | | |
46 | | public: |
47 | | NS_DECL_QUERYFRAME |
48 | | NS_DECL_FRAMEARENA_HELPERS(nsNumberControlFrame) |
49 | | |
50 | | virtual void DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData& aPostDestroyData) override; |
51 | | virtual void ContentStatesChanged(mozilla::EventStates aStates) override; |
52 | | |
53 | | #ifdef ACCESSIBILITY |
54 | | virtual mozilla::a11y::AccType AccessibleType() override; |
55 | | #endif |
56 | | |
57 | | virtual nscoord GetMinISize(gfxContext* aRenderingContext) override; |
58 | | |
59 | | virtual nscoord GetPrefISize(gfxContext* aRenderingContext) override; |
60 | | |
61 | | virtual void Reflow(nsPresContext* aPresContext, |
62 | | ReflowOutput& aDesiredSize, |
63 | | const ReflowInput& aReflowInput, |
64 | | nsReflowStatus& aStatus) override; |
65 | | |
66 | | virtual nsresult AttributeChanged(int32_t aNameSpaceID, |
67 | | nsAtom* aAttribute, |
68 | | int32_t aModType) override; |
69 | | |
70 | | // nsIAnonymousContentCreator |
71 | | virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) override; |
72 | | virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements, |
73 | | uint32_t aFilter) override; |
74 | | |
75 | | #ifdef DEBUG_FRAME_DUMP |
76 | | virtual nsresult GetFrameName(nsAString& aResult) const override { |
77 | | return MakeFrameName(NS_LITERAL_STRING("NumberControl"), aResult); |
78 | | } |
79 | | #endif |
80 | | |
81 | | virtual bool IsFrameOfType(uint32_t aFlags) const override |
82 | 0 | { |
83 | 0 | return nsContainerFrame::IsFrameOfType(aFlags & |
84 | 0 | ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock)); |
85 | 0 | } |
86 | | |
87 | | // nsIFormControlFrame |
88 | | virtual void SetFocus(bool aOn, bool aRepaint) override; |
89 | | virtual nsresult SetFormProperty(nsAtom* aName, const nsAString& aValue) override; |
90 | | |
91 | | /** |
92 | | * This method attempts to localizes aValue and then sets the result as the |
93 | | * value of our anonymous text control. It's called when our |
94 | | * HTMLInputElement's value changes, when we need to sync up the value |
95 | | * displayed in our anonymous text control. |
96 | | */ |
97 | | void SetValueOfAnonTextControl(const nsAString& aValue); |
98 | | |
99 | | /** |
100 | | * This method gets the string value of our anonymous text control, |
101 | | * attempts to normalizes (de-localizes) it, then sets the outparam aValue to |
102 | | * the result. It's called when user input changes the text value of our |
103 | | * anonymous text control so that we can sync up the internal value of our |
104 | | * HTMLInputElement. |
105 | | */ |
106 | | void GetValueOfAnonTextControl(nsAString& aValue); |
107 | | |
108 | | bool AnonTextControlIsEmpty(); |
109 | | |
110 | | /** |
111 | | * Called to notify this frame that its HTMLInputElement is currently |
112 | | * processing a DOM 'input' event. |
113 | | */ |
114 | | void HandlingInputEvent(bool aHandlingEvent) |
115 | 0 | { |
116 | 0 | mHandlingInputEvent = aHandlingEvent; |
117 | 0 | } |
118 | | |
119 | | HTMLInputElement* GetAnonTextControl(); |
120 | | |
121 | | /** |
122 | | * If the frame is the frame for an nsNumberControlFrame's anonymous text |
123 | | * field, returns the nsNumberControlFrame. Else returns nullptr. |
124 | | */ |
125 | | static nsNumberControlFrame* GetNumberControlFrameForTextField(nsIFrame* aFrame); |
126 | | |
127 | | /** |
128 | | * If the frame is the frame for an nsNumberControlFrame's up or down spin |
129 | | * button, returns the nsNumberControlFrame. Else returns nullptr. |
130 | | */ |
131 | | static nsNumberControlFrame* GetNumberControlFrameForSpinButton(nsIFrame* aFrame); |
132 | | |
133 | | enum SpinButtonEnum { |
134 | | eSpinButtonNone, |
135 | | eSpinButtonUp, |
136 | | eSpinButtonDown |
137 | | }; |
138 | | |
139 | | /** |
140 | | * Returns one of the SpinButtonEnum values to depending on whether the |
141 | | * pointer event is over the spin-up button, the spin-down button, or |
142 | | * neither. |
143 | | */ |
144 | | int32_t GetSpinButtonForPointerEvent(WidgetGUIEvent* aEvent) const; |
145 | | |
146 | | void SpinnerStateChanged() const; |
147 | | |
148 | | bool SpinnerUpButtonIsDepressed() const; |
149 | | bool SpinnerDownButtonIsDepressed() const; |
150 | | |
151 | | bool IsFocused() const; |
152 | | |
153 | | void HandleFocusEvent(WidgetEvent* aEvent); |
154 | | |
155 | | /** |
156 | | * Our element had HTMLInputElement::Select() called on it. |
157 | | */ |
158 | | void HandleSelectCall(); |
159 | | |
160 | | bool ShouldUseNativeStyleForSpinner() const; |
161 | | |
162 | | private: |
163 | | |
164 | | nsITextControlFrame* GetTextFieldFrame(); |
165 | | already_AddRefed<Element> MakeAnonymousElement(Element* aParent, |
166 | | nsAtom* aTagName, |
167 | | CSSPseudoElementType aPseudoType); |
168 | | |
169 | | class SyncDisabledStateEvent; |
170 | | friend class SyncDisabledStateEvent; |
171 | | class SyncDisabledStateEvent : public mozilla::Runnable |
172 | | { |
173 | | public: |
174 | | explicit SyncDisabledStateEvent(nsNumberControlFrame* aFrame) |
175 | | : mozilla::Runnable("nsNumberControlFrame::SyncDisabledStateEvent") |
176 | | , mFrame(aFrame) |
177 | 0 | {} |
178 | | |
179 | | NS_IMETHOD Run() override |
180 | 0 | { |
181 | 0 | nsNumberControlFrame* frame = |
182 | 0 | static_cast<nsNumberControlFrame*>(mFrame.GetFrame()); |
183 | 0 | NS_ENSURE_STATE(frame); |
184 | 0 |
|
185 | 0 | frame->SyncDisabledState(); |
186 | 0 | return NS_OK; |
187 | 0 | } |
188 | | |
189 | | private: |
190 | | WeakFrame mFrame; |
191 | | }; |
192 | | |
193 | | /** |
194 | | * Sync the disabled state of the anonymous children up with our content's. |
195 | | */ |
196 | | void SyncDisabledState(); |
197 | | |
198 | | /** |
199 | | * The text field used to edit and show the number. |
200 | | * @see nsNumberControlFrame::CreateAnonymousContent. |
201 | | */ |
202 | | nsCOMPtr<Element> mOuterWrapper; |
203 | | nsCOMPtr<Element> mTextField; |
204 | | nsCOMPtr<Element> mSpinBox; |
205 | | nsCOMPtr<Element> mSpinUp; |
206 | | nsCOMPtr<Element> mSpinDown; |
207 | | bool mHandlingInputEvent; |
208 | | }; |
209 | | |
210 | | #endif // nsNumberControlFrame_h__ |