mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-12-08 06:09:58 +00:00
LibWeb: Parse the view-timeline shorthand CSS property
The remaining failing tests in view-timeline-shorthand.html are due to either: a) incorrect tests, see web-platform-tests/wpt#56181 or; b) a wider issue where we collapse coordinating value list longhand properties to a single value when we shouldn't.
This commit is contained in:
parent
e093c76eea
commit
6bb7224f4e
Notes:
github-actions[bot]
2025-11-28 13:25:55 +00:00
Author: https://github.com/Calme1709
Commit: 6bb7224f4e
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6912
Reviewed-by: https://github.com/AtkinsSJ ✅
8 changed files with 413 additions and 2 deletions
|
|
@ -532,6 +532,7 @@ private:
|
||||||
RefPtr<StyleValue const> parse_grid_area_shorthand_value(TokenStream<ComponentValue>&);
|
RefPtr<StyleValue const> parse_grid_area_shorthand_value(TokenStream<ComponentValue>&);
|
||||||
RefPtr<StyleValue const> parse_grid_shorthand_value(TokenStream<ComponentValue>&);
|
RefPtr<StyleValue const> parse_grid_shorthand_value(TokenStream<ComponentValue>&);
|
||||||
RefPtr<StyleValue const> parse_touch_action_value(TokenStream<ComponentValue>&);
|
RefPtr<StyleValue const> parse_touch_action_value(TokenStream<ComponentValue>&);
|
||||||
|
RefPtr<StyleValue const> parse_view_timeline_value(TokenStream<ComponentValue>&);
|
||||||
RefPtr<StyleValue const> parse_white_space_shorthand(TokenStream<ComponentValue>&);
|
RefPtr<StyleValue const> parse_white_space_shorthand(TokenStream<ComponentValue>&);
|
||||||
RefPtr<StyleValue const> parse_white_space_trim_value(TokenStream<ComponentValue>&);
|
RefPtr<StyleValue const> parse_white_space_trim_value(TokenStream<ComponentValue>&);
|
||||||
RefPtr<StyleValue const> parse_will_change_value(TokenStream<ComponentValue>&);
|
RefPtr<StyleValue const> parse_will_change_value(TokenStream<ComponentValue>&);
|
||||||
|
|
|
||||||
|
|
@ -752,6 +752,8 @@ Parser::ParseErrorOr<NonnullRefPtr<StyleValue const>> Parser::parse_css_value(Pr
|
||||||
case PropertyID::ScrollTimelineAxis:
|
case PropertyID::ScrollTimelineAxis:
|
||||||
case PropertyID::ScrollTimelineName:
|
case PropertyID::ScrollTimelineName:
|
||||||
return parse_all_as(tokens, [this, property_id](auto& tokens) { return parse_simple_comma_separated_value_list(property_id, tokens); });
|
return parse_all_as(tokens, [this, property_id](auto& tokens) { return parse_simple_comma_separated_value_list(property_id, tokens); });
|
||||||
|
case PropertyID::ViewTimeline:
|
||||||
|
return parse_all_as(tokens, [this](auto& tokens) { return parse_view_timeline_value(tokens); });
|
||||||
case PropertyID::ViewTimelineAxis:
|
case PropertyID::ViewTimelineAxis:
|
||||||
case PropertyID::ViewTimelineInset:
|
case PropertyID::ViewTimelineInset:
|
||||||
case PropertyID::ViewTimelineName:
|
case PropertyID::ViewTimelineName:
|
||||||
|
|
@ -6347,6 +6349,115 @@ RefPtr<StyleValue const> Parser::parse_white_space_shorthand(TokenStream<Compone
|
||||||
return make_whitespace_shorthand(white_space_collapse, text_wrap_mode, white_space_trim);
|
return make_whitespace_shorthand(white_space_collapse, text_wrap_mode, white_space_trim);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://drafts.csswg.org/scroll-animations-1/#view-timeline-shorthand
|
||||||
|
RefPtr<StyleValue const> Parser::parse_view_timeline_value(TokenStream<ComponentValue>& tokens)
|
||||||
|
{
|
||||||
|
// [ <'view-timeline-name'> [ <'view-timeline-axis'> || <'view-timeline-inset'> ]? ]#
|
||||||
|
StyleValueVector names;
|
||||||
|
StyleValueVector axes;
|
||||||
|
StyleValueVector insets;
|
||||||
|
|
||||||
|
auto transaction = tokens.begin_transaction();
|
||||||
|
|
||||||
|
do {
|
||||||
|
RefPtr<StyleValue const> name;
|
||||||
|
RefPtr<StyleValue const> axis;
|
||||||
|
RefPtr<StyleValue const> inset;
|
||||||
|
|
||||||
|
auto const append_entry = [&]() {
|
||||||
|
VERIFY(name);
|
||||||
|
names.append(name.release_nonnull());
|
||||||
|
|
||||||
|
// FIXME: Use the first entry in property_initial_value() to get the initial values for these longhands once
|
||||||
|
// we always parse them as lists.
|
||||||
|
if (axis)
|
||||||
|
axes.append(axis.release_nonnull());
|
||||||
|
else
|
||||||
|
axes.append(KeywordStyleValue::create(Keyword::Block));
|
||||||
|
|
||||||
|
if (inset)
|
||||||
|
insets.append(inset.release_nonnull());
|
||||||
|
else
|
||||||
|
insets.append(StyleValueList::create({ KeywordStyleValue::create(Keyword::Auto), KeywordStyleValue::create(Keyword::Auto) }, StyleValueList::Separator::Space));
|
||||||
|
};
|
||||||
|
|
||||||
|
tokens.discard_whitespace();
|
||||||
|
|
||||||
|
auto maybe_name = parse_css_value_for_property(PropertyID::ViewTimelineName, tokens);
|
||||||
|
|
||||||
|
if (!maybe_name)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
name = maybe_name;
|
||||||
|
|
||||||
|
tokens.discard_whitespace();
|
||||||
|
|
||||||
|
if (tokens.next_token().is(Token::Type::Comma)) {
|
||||||
|
tokens.discard_a_token();
|
||||||
|
|
||||||
|
// Disallow trailing commas
|
||||||
|
if (!tokens.has_next_token())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
append_entry();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto remaining_longhands = Vector { PropertyID::ViewTimelineAxis, PropertyID::ViewTimelineInset };
|
||||||
|
|
||||||
|
while (tokens.has_next_token() && !tokens.next_token().is(Token::Type::Comma)) {
|
||||||
|
tokens.discard_whitespace();
|
||||||
|
|
||||||
|
auto property_and_value = parse_css_value_for_properties(remaining_longhands, tokens);
|
||||||
|
|
||||||
|
if (!property_and_value.has_value())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
remove_property(remaining_longhands, property_and_value->property);
|
||||||
|
|
||||||
|
switch (property_and_value->property) {
|
||||||
|
case PropertyID::ViewTimelineAxis:
|
||||||
|
if (axis)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
axis = property_and_value->style_value;
|
||||||
|
break;
|
||||||
|
case PropertyID::ViewTimelineInset:
|
||||||
|
if (inset)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
inset = property_and_value->style_value;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
append_entry();
|
||||||
|
|
||||||
|
if (tokens.next_token().is(Token::Type::Comma)) {
|
||||||
|
tokens.discard_a_token();
|
||||||
|
|
||||||
|
// Disallow trailing commas
|
||||||
|
if (!tokens.has_next_token())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tokens.has_next_token())
|
||||||
|
return nullptr;
|
||||||
|
} while (tokens.has_next_token());
|
||||||
|
|
||||||
|
transaction.commit();
|
||||||
|
|
||||||
|
return ShorthandStyleValue::create(PropertyID::ViewTimeline,
|
||||||
|
{ PropertyID::ViewTimelineName, PropertyID::ViewTimelineAxis, PropertyID::ViewTimelineInset },
|
||||||
|
{ StyleValueList::create(move(names), StyleValueList::Separator::Comma),
|
||||||
|
StyleValueList::create(move(axes), StyleValueList::Separator::Comma),
|
||||||
|
StyleValueList::create(move(insets), StyleValueList::Separator::Comma) });
|
||||||
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/css-will-change/#will-change
|
// https://drafts.csswg.org/css-will-change/#will-change
|
||||||
RefPtr<StyleValue const> Parser::parse_will_change_value(TokenStream<ComponentValue>& tokens)
|
RefPtr<StyleValue const> Parser::parse_will_change_value(TokenStream<ComponentValue>& tokens)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -4013,6 +4013,17 @@
|
||||||
"unitless-length"
|
"unitless-length"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"view-timeline": {
|
||||||
|
"affects-layout": false,
|
||||||
|
"inherited": false,
|
||||||
|
"initial": "none",
|
||||||
|
"multiplicity": "coordinating-list",
|
||||||
|
"longhands": [
|
||||||
|
"view-timeline-name",
|
||||||
|
"view-timeline-axis",
|
||||||
|
"view-timeline-inset"
|
||||||
|
]
|
||||||
|
},
|
||||||
"view-timeline-axis": {
|
"view-timeline-axis": {
|
||||||
"affects-layout": false,
|
"affects-layout": false,
|
||||||
"animation-type": "none",
|
"animation-type": "none",
|
||||||
|
|
|
||||||
|
|
@ -849,6 +849,36 @@ String ShorthandStyleValue::to_string(SerializationMode mode) const
|
||||||
}
|
}
|
||||||
case PropertyID::Transition:
|
case PropertyID::Transition:
|
||||||
return coordinating_value_list_shorthand_to_string("all"sv);
|
return coordinating_value_list_shorthand_to_string("all"sv);
|
||||||
|
case PropertyID::ViewTimeline: {
|
||||||
|
// FIXME: We can use coordinating_value_list_shorthand_to_string function once parse_comma_separated_value_list
|
||||||
|
// always returns a list, currently it doesn't properly handle the fact that the entries for
|
||||||
|
// view-timeline-inset are themselves StyleValueLists
|
||||||
|
StringBuilder builder;
|
||||||
|
|
||||||
|
auto const& name_values = style_value_as_value_list(longhand(PropertyID::ViewTimelineName));
|
||||||
|
auto const& axis_values = style_value_as_value_list(longhand(PropertyID::ViewTimelineAxis));
|
||||||
|
auto const& inset_values = style_value_as_value_list(longhand(PropertyID::ViewTimelineInset));
|
||||||
|
|
||||||
|
if (name_values.size() != axis_values.size())
|
||||||
|
return ""_string;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < name_values.size(); i++) {
|
||||||
|
if (!builder.is_empty())
|
||||||
|
builder.append(", "sv);
|
||||||
|
|
||||||
|
builder.append(name_values[i]->to_string(mode));
|
||||||
|
|
||||||
|
if (axis_values[i]->to_keyword() != Keyword::Block)
|
||||||
|
builder.appendff(" {}", axis_values[i]->to_string(mode));
|
||||||
|
|
||||||
|
auto stringified_inset = inset_values[i]->to_string(mode);
|
||||||
|
|
||||||
|
if (stringified_inset != "auto"sv)
|
||||||
|
builder.appendff(" {}", stringified_inset);
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.to_string_without_validation();
|
||||||
|
}
|
||||||
case PropertyID::WhiteSpace: {
|
case PropertyID::WhiteSpace: {
|
||||||
auto white_space_collapse_property = longhand(PropertyID::WhiteSpaceCollapse);
|
auto white_space_collapse_property = longhand(PropertyID::WhiteSpaceCollapse);
|
||||||
auto text_wrap_mode_property = longhand(PropertyID::TextWrapMode);
|
auto text_wrap_mode_property = longhand(PropertyID::TextWrapMode);
|
||||||
|
|
|
||||||
|
|
@ -801,6 +801,8 @@ All supported properties and their default values exposed from CSSStylePropertie
|
||||||
'user-select': 'auto'
|
'user-select': 'auto'
|
||||||
'verticalAlign': 'baseline'
|
'verticalAlign': 'baseline'
|
||||||
'vertical-align': 'baseline'
|
'vertical-align': 'baseline'
|
||||||
|
'viewTimeline': 'none'
|
||||||
|
'view-timeline': 'none'
|
||||||
'viewTimelineAxis': 'block'
|
'viewTimelineAxis': 'block'
|
||||||
'view-timeline-axis': 'block'
|
'view-timeline-axis': 'block'
|
||||||
'viewTimelineInset': 'auto'
|
'viewTimelineInset': 'auto'
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
Harness status: OK
|
Harness status: OK
|
||||||
|
|
||||||
Found 274 tests
|
Found 277 tests
|
||||||
|
|
||||||
268 Pass
|
271 Pass
|
||||||
6 Fail
|
6 Fail
|
||||||
Pass accent-color
|
Pass accent-color
|
||||||
Pass border-collapse
|
Pass border-collapse
|
||||||
|
|
@ -271,6 +271,9 @@ Pass translate
|
||||||
Pass unicode-bidi
|
Pass unicode-bidi
|
||||||
Pass user-select
|
Pass user-select
|
||||||
Pass vertical-align
|
Pass vertical-align
|
||||||
|
Pass view-timeline-axis
|
||||||
|
Pass view-timeline-inset
|
||||||
|
Pass view-timeline-name
|
||||||
Pass view-transition-name
|
Pass view-transition-name
|
||||||
Pass white-space-trim
|
Pass white-space-trim
|
||||||
Fail width
|
Fail width
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
Harness status: OK
|
||||||
|
|
||||||
|
Found 83 tests
|
||||||
|
|
||||||
|
78 Pass
|
||||||
|
5 Fail
|
||||||
|
Pass e.style['view-timeline'] = "--abcd" should set the property value
|
||||||
|
Pass e.style['view-timeline'] = "none block" should set the property value
|
||||||
|
Pass e.style['view-timeline'] = "none inline" should set the property value
|
||||||
|
Pass e.style['view-timeline'] = "--inline block" should set the property value
|
||||||
|
Pass e.style['view-timeline'] = "--block block" should set the property value
|
||||||
|
Pass e.style['view-timeline'] = "--y block" should set the property value
|
||||||
|
Pass e.style['view-timeline'] = "--x block" should set the property value
|
||||||
|
Pass e.style['view-timeline'] = "--a, --b, --c" should set the property value
|
||||||
|
Pass e.style['view-timeline'] = "--a inline, --b block, --c y" should set the property value
|
||||||
|
Pass e.style['view-timeline'] = "--auto" should set the property value
|
||||||
|
Pass e.style['view-timeline'] = "--abcd block auto" should set the property value
|
||||||
|
Pass e.style['view-timeline'] = "--abcd block auto auto" should set the property value
|
||||||
|
Pass e.style['view-timeline'] = "--abcd block 1px 2px" should set the property value
|
||||||
|
Pass e.style['view-timeline'] = "--abcd inline 1px 2px" should set the property value
|
||||||
|
Pass e.style['view-timeline'] = "--abcd 1px 2px inline" should set the property value
|
||||||
|
Pass e.style['view-timeline'] = "--abcd 1px 2px block" should set the property value
|
||||||
|
Pass e.style['view-timeline'] = "--abcd auto auto block" should set the property value
|
||||||
|
Pass e.style['view-timeline'] = "--abcd auto block" should set the property value
|
||||||
|
Pass e.style['view-timeline'] = "--abcd block 1px 1px" should set the property value
|
||||||
|
Pass e.style['view-timeline'] = "--abc --abc" should not set the property value
|
||||||
|
Pass e.style['view-timeline'] = "block none" should not set the property value
|
||||||
|
Pass e.style['view-timeline'] = "none none" should not set the property value
|
||||||
|
Pass e.style['view-timeline'] = "default" should not set the property value
|
||||||
|
Pass e.style['view-timeline'] = "," should not set the property value
|
||||||
|
Pass e.style['view-timeline'] = ",,--block,," should not set the property value
|
||||||
|
Pass e.style['view-timeline'] = "auto" should not set the property value
|
||||||
|
Pass e.style['view-timeline'] = "auto auto" should not set the property value
|
||||||
|
Pass e.style['view-timeline'] = "--abc 500kg" should not set the property value
|
||||||
|
Pass e.style['view-timeline'] = "--abc #ff0000" should not set the property value
|
||||||
|
Pass e.style['view-timeline'] = "--abc red red" should not set the property value
|
||||||
|
Pass Property view-timeline value '--abcd'
|
||||||
|
Pass Property view-timeline value 'none block'
|
||||||
|
Pass Property view-timeline value 'none inline'
|
||||||
|
Pass Property view-timeline value '--inline block'
|
||||||
|
Pass Property view-timeline value '--block block'
|
||||||
|
Pass Property view-timeline value '--y block'
|
||||||
|
Pass Property view-timeline value '--x block'
|
||||||
|
Pass Property view-timeline value '--a, --b, --c'
|
||||||
|
Pass Property view-timeline value '--a inline, --b block, --c y'
|
||||||
|
Pass Property view-timeline value '--abcd block auto'
|
||||||
|
Pass Property view-timeline value '--abcd block auto auto'
|
||||||
|
Pass Property view-timeline value '--abcd block 1px 2px'
|
||||||
|
Pass Property view-timeline value '--abcd inline 1px 2px'
|
||||||
|
Pass Property view-timeline value '--abcd 1px 2px inline'
|
||||||
|
Pass Property view-timeline value '--abcd 1px 2px block'
|
||||||
|
Pass Property view-timeline value '--abcd auto auto block'
|
||||||
|
Pass Property view-timeline value '--abcd auto block'
|
||||||
|
Pass Property view-timeline value '--abcd block 1px 1px'
|
||||||
|
Pass e.style['view-timeline'] = "--abc y" should set view-timeline-axis
|
||||||
|
Pass e.style['view-timeline'] = "--abc y" should set view-timeline-inset
|
||||||
|
Pass e.style['view-timeline'] = "--abc y" should set view-timeline-name
|
||||||
|
Pass e.style['view-timeline'] = "--abc y" should not set unrelated longhands
|
||||||
|
Pass e.style['view-timeline'] = "--abc y, --def" should set view-timeline-axis
|
||||||
|
Fail e.style['view-timeline'] = "--abc y, --def" should set view-timeline-inset
|
||||||
|
Pass e.style['view-timeline'] = "--abc y, --def" should set view-timeline-name
|
||||||
|
Pass e.style['view-timeline'] = "--abc y, --def" should not set unrelated longhands
|
||||||
|
Fail e.style['view-timeline'] = "--abc, --def" should set view-timeline-axis
|
||||||
|
Fail e.style['view-timeline'] = "--abc, --def" should set view-timeline-inset
|
||||||
|
Pass e.style['view-timeline'] = "--abc, --def" should set view-timeline-name
|
||||||
|
Pass e.style['view-timeline'] = "--abc, --def" should not set unrelated longhands
|
||||||
|
Pass e.style['view-timeline'] = "--inline x" should set view-timeline-axis
|
||||||
|
Pass e.style['view-timeline'] = "--inline x" should set view-timeline-inset
|
||||||
|
Pass e.style['view-timeline'] = "--inline x" should set view-timeline-name
|
||||||
|
Pass e.style['view-timeline'] = "--inline x" should not set unrelated longhands
|
||||||
|
Pass e.style['view-timeline'] = "--abc 1px 2px" should set view-timeline-axis
|
||||||
|
Pass e.style['view-timeline'] = "--abc 1px 2px" should set view-timeline-inset
|
||||||
|
Pass e.style['view-timeline'] = "--abc 1px 2px" should set view-timeline-name
|
||||||
|
Pass e.style['view-timeline'] = "--abc 1px 2px" should not set unrelated longhands
|
||||||
|
Pass e.style['view-timeline'] = "--abc 1px" should set view-timeline-axis
|
||||||
|
Pass e.style['view-timeline'] = "--abc 1px" should set view-timeline-inset
|
||||||
|
Pass e.style['view-timeline'] = "--abc 1px" should set view-timeline-name
|
||||||
|
Pass e.style['view-timeline'] = "--abc 1px" should not set unrelated longhands
|
||||||
|
Pass e.style['view-timeline'] = "--abc 1px inline" should set view-timeline-axis
|
||||||
|
Pass e.style['view-timeline'] = "--abc 1px inline" should set view-timeline-inset
|
||||||
|
Pass e.style['view-timeline'] = "--abc 1px inline" should set view-timeline-name
|
||||||
|
Pass e.style['view-timeline'] = "--abc 1px inline" should not set unrelated longhands
|
||||||
|
Pass Shorthand contraction of view-timeline-name:--abc:undefined;view-timeline-axis:inline:undefined;view-timeline-inset:auto:undefined
|
||||||
|
Pass Shorthand contraction of view-timeline-name:--a, --b:undefined;view-timeline-axis:inline, block:undefined;view-timeline-inset:auto, auto:undefined
|
||||||
|
Pass Shorthand contraction of view-timeline-name:--a, --b:undefined;view-timeline-axis:inline, block:undefined;view-timeline-inset:1px 2px, 3px 3px:undefined
|
||||||
|
Pass Shorthand contraction of view-timeline-name:none, none:undefined;view-timeline-axis:block, block:undefined;view-timeline-inset:auto auto, auto:undefined
|
||||||
|
Fail Shorthand contraction of view-timeline-name:--a, --b, --c:undefined;view-timeline-axis:inline, inline:undefined;view-timeline-inset:auto, auto:undefined
|
||||||
|
Fail Shorthand contraction of view-timeline-name:--a, --b:undefined;view-timeline-axis:inline, inline, inline:undefined;view-timeline-inset:auto, auto, auto:undefined
|
||||||
|
Pass Shorthand contraction of view-timeline-name:--a, --b:undefined;view-timeline-axis:inline, inline:undefined;view-timeline-inset:auto, auto, auto:undefined
|
||||||
|
|
@ -0,0 +1,164 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#view-timeline-shorthand">
|
||||||
|
<script src="../../resources/testharness.js"></script>
|
||||||
|
<script src="../../resources/testharnessreport.js"></script>
|
||||||
|
<script src="../../css/support/computed-testcommon.js"></script>
|
||||||
|
<script src="../../css/support/parsing-testcommon.js"></script>
|
||||||
|
<script src="../../css/support/shorthand-testcommon.js"></script>
|
||||||
|
<div id="target"></div>
|
||||||
|
<script>
|
||||||
|
test_valid_value('view-timeline', '--abcd');
|
||||||
|
test_valid_value('view-timeline', 'none block', 'none');
|
||||||
|
test_valid_value('view-timeline', 'none inline');
|
||||||
|
|
||||||
|
// view-timeline-name: inline/block/x/y.
|
||||||
|
test_valid_value('view-timeline', '--inline block', '--inline');
|
||||||
|
test_valid_value('view-timeline', '--block block', '--block');
|
||||||
|
test_valid_value('view-timeline', '--y block', '--y');
|
||||||
|
test_valid_value('view-timeline', '--x block', '--x');
|
||||||
|
|
||||||
|
test_valid_value('view-timeline', '--a, --b, --c');
|
||||||
|
test_valid_value('view-timeline', '--a inline, --b block, --c y', '--a inline, --b, --c y');
|
||||||
|
test_valid_value('view-timeline', '--auto');
|
||||||
|
test_valid_value('view-timeline', '--abcd block auto', '--abcd');
|
||||||
|
test_valid_value('view-timeline', '--abcd block auto auto', '--abcd');
|
||||||
|
test_valid_value('view-timeline', '--abcd block 1px 2px', '--abcd 1px 2px');
|
||||||
|
test_valid_value('view-timeline', '--abcd inline 1px 2px', '--abcd inline 1px 2px');
|
||||||
|
test_valid_value('view-timeline', '--abcd 1px 2px inline', '--abcd inline 1px 2px');
|
||||||
|
test_valid_value('view-timeline', '--abcd 1px 2px block', '--abcd 1px 2px');
|
||||||
|
test_valid_value('view-timeline', '--abcd auto auto block', '--abcd');
|
||||||
|
test_valid_value('view-timeline', '--abcd auto block', '--abcd');
|
||||||
|
test_valid_value('view-timeline', '--abcd block 1px 1px', '--abcd 1px');
|
||||||
|
|
||||||
|
test_invalid_value('view-timeline', '--abc --abc');
|
||||||
|
test_invalid_value('view-timeline', 'block none');
|
||||||
|
test_invalid_value('view-timeline', 'none none');
|
||||||
|
test_invalid_value('view-timeline', 'default');
|
||||||
|
test_invalid_value('view-timeline', ',');
|
||||||
|
test_invalid_value('view-timeline', ',,--block,,');
|
||||||
|
test_invalid_value('view-timeline', 'auto');
|
||||||
|
test_invalid_value('view-timeline', 'auto auto');
|
||||||
|
test_invalid_value('view-timeline', '--abc 500kg');
|
||||||
|
test_invalid_value('view-timeline', '--abc #ff0000');
|
||||||
|
test_invalid_value('view-timeline', '--abc red red');
|
||||||
|
|
||||||
|
test_computed_value('view-timeline', '--abcd');
|
||||||
|
test_computed_value('view-timeline', 'none block', 'none');
|
||||||
|
test_computed_value('view-timeline', 'none inline');
|
||||||
|
test_computed_value('view-timeline', '--inline block', '--inline');
|
||||||
|
test_computed_value('view-timeline', '--block block', '--block');
|
||||||
|
test_computed_value('view-timeline', '--y block', '--y');
|
||||||
|
test_computed_value('view-timeline', '--x block', '--x');
|
||||||
|
test_computed_value('view-timeline', '--a, --b, --c');
|
||||||
|
test_computed_value('view-timeline', '--a inline, --b block, --c y', '--a inline, --b, --c y');
|
||||||
|
test_computed_value('view-timeline', '--abcd block auto', '--abcd');
|
||||||
|
test_computed_value('view-timeline', '--abcd block auto auto', '--abcd');
|
||||||
|
test_computed_value('view-timeline', '--abcd block 1px 2px', '--abcd 1px 2px');
|
||||||
|
test_computed_value('view-timeline', '--abcd inline 1px 2px', '--abcd inline 1px 2px');
|
||||||
|
test_computed_value('view-timeline', '--abcd 1px 2px inline', '--abcd inline 1px 2px');
|
||||||
|
test_computed_value('view-timeline', '--abcd 1px 2px block', '--abcd 1px 2px');
|
||||||
|
test_computed_value('view-timeline', '--abcd auto auto block', '--abcd');
|
||||||
|
test_computed_value('view-timeline', '--abcd auto block', '--abcd');
|
||||||
|
test_computed_value('view-timeline', '--abcd block 1px 1px', '--abcd 1px');
|
||||||
|
|
||||||
|
test_shorthand_value('view-timeline', '--abc y',
|
||||||
|
{
|
||||||
|
'view-timeline-name': '--abc',
|
||||||
|
'view-timeline-axis': 'y',
|
||||||
|
'view-timeline-inset': 'auto',
|
||||||
|
});
|
||||||
|
test_shorthand_value('view-timeline', '--abc y, --def',
|
||||||
|
{
|
||||||
|
'view-timeline-name': '--abc, --def',
|
||||||
|
'view-timeline-axis': 'y, block',
|
||||||
|
'view-timeline-inset': 'auto, auto',
|
||||||
|
});
|
||||||
|
test_shorthand_value('view-timeline', '--abc, --def',
|
||||||
|
{
|
||||||
|
'view-timeline-name': '--abc, --def',
|
||||||
|
'view-timeline-axis': 'block, block',
|
||||||
|
'view-timeline-inset': 'auto, auto',
|
||||||
|
});
|
||||||
|
test_shorthand_value('view-timeline', '--inline x',
|
||||||
|
{
|
||||||
|
'view-timeline-name': '--inline',
|
||||||
|
'view-timeline-axis': 'x',
|
||||||
|
'view-timeline-inset': 'auto',
|
||||||
|
});
|
||||||
|
test_shorthand_value('view-timeline', '--abc 1px 2px',
|
||||||
|
{
|
||||||
|
'view-timeline-name': '--abc',
|
||||||
|
'view-timeline-axis': 'block',
|
||||||
|
'view-timeline-inset': '1px 2px',
|
||||||
|
});
|
||||||
|
test_shorthand_value('view-timeline', '--abc 1px',
|
||||||
|
{
|
||||||
|
'view-timeline-name': '--abc',
|
||||||
|
'view-timeline-axis': 'block',
|
||||||
|
'view-timeline-inset': '1px',
|
||||||
|
});
|
||||||
|
test_shorthand_value('view-timeline', '--abc 1px inline',
|
||||||
|
{
|
||||||
|
'view-timeline-name': '--abc',
|
||||||
|
'view-timeline-axis': 'inline',
|
||||||
|
'view-timeline-inset': '1px',
|
||||||
|
});
|
||||||
|
|
||||||
|
function test_shorthand_contraction(shorthand, longhands, expected) {
|
||||||
|
let longhands_fmt = Object.entries(longhands).map((e) => `${e[0]}:${e[1]}:${e[2]}`).join(';');
|
||||||
|
test((t) => {
|
||||||
|
t.add_cleanup(() => {
|
||||||
|
for (let shorthand of Object.keys(longhands))
|
||||||
|
target.style.removeProperty(shorthand);
|
||||||
|
});
|
||||||
|
for (let [shorthand, value] of Object.entries(longhands))
|
||||||
|
target.style.setProperty(shorthand, value);
|
||||||
|
assert_equals(target.style.getPropertyValue(shorthand), expected, 'Declared value');
|
||||||
|
assert_equals(getComputedStyle(target).getPropertyValue(shorthand), expected, 'Computed value');
|
||||||
|
}, `Shorthand contraction of ${longhands_fmt}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
test_shorthand_contraction('view-timeline', {
|
||||||
|
'view-timeline-name': '--abc',
|
||||||
|
'view-timeline-axis': 'inline',
|
||||||
|
'view-timeline-inset': 'auto',
|
||||||
|
}, '--abc inline');
|
||||||
|
|
||||||
|
test_shorthand_contraction('view-timeline', {
|
||||||
|
'view-timeline-name': '--a, --b',
|
||||||
|
'view-timeline-axis': 'inline, block',
|
||||||
|
'view-timeline-inset': 'auto, auto',
|
||||||
|
}, '--a inline, --b');
|
||||||
|
|
||||||
|
test_shorthand_contraction('view-timeline', {
|
||||||
|
'view-timeline-name': '--a, --b',
|
||||||
|
'view-timeline-axis': 'inline, block',
|
||||||
|
'view-timeline-inset': '1px 2px, 3px 3px',
|
||||||
|
}, '--a inline 1px 2px, --b 3px');
|
||||||
|
|
||||||
|
test_shorthand_contraction('view-timeline', {
|
||||||
|
'view-timeline-name': 'none, none',
|
||||||
|
'view-timeline-axis': 'block, block',
|
||||||
|
'view-timeline-inset': 'auto auto, auto',
|
||||||
|
}, 'none, none');
|
||||||
|
|
||||||
|
// Longhands with different lengths:
|
||||||
|
|
||||||
|
test_shorthand_contraction('view-timeline', {
|
||||||
|
'view-timeline-name': '--a, --b, --c',
|
||||||
|
'view-timeline-axis': 'inline, inline',
|
||||||
|
'view-timeline-inset': 'auto, auto',
|
||||||
|
}, '--a inline, --b inline, --c inline');
|
||||||
|
|
||||||
|
test_shorthand_contraction('view-timeline', {
|
||||||
|
'view-timeline-name': '--a, --b',
|
||||||
|
'view-timeline-axis': 'inline, inline, inline',
|
||||||
|
'view-timeline-inset': 'auto, auto, auto',
|
||||||
|
}, '--a inline, --b inline');
|
||||||
|
|
||||||
|
test_shorthand_contraction('view-timeline', {
|
||||||
|
'view-timeline-name': '--a, --b',
|
||||||
|
'view-timeline-axis': 'inline, inline',
|
||||||
|
'view-timeline-inset': 'auto, auto, auto',
|
||||||
|
}, '--a inline, --b inline');
|
||||||
|
</script>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue