- 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);