diff -r 000000000000 -r 6474c204b198 layout/forms/nsTextControlFrame.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/layout/forms/nsTextControlFrame.h Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,312 @@ +/* -*- 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 nsTextControlFrame_h___ +#define nsTextControlFrame_h___ + +#include "mozilla/Attributes.h" +#include "nsContainerFrame.h" +#include "nsIAnonymousContentCreator.h" +#include "nsITextControlFrame.h" +#include "nsITextControlElement.h" +#include "nsIStatefulFrame.h" + +class nsISelectionController; +class EditorInitializerEntryTracker; +class nsTextEditorState; +class nsIEditor; +namespace mozilla { +namespace dom { +class Element; +} +} + +class nsTextControlFrame : public nsContainerFrame, + public nsIAnonymousContentCreator, + public nsITextControlFrame, + public nsIStatefulFrame +{ +public: + NS_DECL_FRAMEARENA_HELPERS + + NS_DECLARE_FRAME_PROPERTY(ContentScrollPos, DestroyPoint) + + nsTextControlFrame(nsIPresShell* aShell, nsStyleContext* aContext); + virtual ~nsTextControlFrame(); + + virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; + + virtual nsIScrollableFrame* GetScrollTargetFrame() MOZ_OVERRIDE { + return do_QueryFrame(GetFirstPrincipalChild()); + } + + virtual nscoord GetMinWidth(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE; + virtual nscoord GetPrefWidth(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE; + + virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext, + nsSize aCBSize, nscoord aAvailableWidth, + nsSize aMargin, nsSize aBorder, + nsSize aPadding, bool aShrinkWrap) MOZ_OVERRIDE; + + virtual nsresult Reflow(nsPresContext* aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) MOZ_OVERRIDE; + + virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; + virtual bool IsCollapsed() MOZ_OVERRIDE; + + virtual bool IsLeaf() const MOZ_OVERRIDE; + +#ifdef ACCESSIBILITY + virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE; +#endif + +#ifdef DEBUG_FRAME_DUMP + virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE + { + aResult.AssignLiteral("nsTextControlFrame"); + return NS_OK; + } +#endif + + virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE + { + // nsStackFrame is already both of these, but that's somewhat bogus, + // and we really mean it. + return nsContainerFrame::IsFrameOfType(aFlags & + ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock)); + } + + // nsIAnonymousContentCreator + virtual nsresult CreateAnonymousContent(nsTArray& aElements) MOZ_OVERRIDE; + virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, + uint32_t aFilter) MOZ_OVERRIDE; + + // Utility methods to set current widget state + + virtual nsresult SetInitialChildList(ChildListID aListID, + nsFrameList& aChildList) MOZ_OVERRIDE; + + virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, + const nsDisplayListSet& aLists) MOZ_OVERRIDE; + + virtual mozilla::dom::Element* GetPseudoElement(nsCSSPseudoElements::Type aType) MOZ_OVERRIDE; + +//==== BEGIN NSIFORMCONTROLFRAME + virtual void SetFocus(bool aOn , bool aRepaint) MOZ_OVERRIDE; + virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue) MOZ_OVERRIDE; + +//==== END NSIFORMCONTROLFRAME + +//==== 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; + + 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; + +//==== END NSITEXTCONTROLFRAME + +//==== NSISTATEFULFRAME + + NS_IMETHOD SaveState(nsPresState** aState) MOZ_OVERRIDE; + NS_IMETHOD RestoreState(nsPresState* aState) MOZ_OVERRIDE; + +//=== END NSISTATEFULFRAME + +//==== OVERLOAD of nsIFrame + virtual nsIAtom* GetType() const MOZ_OVERRIDE; + + /** handler for attribute changes to mContent */ + virtual nsresult AttributeChanged(int32_t aNameSpaceID, + nsIAtom* aAttribute, + int32_t aModType) MOZ_OVERRIDE; + + nsresult GetText(nsString& aText); + + virtual nsresult PeekOffset(nsPeekOffsetStruct *aPos) MOZ_OVERRIDE; + + NS_DECL_QUERYFRAME + + // Temp reference to scriptrunner + // We could make these auto-Revoking via the "delete" entry for safety + NS_DECLARE_FRAME_PROPERTY(TextControlInitializer, nullptr) + +protected: + /** + * Launch the reflow on the child frames - see nsTextControlFrame::Reflow() + */ + void ReflowTextControlChild(nsIFrame* aFrame, + nsPresContext* aPresContext, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus, + nsHTMLReflowMetrics& aParentDesiredSize); + +public: //for methods who access nsTextControlFrame directly + void SetValueChanged(bool aValueChanged); + + // called by the focus listener + nsresult MaybeBeginSecureKeyboardInput(); + void MaybeEndSecureKeyboardInput(); + +#define DEFINE_TEXTCTRL_FORWARDER(type, name) \ + type name() { \ + nsCOMPtr txtCtrl = do_QueryInterface(GetContent()); \ + NS_ASSERTION(txtCtrl, "Content not a text control element"); \ + return txtCtrl->name(); \ + } +#define DEFINE_TEXTCTRL_CONST_FORWARDER(type, name) \ + type name() const { \ + nsCOMPtr txtCtrl = do_QueryInterface(GetContent()); \ + NS_ASSERTION(txtCtrl, "Content not a text control element"); \ + return txtCtrl->name(); \ + } + + DEFINE_TEXTCTRL_CONST_FORWARDER(bool, IsSingleLineTextControl) + DEFINE_TEXTCTRL_CONST_FORWARDER(bool, IsTextArea) + DEFINE_TEXTCTRL_CONST_FORWARDER(bool, IsPlainTextControl) + DEFINE_TEXTCTRL_CONST_FORWARDER(bool, IsPasswordTextControl) + DEFINE_TEXTCTRL_FORWARDER(int32_t, GetCols) + DEFINE_TEXTCTRL_FORWARDER(int32_t, GetWrapCols) + DEFINE_TEXTCTRL_FORWARDER(int32_t, GetRows) + +#undef DEFINE_TEXTCTRL_CONST_FORWARDER +#undef DEFINE_TEXTCTRL_FORWARDER + +protected: + class EditorInitializer; + friend class EditorInitializer; + friend class nsTextEditorState; // needs access to UpdateValueDisplay + + class EditorInitializer : public nsRunnable { + public: + EditorInitializer(nsTextControlFrame* aFrame) : + mFrame(aFrame) {} + + NS_IMETHOD Run() MOZ_OVERRIDE; + + // avoids use of nsWeakFrame + void Revoke() { + mFrame = nullptr; + } + + private: + nsTextControlFrame* mFrame; + }; + + class ScrollOnFocusEvent; + friend class ScrollOnFocusEvent; + + class ScrollOnFocusEvent : public nsRunnable { + public: + ScrollOnFocusEvent(nsTextControlFrame* aFrame) : + mFrame(aFrame) {} + + NS_DECL_NSIRUNNABLE + + void Revoke() { + mFrame = nullptr; + } + + private: + nsTextControlFrame* mFrame; + }; + + nsresult OffsetToDOMPoint(int32_t aOffset, nsIDOMNode** aResult, int32_t* aPosition); + + /** + * Update the textnode under our anonymous div to show the new + * value. This should only be called when we have no editor yet. + * @throws NS_ERROR_UNEXPECTED if the div has no text content + */ + nsresult UpdateValueDisplay(bool aNotify, + bool aBeforeEditorInit = false, + const nsAString *aValue = nullptr); + + /** + * Get the maxlength attribute + * @param aMaxLength the value of the max length attr + * @returns false if attr not defined + */ + bool GetMaxLength(int32_t* aMaxLength); + + /** + * Find out whether an attribute exists on the content or not. + * @param aAtt the attribute to determine the existence of + * @returns false if it does not exist + */ + bool AttributeExists(nsIAtom *aAtt) const + { return mContent && mContent->HasAttr(kNameSpaceID_None, aAtt); } + + /** + * We call this when we are being destroyed or removed from the PFM. + * @param aPresContext the current pres context + */ + void PreDestroy(); + + // Compute our intrinsic size. This does not include any borders, paddings, + // etc. Just the size of our actual area for the text (and the scrollbars, + // for