Source code

Revision control

Copy as Markdown

Other Tools

<!DOCTYPE html>
<html>
<title>A scroll over an iframe should not terminate the wheel transaction</title>
<script type="application/javascript" src="apz_test_utils.js"></script>
<script type="application/javascript" src="apz_test_native_event_utils.js"></script>
<script src="/tests/SimpleTest/paint_listener.js"></script>
<head>
<style>
body {
height: 250vh;
width: 100%;
margin: 0;
padding: 0;
}
#spacer {
height: 150px;
width: 100vw;
background: yellow;
}
#subframe {
width: 80vw;
height: 100vh;
}
</style>
</head>
<body>
<div id="spacer"></div>
<iframe id="subframe">
</iframe>
</body>
<script>
const searchParams = new URLSearchParams(location.search);
const GESTURE_Y = 120;
async function scrollWithPan() {
let transformEndPromise = promiseTransformEnd();
await NativePanHandler.promiseNativePanEvent(
window,
150,
GESTURE_Y,
0,
NativePanHandler.delta * 0.5,
NativePanHandler.beginPhase,
);
// The iframe we need to scroll over is 30 CSS pixels lower than the original
// gesture location. We need to perform at least one pan gesture update after
// we have scrolled at least 30 CSS pixels.
await SimpleTest.promiseWaitForCondition(async () => {
let scrollOffset = window.scrollY;
await NativePanHandler.promiseNativePanEvent(
window,
150,
GESTURE_Y,
0,
NativePanHandler.delta * 0.5,
NativePanHandler.updatePhase,
);
await promiseFrame();
await promiseApzFlushedRepaints();
return scrollOffset > 50;
}, "Scroll at least once over the iframe");
await NativePanHandler.promiseNativePanEvent(
window,
150,
GESTURE_Y,
0,
NativePanHandler.delta,
NativePanHandler.endPhase,
);
await transformEndPromise;
}
async function scrollWithWheel() {
let transformEndPromise = promiseTransformEnd();
await promiseMoveMouseAndScrollWheelOver(window, 150, GESTURE_Y, false, 20);
// The iframe we need to scroll over is 30 CSS pixels lower than the original
// gesture location. We need to perform at least one mousewheel scroll after
// we have scrolled at least 30 CSS pixels.
await SimpleTest.promiseWaitForCondition(async () => {
let scrollOffset = window.scrollY;
// While promiseMoveMouseAndScrollWheelOver uses a positive value to scroll
// down, synthesizeNativeWheel uses a negative value to scroll down.
await synthesizeNativeWheel(window, 150, GESTURE_Y, 0, -20, null);
await promiseFrame();
await promiseApzFlushedRepaints();
return scrollOffset > 50;
}, "Scroll at least once over the iframe");
await transformEndPromise;
}
async function test() {
let iframeURL =
SimpleTest.getTestFileURL("helper_scroll_over_subframe_child.html");
switch (searchParams.get("oop")) {
case "true":
iframeURL = iframeURL.replace(window.location.origin, "https://example.com/");
break;
default:
break;
}
const iframeLoadPromise = promiseOneEvent(subframe, "load", null);
subframe.src = iframeURL;
await iframeLoadPromise;
await SpecialPowers.spawn(subframe, [], async () => {
await content.wrappedJSObject.waitUntilApzStable();
await SpecialPowers.contentTransformsReceived(content);
});
let childWindowReceivedWheelEvent = false;
window.addEventListener("message", e => {
if (e.data == "child-received-wheel-event") {
childWindowReceivedWheelEvent = true;
}
});
await SpecialPowers.spawn(subframe, [], () => {
let target = content.document.getElementById("target")
target.style.backgroundColor = "green";
content.getComputedStyle(target).backgroundColor;
target.addEventListener("wheel", () => {
target.style.backgroundColor = "red";
content.getComputedStyle(target).backgroundColor;
});
return new Promise(resolve => resolve());
});
await promiseFrame();
// Scroll over the iframe
switch (searchParams.get("scroll")) {
case "wheel":
await scrollWithWheel();
break;
case "pan":
await scrollWithPan();
break;
default:
ok(false, "Unsupported scroll value: " + searchParams.get("scroll"));
break;
}
// Wait an extra frame to ensure any message from the child has
// extra time to be sent to the parent.
await promiseFrame();
let res = await SpecialPowers.spawn(subframe, [], () => {
let target = content.document.getElementById("target")
return target.style.backgroundColor;
});
await promiseFrame();
// We should not have fired a wheel event to the element in the iframe
ok(!childWindowReceivedWheelEvent, "Child window should not receive wheel events");
is(res, "green", "OOP iframe does not halt user scroll of parent");
}
waitUntilApzStable().then(test).then(subtestDone, subtestFailed);
</script>
</html>