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.
This commit is contained in:
Aliaksandr Kalenik 2025-06-16 22:27:17 +02:00 committed by Alexander Kalenik
commit af602b2555
Notes: github-actions[bot] 2025-06-21 20:08:32 +00:00
23 changed files with 894 additions and 574 deletions

View file

@ -120,16 +120,10 @@ String GridMinMax::to_string() const
return MUST(builder.to_string()); return MUST(builder.to_string());
} }
GridRepeat::GridRepeat(GridTrackSizeList grid_track_size_list, int repeat_count) GridRepeat::GridRepeat(GridTrackSizeList&& grid_track_size_list, GridRepeatParams const& params)
: m_type(Type::Default) : m_type(params.type)
, m_grid_track_size_list(grid_track_size_list) , m_grid_track_size_list(move(grid_track_size_list))
, m_repeat_count(repeat_count) , m_repeat_count(params.count)
{
}
GridRepeat::GridRepeat(GridTrackSizeList grid_track_size_list, Type type)
: m_type(type)
, m_grid_track_size_list(grid_track_size_list)
{ {
} }
@ -138,13 +132,13 @@ String GridRepeat::to_string() const
StringBuilder builder; StringBuilder builder;
builder.append("repeat("sv); builder.append("repeat("sv);
switch (m_type) { switch (m_type) {
case Type::AutoFit: case GridRepeatType::AutoFit:
builder.append("auto-fit"sv); builder.append("auto-fit"sv);
break; break;
case Type::AutoFill: case GridRepeatType::AutoFill:
builder.append("auto-fill"sv); builder.append("auto-fill"sv);
break; break;
case Type::Default: case GridRepeatType::Fixed:
builder.appendff("{}", m_repeat_count); builder.appendff("{}", m_repeat_count);
break; break;
default: default:
@ -177,15 +171,6 @@ String GridLineNames::to_string() const
return MUST(builder.to_string()); return MUST(builder.to_string());
} }
GridTrackSizeList::GridTrackSizeList(Vector<Variant<ExplicitGridTrack, GridLineNames>>&& list)
: m_list(move(list))
{
}
GridTrackSizeList::GridTrackSizeList()
{
}
GridTrackSizeList GridTrackSizeList::make_none() GridTrackSizeList GridTrackSizeList::make_none()
{ {
return GridTrackSizeList(); return GridTrackSizeList();
@ -222,4 +207,14 @@ Vector<ExplicitGridTrack> GridTrackSizeList::track_list() const
bool GridTrackSizeList::operator==(GridTrackSizeList const& other) const = default; 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));
}
} }

View file

@ -7,6 +7,7 @@
#pragma once #pragma once
#include <AK/FlyString.h>
#include <AK/Vector.h> #include <AK/Vector.h>
#include <LibWeb/CSS/PercentageOr.h> #include <LibWeb/CSS/PercentageOr.h>
#include <LibWeb/Layout/AvailableSpace.h> #include <LibWeb/Layout/AvailableSpace.h>
@ -78,7 +79,7 @@ private:
}; };
struct GridLineNames { struct GridLineNames {
Vector<String> names; Vector<FlyString> names;
String to_string() const; String to_string() const;
bool operator==(GridLineNames const& other) const = default; bool operator==(GridLineNames const& other) const = default;
@ -86,9 +87,6 @@ struct GridLineNames {
class GridTrackSizeList { class GridTrackSizeList {
public: public:
GridTrackSizeList(Vector<Variant<ExplicitGridTrack, GridLineNames>>&& list);
GridTrackSizeList();
static GridTrackSizeList make_none(); static GridTrackSizeList make_none();
Vector<CSS::ExplicitGridTrack> track_list() const; Vector<CSS::ExplicitGridTrack> track_list() const;
@ -97,38 +95,48 @@ public:
String to_string() const; String to_string() const;
bool operator==(GridTrackSizeList const& other) const; bool operator==(GridTrackSizeList const& other) const;
bool is_empty() const { return m_list.is_empty(); }
void append(GridLineNames&&);
void append(ExplicitGridTrack&&);
private: private:
Vector<Variant<ExplicitGridTrack, GridLineNames>> m_list; Vector<Variant<ExplicitGridTrack, GridLineNames>> m_list;
}; };
class GridRepeat { enum class GridRepeatType {
public:
enum class Type {
AutoFit, AutoFit,
AutoFill, AutoFill,
Default, Fixed,
}; };
GridRepeat(GridTrackSizeList, int repeat_count);
GridRepeat(GridTrackSizeList, Type);
bool is_auto_fill() const { return m_type == Type::AutoFill; } struct GridRepeatParams {
bool is_auto_fit() const { return m_type == Type::AutoFit; } GridRepeatType type;
bool is_default() const { return m_type == Type::Default; } size_t count { 0 };
int repeat_count() const };
class GridRepeat {
public:
GridRepeat(GridTrackSizeList&&, GridRepeatParams 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; return m_repeat_count;
} }
GridTrackSizeList const& grid_track_size_list() const& { return m_grid_track_size_list; } 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; String to_string() const;
bool operator==(GridRepeat const& other) const = default; bool operator==(GridRepeat const& other) const = default;
private: private:
Type m_type; GridRepeatType m_type;
GridTrackSizeList m_grid_track_size_list; GridTrackSizeList m_grid_track_size_list;
int m_repeat_count { 0 }; size_t m_repeat_count { 0 };
}; };
class ExplicitGridTrack { class ExplicitGridTrack {

View file

@ -282,11 +282,35 @@ private:
Optional<Gfx::UnicodeRange> parse_unicode_range(StringView); Optional<Gfx::UnicodeRange> parse_unicode_range(StringView);
Vector<Gfx::UnicodeRange> parse_unicode_ranges(TokenStream<ComponentValue>&); Vector<Gfx::UnicodeRange> parse_unicode_ranges(TokenStream<ComponentValue>&);
RefPtr<UnicodeRangeStyleValue const> parse_unicode_range_value(TokenStream<ComponentValue>&); RefPtr<UnicodeRangeStyleValue const> parse_unicode_range_value(TokenStream<ComponentValue>&);
Optional<GridSize> parse_grid_size(ComponentValue const&);
Optional<GridSize> parse_grid_fit_content(Vector<ComponentValue> const&); Optional<GridSize> parse_grid_track_breadth(TokenStream<ComponentValue>&);
Optional<GridMinMax> parse_min_max(Vector<ComponentValue> const&); Optional<GridSize> parse_grid_inflexible_breadth(TokenStream<ComponentValue>&);
Optional<GridRepeat> parse_repeat(Vector<ComponentValue> const&); Optional<GridSize> parse_grid_fixed_breadth(TokenStream<ComponentValue>&);
Optional<ExplicitGridTrack> parse_track_sizing_function(ComponentValue const&);
Optional<GridLineNames> parse_grid_line_names(TokenStream<ComponentValue>&);
Optional<GridRepeat> parse_grid_track_repeat(TokenStream<ComponentValue>&);
Optional<GridRepeat> parse_grid_auto_repeat(TokenStream<ComponentValue>&);
Optional<GridRepeat> parse_grid_fixed_repeat(TokenStream<ComponentValue>&);
using GridRepeatTypeParser = AK::Function<Optional<GridRepeatParams>(TokenStream<ComponentValue>&)>;
using GridTrackParser = AK::Function<Optional<ExplicitGridTrack>(TokenStream<ComponentValue>&)>;
Optional<GridRepeat> parse_grid_track_repeat_impl(TokenStream<ComponentValue>&, GridRepeatTypeParser const&, GridTrackParser const&);
using GridMinMaxParamParser = AK::Function<Optional<GridSize>(TokenStream<ComponentValue>&)>;
Optional<ExplicitGridTrack> parse_grid_minmax(TokenStream<ComponentValue>&, GridMinMaxParamParser const&, GridMinMaxParamParser const&);
Optional<ExplicitGridTrack> parse_grid_track_size(TokenStream<ComponentValue>&);
Optional<ExplicitGridTrack> parse_grid_fixed_size(TokenStream<ComponentValue>&);
enum class AllowTrailingLineNamesForEachTrack {
Yes,
No
};
[[nodiscard]] size_t parse_track_list_impl(TokenStream<ComponentValue>& tokens, GridTrackSizeList& output, GridTrackParser const& track_parsing_callback, AllowTrailingLineNamesForEachTrack = AllowTrailingLineNamesForEachTrack::No);
GridTrackSizeList parse_grid_track_list(TokenStream<ComponentValue>&);
GridTrackSizeList parse_grid_auto_track_list(TokenStream<ComponentValue>&);
GridTrackSizeList parse_explicit_track_list(TokenStream<ComponentValue>&);
Optional<URL> parse_url_function(TokenStream<ComponentValue>&); Optional<URL> parse_url_function(TokenStream<ComponentValue>&);
RefPtr<URLStyleValue const> parse_url_value(TokenStream<ComponentValue>&); RefPtr<URLStyleValue const> parse_url_value(TokenStream<ComponentValue>&);
@ -437,7 +461,7 @@ private:
RefPtr<CSSStyleValue const> parse_transition_property_value(TokenStream<ComponentValue>&); RefPtr<CSSStyleValue const> parse_transition_property_value(TokenStream<ComponentValue>&);
RefPtr<CSSStyleValue const> parse_translate_value(TokenStream<ComponentValue>&); RefPtr<CSSStyleValue const> parse_translate_value(TokenStream<ComponentValue>&);
RefPtr<CSSStyleValue const> parse_scale_value(TokenStream<ComponentValue>&); RefPtr<CSSStyleValue const> parse_scale_value(TokenStream<ComponentValue>&);
RefPtr<CSSStyleValue const> parse_grid_track_size_list(TokenStream<ComponentValue>&, bool allow_separate_line_name_blocks = false); RefPtr<CSSStyleValue const> parse_grid_track_size_list(TokenStream<ComponentValue>&);
RefPtr<CSSStyleValue const> parse_grid_auto_track_sizes(TokenStream<ComponentValue>&); RefPtr<CSSStyleValue const> parse_grid_auto_track_sizes(TokenStream<ComponentValue>&);
RefPtr<GridAutoFlowStyleValue const> parse_grid_auto_flow_value(TokenStream<ComponentValue>&); RefPtr<GridAutoFlowStyleValue const> parse_grid_auto_flow_value(TokenStream<ComponentValue>&);
RefPtr<CSSStyleValue const> parse_grid_track_size_list_shorthand_value(PropertyID, TokenStream<ComponentValue>&); RefPtr<CSSStyleValue const> parse_grid_track_size_list_shorthand_value(PropertyID, TokenStream<ComponentValue>&);

View file

@ -8,6 +8,7 @@
* Copyright (c) 2024, Tommy van der Vorst <tommy@pixelspark.nl> * Copyright (c) 2024, Tommy van der Vorst <tommy@pixelspark.nl>
* Copyright (c) 2024, Matthew Olsson <mattco@serenityos.org> * Copyright (c) 2024, Matthew Olsson <mattco@serenityos.org>
* Copyright (c) 2024, Glenn Skrzypczak <glenn.skrzypczak@gmail.com> * Copyright (c) 2024, Glenn Skrzypczak <glenn.skrzypczak@gmail.com>
* Copyright (c) 2025, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -4324,60 +4325,91 @@ RefPtr<CSSStyleValue const> Parser::parse_grid_track_placement_shorthand_value(P
// 7.4. Explicit Grid Shorthand: the grid-template property // 7.4. Explicit Grid Shorthand: the grid-template property
RefPtr<CSSStyleValue const> Parser::parse_grid_track_size_list_shorthand_value(PropertyID property_id, TokenStream<ComponentValue>& tokens) RefPtr<CSSStyleValue const> Parser::parse_grid_track_size_list_shorthand_value(PropertyID property_id, TokenStream<ComponentValue>& tokens)
{ {
// The grid-template property is a shorthand for setting grid-template-columns, grid-template-rows, auto empty_grid_areas = GridTemplateAreaStyleValue::create({});
// and grid-template-areas in a single declaration. It has several distinct syntax forms: auto empty_grid_track_size_list = GridTrackSizeListStyleValue::create({});
// none // none
// - Sets all three properties to their initial values (none). {
// <'grid-template-rows'> / <'grid-template-columns'> if (parse_all_as_single_keyword_value(tokens, Keyword::None)) {
// - Sets grid-template-rows and grid-template-columns to the specified values, respectively, and sets grid-template-areas to 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 });
}
}
// [ <'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() });
}
}
}
}
// [ <line-names>? <string> <track-size>? <line-names>? ]+ [ / <explicit-track-list> ]? // [ <line-names>? <string> <track-size>? <line-names>? ]+ [ / <explicit-track-list> ]?
// - Sets grid-template-areas to the strings listed. {
// - Sets grid-template-rows to the <track-size>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(); auto transaction = tokens.begin_transaction();
// FIXME: Read the parts in place if possible, instead of constructing separate vectors and streams. GridTrackSizeList track_list;
Vector<ComponentValue> template_rows_tokens; Vector<ComponentValue> area_tokens;
Vector<ComponentValue> template_columns_tokens;
Vector<ComponentValue> template_area_tokens;
bool found_forward_slash = false; GridTrackParser parse_grid_track = [&](TokenStream<ComponentValue>& tokens) -> Optional<ExplicitGridTrack> {
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());
};
while (tokens.has_next_token()) { auto parsed_track_count = parse_track_list_impl(tokens, track_list, parse_grid_track, AllowTrailingLineNamesForEachTrack::Yes);
auto& token = tokens.consume_a_token(); if (parsed_track_count > 0) {
if (token.is_delim('/')) { TokenStream area_tokens_stream { area_tokens };
if (found_forward_slash) auto grid_areas = parse_grid_template_areas_value(area_tokens_stream);
if (!grid_areas)
return nullptr; return nullptr;
found_forward_slash = true;
continue;
}
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 }; auto rows_track_list = GridTrackSizeListStyleValue::create(move(track_list));
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);
if (template_area_token_stream.has_next_token() tokens.discard_whitespace();
|| template_rows_token_stream.has_next_token()
|| template_columns_token_stream.has_next_token()) RefPtr<CSSStyleValue const> 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; return nullptr;
}
} else if (tokens.has_next_token()) {
return nullptr;
}
transaction.commit(); transaction.commit();
return ShorthandStyleValue::create(property_id, return ShorthandStyleValue::create(property_id,
{ PropertyID::GridTemplateAreas, PropertyID::GridTemplateRows, PropertyID::GridTemplateColumns }, { PropertyID::GridTemplateAreas, PropertyID::GridTemplateRows, PropertyID::GridTemplateColumns },
{ parsed_template_areas_values.release_nonnull(), parsed_template_rows_values.release_nonnull(), parsed_template_columns_values.release_nonnull() }); { grid_areas.release_nonnull(), rows_track_list, columns_track_list.release_nonnull() });
}
}
return nullptr;
} }
RefPtr<CSSStyleValue const> Parser::parse_grid_area_shorthand_value(TokenStream<ComponentValue>& tokens) RefPtr<CSSStyleValue const> Parser::parse_grid_area_shorthand_value(TokenStream<ComponentValue>& tokens)
@ -4471,10 +4503,103 @@ RefPtr<CSSStyleValue const> Parser::parse_grid_area_shorthand_value(TokenStream<
RefPtr<CSSStyleValue const> Parser::parse_grid_shorthand_value(TokenStream<ComponentValue>& tokens) RefPtr<CSSStyleValue const> Parser::parse_grid_shorthand_value(TokenStream<ComponentValue>& tokens)
{ {
// <'grid-template'> | // <'grid-template'>
// FIXME: <'grid-template-rows'> / [ auto-flow && dense? ] <'grid-auto-columns'>? | if (auto grid_template = parse_grid_track_size_list_shorthand_value(PropertyID::Grid, tokens)) {
// FIXME: [ auto-flow && dense? ] <'grid-auto-rows'>? / <'grid-template-columns'> return grid_template;
return parse_grid_track_size_list_shorthand_value(PropertyID::Grid, tokens); }
auto parse_auto_flow_and_dense = [&](GridAutoFlowStyleValue::Axis axis) -> RefPtr<GridAutoFlowStyleValue const> {
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<CSSStyleValue const> {
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<CSSStyleValue const> {
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 // https://www.w3.org/TR/css-grid-1/#grid-template-areas-property
@ -4543,21 +4668,18 @@ RefPtr<CSSStyleValue const> Parser::parse_grid_auto_track_sizes(TokenStream<Comp
{ {
// https://www.w3.org/TR/css-grid-2/#auto-tracks // https://www.w3.org/TR/css-grid-2/#auto-tracks
// <track-size>+ // <track-size>+
Vector<Variant<ExplicitGridTrack, GridLineNames>> track_list;
auto transaction = tokens.begin_transaction(); auto transaction = tokens.begin_transaction();
GridTrackSizeList track_list;
while (tokens.has_next_token()) { while (tokens.has_next_token()) {
auto const& token = tokens.consume_a_token(); tokens.discard_whitespace();
auto track_sizing_function = parse_track_sizing_function(token); auto track_size = parse_grid_track_size(tokens);
if (!track_sizing_function.has_value()) { if (!track_size.has_value())
transaction.commit(); break;
return GridTrackSizeListStyleValue::make_auto(); track_list.append(track_size.release_value());
}
// 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());
} }
if (!track_list.is_empty())
transaction.commit(); transaction.commit();
return GridTrackSizeListStyleValue::create(GridTrackSizeList(move(track_list))); return GridTrackSizeListStyleValue::create(move(track_list));
} }
// https://www.w3.org/TR/css-grid-1/#grid-auto-flow-property // https://www.w3.org/TR/css-grid-1/#grid-auto-flow-property
@ -4613,51 +4735,34 @@ RefPtr<GridAutoFlowStyleValue const> Parser::parse_grid_auto_flow_value(TokenStr
return GridAutoFlowStyleValue::create(axis.value_or(GridAutoFlowStyleValue::Axis::Row), dense.value_or(GridAutoFlowStyleValue::Dense::No)); return GridAutoFlowStyleValue::create(axis.value_or(GridAutoFlowStyleValue::Axis::Row), dense.value_or(GridAutoFlowStyleValue::Dense::No));
} }
RefPtr<CSSStyleValue const> Parser::parse_grid_track_size_list(TokenStream<ComponentValue>& tokens, bool allow_separate_line_name_blocks) // https://www.w3.org/TR/css-grid-2/#track-sizing
RefPtr<CSSStyleValue const> Parser::parse_grid_track_size_list(TokenStream<ComponentValue>& tokens)
{ {
if (auto none = parse_all_as_single_keyword_value(tokens, Keyword::None)) // none | <track-list> | <auto-track-list> | FIXME subgrid <line-name-list>?
return GridTrackSizeListStyleValue::make_none();
// none
{
auto transaction = tokens.begin_transaction(); auto transaction = tokens.begin_transaction();
if (tokens.has_next_token() && tokens.next_token().is_ident("none"sv)) {
Vector<Variant<ExplicitGridTrack, GridLineNames>> track_list; tokens.discard_a_token();
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(); transaction.commit();
return GridTrackSizeListStyleValue::make_auto(); return GridTrackSizeListStyleValue::make_none();
}
last_object_was_line_names = true;
Vector<String> 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());
} }
} }
transaction.commit(); // <auto-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)));
}
// <track-list>
auto track_list = parse_grid_track_list(tokens);
if (!track_list.is_empty()) {
return GridTrackSizeListStyleValue::create(GridTrackSizeList(move(track_list))); return GridTrackSizeListStyleValue::create(GridTrackSizeList(move(track_list)));
}
return nullptr;
} }
RefPtr<CSSStyleValue const> Parser::parse_filter_value_list_value(TokenStream<ComponentValue>& tokens) RefPtr<CSSStyleValue const> Parser::parse_filter_value_list_value(TokenStream<ComponentValue>& tokens)

View file

@ -8,6 +8,7 @@
* Copyright (c) 2024, Tommy van der Vorst <tommy@pixelspark.nl> * Copyright (c) 2024, Tommy van der Vorst <tommy@pixelspark.nl>
* Copyright (c) 2024, Matthew Olsson <mattco@serenityos.org> * Copyright (c) 2024, Matthew Olsson <mattco@serenityos.org>
* Copyright (c) 2024, Glenn Skrzypczak <glenn.skrzypczak@gmail.com> * Copyright (c) 2024, Glenn Skrzypczak <glenn.skrzypczak@gmail.com>
* Copyright (c) 2025, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -3210,243 +3211,437 @@ RefPtr<CustomIdentStyleValue const> Parser::parse_custom_ident_value(TokenStream
return nullptr; return nullptr;
} }
Optional<CSS::GridSize> Parser::parse_grid_size(ComponentValue const& component_value) // https://www.w3.org/TR/css-grid-2/#typedef-track-breadth
Optional<GridSize> Parser::parse_grid_track_breadth(TokenStream<ComponentValue>& tokens)
{ {
if (component_value.is_function()) { // <track-breadth> = <length-percentage [0,∞]> | <flex [0,∞]> | min-content | max-content | auto
if (auto maybe_calculated = parse_calculated_value(component_value)) {
if (maybe_calculated->is_length()) if (auto inflexible_breadth = parse_grid_inflexible_breadth(tokens); inflexible_breadth.has_value())
return GridSize(maybe_calculated->as_length().length()); return inflexible_breadth;
if (maybe_calculated->is_percentage())
return GridSize(maybe_calculated->as_percentage().percentage()); // FIXME: Handle calculated flex values.
if (maybe_calculated->is_calculated() && maybe_calculated->as_calculated().resolves_to_length_percentage()) if (auto flex_value = parse_flex_value(tokens); flex_value && flex_value->is_flex()) {
return GridSize(LengthPercentage(maybe_calculated->as_calculated())); if (auto flex = flex_value->as_flex().flex(); flex.raw_value() >= 0)
// FIXME: Support calculated <flex> return GridSize(flex);
} }
return {}; return {};
} }
if (component_value.is_ident("auto"sv))
return GridSize::make_auto(); // https://www.w3.org/TR/css-grid-2/#typedef-inflexible-breadth
if (component_value.is_ident("max-content"sv)) Optional<GridSize> Parser::parse_grid_inflexible_breadth(TokenStream<ComponentValue>& tokens)
{
// <inflexible-breadth> = <length-percentage [0,∞]> | 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); 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<GridSize> Parser::parse_grid_fit_content(Vector<ComponentValue> const& component_values)
{
// https://www.w3.org/TR/css-grid-2/#valdef-grid-template-columns-fit-content
// 'fit-content( <length-percentage> )'
// 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<CSS::GridMinMax> Parser::parse_min_max(Vector<ComponentValue> 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 <flex> value sets the tracks 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<ComponentValue const> 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 <flex> value sets the tracks 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 {}; return {};
} }
Optional<CSS::GridRepeat> Parser::parse_repeat(Vector<ComponentValue> const& component_values) // https://www.w3.org/TR/css-grid-2/#typedef-fixed-breadth
Optional<GridSize> Parser::parse_grid_fixed_breadth(TokenStream<ComponentValue>& tokens)
{ {
// https://www.w3.org/TR/css-grid-2/#repeat-syntax // <fixed-breadth> = <length-percentage [0,∞]>
// 7.2.3.1. Syntax of repeat()
// The generic form of the repeat() syntax is, approximately,
// repeat( [ <integer [1,∞]> | auto-fill | auto-fit ] , <track-list> )
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; auto transaction = tokens.begin_transaction();
if (current_token.is(Token::Type::Number) && current_token.token().number().is_integer() && current_token.token().number_value() > 0) auto length_percentage = parse_length_percentage(tokens);
repeat_count = current_token.token().number_value(); if (!length_percentage.has_value())
else if (current_token.is_ident("auto-fill"sv)) return {};
is_auto_fill = true; if (length_percentage->is_length() && length_percentage->length().raw_value() < 0)
else if (current_token.is_ident("auto-fit"sv)) return {};
is_auto_fit = true; if (length_percentage->is_percentage() && length_percentage->percentage().value() < 0)
return {};
transaction.commit();
return GridSize(length_percentage.release_value());
}
// The second argument is a track list, which is repeated that number of times. // https://www.w3.org/TR/css-grid-2/#typedef-line-names
TokenStream part_two_tokens { comma_separated_list[1] }; Optional<GridLineNames> Parser::parse_grid_line_names(TokenStream<ComponentValue>& tokens)
part_two_tokens.discard_whitespace(); {
if (!part_two_tokens.has_next_token()) // <line-names> = '[' <custom-ident>* ']'
return {};
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;
Vector<Variant<ExplicitGridTrack, GridLineNames>> 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<String> 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 }; TokenStream block_tokens { token.block().value };
block_tokens.discard_whitespace();
while (block_tokens.has_next_token()) { while (block_tokens.has_next_token()) {
auto const& current_block_token = block_tokens.consume_a_token(); auto maybe_ident = parse_custom_ident(block_tokens, { { "span"sv, "auto"sv } });
line_names.append(current_block_token.token().ident().to_string()); if (!maybe_ident.has_value())
return OptionalNone {};
line_names.names.append(maybe_ident.release_value());
block_tokens.discard_whitespace(); block_tokens.discard_whitespace();
} }
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 cant be nested.
if (track_sizing_function.value().is_repeat())
return {};
// Automatic repetitions (auto-fill or auto-fit) cannot be combined with intrinsic or flexible sizes. transactions.commit();
// Note that 'auto' is also an intrinsic size (and thus not permitted) but we can't use return line_names;
// 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();
}
}
// Thus the precise syntax of the repeat() notation has several forms:
// <track-repeat> = repeat( [ <integer [1,∞]> ] , [ <line-names>? <track-size> ]+ <line-names>? )
// <auto-repeat> = repeat( [ auto-fill | auto-fit ] , [ <line-names>? <fixed-size> ]+ <line-names>? )
// <fixed-repeat> = repeat( [ <integer [1,∞]> ] , [ <line-names>? <fixed-size> ]+ <line-names>? )
// <name-repeat> = repeat( [ <integer [1,∞]> | auto-fill ], <line-names>+)
// The <track-repeat> variant can represent the repetition of any <track-size>, but is limited to a
// fixed number of repetitions.
// The <auto-repeat> 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 <fixed-repeat>s.
// The <name-repeat> 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 <name-repeat> ends up placing two <line-names> 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);
} }
Optional<CSS::ExplicitGridTrack> Parser::parse_track_sizing_function(ComponentValue const& token) size_t Parser::parse_track_list_impl(TokenStream<ComponentValue>& tokens, GridTrackSizeList& output, GridTrackParser const& track_parsing_callback, AllowTrailingLineNamesForEachTrack allow_trailing_line_names_for_each_track)
{ {
if (token.is_function()) { 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());
}
}
transaction.commit();
parsed_tracks_count++;
}
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());
}
}
return parsed_tracks_count;
}
Optional<GridRepeat> Parser::parse_grid_track_repeat_impl(TokenStream<ComponentValue>& tokens, GridRepeatTypeParser const& repeat_type_parser, GridTrackParser const& repeat_track_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(); 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 context_guard = push_temporary_value_parsing_context(FunctionContext { function_token.name });
if (function_token.name.equals_ignoring_ascii_case("repeat"sv)) { auto function_tokens = TokenStream(function_token.value);
auto maybe_repeat = parse_repeat(function_token.value); auto comma_separated_list = parse_a_comma_separated_list_of_component_values(function_tokens);
if (maybe_repeat.has_value()) if (comma_separated_list.size() != 2)
return CSS::ExplicitGridTrack(maybe_repeat.value());
else
return {}; return {};
} else if (function_token.name.equals_ignoring_ascii_case("minmax"sv)) {
auto maybe_min_max_value = parse_min_max(function_token.value); TokenStream first_arg_tokens { comma_separated_list[0] };
if (maybe_min_max_value.has_value()) first_arg_tokens.discard_whitespace();
return CSS::ExplicitGridTrack(maybe_min_max_value.value()); if (!first_arg_tokens.has_next_token())
else
return {}; 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); auto repeat_params = repeat_type_parser(first_arg_tokens);
if (maybe_fit_content_value.has_value()) if (!repeat_params.has_value())
return CSS::ExplicitGridTrack(maybe_fit_content_value.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<ExplicitGridTrack> Parser::parse_grid_minmax(TokenStream<ComponentValue>& 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<GridRepeat> Parser::parse_grid_track_repeat(TokenStream<ComponentValue>& tokens)
{
// <track-repeat> = repeat( [ <integer [1,∞]> ] , [ <line-names>? <track-size> ]+ <line-names>? )
GridRepeatTypeParser parse_repeat_type = [this](TokenStream<ComponentValue>& tokens) -> Optional<GridRepeatParams> {
auto maybe_integer = parse_integer(tokens);
if (!maybe_integer.has_value())
return {};
if (maybe_integer->is_calculated()) {
// FIXME: Support calculated repeat counts.
return {}; 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())));
} }
if (maybe_integer->value() < 1)
return {}; return {};
} else if (token.is_ident("auto"sv)) { return GridRepeatParams { GridRepeatType::Fixed, static_cast<size_t>(maybe_integer->value()) };
return CSS::ExplicitGridTrack(GridSize(Length::make_auto())); };
} else if (token.is_block()) { GridTrackParser parse_track = [this](TokenStream<ComponentValue>& 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<GridRepeat> Parser::parse_grid_auto_repeat(TokenStream<ComponentValue>& tokens)
{
// <auto-repeat> = repeat( [ auto-fill | auto-fit ] , [ <line-names>? <fixed-size> ]+ <line-names>? )
GridRepeatTypeParser parse_repeat_type = [](TokenStream<ComponentValue>& tokens) -> Optional<GridRepeatParams> {
auto const& first_token = tokens.consume_a_token();
if (!first_token.is_token() || !first_token.token().is(Token::Type::Ident))
return {}; 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<ComponentValue>& 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<GridRepeat> Parser::parse_grid_fixed_repeat(TokenStream<ComponentValue>& tokens)
{
// <fixed-repeat> = repeat( [ <integer [1,∞]> ] , [ <line-names>? <fixed-size> ]+ <line-names>? )
GridRepeatTypeParser parse_repeat_type = [this](TokenStream<ComponentValue>& tokens) -> Optional<GridRepeatParams> {
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<size_t>(maybe_integer->value()) };
};
GridTrackParser parse_track = [this](TokenStream<ComponentValue>& 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<ExplicitGridTrack> Parser::parse_grid_track_size(TokenStream<ComponentValue>& tokens)
{
// <track-size> = <track-breadth> | minmax( <inflexible-breadth> , <track-breadth> ) | fit-content( <length-percentage [0,∞]> )
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("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 {};
if (function_tokens.has_next_token())
return {};
transaction.commit();
return ExplicitGridTrack(GridSize(GridSize::Type::FitContent, maybe_length_percentage->length_percentage()));
}
}
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<ExplicitGridTrack> Parser::parse_grid_fixed_size(TokenStream<ComponentValue>& tokens)
{
// <fixed-size> = <fixed-breadth> | minmax( <fixed-breadth> , <track-breadth> ) | minmax( <inflexible-breadth> , <fixed-breadth> )
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<ComponentValue>& tokens)
{
// <track-list> = [ <line-names>? [ <track-size> | <track-repeat> ] ]+ <line-names>?
auto transaction = tokens.begin_transaction();
GridTrackSizeList track_list;
auto parsed_track_count = parse_track_list_impl(tokens, track_list, [&](auto& tokens) -> Optional<ExplicitGridTrack> {
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<ExplicitGridTrack> {};
});
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<ComponentValue>& tokens)
{
// <auto-track-list> = [ <line-names>? [ <fixed-size> | <fixed-repeat> ] ]* <line-names>? <auto-repeat>
// [ <line-names>? [ <fixed-size> | <fixed-repeat> ] ]* <line-names>?
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<ExplicitGridTrack> {
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<ExplicitGridTrack> {};
});
};
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 { } else {
auto grid_size = parse_grid_size(token);
if (!grid_size.has_value())
return {}; return {};
return CSS::ExplicitGridTrack(grid_size.value());
} }
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<ComponentValue>& tokens)
{
// <explicit-track-list> = [ <line-names>? <track-size> ]+ <line-names>?
auto transaction = tokens.begin_transaction();
GridTrackSizeList track_list;
auto parsed_track_count = parse_track_list_impl(tokens, track_list, [&](auto& tokens) -> Optional<ExplicitGridTrack> {
return parse_grid_track_size(tokens);
});
if (parsed_track_count == 0)
return {};
transaction.commit();
return track_list;
} }
RefPtr<GridTrackPlacementStyleValue const> Parser::parse_grid_track_placement(TokenStream<ComponentValue>& tokens) RefPtr<GridTrackPlacementStyleValue const> Parser::parse_grid_track_placement(TokenStream<ComponentValue>& tokens)

View file

@ -240,7 +240,6 @@ class FrequencyOrCalculated;
class FrequencyPercentage; class FrequencyPercentage;
class FrequencyStyleValue; class FrequencyStyleValue;
class GridAutoFlowStyleValue; class GridAutoFlowStyleValue;
class GridFitContent;
class GridMinMax; class GridMinMax;
class GridRepeat; class GridRepeat;
class GridSize; class GridSize;
@ -317,6 +316,8 @@ enum class PropertyID : u16;
struct BackgroundLayerData; struct BackgroundLayerData;
struct CSSStyleSheetInit; struct CSSStyleSheetInit;
struct GridLineNames;
struct GridRepeatParams;
struct StyleSheetIdentifier; struct StyleSheetIdentifier;
} }

View file

@ -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 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; auto& lines = dimension == GridDimension::Column ? m_column_lines : m_row_lines;
Vector<String> line_names; Vector<FlyString> line_names;
Function<void(CSS::GridTrackSizeList const&)> expand_lines_definition = [&](CSS::GridTrackSizeList const& lines_definition) { Function<void(CSS::GridTrackSizeList const&)> expand_lines_definition = [&](CSS::GridTrackSizeList const& lines_definition) {
for (auto const& item : lines_definition.list()) { for (auto const& item : lines_definition.list()) {
if (item.has<CSS::GridLineNames>()) { if (item.has<CSS::GridLineNames>()) {

View file

@ -233,7 +233,7 @@ private:
}; };
struct GridLine { struct GridLine {
Vector<String> names; Vector<FlyString> names;
}; };
Vector<GridLine> m_row_lines; Vector<GridLine> m_row_lines;
Vector<GridLine> m_column_lines; Vector<GridLine> m_column_lines;

View file

@ -76,10 +76,10 @@ font-weight: 'calc(2)' -> '2'
font-weight: 'calc(2 * var(--n))' -> '4' font-weight: 'calc(2 * var(--n))' -> '4'
font-width: 'calc(2%)' -> '2%' font-width: 'calc(2%)' -> '2%'
font-width: 'calc(2% * var(--n))' -> '4%' font-width: 'calc(2% * var(--n))' -> '4%'
grid-auto-columns: 'calc(2fr)' -> 'none' grid-auto-columns: 'calc(2fr)' -> 'auto'
grid-auto-columns: 'calc(2fr * var(--n))' -> 'none' grid-auto-columns: 'calc(2fr * var(--n))' -> 'auto'
grid-auto-rows: 'calc(2fr)' -> 'none' grid-auto-rows: 'calc(2fr)' -> 'auto'
grid-auto-rows: 'calc(2fr * var(--n))' -> 'none' grid-auto-rows: 'calc(2fr * var(--n))' -> 'auto'
grid-template-columns: 'calc(2fr)' -> 'none' grid-template-columns: 'calc(2fr)' -> 'none'
grid-template-columns: 'calc(2fr * var(--n))' -> 'none' grid-template-columns: 'calc(2fr * var(--n))' -> 'none'
grid-template-rows: 'calc(2fr)' -> 'none' grid-template-rows: 'calc(2fr)' -> 'none'

View file

@ -2,19 +2,18 @@ Harness status: OK
Found 15 tests Found 15 tests
4 Pass 15 Pass
11 Fail Pass e.style['grid-auto-columns'] = "none" should not set the property value
Fail 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
Fail 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
Fail 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
Fail 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
Fail 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
Fail 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
Fail 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
Fail 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
Fail 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
Fail 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
Fail 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'] = "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'] = "auto, 10%" should not set the property value
Pass e.style['grid-auto-columns'] = "1px [a] 1px" should not set the property value Pass e.style['grid-auto-columns'] = "1px [a] 1px" should not set the property value

View file

@ -2,18 +2,17 @@ Harness status: OK
Found 14 tests Found 14 tests
4 Pass 14 Pass
10 Fail Pass e.style['grid-auto-rows'] = "none" should not set the property value
Fail 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
Fail 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
Fail 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
Fail 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
Fail 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
Fail 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
Fail 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
Fail 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
Fail 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
Fail 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'] = "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'] = "auto, 10%" should not set the property value
Pass e.style['grid-auto-rows'] = "1px [a] 1px" should not set the property value Pass e.style['grid-auto-rows'] = "1px [a] 1px" should not set the property value

View file

@ -2,8 +2,8 @@ Harness status: OK
Found 40 tests Found 40 tests
32 Pass 34 Pass
8 Fail 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 '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' 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' 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', 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 = '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' 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' Pass 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, -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' 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(' 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 Fail Test setting grid-template-columns and grid-template-rows to 'inherit' through JS

View file

@ -2,39 +2,38 @@ Harness status: OK
Found 34 tests Found 34 tests
16 Pass 34 Pass
18 Fail
Pass e.style['grid'] = "none none" should not set the property value Pass e.style['grid'] = "none none" should not set the property value
Pass e.style['grid'] = "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 Pass e.style['grid'] = "10px" should not set the property value
Fail e.style['grid'] = "20%" should not set the property value Pass e.style['grid'] = "20%" should not set the property value
Fail e.style['grid'] = "5fr" should not set the property value Pass e.style['grid'] = "5fr" should not set the property value
Fail e.style['grid'] = "[a]" should not set the property value Pass e.style['grid'] = "[a]" should not set the property value
Fail e.style['grid'] = "[a] 10px" should not set the property value Pass e.style['grid'] = "[a] 10px" should not set the property value
Fail e.style['grid'] = "[a] 10px []" should not set the property value Pass e.style['grid'] = "[a] 10px []" should not set the property value
Fail e.style['grid'] = "[]" should not set the property value Pass e.style['grid'] = "[]" should not set the property value
Fail e.style['grid'] = "10px \"a\"" should not set the property value Pass 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 \"a\"" should not set the property value
Fail 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\"" should not set the property value
Pass e.style['grid'] = "\"a\" none" 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 Pass 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 Pass 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 Pass 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 Pass 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 [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]" 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] [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] / none" should not set the property value
Pass e.style['grid'] = "\"a\" \"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 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\" []" should not set the property value
Pass e.style['grid'] = "none / \"a\" [] 10px" 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 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'] = "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'] = "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 Pass e.style['grid'] = "auto / auto-flow foo()" should not set the property value

View file

@ -2,13 +2,13 @@ Harness status: OK
Found 121 tests Found 121 tests
59 Pass 84 Pass
62 Fail 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
Fail e.style.cssText = grid: auto-flow auto / 100px 100px should set grid-template-areas 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 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 Pass 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-rows
Pass e.style.cssText = grid: auto-flow auto / 100px 100px; grid-template-areas: "one two" "three four" 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-template-areas
Fail e.style.cssText = grid: 30px 40px / 50px 60px; grid-auto-flow: column should set grid 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 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-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 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 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 Fail 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 Fail 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 Fail 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: 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) 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(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-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: 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
Pass e.style.cssText = grid: 10px / auto; grid-template-columns: 20px should set grid-template 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 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
Pass e.style.cssText = grid: auto-flow 1px / 2px; grid-auto-columns: 3px should set grid-auto-columns 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 Pass 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 Pass 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-template-columns
Fail e.style.cssText = grid: auto-flow 1px / 2px; grid-auto-columns: 3px should set grid-template-rows 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 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 Pass 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-flow
Pass e.style.cssText = grid: 1px / auto-flow 2px; grid-auto-rows: 3px should set grid-auto-rows 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-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 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 Pass 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-flow
Fail e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: 3px should set grid-auto-rows 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 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 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 Pass 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-flow
Fail e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: repeat(2, 3px) should set grid-auto-rows 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 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 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 Pass 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-flow
Fail e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: repeat(auto-fill, 3px) should set grid-auto-rows 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 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 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 Pass 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-flow
Fail e.style.cssText = grid: none / auto-flow 1px; grid-template-columns: repeat(auto-fit, 3px) should set grid-auto-rows 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 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 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-columns
Fail 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-flow
Fail 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-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-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: 3px should set grid-template-rows
Pass e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: repeat(2, 3px) should set grid 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-columns
Fail 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-flow
Fail 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-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-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(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 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-columns
Fail 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-flow
Fail 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-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-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-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 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-columns
Fail 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-flow
Fail 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-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-template-columns
Pass e.style.cssText = grid: auto-flow 1px / none; grid-template-rows: repeat(auto-fit, 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-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 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 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

View file

@ -2,8 +2,8 @@ Harness status: OK
Found 49 tests Found 49 tests
7 Pass 8 Pass
42 Fail 41 Fail
Pass e.style['grid'] = "none" should set the property value 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'] = "none / none" should set the property value
Pass e.style['grid'] = "auto / auto" 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'] = "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 / auto" should set the property value
Fail e.style['grid'] = "[a] 10px / none" 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
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 Pass e.style['grid'] = "\"a\" 10px" should set the property value

View file

@ -2,8 +2,8 @@ Harness status: OK
Found 63 tests Found 63 tests
24 Pass 34 Pass
39 Fail 29 Fail
Fail e.style['grid'] = "none" should set grid-auto-columns 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-flow
Fail e.style['grid'] = "none" should set grid-auto-rows 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 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-areas
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-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 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-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-flow
Fail e.style['grid'] = " [] \"a a a\" [] [] \"b b b\" 1fr [] / [] auto 1fr [] auto []" should set grid-auto-rows 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-areas
Fail 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-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 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 Pass 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-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-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-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-columns
Fail e.style['grid'] = "10px / auto-flow dense 20px" should set grid-template-rows Pass 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 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-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-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-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 set grid-template-rows
Fail e.style['grid'] = "auto-flow dense 30px / 40px" should not set unrelated longhands Pass e.style['grid'] = "auto-flow dense 30px / 40px" should not set unrelated longhands

View file

@ -2,20 +2,19 @@ Harness status: OK
Found 15 tests Found 15 tests
1 Pass 15 Pass
14 Fail Pass e.style['grid-template-columns'] = "-10px" should not set the property value
Fail 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
Fail 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
Fail 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
Fail 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
Fail 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
Fail 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
Fail 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
Fail 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
Fail 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 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 Pass 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 Pass 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 Pass 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 Pass 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 Pass e.style['grid-template-columns'] = "[auto] 1px" should not set the property value

View file

@ -2,8 +2,7 @@ Harness status: OK
Found 34 tests Found 34 tests
32 Pass 34 Pass
2 Fail
Pass e.style['grid-template-columns'] = "none" should set the property value 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'] = "10px" should set the property value
Pass e.style['grid-template-columns'] = "20%" 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(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 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(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, 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'] = "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 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-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-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 Pass e.style['grid-template-columns'] = "repeat(auto-fill, minmax(30px, 5fr) [two])" should set the property value

View file

@ -2,20 +2,19 @@ Harness status: OK
Found 15 tests Found 15 tests
1 Pass 15 Pass
14 Fail Pass e.style['grid-template-rows'] = "-10px" should not set the property value
Fail 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
Fail 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
Fail 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
Fail 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
Fail 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
Fail 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
Fail 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
Fail 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
Fail 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 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 Pass 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 Pass 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 Pass 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 Pass 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 Pass e.style['grid-template-rows'] = "[auto] 1px" should not set the property value

View file

@ -2,8 +2,7 @@ Harness status: OK
Found 34 tests Found 34 tests
32 Pass 34 Pass
2 Fail
Pass e.style['grid-template-rows'] = "none" should set the property value 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'] = "10px" should set the property value
Pass e.style['grid-template-rows'] = "20%" 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(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 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(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, 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'] = "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 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-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-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 Pass e.style['grid-template-rows'] = "repeat(auto-fill, minmax(30px, 5fr) [two])" should set the property value

View file

@ -2,69 +2,68 @@ Harness status: OK
Found 66 tests Found 66 tests
15 Pass 66 Pass
51 Fail Pass e.style['grid-template'] = "auto" should not set the property value
Fail 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 none" should not set the property value
Pass e.style['grid-template'] = "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 Pass e.style['grid-template'] = "10px" should not set the property value
Fail e.style['grid-template'] = "20%" should not set the property value Pass e.style['grid-template'] = "20%" should not set the property value
Fail e.style['grid-template'] = "5fr" should not set the property value Pass e.style['grid-template'] = "5fr" should not set the property value
Fail e.style['grid-template'] = "[a]" should not set the property value Pass e.style['grid-template'] = "[a]" should not set the property value
Fail e.style['grid-template'] = "[a] 10px" should not set the property value Pass 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 Pass 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 Pass 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 Pass 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 Pass 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 Pass 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 Pass 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 Pass 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 Pass e.style['grid-template'] = "[]" should not set the property value
Fail e.style['grid-template'] = "10px \"a\"" should not set the property value Pass 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 Pass 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 Pass 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'] = "repeat(auto-fit, 10px) \"a\"" should not set the property value
Fail e.style['grid-template'] = "[] 10px \"a\"" should not set the property value Pass 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 Pass 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 Pass 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'] = "[] repeat(auto-fit, 10px) \"a\"" should not set the property value
Fail e.style['grid-template'] = "10px [] \"a\"" should not set the property value Pass 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 Pass 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 Pass 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'] = "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\"" should not set the property value
Pass e.style['grid-template'] = "\"a\" none" 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 Pass 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 Pass 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 Pass 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 Pass 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 Pass 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 Pass 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 Pass 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 Pass 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 Pass 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 Pass 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 Pass 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 Pass 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 Pass 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 Pass 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 Pass 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 Pass 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 Pass 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 Pass 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 Pass 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 Pass 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 Pass 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 Pass 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\" 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]" 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] [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] / none" should not set the property value
Pass e.style['grid-template'] = "\"a\" \"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 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\" []" 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\" [] 10px" should not set the property value
Pass e.style['grid-template'] = "none / \"a\" [] repeat(2, 10px)" should not set the property value Pass e.style['grid-template'] = "none / \"a\" [] repeat(2, 10px)" should not set the property value

View file

@ -2,8 +2,8 @@ Harness status: OK
Found 40 tests Found 40 tests
7 Pass 8 Pass
33 Fail 32 Fail
Pass e.style['grid-template'] = "none" should set the property value 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'] = "none / none" should set the property value
Pass e.style['grid-template'] = "auto / auto" 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'] = "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 / auto" should set the property value
Fail e.style['grid-template'] = "[a] 10px / none" 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
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 Pass e.style['grid-template'] = "\"a\" 10px" should set the property value

View file

@ -2,8 +2,8 @@ Harness status: OK
Found 24 tests Found 24 tests
20 Pass 23 Pass
4 Fail 1 Fail
Pass e.style['grid-template'] = "none" should set grid-template-areas 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-columns
Pass e.style['grid-template'] = "none" should set grid-template-rows 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'] = "[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-areas
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-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 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-areas
Fail 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-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 not set unrelated longhands