tor-browser

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

commit 1d3aea82862601fd5f5b9cf533c6e06d04b1595e
parent 5b42ac4317bfd8b4753c6b2b012a5c8c21d67376
Author: Timothy Nikkel <tnikkel@gmail.com>
Date:   Wed, 26 Nov 2025 13:55:41 +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 @@ -857,7 +857,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 @@ -868,9 +869,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