Changeset 239365 in webkit


Ignore:
Timestamp:
Dec 18, 2018 7:21:15 PM (5 years ago)
Author:
Justin Michaud
Message:

Update CSS Properties and Values API to use new cycle fallback behaviour
https://bugs.webkit.org/show_bug.cgi?id=192800

Reviewed by Antti Koivisto.

LayoutTests/imported/w3c:

Re-import tests and adjust expected results. Some of the tests go from pass to fail because
this patch adds some extra dependency checking to property registrations to fix a crash, but
now unsupported syntaxes like <length-percentage> do not register properly.

  • web-platform-tests/css/css-properties-values-api/register-property-expected.txt:
  • web-platform-tests/css/css-properties-values-api/register-property-syntax-parsing-expected.txt:
  • web-platform-tests/css/css-properties-values-api/register-property-syntax-parsing.html:
  • web-platform-tests/css/css-properties-values-api/register-property.html:
  • web-platform-tests/css/css-properties-values-api/registered-properties-inheritance-expected.txt:
  • web-platform-tests/css/css-properties-values-api/registered-properties-inheritance.html:
  • web-platform-tests/css/css-properties-values-api/registered-property-computation-expected.txt:
  • web-platform-tests/css/css-properties-values-api/registered-property-computation.html:
  • web-platform-tests/css/css-properties-values-api/registered-property-cssom-expected.txt:
  • web-platform-tests/css/css-properties-values-api/registered-property-cssom.html:
  • web-platform-tests/css/css-properties-values-api/registered-property-initial-expected.txt:
  • web-platform-tests/css/css-properties-values-api/registered-property-initial.html:
  • web-platform-tests/css/css-properties-values-api/resources/utils.js: Added.

(generate_name):
(any_initial_value):
(generate_property):
(all_syntaxes):

  • web-platform-tests/css/css-properties-values-api/resources/w3c-import.log: Added.
  • web-platform-tests/css/css-properties-values-api/self-utils-expected.txt: Added.
  • web-platform-tests/css/css-properties-values-api/self-utils.html: Added.
  • web-platform-tests/css/css-properties-values-api/typedom.tentative-expected.txt:
  • web-platform-tests/css/css-properties-values-api/typedom.tentative.html:
  • web-platform-tests/css/css-properties-values-api/unit-cycles-expected.txt:
  • web-platform-tests/css/css-properties-values-api/unit-cycles.html:
  • web-platform-tests/css/css-properties-values-api/var-reference-registered-properties-cycles.html:
  • web-platform-tests/css/css-properties-values-api/var-reference-registered-properties-expected.txt:
  • web-platform-tests/css/css-properties-values-api/var-reference-registered-properties.html:
  • web-platform-tests/css/css-properties-values-api/w3c-import.log:

Source/WebCore:

Make CSS variables that are registered and involved in a cycle be treated as invalid. This also fixes a crash in the
wpt tests where relative units and calc() in a registered property's initial value would break things instead of failing.

  • css/CSSCustomPropertyValue.h:
  • css/CSSVariableReferenceValue.cpp:

(WebCore::resolveVariableReference):

  • css/DOMCSSRegisterCustomProperty.cpp:

(WebCore::DOMCSSRegisterCustomProperty::registerProperty):

  • css/StyleResolver.cpp:

(WebCore::StyleResolver::applyCascadedCustomProperty):

  • css/parser/CSSPropertyParser.cpp:

(WebCore::CSSPropertyParser::parseTypedCustomPropertyValue):

LayoutTests:

  • css-custom-properties-api/crash.html:
  • css-custom-properties-api/inherits-expected.txt:
  • css-custom-properties-api/inherits.html:
  • css-custom-properties-api/registerProperty-expected.txt:
  • css-custom-properties-api/registerProperty.html:
Location:
trunk
Files:
5 added
33 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r239357 r239365  
     12018-12-18  Justin Michaud  <justin_michaud@apple.com>
     2
     3        Update CSS Properties and Values API to use new cycle fallback behaviour
     4        https://bugs.webkit.org/show_bug.cgi?id=192800
     5
     6        Reviewed by Antti Koivisto.
     7
     8        * css-custom-properties-api/crash.html:
     9        * css-custom-properties-api/inherits-expected.txt:
     10        * css-custom-properties-api/inherits.html:
     11        * css-custom-properties-api/registerProperty-expected.txt:
     12        * css-custom-properties-api/registerProperty.html:
     13
    1142018-12-18  Myles C. Maxfield  <mmaxfield@apple.com>
    215
  • trunk/LayoutTests/css-custom-properties-api/crash.html

    r237697 r239365  
    4949  inlineStyle.setProperty('--baz', '   40px');
    5050  assert_equals(computedStyle.getPropertyValue('--baz'), '40px');
    51   assert_equals(computedStyle.getPropertyValue('--foo'), '200px');
    52   assert_equals(computedStyle.getPropertyValue('--bar'), '200px');
     51  assert_equals(computedStyle.getPropertyValue('--foo'), '');
     52  assert_equals(computedStyle.getPropertyValue('--bar'), '');
    5353  assert_equals(computedStyle.getPropertyValue('--baz'), '40px');
    54   assert_equals(computedStyle.getPropertyValue('font-size'), '200px');
     54  assert_equals(computedStyle.getPropertyValue('font-size'), '30px');
    5555  inlineStyle.removeProperty('--baz');
    5656  assert_equals(computedStyle.getPropertyValue('--baz'), '200px');
    57   assert_equals(computedStyle.getPropertyValue('--foo'), '200px');
    58   assert_equals(computedStyle.getPropertyValue('--bar'), '200px');
    59   assert_equals(computedStyle.getPropertyValue('font-size'), '200px');
     57  assert_equals(computedStyle.getPropertyValue('--foo'), '');
     58  assert_equals(computedStyle.getPropertyValue('--bar'), '');
     59  assert_equals(computedStyle.getPropertyValue('font-size'), '30px');
    6060  assert_equals(computedStyle.getPropertyValue('--baz'), '200px');
    6161}, "Setting the inline style is handled correctly when registered");
  • trunk/LayoutTests/css-custom-properties-api/inherits-expected.txt

    r236828 r239365  
    11Specified in parent, inherits=true
    22
    3 100px green
     3test
    44
    55Specified in parent, inherits=false
    66
    7 200px green
     7test
    88
    99Specified in parent, not registered
    1010
    11 100px green
     11test
    1212
    1313Initial
    1414
    15 200px green
     15test
    1616
    1717Unset, inherits=true
    1818
    19 100px green
     19test
    2020
    2121Unset, inherits=false
    2222
    23 200px green
     23test
    2424
    2525A cycle between an inherits=true and inherits=false property
    2626
    27 200px green
     27test
    2828
    2929A cycle between an inherits=true and inherits=false property
    3030
    31 200px green
     31test
    3232
    3333A cycle between an inherits=true and inherits=false property with fallback
    3434
    35 200px green
     35test
    3636
    3737Inheritance should not create a cycle
    3838
    39 110px green
     39test
    4040
    4141A cycle between two unregistered properties
    4242
    43 300px green
     43test
    4444
    4545Revert, inherits=true
    4646
    47 190px purple
     47test
    4848
    4949Revert, inherits=false
    5050
    51 200px purple
     51test
    5252
    5353Revert, unregistered
    5454
    55 purple
     55test
    5656
    5757Inherit, unregistered
    5858
    59 purple
     59test
    6060
    6161Test that inherited properties do variable substitution before being inherited - registered
     
    6969No initial value in registered property should act like unregistered
    7070
    71 200px green
     71test
    7272
    7373(unregistered)
    7474
    75 500px green
     75test
    7676
    7777Inherit should be substituted for unregistered property
    7878
    79 500px green
     79test
    8080
    8181
  • trunk/LayoutTests/css-custom-properties-api/inherits.html

    r236828 r239365  
    245245<div>
    246246  <p> Specified in parent, inherits=true</p>
    247   <div id="parent1"><div id="child1"><p>100px green</p></div> </div>
     247  <div id="parent1"><div id="child1"><p>test</p></div> </div>
    248248  <p> Specified in parent, inherits=false </p>
    249   <div id="parent2"><div id="child2"><p>200px green</p></div> </div>
     249  <div id="parent2"><div id="child2"><p>test</p></div> </div>
    250250  <p> Specified in parent, not registered </p>
    251   <div id="parent3"><div id="child3"><p>100px green</p></div> </div>
     251  <div id="parent3"><div id="child3"><p>test</p></div> </div>
    252252  <p> Initial </p>
    253   <div id="parent4"><div id="child4"><p>200px green</p></div> </div>
     253  <div id="parent4"><div id="child4"><p>test</p></div> </div>
    254254  <p> Unset, inherits=true </p>
    255   <div id="parent5"><div id="child5"><p>100px green</p></div> </div>
     255  <div id="parent5"><div id="child5"><p>test</p></div> </div>
    256256  <p> Unset, inherits=false </p>
    257   <div id="parent6"><div id="child6"><p>200px green</p></div> </div>
     257  <div id="parent6"><div id="child6"><p>test</p></div> </div>
    258258  <p> A cycle between an inherits=true and inherits=false property </p>
    259   <div id="parent7"><div id="child7"><p>200px green</p></div> </div>
     259  <div id="parent7"><div id="child7"><p>test</p></div> </div>
    260260  <p> A cycle between an inherits=true and inherits=false property </p>
    261   <div id="parent8"><div id="child8"><p>200px green</p></div> </div>
     261  <div id="parent8"><div id="child8"><p>test</p></div> </div>
    262262  <p> A cycle between an inherits=true and inherits=false property with fallback </p>
    263   <div id="parent9"><div id="child9"><p>200px green</p></div> </div>
     263  <div id="parent9"><div id="child9"><p>test</p></div> </div>
    264264  <p> Inheritance should not create a cycle </p>
    265   <div id="parent10"><div id="child10"><p>110px green</p></div></div>
     265  <div id="parent10"><div id="child10"><p>test</p></div></div>
    266266  <p> A cycle between two unregistered properties </p>
    267   <div id="parent11"><div id="child11"><p>300px green</p></div> </div>
     267  <div id="parent11"><div id="child11"><p>test</p></div> </div>
    268268
    269269  <p> Revert, inherits=true </p>
    270   <div id="parent12"><div id="child12"><div id="childchild12"><p>190px purple</p></div></div></div>
     270  <div id="parent12"><div id="child12"><div id="childchild12"><p>test</p></div></div></div>
    271271  <p> Revert, inherits=false </p>
    272   <div id="parent13"><div id="child13"><div id="childchild13"><p>200px purple</p></div></div> </div>
     272  <div id="parent13"><div id="child13"><div id="childchild13"><p>test</p></div></div> </div>
    273273  <p> Revert, unregistered </p>
    274   <div id="parent14"><div id="child14"><div id="childchild14"><p>purple</p></div></div> </div>
     274  <div id="parent14"><div id="child14"><div id="childchild14"><p>test</p></div></div> </div>
    275275  <p> Inherit, unregistered </p>
    276   <div id="parent14-1"><div id="child14-1"><div id="childchild14-1"><p>purple</p></div></div> </div>
     276  <div id="parent14-1"><div id="child14-1"><div id="childchild14-1"><p>test</p></div></div> </div>
    277277
    278278  <p> Test that inherited properties do variable substitution before being inherited - registered</p>
     
    282282
    283283  <p> No initial value in registered property should act like unregistered</p>
    284   <div id="parent17"><div id="child17"><p>200px green</p></div> </div>
     284  <div id="parent17"><div id="child17"><p>test</p></div> </div>
    285285  <p> (unregistered) </p>
    286   <div id="parent18"><div id="child18"><p>500px green</p></div> </div>
     286  <div id="parent18"><div id="child18"><p>test</p></div> </div>
    287287
    288288  <p>Inherit should be substituted for unregistered property</p>
    289   <div id="parent19"><div id="child19"><p>500px green</p></div> </div>
     289  <div id="parent19"><div id="child19"><p>test</p></div> </div>
    290290</div>
    291291<script>
     
    347347}, "JS Attributes are valid for element 6");
    348348test(function() {
    349   test_prop('child7', 'width', '200px');
    350   test_prop('child7', '--my-custom-prop', '100px');
    351   test_prop('child7', '--my-custom-prop2', '200px');
     349  test_prop('child7', 'width', '300px');
     350  test_prop('child7', '--my-custom-prop', '');
     351  test_prop('child7', '--my-custom-prop2', '');
    352352}, "JS Attributes are valid for element 7");
    353353test(function() {
    354   test_prop('child8', 'width', '200px');
    355   test_prop('child8', '--my-custom-prop', '200px');
    356   test_prop('child8', '--my-custom-prop2', '200px');
     354  test_prop('child8', 'width', '300px');
     355  test_prop('child8', '--my-custom-prop', '');
     356  test_prop('child8', '--my-custom-prop2', '');
    357357}, "JS Attributes are valid for element 8");
    358358test(function() {
    359   test_prop('child9', 'width', '200px');
    360   test_prop('child9', '--my-custom-prop', '100px');
    361   test_prop('child9', '--my-custom-prop2', '200px');
     359  test_prop('child9', 'width', '300px');
     360  test_prop('child9', '--my-custom-prop', '');
     361  test_prop('child9', '--my-custom-prop2', '');
    362362}, "JS Attributes are valid for element 9");
    363363test(function() {
  • trunk/LayoutTests/css-custom-properties-api/registerProperty-expected.txt

    r236379 r239365  
    44PASS registerProperty always allows omitting initialValue and syntax, requires name and inherits
    55PASS registerProperty requires inherits and name
     6PASS registerProperty requires initialValue to be computationally independent
    67
  • trunk/LayoutTests/css-custom-properties-api/registerProperty.html

    r236379 r239365  
    33<script src="../resources/testharness.js"></script>
    44<script src="../resources/testharnessreport.js"></script>
     5<div id="el"></div>
    56<script>
    67// Tests for error checking during property registration
     
    1920    CSS.registerProperty({name: ['--name', 3], inherits: false});
    2021    // Invalid property names
    21     //assert_throws(new SyntaxError(), () => CSS.registerProperty({name: 'no-leading-dash', inherits: false}));
    22     //assert_throws(new SyntaxError(), () => CSS.registerProperty({name: '', inherits: false}));
    23     //assert_throws(new SyntaxError(), () => CSS.registerProperty({name: '\\--name', inherits: false}));
     22    assert_throws(new SyntaxError(), () => CSS.registerProperty({name: 'no-leading-dash', inherits: false}));
     23    assert_throws(new SyntaxError(), () => CSS.registerProperty({name: '', inherits: false}));
     24    assert_throws(new SyntaxError(), () => CSS.registerProperty({name: '\\--name', inherits: false}));
    2425}, "registerProperty requires a name matching <custom-property-name>");
    2526test(function() {
     
    3839    CSS.registerProperty({name: '--syntax-test-5', inherits: false, syntax: ' * '});
    3940}, "registerProperty requires inherits and name");
     41test(function() {
     42  CSS.registerProperty({name: '--initialvalue-test-0', inherits: false, syntax: '<length>', initialValue: 'calc(10px + 10in)'});
     43  assert_equals(window.getComputedStyle(el).getPropertyValue('--initialvalue-test-0').toString(), '970px');
     44
     45  assert_throws(new SyntaxError(),
     46    () => CSS.registerProperty({name: '--initialvalue-test-1', inherits: false, syntax: '<length>', initialValue: '10em'}));
     47  assert_throws(new SyntaxError(),
     48    () => CSS.registerProperty({name: '--initialvalue-test-2', inherits: false, syntax: '<length>', initialValue: 'calc(10px + 10em)'}));
     49  assert_throws(new SyntaxError(),
     50    () => CSS.registerProperty({name: '--initialvalue-test-3', inherits: false, syntax: '<length>', initialValue: 'calc(10px + 10%)'}));
     51}, "registerProperty requires initialValue to be computationally independent");
    4052</script>
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r239341 r239365  
     12018-12-18  Justin Michaud  <justin_michaud@apple.com>
     2
     3        Update CSS Properties and Values API to use new cycle fallback behaviour
     4        https://bugs.webkit.org/show_bug.cgi?id=192800
     5
     6        Reviewed by Antti Koivisto.
     7
     8        Re-import tests and adjust expected results. Some of the tests go from pass to fail because
     9        this patch adds some extra dependency checking to property registrations to fix a crash, but
     10        now unsupported syntaxes like <length-percentage> do not register properly.
     11
     12        * web-platform-tests/css/css-properties-values-api/register-property-expected.txt:
     13        * web-platform-tests/css/css-properties-values-api/register-property-syntax-parsing-expected.txt:
     14        * web-platform-tests/css/css-properties-values-api/register-property-syntax-parsing.html:
     15        * web-platform-tests/css/css-properties-values-api/register-property.html:
     16        * web-platform-tests/css/css-properties-values-api/registered-properties-inheritance-expected.txt:
     17        * web-platform-tests/css/css-properties-values-api/registered-properties-inheritance.html:
     18        * web-platform-tests/css/css-properties-values-api/registered-property-computation-expected.txt:
     19        * web-platform-tests/css/css-properties-values-api/registered-property-computation.html:
     20        * web-platform-tests/css/css-properties-values-api/registered-property-cssom-expected.txt:
     21        * web-platform-tests/css/css-properties-values-api/registered-property-cssom.html:
     22        * web-platform-tests/css/css-properties-values-api/registered-property-initial-expected.txt:
     23        * web-platform-tests/css/css-properties-values-api/registered-property-initial.html:
     24        * web-platform-tests/css/css-properties-values-api/resources/utils.js: Added.
     25        (generate_name):
     26        (any_initial_value):
     27        (generate_property):
     28        (all_syntaxes):
     29        * web-platform-tests/css/css-properties-values-api/resources/w3c-import.log: Added.
     30        * web-platform-tests/css/css-properties-values-api/self-utils-expected.txt: Added.
     31        * web-platform-tests/css/css-properties-values-api/self-utils.html: Added.
     32        * web-platform-tests/css/css-properties-values-api/typedom.tentative-expected.txt:
     33        * web-platform-tests/css/css-properties-values-api/typedom.tentative.html:
     34        * web-platform-tests/css/css-properties-values-api/unit-cycles-expected.txt:
     35        * web-platform-tests/css/css-properties-values-api/unit-cycles.html:
     36        * web-platform-tests/css/css-properties-values-api/var-reference-registered-properties-cycles.html:
     37        * web-platform-tests/css/css-properties-values-api/var-reference-registered-properties-expected.txt:
     38        * web-platform-tests/css/css-properties-values-api/var-reference-registered-properties.html:
     39        * web-platform-tests/css/css-properties-values-api/w3c-import.log:
     40
    1412018-12-18  Justin Michaud  <justin_michaud@apple.com>
    242
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/register-property-expected.txt

    r236444 r239365  
    11
    22PASS registerProperty requires a Dictionary type
    3 FAIL registerProperty requires a name matching <custom-property-name> assert_throws: function "() => CSS.registerProperty({name: 'no-leading-dash', inherits: false})" did not throw
     3PASS registerProperty requires a name matching <custom-property-name>
    44FAIL registerProperty only allows omitting initialValue if syntax is '*' assert_throws: function "() => CSS.registerProperty({name: '--syntax-test-3', syntax: 'length', inherits: false})" did not throw
    5 PASS registerProperty fails for an already registered property
     5FAIL registerProperty fails for an already registered property assert_throws: function "() => CSS.registerProperty({name: '--re-register', syntax: '<percentage>', initialValue: '0%', inherits: false})" threw object "SyntaxError: The given initial value does not parse for the given syntax." ("SyntaxError") expected object "[object Object]" ("InvalidModificationError")
    66PASS registerProperty requires inherits
     7FAIL Registering a property should not cause a transition The given initial value does not parse for the given syntax.
    78
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/register-property-syntax-parsing-expected.txt

    r237697 r239365  
    44PASS syntax:'<length>', initialValue:'2px' is valid
    55FAIL syntax:' <number>', initialValue:'5' is valid The given initial value does not parse for the given syntax.
    6 PASS syntax:'<percentage> ', initialValue:'10%' is valid
     6FAIL syntax:'<percentage> ', initialValue:'10%' is valid The given initial value does not parse for the given syntax.
    77FAIL syntax:'<color>+', initialValue:'red' is valid The given initial value does not parse for the given syntax.
    88FAIL syntax:' <length>+ | <percentage>', initialValue:'2px 8px' is valid The given initial value does not parse for the given syntax.
     
    2222PASS syntax:'<length>', initialValue:'calc(7in - 12px)' is valid
    2323FAIL syntax:'<length>+', initialValue:'2px 7px calc(8px)' is valid The given initial value does not parse for the given syntax.
     24FAIL syntax:'<length>#', initialValue:'2px, 7px, calc(8px)' is valid The given initial value does not parse for the given syntax.
    2425FAIL syntax:'<percentage>', initialValue:'-9.3e3%' is valid The given initial value does not parse for the given syntax.
    2526FAIL syntax:'<length-percentage>', initialValue:'-54%' is valid The given initial value does not parse for the given syntax.
    2627PASS syntax:'<length-percentage>', initialValue:'0' is valid
    27 PASS syntax:'<length-percentage>', initialValue:'calc(-11px + 10.4%)' is valid
     28FAIL syntax:'<length-percentage>', initialValue:'calc(-11px + 10.4%)' is valid The given initial value does not parse for the given syntax.
    2829FAIL syntax:'<number>', initialValue:'-109' is valid The given initial value does not parse for the given syntax.
    2930FAIL syntax:'<number>', initialValue:'2.3e4' is valid The given initial value does not parse for the given syntax.
    3031FAIL syntax:'<integer>', initialValue:'-109' is valid The given initial value does not parse for the given syntax.
    3132FAIL syntax:'<integer>', initialValue:'19' is valid The given initial value does not parse for the given syntax.
     33FAIL syntax:'<integer>', initialValue:'calc(1)' is valid The given initial value does not parse for the given syntax.
     34FAIL syntax:'<integer>', initialValue:'calc(1 + 2)' is valid The given initial value does not parse for the given syntax.
     35FAIL syntax:'<integer>', initialValue:'calc(3.1415)' is valid The given initial value does not parse for the given syntax.
     36FAIL syntax:'<integer>', initialValue:'calc(3.1415 + 3.1415)' is valid The given initial value does not parse for the given syntax.
    3237FAIL syntax:'<angle>', initialValue:'10deg' is valid The given initial value does not parse for the given syntax.
    3338FAIL syntax:'<angle>', initialValue:'20.5rad' is valid The given initial value does not parse for the given syntax.
     
    8691FAIL syntax:'<length>|initial', initialValue:'10px' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
    8792FAIL syntax:'<length>|INHERIT', initialValue:'10px' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
    88 FAIL syntax:'<percentage>|unsEt', initialValue:'2%' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
     93PASS syntax:'<percentage>|unsEt', initialValue:'2%' is invalid
    8994FAIL syntax:'*', initialValue:'initial' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
    9095FAIL syntax:'*', initialValue:'inherit' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
     
    105110PASS syntax:'<length>', initialValue:'var(--moo)' is invalid
    106111PASS syntax:'<length>', initialValue:'10' is invalid
    107 FAIL syntax:'<length>', initialValue:'10%' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
    108 FAIL syntax:'<length>', initialValue:'calc(5px + 10%)' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
     112PASS syntax:'<length>', initialValue:'10%' is invalid
     113PASS syntax:'<length>', initialValue:'calc(5px + 10%)' is invalid
    109114PASS syntax:'<length>', initialValue:'calc(5px * 3px / 6px)' is invalid
    110 FAIL syntax:'<length>', initialValue:'10em' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
     115PASS syntax:'<length>', initialValue:'10em' is invalid
    111116FAIL syntax:'<length>', initialValue:'10vmin' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
    112 FAIL syntax:'<length>', initialValue:'calc(4px + 3em)' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
    113 FAIL syntax:'<length>', initialValue:'calc(4px + calc(8 * 2em))' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
    114 FAIL syntax:'<length>+', initialValue:'calc(2ex + 16px)' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
     117PASS syntax:'<length>', initialValue:'calc(4px + 3em)' is invalid
     118PASS syntax:'<length>', initialValue:'calc(4px + calc(8 * 2em))' is invalid
     119PASS syntax:'<length>+', initialValue:'calc(2ex + 16px)' is invalid
    115120PASS syntax:'<length>+', initialValue:'10px calc(20px + 4rem)' is invalid
     121FAIL syntax:'<length>+', initialValue:'' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
     122FAIL syntax:'<length>#', initialValue:'' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
    116123PASS syntax:'<percentage> | <length>+', initialValue:'calc(100vh - 10px) 30px' is invalid
    117124PASS syntax:'<length>', initialValue:'10px;' is invalid
    118 FAIL syntax:'<length-percentage>', initialValue:'calc(2px + 10% + 7ex)' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
     125PASS syntax:'<length-percentage>', initialValue:'calc(2px + 10% + 7ex)' is invalid
    119126FAIL syntax:'<percentage>', initialValue:'0' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
    120127PASS syntax:'<integer>', initialValue:'1.0' is invalid
     
    122129PASS syntax:'<number>|foo', initialValue:'foo var(--foo, bla)' is invalid
    123130FAIL syntax:'<angle>', initialValue:'0' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
    124 FAIL syntax:'<angle>', initialValue:'10%' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
     131PASS syntax:'<angle>', initialValue:'10%' is invalid
    125132FAIL syntax:'<time>', initialValue:'2px' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw
    126133PASS syntax:'<resolution>', initialValue:'10' is invalid
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/register-property-syntax-parsing.html

    r236444 r239365  
    4747assert_valid("<length>", "calc(7in - 12px)");
    4848assert_valid("<length>+", "2px 7px calc(8px)");
     49assert_valid("<length>#", "2px, 7px, calc(8px)");
    4950assert_valid("<percentage>", "-9.3e3%");
    5051assert_valid("<length-percentage>", "-54%");
     
    5657assert_valid("<integer>", "-109");
    5758assert_valid("<integer>", "19");
     59assert_valid("<integer>", "calc(1)");
     60assert_valid("<integer>", "calc(1 + 2)");
     61assert_valid("<integer>", "calc(3.1415)");
     62assert_valid("<integer>", "calc(3.1415 + 3.1415)");
    5863
    5964assert_valid("<angle>", "10deg");
     
    148153assert_invalid("<length>+", "calc(2ex + 16px)");
    149154assert_invalid("<length>+", "10px calc(20px + 4rem)");
     155assert_invalid("<length>+", "");
     156assert_invalid("<length>#", "");
    150157assert_invalid("<percentage> | <length>+", "calc(100vh - 10px) 30px");
    151158assert_invalid("<length>", "10px;");
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/register-property.html

    r236444 r239365  
    33<script src="/resources/testharness.js"></script>
    44<script src="/resources/testharnessreport.js"></script>
     5<script src="./resources/utils.js"></script>
     6<div id=target></div>
    57<script>
    68// Tests for error checking during property registration
     
    4648    assert_throws(new TypeError(), () => CSS.registerProperty({name: '--inherit-test-3', syntax: '<length>', initialValue: '0px'}));
    4749}, "registerProperty requires inherits");
     50
     51test(function(){
     52    try {
     53        let name = generate_name();
     54
     55        target.style.setProperty(name, 'green');
     56        target.style.transitionProperty = name;
     57        target.style.transitionDuration = '1s';
     58        target.style.transitionTimingFunction = 'steps(1, end)';
     59
     60        assert_equals(getComputedStyle(target).getPropertyValue(name), 'green');
     61
     62        CSS.registerProperty({
     63            name: name,
     64            syntax: '<color>',
     65            initialValue: 'red',
     66            inherits: false
     67        });
     68
     69        assert_equals(getComputedStyle(target).getPropertyValue(name), 'rgb(0, 128, 0)');
     70    } finally {
     71        target.style = '';
     72    }
     73}, 'Registering a property should not cause a transition');
     74
    4875</script>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-properties-inheritance-expected.txt

    r237697 r239365  
    55PASS Reference to undefined variable results in inherited value
    66PASS Reference to syntax-incompatible variable results in inherited value
     7PASS Font-relative units are absolutized before before inheritance
     8PASS Calc expressions are resolved before inheritance
    79
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-properties-inheritance.html

    r236444 r239365  
    7373}, "Reference to syntax-incompatible variable results in inherited value");
    7474
     75test(function(){
     76    CSS.registerProperty({name: '--inherited-em', syntax: '<length>', initialValue: '0px', inherits: true});
     77    outer.style = 'font-size: 11px; --inherited-em: 10em;';
     78    inner.style = 'font-size: 22px; --unregistered:var(--inherited-em);';
     79    assert_equals(getComputedStyle(inner).getPropertyValue('--unregistered'), '110px');
     80}, "Font-relative units are absolutized before before inheritance");
     81
     82test(function(){
     83    CSS.registerProperty({name: '--calc-length', syntax: '<length>', initialValue: '0px', inherits: true});
     84    outer.style = '--calc-length: calc(10px + 10px);';
     85    inner.style = '--unregistered:var(--calc-length);';
     86    assert_equals(getComputedStyle(inner).getPropertyValue('--unregistered'), '20px');
     87}, "Calc expressions are resolved before inheritance");
     88
    7589</script>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-computation-expected.txt

    r236895 r239365  
    11
    2 FAIL CSS.registerProperty The given initial value does not parse for the given syntax.
    3 PASS <length> values are computed correctly for divWithFontSizeSet
    4 FAIL <length-percentage> values are computed correctly for divWithFontSizeSet assert_equals: expected "calc(190px + -2%)" but got "calc(190px - 2%)"
    5 FAIL <length># values are computed correctly for divWithFontSizeSet assert_equals: expected "10px, 30px" but got "0px"
    6 FAIL <length-percentage># values are computed correctly for divWithFontSizeSet assert_equals: expected "3%, 80px, 22px" but got "0px"
    7 FAIL <length>+ values are computed correctly for divWithFontSizeSet assert_equals: expected "10px 30px" but got "0px"
    8 FAIL <length-percentage>+ values are computed correctly for divWithFontSizeSet assert_equals: expected "3% 80px 22px" but got "0px"
    9 FAIL <transform-function> values are computed correctly for divWithFontSizeSet assert_equals: expected "translateX(2px)" but got " translateX(2px)"
    10 PASS <length> values are computed correctly for divWithFontSizeInherited
    11 FAIL <length-percentage> values are computed correctly for divWithFontSizeInherited assert_equals: expected "calc(190px + -2%)" but got "calc(190px - 2%)"
    12 FAIL <length># values are computed correctly for divWithFontSizeInherited assert_equals: expected "10px, 30px" but got "0px"
    13 FAIL <length-percentage># values are computed correctly for divWithFontSizeInherited assert_equals: expected "3%, 80px, 22px" but got "0px"
    14 FAIL <length>+ values are computed correctly for divWithFontSizeInherited assert_equals: expected "10px 30px" but got "0px"
    15 FAIL <length-percentage>+ values are computed correctly for divWithFontSizeInherited assert_equals: expected "3% 80px 22px" but got "0px"
    16 FAIL <transform-function> values are computed correctly for divWithFontSizeInherited assert_equals: expected "translateX(2px)" but got " translateX(2px)"
     2PASS <length> values computed are correctly via var()-reference
     3PASS <length> values computed are correctly via var()-reference when font-size is inherited
     4PASS <length> values are computed correctly when font-size is inherited [14em]
     5PASS <length> values are computed correctly when font-size is inherited [calc(14em + 10px)]
     6PASS <length> values are computed correctly [12px]
     7PASS <length> values are computed correctly [13vw]
     8PASS <length> values are computed correctly [14em]
     9PASS <length> values are computed correctly [15vmin]
     10PASS <length> values are computed correctly [calc(16px - 7em + 10vh)]
     11PASS <length-percentage> values are computed correctly [17em]
     12FAIL <length-percentage> values are computed correctly [18%] assert_equals: expected "18%" but got "0px"
     13FAIL <length-percentage> values are computed correctly [calc(19em - 2%)] assert_equals: expected "calc(-2% + 190px)" but got "0px"
     14FAIL <length># values are computed correctly [10px, 3em] assert_equals: expected "10px, 30px" but got "0px"
     15FAIL <length># values are computed correctly [4em ,9px] assert_equals: expected "40px, 9px" but got "0px"
     16PASS <length># values are computed correctly [8em]
     17FAIL <length-percentage># values are computed correctly [3% , 10vmax  , 22px] assert_equals: expected "3%, 80px, 22px" but got "0px"
     18FAIL <length-percentage># values are computed correctly [calc(50% + 1em), 4px] assert_equals: expected "calc(50% + 10px), 4px" but got "0px"
     19FAIL <length-percentage># values are computed correctly [calc(13% + 37px)] assert_equals: expected "calc(13% + 37px)" but got "0px"
     20FAIL <length>+ values are computed correctly [10px 3em] assert_equals: expected "10px 30px" but got "0px"
     21FAIL <length>+ values are computed correctly [4em 9px] assert_equals: expected "40px 9px" but got "0px"
     22FAIL <length-percentage>+ values are computed correctly [3% 10vmax 22px] assert_equals: expected "3% 80px 22px" but got "0px"
     23FAIL <length-percentage>+ values are computed correctly [calc(50% + 1em) 4px] assert_equals: expected "calc(50% + 10px) 4px" but got "0px"
     24FAIL <transform-function> values are computed correctly [translateX(2px)] The given initial value does not parse for the given syntax.
     25FAIL <transform-function> values are computed correctly [translateX(10em)] The given initial value does not parse for the given syntax.
     26FAIL <transform-function> values are computed correctly [translateX(calc(11em + 10%))] The given initial value does not parse for the given syntax.
     27FAIL <transform-function>+ values are computed correctly [translateX(10%) scale(2)] The given initial value does not parse for the given syntax.
     28FAIL <integer> values are computed correctly [15] assert_equals: expected "15" but got "0px"
     29FAIL <integer> values are computed correctly [calc(15 + 15)] assert_equals: expected "30" but got "0px"
     30FAIL <integer> values are computed correctly [calc(2.4)] assert_equals: expected "2" but got "0px"
     31FAIL <integer> values are computed correctly [calc(2.6)] assert_equals: expected "3" but got "0px"
     32FAIL <integer> values are computed correctly [calc(2.6 + 3.1)] assert_equals: expected "6" but got "0px"
     33FAIL <integer>+ values are computed correctly [15 calc(2.4) calc(2.6)] assert_equals: expected "15 2 3" but got "0px"
     34FAIL <color> values are computed correctly [#ff0000] The given initial value does not parse for the given syntax.
     35FAIL <color> values are computed correctly [#000f00] The given initial value does not parse for the given syntax.
     36FAIL <color> values are computed correctly [#00000a] The given initial value does not parse for the given syntax.
     37FAIL <color> values are computed correctly [#badbee] The given initial value does not parse for the given syntax.
     38FAIL <color> values are computed correctly [#badbee33] The given initial value does not parse for the given syntax.
     39FAIL <color> values are computed correctly [tomato] The given initial value does not parse for the given syntax.
     40FAIL <color> values are computed correctly [plum] The given initial value does not parse for the given syntax.
     41FAIL <color> values are computed correctly [currentcolor] The given initial value does not parse for the given syntax.
     42PASS * values are computed correctly [tomato]
     43FAIL tomato | plum values are computed correctly [plum] The given initial value does not parse for the given syntax.
     44FAIL tomato | plum | <color> values are computed correctly [plum] The given initial value does not parse for the given syntax.
     45PASS * values are computed correctly [-50grad]
     46FAIL <angle> values are computed correctly [180deg] The given initial value does not parse for the given syntax.
     47FAIL <angle> values are computed correctly [400grad] The given initial value does not parse for the given syntax.
     48FAIL <angle> values are computed correctly [calc(360deg + 400grad)] The given initial value does not parse for the given syntax.
     49PASS * values are computed correctly [50s]
     50FAIL <time> values are computed correctly [1s] The given initial value does not parse for the given syntax.
     51FAIL <time> values are computed correctly [1000ms] The given initial value does not parse for the given syntax.
     52FAIL <time> values are computed correctly [calc(1000ms + 1s)] The given initial value does not parse for the given syntax.
     53PASS * values are computed correctly [50dpi]
     54FAIL <resolution> values are computed correctly [1dppx] The given initial value does not parse for the given syntax.
     55FAIL <resolution> values are computed correctly [96dpi] The given initial value does not parse for the given syntax.
     56FAIL <resolution> values are computed correctly [calc(1dppx + 96dpi)] The given initial value does not parse for the given syntax.
    1757
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-computation.html

    r236444 r239365  
    1 <!DOCTYPE HTML>
     1<!DOCTYPE html>
    22<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#calculation-of-computed-values" />
    33<script src="/resources/testharness.js"></script>
    44<script src="/resources/testharnessreport.js"></script>
     5<script src="./resources/utils.js"></script>
    56
    67<style>
    78#divWithFontSizeSet, #parentDiv {
    89    font-size: 10px;
    9 }
    10 #divWithFontSizeSet, #divWithFontSizeInherited {
    11     --length-1: 12px;
    12     --length-2: 13vw;
    13     --length-3: 14em;
    14     --length-4: 15vmin;
    15     --length-5: calc(16px - 7em + 10vh);
    16     --length-6: var(--length-3);
    17     --length-percentage-1: 17em;
    18     --length-percentage-2: 18%;
    19     --length-percentage-3: calc(19em - 2%);
    20     --csv-1: 10px, 3em;
    21     --csv-2: 4em ,9px;
    22     --csv-3: 8em;
    23     --csv-4: 3% , 10vmax  , 22px;
    24     --csv-5: calc(50% + 1em), 4px;
    25     --csv-6: calc(13% + 37px);
    26     --list-1: 10px 3em;
    27     --list-2: 4em 9px;
    28     --list-3: 3% 10vmax 22px;
    29     --list-4: calc(50% + 1em) 4px;
    30     --transform-function-1: translateX(2px);
    31     --transform-function-2: translateX(10em);
    32     --transform-function-3: translateX(calc(11em + 10%));
    33     --transform-function-4: translateX(10%) scale(2);
    3410}
    3511</style>
     
    3915    <div id=divWithFontSizeInherited></div>
    4016</div>
     17<div id="ref"></div>
    4118
    4219<script>
    43 test(() => {
    44     CSS.registerProperty({name: '--length-1', syntax: '<length>', initialValue: '0px', inherits: false});
    45     CSS.registerProperty({name: '--length-2', syntax: '<length>', initialValue: '0px', inherits: false});
    46     CSS.registerProperty({name: '--length-3', syntax: '<length>', initialValue: '0px', inherits: false});
    47     CSS.registerProperty({name: '--length-4', syntax: '<length>', initialValue: '0px', inherits: false});
    48     CSS.registerProperty({name: '--length-5', syntax: '<length>', initialValue: '0px', inherits: false});
    49     CSS.registerProperty({name: '--length-6', syntax: '<length>', initialValue: '0px', inherits: false});
    50     CSS.registerProperty({name: '--length-percentage-1', syntax: '<length-percentage>', initialValue: '0px', inherits: false});
    51     CSS.registerProperty({name: '--length-percentage-2', syntax: '<length-percentage>', initialValue: '0px', inherits: false});
    52     CSS.registerProperty({name: '--length-percentage-3', syntax: '<length-percentage>', initialValue: '0px', inherits: false});
    53     CSS.registerProperty({name: '--csv-1', syntax: '<length>#', initialValue: '0px', inherits: false});
    54     CSS.registerProperty({name: '--csv-2', syntax: '<length>#', initialValue: '0px', inherits: false});
    55     CSS.registerProperty({name: '--csv-3', syntax: '<length>#', initialValue: '0px', inherits: false});
    56     CSS.registerProperty({name: '--csv-4', syntax: '<length-percentage>#', initialValue: '0px', inherits: false});
    57     CSS.registerProperty({name: '--csv-5', syntax: '<length-percentage>#', initialValue: '0px', inherits: false});
    58     CSS.registerProperty({name: '--csv-6', syntax: '<length-percentage>#', initialValue: '0px', inherits: false});
    59     CSS.registerProperty({name: '--list-1', syntax: '<length>+', initialValue: '0px', inherits: false});
    60     CSS.registerProperty({name: '--list-2', syntax: '<length>+', initialValue: '0px', inherits: false});
    61     CSS.registerProperty({name: '--list-3', syntax: '<length-percentage>+', initialValue: '0px', inherits: false});
    62     CSS.registerProperty({name: '--list-4', syntax: '<length-percentage>+', initialValue: '0px', inherits: false});
    63     CSS.registerProperty({name: '--transform-function-1', syntax: '<transform-function>', initialValue: 'translateX(0px)', inherits: false});
    64     CSS.registerProperty({name: '--transform-function-2', syntax: '<transform-function>', initialValue: 'translateX(0px)', inherits: false});
    65     CSS.registerProperty({name: '--transform-function-3', syntax: '<transform-function>', initialValue: 'translateX(0px)', inherits: false});
    66     CSS.registerProperty({name: '--transform-function-4', syntax: '<transform-function>+', initialValue: 'translateX(0px)', inherits: false});
    67 }, "CSS.registerProperty");
    6820
    69 for (var element of [divWithFontSizeSet, divWithFontSizeInherited]) {
    70     var id = element.id;
    71     var computedStyle = getComputedStyle(element);
     21// Generate a property and temporarily set its value. Then call 'fn' with
     22// the name of the generated property.
     23function with_custom_property(element, reg, value, fn) {
     24    if (element.id.length == 0)
     25        throw 'The specified element must have an ID';
    7226
     27    let name = generate_property(reg);
     28
     29    // Because we want to include the parsing step, insert a stylesheet
     30    // node with textContent.
     31    let node = document.createElement('style');
     32    node.textContent = `#${element.id} { ${name}:${value}; }`;
     33    document.body.append(node);
     34
     35    try {
     36        fn(name);
     37    } finally {
     38        node.remove();
     39    }
     40}
     41
     42function assert_computed_value(element, syntax, value, expected) {
     43    with_custom_property(element, syntax, value, (name) => {
     44        let actual = getComputedStyle(element).getPropertyValue(name);
     45        assert_equals(actual, expected);
     46    });
     47}
     48
     49// Computes an absolute reference value for some length.
     50//
     51// E.g. to figure out how many pixels '10vh' is, do length_ref('10vh').
     52function length_ref(value, refnode = ref) {
     53    try {
     54        // The reference property 'min-height' is chosen arbitrarily, but
     55        // avoid properties with "resolved value is used value"-behavior
     56        // [1], as it may affect rounding, and custom properties do not
     57        // have this behavior.
     58        //
     59        // [1] https://drafts.csswg.org/cssom/#resolved-values
     60        const ref_property = 'min-height';
     61        refnode.style = `${ref_property}: ${value}`;
     62        return getComputedStyle(refnode).getPropertyValue(ref_property);
     63    } finally {
     64        refnode.style = '';
     65    }
     66}
     67
     68function test_computed_value(syntax, value, expected) {
    7369    test(function() {
    74         assert_equals(computedStyle.getPropertyValue('--length-1'), '12px');
    75         assert_equals(computedStyle.getPropertyValue('--length-2'), '104px');
    76         assert_equals(computedStyle.getPropertyValue('--length-3'), '140px');
    77         assert_equals(computedStyle.getPropertyValue('--length-4'), '90px');
    78         assert_equals(computedStyle.getPropertyValue('--length-5'), '6px');
    79         assert_equals(computedStyle.getPropertyValue('--length-6'), '140px');
    80     }, "<length> values are computed correctly for " + id);
     70        assert_computed_value(divWithFontSizeSet, syntax, value, expected);
     71    }, `${syntax} values are computed correctly [${value}]`);
     72}
    8173
    82     test(function() {
    83         assert_equals(computedStyle.getPropertyValue('--length-percentage-1'), '170px');
    84         assert_equals(computedStyle.getPropertyValue('--length-percentage-2'), '18%');
    85         assert_equals(computedStyle.getPropertyValue('--length-percentage-3'), 'calc(190px + -2%)');
    86     }, "<length-percentage> values are computed correctly for " + id);
     74test(function(){
     75    const element = divWithFontSizeSet;
     76    with_custom_property(element, '<length>', '14em', (name) => {
     77        assert_computed_value(element, '<length>', `var(${name})`, '140px');
     78    });
     79}, '<length> values computed are correctly via var()-reference');
    8780
    88     test(function() {
    89         assert_equals(computedStyle.getPropertyValue('--csv-1'), '10px, 30px');
    90         assert_equals(computedStyle.getPropertyValue('--csv-2'), '40px, 9px');
    91         assert_equals(computedStyle.getPropertyValue('--csv-3'), '80px');
    92     }, "<length># values are computed correctly for " + id);
     81test(function(){
     82    const element = divWithFontSizeInherited;
     83    with_custom_property(element, '<length>', '14em', (name) => {
     84        assert_computed_value(element, '<length>', `var(${name})`, '140px');
     85    });
     86}, '<length> values computed are correctly via var()-reference when font-size is inherited');
    9387
    94     test(function() {
    95         assert_equals(computedStyle.getPropertyValue('--csv-4'), '3%, 80px, 22px');
    96         assert_equals(computedStyle.getPropertyValue('--csv-5'), 'calc(10px + 50%), 4px');
    97         assert_equals(computedStyle.getPropertyValue('--csv-6'), 'calc(37px + 13%)');
    98     }, "<length-percentage># values are computed correctly for " + id);
     88test(function(){
     89    const element = divWithFontSizeInherited;
     90    assert_computed_value(element, '<length>', '14em', '140px');
     91}, '<length> values are computed correctly when font-size is inherited [14em]');
    9992
    100     test(function() {
    101         assert_equals(computedStyle.getPropertyValue('--list-1'), '10px 30px');
    102         assert_equals(computedStyle.getPropertyValue('--list-2'), '40px 9px');
    103     }, "<length>+ values are computed correctly for " + id);
     93test(function(){
     94    const element = divWithFontSizeInherited;
     95    assert_computed_value(element, '<length>', 'calc(14em + 10px)', '150px');
     96}, '<length> values are computed correctly when font-size is inherited [calc(14em + 10px)]');
    10497
    105     test(function() {
    106         assert_equals(computedStyle.getPropertyValue('--list-3'), '3% 80px 22px');
    107         assert_equals(computedStyle.getPropertyValue('--list-4'), 'calc(10px + 50%) 4px');
    108     }, "<length-percentage>+ values are computed correctly for " + id);
     98test_computed_value('<length>', '12px', '12px');
     99test_computed_value('<length>', '13vw', length_ref('13vw'));
     100test_computed_value('<length>', '14em', '140px');
     101test_computed_value('<length>', '15vmin', length_ref('15vmin'));
     102test_computed_value('<length>', 'calc(16px - 7em + 10vh)', length_ref('calc(10vh - 54px)'));
    109103
    110     test(function() {
    111         assert_equals(computedStyle.getPropertyValue('--transform-function-1'), 'translateX(2px)');
    112         assert_equals(computedStyle.getPropertyValue('--transform-function-2'), 'translateX(100px)');
    113         assert_equals(computedStyle.getPropertyValue('--transform-function-3'), 'translateX(calc(110px + 10%))');
    114         assert_equals(computedStyle.getPropertyValue('--transform-function-4'), 'translateX(10%) scale(2)');
    115     }, "<transform-function> values are computed correctly for " + id);
    116 }
     104test_computed_value('<length-percentage>', '17em', '170px');
     105test_computed_value('<length-percentage>', '18%', '18%');
     106test_computed_value('<length-percentage>', 'calc(19em - 2%)', 'calc(-2% + 190px)');
     107
     108test_computed_value('<length>#', '10px, 3em', '10px, 30px');
     109test_computed_value('<length>#', '4em ,9px', '40px, 9px');
     110test_computed_value('<length>#', '8em', '80px');
     111
     112test_computed_value('<length-percentage>#', '3% , 10vmax  , 22px', ['3%', length_ref('10vmax'), '22px'].join(', '));
     113test_computed_value('<length-percentage>#', 'calc(50% + 1em), 4px', 'calc(50% + 10px), 4px');
     114test_computed_value('<length-percentage>#', 'calc(13% + 37px)', 'calc(13% + 37px)');
     115
     116test_computed_value('<length>+', '10px 3em', '10px 30px');
     117test_computed_value('<length>+', '4em 9px', '40px 9px');
     118
     119test_computed_value('<length-percentage>+', '3% 10vmax 22px', ['3%', length_ref('10vmax'), '22px'].join(' '));
     120test_computed_value('<length-percentage>+', 'calc(50% + 1em) 4px', 'calc(50% + 10px) 4px');
     121
     122test_computed_value('<transform-function>', 'translateX(2px)', 'translateX(2px)');
     123test_computed_value('<transform-function>', 'translateX(10em)', 'translateX(100px)');
     124test_computed_value('<transform-function>', 'translateX(calc(11em + 10%))', 'translateX(calc(10% + 110px))');
     125test_computed_value('<transform-function>+', 'translateX(10%) scale(2)', 'translateX(10%) scale(2)');
     126
     127test_computed_value('<integer>', '15', '15');
     128test_computed_value('<integer>', 'calc(15 + 15)', '30');
     129test_computed_value('<integer>', 'calc(2.4)', '2');
     130test_computed_value('<integer>', 'calc(2.6)', '3');
     131test_computed_value('<integer>', 'calc(2.6 + 3.1)', '6');
     132
     133test_computed_value('<integer>+', '15 calc(2.4) calc(2.6)', '15 2 3');
     134
     135test_computed_value('<color>', '#ff0000', 'rgb(255, 0, 0)');
     136test_computed_value('<color>', '#000f00', 'rgb(0, 15, 0)');
     137test_computed_value('<color>', '#00000a', 'rgb(0, 0, 10)');
     138test_computed_value('<color>', '#badbee', 'rgb(186, 219, 238)');
     139test_computed_value('<color>', '#badbee33', 'rgba(186, 219, 238, 0.2)');
     140test_computed_value('<color>', 'tomato', 'rgb(255, 99, 71)');
     141test_computed_value('<color>', 'plum', 'rgb(221, 160, 221)');
     142test_computed_value('<color>', 'currentcolor', 'currentcolor');
     143
     144// Custom ident values that look like color keywords should not be converted.
     145test_computed_value('*', 'tomato', 'tomato');
     146test_computed_value('tomato | plum', 'plum', 'plum');
     147test_computed_value('tomato | plum | <color>', 'plum', 'plum');
     148
     149test_computed_value('*', '-50grad', '-50grad');
     150test_computed_value('<angle>', '180deg', '180deg');
     151test_computed_value('<angle>', '400grad', '360deg');
     152test_computed_value('<angle>', 'calc(360deg + 400grad)', '720deg');
     153
     154test_computed_value('*', '50s', '50s');
     155test_computed_value('<time>', '1s', '1s');
     156test_computed_value('<time>', '1000ms', '1s');
     157test_computed_value('<time>', 'calc(1000ms + 1s)', '2s');
     158
     159test_computed_value('*', '50dpi', '50dpi');
     160test_computed_value('<resolution>', '1dppx', '1dppx');
     161test_computed_value('<resolution>', '96dpi', '1dppx');
     162test_computed_value('<resolution>', 'calc(1dppx + 96dpi)', '2dppx');
     163
    117164</script>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-cssom-expected.txt

    r237697 r239365  
    22PASS CSSOM setters function as expected for unregistered properties
    33FAIL CSS.registerProperty The given initial value does not parse for the given syntax.
    4 FAIL Formerly valid values are still readable from inline styles but are computed as the unset value assert_equals: expected "blue" but got "hello"
     4FAIL Formerly valid values are still readable from inline styles but are computed as the unset value assert_equals: expected "rgb(0, 0, 255)" but got "hello"
    55FAIL Values not matching the registered type can't be set assert_equals: expected "hello" but got "20"
    6 FAIL Values can be removed from inline styles assert_equals: expected "red" but got " red"
     6FAIL Values can be removed from inline styles assert_equals: expected "rgb(255, 0, 0)" but got " red"
    77PASS Stylesheets can be modified by CSSOM
    8 FAIL Valid values can be set on inline styles assert_equals: expected "blue" but got " blue"
     8FAIL Valid values can be set on inline styles assert_equals: expected "rgb(255, 192, 203)" but got "pink"
    99
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-cssom.html

    r236444 r239365  
    4747  assert_equals(inlineStyle.getPropertyValue('--color'), 'hello');
    4848  assert_equals(computedStyle.getPropertyValue('--length'), '0px');
    49   assert_equals(computedStyle.getPropertyValue('--color'), 'blue');
     49  assert_equals(computedStyle.getPropertyValue('--color'), 'rgb(0, 0, 255)');
    5050}, "Formerly valid values are still readable from inline styles but are computed as the unset value");
    5151
     
    6363  assert_equals(inlineStyle.getPropertyValue('--color'), '');
    6464  assert_equals(computedStyle.getPropertyValue('--length'), '10px');
    65   assert_equals(computedStyle.getPropertyValue('--color'), 'red');
     65  assert_equals(computedStyle.getPropertyValue('--color'), 'rgb(255, 0, 0)');
    6666}, "Values can be removed from inline styles");
    6767
     
    8181  assert_equals(inlineStyle.getPropertyValue('--color'), 'pink');
    8282  assert_equals(computedStyle.getPropertyValue('--length'), '30px');
    83   assert_equals(computedStyle.getPropertyValue('--color'), 'pink');
     83  assert_equals(computedStyle.getPropertyValue('--color'), 'rgb(255, 192, 203)');
    8484  inlineStyle.setProperty('--color', 'inherit');
    8585  assert_equals(inlineStyle.getPropertyValue('--color'), 'inherit');
    86   assert_equals(computedStyle.getPropertyValue('--color'), 'blue');
     86  assert_equals(computedStyle.getPropertyValue('--color'), 'rgb(0, 0, 255)');
    8787}, "Valid values can be set on inline styles");
    8888</script>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-initial-expected.txt

    r236828 r239365  
    11
    2 FAIL Initial values of registered properties can be referenced when no custom properties are explicitly set. The given initial value does not parse for the given syntax.
     2PASS Initial value for <length> correctly computed [calc(10px + 15px)]
     3FAIL Initial value for <length-percentage> correctly computed [calc(1in + 10% + 4px)] The given initial value does not parse for the given syntax.
     4FAIL Initial value for <color> correctly computed [pink, inherits] The given initial value does not parse for the given syntax.
     5FAIL Initial value for <color> correctly computed [purple] The given initial value does not parse for the given syntax.
     6FAIL Initial value for <transform-function> correctly computed [rotate(42deg)] The given initial value does not parse for the given syntax.
     7FAIL Initial value for <transform-list> correctly computed [scale(calc(2 + 2))] The given initial value does not parse for the given syntax.
     8FAIL Initial value for <transform-list> correctly computed [scale(calc(2 + 1)) translateX(calc(3px + 1px))] The given initial value does not parse for the given syntax.
     9FAIL Initial inherited value can be substituted [purple, color] The given initial value does not parse for the given syntax.
     10FAIL Initial non-inherited value can be substituted [pink, background-color] The given initial value does not parse for the given syntax.
    311
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-initial.html

    r236444 r239365  
    1 <!DOCTYPE HTML>
     1<!DOCTYPE html>
    22<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#dom-propertydescriptor-initialvalue" />
    33<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#register-a-custom-property" />
    44<script src="/resources/testharness.js"></script>
    55<script src="/resources/testharnessreport.js"></script>
    6 <style>
    7 #target {
    8   background: var(--inherited-color);
    9   color: var(--non-inherited-color);
    10 }
    11 </style>
     6<script src="./resources/utils.js"></script>
    127<div id=target></div>
    138<script>
    14 test(function() {
    15     CSS.registerProperty({name: '--length', syntax: '<length>', initialValue: 'calc(10px + 15px)', inherits: false});
    16     CSS.registerProperty({name: '--length-percentage', syntax: '<length-percentage>', initialValue: 'calc(1in + 10% + 4px)', inherits: false});
    17     CSS.registerProperty({name: '--inherited-color', syntax: '<color>', initialValue: 'pink', inherits: true});
    18     CSS.registerProperty({name: '--non-inherited-color', syntax: '<color>', initialValue: 'purple', inherits: false});
    19     CSS.registerProperty({name: '--transform-function', syntax: '<transform-function>', initialValue: 'rotate(42deg)', inherits: false});
    20     CSS.registerProperty({name: '--single-transform-list', syntax: '<transform-list>', initialValue: 'scale(calc(2 + 2))', inherits: false});
    21     CSS.registerProperty({name: '--multiple-transform-list', syntax: '<transform-list>', initialValue: 'scale(calc(2 + 1)) translateX(calc(3px + 1px))', inherits: false});
    229
    23     computedStyle = getComputedStyle(target);
    24     assert_equals(computedStyle.getPropertyValue('--length'), '25px');
    25     assert_equals(computedStyle.getPropertyValue('--length-percentage'), 'calc(100px + 10%)');
    26     assert_equals(computedStyle.getPropertyValue('--inherited-color'), 'pink');
    27     assert_equals(computedStyle.getPropertyValue('--non-inherited-color'), 'purple');
    28     assert_equals(computedStyle.getPropertyValue('--transform-function'), 'rotate(42deg)');
    29     assert_equals(computedStyle.getPropertyValue('--single-transform-list'), 'scale(4)');
    30     assert_equals(computedStyle.getPropertyValue('--multiple-transform-list'), 'scale(3) translateX(4px)');
     10function test_initial_value(reg, expected) {
     11    let suffix = reg.inherits === true ? ', inherits' : '';
     12    test(function(){
     13        let name = generate_property(reg);
     14        let actual = getComputedStyle(target).getPropertyValue(name);
     15        assert_equals(actual, expected);
     16    }, `Initial value for ${reg.syntax} correctly computed [${reg.initialValue}${suffix}]`);
     17}
    3118
    32     assert_equals(computedStyle.backgroundColor, 'rgb(255, 192, 203)');
    33     assert_equals(computedStyle.color, 'rgb(128, 0, 128)');
    34 }, "Initial values of registered properties can be referenced when no custom properties are explicitly set.");
     19test_initial_value({ syntax: '<length>', initialValue: 'calc(10px + 15px)' }, '25px');
     20test_initial_value({ syntax: '<length-percentage>', initialValue: 'calc(1in + 10% + 4px)' }, 'calc(10% + 100px)');
     21test_initial_value({ syntax: '<color>', initialValue: 'pink', inherits: true }, 'rgb(255, 192, 203)');
     22test_initial_value({ syntax: '<color>', initialValue: 'purple' }, 'rgb(128, 0, 128)');
     23test_initial_value({ syntax: '<transform-function>', initialValue: 'rotate(42deg)' }, 'rotate(42deg)');
     24test_initial_value({ syntax: '<transform-list>', initialValue: 'scale(calc(2 + 2))' }, 'scale(4)');
     25test_initial_value({ syntax: '<transform-list>', initialValue: 'scale(calc(2 + 1)) translateX(calc(3px + 1px))' }, 'scale(3) translateX(4px)');
     26
     27// Test that the initial value of the custom property 'reg' is successfully
     28// substituted into 'property'.
     29function test_substituted_value(reg, property, expected) {
     30    let inherits_text = reg.inherits === true ? 'inherited' : 'non-inherited';
     31    test(function(){
     32        try {
     33            let name = generate_property(reg);
     34            target.style = `${property}:var(${name});`;
     35            assert_equals(getComputedStyle(target).getPropertyValue(property), expected);
     36        } finally {
     37            target.style = '';
     38        }
     39    }, `Initial ${inherits_text} value can be substituted [${reg.initialValue}, ${property}]`);
     40}
     41
     42test_substituted_value({ syntax: '<color>', initialValue: 'purple', inherits: true }, 'color', 'rgb(128, 0, 128)');
     43test_substituted_value({ syntax: '<color>', initialValue: 'pink' }, 'background-color', 'rgb(255, 192, 203)');
     44
    3545</script>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/typedom.tentative-expected.txt

    r239341 r239365  
    1 CONSOLE MESSAGE: line 349: TypeError: CSS.px is not a function. (In 'CSS.px(15)', 'CSS.px' is undefined)
     1CONSOLE MESSAGE: line 38: TypeError: target.attributeStyleMap.clear is not a function. (In 'target.attributeStyleMap.clear()', 'target.attributeStyleMap.clear' is undefined)
    22
    3 Harness Error (FAIL), message = TypeError: CSS.px is not a function. (In 'CSS.px(15)', 'CSS.px' is undefined)
     3Harness Error (FAIL), message = TypeError: target.attributeStyleMap.clear is not a function. (In 'target.attributeStyleMap.clear()', 'target.attributeStyleMap.clear' is undefined)
    44
    55FAIL Computed * is reified as CSSUnparsedValue target.computedStyleMap is not a function. (In 'target.computedStyleMap()', 'target.computedStyleMap' is undefined)
    6 FAIL Computed <angle> is reified as CSSUnitValue The given initial value does not parse for the given syntax.
    7 FAIL Computed <color> is reified as CSSStyleValue The given initial value does not parse for the given syntax.
    8 FAIL Computed <custom-ident> is reified as CSSKeywordValue The given initial value does not parse for the given syntax.
    9 FAIL Computed <image> [url] is reified as CSSImageValue The given initial value does not parse for the given syntax.
    10 FAIL Computed <integer> is reified as CSSUnitValue The given initial value does not parse for the given syntax.
    11 FAIL Computed <length-percentage> [%] is reified as CSSUnitValue target.computedStyleMap is not a function. (In 'target.computedStyleMap()', 'target.computedStyleMap' is undefined)
    12 FAIL Computed <length-percentage> [px] is reified as CSSUnitValue target.computedStyleMap is not a function. (In 'target.computedStyleMap()', 'target.computedStyleMap' is undefined)
    13 FAIL Computed <length-percentage> [px + %] is reified as CSSMathSum Can't find variable: CSSMathSum
    14 FAIL Computed <length> is reified as CSSUnitValue target.computedStyleMap is not a function. (In 'target.computedStyleMap()', 'target.computedStyleMap' is undefined)
    15 FAIL Computed <number> is reified as CSSUnitValue The given initial value does not parse for the given syntax.
    16 FAIL Computed <percentage> is reified as CSSUnitValue target.computedStyleMap is not a function. (In 'target.computedStyleMap()', 'target.computedStyleMap' is undefined)
    17 FAIL Computed <resolution> is reified as CSSUnitValue The given initial value does not parse for the given syntax.
    18 FAIL Computed <time> is reified as CSSUnitValue The given initial value does not parse for the given syntax.
    19 FAIL Computed <url> is reified as CSSStyleValue The given initial value does not parse for the given syntax.
    20 FAIL Computed ident is reified as CSSKeywordValue The given initial value does not parse for the given syntax.
    21 FAIL First computed value correctly reified in space-separated list The given initial value does not parse for the given syntax.
    22 FAIL First computed value correctly reified in comma-separated list The given initial value does not parse for the given syntax.
    23 FAIL All computed values correctly reified in space-separated list The given initial value does not parse for the given syntax.
    24 FAIL All computed values correctly reified in comma-separated list The given initial value does not parse for the given syntax.
    25 FAIL attributeStyleMap.get returns CSSUnparsedValue for value with var references target.attributeStyleMap.clear is not a function. (In 'target.attributeStyleMap.clear()', 'target.attributeStyleMap.clear' is undefined)
    26 FAIL styleMap.get returns CSSUnparsedValue for value with var references undefined is not an object (evaluating 'rule.styleMap.clear')
    27 FAIL attributeStyleMap.get returns CSSUnparsedValue for value with var references in list target.attributeStyleMap.clear is not a function. (In 'target.attributeStyleMap.clear()', 'target.attributeStyleMap.clear' is undefined)
    28 FAIL styleMap.get returns CSSUnparsedValue for value with var references in list undefined is not an object (evaluating 'rule.styleMap.clear')
    29 FAIL attributeStyleMap.get returns CSSUnparsedValue for * target.attributeStyleMap.clear is not a function. (In 'target.attributeStyleMap.clear()', 'target.attributeStyleMap.clear' is undefined)
    30 FAIL styleMap.get returns CSSUnparsedValue for * undefined is not an object (evaluating 'rule.styleMap.clear')
    31 FAIL attributeStyleMap.get returns CSSUnitValue for <angle> target.attributeStyleMap.clear is not a function. (In 'target.attributeStyleMap.clear()', 'target.attributeStyleMap.clear' is undefined)
    32 FAIL styleMap.get returns CSSUnitValue for <angle> undefined is not an object (evaluating 'rule.styleMap.clear')
    33 FAIL attributeStyleMap.get returns CSSStyleValue for <color> target.attributeStyleMap.clear is not a function. (In 'target.attributeStyleMap.clear()', 'target.attributeStyleMap.clear' is undefined)
    34 FAIL styleMap.get returns CSSStyleValue for <color> undefined is not an object (evaluating 'rule.styleMap.clear')
    35 FAIL attributeStyleMap.get returns CSSKeywordValue for <custom-ident> target.attributeStyleMap.clear is not a function. (In 'target.attributeStyleMap.clear()', 'target.attributeStyleMap.clear' is undefined)
    36 FAIL styleMap.get returns CSSKeywordValue for <custom-ident> undefined is not an object (evaluating 'rule.styleMap.clear')
    37 FAIL attributeStyleMap.get returns CSSImageValue for <image> target.attributeStyleMap.clear is not a function. (In 'target.attributeStyleMap.clear()', 'target.attributeStyleMap.clear' is undefined)
    38 FAIL styleMap.get returns CSSImageValue for <image> undefined is not an object (evaluating 'rule.styleMap.clear')
    39 FAIL attributeStyleMap.get returns CSSUnitValue for <integer> target.attributeStyleMap.clear is not a function. (In 'target.attributeStyleMap.clear()', 'target.attributeStyleMap.clear' is undefined)
    40 FAIL styleMap.get returns CSSUnitValue for <integer> undefined is not an object (evaluating 'rule.styleMap.clear')
    41 FAIL attributeStyleMap.get returns CSSUnitValue for <length-percentage> [10%] target.attributeStyleMap.clear is not a function. (In 'target.attributeStyleMap.clear()', 'target.attributeStyleMap.clear' is undefined)
    42 FAIL styleMap.get returns CSSUnitValue for <length-percentage> [10%] undefined is not an object (evaluating 'rule.styleMap.clear')
    43 FAIL attributeStyleMap.get returns CSSUnitValue for <length-percentage> [10px] target.attributeStyleMap.clear is not a function. (In 'target.attributeStyleMap.clear()', 'target.attributeStyleMap.clear' is undefined)
    44 FAIL styleMap.get returns CSSUnitValue for <length-percentage> [10px] undefined is not an object (evaluating 'rule.styleMap.clear')
    45 FAIL attributeStyleMap.get returns CSSMathSum for <length-percentage> [calc(10px + 10%)] target.attributeStyleMap.clear is not a function. (In 'target.attributeStyleMap.clear()', 'target.attributeStyleMap.clear' is undefined)
    46 FAIL styleMap.get returns CSSMathSum for <length-percentage> [calc(10px + 10%)] undefined is not an object (evaluating 'rule.styleMap.clear')
    47 FAIL attributeStyleMap.get returns CSSUnitValue for <length> target.attributeStyleMap.clear is not a function. (In 'target.attributeStyleMap.clear()', 'target.attributeStyleMap.clear' is undefined)
    48 FAIL styleMap.get returns CSSUnitValue for <length> undefined is not an object (evaluating 'rule.styleMap.clear')
    49 FAIL attributeStyleMap.get returns CSSUnitValue for <number> target.attributeStyleMap.clear is not a function. (In 'target.attributeStyleMap.clear()', 'target.attributeStyleMap.clear' is undefined)
    50 FAIL styleMap.get returns CSSUnitValue for <number> undefined is not an object (evaluating 'rule.styleMap.clear')
    51 FAIL attributeStyleMap.get returns CSSUnitValue for <percentage> target.attributeStyleMap.clear is not a function. (In 'target.attributeStyleMap.clear()', 'target.attributeStyleMap.clear' is undefined)
    52 FAIL styleMap.get returns CSSUnitValue for <percentage> undefined is not an object (evaluating 'rule.styleMap.clear')
    53 FAIL attributeStyleMap.get returns CSSUnitValue for <resolution> target.attributeStyleMap.clear is not a function. (In 'target.attributeStyleMap.clear()', 'target.attributeStyleMap.clear' is undefined)
    54 FAIL styleMap.get returns CSSUnitValue for <resolution> undefined is not an object (evaluating 'rule.styleMap.clear')
    55 FAIL attributeStyleMap.get returns CSSUnitValue for <time> target.attributeStyleMap.clear is not a function. (In 'target.attributeStyleMap.clear()', 'target.attributeStyleMap.clear' is undefined)
    56 FAIL styleMap.get returns CSSUnitValue for <time> undefined is not an object (evaluating 'rule.styleMap.clear')
    57 FAIL attributeStyleMap.get returns CSSStyleValue for <url> target.attributeStyleMap.clear is not a function. (In 'target.attributeStyleMap.clear()', 'target.attributeStyleMap.clear' is undefined)
    58 FAIL styleMap.get returns CSSStyleValue for <url> undefined is not an object (evaluating 'rule.styleMap.clear')
    59 FAIL attributeStyleMap.get returns CSSKeywordValue for thing1 | THING2 target.attributeStyleMap.clear is not a function. (In 'target.attributeStyleMap.clear()', 'target.attributeStyleMap.clear' is undefined)
    60 FAIL styleMap.get returns CSSKeywordValue for thing1 | THING2 undefined is not an object (evaluating 'rule.styleMap.clear')
    61 FAIL attributeStyleMap.get returns CSSUnitValue for <length>+ target.attributeStyleMap.clear is not a function. (In 'target.attributeStyleMap.clear()', 'target.attributeStyleMap.clear' is undefined)
    62 FAIL styleMap.get returns CSSUnitValue for <length>+ undefined is not an object (evaluating 'rule.styleMap.clear')
    63 FAIL attributeStyleMap.get returns CSSUnitValue for <length># target.attributeStyleMap.clear is not a function. (In 'target.attributeStyleMap.clear()', 'target.attributeStyleMap.clear' is undefined)
    64 FAIL styleMap.get returns CSSUnitValue for <length># undefined is not an object (evaluating 'rule.styleMap.clear')
    65 FAIL attributeStyleMap.getAll returns a list of CSSUnitValues for <length>+ target.attributeStyleMap.clear is not a function. (In 'target.attributeStyleMap.clear()', 'target.attributeStyleMap.clear' is undefined)
    66 FAIL styleMap.getAll returns a list of CSSUnitValues for <length>+ undefined is not an object (evaluating 'rule.styleMap.clear')
    67 FAIL attributeStyleMap.getAll returns a list of CSSUnitValues for <length># target.attributeStyleMap.clear is not a function. (In 'target.attributeStyleMap.clear()', 'target.attributeStyleMap.clear' is undefined)
    68 FAIL styleMap.getAll returns a list of CSSUnitValues for <length># undefined is not an object (evaluating 'rule.styleMap.clear')
    696
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/typedom.tentative.html

    r236444 r239365  
    3434}
    3535
     36// Cleans style rules used for testing between every test.
     37add_result_callback(function(){
     38    target.attributeStyleMap.clear();
     39    // Clears 'div' rule in #style:
     40    style.sheet.rules[0].styleMap.clear();
     41});
     42
    3643// On the target element, verify that computed value of 'name' is an instance
    3744// of 'expected' and not an instance of CSSUnparsedValue.
     
    215222    styleDecl.setProperty(name2, `var(${name1})`);
    216223    assert_true(propertyMap.get(name2) instanceof CSSUnparsedValue);
    217 }, name => `${name}.get returns CSSUnparsedValue for value with var references`);
     224}, name => `StylePropertyMap.get returns CSSUnparsedValue for value with var references (${name})`);
    218225
    219226test_style_property_map_get(function(styleDecl, propertyMap){
     
    222229    styleDecl.setProperty(name2, `1px, var(${name1}), 3px`);
    223230    assert_true(propertyMap.get(name2) instanceof CSSUnparsedValue);
    224 }, name => `${name}.get returns CSSUnparsedValue for value with var references in list`);
     231}, name => `StylePropertyMap.get returns CSSUnparsedValue for value with var references in list (${name})`);
    225232
    226233test_style_property_map_get(function(styleDecl, propertyMap){
    227234    assert_attribute_get_type(styleDecl, propertyMap, '*', 'if(){}', CSSUnparsedValue);
    228 }, name => `${name}.get returns CSSUnparsedValue for *`);
     235}, name => `StylePropertyMap.get returns CSSUnparsedValue for * (${name})`);
    229236
    230237test_style_property_map_get(function(styleDecl, propertyMap){
    231238    assert_attribute_get_type(styleDecl, propertyMap, '<angle>', '42deg', CSSUnitValue);
    232 }, name => `${name}.get returns CSSUnitValue for <angle>`);
     239}, name => `StylePropertyMap.get returns CSSUnitValue for <angle> (${name})`);
    233240
    234241test_style_property_map_get(function(styleDecl, propertyMap){
    235242    assert_attribute_get_type(styleDecl, propertyMap, '<color>', '#fefefe', CSSStyleValue);
    236 }, name => `${name}.get returns CSSStyleValue for <color>`);
     243}, name => `StylePropertyMap.get returns CSSStyleValue for <color> (${name})`);
    237244
    238245test_style_property_map_get(function(styleDecl, propertyMap){
    239246    assert_attribute_get_type(styleDecl, propertyMap, '<custom-ident>', 'none', CSSKeywordValue);
    240 }, name => `${name}.get returns CSSKeywordValue for <custom-ident>`);
     247}, name => `StylePropertyMap.get returns CSSKeywordValue for <custom-ident> (${name})`);
    241248
    242249test_style_property_map_get(function(styleDecl, propertyMap){
    243250    assert_attribute_get_type(styleDecl, propertyMap, '<image>', 'url(thing.png)', CSSImageValue);
    244 }, name => `${name}.get returns CSSImageValue for <image>`);
     251}, name => `StylePropertyMap.get returns CSSImageValue for <image> (${name})`);
    245252
    246253test_style_property_map_get(function(styleDecl, propertyMap){
    247254    assert_attribute_get_type(styleDecl, propertyMap, '<integer>', '100', CSSUnitValue);
    248 }, name => `${name}.get returns CSSUnitValue for <integer>`);
     255}, name => `StylePropertyMap.get returns CSSUnitValue for <integer> (${name})`);
    249256
    250257test_style_property_map_get(function(styleDecl, propertyMap){
    251258    assert_attribute_get_type(styleDecl, propertyMap, '<length-percentage>', '10%', CSSUnitValue);
    252 }, name => `${name}.get returns CSSUnitValue for <length-percentage> [10%]`);
     259}, name => `StylePropertyMap.get returns CSSUnitValue for <length-percentage> [10%] (${name})`);
    253260
    254261test_style_property_map_get(function(styleDecl, propertyMap){
    255262    assert_attribute_get_type(styleDecl, propertyMap, '<length-percentage>', '10px', CSSUnitValue);
    256 }, name => `${name}.get returns CSSUnitValue for <length-percentage> [10px]`);
     263}, name => `StylePropertyMap.get returns CSSUnitValue for <length-percentage> [10px] (${name})`);
    257264
    258265test_style_property_map_get(function(styleDecl, propertyMap){
    259266    assert_attribute_get_type(styleDecl, propertyMap, '<length-percentage>', 'calc(10px + 10%)', CSSMathSum);
    260 }, name => `${name}.get returns CSSMathSum for <length-percentage> [calc(10px + 10%)]`);
     267}, name => `StylePropertyMap.get returns CSSMathSum for <length-percentage> [calc(10px + 10%)] (${name})`);
    261268
    262269test_style_property_map_get(function(styleDecl, propertyMap){
    263270    assert_attribute_get_type(styleDecl, propertyMap, '<length>', '10px', CSSUnitValue);
    264 }, name => `${name}.get returns CSSUnitValue for <length>`);
     271}, name => `StylePropertyMap.get returns CSSUnitValue for <length> (${name})`);
    265272
    266273test_style_property_map_get(function(styleDecl, propertyMap){
    267274    assert_attribute_get_type(styleDecl, propertyMap, '<number>', '42', CSSUnitValue);
    268 }, name => `${name}.get returns CSSUnitValue for <number>`);
     275}, name => `StylePropertyMap.get returns CSSUnitValue for <number> (${name})`);
    269276
    270277test_style_property_map_get(function(styleDecl, propertyMap){
    271278    assert_attribute_get_type(styleDecl, propertyMap, '<percentage>', '10%', CSSUnitValue);
    272 }, name => `${name}.get returns CSSUnitValue for <percentage>`);
     279}, name => `StylePropertyMap.get returns CSSUnitValue for <percentage> (${name})`);
    273280
    274281test_style_property_map_get(function(styleDecl, propertyMap){
    275282    assert_attribute_get_type(styleDecl, propertyMap, '<resolution>', '300dpi', CSSUnitValue);
    276 }, name => `${name}.get returns CSSUnitValue for <resolution>`);
     283}, name => `StylePropertyMap.get returns CSSUnitValue for <resolution> (${name})`);
    277284
    278285test_style_property_map_get(function(styleDecl, propertyMap){
    279286    assert_attribute_get_type(styleDecl, propertyMap, '<time>', '42s', CSSUnitValue);
    280 }, name => `${name}.get returns CSSUnitValue for <time>`);
     287}, name => `StylePropertyMap.get returns CSSUnitValue for <time> (${name})`);
    281288
    282289test_style_property_map_get(function(styleDecl, propertyMap){
    283290    assert_attribute_get_type(styleDecl, propertyMap, '<url>', 'url(a)', CSSStyleValue);
    284 }, name => `${name}.get returns CSSStyleValue for <url>`);
     291}, name => `StylePropertyMap.get returns CSSStyleValue for <url> (${name})`);
    285292
    286293test_style_property_map_get(function(styleDecl, propertyMap){
    287294    assert_attribute_get_type(styleDecl, propertyMap, 'thing1 | THING2', 'thing1', CSSKeywordValue);
    288 }, name => `${name}.get returns CSSKeywordValue for thing1 | THING2`);
     295}, name => `StylePropertyMap.get returns CSSKeywordValue for thing1 | THING2 (${name})`);
    289296
    290297test_style_property_map_get(function(styleDecl, propertyMap){
    291298    assert_attribute_get_type(styleDecl, propertyMap, '<length>+', '10px 20px', CSSUnitValue);
    292 }, name => `${name}.get returns CSSUnitValue for <length>+`);
     299}, name => `StylePropertyMap.get returns CSSUnitValue for <length>+ (${name})`);
    293300
    294301test_style_property_map_get(function(styleDecl, propertyMap){
    295302    assert_attribute_get_type(styleDecl, propertyMap, '<length>#', '10px 20px', CSSUnitValue);
    296 }, name => `${name}.get returns CSSUnitValue for <length>#`);
     303}, name => `StylePropertyMap.get returns CSSUnitValue for <length># (${name})`);
    297304
    298305// attributeStyleMap.getAll
     
    303310    assert_equals(propertyMap.getAll(name).length, 3);
    304311    assert_true(propertyMap.getAll(name).every(x => x instanceof CSSUnitValue));
    305 }, name => `${name}.getAll returns a list of CSSUnitValues for <length>+`);
     312}, name => `StylePropertyMap.getAll returns a list of CSSUnitValues for <length>+ (${name})`);
    306313
    307314test_style_property_map_get(function(styleDecl, propertyMap){
     
    310317    assert_equals(propertyMap.getAll(name).length, 3);
    311318    assert_true(propertyMap.getAll(name).every(x => x instanceof CSSUnitValue));
    312 }, name => `${name}.getAll returns a list of CSSUnitValues for <length>#`);
     319}, name => `StylePropertyMap.getAll returns a list of CSSUnitValues for <length># (${name})`);
    313320
    314321// StylePropertyMap.set
     
    319326        propertyMap.clear();
    320327
     328        let ensureArray = v => v.constructor === Array ? v : [v];
     329
    321330        for (let value of options.shouldAccept)
    322             propertyMap.set(name, value);
     331            propertyMap.set(name, ...ensureArray(value));
    323332
    324333        for (let value of options.shouldReject) {
    325             assert_throws(new TypeError(), () => propertyMap.set(name, value));
     334            assert_throws(new TypeError(), () => propertyMap.set(name, ...ensureArray(value)));
    326335        }
    327     }, `${propertyMapName}.set accepts correct CSSUnitValues for ${options.syntax}`);
     336    }, `StylePropertyMap.set accepts correct CSSStyleValues for ${options.syntax} (${propertyMapName})`);
    328337}
    329338
     
    354363    initialValue: '0deg',
    355364    shouldAccept: [CSS.deg(42), CSS.turn(2), '42deg'],
    356     shouldReject: [unparsed('42deg'), CSS.px(15), '50px'],
     365    shouldReject: [unparsed('42deg'), CSS.px(15), '50px', [CSS.deg(15), '10deg']],
    357366});
    358367
     
    361370    initialValue: 'none',
    362371    shouldAccept: [keyword('foo'), 'foo'],
    363     shouldReject: [unparsed('foo'), CSS.px(15), '15px'],
     372    shouldReject: [unparsed('foo'), CSS.px(15), '15px', [keyword('foo'), 'foo']],
    364373});
    365374
     
    368377    initialValue: 'url(a)',
    369378    shouldAccept: [url_image('url(b)'), 'url(b)'],
    370     shouldReject: [unparsed('url(b)'), CSS.px(100), '50px'],
     379    shouldReject: [unparsed('url(b)'), CSS.px(100), '50px', [url_image('url(1)'), 'url(2)']],
    371380});
    372381
     
    374383    syntax: '<integer>',
    375384    initialValue: '0',
    376     shouldAccept: [CSS.number(1), CSS.number(-42), '1', '-42'],
    377     shouldReject: [unparsed('42'), CSS.px(100), '50px'],
     385    shouldAccept: [CSS.number(1), CSS.number(-42), '1', '-42', 'calc(2.4)'],
     386    shouldReject: [unparsed('42'), CSS.px(100), '50px', [CSS.number(42), '42'], 'calc(2px + 1px)'],
    378387});
    379388
     
    382391    initialValue: '0px',
    383392    shouldAccept: [CSS.percent(10), CSS.px(1), CSS.em(1), '10px', '10%'],
    384     shouldReject: [unparsed('10%'), unparsed('10px'), CSS.dpi(1), 'url(b)'],
     393    shouldReject: [unparsed('10%'), unparsed('10px'), CSS.dpi(1), 'url(b)', [CSS.percent(10), '10%']],
    385394});
    386395
     
    389398    initialValue: '0px',
    390399    shouldAccept: [CSS.px(10), CSS.em(10), CSS.vh(200), sum(CSS.px(10), CSS.em(20)), '10em', 'calc(10px + 10em)'],
    391     shouldReject: [unparsed('10px'), CSS.percent(1), 'url(b)'],
     400    shouldReject: [unparsed('10px'), CSS.percent(1), 'url(b)', [CSS.em(10), '10px']],
    392401});
    393402
     
    396405    initialValue: '0',
    397406    shouldAccept: [CSS.number(1337), CSS.number(-42.5), '1337', '-42.5'],
    398     shouldReject: [unparsed('42'), CSS.px(15), '#fef'],
     407    shouldReject: [unparsed('42'), CSS.px(15), '#fef', [CSS.number(-42.5), '42.5']],
    399408});
    400409
     
    403412    initialValue: '0%',
    404413    shouldAccept: [CSS.percent(10), '10%'],
    405     shouldReject: [unparsed('10%'), CSS.px(1), '#fef'],
     414    shouldReject: [unparsed('10%'), CSS.px(1), '#fef', [CSS.percent(10), '1%']],
    406415});
    407416
     
    410419    initialValue: '0dpi',
    411420    shouldAccept: [CSS.dpi(100), CSS.dpcm(10), CSS.dppx(50), '100dpi'],
    412     shouldReject: [unparsed('42'), CSS.px(15), '#fef'],
     421    shouldReject: [unparsed('42'), CSS.px(15), '#fef', [CSS.dpi(1), '2dpi']],
    413422});
    414423
     
    417426    initialValue: '0s',
    418427    shouldAccept: [CSS.s(42), CSS.ms(16), '16ms'],
    419     shouldReject: [unparsed('42s'), CSS.px(15), '#fef'],
     428    shouldReject: [unparsed('42s'), CSS.px(15), '#fef', [CSS.s(5), '6s']],
    420429});
    421430
     
    424433    initialValue: 'url(a)',
    425434    shouldAccept: [url_image('url(b)')],
    426     shouldReject: [unparsed('url(b)'), CSS.px(100), '#fef'],
     435    shouldReject: [unparsed('url(b)'), CSS.px(100), '#fef', [url_image('url(1)'), 'url(2)']],
    427436});
    428437
     
    438447    initialValue: 'none',
    439448    shouldAccept: [keyword('thing'), keyword('THING'), 'thing'],
    440     shouldReject: [unparsed('thing'), CSS.px(15), keyword('notathing'), 'notathing'],
     449    shouldReject: [unparsed('thing'), CSS.px(15), keyword('notathing'), 'notathing', [keyword('thing'), keyword('thing')]],
    441450});
    442451
     
    445454    initialValue: '0deg',
    446455    shouldAccept: [CSS.deg(42), CSS.turn(2), CSS.px(10), CSS.em(10), '10deg', '10px'],
    447     shouldReject: [unparsed('42deg'), unparsed('20px'), CSS.s(1), '#fef'],
     456    shouldReject: [unparsed('42deg'), unparsed('20px'), CSS.s(1), '#fef', [CSS.deg(42), '21deg']],
     457});
     458
     459// StylePropertyMap.set for list-valued properties:
     460
     461test_style_property_map_set({
     462    syntax: '<angle>+',
     463    initialValue: '0deg',
     464    shouldAccept: [CSS.deg(15), [CSS.deg(15), '10deg'], '15deg 10deg'],
     465    shouldReject: [[CSS.deg(15), CSS.px(10)], '15deg 10px'],
     466});
     467
     468test_style_property_map_set({
     469    syntax: '<custom-ident>+',
     470    initialValue: 'none',
     471    shouldAccept: [keyword('foo'), [keyword('foo'), 'bar'], 'foo bar'],
     472    shouldReject: [[keyword('foo'), CSS.px(10)], 'foo 10px'],
     473});
     474
     475test_style_property_map_set({
     476    syntax: '<image>+',
     477    initialValue: 'url(a)',
     478    shouldAccept: [url_image('url(1)'), [url_image('url(1)'), 'url(2)'], 'url(1) url(2)'],
     479    shouldReject: [[url_image('url(1)'), CSS.px(10)], 'url(1) 10px'],
     480});
     481
     482test_style_property_map_set({
     483    syntax: '<integer>+',
     484    initialValue: '0',
     485    shouldAccept: [CSS.number(42), [CSS.number(42), '42'], '42 42', 'calc(2.4) calc(2.6)'],
     486    shouldReject: [[CSS.number(42), keyword('noint')], '42 noint', 'calc(2px + 2px)'],
     487});
     488
     489test_style_property_map_set({
     490    syntax: '<length-percentage>+',
     491    initialValue: '0px',
     492    shouldAccept: [CSS.percent(10), [CSS.percent(10), '10%']],
     493    shouldReject: [[CSS.percent(10), keyword('nolength')], '10% nolength'],
     494});
     495
     496test_style_property_map_set({
     497    syntax: '<length>+',
     498    initialValue: '0px',
     499    shouldAccept: [CSS.em(10), [CSS.em(10), '10px']],
     500    shouldReject: [[CSS.em(10), keyword('nolength'), '10em nolength']],
     501});
     502
     503test_style_property_map_set({
     504    syntax: '<number>+',
     505    initialValue: '0',
     506    shouldAccept: [CSS.number(-42.5), [CSS.number(-42.5), '42.5'], '-42.5 42.5'],
     507    shouldReject: [[CSS.number(-42.5), CSS.px(10)], '-42.5 10px'],
     508});
     509
     510test_style_property_map_set({
     511    syntax: '<percentage>+',
     512    initialValue: '0%',
     513    shouldAccept: [CSS.percent(10), [CSS.percent(10), '1%'], '10% 1%'],
     514    shouldReject: [[CSS.percent(10), keyword('foo')], '10% foo'],
     515});
     516
     517test_style_property_map_set({
     518    syntax: '<resolution>+',
     519    initialValue: '0dpi',
     520    shouldAccept: [CSS.dpi(1), [CSS.dpi(1), '2dpi'], '1dpi 2dpi'],
     521    shouldReject: [[CSS.dpi(1), keyword('foo')], '1dpi foo'],
     522});
     523
     524test_style_property_map_set({
     525    syntax: '<time>+',
     526    initialValue: '0s',
     527    shouldAccept: [CSS.s(5), [CSS.s(5), '6s'], '5s 6s'],
     528    shouldReject: [[CSS.s(5), keyword('foo')], '5s foo'],
     529});
     530
     531test_style_property_map_set({
     532    syntax: '<url>+',
     533    initialValue: 'url(a)',
     534    shouldAccept: [url_image('url(1)'), [url_image('url(1)'), 'url(2)'], 'url(1) url(2)'],
     535    shouldReject: [[url_image('url(1)'), CSS.px(10)], 'url(1) 10px'],
     536});
     537
     538test_style_property_map_set({
     539    syntax: 'thing+',
     540    initialValue: 'thing',
     541    shouldAccept: [keyword('thing'), [keyword('thing'), 'thing'], 'thing thing'],
     542    shouldReject: [[keyword('thing'), CSS.px(10)], 'thing 10px'],
     543});
     544
     545test_style_property_map_set({
     546    syntax: '<length>#',
     547    initialValue: '0px',
     548    shouldAccept: [CSS.em(10), [CSS.em(10), '10px']],
     549    shouldReject: [[CSS.em(10), keyword('nolength'), '10em nolength']],
     550});
     551
     552function test_append_for_property_map(propertyMapName, propertyMap, options) {
     553    test(function(){
     554        let name = gen_prop(options.syntax, options.initialValue);
     555
     556        let ensureArray = v => v.constructor === Array ? v : [v];
     557
     558        for (let value of options.values) {
     559            propertyMap.clear();
     560
     561            if (value.base !== null)
     562                propertyMap.set(name, ...ensureArray(value.base));
     563
     564            // If 'null' is expected, it means we expect the append to fail.
     565            if (value.expect !== null) {
     566                propertyMap.append(name, ...ensureArray(value.append));
     567                let actual = Array.from(propertyMap.getAll(name)).join(' ');
     568                assert_equals(actual, value.expect);
     569            } else {
     570                assert_throws(new TypeError(), () => propertyMap.append(name, ...ensureArray(value.append)));
     571            }
     572        }
     573    }, `StylePropertyMap.append accepts correct CSSStyleValues for ${options.syntax} (${propertyMapName})`);
     574}
     575
     576// Verify that the correct CSSStyleValues are accepted/rejected when
     577// appending values to list-valued properties.
     578//
     579// The same test is performed twice: once for attributeStyleMap, and once
     580// for styleMap.
     581function test_append(options) {
     582    test_append_for_property_map('attributeStyleMap', target.attributeStyleMap, options);
     583    test_append_for_property_map('styleMap', style.sheet.rules[0].styleMap, options);
     584}
     585
     586test_append({
     587    syntax: '<angle>+',
     588    initialValue: '0deg',
     589    values: [
     590        { base: [CSS.deg(1)], append: [CSS.px(1)], expect: null },
     591        { base: [CSS.deg(1)], append: [CSS.deg(2), CSS.px(1)], expect: null },
     592        { base: [CSS.deg(1)], append: [CSS.deg(2), '1px'], expect: null },
     593        { base: [CSS.deg(1)], append: [CSS.turn(2), CSS.deg(3)], expect: '1deg 2turn 3deg' },
     594        { base: [CSS.deg(1), CSS.deg(2)], append: [CSS.deg(3)], expect: '1deg 2deg 3deg' },
     595        { base: [CSS.deg(1)], append: [CSS.deg(2), '3deg'], expect: '1deg 2deg 3deg' },
     596        { base: [CSS.deg(1)], append: [CSS.deg(2), '3turn 4deg'], expect: '1deg 2deg 3turn 4deg' },
     597        { base: null, append: [CSS.deg(1), '2deg'], expect: '1deg 2deg' },
     598    ],
     599});
     600
     601test_append({
     602    syntax: '<custom-ident>+',
     603    initialValue: 'none',
     604    values: [
     605        { base: [keyword('foo')], append: [CSS.px(1)], expect: null },
     606        { base: [keyword('foo')], append: [keyword('bar'), CSS.px(1)], expect: null },
     607        { base: [keyword('foo')], append: [keyword('bar'), '1px'], expect: null },
     608        { base: [keyword('foo')], append: [keyword('bar'), keyword('baz')], expect: 'foo bar baz' },
     609        { base: [keyword('foo'), keyword('bar')], append: [keyword('baz')], expect: 'foo bar baz' },
     610        { base: [keyword('foo')], append: [keyword('bar'), 'baz'], expect: 'foo bar baz' },
     611        { base: [keyword('foo')], append: [keyword('bar'), 'baz zim'], expect: 'foo bar baz zim' },
     612        { base: null, append: [keyword('foo'), 'bar'], expect: 'foo bar' },
     613    ],
     614});
     615
     616['<image>+', '<url>+'].forEach((syntax) => {
     617    test_append({
     618        syntax: syntax,
     619        initialValue: 'url(0)',
     620        values: [
     621            { base: [url_image('url("1")')], append: [CSS.px(1)], expect: null },
     622            { base: [url_image('url("1")')], append: [url_image('url("2")'), CSS.px(1)], expect: null },
     623            { base: [url_image('url("1")')], append: [url_image('url("2")'), '1px'], expect: null },
     624            { base: [url_image('url("1")')], append: [url_image('url("2")'), url_image('url("3")')], expect: 'url("1") url("2") url("3")' },
     625            { base: [url_image('url("1")'), url_image('url("2")')], append: [url_image('url("3")')], expect: 'url("1") url("2") url("3")' },
     626            { base: [url_image('url("1")')], append: [url_image('url("2")'), 'url("3")'], expect: 'url("1") url("2") url("3")' },
     627            { base: [url_image('url("1")')], append: [url_image('url("2")'), 'url("3") url("4")'], expect: 'url("1") url("2") url("3") url("4")' },
     628            { base: null, append: [url_image('url("1")'), 'url("2")'], expect: 'url("1") url("2")' },
     629        ],
     630    });
     631});
     632
     633test_append({
     634    syntax: '<integer>+',
     635    initialValue: '0',
     636    values: [
     637        { base: [CSS.number(1)], append: [CSS.px(1)], expect: null },
     638        { base: [CSS.number(1)], append: [CSS.number(2), CSS.px(1)], expect: null },
     639        { base: [CSS.number(1)], append: [CSS.number(2), 'noint'], expect: null },
     640        { base: [CSS.number(1)], append: [CSS.number(2), CSS.number(3)], expect: '1 2 3' },
     641        { base: [CSS.number(1), CSS.number(2)], append: [CSS.number(3)], expect: '1 2 3' },
     642        { base: [CSS.number(1)], append: [CSS.number(2), '3'], expect: '1 2 3' },
     643        { base: [CSS.number(1)], append: [CSS.number(2), '3 4'], expect: '1 2 3 4' },
     644        { base: null, append: [CSS.number(1), '2'], expect: '1 2' },
     645    ],
     646});
     647
     648test_append({
     649    syntax: '<length-percentage>+',
     650    initialValue: '0px',
     651    values: [
     652        { base: [CSS.px(1)], append: [keyword('nolength')], expect: null },
     653        { base: [CSS.px(1)], append: [CSS.px(2), keyword('nolength')], expect: null },
     654        { base: [CSS.px(1)], append: [CSS.px(2), 'nolength'], expect: null },
     655        { base: [CSS.px(1)], append: [CSS.px(2), CSS.percent(3)], expect: '1px 2px 3%' },
     656        { base: [CSS.px(1), CSS.px(2)], append: [CSS.percent(3)], expect: '1px 2px 3%' },
     657        { base: [CSS.px(1)], append: [CSS.percent(2), '3px'], expect: '1px 2% 3px' },
     658        { base: [CSS.px(1)], append: [CSS.px(2), '3% 4px'], expect: '1px 2px 3% 4px' },
     659        { base: null, append: [CSS.px(1), '2%'], expect: '1px 2%' },
     660    ],
     661});
     662
     663test_append({
     664    syntax: '<length>+',
     665    initialValue: '0',
     666    values: [
     667        { base: [CSS.px(1)], append: [keyword('nolength')], expect: null },
     668        { base: [CSS.px(1)], append: [CSS.px(2), keyword('nolength')], expect: null },
     669        { base: [CSS.px(1)], append: [CSS.px(2), 'nolength'], expect: null },
     670        { base: [CSS.px(1)], append: [CSS.em(2), CSS.px(3)], expect: '1px 2em 3px' },
     671        { base: [CSS.px(1), CSS.em(2)], append: [CSS.vh(3)], expect: '1px 2em 3vh' },
     672        { base: [CSS.px(1)], append: [CSS.em(2), '3px'], expect: '1px 2em 3px' },
     673        { base: [CSS.px(1)], append: [CSS.px(2), '3em 4cm'], expect: '1px 2px 3em 4cm' },
     674        { base: null, append: [CSS.vh(1), '2px'], expect: '1vh 2px' },
     675    ],
     676});
     677
     678test_append({
     679    syntax: '<number>+',
     680    initialValue: '0',
     681    values: [
     682        { base: [CSS.number(-1)], append: [keyword('NaN')], expect: null },
     683        { base: [CSS.number(-1)], append: [CSS.number(2.5), keyword('NaN')], expect: null },
     684        { base: [CSS.number(-1)], append: [CSS.number(2.5), '1px'], expect: null },
     685        { base: [CSS.number(-1)], append: [CSS.number(2.5), CSS.number(3.2)], expect: '-1 2.5 3.2' },
     686        { base: [CSS.number(-1), CSS.number(2.5)], append: [CSS.number(3.2)], expect: '-1 2.5 3.2' },
     687        { base: [CSS.number(-1)], append: [CSS.number(2.5), '3.2'], expect: '-1 2.5 3.2' },
     688        { base: [CSS.number(-1)], append: [CSS.number(2.5), '3.2 4'], expect: '-1 2.5 3.2 4' },
     689        { base: null, append: [CSS.number(-1), '2.5'], expect: '-1 2.5' },
     690    ],
     691});
     692
     693test_append({
     694    syntax: '<percentage>+',
     695    initialValue: '0%',
     696    values: [
     697        { base: [CSS.percent(1)], append: [CSS.px(1)], expect: null },
     698        { base: [CSS.percent(1)], append: [CSS.percent(2), CSS.px(1)], expect: null },
     699        { base: [CSS.percent(1)], append: [CSS.percent(2), '1px'], expect: null },
     700        { base: [CSS.percent(1)], append: [CSS.percent(2), CSS.percent(3)], expect: '1% 2% 3%' },
     701        { base: [CSS.percent(1), CSS.percent(2)], append: [CSS.percent(3)], expect: '1% 2% 3%' },
     702        { base: [CSS.percent(1)], append: [CSS.percent(2), '3%'], expect: '1% 2% 3%' },
     703        { base: [CSS.percent(1)], append: [CSS.percent(2), '3% 4%'], expect: '1% 2% 3% 4%' },
     704        { base: null, append: [CSS.percent(1), '2%'], expect: '1% 2%' },
     705    ],
     706});
     707
     708test_append({
     709    syntax: '<resolution>+',
     710    initialValue: '0dpi',
     711    values: [
     712        { base: [CSS.dpi(1)], append: [CSS.px(1)], expect: null },
     713        { base: [CSS.dpi(1)], append: [CSS.dpi(2), CSS.px(1)], expect: null },
     714        { base: [CSS.dpi(1)], append: [CSS.dpi(2), '1px'], expect: null },
     715        { base: [CSS.dpi(1)], append: [CSS.dpi(2), CSS.dpi(3)], expect: '1dpi 2dpi 3dpi' },
     716        { base: [CSS.dpi(1), CSS.dpi(2)], append: [CSS.dpi(3)], expect: '1dpi 2dpi 3dpi' },
     717        { base: [CSS.dpi(1)], append: [CSS.dpi(2), '3dpi'], expect: '1dpi 2dpi 3dpi' },
     718        { base: [CSS.dpi(1)], append: [CSS.dpi(2), '3dpi 4dpi'], expect: '1dpi 2dpi 3dpi 4dpi' },
     719        { base: null, append: [CSS.dpi(1), '2dpi'], expect: '1dpi 2dpi' },
     720    ],
     721});
     722
     723test_append({
     724    syntax: '<time>+',
     725    initialValue: '0s',
     726    values: [
     727        { base: [CSS.s(1)], append: [CSS.px(1)], expect: null },
     728        { base: [CSS.s(1)], append: [CSS.s(2), CSS.px(1)], expect: null },
     729        { base: [CSS.s(1)], append: [CSS.ms(2), '1px'], expect: null },
     730        { base: [CSS.s(1)], append: [CSS.ms(2), CSS.s(3)], expect: '1s 2ms 3s' },
     731        { base: [CSS.s(1), CSS.s(2)], append: [CSS.s(3)], expect: '1s 2s 3s' },
     732        { base: [CSS.s(1)], append: [CSS.s(2), '3s'], expect: '1s 2s 3s' },
     733        { base: [CSS.s(1)], append: [CSS.s(2), '3ms 4s'], expect: '1s 2s 3ms 4s' },
     734        { base: null, append: [CSS.s(1), '2s'], expect: '1s 2s' },
     735    ],
     736});
     737
     738test_append({
     739    syntax: 'foo+',
     740    initialValue: 'foo',
     741    values: [
     742        { base: [keyword('foo')], append: [CSS.px(1)], expect: null },
     743        { base: [keyword('foo')], append: [keyword('foo'), CSS.px(1)], expect: null },
     744        { base: [keyword('foo')], append: [keyword('foo'), '1px'], expect: null },
     745        { base: [keyword('foo')], append: [keyword('foo'), keyword('foo')], expect: 'foo foo foo' },
     746        { base: [keyword('foo'), keyword('foo')], append: [keyword('foo')], expect: 'foo foo foo' },
     747        { base: [keyword('foo')], append: [keyword('foo'), 'foo'], expect: 'foo foo foo' },
     748        { base: [keyword('foo')], append: [keyword('foo'), 'foo foo'], expect: 'foo foo foo foo' },
     749        { base: null, append: [keyword('foo'), keyword('foo')], expect: 'foo foo' },
     750    ],
    448751});
    449752
     
    538841}, 'CSSStyleValue.parse[All] returns list of CSSUnitValues for <length>#');
    539842
     843// Direct CSSStyleValue objects:
     844
     845function gen_all_props() {
     846    return [
     847        gen_prop('*', 'foo'),
     848        gen_prop('foo', 'foo'),
     849        gen_prop('<angle>', '0deg'),
     850        gen_prop('<color>', 'rgb(1, 2, 3)'),
     851        gen_prop('<custom-ident>', 'thing'),
     852        gen_prop('<image>', 'url(a)'),
     853        gen_prop('<integer>', '0'),
     854        gen_prop('<length-percentage>', 'calc(10px + 10%)'),
     855        gen_prop('<length>', '0px'),
     856        gen_prop('<number>', '0.5'),
     857        gen_prop('<percentage>', '0%'),
     858        gen_prop('<resolution>', '0dpi'),
     859        gen_prop('<time>', '0s'),
     860        gen_prop('<transform-function>', 'rotateX(0deg)'),
     861        gen_prop('<transform-list>', 'rotateX(0deg)'),
     862        gen_prop('<url>', 'url(a)')
     863    ];
     864}
     865
     866test(function(){
     867    let props0 = gen_all_props();
     868    let props1 = gen_all_props();
     869
     870    for (let i = 0; i < props0.length; i++) {
     871        let prop0 = props0[i];
     872        let prop1 = props1[i];
     873
     874        // Abuse computedStyleMap to get the initialValue (just to get some
     875        // value that will parse for prop0/1's syntax).
     876        let initialValue = target.computedStyleMap().get(prop0);
     877
     878        // We only care about direct CSSStyleValue instances in this test.
     879        // Ultimately, in some future version of CSS TypedOM, we may have no
     880        // direct CSSStyleValue instances at all, which is fine.
     881        if (initialValue.constructor !== CSSStyleValue) {
     882            continue;
     883        }
     884
     885        let value = CSSStyleValue.parse(prop0, initialValue.toString());
     886
     887        // A value parsed for prop0 must be assignable to prop0.
     888        target.attributeStyleMap.clear();
     889        target.attributeStyleMap.set(prop0, value); // Don't throw.
     890
     891        // A value parsed for prop0 must not be assignable to prop1, even if
     892        // the properties have compatible syntaxes.
     893        assert_throws(new TypeError(), () => {
     894            target.attributeStyleMap.clear();
     895            target.attributeStyleMap.set(prop1, value);
     896        });
     897    }
     898}, 'Direct CSSStyleValue instances are tied to their associated property');
     899
     900// StylePropertyMapReadOnly iteration
     901
     902test(function(){
     903    let name = gen_prop('<length>', '10px');
     904    let result = Array.from(target.computedStyleMap()).filter(e => e[0] == name)[0];
     905    assert_true(typeof(result) !== 'undefined');
     906}, 'Registered property with initial value show up on iteration of computedStyleMap');
     907
     908// Verifies that iterating a StylePropertyMap[ReadOnly] yields correctly
     909// typed objects for a given syntax/value.
     910function test_iteration_type_for_property_map(propertyMapName, propertyMap, options) {
     911    test(function(){
     912        let name = gen_prop(options.syntax, options.initialValue);
     913        if (propertyMap instanceof StylePropertyMap) {
     914            // Only set the value if the propertyMap is mutable.
     915            propertyMap.set(name, options.value);
     916        }
     917        let result = Array.from(propertyMap).filter(e => e[0] == name)[0];
     918        let value = result[1];
     919        assert_true(options.expect(value));
     920    }, `Iteration on ${propertyMapName} produces correct type for ${options.syntax}`);
     921}
     922
     923function test_iteration_type(options) {
     924    test_iteration_type_for_property_map('computedStyleMap', target.computedStyleMap(), options);
     925    test_iteration_type_for_property_map('attributeStyleMap', target.attributeStyleMap, options);
     926    test_iteration_type_for_property_map('styleMap', style.sheet.rules[0].styleMap, options);
     927}
     928
     929test_iteration_type({
     930    syntax: '*',
     931    initialValue: 'none',
     932    value: 'thing',
     933    expect: v => v.length == 1 && v[0] instanceof CSSUnparsedValue,
     934});
     935
     936test_iteration_type({
     937    syntax: '<angle>',
     938    initialValue: '0deg',
     939    value: '42deg',
     940    expect: v => v.length == 1 && v[0] instanceof CSSUnitValue,
     941});
     942
     943test_iteration_type({
     944    syntax: '<custom-ident>',
     945    initialValue: 'none',
     946    value: 'thing',
     947    expect: v => v.length == 1 && v[0] instanceof CSSKeywordValue,
     948});
     949
     950test_iteration_type({
     951    syntax: '<image>',
     952    initialValue: 'url(a)',
     953    value: 'url(b)',
     954    expect: v => v.length == 1 && v[0] instanceof CSSImageValue,
     955});
     956
     957test_iteration_type({
     958    syntax: '<integer>',
     959    initialValue: '0',
     960    value: '100',
     961    expect: v => v.length == 1 && v[0] instanceof CSSUnitValue,
     962});
     963
     964test_iteration_type({
     965    syntax: '<length>',
     966    initialValue: '0px',
     967    value: '10px',
     968    expect: v => v.length == 1 && v[0] instanceof CSSUnitValue,
     969});
     970
     971test_iteration_type({
     972    syntax: '<number>',
     973    initialValue: '0',
     974    value: '42',
     975    expect: v => v.length == 1 && v[0] instanceof CSSUnitValue,
     976});
     977
     978test_iteration_type({
     979    syntax: '<percentage>',
     980    initialValue: '0%',
     981    value: '10%',
     982    expect: v => v.length == 1 && v[0] instanceof CSSUnitValue,
     983});
     984
     985test_iteration_type({
     986    syntax: '<resolution>',
     987    initialValue: '0dpi',
     988    value: '300dpi',
     989    expect: v => v.length == 1 && v[0] instanceof CSSUnitValue,
     990});
     991
     992test_iteration_type({
     993    syntax: '<time>',
     994    initialValue: '0s',
     995    value: '10s',
     996    expect: v => v.length == 1 && v[0] instanceof CSSUnitValue,
     997});
     998
     999test_iteration_type({
     1000    syntax: '<url>',
     1001    initialValue: 'url(a)',
     1002    value: 'url(b)',
     1003    expect: v => v.length == 1 && v[0].constructor === CSSStyleValue,
     1004});
     1005
     1006test_iteration_type({
     1007    syntax: 'none | thing | THING',
     1008    initialValue: 'none',
     1009    value: 'THING',
     1010    expect: v => v.length == 1 && v[0] instanceof CSSKeywordValue,
     1011});
     1012
     1013test_iteration_type({
     1014    syntax: '<angle> | <length>',
     1015    initialValue: '0deg',
     1016    value: '10px',
     1017    expect: v => v.length == 1 && v[0] instanceof CSSUnitValue,
     1018});
     1019
    5401020</script>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/unit-cycles-expected.txt

    r239341 r239365  
    1 CONSOLE MESSAGE: line 63: TypeError: element.attributeStyleMap.clear is not a function. (In 'element.attributeStyleMap.clear()', 'element.attributeStyleMap.clear' is undefined)
     1CONSOLE MESSAGE: line 74: TypeError: element.attributeStyleMap.clear is not a function. (In 'element.attributeStyleMap.clear()', 'element.attributeStyleMap.clear' is undefined)
    22
    33FAIL Untitled TypeError: element.attributeStyleMap.clear is not a function. (In 'element.attributeStyleMap.clear()', 'element.attributeStyleMap.clear' is undefined)
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/unit-cycles.html

    r236444 r239365  
    55<script src="/resources/testharnessreport.js"></script>
    66<script>
    7     function register_length(name) {
     7    function register_length(name, inherits=true) {
    88        CSS.registerProperty({
    99            name: name,
    1010            syntax: '<length>',
    1111            initialValue: '0px',
    12             inherits: false
     12            inherits: inherits
    1313        });
    1414    }
     
    2323    register_length('--font-size-ex-via-var');
    2424    register_length('--font-size-ch-via-var');
     25    register_length('--font-size-em-inherited', true);
     26    register_length('--font-size-ex-inherited', true);
     27    register_length('--font-size-ch-inherited', true);
    2528</script>
    2629<style>
     
    4447    }
    4548
     49    #parent {
     50        --font-size-em-inherited: 4em;
     51        --font-size-ex-inherited: 4ex;
     52        --font-size-ch-inherited: 4ch;
     53    }
     54
    4655    #target {
    4756        font-size: 11px;
     
    4958</style>
    5059
    51 <div id=target></div>
     60<div id=parent>
     61    <div id=target></div>
     62</div>
    5263<div id=ref></div>
    5364
     
    171182    }, 'Lengths with rem units are detected via var references');
    172183
     184    test(function() {
     185        let expected4em = compute_dimension('4em', 'unset');
     186        target.style = 'font-size: var(--font-size-em-inherited);';
     187        assert_property_equals('font-size', expected4em);
     188        assert_property_equals('--font-size-em-inherited', expected4em);
     189    }, 'Inherited lengths with em units may be used');
     190
     191    test(function() {
     192        let expected4ex = compute_dimension('4ex', 'unset');
     193        target.style = 'font-size: var(--font-size-ex-inherited);';
     194        assert_property_equals('font-size', expected4ex);
     195        assert_property_equals('--font-size-ex-inherited', expected4ex);
     196    }, 'Inherited lengths with ex units may be used');
     197
     198    test(function() {
     199        let expected4ch = compute_dimension('4ch', 'unset');
     200        target.style = 'font-size: var(--font-size-ch-inherited);';
     201        assert_property_equals('font-size', expected4ch);
     202        assert_property_equals('--font-size-ch-inherited', expected4ch);
     203    }, 'Inherited lengths with ch units may be used');
     204
    173205</script>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/var-reference-registered-properties-cycles.html

    r236444 r239365  
    2626
    2727    computedStyle = getComputedStyle(test1);
    28     assert_equals(computedStyle.getPropertyValue('--registered-1-a'), '1px');
    29     assert_equals(computedStyle.getPropertyValue('--registered-1-b'), '2px');
    30 
    31     assert_equals(computedStyle.getPropertyValue('--registered-1-c'), '2px');
    32     assert_equals(computedStyle.getPropertyValue('--registered-1-d'), '2px');
    33     assert_equals(computedStyle.getPropertyValue('--unregistered-1-a'), '1px');
    34     assert_equals(computedStyle.left, '1px');
    35     assert_equals(computedStyle.top, '2px');
     28    assert_equals(computedStyle.getPropertyValue('--registered-1-a'), '');
     29    assert_equals(computedStyle.getPropertyValue('--registered-1-b'), '');
     30    assert_equals(computedStyle.getPropertyValue('--registered-1-c'), '30px');
     31    assert_equals(computedStyle.getPropertyValue('--registered-1-d'), '4px');
     32    assert_equals(computedStyle.getPropertyValue('--unregistered-1-a'), '');
     33    assert_equals(computedStyle.left, '50px');
     34    assert_equals(computedStyle.top, '60px');
    3635}, "A var() cycle between two registered properties is handled correctly.");
    3736</script>
     
    6463
    6564    computedStyle = getComputedStyle(test2);
    66     assert_equals(computedStyle.getPropertyValue('--registered-2-a'), '1px');
     65    assert_equals(computedStyle.getPropertyValue('--registered-2-a'), '');
    6766    assert_equals(computedStyle.getPropertyValue('--unregistered-2-a'), '');
    6867
    69     assert_equals(computedStyle.getPropertyValue('--registered-2-b'), '1px');
    70     assert_equals(computedStyle.getPropertyValue('--registered-2-c'), '1px');
     68    assert_equals(computedStyle.getPropertyValue('--registered-2-b'), '30px');
     69    assert_equals(computedStyle.getPropertyValue('--registered-2-c'), '3px');
    7170    assert_equals(computedStyle.getPropertyValue('--registered-2-d'), '40px');
    7271    assert_equals(computedStyle.getPropertyValue('--registered-2-e'), '5px');
    73     assert_equals(computedStyle.getPropertyValue('--unregistered-2-b'), '1px');
    74     assert_equals(computedStyle.getPropertyValue('--unregistered-2-c'), '1px');
     72    assert_equals(computedStyle.getPropertyValue('--unregistered-2-b'), '50px');
     73    assert_equals(computedStyle.getPropertyValue('--unregistered-2-c'), '');
    7574    assert_equals(computedStyle.getPropertyValue('--unregistered-2-d'), '60px');
    7675    assert_equals(computedStyle.getPropertyValue('--unregistered-2-e'), '');
    77     assert_equals(computedStyle.left, '1px');
     76    assert_equals(computedStyle.left, '70px');
    7877    assert_equals(computedStyle.top, '80px');
    7978}, "A var() cycle between a registered properties and an unregistered property is handled correctly.");
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/var-reference-registered-properties-expected.txt

    r237697 r239365  
    11
    2 FAIL var() references work with registered properties assert_equals: expected "  10px" but got " 10px"
     2PASS var() references work with registered properties
    33FAIL References to registered var()-properties work in registered lists assert_equals: expected "1px, 10px, 2px" but got "0px"
    44FAIL References to mixed registered and unregistered var()-properties work in registered lists assert_equals: expected "1px, 20px, 10px, 2px" but got "0px"
    55FAIL Registered lists may be concatenated assert_equals: expected "1px, 10px, 2px, 1px, 20px, 10px, 2px" but got "0px"
     6PASS Font-relative units are absolutized when substituting
     7PASS Calc expressions are resolved when substituting
     8FAIL Lists with relative units are absolutized when substituting assert_equals: expected "110px, 120px" but got "0px"
     9PASS Valid fallback does not invalidate var()-reference [<length>, 10px]
     10PASS Valid fallback does not invalidate var()-reference [<length> | <color>, red]
     11PASS Valid fallback does not invalidate var()-reference [<length> | none, none]
     12FAIL Invalid fallback invalidates var()-reference [<length>, red] assert_equals: expected "" but got "40px"
     13FAIL Invalid fallback invalidates var()-reference [<length> | none, nolength] assert_equals: expected "" but got "40px"
     14FAIL Invalid fallback invalidates var()-reference [<length>, var(--novar)] assert_equals: expected "" but got "40px"
    615
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/var-reference-registered-properties.html

    r236444 r239365  
    33<script src="/resources/testharness.js"></script>
    44<script src="/resources/testharnessreport.js"></script>
     5<script src="./resources/utils.js"></script>
    56<style>
    67div {
     
    5556    assert_equals(computedStyle.getPropertyValue('--registered-length-7'), '123px');
    5657    assert_equals(computedStyle.getPropertyValue('--length-1'), ' 20px');
    57     assert_equals(computedStyle.getPropertyValue('--length-2'), '  10px');
     58    assert_equals(computedStyle.getPropertyValue('--length-2'), ' 10px');
    5859    assert_equals(computedStyle.getPropertyValue('--length-3'), ' calc(123px + 123px)');
    5960    assert_equals(computedStyle.getPropertyValue('--registered-length-invalid'), '15px');
     
    9798}, 'Registered lists may be concatenated');
    9899
     100test(function(){
     101    CSS.registerProperty({
     102        name: '--length-em',
     103        syntax: '<length>',
     104        initialValue: '0px',
     105        inherits: false
     106    });
     107    element.style = 'font-size: 11px; --length-em: 10em; --unregistered:var(--length-em);';
     108    let computedStyle = getComputedStyle(element);
     109    assert_equals(computedStyle.getPropertyValue('--unregistered'), '110px');
     110    element.style = '';
     111}, 'Font-relative units are absolutized when substituting');
     112
     113test(function(){
     114    CSS.registerProperty({
     115        name: '--length-calc',
     116        syntax: '<length>',
     117        initialValue: '0px',
     118        inherits: false
     119    });
     120    element.style = 'font-size: 11px; --length-calc: calc(10em + 10px); --unregistered:var(--length-calc);';
     121    let computedStyle = getComputedStyle(element);
     122    assert_equals(computedStyle.getPropertyValue('--unregistered'), '120px');
     123    element.style = '';
     124}, 'Calc expressions are resolved when substituting');
     125
     126test(function(){
     127    CSS.registerProperty({
     128        name: '--length-calc-list',
     129        syntax: '<length>#',
     130        initialValue: '0px',
     131        inherits: false
     132    });
     133    element.style = 'font-size: 11px; --length-calc-list: 10em, calc(10em + 10px); --unregistered:var(--length-calc-list);';
     134    let computedStyle = getComputedStyle(element);
     135    assert_equals(computedStyle.getPropertyValue('--unregistered'), '110px, 120px');
     136    element.style = '';
     137}, 'Lists with relative units are absolutized when substituting');
     138
     139function test_valid_fallback(syntax, value, fallback) {
     140    test(function(){
     141        let name = generate_property(syntax);
     142        try {
     143            element.style = `${name}: ${value}; --x:var(${name},${fallback})`;
     144            let computedStyle = getComputedStyle(element);
     145            assert_equals(computedStyle.getPropertyValue('--x'), value);
     146        } finally {
     147            element.style = '';
     148        }
     149    }, `Valid fallback does not invalidate var()-reference [${syntax}, ${fallback}]`);
     150}
     151
     152function test_invalid_fallback(syntax, value, fallback) {
     153    test(function(){
     154        let name = generate_property(syntax);
     155        try {
     156            element.style = `${name}: ${value}; --x:var(${name},${fallback})`;
     157            let computedStyle = getComputedStyle(element);
     158            assert_equals(computedStyle.getPropertyValue('--x'), '');
     159        } finally {
     160            element.style = '';
     161        }
     162    }, `Invalid fallback invalidates var()-reference [${syntax}, ${fallback}]`);
     163}
     164
     165test_valid_fallback('<length>', '40px', '10px');
     166test_valid_fallback('<length> | <color>', '40px', 'red');
     167test_valid_fallback('<length> | none', '40px', 'none');
     168
     169test_invalid_fallback('<length>', '40px', 'red');
     170test_invalid_fallback('<length> | none', '40px', 'nolength');
     171test_invalid_fallback('<length>', '40px', 'var(--novar)');
    99172
    100173</script>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/w3c-import.log

    r236444 r239365  
    2424/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-cssom.html
    2525/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-initial.html
     26/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/self-utils.html
    2627/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/typedom.tentative.html
    2728/LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/unit-cycles.html
  • trunk/Source/WebCore/ChangeLog

    r239361 r239365  
     12018-12-18  Justin Michaud  <justin_michaud@apple.com>
     2
     3        Update CSS Properties and Values API to use new cycle fallback behaviour
     4        https://bugs.webkit.org/show_bug.cgi?id=192800
     5
     6        Reviewed by Antti Koivisto.
     7
     8        Make CSS variables that are registered and involved in a cycle be treated as invalid. This also fixes a crash in the
     9        wpt tests where relative units and calc() in a registered property's initial value would break things instead of failing.
     10
     11        * css/CSSCustomPropertyValue.h:
     12        * css/CSSVariableReferenceValue.cpp:
     13        (WebCore::resolveVariableReference):
     14        * css/DOMCSSRegisterCustomProperty.cpp:
     15        (WebCore::DOMCSSRegisterCustomProperty::registerProperty):
     16        * css/StyleResolver.cpp:
     17        (WebCore::StyleResolver::applyCascadedCustomProperty):
     18        * css/parser/CSSPropertyParser.cpp:
     19        (WebCore::CSSPropertyParser::parseTypedCustomPropertyValue):
     20
    1212018-12-18  Daniel Bates  <dabates@apple.com>
    222
  • trunk/Source/WebCore/css/CSSCustomPropertyValue.h

    r238872 r239365  
    6868    static Ref<CSSCustomPropertyValue> createSyntaxLength(const AtomicString& name, Length value)
    6969    {
     70        ASSERT(!value.isUndefined());
     71        ASSERT(!value.isCalculated());
    7072        return adoptRef(*new CSSCustomPropertyValue(name, { WTFMove(value) }));
    7173    }
  • trunk/Source/WebCore/css/CSSVariableReferenceValue.cpp

    r237697 r239365  
    7171    // Apply fallback to detect cycles
    7272    Vector<CSSParserToken> fallbackResult;
    73     resolveVariableFallback(CSSParserTokenRange(range), fallbackResult, state);
     73    bool fallbackReturn = resolveVariableFallback(CSSParserTokenRange(range), fallbackResult, state);
    7474
    7575    auto* property = style.getCustomProperty(variableName);
    7676
    77     if (!property || property->isUnset() || property->isInvalid()) {
     77    if (!property || property->isUnset()) {
    7878        auto* registered = registeredProperties.get(variableName);
    7979        if (registered && registered->initialValue())
    8080            property = registered->initialValue();
    81         else
    82             return resolveVariableFallback(range, result, state);
     81    }
     82
     83    if (!property || property->isInvalid()) {
     84        if (fallbackReturn)
     85            result.appendVector(fallbackResult);
     86        return fallbackReturn;
    8387    }
    8488
  • trunk/Source/WebCore/css/DOMCSSRegisterCustomProperty.cpp

    r237697 r239365  
    4141ExceptionOr<void> DOMCSSRegisterCustomProperty::registerProperty(Document& document, const DOMCSSCustomPropertyDescriptor& descriptor)
    4242{
     43    if (!isCustomPropertyName(descriptor.name))
     44        return Exception { SyntaxError, "The name of this property is not a custom property name." };
     45
    4346    RefPtr<CSSCustomPropertyValue> initialValue;
    4447    if (!descriptor.initialValue.isEmpty()) {
     
    5154        styleResolver.updateFont();
    5255
     56        HashSet<CSSPropertyID> dependencies;
     57        CSSPropertyParser::collectParsedCustomPropertyValueDependencies(descriptor.syntax, false, dependencies, tokenizer.tokenRange(), strictCSSParserContext());
     58
     59        if (!dependencies.isEmpty())
     60            return Exception { SyntaxError, "The given initial value must be computationally independent." };
     61
    5362        initialValue = CSSPropertyParser::parseTypedCustomPropertyValue(descriptor.name, descriptor.syntax, tokenizer.tokenRange(), styleResolver, strictCSSParserContext());
    5463
     
    5665            return Exception { SyntaxError, "The given initial value does not parse for the given syntax." };
    5766
    58         HashSet<CSSPropertyID> dependencies;
    5967        initialValue->collectDirectComputationalDependencies(dependencies);
    6068        initialValue->collectDirectRootComputationalDependencies(dependencies);
  • trunk/Source/WebCore/css/StyleResolver.cpp

    r239173 r239365  
    23202320
    23212321    auto property = state.cascade->customProperties().get(name);
     2322    bool inCycle = state.inProgressPropertiesCustom.contains(name);
    23222323
    23232324    for (auto index : { SelectorChecker::MatchDefault, SelectorChecker::MatchLink, SelectorChecker::MatchVisited }) {
     
    23292330        Ref<CSSCustomPropertyValue> valueToApply = CSSCustomPropertyValue::create(downcast<CSSCustomPropertyValue>(*property.cssValue[index]));
    23302331
    2331         if (state.inProgressPropertiesCustom.contains(name)) {
    2332             // We are in a cycle, so reset the value.
    2333             state.appliedCustomProperties.add(name);
    2334             // Resolve this value so that we reset its dependencies
    2335             if (WTF::holds_alternative<Ref<CSSVariableReferenceValue>>(valueToApply->value()))
    2336                 resolvedVariableValue(CSSPropertyCustom, valueToApply.get(), state);
    2337             valueToApply = CSSCustomPropertyValue::createWithID(name, CSSValueUnset);
     2332        if (inCycle) {
     2333            state.appliedCustomProperties.add(name); // Make sure we do not try to apply this property again while resolving it.
     2334            valueToApply = CSSCustomPropertyValue::createWithID(name, CSSValueInvalid);
    23382335        }
    23392336
     
    23422339        if (WTF::holds_alternative<Ref<CSSVariableReferenceValue>>(valueToApply->value())) {
    23432340            RefPtr<CSSValue> parsedValue = resolvedVariableValue(CSSPropertyCustom, valueToApply.get(), state);
     2341
     2342            if (state.appliedCustomProperties.contains(name))
     2343                return; // There was a cycle and the value was reset, so bail.
    23442344
    23452345            if (!parsedValue)
     
    23662366            applyProperty(CSSPropertyCustom, valueToApply.ptr(), state, index);
    23672367        }
    2368         state.inProgressPropertiesCustom.remove(name);
    2369         state.appliedCustomProperties.add(name);
     2368    }
     2369
     2370    state.inProgressPropertiesCustom.remove(name);
     2371    state.appliedCustomProperties.add(name);
     2372
     2373    for (auto index : { SelectorChecker::MatchDefault, SelectorChecker::MatchLink, SelectorChecker::MatchVisited }) {
     2374        if (!property.cssValue[index])
     2375            continue;
     2376        if (index != SelectorChecker::MatchDefault && this->state().style()->insideLink() == InsideLink::NotInside)
     2377            continue;
     2378
     2379        Ref<CSSCustomPropertyValue> valueToApply = CSSCustomPropertyValue::create(downcast<CSSCustomPropertyValue>(*property.cssValue[index]));
     2380
     2381        if (inCycle && WTF::holds_alternative<Ref<CSSVariableReferenceValue>>(valueToApply->value())) {
     2382            // Resolve this value so that we reset its dependencies.
     2383            resolvedVariableValue(CSSPropertyCustom, valueToApply.get(), state);
     2384        }
    23702385    }
    23712386}
  • trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp

    r238698 r239365  
    43944394        m_range.consumeWhitespace();
    43954395        auto primitiveVal = consumeWidthOrHeight(m_range, m_context);
    4396         if (primitiveVal && primitiveVal->isPrimitiveValue())
    4397             return CSSCustomPropertyValue::createSyntaxLength(name, StyleBuilderConverter::convertLength(styleResolver, *primitiveVal));
     4396        if (primitiveVal && primitiveVal->isPrimitiveValue() && downcast<CSSPrimitiveValue>(*primitiveVal).isLength()) {
     4397            auto length = StyleBuilderConverter::convertLength(styleResolver, *primitiveVal);
     4398            if (!length.isCalculated() && !length.isUndefined())
     4399                return CSSCustomPropertyValue::createSyntaxLength(name, WTFMove(length));
     4400        }
    43984401    } else {
    43994402        auto propertyValue = CSSCustomPropertyValue::createSyntaxAll(name, CSSVariableData::create(m_range));
Note: See TracChangeset for help on using the changeset viewer.