aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout_2020/flexbox/layout.rs
diff options
context:
space:
mode:
authorbors-servo <infra@servo.org>2023-06-03 10:43:48 +0200
committerGitHub <noreply@github.com>2023-06-03 10:43:48 +0200
commit0f8824da6d1ec41ac8e779b9238501fddda50e20 (patch)
tree66741460e0b7952cfcae2a720d2b305c7e60a612 /components/layout_2020/flexbox/layout.rs
parent0dd27d487fa6ddbfd517fbc7fa6c8253eaccbd04 (diff)
parent7368673d2e4d029ff5b1863a97f2eeb8533df446 (diff)
downloadservo-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.rs78
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,