Bug 1708422: part 13) Factor code out to `mozInlineSpellChecker::SpellCheckerTimeSlic...
[gecko.git] / layout / generic / nsGfxScrollFrame.h
blob3782e4de2f49f8eeacd64f6320da7bf9cd51bfdc
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"
30 class nsPresContext;
31 class nsIContent;
32 class nsAtom;
33 class nsIScrollPositionListener;
35 namespace mozilla {
36 class PresShell;
37 struct ScrollReflowInput;
38 namespace layers {
39 class Layer;
40 class LayerManager;
41 } // namespace layers
42 namespace layout {
43 class ScrollbarActivity;
44 } // namespace layout
46 class ScrollFrameHelper : public nsIReflowCallback {
47 public:
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;
59 class AsyncScroll;
60 class AsyncSmoothMSDScroll;
62 ScrollFrameHelper(nsContainerFrame* aOuter, bool aIsRoot);
63 ~ScrollFrameHelper();
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,
78 uint32_t aFilter);
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)
91 // to |aLists|.
92 // This is a no-op for scroll frames other than the viewport's
93 // root scroll frame.
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,
99 bool* aIsOpaque);
101 void AppendScrollPartsTo(nsDisplayListBuilder* aBuilder,
102 const nsDisplayListSet& aLists, bool aCreateLayer,
103 bool aPositioned);
105 bool GetBorderRadii(const nsSize& aFrameSize, const nsSize& aBorderArea,
106 Sides aSkipSides, nscoord aRadii[8]) const;
108 // nsIReflowCallback
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) {
152 return mICBSize;
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 {
168 nsPoint pt;
169 pt.x = IsPhysicalLTR()
170 ? mScrollPort.x - mScrolledFrame->GetPosition().x
171 : mScrollPort.XMost() - mScrolledFrame->GetRect().XMost();
172 pt.y = mScrollPort.y - mScrolledFrame->GetPosition().y;
173 return pt;
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;
203 return pt;
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; }
215 public:
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);
252 void ScrollVisual();
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()
342 const;
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;
352 return result;
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(); }
365 private:
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;
378 public:
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
385 // to know I think.
386 return mWillBuildScrollableLayer;
388 bool IsMaybeScrollingActive() const;
389 void ResetScrollPositionForLayerPixelAlignment() {
390 mScrollPosForLayerPixelAlignment = GetScrollPosition();
393 bool ComputeCustomOverflow(mozilla::OverflowAreas& aOverflowAreas);
395 void UpdateSticky();
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,
451 bool aSetBase,
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,
505 nscoord aNewPos);
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,
537 bool aVertical,
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;
548 class ScrollEvent;
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.
576 nsRect mScrollPort;
577 nsSize mMinimumScaleSize;
579 // Stores the ICB size for the root document if this frame is using the
580 // minimum scale size for |mScrollPort|.
581 nsSize mICBSize;
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.
596 nsPoint mRestorePos;
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.
602 nsPoint mLastPos;
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?
643 bool mIsRoot : 1;
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
654 // false.
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
667 // reflow callback.
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
710 // a CSS filter.
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;
743 protected:
744 class AutoScrollbarRepaintSuppression;
745 friend class AutoScrollbarRepaintSuppression;
746 class AutoScrollbarRepaintSuppression {
747 public:
748 AutoScrollbarRepaintSuppression(ScrollFrameHelper* aHelper,
749 AutoWeakFrame& aWeakOuter, bool aSuppress)
750 : mHelper(aHelper),
751 mWeakOuter(aWeakOuter),
752 mOldSuppressValue(aHelper->mSuppressScrollbarRepaints) {
753 mHelper->mSuppressScrollbarRepaints = aSuppress;
756 ~AutoScrollbarRepaintSuppression() {
757 if (mWeakOuter.IsAlive()) {
758 mHelper->mSuppressScrollbarRepaints = mOldSuppressValue;
762 private:
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 {
808 public:
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);
816 NS_DECL_QUERYFRAME
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 "
861 "parallel to aWM");
862 *aBaseline = GetLogicalBaseline(aWM);
863 return true;
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();
896 return pt;
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()
914 const final {
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,
938 gfxContext* aRC,
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,
983 aSnap);
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,
1018 aSnap);
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();
1047 return NS_OK;
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,
1117 aSetBase);
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(
1126 aDisplayPort);
1128 void TriggerDisplayPortExpiration() final {
1129 mHelper.TriggerDisplayPortExpiration();
1132 // nsIStatefulFrame
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);
1139 return NS_OK;
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;
1245 #endif
1247 #ifdef ACCESSIBILITY
1248 mozilla::a11y::AccType AccessibleType() override;
1249 #endif
1251 protected:
1252 nsHTMLScrollFrame(ComputedStyle* aStyle, nsPresContext* aPresContext,
1253 bool aIsRoot)
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 {
1278 return true;
1281 private:
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 {
1299 public:
1300 typedef mozilla::ScrollFrameHelper ScrollFrameHelper;
1301 typedef mozilla::CSSIntPoint CSSIntPoint;
1302 typedef mozilla::layout::ScrollAnchorContainer ScrollAnchorContainer;
1304 NS_DECL_QUERYFRAME
1305 NS_DECL_FRAMEARENA_HELPERS(nsXULScrollFrame)
1307 friend nsXULScrollFrame* NS_NewXULScrollFrame(mozilla::PresShell* aPresShell,
1308 ComputedStyle* aStyle,
1309 bool aIsRoot,
1310 bool aClipAllDescendants);
1312 void BuildDisplayList(nsDisplayListBuilder* aBuilder,
1313 const nsDisplayListSet& aLists) final {
1314 mHelper.BuildDisplayList(aBuilder, aLists);
1317 // XXXldb Is this actually used?
1318 #if 0
1319 nscoord GetMinISize(gfxContext *aRenderingContext) final;
1320 #endif
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);
1329 return true;
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();
1358 return pt;
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,
1396 bool& aSetBack);
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()
1410 const final {
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,
1434 gfxContext* aRC,
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.
1474 void ScrollTo(
1475 nsPoint aScrollPosition, ScrollMode aMode, const nsRect* aRange = nullptr,
1476 ScrollSnapMode aSnap = nsIScrollbarMediator::DISABLE_SNAP) final {
1477 mHelper.ScrollTo(aScrollPosition, aMode, ScrollOrigin::Other, aRange,
1478 aSnap);
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,
1510 aSnap);
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();
1539 return NS_OK;
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(); }
1605 // nsIStatefulFrame
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);
1612 return NS_OK;
1615 bool IsFrameOfType(uint32_t aFlags) const final {
1616 // Override bogus IsFrameOfType in nsBoxFrame.
1617 if (aFlags & (nsIFrame::eReplacedContainsBlock | nsIFrame::eReplaced))
1618 return false;
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,
1685 aSetBase);
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(
1694 aDisplayPort);
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;
1743 #endif
1745 protected:
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);
1762 private:
1763 friend class mozilla::ScrollFrameHelper;
1764 ScrollFrameHelper mHelper;
1767 #endif /* nsGfxScrollFrame_h___ */