Bug 767636 - Expose plugin fallback type to extensions. r=josh
[gecko.git] / layout / forms / nsTextControlFrame.h
blobcf70d34046d15d219b99277c98632057ca803061
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/. */
6 #ifndef nsTextControlFrame_h___
7 #define nsTextControlFrame_h___
9 #include "nsContainerFrame.h"
10 #include "nsBlockFrame.h"
11 #include "nsIFormControlFrame.h"
12 #include "nsIAnonymousContentCreator.h"
13 #include "nsITextControlFrame.h"
14 #include "nsDisplayList.h"
15 #include "nsIScrollableFrame.h"
16 #include "nsStubMutationObserver.h"
17 #include "nsITextControlElement.h"
18 #include "nsIStatefulFrame.h"
19 #include "nsContentUtils.h" // nsAutoScriptBlocker
20 #include "nsIEditor.h"
22 class nsISelectionController;
23 class nsIDOMCharacterData;
24 #ifdef ACCESSIBILITY
25 class nsIAccessible;
26 #endif
27 class EditorInitializerEntryTracker;
28 class nsTextEditorState;
29 namespace mozilla {
30 namespace dom {
31 class Element;
35 class nsTextControlFrame : public nsContainerFrame,
36 public nsIAnonymousContentCreator,
37 public nsITextControlFrame,
38 public nsIStatefulFrame
40 public:
41 NS_DECL_FRAMEARENA_HELPERS
43 NS_DECLARE_FRAME_PROPERTY(ContentScrollPos, DestroyPoint)
45 nsTextControlFrame(nsIPresShell* aShell, nsStyleContext* aContext);
46 virtual ~nsTextControlFrame();
48 virtual void DestroyFrom(nsIFrame* aDestructRoot);
50 virtual nsIScrollableFrame* GetScrollTargetFrame() {
51 if (!IsScrollable())
52 return nullptr;
53 return do_QueryFrame(GetFirstPrincipalChild());
56 virtual nscoord GetMinWidth(nsRenderingContext* aRenderingContext);
57 virtual nscoord GetPrefWidth(nsRenderingContext* aRenderingContext);
59 virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext,
60 nsSize aCBSize, nscoord aAvailableWidth,
61 nsSize aMargin, nsSize aBorder,
62 nsSize aPadding, bool aShrinkWrap);
64 NS_IMETHOD Reflow(nsPresContext* aPresContext,
65 nsHTMLReflowMetrics& aDesiredSize,
66 const nsHTMLReflowState& aReflowState,
67 nsReflowStatus& aStatus);
69 virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState);
70 virtual bool IsCollapsed();
72 DECL_DO_GLOBAL_REFLOW_COUNT_DSP(nsTextControlFrame, nsContainerFrame)
74 virtual bool IsLeaf() const;
76 #ifdef ACCESSIBILITY
77 virtual already_AddRefed<Accessible> CreateAccessible();
78 #endif
80 #ifdef DEBUG
81 NS_IMETHOD GetFrameName(nsAString& aResult) const
83 aResult.AssignLiteral("nsTextControlFrame");
84 return NS_OK;
86 #endif
88 virtual bool IsFrameOfType(PRUint32 aFlags) const
90 // nsStackFrame is already both of these, but that's somewhat bogus,
91 // and we really mean it.
92 return nsContainerFrame::IsFrameOfType(aFlags &
93 ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
96 // nsIAnonymousContentCreator
97 virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements);
98 virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
99 PRUint32 aFilter);
101 // Utility methods to set current widget state
103 NS_IMETHOD SetInitialChildList(ChildListID aListID,
104 nsFrameList& aChildList);
106 //==== BEGIN NSIFORMCONTROLFRAME
107 virtual void SetFocus(bool aOn , bool aRepaint);
108 virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue);
109 virtual nsresult GetFormProperty(nsIAtom* aName, nsAString& aValue) const;
112 //==== END NSIFORMCONTROLFRAME
114 //==== NSITEXTCONTROLFRAME
116 NS_IMETHOD GetEditor(nsIEditor **aEditor);
117 NS_IMETHOD GetTextLength(PRInt32* aTextLength);
118 NS_IMETHOD SetSelectionStart(PRInt32 aSelectionStart);
119 NS_IMETHOD SetSelectionEnd(PRInt32 aSelectionEnd);
120 NS_IMETHOD SetSelectionRange(PRInt32 aSelectionStart,
121 PRInt32 aSelectionEnd,
122 SelectionDirection aDirection = eNone);
123 NS_IMETHOD GetSelectionRange(PRInt32* aSelectionStart,
124 PRInt32* aSelectionEnd,
125 SelectionDirection* aDirection = nullptr);
126 NS_IMETHOD GetOwnedSelectionController(nsISelectionController** aSelCon);
127 virtual nsFrameSelection* GetOwnedFrameSelection();
129 nsresult GetPhonetic(nsAString& aPhonetic);
132 * Ensure mEditor is initialized with the proper flags and the default value.
133 * @throws NS_ERROR_NOT_INITIALIZED if mEditor has not been created
134 * @throws various and sundry other things
136 virtual nsresult EnsureEditorInitialized();
138 //==== END NSITEXTCONTROLFRAME
140 //==== NSISTATEFULFRAME
142 NS_IMETHOD SaveState(SpecialStateID aStateID, nsPresState** aState);
143 NS_IMETHOD RestoreState(nsPresState* aState);
145 //=== END NSISTATEFULFRAME
147 //==== OVERLOAD of nsIFrame
148 virtual nsIAtom* GetType() const;
150 /** handler for attribute changes to mContent */
151 NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,
152 nsIAtom* aAttribute,
153 PRInt32 aModType);
155 nsresult GetText(nsString& aText);
157 NS_IMETHOD PeekOffset(nsPeekOffsetStruct *aPos);
159 NS_DECL_QUERYFRAME
161 // Temp reference to scriptrunner
162 // We could make these auto-Revoking via the "delete" entry for safety
163 NS_DECLARE_FRAME_PROPERTY(TextControlInitializer, nullptr)
165 protected:
167 * Launch the reflow on the child frames - see nsTextControlFrame::Reflow()
169 void ReflowTextControlChild(nsIFrame* aFrame,
170 nsPresContext* aPresContext,
171 const nsHTMLReflowState& aReflowState,
172 nsReflowStatus& aStatus,
173 nsHTMLReflowMetrics& aParentDesiredSize);
175 public: //for methods who access nsTextControlFrame directly
176 void SetValueChanged(bool aValueChanged);
178 // called by the focus listener
179 nsresult MaybeBeginSecureKeyboardInput();
180 void MaybeEndSecureKeyboardInput();
182 NS_STACK_CLASS class ValueSetter {
183 public:
184 ValueSetter(nsIEditor* aEditor)
185 : mEditor(aEditor)
186 , mCanceled(false)
188 MOZ_ASSERT(aEditor);
190 // To protect against a reentrant call to SetValue, we check whether
191 // another SetValue is already happening for this frame. If it is,
192 // we must wait until we unwind to re-enable oninput events.
193 mEditor->GetSuppressDispatchingInputEvent(&mOuterTransaction);
195 void Cancel() {
196 mCanceled = true;
198 void Init() {
199 mEditor->SetSuppressDispatchingInputEvent(true);
201 ~ValueSetter() {
202 mEditor->SetSuppressDispatchingInputEvent(mOuterTransaction);
204 if (mCanceled) {
205 return;
209 private:
210 nsCOMPtr<nsIEditor> mEditor;
211 bool mOuterTransaction;
212 bool mCanceled;
214 friend class ValueSetter;
216 #define DEFINE_TEXTCTRL_FORWARDER(type, name) \
217 type name() { \
218 nsCOMPtr<nsITextControlElement> txtCtrl = do_QueryInterface(GetContent()); \
219 NS_ASSERTION(txtCtrl, "Content not a text control element"); \
220 return txtCtrl->name(); \
222 #define DEFINE_TEXTCTRL_CONST_FORWARDER(type, name) \
223 type name() const { \
224 nsCOMPtr<nsITextControlElement> txtCtrl = do_QueryInterface(GetContent()); \
225 NS_ASSERTION(txtCtrl, "Content not a text control element"); \
226 return txtCtrl->name(); \
229 DEFINE_TEXTCTRL_CONST_FORWARDER(bool, IsSingleLineTextControl)
230 DEFINE_TEXTCTRL_CONST_FORWARDER(bool, IsTextArea)
231 DEFINE_TEXTCTRL_CONST_FORWARDER(bool, IsPlainTextControl)
232 DEFINE_TEXTCTRL_CONST_FORWARDER(bool, IsPasswordTextControl)
233 DEFINE_TEXTCTRL_FORWARDER(PRInt32, GetCols)
234 DEFINE_TEXTCTRL_FORWARDER(PRInt32, GetWrapCols)
235 DEFINE_TEXTCTRL_FORWARDER(PRInt32, GetRows)
237 #undef DEFINE_TEXTCTRL_CONST_FORWARDER
238 #undef DEFINE_TEXTCTRL_FORWARDER
240 protected:
241 class EditorInitializer;
242 friend class EditorInitializer;
243 friend class nsTextEditorState; // needs access to UpdateValueDisplay
245 class EditorInitializer : public nsRunnable {
246 public:
247 EditorInitializer(nsTextControlFrame* aFrame) :
248 mFrame(aFrame) {}
250 NS_IMETHOD Run() {
251 if (mFrame) {
252 // need to block script to avoid bug 669767
253 nsAutoScriptBlocker scriptBlocker;
255 nsCOMPtr<nsIPresShell> shell =
256 mFrame->PresContext()->GetPresShell();
257 bool observes = shell->ObservesNativeAnonMutationsForPrint();
258 shell->ObserveNativeAnonMutationsForPrint(true);
259 // This can cause the frame to be destroyed (and call Revoke())
260 mFrame->EnsureEditorInitialized();
261 shell->ObserveNativeAnonMutationsForPrint(observes);
263 // The frame can *still* be destroyed even though we have a scriptblocker
264 // Bug 682684
265 if (!mFrame)
266 return NS_ERROR_FAILURE;
268 mFrame->FinishedInitializer();
270 return NS_OK;
273 // avoids use of nsWeakFrame
274 void Revoke() {
275 mFrame = nullptr;
278 private:
279 nsTextControlFrame* mFrame;
282 class ScrollOnFocusEvent;
283 friend class ScrollOnFocusEvent;
285 class ScrollOnFocusEvent : public nsRunnable {
286 public:
287 ScrollOnFocusEvent(nsTextControlFrame* aFrame) :
288 mFrame(aFrame) {}
290 NS_DECL_NSIRUNNABLE
292 void Revoke() {
293 mFrame = nullptr;
296 private:
297 nsTextControlFrame* mFrame;
300 nsresult OffsetToDOMPoint(PRInt32 aOffset, nsIDOMNode** aResult, PRInt32* aPosition);
303 * Find out whether this control is scrollable (i.e. if it is not a single
304 * line text control)
305 * @return whether this control is scrollable
307 bool IsScrollable() const;
310 * Update the textnode under our anonymous div to show the new
311 * value. This should only be called when we have no editor yet.
312 * @throws NS_ERROR_UNEXPECTED if the div has no text content
314 nsresult UpdateValueDisplay(bool aNotify,
315 bool aBeforeEditorInit = false,
316 const nsAString *aValue = nullptr);
319 * Get the maxlength attribute
320 * @param aMaxLength the value of the max length attr
321 * @returns false if attr not defined
323 bool GetMaxLength(PRInt32* aMaxLength);
326 * Find out whether an attribute exists on the content or not.
327 * @param aAtt the attribute to determine the existence of
328 * @returns false if it does not exist
330 bool AttributeExists(nsIAtom *aAtt) const
331 { return mContent && mContent->HasAttr(kNameSpaceID_None, aAtt); }
334 * We call this when we are being destroyed or removed from the PFM.
335 * @param aPresContext the current pres context
337 void PreDestroy();
339 // Compute our intrinsic size. This does not include any borders, paddings,
340 // etc. Just the size of our actual area for the text (and the scrollbars,
341 // for <textarea>).
342 nsresult CalcIntrinsicSize(nsRenderingContext* aRenderingContext,
343 nsSize& aIntrinsicSize,
344 float aFontSizeInflation);
346 nsresult ScrollSelectionIntoView();
348 private:
349 //helper methods
350 nsresult SetSelectionInternal(nsIDOMNode *aStartNode, PRInt32 aStartOffset,
351 nsIDOMNode *aEndNode, PRInt32 aEndOffset,
352 SelectionDirection aDirection = eNone);
353 nsresult SelectAllOrCollapseToEndOfText(bool aSelect);
354 nsresult SetSelectionEndPoints(PRInt32 aSelStart, PRInt32 aSelEnd,
355 SelectionDirection aDirection = eNone);
358 * Return the root DOM element, and implicitly initialize the editor if needed.
360 mozilla::dom::Element* GetRootNodeAndInitializeEditor();
361 nsresult GetRootNodeAndInitializeEditor(nsIDOMElement **aRootElement);
363 void FinishedInitializer() {
364 Properties().Delete(TextControlInitializer());
367 private:
368 // these packed bools could instead use the high order bits on mState, saving 4 bytes
369 bool mUseEditor;
370 bool mIsProcessing;
371 // Keep track if we have asked a placeholder node creation.
372 bool mUsePlaceholder;
374 #ifdef DEBUG
375 bool mInEditorInitialization;
376 friend class EditorInitializerEntryTracker;
377 #endif
379 nsRevocableEventPtr<ScrollOnFocusEvent> mScrollEvent;
382 #endif