Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

<!doctype html>
<html>
<!--
-->
<head>
<meta charset=utf-8>
<title>Test for CSS Animation and Transition event handler
attributes. (Bug 911987)</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="animation_utils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<style>
@keyframes anim { to { margin-left: 100px } }
</style>
</head>
<body>
<a target="_blank"
911987</a>
<div id="display"></div>
<pre id="test">
<script type="application/javascript">
'use strict';
// Create the div element with event handlers.
// We need two elements: one with the content attribute speficied and one
// with the IDL attribute specified since we can't set these independently.
function createAndRegisterTargets(eventAttributes) {
var displayElement = document.getElementById('display');
var contentAttributeElement = document.createElement("div");
var idlAttributeElement = document.createElement("div");
displayElement.appendChild(contentAttributeElement);
displayElement.appendChild(idlAttributeElement);
// Add handlers
eventAttributes.forEach(event => {
contentAttributeElement.setAttribute(event, 'handleEvent(event);');
contentAttributeElement.handlerType = 'content attribute';
idlAttributeElement[event] = handleEvent;
idlAttributeElement.handlerType = 'IDL attribute';
});
return [contentAttributeElement, idlAttributeElement];
}
function handleEvent(event) {
if (event.target.receivedEventType) {
ok(false, `Received ${event.type} event, but this element have previous `
`received event '${event.target.receivedEventType}'.`);
return;
}
event.target.receivedEventType = event.type;
}
function checkReceivedEvents(eventType, elements) {
elements.forEach(element => {
is(element.receivedEventType, eventType,
`Expected to receive '${eventType}', got
'${element.receivedEventType}', for event handler registered
using ${element.handlerType}`);
element.receivedEventType = undefined;
});
}
// Take over the refresh driver right from the start.
advance_clock(0);
// 1a. Test CSS Animation event handlers (without animationcancel)
var targets = createAndRegisterTargets([ 'onanimationstart',
'onanimationiteration',
'onanimationend',
'onanimationcancel']);
targets.forEach(div => {
div.setAttribute('style', 'animation: anim 100ms 2');
getComputedStyle(div).animationName; // flush
});
advance_clock(0);
checkReceivedEvents("animationstart", targets);
advance_clock(100);
checkReceivedEvents("animationiteration", targets);
advance_clock(200);
checkReceivedEvents("animationend", targets);
targets.forEach(div => { div.remove(); });
// 1b. Test CSS Animation cancel event handler
var targets = createAndRegisterTargets([ 'onanimationcancel' ]);
targets.forEach(div => {
div.setAttribute('style', 'animation: anim 100ms 2 200ms');
getComputedStyle(div).animationName; // flush
});
advance_clock(200);
targets.forEach(div => {
div.style.display = "none"
getComputedStyle(div).display; // flush
});
advance_clock(0);
checkReceivedEvents("animationcancel", targets);
advance_clock(200);
targets.forEach(div => { div.remove(); });
// 2a. Test CSS Transition event handlers (without transitioncancel)
var targets = createAndRegisterTargets([ 'ontransitionrun',
'ontransitionstart',
'ontransitionend',
'ontransitioncancel' ]);
targets.forEach(div => {
div.style.transition = 'margin-left 100ms 200ms';
getComputedStyle(div).marginLeft; // flush
div.style.marginLeft = "200px";
getComputedStyle(div).marginLeft; // flush
});
advance_clock(0);
checkReceivedEvents("transitionrun", targets);
advance_clock(200);
checkReceivedEvents("transitionstart", targets);
advance_clock(100);
checkReceivedEvents("transitionend", targets);
targets.forEach(div => { div.remove(); });
// 2b. Test CSS Transition cancel event handler.
var targets = createAndRegisterTargets([ 'ontransitioncancel' ]);
targets.forEach(div => {
div.style.transition = 'margin-left 100ms 200ms';
getComputedStyle(div).marginLeft; // flush
div.style.marginLeft = "200px";
getComputedStyle(div).marginLeft; // flush
});
advance_clock(200);
targets.forEach(div => {
div.style.display = "none"
});
getComputedStyle(targets[0]).display; // flush
advance_clock(0);
checkReceivedEvents("transitioncancel", targets);
advance_clock(100);
targets.forEach( div => { is(div.receivedEventType, undefined); });
targets.forEach(div => { div.remove(); });
// 3. Test prefixed CSS Animation event handlers.
var targets = createAndRegisterTargets([ 'onwebkitanimationstart',
'onwebkitanimationiteration',
'onwebkitanimationend' ]);
targets.forEach(div => {
div.setAttribute('style', 'animation: anim 100ms 2');
getComputedStyle(div).animationName; // flush
});
advance_clock(0);
checkReceivedEvents("webkitAnimationStart", targets);
advance_clock(100);
checkReceivedEvents("webkitAnimationIteration", targets);
advance_clock(200);
checkReceivedEvents("webkitAnimationEnd", targets);
targets.forEach(div => { div.remove(); });
// 4. Test prefixed CSS Transition event handlers.
advance_clock(0);
var targets = createAndRegisterTargets([ 'onwebkittransitionend' ]);
targets.forEach(div => {
div.style.transition = 'margin-left 100ms';
getComputedStyle(div).marginLeft; // flush
div.style.marginLeft = "200px";
getComputedStyle(div).marginLeft; // flush
});
advance_clock(100);
checkReceivedEvents("webkitTransitionEnd", targets);
targets.forEach(div => { div.remove(); });
SpecialPowers.DOMWindowUtils.restoreNormalRefresh();
</script>
</body>
</html>