scrollsnapchanging-after-layout-change.tentative.html (4066B)
1 <!DOCTYPE html> 2 <html> 3 <head> 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="/dom/events/scrolling/scroll_support.js"></script> 10 <script src="/css/css-scroll-snap/snap-events/resources/common.js"></script> 11 <script src="/css/css-scroll-snap/snap-events/resources/user-scroll-common.js"></script> 12 <script src="/web-animations/testcommon.js"></script> 13 <style> 14 body { 15 margin: 0px; 16 } 17 #space { 18 height: 200vh; 19 width: 200vw; 20 } 21 .scroller { 22 scroll-snap-type: x mandatory; 23 overflow-x: auto; 24 overflow-y: hidden; 25 position: relative; 26 height: 500px; 27 width: 500px; 28 } 29 30 .box { 31 scroll-snap-align: start; 32 height: 100px; 33 width: 100px; 34 position: absolute; 35 top: 200px; 36 } 37 38 #box1 { 39 background-color: red; 40 } 41 42 #box2 { 43 background-color: yellow; 44 left: 200px; 45 } 46 47 #box3 { 48 background-color: blue; 49 left: 400px; 50 } 51 </style> 52 </head> 53 <body> 54 <div id="scroller" class="scroller"> 55 <div id="space"></div> 56 <div id="box1" class="box"><h1>1</h1></div> 57 <div id="box2" class="box"><h1>2</h1></div> 58 <div id="box3" class="box"><h1>3</h1></div> 59 </div> 60 <script> 61 const scroller = document.getElementById("scroller"); 62 promise_test(async (t) => { 63 // This tests scrollsnapchanging firing after a layout change in the middle of a 64 // touch scroll. We start a touch scroll far enough that scrollsnapchanging 65 // fires and then, with the pointer still down, we change the layout so 66 // that scrollsnapchanging should fire with a different target. 67 await waitForScrollReset(t, scroller); 68 await waitForCompositorCommit(); 69 70 const start_pos_x = Math.round(box2.offsetLeft); 71 // Drag by enough to ensure box2 is the preferred snap target. 72 const drag_amt = Math.round(box2.offsetLeft / 2) + 50; 73 const end_pos_x = start_pos_x - drag_amt; 74 const pos_y = Math.round(scroller.clientHeight / 2); 75 let evt_promise; 76 let snap_evt; 77 78 const save_scrollsnapchanging_evt = (evt) => { snap_evt = evt; } 79 evt_promise = scroller.addEventListener("scrollsnapchanging", 80 save_scrollsnapchanging_evt); 81 // We wait to reach the expected scroll position rather than waiting for a 82 // scrollsnapchanging event to avoid timing out if the scrollsnapchanging event does 83 // not fire. 84 const scroll_promise = new Promise((resolve) => { 85 scroller.addEventListener("scroll", async () => { 86 if (scroller.scrollLeft >= (box2.offsetLeft / 2)) { 87 await waitForAnimationFrames(2); 88 resolve(); 89 } 90 }); 91 }); 92 93 await new test_driver.Actions() 94 .addPointer("TestPointer", "touch") 95 .pointerMove(start_pos_x, pos_y) 96 .pointerDown() 97 .addTick() 98 .pause(200) 99 // Drag closer to box2, which should trigger a scrollsnapchanging event. 100 .pointerMove(start_pos_x - drag_amt, pos_y) 101 .send(); 102 103 // assert scrollsnapchanging that should have already happened. 104 await scroll_promise; 105 assertSnapEvent(snap_evt, { block: null, inline: box2 }); 106 107 evt_promise = waitForSnapEvent(scroller, "scrollsnapchanging", false); 108 // Change layout while pointer is still down. 109 let box2_prev_left = getComputedStyle(box2).getPropertyValue("left"); 110 let box3_prev_left = getComputedStyle(box3).getPropertyValue("left"); 111 box2.style.left = box3_prev_left; 112 box3.style.left = box2_prev_left; 113 snap_evt = await evt_promise; 114 assertSnapEvent(snap_evt, { block: null, inline: box3 }); 115 }, "scrollsnapchanging fires after layout change"); 116 </script> 117 </body> 118 </html>