Bug 1823455 - Merge ScrollFrameHelper and nsHTMLScrollFrame. r=layout-reviewers,TYLin

Now that we've removed nsXULScrollFrame, ScrollFrameHelper can be
subsumed under nsHTMLScrollFrame.

I want to do this before making scrollbars non-XUL.

Renaming to mozilla::ScrollFrame is left for a follow-up bug.

Differential Revision: https://phabricator.services.mozilla.com/D173063
This commit is contained in:
Emilio Cobos Álvarez 2023-03-22 13:06:40 +00:00
parent 9553904295
commit cb2a32d8af
12 changed files with 1223 additions and 1621 deletions

View file

@ -5973,7 +5973,7 @@ void PresShell::MarkFramesInSubtreeApproximatelyVisible(
// We can properly set the base rect for root scroll frames on top level
// and root content documents. Otherwise the base rect we compute might
// be way too big without the limiting that
// ScrollFrameHelper::DecideScrollableLayer does, so we just ignore the
// nsHTMLScrollFrame::DecideScrollableLayer does, so we just ignore the
// displayport in that case.
nsPresContext* pc = aFrame->PresContext();
if (scrollFrame->IsRootScrollFrameOfDocument() &&

View file

@ -1512,7 +1512,7 @@ nsRect nsLayoutUtils::GetScrolledRect(nsIFrame* aScrolledFrame,
StyleDirection aDirection) {
WritingMode wm = aScrolledFrame->GetWritingMode();
// Potentially override the frame's direction to use the direction found
// by ScrollFrameHelper::GetScrolledFrameDir()
// by nsHTMLScrollFrame::GetScrolledFrameDir()
wm.SetDirectionFromBidiLevel(aDirection == StyleDirection::Rtl
? mozilla::intl::BidiEmbeddingLevel::RTL()
: mozilla::intl::BidiEmbeddingLevel::LTR());
@ -9735,7 +9735,8 @@ bool nsLayoutUtils::ShouldHandleMetaViewport(const Document* aDocument) {
}
/* static */
ComputedStyle* nsLayoutUtils::StyleForScrollbar(nsIFrame* aScrollbarPart) {
ComputedStyle* nsLayoutUtils::StyleForScrollbar(
const nsIFrame* aScrollbarPart) {
// Get the closest content node which is not an anonymous scrollbar
// part. It should be the originating element of the scrollbar part.
nsIContent* content = aScrollbarPart->GetContent();

View file

@ -2998,7 +2998,7 @@ class nsLayoutUtils {
* Get the computed style from which the scrollbar style should be
* used for the given scrollbar part frame.
*/
static ComputedStyle* StyleForScrollbar(nsIFrame* aScrollbarPart);
static ComputedStyle* StyleForScrollbar(const nsIFrame* aScrollbarPart);
/**
* Returns true if |aFrame| is scrolled out of view by a scrollable element in

View file

@ -35,7 +35,7 @@ static mozilla::LazyLogModule sAnchorLog("scrollanchor");
->GetDocumentURI() \
->GetSpecOrDefault() \
.get(), \
(anchor_)->ScrollFrame()->mIsRoot, ##__VA_ARGS__));
(anchor_)->Frame()->mIsRoot, ##__VA_ARGS__));
# define ANCHOR_LOG(fmt, ...) ANCHOR_LOG_WITH(this, fmt, ##__VA_ARGS__)
#else
@ -45,18 +45,18 @@ static mozilla::LazyLogModule sAnchorLog("scrollanchor");
namespace mozilla::layout {
inline ScrollFrameHelper* ScrollAnchorContainer::ScrollFrame() const {
return reinterpret_cast<ScrollFrameHelper*>(
((char*)this) - offsetof(ScrollFrameHelper, mAnchor));
nsHTMLScrollFrame* ScrollAnchorContainer::Frame() const {
return reinterpret_cast<nsHTMLScrollFrame*>(
((char*)this) - offsetof(nsHTMLScrollFrame, mAnchor));
}
ScrollAnchorContainer::ScrollAnchorContainer(ScrollFrameHelper* aScrollFrame)
ScrollAnchorContainer::ScrollAnchorContainer(nsHTMLScrollFrame* aScrollFrame)
: mDisabled(false),
mAnchorMightBeSubOptimal(false),
mAnchorNodeIsDirty(true),
mApplyingAnchorAdjustment(false),
mSuppressAnchorAdjustment(false) {
MOZ_ASSERT(aScrollFrame == ScrollFrame());
MOZ_ASSERT(aScrollFrame == Frame());
}
ScrollAnchorContainer::~ScrollAnchorContainer() = default;
@ -75,8 +75,6 @@ ScrollAnchorContainer* ScrollAnchorContainer::FindFor(nsIFrame* aFrame) {
return nullptr;
}
nsIFrame* ScrollAnchorContainer::Frame() const { return ScrollFrame()->mOuter; }
nsIScrollableFrame* ScrollAnchorContainer::ScrollableFrame() const {
return Frame()->GetScrollTargetFrame();
}
@ -205,10 +203,10 @@ static nsRect FindScrollAnchoringBoundingRect(const nsIFrame* aScrollFrame,
* of aScrollFrame.
*/
static nscoord FindScrollAnchoringBoundingOffset(
const ScrollFrameHelper* aScrollFrame, nsIFrame* aCandidate) {
WritingMode writingMode = aScrollFrame->mOuter->GetWritingMode();
const nsHTMLScrollFrame* aScrollFrame, nsIFrame* aCandidate) {
WritingMode writingMode = aScrollFrame->GetWritingMode();
nsRect physicalBounding =
FindScrollAnchoringBoundingRect(aScrollFrame->mOuter, aCandidate);
FindScrollAnchoringBoundingRect(aScrollFrame, aCandidate);
LogicalRect logicalBounding(writingMode, physicalBounding,
aScrollFrame->mScrolledFrame->GetSize());
return logicalBounding.BStart(writingMode);
@ -235,7 +233,7 @@ bool ScrollAnchorContainer::CanMaintainAnchor() const {
// is not in the specification [1], but Blink does this.
//
// [1] https://github.com/w3c/csswg-drafts/issues/3319
if (ScrollFrame()->GetLogicalScrollPosition() == nsPoint()) {
if (Frame()->GetLogicalScrollPosition() == nsPoint()) {
return false;
}
@ -252,23 +250,22 @@ bool ScrollAnchorContainer::CanMaintainAnchor() const {
}
void ScrollAnchorContainer::SelectAnchor() {
MOZ_ASSERT(ScrollFrame()->mScrolledFrame);
MOZ_ASSERT(Frame()->mScrolledFrame);
MOZ_ASSERT(mAnchorNodeIsDirty);
AUTO_PROFILER_LABEL("ScrollAnchorContainer::SelectAnchor", LAYOUT);
ANCHOR_LOG(
"Selecting anchor with scroll-port=%s.\n",
mozilla::ToString(ScrollFrame()->GetVisualOptimalViewingRect()).c_str());
ANCHOR_LOG("Selecting anchor with scroll-port=%s.\n",
mozilla::ToString(Frame()->GetVisualOptimalViewingRect()).c_str());
// Select a new scroll anchor
nsIFrame* oldAnchor = mAnchorNode;
if (CanMaintainAnchor()) {
MOZ_DIAGNOSTIC_ASSERT(
!ScrollFrame()->mScrolledFrame->IsInScrollAnchorChain(),
!Frame()->mScrolledFrame->IsInScrollAnchorChain(),
"Our scrolled frame can't serve as or contain an anchor for an "
"ancestor if it can maintain its own anchor");
ANCHOR_LOG("Beginning selection.\n");
mAnchorNode = FindAnchorIn(ScrollFrame()->mScrolledFrame);
mAnchorNode = FindAnchorIn(Frame()->mScrolledFrame);
} else {
ANCHOR_LOG("Skipping selection, doesn't maintain a scroll anchor.\n");
mAnchorNode = nullptr;
@ -283,7 +280,7 @@ void ScrollAnchorContainer::SelectAnchor() {
// Unset all flags for the old scroll anchor
if (oldAnchor) {
SetAnchorFlags(ScrollFrame()->mScrolledFrame, oldAnchor, false);
SetAnchorFlags(Frame()->mScrolledFrame, oldAnchor, false);
}
// Set all flags for the new scroll anchor
@ -291,7 +288,7 @@ void ScrollAnchorContainer::SelectAnchor() {
// Anchor selection will never select a descendant of a nested scroll
// frame which maintains an anchor, so we can set flags without
// conflicting with other scroll anchor containers.
SetAnchorFlags(ScrollFrame()->mScrolledFrame, mAnchorNode, true);
SetAnchorFlags(Frame()->mScrolledFrame, mAnchorNode, true);
}
} else {
ANCHOR_LOG("Anchor node has remained (%p).\n", mAnchorNode);
@ -299,8 +296,7 @@ void ScrollAnchorContainer::SelectAnchor() {
// Calculate the position to use for scroll adjustments
if (mAnchorNode) {
mLastAnchorOffset =
FindScrollAnchoringBoundingOffset(ScrollFrame(), mAnchorNode);
mLastAnchorOffset = FindScrollAnchoringBoundingOffset(Frame(), mAnchorNode);
ANCHOR_LOG("Using last anchor offset = %d.\n", mLastAnchorOffset);
} else {
mLastAnchorOffset = 0;
@ -424,8 +420,8 @@ void ScrollAnchorContainer::InvalidateAnchor(ScheduleSelection aSchedule) {
ANCHOR_LOG("Invalidating scroll anchor %p for %p.\n", mAnchorNode, this);
if (mAnchorNode) {
SetAnchorFlags(ScrollFrame()->mScrolledFrame, mAnchorNode, false);
} else if (ScrollFrame()->mScrolledFrame->IsInScrollAnchorChain()) {
SetAnchorFlags(Frame()->mScrolledFrame, mAnchorNode, false);
} else if (Frame()->mScrolledFrame->IsInScrollAnchorChain()) {
ANCHOR_LOG(" > Forwarding to parent anchor\n");
// We don't maintain an anchor, and our scrolled frame is in the anchor
// chain of an ancestor. Invalidate that anchor.
@ -452,23 +448,23 @@ void ScrollAnchorContainer::Destroy() {
void ScrollAnchorContainer::ApplyAdjustments() {
if (!mAnchorNode || mAnchorNodeIsDirty || mDisabled ||
ScrollFrame()->HasPendingScrollRestoration() ||
ScrollFrame()->IsProcessingScrollEvent() ||
ScrollFrame()->ScrollAnimationState().contains(
Frame()->HasPendingScrollRestoration() ||
Frame()->IsProcessingScrollEvent() ||
Frame()->ScrollAnimationState().contains(
nsIScrollableFrame::AnimationState::TriggeredByScript) ||
ScrollFrame()->GetScrollPosition() == nsPoint()) {
Frame()->GetScrollPosition() == nsPoint()) {
ANCHOR_LOG(
"Ignoring post-reflow (anchor=%p, dirty=%d, disabled=%d, "
"pendingRestoration=%d, scrollevent=%d, scriptAnimating=%d, "
"zeroScrollPos=%d pendingSuppression=%d, "
"container=%p).\n",
mAnchorNode, mAnchorNodeIsDirty, mDisabled,
ScrollFrame()->HasPendingScrollRestoration(),
ScrollFrame()->IsProcessingScrollEvent(),
ScrollFrame()->ScrollAnimationState().contains(
Frame()->HasPendingScrollRestoration(),
Frame()->IsProcessingScrollEvent(),
Frame()->ScrollAnimationState().contains(
nsIScrollableFrame::AnimationState::TriggeredByScript),
ScrollFrame()->GetScrollPosition() == nsPoint(),
mSuppressAnchorAdjustment, this);
Frame()->GetScrollPosition() == nsPoint(), mSuppressAnchorAdjustment,
this);
if (mSuppressAnchorAdjustment) {
mSuppressAnchorAdjustment = false;
InvalidateAnchor();
@ -476,8 +472,7 @@ void ScrollAnchorContainer::ApplyAdjustments() {
return;
}
nscoord current =
FindScrollAnchoringBoundingOffset(ScrollFrame(), mAnchorNode);
nscoord current = FindScrollAnchoringBoundingOffset(Frame(), mAnchorNode);
nscoord logicalAdjustment = current - mLastAnchorOffset;
WritingMode writingMode = Frame()->GetWritingMode();
@ -530,20 +525,18 @@ void ScrollAnchorContainer::ApplyAdjustments() {
MOZ_RELEASE_ASSERT(!mApplyingAnchorAdjustment);
// We should use AutoRestore here, but that doesn't work with bitfields
mApplyingAnchorAdjustment = true;
ScrollFrame()->ScrollTo(
ScrollFrame()->GetScrollPosition() + physicalAdjustment,
Frame()->ScrollToInternal(Frame()->GetScrollPosition() + physicalAdjustment,
ScrollMode::Instant, ScrollOrigin::Relative);
mApplyingAnchorAdjustment = false;
nsPresContext* pc = Frame()->PresContext();
if (ScrollFrame()->mIsRoot) {
if (Frame()->mIsRoot) {
pc->PresShell()->RootScrollFrameAdjusted(physicalAdjustment.y);
}
// The anchor position may not be in the same relative position after
// adjustment. Update ourselves so we have consistent state.
mLastAnchorOffset =
FindScrollAnchoringBoundingOffset(ScrollFrame(), mAnchorNode);
mLastAnchorOffset = FindScrollAnchoringBoundingOffset(Frame(), mAnchorNode);
}
ScrollAnchorContainer::ExamineResult
@ -654,8 +647,8 @@ ScrollAnchorContainer::ExamineAnchorCandidate(nsIFrame* aFrame) const {
//
// [1] https://github.com/w3c/csswg-drafts/issues/3483
nsRect visibleRect;
if (!visibleRect.IntersectRect(
rect, ScrollFrame()->GetVisualOptimalViewingRect())) {
if (!visibleRect.IntersectRect(rect,
Frame()->GetVisualOptimalViewingRect())) {
return ExamineResult::Exclude;
}

View file

@ -12,13 +12,10 @@
#include "mozilla/TimeStamp.h"
class nsFrameList;
class nsHTMLScrollFrame;
class nsIFrame;
class nsIScrollableFrame;
namespace mozilla {
class ScrollFrameHelper;
} // namespace mozilla
namespace mozilla::layout {
/**
@ -30,7 +27,7 @@ namespace mozilla::layout {
*/
class ScrollAnchorContainer final {
public:
explicit ScrollAnchorContainer(ScrollFrameHelper* aScrollFrame);
explicit ScrollAnchorContainer(nsHTMLScrollFrame* aScrollFrame);
~ScrollAnchorContainer();
/**
@ -45,11 +42,8 @@ class ScrollAnchorContainer final {
*/
nsIFrame* AnchorNode() const { return mAnchorNode; }
/**
* Returns the frame that owns this scroll anchor container. This is always
* non-null.
*/
nsIFrame* Frame() const;
// The owner of this scroll anchor container.
nsHTMLScrollFrame* Frame() const;
/**
* Returns the frame that owns this scroll anchor container as a scrollable
@ -139,9 +133,6 @@ class ScrollAnchorContainer final {
// anchoring on this scroller altogether based on various prefs.
void AdjustmentMade(nscoord aAdjustment);
// The owner of this scroll anchor container.
ScrollFrameHelper* ScrollFrame() const;
// The anchor node that we will scroll to keep in the same relative position
// after reflows. This may be null if we were not able to select a valid
// scroll anchor

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -364,13 +364,13 @@ class nsIScrollableFrame : public nsIScrollbarMediator {
* This basically means that we should allocate resources in the
* expectation that scrolling is going to happen.
*/
virtual bool IsScrollingActive() = 0;
virtual bool IsScrollingActive() const = 0;
/**
* Returns true if this scroll frame might be scrolled
* asynchronously by the compositor.
*/
virtual bool IsMaybeAsynchronouslyScrolled() = 0;
virtual bool IsMaybeAsynchronouslyScrolled() const = 0;
/**
* Was the current presentation state for this frame restored from history?
@ -391,7 +391,7 @@ class nsIScrollableFrame : public nsIScrollbarMediator {
* Determine if the passed in rect is nearly visible according to the frame
* visibility heuristics for how close it is to the visible scrollport.
*/
virtual bool IsRectNearlyVisible(const nsRect& aRect) = 0;
virtual bool IsRectNearlyVisible(const nsRect& aRect) const = 0;
/**
* Expand the given rect taking into account which directions we can scroll
* and how far we want to expand for frame visibility purposes.
@ -402,7 +402,7 @@ class nsIScrollableFrame : public nsIScrollbarMediator {
* ScrollOrigin::Apz when the compositor's replica frame metrics includes the
* latest instant scroll.
*/
virtual ScrollOrigin LastScrollOrigin() = 0;
virtual ScrollOrigin LastScrollOrigin() const = 0;
/**
* Gets the async scroll animation state of this scroll frame.

View file

@ -2465,7 +2465,7 @@ nsChangeHint nsStyleDisplay::CalcDifference(
} else if (isScrollable) {
if (ScrollbarGenerationChanged(*this, aNewData)) {
// We might need to reframe in the case of hidden -> non-hidden case
// though, since ScrollFrameHelper::CreateAnonymousContent avoids
// though, since nsHTMLScrollFrame::CreateAnonymousContent avoids
// creating scrollbars altogether for overflow: hidden. That seems it
// could create some interesting perf cliffs...
hint |= nsChangeHint_ScrollbarChange;

View file

@ -70,7 +70,7 @@
scrollbar, scrollbarbutton, scrollcorner, slider, thumb, resizer {
/* Force legacy XUL layout for now on scrollbars / resizers and descendants,
* as ScrollFrameHelper relies on that (and nsScrollbarFrame is a XUL frame
* as nsHTMLScrollFrame relies on that (and nsScrollbarFrame is a XUL frame
* anyways).
*
* TODO: Eventually we should rewrite scrollbars so that they don't use XUL

View file

@ -65,7 +65,7 @@ class nsIScrollbarMediator : public nsQueryFrame {
* aOldPos and aNewPos are scroll positions.
* The scroll positions start with zero at the left edge; implementors that
* want zero at the right edge for RTL content will need to adjust
* accordingly. (See ScrollFrameHelper::ThumbMoved in nsGfxScrollFrame.cpp.)
* accordingly. (See nsHTMLScrollFrame::ThumbMoved in nsGfxScrollFrame.cpp.)
* @note This method might destroy the frame, pres shell, and other objects.
*/
virtual void ThumbMoved(nsScrollbarFrame* aScrollbar, nscoord aOldPos,

View file

@ -4388,9 +4388,8 @@ pub extern "C" fn Servo_ComputedValues_EqualForCachedAnonymousContentStyle(
//
// If you do need a pref-controlled, inherited property to have an effect on these elements,
// then you will need to add some checks to the
// nsIAnonymousContentCreator::CreateAnonymousContent implementations of
// ScrollFrameHelper and nsScrollbarFrame to clear the AnonymousContentKey
// if a non-initial value is used.
// nsIAnonymousContentCreator::CreateAnonymousContent implementations of nsHTMLScrollFrame and
// nsScrollbarFrame to clear the AnonymousContentKey if a non-initial value is used.
differing_properties.remove_all(&LonghandIdSet::has_no_effect_on_gecko_scrollbars());
if !differing_properties.is_empty() {