helper_zoom_out_clamped_scrollpos.html (3995B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <meta name="viewport" content="width=device-width, minimum-scale=1.0"> 6 <title>Tests that zooming out with an unchanging scroll pos still works properly</title> 7 <script src="/tests/SimpleTest/EventUtils.js"></script> 8 <script type="application/javascript" src="apz_test_utils.js"></script> 9 <script type="application/javascript" src="apz_test_native_event_utils.js"></script> 10 <script src="/tests/SimpleTest/paint_listener.js"></script> 11 </head> 12 <body> 13 <div style="height: 2000px; background-color: linear-gradient(green,blue)"></div> 14 <script type="application/javascript"> 15 const utils = SpecialPowers.getDOMWindowUtils(window); 16 17 async function test() { 18 // Initial state 19 is(await getResolution(), 1.0, "should not be zoomed"); 20 21 // Zoom in 22 utils.setResolutionAndScaleTo(2.0); 23 await promiseApzFlushedRepaints(); 24 // Check that we're still at 0,0 in both layout and visual viewport 25 is(await getResolution(), 2.0, "should be zoomed to 2.0"); 26 is(window.scrollX, 0, "shouldn't have scrolled (1)"); 27 is(window.scrollY, 0, "shouldn't have scrolled (2)"); 28 is(visualViewport.pageLeft, 0, "shouldn't have scrolled (3)"); 29 is(visualViewport.pageTop, 0, "shouldn't have scrolled (4)"); 30 31 // Freeze the main-thread refresh driver to stop it from processing 32 // paint requests 33 utils.advanceTimeAndRefresh(0); 34 35 // Zoom out. This will send a series of paint requests to the main 36 // thread with zooms that go down from 2.0 to 1.0. 37 // Use a similar touch sequence to what pinchZoomOutWithTouchAtCenter() 38 // does, except keep the first touch point anchored and only move the 39 // second touch point. In particular, we drag the second touch point 40 // from the top-left quadrant of the screen to the bottom-right, so that 41 // the scroll position never changes from 0,0. If we move either finger 42 // upwards at all, the synthesization can generate intermediate touch 43 // events with just that change which can cause the page to scroll down 44 // which we don't want here. 45 // The key here is that each of the repaint requests keeps the scroll 46 // position at 0,0, which in terms of the bug, means that only the first 47 // repaint request actually takes effect and the rest are discarded. 48 // The first repaint request has a zoom somewhere between 1.0 and 2.0, 49 // and therefore after the pinch is done, the zoom ends up stuck there 50 // instead of going all the way back to 1.0 like we would expect. 51 const deltaX = window.visualViewport.width / 16; 52 const deltaY = window.visualViewport.height / 16; 53 const centerX = 54 window.visualViewport.pageLeft + window.visualViewport.width / 2; 55 const centerY = 56 window.visualViewport.pageTop + window.visualViewport.height / 2; 57 const anchorFinger = { x: centerX + (deltaX * 6), y: centerY + (deltaY * 6) }; 58 var zoom_out = []; 59 for (var i = -6; i < 6; i++) { 60 var movingFinger = { x: centerX + (deltaX * i), y: centerY + (deltaY * i) }; 61 zoom_out.push([anchorFinger, movingFinger]); 62 } 63 var touchIds = [0, 1]; 64 await synthesizeNativeTouchAndWaitForTransformEnd(zoom_out, touchIds); 65 66 // Release the refresh driver 67 utils.restoreNormalRefresh(); 68 69 // Flush all the things, reach stable state 70 await promiseApzFlushedRepaints(); 71 72 // Check that we're back at 1.0 resolution 73 is(await getResolution(), 1.0, "should be back at initial resolution"); 74 75 // More sanity checks 76 is(window.scrollX, 0, "shouldn't have scrolled (5)"); 77 is(window.scrollY, 0, "shouldn't have scrolled (6)"); 78 is(visualViewport.pageLeft, 0, "shouldn't have scrolled (7)"); 79 is(visualViewport.pageTop, 0, "shouldn't have scrolled (8)"); 80 } 81 82 waitUntilApzStable().then(test).then(subtestDone, subtestFailed); 83 </script> 84 </body> 85 </html>