0
Files
src/third_party/blink/web_tests/rootscroller/fixed-chaining-with-implicit-pointer-events-none.html
David Bokan 69d36845ab Fix IsInitialScrollHitTestReliable for fixed elements
This CL fixes an issue when scroll chaining from fixed nodes in
combination with |pointer-events: none|.

|pointer-events: none| causes a subtree to become invisible to hit
testing. This means scrolling over it should pass through to the element
below. The way the test case in the bug normally works is that the
scroll hit test on the compositor will hit the fixed layer, but the first
*scrollable* layer hit is the <div> below the fixed layer. Since scrolls
from fixed layers chain to the inner viewport, the check in
IsInitialScrollHitTestReliable sees different layers so it returns false
and the scroll is sent to the main thread where the
|pointer-events: none| scroll chaining behaivor is explicitly
implemented. I'm not sure that this behavior is intentional.

With RootScroller, the scroller below the fixed layer becomes the outer
viewport. This means that scrolling the "viewport" scrolls this scroller.
Prior to https://crrev.com/c/1752866, scrolling over a fixed layer would
chain to the viewport so it would incorrectly cause scrolling in this
non-document scroller. The CL above fixed this case by chaining scrolls
from fixed layers to the inner viewport *only*.

However, we failed to update the chaining behavior in
IsInitialScrollHitTestReliable. So when this method checks for the first
scrollable ancestor of the fixed layer, and gets the inner viewport, it
still assumes it'll be scrolled using the "viewport" and thus
substitutes it for the outer viewport node. This causes
IsInitialScrollHitTestReliable to return true and we handle the scroll
on the compositor which doesn't know that the fixed layer has
|pointer-events: none|.

This CL updates IsInitialScrollHitTestReliable to use the same chaining
behavior as the rest of the scrolling code.

Bug: 1011866
Change-Id: I83020cc934255a6e22e1619833f5a5e82a55d6f4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1856853
Commit-Queue: David Bokan <bokan@chromium.org>
Reviewed-by: Philip Rogers <pdr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#707249}
2019-10-18 04:24:49 +00:00

94 lines
2.2 KiB
HTML

<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="../resources/gesture-util.js"></script>
<style>
body, html {
width: 100%;
height: 100%;
margin: 0;
}
#rootscroller::-webkit-scrollbar {
width: 0px;
height: 0px;
}
#rootscroller {
width: 100%;
height: 100%;
overflow: auto;
position: absolute;
left: 0;
top: 0;
background-color: red;
}
.spacer {
width: 100%;
height: 100%;
}
#fixed {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 80%;
background-color: grey;
pointer-events: none;
}
</style>
<div id="rootscroller">
<div class="spacer" style="background-color: PaleGreen"></div>
<div class="spacer" style="background-color: Maroon"></div>
</div>
<div id="fixed">
<p>
To test, try scrolling over the grey region. The root scroller should be
scrolled (you should see red appear). Since the grey fixed region has
|pointer-events:none|, the scroll events should hit the root scroller.
</p>
</div>
<script>
if (window.internals) {
internals.settings.setScrollAnimatorEnabled(false);
internals.runtimeFlags.implicitRootScrollerEnabled = true;
}
async function runTest() {
await waitForCompositorCommit();
assert_equals(window.internals.effectiveRootScroller(document),
rootscroller,
"#rootscroller must be the effective root scroller");
const delta = 3000;
const location = { x: 5, y: 5 };
await smoothScroll(delta,
location.x,
location.y,
GestureSourceType.TOUCH_INPUT,
'down',
SPEED_INSTANT);
assert_greater_than(rootscroller.scrollTop,
0,
"RootScroller must have been scrolled");
}
window.onload = async () => {
if (!window.internals)
return;
var rootscroller = document.querySelector('#rootscroller');
promise_test( async t => {
internals.setPageScaleFactor(1);
await runTest();
}, "Scrolling from fixed element while unzoomed.");
}
</script>