summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/css/css-properties-values-api/at-property-animation.html
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /testing/web-platform/tests/css/css-properties-values-api/at-property-animation.html
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/css/css-properties-values-api/at-property-animation.html')
-rw-r--r--testing/web-platform/tests/css/css-properties-values-api/at-property-animation.html451
1 files changed, 451 insertions, 0 deletions
diff --git a/testing/web-platform/tests/css/css-properties-values-api/at-property-animation.html b/testing/web-platform/tests/css/css-properties-values-api/at-property-animation.html
new file mode 100644
index 0000000000..233b63239f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-properties-values-api/at-property-animation.html
@@ -0,0 +1,451 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api-1">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="./resources/utils.js"></script>
+<div id=outer>
+ <div id=div></div>
+</div>
+<script>
+
+test_with_at_property({
+ syntax: '"<length>"',
+ inherits: false,
+ initialValue: '0px'
+}, (name) => {
+ with_style_node(`
+ @keyframes test {
+ from { ${name}: 100px; }
+ to { ${name}: 200px; }
+ }
+ #div { animation: test 100s -50s linear; }
+ `, () => {
+ assert_equals(getComputedStyle(div).getPropertyValue(name), '150px');
+ });
+}, '@keyframes works with @property');
+
+test_with_at_property({
+ syntax: '"<length>"',
+ inherits: false,
+ initialValue: '0px'
+}, (name) => {
+ with_style_node(`
+ @property ${name} {
+ syntax: "<color>";
+ inherits: false;
+ initial-value: black;
+ }
+ @keyframes test {
+ from { ${name}: rgb(100, 100, 100); }
+ to { ${name}: rgb(200, 200, 200); }
+ }
+ #div { animation: test 100s -50s linear; }
+ `, () => {
+ assert_equals(getComputedStyle(div).getPropertyValue(name), 'rgb(150, 150, 150)');
+ });
+}, '@keyframes picks up the latest @property in the document');
+
+test_with_at_property({
+ syntax: '"<length>"',
+ inherits: false,
+ initialValue: '0px'
+}, (name) => {
+ // These keyframes are initially invalid for the declared custom property.
+ let animation = div.animate([
+ { [name]: 'rgb(100, 100, 100)'},
+ { [name]: 'rgb(200, 200, 200)'},
+ ], { duration: 10000, delay: -5000, easing: 'linear' });
+ let cs = getComputedStyle(div);
+ assert_equals(cs.getPropertyValue(name), '0px');
+
+ // Redeclare the property as a <color>, effectively making the existing
+ // keyframes valid.
+ with_at_property({
+ name: name,
+ syntax: '"<color>"',
+ inherits: false,
+ initialValue: 'black'
+ }, (name) => {
+ assert_equals(cs.getPropertyValue(name), 'rgb(150, 150, 150)');
+ });
+
+ animation.finish();
+}, 'Ongoing animation picks up redeclared custom property');
+
+test_with_at_property({
+ syntax: '"<length>"',
+ inherits: false,
+ initialValue: '0px'
+}, (name) => {
+ // These keyframes are initially invalid for the declared custom property.
+ let animation = div.animate([
+ { [name]: 'rgb(100, 100, 100)'},
+ { [name]: 'rgb(200, 200, 200)'},
+ ], { duration: 10000, delay: -5000, easing: 'linear' });
+ let cs = getComputedStyle(div);
+ assert_equals(cs.getPropertyValue(name), '0px');
+
+ // Setting the keyframes to something that matches <length> makes the
+ // interpolation valid.
+ animation.effect.setKeyframes([
+ {[name]: '100px'},
+ {[name]: '200px'}
+ ]);
+ assert_equals(cs.getPropertyValue(name), '150px');
+
+ animation.finish();
+}, 'Ongoing animation matches new keyframes against the current registration');
+
+test_with_at_property({
+ syntax: '"<length>"',
+ inherits: false,
+ initialValue: '0px'
+}, (name) => {
+ let animation = div.animate([
+ { [name]: 'initial'},
+ { [name]: '400px'},
+ ], { duration: 10000, delay: -5000, easing: 'linear' });
+ let cs = getComputedStyle(div);
+ assert_equals(cs.getPropertyValue(name), '200px');
+
+ // Change initial value.
+ with_at_property({
+ name: name,
+ syntax: '"<length>"',
+ inherits: false,
+ initialValue: '100px'
+ }, (name) => {
+ assert_equals(cs.getPropertyValue(name), '250px');
+ });
+
+ animation.finish();
+}, 'Ongoing animation picks up redeclared intial value');
+
+test_with_at_property({
+ syntax: '"<length>"',
+ inherits: false,
+ initialValue: '0px'
+}, (name) => {
+ try {
+ document.body.style = `${name}: 100px`;
+ // Note that 'inherit' here refers to #outer, which has the initial
+ // value. (#outer did not inherit from body, since the property is not
+ // yet declared as inherited).
+ let animation = div.animate([
+ { [name]: 'inherit'},
+ { [name]: '400px'},
+ ], { duration: 10000, delay: -5000, easing: 'linear' });
+ let cs = getComputedStyle(div);
+ assert_equals(cs.getPropertyValue(name), '200px');
+
+ // Change inherits to 'true'. The value should now propagate from body
+ // to #outer.
+ with_at_property({
+ name: name,
+ syntax: '"<length>"',
+ inherits: true,
+ initialValue: '0px'
+ }, (name) => {
+ assert_equals(cs.getPropertyValue(name), '250px');
+ });
+
+ animation.finish();
+ } finally {
+ document.body.style = '';
+ }
+}, 'Ongoing animation picks up redeclared inherits flag');
+
+test_with_at_property({
+ syntax: '"<length>"',
+ inherits: false,
+ initialValue: '0px'
+}, (name) => {
+ try {
+ outer.style = `${name}: 100px`;
+ // 'unset' should take the initial value (not the value from #outer), since
+ // the property is not declared as inherited.
+ let animation = div.animate([
+ { [name]: 'unset'},
+ { [name]: '400px'},
+ ], { duration: 10000, delay: -5000, easing: 'linear' });
+ let cs = getComputedStyle(div);
+ assert_equals(cs.getPropertyValue(name), '200px');
+
+ // Change inherits to 'true'. 'unset' now refers to #outer's value.
+ with_at_property({
+ name: name,
+ syntax: '"<length>"',
+ inherits: true,
+ initialValue: '0px'
+ }, (name) => {
+ assert_equals(cs.getPropertyValue(name), '250px');
+ });
+
+ animation.finish();
+ } finally {
+ outer.style = '';
+ }
+}, 'Ongoing animation picks up redeclared meaning of \'unset\'');
+
+test_with_at_property({
+ syntax: '"<color>"',
+ inherits: false,
+ initialValue: 'red'
+}, (name) => {
+ try {
+ assert_equals(getComputedStyle(div).getPropertyValue(name), 'rgb(255, 0, 0)');
+ div.style = `transition: ${name} steps(2, start) 100s; ${name}: blue`;
+ assert_equals(getComputedStyle(div).getPropertyValue(name), 'rgb(128, 0, 128)');
+ } finally {
+ div.style = '';
+ }
+}, 'Transitioning from initial value');
+
+test_with_at_property({
+ syntax: '"<color>"',
+ inherits: false,
+ initialValue: 'red'
+}, (name) => {
+ try {
+ div.style = `${name}: blue;`;
+ assert_equals(getComputedStyle(div).getPropertyValue(name), 'rgb(0, 0, 255)');
+ div.style = `transition: ${name} steps(2, start) 100s; ${name}: green`;
+ assert_equals(getComputedStyle(div).getPropertyValue(name), 'rgb(0, 64, 128)');
+ } finally {
+ div.style = '';
+ }
+}, 'Transitioning from specified value');
+
+test_with_at_property({
+ syntax: '"<length>"',
+ inherits: false,
+ initialValue: '100px'
+}, (name) => {
+ with_style_node(`div { transition: ${name} steps(2, start) 100s; }`, () => {
+ assert_equals(getComputedStyle(div).getPropertyValue(name), '100px');
+ // Re-declaring the property with a different initial value effectively
+ // means the computed value has changed. This means we should transition
+ // from the old initial value to the new initial value.
+ with_at_property({
+ name: name,
+ syntax: '"<length>"',
+ inherits: false,
+ initialValue: '200px'
+ }, () => {
+ assert_equals(getComputedStyle(div).getPropertyValue(name), '150px');
+ });
+ });
+}, 'Transition triggered by initial value change');
+
+test_with_at_property({
+ syntax: '"<length>"',
+ inherits: false,
+ initialValue: '100px'
+}, (name) => {
+ with_style_node(`div { transition: ${name} steps(2, start) 100s; }`, () => {
+ assert_equals(getComputedStyle(div).getPropertyValue(name), '100px');
+ with_at_property({
+ name: name,
+ syntax: '"<color>"',
+ inherits: false,
+ initialValue: 'green'
+ }, () => {
+ assert_equals(getComputedStyle(div).getPropertyValue(name), 'rgb(0, 128, 0)');
+ });
+ });
+}, 'No transition when changing types');
+
+test(() => {
+ let name = generate_name();
+ with_style_node(`div { ${name}: 100px; transition: ${name} steps(2, start) 100s; }`, () => {
+ assert_equals(getComputedStyle(div).getPropertyValue(name), '100px');
+
+ let style1 = document.createElement('style');
+ style1.textContent = `
+ @property ${name} {
+ syntax: "<length>";
+ inherits: false;
+ initial-value: 200px;
+ }
+ `;
+
+ let style2 = document.createElement('style');
+ style2.textContent = `div { ${name}: 400px; }`;
+
+ try {
+ // Register the property:
+ document.body.append(style1);
+ // The token sequence ' 100px' is now interpreted as a length '100px'.
+ assert_equals(getComputedStyle(div).getPropertyValue(name), '100px');
+
+ // Change the computed value:
+ document.body.append(style2);
+ // This should cause an interpolation between 100px and 400px:
+ assert_equals(getComputedStyle(div).getPropertyValue(name), '250px');
+
+ // In the middle of the transition above, remove the @property rule
+ // (making the computed value a token sequence again). We should snap
+ // to the new token sequence.
+ style1.remove();
+ assert_equals(getComputedStyle(div).getPropertyValue(name), '400px');
+ } finally {
+ style1.remove();
+ style2.remove();
+ }
+ });
+}, 'No transition when removing @property rule');
+
+test_with_at_property({
+ syntax: '"<length>"',
+ inherits: false,
+ initialValue: '0px'
+}, (name) => {
+ with_style_node(`
+ @keyframes test {
+ from { ${name}: 100px; }
+ to { ${name}: 200px; }
+ }
+ #div {
+ animation: test 100s -50s linear;
+ --unregistered: var(${name});
+ }
+ `, () => {
+ assert_equals(getComputedStyle(div).getPropertyValue('--unregistered'), '150px');
+ });
+}, 'Unregistered properties referencing animated properties update correctly.');
+
+test_with_at_property({
+ syntax: '"<length>"',
+ inherits: false,
+ initialValue: '0px'
+}, (name) => {
+ with_style_node(`
+ @keyframes test {
+ from { ${name}: 100px; }
+ to { ${name}: 200px; }
+ }
+ @property --registered {
+ syntax: "<length>";
+ inherits: false;
+ initialValue: 0px;
+ }
+ #div {
+ animation: test 100s -50s linear;
+ --registered: var(${name});
+ }
+ `, () => {
+ assert_equals(getComputedStyle(div).getPropertyValue('--registered'), '150px');
+ });
+}, 'Registered properties referencing animated properties update correctly.');
+
+test_with_at_property({
+ syntax: '"<length>"',
+ inherits: false,
+ initialValue: '0px'
+}, (name) => {
+ with_style_node(`
+ @keyframes test {
+ from { ${name}: inherit; }
+ to { ${name}: 300px; }
+ }
+ #outer {
+ ${name}: 100px;
+ }
+ #div {
+ animation: test 100s -50s linear paused;
+ }
+ `, () => {
+ assert_equals(getComputedStyle(div).getPropertyValue(name), '200px');
+
+ outer.style.setProperty(name, '200px');
+ assert_equals(getComputedStyle(div).getPropertyValue(name), '250px');
+
+ outer.style.setProperty(name, '0px');
+ assert_equals(getComputedStyle(div).getPropertyValue(name), '150px');
+
+ outer.style.removeProperty(name);
+ });
+}, 'CSS animation setting "inherit" for a custom property on a keyframe is responsive to changing that custom property on the parent.');
+
+test_with_at_property({
+ syntax: '"<length>"',
+ inherits: false,
+ initialValue: '0px'
+}, (name) => {
+ with_style_node(`
+ #outer {
+ ${name}: 100px;
+ }
+ `, () => {
+ const animation = div.animate({ [name]: ["inherit", "300px"]}, 1000);
+ animation.currentTime = 500;
+ animation.pause();
+
+ assert_equals(getComputedStyle(div).getPropertyValue(name), '200px');
+
+ outer.style.setProperty(name, '200px');
+ assert_equals(getComputedStyle(div).getPropertyValue(name), '250px');
+
+ outer.style.setProperty(name, '0px');
+ assert_equals(getComputedStyle(div).getPropertyValue(name), '150px');
+
+ outer.style.removeProperty(name);
+ });
+}, 'JS-originated animation setting "inherit" for a custom property on a keyframe is responsive to changing that custom property on the parent.');
+
+test_with_at_property({
+ syntax: '"<color>"',
+ inherits: false,
+ initialValue: 'black'
+}, (name) => {
+ with_style_node(`
+ @keyframes test {
+ from { ${name}: currentcolor; }
+ to { ${name}: rgb(200, 200, 200); }
+ }
+ #outer {
+ color: rgb(100, 100, 100);
+ }
+ #div {
+ animation: test 100s -50s linear paused;
+ }
+ `, (style) => {
+ assert_equals(getComputedStyle(div).getPropertyValue(name), 'rgb(150, 150, 150)');
+
+ outer.style.color = 'rgb(50, 50, 50)';
+ assert_equals(getComputedStyle(div).getPropertyValue(name), 'rgb(125, 125, 125)');
+
+ outer.style.color = 'rgb(150, 150, 150)';
+ assert_equals(getComputedStyle(div).getPropertyValue(name), 'rgb(175, 175, 175)');
+
+ outer.style.removeProperty("color");
+ });
+}, 'CSS animation setting "currentColor" for a custom property on a keyframe is responsive to changing "color" on the parent.');
+
+test_with_at_property({
+ syntax: '"<color>"',
+ inherits: false,
+ initialValue: 'black'
+}, (name) => {
+ with_style_node(`
+ #outer {
+ color: rgb(100, 100, 100);
+ }
+ `, () => {
+ const animation = div.animate({ [name]: ["currentcolor", "rgb(200, 200, 200)"]}, 1000);
+ animation.currentTime = 500;
+ animation.pause();
+
+ assert_equals(getComputedStyle(div).getPropertyValue(name), 'rgb(150, 150, 150)');
+
+ outer.style.color = 'rgb(50, 50, 50)';
+ assert_equals(getComputedStyle(div).getPropertyValue(name), 'rgb(125, 125, 125)');
+
+ outer.style.color = 'rgb(150, 150, 150)';
+ assert_equals(getComputedStyle(div).getPropertyValue(name), 'rgb(175, 175, 175)');
+
+ outer.style.removeProperty("color");
+ });
+}, 'JS-originated animation setting "currentColor" for a custom property on a keyframe is responsive to changing "color" on the parent.');
+
+</script>