From af602b2555b254d8764bcf5ce5b89ee432a6f7d0 Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Mon, 16 Jun 2025 22:27:17 +0200 Subject: [PATCH] LibWeb: Align CSS Grid properties parsing with the specification Reimplements `grid`, `grid-template`, `grid-template-rows`, and `grid-template-columns` in a way that uses a separate function for each grammar rule defined in the specification. This change results in many additional passing tests from the already imported WPT suite. Most of the remaining test failures are related to incorrect serialization of grid properties. --- Libraries/LibWeb/CSS/GridTrackSize.cpp | 39 +- Libraries/LibWeb/CSS/GridTrackSize.h | 46 +- Libraries/LibWeb/CSS/Parser/Parser.h | 36 +- .../LibWeb/CSS/Parser/PropertyParsing.cpp | 313 ++++++--- Libraries/LibWeb/CSS/Parser/ValueParsing.cpp | 615 ++++++++++++------ Libraries/LibWeb/Forward.h | 3 +- .../LibWeb/Layout/GridFormattingContext.cpp | 2 +- .../LibWeb/Layout/GridFormattingContext.h | 2 +- .../Text/expected/css/calc-coverage.txt | 8 +- .../parsing/grid-auto-columns-invalid.txt | 25 +- .../parsing/grid-auto-rows-invalid.txt | 23 +- .../grid-columns-rows-get-set-multiple.txt | 8 +- .../parsing/grid-shorthand-invalid.txt | 39 +- .../parsing/grid-shorthand-serialization.txt | 82 +-- .../css-grid/parsing/grid-shorthand-valid.txt | 6 +- .../css/css-grid/parsing/grid-shorthand.txt | 24 +- .../parsing/grid-template-columns-invalid.txt | 31 +- .../parsing/grid-template-columns-valid.txt | 7 +- .../parsing/grid-template-rows-invalid.txt | 31 +- .../parsing/grid-template-rows-valid.txt | 7 +- .../grid-template-shorthand-invalid.txt | 105 ++- .../parsing/grid-template-shorthand-valid.txt | 6 +- .../parsing/grid-template-shorthand.txt | 10 +- 23 files changed, 894 insertions(+), 574 deletions(-) diff --git a/Libraries/LibWeb/CSS/GridTrackSize.cpp b/Libraries/LibWeb/CSS/GridTrackSize.cpp index f58b5670ab4..86fde7f2cec 100644 --- a/Libraries/LibWeb/CSS/GridTrackSize.cpp +++ b/Libraries/LibWeb/CSS/GridTrackSize.cpp @@ -120,16 +120,10 @@ String GridMinMax::to_string() const return MUST(builder.to_string()); } -GridRepeat::GridRepeat(GridTrackSizeList grid_track_size_list, int repeat_count) - : m_type(Type::Default) - , m_grid_track_size_list(grid_track_size_list) - , m_repeat_count(repeat_count) -{ -} - -GridRepeat::GridRepeat(GridTrackSizeList grid_track_size_list, Type type) - : m_type(type) - , m_grid_track_size_list(grid_track_size_list) +GridRepeat::GridRepeat(GridTrackSizeList&& grid_track_size_list, GridRepeatParams const& params) + : m_type(params.type) + , m_grid_track_size_list(move(grid_track_size_list)) + , m_repeat_count(params.count) { } @@ -138,13 +132,13 @@ String GridRepeat::to_string() const StringBuilder builder; builder.append("repeat("sv); switch (m_type) { - case Type::AutoFit: + case GridRepeatType::AutoFit: builder.append("auto-fit"sv); break; - case Type::AutoFill: + case GridRepeatType::AutoFill: builder.append("auto-fill"sv); break; - case Type::Default: + case GridRepeatType::Fixed: builder.appendff("{}", m_repeat_count); break; default: @@ -177,15 +171,6 @@ String GridLineNames::to_string() const return MUST(builder.to_string()); } -GridTrackSizeList::GridTrackSizeList(Vector>&& list) - : m_list(move(list)) -{ -} - -GridTrackSizeList::GridTrackSizeList() -{ -} - GridTrackSizeList GridTrackSizeList::make_none() { return GridTrackSizeList(); @@ -222,4 +207,14 @@ Vector GridTrackSizeList::track_list() const bool GridTrackSizeList::operator==(GridTrackSizeList const& other) const = default; +void GridTrackSizeList::append(GridLineNames&& line_names) +{ + m_list.append(move(line_names)); +} + +void GridTrackSizeList::append(ExplicitGridTrack&& explicit_track) +{ + m_list.append(move(explicit_track)); +} + } diff --git a/Libraries/LibWeb/CSS/GridTrackSize.h b/Libraries/LibWeb/CSS/GridTrackSize.h index 11b3fcd9908..84ecc28b667 100644 --- a/Libraries/LibWeb/CSS/GridTrackSize.h +++ b/Libraries/LibWeb/CSS/GridTrackSize.h @@ -7,6 +7,7 @@ #pragma once +#include #include #include #include @@ -78,7 +79,7 @@ private: }; struct GridLineNames { - Vector names; + Vector names; String to_string() const; bool operator==(GridLineNames const& other) const = default; @@ -86,9 +87,6 @@ struct GridLineNames { class GridTrackSizeList { public: - GridTrackSizeList(Vector>&& list); - GridTrackSizeList(); - static GridTrackSizeList make_none(); Vector track_list() const; @@ -97,38 +95,48 @@ public: String to_string() const; bool operator==(GridTrackSizeList const& other) const; + bool is_empty() const { return m_list.is_empty(); } + + void append(GridLineNames&&); + void append(ExplicitGridTrack&&); + private: Vector> m_list; }; +enum class GridRepeatType { + AutoFit, + AutoFill, + Fixed, +}; + +struct GridRepeatParams { + GridRepeatType type; + size_t count { 0 }; +}; + class GridRepeat { public: - enum class Type { - AutoFit, - AutoFill, - Default, - }; - GridRepeat(GridTrackSizeList, int repeat_count); - GridRepeat(GridTrackSizeList, Type); + GridRepeat(GridTrackSizeList&&, GridRepeatParams const&); - bool is_auto_fill() const { return m_type == Type::AutoFill; } - bool is_auto_fit() const { return m_type == Type::AutoFit; } - bool is_default() const { return m_type == Type::Default; } - int repeat_count() const + bool is_auto_fill() const { return m_type == GridRepeatType::AutoFill; } + bool is_auto_fit() const { return m_type == GridRepeatType::AutoFit; } + bool is_fixed() const { return m_type == GridRepeatType::Fixed; } + size_t repeat_count() const { - VERIFY(is_default()); + VERIFY(is_fixed()); return m_repeat_count; } GridTrackSizeList const& grid_track_size_list() const& { return m_grid_track_size_list; } - Type type() const& { return m_type; } + GridRepeatType type() const& { return m_type; } String to_string() const; bool operator==(GridRepeat const& other) const = default; private: - Type m_type; + GridRepeatType m_type; GridTrackSizeList m_grid_track_size_list; - int m_repeat_count { 0 }; + size_t m_repeat_count { 0 }; }; class ExplicitGridTrack { diff --git a/Libraries/LibWeb/CSS/Parser/Parser.h b/Libraries/LibWeb/CSS/Parser/Parser.h index d1354433537..3e5ebaa6fa5 100644 --- a/Libraries/LibWeb/CSS/Parser/Parser.h +++ b/Libraries/LibWeb/CSS/Parser/Parser.h @@ -282,11 +282,35 @@ private: Optional parse_unicode_range(StringView); Vector parse_unicode_ranges(TokenStream&); RefPtr parse_unicode_range_value(TokenStream&); - Optional parse_grid_size(ComponentValue const&); - Optional parse_grid_fit_content(Vector const&); - Optional parse_min_max(Vector const&); - Optional parse_repeat(Vector const&); - Optional parse_track_sizing_function(ComponentValue const&); + + Optional parse_grid_track_breadth(TokenStream&); + Optional parse_grid_inflexible_breadth(TokenStream&); + Optional parse_grid_fixed_breadth(TokenStream&); + + Optional parse_grid_line_names(TokenStream&); + + Optional parse_grid_track_repeat(TokenStream&); + Optional parse_grid_auto_repeat(TokenStream&); + Optional parse_grid_fixed_repeat(TokenStream&); + + using GridRepeatTypeParser = AK::Function(TokenStream&)>; + using GridTrackParser = AK::Function(TokenStream&)>; + Optional parse_grid_track_repeat_impl(TokenStream&, GridRepeatTypeParser const&, GridTrackParser const&); + + using GridMinMaxParamParser = AK::Function(TokenStream&)>; + Optional parse_grid_minmax(TokenStream&, GridMinMaxParamParser const&, GridMinMaxParamParser const&); + + Optional parse_grid_track_size(TokenStream&); + Optional parse_grid_fixed_size(TokenStream&); + + enum class AllowTrailingLineNamesForEachTrack { + Yes, + No + }; + [[nodiscard]] size_t parse_track_list_impl(TokenStream& tokens, GridTrackSizeList& output, GridTrackParser const& track_parsing_callback, AllowTrailingLineNamesForEachTrack = AllowTrailingLineNamesForEachTrack::No); + GridTrackSizeList parse_grid_track_list(TokenStream&); + GridTrackSizeList parse_grid_auto_track_list(TokenStream&); + GridTrackSizeList parse_explicit_track_list(TokenStream&); Optional parse_url_function(TokenStream&); RefPtr parse_url_value(TokenStream&); @@ -437,7 +461,7 @@ private: RefPtr parse_transition_property_value(TokenStream&); RefPtr parse_translate_value(TokenStream&); RefPtr parse_scale_value(TokenStream&); - RefPtr parse_grid_track_size_list(TokenStream&, bool allow_separate_line_name_blocks = false); + RefPtr parse_grid_track_size_list(TokenStream&); RefPtr parse_grid_auto_track_sizes(TokenStream&); RefPtr parse_grid_auto_flow_value(TokenStream&); RefPtr parse_grid_track_size_list_shorthand_value(PropertyID, TokenStream&); diff --git a/Libraries/LibWeb/CSS/Parser/PropertyParsing.cpp b/Libraries/LibWeb/CSS/Parser/PropertyParsing.cpp index 4370c142b50..268e5b2d4c4 100644 --- a/Libraries/LibWeb/CSS/Parser/PropertyParsing.cpp +++ b/Libraries/LibWeb/CSS/Parser/PropertyParsing.cpp @@ -8,6 +8,7 @@ * Copyright (c) 2024, Tommy van der Vorst * Copyright (c) 2024, Matthew Olsson * Copyright (c) 2024, Glenn Skrzypczak + * Copyright (c) 2025, Aliaksandr Kalenik * * SPDX-License-Identifier: BSD-2-Clause */ @@ -4324,60 +4325,91 @@ RefPtr Parser::parse_grid_track_placement_shorthand_value(P // 7.4. Explicit Grid Shorthand: the grid-template property RefPtr Parser::parse_grid_track_size_list_shorthand_value(PropertyID property_id, TokenStream& tokens) { - // The grid-template property is a shorthand for setting grid-template-columns, grid-template-rows, - // and grid-template-areas in a single declaration. It has several distinct syntax forms: + auto empty_grid_areas = GridTemplateAreaStyleValue::create({}); + auto empty_grid_track_size_list = GridTrackSizeListStyleValue::create({}); + // none - // - Sets all three properties to their initial values (none). - // <'grid-template-rows'> / <'grid-template-columns'> - // - Sets grid-template-rows and grid-template-columns to the specified values, respectively, and sets grid-template-areas to none. - // [ ? ? ? ]+ [ / ]? - // - Sets grid-template-areas to the strings listed. - // - Sets grid-template-rows to the s following each string (filling in auto for any missing sizes), - // and splicing in the named lines defined before/after each size. - // - Sets grid-template-columns to the track listing specified after the slash (or none, if not specified). - auto transaction = tokens.begin_transaction(); - - // FIXME: Read the parts in place if possible, instead of constructing separate vectors and streams. - Vector template_rows_tokens; - Vector template_columns_tokens; - Vector template_area_tokens; - - bool found_forward_slash = false; - - while (tokens.has_next_token()) { - auto& token = tokens.consume_a_token(); - if (token.is_delim('/')) { - if (found_forward_slash) - return nullptr; - found_forward_slash = true; - continue; + { + if (parse_all_as_single_keyword_value(tokens, Keyword::None)) { + return ShorthandStyleValue::create(property_id, + { PropertyID::GridTemplateAreas, PropertyID::GridTemplateRows, PropertyID::GridTemplateColumns }, + { empty_grid_areas, empty_grid_track_size_list, empty_grid_track_size_list }); } - if (found_forward_slash) { - template_columns_tokens.append(token); - continue; - } - if (token.is(Token::Type::String)) - template_area_tokens.append(token); - else - template_rows_tokens.append(token); } - TokenStream template_area_token_stream { template_area_tokens }; - TokenStream template_rows_token_stream { template_rows_tokens }; - TokenStream template_columns_token_stream { template_columns_tokens }; - auto parsed_template_areas_values = parse_grid_template_areas_value(template_area_token_stream); - auto parsed_template_rows_values = parse_grid_track_size_list(template_rows_token_stream, true); - auto parsed_template_columns_values = parse_grid_track_size_list(template_columns_token_stream); + // [ <'grid-template-rows'> / <'grid-template-columns'> ] + { + auto transaction = tokens.begin_transaction(); + if (auto parsed_template_rows_values = parse_grid_track_size_list(tokens)) { + tokens.discard_whitespace(); + if (tokens.has_next_token() && tokens.next_token().is_delim('/')) { + tokens.discard_a_token(); + tokens.discard_whitespace(); + if (auto parsed_template_columns_values = parse_grid_track_size_list(tokens)) { + transaction.commit(); + return ShorthandStyleValue::create(property_id, + { PropertyID::GridTemplateAreas, PropertyID::GridTemplateRows, PropertyID::GridTemplateColumns }, + { empty_grid_areas, parsed_template_rows_values.release_nonnull(), parsed_template_columns_values.release_nonnull() }); + } + } + } + } - if (template_area_token_stream.has_next_token() - || template_rows_token_stream.has_next_token() - || template_columns_token_stream.has_next_token()) - return nullptr; + // [ ? ? ? ]+ [ / ]? + { + auto transaction = tokens.begin_transaction(); - transaction.commit(); - return ShorthandStyleValue::create(property_id, - { PropertyID::GridTemplateAreas, PropertyID::GridTemplateRows, PropertyID::GridTemplateColumns }, - { parsed_template_areas_values.release_nonnull(), parsed_template_rows_values.release_nonnull(), parsed_template_columns_values.release_nonnull() }); + GridTrackSizeList track_list; + Vector area_tokens; + + GridTrackParser parse_grid_track = [&](TokenStream& tokens) -> Optional { + if (!tokens.has_next_token()) + return {}; + tokens.discard_whitespace(); + auto const& token = tokens.consume_a_token(); + if (!token.is(Token::Type::String)) + return {}; + area_tokens.append(token); + tokens.discard_whitespace(); + if (auto track_size = parse_grid_track_size(tokens); track_size.has_value()) + return track_size.release_value(); + tokens.discard_whitespace(); + return ExplicitGridTrack(GridSize::make_auto()); + }; + + auto parsed_track_count = parse_track_list_impl(tokens, track_list, parse_grid_track, AllowTrailingLineNamesForEachTrack::Yes); + if (parsed_track_count > 0) { + TokenStream area_tokens_stream { area_tokens }; + auto grid_areas = parse_grid_template_areas_value(area_tokens_stream); + if (!grid_areas) + return nullptr; + + auto rows_track_list = GridTrackSizeListStyleValue::create(move(track_list)); + + tokens.discard_whitespace(); + + RefPtr columns_track_list = empty_grid_track_size_list; + if (tokens.has_next_token() && tokens.next_token().is_delim('/')) { + tokens.discard_a_token(); + tokens.discard_whitespace(); + if (auto parsed_columns = parse_explicit_track_list(tokens); !parsed_columns.is_empty()) { + transaction.commit(); + columns_track_list = GridTrackSizeListStyleValue::create(move(parsed_columns)); + } else { + return nullptr; + } + } else if (tokens.has_next_token()) { + return nullptr; + } + + transaction.commit(); + return ShorthandStyleValue::create(property_id, + { PropertyID::GridTemplateAreas, PropertyID::GridTemplateRows, PropertyID::GridTemplateColumns }, + { grid_areas.release_nonnull(), rows_track_list, columns_track_list.release_nonnull() }); + } + } + + return nullptr; } RefPtr Parser::parse_grid_area_shorthand_value(TokenStream& tokens) @@ -4471,10 +4503,103 @@ RefPtr Parser::parse_grid_area_shorthand_value(TokenStream< RefPtr Parser::parse_grid_shorthand_value(TokenStream& tokens) { - // <'grid-template'> | - // FIXME: <'grid-template-rows'> / [ auto-flow && dense? ] <'grid-auto-columns'>? | - // FIXME: [ auto-flow && dense? ] <'grid-auto-rows'>? / <'grid-template-columns'> - return parse_grid_track_size_list_shorthand_value(PropertyID::Grid, tokens); + // <'grid-template'> + if (auto grid_template = parse_grid_track_size_list_shorthand_value(PropertyID::Grid, tokens)) { + return grid_template; + } + + auto parse_auto_flow_and_dense = [&](GridAutoFlowStyleValue::Axis axis) -> RefPtr { + bool found_auto_flow = false; + auto dense = GridAutoFlowStyleValue::Dense::No; + for (int i = 0; i < 2 && tokens.has_next_token(); ++i) { + auto const& token = tokens.next_token(); + if (token.is_ident("auto-flow"sv) && !found_auto_flow) { + tokens.discard_a_token(); + tokens.discard_whitespace(); + found_auto_flow = true; + } else if (token.is_ident("dense"sv) && dense == GridAutoFlowStyleValue::Dense::No) { + tokens.discard_a_token(); + tokens.discard_whitespace(); + dense = GridAutoFlowStyleValue::Dense::Yes; + } else { + break; + } + } + + if (found_auto_flow) + return GridAutoFlowStyleValue::create(axis, dense); + return {}; + }; + + // [ auto-flow && dense? ] <'grid-auto-rows'>? / <'grid-template-columns'> + auto parse_shorthand_branch_1 = [&] -> RefPtr { + auto transaction = tokens.begin_transaction(); + tokens.discard_whitespace(); + + auto grid_auto_flow = parse_auto_flow_and_dense(GridAutoFlowStyleValue::Axis::Row); + if (!grid_auto_flow) + return nullptr; + + auto grid_auto_rows = parse_grid_auto_track_sizes(tokens); + if (!grid_auto_rows) { + grid_auto_rows = GridTrackSizeListStyleValue::create({}); + } + + tokens.discard_whitespace(); + if (!tokens.has_next_token() || !tokens.next_token().is_delim('/')) + return nullptr; + tokens.discard_a_token(); + tokens.discard_whitespace(); + + auto grid_template_columns = parse_grid_track_size_list(tokens); + if (!grid_template_columns) + return nullptr; + + transaction.commit(); + return ShorthandStyleValue::create(PropertyID::Grid, + { PropertyID::GridAutoFlow, PropertyID::GridAutoRows, PropertyID::GridTemplateColumns }, + { grid_auto_flow.release_nonnull(), grid_auto_rows.release_nonnull(), grid_template_columns.release_nonnull() }); + }; + + // <'grid-template-rows'> / [ auto-flow && dense? ] <'grid-auto-columns'>? + auto parse_shorthand_branch_2 = [&] -> RefPtr { + auto transaction = tokens.begin_transaction(); + tokens.discard_whitespace(); + + auto grid_template_rows = parse_grid_track_size_list(tokens); + if (!grid_template_rows) + return nullptr; + + tokens.discard_whitespace(); + if (!tokens.has_next_token() || !tokens.next_token().is_delim('/')) + return nullptr; + tokens.discard_a_token(); + tokens.discard_whitespace(); + + auto grid_auto_flow = parse_auto_flow_and_dense(GridAutoFlowStyleValue::Axis::Column); + if (!grid_auto_flow) + return nullptr; + + auto grid_auto_columns = parse_grid_auto_track_sizes(tokens); + if (!grid_auto_columns) { + grid_auto_columns = GridTrackSizeListStyleValue::create({}); + } + + transaction.commit(); + return ShorthandStyleValue::create(PropertyID::Grid, + { PropertyID::GridTemplateRows, PropertyID::GridAutoFlow, PropertyID::GridAutoColumns }, + { grid_template_rows.release_nonnull(), grid_auto_flow.release_nonnull(), grid_auto_columns.release_nonnull() }); + }; + + if (auto grid = parse_shorthand_branch_1()) { + return grid; + } + + if (auto grid = parse_shorthand_branch_2()) { + return grid; + } + + return nullptr; } // https://www.w3.org/TR/css-grid-1/#grid-template-areas-property @@ -4543,21 +4668,18 @@ RefPtr Parser::parse_grid_auto_track_sizes(TokenStream+ - Vector> track_list; auto transaction = tokens.begin_transaction(); + GridTrackSizeList track_list; while (tokens.has_next_token()) { - auto const& token = tokens.consume_a_token(); - auto track_sizing_function = parse_track_sizing_function(token); - if (!track_sizing_function.has_value()) { - transaction.commit(); - return GridTrackSizeListStyleValue::make_auto(); - } - // FIXME: Handle multiple repeat values (should combine them here, or remove - // any other ones if the first one is auto-fill, etc.) - track_list.append(track_sizing_function.value()); + tokens.discard_whitespace(); + auto track_size = parse_grid_track_size(tokens); + if (!track_size.has_value()) + break; + track_list.append(track_size.release_value()); } - transaction.commit(); - return GridTrackSizeListStyleValue::create(GridTrackSizeList(move(track_list))); + if (!track_list.is_empty()) + transaction.commit(); + return GridTrackSizeListStyleValue::create(move(track_list)); } // https://www.w3.org/TR/css-grid-1/#grid-auto-flow-property @@ -4613,51 +4735,34 @@ RefPtr Parser::parse_grid_auto_flow_value(TokenStr return GridAutoFlowStyleValue::create(axis.value_or(GridAutoFlowStyleValue::Axis::Row), dense.value_or(GridAutoFlowStyleValue::Dense::No)); } -RefPtr Parser::parse_grid_track_size_list(TokenStream& tokens, bool allow_separate_line_name_blocks) +// https://www.w3.org/TR/css-grid-2/#track-sizing +RefPtr Parser::parse_grid_track_size_list(TokenStream& tokens) { - if (auto none = parse_all_as_single_keyword_value(tokens, Keyword::None)) - return GridTrackSizeListStyleValue::make_none(); + // none | | | FIXME subgrid ? - auto transaction = tokens.begin_transaction(); - - Vector> track_list; - auto last_object_was_line_names = false; - while (tokens.has_next_token()) { - auto const& token = tokens.consume_a_token(); - if (token.is_block()) { - if (last_object_was_line_names && !allow_separate_line_name_blocks) { - transaction.commit(); - return GridTrackSizeListStyleValue::make_auto(); - } - last_object_was_line_names = true; - Vector line_names; - if (!token.block().is_square()) { - transaction.commit(); - return GridTrackSizeListStyleValue::make_auto(); - } - TokenStream block_tokens { token.block().value }; - block_tokens.discard_whitespace(); - while (block_tokens.has_next_token()) { - auto const& current_block_token = block_tokens.consume_a_token(); - line_names.append(current_block_token.token().ident().to_string()); - block_tokens.discard_whitespace(); - } - track_list.append(GridLineNames { move(line_names) }); - } else { - last_object_was_line_names = false; - auto track_sizing_function = parse_track_sizing_function(token); - if (!track_sizing_function.has_value()) { - transaction.commit(); - return GridTrackSizeListStyleValue::make_auto(); - } - // FIXME: Handle multiple repeat values (should combine them here, or remove - // any other ones if the first one is auto-fill, etc.) - track_list.append(track_sizing_function.value()); + // none + { + auto transaction = tokens.begin_transaction(); + if (tokens.has_next_token() && tokens.next_token().is_ident("none"sv)) { + tokens.discard_a_token(); + transaction.commit(); + return GridTrackSizeListStyleValue::make_none(); } } - transaction.commit(); - return GridTrackSizeListStyleValue::create(GridTrackSizeList(move(track_list))); + // + auto auto_track_list = parse_grid_auto_track_list(tokens); + if (!auto_track_list.is_empty()) { + return GridTrackSizeListStyleValue::create(GridTrackSizeList(move(auto_track_list))); + } + + // + auto track_list = parse_grid_track_list(tokens); + if (!track_list.is_empty()) { + return GridTrackSizeListStyleValue::create(GridTrackSizeList(move(track_list))); + } + + return nullptr; } RefPtr Parser::parse_filter_value_list_value(TokenStream& tokens) diff --git a/Libraries/LibWeb/CSS/Parser/ValueParsing.cpp b/Libraries/LibWeb/CSS/Parser/ValueParsing.cpp index 33c8ab89455..fab43af63b4 100644 --- a/Libraries/LibWeb/CSS/Parser/ValueParsing.cpp +++ b/Libraries/LibWeb/CSS/Parser/ValueParsing.cpp @@ -8,6 +8,7 @@ * Copyright (c) 2024, Tommy van der Vorst * Copyright (c) 2024, Matthew Olsson * Copyright (c) 2024, Glenn Skrzypczak + * Copyright (c) 2025, Aliaksandr Kalenik * * SPDX-License-Identifier: BSD-2-Clause */ @@ -3210,243 +3211,437 @@ RefPtr Parser::parse_custom_ident_value(TokenStream return nullptr; } -Optional Parser::parse_grid_size(ComponentValue const& component_value) +// https://www.w3.org/TR/css-grid-2/#typedef-track-breadth +Optional Parser::parse_grid_track_breadth(TokenStream& tokens) { - if (component_value.is_function()) { - if (auto maybe_calculated = parse_calculated_value(component_value)) { - if (maybe_calculated->is_length()) - return GridSize(maybe_calculated->as_length().length()); - if (maybe_calculated->is_percentage()) - return GridSize(maybe_calculated->as_percentage().percentage()); - if (maybe_calculated->is_calculated() && maybe_calculated->as_calculated().resolves_to_length_percentage()) - return GridSize(LengthPercentage(maybe_calculated->as_calculated())); - // FIXME: Support calculated - } + // = | | min-content | max-content | auto - return {}; + if (auto inflexible_breadth = parse_grid_inflexible_breadth(tokens); inflexible_breadth.has_value()) + return inflexible_breadth; + + // FIXME: Handle calculated flex values. + if (auto flex_value = parse_flex_value(tokens); flex_value && flex_value->is_flex()) { + if (auto flex = flex_value->as_flex().flex(); flex.raw_value() >= 0) + return GridSize(flex); } - if (component_value.is_ident("auto"sv)) - return GridSize::make_auto(); - if (component_value.is_ident("max-content"sv)) + + return {}; +} + +// https://www.w3.org/TR/css-grid-2/#typedef-inflexible-breadth +Optional Parser::parse_grid_inflexible_breadth(TokenStream& tokens) +{ + // = | min-content | max-content | auto + + if (auto fixed_breadth = parse_grid_fixed_breadth(tokens); fixed_breadth.has_value()) + return fixed_breadth; + + auto transaction = tokens.begin_transaction(); + if (!tokens.has_next_token()) + return {}; + + auto const& token = tokens.consume_a_token(); + if (token.is_ident("max-content"sv)) { + transaction.commit(); return GridSize(GridSize::Type::MaxContent); - if (component_value.is_ident("min-content"sv)) - return GridSize(GridSize::Type::MinContent); - auto dimension = parse_dimension(component_value); - if (!dimension.has_value()) - return {}; - if (dimension->is_length()) - return GridSize(dimension->length()); - else if (dimension->is_percentage()) - return GridSize(dimension->percentage()); - else if (dimension->is_flex()) - return GridSize(dimension->flex()); - return {}; -} - -Optional Parser::parse_grid_fit_content(Vector const& component_values) -{ - // https://www.w3.org/TR/css-grid-2/#valdef-grid-template-columns-fit-content - // 'fit-content( )' - // Represents the formula max(minimum, min(limit, max-content)), where minimum represents an auto minimum (which is often, but not always, - // equal to a min-content minimum), and limit is the track sizing function passed as an argument to fit-content(). - // This is essentially calculated as the smaller of minmax(auto, max-content) and minmax(auto, limit). - auto function_tokens = TokenStream(component_values); - function_tokens.discard_whitespace(); - auto maybe_length_percentage = parse_length_percentage(function_tokens); - if (maybe_length_percentage.has_value()) - return GridSize(GridSize::Type::FitContent, maybe_length_percentage.value()); - return {}; -} - -Optional Parser::parse_min_max(Vector const& component_values) -{ - // 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 {}; - - TokenStream part_one_tokens { comma_separated_list[0] }; - part_one_tokens.discard_whitespace(); - if (!part_one_tokens.has_next_token()) - return {}; - NonnullRawPtr current_token = part_one_tokens.consume_a_token(); - auto min_grid_size = parse_grid_size(current_token); - - TokenStream part_two_tokens { comma_separated_list[1] }; - part_two_tokens.discard_whitespace(); - if (!part_two_tokens.has_next_token()) - return {}; - current_token = part_two_tokens.consume_a_token(); - auto max_grid_size = parse_grid_size(current_token); - - if (min_grid_size.has_value() && max_grid_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_size.value().is_flexible_length()) - return {}; - return CSS::GridMinMax(min_grid_size.value(), max_grid_size.value()); } + if (token.is_ident("min-content"sv)) { + transaction.commit(); + return GridSize(GridSize::Type::MinContent); + } + if (token.is_ident("auto"sv)) { + transaction.commit(); + return GridSize::make_auto(); + } + return {}; } -Optional Parser::parse_repeat(Vector const& component_values) +// https://www.w3.org/TR/css-grid-2/#typedef-fixed-breadth +Optional Parser::parse_grid_fixed_breadth(TokenStream& tokens) { - // https://www.w3.org/TR/css-grid-2/#repeat-syntax - // 7.2.3.1. Syntax of repeat() - // The generic form of the repeat() syntax is, approximately, - // repeat( [ | auto-fill | auto-fit ] , ) - auto is_auto_fill = false; - auto is_auto_fit = false; - 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 {}; - // The first argument specifies the number of repetitions. - TokenStream part_one_tokens { comma_separated_list[0] }; - part_one_tokens.discard_whitespace(); - if (!part_one_tokens.has_next_token()) - return {}; - auto& current_token = part_one_tokens.consume_a_token(); + // = - auto repeat_count = 0; - if (current_token.is(Token::Type::Number) && current_token.token().number().is_integer() && current_token.token().number_value() > 0) - repeat_count = current_token.token().number_value(); - else if (current_token.is_ident("auto-fill"sv)) - is_auto_fill = true; - else if (current_token.is_ident("auto-fit"sv)) - is_auto_fit = true; - - // The second argument is a track list, which is repeated that number of times. - TokenStream part_two_tokens { comma_separated_list[1] }; - part_two_tokens.discard_whitespace(); - if (!part_two_tokens.has_next_token()) + auto transaction = tokens.begin_transaction(); + auto length_percentage = parse_length_percentage(tokens); + if (!length_percentage.has_value()) return {}; + if (length_percentage->is_length() && length_percentage->length().raw_value() < 0) + return {}; + if (length_percentage->is_percentage() && length_percentage->percentage().value() < 0) + return {}; + transaction.commit(); + return GridSize(length_percentage.release_value()); +} - Vector> repeat_params; - auto last_object_was_line_names = false; - while (part_two_tokens.has_next_token()) { - auto const& token = part_two_tokens.consume_a_token(); - Vector line_names; - if (token.is_block()) { - if (last_object_was_line_names) - return {}; - last_object_was_line_names = true; - if (!token.block().is_square()) - return {}; - TokenStream block_tokens { token.block().value }; - while (block_tokens.has_next_token()) { - auto const& current_block_token = block_tokens.consume_a_token(); - line_names.append(current_block_token.token().ident().to_string()); - block_tokens.discard_whitespace(); +// https://www.w3.org/TR/css-grid-2/#typedef-line-names +Optional Parser::parse_grid_line_names(TokenStream& tokens) +{ + // = '[' * ']' + + auto transactions = tokens.begin_transaction(); + GridLineNames line_names; + auto const& token = tokens.consume_a_token(); + if (!token.is_block() || !token.block().is_square()) + return line_names; + + TokenStream block_tokens { token.block().value }; + block_tokens.discard_whitespace(); + while (block_tokens.has_next_token()) { + auto maybe_ident = parse_custom_ident(block_tokens, { { "span"sv, "auto"sv } }); + if (!maybe_ident.has_value()) + return OptionalNone {}; + line_names.names.append(maybe_ident.release_value()); + block_tokens.discard_whitespace(); + } + + transactions.commit(); + return line_names; +} + +size_t Parser::parse_track_list_impl(TokenStream& tokens, GridTrackSizeList& output, GridTrackParser const& track_parsing_callback, AllowTrailingLineNamesForEachTrack allow_trailing_line_names_for_each_track) +{ + size_t parsed_tracks_count = 0; + while (tokens.has_next_token()) { + auto transaction = tokens.begin_transaction(); + auto line_names = parse_grid_line_names(tokens); + + tokens.discard_whitespace(); + auto explicit_grid_track = track_parsing_callback(tokens); + tokens.discard_whitespace(); + + if (!explicit_grid_track.has_value()) + break; + + if (line_names.has_value() && !line_names->names.is_empty()) + output.append(line_names.release_value()); + + output.append(explicit_grid_track.release_value()); + if (allow_trailing_line_names_for_each_track == AllowTrailingLineNamesForEachTrack::Yes) { + auto trailing_line_names = parse_grid_line_names(tokens); + if (trailing_line_names.has_value() && !trailing_line_names->names.is_empty()) { + output.append(trailing_line_names.release_value()); } - repeat_params.append(GridLineNames { move(line_names) }); - part_two_tokens.discard_whitespace(); - } else { - last_object_was_line_names = false; - auto track_sizing_function = parse_track_sizing_function(token); - if (!track_sizing_function.has_value()) - return {}; - // However, there are some restrictions: - // The repeat() notation can’t be nested. - if (track_sizing_function.value().is_repeat()) - return {}; + } + transaction.commit(); + parsed_tracks_count++; + } - // Automatic repetitions (auto-fill or auto-fit) cannot be combined with intrinsic or flexible sizes. - // Note that 'auto' is also an intrinsic size (and thus not permitted) but we can't use - // track_sizing_function.is_auto(..) to check for it, as it requires AvailableSize, which is why there is - // a separate check for it below. - // https://www.w3.org/TR/css-grid-2/#repeat-syntax - // https://www.w3.org/TR/css-grid-2/#intrinsic-sizing-function - if (track_sizing_function.value().is_default() - && (track_sizing_function.value().grid_size().is_flexible_length() || token.is_ident("auto"sv)) - && (is_auto_fill || is_auto_fit)) - return {}; - if ((is_auto_fill || is_auto_fit) && track_sizing_function->is_minmax()) { - auto const& minmax = track_sizing_function->minmax(); - if (!minmax.min_grid_size().is_definite() && !minmax.max_grid_size().is_definite()) { - return {}; - } - } - - repeat_params.append(track_sizing_function.value()); - part_two_tokens.discard_whitespace(); + if (allow_trailing_line_names_for_each_track == AllowTrailingLineNamesForEachTrack::No) { + if (auto trailing_line_names = parse_grid_line_names(tokens); trailing_line_names.has_value() && !trailing_line_names->names.is_empty()) { + output.append(trailing_line_names.release_value()); } } - // Thus the precise syntax of the repeat() notation has several forms: - // = repeat( [ ] , [ ? ]+ ? ) - // = repeat( [ auto-fill | auto-fit ] , [ ? ]+ ? ) - // = repeat( [ ] , [ ? ]+ ? ) - // = repeat( [ | auto-fill ], +) - - // The variant can represent the repetition of any , but is limited to a - // fixed number of repetitions. - - // The variant can repeat automatically to fill a space, but requires definite track - // sizes so that the number of repetitions can be calculated. It can only appear once in the track - // list, but the same track list can also contain s. - - // The variant is for adding line names to subgrids. It can only be used with the - // subgrid keyword and cannot specify track sizes, only line names. - - // If a repeat() function that is not a ends up placing two adjacent to - // each other, the name lists are merged. For example, repeat(2, [a] 1fr [b]) is equivalent to [a] - // 1fr [b a] 1fr [b]. - if (is_auto_fill) - return GridRepeat(GridTrackSizeList(move(repeat_params)), GridRepeat::Type::AutoFill); - else if (is_auto_fit) - return GridRepeat(GridTrackSizeList(move(repeat_params)), GridRepeat::Type::AutoFit); - else - return GridRepeat(GridTrackSizeList(move(repeat_params)), repeat_count); + return parsed_tracks_count; } -Optional Parser::parse_track_sizing_function(ComponentValue const& token) +Optional Parser::parse_grid_track_repeat_impl(TokenStream& tokens, GridRepeatTypeParser const& repeat_type_parser, GridTrackParser const& repeat_track_parser) { - if (token.is_function()) { + auto transaction = tokens.begin_transaction(); + + if (!tokens.has_next_token()) + return {}; + + auto const& token = tokens.consume_a_token(); + if (!token.is_function()) + return {}; + + auto const& function_token = token.function(); + if (!function_token.name.equals_ignoring_ascii_case("repeat"sv)) + return {}; + auto context_guard = push_temporary_value_parsing_context(FunctionContext { function_token.name }); + + auto function_tokens = TokenStream(function_token.value); + auto comma_separated_list = parse_a_comma_separated_list_of_component_values(function_tokens); + if (comma_separated_list.size() != 2) + return {}; + + TokenStream first_arg_tokens { comma_separated_list[0] }; + first_arg_tokens.discard_whitespace(); + if (!first_arg_tokens.has_next_token()) + return {}; + + auto repeat_params = repeat_type_parser(first_arg_tokens); + if (!repeat_params.has_value()) + return {}; + first_arg_tokens.discard_whitespace(); + if (first_arg_tokens.has_next_token()) + return {}; + + TokenStream second_arg_tokens { comma_separated_list[1] }; + second_arg_tokens.discard_whitespace(); + GridTrackSizeList track_list; + if (auto parsed_track_count = parse_track_list_impl(second_arg_tokens, track_list, repeat_track_parser); parsed_track_count == 0) + return {}; + if (second_arg_tokens.has_next_token()) + return {}; + transaction.commit(); + return GridRepeat(GridTrackSizeList(move(track_list)), repeat_params.release_value()); +} + +Optional Parser::parse_grid_minmax(TokenStream& tokens, GridMinMaxParamParser const& min_parser, GridMinMaxParamParser const& max_parser) +{ + auto transaction = tokens.begin_transaction(); + + if (!tokens.has_next_token()) + return {}; + + auto const& token = tokens.consume_a_token(); + if (!token.is_function()) + return {}; + + auto const& function_token = token.function(); + if (!function_token.name.equals_ignoring_ascii_case("minmax"sv)) + return {}; + + auto context_guard = push_temporary_value_parsing_context(FunctionContext { function_token.name }); + auto function_tokens = TokenStream(function_token.value); + auto comma_separated_list = parse_a_comma_separated_list_of_component_values(function_tokens); + if (comma_separated_list.size() != 2) + return {}; + + TokenStream min_tokens { comma_separated_list[0] }; + min_tokens.discard_whitespace(); + auto min_value = min_parser(min_tokens); + if (!min_value.has_value()) + return {}; + min_tokens.discard_whitespace(); + if (min_tokens.has_next_token()) + return {}; + + TokenStream max_tokens { comma_separated_list[1] }; + max_tokens.discard_whitespace(); + auto max_value = max_parser(max_tokens); + if (!max_value.has_value()) + return {}; + max_tokens.discard_whitespace(); + if (max_tokens.has_next_token()) + return {}; + + transaction.commit(); + return ExplicitGridTrack(GridMinMax(min_value.release_value(), max_value.release_value())); +} + +// https://www.w3.org/TR/css-grid-2/#typedef-track-repeat +Optional Parser::parse_grid_track_repeat(TokenStream& tokens) +{ + // = repeat( [ ] , [ ? ]+ ? ) + + GridRepeatTypeParser parse_repeat_type = [this](TokenStream& tokens) -> Optional { + auto maybe_integer = parse_integer(tokens); + if (!maybe_integer.has_value()) + return {}; + if (maybe_integer->is_calculated()) { + // FIXME: Support calculated repeat counts. + return {}; + } + if (maybe_integer->value() < 1) + return {}; + return GridRepeatParams { GridRepeatType::Fixed, static_cast(maybe_integer->value()) }; + }; + GridTrackParser parse_track = [this](TokenStream& tokens) { + return parse_grid_track_size(tokens); + }; + return parse_grid_track_repeat_impl(tokens, parse_repeat_type, parse_track); +} + +// https://www.w3.org/TR/css-grid-2/#typedef-auto-repeat +Optional Parser::parse_grid_auto_repeat(TokenStream& tokens) +{ + // = repeat( [ auto-fill | auto-fit ] , [ ? ]+ ? ) + + GridRepeatTypeParser parse_repeat_type = [](TokenStream& tokens) -> Optional { + auto const& first_token = tokens.consume_a_token(); + if (!first_token.is_token() || !first_token.token().is(Token::Type::Ident)) + return {}; + + auto ident_value = first_token.token().ident(); + if (ident_value.equals_ignoring_ascii_case("auto-fill"sv)) + return GridRepeatParams { GridRepeatType::AutoFill }; + if (ident_value.equals_ignoring_ascii_case("auto-fit"sv)) + return GridRepeatParams { GridRepeatType::AutoFit }; + return {}; + }; + GridTrackParser parse_track = [this](TokenStream& tokens) { + return parse_grid_fixed_size(tokens); + }; + return parse_grid_track_repeat_impl(tokens, parse_repeat_type, parse_track); +} + +// https://www.w3.org/TR/css-grid-2/#typedef-fixed-repeat +Optional Parser::parse_grid_fixed_repeat(TokenStream& tokens) +{ + // = repeat( [ ] , [ ? ]+ ? ) + + GridRepeatTypeParser parse_repeat_type = [this](TokenStream& tokens) -> Optional { + auto maybe_integer = parse_integer(tokens); + if (!maybe_integer.has_value()) + return {}; + if (maybe_integer->is_calculated()) { + // FIXME: Support calculated repeat counts. + return {}; + } + if (maybe_integer->value() < 1) + return {}; + return GridRepeatParams { GridRepeatType::Fixed, static_cast(maybe_integer->value()) }; + }; + GridTrackParser parse_track = [this](TokenStream& tokens) { + return parse_grid_fixed_size(tokens); + }; + return parse_grid_track_repeat_impl(tokens, parse_repeat_type, parse_track); +} + +// https://www.w3.org/TR/css-grid-2/#typedef-track-size +Optional Parser::parse_grid_track_size(TokenStream& tokens) +{ + // = | minmax( , ) | fit-content( ) + + if (!tokens.has_next_token()) + return {}; + + if (tokens.peek_token().is_function()) { + auto const& token = tokens.peek_token(); auto const& function_token = token.function(); + + if (function_token.name.equals_ignoring_ascii_case("minmax"sv)) { + GridMinMaxParamParser parse_min = [this](auto& tokens) { return parse_grid_inflexible_breadth(tokens); }; + GridMinMaxParamParser parse_max = [this](auto& tokens) { return parse_grid_track_breadth(tokens); }; + return parse_grid_minmax(tokens, parse_min, parse_max); + } + + auto transaction = tokens.begin_transaction(); + tokens.discard_a_token(); auto context_guard = push_temporary_value_parsing_context(FunctionContext { function_token.name }); - if (function_token.name.equals_ignoring_ascii_case("repeat"sv)) { - auto maybe_repeat = parse_repeat(function_token.value); - if (maybe_repeat.has_value()) - return CSS::ExplicitGridTrack(maybe_repeat.value()); - else + if (function_token.name.equals_ignoring_ascii_case("fit-content"sv)) { + auto function_tokens = TokenStream(function_token.value); + function_tokens.discard_whitespace(); + auto maybe_length_percentage = parse_grid_fixed_breadth(function_tokens); + if (!maybe_length_percentage.has_value()) return {}; - } else if (function_token.name.equals_ignoring_ascii_case("minmax"sv)) { - auto maybe_min_max_value = parse_min_max(function_token.value); - if (maybe_min_max_value.has_value()) - return CSS::ExplicitGridTrack(maybe_min_max_value.value()); - else + if (function_tokens.has_next_token()) return {}; - } else if (function_token.name.equals_ignoring_ascii_case("fit-content"sv)) { - auto maybe_fit_content_value = parse_grid_fit_content(function_token.value); - if (maybe_fit_content_value.has_value()) - return CSS::ExplicitGridTrack(maybe_fit_content_value.value()); - return {}; - } else if (auto maybe_calculated = parse_calculated_value(token)) { - if (maybe_calculated->is_length()) - return ExplicitGridTrack(GridSize(maybe_calculated->as_length().length())); - if (maybe_calculated->is_percentage()) - return ExplicitGridTrack(GridSize(maybe_calculated->as_percentage().percentage())); - if (maybe_calculated->is_calculated() && maybe_calculated->as_calculated().resolves_to_length_percentage()) - return ExplicitGridTrack(GridSize(LengthPercentage(maybe_calculated->as_calculated()))); + transaction.commit(); + return ExplicitGridTrack(GridSize(GridSize::Type::FitContent, maybe_length_percentage->length_percentage())); } - return {}; - } else if (token.is_ident("auto"sv)) { - return CSS::ExplicitGridTrack(GridSize(Length::make_auto())); - } else if (token.is_block()) { - return {}; - } else { - auto grid_size = parse_grid_size(token); - if (!grid_size.has_value()) - return {}; - return CSS::ExplicitGridTrack(grid_size.value()); } + + if (auto track_breadth = parse_grid_track_breadth(tokens); track_breadth.has_value()) { + return ExplicitGridTrack(track_breadth.value()); + } + + return {}; +} + +// https://www.w3.org/TR/css-grid-2/#typedef-fixed-size +Optional Parser::parse_grid_fixed_size(TokenStream& tokens) +{ + // = | minmax( , ) | minmax( , ) + + if (!tokens.has_next_token()) + return {}; + + if (tokens.peek_token().is_function()) { + auto const& token = tokens.peek_token(); + auto const& function_token = token.function(); + if (function_token.name.equals_ignoring_ascii_case("minmax"sv)) { + { + GridMinMaxParamParser parse_min = [this](auto& tokens) { return parse_grid_fixed_breadth(tokens); }; + GridMinMaxParamParser parse_max = [this](auto& tokens) { return parse_grid_track_breadth(tokens); }; + if (auto result = parse_grid_minmax(tokens, parse_min, parse_max); result.has_value()) + return result; + } + { + GridMinMaxParamParser parse_min = [this](auto& tokens) { return parse_grid_inflexible_breadth(tokens); }; + GridMinMaxParamParser parse_max = [this](auto& tokens) { return parse_grid_fixed_breadth(tokens); }; + if (auto result = parse_grid_minmax(tokens, parse_min, parse_max); result.has_value()) + return result; + } + + return {}; + } + } + + if (auto fixed_breadth = parse_grid_fixed_breadth(tokens); fixed_breadth.has_value()) { + return ExplicitGridTrack(fixed_breadth.value()); + } + + return {}; +} + +// https://www.w3.org/TR/css-grid-2/#typedef-track-list +GridTrackSizeList Parser::parse_grid_track_list(TokenStream& tokens) +{ + // = [ ? [ | ] ]+ ? + + auto transaction = tokens.begin_transaction(); + GridTrackSizeList track_list; + auto parsed_track_count = parse_track_list_impl(tokens, track_list, [&](auto& tokens) -> Optional { + if (auto track_repeat = parse_grid_track_repeat(tokens); track_repeat.has_value()) + return ExplicitGridTrack(track_repeat.value()); + if (auto track_size = parse_grid_track_size(tokens); track_size.has_value()) + return ExplicitGridTrack(track_size.value()); + return Optional {}; + }); + if (parsed_track_count == 0) + return {}; + transaction.commit(); + return track_list; +} + +// https://www.w3.org/TR/css-grid-2/#typedef-auto-track-list +GridTrackSizeList Parser::parse_grid_auto_track_list(TokenStream& tokens) +{ + // = [ ? [ | ] ]* ? + // [ ? [ | ] ]* ? + + auto transaction = tokens.begin_transaction(); + GridTrackSizeList track_list; + size_t parsed_track_count = 0; + auto parse_zero_or_more_fixed_tracks = [&] { + parsed_track_count += parse_track_list_impl(tokens, track_list, [&](auto& tokens) -> Optional { + if (auto fixed_repeat = parse_grid_fixed_repeat(tokens); fixed_repeat.has_value()) + return ExplicitGridTrack(fixed_repeat.value()); + if (auto fixed_size = parse_grid_fixed_size(tokens); fixed_size.has_value()) + return ExplicitGridTrack(fixed_size.value()); + return Optional {}; + }); + }; + + parse_zero_or_more_fixed_tracks(); + if (!tokens.has_next_token()) { + if (parsed_track_count == 0) + return {}; + transaction.commit(); + return track_list; + } + + if (auto auto_repeat = parse_grid_auto_repeat(tokens); auto_repeat.has_value()) { + track_list.append(ExplicitGridTrack(auto_repeat.release_value())); + } else { + return {}; + } + + parse_zero_or_more_fixed_tracks(); + transaction.commit(); + return track_list; +} + +// https://www.w3.org/TR/css-grid-2/#typedef-explicit-track-list +GridTrackSizeList Parser::parse_explicit_track_list(TokenStream& tokens) +{ + // = [ ? ]+ ? + + auto transaction = tokens.begin_transaction(); + GridTrackSizeList track_list; + auto parsed_track_count = parse_track_list_impl(tokens, track_list, [&](auto& tokens) -> Optional { + return parse_grid_track_size(tokens); + }); + if (parsed_track_count == 0) + return {}; + transaction.commit(); + return track_list; } RefPtr Parser::parse_grid_track_placement(TokenStream& tokens) diff --git a/Libraries/LibWeb/Forward.h b/Libraries/LibWeb/Forward.h index 5185e433ca6..d5300f7783e 100644 --- a/Libraries/LibWeb/Forward.h +++ b/Libraries/LibWeb/Forward.h @@ -240,7 +240,6 @@ class FrequencyOrCalculated; class FrequencyPercentage; class FrequencyStyleValue; class GridAutoFlowStyleValue; -class GridFitContent; class GridMinMax; class GridRepeat; class GridSize; @@ -317,6 +316,8 @@ enum class PropertyID : u16; struct BackgroundLayerData; struct CSSStyleSheetInit; +struct GridLineNames; +struct GridRepeatParams; struct StyleSheetIdentifier; } diff --git a/Libraries/LibWeb/Layout/GridFormattingContext.cpp b/Libraries/LibWeb/Layout/GridFormattingContext.cpp index e7b5f53c049..0753966244f 100644 --- a/Libraries/LibWeb/Layout/GridFormattingContext.cpp +++ b/Libraries/LibWeb/Layout/GridFormattingContext.cpp @@ -2292,7 +2292,7 @@ void GridFormattingContext::init_grid_lines(GridDimension dimension) auto const& lines_definition = dimension == GridDimension::Column ? grid_computed_values.grid_template_columns() : grid_computed_values.grid_template_rows(); auto& lines = dimension == GridDimension::Column ? m_column_lines : m_row_lines; - Vector line_names; + Vector line_names; Function expand_lines_definition = [&](CSS::GridTrackSizeList const& lines_definition) { for (auto const& item : lines_definition.list()) { if (item.has()) { diff --git a/Libraries/LibWeb/Layout/GridFormattingContext.h b/Libraries/LibWeb/Layout/GridFormattingContext.h index 814c6580f2d..db22802ac83 100644 --- a/Libraries/LibWeb/Layout/GridFormattingContext.h +++ b/Libraries/LibWeb/Layout/GridFormattingContext.h @@ -233,7 +233,7 @@ private: }; struct GridLine { - Vector names; + Vector names; }; Vector m_row_lines; Vector m_column_lines; diff --git a/Tests/LibWeb/Text/expected/css/calc-coverage.txt b/Tests/LibWeb/Text/expected/css/calc-coverage.txt index bb3d57ede5e..a01b906a342 100644 --- a/Tests/LibWeb/Text/expected/css/calc-coverage.txt +++ b/Tests/LibWeb/Text/expected/css/calc-coverage.txt @@ -76,10 +76,10 @@ font-weight: 'calc(2)' -> '2' font-weight: 'calc(2 * var(--n))' -> '4' font-width: 'calc(2%)' -> '2%' font-width: 'calc(2% * var(--n))' -> '4%' -grid-auto-columns: 'calc(2fr)' -> 'none' -grid-auto-columns: 'calc(2fr * var(--n))' -> 'none' -grid-auto-rows: 'calc(2fr)' -> 'none' -grid-auto-rows: 'calc(2fr * var(--n))' -> 'none' +grid-auto-columns: 'calc(2fr)' -> 'auto' +grid-auto-columns: 'calc(2fr * var(--n))' -> 'auto' +grid-auto-rows: 'calc(2fr)' -> 'auto' +grid-auto-rows: 'calc(2fr * var(--n))' -> 'auto' grid-template-columns: 'calc(2fr)' -> 'none' grid-template-columns: 'calc(2fr * var(--n))' -> 'none' grid-template-rows: 'calc(2fr)' -> 'none' diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-auto-columns-invalid.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-auto-columns-invalid.txt index ae25e2cb4de..748faffa5b9 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-auto-columns-invalid.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-auto-columns-invalid.txt @@ -2,19 +2,18 @@ Harness status: OK Found 15 tests -4 Pass -11 Fail -Fail e.style['grid-auto-columns'] = "none" should not set the property value -Fail e.style['grid-auto-columns'] = "-1px" should not set the property value -Fail e.style['grid-auto-columns'] = "-4%" should not set the property value -Fail e.style['grid-auto-columns'] = "minmax(1px)" should not set the property value -Fail e.style['grid-auto-columns'] = "minmax(1px, 2px, 3px)" should not set the property value -Fail e.style['grid-auto-columns'] = "minmax(5fr, 1px)" should not set the property value -Fail e.style['grid-auto-columns'] = "minmax(6px, -7%)" should not set the property value -Fail e.style['grid-auto-columns'] = "minmax(8px, -9fr)" should not set the property value -Fail e.style['grid-auto-columns'] = "fit-content(-1px)" should not set the property value -Fail e.style['grid-auto-columns'] = "fit-content(1px, 2px)" should not set the property value -Fail e.style['grid-auto-columns'] = "fit-content(1px auto)" should not set the property value +15 Pass +Pass e.style['grid-auto-columns'] = "none" should not set the property value +Pass e.style['grid-auto-columns'] = "-1px" should not set the property value +Pass e.style['grid-auto-columns'] = "-4%" should not set the property value +Pass e.style['grid-auto-columns'] = "minmax(1px)" should not set the property value +Pass e.style['grid-auto-columns'] = "minmax(1px, 2px, 3px)" should not set the property value +Pass e.style['grid-auto-columns'] = "minmax(5fr, 1px)" should not set the property value +Pass e.style['grid-auto-columns'] = "minmax(6px, -7%)" should not set the property value +Pass e.style['grid-auto-columns'] = "minmax(8px, -9fr)" should not set the property value +Pass e.style['grid-auto-columns'] = "fit-content(-1px)" should not set the property value +Pass e.style['grid-auto-columns'] = "fit-content(1px, 2px)" should not set the property value +Pass e.style['grid-auto-columns'] = "fit-content(1px auto)" should not set the property value Pass e.style['grid-auto-columns'] = "2em / 3em" should not set the property value Pass e.style['grid-auto-columns'] = "auto, 10%" should not set the property value Pass e.style['grid-auto-columns'] = "1px [a] 1px" should not set the property value diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-auto-rows-invalid.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-auto-rows-invalid.txt index f2b712322d5..22a12039d9d 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-auto-rows-invalid.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-auto-rows-invalid.txt @@ -2,18 +2,17 @@ Harness status: OK Found 14 tests -4 Pass -10 Fail -Fail e.style['grid-auto-rows'] = "none" should not set the property value -Fail e.style['grid-auto-rows'] = "-1px" should not set the property value -Fail e.style['grid-auto-rows'] = "-4%" should not set the property value -Fail e.style['grid-auto-rows'] = "minmax(1px)" should not set the property value -Fail e.style['grid-auto-rows'] = "minmax(1px, 2px, 3px)" should not set the property value -Fail e.style['grid-auto-rows'] = "minmax(5fr, 1px)" should not set the property value -Fail e.style['grid-auto-rows'] = "minmax(6px, -7%)" should not set the property value -Fail e.style['grid-auto-rows'] = "fit-content(-1px)" should not set the property value -Fail e.style['grid-auto-rows'] = "fit-content(1px, 2px)" should not set the property value -Fail e.style['grid-auto-rows'] = "fit-content(1px auto)" should not set the property value +14 Pass +Pass e.style['grid-auto-rows'] = "none" should not set the property value +Pass e.style['grid-auto-rows'] = "-1px" should not set the property value +Pass e.style['grid-auto-rows'] = "-4%" should not set the property value +Pass e.style['grid-auto-rows'] = "minmax(1px)" should not set the property value +Pass e.style['grid-auto-rows'] = "minmax(1px, 2px, 3px)" should not set the property value +Pass e.style['grid-auto-rows'] = "minmax(5fr, 1px)" should not set the property value +Pass e.style['grid-auto-rows'] = "minmax(6px, -7%)" should not set the property value +Pass e.style['grid-auto-rows'] = "fit-content(-1px)" should not set the property value +Pass e.style['grid-auto-rows'] = "fit-content(1px, 2px)" should not set the property value +Pass e.style['grid-auto-rows'] = "fit-content(1px auto)" should not set the property value Pass e.style['grid-auto-rows'] = "2em / 3em" should not set the property value Pass e.style['grid-auto-rows'] = "auto, 10%" should not set the property value Pass e.style['grid-auto-rows'] = "1px [a] 1px" should not set the property value diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-columns-rows-get-set-multiple.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-columns-rows-get-set-multiple.txt index edf09068564..3698f718b83 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-columns-rows-get-set-multiple.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-columns-rows-get-set-multiple.txt @@ -2,8 +2,8 @@ Harness status: OK Found 40 tests -32 Pass -8 Fail +34 Pass +6 Fail Pass Test getting grid-template-columns and grid-template-rows set through CSS for element 'gridWithFixedElement' : grid-template-columns = '7px 11px', grid-template-rows = '17px 2px' Pass Test getting grid-template-columns and grid-template-rows set through CSS for element 'gridWithPercentElement' : grid-template-columns = '400px 800px', grid-template-rows = '150px 450px' Fail Test getting grid-template-columns and grid-template-rows set through CSS for element 'gridWithPercentWithoutSize' : grid-template-columns = '3.5px 7px', grid-template-rows = '4px 12px' @@ -37,8 +37,8 @@ Pass Test setting bad JS values: grid-template-columns = 'none none', grid-templ Pass Test setting bad JS values: grid-template-columns = 'auto none', grid-template-rows = 'auto none' Pass Test setting bad JS values: grid-template-columns = 'auto none 16em', grid-template-rows = 'auto 18em none' Pass Test setting bad JS values: grid-template-columns = '-webkit-fit-content -webkit-fit-content', grid-template-rows = '-webkit-fit-available -webkit-fit-available' -Fail Test setting bad JS values: grid-template-columns = '-10px minmax(16px, 32px)', grid-template-rows = 'minmax(10%, 15%) -10vw' -Fail Test setting bad JS values: grid-template-columns = '10px minmax(16px, -1vw)', grid-template-rows = 'minmax(-1%, 15%) 10vw' +Pass Test setting bad JS values: grid-template-columns = '-10px minmax(16px, 32px)', grid-template-rows = 'minmax(10%, 15%) -10vw' +Pass Test setting bad JS values: grid-template-columns = '10px minmax(16px, -1vw)', grid-template-rows = 'minmax(-1%, 15%) 10vw' Fail Test setting bad JS values: grid-template-columns = '10px calc(16px 30px)', grid-template-rows = 'calc(25px + auto) 2em' Pass Test setting bad JS values: grid-template-columns = 'minmax(min-content, calc() 250px', grid-template-rows = 'calc(2em(' Fail Test setting grid-template-columns and grid-template-rows to 'inherit' through JS diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-shorthand-invalid.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-shorthand-invalid.txt index c5519e59bb1..c62f2fb9f85 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-shorthand-invalid.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-shorthand-invalid.txt @@ -2,39 +2,38 @@ Harness status: OK Found 34 tests -16 Pass -18 Fail +34 Pass Pass e.style['grid'] = "none none" should not set the property value Pass e.style['grid'] = "none []" should not set the property value -Fail e.style['grid'] = "10px" should not set the property value -Fail e.style['grid'] = "20%" should not set the property value -Fail e.style['grid'] = "5fr" should not set the property value -Fail e.style['grid'] = "[a]" should not set the property value -Fail e.style['grid'] = "[a] 10px" should not set the property value -Fail e.style['grid'] = "[a] 10px []" should not set the property value -Fail e.style['grid'] = "[]" should not set the property value -Fail e.style['grid'] = "10px \"a\"" should not set the property value -Fail e.style['grid'] = "[] 10px \"a\"" should not set the property value -Fail e.style['grid'] = "10px [] \"a\"" should not set the property value +Pass e.style['grid'] = "10px" should not set the property value +Pass e.style['grid'] = "20%" should not set the property value +Pass e.style['grid'] = "5fr" should not set the property value +Pass e.style['grid'] = "[a]" should not set the property value +Pass e.style['grid'] = "[a] 10px" should not set the property value +Pass e.style['grid'] = "[a] 10px []" should not set the property value +Pass e.style['grid'] = "[]" should not set the property value +Pass e.style['grid'] = "10px \"a\"" should not set the property value +Pass e.style['grid'] = "[] 10px \"a\"" should not set the property value +Pass e.style['grid'] = "10px [] \"a\"" should not set the property value Pass e.style['grid'] = "[] [] \"a\"" should not set the property value Pass e.style['grid'] = "\"a\" none" should not set the property value -Fail e.style['grid'] = "\"a\" 10px 10px" should not set the property value -Fail e.style['grid'] = "\"a\" [a] 10px" should not set the property value -Fail e.style['grid'] = "\"a\" [a] 10px [a]" should not set the property value -Fail e.style['grid'] = "\"a\" [a] [a] 10px" should not set the property value -Fail e.style['grid'] = "\"a\" 10px [a] [a]" should not set the property value +Pass e.style['grid'] = "\"a\" 10px 10px" should not set the property value +Pass e.style['grid'] = "\"a\" [a] 10px" should not set the property value +Pass e.style['grid'] = "\"a\" [a] 10px [a]" should not set the property value +Pass e.style['grid'] = "\"a\" [a] [a] 10px" should not set the property value +Pass e.style['grid'] = "\"a\" 10px [a] [a]" should not set the property value Pass e.style['grid'] = "\"a\" [a] [a]" should not set the property value Pass e.style['grid'] = "[a] \"a\" [a] [a]" should not set the property value Pass e.style['grid'] = "\"a\" \"a\" [a] [a]" should not set the property value Pass e.style['grid'] = "\"a\" [a] [a] / none" should not set the property value Pass e.style['grid'] = "\"a\" \"a\" [a] [a] / none" should not set the property value -Fail e.style['grid'] = "none / \"a\"" should not set the property value +Pass e.style['grid'] = "none / \"a\"" should not set the property value Pass e.style['grid'] = "\"a\" / none" should not set the property value -Fail e.style['grid'] = "none / [] \"a\"" should not set the property value +Pass e.style['grid'] = "none / [] \"a\"" should not set the property value Pass e.style['grid'] = "none / \"a\" []" should not set the property value Pass e.style['grid'] = "none / \"a\" [] 10px" should not set the property value Pass e.style['grid'] = "auto-flow 100px" should not set the property value -Fail e.style['grid'] = "auto-flow / auto-flow" should not set the property value +Pass e.style['grid'] = "auto-flow / auto-flow" should not set the property value Pass e.style['grid'] = "auto-flow 1fr / auto-flow 1fr" should not set the property value Pass e.style['grid'] = "dense auto-flow / dense auto-flow" should not set the property value Pass e.style['grid'] = "auto / auto-flow foo()" should not set the property value \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-shorthand-serialization.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-shorthand-serialization.txt index 1ab12064252..a2f2f58cd3a 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-shorthand-serialization.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-shorthand-serialization.txt @@ -2,13 +2,13 @@ Harness status: OK Found 121 tests -59 Pass -62 Fail +84 Pass +37 Fail Fail e.style.cssText = grid: auto-flow auto / 100px 100px should set grid Fail e.style.cssText = grid: auto-flow auto / 100px 100px should set grid-template-areas Pass e.style.cssText = grid: auto-flow auto / 100px 100px; grid-template-areas: "one two" "three four" should set grid -Fail e.style.cssText = grid: auto-flow auto / 100px 100px; grid-template-areas: "one two" "three four" should set grid-auto-flow -Fail e.style.cssText = grid: auto-flow auto / 100px 100px; grid-template-areas: "one two" "three four" should set grid-auto-rows +Pass e.style.cssText = grid: auto-flow auto / 100px 100px; grid-template-areas: "one two" "three four" should set grid-auto-flow +Pass e.style.cssText = grid: auto-flow auto / 100px 100px; grid-template-areas: "one two" "three four" should set grid-auto-rows Pass e.style.cssText = grid: auto-flow auto / 100px 100px; grid-template-areas: "one two" "three four" should set grid-template-areas Fail e.style.cssText = grid: 30px 40px / 50px 60px; grid-auto-flow: column should set grid Pass e.style.cssText = grid: 30px 40px / 50px 60px; grid-auto-flow: column should set grid-auto-flow @@ -17,16 +17,16 @@ Fail cssText ('grid: 30px 40px / 50px 60px; grid-auto-flow: column') must contai Fail cssText ('grid: 30px 40px / 50px 60px; grid-auto-flow: column') must contain 'grid-auto-rows: auto;' in its serialization Fail cssText ('grid: 30px 40px / 50px 60px; grid-auto-flow: column') must contain 'grid-auto-columns: auto;' in its serialization Pass cssText ('grid: 30px 40px / 50px 60px; grid-auto-flow: column') must contain 'grid-auto-flow: column;' in its serialization -Pass e.style.cssText = grid: auto-flow / 10px; grid-template-rows: 20px should set grid -Pass e.style.cssText = grid: auto-flow / 10px; grid-template-rows: 20px should set grid-template -Pass cssText ('grid: auto-flow / 10px; grid-template-rows: 20px') must contain 'grid: 20px / 10px;' in its serialization -Pass e.style.cssText = grid: auto-flow / 10px; grid-template-rows: repeat(2, 20px) should set grid +Fail e.style.cssText = grid: auto-flow / 10px; grid-template-rows: 20px should set grid +Fail e.style.cssText = grid: auto-flow / 10px; grid-template-rows: 20px should set grid-template +Fail cssText ('grid: auto-flow / 10px; grid-template-rows: 20px') must contain 'grid: 20px / 10px;' in its serialization +Fail e.style.cssText = grid: auto-flow / 10px; grid-template-rows: repeat(2, 20px) should set grid Pass e.style.cssText = grid: auto-flow / 10px; grid-template-rows: repeat(2, 20px) should set grid-template-rows -Pass e.style.cssText = grid: auto-flow / 10px; grid-template-rows: repeat(2, 20px) repeat(3, 30px) should set grid +Fail e.style.cssText = grid: auto-flow / 10px; grid-template-rows: repeat(2, 20px) repeat(3, 30px) should set grid Pass e.style.cssText = grid: auto-flow / 10px; grid-template-rows: repeat(2, 20px) repeat(3, 30px) should set grid-template-rows -Pass e.style.cssText = grid: auto-flow / 10px; grid-template-rows: repeat(auto-fill, 20px) should set grid +Fail e.style.cssText = grid: auto-flow / 10px; grid-template-rows: repeat(auto-fill, 20px) should set grid Pass e.style.cssText = grid: auto-flow / 10px; grid-template-rows: repeat(auto-fill, 20px) should set grid-template-rows -Pass e.style.cssText = grid: auto-flow / 10px; grid-template-rows: repeat(auto-fit, 20px) should set grid +Fail e.style.cssText = grid: auto-flow / 10px; grid-template-rows: repeat(auto-fit, 20px) should set grid Pass e.style.cssText = grid: auto-flow / 10px; grid-template-rows: repeat(auto-fit, 20px) should set grid-template-rows Pass e.style.cssText = grid: 10px / auto; grid-template-columns: 20px should set grid Pass e.style.cssText = grid: 10px / auto; grid-template-columns: 20px should set grid-template @@ -51,63 +51,63 @@ Fail e.style.cssText = grid: auto-flow 1px / none; grid-auto-columns: auto shoul Fail e.style.cssText = grid: auto-flow dense / 2px; grid-auto-rows: auto should set grid Pass e.style.cssText = grid: auto-flow 1px / 2px; grid-auto-columns: 3px should set grid Pass e.style.cssText = grid: auto-flow 1px / 2px; grid-auto-columns: 3px should set grid-auto-columns -Fail e.style.cssText = grid: auto-flow 1px / 2px; grid-auto-columns: 3px should set grid-auto-flow -Fail e.style.cssText = grid: auto-flow 1px / 2px; grid-auto-columns: 3px should set grid-auto-rows -Fail e.style.cssText = grid: auto-flow 1px / 2px; grid-auto-columns: 3px should set grid-template-columns +Pass e.style.cssText = grid: auto-flow 1px / 2px; grid-auto-columns: 3px should set grid-auto-flow +Pass e.style.cssText = grid: auto-flow 1px / 2px; grid-auto-columns: 3px should set grid-auto-rows +Pass e.style.cssText = grid: auto-flow 1px / 2px; grid-auto-columns: 3px should set grid-template-columns Fail e.style.cssText = grid: auto-flow 1px / 2px; grid-auto-columns: 3px should set grid-template-rows Pass e.style.cssText = grid: 1px / auto-flow 2px; grid-auto-rows: 3px should set grid -Fail e.style.cssText = grid: 1px / auto-flow 2px; grid-auto-rows: 3px should set grid-auto-columns -Fail e.style.cssText = grid: 1px / auto-flow 2px; grid-auto-rows: 3px should set grid-auto-flow +Pass e.style.cssText = grid: 1px / auto-flow 2px; grid-auto-rows: 3px should set grid-auto-columns +Pass e.style.cssText = grid: 1px / auto-flow 2px; grid-auto-rows: 3px should set grid-auto-flow Pass e.style.cssText = grid: 1px / auto-flow 2px; grid-auto-rows: 3px should set grid-auto-rows Fail e.style.cssText = grid: 1px / auto-flow 2px; grid-auto-rows: 3px should set grid-template-columns -Fail e.style.cssText = grid: 1px / auto-flow 2px; grid-auto-rows: 3px should set grid-template-rows +Pass e.style.cssText = grid: 1px / auto-flow 2px; grid-auto-rows: 3px should set grid-template-rows Pass e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: 3px should set grid -Fail e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: 3px should set grid-auto-columns -Fail e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: 3px should set grid-auto-flow +Pass e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: 3px should set grid-auto-columns +Pass e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: 3px should set grid-auto-flow Fail e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: 3px should set grid-auto-rows Pass e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: 3px should set grid-template-columns -Fail e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: 3px should set grid-template-rows +Pass e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: 3px should set grid-template-rows Pass e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: repeat(2, 3px) should set grid -Fail e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: repeat(2, 3px) should set grid-auto-columns -Fail e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: repeat(2, 3px) should set grid-auto-flow +Pass e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: repeat(2, 3px) should set grid-auto-columns +Pass e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: repeat(2, 3px) should set grid-auto-flow Fail e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: repeat(2, 3px) should set grid-auto-rows Pass e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: repeat(2, 3px) should set grid-template-columns -Fail e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: repeat(2, 3px) should set grid-template-rows +Pass e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: repeat(2, 3px) should set grid-template-rows Pass e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: repeat(auto-fill, 3px) should set grid -Fail e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: repeat(auto-fill, 3px) should set grid-auto-columns -Fail e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: repeat(auto-fill, 3px) should set grid-auto-flow +Pass e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: repeat(auto-fill, 3px) should set grid-auto-columns +Pass e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: repeat(auto-fill, 3px) should set grid-auto-flow Fail e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: repeat(auto-fill, 3px) should set grid-auto-rows Pass e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: repeat(auto-fill, 3px) should set grid-template-columns -Fail e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: repeat(auto-fill, 3px) should set grid-template-rows +Pass e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: repeat(auto-fill, 3px) should set grid-template-rows Pass e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: repeat(auto-fit, 3px) should set grid -Fail e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: repeat(auto-fit, 3px) should set grid-auto-columns -Fail e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: repeat(auto-fit, 3px) should set grid-auto-flow +Pass e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: repeat(auto-fit, 3px) should set grid-auto-columns +Pass e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: repeat(auto-fit, 3px) should set grid-auto-flow Fail e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: repeat(auto-fit, 3px) should set grid-auto-rows Pass e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: repeat(auto-fit, 3px) should set grid-template-columns -Fail e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: repeat(auto-fit, 3px) should set grid-template-rows +Pass e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: repeat(auto-fit, 3px) should set grid-template-rows Pass e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: 3px should set grid Fail e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: 3px should set grid-auto-columns -Fail e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: 3px should set grid-auto-flow -Fail e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: 3px should set grid-auto-rows -Fail e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: 3px should set grid-template-columns +Pass e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: 3px should set grid-auto-flow +Pass e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: 3px should set grid-auto-rows +Pass e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: 3px should set grid-template-columns Pass e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: 3px should set grid-template-rows Pass e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: repeat(2, 3px) should set grid Fail e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: repeat(2, 3px) should set grid-auto-columns -Fail e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: repeat(2, 3px) should set grid-auto-flow -Fail e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: repeat(2, 3px) should set grid-auto-rows -Fail e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: repeat(2, 3px) should set grid-template-columns +Pass e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: repeat(2, 3px) should set grid-auto-flow +Pass e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: repeat(2, 3px) should set grid-auto-rows +Pass e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: repeat(2, 3px) should set grid-template-columns Pass e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: repeat(2, 3px) should set grid-template-rows Pass e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: repeat(auto-fill, 3px) should set grid Fail e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: repeat(auto-fill, 3px) should set grid-auto-columns -Fail e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: repeat(auto-fill, 3px) should set grid-auto-flow -Fail e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: repeat(auto-fill, 3px) should set grid-auto-rows -Fail e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: repeat(auto-fill, 3px) should set grid-template-columns +Pass e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: repeat(auto-fill, 3px) should set grid-auto-flow +Pass e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: repeat(auto-fill, 3px) should set grid-auto-rows +Pass e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: repeat(auto-fill, 3px) should set grid-template-columns Pass e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: repeat(auto-fill, 3px) should set grid-template-rows Pass e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: repeat(auto-fit, 3px) should set grid Fail e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: repeat(auto-fit, 3px) should set grid-auto-columns -Fail e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: repeat(auto-fit, 3px) should set grid-auto-flow -Fail e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: repeat(auto-fit, 3px) should set grid-auto-rows -Fail e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: repeat(auto-fit, 3px) should set grid-template-columns +Pass e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: repeat(auto-fit, 3px) should set grid-auto-flow +Pass e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: repeat(auto-fit, 3px) should set grid-auto-rows +Pass e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: repeat(auto-fit, 3px) should set grid-template-columns Pass e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: repeat(auto-fit, 3px) should set grid-template-rows Fail e.style.cssText = grid-template-rows: auto auto; grid-template-columns: repeat(2, 3px); grid-template-areas: "one two" "three four" should set grid Pass e.style.cssText = grid-template-rows: auto auto; grid-template-columns: repeat(2, 3px); grid-template-areas: "one two" "three four" should set grid-template-areas diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-shorthand-valid.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-shorthand-valid.txt index 1bf04722cb8..c7ed5b7283e 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-shorthand-valid.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-shorthand-valid.txt @@ -2,8 +2,8 @@ Harness status: OK Found 49 tests -7 Pass -42 Fail +8 Pass +41 Fail Pass e.style['grid'] = "none" should set the property value Pass e.style['grid'] = "none / none" should set the property value Pass e.style['grid'] = "auto / auto" should set the property value @@ -11,7 +11,7 @@ Fail e.style['grid'] = "none / [a] 0px" should set the property value Fail e.style['grid'] = "none / [] 0px" should set the property value Fail e.style['grid'] = "[a] 10px / auto" should set the property value Fail e.style['grid'] = "[a] 10px / none" should set the property value -Fail e.style['grid'] = "[] 10px [] / [] auto []" should set the property value +Pass e.style['grid'] = "[] 10px [] / [] auto []" should set the property value Fail e.style['grid'] = "[a] \"a\" 10px" should set the property value Fail e.style['grid'] = "[a] \"a\" 10px []" should set the property value Pass e.style['grid'] = "\"a\" 10px" should set the property value diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-shorthand.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-shorthand.txt index 0713219c85c..e280199a577 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-shorthand.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-shorthand.txt @@ -2,8 +2,8 @@ Harness status: OK Found 63 tests -24 Pass -39 Fail +34 Pass +29 Fail Fail e.style['grid'] = "none" should set grid-auto-columns Fail e.style['grid'] = "none" should set grid-auto-flow Fail e.style['grid'] = "none" should set grid-auto-rows @@ -44,26 +44,26 @@ Fail e.style['grid'] = " \"a a a\" \"b b b\" 1fr/ auto 1fr auto" should set gr Fail e.style['grid'] = " \"a a a\" \"b b b\" 1fr/ auto 1fr auto" should set grid-auto-rows Pass e.style['grid'] = " \"a a a\" \"b b b\" 1fr/ auto 1fr auto" should set grid-template-areas Pass e.style['grid'] = " \"a a a\" \"b b b\" 1fr/ auto 1fr auto" should set grid-template-columns -Fail e.style['grid'] = " \"a a a\" \"b b b\" 1fr/ auto 1fr auto" should set grid-template-rows +Pass e.style['grid'] = " \"a a a\" \"b b b\" 1fr/ auto 1fr auto" should set grid-template-rows Pass e.style['grid'] = " \"a a a\" \"b b b\" 1fr/ auto 1fr auto" should not set unrelated longhands Fail e.style['grid'] = " [] \"a a a\" [] [] \"b b b\" 1fr [] / [] auto 1fr [] auto []" should set grid-auto-columns Fail e.style['grid'] = " [] \"a a a\" [] [] \"b b b\" 1fr [] / [] auto 1fr [] auto []" should set grid-auto-flow Fail e.style['grid'] = " [] \"a a a\" [] [] \"b b b\" 1fr [] / [] auto 1fr [] auto []" should set grid-auto-rows Pass e.style['grid'] = " [] \"a a a\" [] [] \"b b b\" 1fr [] / [] auto 1fr [] auto []" should set grid-template-areas -Fail e.style['grid'] = " [] \"a a a\" [] [] \"b b b\" 1fr [] / [] auto 1fr [] auto []" should set grid-template-columns -Fail e.style['grid'] = " [] \"a a a\" [] [] \"b b b\" 1fr [] / [] auto 1fr [] auto []" should set grid-template-rows +Pass e.style['grid'] = " [] \"a a a\" [] [] \"b b b\" 1fr [] / [] auto 1fr [] auto []" should set grid-template-columns +Pass e.style['grid'] = " [] \"a a a\" [] [] \"b b b\" 1fr [] / [] auto 1fr [] auto []" should set grid-template-rows Pass e.style['grid'] = " [] \"a a a\" [] [] \"b b b\" 1fr [] / [] auto 1fr [] auto []" should not set unrelated longhands -Fail e.style['grid'] = "10px / auto-flow dense 20px" should set grid-auto-columns -Fail e.style['grid'] = "10px / auto-flow dense 20px" should set grid-auto-flow +Pass e.style['grid'] = "10px / auto-flow dense 20px" should set grid-auto-columns +Pass e.style['grid'] = "10px / auto-flow dense 20px" should set grid-auto-flow Fail e.style['grid'] = "10px / auto-flow dense 20px" should set grid-auto-rows Fail e.style['grid'] = "10px / auto-flow dense 20px" should set grid-template-areas Fail e.style['grid'] = "10px / auto-flow dense 20px" should set grid-template-columns -Fail e.style['grid'] = "10px / auto-flow dense 20px" should set grid-template-rows -Fail e.style['grid'] = "10px / auto-flow dense 20px" should not set unrelated longhands +Pass e.style['grid'] = "10px / auto-flow dense 20px" should set grid-template-rows +Pass e.style['grid'] = "10px / auto-flow dense 20px" should not set unrelated longhands Fail e.style['grid'] = "auto-flow dense 30px / 40px" should set grid-auto-columns Fail e.style['grid'] = "auto-flow dense 30px / 40px" should set grid-auto-flow -Fail e.style['grid'] = "auto-flow dense 30px / 40px" should set grid-auto-rows +Pass e.style['grid'] = "auto-flow dense 30px / 40px" should set grid-auto-rows Fail e.style['grid'] = "auto-flow dense 30px / 40px" should set grid-template-areas -Fail e.style['grid'] = "auto-flow dense 30px / 40px" should set grid-template-columns +Pass e.style['grid'] = "auto-flow dense 30px / 40px" should set grid-template-columns Fail e.style['grid'] = "auto-flow dense 30px / 40px" should set grid-template-rows -Fail e.style['grid'] = "auto-flow dense 30px / 40px" should not set unrelated longhands \ No newline at end of file +Pass e.style['grid'] = "auto-flow dense 30px / 40px" should not set unrelated longhands \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-template-columns-invalid.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-template-columns-invalid.txt index 67a5a707e91..7c932738546 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-template-columns-invalid.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-template-columns-invalid.txt @@ -2,20 +2,19 @@ Harness status: OK Found 15 tests -1 Pass -14 Fail -Fail e.style['grid-template-columns'] = "-10px" should not set the property value -Fail e.style['grid-template-columns'] = "-20%" should not set the property value -Fail e.style['grid-template-columns'] = "-5fr" should not set the property value -Fail e.style['grid-template-columns'] = "minmax(5fr, calc(0.5em + 10px))" should not set the property value -Fail e.style['grid-template-columns'] = "minmax(-10px, auto)" should not set the property value -Fail e.style['grid-template-columns'] = "minmax(-20%, max-content)" should not set the property value -Fail e.style['grid-template-columns'] = "minmax(min-content, -20%)" should not set the property value -Fail e.style['grid-template-columns'] = "fit-content(-10px)" should not set the property value -Fail e.style['grid-template-columns'] = "fit-content(-20%)" should not set the property value +15 Pass +Pass e.style['grid-template-columns'] = "-10px" should not set the property value +Pass e.style['grid-template-columns'] = "-20%" should not set the property value +Pass e.style['grid-template-columns'] = "-5fr" should not set the property value +Pass e.style['grid-template-columns'] = "minmax(5fr, calc(0.5em + 10px))" should not set the property value +Pass e.style['grid-template-columns'] = "minmax(-10px, auto)" should not set the property value +Pass e.style['grid-template-columns'] = "minmax(-20%, max-content)" should not set the property value +Pass e.style['grid-template-columns'] = "minmax(min-content, -20%)" should not set the property value +Pass e.style['grid-template-columns'] = "fit-content(-10px)" should not set the property value +Pass e.style['grid-template-columns'] = "fit-content(-20%)" should not set the property value Pass e.style['grid-template-columns'] = "[one] 10px [two three] repeat(20%) [four five six] 3fr [seven]" should not set the property value -Fail e.style['grid-template-columns'] = "[one]" should not set the property value -Fail e.style['grid-template-columns'] = "[one] 10px [two] [three]" should not set the property value -Fail e.style['grid-template-columns'] = "repeat(auto-fill, -10px)" should not set the property value -Fail e.style['grid-template-columns'] = "repeat(auto-fill, 10px) repeat(auto-fit, 20%)" should not set the property value -Fail e.style['grid-template-columns'] = "[auto] 1px" should not set the property value \ No newline at end of file +Pass e.style['grid-template-columns'] = "[one]" should not set the property value +Pass e.style['grid-template-columns'] = "[one] 10px [two] [three]" should not set the property value +Pass e.style['grid-template-columns'] = "repeat(auto-fill, -10px)" should not set the property value +Pass e.style['grid-template-columns'] = "repeat(auto-fill, 10px) repeat(auto-fit, 20%)" should not set the property value +Pass e.style['grid-template-columns'] = "[auto] 1px" should not set the property value \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-template-columns-valid.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-template-columns-valid.txt index 6c77a163e2f..a998ab85afe 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-template-columns-valid.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-template-columns-valid.txt @@ -2,8 +2,7 @@ Harness status: OK Found 34 tests -32 Pass -2 Fail +34 Pass Pass e.style['grid-template-columns'] = "none" should set the property value Pass e.style['grid-template-columns'] = "10px" should set the property value Pass e.style['grid-template-columns'] = "20%" should set the property value @@ -27,12 +26,12 @@ Pass e.style['grid-template-columns'] = "fit-content(20%)" should set the proper Pass e.style['grid-template-columns'] = "fit-content(calc(-0.5em + 10px))" should set the property value Pass e.style['grid-template-columns'] = "fit-content(calc(0.5em + 10px))" should set the property value Pass e.style['grid-template-columns'] = "fit-content(calc(30% + 40vw))" should set the property value -Fail e.style['grid-template-columns'] = "repeat(1, [] 10px [])" should set the property value +Pass e.style['grid-template-columns'] = "repeat(1, [] 10px [])" should set the property value Pass e.style['grid-template-columns'] = "repeat(1, [one two] 20%)" should set the property value Pass e.style['grid-template-columns'] = "repeat(2, minmax(10px, auto))" should set the property value Pass e.style['grid-template-columns'] = "repeat(2, fit-content(20%) [three four] 30px 40px [five six])" should set the property value Pass e.style['grid-template-columns'] = "min-content repeat(5, minmax(10px, auto))" should set the property value -Fail e.style['grid-template-columns'] = "[] 150px [] 1fr []" should set the property value +Pass e.style['grid-template-columns'] = "[] 150px [] 1fr []" should set the property value Pass e.style['grid-template-columns'] = "repeat(auto-fill, 10px)" should set the property value Pass e.style['grid-template-columns'] = "repeat(auto-fit, [one] 20%)" should set the property value Pass e.style['grid-template-columns'] = "repeat(auto-fill, minmax(30px, 5fr) [two])" should set the property value diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-template-rows-invalid.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-template-rows-invalid.txt index adbe41f92de..a671222c4ea 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-template-rows-invalid.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-template-rows-invalid.txt @@ -2,20 +2,19 @@ Harness status: OK Found 15 tests -1 Pass -14 Fail -Fail e.style['grid-template-rows'] = "-10px" should not set the property value -Fail e.style['grid-template-rows'] = "-20%" should not set the property value -Fail e.style['grid-template-rows'] = "-5fr" should not set the property value -Fail e.style['grid-template-rows'] = "minmax(5fr, calc(0.5em + 10px))" should not set the property value -Fail e.style['grid-template-rows'] = "minmax(-10px, auto)" should not set the property value -Fail e.style['grid-template-rows'] = "minmax(-20%, max-content)" should not set the property value -Fail e.style['grid-template-rows'] = "minmax(min-content, -20%)" should not set the property value -Fail e.style['grid-template-rows'] = "fit-content(-10px)" should not set the property value -Fail e.style['grid-template-rows'] = "fit-content(-20%)" should not set the property value +15 Pass +Pass e.style['grid-template-rows'] = "-10px" should not set the property value +Pass e.style['grid-template-rows'] = "-20%" should not set the property value +Pass e.style['grid-template-rows'] = "-5fr" should not set the property value +Pass e.style['grid-template-rows'] = "minmax(5fr, calc(0.5em + 10px))" should not set the property value +Pass e.style['grid-template-rows'] = "minmax(-10px, auto)" should not set the property value +Pass e.style['grid-template-rows'] = "minmax(-20%, max-content)" should not set the property value +Pass e.style['grid-template-rows'] = "minmax(min-content, -20%)" should not set the property value +Pass e.style['grid-template-rows'] = "fit-content(-10px)" should not set the property value +Pass e.style['grid-template-rows'] = "fit-content(-20%)" should not set the property value Pass e.style['grid-template-rows'] = "[one] 10px [two three] repeat(20%) [four five six] 3fr [seven]" should not set the property value -Fail e.style['grid-template-rows'] = "[one]" should not set the property value -Fail e.style['grid-template-rows'] = "[one] 10px [two] [three]" should not set the property value -Fail e.style['grid-template-rows'] = "repeat(auto-fill, -10px)" should not set the property value -Fail e.style['grid-template-rows'] = "repeat(auto-fill, 10px) repeat(auto-fit, 20%)" should not set the property value -Fail e.style['grid-template-rows'] = "[auto] 1px" should not set the property value \ No newline at end of file +Pass e.style['grid-template-rows'] = "[one]" should not set the property value +Pass e.style['grid-template-rows'] = "[one] 10px [two] [three]" should not set the property value +Pass e.style['grid-template-rows'] = "repeat(auto-fill, -10px)" should not set the property value +Pass e.style['grid-template-rows'] = "repeat(auto-fill, 10px) repeat(auto-fit, 20%)" should not set the property value +Pass e.style['grid-template-rows'] = "[auto] 1px" should not set the property value \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-template-rows-valid.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-template-rows-valid.txt index 566d76625da..1ccf4fda382 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-template-rows-valid.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-template-rows-valid.txt @@ -2,8 +2,7 @@ Harness status: OK Found 34 tests -32 Pass -2 Fail +34 Pass Pass e.style['grid-template-rows'] = "none" should set the property value Pass e.style['grid-template-rows'] = "10px" should set the property value Pass e.style['grid-template-rows'] = "20%" should set the property value @@ -27,12 +26,12 @@ Pass e.style['grid-template-rows'] = "fit-content(20%)" should set the property Pass e.style['grid-template-rows'] = "fit-content(calc(-0.5em + 10px))" should set the property value Pass e.style['grid-template-rows'] = "fit-content(calc(0.5em + 10px))" should set the property value Pass e.style['grid-template-rows'] = "fit-content(calc(30% + 40vw))" should set the property value -Fail e.style['grid-template-rows'] = "repeat(1, [] 10px [])" should set the property value +Pass e.style['grid-template-rows'] = "repeat(1, [] 10px [])" should set the property value Pass e.style['grid-template-rows'] = "repeat(1, [one two] 20%)" should set the property value Pass e.style['grid-template-rows'] = "repeat(2, minmax(10px, auto))" should set the property value Pass e.style['grid-template-rows'] = "repeat(2, fit-content(20%) [three four] 30px 40px [five six])" should set the property value Pass e.style['grid-template-rows'] = "min-content repeat(5, minmax(10px, auto))" should set the property value -Fail e.style['grid-template-rows'] = "[] 150px [] 1fr []" should set the property value +Pass e.style['grid-template-rows'] = "[] 150px [] 1fr []" should set the property value Pass e.style['grid-template-rows'] = "repeat(auto-fill, 10px)" should set the property value Pass e.style['grid-template-rows'] = "repeat(auto-fit, [one] 20%)" should set the property value Pass e.style['grid-template-rows'] = "repeat(auto-fill, minmax(30px, 5fr) [two])" should set the property value diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-template-shorthand-invalid.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-template-shorthand-invalid.txt index 16632b34461..a2a237fc95e 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-template-shorthand-invalid.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-template-shorthand-invalid.txt @@ -2,69 +2,68 @@ Harness status: OK Found 66 tests -15 Pass -51 Fail -Fail e.style['grid-template'] = "auto" should not set the property value +66 Pass +Pass e.style['grid-template'] = "auto" should not set the property value Pass e.style['grid-template'] = "none none" should not set the property value Pass e.style['grid-template'] = "none []" should not set the property value -Fail e.style['grid-template'] = "10px" should not set the property value -Fail e.style['grid-template'] = "20%" should not set the property value -Fail e.style['grid-template'] = "5fr" should not set the property value -Fail e.style['grid-template'] = "[a]" should not set the property value -Fail e.style['grid-template'] = "[a] 10px" should not set the property value -Fail e.style['grid-template'] = "[a] repeat(2, 10px)" should not set the property value -Fail e.style['grid-template'] = "[a] repeat(auto-fill, 10px)" should not set the property value -Fail e.style['grid-template'] = "[a] repeat(auto-fit, 10px)" should not set the property value -Fail e.style['grid-template'] = "[a] 10px []" should not set the property value -Fail e.style['grid-template'] = "[a] repeat(2, 10px) []" should not set the property value -Fail e.style['grid-template'] = "[a] repeat(auto-fill, 10px) []" should not set the property value -Fail e.style['grid-template'] = "[a] repeat(auto-fit, 10px) []" should not set the property value -Fail e.style['grid-template'] = "[]" should not set the property value -Fail e.style['grid-template'] = "10px \"a\"" should not set the property value -Fail e.style['grid-template'] = "repeat(2, 10px) \"a\"" should not set the property value -Fail e.style['grid-template'] = "repeat(auto-fill, 10px) \"a\"" should not set the property value -Fail e.style['grid-template'] = "repeat(auto-fit, 10px) \"a\"" should not set the property value -Fail e.style['grid-template'] = "[] 10px \"a\"" should not set the property value -Fail e.style['grid-template'] = "[] repeat(2, 10px) \"a\"" should not set the property value -Fail e.style['grid-template'] = "[] repeat(auto-fill, 10px) \"a\"" should not set the property value -Fail e.style['grid-template'] = "[] repeat(auto-fit, 10px) \"a\"" should not set the property value -Fail e.style['grid-template'] = "10px [] \"a\"" should not set the property value -Fail e.style['grid-template'] = "repeat(2, 10px) [] \"a\"" should not set the property value -Fail e.style['grid-template'] = "repeat(auto-fill, 10px) [] \"a\"" should not set the property value -Fail e.style['grid-template'] = "repeat(auto-fit, 10px) [] \"a\"" should not set the property value +Pass e.style['grid-template'] = "10px" should not set the property value +Pass e.style['grid-template'] = "20%" should not set the property value +Pass e.style['grid-template'] = "5fr" should not set the property value +Pass e.style['grid-template'] = "[a]" should not set the property value +Pass e.style['grid-template'] = "[a] 10px" should not set the property value +Pass e.style['grid-template'] = "[a] repeat(2, 10px)" should not set the property value +Pass e.style['grid-template'] = "[a] repeat(auto-fill, 10px)" should not set the property value +Pass e.style['grid-template'] = "[a] repeat(auto-fit, 10px)" should not set the property value +Pass e.style['grid-template'] = "[a] 10px []" should not set the property value +Pass e.style['grid-template'] = "[a] repeat(2, 10px) []" should not set the property value +Pass e.style['grid-template'] = "[a] repeat(auto-fill, 10px) []" should not set the property value +Pass e.style['grid-template'] = "[a] repeat(auto-fit, 10px) []" should not set the property value +Pass e.style['grid-template'] = "[]" should not set the property value +Pass e.style['grid-template'] = "10px \"a\"" should not set the property value +Pass e.style['grid-template'] = "repeat(2, 10px) \"a\"" should not set the property value +Pass e.style['grid-template'] = "repeat(auto-fill, 10px) \"a\"" should not set the property value +Pass e.style['grid-template'] = "repeat(auto-fit, 10px) \"a\"" should not set the property value +Pass e.style['grid-template'] = "[] 10px \"a\"" should not set the property value +Pass e.style['grid-template'] = "[] repeat(2, 10px) \"a\"" should not set the property value +Pass e.style['grid-template'] = "[] repeat(auto-fill, 10px) \"a\"" should not set the property value +Pass e.style['grid-template'] = "[] repeat(auto-fit, 10px) \"a\"" should not set the property value +Pass e.style['grid-template'] = "10px [] \"a\"" should not set the property value +Pass e.style['grid-template'] = "repeat(2, 10px) [] \"a\"" should not set the property value +Pass e.style['grid-template'] = "repeat(auto-fill, 10px) [] \"a\"" should not set the property value +Pass e.style['grid-template'] = "repeat(auto-fit, 10px) [] \"a\"" should not set the property value Pass e.style['grid-template'] = "[] [] \"a\"" should not set the property value Pass e.style['grid-template'] = "\"a\" none" should not set the property value -Fail e.style['grid-template'] = "\"a\" 10px 10px" should not set the property value -Fail e.style['grid-template'] = "\"a\" repeat(2, 10px) 10px" should not set the property value -Fail e.style['grid-template'] = "\"a\" 10px repeat(2, 10px)" should not set the property value -Fail e.style['grid-template'] = "\"a\" repeat(auto-fill, 10px) 10px" should not set the property value -Fail e.style['grid-template'] = "\"a\" 10px repeat(auto-fill, 10px)" should not set the property value -Fail e.style['grid-template'] = "\"a\" repeat(auto-fit, 10px) 10px" should not set the property value -Fail e.style['grid-template'] = "\"a\" 10px repeat(auto-fit, 10px)" should not set the property value -Fail e.style['grid-template'] = "\"a\" [a] 10px" should not set the property value -Fail e.style['grid-template'] = "\"a\" [a] repeat(2, 10px)" should not set the property value -Fail e.style['grid-template'] = "\"a\" [a] repeat(auto-fill, 10px)" should not set the property value -Fail e.style['grid-template'] = "\"a\" [a] repeat(auto-fit, 10px)" should not set the property value -Fail e.style['grid-template'] = "\"a\" [a] 10px [a]" should not set the property value -Fail e.style['grid-template'] = "\"a\" [a] repeat(2, 10px) [a]" should not set the property value -Fail e.style['grid-template'] = "\"a\" [a] repeat(auto-fill, 10px) [a]" should not set the property value -Fail e.style['grid-template'] = "\"a\" [a] repeat(auto-fit, 10px) [a]" should not set the property value -Fail e.style['grid-template'] = "\"a\" [a] [a] 10px" should not set the property value -Fail e.style['grid-template'] = "\"a\" [a] [a] repeat(2, 10px)" should not set the property value -Fail e.style['grid-template'] = "\"a\" [a] [a] repeat(auto-fill, 10px)" should not set the property value -Fail e.style['grid-template'] = "\"a\" [a] [a] repeat(auto-fit, 10px)" should not set the property value -Fail e.style['grid-template'] = "\"a\" 10px [a] [a]" should not set the property value -Fail e.style['grid-template'] = "\"a\" repeat(2, 10px) [a] [a]" should not set the property value -Fail e.style['grid-template'] = "\"a\" repeat(auto-fill, 10px) [a] [a]" should not set the property value -Fail e.style['grid-template'] = "\"a\" repeat(auto-fit, 10px) [a] [a]" should not set the property value +Pass e.style['grid-template'] = "\"a\" 10px 10px" should not set the property value +Pass e.style['grid-template'] = "\"a\" repeat(2, 10px) 10px" should not set the property value +Pass e.style['grid-template'] = "\"a\" 10px repeat(2, 10px)" should not set the property value +Pass e.style['grid-template'] = "\"a\" repeat(auto-fill, 10px) 10px" should not set the property value +Pass e.style['grid-template'] = "\"a\" 10px repeat(auto-fill, 10px)" should not set the property value +Pass e.style['grid-template'] = "\"a\" repeat(auto-fit, 10px) 10px" should not set the property value +Pass e.style['grid-template'] = "\"a\" 10px repeat(auto-fit, 10px)" should not set the property value +Pass e.style['grid-template'] = "\"a\" [a] 10px" should not set the property value +Pass e.style['grid-template'] = "\"a\" [a] repeat(2, 10px)" should not set the property value +Pass e.style['grid-template'] = "\"a\" [a] repeat(auto-fill, 10px)" should not set the property value +Pass e.style['grid-template'] = "\"a\" [a] repeat(auto-fit, 10px)" should not set the property value +Pass e.style['grid-template'] = "\"a\" [a] 10px [a]" should not set the property value +Pass e.style['grid-template'] = "\"a\" [a] repeat(2, 10px) [a]" should not set the property value +Pass e.style['grid-template'] = "\"a\" [a] repeat(auto-fill, 10px) [a]" should not set the property value +Pass e.style['grid-template'] = "\"a\" [a] repeat(auto-fit, 10px) [a]" should not set the property value +Pass e.style['grid-template'] = "\"a\" [a] [a] 10px" should not set the property value +Pass e.style['grid-template'] = "\"a\" [a] [a] repeat(2, 10px)" should not set the property value +Pass e.style['grid-template'] = "\"a\" [a] [a] repeat(auto-fill, 10px)" should not set the property value +Pass e.style['grid-template'] = "\"a\" [a] [a] repeat(auto-fit, 10px)" should not set the property value +Pass e.style['grid-template'] = "\"a\" 10px [a] [a]" should not set the property value +Pass e.style['grid-template'] = "\"a\" repeat(2, 10px) [a] [a]" should not set the property value +Pass e.style['grid-template'] = "\"a\" repeat(auto-fill, 10px) [a] [a]" should not set the property value +Pass e.style['grid-template'] = "\"a\" repeat(auto-fit, 10px) [a] [a]" should not set the property value Pass e.style['grid-template'] = "\"a\" [a] [a]" should not set the property value Pass e.style['grid-template'] = "[a] \"a\" [a] [a]" should not set the property value Pass e.style['grid-template'] = "\"a\" \"a\" [a] [a]" should not set the property value Pass e.style['grid-template'] = "\"a\" [a] [a] / none" should not set the property value Pass e.style['grid-template'] = "\"a\" \"a\" [a] [a] / none" should not set the property value -Fail e.style['grid-template'] = "none / \"a\"" should not set the property value +Pass e.style['grid-template'] = "none / \"a\"" should not set the property value Pass e.style['grid-template'] = "\"a\" / none" should not set the property value -Fail e.style['grid-template'] = "none / [] \"a\"" should not set the property value +Pass e.style['grid-template'] = "none / [] \"a\"" should not set the property value Pass e.style['grid-template'] = "none / \"a\" []" should not set the property value Pass e.style['grid-template'] = "none / \"a\" [] 10px" should not set the property value Pass e.style['grid-template'] = "none / \"a\" [] repeat(2, 10px)" should not set the property value diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-template-shorthand-valid.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-template-shorthand-valid.txt index a19f0668a84..9d82224c85d 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-template-shorthand-valid.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-template-shorthand-valid.txt @@ -2,8 +2,8 @@ Harness status: OK Found 40 tests -7 Pass -33 Fail +8 Pass +32 Fail Pass e.style['grid-template'] = "none" should set the property value Pass e.style['grid-template'] = "none / none" should set the property value Pass e.style['grid-template'] = "auto / auto" should set the property value @@ -11,7 +11,7 @@ Fail e.style['grid-template'] = "none / [a] 0px" should set the property value Fail e.style['grid-template'] = "none / [] 0px" should set the property value Fail e.style['grid-template'] = "[a] 10px / auto" should set the property value Fail e.style['grid-template'] = "[a] 10px / none" should set the property value -Fail e.style['grid-template'] = "[] 10px [] / [] auto []" should set the property value +Pass e.style['grid-template'] = "[] 10px [] / [] auto []" should set the property value Fail e.style['grid-template'] = "[a] \"a\" 10px" should set the property value Fail e.style['grid-template'] = "[a] \"a\" 10px []" should set the property value Pass e.style['grid-template'] = "\"a\" 10px" should set the property value diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-template-shorthand.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-template-shorthand.txt index b9f5df48468..b4d46b1313f 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-template-shorthand.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-grid/parsing/grid-template-shorthand.txt @@ -2,8 +2,8 @@ Harness status: OK Found 24 tests -20 Pass -4 Fail +23 Pass +1 Fail Pass e.style['grid-template'] = "none" should set grid-template-areas Pass e.style['grid-template'] = "none" should set grid-template-columns Pass e.style['grid-template'] = "none" should set grid-template-rows @@ -22,9 +22,9 @@ Fail e.style['grid-template'] = "[header-top] \"a a a\" [header-bottom] [ma Pass e.style['grid-template'] = "[header-top] \"a a a\" [header-bottom] [main-top] \"b b b\" 1fr [main-bottom] / auto 1fr auto" should not set unrelated longhands Pass e.style['grid-template'] = " \"a a a\" \"b b b\" 1fr/ auto 1fr auto" should set grid-template-areas Pass e.style['grid-template'] = " \"a a a\" \"b b b\" 1fr/ auto 1fr auto" should set grid-template-columns -Fail e.style['grid-template'] = " \"a a a\" \"b b b\" 1fr/ auto 1fr auto" should set grid-template-rows +Pass e.style['grid-template'] = " \"a a a\" \"b b b\" 1fr/ auto 1fr auto" should set grid-template-rows Pass e.style['grid-template'] = " \"a a a\" \"b b b\" 1fr/ auto 1fr auto" should not set unrelated longhands Pass e.style['grid-template'] = " [] \"a a a\" [] [] \"b b b\" 1fr [] / [] auto 1fr [] auto []" should set grid-template-areas -Fail e.style['grid-template'] = " [] \"a a a\" [] [] \"b b b\" 1fr [] / [] auto 1fr [] auto []" should set grid-template-columns -Fail e.style['grid-template'] = " [] \"a a a\" [] [] \"b b b\" 1fr [] / [] auto 1fr [] auto []" should set grid-template-rows +Pass e.style['grid-template'] = " [] \"a a a\" [] [] \"b b b\" 1fr [] / [] auto 1fr [] auto []" should set grid-template-columns +Pass e.style['grid-template'] = " [] \"a a a\" [] [] \"b b b\" 1fr [] / [] auto 1fr [] auto []" should set grid-template-rows Pass e.style['grid-template'] = " [] \"a a a\" [] [] \"b b b\" 1fr [] / [] auto 1fr [] auto []" should not set unrelated longhands \ No newline at end of file