new-scroll-event-dispatched-at-next-updating-rendering-time.html (4080B)
1 <!doctype html> 2 <meta charset="utf-8"> 3 <link rel="help" href="https://html.spec.whatwg.org/#event-loop-processing-model"> 4 <link rel="help" href="https://issues.chromium.org/issues/397737222"> 5 <meta name="viewport" content="width=device-width,initial-scale=1"> 6 <script src="/resources/testharness.js"></script> 7 <script src="/resources/testharnessreport.js"></script> 8 <style> 9 </style> 10 <iframe width="300" height="300" srcdoc=" 11 <style> 12 html { 13 transition: color 1s step-start; 14 } 15 .scroller { 16 overflow: auto; 17 width: 100%; 18 height: 100px; 19 } 20 .spacer { 21 height: 500px; 22 } 23 </style> 24 <div class='scroller'> 25 <div class='spacer'></div> 26 </div> 27 <div class='scroller'> 28 <div class='spacer'></div> 29 </div> 30 "></iframe> 31 <script> 32 promise_test(async function() { 33 await new Promise(resolve => window.addEventListener("load", resolve, { once: true })); 34 35 const iframe = document.querySelector("iframe"); 36 const mql = iframe.contentWindow.matchMedia("(max-width: 300px)"); 37 assert_true(mql.matches, ""); 38 39 // Set up a MQL change event listener to receive the event in between 40 // scroll and transitionrun events. 41 let timeOnMQLChange = null; 42 iframe.width = "400"; 43 const mqlChangeEvent = new Promise(resolve => { 44 mql.addEventListener("change", () => { 45 timeOnMQLChange = performance.now(); 46 resolve(); 47 }, { once: true }); 48 }); 49 50 // There are two scroll containers, setup a scroll event listener for one 51 // of them. 52 const scrollers = iframe.contentDocument.querySelectorAll(".scroller"); 53 let timeOnScrollEventOnAnotherScroller = null; 54 scrollers[1].addEventListener("scroll", () => { 55 timeOnScrollEventOnAnotherScroller = performance.now(); 56 }, { once: true }); 57 58 // Setup another scroll event listener for the other scroll container. 59 const scrollEventPromise = new Promise(resolve => { 60 scrollers[0].addEventListener("scroll", resolve, { once: true }); 61 }); 62 // And scroll the scroller. 63 scrollers[0].scrollTop = 10; 64 65 // Await the scroll event. 66 await scrollEventPromise; 67 68 const timeOnScrollEvent = performance.now(); 69 70 // Scroll the other scroller. 71 scrollers[1].scrollTop = 10; 72 73 assert_equals(timeOnScrollEventOnAnotherScroller, null, 74 "The new scroll event should not yet have been dispatched"); 75 76 // Trigger a CSS transition. 77 let timeOnTransitionRun = null; 78 const transitionrunEventPromise = new Promise(resolve => { 79 iframe.contentDocument.documentElement.addEventListener("transitionrun", () => { 80 timeOnTransitionRun = performance.now(); 81 resolve(); 82 }, { once: true }); 83 }); 84 iframe.contentDocument.documentElement.style.color = "blue"; 85 getComputedStyle(iframe.contentDocument.documentElement).color; 86 87 // Now it's time to receive the MQL change event. 88 await mqlChangeEvent; 89 assert_less_than(timeOnScrollEvent, timeOnMQLChange, 90 "The MQL change event should have been dispatched after the first scroll event"); 91 assert_equals(timeOnScrollEventOnAnotherScroller, null, 92 "The new scroll event should not yet have been dispatched"); 93 94 // Await the transitionrun event. 95 await transitionrunEventPromise; 96 97 assert_less_than(timeOnScrollEvent, timeOnTransitionRun, 98 "The transitionrun event should have been dispatched after the first scroll event"); 99 assert_equals(timeOnScrollEventOnAnotherScroller, null, 100 "The new scroll event should not yet have been dispatched"); 101 102 // Await a requestAnimationFrame callback. 103 await new Promise(resolve => requestAnimationFrame(resolve)); 104 105 assert_equals(timeOnScrollEventOnAnotherScroller, null, 106 "The new scroll event should not yet have been dispatched"); 107 108 // Await one more requestAnimationFrame callback. 109 await new Promise(resolve => requestAnimationFrame(resolve)); 110 111 assert_not_equals(timeOnScrollEventOnAnotherScroller, null, 112 "The new scroll event should now have been dispatched"); 113 assert_less_than(timeOnTransitionRun, timeOnScrollEventOnAnotherScroller, 114 "The new scroll event should have been dispatched after the transitionrun event"); 115 }); 116 </script>