|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #ifndef nsNumberControlFrame_h__ |
|
7 #define nsNumberControlFrame_h__ |
|
8 |
|
9 #include "mozilla/Attributes.h" |
|
10 #include "nsContainerFrame.h" |
|
11 #include "nsIFormControlFrame.h" |
|
12 #include "nsITextControlFrame.h" |
|
13 #include "nsIAnonymousContentCreator.h" |
|
14 #include "nsCOMPtr.h" |
|
15 |
|
16 class nsPresContext; |
|
17 |
|
18 namespace mozilla { |
|
19 class WidgetEvent; |
|
20 class WidgetGUIEvent; |
|
21 namespace dom { |
|
22 class HTMLInputElement; |
|
23 } |
|
24 } |
|
25 |
|
26 /** |
|
27 * This frame type is used for <input type=number>. |
|
28 */ |
|
29 class nsNumberControlFrame MOZ_FINAL : public nsContainerFrame |
|
30 , public nsIAnonymousContentCreator |
|
31 , public nsITextControlFrame |
|
32 { |
|
33 friend nsIFrame* |
|
34 NS_NewNumberControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); |
|
35 |
|
36 typedef mozilla::dom::Element Element; |
|
37 typedef mozilla::dom::HTMLInputElement HTMLInputElement; |
|
38 typedef mozilla::WidgetEvent WidgetEvent; |
|
39 typedef mozilla::WidgetGUIEvent WidgetGUIEvent; |
|
40 |
|
41 nsNumberControlFrame(nsStyleContext* aContext); |
|
42 |
|
43 public: |
|
44 NS_DECL_QUERYFRAME_TARGET(nsNumberControlFrame) |
|
45 NS_DECL_QUERYFRAME |
|
46 NS_DECL_FRAMEARENA_HELPERS |
|
47 |
|
48 virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; |
|
49 virtual void ContentStatesChanged(mozilla::EventStates aStates) MOZ_OVERRIDE; |
|
50 virtual bool IsLeaf() const MOZ_OVERRIDE { return true; } |
|
51 |
|
52 #ifdef ACCESSIBILITY |
|
53 virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE; |
|
54 #endif |
|
55 |
|
56 virtual nscoord GetMinWidth(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE; |
|
57 |
|
58 virtual nscoord GetPrefWidth(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE; |
|
59 |
|
60 virtual nsresult Reflow(nsPresContext* aPresContext, |
|
61 nsHTMLReflowMetrics& aDesiredSize, |
|
62 const nsHTMLReflowState& aReflowState, |
|
63 nsReflowStatus& aStatus) MOZ_OVERRIDE; |
|
64 |
|
65 virtual nsresult AttributeChanged(int32_t aNameSpaceID, |
|
66 nsIAtom* aAttribute, |
|
67 int32_t aModType) MOZ_OVERRIDE; |
|
68 |
|
69 // nsIAnonymousContentCreator |
|
70 virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) MOZ_OVERRIDE; |
|
71 virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, |
|
72 uint32_t aFilter) MOZ_OVERRIDE; |
|
73 |
|
74 #ifdef DEBUG_FRAME_DUMP |
|
75 virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE { |
|
76 return MakeFrameName(NS_LITERAL_STRING("NumberControl"), aResult); |
|
77 } |
|
78 #endif |
|
79 |
|
80 virtual nsIAtom* GetType() const MOZ_OVERRIDE; |
|
81 |
|
82 virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE |
|
83 { |
|
84 return nsContainerFrame::IsFrameOfType(aFlags & |
|
85 ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock)); |
|
86 } |
|
87 |
|
88 // nsITextControlFrame |
|
89 NS_IMETHOD GetEditor(nsIEditor **aEditor) MOZ_OVERRIDE; |
|
90 |
|
91 NS_IMETHOD SetSelectionStart(int32_t aSelectionStart) MOZ_OVERRIDE; |
|
92 NS_IMETHOD SetSelectionEnd(int32_t aSelectionEnd) MOZ_OVERRIDE; |
|
93 |
|
94 NS_IMETHOD SetSelectionRange(int32_t aSelectionStart, |
|
95 int32_t aSelectionEnd, |
|
96 SelectionDirection aDirection = eNone) MOZ_OVERRIDE; |
|
97 |
|
98 NS_IMETHOD GetSelectionRange(int32_t* aSelectionStart, |
|
99 int32_t* aSelectionEnd, |
|
100 SelectionDirection* aDirection = nullptr) MOZ_OVERRIDE; |
|
101 |
|
102 NS_IMETHOD GetOwnedSelectionController(nsISelectionController** aSelCon) MOZ_OVERRIDE; |
|
103 virtual nsFrameSelection* GetOwnedFrameSelection() MOZ_OVERRIDE; |
|
104 |
|
105 virtual nsresult GetPhonetic(nsAString& aPhonetic) MOZ_OVERRIDE; |
|
106 |
|
107 /** |
|
108 * Ensure mEditor is initialized with the proper flags and the default value. |
|
109 * @throws NS_ERROR_NOT_INITIALIZED if mEditor has not been created |
|
110 * @throws various and sundry other things |
|
111 */ |
|
112 virtual nsresult EnsureEditorInitialized() MOZ_OVERRIDE; |
|
113 |
|
114 virtual nsresult ScrollSelectionIntoView() MOZ_OVERRIDE; |
|
115 |
|
116 // nsIFormControlFrame |
|
117 virtual void SetFocus(bool aOn, bool aRepaint) MOZ_OVERRIDE; |
|
118 virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue) MOZ_OVERRIDE; |
|
119 |
|
120 /** |
|
121 * This method attempts to localizes aValue and then sets the result as the |
|
122 * value of our anonymous text control. It's called when our |
|
123 * HTMLInputElement's value changes, when we need to sync up the value |
|
124 * displayed in our anonymous text control. |
|
125 */ |
|
126 void SetValueOfAnonTextControl(const nsAString& aValue); |
|
127 |
|
128 /** |
|
129 * This method gets the string value of our anonymous text control, |
|
130 * attempts to normalizes (de-localizes) it, then sets the outparam aValue to |
|
131 * the result. It's called when user input changes the text value of our |
|
132 * anonymous text control so that we can sync up the internal value of our |
|
133 * HTMLInputElement. |
|
134 */ |
|
135 void GetValueOfAnonTextControl(nsAString& aValue); |
|
136 |
|
137 bool AnonTextControlIsEmpty(); |
|
138 |
|
139 /** |
|
140 * Called to notify this frame that its HTMLInputElement is currently |
|
141 * processing a DOM 'input' event. |
|
142 */ |
|
143 void HandlingInputEvent(bool aHandlingEvent) |
|
144 { |
|
145 mHandlingInputEvent = aHandlingEvent; |
|
146 } |
|
147 |
|
148 HTMLInputElement* GetAnonTextControl(); |
|
149 |
|
150 /** |
|
151 * If the frame is the frame for an nsNumberControlFrame's anonymous text |
|
152 * field, returns the nsNumberControlFrame. Else returns nullptr. |
|
153 */ |
|
154 static nsNumberControlFrame* GetNumberControlFrameForTextField(nsIFrame* aFrame); |
|
155 |
|
156 /** |
|
157 * If the frame is the frame for an nsNumberControlFrame's up or down spin |
|
158 * button, returns the nsNumberControlFrame. Else returns nullptr. |
|
159 */ |
|
160 static nsNumberControlFrame* GetNumberControlFrameForSpinButton(nsIFrame* aFrame); |
|
161 |
|
162 enum SpinButtonEnum { |
|
163 eSpinButtonNone, |
|
164 eSpinButtonUp, |
|
165 eSpinButtonDown |
|
166 }; |
|
167 |
|
168 /** |
|
169 * Returns one of the SpinButtonEnum values to depending on whether the |
|
170 * pointer event is over the spin-up button, the spin-down button, or |
|
171 * neither. |
|
172 */ |
|
173 int32_t GetSpinButtonForPointerEvent(WidgetGUIEvent* aEvent) const; |
|
174 |
|
175 void SpinnerStateChanged() const; |
|
176 |
|
177 bool SpinnerUpButtonIsDepressed() const; |
|
178 bool SpinnerDownButtonIsDepressed() const; |
|
179 |
|
180 bool IsFocused() const; |
|
181 |
|
182 void HandleFocusEvent(WidgetEvent* aEvent); |
|
183 |
|
184 /** |
|
185 * Our element had HTMLInputElement::Select() called on it. |
|
186 */ |
|
187 nsresult HandleSelectCall(); |
|
188 |
|
189 virtual Element* GetPseudoElement(nsCSSPseudoElements::Type aType) MOZ_OVERRIDE; |
|
190 |
|
191 bool ShouldUseNativeStyleForSpinner() const; |
|
192 |
|
193 private: |
|
194 |
|
195 nsITextControlFrame* GetTextFieldFrame(); |
|
196 nsresult MakeAnonymousElement(Element** aResult, |
|
197 nsTArray<ContentInfo>& aElements, |
|
198 nsIAtom* aTagName, |
|
199 nsCSSPseudoElements::Type aPseudoType, |
|
200 nsStyleContext* aParentContext); |
|
201 |
|
202 class SyncDisabledStateEvent; |
|
203 friend class SyncDisabledStateEvent; |
|
204 class SyncDisabledStateEvent : public nsRunnable |
|
205 { |
|
206 public: |
|
207 SyncDisabledStateEvent(nsNumberControlFrame* aFrame) |
|
208 : mFrame(aFrame) |
|
209 {} |
|
210 |
|
211 NS_IMETHOD Run() MOZ_OVERRIDE |
|
212 { |
|
213 nsNumberControlFrame* frame = |
|
214 static_cast<nsNumberControlFrame*>(mFrame.GetFrame()); |
|
215 NS_ENSURE_STATE(frame); |
|
216 |
|
217 frame->SyncDisabledState(); |
|
218 return NS_OK; |
|
219 } |
|
220 |
|
221 private: |
|
222 nsWeakFrame mFrame; |
|
223 }; |
|
224 |
|
225 /** |
|
226 * Sync the disabled state of the anonymous children up with our content's. |
|
227 */ |
|
228 void SyncDisabledState(); |
|
229 |
|
230 /** |
|
231 * The text field used to edit and show the number. |
|
232 * @see nsNumberControlFrame::CreateAnonymousContent. |
|
233 */ |
|
234 nsCOMPtr<Element> mOuterWrapper; |
|
235 nsCOMPtr<Element> mTextField; |
|
236 nsCOMPtr<Element> mSpinBox; |
|
237 nsCOMPtr<Element> mSpinUp; |
|
238 nsCOMPtr<Element> mSpinDown; |
|
239 bool mHandlingInputEvent; |
|
240 }; |
|
241 |
|
242 #endif // nsNumberControlFrame_h__ |