summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibWeb
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2022-06-21 21:06:19 +0200
committerAndreas Kling <kling@serenityos.org>2022-06-21 21:06:19 +0200
commit99e96f951fbe5db87ba0f8fcfeaab3ef942bc289 (patch)
treef6b4bc61f27f15eea15fa7b9971dfee0ab3a14ed /Userland/Libraries/LibWeb
parent967b257518cc4ac165a558862b51a536ac3df4af (diff)
downloadserenity-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.cpp53
-rw-r--r--Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h5
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);