\
',
},
{ elem: "k", expected: expectScrollBoth },
{ elem: "k", expected: expectScrollNone, testwindow: true },
{ elem: "l", expected: expectScrollNone },
{ elem: "m", expected: expectScrollVert, testwindow: true },
{
dataUri:
'data:text/html,\
\
\
link\
\
\
\
',
},
{ elem: "n", expected: expectScrollNone, testwindow: true },
{ elem: "o", expected: expectScrollNone, testwindow: true },
{
elem: "p",
expected: expectScrollVert,
testwindow: true,
middlemousepastepref: false,
},
{
elem: "q",
expected: expectScrollVert,
testwindow: true,
middlemousepastepref: false,
},
{
dataUri:
'data:text/html,\
\
\
\
',
},
{
elem: "r",
expected: expectScrollNone,
testwindow: true,
middlemousepastepref: true,
},
{
elem: "s",
expected: expectScrollNone,
testwindow: true,
middlemousepastepref: true,
},
{
dataUri:
"data:text/html," +
encodeURIComponent(`
`),
},
{
elem: "i",
// We expect the outer window to scroll vertically, not the iframe's window.
expected: expectScrollVert,
testwindow: true,
},
{
dataUri:
"data:text/html," +
encodeURIComponent(`
`),
},
{
elem: "i",
// We expect the iframe's window to scroll vertically, so the outer window should not scroll.
expected: expectScrollNone,
testwindow: true,
},
{
// Test: scroll is initiated in out of process iframe having no scrollable area
dataUri:
"data:text/html," +
encodeURIComponent(`
`),
},
{
elem: "noscroll-outofprocess-iframe",
// We expect the div to scroll vertically, not the iframe's window.
expected: expectScrollVert,
scrollable: "scroller",
},
];
for (let test of allTests) {
if (test.dataUri) {
let loadedPromise = BrowserTestUtils.browserLoaded(
gBrowser.selectedBrowser
);
BrowserTestUtils.loadURI(gBrowser, test.dataUri);
await loadedPromise;
continue;
}
let prefsChanged = "middlemousepastepref" in test;
if (prefsChanged) {
await pushPrefs([["middlemouse.paste", test.middlemousepastepref]]);
}
await BrowserTestUtils.synthesizeMouse(
"#" + test.elem,
50,
80,
{ button: 1 },
gBrowser.selectedBrowser
);
// This ensures bug 605127 is fixed: pagehide in an unrelated document
// should not cancel the autoscroll.
await ContentTask.spawn(
gBrowser.selectedBrowser,
{ waitForAutoScrollStart: test.expected != expectScrollNone },
async ({ waitForAutoScrollStart }) => {
var iframe = content.document.getElementById("iframe");
if (iframe) {
var e = new iframe.contentWindow.PageTransitionEvent("pagehide", {
bubbles: true,
cancelable: true,
persisted: false,
});
iframe.contentDocument.dispatchEvent(e);
iframe.contentDocument.documentElement.dispatchEvent(e);
}
if (waitForAutoScrollStart) {
await new Promise(resolve =>
Services.obs.addObserver(resolve, "autoscroll-start")
);
}
}
);
is(
document.activeElement,
gBrowser.selectedBrowser,
"Browser still focused after autoscroll started"
);
await BrowserTestUtils.synthesizeMouse(
"#" + test.elem,
100,
100,
{ type: "mousemove", clickCount: "0" },
gBrowser.selectedBrowser
);
if (prefsChanged) {
await SpecialPowers.popPrefEnv();
}
// Start checking for the scroll.
let firstTimestamp = undefined;
let timeCompensation;
do {
let timestamp = await new Promise(resolve =>
window.requestAnimationFrame(resolve)
);
if (firstTimestamp === undefined) {
firstTimestamp = timestamp;
}
// This value is calculated similarly to the value of the same name in
// ClickEventHandler.autoscrollLoop, except here it's cumulative across
// all frames after the first one instead of being based only on the
// current frame.
timeCompensation = (timestamp - firstTimestamp) / 20;
info(
"timestamp=" +
timestamp +
" firstTimestamp=" +
firstTimestamp +
" timeCompensation=" +
timeCompensation
);
// Try to wait until enough time has passed to allow the scroll to happen.
// autoscrollLoop incrementally scrolls during each animation frame, but
// due to how its calculations work, when a frame is very close to the
// previous frame, no scrolling may actually occur during that frame.
// After 100ms's worth of frames, timeCompensation will be 1, making it
// more likely that the accumulated scroll in autoscrollLoop will be >= 1,
// although it also depends on acceleration, which here in this test
// should be > 1 due to how it synthesizes mouse events below.
} while (timeCompensation < 5);
// Close the autoscroll popup by synthesizing Esc.
EventUtils.synthesizeKey("KEY_Escape");
let scrollVert = test.expected & expectScrollVert;
let scrollHori = test.expected & expectScrollHori;
await SpecialPowers.spawn(
gBrowser.selectedBrowser,
[
{
scrollVert,
scrollHori,
elemid: test.scrollable || test.elem,
checkWindow: test.testwindow,
},
],
async function(args) {
let msg = "";
if (args.checkWindow) {
if (
!(
(args.scrollVert && content.scrollY > 0) ||
(!args.scrollVert && content.scrollY == 0)
)
) {
msg += "Failed: ";
}
msg +=
"Window for " +
args.elemid +
" should" +
(args.scrollVert ? "" : " not") +
" have scrolled vertically\n";
if (
!(
(args.scrollHori && content.scrollX > 0) ||
(!args.scrollHori && content.scrollX == 0)
)
) {
msg += "Failed: ";
}
msg +=
" Window for " +
args.elemid +
" should" +
(args.scrollHori ? "" : " not") +
" have scrolled horizontally\n";
} else {
let elem = content.document.getElementById(args.elemid);
if (
!(
(args.scrollVert && elem.scrollTop > 0) ||
(!args.scrollVert && elem.scrollTop == 0)
)
) {
msg += "Failed: ";
}
msg +=
" " +
args.elemid +
" should" +
(args.scrollVert ? "" : " not") +
" have scrolled vertically\n";
if (
!(
(args.scrollHori && elem.scrollLeft > 0) ||
(!args.scrollHori && elem.scrollLeft == 0)
)
) {
msg += "Failed: ";
}
msg +=
args.elemid +
" should" +
(args.scrollHori ? "" : " not") +
" have scrolled horizontally";
}
Assert.ok(!msg.includes("Failed"), msg);
}
);
// Before continuing the test, we need to ensure that the IPC
// message that stops autoscrolling has had time to arrive.
await new Promise(resolve => executeSoon(resolve));
}
// remove 2 tabs that were opened by middle-click on links
while (gBrowser.visibleTabs.length > 1) {
gBrowser.removeTab(gBrowser.visibleTabs[gBrowser.visibleTabs.length - 1]);
}
// wait for focus to fix a failure in the next test if the latter runs too soon.
await SimpleTest.promiseFocus();
});