forked from mirrors/gecko-dev
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:
parent
9553904295
commit
cb2a32d8af
12 changed files with 1223 additions and 1621 deletions
|
|
@ -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() &&
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue