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/. */
6 
7 /*
8  * interface that provides scroll APIs implemented by scrollable frames
9  */
10 
11 #ifndef nsIScrollFrame_h___
12 #define nsIScrollFrame_h___
13 
14 #include "nsCoord.h"
15 #include "mozilla/dom/WindowBinding.h"  // for mozilla::dom::ScrollBehavior
16 #include "mozilla/Maybe.h"
17 #include "mozilla/ScrollOrigin.h"
18 #include "mozilla/ScrollPositionUpdate.h"
19 #include "mozilla/ScrollStyles.h"
20 #include "mozilla/ScrollTypes.h"
21 #include "mozilla/gfx/Point.h"
22 #include "nsIScrollbarMediator.h"
23 #include "Units.h"
24 #include "FrameMetrics.h"
25 
26 #define NS_DEFAULT_VERTICAL_SCROLL_DISTANCE 3
27 #define NS_DEFAULT_HORIZONTAL_SCROLL_DISTANCE 5
28 
29 class gfxContext;
30 class nsBoxLayoutState;
31 class nsIScrollPositionListener;
32 class nsIFrame;
33 class nsPresContext;
34 class nsIContent;
35 
36 namespace mozilla {
37 class DisplayItemClip;
38 class nsDisplayListBuilder;
39 
40 namespace layers {
41 struct ScrollMetadata;
42 class Layer;
43 class WebRenderLayerManager;
44 }  // namespace layers
45 namespace layout {
46 class ScrollAnchorContainer;
47 }  // namespace layout
48 }  // namespace mozilla
49 
50 /**
51  * Interface for frames that are scrollable. This interface exposes
52  * APIs for examining scroll state, observing changes to scroll state,
53  * and triggering scrolling.
54  */
55 class nsIScrollableFrame : public nsIScrollbarMediator {
56  public:
57   typedef mozilla::CSSIntPoint CSSIntPoint;
58   typedef mozilla::layers::ScrollSnapInfo ScrollSnapInfo;
59   typedef mozilla::layout::ScrollAnchorContainer ScrollAnchorContainer;
60   typedef mozilla::ScrollMode ScrollMode;
61   typedef mozilla::ScrollOrigin ScrollOrigin;
62 
63   NS_DECL_QUERYFRAME_TARGET(nsIScrollableFrame)
64 
65   /**
66    * Get the frame for the content that we are scrolling within
67    * this scrollable frame.
68    */
69   virtual nsIFrame* GetScrolledFrame() const = 0;
70 
71   /**
72    * Get the overflow styles (StyleOverflow::Scroll, StyleOverflow::Hidden, or
73    * StyleOverflow::Auto) governing the horizontal and vertical scrollbars for
74    * this frame.
75    *
76    * This is special because they can be propagated from the <body> element,
77    * unlike other styles.
78    */
79   virtual mozilla::ScrollStyles GetScrollStyles() const = 0;
80 
81   /**
82    * Returns whether this scroll frame is for a text control element with no
83    * scrollbars (for <input>, basically).
84    */
85   virtual bool IsForTextControlWithNoScrollbars() const = 0;
86 
87   /**
88    * Returns whether we already have anonymous content nodes for all our needed
89    * scrollbar parts (or a superset thereof).
90    */
91   virtual bool HasAllNeededScrollbars() const = 0;
92 
93   /**
94    * Get the overscroll-behavior styles.
95    */
96   virtual mozilla::layers::OverscrollBehaviorInfo GetOverscrollBehaviorInfo()
97       const = 0;
98 
99   /**
100    * Return the scrollbars which are visible. It's OK to call this during reflow
101    * of the scrolled contents, in which case it will reflect the current
102    * assumptions about scrollbar visibility.
103    */
104   virtual mozilla::layers::ScrollDirections GetScrollbarVisibility() const = 0;
105   /**
106    * Returns the directions in which scrolling is allowed (if the scroll range
107    * is at least one device pixel in that direction).
108    */
109   mozilla::layers::ScrollDirections GetAvailableScrollingDirections() const;
110   /**
111    * Returns the directions in which scrolling is allowed when taking into
112    * account the visual viewport size and overflow hidden. (An (apz) zoomed in
113    * overflow hidden scrollframe is actually user scrollable.)
114    */
115   virtual mozilla::layers::ScrollDirections
116   GetAvailableScrollingDirectionsForUserInputEvents() const = 0;
117   /**
118    * Return the actual sizes of all possible scrollbars. Returns 0 for scrollbar
119    * positions that don't have a scrollbar or where the scrollbar is not
120    * visible. Do not call this while this frame's descendants are being
121    * reflowed, it won't be accurate.
122    * INCLUDE_VISUAL_VIEWPORT_SCROLLBARS means we include the size of layout
123    * scrollbars that are only visible to scroll the visual viewport inside the
124    * layout viewport (ie the layout viewport cannot be scrolled) even though
125    * there is no layout space set aside for these scrollbars.
126    */
127   enum class ScrollbarSizesOptions { NONE, INCLUDE_VISUAL_VIEWPORT_SCROLLBARS };
128   virtual nsMargin GetActualScrollbarSizes(
129       ScrollbarSizesOptions aOptions = ScrollbarSizesOptions::NONE) const = 0;
130   /**
131    * Return the sizes of all scrollbars assuming that any scrollbars that could
132    * be visible due to overflowing content, are. This can be called during
133    * reflow of the scrolled contents.
134    */
135   virtual nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState) = 0;
136   /**
137    * Return the sizes of all scrollbars assuming that any scrollbars that could
138    * be visible due to overflowing content, are. This can be called during
139    * reflow of the scrolled contents.
140    */
141   virtual nsMargin GetDesiredScrollbarSizes(nsPresContext* aPresContext,
142                                             gfxContext* aRC) = 0;
143   /**
144    * Return the width for non-disappearing scrollbars.
145    */
146   static nscoord GetNondisappearingScrollbarWidth(nsPresContext*,
147                                                   mozilla::WritingMode);
148   /**
149    * Get the layout size of this frame.
150    * Note that this is a value which is not expanded by the minimum scale size.
151    * For scroll frames other than the root content document's scroll frame, this
152    * value will be the same as GetScrollPortRect().Size().
153    *
154    * This value is used for Element.clientWidth and clientHeight.
155    */
156   virtual nsSize GetLayoutSize() const = 0;
157   /**
158    * GetScrolledRect is designed to encapsulate deciding which
159    * directions of overflow should be reachable by scrolling and which
160    * should not.  Callers should NOT depend on it having any particular
161    * behavior (although nsXULScrollFrame currently does).
162    *
163    * This should only be called when the scrolled frame has been
164    * reflowed with the scroll port size given in mScrollPort.
165    *
166    * Currently it allows scrolling down and to the right for
167    * nsHTMLScrollFrames with LTR directionality and for all
168    * nsXULScrollFrames, and allows scrolling down and to the left for
169    * nsHTMLScrollFrames with RTL directionality.
170    */
171   virtual nsRect GetScrolledRect() const = 0;
172   /**
173    * Get the area of the scrollport relative to the origin of this frame's
174    * border-box.
175    * This is the area of this frame minus border and scrollbars.
176    */
177   virtual nsRect GetScrollPortRect() const = 0;
178   /**
179    * Get the offset of the scrollport origin relative to the scrolled
180    * frame origin. Typically the position will be non-negative.
181    * This will always be a multiple of device pixels.
182    */
183   virtual nsPoint GetScrollPosition() const = 0;
184   /**
185    * As GetScrollPosition(), but uses the top-right as origin for RTL frames.
186    */
187   virtual nsPoint GetLogicalScrollPosition() const = 0;
188 
189   /**
190    * Get the area that must contain the scroll position. Typically
191    * (but not always, e.g. for RTL content) x and y will be 0, and
192    * width or height will be nonzero if the content can be scrolled in
193    * that direction. Since scroll positions must be a multiple of
194    * device pixels, the range extrema will also be a multiple of
195    * device pixels.
196    */
197   virtual nsRect GetScrollRange() const = 0;
198   /**
199    * Get the size of the view port to use when clamping the scroll
200    * position.
201    */
202   virtual nsSize GetVisualViewportSize() const = 0;
203   /**
204    * Returns the offset of the visual viewport relative to
205    * the origin of the scrolled content. Note that only the RCD-RSF
206    * has a distinct visual viewport; for other scroll frames, the
207    * visual viewport always coincides with the layout viewport, and
208    * consequently the offset this function returns is equal to
209    * GetScrollPosition().
210    */
211   virtual nsPoint GetVisualViewportOffset() const = 0;
212   /**
213    * Set the visual viewport offset associated with a root scroll frame. This is
214    * only valid when called on a root scroll frame and will assert otherwise.
215    * aRepaint indicates if we need to ask for a main thread paint if this
216    * changes scrollbar positions or not. For example, if the compositor has
217    * already put the scrollbars at this position then they don't need to move so
218    * we can skip the repaint. Returns true if the offset changed and the scroll
219    * frame is still alive after this call.
220    */
221   virtual bool SetVisualViewportOffset(const nsPoint& aOffset,
222                                        bool aRepaint) = 0;
223   /**
224    * Get the area that must contain the visual viewport offset.
225    */
226   virtual nsRect GetVisualScrollRange() const = 0;
227   /**
228    * Like GetVisualScrollRange but also takes into account overflow: hidden.
229    */
230   virtual nsRect GetScrollRangeForUserInputEvents() const = 0;
231   /**
232    * Return how much we would try to scroll by in each direction if
233    * asked to scroll by one "line" vertically and horizontally.
234    */
235   virtual nsSize GetLineScrollAmount() const = 0;
236   /**
237    * Return how much we would try to scroll by in each direction if
238    * asked to scroll by one "page" vertically and horizontally.
239    */
240   virtual nsSize GetPageScrollAmount() const = 0;
241 
242   /**
243    * Return scroll-padding value of this frame.
244    */
245   virtual nsMargin GetScrollPadding() const = 0;
246   /**
247    * Some platforms (OSX) may generate additional scrolling events even
248    * after the user has stopped scrolling, simulating a momentum scrolling
249    * effect resulting from fling gestures.
250    * SYNTHESIZED_MOMENTUM_EVENT indicates that the scrolling is being requested
251    * by such a synthesized event and may be ignored if another scroll has
252    * been started since the last actual user input.
253    */
254   enum ScrollMomentum { NOT_MOMENTUM, SYNTHESIZED_MOMENTUM_EVENT };
255   /**
256    * @note This method might destroy the frame, pres shell and other objects.
257    * Clamps aScrollPosition to GetScrollRange and sets the scroll position
258    * to that value.
259    * @param aRange If non-null, specifies area which contains aScrollPosition
260    * and can be used for choosing a performance-optimized scroll position.
261    * Any point within this area can be chosen.
262    * The choosen point will be as close as possible to aScrollPosition.
263    */
264   virtual void ScrollTo(nsPoint aScrollPosition, ScrollMode aMode,
265                         const nsRect* aRange = nullptr,
266                         nsIScrollbarMediator::ScrollSnapMode aSnap =
267                             nsIScrollbarMediator::DISABLE_SNAP,
268                         mozilla::ScrollTriggeredByScript aTriggeredByScript =
269                             mozilla::ScrollTriggeredByScript::No) = 0;
270   /**
271    * @note This method might destroy the frame, pres shell and other objects.
272    * Scrolls to a particular position in integer CSS pixels.
273    * Keeps the exact current horizontal or vertical position if the current
274    * position, rounded to CSS pixels, matches aScrollPosition. If
275    * aScrollPosition.x/y is different from the current CSS pixel position,
276    * makes sure we only move in the direction given by the difference.
277    *
278    * When aMode is SMOOTH, INSTANT, or NORMAL, GetScrollPositionCSSPixels (the
279    * scroll position after rounding to CSS pixels) will be exactly
280    * aScrollPosition at the end of the scroll animation.
281    *
282    * When aMode is SMOOTH_MSD, intermediate animation frames may be outside the
283    * range and / or moving in any direction; GetScrollPositionCSSPixels will be
284    * exactly aScrollPosition at the end of the scroll animation unless the
285    * SMOOTH_MSD animation is interrupted.
286    */
287   virtual void ScrollToCSSPixels(const CSSIntPoint& aScrollPosition,
288                                  ScrollMode aMode = ScrollMode::Instant) = 0;
289   /**
290    * @note This method might destroy the frame, pres shell and other objects.
291    * Scrolls to a particular position in float CSS pixels.
292    * This does not guarantee that GetScrollPositionCSSPixels equals
293    * aScrollPosition afterward. It tries to scroll as close to
294    * aScrollPosition as possible while scrolling by an integer
295    * number of layer pixels (so the operation is fast and looks clean).
296    */
297   virtual void ScrollToCSSPixelsForApz(
298       const mozilla::CSSPoint& aScrollPosition) = 0;
299 
300   /**
301    * Returns the scroll position in integer CSS pixels, rounded to the nearest
302    * pixel.
303    */
304   virtual CSSIntPoint GetScrollPositionCSSPixels() = 0;
305   /**
306    * @note This method might destroy the frame, pres shell and other objects.
307    * Modifies the current scroll position by aDelta units given by aUnit,
308    * clamping it to GetScrollRange. If WHOLE is specified as the unit,
309    * content is scrolled all the way in the direction(s) given by aDelta.
310    * @param aOverflow if non-null, returns the amount that scrolling
311    * was clamped by in each direction (how far we moved the scroll position
312    * to bring it back into the legal range). This is never negative. The
313    * values are in device pixels.
314    */
315   virtual void ScrollBy(nsIntPoint aDelta, mozilla::ScrollUnit aUnit,
316                         ScrollMode aMode, nsIntPoint* aOverflow = nullptr,
317                         ScrollOrigin aOrigin = ScrollOrigin::NotSpecified,
318                         ScrollMomentum aMomentum = NOT_MOMENTUM,
319                         nsIScrollbarMediator::ScrollSnapMode aSnap =
320                             nsIScrollbarMediator::DISABLE_SNAP) = 0;
321 
322   virtual void ScrollByCSSPixels(const CSSIntPoint& aDelta,
323                                  ScrollMode aMode = ScrollMode::Instant) = 0;
324 
325   /**
326    * Perform scroll snapping, possibly resulting in a smooth scroll to
327    * maintain the scroll snap position constraints.  Velocity sampled from
328    * main thread scrolling is used to determine best matching snap point
329    * when called after a fling gesture on a trackpad or mouse wheel.
330    */
331   virtual void ScrollSnap() = 0;
332 
333   /**
334    * @note This method might destroy the frame, pres shell and other objects.
335    * This tells the scroll frame to try scrolling to the scroll
336    * position that was restored from the history. This must be called
337    * at least once after state has been restored. It is called by the
338    * scrolled frame itself during reflow, but sometimes state can be
339    * restored after reflows are done...
340    * XXX should we take an aMode parameter here? Currently it's instant.
341    */
342   virtual void ScrollToRestoredPosition() = 0;
343 
344   /**
345    * Add a scroll position listener. This listener must be removed
346    * before it is destroyed.
347    */
348   virtual void AddScrollPositionListener(
349       nsIScrollPositionListener* aListener) = 0;
350   /**
351    * Remove a scroll position listener.
352    */
353   virtual void RemoveScrollPositionListener(
354       nsIScrollPositionListener* aListener) = 0;
355 
356   /**
357    * Internal method used by scrollbars to notify their scrolling
358    * container of changes.
359    */
360   virtual void CurPosAttributeChanged(nsIContent* aChild) = 0;
361 
362   /**
363    * Allows the docshell to request that the scroll frame post an event
364    * after being restored from history.
365    */
366   NS_IMETHOD PostScrolledAreaEventForCurrentArea() = 0;
367 
368   /**
369    * Returns true if this scrollframe is being "actively scrolled".
370    * This basically means that we should allocate resources in the
371    * expectation that scrolling is going to happen.
372    */
373   virtual bool IsScrollingActive() = 0;
374 
375   /**
376    * Returns true if this scroll frame might be scrolled
377    * asynchronously by the compositor.
378    */
379   virtual bool IsMaybeAsynchronouslyScrolled() = 0;
380 
381   /**
382    * Was the current presentation state for this frame restored from history?
383    */
384   virtual bool DidHistoryRestore() const = 0;
385   /**
386    * Clear the flag so that DidHistoryRestore() returns false until the next
387    * RestoreState call.
388    * @see nsIStatefulFrame::RestoreState
389    */
390   virtual void ClearDidHistoryRestore() = 0;
391   /**
392    * Mark the frame as having been scrolled at least once, so that it remains
393    * active and we can also start storing its scroll position when saving state.
394    */
395   virtual void MarkEverScrolled() = 0;
396   /**
397    * Determine if the passed in rect is nearly visible according to the frame
398    * visibility heuristics for how close it is to the visible scrollport.
399    */
400   virtual bool IsRectNearlyVisible(const nsRect& aRect) = 0;
401   /**
402    * Expand the given rect taking into account which directions we can scroll
403    * and how far we want to expand for frame visibility purposes.
404    */
405   virtual nsRect ExpandRectToNearlyVisible(const nsRect& aRect) const = 0;
406   /**
407    * Returns the origin that triggered the last instant scroll. Will equal
408    * ScrollOrigin::Apz when the compositor's replica frame metrics includes the
409    * latest instant scroll.
410    */
411   virtual ScrollOrigin LastScrollOrigin() = 0;
412 
413   /**
414    * Returns whether there's an async scroll going on.
415    *
416    * The argument allows a subtle distinction that's needed for APZ. When
417    * `IncludeApzAnimation::No` is given, ongoing APZ animations that have
418    * already been synced to the main thread are not included, which is needed so
419    * that APZ can keep syncing the scroll offset properly.
420    */
421   enum class IncludeApzAnimation : bool { No, Yes };
422   virtual bool IsScrollAnimating(
423       IncludeApzAnimation = IncludeApzAnimation::Yes) = 0;
424 
425   /**
426    * Returns the current generation counter for the scrollframe. This counter
427    * increments every time the scroll position is set.
428    */
429   virtual mozilla::MainThreadScrollGeneration CurrentScrollGeneration()
430       const = 0;
431   /**
432    * The APZ scroll generation associated with the last APZ scroll offset for
433    * which we processed a repaint request.
434    */
435   virtual mozilla::APZScrollGeneration ScrollGenerationOnApz() const = 0;
436   /**
437    * LastScrollDestination returns the destination of the most recently
438    * requested smooth scroll animation.
439    */
440   virtual nsPoint LastScrollDestination() = 0;
441   /**
442    * Returns the list of scroll position updates since the last call to
443    * NotifyApzTransaction().
444    */
445   virtual nsTArray<mozilla::ScrollPositionUpdate> GetScrollUpdates() const = 0;
446   /**
447    * Returns true if the scroll frame has any scroll position updates since
448    * the last call to NotifyApzTransaction().
449    */
450   virtual bool HasScrollUpdates() const = 0;
451   /**
452    * Clears the "origin of last scroll" property stored in this frame, if
453    * the generation counter passed in matches the current scroll generation
454    * counter, and clears the "origin of last smooth scroll" property if the
455    * generation counter matches. It also resets whether there's an ongoing apz
456    * animation.
457    */
458   virtual void ResetScrollInfoIfNeeded(
459       const mozilla::MainThreadScrollGeneration& aGeneration,
460       const mozilla::APZScrollGeneration& aGenerationOnApz,
461       mozilla::APZScrollAnimationType aAPZScrollAnimationType) = 0;
462   /**
463    * Determine whether it is desirable to be able to asynchronously scroll this
464    * scroll frame.
465    */
466   virtual bool WantAsyncScroll() const = 0;
467   /**
468    * Returns the ScrollMetadata contributed by this frame, if there is one.
469    */
470   virtual mozilla::Maybe<mozilla::layers::ScrollMetadata> ComputeScrollMetadata(
471       mozilla::layers::WebRenderLayerManager* aLayerManager,
472       const nsIFrame* aItemFrame,
473       const nsPoint& aOffsetToReferenceFrame) const = 0;
474 
475   /**
476    * Mark the scrollbar frames for reflow.
477    */
478   virtual void MarkScrollbarsDirtyForReflow() const = 0;
479 
480   /**
481    * Invalidate the scrollbar after the marks have been changed.
482    */
483   virtual void InvalidateScrollbars() const = 0;
484 
485   virtual void UpdateScrollbarPosition() = 0;
486 
487   virtual void SetTransformingByAPZ(bool aTransforming) = 0;
488   virtual bool IsTransformingByAPZ() const = 0;
489 
490   /**
491    * Notify this scroll frame that it can be scrolled by APZ. In particular,
492    * this is called *after* the APZ code has created an APZC for this scroll
493    * frame and verified that it is not a scrollinfo layer. Therefore, setting an
494    * async transform on it is actually user visible.
495    */
496   virtual void SetScrollableByAPZ(bool aScrollable) = 0;
497 
498   /**
499    * Notify this scroll frame that it can be zoomed by APZ.
500    */
501   virtual void SetZoomableByAPZ(bool aZoomable) = 0;
502 
503   /**
504    * Mark this scroll frame as having out-of-flow content inside a CSS filter.
505    * Such content will move incorrectly during async-scrolling; to mitigate
506    * this, paint skipping is disabled for such scroll frames.
507    */
508   virtual void SetHasOutOfFlowContentInsideFilter() = 0;
509 
510   /**
511    * Determine if we should build a scrollable layer for this scroll frame and
512    * return the result. It will also record this result on the scroll frame.
513    * Pass the visible rect in aVisibleRect. On return it will be set to the
514    * displayport if there is one.
515    * Pass the dirty rect in aDirtyRect. On return it will be set to the
516    * dirty rect inside the displayport (ie the dirty rect that should be used).
517    * This function will set the display port base rect if aSetBase is true.
518    * aSetBase is only allowed to be false if there has been a call with it
519    * set to true before on the same paint.
520    */
521   virtual bool DecideScrollableLayer(mozilla::nsDisplayListBuilder* aBuilder,
522                                      nsRect* aVisibleRect, nsRect* aDirtyRect,
523                                      bool aSetBase) = 0;
524 
525   /**
526    * Notify the scrollframe that the current scroll offset and origin have been
527    * sent over in a layers transaction.
528    *
529    * This sets a flag on the scrollframe that indicates subsequent changes
530    * to the scroll position by "weaker" origins are permitted to overwrite the
531    * the scroll origin. Scroll origins that
532    * nsLayoutUtils::CanScrollOriginClobberApz returns false for are considered
533    * "weaker" than scroll origins for which that function returns true.
534    *
535    * This function must be called for a scrollframe after all calls to
536    * ComputeScrollMetadata in a layers transaction have been completed.
537    *
538    */
539   virtual void NotifyApzTransaction() = 0;
540 
541   /**
542    * Notification that this scroll frame is getting its frame visibility
543    * updated. aIgnoreDisplayPort indicates that the display port was ignored
544    * (because there was no suitable base rect)
545    */
546   virtual void NotifyApproximateFrameVisibilityUpdate(
547       bool aIgnoreDisplayPort) = 0;
548 
549   /**
550    * Returns true if this scroll frame had a display port at the last frame
551    * visibility update and fills in aDisplayPort with that displayport. Returns
552    * false otherwise, and doesn't touch aDisplayPort.
553    */
554   virtual bool GetDisplayPortAtLastApproximateFrameVisibilityUpdate(
555       nsRect* aDisplayPort) = 0;
556 
557   /**
558    * This is called when a descendant scrollframe's has its displayport expired.
559    * This function will check to see if this scrollframe may safely expire its
560    * own displayport and schedule a timer to do that if it is safe.
561    */
562   virtual void TriggerDisplayPortExpiration() = 0;
563 
564   /**
565    * Returns information required to determine where to snap to after a scroll.
566    */
567   virtual ScrollSnapInfo GetScrollSnapInfo() const = 0;
568 
569   /**
570    * Given the drag event aEvent, determine whether the mouse is near the edge
571    * of the scrollable area, and scroll the view in the direction of that edge
572    * if so. If scrolling occurred, true is returned. When false is returned, the
573    * caller should look for an ancestor to scroll.
574    */
575   virtual bool DragScroll(mozilla::WidgetEvent* aEvent) = 0;
576 
577   virtual void AsyncScrollbarDragInitiated(
578       uint64_t aDragBlockId, mozilla::layers::ScrollDirection aDirection) = 0;
579   virtual void AsyncScrollbarDragRejected() = 0;
580 
581   /**
582    * Returns whether this scroll frame is the root scroll frame of the document
583    * that it is in. Note that some documents don't have root scroll frames at
584    * all (ie XUL documents) even though they may contain other scroll frames.
585    */
586   virtual bool IsRootScrollFrameOfDocument() const = 0;
587 
588   /**
589    * Returns the scroll anchor associated with this scrollable frame. This is
590    * never null.
591    */
592   virtual const ScrollAnchorContainer* Anchor() const = 0;
593   virtual ScrollAnchorContainer* Anchor() = 0;
594 
595   virtual bool SmoothScrollVisual(
596       const nsPoint& aVisualViewportOffset,
597       mozilla::layers::FrameMetrics::ScrollOffsetUpdateType aUpdateType) = 0;
598 
599   /**
600    * Returns true if this scroll frame should perform smooth scroll with the
601    * given |aBehavior|.
602    */
603   virtual bool IsSmoothScroll(mozilla::dom::ScrollBehavior aBehavior =
604                                   mozilla::dom::ScrollBehavior::Auto) const = 0;
605 };
606 
607 #endif
608