diff --git a/components/layout_2020/positioned.rs b/components/layout_2020/positioned.rs index c7b27bb27fc..7fcc7cdb254 100644 --- a/components/layout_2020/positioned.rs +++ b/components/layout_2020/positioned.rs @@ -7,6 +7,7 @@ use crate::dom_traversal::{Contents, NodeExt}; use crate::formatting_contexts::IndependentFormattingContext; use crate::fragments::{AnonymousFragment, BoxFragment, CollapsedBlockMargins, Fragment}; use crate::geom::flow_relative::{Rect, Sides, Vec2}; +use crate::sizing::shrink_to_fit; use crate::style_ext::{ComputedValuesExt, Direction, DisplayInside, WritingMode}; use crate::{ContainingBlock, DefiniteContainingBlock}; use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; @@ -51,8 +52,15 @@ impl AbsolutelyPositionedBox { display_inside: DisplayInside, contents: Contents>, ) -> Self { - let request_content_sizes = - style.inline_size_is_auto() && !style.inline_box_offsets_are_both_auto(); + // "Shrink-to-fit" in https://drafts.csswg.org/css2/visudet.html#abs-non-replaced-width + let request_content_sizes = { + // If inline-size is non-auto, that value is used without shrink-to-fit + style.inline_size_is_auto() && + // If it is, then the only case where shrink-to-fit is *not* used is + // if both offsets are non-auto, leaving inline-size as the only variable + // in the constraint equation. + !style.inline_box_offsets_are_both_non_auto() + }; Self { contents: IndependentFormattingContext::construct( context, @@ -278,8 +286,20 @@ impl<'a> AbsolutelyPositionedFragment<'a> { Anchor::End(end) => cbis - end - pb.inline_sum() - margin.inline_sum(), }; - // FIXME(nox): shrink-to-fit. - available_size + if self + .absolutely_positioned_box + .contents + .as_replaced() + .is_ok() + { + // FIXME: implement https://drafts.csswg.org/css2/visudet.html#abs-replaced-width + available_size + } else { + shrink_to_fit( + &self.absolutely_positioned_box.contents.inline_content_sizes, + available_size, + ) + } }); let containing_block_for_children = ContainingBlock { diff --git a/components/layout_2020/sizing.rs b/components/layout_2020/sizing.rs index a58602d23fd..01e28c7a064 100644 --- a/components/layout_2020/sizing.rs +++ b/components/layout_2020/sizing.rs @@ -65,10 +65,7 @@ pub(crate) fn outer_inline_content_sizes_and_percentages( let specified = specified.map(|lp| lp.as_length()); // The (inner) min/max-content are only used for 'auto' let mut outer = match specified.non_auto().flatten() { - None => inner_content_sizes - .as_ref() - .expect("Accessing content size that was not requested") - .clone(), + None => expect(inner_content_sizes).clone(), Some(length) => ContentSizes { min_content: length, max_content: length, @@ -96,3 +93,20 @@ pub(crate) fn outer_inline_content_sizes_and_percentages( (outer, pbm_percentages) } + +/// https://drafts.csswg.org/css2/visudet.html#shrink-to-fit-float +pub(crate) fn shrink_to_fit( + content_sizes: &Option, + available_size: Length, +) -> Length { + let content_sizes = expect(content_sizes); + available_size + .max(content_sizes.min_content) + .min(content_sizes.max_content) +} + +fn expect(content_sizes: &Option) -> &ContentSizes { + content_sizes + .as_ref() + .expect("Accessing content size that was not requested") +} diff --git a/components/layout_2020/style_ext.rs b/components/layout_2020/style_ext.rs index 436058798d9..ebdf217e81a 100644 --- a/components/layout_2020/style_ext.rs +++ b/components/layout_2020/style_ext.rs @@ -45,7 +45,7 @@ pub(crate) trait ComputedValuesExt { fn writing_mode(&self) -> (WritingMode, Direction); fn writing_mode_is_horizontal(&self) -> bool; fn inline_size_is_auto(&self) -> bool; - fn inline_box_offsets_are_both_auto(&self) -> bool; + fn inline_box_offsets_are_both_non_auto(&self) -> bool; fn box_offsets(&self) -> flow_relative::Sides; fn box_size(&self) -> flow_relative::Vec2; fn padding(&self) -> flow_relative::Sides; @@ -78,7 +78,7 @@ impl ComputedValuesExt for ComputedValues { matches!(size, Size::Auto) } - fn inline_box_offsets_are_both_auto(&self) -> bool { + fn inline_box_offsets_are_both_non_auto(&self) -> bool { let position = self.get_position(); let offsets = if self.writing_mode_is_horizontal() { (position.left, position.right) @@ -87,7 +87,10 @@ impl ComputedValuesExt for ComputedValues { }; matches!( offsets, - (LengthPercentageOrAuto::Auto, LengthPercentageOrAuto::Auto) + ( + LengthPercentageOrAuto::LengthPercentage(_), + LengthPercentageOrAuto::LengthPercentage(_), + ) ) } diff --git a/tests/wpt/metadata-layout-2020/css/CSS2/box-display/containing-block-008.xht.ini b/tests/wpt/metadata-layout-2020/css/CSS2/box-display/containing-block-008.xht.ini deleted file mode 100644 index dd630be0f54..00000000000 --- a/tests/wpt/metadata-layout-2020/css/CSS2/box-display/containing-block-008.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[containing-block-008.xht] - expected: FAIL diff --git a/tests/wpt/metadata-layout-2020/css/CSS2/box-display/containing-block-010.xht.ini b/tests/wpt/metadata-layout-2020/css/CSS2/box-display/containing-block-010.xht.ini deleted file mode 100644 index af40eef0a5d..00000000000 --- a/tests/wpt/metadata-layout-2020/css/CSS2/box-display/containing-block-010.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[containing-block-010.xht] - expected: FAIL