Skip to content

Commit

Permalink
Add tests for Event.cancelBubble
Browse files Browse the repository at this point in the history
  • Loading branch information
cvrebert committed Dec 8, 2016
1 parent e4860d0 commit 55f3229
Show file tree
Hide file tree
Showing 5 changed files with 250 additions and 0 deletions.
132 changes: 132 additions & 0 deletions dom/events/Event-cancelBubble.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Event.cancelBubble</title>
<link rel="author" title="Chris Rebert" href="http://chrisrebert.com">
<link rel="help" href="https://dom.spec.whatwg.org/#dom-event-cancelbubble">
<meta name="flags" content="dom">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<div id="outer">
<div id="middle">
<div id="inner"></div>
</div>
</div>
<script>
test(function () {
// See https://dom.spec.whatwg.org/#stop-propagation-flag
var e = document.createEvent('Event');
assert_false(e.cancelBubble, "cancelBubble must be false after event creation.");
}, "cancelBubble must be false when an event is initially created.");

test(function () {
// See https://dom.spec.whatwg.org/#concept-event-initialize

// Event which bubbles.
var one = document.createEvent('Event');
one.cancelBubble = true;
one.initEvent('foo', true/*bubbles*/, false/*cancelable*/);
assert_false(one.cancelBubble, "initEvent() must set cancelBubble to false. [bubbles=true]");
// Re-initialization.
one.cancelBubble = true;
one.initEvent('foo', true/*bubbles*/, false/*cancelable*/);
assert_false(one.cancelBubble, "2nd initEvent() call must set cancelBubble to false. [bubbles=true]");

// Event which doesn't bubble.
var two = document.createEvent('Event');
two.cancelBubble = true;
two.initEvent('foo', false/*bubbles*/, false/*cancelable*/);
assert_false(two.cancelBubble, "initEvent() must set cancelBubble to false. [bubbles=false]");
// Re-initialization.
two.cancelBubble = true;
two.initEvent('foo', false/*bubbles*/, false/*cancelable*/);
assert_false(two.cancelBubble, "2nd initEvent() call must set cancelBubble to false. [bubbles=false]");
}, "Initializing an event must set cancelBubble to false.");

test(function () {
// See https://dom.spec.whatwg.org/#dom-event-stoppropagation
var e = document.createEvent('Event');
e.stopPropagation();
assert_true(e.cancelBubble, "stopPropagation() must set cancelBubble to true.");
}, "stopPropagation() must set cancelBubble to true.");

test(function () {
// See https://dom.spec.whatwg.org/#dom-event-stopimmediatepropagation
var e = document.createEvent('Event');
e.stopImmediatePropagation();
assert_true(e.cancelBubble, "stopImmediatePropagation() must set cancelBubble to true.");
}, "stopImmediatePropagation() must set cancelBubble to true.");

test(function () {
var one = document.createEvent('Event');
one.stopPropagation();
one.cancelBubble = false;
assert_true(one.cancelBubble, "cancelBubble must still be true after attempting to set it to false.");
}, "Event.cancelBubble=false must have no effect.");

test(function () {
var outer = document.getElementById('outer');
var middle = document.getElementById('middle');
var inner = document.getElementById('inner');

outer.addEventListener('barbaz', function () {
assert_unreached("Setting Event.cancelBubble=false after setting Event.cancelBubble=true should have no effect.");
}, false/*useCapture*/);

middle.addEventListener('barbaz', function (e) {
e.cancelBubble = true;// Stop propagation.
e.cancelBubble = false;// Should be a no-op.
}, false/*useCapture*/);

var barbazEvent = document.createEvent('Event');
barbazEvent.initEvent('barbaz', true/*bubbles*/, false/*cancelable*/);
inner.dispatchEvent(barbazEvent);
}, "Event.cancelBubble=false must have no effect during event propagation.");

test(function () {
// See https://dom.spec.whatwg.org/#concept-event-dispatch
// "14. Unset event’s [...] stop propagation flag,"
var e = document.createEvent('Event');
e.initEvent('foobar', true/*bubbles*/, true/*cancelable*/);
document.body.addEventListener('foobar', function listener(e) {
e.stopPropagation();
});
document.body.dispatchEvent(e);
assert_false(e.cancelBubble, "cancelBubble must be false after an event has been dispatched.");
}, "cancelBubble must be false after an event has been dispatched.");

test(function () {
var outer = document.getElementById('outer');
var middle = document.getElementById('middle');
var inner = document.getElementById('inner');

var propagationStopper = function (e) {
e.cancelBubble = true;
};

// Bubble phase
middle.addEventListener('bar', propagationStopper, false/*useCapture*/);
outer.addEventListener('bar', function listenerOne() {
assert_unreached("Setting cancelBubble=true should stop the event from bubbling further.");
}, false/*useCapture*/);

var barEvent = document.createEvent('Event');
barEvent.initEvent('bar', true/*bubbles*/, false/*cancelable*/);
inner.dispatchEvent(barEvent);

// Capture phase
outer.addEventListener('qux', propagationStopper, true/*useCapture*/);
middle.addEventListener('qux', function listenerTwo() {
assert_unreached("Setting cancelBubble=true should stop the event from propagating further, including during the Capture Phase.");
}, true/*useCapture*/);

var quxEvent = document.createEvent('Event');
quxEvent.initEvent('qux', false/*bubbles*/, false/*cancelable*/);
inner.dispatchEvent(quxEvent);
}, "Event.cancelBubble=true must set the stop propagation flag.");
</script>
</body>
</html>
59 changes: 59 additions & 0 deletions dom/events/Event-dispatch-bubble-canceled.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<!DOCTYPE html>
<html>
<head>
<title>Setting cancelBubble=true prior to dispatchEvent()</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<div id="log"></div>

<table id="table" border="1" style="display: none">
<tbody id="table-body">
<tr id="table-row">
<td id="table-cell">Shady Grove</td>
<td>Aeolian</td>
</tr>
<tr id="parent">
<td id="target">Over the river, Charlie</td>
<td>Dorian</td>
</tr>
</tbody>
</table>

<script>
test(function() {
var event = "foo";
var target = document.getElementById("target");
var parent = document.getElementById("parent");
var tbody = document.getElementById("table-body");
var table = document.getElementById("table");
var body = document.body;
var html = document.documentElement;
var current_targets = [window, document, html, body, table, tbody, parent, target];
var expected_targets = [];
var actual_targets = [];
var expected_phases = [];
var actual_phases = [];

var test_event = function(evt) {
actual_targets.push(evt.currentTarget);
actual_phases.push(evt.eventPhase);
};

for (var i = 0; i < current_targets.length; ++i) {
current_targets[i].addEventListener(event, test_event, true);
current_targets[i].addEventListener(event, test_event, false);
}

var evt = document.createEvent("Event");
evt.initEvent(event, true, true);
evt.cancelBubble = true;
target.dispatchEvent(evt);

assert_array_equals(actual_targets, expected_targets, "actual_targets");
assert_array_equals(actual_phases, expected_phases, "actual_phases");
});
</script>
</body>
</html>
51 changes: 51 additions & 0 deletions dom/events/Event-dispatch-multiple-cancelBubble.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<!DOCTYPE html>
<html>
<head>
<title>Multiple dispatchEvent() and cancelBubble</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<div id=log></div>

<div id="parent" style="display: none">
<input id="target" type="hidden" value=""/>
</div>

<script>
test(function() {
var event_type = "foo";
var target = document.getElementById("target");
var parent = document.getElementById("parent");
var actual_result;
var test_event = function(evt) {
actual_result.push(evt.currentTarget);

if (parent == evt.currentTarget) {
evt.cancelBubble = true;
}
};

var evt = document.createEvent("Event");
evt.initEvent(event_type, true, true);

target.addEventListener(event_type, test_event, false);
parent.addEventListener(event_type, test_event, false);
document.addEventListener(event_type, test_event, false);
window.addEventListener(event_type, test_event, false);

actual_result = [];
target.dispatchEvent(evt);
assert_array_equals(actual_result, [target, parent]);

actual_result = [];
parent.dispatchEvent(evt);
assert_array_equals(actual_result, [parent]);

actual_result = [];
document.dispatchEvent(evt);
assert_array_equals(actual_result, [document, window]);
});
</script>
</body>
</html>
1 change: 1 addition & 0 deletions dom/events/Event-initEvent.html
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
var target = document.createElement("div")
var called = false
target.addEventListener("type", function() { called = true }, false)
assert_false(e.cancelBubble, "cancelBubble must be false")
assert_true(target.dispatchEvent(e), "dispatchEvent must return true")
assert_true(called, "Listener must be called")
}, "Calling initEvent must unset the stop propagation flag.")
Expand Down
7 changes: 7 additions & 0 deletions dom/events/Event-propagation.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,11 @@
testPropagationFlag(ev, false, "After stopImmediatePropagation()");
ev.initEvent("foo", true, false);
testPropagationFlag(ev, true, "Reinitialized after stopImmediatePropagation()");

var ev = document.createEvent("Event");
ev.initEvent("foo", true, false);
ev.cancelBubble = true;
testPropagationFlag(ev, false, "After cancelBubble=true");
ev.initEvent("foo", true, false);
testPropagationFlag(ev, true, "Reinitialized after cancelBubble=true");
</script>

0 comments on commit 55f3229

Please sign in to comment.