layout: Properly handle min/max cross container size (#32785)

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Mukilan Thiyagarajan <mukilan@igalia.com>
This commit is contained in:
Delan Azabani 2024-07-16 20:14:02 +08:00 committed by GitHub
parent 80559c829b
commit 039631cfa5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 47 additions and 32 deletions

View file

@ -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_direction::computed_value::T as FlexDirection;
use style::properties::longhands::flex_wrap::computed_value::T as FlexWrap; 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::longhands::justify_content::computed_value::T as JustifyContent;
use style::properties::ComputedValues;
use style::values::computed::length::Size; use style::values::computed::length::Size;
use style::values::computed::Length;
use style::values::generics::flex::GenericFlexBasis as FlexBasis; use style::values::generics::flex::GenericFlexBasis as FlexBasis;
use style::Zero; use style::Zero;
@ -160,6 +162,7 @@ impl FlexContainer {
layout_context: &LayoutContext, layout_context: &LayoutContext,
positioning_context: &mut PositioningContext, positioning_context: &mut PositioningContext,
containing_block: &ContainingBlock, containing_block: &ContainingBlock,
containing_block_for_container: &ContainingBlock,
) -> IndependentLayout { ) -> IndependentLayout {
// Actual length may be less, but we guess that usually not by a lot // Actual length may be less, but we guess that usually not by a lot
let mut flex_items = Vec::with_capacity(self.children.len()); let mut flex_items = Vec::with_capacity(self.children.len());
@ -192,33 +195,28 @@ impl FlexContainer {
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
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 containers own containing block which we dont 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, // Column flex containers are not fully implemented yet,
// so give a different layout instead of panicking. // so give a different layout instead of panicking.
// FIXME: implement `todo!`s for FlexAxis::Column below, and remove this // 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::Row | FlexDirection::Column => FlexDirection::Row,
FlexDirection::RowReverse | FlexDirection::ColumnReverse => FlexDirection::RowReverse, 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::Nowrap => true,
FlexWrap::Wrap | FlexWrap::WrapReverse => false, FlexWrap::Wrap | FlexWrap::WrapReverse => false,
}; };
let flex_axis = FlexAxis::from(flex_direction);
let flex_direction_is_reversed = match flex_direction { let flex_direction_is_reversed = match flex_direction {
FlexDirection::Row | FlexDirection::Column => false, FlexDirection::Row | FlexDirection::Column => false,
FlexDirection::RowReverse | FlexDirection::ColumnReverse => true, FlexDirection::RowReverse | FlexDirection::ColumnReverse => true,
@ -227,9 +225,9 @@ impl FlexContainer {
FlexWrap::Nowrap | FlexWrap::Wrap => false, FlexWrap::Nowrap | FlexWrap::Wrap => false,
FlexWrap::WrapReverse => true, FlexWrap::WrapReverse => true,
}; };
let align_content = containing_block.style.clone_align_content(); let align_content = container_style.clone_align_content();
let align_items = containing_block.style.clone_align_items(); let align_items = container_style.clone_align_items();
let justify_content = containing_block.style.clone_justify_content(); let justify_content = container_style.clone_justify_content();
let mut flex_context = FlexContext { let mut flex_context = FlexContext {
layout_context, 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 let mut flex_items = flex_item_boxes
.map(|box_| FlexItem::new(&flex_context, box_)) .map(|box_| FlexItem::new(&flex_context, box_))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
@ -473,6 +472,27 @@ impl FlexContainer {
baselines: Baselines::default(), baselines: Baselines::default(),
} }
} }
fn available_cross_space_for_flex_items(
&self,
style: &ComputedValues,
flex_axis: FlexAxis,
containing_block_for_container: &ContainingBlock,
) -> (Au, Option<Au>) {
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> { impl<'a> FlexItem<'a> {

View file

@ -228,6 +228,7 @@ impl NonReplacedFormattingContext {
layout_context, layout_context,
positioning_context, positioning_context,
containing_block_for_children, containing_block_for_children,
containing_block,
), ),
NonReplacedFormattingContextContents::Table(table) => table.layout( NonReplacedFormattingContextContents::Table(table) => table.layout(
layout_context, layout_context,

View file

@ -0,0 +1,3 @@
[fieldset-as-container-justify-center.tentative.html]
[.item 1]
expected: FAIL

View file

@ -1,2 +0,0 @@
[flexbox-definite-sizes-001.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[flexbox-single-line-clamp-1.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[flexbox-single-line-clamp-3.html]
expected: FAIL

View file

@ -1,9 +1,6 @@
[percentage-heights-003.html] [percentage-heights-003.html]
[.flexbox 6]
expected: FAIL
[.flexbox 7]
expected: FAIL
[.flexbox 2] [.flexbox 2]
expected: FAIL expected: FAIL
[.flexbox 3]
expected: FAIL