mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Update web-platform-tests to revision e426a6933a05bf144eba06a1d4c47ba876a4e2d1
This commit is contained in:
parent
415b26e4f1
commit
5e5eccabf8
495 changed files with 14920 additions and 784 deletions
|
@ -0,0 +1,389 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>Animation.commitStyles</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/web-animations/#dom-animation-commitstyles">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../../testcommon.js"></script>
|
||||
<body>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
function assert_numeric_style_equals(opacity, expected, description) {
|
||||
return assert_approx_equals(
|
||||
parseFloat(opacity),
|
||||
expected,
|
||||
0.0001,
|
||||
description
|
||||
);
|
||||
}
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
div.style.opacity = '0.1';
|
||||
|
||||
const animation = div.animate(
|
||||
{ opacity: 0.2 },
|
||||
{ duration: 1, fill: 'forwards' }
|
||||
);
|
||||
animation.finish();
|
||||
|
||||
animation.commitStyles();
|
||||
|
||||
// Cancel the animation so we can inspect the underlying style
|
||||
animation.cancel();
|
||||
|
||||
assert_numeric_style_equals(getComputedStyle(div).opacity, 0.2);
|
||||
}, 'Commits styles');
|
||||
|
||||
promise_test(async t => {
|
||||
const div = createDiv(t);
|
||||
div.style.opacity = '0.1';
|
||||
|
||||
const animA = div.animate(
|
||||
{ opacity: 0.2 },
|
||||
{ duration: 1, fill: 'forwards' }
|
||||
);
|
||||
const animB = div.animate(
|
||||
{ opacity: 0.3 },
|
||||
{ duration: 1, fill: 'forwards' }
|
||||
);
|
||||
|
||||
await animA.finished;
|
||||
|
||||
animB.cancel();
|
||||
|
||||
animA.commitStyles();
|
||||
|
||||
assert_numeric_style_equals(getComputedStyle(div).opacity, 0.2);
|
||||
}, 'Commits styles for an animation that has been removed');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
div.style.margin = '10px';
|
||||
|
||||
const animation = div.animate(
|
||||
{ margin: '20px' },
|
||||
{ duration: 1, fill: 'forwards' }
|
||||
);
|
||||
animation.finish();
|
||||
|
||||
animation.commitStyles();
|
||||
|
||||
animation.cancel();
|
||||
|
||||
assert_equals(div.style.marginLeft, '20px');
|
||||
}, 'Commits shorthand styles');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
div.style.marginLeft = '10px';
|
||||
|
||||
const animation = div.animate(
|
||||
{ marginInlineStart: '20px' },
|
||||
{ duration: 1, fill: 'forwards' }
|
||||
);
|
||||
animation.finish();
|
||||
|
||||
animation.commitStyles();
|
||||
|
||||
animation.cancel();
|
||||
|
||||
assert_equals(div.style.marginLeft, '20px');
|
||||
}, 'Commits logical properties');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
div.style.marginLeft = '10px';
|
||||
|
||||
const animation = div.animate({ opacity: [0.2, 0.7] }, 1000);
|
||||
animation.currentTime = 500;
|
||||
animation.commitStyles();
|
||||
animation.cancel();
|
||||
|
||||
assert_numeric_style_equals(getComputedStyle(div).opacity, 0.45);
|
||||
}, 'Commits values calculated mid-interval');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
div.style.setProperty('--target', '0.5');
|
||||
|
||||
const animation = div.animate(
|
||||
{ opacity: 'var(--target)' },
|
||||
{ duration: 1, fill: 'forwards' }
|
||||
);
|
||||
animation.finish();
|
||||
animation.commitStyles();
|
||||
animation.cancel();
|
||||
|
||||
assert_numeric_style_equals(getComputedStyle(div).opacity, 0.5);
|
||||
|
||||
// Changes to the variable should have no effect
|
||||
div.style.setProperty('--target', '1');
|
||||
|
||||
assert_numeric_style_equals(getComputedStyle(div).opacity, 0.5);
|
||||
}, 'Commits variables as their computed values');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
div.style.fontSize = '10px';
|
||||
|
||||
const animation = div.animate(
|
||||
{ width: '10em' },
|
||||
{ duration: 1, fill: 'forwards' }
|
||||
);
|
||||
animation.finish();
|
||||
animation.commitStyles();
|
||||
animation.cancel();
|
||||
|
||||
assert_numeric_style_equals(getComputedStyle(div).width, 100);
|
||||
|
||||
// Changes to the font-size should have no effect
|
||||
div.style.fontSize = '20px';
|
||||
|
||||
assert_numeric_style_equals(getComputedStyle(div).width, 100);
|
||||
}, 'Commits em units as pixel values');
|
||||
|
||||
promise_test(async t => {
|
||||
const div = createDiv(t);
|
||||
div.style.opacity = '0.1';
|
||||
|
||||
const animA = div.animate(
|
||||
{ opacity: '0.2' },
|
||||
{ duration: 1, fill: 'forwards' }
|
||||
);
|
||||
const animB = div.animate(
|
||||
{ opacity: '0.2', composite: 'add' },
|
||||
{ duration: 1, fill: 'forwards' }
|
||||
);
|
||||
const animC = div.animate(
|
||||
{ opacity: '0.3', composite: 'add' },
|
||||
{ duration: 1, fill: 'forwards' }
|
||||
);
|
||||
|
||||
animA.persist();
|
||||
animB.persist();
|
||||
|
||||
await animB.finished;
|
||||
|
||||
// The values above have been chosen such that various error conditions
|
||||
// produce results that all differ from the desired result:
|
||||
//
|
||||
// Expected result:
|
||||
//
|
||||
// animA + animB = 0.4
|
||||
//
|
||||
// Likely error results:
|
||||
//
|
||||
// <underlying> = 0.1
|
||||
// (Commit didn't work at all)
|
||||
//
|
||||
// animB = 0.2
|
||||
// (Didn't add at all when resolving)
|
||||
//
|
||||
// <underlying> + animB = 0.3
|
||||
// (Added to the underlying value instead of lower-priority animations when
|
||||
// resolving)
|
||||
//
|
||||
// <underlying> + animA + animB = 0.5
|
||||
// (Didn't respect the composite mode of lower-priority animations)
|
||||
//
|
||||
// animA + animB + animC = 0.7
|
||||
// (Resolved the whole stack, not just up to the target effect)
|
||||
//
|
||||
|
||||
animB.commitStyles();
|
||||
|
||||
animA.cancel();
|
||||
animB.cancel();
|
||||
animC.cancel();
|
||||
|
||||
assert_numeric_style_equals(getComputedStyle(div).opacity, 0.4);
|
||||
}, 'Commits the intermediate value of an animation in the middle of stack');
|
||||
|
||||
promise_test(async t => {
|
||||
const div = createDiv(t);
|
||||
div.style.opacity = '0.1';
|
||||
|
||||
// Setup animation
|
||||
const animation = div.animate(
|
||||
{ opacity: 0.2 },
|
||||
{ duration: 1, fill: 'forwards' }
|
||||
);
|
||||
animation.finish();
|
||||
|
||||
// Setup observer
|
||||
const mutationRecords = [];
|
||||
const observer = new MutationObserver(mutations => {
|
||||
mutationRecords.push(...mutations);
|
||||
});
|
||||
observer.observe(div, { attributes: true, attributeOldValue: true });
|
||||
|
||||
animation.commitStyles();
|
||||
|
||||
// Wait for mutation records to be dispatched
|
||||
await Promise.resolve();
|
||||
|
||||
assert_equals(mutationRecords.length, 1, 'Should have one mutation record');
|
||||
|
||||
const mutation = mutationRecords[0];
|
||||
assert_equals(mutation.type, 'attributes');
|
||||
assert_equals(mutation.oldValue, 'opacity: 0.1;');
|
||||
|
||||
observer.disconnect();
|
||||
}, 'Triggers mutation observers when updating style');
|
||||
|
||||
promise_test(async t => {
|
||||
const div = createDiv(t);
|
||||
div.style.opacity = '0.2';
|
||||
|
||||
// Setup animation
|
||||
const animation = div.animate(
|
||||
{ opacity: 0.2 },
|
||||
{ duration: 1, fill: 'forwards' }
|
||||
);
|
||||
animation.finish();
|
||||
|
||||
// Setup observer
|
||||
const mutationRecords = [];
|
||||
const observer = new MutationObserver(mutations => {
|
||||
mutationRecords.push(...mutations);
|
||||
});
|
||||
observer.observe(div, { attributes: true });
|
||||
|
||||
animation.commitStyles();
|
||||
|
||||
// Wait for mutation records to be dispatched
|
||||
await Promise.resolve();
|
||||
|
||||
assert_equals(mutationRecords.length, 0, 'Should have no mutation records');
|
||||
|
||||
observer.disconnect();
|
||||
}, 'Does NOT trigger mutation observers when the change to style is redundant');
|
||||
|
||||
test(t => {
|
||||
const pseudo = getPseudoElement(t, 'before');
|
||||
const animation = pseudo.animate(
|
||||
{ opacity: 0 },
|
||||
{ duration: 1, fill: 'forwards' }
|
||||
);
|
||||
|
||||
assert_throws('NoModificationAllowedError', () => {
|
||||
animation.commitStyles();
|
||||
});
|
||||
}, 'Throws if the target element is a pseudo element');
|
||||
|
||||
test(t => {
|
||||
const animation = createDiv(t).animate(
|
||||
{ opacity: 0 },
|
||||
{ duration: 1, fill: 'forwards' }
|
||||
);
|
||||
|
||||
const nonStyleElement
|
||||
= document.createElementNS('http://example.org/test', 'test');
|
||||
document.body.appendChild(nonStyleElement);
|
||||
animation.effect.target = nonStyleElement;
|
||||
|
||||
assert_throws('NoModificationAllowedError', () => {
|
||||
animation.commitStyles();
|
||||
});
|
||||
|
||||
nonStyleElement.remove();
|
||||
}, 'Throws if the target element is not something with a style attribute');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const animation = div.animate(
|
||||
{ opacity: 0 },
|
||||
{ duration: 1, fill: 'forwards' }
|
||||
);
|
||||
|
||||
div.style.display = 'none';
|
||||
|
||||
assert_throws('InvalidStateError', () => {
|
||||
animation.commitStyles();
|
||||
});
|
||||
}, 'Throws if the target effect is display:none');
|
||||
|
||||
test(t => {
|
||||
const container = createDiv(t);
|
||||
const div = createDiv(t);
|
||||
container.append(div);
|
||||
|
||||
const animation = div.animate(
|
||||
{ opacity: 0 },
|
||||
{ duration: 1, fill: 'forwards' }
|
||||
);
|
||||
|
||||
container.style.display = 'none';
|
||||
|
||||
assert_throws('InvalidStateError', () => {
|
||||
animation.commitStyles();
|
||||
});
|
||||
}, "Throws if the target effect's ancestor is display:none");
|
||||
|
||||
test(t => {
|
||||
const container = createDiv(t);
|
||||
const div = createDiv(t);
|
||||
container.append(div);
|
||||
|
||||
const animation = div.animate(
|
||||
{ opacity: 0 },
|
||||
{ duration: 1, fill: 'forwards' }
|
||||
);
|
||||
|
||||
container.style.display = 'contents';
|
||||
|
||||
// Should NOT throw
|
||||
animation.commitStyles();
|
||||
}, 'Treats display:contents as rendered');
|
||||
|
||||
test(t => {
|
||||
const container = createDiv(t);
|
||||
const div = createDiv(t);
|
||||
container.append(div);
|
||||
|
||||
const animation = div.animate(
|
||||
{ opacity: 0 },
|
||||
{ duration: 1, fill: 'forwards' }
|
||||
);
|
||||
|
||||
div.style.display = 'contents';
|
||||
container.style.display = 'none';
|
||||
|
||||
assert_throws('InvalidStateError', () => {
|
||||
animation.commitStyles();
|
||||
});
|
||||
}, 'Treats display:contents in a display:none subtree as not rendered');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const animation = div.animate(
|
||||
{ opacity: 0 },
|
||||
{ duration: 1, fill: 'forwards' }
|
||||
);
|
||||
|
||||
div.remove();
|
||||
|
||||
assert_throws('InvalidStateError', () => {
|
||||
animation.commitStyles();
|
||||
});
|
||||
}, 'Throws if the target effect is disconnected');
|
||||
|
||||
test(t => {
|
||||
const pseudo = getPseudoElement(t, 'before');
|
||||
const animation = pseudo.animate(
|
||||
{ opacity: 0 },
|
||||
{ duration: 1, fill: 'forwards' }
|
||||
);
|
||||
|
||||
pseudo.element.remove();
|
||||
|
||||
assert_throws('NoModificationAllowedError', () => {
|
||||
animation.commitStyles();
|
||||
});
|
||||
}, 'Checks the pseudo element condition before the not rendered condition');
|
||||
|
||||
</script>
|
||||
</body>
|
Loading…
Add table
Add a link
Reference in a new issue