Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

<!DOCTYPE HTML>
<html id="root">
<head>
<title>Test for MozMousePixelScroll events</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="/tests/SimpleTest/paint_listener.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
<style>
html, body { margin: 0 }
.scrollable {
overflow: auto;
line-height: 1;
margin: 15px;
box-sizing: border-box;
}
.scrollable > div {
width: 1000px;
height: 1000px;
font-size: 1000px;
line-height: 1;
}
/* Ensure viewport is scrollable */
.viewport-padding { height: 200vh; width: 200vh; }
</style>
</head>
<body>
<p id="display"></p>
<div id="Scrollable128" class="scrollable" style="font-size: 128px; width: 100px; height: 100px;">
<div>
<div id="Scrollable96" class="scrollable" style="font-size: 96px; width: 150px; height: 150px;">
<div>
<div id="Scrollable64" class="scrollable" style="font-size: 64px; width: 200px; height: 200px;">
<div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="Scrollable32" class="scrollable" style="font-size: 32px; width: 50px; height: 50px;">
<div>
</div>
</div>
<div class="viewport-padding"></div>
<div id="content" style="display: none"></div>
<pre id="test">
<script>
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(startTest, window);
var gScrollable128 = document.getElementById("Scrollable128");
var gScrollable96 = document.getElementById("Scrollable96");
var gScrollable64 = document.getElementById("Scrollable64");
var gScrollable32 = document.getElementById("Scrollable32");
var gRoot = document.documentElement;
// TODO(emilio): page scrolling seems to interact weirdly with
// Android (probably due to the visual viewport? but I can't repro
// on the emulator). It's probably not a big deal though since you
// can't usually do page scrolling on Android, and chances are
// actual behavior is correct and we just need to tweak the test.
const kIsAndroid = navigator.userAgent.includes("Android");
function* prepareScrollUnits()
{
var result = -1;
function handler(aEvent)
{
result = aEvent.detail;
aEvent.preventDefault();
setTimeout(runTest, 0);
}
window.addEventListener("MozMousePixelScroll", handler, { capture: true, passive: false });
yield waitForAllPaints(function () { setTimeout(runTest, 0); });
yield synthesizeWheel(gScrollable128, 10, 10,
{ deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaY: 1.0, lineOrPageDeltaY: 1 });
gScrollable128.wheelLineHeight = result;
ok(result > 96 && result < 200, "prepareScrollUnits: gScrollable128.wheelLineHeight may be illegal value, got " + result);
result = -1;
yield synthesizeWheel(gScrollable96, 10, 10,
{ deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaY: 1.0, lineOrPageDeltaY: 1 });
gScrollable96.wheelLineHeight = result;
ok(result > 64 && result < gScrollable128.wheelLineHeight, "prepareScrollUnits: gScrollable96.wheelLineHeight may be illegal value, got " + result);
result = -1;
yield synthesizeWheel(gScrollable64, 10, 10,
{ deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaY: 1.0, lineOrPageDeltaY: 1 });
gScrollable64.wheelLineHeight = result;
ok(result > 32 && result < gScrollable96.wheelLineHeight, "prepareScrollUnits: gScrollable64.wheelLineHeight may be illegal value, got " + result);
result = -1;
yield synthesizeWheel(gScrollable32, 10, 10,
{ deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaY: 1.0, lineOrPageDeltaY: 1 });
gScrollable32.wheelLineHeight = result;
ok(result > 16 && result < gScrollable64.wheelLineHeight, "prepareScrollUnits: gScrollable32.wheelLineHeight may be illegal value, got " + result);
result = -1;
yield synthesizeWheel(gRoot, 10, 10,
{ deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaY: 1.0, lineOrPageDeltaY: 1 });
gRoot.wheelLineHeight = result;
ok(result > 10 && result < gScrollable32.wheelLineHeight, "prepareScrollUnits: gRoot.wheelLineHeight may be illegal value, got " + result);
result = -1;
yield synthesizeWheel(gScrollable128, 10, 10,
{ deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaX: 1.0, lineOrPageDeltaX: 1 });
gScrollable128.wheelHorizontalLine = result;
ok(result > 50 && result < 200, "prepareScrollUnits: gScrollable128.wheelHorizontalLine may be illegal value, got " + result);
result = -1;
yield synthesizeWheel(gScrollable96, 10, 10,
{ deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaX: 1.0, lineOrPageDeltaX: 1 });
gScrollable96.wheelHorizontalLine = result;
ok(result > 30 && result < gScrollable128.wheelHorizontalLine, "prepareScrollUnits: gScrollable96.wheelHorizontalLine may be illegal value, got " + result);
result = -1;
yield synthesizeWheel(gScrollable64, 10, 10,
{ deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaX: 1.0, lineOrPageDeltaX: 1 });
gScrollable64.wheelHorizontalLine = result;
ok(result > 20 && result < gScrollable96.wheelHorizontalLine, "prepareScrollUnits: gScrollable64.wheelHorizontalLine may be illegal value, got " + result);
result = -1;
yield synthesizeWheel(gScrollable32, 10, 10,
{ deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaX: 1.0, lineOrPageDeltaX: 1 });
gScrollable32.wheelHorizontalLine = result;
ok(result > 12 && result < gScrollable64.wheelHorizontalLine, "prepareScrollUnits: gScrollable32.wheelHorizontalLine may be illegal value, got " + result);
result = -1;
yield synthesizeWheel(gRoot, 10, 10,
{ deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaX: 1.0, lineOrPageDeltaX: 1 });
gRoot.wheelHorizontalLine = result;
ok(result > 5 && result < gScrollable32.wheelHorizontalLine, "prepareScrollUnits: gRoot.wheelHorizontalLine may be illegal value, got " + result);
result = -1;
yield synthesizeWheel(gScrollable128, 10, 10,
{ deltaMode: WheelEvent.DOM_DELTA_PAGE,
deltaY: 1.0, lineOrPageDeltaY: 1 });
gScrollable128.wheelPageHeight = result;
ok(result >= (100 - gScrollable128.wheelLineHeight * 2) && result <= 100,
"prepareScrollUnits: gScrollable128.wheelPageHeight is strange value, got " + result);
result = -1;
yield synthesizeWheel(gScrollable96, 10, 10,
{ deltaMode: WheelEvent.DOM_DELTA_PAGE,
deltaY: 1.0, lineOrPageDeltaY: 1 });
gScrollable96.wheelPageHeight = result;
ok(result >= (150 - gScrollable96.wheelLineHeight * 2) && result <= 150,
"prepareScrollUnits: gScrollable96.wheelPageHeight is strange value, got " + result);
result = -1;
yield synthesizeWheel(gScrollable64, 10, 10,
{ deltaMode: WheelEvent.DOM_DELTA_PAGE,
deltaY: 1.0, lineOrPageDeltaY: 1 });
gScrollable64.wheelPageHeight = result;
ok(result >= (200 - gScrollable64.wheelLineHeight * 2) && result <= 200,
"prepareScrollUnits: gScrollable64.wheelPageHeight is strange value, got " + result);
result = -1;
yield synthesizeWheel(gScrollable32, 10, 10,
{ deltaMode: WheelEvent.DOM_DELTA_PAGE,
deltaY: 1.0, lineOrPageDeltaY: 1 });
gScrollable32.wheelPageHeight = result;
ok(result >= (50 - gScrollable32.wheelLineHeight * 2) && result <= 50,
"prepareScrollUnits: gScrollable32.wheelPageHeight is strange value, got " + result);
result = -1;
yield synthesizeWheel(gRoot, 10, 10,
{ deltaMode: WheelEvent.DOM_DELTA_PAGE,
deltaY: 1.0, lineOrPageDeltaY: 1 });
gRoot.wheelPageHeight = result;
if (!kIsAndroid) {
ok(window.innerHeight - result < 100 && window.innerHeight - result > 0,
"prepareScrollUnits: gRoot.wheelPageHeight is strange value, got " + result);
}
result = -1;
yield synthesizeWheel(gScrollable128, 10, 10,
{ deltaMode: WheelEvent.DOM_DELTA_PAGE,
deltaX: 1.0, lineOrPageDeltaX: 1 });
gScrollable128.wheelPageWidth = result;
ok(result >= (100 - gScrollable128.wheelLineHeight * 2) && result <= 100,
"prepareScrollUnits: gScrollable128.wheelPageWidth is strange value, got " + result);
result = -1;
yield synthesizeWheel(gScrollable96, 10, 10,
{ deltaMode: WheelEvent.DOM_DELTA_PAGE,
deltaX: 1.0, lineOrPageDeltaX: 1 });
gScrollable96.wheelPageWidth = result;
ok(result >= (150 - gScrollable96.wheelLineHeight * 2) && result <= 150,
"prepareScrollUnits: gScrollable96.wheelPageWidth is strange value, got " + result);
result = -1;
yield synthesizeWheel(gScrollable64, 10, 10,
{ deltaMode: WheelEvent.DOM_DELTA_PAGE,
deltaX: 1.0, lineOrPageDeltaX: 1 });
gScrollable64.wheelPageWidth = result;
ok(result >= (200 - gScrollable64.wheelLineHeight * 2) && result <= 200,
"prepareScrollUnits: gScrollable64.wheelPageWidth is strange value, got " + result);
result = -1;
yield synthesizeWheel(gScrollable32, 10, 10,
{ deltaMode: WheelEvent.DOM_DELTA_PAGE,
deltaX: 1.0, lineOrPageDeltaX: 1 });
gScrollable32.wheelPageWidth = result;
ok(result >= (50 - gScrollable32.wheelLineHeight * 2) && result <= 50,
"prepareScrollUnits: gScrollable32.wheelPageWidth is strange value, got " + result);
result = -1;
yield synthesizeWheel(gRoot, 10, 10,
{ deltaMode: WheelEvent.DOM_DELTA_PAGE,
deltaX: 1.0, lineOrPageDeltaX: 1 });
gRoot.wheelPageWidth = result;
if (!kIsAndroid) {
ok(window.innerWidth - result < 100 && window.innerWidth - result > 0,
"prepareScrollUnits: gRoot.wheelPageWidth is strange value, got " + result);
}
window.removeEventListener("MozMousePixelScroll", handler, true);
}
function* doTests()
{
let tests = [];
{
const kAllScrollables = [gRoot, gScrollable128, gScrollable96, gScrollable64, gScrollable32];
function resetAllScrollables() {
for (let scrollable of kAllScrollables) {
scrollable.style.overflow = "";
scrollable.scrollLeft = 0;
scrollable.scrollTop = 0;
}
}
function closestScrollable(s) {
if (s == gScrollable32 || s == gRoot) {
return gRoot;
}
let closest = kAllScrollables[kAllScrollables.indexOf(s) - 1];
ok(closest, `Should find a closest scrollable for ${s.id}`);
return closest;
}
const kAllScrollDirections = [
{
direction: "both",
x: 1,
y: 1,
},
{
direction: "horizontal",
x: 1,
y: 0,
},
{
direction: "vertical",
x: 0,
y: 1,
},
];
for (let deltaMode of [WheelEvent.DOM_DELTA_LINE, WheelEvent.DOM_DELTA_PAGE]) {
if (deltaMode == WheelEvent.DOM_DELTA_PAGE && kIsAndroid) {
// See comment around kIsAndroid.
continue;
}
for (let scrollable of kAllScrollables) {
for (let { x, y, direction } of kAllScrollDirections) {
tests.push({
description: `Should be computed from nearest scrollable element (${scrollable.id}, ${deltaMode}, ${direction})`,
target: scrollable,
event: {
deltaMode,
deltaX: x,
deltaY: y,
lineOrPageDeltaX: x,
lineOrPageDeltaY: y,
},
prepare () {
resetAllScrollables();
},
cleanup () {
},
expected: {
x: x ? scrollable : null,
y: y ? scrollable : null,
}
});
tests.push({
description: `Should be computed from actual scroll target or root if not scrollable in the direction (${scrollable.id}, ${deltaMode}, ${direction})`,
target: scrollable,
event: {
deltaMode,
deltaX: -x,
deltaY: -y,
lineOrPageDeltaX: -x,
lineOrPageDeltaY: -y
},
prepare () {
resetAllScrollables();
},
cleanup () {
},
expected: {
x: x ? gRoot : null,
y: y ? gRoot : null,
}
});
// Root's page delta depends on whether there's an horizontal scrollbar
// or not, so this test on the root would be off by a few pixels.
if (scrollable != gRoot || deltaMode != WheelEvent.DOM_DELTA_PAGE) {
tests.push({
description: `Should be computed from actual scroll target or root if scrollable in the direction but overflow: hidden (${scrollable.id}, ${deltaMode}, ${direction})`,
target: scrollable,
event: {
deltaMode,
deltaX: x,
deltaY: y,
lineOrPageDeltaX: x,
lineOrPageDeltaY: y,
},
prepare () {
resetAllScrollables();
scrollable.style.overflow = "hidden";
},
cleanup () {
scrollable.style.overflow = "";
},
expected: {
x: x ? closestScrollable(scrollable) : null,
y: y ? closestScrollable(scrollable) : null,
}
});
}
}
}
}
}
var currentTest, description, firedX, firedY;
var expectedHandlerCalls;
function handler(aEvent)
{
aEvent.preventDefault();
if (aEvent.axis != MouseScrollEvent.HORIZONTAL_AXIS &&
aEvent.axis != MouseScrollEvent.VERTICAL_AXIS) {
ok(false,
description + "The event had invalid axis (" + aEvent.axis + ")");
if (--expectedHandlerCalls == 0) {
setTimeout(runTest, 0);
}
return;
}
var isHorizontal = (aEvent.axis == MouseScrollEvent.HORIZONTAL_AXIS);
if ((isHorizontal && !currentTest.expected.x) ||
(!isHorizontal && !currentTest.expected.y)) {
ok(false,
description + "The event fired unexpectedly (" +
(isHorizontal ? "Horizontal" : "Vertical") + ")");
if (--expectedHandlerCalls == 0) {
setTimeout(runTest, 0);
}
return;
}
if (isHorizontal) {
firedX = true;
} else {
firedY = true;
}
var expectedDetail =
(currentTest.event.deltaMode == WheelEvent.DOM_DELTA_LINE) ?
(isHorizontal ? currentTest.expected.x.wheelHorizontalLine :
currentTest.expected.y.wheelLineHeight) :
(isHorizontal ? currentTest.expected.x.wheelPageWidth :
currentTest.expected.y.wheelPageHeight);
is(Math.abs(aEvent.detail), expectedDetail,
description + ((isHorizontal) ? "horizontal" : "vertical") + " event detail is wrong");
if (--expectedHandlerCalls == 0) {
setTimeout(runTest, 0);
}
}
window.addEventListener("MozMousePixelScroll", handler, { capture: true, passive: false });
for (var i = 0; i < tests.length; i++) {
currentTest = tests[i];
description = "doTests, " + currentTest.description + " (deltaMode: " +
(currentTest.event.deltaMode == WheelEvent.DOM_DELTA_LINE ?
"DOM_DELTA_LINE" : "DOM_DELTA_PAGE") +
", deltaX: " + currentTest.event.deltaX +
", deltaY: " + currentTest.event.deltaY + "): ";
currentTest.prepare();
firedX = firedY = false;
expectedHandlerCalls = (currentTest.expected.x ? 1 : 0)
+ (currentTest.expected.y ? 1 : 0);
yield synthesizeWheel(currentTest.target, 10, 10, currentTest.event);
if (currentTest.expected.x) {
ok(firedX, description + "Horizontal MozMousePixelScroll event wasn't fired");
}
if (currentTest.expected.y) {
ok(firedY, description + "Vertical MozMousePixelScroll event wasn't fired");
}
currentTest.cleanup();
}
window.removeEventListener("MozMousePixelScroll", handler, true);
}
function* testBody()
{
yield* prepareScrollUnits();
yield* doTests();
}
var gTestContinuation = null;
function runTest()
{
if (!gTestContinuation) {
gTestContinuation = testBody();
}
var ret = gTestContinuation.next();
if (ret.done) {
SimpleTest.finish();
}
}
function startTest() {
SpecialPowers.pushPrefEnv({"set": [["mousewheel.default.delta_multiplier_x", 100],
["mousewheel.default.delta_multiplier_y", 100],
["mousewheel.default.delta_multiplier_z", 100],
["mousewheel.with_alt.delta_multiplier_x", 100],
["mousewheel.with_alt.delta_multiplier_y", 100],
["mousewheel.with_alt.delta_multiplier_z", 100],
["mousewheel.with_control.delta_multiplier_x", 100],
["mousewheel.with_control.delta_multiplier_y", 100],
["mousewheel.with_control.delta_multiplier_z", 100],
["mousewheel.with_meta.delta_multiplier_x", 100],
["mousewheel.with_meta.delta_multiplier_y", 100],
["mousewheel.with_meta.delta_multiplier_z", 100],
["mousewheel.with_shift.delta_multiplier_x", 100],
["mousewheel.with_shift.delta_multiplier_y", 100],
["mousewheel.with_shift.delta_multiplier_z", 100],
// If APZ is enabled we should ensure the preventDefault calls work even
// if the test is running slowly.
["apz.content_response_timeout", 2000],
]}, runTest);
}
</script>
</pre>
</body>
</html>