dom/smil/test/test_smilTimeEvents.xhtml

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 <html xmlns="http://www.w3.org/1999/xhtml">
     2 <!--
     3 https://bugzilla.mozilla.org/show_bug.cgi?id=572270
     4 -->
     5 <head>
     6   <title>Test TimeEvents dispatching</title>
     7   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
     8   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
     9 </head>
    10 <body>
    11 <a target="_blank"
    12   href="https://bugzilla.mozilla.org/show_bug.cgi?id=572270">Mozilla Bug
    13   572270</a>
    14 <p id="display"></p>
    15 <div id="content" style="display: none">
    16 <svg id="svg" xmlns="http://www.w3.org/2000/svg" width="100px" height="100px">
    17   <g font-size="10px">
    18     <circle cx="0" cy="0" r="15" fill="blue" id="circle"
    19       onbegin="parentHandler(evt)" onrepeat="parentHandler(evt)"
    20       onend="parentHandler(evt)">
    21       <animate attributeName="cy" from="0" to="100" dur="60s" begin="2s"
    22         id="anim" repeatCount="2"
    23         onbegin="handleOnBegin(evt)" onrepeat="handleOnRepeat(evt)"
    24         onend="handleOnEnd(evt)"/>
    25     </circle>
    26   </g>
    27 </svg>
    28 </div>
    29 <pre id="test">
    30 <script class="testbody" type="text/javascript">
    31 <![CDATA[
    32 /** Test SMIL TimeEvents dispatching **/
    34 /* Global Variables */
    35 const gTimeoutDur = 5000; // Time until we give up waiting for events in ms
    36 var gSvg    = document.getElementById("svg");
    37 var gAnim   = document.getElementById('anim');
    38 var gCircle = document.getElementById('circle');
    39 var gExpectedEvents = new Array();
    40 var gTimeoutID;
    41 var gTestStages =
    42   [ testPlaybackBegin,
    43     testPlaybackRepeat,
    44     testPlaybackEnd,
    45     testForwardsSeekToMid,
    46     testForwardsSeekToNextInterval,
    47     testForwardsSeekPastEnd,
    48     testBackwardsSeekToMid,
    49     testBackwardsSeekToStart,
    50     testCreateEvent,
    51     testRegistration
    52     ];
    54 SimpleTest.waitForExplicitFinish();
    56 function continueTest()
    57 {
    58   if (gTestStages.length == 0) {
    59     SimpleTest.finish();
    60     return;
    61   }
    62   gTestStages.shift()();
    63 }
    65 function testPlaybackBegin()
    66 {
    67   // Test events are dispatched through normal playback
    68   gSvg.pauseAnimations();
    69   gSvg.setCurrentTime(1.99);
    70   gExpectedEvents.push("beginEvent", "beginEvent"); // Two registered handlers
    71   gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
    72   gSvg.unpauseAnimations();
    73 }
    75 function testPlaybackRepeat()
    76 {
    77   gSvg.pauseAnimations();
    78   gSvg.setCurrentTime(61.99);
    79   gExpectedEvents.push(["repeatEvent", 1], ["repeatEvent", 1]);
    80   gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
    81   gSvg.unpauseAnimations();
    82 }
    84 function testPlaybackEnd()
    85 {
    86   gSvg.pauseAnimations();
    87   gSvg.setCurrentTime(121.99);
    88   gExpectedEvents.push("endEvent", "endEvent");
    89   gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
    90   gSvg.unpauseAnimations();
    91 }
    93 function testForwardsSeekToMid()
    94 {
    95   gSvg.pauseAnimations();
    96   // Set animation parameters to something that repeats a lot
    97   gSvg.setCurrentTime(0);
    98   gAnim.setAttribute('begin', '2s; 102s');
    99   gAnim.setAttribute('dur', '15s');
   100   gAnim.setAttribute('repeatCount', '6');
   101   gSvg.setCurrentTime(46.99);
   102   gExpectedEvents.push("beginEvent", "beginEvent",
   103                        ["repeatEvent", 3], ["repeatEvent", 3]);
   104   gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
   105   gSvg.unpauseAnimations();
   106 }
   108 function testForwardsSeekToNextInterval()
   109 {
   110   // Skip to next interval -- we shouldn't get any additional begin or end
   111   // events in between
   112   gSvg.pauseAnimations();
   113   gSvg.setCurrentTime(131.99);
   114   gExpectedEvents.push(["repeatEvent", 2], ["repeatEvent", 2]);
   115   gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
   116   gSvg.unpauseAnimations();
   117 }
   119 function testForwardsSeekPastEnd()
   120 {
   121   gSvg.pauseAnimations();
   122   gSvg.setCurrentTime(200);
   123   gExpectedEvents.push("endEvent", "endEvent");
   124   gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
   125   gSvg.unpauseAnimations();
   126 }
   128 function testBackwardsSeekToMid()
   129 {
   130   gSvg.pauseAnimations();
   131   gSvg.setCurrentTime(31.99);
   132   gExpectedEvents.push("beginEvent", "beginEvent",
   133                        ["repeatEvent", 2], ["repeatEvent", 2]);
   134   gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
   135   gSvg.unpauseAnimations();
   136 }
   138 function testBackwardsSeekToStart()
   139 {
   140   gSvg.pauseAnimations();
   141   gExpectedEvents.push("endEvent", "endEvent");
   142   gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
   143   gSvg.setCurrentTime(0);
   144 }
   146 function testCreateEvent()
   147 {
   148   var evt;
   149   try {
   150     evt = document.createEvent("TimeEvents");
   151   } catch (e) {
   152     ok(false, "Failed to create TimeEvent via script: " + e);
   153     return;
   154   }
   155   evt.initTimeEvent("repeatEvent", null, 3);
   156   is(evt.type, "repeatEvent", "Unexpected type for user-generated event");
   157   is(evt.detail, 3, "Unexpected detail for user-generated event");
   158   is(evt.target, null, "Unexpected event target");
   159   is(evt.currentTarget, null, "Unexpected event current target");
   160   is(evt.eventPhase, evt.NONE);
   161   is(evt.bubbles, false, "Event should not bubble");
   162   is(evt.cancelable, false, "Event should not be cancelable");
   163   is(evt.view, null, "Event view should be null");
   165   // Prior to dispatch we should be able to change the event type
   166   evt.initTimeEvent("beginEvent", document.defaultView, 0);
   167   is(evt.type, "beginEvent", "Failed to update event type before dispatch");
   168   is(evt.detail, 0, "Failed to update event detail before dispatch");
   169   is(evt.view, document.defaultView, "Event view should be set");
   171   // But not directly as it's readonly
   172   try {
   173     evt.type = "endEvent";
   174   } catch(e) { }
   175   is(evt.type, "beginEvent", "Event type should be readonly");
   177   // Likewise the detail field should be readonly
   178   try {
   179     evt.detail = "8";
   180   } catch(e) { }
   181   is(evt.detail, 0, "Event detail should be readonly");
   183   // Dispatch
   184   gExpectedEvents.push("beginEvent", "beginEvent");
   185   gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
   186   gAnim.dispatchEvent(evt);
   187 }
   189 function testRegistration()
   190 {
   191   gSvg.pauseAnimations();
   192   // Reset animation to something simple
   193   gSvg.setCurrentTime(0);
   194   gAnim.setAttribute('begin', '2s');
   195   gAnim.setAttribute('dur', '50s');
   197   // Remove attribute handler
   198   gAnim.removeAttribute('onbegin');
   200   // Add bogus handlers
   201   gAnim.setAttribute('onbeginElement', 'handleOnBegin(evt)');
   202   gAnim.addEventListener("begin", handleOnBegin, false);
   203   gAnim.addEventListener("onbegin", handleOnBegin, false);
   205   // We should now have just one legitimate listener: the one registered to
   206   // handle 'beginElement'
   207   gSvg.setCurrentTime(1.99);
   208   gExpectedEvents.push("beginEvent");
   209   gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
   210   gSvg.unpauseAnimations();
   211 }
   213 function handleOnBegin(evt)
   214 {
   215   is(evt.type, "beginEvent", "Expected begin event but got " + evt.type);
   216   checkExpectedEvent(evt);
   217 }
   219 function handleOnRepeat(evt)
   220 {
   221   is(evt.type, "repeatEvent", "Expected repeat event but got " + evt.type);
   222   checkExpectedEvent(evt);
   223 }
   225 function handleOnEnd(evt)
   226 {
   227   is(evt.type, "endEvent", "Expected end event but got " + evt.type);
   228   checkExpectedEvent(evt);
   229 }
   231 function sanityCheckEvent(evt)
   232 {
   233   is(evt.target, gAnim, "Unexpected event target");
   234   is(evt.currentTarget, gAnim, "Unexpected event current target");
   235   is(evt.eventPhase, evt.AT_TARGET);
   236   is(evt.bubbles, false, "Event should not bubble");
   237   is(evt.cancelable, false, "Event should not be cancelable");
   238   // Currently we set event timestamps to 0 which DOM 2 allows. This isn't
   239   // correct since SMIL uses this field to avoid synchronisation slew but first
   240   // we need to fix bug 323039 and bug 77992 which involve storing timestamps as
   241   // 64-bit integers and deciding whether those timestamps should be related to
   242   // the epoch or system start.
   243   is(evt.timeStamp, 0, "Event timeStamp should be 0");
   244   ok(evt.view !== null, "Event view not set");
   245 }
   247 function checkExpectedEvent(evt)
   248 {
   249   sanityCheckEvent(evt);
   250   ok(gExpectedEvents.length > 0, "Unexpected event: " + evt.type);
   251   if (gExpectedEvents.length == 0) return;
   253   var expected = gExpectedEvents.shift();
   254   if (typeof expected == 'string') {
   255     is(evt.type, expected, "Unexpected event type");
   256     is(evt.detail, 0, "Unexpected event detail (repeat iteration)");
   257   } else {
   258     is(evt.type, expected[0], "Unexpected event type");
   259     is(evt.detail, expected[1], "Unexpected event detail (repeat iteration)");
   260   }
   261   if (gExpectedEvents.length == 0) {
   262     clearTimeout(gTimeoutID);
   263     continueTest();
   264   }
   265 }
   267 function timeoutFail()
   268 {
   269   ok(false, "Timed out waiting for events: " + gExpectedEvents.join(', '));
   270   SimpleTest.finish(); // No point continuing
   271 }
   273 function parentHandler(evt)
   274 {
   275   ok(false, "Handler on parent got called but event shouldn't bubble.");
   276 }
   278 window.addEventListener("load", continueTest, false);
   280 // Register event handlers *in addition* to the handlers already added via the
   281 // "onbegin", "onend", "onrepeat" attributes on the <animate> and <circle>
   282 // elements. This is to test that both types of registration work.
   283 gAnim.addEventListener("beginEvent", handleOnBegin, false);
   284 gAnim.addEventListener("repeatEvent", handleOnRepeat, false);
   285 gAnim.addEventListener("endEvent", handleOnEnd, false);
   286 gCircle.addEventListener("beginEvent", parentHandler, false);
   287 ]]>
   288 </script>
   289 </pre>
   290 </body>
   291 </html>

mercurial