diff --git a/Userland/Libraries/LibWeb/CSS/GridTrackSize.cpp b/Userland/Libraries/LibWeb/CSS/GridTrackSize.cpp index 5d9669a8bc..0097d1e3d6 100644 --- a/Userland/Libraries/LibWeb/CSS/GridTrackSize.cpp +++ b/Userland/Libraries/LibWeb/CSS/GridTrackSize.cpp @@ -63,8 +63,24 @@ MetaGridTrackSize::MetaGridTrackSize(GridTrackSize grid_track_size) { } +MetaGridTrackSize::MetaGridTrackSize(GridTrackSize min_grid_track_size, GridTrackSize max_grid_track_size) + : m_min_grid_track_size(min_grid_track_size) + , m_max_grid_track_size(max_grid_track_size) + , m_is_min_max(true) +{ +} + String MetaGridTrackSize::to_string() const { + if (m_is_min_max) { + StringBuilder builder; + builder.append("minmax("sv); + builder.appendff("{}", m_min_grid_track_size.to_string()); + builder.append(", "sv); + builder.appendff("{}", m_max_grid_track_size.to_string()); + builder.append(")"sv); + return builder.to_string(); + } return String::formatted("{}", m_min_grid_track_size.to_string()); } diff --git a/Userland/Libraries/LibWeb/CSS/GridTrackSize.h b/Userland/Libraries/LibWeb/CSS/GridTrackSize.h index c813571353..a630ceab0c 100644 --- a/Userland/Libraries/LibWeb/CSS/GridTrackSize.h +++ b/Userland/Libraries/LibWeb/CSS/GridTrackSize.h @@ -18,7 +18,6 @@ public: Length, Percentage, FlexibleLength, - // TODO: MinMax // TODO: Max-Content }; @@ -68,6 +67,9 @@ private: class MetaGridTrackSize { public: MetaGridTrackSize(CSS::GridTrackSize); + MetaGridTrackSize(CSS::GridTrackSize min_grid_track_size, CSS::GridTrackSize max_grid_track_size); + + bool is_min_max() const { return m_is_min_max; } GridTrackSize grid_track_size() const& { return m_min_grid_track_size; } GridTrackSize min_grid_track_size() const& { return m_min_grid_track_size; } @@ -83,6 +85,7 @@ public: private: GridTrackSize m_min_grid_track_size; GridTrackSize m_max_grid_track_size; + bool m_is_min_max { false }; }; class ExplicitTrackSizing { diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 67f7266e67..f43ac3eeee 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -5431,6 +5431,41 @@ RefPtr Parser::parse_grid_track_sizes(Vector const& return {}; }; + auto parse_min_max = [&](Vector const& component_values) -> Optional { + // https://www.w3.org/TR/css-grid-2/#valdef-grid-template-columns-minmax + // 'minmax(min, max)' + // Defines a size range greater than or equal to min and less than or equal to max. If the max is + // less than the min, then the max will be floored by the min (essentially yielding minmax(min, + // min)). As a maximum, a value sets the track’s flex factor; it is invalid as a minimum. + auto function_tokens = TokenStream(component_values); + auto comma_separated_list = parse_a_comma_separated_list_of_component_values(function_tokens); + if (comma_separated_list.size() != 2) + return MetaGridTrackSize(GridTrackSize::make_auto()); + + TokenStream part_one_tokens { comma_separated_list[0] }; + part_one_tokens.skip_whitespace(); + if (!part_one_tokens.has_next_token()) + return MetaGridTrackSize(GridTrackSize::make_auto()); + auto current_token = part_one_tokens.next_token(); + auto min_grid_track_size = parse_grid_track_size(current_token); + + TokenStream part_two_tokens { comma_separated_list[1] }; + part_two_tokens.skip_whitespace(); + if (!part_two_tokens.has_next_token()) + return MetaGridTrackSize(GridTrackSize::make_auto()); + current_token = part_two_tokens.next_token(); + auto max_grid_track_size = parse_grid_track_size(current_token); + + if (min_grid_track_size.has_value() && max_grid_track_size.has_value()) { + // https://www.w3.org/TR/css-grid-2/#valdef-grid-template-columns-minmax + // As a maximum, a value sets the track’s flex factor; it is invalid as a minimum. + if (min_grid_track_size.value().is_flexible_length()) + return {}; + return MetaGridTrackSize(min_grid_track_size.value(), max_grid_track_size.value()); + } + return MetaGridTrackSize(GridTrackSize::make_auto(), GridTrackSize::make_auto()); + }; + Vector params; for (auto const& component_value : component_values) { if (component_value.is_function()) { @@ -5476,8 +5511,14 @@ RefPtr Parser::parse_grid_track_sizes(Vector const& // The repeat() notation can’t be nested. if (current_component_value.function().name().equals_ignoring_case("repeat"sv)) return GridTrackSizeStyleValue::create({}); - - // FIXME: Implement MinMax, etc. + if (current_component_value.function().name().equals_ignoring_case("minmax"sv)) { + auto maybe_min_max_value = parse_min_max(current_component_value.function().values()); + if (maybe_min_max_value.has_value()) + repeat_params.append(maybe_min_max_value.value()); + else + return GridTrackSizeStyleValue::create({}); + } + // FIXME: Implement other function values possible within repeat } else if (current_component_value.is_block()) { // FIXME: Implement things like grid-template-columns: repeat(1, [col-start] 8); } else { @@ -5518,8 +5559,12 @@ RefPtr Parser::parse_grid_track_sizes(Vector const& if (is_auto_fit) return GridTrackSizeStyleValue::create(CSS::ExplicitTrackSizing(repeat_params, CSS::ExplicitTrackSizing::Type::AutoFit)); return GridTrackSizeStyleValue::create(CSS::ExplicitTrackSizing(repeat_params, repeat_count)); - } else { - // FIXME: Implement MinMax, etc. + } else if (function_token.name().equals_ignoring_case("minmax"sv)) { + auto maybe_min_max_value = parse_min_max(function_token.values()); + if (maybe_min_max_value.has_value()) + params.append(maybe_min_max_value.value()); + else + return GridTrackSizeStyleValue::create({}); } continue; }