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