diff options
author | bors-servo <infra@servo.org> | 2023-06-03 10:43:48 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-03 10:43:48 +0200 |
commit | 0f8824da6d1ec41ac8e779b9238501fddda50e20 (patch) | |
tree | 66741460e0b7952cfcae2a720d2b305c7e60a612 /components/layout_2020/flexbox/layout.rs | |
parent | 0dd27d487fa6ddbfd517fbc7fa6c8253eaccbd04 (diff) | |
parent | 7368673d2e4d029ff5b1863a97f2eeb8533df446 (diff) | |
download | servo-0f8824da6d1ec41ac8e779b9238501fddda50e20.tar.gz servo-0f8824da6d1ec41ac8e779b9238501fddda50e20.zip |
Auto merge of #29755 - stshine:automatic-min-size, r=Loirooriol
layout_2020: Implement automatic minimum size of flex items
Implement the algorithm described in
https://drafts.csswg.org/css-flexbox/#min-size-auto.
<!-- Please describe your changes on the following line: -->
---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
<!-- Either: -->
- [x] There are tests for these changes OR
<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->
<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
Diffstat (limited to 'components/layout_2020/flexbox/layout.rs')
-rw-r--r-- | components/layout_2020/flexbox/layout.rs | 78 |
1 files changed, 71 insertions, 7 deletions
diff --git a/components/layout_2020/flexbox/layout.rs b/components/layout_2020/flexbox/layout.rs index 1c8001d9b95..b0744e08aa3 100644 --- a/components/layout_2020/flexbox/layout.rs +++ b/components/layout_2020/flexbox/layout.rs @@ -444,7 +444,77 @@ impl<'a> FlexItem<'a> { let max_size = box_style.content_max_box_size(containing_block, &pbm); let min_size = box_style.content_min_box_size(containing_block, &pbm); - let min_size = min_size.auto_is(|| automatic_min_size(box_)); + // https://drafts.csswg.org/css-flexbox/#min-size-auto + let automatic_min_size = || { + // FIXME(stshine): Consider more situations when auto min size is not needed. + if box_style.get_box().overflow_x.is_scrollable() { + return Length::zero(); + } + + if cross_axis_is_item_block_axis { + let specified_size_suggestion = content_box_size.inline; + + let transferred_size_suggestion = match box_ { + IndependentFormattingContext::NonReplaced(_) => None, + IndependentFormattingContext::Replaced(ref bfc) => { + match ( + bfc.contents + .inline_size_over_block_size_intrinsic_ratio(box_style), + content_box_size.block, + ) { + (Some(ratio), LengthOrAuto::LengthPercentage(block_size)) => { + let block_size = block_size.clamp_between_extremums( + min_size.block.auto_is(|| Length::zero()), + max_size.block, + ); + Some(block_size * ratio) + }, + _ => None, + } + }, + }; + + let inline_content_size = box_ + .inline_content_sizes(&flex_context.layout_context) + .min_content; + let content_size_suggestion = match box_ { + IndependentFormattingContext::NonReplaced(_) => inline_content_size, + IndependentFormattingContext::Replaced(ref replaced) => { + if let Some(ratio) = replaced + .contents + .inline_size_over_block_size_intrinsic_ratio(box_style) + { + inline_content_size.clamp_between_extremums( + min_size.block.auto_is(|| Length::zero()) * ratio, + max_size.block.map(|l| l * ratio), + ) + } else { + inline_content_size + } + }, + }; + + let result = match specified_size_suggestion { + LengthOrAuto::LengthPercentage(l) => l.min(content_size_suggestion), + LengthOrAuto::Auto => { + if let Some(l) = transferred_size_suggestion { + l.min(content_size_suggestion) + } else { + content_size_suggestion + } + }, + }; + result.clamp_below_max(max_size.inline) + } else { + // FIXME(stshine): Implement this when main axis is item's block axis. + Length::zero() + } + }; + + let min_size = Vec2 { + inline: min_size.inline.auto_is(automatic_min_size), + block: min_size.block.auto_is(|| Length::zero()), + }; let margin_auto_is_zero = pbm.margin.auto_is(Length::zero); let content_box_size = flex_context.vec2_to_flex_relative(content_box_size); @@ -488,12 +558,6 @@ impl<'a> FlexItem<'a> { } } -/// https://drafts.csswg.org/css-flexbox/#min-size-auto -fn automatic_min_size(_box: &IndependentFormattingContext) -> Length { - // FIMXE: implement the actual algorithm - Length::zero() // Give an incorrect value rather than panicking -} - /// https://drafts.csswg.org/css-flexbox/#algo-main-item fn flex_base_size( flex_context: &FlexContext, |