tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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>