layout/style/test/test_animations.html

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 <!DOCTYPE HTML>
     2 <html>
     3 <!--
     4 https://bugzilla.mozilla.org/show_bug.cgi?id=435442
     5 -->
     6 <!--
     8  ====== PLEASE KEEP THIS IN SYNC WITH test_animations_omta.html =======
    10  test_animations_omta.html mimicks the content of this file but with
    11  extra machinery for testing animation values on the compositor thread.
    13  If you are making changes to this file or to test_animations_omta.html, please
    14  try to keep them consistent where appropriate.
    16 -->
    17 <head>
    18   <title>Test for css3-animations (Bug 435442)</title>
    19   <script type="application/javascript" 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   }
    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: inline; 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   }
    74   @keyframes always_fifty {
    75     from, to { margin-left: 50px }
    76   }
    78   #withbefore::before, #withafter::after {
    79     content: "";
    80     animation: anim2 1s linear alternate 3;
    81   }
    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   }
   101   @keyframes uaoverride {
   102     0%, 100% { line-height: 3; margin-top: 20px }
   103     50% { margin-top: 120px }
   104   }
   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   }
   120   @keyframes primitives1 {
   121     from { -moz-transform: rotate(0deg) translateX(0px) scaleX(1)
   122       translate(0px) scale3d(1, 1, 1); }
   123     to { -moz-transform: rotate(270deg) translate3d(0px, 0px, 0px) scale(1)
   124       translateY(0px) scaleY(1); }
   125   }
   127   @keyframes important1 {
   128     from { margin-top: 50px; }
   129     50%  { margin-top: 150px !important; } /* ignored */
   130     to   { margin-top: 100px; }
   131   }
   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   </style>
   140 </head>
   141 <body>
   142 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=435442">Mozilla Bug 435442</a>
   143 <div id="display"></div>
   144 <pre id="test">
   145 <script type="application/javascript">
   146 "use strict";
   148 /** Test for css3-animations (Bug 435442) **/
   150 var e = new AnimationEvent("foo",
   151                             {
   152                               bubbles: true,
   153                               cancelable: true,
   154                               animationName: "name",
   155                               elapsedTime: 0.5,
   156                               pseudoElement: "pseudo"
   157                             });
   158 is(e.bubbles, true);
   159 is(e.cancelable, true);
   160 is(e.animationName, "name");
   161 is(e.elapsedTime, 0.5);
   162 is(e.pseudoElement, "pseudo");
   163 is(e.isTrusted, false)
   165 function advance_clock(milliseconds) {
   166   SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(milliseconds);
   167 }
   169 var display = document.getElementById("display");
   170 var div = null;
   171 var cs = null;
   172 var events_received = [];
   173 function new_div(style) {
   174   return new_element("div", style);
   175 }
   176 function new_element(tagname, style) {
   177   if (div != null || cs != null) {
   178     ok(false, "test author forgot to call done_div");
   179   }
   180   if (typeof(style) != "string") {
   181     ok(false, "test author forgot to pass argument");
   182   }
   183   div = document.createElement(tagname);
   184   div.setAttribute("style", style);
   185   display.appendChild(div);
   186   cs = getComputedStyle(div, "");
   187 }
   188 function listen() {
   189   events_received = [];
   190   function listener(event) {
   191     events_received.push(event);
   192   }
   193   div.addEventListener("animationstart", listener, false);
   194   div.addEventListener("animationiteration", listener, false);
   195   div.addEventListener("animationend", listener, false);
   196 }
   197 function check_events(events_expected, desc) {
   198   // This function checks that the list of events_expected matches
   199   // the received events -- but it only checks the properties that
   200   // are present on events_expected.
   201   is(events_received.length, events_expected.length,
   202      "number of events received for " + desc);
   203   for (var i = 0,
   204        i_end = Math.min(events_expected.length, events_received.length);
   205        i != i_end; ++i) {
   206     var exp = events_expected[i];
   207     var rec = events_received[i];
   208     for (var prop in exp) {
   209       if (prop == "elapsedTime") {
   210         // Allow floating point error.
   211         ok(Math.abs(rec.elapsedTime - exp.elapsedTime) < 0.000002,
   212            "events[" + i + "]." + prop + " for " + desc +
   213            " received=" + rec.elapsedTime + " expected=" + exp.elapsedTime);
   214       } else {
   215         is(rec[prop], exp[prop], "events[" + i + "]." + prop + " for " + desc);
   216       }
   217     }
   218   }
   219   for (var i = events_expected.length; i < events_received.length; ++i) {
   220     ok(false, "unexpected " + events_received[i].type + " event for " + desc);
   221   }
   222   events_received = [];
   223 }
   224 function done_div() {
   225   display.removeChild(div);
   226   div = null;
   227   cs = null;
   228   if (events_received.length) {
   229     ok(false, "caller should have called check_events");
   230   }
   231 }
   233 // take over the refresh driver right from the start.
   234 advance_clock(0);
   236 /*
   237  * css3-animations:  2. Animations
   238  * http://dev.w3.org/csswg/css3-animations/#animations
   239  */
   241 // Test that animations don't affect the computed value before the
   242 // start of the animation or after its end.  Test without
   243 // animation-fill-mode, but then repeat the test with all the values of
   244 // animation-fill-mode.
   245 function test_fill_mode(fill_mode, fills_backwards, fills_forwards)
   246 {
   247   var style = "margin-left: 30px; animation: 10s 3s anim1 linear";
   248   var desc;
   249   if (fill_mode.length > 0) {
   250     style += " " + fill_mode;
   251     desc = "fill mode " + fill_mode + ": ";
   252   } else {
   253     desc = "default fill mode: ";
   254   }
   255   new_div(style);
   256   listen();
   257   if (fills_backwards)
   258     is(cs.marginLeft, "0px", desc + "does affect value during delay (0s)");
   259   else
   260     is(cs.marginLeft, "30px", desc + "doesn't affect value during delay (0s)");
   261   advance_clock(2000);
   262   if (fills_backwards)
   263     is(cs.marginLeft, "0px", desc + "does affect value during delay (2s)");
   264   else
   265     is(cs.marginLeft, "30px", desc + "doesn't affect value during delay (2s)");
   266   check_events([], "before start in test_fill_mode");
   267   advance_clock(1000);
   268   check_events([{ type: 'animationstart', target: div,
   269                   bubbles: true, cancelable: false,
   270                   animationName: 'anim1', elapsedTime: 0.0,
   271                   pseudoElement: "" }],
   272                "right after start in test_fill_mode");
   273   if (fills_backwards)
   274     is(cs.marginLeft, "0px", desc + "affects value at start of animation");
   275   advance_clock(125);
   276   is(cs.marginLeft, "2px", desc + "affects value during animation");
   277   advance_clock(2375);
   278   is(cs.marginLeft, "40px", desc + "affects value during animation");
   279   advance_clock(2500);
   280   is(cs.marginLeft, "80px", desc + "affects value during animation");
   281   advance_clock(2500);
   282   is(cs.marginLeft, "90px", desc + "affects value during animation");
   283   advance_clock(2375);
   284   is(cs.marginLeft, "99.5px", desc + "affects value during animation");
   285   check_events([], "before end in test_fill_mode");
   286   advance_clock(125);
   287   check_events([{ type: 'animationend', target: div,
   288                   bubbles: true, cancelable: false,
   289                   animationName: 'anim1', elapsedTime: 10.0,
   290                   pseudoElement: "" }],
   291                "right after end in test_fill_mode");
   292   if (fills_forwards)
   293     is(cs.marginLeft, "100px", desc + "affects value at end of animation");
   294   advance_clock(10);
   295   if (fills_forwards)
   296     is(cs.marginLeft, "100px", desc + "does affect value after animation");
   297   else
   298     is(cs.marginLeft, "30px", desc + "does not affect value after animation");
   299   done_div();
   300 }
   301 test_fill_mode("", false, false);
   302 test_fill_mode("none", false, false);
   303 test_fill_mode("forwards", false, true);
   304 test_fill_mode("backwards", true, false);
   305 test_fill_mode("both", true, true);
   307 // Test that animations continue running when the animation name
   308 // list is changed.
   309 new_div("animation: anim1 linear 10s");
   310   is(cs.getPropertyValue("margin-top"), "0px",
   311      "just anim1, margin-top at start");
   312   is(cs.getPropertyValue("margin-right"), "0px",
   313      "just anim1, margin-right at start");
   314   is(cs.getPropertyValue("margin-bottom"), "0px",
   315      "just anim1, margin-bottom at start");
   316   is(cs.getPropertyValue("margin-left"), "0px",
   317      "just anim1, margin-left at start");
   318 advance_clock(1000);
   319   is(cs.getPropertyValue("margin-top"), "0px",
   320      "just anim1, margin-top at 1s");
   321   is(cs.getPropertyValue("margin-right"), "0px",
   322      "just anim1, margin-right at 1s");
   323   is(cs.getPropertyValue("margin-bottom"), "0px",
   324      "just anim1, margin-bottom at 1s");
   325   is(cs.getPropertyValue("margin-left"), "16px",
   326      "just anim1, margin-left at 1s");
   327 // append anim2
   328 div.style.animation = "anim1 linear 10s, anim2 linear 10s";
   329   is(cs.getPropertyValue("margin-top"), "0px",
   330      "anim1 + anim2, margin-top at 1s");
   331   is(cs.getPropertyValue("margin-right"), "0px",
   332      "anim1 + anim2, margin-right at 1s");
   333   is(cs.getPropertyValue("margin-bottom"), "0px",
   334      "anim1 + anim2, margin-bottom at 1s");
   335   is(cs.getPropertyValue("margin-left"), "16px",
   336      "anim1 + anim2, margin-left at 1s");
   337 advance_clock(1000);
   338   is(cs.getPropertyValue("margin-top"), "0px",
   339      "anim1 + anim2, margin-top at 2s");
   340   is(cs.getPropertyValue("margin-right"), "10px",
   341      "anim1 + anim2, margin-right at 2s");
   342   is(cs.getPropertyValue("margin-bottom"), "0px",
   343      "anim1 + anim2, margin-bottom at 2s");
   344   is(cs.getPropertyValue("margin-left"), "32px",
   345      "anim1 + anim2, margin-left at 2s");
   346 // prepend anim3
   347 div.style.animation = "anim3 linear 10s, anim1 linear 10s, anim2 linear 10s";
   348   is(cs.getPropertyValue("margin-top"), "0px",
   349      "anim3 + anim1 + anim2, margin-top at 2s");
   350   is(cs.getPropertyValue("margin-right"), "10px",
   351      "anim3 + anim1 + anim2, margin-right at 2s");
   352   is(cs.getPropertyValue("margin-bottom"), "0px",
   353      "anim3 + anim1 + anim2, margin-bottom at 2s");
   354   is(cs.getPropertyValue("margin-left"), "32px",
   355      "anim3 + anim1 + anim2, margin-left at 2s");
   356 advance_clock(1000);
   357   is(cs.getPropertyValue("margin-top"), "10px",
   358      "anim3 + anim1 + anim2, margin-top at 3s");
   359   is(cs.getPropertyValue("margin-right"), "20px",
   360      "anim3 + anim1 + anim2, margin-right at 3s");
   361   is(cs.getPropertyValue("margin-bottom"), "0px",
   362      "anim3 + anim1 + anim2, margin-bottom at 3s");
   363   is(cs.getPropertyValue("margin-left"), "48px",
   364      "anim3 + anim1 + anim2, margin-left at 3s");
   365 // remove anim2 from end
   366 div.style.animation = "anim3 linear 10s, anim1 linear 10s";
   367   is(cs.getPropertyValue("margin-top"), "10px",
   368      "anim3 + anim1, margin-top at 3s");
   369   is(cs.getPropertyValue("margin-right"), "0px",
   370      "anim3 + anim1, margin-right at 3s");
   371   is(cs.getPropertyValue("margin-bottom"), "0px",
   372      "anim3 + anim1, margin-bottom at 3s");
   373   is(cs.getPropertyValue("margin-left"), "48px",
   374      "anim3 + anim1, margin-left at 3s");
   375 advance_clock(1000);
   376   is(cs.getPropertyValue("margin-top"), "20px",
   377      "anim3 + anim1, margin-top at 4s");
   378   is(cs.getPropertyValue("margin-right"), "0px",
   379      "anim3 + anim1, margin-right at 4s");
   380   is(cs.getPropertyValue("margin-bottom"), "0px",
   381      "anim3 + anim1, margin-bottom at 4s");
   382   is(cs.getPropertyValue("margin-left"), "64px",
   383      "anim3 + anim1, margin-left at 4s");
   384 // swap anim1 and anim3, change duration of anim3
   385 div.style.animation = "anim1 linear 10s, anim3 linear 5s";
   386   is(cs.getPropertyValue("margin-top"), "40px",
   387      "anim1 + anim3, margin-top at 4s");
   388   is(cs.getPropertyValue("margin-right"), "0px",
   389      "anim1 + anim3, margin-right at 4s");
   390   is(cs.getPropertyValue("margin-bottom"), "0px",
   391      "anim1 + anim3, margin-bottom at 4s");
   392   is(cs.getPropertyValue("margin-left"), "64px",
   393      "anim1 + anim3, margin-left at 4s");
   394 advance_clock(1000);
   395   is(cs.getPropertyValue("margin-top"), "60px",
   396      "anim1 + anim3, margin-top at 5s");
   397   is(cs.getPropertyValue("margin-right"), "0px",
   398      "anim1 + anim3, margin-right at 5s");
   399   is(cs.getPropertyValue("margin-bottom"), "0px",
   400      "anim1 + anim3, margin-bottom at 5s");
   401   is(cs.getPropertyValue("margin-left"), "80px",
   402      "anim1 + anim3, margin-left at 5s");
   403 // list anim1 twice, last duration wins, original start time still applies
   404 div.style.animation = "anim1 linear 10s, anim3 linear 5s, anim1 linear 20s";
   405   is(cs.getPropertyValue("margin-top"), "60px",
   406      "anim1 + anim3 + anim1, margin-top at 5s");
   407   is(cs.getPropertyValue("margin-right"), "0px",
   408      "anim1 + anim3 + anim1, margin-right at 5s");
   409   is(cs.getPropertyValue("margin-bottom"), "0px",
   410      "anim1 + anim3 + anim1, margin-bottom at 5s");
   411   is(cs.getPropertyValue("margin-left"), "40px",
   412      "anim1 + anim3 + anim1, margin-left at 5s");
   413 // drop one of the anim1, and list anim5 as well, which animates
   414 // the same property as anim1
   415 div.style.animation = "anim3 linear 5s, anim1 linear 20s, anim5 linear 10s";
   416   is(cs.getPropertyValue("margin-top"), "60px",
   417      "anim3 + anim1 + anim5, margin-top at 5s");
   418   is(cs.getPropertyValue("margin-right"), "0px",
   419      "anim3 + anim1 + anim5, margin-right at 5s");
   420   is(cs.getPropertyValue("margin-bottom"), "0px",
   421      "anim3 + anim1 + anim5, margin-bottom at 5s");
   422   is(cs.getPropertyValue("margin-left"), "0px",
   423      "anim3 + anim1 + anim5, margin-left at 5s");
   424 advance_clock(1000);
   425   is(cs.getPropertyValue("margin-top"), "80px",
   426      "anim3 + anim1 + anim5, margin-top at 6s");
   427   is(cs.getPropertyValue("margin-right"), "0px",
   428      "anim3 + anim1 + anim5, margin-right at 6s");
   429   is(cs.getPropertyValue("margin-bottom"), "0px",
   430      "anim3 + anim1 + anim5, margin-bottom at 6s");
   431   is(cs.getPropertyValue("margin-left"), "10px",
   432      "anim3 + anim1 + anim5, margin-left at 6s");
   433 // now swap the anim5 and anim1 order
   434 div.style.animation = "anim3 linear 5s, anim5 linear 10s, anim1 linear 20s";
   435   is(cs.getPropertyValue("margin-top"), "80px",
   436      "anim3 + anim1 + anim5, margin-top at 6s");
   437   is(cs.getPropertyValue("margin-right"), "0px",
   438      "anim3 + anim1 + anim5, margin-right at 6s");
   439   is(cs.getPropertyValue("margin-bottom"), "0px",
   440      "anim3 + anim1 + anim5, margin-bottom at 6s");
   441   is(cs.getPropertyValue("margin-left"), "48px",
   442      "anim3 + anim1 + anim5, margin-left at 6s");
   443 advance_clock(1000);
   444   is(cs.getPropertyValue("margin-top"), "0px",
   445      "anim3 + anim1 + anim5, margin-top at 7s");
   446   is(cs.getPropertyValue("margin-right"), "0px",
   447      "anim3 + anim1 + anim5, margin-right at 7s");
   448   is(cs.getPropertyValue("margin-bottom"), "0px",
   449      "anim3 + anim1 + anim5, margin-bottom at 7s");
   450   is(cs.getPropertyValue("margin-left"), "56px",
   451      "anim3 + anim1 + anim5, margin-left at 7s");
   452 // swap anim1 and anim5 back
   453 div.style.animation = "anim3 linear 5s, anim1 linear 20s, anim5 linear 10s";
   454   is(cs.getPropertyValue("margin-top"), "0px",
   455      "anim3 + anim1 + anim5, margin-top at 7s");
   456   is(cs.getPropertyValue("margin-right"), "0px",
   457      "anim3 + anim1 + anim5, margin-right at 7s");
   458   is(cs.getPropertyValue("margin-bottom"), "0px",
   459      "anim3 + anim1 + anim5, margin-bottom at 7s");
   460   is(cs.getPropertyValue("margin-left"), "20px",
   461      "anim3 + anim1 + anim5, margin-left at 7s");
   462 advance_clock(100);
   463   is(cs.getPropertyValue("margin-top"), "0px",
   464      "anim3 + anim1 + anim5, margin-top at 7.1s");
   465 // Change the animation fill mode on the completed animation.
   466 div.style.animation = "anim3 linear 5s forwards, anim1 linear 20s, anim5 linear 10s";
   467   is(cs.getPropertyValue("margin-top"), "100px",
   468      "anim3 + anim1 + anim5, margin-top at 7.1s, with fill mode");
   469 advance_clock(900);
   470   is(cs.getPropertyValue("margin-top"), "100px",
   471      "anim3 + anim1 + anim5, margin-top at 8s, with fill mode");
   472 // Change the animation duration on the completed animation, so it is
   473 // no longer completed.
   474 div.style.animation = "anim3 linear 10s, anim1 linear 20s, anim5 linear 10s";
   475   is(cs.getPropertyValue("margin-top"), "60px",
   476      "anim3 + anim1 + anim5, margin-top at 8s, with fill mode");
   477   is(cs.getPropertyValue("margin-left"), "30px",
   478      "anim3 + anim1 + anim5, margin-left at 8s");
   479 done_div();
   481 /*
   482  * css3-animations:  3. Keyframes
   483  * http://dev.w3.org/csswg/css3-animations/#keyframes
   484  *
   485  * Also see test_keyframes_rules.html .
   486  */
   488 // Test the rules on keyframes that lack a 0% or 100% rule:
   489 // (simultaneously, test that reverse animations have their keyframes
   490 // run backwards)
   492 // 100px at 0%, 50px at 50%, 150px at 100%
   493 new_div("margin-top: 100px; animation: kf1 ease 1s alternate infinite");
   494 is(cs.marginTop, "100px", "no-0% at 0.0s");
   495 advance_clock(100);
   496 is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease(0.2), 0.01,
   497           "no-0% at 0.1s");
   498 advance_clock(200);
   499 is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease(0.6), 0.01,
   500           "no-0% at 0.3s");
   501 advance_clock(200);
   502 is(cs.marginTop, "50px", "no-0% at 0.5s");
   503 advance_clock(200);
   504 is_approx(px_to_num(cs.marginTop), 50 + 100 * gTF.ease(0.4), 0.01,
   505           "no-0% at 0.7s");
   506 advance_clock(200);
   507 is_approx(px_to_num(cs.marginTop), 50 + 100 * gTF.ease(0.8), 0.01,
   508           "no-0% at 0.9s");
   509 advance_clock(100);
   510 is(cs.marginTop, "150px", "no-0% at 1.0s");
   511 advance_clock(100);
   512 is_approx(px_to_num(cs.marginTop), 50 + 100 * gTF.ease(0.8), 0.01,
   513           "no-0% at 1.1s");
   514 advance_clock(300);
   515 is_approx(px_to_num(cs.marginTop), 50 + 100 * gTF.ease(0.2), 0.01,
   516           "no-0% at 1.4s");
   517 advance_clock(300);
   518 is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease(0.6), 0.01,
   519           "no-0% at 1.7s");
   520 advance_clock(200);
   521 is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease(0.2), 0.01,
   522           "no-0% at 1.9s");
   523 advance_clock(100);
   524 is(cs.marginTop, "100px", "no-0% at 2.0s");
   525 done_div();
   527 // 150px at 0%, 50px at 50%, 100px at 100%
   528 new_div("margin-top: 100px; animation: kf2 ease-in 1s alternate infinite");
   529 is(cs.marginTop, "150px", "no-100% at 0.0s");
   530 advance_clock(100);
   531 is_approx(px_to_num(cs.marginTop), 150 - 100 * gTF.ease_in(0.2), 0.01,
   532           "no-100% at 0.1s");
   533 advance_clock(200);
   534 is_approx(px_to_num(cs.marginTop), 150 - 100 * gTF.ease_in(0.6), 0.01,
   535           "no-100% at 0.3s");
   536 advance_clock(200);
   537 is(cs.marginTop, "50px", "no-100% at 0.5s");
   538 advance_clock(200);
   539 is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_in(0.4), 0.01,
   540           "no-100% at 0.7s");
   541 advance_clock(200);
   542 is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_in(0.8), 0.01,
   543           "no-100% at 0.9s");
   544 advance_clock(100);
   545 is(cs.marginTop, "100px", "no-100% at 1.0s");
   546 advance_clock(100);
   547 is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_in(0.8), 0.01,
   548           "no-100% at 1.1s");
   549 advance_clock(300);
   550 is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_in(0.2), 0.01,
   551           "no-100% at 1.4s");
   552 advance_clock(300);
   553 is_approx(px_to_num(cs.marginTop), 150 - 100 * gTF.ease_in(0.6), 0.01,
   554           "no-100% at 1.7s");
   555 advance_clock(200);
   556 is_approx(px_to_num(cs.marginTop), 150 - 100 * gTF.ease_in(0.2), 0.01,
   557           "no-100% at 1.9s");
   558 advance_clock(100);
   559 is(cs.marginTop, "150px", "no-100% at 2.0s");
   560 done_div();
   563 // 50px at 0%, 100px at 25%, 50px at 100%
   564 new_div("margin-top: 50px; animation: kf3 ease-out 1s alternate infinite");
   565 is(cs.marginTop, "50px", "no-0%-no-100% at 0.0s");
   566 advance_clock(50);
   567 is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_out(0.2), 0.01,
   568           "no-0%-no-100% at 0.05s");
   569 advance_clock(100);
   570 is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_out(0.6), 0.01,
   571           "no-0%-no-100% at 0.15s");
   572 advance_clock(100);
   573 is(cs.marginTop, "100px", "no-0%-no-100% at 0.25s");
   574 advance_clock(300);
   575 is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease_out(0.4), 0.01,
   576           "no-0%-no-100% at 0.55s");
   577 advance_clock(300);
   578 is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease_out(0.8), 0.01,
   579           "no-0%-no-100% at 0.85s");
   580 advance_clock(150);
   581 is(cs.marginTop, "50px", "no-0%-no-100% at 1.0s");
   582 advance_clock(150);
   583 is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease_out(0.8), 0.01,
   584           "no-0%-no-100% at 1.15s");
   585 advance_clock(450);
   586 is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease_out(0.2), 0.01,
   587           "no-0%-no-100% at 1.6s");
   588 advance_clock(250);
   589 is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_out(0.6), 0.01,
   590           "no-0%-no-100% at 1.85s");
   591 advance_clock(100);
   592 is_approx(px_to_num(cs.marginTop), 50 + 50 * gTF.ease_out(0.2), 0.01,
   593           "no-0%-no-100% at 1.95s");
   594 advance_clock(50);
   595 is(cs.marginTop, "50px", "no-0%-no-100% at 2.0s");
   596 done_div();
   598 // Test that non-animatable properties are ignored.
   599 // Simultaneously, test that the block is still honored, and that
   600 // we still override the value when two consecutive keyframes have
   601 // the same value.
   602 new_div("animation: kf4 ease 10s");
   603 is(cs.display, "block",
   604    "non-animatable properties should be ignored (linear, 0s)");
   605 is(cs.marginTop, "37px",
   606    "animatable properties should still apply (linear, 0s)");
   607 advance_clock(1000);
   608 is(cs.display, "block",
   609    "non-animatable properties should be ignored (linear, 1s)");
   610 is(cs.marginTop, "37px",
   611    "animatable properties should still apply (linear, 1s)");
   612 done_div();
   613 new_div("animation: kf4 step-start 10s");
   614 is(cs.display, "block",
   615    "non-animatable properties should be ignored (step-start, 0s)");
   616 is(cs.marginTop, "37px",
   617    "animatable properties should still apply (step-start, 0s)");
   618 advance_clock(1000);
   619 is(cs.display, "block",
   620    "non-animatable properties should be ignored (step-start, 1s)");
   621 is(cs.marginTop, "37px",
   622    "animatable properties should still apply (step-start, 1s)");
   623 done_div();
   625 // Test cascading of the keyframes within an @keyframes rule.
   626 new_div("animation: kf_cascade1 linear 10s");
   627 //   0%: 30px
   628 //  50%: 20px
   629 //  75%: 20px
   630 //  85%: 30px
   631 //  85.1%: 60px
   632 // 100%: 70px
   633 is(cs.paddingTop, "30px", "kf_cascade1 at 0s");
   634 advance_clock(2500);
   635 is(cs.paddingTop, "25px", "kf_cascade1 at 2.5s");
   636 advance_clock(2500);
   637 is(cs.paddingTop, "20px", "kf_cascade1 at 5s");
   638 advance_clock(2000);
   639 is(cs.paddingTop, "20px", "kf_cascade1 at 7s");
   640 advance_clock(500);
   641 is(cs.paddingTop, "20px", "kf_cascade1 at 7.5s");
   642 advance_clock(500);
   643 is(cs.paddingTop, "25px", "kf_cascade1 at 8s");
   644 advance_clock(500);
   645 is(cs.paddingTop, "30px", "kf_cascade1 at 8.5s");
   646 advance_clock(10);
   647 is(cs.paddingTop, "60px", "kf_cascade1 at 8.51s");
   648 advance_clock(745);
   649 is(cs.paddingTop, "65px", "kf_cascade1 at 9.2505s");
   650 done_div();
   652 // Test cascading of the @keyframes rules themselves.
   653 new_div("animation: kf_cascade2 linear 10s");
   654 is(cs.marginTop, "0px", "@keyframes rule with margin-top should be ignored");
   655 is(cs.marginLeft, "300px", "last @keyframes rule with margin-left should win");
   656 done_div();
   658 /*
   659  * css3-animations:  3.1. Timing functions for keyframes
   660  * http://dev.w3.org/csswg/css3-animations/#timing-functions-for-keyframes-
   661  */
   662 new_div("animation: kf_tf1 ease-in 10s alternate infinite");
   663 is(cs.paddingBottom, "20px",
   664    "keyframe timing functions test at 0s (test needed for flush)");
   665 advance_clock(1000);
   666 is_approx(px_to_num(cs.paddingBottom), 20 + 40 * gTF.ease(0.4), 0.01,
   667           "keyframe timing functions test at 1s");
   668 advance_clock(1000);
   669 is_approx(px_to_num(cs.paddingBottom), 20 + 40 * gTF.ease(0.8), 0.01,
   670           "keyframe timing functions test at 2s");
   671 advance_clock(1000);
   672 is_approx(px_to_num(cs.paddingBottom), 60 + 100 * gTF.ease_in(0.2), 0.01,
   673           "keyframe timing functions test at 3s");
   674 advance_clock(1000);
   675 is_approx(px_to_num(cs.paddingBottom), 60 + 100 * gTF.ease_in(0.6), 0.01,
   676           "keyframe timing functions test at 4s");
   677 advance_clock(1000);
   678 is(cs.paddingBottom, "160px",
   679    "keyframe timing functions test at 5s");
   680 advance_clock(1010); // avoid floating point error
   681 is_approx(px_to_num(cs.paddingBottom), 160 - 40 * step_end(5)(0.4), 0.01,
   682           "keyframe timing functions test at 6s");
   683 advance_clock(1000);
   684 is_approx(px_to_num(cs.paddingBottom), 160 - 40 * step_end(5)(0.8), 0.01,
   685           "keyframe timing functions test at 7s");
   686 advance_clock(990);
   687 is_approx(px_to_num(cs.paddingBottom), 120 - 100 * gTF.linear(0.2), 0.01,
   688           "keyframe timing functions test at 8s");
   689 advance_clock(1000);
   690 is_approx(px_to_num(cs.paddingBottom), 120 - 100 * gTF.linear(0.6), 0.01,
   691           "keyframe timing functions test at 9s");
   692 advance_clock(1000);
   693 is(cs.paddingBottom, "20px",
   694    "keyframe timing functions test at 10s");
   695 advance_clock(20000);
   696 is(cs.paddingBottom, "20px",
   697    "keyframe timing functions test at 30s");
   698 advance_clock(1000);
   699 is_approx(px_to_num(cs.paddingBottom), 120 - 100 * gTF.linear(0.6), 0.01,
   700           "keyframe timing functions test at 31s");
   701 advance_clock(1000);
   702 is_approx(px_to_num(cs.paddingBottom), 120 - 100 * gTF.linear(0.2), 0.01,
   703           "keyframe timing functions test at 32s");
   704 advance_clock(1000);
   705 is_approx(px_to_num(cs.paddingBottom), 160 - 40 * step_end(5)(0.8), 0.01,
   706           "keyframe timing functions test at 33s");
   707 advance_clock(1000);
   708 is_approx(px_to_num(cs.paddingBottom), 160 - 40 * step_end(5)(0.4), 0.01,
   709           "keyframe timing functions test at 34s");
   710 advance_clock(1000);
   711 is(cs.paddingBottom, "160px",
   712    "keyframe timing functions test at 35s");
   713 advance_clock(1000);
   714 is_approx(px_to_num(cs.paddingBottom), 60 + 100 * gTF.ease_in(0.6), 0.01,
   715           "keyframe timing functions test at 36s");
   716 advance_clock(1000);
   717 is_approx(px_to_num(cs.paddingBottom), 60 + 100 * gTF.ease_in(0.2), 0.01,
   718           "keyframe timing functions test at 37s");
   719 advance_clock(1000);
   720 is_approx(px_to_num(cs.paddingBottom), 20 + 40 * gTF.ease(0.8), 0.01,
   721           "keyframe timing functions test at 38s");
   722 advance_clock(1000);
   723 is_approx(px_to_num(cs.paddingBottom), 20 + 40 * gTF.ease(0.4), 0.01,
   724           "keyframe timing functions test at 39s");
   725 advance_clock(1000);
   726 is(cs.paddingBottom, "20px",
   727    "keyframe timing functions test at 40s");
   728 done_div();
   730 // spot-check the same thing without alternate
   731 new_div("animation: kf_tf1 ease-in 10s infinite");
   732 is(cs.paddingBottom, "20px",
   733    "keyframe timing functions test at 0s (test needed for flush)");
   734 advance_clock(11000);
   735 is_approx(px_to_num(cs.paddingBottom), 20 + 40 * gTF.ease(0.4), 0.01,
   736           "keyframe timing functions test at 11s");
   737 advance_clock(3000);
   738 is_approx(px_to_num(cs.paddingBottom), 60 + 100 * gTF.ease_in(0.6), 0.01,
   739           "keyframe timing functions test at 14s");
   740 advance_clock(2000);
   741 is_approx(px_to_num(cs.paddingBottom), 160 - 40 * step_end(5)(0.4), 0.01,
   742           "keyframe timing functions test at 16s");
   743 advance_clock(2000);
   744 is_approx(px_to_num(cs.paddingBottom), 120 - 100 * gTF.linear(0.2), 0.01,
   745           "keyframe timing functions test at 18s");
   746 done_div();
   748 /*
   749  * css3-animations:  3.2. The 'animation-name' Property
   750  * http://dev.w3.org/csswg/css3-animations/#the-animation-name-property-
   751  */
   753 // animation-name is reasonably well-tested up in the tests for Section
   754 // 2, particularly the tests that "Test that animations continue running
   755 // when the animation name list is changed."
   757 // Test that 'animation-name: none' steps the animation, and setting
   758 // it again starts a new one.
   760 new_div("");
   761 div.style.animation = "anim2 ease-in-out 10s";
   762 is(cs.marginRight, "0px", "after setting animation-name to anim2");
   763 advance_clock(1000);
   764 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in_out(0.1), 0.01,
   765           "before changing animation-name to none");
   766 div.style.animationName = "none";
   767 is(cs.marginRight, "0px", "after changing animation-name to none");
   768 advance_clock(1000);
   769 is(cs.marginRight, "0px", "after changing animation-name to none plus 1s");
   770 div.style.animationName = "anim2";
   771 is(cs.marginRight, "0px", "after changing animation-name to anim2");
   772 advance_clock(1000);
   773 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in_out(0.1), 0.01,
   774           "at 1s in animation when animation-name no longer none again");
   775 div.style.animationName = "none";
   776 is(cs.marginRight, "0px", "after changing animation-name to none");
   777 advance_clock(1000);
   778 is(cs.marginRight, "0px", "after changing animation-name to none plus 1s");
   779 done_div();
   781 /*
   782  * css3-animations:  3.3. The 'animation-duration' Property
   783  * http://dev.w3.org/csswg/css3-animations/#the-animation-duration-property-
   784  */
   786 // FIXME: test animation-duration of 0 (quite a bit, including interaction
   787 // with fill-mode, count, and reversing), once I know what the right
   788 // behavior is.
   790 /*
   791  * css3-animations:  3.4. The 'animation-timing-function' Property
   792  * http://dev.w3.org/csswg/css3-animations/#animation-timing-function_tag
   793  */
   795 // tested in tests for section 3.1
   797 /*
   798  * css3-animations:  3.5. The 'animation-iteration-count' Property
   799  * http://dev.w3.org/csswg/css3-animations/#the-animation-iteration-count-property-
   800  */
   801 new_div("animation: anim2 ease-in 10s 0.3 forwards");
   802 is(cs.marginRight, "0px", "animation-iteration-count test 1 at 0s");
   803 advance_clock(2000);
   804 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01,
   805           "animation-iteration-count test 1 at 2s");
   806 advance_clock(900);
   807 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.29), 0.01,
   808           "animation-iteration-count test 1 at 2.9s");
   809 advance_clock(100);
   810 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.3), 0.01,
   811           "animation-iteration-count test 1 at 3s");
   812 advance_clock(100);
   813 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.3), 0.01,
   814           "animation-iteration-count test 1 at 3.1s");
   815 advance_clock(5000);
   816 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.3), 0.01,
   817           "animation-iteration-count test 1 at 8.1s");
   818 done_div();
   820 new_div("animation: anim2 ease-in 10s 0.3, anim3 ease-out 20s 1.2 alternate forwards, anim4 ease-in-out 5s 1.6 forwards");
   821 is(cs.marginRight, "0px", "animation-iteration-count test 2 at 0s");
   822 is(cs.marginTop, "0px", "animation-iteration-count test 3 at 0s");
   823 is(cs.marginBottom, "0px", "animation-iteration-count test 4 at 0s");
   824 advance_clock(2000);
   825 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01,
   826           "animation-iteration-count test 2 at 2s");
   827 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_out(0.1), 0.01,
   828           "animation-iteration-count test 3 at 2s");
   829 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.4), 0.01,
   830           "animation-iteration-count test 4 at 2s");
   831 advance_clock(900);
   832 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.29), 0.01,
   833           "animation-iteration-count test 2 at 2.9s");
   834 advance_clock(200);
   835 is(cs.marginRight, "0px", "animation-iteration-count test 2 at 3.1s");
   836 advance_clock(1800);
   837 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.98), 0.01,
   838           "animation-iteration-count test 4 at 4.9s");
   839 advance_clock(200);
   840 is(cs.marginRight, "0px", "animation-iteration-count test 2 at 5.1s");
   841 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.02), 0.01,
   842           "animation-iteration-count test 4 at 5.1s");
   843 advance_clock(2800);
   844 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.58), 0.01,
   845           "animation-iteration-count test 4 at 7.9s");
   846 advance_clock(100);
   847 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.6), 0.01,
   848           "animation-iteration-count test 4 at 8s");
   849 advance_clock(100);
   850 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.6), 0.01,
   851           "animation-iteration-count test 4 at 8.1s");
   852 advance_clock(11700);
   853 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_out(0.99), 0.01,
   854           "animation-iteration-count test 3 at 19.8s");
   855 advance_clock(200);
   856 is(cs.marginTop, "100px", "animation-iteration-count test 3 at 20s");
   857 advance_clock(200);
   858 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_out(0.99), 0.01,
   859           "animation-iteration-count test 3 at 20.2s");
   860 advance_clock(3600);
   861 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_out(0.81), 0.01,
   862           "animation-iteration-count test 3 at 23.8s");
   863 advance_clock(200);
   864 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_out(0.8), 0.01,
   865           "animation-iteration-count test 3 at 24s");
   866 advance_clock(200);
   867 is(cs.marginRight, "0px", "animation-iteration-count test 2 at 25s");
   868 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_out(0.8), 0.01,
   869           "animation-iteration-count test 3 at 25s");
   870 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.6), 0.01,
   871           "animation-iteration-count test 4 at 25s");
   872 done_div();
   874 /*
   875  * css3-animations:  3.6. The 'animation-direction' Property
   876  * http://dev.w3.org/csswg/css3-animations/#the-animation-direction-property-
   877  */
   879 // Tested in tests for sections 3.1 and 3.5.
   881 new_div("animation: anim2 ease-in 10s infinite");
   882 div.style.animationDirection = "normal";
   883 is(cs.marginRight, "0px", "animation-direction test 1 (normal) at 0s");
   884 div.style.animationDirection = "reverse";
   885 is(cs.marginRight, "100px", "animation-direction test 1 (reverse) at 0s");
   886 div.style.animationDirection = "alternate";
   887 is(cs.marginRight, "0px", "animation-direction test 1 (alternate) at 0s");
   888 div.style.animationDirection = "alternate-reverse";
   889 is(cs.marginRight, "100px", "animation-direction test 1 (alternate-reverse) at 0s");
   890 advance_clock(2000);
   891 div.style.animationDirection = "normal";
   892 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01,
   893           "animation-direction test 1 (normal) at 2s");
   894 div.style.animationDirection = "reverse";
   895 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.8), 0.01,
   896           "animation-direction test 1 (reverse) at 2s");
   897 div.style.animationDirection = "alternate";
   898 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01,
   899           "animation-direction test 1 (alternate) at 2s");
   900 div.style.animationDirection = "alternate-reverse";
   901 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.8), 0.01,
   902           "animation-direction test 1 (alternate-reverse) at 2s");
   903 advance_clock(5000);
   904 div.style.animationDirection = "normal";
   905 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.7), 0.01,
   906           "animation-direction test 1 (normal) at 7s");
   907 div.style.animationDirection = "reverse";
   908 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.3), 0.01,
   909           "animation-direction test 1 (reverse) at 7s");
   910 div.style.animationDirection = "alternate";
   911 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.7), 0.01,
   912           "animation-direction test 1 (alternate) at 7s");
   913 div.style.animationDirection = "alternate-reverse";
   914 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.3), 0.01,
   915           "animation-direction test 1 (alternate-reverse) at 7s");
   916 advance_clock(5000);
   917 div.style.animationDirection = "normal";
   918 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01,
   919           "animation-direction test 1 (normal) at 12s");
   920 div.style.animationDirection = "reverse";
   921 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.8), 0.01,
   922           "animation-direction test 1 (reverse) at 12s");
   923 div.style.animationDirection = "alternate";
   924 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.8), 0.01,
   925           "animation-direction test 1 (alternate) at 12s");
   926 div.style.animationDirection = "alternate-reverse";
   927 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01,
   928           "animation-direction test 1 (alternate-reverse) at 12s");
   929 advance_clock(10000);
   930 div.style.animationDirection = "normal";
   931 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01,
   932           "animation-direction test 1 (normal) at 22s");
   933 div.style.animationDirection = "reverse";
   934 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.8), 0.01,
   935           "animation-direction test 1 (reverse) at 22s");
   936 div.style.animationDirection = "alternate";
   937 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01,
   938           "animation-direction test 1 (alternate) at 22s");
   939 div.style.animationDirection = "alternate-reverse";
   940 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.8), 0.01,
   941           "animation-direction test 1 (alternate-reverse) at 22s");
   942 advance_clock(30000);
   943 div.style.animationDirection = "normal";
   944 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01,
   945           "animation-direction test 1 (normal) at 52s");
   946 div.style.animationDirection = "reverse";
   947 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.8), 0.01,
   948           "animation-direction test 1 (reverse) at 52s");
   949 div.style.animationDirection = "alternate";
   950 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.8), 0.01,
   951           "animation-direction test 1 (alternate) at 52s");
   952 div.style.animationDirection = "alternate-reverse";
   953 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.2), 0.01,
   954           "animation-direction test 1 (alternate-reverse) at 52s");
   955 done_div();
   957 /*
   958  * css3-animations:  3.7. The 'animation-play-state' Property
   959  * http://dev.w3.org/csswg/css3-animations/#the-animation-play-state-property-
   960  */
   962 // simple test with just one animation
   963 new_div("");
   964 div.style.animationTimingFunction = "ease";
   965 div.style.animationName = "anim1";
   966 div.style.animationDuration = "1s";
   967 div.style.animationDirection = "alternate";
   968 div.style.animationIterationCount = "2";
   969 is(cs.marginLeft, "0px", "animation-play-state test 1, at 0s");
   970 advance_clock(250);
   971 is_approx(px_to_num(cs.marginLeft), 80 * gTF.ease(0.5), 0.01,
   972           "animation-play-state test 1 at 250ms");
   973 div.style.animationPlayState = "paused";
   974 is_approx(px_to_num(cs.marginLeft), 80 * gTF.ease(0.5), 0.01,
   975           "animation-play-state test 1 at 250ms");
   976 advance_clock(250);
   977 is_approx(px_to_num(cs.marginLeft), 80 * gTF.ease(0.5), 0.01,
   978           "animation-play-state test 1 still at 500ms");
   979 div.style.animationPlayState = "running";
   980 is_approx(px_to_num(cs.marginLeft), 80 * gTF.ease(0.5), 0.01,
   981           "animation-play-state test 1 still at 500ms");
   982 advance_clock(500);
   983 is_approx(px_to_num(cs.marginLeft), 80 + 20 * gTF.ease(0.5), 0.01,
   984           "animation-play-state test 1 at 1000ms");
   985 advance_clock(250);
   986 is(cs.marginLeft, "100px", "animation-play-state test 1 at 1250ms");
   987 advance_clock(250);
   988 is_approx(px_to_num(cs.marginLeft), 80 + 20 * gTF.ease(0.5), 0.01,
   989           "animation-play-state test 1 at 1500ms");
   990 div.style.animationPlayState = "paused";
   991 is_approx(px_to_num(cs.marginLeft), 80 + 20 * gTF.ease(0.5), 0.01,
   992           "animation-play-state test 1 at 1500ms");
   993 advance_clock(2000);
   994 is_approx(px_to_num(cs.marginLeft), 80 + 20 * gTF.ease(0.5), 0.01,
   995           "animation-play-state test 1 at 3500ms");
   996 advance_clock(500);
   997 is_approx(px_to_num(cs.marginLeft), 80 + 20 * gTF.ease(0.5), 0.01,
   998           "animation-play-state test 1 at 4000ms");
   999 div.style.animationPlayState = "";
  1000 is_approx(px_to_num(cs.marginLeft), 80 + 20 * gTF.ease(0.5), 0.01,
  1001           "animation-play-state test 1 at 4000ms");
  1002 advance_clock(500);
  1003 is_approx(px_to_num(cs.marginLeft), 80 * gTF.ease(0.5), 0.01,
  1004           "animation-play-state test 1 at 4500ms");
  1005 advance_clock(250);
  1006 is(cs.marginLeft, "0px", "animation-play-state test 1, at 4750ms");
  1007 advance_clock(250);
  1008 is(cs.marginLeft, "0px", "animation-play-state test 1, at 5000ms");
  1009 done_div();
  1011 // more complicated test with multiple animations (and different directions
  1012 // and iteration counts)
  1013 new_div("");
  1014 div.style.animationTimingFunction = "ease-out, ease-in, ease-in-out";
  1015 div.style.animationName = "anim2, anim3, anim4";
  1016 div.style.animationDuration = "1s, 2s, 1s";
  1017 div.style.animationDirection = "alternate, normal, normal";
  1018 div.style.animationIterationCount = "4, 2, infinite";
  1019 is(cs.marginRight, "0px", "animation-play-state test 2, at 0s");
  1020 is(cs.marginTop, "0px", "animation-play-state test 3, at 0s");
  1021 is(cs.marginBottom, "0px", "animation-play-state test 4, at 0s");
  1022 advance_clock(250);
  1023 div.style.animationPlayState = "paused, running"; // pause 1 and 3
  1024 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.25), 0.01,
  1025           "animation-play-state test 2 at 250ms");
  1026 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.125), 0.01,
  1027           "animation-play-state test 3 at 250ms");
  1028 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.25), 0.01,
  1029           "animation-play-state test 4 at 250ms");
  1030 advance_clock(250);
  1031 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.25), 0.01,
  1032           "animation-play-state test 2 at 500ms");
  1033 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.25), 0.01,
  1034           "animation-play-state test 3 at 500ms");
  1035 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.25), 0.01,
  1036           "animation-play-state test 4 at 500ms");
  1037 div.style.animationPlayState = "paused, running, running"; // unpause 3
  1038 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.25), 0.01,
  1039           "animation-play-state test 2 at 500ms");
  1040 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.25), 0.01,
  1041           "animation-play-state test 3 at 500ms");
  1042 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.25), 0.01,
  1043           "animation-play-state test 4 at 500ms");
  1044 advance_clock(250);
  1045 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.25), 0.01,
  1046           "animation-play-state test 2 at 750ms");
  1047 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.375), 0.01,
  1048           "animation-play-state test 3 at 750ms");
  1049 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.5), 0.01,
  1050           "animation-play-state test 4 at 750ms");
  1051 div.style.animationPlayState = "running, paused"; // unpause 1, pause 2
  1052 advance_clock(0); // notify refresh observers
  1053 advance_clock(250);
  1054 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.5), 0.01,
  1055           "animation-play-state test 2 at 1000ms");
  1056 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.375), 0.01,
  1057           "animation-play-state test 3 at 1000ms");
  1058 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.75), 0.01,
  1059           "animation-play-state test 4 at 1000ms");
  1060 div.style.animationPlayState = "paused"; // pause all
  1061 advance_clock(0); // notify refresh observers
  1062 advance_clock(3000);
  1063 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.5), 0.01,
  1064           "animation-play-state test 2 at 4000ms");
  1065 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.375), 0.01,
  1066           "animation-play-state test 3 at 4000ms");
  1067 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.75), 0.01,
  1068           "animation-play-state test 4 at 4000ms");
  1069 div.style.animationPlayState = "running, paused"; // pause 2
  1070 advance_clock(0); // notify refresh observers
  1071 advance_clock(850);
  1072 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.65), 0.01,
  1073           "animation-play-state test 2 at 4850ms");
  1074 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.375), 0.01,
  1075           "animation-play-state test 3 at 4850ms");
  1076 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.6), 0.01,
  1077           "animation-play-state test 4 at 4850ms");
  1078 advance_clock(300);
  1079 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.35), 0.01,
  1080           "animation-play-state test 2 at 5150ms");
  1081 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.375), 0.01,
  1082           "animation-play-state test 3 at 5150ms");
  1083 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.9), 0.01,
  1084           "animation-play-state test 4 at 5150ms");
  1085 advance_clock(2300);
  1086 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.05), 0.01,
  1087           "animation-play-state test 2 at 7450ms");
  1088 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.375), 0.01,
  1089           "animation-play-state test 3 at 7450ms");
  1090 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.2), 0.01,
  1091           "animation-play-state test 4 at 7450ms");
  1092 advance_clock(100);
  1093 is(cs.marginRight, "0px", "animation-play-state test 2 at 7550ms");
  1094 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.375), 0.01,
  1095           "animation-play-state test 3 at 7550ms");
  1096 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.3), 0.01,
  1097           "animation-play-state test 4 at 7550ms");
  1098 div.style.animationPlayState = "running"; // unpause 2
  1099 advance_clock(0); // notify refresh observers
  1100 advance_clock(1000);
  1101 is(cs.marginRight, "0px", "animation-play-state test 2 at 7550ms");
  1102 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.875), 0.01,
  1103           "animation-play-state test 3 at 7550ms");
  1104 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.3), 0.01,
  1105           "animation-play-state test 4 at 7550ms");
  1106 advance_clock(500);
  1107 is(cs.marginRight, "0px", "animation-play-state test 2 at 8050ms");
  1108 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.125), 0.01,
  1109           "animation-play-state test 3 at 8050ms");
  1110 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.8), 0.01,
  1111           "animation-play-state test 4 at 8050ms");
  1112 advance_clock(1000);
  1113 is(cs.marginRight, "0px", "animation-play-state test 2 at 9050ms");
  1114 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.625), 0.01,
  1115           "animation-play-state test 3 at 9050ms");
  1116 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.8), 0.01,
  1117           "animation-play-state test 4 at 9050ms");
  1118 advance_clock(500);
  1119 is(cs.marginRight, "0px", "animation-play-state test 2 at 9550ms");
  1120 is_approx(px_to_num(cs.marginTop), 100 * gTF.ease_in(0.875), 0.01,
  1121           "animation-play-state test 3 at 9550ms");
  1122 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.3), 0.01,
  1123           "animation-play-state test 4 at 9550ms");
  1124 advance_clock(500);
  1125 is(cs.marginRight, "0px", "animation-play-state test 2 at 10050ms");
  1126 is(cs.marginTop, "0px", "animation-play-state test 3 at 10050ms");
  1127 is_approx(px_to_num(cs.marginBottom), 100 * gTF.ease_in_out(0.8), 0.01,
  1128           "animation-play-state test 4 at 10050ms");
  1129 done_div();
  1131 /*
  1132  * css3-animations:  3.8. The 'animation-delay' Property
  1133  * http://dev.w3.org/csswg/css3-animations/#the-animation-delay-property-
  1134  */
  1136 // test positive delay
  1137 new_div("animation: anim2 1s 0.5s ease-out");
  1138 is(cs.marginRight, "0px", "positive delay test at 0ms");
  1139 advance_clock(400);
  1140 is(cs.marginRight, "0px", "positive delay test at 400ms");
  1141 advance_clock(100);
  1142 is(cs.marginRight, "0px", "positive delay test at 500ms");
  1143 advance_clock(100);
  1144 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.1), 0.01,
  1145           "positive delay test at 500ms");
  1146 done_div();
  1148 // test dynamic changes to delay (i.e., that we preserve the start time
  1149 // that's before the delay)
  1150 new_div("animation: anim2 1s 0.5s ease-out both");
  1151 is(cs.marginRight, "0px", "dynamic delay delay test at 0ms");
  1152 advance_clock(400);
  1153 is(cs.marginRight, "0px", "dynamic delay delay test at 400ms (1)");
  1154 div.style.animationDelay = "0.2s";
  1155 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.2), 0.01,
  1156           "dynamic delay delay test at 400ms (2)");
  1157 div.style.animationDelay = "0.6s";
  1158 advance_clock(0);
  1159 advance_clock(200);
  1160 is(cs.marginRight, "0px", "dynamic delay delay test at 600ms");
  1161 advance_clock(200);
  1162 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.2), 0.01,
  1163           "dynamic delay delay test at 800ms");
  1164 advance_clock(1000);
  1165 is(cs.marginRight, "100px", "dynamic delay delay test at 1800ms (1)");
  1166 div.style.animationDelay = "1.5s";
  1167 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.3), 0.01,
  1168           "dynamic delay delay test at 1800ms (2)");
  1169 div.style.animationDelay = "2s";
  1170 is(cs.marginRight, "0px", "dynamic delay delay test at 1800ms (3)");
  1171 done_div();
  1173 // test delay and play-state interaction
  1174 new_div("animation: anim2 1s 0.5s ease-out");
  1175 is(cs.marginRight, "0px", "delay and play-state delay test at 0ms");
  1176 advance_clock(400);
  1177 is(cs.marginRight, "0px", "delay and play-state delay test at 400ms");
  1178 div.style.animationPlayState = "paused";
  1179 advance_clock(0);
  1180 advance_clock(100);
  1181 is(cs.marginRight, "0px", "delay and play-state delay test at 500ms");
  1182 advance_clock(500);
  1183 is(cs.marginRight, "0px", "delay and play-state delay test at 1000ms");
  1184 div.style.animationPlayState = "running";
  1185 advance_clock(0);
  1186 advance_clock(100);
  1187 is(cs.marginRight, "0px", "delay and play-state delay test at 1100ms");
  1188 advance_clock(100);
  1189 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.1), 0.01,
  1190           "delay and play-state delay test at 1200ms");
  1191 div.style.animationPlayState = "paused";
  1192 advance_clock(0);
  1193 advance_clock(100);
  1194 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_out(0.1), 0.01,
  1195           "delay and play-state delay test at 1300ms");
  1196 done_div();
  1198 // test negative delay and implicit starting values
  1199 new_div("margin-top: 1000px");
  1200 advance_clock(300);
  1201 div.style.marginTop = "100px";
  1202 div.style.animation = "kf1 1s -0.1s ease-in";
  1203 is_approx(px_to_num(cs.marginTop), 100 - 50 * gTF.ease_in(0.2), 0.01,
  1204           "delay and implicit starting values test");
  1205 done_div();
  1207 // test large negative delay that causes the animation to start
  1208 // in the fourth iteration
  1209 new_div("animation: anim2 1s -3.6s ease-in 5 alternate forwards");
  1210 listen(); // rely on no flush having happened yet
  1211 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.4), 0.01,
  1212           "large negative delay test at 0ms");
  1213 check_events([{ type: 'animationstart', target: div,
  1214                 animationName: 'anim2', elapsedTime: 3.6,
  1215                 pseudoElement: "" }],
  1216              "right after start in large negative delay test");
  1217 advance_clock(380);
  1218 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.02), 0.01,
  1219           "large negative delay test at 380ms");
  1220 check_events([]);
  1221 advance_clock(20);
  1222 is(cs.marginRight, "0px", "large negative delay test at 400ms");
  1223 check_events([{ type: 'animationiteration', target: div,
  1224                 animationName: 'anim2', elapsedTime: 4.0,
  1225                 pseudoElement: "" }],
  1226              "right after start in large negative delay test");
  1227 advance_clock(800);
  1228 is_approx(px_to_num(cs.marginRight), 100 * gTF.ease_in(0.8), 0.01,
  1229           "large negative delay test at 1200ms");
  1230 check_events([]);
  1231 advance_clock(200);
  1232 is(cs.marginRight, "100px", "large negative delay test at 1400ms");
  1233 check_events([{ type: 'animationend', target: div,
  1234                 animationName: 'anim2', elapsedTime: 5.0,
  1235                 pseudoElement: "" }],
  1236              "right after start in large negative delay test");
  1237 done_div();
  1239 /*
  1240  * css3-animations:  3.9. The 'animation-fill-mode' Property
  1241  * http://dev.w3.org/csswg/css3-animations/#the-animation-fill-mode-property-
  1242  */
  1244 // animation-fill-mode is tested in the tests for section (2).
  1246 /*
  1247  * css3-animations:  3.10. The 'animation' Shorthand Property
  1248  * http://dev.w3.org/csswg/css3-animations/#the-animation-shorthand-property-
  1249  */
  1251 // shorthand vs. longhand is adequately tested by the
  1252 // property_database.js-based tests.
  1254 /**
  1255  * Basic tests of animations on pseudo-elements
  1256  */
  1257 new_div("");
  1258 listen();
  1259 div.id = "withbefore";
  1260 var cs_before = getComputedStyle(div, ":before");
  1261 is(cs_before.marginRight, "0px", ":before test at 0ms");
  1262 advance_clock(400);
  1263 is(cs_before.marginRight, "40px", ":before test at 400ms");
  1264 advance_clock(800);
  1265 is(cs_before.marginRight, "80px", ":before test at 1200ms");
  1266 is(cs.marginRight, "0px", ":before animation should not affect element");
  1267 advance_clock(800);
  1268 is(cs_before.marginRight, "0px", ":before test at 2000ms");
  1269 advance_clock(300);
  1270 is(cs_before.marginRight, "30px", ":before test at 2300ms");
  1271 advance_clock(700);
  1272 check_events([ { type: "animationstart", animationName: "anim2", elapsedTime: 0, pseudoElement: "::before" },
  1273                { type: "animationiteration", animationName: "anim2", elapsedTime: 1.2, pseudoElement: "::before" },
  1274                { type: "animationiteration", animationName: "anim2", elapsedTime: 2, pseudoElement: "::before" },
  1275                { type: "animationend", animationName: "anim2", elapsedTime: 3, pseudoElement: "::before" }]);
  1276 done_div();
  1278 new_div("");
  1279 listen();
  1280 div.id = "withafter";
  1281 var cs_after = getComputedStyle(div, ":after");
  1282 is(cs_after.marginRight, "0px", ":after test at 0ms");
  1283 advance_clock(400);
  1284 is(cs_after.marginRight, "40px", ":after test at 400ms");
  1285 advance_clock(800);
  1286 is(cs_after.marginRight, "80px", ":after test at 1200ms");
  1287 is(cs.marginRight, "0px", ":after animation should not affect element");
  1288 advance_clock(800);
  1289 is(cs_after.marginRight, "0px", ":after test at 2000ms");
  1290 advance_clock(300);
  1291 is(cs_after.marginRight, "30px", ":after test at 2300ms");
  1292 advance_clock(700);
  1293 check_events([ { type: "animationstart", animationName: "anim2", elapsedTime: 0, pseudoElement: "::after" },
  1294                { type: "animationiteration", animationName: "anim2", elapsedTime: 1.2, pseudoElement: "::after" },
  1295                { type: "animationiteration", animationName: "anim2", elapsedTime: 2, pseudoElement: "::after" },
  1296                { type: "animationend", animationName: "anim2", elapsedTime: 3, pseudoElement: "::after" }]);
  1297 done_div();
  1299 /**
  1300  * Test handling of properties that are present in only some of the
  1301  * keyframes.
  1302  */
  1303 new_div("animation: multiprop 1s ease-in-out alternate infinite");
  1304 is(cs.paddingTop, "10px", "multiprop top at 0ms");
  1305 is(cs.paddingLeft, "30px", "multiprop top at 0ms");
  1306 advance_clock(100);
  1307 is_approx(px_to_num(cs.paddingTop), 10 + 30 * gTF.ease(0.2), 0.01,
  1308           "multiprop top at 100ms");
  1309 is_approx(px_to_num(cs.paddingLeft), 30 + 20 * gTF.ease(0.4), 0.01,
  1310           "multiprop left at 100ms");
  1311 advance_clock(200);
  1312 is_approx(px_to_num(cs.paddingTop), 10 + 30 * gTF.ease(0.6), 0.01,
  1313           "multiprop top at 300ms");
  1314 is_approx(px_to_num(cs.paddingLeft), 50 + 10 * gTF.ease_out(0.1), 0.01,
  1315           "multiprop left at 300ms");
  1316 advance_clock(300);
  1317 is_approx(px_to_num(cs.paddingTop), 40 + 40 * gTF.ease_in_out(0.4), 0.01,
  1318           "multiprop top at 600ms");
  1319 is_approx(px_to_num(cs.paddingLeft), 50 + 10 * gTF.ease_out(0.7), 0.01,
  1320           "multiprop left at 600ms");
  1321 advance_clock(200);
  1322 is_approx(px_to_num(cs.paddingTop), 80 - 80 * gTF.ease_in(0.2), 0.01,
  1323           "multiprop top at 800ms");
  1324 is_approx(px_to_num(cs.paddingLeft), 60 - 60 * gTF.ease_in(0.2), 0.01,
  1325           "multiprop left at 800ms");
  1326 advance_clock(400);
  1327 is_approx(px_to_num(cs.paddingTop), 80 - 80 * gTF.ease_in(0.2), 0.01,
  1328           "multiprop top at 1200ms");
  1329 is_approx(px_to_num(cs.paddingLeft), 60 - 60 * gTF.ease_in(0.2), 0.01,
  1330           "multiprop left at 1200ms");
  1331 advance_clock(200);
  1332 is_approx(px_to_num(cs.paddingTop), 40 + 40 * gTF.ease_in_out(0.4), 0.01,
  1333           "multiprop top at 1400ms");
  1334 is_approx(px_to_num(cs.paddingLeft), 50 + 10 * gTF.ease_out(0.7), 0.01,
  1335           "multiprop left at 1400ms");
  1336 advance_clock(300);
  1337 is_approx(px_to_num(cs.paddingTop), 10 + 30 * gTF.ease(0.6), 0.01,
  1338           "multiprop top at 1700ms");
  1339 is_approx(px_to_num(cs.paddingLeft), 50 + 10 * gTF.ease_out(0.1), 0.01,
  1340           "multiprop left at 1700ms");
  1341 advance_clock(200);
  1342 is_approx(px_to_num(cs.paddingTop), 10 + 30 * gTF.ease(0.2), 0.01,
  1343           "multiprop top at 1900ms");
  1344 is_approx(px_to_num(cs.paddingLeft), 30 + 20 * gTF.ease(0.4), 0.01,
  1345           "multiprop left at 1900ms");
  1346 done_div();
  1348 // Test for https://bugzilla.mozilla.org/show_bug.cgi?id=651456 -- make
  1349 // sure that refreshing of animations doesn't break when we get two
  1350 // refreshes with the same timestamp.
  1351 new_div("animation: anim2 1s linear");
  1352 is(cs.marginRight, "0px", "bug 651456 at 0ms");
  1353 advance_clock(100);
  1354 is(cs.marginRight, "10px", "bug 651456 at 100ms (1)");
  1355 advance_clock(0); // still forces a refresh
  1356 is(cs.marginRight, "10px", "bug 651456 at 100ms (2)");
  1357 advance_clock(100);
  1358 is(cs.marginRight, "20px", "bug 651456 at 200ms");
  1359 done_div();
  1361 // Test that UA !important rules override animations.
  1362 // This test depends on forms.css having a rule
  1363 //   select { line-height: !important }
  1364 // If that rule changes, we should rewrite it to depend on a different rule.
  1365 new_element("select", "");
  1366 var default_line_height = cs.lineHeight;
  1367 done_div();
  1368 new_element("select", "animation: uaoverride 2s linear infinite");
  1369 is(cs.lineHeight, default_line_height,
  1370    "animations should not override UA !important at 0ms");
  1371 is(cs.marginTop, "20px",
  1372    "rest of animation should still work when UA !important present at 0ms");
  1373 advance_clock(200);
  1374 is(cs.lineHeight, default_line_height,
  1375    "animations should not override UA !important at 200ms");
  1376 is(cs.marginTop, "40px",
  1377    "rest of animation should still work when UA !important present at 200ms");
  1378 done_div();
  1380 // Test that author !important rules override animations, but
  1381 // that animations override regular author rules.
  1382 new_div("animation: always_fifty 1s linear infinite; margin-left: 200px");
  1383 is(cs.marginLeft, "50px", "animations override regular author rules");
  1384 done_div();
  1385 new_div("animation: always_fifty 1s linear infinite; margin-left: 200px ! important;");
  1386 is(cs.marginLeft, "200px", "important author rules override animations");
  1387 done_div();
  1389 // Test interaction of animations and restyling (Bug 686656).
  1390 // This test depends on kf3 getting its 0% and 100% values from the
  1391 // rules below it in the cascade; we're checking that the animation
  1392 // isn't rebuilt when the restyles happen.
  1393 new_div("animation: kf3 1s linear forwards");
  1394 is(cs.marginTop, "0px", "bug 686656 test 1 at 0ms");
  1395 advance_clock(250);
  1396 display.style.color = "blue";
  1397 is(cs.marginTop, "100px", "bug 686656 test 1 at 250ms");
  1398 advance_clock(375);
  1399 is(cs.marginTop, "50px", "bug 686656 test 1 at 625ms");
  1400 advance_clock(375);
  1401 is(cs.marginTop, "0px", "bug 686656 test 1 at 1000ms");
  1402 done_div();
  1403 display.style.color = "";
  1405 // Test interaction of animations and restyling (Bug 686656),
  1406 // with reframing.
  1407 // This test depends on kf3 getting its 0% and 100% values from the
  1408 // rules below it in the cascade; we're checking that the animation
  1409 // isn't rebuilt when the restyles happen.
  1410 new_div("animation: kf3 1s linear forwards");
  1411 is(cs.marginTop, "0px", "bug 686656 test 2 at 0ms");
  1412 advance_clock(250);
  1413 display.style.overflow = "scroll";
  1414 is(cs.marginTop, "100px", "bug 686656 test 2 at 250ms");
  1415 advance_clock(375);
  1416 is(cs.marginTop, "50px", "bug 686656 test 2 at 625ms");
  1417 advance_clock(375);
  1418 is(cs.marginTop, "0px", "bug 686656 test 2 at 1000ms");
  1419 done_div();
  1420 display.style.overflow = "";
  1422 // Test that cascading between keyframes rules is per-property rather
  1423 // than per-rule (bug ), and that the timing function isn't taken from a
  1424 // rule that's skipped.  (Bug 738003)
  1425 new_div("animation: cascade 1s linear forwards; position: relative");
  1426 is(cs.top, "0px", "cascade test (top) at 0ms");
  1427 is(cs.left, "0px", "cascade test (top) at 0ms");
  1428 advance_clock(125);
  1429 is(cs.top, "0px", "cascade test (top) at 125ms");
  1430 is(cs.left, "50px", "cascade test (top) at 125ms");
  1431 advance_clock(125);
  1432 is(cs.top, "0px", "cascade test (top) at 250ms");
  1433 is(cs.left, "100px", "cascade test (top) at 250ms");
  1434 advance_clock(125);
  1435 is(cs.top, "50px", "cascade test (top) at 375ms");
  1436 is(cs.left, "100px", "cascade test (top) at 375ms");
  1437 advance_clock(125);
  1438 is(cs.top, "100px", "cascade test (top) at 500ms");
  1439 is(cs.left, "100px", "cascade test (top) at 500ms");
  1440 advance_clock(125);
  1441 is(cs.top, "100px", "cascade test (top) at 625ms");
  1442 is(cs.left, "50px", "cascade test (top) at 625ms");
  1443 advance_clock(125);
  1444 is(cs.top, "100px", "cascade test (top) at 750ms");
  1445 is(cs.left, "0px", "cascade test (top) at 750ms");
  1446 advance_clock(125);
  1447 is(cs.top, "50px", "cascade test (top) at 875ms");
  1448 is(cs.left, "0px", "cascade test (top) at 875ms");
  1449 advance_clock(125);
  1450 is(cs.top, "0px", "cascade test (top) at 1000ms");
  1451 is(cs.left, "0px", "cascade test (top) at 1000ms");
  1452 done_div();
  1454 new_div("animation: cascade2 8s linear forwards");
  1455 is(cs.textIndent, "0px", "cascade2 test at 0s");
  1456 advance_clock(1000);
  1457 is(cs.textIndent, "25px", "cascade2 test at 1s");
  1458 advance_clock(1000);
  1459 is(cs.textIndent, "50px", "cascade2 test at 2s");
  1460 advance_clock(1000);
  1461 is(cs.textIndent, "25px", "cascade2 test at 3s");
  1462 advance_clock(1000);
  1463 is(cs.textIndent, "0px", "cascade2 test at 4s");
  1464 advance_clock(3000);
  1465 is(cs.textIndent, "75px", "cascade2 test at 7s");
  1466 advance_clock(1000);
  1467 is(cs.textIndent, "100px", "cascade2 test at 8s");
  1468 done_div();
  1470 new_div("-moz-animation: primitives1 2s linear forwards");
  1471 is(cs.getPropertyValue("-moz-transform"), "matrix(1, 0, 0, 1, 0, 0)",
  1472     "primitives1 at 0s");
  1473 advance_clock(1000);
  1474 is(cs.getPropertyValue("-moz-transform"),
  1475    "matrix(-0.707107, 0.707107, -0.707107, -0.707107, 0, 0)",
  1476    "primitives1 at 1s");
  1477 advance_clock(1000);
  1478 is(cs.getPropertyValue("-moz-transform"), "matrix(0, -1, 1, 0, 0, 0)",
  1479     "primitives1 at 0s");
  1480 done_div();
  1482 new_div("animation: important1 1s linear forwards");
  1483 is(cs.marginTop, "50px", "important1 test at 0s");
  1484 advance_clock(500);
  1485 is(cs.marginTop, "75px", "important1 test at 0.5s");
  1486 advance_clock(500);
  1487 is(cs.marginTop, "100px", "important1 test at 1s");
  1488 done_div();
  1490 new_div("animation: important2 1s linear forwards");
  1491 is(cs.marginTop, "50px", "important2 (margin-top) test at 0s");
  1492 is(cs.marginBottom, "100px", "important2 (margin-bottom) test at 0s");
  1493 advance_clock(1000);
  1494 is(cs.marginTop, "0px", "important2 (margin-top) test at 1s");
  1495 is(cs.marginBottom, "50px", "important2 (margin-bottom) test at 1s");
  1496 done_div();
  1498 // Test that it's the length of the 'animation-name' list that's used to
  1499 // start animations.
  1500 // note: anim2 animates margin-right from 0 to 100px
  1501 // note: anim3 animates margin-top from 0 to 100px
  1502 new_div("animation-name: anim2, anim3; animation-duration: 1s; animation-timing-function: linear; animation-delay: -250ms, -250ms, -750ms, -500ms;");
  1503 is(cs.marginRight, "25px", "animation-name list length is the length that matters");
  1504 is(cs.marginTop, "25px", "animation-name list length is the length that matters");
  1505 done_div();
  1506 new_div("animation-name: anim2, anim3, anim2; animation-duration: 1s; animation-timing-function: linear; animation-delay: -250ms, -250ms, -750ms, -500ms;");
  1507 is(cs.marginRight, "75px", "animation-name list length is the length that matters, and the last occurrence of a name wins");
  1508 is(cs.marginTop, "25px", "animation-name list length is the length that matters");
  1509 done_div();
  1511 var dyn_sheet_elt = document.createElement("style");
  1512 document.head.appendChild(dyn_sheet_elt);
  1513 var dyn_sheet = dyn_sheet_elt.sheet;
  1514 dyn_sheet.insertRule("@keyframes dyn1 { from { margin-left: 0 } 50% { margin-left: 50px } to { margin-left: 100px } }", 0);
  1515 dyn_sheet.insertRule("@keyframes dyn2 { from { margin-left: 100px } to { margin-left: 200px } }", 1);
  1516 var dyn1 = dyn_sheet.cssRules[0];
  1517 var dyn2 = dyn_sheet.cssRules[1];
  1518 new_div("animation: dyn1 1s linear");
  1519 is(cs.marginLeft, "0px", "dynamic rule change test, initial state");
  1520 advance_clock(250);
  1521 is(cs.marginLeft, "25px", "dynamic rule change test, 250ms");
  1522 dyn2.name = "dyn1";
  1523 is(cs.marginLeft, "125px", "dynamic rule change test, change in @keyframes name applies");
  1524 dyn2.appendRule("50% { margin-left: 0px }");
  1525 is(cs.marginLeft, "50px", "dynamic rule change test, @keyframes appendRule");
  1526 var dyn2_kf1 = dyn2.cssRules[0]; // currently 0% { margin-left: 100px }
  1527 dyn2_kf1.style.marginLeft = "-100px";
  1528 // FIXME: Bug 978833 (keyframe rules used as nsIStyleRule but doesn't follow immutability contract)
  1529 todo_is(cs.marginLeft, "-50px", "dynamic rule change test, keyframe style set");
  1530 dyn2.name = "dyn2";
  1531 is(cs.marginLeft, "25px", "dynamic rule change test, change in @keyframes name applies (second time)");
  1532 var dyn1_kf2 = dyn1.cssRules[1]; // currently 50% { margin-left: 50px }
  1533 dyn1_kf2.keyText = "25%";
  1534 is(cs.marginLeft, "50px", "dynamic rule change test, change in keyframe keyText");
  1535 dyn1.deleteRule("25%");
  1536 is(cs.marginLeft, "25px", "dynamic rule change test, @keyframes deleteRule");
  1537 done_div();
  1538 dyn_sheet_elt.parentNode.removeChild(dyn_sheet_elt);
  1539 dyn_sheet_elt = null;
  1540 dyn_sheet = null;
  1542 SpecialPowers.DOMWindowUtils.restoreNormalRefresh();
  1544 </script>
  1545 </pre>
  1546 </body>
  1547 </html>

mercurial