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

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

mercurial