mirror of
https://github.com/servo/servo.git
synced 2025-08-16 19:05:33 +01:00
Update web-platform-tests to revision 38bd28fe2368c650cf6e57be205cf3118dbd4997
This commit is contained in:
parent
a28e15e4ea
commit
85fe63f512
165 changed files with 2144 additions and 2644 deletions
|
@ -202,6 +202,39 @@ test(t => {
|
|||
assert_equals(anim.playState, 'running');
|
||||
}, 'Element.animate() calls play on the Animation');
|
||||
|
||||
promise_test(async t => {
|
||||
const div = createDiv(t);
|
||||
|
||||
let gotTransition = false;
|
||||
div.addEventListener('transitionrun', () => {
|
||||
gotTransition = true;
|
||||
});
|
||||
|
||||
// Setup transition start point.
|
||||
div.style.transition = 'opacity 100s';
|
||||
getComputedStyle(div).opacity;
|
||||
|
||||
// Update specified style but don't flush style.
|
||||
div.style.opacity = '0.5';
|
||||
|
||||
// Trigger a new animation at the same time.
|
||||
const anim = div.animate({ opacity: [0, 1] }, 100 * MS_PER_SEC);
|
||||
|
||||
// If Element.animate() produces a style change event it will have triggered
|
||||
// a transition.
|
||||
//
|
||||
// If it does NOT produce a style change event, the animation will override
|
||||
// the before-change style and after-change style such that a transition is
|
||||
// never triggered.
|
||||
|
||||
// Wait for the animation to start and then for one more animation
|
||||
// frame to give the transitionrun event a chance to be dispatched.
|
||||
await anim.ready;
|
||||
await waitForAnimationFrames(1);
|
||||
|
||||
assert_false(gotTransition, 'A transition should NOT have been triggered');
|
||||
}, 'Element.animate() does NOT trigger a style change event');
|
||||
|
||||
// Tests on CSSPseudoElement
|
||||
|
||||
test(t => {
|
||||
|
|
|
@ -197,5 +197,33 @@ test(t => {
|
|||
}, 'Returns animations based on dynamic changes to individual'
|
||||
+ ' animations\' current time');
|
||||
|
||||
promise_test(async t => {
|
||||
const div = createDiv(t);
|
||||
const watcher = EventWatcher(t, div, 'transitionrun');
|
||||
|
||||
// Create a covering animation to prevent transitions from firing after
|
||||
// calling getAnimations().
|
||||
const coveringAnimation = new Animation(
|
||||
new KeyframeEffect(div, { opacity: [0, 1] }, 100 * MS_PER_SEC)
|
||||
);
|
||||
|
||||
// Setup transition start point.
|
||||
div.style.transition = 'opacity 100s';
|
||||
getComputedStyle(div).opacity;
|
||||
|
||||
// Update specified style but don't flush style.
|
||||
div.style.opacity = '0.5';
|
||||
|
||||
// Fetch animations
|
||||
div.getAnimations();
|
||||
|
||||
// Play the covering animation to ensure that only the call to
|
||||
// getAnimations() has a chance to trigger transitions.
|
||||
coveringAnimation.play();
|
||||
|
||||
// If getAnimations() flushed style, we should get a transitionrun event.
|
||||
await watcher.wait_for('transitionrun');
|
||||
}, 'Triggers a style change event');
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -0,0 +1,307 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>Animation interface: style change events</title>
|
||||
<link rel="help"
|
||||
href="https://drafts.csswg.org/web-animations-1/#model-liveness">
|
||||
<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';
|
||||
|
||||
// Test that each property defined in the Animation interface does not produce
|
||||
// style change events.
|
||||
//
|
||||
// There are two types of tests:
|
||||
//
|
||||
// PlayAnimationTest
|
||||
//
|
||||
// For properties that are able to cause the Animation to start affecting
|
||||
// the target CSS property.
|
||||
//
|
||||
// This function takes either:
|
||||
//
|
||||
// (a) A function that simply "plays" that passed-in Animation (i.e. makes
|
||||
// it start affecting the target CSS property.
|
||||
//
|
||||
// (b) An object with the following format:
|
||||
//
|
||||
// {
|
||||
// setup: elem => { /* return Animation */ }
|
||||
// test: animation => { /* play |animation| */ }
|
||||
// }
|
||||
//
|
||||
// If the latter form is used, the setup function should return an Animation
|
||||
// that does NOT (yet) have an in-effect AnimationEffect that affects the
|
||||
// 'opacity' property. Otherwise, the transition we use to detect if a style
|
||||
// change event has occurred will never have a chance to be triggered (since
|
||||
// the animated style will clobber both before-change and after-change
|
||||
// style).
|
||||
//
|
||||
// Examples of valid animations:
|
||||
//
|
||||
// - An animation that is idle, or finished but without a fill mode.
|
||||
// - An animation with an effect that that does not affect opacity.
|
||||
//
|
||||
// UsePropertyTest
|
||||
//
|
||||
// For properties that cannot cause the Animation to start affecting the
|
||||
// target CSS property.
|
||||
//
|
||||
// The shape of the parameter to the UsePropertyTest is identical to the
|
||||
// PlayAnimationTest. The only difference is that the function (or 'test'
|
||||
// function of the object format is used) does not need to play the
|
||||
// animation, but simply needs to get/set the property under test.
|
||||
|
||||
const PlayAnimationTest = testFuncOrObj => {
|
||||
let test, setup;
|
||||
|
||||
if (typeof testFuncOrObj === 'function') {
|
||||
test = testFuncOrObj;
|
||||
} else {
|
||||
test = testFuncOrObj.test;
|
||||
if (typeof testFuncOrObj.setup === 'function') {
|
||||
setup = testFuncOrObj.setup;
|
||||
}
|
||||
}
|
||||
|
||||
if (!setup) {
|
||||
setup = elem =>
|
||||
new Animation(
|
||||
new KeyframeEffect(elem, { opacity: [0, 1] }, 100 * MS_PER_SEC)
|
||||
);
|
||||
}
|
||||
|
||||
return { test, setup };
|
||||
};
|
||||
|
||||
const UsePropertyTest = testFuncOrObj => {
|
||||
const { setup, test } = PlayAnimationTest(testFuncOrObj);
|
||||
|
||||
let coveringAnimation;
|
||||
return {
|
||||
setup: elem => {
|
||||
coveringAnimation = new Animation(
|
||||
new KeyframeEffect(elem, { opacity: [0, 1] }, 100 * MS_PER_SEC)
|
||||
);
|
||||
|
||||
return setup(elem);
|
||||
},
|
||||
test: animation => {
|
||||
test(animation);
|
||||
coveringAnimation.play();
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const tests = {
|
||||
id: UsePropertyTest(animation => (animation.id = 'yer')),
|
||||
get effect() {
|
||||
let effect;
|
||||
return PlayAnimationTest({
|
||||
setup: elem => {
|
||||
// Create a new effect and animation but don't associate them yet
|
||||
effect = new KeyframeEffect(
|
||||
elem,
|
||||
{ opacity: [0.5, 1] },
|
||||
100 * MS_PER_SEC
|
||||
);
|
||||
return elem.animate(null, 100 * MS_PER_SEC);
|
||||
},
|
||||
test: animation => {
|
||||
// Read the effect
|
||||
animation.effect;
|
||||
|
||||
// Assign the effect
|
||||
animation.effect = effect;
|
||||
},
|
||||
});
|
||||
},
|
||||
timeline: PlayAnimationTest({
|
||||
setup: elem => {
|
||||
// Create a new animation with no timeline
|
||||
const animation = new Animation(
|
||||
new KeyframeEffect(elem, { opacity: [0.5, 1] }, 100 * MS_PER_SEC),
|
||||
null
|
||||
);
|
||||
// Set the hold time so that once we assign a timeline it will begin to
|
||||
// play.
|
||||
animation.currentTime = 0;
|
||||
|
||||
return animation;
|
||||
},
|
||||
test: animation => {
|
||||
// Get the timeline
|
||||
animation.timeline;
|
||||
|
||||
// Play the animation by setting the timeline
|
||||
animation.timeline = document.timeline;
|
||||
},
|
||||
}),
|
||||
startTime: PlayAnimationTest(animation => {
|
||||
// Get the startTime
|
||||
animation.startTime;
|
||||
|
||||
// Play the animation by setting the startTime
|
||||
animation.startTime = document.timeline.currentTime;
|
||||
}),
|
||||
currentTime: PlayAnimationTest(animation => {
|
||||
// Get the currentTime
|
||||
animation.currentTime;
|
||||
|
||||
// Play the animation by setting the currentTime
|
||||
animation.currentTime = 0;
|
||||
}),
|
||||
playbackRate: UsePropertyTest(animation => {
|
||||
// Get and set the playbackRate
|
||||
animation.playbackRate = animation.playbackRate * 1.1;
|
||||
}),
|
||||
playState: UsePropertyTest(animation => animation.playState),
|
||||
pending: UsePropertyTest(animation => animation.pending),
|
||||
ready: UsePropertyTest(animation => animation.ready),
|
||||
finished: UsePropertyTest(animation => {
|
||||
// Get the finished Promise
|
||||
animation.finished;
|
||||
}),
|
||||
onfinish: UsePropertyTest(animation => {
|
||||
// Get the onfinish member
|
||||
animation.onfinish;
|
||||
|
||||
// Set the onfinish menber
|
||||
animation.onfinish = () => {};
|
||||
}),
|
||||
oncancel: UsePropertyTest(animation => {
|
||||
// Get the oncancel member
|
||||
animation.oncancel;
|
||||
|
||||
// Set the oncancel menber
|
||||
animation.oncancel = () => {};
|
||||
}),
|
||||
cancel: UsePropertyTest({
|
||||
// Animate _something_ just to make the test more interesting
|
||||
setup: elem => elem.animate({ color: ['green', 'blue'] }, 100 * MS_PER_SEC),
|
||||
test: animation => {
|
||||
animation.cancel();
|
||||
},
|
||||
}),
|
||||
finish: PlayAnimationTest({
|
||||
setup: elem =>
|
||||
new Animation(
|
||||
new KeyframeEffect(
|
||||
elem,
|
||||
{ opacity: [0.5, 1] },
|
||||
{
|
||||
duration: 100 * MS_PER_SEC,
|
||||
fill: 'both',
|
||||
}
|
||||
)
|
||||
),
|
||||
test: animation => {
|
||||
animation.finish();
|
||||
},
|
||||
}),
|
||||
play: PlayAnimationTest(animation => animation.play()),
|
||||
pause: PlayAnimationTest(animation => {
|
||||
// Pause animation -- this will cause the animation to transition from the
|
||||
// 'idle' state to the 'paused' (but pending) state with hold time zero.
|
||||
animation.pause();
|
||||
}),
|
||||
updatePlaybackRate: UsePropertyTest(animation => {
|
||||
animation.updatePlaybackRate(1.1);
|
||||
}),
|
||||
// We would like to use a PlayAnimationTest here but reverse() is async and
|
||||
// doesn't start applying its result until the animation is ready.
|
||||
reverse: UsePropertyTest({
|
||||
setup: elem => {
|
||||
// Create a new animation and seek it to the end so that it no longer
|
||||
// affects style (since it has no fill mode).
|
||||
const animation = elem.animate({ opacity: [0.5, 1] }, 100 * MS_PER_SEC);
|
||||
animation.finish();
|
||||
return animation;
|
||||
},
|
||||
test: animation => {
|
||||
animation.reverse();
|
||||
},
|
||||
}),
|
||||
get ['Animation constructor']() {
|
||||
let originalElem;
|
||||
return UsePropertyTest({
|
||||
setup: elem => {
|
||||
originalElem = elem;
|
||||
// Return a dummy animation so the caller has something to wait on
|
||||
return elem.animate(null);
|
||||
},
|
||||
test: () =>
|
||||
new Animation(
|
||||
new KeyframeEffect(
|
||||
originalElem,
|
||||
{ opacity: [0.5, 1] },
|
||||
100 * MS_PER_SEC
|
||||
)
|
||||
),
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
// Check that each enumerable property and the constructor follow the
|
||||
// expected behavior with regards to triggering style change events.
|
||||
const properties = [
|
||||
...Object.keys(Animation.prototype),
|
||||
'Animation constructor',
|
||||
];
|
||||
|
||||
test(() => {
|
||||
for (const property of Object.keys(tests)) {
|
||||
assert_in_array(
|
||||
property,
|
||||
properties,
|
||||
`Test property '${property}' should be one of the properties on ` +
|
||||
' Animation'
|
||||
);
|
||||
}
|
||||
}, 'All property keys are recognized');
|
||||
|
||||
for (const key of properties) {
|
||||
promise_test(async t => {
|
||||
assert_own_property(tests, key, `Should have a test for '${key}' property`);
|
||||
const { setup, test } = tests[key];
|
||||
|
||||
// Setup target element
|
||||
const div = createDiv(t);
|
||||
let gotTransition = false;
|
||||
div.addEventListener('transitionrun', () => {
|
||||
gotTransition = true;
|
||||
});
|
||||
|
||||
// Setup animation
|
||||
const animation = setup(div);
|
||||
|
||||
// Setup transition start point
|
||||
div.style.transition = 'opacity 100s';
|
||||
getComputedStyle(div).opacity;
|
||||
|
||||
// Update specified style but don't flush
|
||||
div.style.opacity = '0.5';
|
||||
|
||||
// Trigger the property
|
||||
test(animation);
|
||||
|
||||
// If the test function produced a style change event it will have triggered
|
||||
// a transition.
|
||||
|
||||
// Wait for the animation to start and then for at least one animation
|
||||
// frame to give the transitionrun event a chance to be dispatched.
|
||||
assert_true(
|
||||
typeof animation.ready !== 'undefined',
|
||||
'Should have a valid animation to wait on'
|
||||
);
|
||||
await animation.ready;
|
||||
await waitForAnimationFrames(1);
|
||||
|
||||
assert_false(gotTransition, 'A transition should NOT have been triggered');
|
||||
}, `Animation.${key} does NOT trigger a style change event`);
|
||||
}
|
||||
</script>
|
||||
</body>
|
|
@ -64,26 +64,56 @@ test(t => {
|
|||
'elements in this document');
|
||||
}, 'Test document.getAnimations with null target');
|
||||
|
||||
async_test(t => {
|
||||
promise_test(async t => {
|
||||
const iframe = document.createElement('iframe');
|
||||
|
||||
iframe.addEventListener("load", t.step_func_done(function() {
|
||||
const div = createDiv(t, iframe.contentDocument)
|
||||
const effect = new KeyframeEffect(div, null, 100 * MS_PER_SEC);
|
||||
const anim = new Animation(effect, document.timeline);
|
||||
anim.play();
|
||||
|
||||
// The animation's timeline is from the main document, but the effect's
|
||||
// target element is part of the iframe document and that is what matters
|
||||
// for getAnimations.
|
||||
assert_equals(document.getAnimations().length, 0);
|
||||
assert_equals(iframe.contentDocument.getAnimations().length, 1);
|
||||
anim.finish();
|
||||
}));
|
||||
const eventWatcher = new EventWatcher(t, iframe, ['load']);
|
||||
|
||||
document.body.appendChild(iframe);
|
||||
t.add_cleanup(function() { document.body.removeChild(iframe); });
|
||||
t.add_cleanup(() => { document.body.removeChild(iframe); });
|
||||
|
||||
await eventWatcher.wait_for('load');
|
||||
|
||||
const div = createDiv(t, iframe.contentDocument)
|
||||
const effect = new KeyframeEffect(div, null, 100 * MS_PER_SEC);
|
||||
const anim = new Animation(effect, document.timeline);
|
||||
anim.play();
|
||||
|
||||
// The animation's timeline is from the main document, but the effect's
|
||||
// target element is part of the iframe document and that is what matters
|
||||
// for getAnimations.
|
||||
assert_equals(document.getAnimations().length, 0);
|
||||
assert_equals(iframe.contentDocument.getAnimations().length, 1);
|
||||
anim.finish();
|
||||
}, 'Test document.getAnimations for elements inside same-origin iframes');
|
||||
|
||||
promise_test(async t => {
|
||||
const div = createDiv(t);
|
||||
const watcher = EventWatcher(t, div, 'transitionrun');
|
||||
|
||||
// Create a covering animation to prevent transitions from firing after
|
||||
// calling getAnimations().
|
||||
const coveringAnimation = new Animation(
|
||||
new KeyframeEffect(div, { opacity: [0, 1] }, 100 * MS_PER_SEC)
|
||||
);
|
||||
|
||||
// Setup transition start point.
|
||||
div.style.transition = 'opacity 100s';
|
||||
getComputedStyle(div).opacity;
|
||||
|
||||
// Update specified style but don't flush style.
|
||||
div.style.opacity = '0.5';
|
||||
|
||||
// Fetch animations
|
||||
document.getAnimations();
|
||||
|
||||
// Play the covering animation to ensure that only the call to
|
||||
// getAnimations() has a chance to trigger transitions.
|
||||
coveringAnimation.play();
|
||||
|
||||
// If getAnimations() flushed style, we should get a transitionrun event.
|
||||
await watcher.wait_for('transitionrun');
|
||||
}, 'Triggers a style change event');
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>DocumentTimeline interface: style change events</title>
|
||||
<link rel="help"
|
||||
href="https://drafts.csswg.org/web-animations-1/#model-liveness">
|
||||
<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';
|
||||
|
||||
// NOTE: If more members are added to the DocumentTimeline interface it might be
|
||||
// better to rewrite these test in the same style as:
|
||||
//
|
||||
// web-animations/interfaces/Animation/style-change-events.html
|
||||
// web-animations/interfaces/KeyframeEffect/style-change-events.html
|
||||
|
||||
promise_test(async t => {
|
||||
const div = createDiv(t);
|
||||
|
||||
let gotTransition = false;
|
||||
div.addEventListener('transitionrun', () => {
|
||||
gotTransition = true;
|
||||
});
|
||||
|
||||
// Create a covering animation but don't play it yet.
|
||||
const coveringAnimation = new Animation(
|
||||
new KeyframeEffect(div, { opacity: [0, 1] }, 100 * MS_PER_SEC)
|
||||
);
|
||||
|
||||
// Setup transition start point.
|
||||
div.style.transition = 'opacity 100s';
|
||||
getComputedStyle(div).opacity;
|
||||
|
||||
// Update specified style but don't flush style.
|
||||
div.style.opacity = '0.5';
|
||||
|
||||
// Get the currentTime
|
||||
document.timeline.currentTime;
|
||||
|
||||
// Run the covering animation
|
||||
coveringAnimation.play();
|
||||
|
||||
// If getting DocumentTimeline.currentTime produced a style change event it
|
||||
// will trigger a transition. Otherwise, the covering animation will cause
|
||||
// the before-change and after-change styles to be the same such that no
|
||||
// transition is triggered on the next restyle.
|
||||
|
||||
// Wait for a couple of animation frames to give the transitionrun event
|
||||
// a chance to be dispatched.
|
||||
await waitForAnimationFrames(2);
|
||||
|
||||
assert_false(gotTransition, 'A transition should NOT have been triggered');
|
||||
}, 'DocumentTimeline.currentTime does NOT trigger a style change event');
|
||||
|
||||
promise_test(async t => {
|
||||
const div = createDiv(t);
|
||||
|
||||
let gotTransition = false;
|
||||
div.addEventListener('transitionrun', () => {
|
||||
gotTransition = true;
|
||||
});
|
||||
|
||||
// Create a covering animation but don't play it yet.
|
||||
const coveringAnimation = new Animation(
|
||||
new KeyframeEffect(div, { opacity: [0, 1] }, 100 * MS_PER_SEC)
|
||||
);
|
||||
|
||||
// Setup transition start point.
|
||||
div.style.transition = 'opacity 100s';
|
||||
getComputedStyle(div).opacity;
|
||||
|
||||
// Update specified style but don't flush style.
|
||||
div.style.opacity = '0.5';
|
||||
|
||||
// Create a new DocumentTimeline
|
||||
new DocumentTimeline();
|
||||
|
||||
// Run the covering animation
|
||||
coveringAnimation.play();
|
||||
|
||||
// Wait for a couple of animation frames to give the transitionrun event
|
||||
// a chance to be dispatched.
|
||||
await waitForAnimationFrames(2);
|
||||
|
||||
assert_false(gotTransition, 'A transition should NOT have been triggered');
|
||||
}, 'DocumentTimeline constructor does NOT trigger a style change event');
|
||||
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,233 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>KeyframeEffect interface: style change events</title>
|
||||
<link rel="help"
|
||||
href="https://drafts.csswg.org/web-animations-1/#model-liveness">
|
||||
<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';
|
||||
|
||||
// Test that each property defined in the KeyframeEffect interface does not
|
||||
// produce style change events.
|
||||
//
|
||||
// There are two types of tests:
|
||||
//
|
||||
// MakeInEffectTest
|
||||
//
|
||||
// For properties that are able to cause the KeyframeEffect to start
|
||||
// affecting the CSS 'opacity' property.
|
||||
//
|
||||
// This function takes either:
|
||||
//
|
||||
// (a) A function that makes the passed-in KeyframeEffect affect the
|
||||
// 'opacity' property.
|
||||
//
|
||||
// (b) An object with the following format:
|
||||
//
|
||||
// {
|
||||
// setup: elem => { /* return Animation */ }
|
||||
// test: effect => { /* make |effect| affect 'opacity' */ }
|
||||
// }
|
||||
//
|
||||
// If the latter form is used, the setup function should return an Animation
|
||||
// whose KeyframeEffect does NOT (yet) affect the 'opacity' property (or is
|
||||
// NOT yet in-effect). Otherwise, the transition we use to detect if a style
|
||||
// change event has occurred will never have a chance to be triggered (since
|
||||
// the animated style will clobber both before-change and after-change
|
||||
// style).
|
||||
//
|
||||
// UsePropertyTest
|
||||
//
|
||||
// For properties that cannot cause the KeyframeEffect to start affecting the
|
||||
// CSS 'opacity' property.
|
||||
//
|
||||
// The shape of the parameter to the UsePropertyTest is identical to the
|
||||
// MakeInEffectTest. The only difference is that the function (or 'test'
|
||||
// function of the object format is used) does not need to make the
|
||||
// KeyframeEffect affect the CSS 'opacity' property, but simply needs to
|
||||
// get/set the property under test.
|
||||
|
||||
const MakeInEffectTest = testFuncOrObj => {
|
||||
let test, setup;
|
||||
|
||||
if (typeof testFuncOrObj === 'function') {
|
||||
test = testFuncOrObj;
|
||||
} else {
|
||||
test = testFuncOrObj.test;
|
||||
if (typeof testFuncOrObj.setup === 'function') {
|
||||
setup = testFuncOrObj.setup;
|
||||
}
|
||||
}
|
||||
|
||||
if (!setup) {
|
||||
setup = elem =>
|
||||
elem.animate({ color: ['blue', 'green'] }, 100 * MS_PER_SEC);
|
||||
}
|
||||
|
||||
return { test, setup };
|
||||
};
|
||||
|
||||
const UsePropertyTest = testFuncOrObj => {
|
||||
const { test, setup } = MakeInEffectTest(testFuncOrObj);
|
||||
|
||||
let coveringAnimation;
|
||||
return {
|
||||
setup: elem => {
|
||||
coveringAnimation = new Animation(
|
||||
new KeyframeEffect(elem, { opacity: [0, 1] }, 100 * MS_PER_SEC)
|
||||
);
|
||||
|
||||
return setup(elem);
|
||||
},
|
||||
test: effect => {
|
||||
test(effect);
|
||||
coveringAnimation.play();
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const tests = {
|
||||
getTiming: UsePropertyTest(effect => effect.getTiming()),
|
||||
getComputedTiming: UsePropertyTest(effect => effect.getComputedTiming()),
|
||||
updateTiming: MakeInEffectTest({
|
||||
// Initially put the effect in its before phase (with no fill mode)...
|
||||
setup: elem =>
|
||||
elem.animate(
|
||||
{ opacity: [0.5, 1] },
|
||||
{
|
||||
duration: 100 * MS_PER_SEC,
|
||||
delay: 100 * MS_PER_SEC,
|
||||
}
|
||||
),
|
||||
// ... so that when the delay is removed, it begins to affect the opacity.
|
||||
test: effect => {
|
||||
effect.updateTiming({ delay: 0 });
|
||||
},
|
||||
}),
|
||||
get target() {
|
||||
let targetElem;
|
||||
return MakeInEffectTest({
|
||||
setup: (elem, t) => {
|
||||
targetElem = elem;
|
||||
const targetB = createDiv(t);
|
||||
return targetB.animate({ opacity: [0.5, 1] }, 100 * MS_PER_SEC);
|
||||
},
|
||||
test: effect => {
|
||||
effect.target = targetElem;
|
||||
},
|
||||
});
|
||||
},
|
||||
iterationComposite: UsePropertyTest(effect => {
|
||||
// Get iterationComposite
|
||||
effect.iterationComposite;
|
||||
|
||||
// Set iterationComposite
|
||||
effect.iterationComposite = 'accumulate';
|
||||
}),
|
||||
composite: UsePropertyTest(effect => {
|
||||
// Get composite
|
||||
effect.composite;
|
||||
|
||||
// Set composite
|
||||
effect.composite = 'add';
|
||||
}),
|
||||
getKeyframes: UsePropertyTest(effect => effect.getKeyframes()),
|
||||
setKeyframes: MakeInEffectTest(effect =>
|
||||
effect.setKeyframes({ opacity: [0.5, 1] })
|
||||
),
|
||||
get ['KeyframeEffect constructor']() {
|
||||
let originalElem;
|
||||
let animation;
|
||||
return UsePropertyTest({
|
||||
setup: elem => {
|
||||
originalElem = elem;
|
||||
// Return a dummy animation so the caller has something to wait on
|
||||
return elem.animate(null);
|
||||
},
|
||||
test: () =>
|
||||
new KeyframeEffect(
|
||||
originalElem,
|
||||
{ opacity: [0.5, 1] },
|
||||
100 * MS_PER_SEC
|
||||
),
|
||||
});
|
||||
},
|
||||
get ['KeyframeEffect copy constructor']() {
|
||||
let effectToClone;
|
||||
return UsePropertyTest({
|
||||
setup: elem => {
|
||||
effectToClone = new KeyframeEffect(
|
||||
elem,
|
||||
{ opacity: [0.5, 1] },
|
||||
100 * MS_PER_SEC
|
||||
);
|
||||
// Return a dummy animation so the caller has something to wait on
|
||||
return elem.animate(null);
|
||||
},
|
||||
test: () => new KeyframeEffect(effectToClone),
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
// Check that each enumerable property and the constructors follow the
|
||||
// expected behavior with regards to triggering style change events.
|
||||
const properties = [
|
||||
...Object.keys(AnimationEffect.prototype),
|
||||
...Object.keys(KeyframeEffect.prototype),
|
||||
'KeyframeEffect constructor',
|
||||
'KeyframeEffect copy constructor',
|
||||
];
|
||||
|
||||
test(() => {
|
||||
for (const property of Object.keys(tests)) {
|
||||
assert_in_array(
|
||||
property,
|
||||
properties,
|
||||
`Test property '${property}' should be one of the properties on ` +
|
||||
' KeyframeEffect'
|
||||
);
|
||||
}
|
||||
}, 'All property keys are recognized');
|
||||
|
||||
for (const key of properties) {
|
||||
promise_test(async t => {
|
||||
assert_own_property(tests, key, `Should have a test for '${key}' property`);
|
||||
const { setup, test } = tests[key];
|
||||
|
||||
// Setup target element
|
||||
const div = createDiv(t);
|
||||
let gotTransition = false;
|
||||
div.addEventListener('transitionrun', () => {
|
||||
gotTransition = true;
|
||||
});
|
||||
|
||||
// Setup animation
|
||||
const animation = setup(div, t);
|
||||
|
||||
// Setup transition start point
|
||||
div.style.transition = 'opacity 100s';
|
||||
getComputedStyle(div).opacity;
|
||||
|
||||
// Update specified style but don't flush
|
||||
div.style.opacity = '0.5';
|
||||
|
||||
// Trigger the property
|
||||
test(animation.effect);
|
||||
|
||||
// If the test function produced a style change event it will have triggered
|
||||
// a transition.
|
||||
|
||||
// Wait for the animation to start and then for at least one animation
|
||||
// frame to give the transitionrun event a chance to be dispatched.
|
||||
await animation.ready;
|
||||
await waitForAnimationFrames(1);
|
||||
|
||||
assert_false(gotTransition, 'A transition should NOT have been triggered');
|
||||
}, `KeyframeEffect.${key} does NOT trigger a style change event`);
|
||||
}
|
||||
</script>
|
||||
</body>
|
Loading…
Add table
Add a link
Reference in a new issue