From 8c56cbdab207239e4f05b253970e16e75b0a3958 Mon Sep 17 00:00:00 2001 From: Oriol Brufau Date: Thu, 10 Oct 2024 17:25:59 +0200 Subject: [PATCH] Implement keyword sizes on atomic inlines (#33737) Adds support for min-content, max-content, fit-content and stretch, for atomic inlines. There are some new test failures because we don't support vertical writing modes nor `transition-behavior:allow-discrete`. Signed-off-by: Oriol Brufau --- components/layout_2020/flow/inline/mod.rs | 112 ++++++++----- tests/wpt/meta/MANIFEST.json | 7 + .../animation/height-interpolation.html.ini | 18 +++ ...ntainer-with-min-or-max-content-1.html.ini | 2 - ...tainer-with-min-or-max-content-2a.html.ini | 2 + .../keyword-sizes-on-inline-block.html | 148 ++++++++++++++++++ 6 files changed, 248 insertions(+), 41 deletions(-) delete mode 100644 tests/wpt/meta/css/css-sizing/hori-block-size-small-or-larger-than-container-with-min-or-max-content-1.html.ini create mode 100644 tests/wpt/meta/css/css-sizing/vert-block-size-small-or-larger-than-container-with-min-or-max-content-2a.html.ini create mode 100644 tests/wpt/tests/css/css-sizing/keyword-sizes-on-inline-block.html diff --git a/components/layout_2020/flow/inline/mod.rs b/components/layout_2020/flow/inline/mod.rs index 8a2c47ef282..d2890234da8 100644 --- a/components/layout_2020/flow/inline/mod.rs +++ b/components/layout_2020/flow/inline/mod.rs @@ -123,11 +123,11 @@ use crate::fragment_tree::{ BoxFragment, CollapsedBlockMargins, CollapsedMargin, Fragment, FragmentFlags, PositioningFragment, }; -use crate::geom::{LogicalRect, LogicalVec2, PhysicalPoint, PhysicalRect, ToLogical}; +use crate::geom::{LogicalRect, LogicalVec2, PhysicalPoint, PhysicalRect, Size, ToLogical}; use crate::positioned::{AbsolutelyPositionedBox, PositioningContext}; use crate::sizing::ContentSizes; use crate::style_ext::{Clamp, ComputedValuesExt, PaddingBorderMargin}; -use crate::{ContainingBlock, IndefiniteContainingBlock}; +use crate::{AuOrAuto, ContainingBlock, IndefiniteContainingBlock}; // From gfxFontConstants.h in Firefox. static FONT_SUBSCRIPT_OFFSET_RATIO: f32 = 0.20; @@ -1932,42 +1932,70 @@ impl IndependentFormattingContext { IndependentFormattingContext::NonReplaced(non_replaced) => { let box_size = non_replaced .style - .content_box_size_deprecated(layout.containing_block, &pbm) - .map(|v| v.map(Au::from)); + .content_box_size(layout.containing_block, &pbm); let max_box_size = non_replaced .style - .content_max_box_size_deprecated(layout.containing_block, &pbm) - .map(|v| v.map(Au::from)); + .content_max_box_size(layout.containing_block, &pbm); let min_box_size = non_replaced .style - .content_min_box_size_deprecated(layout.containing_block, &pbm) - .map(|v| v.map(Au::from)) - .auto_is(Au::zero); - let block_size = box_size - .block - .map(|v| v.clamp_between_extremums(min_box_size.block, max_box_size.block)); + .content_min_box_size(layout.containing_block, &pbm); - // https://drafts.csswg.org/css2/visudet.html#inlineblock-width - let tentative_inline_size = box_size.inline.auto_is(|| { - let style = non_replaced.style.clone(); + let available_inline_size = + layout.containing_block.inline_size - pbm_sums.inline_sum(); + let available_block_size = layout + .containing_block + .block_size + .non_auto() + .map(|block_size| block_size - pbm_sums.block_sum()); + let tentative_block_size = box_size + .block + .maybe_resolve_extrinsic(available_block_size) + .map(|v| { + let min_block_size = min_box_size + .block + .maybe_resolve_extrinsic(available_block_size) + .unwrap_or_default(); + let max_block_size = max_box_size + .block + .maybe_resolve_extrinsic(available_block_size); + v.clamp_between_extremums(min_block_size, max_block_size) + }) + .map_or(AuOrAuto::Auto, AuOrAuto::LengthPercentage); + + let style = non_replaced.style.clone(); + let mut get_content_size = || { let containing_block_for_children = - IndefiniteContainingBlock::new_for_style_and_block_size(&style, block_size); - let available_size = - layout.containing_block.inline_size - pbm_sums.inline_sum(); + IndefiniteContainingBlock::new_for_style_and_block_size( + &style, + tentative_block_size, + ); non_replaced .inline_content_sizes(layout.layout_context, &containing_block_for_children) - .shrink_to_fit(available_size) - }); + }; + + // https://drafts.csswg.org/css2/visudet.html#inlineblock-width + let tentative_inline_size = box_size.inline.resolve( + Size::fit_content, + available_inline_size, + &mut get_content_size, + ); // https://drafts.csswg.org/css2/visudet.html#min-max-widths // In this case “applying the rules above again” with a non-auto inline-size // always results in that size. - let inline_size = tentative_inline_size - .clamp_between_extremums(min_box_size.inline, max_box_size.inline); + let min_inline_size = min_box_size + .inline + .resolve_non_initial(available_inline_size, &mut get_content_size) + .unwrap_or_default(); + let max_inline_size = max_box_size + .inline + .resolve_non_initial(available_inline_size, &mut get_content_size); + let inline_size = + tentative_inline_size.clamp_between_extremums(min_inline_size, max_inline_size); let containing_block_for_children = ContainingBlock { inline_size, - block_size, + block_size: tentative_block_size, style: &non_replaced.style, }; assert_eq!( @@ -1988,22 +2016,28 @@ impl IndependentFormattingContext { &containing_block_for_children, layout.containing_block, ); - let (inline_size, block_size) = - match independent_layout.content_inline_size_for_table { - Some(inline) => (inline, independent_layout.content_block_size), - None => { - // https://drafts.csswg.org/css2/visudet.html#block-root-margin - let block_size = block_size.auto_is(|| { - // https://drafts.csswg.org/css2/visudet.html#min-max-heights - // In this case “applying the rules above again” with a non-auto block-size - // always results in that size. - independent_layout - .content_block_size - .clamp_between_extremums(min_box_size.block, max_box_size.block) - }); - (inline_size, block_size) - }, - }; + let (inline_size, block_size) = match independent_layout + .content_inline_size_for_table + { + Some(inline) => (inline, independent_layout.content_block_size), + None => { + // https://drafts.csswg.org/css2/visudet.html#block-root-margin + let stretch_size = + available_block_size.unwrap_or(independent_layout.content_block_size); + let mut get_content_size = || independent_layout.content_block_size.into(); + let min_block_size = min_box_size + .block + .resolve_non_initial(stretch_size, &mut get_content_size) + .unwrap_or_default(); + let max_block_size = max_box_size + .block + .resolve_non_initial(stretch_size, &mut get_content_size); + let block_size = tentative_block_size + .auto_is(|| independent_layout.content_block_size) + .clamp_between_extremums(min_block_size, max_block_size); + (inline_size, block_size) + }, + }; let content_rect = PhysicalRect::new( PhysicalPoint::zero(), diff --git a/tests/wpt/meta/MANIFEST.json b/tests/wpt/meta/MANIFEST.json index 5d76955c361..bab19e96824 100644 --- a/tests/wpt/meta/MANIFEST.json +++ b/tests/wpt/meta/MANIFEST.json @@ -565466,6 +565466,13 @@ {} ] ], + "keyword-sizes-on-inline-block.html": [ + "a66e118c203678bae777c1fbd572a30dde6e0a5f", + [ + null, + {} + ] + ], "min-max-content-orthogonal-flow-crash-001.html": [ "d2617f8aa2d1c966e394abb1d1617c012ea4648e", [ diff --git a/tests/wpt/meta/css/css-sizing/animation/height-interpolation.html.ini b/tests/wpt/meta/css/css-sizing/animation/height-interpolation.html.ini index 4e9354a0d3b..88ff05eb181 100644 --- a/tests/wpt/meta/css/css-sizing/animation/height-interpolation.html.ini +++ b/tests/wpt/meta/css/css-sizing/animation/height-interpolation.html.ini @@ -478,3 +478,21 @@ [Web Animations: property from neutral to [fit-content\] at (1.5) should be [fit-content\]] expected: FAIL + + [CSS Transitions with transition-behavior:allow-discrete: property from [max-content\] to [stretch\] at (-0.3) should be [max-content\]] + expected: FAIL + + [CSS Transitions with transition-behavior:allow-discrete: property from [max-content\] to [stretch\] at (0) should be [max-content\]] + expected: FAIL + + [CSS Transitions with transition-behavior:allow-discrete: property from [max-content\] to [stretch\] at (0.3) should be [max-content\]] + expected: FAIL + + [CSS Transitions with transition-property:all and transition-behavor:allow-discrete: property from [max-content\] to [stretch\] at (-0.3) should be [max-content\]] + expected: FAIL + + [CSS Transitions with transition-property:all and transition-behavor:allow-discrete: property from [max-content\] to [stretch\] at (0) should be [max-content\]] + expected: FAIL + + [CSS Transitions with transition-property:all and transition-behavor:allow-discrete: property from [max-content\] to [stretch\] at (0.3) should be [max-content\]] + expected: FAIL diff --git a/tests/wpt/meta/css/css-sizing/hori-block-size-small-or-larger-than-container-with-min-or-max-content-1.html.ini b/tests/wpt/meta/css/css-sizing/hori-block-size-small-or-larger-than-container-with-min-or-max-content-1.html.ini deleted file mode 100644 index a74a97f81dd..00000000000 --- a/tests/wpt/meta/css/css-sizing/hori-block-size-small-or-larger-than-container-with-min-or-max-content-1.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[hori-block-size-small-or-larger-than-container-with-min-or-max-content-1.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-sizing/vert-block-size-small-or-larger-than-container-with-min-or-max-content-2a.html.ini b/tests/wpt/meta/css/css-sizing/vert-block-size-small-or-larger-than-container-with-min-or-max-content-2a.html.ini new file mode 100644 index 00000000000..0958045ea3e --- /dev/null +++ b/tests/wpt/meta/css/css-sizing/vert-block-size-small-or-larger-than-container-with-min-or-max-content-2a.html.ini @@ -0,0 +1,2 @@ +[vert-block-size-small-or-larger-than-container-with-min-or-max-content-2a.html] + expected: FAIL diff --git a/tests/wpt/tests/css/css-sizing/keyword-sizes-on-inline-block.html b/tests/wpt/tests/css/css-sizing/keyword-sizes-on-inline-block.html new file mode 100644 index 00000000000..a66e118c203 --- /dev/null +++ b/tests/wpt/tests/css/css-sizing/keyword-sizes-on-inline-block.html @@ -0,0 +1,148 @@ + +Keyword sizes on floated element + + + + + + + + + +
+ + +
+
X X
+
X X
+
X X
+ +
XXX XXX
+
XXX XXX
+
XXX XXX
+ +
XXXXX XXXXX
+
XXXXX XXXXX
+
XXXXX XXXXX
+ +
+ +
X X
+
X X
+
X X
+ +
XXX XXX
+
XXX XXX
+
XXX XXX
+ +
XXXXX XXXXX
+
XXXXX XXXXX
+
XXXXX XXXXX
+ +
+ +
X X
+
X X
+
X X
+ +
XXX XXX
+
XXX XXX
+
XXX XXX
+ +
XXXXX XXXXX
+
XXXXX XXXXX
+
XXXXX XXXXX
+ +
+ +
X X
+
X X
+
X X
+ +
X X
+
X X
+
X X
+ +
X X
+
X X
+
X X
+
+ + +
+
X X
+
XXX XXX
+
XXXXX XXXXX
+ +
X X
+
XXX XXX
+
XXXXX XXXXX
+ +
X X
+
XXX XXX
+
XXXXX XXXXX
+ +
X X
+
XXX XXX<
+
XXXXX XXXXX
+ +
X X
+
XXX XXX
+
XXXXX XXXXX
+ +
X X
+
XXX XXX
+
XXXXX XXXXX
+
+ + +
+
X X
+
XXX XXX
+
XXXXX XXXXX
+ +
X X
+
XXX XXX
+
XXXXX XXXXX
+ +
X X
+
XXX XXX
+
XXXXX XXXXX
+
+ + + + +