REGRESSION (r173784): [Mac] Correct latching error for non-scrollable iframe nested...
authorbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 5 Aug 2015 01:26:16 +0000 (01:26 +0000)
committerbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 5 Aug 2015 01:26:16 +0000 (01:26 +0000)
https://bugs.webkit.org/show_bug.cgi?id=147668
<rdar://problem/21870332>

Reviewed by Simon Fraser.

Source/WebCore:

Test: platform/mac/fast/scrolling/scroll-div-with-nested-nonscrollable-iframe.html

When we are wrapping up processing of the wheel event for a given frame, if the current latching context
does NOT apply to the current frame (e.g., because it's latched to an enclosing frame) we should not pass
wheel events directly to the latched elements scrollable container. Instead, we should just give the current
frame an opportunity to perform any custom wheel event handling and return, so that the enclosing (latched)
frame can do the rest of its event handling.

If we don't do this, we incorrectly ask the enclosing frame to process the event, then return claiming that
we handled the event, preventing the enclosing frame from doing its part of the processing.

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

LayoutTests:

* platform/mac/fast/scrolling/resources/background.html: Added.
* platform/mac/fast/scrolling/scroll-div-with-nested-nonscrollable-iframe-expected.txt: Added.
* platform/mac/fast/scrolling/scroll-div-with-nested-nonscrollable-iframe.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/platform/mac/fast/scrolling/resources/background.html [new file with mode: 0644]
LayoutTests/platform/mac/fast/scrolling/scroll-div-with-nested-nonscrollable-iframe-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/fast/scrolling/scroll-div-with-nested-nonscrollable-iframe.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/page/mac/EventHandlerMac.mm

index fa1f715..2fc124b 100644 (file)
@@ -1,3 +1,15 @@
+2015-08-04  Brent Fulgham  <bfulgham@apple.com>
+
+        REGRESSION (r173784): [Mac] Correct latching error for non-scrollable iframe nested inside scrollable div.
+        https://bugs.webkit.org/show_bug.cgi?id=147668
+        <rdar://problem/21870332>
+
+        Reviewed by Simon Fraser.
+
+        * platform/mac/fast/scrolling/resources/background.html: Added.
+        * platform/mac/fast/scrolling/scroll-div-with-nested-nonscrollable-iframe-expected.txt: Added.
+        * platform/mac/fast/scrolling/scroll-div-with-nested-nonscrollable-iframe.html: Added.
+
 2015-08-04  Chris Dumez  <cdumez@apple.com>
 
         Subframes with no current HistoryItem should not prevent page-caching
diff --git a/LayoutTests/platform/mac/fast/scrolling/resources/background.html b/LayoutTests/platform/mac/fast/scrolling/resources/background.html
new file mode 100644 (file)
index 0000000..528ed32
--- /dev/null
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+    div {
+        position: relative;
+        width: 400px;
+        height: 2000px;
+        padding: 0;
+        background-image: repeating-linear-gradient(to bottom, white, silver 200px);
+    }
+    </style>
+</head>
+<body>
+    <div>This content is displayed in an iframe. The iframe should be sized such that it does not need to scroll.</div>
+</body>
+</html>
diff --git a/LayoutTests/platform/mac/fast/scrolling/scroll-div-with-nested-nonscrollable-iframe-expected.txt b/LayoutTests/platform/mac/fast/scrolling/scroll-div-with-nested-nonscrollable-iframe-expected.txt
new file mode 100644 (file)
index 0000000..8d98581
--- /dev/null
@@ -0,0 +1,16 @@
+Put mouse inside the iframe (below) and flick downwards
+
+Tests that iframe does scroll when inner iframe is NOT scrollable.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+PASS div did scroll.
+PASS Page did NOT scroll.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/mac/fast/scrolling/scroll-div-with-nested-nonscrollable-iframe.html b/LayoutTests/platform/mac/fast/scrolling/scroll-div-with-nested-nonscrollable-iframe.html
new file mode 100644 (file)
index 0000000..a6c4d94
--- /dev/null
@@ -0,0 +1,118 @@
+<!DOCTYPE html>
+<html>
+<head>
+<link rel="help" href="http://www.w3.org/TR/DOM-Level-3-Events/#events-WheelEvent">
+<script src="../../../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<script>
+
+var divTarget;
+var pageScrollPositionBefore;
+var divScrollPositionBefore;
+
+var continueCount = 5;
+
+function locationInWindowCoordinates(element)
+{
+    var position = {};
+    position.x = element.offsetLeft;
+    position.y = element.offsetTop;
+
+    while (element.offsetParent) {
+        position.x = position.x + element.offsetParent.offsetLeft;
+        position.y = position.y + element.offsetParent.offsetTop;
+        if (element == document.getElementsByTagName("body")[0])
+            break;
+
+        element = element.offsetParent;
+    }
+
+    return position;
+}
+
+function finishTest()
+{
+    finishJSTest();
+    testRunner.notifyDone();            
+}
+
+function checkForScroll() {
+    var pageScrollPositionAfter = document.body.scrollTop;
+    var divScrollPositionAfter = divTarget.scrollTop;
+
+    if (divScrollPositionBefore != divScrollPositionAfter)
+        testPassed("div did scroll.");
+    else
+        testFailed("div did NOT scroll.");
+
+    if (pageScrollPositionBefore == pageScrollPositionAfter)
+        testPassed("Page did NOT scroll.");
+    else
+        testFailed("Page DID scroll.");
+
+    finishTest();
+}
+
+function scrollTest() {
+    pageScrollPositionBefore = document.body.scrollTop;
+
+    divTarget = document.getElementById('scrollable_div');
+
+    var windowPosition = locationInWindowCoordinates(divTarget);
+
+    var startPosX = windowPosition.x + 0.5 * divTarget.clientWidth;
+    var startPosY = windowPosition.y + 0.5 * divTarget.clientHeight;
+
+    divScrollPositionBefore = divTarget.scrollTop;
+
+    // Scroll the #source until we reach the #target.
+    eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'begin', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'none', 'end', true);
+    eventSender.callAfterScrollingCompletes(checkForScroll);
+}
+
+function setupTopLevel() {
+
+    if (window.eventSender) {
+        testRunner.waitUntilDone();
+
+        eventSender.monitorWheelEvents();
+        setTimeout(scrollTest, 0);
+    } else {
+        var messageLocation = document.getElementById('parent');
+        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 the mouse wheel or a two-finger swipe to scroll the IFrame to the bottom (and beyond).<br/>"
+            + "<br/><br/>"
+            + "The test passes if you scroll far enough to see the row of END labels but the main page does not scroll.</p>";
+        messageLocation.appendChild(message);
+    }
+}
+
+</script>
+<div id="parent" style="height: 2000px">
+    <div id="source" style="height: 20px">
+        Put mouse inside the iframe (below) and flick downwards
+    </div>
+    <div id="scrollable_div" style="height: 400px; width: 430px; overflow-y:auto; padding: 0;">
+        <iframe id="non_scrollable_iframe" src="resources/background.html" style="height: 2100px; width:410px; overflow:hidden; scrolling: no" onload="setupTopLevel();">
+        </iframe>
+    </div>
+</div>
+<div id="console"></div>
+<script>
+description("Tests that iframe does scroll when inner iframe is NOT scrollable.");
+</script>
+<script src="../../../../resources/js-test-post.js"></script>
+</body>
+</html>
index a32da40..dcb1d0a 100644 (file)
@@ -1,3 +1,25 @@
+2015-08-04  Brent Fulgham  <bfulgham@apple.com>
+
+        REGRESSION (r173784): [Mac] Correct latching error for non-scrollable iframe nested inside scrollable div.
+        https://bugs.webkit.org/show_bug.cgi?id=147668
+        <rdar://problem/21870332>
+
+        Reviewed by Simon Fraser.
+
+        Test: platform/mac/fast/scrolling/scroll-div-with-nested-nonscrollable-iframe.html
+
+        When we are wrapping up processing of the wheel event for a given frame, if the current latching context
+        does NOT apply to the current frame (e.g., because it's latched to an enclosing frame) we should not pass
+        wheel events directly to the latched elements scrollable container. Instead, we should just give the current
+        frame an opportunity to perform any custom wheel event handling and return, so that the enclosing (latched)
+        frame can do the rest of its event handling.
+        
+        If we don't do this, we incorrectly ask the enclosing frame to process the event, then return claiming that
+        we handled the event, preventing the enclosing frame from doing its part of the processing.
+
+        * page/mac/EventHandlerMac.mm:
+        (WebCore::EventHandler::platformCompleteWheelEvent):
+
 2015-08-04  Alex Christensen  <achristensen@webkit.org>
 
         Soft link libGLESv2 and libEGL on Windows again
index 5d5c8e2..5569e34 100644 (file)
@@ -1009,7 +1009,7 @@ bool EventHandler::platformCompleteWheelEvent(const PlatformWheelEvent& wheelEve
     FrameView* view = m_frame.view();
 
     ScrollLatchingState* latchingState = m_frame.mainFrame().latchingState();
-    if (wheelEvent.useLatchedEventElement() && latchingState && latchingState->scrollableContainer()) {
+    if (wheelEvent.useLatchedEventElement() && !latchingIsLockedToAncestorOfThisFrame(m_frame) && latchingState && latchingState->scrollableContainer()) {
 
         m_isHandlingWheelEvent = false;