From 039631cfa59e4f831fbbb42a164e46026f217d41 Mon Sep 17 00:00:00 2001 From: Delan Azabani Date: Tue, 16 Jul 2024 20:14:02 +0800 Subject: [PATCH] layout: Properly handle min/max cross container size (#32785) Signed-off-by: Martin Robinson Co-authored-by: Martin Robinson Co-authored-by: Mukilan Thiyagarajan --- components/layout_2020/flexbox/layout.rs | 60 ++++++++++++------- components/layout_2020/formatting_contexts.rs | 1 + ...ontainer-justify-center.tentative.html.ini | 3 + .../flexbox-definite-sizes-001.html.ini | 2 - .../flexbox-single-line-clamp-1.html.ini | 2 - .../flexbox-single-line-clamp-3.html.ini | 2 - .../percentage-heights-003.html.ini | 9 +-- 7 files changed, 47 insertions(+), 32 deletions(-) create mode 100644 tests/wpt/meta/css/css-flexbox/fieldset-as-container-justify-center.tentative.html.ini delete mode 100644 tests/wpt/meta/css/css-flexbox/flexbox-definite-sizes-001.html.ini delete mode 100644 tests/wpt/meta/css/css-flexbox/flexbox-single-line-clamp-1.html.ini delete mode 100644 tests/wpt/meta/css/css-flexbox/flexbox-single-line-clamp-3.html.ini diff --git a/components/layout_2020/flexbox/layout.rs b/components/layout_2020/flexbox/layout.rs index 624451a4d97..b9029f7fac2 100644 --- a/components/layout_2020/flexbox/layout.rs +++ b/components/layout_2020/flexbox/layout.rs @@ -14,7 +14,9 @@ use style::properties::longhands::box_sizing::computed_value::T as BoxSizing; use style::properties::longhands::flex_direction::computed_value::T as FlexDirection; use style::properties::longhands::flex_wrap::computed_value::T as FlexWrap; use style::properties::longhands::justify_content::computed_value::T as JustifyContent; +use style::properties::ComputedValues; use style::values::computed::length::Size; +use style::values::computed::Length; use style::values::generics::flex::GenericFlexBasis as FlexBasis; use style::Zero; @@ -160,6 +162,7 @@ impl FlexContainer { layout_context: &LayoutContext, positioning_context: &mut PositioningContext, containing_block: &ContainingBlock, + containing_block_for_container: &ContainingBlock, ) -> IndependentLayout { // Actual length may be less, but we guess that usually not by a lot let mut flex_items = Vec::with_capacity(self.children.len()); @@ -192,33 +195,28 @@ impl FlexContainer { }) .collect::>(); - let flex_item_boxes = flex_items.iter_mut().map(|child| &mut **child); - - // FIXME: get actual min/max cross size for the flex container. - // We have access to style for the flex container in `containing_block.style`, - // but resolving percentages there requires access - // to the flex container’s own containing block which we don’t have. - // For now, use incorrect values instead of panicking: - let container_min_cross_size = Au::zero(); - let container_max_cross_size = None; - - let flex_container_position_style = containing_block.style.get_position(); - let flex_wrap = flex_container_position_style.flex_wrap; - let flex_direction = flex_container_position_style.flex_direction; - // Column flex containers are not fully implemented yet, // so give a different layout instead of panicking. // FIXME: implement `todo!`s for FlexAxis::Column below, and remove this - let flex_direction = match flex_direction { + let container_style = containing_block.style; + let flex_direction = match container_style.clone_flex_direction() { FlexDirection::Row | FlexDirection::Column => FlexDirection::Row, FlexDirection::RowReverse | FlexDirection::ColumnReverse => FlexDirection::RowReverse, }; - let container_is_single_line = match containing_block.style.get_position().flex_wrap { + let flex_axis = FlexAxis::from(flex_direction); + let (container_min_cross_size, container_max_cross_size) = self + .available_cross_space_for_flex_items( + container_style, + flex_axis, + containing_block_for_container, + ); + + let flex_wrap = container_style.get_position().flex_wrap; + let container_is_single_line = match flex_wrap { FlexWrap::Nowrap => true, FlexWrap::Wrap | FlexWrap::WrapReverse => false, }; - let flex_axis = FlexAxis::from(flex_direction); let flex_direction_is_reversed = match flex_direction { FlexDirection::Row | FlexDirection::Column => false, FlexDirection::RowReverse | FlexDirection::ColumnReverse => true, @@ -227,9 +225,9 @@ impl FlexContainer { FlexWrap::Nowrap | FlexWrap::Wrap => false, FlexWrap::WrapReverse => true, }; - let align_content = containing_block.style.clone_align_content(); - let align_items = containing_block.style.clone_align_items(); - let justify_content = containing_block.style.clone_justify_content(); + let align_content = container_style.clone_align_content(); + let align_items = container_style.clone_align_items(); + let justify_content = container_style.clone_justify_content(); let mut flex_context = FlexContext { layout_context, @@ -255,6 +253,7 @@ impl FlexContainer { }), }; + let flex_item_boxes = flex_items.iter_mut().map(|child| &mut **child); let mut flex_items = flex_item_boxes .map(|box_| FlexItem::new(&flex_context, box_)) .collect::>(); @@ -473,6 +472,27 @@ impl FlexContainer { baselines: Baselines::default(), } } + + fn available_cross_space_for_flex_items( + &self, + style: &ComputedValues, + flex_axis: FlexAxis, + containing_block_for_container: &ContainingBlock, + ) -> (Au, Option) { + let pbm = style.padding_border_margin(containing_block_for_container); + let max_box_size = style.content_max_box_size(containing_block_for_container, &pbm); + let min_box_size = style + .content_min_box_size(containing_block_for_container, &pbm) + .auto_is(Length::zero); + + let max_box_size = flex_axis.vec2_to_flex_relative(max_box_size); + let min_box_size = flex_axis.vec2_to_flex_relative(min_box_size); + + ( + min_box_size.cross.into(), + max_box_size.cross.map(Into::into), + ) + } } impl<'a> FlexItem<'a> { diff --git a/components/layout_2020/formatting_contexts.rs b/components/layout_2020/formatting_contexts.rs index 371201e09eb..c056709deb5 100644 --- a/components/layout_2020/formatting_contexts.rs +++ b/components/layout_2020/formatting_contexts.rs @@ -228,6 +228,7 @@ impl NonReplacedFormattingContext { layout_context, positioning_context, containing_block_for_children, + containing_block, ), NonReplacedFormattingContextContents::Table(table) => table.layout( layout_context, diff --git a/tests/wpt/meta/css/css-flexbox/fieldset-as-container-justify-center.tentative.html.ini b/tests/wpt/meta/css/css-flexbox/fieldset-as-container-justify-center.tentative.html.ini new file mode 100644 index 00000000000..3363b8e7b91 --- /dev/null +++ b/tests/wpt/meta/css/css-flexbox/fieldset-as-container-justify-center.tentative.html.ini @@ -0,0 +1,3 @@ +[fieldset-as-container-justify-center.tentative.html] + [.item 1] + expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/flexbox-definite-sizes-001.html.ini b/tests/wpt/meta/css/css-flexbox/flexbox-definite-sizes-001.html.ini deleted file mode 100644 index 8a5d723170b..00000000000 --- a/tests/wpt/meta/css/css-flexbox/flexbox-definite-sizes-001.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[flexbox-definite-sizes-001.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/flexbox-single-line-clamp-1.html.ini b/tests/wpt/meta/css/css-flexbox/flexbox-single-line-clamp-1.html.ini deleted file mode 100644 index d25f6f6fbdc..00000000000 --- a/tests/wpt/meta/css/css-flexbox/flexbox-single-line-clamp-1.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[flexbox-single-line-clamp-1.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/flexbox-single-line-clamp-3.html.ini b/tests/wpt/meta/css/css-flexbox/flexbox-single-line-clamp-3.html.ini deleted file mode 100644 index 8ee6ca6fddd..00000000000 --- a/tests/wpt/meta/css/css-flexbox/flexbox-single-line-clamp-3.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[flexbox-single-line-clamp-3.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/percentage-heights-003.html.ini b/tests/wpt/meta/css/css-flexbox/percentage-heights-003.html.ini index a4e2fcc1efc..17cc488a50e 100644 --- a/tests/wpt/meta/css/css-flexbox/percentage-heights-003.html.ini +++ b/tests/wpt/meta/css/css-flexbox/percentage-heights-003.html.ini @@ -1,9 +1,6 @@ [percentage-heights-003.html] - [.flexbox 6] - expected: FAIL - - [.flexbox 7] - expected: FAIL - [.flexbox 2] expected: FAIL + + [.flexbox 3] + expected: FAIL