Index: third_party/WebKit/Source/web/tests/RootScrollerTest.cpp |
diff --git a/third_party/WebKit/Source/web/tests/RootScrollerTest.cpp b/third_party/WebKit/Source/web/tests/RootScrollerTest.cpp |
index 230727d51733a778b4330c06332876ffffbc32b4..5f4e912ccff293363ada7b985d66724254a3c741 100644 |
--- a/third_party/WebKit/Source/web/tests/RootScrollerTest.cpp |
+++ b/third_party/WebKit/Source/web/tests/RootScrollerTest.cpp |
@@ -24,6 +24,7 @@ |
#include "public/platform/WebURLLoaderMockFactory.h" |
#include "public/web/WebCache.h" |
#include "public/web/WebConsoleMessage.h" |
+#include "public/web/WebHitTestResult.h" |
#include "public/web/WebRemoteFrame.h" |
#include "public/web/WebScriptSource.h" |
#include "public/web/WebSettings.h" |
@@ -1316,6 +1317,228 @@ TEST_F(RootScrollerTest, ImmediateUpdateOfLayoutViewport) { |
&mainFrameView()->getRootFrameViewport()->layoutViewport()); |
} |
+class RootScrollerHitTest : public RootScrollerTest { |
+ public: |
+ void checkHitTestAtBottomOfScreen() { |
+ // Hide the top controls and scroll down maximally. |
+ { |
+ webViewImpl()->handleInputEvent( |
+ generateTouchGestureEvent(WebInputEvent::GestureScrollBegin)); |
+ ASSERT_EQ(1, browserControls().shownRatio()); |
+ webViewImpl()->handleInputEvent(generateTouchGestureEvent( |
+ WebInputEvent::GestureScrollUpdate, 0, -browserControls().height())); |
+ ASSERT_EQ(0, browserControls().shownRatio()); |
+ webViewImpl()->handleInputEvent(generateTouchGestureEvent( |
+ WebInputEvent::GestureScrollUpdate, 0, -3000)); |
+ webViewImpl()->handleInputEvent( |
+ generateTouchGestureEvent(WebInputEvent::GestureScrollEnd)); |
+ webViewImpl()->resizeWithBrowserControls(IntSize(400, 450), 50, false); |
+ } |
+ |
+ mainFrameView()->updateAllLifecyclePhases(); |
+ |
+ // Do a hit test at the very bottom of the screen. This should be outside |
+ // the |
+ // root scroller's LayoutBox since inert top controls won't resize the ICB |
+ // but, |
+ // since we expaned the clip, we should still be able to hit the target. |
+ WebPoint point(200, 445); |
+ WebSize tapArea(20, 20); |
+ WebHitTestResult result = |
+ webViewImpl()->hitTestResultForTap(point, tapArea); |
+ |
+ ASSERT_TRUE(result.node()); |
+ EXPECT_EQ("target", |
+ result.node().to<WebElement>().getAttribute("id").utf8()); |
+ } |
+}; |
+ |
+// Test that hit testing in the area revealed at the bottom of the screen |
+// revealed by hiding the URL bar works properly when using a root scroller |
+// when the target and scroller are in the same PaintLayer. |
+TEST_F(RootScrollerHitTest, HitTestInAreaRevealedByURLBarSameLayer) { |
+ bool oldInertTopControls = RuntimeEnabledFeatures::inertTopControlsEnabled(); |
+ RuntimeEnabledFeatures::setInertTopControlsEnabled(true); |
+ |
+ // Add a target at the bottom of the root scroller that's the size of the url |
+ // bar. We'll test that hiding the URL bar appropriately adjusts clipping so |
+ // that we can hit this target. |
+ initialize("root-scroller.html"); |
+ executeScript( |
+ "var target = document.createElement('div');" |
+ "target.style.width = '100%';" |
+ "target.style.height = '50px';" |
+ "target.id = 'target';" |
+ "document.getElementById('container').appendChild(target);"); |
+ |
+ Document* document = mainFrame()->document(); |
+ Element* container = document->getElementById("container"); |
+ Element* target = document->getElementById("target"); |
+ DummyExceptionStateForTesting exceptionState; |
+ document->setRootScroller(container, exceptionState); |
+ |
+ // This test checks hit testing while the target is in the same PaintLayer as |
+ // the root scroller. |
+ ASSERT_EQ(toLayoutBox(target->layoutObject())->enclosingLayer(), |
+ toLayoutBox(container->layoutObject())->layer()); |
+ |
+ checkHitTestAtBottomOfScreen(); |
+ |
+ RuntimeEnabledFeatures::setInertTopControlsEnabled(oldInertTopControls); |
+} |
+ |
+// Test that hit testing in the area revealed at the bottom of the screen |
+// revealed by hiding the URL bar works properly when using a root scroller |
+// when the target and scroller are in different PaintLayers. |
+TEST_F(RootScrollerHitTest, HitTestInAreaRevealedByURLBarDifferentLayer) { |
+ bool oldInertTopControls = RuntimeEnabledFeatures::inertTopControlsEnabled(); |
+ RuntimeEnabledFeatures::setInertTopControlsEnabled(true); |
+ |
+ // Add a target at the bottom of the root scroller that's the size of the url |
+ // bar. We'll test that hiding the URL bar appropriately adjusts clipping so |
+ // that we can hit this target. |
+ initialize("root-scroller.html"); |
+ executeScript( |
+ "var target = document.createElement('div');" |
+ "target.style.width = '100%';" |
+ "target.style.height = '50px';" |
+ "target.style.willChange = 'transform';" |
+ "target.id = 'target';" |
+ "document.getElementById('container').appendChild(target);"); |
+ |
+ Document* document = mainFrame()->document(); |
+ Element* container = document->getElementById("container"); |
+ Element* target = document->getElementById("target"); |
+ DummyExceptionStateForTesting exceptionState; |
+ document->setRootScroller(container, exceptionState); |
+ |
+ // Ensure the target and container weren't put into the same layer. |
+ ASSERT_NE(toLayoutBox(target->layoutObject())->enclosingLayer(), |
+ toLayoutBox(container->layoutObject())->layer()); |
+ |
+ checkHitTestAtBottomOfScreen(); |
+ |
+ RuntimeEnabledFeatures::setInertTopControlsEnabled(oldInertTopControls); |
+} |
+ |
+// Test that hit testing in the area revealed at the bottom of the screen |
+// revealed by hiding the URL bar works properly when using a root scroller |
+// inside an iframe and the target is in the same paint layer as the scroller. |
+TEST_F(RootScrollerHitTest, HitTestInAreaRevealedByURLBarIframeSameLayer) { |
+ bool oldInertTopControls = RuntimeEnabledFeatures::inertTopControlsEnabled(); |
+ RuntimeEnabledFeatures::setInertTopControlsEnabled(true); |
+ |
+ // Add a target at the bottom of the root scroller that's the size of the url |
+ // bar. We'll test that hiding the URL bar appropriately adjusts clipping so |
+ // that we can hit this target. |
+ initialize("root-scroller-iframe.html"); |
+ WebLocalFrame* childWebFrame = |
+ mainWebFrame()->firstChild()->toWebLocalFrame(); |
+ executeScript( |
+ "var target = document.createElement('div');" |
+ "target.style.width = '100%';" |
+ "target.style.height = '50px';" |
+ "target.id = 'target';" |
+ "document.getElementById('container').appendChild(target);", |
+ *childWebFrame); |
+ |
+ Element* iframe = mainFrame()->document()->getElementById("iframe"); |
+ LocalFrame* childFrame = |
+ toLocalFrame(toHTMLFrameOwnerElement(iframe)->contentFrame()); |
+ |
+ Document* childDocument = childFrame->document(); |
+ Element* container = childDocument->getElementById("container"); |
+ Element* target = childDocument->getElementById("target"); |
+ DummyExceptionStateForTesting exceptionState; |
+ childDocument->setRootScroller(container, exceptionState); |
+ mainFrame()->document()->setRootScroller(iframe, exceptionState); |
+ |
+ // This test checks hit testing while the target is in the same PaintLayer as |
+ // the root scroller. |
+ ASSERT_EQ(toLayoutBox(target->layoutObject())->enclosingLayer(), |
+ toLayoutBox(container->layoutObject())->layer()); |
+ |
+ checkHitTestAtBottomOfScreen(); |
+ |
+ RuntimeEnabledFeatures::setInertTopControlsEnabled(oldInertTopControls); |
+} |
+ |
+// Test that hit testing in the area revealed at the bottom of the screen |
+// revealed by hiding the URL bar works properly when using a root scroller |
+// inside an iframe and the target is in a different PaintLayer as the scroller. |
+TEST_F(RootScrollerHitTest, HitTestInAreaRevealedByURLBarIframeDifferentLayer) { |
+ bool oldInertTopControls = RuntimeEnabledFeatures::inertTopControlsEnabled(); |
+ RuntimeEnabledFeatures::setInertTopControlsEnabled(true); |
+ |
+ // Add a target at the bottom of the root scroller that's the size of the url |
+ // bar. We'll test that hiding the URL bar appropriately adjusts clipping so |
+ // that we can hit this target. |
+ initialize("root-scroller-iframe.html"); |
+ WebLocalFrame* childWebFrame = |
+ mainWebFrame()->firstChild()->toWebLocalFrame(); |
+ executeScript( |
+ "var target = document.createElement('div');" |
+ "target.style.width = '100%';" |
+ "target.style.height = '50px';" |
+ "target.style.willChange = 'transform';" |
+ "target.id = 'target';" |
+ "document.getElementById('container').appendChild(target);", |
+ *childWebFrame); |
+ |
+ Element* iframe = mainFrame()->document()->getElementById("iframe"); |
+ LocalFrame* childFrame = |
+ toLocalFrame(toHTMLFrameOwnerElement(iframe)->contentFrame()); |
+ |
+ Document* childDocument = childFrame->document(); |
+ Element* container = childDocument->getElementById("container"); |
+ Element* target = childDocument->getElementById("target"); |
+ DummyExceptionStateForTesting exceptionState; |
+ childDocument->setRootScroller(container, exceptionState); |
+ mainFrame()->document()->setRootScroller(iframe, exceptionState); |
+ |
+ // This test checks hit testing while the target is in a different PaintLayer |
+ // as the root scroller (ensured by will-change style). |
+ ASSERT_NE(toLayoutBox(target->layoutObject())->enclosingLayer(), |
+ toLayoutBox(container->layoutObject())->layer()); |
+ |
+ checkHitTestAtBottomOfScreen(); |
+ |
+ RuntimeEnabledFeatures::setInertTopControlsEnabled(oldInertTopControls); |
+} |
+ |
+// Test that hit testing in the area revealed at the bottom of the screen |
+// revealed by hiding the URL bar works properly when using a iframe itself as |
+// the root scroller. |
+TEST_F(RootScrollerHitTest, HitTestInAreaRevealedByURLBarIframeRootScroller) { |
+ bool oldInertTopControls = RuntimeEnabledFeatures::inertTopControlsEnabled(); |
+ RuntimeEnabledFeatures::setInertTopControlsEnabled(true); |
+ |
+ // Add a target at the bottom of the root scroller that's the size of the url |
+ // bar. We'll test that hiding the URL bar appropriately adjusts clipping so |
+ // that we can hit this target. |
+ initialize("root-scroller-iframe.html"); |
+ WebLocalFrame* childWebFrame = |
+ mainWebFrame()->firstChild()->toWebLocalFrame(); |
+ executeScript( |
+ "var target = document.createElement('div');" |
+ "target.style.width = '100%';" |
+ "target.style.height = '50px';" |
+ "target.id = 'target';" |
+ "document.getElementById('container').innerHTML = '';" |
+ "document.getElementById('container').style.height = '200%';" |
+ "document.body.appendChild(target);", |
+ *childWebFrame); |
+ |
+ Element* iframe = mainFrame()->document()->getElementById("iframe"); |
+ |
+ DummyExceptionStateForTesting exceptionState; |
+ mainFrame()->document()->setRootScroller(iframe, exceptionState); |
+ |
+ checkHitTestAtBottomOfScreen(); |
+ |
+ RuntimeEnabledFeatures::setInertTopControlsEnabled(oldInertTopControls); |
+} |
+ |
} // namespace |
} // namespace blink |