scrollend-event-fired-to-element-with-overscroll-behavior.html (5864B)
1 <!DOCTYPE HTML> 2 <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1"> 3 <script src="/resources/testharness.js"></script> 4 <script src="/resources/testharnessreport.js"></script> 5 <script src="/resources/testdriver.js"></script> 6 <script src="/resources/testdriver-actions.js"></script> 7 <script src="/resources/testdriver-vendor.js"></script> 8 <script src="scroll_support.js"></script> 9 <style> 10 #overscrollXDiv { 11 width: 200px; 12 height: 200px; 13 overflow: scroll; 14 overscroll-behavior-x: contain; 15 border: solid 1px black; 16 display: grid; 17 /* Places content and targetXDiv beside each other. */ 18 grid-template-columns: 500px 100px; 19 } 20 21 #overscrollYDiv { 22 width: 200px; 23 height: 200px; 24 overflow: scroll; 25 overscroll-behavior-y: none; 26 border: solid 1px black; 27 } 28 29 #targetXDiv { 30 width: 100px; 31 height: 100px; 32 overflow: scroll; 33 border: solid 1px black; 34 } 35 36 #targetYDiv { 37 width: 100px; 38 height: 100px; 39 overflow: scroll; 40 border: solid 1px black; 41 } 42 43 .content { 44 width: 500px; 45 height: 500px; 46 } 47 48 #spacer { 49 height: 200vh; 50 width: 200vw; 51 border: solid 1px black; 52 } 53 </style> 54 55 <body style="margin:0" onload=runTest()> 56 <div id="overscrollXDiv"> 57 <div class="content"></div> 58 <div id="targetXDiv"> 59 <div class="content"> 60 </div> 61 </div> 62 </div> 63 <div id="overscrollYDiv"> 64 <div class="content"></div> 65 <!-- Place targetYDiv below content so that is in view when 66 overscrollYDiv is scrolled all the way down --> 67 <div id="targetYDiv"> 68 <div class="content"> 69 </div> 70 </div> 71 </div> 72 <div id="spacer"></div> 73 </body> 74 75 <script> 76 var horizontal_scrollend_arrived = false; 77 var vertical_scrollend_arrived = false; 78 let scrollers = [document.scrollingElement, targetXDiv, targetYDiv, 79 overscrollXDiv, overscrollYDiv]; 80 81 async function resetScrollers(test) { 82 for (const scroller of scrollers) { 83 await resetTargetScrollState(test, scroller); 84 } 85 } 86 function onHorizontalScrollEnd(event) { 87 assert_false(event.cancelable); 88 assert_false(event.bubbles); 89 horizontal_scrollend_arrived = true; 90 } 91 function onVerticalScrollEnd(event) { 92 assert_false(event.cancelable); 93 assert_false(event.bubbles); 94 vertical_scrollend_arrived = true; 95 } 96 // Test that both "onscrollend" and addEventListener("scrollend"... work. 97 document.getElementById('overscrollXDiv').onscrollend = onHorizontalScrollEnd; 98 document.getElementById('overscrollYDiv'). 99 addEventListener("scrollend", onVerticalScrollEnd); 100 101 function runTest() { 102 promise_test(async (t) => { 103 await resetScrollers(t); 104 await waitForCompositorCommit(); 105 106 // Make sure that no scrollend event is sent to document. 107 document.addEventListener("scrollend", 108 t.unreached_func("Document got unexpected scrollend event.")); 109 let scrollend_promise; 110 111 scrollend_promise = waitForScrollendEvent(t, targetXDiv, 2000); 112 targetXDiv.scrollLeft = targetXDiv.scrollWidth; 113 await scrollend_promise; 114 115 scrollend_promise = waitForScrollendEvent(t, overscrollXDiv, 2000); 116 overscrollXDiv.scrollLeft = overscrollXDiv.scrollWidth; 117 await scrollend_promise; 118 horizontal_scrollend_arrived = false; 119 120 assert_equals(targetXDiv.scrollLeft, 121 targetXDiv.scrollWidth - targetXDiv.clientWidth); 122 assert_equals(overscrollXDiv.scrollLeft, 123 overscrollXDiv.scrollWidth - overscrollXDiv.clientWidth); 124 // Attempt to scroll targetXDiv further to the right. 125 // targetXDiv and overscrollXDiv are already fully scrolled right but the 126 // scroll should not propagate to the document because of 127 // overscroll-behavior-x: contain on overscrollXDiv. 128 let touchEndPromise = new Promise((resolve) => { 129 targetXDiv.addEventListener("touchend", resolve); 130 }); 131 await touchScrollInTarget(100, targetXDiv, 'right'); 132 // The scrollend event should never be fired before the gesture has 133 // completed. 134 await touchEndPromise; 135 136 scrollend_promise = waitForScrollendEvent(t, targetYDiv, 2000); 137 targetYDiv.scrollTop = targetXDiv.scrollHeight; 138 await scrollend_promise; 139 140 scrollend_promise = waitForScrollendEvent(t, overscrollYDiv, 2000); 141 overscrollYDiv.scrollTop = overscrollYDiv.scrollHeight; 142 await scrollend_promise; 143 vertical_scrollend_arrived = false; 144 145 assert_equals(targetYDiv.scrollTop, 146 targetYDiv.scrollHeight - targetYDiv.clientHeight); 147 assert_equals(overscrollYDiv.scrollTop, 148 overscrollYDiv.scrollHeight - overscrollYDiv.clientHeight); 149 // Attempt to scroll targetYDiv further down. 150 // targetYDiv and overscrollYDiv are already fully scrolled down but the 151 // scroll should not propagate to the document because of 152 // overscroll-behavior-y: none on overscrollYDiv. 153 touchEndPromise = new Promise((resolve) => { 154 targetYDiv.addEventListener("touchend", resolve); 155 }); 156 await touchScrollInTarget(50, targetYDiv, 'down'); 157 // The scrollend event should never be fired before the gesture has 158 // completed. 159 await touchEndPromise; 160 161 // Ensure we wait at least a tick after the touch end. 162 await waitForCompositorCommit(); 163 164 // We should not trigger a scrollend event for a scroll that did not 165 // change the scroll position. 166 assert_equals(horizontal_scrollend_arrived, false, 167 "overscrollXDiv should not receive scrollend"); 168 assert_equals(vertical_scrollend_arrived, false, 169 "overscrollYDiv should not receive scrollend"); 170 }, "Tests that the scroll is not propagated beyond div with non-auto " + 171 "overscroll-behavior."); 172 } 173 </script>