diff options
Diffstat (limited to 'dom/smil/test/test_smilTimeEvents.xhtml')
-rw-r--r-- | dom/smil/test/test_smilTimeEvents.xhtml | 337 |
1 files changed, 337 insertions, 0 deletions
diff --git a/dom/smil/test/test_smilTimeEvents.xhtml b/dom/smil/test/test_smilTimeEvents.xhtml new file mode 100644 index 000000000..bf6924ddb --- /dev/null +++ b/dom/smil/test/test_smilTimeEvents.xhtml @@ -0,0 +1,337 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=572270 +--> +<head> + <title>Test TimeEvents dispatching</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=572270">Mozilla Bug + 572270</a> +<p id="display"></p> +<div id="content" style="display: none"> +<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="100px" height="100px"> + <g font-size="10px"> + <circle cx="0" cy="0" r="15" fill="blue" id="circle" + onbegin="parentHandler(evt)" onrepeat="parentHandler(evt)" + onend="parentHandler(evt)"> + <animate attributeName="cy" from="0" to="100" dur="60s" begin="2s" + id="anim" repeatCount="2" + onbegin="handleOnBegin(evt)" onrepeat="handleOnRepeat(evt)" + onend="handleOnEnd(evt)"/> + </circle> + </g> +</svg> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +<![CDATA[ +/** Test SMIL TimeEvents dispatching **/ + +/* Global Variables */ +const gTimeoutDur = 60000; // Time until we give up waiting for events in ms +var gSvg = document.getElementById("svg"); +var gAnim = document.getElementById('anim'); +var gCircle = document.getElementById('circle'); +var gExpectedEvents = new Array(); +var gTimeoutID; +var gTestStages = + [ testPlaybackBegin, + testPlaybackRepeat, + testPlaybackEnd, + testForwardsSeekToMid, + testForwardsSeekToNextInterval, + testForwardsSeekPastEnd, + testBackwardsSeekToMid, + testBackwardsSeekToStart, + testCreateEvent, + testRegistration + ]; + +SimpleTest.waitForExplicitFinish(); +SimpleTest.requestFlakyTimeout("untriaged"); + +function continueTest() +{ + if (gTestStages.length == 0) { + SimpleTest.finish(); + return; + } + gTestStages.shift()(); +} + +function testPlaybackBegin() +{ + // Test events are dispatched through normal playback + gSvg.pauseAnimations(); + gSvg.setCurrentTime(1.99); + gExpectedEvents.push("beginEvent", "beginEvent"); // Two registered handlers + gTimeoutID = setTimeout(timeoutFail, gTimeoutDur); + gSvg.unpauseAnimations(); +} + +function testPlaybackRepeat() +{ + gSvg.pauseAnimations(); + gSvg.setCurrentTime(61.99); + gExpectedEvents.push(["repeatEvent", 1], ["repeatEvent", 1]); + gTimeoutID = setTimeout(timeoutFail, gTimeoutDur); + gSvg.unpauseAnimations(); +} + +function testPlaybackEnd() +{ + gSvg.pauseAnimations(); + gSvg.setCurrentTime(121.99); + gExpectedEvents.push("endEvent", "endEvent"); + gTimeoutID = setTimeout(timeoutFail, gTimeoutDur); + gSvg.unpauseAnimations(); +} + +function testForwardsSeekToMid() +{ + gSvg.pauseAnimations(); + // Set animation parameters to something that repeats a lot + gSvg.setCurrentTime(0); + gAnim.setAttribute('begin', '2s; 102s'); + gAnim.setAttribute('dur', '15s'); + gAnim.setAttribute('repeatCount', '6'); + gSvg.setCurrentTime(46.99); + gExpectedEvents.push("beginEvent", "beginEvent", + ["repeatEvent", 3], ["repeatEvent", 3]); + gTimeoutID = setTimeout(timeoutFail, gTimeoutDur); + gSvg.unpauseAnimations(); +} + +function testForwardsSeekToNextInterval() +{ + // Skip to next interval -- we shouldn't get any additional begin or end + // events in between + gSvg.pauseAnimations(); + gSvg.setCurrentTime(131.99); + gExpectedEvents.push(["repeatEvent", 2], ["repeatEvent", 2]); + gTimeoutID = setTimeout(timeoutFail, gTimeoutDur); + gSvg.unpauseAnimations(); +} + +function testForwardsSeekPastEnd() +{ + gSvg.pauseAnimations(); + gSvg.setCurrentTime(200); + gExpectedEvents.push("endEvent", "endEvent"); + gTimeoutID = setTimeout(timeoutFail, gTimeoutDur); + gSvg.unpauseAnimations(); +} + +function testBackwardsSeekToMid() +{ + gSvg.pauseAnimations(); + gSvg.setCurrentTime(31.99); + gExpectedEvents.push("beginEvent", "beginEvent", + ["repeatEvent", 2], ["repeatEvent", 2]); + gTimeoutID = setTimeout(timeoutFail, gTimeoutDur); + gSvg.unpauseAnimations(); +} + +function testBackwardsSeekToStart() +{ + gSvg.pauseAnimations(); + gExpectedEvents.push("endEvent", "endEvent"); + gTimeoutID = setTimeout(timeoutFail, gTimeoutDur); + gSvg.setCurrentTime(0); +} + +function testCreateEvent() +{ + var evt; + try { + evt = document.createEvent("TimeEvents"); + } catch (e) { + ok(false, "Failed to create TimeEvent via script: " + e); + return; + } + evt.initTimeEvent("repeatEvent", null, 3); + is(evt.type, "repeatEvent", "Unexpected type for user-generated event"); + is(evt.detail, 3, "Unexpected detail for user-generated event"); + is(evt.target, null, "Unexpected event target"); + is(evt.currentTarget, null, "Unexpected event current target"); + is(evt.eventPhase, evt.NONE); + is(evt.bubbles, false, "Event should not bubble"); + is(evt.cancelable, false, "Event should not be cancelable"); + is(evt.view, null, "Event view should be null"); + + // Prior to dispatch we should be able to change the event type + evt.initTimeEvent("beginEvent", document.defaultView, 0); + is(evt.type, "beginEvent", "Failed to update event type before dispatch"); + is(evt.detail, 0, "Failed to update event detail before dispatch"); + is(evt.view, document.defaultView, "Event view should be set"); + + // But not directly as it's readonly + try { + evt.type = "endEvent"; + } catch(e) { } + is(evt.type, "beginEvent", "Event type should be readonly"); + + // Likewise the detail field should be readonly + try { + evt.detail = "8"; + } catch(e) { } + is(evt.detail, 0, "Event detail should be readonly"); + + // Dispatch + gExpectedEvents.push("beginEvent", "beginEvent"); + gTimeoutID = setTimeout(timeoutFail, gTimeoutDur); + gAnim.dispatchEvent(evt); +} + +function testRegistration() +{ + gSvg.pauseAnimations(); + // Reset animation to something simple + gSvg.setCurrentTime(0); + gAnim.setAttribute('begin', '2s'); + gAnim.setAttribute('dur', '50s'); + + // Remove attribute handler + gAnim.removeAttribute('onbegin'); + + // Add bogus handlers + gAnim.setAttribute('onbeginElement', 'handleOnBegin(evt)'); + gAnim.addEventListener("begin", handleOnBegin, false); + gAnim.addEventListener("onbegin", handleOnBegin, false); + + // We should now have just one legitimate listener: the one registered to + // handle 'beginElement' + gSvg.setCurrentTime(1.99); + gExpectedEvents.push("beginEvent"); + gTimeoutID = setTimeout(timeoutFail, gTimeoutDur); + gSvg.unpauseAnimations(); +} + +function handleOnBegin(evt) +{ + is(evt.type, "beginEvent", "Expected begin event but got " + evt.type); + checkExpectedEvent(evt); +} + +function handleOnRepeat(evt) +{ + is(evt.type, "repeatEvent", "Expected repeat event but got " + evt.type); + checkExpectedEvent(evt); +} + +function handleOnEnd(evt) +{ + is(evt.type, "endEvent", "Expected end event but got " + evt.type); + checkExpectedEvent(evt); +} + +function sanityCheckEvent(evt) +{ + is(evt.target, gAnim, "Unexpected event target"); + is(evt.currentTarget, gAnim, "Unexpected event current target"); + is(evt.eventPhase, evt.AT_TARGET); + is(evt.bubbles, false, "Event should not bubble"); + is(evt.cancelable, false, "Event should not be cancelable"); + if (SpecialPowers.getBoolPref("dom.event.highrestimestamp.enabled")) { + var now = window.performance.now(); + ok(evt.timeStamp > 0 && evt.timeStamp < now, + "Event timeStamp (" + evt.timeStamp + ") should be > 0 but " + + "before the current time (" + now + ")"); + } else { + is(evt.timeStamp, 0, "Event timeStamp should be 0"); + } + ok(evt.view !== null, "Event view not set"); +} + +function checkExpectedEvent(evt) +{ + sanityCheckEvent(evt); + ok(gExpectedEvents.length > 0, "Unexpected event: " + evt.type); + if (gExpectedEvents.length == 0) return; + + var expected = gExpectedEvents.shift(); + if (typeof expected == 'string') { + is(evt.type, expected, "Unexpected event type"); + is(evt.detail, 0, "Unexpected event detail (repeat iteration)"); + } else { + is(evt.type, expected[0], "Unexpected event type"); + is(evt.detail, expected[1], "Unexpected event detail (repeat iteration)"); + } + if (gExpectedEvents.length == 0) { + clearTimeout(gTimeoutID); + continueTest(); + } +} + +function timeoutFail() +{ + ok(false, "Timed out waiting for events: " + gExpectedEvents.join(', ')); + SimpleTest.finish(); // No point continuing +} + +function parentHandler(evt) +{ + ok(false, "Handler on parent got called but event shouldn't bubble."); +} + +window.addEventListener("load", continueTest, false); + +// Register event handlers *in addition* to the handlers already added via the +// "onbegin", "onend", "onrepeat" attributes on the <animate> and <circle> +// elements. This is to test that both types of registration work. +gAnim.addEventListener("beginEvent", handleOnBegin, false); +gAnim.addEventListener("repeatEvent", handleOnRepeat, false); +gAnim.addEventListener("endEvent", handleOnEnd, false); +gCircle.addEventListener("beginEvent", parentHandler, false); + +var expectedEvents = + ["begin", "beginEvent", "repeat", "repeatEvent", "end", "endEvent", "SVGZoom", "zoom"]; + +for (var i = 0; i < expectedEvents.length; ++i) { + is((new Event(expectedEvents[i])).type, expectedEvents[i], "Unexpected event type!"); +} + +var timeEvents = ["begin", "repeat", "end"]; +var expectedEvents = ["begin", "beginEvent", "repeat", "repeatEvent", "end", "endEvent"]; +var d = document.createElement("div"); +for (var i = 0; i < timeEvents.length; ++i) { + d.addEventListener(timeEvents[i], function(e) { + is(e.type, expectedEvents[0], "Got the expected event type."); + expectedEvents.shift(); + }); + + // Without "Event" suffix. + var e = document.createEvent("timeevent"); + e.initEvent(timeEvents[i], true, true); + d.dispatchEvent(e); + + // With "Event" suffix. + e = document.createEvent("timeevent"); + e.initEvent(timeEvents[i] + "Event", true, true); + d.dispatchEvent(e); +} +is(expectedEvents.length, 0, "Got all the expected events."); + +expectedEvents = ["zoom", "SVGZoom"]; +d.addEventListener("zoom", function(e) { + is(e.type, expectedEvents[0]); + expectedEvents.shift(); +}); + +var zoomEvent = document.createEvent("svgzoomevent"); +zoomEvent.initEvent("zoom", true, true); +d.dispatchEvent(zoomEvent); +zoomEvent = document.createEvent("svgzoomevent"); +zoomEvent.initEvent("SVGZoom", true, true); +d.dispatchEvent(zoomEvent); +is(expectedEvents.length, 0, "Got all the expected events."); + +]]> +</script> +</pre> +</body> +</html> |