test_animations.html (85950B)
1 <!DOCTYPE HTML> 2 <html> 3 <!-- 4 https://bugzilla.mozilla.org/show_bug.cgi?id=435442 5 --> 6 <!-- 7 8 ====== PLEASE KEEP THIS IN SYNC WITH test_animations_omta.html ======= 9 10 test_animations_omta.html mimicks the content of this file but with 11 extra machinery for testing animation values on the compositor thread. 12 13 If you are making changes to this file or to test_animations_omta.html, please 14 try to keep them consistent where appropriate. 15 16 --> 17 <head> 18 <title>Test for css3-animations (Bug 435442)</title> 19 <script src="/tests/SimpleTest/SimpleTest.js"></script> 20 <script type="application/javascript" src="animation_utils.js"></script> 21 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> 22 <style type="text/css"> 23 @keyframes anim1 { 24 0% { margin-left: 0px } 25 50% { margin-left: 80px } 26 100% { margin-left: 100px } 27 } 28 @keyframes anim2 { 29 from { margin-right: 0 } to { margin-right: 100px } 30 } 31 @keyframes anim3 { 32 from { margin-top: 0 } to { margin-top: 100px } 33 } 34 @keyframes anim4 { 35 from { margin-bottom: 0 } to { margin-bottom: 100px } 36 } 37 @keyframes anim5 { 38 from { margin-left: 0 } to { margin-left: 100px } 39 } 40 41 @keyframes kf1 { 42 50% { margin-top: 50px } 43 to { margin-top: 150px } 44 } 45 @keyframes kf2 { 46 from { margin-top: 150px } 47 50% { margin-top: 50px } 48 } 49 @keyframes kf3 { 50 25% { margin-top: 100px } 51 } 52 @keyframes kf4 { 53 to, from { display: none; margin-top: 37px } 54 } 55 @keyframes kf_cascade1 { 56 from { padding-top: 50px } 57 50%, from { padding-top: 30px } /* wins: 0% */ 58 75%, 85%, 50% { padding-top: 20px } /* wins: 75%, 50% */ 59 100%, 85% { padding-top: 70px } /* wins: 100% */ 60 85.1% { padding-top: 60px } /* wins: 85.1% */ 61 85% { padding-top: 30px } /* wins: 85% */ 62 } 63 @keyframes kf_cascade2 { from, to { margin-top: 100px } } 64 @keyframes kf_cascade2 { from, to { margin-left: 200px } } 65 @keyframes kf_cascade2 { from, to { margin-left: 300px } } 66 @keyframes kf_tf1 { 67 0% { padding-bottom: 20px; animation-timing-function: ease } 68 25% { padding-bottom: 60px; } 69 50% { padding-bottom: 160px; animation-timing-function: steps(5) } 70 75% { padding-bottom: 120px; animation-timing-function: linear } 71 100% { padding-bottom: 20px; animation-timing-function: ease-out } 72 } 73 74 @keyframes always_fifty { 75 from, to { margin-left: 50px } 76 } 77 78 #withbefore::before, #withafter::after { 79 content: ""; 80 animation: anim2 1s linear alternate 3; 81 } 82 83 @keyframes multiprop { 84 0% { 85 padding-top: 10px; padding-left: 30px; 86 animation-timing-function: ease; 87 } 88 25% { 89 padding-left: 50px; 90 animation-timing-function: ease-out; 91 } 92 50% { 93 padding-top: 40px; 94 } 95 75% { 96 padding-top: 80px; padding-left: 60px; 97 animation-timing-function: ease-in; 98 } 99 } 100 101 @keyframes uaoverride { 102 0%, 100% { white-space: pre; margin-top: 20px } 103 50% { margin-top: 120px } 104 } 105 106 @keyframes cascade { 107 0%, 25%, 100% { top: 0 } 108 50%, 75% { top: 100px } 109 0%, 75%, 100% { left: 0 } 110 25%, 50% { left: 100px } 111 } 112 @keyframes cascade2 { 113 0% { text-indent: 0 } 114 25% { text-indent: 30px; animation-timing-function: ease-in } /* beaten by rule below */ 115 50% { text-indent: 0 } 116 25% { text-indent: 50px } 117 100% { text-indent: 100px } 118 } 119 120 @keyframes primitives1 { 121 from { transform: rotate(0deg) translateX(0px) scaleX(1) 122 translate(0px) scale3d(1, 1, 1); } 123 to { transform: rotate(270deg) translate3d(0px, 0px, 0px) scale(1) 124 translateY(0px) scaleY(1); } 125 } 126 127 @keyframes important1 { 128 from { margin-top: 50px; } 129 50% { margin-top: 150px !important; } /* ignored */ 130 to { margin-top: 100px; } 131 } 132 133 @keyframes important2 { 134 from { margin-top: 50px; 135 margin-bottom: 100px; } 136 to { margin-top: 150px !important; /* ignored */ 137 margin-bottom: 50px; } 138 } 139 140 @keyframes empty { } 141 @keyframes nearlyempty { to { margin-left: 100px; } } 142 143 @keyframes lowerpriority { 144 0% { 145 top: 0px; 146 left: 0px; 147 } 148 100% { 149 top: 100px; 150 left: 100px; 151 } 152 } 153 154 @keyframes overrideleft { 155 0%, 100% { left: 0px } 156 } 157 158 @keyframes overridetop { 159 0%, 100% { top: 0px } 160 } 161 162 @keyframes opacitymid { 163 0% { opacity: 0.2 } 164 100% { opacity: 0.8 } 165 } 166 167 @keyframes "string name 1" { /* using string for keyframes name */ 168 0%, 100% { left: 1px } 169 } 170 171 @keyframes "string name 2" { 172 0%, 100% { left: 2px } 173 } 174 175 @keyframes custom\ ident\ 1 { 176 0%, 100% { left: 3px } 177 } 178 179 @keyframes custom\ ident\ 2 { 180 0%, 100% { left: 4px } 181 } 182 183 @keyframes "initial" { 184 0%, 100% { left: 5px } 185 } 186 187 @keyframes initial { /* illegal as an identifier, should be dropped */ 188 0%, 100% { left: 6px } 189 } 190 191 @keyframes "none" { 192 0%, 100% { left: 7px } 193 } 194 195 @keyframes none { /* illegal as an identifier, should be dropped */ 196 0%, 100% { left: 8px } 197 } 198 </style> 199 </head> 200 <body> 201 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=435442">Mozilla Bug 435442</a> 202 <div id="display"></div> 203 <pre id="test"> 204 <script type="application/javascript"> 205 "use strict"; 206 207 /** Test for css3-animations (Bug 435442) */ 208 209 var e = new AnimationEvent("foo", 210 { 211 bubbles: true, 212 cancelable: true, 213 animationName: "name", 214 elapsedTime: 0.5, 215 pseudoElement: "pseudo" 216 }); 217 is(e.bubbles, true); 218 is(e.cancelable, true); 219 is(e.animationName, "name"); 220 is(e.elapsedTime, 0.5); 221 is(e.pseudoElement, "pseudo"); 222 is(e.isTrusted, false) 223 224 // Shortcut new_div to update div, cs 225 var div, cs; 226 var originalNewDiv = window.new_div; 227 window.new_div = function(style) { 228 [ div, cs ] = originalNewDiv(style); 229 }; 230 231 // take over the refresh driver right from the start. 232 advance_clock(0); 233 234 SimpleTest.registerCleanupFunction(() => { 235 SpecialPowers.DOMWindowUtils.restoreNormalRefresh(); 236 }); 237 238 /* 239 * css3-animations: 2. Animations 240 * http://dev.w3.org/csswg/css3-animations/#animations 241 */ 242 243 // Test that animations don't affect the computed value before the 244 // start of the animation or after its end. Test without 245 // animation-fill-mode, but then repeat the test with all the values of 246 // animation-fill-mode. 247 function test_fill_mode(fill_mode, fills_backwards, fills_forwards) 248 { 249 var style = "margin-left: 30px; animation: 10s 3s anim1 linear"; 250 var desc; 251 if (fill_mode.length > 0) { 252 style += " " + fill_mode; 253 desc = "fill mode " + fill_mode + ": "; 254 } else { 255 desc = "default fill mode: "; 256 } 257 new_div(style); 258 listen(); 259 if (fills_backwards) 260 is(cs.marginLeft, "0px", desc + "does affect value during delay (0s)"); 261 else 262 is(cs.marginLeft, "30px", desc + "doesn't affect value during delay (0s)"); 263 advance_clock(2000); 264 if (fills_backwards) 265 is(cs.marginLeft, "0px", desc + "does affect value during delay (2s)"); 266 else 267 is(cs.marginLeft, "30px", desc + "doesn't affect value during delay (2s)"); 268 check_events([], "before start in test_fill_mode"); 269 advance_clock(1000); 270 check_events([{ type: 'animationstart', target: div, 271 bubbles: true, cancelable: false, 272 animationName: 'anim1', elapsedTime: 0.0, 273 pseudoElement: "" }], 274 "right after start in test_fill_mode"); 275 if (fills_backwards) 276 is(cs.marginLeft, "0px", desc + "affects value at start of animation"); 277 advance_clock(125); 278 is(cs.marginLeft, "2px", desc + "affects value during animation"); 279 advance_clock(2375); 280 is(cs.marginLeft, "40px", desc + "affects value during animation"); 281 advance_clock(2500); 282 is(cs.marginLeft, "80px", desc + "affects value during animation"); 283 advance_clock(2500); 284 is(cs.marginLeft, "90px", desc + "affects value during animation"); 285 advance_clock(2375); 286 is(cs.marginLeft, "99.5px", desc + "affects value during animation"); 287 check_events([], "before end in test_fill_mode"); 288 advance_clock(125); 289 check_events([{ type: 'animationend', target: div, 290 bubbles: true, cancelable: false, 291 animationName: 'anim1', elapsedTime: 10.0, 292 pseudoElement: "" }], 293 "right after end in test_fill_mode"); 294 if (fills_forwards) 295 is(cs.marginLeft, "100px", desc + "affects value at end of animation"); 296 advance_clock(10); 297 if (fills_forwards) 298 is(cs.marginLeft, "100px", desc + "does affect value after animation"); 299 else 300 is(cs.marginLeft, "30px", desc + "does not affect value after animation"); 301 done_div(); 302 } 303 test_fill_mode("", false, false); 304 test_fill_mode("none", false, false); 305 test_fill_mode("forwards", false, true); 306 test_fill_mode("backwards", true, false); 307 test_fill_mode("both", true, true); 308 309 // Test that animations continue running when the animation name 310 // list is changed. 311 new_div("animation: anim1 linear 10s"); 312 is(cs.getPropertyValue("margin-top"), "0px", 313 "just anim1, margin-top at start"); 314 is(cs.getPropertyValue("margin-right"), "0px", 315 "just anim1, margin-right at start"); 316 is(cs.getPropertyValue("margin-bottom"), "0px", 317 "just anim1, margin-bottom at start"); 318 is(cs.getPropertyValue("margin-left"), "0px", 319 "just anim1, margin-left at start"); 320 advance_clock(1000); 321 is(cs.getPropertyValue("margin-top"), "0px", 322 "just anim1, margin-top at 1s"); 323 is(cs.getPropertyValue("margin-right"), "0px", 324 "just anim1, margin-right at 1s"); 325 is(cs.getPropertyValue("margin-bottom"), "0px", 326 "just anim1, margin-bottom at 1s"); 327 is(cs.getPropertyValue("margin-left"), "16px", 328 "just anim1, margin-left at 1s"); 329 // append anim2 330 div.style.animation = "anim1 linear 10s, anim2 linear 10s"; 331 is(cs.getPropertyValue("margin-top"), "0px", 332 "anim1 + anim2, margin-top at 1s"); 333 is(cs.getPropertyValue("margin-right"), "0px", 334 "anim1 + anim2, margin-right at 1s"); 335 is(cs.getPropertyValue("margin-bottom"), "0px", 336 "anim1 + anim2, margin-bottom at 1s"); 337 is(cs.getPropertyValue("margin-left"), "16px", 338 "anim1 + anim2, margin-left at 1s"); 339 advance_clock(1000); 340 is(cs.getPropertyValue("margin-top"), "0px", 341 "anim1 + anim2, margin-top at 2s"); 342 is(cs.getPropertyValue("margin-right"), "10px", 343 "anim1 + anim2, margin-right at 2s"); 344 is(cs.getPropertyValue("margin-bottom"), "0px", 345 "anim1 + anim2, margin-bottom at 2s"); 346 is(cs.getPropertyValue("margin-left"), "32px", 347 "anim1 + anim2, margin-left at 2s"); 348 // prepend anim3 349 div.style.animation = "anim3 linear 10s, anim1 linear 10s, anim2 linear 10s"; 350 is(cs.getPropertyValue("margin-top"), "0px", 351 "anim3 + anim1 + anim2, margin-top at 2s"); 352 is(cs.getPropertyValue("margin-right"), "10px", 353 "anim3 + anim1 + anim2, margin-right at 2s"); 354 is(cs.getPropertyValue("margin-bottom"), "0px", 355 "anim3 + anim1 + anim2, margin-bottom at 2s"); 356 is(cs.getPropertyValue("margin-left"), "32px", 357 "anim3 + anim1 + anim2, margin-left at 2s"); 358 advance_clock(1000); 359 is(cs.getPropertyValue("margin-top"), "10px", 360 "anim3 + anim1 + anim2, margin-top at 3s"); 361 is(cs.getPropertyValue("margin-right"), "20px", 362 "anim3 + anim1 + anim2, margin-right at 3s"); 363 is(cs.getPropertyValue("margin-bottom"), "0px", 364 "anim3 + anim1 + anim2, margin-bottom at 3s"); 365 is(cs.getPropertyValue("margin-left"), "48px", 366 "anim3 + anim1 + anim2, margin-left at 3s"); 367 // remove anim2 from end 368 div.style.animation = "anim3 linear 10s, anim1 linear 10s"; 369 is(cs.getPropertyValue("margin-top"), "10px", 370 "anim3 + anim1, margin-top at 3s"); 371 is(cs.getPropertyValue("margin-right"), "0px", 372 "anim3 + anim1, margin-right at 3s"); 373 is(cs.getPropertyValue("margin-bottom"), "0px", 374 "anim3 + anim1, margin-bottom at 3s"); 375 is(cs.getPropertyValue("margin-left"), "48px", 376 "anim3 + anim1, margin-left at 3s"); 377 advance_clock(1000); 378 is(cs.getPropertyValue("margin-top"), "20px", 379 "anim3 + anim1, margin-top at 4s"); 380 is(cs.getPropertyValue("margin-right"), "0px", 381 "anim3 + anim1, margin-right at 4s"); 382 is(cs.getPropertyValue("margin-bottom"), "0px", 383 "anim3 + anim1, margin-bottom at 4s"); 384 is(cs.getPropertyValue("margin-left"), "64px", 385 "anim3 + anim1, margin-left at 4s"); 386 // swap anim1 and anim3, change duration of anim3 387 div.style.animation = "anim1 linear 10s, anim3 linear 5s"; 388 is(cs.getPropertyValue("margin-top"), "40px", 389 "anim1 + anim3, margin-top at 4s"); 390 is(cs.getPropertyValue("margin-right"), "0px", 391 "anim1 + anim3, margin-right at 4s"); 392 is(cs.getPropertyValue("margin-bottom"), "0px", 393 "anim1 + anim3, margin-bottom at 4s"); 394 is(cs.getPropertyValue("margin-left"), "64px", 395 "anim1 + anim3, margin-left at 4s"); 396 advance_clock(1000); 397 is(cs.getPropertyValue("margin-top"), "60px", 398 "anim1 + anim3, margin-top at 5s"); 399 is(cs.getPropertyValue("margin-right"), "0px", 400 "anim1 + anim3, margin-right at 5s"); 401 is(cs.getPropertyValue("margin-bottom"), "0px", 402 "anim1 + anim3, margin-bottom at 5s"); 403 is(cs.getPropertyValue("margin-left"), "80px", 404 "anim1 + anim3, margin-left at 5s"); 405 // list anim1 twice, last duration wins, original start time still applies 406 div.style.animation = "anim1 linear 10s, anim3 linear 5s, anim1 linear 20s"; 407 is(cs.getPropertyValue("margin-top"), "60px", 408 "anim1 + anim3 + anim1, margin-top at 5s"); 409 is(cs.getPropertyValue("margin-right"), "0px", 410 "anim1 + anim3 + anim1, margin-right at 5s"); 411 is(cs.getPropertyValue("margin-bottom"), "0px", 412 "anim1 + anim3 + anim1, margin-bottom at 5s"); 413 is(cs.getPropertyValue("margin-left"), "40px", 414 "anim1 + anim3 + anim1, margin-left at 5s"); 415 // drop one of the anim1, and list anim5 as well, which animates 416 // the same property as anim1 417 div.style.animation = "anim3 linear 5s, anim1 linear 20s, anim5 linear 10s"; 418 is(cs.getPropertyValue("margin-top"), "60px", 419 "anim3 + anim1 + anim5, margin-top at 5s"); 420 is(cs.getPropertyValue("margin-right"), "0px", 421 "anim3 + anim1 + anim5, margin-right at 5s"); 422 is(cs.getPropertyValue("margin-bottom"), "0px", 423 "anim3 + anim1 + anim5, margin-bottom at 5s"); 424 is(cs.getPropertyValue("margin-left"), "0px", 425 "anim3 + anim1 + anim5, margin-left at 5s"); 426 advance_clock(1000); 427 is(cs.getPropertyValue("margin-top"), "80px", 428 "anim3 + anim1 + anim5, margin-top at 6s"); 429 is(cs.getPropertyValue("margin-right"), "0px", 430 "anim3 + anim1 + anim5, margin-right at 6s"); 431 is(cs.getPropertyValue("margin-bottom"), "0px", 432 "anim3 + anim1 + anim5, margin-bottom at 6s"); 433 is(cs.getPropertyValue("margin-left"), "10px", 434 "anim3 + anim1 + anim5, margin-left at 6s"); 435 // now swap the anim5 and anim1 order 436 div.style.animation = "anim3 linear 5s, anim5 linear 10s, anim1 linear 20s"; 437 is(cs.getPropertyValue("margin-top"), "80px", 438 "anim3 + anim1 + anim5, margin-top at 6s"); 439 is(cs.getPropertyValue("margin-right"), "0px", 440 "anim3 + anim1 + anim5, margin-right at 6s"); 441 is(cs.getPropertyValue("margin-bottom"), "0px", 442 "anim3 + anim1 + anim5, margin-bottom at 6s"); 443 is(cs.getPropertyValue("margin-left"), "48px", 444 "anim3 + anim1 + anim5, margin-left at 6s"); 445 advance_clock(1000); 446 is(cs.getPropertyValue("margin-top"), "0px", 447 "anim3 + anim1 + anim5, margin-top at 7s"); 448 is(cs.getPropertyValue("margin-right"), "0px", 449 "anim3 + anim1 + anim5, margin-right at 7s"); 450 is(cs.getPropertyValue("margin-bottom"), "0px", 451 "anim3 + anim1 + anim5, margin-bottom at 7s"); 452 is(cs.getPropertyValue("margin-left"), "56px", 453 "anim3 + anim1 + anim5, margin-left at 7s"); 454 // swap anim1 and anim5 back 455 div.style.animation = "anim3 linear 5s, anim1 linear 20s, anim5 linear 10s"; 456 is(cs.getPropertyValue("margin-top"), "0px", 457 "anim3 + anim1 + anim5, margin-top at 7s"); 458 is(cs.getPropertyValue("margin-right"), "0px", 459 "anim3 + anim1 + anim5, margin-right at 7s"); 460 is(cs.getPropertyValue("margin-bottom"), "0px", 461 "anim3 + anim1 + anim5, margin-bottom at 7s"); 462 is(cs.getPropertyValue("margin-left"), "20px", 463 "anim3 + anim1 + anim5, margin-left at 7s"); 464 advance_clock(100); 465 is(cs.getPropertyValue("margin-top"), "0px", 466 "anim3 + anim1 + anim5, margin-top at 7.1s"); 467 // Change the animation fill mode on the completed animation. 468 div.style.animation = "anim3 linear 5s forwards, anim1 linear 20s, anim5 linear 10s"; 469 is(cs.getPropertyValue("margin-top"), "100px", 470 "anim3 + anim1 + anim5, margin-top at 7.1s, with fill mode"); 471 advance_clock(900); 472 is(cs.getPropertyValue("margin-top"), "100px", 473 "anim3 + anim1 + anim5, margin-top at 8s, with fill mode"); 474 // Change the animation duration on the completed animation, so it is 475 // no longer completed. 476 div.style.animation = "anim3 linear 10s, anim1 linear 20s, anim5 linear 10s"; 477 is(cs.getPropertyValue("margin-top"), "60px", 478 "anim3 + anim1 + anim5, margin-top at 8s, with fill mode"); 479 is(cs.getPropertyValue("margin-left"), "30px", 480 "anim3 + anim1 + anim5, margin-left at 8s"); 481 done_div(); 482 483 /* 484 * css3-animations: 3. Keyframes 485 * http://dev.w3.org/csswg/css3-animations/#keyframes 486 * 487 * Also see test_keyframes_rules.html . 488 */ 489 490 // Test the rules on keyframes that lack a 0% or 100% rule: 491 // (simultaneously, test that reverse animations have their keyframes 492 // run backwards) 493 494 // 100px at 0%, 50px at 50%, 150px at 100% 495 new_div("margin-top: 100px; animation: kf1 ease 1s alternate infinite"); 496 is(cs.marginTop, "100px", "no-0% at 0.0s"); 497 advance_clock(100); 498 is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease(0.2), 0.01, 499 "no-0% at 0.1s"); 500 advance_clock(200); 501 is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease(0.6), 0.01, 502 "no-0% at 0.3s"); 503 advance_clock(200); 504 is(cs.marginTop, "50px", "no-0% at 0.5s"); 505 advance_clock(200); 506 is_approx(px_to_num(cs.marginTop), 50 + 100 * gTF.ease(0.4), 0.01, 507 "no-0% at 0.7s"); 508 advance_clock(200); 509 is_approx(px_to_num(cs.marginTop), 50 + 100 * gTF.ease(0.8), 0.01, 510 "no-0% at 0.9s"); 511 advance_clock(100); 512 is(cs.marginTop, "150px", "no-0% at 1.0s"); 513 advance_clock(100); 514 is_approx(px_to_num(cs.marginTop), 50 + 100 * gTF.ease(0.8), 0.01, 515 "no-0% at 1.1s"); 516 advance_clock(300); 517 is_approx(px_to_num(cs.marginTop), 50 + 100 * gTF.ease(0.2), 0.01, 518 "no-0% at 1.4s"); 519 advance_clock(300); 520 is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease(0.6), 0.01, 521 "no-0% at 1.7s"); 522 advance_clock(200); 523 is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease(0.2), 0.01, 524 "no-0% at 1.9s"); 525 advance_clock(100); 526 is(cs.marginTop, "100px", "no-0% at 2.0s"); 527 done_div(); 528 529 // 150px at 0%, 50px at 50%, 100px at 100% 530 new_div("margin-top: 100px; animation: kf2 ease-in 1s alternate infinite"); 531 is(cs.marginTop, "150px", "no-100% at 0.0s"); 532 advance_clock(100); 533 is_approx(px_to_num(cs.marginTop), 150 - 100 * gTF.ease_in(0.2), 0.01, 534 "no-100% at 0.1s"); 535 advance_clock(200); 536 is_approx(px_to_num(cs.marginTop), 150 - 100 * gTF.ease_in(0.6), 0.01, 537 "no-100% at 0.3s"); 538 advance_clock(200); 539 is(cs.marginTop, "50px", "no-100% at 0.5s"); 540 advance_clock(200); 541 is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_in(0.4), 0.01, 542 "no-100% at 0.7s"); 543 advance_clock(200); 544 is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_in(0.8), 0.01, 545 "no-100% at 0.9s"); 546 advance_clock(100); 547 is(cs.marginTop, "100px", "no-100% at 1.0s"); 548 advance_clock(100); 549 is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_in(0.8), 0.01, 550 "no-100% at 1.1s"); 551 advance_clock(300); 552 is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_in(0.2), 0.01, 553 "no-100% at 1.4s"); 554 advance_clock(300); 555 is_approx(px_to_num(cs.marginTop), 150 - 100 * gTF.ease_in(0.6), 0.01, 556 "no-100% at 1.7s"); 557 advance_clock(200); 558 is_approx(px_to_num(cs.marginTop), 150 - 100 * gTF.ease_in(0.2), 0.01, 559 "no-100% at 1.9s"); 560 advance_clock(100); 561 is(cs.marginTop, "150px", "no-100% at 2.0s"); 562 done_div(); 563 564 565 // 50px at 0%, 100px at 25%, 50px at 100% 566 new_div("margin-top: 50px; animation: kf3 ease-out 1s alternate infinite"); 567 is(cs.marginTop, "50px", "no-0%-no-100% at 0.0s"); 568 advance_clock(50); 569 is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_out(0.2), 0.01, 570 "no-0%-no-100% at 0.05s"); 571 advance_clock(100); 572 is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_out(0.6), 0.01, 573 "no-0%-no-100% at 0.15s"); 574 advance_clock(100); 575 is(cs.marginTop, "100px", "no-0%-no-100% at 0.25s"); 576 advance_clock(300); 577 is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease_out(0.4), 0.01, 578 "no-0%-no-100% at 0.55s"); 579 advance_clock(300); 580 is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease_out(0.8), 0.01, 581 "no-0%-no-100% at 0.85s"); 582 advance_clock(150); 583 is(cs.marginTop, "50px", "no-0%-no-100% at 1.0s"); 584 advance_clock(150); 585 is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease_out(0.8), 0.01, 586 "no-0%-no-100% at 1.15s"); 587 advance_clock(450); 588 is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease_out(0.2), 0.01, 589 "no-0%-no-100% at 1.6s"); 590 advance_clock(250); 591 is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_out(0.6), 0.01, 592 "no-0%-no-100% at 1.85s"); 593 advance_clock(100); 594 is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_out(0.2), 0.01, 595 "no-0%-no-100% at 1.95s"); 596 advance_clock(50); 597 is(cs.marginTop, "50px", "no-0%-no-100% at 2.0s"); 598 done_div(); 599 600 // Test that non-animatable properties are ignored. 601 // Simultaneously, test that the block is still honored, and that 602 // we still override the value when two consecutive keyframes have 603 // the same value. 604 new_div("animation: kf4 ease 10s"); 605 is(cs.display, "block", 606 "non-animatable properties should be ignored (linear, 0s)"); 607 is(cs.marginTop, "37px", 608 "animatable properties should still apply (linear, 0s)"); 609 advance_clock(1000); 610 is(cs.display, "block", 611 "non-animatable properties should be ignored (linear, 1s)"); 612 is(cs.marginTop, "37px", 613 "animatable properties should still apply (linear, 1s)"); 614 done_div(); 615 new_div("animation: kf4 step-start 10s"); 616 is(cs.display, "block", 617 "non-animatable properties should be ignored (step-start, 0s)"); 618 is(cs.marginTop, "37px", 619 "animatable properties should still apply (step-start, 0s)"); 620 advance_clock(1000); 621 is(cs.display, "block", 622 "non-animatable properties should be ignored (step-start, 1s)"); 623 is(cs.marginTop, "37px", 624 "animatable properties should still apply (step-start, 1s)"); 625 done_div(); 626 627 // Test cascading of the keyframes within an @keyframes rule. 628 new_div("animation: kf_cascade1 linear 10s"); 629 // 0%: 30px 630 // 50%: 20px 631 // 75%: 20px 632 // 85%: 30px 633 // 85.1%: 60px 634 // 100%: 70px 635 is(cs.paddingTop, "30px", "kf_cascade1 at 0s"); 636 advance_clock(2500); 637 is(cs.paddingTop, "25px", "kf_cascade1 at 2.5s"); 638 advance_clock(2500); 639 is(cs.paddingTop, "20px", "kf_cascade1 at 5s"); 640 advance_clock(2000); 641 is(cs.paddingTop, "20px", "kf_cascade1 at 7s"); 642 advance_clock(500); 643 is(cs.paddingTop, "20px", "kf_cascade1 at 7.5s"); 644 advance_clock(500); 645 is(cs.paddingTop, "25px", "kf_cascade1 at 8s"); 646 advance_clock(500); 647 is(cs.paddingTop, "30px", "kf_cascade1 at 8.5s"); 648 advance_clock(10); 649 is_approx(px_to_num(cs.paddingTop), 60, 0.001, "kf_cascade1 at 8.51s"); 650 advance_clock(745); 651 is(cs.paddingTop, "65px", "kf_cascade1 at 9.2505s"); 652 done_div(); 653 654 // Test cascading of the @keyframes rules themselves. 655 new_div("animation: kf_cascade2 linear 10s"); 656 is(cs.marginTop, "0px", "@keyframes rule with margin-top should be ignored"); 657 is(cs.marginLeft, "300px", "last @keyframes rule with margin-left should win"); 658 done_div(); 659 660 /* 661 * css3-animations: 3.1. Timing functions for keyframes 662 * http://dev.w3.org/csswg/css3-animations/#timing-functions-for-keyframes- 663 */ 664 new_div("animation: kf_tf1 ease-in 10s alternate infinite"); 665 is(cs.paddingBottom, "20px", 666 "keyframe timing functions test at 0s (test needed for flush)"); 667 advance_clock(1000); 668 is_approx(px_to_num(cs.paddingBottom), 20 + 40 * gTF.ease(0.4), 0.01, 669 "keyframe timing functions test at 1s"); 670 advance_clock(1000); 671 is_approx(px_to_num(cs.paddingBottom), 20 + 40 * gTF.ease(0.8), 0.01, 672 "keyframe timing functions test at 2s"); 673 advance_clock(1000); 674 is_approx(px_to_num(cs.paddingBottom), 60 + 100 * gTF.ease_in(0.2), 0.01, 675 "keyframe timing functions test at 3s"); 676 advance_clock(1000); 677 is_approx(px_to_num(cs.paddingBottom), 60 + 100 * gTF.ease_in(0.6), 0.01, 678 "keyframe timing functions test at 4s"); 679 advance_clock(1000); 680 is(cs.paddingBottom, "160px", 681 "keyframe timing functions test at 5s"); 682 advance_clock(1001); // avoid floating-point error 683 is_approx(px_to_num(cs.paddingBottom), 160 - 40 * step_end(5)(0.4), 0.01, 684 "keyframe timing functions test at 6s"); 685 advance_clock(1000); 686 is_approx(px_to_num(cs.paddingBottom), 160 - 40 * step_end(5)(0.8), 0.01, 687 "keyframe timing functions test at 7s"); 688 advance_clock(999); 689 is_approx(px_to_num(cs.paddingBottom), 120 - 100 * gTF.linear(0.2), 0.01, 690 "keyframe timing functions test at 8s"); 691 advance_clock(1000); 692 is_approx(px_to_num(cs.paddingBottom), 120 - 100 * gTF.linear(0.6), 0.01, 693 "keyframe timing functions test at 9s"); 694 advance_clock(1000); 695 is(cs.paddingBottom, "20px", 696 "keyframe timing functions test at 10s"); 697 advance_clock(20000); 698 is(cs.paddingBottom, "20px", 699 "keyframe timing functions test at 30s"); 700 advance_clock(1000); 701 is_approx(px_to_num(cs.paddingBottom), 120 - 100 * gTF.linear(0.6), 0.01, 702 "keyframe timing functions test at 31s"); 703 advance_clock(1000); 704 is_approx(px_to_num(cs.paddingBottom), 120 - 100 * gTF.linear(0.2), 0.01, 705 "keyframe timing functions test at 32s"); 706 advance_clock(999); // avoid floating-point error 707 is_approx(px_to_num(cs.paddingBottom), 160 - 40 * step_end(5)(0.8), 0.01, 708 "keyframe timing functions test at 33s"); 709 advance_clock(1000); 710 is_approx(px_to_num(cs.paddingBottom), 160 - 40 * step_end(5)(0.4), 0.01, 711 "keyframe timing functions test at 34s"); 712 advance_clock(1001); 713 is(cs.paddingBottom, "160px", 714 "keyframe timing functions test at 35s"); 715 advance_clock(1000); 716 is_approx(px_to_num(cs.paddingBottom), 60 + 100 * gTF.ease_in(0.6), 0.01, 717 "keyframe timing functions test at 36s"); 718 advance_clock(1000); 719 is_approx(px_to_num(cs.paddingBottom), 60 + 100 * gTF.ease_in(0.2), 0.01, 720 "keyframe timing functions test at 37s"); 721 advance_clock(1000); 722 is_approx(px_to_num(cs.paddingBottom), 20 + 40 * gTF.ease(0.8), 0.01, 723 "keyframe timing functions test at 38s"); 724 advance_clock(1000); 725 is_approx(px_to_num(cs.paddingBottom), 20 + 40 * gTF.ease(0.4), 0.01, 726 "keyframe timing functions test at 39s"); 727 advance_clock(1000); 728 is(cs.paddingBottom, "20px", 729 "keyframe timing functions test at 40s"); 730 done_div(); 731 732 // spot-check the same thing without alternate 733 new_div("animation: kf_tf1 ease-in 10s infinite"); 734 is(cs.paddingBottom, "20px", 735 "keyframe timing functions test at 0s (test needed for flush)"); 736 advance_clock(11000); 737 is_approx(px_to_num(cs.paddingBottom), 20 + 40 * gTF.ease(0.4), 0.01, 738 "keyframe timing functions test at 11s"); 739 advance_clock(3000); 740 is_approx(px_to_num(cs.paddingBottom), 60 + 100 * gTF.ease_in(0.6), 0.01, 741 "keyframe timing functions test at 14s"); 742 advance_clock(2001); // avoid floating-point error 743 is_approx(px_to_num(cs.paddingBottom), 160 - 40 * step_end(5)(0.4), 0.01, 744 "keyframe timing functions test at 16s"); 745 advance_clock(1999); 746 is_approx(px_to_num(cs.paddingBottom), 120 - 100 * gTF.linear(0.2), 0.01, 747 "keyframe timing functions test at 18s"); 748 done_div(); 749 750 /* 751 * css3-animations: 3.2. The 'animation-name' Property 752 * http://dev.w3.org/csswg/css3-animations/#the-animation-name-property- 753 */ 754 755 // animation-name is reasonably well-tested up in the tests for Section 756 // 2, particularly the tests that "Test that animations continue running 757 // when the animation name list is changed." 758 759 // Test that 'animation-name: none' steps the animation, and setting 760 // it again starts a new one. 761 762 new_div(""); 763 div.style.animation = "anim2 ease-in-out 10s"; 764 is(cs.marginRight, "0px", "after setting animation-name to anim2"); 765 advance_clock(1000); 766 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in_out(0.1), 0.01, 767 "before changing animation-name to none"); 768 div.style.animationName = "none"; 769 is(cs.marginRight, "0px", "after changing animation-name to none"); 770 advance_clock(1000); 771 is(cs.marginRight, "0px", "after changing animation-name to none plus 1s"); 772 div.style.animationName = "anim2"; 773 is(cs.marginRight, "0px", "after changing animation-name to anim2"); 774 advance_clock(1000); 775 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in_out(0.1), 0.01, 776 "at 1s in animation when animation-name no longer none again"); 777 div.style.animationName = "none"; 778 is(cs.marginRight, "0px", "after changing animation-name to none"); 779 advance_clock(1000); 780 is(cs.marginRight, "0px", "after changing animation-name to none plus 1s"); 781 done_div(); 782 783 /* 784 * css3-animations: 3.3. The 'animation-duration' Property 785 * http://dev.w3.org/csswg/css3-animations/#the-animation-duration-property- 786 */ 787 788 // FIXME: test animation-duration of 0 (quite a bit, including interaction 789 // with fill-mode, count, and reversing), once I know what the right 790 // behavior is. 791 792 /* 793 * css3-animations: 3.4. The 'animation-timing-function' Property 794 * http://dev.w3.org/csswg/css3-animations/#animation-timing-function_tag 795 */ 796 797 // tested in tests for section 3.1 798 799 /* 800 * css3-animations: 3.5. The 'animation-iteration-count' Property 801 * http://dev.w3.org/csswg/css3-animations/#the-animation-iteration-count-property- 802 */ 803 new_div("animation: anim2 ease-in 10s 0.3 forwards"); 804 is(cs.marginRight, "0px", "animation-iteration-count test 1 at 0s"); 805 advance_clock(2000); 806 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01, 807 "animation-iteration-count test 1 at 2s"); 808 advance_clock(900); 809 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.29), 0.01, 810 "animation-iteration-count test 1 at 2.9s"); 811 advance_clock(100); 812 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.3), 0.01, 813 "animation-iteration-count test 1 at 3s"); 814 advance_clock(100); 815 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.3), 0.01, 816 "animation-iteration-count test 1 at 3.1s"); 817 advance_clock(5000); 818 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.3), 0.01, 819 "animation-iteration-count test 1 at 8.1s"); 820 done_div(); 821 822 new_div("animation: anim2 ease-in 10s 0.3" 823 + ", anim3 ease-out 20s 1.2 alternate forwards" 824 + ", anim4 ease-in-out 5s 1.6 forwards"); 825 is(cs.marginRight, "0px", "animation-iteration-count test 2 at 0s"); 826 is(cs.marginTop, "0px", "animation-iteration-count test 3 at 0s"); 827 is(cs.marginBottom, "0px", "animation-iteration-count test 4 at 0s"); 828 advance_clock(2000); 829 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01, 830 "animation-iteration-count test 2 at 2s"); 831 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_out(0.1), 0.01, 832 "animation-iteration-count test 3 at 2s"); 833 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.4), 0.01, 834 "animation-iteration-count test 4 at 2s"); 835 advance_clock(900); 836 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.29), 0.01, 837 "animation-iteration-count test 2 at 2.9s"); 838 advance_clock(200); 839 is(cs.marginRight, "0px", "animation-iteration-count test 2 at 3.1s"); 840 advance_clock(1800); 841 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.98), 0.01, 842 "animation-iteration-count test 4 at 4.9s"); 843 advance_clock(200); 844 is(cs.marginRight, "0px", "animation-iteration-count test 2 at 5.1s"); 845 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.02), 0.01, 846 "animation-iteration-count test 4 at 5.1s"); 847 advance_clock(2800); 848 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.58), 0.01, 849 "animation-iteration-count test 4 at 7.9s"); 850 advance_clock(100); 851 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.6), 0.01, 852 "animation-iteration-count test 4 at 8s"); 853 advance_clock(100); 854 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.6), 0.01, 855 "animation-iteration-count test 4 at 8.1s"); 856 advance_clock(11700); 857 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_out(0.99), 0.01, 858 "animation-iteration-count test 3 at 19.8s"); 859 advance_clock(200); 860 is(cs.marginTop, "100px", "animation-iteration-count test 3 at 20s"); 861 advance_clock(200); 862 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_out(0.99), 0.01, 863 "animation-iteration-count test 3 at 20.2s"); 864 advance_clock(3600); 865 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_out(0.81), 0.01, 866 "animation-iteration-count test 3 at 23.8s"); 867 advance_clock(200); 868 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_out(0.8), 0.01, 869 "animation-iteration-count test 3 at 24s"); 870 advance_clock(200); 871 is(cs.marginRight, "0px", "animation-iteration-count test 2 at 25s"); 872 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_out(0.8), 0.01, 873 "animation-iteration-count test 3 at 25s"); 874 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.6), 0.01, 875 "animation-iteration-count test 4 at 25s"); 876 done_div(); 877 878 /* 879 * css3-animations: 3.6. The 'animation-direction' Property 880 * http://dev.w3.org/csswg/css3-animations/#the-animation-direction-property- 881 */ 882 883 // Tested in tests for sections 3.1 and 3.5. 884 885 new_div("animation: anim2 ease-in 10s infinite"); 886 div.style.animationDirection = "normal"; 887 is(cs.marginRight, "0px", "animation-direction test 1 (normal) at 0s"); 888 div.style.animationDirection = "reverse"; 889 is(cs.marginRight, "100px", "animation-direction test 1 (reverse) at 0s"); 890 div.style.animationDirection = "alternate"; 891 is(cs.marginRight, "0px", "animation-direction test 1 (alternate) at 0s"); 892 div.style.animationDirection = "alternate-reverse"; 893 is(cs.marginRight, "100px", "animation-direction test 1 (alternate-reverse) at 0s"); 894 advance_clock(2000); 895 div.style.animationDirection = "normal"; 896 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01, 897 "animation-direction test 1 (normal) at 2s"); 898 div.style.animationDirection = "reverse"; 899 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.8), 0.01, 900 "animation-direction test 1 (reverse) at 2s"); 901 div.style.animationDirection = "alternate"; 902 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01, 903 "animation-direction test 1 (alternate) at 2s"); 904 div.style.animationDirection = "alternate-reverse"; 905 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.8), 0.01, 906 "animation-direction test 1 (alternate-reverse) at 2s"); 907 advance_clock(5000); 908 div.style.animationDirection = "normal"; 909 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.7), 0.01, 910 "animation-direction test 1 (normal) at 7s"); 911 div.style.animationDirection = "reverse"; 912 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.3), 0.01, 913 "animation-direction test 1 (reverse) at 7s"); 914 div.style.animationDirection = "alternate"; 915 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.7), 0.01, 916 "animation-direction test 1 (alternate) at 7s"); 917 div.style.animationDirection = "alternate-reverse"; 918 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.3), 0.01, 919 "animation-direction test 1 (alternate-reverse) at 7s"); 920 advance_clock(5000); 921 div.style.animationDirection = "normal"; 922 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01, 923 "animation-direction test 1 (normal) at 12s"); 924 div.style.animationDirection = "reverse"; 925 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.8), 0.01, 926 "animation-direction test 1 (reverse) at 12s"); 927 div.style.animationDirection = "alternate"; 928 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.8), 0.01, 929 "animation-direction test 1 (alternate) at 12s"); 930 div.style.animationDirection = "alternate-reverse"; 931 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01, 932 "animation-direction test 1 (alternate-reverse) at 12s"); 933 advance_clock(10000); 934 div.style.animationDirection = "normal"; 935 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01, 936 "animation-direction test 1 (normal) at 22s"); 937 div.style.animationDirection = "reverse"; 938 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.8), 0.01, 939 "animation-direction test 1 (reverse) at 22s"); 940 div.style.animationDirection = "alternate"; 941 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01, 942 "animation-direction test 1 (alternate) at 22s"); 943 div.style.animationDirection = "alternate-reverse"; 944 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.8), 0.01, 945 "animation-direction test 1 (alternate-reverse) at 22s"); 946 advance_clock(30000); 947 div.style.animationDirection = "normal"; 948 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01, 949 "animation-direction test 1 (normal) at 52s"); 950 div.style.animationDirection = "reverse"; 951 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.8), 0.01, 952 "animation-direction test 1 (reverse) at 52s"); 953 div.style.animationDirection = "alternate"; 954 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.8), 0.01, 955 "animation-direction test 1 (alternate) at 52s"); 956 div.style.animationDirection = "alternate-reverse"; 957 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01, 958 "animation-direction test 1 (alternate-reverse) at 52s"); 959 done_div(); 960 961 /* 962 * css3-animations: 3.7. The 'animation-play-state' Property 963 * http://dev.w3.org/csswg/css3-animations/#the-animation-play-state-property- 964 */ 965 966 // simple test with just one animation 967 new_div(""); 968 div.style.animationTimingFunction = "ease"; 969 div.style.animationName = "anim1"; 970 div.style.animationDuration = "1s"; 971 div.style.animationDirection = "alternate"; 972 div.style.animationIterationCount = "2"; 973 is(cs.marginLeft, "0px", "animation-play-state test 1, at 0s"); 974 advance_clock(250); 975 is_approx(px_to_num(cs.marginLeft), 80 * gTF.ease(0.5), 0.01, 976 "animation-play-state test 1 at 250ms"); 977 div.style.animationPlayState = "paused"; 978 is_approx(px_to_num(cs.marginLeft), 80 * gTF.ease(0.5), 0.01, 979 "animation-play-state test 1 at 250ms"); 980 advance_clock(250); 981 is_approx(px_to_num(cs.marginLeft), 80 * gTF.ease(0.5), 0.01, 982 "animation-play-state test 1 still at 500ms"); 983 div.style.animationPlayState = "running"; 984 is_approx(px_to_num(cs.marginLeft), 80 * gTF.ease(0.5), 0.01, 985 "animation-play-state test 1 still at 500ms"); 986 advance_clock(500); 987 is_approx(px_to_num(cs.marginLeft), 80 + 20 * gTF.ease(0.5), 0.01, 988 "animation-play-state test 1 at 1000ms"); 989 advance_clock(250); 990 is(cs.marginLeft, "100px", "animation-play-state test 1 at 1250ms"); 991 advance_clock(250); 992 is_approx(px_to_num(cs.marginLeft), 80 + 20 * gTF.ease(0.5), 0.01, 993 "animation-play-state test 1 at 1500ms"); 994 div.style.animationPlayState = "paused"; 995 is_approx(px_to_num(cs.marginLeft), 80 + 20 * gTF.ease(0.5), 0.01, 996 "animation-play-state test 1 at 1500ms"); 997 advance_clock(2000); 998 is_approx(px_to_num(cs.marginLeft), 80 + 20 * gTF.ease(0.5), 0.01, 999 "animation-play-state test 1 at 3500ms"); 1000 advance_clock(500); 1001 is_approx(px_to_num(cs.marginLeft), 80 + 20 * gTF.ease(0.5), 0.01, 1002 "animation-play-state test 1 at 4000ms"); 1003 div.style.animationPlayState = ""; 1004 is_approx(px_to_num(cs.marginLeft), 80 + 20 * gTF.ease(0.5), 0.01, 1005 "animation-play-state test 1 at 4000ms"); 1006 advance_clock(500); 1007 is_approx(px_to_num(cs.marginLeft), 80 * gTF.ease(0.5), 0.01, 1008 "animation-play-state test 1 at 4500ms"); 1009 advance_clock(250); 1010 is(cs.marginLeft, "0px", "animation-play-state test 1, at 4750ms"); 1011 advance_clock(250); 1012 is(cs.marginLeft, "0px", "animation-play-state test 1, at 5000ms"); 1013 done_div(); 1014 1015 // more complicated test with multiple animations (and different directions 1016 // and iteration counts) 1017 new_div(""); 1018 div.style.animationTimingFunction = "ease-out, ease-in, ease-in-out"; 1019 div.style.animationName = "anim2, anim3, anim4"; 1020 div.style.animationDuration = "1s, 2s, 1s"; 1021 div.style.animationDirection = "alternate, normal, normal"; 1022 div.style.animationIterationCount = "4, 2, infinite"; 1023 is(cs.marginRight, "0px", "animation-play-state test 2, at 0s"); 1024 is(cs.marginTop, "0px", "animation-play-state test 3, at 0s"); 1025 is(cs.marginBottom, "0px", "animation-play-state test 4, at 0s"); 1026 advance_clock(250); 1027 div.style.animationPlayState = "paused, running"; // pause 1 and 3 1028 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.25), 0.01, 1029 "animation-play-state test 2 at 250ms"); 1030 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.125), 0.01, 1031 "animation-play-state test 3 at 250ms"); 1032 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.25), 0.01, 1033 "animation-play-state test 4 at 250ms"); 1034 advance_clock(250); 1035 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.25), 0.01, 1036 "animation-play-state test 2 at 500ms"); 1037 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.25), 0.01, 1038 "animation-play-state test 3 at 500ms"); 1039 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.25), 0.01, 1040 "animation-play-state test 4 at 500ms"); 1041 div.style.animationPlayState = "paused, running, running"; // unpause 3 1042 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.25), 0.01, 1043 "animation-play-state test 2 at 500ms"); 1044 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.25), 0.01, 1045 "animation-play-state test 3 at 500ms"); 1046 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.25), 0.01, 1047 "animation-play-state test 4 at 500ms"); 1048 advance_clock(250); 1049 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.25), 0.01, 1050 "animation-play-state test 2 at 750ms"); 1051 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.375), 0.01, 1052 "animation-play-state test 3 at 750ms"); 1053 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.5), 0.01, 1054 "animation-play-state test 4 at 750ms"); 1055 div.style.animationPlayState = "running, paused"; // unpause 1, pause 2 1056 advance_clock(0); // notify refresh observers 1057 advance_clock(250); 1058 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.5), 0.01, 1059 "animation-play-state test 2 at 1000ms"); 1060 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.375), 0.01, 1061 "animation-play-state test 3 at 1000ms"); 1062 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.75), 0.01, 1063 "animation-play-state test 4 at 1000ms"); 1064 div.style.animationPlayState = "paused"; // pause all 1065 advance_clock(0); // notify refresh observers 1066 advance_clock(3000); 1067 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.5), 0.01, 1068 "animation-play-state test 2 at 4000ms"); 1069 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.375), 0.01, 1070 "animation-play-state test 3 at 4000ms"); 1071 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.75), 0.01, 1072 "animation-play-state test 4 at 4000ms"); 1073 div.style.animationPlayState = "running, paused"; // pause 2 1074 advance_clock(0); // notify refresh observers 1075 advance_clock(850); 1076 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.65), 0.01, 1077 "animation-play-state test 2 at 4850ms"); 1078 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.375), 0.01, 1079 "animation-play-state test 3 at 4850ms"); 1080 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.6), 0.01, 1081 "animation-play-state test 4 at 4850ms"); 1082 advance_clock(300); 1083 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.35), 0.01, 1084 "animation-play-state test 2 at 5150ms"); 1085 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.375), 0.01, 1086 "animation-play-state test 3 at 5150ms"); 1087 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.9), 0.01, 1088 "animation-play-state test 4 at 5150ms"); 1089 advance_clock(2300); 1090 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.05), 0.01, 1091 "animation-play-state test 2 at 7450ms"); 1092 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.375), 0.01, 1093 "animation-play-state test 3 at 7450ms"); 1094 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.2), 0.01, 1095 "animation-play-state test 4 at 7450ms"); 1096 advance_clock(100); 1097 is(cs.marginRight, "0px", "animation-play-state test 2 at 7550ms"); 1098 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.375), 0.01, 1099 "animation-play-state test 3 at 7550ms"); 1100 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.3), 0.01, 1101 "animation-play-state test 4 at 7550ms"); 1102 div.style.animationPlayState = "running"; // unpause 2 1103 advance_clock(0); // notify refresh observers 1104 advance_clock(1000); 1105 is(cs.marginRight, "0px", "animation-play-state test 2 at 7550ms"); 1106 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.875), 0.01, 1107 "animation-play-state test 3 at 7550ms"); 1108 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.3), 0.01, 1109 "animation-play-state test 4 at 7550ms"); 1110 advance_clock(500); 1111 is(cs.marginRight, "0px", "animation-play-state test 2 at 8050ms"); 1112 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.125), 0.01, 1113 "animation-play-state test 3 at 8050ms"); 1114 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.8), 0.01, 1115 "animation-play-state test 4 at 8050ms"); 1116 advance_clock(1000); 1117 is(cs.marginRight, "0px", "animation-play-state test 2 at 9050ms"); 1118 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.625), 0.01, 1119 "animation-play-state test 3 at 9050ms"); 1120 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.8), 0.01, 1121 "animation-play-state test 4 at 9050ms"); 1122 advance_clock(500); 1123 is(cs.marginRight, "0px", "animation-play-state test 2 at 9550ms"); 1124 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.875), 0.01, 1125 "animation-play-state test 3 at 9550ms"); 1126 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.3), 0.01, 1127 "animation-play-state test 4 at 9550ms"); 1128 advance_clock(500); 1129 is(cs.marginRight, "0px", "animation-play-state test 2 at 10050ms"); 1130 is(cs.marginTop, "0px", "animation-play-state test 3 at 10050ms"); 1131 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.8), 0.01, 1132 "animation-play-state test 4 at 10050ms"); 1133 done_div(); 1134 1135 // an initially paused animation (bug 1063992) 1136 new_div("animation: anim1 1s paused both"); 1137 is(cs.marginLeft, "0px", "animation-play-state test 5, at 0s"); 1138 advance_clock(500); 1139 is(cs.marginLeft, "0px", "animation-play-state test 5, at 0.5s"); 1140 div.style.animationPlayState = "running"; 1141 is(cs.marginLeft, "0px", 1142 "animation-play-state test 5, at 0.5s after unpausing"); 1143 advance_clock(500); 1144 is(cs.marginLeft, "80px", 1145 "animation-play-state test 5, at 1s after unpaused"); 1146 done_div(); 1147 1148 /* 1149 * css3-animations: 3.8. The 'animation-delay' Property 1150 * http://dev.w3.org/csswg/css3-animations/#the-animation-delay-property- 1151 */ 1152 1153 // test positive delay 1154 new_div("animation: anim2 1s 0.5s ease-out"); 1155 is(cs.marginRight, "0px", "positive delay test at 0ms"); 1156 advance_clock(400); 1157 is(cs.marginRight, "0px", "positive delay test at 400ms"); 1158 advance_clock(100); 1159 is(cs.marginRight, "0px", "positive delay test at 500ms"); 1160 advance_clock(100); 1161 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.1), 0.01, 1162 "positive delay test at 500ms"); 1163 done_div(); 1164 1165 // test dynamic changes to delay (i.e., that we preserve the start time 1166 // that's before the delay) 1167 new_div("animation: anim2 1s 0.5s ease-out both"); 1168 is(cs.marginRight, "0px", "dynamic delay delay test at 0ms"); 1169 advance_clock(400); 1170 is(cs.marginRight, "0px", "dynamic delay delay test at 400ms (1)"); 1171 div.style.animationDelay = "0.2s"; 1172 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.2), 0.01, 1173 "dynamic delay delay test at 400ms (2)"); 1174 div.style.animationDelay = "0.6s"; 1175 advance_clock(0); 1176 advance_clock(200); 1177 is(cs.marginRight, "0px", "dynamic delay delay test at 600ms"); 1178 advance_clock(200); 1179 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.2), 0.01, 1180 "dynamic delay delay test at 800ms"); 1181 advance_clock(1000); 1182 is(cs.marginRight, "100px", "dynamic delay delay test at 1800ms (1)"); 1183 div.style.animationDelay = "1.5s"; 1184 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.3), 0.01, 1185 "dynamic delay delay test at 1800ms (2)"); 1186 div.style.animationDelay = "2s"; 1187 is(cs.marginRight, "0px", "dynamic delay delay test at 1800ms (3)"); 1188 done_div(); 1189 1190 // test delay and play-state interaction 1191 new_div("animation: anim2 1s 0.5s ease-out"); 1192 is(cs.marginRight, "0px", "delay and play-state delay test at 0ms"); 1193 advance_clock(400); 1194 is(cs.marginRight, "0px", "delay and play-state delay test at 400ms"); 1195 div.style.animationPlayState = "paused"; 1196 advance_clock(0); 1197 advance_clock(100); 1198 is(cs.marginRight, "0px", "delay and play-state delay test at 500ms"); 1199 advance_clock(500); 1200 is(cs.marginRight, "0px", "delay and play-state delay test at 1000ms"); 1201 div.style.animationPlayState = "running"; 1202 advance_clock(0); 1203 advance_clock(100); 1204 is(cs.marginRight, "0px", "delay and play-state delay test at 1100ms"); 1205 advance_clock(100); 1206 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.1), 0.01, 1207 "delay and play-state delay test at 1200ms"); 1208 div.style.animationPlayState = "paused"; 1209 advance_clock(0); 1210 advance_clock(100); 1211 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.1), 0.01, 1212 "delay and play-state delay test at 1300ms"); 1213 done_div(); 1214 1215 // test negative delay and implicit starting values 1216 new_div("margin-top: 1000px"); 1217 advance_clock(300); 1218 div.style.marginTop = "100px"; 1219 div.style.animation = "kf1 1s -0.1s ease-in"; 1220 is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease_in(0.2), 0.01, 1221 "delay and implicit starting values test"); 1222 done_div(); 1223 1224 // test large negative delay that causes the animation to start 1225 // in the fourth iteration 1226 new_div("animation: anim2 1s -3.6s ease-in 5 alternate forwards"); 1227 listen(); // rely on no flush having happened yet 1228 cs.animationName; // flush styles so animation is created 1229 advance_clock(0); // complete pending animation start 1230 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.4), 0.01, 1231 "large negative delay test at 0ms"); 1232 check_events([{ type: 'animationstart', target: div, 1233 animationName: 'anim2', elapsedTime: 3.6, 1234 pseudoElement: "" }], 1235 "right after start in large negative delay test"); 1236 advance_clock(380); 1237 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.02), 0.01, 1238 "large negative delay test at 380ms"); 1239 check_events([]); 1240 advance_clock(20); 1241 is(cs.marginRight, "0px", "large negative delay test at 400ms"); 1242 check_events([{ type: 'animationiteration', target: div, 1243 animationName: 'anim2', elapsedTime: 4.0, 1244 pseudoElement: "" }], 1245 "large negative delay test at 400ms"); 1246 advance_clock(800); 1247 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.8), 0.01, 1248 "large negative delay test at 1200ms"); 1249 check_events([]); 1250 advance_clock(200); 1251 is(cs.marginRight, "100px", "large negative delay test at 1400ms"); 1252 check_events([{ type: 'animationend', target: div, 1253 animationName: 'anim2', elapsedTime: 5.0, 1254 pseudoElement: "" }], 1255 "large negative delay test at 1400ms"); 1256 done_div(); 1257 1258 /* 1259 * css3-animations: 3.9. The 'animation-fill-mode' Property 1260 * http://dev.w3.org/csswg/css3-animations/#the-animation-fill-mode-property- 1261 */ 1262 1263 // animation-fill-mode is tested in the tests for section (2). 1264 1265 /* 1266 * css3-animations: 3.10. The 'animation' Shorthand Property 1267 * http://dev.w3.org/csswg/css3-animations/#the-animation-shorthand-property- 1268 */ 1269 1270 // shorthand vs. longhand is adequately tested by the 1271 // property_database.js-based tests. 1272 1273 /** 1274 * Basic tests of animations on pseudo-elements 1275 */ 1276 new_div(""); 1277 listen(); 1278 div.id = "withbefore"; 1279 var cs_before = getComputedStyle(div, ":before"); 1280 is(cs_before.marginRight, "0px", ":before test at 0ms"); 1281 advance_clock(400); 1282 is(cs_before.marginRight, "40px", ":before test at 400ms"); 1283 advance_clock(800); 1284 is(cs_before.marginRight, "80px", ":before test at 1200ms"); 1285 is(cs.marginRight, "0px", ":before animation should not affect element"); 1286 advance_clock(800); 1287 is(cs_before.marginRight, "0px", ":before test at 2000ms"); 1288 advance_clock(300); 1289 is(cs_before.marginRight, "30px", ":before test at 2300ms"); 1290 advance_clock(700); 1291 check_events([ { type: "animationstart", animationName: "anim2", elapsedTime: 0, pseudoElement: "::before" }, 1292 { type: "animationiteration", animationName: "anim2", elapsedTime: 1, pseudoElement: "::before" }, 1293 { type: "animationiteration", animationName: "anim2", elapsedTime: 2, pseudoElement: "::before" }, 1294 { type: "animationend", animationName: "anim2", elapsedTime: 3, pseudoElement: "::before" }]); 1295 done_div(); 1296 1297 new_div(""); 1298 listen(); 1299 div.id = "withafter"; 1300 var cs_after = getComputedStyle(div, ":after"); 1301 is(cs_after.marginRight, "0px", ":after test at 0ms"); 1302 advance_clock(400); 1303 is(cs_after.marginRight, "40px", ":after test at 400ms"); 1304 advance_clock(800); 1305 is(cs_after.marginRight, "80px", ":after test at 1200ms"); 1306 is(cs.marginRight, "0px", ":after animation should not affect element"); 1307 advance_clock(800); 1308 is(cs_after.marginRight, "0px", ":after test at 2000ms"); 1309 advance_clock(300); 1310 is(cs_after.marginRight, "30px", ":after test at 2300ms"); 1311 advance_clock(700); 1312 check_events([ { type: "animationstart", animationName: "anim2", elapsedTime: 0, pseudoElement: "::after" }, 1313 { type: "animationiteration", animationName: "anim2", elapsedTime: 1, pseudoElement: "::after" }, 1314 { type: "animationiteration", animationName: "anim2", elapsedTime: 2, pseudoElement: "::after" }, 1315 { type: "animationend", animationName: "anim2", elapsedTime: 3, pseudoElement: "::after" }]); 1316 done_div(); 1317 1318 /** 1319 * Test handling of properties that are present in only some of the 1320 * keyframes. 1321 */ 1322 new_div("animation: multiprop 1s ease-in-out alternate infinite"); 1323 is(cs.paddingTop, "10px", "multiprop top at 0ms"); 1324 is(cs.paddingLeft, "30px", "multiprop top at 0ms"); 1325 advance_clock(100); 1326 is_approx(px_to_num(cs.paddingTop), 10 + 30 * gTF.ease(0.2), 0.01, 1327 "multiprop top at 100ms"); 1328 is_approx(px_to_num(cs.paddingLeft), 30 + 20 * gTF.ease(0.4), 0.01, 1329 "multiprop left at 100ms"); 1330 advance_clock(200); 1331 is_approx(px_to_num(cs.paddingTop), 10 + 30 * gTF.ease(0.6), 0.01, 1332 "multiprop top at 300ms"); 1333 is_approx(px_to_num(cs.paddingLeft), 50 + 10 * gTF.ease_out(0.1), 0.01, 1334 "multiprop left at 300ms"); 1335 advance_clock(300); 1336 is_approx(px_to_num(cs.paddingTop), 40 + 40 * gTF.ease_in_out(0.4), 0.01, 1337 "multiprop top at 600ms"); 1338 is_approx(px_to_num(cs.paddingLeft), 50 + 10 * gTF.ease_out(0.7), 0.01, 1339 "multiprop left at 600ms"); 1340 advance_clock(200); 1341 is_approx(px_to_num(cs.paddingTop), 80 - 80 * gTF.ease_in(0.2), 0.01, 1342 "multiprop top at 800ms"); 1343 is_approx(px_to_num(cs.paddingLeft), 60 - 60 * gTF.ease_in(0.2), 0.01, 1344 "multiprop left at 800ms"); 1345 advance_clock(400); 1346 is_approx(px_to_num(cs.paddingTop), 80 - 80 * gTF.ease_in(0.2), 0.01, 1347 "multiprop top at 1200ms"); 1348 is_approx(px_to_num(cs.paddingLeft), 60 - 60 * gTF.ease_in(0.2), 0.01, 1349 "multiprop left at 1200ms"); 1350 advance_clock(200); 1351 is_approx(px_to_num(cs.paddingTop), 40 + 40 * gTF.ease_in_out(0.4), 0.01, 1352 "multiprop top at 1400ms"); 1353 is_approx(px_to_num(cs.paddingLeft), 50 + 10 * gTF.ease_out(0.7), 0.01, 1354 "multiprop left at 1400ms"); 1355 advance_clock(300); 1356 is_approx(px_to_num(cs.paddingTop), 10 + 30 * gTF.ease(0.6), 0.01, 1357 "multiprop top at 1700ms"); 1358 is_approx(px_to_num(cs.paddingLeft), 50 + 10 * gTF.ease_out(0.1), 0.01, 1359 "multiprop left at 1700ms"); 1360 advance_clock(200); 1361 is_approx(px_to_num(cs.paddingTop), 10 + 30 * gTF.ease(0.2), 0.01, 1362 "multiprop top at 1900ms"); 1363 is_approx(px_to_num(cs.paddingLeft), 30 + 20 * gTF.ease(0.4), 0.01, 1364 "multiprop left at 1900ms"); 1365 done_div(); 1366 1367 // Test for https://bugzilla.mozilla.org/show_bug.cgi?id=651456 -- make 1368 // sure that refreshing of animations doesn't break when we get two 1369 // refreshes with the same timestamp. 1370 new_div("animation: anim2 1s linear"); 1371 is(cs.marginRight, "0px", "bug 651456 at 0ms"); 1372 advance_clock(100); 1373 is(cs.marginRight, "10px", "bug 651456 at 100ms (1)"); 1374 advance_clock(0); // still forces a refresh 1375 is(cs.marginRight, "10px", "bug 651456 at 100ms (2)"); 1376 advance_clock(100); 1377 is(cs.marginRight, "20px", "bug 651456 at 200ms"); 1378 done_div(); 1379 1380 // Test that UA !important rules override animations. 1381 // This test depends on forms.css having a rule 1382 // option { white-space: !important } 1383 // If that rule changes, we should rewrite it to depend on a different rule. 1384 var option; 1385 [ option, cs ] = new_element("option", ""); 1386 var default_white_space = cs.whiteSpace; 1387 isnot(default_white_space, "pre", 1388 "default style should not be the same as animation style"); 1389 done_element(); 1390 [ option, cs ] = new_element("option", 1391 "animation: uaoverride 2s linear infinite"); 1392 is(cs.whiteSpace, default_white_space, 1393 "animations should not override UA !important at 0ms"); 1394 is(cs.marginTop, "20px", 1395 "rest of animation should still work when UA !important present at 0ms"); 1396 advance_clock(200); 1397 is(cs.whiteSpace, default_white_space, 1398 "animations should not override UA !important at 200ms"); 1399 is(cs.marginTop, "40px", 1400 "rest of animation should still work when UA !important present at 200ms"); 1401 done_element(); 1402 1403 // Test that author !important rules override animations, but 1404 // that animations override regular author rules. 1405 new_div("animation: always_fifty 1s linear infinite; margin-left: 200px"); 1406 is(cs.marginLeft, "50px", "animations override regular author rules"); 1407 done_div(); 1408 new_div("animation: always_fifty 1s linear infinite;" 1409 + " margin-left: 200px ! important;"); 1410 is(cs.marginLeft, "200px", "important author rules override animations"); 1411 done_div(); 1412 1413 // Test interaction of animations and restyling (Bug 686656). 1414 // This test depends on kf3 getting its 0% and 100% values from the 1415 // rules below it in the cascade; we're checking that the animation 1416 // isn't rebuilt when the restyles happen. 1417 new_div("animation: kf3 1s linear forwards"); 1418 is(cs.marginTop, "0px", "bug 686656 test 1 at 0ms"); 1419 advance_clock(250); 1420 display.style.color = "blue"; 1421 is(cs.marginTop, "100px", "bug 686656 test 1 at 250ms"); 1422 advance_clock(375); 1423 is(cs.marginTop, "50px", "bug 686656 test 1 at 625ms"); 1424 advance_clock(375); 1425 is(cs.marginTop, "0px", "bug 686656 test 1 at 1000ms"); 1426 done_div(); 1427 display.style.color = ""; 1428 1429 // Test interaction of animations and restyling (Bug 686656), 1430 // with reframing. 1431 // This test depends on kf3 getting its 0% and 100% values from the 1432 // rules below it in the cascade; we're checking that the animation 1433 // isn't rebuilt when the restyles happen. 1434 new_div("animation: kf3 1s linear forwards"); 1435 is(cs.marginTop, "0px", "bug 686656 test 2 at 0ms"); 1436 advance_clock(250); 1437 display.style.overflow = "scroll"; 1438 is(cs.marginTop, "100px", "bug 686656 test 2 at 250ms"); 1439 advance_clock(375); 1440 is(cs.marginTop, "50px", "bug 686656 test 2 at 625ms"); 1441 advance_clock(375); 1442 is(cs.marginTop, "0px", "bug 686656 test 2 at 1000ms"); 1443 done_div(); 1444 display.style.overflow = ""; 1445 1446 // Test that cascading between keyframes rules is per-property rather 1447 // than per-rule (bug ), and that the timing function isn't taken from a 1448 // rule that's skipped. (Bug 738003) 1449 new_div("animation: cascade 1s linear forwards; position: relative"); 1450 is(cs.top, "0px", "cascade test (top) at 0ms"); 1451 is(cs.left, "0px", "cascade test (top) at 0ms"); 1452 advance_clock(125); 1453 is(cs.top, "0px", "cascade test (top) at 125ms"); 1454 is(cs.left, "50px", "cascade test (top) at 125ms"); 1455 advance_clock(125); 1456 is(cs.top, "0px", "cascade test (top) at 250ms"); 1457 is(cs.left, "100px", "cascade test (top) at 250ms"); 1458 advance_clock(125); 1459 is(cs.top, "50px", "cascade test (top) at 375ms"); 1460 is(cs.left, "100px", "cascade test (top) at 375ms"); 1461 advance_clock(125); 1462 is(cs.top, "100px", "cascade test (top) at 500ms"); 1463 is(cs.left, "100px", "cascade test (top) at 500ms"); 1464 advance_clock(125); 1465 is(cs.top, "100px", "cascade test (top) at 625ms"); 1466 is(cs.left, "50px", "cascade test (top) at 625ms"); 1467 advance_clock(125); 1468 is(cs.top, "100px", "cascade test (top) at 750ms"); 1469 is(cs.left, "0px", "cascade test (top) at 750ms"); 1470 advance_clock(125); 1471 is(cs.top, "50px", "cascade test (top) at 875ms"); 1472 is(cs.left, "0px", "cascade test (top) at 875ms"); 1473 advance_clock(125); 1474 is(cs.top, "0px", "cascade test (top) at 1000ms"); 1475 is(cs.left, "0px", "cascade test (top) at 1000ms"); 1476 done_div(); 1477 1478 new_div("animation: cascade2 8s linear forwards"); 1479 is(cs.textIndent, "0px", "cascade2 test at 0s"); 1480 advance_clock(1000); 1481 is(cs.textIndent, "25px", "cascade2 test at 1s"); 1482 advance_clock(1000); 1483 is(cs.textIndent, "50px", "cascade2 test at 2s"); 1484 advance_clock(1000); 1485 is(cs.textIndent, "25px", "cascade2 test at 3s"); 1486 advance_clock(1000); 1487 is(cs.textIndent, "0px", "cascade2 test at 4s"); 1488 advance_clock(3000); 1489 is(cs.textIndent, "75px", "cascade2 test at 7s"); 1490 advance_clock(1000); 1491 is(cs.textIndent, "100px", "cascade2 test at 8s"); 1492 done_div(); 1493 1494 new_div("animation: primitives1 2s linear forwards"); 1495 is(cs.getPropertyValue("transform"), "matrix(1, 0, 0, 1, 0, 0)", 1496 "primitives1 at 0s"); 1497 advance_clock(1000); 1498 is(cs.getPropertyValue("transform"), 1499 "matrix(-0.707107, 0.707107, -0.707107, -0.707107, 0, 0)", 1500 "primitives1 at 1s"); 1501 advance_clock(1000); 1502 is(cs.getPropertyValue("transform"), "matrix(0, -1, 1, 0, 0, 0)", 1503 "primitives1 at 0s"); 1504 done_div(); 1505 1506 new_div("animation: important1 1s linear forwards"); 1507 is(cs.marginTop, "50px", "important1 test at 0s"); 1508 advance_clock(500); 1509 is(cs.marginTop, "75px", "important1 test at 0.5s"); 1510 advance_clock(500); 1511 is(cs.marginTop, "100px", "important1 test at 1s"); 1512 done_div(); 1513 1514 new_div("animation: important2 1s linear forwards"); 1515 is(cs.marginTop, "50px", "important2 (margin-top) test at 0s"); 1516 is(cs.marginBottom, "100px", "important2 (margin-bottom) test at 0s"); 1517 advance_clock(1000); 1518 is(cs.marginTop, "0px", "important2 (margin-top) test at 1s"); 1519 is(cs.marginBottom, "50px", "important2 (margin-bottom) test at 1s"); 1520 done_div(); 1521 1522 // Test that it's the length of the 'animation-name' list that's used to 1523 // start animations. 1524 // note: anim2 animates margin-right from 0 to 100px 1525 // note: anim3 animates margin-top from 0 to 100px 1526 new_div("animation-name: anim2, anim3;" 1527 + " animation-duration: 1s;" 1528 + " animation-timing-function: linear;" 1529 + " animation-delay: -250ms, -250ms, -750ms, -500ms;"); 1530 is(cs.marginRight, "25px", "animation-name list length is the length that matters"); 1531 is(cs.marginTop, "25px", "animation-name list length is the length that matters"); 1532 done_div(); 1533 new_div("animation-name: anim2, anim3, anim2;" 1534 + " animation-duration: 1s;" 1535 + " animation-timing-function: linear;" 1536 + " animation-delay: -250ms, -250ms, -750ms, -500ms;"); 1537 is(cs.marginRight, "75px", "animation-name list length is the length that matters, and the last occurrence of a name wins"); 1538 is(cs.marginTop, "25px", "animation-name list length is the length that matters"); 1539 done_div(); 1540 1541 var dyn_sheet_elt = document.createElement("style"); 1542 document.head.appendChild(dyn_sheet_elt); 1543 var dyn_sheet = dyn_sheet_elt.sheet; 1544 dyn_sheet.insertRule("@keyframes dyn1 { from { margin-left: 0 } 50% { margin-left: 50px } to { margin-left: 100px } }", 0); 1545 dyn_sheet.insertRule("@keyframes dyn2 { from { margin-left: 100px } to { margin-left: 200px } }", 1); 1546 var dyn1 = dyn_sheet.cssRules[0]; 1547 var dyn2 = dyn_sheet.cssRules[1]; 1548 new_div("animation: dyn1 1s linear"); 1549 is(cs.marginLeft, "0px", "dynamic rule change test, initial state"); 1550 advance_clock(250); 1551 is(cs.marginLeft, "25px", "dynamic rule change test, 250ms"); 1552 dyn2.name = "dyn1"; 1553 is(cs.marginLeft, "125px", "dynamic rule change test, change in @keyframes name applies"); 1554 dyn2.appendRule("50% { margin-left: 0px }"); 1555 is(cs.marginLeft, "50px", "dynamic rule change test, @keyframes appendRule"); 1556 var dyn2_kf1 = dyn2.cssRules[0]; // currently 0% { margin-left: 100px } 1557 dyn2_kf1.style.marginLeft = "-100px"; 1558 is(cs.marginLeft, "-50px", "dynamic rule change test, keyframe style set"); 1559 dyn2.name = "dyn2"; 1560 is(cs.marginLeft, "25px", "dynamic rule change test, change in @keyframes name applies (second time)"); 1561 var dyn1_kf2 = dyn1.cssRules[1]; // currently 50% { margin-left: 50px } 1562 dyn1_kf2.keyText = "25%"; 1563 is(cs.marginLeft, "50px", "dynamic rule change test, change in keyframe keyText"); 1564 dyn1.deleteRule("25%"); 1565 is(cs.marginLeft, "25px", "dynamic rule change test, @keyframes deleteRule"); 1566 done_div(); 1567 dyn_sheet_elt.remove(); 1568 dyn_sheet_elt = null; 1569 dyn_sheet = null; 1570 1571 /* 1572 * Bug 1004361 - CSS animations with short duration sometimes don't dispatch 1573 * a start event 1574 */ 1575 new_div("animation: anim2 1s 0.1s"); 1576 listen(); 1577 advance_clock(0); // Trigger animation 1578 advance_clock(1200); // Skip past end of animation's entire active duration 1579 check_events([{ type: 'animationstart', target: div, 1580 animationName: 'anim2', elapsedTime: 0, 1581 pseudoElement: "" }, 1582 { type: 'animationend', target: div, 1583 animationName: 'anim2', elapsedTime: 1, 1584 pseudoElement: "" }], 1585 "events after skipping over animation interval"); 1586 done_div(); 1587 1588 /* 1589 * Bug 1007513 - AnimationEvent.elapsedTime should be animation time 1590 */ 1591 new_div("animation: anim2 1s 2"); 1592 listen(); 1593 advance_clock(0); // Trigger animation 1594 advance_clock(500); // Jump to middle of first interval 1595 advance_clock(1000); // Jump to middle of second interval 1596 advance_clock(1000); // Jump past end of last interval 1597 check_events([{ type: 'animationstart', target: div, 1598 animationName: 'anim2', elapsedTime: 0, 1599 pseudoElement: "" }, 1600 { type: 'animationiteration', target: div, 1601 animationName: 'anim2', elapsedTime: 1, 1602 pseudoElement: "" }, 1603 { type: 'animationend', target: div, 1604 animationName: 'anim2', elapsedTime: 2, 1605 pseudoElement: "" }], 1606 "events after skipping past event moments"); 1607 done_div(); 1608 1609 new_div("animation: anim2 1s -2s"); 1610 listen(); 1611 cs.animationName; // build animation 1612 advance_clock(0); // finish pending 1613 check_events([{ type: 'animationstart', target: div, 1614 animationName: 'anim2', elapsedTime: 1, 1615 pseudoElement: "" }, 1616 { type: 'animationend', target: div, 1617 animationName: 'anim2', elapsedTime: 1, 1618 pseudoElement: "" }], 1619 "events after skipping over animation with negative delay"); 1620 done_div(); 1621 1622 /* 1623 * Bug 1004365 - zero-duration animations 1624 */ 1625 1626 new_div("margin-right: 200px; animation: anim2 0s 1s both"); 1627 listen(); 1628 advance_clock(0); 1629 is(cs.getPropertyValue("margin-right"), "0px", 1630 "margin-right during backwards fill of zero-duration animation"); 1631 advance_clock(2000); // Skip over animation 1632 is(cs.getPropertyValue("margin-right"), "100px", 1633 "margin-right during forwards fill of zero-duration animation"); 1634 check_events([{ type: 'animationstart', target: div, 1635 animationName: 'anim2', elapsedTime: 0, 1636 pseudoElement: "" }, 1637 { type: 'animationend', target: div, 1638 animationName: 'anim2', elapsedTime: 0, 1639 pseudoElement: "" }], 1640 "events after skipping over zero-duration animation"); 1641 done_div(); 1642 1643 new_div("margin-right: 200px; animation: anim2 0s 1s both"); 1644 listen(); 1645 advance_clock(0); 1646 // Seek to just before the animation starts and stops 1647 advance_clock(999); 1648 is(cs.getPropertyValue("margin-right"), "0px", 1649 "margin-right at exact end of zero-duration animation"); 1650 check_events([]); 1651 // Seek to exactly the point where the animation starts and stops 1652 advance_clock(1); 1653 is(cs.getPropertyValue("margin-right"), "100px", 1654 "margin-right at exact end of zero-duration animation"); 1655 check_events([{ type: 'animationstart', target: div, 1656 animationName: 'anim2', elapsedTime: 0, 1657 pseudoElement: "" }, 1658 { type: 'animationend', target: div, 1659 animationName: 'anim2', elapsedTime: 0, 1660 pseudoElement: "" }], 1661 "events after seeking to end of zero-duration animation"); 1662 // Check no further events are dispatched 1663 advance_clock(0); 1664 advance_clock(100); 1665 check_events([]); 1666 done_div(); 1667 1668 // Test with animation-direction reverse 1669 new_div("margin-right: 200px;" 1670 + " animation: anim2 0s 1s both reverse"); 1671 advance_clock(0); 1672 is(cs.getPropertyValue("margin-right"), "100px", 1673 "margin-right during backwards fill of reversed zero-duration animation"); 1674 advance_clock(2000); 1675 is(cs.getPropertyValue("margin-right"), "0px", 1676 "margin-right during forwards fill of reversed zero-duration animation"); 1677 done_div(); 1678 1679 // Test with animation-direction alternate 1680 new_div("margin-right: 200px; animation: anim2 0s 1s both alternate 2"); 1681 listen(); 1682 advance_clock(0); 1683 is(cs.getPropertyValue("margin-right"), "0px", 1684 "margin-right during backwards fill of alternating zero-duration animation"); 1685 advance_clock(2000); 1686 is(cs.getPropertyValue("margin-right"), "0px", 1687 "margin-right during forwards fill of alternating zero-duration animation"); 1688 check_events([{ type: 'animationstart', target: div, 1689 animationName: 'anim2', elapsedTime: 0, 1690 pseudoElement: "" }, 1691 { type: 'animationend', target: div, 1692 animationName: 'anim2', elapsedTime: 0, 1693 pseudoElement: "" }], 1694 "events after seeking to end of zero-duration animation" 1695 + " that repeats twice"); 1696 done_div(); 1697 1698 // Test with animation-direction alternate and odd number of iterations 1699 new_div("margin-right: 200px; animation: anim2 0s 1s both alternate 3"); 1700 advance_clock(0); 1701 is(cs.getPropertyValue("margin-right"), "0px", 1702 "margin-right during backwards fill of alternating zero-duration " + 1703 "animation with odd number of iterations"); 1704 advance_clock(2000); 1705 is(cs.getPropertyValue("margin-right"), "100px", 1706 "margin-right during forwards fill of alternating zero-duration " + 1707 "animation with odd number of iterations"); 1708 done_div(); 1709 1710 // Test with animation-direction alternate and non-integral number of iterations 1711 new_div("margin-right: 200px;" 1712 + " animation: anim2 0s 1s both alternate 7.3 linear"); 1713 advance_clock(0); 1714 is(cs.getPropertyValue("margin-right"), "0px", 1715 "margin-right during backwards fill of alternating zero-duration " + 1716 "animation with non-integral number of iterations"); 1717 advance_clock(2000); 1718 is(cs.getPropertyValue("margin-right"), "70px", 1719 "margin-right during forwards fill of alternating zero-duration " + 1720 "animation with non-integral number of iterations"); 1721 done_div(); 1722 1723 // Test with infinite iteration count 1724 // CSS Animations doesn't actually define what the behavior is in this case 1725 // (and many many other similar cases) so we follow the behavior defined in Web 1726 // Animations which is that the zero-duration "wins". 1727 new_div("margin-right: 200px; animation: anim2 0s 1s both infinite"); 1728 listen(); 1729 advance_clock(0); 1730 is(cs.getPropertyValue("margin-right"), "0px", 1731 "margin-right during backwards fill of infinitely repeating " + 1732 "zero-duration animation"); 1733 advance_clock(2000); 1734 is(cs.getPropertyValue("margin-right"), "100px", 1735 "margin-right during forwards fill of infinitely repeating " + 1736 "zero-duration animation"); 1737 // Check we don't get infinite iteration events :) 1738 check_events([{ type: 'animationstart', target: div, 1739 animationName: 'anim2', elapsedTime: 0, 1740 pseudoElement: "" }, 1741 { type: 'animationend', target: div, 1742 animationName: 'anim2', elapsedTime: 0, 1743 pseudoElement: "" }], 1744 "events after seeking to end of infinitely repeating " + 1745 "zero-duration animation"); 1746 done_div(); 1747 1748 // Test with infinite iteration count and alternating direction 1749 new_div("margin-right: 200px; animation: anim2 0s 1s alternate both infinite"); 1750 advance_clock(0); 1751 is(cs.getPropertyValue("margin-right"), "0px", 1752 "margin-right during backwards fill of infinitely repeating and " + 1753 "alternating zero-duration animation"); 1754 advance_clock(2000); 1755 is(cs.getPropertyValue("margin-right"), "0px", 1756 "margin-right during forwards fill of infinitely repeating and " + 1757 "alternating zero-duration animation"); 1758 done_div(); 1759 1760 // Test with infinite iteration count and alternate-reverse direction 1761 new_div("margin-right: 200px;" 1762 + " animation: anim2 0s 1s alternate-reverse infinite both"); 1763 advance_clock(0); 1764 is(cs.getPropertyValue("margin-right"), "100px", 1765 "margin-right during backwards fill of infinitely repeating and " + 1766 "alternate-reverse zero-duration animation"); 1767 advance_clock(2000); 1768 is(cs.getPropertyValue("margin-right"), "100px", 1769 "margin-right during forwards fill of infinitely repeating and " + 1770 "alternate-reverse zero-duration animation"); 1771 done_div(); 1772 1773 // Test with negative delay 1774 new_div("margin-right: 200px;" 1775 + " animation: anim2 0s -1s both reverse 12.7 linear"); 1776 listen(); 1777 cs.animationName; // build animation 1778 advance_clock(0); // finish pending 1779 is(cs.getPropertyValue("margin-right"), "30px", 1780 "margin-right during forwards fill of reversed and repeated " + 1781 "zero-duration animation with negative delay"); 1782 check_events([{ type: 'animationstart', target: div, 1783 animationName: 'anim2', elapsedTime: 0, 1784 pseudoElement: "" }, 1785 { type: 'animationend', target: div, 1786 animationName: 'anim2', elapsedTime: 0, 1787 pseudoElement: "" }], 1788 "events after skipping over zero-duration animation " + 1789 "with negative delay"); 1790 done_div(); 1791 1792 // Test zero duration with zero iteration count 1793 new_div("margin-right: 200px; animation: anim2 0s 1s both 0"); 1794 listen(); 1795 advance_clock(0); 1796 is(cs.getPropertyValue("margin-right"), "0px", 1797 "margin-right during backwards fill of zero-duration animation"); 1798 advance_clock(2000); // Skip over animation 1799 is(cs.getPropertyValue("margin-right"), "0px", 1800 "margin-right during forwards fill of zero-duration animation"); 1801 check_events([{ type: 'animationstart', target: div, 1802 animationName: 'anim2', elapsedTime: 0, 1803 pseudoElement: "" }, 1804 { type: 'animationend', target: div, 1805 animationName: 'anim2', elapsedTime: 0, 1806 pseudoElement: "" }], 1807 "events after skipping over zero-duration, zero iteration count" 1808 + " animation"); 1809 done_div(); 1810 1811 /* 1812 * Bug 1004377 - Animations with empty keyframes rule 1813 */ 1814 1815 new_div("margin-right: 200px; animation: empty 2s 1s both"); 1816 listen(); 1817 advance_clock(0); 1818 check_events([], "events during delay"); 1819 advance_clock(2000); // Skip to middle of animation 1820 div.clientTop; // Trigger events 1821 check_events([{ type: 'animationstart', target: div, 1822 animationName: 'empty', elapsedTime: 0, 1823 pseudoElement: "" }], 1824 "middle of animation with empty keyframes rule"); 1825 advance_clock(1000); // Skip to end of animation 1826 div.clientTop; // Trigger events 1827 check_events([{ type: 'animationend', target: div, 1828 animationName: 'empty', elapsedTime: 2, 1829 pseudoElement: "" }], 1830 "end of animation with empty keyframes rule"); 1831 done_div(); 1832 1833 // Test with a zero-duration animation and empty @keyframes rule 1834 new_div("margin-right: 200px; animation: empty 0s 1s both"); 1835 listen(); 1836 advance_clock(0); 1837 advance_clock(1000); 1838 div.clientTop; // Trigger events 1839 check_events([{ type: 'animationstart', target: div, 1840 animationName: 'empty', elapsedTime: 0, 1841 pseudoElement: "" }, 1842 { type: 'animationend', target: div, 1843 animationName: 'empty', elapsedTime: 0, 1844 pseudoElement: "" }], 1845 "end of zero-duration animation with empty keyframes rule"); 1846 done_div(); 1847 1848 // Test with a keyframes rule that becomes empty 1849 new_div("animation: nearlyempty 1s both linear"); 1850 advance_clock(0); 1851 advance_clock(500); 1852 is(cs.getPropertyValue("margin-left"), "50px", 1853 "margin-left for animation that is about to be emptied"); 1854 listen(); 1855 findKeyframesRule("nearlyempty").deleteRule("to"); 1856 is(cs.getPropertyValue("margin-left"), "0px", 1857 "margin-left for animation with (now) empty keyframes rule"); 1858 check_events([], "events after emptying keyframes rule"); 1859 advance_clock(500); 1860 div.clientTop; // Trigger events 1861 check_events([{ type: 'animationend', target: div, 1862 animationName: 'nearlyempty', elapsedTime: 1, 1863 pseudoElement: "" }], 1864 "events at end of animation with newly " + 1865 "empty keyframes rule"); 1866 done_div(); 1867 1868 // Test when we update to point to an empty animation 1869 new_div("animation: always_fifty 1s both linear"); 1870 advance_clock(0); 1871 advance_clock(500); 1872 is(cs.getPropertyValue("margin-left"), "50px", 1873 "margin-left for animation that will soon point to an empty keyframes rule"); 1874 listen(); 1875 div.style.animationName = "empty"; 1876 is(cs.getPropertyValue("margin-left"), "0px", 1877 "margin-left for animation now points to empty keyframes rule"); 1878 advance_clock(500); 1879 div.clientTop; // Trigger events 1880 check_events([{ type: 'animationstart', target: div, 1881 animationName: 'empty', elapsedTime: 0, 1882 pseudoElement: "" }], 1883 "events at start of animation updated to use " + 1884 "empty keyframes rule"); 1885 done_div(); 1886 1887 /* 1888 * Bug 1031319 - 'none' animations 1889 * 1890 * The code under test here is run entirely on the main thread so there is no 1891 * OMTA version of these tests in test_animations_omta.html. 1892 */ 1893 1894 // Setting "animation: none" after animations have finished should not trigger 1895 // animation events 1896 new_div("animation: always_fifty 1s"); 1897 listen(); 1898 advance_clock(0); 1899 advance_clock(1000); 1900 check_events([{ type: 'animationstart', target: div, 1901 animationName: 'always_fifty', elapsedTime: 0, 1902 pseudoElement: '' }, 1903 { type: 'animationend', target: div, 1904 animationName: 'always_fifty', elapsedTime: 1, 1905 pseudoElement: '' }], 1906 "events after running initial animation"); 1907 div.style.animation = "none"; 1908 div.clientTop; // Trigger events 1909 check_events([], "events after setting animation to 'none'"); 1910 done_div(); 1911 1912 // Setting "animation: " after animations have finished should not trigger 1913 // animation events 1914 new_div("animation: always_fifty 1s"); 1915 listen(); 1916 advance_clock(0); 1917 advance_clock(1000); 1918 check_events([{ type: 'animationstart', target: div, 1919 animationName: 'always_fifty', elapsedTime: 0, 1920 pseudoElement: '' }, 1921 { type: 'animationend', target: div, 1922 animationName: 'always_fifty', elapsedTime: 1, 1923 pseudoElement: '' }], 1924 "events after running initial animation"); 1925 div.style.animation = ""; 1926 div.clientTop; // Trigger events 1927 check_events([], "events after setting animation to ''"); 1928 done_div(); 1929 1930 // Setting "animation: none 1s" should not trigger events 1931 new_div("animation: none 1s"); 1932 listen(); 1933 advance_clock(0); 1934 advance_clock(1000); 1935 check_events([], "events after setting animation to 'none 1s'"); 1936 done_div(); 1937 1938 // Setting "animation: 1s" should not trigger events 1939 new_div("animation: 1s"); 1940 listen(); 1941 advance_clock(0); 1942 advance_clock(1000); 1943 check_events([], "events after setting animation to '1s'"); 1944 done_div(); 1945 1946 // Setting animation-name: none among other animations should cause only that 1947 // animation to be skipped 1948 new_div("animation-name: always_fifty, none, always_fifty;" 1949 + " animation-duration: 1s"); 1950 listen(); 1951 advance_clock(0); 1952 advance_clock(500); 1953 advance_clock(500); 1954 check_events([{ type: 'animationstart', target: div, 1955 animationName: 'always_fifty', elapsedTime: 0, 1956 pseudoElement: '' }, 1957 { type: 'animationstart', target: div, 1958 animationName: 'always_fifty', elapsedTime: 0, 1959 pseudoElement: '' }, 1960 { type: 'animationend', target: div, 1961 animationName: 'always_fifty', elapsedTime: 1, 1962 pseudoElement: '' }, 1963 { type: 'animationend', target: div, 1964 animationName: 'always_fifty', elapsedTime: 1, 1965 pseudoElement: '' }], 1966 "events for animation-name: a, none, a"); 1967 done_div(); 1968 1969 /* 1970 * Bug 1033881 - Non-matching animation-name 1971 * 1972 * The code under test here is run entirely on the main thread so there is no 1973 * OMTA version of these tests in test_animations_omta.html. 1974 */ 1975 1976 new_div("animation-name: non_existent, always_fifty; animation-duration: 1s"); 1977 listen(); 1978 advance_clock(0); 1979 advance_clock(500); 1980 advance_clock(500); 1981 check_events([{ type: 'animationstart', target: div, 1982 animationName: 'always_fifty', elapsedTime: 0, 1983 pseudoElement: '' }, 1984 { type: 'animationend', target: div, 1985 animationName: 'always_fifty', elapsedTime: 1, 1986 pseudoElement: '' }], 1987 "events for animation-name: non_existent, always_fifty"); 1988 done_div(); 1989 1990 /* 1991 * Bug 1038032 - Infinite repetition and delay causes overflow 1992 */ 1993 new_div("animation: always_fifty 10s 1s infinite"); 1994 advance_clock(0); 1995 advance_clock(2000); 1996 is(cs.marginLeft, "50px", 1997 "infinitely repeating animation with positive delay takes effect" 1998 + " (does not overflow)"); 1999 done_div(); 2000 2001 /* 2002 * Bug 1140134 - A property in a CSS animation being overridden by later 2003 * animation causes later properties in that animation to be skipped 2004 */ 2005 new_div("position: relative; animation: lowerpriority 1s linear infinite alternate, overridetop 1s linear infinite alternate"); 2006 advance_clock(0); 2007 advance_clock(500); 2008 is(cs.getPropertyValue("left"), "50px", "left is animating"); 2009 is(cs.getPropertyValue("top"), "0px", "top is not animating"); 2010 done_div(); 2011 2012 new_div("position: relative; animation: lowerpriority 1s linear infinite alternate, overrideleft 1s linear infinite alternate"); 2013 advance_clock(0); 2014 advance_clock(500); 2015 is(cs.getPropertyValue("left"), "0px", "left is not animating"); 2016 is(cs.getPropertyValue("top"), "50px", "top is animating"); 2017 done_div(); 2018 2019 /* 2020 * Bug 962594 - Turn off CSS animations when the element is display:none, or 2021 * is in a display:none subtree. 2022 */ 2023 2024 // Helper function for the two tests below 2025 function testDisplayNoneTurnsOffAnimations(aTestName, aElementToDisplayNone) { 2026 is(cs.getPropertyValue("margin-right"), "0px", 2027 aTestName + "margin-right at 0s"); 2028 advance_clock(1000); 2029 is(cs.getPropertyValue("margin-right"), "10px", 2030 aTestName + "margin-right at 1s"); 2031 aElementToDisplayNone.style.display = "none"; 2032 is(cs.getPropertyValue("margin-right"), "0px", 2033 aTestName + "margin-right after display:none"); 2034 advance_clock(1000); 2035 is(cs.getPropertyValue("margin-right"), "0px", 2036 aTestName + "margin-right 1s after display:none"); 2037 aElementToDisplayNone.style.display = ""; 2038 is(cs.getPropertyValue("margin-right"), "0px", 2039 aTestName + "margin-right after display:block"); 2040 advance_clock(1000); 2041 is(cs.getPropertyValue("margin-right"), "10px", 2042 aTestName + "margin-right 1s after display:block"); 2043 } 2044 2045 // Check that it works if the animated element itself becomes display:none 2046 new_div("animation: anim2 linear 10s"); 2047 testDisplayNoneTurnsOffAnimations("AnimatedElement ", div); 2048 done_div(); 2049 2050 // Check that it works if an ancestor of the animated element becomes display:none 2051 new_div("animation: anim2 linear 10s"); 2052 var ancestor = document.createElement("div"); 2053 div.parentNode.insertBefore(ancestor, div); 2054 ancestor.appendChild(div); 2055 testDisplayNoneTurnsOffAnimations("AncestorElement ", ancestor); 2056 ancestor.parentNode.insertBefore(div, ancestor); 2057 ancestor.remove(); 2058 done_div(); 2059 2060 2061 /* 2062 * Bug 1125455 - Transitions should not run when animations are running. 2063 */ 2064 new_div("transition: opacity 2s linear; opacity: 0.8"); 2065 advance_clock(0); 2066 is(cs.getPropertyValue("opacity"), "0.8", "initial opacity"); 2067 div.style.opacity = "0.2"; 2068 is(cs.getPropertyValue("opacity"), "0.8", "opacity transition at 0s"); 2069 advance_clock(500); 2070 is(cs.getPropertyValue("opacity"), "0.65", "opacity transition at 0.5s"); 2071 div.style.animation = "opacitymid 2s linear"; 2072 is(cs.getPropertyValue("opacity"), "0.2", "opacity animation overriding transition at 0s"); 2073 advance_clock(500); 2074 is(cs.getPropertyValue("opacity"), "0.35", "opacity animation overriding transition at 0.5s"); 2075 done_div(); 2076 2077 2078 /* 2079 * Bug 1320474 - keyframes-name may be a string, allows names that would otherwise be excluded 2080 */ 2081 new_div("position: relative; animation: \"string name 1\" 1s linear"); 2082 advance_clock(0); 2083 is(cs.getPropertyValue("left"), "1px", "animation name as a string"); 2084 div.style.animation = "string\\ name\\ 2 1s linear"; 2085 is(cs.getPropertyValue("left"), "2px", "animation name specified as string, referenced using custom ident"); 2086 div.style.animation = "custom\\ ident\\ 1 1s linear"; 2087 is(cs.getPropertyValue("left"), "3px", "animation name specified as custom-ident"); 2088 div.style.animation = "\"custom ident 2\" 1s linear"; 2089 is(cs.getPropertyValue("left"), "4px", "animation name specified as custom-ident, referenced using string"); 2090 div.style.animation = "unset"; 2091 div.style.animation = "initial 1s linear"; 2092 is(cs.getPropertyValue("left"), "0px", "animation name 'initial' as identifier is ignored"); 2093 div.style.animation = "unset"; 2094 div.style.animation = "\"initial\" 1s linear"; 2095 is(cs.getPropertyValue("left"), "5px", "animation name 'initial' as string is accepted"); 2096 div.style.animation = "unset"; 2097 div.style.animation = "none 1s linear"; 2098 is(cs.getPropertyValue("left"), "0px", "animation name 'none' as identifier is ignored"); 2099 div.style.animation = "unset"; 2100 div.style.animation = "\"none\" 1s linear"; 2101 is(cs.getPropertyValue("left"), "7px", "animation name 'none' as string is accepted"); 2102 done_div(); 2103 2104 </script> 2105 </pre> 2106 </body> 2107 </html>