diff options
author | Andreas Kling <kling@serenityos.org> | 2022-06-21 21:06:19 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-06-21 21:06:19 +0200 |
commit | 99e96f951fbe5db87ba0f8fcfeaab3ef942bc289 (patch) | |
tree | f6b4bc61f27f15eea15fa7b9971dfee0ab3a14ed /Userland/Libraries/LibWeb | |
parent | 967b257518cc4ac165a558862b51a536ac3df4af (diff) | |
download | serenity-99e96f951fbe5db87ba0f8fcfeaab3ef942bc289.zip |
LibWeb: Implement (some of) "automatic minimum size" for flex items
Diffstat (limited to 'Userland/Libraries/LibWeb')
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp | 53 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h | 5 |
2 files changed, 53 insertions, 5 deletions
diff --git a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp index b2c0b6f2ce..f9726b4dc8 100644 --- a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp @@ -621,14 +621,59 @@ void FlexFormattingContext::determine_flex_base_size_and_hypothetical_main_size( }(); // The hypothetical main size is the item’s 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 item’s 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 it’s 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(); diff --git a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h index 4ce825659c..5a7f87b153 100644 --- a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h +++ b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h @@ -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); |