handler-count.html (3740B)
1 <!DOCTYPE html> 2 <meta name="variant" content="?document"> 3 <meta name="variant" content="?window"> 4 <meta name="variant" content="?element"> 5 <link rel="help" 6 href="https://dom.spec.whatwg.org/#add-an-event-listener"> 7 <script src="/resources/testharness.js"></script> 8 <script src="/resources/testharnessreport.js"></script> 9 <script src="/resources/testdriver.js"></script> 10 <script src="/resources/testdriver-actions.js"></script> 11 <script src="/resources/testdriver-vendor.js"></script> 12 <style> 13 #target { 14 background-color: green; 15 width: 100px; 16 height: 100px; 17 } 18 @keyframes fade-out { 19 from { opacity: 1; } 20 to { opacity: 0; } 21 } 22 #target.animate { 23 animation: fade-out 300ms ease-in; 24 } 25 </style> 26 <!-- Tests handlers with various means of set up and tear down --> 27 <body> 28 <div id="target"></div> 29 </body> 30 <script> 31 let eventTally = 0; 32 let nextListenerId = 0; 33 34 function createEventTallyListener() { 35 return (event) => { 36 eventTally++; 37 } 38 } 39 40 function resetAndRecordEvents() { 41 const target = document.getElementById('target'); 42 eventTally = 0; 43 const ready = new Promise(async resolve => { 44 target.addEventListener('click', () => { 45 requestAnimationFrame(resolve); 46 }, { once: true }); 47 await new test_driver.Actions() 48 .pointerMove(0, 0, {origin: target}) 49 .pointerDown() 50 .pointerUp() 51 .send(); 52 }); 53 return ready; 54 } 55 56 const variant = location.search.substring(1) || 'window'; 57 let source = undefined; 58 switch(variant) { 59 case 'document': 60 source = document; 61 break; 62 63 case 'window': 64 source = window; 65 break; 66 67 case 'element': 68 source = document.getElementById('target'); 69 break; 70 71 default: 72 source = window; 73 } 74 75 promise_test(async t => { 76 // Add listeners 77 const first = createEventTallyListener(); 78 source.addEventListener('click', first, true); 79 await resetAndRecordEvents(); 80 assert_equals(eventTally, 1, 'After adding first listener'); 81 const second = createEventTallyListener(); 82 source.addEventListener('click', second, false); 83 await resetAndRecordEvents(); 84 assert_equals(eventTally, 2, 'After adding second listener'); 85 86 // Duplicate listener is discarded. 87 source.addEventListener('click', second, false); 88 await resetAndRecordEvents(); 89 assert_equals(eventTally, 2, 90 'After adding third listener with matching useCapture'); 91 92 // Remove first listener 93 source.removeEventListener('click', first, true); 94 await resetAndRecordEvents(); 95 assert_equals(eventTally, 1, 'After removing first listener'); 96 97 // Try to remove again. 98 source.removeEventListener('click', first, true); 99 await resetAndRecordEvents(); 100 assert_equals(eventTally, 1, 'Cannot remove a second time'); 101 102 // Try to remove second, but with mismatched capture 103 source.removeEventListener('click', second, true); 104 await resetAndRecordEvents(); 105 assert_equals(eventTally, 1, 'Capture argument must match'); 106 107 // Remove second listener. 108 source.removeEventListener('click', second, false); 109 await resetAndRecordEvents(); 110 assert_equals(eventTally, 0, 'After removal of second listener'); 111 }, `Test addEventListener/removeEventListener on the ${variant}.`); 112 113 promise_test(async t => { 114 // Add listener 115 source.onclick = createEventTallyListener(); 116 await resetAndRecordEvents(); 117 assert_equals(eventTally, 1, 'After adding listener'); 118 119 // Replace listener. 120 source.onclick = createEventTallyListener(); 121 await resetAndRecordEvents(); 122 assert_equals(eventTally, 1, 'After replacing listener'); 123 124 // Remove listener 125 source.onclick = null; 126 await resetAndRecordEvents(); 127 assert_equals(eventTally, 0, 'After removing listener'); 128 }, `Test setting onanimationstart handler on the ${variant}.`); 129 130 </script> 131 </body>