aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout_2020
diff options
context:
space:
mode:
authorOriol Brufau <obrufau@igalia.com>2025-01-20 05:25:00 -0800
committerGitHub <noreply@github.com>2025-01-20 13:25:00 +0000
commitf6c166533e1e324dd20d47ec3677acdbb1ae9c68 (patch)
treec7011f0093fe5ce3c0828e9eef8a2f2046de2d6e /components/layout_2020
parent2965b2fda7046a25e0b919a8413994f081d85d44 (diff)
downloadservo-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.rs62
-rw-r--r--components/layout_2020/geom.rs16
-rw-r--r--components/layout_2020/positioned.rs17
-rw-r--r--components/layout_2020/replaced.rs25
-rw-r--r--components/layout_2020/taffy/layout.rs23
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);