| <!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 (t) { |
| var outer = document.getElementById('outer'); |
| var middle = document.getElementById('middle'); |
| var inner = document.getElementById('inner'); |
| |
| outer.addEventListener('barbaz', t.step_func(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 (t) { |
| 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', t.step_func(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', t.step_func(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> |