tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 7cd59a61c6a01fdd88254a2d880191ebcd3865ab
parent e53645f574d4cccad40a679ab9cb3cf0fbbcf110
Author: Timothy Nikkel <tnikkel@gmail.com>
Date:   Wed, 26 Nov 2025 13:04:52 +0000

Bug 1988030. Allow passing a limit ancestor to DisplayPortUtils::OneStepInASRChain that we don't walk past. r=hiro,layout-reviewers

With CSS anchor pos we know that the anchor is in the containing block of the anchored content. We use that to limit a walk up the frame tree in subsequent patches and make the computation simpler. So we need OneStepInASRChain to obey that limit too.

Differential Revision: https://phabricator.services.mozilla.com/D271804

Diffstat:
Mlayout/base/DisplayPortUtils.cpp | 14++++++++++++--
Mlayout/base/DisplayPortUtils.h | 6++++--
2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/layout/base/DisplayPortUtils.cpp b/layout/base/DisplayPortUtils.cpp @@ -856,7 +856,8 @@ nsIFrame* DisplayPortUtils::OneStepInAsyncScrollableAncestorChain( return nsLayoutUtils::GetCrossDocParentFrameInProcess(aFrame); } -nsIFrame* DisplayPortUtils::OneStepInASRChain(nsIFrame* aFrame) { +nsIFrame* DisplayPortUtils::OneStepInASRChain( + nsIFrame* aFrame, nsIFrame* aLimitAncestor /* = nullptr */) { // This mirrors one iteration of GetNearestScrollableOrOverflowClipFrame in // nsLayoutUtils.cpp as called by nsLayoutUtils::GetASRAncestorFrame. They // should be kept in sync. See that function for comments about the structure @@ -867,9 +868,18 @@ nsIFrame* DisplayPortUtils::OneStepInASRChain(nsIFrame* aFrame) { nsIFrame* anchor = nullptr; while ((anchor = AnchorPositioningUtils::GetAnchorThatFrameScrollsWith(aFrame))) { + MOZ_ASSERT_IF(aLimitAncestor, + nsLayoutUtils::IsProperAncestorFrameConsideringContinuations( + aLimitAncestor, anchor)); aFrame = anchor; } - return nsLayoutUtils::GetCrossDocParentFrameInProcess(aFrame); + nsIFrame* parent = nsLayoutUtils::GetCrossDocParentFrameInProcess(aFrame); + if (aLimitAncestor && parent && + (parent == aLimitAncestor || + parent->FirstContinuation() == aLimitAncestor->FirstContinuation())) { + return nullptr; + } + return parent; } void DisplayPortUtils::SetZeroMarginDisplayPortOnAsyncScrollableAncestors( diff --git a/layout/base/DisplayPortUtils.h b/layout/base/DisplayPortUtils.h @@ -294,9 +294,11 @@ class DisplayPortUtils { * ASR frame to the next. Rather this walks all frame types, taking only one * ancestor step per call. Note that a frame returned from this function could * generate two ASRs: an inner one corresponding to an activated scroll frame, - * and an outer one corresponding to sticky pos. + * and an outer one corresponding to sticky pos. Returns null if we hit + * aLimitAncestor. */ - static nsIFrame* OneStepInASRChain(nsIFrame* aFrame); + static nsIFrame* OneStepInASRChain(nsIFrame* aFrame, + nsIFrame* aLimitAncestor = nullptr); /** * Sets a zero margin display port on all proper ancestors of aFrame that