Commit ce8f1831 authored by tonikitoo@webkit.org's avatar tonikitoo@webkit.org
Browse files

Text dragging can scroll overflow:hidden boxes https://bugs.webkit.org/show_bug.cgi?id=119760

Reviewed by Darin Adler.
Patch by Antonio Gomes <a1.gomes@sisa.samsung.com>

Source/WebCore:

Consider the case of the following HTML:
<div style="overflow:hidden; width: 100px; height: 100px" >
  <input id="input" type="text" size=10 value="any text here!"/>
  <button style="position:relative; top: 100px; left: 100px"/>
</div>

If ones starts a text selection by dragging the mouse from within the input
field, and continues to drag beyong the outer div boundary, the latter will
be scrolled no matter its overflow:hidden style.
That happens because when the autoscroll has started, it gets propagated up
to the current layer's parent layer, instead of the to current layer's enclosing
scrollable layer.

Patch fixes the issue by hardening the way scrolling is
propagated upwards when autoscroll is being performed.

RenderLayer::enclosingScrollableLayer method also got rewritten
in terms of RenderLayer tree traversing, instead of RenderObject tree.
The rewrite adds support for cross frame upwards traversal.

Test: fast/events/autoscroll-upwards-propagation.html

* rendering/RenderLayer.cpp:
(WebCore::parentLayerCrossFrame):
(WebCore::RenderLayer::enclosingScrollableLayer):
(WebCore::RenderLayer::scrollRectToVisible):

LayoutTests:

* fast/events/autoscroll-upwards-propagation-expected.txt: Added.
* fast/events/autoscroll-upwards-propagation.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@154382 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 0450eb52
2013-08-19 Antonio Gomes <a1.gomes@sisa.samsung.com>
Text dragging can scroll overflow:hidden boxes
https://bugs.webkit.org/show_bug.cgi?id=119760
Reviewed by Darin Adler.
Patch by Antonio Gomes <a1.gomes@sisa.samsung.com>
* fast/events/autoscroll-upwards-propagation-expected.txt: Added.
* fast/events/autoscroll-upwards-propagation.html: Added.
2013-08-20 Gavin Barraclough <barraclough@apple.com>
 
https://bugs.webkit.org/show_bug.cgi?id=120086
<head>
<style type="text/css">
.overflow-hidden {
width: 100px;
height: 100px;
background: #000;
overflow: hidden;
}
input {
font-size: 10px;
height: 20px;
}
button {
position: relative;
left: 100px;
top: 100px;
}
</style>
<script>
function runTest() {
if (!window.testRunner)
return;
if (!window.eventSender)
return;
testRunner.dumpAsText();
testRunner.waitUntilDone();
setTimeout(startTest, 0);
}
function startTest()
{
var input = document.getElementById("input");
var x = input.offsetLeft + input.offsetWidth / 2;
var y = input.offsetTop + input.offsetHeight / 2;
eventSender.dragMode = false;
eventSender.mouseMoveTo(x, y);
eventSender.mouseDown();
// We do the dragging/selection in two steps here, because if we move
// the mouse beyond the input boundary right way, it won't start the autoscroll
// timer. See early return in AutoscrollController::startAutoscrollForSelection
// after calling RenderBox::findAutoscrollable.
eventSender.mouseMoveTo(x + 48, y);
eventSender.mouseMoveTo(x + 55, y);
setTimeout(finishTest, 100);
}
function finishTest()
{
eventSender.mouseUp();
var div = document.getElementById("div");
if (div.scrollTop == 0 && div.scrollLeft == 0)
document.getElementById("result").innerText = "Test succeeded!";
else
document.getElementById("result").innerText = "Test failed!";
testRunner.notifyDone();
}
</script>
<body onload="runTest()">
</head>
<div id="div" class="overflow-hidden">
<input id="input" type="text" value="any text here!"/>
<button/>
</div>
<p id="result">If the test has completed this sentence should be replaced by a success message.</p>
</body>
2013-08-19 Antonio Gomes <a1.gomes@sisa.samsung.com>
Text dragging can scroll overflow:hidden boxes
https://bugs.webkit.org/show_bug.cgi?id=119760
Reviewed by Darin Adler.
Consider the case of the following HTML:
<div style="overflow:hidden; width: 100px; height: 100px" >
<input id="input" type="text" size=10 value="any text here!"/>
<button style="position:relative; top: 100px; left: 100px"/>
</div>
If ones starts a text selection by dragging the mouse from within the input
field, and continues to drag beyong the outer div boundary, the latter will
be scrolled no matter its overflow:hidden style.
That happens because when the autoscroll has started, it gets propagated up
to the current layer's parent layer, instead of the to current layer's enclosing
scrollable layer.
Patch fixes the issue by hardening the way scrolling is
propagated upwards when autoscroll is being performed.
RenderLayer::enclosingScrollableLayer method also got rewritten
in terms of RenderLayer tree traversing, instead of RenderObject tree.
The rewrite adds support for cross frame upwards traversal.
Test: fast/events/autoscroll-upwards-propagation.html
* rendering/RenderLayer.cpp:
(WebCore::parentLayerCrossFrame):
(WebCore::RenderLayer::enclosingScrollableLayer):
(WebCore::RenderLayer::scrollRectToVisible):
2013-08-20 Jer Noble <jer.noble@apple.com>
 
<https://webkit.org/b/120101> [Mac] Suspended HTMLMediaElements can still hold power assertion after playback stops.
......@@ -1379,11 +1379,33 @@ RenderLayer* RenderLayer::enclosingPositionedAncestor() const
return curr;
}
static RenderLayer* parentLayerCrossFrame(const RenderLayer* layer)
{
ASSERT(layer);
if (layer->parent())
return layer->parent();
RenderObject* renderer = layer->renderer();
Document* document = renderer->document();
if (!document)
return 0;
HTMLFrameOwnerElement* ownerElement = document->ownerElement();
if (!ownerElement)
return 0;
RenderObject* ownerRenderer = ownerElement->renderer();
if (!ownerRenderer)
return 0;
return ownerRenderer->enclosingLayer();
}
RenderLayer* RenderLayer::enclosingScrollableLayer() const
{
for (RenderObject* nextRenderer = renderer()->parent(); nextRenderer; nextRenderer = nextRenderer->parent()) {
if (nextRenderer->isBox() && toRenderBox(nextRenderer)->canBeScrolledAndHasScrollableArea())
return nextRenderer->enclosingLayer();
for (RenderLayer* nextLayer = parentLayerCrossFrame(this); nextLayer; nextLayer = parentLayerCrossFrame(nextLayer)) {
if (nextLayer->renderer()->isBox() && toRenderBox(nextLayer->renderer())->canBeScrolledAndHasScrollableArea())
return nextLayer;
}
return 0;
......@@ -2366,6 +2388,9 @@ void RenderLayer::scrollRectToVisible(const LayoutRect& rect, const ScrollAlignm
}
}
if (renderer()->frame()->eventHandler().autoscrollInProgress())
parentLayer = enclosingScrollableLayer();
if (parentLayer)
parentLayer->scrollRectToVisible(newRect, alignX, alignY);
......
Supports Markdown
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