blob: 05057cd0ac92a1a1077a15a31b0a831ada5e3612 [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Scroll customization methods are called appropriately.</title>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<style>
* {
margin:0;
padding:0;
}
*::-webkit-scrollbar {
width: 0 !important;
height: 0 !important;
}
#a {
height:400px;
width:400px;
overflow:scroll;
}
#b {
height:500px;
width:500px;
background-color:purple;
}
#c {
height:300px;
width:300px;
overflow:scroll;
}
#d {
height:400px;
width:400px;
background-color:green;
}
body {
height:3000px;
}
</style>
</head>
<body>
<div id="a">
<div id="b">
<div id="c">
<div id="d">
</div>
</div>
</div>
</div>
<script>
test(function() {
assert_true('ScrollState' in window, "'ScrollState' in window");
}, "These tests only work with scroll customization enabled.");
internals.settings.setScrollAnimatorEnabled(false);
var originalApplyScrolls = [];
var originalDistributeScrolls = [];
var deltas = [85, 75, 65, 55, 45];
var elements = [
document.getElementById("d"),
document.getElementById("c"),
document.getElementById("b"),
document.getElementById("a"),
document.scrollingElement];
var scrollableElements = [elements[1], elements[3], elements[4]];
document.scrollingElement.id = "scrollingElement";
function reset() {
for (var i = 0; i < elements.length; ++i) {
elements[i].scrollTop = 0;
elements[i].unappliedDeltaY = [];
elements[i].distributedDeltaY = [];
elements[i].numberOfScrollBegins = 0;
elements[i].numberOfScrollEnds = 0;
elements[i].setApplyScroll((function(scrollState){
if (!scrollState.isEnding && !scrollState.isBeginning)
this.unappliedDeltaY.push(scrollState.deltaY);
}).bind(elements[i]), "perform-after-native-scroll");
elements[i].setDistributeScroll((function(scrollState) {
if (scrollState.isBeginning)
this.numberOfScrollBegins++;
else if (scrollState.isEnding)
this.numberOfScrollEnds++;
else
this.distributedDeltaY.push(scrollState.deltaY);
}).bind(elements[i]), "perform-before-native-scroll");
// Add a gc, to ensure that these callbacks don't get collected.
gc();
}
}
function applyDelta(d) {
eventSender.gestureScrollBegin(10, 10);
eventSender.gestureScrollUpdate(0, -d);
eventSender.gestureScrollEnd(0, 0);
}
if ('ScrollState' in window) {
test(function() {
reset();
// Scroll five times, with three scrollable elements.
var cScrollTop = [85, 100, 100, 100, 100];
var aScrollTop = [0, 0, 65, 100, 100];
var scrollingElementScrollTop = [0, 0, 0, 0, 45];
for (var i = 0; i < deltas.length; ++i) {
applyDelta(deltas[i]);
assert_equals(a.scrollTop, aScrollTop[i], "For id 'a' on step " + i);
assert_equals(c.scrollTop, cScrollTop[i], "For id 'c' on step " + i);
assert_equals(document.scrollingElement.scrollTop, scrollingElementScrollTop[i], "For scrollingElement on step " + i);
}
}, "Scroll offsets are modified correctly.");
test(function() {
reset();
// Scroll five times, with five elements.
var unapplied = [
// d, the innermost element, never applies any scroll.
[85, 75, 65, 55, 45],
// c applies the first two scrolls, and then hits its scroll extents.
[0, 0, 65, 55, 45],
// b doesn't scroll, and so leaves the same deltas unapplied as c.
[65, 55, 45],
// a hits its scroll extent on the second last step.
[0, 0, 45],
// The scrollingElement performs the frame scroll.
[0]];
for (var i = 0; i < deltas.length; ++i)
applyDelta(deltas[i]);
for (var i = 0; i < elements.length; ++i) {
var el = elements[i];
// Every element sees the same deltas being distributed.
assert_array_equals(el.distributedDeltaY, deltas, "distributed delta for " + el.id + ":");
assert_array_equals(el.unappliedDeltaY, unapplied[i], "unapplied delta for " + el.id + ":");
}
// Ensure that the document leaves scroll unapplied when appropriate.
var documentUnapplied = document.scrollingElement.unappliedDeltaY;
applyDelta(4000);
assert_equals(documentUnapplied[documentUnapplied.length - 1], 0);
applyDelta(4000);
assert_equals(documentUnapplied[documentUnapplied.length - 1], 4000);
}, "Correct amount of delta is consumed.");
test(function() {
reset();
// Scroll five times, with three scrollable elements.
var cScrollTop = [85, 100, 100, 100, 100];
var aScrollTop = [0, 0, 65, 100, 100];
var scrollingElementScrollTop = [0, 0, 0, 0, 45];
for (var i = 0; i < deltas.length; ++i) {
applyDelta(deltas[i]);
assert_equals(c.scrollTop, cScrollTop[i], "For id 'c' on step " + i);
assert_equals(a.scrollTop, aScrollTop[i], "For id 'a' on step " + i);
assert_equals(document.scrollingElement.scrollTop, scrollingElementScrollTop[i], "For scrollingElement on step " + i);
}
}, "Scroll propagation behaves correctly.");
test(function() {
reset();
for (var i = 0; i < deltas.length; ++i)
applyDelta(deltas[i]);
for (var i = 0; i < elements.length; ++i) {
assert_equals(elements[i].numberOfScrollBegins, deltas.length, "Incorrect number of begin events for " + elements[i].id);
assert_equals(elements[i].numberOfScrollEnds, deltas.length, "Incorrect number of end events for " + elements[i].id);
}
}, "Correct number of scroll begin and end events observed.");
{
// NOTE - this async test needs to be run last, as it shares state with the
// other tests. If other tests are run after it, they'll modify the state
// while this test is still running.
var flingTest = async_test("Touchscreen fling doesn't propagate.");
reset();
function assertScrollTops(cTop, aTop, scrollingElementTop, step) {
assert_equals(c.scrollTop, cTop, "For id 'c' on step " + step);
assert_equals(a.scrollTop, aTop, "For id 'a' on step " + step);
assert_equals(document.scrollingElement.scrollTop, scrollingElementTop, "For scrollingElement on step " + step);
};
var frame_actions = [
function() {
eventSender.gestureFlingStart(10, 10, -1000000, -1000000, "touchscreen");
},
flingTest.step_func(function() {
assertScrollTops(0, 0, 0, 1);
}),
flingTest.step_func(function() {
assertScrollTops(100, 0, 0, 2);
}),
flingTest.step_func(function() {
assertScrollTops(100, 0, 0, 3);
}),
flingTest.step_func(function() {
assertScrollTops(100, 0, 0, 4);
flingTest.done();
})
]
function executeFrameActions(frame_actions) {
var frame = 0;
function raf() {
frame_actions[frame]();
frame++;
if (frame >= frame_actions.length)
return;
window.requestAnimationFrame(raf);
}
window.requestAnimationFrame(raf);
}
executeFrameActions(frame_actions);
}
}
</script>
</body>
</html>