From ae40c7ed954a881e4b4559e2ed9e6abbee7f0c2a Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Thu, 4 Sep 2025 11:38:27 +0100 Subject: [PATCH] LibWeb/CSS: Use Size in GridSize Reduces a bunch of duplicate logic here for holding different sizing functions, and also removes a user of `auto` Length. --- Libraries/LibWeb/CSS/GridTrackSize.cpp | 123 ++++++++++-------- Libraries/LibWeb/CSS/GridTrackSize.h | 35 ++--- Libraries/LibWeb/CSS/Parser/Parser.h | 2 +- Libraries/LibWeb/CSS/Parser/ValueParsing.cpp | 18 +-- .../LibWeb/Layout/GridFormattingContext.cpp | 16 +-- 5 files changed, 92 insertions(+), 102 deletions(-) diff --git a/Libraries/LibWeb/CSS/GridTrackSize.cpp b/Libraries/LibWeb/CSS/GridTrackSize.cpp index 6a117f33e38..097c77b6ed8 100644 --- a/Libraries/LibWeb/CSS/GridTrackSize.cpp +++ b/Libraries/LibWeb/CSS/GridTrackSize.cpp @@ -11,41 +11,26 @@ namespace Web::CSS { -GridSize::GridSize(Type type, LengthPercentage length_percentage) - : m_value(move(length_percentage)) -{ - VERIFY(type == Type::FitContent); - m_type = type; -} - -GridSize::GridSize(LengthPercentage length_percentage) - : m_type(Type::LengthPercentage) - , m_value(move(length_percentage)) +GridSize::GridSize(Size size) + : m_value(move(size)) { } GridSize::GridSize(Flex flex_factor) - : m_type(Type::FlexibleLength) - , m_value(move(flex_factor)) + : m_value(move(flex_factor)) { } -GridSize::GridSize(Type type) - : m_value { Empty() } -{ - VERIFY(type == Type::MinContent || type == Type::MaxContent); - m_type = type; -} - GridSize::~GridSize() = default; bool GridSize::is_auto(Layout::AvailableSize const& available_size) const { - if (m_type == Type::LengthPercentage) { - auto& length_percentage = m_value.get(); - if (length_percentage.contains_percentage()) + if (auto const* size = m_value.get_pointer()) { + if (size->is_auto()) + return true; + if (size->contains_percentage()) return !available_size.is_definite(); - return length_percentage.is_auto(); + return false; } return false; @@ -53,59 +38,83 @@ bool GridSize::is_auto(Layout::AvailableSize const& available_size) const bool GridSize::is_fixed(Layout::AvailableSize const& available_size) const { - if (m_type == Type::LengthPercentage) { - auto& length_percentage = m_value.get(); - if (length_percentage.contains_percentage()) + if (auto const* size = m_value.get_pointer()) { + if (!size->is_length_percentage()) + return false; + if (size->contains_percentage()) return available_size.is_definite(); - return !length_percentage.is_auto(); + return true; } return false; } +bool GridSize::is_flexible_length() const +{ + return m_value.has(); +} + +bool GridSize::is_fit_content() const +{ + if (auto const* size = m_value.get_pointer()) + return size->is_fit_content(); + + return false; +} + +bool GridSize::is_max_content() const +{ + if (auto const* size = m_value.get_pointer()) + return size->is_max_content(); + + return false; +} + +bool GridSize::is_min_content() const +{ + if (auto const* size = m_value.get_pointer()) + return size->is_min_content(); + + return false; +} + bool GridSize::is_intrinsic(Layout::AvailableSize const& available_size) const { - return is_auto(available_size) || is_max_content() || is_min_content() || is_fit_content(); + return m_value.visit( + [&available_size](Size const& size) { + return size.is_auto() + || size.is_max_content() + || size.is_min_content() + || size.is_fit_content() + || (size.contains_percentage() && !available_size.is_definite()); + }, + [](Flex const&) { + return false; + }); +} + +bool GridSize::is_definite() const +{ + return m_value.visit( + [](Size const& size) { + return (size.is_length() && !size.length().is_auto()) || size.is_percentage() || size.is_calculated(); + }, + [](Flex const&) { return false; }); } GridSize GridSize::make_auto() { - return GridSize(CSS::Length::make_auto()); -} - -Size GridSize::css_size() const -{ - VERIFY(m_type == Type::LengthPercentage || m_type == Type::FitContent); - auto& length_percentage = m_value.get(); - if (length_percentage.is_auto()) - return CSS::Size::make_auto(); - if (length_percentage.is_length()) - return CSS::Size::make_length(length_percentage.length()); - if (length_percentage.is_calculated()) - return CSS::Size::make_calculated(length_percentage.calculated()); - return CSS::Size::make_percentage(length_percentage.percentage()); + return GridSize(Size::make_auto()); } String GridSize::to_string(SerializationMode mode) const { - switch (m_type) { - case Type::LengthPercentage: - return m_value.get().to_string(mode); - case Type::FitContent: - return MUST(String::formatted("fit-content({})", m_value.get().to_string(mode))); - case Type::FlexibleLength: - return m_value.get().to_string(); - case Type::MaxContent: - return "max-content"_string; - case Type::MinContent: - return "min-content"_string; - } - VERIFY_NOT_REACHED(); + return m_value.visit([mode](auto const& it) { return it.to_string(mode); }); } GridMinMax::GridMinMax(GridSize min_grid_size, GridSize max_grid_size) - : m_min_grid_size(min_grid_size) - , m_max_grid_size(max_grid_size) + : m_min_grid_size(move(min_grid_size)) + , m_max_grid_size(move(max_grid_size)) { } diff --git a/Libraries/LibWeb/CSS/GridTrackSize.h b/Libraries/LibWeb/CSS/GridTrackSize.h index 4b69cdb0d03..17bbe40db32 100644 --- a/Libraries/LibWeb/CSS/GridTrackSize.h +++ b/Libraries/LibWeb/CSS/GridTrackSize.h @@ -10,57 +10,40 @@ #include #include #include +#include #include namespace Web::CSS { class GridSize { public: - enum class Type { - LengthPercentage, - FlexibleLength, - FitContent, - MaxContent, - MinContent, - }; - - GridSize(Type, LengthPercentage); - GridSize(LengthPercentage); + GridSize(Size); GridSize(Flex); - GridSize(Type); ~GridSize(); static GridSize make_auto(); - Type type() const { return m_type; } - bool is_auto(Layout::AvailableSize const&) const; bool is_fixed(Layout::AvailableSize const&) const; - bool is_flexible_length() const { return m_type == Type::FlexibleLength; } - bool is_fit_content() const { return m_type == Type::FitContent; } - bool is_max_content() const { return m_type == Type::MaxContent; } - bool is_min_content() const { return m_type == Type::MinContent; } + bool is_flexible_length() const; + bool is_fit_content() const; + bool is_max_content() const; + bool is_min_content() const; - LengthPercentage const& length_percentage() const { return m_value.get(); } + Size css_size() const { return m_value.get(); } double flex_factor() const { return m_value.get().to_fr(); } // https://www.w3.org/TR/css-grid-2/#layout-algorithm // An intrinsic sizing function (min-content, max-content, auto, fit-content()). bool is_intrinsic(Layout::AvailableSize const&) const; - bool is_definite() const - { - return type() == Type::LengthPercentage && !length_percentage().is_auto(); - } - - Size css_size() const; + bool is_definite() const; String to_string(SerializationMode) const; bool operator==(GridSize const& other) const = default; private: - Type m_type; - Variant m_value; + Variant m_value; }; class GridMinMax { diff --git a/Libraries/LibWeb/CSS/Parser/Parser.h b/Libraries/LibWeb/CSS/Parser/Parser.h index 42c285e16b1..290bfad4011 100644 --- a/Libraries/LibWeb/CSS/Parser/Parser.h +++ b/Libraries/LibWeb/CSS/Parser/Parser.h @@ -298,7 +298,7 @@ private: Optional parse_grid_track_breadth(TokenStream&); Optional parse_grid_inflexible_breadth(TokenStream&); - Optional parse_grid_fixed_breadth(TokenStream&); + Optional parse_grid_fixed_breadth(TokenStream&); Optional parse_grid_line_names(TokenStream&); diff --git a/Libraries/LibWeb/CSS/Parser/ValueParsing.cpp b/Libraries/LibWeb/CSS/Parser/ValueParsing.cpp index d5299fd8441..eb020128bdf 100644 --- a/Libraries/LibWeb/CSS/Parser/ValueParsing.cpp +++ b/Libraries/LibWeb/CSS/Parser/ValueParsing.cpp @@ -3582,7 +3582,7 @@ Optional Parser::parse_grid_inflexible_breadth(TokenStream = | min-content | max-content | auto if (auto fixed_breadth = parse_grid_fixed_breadth(tokens); fixed_breadth.has_value()) - return fixed_breadth; + return GridSize { Size::make_length_percentage(fixed_breadth.value()) }; auto transaction = tokens.begin_transaction(); if (!tokens.has_next_token()) @@ -3591,11 +3591,11 @@ Optional Parser::parse_grid_inflexible_breadth(TokenStream Parser::parse_grid_inflexible_breadth(TokenStream Parser::parse_grid_fixed_breadth(TokenStream& tokens) +Optional Parser::parse_grid_fixed_breadth(TokenStream& tokens) { // = @@ -3619,7 +3619,7 @@ Optional Parser::parse_grid_fixed_breadth(TokenStream& if (length_percentage->is_percentage() && length_percentage->percentage().value() < 0) return {}; transaction.commit(); - return GridSize(length_percentage.release_value()); + return length_percentage.release_value(); } // https://www.w3.org/TR/css-grid-2/#typedef-line-names @@ -3871,7 +3871,7 @@ Optional Parser::parse_grid_track_size(TokenStreamlength_percentage())); + return ExplicitGridTrack(GridSize(Size::make_fit_content(maybe_length_percentage.release_value()))); } } @@ -3895,14 +3895,14 @@ Optional Parser::parse_grid_fixed_size(TokenStream Parser::parse_grid_fixed_size(TokenStreamwidth.to_px_or_zero()); + sum_of_max_sizing_functions += track.max_track_sizing_function.css_size().to_px(item.box, m_available_space->width.to_px_or_zero()); } if (spans_only_tracks_with_limited_max_track_sizing_function) { result = min(result, sum_of_max_sizing_functions);