| Index: LayoutTests/fast/scroll-behavior/scroll-customization/touch-scroll-customization.html
|
| diff --git a/LayoutTests/fast/scroll-behavior/scroll-customization/touch-scroll-customization.html b/LayoutTests/fast/scroll-behavior/scroll-customization/touch-scroll-customization.html
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..40a4c2cdb27311b14e2291165ffb879182b86b44
|
| --- /dev/null
|
| +++ b/LayoutTests/fast/scroll-behavior/scroll-customization/touch-scroll-customization.html
|
| @@ -0,0 +1,246 @@
|
| +<!DOCTYPE html>
|
| +<html>
|
| +<head>
|
| +<meta charset="utf-8">
|
| +<title>ScrollState constructor behaves correctly</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>
|
| +
|
| +if (!window.internals || !window.internals.runtimeFlags.scrollCustomizationEnabled || !window.eventSender) {
|
| + console.log("These tests only work with window.internals and " +
|
| + "window.eventSender exposed, and require scroll customization.");
|
| + done();
|
| +}
|
| +
|
| +var originalApplyScroll = Element.prototype.applyScroll;
|
| +var originalDistributeScroll = Element.prototype.distributeScroll;
|
| +var deltas = [-85, -75, -65, -55, -45];
|
| +
|
| +var elements = [
|
| + document.getElementById("d"),
|
| + document.getElementById("c"),
|
| + document.getElementById("b"),
|
| + document.getElementById("a"),
|
| + document.body,
|
| + document.documentElement];
|
| +
|
| +document.body.id = "body";
|
| +document.documentElement.id = "document";
|
| +
|
| +function reset() {
|
| + for (var i = 0; i < elements.length; ++i) {
|
| + elements[i].scrollTop = 0;
|
| + elements[i].unappliedDeltaY = [];
|
| + elements[i].distributedDeltaY = [];
|
| + elements[i].numberOfScrollEnds = 0;
|
| + }
|
| +
|
| + Element.prototype.applyScroll = function(scrollState) {
|
| + originalApplyScroll.call(this, scrollState);
|
| + if (!scrollState.isEnding)
|
| + this.unappliedDeltaY.push(scrollState.deltaY);
|
| + }
|
| +
|
| + Element.prototype.distributeScroll = function(scrollState) {
|
| + if (!scrollState.isEnding)
|
| + this.distributedDeltaY.push(scrollState.deltaY);
|
| + else
|
| + this.numberOfScrollEnds++;
|
| + originalDistributeScroll.call(this, scrollState);
|
| + }
|
| +}
|
| +
|
| +function applyDelta(d) {
|
| + eventSender.gestureScrollBegin(10, 10);
|
| + eventSender.gestureScrollUpdate(0, d);
|
| + eventSender.gestureScrollEnd(0, 0);
|
| +}
|
| +
|
| +test(function() {
|
| + reset();
|
| +
|
| + // Scroll five times, with four scrollable elements.
|
| + var cScrollTop = [85, 100, 100, 100, 100];
|
| + var aScrollTop = [0, 0, 65, 100, 100];
|
| + var bodyScrollTop = [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.body.scrollTop, bodyScrollTop[i], "For body on step " + i);
|
| + }
|
| +}, "Scroll offsets are modified correctly.");
|
| +
|
| +test(function() {
|
| + reset();
|
| +
|
| + // Scroll five times, with six 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.
|
| + [0, 0, -65, -55, -45],
|
| + // a hits its scroll extent on the second last step.
|
| + [0, 0, 0, 0, -45],
|
| + // body doesn't scroll (it's the documentElement that scrolls, but the body's
|
| + // scrollTop updates), and so leaves the same deltas unapplied as a.
|
| + [0, 0, 0, 0, -45],
|
| + // The documentElement performs the frame scroll.
|
| + [0, 0, 0, 0, 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.documentElement.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();
|
| +
|
| + // Consume one pixel of delta per call to applyScroll.
|
| + var applyScroll = Element.prototype.applyScroll;
|
| + Element.prototype.applyScroll = function(scrollState) {
|
| + if (scrollState.deltaY !== 0)
|
| + scrollState.consumeDelta(0, -1);
|
| + applyScroll.call(this, scrollState);
|
| + }
|
| +
|
| + // Scroll five times, with four scrollable elements.
|
| + // The scroll distance is decreased more the higher up the scroll chain the element is.
|
| + var cScrollTop = [85 - 2, 100, 100, 100, 100];
|
| + var aScrollTop = [0, 0, 65 - 4, 100, 100];
|
| + var bodyScrollTop = [0, 0, 0, 0, 45 - 6];
|
| +
|
| + 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.body.scrollTop, bodyScrollTop[i], "For body on step " + i);
|
| + }
|
| +}, "Consuming deltas prevents scrolling.");
|
| +
|
| +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].numberOfScrollEnds, deltas.length);
|
| +}, "Correct number of scroll ends observed.");
|
| +
|
| +{
|
| + var flingTest = async_test("Touchscreen fling doesn't propagate.");
|
| + reset();
|
| +
|
| + function assertScrollTops(cTop, aTop, bodyTop, 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.body.scrollTop, bodyTop, "For body 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]();
|
| + if (frame >= frame_actions.length)
|
| + return;
|
| + frame++;
|
| + window.requestAnimationFrame(raf);
|
| + }
|
| + window.requestAnimationFrame(raf);
|
| + }
|
| +
|
| + executeFrameActions(frame_actions);
|
| +}
|
| +</script>
|
| +</body>
|
| +</html>
|
|
|