Title: [185201] trunk
Revision
185201
Author
bfulg...@apple.com
Date
2015-06-04 10:53:24 -0700 (Thu, 04 Jun 2015)

Log Message

REGRESSION (r181879): Scrolling order on pages with focused iframe is broken.
https://bugs.webkit.org/show_bug.cgi?id=145637
<rdar://problem/20635581>

Reviewed by Zalan Bujtas.

Source/WebCore:

Test: platform/mac-wk2/tiled-drawing/scrolling/iframe_in_iframe.html

This page revealed a bug in our RenderBox code caused by the mismatch between
our scrolling units, which are all integrally snapped, with our client height
and widths, which are not snapped at all. 
        
In certain cases, the client height would have a small subpixel difference compared
to the scroll height, which would cause WebKit to believe it was scrollable. When
this happened, it would get stuck latched to this element and block scrolling events. 

* page/Frame.cpp:
(WebCore::Frame::scrollOverflowLayer): Use roundToInt for clientWidth and clientHeight,
rather than integer truncation.
* rendering/RenderBox.cpp:
(WebCore::RenderBox::canBeScrolledAndHasScrollableArea): Need to round clientWidth
and clientHeight to compare with scrollWidth/scrollHeight.
* rendering/RenderBox.h:
(WebCore::RenderBox::hasScrollableOverflowX): Ditto.
(WebCore::RenderBox::hasScrollableOverflowY): Ditto.
* rendering/RenderMarquee.cpp:
(WebCore::RenderMarquee::computePosition): Use roundToInt for clientWidth and
clientHeight, rather than integer truncation.

LayoutTests:

* platform/mac-wk2/tiled-drawing/scrolling/iframe_in_iframe-expected.txt: Added.
* platform/mac-wk2/tiled-drawing/scrolling/iframe_in_iframe.html: Added.
* platform/mac-wk2/tiled-drawing/scrolling/resources/inner_content.html: Added.
* platform/mac-wk2/tiled-drawing/scrolling/resources/testContent.html: Added.
* platform/mac-wk2/tiled-drawing/scrolling/resources/testImage.png: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (185200 => 185201)


--- trunk/LayoutTests/ChangeLog	2015-06-04 16:50:38 UTC (rev 185200)
+++ trunk/LayoutTests/ChangeLog	2015-06-04 17:53:24 UTC (rev 185201)
@@ -1,3 +1,17 @@
+2015-06-03  Brent Fulgham  <bfulg...@apple.com>
+
+        REGRESSION (r181879): Scrolling order on pages with focused iframe is broken.
+        https://bugs.webkit.org/show_bug.cgi?id=145637
+        <rdar://problem/20635581>
+
+        Reviewed by Zalan Bujtas.
+
+        * platform/mac-wk2/tiled-drawing/scrolling/iframe_in_iframe-expected.txt: Added.
+        * platform/mac-wk2/tiled-drawing/scrolling/iframe_in_iframe.html: Added.
+        * platform/mac-wk2/tiled-drawing/scrolling/resources/inner_content.html: Added.
+        * platform/mac-wk2/tiled-drawing/scrolling/resources/testContent.html: Added.
+        * platform/mac-wk2/tiled-drawing/scrolling/resources/testImage.png: Added.
+
 2015-06-04  Zalan Bujtas  <za...@apple.com>
 
         css3/filters/backdrop/backdrop-filter-with-mask.html is missing the mask layer.

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/iframe_in_iframe-expected.txt (0 => 185201)


--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/iframe_in_iframe-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/iframe_in_iframe-expected.txt	2015-06-04 17:53:24 UTC (rev 185201)
@@ -0,0 +1,17 @@
+Inner Frame:
+
+Tests that iframe doesn't pass wheel events to main frame when scrolling inside iframe
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+PASS Page did not receive wheel events.
+PASS iframe did not receive wheel events.
+PASS iframe received wheel events.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/iframe_in_iframe.html (0 => 185201)


--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/iframe_in_iframe.html	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/iframe_in_iframe.html	2015-06-04 17:53:24 UTC (rev 185201)
@@ -0,0 +1,114 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>iFrame in iFrame Test</title>
+        <style>
+        * {
+            box-sizing: border-box;
+        }
+
+        .container {
+            width:100%;
+            overflow:auto;
+            height:auto;
+        }
+
+        .innercontainer {
+            height:100%;
+            width:50%;
+        }
+        </style>
+        <script src=""
+    </head>
+    <body>
+<script>
+
+var iframeTarget;
+var innerIFrameTarget;
+var pageScrollPositionBefore;
+var iFrameScrollPositionBefore;
+var continueCount = 5;
+
+function checkForScroll()
+{
+    // The IFrame should not have scrolled at all.
+    var pageScrollPositionAfter = document.body.scrollTop;
+    var iFrameScrollPositionAfter = window.frames['target'].document.body.scrollTop;
+    var innerIFrameScrollPositionAfter = iframeTarget.contentWindow.frames['target'].document.body.scrollTop;
+
+    if (pageScrollPositionBefore != pageScrollPositionAfter)
+        testFailed("Page received wheel events.");
+    else
+        testPassed("Page did not receive wheel events.");
+
+    if (iFrameScrollPositionBefore != iFrameScrollPositionAfter)
+        testFailed("iframe received wheel events.");
+    else
+        testPassed("iframe did not receive wheel events.");
+
+    if (innerIFrameScrollPositionBefore != innerIFrameScrollPositionAfter)
+        testPassed("iframe received wheel events.");
+    else
+        testFailed("iframe did not receive wheel events.");
+
+    finishJSTest();
+    testRunner.notifyDone();
+}
+
+function scrollTest()
+{
+    pageScrollPositionBefore = document.body.scrollTop;
+
+    iframeTarget = document.getElementById('target');
+
+    var iFrameBody = window.frames['target'].document.body;
+    iFrameScrollPositionBefore = iFrameBody.scrollTop;
+
+    innerIFrameTarget = iframeTarget.contentWindow.frames['target'].document.body;
+    innerIFrameScrollPositionBefore = innerIFrameTarget.scrollTop;
+
+    // Scroll the #source until we reach the #target.
+    var startPosX = Math.round(iframeTarget.offsetLeft) + 20;
+    var startPosY = Math.round(iframeTarget.offsetTop) + 80;
+    eventSender.mouseMoveTo(startPosX, startPosY);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none');
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none');
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none');
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none');
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'begin');
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue');
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue');
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue');
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue');
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'none', 'end');
+    eventSender.callAfterScrollingCompletes(checkForScroll);
+}
+
+function setupTopLevel()
+{
+    if (window.eventSender) {
+        testRunner.dumpAsText();
+        testRunner.waitUntilDone();
+
+        eventSender.monitorWheelEvents();
+        setTimeout(scrollTest, 0);
+    }
+}
+</script>
+        <div class="container">
+            <div class="innercontainer">
+                <div style="width:100%;">
+                    <div>Inner Frame:</div>
+                    <div style="height:92%;">
+                        <iframe id="target" name="target" src="" _onload_="setupTopLevel();"></iframe>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div id="console"></div>
+        <script>
+        description("Tests that iframe doesn't pass wheel events to main frame when scrolling inside iframe");
+        </script>
+        <script src=""
+    </body>
+</html>
\ No newline at end of file

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/resources/inner_content.html (0 => 185201)


--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/resources/inner_content.html	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/resources/inner_content.html	2015-06-04 17:53:24 UTC (rev 185201)
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html lang="en-US">
+    <head>
+        <title>Inner iFrame Example</title>
+        <meta charset="utf-8">
+        <style>
+        img {
+            display:block;
+            max-width:100%;
+        }
+        </style>
+    </head>
+    <body style="position: relative; min-height: 100%; top: 0px;">
+        <div style="overflow:auto;">
+            <img src=""
+            <div>TEST CASE TEST CASE TEST CASE TEST CASE</div>
+        </div>
+        <div style="overflow:auto;">
+            <h1>TEST HEADING</h1>
+            <p>Test paragraph.</p>
+            <div>TEST BUTTON 1</div>
+            <div>TEST BUTTON 2</div>      
+        </div>
+    </body>
+</html>
\ No newline at end of file

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/resources/testContent.html (0 => 185201)


--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/resources/testContent.html	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/resources/testContent.html	2015-06-04 17:53:24 UTC (rev 185201)
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<body>
+
+<p>An iframe where scrollbars are always shown:</p>
+<iframe id="target" name="target" src="" width="200" height="200" scrolling="yes">
+  <p>Your browser does not support iframes.</p>
+</iframe>
+
+<p>An iframe where scrollbars are never shown:</p>
+<iframe src="" width="200" height="200" scrolling="no">
+  <p>Your browser does not support iframes.</p>
+</iframe>
+
+<p>The scrolling attribute is not supported in HTML5. Use CSS instead.</p>
+
+</body>
+</html>
\ No newline at end of file

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/resources/testImage.png


(Binary files differ)
Property changes on: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/resources/testImage.png ___________________________________________________________________

Added: svn:mime-type

Modified: trunk/Source/WebCore/ChangeLog (185200 => 185201)


--- trunk/Source/WebCore/ChangeLog	2015-06-04 16:50:38 UTC (rev 185200)
+++ trunk/Source/WebCore/ChangeLog	2015-06-04 17:53:24 UTC (rev 185201)
@@ -1,3 +1,34 @@
+2015-06-03  Brent Fulgham  <bfulg...@apple.com>
+
+        REGRESSION (r181879): Scrolling order on pages with focused iframe is broken.
+        https://bugs.webkit.org/show_bug.cgi?id=145637
+        <rdar://problem/20635581>
+
+        Reviewed by Zalan Bujtas.
+
+        Test: platform/mac-wk2/tiled-drawing/scrolling/iframe_in_iframe.html
+
+        This page revealed a bug in our RenderBox code caused by the mismatch between
+        our scrolling units, which are all integrally snapped, with our client height
+        and widths, which are not snapped at all. 
+        
+        In certain cases, the client height would have a small subpixel difference compared
+        to the scroll height, which would cause WebKit to believe it was scrollable. When
+        this happened, it would get stuck latched to this element and block scrolling events. 
+
+        * page/Frame.cpp:
+        (WebCore::Frame::scrollOverflowLayer): Use roundToInt for clientWidth and clientHeight,
+        rather than integer truncation.
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::canBeScrolledAndHasScrollableArea): Need to round clientWidth
+        and clientHeight to compare with scrollWidth/scrollHeight.
+        * rendering/RenderBox.h:
+        (WebCore::RenderBox::hasScrollableOverflowX): Ditto.
+        (WebCore::RenderBox::hasScrollableOverflowY): Ditto.
+        * rendering/RenderMarquee.cpp:
+        (WebCore::RenderMarquee::computePosition): Use roundToInt for clientWidth and
+        clientHeight, rather than integer truncation.
+
 2015-06-04  Myles C. Maxfield  <mmaxfi...@apple.com>
 
         [Cocoa] Clean up m_font inside FontPlatformData

Modified: trunk/Source/WebCore/page/Frame.cpp (185200 => 185201)


--- trunk/Source/WebCore/page/Frame.cpp	2015-06-04 16:50:38 UTC (rev 185200)
+++ trunk/Source/WebCore/page/Frame.cpp	2015-06-04 17:53:24 UTC (rev 185201)
@@ -501,7 +501,7 @@
     int x = layer->scrollXOffset();
     int exposeLeft = exposeRect.x();
     int exposeRight = exposeLeft + exposeRect.width();
-    int clientWidth = box->clientWidth();
+    int clientWidth = roundToInt(box->clientWidth());
     if (exposeLeft <= 0)
         x = std::max(0, x + exposeLeft - clientWidth / 2);
     else if (exposeRight >= clientWidth)
@@ -510,7 +510,7 @@
     int y = layer->scrollYOffset();
     int exposeTop = exposeRect.y();
     int exposeBottom = exposeTop + exposeRect.height();
-    int clientHeight = box->clientHeight();
+    int clientHeight = roundToInt(box->clientHeight());
     if (exposeTop <= 0)
         y = std::max(0, y + exposeTop - clientHeight / 2);
     else if (exposeBottom >= clientHeight)

Modified: trunk/Source/WebCore/rendering/RenderBox.cpp (185200 => 185201)


--- trunk/Source/WebCore/rendering/RenderBox.cpp	2015-06-04 16:50:38 UTC (rev 185200)
+++ trunk/Source/WebCore/rendering/RenderBox.cpp	2015-06-04 17:53:24 UTC (rev 185201)
@@ -876,7 +876,7 @@
 
 bool RenderBox::canBeScrolledAndHasScrollableArea() const
 {
-    return canBeProgramaticallyScrolled() && (scrollHeight() != clientHeight() || scrollWidth() != clientWidth());
+    return canBeProgramaticallyScrolled() && (scrollHeight() != roundToInt(clientHeight()) || scrollWidth() != roundToInt(clientWidth()));
 }
 
 bool RenderBox::isScrollableOrRubberbandableBox() const

Modified: trunk/Source/WebCore/rendering/RenderBox.h (185200 => 185201)


--- trunk/Source/WebCore/rendering/RenderBox.h	2015-06-04 16:50:38 UTC (rev 185200)
+++ trunk/Source/WebCore/rendering/RenderBox.h	2015-06-04 17:53:24 UTC (rev 185201)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 1999 Lars Knoll (kn...@kde.org)
  *           (C) 1999 Antti Koivisto (koivi...@kde.org)
- * Copyright (C) 2003, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2006, 2007, 2015 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -477,8 +477,8 @@
     bool scrollsOverflow() const { return scrollsOverflowX() || scrollsOverflowY(); }
     bool scrollsOverflowX() const { return hasOverflowClip() && (style().overflowX() == OSCROLL || hasHorizontalScrollbarWithAutoBehavior()); }
     bool scrollsOverflowY() const { return hasOverflowClip() && (style().overflowY() == OSCROLL || hasVerticalScrollbarWithAutoBehavior()); }
-    bool hasScrollableOverflowX() const { return scrollsOverflowX() && scrollWidth() != clientWidth(); }
-    bool hasScrollableOverflowY() const { return scrollsOverflowY() && scrollHeight() != clientHeight(); }
+    bool hasScrollableOverflowX() const { return scrollsOverflowX() && scrollWidth() != roundToInt(clientWidth()); }
+    bool hasScrollableOverflowY() const { return scrollsOverflowY() && scrollHeight() != roundToInt(clientHeight()); }
 
     bool usesCompositedScrolling() const;
     

Modified: trunk/Source/WebCore/rendering/RenderMarquee.cpp (185200 => 185201)


--- trunk/Source/WebCore/rendering/RenderMarquee.cpp	2015-06-04 16:50:38 UTC (rev 185200)
+++ trunk/Source/WebCore/rendering/RenderMarquee.cpp	2015-06-04 17:53:24 UTC (rev 185201)
@@ -135,7 +135,7 @@
     }
     else {
         int contentHeight = box->layoutOverflowRect().maxY() - box->borderTop() + box->paddingBottom();
-        int clientHeight = box->clientHeight();
+        int clientHeight = roundToInt(box->clientHeight());
         if (dir == MUP) {
             if (stopAtContentEdge)
                  return std::min(contentHeight - clientHeight, 0);
@@ -271,7 +271,7 @@
             addIncrement = !addIncrement;
         }
         bool positive = range > 0;
-        int clientSize = (isHorizontal() ? m_layer->renderBox()->clientWidth() : m_layer->renderBox()->clientHeight());
+        int clientSize = (isHorizontal() ? roundToInt(m_layer->renderBox()->clientWidth()) : roundToInt(m_layer->renderBox()->clientHeight()));
         int increment = abs(intValueForLength(m_layer->renderer().style().marqueeIncrement(), clientSize));
         int currentPos = (isHorizontal() ? m_layer->scrollXOffset() : m_layer->scrollYOffset());
         newPos =  currentPos + (addIncrement ? increment : -increment);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to