--- a/dom/animation/test/chrome/test_animation_observers_sync.html
+++ b/dom/animation/test/chrome/test_animation_observers_sync.html
@@ -101,42 +101,44 @@ function runTest() {
aOptions.subtree);
var anim = div.animate({ opacity: [ 0, 1 ] }, 200 * MS_PER_SEC);
assert_equals_records(observer.takeRecords(),
[{ added: [anim], changed: [], removed: [] }],
"records after animation is added");
- anim.effect.timing.duration = 100 * MS_PER_SEC;
+ anim.effect.updateTiming({ duration: 100 * MS_PER_SEC });
assert_equals_records(observer.takeRecords(),
[{ added: [], changed: [anim], removed: [] }],
"records after duration is changed");
- anim.effect.timing.duration = 100 * MS_PER_SEC;
+ anim.effect.updateTiming({ duration: 100 * MS_PER_SEC });
assert_equals_records(observer.takeRecords(),
[], "records after assigning same value");
- anim.currentTime = anim.effect.timing.duration * 2;
+ anim.currentTime = anim.effect.getComputedTiming().duration * 2;
anim.finish();
assert_equals_records(observer.takeRecords(),
[{ added: [], changed: [], removed: [anim] }],
"records after animation end");
- anim.effect.timing.duration = anim.effect.timing.duration * 3;
+ anim.effect.updateTiming({
+ duration: anim.effect.getComputedTiming().duration * 3
+ });
assert_equals_records(observer.takeRecords(),
[{ added: [anim], changed: [], removed: [] }],
"records after animation restarted");
- anim.effect.timing.duration = "auto";
+ anim.effect.updateTiming({ duration: 'auto' });
assert_equals_records(observer.takeRecords(),
[{ added: [], changed: [], removed: [anim] }],
"records after duration set \"auto\"");
- anim.effect.timing.duration = "auto";
+ anim.effect.updateTiming({ duration: 'auto' });
assert_equals_records(observer.takeRecords(),
[], "records after assigning same value \"auto\"");
}, "change_duration_and_currenttime");
test(t => {
var div = addDiv(t);
var observer =
setupSynchronousObserver(t,
@@ -144,31 +146,31 @@ function runTest() {
aOptions.subtree);
var anim = div.animate({ opacity: [ 0, 1 ] }, 100 * MS_PER_SEC);
assert_equals_records(observer.takeRecords(),
[{ added: [anim], changed: [], removed: [] }],
"records after animation is added");
- anim.effect.timing.endDelay = 10 * MS_PER_SEC;
+ anim.effect.updateTiming({ endDelay: 10 * MS_PER_SEC });
assert_equals_records(observer.takeRecords(),
[{ added: [], changed: [anim], removed: [] }],
"records after endDelay is changed");
- anim.effect.timing.endDelay = 10 * MS_PER_SEC;
+ anim.effect.updateTiming({ endDelay: 10 * MS_PER_SEC });
assert_equals_records(observer.takeRecords(),
[], "records after assigning same value");
anim.currentTime = 109 * MS_PER_SEC;
assert_equals_records(observer.takeRecords(),
[{ added: [], changed: [], removed: [anim] }],
"records after currentTime during endDelay");
- anim.effect.timing.endDelay = -110 * MS_PER_SEC;
+ anim.effect.updateTiming({ endDelay: -110 * MS_PER_SEC });
assert_equals_records(observer.takeRecords(),
[], "records after assigning negative value");
}, "change_enddelay_and_currenttime");
test(t => {
var div = addDiv(t);
var observer =
setupSynchronousObserver(t,
@@ -190,31 +192,31 @@ function runTest() {
aOptions.subtree);
var anim = div.animate({ opacity: [ 0, 1 ] }, 100 * MS_PER_SEC);
assert_equals_records(observer.takeRecords(),
[{ added: [anim], changed: [], removed: [] }],
"records after animation is added");
- anim.effect.timing.iterations = 2;
+ anim.effect.updateTiming({ iterations: 2 });
assert_equals_records(observer.takeRecords(),
[{ added: [], changed: [anim], removed: [] }],
"records after iterations is changed");
- anim.effect.timing.iterations = 2;
+ anim.effect.updateTiming({ iterations: 2 });
assert_equals_records(observer.takeRecords(),
[], "records after assigning same value");
- anim.effect.timing.iterations = 0;
+ anim.effect.updateTiming({ iterations: 0 });
assert_equals_records(observer.takeRecords(),
[{ added: [], changed: [], removed: [anim] }],
"records after animation end");
- anim.effect.timing.iterations = Infinity;
+ anim.effect.updateTiming({ iterations: Infinity });
assert_equals_records(observer.takeRecords(),
[{ added: [anim], changed: [], removed: [] }],
"records after animation restarted");
}, "change_iterations");
test(t => {
var div = addDiv(t);
var observer =
@@ -223,31 +225,31 @@ function runTest() {
aOptions.subtree);
var anim = div.animate({ opacity: [ 0, 1 ] }, 100 * MS_PER_SEC);
assert_equals_records(observer.takeRecords(),
[{ added: [anim], changed: [], removed: [] }],
"records after animation is added");
- anim.effect.timing.delay = 100;
+ anim.effect.updateTiming({ delay: 100 });
assert_equals_records(observer.takeRecords(),
[{ added: [], changed: [anim], removed: [] }],
"records after delay is changed");
- anim.effect.timing.delay = 100;
+ anim.effect.updateTiming({ delay: 100 });
assert_equals_records(observer.takeRecords(),
[], "records after assigning same value");
- anim.effect.timing.delay = -100 * MS_PER_SEC;
+ anim.effect.updateTiming({ delay: -100 * MS_PER_SEC });
assert_equals_records(observer.takeRecords(),
[{ added: [], changed: [], removed: [anim] }],
"records after animation end");
- anim.effect.timing.delay = 0;
+ anim.effect.updateTiming({ delay: 0 });
assert_equals_records(observer.takeRecords(),
[{ added: [anim], changed: [], removed: [] }],
"records after animation restarted");
}, "change_delay");
test(t => {
var div = addDiv(t);
var observer =
@@ -258,22 +260,22 @@ function runTest() {
var anim = div.animate({ opacity: [ 0, 1 ] },
{ duration: 100 * MS_PER_SEC,
easing: "steps(2, start)" });
assert_equals_records(observer.takeRecords(),
[{ added: [anim], changed: [], removed: [] }],
"records after animation is added");
- anim.effect.timing.easing = "steps(2, end)";
+ anim.effect.updateTiming({ easing: "steps(2, end)" });
assert_equals_records(observer.takeRecords(),
[{ added: [], changed: [anim], removed: [] }],
"records after easing is changed");
- anim.effect.timing.easing = "steps(2, end)";
+ anim.effect.updateTiming({ easing: "steps(2, end)" });
assert_equals_records(observer.takeRecords(),
[], "records after assigning same value");
}, "change_easing");
test(t => {
var div = addDiv(t);
var observer =
setupSynchronousObserver(t,
@@ -1520,42 +1522,44 @@ function runTest() {
var observer = setupSynchronousObserver(t, div, true);
var anim = pseudoTarget.animate({ opacity: [ 0, 1 ] }, 200 * MS_PER_SEC);
assert_equals_records(observer.takeRecords(),
[{ added: [anim], changed: [], removed: [] }],
"records after animation is added");
- anim.effect.timing.duration = 100 * MS_PER_SEC;
+ anim.effect.updateTiming({ duration: 100 * MS_PER_SEC });
assert_equals_records(observer.takeRecords(),
[{ added: [], changed: [anim], removed: [] }],
"records after duration is changed");
- anim.effect.timing.duration = 100 * MS_PER_SEC;
+ anim.effect.updateTiming({ duration: 100 * MS_PER_SEC });
assert_equals_records(observer.takeRecords(),
[], "records after assigning same value");
- anim.currentTime = anim.effect.timing.duration * 2;
+ anim.currentTime = anim.effect.getComputedTiming().duration * 2;
anim.finish();
assert_equals_records(observer.takeRecords(),
[{ added: [], changed: [], removed: [anim] }],
"records after animation end");
- anim.effect.timing.duration = anim.effect.timing.duration * 3;
+ anim.effect.updateTiming({
+ duration: anim.effect.getComputedTiming().duration * 3
+ });
assert_equals_records(observer.takeRecords(),
[{ added: [anim], changed: [], removed: [] }],
"records after animation restarted");
- anim.effect.timing.duration = "auto";
+ anim.effect.updateTiming({ duration: "auto" });
assert_equals_records(observer.takeRecords(),
[{ added: [], changed: [], removed: [anim] }],
"records after duration set \"auto\"");
- anim.effect.timing.duration = "auto";
+ anim.effect.updateTiming({ duration: "auto" });
assert_equals_records(observer.takeRecords(),
[], "records after assigning same value \"auto\"");
}, "change_duration_and_currenttime_on_pseudo_elements");
test(t => {
var div = addDiv(t);
var pseudoTarget = createPseudo(t, div, 'before');
var observer = setupSynchronousObserver(t, div, false);
--- a/dom/animation/test/chrome/test_running_on_compositor.html
+++ b/dom/animation/test/chrome/test_running_on_compositor.html
@@ -315,23 +315,23 @@ promise_test(async t => {
{ opacity: [ 0, 1 ] }, 200 * MS_PER_SEC);
await waitForPaints();
assert_animation_is_running_on_compositor(animation,
'Animation reports that it is running on the compositor');
animation.currentTime = 150 * MS_PER_SEC;
- animation.effect.timing.duration = 100 * MS_PER_SEC;
+ animation.effect.updateTiming({ duration: 100 * MS_PER_SEC });
assert_animation_is_not_running_on_compositor(animation,
'Animation reports that it is NOT running on the compositor'
+ ' when the animation is set a shorter duration than current time');
}, 'animation is immediately removed from compositor' +
- 'when timing.duration is made shorter than the current time');
+ 'when the duration is made shorter than the current time');
promise_test(async t => {
var animation = addDivAndAnimate(t,
{},
{ opacity: [ 0, 1 ] }, 100 * MS_PER_SEC);
await waitForPaints();
@@ -339,36 +339,36 @@ promise_test(async t => {
'Animation reports that it is running on the compositor');
animation.currentTime = 500 * MS_PER_SEC;
assert_animation_is_not_running_on_compositor(animation,
'Animation reports that it is NOT running on the compositor'
+ ' when finished');
- animation.effect.timing.duration = 1000 * MS_PER_SEC;
+ animation.effect.updateTiming({ duration: 1000 * MS_PER_SEC });
await waitForFrame();
assert_animation_is_running_on_compositor(animation,
'Animation reports that it is running on the compositor'
+ ' when restarted');
}, 'animation is added to compositor' +
- ' when timing.duration is made longer than the current time');
+ ' when the duration is made longer than the current time');
promise_test(async t => {
var animation = addDivAndAnimate(t,
{},
{ opacity: [ 0, 1 ] }, 100 * MS_PER_SEC);
await waitForPaints();
assert_animation_is_running_on_compositor(animation,
'Animation reports that it is running on the compositor');
- animation.effect.timing.endDelay = 100 * MS_PER_SEC;
+ animation.effect.updateTiming({ endDelay: 100 * MS_PER_SEC });
assert_animation_is_running_on_compositor(animation,
'Animation reports that it is running on the compositor'
+ ' when endDelay is changed');
animation.currentTime = 110 * MS_PER_SEC;
await waitForFrame();
@@ -383,17 +383,17 @@ promise_test(async t => {
{},
{ opacity: [ 0, 1 ] }, 100 * MS_PER_SEC);
await waitForPaints();
assert_animation_is_running_on_compositor(animation,
'Animation reports that it is running on the compositor');
- animation.effect.timing.endDelay = -200 * MS_PER_SEC;
+ animation.effect.updateTiming({ endDelay: -200 * MS_PER_SEC });
await waitForFrame();
assert_animation_is_not_running_on_compositor(animation,
'Animation reports that it is NOT running on the compositor'
+ ' when endTime is negative value');
}, 'animation is removed from compositor' +
' when endTime is negative value');
@@ -402,17 +402,17 @@ promise_test(async t => {
{},
{ opacity: [ 0, 1 ] }, 200 * MS_PER_SEC);
await waitForPaints();
assert_animation_is_running_on_compositor(animation,
'Animation reports that it is running on the compositor');
- animation.effect.timing.endDelay = -100 * MS_PER_SEC;
+ animation.effect.updateTiming({ endDelay: -100 * MS_PER_SEC });
await waitForFrame();
assert_animation_is_running_on_compositor(animation,
'Animation reports that it is running on the compositor'
+ ' when endTime is positive and endDelay is negative');
animation.currentTime = 110 * MS_PER_SEC;
await waitForFrame();
--- a/dom/animation/test/crashtests/1359658-1.html
+++ b/dom/animation/test/crashtests/1359658-1.html
@@ -18,16 +18,16 @@
const ancestor = document.getElementById('ancestor');
const target = document.getElementById('target');
document.addEventListener('DOMContentLoaded', () => {
const animation = target.animate({ color: [ 'red', 'lime' ] },
{ duration: 1000, iterations: Infinity });
requestAnimationFrame(() => {
// Tweak animation to cause animation dirty bit to be set
- animation.effect.timing.duration = 2000;
+ animation.effect.updateTiming({ duration: 2000 });
ancestor.style.display = "none";
getComputedStyle(ancestor).display;
document.documentElement.className = '';
});
});
</script>
</html>
--- a/dom/animation/test/mozilla/file_restyles.html
+++ b/dom/animation/test/mozilla/file_restyles.html
@@ -1144,21 +1144,21 @@ waitForAllPaints(() => {
// Set currentTime to a time longer than duration.
animation.currentTime = 500 * MS_PER_SEC;
// Now the animation immediately get back from compositor.
ok(!SpecialPowers.wrap(animation).isRunningOnCompositor);
// Extend the duration.
- animation.effect.timing.duration = 800 * MS_PER_SEC;
+ animation.effect.updateTiming({ duration: 800 * MS_PER_SEC });
var markers = await observeStyling(5);
is(markers.length, 1,
'Animations running on the compositor should update style ' +
- 'when timing.duration is made longer than the current time');
+ 'when duration is made longer than the current time');
await ensureElementRemoval(div);
});
add_task(async function script_animation_on_display_none_element() {
var div = addDiv(null);
var animation = div.animate({ backgroundColor: [ 'red', 'blue' ] },
100 * MS_PER_SEC);
--- a/dom/animation/test/mozilla/test_cubic_bezier_limits.html
+++ b/dom/animation/test/mozilla/test_cubic_bezier_limits.html
@@ -20,33 +20,33 @@
// We clamp +infinity or -inifinity value in floating point to
// maximum floating point value or -maxinum floating point value.
const max_float = 3.40282e+38;
test(function(t) {
var div = addDiv(t);
var anim = div.animate({ }, 100 * MS_PER_SEC);
- anim.effect.timing.easing = 'cubic-bezier(0, 1e+39, 0, 0)';
- assert_equals(anim.effect.timing.easing,
+ anim.effect.updateTiming({ easing: 'cubic-bezier(0, 1e+39, 0, 0)' });
+ assert_equals(anim.effect.getComputedTiming().easing,
'cubic-bezier(0, ' + max_float + ', 0, 0)',
'y1 control point for effect easing is out of upper boundary');
- anim.effect.timing.easing = 'cubic-bezier(0, 0, 0, 1e+39)';
- assert_equals(anim.effect.timing.easing,
+ anim.effect.updateTiming({ easing: 'cubic-bezier(0, 0, 0, 1e+39)' });
+ assert_equals(anim.effect.getComputedTiming().easing,
'cubic-bezier(0, 0, 0, ' + max_float + ')',
'y2 control point for effect easing is out of upper boundary');
- anim.effect.timing.easing = 'cubic-bezier(0, -1e+39, 0, 0)';
- assert_equals(anim.effect.timing.easing,
+ anim.effect.updateTiming({ easing: 'cubic-bezier(0, -1e+39, 0, 0)' });
+ assert_equals(anim.effect.getComputedTiming().easing,
'cubic-bezier(0, ' + -max_float + ', 0, 0)',
'y1 control point for effect easing is out of lower boundary');
- anim.effect.timing.easing = 'cubic-bezier(0, 0, 0, -1e+39)';
- assert_equals(anim.effect.timing.easing,
+ anim.effect.updateTiming({ easing: 'cubic-bezier(0, 0, 0, -1e+39)' });
+ assert_equals(anim.effect.getComputedTiming().easing,
'cubic-bezier(0, 0, 0, ' + -max_float + ')',
'y2 control point for effect easing is out of lower boundary');
}, 'Clamp y1 and y2 control point out of boundaries for effect easing' );
test(function(t) {
var div = addDiv(t);
var anim = div.animate({ }, 100 * MS_PER_SEC);
@@ -139,26 +139,26 @@ test(function(t) {
}, 'Clamp y1 and y2 control point out of boundaries for CSS transition' );
test(function(t) {
var div = addDiv(t);
var anim = div.animate({ }, { duration: 100 * MS_PER_SEC, fill: 'forwards' });
anim.pause();
// The positive steepest function on both edges.
- anim.effect.timing.easing = 'cubic-bezier(0, 1e+39, 0, 1e+39)';
+ anim.effect.updateTiming({ easing: 'cubic-bezier(0, 1e+39, 0, 1e+39)' });
assert_equals(anim.effect.getComputedTiming().progress, 0.0,
'progress on lower edge for the highest value of y1 and y2 control points');
anim.finish();
assert_equals(anim.effect.getComputedTiming().progress, 1.0,
'progress on upper edge for the highest value of y1 and y2 control points');
// The negative steepest function on both edges.
- anim.effect.timing.easing = 'cubic-bezier(0, -1e+39, 0, -1e+39)';
+ anim.effect.updateTiming({ easing: 'cubic-bezier(0, -1e+39, 0, -1e+39)' });
anim.currentTime = 0;
assert_equals(anim.effect.getComputedTiming().progress, 0.0,
'progress on lower edge for the lowest value of y1 and y2 control points');
anim.finish();
assert_equals(anim.effect.getComputedTiming().progress, 1.0,
'progress on lower edge for the lowest value of y1 and y2 control points');
--- a/dom/animation/test/mozilla/test_set_easing.html
+++ b/dom/animation/test/mozilla/test_set_easing.html
@@ -13,17 +13,17 @@
test(function(t) {
const div = document.createElement("div");
document.body.appendChild(div);
div.animate({ opacity: [0, 1] }, 100000 );
const contentScript = function() {
try {
- document.getAnimations()[0].effect.timing.easing = "linear";
+ document.getAnimations()[0].effect.updateTiming({ easing: 'linear' });
assert_true(true, 'Setting easing should not throw in sandbox');
} catch (e) {
assert_unreached('Setting easing threw ' + e);
}
};
const sandbox = new SpecialPowers.Cu.Sandbox(window);
sandbox.importFunction(document, "document");
--- a/dom/animation/test/style/test_missing-keyframe-on-compositor.html
+++ b/dom/animation/test/style/test_missing-keyframe-on-compositor.html
@@ -208,18 +208,20 @@ promise_test(t => {
var lowerAnimation;
return useTestRefreshMode(t).then(() => {
div = addDiv(t);
lowerAnimation = div.animate({ opacity: [ 1, 0.5 ] }, 100 * MS_PER_SEC);
var higherAnimation = div.animate({ opacity: 1 }, 100 * MS_PER_SEC);
return waitForPaintsFlushed();
}).then(() => {
- lowerAnimation.effect.timing.duration = 0;
- lowerAnimation.effect.timing.fill = 'forwards';
+ lowerAnimation.effect.updateTiming({
+ duration: 0,
+ fill: 'forwards',
+ });
return waitForPaintsFlushed();
}).then(() => {
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(50 * MS_PER_SEC);
var opacity =
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'opacity');
// The underlying value is the value that is filling forwards state of the
// lowerAnimation, that is 0.5.
--- a/layout/style/test/test_animations_effect_timing_duration.html
+++ b/layout/style/test/test_animations_effect_timing_duration.html
@@ -1,13 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<title>
- Test for Animation.effect.timing.duration on compositor animations
+ Test for animation.effect.updateTiming({ duration }) on compositor
+ animations
</title>
<script type="application/javascript"
src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="/tests/SimpleTest/paint_listener.js"></script>
<script type="application/javascript" src="animation_utils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
<style type="text/css">
@@ -39,17 +40,17 @@ addAsyncAnimTest(async function() {
var animation = div.animate(
[ { transform: 'translate(0px)', easing: "steps(2, start)" },
{ transform: 'translate(100px)' } ], 4000);
await waitForPaints();
advance_clock(500);
omta_is(div, "transform", { tx: 50 }, RunningOn.Compositor,
"Animation is running on compositor");
- animation.effect.timing.duration = 2000;
+ animation.effect.updateTiming({ duration: 2000 });
// Setter of timing option should set up the changes to animations for the
// next layer transaction but it won't schedule a paint immediately so we need
// to tick the refresh driver before we can wait on the next paint.
advance_clock(0);
await waitForPaints();
omta_is(div, "transform", { tx: 50 }, RunningOn.Compositor,
"Animation remains on compositor");
@@ -64,17 +65,17 @@ addAsyncAnimTest(async function() {
addAsyncAnimTest(async function() {
var [ div ] = new_div("");
var animation = div.animate(
[ { transform: 'translate(0px)', easing: "steps(2, end)" },
{ transform: 'translate(100px)' } ], 4000);
await waitForPaints();
advance_clock(1000);
- animation.effect.timing.duration = 2000;
+ animation.effect.updateTiming({ duration: 2000 });
advance_clock(0);
await waitForPaints();
omta_is(div, "transform", { tx: 50 }, RunningOn.Compositor,
"Animation is running on compositor");
done_div();
})
</script>
--- a/layout/style/test/test_animations_effect_timing_enddelay.html
+++ b/layout/style/test/test_animations_effect_timing_enddelay.html
@@ -1,12 +1,15 @@
<!DOCTYPE html>
<html>
<head>
- <title>Test for Animation.effect.endDelay on compositor animations</title>
+ <title>
+ Test for animation.effect.updateTiming({ endDelay }) on compositor
+ animations
+ </title>
<script type="application/javascript"
src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="/tests/SimpleTest/paint_listener.js"></script>
<script type="application/javascript" src="animation_utils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
<style type="text/css">
.target {
@@ -33,17 +36,17 @@ addAsyncAnimTest(async function() {
var animation = div.animate(
[ { transform: 'translate(0px)' }, { transform: 'translate(100px)' } ],
{ duration: 1000, fill: 'none' });
await waitForPaints();
advance_clock(100);
omta_is(div, "transform", { tx: 10 }, RunningOn.Compositor,
"Animation is running on compositor");
- animation.effect.timing.endDelay = 1000;
+ animation.effect.updateTiming({ endDelay: 1000 });
await waitForPaints();
omta_is(div, "transform", { tx: 10 }, RunningOn.Compositor,
"Animation remains on compositor when endDelay is changed");
advance_clock(1000);
await waitForPaints();
omta_is(div, "transform", { tx: 0 }, RunningOn.MainThread,
--- a/layout/style/test/test_animations_effect_timing_iterations.html
+++ b/layout/style/test/test_animations_effect_timing_iterations.html
@@ -1,13 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<title>
- Test for Animation.effect.timing.iterations on compositor animations
+ Test for Animation.effect.updateTiming({ iterations }) on compositor
+ animations
</title>
<script type="application/javascript"
src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="/tests/SimpleTest/paint_listener.js"></script>
<script type="application/javascript" src="animation_utils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
<style type="text/css">
@@ -42,24 +43,24 @@ addAsyncAnimTest(async function() {
{ duration: 4000,
iterations: 2
});
await waitForPaints();
advance_clock(6000);
omta_is(div, "transform", { tx: 50 }, RunningOn.Compositor,
"Animation is running on compositor");
- animation.effect.timing.iterations = 1;
+ animation.effect.updateTiming({ iterations: 1 });
advance_clock(0);
await waitForPaints();
omta_is(div, "transform", { tx: 0 }, RunningOn.MainThread,
"Animation is on MainThread");
- animation.effect.timing.iterations = 3;
+ animation.effect.updateTiming({ iterations: 3 });
advance_clock(0);
await waitForPaints();
omta_is(div, "transform", { tx: 50 }, RunningOn.Compositor,
"Animation is running again on compositor");
done_div();
});