tor-browser

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

commit 330ab66d10425ffea1a5145f8e454c83f52205e4
parent bb13e903d533c70ff7a4dd58328e614ed950503d
Author: Cristina Horotan <chorotan@mozilla.com>
Date:   Thu, 18 Dec 2025 01:50:13 +0200

Revert "Bug 2006002: Ensure that positioned elements with implicit anchors get scroll compensated. r=layout-anchor-positioning-reviewers,firefox-style-system-reviewers,layout-reviewers,emilio" for causing bc failures on browser_retainedResultsOnFocus.js

This reverts commit 7b0c7c8034392fdb8cd13f220973f47927c4bfc4.

Diffstat:
Mlayout/base/PresShell.cpp | 66++++++++++++++++++++++++------------------------------------------
Mlayout/base/PresShell.h | 3---
Mlayout/style/ComputedStyle.cpp | 9+++++----
Dtesting/web-platform/tests/css/css-anchor-position/anchor-scroll-implicit-001.html | 53-----------------------------------------------------
Dtesting/web-platform/tests/css/css-anchor-position/anchor-scroll-implicit-002.html | 60------------------------------------------------------------
5 files changed, 29 insertions(+), 162 deletions(-)

diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp @@ -11571,26 +11571,17 @@ struct AffectedAnchorGroup { nsTArray<AffectedAnchor> mFrames; }; -static const nsIFrame* NearestScrollContainerOfAffectedAnchor( - const nsIFrame* aAnchor, const ScrollContainerFrame* aScrollContainer) { - const auto* scrollContainer = - AnchorPositioningUtils::GetNearestScrollFrame(aAnchor).mScrollContainer; - if (!scrollContainer) { - // Fixed-pos anchor, likely - return nullptr; - } - // Does this scroll container match a anchor's nearest scroll container, - // or contain it? - if (scrollContainer == aScrollContainer || - nsLayoutUtils::IsProperAncestorFrame(aScrollContainer, scrollContainer)) { - return scrollContainer; - } - return nullptr; -} - static nsTArray<AffectedAnchorGroup> FindAnchorsAffectedByScroll( const nsTHashMap<RefPtr<const nsAtom>, nsTArray<nsIFrame*>>& aAnchors, const ScrollContainerFrame* aScrollContainer) { + const auto AffectedByScrollContainer = + [](const nsIFrame* aFrame, const ScrollContainerFrame* aScrollContainer) { + MOZ_ASSERT(aFrame); + MOZ_ASSERT(aScrollContainer); + return aFrame == aScrollContainer || + nsLayoutUtils::IsProperAncestorFrame(aScrollContainer, aFrame); + }; + nsTArray<AffectedAnchorGroup> affectedAnchors; // We keep only referenced anchors' name in positioned frames to avoid dealing // with lifetime issues associated with it. Now we need to re-establish that @@ -11600,8 +11591,14 @@ static nsTArray<AffectedAnchorGroup> FindAnchorsAffectedByScroll( Maybe<nsTArray<AffectedAnchor>> affected; for (const auto& frame : anchorFrames) { const auto* scrollContainer = - NearestScrollContainerOfAffectedAnchor(frame, aScrollContainer); + AnchorPositioningUtils::GetNearestScrollFrame(frame).mScrollContainer; if (!scrollContainer) { + // Fixed-pos anchor, likely + continue; + } + // Does this scroll container match a anchor's nearest scroll container, + // or contain it? + if (!AffectedByScrollContainer(scrollContainer, aScrollContainer)) { continue; } if (affected.isNothing()) { @@ -11619,9 +11616,8 @@ static nsTArray<AffectedAnchorGroup> FindAnchorsAffectedByScroll( // Given a list of anchors affected by scrolling, find one that the given // positioned frame need to compensate scroll for. -static Maybe<AffectedAnchor> FindScrollCompensatedAnchor( +static Maybe<const AffectedAnchor&> FindScrollCompensatedAnchor( const PresShell* aPresShell, - const ScrollContainerFrame* aScrolledScrollContainer, const nsTArray<AffectedAnchorGroup>& aAffectedAnchors, const nsIFrame* aPositioned, const AnchorPosReferenceData& aReferenceData, const nsIFrame** aResolvedDefaultAnchor) { @@ -11654,22 +11650,6 @@ static Maybe<AffectedAnchor> FindScrollCompensatedAnchor( return Nothing{}; } - if (defaultAnchorName == nsGkAtoms::AnchorPosImplicitAnchor) { - // We're not going to find this in `aAffectedAnchors`, which works off of - // `PresShell::mAnchorPosAnchors`, which doesn't store implicit anchors. - const auto* anchor = - AnchorPositioningUtils::GetAnchorPosImplicitAnchor(aPositioned); - if (!anchor) { - return Nothing{}; - } - const auto* scrollContainer = NearestScrollContainerOfAffectedAnchor( - anchor, aScrolledScrollContainer); - if (!scrollContainer) { - return Nothing{}; - } - return Some(AffectedAnchor{anchor, scrollContainer}); - } - struct Comparator { bool Equals(const AffectedAnchor& aEntry, const nsIFrame* aFrame) const { return aEntry.mAnchor == aFrame; @@ -11692,7 +11672,7 @@ static Maybe<AffectedAnchor> FindScrollCompensatedAnchor( break; } const auto& info = anchors.ElementAt(idx); - return Some(info); + return SomeRef(info); } return Nothing{}; @@ -11746,7 +11726,7 @@ static bool AnchorIsStickyOrChainedToScrollCompensatedAnchor( // https://drafts.csswg.org/css-anchor-position-1/#default-scroll-shift void PresShell::UpdateAnchorPosForScroll( const ScrollContainerFrame* aScrollContainer) { - if (mAnchorPosAnchors.IsEmpty() && mAnchorPosPositioned.IsEmpty()) { + if (mAnchorPosAnchors.IsEmpty()) { return; } @@ -11757,7 +11737,10 @@ void PresShell::UpdateAnchorPosForScroll( // can. nsTArray<AffectedAnchorGroup> affectedAnchors = FindAnchorsAffectedByScroll(mAnchorPosAnchors, aScrollContainer); - // Affected anchors may be empty, an implicit anchor may have scrolled. + + if (affectedAnchors.IsEmpty()) { + return; + } // Now, update all affected positioned elements' scroll offsets. for (auto* positioned : mAnchorPosPositioned) { @@ -11767,9 +11750,8 @@ void PresShell::UpdateAnchorPosForScroll( continue; } const nsIFrame* defaultAnchor = nullptr; - const auto scrollDependency = - FindScrollCompensatedAnchor(this, aScrollContainer, affectedAnchors, - positioned, *referenceData, &defaultAnchor); + const auto scrollDependency = FindScrollCompensatedAnchor( + this, affectedAnchors, positioned, *referenceData, &defaultAnchor); const bool offsetChanged = [&]() { if (!scrollDependency) { return false; diff --git a/layout/base/PresShell.h b/layout/base/PresShell.h @@ -3261,9 +3261,6 @@ class PresShell final : public nsStubDocumentObserver, // cannot be determined. nsTArray<AnchorPosAnchorChange> mLazyAnchorPosAnchorChanges; - // Note: Does not store implicit anchors, since many elements can be - // potential implicit anchors (e.g. pseudo-elements' implicit anchor - // is its originating element). nsTHashMap<RefPtr<const nsAtom>, nsTArray<nsIFrame*>> mAnchorPosAnchors; nsTArray<nsIFrame*> mAnchorPosPositioned; diff --git a/layout/style/ComputedStyle.cpp b/layout/style/ComputedStyle.cpp @@ -432,10 +432,11 @@ void ComputedStyle::DumpMatchedRules() const { bool ComputedStyle::HasAnchorPosReference() const { const auto* pos = StylePosition(); - if (pos->mPositionAnchor.IsIdent() || pos->mPositionAnchor.IsAuto()) { - // Short circuit if there's a default anchor defined (Or an implicit one), - // even if it may not end up being referenced. If this early return is - // removed, we'll need to handle mPositionArea explicitly. + if (pos->mPositionAnchor.IsIdent()) { + // Short circuit if there's a default anchor defined, even if + // it may not end up being referenced. + // If this early return is removed, we'll need to handle mPositionArea + // explicitly. return true; } diff --git a/testing/web-platform/tests/css/css-anchor-position/anchor-scroll-implicit-001.html b/testing/web-platform/tests/css/css-anchor-position/anchor-scroll-implicit-001.html @@ -1,53 +0,0 @@ -<!DOCTYPE html> -<html class=reftest-wait> -<title>Tests that scroll adjustments of implicitly anchored elements are applied correctly</title> -<link rel="author" href="mailto:dshin@mozilla.com"> -<link rel="help" href="https://drafts.csswg.org/css-anchor-position-1/"> -<link rel="match" href="../reference/ref-filled-green-100px-square.xht"> -<style> -.positioned { - position: fixed; - width: 100px; - height: 50px; - left: anchor(left); - top: anchor(bottom); - background: green; - border: none; - padding: 0; - margin: 0; -} - -.container { - position: relative; - width: 100px; - height: 100px; - background: red; - overflow: hidden; -} - -.filler { - width: 1px; - height: 50px; -} - -.anchor { - width: 100px; - height: 50px; - background: green; - border: none; - padding: 0; -} -</style> -<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> -<div class=positioned popover id="popover"></div> -<div id=s class=container> - <div class=filler></div> - <button id=b class=anchor popovertarget="popover"></button> - <div class=filler></div> -</div> -<script> -b.click(); -s.scrollTop = 50; -document.documentElement.classList.remove('reftest-wait'); -</script> -</html> diff --git a/testing/web-platform/tests/css/css-anchor-position/anchor-scroll-implicit-002.html b/testing/web-platform/tests/css/css-anchor-position/anchor-scroll-implicit-002.html @@ -1,60 +0,0 @@ -<!DOCTYPE html> -<html class=reftest-wait> -<title>Tests that scroll adjustments of implicitly anchored elements are applied correctly</title> -<link rel="author" href="mailto:dshin@mozilla.com"> -<link rel="help" href="https://drafts.csswg.org/css-anchor-position-1/"> -<link rel="match" href="../reference/ref-filled-green-100px-square.xht"> -<style> -.positioned { - position: absolute; - width: 100px; - height: 50px; - left: anchor(left); - top: anchor(bottom); - background: green; - border: none; - padding: 0; - margin: 0; -} - -.container { - position: relative; - width: 100px; - height: 100px; - background: red; -} - -.scroller { - width: 100%; - height: 100%; - overflow: hidden; -} - -.filler { - width: 1px; - height: 50px; -} - -.anchor { - width: 100px; - height: 50px; - background: green; - border: none; - padding: 0; -} -</style> -<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> -<div class=container> - <div id=s class=scroller> - <div class=filler></div> - <button id=b class=anchor popovertarget="popover"></button> - <div class=filler></div> - </div> - <div class=positioned popover id="popover"></div> -</div> -<script> -b.click(); -s.scrollTop = 50; -document.documentElement.classList.remove('reftest-wait'); -</script> -</html>