1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /* rendering object to wrap rendering objects that should be scrollable */
9 #ifndef nsGfxScrollFrame_h___
10 #define nsGfxScrollFrame_h___
12 #include "mozilla/Attributes.h"
13 #include "nsContainerFrame.h"
14 #include "nsIAnonymousContentCreator.h"
15 #include "nsBoxFrame.h"
16 #include "nsIScrollableFrame.h"
17 #include "nsIScrollbarMediator.h"
18 #include "nsIStatefulFrame.h"
19 #include "nsThreadUtils.h"
20 #include "nsIReflowCallback.h"
21 #include "nsBoxLayoutState.h"
22 #include "nsQueryFrame.h"
23 #include "nsExpirationTracker.h"
24 #include "TextOverflow.h"
25 #include "ScrollVelocityQueue.h"
26 #include "mozilla/ScrollTypes.h"
27 #include "mozilla/PresState.h"
28 #include "mozilla/layout/ScrollAnchorContainer.h"
33 class nsIScrollPositionListener
;
37 struct ScrollReflowInput
;
43 class ScrollbarActivity
;
46 class ScrollFrameHelper
: public nsIReflowCallback
{
48 typedef nsIFrame::Sides Sides
;
49 typedef mozilla::CSSIntPoint CSSIntPoint
;
50 typedef mozilla::layout::ScrollbarActivity ScrollbarActivity
;
51 typedef mozilla::layers::FrameMetrics FrameMetrics
;
52 typedef mozilla::layers::ScrollableLayerGuid ScrollableLayerGuid
;
53 typedef mozilla::layers::ScrollSnapInfo ScrollSnapInfo
;
54 typedef mozilla::layers::Layer Layer
;
55 typedef mozilla::layers::LayerManager LayerManager
;
56 typedef mozilla::layout::ScrollAnchorContainer ScrollAnchorContainer
;
57 using Element
= mozilla::dom::Element
;
60 class AsyncSmoothMSDScroll
;
62 ScrollFrameHelper(nsContainerFrame
* aOuter
, bool aIsRoot
);
65 mozilla::ScrollStyles
GetScrollStylesFromFrame() const;
66 mozilla::layers::OverscrollBehaviorInfo
GetOverscrollBehaviorInfo() const;
68 bool IsForTextControlWithNoScrollbars() const;
70 // If a child frame was added or removed on the scrollframe,
71 // reload our child frame list.
72 // We need this if a scrollbar frame is recreated.
73 void ReloadChildFrames();
75 nsresult
CreateAnonymousContent(
76 nsTArray
<nsIAnonymousContentCreator::ContentInfo
>& aElements
);
77 void AppendAnonymousContentTo(nsTArray
<nsIContent
*>& aElements
,
79 nsresult
FireScrollPortEvent();
80 void PostScrollEndEvent();
81 void FireScrollEndEvent();
82 void PostOverflowEvent();
83 using PostDestroyData
= nsIFrame::PostDestroyData
;
84 void Destroy(PostDestroyData
& aPostDestroyData
);
86 void BuildDisplayList(nsDisplayListBuilder
* aBuilder
,
87 const nsDisplayListSet
& aLists
);
89 // Add display items for the top-layer (which includes things like
90 // the fullscreen element, its backdrop, and text selection carets)
92 // This is a no-op for scroll frames other than the viewport's
94 // This should be called with an nsDisplayListSet that will be
95 // wrapped in the async zoom container, if we're building one.
96 // It should not be called with an ASR setter on the stack, as the
97 // top-layer items handle setting up their own ASRs.
98 nsDisplayWrapList
* MaybeCreateTopLayerItems(nsDisplayListBuilder
* aBuilder
,
101 void AppendScrollPartsTo(nsDisplayListBuilder
* aBuilder
,
102 const nsDisplayListSet
& aLists
, bool aCreateLayer
,
105 bool GetBorderRadii(const nsSize
& aFrameSize
, const nsSize
& aBorderArea
,
106 Sides aSkipSides
, nscoord aRadii
[8]) const;
109 bool ReflowFinished() final
;
110 void ReflowCallbackCanceled() final
;
113 * @note This method might destroy the frame, pres shell and other objects.
114 * Called when the 'curpos' attribute on one of the scrollbars changes.
116 void CurPosAttributeChanged(nsIContent
* aChild
, bool aDoScroll
= true);
118 void PostScrollEvent(bool aDelayed
= false);
119 void FireScrollEvent();
120 void PostScrolledAreaEvent();
121 void FireScrolledAreaEvent();
123 bool IsSmoothScrollingEnabled();
126 * @note This method might destroy the frame, pres shell and other objects.
128 void FinishReflowForScrollbar(Element
* aElement
, nscoord aMinXY
,
129 nscoord aMaxXY
, nscoord aCurPosXY
,
130 nscoord aPageIncrement
, nscoord aIncrement
);
132 * @note This method might destroy the frame, pres shell and other objects.
134 void SetScrollbarEnabled(Element
* aElement
, nscoord aMaxPos
);
136 * @note This method might destroy the frame, pres shell and other objects.
138 void SetCoordAttribute(Element
* aElement
, nsAtom
* aAtom
, nscoord aSize
);
140 nscoord
GetCoordAttribute(nsIFrame
* aFrame
, nsAtom
* aAtom
,
141 nscoord aDefaultValue
, nscoord
* aRangeStart
,
142 nscoord
* aRangeLength
);
145 * @note This method might destroy the frame, pres shell and other objects.
146 * Update scrollbar curpos attributes to reflect current scroll position
148 void UpdateScrollbarPosition();
150 nsSize
GetLayoutSize() const {
151 if (mIsUsingMinimumScaleSize
) {
154 return mScrollPort
.Size();
156 nsRect
GetScrollPortRect() const { return mScrollPort
; }
157 nsPoint
GetScrollPosition() const {
158 return mScrollPort
.TopLeft() - mScrolledFrame
->GetPosition();
161 * For LTR frames, the logical scroll position is the offset of the top left
162 * corner of the frame from the top left corner of the scroll port (same as
163 * GetScrollPosition).
164 * For RTL frames, it is the offset of the top right corner of the frame from
165 * the top right corner of the scroll port
167 nsPoint
GetLogicalScrollPosition() const {
169 pt
.x
= IsPhysicalLTR()
170 ? mScrollPort
.x
- mScrolledFrame
->GetPosition().x
171 : mScrollPort
.XMost() - mScrolledFrame
->GetRect().XMost();
172 pt
.y
= mScrollPort
.y
- mScrolledFrame
->GetPosition().y
;
175 nsRect
GetLayoutScrollRange() const;
176 // Get the scroll range assuming the viewport has size (aWidth, aHeight).
177 nsRect
GetScrollRange(nscoord aWidth
, nscoord aHeight
) const;
178 nsSize
GetVisualViewportSize() const;
179 nsPoint
GetVisualViewportOffset() const;
180 bool SetVisualViewportOffset(const nsPoint
& aOffset
, bool aRepaint
);
181 nsRect
GetVisualScrollRange() const;
182 nsRect
GetScrollRangeForUserInputEvents() const;
185 * Return the 'optimal viewing region' as a rect suitable for use by
186 * scroll anchoring. This rect is in the same coordinate space as
187 * 'GetScrollPortRect', and accounts for 'scroll-padding' as defined by:
189 * https://drafts.csswg.org/css-scroll-snap-1/#optimal-viewing-region
191 nsRect
GetVisualOptimalViewingRect() const;
194 * For LTR frames, this is the same as GetVisualViewportOffset().
195 * For RTL frames, we take the offset from the top right corner of the frame
196 * to the top right corner of the visual viewport.
198 nsPoint
GetLogicalVisualViewportOffset() const {
199 nsPoint pt
= GetVisualViewportOffset();
200 if (!IsPhysicalLTR()) {
201 pt
.x
+= GetVisualViewportSize().width
- mScrolledFrame
->GetRect().width
;
205 void ScrollSnap(ScrollMode aMode
= ScrollMode::SmoothMsd
);
206 void ScrollSnap(const nsPoint
& aDestination
,
207 ScrollMode aMode
= ScrollMode::SmoothMsd
);
209 bool HasPendingScrollRestoration() const {
210 return mRestorePos
!= nsPoint(-1, -1);
213 bool IsProcessingScrollEvent() const { return mProcessingScrollEvent
; }
216 static void AsyncScrollCallback(ScrollFrameHelper
* aInstance
,
217 mozilla::TimeStamp aTime
);
218 static void AsyncSmoothMSDScrollCallback(ScrollFrameHelper
* aInstance
,
219 mozilla::TimeDuration aDeltaTime
);
221 * @note This method might destroy the frame, pres shell and other objects.
222 * aRange is the range of allowable scroll positions around the desired
223 * aScrollPosition. Null means only aScrollPosition is allowed.
224 * This is a closed-ended range --- aRange.XMost()/aRange.YMost() are allowed.
226 void ScrollTo(nsPoint aScrollPosition
, ScrollMode aMode
,
227 ScrollOrigin aOrigin
= ScrollOrigin::NotSpecified
,
228 const nsRect
* aRange
= nullptr,
229 nsIScrollbarMediator::ScrollSnapMode aSnap
=
230 nsIScrollbarMediator::DISABLE_SNAP
);
232 * @note This method might destroy the frame, pres shell and other objects.
234 void ScrollToCSSPixels(const CSSIntPoint
& aScrollPosition
,
235 ScrollMode aMode
= ScrollMode::Instant
,
236 nsIScrollbarMediator::ScrollSnapMode aSnap
=
237 nsIScrollbarMediator::DEFAULT
,
238 ScrollOrigin aOrigin
= ScrollOrigin::NotSpecified
);
240 * @note This method might destroy the frame, pres shell and other objects.
242 void ScrollToCSSPixelsApproximate(
243 const mozilla::CSSPoint
& aScrollPosition
,
244 ScrollOrigin aOrigin
= ScrollOrigin::NotSpecified
);
246 CSSIntPoint
GetScrollPositionCSSPixels();
248 * @note This method might destroy the frame, pres shell and other objects.
250 void ScrollToImpl(nsPoint aScrollPosition
, const nsRect
& aRange
,
251 ScrollOrigin aOrigin
= ScrollOrigin::NotSpecified
);
254 * @note This method might destroy the frame, pres shell and other objects.
256 void ScrollBy(nsIntPoint aDelta
, mozilla::ScrollUnit aUnit
, ScrollMode aMode
,
257 nsIntPoint
* aOverflow
,
258 ScrollOrigin aOrigin
= ScrollOrigin::NotSpecified
,
259 nsIScrollableFrame::ScrollMomentum aMomentum
=
260 nsIScrollableFrame::NOT_MOMENTUM
,
261 nsIScrollbarMediator::ScrollSnapMode aSnap
=
262 nsIScrollbarMediator::DISABLE_SNAP
);
263 void ScrollByCSSPixels(const CSSIntPoint
& aDelta
,
264 ScrollMode aMode
= ScrollMode::Instant
,
265 ScrollOrigin aOrigin
= ScrollOrigin::NotSpecified
,
266 nsIScrollbarMediator::ScrollSnapMode aSnap
=
267 nsIScrollbarMediator::DEFAULT
);
269 * @note This method might destroy the frame, pres shell and other objects.
271 void ScrollToRestoredPosition();
273 enum class LoadingState
{ Loading
, Stopped
, Loaded
};
275 LoadingState
GetPageLoadingState();
278 * GetSnapPointForDestination determines which point to snap to after
279 * scrolling. aStartPos gives the position before scrolling and aDestination
280 * gives the position after scrolling, with no snapping. Behaviour is
281 * dependent on the value of aUnit.
282 * Returns true if a suitable snap point could be found and aDestination has
283 * been updated to a valid snapping position.
285 bool GetSnapPointForDestination(mozilla::ScrollUnit aUnit
,
286 const nsPoint
& aStartPos
,
287 nsPoint
& aDestination
);
289 nsMargin
GetScrollPadding() const;
291 nsSize
GetLineScrollAmount() const;
292 nsSize
GetPageScrollAmount() const;
294 mozilla::UniquePtr
<mozilla::PresState
> SaveState() const;
295 void RestoreState(mozilla::PresState
* aState
);
297 nsIFrame
* GetScrolledFrame() const { return mScrolledFrame
; }
298 nsIFrame
* GetScrollbarBox(bool aVertical
) const {
299 return aVertical
? mVScrollbarBox
: mHScrollbarBox
;
302 void AddScrollPositionListener(nsIScrollPositionListener
* aListener
) {
303 mListeners
.AppendElement(aListener
);
305 void RemoveScrollPositionListener(nsIScrollPositionListener
* aListener
) {
306 mListeners
.RemoveElement(aListener
);
309 static void SetScrollbarVisibility(nsIFrame
* aScrollbar
, bool aVisible
);
312 * GetScrolledRect is designed to encapsulate deciding which
313 * directions of overflow should be reachable by scrolling and which
314 * should not. Callers should NOT depend on it having any particular
315 * behavior (although nsXULScrollFrame currently does).
317 * This should only be called when the scrolled frame has been
318 * reflowed with the scroll port size given in mScrollPort.
320 * Currently it allows scrolling down and to the right for
321 * nsHTMLScrollFrames with LTR directionality and for all
322 * nsXULScrollFrames, and allows scrolling down and to the left for
323 * nsHTMLScrollFrames with RTL directionality.
325 nsRect
GetScrolledRect() const;
328 * GetUnsnappedScrolledRectInternal is designed to encapsulate deciding which
329 * directions of overflow should be reachable by scrolling and which
330 * should not. Callers should NOT depend on it having any particular
331 * behavior (although nsXULScrollFrame currently does).
333 * Currently it allows scrolling down and to the right for
334 * nsHTMLScrollFrames with LTR directionality and for all
335 * nsXULScrollFrames, and allows scrolling down and to the left for
336 * nsHTMLScrollFrames with RTL directionality.
338 nsRect
GetUnsnappedScrolledRectInternal(const nsRect
& aScrolledOverflowArea
,
339 const nsSize
& aScrollPortSize
) const;
341 layers::ScrollDirections
GetAvailableScrollingDirectionsForUserInputEvents()
344 layers::ScrollDirections
GetScrollbarVisibility() const {
345 layers::ScrollDirections result
;
346 if (mHasHorizontalScrollbar
) {
347 result
+= layers::ScrollDirection::eHorizontal
;
349 if (mHasVerticalScrollbar
) {
350 result
+= layers::ScrollDirection::eVertical
;
354 nsMargin
GetActualScrollbarSizes(
355 nsIScrollableFrame::ScrollbarSizesOptions aOptions
=
356 nsIScrollableFrame::ScrollbarSizesOptions::NONE
) const;
357 nsMargin
GetDesiredScrollbarSizes(nsBoxLayoutState
* aState
);
358 nscoord
GetNondisappearingScrollbarWidth(nsBoxLayoutState
* aState
,
359 mozilla::WritingMode aVerticalWM
);
360 bool IsPhysicalLTR() const {
361 return mOuter
->GetWritingMode().IsPhysicalLTR();
363 bool IsBidiLTR() const { return mOuter
->GetWritingMode().IsBidiLTR(); }
366 // NOTE: Use GetScrollStylesFromFrame() if you want to know `overflow`
367 // and `overflow-behavior` properties.
368 nsIFrame
* GetFrameForStyle() const;
370 // This is the for the old unspecced scroll snap implementation.
371 ScrollSnapInfo
ComputeOldScrollSnapInfo() const;
372 // This is the for the scroll snap v1 implementation.
373 ScrollSnapInfo
ComputeScrollSnapInfo(
374 const Maybe
<nsPoint
>& aDestination
) const;
376 bool NeedsScrollSnap() const;
379 bool IsScrollbarOnRight() const;
380 bool IsScrollingActive(nsDisplayListBuilder
* aBuilder
) const;
381 bool IsScrollingActiveNotMinimalDisplayPort(
382 nsDisplayListBuilder
* aBuilder
) const;
383 bool IsMaybeAsynchronouslyScrolled() const {
384 // If this is true, then we'll build an ASR, and that's what we want
386 return mWillBuildScrollableLayer
;
388 bool IsMaybeScrollingActive() const;
389 void ResetScrollPositionForLayerPixelAlignment() {
390 mScrollPosForLayerPixelAlignment
= GetScrollPosition();
393 bool ComputeCustomOverflow(mozilla::OverflowAreas
& aOverflowAreas
);
397 void UpdatePrevScrolledRect();
399 bool IsRectNearlyVisible(const nsRect
& aRect
) const;
400 nsRect
ExpandRectToNearlyVisible(const nsRect
& aRect
) const;
402 // adjust the scrollbar rectangle aRect to account for any visible resizer.
403 // aHasResizer specifies if there is a content resizer, however this method
404 // will also check if a widget resizer is present as well.
405 void AdjustScrollbarRectForResizer(
406 nsIFrame
* aFrame
, nsPresContext
* aPresContext
, nsRect
& aRect
,
407 bool aHasResizer
, mozilla::layers::ScrollDirection aDirection
);
408 // returns true if a resizer should be visible
409 bool HasResizer() { return mResizerBox
; }
410 void LayoutScrollbars(nsBoxLayoutState
& aState
, const nsRect
& aContentArea
,
411 const nsRect
& aOldScrollArea
);
413 void MarkScrollbarsDirtyForReflow() const;
414 void InvalidateVerticalScrollbar() const;
416 bool IsAlwaysActive() const;
417 void MarkEverScrolled();
418 void MarkRecentlyScrolled();
419 void MarkNotRecentlyScrolled();
420 nsExpirationState
* GetExpirationState() { return &mActivityExpirationState
; }
422 void SetTransformingByAPZ(bool aTransforming
) {
423 if (mTransformingByAPZ
&& !aTransforming
) {
424 PostScrollEndEvent();
426 mTransformingByAPZ
= aTransforming
;
427 if (!mozilla::css::TextOverflow::HasClippedTextOverflow(mOuter
) ||
428 mozilla::css::TextOverflow::HasBlockEllipsis(mScrolledFrame
)) {
429 // If the block has some overflow marker stuff we should kick off a paint
430 // because we have special behaviour for it when APZ scrolling is active.
431 mOuter
->SchedulePaint();
434 bool IsTransformingByAPZ() const { return mTransformingByAPZ
; }
435 void SetScrollableByAPZ(bool aScrollable
);
436 void SetZoomableByAPZ(bool aZoomable
);
437 void SetHasOutOfFlowContentInsideFilter();
439 bool UsesOverlayScrollbars() const;
441 // In the case where |aDestination| is given, elements which are entirely out
442 // of view when the scroll position is moved to |aDestination| are not going
443 // to be used for snap positions.
444 ScrollSnapInfo
GetScrollSnapInfo(
445 const mozilla::Maybe
<nsPoint
>& aDestination
) const;
447 static bool ShouldActivateAllScrollFrames();
448 nsRect
RestrictToRootDisplayPort(const nsRect
& aDisplayportBase
);
449 bool DecideScrollableLayer(nsDisplayListBuilder
* aBuilder
,
450 nsRect
* aVisibleRect
, nsRect
* aDirtyRect
,
452 bool* aDirtyRectHasBeenOverriden
= nullptr);
453 void NotifyApzTransaction();
454 void NotifyApproximateFrameVisibilityUpdate(bool aIgnoreDisplayPort
);
455 bool GetDisplayPortAtLastApproximateFrameVisibilityUpdate(
456 nsRect
* aDisplayPort
);
458 bool AllowDisplayPortExpiration();
459 void TriggerDisplayPortExpiration();
460 void ResetDisplayPortExpiryTimer();
462 void ScheduleSyntheticMouseMove();
463 static void ScrollActivityCallback(nsITimer
* aTimer
, void* anInstance
);
465 void HandleScrollbarStyleSwitching();
467 ScrollOrigin
LastScrollOrigin() const { return mLastScrollOrigin
; }
468 bool IsApzAnimationInProgress() const { return mApzAnimationInProgress
; }
469 ScrollGeneration
CurrentScrollGeneration() const { return mScrollGeneration
; }
470 nsPoint
LastScrollDestination() const { return mDestination
; }
471 nsTArray
<ScrollPositionUpdate
> GetScrollUpdates() const;
472 bool HasScrollUpdates() const { return !mScrollUpdates
.IsEmpty(); }
474 bool IsLastScrollUpdateAnimating() const;
475 using IncludeApzAnimation
= nsIScrollableFrame::IncludeApzAnimation
;
476 bool IsScrollAnimating(IncludeApzAnimation
= IncludeApzAnimation::Yes
) const;
478 void ResetScrollInfoIfNeeded(const ScrollGeneration
& aGeneration
,
479 bool aApzAnimationInProgress
);
480 bool WantAsyncScroll() const;
481 Maybe
<mozilla::layers::ScrollMetadata
> ComputeScrollMetadata(
482 LayerManager
* aLayerManager
, const nsIFrame
* aContainerReferenceFrame
,
483 const Maybe
<ContainerLayerParameters
>& aParameters
,
484 const mozilla::DisplayItemClip
* aClip
) const;
485 void ClipLayerToDisplayPort(
486 Layer
* aLayer
, const mozilla::DisplayItemClip
* aClip
,
487 const ContainerLayerParameters
& aParameters
) const;
489 // nsIScrollbarMediator
490 void ScrollByPage(nsScrollbarFrame
* aScrollbar
, int32_t aDirection
,
491 nsIScrollbarMediator::ScrollSnapMode aSnap
=
492 nsIScrollbarMediator::DISABLE_SNAP
);
493 void ScrollByWhole(nsScrollbarFrame
* aScrollbar
, int32_t aDirection
,
494 nsIScrollbarMediator::ScrollSnapMode aSnap
=
495 nsIScrollbarMediator::DISABLE_SNAP
);
496 void ScrollByLine(nsScrollbarFrame
* aScrollbar
, int32_t aDirection
,
497 nsIScrollbarMediator::ScrollSnapMode aSnap
=
498 nsIScrollbarMediator::DISABLE_SNAP
);
499 void ScrollByUnit(nsScrollbarFrame
* aScrollbar
, ScrollMode aMode
,
500 int32_t aDirection
, ScrollUnit aUnit
,
501 nsIScrollbarMediator::ScrollSnapMode aSnap
=
502 nsIScrollbarMediator::DISABLE_SNAP
);
503 void RepeatButtonScroll(nsScrollbarFrame
* aScrollbar
);
504 void ThumbMoved(nsScrollbarFrame
* aScrollbar
, nscoord aOldPos
,
506 void ScrollbarReleased(nsScrollbarFrame
* aScrollbar
);
507 bool ShouldSuppressScrollbarRepaints() const {
508 return mSuppressScrollbarRepaints
;
511 bool DragScroll(WidgetEvent
* aEvent
);
513 void AsyncScrollbarDragInitiated(uint64_t aDragBlockId
,
514 mozilla::layers::ScrollDirection aDirection
);
515 void AsyncScrollbarDragRejected();
517 bool IsRootScrollFrameOfDocument() const { return mIsRoot
; }
519 bool SmoothScrollVisual(
520 const nsPoint
& aVisualViewportOffset
,
521 mozilla::layers::FrameMetrics::ScrollOffsetUpdateType aUpdateType
);
523 bool IsSmoothScroll(mozilla::dom::ScrollBehavior aBehavior
) const;
525 // Update minimum-scale size. The minimum-scale size will be set/used only
526 // if there is overflow-x:hidden region.
527 void UpdateMinimumScaleSize(const nsRect
& aScrollableOverflow
,
528 const nsSize
& aICBSize
);
530 // Return the scroll frame's "true outer size".
531 // This is mOuter->GetSize(), except when mOuter has been sized to reflect
532 // a virtual (layout) viewport in which case this returns the outer size
533 // used to size the physical (visual) viewport.
534 nsSize
TrueOuterSize(nsDisplayListBuilder
* aBuilder
) const;
536 already_AddRefed
<Element
> MakeScrollbar(dom::NodeInfo
* aNodeInfo
,
538 AnonymousContentKey
& aKey
);
540 void AppendScrollUpdate(const ScrollPositionUpdate
& aUpdate
);
542 // owning references to the nsIAnonymousContentCreator-built content
543 nsCOMPtr
<Element
> mHScrollbarContent
;
544 nsCOMPtr
<Element
> mVScrollbarContent
;
545 nsCOMPtr
<Element
> mScrollCornerContent
;
546 nsCOMPtr
<Element
> mResizerContent
;
549 class ScrollEndEvent
;
550 class AsyncScrollPortEvent
;
551 class ScrolledAreaEvent
;
553 RefPtr
<ScrollEvent
> mScrollEvent
;
554 RefPtr
<ScrollEndEvent
> mScrollEndEvent
;
555 nsRevocableEventPtr
<AsyncScrollPortEvent
> mAsyncScrollPortEvent
;
556 nsRevocableEventPtr
<ScrolledAreaEvent
> mScrolledAreaEvent
;
557 nsIFrame
* mHScrollbarBox
;
558 nsIFrame
* mVScrollbarBox
;
559 nsIFrame
* mScrolledFrame
;
560 nsIFrame
* mScrollCornerBox
;
561 nsIFrame
* mResizerBox
;
562 nsContainerFrame
* mOuter
;
563 const nsIFrame
* mReferenceFrameDuringPainting
;
564 RefPtr
<AsyncScroll
> mAsyncScroll
;
565 RefPtr
<AsyncSmoothMSDScroll
> mAsyncSmoothMSDScroll
;
566 RefPtr
<ScrollbarActivity
> mScrollbarActivity
;
567 nsTArray
<nsIScrollPositionListener
*> mListeners
;
568 ScrollOrigin mLastScrollOrigin
;
569 Maybe
<nsPoint
> mApzSmoothScrollDestination
;
570 ScrollGeneration mScrollGeneration
;
572 nsTArray
<ScrollPositionUpdate
> mScrollUpdates
;
574 // NOTE: On mobile this value might be factoring into overflow:hidden region
575 // in the case of the top level document.
577 nsSize mMinimumScaleSize
;
579 // Stores the ICB size for the root document if this frame is using the
580 // minimum scale size for |mScrollPort|.
583 // Where we're currently scrolling to, if we're scrolling asynchronously.
584 // If we're not in the middle of an asynchronous scroll then this is
585 // just the current scroll position. ScrollBy will choose its
586 // destination based on this value.
587 nsPoint mDestination
;
589 // A goal position to try to scroll to as content loads. As long as mLastPos
590 // matches the current logical scroll position, we try to scroll to
591 // mRestorePos after every reflow --- because after each time content is
592 // loaded/added to the scrollable element, there will be a reflow.
593 // Note that for frames where layout and visual viewport aren't one and the
594 // same thing, this scroll position will be the logical scroll position of
595 // the *visual* viewport, as its position will be more relevant to the user.
597 // The last logical position we scrolled to while trying to restore
598 // mRestorePos, or 0,0 when this is a new frame. Set to -1,-1 once we've
599 // scrolled for any reason other than trying to restore mRestorePos.
600 // Just as with mRestorePos, this position will be the logical position of
601 // the *visual* viewport where available.
604 // The latest scroll position we've sent or received from APZ. This
605 // represents the main thread's best knowledge of the APZ scroll position,
606 // and is used to calculate relative scroll offset updates.
607 nsPoint mApzScrollPos
;
609 nsExpirationState mActivityExpirationState
;
611 nsCOMPtr
<nsITimer
> mScrollActivityTimer
;
612 nsPoint mScrollPosForLayerPixelAlignment
;
614 // The scroll position where we last updated frame visibility.
615 nsPoint mLastUpdateFramesPos
;
616 nsRect mDisplayPortAtLastFrameUpdate
;
618 nsRect mPrevScrolledRect
;
620 ScrollableLayerGuid::ViewID mScrollParentID
;
622 // Timer to remove the displayport some time after scrolling has stopped
623 nsCOMPtr
<nsITimer
> mDisplayPortExpiryTimer
;
625 ScrollAnchorContainer mAnchor
;
627 bool mAllowScrollOriginDowngrade
: 1;
628 bool mHadDisplayPortAtLastFrameUpdate
: 1;
629 bool mNeverHasVerticalScrollbar
: 1;
630 bool mNeverHasHorizontalScrollbar
: 1;
631 bool mHasVerticalScrollbar
: 1;
632 bool mHasHorizontalScrollbar
: 1;
633 // If mHas(Vertical|Horizontal)Scrollbar is true then
634 // mOnlyNeed(V|H)ScrollbarToScrollVVInsideLV indicates if the only reason we
635 // need that scrollbar is to scroll the visual viewport inside the layout
636 // viewport. These scrollbars are special in that even if they are layout
637 // scrollbars they do not take up any layout space.
638 bool mOnlyNeedVScrollbarToScrollVVInsideLV
: 1;
639 bool mOnlyNeedHScrollbarToScrollVVInsideLV
: 1;
640 bool mFrameIsUpdatingScrollbar
: 1;
641 bool mDidHistoryRestore
: 1;
642 // Is this the scrollframe for the document's viewport?
644 // True if we should clip all descendants, false if we should only clip
645 // descendants for which we are the containing block.
646 bool mClipAllDescendants
: 1;
647 // If true, don't try to layout the scrollbars in Reflow(). This can be
648 // useful if multiple passes are involved, because we don't want to place the
649 // scrollbars at the wrong size.
650 bool mSuppressScrollbarUpdate
: 1;
651 // If true, we skipped a scrollbar layout due to mSuppressScrollbarUpdate
652 // being set at some point. That means we should lay out scrollbars even if
653 // it might not strictly be needed next time mSuppressScrollbarUpdate is
655 bool mSkippedScrollbarLayout
: 1;
657 bool mHadNonInitialReflow
: 1;
658 // Initially true; first call to ReflowFinished() sets it to false.
659 bool mFirstReflow
: 1;
660 // State used only by PostScrollEvents so we know
661 // which overflow states have changed.
662 bool mHorizontalOverflow
: 1;
663 bool mVerticalOverflow
: 1;
664 bool mPostedReflowCallback
: 1;
665 bool mMayHaveDirtyFixedChildren
: 1;
666 // If true, need to actually update our scrollbar attributes in the
668 bool mUpdateScrollbarAttributes
: 1;
669 // If true, we should be prepared to scroll using this scrollframe
670 // by placing descendant content into its own layer(s)
671 bool mHasBeenScrolledRecently
: 1;
673 // If true, the scroll frame should always be active because we always build
674 // a scrollable layer. Used for asynchronous scrolling.
675 bool mWillBuildScrollableLayer
: 1;
677 // If true, the scroll frame is an ancestor of other "active" scrolling
678 // frames, where "active" means has a non-minimal display port if
679 // ShouldActivateAllScrollFrames is true, or has a display port if
680 // ShouldActivateAllScrollFrames is false. And this means that we shouldn't
681 // expire the display port (if ShouldActivateAllScrollFrames is true then
682 // expiring a display port means making it minimal, otherwise it means
683 // removing the display port). If those descendant scrollframes have their
684 // display ports removed or made minimal, then we expire our display port.
685 bool mIsParentToActiveScrollFrames
: 1;
687 // If true, add clipping in ScrollFrameHelper::ClipLayerToDisplayPort.
688 // XXX this flag needs some auditing and better documentation, bug 1646686.
689 bool mAddClipRectToLayer
: 1;
691 // True if this frame has been scrolled at least once
692 bool mHasBeenScrolled
: 1;
694 // True if the events synthesized by OSX to produce momentum scrolling should
695 // be ignored. Reset when the next real, non-synthesized scroll event occurs.
696 bool mIgnoreMomentumScroll
: 1;
698 // True if the APZ is in the process of async-transforming this scrollframe,
699 // (as best as we can tell on the main thread, anyway).
700 bool mTransformingByAPZ
: 1;
702 // True if APZ can scroll this frame asynchronously (i.e. it has an APZC
703 // set up for this frame and it's not a scrollinfo layer).
704 bool mScrollableByAPZ
: 1;
706 // True if the APZ is allowed to zoom this scrollframe.
707 bool mZoomableByAPZ
: 1;
709 // True if the scroll frame contains out-of-flow content and is inside
711 bool mHasOutOfFlowContentInsideFilter
: 1;
713 // True if we don't want the scrollbar to repaint itself right now.
714 bool mSuppressScrollbarRepaints
: 1;
716 // True if we are using the minimum scale size instead of ICB for scroll port.
717 bool mIsUsingMinimumScaleSize
: 1;
719 // True if the minimum scale size has been changed since the last reflow.
720 bool mMinimumScaleSizeChanged
: 1;
722 // True if we're processing an scroll event.
723 bool mProcessingScrollEvent
: 1;
725 // Whether an APZ animation is in progress. Note that this is only set to true
726 // when repainted via APZ, which means that there may be a request for an APZ
727 // animation in flight for example, while this is still false. In order to
728 // answer "is an APZ animation in the process of starting or in progress" you
729 // need to check mScrollUpdates, mApzAnimationRequested, and this bit.
730 bool mApzAnimationInProgress
: 1;
731 // This is true from the time a scroll animation is requested of APZ to the
732 // time that APZ responds with an up-to-date repaint request. More precisely,
733 // this is flipped to true if a repaint request is dispatched to APZ where
734 // the most recent scroll request is a smooth scroll, and it is cleared when
735 // mApzAnimationInProgress is updated.
736 bool mApzAnimationRequested
: 1;
738 // Whether we need to reclamp the visual viewport offset in ReflowFinished.
739 bool mReclampVVOffsetInReflowFinished
: 1;
741 mozilla::layout::ScrollVelocityQueue mVelocityQueue
;
744 class AutoScrollbarRepaintSuppression
;
745 friend class AutoScrollbarRepaintSuppression
;
746 class AutoScrollbarRepaintSuppression
{
748 AutoScrollbarRepaintSuppression(ScrollFrameHelper
* aHelper
,
749 AutoWeakFrame
& aWeakOuter
, bool aSuppress
)
751 mWeakOuter(aWeakOuter
),
752 mOldSuppressValue(aHelper
->mSuppressScrollbarRepaints
) {
753 mHelper
->mSuppressScrollbarRepaints
= aSuppress
;
756 ~AutoScrollbarRepaintSuppression() {
757 if (mWeakOuter
.IsAlive()) {
758 mHelper
->mSuppressScrollbarRepaints
= mOldSuppressValue
;
763 ScrollFrameHelper
* mHelper
;
764 AutoWeakFrame
& mWeakOuter
;
765 bool mOldSuppressValue
;
769 * @note This method might destroy the frame, pres shell and other objects.
771 void ScrollToWithOrigin(nsPoint aScrollPosition
, ScrollMode aMode
,
772 ScrollOrigin aOrigin
, const nsRect
* aRange
,
773 nsIScrollbarMediator::ScrollSnapMode aSnap
=
774 nsIScrollbarMediator::DISABLE_SNAP
);
776 void CompleteAsyncScroll(const nsRect
& aRange
,
777 ScrollOrigin aOrigin
= ScrollOrigin::NotSpecified
);
779 bool HasPerspective() const { return mOuter
->ChildrenHavePerspective(); }
780 bool HasBgAttachmentLocal() const;
781 mozilla::StyleDirection
GetScrolledFrameDir() const;
783 // Ask APZ to smooth scroll to |aDestination|.
784 // This method does not clamp the destination; callers should clamp it to
785 // either the layout or the visual scroll range (APZ will happily smooth
786 // scroll to either).
787 void ApzSmoothScrollTo(const nsPoint
& aDestination
, ScrollOrigin aOrigin
);
789 // Removes any RefreshDriver observers we might have registered.
790 void RemoveObservers();
793 } // namespace mozilla
796 * The scroll frame creates and manages the scrolling view
798 * It only supports having a single child frame that typically is an area
799 * frame, but doesn't have to be. The child frame must have a view, though
801 * Scroll frames don't support incremental changes, i.e. you can't replace
802 * or remove the scrolled frame
804 class nsHTMLScrollFrame
: public nsContainerFrame
,
805 public nsIScrollableFrame
,
806 public nsIAnonymousContentCreator
,
807 public nsIStatefulFrame
{
809 typedef mozilla::ScrollFrameHelper ScrollFrameHelper
;
810 typedef mozilla::CSSIntPoint CSSIntPoint
;
811 typedef mozilla::ScrollReflowInput ScrollReflowInput
;
812 typedef mozilla::layout::ScrollAnchorContainer ScrollAnchorContainer
;
813 friend nsHTMLScrollFrame
* NS_NewHTMLScrollFrame(
814 mozilla::PresShell
* aPresShell
, ComputedStyle
* aStyle
, bool aIsRoot
);
817 NS_DECL_FRAMEARENA_HELPERS(nsHTMLScrollFrame
)
819 void BuildDisplayList(nsDisplayListBuilder
* aBuilder
,
820 const nsDisplayListSet
& aLists
) override
{
821 mHelper
.BuildDisplayList(aBuilder
, aLists
);
824 bool TryLayout(ScrollReflowInput
* aState
, ReflowOutput
* aKidMetrics
,
825 bool aAssumeVScroll
, bool aAssumeHScroll
, bool aForce
);
826 bool ScrolledContentDependsOnHeight(ScrollReflowInput
* aState
);
827 void ReflowScrolledFrame(ScrollReflowInput
* aState
, bool aAssumeHScroll
,
828 bool aAssumeVScroll
, ReflowOutput
* aMetrics
);
829 void ReflowContents(ScrollReflowInput
* aState
,
830 const ReflowOutput
& aDesiredSize
);
831 void PlaceScrollArea(ScrollReflowInput
& aState
,
832 const nsPoint
& aScrollPosition
);
833 nscoord
GetIntrinsicVScrollbarWidth(gfxContext
* aRenderingContext
);
835 bool GetBorderRadii(const nsSize
& aFrameSize
, const nsSize
& aBorderArea
,
836 Sides aSkipSides
, nscoord aRadii
[8]) const final
{
837 return mHelper
.GetBorderRadii(aFrameSize
, aBorderArea
, aSkipSides
, aRadii
);
840 nscoord
GetMinISize(gfxContext
* aRenderingContext
) override
;
841 nscoord
GetPrefISize(gfxContext
* aRenderingContext
) override
;
842 nsresult
GetXULPadding(nsMargin
& aPadding
) final
;
843 bool IsXULCollapsed() final
;
845 void Reflow(nsPresContext
* aPresContext
, ReflowOutput
& aDesiredSize
,
846 const ReflowInput
& aReflowInput
,
847 nsReflowStatus
& aStatus
) override
;
848 void DidReflow(nsPresContext
* aPresContext
,
849 const ReflowInput
* aReflowInput
) override
;
851 bool ComputeCustomOverflow(mozilla::OverflowAreas
& aOverflowAreas
) final
{
852 return mHelper
.ComputeCustomOverflow(aOverflowAreas
);
855 nscoord
GetLogicalBaseline(mozilla::WritingMode aWritingMode
) const final
;
857 bool GetVerticalAlignBaseline(mozilla::WritingMode aWM
,
858 nscoord
* aBaseline
) const final
{
859 NS_ASSERTION(!aWM
.IsOrthogonalTo(GetWritingMode()),
860 "You should only call this on frames with a WM that's "
862 *aBaseline
= GetLogicalBaseline(aWM
);
866 // Recomputes the scrollable overflow area we store in the helper to take
867 // children that are affected by perpsective set on the outer frame and scroll
868 // at different rates.
869 void AdjustForPerspective(nsRect
& aScrollableOverflow
);
871 // Called to set the child frames. We typically have three: the scroll area,
872 // the vertical scrollbar, and the horizontal scrollbar.
873 void SetInitialChildList(ChildListID aListID
,
874 nsFrameList
& aChildList
) override
;
875 void AppendFrames(ChildListID aListID
, nsFrameList
& aFrameList
) final
;
876 void InsertFrames(ChildListID aListID
, nsIFrame
* aPrevFrame
,
877 const nsLineList::iterator
* aPrevFrameLine
,
878 nsFrameList
& aFrameList
) final
;
879 void RemoveFrame(ChildListID aListID
, nsIFrame
* aOldFrame
) final
;
881 void DestroyFrom(nsIFrame
* aDestructRoot
, PostDestroyData
&) override
;
883 nsIScrollableFrame
* GetScrollTargetFrame() const final
{
884 return const_cast<nsHTMLScrollFrame
*>(this);
887 nsContainerFrame
* GetContentInsertionFrame() override
{
888 return mHelper
.GetScrolledFrame()->GetContentInsertionFrame();
891 bool DoesClipChildrenInBothAxes() final
{ return true; }
893 nsPoint
GetPositionOfChildIgnoringScrolling(const nsIFrame
* aChild
) final
{
894 nsPoint pt
= aChild
->GetPosition();
895 if (aChild
== mHelper
.GetScrolledFrame()) pt
+= GetScrollPosition();
899 // nsIAnonymousContentCreator
900 nsresult
CreateAnonymousContent(nsTArray
<ContentInfo
>&) final
;
901 void AppendAnonymousContentTo(nsTArray
<nsIContent
*>&, uint32_t aFilter
) final
;
903 // nsIScrollableFrame
904 nsIFrame
* GetScrolledFrame() const final
{
905 return mHelper
.GetScrolledFrame();
907 mozilla::ScrollStyles
GetScrollStyles() const override
{
908 return mHelper
.GetScrollStylesFromFrame();
910 bool IsForTextControlWithNoScrollbars() const final
{
911 return mHelper
.IsForTextControlWithNoScrollbars();
913 mozilla::layers::OverscrollBehaviorInfo
GetOverscrollBehaviorInfo()
915 return mHelper
.GetOverscrollBehaviorInfo();
917 mozilla::layers::ScrollDirections
918 GetAvailableScrollingDirectionsForUserInputEvents() const final
{
919 return mHelper
.GetAvailableScrollingDirectionsForUserInputEvents();
921 mozilla::layers::ScrollDirections
GetScrollbarVisibility() const final
{
922 return mHelper
.GetScrollbarVisibility();
924 nsMargin
GetActualScrollbarSizes(
925 nsIScrollableFrame::ScrollbarSizesOptions aOptions
=
926 nsIScrollableFrame::ScrollbarSizesOptions::NONE
) const final
{
927 return mHelper
.GetActualScrollbarSizes(aOptions
);
929 nsMargin
GetDesiredScrollbarSizes(nsBoxLayoutState
* aState
) final
{
930 return mHelper
.GetDesiredScrollbarSizes(aState
);
932 nsMargin
GetDesiredScrollbarSizes(nsPresContext
* aPresContext
,
933 gfxContext
* aRC
) final
{
934 nsBoxLayoutState
bls(aPresContext
, aRC
, 0);
935 return GetDesiredScrollbarSizes(&bls
);
937 nscoord
GetNondisappearingScrollbarWidth(nsPresContext
* aPresContext
,
939 mozilla::WritingMode aWM
) final
{
940 nsBoxLayoutState
bls(aPresContext
, aRC
, 0);
941 return mHelper
.GetNondisappearingScrollbarWidth(&bls
, aWM
);
943 nsSize
GetLayoutSize() const final
{ return mHelper
.GetLayoutSize(); }
944 nsRect
GetScrolledRect() const final
{ return mHelper
.GetScrolledRect(); }
945 nsRect
GetScrollPortRect() const final
{ return mHelper
.GetScrollPortRect(); }
946 nsPoint
GetScrollPosition() const final
{
947 return mHelper
.GetScrollPosition();
949 nsPoint
GetLogicalScrollPosition() const final
{
950 return mHelper
.GetLogicalScrollPosition();
952 nsRect
GetScrollRange() const final
{ return mHelper
.GetLayoutScrollRange(); }
953 nsSize
GetVisualViewportSize() const final
{
954 return mHelper
.GetVisualViewportSize();
956 nsPoint
GetVisualViewportOffset() const final
{
957 return mHelper
.GetVisualViewportOffset();
959 bool SetVisualViewportOffset(const nsPoint
& aOffset
, bool aRepaint
) final
{
960 return mHelper
.SetVisualViewportOffset(aOffset
, aRepaint
);
962 nsRect
GetVisualScrollRange() const final
{
963 return mHelper
.GetVisualScrollRange();
965 nsRect
GetScrollRangeForUserInputEvents() const final
{
966 return mHelper
.GetScrollRangeForUserInputEvents();
968 nsSize
GetLineScrollAmount() const final
{
969 return mHelper
.GetLineScrollAmount();
971 nsSize
GetPageScrollAmount() const final
{
972 return mHelper
.GetPageScrollAmount();
974 nsMargin
GetScrollPadding() const final
{ return mHelper
.GetScrollPadding(); }
976 * @note This method might destroy the frame, pres shell and other objects.
978 void ScrollTo(nsPoint aScrollPosition
, ScrollMode aMode
,
979 const nsRect
* aRange
= nullptr,
980 nsIScrollbarMediator::ScrollSnapMode aSnap
=
981 nsIScrollbarMediator::DISABLE_SNAP
) final
{
982 mHelper
.ScrollTo(aScrollPosition
, aMode
, ScrollOrigin::Other
, aRange
,
986 * @note This method might destroy the frame, pres shell and other objects.
988 void ScrollToCSSPixels(
989 const CSSIntPoint
& aScrollPosition
,
990 ScrollMode aMode
= ScrollMode::Instant
,
991 nsIScrollbarMediator::ScrollSnapMode aSnap
=
992 nsIScrollbarMediator::DEFAULT
,
993 ScrollOrigin aOrigin
= ScrollOrigin::NotSpecified
) final
{
994 mHelper
.ScrollToCSSPixels(aScrollPosition
, aMode
, aSnap
, aOrigin
);
996 void ScrollToCSSPixelsApproximate(
997 const mozilla::CSSPoint
& aScrollPosition
,
998 ScrollOrigin aOrigin
= ScrollOrigin::NotSpecified
) final
{
999 mHelper
.ScrollToCSSPixelsApproximate(aScrollPosition
, aOrigin
);
1002 * @note This method might destroy the frame, pres shell and other objects.
1004 CSSIntPoint
GetScrollPositionCSSPixels() final
{
1005 return mHelper
.GetScrollPositionCSSPixels();
1008 * @note This method might destroy the frame, pres shell and other objects.
1010 void ScrollBy(nsIntPoint aDelta
, mozilla::ScrollUnit aUnit
, ScrollMode aMode
,
1011 nsIntPoint
* aOverflow
,
1012 ScrollOrigin aOrigin
= ScrollOrigin::NotSpecified
,
1013 nsIScrollableFrame::ScrollMomentum aMomentum
=
1014 nsIScrollableFrame::NOT_MOMENTUM
,
1015 nsIScrollbarMediator::ScrollSnapMode aSnap
=
1016 nsIScrollbarMediator::DISABLE_SNAP
) final
{
1017 mHelper
.ScrollBy(aDelta
, aUnit
, aMode
, aOverflow
, aOrigin
, aMomentum
,
1020 void ScrollByCSSPixels(const CSSIntPoint
& aDelta
,
1021 ScrollMode aMode
= ScrollMode::Instant
,
1022 ScrollOrigin aOrigin
= ScrollOrigin::NotSpecified
,
1023 nsIScrollbarMediator::ScrollSnapMode aSnap
=
1024 nsIScrollbarMediator::DEFAULT
) final
{
1025 mHelper
.ScrollByCSSPixels(aDelta
, aMode
, aOrigin
, aSnap
);
1027 void ScrollSnap() final
{ mHelper
.ScrollSnap(); }
1029 * @note This method might destroy the frame, pres shell and other objects.
1031 void ScrollToRestoredPosition() final
{ mHelper
.ScrollToRestoredPosition(); }
1032 void AddScrollPositionListener(nsIScrollPositionListener
* aListener
) final
{
1033 mHelper
.AddScrollPositionListener(aListener
);
1035 void RemoveScrollPositionListener(
1036 nsIScrollPositionListener
* aListener
) final
{
1037 mHelper
.RemoveScrollPositionListener(aListener
);
1040 * @note This method might destroy the frame, pres shell and other objects.
1042 void CurPosAttributeChanged(nsIContent
* aChild
) final
{
1043 mHelper
.CurPosAttributeChanged(aChild
);
1045 NS_IMETHOD
PostScrolledAreaEventForCurrentArea() final
{
1046 mHelper
.PostScrolledAreaEvent();
1049 bool IsScrollingActive(nsDisplayListBuilder
* aBuilder
) final
{
1050 return mHelper
.IsScrollingActive(aBuilder
);
1052 bool IsScrollingActiveNotMinimalDisplayPort(
1053 nsDisplayListBuilder
* aBuilder
) final
{
1054 return mHelper
.IsScrollingActiveNotMinimalDisplayPort(aBuilder
);
1056 bool IsMaybeScrollingActive() const final
{
1057 return mHelper
.IsMaybeScrollingActive();
1059 bool IsMaybeAsynchronouslyScrolled() final
{
1060 return mHelper
.IsMaybeAsynchronouslyScrolled();
1062 void ResetScrollPositionForLayerPixelAlignment() final
{
1063 mHelper
.ResetScrollPositionForLayerPixelAlignment();
1065 bool DidHistoryRestore() const final
{ return mHelper
.mDidHistoryRestore
; }
1066 void ClearDidHistoryRestore() final
{ mHelper
.mDidHistoryRestore
= false; }
1067 void MarkEverScrolled() final
{ mHelper
.MarkEverScrolled(); }
1068 bool IsRectNearlyVisible(const nsRect
& aRect
) final
{
1069 return mHelper
.IsRectNearlyVisible(aRect
);
1071 nsRect
ExpandRectToNearlyVisible(const nsRect
& aRect
) const final
{
1072 return mHelper
.ExpandRectToNearlyVisible(aRect
);
1074 ScrollOrigin
LastScrollOrigin() final
{ return mHelper
.LastScrollOrigin(); }
1075 bool IsScrollAnimating(IncludeApzAnimation aIncludeApz
) final
{
1076 return mHelper
.IsScrollAnimating(aIncludeApz
);
1078 mozilla::ScrollGeneration
CurrentScrollGeneration() const final
{
1079 return mHelper
.CurrentScrollGeneration();
1081 nsPoint
LastScrollDestination() final
{
1082 return mHelper
.LastScrollDestination();
1084 nsTArray
<mozilla::ScrollPositionUpdate
> GetScrollUpdates() const final
{
1085 return mHelper
.GetScrollUpdates();
1087 bool HasScrollUpdates() const final
{ return mHelper
.HasScrollUpdates(); }
1088 void ResetScrollInfoIfNeeded(const mozilla::ScrollGeneration
& aGeneration
,
1089 bool aApzAnimationInProgress
) final
{
1090 mHelper
.ResetScrollInfoIfNeeded(aGeneration
, aApzAnimationInProgress
);
1092 bool WantAsyncScroll() const final
{ return mHelper
.WantAsyncScroll(); }
1093 mozilla::Maybe
<mozilla::layers::ScrollMetadata
> ComputeScrollMetadata(
1094 LayerManager
* aLayerManager
, const nsIFrame
* aContainerReferenceFrame
,
1095 const Maybe
<ContainerLayerParameters
>& aParameters
,
1096 const mozilla::DisplayItemClip
* aClip
) const final
{
1097 return mHelper
.ComputeScrollMetadata(
1098 aLayerManager
, aContainerReferenceFrame
, aParameters
, aClip
);
1100 void ClipLayerToDisplayPort(
1101 Layer
* aLayer
, const mozilla::DisplayItemClip
* aClip
,
1102 const ContainerLayerParameters
& aParameters
) const final
{
1103 mHelper
.ClipLayerToDisplayPort(aLayer
, aClip
, aParameters
);
1105 void MarkScrollbarsDirtyForReflow() const final
{
1106 mHelper
.MarkScrollbarsDirtyForReflow();
1108 void InvalidateVerticalScrollbar() const final
{
1109 mHelper
.InvalidateVerticalScrollbar();
1112 void UpdateScrollbarPosition() final
{ mHelper
.UpdateScrollbarPosition(); }
1113 bool DecideScrollableLayer(nsDisplayListBuilder
* aBuilder
,
1114 nsRect
* aVisibleRect
, nsRect
* aDirtyRect
,
1115 bool aSetBase
) final
{
1116 return mHelper
.DecideScrollableLayer(aBuilder
, aVisibleRect
, aDirtyRect
,
1119 void NotifyApzTransaction() final
{ mHelper
.NotifyApzTransaction(); }
1120 void NotifyApproximateFrameVisibilityUpdate(bool aIgnoreDisplayPort
) final
{
1121 mHelper
.NotifyApproximateFrameVisibilityUpdate(aIgnoreDisplayPort
);
1123 bool GetDisplayPortAtLastApproximateFrameVisibilityUpdate(
1124 nsRect
* aDisplayPort
) final
{
1125 return mHelper
.GetDisplayPortAtLastApproximateFrameVisibilityUpdate(
1128 void TriggerDisplayPortExpiration() final
{
1129 mHelper
.TriggerDisplayPortExpiration();
1133 mozilla::UniquePtr
<mozilla::PresState
> SaveState() final
{
1134 return mHelper
.SaveState();
1136 NS_IMETHOD
RestoreState(mozilla::PresState
* aState
) final
{
1137 NS_ENSURE_ARG_POINTER(aState
);
1138 mHelper
.RestoreState(aState
);
1142 // nsIScrollbarMediator
1143 void ScrollByPage(nsScrollbarFrame
* aScrollbar
, int32_t aDirection
,
1144 nsIScrollbarMediator::ScrollSnapMode aSnap
=
1145 nsIScrollbarMediator::DISABLE_SNAP
) final
{
1146 mHelper
.ScrollByPage(aScrollbar
, aDirection
, aSnap
);
1148 void ScrollByWhole(nsScrollbarFrame
* aScrollbar
, int32_t aDirection
,
1149 nsIScrollbarMediator::ScrollSnapMode aSnap
=
1150 nsIScrollbarMediator::DISABLE_SNAP
) final
{
1151 mHelper
.ScrollByWhole(aScrollbar
, aDirection
, aSnap
);
1153 void ScrollByLine(nsScrollbarFrame
* aScrollbar
, int32_t aDirection
,
1154 nsIScrollbarMediator::ScrollSnapMode aSnap
=
1155 nsIScrollbarMediator::DISABLE_SNAP
) final
{
1156 mHelper
.ScrollByLine(aScrollbar
, aDirection
, aSnap
);
1158 void ScrollByUnit(nsScrollbarFrame
* aScrollbar
, ScrollMode aMode
,
1159 int32_t aDirection
, mozilla::ScrollUnit aUnit
,
1160 ScrollSnapMode aSnap
= DISABLE_SNAP
) final
{
1161 mHelper
.ScrollByUnit(aScrollbar
, aMode
, aDirection
, aUnit
, aSnap
);
1163 void RepeatButtonScroll(nsScrollbarFrame
* aScrollbar
) final
{
1164 mHelper
.RepeatButtonScroll(aScrollbar
);
1166 void ThumbMoved(nsScrollbarFrame
* aScrollbar
, nscoord aOldPos
,
1167 nscoord aNewPos
) final
{
1168 mHelper
.ThumbMoved(aScrollbar
, aOldPos
, aNewPos
);
1170 void ScrollbarReleased(nsScrollbarFrame
* aScrollbar
) final
{
1171 mHelper
.ScrollbarReleased(aScrollbar
);
1173 void VisibilityChanged(bool aVisible
) final
{}
1174 nsIFrame
* GetScrollbarBox(bool aVertical
) final
{
1175 return mHelper
.GetScrollbarBox(aVertical
);
1177 void ScrollbarActivityStarted() const final
;
1178 void ScrollbarActivityStopped() const final
;
1180 bool IsScrollbarOnRight() const final
{ return mHelper
.IsScrollbarOnRight(); }
1182 bool ShouldSuppressScrollbarRepaints() const final
{
1183 return mHelper
.ShouldSuppressScrollbarRepaints();
1186 void SetTransformingByAPZ(bool aTransforming
) final
{
1187 mHelper
.SetTransformingByAPZ(aTransforming
);
1189 bool IsTransformingByAPZ() const final
{
1190 return mHelper
.IsTransformingByAPZ();
1192 void SetScrollableByAPZ(bool aScrollable
) final
{
1193 mHelper
.SetScrollableByAPZ(aScrollable
);
1195 void SetZoomableByAPZ(bool aZoomable
) final
{
1196 mHelper
.SetZoomableByAPZ(aZoomable
);
1198 void SetHasOutOfFlowContentInsideFilter() final
{
1199 mHelper
.SetHasOutOfFlowContentInsideFilter();
1202 ScrollSnapInfo
GetScrollSnapInfo() const final
{
1203 return mHelper
.GetScrollSnapInfo(Nothing());
1206 bool DragScroll(mozilla::WidgetEvent
* aEvent
) final
{
1207 return mHelper
.DragScroll(aEvent
);
1210 void AsyncScrollbarDragInitiated(
1211 uint64_t aDragBlockId
,
1212 mozilla::layers::ScrollDirection aDirection
) final
{
1213 return mHelper
.AsyncScrollbarDragInitiated(aDragBlockId
, aDirection
);
1216 void AsyncScrollbarDragRejected() final
{
1217 return mHelper
.AsyncScrollbarDragRejected();
1220 bool IsRootScrollFrameOfDocument() const final
{
1221 return mHelper
.IsRootScrollFrameOfDocument();
1224 const ScrollAnchorContainer
* Anchor() const final
{ return &mHelper
.mAnchor
; }
1226 ScrollAnchorContainer
* Anchor() final
{ return &mHelper
.mAnchor
; }
1228 // Return the scrolled frame.
1229 void AppendDirectlyOwnedAnonBoxes(nsTArray
<OwnedAnonBox
>& aResult
) final
{
1230 aResult
.AppendElement(OwnedAnonBox(mHelper
.GetScrolledFrame()));
1233 bool SmoothScrollVisual(
1234 const nsPoint
& aVisualViewportOffset
,
1235 mozilla::layers::FrameMetrics::ScrollOffsetUpdateType aUpdateType
) final
{
1236 return mHelper
.SmoothScrollVisual(aVisualViewportOffset
, aUpdateType
);
1239 bool IsSmoothScroll(mozilla::dom::ScrollBehavior aBehavior
) const final
{
1240 return mHelper
.IsSmoothScroll(aBehavior
);
1243 #ifdef DEBUG_FRAME_DUMP
1244 nsresult
GetFrameName(nsAString
& aResult
) const override
;
1247 #ifdef ACCESSIBILITY
1248 mozilla::a11y::AccType
AccessibleType() override
;
1252 nsHTMLScrollFrame(ComputedStyle
* aStyle
, nsPresContext
* aPresContext
,
1254 : nsHTMLScrollFrame(aStyle
, aPresContext
, kClassID
, aIsRoot
) {}
1256 nsHTMLScrollFrame(ComputedStyle
* aStyle
, nsPresContext
* aPresContext
,
1257 nsIFrame::ClassID aID
, bool aIsRoot
);
1258 void SetSuppressScrollbarUpdate(bool aSuppress
) {
1259 mHelper
.mSuppressScrollbarUpdate
= aSuppress
;
1261 bool GuessHScrollbarNeeded(const ScrollReflowInput
& aState
);
1262 bool GuessVScrollbarNeeded(const ScrollReflowInput
& aState
);
1264 bool IsScrollbarUpdateSuppressed() const {
1265 return mHelper
.mSuppressScrollbarUpdate
;
1268 // Return whether we're in an "initial" reflow. Some reflows with
1269 // NS_FRAME_FIRST_REFLOW set are NOT "initial" as far as we're concerned.
1270 bool InInitialReflow() const;
1273 * Override this to return false if computed bsize/min-bsize/max-bsize
1274 * should NOT be propagated to child content.
1275 * nsListControlFrame uses this.
1277 virtual bool ShouldPropagateComputedBSizeToScrolledContent() const {
1282 friend class mozilla::ScrollFrameHelper
;
1283 ScrollFrameHelper mHelper
;
1287 * The scroll frame creates and manages the scrolling view
1289 * It only supports having a single child frame that typically is an area
1290 * frame, but doesn't have to be. The child frame must have a view, though
1292 * Scroll frames don't support incremental changes, i.e. you can't replace
1293 * or remove the scrolled frame
1295 class nsXULScrollFrame final
: public nsBoxFrame
,
1296 public nsIScrollableFrame
,
1297 public nsIAnonymousContentCreator
,
1298 public nsIStatefulFrame
{
1300 typedef mozilla::ScrollFrameHelper ScrollFrameHelper
;
1301 typedef mozilla::CSSIntPoint CSSIntPoint
;
1302 typedef mozilla::layout::ScrollAnchorContainer ScrollAnchorContainer
;
1305 NS_DECL_FRAMEARENA_HELPERS(nsXULScrollFrame
)
1307 friend nsXULScrollFrame
* NS_NewXULScrollFrame(mozilla::PresShell
* aPresShell
,
1308 ComputedStyle
* aStyle
,
1310 bool aClipAllDescendants
);
1312 void BuildDisplayList(nsDisplayListBuilder
* aBuilder
,
1313 const nsDisplayListSet
& aLists
) final
{
1314 mHelper
.BuildDisplayList(aBuilder
, aLists
);
1317 // XXXldb Is this actually used?
1319 nscoord
GetMinISize(gfxContext
*aRenderingContext
) final
;
1322 bool ComputeCustomOverflow(mozilla::OverflowAreas
& aOverflowAreas
) final
{
1323 return mHelper
.ComputeCustomOverflow(aOverflowAreas
);
1326 bool GetVerticalAlignBaseline(mozilla::WritingMode aWM
,
1327 nscoord
* aBaseline
) const final
{
1328 *aBaseline
= GetLogicalBaseline(aWM
);
1332 // Called to set the child frames. We typically have three: the scroll area,
1333 // the vertical scrollbar, and the horizontal scrollbar.
1334 void SetInitialChildList(ChildListID aListID
, nsFrameList
& aChildList
) final
;
1335 void AppendFrames(ChildListID aListID
, nsFrameList
& aFrameList
) final
;
1336 void InsertFrames(ChildListID aListID
, nsIFrame
* aPrevFrame
,
1337 const nsLineList::iterator
* aPrevFrameLine
,
1338 nsFrameList
& aFrameList
) final
;
1339 void RemoveFrame(ChildListID aListID
, nsIFrame
* aOldFrame
) final
;
1341 void DestroyFrom(nsIFrame
* aDestructRoot
,
1342 PostDestroyData
& aPostDestroyData
) final
;
1344 nsIScrollableFrame
* GetScrollTargetFrame() const final
{
1345 return const_cast<nsXULScrollFrame
*>(this);
1348 nsContainerFrame
* GetContentInsertionFrame() final
{
1349 return mHelper
.GetScrolledFrame()->GetContentInsertionFrame();
1352 bool DoesClipChildrenInBothAxes() final
{ return true; }
1354 nsPoint
GetPositionOfChildIgnoringScrolling(const nsIFrame
* aChild
) final
{
1355 nsPoint pt
= aChild
->GetPosition();
1356 if (aChild
== mHelper
.GetScrolledFrame())
1357 pt
+= mHelper
.GetLogicalScrollPosition();
1361 // nsIAnonymousContentCreator
1362 nsresult
CreateAnonymousContent(nsTArray
<ContentInfo
>& aElements
) final
;
1363 void AppendAnonymousContentTo(nsTArray
<nsIContent
*>& aElements
,
1364 uint32_t aFilter
) final
;
1366 nsSize
GetXULMinSize(nsBoxLayoutState
& aBoxLayoutState
) final
;
1367 nsSize
GetXULPrefSize(nsBoxLayoutState
& aBoxLayoutState
) final
;
1368 nsSize
GetXULMaxSize(nsBoxLayoutState
& aBoxLayoutState
) final
;
1369 nscoord
GetXULBoxAscent(nsBoxLayoutState
& aBoxLayoutState
) final
;
1371 NS_IMETHOD
DoXULLayout(nsBoxLayoutState
& aBoxLayoutState
) final
;
1372 nsresult
GetXULPadding(nsMargin
& aPadding
) final
;
1374 bool GetBorderRadii(const nsSize
& aFrameSize
, const nsSize
& aBorderArea
,
1375 Sides aSkipSides
, nscoord aRadii
[8]) const final
{
1376 return mHelper
.GetBorderRadii(aFrameSize
, aBorderArea
, aSkipSides
, aRadii
);
1379 nsresult
XULLayout(nsBoxLayoutState
& aState
);
1380 void LayoutScrollArea(nsBoxLayoutState
& aState
,
1381 const nsPoint
& aScrollPosition
);
1383 static bool AddRemoveScrollbar(bool& aHasScrollbar
, nscoord
& aXY
,
1384 nscoord
& aSize
, nscoord aSbSize
,
1385 bool aOnRightOrBottom
, bool aAdd
);
1387 bool AddRemoveScrollbar(nsBoxLayoutState
& aState
, bool aOnRightOrBottom
,
1388 bool aHorizontal
, bool aAdd
);
1390 bool AddHorizontalScrollbar(nsBoxLayoutState
& aState
, bool aOnBottom
);
1391 bool AddVerticalScrollbar(nsBoxLayoutState
& aState
, bool aOnRight
);
1392 void RemoveHorizontalScrollbar(nsBoxLayoutState
& aState
, bool aOnBottom
);
1393 void RemoveVerticalScrollbar(nsBoxLayoutState
& aState
, bool aOnRight
);
1395 static void AdjustReflowInputForPrintPreview(nsBoxLayoutState
& aState
,
1397 static void AdjustReflowInputBack(nsBoxLayoutState
& aState
, bool aSetBack
);
1399 // nsIScrollableFrame
1400 nsIFrame
* GetScrolledFrame() const final
{
1401 return mHelper
.GetScrolledFrame();
1403 mozilla::ScrollStyles
GetScrollStyles() const final
{
1404 return mHelper
.GetScrollStylesFromFrame();
1406 bool IsForTextControlWithNoScrollbars() const final
{
1407 return mHelper
.IsForTextControlWithNoScrollbars();
1409 mozilla::layers::OverscrollBehaviorInfo
GetOverscrollBehaviorInfo()
1411 return mHelper
.GetOverscrollBehaviorInfo();
1413 mozilla::layers::ScrollDirections
1414 GetAvailableScrollingDirectionsForUserInputEvents() const final
{
1415 return mHelper
.GetAvailableScrollingDirectionsForUserInputEvents();
1417 mozilla::layers::ScrollDirections
GetScrollbarVisibility() const final
{
1418 return mHelper
.GetScrollbarVisibility();
1420 nsMargin
GetActualScrollbarSizes(
1421 nsIScrollableFrame::ScrollbarSizesOptions aOptions
=
1422 nsIScrollableFrame::ScrollbarSizesOptions::NONE
) const final
{
1423 return mHelper
.GetActualScrollbarSizes(aOptions
);
1425 nsMargin
GetDesiredScrollbarSizes(nsBoxLayoutState
* aState
) final
{
1426 return mHelper
.GetDesiredScrollbarSizes(aState
);
1428 nsMargin
GetDesiredScrollbarSizes(nsPresContext
* aPresContext
,
1429 gfxContext
* aRC
) final
{
1430 nsBoxLayoutState
bls(aPresContext
, aRC
, 0);
1431 return GetDesiredScrollbarSizes(&bls
);
1433 nscoord
GetNondisappearingScrollbarWidth(nsPresContext
* aPresContext
,
1435 mozilla::WritingMode aWM
) final
{
1436 nsBoxLayoutState
bls(aPresContext
, aRC
, 0);
1437 return mHelper
.GetNondisappearingScrollbarWidth(&bls
, aWM
);
1439 nsSize
GetLayoutSize() const final
{ return mHelper
.GetLayoutSize(); }
1440 nsRect
GetScrolledRect() const final
{ return mHelper
.GetScrolledRect(); }
1441 nsRect
GetScrollPortRect() const final
{ return mHelper
.GetScrollPortRect(); }
1442 nsPoint
GetScrollPosition() const final
{
1443 return mHelper
.GetScrollPosition();
1445 nsPoint
GetLogicalScrollPosition() const final
{
1446 return mHelper
.GetLogicalScrollPosition();
1448 nsRect
GetScrollRange() const final
{ return mHelper
.GetLayoutScrollRange(); }
1449 nsSize
GetVisualViewportSize() const final
{
1450 return mHelper
.GetVisualViewportSize();
1452 nsPoint
GetVisualViewportOffset() const final
{
1453 return mHelper
.GetVisualViewportOffset();
1455 bool SetVisualViewportOffset(const nsPoint
& aOffset
, bool aRepaint
) final
{
1456 return mHelper
.SetVisualViewportOffset(aOffset
, aRepaint
);
1458 nsRect
GetVisualScrollRange() const final
{
1459 return mHelper
.GetVisualScrollRange();
1461 nsRect
GetScrollRangeForUserInputEvents() const final
{
1462 return mHelper
.GetScrollRangeForUserInputEvents();
1464 nsSize
GetLineScrollAmount() const final
{
1465 return mHelper
.GetLineScrollAmount();
1467 nsSize
GetPageScrollAmount() const final
{
1468 return mHelper
.GetPageScrollAmount();
1470 nsMargin
GetScrollPadding() const final
{ return mHelper
.GetScrollPadding(); }
1472 * @note This method might destroy the frame, pres shell and other objects.
1475 nsPoint aScrollPosition
, ScrollMode aMode
, const nsRect
* aRange
= nullptr,
1476 ScrollSnapMode aSnap
= nsIScrollbarMediator::DISABLE_SNAP
) final
{
1477 mHelper
.ScrollTo(aScrollPosition
, aMode
, ScrollOrigin::Other
, aRange
,
1481 * @note This method might destroy the frame, pres shell and other objects.
1483 void ScrollToCSSPixels(
1484 const CSSIntPoint
& aScrollPosition
,
1485 ScrollMode aMode
= ScrollMode::Instant
,
1486 nsIScrollbarMediator::ScrollSnapMode aSnap
=
1487 nsIScrollbarMediator::DISABLE_SNAP
,
1488 ScrollOrigin aOrigin
= ScrollOrigin::NotSpecified
) final
{
1489 mHelper
.ScrollToCSSPixels(aScrollPosition
, aMode
, aSnap
, aOrigin
);
1491 void ScrollToCSSPixelsApproximate(
1492 const mozilla::CSSPoint
& aScrollPosition
,
1493 ScrollOrigin aOrigin
= ScrollOrigin::NotSpecified
) final
{
1494 mHelper
.ScrollToCSSPixelsApproximate(aScrollPosition
, aOrigin
);
1496 CSSIntPoint
GetScrollPositionCSSPixels() final
{
1497 return mHelper
.GetScrollPositionCSSPixels();
1500 * @note This method might destroy the frame, pres shell and other objects.
1502 void ScrollBy(nsIntPoint aDelta
, mozilla::ScrollUnit aUnit
, ScrollMode aMode
,
1503 nsIntPoint
* aOverflow
,
1504 ScrollOrigin aOrigin
= ScrollOrigin::NotSpecified
,
1505 nsIScrollableFrame::ScrollMomentum aMomentum
=
1506 nsIScrollableFrame::NOT_MOMENTUM
,
1507 nsIScrollbarMediator::ScrollSnapMode aSnap
=
1508 nsIScrollbarMediator::DISABLE_SNAP
) final
{
1509 mHelper
.ScrollBy(aDelta
, aUnit
, aMode
, aOverflow
, aOrigin
, aMomentum
,
1512 void ScrollByCSSPixels(const CSSIntPoint
& aDelta
,
1513 ScrollMode aMode
= ScrollMode::Instant
,
1514 ScrollOrigin aOrigin
= ScrollOrigin::NotSpecified
,
1515 nsIScrollbarMediator::ScrollSnapMode aSnap
=
1516 nsIScrollbarMediator::DEFAULT
) final
{
1517 mHelper
.ScrollByCSSPixels(aDelta
, aMode
, aOrigin
, aSnap
);
1519 void ScrollSnap() final
{ mHelper
.ScrollSnap(); }
1521 * @note This method might destroy the frame, pres shell and other objects.
1523 void ScrollToRestoredPosition() final
{ mHelper
.ScrollToRestoredPosition(); }
1524 void AddScrollPositionListener(nsIScrollPositionListener
* aListener
) final
{
1525 mHelper
.AddScrollPositionListener(aListener
);
1527 void RemoveScrollPositionListener(
1528 nsIScrollPositionListener
* aListener
) final
{
1529 mHelper
.RemoveScrollPositionListener(aListener
);
1532 * @note This method might destroy the frame, pres shell and other objects.
1534 void CurPosAttributeChanged(nsIContent
* aChild
) final
{
1535 mHelper
.CurPosAttributeChanged(aChild
);
1537 NS_IMETHOD
PostScrolledAreaEventForCurrentArea() final
{
1538 mHelper
.PostScrolledAreaEvent();
1541 bool IsScrollingActive(nsDisplayListBuilder
* aBuilder
) final
{
1542 return mHelper
.IsScrollingActive(aBuilder
);
1544 bool IsScrollingActiveNotMinimalDisplayPort(
1545 nsDisplayListBuilder
* aBuilder
) final
{
1546 return mHelper
.IsScrollingActiveNotMinimalDisplayPort(aBuilder
);
1548 bool IsMaybeScrollingActive() const final
{
1549 return mHelper
.IsMaybeScrollingActive();
1551 bool IsMaybeAsynchronouslyScrolled() final
{
1552 return mHelper
.IsMaybeAsynchronouslyScrolled();
1554 void ResetScrollPositionForLayerPixelAlignment() final
{
1555 mHelper
.ResetScrollPositionForLayerPixelAlignment();
1557 bool DidHistoryRestore() const final
{ return mHelper
.mDidHistoryRestore
; }
1558 void ClearDidHistoryRestore() final
{ mHelper
.mDidHistoryRestore
= false; }
1559 void MarkEverScrolled() final
{ mHelper
.MarkEverScrolled(); }
1560 bool IsRectNearlyVisible(const nsRect
& aRect
) final
{
1561 return mHelper
.IsRectNearlyVisible(aRect
);
1563 nsRect
ExpandRectToNearlyVisible(const nsRect
& aRect
) const final
{
1564 return mHelper
.ExpandRectToNearlyVisible(aRect
);
1566 ScrollOrigin
LastScrollOrigin() final
{ return mHelper
.LastScrollOrigin(); }
1567 bool IsScrollAnimating(IncludeApzAnimation aIncludeApz
) final
{
1568 return mHelper
.IsScrollAnimating(aIncludeApz
);
1570 mozilla::ScrollGeneration
CurrentScrollGeneration() const final
{
1571 return mHelper
.CurrentScrollGeneration();
1573 nsPoint
LastScrollDestination() final
{
1574 return mHelper
.LastScrollDestination();
1576 nsTArray
<mozilla::ScrollPositionUpdate
> GetScrollUpdates() const final
{
1577 return mHelper
.GetScrollUpdates();
1579 bool HasScrollUpdates() const final
{ return mHelper
.HasScrollUpdates(); }
1580 void ResetScrollInfoIfNeeded(const mozilla::ScrollGeneration
& aGeneration
,
1581 bool aApzAnimationInProgress
) final
{
1582 mHelper
.ResetScrollInfoIfNeeded(aGeneration
, aApzAnimationInProgress
);
1584 bool WantAsyncScroll() const final
{ return mHelper
.WantAsyncScroll(); }
1585 mozilla::Maybe
<mozilla::layers::ScrollMetadata
> ComputeScrollMetadata(
1586 LayerManager
* aLayerManager
, const nsIFrame
* aContainerReferenceFrame
,
1587 const Maybe
<ContainerLayerParameters
>& aParameters
,
1588 const mozilla::DisplayItemClip
* aClip
) const final
{
1589 return mHelper
.ComputeScrollMetadata(
1590 aLayerManager
, aContainerReferenceFrame
, aParameters
, aClip
);
1592 void ClipLayerToDisplayPort(
1593 Layer
* aLayer
, const mozilla::DisplayItemClip
* aClip
,
1594 const ContainerLayerParameters
& aParameters
) const final
{
1595 mHelper
.ClipLayerToDisplayPort(aLayer
, aClip
, aParameters
);
1597 void MarkScrollbarsDirtyForReflow() const final
{
1598 mHelper
.MarkScrollbarsDirtyForReflow();
1600 void InvalidateVerticalScrollbar() const final
{
1601 mHelper
.InvalidateVerticalScrollbar();
1603 void UpdateScrollbarPosition() final
{ mHelper
.UpdateScrollbarPosition(); }
1606 mozilla::UniquePtr
<mozilla::PresState
> SaveState() final
{
1607 return mHelper
.SaveState();
1609 NS_IMETHOD
RestoreState(mozilla::PresState
* aState
) final
{
1610 NS_ENSURE_ARG_POINTER(aState
);
1611 mHelper
.RestoreState(aState
);
1615 bool IsFrameOfType(uint32_t aFlags
) const final
{
1616 // Override bogus IsFrameOfType in nsBoxFrame.
1617 if (aFlags
& (nsIFrame::eReplacedContainsBlock
| nsIFrame::eReplaced
))
1619 return nsBoxFrame::IsFrameOfType(aFlags
);
1622 void ScrollByPage(nsScrollbarFrame
* aScrollbar
, int32_t aDirection
,
1623 nsIScrollbarMediator::ScrollSnapMode aSnap
=
1624 nsIScrollbarMediator::DISABLE_SNAP
) final
{
1625 mHelper
.ScrollByPage(aScrollbar
, aDirection
, aSnap
);
1627 void ScrollByWhole(nsScrollbarFrame
* aScrollbar
, int32_t aDirection
,
1628 nsIScrollbarMediator::ScrollSnapMode aSnap
=
1629 nsIScrollbarMediator::DISABLE_SNAP
) final
{
1630 mHelper
.ScrollByWhole(aScrollbar
, aDirection
, aSnap
);
1632 void ScrollByLine(nsScrollbarFrame
* aScrollbar
, int32_t aDirection
,
1633 nsIScrollbarMediator::ScrollSnapMode aSnap
=
1634 nsIScrollbarMediator::DISABLE_SNAP
) final
{
1635 mHelper
.ScrollByLine(aScrollbar
, aDirection
, aSnap
);
1637 void ScrollByUnit(nsScrollbarFrame
* aScrollbar
, ScrollMode aMode
,
1638 int32_t aDirection
, mozilla::ScrollUnit aUnit
,
1639 ScrollSnapMode aSnap
= DISABLE_SNAP
) final
{
1640 mHelper
.ScrollByUnit(aScrollbar
, aMode
, aDirection
, aUnit
, aSnap
);
1642 void RepeatButtonScroll(nsScrollbarFrame
* aScrollbar
) final
{
1643 mHelper
.RepeatButtonScroll(aScrollbar
);
1645 void ThumbMoved(nsScrollbarFrame
* aScrollbar
, nscoord aOldPos
,
1646 nscoord aNewPos
) final
{
1647 mHelper
.ThumbMoved(aScrollbar
, aOldPos
, aNewPos
);
1649 void ScrollbarReleased(nsScrollbarFrame
* aScrollbar
) final
{
1650 mHelper
.ScrollbarReleased(aScrollbar
);
1652 void VisibilityChanged(bool aVisible
) final
{}
1653 nsIFrame
* GetScrollbarBox(bool aVertical
) final
{
1654 return mHelper
.GetScrollbarBox(aVertical
);
1657 void ScrollbarActivityStarted() const final
;
1658 void ScrollbarActivityStopped() const final
;
1660 bool IsScrollbarOnRight() const final
{ return mHelper
.IsScrollbarOnRight(); }
1662 bool ShouldSuppressScrollbarRepaints() const final
{
1663 return mHelper
.ShouldSuppressScrollbarRepaints();
1666 void SetTransformingByAPZ(bool aTransforming
) final
{
1667 mHelper
.SetTransformingByAPZ(aTransforming
);
1669 bool IsTransformingByAPZ() const final
{
1670 return mHelper
.IsTransformingByAPZ();
1672 void SetScrollableByAPZ(bool aScrollable
) final
{
1673 mHelper
.SetScrollableByAPZ(aScrollable
);
1675 void SetZoomableByAPZ(bool aZoomable
) final
{
1676 mHelper
.SetZoomableByAPZ(aZoomable
);
1678 void SetHasOutOfFlowContentInsideFilter() final
{
1679 mHelper
.SetHasOutOfFlowContentInsideFilter();
1681 bool DecideScrollableLayer(nsDisplayListBuilder
* aBuilder
,
1682 nsRect
* aVisibleRect
, nsRect
* aDirtyRect
,
1683 bool aSetBase
) final
{
1684 return mHelper
.DecideScrollableLayer(aBuilder
, aVisibleRect
, aDirtyRect
,
1687 void NotifyApzTransaction() final
{ mHelper
.NotifyApzTransaction(); }
1688 void NotifyApproximateFrameVisibilityUpdate(bool aIgnoreDisplayPort
) final
{
1689 mHelper
.NotifyApproximateFrameVisibilityUpdate(aIgnoreDisplayPort
);
1691 bool GetDisplayPortAtLastApproximateFrameVisibilityUpdate(
1692 nsRect
* aDisplayPort
) final
{
1693 return mHelper
.GetDisplayPortAtLastApproximateFrameVisibilityUpdate(
1696 void TriggerDisplayPortExpiration() final
{
1697 mHelper
.TriggerDisplayPortExpiration();
1700 ScrollSnapInfo
GetScrollSnapInfo() const final
{
1701 return mHelper
.GetScrollSnapInfo(Nothing());
1704 bool DragScroll(mozilla::WidgetEvent
* aEvent
) final
{
1705 return mHelper
.DragScroll(aEvent
);
1708 void AsyncScrollbarDragInitiated(
1709 uint64_t aDragBlockId
,
1710 mozilla::layers::ScrollDirection aDirection
) final
{
1711 return mHelper
.AsyncScrollbarDragInitiated(aDragBlockId
, aDirection
);
1714 void AsyncScrollbarDragRejected() final
{
1715 return mHelper
.AsyncScrollbarDragRejected();
1718 bool IsRootScrollFrameOfDocument() const final
{
1719 return mHelper
.IsRootScrollFrameOfDocument();
1722 const ScrollAnchorContainer
* Anchor() const final
{ return &mHelper
.mAnchor
; }
1724 ScrollAnchorContainer
* Anchor() final
{ return &mHelper
.mAnchor
; }
1726 // Return the scrolled frame.
1727 void AppendDirectlyOwnedAnonBoxes(nsTArray
<OwnedAnonBox
>& aResult
) final
{
1728 aResult
.AppendElement(OwnedAnonBox(mHelper
.GetScrolledFrame()));
1731 bool SmoothScrollVisual(
1732 const nsPoint
& aVisualViewportOffset
,
1733 mozilla::layers::FrameMetrics::ScrollOffsetUpdateType aUpdateType
) final
{
1734 return mHelper
.SmoothScrollVisual(aVisualViewportOffset
, aUpdateType
);
1737 bool IsSmoothScroll(mozilla::dom::ScrollBehavior aBehavior
) const final
{
1738 return mHelper
.IsSmoothScroll(aBehavior
);
1741 #ifdef DEBUG_FRAME_DUMP
1742 nsresult
GetFrameName(nsAString
& aResult
) const final
;
1746 nsXULScrollFrame(ComputedStyle
*, nsPresContext
*, bool aIsRoot
,
1747 bool aClipAllDescendants
);
1749 void ClampAndSetBounds(nsBoxLayoutState
& aState
, nsRect
& aRect
,
1750 nsPoint aScrollPosition
,
1751 bool aRemoveOverflowAreas
= false) {
1753 * For RTL frames, restore the original scrolled position of the right
1754 * edge, then subtract the current width to find the physical position.
1756 if (!mHelper
.IsPhysicalLTR()) {
1757 aRect
.x
= mHelper
.mScrollPort
.XMost() - aScrollPosition
.x
- aRect
.width
;
1759 mHelper
.mScrolledFrame
->SetXULBounds(aState
, aRect
, aRemoveOverflowAreas
);
1763 friend class mozilla::ScrollFrameHelper
;
1764 ScrollFrameHelper mHelper
;
1767 #endif /* nsGfxScrollFrame_h___ */