1<!DOCTYPE html>
2<html>
3<head>
4  <meta charset="utf-8">
5  <title>Event.cancelBubble</title>
6  <link rel="author" title="Chris Rebert" href="http://chrisrebert.com">
7  <link rel="help" href="https://dom.spec.whatwg.org/#dom-event-cancelbubble">
8  <meta name="flags" content="dom">
9  <script src="/resources/testharness.js"></script>
10  <script src="/resources/testharnessreport.js"></script>
11</head>
12<body>
13  <div id="outer">
14    <div id="middle">
15      <div id="inner"></div>
16    </div>
17  </div>
18  <script>
19test(function () {
20  // See https://dom.spec.whatwg.org/#stop-propagation-flag
21  var e = document.createEvent('Event');
22  assert_false(e.cancelBubble, "cancelBubble must be false after event creation.");
23}, "cancelBubble must be false when an event is initially created.");
24
25test(function () {
26  // See https://dom.spec.whatwg.org/#concept-event-initialize
27
28  // Event which bubbles.
29  var one = document.createEvent('Event');
30  one.cancelBubble = true;
31  one.initEvent('foo', true/*bubbles*/, false/*cancelable*/);
32  assert_false(one.cancelBubble, "initEvent() must set cancelBubble to false. [bubbles=true]");
33  // Re-initialization.
34  one.cancelBubble = true;
35  one.initEvent('foo', true/*bubbles*/, false/*cancelable*/);
36  assert_false(one.cancelBubble, "2nd initEvent() call must set cancelBubble to false. [bubbles=true]");
37
38  // Event which doesn't bubble.
39  var two = document.createEvent('Event');
40  two.cancelBubble = true;
41  two.initEvent('foo', false/*bubbles*/, false/*cancelable*/);
42  assert_false(two.cancelBubble, "initEvent() must set cancelBubble to false. [bubbles=false]");
43  // Re-initialization.
44  two.cancelBubble = true;
45  two.initEvent('foo', false/*bubbles*/, false/*cancelable*/);
46  assert_false(two.cancelBubble, "2nd initEvent() call must set cancelBubble to false. [bubbles=false]");
47}, "Initializing an event must set cancelBubble to false.");
48
49test(function () {
50  // See https://dom.spec.whatwg.org/#dom-event-stoppropagation
51  var e = document.createEvent('Event');
52  e.stopPropagation();
53  assert_true(e.cancelBubble, "stopPropagation() must set cancelBubble to true.");
54}, "stopPropagation() must set cancelBubble to true.");
55
56test(function () {
57  // See https://dom.spec.whatwg.org/#dom-event-stopimmediatepropagation
58  var e = document.createEvent('Event');
59  e.stopImmediatePropagation();
60  assert_true(e.cancelBubble, "stopImmediatePropagation() must set cancelBubble to true.");
61}, "stopImmediatePropagation() must set cancelBubble to true.");
62
63test(function () {
64  var one = document.createEvent('Event');
65  one.stopPropagation();
66  one.cancelBubble = false;
67  assert_true(one.cancelBubble, "cancelBubble must still be true after attempting to set it to false.");
68}, "Event.cancelBubble=false must have no effect.");
69
70test(function (t) {
71  var outer = document.getElementById('outer');
72  var middle = document.getElementById('middle');
73  var inner = document.getElementById('inner');
74
75  outer.addEventListener('barbaz', t.step_func(function () {
76    assert_unreached("Setting Event.cancelBubble=false after setting Event.cancelBubble=true should have no effect.");
77  }), false/*useCapture*/);
78
79  middle.addEventListener('barbaz', function (e) {
80    e.cancelBubble = true;// Stop propagation.
81    e.cancelBubble = false;// Should be a no-op.
82  }, false/*useCapture*/);
83
84  var barbazEvent = document.createEvent('Event');
85  barbazEvent.initEvent('barbaz', true/*bubbles*/, false/*cancelable*/);
86  inner.dispatchEvent(barbazEvent);
87}, "Event.cancelBubble=false must have no effect during event propagation.");
88
89test(function () {
90  // See https://dom.spec.whatwg.org/#concept-event-dispatch
91  // "14. Unset event’s [...] stop propagation flag,"
92  var e = document.createEvent('Event');
93  e.initEvent('foobar', true/*bubbles*/, true/*cancelable*/);
94  document.body.addEventListener('foobar', function listener(e) {
95    e.stopPropagation();
96  });
97  document.body.dispatchEvent(e);
98  assert_false(e.cancelBubble, "cancelBubble must be false after an event has been dispatched.");
99}, "cancelBubble must be false after an event has been dispatched.");
100
101test(function (t) {
102  var outer = document.getElementById('outer');
103  var middle = document.getElementById('middle');
104  var inner = document.getElementById('inner');
105
106  var propagationStopper = function (e) {
107    e.cancelBubble = true;
108  };
109
110  // Bubble phase
111  middle.addEventListener('bar', propagationStopper, false/*useCapture*/);
112  outer.addEventListener('bar', t.step_func(function listenerOne() {
113    assert_unreached("Setting cancelBubble=true should stop the event from bubbling further.");
114  }), false/*useCapture*/);
115
116  var barEvent = document.createEvent('Event');
117  barEvent.initEvent('bar', true/*bubbles*/, false/*cancelable*/);
118  inner.dispatchEvent(barEvent);
119
120  // Capture phase
121  outer.addEventListener('qux', propagationStopper, true/*useCapture*/);
122  middle.addEventListener('qux', t.step_func(function listenerTwo() {
123    assert_unreached("Setting cancelBubble=true should stop the event from propagating further, including during the Capture Phase.");
124  }), true/*useCapture*/);
125
126  var quxEvent = document.createEvent('Event');
127  quxEvent.initEvent('qux', false/*bubbles*/, false/*cancelable*/);
128  inner.dispatchEvent(quxEvent);
129}, "Event.cancelBubble=true must set the stop propagation flag.");
130  </script>
131</body>
132</html>
133