summaryrefslogtreecommitdiffstats
path: root/layout/forms/nsTextControlFrame.h
diff options
context:
space:
mode:
Diffstat (limited to 'layout/forms/nsTextControlFrame.h')
-rw-r--r--layout/forms/nsTextControlFrame.h319
1 files changed, 319 insertions, 0 deletions
diff --git a/layout/forms/nsTextControlFrame.h b/layout/forms/nsTextControlFrame.h
new file mode 100644
index 000000000..a76cba514
--- /dev/null
+++ b/layout/forms/nsTextControlFrame.h
@@ -0,0 +1,319 @@
+/* -*- 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 "nsIContent.h"
+#include "nsITextControlFrame.h"
+#include "nsITextControlElement.h"
+#include "nsIStatefulFrame.h"
+
+class nsISelectionController;
+class EditorInitializerEntryTracker;
+class nsTextEditorState;
+class nsIEditor;
+namespace mozilla {
+enum class CSSPseudoElementType : uint8_t;
+namespace dom {
+class Element;
+} // namespace dom
+} // namespace mozilla
+
+class nsTextControlFrame final : public nsContainerFrame,
+ public nsIAnonymousContentCreator,
+ public nsITextControlFrame,
+ public nsIStatefulFrame
+{
+public:
+ NS_DECL_FRAMEARENA_HELPERS
+
+ NS_DECLARE_FRAME_PROPERTY_DELETABLE(ContentScrollPos, nsPoint)
+
+ explicit nsTextControlFrame(nsStyleContext* aContext);
+ virtual ~nsTextControlFrame();
+
+ virtual void DestroyFrom(nsIFrame* aDestructRoot) override;
+
+ virtual nsIScrollableFrame* GetScrollTargetFrame() override {
+ return do_QueryFrame(PrincipalChildList().FirstChild());
+ }
+
+ virtual nscoord GetMinISize(nsRenderingContext* aRenderingContext) override;
+ virtual nscoord GetPrefISize(nsRenderingContext* aRenderingContext) override;
+
+ virtual mozilla::LogicalSize
+ ComputeAutoSize(nsRenderingContext* aRenderingContext,
+ mozilla::WritingMode aWM,
+ const mozilla::LogicalSize& aCBSize,
+ nscoord aAvailableISize,
+ const mozilla::LogicalSize& aMargin,
+ const mozilla::LogicalSize& aBorder,
+ const mozilla::LogicalSize& aPadding,
+ ComputeSizeFlags aFlags) override;
+
+ virtual void Reflow(nsPresContext* aPresContext,
+ ReflowOutput& aDesiredSize,
+ const ReflowInput& aReflowInput,
+ nsReflowStatus& aStatus) override;
+
+ virtual nsSize GetXULMinSize(nsBoxLayoutState& aBoxLayoutState) override;
+ virtual bool IsXULCollapsed() override;
+
+ virtual bool IsLeaf() const override;
+
+#ifdef ACCESSIBILITY
+ virtual mozilla::a11y::AccType AccessibleType() override;
+#endif
+
+#ifdef DEBUG_FRAME_DUMP
+ virtual nsresult GetFrameName(nsAString& aResult) const override
+ {
+ aResult.AssignLiteral("nsTextControlFrame");
+ return NS_OK;
+ }
+#endif
+
+ virtual bool IsFrameOfType(uint32_t aFlags) const 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<ContentInfo>& aElements) override;
+ virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
+ uint32_t aFilter) override;
+
+ virtual void SetInitialChildList(ChildListID aListID,
+ nsFrameList& aChildList) override;
+
+ virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
+ const nsRect& aDirtyRect,
+ const nsDisplayListSet& aLists) override;
+
+ virtual mozilla::dom::Element*
+ GetPseudoElement(mozilla::CSSPseudoElementType aType) override;
+
+//==== BEGIN NSIFORMCONTROLFRAME
+ virtual void SetFocus(bool aOn , bool aRepaint) override;
+ virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue) override;
+
+//==== END NSIFORMCONTROLFRAME
+
+//==== NSITEXTCONTROLFRAME
+
+ NS_IMETHOD GetEditor(nsIEditor **aEditor) override;
+ NS_IMETHOD SetSelectionStart(int32_t aSelectionStart) override;
+ NS_IMETHOD SetSelectionEnd(int32_t aSelectionEnd) override;
+ NS_IMETHOD SetSelectionRange(int32_t aSelectionStart,
+ int32_t aSelectionEnd,
+ SelectionDirection aDirection = eNone) override;
+ NS_IMETHOD GetSelectionRange(int32_t* aSelectionStart,
+ int32_t* aSelectionEnd,
+ SelectionDirection* aDirection = nullptr) override;
+ NS_IMETHOD GetOwnedSelectionController(nsISelectionController** aSelCon) override;
+ virtual nsFrameSelection* GetOwnedFrameSelection() override;
+
+ nsresult GetPhonetic(nsAString& aPhonetic) 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() override;
+
+//==== END NSITEXTCONTROLFRAME
+
+//==== NSISTATEFULFRAME
+
+ NS_IMETHOD SaveState(nsPresState** aState) override;
+ NS_IMETHOD RestoreState(nsPresState* aState) override;
+
+//=== END NSISTATEFULFRAME
+
+//==== OVERLOAD of nsIFrame
+ virtual nsIAtom* GetType() const override;
+
+ /** handler for attribute changes to mContent */
+ virtual nsresult AttributeChanged(int32_t aNameSpaceID,
+ nsIAtom* aAttribute,
+ int32_t aModType) override;
+
+ nsresult GetText(nsString& aText);
+
+ virtual nsresult PeekOffset(nsPeekOffsetStruct *aPos) override;
+
+ NS_DECL_QUERYFRAME
+
+protected:
+ /**
+ * Launch the reflow on the child frames - see nsTextControlFrame::Reflow()
+ */
+ void ReflowTextControlChild(nsIFrame* aFrame,
+ nsPresContext* aPresContext,
+ const ReflowInput& aReflowInput,
+ nsReflowStatus& aStatus,
+ ReflowOutput& 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<nsITextControlElement> 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<nsITextControlElement> 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_CONST_FORWARDER(int32_t, GetCols)
+ DEFINE_TEXTCTRL_CONST_FORWARDER(int32_t, GetWrapCols)
+ DEFINE_TEXTCTRL_CONST_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
+
+ // Temp reference to scriptrunner
+ // We could make these auto-Revoking via the "delete" entry for safety
+ NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(TextControlInitializer,
+ EditorInitializer)
+
+ class EditorInitializer : public mozilla::Runnable {
+ public:
+ explicit EditorInitializer(nsTextControlFrame* aFrame) :
+ mFrame(aFrame) {}
+
+ NS_IMETHOD Run() override;
+
+ // avoids use of nsWeakFrame
+ void Revoke() {
+ mFrame = nullptr;
+ }
+
+ private:
+ nsTextControlFrame* mFrame;
+ };
+
+ class ScrollOnFocusEvent;
+ friend class ScrollOnFocusEvent;
+
+ class ScrollOnFocusEvent : public mozilla::Runnable {
+ public:
+ explicit 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 <textarea>).
+ mozilla::LogicalSize CalcIntrinsicSize(nsRenderingContext* aRenderingContext,
+ mozilla::WritingMode aWM,
+ float aFontSizeInflation) const;
+
+ nsresult ScrollSelectionIntoView() override;
+
+private:
+ //helper methods
+ nsresult SetSelectionInternal(nsIDOMNode *aStartNode, int32_t aStartOffset,
+ nsIDOMNode *aEndNode, int32_t aEndOffset,
+ SelectionDirection aDirection = eNone);
+ nsresult SelectAllOrCollapseToEndOfText(bool aSelect);
+ nsresult SetSelectionEndPoints(int32_t aSelStart, int32_t aSelEnd,
+ SelectionDirection aDirection = eNone);
+
+ /**
+ * Return the root DOM element, and implicitly initialize the editor if needed.
+ */
+ mozilla::dom::Element* GetRootNodeAndInitializeEditor();
+ nsresult GetRootNodeAndInitializeEditor(nsIDOMElement **aRootElement);
+
+ void FinishedInitializer() {
+ Properties().Delete(TextControlInitializer());
+ }
+
+private:
+ // these packed bools could instead use the high order bits on mState, saving 4 bytes
+ bool mEditorHasBeenInitialized;
+ bool mIsProcessing;
+ // Keep track if we have asked a placeholder node creation.
+ bool mUsePlaceholder;
+
+#ifdef DEBUG
+ bool mInEditorInitialization;
+ friend class EditorInitializerEntryTracker;
+#endif
+
+ nsRevocableEventPtr<ScrollOnFocusEvent> mScrollEvent;
+};
+
+#endif
+
+