tor-browser

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

commit b9daf63e7c7b0f79ab612ae4339079cf530bfa5c
parent 75b5b74832e62fa4129ee70d450863ff13e3e6d5
Author: Jonathan Kew <jkew@mozilla.com>
Date:   Wed, 10 Dec 2025 16:41:10 +0000

Bug 2005214 - patch 1 - Fix PositionAreaKeyword::to_self_alignment() to resolve correctly for the containing block's writing mode. r=layout-reviewers,firefox-style-system-reviewers,jwatt,emilio

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

Diffstat:
Mservo/components/style/logical_geometry.rs | 7++++++-
Mservo/components/style/values/specified/position.rs | 27++++++++++++++++++++++-----
Mservo/ports/geckolib/glue.rs | 9++++-----
3 files changed, 32 insertions(+), 11 deletions(-)

diff --git a/servo/components/style/logical_geometry.rs b/servo/components/style/logical_geometry.rs @@ -113,7 +113,7 @@ bitflags!( const WRITING_MODE_HORIZONTAL_TB = 0; /// * writing-mode: vertical_rl; const WRITING_MODE_VERTICAL_RL = WritingMode::VERTICAL.bits(); - /// * writing-mode: vertcail-lr; + /// * writing-mode: vertical-lr; const WRITING_MODE_VERTICAL_LR = WritingMode::VERTICAL.bits() | WritingMode::VERTICAL_LR.bits() | WritingMode::LINE_INVERTED.bits(); @@ -223,6 +223,11 @@ impl WritingMode { } #[inline] + pub fn is_vertical_rl(&self) -> bool { + self.is_vertical() && !self.is_vertical_lr() + } + + #[inline] pub fn is_horizontal(&self) -> bool { !self.is_vertical() } diff --git a/servo/components/style/values/specified/position.rs b/servo/components/style/values/specified/position.rs @@ -1177,10 +1177,13 @@ impl PositionAreaKeyword { } /// Returns a value for the self-alignment properties in order to resolve - /// `normal`. + /// `normal`, in terms of the containing block's writing mode. + /// + /// Note that the caller must have converted the position-area to physical + /// values. /// /// <https://drafts.csswg.org/css-anchor-position/#position-area-alignment> - pub fn to_self_alignment(self) -> Option<AlignFlags> { + pub fn to_self_alignment(self, axis: LogicalAxis, cb_wm: &WritingMode) -> Option<AlignFlags> { let track = self.track()?; Some(match track { // "If the only the center track in an axis is selected, the default alignment in that axis is center." @@ -1190,10 +1193,24 @@ impl PositionAreaKeyword { // "Otherwise, the default alignment in that axis is toward the non-specified side track: if it’s // specifying the “start” track of its axis, the default alignment in that axis is end; etc." _ => { - if track.start() { - AlignFlags::END + debug_assert_eq!(self.group_type(), PositionAreaType::Physical); + if axis == LogicalAxis::Inline { + // For the inline axis, map 'start' to 'end' unless the axis is inline-reversed, + // meaning that its logical flow is counter to physical coordinates and therefore + // physical 'start' already corresponds to logical 'end'. + if track.start() == cb_wm.intersects(WritingMode::INLINE_REVERSED) { + AlignFlags::START + } else { + AlignFlags::END + } } else { - AlignFlags::START + // For the block axis, only vertical-rl has reversed flow and therefore + // does not map 'start' to 'end' here. + if track.start() == cb_wm.is_vertical_rl() { + AlignFlags::START + } else { + AlignFlags::END + } } }, }) diff --git a/servo/ports/geckolib/glue.rs b/servo/ports/geckolib/glue.rs @@ -164,9 +164,7 @@ use style::values::computed::length_percentage::{ AllowAnchorPosResolutionInCalcPercentage, Unpacked, }; use style::values::computed::position::{AnchorFunction, PositionArea}; -use style::values::computed::{ - self, ContentVisibility, Context, ToComputedValue, -}; +use style::values::computed::{self, ContentVisibility, Context, ToComputedValue}; use style::values::distance::{ComputeSquaredDistance, SquaredDistance}; use style::values::generics::color::ColorMixFlags; use style::values::generics::easing::BeforeFlag; @@ -10852,14 +10850,15 @@ pub extern "C" fn Servo_ResolvePositionAreaSelfAlignment( out: &mut AlignFlags, ) { // As well as converting `area` and `axis` to the same form for comparison - // this also makes sure `area`'s second keyword explicit (not none). + // this also makes sure `area`'s second keyword is 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 { + // Note that area_keyword is a physical value (left/right/top/bottom). + let Some(align) = area_keyword.to_self_alignment(axis, cb_wm) else { debug_assert!( false, "ResolvePositionAreaSelfAlignment called on {:?}",