helper_tap_passive.html (2822B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <meta name="viewport" content="width=device-width; initial-scale=1.0"> 6 <title>Ensure APZ doesn't wait for passive listeners</title> 7 <script type="application/javascript" src="apz_test_native_event_utils.js"></script> 8 <script type="application/javascript" src="apz_test_utils.js"></script> 9 <script src="/tests/SimpleTest/paint_listener.js"></script> 10 <script type="application/javascript"> 11 12 var touchdownTime; 13 14 async function longPressLink() { 15 await synthesizeNativeTouch(document.getElementById("b"), 5, 5, SpecialPowers.DOMWindowUtils.TOUCH_CONTACT, function() { 16 dump("Finished synthesizing touch-start, waiting for events...\n"); 17 }); 18 } 19 20 var touchstartReceived = false; 21 function recordEvent(e) { 22 if (!touchstartReceived) { 23 touchstartReceived = true; 24 is(e.type, "touchstart", "Got a touchstart"); 25 e.preventDefault(); // should be a no-op because it's a passive listener 26 return; 27 } 28 29 // If APZ decides to wait for the content response on a particular input block, 30 // it needs to wait until both the touchstart and touchmove event are handled 31 // by the main thread. In this case there is no touchmove at all, so APZ would 32 // end up waiting indefinitely and time out the test. The fact that we get this 33 // contextmenu event (mouselongtap on Windows) at all means that APZ decided 34 // not to wait for the content response, which is the desired behaviour, since 35 // the touchstart listener was registered as a passive listener. 36 if (getPlatform() == "windows") { 37 is(e.type, "mouselongtap", "Got a mouselongtap"); 38 } else { 39 is(e.type, "contextmenu", "Got a contextmenu"); 40 } 41 e.preventDefault(); 42 43 setTimeout(async () => { 44 // On Windows below TOUCH_REMOVE event triggers opening a context menu, we 45 // need to prevent it. 46 const contextmenuPromise = promiseOneEvent(window, "contextmenu", event => { 47 event.preventDefault(); 48 return true; 49 }); 50 const touchendPromise = promiseOneEvent(window, "touchend", () => { 51 return true; 52 }); 53 await synthesizeNativeTouch(document.getElementById("b"), 5, 5, SpecialPowers.DOMWindowUtils.TOUCH_REMOVE, function() { 54 dump("Finished synthesizing touch-end to clear state; finishing test...\n"); 55 }); 56 57 await touchendPromise; 58 if (getPlatform() == "windows") { 59 await contextmenuPromise; 60 } 61 subtestDone(); 62 }, 0); 63 } 64 65 window.addEventListener("touchstart", recordEvent, { passive: true, capture: true }); 66 if (getPlatform() == "windows") { 67 SpecialPowers.addChromeEventListener("mouselongtap", recordEvent, true); 68 } else { 69 window.addEventListener("contextmenu", recordEvent, true); 70 } 71 72 waitUntilApzStable() 73 .then(longPressLink); 74 75 </script> 76 </head> 77 <body> 78 <a id="b" href="#">Link to nowhere</a> 79 </body> 80 </html>