scrollend-event-fired-for-scrollIntoView.html (6945B)
1 <!DOCTYPE HTML> 2 <meta name="timeout" content="long"> 3 <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1"> 4 <script src="/resources/testharness.js"></script> 5 <script src="/resources/testharnessreport.js"></script> 6 <script src="/resources/testdriver.js"></script> 7 <script src="/resources/testdriver-actions.js"></script> 8 <script src="/resources/testdriver-vendor.js"></script> 9 <script src="/common/subset-tests-by-key.js"></script> 10 <meta name="variant" content="?include=subframe-inline-end-block-end-behavior-auto"/> 11 <meta name="variant" content="?include=subframe-inline-start-block-start-behavior-smooth"/> 12 <meta name="variant" content="?include=root-inline-end-block-end-behavior-auto"/> 13 <meta name="variant" content="?include=root-inline-start-block-start-behavior-smooth"/> 14 <meta name="variant" content="?include=nested-scrollIntoView"/> 15 <script src="scroll_support.js"></script> 16 <style> 17 html { 18 height: 3000px; 19 width: 3000px; 20 } 21 #targetDiv { 22 width: 200px; 23 height: 200px; 24 overflow: scroll; 25 } 26 27 #innerDiv { 28 width: 400px; 29 height: 400px; 30 } 31 </style> 32 33 <body style="margin:0" onload=runTest()> 34 <div id="targetDiv"> 35 <div id="innerDiv"> 36 </div> 37 </div> 38 </body> 39 <script> 40 let element_scrollend_arrived = false; 41 let document_scrollend_arrived = false; 42 43 function onElementScrollEnd(event) { 44 assert_false(event.cancelable); 45 assert_false(event.bubbles); 46 element_scrollend_arrived = true; 47 } 48 49 function onDocumentScrollEnd(event) { 50 assert_false(event.cancelable); 51 // scrollend events are bubbled when the target node is document. 52 assert_true(event.bubbles); 53 document_scrollend_arrived = true; 54 } 55 56 let root_element = document.scrollingElement; 57 let target_div = document.getElementById("targetDiv"); 58 let inner_div = document.getElementById("innerDiv"); 59 60 // Get expected position for root_element scrollIntoView. 61 root_element.scrollTo(10000, 10000); 62 let max_root_x = root_element.scrollLeft; 63 let max_root_y = root_element.scrollTop; 64 root_element.scrollTo(0, 0); 65 66 target_div.scrollTo(10000, 10000); 67 let max_element_x = target_div.scrollLeft; 68 let max_element_y = target_div.scrollTop; 69 target_div.scrollTo(0, 0); 70 71 let test_cases = [ 72 { 73 key: "subframe-inline-end-block-end-behavior-auto", 74 args: { inline: "end", block: "end", behavior: "smooth" }, 75 target: target_div, 76 scroll_target: inner_div, 77 expected: { 78 pos: { x: max_element_x, y: max_element_y }, 79 }, 80 title: "Tests scrollend event for scrollIntoView with behavior 'auto' on subframe.", 81 }, 82 { 83 key: "subframe-inline-start-block-start-behavior-smooth", 84 args: { inline: "start", block: "start", behavior: "auto" }, 85 target: target_div, 86 scroll_target: inner_div, 87 expected: { 88 pos: { x: 0, y: 0 }, 89 }, 90 title: "Tests scrollend event for scrollIntoView with behavior 'smooth' on subframe.", 91 }, 92 { 93 key: "root-inline-end-block-end-behavior-auto", 94 args: { inline: "end", block: "end", behavior: "smooth" }, 95 target: document.scrollingElement, 96 scroll_target: document.scrollingElement, 97 expected: { 98 pos: { x: max_root_x, y: max_root_y }, 99 }, 100 title: "Tests scrollend event for scrollIntoView with behavior 'auto' on root.", 101 }, 102 { 103 key: "root-inline-start-block-start-behavior-smooth", 104 args: { inline: "start", block: "start", behavior: "auto" }, 105 target: document.scrollingElement, 106 scroll_target: document.scrollingElement, 107 expected: { 108 pos: { x: 0, y: 0 }, 109 }, 110 title: "Tests scrollend event for scrollIntoView with behavior 'smooth' on root.", 111 }, 112 ]; 113 114 function runTest() { 115 async function testScrollIntoView(testInfo, t) { 116 let test_start = { x: 0, y: 0 }; 117 if (testInfo.args.inline == "start") { 118 test_start.x = 10000; 119 } 120 if (testInfo.args.block == "start") { 121 test_start.y = 10000; 122 } 123 124 if (test_start.x != 0 || test_start.y != 0) { 125 testInfo.target.scrollTo(test_start.x, test_start.y); 126 } 127 128 await waitForCompositorCommit(); 129 130 targetDiv.addEventListener("scrollend", onElementScrollEnd); 131 document.addEventListener("scrollend", onDocumentScrollEnd); 132 133 await waitForCompositorCommit(); 134 135 testInfo.scroll_target.scrollIntoView({ inline: testInfo.args.inline, 136 block: testInfo.args.block, 137 behavior: testInfo.args.behavior }); 138 139 await waitFor( 140 () => { return element_scrollend_arrived || document_scrollend_arrived; }, 141 testInfo.target.tagName + ".scrollIntoView did not receive scrollend event." 142 ); 143 144 assert_equals(testInfo.target.scrollLeft, testInfo.expected.pos.x, 145 testInfo.target.tagName + ".scrollIntoView scrollLeft"); 146 assert_equals(testInfo.target.scrollTop, testInfo.expected.pos.y, 147 testInfo.target.tagName + ".scrollIntoView scrollTop"); 148 149 if (testInfo.target == root_element) { 150 assert_false(element_scrollend_arrived, 151 "root element targetted, but element scrollend arrived"); 152 } else { 153 assert_false(document_scrollend_arrived, 154 "subframe targetted, but document scrollend arrived"); 155 } 156 } 157 158 test_cases.forEach((test_info) => { 159 subsetTestByKey(test_info.key, promise_test, 160 async (t) => testScrollIntoView(test_info, t), test_info.title); 161 }); 162 163 subsetTestByKey( 164 "nested-scrollIntoView", 165 promise_test, 166 async (t) => { 167 await waitForCompositorCommit(); 168 169 document.addEventListener("scrollend", onDocumentScrollEnd); 170 target_div.addEventListener("scrollend", onElementScrollEnd); 171 172 await waitForCompositorCommit(); 173 174 document.body.removeChild(target_div); 175 let out_div = document.createElement("div"); 176 out_div.style = "width: 100px; height:100px; overflow:scroll; scroll-behavior:smooth;"; 177 out_div.appendChild(target_div); 178 document.body.appendChild(out_div); 179 await waitForCompositorCommit(); 180 181 inner_div.scrollIntoView({ inline: "end", block: "end", behavior: "auto" }); 182 const scrollend_events = [ 183 waitForScrollendEventNoTimeout(out_div), 184 waitForScrollendEventNoTimeout(target_div) 185 ]; 186 await Promise.all(scrollend_events); 187 assert_equals(root_element.scrollLeft, 0, "Nested scrollIntoView root_element scrollLeft"); 188 assert_equals(root_element.scrollTop, 0, "Nested scrollIntoView root_element scrollTop"); 189 assert_equals(out_div.scrollLeft, 100, "Nested scrollIntoView out_div scrollLeft"); 190 assert_equals(out_div.scrollTop, 100, "Nested scrollIntoView out_div scrollTop"); 191 assert_equals(target_div.scrollLeft, max_element_x, "Nested scrollIntoView target_div scrollLeft"); 192 assert_equals(target_div.scrollTop, max_element_y, "Nested scrollIntoView target_div scrollTop"); 193 assert_false(document_scrollend_arrived); 194 }, 195 "Tests scrollend event for nested scrollIntoView.", 196 ); 197 } 198 199 </script>