helper_hittest_overscroll_subframe.html (4229B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <title>Test APZ hit-testing while overscrolled</title> 5 <script type="application/javascript" src="apz_test_utils.js"></script> 6 <script type="application/javascript" src="apz_test_native_event_utils.js"></script> 7 <script src="/tests/SimpleTest/paint_listener.js"></script> 8 <meta name="viewport" content="width=device-width"/> 9 <style> 10 html, body { 11 margin: 0; 12 padding: 0; 13 } 14 #subframe { 15 width: 100px; 16 height: 100px; 17 overflow: scroll; 18 } 19 .spacer { 20 height: 5000px; 21 } 22 #target { 23 margin-left: 20px; 24 margin-top: 2px; 25 height: 4px; 26 width: 4px; 27 background: red; 28 } 29 </style> 30 </head> 31 <body> 32 <div id="subframe"> 33 <div id="target"></div> 34 <div class="spacer"></div> 35 </div> 36 <div class="spacer"></div> 37 </body> 38 <script type="application/javascript"> 39 40 async function test() { 41 var config = getHitTestConfig(); 42 var utils = config.utils; 43 44 // Subframe hit testing of overscrolled APZCs does not yet work with WebRender 45 // (bug 1701831), so bail out early. 46 if (true) { 47 todo(false, "This test does not currently pass with WebRender"); 48 return; 49 } 50 51 // Activate the subframe. This both matches reality (if you're 52 // scrolling the subframe, it's active), and makes it easier 53 // to check for expected hit test outcomes. 54 utils.setDisplayPortForElement(0, 0, 500, 500, subframe, 1); 55 await promiseApzFlushedRepaints(); 56 57 // Overscroll the subframe at the top, creating a gutter. 58 // Note that the size of the gutter will only be 8px, because 59 // setAsyncScrollOffset() applies the overscroll as a single delta, 60 // and current APZ logic that transforms a delta into an overscroll 61 // amount limits each delta to at most 8px. 62 utils.setAsyncScrollOffset(subframe, 0, -200); 63 64 // Check that the event hits the subframe frame in APZ. 65 // This is important because additional pan-gesture events in the gutter 66 // should continue to be handled and cause further overscroll (or 67 // relieving overscroll, depending on their direction). 68 let subframeBounds = subframe.getBoundingClientRect(); 69 hitResult = hitTest({ 70 x: subframeBounds.x + 50, 71 y: subframeBounds.y + 4 72 }); 73 let subframeViewId = utils.getViewId(subframe); 74 checkHitResult(hitResult, 75 APZHitResultFlags.VISIBLE, 76 subframeViewId, 77 utils.getLayersId(), 78 "APZ hit-test in the subframe gutter"); 79 80 // Now, perform a click in the gutter and check that APZ prevents 81 // the event from reaching Gecko. 82 // To be sure that no event was dispatched to Gecko, install the listener 83 // on the document, not the subframe. 84 // This makes sure we catch the case where the overscroll transform causes 85 // the event to incorrectly target the document. 86 let receivedClick = false; 87 let listener = function() { 88 receivedClick = true; 89 }; 90 document.addEventListener("click", listener); 91 await synthesizeNativeMouseEventWithAPZ({ 92 type: "click", 93 target: subframe, 94 offsetX: 50, 95 offsetY: 4 96 }); 97 // Wait 10 frames for the event to maybe arrive, and if it 98 // hasn't, assume it won't. 99 for (let i = 0; i < 10; i++) { 100 await promiseFrame(); 101 } 102 info("Finished waiting around for click event"); 103 ok(!receivedClick, "Gecko received click event when it shouldn't have"); 104 document.removeEventListener("click", listener); 105 106 // Finally, while still overscrolled, perform a click not in the gutter. 107 // This event should successfully go through to the web content, and 108 // be untransformed by the overscroll transform (such that it hits the 109 // content that is visually under the cursor). 110 let clickPromise = new Promise(resolve => { 111 document.addEventListener("click", function(e) { 112 info("event clientX = " + e.clientX); 113 info("event clientY = " + e.clientY); 114 is(e.target, target, "Click while overscrolled hit intended target"); 115 resolve(); 116 }, { once: true }); 117 }); 118 await synthesizeNativeMouseEventWithAPZ({ 119 type: "click", 120 target: window, 121 offsetX: 22, 122 offsetY: 12 123 }); 124 await clickPromise; 125 } 126 127 waitUntilApzStable() 128 .then(test) 129 .then(subtestDone, subtestFailed); 130 131 </script> 132 </html>