diff --git a/components/layout_2020/flexbox/layout.rs b/components/layout_2020/flexbox/layout.rs index 040f1fe9bcd..edbc40c9264 100644 --- a/components/layout_2020/flexbox/layout.rs +++ b/components/layout_2020/flexbox/layout.rs @@ -19,6 +19,7 @@ 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::values::generics::length::LengthPercentageOrNormal; use style::values::specified::align::AlignFlags; use style::Zero; @@ -299,16 +300,37 @@ impl FlexContainer { }, }; + let row_gap = container_style.clone_row_gap(); + let column_gap = container_style.clone_column_gap(); + let (cross_gap, main_gap) = match flex_context.flex_axis { + FlexAxis::Row => (row_gap, column_gap), + FlexAxis::Column => (column_gap, row_gap), + }; + let cross_gap = match cross_gap { + LengthPercentageOrNormal::LengthPercentage(length_percent) => length_percent + .maybe_to_used_value(flex_context.container_definite_inner_size.cross) + .unwrap_or_default(), + LengthPercentageOrNormal::Normal => Au::zero(), + }; + let main_gap = match main_gap { + LengthPercentageOrNormal::LengthPercentage(length_percent) => length_percent + .maybe_to_used_value(flex_context.container_definite_inner_size.main) + .unwrap_or_default(), + LengthPercentageOrNormal::Normal => Au::zero(), + }; + // “Resolve the flexible lengths of all the flex items to find their *used main size*.” // https://drafts.csswg.org/css-flexbox/#algo-flex let flex_lines = collect_flex_lines( &mut flex_context, container_main_size, &mut flex_items, - |flex_context, mut line| line.layout(flex_context, container_main_size), + main_gap, ); - let content_cross_size = flex_lines.iter().map(|line| line.cross_size).sum(); + let line_count = flex_lines.len(); + let content_cross_size = flex_lines.iter().map(|line| line.cross_size).sum::() + + cross_gap * (line_count as i32 - 1); // https://drafts.csswg.org/css-flexbox/#algo-cross-container let container_cross_size = flex_context @@ -322,9 +344,8 @@ impl FlexContainer { // https://drafts.csswg.org/css-flexbox/#algo-line-align // Align all flex lines per `align-content`. - let line_count = flex_lines.len(); let mut cross_start_position_cursor = Au::zero(); - let mut line_interval = Au::zero(); + let mut line_interval = cross_gap; if let Some(cross_size) = flex_context.container_definite_inner_size.cross { let free_space = cross_size - content_cross_size; @@ -391,8 +412,7 @@ impl FlexContainer { _ => Au::zero(), }; - // TODO: Implement gap property - line_interval = /*gap + */ match resolved_align_content { + line_interval += match resolved_align_content { AlignFlags::START => Au::zero(), AlignFlags::FLEX_START => Au::zero(), AlignFlags::END => Au::zero(), @@ -791,17 +811,17 @@ fn collect_flex_lines<'items>( flex_context: &mut FlexContext, container_main_size: Au, mut items: &'items mut [FlexItem<'items>], - mut each: impl FnMut(&mut FlexContext, FlexLine<'items>) -> FlexLineLayoutResult, + main_gap: Au, ) -> Vec { if flex_context.container_is_single_line { - let line = FlexLine { + let mut line = FlexLine { outer_hypothetical_main_sizes_sum: items .iter() .map(|item| item.hypothetical_main_size + item.pbm_auto_is_zero.main) .sum(), items, }; - vec![each(flex_context, line)] + vec![line.layout(flex_context, container_main_size, main_gap)] } else { let mut lines = Vec::new(); let mut line_size_so_far = Au::zero(); @@ -809,7 +829,10 @@ fn collect_flex_lines<'items>( let mut index = 0; while let Some(item) = items.get(index) { let item_size = item.hypothetical_main_size + item.pbm_auto_is_zero.main; - let line_size_would_be = line_size_so_far + item_size; + let mut line_size_would_be = line_size_so_far + item_size; + if !line_so_far_is_empty { + line_size_would_be += main_gap; + } let item_fits = line_size_would_be <= container_main_size; if item_fits || line_so_far_is_empty { line_size_so_far = line_size_would_be; @@ -818,23 +841,23 @@ fn collect_flex_lines<'items>( } else { // We found something that doesn’t fit. This line ends *before* this item. let (line_items, rest) = items.split_at_mut(index); - let line = FlexLine { + let mut line = FlexLine { items: line_items, outer_hypothetical_main_sizes_sum: line_size_so_far, }; items = rest; - lines.push(each(flex_context, line)); + lines.push(line.layout(flex_context, container_main_size, main_gap)); // The next line has this item. line_size_so_far = item_size; index = 1; } } // The last line is added even without finding an item that doesn’t fit - let line = FlexLine { + let mut line = FlexLine { items, outer_hypothetical_main_sizes_sum: line_size_so_far, }; - lines.push(each(flex_context, line)); + lines.push(line.layout(flex_context, container_main_size, main_gap)); lines } } @@ -844,9 +867,11 @@ impl FlexLine<'_> { &mut self, flex_context: &mut FlexContext, container_main_size: Au, + main_gap: Au, ) -> FlexLineLayoutResult { + let item_count = self.items.len(); let (item_used_main_sizes, mut free_space) = - self.resolve_flexible_lengths(container_main_size); + self.resolve_flexible_lengths(container_main_size - main_gap * (item_count as i32 - 1)); // https://drafts.csswg.org/css-flexbox/#algo-cross-item let mut item_layout_results = self @@ -873,7 +898,6 @@ impl FlexLine<'_> { // Determine the used cross size of each flex item // https://drafts.csswg.org/css-flexbox/#algo-stretch - let item_count = self.items.len(); let mut shared_alignment_baseline = None; let mut item_used_cross_sizes = Vec::with_capacity(item_count); let mut item_cross_margins = Vec::with_capacity(item_count); @@ -999,8 +1023,7 @@ impl FlexLine<'_> { _ => Au::zero(), }; - // TODO: Implement gap property - let item_main_interval = /*gap + */ match resolved_justify_content { + let item_main_interval = match resolved_justify_content { AlignFlags::START => Au::zero(), AlignFlags::FLEX_START => Au::zero(), AlignFlags::END => Au::zero(), @@ -1014,6 +1037,7 @@ impl FlexLine<'_> { // TODO: Implement all alignments. Note: not all alignment values are valid for content distribution _ => Au::zero(), }; + let item_main_interval = item_main_interval + main_gap; let mut all_baselines = Baselines::default(); let mut main_position_cursor = main_start_position; diff --git a/tests/wpt/meta/css/css-flexbox/alignment/flex-align-baseline-flex-003.html.ini b/tests/wpt/meta/css/css-flexbox/alignment/flex-align-baseline-flex-003.html.ini index 6ba49f2afb7..bf9fc23d072 100644 --- a/tests/wpt/meta/css/css-flexbox/alignment/flex-align-baseline-flex-003.html.ini +++ b/tests/wpt/meta/css/css-flexbox/alignment/flex-align-baseline-flex-003.html.ini @@ -5,12 +5,6 @@ [.target > * 7] expected: FAIL - [.target > * 9] - expected: FAIL - - [.target > * 11] - expected: FAIL - [.target > * 13] expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/flexbox-column-row-gap-003.html.ini b/tests/wpt/meta/css/css-flexbox/flexbox-column-row-gap-003.html.ini deleted file mode 100644 index 1efedb0d6eb..00000000000 --- a/tests/wpt/meta/css/css-flexbox/flexbox-column-row-gap-003.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[flexbox-column-row-gap-003.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/flexbox-gap-position-absolute.html.ini b/tests/wpt/meta/css/css-flexbox/flexbox-gap-position-absolute.html.ini new file mode 100644 index 00000000000..0f12b4d1a2a --- /dev/null +++ b/tests/wpt/meta/css/css-flexbox/flexbox-gap-position-absolute.html.ini @@ -0,0 +1,2 @@ +[flexbox-gap-position-absolute.html] + expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/gap-001-lr.html.ini b/tests/wpt/meta/css/css-flexbox/gap-001-lr.html.ini deleted file mode 100644 index a2a3c119b87..00000000000 --- a/tests/wpt/meta/css/css-flexbox/gap-001-lr.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[gap-001-lr.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/gap-001-ltr.html.ini b/tests/wpt/meta/css/css-flexbox/gap-001-ltr.html.ini deleted file mode 100644 index 374de8b3559..00000000000 --- a/tests/wpt/meta/css/css-flexbox/gap-001-ltr.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[gap-001-ltr.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/gap-001-rl.html.ini b/tests/wpt/meta/css/css-flexbox/gap-001-rl.html.ini deleted file mode 100644 index 10e5eff6d0b..00000000000 --- a/tests/wpt/meta/css/css-flexbox/gap-001-rl.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[gap-001-rl.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/gap-001-rtl.html.ini b/tests/wpt/meta/css/css-flexbox/gap-001-rtl.html.ini deleted file mode 100644 index 9251a8bbc6d..00000000000 --- a/tests/wpt/meta/css/css-flexbox/gap-001-rtl.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[gap-001-rtl.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/gap-004-lr.html.ini b/tests/wpt/meta/css/css-flexbox/gap-004-lr.html.ini deleted file mode 100644 index 096d80a2836..00000000000 --- a/tests/wpt/meta/css/css-flexbox/gap-004-lr.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[gap-004-lr.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/gap-004-ltr.html.ini b/tests/wpt/meta/css/css-flexbox/gap-004-ltr.html.ini deleted file mode 100644 index bb84397e7c2..00000000000 --- a/tests/wpt/meta/css/css-flexbox/gap-004-ltr.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[gap-004-ltr.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/gap-004-rl.html.ini b/tests/wpt/meta/css/css-flexbox/gap-004-rl.html.ini deleted file mode 100644 index 6f9f4f44354..00000000000 --- a/tests/wpt/meta/css/css-flexbox/gap-004-rl.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[gap-004-rl.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/gap-004-rtl.html.ini b/tests/wpt/meta/css/css-flexbox/gap-004-rtl.html.ini deleted file mode 100644 index ab6594b3895..00000000000 --- a/tests/wpt/meta/css/css-flexbox/gap-004-rtl.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[gap-004-rtl.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/gap-011.html.ini b/tests/wpt/meta/css/css-flexbox/gap-011.html.ini deleted file mode 100644 index 20e1b790822..00000000000 --- a/tests/wpt/meta/css/css-flexbox/gap-011.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[gap-011.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/gap-013.html.ini b/tests/wpt/meta/css/css-flexbox/gap-013.html.ini deleted file mode 100644 index 856975d6f05..00000000000 --- a/tests/wpt/meta/css/css-flexbox/gap-013.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[gap-013.html] - expected: FAIL