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. -->
This commit is contained in:
bors-servo 2023-06-03 10:43:48 +02:00 committed by GitHub
commit 0f8824da6d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 78 additions and 63 deletions

View file

@ -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,

View file

@ -138,7 +138,7 @@ impl IndependentFormattingContext {
}
}
pub fn inline_content_sizes(&mut self, layout_context: &LayoutContext) -> ContentSizes {
pub fn inline_content_sizes(&self, layout_context: &LayoutContext) -> ContentSizes {
match self {
Self::NonReplaced(inner) => inner
.contents

View file

@ -201,7 +201,7 @@ impl ReplacedContent {
Vec2::from_physical_size(&intrinsic_size, style.writing_mode)
}
fn inline_size_over_block_size_intrinsic_ratio(
pub fn inline_size_over_block_size_intrinsic_ratio(
&self,
style: &ComputedValues,
) -> Option<CSSFloat> {

View file

@ -22,6 +22,3 @@
[.flexbox 12]
expected: FAIL
[.flexbox 19]
expected: FAIL

View file

@ -1,2 +0,0 @@
[flex-minimum-height-flex-items-024.html]
expected: FAIL

View file

@ -1,15 +1,6 @@
[flex-minimum-size-001.html]
[.flexbox, .inline-flexbox 1]
expected: FAIL
[.flexbox, .inline-flexbox 6]
expected: FAIL
[.flexbox, .inline-flexbox 5]
expected: FAIL
[.flexbox, .inline-flexbox 4]
expected: FAIL
[.flexbox, .inline-flexbox 2]
expected: FAIL

View file

@ -1,2 +0,0 @@
[flex-minimum-width-flex-items-001.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[flex-minimum-width-flex-items-002.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[flex-minimum-width-flex-items-003.xht]
expected: FAIL

View file

@ -0,0 +1,2 @@
[flex-wrap-003.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[flex-wrap-004.html]
expected: FAIL

View file

@ -1,2 +1,2 @@
[flexbox-align-self-stretch-vert-001.html]
expected: FAIL
expected: TIMEOUT

View file

@ -1,2 +0,0 @@
[flexbox-min-width-auto-001.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[flexbox-min-width-auto-003.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[flexbox-min-width-auto-004.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[flexbox_flex-0-0-0-unitless.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[flexbox_flex-0-0-0.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[flexbox_flex-0-0.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[flexbox_flex-0-1-0-unitless.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[flexbox_flex-0-1-0.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[flexbox_flex-0-1.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[flexbox_flex-0-N-0-unitless.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[flexbox_flex-0-N-0.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[flexbox_flex-0-N.html]
expected: FAIL

View file

@ -1,4 +0,0 @@
[radiobutton-min-size.html]
[two radio button widths are identical]
expected: FAIL

View file

@ -1,3 +0,0 @@
[relayout-image-load.html]
[#test 1]
expected: FAIL

View file

@ -1,2 +0,0 @@
[table-as-item-stretch-cross-size-4.html]
expected: FAIL