Scrolling allowed when overflow:hidden (seen on Acid2)

Autoscroll, as well as other user-driven scroll actions,
has to respect the scrollability styled into the web page.
More specifically, if a html or body tags are styled with
overflow:hidden, autoscroll should not scroll the containing document.

In order to fix this, patch hardens RenderBox::canAutoscroll as
following: previously, ::canAutoscroll was relying only on
::canBeScrolledAndHasScrollableArea to determine the scrollability
of #document node, which was unconditionally returned as 'true'.
Patch extends ::canAutoscroll to handle the #document case for
main and inner frames, and now it asks through ::isScrollable if
the corresponding document's FrameView is actually user-scrollable.

Note, that the patch changes ::canAutoscroll to cover the non-mainFrame
case now.

Autoscroll'ing the mainframe's document is hard with the current
EventSender machinary. Because of that, patch adds an iframe's document test case.
Test added in fast/events/autoscroll-in-overflow-hidden-html.html

Corresponding WebKit commit: <http://trac.webkit.org/changeset/154722>

BUG=chromium:1701

Review URL: https://chromiumcodereview.appspot.com/23450017

git-svn-id: svn://svn.chromium.org/blink/trunk@157371 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent f2dea752
Document whose HTML or BODY tags have overflow:hidden should not autoscroll.
PASSED: the autoscroll has not happened.
<html>
<head>
<script src="../js/resources/js-test-pre.js"></script>
<script>
function log(msg)
{
document.getElementById('console').appendChild(document.createTextNode(msg + '\n'));
}
var iframe;
var iframeDocument;
var iframeScrollTopAfterAnchor = 0;
function test()
{
if (window.testRunner) {
testRunner.waitUntilDone();
testRunner.dumpAsText();
}
iframe = document.getElementById('NoScrolliFrame');
iframeDocument = iframe.contentDocument;
iframeScrollTopAfterAnchor = 0;
var clickme = iframeDocument.getElementById('clickme');
var x = iframe.offsetLeft + clickme.offsetLeft + 7;
var y = iframe.offsetTop + clickme.offsetTop + 7;
if (window.eventSender) {
eventSender.dragMode = false;
eventSender.mouseMoveTo(x, y);
eventSender.mouseDown();
eventSender.mouseUp();
}
setTimeout(autoscrollTestPart1, 0);
}
function autoscrollTestPart1()
{
iframeScrollTopAfterAnchor = iframeDocument.body.scrollTop;
if (iframeDocument.body.scrollTop == 0)
log("FAILED: anchor clicking within non-scrollable inner frame failed.");
if (window.eventSender) {
var textInIframe = iframeDocument.getElementById('textInFrame');
var x = iframe.offsetLeft + textInIframe.offsetLeft - iframeDocument.body.scrollLeft + 7;
var y = iframe.offsetTop + textInIframe.offsetTop - iframeDocument.body.scrollTop + 7;
eventSender.dragMode = false;
eventSender.mouseMoveTo(x, y);
eventSender.mouseDown();
eventSender.mouseMoveTo(x, y - 10);
y = iframe.offsetTop;
eventSender.mouseMoveTo(x, y - 5);
}
setTimeout(autoscrollTestPart2, 100);
}
function autoscrollTestPart2()
{
if (window.eventSender)
eventSender.mouseUp();
log("Document whose HTML or BODY tags have overflow:hidden should not autoscroll.");
if (iframeScrollTopAfterAnchor == iframeDocument.body.scrollTop)
log("PASSED: the autoscroll has not happened.");
else
log("FAILED: the autoscroll has happened.");
if (window.testRunner)
testRunner.notifyDone();
}
</script>
</head>
<body onload="test()">
<iframe id="NoScrolliFrame" style="height: 150px; width: 150px" src="resources/big-page-with-overflow-hidden-and-anchor-scroll.html" ></iframe>
<div id="console"></div>
</body>
</html>
<head>
<style type="text/css">
html { overflow: hidden; }
#anchor { margin: 100em 0em 0;}
.picture {margin: 0 0 50em 0em; }
</style>
</head>
<body>
<a id="clickme" href="#anchor">Click here</a>
<h2 id="anchor">Any text</h2>
<div id="textInFrame" class="picture">
<span> click and hold and drag mouse up to see if it scrolls.</div>
</div>
<div id="console"></div>
</body>
......@@ -751,18 +751,11 @@ bool RenderBox::autoscrollInProgress() const
// There are two kinds of renderer that can autoscroll.
bool RenderBox::canAutoscroll() const
{
// Check for a box that can be scrolled in its own right.
if (canBeScrolledAndHasScrollableArea())
return true;
if (node() && node()->isDocumentNode())
return view()->frameView()->isScrollable();
// Check for a box that represents the top level of a web page.
if (node() != &document())
return false;
Frame* frame = this->frame();
if (!frame)
return false;
Page* page = frame->page();
return page && page->mainFrame() == frame && frame->view()->isScrollable();
// Check for a box that can be scrolled in its own right.
return canBeScrolledAndHasScrollableArea();
}
// If specified point is in border belt, returned offset denotes direction of
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment