Bug 1483570 [wpt PR 12503] - [css-properties-values-api] Support CSSStyleValues in StylePropertyMap.set., a=testonly
authorAnders Hartvoll Ruud <andruud@chromium.org>
Mon, 20 Aug 2018 22:08:38 +0000
changeset 487794 3166f55901c15bab16166a1daa2ebe09c4395311
parent 487793 2dcc5b1e23dde5ef5ed30c1f38e40b149aa00744
child 487795 d07641a80a1f4d91a8f85f1acd2e0366197bc620
push id9719
push userffxbld-merge
push dateFri, 24 Aug 2018 17:49:46 +0000
treeherdermozilla-beta@719ec98fba77 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1483570, 12503, 641877, 1175822, 583695
milestone63.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1483570 [wpt PR 12503] - [css-properties-values-api] Support CSSStyleValues in StylePropertyMap.set., a=testonly Automatic update from web-platform-tests[css-properties-values-api] Support CSSStyleValues in StylePropertyMap.set. In StyleValueToCSSValue, when checking whether a certain CSSStyleValue matches the property in question, we now ask the registration (via CSSOMTypes) if the CSSStyleValue matches. If it doesn't match, we throw a TypeError like for normal properties. If it does match, the CSSStyleValue is stringified, tokenized, and set on the style rule as tokens. I have postponed support for <color> and <transform-function>, because CSSUnsupportedStyleValue currently does not handle registered custom properties at all. This is appropriate to fix in a separate CL. Note that, because the string version of StylePropertyMap.set also uses StyleValueToCSSValue, it will no longer be possible to set registered custom properties with a string--even if the syntax is matched. A subsequent CL will fix this. R=futhark@chromium.org Bug: 641877 Change-Id: Ie0cc2f87e39f8f59015824bfd1b81efaf402c326 Reviewed-on: https://chromium-review.googlesource.com/1175822 Commit-Queue: Anders Ruud <andruud@chromium.org> Reviewed-by: Rune Lillesveen <futhark@chromium.org> Cr-Commit-Position: refs/heads/master@{#583695} -- wpt-commits: 218a15f938b8612bac6a74baa8cccdaf53d57221 wpt-pr: 12503
testing/web-platform/meta/MANIFEST.json
testing/web-platform/tests/css/css-properties-values-api/typedom.tentative.html
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -539983,17 +539983,17 @@
    "169ed7b53c16a145df8598e0888e1271d288d5c7",
    "support"
   ],
   "css/css-properties-values-api/support/main/main.utf16be.css": [
    "26485da32b751b8c66191f3e64814051bd91c284",
    "support"
   ],
   "css/css-properties-values-api/typedom.tentative.html": [
-   "065280614cca9fa52b79c28e253c30ada188a1b9",
+   "69ebf7a13d8cf3d71413259db68336368e5032e7",
    "testharness"
   ],
   "css/css-properties-values-api/unit-cycles.html": [
    "c242640f2b93e7820b9d016b53f5f2279ec18eca",
    "testharness"
   ],
   "css/css-properties-values-api/url-resolution.html": [
    "6e7c008a58c311aeb18e89edd4dd29e8a3e6c1ed",
--- a/testing/web-platform/tests/css/css-properties-values-api/typedom.tentative.html
+++ b/testing/web-platform/tests/css/css-properties-values-api/typedom.tentative.html
@@ -1,16 +1,18 @@
 <!DOCTYPE html>
 <link rel="author" title="Anders Hartvoll Ruud" href="andruud@chromium.org">
 <!-- TODO(andruud): Add Typed OM details to spec and link to it here. -->
-<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api-1/#supported-syntax-strings" />
+<link rel="help" href="https://github.com/w3c/css-houdini-drafts/pull/783" />
 <meta name="assert" content="Verifies that registered custom properties interact correctly with CSS Typed OM" />
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-
+<style id=style>
+    div {}
+</style>
 <div id=target></div>
 
 <script>
 
 // Properties are generated on demand, as `--prop-${g_counter}`.
 let g_counter = 1;
 
 // Generate a new property name.
@@ -38,26 +40,26 @@ function gen_prop(syntax, initialValue) 
 // If 'value' is non-null, that value is first set on the attributeStyleMap
 // of the target.
 function assert_computed_type(name, value, expected) {
     if (expected == CSSUnparsedValue) {
         throw 'CSSUnparsedValue may not be used as expected type';
     }
 
     if (value != null) {
-        target.attributeStyleMap.set(name, value);
+        target.style = `${name}: ${value}`;
     }
 
     let computedValue = target.computedStyleMap().get(name);
 
     assert_false(computedValue instanceof CSSUnparsedValue);
     assert_true(computedValue instanceof expected);
 
     if (value != null) {
-        target.attributeStyleMap.delete(name);
+        target.style = '';
     }
 }
 
 function assert_attribute_get_type(syntax, value, expected) {
     let name = gen_name();
     target.style = `${name}: ${value}`;
 
     assert_true(target.attributeStyleMap.get(name) instanceof CSSUnparsedValue);
@@ -172,27 +174,27 @@ test(function(){
     assert_computed_type(gen_prop('<length>#', '0px, 0px'), '10px, 20px', CSSUnitValue);
 }, 'First computed value correctly reified in comma-separated list');
 
 test(function(){
     let name = gen_prop('<length>+', '10px 20px');
     assert_equals(target.computedStyleMap().getAll(name).length, 2);
     assert_true(target.computedStyleMap().getAll(name).every(x => x instanceof CSSUnitValue));
 
-    target.attributeStyleMap.set(name, '10px 20px 30px');
+    target.style = `${name}: 10px 20px 30px`;
     assert_equals(target.computedStyleMap().getAll(name).length, 3);
     assert_true(target.computedStyleMap().getAll(name).every(x => x instanceof CSSUnitValue));
 }, 'All computed values correctly reified in space-separated list');
 
 test(function(){
     let name = gen_prop('<length>#', '10px, 20px');
     assert_equals(target.computedStyleMap().getAll(name).length, 2);
     assert_true(target.computedStyleMap().getAll(name).every(x => x instanceof CSSUnitValue));
 
-    target.attributeStyleMap.set(name, '10px, 20px, 30px');
+    target.style = `${name}: 10px, 20px, 30px`;
     assert_equals(target.computedStyleMap().getAll(name).length, 3);
     assert_true(target.computedStyleMap().getAll(name).every(x => x instanceof CSSUnitValue));
 }, 'All computed values correctly reified in comma-separated list');
 
 // attributeStyleMap.get
 
 test(function(){
     let name1 = gen_prop('<length>', '100px');
@@ -280,22 +282,158 @@ test(function(){
     assert_attribute_get_type('<length>#', '10px 20px', CSSUnitValue);
 }, 'attributeStyleMap.get returns CSSUnitValue for <length>#');
 
 // attributeStyleMap.getAll
 
 test(function(){
     let name = gen_prop('<length>+', '0px');
     target.attributeStyleMap.clear();
-    target.attributeStyleMap.set(name, '10px 20px 30px');
+    target.style = `${name}: 10px 20px 30px`;
     assert_equals(target.attributeStyleMap.getAll(name).length, 3);
     assert_true(target.attributeStyleMap.getAll(name).every(x => x instanceof CSSUnitValue));
 }, 'attributeStyleMap.getAll returns a list of CSSUnitValues for <length>+');
 
 test(function(){
     let name = gen_prop('<length>#', '0px');
     target.attributeStyleMap.clear();
-    target.attributeStyleMap.set(name, '10px, 20px, 30px');
+    target.style = `${name}: 10px, 20px, 30px`;
     assert_equals(target.attributeStyleMap.getAll(name).length, 3);
     assert_true(target.attributeStyleMap.getAll(name).every(x => x instanceof CSSUnitValue));
 }, 'attributeStyleMap.getAll returns a list of CSSUnitValues for <length>#');
 
+// StylePropertyMap.set
+
+function test_style_property_map_set_using_property_map(propertyMapName, propertyMap, options) {
+    test(function(){
+        let name = gen_prop(options.syntax, options.initialValue);
+        propertyMap.clear();
+
+        for (let value of options.shouldAccept)
+            propertyMap.set(name, value);
+
+        for (let value of options.shouldReject) {
+            assert_throws(new TypeError(), () => propertyMap.set(name, value));
+        }
+    }, `${propertyMapName}.set accepts correct CSSUnitValues for ${options.syntax}`);
+}
+
+// Verify that the correct CSSStyleValues are accepted/rejected for a registered
+// property with the specified syntax.
+//
+// The same test is performed twice: once for attributeStyleMap, and once
+// for styleMap.
+function test_style_property_map_set(options) {
+    test_style_property_map_set_using_property_map('attributeStyleMap', target.attributeStyleMap, options);
+    test_style_property_map_set_using_property_map('styleMap', style.sheet.rules[0].styleMap, options);
+}
+
+let unparsed = x => new CSSUnparsedValue([x]);
+let keyword = x => new CSSKeywordValue(x);
+let sum = (a, b) => new CSSMathSum(a, b);
+let url_image = x => CSSStyleValue.parse('background-image', x);
+
+test_style_property_map_set({
+    syntax: '*',
+    initialValue: 'none',
+    shouldAccept: [unparsed('thing')],
+    shouldReject: [CSS.px(15), keyword('none')],
+});
+
+test_style_property_map_set({
+    syntax: '<angle>',
+    initialValue: '0deg',
+    shouldAccept: [CSS.deg(42), CSS.turn(2)],
+    shouldReject: [unparsed('42deg'), CSS.px(15)],
+});
+
+test_style_property_map_set({
+    syntax: '<custom-ident>',
+    initialValue: 'none',
+    shouldAccept: [keyword('foo')],
+    shouldReject: [unparsed('foo'), CSS.px(15)],
+});
+
+test_style_property_map_set({
+    syntax: '<image>',
+    initialValue: 'url(a)',
+    shouldAccept: [url_image('url(b)')],
+    shouldReject: [unparsed('url(b)'), CSS.px(100)],
+});
+
+test_style_property_map_set({
+    syntax: '<integer>',
+    initialValue: '0',
+    shouldAccept: [CSS.number(1), CSS.number(-42)],
+    shouldReject: [unparsed('42'), CSS.px(100)],
+});
+
+test_style_property_map_set({
+    syntax: '<length-percentage>',
+    initialValue: '0px',
+    shouldAccept: [CSS.percent(10), CSS.px(1), CSS.em(1)],
+    shouldReject: [unparsed('10%'), unparsed('10px'), CSS.dpi(1)],
+});
+
+test_style_property_map_set({
+    syntax: '<length>',
+    initialValue: '0px',
+    shouldAccept: [CSS.px(10), CSS.em(10), CSS.vh(200), sum(CSS.px(10), CSS.em(20))],
+    shouldReject: [unparsed('10px'), CSS.percent(1)],
+});
+
+test_style_property_map_set({
+    syntax: '<number>',
+    initialValue: '0',
+    shouldAccept: [CSS.number(1337), CSS.number(-42.5)],
+    shouldReject: [unparsed('42'), CSS.px(15)],
+});
+
+test_style_property_map_set({
+    syntax: '<percentage>',
+    initialValue: '0%',
+    shouldAccept: [CSS.percent(10)],
+    shouldReject: [unparsed('10%'), CSS.px(1)],
+});
+
+test_style_property_map_set({
+    syntax: '<resolution>',
+    initialValue: '0dpi',
+    shouldAccept: [CSS.dpi(100), CSS.dpcm(10), CSS.dppx(50)],
+    shouldReject: [unparsed('42'), CSS.px(15)],
+});
+
+test_style_property_map_set({
+    syntax: '<time>',
+    initialValue: '0s',
+    shouldAccept: [CSS.s(42), CSS.ms(16)],
+    shouldReject: [unparsed('42s'), CSS.px(15)],
+});
+
+test_style_property_map_set({
+    syntax: '<url>',
+    initialValue: 'url(a)',
+    shouldAccept: [url_image('url(b)')],
+    shouldReject: [unparsed('url(b)'), CSS.px(100)],
+});
+
+test_style_property_map_set({
+    syntax: '<transform-list>',
+    initialValue: 'translateX(0px)',
+    shouldAccept: [CSSStyleValue.parse('transform', 'translateX(10px)')],
+    shouldReject: [unparsed('transformX(10px'), CSS.px(100)],
+});
+
+test_style_property_map_set({
+    syntax: 'none | thing | THING',
+    initialValue: 'none',
+    shouldAccept: [keyword('thing'), keyword('THING')],
+    shouldReject: [unparsed('thing'), CSS.px(15), keyword('notathing')],
+});
+
+test_style_property_map_set({
+    syntax: '<angle> | <length>',
+    initialValue: '0deg',
+    shouldAccept: [CSS.deg(42), CSS.turn(2), CSS.px(10), CSS.em(10)],
+    shouldReject: [unparsed('42deg'), unparsed('20px'), CSS.s(1)],
+});
+
 </script>