mirror of
https://github.com/servo/servo.git
synced 2025-08-07 06:25:32 +01:00
layout_2020: Implement automatic minimum size of flex items
Implement the algorithm described in https://drafts.csswg.org/css-flexbox/#min-size-auto.
This commit is contained in:
parent
4e1d3a801f
commit
4b73436684
3 changed files with 73 additions and 9 deletions
|
@ -444,7 +444,77 @@ impl<'a> FlexItem<'a> {
|
||||||
let max_size = box_style.content_max_box_size(containing_block, &pbm);
|
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 = 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 margin_auto_is_zero = pbm.margin.auto_is(Length::zero);
|
||||||
|
|
||||||
let content_box_size = flex_context.vec2_to_flex_relative(content_box_size);
|
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
|
/// https://drafts.csswg.org/css-flexbox/#algo-main-item
|
||||||
fn flex_base_size(
|
fn flex_base_size(
|
||||||
flex_context: &FlexContext,
|
flex_context: &FlexContext,
|
||||||
|
|
|
@ -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 {
|
match self {
|
||||||
Self::NonReplaced(inner) => inner
|
Self::NonReplaced(inner) => inner
|
||||||
.contents
|
.contents
|
||||||
|
|
|
@ -201,7 +201,7 @@ impl ReplacedContent {
|
||||||
Vec2::from_physical_size(&intrinsic_size, style.writing_mode)
|
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,
|
&self,
|
||||||
style: &ComputedValues,
|
style: &ComputedValues,
|
||||||
) -> Option<CSSFloat> {
|
) -> Option<CSSFloat> {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue