tor-browser

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

commit ed620cdee7bb063499f54733c34230e437694c1a
parent a9a60b32dcc92e40f6460c8e28a1a072919588bc
Author: Jonathan Watt <jwatt@jwatt.org>
Date:   Tue,  9 Dec 2025 17:22:27 +0000

Bug 2004161. Fix position-area default self-alignment. r=dshin,firefox-style-system-reviewers,layout-reviewers,emilio

https://drafts.csswg.org/css-anchor-position-1/#position-area-alignment

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

Diffstat:
Mlayout/generic/WritingModes.h | 10++++++++++
Mlayout/generic/nsContainerFrame.cpp | 13++++++++-----
Mservo/ports/geckolib/glue.rs | 20++++++++++++++++----
3 files changed, 34 insertions(+), 9 deletions(-)

diff --git a/layout/generic/WritingModes.h b/layout/generic/WritingModes.h @@ -71,6 +71,12 @@ using PhysicalAxes = EnumSet<PhysicalAxis>; static constexpr PhysicalAxes kPhysicalAxesBoth{PhysicalAxis::Vertical, PhysicalAxis::Horizontal}; +inline StyleLogicalAxis ToStyleLogicalAxis(LogicalAxis aLogicalAxis) { + return StyleLogicalAxis(aLogicalAxis == LogicalAxis::Block + ? StyleLogicalAxis::Block + : StyleLogicalAxis::Inline); +} + inline LogicalAxis GetOrthogonalAxis(LogicalAxis aAxis) { return aAxis == LogicalAxis::Block ? LogicalAxis::Inline : LogicalAxis::Block; } @@ -474,6 +480,10 @@ class WritingMode { mWritingMode = aComputedStyle->WritingMode(); } + inline StyleWritingMode ToStyleWritingMode() const { + return StyleWritingMode(GetBits()); + } + /** * This function performs fixup for elements with 'unicode-bidi: plaintext', * where inline directionality is derived from the Unicode bidi categories diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp @@ -2550,11 +2550,14 @@ nsContainerFrame::CSSAlignmentForAbsPosChildWithinContainingBlock( : StyleAlignFlags::START; alignment |= StyleAlignFlags::UNSAFE; } else { - auto keyword = aLogicalAxis == LogicalAxis::Inline - ? aResolvedPositionArea.first - : aResolvedPositionArea.second; - // Use normal position-area alignment - Servo_ResolvePositionAreaSelfAlignment(&keyword, &alignment); + // Use default position-area self-alignment: + // https://drafts.csswg.org/css-anchor-position-1/#position-area-alignment + const auto axis = ToStyleLogicalAxis(aLogicalAxis); + const auto cbSWM = cbWM.ToStyleWritingMode(); + const auto selfWM = + aChildRI.mFrame->GetWritingMode().ToStyleWritingMode(); + Servo_ResolvePositionAreaSelfAlignment(&aResolvedPositionArea, axis, + &cbSWM, &selfWM, &alignment); } } diff --git a/servo/ports/geckolib/glue.rs b/servo/ports/geckolib/glue.rs @@ -106,7 +106,7 @@ use style::invalidation::element::relative_selector::{ }; use style::invalidation::element::restyle_hints::RestyleHint; use style::invalidation::stylesheets::RuleChangeKind; -use style::logical_geometry::{PhysicalAxis, PhysicalSide, WritingMode}; +use style::logical_geometry::{LogicalAxis, PhysicalAxis, PhysicalSide, WritingMode}; use style::media_queries::MediaList; use style::parser::{Parse, ParserContext}; use style::properties::declaration_block::PropertyTypedValue; @@ -165,7 +165,7 @@ use style::values::computed::length_percentage::{ }; use style::values::computed::position::{AnchorFunction, PositionArea}; use style::values::computed::{ - self, ContentVisibility, Context, PositionAreaKeyword, ToComputedValue, + self, ContentVisibility, Context, ToComputedValue, }; use style::values::distance::{ComputeSquaredDistance, SquaredDistance}; use style::values::generics::color::ColorMixFlags; @@ -10842,12 +10842,24 @@ pub extern "C" fn Servo_PhysicalizePositionArea( *area = area.to_physical(*cb_wm, *self_wm); } +/// https://drafts.csswg.org/css-anchor-position-1/#position-area-alignment #[no_mangle] pub extern "C" fn Servo_ResolvePositionAreaSelfAlignment( - area: &PositionAreaKeyword, + area: &PositionArea, + axis: LogicalAxis, + cb_wm: &WritingMode, + self_wm: &WritingMode, out: &mut AlignFlags, ) { - let Some(align) = area.to_self_alignment() else { + // As well as converting `area` and `axis` to the same form for comparison + // this also makes sure `area`'s second keyword explicit (not none). + let physical_area = area.to_physical(*cb_wm, *self_wm); + let physical_axis = axis.to_physical(*cb_wm); + let area_keyword = match physical_axis { + PhysicalAxis::Horizontal => physical_area.first, + PhysicalAxis::Vertical => physical_area.second, + }; + let Some(align) = area_keyword.to_self_alignment() else { debug_assert!( false, "ResolvePositionAreaSelfAlignment called on {:?}",