tor-browser

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

commit 0793c4b404d9a35dbe3e3fd664f79c4eaf413490
parent 1d4569b701e516aeac490140b832a4fc07f28a5b
Author: Timothy Nikkel <tnikkel@gmail.com>
Date:   Wed, 26 Nov 2025 13:55:40 +0000

Bug 1988030. Adjust nsLayoutUtils::GetAsyncScrollableAncestorFrame to be CSS anchor pos aware. r=layout-reviewers,layout-anchor-positioning-reviewers,hiro,emilio

We want to assign the ASR of the anchor to the anchored content. That means we are changing the ASR chain so we need to adjust the functions that walk the async scrollable ancestors chain. In this patch we adjust nsLayoutUtils::GetAsyncScrollableAncestorFrame.

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

Diffstat:
Mlayout/base/AnchorPositioningUtils.cpp | 19+++++++++++++++++++
Mlayout/base/AnchorPositioningUtils.h | 6++++++
Mlayout/base/nsLayoutUtils.cpp | 25+++++++++++++++++++++++++
3 files changed, 50 insertions(+), 0 deletions(-)

diff --git a/layout/base/AnchorPositioningUtils.cpp b/layout/base/AnchorPositioningUtils.cpp @@ -874,4 +874,23 @@ bool AnchorPositioningUtils::FitsInContainingBlock( .Contains(rect); } +nsIFrame* AnchorPositioningUtils::GetAnchorThatFrameScrollsWith( + nsIFrame* aFrame) { + mozilla::PhysicalAxes axes = aFrame->GetAnchorPosCompensatingForScroll(); + // TODO for now we return the anchor if we are compensating in either axis. + // This is not fully spec compliant, bug 1988034 tracks this. + if (axes.isEmpty()) { + return nullptr; + } + + const auto* pos = aFrame->StylePosition(); + if (!pos->mPositionAnchor.IsIdent()) { + return nullptr; + } + + const nsAtom* defaultAnchorName = pos->mPositionAnchor.AsIdent().AsAtom(); + return const_cast<nsIFrame*>( + aFrame->PresShell()->GetAnchorPosAnchor(defaultAnchorName, aFrame)); +} + } // namespace mozilla diff --git a/layout/base/AnchorPositioningUtils.h b/layout/base/AnchorPositioningUtils.h @@ -309,6 +309,12 @@ struct AnchorPositioningUtils { const ContainingBlockInfo& aContainingBlockInfo, const nsIFrame* aPositioned, const AnchorPosReferenceData* aReferenceData); + + /** + * If aFrame is positioned using CSS anchor positioning, and it scrolls with + * its anchor this function returns the anchor. Otherwise null. + */ + static nsIFrame* GetAnchorThatFrameScrollsWith(nsIFrame* aFrame); }; } // namespace mozilla diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp @@ -10,6 +10,7 @@ #include <limits> #include "ActiveLayerTracker.h" +#include "AnchorPositioningUtils.h" #include "DisplayItemClip.h" #include "ImageContainer.h" #include "ImageOps.h" @@ -164,6 +165,7 @@ #include "nsTransitionManager.h" #include "nsXULPopupManager.h" #include "prenv.h" +#include "AnchorPositioningUtils.h" // Make sure getpid() works. #ifdef XP_WIN @@ -1362,6 +1364,29 @@ static nsIFrame* GetNearestScrollableOrOverflowClipFrame( } } } + + nsIFrame* anchor = nullptr; + // If the current frame also happens to be fixed then we want to check if it + // scrolls with its anchor before the special fixed behaviour below because + // scrolling with its anchor overrides that behaviour and is higher + // priority. + + // This needs to be a while loop because anchors can chain, and we don't + // want to consider each frame in this loop separately (as a potential + // scrollable ancestor) because they are all equivalent in the scrollable + // ancestor chain: they all scroll together. We are not walking up the async + // scrollable ancestor chain, but rather we are move sideways. And when we + // exit this loop we want to move up one because we haven't yet ascended + // (because of that same reason), and that moving up one will happen either + // via the special fixed pos behaviour below or the next iteration of the + // outer for loop. + if (aFlags & nsLayoutUtils::SCROLLABLE_ONLY_ASYNC_SCROLLABLE) { + while ( + (anchor = AnchorPositioningUtils::GetAnchorThatFrameScrollsWith(f))) { + f = anchor; + } + } + if ((aFlags & nsLayoutUtils::SCROLLABLE_FIXEDPOS_FINDS_ROOT) && f->StyleDisplay()->mPosition == StylePositionProperty::Fixed && nsLayoutUtils::IsReallyFixedPos(f)) {