helper_fission_utils.js (3013B)
1 /** 2 * This is similar to the hitTest function in apz_test_utils.js, in that it 3 * does a hit-test for a point and returns the result. The difference is that 4 * in the fission world, the hit-test may land on an OOPIF, which means the 5 * result information will be in the APZ test data for the OOPIF process. This 6 * function checks both the current process and OOPIF process to see which one 7 * got a hit result, and returns the result regardless of which process got it. 8 * The caller is expected to check the layers id which will allow distinguishing 9 * the two cases. 10 */ 11 async function hitTestOOPIF(point, iframeElement) { 12 let getIframeCompositorTestData = async iframe => { 13 let data = await SpecialPowers.spawn(iframe, [], () => { 14 let utils = SpecialPowers.getDOMWindowUtils(content.window); 15 return JSON.stringify(utils.getCompositorAPZTestData()); 16 }); 17 18 return JSON.parse(data); 19 }; 20 21 let utils = SpecialPowers.getDOMWindowUtils(window); 22 23 // Get the test data before doing the actual hit-test, to get a baseline 24 // of what we can ignore. 25 let oldParentTestData = utils.getCompositorAPZTestData(); 26 let oldIframeTestData = await getIframeCompositorTestData(iframeElement); 27 28 let hittestPromise = SpecialPowers.spawnChrome([], () => { 29 return new Promise(resolve => { 30 browsingContext.topChromeWindow.addEventListener( 31 "MozMouseHittest", 32 () => { 33 resolve(); 34 }, 35 { once: true } 36 ); 37 }); 38 }); 39 await SpecialPowers.executeAfterFlushingMessageQueue(); 40 41 // Now do the hit-test 42 dump(`Hit-testing point (${point.x}, ${point.y}) in fission context\n`); 43 SpecialPowers.wrap(window).synthesizeMouseEvent( 44 "MozMouseHittest", 45 point.x, 46 point.y, 47 {}, 48 { ignoreRootScrollFrame: true } 49 ); 50 51 await hittestPromise; 52 53 // Collect the new test data 54 let newParentTestData = utils.getCompositorAPZTestData(); 55 let newIframeTestData = await getIframeCompositorTestData(iframeElement); 56 57 // See which test data has new hit results 58 let hitResultCount = testData => { 59 return Object.keys(testData.hitResults).length; 60 }; 61 62 let hitIframe = 63 hitResultCount(newIframeTestData) > hitResultCount(oldIframeTestData); 64 let hitParent = 65 hitResultCount(newParentTestData) > hitResultCount(oldParentTestData); 66 67 // Extract the results from the appropriate test data 68 let lastHitResult = testData => { 69 let lastHit = 70 testData.hitResults[Object.keys(testData.hitResults).length - 1]; 71 return { 72 hitInfo: lastHit.hitResult, 73 scrollId: lastHit.scrollId, 74 layersId: lastHit.layersId, 75 }; 76 }; 77 if (hitIframe && hitParent) { 78 throw new Error( 79 "Both iframe and parent got hit-results, that is unexpected!" 80 ); 81 } else if (hitIframe) { 82 return lastHitResult(newIframeTestData); 83 } else if (hitParent) { 84 return lastHitResult(newParentTestData); 85 } else { 86 throw new Error( 87 "Neither iframe nor parent got the hit-result, that is unexpected!" 88 ); 89 } 90 }