Bug 1568157 - Part 5: Move the NodePicker initialization into a getter. r=yulia
[gecko.git] / layout / generic / nsGfxScrollFrame.h
blob554ece5c5fb0941954afa28db1e47487707fae03
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 "nsRefreshDriver.h"
24 #include "nsExpirationTracker.h"
25 #include "TextOverflow.h"
26 #include "ScrollVelocityQueue.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;
58 class AsyncScroll;
59 class AsyncSmoothMSDScroll;
61 ScrollFrameHelper(nsContainerFrame* aOuter, bool aIsRoot);
62 ~ScrollFrameHelper();
64 mozilla::ScrollStyles GetScrollStylesFromFrame() const;
66 // If a child frame was added or removed on the scrollframe,
67 // reload our child frame list.
68 // We need this if a scrollbar frame is recreated.
69 void ReloadChildFrames();
71 nsresult CreateAnonymousContent(
72 nsTArray<nsIAnonymousContentCreator::ContentInfo>& aElements);
73 void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
74 uint32_t aFilter);
75 nsresult FireScrollPortEvent();
76 void PostScrollEndEvent();
77 void FireScrollEndEvent();
78 void PostOverflowEvent();
79 using PostDestroyData = nsIFrame::PostDestroyData;
80 void Destroy(PostDestroyData& aPostDestroyData);
82 void BuildDisplayList(nsDisplayListBuilder* aBuilder,
83 const nsDisplayListSet& aLists);
85 // Add display items for the top-layer (which includes things like
86 // the fullscreen element, its backdrop, and text selection carets)
87 // to |aLists|.
88 // This is a no-op for scroll frames other than the viewport's
89 // root scroll frame.
90 // This should be called with an nsDisplayListSet that will be
91 // wrapped in the async zoom container, if we're building one.
92 // It should not be called with an ASR setter on the stack, as the
93 // top-layer items handle setting up their own ASRs.
94 void MaybeAddTopLayerItems(nsDisplayListBuilder* aBuilder,
95 const nsDisplayListSet& aLists);
97 void AppendScrollPartsTo(nsDisplayListBuilder* aBuilder,
98 const nsDisplayListSet& aLists, bool aCreateLayer,
99 bool aPositioned);
101 bool GetBorderRadii(const nsSize& aFrameSize, const nsSize& aBorderArea,
102 Sides aSkipSides, nscoord aRadii[8]) const;
104 // nsIReflowCallback
105 virtual bool ReflowFinished() override;
106 virtual void ReflowCallbackCanceled() override;
109 * @note This method might destroy the frame, pres shell and other objects.
110 * Called when the 'curpos' attribute on one of the scrollbars changes.
112 void CurPosAttributeChanged(nsIContent* aChild, bool aDoScroll = true);
114 void PostScrollEvent(bool aDelayed = false);
115 void FireScrollEvent();
116 void PostScrolledAreaEvent();
117 void FireScrolledAreaEvent();
119 bool IsSmoothScrollingEnabled();
122 * @note This method might destroy the frame, pres shell and other objects.
124 void FinishReflowForScrollbar(mozilla::dom::Element* aElement, nscoord aMinXY,
125 nscoord aMaxXY, nscoord aCurPosXY,
126 nscoord aPageIncrement, nscoord aIncrement);
128 * @note This method might destroy the frame, pres shell and other objects.
130 void SetScrollbarEnabled(mozilla::dom::Element* aElement, nscoord aMaxPos);
132 * @note This method might destroy the frame, pres shell and other objects.
134 void SetCoordAttribute(mozilla::dom::Element* aElement, nsAtom* aAtom,
135 nscoord aSize);
137 nscoord GetCoordAttribute(nsIFrame* aFrame, nsAtom* aAtom,
138 nscoord aDefaultValue, nscoord* aRangeStart,
139 nscoord* aRangeLength);
142 * @note This method might destroy the frame, pres shell and other objects.
143 * Update scrollbar curpos attributes to reflect current scroll position
145 void UpdateScrollbarPosition();
147 nsSize GetLayoutSize() const {
148 if (mIsUsingMinimumScaleSize) {
149 return mICBSize;
151 return mScrollPort.Size();
153 nsRect GetScrollPortRect() const { return mScrollPort; }
154 nsPoint GetScrollPosition() const {
155 return mScrollPort.TopLeft() - mScrolledFrame->GetPosition();
158 * For LTR frames, the logical scroll position is the offset of the top left
159 * corner of the frame from the top left corner of the scroll port (same as
160 * GetScrollPosition).
161 * For RTL frames, it is the offset of the top right corner of the frame from
162 * the top right corner of the scroll port
164 nsPoint GetLogicalScrollPosition() const {
165 nsPoint pt;
166 pt.x = IsPhysicalLTR()
167 ? mScrollPort.x - mScrolledFrame->GetPosition().x
168 : mScrollPort.XMost() - mScrolledFrame->GetRect().XMost();
169 pt.y = mScrollPort.y - mScrolledFrame->GetPosition().y;
170 return pt;
172 nsPoint GetApzScrollPosition() const { return mApzScrollPos; }
173 nsRect GetLayoutScrollRange() const;
174 // Get the scroll range assuming the viewport has size (aWidth, aHeight).
175 nsRect GetScrollRange(nscoord aWidth, nscoord aHeight) const;
176 nsSize GetVisualViewportSize() const;
177 nsPoint GetVisualViewportOffset() const;
180 * Return the 'optimal viewing region' [1] as a rect suitable for use by
181 * scroll anchoring. This rect is in the same coordinate space as
182 * 'GetScrollPortRect'.
184 * [1] https://drafts.csswg.org/css-scroll-snap-1/#optimal-viewing-region
186 nsRect GetVisualOptimalViewingRect() const;
189 * For LTR frames, this is the same as GetVisualViewportOffset().
190 * For RTL frames, we take the offset from the top right corner of the frame
191 * to the top right corner of the visual viewport.
193 nsPoint GetLogicalVisualViewportOffset() const {
194 nsPoint pt = GetVisualViewportOffset();
195 if (!IsPhysicalLTR()) {
196 pt.x += GetVisualViewportSize().width - mScrolledFrame->GetRect().width;
198 return pt;
200 void ScrollSnap(ScrollMode aMode = ScrollMode::SmoothMsd);
201 void ScrollSnap(const nsPoint& aDestination,
202 ScrollMode aMode = ScrollMode::SmoothMsd);
204 bool HasPendingScrollRestoration() const {
205 return mRestorePos != nsPoint(-1, -1);
208 bool IsProcessingScrollEvent() const { return mProcessingScrollEvent; }
210 protected:
211 nsRect GetVisualScrollRange() const;
213 public:
214 static void AsyncScrollCallback(ScrollFrameHelper* aInstance,
215 mozilla::TimeStamp aTime);
216 static void AsyncSmoothMSDScrollCallback(ScrollFrameHelper* aInstance,
217 mozilla::TimeDuration aDeltaTime);
219 * @note This method might destroy the frame, pres shell and other objects.
220 * aRange is the range of allowable scroll positions around the desired
221 * aScrollPosition. Null means only aScrollPosition is allowed.
222 * This is a closed-ended range --- aRange.XMost()/aRange.YMost() are allowed.
224 void ScrollTo(nsPoint aScrollPosition, ScrollMode aMode,
225 nsAtom* aOrigin = nullptr, const nsRect* aRange = nullptr,
226 nsIScrollbarMediator::ScrollSnapMode aSnap =
227 nsIScrollbarMediator::DISABLE_SNAP);
229 * @note This method might destroy the frame, pres shell and other objects.
231 void ScrollToCSSPixels(const CSSIntPoint& aScrollPosition,
232 ScrollMode aMode = ScrollMode::Instant,
233 nsIScrollbarMediator::ScrollSnapMode aSnap =
234 nsIScrollbarMediator::DEFAULT,
235 nsAtom* aOrigin = nullptr);
237 * @note This method might destroy the frame, pres shell and other objects.
239 void ScrollToCSSPixelsApproximate(const mozilla::CSSPoint& aScrollPosition,
240 nsAtom* aOrigin = nullptr);
242 CSSIntPoint GetScrollPositionCSSPixels();
244 * @note This method might destroy the frame, pres shell and other objects.
246 void ScrollToImpl(nsPoint aScrollPosition, const nsRect& aRange,
247 nsAtom* aOrigin = nullptr);
248 void ScrollVisual();
250 * @note This method might destroy the frame, pres shell and other objects.
252 void ScrollBy(nsIntPoint aDelta, nsIScrollableFrame::ScrollUnit aUnit,
253 ScrollMode aMode, nsIntPoint* aOverflow,
254 nsAtom* aOrigin = nullptr,
255 nsIScrollableFrame::ScrollMomentum aMomentum =
256 nsIScrollableFrame::NOT_MOMENTUM,
257 nsIScrollbarMediator::ScrollSnapMode aSnap =
258 nsIScrollbarMediator::DISABLE_SNAP);
259 void ScrollByCSSPixels(const CSSIntPoint& aDelta,
260 ScrollMode aMode = ScrollMode::Instant,
261 nsAtom* aOrigin = nullptr,
262 nsIScrollbarMediator::ScrollSnapMode aSnap =
263 nsIScrollbarMediator::DEFAULT);
265 * @note This method might destroy the frame, pres shell and other objects.
267 void ScrollToRestoredPosition();
269 enum class LoadingState { Loading, Stopped, Loaded };
271 LoadingState GetPageLoadingState();
274 * GetSnapPointForDestination determines which point to snap to after
275 * scrolling. aStartPos gives the position before scrolling and aDestination
276 * gives the position after scrolling, with no snapping. Behaviour is
277 * dependent on the value of aUnit.
278 * Returns true if a suitable snap point could be found and aDestination has
279 * been updated to a valid snapping position.
281 bool GetSnapPointForDestination(nsIScrollableFrame::ScrollUnit aUnit,
282 nsPoint aStartPos, nsPoint& aDestination);
284 nsMargin GetScrollPadding() const;
286 nsSize GetLineScrollAmount() const;
287 nsSize GetPageScrollAmount() const;
289 mozilla::UniquePtr<mozilla::PresState> SaveState() const;
290 void RestoreState(mozilla::PresState* aState);
292 nsIFrame* GetScrolledFrame() const { return mScrolledFrame; }
293 nsIFrame* GetScrollbarBox(bool aVertical) const {
294 return aVertical ? mVScrollbarBox : mHScrollbarBox;
297 void AddScrollPositionListener(nsIScrollPositionListener* aListener) {
298 mListeners.AppendElement(aListener);
300 void RemoveScrollPositionListener(nsIScrollPositionListener* aListener) {
301 mListeners.RemoveElement(aListener);
304 static void SetScrollbarVisibility(nsIFrame* aScrollbar, bool aVisible);
307 * GetScrolledRect is designed to encapsulate deciding which
308 * directions of overflow should be reachable by scrolling and which
309 * should not. Callers should NOT depend on it having any particular
310 * behavior (although nsXULScrollFrame currently does).
312 * This should only be called when the scrolled frame has been
313 * reflowed with the scroll port size given in mScrollPort.
315 * Currently it allows scrolling down and to the right for
316 * nsHTMLScrollFrames with LTR directionality and for all
317 * nsXULScrollFrames, and allows scrolling down and to the left for
318 * nsHTMLScrollFrames with RTL directionality.
320 nsRect GetScrolledRect() const;
323 * GetUnsnappedScrolledRectInternal is designed to encapsulate deciding which
324 * directions of overflow should be reachable by scrolling and which
325 * should not. Callers should NOT depend on it having any particular
326 * behavior (although nsXULScrollFrame currently does).
328 * Currently it allows scrolling down and to the right for
329 * nsHTMLScrollFrames with LTR directionality and for all
330 * nsXULScrollFrames, and allows scrolling down and to the left for
331 * nsHTMLScrollFrames with RTL directionality.
333 nsRect GetUnsnappedScrolledRectInternal(const nsRect& aScrolledOverflowArea,
334 const nsSize& aScrollPortSize) const;
336 uint32_t GetScrollbarVisibility() const {
337 return (mHasVerticalScrollbar ? nsIScrollableFrame::VERTICAL : 0) |
338 (mHasHorizontalScrollbar ? nsIScrollableFrame::HORIZONTAL : 0);
340 nsMargin GetActualScrollbarSizes() const;
341 nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState);
342 nscoord GetNondisappearingScrollbarWidth(nsBoxLayoutState* aState,
343 mozilla::WritingMode aVerticalWM);
344 bool IsPhysicalLTR() const {
345 WritingMode wm = GetFrameForDir()->GetWritingMode();
346 return wm.IsVertical() ? wm.IsVerticalLR() : wm.IsBidiLTR();
348 bool IsBidiLTR() const {
349 nsIFrame* frame = GetFrameForDir();
350 return frame->StyleVisibility()->mDirection == NS_STYLE_DIRECTION_LTR;
353 private:
354 nsIFrame* GetFrameForDir() const; // helper for Is{Physical,Bidi}LTR to find
355 // the frame whose directionality we use
356 // helper to find the frame that style data for this scrollable frame is
357 // stored.
359 // NOTE: Use GetFrameForDir() if you want to know `writing-mode` or `dir`
360 // properties. Use GetScrollStylesFromFrame() if you want to know `overflow`
361 // and `overflow-behavior` properties.
362 nsIFrame* GetFrameForStyle() const;
364 // This is the for the old unspecced scroll snap implementation.
365 ScrollSnapInfo ComputeOldScrollSnapInfo() const;
366 // This is the for the scroll snap v1 implementation.
367 ScrollSnapInfo ComputeScrollSnapInfo(
368 const Maybe<nsPoint>& aDestination) const;
370 bool NeedsScrollSnap() const;
372 public:
373 bool IsScrollbarOnRight() const;
374 bool IsScrollingActive(nsDisplayListBuilder* aBuilder) const;
375 bool IsMaybeAsynchronouslyScrolled() const {
376 // If this is true, then we'll build an ASR, and that's what we want
377 // to know I think.
378 return mWillBuildScrollableLayer;
380 bool IsMaybeScrollingActive() const;
381 bool IsProcessingAsyncScroll() const {
382 return mAsyncScroll != nullptr || mAsyncSmoothMSDScroll != nullptr;
384 void ResetScrollPositionForLayerPixelAlignment() {
385 mScrollPosForLayerPixelAlignment = GetScrollPosition();
388 bool ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas);
390 void UpdateSticky();
392 void UpdatePrevScrolledRect();
394 bool IsRectNearlyVisible(const nsRect& aRect) const;
395 nsRect ExpandRectToNearlyVisible(const nsRect& aRect) const;
397 // adjust the scrollbar rectangle aRect to account for any visible resizer.
398 // aHasResizer specifies if there is a content resizer, however this method
399 // will also check if a widget resizer is present as well.
400 void AdjustScrollbarRectForResizer(
401 nsIFrame* aFrame, nsPresContext* aPresContext, nsRect& aRect,
402 bool aHasResizer, mozilla::layers::ScrollDirection aDirection);
403 // returns true if a resizer should be visible
404 bool HasResizer() { return mResizerBox && !mCollapsedResizer; }
405 void LayoutScrollbars(nsBoxLayoutState& aState, const nsRect& aContentArea,
406 const nsRect& aOldScrollArea);
408 void MarkScrollbarsDirtyForReflow() const;
410 bool IsAlwaysActive() const;
411 void MarkEverScrolled();
412 void MarkRecentlyScrolled();
413 void MarkNotRecentlyScrolled();
414 nsExpirationState* GetExpirationState() { return &mActivityExpirationState; }
416 void SetTransformingByAPZ(bool aTransforming) {
417 if (mTransformingByAPZ && !aTransforming) {
418 PostScrollEndEvent();
420 mTransformingByAPZ = aTransforming;
421 if (!mozilla::css::TextOverflow::HasClippedTextOverflow(mOuter) ||
422 mozilla::css::TextOverflow::HasBlockEllipsis(mScrolledFrame)) {
423 // If the block has some overflow marker stuff we should kick off a paint
424 // because we have special behaviour for it when APZ scrolling is active.
425 mOuter->SchedulePaint();
428 bool IsTransformingByAPZ() const { return mTransformingByAPZ; }
429 void SetScrollableByAPZ(bool aScrollable);
430 void SetZoomableByAPZ(bool aZoomable);
431 void SetHasOutOfFlowContentInsideFilter();
433 bool UsesContainerScrolling() const;
435 bool UsesOverlayScrollbars() const;
437 // In the case where |aDestination| is given, elements which are entirely out
438 // of view when the scroll position is moved to |aDestination| are not going
439 // to be used for snap positions.
440 ScrollSnapInfo GetScrollSnapInfo(
441 const mozilla::Maybe<nsPoint>& aDestination) const;
443 bool DecideScrollableLayer(nsDisplayListBuilder* aBuilder,
444 nsRect* aVisibleRect, nsRect* aDirtyRect,
445 bool aSetBase,
446 bool* aDirtyRectHasBeenOverriden = nullptr);
447 void NotifyApzTransaction() {
448 mAllowScrollOriginDowngrade = true;
449 mApzScrollPos = GetScrollPosition();
451 void NotifyApproximateFrameVisibilityUpdate(bool aIgnoreDisplayPort);
452 bool GetDisplayPortAtLastApproximateFrameVisibilityUpdate(
453 nsRect* aDisplayPort);
455 bool AllowDisplayPortExpiration();
456 void TriggerDisplayPortExpiration();
457 void ResetDisplayPortExpiryTimer();
459 void ScheduleSyntheticMouseMove();
460 static void ScrollActivityCallback(nsITimer* aTimer, void* anInstance);
462 void HandleScrollbarStyleSwitching();
464 nsAtom* LastScrollOrigin() const { return mLastScrollOrigin; }
465 nsAtom* LastSmoothScrollOrigin() const { return mLastSmoothScrollOrigin; }
466 uint32_t CurrentScrollGeneration() const { return mScrollGeneration; }
467 nsPoint LastScrollDestination() const { return mDestination; }
468 void ResetScrollInfoIfGeneration(uint32_t aGeneration) {
469 if (aGeneration == mScrollGeneration) {
470 mLastScrollOrigin = nullptr;
471 mLastSmoothScrollOrigin = nullptr;
474 bool WantAsyncScroll() const;
475 Maybe<mozilla::layers::ScrollMetadata> ComputeScrollMetadata(
476 LayerManager* aLayerManager, const nsIFrame* aContainerReferenceFrame,
477 const Maybe<ContainerLayerParameters>& aParameters,
478 const mozilla::DisplayItemClip* aClip) const;
479 void ClipLayerToDisplayPort(
480 Layer* aLayer, const mozilla::DisplayItemClip* aClip,
481 const ContainerLayerParameters& aParameters) const;
483 // nsIScrollbarMediator
484 void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection,
485 nsIScrollbarMediator::ScrollSnapMode aSnap =
486 nsIScrollbarMediator::DISABLE_SNAP);
487 void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection,
488 nsIScrollbarMediator::ScrollSnapMode aSnap =
489 nsIScrollbarMediator::DISABLE_SNAP);
490 void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection,
491 nsIScrollbarMediator::ScrollSnapMode aSnap =
492 nsIScrollbarMediator::DISABLE_SNAP);
493 void RepeatButtonScroll(nsScrollbarFrame* aScrollbar);
494 void ThumbMoved(nsScrollbarFrame* aScrollbar, nscoord aOldPos,
495 nscoord aNewPos);
496 void ScrollbarReleased(nsScrollbarFrame* aScrollbar);
497 void ScrollByUnit(nsScrollbarFrame* aScrollbar, ScrollMode aMode,
498 int32_t aDirection, nsIScrollableFrame::ScrollUnit aUnit,
499 nsIScrollbarMediator::ScrollSnapMode aSnap =
500 nsIScrollbarMediator::DISABLE_SNAP);
501 bool ShouldSuppressScrollbarRepaints() const {
502 return mSuppressScrollbarRepaints;
505 bool DragScroll(WidgetEvent* aEvent);
507 void AsyncScrollbarDragInitiated(uint64_t aDragBlockId,
508 mozilla::layers::ScrollDirection aDirection);
509 void AsyncScrollbarDragRejected();
511 bool IsRootScrollFrameOfDocument() const { return mIsRoot; }
513 bool SmoothScrollVisual(
514 const nsPoint& aVisualViewportOffset,
515 mozilla::layers::FrameMetrics::ScrollOffsetUpdateType aUpdateType);
517 bool IsSmoothScroll(mozilla::dom::ScrollBehavior aBehavior) const;
519 // Update minimum-scale size. The minimum-scale size will be set/used only
520 // if there is overflow-x:hidden region.
521 void UpdateMinimumScaleSize(const nsRect& aScrollableOverflow,
522 const nsSize& aICBSize);
524 // Return the scroll frame's "true outer size".
525 // This is mOuter->GetSize(), except when mOuter has been sized to reflect
526 // a virtual (layout) viewport in which case this returns the outer size
527 // used to size the physical (visual) viewport.
528 nsSize TrueOuterSize() const;
530 already_AddRefed<Element> MakeScrollbar(dom::NodeInfo* aNodeInfo,
531 bool aVertical,
532 AnonymousContentKey& aKey);
534 // owning references to the nsIAnonymousContentCreator-built content
535 nsCOMPtr<mozilla::dom::Element> mHScrollbarContent;
536 nsCOMPtr<mozilla::dom::Element> mVScrollbarContent;
537 nsCOMPtr<mozilla::dom::Element> mScrollCornerContent;
538 nsCOMPtr<mozilla::dom::Element> mResizerContent;
540 class ScrollEvent;
541 class ScrollEndEvent;
542 class AsyncScrollPortEvent;
543 class ScrolledAreaEvent;
545 RefPtr<ScrollEvent> mScrollEvent;
546 RefPtr<ScrollEndEvent> mScrollEndEvent;
547 nsRevocableEventPtr<AsyncScrollPortEvent> mAsyncScrollPortEvent;
548 nsRevocableEventPtr<ScrolledAreaEvent> mScrolledAreaEvent;
549 nsIFrame* mHScrollbarBox;
550 nsIFrame* mVScrollbarBox;
551 nsIFrame* mScrolledFrame;
552 nsIFrame* mScrollCornerBox;
553 nsIFrame* mResizerBox;
554 nsContainerFrame* mOuter;
555 const nsIFrame* mReferenceFrameDuringPainting;
556 RefPtr<AsyncScroll> mAsyncScroll;
557 RefPtr<AsyncSmoothMSDScroll> mAsyncSmoothMSDScroll;
558 RefPtr<ScrollbarActivity> mScrollbarActivity;
559 nsTArray<nsIScrollPositionListener*> mListeners;
560 nsAtom* mLastScrollOrigin;
561 nsAtom* mLastSmoothScrollOrigin;
562 Maybe<nsPoint> mApzSmoothScrollDestination;
563 uint32_t mScrollGeneration;
564 // NOTE: On mobile this value might be factoring into overflow:hidden region
565 // in the case of the top level document.
566 nsRect mScrollPort;
567 nsSize mMinimumScaleSize;
569 // Stores the ICB size for the root document if this frame is using the
570 // minimum scale size for |mScrollPort|.
571 nsSize mICBSize;
573 // Where we're currently scrolling to, if we're scrolling asynchronously.
574 // If we're not in the middle of an asynchronous scroll then this is
575 // just the current scroll position. ScrollBy will choose its
576 // destination based on this value.
577 nsPoint mDestination;
579 // A goal position to try to scroll to as content loads. As long as mLastPos
580 // matches the current logical scroll position, we try to scroll to
581 // mRestorePos after every reflow --- because after each time content is
582 // loaded/added to the scrollable element, there will be a reflow.
583 // Note that for frames where layout and visual viewport aren't one and the
584 // same thing, this scroll position will be the logical scroll position of
585 // the *visual* viewport, as its position will be more relevant to the user.
586 nsPoint mRestorePos;
587 // The last logical position we scrolled to while trying to restore
588 // mRestorePos, or 0,0 when this is a new frame. Set to -1,-1 once we've
589 // scrolled for any reason other than trying to restore mRestorePos.
590 // Just as with mRestorePos, this position will be the logical position of
591 // the *visual* viewport where available.
592 nsPoint mLastPos;
594 // The latest scroll position we've sent or received from APZ. This
595 // represents the main thread's best knowledge of the APZ scroll position,
596 // and is used to calculate relative scroll offset updates.
597 nsPoint mApzScrollPos;
599 nsExpirationState mActivityExpirationState;
601 nsCOMPtr<nsITimer> mScrollActivityTimer;
602 nsPoint mScrollPosForLayerPixelAlignment;
604 // The scroll position where we last updated frame visibility.
605 nsPoint mLastUpdateFramesPos;
606 nsRect mDisplayPortAtLastFrameUpdate;
608 nsRect mPrevScrolledRect;
610 ScrollableLayerGuid::ViewID mScrollParentID;
612 // Timer to remove the displayport some time after scrolling has stopped
613 nsCOMPtr<nsITimer> mDisplayPortExpiryTimer;
615 ScrollAnchorContainer mAnchor;
617 bool mAllowScrollOriginDowngrade : 1;
618 bool mHadDisplayPortAtLastFrameUpdate : 1;
619 bool mNeverHasVerticalScrollbar : 1;
620 bool mNeverHasHorizontalScrollbar : 1;
621 bool mHasVerticalScrollbar : 1;
622 bool mHasHorizontalScrollbar : 1;
623 bool mFrameIsUpdatingScrollbar : 1;
624 bool mDidHistoryRestore : 1;
625 // Is this the scrollframe for the document's viewport?
626 bool mIsRoot : 1;
627 // True if we should clip all descendants, false if we should only clip
628 // descendants for which we are the containing block.
629 bool mClipAllDescendants : 1;
630 // If true, don't try to layout the scrollbars in Reflow(). This can be
631 // useful if multiple passes are involved, because we don't want to place the
632 // scrollbars at the wrong size.
633 bool mSuppressScrollbarUpdate : 1;
634 // If true, we skipped a scrollbar layout due to mSuppressScrollbarUpdate
635 // being set at some point. That means we should lay out scrollbars even if
636 // it might not strictly be needed next time mSuppressScrollbarUpdate is
637 // false.
638 bool mSkippedScrollbarLayout : 1;
640 bool mHadNonInitialReflow : 1;
641 // State used only by PostScrollEvents so we know
642 // which overflow states have changed.
643 bool mHorizontalOverflow : 1;
644 bool mVerticalOverflow : 1;
645 bool mPostedReflowCallback : 1;
646 bool mMayHaveDirtyFixedChildren : 1;
647 // If true, need to actually update our scrollbar attributes in the
648 // reflow callback.
649 bool mUpdateScrollbarAttributes : 1;
650 // If true, we should be prepared to scroll using this scrollframe
651 // by placing descendant content into its own layer(s)
652 bool mHasBeenScrolledRecently : 1;
653 // If true, the resizer is collapsed and not displayed
654 bool mCollapsedResizer : 1;
656 // If true, the scroll frame should always be active because we always build
657 // a scrollable layer. Used for asynchronous scrolling.
658 bool mWillBuildScrollableLayer : 1;
660 // If true, the scroll frame is an ancestor of other scrolling frames, so
661 // we shouldn't expire the displayport on this scrollframe unless those
662 // descendant scrollframes also have their displayports removed.
663 bool mIsScrollParent : 1;
665 // Whether we are the root scroll frame that is used for containerful
666 // scrolling with a display port. If true, the scrollable frame
667 // shouldn't attach frame metrics to its layers because the container
668 // will already have the necessary frame metrics.
669 bool mIsScrollableLayerInRootContainer : 1;
671 // If true, add clipping in ScrollFrameHelper::ClipLayerToDisplayPort.
672 bool mAddClipRectToLayer : 1;
674 // True if this frame has been scrolled at least once
675 bool mHasBeenScrolled : 1;
677 // True if the events synthesized by OSX to produce momentum scrolling should
678 // be ignored. Reset when the next real, non-synthesized scroll event occurs.
679 bool mIgnoreMomentumScroll : 1;
681 // True if the APZ is in the process of async-transforming this scrollframe,
682 // (as best as we can tell on the main thread, anyway).
683 bool mTransformingByAPZ : 1;
685 // True if APZ can scroll this frame asynchronously (i.e. it has an APZC
686 // set up for this frame and it's not a scrollinfo layer).
687 bool mScrollableByAPZ : 1;
689 // True if the APZ is allowed to zoom this scrollframe.
690 bool mZoomableByAPZ : 1;
692 // True if the scroll frame contains out-of-flow content and is inside
693 // a CSS filter.
694 bool mHasOutOfFlowContentInsideFilter : 1;
696 // True if we don't want the scrollbar to repaint itself right now.
697 bool mSuppressScrollbarRepaints : 1;
699 // True if we are using the minimum scale size instead of ICB for scroll port.
700 bool mIsUsingMinimumScaleSize : 1;
702 // True if the minimum scale size has been changed since the last reflow.
703 bool mMinimumScaleSizeChanged : 1;
705 // True if we're processing an scroll event.
706 bool mProcessingScrollEvent : 1;
708 mozilla::layout::ScrollVelocityQueue mVelocityQueue;
710 protected:
711 class AutoScrollbarRepaintSuppression;
712 friend class AutoScrollbarRepaintSuppression;
713 class AutoScrollbarRepaintSuppression {
714 public:
715 AutoScrollbarRepaintSuppression(ScrollFrameHelper* aHelper, bool aSuppress)
716 : mHelper(aHelper),
717 mOldSuppressValue(aHelper->mSuppressScrollbarRepaints) {
718 mHelper->mSuppressScrollbarRepaints = aSuppress;
721 ~AutoScrollbarRepaintSuppression() {
722 mHelper->mSuppressScrollbarRepaints = mOldSuppressValue;
725 private:
726 ScrollFrameHelper* mHelper;
727 bool mOldSuppressValue;
731 * @note This method might destroy the frame, pres shell and other objects.
733 void ScrollToWithOrigin(nsPoint aScrollPosition, ScrollMode aMode,
734 nsAtom* aOrigin, // nullptr indicates "other" origin
735 const nsRect* aRange,
736 nsIScrollbarMediator::ScrollSnapMode aSnap =
737 nsIScrollbarMediator::DISABLE_SNAP);
739 void CompleteAsyncScroll(const nsRect& aRange, nsAtom* aOrigin = nullptr);
741 bool HasPluginFrames();
742 bool HasPerspective() const { return mOuter->ChildrenHavePerspective(); }
743 bool HasBgAttachmentLocal() const;
744 uint8_t GetScrolledFrameDir() const;
746 bool IsForTextControlWithNoScrollbars() const;
748 // Ask APZ to smooth scroll to |aDestination|.
749 // This method does not clamp the destination; callers should clamp it to
750 // either the layout or the visual scroll range (APZ will happily smooth
751 // scroll to either).
752 void ApzSmoothScrollTo(const nsPoint& aDestination, nsAtom* aOrigin);
754 // Removes any RefreshDriver observers we might have registered.
755 void RemoveObservers();
757 static void EnsureFrameVisPrefsCached();
758 static bool sFrameVisPrefsCached;
759 // The number of scrollports wide/high to expand when tracking frame
760 // visibility.
761 static uint32_t sHorzExpandScrollPort;
762 static uint32_t sVertExpandScrollPort;
765 } // namespace mozilla
768 * The scroll frame creates and manages the scrolling view
770 * It only supports having a single child frame that typically is an area
771 * frame, but doesn't have to be. The child frame must have a view, though
773 * Scroll frames don't support incremental changes, i.e. you can't replace
774 * or remove the scrolled frame
776 class nsHTMLScrollFrame : public nsContainerFrame,
777 public nsIScrollableFrame,
778 public nsIAnonymousContentCreator,
779 public nsIStatefulFrame {
780 public:
781 typedef mozilla::ScrollFrameHelper ScrollFrameHelper;
782 typedef mozilla::CSSIntPoint CSSIntPoint;
783 typedef mozilla::ScrollReflowInput ScrollReflowInput;
784 typedef mozilla::layout::ScrollAnchorContainer ScrollAnchorContainer;
785 friend nsHTMLScrollFrame* NS_NewHTMLScrollFrame(
786 mozilla::PresShell* aPresShell, ComputedStyle* aStyle, bool aIsRoot);
788 NS_DECL_QUERYFRAME
789 NS_DECL_FRAMEARENA_HELPERS(nsHTMLScrollFrame)
791 virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
792 const nsDisplayListSet& aLists) override {
793 mHelper.BuildDisplayList(aBuilder, aLists);
796 bool TryLayout(ScrollReflowInput* aState, ReflowOutput* aKidMetrics,
797 bool aAssumeVScroll, bool aAssumeHScroll, bool aForce);
798 bool ScrolledContentDependsOnHeight(ScrollReflowInput* aState);
799 void ReflowScrolledFrame(ScrollReflowInput* aState, bool aAssumeHScroll,
800 bool aAssumeVScroll, ReflowOutput* aMetrics);
801 void ReflowContents(ScrollReflowInput* aState,
802 const ReflowOutput& aDesiredSize);
803 void PlaceScrollArea(ScrollReflowInput& aState,
804 const nsPoint& aScrollPosition);
805 nscoord GetIntrinsicVScrollbarWidth(gfxContext* aRenderingContext);
807 virtual bool GetBorderRadii(const nsSize& aFrameSize,
808 const nsSize& aBorderArea, Sides aSkipSides,
809 nscoord aRadii[8]) const override {
810 return mHelper.GetBorderRadii(aFrameSize, aBorderArea, aSkipSides, aRadii);
813 virtual nscoord GetMinISize(gfxContext* aRenderingContext) override;
814 virtual nscoord GetPrefISize(gfxContext* aRenderingContext) override;
815 virtual nsresult GetXULPadding(nsMargin& aPadding) override;
816 virtual bool IsXULCollapsed() override;
818 virtual void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
819 const ReflowInput& aReflowInput,
820 nsReflowStatus& aStatus) override;
821 virtual void DidReflow(nsPresContext* aPresContext,
822 const ReflowInput* aReflowInput) override;
824 virtual bool ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas) override {
825 return mHelper.ComputeCustomOverflow(aOverflowAreas);
828 nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode) const override;
830 bool GetVerticalAlignBaseline(mozilla::WritingMode aWM,
831 nscoord* aBaseline) const override {
832 NS_ASSERTION(!aWM.IsOrthogonalTo(GetWritingMode()),
833 "You should only call this on frames with a WM that's "
834 "parallel to aWM");
835 *aBaseline = GetLogicalBaseline(aWM);
836 return true;
839 // Recomputes the scrollable overflow area we store in the helper to take
840 // children that are affected by perpsective set on the outer frame and scroll
841 // at different rates.
842 void AdjustForPerspective(nsRect& aScrollableOverflow);
844 // Called to set the child frames. We typically have three: the scroll area,
845 // the vertical scrollbar, and the horizontal scrollbar.
846 virtual void SetInitialChildList(ChildListID aListID,
847 nsFrameList& aChildList) override;
848 virtual void AppendFrames(ChildListID aListID,
849 nsFrameList& aFrameList) override;
850 virtual void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
851 const nsLineList::iterator* aPrevFrameLine,
852 nsFrameList& aFrameList) override;
853 virtual void RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) override;
855 virtual void DestroyFrom(nsIFrame* aDestructRoot,
856 PostDestroyData& aPostDestroyData) override;
858 virtual nsIScrollableFrame* GetScrollTargetFrame() override { return this; }
860 virtual nsContainerFrame* GetContentInsertionFrame() override {
861 return mHelper.GetScrolledFrame()->GetContentInsertionFrame();
864 virtual bool DoesClipChildren() override { return true; }
866 nsPoint GetPositionOfChildIgnoringScrolling(const nsIFrame* aChild) override {
867 nsPoint pt = aChild->GetPosition();
868 if (aChild == mHelper.GetScrolledFrame()) pt += GetScrollPosition();
869 return pt;
872 // nsIAnonymousContentCreator
873 virtual nsresult CreateAnonymousContent(
874 nsTArray<ContentInfo>& aElements) override;
875 virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
876 uint32_t aFilter) override;
878 // nsIScrollableFrame
879 virtual nsIFrame* GetScrolledFrame() const override {
880 return mHelper.GetScrolledFrame();
882 virtual mozilla::ScrollStyles GetScrollStyles() const override {
883 return mHelper.GetScrollStylesFromFrame();
885 virtual uint32_t GetScrollbarVisibility() const override {
886 return mHelper.GetScrollbarVisibility();
888 virtual nsMargin GetActualScrollbarSizes() const override {
889 return mHelper.GetActualScrollbarSizes();
891 virtual nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState) override {
892 return mHelper.GetDesiredScrollbarSizes(aState);
894 virtual nsMargin GetDesiredScrollbarSizes(nsPresContext* aPresContext,
895 gfxContext* aRC) override {
896 nsBoxLayoutState bls(aPresContext, aRC, 0);
897 return GetDesiredScrollbarSizes(&bls);
899 virtual nscoord GetNondisappearingScrollbarWidth(
900 nsPresContext* aPresContext, gfxContext* aRC,
901 mozilla::WritingMode aWM) override {
902 nsBoxLayoutState bls(aPresContext, aRC, 0);
903 return mHelper.GetNondisappearingScrollbarWidth(&bls, aWM);
905 virtual nsSize GetLayoutSize() const override {
906 return mHelper.GetLayoutSize();
908 virtual nsRect GetScrolledRect() const override {
909 return mHelper.GetScrolledRect();
911 virtual nsRect GetScrollPortRect() const override {
912 return mHelper.GetScrollPortRect();
914 virtual nsPoint GetScrollPosition() const override {
915 return mHelper.GetScrollPosition();
917 virtual nsPoint GetLogicalScrollPosition() const override {
918 return mHelper.GetLogicalScrollPosition();
920 virtual nsPoint GetApzScrollPosition() const override {
921 return mHelper.GetApzScrollPosition();
923 virtual nsRect GetScrollRange() const override {
924 return mHelper.GetLayoutScrollRange();
926 virtual nsSize GetVisualViewportSize() const override {
927 return mHelper.GetVisualViewportSize();
929 virtual nsPoint GetVisualViewportOffset() const override {
930 return mHelper.GetVisualViewportOffset();
932 virtual nsSize GetLineScrollAmount() const override {
933 return mHelper.GetLineScrollAmount();
935 virtual nsSize GetPageScrollAmount() const override {
936 return mHelper.GetPageScrollAmount();
938 virtual nsMargin GetScrollPadding() const override {
939 return mHelper.GetScrollPadding();
942 * @note This method might destroy the frame, pres shell and other objects.
944 virtual void ScrollTo(nsPoint aScrollPosition, ScrollMode aMode,
945 const nsRect* aRange = nullptr,
946 nsIScrollbarMediator::ScrollSnapMode aSnap =
947 nsIScrollbarMediator::DISABLE_SNAP) override {
948 mHelper.ScrollTo(aScrollPosition, aMode, nsGkAtoms::other, aRange, aSnap);
951 * @note This method might destroy the frame, pres shell and other objects.
953 virtual void ScrollToCSSPixels(const CSSIntPoint& aScrollPosition,
954 ScrollMode aMode = ScrollMode::Instant,
955 nsIScrollbarMediator::ScrollSnapMode aSnap =
956 nsIScrollbarMediator::DEFAULT,
957 nsAtom* aOrigin = nullptr) override {
958 mHelper.ScrollToCSSPixels(aScrollPosition, aMode, aSnap, aOrigin);
960 virtual void ScrollToCSSPixelsApproximate(
961 const mozilla::CSSPoint& aScrollPosition,
962 nsAtom* aOrigin = nullptr) override {
963 mHelper.ScrollToCSSPixelsApproximate(aScrollPosition, aOrigin);
966 * @note This method might destroy the frame, pres shell and other objects.
968 virtual CSSIntPoint GetScrollPositionCSSPixels() override {
969 return mHelper.GetScrollPositionCSSPixels();
972 * @note This method might destroy the frame, pres shell and other objects.
974 virtual void ScrollBy(nsIntPoint aDelta, ScrollUnit aUnit, ScrollMode aMode,
975 nsIntPoint* aOverflow, nsAtom* aOrigin = nullptr,
976 nsIScrollableFrame::ScrollMomentum aMomentum =
977 nsIScrollableFrame::NOT_MOMENTUM,
978 nsIScrollbarMediator::ScrollSnapMode aSnap =
979 nsIScrollbarMediator::DISABLE_SNAP) override {
980 mHelper.ScrollBy(aDelta, aUnit, aMode, aOverflow, aOrigin, aMomentum,
981 aSnap);
983 virtual void ScrollByCSSPixels(const CSSIntPoint& aDelta,
984 ScrollMode aMode = ScrollMode::Instant,
985 nsAtom* aOrigin = nullptr,
986 nsIScrollbarMediator::ScrollSnapMode aSnap =
987 nsIScrollbarMediator::DEFAULT) override {
988 mHelper.ScrollByCSSPixels(aDelta, aMode, aOrigin, aSnap);
990 virtual void ScrollSnap() override { mHelper.ScrollSnap(); }
992 * @note This method might destroy the frame, pres shell and other objects.
994 virtual void ScrollToRestoredPosition() override {
995 mHelper.ScrollToRestoredPosition();
997 virtual void AddScrollPositionListener(
998 nsIScrollPositionListener* aListener) override {
999 mHelper.AddScrollPositionListener(aListener);
1001 virtual void RemoveScrollPositionListener(
1002 nsIScrollPositionListener* aListener) override {
1003 mHelper.RemoveScrollPositionListener(aListener);
1006 * @note This method might destroy the frame, pres shell and other objects.
1008 virtual void CurPosAttributeChanged(nsIContent* aChild) override {
1009 mHelper.CurPosAttributeChanged(aChild);
1011 NS_IMETHOD PostScrolledAreaEventForCurrentArea() override {
1012 mHelper.PostScrolledAreaEvent();
1013 return NS_OK;
1015 virtual bool IsScrollingActive(nsDisplayListBuilder* aBuilder) override {
1016 return mHelper.IsScrollingActive(aBuilder);
1018 virtual bool IsMaybeScrollingActive() const override {
1019 return mHelper.IsMaybeScrollingActive();
1021 virtual bool IsMaybeAsynchronouslyScrolled() override {
1022 return mHelper.IsMaybeAsynchronouslyScrolled();
1024 virtual bool IsProcessingAsyncScroll() override {
1025 return mHelper.IsProcessingAsyncScroll();
1027 virtual void ResetScrollPositionForLayerPixelAlignment() override {
1028 mHelper.ResetScrollPositionForLayerPixelAlignment();
1030 virtual bool DidHistoryRestore() const override {
1031 return mHelper.mDidHistoryRestore;
1033 virtual void ClearDidHistoryRestore() override {
1034 mHelper.mDidHistoryRestore = false;
1036 virtual void MarkEverScrolled() override { mHelper.MarkEverScrolled(); }
1037 virtual bool IsRectNearlyVisible(const nsRect& aRect) override {
1038 return mHelper.IsRectNearlyVisible(aRect);
1040 virtual nsRect ExpandRectToNearlyVisible(const nsRect& aRect) const override {
1041 return mHelper.ExpandRectToNearlyVisible(aRect);
1043 virtual nsAtom* LastScrollOrigin() override {
1044 return mHelper.LastScrollOrigin();
1046 virtual nsAtom* LastSmoothScrollOrigin() override {
1047 return mHelper.LastSmoothScrollOrigin();
1049 virtual uint32_t CurrentScrollGeneration() override {
1050 return mHelper.CurrentScrollGeneration();
1052 virtual nsPoint LastScrollDestination() override {
1053 return mHelper.LastScrollDestination();
1055 virtual void ResetScrollInfoIfGeneration(uint32_t aGeneration) override {
1056 mHelper.ResetScrollInfoIfGeneration(aGeneration);
1058 virtual bool WantAsyncScroll() const override {
1059 return mHelper.WantAsyncScroll();
1061 virtual mozilla::Maybe<mozilla::layers::ScrollMetadata> ComputeScrollMetadata(
1062 LayerManager* aLayerManager, const nsIFrame* aContainerReferenceFrame,
1063 const Maybe<ContainerLayerParameters>& aParameters,
1064 const mozilla::DisplayItemClip* aClip) const override {
1065 return mHelper.ComputeScrollMetadata(
1066 aLayerManager, aContainerReferenceFrame, aParameters, aClip);
1068 virtual void ClipLayerToDisplayPort(
1069 Layer* aLayer, const mozilla::DisplayItemClip* aClip,
1070 const ContainerLayerParameters& aParameters) const override {
1071 mHelper.ClipLayerToDisplayPort(aLayer, aClip, aParameters);
1073 virtual void MarkScrollbarsDirtyForReflow() const override {
1074 mHelper.MarkScrollbarsDirtyForReflow();
1076 virtual bool UsesContainerScrolling() const override {
1077 return mHelper.UsesContainerScrolling();
1079 virtual bool DecideScrollableLayer(nsDisplayListBuilder* aBuilder,
1080 nsRect* aVisibleRect, nsRect* aDirtyRect,
1081 bool aSetBase) override {
1082 return mHelper.DecideScrollableLayer(aBuilder, aVisibleRect, aDirtyRect,
1083 aSetBase);
1085 virtual void NotifyApzTransaction() override {
1086 mHelper.NotifyApzTransaction();
1088 virtual void NotifyApproximateFrameVisibilityUpdate(
1089 bool aIgnoreDisplayPort) override {
1090 mHelper.NotifyApproximateFrameVisibilityUpdate(aIgnoreDisplayPort);
1092 virtual bool GetDisplayPortAtLastApproximateFrameVisibilityUpdate(
1093 nsRect* aDisplayPort) override {
1094 return mHelper.GetDisplayPortAtLastApproximateFrameVisibilityUpdate(
1095 aDisplayPort);
1097 void TriggerDisplayPortExpiration() override {
1098 mHelper.TriggerDisplayPortExpiration();
1101 // nsIStatefulFrame
1102 mozilla::UniquePtr<mozilla::PresState> SaveState() override {
1103 return mHelper.SaveState();
1105 NS_IMETHOD RestoreState(mozilla::PresState* aState) override {
1106 NS_ENSURE_ARG_POINTER(aState);
1107 mHelper.RestoreState(aState);
1108 return NS_OK;
1111 // nsIScrollbarMediator
1112 virtual void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection,
1113 nsIScrollbarMediator::ScrollSnapMode aSnap =
1114 nsIScrollbarMediator::DISABLE_SNAP) override {
1115 mHelper.ScrollByPage(aScrollbar, aDirection, aSnap);
1117 virtual void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection,
1118 nsIScrollbarMediator::ScrollSnapMode aSnap =
1119 nsIScrollbarMediator::DISABLE_SNAP) override {
1120 mHelper.ScrollByWhole(aScrollbar, aDirection, aSnap);
1122 virtual void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection,
1123 nsIScrollbarMediator::ScrollSnapMode aSnap =
1124 nsIScrollbarMediator::DISABLE_SNAP) override {
1125 mHelper.ScrollByLine(aScrollbar, aDirection, aSnap);
1127 virtual void RepeatButtonScroll(nsScrollbarFrame* aScrollbar) override {
1128 mHelper.RepeatButtonScroll(aScrollbar);
1130 virtual void ThumbMoved(nsScrollbarFrame* aScrollbar, nscoord aOldPos,
1131 nscoord aNewPos) override {
1132 mHelper.ThumbMoved(aScrollbar, aOldPos, aNewPos);
1134 virtual void ScrollbarReleased(nsScrollbarFrame* aScrollbar) override {
1135 mHelper.ScrollbarReleased(aScrollbar);
1137 virtual void VisibilityChanged(bool aVisible) override {}
1138 virtual nsIFrame* GetScrollbarBox(bool aVertical) override {
1139 return mHelper.GetScrollbarBox(aVertical);
1141 virtual void ScrollbarActivityStarted() const override;
1142 virtual void ScrollbarActivityStopped() const override;
1144 virtual bool IsScrollbarOnRight() const override {
1145 return mHelper.IsScrollbarOnRight();
1148 virtual bool ShouldSuppressScrollbarRepaints() const override {
1149 return mHelper.ShouldSuppressScrollbarRepaints();
1152 virtual void SetTransformingByAPZ(bool aTransforming) override {
1153 mHelper.SetTransformingByAPZ(aTransforming);
1155 bool IsTransformingByAPZ() const override {
1156 return mHelper.IsTransformingByAPZ();
1158 void SetScrollableByAPZ(bool aScrollable) override {
1159 mHelper.SetScrollableByAPZ(aScrollable);
1161 void SetZoomableByAPZ(bool aZoomable) override {
1162 mHelper.SetZoomableByAPZ(aZoomable);
1164 void SetHasOutOfFlowContentInsideFilter() override {
1165 mHelper.SetHasOutOfFlowContentInsideFilter();
1168 ScrollSnapInfo GetScrollSnapInfo() const override {
1169 return mHelper.GetScrollSnapInfo(Nothing());
1172 virtual bool DragScroll(mozilla::WidgetEvent* aEvent) override {
1173 return mHelper.DragScroll(aEvent);
1176 virtual void AsyncScrollbarDragInitiated(
1177 uint64_t aDragBlockId,
1178 mozilla::layers::ScrollDirection aDirection) override {
1179 return mHelper.AsyncScrollbarDragInitiated(aDragBlockId, aDirection);
1182 virtual void AsyncScrollbarDragRejected() override {
1183 return mHelper.AsyncScrollbarDragRejected();
1186 virtual bool IsRootScrollFrameOfDocument() const override {
1187 return mHelper.IsRootScrollFrameOfDocument();
1190 virtual const ScrollAnchorContainer* Anchor() const override {
1191 return &mHelper.mAnchor;
1194 virtual ScrollAnchorContainer* Anchor() override { return &mHelper.mAnchor; }
1196 // Return the scrolled frame.
1197 void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) override {
1198 aResult.AppendElement(OwnedAnonBox(mHelper.GetScrolledFrame()));
1201 bool SmoothScrollVisual(const nsPoint& aVisualViewportOffset,
1202 mozilla::layers::FrameMetrics::ScrollOffsetUpdateType
1203 aUpdateType) override {
1204 return mHelper.SmoothScrollVisual(aVisualViewportOffset, aUpdateType);
1207 bool IsSmoothScroll(mozilla::dom::ScrollBehavior aBehavior) const override {
1208 return mHelper.IsSmoothScroll(aBehavior);
1211 #ifdef DEBUG_FRAME_DUMP
1212 virtual nsresult GetFrameName(nsAString& aResult) const override;
1213 #endif
1215 #ifdef ACCESSIBILITY
1216 virtual mozilla::a11y::AccType AccessibleType() override;
1217 #endif
1219 protected:
1220 nsHTMLScrollFrame(ComputedStyle* aStyle, nsPresContext* aPresContext,
1221 bool aIsRoot)
1222 : nsHTMLScrollFrame(aStyle, aPresContext, kClassID, aIsRoot) {}
1224 nsHTMLScrollFrame(ComputedStyle* aStyle, nsPresContext* aPresContext,
1225 nsIFrame::ClassID aID, bool aIsRoot);
1226 void SetSuppressScrollbarUpdate(bool aSuppress) {
1227 mHelper.mSuppressScrollbarUpdate = aSuppress;
1229 bool GuessHScrollbarNeeded(const ScrollReflowInput& aState);
1230 bool GuessVScrollbarNeeded(const ScrollReflowInput& aState);
1232 bool IsScrollbarUpdateSuppressed() const {
1233 return mHelper.mSuppressScrollbarUpdate;
1236 // Return whether we're in an "initial" reflow. Some reflows with
1237 // NS_FRAME_FIRST_REFLOW set are NOT "initial" as far as we're concerned.
1238 bool InInitialReflow() const;
1241 * Override this to return false if computed bsize/min-bsize/max-bsize
1242 * should NOT be propagated to child content.
1243 * nsListControlFrame uses this.
1245 virtual bool ShouldPropagateComputedBSizeToScrolledContent() const {
1246 return true;
1249 private:
1250 friend class mozilla::ScrollFrameHelper;
1251 ScrollFrameHelper mHelper;
1255 * The scroll frame creates and manages the scrolling view
1257 * It only supports having a single child frame that typically is an area
1258 * frame, but doesn't have to be. The child frame must have a view, though
1260 * Scroll frames don't support incremental changes, i.e. you can't replace
1261 * or remove the scrolled frame
1263 class nsXULScrollFrame final : public nsBoxFrame,
1264 public nsIScrollableFrame,
1265 public nsIAnonymousContentCreator,
1266 public nsIStatefulFrame {
1267 public:
1268 typedef mozilla::ScrollFrameHelper ScrollFrameHelper;
1269 typedef mozilla::CSSIntPoint CSSIntPoint;
1270 typedef mozilla::layout::ScrollAnchorContainer ScrollAnchorContainer;
1272 NS_DECL_QUERYFRAME
1273 NS_DECL_FRAMEARENA_HELPERS(nsXULScrollFrame)
1275 friend nsXULScrollFrame* NS_NewXULScrollFrame(mozilla::PresShell* aPresShell,
1276 ComputedStyle* aStyle,
1277 bool aIsRoot,
1278 bool aClipAllDescendants);
1280 virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
1281 const nsDisplayListSet& aLists) override {
1282 mHelper.BuildDisplayList(aBuilder, aLists);
1285 // XXXldb Is this actually used?
1286 #if 0
1287 virtual nscoord GetMinISize(gfxContext *aRenderingContext) override;
1288 #endif
1290 virtual bool ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas) override {
1291 return mHelper.ComputeCustomOverflow(aOverflowAreas);
1294 bool GetVerticalAlignBaseline(mozilla::WritingMode aWM,
1295 nscoord* aBaseline) const override {
1296 *aBaseline = GetLogicalBaseline(aWM);
1297 return true;
1300 // Called to set the child frames. We typically have three: the scroll area,
1301 // the vertical scrollbar, and the horizontal scrollbar.
1302 virtual void SetInitialChildList(ChildListID aListID,
1303 nsFrameList& aChildList) override;
1304 virtual void AppendFrames(ChildListID aListID,
1305 nsFrameList& aFrameList) override;
1306 virtual void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
1307 const nsLineList::iterator* aPrevFrameLine,
1308 nsFrameList& aFrameList) override;
1309 virtual void RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) override;
1311 virtual void DestroyFrom(nsIFrame* aDestructRoot,
1312 PostDestroyData& aPostDestroyData) override;
1314 virtual nsIScrollableFrame* GetScrollTargetFrame() override { return this; }
1316 virtual nsContainerFrame* GetContentInsertionFrame() override {
1317 return mHelper.GetScrolledFrame()->GetContentInsertionFrame();
1320 virtual bool DoesClipChildren() override { return true; }
1322 nsPoint GetPositionOfChildIgnoringScrolling(const nsIFrame* aChild) override {
1323 nsPoint pt = aChild->GetPosition();
1324 if (aChild == mHelper.GetScrolledFrame())
1325 pt += mHelper.GetLogicalScrollPosition();
1326 return pt;
1329 // nsIAnonymousContentCreator
1330 virtual nsresult CreateAnonymousContent(
1331 nsTArray<ContentInfo>& aElements) override;
1332 virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
1333 uint32_t aFilter) override;
1335 virtual nsSize GetXULMinSize(nsBoxLayoutState& aBoxLayoutState) override;
1336 virtual nsSize GetXULPrefSize(nsBoxLayoutState& aBoxLayoutState) override;
1337 virtual nsSize GetXULMaxSize(nsBoxLayoutState& aBoxLayoutState) override;
1338 virtual nscoord GetXULBoxAscent(nsBoxLayoutState& aBoxLayoutState) override;
1340 NS_IMETHOD DoXULLayout(nsBoxLayoutState& aBoxLayoutState) override;
1341 virtual nsresult GetXULPadding(nsMargin& aPadding) override;
1343 virtual bool GetBorderRadii(const nsSize& aFrameSize,
1344 const nsSize& aBorderArea, Sides aSkipSides,
1345 nscoord aRadii[8]) const override {
1346 return mHelper.GetBorderRadii(aFrameSize, aBorderArea, aSkipSides, aRadii);
1349 nsresult XULLayout(nsBoxLayoutState& aState);
1350 void LayoutScrollArea(nsBoxLayoutState& aState,
1351 const nsPoint& aScrollPosition);
1353 static bool AddRemoveScrollbar(bool& aHasScrollbar, nscoord& aXY,
1354 nscoord& aSize, nscoord aSbSize,
1355 bool aOnRightOrBottom, bool aAdd);
1357 bool AddRemoveScrollbar(nsBoxLayoutState& aState, bool aOnRightOrBottom,
1358 bool aHorizontal, bool aAdd);
1360 bool AddHorizontalScrollbar(nsBoxLayoutState& aState, bool aOnBottom);
1361 bool AddVerticalScrollbar(nsBoxLayoutState& aState, bool aOnRight);
1362 void RemoveHorizontalScrollbar(nsBoxLayoutState& aState, bool aOnBottom);
1363 void RemoveVerticalScrollbar(nsBoxLayoutState& aState, bool aOnRight);
1365 static void AdjustReflowInputForPrintPreview(nsBoxLayoutState& aState,
1366 bool& aSetBack);
1367 static void AdjustReflowInputBack(nsBoxLayoutState& aState, bool aSetBack);
1369 // nsIScrollableFrame
1370 virtual nsIFrame* GetScrolledFrame() const override {
1371 return mHelper.GetScrolledFrame();
1373 virtual mozilla::ScrollStyles GetScrollStyles() const override {
1374 return mHelper.GetScrollStylesFromFrame();
1376 virtual uint32_t GetScrollbarVisibility() const override {
1377 return mHelper.GetScrollbarVisibility();
1379 virtual nsMargin GetActualScrollbarSizes() const override {
1380 return mHelper.GetActualScrollbarSizes();
1382 virtual nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState) override {
1383 return mHelper.GetDesiredScrollbarSizes(aState);
1385 virtual nsMargin GetDesiredScrollbarSizes(nsPresContext* aPresContext,
1386 gfxContext* aRC) override {
1387 nsBoxLayoutState bls(aPresContext, aRC, 0);
1388 return GetDesiredScrollbarSizes(&bls);
1390 virtual nscoord GetNondisappearingScrollbarWidth(
1391 nsPresContext* aPresContext, gfxContext* aRC,
1392 mozilla::WritingMode aWM) override {
1393 nsBoxLayoutState bls(aPresContext, aRC, 0);
1394 return mHelper.GetNondisappearingScrollbarWidth(&bls, aWM);
1396 virtual nsSize GetLayoutSize() const override {
1397 return mHelper.GetLayoutSize();
1399 virtual nsRect GetScrolledRect() const override {
1400 return mHelper.GetScrolledRect();
1402 virtual nsRect GetScrollPortRect() const override {
1403 return mHelper.GetScrollPortRect();
1405 virtual nsPoint GetScrollPosition() const override {
1406 return mHelper.GetScrollPosition();
1408 virtual nsPoint GetLogicalScrollPosition() const override {
1409 return mHelper.GetLogicalScrollPosition();
1411 virtual nsPoint GetApzScrollPosition() const override {
1412 return mHelper.GetApzScrollPosition();
1414 virtual nsRect GetScrollRange() const override {
1415 return mHelper.GetLayoutScrollRange();
1417 virtual nsSize GetVisualViewportSize() const override {
1418 return mHelper.GetVisualViewportSize();
1420 virtual nsPoint GetVisualViewportOffset() const override {
1421 return mHelper.GetVisualViewportOffset();
1423 virtual nsSize GetLineScrollAmount() const override {
1424 return mHelper.GetLineScrollAmount();
1426 virtual nsSize GetPageScrollAmount() const override {
1427 return mHelper.GetPageScrollAmount();
1429 virtual nsMargin GetScrollPadding() const override {
1430 return mHelper.GetScrollPadding();
1433 * @note This method might destroy the frame, pres shell and other objects.
1435 virtual void ScrollTo(
1436 nsPoint aScrollPosition, ScrollMode aMode, const nsRect* aRange = nullptr,
1437 ScrollSnapMode aSnap = nsIScrollbarMediator::DISABLE_SNAP) override {
1438 mHelper.ScrollTo(aScrollPosition, aMode, nsGkAtoms::other, aRange, aSnap);
1441 * @note This method might destroy the frame, pres shell and other objects.
1443 virtual void ScrollToCSSPixels(const CSSIntPoint& aScrollPosition,
1444 ScrollMode aMode = ScrollMode::Instant,
1445 nsIScrollbarMediator::ScrollSnapMode aSnap =
1446 nsIScrollbarMediator::DISABLE_SNAP,
1447 nsAtom* aOrigin = nullptr) override {
1448 mHelper.ScrollToCSSPixels(aScrollPosition, aMode, aSnap, aOrigin);
1450 virtual void ScrollToCSSPixelsApproximate(
1451 const mozilla::CSSPoint& aScrollPosition,
1452 nsAtom* aOrigin = nullptr) override {
1453 mHelper.ScrollToCSSPixelsApproximate(aScrollPosition, aOrigin);
1455 virtual CSSIntPoint GetScrollPositionCSSPixels() override {
1456 return mHelper.GetScrollPositionCSSPixels();
1459 * @note This method might destroy the frame, pres shell and other objects.
1461 virtual void ScrollBy(nsIntPoint aDelta, ScrollUnit aUnit, ScrollMode aMode,
1462 nsIntPoint* aOverflow, nsAtom* aOrigin = nullptr,
1463 nsIScrollableFrame::ScrollMomentum aMomentum =
1464 nsIScrollableFrame::NOT_MOMENTUM,
1465 nsIScrollbarMediator::ScrollSnapMode aSnap =
1466 nsIScrollbarMediator::DISABLE_SNAP) override {
1467 mHelper.ScrollBy(aDelta, aUnit, aMode, aOverflow, aOrigin, aMomentum,
1468 aSnap);
1470 virtual void ScrollByCSSPixels(const CSSIntPoint& aDelta,
1471 ScrollMode aMode = ScrollMode::Instant,
1472 nsAtom* aOrigin = nullptr,
1473 nsIScrollbarMediator::ScrollSnapMode aSnap =
1474 nsIScrollbarMediator::DEFAULT) override {
1475 mHelper.ScrollByCSSPixels(aDelta, aMode, aOrigin, aSnap);
1477 virtual void ScrollSnap() override { mHelper.ScrollSnap(); }
1479 * @note This method might destroy the frame, pres shell and other objects.
1481 virtual void ScrollToRestoredPosition() override {
1482 mHelper.ScrollToRestoredPosition();
1484 virtual void AddScrollPositionListener(
1485 nsIScrollPositionListener* aListener) override {
1486 mHelper.AddScrollPositionListener(aListener);
1488 virtual void RemoveScrollPositionListener(
1489 nsIScrollPositionListener* aListener) override {
1490 mHelper.RemoveScrollPositionListener(aListener);
1493 * @note This method might destroy the frame, pres shell and other objects.
1495 virtual void CurPosAttributeChanged(nsIContent* aChild) override {
1496 mHelper.CurPosAttributeChanged(aChild);
1498 NS_IMETHOD PostScrolledAreaEventForCurrentArea() override {
1499 mHelper.PostScrolledAreaEvent();
1500 return NS_OK;
1502 virtual bool IsScrollingActive(nsDisplayListBuilder* aBuilder) override {
1503 return mHelper.IsScrollingActive(aBuilder);
1505 virtual bool IsMaybeScrollingActive() const override {
1506 return mHelper.IsMaybeScrollingActive();
1508 virtual bool IsMaybeAsynchronouslyScrolled() override {
1509 return mHelper.IsMaybeAsynchronouslyScrolled();
1511 virtual bool IsProcessingAsyncScroll() override {
1512 return mHelper.IsProcessingAsyncScroll();
1514 virtual void ResetScrollPositionForLayerPixelAlignment() override {
1515 mHelper.ResetScrollPositionForLayerPixelAlignment();
1517 virtual bool DidHistoryRestore() const override {
1518 return mHelper.mDidHistoryRestore;
1520 virtual void ClearDidHistoryRestore() override {
1521 mHelper.mDidHistoryRestore = false;
1523 virtual void MarkEverScrolled() override { mHelper.MarkEverScrolled(); }
1524 virtual bool IsRectNearlyVisible(const nsRect& aRect) override {
1525 return mHelper.IsRectNearlyVisible(aRect);
1527 virtual nsRect ExpandRectToNearlyVisible(const nsRect& aRect) const override {
1528 return mHelper.ExpandRectToNearlyVisible(aRect);
1530 virtual nsAtom* LastScrollOrigin() override {
1531 return mHelper.LastScrollOrigin();
1533 virtual nsAtom* LastSmoothScrollOrigin() override {
1534 return mHelper.LastSmoothScrollOrigin();
1536 virtual uint32_t CurrentScrollGeneration() override {
1537 return mHelper.CurrentScrollGeneration();
1539 virtual nsPoint LastScrollDestination() override {
1540 return mHelper.LastScrollDestination();
1542 virtual void ResetScrollInfoIfGeneration(uint32_t aGeneration) override {
1543 mHelper.ResetScrollInfoIfGeneration(aGeneration);
1545 virtual bool WantAsyncScroll() const override {
1546 return mHelper.WantAsyncScroll();
1548 virtual mozilla::Maybe<mozilla::layers::ScrollMetadata> ComputeScrollMetadata(
1549 LayerManager* aLayerManager, const nsIFrame* aContainerReferenceFrame,
1550 const Maybe<ContainerLayerParameters>& aParameters,
1551 const mozilla::DisplayItemClip* aClip) const override {
1552 return mHelper.ComputeScrollMetadata(
1553 aLayerManager, aContainerReferenceFrame, aParameters, aClip);
1555 virtual void ClipLayerToDisplayPort(
1556 Layer* aLayer, const mozilla::DisplayItemClip* aClip,
1557 const ContainerLayerParameters& aParameters) const override {
1558 mHelper.ClipLayerToDisplayPort(aLayer, aClip, aParameters);
1560 virtual void MarkScrollbarsDirtyForReflow() const override {
1561 mHelper.MarkScrollbarsDirtyForReflow();
1564 // nsIStatefulFrame
1565 mozilla::UniquePtr<mozilla::PresState> SaveState() override {
1566 return mHelper.SaveState();
1568 NS_IMETHOD RestoreState(mozilla::PresState* aState) override {
1569 NS_ENSURE_ARG_POINTER(aState);
1570 mHelper.RestoreState(aState);
1571 return NS_OK;
1574 virtual bool IsFrameOfType(uint32_t aFlags) const override {
1575 // Override bogus IsFrameOfType in nsBoxFrame.
1576 if (aFlags & (nsIFrame::eReplacedContainsBlock | nsIFrame::eReplaced))
1577 return false;
1578 return nsBoxFrame::IsFrameOfType(aFlags);
1581 virtual void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection,
1582 nsIScrollbarMediator::ScrollSnapMode aSnap =
1583 nsIScrollbarMediator::DISABLE_SNAP) override {
1584 mHelper.ScrollByPage(aScrollbar, aDirection, aSnap);
1586 virtual void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection,
1587 nsIScrollbarMediator::ScrollSnapMode aSnap =
1588 nsIScrollbarMediator::DISABLE_SNAP) override {
1589 mHelper.ScrollByWhole(aScrollbar, aDirection, aSnap);
1591 virtual void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection,
1592 nsIScrollbarMediator::ScrollSnapMode aSnap =
1593 nsIScrollbarMediator::DISABLE_SNAP) override {
1594 mHelper.ScrollByLine(aScrollbar, aDirection, aSnap);
1596 virtual void RepeatButtonScroll(nsScrollbarFrame* aScrollbar) override {
1597 mHelper.RepeatButtonScroll(aScrollbar);
1599 virtual void ThumbMoved(nsScrollbarFrame* aScrollbar, nscoord aOldPos,
1600 nscoord aNewPos) override {
1601 mHelper.ThumbMoved(aScrollbar, aOldPos, aNewPos);
1603 virtual void ScrollbarReleased(nsScrollbarFrame* aScrollbar) override {
1604 mHelper.ScrollbarReleased(aScrollbar);
1606 virtual void VisibilityChanged(bool aVisible) override {}
1607 virtual nsIFrame* GetScrollbarBox(bool aVertical) override {
1608 return mHelper.GetScrollbarBox(aVertical);
1611 virtual void ScrollbarActivityStarted() const override;
1612 virtual void ScrollbarActivityStopped() const override;
1614 virtual bool IsScrollbarOnRight() const override {
1615 return mHelper.IsScrollbarOnRight();
1618 virtual bool ShouldSuppressScrollbarRepaints() const override {
1619 return mHelper.ShouldSuppressScrollbarRepaints();
1622 virtual void SetTransformingByAPZ(bool aTransforming) override {
1623 mHelper.SetTransformingByAPZ(aTransforming);
1625 virtual bool UsesContainerScrolling() const override {
1626 return mHelper.UsesContainerScrolling();
1628 bool IsTransformingByAPZ() const override {
1629 return mHelper.IsTransformingByAPZ();
1631 void SetScrollableByAPZ(bool aScrollable) override {
1632 mHelper.SetScrollableByAPZ(aScrollable);
1634 void SetZoomableByAPZ(bool aZoomable) override {
1635 mHelper.SetZoomableByAPZ(aZoomable);
1637 void SetHasOutOfFlowContentInsideFilter() override {
1638 mHelper.SetHasOutOfFlowContentInsideFilter();
1640 virtual bool DecideScrollableLayer(nsDisplayListBuilder* aBuilder,
1641 nsRect* aVisibleRect, nsRect* aDirtyRect,
1642 bool aSetBase) override {
1643 return mHelper.DecideScrollableLayer(aBuilder, aVisibleRect, aDirtyRect,
1644 aSetBase);
1646 virtual void NotifyApzTransaction() override {
1647 mHelper.NotifyApzTransaction();
1649 virtual void NotifyApproximateFrameVisibilityUpdate(
1650 bool aIgnoreDisplayPort) override {
1651 mHelper.NotifyApproximateFrameVisibilityUpdate(aIgnoreDisplayPort);
1653 virtual bool GetDisplayPortAtLastApproximateFrameVisibilityUpdate(
1654 nsRect* aDisplayPort) override {
1655 return mHelper.GetDisplayPortAtLastApproximateFrameVisibilityUpdate(
1656 aDisplayPort);
1658 void TriggerDisplayPortExpiration() override {
1659 mHelper.TriggerDisplayPortExpiration();
1662 ScrollSnapInfo GetScrollSnapInfo() const override {
1663 return mHelper.GetScrollSnapInfo(Nothing());
1666 virtual bool DragScroll(mozilla::WidgetEvent* aEvent) override {
1667 return mHelper.DragScroll(aEvent);
1670 virtual void AsyncScrollbarDragInitiated(
1671 uint64_t aDragBlockId,
1672 mozilla::layers::ScrollDirection aDirection) override {
1673 return mHelper.AsyncScrollbarDragInitiated(aDragBlockId, aDirection);
1676 virtual void AsyncScrollbarDragRejected() override {
1677 return mHelper.AsyncScrollbarDragRejected();
1680 virtual bool IsRootScrollFrameOfDocument() const override {
1681 return mHelper.IsRootScrollFrameOfDocument();
1684 virtual const ScrollAnchorContainer* Anchor() const override {
1685 return &mHelper.mAnchor;
1688 virtual ScrollAnchorContainer* Anchor() override { return &mHelper.mAnchor; }
1690 // Return the scrolled frame.
1691 void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) override {
1692 aResult.AppendElement(OwnedAnonBox(mHelper.GetScrolledFrame()));
1695 bool SmoothScrollVisual(const nsPoint& aVisualViewportOffset,
1696 mozilla::layers::FrameMetrics::ScrollOffsetUpdateType
1697 aUpdateType) override {
1698 return mHelper.SmoothScrollVisual(aVisualViewportOffset, aUpdateType);
1701 bool IsSmoothScroll(mozilla::dom::ScrollBehavior aBehavior) const override {
1702 return mHelper.IsSmoothScroll(aBehavior);
1705 #ifdef DEBUG_FRAME_DUMP
1706 virtual nsresult GetFrameName(nsAString& aResult) const override;
1707 #endif
1709 protected:
1710 nsXULScrollFrame(ComputedStyle*, nsPresContext*, bool aIsRoot,
1711 bool aClipAllDescendants);
1713 void ClampAndSetBounds(nsBoxLayoutState& aState, nsRect& aRect,
1714 nsPoint aScrollPosition,
1715 bool aRemoveOverflowAreas = false) {
1717 * For RTL frames, restore the original scrolled position of the right
1718 * edge, then subtract the current width to find the physical position.
1720 if (!mHelper.IsPhysicalLTR()) {
1721 aRect.x = mHelper.mScrollPort.XMost() - aScrollPosition.x - aRect.width;
1723 mHelper.mScrolledFrame->SetXULBounds(aState, aRect, aRemoveOverflowAreas);
1726 private:
1727 friend class mozilla::ScrollFrameHelper;
1728 ScrollFrameHelper mHelper;
1731 #endif /* nsGfxScrollFrame_h___ */