Scrolling iframe inside scrollable div does not work with trackpad
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 7 Nov 2015 02:32:13 +0000 (02:32 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 7 Nov 2015 02:32:13 +0000 (02:32 +0000)
https://bugs.webkit.org/show_bug.cgi?id=150168
<rdar://problem/23143931>

Reviewed by Brent Fulgham.

Source/WebCore:

When scrolling in an iframe nested under an overflow scrolling region, EventHandler::platformPrepareForWheelEvents
fails to compute the correct scrollableArea, using the overflow div's scrollable area instead of the iframe's view.
This causes the latching algorithm to bail out of handling the wheel event. To avoid this, we special-case the
decision to compute the scrollableArea from the scrollableContainer if we are attempting to scroll in an iframe.

Test: fast/scrolling/latching/scroll-iframe-in-overflow.html

* page/mac/EventHandlerMac.mm:
(WebCore::EventHandler::platformPrepareForWheelEvents):

LayoutTests:

Tests that an iframe nested under an overflow scrolling div can be scrolled.

* fast/scrolling/latching/scroll-iframe-in-overflow-expected.txt: Added.
* fast/scrolling/latching/scroll-iframe-in-overflow.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@192124 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/scrolling/latching/scroll-iframe-in-overflow-expected.txt [new file with mode: 0644]
LayoutTests/fast/scrolling/latching/scroll-iframe-in-overflow.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/page/mac/EventHandlerMac.mm

index 555345f..8d62b99 100644 (file)
@@ -1,3 +1,16 @@
+2015-11-06  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        Scrolling iframe inside scrollable div does not work with trackpad
+        https://bugs.webkit.org/show_bug.cgi?id=150168
+        <rdar://problem/23143931>
+
+        Reviewed by Brent Fulgham.
+
+        Tests that an iframe nested under an overflow scrolling div can be scrolled.
+
+        * fast/scrolling/latching/scroll-iframe-in-overflow-expected.txt: Added.
+        * fast/scrolling/latching/scroll-iframe-in-overflow.html: Added.
+
 2015-11-06  Myles C. Maxfield  <mmaxfield@apple.com>
 
         REGRESSION(r182286): Tatechuyoko following ruby is drawn too far to the right
diff --git a/LayoutTests/fast/scrolling/latching/scroll-iframe-in-overflow-expected.txt b/LayoutTests/fast/scrolling/latching/scroll-iframe-in-overflow-expected.txt
new file mode 100644 (file)
index 0000000..f704196
--- /dev/null
@@ -0,0 +1,2 @@
+PASS The iframe scrolled but the wrapper did not.
+
diff --git a/LayoutTests/fast/scrolling/latching/scroll-iframe-in-overflow.html b/LayoutTests/fast/scrolling/latching/scroll-iframe-in-overflow.html
new file mode 100644 (file)
index 0000000..d25667a
--- /dev/null
@@ -0,0 +1,78 @@
+<html>
+<head>
+    <script src="../../../resources/js-test-pre.js"></script>
+    <style type="text/css">
+    #wrapper {
+        height: 400px;
+        width: 600px;
+        overflow: scroll;
+        background-color: #EEE;
+    }
+
+    iframe {
+        background-color: #CCC;
+        width: 400px;
+        height: 100px;
+        margin-bottom: 1000px;
+    }
+
+    body {
+        margin: 0;
+    }
+    </style>
+    <script>
+    window.jsTestIsAsync = true;
+
+    function checkForScroll() {
+        var iframe = document.getElementById("frame");
+        var wrapper = document.getElementById("wrapper");
+        if (iframe.contentWindow.scrollY && !wrapper.scrollTop)
+            testPassed("The iframe scrolled but the wrapper did not.");
+        else
+            testFailed("The iframe's scroll position is: " + iframe.contentWindow.scrollY + ", and the wrapper's scroll position is: " + wrapper.scrollTop);
+
+        testRunner.notifyDone();
+    }
+
+    function scrollTest() {
+        eventSender.mouseMoveTo(200, 50);
+        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, "began", "none");
+        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, "changed", "none");
+        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, "changed", "none");
+        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, "changed", "none");
+        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, "changed", "none");
+        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, "changed", "none");
+        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, "ended", "none");
+        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -10, "none", "begin");
+        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -10, "none", "continue");
+        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -10, "none", "continue");
+        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -10, "none", "continue");
+        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -10, "none", "continue");
+        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -10, "none", "continue");
+        eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, "none", "end");
+        eventSender.callAfterScrollingCompletes(checkForScroll);
+    }
+
+    function setup() {
+        if (window.eventSender) {
+            eventSender.monitorWheelEvents();
+            setTimeout(scrollTest, 0);
+        } else {
+            var message = document.createElement("div");
+            message.innerHTML = "<p>This test is better run under DumpRenderTree. To manually test it, place the mouse pointer<br/>"
+                + "inside the IFrame, then use a two-finger swipe to scroll the iframe to the bottom (and beyond).<br/>"
+                + "<br/><br/>"
+                + "The test passes if the overflow container does not scroll but the iframe scrolls to the bottom.</p>";
+            document.body.appendChild(message);
+        }
+    }
+
+    </script>
+</head>
+<body onload="setup()">
+    <div id="wrapper">
+        <iframe id="frame" src="./resources/inner_content.html"></iframe>
+    </div>
+    <script src="../../../resources/js-test-post.js"></script>
+</body>
+</html>
index 6bf3987..7caa83c 100644 (file)
@@ -1,3 +1,21 @@
+2015-11-06  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        Scrolling iframe inside scrollable div does not work with trackpad
+        https://bugs.webkit.org/show_bug.cgi?id=150168
+        <rdar://problem/23143931>
+
+        Reviewed by Brent Fulgham.
+
+        When scrolling in an iframe nested under an overflow scrolling region, EventHandler::platformPrepareForWheelEvents
+        fails to compute the correct scrollableArea, using the overflow div's scrollable area instead of the iframe's view.
+        This causes the latching algorithm to bail out of handling the wheel event. To avoid this, we special-case the
+        decision to compute the scrollableArea from the scrollableContainer if we are attempting to scroll in an iframe.
+
+        Test: fast/scrolling/latching/scroll-iframe-in-overflow.html
+
+        * page/mac/EventHandlerMac.mm:
+        (WebCore::EventHandler::platformPrepareForWheelEvents):
+
 2015-11-06  Brady Eidson  <beidson@apple.com>
 
         Modern IDB: Make the result data for a "get" request be an IDBGetResult.
index db97677..fffde8c 100644 (file)
@@ -932,7 +932,7 @@ void EventHandler::platformPrepareForWheelEvents(const PlatformWheelEvent& wheel
             scrollableArea = scrollViewForEventTarget(wheelEventTarget.get());
         } else {
             scrollableContainer = findEnclosingScrollableContainer(wheelEventTarget.get(), wheelEvent.deltaX(), wheelEvent.deltaY());
-            if (scrollableContainer)
+            if (scrollableContainer && !is<HTMLIFrameElement>(wheelEventTarget.get()))
                 scrollableArea = scrollableAreaForContainerNode(*scrollableContainer);
             else {
                 scrollableContainer = view->frame().document()->bodyOrFrameset();