Bug 1484154 [wpt PR 12544] - Support CSSStyleValues in StylePropertyMap.set. (Reland), a=testonly
authorAnders Hartvoll Ruud <andruud@chromium.org>
Mon, 20 Aug 2018 22:11:18 +0000
changeset 487806 0131ba65ffa252c739de0a8bb55fe5dc282eaf02
parent 487805 b7174f9d6e6437c09f9b70c2d89a980034db11b8
child 487807 d7b6d67aaf7cfef54c46e9d1c80872e9dd1b2da7
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
bugs1484154, 12544, 641877, 1179153, 584024
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 1484154 [wpt PR 12544] - Support CSSStyleValues in StylePropertyMap.set. (Reland), a=testonly Automatic update from web-platform-testsSupport CSSStyleValues in StylePropertyMap.set. (Reland) 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: Ib5c31640f81e957620339c9bdf617ab1af5d3d47 Reviewed-on: https://chromium-review.googlesource.com/1179153 Reviewed-by: Rune Lillesveen <futhark@chromium.org> Commit-Queue: Anders Ruud <andruud@chromium.org> Cr-Commit-Position: refs/heads/master@{#584024} -- wpt-commits: b6f1c190818648dc0c33eb7ada54bf3f209fc938 wpt-pr: 12544
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
@@ -540075,17 +540075,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>