helper_custom_scrolling_bug1932985.html (3086B)
1 <!DOCTYPE HTML> 2 <meta charset="utf-8"> 3 <meta name="viewport" content="width=device-width, minimum-scale=1.0"> 4 <title>Test that a custom scrolling implementation using scrollBy() is 5 not much slower than native wheel event handling</title> 6 <script src="apz_test_utils.js"></script> 7 <script src="apz_test_native_event_utils.js"></script> 8 <script src="/tests/SimpleTest/paint_listener.js"></script> 9 <style> 10 html { 11 scroll-behavior: smooth; 12 } 13 .spacer { 14 height: 2000vh; 15 } 16 </style> 17 <div class="spacer"></div> 18 <script> 19 async function test() { 20 // The test will be sending 10 events and expecting each to 21 // accomplish a full 50 pixels of scrolling. 22 let wheelDelta = 50; 23 let eventCount = 10; 24 let finalDestination = eventCount * wheelDelta; 25 26 // Set up a custom scrolling mechanism which emulates the one in 27 // arrowscrollbox.js in important respects: 28 // - Listen for wheel events but preventDefault() them and scroll 29 // using scrollBy() instead. 30 // - Track the scroll destination in script. 31 // - Reset the destination when a `scrollend` is received. 32 let currentDestination = 0; 33 let isScrolling = false; 34 window.addEventListener("wheel", e => { 35 if (!isScrolling) { 36 currentDestination = window.scrollY; 37 isScrolling = true; 38 } 39 currentDestination += wheelDelta; 40 let delta = currentDestination - window.scrollY; 41 window.scrollBy(0, delta); 42 e.preventDefault(); 43 }, { passive: false }); 44 window.addEventListener("scrollend", () => { 45 isScrolling = false; 46 }); 47 48 // Make sure APZ is aware of the active event listener. 49 await promiseApzFlushedRepaints(); 50 51 // Set up a promise that is resolved when we reach the expected 52 // destination. 53 let destinationPromise = new Promise(resolve => { 54 window.addEventListener("scroll", () => { 55 info(`Scrolled to ${window.scrollY}`); 56 // Use fuzzy comparison with epsilon=1 to account for rounding 57 // of scrollBy() delta to the nearest pixel. This should be fixed 58 // by bug 1674687. 59 if (window.scrollY >= (finalDestination - 1)) { 60 ok(true, "Scroll destination reached"); 61 resolve(); 62 } 63 }); 64 }); 65 66 // Send 10 wheel events in fairly quick succession (one frame between each). 67 let useTouchpad = (location.search == "?touchpad"); 68 for (var i = 0; i < eventCount; i++) { 69 if (useTouchpad) { 70 let phase; 71 if (i == 0) { 72 phase = NativePanHandler.beginPhase; 73 } else if (i == (eventCount - 1)) { 74 phase = NativePanHandler.endPhase; 75 } else { 76 phase = NativePanHandler.updatePhase; 77 } 78 await NativePanHandler.promiseNativePanEvent(window, 50, 50, 0, -50, phase); 79 } else { 80 await synthesizeNativeWheel(window, 50, 50, 0, -50); 81 } 82 await promiseFrame(); 83 } 84 85 // Wait for us to reach the destination. 86 await destinationPromise; 87 } 88 89 waitUntilApzStable() 90 .then(test) 91 .then(subtestDone, subtestFailed); 92 </script>