зеркало из https://github.com/mozilla/gecko-dev.git
1229 строки
50 KiB
HTML
1229 строки
50 KiB
HTML
<!DOCTYPE HTML>
|
|
<html>
|
|
<!--
|
|
https://bugzilla.mozilla.org/show_bug.cgi?id=435442
|
|
-->
|
|
<head>
|
|
<title>Test for css3-animations (Bug 435442)</title>
|
|
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
|
<script type="application/javascript" 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 type="text/css">
|
|
@-moz-keyframes anim1 {
|
|
0% { margin-left: 0px }
|
|
50% { margin-left: 80px }
|
|
100% { margin-left: 100px }
|
|
}
|
|
@-moz-keyframes anim2 {
|
|
from { margin-right: 0 } to { margin-right: 100px }
|
|
}
|
|
@-moz-keyframes anim3 {
|
|
from { margin-top: 0 } to { margin-top: 100px }
|
|
}
|
|
@-moz-keyframes anim4 {
|
|
from { margin-bottom: 0 } to { margin-bottom: 100px }
|
|
}
|
|
@-moz-keyframes anim5 {
|
|
from { margin-left: 0 } to { margin-left: 100px }
|
|
}
|
|
|
|
@-moz-keyframes kf1 {
|
|
50% { margin-top: 50px }
|
|
to { margin-top: 150px }
|
|
}
|
|
@-moz-keyframes kf2 {
|
|
from { margin-top: 150px }
|
|
50% { margin-top: 50px }
|
|
}
|
|
@-moz-keyframes kf3 {
|
|
25% { margin-top: 100px }
|
|
}
|
|
@-moz-keyframes kf4 {
|
|
to, from { display: inline; margin-top: 37px }
|
|
}
|
|
@-moz-keyframes kf_cascade1 {
|
|
from { padding-top: 50px }
|
|
50%, from { padding-top: 30px } /* wins: 0% */
|
|
75%, 85%, 50% { padding-top: 20px } /* wins: 75%, 50% */
|
|
100%, 85% { padding-top: 70px } /* wins: 100% */
|
|
85.1% { padding-top: 60px } /* wins: 85.1% */
|
|
85% { padding-top: 30px } /* wins: 85% */
|
|
}
|
|
@-moz-keyframes kf_cascade2 { from, to { margin-top: 100px } }
|
|
@-moz-keyframes kf_cascade2 { from, to { margin-left: 200px } }
|
|
@-moz-keyframes kf_cascade2 { from, to { margin-left: 300px } }
|
|
@-moz-keyframes kf_tf1 {
|
|
0% { padding-bottom: 20px; -moz-animation-timing-function: ease }
|
|
25% { padding-bottom: 60px; }
|
|
50% { padding-bottom: 160px; -moz-animation-timing-function: steps(5) }
|
|
75% { padding-bottom: 120px; -moz-animation-timing-function: linear }
|
|
100% { padding-bottom: 20px; -moz-animation-timing-function: ease-out }
|
|
}
|
|
|
|
#withbefore::before, #withafter::after {
|
|
content: "";
|
|
-moz-animation: anim2 1s linear alternate infinite;
|
|
}
|
|
|
|
@-moz-keyframes multiprop {
|
|
0% {
|
|
padding-top: 10px; padding-left: 30px;
|
|
-moz-animation-timing-function: ease;
|
|
}
|
|
25% {
|
|
padding-left: 50px;
|
|
-moz-animation-timing-function: ease-out;
|
|
}
|
|
50% {
|
|
padding-top: 40px;
|
|
}
|
|
75% {
|
|
padding-top: 80px; padding-left: 60px;
|
|
-moz-animation-timing-function: ease-in;
|
|
}
|
|
}
|
|
|
|
@-moz-keyframes uaoverride {
|
|
0%, 100% { line-height: 3; margin-top: 20px }
|
|
50% { margin-top: 120px }
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=435442">Mozilla Bug 435442</a>
|
|
<div id="display"></div>
|
|
<pre id="test">
|
|
<script type="application/javascript">
|
|
"use strict";
|
|
|
|
/** Test for css3-animations (Bug 435442) **/
|
|
|
|
function advance_clock(milliseconds) {
|
|
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(milliseconds);
|
|
}
|
|
|
|
var display = document.getElementById("display");
|
|
var div = null;
|
|
var cs = null;
|
|
var events_received = [];
|
|
function new_div(style) {
|
|
return new_element("div", style);
|
|
}
|
|
function new_element(tagname, style) {
|
|
if (div != null || cs != null) {
|
|
ok(false, "test author forgot to call done_div");
|
|
}
|
|
if (typeof(style) != "string") {
|
|
ok(false, "test author forgot to pass argument");
|
|
}
|
|
div = document.createElement(tagname);
|
|
div.setAttribute("style", style);
|
|
display.appendChild(div);
|
|
cs = getComputedStyle(div, "");
|
|
}
|
|
function listen() {
|
|
events_received = [];
|
|
function listener(event) {
|
|
events_received.push(event);
|
|
}
|
|
div.addEventListener("animationstart", listener, false);
|
|
div.addEventListener("animationiteration", listener, false);
|
|
div.addEventListener("animationend", listener, false);
|
|
}
|
|
function check_events(events_expected, desc) {
|
|
// This function checks that the list of events_expected matches
|
|
// the received events -- but it only checks the properties that
|
|
// are present on events_expected.
|
|
is(events_received.length, events_expected.length,
|
|
"number of events received for " + desc);
|
|
for (var i = 0,
|
|
i_end = Math.min(events_expected.length, events_received.length);
|
|
i != i_end; ++i) {
|
|
var exp = events_expected[i];
|
|
var rec = events_received[i];
|
|
for (var prop in exp) {
|
|
if (prop == "elapsedTime") {
|
|
// Allow floating point error.
|
|
ok(Math.abs(rec.elapsedTime - exp.elapsedTime) < 0.000002,
|
|
"events[" + i + "]." + prop + " for " + desc +
|
|
" received=" + rec.elapsedTime + " expected=" + exp.elapsedTime);
|
|
} else {
|
|
is(rec[prop], exp[prop], "events[" + i + "]." + prop + " for " + desc);
|
|
}
|
|
}
|
|
}
|
|
for (var i = events_expected.length; i < events_received.length; ++i) {
|
|
ok(false, "unexpected " + events_received[i].type + " event for " + desc);
|
|
}
|
|
events_received = [];
|
|
}
|
|
function done_div() {
|
|
display.removeChild(div);
|
|
div = null;
|
|
cs = null;
|
|
if (events_received.length) {
|
|
ok(false, "caller should have called check_events");
|
|
}
|
|
}
|
|
|
|
// take over the refresh driver right from the start.
|
|
advance_clock(0);
|
|
|
|
/*
|
|
* css3-animations: 2. Animations
|
|
* http://dev.w3.org/csswg/css3-animations/#animations
|
|
*/
|
|
|
|
// Test that animations don't affect the computed value before the
|
|
// start of the animation or after its end. Test without
|
|
// animation-fill-mode, but then repeat the test with all the values of
|
|
// animation-fill-mode.
|
|
function test_fill_mode(fill_mode, fills_backwards, fills_forwards)
|
|
{
|
|
var style = "margin-left: 30px; -moz-animation: 10s 3s anim1 linear";
|
|
var desc;
|
|
if (fill_mode.length > 0) {
|
|
style += " " + fill_mode;
|
|
desc = "fill mode " + fill_mode + ": ";
|
|
} else {
|
|
desc = "default fill mode: ";
|
|
}
|
|
new_div(style);
|
|
listen();
|
|
if (fills_backwards)
|
|
is(cs.marginLeft, "0px", desc + "does affect value during delay (0s)");
|
|
else
|
|
is(cs.marginLeft, "30px", desc + "doesn't affect value during delay (0s)");
|
|
advance_clock(2000);
|
|
if (fills_backwards)
|
|
is(cs.marginLeft, "0px", desc + "does affect value during delay (2s)");
|
|
else
|
|
is(cs.marginLeft, "30px", desc + "doesn't affect value during delay (2s)");
|
|
check_events([], "before start in test_fill_mode");
|
|
advance_clock(1000);
|
|
check_events([{ type: 'animationstart', target: div,
|
|
bubbles: true, cancelable: true,
|
|
animationName: 'anim1', elapsedTime: 0.0 }],
|
|
"right after start in test_fill_mode");
|
|
if (fills_backwards)
|
|
is(cs.marginLeft, "0px", desc + "affects value at start of animation");
|
|
advance_clock(125);
|
|
is(cs.marginLeft, "2px", desc + "affects value during animation");
|
|
advance_clock(2375);
|
|
is(cs.marginLeft, "40px", desc + "affects value during animation");
|
|
advance_clock(2500);
|
|
is(cs.marginLeft, "80px", desc + "affects value during animation");
|
|
advance_clock(2500);
|
|
is(cs.marginLeft, "90px", desc + "affects value during animation");
|
|
advance_clock(2375);
|
|
is(cs.marginLeft, "99.5px", desc + "affects value during animation");
|
|
check_events([], "before end in test_fill_mode");
|
|
advance_clock(125);
|
|
check_events([{ type: 'animationend', target: div,
|
|
bubbles: true, cancelable: true,
|
|
animationName: 'anim1', elapsedTime: 10.0 }],
|
|
"right after end in test_fill_mode");
|
|
if (fills_forwards)
|
|
is(cs.marginLeft, "100px", desc + "affects value at end of animation");
|
|
advance_clock(10);
|
|
if (fills_forwards)
|
|
is(cs.marginLeft, "100px", desc + "does affect value after animation");
|
|
else
|
|
is(cs.marginLeft, "30px", desc + "does not affect value after animation");
|
|
done_div();
|
|
}
|
|
test_fill_mode("", false, false);
|
|
test_fill_mode("none", false, false);
|
|
test_fill_mode("forwards", false, true);
|
|
test_fill_mode("backwards", true, false);
|
|
test_fill_mode("both", true, true);
|
|
|
|
// Test that animations continue running when the animation name
|
|
// list is changed.
|
|
new_div("-moz-animation: anim1 linear 10s");
|
|
is(cs.getPropertyValue("margin-top"), "0px",
|
|
"just anim1, margin-top at start");
|
|
is(cs.getPropertyValue("margin-right"), "0px",
|
|
"just anim1, margin-right at start");
|
|
is(cs.getPropertyValue("margin-bottom"), "0px",
|
|
"just anim1, margin-bottom at start");
|
|
is(cs.getPropertyValue("margin-left"), "0px",
|
|
"just anim1, margin-left at start");
|
|
advance_clock(1000);
|
|
is(cs.getPropertyValue("margin-top"), "0px",
|
|
"just anim1, margin-top at 1s");
|
|
is(cs.getPropertyValue("margin-right"), "0px",
|
|
"just anim1, margin-right at 1s");
|
|
is(cs.getPropertyValue("margin-bottom"), "0px",
|
|
"just anim1, margin-bottom at 1s");
|
|
is(cs.getPropertyValue("margin-left"), "16px",
|
|
"just anim1, margin-left at 1s");
|
|
// append anim2
|
|
div.style.MozAnimation = "anim1 linear 10s, anim2 linear 10s";
|
|
is(cs.getPropertyValue("margin-top"), "0px",
|
|
"anim1 + anim2, margin-top at 1s");
|
|
is(cs.getPropertyValue("margin-right"), "0px",
|
|
"anim1 + anim2, margin-right at 1s");
|
|
is(cs.getPropertyValue("margin-bottom"), "0px",
|
|
"anim1 + anim2, margin-bottom at 1s");
|
|
is(cs.getPropertyValue("margin-left"), "16px",
|
|
"anim1 + anim2, margin-left at 1s");
|
|
advance_clock(1000);
|
|
is(cs.getPropertyValue("margin-top"), "0px",
|
|
"anim1 + anim2, margin-top at 2s");
|
|
is(cs.getPropertyValue("margin-right"), "10px",
|
|
"anim1 + anim2, margin-right at 2s");
|
|
is(cs.getPropertyValue("margin-bottom"), "0px",
|
|
"anim1 + anim2, margin-bottom at 2s");
|
|
is(cs.getPropertyValue("margin-left"), "32px",
|
|
"anim1 + anim2, margin-left at 2s");
|
|
// prepend anim3
|
|
div.style.MozAnimation = "anim3 linear 10s, anim1 linear 10s, anim2 linear 10s";
|
|
is(cs.getPropertyValue("margin-top"), "0px",
|
|
"anim3 + anim1 + anim2, margin-top at 2s");
|
|
is(cs.getPropertyValue("margin-right"), "10px",
|
|
"anim3 + anim1 + anim2, margin-right at 2s");
|
|
is(cs.getPropertyValue("margin-bottom"), "0px",
|
|
"anim3 + anim1 + anim2, margin-bottom at 2s");
|
|
is(cs.getPropertyValue("margin-left"), "32px",
|
|
"anim3 + anim1 + anim2, margin-left at 2s");
|
|
advance_clock(1000);
|
|
is(cs.getPropertyValue("margin-top"), "10px",
|
|
"anim3 + anim1 + anim2, margin-top at 3s");
|
|
is(cs.getPropertyValue("margin-right"), "20px",
|
|
"anim3 + anim1 + anim2, margin-right at 3s");
|
|
is(cs.getPropertyValue("margin-bottom"), "0px",
|
|
"anim3 + anim1 + anim2, margin-bottom at 3s");
|
|
is(cs.getPropertyValue("margin-left"), "48px",
|
|
"anim3 + anim1 + anim2, margin-left at 3s");
|
|
// remove anim2 from end
|
|
div.style.MozAnimation = "anim3 linear 10s, anim1 linear 10s";
|
|
is(cs.getPropertyValue("margin-top"), "10px",
|
|
"anim3 + anim1, margin-top at 3s");
|
|
is(cs.getPropertyValue("margin-right"), "0px",
|
|
"anim3 + anim1, margin-right at 3s");
|
|
is(cs.getPropertyValue("margin-bottom"), "0px",
|
|
"anim3 + anim1, margin-bottom at 3s");
|
|
is(cs.getPropertyValue("margin-left"), "48px",
|
|
"anim3 + anim1, margin-left at 3s");
|
|
advance_clock(1000);
|
|
is(cs.getPropertyValue("margin-top"), "20px",
|
|
"anim3 + anim1, margin-top at 4s");
|
|
is(cs.getPropertyValue("margin-right"), "0px",
|
|
"anim3 + anim1, margin-right at 4s");
|
|
is(cs.getPropertyValue("margin-bottom"), "0px",
|
|
"anim3 + anim1, margin-bottom at 4s");
|
|
is(cs.getPropertyValue("margin-left"), "64px",
|
|
"anim3 + anim1, margin-left at 4s");
|
|
// swap anim1 and anim3, change duration of anim3
|
|
div.style.MozAnimation = "anim1 linear 10s, anim3 linear 5s";
|
|
is(cs.getPropertyValue("margin-top"), "40px",
|
|
"anim1 + anim3, margin-top at 4s");
|
|
is(cs.getPropertyValue("margin-right"), "0px",
|
|
"anim1 + anim3, margin-right at 4s");
|
|
is(cs.getPropertyValue("margin-bottom"), "0px",
|
|
"anim1 + anim3, margin-bottom at 4s");
|
|
is(cs.getPropertyValue("margin-left"), "64px",
|
|
"anim1 + anim3, margin-left at 4s");
|
|
advance_clock(1000);
|
|
is(cs.getPropertyValue("margin-top"), "60px",
|
|
"anim1 + anim3, margin-top at 5s");
|
|
is(cs.getPropertyValue("margin-right"), "0px",
|
|
"anim1 + anim3, margin-right at 5s");
|
|
is(cs.getPropertyValue("margin-bottom"), "0px",
|
|
"anim1 + anim3, margin-bottom at 5s");
|
|
is(cs.getPropertyValue("margin-left"), "80px",
|
|
"anim1 + anim3, margin-left at 5s");
|
|
// list anim1 twice, last duration wins, original start time still applies
|
|
div.style.MozAnimation = "anim1 linear 10s, anim3 linear 5s, anim1 linear 20s";
|
|
is(cs.getPropertyValue("margin-top"), "60px",
|
|
"anim1 + anim3 + anim1, margin-top at 5s");
|
|
is(cs.getPropertyValue("margin-right"), "0px",
|
|
"anim1 + anim3 + anim1, margin-right at 5s");
|
|
is(cs.getPropertyValue("margin-bottom"), "0px",
|
|
"anim1 + anim3 + anim1, margin-bottom at 5s");
|
|
is(cs.getPropertyValue("margin-left"), "40px",
|
|
"anim1 + anim3 + anim1, margin-left at 5s");
|
|
// drop one of the anim1, and list anim5 as well, which animates
|
|
// the same property as anim1
|
|
div.style.MozAnimation = "anim3 linear 5s, anim1 linear 20s, anim5 linear 10s";
|
|
is(cs.getPropertyValue("margin-top"), "60px",
|
|
"anim3 + anim1 + anim5, margin-top at 5s");
|
|
is(cs.getPropertyValue("margin-right"), "0px",
|
|
"anim3 + anim1 + anim5, margin-right at 5s");
|
|
is(cs.getPropertyValue("margin-bottom"), "0px",
|
|
"anim3 + anim1 + anim5, margin-bottom at 5s");
|
|
is(cs.getPropertyValue("margin-left"), "0px",
|
|
"anim3 + anim1 + anim5, margin-left at 5s");
|
|
advance_clock(1000);
|
|
is(cs.getPropertyValue("margin-top"), "80px",
|
|
"anim3 + anim1 + anim5, margin-top at 6s");
|
|
is(cs.getPropertyValue("margin-right"), "0px",
|
|
"anim3 + anim1 + anim5, margin-right at 6s");
|
|
is(cs.getPropertyValue("margin-bottom"), "0px",
|
|
"anim3 + anim1 + anim5, margin-bottom at 6s");
|
|
is(cs.getPropertyValue("margin-left"), "10px",
|
|
"anim3 + anim1 + anim5, margin-left at 6s");
|
|
// now swap the anim5 and anim1 order
|
|
div.style.MozAnimation = "anim3 linear 5s, anim5 linear 10s, anim1 linear 20s";
|
|
is(cs.getPropertyValue("margin-top"), "80px",
|
|
"anim3 + anim1 + anim5, margin-top at 6s");
|
|
is(cs.getPropertyValue("margin-right"), "0px",
|
|
"anim3 + anim1 + anim5, margin-right at 6s");
|
|
is(cs.getPropertyValue("margin-bottom"), "0px",
|
|
"anim3 + anim1 + anim5, margin-bottom at 6s");
|
|
is(cs.getPropertyValue("margin-left"), "48px",
|
|
"anim3 + anim1 + anim5, margin-left at 6s");
|
|
advance_clock(1000);
|
|
is(cs.getPropertyValue("margin-top"), "0px",
|
|
"anim3 + anim1 + anim5, margin-top at 7s");
|
|
is(cs.getPropertyValue("margin-right"), "0px",
|
|
"anim3 + anim1 + anim5, margin-right at 7s");
|
|
is(cs.getPropertyValue("margin-bottom"), "0px",
|
|
"anim3 + anim1 + anim5, margin-bottom at 7s");
|
|
is(cs.getPropertyValue("margin-left"), "56px",
|
|
"anim3 + anim1 + anim5, margin-left at 7s");
|
|
// swap anim1 and anim5 back
|
|
div.style.MozAnimation = "anim3 linear 5s, anim1 linear 20s, anim5 linear 10s";
|
|
is(cs.getPropertyValue("margin-top"), "0px",
|
|
"anim3 + anim1 + anim5, margin-top at 7s");
|
|
is(cs.getPropertyValue("margin-right"), "0px",
|
|
"anim3 + anim1 + anim5, margin-right at 7s");
|
|
is(cs.getPropertyValue("margin-bottom"), "0px",
|
|
"anim3 + anim1 + anim5, margin-bottom at 7s");
|
|
is(cs.getPropertyValue("margin-left"), "20px",
|
|
"anim3 + anim1 + anim5, margin-left at 7s");
|
|
advance_clock(100);
|
|
is(cs.getPropertyValue("margin-top"), "0px",
|
|
"anim3 + anim1 + anim5, margin-top at 7.1s");
|
|
// Change the animation fill mode on the completed animation.
|
|
div.style.MozAnimation = "anim3 linear 5s forwards, anim1 linear 20s, anim5 linear 10s";
|
|
is(cs.getPropertyValue("margin-top"), "100px",
|
|
"anim3 + anim1 + anim5, margin-top at 7.1s, with fill mode");
|
|
advance_clock(900);
|
|
is(cs.getPropertyValue("margin-top"), "100px",
|
|
"anim3 + anim1 + anim5, margin-top at 8s, with fill mode");
|
|
// Change the animation duration on the completed animation, so it is
|
|
// no longer completed.
|
|
div.style.MozAnimation = "anim3 linear 10s, anim1 linear 20s, anim5 linear 10s";
|
|
is(cs.getPropertyValue("margin-top"), "60px",
|
|
"anim3 + anim1 + anim5, margin-top at 8s, with fill mode");
|
|
is(cs.getPropertyValue("margin-left"), "30px",
|
|
"anim3 + anim1 + anim5, margin-left at 8s");
|
|
done_div();
|
|
|
|
/*
|
|
* css3-animations: 3. Keyframes
|
|
* http://dev.w3.org/csswg/css3-animations/#keyframes
|
|
*
|
|
* Also see test_keyframes_rules.html .
|
|
*/
|
|
|
|
// Test the rules on keyframes that lack a 0% or 100% rule:
|
|
// (simultaneously, test that reverse animations have their keyframes
|
|
// run backwards)
|
|
|
|
// 100px at 0%, 50px at 50%, 150px at 100%
|
|
new_div("margin-top: 100px; -moz-animation: kf1 ease 1s alternate infinite");
|
|
is(cs.marginTop, "100px", "no-0% at 0.0s");
|
|
advance_clock(100);
|
|
is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease(0.2), 0.01,
|
|
"no-0% at 0.1s");
|
|
advance_clock(200);
|
|
is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease(0.6), 0.01,
|
|
"no-0% at 0.3s");
|
|
advance_clock(200);
|
|
is(cs.marginTop, "50px", "no-0% at 0.5s");
|
|
advance_clock(200);
|
|
is_approx(px_to_num(cs.marginTop), 50 + 100 * gTF.ease(0.4), 0.01,
|
|
"no-0% at 0.7s");
|
|
advance_clock(200);
|
|
is_approx(px_to_num(cs.marginTop), 50 + 100 * gTF.ease(0.8), 0.01,
|
|
"no-0% at 0.9s");
|
|
advance_clock(100);
|
|
is(cs.marginTop, "150px", "no-0% at 1.0s");
|
|
advance_clock(100);
|
|
is_approx(px_to_num(cs.marginTop), 50 + 100 * gTF.ease(0.8), 0.01,
|
|
"no-0% at 1.1s");
|
|
advance_clock(300);
|
|
is_approx(px_to_num(cs.marginTop), 50 + 100 * gTF.ease(0.2), 0.01,
|
|
"no-0% at 1.4s");
|
|
advance_clock(300);
|
|
is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease(0.6), 0.01,
|
|
"no-0% at 1.7s");
|
|
advance_clock(200);
|
|
is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease(0.2), 0.01,
|
|
"no-0% at 1.9s");
|
|
advance_clock(100);
|
|
is(cs.marginTop, "100px", "no-0% at 2.0s");
|
|
done_div();
|
|
|
|
// 150px at 0%, 50px at 50%, 100px at 100%
|
|
new_div("margin-top: 100px; -moz-animation: kf2 ease-in 1s alternate infinite");
|
|
is(cs.marginTop, "150px", "no-100% at 0.0s");
|
|
advance_clock(100);
|
|
is_approx(px_to_num(cs.marginTop), 150 - 100 * gTF.ease_in(0.2), 0.01,
|
|
"no-100% at 0.1s");
|
|
advance_clock(200);
|
|
is_approx(px_to_num(cs.marginTop), 150 - 100 * gTF.ease_in(0.6), 0.01,
|
|
"no-100% at 0.3s");
|
|
advance_clock(200);
|
|
is(cs.marginTop, "50px", "no-100% at 0.5s");
|
|
advance_clock(200);
|
|
is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_in(0.4), 0.01,
|
|
"no-100% at 0.7s");
|
|
advance_clock(200);
|
|
is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_in(0.8), 0.01,
|
|
"no-100% at 0.9s");
|
|
advance_clock(100);
|
|
is(cs.marginTop, "100px", "no-100% at 1.0s");
|
|
advance_clock(100);
|
|
is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_in(0.8), 0.01,
|
|
"no-100% at 1.1s");
|
|
advance_clock(300);
|
|
is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_in(0.2), 0.01,
|
|
"no-100% at 1.4s");
|
|
advance_clock(300);
|
|
is_approx(px_to_num(cs.marginTop), 150 - 100 * gTF.ease_in(0.6), 0.01,
|
|
"no-100% at 1.7s");
|
|
advance_clock(200);
|
|
is_approx(px_to_num(cs.marginTop), 150 - 100 * gTF.ease_in(0.2), 0.01,
|
|
"no-100% at 1.9s");
|
|
advance_clock(100);
|
|
is(cs.marginTop, "150px", "no-100% at 2.0s");
|
|
done_div();
|
|
|
|
|
|
// 50px at 0%, 100px at 25%, 50px at 100%
|
|
new_div("margin-top: 50px; -moz-animation: kf3 ease-out 1s alternate infinite");
|
|
is(cs.marginTop, "50px", "no-0%-no-100% at 0.0s");
|
|
advance_clock(50);
|
|
is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_out(0.2), 0.01,
|
|
"no-0%-no-100% at 0.05s");
|
|
advance_clock(100);
|
|
is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_out(0.6), 0.01,
|
|
"no-0%-no-100% at 0.15s");
|
|
advance_clock(100);
|
|
is(cs.marginTop, "100px", "no-0%-no-100% at 0.25s");
|
|
advance_clock(300);
|
|
is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease_out(0.4), 0.01,
|
|
"no-0%-no-100% at 0.55s");
|
|
advance_clock(300);
|
|
is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease_out(0.8), 0.01,
|
|
"no-0%-no-100% at 0.85s");
|
|
advance_clock(150);
|
|
is(cs.marginTop, "50px", "no-0%-no-100% at 1.0s");
|
|
advance_clock(150);
|
|
is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease_out(0.8), 0.01,
|
|
"no-0%-no-100% at 1.15s");
|
|
advance_clock(450);
|
|
is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease_out(0.2), 0.01,
|
|
"no-0%-no-100% at 1.6s");
|
|
advance_clock(250);
|
|
is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_out(0.6), 0.01,
|
|
"no-0%-no-100% at 1.85s");
|
|
advance_clock(100);
|
|
is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_out(0.2), 0.01,
|
|
"no-0%-no-100% at 1.95s");
|
|
advance_clock(50);
|
|
is(cs.marginTop, "50px", "no-0%-no-100% at 2.0s");
|
|
done_div();
|
|
|
|
// Test that non-animatable properties are ignored.
|
|
// Simultaneously, test that the block is still honored, and that
|
|
// we still override the value when two consecutive keyframes have
|
|
// the same value.
|
|
new_div("-moz-animation: kf4 ease 10s");
|
|
is(cs.display, "block",
|
|
"non-animatable properties should be ignored (linear, 0s)");
|
|
is(cs.marginTop, "37px",
|
|
"animatable properties should still apply (linear, 0s)");
|
|
advance_clock(1000);
|
|
is(cs.display, "block",
|
|
"non-animatable properties should be ignored (linear, 1s)");
|
|
is(cs.marginTop, "37px",
|
|
"animatable properties should still apply (linear, 1s)");
|
|
done_div();
|
|
new_div("-moz-animation: kf4 step-start 10s");
|
|
is(cs.display, "block",
|
|
"non-animatable properties should be ignored (step-start, 0s)");
|
|
is(cs.marginTop, "37px",
|
|
"animatable properties should still apply (step-start, 0s)");
|
|
advance_clock(1000);
|
|
is(cs.display, "block",
|
|
"non-animatable properties should be ignored (step-start, 1s)");
|
|
is(cs.marginTop, "37px",
|
|
"animatable properties should still apply (step-start, 1s)");
|
|
done_div();
|
|
|
|
// Test cascading of the keyframes within an @keyframes rule.
|
|
new_div("-moz-animation: kf_cascade1 linear 10s");
|
|
// 0%: 30px
|
|
// 50%: 20px
|
|
// 75%: 20px
|
|
// 85%: 30px
|
|
// 85.1%: 60px
|
|
// 100%: 70px
|
|
is(cs.paddingTop, "30px", "kf_cascade1 at 0s");
|
|
advance_clock(2500);
|
|
is(cs.paddingTop, "25px", "kf_cascade1 at 2.5s");
|
|
advance_clock(2500);
|
|
is(cs.paddingTop, "20px", "kf_cascade1 at 5s");
|
|
advance_clock(2000);
|
|
is(cs.paddingTop, "20px", "kf_cascade1 at 7s");
|
|
advance_clock(500);
|
|
is(cs.paddingTop, "20px", "kf_cascade1 at 7.5s");
|
|
advance_clock(500);
|
|
is(cs.paddingTop, "25px", "kf_cascade1 at 8s");
|
|
advance_clock(500);
|
|
is(cs.paddingTop, "30px", "kf_cascade1 at 8.5s");
|
|
advance_clock(10);
|
|
is(cs.paddingTop, "60px", "kf_cascade1 at 8.51s");
|
|
advance_clock(745);
|
|
is(cs.paddingTop, "65px", "kf_cascade1 at 9.2505s");
|
|
done_div();
|
|
|
|
// Test cascading of the @keyframes rules themselves.
|
|
new_div("-moz-animation: kf_cascade2 linear 10s");
|
|
is(cs.marginTop, "0px", "@keyframes rule with margin-top should be ignored");
|
|
is(cs.marginLeft, "300px", "last @keyframes rule with margin-left should win");
|
|
done_div();
|
|
|
|
/*
|
|
* css3-animations: 3.1. Timing functions for keyframes
|
|
* http://dev.w3.org/csswg/css3-animations/#timing-functions-for-keyframes-
|
|
*/
|
|
new_div("-moz-animation: kf_tf1 ease-in 10s alternate infinite");
|
|
is(cs.paddingBottom, "20px",
|
|
"keyframe timing functions test at 0s (test needed for flush)");
|
|
advance_clock(1000);
|
|
is_approx(px_to_num(cs.paddingBottom), 20 + 40 * gTF.ease(0.4), 0.01,
|
|
"keyframe timing functions test at 1s");
|
|
advance_clock(1000);
|
|
is_approx(px_to_num(cs.paddingBottom), 20 + 40 * gTF.ease(0.8), 0.01,
|
|
"keyframe timing functions test at 2s");
|
|
advance_clock(1000);
|
|
is_approx(px_to_num(cs.paddingBottom), 60 + 100 * gTF.ease_in(0.2), 0.01,
|
|
"keyframe timing functions test at 3s");
|
|
advance_clock(1000);
|
|
is_approx(px_to_num(cs.paddingBottom), 60 + 100 * gTF.ease_in(0.6), 0.01,
|
|
"keyframe timing functions test at 4s");
|
|
advance_clock(1000);
|
|
is(cs.paddingBottom, "160px",
|
|
"keyframe timing functions test at 5s");
|
|
advance_clock(1010); // avoid floating point error
|
|
is_approx(px_to_num(cs.paddingBottom), 160 - 40 * step_end(5)(0.4), 0.01,
|
|
"keyframe timing functions test at 6s");
|
|
advance_clock(1000);
|
|
is_approx(px_to_num(cs.paddingBottom), 160 - 40 * step_end(5)(0.8), 0.01,
|
|
"keyframe timing functions test at 7s");
|
|
advance_clock(990);
|
|
is_approx(px_to_num(cs.paddingBottom), 120 - 100 * gTF.linear(0.2), 0.01,
|
|
"keyframe timing functions test at 8s");
|
|
advance_clock(1000);
|
|
is_approx(px_to_num(cs.paddingBottom), 120 - 100 * gTF.linear(0.6), 0.01,
|
|
"keyframe timing functions test at 9s");
|
|
advance_clock(1000);
|
|
is(cs.paddingBottom, "20px",
|
|
"keyframe timing functions test at 10s");
|
|
advance_clock(20000);
|
|
is(cs.paddingBottom, "20px",
|
|
"keyframe timing functions test at 30s");
|
|
advance_clock(1000);
|
|
is_approx(px_to_num(cs.paddingBottom), 120 - 100 * gTF.linear(0.6), 0.01,
|
|
"keyframe timing functions test at 31s");
|
|
advance_clock(1000);
|
|
is_approx(px_to_num(cs.paddingBottom), 120 - 100 * gTF.linear(0.2), 0.01,
|
|
"keyframe timing functions test at 32s");
|
|
advance_clock(1000);
|
|
is_approx(px_to_num(cs.paddingBottom), 160 - 40 * step_end(5)(0.8), 0.01,
|
|
"keyframe timing functions test at 33s");
|
|
advance_clock(1000);
|
|
is_approx(px_to_num(cs.paddingBottom), 160 - 40 * step_end(5)(0.4), 0.01,
|
|
"keyframe timing functions test at 34s");
|
|
advance_clock(1000);
|
|
is(cs.paddingBottom, "160px",
|
|
"keyframe timing functions test at 35s");
|
|
advance_clock(1000);
|
|
is_approx(px_to_num(cs.paddingBottom), 60 + 100 * gTF.ease_in(0.6), 0.01,
|
|
"keyframe timing functions test at 36s");
|
|
advance_clock(1000);
|
|
is_approx(px_to_num(cs.paddingBottom), 60 + 100 * gTF.ease_in(0.2), 0.01,
|
|
"keyframe timing functions test at 37s");
|
|
advance_clock(1000);
|
|
is_approx(px_to_num(cs.paddingBottom), 20 + 40 * gTF.ease(0.8), 0.01,
|
|
"keyframe timing functions test at 38s");
|
|
advance_clock(1000);
|
|
is_approx(px_to_num(cs.paddingBottom), 20 + 40 * gTF.ease(0.4), 0.01,
|
|
"keyframe timing functions test at 39s");
|
|
advance_clock(1000);
|
|
is(cs.paddingBottom, "20px",
|
|
"keyframe timing functions test at 40s");
|
|
done_div();
|
|
|
|
// spot-check the same thing without alternate
|
|
new_div("-moz-animation: kf_tf1 ease-in 10s infinite");
|
|
is(cs.paddingBottom, "20px",
|
|
"keyframe timing functions test at 0s (test needed for flush)");
|
|
advance_clock(11000);
|
|
is_approx(px_to_num(cs.paddingBottom), 20 + 40 * gTF.ease(0.4), 0.01,
|
|
"keyframe timing functions test at 11s");
|
|
advance_clock(3000);
|
|
is_approx(px_to_num(cs.paddingBottom), 60 + 100 * gTF.ease_in(0.6), 0.01,
|
|
"keyframe timing functions test at 14s");
|
|
advance_clock(2000);
|
|
is_approx(px_to_num(cs.paddingBottom), 160 - 40 * step_end(5)(0.4), 0.01,
|
|
"keyframe timing functions test at 16s");
|
|
advance_clock(2000);
|
|
is_approx(px_to_num(cs.paddingBottom), 120 - 100 * gTF.linear(0.2), 0.01,
|
|
"keyframe timing functions test at 18s");
|
|
done_div();
|
|
|
|
/*
|
|
* css3-animations: 3.2. The 'animation-name' Property
|
|
* http://dev.w3.org/csswg/css3-animations/#the-animation-name-property-
|
|
*/
|
|
|
|
// animation-name is reasonably well-tested up in the tests for Section
|
|
// 2, particularly the tests that "Test that animations continue running
|
|
// when the animation name list is changed."
|
|
|
|
// Test that 'animation-name: none' steps the animation, and setting
|
|
// it again starts a new one.
|
|
|
|
new_div("");
|
|
div.style.MozAnimation = "anim2 ease-in-out 10s";
|
|
is(cs.marginRight, "0px", "after setting animation-name to anim2");
|
|
advance_clock(1000);
|
|
is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in_out(0.1), 0.01,
|
|
"before changing animation-name to none");
|
|
div.style.MozAnimationName = "none";
|
|
is(cs.marginRight, "0px", "after changing animation-name to none");
|
|
advance_clock(1000);
|
|
is(cs.marginRight, "0px", "after changing animation-name to none plus 1s");
|
|
div.style.MozAnimationName = "anim2";
|
|
is(cs.marginRight, "0px", "after changing animation-name to anim2");
|
|
advance_clock(1000);
|
|
is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in_out(0.1), 0.01,
|
|
"at 1s in animation when animation-name no longer none again");
|
|
div.style.MozAnimationName = "none";
|
|
is(cs.marginRight, "0px", "after changing animation-name to none");
|
|
advance_clock(1000);
|
|
is(cs.marginRight, "0px", "after changing animation-name to none plus 1s");
|
|
done_div();
|
|
|
|
/*
|
|
* css3-animations: 3.3. The 'animation-duration' Property
|
|
* http://dev.w3.org/csswg/css3-animations/#the-animation-duration-property-
|
|
*/
|
|
|
|
// FIXME: test animation-duration of 0 (quite a bit, including interaction
|
|
// with fill-mode, count, and reversing), once I know what the right
|
|
// behavior is.
|
|
|
|
/*
|
|
* css3-animations: 3.4. The 'animation-timing-function' Property
|
|
* http://dev.w3.org/csswg/css3-animations/#animation-timing-function_tag
|
|
*/
|
|
|
|
// tested in tests for section 3.1
|
|
|
|
/*
|
|
* css3-animations: 3.5. The 'animation-iteration-count' Property
|
|
* http://dev.w3.org/csswg/css3-animations/#the-animation-iteration-count-property-
|
|
*/
|
|
new_div("-moz-animation: anim2 ease-in 10s 0.3 forwards");
|
|
is(cs.marginRight, "0px", "animation-iteration-count test 1 at 0s");
|
|
advance_clock(2000);
|
|
is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01,
|
|
"animation-iteration-count test 1 at 2s");
|
|
advance_clock(900);
|
|
is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.29), 0.01,
|
|
"animation-iteration-count test 1 at 2.9s");
|
|
advance_clock(100);
|
|
is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.3), 0.01,
|
|
"animation-iteration-count test 1 at 3s");
|
|
advance_clock(100);
|
|
is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.3), 0.01,
|
|
"animation-iteration-count test 1 at 3.1s");
|
|
advance_clock(5000);
|
|
is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.3), 0.01,
|
|
"animation-iteration-count test 1 at 8.1s");
|
|
done_div();
|
|
|
|
new_div("-moz-animation: anim2 ease-in 10s 0.3, anim3 ease-out 20s 1.2 alternate forwards, anim4 ease-in-out 5s 1.6 forwards");
|
|
is(cs.marginRight, "0px", "animation-iteration-count test 2 at 0s");
|
|
is(cs.marginTop, "0px", "animation-iteration-count test 3 at 0s");
|
|
is(cs.marginBottom, "0px", "animation-iteration-count test 4 at 0s");
|
|
advance_clock(2000);
|
|
is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01,
|
|
"animation-iteration-count test 2 at 2s");
|
|
is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_out(0.1), 0.01,
|
|
"animation-iteration-count test 3 at 2s");
|
|
is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.4), 0.01,
|
|
"animation-iteration-count test 4 at 2s");
|
|
advance_clock(900);
|
|
is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.29), 0.01,
|
|
"animation-iteration-count test 2 at 2.9s");
|
|
advance_clock(200);
|
|
is(cs.marginRight, "0px", "animation-iteration-count test 2 at 3.1s");
|
|
advance_clock(1800);
|
|
is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.98), 0.01,
|
|
"animation-iteration-count test 4 at 4.9s");
|
|
advance_clock(200);
|
|
is(cs.marginRight, "0px", "animation-iteration-count test 2 at 5.1s");
|
|
is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.02), 0.01,
|
|
"animation-iteration-count test 4 at 5.1s");
|
|
advance_clock(2800);
|
|
is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.58), 0.01,
|
|
"animation-iteration-count test 4 at 7.9s");
|
|
advance_clock(100);
|
|
is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.6), 0.01,
|
|
"animation-iteration-count test 4 at 8s");
|
|
advance_clock(100);
|
|
is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.6), 0.01,
|
|
"animation-iteration-count test 4 at 8.1s");
|
|
advance_clock(11700);
|
|
is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_out(0.99), 0.01,
|
|
"animation-iteration-count test 3 at 19.8s");
|
|
advance_clock(200);
|
|
is(cs.marginTop, "100px", "animation-iteration-count test 3 at 20s");
|
|
advance_clock(200);
|
|
is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_out(0.99), 0.01,
|
|
"animation-iteration-count test 3 at 20.2s");
|
|
advance_clock(3600);
|
|
is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_out(0.81), 0.01,
|
|
"animation-iteration-count test 3 at 23.8s");
|
|
advance_clock(200);
|
|
is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_out(0.8), 0.01,
|
|
"animation-iteration-count test 3 at 24s");
|
|
advance_clock(200);
|
|
is(cs.marginRight, "0px", "animation-iteration-count test 2 at 25s");
|
|
is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_out(0.8), 0.01,
|
|
"animation-iteration-count test 3 at 25s");
|
|
is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.6), 0.01,
|
|
"animation-iteration-count test 4 at 25s");
|
|
done_div();
|
|
|
|
/*
|
|
* css3-animations: 3.6. The 'animation-direction' Property
|
|
* http://dev.w3.org/csswg/css3-animations/#the-animation-direction-property-
|
|
*/
|
|
|
|
// Tested in tests for sections 3.1 and 3.5.
|
|
|
|
/*
|
|
* css3-animations: 3.7. The 'animation-play-state' Property
|
|
* http://dev.w3.org/csswg/css3-animations/#the-animation-play-state-property-
|
|
*/
|
|
|
|
// simple test with just one animation
|
|
new_div("");
|
|
div.style.MozAnimationTimingFunction = "ease";
|
|
div.style.MozAnimationName = "anim1";
|
|
div.style.MozAnimationDuration = "1s";
|
|
div.style.MozAnimationDirection = "alternate";
|
|
div.style.MozAnimationIterationCount = "2";
|
|
is(cs.marginLeft, "0px", "animation-play-state test 1, at 0s");
|
|
advance_clock(250);
|
|
is_approx(px_to_num(cs.marginLeft), 80 * gTF.ease(0.5), 0.01,
|
|
"animation-play-state test 1 at 250ms");
|
|
div.style.MozAnimationPlayState = "paused";
|
|
is_approx(px_to_num(cs.marginLeft), 80 * gTF.ease(0.5), 0.01,
|
|
"animation-play-state test 1 at 250ms");
|
|
advance_clock(250);
|
|
is_approx(px_to_num(cs.marginLeft), 80 * gTF.ease(0.5), 0.01,
|
|
"animation-play-state test 1 still at 500ms");
|
|
div.style.MozAnimationPlayState = "running";
|
|
is_approx(px_to_num(cs.marginLeft), 80 * gTF.ease(0.5), 0.01,
|
|
"animation-play-state test 1 still at 500ms");
|
|
advance_clock(500);
|
|
is_approx(px_to_num(cs.marginLeft), 80 + 20 * gTF.ease(0.5), 0.01,
|
|
"animation-play-state test 1 at 1000ms");
|
|
advance_clock(250);
|
|
is(cs.marginLeft, "100px", "animation-play-state test 1 at 1250ms");
|
|
advance_clock(250);
|
|
is_approx(px_to_num(cs.marginLeft), 80 + 20 * gTF.ease(0.5), 0.01,
|
|
"animation-play-state test 1 at 1500ms");
|
|
div.style.MozAnimationPlayState = "paused";
|
|
is_approx(px_to_num(cs.marginLeft), 80 + 20 * gTF.ease(0.5), 0.01,
|
|
"animation-play-state test 1 at 1500ms");
|
|
advance_clock(2000);
|
|
is_approx(px_to_num(cs.marginLeft), 80 + 20 * gTF.ease(0.5), 0.01,
|
|
"animation-play-state test 1 at 3500ms");
|
|
advance_clock(500);
|
|
is_approx(px_to_num(cs.marginLeft), 80 + 20 * gTF.ease(0.5), 0.01,
|
|
"animation-play-state test 1 at 4000ms");
|
|
div.style.MozAnimationPlayState = "";
|
|
is_approx(px_to_num(cs.marginLeft), 80 + 20 * gTF.ease(0.5), 0.01,
|
|
"animation-play-state test 1 at 4000ms");
|
|
advance_clock(500);
|
|
is_approx(px_to_num(cs.marginLeft), 80 * gTF.ease(0.5), 0.01,
|
|
"animation-play-state test 1 at 4500ms");
|
|
advance_clock(250);
|
|
is(cs.marginLeft, "0px", "animation-play-state test 1, at 4750ms");
|
|
advance_clock(250);
|
|
is(cs.marginLeft, "0px", "animation-play-state test 1, at 5000ms");
|
|
done_div();
|
|
|
|
// more complicated test with multiple animations (and different directions
|
|
// and iteration counts)
|
|
new_div("");
|
|
div.style.MozAnimationTimingFunction = "ease-out, ease-in, ease-in-out";
|
|
div.style.MozAnimationName = "anim2, anim3, anim4";
|
|
div.style.MozAnimationDuration = "1s, 2s, 1s";
|
|
div.style.MozAnimationDirection = "alternate, normal, normal";
|
|
div.style.MozAnimationIterationCount = "4, 2, infinite";
|
|
is(cs.marginRight, "0px", "animation-play-state test 2, at 0s");
|
|
is(cs.marginTop, "0px", "animation-play-state test 3, at 0s");
|
|
is(cs.marginBottom, "0px", "animation-play-state test 4, at 0s");
|
|
advance_clock(250);
|
|
div.style.MozAnimationPlayState = "paused, running"; // pause 1 and 3
|
|
is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.25), 0.01,
|
|
"animation-play-state test 2 at 250ms");
|
|
is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.125), 0.01,
|
|
"animation-play-state test 3 at 250ms");
|
|
is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.25), 0.01,
|
|
"animation-play-state test 4 at 250ms");
|
|
advance_clock(250);
|
|
is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.25), 0.01,
|
|
"animation-play-state test 2 at 500ms");
|
|
is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.25), 0.01,
|
|
"animation-play-state test 3 at 500ms");
|
|
is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.25), 0.01,
|
|
"animation-play-state test 4 at 500ms");
|
|
div.style.MozAnimationPlayState = "paused, running, running"; // unpause 3
|
|
is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.25), 0.01,
|
|
"animation-play-state test 2 at 500ms");
|
|
is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.25), 0.01,
|
|
"animation-play-state test 3 at 500ms");
|
|
is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.25), 0.01,
|
|
"animation-play-state test 4 at 500ms");
|
|
advance_clock(250);
|
|
is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.25), 0.01,
|
|
"animation-play-state test 2 at 750ms");
|
|
is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.375), 0.01,
|
|
"animation-play-state test 3 at 750ms");
|
|
is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.5), 0.01,
|
|
"animation-play-state test 4 at 750ms");
|
|
div.style.MozAnimationPlayState = "running, paused"; // unpause 1, pause 2
|
|
advance_clock(0); // notify refresh observers
|
|
advance_clock(250);
|
|
is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.5), 0.01,
|
|
"animation-play-state test 2 at 1000ms");
|
|
is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.375), 0.01,
|
|
"animation-play-state test 3 at 1000ms");
|
|
is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.75), 0.01,
|
|
"animation-play-state test 4 at 1000ms");
|
|
div.style.MozAnimationPlayState = "paused"; // pause all
|
|
advance_clock(0); // notify refresh observers
|
|
advance_clock(3000);
|
|
is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.5), 0.01,
|
|
"animation-play-state test 2 at 4000ms");
|
|
is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.375), 0.01,
|
|
"animation-play-state test 3 at 4000ms");
|
|
is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.75), 0.01,
|
|
"animation-play-state test 4 at 4000ms");
|
|
div.style.MozAnimationPlayState = "running, paused"; // pause 2
|
|
advance_clock(0); // notify refresh observers
|
|
advance_clock(850);
|
|
is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.65), 0.01,
|
|
"animation-play-state test 2 at 4850ms");
|
|
is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.375), 0.01,
|
|
"animation-play-state test 3 at 4850ms");
|
|
is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.6), 0.01,
|
|
"animation-play-state test 4 at 4850ms");
|
|
advance_clock(300);
|
|
is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.35), 0.01,
|
|
"animation-play-state test 2 at 5150ms");
|
|
is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.375), 0.01,
|
|
"animation-play-state test 3 at 5150ms");
|
|
is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.9), 0.01,
|
|
"animation-play-state test 4 at 5150ms");
|
|
advance_clock(2300);
|
|
is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.05), 0.01,
|
|
"animation-play-state test 2 at 7450ms");
|
|
is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.375), 0.01,
|
|
"animation-play-state test 3 at 7450ms");
|
|
is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.2), 0.01,
|
|
"animation-play-state test 4 at 7450ms");
|
|
advance_clock(100);
|
|
is(cs.marginRight, "0px", "animation-play-state test 2 at 7550ms");
|
|
is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.375), 0.01,
|
|
"animation-play-state test 3 at 7550ms");
|
|
is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.3), 0.01,
|
|
"animation-play-state test 4 at 7550ms");
|
|
div.style.MozAnimationPlayState = "running"; // unpause 2
|
|
advance_clock(0); // notify refresh observers
|
|
advance_clock(1000);
|
|
is(cs.marginRight, "0px", "animation-play-state test 2 at 7550ms");
|
|
is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.875), 0.01,
|
|
"animation-play-state test 3 at 7550ms");
|
|
is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.3), 0.01,
|
|
"animation-play-state test 4 at 7550ms");
|
|
advance_clock(500);
|
|
is(cs.marginRight, "0px", "animation-play-state test 2 at 8050ms");
|
|
is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.125), 0.01,
|
|
"animation-play-state test 3 at 8050ms");
|
|
is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.8), 0.01,
|
|
"animation-play-state test 4 at 8050ms");
|
|
advance_clock(1000);
|
|
is(cs.marginRight, "0px", "animation-play-state test 2 at 9050ms");
|
|
is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.625), 0.01,
|
|
"animation-play-state test 3 at 9050ms");
|
|
is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.8), 0.01,
|
|
"animation-play-state test 4 at 9050ms");
|
|
advance_clock(500);
|
|
is(cs.marginRight, "0px", "animation-play-state test 2 at 9550ms");
|
|
is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.875), 0.01,
|
|
"animation-play-state test 3 at 9550ms");
|
|
is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.3), 0.01,
|
|
"animation-play-state test 4 at 9550ms");
|
|
advance_clock(500);
|
|
is(cs.marginRight, "0px", "animation-play-state test 2 at 10050ms");
|
|
is(cs.marginTop, "0px", "animation-play-state test 3 at 10050ms");
|
|
is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.8), 0.01,
|
|
"animation-play-state test 4 at 10050ms");
|
|
done_div();
|
|
|
|
/*
|
|
* css3-animations: 3.8. The 'animation-delay' Property
|
|
* http://dev.w3.org/csswg/css3-animations/#the-animation-delay-property-
|
|
*/
|
|
|
|
// test positive delay
|
|
new_div("-moz-animation: anim2 1s 0.5s ease-out");
|
|
is(cs.marginRight, "0px", "positive delay test at 0ms");
|
|
advance_clock(400);
|
|
is(cs.marginRight, "0px", "positive delay test at 400ms");
|
|
advance_clock(100);
|
|
is(cs.marginRight, "0px", "positive delay test at 500ms");
|
|
advance_clock(100);
|
|
is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.1), 0.01,
|
|
"positive delay test at 500ms");
|
|
done_div();
|
|
|
|
// test dynamic changes to delay (i.e., that we only check delay once,
|
|
// at the very start of the animation)
|
|
new_div("-moz-animation: anim2 1s 0.5s ease-out");
|
|
is(cs.marginRight, "0px", "dynamic delay delay test at 0ms");
|
|
advance_clock(400);
|
|
is(cs.marginRight, "0px", "dynamic delay delay test at 400ms");
|
|
div.style.MozAnimationDelay = "0.2s";
|
|
advance_clock(0);
|
|
advance_clock(100);
|
|
is(cs.marginRight, "0px", "dynamic delay delay test at 500ms");
|
|
advance_clock(100);
|
|
is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.1), 0.01,
|
|
"dynamic delay delay test at 500ms");
|
|
div.style.MozAnimationDelay = "1s";
|
|
advance_clock(0);
|
|
advance_clock(100);
|
|
is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.2), 0.01,
|
|
"dynamic delay delay test at 500ms");
|
|
done_div();
|
|
|
|
// test delay and play-state interaction
|
|
new_div("-moz-animation: anim2 1s 0.5s ease-out");
|
|
is(cs.marginRight, "0px", "delay and play-state delay test at 0ms");
|
|
advance_clock(400);
|
|
is(cs.marginRight, "0px", "delay and play-state delay test at 400ms");
|
|
div.style.MozAnimationPlayState = "paused";
|
|
advance_clock(0);
|
|
advance_clock(100);
|
|
is(cs.marginRight, "0px", "delay and play-state delay test at 500ms");
|
|
advance_clock(500);
|
|
is(cs.marginRight, "0px", "delay and play-state delay test at 1000ms");
|
|
div.style.MozAnimationPlayState = "running";
|
|
advance_clock(0);
|
|
advance_clock(100);
|
|
is(cs.marginRight, "0px", "delay and play-state delay test at 1100ms");
|
|
advance_clock(100);
|
|
is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.1), 0.01,
|
|
"delay and play-state delay test at 1200ms");
|
|
div.style.MozAnimationPlayState = "paused";
|
|
advance_clock(0);
|
|
advance_clock(100);
|
|
is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.1), 0.01,
|
|
"delay and play-state delay test at 1300ms");
|
|
done_div();
|
|
|
|
// test negative delay and implicit starting values
|
|
new_div("margin-top: 1000px");
|
|
advance_clock(300);
|
|
div.style.marginTop = "100px";
|
|
div.style.MozAnimation = "kf1 1s -0.1s ease-in";
|
|
is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease_in(0.2), 0.01,
|
|
"delay and implicit starting values test");
|
|
done_div();
|
|
|
|
// test large negative delay that causes the animation to start
|
|
// in the fourth iteration
|
|
new_div("-moz-animation: anim2 1s -3.6s ease-in 5 alternate forwards");
|
|
listen(); // rely on no flush having happened yet
|
|
is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.4), 0.01,
|
|
"large negative delay test at 0ms");
|
|
check_events([{ type: 'animationstart', target: div,
|
|
animationName: 'anim2', elapsedTime: 3.6 }],
|
|
"right after start in large negative delay test");
|
|
advance_clock(380);
|
|
is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.02), 0.01,
|
|
"large negative delay test at 380ms");
|
|
check_events([]);
|
|
advance_clock(20);
|
|
is(cs.marginRight, "0px", "large negative delay test at 400ms");
|
|
check_events([{ type: 'animationiteration', target: div,
|
|
animationName: 'anim2', elapsedTime: 4.0 }],
|
|
"right after start in large negative delay test");
|
|
advance_clock(800);
|
|
is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.8), 0.01,
|
|
"large negative delay test at 1200ms");
|
|
check_events([]);
|
|
advance_clock(200);
|
|
is(cs.marginRight, "100px", "large negative delay test at 1400ms");
|
|
check_events([{ type: 'animationend', target: div,
|
|
animationName: 'anim2', elapsedTime: 5.0 }],
|
|
"right after start in large negative delay test");
|
|
done_div();
|
|
|
|
/*
|
|
* css3-animations: 3.9. The 'animation-fill-mode' Property
|
|
* http://dev.w3.org/csswg/css3-animations/#the-animation-fill-mode-property-
|
|
*/
|
|
|
|
// animation-fill-mode is tested in the tests for section (2).
|
|
|
|
/*
|
|
* css3-animations: 3.10. The 'animation' Shorthand Property
|
|
* http://dev.w3.org/csswg/css3-animations/#the-animation-shorthand-property-
|
|
*/
|
|
|
|
// shorthand vs. longhand is adequately tested by the
|
|
// property_database.js-based tests.
|
|
|
|
/**
|
|
* Basic tests of animations on pseudo-elements
|
|
*/
|
|
new_div("");
|
|
listen();
|
|
div.id = "withbefore";
|
|
var cs_before = getComputedStyle(div, ":before");
|
|
is(cs_before.marginRight, "0px", ":before test at 0ms");
|
|
advance_clock(400);
|
|
is(cs_before.marginRight, "40px", ":before test at 400ms");
|
|
advance_clock(800);
|
|
is(cs_before.marginRight, "80px", ":before test at 1200ms");
|
|
is(cs.marginRight, "0px", ":before animation should not affect element");
|
|
advance_clock(800);
|
|
is(cs_before.marginRight, "0px", ":before test at 2000ms");
|
|
advance_clock(300);
|
|
is(cs_before.marginRight, "30px", ":before test at 2300ms");
|
|
check_events([], "no events should be fired for animations on :before");
|
|
done_div();
|
|
|
|
new_div("");
|
|
listen();
|
|
div.id = "withafter";
|
|
var cs_after = getComputedStyle(div, ":after");
|
|
is(cs_after.marginRight, "0px", ":after test at 0ms");
|
|
advance_clock(400);
|
|
is(cs_after.marginRight, "40px", ":after test at 400ms");
|
|
advance_clock(800);
|
|
is(cs_after.marginRight, "80px", ":after test at 1200ms");
|
|
is(cs.marginRight, "0px", ":after animation should not affect element");
|
|
advance_clock(800);
|
|
is(cs_after.marginRight, "0px", ":after test at 2000ms");
|
|
advance_clock(300);
|
|
is(cs_after.marginRight, "30px", ":after test at 2300ms");
|
|
check_events([], "no events should be fired for animations on :after");
|
|
done_div();
|
|
|
|
/**
|
|
* Test handling of properties that are present in only some of the
|
|
* keyframes.
|
|
*/
|
|
new_div("-moz-animation: multiprop 1s ease-in-out alternate infinite");
|
|
is(cs.paddingTop, "10px", "multiprop top at 0ms");
|
|
is(cs.paddingLeft, "30px", "multiprop top at 0ms");
|
|
advance_clock(100);
|
|
is_approx(px_to_num(cs.paddingTop), 10 + 30 * gTF.ease(0.2), 0.01,
|
|
"multiprop top at 100ms");
|
|
is_approx(px_to_num(cs.paddingLeft), 30 + 20 * gTF.ease(0.4), 0.01,
|
|
"multiprop left at 100ms");
|
|
advance_clock(200);
|
|
is_approx(px_to_num(cs.paddingTop), 10 + 30 * gTF.ease(0.6), 0.01,
|
|
"multiprop top at 300ms");
|
|
is_approx(px_to_num(cs.paddingLeft), 50 + 10 * gTF.ease_out(0.1), 0.01,
|
|
"multiprop left at 300ms");
|
|
advance_clock(300);
|
|
is_approx(px_to_num(cs.paddingTop), 40 + 40 * gTF.ease_in_out(0.4), 0.01,
|
|
"multiprop top at 600ms");
|
|
is_approx(px_to_num(cs.paddingLeft), 50 + 10 * gTF.ease_out(0.7), 0.01,
|
|
"multiprop left at 600ms");
|
|
advance_clock(200);
|
|
is_approx(px_to_num(cs.paddingTop), 80 - 80 * gTF.ease_in(0.2), 0.01,
|
|
"multiprop top at 800ms");
|
|
is_approx(px_to_num(cs.paddingLeft), 60 - 60 * gTF.ease_in(0.2), 0.01,
|
|
"multiprop left at 800ms");
|
|
advance_clock(400);
|
|
is_approx(px_to_num(cs.paddingTop), 80 - 80 * gTF.ease_in(0.2), 0.01,
|
|
"multiprop top at 1200ms");
|
|
is_approx(px_to_num(cs.paddingLeft), 60 - 60 * gTF.ease_in(0.2), 0.01,
|
|
"multiprop left at 1200ms");
|
|
advance_clock(200);
|
|
is_approx(px_to_num(cs.paddingTop), 40 + 40 * gTF.ease_in_out(0.4), 0.01,
|
|
"multiprop top at 1400ms");
|
|
is_approx(px_to_num(cs.paddingLeft), 50 + 10 * gTF.ease_out(0.7), 0.01,
|
|
"multiprop left at 1400ms");
|
|
advance_clock(300);
|
|
is_approx(px_to_num(cs.paddingTop), 10 + 30 * gTF.ease(0.6), 0.01,
|
|
"multiprop top at 1700ms");
|
|
is_approx(px_to_num(cs.paddingLeft), 50 + 10 * gTF.ease_out(0.1), 0.01,
|
|
"multiprop left at 1700ms");
|
|
advance_clock(200);
|
|
is_approx(px_to_num(cs.paddingTop), 10 + 30 * gTF.ease(0.2), 0.01,
|
|
"multiprop top at 1900ms");
|
|
is_approx(px_to_num(cs.paddingLeft), 30 + 20 * gTF.ease(0.4), 0.01,
|
|
"multiprop left at 1900ms");
|
|
done_div();
|
|
|
|
// Test for https://bugzilla.mozilla.org/show_bug.cgi?id=651456 -- make
|
|
// sure that refreshing of animations doesn't break when we get two
|
|
// refreshes with the same timestamp.
|
|
new_div("-moz-animation: anim2 1s linear");
|
|
is(cs.marginRight, "0px", "bug 651456 at 0ms");
|
|
advance_clock(100);
|
|
is(cs.marginRight, "10px", "bug 651456 at 100ms (1)");
|
|
advance_clock(0); // still forces a refresh
|
|
is(cs.marginRight, "10px", "bug 651456 at 100ms (2)");
|
|
advance_clock(100);
|
|
is(cs.marginRight, "20px", "bug 651456 at 200ms");
|
|
done_div();
|
|
|
|
// Test that UA !important rules override animations.
|
|
// This test depends on forms.css having a rule
|
|
// input { line-height: !important }
|
|
// If that rule changes, we should rewrite it to depend on a different rule.
|
|
new_element("input", "");
|
|
var default_line_height = cs.lineHeight;
|
|
done_div();
|
|
new_element("input", "-moz-animation: uaoverride 2s linear infinite");
|
|
is(cs.lineHeight, default_line_height,
|
|
"animations should not override UA !important at 0ms");
|
|
is(cs.marginTop, "20px",
|
|
"rest of animation should still work when UA !important present at 0ms");
|
|
advance_clock(200);
|
|
is(cs.lineHeight, default_line_height,
|
|
"animations should not override UA !important at 200ms");
|
|
is(cs.marginTop, "40px",
|
|
"rest of animation should still work when UA !important present at 200ms");
|
|
done_div();
|
|
|
|
SpecialPowers.DOMWindowUtils.restoreNormalRefresh();
|
|
|
|
</script>
|
|
</pre>
|
|
</body>
|
|
</html>
|