LibWeb: Parse CSS grid subgrid track listings
Parse subgrid track listings for grid-template rows and columns, including fixed and auto-fill name-repeat line-name lists. Preserve the subgrid keyword through computed values and shorthand serialization, and make interpolation discrete instead of routing subgrid lists through the explicit track interpolation path. Import WPT coverage for subgrid grid-template parsing and computed values, and add text coverage for discrete subgrid track-list animation.
This commit is contained in:
parent
ceb25e10d4
commit
19e5b57672
15 changed files with 484 additions and 3 deletions
|
|
@ -239,8 +239,30 @@ GridTrackSizeList GridTrackSizeList::make_none()
|
|||
return GridTrackSizeList();
|
||||
}
|
||||
|
||||
GridTrackSizeList GridTrackSizeList::make_line_name_list()
|
||||
{
|
||||
GridTrackSizeList list;
|
||||
list.m_preserve_line_name_sets = true;
|
||||
return list;
|
||||
}
|
||||
|
||||
GridTrackSizeList GridTrackSizeList::make_subgrid()
|
||||
{
|
||||
GridTrackSizeList list;
|
||||
list.m_is_subgrid = true;
|
||||
list.m_preserve_line_name_sets = true;
|
||||
return list;
|
||||
}
|
||||
|
||||
void GridTrackSizeList::serialize(StringBuilder& builder, SerializationMode mode) const
|
||||
{
|
||||
if (m_is_subgrid) {
|
||||
builder.append("subgrid"sv);
|
||||
if (m_list.is_empty())
|
||||
return;
|
||||
builder.append(" "sv);
|
||||
}
|
||||
|
||||
if (m_list.is_empty()) {
|
||||
builder.append("none"sv);
|
||||
return;
|
||||
|
|
@ -280,6 +302,11 @@ bool GridTrackSizeList::operator==(GridTrackSizeList const& other) const = defau
|
|||
|
||||
void GridTrackSizeList::append(GridLineNames&& line_names)
|
||||
{
|
||||
if (m_preserve_line_name_sets) {
|
||||
m_list.append(move(line_names));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_list.is_empty() && m_list.last().has<GridLineNames>()) {
|
||||
auto& last_line_names = m_list.last().get<GridLineNames>();
|
||||
for (auto const& name : line_names.names())
|
||||
|
|
@ -297,6 +324,8 @@ void GridTrackSizeList::append(ExplicitGridTrack&& explicit_track)
|
|||
GridTrackSizeList GridTrackSizeList::absolutized(ComputationContext const& context) const
|
||||
{
|
||||
GridTrackSizeList result;
|
||||
result.m_is_subgrid = m_is_subgrid;
|
||||
result.m_preserve_line_name_sets = m_preserve_line_name_sets;
|
||||
for (auto const& item : m_list) {
|
||||
item.visit(
|
||||
[&result, &context](ExplicitGridTrack const& track) {
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ private:
|
|||
struct GridLineName {
|
||||
FlyString name;
|
||||
bool implicit { false };
|
||||
bool adopted_from_parent_grid { false };
|
||||
|
||||
bool operator==(GridLineName const& other) const = default;
|
||||
};
|
||||
|
|
@ -118,15 +119,18 @@ private:
|
|||
class GridTrackSizeList {
|
||||
public:
|
||||
static GridTrackSizeList make_none();
|
||||
static GridTrackSizeList make_line_name_list();
|
||||
static GridTrackSizeList make_subgrid();
|
||||
|
||||
Vector<CSS::ExplicitGridTrack> track_list() const;
|
||||
auto const& list() const { return m_list; }
|
||||
bool is_subgrid() const { return m_is_subgrid; }
|
||||
|
||||
void serialize(StringBuilder&, SerializationMode) const;
|
||||
String to_string(SerializationMode) const;
|
||||
bool operator==(GridTrackSizeList const& other) const;
|
||||
|
||||
bool is_empty() const { return m_list.is_empty(); }
|
||||
bool is_empty() const { return !m_is_subgrid && m_list.is_empty(); }
|
||||
|
||||
void append(GridLineNames&&);
|
||||
void append(ExplicitGridTrack&&);
|
||||
|
|
@ -136,6 +140,8 @@ public:
|
|||
bool is_computationally_independent() const;
|
||||
|
||||
private:
|
||||
bool m_is_subgrid { false };
|
||||
bool m_preserve_line_name_sets { false };
|
||||
Vector<Variant<ExplicitGridTrack, GridLineNames>> m_list;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -577,6 +577,15 @@ static void append_grid_track_with_line_names(GridTrackSizeList& list, ExplicitG
|
|||
|
||||
static Optional<GridTrackSizeList> interpolate_grid_track_size_list(DOM::Element& element, CalculationContext const& calculation_context, GridTrackSizeList const& from, GridTrackSizeList const& to, float delta)
|
||||
{
|
||||
// https://drafts.csswg.org/css-grid-2/#track-sizing
|
||||
// Animation type: if the list lengths match, by computed value type per item in the computed track list;
|
||||
// discrete otherwise.
|
||||
//
|
||||
// https://drafts.csswg.org/css-grid-2/#computed-track-list-subgrid
|
||||
// The computed track list of a subgrid axis is the subgrid keyword followed by a list of line names.
|
||||
if (from.is_subgrid() || to.is_subgrid())
|
||||
return {};
|
||||
|
||||
auto interpolate_grid_size = [&](GridSize const& from_grid_size, GridSize const& to_grid_size) -> GridSize {
|
||||
return GridSize { *interpolate_value(element, calculation_context, from_grid_size.style_value(), to_grid_size.style_value(), delta, AllowDiscrete::Yes) };
|
||||
};
|
||||
|
|
@ -2260,6 +2269,15 @@ static T composite_raw_values(T underlying_raw_value, T animated_raw_value)
|
|||
|
||||
static Optional<GridTrackSizeList> composite_grid_track_size_list(PropertyID property_id, CalculationContext const& calculation_context, GridTrackSizeList const& underlying, GridTrackSizeList const& animated, Bindings::CompositeOperation composite_operation)
|
||||
{
|
||||
// https://drafts.csswg.org/css-grid-2/#track-sizing
|
||||
// Animation type: if the list lengths match, by computed value type per item in the computed track list;
|
||||
// discrete otherwise.
|
||||
//
|
||||
// https://drafts.csswg.org/css-grid-2/#computed-track-list-subgrid
|
||||
// The computed track list of a subgrid axis is the subgrid keyword followed by a list of line names.
|
||||
if (underlying.is_subgrid() || animated.is_subgrid())
|
||||
return {};
|
||||
|
||||
auto composite_grid_size = [&](GridSize const& underlying_grid_size, GridSize const& animated_grid_size) -> Optional<GridSize> {
|
||||
if (auto composited_value = composite_value(property_id, underlying_grid_size.style_value(), animated_grid_size.style_value(), composite_operation))
|
||||
return GridSize { *composited_value };
|
||||
|
|
|
|||
|
|
@ -343,6 +343,7 @@ private:
|
|||
Optional<GridRepeat> parse_grid_track_repeat(TokenStream<ComponentValue>&);
|
||||
Optional<GridRepeat> parse_grid_auto_repeat(TokenStream<ComponentValue>&);
|
||||
Optional<GridRepeat> parse_grid_fixed_repeat(TokenStream<ComponentValue>&);
|
||||
Optional<GridRepeat> parse_grid_name_repeat(TokenStream<ComponentValue>&);
|
||||
|
||||
using GridRepeatTypeParser = AK::Function<Optional<GridRepeatParams>(TokenStream<ComponentValue>&)>;
|
||||
using GridTrackParser = AK::Function<Optional<ExplicitGridTrack>(TokenStream<ComponentValue>&)>;
|
||||
|
|
|
|||
|
|
@ -5334,7 +5334,7 @@ RefPtr<GridAutoFlowStyleValue const> Parser::parse_grid_auto_flow_value(TokenStr
|
|||
// https://www.w3.org/TR/css-grid-2/#track-sizing
|
||||
RefPtr<StyleValue const> Parser::parse_grid_track_size_list(TokenStream<ComponentValue>& tokens)
|
||||
{
|
||||
// none | <track-list> | <auto-track-list> | FIXME: subgrid <line-name-list>?
|
||||
// none | <track-list> | <auto-track-list> | subgrid <line-name-list>?
|
||||
|
||||
// none
|
||||
{
|
||||
|
|
@ -5347,6 +5347,40 @@ RefPtr<StyleValue const> Parser::parse_grid_track_size_list(TokenStream<Componen
|
|||
}
|
||||
}
|
||||
|
||||
// subgrid <line-name-list>?
|
||||
{
|
||||
auto transaction = tokens.begin_transaction();
|
||||
tokens.discard_whitespace();
|
||||
if (tokens.has_next_token() && tokens.next_token().is_ident("subgrid"sv)) {
|
||||
tokens.discard_a_token(); // subgrid
|
||||
|
||||
auto track_list = GridTrackSizeList::make_subgrid();
|
||||
bool has_auto_fill_repeat = false;
|
||||
tokens.discard_whitespace();
|
||||
while (tokens.has_next_token()) {
|
||||
if (tokens.next_token().is_block() && tokens.next_token().block().is_square()) {
|
||||
auto line_names = parse_grid_line_names(tokens);
|
||||
if (!line_names.has_value())
|
||||
return nullptr;
|
||||
track_list.append(line_names.release_value());
|
||||
} else if (auto name_repeat = parse_grid_name_repeat(tokens); name_repeat.has_value()) {
|
||||
if (name_repeat->is_auto_fill()) {
|
||||
if (has_auto_fill_repeat)
|
||||
return nullptr;
|
||||
has_auto_fill_repeat = true;
|
||||
}
|
||||
track_list.append(ExplicitGridTrack(name_repeat.release_value()));
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
tokens.discard_whitespace();
|
||||
}
|
||||
|
||||
transaction.commit();
|
||||
return GridTrackSizeListStyleValue::create(move(track_list));
|
||||
}
|
||||
}
|
||||
|
||||
// <auto-track-list>
|
||||
if (auto auto_track_list = parse_grid_auto_track_list(tokens); !auto_track_list.is_empty()) {
|
||||
return GridTrackSizeListStyleValue::create(GridTrackSizeList(move(auto_track_list)));
|
||||
|
|
|
|||
|
|
@ -4642,6 +4642,67 @@ Optional<GridRepeat> Parser::parse_grid_fixed_repeat(TokenStream<ComponentValue>
|
|||
return parse_grid_track_repeat_impl(tokens, parse_repeat_type, parse_track);
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/css-grid-2/#typedef-name-repeat
|
||||
Optional<GridRepeat> Parser::parse_grid_name_repeat(TokenStream<ComponentValue>& tokens)
|
||||
{
|
||||
// <name-repeat> = repeat( [ <integer [1,∞]> | auto-fill ] , <line-names>+ )
|
||||
|
||||
auto transaction = tokens.begin_transaction();
|
||||
tokens.discard_whitespace();
|
||||
|
||||
if (!tokens.has_next_token())
|
||||
return {};
|
||||
|
||||
auto const& token = tokens.consume_a_token();
|
||||
if (!token.is_function())
|
||||
return {};
|
||||
|
||||
auto const& function_token = token.function();
|
||||
if (!function_token.name.equals_ignoring_ascii_case("repeat"sv))
|
||||
return {};
|
||||
auto context_guard = push_temporary_value_parsing_context(FunctionContext { function_token.name });
|
||||
|
||||
auto function_tokens = TokenStream(function_token.value);
|
||||
auto comma_separated_list = parse_a_comma_separated_list_of_component_values(function_tokens);
|
||||
if (comma_separated_list.size() != 2)
|
||||
return {};
|
||||
|
||||
TokenStream first_arg_tokens { comma_separated_list[0] };
|
||||
first_arg_tokens.discard_whitespace();
|
||||
Optional<GridRepeatParams> repeat_params;
|
||||
if (auto maybe_integer = parse_integer_value(first_arg_tokens, { .min = 1, .max = NumericLimits<i32>::max() })) {
|
||||
repeat_params = GridRepeatParams { GridRepeatType::Fixed, maybe_integer };
|
||||
} else if (first_arg_tokens.has_next_token() && first_arg_tokens.next_token().is_ident("auto-fill"sv)) {
|
||||
first_arg_tokens.discard_a_token(); // auto-fill
|
||||
repeat_params = GridRepeatParams { GridRepeatType::AutoFill };
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
first_arg_tokens.discard_whitespace();
|
||||
if (first_arg_tokens.has_next_token())
|
||||
return {};
|
||||
|
||||
TokenStream second_arg_tokens { comma_separated_list[1] };
|
||||
GridTrackSizeList line_name_list = GridTrackSizeList::make_line_name_list();
|
||||
size_t parsed_line_name_count = 0;
|
||||
second_arg_tokens.discard_whitespace();
|
||||
while (second_arg_tokens.has_next_token()) {
|
||||
if (!second_arg_tokens.next_token().is_block() || !second_arg_tokens.next_token().block().is_square())
|
||||
return {};
|
||||
auto line_names = parse_grid_line_names(second_arg_tokens);
|
||||
if (!line_names.has_value())
|
||||
return {};
|
||||
line_name_list.append(line_names.release_value());
|
||||
++parsed_line_name_count;
|
||||
second_arg_tokens.discard_whitespace();
|
||||
}
|
||||
if (parsed_line_name_count == 0)
|
||||
return {};
|
||||
|
||||
transaction.commit();
|
||||
return GridRepeat(move(line_name_list), repeat_params.release_value());
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/css-grid-2/#typedef-track-size
|
||||
Optional<ExplicitGridTrack> Parser::parse_grid_track_size(TokenStream<ComponentValue>& tokens)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -749,7 +749,7 @@ void ShorthandStyleValue::serialize(StringBuilder& builder, SerializationMode mo
|
|||
auto& rows = rows_value->as_grid_track_size_list();
|
||||
auto& columns = columns_value->as_grid_track_size_list();
|
||||
|
||||
if (areas.row_count() == 0 && rows.grid_track_size_list().track_list().size() == 0 && columns.grid_track_size_list().track_list().size() == 0) {
|
||||
if (areas.row_count() == 0 && rows.grid_track_size_list().is_empty() && columns.grid_track_size_list().is_empty()) {
|
||||
builder.append("none"sv);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
250: subgrid [a] [b] [c]
|
||||
500: subgrid [x] [y] [z]
|
||||
750: subgrid [x] [y] [z]
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 50 tests
|
||||
|
||||
50 Pass
|
||||
Pass Property grid-template-columns value 'subgrid []'
|
||||
Pass Property grid-template-columns value 'subgrid [a]'
|
||||
Pass Property grid-template-columns value 'subgrid [a] [b]'
|
||||
Pass Property grid-template-columns value 'subgrid [] [b]'
|
||||
Pass Property grid-template-columns value 'subgrid [a] [b] [b] [c]'
|
||||
Pass Property grid-template-columns value 'subgrid [a] [b c d] [e f] [e f] [g]'
|
||||
Pass Property grid-template-columns value 'subgrid [a b c] [d] [e f]'
|
||||
Pass Property grid-template-columns value 'subgrid repeat(auto-fill, [c])'
|
||||
Pass Property grid-template-columns value 'subgrid repeat(auto-fill, [])'
|
||||
Pass Property grid-template-columns value 'subgrid repeat(auto-fill, [c]) [g] [h i]'
|
||||
Pass Property grid-template-columns value 'subgrid [a] repeat(auto-fill, [c]) [g] [h i]'
|
||||
Pass Property grid-template-columns value 'subgrid [a b] repeat(auto-fill, [c]) [g]'
|
||||
Pass Property grid-template-columns value 'subgrid [a] [b] repeat(auto-fill, [c]) [g h]'
|
||||
Pass Property grid-template-columns value 'subgrid [a] [b] repeat(auto-fill, [c])'
|
||||
Pass Property grid-template-columns value 'subgrid repeat(auto-fill, [c d])'
|
||||
Pass Property grid-template-columns value 'subgrid repeat(auto-fill, [c d]) [g] [h i]'
|
||||
Pass Property grid-template-columns value 'subgrid [a] repeat(auto-fill, [c d]) [g] [h i]'
|
||||
Pass Property grid-template-columns value 'subgrid [a b] repeat(auto-fill, [c d]) [g]'
|
||||
Pass Property grid-template-columns value 'subgrid [a] [b] repeat(auto-fill, [c d]) [g h]'
|
||||
Pass Property grid-template-columns value 'subgrid [a] [b] repeat(auto-fill, [c d])'
|
||||
Pass Property grid-template-columns value 'subgrid repeat(auto-fill, [c] [d])'
|
||||
Pass Property grid-template-columns value 'subgrid repeat(auto-fill, [c] [d]) [g] [h i]'
|
||||
Pass Property grid-template-columns value 'subgrid [a] repeat(auto-fill, [c] [d]) [g] [h i]'
|
||||
Pass Property grid-template-columns value 'subgrid [a b] repeat(auto-fill, [c] [d]) [g]'
|
||||
Pass Property grid-template-columns value 'subgrid [a] [b] repeat(auto-fill, [c] [d]) [g h]'
|
||||
Pass Property grid-template-columns value 'subgrid [a] [b] repeat(auto-fill, [c] [d])'
|
||||
Pass Property grid-template-columns value 'subgrid repeat(auto-fill, [c] [d e])'
|
||||
Pass Property grid-template-columns value 'subgrid repeat(auto-fill, [c] [d e]) [g] [h i]'
|
||||
Pass Property grid-template-columns value 'subgrid [a] repeat(auto-fill, [c] [d e]) [g] [h i]'
|
||||
Pass Property grid-template-columns value 'subgrid [a b] repeat(auto-fill, [c] [d e]) [g]'
|
||||
Pass Property grid-template-columns value 'subgrid [a] [b] repeat(auto-fill, [c] [d e]) [g h]'
|
||||
Pass Property grid-template-columns value 'subgrid [a] [b] repeat(auto-fill, [c] [d e])'
|
||||
Pass Property grid-template-columns value 'subgrid [a] repeat(2, [c] [d e])'
|
||||
Pass Property grid-template-columns value 'subgrid repeat(1, [])'
|
||||
Pass Property grid-template-columns value 'subgrid repeat(2, [])'
|
||||
Pass Property grid-template-columns value 'subgrid repeat(2, [a])'
|
||||
Pass Property grid-template-columns value 'subgrid repeat(2, [a] [])'
|
||||
Pass Property grid-template-columns value 'subgrid repeat(2, [] [a] [])'
|
||||
Pass Property grid-template-columns value 'subgrid repeat(2, [] [] []) repeat(auto-fill, [] [] [])'
|
||||
Pass Property grid-template-columns value 'subgrid repeat(1, [a b])'
|
||||
Pass Property grid-template-columns value 'subgrid repeat(2, [a b])'
|
||||
Pass Property grid-template-columns value 'subgrid repeat(1, [a] [b])'
|
||||
Pass Property grid-template-columns value 'subgrid repeat(2, [a] [b])'
|
||||
Pass Property grid-template-columns value 'subgrid [a] repeat(2, [b])'
|
||||
Pass Property grid-template-columns value 'subgrid repeat(2, [a]) [b]'
|
||||
Pass Property grid-template-columns value 'subgrid [a] repeat(2, [b] [c d]) [e]'
|
||||
Pass Property grid-template-columns value 'subgrid repeat(2, [a b]) repeat(auto-fill, [c] [d e])'
|
||||
Pass Property grid-template-columns value 'subgrid repeat(auto-fill, [a] [b c]) repeat(2, [d e])'
|
||||
Pass Property grid-template-columns value 'subgrid repeat(2, [a b]) repeat(auto-fill, [c] [d e]) repeat(2, [f g])'
|
||||
Pass Property grid-template-columns value 'subgrid [a] [b c] repeat(2, [d e]) [f] [g h] repeat(auto-fill, [i] [j k]) [l] repeat(2, [m n]) [o]'
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 22 tests
|
||||
|
||||
22 Pass
|
||||
Pass e.style['grid-template-rows'] = "subgrid subgrid" should not set the property value
|
||||
Pass e.style['grid-template-rows'] = "subgrid none" should not set the property value
|
||||
Pass e.style['grid-template-rows'] = "subgrid 1px" should not set the property value
|
||||
Pass e.style['grid-template-rows'] = "subgrid [a] 1px" should not set the property value
|
||||
Pass e.style['grid-template-rows'] = "subgrid repeat(auto-fill, 1px)" should not set the property value
|
||||
Pass e.style['grid-template-rows'] = "subgrid repeat(auto-fill, line)" should not set the property value
|
||||
Pass e.style['grid-template-rows'] = "subgrid repeat(auto-fit, [a])" should not set the property value
|
||||
Pass e.style['grid-template-rows'] = "subgrid repeat(2, 1px)" should not set the property value
|
||||
Pass e.style['grid-template-rows'] = "subgrid repeat(2, line)" should not set the property value
|
||||
Pass e.style['grid-template-rows'] = "subgrid repeat(2," should not set the property value
|
||||
Pass e.style['grid-template-rows'] = "subgrid repeat(auto-fill, [a]) repeat(auto-fill, [b]" should not set the property value
|
||||
Pass e.style['grid-template-columns'] = "subgrid subgrid" should not set the property value
|
||||
Pass e.style['grid-template-columns'] = "subgrid none" should not set the property value
|
||||
Pass e.style['grid-template-columns'] = "subgrid 1px" should not set the property value
|
||||
Pass e.style['grid-template-columns'] = "subgrid [a] 1px" should not set the property value
|
||||
Pass e.style['grid-template-columns'] = "subgrid repeat(auto-fill, 1px)" should not set the property value
|
||||
Pass e.style['grid-template-columns'] = "subgrid repeat(auto-fill, line)" should not set the property value
|
||||
Pass e.style['grid-template-columns'] = "subgrid repeat(auto-fit, [a])" should not set the property value
|
||||
Pass e.style['grid-template-columns'] = "subgrid repeat(2, 1px)" should not set the property value
|
||||
Pass e.style['grid-template-columns'] = "subgrid repeat(2, line)" should not set the property value
|
||||
Pass e.style['grid-template-columns'] = "subgrid repeat(2," should not set the property value
|
||||
Pass e.style['grid-template-columns'] = "subgrid repeat(auto-fill, [a]) repeat(auto-fill, [b]" should not set the property value
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 38 tests
|
||||
|
||||
38 Pass
|
||||
Pass e.style['grid-template-rows'] = "subgrid" should set the property value
|
||||
Pass e.style['grid-template-rows'] = "subgrid [a]" should set the property value
|
||||
Pass e.style['grid-template-rows'] = "subgrid [a] [b]" should set the property value
|
||||
Pass e.style['grid-template-rows'] = "subgrid [a] [b] [c]" should set the property value
|
||||
Pass e.style['grid-template-rows'] = "subgrid []" should set the property value
|
||||
Pass e.style['grid-template-rows'] = "subgrid [a] [b] [] [c]" should set the property value
|
||||
Pass e.style['grid-template-rows'] = "subgrid [] [] [] [c]" should set the property value
|
||||
Pass e.style['grid-template-rows'] = "subgrid [] [] [] []" should set the property value
|
||||
Pass e.style['grid-template-rows'] = "subgrid repeat(auto-fill, [a])" should set the property value
|
||||
Pass e.style['grid-template-rows'] = "subgrid repeat(auto-fill, [])" should set the property value
|
||||
Pass e.style['grid-template-rows'] = "subgrid [a] repeat(auto-fill, [b])" should set the property value
|
||||
Pass e.style['grid-template-rows'] = "subgrid [a] repeat(auto-fill, [b]) [c]" should set the property value
|
||||
Pass e.style['grid-template-rows'] = "subgrid [] repeat(auto-fill, []) []" should set the property value
|
||||
Pass e.style['grid-template-rows'] = "subgrid repeat(2, [a])" should set the property value
|
||||
Pass e.style['grid-template-rows'] = "subgrid repeat(2, [a] [b])" should set the property value
|
||||
Pass e.style['grid-template-rows'] = "subgrid [a] repeat(2, [b])" should set the property value
|
||||
Pass e.style['grid-template-rows'] = "subgrid [a] repeat(2, [b]) [c]" should set the property value
|
||||
Pass e.style['grid-template-rows'] = "subgrid [] repeat(2, []) []" should set the property value
|
||||
Pass e.style['grid-template-rows'] = "subgrid [a] repeat(2, [b]) repeat(auto-fill, [c]) [d]" should set the property value
|
||||
Pass e.style['grid-template-columns'] = "subgrid" should set the property value
|
||||
Pass e.style['grid-template-columns'] = "subgrid [a]" should set the property value
|
||||
Pass e.style['grid-template-columns'] = "subgrid [a] [b]" should set the property value
|
||||
Pass e.style['grid-template-columns'] = "subgrid [a] [b] [c]" should set the property value
|
||||
Pass e.style['grid-template-columns'] = "subgrid []" should set the property value
|
||||
Pass e.style['grid-template-columns'] = "subgrid [a] [b] [] [c]" should set the property value
|
||||
Pass e.style['grid-template-columns'] = "subgrid [] [] [] [c]" should set the property value
|
||||
Pass e.style['grid-template-columns'] = "subgrid [] [] [] []" should set the property value
|
||||
Pass e.style['grid-template-columns'] = "subgrid repeat(auto-fill, [a])" should set the property value
|
||||
Pass e.style['grid-template-columns'] = "subgrid repeat(auto-fill, [])" should set the property value
|
||||
Pass e.style['grid-template-columns'] = "subgrid [a] repeat(auto-fill, [b])" should set the property value
|
||||
Pass e.style['grid-template-columns'] = "subgrid [a] repeat(auto-fill, [b]) [c]" should set the property value
|
||||
Pass e.style['grid-template-columns'] = "subgrid [] repeat(auto-fill, []) []" should set the property value
|
||||
Pass e.style['grid-template-columns'] = "subgrid repeat(2, [a])" should set the property value
|
||||
Pass e.style['grid-template-columns'] = "subgrid repeat(2, [a] [b])" should set the property value
|
||||
Pass e.style['grid-template-columns'] = "subgrid [a] repeat(2, [b])" should set the property value
|
||||
Pass e.style['grid-template-columns'] = "subgrid [a] repeat(2, [b]) [c]" should set the property value
|
||||
Pass e.style['grid-template-columns'] = "subgrid [] repeat(2, []) []" should set the property value
|
||||
Pass e.style['grid-template-columns'] = "subgrid [a] repeat(2, [b]) repeat(auto-fill, [c]) [d]" should set the property value
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
<!DOCTYPE html>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.parent {
|
||||
display: grid;
|
||||
grid-template-columns: 10px 20px;
|
||||
}
|
||||
|
||||
.target {
|
||||
display: grid;
|
||||
grid-column: 1 / span 2;
|
||||
grid-template-columns: subgrid [a] [b] [c];
|
||||
}
|
||||
</style>
|
||||
<div class="parent"><div class="target"></div></div>
|
||||
<script src="../include.js"></script>
|
||||
<script>
|
||||
test(() => {
|
||||
const target = document.querySelector(".target");
|
||||
const animation = target.animate([
|
||||
{ gridTemplateColumns: "subgrid [a] [b] [c]" },
|
||||
{ gridTemplateColumns: "subgrid [x] [y] [z]" },
|
||||
], { duration: 1000, fill: "both" });
|
||||
animation.pause();
|
||||
|
||||
for (const time of [250, 500, 750]) {
|
||||
animation.currentTime = time;
|
||||
println(`${time}: ${getComputedStyle(target).gridTemplateColumns}`);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Grid Layout Test: getComputedStyle().gridTemplateColumns</title>
|
||||
<link rel="author" title="Mozilla" href="https://mozilla.org">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-grid-2/#resolved-track-list" "title"="2.3. Resolved Value of a Track Listing">
|
||||
<meta name="assert" content="Checks the resolved value of grid-template-columns or grid-template-columns on an element which is not a grid container.">
|
||||
<style>
|
||||
#target {
|
||||
display: block;
|
||||
height: 1px;
|
||||
font-size: 1px;
|
||||
}
|
||||
</style>
|
||||
<script src="../../../resources/testharness.js"></script>
|
||||
<script src="../../../resources/testharnessreport.js"></script>
|
||||
<script src="../../../css/support/computed-testcommon.js"></script>
|
||||
<div id="target"></div>
|
||||
<script>
|
||||
test_computed_value("grid-template-columns", "subgrid []");
|
||||
test_computed_value("grid-template-columns", "subgrid [a]");
|
||||
test_computed_value("grid-template-columns", "subgrid [a] [b]");
|
||||
test_computed_value("grid-template-columns", "subgrid [] [b]");
|
||||
test_computed_value("grid-template-columns", "subgrid [a] [b] [b] [c]");
|
||||
test_computed_value("grid-template-columns", "subgrid [a] [b c d] [e f] [e f] [g]");
|
||||
test_computed_value("grid-template-columns", "subgrid [a b c] [d] [e f]");
|
||||
test_computed_value("grid-template-columns", "subgrid repeat(auto-fill, [c])");
|
||||
test_computed_value("grid-template-columns", "subgrid repeat(auto-fill, [])");
|
||||
test_computed_value("grid-template-columns", "subgrid repeat(auto-fill, [c]) [g] [h i]");
|
||||
test_computed_value("grid-template-columns", "subgrid [a] repeat(auto-fill, [c]) [g] [h i]");
|
||||
test_computed_value("grid-template-columns", "subgrid [a b] repeat(auto-fill, [c]) [g]");
|
||||
test_computed_value("grid-template-columns", "subgrid [a] [b] repeat(auto-fill, [c]) [g h]");
|
||||
test_computed_value("grid-template-columns", "subgrid [a] [b] repeat(auto-fill, [c])");
|
||||
test_computed_value("grid-template-columns", "subgrid repeat(auto-fill, [c d])");
|
||||
test_computed_value("grid-template-columns", "subgrid repeat(auto-fill, [c d]) [g] [h i]");
|
||||
test_computed_value("grid-template-columns", "subgrid [a] repeat(auto-fill, [c d]) [g] [h i]");
|
||||
test_computed_value("grid-template-columns", "subgrid [a b] repeat(auto-fill, [c d]) [g]");
|
||||
test_computed_value("grid-template-columns", "subgrid [a] [b] repeat(auto-fill, [c d]) [g h]");
|
||||
test_computed_value("grid-template-columns", "subgrid [a] [b] repeat(auto-fill, [c d])");
|
||||
test_computed_value("grid-template-columns", "subgrid repeat(auto-fill, [c] [d])");
|
||||
test_computed_value("grid-template-columns", "subgrid repeat(auto-fill, [c] [d]) [g] [h i]");
|
||||
test_computed_value("grid-template-columns", "subgrid [a] repeat(auto-fill, [c] [d]) [g] [h i]");
|
||||
test_computed_value("grid-template-columns", "subgrid [a b] repeat(auto-fill, [c] [d]) [g]");
|
||||
test_computed_value("grid-template-columns", "subgrid [a] [b] repeat(auto-fill, [c] [d]) [g h]");
|
||||
test_computed_value("grid-template-columns", "subgrid [a] [b] repeat(auto-fill, [c] [d])");
|
||||
test_computed_value("grid-template-columns", "subgrid repeat(auto-fill, [c] [d e])");
|
||||
test_computed_value("grid-template-columns", "subgrid repeat(auto-fill, [c] [d e]) [g] [h i]");
|
||||
test_computed_value("grid-template-columns", "subgrid [a] repeat(auto-fill, [c] [d e]) [g] [h i]");
|
||||
test_computed_value("grid-template-columns", "subgrid [a b] repeat(auto-fill, [c] [d e]) [g]");
|
||||
test_computed_value("grid-template-columns", "subgrid [a] [b] repeat(auto-fill, [c] [d e]) [g h]");
|
||||
test_computed_value("grid-template-columns", "subgrid [a] [b] repeat(auto-fill, [c] [d e])");
|
||||
test_computed_value("grid-template-columns", "subgrid [a] repeat(2, [c] [d e])");
|
||||
test_computed_value("grid-template-columns", "subgrid repeat(1, [])");
|
||||
test_computed_value("grid-template-columns", "subgrid repeat(2, [])");
|
||||
test_computed_value("grid-template-columns", "subgrid repeat(2, [a])");
|
||||
test_computed_value("grid-template-columns", "subgrid repeat(2, [a] [])");
|
||||
test_computed_value("grid-template-columns", "subgrid repeat(2, [] [a] [])");
|
||||
test_computed_value("grid-template-columns", "subgrid repeat(2, [] [] []) repeat(auto-fill, [] [] [])");
|
||||
test_computed_value("grid-template-columns", "subgrid repeat(1, [a b])");
|
||||
test_computed_value("grid-template-columns", "subgrid repeat(2, [a b])");
|
||||
test_computed_value("grid-template-columns", "subgrid repeat(1, [a] [b])");
|
||||
test_computed_value("grid-template-columns", "subgrid repeat(2, [a] [b])");
|
||||
test_computed_value("grid-template-columns", "subgrid [a] repeat(2, [b])");
|
||||
test_computed_value("grid-template-columns", "subgrid repeat(2, [a]) [b]");
|
||||
test_computed_value("grid-template-columns", "subgrid [a] repeat(2, [b] [c d]) [e]");
|
||||
test_computed_value("grid-template-columns", "subgrid repeat(2, [a b]) repeat(auto-fill, [c] [d e])");
|
||||
test_computed_value("grid-template-columns", "subgrid repeat(auto-fill, [a] [b c]) repeat(2, [d e])");
|
||||
test_computed_value("grid-template-columns", "subgrid repeat(2, [a b]) repeat(auto-fill, [c] [d e]) repeat(2, [f g])");
|
||||
test_computed_value("grid-template-columns", "subgrid [a] [b c] repeat(2, [d e]) [f] [g h] repeat(auto-fill, [i] [j k]) [l] repeat(2, [m n]) [o]");
|
||||
</script>
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Grid Layout Test: parsing 'grid' with invalid values</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-grid-2">
|
||||
<meta name="assert" content="grid-template supports the grammar `none | <track-list> | <auto-track-list> | subgrid <line-name-list>?`.">
|
||||
<script src="../../../resources/testharness.js"></script>
|
||||
<script src="../../../resources/testharnessreport.js"></script>
|
||||
<script src="../../../css/support/parsing-testcommon.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
// <'grid-template'> invalid values
|
||||
test_invalid_value("grid-template-rows", 'subgrid subgrid');
|
||||
test_invalid_value("grid-template-rows", 'subgrid none');
|
||||
test_invalid_value("grid-template-rows", 'subgrid 1px');
|
||||
test_invalid_value("grid-template-rows", 'subgrid [a] 1px');
|
||||
test_invalid_value("grid-template-rows", 'subgrid repeat(auto-fill, 1px)');
|
||||
test_invalid_value("grid-template-rows", 'subgrid repeat(auto-fill, line)');
|
||||
test_invalid_value("grid-template-rows", 'subgrid repeat(auto-fit, [a])');
|
||||
test_invalid_value("grid-template-rows", 'subgrid repeat(2, 1px)');
|
||||
test_invalid_value("grid-template-rows", 'subgrid repeat(2, line)');
|
||||
test_invalid_value("grid-template-rows", 'subgrid repeat(2,');
|
||||
test_invalid_value("grid-template-rows", 'subgrid repeat(auto-fill, [a]) repeat(auto-fill, [b]');
|
||||
|
||||
test_invalid_value("grid-template-columns", 'subgrid subgrid');
|
||||
test_invalid_value("grid-template-columns", 'subgrid none');
|
||||
test_invalid_value("grid-template-columns", 'subgrid 1px');
|
||||
test_invalid_value("grid-template-columns", 'subgrid [a] 1px');
|
||||
test_invalid_value("grid-template-columns", 'subgrid repeat(auto-fill, 1px)');
|
||||
test_invalid_value("grid-template-columns", 'subgrid repeat(auto-fill, line)');
|
||||
test_invalid_value("grid-template-columns", 'subgrid repeat(auto-fit, [a])');
|
||||
test_invalid_value("grid-template-columns", 'subgrid repeat(2, 1px)');
|
||||
test_invalid_value("grid-template-columns", 'subgrid repeat(2, line)');
|
||||
test_invalid_value("grid-template-columns", 'subgrid repeat(2,');
|
||||
test_invalid_value("grid-template-columns", 'subgrid repeat(auto-fill, [a]) repeat(auto-fill, [b]');
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Grid Layout Test: parsing 'grid' with valid values</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-grid-2">
|
||||
<meta name="assert" content="grid-template supports the grammar `none | <track-list> | <auto-track-list> | subgrid <line-name-list>?`.">
|
||||
<script src="../../../resources/testharness.js"></script>
|
||||
<script src="../../../resources/testharnessreport.js"></script>
|
||||
<script src="../../../css/support/parsing-testcommon.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
// <'grid-template'> values
|
||||
test_valid_value("grid-template-rows", 'subgrid');
|
||||
test_valid_value("grid-template-rows", 'subgrid [a]');
|
||||
test_valid_value("grid-template-rows", 'subgrid [a] [b]');
|
||||
test_valid_value("grid-template-rows", 'subgrid [a] [b] [c]');
|
||||
test_valid_value("grid-template-rows", 'subgrid []');
|
||||
test_valid_value("grid-template-rows", 'subgrid [a] [b] [] [c]');
|
||||
test_valid_value("grid-template-rows", 'subgrid [] [] [] [c]');
|
||||
test_valid_value("grid-template-rows", 'subgrid [] [] [] []');
|
||||
test_valid_value("grid-template-rows", 'subgrid repeat(auto-fill, [a])');
|
||||
test_valid_value("grid-template-rows", 'subgrid repeat(auto-fill, [])');
|
||||
test_valid_value("grid-template-rows", 'subgrid [a] repeat(auto-fill, [b])');
|
||||
test_valid_value("grid-template-rows", 'subgrid [a] repeat(auto-fill, [b]) [c]');
|
||||
test_valid_value("grid-template-rows", 'subgrid [] repeat(auto-fill, []) []');
|
||||
test_valid_value("grid-template-rows", 'subgrid repeat(2, [a])');
|
||||
test_valid_value("grid-template-rows", 'subgrid repeat(2, [a] [b])');
|
||||
test_valid_value("grid-template-rows", 'subgrid [a] repeat(2, [b])');
|
||||
test_valid_value("grid-template-rows", 'subgrid [a] repeat(2, [b]) [c]');
|
||||
test_valid_value("grid-template-rows", 'subgrid [] repeat(2, []) []');
|
||||
test_valid_value("grid-template-rows", 'subgrid [a] repeat(2, [b]) repeat(auto-fill, [c]) [d]');
|
||||
|
||||
test_valid_value("grid-template-columns", 'subgrid');
|
||||
test_valid_value("grid-template-columns", 'subgrid [a]');
|
||||
test_valid_value("grid-template-columns", 'subgrid [a] [b]');
|
||||
test_valid_value("grid-template-columns", 'subgrid [a] [b] [c]');
|
||||
test_valid_value("grid-template-columns", 'subgrid []');
|
||||
test_valid_value("grid-template-columns", 'subgrid [a] [b] [] [c]');
|
||||
test_valid_value("grid-template-columns", 'subgrid [] [] [] [c]');
|
||||
test_valid_value("grid-template-columns", 'subgrid [] [] [] []');
|
||||
test_valid_value("grid-template-columns", 'subgrid repeat(auto-fill, [a])');
|
||||
test_valid_value("grid-template-columns", 'subgrid repeat(auto-fill, [])');
|
||||
test_valid_value("grid-template-columns", 'subgrid [a] repeat(auto-fill, [b])');
|
||||
test_valid_value("grid-template-columns", 'subgrid [a] repeat(auto-fill, [b]) [c]');
|
||||
test_valid_value("grid-template-columns", 'subgrid [] repeat(auto-fill, []) []');
|
||||
test_valid_value("grid-template-columns", 'subgrid repeat(2, [a])');
|
||||
test_valid_value("grid-template-columns", 'subgrid repeat(2, [a] [b])');
|
||||
test_valid_value("grid-template-columns", 'subgrid [a] repeat(2, [b])');
|
||||
test_valid_value("grid-template-columns", 'subgrid [a] repeat(2, [b]) [c]');
|
||||
test_valid_value("grid-template-columns", 'subgrid [] repeat(2, []) []');
|
||||
test_valid_value("grid-template-columns", 'subgrid [a] repeat(2, [b]) repeat(auto-fill, [c]) [d]');
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Reference in a new issue