michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* rendering object to wrap rendering objects that should be scrollable */ michael@0: michael@0: #ifndef nsGfxScrollFrame_h___ michael@0: #define nsGfxScrollFrame_h___ michael@0: michael@0: #include "mozilla/Attributes.h" michael@0: #include "nsContainerFrame.h" michael@0: #include "nsIAnonymousContentCreator.h" michael@0: #include "nsBoxFrame.h" michael@0: #include "nsIScrollableFrame.h" michael@0: #include "nsIStatefulFrame.h" michael@0: #include "nsThreadUtils.h" michael@0: #include "nsIReflowCallback.h" michael@0: #include "nsBoxLayoutState.h" michael@0: #include "nsQueryFrame.h" michael@0: #include "nsExpirationTracker.h" michael@0: michael@0: class nsPresContext; michael@0: class nsIPresShell; michael@0: class nsIContent; michael@0: class nsIAtom; michael@0: class nsIScrollFrameInternal; michael@0: class nsPresState; michael@0: class nsIScrollPositionListener; michael@0: struct ScrollReflowState; michael@0: michael@0: namespace mozilla { michael@0: namespace layout { michael@0: class ScrollbarActivity; michael@0: } michael@0: } michael@0: michael@0: namespace mozilla { michael@0: michael@0: class ScrollFrameHelper : public nsIReflowCallback { michael@0: public: michael@0: typedef mozilla::CSSIntPoint CSSIntPoint; michael@0: typedef mozilla::layout::ScrollbarActivity ScrollbarActivity; michael@0: michael@0: class AsyncScroll; michael@0: michael@0: ScrollFrameHelper(nsContainerFrame* aOuter, bool aIsRoot); michael@0: ~ScrollFrameHelper(); michael@0: michael@0: mozilla::ScrollbarStyles GetScrollbarStylesFromFrame() const; michael@0: michael@0: // If a child frame was added or removed on the scrollframe, michael@0: // reload our child frame list. michael@0: // We need this if a scrollbar frame is recreated. michael@0: void ReloadChildFrames(); michael@0: michael@0: nsresult CreateAnonymousContent( michael@0: nsTArray& aElements); michael@0: void AppendAnonymousContentTo(nsBaseContentList& aElements, uint32_t aFilter); michael@0: nsresult FireScrollPortEvent(); michael@0: void PostOverflowEvent(); michael@0: void Destroy(); michael@0: michael@0: void BuildDisplayList(nsDisplayListBuilder* aBuilder, michael@0: const nsRect& aDirtyRect, michael@0: const nsDisplayListSet& aLists); michael@0: michael@0: void AppendScrollPartsTo(nsDisplayListBuilder* aBuilder, michael@0: const nsRect& aDirtyRect, michael@0: const nsDisplayListSet& aLists, michael@0: bool& aCreateLayer, michael@0: bool aPositioned); michael@0: michael@0: bool GetBorderRadii(nscoord aRadii[8]) const; michael@0: michael@0: // nsIReflowCallback michael@0: virtual bool ReflowFinished() MOZ_OVERRIDE; michael@0: virtual void ReflowCallbackCanceled() MOZ_OVERRIDE; michael@0: michael@0: /** michael@0: * @note This method might destroy the frame, pres shell and other objects. michael@0: * Called when the 'curpos' attribute on one of the scrollbars changes. michael@0: */ michael@0: void CurPosAttributeChanged(nsIContent* aChild); michael@0: michael@0: void PostScrollEvent(); michael@0: void FireScrollEvent(); michael@0: void PostScrolledAreaEvent(); michael@0: void FireScrolledAreaEvent(); michael@0: michael@0: class ScrollEvent : public nsRunnable { michael@0: public: michael@0: NS_DECL_NSIRUNNABLE michael@0: ScrollEvent(ScrollFrameHelper *helper) : mHelper(helper) {} michael@0: void Revoke() { mHelper = nullptr; } michael@0: private: michael@0: ScrollFrameHelper *mHelper; michael@0: }; michael@0: michael@0: class AsyncScrollPortEvent : public nsRunnable { michael@0: public: michael@0: NS_DECL_NSIRUNNABLE michael@0: AsyncScrollPortEvent(ScrollFrameHelper *helper) : mHelper(helper) {} michael@0: void Revoke() { mHelper = nullptr; } michael@0: private: michael@0: ScrollFrameHelper *mHelper; michael@0: }; michael@0: michael@0: class ScrolledAreaEvent : public nsRunnable { michael@0: public: michael@0: NS_DECL_NSIRUNNABLE michael@0: ScrolledAreaEvent(ScrollFrameHelper *helper) : mHelper(helper) {} michael@0: void Revoke() { mHelper = nullptr; } michael@0: private: michael@0: ScrollFrameHelper *mHelper; michael@0: }; michael@0: michael@0: /** michael@0: * @note This method might destroy the frame, pres shell and other objects. michael@0: */ michael@0: void FinishReflowForScrollbar(nsIContent* aContent, nscoord aMinXY, michael@0: nscoord aMaxXY, nscoord aCurPosXY, michael@0: nscoord aPageIncrement, michael@0: nscoord aIncrement); michael@0: /** michael@0: * @note This method might destroy the frame, pres shell and other objects. michael@0: */ michael@0: void SetScrollbarEnabled(nsIContent* aContent, nscoord aMaxPos); michael@0: /** michael@0: * @note This method might destroy the frame, pres shell and other objects. michael@0: */ michael@0: void SetCoordAttribute(nsIContent* aContent, nsIAtom* aAtom, nscoord aSize); michael@0: michael@0: nscoord GetCoordAttribute(nsIFrame* aFrame, nsIAtom* aAtom, nscoord aDefaultValue, michael@0: nscoord* aRangeStart, nscoord* aRangeLength); michael@0: michael@0: /** michael@0: * @note This method might destroy the frame, pres shell and other objects. michael@0: * Update scrollbar curpos attributes to reflect current scroll position michael@0: */ michael@0: void UpdateScrollbarPosition(); michael@0: michael@0: nsRect GetScrollPortRect() const { return mScrollPort; } michael@0: nsPoint GetScrollPosition() const { michael@0: return mScrollPort.TopLeft() - mScrolledFrame->GetPosition(); michael@0: } michael@0: /** michael@0: * For LTR frames, the logical scroll position is the offset of the top left michael@0: * corner of the frame from the top left corner of the scroll port (same as michael@0: * GetScrollPosition). michael@0: * For RTL frames, it is the offset of the top right corner of the frame from michael@0: * the top right corner of the scroll port michael@0: */ michael@0: nsPoint GetLogicalScrollPosition() const { michael@0: nsPoint pt; michael@0: pt.x = IsLTR() ? michael@0: mScrollPort.x - mScrolledFrame->GetPosition().x : michael@0: mScrollPort.XMost() - mScrolledFrame->GetRect().XMost(); michael@0: pt.y = mScrollPort.y - mScrolledFrame->GetPosition().y; michael@0: return pt; michael@0: } michael@0: nsRect GetScrollRange() const; michael@0: // Get the scroll range assuming the scrollport has size (aWidth, aHeight). michael@0: nsRect GetScrollRange(nscoord aWidth, nscoord aHeight) const; michael@0: nsSize GetScrollPositionClampingScrollPortSize() const; michael@0: gfxSize GetResolution() const; michael@0: void SetResolution(const gfxSize& aResolution); michael@0: michael@0: protected: michael@0: nsRect GetScrollRangeForClamping() const; michael@0: michael@0: public: michael@0: static void AsyncScrollCallback(void* anInstance, mozilla::TimeStamp aTime); michael@0: /** michael@0: * @note This method might destroy the frame, pres shell and other objects. michael@0: * aRange is the range of allowable scroll positions around the desired michael@0: * aScrollPosition. Null means only aScrollPosition is allowed. michael@0: * This is a closed-ended range --- aRange.XMost()/aRange.YMost() are allowed. michael@0: */ michael@0: void ScrollTo(nsPoint aScrollPosition, nsIScrollableFrame::ScrollMode aMode, michael@0: const nsRect* aRange = nullptr) { michael@0: ScrollToWithOrigin(aScrollPosition, aMode, nsGkAtoms::other, aRange); michael@0: } michael@0: /** michael@0: * @note This method might destroy the frame, pres shell and other objects. michael@0: */ michael@0: void ScrollToCSSPixels(const CSSIntPoint& aScrollPosition); michael@0: /** michael@0: * @note This method might destroy the frame, pres shell and other objects. michael@0: */ michael@0: void ScrollToCSSPixelsApproximate(const mozilla::CSSPoint& aScrollPosition, michael@0: nsIAtom* aOrigin = nullptr); michael@0: michael@0: CSSIntPoint GetScrollPositionCSSPixels(); michael@0: /** michael@0: * @note This method might destroy the frame, pres shell and other objects. michael@0: */ michael@0: void ScrollToImpl(nsPoint aScrollPosition, const nsRect& aRange, nsIAtom* aOrigin = nullptr); michael@0: void ScrollVisual(nsPoint aOldScrolledFramePosition); michael@0: /** michael@0: * @note This method might destroy the frame, pres shell and other objects. michael@0: */ michael@0: void ScrollBy(nsIntPoint aDelta, nsIScrollableFrame::ScrollUnit aUnit, michael@0: nsIScrollableFrame::ScrollMode aMode, nsIntPoint* aOverflow, nsIAtom *aOrigin = nullptr); michael@0: /** michael@0: * @note This method might destroy the frame, pres shell and other objects. michael@0: */ michael@0: void ScrollToRestoredPosition(); michael@0: michael@0: nsSize GetLineScrollAmount() const; michael@0: nsSize GetPageScrollAmount() const; michael@0: michael@0: nsPresState* SaveState() const; michael@0: void RestoreState(nsPresState* aState); michael@0: michael@0: nsIFrame* GetScrolledFrame() const { return mScrolledFrame; } michael@0: nsIFrame* GetScrollbarBox(bool aVertical) const { michael@0: return aVertical ? mVScrollbarBox : mHScrollbarBox; michael@0: } michael@0: michael@0: void AddScrollPositionListener(nsIScrollPositionListener* aListener) { michael@0: mListeners.AppendElement(aListener); michael@0: } michael@0: void RemoveScrollPositionListener(nsIScrollPositionListener* aListener) { michael@0: mListeners.RemoveElement(aListener); michael@0: } michael@0: michael@0: static void SetScrollbarVisibility(nsIFrame* aScrollbar, bool aVisible); michael@0: michael@0: /** michael@0: * GetScrolledRect is designed to encapsulate deciding which michael@0: * directions of overflow should be reachable by scrolling and which michael@0: * should not. Callers should NOT depend on it having any particular michael@0: * behavior (although nsXULScrollFrame currently does). michael@0: * michael@0: * This should only be called when the scrolled frame has been michael@0: * reflowed with the scroll port size given in mScrollPort. michael@0: * michael@0: * Currently it allows scrolling down and to the right for michael@0: * nsHTMLScrollFrames with LTR directionality and for all michael@0: * nsXULScrollFrames, and allows scrolling down and to the left for michael@0: * nsHTMLScrollFrames with RTL directionality. michael@0: */ michael@0: nsRect GetScrolledRect() const; michael@0: michael@0: /** michael@0: * GetScrolledRectInternal is designed to encapsulate deciding which michael@0: * directions of overflow should be reachable by scrolling and which michael@0: * should not. Callers should NOT depend on it having any particular michael@0: * behavior (although nsXULScrollFrame currently does). michael@0: * michael@0: * Currently it allows scrolling down and to the right for michael@0: * nsHTMLScrollFrames with LTR directionality and for all michael@0: * nsXULScrollFrames, and allows scrolling down and to the left for michael@0: * nsHTMLScrollFrames with RTL directionality. michael@0: */ michael@0: nsRect GetScrolledRectInternal(const nsRect& aScrolledOverflowArea, michael@0: const nsSize& aScrollPortSize) const; michael@0: michael@0: uint32_t GetScrollbarVisibility() const { michael@0: return (mHasVerticalScrollbar ? nsIScrollableFrame::VERTICAL : 0) | michael@0: (mHasHorizontalScrollbar ? nsIScrollableFrame::HORIZONTAL : 0); michael@0: } michael@0: nsMargin GetActualScrollbarSizes() const; michael@0: nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState); michael@0: nscoord GetNondisappearingScrollbarWidth(nsBoxLayoutState* aState); michael@0: bool IsLTR() const; michael@0: bool IsScrollbarOnRight() const; michael@0: bool IsScrollingActive() const { return mScrollingActive || mShouldBuildScrollableLayer; } michael@0: bool IsProcessingAsyncScroll() const { return mAsyncScroll != nullptr; } michael@0: void ResetScrollPositionForLayerPixelAlignment() michael@0: { michael@0: mScrollPosForLayerPixelAlignment = GetScrollPosition(); michael@0: } michael@0: michael@0: bool UpdateOverflow(); michael@0: michael@0: void UpdateSticky(); michael@0: michael@0: bool IsRectNearlyVisible(const nsRect& aRect) const; michael@0: michael@0: // adjust the scrollbar rectangle aRect to account for any visible resizer. michael@0: // aHasResizer specifies if there is a content resizer, however this method michael@0: // will also check if a widget resizer is present as well. michael@0: void AdjustScrollbarRectForResizer(nsIFrame* aFrame, nsPresContext* aPresContext, michael@0: nsRect& aRect, bool aHasResizer, bool aVertical); michael@0: // returns true if a resizer should be visible michael@0: bool HasResizer() { return mResizerBox && !mCollapsedResizer; } michael@0: void LayoutScrollbars(nsBoxLayoutState& aState, michael@0: const nsRect& aContentArea, michael@0: const nsRect& aOldScrollArea); michael@0: michael@0: bool IsIgnoringViewportClipping() const; michael@0: michael@0: bool ShouldClampScrollPosition() const; michael@0: michael@0: bool IsAlwaysActive() const; michael@0: void MarkActive(); michael@0: void MarkInactive(); michael@0: nsExpirationState* GetExpirationState() { return &mActivityExpirationState; } michael@0: michael@0: void ScheduleSyntheticMouseMove(); michael@0: static void ScrollActivityCallback(nsITimer *aTimer, void* anInstance); michael@0: michael@0: void HandleScrollbarStyleSwitching(); michael@0: michael@0: nsIAtom* OriginOfLastScroll() const { return mOriginOfLastScroll; } michael@0: uint32_t CurrentScrollGeneration() const { return mScrollGeneration; } michael@0: void ResetOriginIfScrollAtGeneration(uint32_t aGeneration) { michael@0: if (aGeneration == mScrollGeneration) { michael@0: mOriginOfLastScroll = nullptr; michael@0: } michael@0: } michael@0: bool WantAsyncScroll() const; michael@0: michael@0: // owning references to the nsIAnonymousContentCreator-built content michael@0: nsCOMPtr mHScrollbarContent; michael@0: nsCOMPtr mVScrollbarContent; michael@0: nsCOMPtr mScrollCornerContent; michael@0: nsCOMPtr mResizerContent; michael@0: michael@0: nsRevocableEventPtr mScrollEvent; michael@0: nsRevocableEventPtr mAsyncScrollPortEvent; michael@0: nsRevocableEventPtr mScrolledAreaEvent; michael@0: nsIFrame* mHScrollbarBox; michael@0: nsIFrame* mVScrollbarBox; michael@0: nsIFrame* mScrolledFrame; michael@0: nsIFrame* mScrollCornerBox; michael@0: nsIFrame* mResizerBox; michael@0: nsContainerFrame* mOuter; michael@0: nsRefPtr mAsyncScroll; michael@0: nsRefPtr mScrollbarActivity; michael@0: nsTArray mListeners; michael@0: nsIAtom* mOriginOfLastScroll; michael@0: uint32_t mScrollGeneration; michael@0: nsRect mScrollPort; michael@0: // Where we're currently scrolling to, if we're scrolling asynchronously. michael@0: // If we're not in the middle of an asynchronous scroll then this is michael@0: // just the current scroll position. ScrollBy will choose its michael@0: // destination based on this value. michael@0: nsPoint mDestination; michael@0: nsPoint mScrollPosAtLastPaint; michael@0: michael@0: // A goal position to try to scroll to as content loads. As long as mLastPos michael@0: // matches the current logical scroll position, we try to scroll to mRestorePos michael@0: // after every reflow --- because after each time content is loaded/added to the michael@0: // scrollable element, there will be a reflow. michael@0: nsPoint mRestorePos; michael@0: // The last logical position we scrolled to while trying to restore mRestorePos, or michael@0: // 0,0 when this is a new frame. Set to -1,-1 once we've scrolled for any reason michael@0: // other than trying to restore mRestorePos. michael@0: nsPoint mLastPos; michael@0: michael@0: // The current resolution derived from the zoom level and device pixel ratio. michael@0: gfxSize mResolution; michael@0: michael@0: nsExpirationState mActivityExpirationState; michael@0: michael@0: nsCOMPtr mScrollActivityTimer; michael@0: nsPoint mScrollPosForLayerPixelAlignment; michael@0: michael@0: // The scroll position where we last updated image visibility. michael@0: nsPoint mLastUpdateImagesPos; michael@0: michael@0: bool mNeverHasVerticalScrollbar:1; michael@0: bool mNeverHasHorizontalScrollbar:1; michael@0: bool mHasVerticalScrollbar:1; michael@0: bool mHasHorizontalScrollbar:1; michael@0: bool mFrameIsUpdatingScrollbar:1; michael@0: bool mDidHistoryRestore:1; michael@0: // Is this the scrollframe for the document's viewport? michael@0: bool mIsRoot:1; michael@0: // True if we should clip all descendants, false if we should only clip michael@0: // descendants for which we are the containing block. michael@0: bool mClipAllDescendants:1; michael@0: // If true, don't try to layout the scrollbars in Reflow(). This can be michael@0: // useful if multiple passes are involved, because we don't want to place the michael@0: // scrollbars at the wrong size. michael@0: bool mSupppressScrollbarUpdate:1; michael@0: // If true, we skipped a scrollbar layout due to mSupppressScrollbarUpdate michael@0: // being set at some point. That means we should lay out scrollbars even if michael@0: // it might not strictly be needed next time mSupppressScrollbarUpdate is michael@0: // false. michael@0: bool mSkippedScrollbarLayout:1; michael@0: michael@0: bool mHadNonInitialReflow:1; michael@0: // State used only by PostScrollEvents so we know michael@0: // which overflow states have changed. michael@0: bool mHorizontalOverflow:1; michael@0: bool mVerticalOverflow:1; michael@0: bool mPostedReflowCallback:1; michael@0: bool mMayHaveDirtyFixedChildren:1; michael@0: // If true, need to actually update our scrollbar attributes in the michael@0: // reflow callback. michael@0: bool mUpdateScrollbarAttributes:1; michael@0: // If true, we should be prepared to scroll using this scrollframe michael@0: // by placing descendant content into its own layer(s) michael@0: bool mScrollingActive:1; michael@0: // If true, the resizer is collapsed and not displayed michael@0: bool mCollapsedResizer:1; michael@0: michael@0: // If true, the layer should always be active because we always build a michael@0: // scrollable layer. Used for asynchronous scrolling. michael@0: bool mShouldBuildScrollableLayer:1; michael@0: michael@0: // True if this frame has been scrolled at least once michael@0: bool mHasBeenScrolled:1; michael@0: michael@0: // True if the frame's resolution has been set via SetResolution or restored michael@0: // via RestoreState. michael@0: bool mIsResolutionSet:1; michael@0: michael@0: protected: michael@0: /** michael@0: * @note This method might destroy the frame, pres shell and other objects. michael@0: */ michael@0: void ScrollToWithOrigin(nsPoint aScrollPosition, michael@0: nsIScrollableFrame::ScrollMode aMode, michael@0: nsIAtom *aOrigin, // nullptr indicates "other" origin michael@0: const nsRect* aRange); michael@0: michael@0: nsRect ExpandRect(const nsRect& aRect) const; michael@0: static void EnsureImageVisPrefsCached(); michael@0: static bool sImageVisPrefsCached; michael@0: // The number of scrollports wide/high to expand when looking for images. michael@0: static uint32_t sHorzExpandScrollPort; michael@0: static uint32_t sVertExpandScrollPort; michael@0: // The fraction of the scrollport we allow to scroll by before we schedule michael@0: // an update of image visibility. michael@0: static int32_t sHorzScrollFraction; michael@0: static int32_t sVertScrollFraction; michael@0: }; michael@0: michael@0: } michael@0: michael@0: /** michael@0: * The scroll frame creates and manages the scrolling view michael@0: * michael@0: * It only supports having a single child frame that typically is an area michael@0: * frame, but doesn't have to be. The child frame must have a view, though michael@0: * michael@0: * Scroll frames don't support incremental changes, i.e. you can't replace michael@0: * or remove the scrolled frame michael@0: */ michael@0: class nsHTMLScrollFrame : public nsContainerFrame, michael@0: public nsIScrollableFrame, michael@0: public nsIAnonymousContentCreator, michael@0: public nsIStatefulFrame { michael@0: public: michael@0: typedef mozilla::ScrollFrameHelper ScrollFrameHelper; michael@0: typedef mozilla::CSSIntPoint CSSIntPoint; michael@0: friend nsIFrame* NS_NewHTMLScrollFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, bool aIsRoot); michael@0: michael@0: NS_DECL_QUERYFRAME michael@0: NS_DECL_FRAMEARENA_HELPERS michael@0: michael@0: // Called to set the child frames. We typically have three: the scroll area, michael@0: // the vertical scrollbar, and the horizontal scrollbar. michael@0: virtual nsresult SetInitialChildList(ChildListID aListID, michael@0: nsFrameList& aChildList) MOZ_OVERRIDE; michael@0: michael@0: virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, michael@0: const nsRect& aDirtyRect, michael@0: const nsDisplayListSet& aLists) MOZ_OVERRIDE { michael@0: mHelper.BuildDisplayList(aBuilder, aDirtyRect, aLists); michael@0: } michael@0: michael@0: bool TryLayout(ScrollReflowState* aState, michael@0: nsHTMLReflowMetrics* aKidMetrics, michael@0: bool aAssumeVScroll, bool aAssumeHScroll, michael@0: bool aForce, nsresult* aResult); michael@0: bool ScrolledContentDependsOnHeight(ScrollReflowState* aState); michael@0: nsresult ReflowScrolledFrame(ScrollReflowState* aState, michael@0: bool aAssumeHScroll, michael@0: bool aAssumeVScroll, michael@0: nsHTMLReflowMetrics* aMetrics, michael@0: bool aFirstPass); michael@0: nsresult ReflowContents(ScrollReflowState* aState, michael@0: const nsHTMLReflowMetrics& aDesiredSize); michael@0: void PlaceScrollArea(const ScrollReflowState& aState, michael@0: const nsPoint& aScrollPosition); michael@0: nscoord GetIntrinsicVScrollbarWidth(nsRenderingContext *aRenderingContext); michael@0: michael@0: virtual bool GetBorderRadii(nscoord aRadii[8]) const MOZ_OVERRIDE { michael@0: return mHelper.GetBorderRadii(aRadii); michael@0: } michael@0: michael@0: virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; michael@0: virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; michael@0: virtual nsresult GetPadding(nsMargin& aPadding) MOZ_OVERRIDE; michael@0: virtual bool IsCollapsed() MOZ_OVERRIDE; michael@0: michael@0: virtual nsresult Reflow(nsPresContext* aPresContext, michael@0: nsHTMLReflowMetrics& aDesiredSize, michael@0: const nsHTMLReflowState& aReflowState, michael@0: nsReflowStatus& aStatus) MOZ_OVERRIDE; michael@0: michael@0: virtual bool UpdateOverflow() MOZ_OVERRIDE { michael@0: return mHelper.UpdateOverflow(); michael@0: } michael@0: michael@0: // Because there can be only one child frame, these two function return michael@0: // NS_ERROR_FAILURE michael@0: virtual nsresult AppendFrames(ChildListID aListID, michael@0: nsFrameList& aFrameList) MOZ_OVERRIDE; michael@0: virtual nsresult InsertFrames(ChildListID aListID, michael@0: nsIFrame* aPrevFrame, michael@0: nsFrameList& aFrameList) MOZ_OVERRIDE; michael@0: michael@0: virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; michael@0: michael@0: michael@0: virtual nsresult RemoveFrame(ChildListID aListID, michael@0: nsIFrame* aOldFrame) MOZ_OVERRIDE; michael@0: michael@0: virtual nsIScrollableFrame* GetScrollTargetFrame() MOZ_OVERRIDE { michael@0: return this; michael@0: } michael@0: michael@0: virtual nsIFrame* GetContentInsertionFrame() MOZ_OVERRIDE { michael@0: return mHelper.GetScrolledFrame()->GetContentInsertionFrame(); michael@0: } michael@0: michael@0: virtual bool DoesClipChildren() MOZ_OVERRIDE { return true; } michael@0: virtual nsSplittableType GetSplittableType() const MOZ_OVERRIDE; michael@0: michael@0: virtual nsPoint GetPositionOfChildIgnoringScrolling(nsIFrame* aChild) MOZ_OVERRIDE michael@0: { nsPoint pt = aChild->GetPosition(); michael@0: if (aChild == mHelper.GetScrolledFrame()) pt += GetScrollPosition(); michael@0: return pt; michael@0: } michael@0: michael@0: // nsIAnonymousContentCreator michael@0: virtual nsresult CreateAnonymousContent(nsTArray& aElements) MOZ_OVERRIDE; michael@0: virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, michael@0: uint32_t aFilter) MOZ_OVERRIDE; michael@0: michael@0: // nsIScrollbarOwner michael@0: virtual nsIFrame* GetScrollbarBox(bool aVertical) MOZ_OVERRIDE { michael@0: return mHelper.GetScrollbarBox(aVertical); michael@0: } michael@0: michael@0: virtual void ScrollbarActivityStarted() const MOZ_OVERRIDE; michael@0: virtual void ScrollbarActivityStopped() const MOZ_OVERRIDE; michael@0: michael@0: // nsIScrollableFrame michael@0: virtual nsIFrame* GetScrolledFrame() const MOZ_OVERRIDE { michael@0: return mHelper.GetScrolledFrame(); michael@0: } michael@0: virtual mozilla::ScrollbarStyles GetScrollbarStyles() const MOZ_OVERRIDE { michael@0: return mHelper.GetScrollbarStylesFromFrame(); michael@0: } michael@0: virtual uint32_t GetScrollbarVisibility() const MOZ_OVERRIDE { michael@0: return mHelper.GetScrollbarVisibility(); michael@0: } michael@0: virtual nsMargin GetActualScrollbarSizes() const MOZ_OVERRIDE { michael@0: return mHelper.GetActualScrollbarSizes(); michael@0: } michael@0: virtual nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState) MOZ_OVERRIDE { michael@0: return mHelper.GetDesiredScrollbarSizes(aState); michael@0: } michael@0: virtual nsMargin GetDesiredScrollbarSizes(nsPresContext* aPresContext, michael@0: nsRenderingContext* aRC) MOZ_OVERRIDE { michael@0: nsBoxLayoutState bls(aPresContext, aRC, 0); michael@0: return GetDesiredScrollbarSizes(&bls); michael@0: } michael@0: virtual nscoord GetNondisappearingScrollbarWidth(nsPresContext* aPresContext, michael@0: nsRenderingContext* aRC) MOZ_OVERRIDE { michael@0: nsBoxLayoutState bls(aPresContext, aRC, 0); michael@0: return mHelper.GetNondisappearingScrollbarWidth(&bls); michael@0: } michael@0: virtual nsRect GetScrolledRect() const MOZ_OVERRIDE { michael@0: return mHelper.GetScrolledRect(); michael@0: } michael@0: virtual nsRect GetScrollPortRect() const MOZ_OVERRIDE { michael@0: return mHelper.GetScrollPortRect(); michael@0: } michael@0: virtual nsPoint GetScrollPosition() const MOZ_OVERRIDE { michael@0: return mHelper.GetScrollPosition(); michael@0: } michael@0: virtual nsPoint GetLogicalScrollPosition() const MOZ_OVERRIDE { michael@0: return mHelper.GetLogicalScrollPosition(); michael@0: } michael@0: virtual nsRect GetScrollRange() const MOZ_OVERRIDE { michael@0: return mHelper.GetScrollRange(); michael@0: } michael@0: virtual nsSize GetScrollPositionClampingScrollPortSize() const MOZ_OVERRIDE { michael@0: return mHelper.GetScrollPositionClampingScrollPortSize(); michael@0: } michael@0: virtual gfxSize GetResolution() const MOZ_OVERRIDE { michael@0: return mHelper.GetResolution(); michael@0: } michael@0: virtual void SetResolution(const gfxSize& aResolution) MOZ_OVERRIDE { michael@0: return mHelper.SetResolution(aResolution); michael@0: } michael@0: virtual nsSize GetLineScrollAmount() const MOZ_OVERRIDE { michael@0: return mHelper.GetLineScrollAmount(); michael@0: } michael@0: virtual nsSize GetPageScrollAmount() const MOZ_OVERRIDE { michael@0: return mHelper.GetPageScrollAmount(); michael@0: } michael@0: /** michael@0: * @note This method might destroy the frame, pres shell and other objects. michael@0: */ michael@0: virtual void ScrollTo(nsPoint aScrollPosition, ScrollMode aMode, michael@0: const nsRect* aRange = nullptr) MOZ_OVERRIDE { michael@0: mHelper.ScrollTo(aScrollPosition, aMode, aRange); michael@0: } michael@0: /** michael@0: * @note This method might destroy the frame, pres shell and other objects. michael@0: */ michael@0: virtual void ScrollToCSSPixels(const CSSIntPoint& aScrollPosition) MOZ_OVERRIDE { michael@0: mHelper.ScrollToCSSPixels(aScrollPosition); michael@0: } michael@0: virtual void ScrollToCSSPixelsApproximate(const mozilla::CSSPoint& aScrollPosition, michael@0: nsIAtom* aOrigin = nullptr) MOZ_OVERRIDE { michael@0: mHelper.ScrollToCSSPixelsApproximate(aScrollPosition, aOrigin); michael@0: } michael@0: /** michael@0: * @note This method might destroy the frame, pres shell and other objects. michael@0: */ michael@0: virtual CSSIntPoint GetScrollPositionCSSPixels() MOZ_OVERRIDE { michael@0: return mHelper.GetScrollPositionCSSPixels(); michael@0: } michael@0: /** michael@0: * @note This method might destroy the frame, pres shell and other objects. michael@0: */ michael@0: virtual void ScrollBy(nsIntPoint aDelta, ScrollUnit aUnit, ScrollMode aMode, michael@0: nsIntPoint* aOverflow, nsIAtom *aOrigin = nullptr) MOZ_OVERRIDE { michael@0: mHelper.ScrollBy(aDelta, aUnit, aMode, aOverflow, aOrigin); michael@0: } michael@0: /** michael@0: * @note This method might destroy the frame, pres shell and other objects. michael@0: */ michael@0: virtual void ScrollToRestoredPosition() MOZ_OVERRIDE { michael@0: mHelper.ScrollToRestoredPosition(); michael@0: } michael@0: virtual void AddScrollPositionListener(nsIScrollPositionListener* aListener) MOZ_OVERRIDE { michael@0: mHelper.AddScrollPositionListener(aListener); michael@0: } michael@0: virtual void RemoveScrollPositionListener(nsIScrollPositionListener* aListener) MOZ_OVERRIDE { michael@0: mHelper.RemoveScrollPositionListener(aListener); michael@0: } michael@0: /** michael@0: * @note This method might destroy the frame, pres shell and other objects. michael@0: */ michael@0: virtual void CurPosAttributeChanged(nsIContent* aChild) MOZ_OVERRIDE { michael@0: mHelper.CurPosAttributeChanged(aChild); michael@0: } michael@0: NS_IMETHOD PostScrolledAreaEventForCurrentArea() MOZ_OVERRIDE { michael@0: mHelper.PostScrolledAreaEvent(); michael@0: return NS_OK; michael@0: } michael@0: virtual bool IsScrollingActive() MOZ_OVERRIDE { michael@0: return mHelper.IsScrollingActive(); michael@0: } michael@0: virtual bool IsProcessingAsyncScroll() MOZ_OVERRIDE { michael@0: return mHelper.IsProcessingAsyncScroll(); michael@0: } michael@0: virtual void ResetScrollPositionForLayerPixelAlignment() MOZ_OVERRIDE { michael@0: mHelper.ResetScrollPositionForLayerPixelAlignment(); michael@0: } michael@0: virtual bool IsResolutionSet() const MOZ_OVERRIDE { michael@0: return mHelper.mIsResolutionSet; michael@0: } michael@0: virtual bool DidHistoryRestore() const MOZ_OVERRIDE { michael@0: return mHelper.mDidHistoryRestore; michael@0: } michael@0: virtual void ClearDidHistoryRestore() MOZ_OVERRIDE { michael@0: mHelper.mDidHistoryRestore = false; michael@0: } michael@0: virtual bool IsRectNearlyVisible(const nsRect& aRect) MOZ_OVERRIDE { michael@0: return mHelper.IsRectNearlyVisible(aRect); michael@0: } michael@0: virtual nsIAtom* OriginOfLastScroll() MOZ_OVERRIDE { michael@0: return mHelper.OriginOfLastScroll(); michael@0: } michael@0: virtual uint32_t CurrentScrollGeneration() MOZ_OVERRIDE { michael@0: return mHelper.CurrentScrollGeneration(); michael@0: } michael@0: virtual void ResetOriginIfScrollAtGeneration(uint32_t aGeneration) MOZ_OVERRIDE { michael@0: mHelper.ResetOriginIfScrollAtGeneration(aGeneration); michael@0: } michael@0: virtual bool WantAsyncScroll() const MOZ_OVERRIDE { michael@0: return mHelper.WantAsyncScroll(); michael@0: } michael@0: michael@0: // nsIStatefulFrame michael@0: NS_IMETHOD SaveState(nsPresState** aState) MOZ_OVERRIDE { michael@0: NS_ENSURE_ARG_POINTER(aState); michael@0: *aState = mHelper.SaveState(); michael@0: return NS_OK; michael@0: } michael@0: NS_IMETHOD RestoreState(nsPresState* aState) MOZ_OVERRIDE { michael@0: NS_ENSURE_ARG_POINTER(aState); michael@0: mHelper.RestoreState(aState); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /** michael@0: * Get the "type" of the frame michael@0: * michael@0: * @see nsGkAtoms::scrollFrame michael@0: */ michael@0: virtual nsIAtom* GetType() const MOZ_OVERRIDE; michael@0: michael@0: #ifdef DEBUG_FRAME_DUMP michael@0: virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; michael@0: #endif michael@0: michael@0: #ifdef ACCESSIBILITY michael@0: virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE; michael@0: #endif michael@0: michael@0: protected: michael@0: nsHTMLScrollFrame(nsIPresShell* aShell, nsStyleContext* aContext, bool aIsRoot); michael@0: void SetSuppressScrollbarUpdate(bool aSuppress) { michael@0: mHelper.mSupppressScrollbarUpdate = aSuppress; michael@0: } michael@0: bool GuessHScrollbarNeeded(const ScrollReflowState& aState); michael@0: bool GuessVScrollbarNeeded(const ScrollReflowState& aState); michael@0: michael@0: bool IsScrollbarUpdateSuppressed() const { michael@0: return mHelper.mSupppressScrollbarUpdate; michael@0: } michael@0: michael@0: // Return whether we're in an "initial" reflow. Some reflows with michael@0: // NS_FRAME_FIRST_REFLOW set are NOT "initial" as far as we're concerned. michael@0: bool InInitialReflow() const; michael@0: michael@0: /** michael@0: * Override this to return false if computed height/min-height/max-height michael@0: * should NOT be propagated to child content. michael@0: * nsListControlFrame uses this. michael@0: */ michael@0: virtual bool ShouldPropagateComputedHeightToScrolledContent() const { return true; } michael@0: michael@0: private: michael@0: friend class mozilla::ScrollFrameHelper; michael@0: ScrollFrameHelper mHelper; michael@0: }; michael@0: michael@0: /** michael@0: * The scroll frame creates and manages the scrolling view michael@0: * michael@0: * It only supports having a single child frame that typically is an area michael@0: * frame, but doesn't have to be. The child frame must have a view, though michael@0: * michael@0: * Scroll frames don't support incremental changes, i.e. you can't replace michael@0: * or remove the scrolled frame michael@0: */ michael@0: class nsXULScrollFrame : public nsBoxFrame, michael@0: public nsIScrollableFrame, michael@0: public nsIAnonymousContentCreator, michael@0: public nsIStatefulFrame { michael@0: public: michael@0: typedef mozilla::ScrollFrameHelper ScrollFrameHelper; michael@0: typedef mozilla::CSSIntPoint CSSIntPoint; michael@0: michael@0: NS_DECL_QUERYFRAME michael@0: NS_DECL_FRAMEARENA_HELPERS michael@0: michael@0: friend nsIFrame* NS_NewXULScrollFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, michael@0: bool aIsRoot, bool aClipAllDescendants); michael@0: michael@0: // Called to set the child frames. We typically have three: the scroll area, michael@0: // the vertical scrollbar, and the horizontal scrollbar. michael@0: virtual nsresult SetInitialChildList(ChildListID aListID, michael@0: nsFrameList& aChildList) MOZ_OVERRIDE; michael@0: michael@0: virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, michael@0: const nsRect& aDirtyRect, michael@0: const nsDisplayListSet& aLists) MOZ_OVERRIDE { michael@0: mHelper.BuildDisplayList(aBuilder, aDirtyRect, aLists); michael@0: } michael@0: michael@0: // XXXldb Is this actually used? michael@0: #if 0 michael@0: virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; michael@0: #endif michael@0: michael@0: virtual bool UpdateOverflow() MOZ_OVERRIDE { michael@0: return mHelper.UpdateOverflow(); michael@0: } michael@0: michael@0: // Because there can be only one child frame, these two function return michael@0: // NS_ERROR_FAILURE michael@0: virtual nsresult AppendFrames(ChildListID aListID, michael@0: nsFrameList& aFrameList) MOZ_OVERRIDE; michael@0: virtual nsresult InsertFrames(ChildListID aListID, michael@0: nsIFrame* aPrevFrame, michael@0: nsFrameList& aFrameList) MOZ_OVERRIDE; michael@0: michael@0: virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; michael@0: michael@0: virtual nsresult RemoveFrame(ChildListID aListID, michael@0: nsIFrame* aOldFrame) MOZ_OVERRIDE; michael@0: michael@0: virtual nsIScrollableFrame* GetScrollTargetFrame() MOZ_OVERRIDE { michael@0: return this; michael@0: } michael@0: michael@0: virtual nsIFrame* GetContentInsertionFrame() MOZ_OVERRIDE { michael@0: return mHelper.GetScrolledFrame()->GetContentInsertionFrame(); michael@0: } michael@0: michael@0: virtual bool DoesClipChildren() MOZ_OVERRIDE { return true; } michael@0: virtual nsSplittableType GetSplittableType() const MOZ_OVERRIDE; michael@0: michael@0: virtual nsPoint GetPositionOfChildIgnoringScrolling(nsIFrame* aChild) MOZ_OVERRIDE michael@0: { nsPoint pt = aChild->GetPosition(); michael@0: if (aChild == mHelper.GetScrolledFrame()) michael@0: pt += mHelper.GetLogicalScrollPosition(); michael@0: return pt; michael@0: } michael@0: michael@0: // nsIAnonymousContentCreator michael@0: virtual nsresult CreateAnonymousContent(nsTArray& aElements) MOZ_OVERRIDE; michael@0: virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, michael@0: uint32_t aFilter) MOZ_OVERRIDE; michael@0: michael@0: virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; michael@0: virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; michael@0: virtual nsSize GetMaxSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; michael@0: virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; michael@0: michael@0: NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; michael@0: virtual nsresult GetPadding(nsMargin& aPadding) MOZ_OVERRIDE; michael@0: michael@0: virtual bool GetBorderRadii(nscoord aRadii[8]) const MOZ_OVERRIDE { michael@0: return mHelper.GetBorderRadii(aRadii); michael@0: } michael@0: michael@0: nsresult Layout(nsBoxLayoutState& aState); michael@0: void LayoutScrollArea(nsBoxLayoutState& aState, const nsPoint& aScrollPosition); michael@0: michael@0: static bool AddRemoveScrollbar(bool& aHasScrollbar, michael@0: nscoord& aXY, michael@0: nscoord& aSize, michael@0: nscoord aSbSize, michael@0: bool aOnRightOrBottom, michael@0: bool aAdd); michael@0: michael@0: bool AddRemoveScrollbar(nsBoxLayoutState& aState, michael@0: bool aOnRightOrBottom, michael@0: bool aHorizontal, michael@0: bool aAdd); michael@0: michael@0: bool AddHorizontalScrollbar (nsBoxLayoutState& aState, bool aOnBottom); michael@0: bool AddVerticalScrollbar (nsBoxLayoutState& aState, bool aOnRight); michael@0: void RemoveHorizontalScrollbar(nsBoxLayoutState& aState, bool aOnBottom); michael@0: void RemoveVerticalScrollbar (nsBoxLayoutState& aState, bool aOnRight); michael@0: michael@0: static void AdjustReflowStateForPrintPreview(nsBoxLayoutState& aState, bool& aSetBack); michael@0: static void AdjustReflowStateBack(nsBoxLayoutState& aState, bool aSetBack); michael@0: michael@0: // nsIScrollbarOwner michael@0: virtual nsIFrame* GetScrollbarBox(bool aVertical) MOZ_OVERRIDE { michael@0: return mHelper.GetScrollbarBox(aVertical); michael@0: } michael@0: michael@0: virtual void ScrollbarActivityStarted() const MOZ_OVERRIDE; michael@0: virtual void ScrollbarActivityStopped() const MOZ_OVERRIDE; michael@0: michael@0: // nsIScrollableFrame michael@0: virtual nsIFrame* GetScrolledFrame() const MOZ_OVERRIDE { michael@0: return mHelper.GetScrolledFrame(); michael@0: } michael@0: virtual mozilla::ScrollbarStyles GetScrollbarStyles() const MOZ_OVERRIDE { michael@0: return mHelper.GetScrollbarStylesFromFrame(); michael@0: } michael@0: virtual uint32_t GetScrollbarVisibility() const MOZ_OVERRIDE { michael@0: return mHelper.GetScrollbarVisibility(); michael@0: } michael@0: virtual nsMargin GetActualScrollbarSizes() const MOZ_OVERRIDE { michael@0: return mHelper.GetActualScrollbarSizes(); michael@0: } michael@0: virtual nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState) MOZ_OVERRIDE { michael@0: return mHelper.GetDesiredScrollbarSizes(aState); michael@0: } michael@0: virtual nsMargin GetDesiredScrollbarSizes(nsPresContext* aPresContext, michael@0: nsRenderingContext* aRC) MOZ_OVERRIDE { michael@0: nsBoxLayoutState bls(aPresContext, aRC, 0); michael@0: return GetDesiredScrollbarSizes(&bls); michael@0: } michael@0: virtual nscoord GetNondisappearingScrollbarWidth(nsPresContext* aPresContext, michael@0: nsRenderingContext* aRC) MOZ_OVERRIDE { michael@0: nsBoxLayoutState bls(aPresContext, aRC, 0); michael@0: return mHelper.GetNondisappearingScrollbarWidth(&bls); michael@0: } michael@0: virtual nsRect GetScrolledRect() const MOZ_OVERRIDE { michael@0: return mHelper.GetScrolledRect(); michael@0: } michael@0: virtual nsRect GetScrollPortRect() const MOZ_OVERRIDE { michael@0: return mHelper.GetScrollPortRect(); michael@0: } michael@0: virtual nsPoint GetScrollPosition() const MOZ_OVERRIDE { michael@0: return mHelper.GetScrollPosition(); michael@0: } michael@0: virtual nsPoint GetLogicalScrollPosition() const MOZ_OVERRIDE { michael@0: return mHelper.GetLogicalScrollPosition(); michael@0: } michael@0: virtual nsRect GetScrollRange() const MOZ_OVERRIDE { michael@0: return mHelper.GetScrollRange(); michael@0: } michael@0: virtual nsSize GetScrollPositionClampingScrollPortSize() const MOZ_OVERRIDE { michael@0: return mHelper.GetScrollPositionClampingScrollPortSize(); michael@0: } michael@0: virtual gfxSize GetResolution() const MOZ_OVERRIDE { michael@0: return mHelper.GetResolution(); michael@0: } michael@0: virtual void SetResolution(const gfxSize& aResolution) MOZ_OVERRIDE { michael@0: return mHelper.SetResolution(aResolution); michael@0: } michael@0: virtual nsSize GetLineScrollAmount() const MOZ_OVERRIDE { michael@0: return mHelper.GetLineScrollAmount(); michael@0: } michael@0: virtual nsSize GetPageScrollAmount() const MOZ_OVERRIDE { michael@0: return mHelper.GetPageScrollAmount(); michael@0: } michael@0: /** michael@0: * @note This method might destroy the frame, pres shell and other objects. michael@0: */ michael@0: virtual void ScrollTo(nsPoint aScrollPosition, ScrollMode aMode, michael@0: const nsRect* aRange = nullptr) MOZ_OVERRIDE { michael@0: mHelper.ScrollTo(aScrollPosition, aMode, aRange); michael@0: } michael@0: /** michael@0: * @note This method might destroy the frame, pres shell and other objects. michael@0: */ michael@0: virtual void ScrollToCSSPixels(const CSSIntPoint& aScrollPosition) MOZ_OVERRIDE { michael@0: mHelper.ScrollToCSSPixels(aScrollPosition); michael@0: } michael@0: virtual void ScrollToCSSPixelsApproximate(const mozilla::CSSPoint& aScrollPosition, michael@0: nsIAtom* aOrigin = nullptr) MOZ_OVERRIDE { michael@0: mHelper.ScrollToCSSPixelsApproximate(aScrollPosition, aOrigin); michael@0: } michael@0: virtual CSSIntPoint GetScrollPositionCSSPixels() MOZ_OVERRIDE { michael@0: return mHelper.GetScrollPositionCSSPixels(); michael@0: } michael@0: /** michael@0: * @note This method might destroy the frame, pres shell and other objects. michael@0: */ michael@0: virtual void ScrollBy(nsIntPoint aDelta, ScrollUnit aUnit, ScrollMode aMode, michael@0: nsIntPoint* aOverflow, nsIAtom* aOrigin = nullptr) MOZ_OVERRIDE { michael@0: mHelper.ScrollBy(aDelta, aUnit, aMode, aOverflow, aOrigin); michael@0: } michael@0: /** michael@0: * @note This method might destroy the frame, pres shell and other objects. michael@0: */ michael@0: virtual void ScrollToRestoredPosition() MOZ_OVERRIDE { michael@0: mHelper.ScrollToRestoredPosition(); michael@0: } michael@0: virtual void AddScrollPositionListener(nsIScrollPositionListener* aListener) MOZ_OVERRIDE { michael@0: mHelper.AddScrollPositionListener(aListener); michael@0: } michael@0: virtual void RemoveScrollPositionListener(nsIScrollPositionListener* aListener) MOZ_OVERRIDE { michael@0: mHelper.RemoveScrollPositionListener(aListener); michael@0: } michael@0: /** michael@0: * @note This method might destroy the frame, pres shell and other objects. michael@0: */ michael@0: virtual void CurPosAttributeChanged(nsIContent* aChild) MOZ_OVERRIDE { michael@0: mHelper.CurPosAttributeChanged(aChild); michael@0: } michael@0: NS_IMETHOD PostScrolledAreaEventForCurrentArea() MOZ_OVERRIDE { michael@0: mHelper.PostScrolledAreaEvent(); michael@0: return NS_OK; michael@0: } michael@0: virtual bool IsScrollingActive() MOZ_OVERRIDE { michael@0: return mHelper.IsScrollingActive(); michael@0: } michael@0: virtual bool IsProcessingAsyncScroll() MOZ_OVERRIDE { michael@0: return mHelper.IsProcessingAsyncScroll(); michael@0: } michael@0: virtual void ResetScrollPositionForLayerPixelAlignment() MOZ_OVERRIDE { michael@0: mHelper.ResetScrollPositionForLayerPixelAlignment(); michael@0: } michael@0: virtual bool IsResolutionSet() const MOZ_OVERRIDE { michael@0: return mHelper.mIsResolutionSet; michael@0: } michael@0: virtual bool DidHistoryRestore() const MOZ_OVERRIDE { michael@0: return mHelper.mDidHistoryRestore; michael@0: } michael@0: virtual void ClearDidHistoryRestore() MOZ_OVERRIDE { michael@0: mHelper.mDidHistoryRestore = false; michael@0: } michael@0: virtual bool IsRectNearlyVisible(const nsRect& aRect) MOZ_OVERRIDE { michael@0: return mHelper.IsRectNearlyVisible(aRect); michael@0: } michael@0: virtual nsIAtom* OriginOfLastScroll() MOZ_OVERRIDE { michael@0: return mHelper.OriginOfLastScroll(); michael@0: } michael@0: virtual uint32_t CurrentScrollGeneration() MOZ_OVERRIDE { michael@0: return mHelper.CurrentScrollGeneration(); michael@0: } michael@0: virtual void ResetOriginIfScrollAtGeneration(uint32_t aGeneration) MOZ_OVERRIDE { michael@0: mHelper.ResetOriginIfScrollAtGeneration(aGeneration); michael@0: } michael@0: virtual bool WantAsyncScroll() const MOZ_OVERRIDE { michael@0: return mHelper.WantAsyncScroll(); michael@0: } michael@0: michael@0: // nsIStatefulFrame michael@0: NS_IMETHOD SaveState(nsPresState** aState) MOZ_OVERRIDE { michael@0: NS_ENSURE_ARG_POINTER(aState); michael@0: *aState = mHelper.SaveState(); michael@0: return NS_OK; michael@0: } michael@0: NS_IMETHOD RestoreState(nsPresState* aState) MOZ_OVERRIDE { michael@0: NS_ENSURE_ARG_POINTER(aState); michael@0: mHelper.RestoreState(aState); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /** michael@0: * Get the "type" of the frame michael@0: * michael@0: * @see nsGkAtoms::scrollFrame michael@0: */ michael@0: virtual nsIAtom* GetType() const MOZ_OVERRIDE; michael@0: michael@0: virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE michael@0: { michael@0: // Override bogus IsFrameOfType in nsBoxFrame. michael@0: if (aFlags & (nsIFrame::eReplacedContainsBlock | nsIFrame::eReplaced)) michael@0: return false; michael@0: return nsBoxFrame::IsFrameOfType(aFlags); michael@0: } michael@0: michael@0: #ifdef DEBUG_FRAME_DUMP michael@0: virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; michael@0: #endif michael@0: michael@0: protected: michael@0: nsXULScrollFrame(nsIPresShell* aShell, nsStyleContext* aContext, bool aIsRoot, michael@0: bool aClipAllDescendants); michael@0: michael@0: void ClampAndSetBounds(nsBoxLayoutState& aState, michael@0: nsRect& aRect, michael@0: nsPoint aScrollPosition, michael@0: bool aRemoveOverflowAreas = false) { michael@0: /* michael@0: * For RTL frames, restore the original scrolled position of the right michael@0: * edge, then subtract the current width to find the physical position. michael@0: */ michael@0: if (!mHelper.IsLTR()) { michael@0: aRect.x = mHelper.mScrollPort.XMost() - aScrollPosition.x - aRect.width; michael@0: } michael@0: mHelper.mScrolledFrame->SetBounds(aState, aRect, aRemoveOverflowAreas); michael@0: } michael@0: michael@0: private: michael@0: friend class mozilla::ScrollFrameHelper; michael@0: ScrollFrameHelper mHelper; michael@0: }; michael@0: michael@0: #endif /* nsGfxScrollFrame_h___ */