diff options
author | Oriol Brufau <obrufau@igalia.com> | 2025-01-20 05:25:00 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-01-20 13:25:00 +0000 |
commit | f6c166533e1e324dd20d47ec3677acdbb1ae9c68 (patch) | |
tree | c7011f0093fe5ce3c0828e9eef8a2f2046de2d6e /components/layout_2020 | |
parent | 2965b2fda7046a25e0b919a8413994f081d85d44 (diff) | |
download | servo-f6c166533e1e324dd20d47ec3677acdbb1ae9c68.tar.gz servo-f6c166533e1e324dd20d47ec3677acdbb1ae9c68.zip |
layout: Respect alignment when sizing replaced abspos (#35085)
If an absolutely position element which is replaced has `justify-self`
or `align-self` set to `stretch`, and no inset is `auto` on that axis,
then an automatic size should behave as `stretch`, not as `fit-content`.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Diffstat (limited to 'components/layout_2020')
-rw-r--r-- | components/layout_2020/flexbox/layout.rs | 62 | ||||
-rw-r--r-- | components/layout_2020/geom.rs | 16 | ||||
-rw-r--r-- | components/layout_2020/positioned.rs | 17 | ||||
-rw-r--r-- | components/layout_2020/replaced.rs | 25 | ||||
-rw-r--r-- | components/layout_2020/taffy/layout.rs | 23 |
5 files changed, 92 insertions, 51 deletions
diff --git a/components/layout_2020/flexbox/layout.rs b/components/layout_2020/flexbox/layout.rs index 8501398b5d4..228370ecfac 100644 --- a/components/layout_2020/flexbox/layout.rs +++ b/components/layout_2020/flexbox/layout.rs @@ -1972,18 +1972,21 @@ impl FlexItem<'_> { containing_block, item_style, self.preferred_aspect_ratio, - &Sizes::new( - block_size - .to_definite() - .map_or(Size::Initial, Size::Numeric), - Size::Numeric(min_size.block), - max_size.block.map_or(Size::Initial, Size::Numeric), - ), - &Sizes::new( - Size::Numeric(inline_size), - Size::Numeric(min_size.inline), - max_size.inline.map_or(Size::Initial, Size::Numeric), - ), + LogicalVec2 { + block: &Sizes::new( + block_size + .to_definite() + .map_or(Size::Initial, Size::Numeric), + Size::Numeric(min_size.block), + max_size.block.map_or(Size::Initial, Size::Numeric), + ), + inline: &Sizes::new( + Size::Numeric(inline_size), + Size::Numeric(min_size.inline), + max_size.inline.map_or(Size::Initial, Size::Numeric), + ), + }, + Size::FitContent.into(), flex_axis.vec2_to_flow_relative(self.pbm_auto_is_zero), ); let hypothetical_cross_size = flex_axis.vec2_to_flex_relative(size).cross; @@ -2792,22 +2795,25 @@ impl FlexItemBox { flex_context.containing_block, style, preferred_aspect_ratio, - &Sizes::new( - content_box_size - .block - .non_auto() - .map_or(Size::Initial, Size::Numeric), - Size::Numeric(min_size.block), - max_size.block.map_or(Size::Initial, Size::Numeric), - ), - &Sizes::new( - content_box_size - .inline - .non_auto() - .map_or(Size::Initial, Size::Numeric), - Size::Numeric(min_size.inline), - max_size.inline.map_or(Size::Initial, Size::Numeric), - ), + LogicalVec2 { + block: &Sizes::new( + content_box_size + .block + .non_auto() + .map_or(Size::Initial, Size::Numeric), + Size::Numeric(min_size.block), + max_size.block.map_or(Size::Initial, Size::Numeric), + ), + inline: &Sizes::new( + content_box_size + .inline + .non_auto() + .map_or(Size::Initial, Size::Numeric), + Size::Numeric(min_size.inline), + max_size.inline.map_or(Size::Initial, Size::Numeric), + ), + }, + Size::FitContent.into(), padding_border_margin.padding_border_sums + padding_border_margin.margin.auto_is(Au::zero).sum(), ) diff --git a/components/layout_2020/geom.rs b/components/layout_2020/geom.rs index d316f165609..7114d4dc900 100644 --- a/components/layout_2020/geom.rs +++ b/components/layout_2020/geom.rs @@ -68,7 +68,23 @@ impl<T: Default> Default for LogicalVec2<T> { } } +impl<T: Copy> From<T> for LogicalVec2<T> { + fn from(value: T) -> Self { + Self { + inline: value, + block: value, + } + } +} + impl<T> LogicalVec2<T> { + pub(crate) fn as_ref(&self) -> LogicalVec2<&T> { + LogicalVec2 { + inline: &self.inline, + block: &self.block, + } + } + pub fn map_inline_and_block_axes<U>( &self, inline_f: impl FnOnce(&T) -> U, diff --git a/components/layout_2020/positioned.rs b/components/layout_2020/positioned.rs index df9ab1e7712..0aea0f76460 100644 --- a/components/layout_2020/positioned.rs +++ b/components/layout_2020/positioned.rs @@ -536,12 +536,25 @@ impl HoistedAbsolutelyPositionedBox { inline: inline_axis_solver.inset_sum(), block: block_axis_solver.inset_sum(), }; + let automatic_size = |alignment: AlignFlags, offsets: &AbsoluteBoxOffsets| { + if alignment.value() == AlignFlags::STRETCH && !offsets.either_auto() { + Size::Stretch + } else { + Size::FitContent + } + }; let used_size = replaced.used_size_as_if_inline_element_from_content_box_sizes( containing_block, &style, context.preferred_aspect_ratio(&pbm.padding_border_sums), - &block_axis_solver.computed_sizes, - &inline_axis_solver.computed_sizes, + LogicalVec2 { + inline: &inline_axis_solver.computed_sizes, + block: &block_axis_solver.computed_sizes, + }, + LogicalVec2 { + inline: automatic_size(inline_alignment, &inline_axis_solver.box_offsets), + block: automatic_size(block_alignment, &block_axis_solver.box_offsets), + }, pbm.padding_border_sums + pbm.margin.auto_is(Au::zero).sum() + inset_sums, ); inline_axis_solver.override_size(used_size.inline); diff --git a/components/layout_2020/replaced.rs b/components/layout_2020/replaced.rs index fe45344fcab..5d982dc4ee3 100644 --- a/components/layout_2020/replaced.rs +++ b/components/layout_2020/replaced.rs @@ -440,8 +440,8 @@ impl ReplacedContents { containing_block, style, self.preferred_aspect_ratio(style, &pbm.padding_border_sums), - &content_box_sizes_and_pbm.content_box_sizes.block, - &content_box_sizes_and_pbm.content_box_sizes.inline, + content_box_sizes_and_pbm.content_box_sizes.as_ref(), + Size::FitContent.into(), pbm.padding_border_sums + pbm.margin.auto_is(Au::zero).sum(), ) } @@ -486,8 +486,8 @@ impl ReplacedContents { containing_block: &ContainingBlock, style: &ComputedValues, preferred_aspect_ratio: Option<AspectRatio>, - block_sizes: &Sizes, - inline_sizes: &Sizes, + sizes: LogicalVec2<&Sizes>, + automatic_size: LogicalVec2<Size<Au>>, pbm_sums: LogicalVec2<Au>, ) -> LogicalVec2<Au> { // <https://drafts.csswg.org/css-images-3/#natural-dimensions> @@ -519,8 +519,11 @@ impl ReplacedContents { // through the aspect ratio, but these can also be intrinsic and depend on the inline size. // Therefore, we tentatively treat intrinsic block sizing properties as their initial value. let get_inline_content_size = || { - let get_block_size = - || block_sizes.resolve_extrinsic(Size::FitContent, Au::zero(), block_stretch_size); + let get_block_size = || { + sizes + .block + .resolve_extrinsic(automatic_size.block, Au::zero(), block_stretch_size) + }; self.content_size( Direction::Inline, preferred_aspect_ratio, @@ -529,8 +532,8 @@ impl ReplacedContents { ) .into() }; - let (preferred_inline, min_inline, max_inline) = inline_sizes.resolve_each( - Size::FitContent, + let (preferred_inline, min_inline, max_inline) = sizes.inline.resolve_each( + automatic_size.inline, Au::zero(), inline_stretch_size, get_inline_content_size, @@ -540,7 +543,7 @@ impl ReplacedContents { // Now we can compute the block size, using the inline size from above. let block_content_size = LazyCell::new(|| -> ContentSizes { let get_inline_size = || { - if inline_sizes.preferred.is_initial() { + if sizes.inline.preferred.is_initial() { // TODO: do we really need to special-case `auto`? // https://github.com/w3c/csswg-drafts/issues/11236 SizeConstraint::MinMax(min_inline, max_inline) @@ -556,8 +559,8 @@ impl ReplacedContents { ) .into() }); - let block_size = block_sizes.resolve( - Size::FitContent, + let block_size = sizes.block.resolve( + automatic_size.block, Au::zero(), block_stretch_size.unwrap_or_else(|| block_content_size.max_content), || *block_content_size, diff --git a/components/layout_2020/taffy/layout.rs b/components/layout_2020/taffy/layout.rs index ffbbbb6633c..2f58697eac3 100644 --- a/components/layout_2020/taffy/layout.rs +++ b/components/layout_2020/taffy/layout.rs @@ -161,16 +161,19 @@ impl taffy::LayoutPartialTree for TaffyContainerContext<'_> { style, independent_context .preferred_aspect_ratio(&pbm.padding_border_sums), - &Sizes::new( - option_f32_to_size(content_box_known_dimensions.height), - Size::Initial, - Size::Initial, - ), - &Sizes::new( - option_f32_to_size(content_box_known_dimensions.width), - Size::Initial, - Size::Initial, - ), + LogicalVec2 { + block: &Sizes::new( + option_f32_to_size(content_box_known_dimensions.height), + Size::Initial, + Size::Initial, + ), + inline: &Sizes::new( + option_f32_to_size(content_box_known_dimensions.width), + Size::Initial, + Size::Initial, + ), + }, + Size::FitContent.into(), pbm.padding_border_sums + pbm.margin.auto_is(Au::zero).sum(), ) .to_physical_size(self.style.writing_mode); |