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