[css-typed-om] Rejig CSSResourceValue hierarchy.
We implement the new CSSImageValue, which is an opaque object with no
constructor. We also had to change the testsuite.js a bit to test it.
Bug: 545318
Change-Id: I0ae719c5380e01ff9423e0ff0684afe547de1bb0
Reviewed-on: https://chromium-review.googlesource.com/934001
Commit-Queue: Darren Shen <shend@chromium.org>
Reviewed-by: nainar <nainar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#538730}
diff --git a/css/css-typed-om/resources/testhelper.js b/css/css-typed-om/resources/testhelper.js
index 91af64c..cae0e27 100644
--- a/css/css-typed-om/resources/testhelper.js
+++ b/css/css-typed-om/resources/testhelper.js
@@ -66,12 +66,6 @@
case 'CSSMatrixComponent':
assert_matrix_approx_equals(a.matrix, b.matrix, 1e-6);
break;
- case 'CSSURLImageValue':
- assert_equals(a.instrinsicWidth, b.instrinsicWidth);
- assert_equals(a.instrinsicHeight, b.instrinsicHeight);
- assert_equals(a.instrinsicRatio, b.instrinsicRatio);
- assert_equals(a.url, b.url);
- break;
default:
assert_equals(a, b);
break;
diff --git a/css/css-typed-om/stylevalue-normalization/normalize-image.html b/css/css-typed-om/stylevalue-normalization/normalize-image.html
new file mode 100644
index 0000000..0b60ec4
--- /dev/null
+++ b/css/css-typed-om/stylevalue-normalization/normalize-image.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSSImageValue normalization tests</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#resourcevalue-normalization">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../resources/testhelper.js"></script>
+<body>
+<script>
+'use strict';
+
+const gTestUrl = '/media/1x1-green.png';
+const gBadTestUrl = document.location.href;
+
+test(t => {
+ const result = CSSStyleValue.parse('background-image', 'url("' + gTestUrl + '")');
+ assert_class_string(result, 'CSSImageValue');
+}, 'Normalizing a valid <url> returns a CSSImageValue');
+
+test(t => {
+ const result = CSSStyleValue.parse('background-image', 'url("' + gBadTestUrl + '")');
+ assert_class_string(result, 'CSSImageValue');
+}, 'Normalizing a bad <url> returns a CSSImageValue');
+
+test(t => {
+ const result = CSSStyleValue.parse('background-image', 'linear-gradient(red, orange)');
+ assert_equals(result.constructor.name, 'CSSImageValue');
+}, 'Normalizing a <gradient> returns a CSSImageValue');
+
+</script>
diff --git a/css/css-typed-om/stylevalue-normalization/normalize-resource.tentative.html b/css/css-typed-om/stylevalue-normalization/normalize-resource.tentative.html
deleted file mode 100644
index a972277..0000000
--- a/css/css-typed-om/stylevalue-normalization/normalize-resource.tentative.html
+++ /dev/null
@@ -1,56 +0,0 @@
-<!doctype html>
-<meta charset="utf-8">
-<title>CSSResourceValue normalization tests</title>
-<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#resourcevalue-normalization">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../resources/testhelper.js"></script>
-<body>
-<script>
-'use strict';
-
-const gTestUrl = '/media/1x1-green.png';
-const gBadTestUrl = document.location.href;
-
-async_test(t => {
- const result = CSSStyleValue.parse('background-image', 'url("' + gTestUrl + '")');
- assert_equals(result.constructor.name, 'CSSURLImageValue');
- assert_equals(result.intrinsicWidth, null);
- assert_equals(result.intrinsicHeight, null);
- assert_equals(result.intrinsicRatio, null);
- assert_equals(result.state, 'unloaded');
-
- let image = loadImageResource(t, result);
- image.addEventListener('load', t.step_func_done(() => {
- assert_equals(result.url, gTestUrl);
- assert_equals(result.state, 'loaded');
- assert_equals(result.intrinsicWidth, 1);
- assert_equals(result.intrinsicHeight, 1);
- assert_equals(result.intrinsicRatio, 1);
- }));
-}, 'Normalizing a valid <url> returns a CSSURLImageValue that eventually loads');
-
-async_test(t => {
- const result = CSSStyleValue.parse('background-image', 'url("' + gBadTestUrl + '")');
- assert_equals(result.constructor.name, 'CSSURLImageValue');
-
- let image = loadImageResource(t, result);
- image.addEventListener('error', t.step_func_done(() => {
- assert_equals(result.url, gBadTestUrl);
- assert_equals(result.state, 'error');
- assert_equals(result.intrinsicWidth, null);
- assert_equals(result.intrinsicHeight, null);
- assert_equals(result.intrinsicRatio, null);
- }));
-}, 'Normalizing a bad <url> returns a CSSURLImageValue in error state');
-
-test(t => {
- const result = CSSStyleValue.parse('background-image', 'linear-gradient(red, orange)');
- assert_equals(result.constructor.name, 'CSSImageValue');
- assert_equals(result.state, 'loaded');
- assert_equals(result.intrinsicWidth, null);
- assert_equals(result.intrinsicHeight, null);
- assert_equals(result.intrinsicRatio, null);
-}, 'Normalizing a <gradient> returns a CSSImageValue');
-
-</script>
diff --git a/css/css-typed-om/stylevalue-serialization/cssImageValue.html b/css/css-typed-om/stylevalue-serialization/cssImageValue.html
new file mode 100644
index 0000000..92256e5
--- /dev/null
+++ b/css/css-typed-om/stylevalue-serialization/cssImageValue.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSSURLImageValue serialization tests</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#urlimagevalue-serialization">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../resources/testhelper.js"></script>
+<body>
+<div id="log"></div>
+<div id="testUrl" style="background-image: url('/media/1x1-green.png')"></div>
+<script>
+'use strict';
+
+test(() => {
+ const result = document.getElementById('testUrl').attributeStyleMap.get('background-image');
+ assert_equals(result.toString(), 'url("/media/1x1-green.png")');
+}, 'CSSUrlImageValue serializes correctly');
+
+</script>
diff --git a/css/css-typed-om/stylevalue-serialization/cssUrlImageValue.tentative.html b/css/css-typed-om/stylevalue-serialization/cssUrlImageValue.tentative.html
deleted file mode 100644
index c97ed0d..0000000
--- a/css/css-typed-om/stylevalue-serialization/cssUrlImageValue.tentative.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!doctype html>
-<meta charset="utf-8">
-<title>IDL-constructed CSSURLImageValue serialization tests</title>
-<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#urlimagevalue-serialization">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../resources/testhelper.js"></script>
-<script>
-'use strict';
-
-test(() => {
- assert_equals(new CSSURLImageValue('http://foo.bar').toString(), 'url("http://foo.bar")');
-}, 'CSSUrlImageValue constructed from IDL serializes correctly');
-
-</script>
diff --git a/css/css-typed-om/stylevalue-subclasses/cssUrlImageValue-interface.html b/css/css-typed-om/stylevalue-subclasses/cssUrlImageValue-interface.html
deleted file mode 100644
index ed86054..0000000
--- a/css/css-typed-om/stylevalue-subclasses/cssUrlImageValue-interface.html
+++ /dev/null
@@ -1,22 +0,0 @@
-<!doctype html>
-<meta charset=utf-8>
-<title>CSSURLImageValue IDL</title>
-<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#cssurlimagevalue">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/resources/WebIDLParser.js"></script>
-<script src="/resources/idlharness.js"></script>
-<script type="text/plain" id="idl">
-[Exposed=(Window, Worker, PaintWorklet, LayoutWorklet),
- Constructor(USVString url)]
-interface CSSURLImageValue : CSSImageValue {
- readonly attribute USVString url;
-};
-</script>
-<script>
-'use strict';
-const idlArray = new IdlArray();
-idlArray.add_untested_idls('interface CSSImageValue { stringifier; };');
-idlArray.add_idls(document.getElementById('idl').textContent);
-idlArray.test();
-</script>
diff --git a/css/css-typed-om/stylevalue-subclasses/cssUrlImageValue-invalid.html b/css/css-typed-om/stylevalue-subclasses/cssUrlImageValue-invalid.html
deleted file mode 100644
index 8d6370a..0000000
--- a/css/css-typed-om/stylevalue-subclasses/cssUrlImageValue-invalid.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<!doctype html>
-<meta charset="utf-8">
-<title>CSSURLImageValue Error Handling</title>
-<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#imagevalue-objects">
-<meta name="assert" content="Test CSSURLImageValue constructor error handling" />
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<body>
-<div id="log">
-<script>
-'use strict';
-
-test(() => {
- assert_throws(new TypeError(), () => new CSSURLImageValue("file://:invalid url"));
-}, 'Constructing a CSSURLImageValue with an invalid URL throws a TypeError');
-
-</script>
diff --git a/css/css-typed-om/stylevalue-subclasses/cssUrlImageValue.html b/css/css-typed-om/stylevalue-subclasses/cssUrlImageValue.html
deleted file mode 100644
index abc944f..0000000
--- a/css/css-typed-om/stylevalue-subclasses/cssUrlImageValue.html
+++ /dev/null
@@ -1,81 +0,0 @@
-<!doctype html>
-<meta charset="utf-8">
-<title>CSSURLImageValue</title>
-<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#imagevalue-objects">
-<meta name="assert" content="Test CSSURLImageValue constructor and attributes" />
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../resources/testhelper.js"></script>
-<body>
-<div id="log">
-<script>
-'use strict';
-
-const gTestUrl = '/media/1x1-green.png';
-const gBase64TestUrl = 'data:image/gif;base64,R0lGODlhAQABAAAAACwAAAAAAQABAAA=';
-const gBadTestUrl = document.location.href;
-
-test(() => {
- const result = new CSSURLImageValue(gTestUrl);
-
- assert_not_equals(result, null,
- 'A CSSURLImageValue should be created');
- assert_equals(result.url, gTestUrl,
- 'url member should be same as passed in the constructor');
- assert_equals(result.intrinsicWidth, null, 'intrinsicWidth');
- assert_equals(result.intrinsicHeight, null, 'intrinsicHeight');
- assert_equals(result.intrinsicRatio, null, 'intrinsicRatio');
- assert_equals(result.state, 'unloaded', 'state');
-}, 'Constructing a CSSURLImageValue with a valid URL puts it in an ' +
- 'unloaded state');
-
-async_test(t => {
- const result = new CSSURLImageValue(gTestUrl);
- let image = loadImageResource(t, result);
-
- image.addEventListener('load', t.step_func_done(() => {
- assert_equals(result.url, gTestUrl,
- 'url member should be same as passed in the constructor');
- assert_equals(result.state, 'loaded', 'state');
- assert_equals(result.intrinsicWidth, 1,
- 'intrinsicWidth member should be width of loaded image');
- assert_equals(result.intrinsicHeight, 1,
- 'intrinsicHeight member should be height of loaded image');
- assert_equals(result.intrinsicRatio, 1,
- 'intrinsicRatio member should be ratio of loaded image');
- }));
-}, 'Constructing a CSSURLImageValue from a URL sets its state to loaded');
-
-async_test(t => {
- const result = new CSSURLImageValue(gBase64TestUrl);
- let image = loadImageResource(t, result);
-
- image.addEventListener('load', t.step_func_done(() => {
- assert_equals(result.url, gBase64TestUrl,
- 'url member should be same as passed in the constructor');
- assert_equals(result.state, 'loaded', 'state');
- assert_equals(result.intrinsicWidth, 1,
- 'intrinsicWidth member should be width of loaded image');
- assert_equals(result.intrinsicHeight, 1,
- 'intrinsicHeight member should be height of loaded image');
- assert_equals(result.intrinsicRatio, 1,
- 'intrinsicRatio member should be ratio of loaded image');
- }));
-}, 'Constructing a CSSURLImageValue from a base64 URL sets its state to loaded');
-
-async_test(t => {
- const result = new CSSURLImageValue(gBadTestUrl);
- let image = loadImageResource(t, result);
-
- image.addEventListener('error', t.step_func_done(() => {
- assert_equals(result.url, gBadTestUrl,
- 'url member should be same as passed in the constructor');
- assert_equals(result.state, 'error', 'state');
- assert_equals(result.intrinsicWidth, null, 'intrinsicWidth');
- assert_equals(result.intrinsicHeight, null, 'intrinsicHeight');
- assert_equals(result.intrinsicRatio, null, 'intrinsicRatio');
- }));
-}, 'Constructing a CSSURLImageValue from a URL to an invalid image sets ' +
- 'its state to error');
-
-</script>
diff --git a/css/css-typed-om/the-stylepropertymap/properties/resources/testsuite.js b/css/css-typed-om/the-stylepropertymap/properties/resources/testsuite.js
index a198c41..b4ed1e7 100644
--- a/css/css-typed-om/the-stylepropertymap/properties/resources/testsuite.js
+++ b/css/css-typed-om/the-stylepropertymap/properties/resources/testsuite.js
@@ -145,22 +145,6 @@
}
],
},
- '<image>': {
- description: 'an image',
- examples: [
- {
- description: "a PNG image",
- input: new CSSURLImageValue('/media/1x1.png'),
- defaultComputed: (_, result) => {
- // URLs compute to absolute URLs
- assert_true(result instanceof CSSURLImageValue,
- 'Computed value should be a CSSURLImageValue');
- assert_true(result.url.endsWith('/media/1x1.png'),
- 'Computed value should be an absolute URL');
- }
- }
- ],
- },
'<transform>': {
description: 'a transform',
examples: [
@@ -218,6 +202,24 @@
}, `Can set '${propertyName}' to ${description}`);
}
+// We have to special case CSSImageValue as they cannot be created with a
+// constructor and are completely opaque.
+function testIsImageValidForProperty(propertyName) {
+ test(t => {
+ let element1 = createDivWithStyle(t, `${propertyName}: url("/media/1x1-green.png")`);
+ let element2 = createDivWithStyle(t);
+
+ const result = element1.attributeStyleMap.get(propertyName);
+ assert_not_equals(result, null, 'Image value must not be null');
+ assert_class_string(result, 'CSSImageValue',
+ 'Image value must be a CSSImageValue');
+
+ element2.attributeStyleMap.set(propertyName, result);
+ assert_equals(element2.style[propertyName], element1.style[propertyName],
+ 'Image value can be set on different element');
+ }, `Can set '${propertyName}' to an image`);
+}
+
// Test that styleMap.set throws for invalid values
function testPropertyInvalid(propertyName, examples, description) {
test(t => {
@@ -289,6 +291,12 @@
'CSS-wide keywords');
for (const testCase of testCases) {
+ // <image> is a special case
+ if (testCase.syntax === '<image>') {
+ testIsImageValidForProperty(propertyName);
+ continue;
+ }
+
// Retrieve test examples for this test case's syntax. If the syntax
// looks like a keyword, then create an example on the fly.
const syntaxExamples = testCase.syntax.match(/^[a-z\-]+$/) ?
diff --git a/interfaces/css-typed-om.idl b/interfaces/css-typed-om.idl
index 2744076..6c33907 100644
--- a/interfaces/css-typed-om.idl
+++ b/interfaces/css-typed-om.idl
@@ -308,23 +308,6 @@
attribute CSSNumericValue y;
};
-enum CSSResourceState {"unloaded", "loading", "loaded", "error"};
-
[Exposed=(Window, Worker, PaintWorklet, LayoutWorklet)]
-interface CSSResourceValue : CSSStyleValue {
- readonly attribute CSSResourceState state;
-};
-
-
-[Exposed=(Window, Worker, PaintWorklet, LayoutWorklet)]
-interface CSSImageValue : CSSResourceValue {
- readonly attribute double? intrinsicWidth;
- readonly attribute double? intrinsicHeight;
- readonly attribute double? intrinsicRatio;
-};
-
-[Exposed=(Window, Worker, PaintWorklet, LayoutWorklet),
- Constructor(USVString url)]
-interface CSSURLImageValue : CSSImageValue {
- readonly attribute USVString url;
+interface CSSImageValue : CSSStyleValue {
};