291 lines
12 KiB
HTML
291 lines
12 KiB
HTML
<?xml version="1.0"?>
|
|
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
|
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
|
<!--
|
|
https://bugzilla.mozilla.org/show_bug.cgi?id=378028
|
|
-->
|
|
<window title="Mozilla Bug 378028"
|
|
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
|
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
|
<script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
|
|
<script src="chrome://mochikit/content/tests/SimpleTest/paint_listener.js"/>
|
|
|
|
<!-- test results are displayed in the html:body -->
|
|
<body xmlns="http://www.w3.org/1999/xhtml">
|
|
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=378028"
|
|
target="_blank">Mozilla Bug 378028</a>
|
|
</body>
|
|
|
|
<!-- richlistbox currently has no way of giving us a defined number of
|
|
rows, so we just choose an arbitrary height limit that should give
|
|
us plenty of vertical scrollability -->
|
|
<richlistbox id="richlistbox" style="height:50px;">
|
|
<richlistitem id="richlistbox_item0" hidden="true"><label value="Item 0"/></richlistitem>
|
|
<richlistitem id="richlistbox_item1"><label value="Item 1"/></richlistitem>
|
|
<richlistitem id="richlistbox_item2"><label value="Item 2"/></richlistitem>
|
|
<richlistitem id="richlistbox_item3"><label value="Item 3"/></richlistitem>
|
|
<richlistitem id="richlistbox_item4"><label value="Item 4"/></richlistitem>
|
|
<richlistitem id="richlistbox_item5"><label value="Item 5"/></richlistitem>
|
|
<richlistitem id="richlistbox_item6"><label value="Item 6"/></richlistitem>
|
|
<richlistitem id="richlistbox_item7"><label value="Item 7"/></richlistitem>
|
|
<richlistitem id="richlistbox_item8"><label value="Item 8"/></richlistitem>
|
|
</richlistbox>
|
|
|
|
<box orient="horizontal">
|
|
<arrowscrollbox id="hscrollbox" clicktoscroll="true" orient="horizontal"
|
|
smoothscroll="false" style="max-width:80px;" flex="1">
|
|
<hbox style="min-width:40px; min-height:20px; background:black;" hidden="true"/>
|
|
<hbox style="min-width:40px; min-height:20px; background:white;"/>
|
|
<hbox style="min-width:40px; min-height:20px; background:black;"/>
|
|
<hbox style="min-width:40px; min-height:20px; background:white;"/>
|
|
<hbox style="min-width:40px; min-height:20px; background:black;"/>
|
|
<hbox style="min-width:40px; min-height:20px; background:white;"/>
|
|
<hbox style="min-width:40px; min-height:20px; background:black;"/>
|
|
<hbox style="min-width:40px; min-height:20px; background:white;"/>
|
|
<hbox style="min-width:40px; min-height:20px; background:black;"/>
|
|
</arrowscrollbox>
|
|
</box>
|
|
|
|
<arrowscrollbox id="vscrollbox" clicktoscroll="true" orient="vertical"
|
|
smoothscroll="false" style="max-height:80px;" flex="1">
|
|
<vbox style="min-width:100px; min-height:40px; background:black;" hidden="true"/>
|
|
<vbox style="min-width:100px; min-height:40px; background:white;"/>
|
|
<vbox style="min-width:100px; min-height:40px; background:black;"/>
|
|
<vbox style="min-width:100px; min-height:40px; background:white;"/>
|
|
<vbox style="min-width:100px; min-height:40px; background:black;"/>
|
|
<vbox style="min-width:100px; min-height:40px; background:white;"/>
|
|
<vbox style="min-width:100px; min-height:40px; background:black;"/>
|
|
<vbox style="min-width:100px; min-height:40px; background:white;"/>
|
|
<vbox style="min-width:100px; min-height:40px; background:black;"/>
|
|
<vbox style="min-width:100px; min-height:40px; background:white;"/>
|
|
<vbox style="min-width:100px; min-height:40px; background:black;"/>
|
|
</arrowscrollbox>
|
|
|
|
<!-- test code goes here -->
|
|
<script type="application/javascript"><![CDATA[
|
|
|
|
/** Test for Bug 378028 **/
|
|
/* and for Bug 350471 **/
|
|
SimpleTest.waitForExplicitFinish();
|
|
SimpleTest.waitForFocus(prepareRunningTests);
|
|
|
|
// Some tests need to wait until stopping scroll completely. At this time,
|
|
// setTimeout() will retry to check up to MAX_RETRY_COUNT times.
|
|
const MAX_RETRY_COUNT = 5;
|
|
|
|
const deltaModes = [
|
|
WheelEvent.DOM_DELTA_PIXEL, // 0
|
|
WheelEvent.DOM_DELTA_LINE, // 1
|
|
WheelEvent.DOM_DELTA_PAGE // 2
|
|
];
|
|
|
|
function sendWheelAndWait(aScrollTaget, aX, aY, aEvent, aChecker)
|
|
{
|
|
function continueTestsIfScrolledAsExpected() {
|
|
if (!aChecker())
|
|
SimpleTest.executeSoon(()=>{ continueTestsIfScrolledAsExpected(aChecker) });
|
|
else
|
|
runTests();
|
|
}
|
|
|
|
sendWheelAndPaint(aScrollTaget, aX, aY, aEvent, ()=>{
|
|
// sendWheelAndPaint may wait not enough for <scrollbox>.
|
|
// Let's check the position before using is() for avoiding random orange.
|
|
// So, this test may detect regressions with timeout.
|
|
continueTestsIfScrolledAsExpected(aChecker);
|
|
});
|
|
}
|
|
|
|
function* testRichListbox(id)
|
|
{
|
|
var listbox = document.getElementById(id);
|
|
|
|
function* helper(aStart, aDelta, aIntDelta, aDeltaMode) {
|
|
listbox.ensureElementIsVisible(listbox.getItemAtIndex(aStart),true);
|
|
|
|
let event = {
|
|
deltaMode: aDeltaMode,
|
|
deltaY: aDelta,
|
|
lineOrPageDeltaY: aIntDelta
|
|
};
|
|
// We don't need to wait for finishing the scroll in this test.
|
|
yield sendWheelAndWait(listbox, 10, 10, event, ()=>{ return true; });
|
|
var change = listbox.getIndexOfFirstVisibleRow() - aStart;
|
|
var direction = (change > 0) - (change < 0);
|
|
var expected = (aDelta > 0) - (aDelta < 0);
|
|
is(direction, expected,
|
|
"testRichListbox(" + id + "): vertical, starting " + aStart +
|
|
" delta " + aDelta + " lineOrPageDeltaY " + aIntDelta +
|
|
" aDeltaMode " + aDeltaMode);
|
|
|
|
// Check that horizontal scrolling has no effect
|
|
event = {
|
|
deltaMode: aDeltaMode,
|
|
deltaX: aDelta,
|
|
lineOrPageDeltaX: aIntDelta
|
|
};
|
|
|
|
listbox.ensureElementIsVisible(listbox.getItemAtIndex(aStart),true);
|
|
yield sendWheelAndWait(listbox, 10, 10, event, ()=>{ return true; });
|
|
is(listbox.getIndexOfFirstVisibleRow(), aStart,
|
|
"testRichListbox(" + id + "): horizontal, starting " + aStart +
|
|
" delta " + aDelta + " lineOrPageDeltaX " + aIntDelta +
|
|
" aDeltaMode " + aDeltaMode);
|
|
}
|
|
|
|
// richlistbox currently uses native XUL scrolling, so the "line"
|
|
// amounts don't necessarily correspond 1-to-1 with listbox items. So
|
|
// we just check that scrolling up/down scrolls in the right direction.
|
|
for (let i = 0; i < deltaModes.length; i++) {
|
|
let delta = (deltaModes[i] == WheelEvent.DOM_DELTA_PIXEL) ? 32.0 : 2.0;
|
|
yield* helper(5, -delta, -1, deltaModes[i]);
|
|
yield* helper(5, -delta, 0, deltaModes[i]);
|
|
yield* helper(5, delta, 1, deltaModes[i]);
|
|
yield* helper(5, delta, 0, deltaModes[i]);
|
|
}
|
|
}
|
|
|
|
function* testArrowScrollbox(id)
|
|
{
|
|
var arrowscrollbox = document.getElementById(id);
|
|
var scrollbox = arrowscrollbox.scrollbox;
|
|
var orient = scrollbox.getAttribute("orient");
|
|
var orientIsHorizontal = (orient == "horizontal");
|
|
|
|
function* helper(aStart, aDelta, aDeltaMode, aExpected)
|
|
{
|
|
var lineOrPageDelta = (aDeltaMode == WheelEvent.DOM_DELTA_PIXEL) ? aDelta / 10 : aDelta;
|
|
|
|
scrollbox.scrollTo(aStart, aStart);
|
|
for (let i = orientIsHorizontal ? 2 : 0; i >= 0; i--) {
|
|
// Note, vertical mouse scrolling is allowed to scroll horizontal
|
|
// arrowscrollboxes, because many users have no horizontal mouse scroll
|
|
// capability
|
|
let expected = !i ? aExpected : aStart;
|
|
let getPos = ()=>{
|
|
return orientIsHorizontal ? scrollbox.scrollLeft :
|
|
scrollbox.scrollTop;
|
|
};
|
|
let oldPos = -1;
|
|
let retry = 0;
|
|
yield sendWheelAndWait(scrollbox, 5, 5,
|
|
{ deltaMode: aDeltaMode, deltaY: aDelta,
|
|
lineOrPageDeltaY: lineOrPageDelta },
|
|
()=>{
|
|
if (getPos() == expected) {
|
|
return true;
|
|
}
|
|
if (oldPos == getPos()) {
|
|
// If scroll stopped completely, let's continue the test.
|
|
return ++retry == MAX_RETRY_COUNT;
|
|
}
|
|
oldPos = getPos();
|
|
retry = 0;
|
|
return false;
|
|
});
|
|
is(getPos(), expected,
|
|
"testArrowScrollbox(" + id + "): vertical, starting " + aStart +
|
|
" delta " + aDelta + " lineOrPageDelta " + lineOrPageDelta +
|
|
" aDeltaMode " + aDeltaMode);
|
|
}
|
|
|
|
scrollbox.scrollTo(aStart, aStart);
|
|
for (let i = orientIsHorizontal ? 2 : 0; i >= 0; i--) {
|
|
// horizontal mouse scrolling is never allowed to scroll vertical
|
|
// arrowscrollboxes
|
|
let expected = (!i && orientIsHorizontal) ? aExpected : aStart;
|
|
let getPos = ()=>{
|
|
return orientIsHorizontal ? scrollbox.scrollLeft :
|
|
scrollbox.scrollTop;
|
|
};
|
|
let oldPos = -1;
|
|
let retry = 0;
|
|
yield sendWheelAndWait(scrollbox, 5, 5,
|
|
{ deltaMode: aDeltaMode, deltaX: aDelta,
|
|
lineOrPageDeltaX: lineOrPageDelta },
|
|
()=>{
|
|
if (getPos() == expected) {
|
|
return true;
|
|
}
|
|
if (oldPos == getPos()) {
|
|
// If scroll stopped completely, let's continue the test.
|
|
return ++retry == MAX_RETRY_COUNT;
|
|
}
|
|
oldPos = getPos();
|
|
retry = 0;
|
|
return false;
|
|
});
|
|
is(getPos(), expected,
|
|
"testArrowScrollbox(" + id + "): horizontal, starting " + aStart +
|
|
" delta " + aDelta + " lineOrPageDelta " + lineOrPageDelta +
|
|
" aDeltaMode " + aDeltaMode);
|
|
}
|
|
}
|
|
|
|
var line = arrowscrollbox.lineScrollAmount;
|
|
var scrolledWidth = scrollbox.scrollWidth;
|
|
var scrolledHeight = scrollbox.scrollHeight;
|
|
var scrollMaxX = scrolledWidth - scrollbox.getBoundingClientRect().width;
|
|
var scrollMaxY = scrolledHeight - scrollbox.getBoundingClientRect().height;
|
|
var scrollMax = orientIsHorizontal ? scrollMaxX : scrollMaxY;
|
|
|
|
for (let deltaMode of deltaModes) {
|
|
const start = 50;
|
|
const delta = 1000;
|
|
let expectedNegative = 0;
|
|
let expectedPositive = scrollMax;
|
|
if (deltaMode == WheelEvent.DOM_DELTA_LINE) {
|
|
let maxDelta = Math.floor(Math.max(1, arrowscrollbox.scrollClientSize / line)) * line;
|
|
expectedNegative = Math.max(0, start - maxDelta);
|
|
expectedPositive = Math.min(scrollMax, start + maxDelta);
|
|
}
|
|
yield* helper(start, -delta, deltaMode, expectedNegative);
|
|
yield* helper(start, delta, deltaMode, expectedPositive);
|
|
}
|
|
}
|
|
|
|
var gTestContinuation = null;
|
|
|
|
function runTests()
|
|
{
|
|
if (!gTestContinuation) {
|
|
gTestContinuation = testBody();
|
|
}
|
|
var ret = gTestContinuation.next();
|
|
if (ret.done) {
|
|
var winUtils = SpecialPowers.getDOMWindowUtils(window);
|
|
winUtils.restoreNormalRefresh();
|
|
SimpleTest.finish();
|
|
}
|
|
}
|
|
|
|
async function prepareRunningTests()
|
|
{
|
|
// Before actually running tests, we disable auto-dir scrolling, becasue the
|
|
// horizontal scrolling tests in this file are mostly meant to ensure that the
|
|
// tested controls in the default style should only have one scrollbar and it
|
|
// must always be in the block-flow direction so they are not really meant to
|
|
// test default actions for wheel events, so we simply disabled auto-dir
|
|
// scrolling, which are well tested in
|
|
// dom/events/test/window_wheel_default_action.html.
|
|
await SpecialPowers.pushPrefEnv({"set": [["mousewheel.autodir.enabled",
|
|
false]]});
|
|
|
|
runTests();
|
|
}
|
|
|
|
function* testBody()
|
|
{
|
|
yield* testRichListbox("richlistbox");
|
|
|
|
// Perform a mousedown to ensure the wheel transaction from the previous test
|
|
// does not impact the next test.
|
|
synthesizeMouse(document.scrollingElement, 0, 0, {type: "mousedown"}, window);
|
|
yield* testArrowScrollbox("hscrollbox");
|
|
|
|
synthesizeMouse(document.scrollingElement, -1, -1, {type: "mousedown"}, window);
|
|
yield* testArrowScrollbox("vscrollbox");
|
|
}
|
|
|
|
]]></script>
|
|
</window>
|