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 /* rendering object to wrap rendering objects that should be scrollable */ 8 9 #ifndef nsGfxScrollFrame_h___ 10 #define nsGfxScrollFrame_h___ 11 12 #include "mozilla/Attributes.h" 13 #include "nsContainerFrame.h" 14 #include "nsIAnonymousContentCreator.h" 15 #include "nsBoxFrame.h" 16 #include "nsIScrollableFrame.h" 17 #include "nsIScrollbarMediator.h" 18 #include "nsIStatefulFrame.h" 19 #include "nsThreadUtils.h" 20 #include "nsIReflowCallback.h" 21 #include "nsBoxLayoutState.h" 22 #include "nsQueryFrame.h" 23 #include "nsExpirationTracker.h" 24 #include "TextOverflow.h" 25 #include "ScrollVelocityQueue.h" 26 #include "mozilla/ScrollTypes.h" 27 #include "mozilla/PresState.h" 28 #include "mozilla/layout/ScrollAnchorContainer.h" 29 #include "mozilla/TypedEnumBits.h" 30 31 class nsPresContext; 32 class nsIContent; 33 class nsAtom; 34 class nsIScrollPositionListener; 35 36 namespace mozilla { 37 class PresShell; 38 struct ScrollReflowInput; 39 namespace layers { 40 class Layer; 41 class WebRenderLayerManager; 42 } // namespace layers 43 namespace layout { 44 class ScrollbarActivity; 45 } // namespace layout 46 47 class ScrollFrameHelper : public nsIReflowCallback { 48 public: 49 using Sides = nsIFrame::Sides; 50 using CSSIntPoint = mozilla::CSSIntPoint; 51 using ScrollbarActivity = mozilla::layout::ScrollbarActivity; 52 using FrameMetrics = mozilla::layers::FrameMetrics; 53 using ScrollableLayerGuid = mozilla::layers::ScrollableLayerGuid; 54 using ScrollSnapInfo = mozilla::layers::ScrollSnapInfo; 55 using Layer = mozilla::layers::Layer; 56 using WebRenderLayerManager = mozilla::layers::WebRenderLayerManager; 57 using ScrollAnchorContainer = mozilla::layout::ScrollAnchorContainer; 58 using APZScrollAnimationType = mozilla::APZScrollAnimationType; 59 using Element = mozilla::dom::Element; 60 61 class AsyncScroll; 62 class AsyncSmoothMSDScroll; 63 64 ScrollFrameHelper(nsContainerFrame* aOuter, bool aIsRoot); 65 ~ScrollFrameHelper(); 66 67 mozilla::ScrollStyles GetScrollStylesFromFrame() const; 68 mozilla::layers::OverscrollBehaviorInfo GetOverscrollBehaviorInfo() const; 69 70 bool IsForTextControlWithNoScrollbars() const; 71 72 enum class AnonymousContentType { 73 VerticalScrollbar, 74 HorizontalScrollbar, 75 Resizer, 76 }; 77 EnumSet<AnonymousContentType> GetNeededAnonymousContent() const; 78 EnumSet<AnonymousContentType> GetCurrentAnonymousContent() const; 79 HasAllNeededScrollbars()80 bool HasAllNeededScrollbars() const { 81 return GetCurrentAnonymousContent().contains(GetNeededAnonymousContent()); 82 } 83 84 // If a child frame was added or removed on the scrollframe, 85 // reload our child frame list. 86 // We need this if a scrollbar frame is recreated. 87 void ReloadChildFrames(); 88 89 nsresult CreateAnonymousContent( 90 nsTArray<nsIAnonymousContentCreator::ContentInfo>& aElements); 91 void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements, 92 uint32_t aFilter); 93 94 enum class OverflowState : uint32_t { 95 None = 0, 96 Vertical = (1 << 0), 97 Horizontal = (1 << 1), 98 }; 99 100 OverflowState GetOverflowState() const; 101 102 MOZ_CAN_RUN_SCRIPT nsresult FireScrollPortEvent(); 103 void PostScrollEndEvent(); 104 void FireScrollEndEvent(); 105 void PostOverflowEvent(); 106 using PostDestroyData = nsIFrame::PostDestroyData; 107 void Destroy(PostDestroyData& aPostDestroyData); 108 109 void BuildDisplayList(nsDisplayListBuilder* aBuilder, 110 const nsDisplayListSet& aLists); 111 112 // Add display items for the top-layer (which includes things like 113 // the fullscreen element, its backdrop, and text selection carets) 114 // to |aLists|. 115 // This is a no-op for scroll frames other than the viewport's 116 // root scroll frame. 117 // This should be called with an nsDisplayListSet that will be 118 // wrapped in the async zoom container, if we're building one. 119 // It should not be called with an ASR setter on the stack, as the 120 // top-layer items handle setting up their own ASRs. 121 nsDisplayWrapList* MaybeCreateTopLayerItems(nsDisplayListBuilder* aBuilder, 122 bool* aIsOpaque); 123 124 void AppendScrollPartsTo(nsDisplayListBuilder* aBuilder, 125 const nsDisplayListSet& aLists, bool aCreateLayer, 126 bool aPositioned); 127 128 bool GetBorderRadii(const nsSize& aFrameSize, const nsSize& aBorderArea, 129 Sides aSkipSides, nscoord aRadii[8]) const; 130 131 // nsIReflowCallback 132 bool ReflowFinished() final; 133 void ReflowCallbackCanceled() final; 134 135 /** 136 * @note This method might destroy the frame, pres shell and other objects. 137 * Called when the 'curpos' attribute on one of the scrollbars changes. 138 */ 139 void CurPosAttributeChanged(nsIContent* aChild, bool aDoScroll = true); 140 141 void PostScrollEvent(bool aDelayed = false); 142 MOZ_CAN_RUN_SCRIPT void FireScrollEvent(); 143 void PostScrolledAreaEvent(); 144 MOZ_CAN_RUN_SCRIPT void FireScrolledAreaEvent(); 145 146 bool IsSmoothScrollingEnabled(); 147 148 /** 149 * @note This method might destroy the frame, pres shell and other objects. 150 */ 151 void FinishReflowForScrollbar(Element* aElement, nscoord aMinXY, 152 nscoord aMaxXY, nscoord aCurPosXY, 153 nscoord aPageIncrement, nscoord aIncrement); 154 /** 155 * @note This method might destroy the frame, pres shell and other objects. 156 */ 157 void SetScrollbarEnabled(Element* aElement, nscoord aMaxPos); 158 /** 159 * @note This method might destroy the frame, pres shell and other objects. 160 */ 161 void SetCoordAttribute(Element* aElement, nsAtom* aAtom, nscoord aSize); 162 163 nscoord GetCoordAttribute(nsIFrame* aFrame, nsAtom* aAtom, 164 nscoord aDefaultValue, nscoord* aRangeStart, 165 nscoord* aRangeLength); 166 167 /** 168 * @note This method might destroy the frame, pres shell and other objects. 169 * Update scrollbar curpos attributes to reflect current scroll position 170 */ 171 void UpdateScrollbarPosition(); 172 GetLayoutSize()173 nsSize GetLayoutSize() const { 174 if (mIsUsingMinimumScaleSize) { 175 return mICBSize; 176 } 177 return mScrollPort.Size(); 178 } GetScrollPortRect()179 nsRect GetScrollPortRect() const { return mScrollPort; } GetScrollPosition()180 nsPoint GetScrollPosition() const { 181 return mScrollPort.TopLeft() - mScrolledFrame->GetPosition(); 182 } 183 /** 184 * For LTR frames, the logical scroll position is the offset of the top left 185 * corner of the frame from the top left corner of the scroll port (same as 186 * GetScrollPosition). 187 * For RTL frames, it is the offset of the top right corner of the frame from 188 * the top right corner of the scroll port 189 */ GetLogicalScrollPosition()190 nsPoint GetLogicalScrollPosition() const { 191 nsPoint pt; 192 pt.x = IsPhysicalLTR() 193 ? mScrollPort.x - mScrolledFrame->GetPosition().x 194 : mScrollPort.XMost() - mScrolledFrame->GetRect().XMost(); 195 pt.y = mScrollPort.y - mScrolledFrame->GetPosition().y; 196 return pt; 197 } 198 nsRect GetLayoutScrollRange() const; 199 // Get the scroll range assuming the viewport has size (aWidth, aHeight). 200 nsRect GetScrollRange(nscoord aWidth, nscoord aHeight) const; 201 nsSize GetVisualViewportSize() const; 202 nsPoint GetVisualViewportOffset() const; 203 bool SetVisualViewportOffset(const nsPoint& aOffset, bool aRepaint); 204 nsRect GetVisualScrollRange() const; 205 nsRect GetScrollRangeForUserInputEvents() const; 206 ScrollPort()207 const nsRect& ScrollPort() const { return mScrollPort; } SetScrollPort(const nsRect & aNewScrollPort)208 void SetScrollPort(const nsRect& aNewScrollPort) { 209 if (!mScrollPort.IsEqualEdges(aNewScrollPort)) { 210 mMayScheduleScrollAnimations = true; 211 } 212 mScrollPort = aNewScrollPort; 213 } 214 215 /** 216 * Return the 'optimal viewing region' as a rect suitable for use by 217 * scroll anchoring. This rect is in the same coordinate space as 218 * 'GetScrollPortRect', and accounts for 'scroll-padding' as defined by: 219 * 220 * https://drafts.csswg.org/css-scroll-snap-1/#optimal-viewing-region 221 */ 222 nsRect GetVisualOptimalViewingRect() const; 223 224 /** 225 * For LTR frames, this is the same as GetVisualViewportOffset(). 226 * For RTL frames, we take the offset from the top right corner of the frame 227 * to the top right corner of the visual viewport. 228 */ GetLogicalVisualViewportOffset()229 nsPoint GetLogicalVisualViewportOffset() const { 230 nsPoint pt = GetVisualViewportOffset(); 231 if (!IsPhysicalLTR()) { 232 pt.x += GetVisualViewportSize().width - mScrolledFrame->GetRect().width; 233 } 234 return pt; 235 } 236 void ScrollSnap(ScrollMode aMode = ScrollMode::SmoothMsd); 237 void ScrollSnap(const nsPoint& aDestination, 238 ScrollMode aMode = ScrollMode::SmoothMsd); 239 HasPendingScrollRestoration()240 bool HasPendingScrollRestoration() const { 241 return mRestorePos != nsPoint(-1, -1); 242 } 243 IsProcessingScrollEvent()244 bool IsProcessingScrollEvent() const { return mProcessingScrollEvent; } 245 246 public: 247 static void AsyncScrollCallback(ScrollFrameHelper* aInstance, 248 mozilla::TimeStamp aTime); 249 static void AsyncSmoothMSDScrollCallback(ScrollFrameHelper* aInstance, 250 mozilla::TimeDuration aDeltaTime); 251 /** 252 * @note This method might destroy the frame, pres shell and other objects. 253 * aRange is the range of allowable scroll positions around the desired 254 * aScrollPosition. Null means only aScrollPosition is allowed. 255 * This is a closed-ended range --- aRange.XMost()/aRange.YMost() are allowed. 256 */ 257 void ScrollTo( 258 nsPoint aScrollPosition, ScrollMode aMode, 259 ScrollOrigin aOrigin = ScrollOrigin::NotSpecified, 260 const nsRect* aRange = nullptr, 261 nsIScrollbarMediator::ScrollSnapMode aSnap = 262 nsIScrollbarMediator::DISABLE_SNAP, 263 ScrollTriggeredByScript aTriggeredByScript = ScrollTriggeredByScript::No); 264 /** 265 * @note This method might destroy the frame, pres shell and other objects. 266 */ 267 void ScrollToCSSPixels(const CSSIntPoint& aScrollPosition, 268 ScrollMode aMode = ScrollMode::Instant); 269 /** 270 * @note This method might destroy the frame, pres shell and other objects. 271 */ 272 void ScrollToCSSPixelsForApz(const mozilla::CSSPoint& aScrollPosition); 273 274 CSSIntPoint GetScrollPositionCSSPixels(); 275 /** 276 * @note This method might destroy the frame, pres shell and other objects. 277 */ 278 void ScrollToImpl( 279 nsPoint aPt, const nsRect& aRange, 280 ScrollOrigin aOrigin = ScrollOrigin::NotSpecified, 281 ScrollTriggeredByScript aTriggeredByScript = ScrollTriggeredByScript::No); 282 void ScrollVisual(); 283 /** 284 * @note This method might destroy the frame, pres shell and other objects. 285 */ 286 void ScrollBy(nsIntPoint aDelta, mozilla::ScrollUnit aUnit, ScrollMode aMode, 287 nsIntPoint* aOverflow, 288 ScrollOrigin aOrigin = ScrollOrigin::NotSpecified, 289 nsIScrollableFrame::ScrollMomentum aMomentum = 290 nsIScrollableFrame::NOT_MOMENTUM, 291 nsIScrollbarMediator::ScrollSnapMode aSnap = 292 nsIScrollbarMediator::DISABLE_SNAP); 293 void ScrollByCSSPixels(const CSSIntPoint& aDelta, 294 ScrollMode aMode = ScrollMode::Instant); 295 /** 296 * @note This method might destroy the frame, pres shell and other objects. 297 */ 298 void ScrollToRestoredPosition(); 299 300 enum class LoadingState { Loading, Stopped, Loaded }; 301 302 LoadingState GetPageLoadingState(); 303 304 /** 305 * GetSnapPointForDestination determines which point to snap to after 306 * scrolling. aStartPos gives the position before scrolling and aDestination 307 * gives the position after scrolling, with no snapping. Behaviour is 308 * dependent on the value of aUnit. 309 * Returns true if a suitable snap point could be found and aDestination has 310 * been updated to a valid snapping position. 311 */ 312 bool GetSnapPointForDestination(mozilla::ScrollUnit aUnit, 313 const nsPoint& aStartPos, 314 nsPoint& aDestination); 315 316 nsMargin GetScrollPadding() const; 317 318 nsSize GetLineScrollAmount() const; 319 nsSize GetPageScrollAmount() const; 320 321 mozilla::UniquePtr<mozilla::PresState> SaveState() const; 322 void RestoreState(mozilla::PresState* aState); 323 GetScrolledFrame()324 nsIFrame* GetScrolledFrame() const { return mScrolledFrame; } GetScrollbarBox(bool aVertical)325 nsIFrame* GetScrollbarBox(bool aVertical) const { 326 return aVertical ? mVScrollbarBox : mHScrollbarBox; 327 } 328 AddScrollPositionListener(nsIScrollPositionListener * aListener)329 void AddScrollPositionListener(nsIScrollPositionListener* aListener) { 330 mListeners.AppendElement(aListener); 331 } RemoveScrollPositionListener(nsIScrollPositionListener * aListener)332 void RemoveScrollPositionListener(nsIScrollPositionListener* aListener) { 333 mListeners.RemoveElement(aListener); 334 } 335 336 static void SetScrollbarVisibility(nsIFrame* aScrollbar, bool aVisible); 337 338 /** 339 * GetScrolledRect is designed to encapsulate deciding which 340 * directions of overflow should be reachable by scrolling and which 341 * should not. Callers should NOT depend on it having any particular 342 * behavior (although nsXULScrollFrame currently does). 343 * 344 * This should only be called when the scrolled frame has been 345 * reflowed with the scroll port size given in mScrollPort. 346 * 347 * Currently it allows scrolling down and to the right for 348 * nsHTMLScrollFrames with LTR directionality and for all 349 * nsXULScrollFrames, and allows scrolling down and to the left for 350 * nsHTMLScrollFrames with RTL directionality. 351 */ 352 nsRect GetScrolledRect() const; 353 354 /** 355 * GetUnsnappedScrolledRectInternal is designed to encapsulate deciding which 356 * directions of overflow should be reachable by scrolling and which 357 * should not. Callers should NOT depend on it having any particular 358 * behavior (although nsXULScrollFrame currently does). 359 * 360 * Currently it allows scrolling down and to the right for 361 * nsHTMLScrollFrames with LTR directionality and for all 362 * nsXULScrollFrames, and allows scrolling down and to the left for 363 * nsHTMLScrollFrames with RTL directionality. 364 */ 365 nsRect GetUnsnappedScrolledRectInternal(const nsRect& aScrolledOverflowArea, 366 const nsSize& aScrollPortSize) const; 367 368 layers::ScrollDirections GetAvailableScrollingDirectionsForUserInputEvents() 369 const; 370 GetScrollbarVisibility()371 layers::ScrollDirections GetScrollbarVisibility() const { 372 layers::ScrollDirections result; 373 if (mHasHorizontalScrollbar) { 374 result += layers::ScrollDirection::eHorizontal; 375 } 376 if (mHasVerticalScrollbar) { 377 result += layers::ScrollDirection::eVertical; 378 } 379 return result; 380 } 381 nsMargin GetActualScrollbarSizes( 382 nsIScrollableFrame::ScrollbarSizesOptions aOptions = 383 nsIScrollableFrame::ScrollbarSizesOptions::NONE) const; 384 nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState); IsPhysicalLTR()385 bool IsPhysicalLTR() const { 386 return mOuter->GetWritingMode().IsPhysicalLTR(); 387 } IsBidiLTR()388 bool IsBidiLTR() const { return mOuter->GetWritingMode().IsBidiLTR(); } 389 390 private: 391 // NOTE: Use GetScrollStylesFromFrame() if you want to know `overflow` 392 // and `overflow-behavior` properties. 393 nsIFrame* GetFrameForStyle() const; 394 395 // This is the for the old unspecced scroll snap implementation. 396 ScrollSnapInfo ComputeOldScrollSnapInfo() const; 397 // This is the for the scroll snap v1 implementation. 398 ScrollSnapInfo ComputeScrollSnapInfo( 399 const Maybe<nsPoint>& aDestination) const; 400 401 bool NeedsScrollSnap() const; 402 403 // Schedule the scroll-linked animations. 404 void ScheduleScrollAnimations(); TryScheduleScrollAnimations()405 void TryScheduleScrollAnimations() { 406 if (!mMayScheduleScrollAnimations) { 407 return; 408 } 409 ScheduleScrollAnimations(); 410 mMayScheduleScrollAnimations = false; 411 } 412 413 public: 414 bool IsScrollbarOnRight() const; 415 bool IsScrollingActive() const; IsMaybeAsynchronouslyScrolled()416 bool IsMaybeAsynchronouslyScrolled() const { 417 // If this is true, then we'll build an ASR, and that's what we want 418 // to know I think. 419 return mWillBuildScrollableLayer; 420 } 421 422 bool ComputeCustomOverflow(mozilla::OverflowAreas& aOverflowAreas); 423 424 void UpdateSticky(); 425 426 void UpdatePrevScrolledRect(); 427 428 bool IsRectNearlyVisible(const nsRect& aRect) const; 429 nsRect ExpandRectToNearlyVisible(const nsRect& aRect) const; 430 431 // adjust the scrollbar rectangle aRect to account for any visible resizer. 432 // aHasResizer specifies if there is a content resizer, however this method 433 // will also check if a widget resizer is present as well. 434 void AdjustScrollbarRectForResizer( 435 nsIFrame* aFrame, nsPresContext* aPresContext, nsRect& aRect, 436 bool aHasResizer, mozilla::layers::ScrollDirection aDirection); 437 void LayoutScrollbars(nsBoxLayoutState& aState, 438 const nsRect& aInsideBorderArea, 439 const nsRect& aOldScrollPort); 440 441 void MarkScrollbarsDirtyForReflow() const; 442 void InvalidateScrollbars() const; 443 444 bool IsAlwaysActive() const; 445 void MarkEverScrolled(); 446 void MarkRecentlyScrolled(); 447 void MarkNotRecentlyScrolled(); GetExpirationState()448 nsExpirationState* GetExpirationState() { return &mActivityExpirationState; } 449 SetTransformingByAPZ(bool aTransforming)450 void SetTransformingByAPZ(bool aTransforming) { 451 if (mTransformingByAPZ && !aTransforming) { 452 PostScrollEndEvent(); 453 } 454 mTransformingByAPZ = aTransforming; 455 if (!mozilla::css::TextOverflow::HasClippedTextOverflow(mOuter) || 456 mozilla::css::TextOverflow::HasBlockEllipsis(mScrolledFrame)) { 457 // If the block has some overflow marker stuff we should kick off a paint 458 // because we have special behaviour for it when APZ scrolling is active. 459 mOuter->SchedulePaint(); 460 } 461 } IsTransformingByAPZ()462 bool IsTransformingByAPZ() const { return mTransformingByAPZ; } 463 void SetScrollableByAPZ(bool aScrollable); 464 void SetZoomableByAPZ(bool aZoomable); 465 void SetHasOutOfFlowContentInsideFilter(); 466 467 bool UsesOverlayScrollbars() const; 468 469 // In the case where |aDestination| is given, elements which are entirely out 470 // of view when the scroll position is moved to |aDestination| are not going 471 // to be used for snap positions. 472 ScrollSnapInfo GetScrollSnapInfo( 473 const mozilla::Maybe<nsPoint>& aDestination) const; 474 475 static bool ShouldActivateAllScrollFrames(); 476 nsRect RestrictToRootDisplayPort(const nsRect& aDisplayportBase); 477 bool DecideScrollableLayer(nsDisplayListBuilder* aBuilder, 478 nsRect* aVisibleRect, nsRect* aDirtyRect, 479 bool aSetBase, 480 bool* aDirtyRectHasBeenOverriden = nullptr); 481 void NotifyApzTransaction(); 482 void NotifyApproximateFrameVisibilityUpdate(bool aIgnoreDisplayPort); 483 bool GetDisplayPortAtLastApproximateFrameVisibilityUpdate( 484 nsRect* aDisplayPort); 485 486 bool AllowDisplayPortExpiration(); 487 void TriggerDisplayPortExpiration(); 488 void ResetDisplayPortExpiryTimer(); 489 490 void ScheduleSyntheticMouseMove(); 491 static void ScrollActivityCallback(nsITimer* aTimer, void* anInstance); 492 493 void HandleScrollbarStyleSwitching(); 494 LastScrollOrigin()495 ScrollOrigin LastScrollOrigin() const { return mLastScrollOrigin; } IsApzAnimationInProgress()496 bool IsApzAnimationInProgress() const { 497 return mCurrentAPZScrollAnimationType != APZScrollAnimationType::No; 498 } CurrentScrollGeneration()499 MainThreadScrollGeneration CurrentScrollGeneration() const { 500 return mScrollGeneration; 501 } ScrollGenerationOnApz()502 APZScrollGeneration ScrollGenerationOnApz() const { 503 return mScrollGenerationOnApz; 504 } LastScrollDestination()505 nsPoint LastScrollDestination() const { return mDestination; } 506 nsTArray<ScrollPositionUpdate> GetScrollUpdates() const; HasScrollUpdates()507 bool HasScrollUpdates() const { return !mScrollUpdates.IsEmpty(); } 508 509 bool IsLastScrollUpdateAnimating() const; 510 using IncludeApzAnimation = nsIScrollableFrame::IncludeApzAnimation; 511 bool IsScrollAnimating(IncludeApzAnimation = IncludeApzAnimation::Yes) const; 512 513 void ResetScrollInfoIfNeeded(const MainThreadScrollGeneration& aGeneration, 514 const APZScrollGeneration& aGenerationOnApz, 515 APZScrollAnimationType aAPZScrollAnimationType); 516 bool WantAsyncScroll() const; 517 Maybe<mozilla::layers::ScrollMetadata> ComputeScrollMetadata( 518 WebRenderLayerManager* aLayerManager, const nsIFrame* aItemFrame, 519 const nsPoint& aOffsetToReferenceFrame) const; 520 // nsIScrollbarMediator 521 void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection, 522 nsIScrollbarMediator::ScrollSnapMode aSnap = 523 nsIScrollbarMediator::DISABLE_SNAP); 524 void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection, 525 nsIScrollbarMediator::ScrollSnapMode aSnap = 526 nsIScrollbarMediator::DISABLE_SNAP); 527 void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection, 528 nsIScrollbarMediator::ScrollSnapMode aSnap = 529 nsIScrollbarMediator::DISABLE_SNAP); 530 void ScrollByUnit(nsScrollbarFrame* aScrollbar, ScrollMode aMode, 531 int32_t aDirection, ScrollUnit aUnit, 532 nsIScrollbarMediator::ScrollSnapMode aSnap = 533 nsIScrollbarMediator::DISABLE_SNAP); 534 void RepeatButtonScroll(nsScrollbarFrame* aScrollbar); 535 void ThumbMoved(nsScrollbarFrame* aScrollbar, nscoord aOldPos, 536 nscoord aNewPos); 537 void ScrollbarReleased(nsScrollbarFrame* aScrollbar); ShouldSuppressScrollbarRepaints()538 bool ShouldSuppressScrollbarRepaints() const { 539 return mSuppressScrollbarRepaints; 540 } 541 542 bool DragScroll(WidgetEvent* aEvent); 543 544 void AsyncScrollbarDragInitiated(uint64_t aDragBlockId, 545 mozilla::layers::ScrollDirection aDirection); 546 void AsyncScrollbarDragRejected(); 547 IsRootScrollFrameOfDocument()548 bool IsRootScrollFrameOfDocument() const { return mIsRoot; } 549 550 bool SmoothScrollVisual( 551 const nsPoint& aVisualViewportOffset, 552 mozilla::layers::FrameMetrics::ScrollOffsetUpdateType aUpdateType); 553 554 bool IsSmoothScroll(mozilla::dom::ScrollBehavior aBehavior) const; 555 556 // Update minimum-scale size. The minimum-scale size will be set/used only 557 // if there is overflow-x:hidden region. 558 void UpdateMinimumScaleSize(const nsRect& aScrollableOverflow, 559 const nsSize& aICBSize); 560 561 // Return the scroll frame's "true outer size". 562 // This is mOuter->GetSize(), except when mOuter has been sized to reflect 563 // a virtual (layout) viewport in which case this returns the outer size 564 // used to size the physical (visual) viewport. 565 nsSize TrueOuterSize(nsDisplayListBuilder* aBuilder) const; 566 567 already_AddRefed<Element> MakeScrollbar(dom::NodeInfo* aNodeInfo, 568 bool aVertical, 569 AnonymousContentKey& aKey); 570 571 void AppendScrollUpdate(const ScrollPositionUpdate& aUpdate); 572 573 // owning references to the nsIAnonymousContentCreator-built content 574 nsCOMPtr<Element> mHScrollbarContent; 575 nsCOMPtr<Element> mVScrollbarContent; 576 nsCOMPtr<Element> mScrollCornerContent; 577 nsCOMPtr<Element> mResizerContent; 578 579 class ScrollEvent; 580 class ScrollEndEvent; 581 class AsyncScrollPortEvent; 582 class ScrolledAreaEvent; 583 584 RefPtr<ScrollEvent> mScrollEvent; 585 RefPtr<ScrollEndEvent> mScrollEndEvent; 586 nsRevocableEventPtr<AsyncScrollPortEvent> mAsyncScrollPortEvent; 587 nsRevocableEventPtr<ScrolledAreaEvent> mScrolledAreaEvent; 588 nsIFrame* mHScrollbarBox; 589 nsIFrame* mVScrollbarBox; 590 nsIFrame* mScrolledFrame; 591 nsIFrame* mScrollCornerBox; 592 nsIFrame* mResizerBox; 593 nsContainerFrame* mOuter; 594 const nsIFrame* mReferenceFrameDuringPainting; 595 RefPtr<AsyncScroll> mAsyncScroll; 596 RefPtr<AsyncSmoothMSDScroll> mAsyncSmoothMSDScroll; 597 RefPtr<ScrollbarActivity> mScrollbarActivity; 598 nsTArray<nsIScrollPositionListener*> mListeners; 599 ScrollOrigin mLastScrollOrigin; 600 Maybe<nsPoint> mApzSmoothScrollDestination; 601 MainThreadScrollGeneration mScrollGeneration; 602 APZScrollGeneration mScrollGenerationOnApz; 603 604 nsTArray<ScrollPositionUpdate> mScrollUpdates; 605 606 nsSize mMinimumScaleSize; 607 608 // Stores the ICB size for the root document if this frame is using the 609 // minimum scale size for |mScrollPort|. 610 nsSize mICBSize; 611 612 // Where we're currently scrolling to, if we're scrolling asynchronously. 613 // If we're not in the middle of an asynchronous scroll then this is 614 // just the current scroll position. ScrollBy will choose its 615 // destination based on this value. 616 nsPoint mDestination; 617 618 // A goal position to try to scroll to as content loads. As long as mLastPos 619 // matches the current logical scroll position, we try to scroll to 620 // mRestorePos after every reflow --- because after each time content is 621 // loaded/added to the scrollable element, there will be a reflow. 622 // Note that for frames where layout and visual viewport aren't one and the 623 // same thing, this scroll position will be the logical scroll position of 624 // the *visual* viewport, as its position will be more relevant to the user. 625 nsPoint mRestorePos; 626 // The last logical position we scrolled to while trying to restore 627 // mRestorePos, or 0,0 when this is a new frame. Set to -1,-1 once we've 628 // scrolled for any reason other than trying to restore mRestorePos. 629 // Just as with mRestorePos, this position will be the logical position of 630 // the *visual* viewport where available. 631 nsPoint mLastPos; 632 633 // The latest scroll position we've sent or received from APZ. This 634 // represents the main thread's best knowledge of the APZ scroll position, 635 // and is used to calculate relative scroll offset updates. 636 nsPoint mApzScrollPos; 637 638 nsExpirationState mActivityExpirationState; 639 640 nsCOMPtr<nsITimer> mScrollActivityTimer; 641 642 // The scroll position where we last updated frame visibility. 643 nsPoint mLastUpdateFramesPos; 644 nsRect mDisplayPortAtLastFrameUpdate; 645 646 nsRect mPrevScrolledRect; 647 648 ScrollableLayerGuid::ViewID mScrollParentID; 649 650 // Timer to remove the displayport some time after scrolling has stopped 651 nsCOMPtr<nsITimer> mDisplayPortExpiryTimer; 652 653 ScrollAnchorContainer mAnchor; 654 655 // Representing there's an APZ animation is in progress and what caused the 656 // animation. Note that this is only set when repainted via APZ, which means 657 // that there may be a request for an APZ animation in flight for example, 658 // while this is still `No`. In order to answer "is an APZ animation in the 659 // process of starting or in progress" you need to check mScrollUpdates, 660 // mApzAnimationRequested, and this type. 661 APZScrollAnimationType mCurrentAPZScrollAnimationType; 662 663 bool mAllowScrollOriginDowngrade : 1; 664 bool mHadDisplayPortAtLastFrameUpdate : 1; 665 666 // True if the most recent reflow of the scroll container frame (mOuter) has 667 // the vertical scrollbar shown. 668 bool mHasVerticalScrollbar : 1; 669 // True if the most recent reflow of the scroll container frame (mOuter) has 670 // the horizontal scrollbar shown. 671 bool mHasHorizontalScrollbar : 1; 672 673 // If mHas(Vertical|Horizontal)Scrollbar is true then 674 // mOnlyNeed(V|H)ScrollbarToScrollVVInsideLV indicates if the only reason we 675 // need that scrollbar is to scroll the visual viewport inside the layout 676 // viewport. These scrollbars are special in that even if they are layout 677 // scrollbars they do not take up any layout space. 678 bool mOnlyNeedVScrollbarToScrollVVInsideLV : 1; 679 bool mOnlyNeedHScrollbarToScrollVVInsideLV : 1; 680 bool mFrameIsUpdatingScrollbar : 1; 681 bool mDidHistoryRestore : 1; 682 // Is this the scrollframe for the document's viewport? 683 bool mIsRoot : 1; 684 // If true, don't try to layout the scrollbars in Reflow(). This can be 685 // useful if multiple passes are involved, because we don't want to place the 686 // scrollbars at the wrong size. 687 bool mSuppressScrollbarUpdate : 1; 688 // If true, we skipped a scrollbar layout due to mSuppressScrollbarUpdate 689 // being set at some point. That means we should lay out scrollbars even if 690 // it might not strictly be needed next time mSuppressScrollbarUpdate is 691 // false. 692 bool mSkippedScrollbarLayout : 1; 693 694 bool mHadNonInitialReflow : 1; 695 // Initially true; first call to ReflowFinished() sets it to false. 696 bool mFirstReflow : 1; 697 // State used only by PostScrollEvents so we know 698 // which overflow states have changed. 699 bool mHorizontalOverflow : 1; 700 bool mVerticalOverflow : 1; 701 bool mPostedReflowCallback : 1; 702 bool mMayHaveDirtyFixedChildren : 1; 703 // If true, need to actually update our scrollbar attributes in the 704 // reflow callback. 705 bool mUpdateScrollbarAttributes : 1; 706 // If true, we should be prepared to scroll using this scrollframe 707 // by placing descendant content into its own layer(s) 708 bool mHasBeenScrolledRecently : 1; 709 710 // If true, the scroll frame should always be active because we always build 711 // a scrollable layer. Used for asynchronous scrolling. 712 bool mWillBuildScrollableLayer : 1; 713 714 // If true, the scroll frame is an ancestor of other "active" scrolling 715 // frames, where "active" means has a non-minimal display port if 716 // ShouldActivateAllScrollFrames is true, or has a display port if 717 // ShouldActivateAllScrollFrames is false. And this means that we shouldn't 718 // expire the display port (if ShouldActivateAllScrollFrames is true then 719 // expiring a display port means making it minimal, otherwise it means 720 // removing the display port). If those descendant scrollframes have their 721 // display ports removed or made minimal, then we expire our display port. 722 bool mIsParentToActiveScrollFrames : 1; 723 724 // True if this frame has been scrolled at least once 725 bool mHasBeenScrolled : 1; 726 727 // True if the events synthesized by OSX to produce momentum scrolling should 728 // be ignored. Reset when the next real, non-synthesized scroll event occurs. 729 bool mIgnoreMomentumScroll : 1; 730 731 // True if the APZ is in the process of async-transforming this scrollframe, 732 // (as best as we can tell on the main thread, anyway). 733 bool mTransformingByAPZ : 1; 734 735 // True if APZ can scroll this frame asynchronously (i.e. it has an APZC 736 // set up for this frame and it's not a scrollinfo layer). 737 bool mScrollableByAPZ : 1; 738 739 // True if the APZ is allowed to zoom this scrollframe. 740 bool mZoomableByAPZ : 1; 741 742 // True if the scroll frame contains out-of-flow content and is inside 743 // a CSS filter. 744 bool mHasOutOfFlowContentInsideFilter : 1; 745 746 // True if we don't want the scrollbar to repaint itself right now. 747 bool mSuppressScrollbarRepaints : 1; 748 749 // True if we are using the minimum scale size instead of ICB for scroll port. 750 bool mIsUsingMinimumScaleSize : 1; 751 752 // True if the minimum scale size has been changed since the last reflow. 753 bool mMinimumScaleSizeChanged : 1; 754 755 // True if we're processing an scroll event. 756 bool mProcessingScrollEvent : 1; 757 758 // This is true from the time a scroll animation is requested of APZ to the 759 // time that APZ responds with an up-to-date repaint request. More precisely, 760 // this is flipped to true if a repaint request is dispatched to APZ where 761 // the most recent scroll request is a smooth scroll, and it is cleared when 762 // mApzAnimationInProgress is updated. 763 bool mApzAnimationRequested : 1; 764 765 // Whether we need to reclamp the visual viewport offset in ReflowFinished. 766 bool mReclampVVOffsetInReflowFinished : 1; 767 768 // Whether we need to schedule the scroll-linked animations. 769 bool mMayScheduleScrollAnimations : 1; 770 771 #ifdef MOZ_WIDGET_ANDROID 772 // True if this scrollable frame was vertically overflowed on the last reflow. 773 bool mHasVerticalOverflowForDynamicToolbar : 1; 774 #endif 775 776 mozilla::layout::ScrollVelocityQueue mVelocityQueue; 777 778 protected: 779 class AutoScrollbarRepaintSuppression; 780 friend class AutoScrollbarRepaintSuppression; 781 class AutoScrollbarRepaintSuppression { 782 public: AutoScrollbarRepaintSuppression(ScrollFrameHelper * aHelper,AutoWeakFrame & aWeakOuter,bool aSuppress)783 AutoScrollbarRepaintSuppression(ScrollFrameHelper* aHelper, 784 AutoWeakFrame& aWeakOuter, bool aSuppress) 785 : mHelper(aHelper), 786 mWeakOuter(aWeakOuter), 787 mOldSuppressValue(aHelper->mSuppressScrollbarRepaints) { 788 mHelper->mSuppressScrollbarRepaints = aSuppress; 789 } 790 ~AutoScrollbarRepaintSuppression()791 ~AutoScrollbarRepaintSuppression() { 792 if (mWeakOuter.IsAlive()) { 793 mHelper->mSuppressScrollbarRepaints = mOldSuppressValue; 794 } 795 } 796 797 private: 798 ScrollFrameHelper* mHelper; 799 AutoWeakFrame& mWeakOuter; 800 bool mOldSuppressValue; 801 }; 802 803 /** 804 * @note This method might destroy the frame, pres shell and other objects. 805 */ 806 void ScrollToWithOrigin( 807 nsPoint aScrollPosition, ScrollMode aMode, ScrollOrigin aOrigin, 808 const nsRect* aRange, 809 nsIScrollbarMediator::ScrollSnapMode aSnap = 810 nsIScrollbarMediator::DISABLE_SNAP, 811 ScrollTriggeredByScript aTriggeredByScript = ScrollTriggeredByScript::No); 812 813 void CompleteAsyncScroll(const nsRect& aRange, 814 ScrollOrigin aOrigin = ScrollOrigin::NotSpecified); 815 HasPerspective()816 bool HasPerspective() const { return mOuter->ChildrenHavePerspective(); } 817 bool HasBgAttachmentLocal() const; 818 mozilla::StyleDirection GetScrolledFrameDir() const; 819 820 // Ask APZ to smooth scroll to |aDestination|. 821 // This method does not clamp the destination; callers should clamp it to 822 // either the layout or the visual scroll range (APZ will happily smooth 823 // scroll to either). 824 void ApzSmoothScrollTo(const nsPoint& aDestination, ScrollOrigin aOrigin, 825 ScrollTriggeredByScript aTriggeredByScript); 826 827 // Removes any RefreshDriver observers we might have registered. 828 void RemoveObservers(); 829 830 private: 831 // NOTE: On mobile this value might be factoring into overflow:hidden region 832 // in the case of the top level document. 833 nsRect mScrollPort; 834 }; 835 836 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(ScrollFrameHelper::OverflowState) 837 838 } // namespace mozilla 839 840 /** 841 * The scroll frame creates and manages the scrolling view 842 * 843 * It only supports having a single child frame that typically is an area 844 * frame, but doesn't have to be. The child frame must have a view, though 845 * 846 * Scroll frames don't support incremental changes, i.e. you can't replace 847 * or remove the scrolled frame 848 */ 849 class nsHTMLScrollFrame : public nsContainerFrame, 850 public nsIScrollableFrame, 851 public nsIAnonymousContentCreator, 852 public nsIStatefulFrame { 853 public: 854 using ScrollFrameHelper = mozilla::ScrollFrameHelper; 855 using CSSIntPoint = mozilla::CSSIntPoint; 856 using ScrollReflowInput = mozilla::ScrollReflowInput; 857 using ScrollAnchorContainer = mozilla::layout::ScrollAnchorContainer; 858 friend nsHTMLScrollFrame* NS_NewHTMLScrollFrame( 859 mozilla::PresShell* aPresShell, ComputedStyle* aStyle, bool aIsRoot); 860 861 NS_DECL_QUERYFRAME NS_DECL_FRAMEARENA_HELPERS(nsHTMLScrollFrame)862 NS_DECL_FRAMEARENA_HELPERS(nsHTMLScrollFrame) 863 864 void BuildDisplayList(nsDisplayListBuilder* aBuilder, 865 const nsDisplayListSet& aLists) override { 866 mHelper.BuildDisplayList(aBuilder, aLists); 867 } 868 869 bool TryLayout(ScrollReflowInput& aState, ReflowOutput* aKidMetrics, 870 bool aAssumeHScroll, bool aAssumeVScroll, bool aForce); 871 872 // Return true if ReflowScrolledFrame is going to do something different based 873 // on the presence of a horizontal scrollbar in a horizontal writing mode or a 874 // vertical scrollbar in a vertical writing mode. 875 bool ScrolledContentDependsOnBSize(const ScrollReflowInput& aState) const; 876 877 void ReflowScrolledFrame(ScrollReflowInput& aState, bool aAssumeHScroll, 878 bool aAssumeVScroll, ReflowOutput* aMetrics); 879 void ReflowContents(ScrollReflowInput& aState, 880 const ReflowOutput& aDesiredSize); 881 void PlaceScrollArea(ScrollReflowInput& aState, 882 const nsPoint& aScrollPosition); 883 884 // Return the sum of inline-size of the scrollbar gutters (if any) at the 885 // inline-start and inline-end edges of the scroll frame (for a potential 886 // scrollbar that scrolls in the block axis). 887 nscoord IntrinsicScrollbarGutterSizeAtInlineEdges( 888 gfxContext* aRenderingContext); 889 GetBorderRadii(const nsSize & aFrameSize,const nsSize & aBorderArea,Sides aSkipSides,nscoord aRadii[8])890 bool GetBorderRadii(const nsSize& aFrameSize, const nsSize& aBorderArea, 891 Sides aSkipSides, nscoord aRadii[8]) const final { 892 return mHelper.GetBorderRadii(aFrameSize, aBorderArea, aSkipSides, aRadii); 893 } 894 895 nscoord GetMinISize(gfxContext* aRenderingContext) override; 896 nscoord GetPrefISize(gfxContext* aRenderingContext) override; 897 nsresult GetXULPadding(nsMargin& aPadding) final; 898 bool IsXULCollapsed() final; 899 900 void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize, 901 const ReflowInput& aReflowInput, 902 nsReflowStatus& aStatus) override; 903 void DidReflow(nsPresContext* aPresContext, 904 const ReflowInput* aReflowInput) override; 905 ComputeCustomOverflow(mozilla::OverflowAreas & aOverflowAreas)906 bool ComputeCustomOverflow(mozilla::OverflowAreas& aOverflowAreas) final { 907 return mHelper.ComputeCustomOverflow(aOverflowAreas); 908 } 909 910 nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode) const final; 911 GetVerticalAlignBaseline(mozilla::WritingMode aWM,nscoord * aBaseline)912 bool GetVerticalAlignBaseline(mozilla::WritingMode aWM, 913 nscoord* aBaseline) const final { 914 NS_ASSERTION(!aWM.IsOrthogonalTo(GetWritingMode()), 915 "You should only call this on frames with a WM that's " 916 "parallel to aWM"); 917 *aBaseline = GetLogicalBaseline(aWM); 918 return true; 919 } 920 921 // Recomputes the scrollable overflow area we store in the helper to take 922 // children that are affected by perpsective set on the outer frame and scroll 923 // at different rates. 924 void AdjustForPerspective(nsRect& aScrollableOverflow); 925 926 // Called to set the child frames. We typically have three: the scroll area, 927 // the vertical scrollbar, and the horizontal scrollbar. 928 void SetInitialChildList(ChildListID aListID, 929 nsFrameList& aChildList) override; 930 void AppendFrames(ChildListID aListID, nsFrameList& aFrameList) final; 931 void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, 932 const nsLineList::iterator* aPrevFrameLine, 933 nsFrameList& aFrameList) final; 934 void RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) final; 935 936 void DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData&) override; 937 GetScrollTargetFrame()938 nsIScrollableFrame* GetScrollTargetFrame() const final { 939 return const_cast<nsHTMLScrollFrame*>(this); 940 } 941 GetContentInsertionFrame()942 nsContainerFrame* GetContentInsertionFrame() override { 943 return mHelper.GetScrolledFrame()->GetContentInsertionFrame(); 944 } 945 DoesClipChildrenInBothAxes()946 bool DoesClipChildrenInBothAxes() final { return true; } 947 GetPositionOfChildIgnoringScrolling(const nsIFrame * aChild)948 nsPoint GetPositionOfChildIgnoringScrolling(const nsIFrame* aChild) final { 949 nsPoint pt = aChild->GetPosition(); 950 if (aChild == mHelper.GetScrolledFrame()) pt += GetScrollPosition(); 951 return pt; 952 } 953 954 // nsIAnonymousContentCreator 955 nsresult CreateAnonymousContent(nsTArray<ContentInfo>&) final; 956 void AppendAnonymousContentTo(nsTArray<nsIContent*>&, uint32_t aFilter) final; 957 958 // nsIScrollableFrame GetScrolledFrame()959 nsIFrame* GetScrolledFrame() const final { 960 return mHelper.GetScrolledFrame(); 961 } GetScrollStyles()962 mozilla::ScrollStyles GetScrollStyles() const override { 963 return mHelper.GetScrollStylesFromFrame(); 964 } IsForTextControlWithNoScrollbars()965 bool IsForTextControlWithNoScrollbars() const final { 966 return mHelper.IsForTextControlWithNoScrollbars(); 967 } HasAllNeededScrollbars()968 bool HasAllNeededScrollbars() const final { 969 return mHelper.HasAllNeededScrollbars(); 970 } GetOverscrollBehaviorInfo()971 mozilla::layers::OverscrollBehaviorInfo GetOverscrollBehaviorInfo() 972 const final { 973 return mHelper.GetOverscrollBehaviorInfo(); 974 } 975 mozilla::layers::ScrollDirections GetAvailableScrollingDirectionsForUserInputEvents()976 GetAvailableScrollingDirectionsForUserInputEvents() const final { 977 return mHelper.GetAvailableScrollingDirectionsForUserInputEvents(); 978 } GetScrollbarVisibility()979 mozilla::layers::ScrollDirections GetScrollbarVisibility() const final { 980 return mHelper.GetScrollbarVisibility(); 981 } 982 nsMargin GetActualScrollbarSizes( 983 nsIScrollableFrame::ScrollbarSizesOptions aOptions = 984 nsIScrollableFrame::ScrollbarSizesOptions::NONE) const final { 985 return mHelper.GetActualScrollbarSizes(aOptions); 986 } GetDesiredScrollbarSizes(nsBoxLayoutState * aState)987 nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState) final { 988 return mHelper.GetDesiredScrollbarSizes(aState); 989 } GetDesiredScrollbarSizes(nsPresContext * aPresContext,gfxContext * aRC)990 nsMargin GetDesiredScrollbarSizes(nsPresContext* aPresContext, 991 gfxContext* aRC) final { 992 nsBoxLayoutState bls(aPresContext, aRC, 0); 993 return GetDesiredScrollbarSizes(&bls); 994 } GetLayoutSize()995 nsSize GetLayoutSize() const final { return mHelper.GetLayoutSize(); } GetScrolledRect()996 nsRect GetScrolledRect() const final { return mHelper.GetScrolledRect(); } GetScrollPortRect()997 nsRect GetScrollPortRect() const final { return mHelper.GetScrollPortRect(); } GetScrollPosition()998 nsPoint GetScrollPosition() const final { 999 return mHelper.GetScrollPosition(); 1000 } GetLogicalScrollPosition()1001 nsPoint GetLogicalScrollPosition() const final { 1002 return mHelper.GetLogicalScrollPosition(); 1003 } GetScrollRange()1004 nsRect GetScrollRange() const final { return mHelper.GetLayoutScrollRange(); } GetVisualViewportSize()1005 nsSize GetVisualViewportSize() const final { 1006 return mHelper.GetVisualViewportSize(); 1007 } GetVisualViewportOffset()1008 nsPoint GetVisualViewportOffset() const final { 1009 return mHelper.GetVisualViewportOffset(); 1010 } SetVisualViewportOffset(const nsPoint & aOffset,bool aRepaint)1011 bool SetVisualViewportOffset(const nsPoint& aOffset, bool aRepaint) final { 1012 return mHelper.SetVisualViewportOffset(aOffset, aRepaint); 1013 } GetVisualScrollRange()1014 nsRect GetVisualScrollRange() const final { 1015 return mHelper.GetVisualScrollRange(); 1016 } GetScrollRangeForUserInputEvents()1017 nsRect GetScrollRangeForUserInputEvents() const final { 1018 return mHelper.GetScrollRangeForUserInputEvents(); 1019 } GetLineScrollAmount()1020 nsSize GetLineScrollAmount() const final { 1021 return mHelper.GetLineScrollAmount(); 1022 } GetPageScrollAmount()1023 nsSize GetPageScrollAmount() const final { 1024 return mHelper.GetPageScrollAmount(); 1025 } GetScrollPadding()1026 nsMargin GetScrollPadding() const final { return mHelper.GetScrollPadding(); } 1027 /** 1028 * @note This method might destroy the frame, pres shell and other objects. 1029 */ 1030 void ScrollTo(nsPoint aScrollPosition, ScrollMode aMode, 1031 const nsRect* aRange = nullptr, 1032 nsIScrollbarMediator::ScrollSnapMode aSnap = 1033 nsIScrollbarMediator::DISABLE_SNAP, 1034 mozilla::ScrollTriggeredByScript aTriggeredByScript = 1035 mozilla::ScrollTriggeredByScript::No) final { 1036 mHelper.ScrollTo(aScrollPosition, aMode, ScrollOrigin::Other, aRange, 1037 aSnap); 1038 } 1039 /** 1040 * @note This method might destroy the frame, pres shell and other objects. 1041 */ 1042 void ScrollToCSSPixels(const CSSIntPoint& aScrollPosition, 1043 ScrollMode aMode = ScrollMode::Instant) final { 1044 mHelper.ScrollToCSSPixels(aScrollPosition, aMode); 1045 } ScrollToCSSPixelsForApz(const mozilla::CSSPoint & aScrollPosition)1046 void ScrollToCSSPixelsForApz(const mozilla::CSSPoint& aScrollPosition) final { 1047 mHelper.ScrollToCSSPixelsForApz(aScrollPosition); 1048 } 1049 /** 1050 * @note This method might destroy the frame, pres shell and other objects. 1051 */ GetScrollPositionCSSPixels()1052 CSSIntPoint GetScrollPositionCSSPixels() final { 1053 return mHelper.GetScrollPositionCSSPixels(); 1054 } 1055 /** 1056 * @note This method might destroy the frame, pres shell and other objects. 1057 */ 1058 void ScrollBy(nsIntPoint aDelta, mozilla::ScrollUnit aUnit, ScrollMode aMode, 1059 nsIntPoint* aOverflow, 1060 ScrollOrigin aOrigin = ScrollOrigin::NotSpecified, 1061 nsIScrollableFrame::ScrollMomentum aMomentum = 1062 nsIScrollableFrame::NOT_MOMENTUM, 1063 nsIScrollbarMediator::ScrollSnapMode aSnap = 1064 nsIScrollbarMediator::DISABLE_SNAP) final { 1065 mHelper.ScrollBy(aDelta, aUnit, aMode, aOverflow, aOrigin, aMomentum, 1066 aSnap); 1067 } 1068 void ScrollByCSSPixels(const CSSIntPoint& aDelta, 1069 ScrollMode aMode = ScrollMode::Instant) final { 1070 mHelper.ScrollByCSSPixels(aDelta, aMode); 1071 } ScrollSnap()1072 void ScrollSnap() final { mHelper.ScrollSnap(); } 1073 /** 1074 * @note This method might destroy the frame, pres shell and other objects. 1075 */ ScrollToRestoredPosition()1076 void ScrollToRestoredPosition() final { mHelper.ScrollToRestoredPosition(); } AddScrollPositionListener(nsIScrollPositionListener * aListener)1077 void AddScrollPositionListener(nsIScrollPositionListener* aListener) final { 1078 mHelper.AddScrollPositionListener(aListener); 1079 } RemoveScrollPositionListener(nsIScrollPositionListener * aListener)1080 void RemoveScrollPositionListener( 1081 nsIScrollPositionListener* aListener) final { 1082 mHelper.RemoveScrollPositionListener(aListener); 1083 } 1084 /** 1085 * @note This method might destroy the frame, pres shell and other objects. 1086 */ CurPosAttributeChanged(nsIContent * aChild)1087 void CurPosAttributeChanged(nsIContent* aChild) final { 1088 mHelper.CurPosAttributeChanged(aChild); 1089 } PostScrolledAreaEventForCurrentArea()1090 NS_IMETHOD PostScrolledAreaEventForCurrentArea() final { 1091 mHelper.PostScrolledAreaEvent(); 1092 return NS_OK; 1093 } IsScrollingActive()1094 bool IsScrollingActive() final { return mHelper.IsScrollingActive(); } IsMaybeAsynchronouslyScrolled()1095 bool IsMaybeAsynchronouslyScrolled() final { 1096 return mHelper.IsMaybeAsynchronouslyScrolled(); 1097 } DidHistoryRestore()1098 bool DidHistoryRestore() const final { return mHelper.mDidHistoryRestore; } ClearDidHistoryRestore()1099 void ClearDidHistoryRestore() final { mHelper.mDidHistoryRestore = false; } MarkEverScrolled()1100 void MarkEverScrolled() final { mHelper.MarkEverScrolled(); } IsRectNearlyVisible(const nsRect & aRect)1101 bool IsRectNearlyVisible(const nsRect& aRect) final { 1102 return mHelper.IsRectNearlyVisible(aRect); 1103 } ExpandRectToNearlyVisible(const nsRect & aRect)1104 nsRect ExpandRectToNearlyVisible(const nsRect& aRect) const final { 1105 return mHelper.ExpandRectToNearlyVisible(aRect); 1106 } LastScrollOrigin()1107 ScrollOrigin LastScrollOrigin() final { return mHelper.LastScrollOrigin(); } IsScrollAnimating(IncludeApzAnimation aIncludeApz)1108 bool IsScrollAnimating(IncludeApzAnimation aIncludeApz) final { 1109 return mHelper.IsScrollAnimating(aIncludeApz); 1110 } CurrentScrollGeneration()1111 mozilla::MainThreadScrollGeneration CurrentScrollGeneration() const final { 1112 return mHelper.CurrentScrollGeneration(); 1113 } ScrollGenerationOnApz()1114 mozilla::APZScrollGeneration ScrollGenerationOnApz() const final { 1115 return mHelper.ScrollGenerationOnApz(); 1116 } LastScrollDestination()1117 nsPoint LastScrollDestination() final { 1118 return mHelper.LastScrollDestination(); 1119 } GetScrollUpdates()1120 nsTArray<mozilla::ScrollPositionUpdate> GetScrollUpdates() const final { 1121 return mHelper.GetScrollUpdates(); 1122 } HasScrollUpdates()1123 bool HasScrollUpdates() const final { return mHelper.HasScrollUpdates(); } ResetScrollInfoIfNeeded(const mozilla::MainThreadScrollGeneration & aGeneration,const mozilla::APZScrollGeneration & aGenerationOnApz,mozilla::APZScrollAnimationType aAPZScrollAnimationType)1124 void ResetScrollInfoIfNeeded( 1125 const mozilla::MainThreadScrollGeneration& aGeneration, 1126 const mozilla::APZScrollGeneration& aGenerationOnApz, 1127 mozilla::APZScrollAnimationType aAPZScrollAnimationType) final { 1128 mHelper.ResetScrollInfoIfNeeded(aGeneration, aGenerationOnApz, 1129 aAPZScrollAnimationType); 1130 } WantAsyncScroll()1131 bool WantAsyncScroll() const final { return mHelper.WantAsyncScroll(); } ComputeScrollMetadata(mozilla::layers::WebRenderLayerManager * aLayerManager,const nsIFrame * aItemFrame,const nsPoint & aOffsetToReferenceFrame)1132 mozilla::Maybe<mozilla::layers::ScrollMetadata> ComputeScrollMetadata( 1133 mozilla::layers::WebRenderLayerManager* aLayerManager, 1134 const nsIFrame* aItemFrame, 1135 const nsPoint& aOffsetToReferenceFrame) const final { 1136 return mHelper.ComputeScrollMetadata(aLayerManager, aItemFrame, 1137 aOffsetToReferenceFrame); 1138 } MarkScrollbarsDirtyForReflow()1139 void MarkScrollbarsDirtyForReflow() const final { 1140 mHelper.MarkScrollbarsDirtyForReflow(); 1141 } InvalidateScrollbars()1142 void InvalidateScrollbars() const final { mHelper.InvalidateScrollbars(); } 1143 UpdateScrollbarPosition()1144 void UpdateScrollbarPosition() final { mHelper.UpdateScrollbarPosition(); } DecideScrollableLayer(nsDisplayListBuilder * aBuilder,nsRect * aVisibleRect,nsRect * aDirtyRect,bool aSetBase)1145 bool DecideScrollableLayer(nsDisplayListBuilder* aBuilder, 1146 nsRect* aVisibleRect, nsRect* aDirtyRect, 1147 bool aSetBase) final { 1148 return mHelper.DecideScrollableLayer(aBuilder, aVisibleRect, aDirtyRect, 1149 aSetBase); 1150 } NotifyApzTransaction()1151 void NotifyApzTransaction() final { mHelper.NotifyApzTransaction(); } NotifyApproximateFrameVisibilityUpdate(bool aIgnoreDisplayPort)1152 void NotifyApproximateFrameVisibilityUpdate(bool aIgnoreDisplayPort) final { 1153 mHelper.NotifyApproximateFrameVisibilityUpdate(aIgnoreDisplayPort); 1154 } GetDisplayPortAtLastApproximateFrameVisibilityUpdate(nsRect * aDisplayPort)1155 bool GetDisplayPortAtLastApproximateFrameVisibilityUpdate( 1156 nsRect* aDisplayPort) final { 1157 return mHelper.GetDisplayPortAtLastApproximateFrameVisibilityUpdate( 1158 aDisplayPort); 1159 } TriggerDisplayPortExpiration()1160 void TriggerDisplayPortExpiration() final { 1161 mHelper.TriggerDisplayPortExpiration(); 1162 } 1163 1164 // nsIStatefulFrame SaveState()1165 mozilla::UniquePtr<mozilla::PresState> SaveState() final { 1166 return mHelper.SaveState(); 1167 } RestoreState(mozilla::PresState * aState)1168 NS_IMETHOD RestoreState(mozilla::PresState* aState) final { 1169 NS_ENSURE_ARG_POINTER(aState); 1170 mHelper.RestoreState(aState); 1171 return NS_OK; 1172 } 1173 1174 // nsIScrollbarMediator 1175 void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection, 1176 nsIScrollbarMediator::ScrollSnapMode aSnap = 1177 nsIScrollbarMediator::DISABLE_SNAP) final { 1178 mHelper.ScrollByPage(aScrollbar, aDirection, aSnap); 1179 } 1180 void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection, 1181 nsIScrollbarMediator::ScrollSnapMode aSnap = 1182 nsIScrollbarMediator::DISABLE_SNAP) final { 1183 mHelper.ScrollByWhole(aScrollbar, aDirection, aSnap); 1184 } 1185 void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection, 1186 nsIScrollbarMediator::ScrollSnapMode aSnap = 1187 nsIScrollbarMediator::DISABLE_SNAP) final { 1188 mHelper.ScrollByLine(aScrollbar, aDirection, aSnap); 1189 } 1190 void ScrollByUnit(nsScrollbarFrame* aScrollbar, ScrollMode aMode, 1191 int32_t aDirection, mozilla::ScrollUnit aUnit, 1192 ScrollSnapMode aSnap = DISABLE_SNAP) final { 1193 mHelper.ScrollByUnit(aScrollbar, aMode, aDirection, aUnit, aSnap); 1194 } RepeatButtonScroll(nsScrollbarFrame * aScrollbar)1195 void RepeatButtonScroll(nsScrollbarFrame* aScrollbar) final { 1196 mHelper.RepeatButtonScroll(aScrollbar); 1197 } ThumbMoved(nsScrollbarFrame * aScrollbar,nscoord aOldPos,nscoord aNewPos)1198 void ThumbMoved(nsScrollbarFrame* aScrollbar, nscoord aOldPos, 1199 nscoord aNewPos) final { 1200 mHelper.ThumbMoved(aScrollbar, aOldPos, aNewPos); 1201 } ScrollbarReleased(nsScrollbarFrame * aScrollbar)1202 void ScrollbarReleased(nsScrollbarFrame* aScrollbar) final { 1203 mHelper.ScrollbarReleased(aScrollbar); 1204 } VisibilityChanged(bool aVisible)1205 void VisibilityChanged(bool aVisible) final {} GetScrollbarBox(bool aVertical)1206 nsIFrame* GetScrollbarBox(bool aVertical) final { 1207 return mHelper.GetScrollbarBox(aVertical); 1208 } 1209 void ScrollbarActivityStarted() const final; 1210 void ScrollbarActivityStopped() const final; 1211 IsScrollbarOnRight()1212 bool IsScrollbarOnRight() const final { return mHelper.IsScrollbarOnRight(); } 1213 ShouldSuppressScrollbarRepaints()1214 bool ShouldSuppressScrollbarRepaints() const final { 1215 return mHelper.ShouldSuppressScrollbarRepaints(); 1216 } 1217 SetTransformingByAPZ(bool aTransforming)1218 void SetTransformingByAPZ(bool aTransforming) final { 1219 mHelper.SetTransformingByAPZ(aTransforming); 1220 } IsTransformingByAPZ()1221 bool IsTransformingByAPZ() const final { 1222 return mHelper.IsTransformingByAPZ(); 1223 } SetScrollableByAPZ(bool aScrollable)1224 void SetScrollableByAPZ(bool aScrollable) final { 1225 mHelper.SetScrollableByAPZ(aScrollable); 1226 } SetZoomableByAPZ(bool aZoomable)1227 void SetZoomableByAPZ(bool aZoomable) final { 1228 mHelper.SetZoomableByAPZ(aZoomable); 1229 } SetHasOutOfFlowContentInsideFilter()1230 void SetHasOutOfFlowContentInsideFilter() final { 1231 mHelper.SetHasOutOfFlowContentInsideFilter(); 1232 } 1233 GetScrollSnapInfo()1234 ScrollSnapInfo GetScrollSnapInfo() const final { 1235 return mHelper.GetScrollSnapInfo(Nothing()); 1236 } 1237 DragScroll(mozilla::WidgetEvent * aEvent)1238 bool DragScroll(mozilla::WidgetEvent* aEvent) final { 1239 return mHelper.DragScroll(aEvent); 1240 } 1241 AsyncScrollbarDragInitiated(uint64_t aDragBlockId,mozilla::layers::ScrollDirection aDirection)1242 void AsyncScrollbarDragInitiated( 1243 uint64_t aDragBlockId, 1244 mozilla::layers::ScrollDirection aDirection) final { 1245 return mHelper.AsyncScrollbarDragInitiated(aDragBlockId, aDirection); 1246 } 1247 AsyncScrollbarDragRejected()1248 void AsyncScrollbarDragRejected() final { 1249 return mHelper.AsyncScrollbarDragRejected(); 1250 } 1251 IsRootScrollFrameOfDocument()1252 bool IsRootScrollFrameOfDocument() const final { 1253 return mHelper.IsRootScrollFrameOfDocument(); 1254 } 1255 Anchor()1256 const ScrollAnchorContainer* Anchor() const final { return &mHelper.mAnchor; } 1257 Anchor()1258 ScrollAnchorContainer* Anchor() final { return &mHelper.mAnchor; } 1259 1260 // Return the scrolled frame. AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox> & aResult)1261 void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) final { 1262 aResult.AppendElement(OwnedAnonBox(mHelper.GetScrolledFrame())); 1263 } 1264 SmoothScrollVisual(const nsPoint & aVisualViewportOffset,mozilla::layers::FrameMetrics::ScrollOffsetUpdateType aUpdateType)1265 bool SmoothScrollVisual( 1266 const nsPoint& aVisualViewportOffset, 1267 mozilla::layers::FrameMetrics::ScrollOffsetUpdateType aUpdateType) final { 1268 return mHelper.SmoothScrollVisual(aVisualViewportOffset, aUpdateType); 1269 } 1270 IsSmoothScroll(mozilla::dom::ScrollBehavior aBehavior)1271 bool IsSmoothScroll(mozilla::dom::ScrollBehavior aBehavior) const final { 1272 return mHelper.IsSmoothScroll(aBehavior); 1273 } 1274 1275 #ifdef DEBUG_FRAME_DUMP 1276 nsresult GetFrameName(nsAString& aResult) const override; 1277 #endif 1278 1279 #ifdef ACCESSIBILITY 1280 mozilla::a11y::AccType AccessibleType() override; 1281 #endif 1282 1283 protected: nsHTMLScrollFrame(ComputedStyle * aStyle,nsPresContext * aPresContext,bool aIsRoot)1284 nsHTMLScrollFrame(ComputedStyle* aStyle, nsPresContext* aPresContext, 1285 bool aIsRoot) 1286 : nsHTMLScrollFrame(aStyle, aPresContext, kClassID, aIsRoot) {} 1287 1288 nsHTMLScrollFrame(ComputedStyle* aStyle, nsPresContext* aPresContext, 1289 nsIFrame::ClassID aID, bool aIsRoot); SetSuppressScrollbarUpdate(bool aSuppress)1290 void SetSuppressScrollbarUpdate(bool aSuppress) { 1291 mHelper.mSuppressScrollbarUpdate = aSuppress; 1292 } 1293 bool GuessHScrollbarNeeded(const ScrollReflowInput& aState); 1294 bool GuessVScrollbarNeeded(const ScrollReflowInput& aState); 1295 IsScrollbarUpdateSuppressed()1296 bool IsScrollbarUpdateSuppressed() const { 1297 return mHelper.mSuppressScrollbarUpdate; 1298 } 1299 1300 // Return whether we're in an "initial" reflow. Some reflows with 1301 // NS_FRAME_FIRST_REFLOW set are NOT "initial" as far as we're concerned. 1302 bool InInitialReflow() const; 1303 1304 /** 1305 * Override this to return false if computed bsize/min-bsize/max-bsize 1306 * should NOT be propagated to child content. 1307 * nsListControlFrame uses this. 1308 */ ShouldPropagateComputedBSizeToScrolledContent()1309 virtual bool ShouldPropagateComputedBSizeToScrolledContent() const { 1310 return true; 1311 } 1312 1313 private: 1314 friend class mozilla::ScrollFrameHelper; 1315 ScrollFrameHelper mHelper; 1316 }; 1317 1318 /** 1319 * The scroll frame creates and manages the scrolling view 1320 * 1321 * It only supports having a single child frame that typically is an area 1322 * frame, but doesn't have to be. The child frame must have a view, though 1323 * 1324 * Scroll frames don't support incremental changes, i.e. you can't replace 1325 * or remove the scrolled frame 1326 */ 1327 class nsXULScrollFrame final : public nsBoxFrame, 1328 public nsIScrollableFrame, 1329 public nsIAnonymousContentCreator, 1330 public nsIStatefulFrame { 1331 public: 1332 using ScrollFrameHelper = mozilla::ScrollFrameHelper; 1333 using CSSIntPoint = mozilla::CSSIntPoint; 1334 using ScrollAnchorContainer = mozilla::layout::ScrollAnchorContainer; 1335 1336 NS_DECL_QUERYFRAME 1337 NS_DECL_FRAMEARENA_HELPERS(nsXULScrollFrame) 1338 1339 friend nsXULScrollFrame* NS_NewXULScrollFrame(mozilla::PresShell* aPresShell, 1340 ComputedStyle* aStyle, 1341 bool aIsRoot); 1342 BuildDisplayList(nsDisplayListBuilder * aBuilder,const nsDisplayListSet & aLists)1343 void BuildDisplayList(nsDisplayListBuilder* aBuilder, 1344 const nsDisplayListSet& aLists) final { 1345 mHelper.BuildDisplayList(aBuilder, aLists); 1346 } 1347 1348 // XXXldb Is this actually used? 1349 #if 0 1350 nscoord GetMinISize(gfxContext *aRenderingContext) final; 1351 #endif 1352 ComputeCustomOverflow(mozilla::OverflowAreas & aOverflowAreas)1353 bool ComputeCustomOverflow(mozilla::OverflowAreas& aOverflowAreas) final { 1354 return mHelper.ComputeCustomOverflow(aOverflowAreas); 1355 } 1356 GetVerticalAlignBaseline(mozilla::WritingMode aWM,nscoord * aBaseline)1357 bool GetVerticalAlignBaseline(mozilla::WritingMode aWM, 1358 nscoord* aBaseline) const final { 1359 *aBaseline = GetLogicalBaseline(aWM); 1360 return true; 1361 } 1362 1363 // Called to set the child frames. We typically have three: the scroll area, 1364 // the vertical scrollbar, and the horizontal scrollbar. 1365 void SetInitialChildList(ChildListID aListID, nsFrameList& aChildList) final; 1366 void AppendFrames(ChildListID aListID, nsFrameList& aFrameList) final; 1367 void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, 1368 const nsLineList::iterator* aPrevFrameLine, 1369 nsFrameList& aFrameList) final; 1370 void RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) final; 1371 1372 void DestroyFrom(nsIFrame* aDestructRoot, 1373 PostDestroyData& aPostDestroyData) final; 1374 GetScrollTargetFrame()1375 nsIScrollableFrame* GetScrollTargetFrame() const final { 1376 return const_cast<nsXULScrollFrame*>(this); 1377 } 1378 GetContentInsertionFrame()1379 nsContainerFrame* GetContentInsertionFrame() final { 1380 return mHelper.GetScrolledFrame()->GetContentInsertionFrame(); 1381 } 1382 DoesClipChildrenInBothAxes()1383 bool DoesClipChildrenInBothAxes() final { return true; } 1384 GetPositionOfChildIgnoringScrolling(const nsIFrame * aChild)1385 nsPoint GetPositionOfChildIgnoringScrolling(const nsIFrame* aChild) final { 1386 nsPoint pt = aChild->GetPosition(); 1387 if (aChild == mHelper.GetScrolledFrame()) 1388 pt += mHelper.GetLogicalScrollPosition(); 1389 return pt; 1390 } 1391 1392 // nsIAnonymousContentCreator 1393 nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) final; 1394 void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements, 1395 uint32_t aFilter) final; 1396 1397 nsSize GetXULMinSize(nsBoxLayoutState& aBoxLayoutState) final; 1398 nsSize GetXULPrefSize(nsBoxLayoutState& aBoxLayoutState) final; 1399 nsSize GetXULMaxSize(nsBoxLayoutState& aBoxLayoutState) final; 1400 nscoord GetXULBoxAscent(nsBoxLayoutState& aBoxLayoutState) final; 1401 1402 NS_IMETHOD DoXULLayout(nsBoxLayoutState& aBoxLayoutState) final; 1403 nsresult GetXULPadding(nsMargin& aPadding) final; 1404 GetBorderRadii(const nsSize & aFrameSize,const nsSize & aBorderArea,Sides aSkipSides,nscoord aRadii[8])1405 bool GetBorderRadii(const nsSize& aFrameSize, const nsSize& aBorderArea, 1406 Sides aSkipSides, nscoord aRadii[8]) const final { 1407 return mHelper.GetBorderRadii(aFrameSize, aBorderArea, aSkipSides, aRadii); 1408 } 1409 1410 nsresult XULLayout(nsBoxLayoutState& aState); 1411 void LayoutScrollArea(nsBoxLayoutState& aState, 1412 const nsPoint& aScrollPosition); 1413 1414 bool AddRemoveScrollbar(nsBoxLayoutState& aState, bool aOnRightOrBottom, 1415 bool aHorizontal, bool aAdd); 1416 1417 bool AddHorizontalScrollbar(nsBoxLayoutState& aState, bool aOnBottom); 1418 bool AddVerticalScrollbar(nsBoxLayoutState& aState, bool aOnRight); 1419 void RemoveHorizontalScrollbar(nsBoxLayoutState& aState, bool aOnBottom); 1420 void RemoveVerticalScrollbar(nsBoxLayoutState& aState, bool aOnRight); 1421 1422 static void AdjustReflowInputForPrintPreview(nsBoxLayoutState& aState, 1423 bool& aSetBack); 1424 static void AdjustReflowInputBack(nsBoxLayoutState& aState, bool aSetBack); 1425 1426 // nsIScrollableFrame GetScrolledFrame()1427 nsIFrame* GetScrolledFrame() const final { 1428 return mHelper.GetScrolledFrame(); 1429 } GetScrollStyles()1430 mozilla::ScrollStyles GetScrollStyles() const final { 1431 return mHelper.GetScrollStylesFromFrame(); 1432 } IsForTextControlWithNoScrollbars()1433 bool IsForTextControlWithNoScrollbars() const final { 1434 return mHelper.IsForTextControlWithNoScrollbars(); 1435 } HasAllNeededScrollbars()1436 bool HasAllNeededScrollbars() const final { 1437 return mHelper.HasAllNeededScrollbars(); 1438 } GetOverscrollBehaviorInfo()1439 mozilla::layers::OverscrollBehaviorInfo GetOverscrollBehaviorInfo() 1440 const final { 1441 return mHelper.GetOverscrollBehaviorInfo(); 1442 } 1443 mozilla::layers::ScrollDirections GetAvailableScrollingDirectionsForUserInputEvents()1444 GetAvailableScrollingDirectionsForUserInputEvents() const final { 1445 return mHelper.GetAvailableScrollingDirectionsForUserInputEvents(); 1446 } GetScrollbarVisibility()1447 mozilla::layers::ScrollDirections GetScrollbarVisibility() const final { 1448 return mHelper.GetScrollbarVisibility(); 1449 } 1450 nsMargin GetActualScrollbarSizes( 1451 nsIScrollableFrame::ScrollbarSizesOptions aOptions = 1452 nsIScrollableFrame::ScrollbarSizesOptions::NONE) const final { 1453 return mHelper.GetActualScrollbarSizes(aOptions); 1454 } GetDesiredScrollbarSizes(nsBoxLayoutState * aState)1455 nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState) final { 1456 return mHelper.GetDesiredScrollbarSizes(aState); 1457 } GetDesiredScrollbarSizes(nsPresContext * aPresContext,gfxContext * aRC)1458 nsMargin GetDesiredScrollbarSizes(nsPresContext* aPresContext, 1459 gfxContext* aRC) final { 1460 nsBoxLayoutState bls(aPresContext, aRC, 0); 1461 return GetDesiredScrollbarSizes(&bls); 1462 } GetLayoutSize()1463 nsSize GetLayoutSize() const final { return mHelper.GetLayoutSize(); } GetScrolledRect()1464 nsRect GetScrolledRect() const final { return mHelper.GetScrolledRect(); } GetScrollPortRect()1465 nsRect GetScrollPortRect() const final { return mHelper.GetScrollPortRect(); } GetScrollPosition()1466 nsPoint GetScrollPosition() const final { 1467 return mHelper.GetScrollPosition(); 1468 } GetLogicalScrollPosition()1469 nsPoint GetLogicalScrollPosition() const final { 1470 return mHelper.GetLogicalScrollPosition(); 1471 } GetScrollRange()1472 nsRect GetScrollRange() const final { return mHelper.GetLayoutScrollRange(); } GetVisualViewportSize()1473 nsSize GetVisualViewportSize() const final { 1474 return mHelper.GetVisualViewportSize(); 1475 } GetVisualViewportOffset()1476 nsPoint GetVisualViewportOffset() const final { 1477 return mHelper.GetVisualViewportOffset(); 1478 } SetVisualViewportOffset(const nsPoint & aOffset,bool aRepaint)1479 bool SetVisualViewportOffset(const nsPoint& aOffset, bool aRepaint) final { 1480 return mHelper.SetVisualViewportOffset(aOffset, aRepaint); 1481 } GetVisualScrollRange()1482 nsRect GetVisualScrollRange() const final { 1483 return mHelper.GetVisualScrollRange(); 1484 } GetScrollRangeForUserInputEvents()1485 nsRect GetScrollRangeForUserInputEvents() const final { 1486 return mHelper.GetScrollRangeForUserInputEvents(); 1487 } GetLineScrollAmount()1488 nsSize GetLineScrollAmount() const final { 1489 return mHelper.GetLineScrollAmount(); 1490 } GetPageScrollAmount()1491 nsSize GetPageScrollAmount() const final { 1492 return mHelper.GetPageScrollAmount(); 1493 } GetScrollPadding()1494 nsMargin GetScrollPadding() const final { return mHelper.GetScrollPadding(); } 1495 /** 1496 * @note This method might destroy the frame, pres shell and other objects. 1497 */ 1498 void ScrollTo(nsPoint aScrollPosition, ScrollMode aMode, 1499 const nsRect* aRange = nullptr, 1500 ScrollSnapMode aSnap = nsIScrollbarMediator::DISABLE_SNAP, 1501 mozilla::ScrollTriggeredByScript aTriggeredByScript = 1502 mozilla::ScrollTriggeredByScript::No) final { 1503 mHelper.ScrollTo(aScrollPosition, aMode, ScrollOrigin::Other, aRange, 1504 aSnap); 1505 } 1506 /** 1507 * @note This method might destroy the frame, pres shell and other objects. 1508 */ 1509 void ScrollToCSSPixels(const CSSIntPoint& aScrollPosition, 1510 ScrollMode aMode = ScrollMode::Instant) final { 1511 mHelper.ScrollToCSSPixels(aScrollPosition, aMode); 1512 } ScrollToCSSPixelsForApz(const mozilla::CSSPoint & aScrollPosition)1513 void ScrollToCSSPixelsForApz(const mozilla::CSSPoint& aScrollPosition) final { 1514 mHelper.ScrollToCSSPixelsForApz(aScrollPosition); 1515 } GetScrollPositionCSSPixels()1516 CSSIntPoint GetScrollPositionCSSPixels() final { 1517 return mHelper.GetScrollPositionCSSPixels(); 1518 } 1519 /** 1520 * @note This method might destroy the frame, pres shell and other objects. 1521 */ 1522 void ScrollBy(nsIntPoint aDelta, mozilla::ScrollUnit aUnit, ScrollMode aMode, 1523 nsIntPoint* aOverflow, 1524 ScrollOrigin aOrigin = ScrollOrigin::NotSpecified, 1525 nsIScrollableFrame::ScrollMomentum aMomentum = 1526 nsIScrollableFrame::NOT_MOMENTUM, 1527 nsIScrollbarMediator::ScrollSnapMode aSnap = 1528 nsIScrollbarMediator::DISABLE_SNAP) final { 1529 mHelper.ScrollBy(aDelta, aUnit, aMode, aOverflow, aOrigin, aMomentum, 1530 aSnap); 1531 } 1532 void ScrollByCSSPixels(const CSSIntPoint& aDelta, 1533 ScrollMode aMode = ScrollMode::Instant) final { 1534 mHelper.ScrollByCSSPixels(aDelta, aMode); 1535 } ScrollSnap()1536 void ScrollSnap() final { mHelper.ScrollSnap(); } 1537 /** 1538 * @note This method might destroy the frame, pres shell and other objects. 1539 */ ScrollToRestoredPosition()1540 void ScrollToRestoredPosition() final { mHelper.ScrollToRestoredPosition(); } AddScrollPositionListener(nsIScrollPositionListener * aListener)1541 void AddScrollPositionListener(nsIScrollPositionListener* aListener) final { 1542 mHelper.AddScrollPositionListener(aListener); 1543 } RemoveScrollPositionListener(nsIScrollPositionListener * aListener)1544 void RemoveScrollPositionListener( 1545 nsIScrollPositionListener* aListener) final { 1546 mHelper.RemoveScrollPositionListener(aListener); 1547 } 1548 /** 1549 * @note This method might destroy the frame, pres shell and other objects. 1550 */ CurPosAttributeChanged(nsIContent * aChild)1551 void CurPosAttributeChanged(nsIContent* aChild) final { 1552 mHelper.CurPosAttributeChanged(aChild); 1553 } PostScrolledAreaEventForCurrentArea()1554 NS_IMETHOD PostScrolledAreaEventForCurrentArea() final { 1555 mHelper.PostScrolledAreaEvent(); 1556 return NS_OK; 1557 } IsScrollingActive()1558 bool IsScrollingActive() final { return mHelper.IsScrollingActive(); } IsMaybeAsynchronouslyScrolled()1559 bool IsMaybeAsynchronouslyScrolled() final { 1560 return mHelper.IsMaybeAsynchronouslyScrolled(); 1561 } DidHistoryRestore()1562 bool DidHistoryRestore() const final { return mHelper.mDidHistoryRestore; } ClearDidHistoryRestore()1563 void ClearDidHistoryRestore() final { mHelper.mDidHistoryRestore = false; } MarkEverScrolled()1564 void MarkEverScrolled() final { mHelper.MarkEverScrolled(); } IsRectNearlyVisible(const nsRect & aRect)1565 bool IsRectNearlyVisible(const nsRect& aRect) final { 1566 return mHelper.IsRectNearlyVisible(aRect); 1567 } ExpandRectToNearlyVisible(const nsRect & aRect)1568 nsRect ExpandRectToNearlyVisible(const nsRect& aRect) const final { 1569 return mHelper.ExpandRectToNearlyVisible(aRect); 1570 } LastScrollOrigin()1571 ScrollOrigin LastScrollOrigin() final { return mHelper.LastScrollOrigin(); } IsScrollAnimating(IncludeApzAnimation aIncludeApz)1572 bool IsScrollAnimating(IncludeApzAnimation aIncludeApz) final { 1573 return mHelper.IsScrollAnimating(aIncludeApz); 1574 } CurrentScrollGeneration()1575 mozilla::MainThreadScrollGeneration CurrentScrollGeneration() const final { 1576 return mHelper.CurrentScrollGeneration(); 1577 } ScrollGenerationOnApz()1578 mozilla::APZScrollGeneration ScrollGenerationOnApz() const final { 1579 return mHelper.ScrollGenerationOnApz(); 1580 } LastScrollDestination()1581 nsPoint LastScrollDestination() final { 1582 return mHelper.LastScrollDestination(); 1583 } GetScrollUpdates()1584 nsTArray<mozilla::ScrollPositionUpdate> GetScrollUpdates() const final { 1585 return mHelper.GetScrollUpdates(); 1586 } HasScrollUpdates()1587 bool HasScrollUpdates() const final { return mHelper.HasScrollUpdates(); } ResetScrollInfoIfNeeded(const mozilla::MainThreadScrollGeneration & aGeneration,const mozilla::APZScrollGeneration & aGenerationOnApz,mozilla::APZScrollAnimationType aAPZScrollAnimationType)1588 void ResetScrollInfoIfNeeded( 1589 const mozilla::MainThreadScrollGeneration& aGeneration, 1590 const mozilla::APZScrollGeneration& aGenerationOnApz, 1591 mozilla::APZScrollAnimationType aAPZScrollAnimationType) final { 1592 mHelper.ResetScrollInfoIfNeeded(aGeneration, aGenerationOnApz, 1593 aAPZScrollAnimationType); 1594 } WantAsyncScroll()1595 bool WantAsyncScroll() const final { return mHelper.WantAsyncScroll(); } ComputeScrollMetadata(mozilla::layers::WebRenderLayerManager * aLayerManager,const nsIFrame * aItemFrame,const nsPoint & aOffsetToReferenceFrame)1596 mozilla::Maybe<mozilla::layers::ScrollMetadata> ComputeScrollMetadata( 1597 mozilla::layers::WebRenderLayerManager* aLayerManager, 1598 const nsIFrame* aItemFrame, 1599 const nsPoint& aOffsetToReferenceFrame) const final { 1600 return mHelper.ComputeScrollMetadata(aLayerManager, aItemFrame, 1601 aOffsetToReferenceFrame); 1602 } MarkScrollbarsDirtyForReflow()1603 void MarkScrollbarsDirtyForReflow() const final { 1604 mHelper.MarkScrollbarsDirtyForReflow(); 1605 } InvalidateScrollbars()1606 void InvalidateScrollbars() const final { mHelper.InvalidateScrollbars(); } UpdateScrollbarPosition()1607 void UpdateScrollbarPosition() final { mHelper.UpdateScrollbarPosition(); } 1608 1609 // nsIStatefulFrame SaveState()1610 mozilla::UniquePtr<mozilla::PresState> SaveState() final { 1611 return mHelper.SaveState(); 1612 } RestoreState(mozilla::PresState * aState)1613 NS_IMETHOD RestoreState(mozilla::PresState* aState) final { 1614 NS_ENSURE_ARG_POINTER(aState); 1615 mHelper.RestoreState(aState); 1616 return NS_OK; 1617 } 1618 IsFrameOfType(uint32_t aFlags)1619 bool IsFrameOfType(uint32_t aFlags) const final { 1620 // Override bogus IsFrameOfType in nsBoxFrame. 1621 if (aFlags & (nsIFrame::eReplacedContainsBlock | nsIFrame::eReplaced)) 1622 return false; 1623 return nsBoxFrame::IsFrameOfType(aFlags); 1624 } 1625 1626 void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection, 1627 nsIScrollbarMediator::ScrollSnapMode aSnap = 1628 nsIScrollbarMediator::DISABLE_SNAP) final { 1629 mHelper.ScrollByPage(aScrollbar, aDirection, aSnap); 1630 } 1631 void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection, 1632 nsIScrollbarMediator::ScrollSnapMode aSnap = 1633 nsIScrollbarMediator::DISABLE_SNAP) final { 1634 mHelper.ScrollByWhole(aScrollbar, aDirection, aSnap); 1635 } 1636 void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection, 1637 nsIScrollbarMediator::ScrollSnapMode aSnap = 1638 nsIScrollbarMediator::DISABLE_SNAP) final { 1639 mHelper.ScrollByLine(aScrollbar, aDirection, aSnap); 1640 } 1641 void ScrollByUnit(nsScrollbarFrame* aScrollbar, ScrollMode aMode, 1642 int32_t aDirection, mozilla::ScrollUnit aUnit, 1643 ScrollSnapMode aSnap = DISABLE_SNAP) final { 1644 mHelper.ScrollByUnit(aScrollbar, aMode, aDirection, aUnit, aSnap); 1645 } RepeatButtonScroll(nsScrollbarFrame * aScrollbar)1646 void RepeatButtonScroll(nsScrollbarFrame* aScrollbar) final { 1647 mHelper.RepeatButtonScroll(aScrollbar); 1648 } ThumbMoved(nsScrollbarFrame * aScrollbar,nscoord aOldPos,nscoord aNewPos)1649 void ThumbMoved(nsScrollbarFrame* aScrollbar, nscoord aOldPos, 1650 nscoord aNewPos) final { 1651 mHelper.ThumbMoved(aScrollbar, aOldPos, aNewPos); 1652 } ScrollbarReleased(nsScrollbarFrame * aScrollbar)1653 void ScrollbarReleased(nsScrollbarFrame* aScrollbar) final { 1654 mHelper.ScrollbarReleased(aScrollbar); 1655 } VisibilityChanged(bool aVisible)1656 void VisibilityChanged(bool aVisible) final {} GetScrollbarBox(bool aVertical)1657 nsIFrame* GetScrollbarBox(bool aVertical) final { 1658 return mHelper.GetScrollbarBox(aVertical); 1659 } 1660 1661 void ScrollbarActivityStarted() const final; 1662 void ScrollbarActivityStopped() const final; 1663 IsScrollbarOnRight()1664 bool IsScrollbarOnRight() const final { return mHelper.IsScrollbarOnRight(); } 1665 ShouldSuppressScrollbarRepaints()1666 bool ShouldSuppressScrollbarRepaints() const final { 1667 return mHelper.ShouldSuppressScrollbarRepaints(); 1668 } 1669 SetTransformingByAPZ(bool aTransforming)1670 void SetTransformingByAPZ(bool aTransforming) final { 1671 mHelper.SetTransformingByAPZ(aTransforming); 1672 } IsTransformingByAPZ()1673 bool IsTransformingByAPZ() const final { 1674 return mHelper.IsTransformingByAPZ(); 1675 } SetScrollableByAPZ(bool aScrollable)1676 void SetScrollableByAPZ(bool aScrollable) final { 1677 mHelper.SetScrollableByAPZ(aScrollable); 1678 } SetZoomableByAPZ(bool aZoomable)1679 void SetZoomableByAPZ(bool aZoomable) final { 1680 mHelper.SetZoomableByAPZ(aZoomable); 1681 } SetHasOutOfFlowContentInsideFilter()1682 void SetHasOutOfFlowContentInsideFilter() final { 1683 mHelper.SetHasOutOfFlowContentInsideFilter(); 1684 } DecideScrollableLayer(nsDisplayListBuilder * aBuilder,nsRect * aVisibleRect,nsRect * aDirtyRect,bool aSetBase)1685 bool DecideScrollableLayer(nsDisplayListBuilder* aBuilder, 1686 nsRect* aVisibleRect, nsRect* aDirtyRect, 1687 bool aSetBase) final { 1688 return mHelper.DecideScrollableLayer(aBuilder, aVisibleRect, aDirtyRect, 1689 aSetBase); 1690 } NotifyApzTransaction()1691 void NotifyApzTransaction() final { mHelper.NotifyApzTransaction(); } NotifyApproximateFrameVisibilityUpdate(bool aIgnoreDisplayPort)1692 void NotifyApproximateFrameVisibilityUpdate(bool aIgnoreDisplayPort) final { 1693 mHelper.NotifyApproximateFrameVisibilityUpdate(aIgnoreDisplayPort); 1694 } GetDisplayPortAtLastApproximateFrameVisibilityUpdate(nsRect * aDisplayPort)1695 bool GetDisplayPortAtLastApproximateFrameVisibilityUpdate( 1696 nsRect* aDisplayPort) final { 1697 return mHelper.GetDisplayPortAtLastApproximateFrameVisibilityUpdate( 1698 aDisplayPort); 1699 } TriggerDisplayPortExpiration()1700 void TriggerDisplayPortExpiration() final { 1701 mHelper.TriggerDisplayPortExpiration(); 1702 } 1703 GetScrollSnapInfo()1704 ScrollSnapInfo GetScrollSnapInfo() const final { 1705 return mHelper.GetScrollSnapInfo(Nothing()); 1706 } 1707 DragScroll(mozilla::WidgetEvent * aEvent)1708 bool DragScroll(mozilla::WidgetEvent* aEvent) final { 1709 return mHelper.DragScroll(aEvent); 1710 } 1711 AsyncScrollbarDragInitiated(uint64_t aDragBlockId,mozilla::layers::ScrollDirection aDirection)1712 void AsyncScrollbarDragInitiated( 1713 uint64_t aDragBlockId, 1714 mozilla::layers::ScrollDirection aDirection) final { 1715 return mHelper.AsyncScrollbarDragInitiated(aDragBlockId, aDirection); 1716 } 1717 AsyncScrollbarDragRejected()1718 void AsyncScrollbarDragRejected() final { 1719 return mHelper.AsyncScrollbarDragRejected(); 1720 } 1721 IsRootScrollFrameOfDocument()1722 bool IsRootScrollFrameOfDocument() const final { 1723 return mHelper.IsRootScrollFrameOfDocument(); 1724 } 1725 Anchor()1726 const ScrollAnchorContainer* Anchor() const final { return &mHelper.mAnchor; } 1727 Anchor()1728 ScrollAnchorContainer* Anchor() final { return &mHelper.mAnchor; } 1729 1730 // Return the scrolled frame. AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox> & aResult)1731 void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) final { 1732 aResult.AppendElement(OwnedAnonBox(mHelper.GetScrolledFrame())); 1733 } 1734 SmoothScrollVisual(const nsPoint & aVisualViewportOffset,mozilla::layers::FrameMetrics::ScrollOffsetUpdateType aUpdateType)1735 bool SmoothScrollVisual( 1736 const nsPoint& aVisualViewportOffset, 1737 mozilla::layers::FrameMetrics::ScrollOffsetUpdateType aUpdateType) final { 1738 return mHelper.SmoothScrollVisual(aVisualViewportOffset, aUpdateType); 1739 } 1740 IsSmoothScroll(mozilla::dom::ScrollBehavior aBehavior)1741 bool IsSmoothScroll(mozilla::dom::ScrollBehavior aBehavior) const final { 1742 return mHelper.IsSmoothScroll(aBehavior); 1743 } 1744 1745 #ifdef DEBUG_FRAME_DUMP 1746 nsresult GetFrameName(nsAString& aResult) const final; 1747 #endif 1748 1749 protected: 1750 nsXULScrollFrame(ComputedStyle*, nsPresContext*, bool aIsRoot); 1751 1752 void ClampAndSetBounds(nsBoxLayoutState& aState, nsRect& aRect, 1753 nsPoint aScrollPosition, 1754 bool aRemoveOverflowAreas = false) { 1755 /* 1756 * For RTL frames, restore the original scrolled position of the right 1757 * edge, then subtract the current width to find the physical position. 1758 */ 1759 if (!mHelper.IsPhysicalLTR()) { 1760 aRect.x = mHelper.ScrollPort().XMost() - aScrollPosition.x - aRect.width; 1761 } 1762 mHelper.mScrolledFrame->SetXULBounds(aState, aRect, aRemoveOverflowAreas); 1763 } 1764 1765 private: 1766 friend class mozilla::ScrollFrameHelper; 1767 ScrollFrameHelper mHelper; 1768 }; 1769 1770 #endif /* nsGfxScrollFrame_h___ */ 1771