1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/style/test/test_animations.html Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1547 @@ 1.4 +<!DOCTYPE HTML> 1.5 +<html> 1.6 +<!-- 1.7 +https://bugzilla.mozilla.org/show_bug.cgi?id=435442 1.8 +--> 1.9 +<!-- 1.10 + 1.11 + ====== PLEASE KEEP THIS IN SYNC WITH test_animations_omta.html ======= 1.12 + 1.13 + test_animations_omta.html mimicks the content of this file but with 1.14 + extra machinery for testing animation values on the compositor thread. 1.15 + 1.16 + If you are making changes to this file or to test_animations_omta.html, please 1.17 + try to keep them consistent where appropriate. 1.18 + 1.19 +--> 1.20 +<head> 1.21 + <title>Test for css3-animations (Bug 435442)</title> 1.22 + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> 1.23 + <script type="application/javascript" src="animation_utils.js"></script> 1.24 + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> 1.25 + <style type="text/css"> 1.26 + @keyframes anim1 { 1.27 + 0% { margin-left: 0px } 1.28 + 50% { margin-left: 80px } 1.29 + 100% { margin-left: 100px } 1.30 + } 1.31 + @keyframes anim2 { 1.32 + from { margin-right: 0 } to { margin-right: 100px } 1.33 + } 1.34 + @keyframes anim3 { 1.35 + from { margin-top: 0 } to { margin-top: 100px } 1.36 + } 1.37 + @keyframes anim4 { 1.38 + from { margin-bottom: 0 } to { margin-bottom: 100px } 1.39 + } 1.40 + @keyframes anim5 { 1.41 + from { margin-left: 0 } to { margin-left: 100px } 1.42 + } 1.43 + 1.44 + @keyframes kf1 { 1.45 + 50% { margin-top: 50px } 1.46 + to { margin-top: 150px } 1.47 + } 1.48 + @keyframes kf2 { 1.49 + from { margin-top: 150px } 1.50 + 50% { margin-top: 50px } 1.51 + } 1.52 + @keyframes kf3 { 1.53 + 25% { margin-top: 100px } 1.54 + } 1.55 + @keyframes kf4 { 1.56 + to, from { display: inline; margin-top: 37px } 1.57 + } 1.58 + @keyframes kf_cascade1 { 1.59 + from { padding-top: 50px } 1.60 + 50%, from { padding-top: 30px } /* wins: 0% */ 1.61 + 75%, 85%, 50% { padding-top: 20px } /* wins: 75%, 50% */ 1.62 + 100%, 85% { padding-top: 70px } /* wins: 100% */ 1.63 + 85.1% { padding-top: 60px } /* wins: 85.1% */ 1.64 + 85% { padding-top: 30px } /* wins: 85% */ 1.65 + } 1.66 + @keyframes kf_cascade2 { from, to { margin-top: 100px } } 1.67 + @keyframes kf_cascade2 { from, to { margin-left: 200px } } 1.68 + @keyframes kf_cascade2 { from, to { margin-left: 300px } } 1.69 + @keyframes kf_tf1 { 1.70 + 0% { padding-bottom: 20px; animation-timing-function: ease } 1.71 + 25% { padding-bottom: 60px; } 1.72 + 50% { padding-bottom: 160px; animation-timing-function: steps(5) } 1.73 + 75% { padding-bottom: 120px; animation-timing-function: linear } 1.74 + 100% { padding-bottom: 20px; animation-timing-function: ease-out } 1.75 + } 1.76 + 1.77 + @keyframes always_fifty { 1.78 + from, to { margin-left: 50px } 1.79 + } 1.80 + 1.81 + #withbefore::before, #withafter::after { 1.82 + content: ""; 1.83 + animation: anim2 1s linear alternate 3; 1.84 + } 1.85 + 1.86 + @keyframes multiprop { 1.87 + 0% { 1.88 + padding-top: 10px; padding-left: 30px; 1.89 + animation-timing-function: ease; 1.90 + } 1.91 + 25% { 1.92 + padding-left: 50px; 1.93 + animation-timing-function: ease-out; 1.94 + } 1.95 + 50% { 1.96 + padding-top: 40px; 1.97 + } 1.98 + 75% { 1.99 + padding-top: 80px; padding-left: 60px; 1.100 + animation-timing-function: ease-in; 1.101 + } 1.102 + } 1.103 + 1.104 + @keyframes uaoverride { 1.105 + 0%, 100% { line-height: 3; margin-top: 20px } 1.106 + 50% { margin-top: 120px } 1.107 + } 1.108 + 1.109 + @keyframes cascade { 1.110 + 0%, 25%, 100% { top: 0 } 1.111 + 50%, 75% { top: 100px } 1.112 + 0%, 75%, 100% { left: 0 } 1.113 + 25%, 50% { left: 100px } 1.114 + } 1.115 + @keyframes cascade2 { 1.116 + 0% { text-indent: 0 } 1.117 + 25% { text-indent: 30px; animation-timing-function: ease-in } /* beaten by rule below */ 1.118 + 50% { text-indent: 0 } 1.119 + 25% { text-indent: 50px } 1.120 + 100% { text-indent: 100px } 1.121 + } 1.122 + 1.123 + @keyframes primitives1 { 1.124 + from { -moz-transform: rotate(0deg) translateX(0px) scaleX(1) 1.125 + translate(0px) scale3d(1, 1, 1); } 1.126 + to { -moz-transform: rotate(270deg) translate3d(0px, 0px, 0px) scale(1) 1.127 + translateY(0px) scaleY(1); } 1.128 + } 1.129 + 1.130 + @keyframes important1 { 1.131 + from { margin-top: 50px; } 1.132 + 50% { margin-top: 150px !important; } /* ignored */ 1.133 + to { margin-top: 100px; } 1.134 + } 1.135 + 1.136 + @keyframes important2 { 1.137 + from { margin-top: 50px; 1.138 + margin-bottom: 100px; } 1.139 + to { margin-top: 150px !important; /* ignored */ 1.140 + margin-bottom: 50px; } 1.141 + } 1.142 + </style> 1.143 +</head> 1.144 +<body> 1.145 +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=435442">Mozilla Bug 435442</a> 1.146 +<div id="display"></div> 1.147 +<pre id="test"> 1.148 +<script type="application/javascript"> 1.149 +"use strict"; 1.150 + 1.151 +/** Test for css3-animations (Bug 435442) **/ 1.152 + 1.153 +var e = new AnimationEvent("foo", 1.154 + { 1.155 + bubbles: true, 1.156 + cancelable: true, 1.157 + animationName: "name", 1.158 + elapsedTime: 0.5, 1.159 + pseudoElement: "pseudo" 1.160 + }); 1.161 +is(e.bubbles, true); 1.162 +is(e.cancelable, true); 1.163 +is(e.animationName, "name"); 1.164 +is(e.elapsedTime, 0.5); 1.165 +is(e.pseudoElement, "pseudo"); 1.166 +is(e.isTrusted, false) 1.167 + 1.168 +function advance_clock(milliseconds) { 1.169 + SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(milliseconds); 1.170 +} 1.171 + 1.172 +var display = document.getElementById("display"); 1.173 +var div = null; 1.174 +var cs = null; 1.175 +var events_received = []; 1.176 +function new_div(style) { 1.177 + return new_element("div", style); 1.178 +} 1.179 +function new_element(tagname, style) { 1.180 + if (div != null || cs != null) { 1.181 + ok(false, "test author forgot to call done_div"); 1.182 + } 1.183 + if (typeof(style) != "string") { 1.184 + ok(false, "test author forgot to pass argument"); 1.185 + } 1.186 + div = document.createElement(tagname); 1.187 + div.setAttribute("style", style); 1.188 + display.appendChild(div); 1.189 + cs = getComputedStyle(div, ""); 1.190 +} 1.191 +function listen() { 1.192 + events_received = []; 1.193 + function listener(event) { 1.194 + events_received.push(event); 1.195 + } 1.196 + div.addEventListener("animationstart", listener, false); 1.197 + div.addEventListener("animationiteration", listener, false); 1.198 + div.addEventListener("animationend", listener, false); 1.199 +} 1.200 +function check_events(events_expected, desc) { 1.201 + // This function checks that the list of events_expected matches 1.202 + // the received events -- but it only checks the properties that 1.203 + // are present on events_expected. 1.204 + is(events_received.length, events_expected.length, 1.205 + "number of events received for " + desc); 1.206 + for (var i = 0, 1.207 + i_end = Math.min(events_expected.length, events_received.length); 1.208 + i != i_end; ++i) { 1.209 + var exp = events_expected[i]; 1.210 + var rec = events_received[i]; 1.211 + for (var prop in exp) { 1.212 + if (prop == "elapsedTime") { 1.213 + // Allow floating point error. 1.214 + ok(Math.abs(rec.elapsedTime - exp.elapsedTime) < 0.000002, 1.215 + "events[" + i + "]." + prop + " for " + desc + 1.216 + " received=" + rec.elapsedTime + " expected=" + exp.elapsedTime); 1.217 + } else { 1.218 + is(rec[prop], exp[prop], "events[" + i + "]." + prop + " for " + desc); 1.219 + } 1.220 + } 1.221 + } 1.222 + for (var i = events_expected.length; i < events_received.length; ++i) { 1.223 + ok(false, "unexpected " + events_received[i].type + " event for " + desc); 1.224 + } 1.225 + events_received = []; 1.226 +} 1.227 +function done_div() { 1.228 + display.removeChild(div); 1.229 + div = null; 1.230 + cs = null; 1.231 + if (events_received.length) { 1.232 + ok(false, "caller should have called check_events"); 1.233 + } 1.234 +} 1.235 + 1.236 +// take over the refresh driver right from the start. 1.237 +advance_clock(0); 1.238 + 1.239 +/* 1.240 + * css3-animations: 2. Animations 1.241 + * http://dev.w3.org/csswg/css3-animations/#animations 1.242 + */ 1.243 + 1.244 +// Test that animations don't affect the computed value before the 1.245 +// start of the animation or after its end. Test without 1.246 +// animation-fill-mode, but then repeat the test with all the values of 1.247 +// animation-fill-mode. 1.248 +function test_fill_mode(fill_mode, fills_backwards, fills_forwards) 1.249 +{ 1.250 + var style = "margin-left: 30px; animation: 10s 3s anim1 linear"; 1.251 + var desc; 1.252 + if (fill_mode.length > 0) { 1.253 + style += " " + fill_mode; 1.254 + desc = "fill mode " + fill_mode + ": "; 1.255 + } else { 1.256 + desc = "default fill mode: "; 1.257 + } 1.258 + new_div(style); 1.259 + listen(); 1.260 + if (fills_backwards) 1.261 + is(cs.marginLeft, "0px", desc + "does affect value during delay (0s)"); 1.262 + else 1.263 + is(cs.marginLeft, "30px", desc + "doesn't affect value during delay (0s)"); 1.264 + advance_clock(2000); 1.265 + if (fills_backwards) 1.266 + is(cs.marginLeft, "0px", desc + "does affect value during delay (2s)"); 1.267 + else 1.268 + is(cs.marginLeft, "30px", desc + "doesn't affect value during delay (2s)"); 1.269 + check_events([], "before start in test_fill_mode"); 1.270 + advance_clock(1000); 1.271 + check_events([{ type: 'animationstart', target: div, 1.272 + bubbles: true, cancelable: false, 1.273 + animationName: 'anim1', elapsedTime: 0.0, 1.274 + pseudoElement: "" }], 1.275 + "right after start in test_fill_mode"); 1.276 + if (fills_backwards) 1.277 + is(cs.marginLeft, "0px", desc + "affects value at start of animation"); 1.278 + advance_clock(125); 1.279 + is(cs.marginLeft, "2px", desc + "affects value during animation"); 1.280 + advance_clock(2375); 1.281 + is(cs.marginLeft, "40px", desc + "affects value during animation"); 1.282 + advance_clock(2500); 1.283 + is(cs.marginLeft, "80px", desc + "affects value during animation"); 1.284 + advance_clock(2500); 1.285 + is(cs.marginLeft, "90px", desc + "affects value during animation"); 1.286 + advance_clock(2375); 1.287 + is(cs.marginLeft, "99.5px", desc + "affects value during animation"); 1.288 + check_events([], "before end in test_fill_mode"); 1.289 + advance_clock(125); 1.290 + check_events([{ type: 'animationend', target: div, 1.291 + bubbles: true, cancelable: false, 1.292 + animationName: 'anim1', elapsedTime: 10.0, 1.293 + pseudoElement: "" }], 1.294 + "right after end in test_fill_mode"); 1.295 + if (fills_forwards) 1.296 + is(cs.marginLeft, "100px", desc + "affects value at end of animation"); 1.297 + advance_clock(10); 1.298 + if (fills_forwards) 1.299 + is(cs.marginLeft, "100px", desc + "does affect value after animation"); 1.300 + else 1.301 + is(cs.marginLeft, "30px", desc + "does not affect value after animation"); 1.302 + done_div(); 1.303 +} 1.304 +test_fill_mode("", false, false); 1.305 +test_fill_mode("none", false, false); 1.306 +test_fill_mode("forwards", false, true); 1.307 +test_fill_mode("backwards", true, false); 1.308 +test_fill_mode("both", true, true); 1.309 + 1.310 +// Test that animations continue running when the animation name 1.311 +// list is changed. 1.312 +new_div("animation: anim1 linear 10s"); 1.313 + is(cs.getPropertyValue("margin-top"), "0px", 1.314 + "just anim1, margin-top at start"); 1.315 + is(cs.getPropertyValue("margin-right"), "0px", 1.316 + "just anim1, margin-right at start"); 1.317 + is(cs.getPropertyValue("margin-bottom"), "0px", 1.318 + "just anim1, margin-bottom at start"); 1.319 + is(cs.getPropertyValue("margin-left"), "0px", 1.320 + "just anim1, margin-left at start"); 1.321 +advance_clock(1000); 1.322 + is(cs.getPropertyValue("margin-top"), "0px", 1.323 + "just anim1, margin-top at 1s"); 1.324 + is(cs.getPropertyValue("margin-right"), "0px", 1.325 + "just anim1, margin-right at 1s"); 1.326 + is(cs.getPropertyValue("margin-bottom"), "0px", 1.327 + "just anim1, margin-bottom at 1s"); 1.328 + is(cs.getPropertyValue("margin-left"), "16px", 1.329 + "just anim1, margin-left at 1s"); 1.330 +// append anim2 1.331 +div.style.animation = "anim1 linear 10s, anim2 linear 10s"; 1.332 + is(cs.getPropertyValue("margin-top"), "0px", 1.333 + "anim1 + anim2, margin-top at 1s"); 1.334 + is(cs.getPropertyValue("margin-right"), "0px", 1.335 + "anim1 + anim2, margin-right at 1s"); 1.336 + is(cs.getPropertyValue("margin-bottom"), "0px", 1.337 + "anim1 + anim2, margin-bottom at 1s"); 1.338 + is(cs.getPropertyValue("margin-left"), "16px", 1.339 + "anim1 + anim2, margin-left at 1s"); 1.340 +advance_clock(1000); 1.341 + is(cs.getPropertyValue("margin-top"), "0px", 1.342 + "anim1 + anim2, margin-top at 2s"); 1.343 + is(cs.getPropertyValue("margin-right"), "10px", 1.344 + "anim1 + anim2, margin-right at 2s"); 1.345 + is(cs.getPropertyValue("margin-bottom"), "0px", 1.346 + "anim1 + anim2, margin-bottom at 2s"); 1.347 + is(cs.getPropertyValue("margin-left"), "32px", 1.348 + "anim1 + anim2, margin-left at 2s"); 1.349 +// prepend anim3 1.350 +div.style.animation = "anim3 linear 10s, anim1 linear 10s, anim2 linear 10s"; 1.351 + is(cs.getPropertyValue("margin-top"), "0px", 1.352 + "anim3 + anim1 + anim2, margin-top at 2s"); 1.353 + is(cs.getPropertyValue("margin-right"), "10px", 1.354 + "anim3 + anim1 + anim2, margin-right at 2s"); 1.355 + is(cs.getPropertyValue("margin-bottom"), "0px", 1.356 + "anim3 + anim1 + anim2, margin-bottom at 2s"); 1.357 + is(cs.getPropertyValue("margin-left"), "32px", 1.358 + "anim3 + anim1 + anim2, margin-left at 2s"); 1.359 +advance_clock(1000); 1.360 + is(cs.getPropertyValue("margin-top"), "10px", 1.361 + "anim3 + anim1 + anim2, margin-top at 3s"); 1.362 + is(cs.getPropertyValue("margin-right"), "20px", 1.363 + "anim3 + anim1 + anim2, margin-right at 3s"); 1.364 + is(cs.getPropertyValue("margin-bottom"), "0px", 1.365 + "anim3 + anim1 + anim2, margin-bottom at 3s"); 1.366 + is(cs.getPropertyValue("margin-left"), "48px", 1.367 + "anim3 + anim1 + anim2, margin-left at 3s"); 1.368 +// remove anim2 from end 1.369 +div.style.animation = "anim3 linear 10s, anim1 linear 10s"; 1.370 + is(cs.getPropertyValue("margin-top"), "10px", 1.371 + "anim3 + anim1, margin-top at 3s"); 1.372 + is(cs.getPropertyValue("margin-right"), "0px", 1.373 + "anim3 + anim1, margin-right at 3s"); 1.374 + is(cs.getPropertyValue("margin-bottom"), "0px", 1.375 + "anim3 + anim1, margin-bottom at 3s"); 1.376 + is(cs.getPropertyValue("margin-left"), "48px", 1.377 + "anim3 + anim1, margin-left at 3s"); 1.378 +advance_clock(1000); 1.379 + is(cs.getPropertyValue("margin-top"), "20px", 1.380 + "anim3 + anim1, margin-top at 4s"); 1.381 + is(cs.getPropertyValue("margin-right"), "0px", 1.382 + "anim3 + anim1, margin-right at 4s"); 1.383 + is(cs.getPropertyValue("margin-bottom"), "0px", 1.384 + "anim3 + anim1, margin-bottom at 4s"); 1.385 + is(cs.getPropertyValue("margin-left"), "64px", 1.386 + "anim3 + anim1, margin-left at 4s"); 1.387 +// swap anim1 and anim3, change duration of anim3 1.388 +div.style.animation = "anim1 linear 10s, anim3 linear 5s"; 1.389 + is(cs.getPropertyValue("margin-top"), "40px", 1.390 + "anim1 + anim3, margin-top at 4s"); 1.391 + is(cs.getPropertyValue("margin-right"), "0px", 1.392 + "anim1 + anim3, margin-right at 4s"); 1.393 + is(cs.getPropertyValue("margin-bottom"), "0px", 1.394 + "anim1 + anim3, margin-bottom at 4s"); 1.395 + is(cs.getPropertyValue("margin-left"), "64px", 1.396 + "anim1 + anim3, margin-left at 4s"); 1.397 +advance_clock(1000); 1.398 + is(cs.getPropertyValue("margin-top"), "60px", 1.399 + "anim1 + anim3, margin-top at 5s"); 1.400 + is(cs.getPropertyValue("margin-right"), "0px", 1.401 + "anim1 + anim3, margin-right at 5s"); 1.402 + is(cs.getPropertyValue("margin-bottom"), "0px", 1.403 + "anim1 + anim3, margin-bottom at 5s"); 1.404 + is(cs.getPropertyValue("margin-left"), "80px", 1.405 + "anim1 + anim3, margin-left at 5s"); 1.406 +// list anim1 twice, last duration wins, original start time still applies 1.407 +div.style.animation = "anim1 linear 10s, anim3 linear 5s, anim1 linear 20s"; 1.408 + is(cs.getPropertyValue("margin-top"), "60px", 1.409 + "anim1 + anim3 + anim1, margin-top at 5s"); 1.410 + is(cs.getPropertyValue("margin-right"), "0px", 1.411 + "anim1 + anim3 + anim1, margin-right at 5s"); 1.412 + is(cs.getPropertyValue("margin-bottom"), "0px", 1.413 + "anim1 + anim3 + anim1, margin-bottom at 5s"); 1.414 + is(cs.getPropertyValue("margin-left"), "40px", 1.415 + "anim1 + anim3 + anim1, margin-left at 5s"); 1.416 +// drop one of the anim1, and list anim5 as well, which animates 1.417 +// the same property as anim1 1.418 +div.style.animation = "anim3 linear 5s, anim1 linear 20s, anim5 linear 10s"; 1.419 + is(cs.getPropertyValue("margin-top"), "60px", 1.420 + "anim3 + anim1 + anim5, margin-top at 5s"); 1.421 + is(cs.getPropertyValue("margin-right"), "0px", 1.422 + "anim3 + anim1 + anim5, margin-right at 5s"); 1.423 + is(cs.getPropertyValue("margin-bottom"), "0px", 1.424 + "anim3 + anim1 + anim5, margin-bottom at 5s"); 1.425 + is(cs.getPropertyValue("margin-left"), "0px", 1.426 + "anim3 + anim1 + anim5, margin-left at 5s"); 1.427 +advance_clock(1000); 1.428 + is(cs.getPropertyValue("margin-top"), "80px", 1.429 + "anim3 + anim1 + anim5, margin-top at 6s"); 1.430 + is(cs.getPropertyValue("margin-right"), "0px", 1.431 + "anim3 + anim1 + anim5, margin-right at 6s"); 1.432 + is(cs.getPropertyValue("margin-bottom"), "0px", 1.433 + "anim3 + anim1 + anim5, margin-bottom at 6s"); 1.434 + is(cs.getPropertyValue("margin-left"), "10px", 1.435 + "anim3 + anim1 + anim5, margin-left at 6s"); 1.436 +// now swap the anim5 and anim1 order 1.437 +div.style.animation = "anim3 linear 5s, anim5 linear 10s, anim1 linear 20s"; 1.438 + is(cs.getPropertyValue("margin-top"), "80px", 1.439 + "anim3 + anim1 + anim5, margin-top at 6s"); 1.440 + is(cs.getPropertyValue("margin-right"), "0px", 1.441 + "anim3 + anim1 + anim5, margin-right at 6s"); 1.442 + is(cs.getPropertyValue("margin-bottom"), "0px", 1.443 + "anim3 + anim1 + anim5, margin-bottom at 6s"); 1.444 + is(cs.getPropertyValue("margin-left"), "48px", 1.445 + "anim3 + anim1 + anim5, margin-left at 6s"); 1.446 +advance_clock(1000); 1.447 + is(cs.getPropertyValue("margin-top"), "0px", 1.448 + "anim3 + anim1 + anim5, margin-top at 7s"); 1.449 + is(cs.getPropertyValue("margin-right"), "0px", 1.450 + "anim3 + anim1 + anim5, margin-right at 7s"); 1.451 + is(cs.getPropertyValue("margin-bottom"), "0px", 1.452 + "anim3 + anim1 + anim5, margin-bottom at 7s"); 1.453 + is(cs.getPropertyValue("margin-left"), "56px", 1.454 + "anim3 + anim1 + anim5, margin-left at 7s"); 1.455 +// swap anim1 and anim5 back 1.456 +div.style.animation = "anim3 linear 5s, anim1 linear 20s, anim5 linear 10s"; 1.457 + is(cs.getPropertyValue("margin-top"), "0px", 1.458 + "anim3 + anim1 + anim5, margin-top at 7s"); 1.459 + is(cs.getPropertyValue("margin-right"), "0px", 1.460 + "anim3 + anim1 + anim5, margin-right at 7s"); 1.461 + is(cs.getPropertyValue("margin-bottom"), "0px", 1.462 + "anim3 + anim1 + anim5, margin-bottom at 7s"); 1.463 + is(cs.getPropertyValue("margin-left"), "20px", 1.464 + "anim3 + anim1 + anim5, margin-left at 7s"); 1.465 +advance_clock(100); 1.466 + is(cs.getPropertyValue("margin-top"), "0px", 1.467 + "anim3 + anim1 + anim5, margin-top at 7.1s"); 1.468 +// Change the animation fill mode on the completed animation. 1.469 +div.style.animation = "anim3 linear 5s forwards, anim1 linear 20s, anim5 linear 10s"; 1.470 + is(cs.getPropertyValue("margin-top"), "100px", 1.471 + "anim3 + anim1 + anim5, margin-top at 7.1s, with fill mode"); 1.472 +advance_clock(900); 1.473 + is(cs.getPropertyValue("margin-top"), "100px", 1.474 + "anim3 + anim1 + anim5, margin-top at 8s, with fill mode"); 1.475 +// Change the animation duration on the completed animation, so it is 1.476 +// no longer completed. 1.477 +div.style.animation = "anim3 linear 10s, anim1 linear 20s, anim5 linear 10s"; 1.478 + is(cs.getPropertyValue("margin-top"), "60px", 1.479 + "anim3 + anim1 + anim5, margin-top at 8s, with fill mode"); 1.480 + is(cs.getPropertyValue("margin-left"), "30px", 1.481 + "anim3 + anim1 + anim5, margin-left at 8s"); 1.482 +done_div(); 1.483 + 1.484 +/* 1.485 + * css3-animations: 3. Keyframes 1.486 + * http://dev.w3.org/csswg/css3-animations/#keyframes 1.487 + * 1.488 + * Also see test_keyframes_rules.html . 1.489 + */ 1.490 + 1.491 +// Test the rules on keyframes that lack a 0% or 100% rule: 1.492 +// (simultaneously, test that reverse animations have their keyframes 1.493 +// run backwards) 1.494 + 1.495 +// 100px at 0%, 50px at 50%, 150px at 100% 1.496 +new_div("margin-top: 100px; animation: kf1 ease 1s alternate infinite"); 1.497 +is(cs.marginTop, "100px", "no-0% at 0.0s"); 1.498 +advance_clock(100); 1.499 +is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease(0.2), 0.01, 1.500 + "no-0% at 0.1s"); 1.501 +advance_clock(200); 1.502 +is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease(0.6), 0.01, 1.503 + "no-0% at 0.3s"); 1.504 +advance_clock(200); 1.505 +is(cs.marginTop, "50px", "no-0% at 0.5s"); 1.506 +advance_clock(200); 1.507 +is_approx(px_to_num(cs.marginTop), 50 + 100 * gTF.ease(0.4), 0.01, 1.508 + "no-0% at 0.7s"); 1.509 +advance_clock(200); 1.510 +is_approx(px_to_num(cs.marginTop), 50 + 100 * gTF.ease(0.8), 0.01, 1.511 + "no-0% at 0.9s"); 1.512 +advance_clock(100); 1.513 +is(cs.marginTop, "150px", "no-0% at 1.0s"); 1.514 +advance_clock(100); 1.515 +is_approx(px_to_num(cs.marginTop), 50 + 100 * gTF.ease(0.8), 0.01, 1.516 + "no-0% at 1.1s"); 1.517 +advance_clock(300); 1.518 +is_approx(px_to_num(cs.marginTop), 50 + 100 * gTF.ease(0.2), 0.01, 1.519 + "no-0% at 1.4s"); 1.520 +advance_clock(300); 1.521 +is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease(0.6), 0.01, 1.522 + "no-0% at 1.7s"); 1.523 +advance_clock(200); 1.524 +is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease(0.2), 0.01, 1.525 + "no-0% at 1.9s"); 1.526 +advance_clock(100); 1.527 +is(cs.marginTop, "100px", "no-0% at 2.0s"); 1.528 +done_div(); 1.529 + 1.530 +// 150px at 0%, 50px at 50%, 100px at 100% 1.531 +new_div("margin-top: 100px; animation: kf2 ease-in 1s alternate infinite"); 1.532 +is(cs.marginTop, "150px", "no-100% at 0.0s"); 1.533 +advance_clock(100); 1.534 +is_approx(px_to_num(cs.marginTop), 150 - 100 * gTF.ease_in(0.2), 0.01, 1.535 + "no-100% at 0.1s"); 1.536 +advance_clock(200); 1.537 +is_approx(px_to_num(cs.marginTop), 150 - 100 * gTF.ease_in(0.6), 0.01, 1.538 + "no-100% at 0.3s"); 1.539 +advance_clock(200); 1.540 +is(cs.marginTop, "50px", "no-100% at 0.5s"); 1.541 +advance_clock(200); 1.542 +is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_in(0.4), 0.01, 1.543 + "no-100% at 0.7s"); 1.544 +advance_clock(200); 1.545 +is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_in(0.8), 0.01, 1.546 + "no-100% at 0.9s"); 1.547 +advance_clock(100); 1.548 +is(cs.marginTop, "100px", "no-100% at 1.0s"); 1.549 +advance_clock(100); 1.550 +is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_in(0.8), 0.01, 1.551 + "no-100% at 1.1s"); 1.552 +advance_clock(300); 1.553 +is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_in(0.2), 0.01, 1.554 + "no-100% at 1.4s"); 1.555 +advance_clock(300); 1.556 +is_approx(px_to_num(cs.marginTop), 150 - 100 * gTF.ease_in(0.6), 0.01, 1.557 + "no-100% at 1.7s"); 1.558 +advance_clock(200); 1.559 +is_approx(px_to_num(cs.marginTop), 150 - 100 * gTF.ease_in(0.2), 0.01, 1.560 + "no-100% at 1.9s"); 1.561 +advance_clock(100); 1.562 +is(cs.marginTop, "150px", "no-100% at 2.0s"); 1.563 +done_div(); 1.564 + 1.565 + 1.566 +// 50px at 0%, 100px at 25%, 50px at 100% 1.567 +new_div("margin-top: 50px; animation: kf3 ease-out 1s alternate infinite"); 1.568 +is(cs.marginTop, "50px", "no-0%-no-100% at 0.0s"); 1.569 +advance_clock(50); 1.570 +is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_out(0.2), 0.01, 1.571 + "no-0%-no-100% at 0.05s"); 1.572 +advance_clock(100); 1.573 +is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_out(0.6), 0.01, 1.574 + "no-0%-no-100% at 0.15s"); 1.575 +advance_clock(100); 1.576 +is(cs.marginTop, "100px", "no-0%-no-100% at 0.25s"); 1.577 +advance_clock(300); 1.578 +is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease_out(0.4), 0.01, 1.579 + "no-0%-no-100% at 0.55s"); 1.580 +advance_clock(300); 1.581 +is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease_out(0.8), 0.01, 1.582 + "no-0%-no-100% at 0.85s"); 1.583 +advance_clock(150); 1.584 +is(cs.marginTop, "50px", "no-0%-no-100% at 1.0s"); 1.585 +advance_clock(150); 1.586 +is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease_out(0.8), 0.01, 1.587 + "no-0%-no-100% at 1.15s"); 1.588 +advance_clock(450); 1.589 +is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease_out(0.2), 0.01, 1.590 + "no-0%-no-100% at 1.6s"); 1.591 +advance_clock(250); 1.592 +is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_out(0.6), 0.01, 1.593 + "no-0%-no-100% at 1.85s"); 1.594 +advance_clock(100); 1.595 +is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_out(0.2), 0.01, 1.596 + "no-0%-no-100% at 1.95s"); 1.597 +advance_clock(50); 1.598 +is(cs.marginTop, "50px", "no-0%-no-100% at 2.0s"); 1.599 +done_div(); 1.600 + 1.601 +// Test that non-animatable properties are ignored. 1.602 +// Simultaneously, test that the block is still honored, and that 1.603 +// we still override the value when two consecutive keyframes have 1.604 +// the same value. 1.605 +new_div("animation: kf4 ease 10s"); 1.606 +is(cs.display, "block", 1.607 + "non-animatable properties should be ignored (linear, 0s)"); 1.608 +is(cs.marginTop, "37px", 1.609 + "animatable properties should still apply (linear, 0s)"); 1.610 +advance_clock(1000); 1.611 +is(cs.display, "block", 1.612 + "non-animatable properties should be ignored (linear, 1s)"); 1.613 +is(cs.marginTop, "37px", 1.614 + "animatable properties should still apply (linear, 1s)"); 1.615 +done_div(); 1.616 +new_div("animation: kf4 step-start 10s"); 1.617 +is(cs.display, "block", 1.618 + "non-animatable properties should be ignored (step-start, 0s)"); 1.619 +is(cs.marginTop, "37px", 1.620 + "animatable properties should still apply (step-start, 0s)"); 1.621 +advance_clock(1000); 1.622 +is(cs.display, "block", 1.623 + "non-animatable properties should be ignored (step-start, 1s)"); 1.624 +is(cs.marginTop, "37px", 1.625 + "animatable properties should still apply (step-start, 1s)"); 1.626 +done_div(); 1.627 + 1.628 +// Test cascading of the keyframes within an @keyframes rule. 1.629 +new_div("animation: kf_cascade1 linear 10s"); 1.630 +// 0%: 30px 1.631 +// 50%: 20px 1.632 +// 75%: 20px 1.633 +// 85%: 30px 1.634 +// 85.1%: 60px 1.635 +// 100%: 70px 1.636 +is(cs.paddingTop, "30px", "kf_cascade1 at 0s"); 1.637 +advance_clock(2500); 1.638 +is(cs.paddingTop, "25px", "kf_cascade1 at 2.5s"); 1.639 +advance_clock(2500); 1.640 +is(cs.paddingTop, "20px", "kf_cascade1 at 5s"); 1.641 +advance_clock(2000); 1.642 +is(cs.paddingTop, "20px", "kf_cascade1 at 7s"); 1.643 +advance_clock(500); 1.644 +is(cs.paddingTop, "20px", "kf_cascade1 at 7.5s"); 1.645 +advance_clock(500); 1.646 +is(cs.paddingTop, "25px", "kf_cascade1 at 8s"); 1.647 +advance_clock(500); 1.648 +is(cs.paddingTop, "30px", "kf_cascade1 at 8.5s"); 1.649 +advance_clock(10); 1.650 +is(cs.paddingTop, "60px", "kf_cascade1 at 8.51s"); 1.651 +advance_clock(745); 1.652 +is(cs.paddingTop, "65px", "kf_cascade1 at 9.2505s"); 1.653 +done_div(); 1.654 + 1.655 +// Test cascading of the @keyframes rules themselves. 1.656 +new_div("animation: kf_cascade2 linear 10s"); 1.657 +is(cs.marginTop, "0px", "@keyframes rule with margin-top should be ignored"); 1.658 +is(cs.marginLeft, "300px", "last @keyframes rule with margin-left should win"); 1.659 +done_div(); 1.660 + 1.661 +/* 1.662 + * css3-animations: 3.1. Timing functions for keyframes 1.663 + * http://dev.w3.org/csswg/css3-animations/#timing-functions-for-keyframes- 1.664 + */ 1.665 +new_div("animation: kf_tf1 ease-in 10s alternate infinite"); 1.666 +is(cs.paddingBottom, "20px", 1.667 + "keyframe timing functions test at 0s (test needed for flush)"); 1.668 +advance_clock(1000); 1.669 +is_approx(px_to_num(cs.paddingBottom), 20 + 40 * gTF.ease(0.4), 0.01, 1.670 + "keyframe timing functions test at 1s"); 1.671 +advance_clock(1000); 1.672 +is_approx(px_to_num(cs.paddingBottom), 20 + 40 * gTF.ease(0.8), 0.01, 1.673 + "keyframe timing functions test at 2s"); 1.674 +advance_clock(1000); 1.675 +is_approx(px_to_num(cs.paddingBottom), 60 + 100 * gTF.ease_in(0.2), 0.01, 1.676 + "keyframe timing functions test at 3s"); 1.677 +advance_clock(1000); 1.678 +is_approx(px_to_num(cs.paddingBottom), 60 + 100 * gTF.ease_in(0.6), 0.01, 1.679 + "keyframe timing functions test at 4s"); 1.680 +advance_clock(1000); 1.681 +is(cs.paddingBottom, "160px", 1.682 + "keyframe timing functions test at 5s"); 1.683 +advance_clock(1010); // avoid floating point error 1.684 +is_approx(px_to_num(cs.paddingBottom), 160 - 40 * step_end(5)(0.4), 0.01, 1.685 + "keyframe timing functions test at 6s"); 1.686 +advance_clock(1000); 1.687 +is_approx(px_to_num(cs.paddingBottom), 160 - 40 * step_end(5)(0.8), 0.01, 1.688 + "keyframe timing functions test at 7s"); 1.689 +advance_clock(990); 1.690 +is_approx(px_to_num(cs.paddingBottom), 120 - 100 * gTF.linear(0.2), 0.01, 1.691 + "keyframe timing functions test at 8s"); 1.692 +advance_clock(1000); 1.693 +is_approx(px_to_num(cs.paddingBottom), 120 - 100 * gTF.linear(0.6), 0.01, 1.694 + "keyframe timing functions test at 9s"); 1.695 +advance_clock(1000); 1.696 +is(cs.paddingBottom, "20px", 1.697 + "keyframe timing functions test at 10s"); 1.698 +advance_clock(20000); 1.699 +is(cs.paddingBottom, "20px", 1.700 + "keyframe timing functions test at 30s"); 1.701 +advance_clock(1000); 1.702 +is_approx(px_to_num(cs.paddingBottom), 120 - 100 * gTF.linear(0.6), 0.01, 1.703 + "keyframe timing functions test at 31s"); 1.704 +advance_clock(1000); 1.705 +is_approx(px_to_num(cs.paddingBottom), 120 - 100 * gTF.linear(0.2), 0.01, 1.706 + "keyframe timing functions test at 32s"); 1.707 +advance_clock(1000); 1.708 +is_approx(px_to_num(cs.paddingBottom), 160 - 40 * step_end(5)(0.8), 0.01, 1.709 + "keyframe timing functions test at 33s"); 1.710 +advance_clock(1000); 1.711 +is_approx(px_to_num(cs.paddingBottom), 160 - 40 * step_end(5)(0.4), 0.01, 1.712 + "keyframe timing functions test at 34s"); 1.713 +advance_clock(1000); 1.714 +is(cs.paddingBottom, "160px", 1.715 + "keyframe timing functions test at 35s"); 1.716 +advance_clock(1000); 1.717 +is_approx(px_to_num(cs.paddingBottom), 60 + 100 * gTF.ease_in(0.6), 0.01, 1.718 + "keyframe timing functions test at 36s"); 1.719 +advance_clock(1000); 1.720 +is_approx(px_to_num(cs.paddingBottom), 60 + 100 * gTF.ease_in(0.2), 0.01, 1.721 + "keyframe timing functions test at 37s"); 1.722 +advance_clock(1000); 1.723 +is_approx(px_to_num(cs.paddingBottom), 20 + 40 * gTF.ease(0.8), 0.01, 1.724 + "keyframe timing functions test at 38s"); 1.725 +advance_clock(1000); 1.726 +is_approx(px_to_num(cs.paddingBottom), 20 + 40 * gTF.ease(0.4), 0.01, 1.727 + "keyframe timing functions test at 39s"); 1.728 +advance_clock(1000); 1.729 +is(cs.paddingBottom, "20px", 1.730 + "keyframe timing functions test at 40s"); 1.731 +done_div(); 1.732 + 1.733 +// spot-check the same thing without alternate 1.734 +new_div("animation: kf_tf1 ease-in 10s infinite"); 1.735 +is(cs.paddingBottom, "20px", 1.736 + "keyframe timing functions test at 0s (test needed for flush)"); 1.737 +advance_clock(11000); 1.738 +is_approx(px_to_num(cs.paddingBottom), 20 + 40 * gTF.ease(0.4), 0.01, 1.739 + "keyframe timing functions test at 11s"); 1.740 +advance_clock(3000); 1.741 +is_approx(px_to_num(cs.paddingBottom), 60 + 100 * gTF.ease_in(0.6), 0.01, 1.742 + "keyframe timing functions test at 14s"); 1.743 +advance_clock(2000); 1.744 +is_approx(px_to_num(cs.paddingBottom), 160 - 40 * step_end(5)(0.4), 0.01, 1.745 + "keyframe timing functions test at 16s"); 1.746 +advance_clock(2000); 1.747 +is_approx(px_to_num(cs.paddingBottom), 120 - 100 * gTF.linear(0.2), 0.01, 1.748 + "keyframe timing functions test at 18s"); 1.749 +done_div(); 1.750 + 1.751 +/* 1.752 + * css3-animations: 3.2. The 'animation-name' Property 1.753 + * http://dev.w3.org/csswg/css3-animations/#the-animation-name-property- 1.754 + */ 1.755 + 1.756 +// animation-name is reasonably well-tested up in the tests for Section 1.757 +// 2, particularly the tests that "Test that animations continue running 1.758 +// when the animation name list is changed." 1.759 + 1.760 +// Test that 'animation-name: none' steps the animation, and setting 1.761 +// it again starts a new one. 1.762 + 1.763 +new_div(""); 1.764 +div.style.animation = "anim2 ease-in-out 10s"; 1.765 +is(cs.marginRight, "0px", "after setting animation-name to anim2"); 1.766 +advance_clock(1000); 1.767 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in_out(0.1), 0.01, 1.768 + "before changing animation-name to none"); 1.769 +div.style.animationName = "none"; 1.770 +is(cs.marginRight, "0px", "after changing animation-name to none"); 1.771 +advance_clock(1000); 1.772 +is(cs.marginRight, "0px", "after changing animation-name to none plus 1s"); 1.773 +div.style.animationName = "anim2"; 1.774 +is(cs.marginRight, "0px", "after changing animation-name to anim2"); 1.775 +advance_clock(1000); 1.776 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in_out(0.1), 0.01, 1.777 + "at 1s in animation when animation-name no longer none again"); 1.778 +div.style.animationName = "none"; 1.779 +is(cs.marginRight, "0px", "after changing animation-name to none"); 1.780 +advance_clock(1000); 1.781 +is(cs.marginRight, "0px", "after changing animation-name to none plus 1s"); 1.782 +done_div(); 1.783 + 1.784 +/* 1.785 + * css3-animations: 3.3. The 'animation-duration' Property 1.786 + * http://dev.w3.org/csswg/css3-animations/#the-animation-duration-property- 1.787 + */ 1.788 + 1.789 +// FIXME: test animation-duration of 0 (quite a bit, including interaction 1.790 +// with fill-mode, count, and reversing), once I know what the right 1.791 +// behavior is. 1.792 + 1.793 +/* 1.794 + * css3-animations: 3.4. The 'animation-timing-function' Property 1.795 + * http://dev.w3.org/csswg/css3-animations/#animation-timing-function_tag 1.796 + */ 1.797 + 1.798 +// tested in tests for section 3.1 1.799 + 1.800 +/* 1.801 + * css3-animations: 3.5. The 'animation-iteration-count' Property 1.802 + * http://dev.w3.org/csswg/css3-animations/#the-animation-iteration-count-property- 1.803 + */ 1.804 +new_div("animation: anim2 ease-in 10s 0.3 forwards"); 1.805 +is(cs.marginRight, "0px", "animation-iteration-count test 1 at 0s"); 1.806 +advance_clock(2000); 1.807 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01, 1.808 + "animation-iteration-count test 1 at 2s"); 1.809 +advance_clock(900); 1.810 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.29), 0.01, 1.811 + "animation-iteration-count test 1 at 2.9s"); 1.812 +advance_clock(100); 1.813 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.3), 0.01, 1.814 + "animation-iteration-count test 1 at 3s"); 1.815 +advance_clock(100); 1.816 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.3), 0.01, 1.817 + "animation-iteration-count test 1 at 3.1s"); 1.818 +advance_clock(5000); 1.819 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.3), 0.01, 1.820 + "animation-iteration-count test 1 at 8.1s"); 1.821 +done_div(); 1.822 + 1.823 +new_div("animation: anim2 ease-in 10s 0.3, anim3 ease-out 20s 1.2 alternate forwards, anim4 ease-in-out 5s 1.6 forwards"); 1.824 +is(cs.marginRight, "0px", "animation-iteration-count test 2 at 0s"); 1.825 +is(cs.marginTop, "0px", "animation-iteration-count test 3 at 0s"); 1.826 +is(cs.marginBottom, "0px", "animation-iteration-count test 4 at 0s"); 1.827 +advance_clock(2000); 1.828 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01, 1.829 + "animation-iteration-count test 2 at 2s"); 1.830 +is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_out(0.1), 0.01, 1.831 + "animation-iteration-count test 3 at 2s"); 1.832 +is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.4), 0.01, 1.833 + "animation-iteration-count test 4 at 2s"); 1.834 +advance_clock(900); 1.835 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.29), 0.01, 1.836 + "animation-iteration-count test 2 at 2.9s"); 1.837 +advance_clock(200); 1.838 +is(cs.marginRight, "0px", "animation-iteration-count test 2 at 3.1s"); 1.839 +advance_clock(1800); 1.840 +is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.98), 0.01, 1.841 + "animation-iteration-count test 4 at 4.9s"); 1.842 +advance_clock(200); 1.843 +is(cs.marginRight, "0px", "animation-iteration-count test 2 at 5.1s"); 1.844 +is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.02), 0.01, 1.845 + "animation-iteration-count test 4 at 5.1s"); 1.846 +advance_clock(2800); 1.847 +is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.58), 0.01, 1.848 + "animation-iteration-count test 4 at 7.9s"); 1.849 +advance_clock(100); 1.850 +is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.6), 0.01, 1.851 + "animation-iteration-count test 4 at 8s"); 1.852 +advance_clock(100); 1.853 +is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.6), 0.01, 1.854 + "animation-iteration-count test 4 at 8.1s"); 1.855 +advance_clock(11700); 1.856 +is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_out(0.99), 0.01, 1.857 + "animation-iteration-count test 3 at 19.8s"); 1.858 +advance_clock(200); 1.859 +is(cs.marginTop, "100px", "animation-iteration-count test 3 at 20s"); 1.860 +advance_clock(200); 1.861 +is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_out(0.99), 0.01, 1.862 + "animation-iteration-count test 3 at 20.2s"); 1.863 +advance_clock(3600); 1.864 +is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_out(0.81), 0.01, 1.865 + "animation-iteration-count test 3 at 23.8s"); 1.866 +advance_clock(200); 1.867 +is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_out(0.8), 0.01, 1.868 + "animation-iteration-count test 3 at 24s"); 1.869 +advance_clock(200); 1.870 +is(cs.marginRight, "0px", "animation-iteration-count test 2 at 25s"); 1.871 +is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_out(0.8), 0.01, 1.872 + "animation-iteration-count test 3 at 25s"); 1.873 +is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.6), 0.01, 1.874 + "animation-iteration-count test 4 at 25s"); 1.875 +done_div(); 1.876 + 1.877 +/* 1.878 + * css3-animations: 3.6. The 'animation-direction' Property 1.879 + * http://dev.w3.org/csswg/css3-animations/#the-animation-direction-property- 1.880 + */ 1.881 + 1.882 +// Tested in tests for sections 3.1 and 3.5. 1.883 + 1.884 +new_div("animation: anim2 ease-in 10s infinite"); 1.885 +div.style.animationDirection = "normal"; 1.886 +is(cs.marginRight, "0px", "animation-direction test 1 (normal) at 0s"); 1.887 +div.style.animationDirection = "reverse"; 1.888 +is(cs.marginRight, "100px", "animation-direction test 1 (reverse) at 0s"); 1.889 +div.style.animationDirection = "alternate"; 1.890 +is(cs.marginRight, "0px", "animation-direction test 1 (alternate) at 0s"); 1.891 +div.style.animationDirection = "alternate-reverse"; 1.892 +is(cs.marginRight, "100px", "animation-direction test 1 (alternate-reverse) at 0s"); 1.893 +advance_clock(2000); 1.894 +div.style.animationDirection = "normal"; 1.895 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01, 1.896 + "animation-direction test 1 (normal) at 2s"); 1.897 +div.style.animationDirection = "reverse"; 1.898 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.8), 0.01, 1.899 + "animation-direction test 1 (reverse) at 2s"); 1.900 +div.style.animationDirection = "alternate"; 1.901 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01, 1.902 + "animation-direction test 1 (alternate) at 2s"); 1.903 +div.style.animationDirection = "alternate-reverse"; 1.904 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.8), 0.01, 1.905 + "animation-direction test 1 (alternate-reverse) at 2s"); 1.906 +advance_clock(5000); 1.907 +div.style.animationDirection = "normal"; 1.908 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.7), 0.01, 1.909 + "animation-direction test 1 (normal) at 7s"); 1.910 +div.style.animationDirection = "reverse"; 1.911 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.3), 0.01, 1.912 + "animation-direction test 1 (reverse) at 7s"); 1.913 +div.style.animationDirection = "alternate"; 1.914 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.7), 0.01, 1.915 + "animation-direction test 1 (alternate) at 7s"); 1.916 +div.style.animationDirection = "alternate-reverse"; 1.917 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.3), 0.01, 1.918 + "animation-direction test 1 (alternate-reverse) at 7s"); 1.919 +advance_clock(5000); 1.920 +div.style.animationDirection = "normal"; 1.921 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01, 1.922 + "animation-direction test 1 (normal) at 12s"); 1.923 +div.style.animationDirection = "reverse"; 1.924 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.8), 0.01, 1.925 + "animation-direction test 1 (reverse) at 12s"); 1.926 +div.style.animationDirection = "alternate"; 1.927 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.8), 0.01, 1.928 + "animation-direction test 1 (alternate) at 12s"); 1.929 +div.style.animationDirection = "alternate-reverse"; 1.930 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01, 1.931 + "animation-direction test 1 (alternate-reverse) at 12s"); 1.932 +advance_clock(10000); 1.933 +div.style.animationDirection = "normal"; 1.934 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01, 1.935 + "animation-direction test 1 (normal) at 22s"); 1.936 +div.style.animationDirection = "reverse"; 1.937 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.8), 0.01, 1.938 + "animation-direction test 1 (reverse) at 22s"); 1.939 +div.style.animationDirection = "alternate"; 1.940 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01, 1.941 + "animation-direction test 1 (alternate) at 22s"); 1.942 +div.style.animationDirection = "alternate-reverse"; 1.943 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.8), 0.01, 1.944 + "animation-direction test 1 (alternate-reverse) at 22s"); 1.945 +advance_clock(30000); 1.946 +div.style.animationDirection = "normal"; 1.947 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01, 1.948 + "animation-direction test 1 (normal) at 52s"); 1.949 +div.style.animationDirection = "reverse"; 1.950 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.8), 0.01, 1.951 + "animation-direction test 1 (reverse) at 52s"); 1.952 +div.style.animationDirection = "alternate"; 1.953 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.8), 0.01, 1.954 + "animation-direction test 1 (alternate) at 52s"); 1.955 +div.style.animationDirection = "alternate-reverse"; 1.956 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01, 1.957 + "animation-direction test 1 (alternate-reverse) at 52s"); 1.958 +done_div(); 1.959 + 1.960 +/* 1.961 + * css3-animations: 3.7. The 'animation-play-state' Property 1.962 + * http://dev.w3.org/csswg/css3-animations/#the-animation-play-state-property- 1.963 + */ 1.964 + 1.965 +// simple test with just one animation 1.966 +new_div(""); 1.967 +div.style.animationTimingFunction = "ease"; 1.968 +div.style.animationName = "anim1"; 1.969 +div.style.animationDuration = "1s"; 1.970 +div.style.animationDirection = "alternate"; 1.971 +div.style.animationIterationCount = "2"; 1.972 +is(cs.marginLeft, "0px", "animation-play-state test 1, at 0s"); 1.973 +advance_clock(250); 1.974 +is_approx(px_to_num(cs.marginLeft), 80 * gTF.ease(0.5), 0.01, 1.975 + "animation-play-state test 1 at 250ms"); 1.976 +div.style.animationPlayState = "paused"; 1.977 +is_approx(px_to_num(cs.marginLeft), 80 * gTF.ease(0.5), 0.01, 1.978 + "animation-play-state test 1 at 250ms"); 1.979 +advance_clock(250); 1.980 +is_approx(px_to_num(cs.marginLeft), 80 * gTF.ease(0.5), 0.01, 1.981 + "animation-play-state test 1 still at 500ms"); 1.982 +div.style.animationPlayState = "running"; 1.983 +is_approx(px_to_num(cs.marginLeft), 80 * gTF.ease(0.5), 0.01, 1.984 + "animation-play-state test 1 still at 500ms"); 1.985 +advance_clock(500); 1.986 +is_approx(px_to_num(cs.marginLeft), 80 + 20 * gTF.ease(0.5), 0.01, 1.987 + "animation-play-state test 1 at 1000ms"); 1.988 +advance_clock(250); 1.989 +is(cs.marginLeft, "100px", "animation-play-state test 1 at 1250ms"); 1.990 +advance_clock(250); 1.991 +is_approx(px_to_num(cs.marginLeft), 80 + 20 * gTF.ease(0.5), 0.01, 1.992 + "animation-play-state test 1 at 1500ms"); 1.993 +div.style.animationPlayState = "paused"; 1.994 +is_approx(px_to_num(cs.marginLeft), 80 + 20 * gTF.ease(0.5), 0.01, 1.995 + "animation-play-state test 1 at 1500ms"); 1.996 +advance_clock(2000); 1.997 +is_approx(px_to_num(cs.marginLeft), 80 + 20 * gTF.ease(0.5), 0.01, 1.998 + "animation-play-state test 1 at 3500ms"); 1.999 +advance_clock(500); 1.1000 +is_approx(px_to_num(cs.marginLeft), 80 + 20 * gTF.ease(0.5), 0.01, 1.1001 + "animation-play-state test 1 at 4000ms"); 1.1002 +div.style.animationPlayState = ""; 1.1003 +is_approx(px_to_num(cs.marginLeft), 80 + 20 * gTF.ease(0.5), 0.01, 1.1004 + "animation-play-state test 1 at 4000ms"); 1.1005 +advance_clock(500); 1.1006 +is_approx(px_to_num(cs.marginLeft), 80 * gTF.ease(0.5), 0.01, 1.1007 + "animation-play-state test 1 at 4500ms"); 1.1008 +advance_clock(250); 1.1009 +is(cs.marginLeft, "0px", "animation-play-state test 1, at 4750ms"); 1.1010 +advance_clock(250); 1.1011 +is(cs.marginLeft, "0px", "animation-play-state test 1, at 5000ms"); 1.1012 +done_div(); 1.1013 + 1.1014 +// more complicated test with multiple animations (and different directions 1.1015 +// and iteration counts) 1.1016 +new_div(""); 1.1017 +div.style.animationTimingFunction = "ease-out, ease-in, ease-in-out"; 1.1018 +div.style.animationName = "anim2, anim3, anim4"; 1.1019 +div.style.animationDuration = "1s, 2s, 1s"; 1.1020 +div.style.animationDirection = "alternate, normal, normal"; 1.1021 +div.style.animationIterationCount = "4, 2, infinite"; 1.1022 +is(cs.marginRight, "0px", "animation-play-state test 2, at 0s"); 1.1023 +is(cs.marginTop, "0px", "animation-play-state test 3, at 0s"); 1.1024 +is(cs.marginBottom, "0px", "animation-play-state test 4, at 0s"); 1.1025 +advance_clock(250); 1.1026 +div.style.animationPlayState = "paused, running"; // pause 1 and 3 1.1027 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.25), 0.01, 1.1028 + "animation-play-state test 2 at 250ms"); 1.1029 +is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.125), 0.01, 1.1030 + "animation-play-state test 3 at 250ms"); 1.1031 +is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.25), 0.01, 1.1032 + "animation-play-state test 4 at 250ms"); 1.1033 +advance_clock(250); 1.1034 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.25), 0.01, 1.1035 + "animation-play-state test 2 at 500ms"); 1.1036 +is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.25), 0.01, 1.1037 + "animation-play-state test 3 at 500ms"); 1.1038 +is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.25), 0.01, 1.1039 + "animation-play-state test 4 at 500ms"); 1.1040 +div.style.animationPlayState = "paused, running, running"; // unpause 3 1.1041 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.25), 0.01, 1.1042 + "animation-play-state test 2 at 500ms"); 1.1043 +is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.25), 0.01, 1.1044 + "animation-play-state test 3 at 500ms"); 1.1045 +is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.25), 0.01, 1.1046 + "animation-play-state test 4 at 500ms"); 1.1047 +advance_clock(250); 1.1048 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.25), 0.01, 1.1049 + "animation-play-state test 2 at 750ms"); 1.1050 +is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.375), 0.01, 1.1051 + "animation-play-state test 3 at 750ms"); 1.1052 +is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.5), 0.01, 1.1053 + "animation-play-state test 4 at 750ms"); 1.1054 +div.style.animationPlayState = "running, paused"; // unpause 1, pause 2 1.1055 +advance_clock(0); // notify refresh observers 1.1056 +advance_clock(250); 1.1057 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.5), 0.01, 1.1058 + "animation-play-state test 2 at 1000ms"); 1.1059 +is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.375), 0.01, 1.1060 + "animation-play-state test 3 at 1000ms"); 1.1061 +is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.75), 0.01, 1.1062 + "animation-play-state test 4 at 1000ms"); 1.1063 +div.style.animationPlayState = "paused"; // pause all 1.1064 +advance_clock(0); // notify refresh observers 1.1065 +advance_clock(3000); 1.1066 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.5), 0.01, 1.1067 + "animation-play-state test 2 at 4000ms"); 1.1068 +is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.375), 0.01, 1.1069 + "animation-play-state test 3 at 4000ms"); 1.1070 +is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.75), 0.01, 1.1071 + "animation-play-state test 4 at 4000ms"); 1.1072 +div.style.animationPlayState = "running, paused"; // pause 2 1.1073 +advance_clock(0); // notify refresh observers 1.1074 +advance_clock(850); 1.1075 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.65), 0.01, 1.1076 + "animation-play-state test 2 at 4850ms"); 1.1077 +is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.375), 0.01, 1.1078 + "animation-play-state test 3 at 4850ms"); 1.1079 +is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.6), 0.01, 1.1080 + "animation-play-state test 4 at 4850ms"); 1.1081 +advance_clock(300); 1.1082 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.35), 0.01, 1.1083 + "animation-play-state test 2 at 5150ms"); 1.1084 +is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.375), 0.01, 1.1085 + "animation-play-state test 3 at 5150ms"); 1.1086 +is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.9), 0.01, 1.1087 + "animation-play-state test 4 at 5150ms"); 1.1088 +advance_clock(2300); 1.1089 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.05), 0.01, 1.1090 + "animation-play-state test 2 at 7450ms"); 1.1091 +is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.375), 0.01, 1.1092 + "animation-play-state test 3 at 7450ms"); 1.1093 +is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.2), 0.01, 1.1094 + "animation-play-state test 4 at 7450ms"); 1.1095 +advance_clock(100); 1.1096 +is(cs.marginRight, "0px", "animation-play-state test 2 at 7550ms"); 1.1097 +is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.375), 0.01, 1.1098 + "animation-play-state test 3 at 7550ms"); 1.1099 +is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.3), 0.01, 1.1100 + "animation-play-state test 4 at 7550ms"); 1.1101 +div.style.animationPlayState = "running"; // unpause 2 1.1102 +advance_clock(0); // notify refresh observers 1.1103 +advance_clock(1000); 1.1104 +is(cs.marginRight, "0px", "animation-play-state test 2 at 7550ms"); 1.1105 +is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.875), 0.01, 1.1106 + "animation-play-state test 3 at 7550ms"); 1.1107 +is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.3), 0.01, 1.1108 + "animation-play-state test 4 at 7550ms"); 1.1109 +advance_clock(500); 1.1110 +is(cs.marginRight, "0px", "animation-play-state test 2 at 8050ms"); 1.1111 +is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.125), 0.01, 1.1112 + "animation-play-state test 3 at 8050ms"); 1.1113 +is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.8), 0.01, 1.1114 + "animation-play-state test 4 at 8050ms"); 1.1115 +advance_clock(1000); 1.1116 +is(cs.marginRight, "0px", "animation-play-state test 2 at 9050ms"); 1.1117 +is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.625), 0.01, 1.1118 + "animation-play-state test 3 at 9050ms"); 1.1119 +is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.8), 0.01, 1.1120 + "animation-play-state test 4 at 9050ms"); 1.1121 +advance_clock(500); 1.1122 +is(cs.marginRight, "0px", "animation-play-state test 2 at 9550ms"); 1.1123 +is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.875), 0.01, 1.1124 + "animation-play-state test 3 at 9550ms"); 1.1125 +is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.3), 0.01, 1.1126 + "animation-play-state test 4 at 9550ms"); 1.1127 +advance_clock(500); 1.1128 +is(cs.marginRight, "0px", "animation-play-state test 2 at 10050ms"); 1.1129 +is(cs.marginTop, "0px", "animation-play-state test 3 at 10050ms"); 1.1130 +is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.8), 0.01, 1.1131 + "animation-play-state test 4 at 10050ms"); 1.1132 +done_div(); 1.1133 + 1.1134 +/* 1.1135 + * css3-animations: 3.8. The 'animation-delay' Property 1.1136 + * http://dev.w3.org/csswg/css3-animations/#the-animation-delay-property- 1.1137 + */ 1.1138 + 1.1139 +// test positive delay 1.1140 +new_div("animation: anim2 1s 0.5s ease-out"); 1.1141 +is(cs.marginRight, "0px", "positive delay test at 0ms"); 1.1142 +advance_clock(400); 1.1143 +is(cs.marginRight, "0px", "positive delay test at 400ms"); 1.1144 +advance_clock(100); 1.1145 +is(cs.marginRight, "0px", "positive delay test at 500ms"); 1.1146 +advance_clock(100); 1.1147 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.1), 0.01, 1.1148 + "positive delay test at 500ms"); 1.1149 +done_div(); 1.1150 + 1.1151 +// test dynamic changes to delay (i.e., that we preserve the start time 1.1152 +// that's before the delay) 1.1153 +new_div("animation: anim2 1s 0.5s ease-out both"); 1.1154 +is(cs.marginRight, "0px", "dynamic delay delay test at 0ms"); 1.1155 +advance_clock(400); 1.1156 +is(cs.marginRight, "0px", "dynamic delay delay test at 400ms (1)"); 1.1157 +div.style.animationDelay = "0.2s"; 1.1158 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.2), 0.01, 1.1159 + "dynamic delay delay test at 400ms (2)"); 1.1160 +div.style.animationDelay = "0.6s"; 1.1161 +advance_clock(0); 1.1162 +advance_clock(200); 1.1163 +is(cs.marginRight, "0px", "dynamic delay delay test at 600ms"); 1.1164 +advance_clock(200); 1.1165 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.2), 0.01, 1.1166 + "dynamic delay delay test at 800ms"); 1.1167 +advance_clock(1000); 1.1168 +is(cs.marginRight, "100px", "dynamic delay delay test at 1800ms (1)"); 1.1169 +div.style.animationDelay = "1.5s"; 1.1170 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.3), 0.01, 1.1171 + "dynamic delay delay test at 1800ms (2)"); 1.1172 +div.style.animationDelay = "2s"; 1.1173 +is(cs.marginRight, "0px", "dynamic delay delay test at 1800ms (3)"); 1.1174 +done_div(); 1.1175 + 1.1176 +// test delay and play-state interaction 1.1177 +new_div("animation: anim2 1s 0.5s ease-out"); 1.1178 +is(cs.marginRight, "0px", "delay and play-state delay test at 0ms"); 1.1179 +advance_clock(400); 1.1180 +is(cs.marginRight, "0px", "delay and play-state delay test at 400ms"); 1.1181 +div.style.animationPlayState = "paused"; 1.1182 +advance_clock(0); 1.1183 +advance_clock(100); 1.1184 +is(cs.marginRight, "0px", "delay and play-state delay test at 500ms"); 1.1185 +advance_clock(500); 1.1186 +is(cs.marginRight, "0px", "delay and play-state delay test at 1000ms"); 1.1187 +div.style.animationPlayState = "running"; 1.1188 +advance_clock(0); 1.1189 +advance_clock(100); 1.1190 +is(cs.marginRight, "0px", "delay and play-state delay test at 1100ms"); 1.1191 +advance_clock(100); 1.1192 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.1), 0.01, 1.1193 + "delay and play-state delay test at 1200ms"); 1.1194 +div.style.animationPlayState = "paused"; 1.1195 +advance_clock(0); 1.1196 +advance_clock(100); 1.1197 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.1), 0.01, 1.1198 + "delay and play-state delay test at 1300ms"); 1.1199 +done_div(); 1.1200 + 1.1201 +// test negative delay and implicit starting values 1.1202 +new_div("margin-top: 1000px"); 1.1203 +advance_clock(300); 1.1204 +div.style.marginTop = "100px"; 1.1205 +div.style.animation = "kf1 1s -0.1s ease-in"; 1.1206 +is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease_in(0.2), 0.01, 1.1207 + "delay and implicit starting values test"); 1.1208 +done_div(); 1.1209 + 1.1210 +// test large negative delay that causes the animation to start 1.1211 +// in the fourth iteration 1.1212 +new_div("animation: anim2 1s -3.6s ease-in 5 alternate forwards"); 1.1213 +listen(); // rely on no flush having happened yet 1.1214 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.4), 0.01, 1.1215 + "large negative delay test at 0ms"); 1.1216 +check_events([{ type: 'animationstart', target: div, 1.1217 + animationName: 'anim2', elapsedTime: 3.6, 1.1218 + pseudoElement: "" }], 1.1219 + "right after start in large negative delay test"); 1.1220 +advance_clock(380); 1.1221 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.02), 0.01, 1.1222 + "large negative delay test at 380ms"); 1.1223 +check_events([]); 1.1224 +advance_clock(20); 1.1225 +is(cs.marginRight, "0px", "large negative delay test at 400ms"); 1.1226 +check_events([{ type: 'animationiteration', target: div, 1.1227 + animationName: 'anim2', elapsedTime: 4.0, 1.1228 + pseudoElement: "" }], 1.1229 + "right after start in large negative delay test"); 1.1230 +advance_clock(800); 1.1231 +is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.8), 0.01, 1.1232 + "large negative delay test at 1200ms"); 1.1233 +check_events([]); 1.1234 +advance_clock(200); 1.1235 +is(cs.marginRight, "100px", "large negative delay test at 1400ms"); 1.1236 +check_events([{ type: 'animationend', target: div, 1.1237 + animationName: 'anim2', elapsedTime: 5.0, 1.1238 + pseudoElement: "" }], 1.1239 + "right after start in large negative delay test"); 1.1240 +done_div(); 1.1241 + 1.1242 +/* 1.1243 + * css3-animations: 3.9. The 'animation-fill-mode' Property 1.1244 + * http://dev.w3.org/csswg/css3-animations/#the-animation-fill-mode-property- 1.1245 + */ 1.1246 + 1.1247 +// animation-fill-mode is tested in the tests for section (2). 1.1248 + 1.1249 +/* 1.1250 + * css3-animations: 3.10. The 'animation' Shorthand Property 1.1251 + * http://dev.w3.org/csswg/css3-animations/#the-animation-shorthand-property- 1.1252 + */ 1.1253 + 1.1254 +// shorthand vs. longhand is adequately tested by the 1.1255 +// property_database.js-based tests. 1.1256 + 1.1257 +/** 1.1258 + * Basic tests of animations on pseudo-elements 1.1259 + */ 1.1260 +new_div(""); 1.1261 +listen(); 1.1262 +div.id = "withbefore"; 1.1263 +var cs_before = getComputedStyle(div, ":before"); 1.1264 +is(cs_before.marginRight, "0px", ":before test at 0ms"); 1.1265 +advance_clock(400); 1.1266 +is(cs_before.marginRight, "40px", ":before test at 400ms"); 1.1267 +advance_clock(800); 1.1268 +is(cs_before.marginRight, "80px", ":before test at 1200ms"); 1.1269 +is(cs.marginRight, "0px", ":before animation should not affect element"); 1.1270 +advance_clock(800); 1.1271 +is(cs_before.marginRight, "0px", ":before test at 2000ms"); 1.1272 +advance_clock(300); 1.1273 +is(cs_before.marginRight, "30px", ":before test at 2300ms"); 1.1274 +advance_clock(700); 1.1275 +check_events([ { type: "animationstart", animationName: "anim2", elapsedTime: 0, pseudoElement: "::before" }, 1.1276 + { type: "animationiteration", animationName: "anim2", elapsedTime: 1.2, pseudoElement: "::before" }, 1.1277 + { type: "animationiteration", animationName: "anim2", elapsedTime: 2, pseudoElement: "::before" }, 1.1278 + { type: "animationend", animationName: "anim2", elapsedTime: 3, pseudoElement: "::before" }]); 1.1279 +done_div(); 1.1280 + 1.1281 +new_div(""); 1.1282 +listen(); 1.1283 +div.id = "withafter"; 1.1284 +var cs_after = getComputedStyle(div, ":after"); 1.1285 +is(cs_after.marginRight, "0px", ":after test at 0ms"); 1.1286 +advance_clock(400); 1.1287 +is(cs_after.marginRight, "40px", ":after test at 400ms"); 1.1288 +advance_clock(800); 1.1289 +is(cs_after.marginRight, "80px", ":after test at 1200ms"); 1.1290 +is(cs.marginRight, "0px", ":after animation should not affect element"); 1.1291 +advance_clock(800); 1.1292 +is(cs_after.marginRight, "0px", ":after test at 2000ms"); 1.1293 +advance_clock(300); 1.1294 +is(cs_after.marginRight, "30px", ":after test at 2300ms"); 1.1295 +advance_clock(700); 1.1296 +check_events([ { type: "animationstart", animationName: "anim2", elapsedTime: 0, pseudoElement: "::after" }, 1.1297 + { type: "animationiteration", animationName: "anim2", elapsedTime: 1.2, pseudoElement: "::after" }, 1.1298 + { type: "animationiteration", animationName: "anim2", elapsedTime: 2, pseudoElement: "::after" }, 1.1299 + { type: "animationend", animationName: "anim2", elapsedTime: 3, pseudoElement: "::after" }]); 1.1300 +done_div(); 1.1301 + 1.1302 +/** 1.1303 + * Test handling of properties that are present in only some of the 1.1304 + * keyframes. 1.1305 + */ 1.1306 +new_div("animation: multiprop 1s ease-in-out alternate infinite"); 1.1307 +is(cs.paddingTop, "10px", "multiprop top at 0ms"); 1.1308 +is(cs.paddingLeft, "30px", "multiprop top at 0ms"); 1.1309 +advance_clock(100); 1.1310 +is_approx(px_to_num(cs.paddingTop), 10 + 30 * gTF.ease(0.2), 0.01, 1.1311 + "multiprop top at 100ms"); 1.1312 +is_approx(px_to_num(cs.paddingLeft), 30 + 20 * gTF.ease(0.4), 0.01, 1.1313 + "multiprop left at 100ms"); 1.1314 +advance_clock(200); 1.1315 +is_approx(px_to_num(cs.paddingTop), 10 + 30 * gTF.ease(0.6), 0.01, 1.1316 + "multiprop top at 300ms"); 1.1317 +is_approx(px_to_num(cs.paddingLeft), 50 + 10 * gTF.ease_out(0.1), 0.01, 1.1318 + "multiprop left at 300ms"); 1.1319 +advance_clock(300); 1.1320 +is_approx(px_to_num(cs.paddingTop), 40 + 40 * gTF.ease_in_out(0.4), 0.01, 1.1321 + "multiprop top at 600ms"); 1.1322 +is_approx(px_to_num(cs.paddingLeft), 50 + 10 * gTF.ease_out(0.7), 0.01, 1.1323 + "multiprop left at 600ms"); 1.1324 +advance_clock(200); 1.1325 +is_approx(px_to_num(cs.paddingTop), 80 - 80 * gTF.ease_in(0.2), 0.01, 1.1326 + "multiprop top at 800ms"); 1.1327 +is_approx(px_to_num(cs.paddingLeft), 60 - 60 * gTF.ease_in(0.2), 0.01, 1.1328 + "multiprop left at 800ms"); 1.1329 +advance_clock(400); 1.1330 +is_approx(px_to_num(cs.paddingTop), 80 - 80 * gTF.ease_in(0.2), 0.01, 1.1331 + "multiprop top at 1200ms"); 1.1332 +is_approx(px_to_num(cs.paddingLeft), 60 - 60 * gTF.ease_in(0.2), 0.01, 1.1333 + "multiprop left at 1200ms"); 1.1334 +advance_clock(200); 1.1335 +is_approx(px_to_num(cs.paddingTop), 40 + 40 * gTF.ease_in_out(0.4), 0.01, 1.1336 + "multiprop top at 1400ms"); 1.1337 +is_approx(px_to_num(cs.paddingLeft), 50 + 10 * gTF.ease_out(0.7), 0.01, 1.1338 + "multiprop left at 1400ms"); 1.1339 +advance_clock(300); 1.1340 +is_approx(px_to_num(cs.paddingTop), 10 + 30 * gTF.ease(0.6), 0.01, 1.1341 + "multiprop top at 1700ms"); 1.1342 +is_approx(px_to_num(cs.paddingLeft), 50 + 10 * gTF.ease_out(0.1), 0.01, 1.1343 + "multiprop left at 1700ms"); 1.1344 +advance_clock(200); 1.1345 +is_approx(px_to_num(cs.paddingTop), 10 + 30 * gTF.ease(0.2), 0.01, 1.1346 + "multiprop top at 1900ms"); 1.1347 +is_approx(px_to_num(cs.paddingLeft), 30 + 20 * gTF.ease(0.4), 0.01, 1.1348 + "multiprop left at 1900ms"); 1.1349 +done_div(); 1.1350 + 1.1351 +// Test for https://bugzilla.mozilla.org/show_bug.cgi?id=651456 -- make 1.1352 +// sure that refreshing of animations doesn't break when we get two 1.1353 +// refreshes with the same timestamp. 1.1354 +new_div("animation: anim2 1s linear"); 1.1355 +is(cs.marginRight, "0px", "bug 651456 at 0ms"); 1.1356 +advance_clock(100); 1.1357 +is(cs.marginRight, "10px", "bug 651456 at 100ms (1)"); 1.1358 +advance_clock(0); // still forces a refresh 1.1359 +is(cs.marginRight, "10px", "bug 651456 at 100ms (2)"); 1.1360 +advance_clock(100); 1.1361 +is(cs.marginRight, "20px", "bug 651456 at 200ms"); 1.1362 +done_div(); 1.1363 + 1.1364 +// Test that UA !important rules override animations. 1.1365 +// This test depends on forms.css having a rule 1.1366 +// select { line-height: !important } 1.1367 +// If that rule changes, we should rewrite it to depend on a different rule. 1.1368 +new_element("select", ""); 1.1369 +var default_line_height = cs.lineHeight; 1.1370 +done_div(); 1.1371 +new_element("select", "animation: uaoverride 2s linear infinite"); 1.1372 +is(cs.lineHeight, default_line_height, 1.1373 + "animations should not override UA !important at 0ms"); 1.1374 +is(cs.marginTop, "20px", 1.1375 + "rest of animation should still work when UA !important present at 0ms"); 1.1376 +advance_clock(200); 1.1377 +is(cs.lineHeight, default_line_height, 1.1378 + "animations should not override UA !important at 200ms"); 1.1379 +is(cs.marginTop, "40px", 1.1380 + "rest of animation should still work when UA !important present at 200ms"); 1.1381 +done_div(); 1.1382 + 1.1383 +// Test that author !important rules override animations, but 1.1384 +// that animations override regular author rules. 1.1385 +new_div("animation: always_fifty 1s linear infinite; margin-left: 200px"); 1.1386 +is(cs.marginLeft, "50px", "animations override regular author rules"); 1.1387 +done_div(); 1.1388 +new_div("animation: always_fifty 1s linear infinite; margin-left: 200px ! important;"); 1.1389 +is(cs.marginLeft, "200px", "important author rules override animations"); 1.1390 +done_div(); 1.1391 + 1.1392 +// Test interaction of animations and restyling (Bug 686656). 1.1393 +// This test depends on kf3 getting its 0% and 100% values from the 1.1394 +// rules below it in the cascade; we're checking that the animation 1.1395 +// isn't rebuilt when the restyles happen. 1.1396 +new_div("animation: kf3 1s linear forwards"); 1.1397 +is(cs.marginTop, "0px", "bug 686656 test 1 at 0ms"); 1.1398 +advance_clock(250); 1.1399 +display.style.color = "blue"; 1.1400 +is(cs.marginTop, "100px", "bug 686656 test 1 at 250ms"); 1.1401 +advance_clock(375); 1.1402 +is(cs.marginTop, "50px", "bug 686656 test 1 at 625ms"); 1.1403 +advance_clock(375); 1.1404 +is(cs.marginTop, "0px", "bug 686656 test 1 at 1000ms"); 1.1405 +done_div(); 1.1406 +display.style.color = ""; 1.1407 + 1.1408 +// Test interaction of animations and restyling (Bug 686656), 1.1409 +// with reframing. 1.1410 +// This test depends on kf3 getting its 0% and 100% values from the 1.1411 +// rules below it in the cascade; we're checking that the animation 1.1412 +// isn't rebuilt when the restyles happen. 1.1413 +new_div("animation: kf3 1s linear forwards"); 1.1414 +is(cs.marginTop, "0px", "bug 686656 test 2 at 0ms"); 1.1415 +advance_clock(250); 1.1416 +display.style.overflow = "scroll"; 1.1417 +is(cs.marginTop, "100px", "bug 686656 test 2 at 250ms"); 1.1418 +advance_clock(375); 1.1419 +is(cs.marginTop, "50px", "bug 686656 test 2 at 625ms"); 1.1420 +advance_clock(375); 1.1421 +is(cs.marginTop, "0px", "bug 686656 test 2 at 1000ms"); 1.1422 +done_div(); 1.1423 +display.style.overflow = ""; 1.1424 + 1.1425 +// Test that cascading between keyframes rules is per-property rather 1.1426 +// than per-rule (bug ), and that the timing function isn't taken from a 1.1427 +// rule that's skipped. (Bug 738003) 1.1428 +new_div("animation: cascade 1s linear forwards; position: relative"); 1.1429 +is(cs.top, "0px", "cascade test (top) at 0ms"); 1.1430 +is(cs.left, "0px", "cascade test (top) at 0ms"); 1.1431 +advance_clock(125); 1.1432 +is(cs.top, "0px", "cascade test (top) at 125ms"); 1.1433 +is(cs.left, "50px", "cascade test (top) at 125ms"); 1.1434 +advance_clock(125); 1.1435 +is(cs.top, "0px", "cascade test (top) at 250ms"); 1.1436 +is(cs.left, "100px", "cascade test (top) at 250ms"); 1.1437 +advance_clock(125); 1.1438 +is(cs.top, "50px", "cascade test (top) at 375ms"); 1.1439 +is(cs.left, "100px", "cascade test (top) at 375ms"); 1.1440 +advance_clock(125); 1.1441 +is(cs.top, "100px", "cascade test (top) at 500ms"); 1.1442 +is(cs.left, "100px", "cascade test (top) at 500ms"); 1.1443 +advance_clock(125); 1.1444 +is(cs.top, "100px", "cascade test (top) at 625ms"); 1.1445 +is(cs.left, "50px", "cascade test (top) at 625ms"); 1.1446 +advance_clock(125); 1.1447 +is(cs.top, "100px", "cascade test (top) at 750ms"); 1.1448 +is(cs.left, "0px", "cascade test (top) at 750ms"); 1.1449 +advance_clock(125); 1.1450 +is(cs.top, "50px", "cascade test (top) at 875ms"); 1.1451 +is(cs.left, "0px", "cascade test (top) at 875ms"); 1.1452 +advance_clock(125); 1.1453 +is(cs.top, "0px", "cascade test (top) at 1000ms"); 1.1454 +is(cs.left, "0px", "cascade test (top) at 1000ms"); 1.1455 +done_div(); 1.1456 + 1.1457 +new_div("animation: cascade2 8s linear forwards"); 1.1458 +is(cs.textIndent, "0px", "cascade2 test at 0s"); 1.1459 +advance_clock(1000); 1.1460 +is(cs.textIndent, "25px", "cascade2 test at 1s"); 1.1461 +advance_clock(1000); 1.1462 +is(cs.textIndent, "50px", "cascade2 test at 2s"); 1.1463 +advance_clock(1000); 1.1464 +is(cs.textIndent, "25px", "cascade2 test at 3s"); 1.1465 +advance_clock(1000); 1.1466 +is(cs.textIndent, "0px", "cascade2 test at 4s"); 1.1467 +advance_clock(3000); 1.1468 +is(cs.textIndent, "75px", "cascade2 test at 7s"); 1.1469 +advance_clock(1000); 1.1470 +is(cs.textIndent, "100px", "cascade2 test at 8s"); 1.1471 +done_div(); 1.1472 + 1.1473 +new_div("-moz-animation: primitives1 2s linear forwards"); 1.1474 +is(cs.getPropertyValue("-moz-transform"), "matrix(1, 0, 0, 1, 0, 0)", 1.1475 + "primitives1 at 0s"); 1.1476 +advance_clock(1000); 1.1477 +is(cs.getPropertyValue("-moz-transform"), 1.1478 + "matrix(-0.707107, 0.707107, -0.707107, -0.707107, 0, 0)", 1.1479 + "primitives1 at 1s"); 1.1480 +advance_clock(1000); 1.1481 +is(cs.getPropertyValue("-moz-transform"), "matrix(0, -1, 1, 0, 0, 0)", 1.1482 + "primitives1 at 0s"); 1.1483 +done_div(); 1.1484 + 1.1485 +new_div("animation: important1 1s linear forwards"); 1.1486 +is(cs.marginTop, "50px", "important1 test at 0s"); 1.1487 +advance_clock(500); 1.1488 +is(cs.marginTop, "75px", "important1 test at 0.5s"); 1.1489 +advance_clock(500); 1.1490 +is(cs.marginTop, "100px", "important1 test at 1s"); 1.1491 +done_div(); 1.1492 + 1.1493 +new_div("animation: important2 1s linear forwards"); 1.1494 +is(cs.marginTop, "50px", "important2 (margin-top) test at 0s"); 1.1495 +is(cs.marginBottom, "100px", "important2 (margin-bottom) test at 0s"); 1.1496 +advance_clock(1000); 1.1497 +is(cs.marginTop, "0px", "important2 (margin-top) test at 1s"); 1.1498 +is(cs.marginBottom, "50px", "important2 (margin-bottom) test at 1s"); 1.1499 +done_div(); 1.1500 + 1.1501 +// Test that it's the length of the 'animation-name' list that's used to 1.1502 +// start animations. 1.1503 +// note: anim2 animates margin-right from 0 to 100px 1.1504 +// note: anim3 animates margin-top from 0 to 100px 1.1505 +new_div("animation-name: anim2, anim3; animation-duration: 1s; animation-timing-function: linear; animation-delay: -250ms, -250ms, -750ms, -500ms;"); 1.1506 +is(cs.marginRight, "25px", "animation-name list length is the length that matters"); 1.1507 +is(cs.marginTop, "25px", "animation-name list length is the length that matters"); 1.1508 +done_div(); 1.1509 +new_div("animation-name: anim2, anim3, anim2; animation-duration: 1s; animation-timing-function: linear; animation-delay: -250ms, -250ms, -750ms, -500ms;"); 1.1510 +is(cs.marginRight, "75px", "animation-name list length is the length that matters, and the last occurrence of a name wins"); 1.1511 +is(cs.marginTop, "25px", "animation-name list length is the length that matters"); 1.1512 +done_div(); 1.1513 + 1.1514 +var dyn_sheet_elt = document.createElement("style"); 1.1515 +document.head.appendChild(dyn_sheet_elt); 1.1516 +var dyn_sheet = dyn_sheet_elt.sheet; 1.1517 +dyn_sheet.insertRule("@keyframes dyn1 { from { margin-left: 0 } 50% { margin-left: 50px } to { margin-left: 100px } }", 0); 1.1518 +dyn_sheet.insertRule("@keyframes dyn2 { from { margin-left: 100px } to { margin-left: 200px } }", 1); 1.1519 +var dyn1 = dyn_sheet.cssRules[0]; 1.1520 +var dyn2 = dyn_sheet.cssRules[1]; 1.1521 +new_div("animation: dyn1 1s linear"); 1.1522 +is(cs.marginLeft, "0px", "dynamic rule change test, initial state"); 1.1523 +advance_clock(250); 1.1524 +is(cs.marginLeft, "25px", "dynamic rule change test, 250ms"); 1.1525 +dyn2.name = "dyn1"; 1.1526 +is(cs.marginLeft, "125px", "dynamic rule change test, change in @keyframes name applies"); 1.1527 +dyn2.appendRule("50% { margin-left: 0px }"); 1.1528 +is(cs.marginLeft, "50px", "dynamic rule change test, @keyframes appendRule"); 1.1529 +var dyn2_kf1 = dyn2.cssRules[0]; // currently 0% { margin-left: 100px } 1.1530 +dyn2_kf1.style.marginLeft = "-100px"; 1.1531 +// FIXME: Bug 978833 (keyframe rules used as nsIStyleRule but doesn't follow immutability contract) 1.1532 +todo_is(cs.marginLeft, "-50px", "dynamic rule change test, keyframe style set"); 1.1533 +dyn2.name = "dyn2"; 1.1534 +is(cs.marginLeft, "25px", "dynamic rule change test, change in @keyframes name applies (second time)"); 1.1535 +var dyn1_kf2 = dyn1.cssRules[1]; // currently 50% { margin-left: 50px } 1.1536 +dyn1_kf2.keyText = "25%"; 1.1537 +is(cs.marginLeft, "50px", "dynamic rule change test, change in keyframe keyText"); 1.1538 +dyn1.deleteRule("25%"); 1.1539 +is(cs.marginLeft, "25px", "dynamic rule change test, @keyframes deleteRule"); 1.1540 +done_div(); 1.1541 +dyn_sheet_elt.parentNode.removeChild(dyn_sheet_elt); 1.1542 +dyn_sheet_elt = null; 1.1543 +dyn_sheet = null; 1.1544 + 1.1545 +SpecialPowers.DOMWindowUtils.restoreNormalRefresh(); 1.1546 + 1.1547 +</script> 1.1548 +</pre> 1.1549 +</body> 1.1550 +</html>