tor-browser

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

commit f9538b019e72db60784a50b613c4ed9bcd26a905
parent 89b86fad2fafb90dcd329d06999393dab29af58a
Author: Jonathan Kew <jkew@mozilla.com>
Date:   Sat, 27 Dec 2025 15:37:20 +0000

Bug 1989059 - Account for position-try-order when choosing position fallback. r=layout-anchor-positioning-reviewers,layout-reviewers,emilio

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

Diffstat:
Mlayout/generic/AbsoluteContainingBlock.cpp | 64+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Dtesting/web-platform/meta/css/css-anchor-position/position-try-order-basic.html.ini | 39---------------------------------------
Dtesting/web-platform/meta/css/css-anchor-position/position-try-order-position-area.html.ini | 39---------------------------------------
3 files changed, 59 insertions(+), 83 deletions(-)

diff --git a/layout/generic/AbsoluteContainingBlock.cpp b/layout/generic/AbsoluteContainingBlock.cpp @@ -1176,8 +1176,10 @@ void AbsoluteContainingBlock::ReflowAbsoluteFrame( AutoNoisyIndenter indent(nsBlockFrame::gNoisy); #endif // DEBUG + const WritingMode outerWM = aReflowInput.GetWritingMode(); + const WritingMode wm = aKidFrame->GetWritingMode(); + const bool isGrid = aFlags.contains(AbsPosReflowFlag::IsGridContainerCB); - // TODO(bug 1989059): position-try-order. auto fallbacks = aKidFrame->StylePosition()->mPositionTryFallbacks._0.AsSpan(); Maybe<uint32_t> currentFallbackIndex; @@ -1185,6 +1187,31 @@ void AbsoluteContainingBlock::ReflowAbsoluteFrame( RefPtr<ComputedStyle> currentFallbackStyle; RefPtr<ComputedStyle> firstTryStyle; Maybe<uint32_t> firstTryIndex; + // If non-'normal' position-try-order is in effect, we keep track of the + // index of the "best" option seen, and its size in the relevant axis, so + // that once all fallbacks have been considered we can reset to the one + // that provided the most space. + Maybe<uint32_t> bestIndex; + nscoord bestSize = -1; + // Flag to indicate that we've determined which fallback to use and should + // exit the loop. + bool finalizing = false; + + auto tryOrder = aKidFrame->StylePosition()->mPositionTryOrder; + // If position-try-order is a logical value, resolve to physical using + // the containing block's writing mode. + switch (tryOrder) { + case StylePositionTryOrder::MostInlineSize: + tryOrder = outerWM.IsVertical() ? StylePositionTryOrder::MostHeight + : StylePositionTryOrder::MostWidth; + break; + case StylePositionTryOrder::MostBlockSize: + tryOrder = outerWM.IsVertical() ? StylePositionTryOrder::MostWidth + : StylePositionTryOrder::MostHeight; + break; + default: + break; + } // Set the current fallback to the given index, or reset to the base position // if Nothing() is passed. @@ -1355,8 +1382,6 @@ void AbsoluteContainingBlock::ReflowAbsoluteFrame( aAnchorPosResolutionCache->mReferenceData->mAdjustedContainingBlock = cb.mFinalRect; } - const WritingMode outerWM = aReflowInput.GetWritingMode(); - const WritingMode wm = aKidFrame->GetWritingMode(); const LogicalSize cbSize(outerWM, cb.mFinalRect.Size()); ReflowInput::InitFlags initFlags; @@ -1658,7 +1683,9 @@ void AbsoluteContainingBlock::ReflowAbsoluteFrame( // containing-block, see: // https://drafts.csswg.org/css-anchor-position-1/#fallback-apply const auto fits = aStatus.IsComplete() && FitsInContainingBlock(); - if (fallbacks.IsEmpty() || fits) { + if (fallbacks.IsEmpty() || finalizing || + (fits && (tryOrder == StylePositionTryOrder::Normal || + currentFallbackIndex == firstTryIndex))) { // We completed the reflow - Either we had a fallback that fit, or we // didn't have any to try in the first place. isOverflowingCB = !fits; @@ -1669,9 +1696,36 @@ void AbsoluteContainingBlock::ReflowAbsoluteFrame( break; } + if (fits) { + auto imcbSize = cb.mFinalRect.Size(); + imcbSize -= nsSize{insets.LeftRight(), insets.TopBottom()}; + switch (tryOrder) { + case StylePositionTryOrder::MostWidth: + if (imcbSize.Width() > bestSize) { + bestSize = imcbSize.Width(); + bestIndex = currentFallbackIndex; + } + break; + case StylePositionTryOrder::MostHeight: + if (imcbSize.Height() > bestSize) { + bestSize = imcbSize.Height(); + bestIndex = currentFallbackIndex; + } + break; + default: + MOZ_ASSERT_UNREACHABLE("unexpected try-order value"); + break; + } + } + if (!TryAdvanceFallback()) { // If there are no further fallbacks, we're done. - break; + if (bestSize >= 0) { + finalizing = true; + SeekFallbackTo(bestIndex); + } else { + break; + } } // Try with the next fallback. diff --git a/testing/web-platform/meta/css/css-anchor-position/position-try-order-basic.html.ini b/testing/web-platform/meta/css/css-anchor-position/position-try-order-basic.html.ini @@ -1,39 +0,0 @@ -[position-try-order-basic.html] - [most-inline-size --right, --left | --left] - expected: FAIL - - [most-width --right, --left | --left] - expected: FAIL - - [most-block-size --bottom, --top | --top] - expected: FAIL - - [most-height --bottom, --top | --top] - expected: FAIL - - [most-inline-size --right, --left, --bottom, --top | --bottom] - expected: FAIL - - [most-inline-size --right, --left, --top, --bottom | --top] - expected: FAIL - - [most-block-size --bottom, --top, --right, --left | --right] - expected: FAIL - - [most-block-size --bottom, --top, --left, --right | --left] - expected: FAIL - - [most-block-size --bottom-sweep, --left-sweep | --left-sweep] - expected: FAIL - - [most-inline-size --right-sweep, --left-sweep, --bottom-sweep, --top-sweep | --left-sweep] - expected: FAIL - - [most-block-size --right-sweep, --left-sweep, --bottom-sweep, --top-sweep | --top-sweep] - expected: FAIL - - [most-inline-size\n --right-sweep, --left-sweep, --bottom-sweep, --top-sweep,\n /* --right, --left, --bottom, --top */\n --bottom\n | --bottom] - expected: FAIL - - [most-block-size\n --right-sweep, --left-sweep, --bottom-sweep, --top-sweep,\n /* --right, --left, --bottom, --top */\n --right\n | --right] - expected: FAIL diff --git a/testing/web-platform/meta/css/css-anchor-position/position-try-order-position-area.html.ini b/testing/web-platform/meta/css/css-anchor-position/position-try-order-position-area.html.ini @@ -1,39 +0,0 @@ -[position-try-order-position-area.html] - [most-inline-size --right, --left, --bottom, --top | --bottom] - expected: FAIL - - [most-inline-size --right, --left, --top, --bottom | --top] - expected: FAIL - - [most-block-size --bottom, --top, --right, --left | --right] - expected: FAIL - - [most-block-size --bottom, --top, --left, --right | --left] - expected: FAIL - - [most-inline-size --right-sweep, --left-sweep, --bottom-sweep, --top-sweep | --left-sweep] - expected: FAIL - - [most-inline-size --right, --left | --left] - expected: FAIL - - [most-width --right, --left | --left] - expected: FAIL - - [most-block-size --bottom, --top | --top] - expected: FAIL - - [most-height --bottom, --top | --top] - expected: FAIL - - [most-block-size --bottom-sweep, --left-sweep | --left-sweep] - expected: FAIL - - [most-block-size --right-sweep, --left-sweep, --bottom-sweep, --top-sweep | --top-sweep] - expected: FAIL - - [most-inline-size\n --right-sweep, --left-sweep, --bottom-sweep, --top-sweep,\n /* --right, --left, --bottom, --top */\n --bottom\n | --bottom] - expected: FAIL - - [most-block-size\n --right-sweep, --left-sweep, --bottom-sweep, --top-sweep,\n /* --right, --left, --bottom, --top */\n --right\n | --right] - expected: FAIL