LibWeb: Implement (some of) "automatic minimum size" for flex items

This commit is contained in:
Andreas Kling 2022-06-21 21:06:19 +02:00
parent 967b257518
commit 99e96f951f
Notes: sideshowbarker 2024-07-17 10:02:59 +09:00
2 changed files with 53 additions and 5 deletions
Userland/Libraries/LibWeb/Layout

View file

@ -621,14 +621,59 @@ void FlexFormattingContext::determine_flex_base_size_and_hypothetical_main_size(
}();
// The hypothetical main size is the items flex base size clamped according to its used min and max main sizes (and flooring the content box size at zero).
auto clamp_min = has_main_min_size(child_box) ? specified_main_min_size(child_box) : determine_min_main_size_of_child(child_box);
auto clamp_min = has_main_min_size(child_box) ? specified_main_min_size(child_box) : automatic_minimum_size(flex_item);
auto clamp_max = has_main_max_size(child_box) ? specified_main_max_size(child_box) : NumericLimits<float>::max();
flex_item.hypothetical_main_size = css_clamp(flex_item.flex_base_size, clamp_min, clamp_max);
}
float FlexFormattingContext::determine_min_main_size_of_child(Box const& box)
// https://drafts.csswg.org/css-flexbox-1/#min-size-auto
float FlexFormattingContext::automatic_minimum_size(FlexItem const& item) const
{
return is_row_layout() ? calculate_min_and_max_content_width(box).min_content_size : calculate_min_and_max_content_height(box).min_content_size;
// FIXME: Deal with scroll containers.
return content_based_minimum_size(item);
}
// https://drafts.csswg.org/css-flexbox-1/#specified-size-suggestion
Optional<float> FlexFormattingContext::specified_size_suggestion(FlexItem const& item) const
{
// If the items preferred main size is definite and not automatic,
// then the specified size suggestion is that size. It is otherwise undefined.
if (has_definite_main_size(item.box))
return specified_main_size(item.box);
return {};
}
// https://drafts.csswg.org/css-flexbox-1/#content-size-suggestion
float FlexFormattingContext::content_size_suggestion(FlexItem const& item) const
{
// FIXME: Apply clamps
if (is_row_layout())
return calculate_min_and_max_content_width(item.box).min_content_size;
return calculate_min_and_max_content_height(item.box).min_content_size;
}
// https://drafts.csswg.org/css-flexbox-1/#content-based-minimum-size
float FlexFormattingContext::content_based_minimum_size(FlexItem const& item) const
{
auto unclamped_size = [&] {
// The content-based minimum size of a flex item is the smaller of its specified size suggestion
// and its content size suggestion if its specified size suggestion exists;
if (auto specified_size_suggestion = this->specified_size_suggestion(item); specified_size_suggestion.has_value()) {
return min(specified_size_suggestion.value(), content_size_suggestion(item));
}
// FIXME: otherwise, the smaller of its transferred size suggestion and its content size suggestion
// if the element is replaced and its transferred size suggestion exists;
// otherwise its content size suggestion.
return content_size_suggestion(item);
}();
// In all cases, the size is clamped by the maximum main size if its definite.
if (has_main_max_size(item.box)) {
return min(unclamped_size, specified_main_max_size(item.box));
}
return unclamped_size;
}
// https://www.w3.org/TR/css-flexbox-1/#algo-main-container
@ -832,7 +877,7 @@ void FlexFormattingContext::resolve_flexible_lengths()
for_each_unfrozen_item([&](FlexItem* item) {
auto min_main = has_main_min_size(item->box)
? specified_main_min_size(item->box)
: determine_min_main_size_of_child(item->box);
: automatic_minimum_size(*item);
auto max_main = has_main_max_size(item->box)
? specified_main_max_size(item->box)
: NumericLimits<float>::max();

View file

@ -79,7 +79,10 @@ private:
bool has_main_max_size(Box const&) const;
bool has_cross_max_size(Box const&) const;
float sum_of_margin_padding_border_in_main_axis(Box const&) const;
float determine_min_main_size_of_child(Box const& box);
float automatic_minimum_size(FlexItem const&) const;
float content_based_minimum_size(FlexItem const&) const;
Optional<float> specified_size_suggestion(FlexItem const&) const;
float content_size_suggestion(FlexItem const&) const;
void set_main_size(Box const&, float size);
void set_cross_size(Box const&, float size);