dom/smil/test/test_smilTimeEvents.xhtml

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:58c74ac8b062
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 **/
33
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 ];
53
54 SimpleTest.waitForExplicitFinish();
55
56 function continueTest()
57 {
58 if (gTestStages.length == 0) {
59 SimpleTest.finish();
60 return;
61 }
62 gTestStages.shift()();
63 }
64
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 }
74
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 }
83
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 }
92
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 }
107
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 }
118
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 }
127
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 }
137
138 function testBackwardsSeekToStart()
139 {
140 gSvg.pauseAnimations();
141 gExpectedEvents.push("endEvent", "endEvent");
142 gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
143 gSvg.setCurrentTime(0);
144 }
145
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");
164
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");
170
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");
176
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");
182
183 // Dispatch
184 gExpectedEvents.push("beginEvent", "beginEvent");
185 gTimeoutID = setTimeout(timeoutFail, gTimeoutDur);
186 gAnim.dispatchEvent(evt);
187 }
188
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');
196
197 // Remove attribute handler
198 gAnim.removeAttribute('onbegin');
199
200 // Add bogus handlers
201 gAnim.setAttribute('onbeginElement', 'handleOnBegin(evt)');
202 gAnim.addEventListener("begin", handleOnBegin, false);
203 gAnim.addEventListener("onbegin", handleOnBegin, false);
204
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 }
212
213 function handleOnBegin(evt)
214 {
215 is(evt.type, "beginEvent", "Expected begin event but got " + evt.type);
216 checkExpectedEvent(evt);
217 }
218
219 function handleOnRepeat(evt)
220 {
221 is(evt.type, "repeatEvent", "Expected repeat event but got " + evt.type);
222 checkExpectedEvent(evt);
223 }
224
225 function handleOnEnd(evt)
226 {
227 is(evt.type, "endEvent", "Expected end event but got " + evt.type);
228 checkExpectedEvent(evt);
229 }
230
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 }
246
247 function checkExpectedEvent(evt)
248 {
249 sanityCheckEvent(evt);
250 ok(gExpectedEvents.length > 0, "Unexpected event: " + evt.type);
251 if (gExpectedEvents.length == 0) return;
252
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 }
266
267 function timeoutFail()
268 {
269 ok(false, "Timed out waiting for events: " + gExpectedEvents.join(', '));
270 SimpleTest.finish(); // No point continuing
271 }
272
273 function parentHandler(evt)
274 {
275 ok(false, "Handler on parent got called but event shouldn't bubble.");
276 }
277
278 window.addEventListener("load", continueTest, false);
279
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