Ensure scrolling causes updateWidgetPositions even on nested frames.

Previously, updateWidgetPositionsIfNeeded() (ie, the deferred call
caused by scroll updates) was only called on the top-level frame,
causing incorrectly positioned widgets in cases of multiple nested
frames and scrollers.

BUG=430069

Review URL: https://codereview.chromium.org/719813002

git-svn-id: svn://svn.chromium.org/blink/trunk@185252 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 57df4e50
......@@ -183,6 +183,9 @@ crbug.com/377960 fast/css/font-load-while-styleresolver-missing.html [ Pass Ima
crbug.com/377970 [ Win Linux ] http/tests/misc/image-blocked-src-change.html [ Failure Pass ]
Bug(hartmanng) [ Win Mac Android ] compositing/overflow/update-widget-positions-on-nested-frames-and-scrollers.html [ NeedsRebaseline ]
Bug(hartmanng) [ Win Mac Android ] virtual/prefer_compositing_to_lcd_text/compositing/overflow/update-widget-positions-on-nested-frames-and-scrollers.html [ NeedsRebaseline ]
# Flaky on Linux ASAN and debug bots.
crbug.com/321607 [ Linux ] fast/forms/submit-to-blank-multiple-times.html [ Failure Pass ]
crbug.com/321607 [ Win Debug ] fast/forms/submit-to-blank-multiple-times.html [ Failure Pass ]
......
<!DOCTYPE html>
<html>
<head>
<style>
select {
display: block;
margin: 5px;
}
</style>
<script>
// We need to 'click' the select element by sending an actual event
// through internals, since the regular javascript click() method
// won't trigger the right events for this test.
function clickSelect() {
if (!window.eventSender)
return;
var select = document.getElementById('select');
// FIXME: it would be really nice to use getBoundingClientRect() and not
// hard-code pixel coordinates here, but since it's in an iframe, the
// coordinates are translated anyway.
eventSender.mouseMoveTo(50, 120);
eventSender.mouseDown();
eventSender.mouseUp();
}
// We'll get a message from the outer frame when it's done scrolling,
// so we know it's time to click on a select element.
window.onmessage = function() {
clickSelect();
if (window.testRunner)
window.setTimeout(function() { window.testRunner.notifyDone(); }, 0);
};
// This function just saves us from hard-coding 30 select elements
// (each with a few option elements) in the body. One of the
// select elements near the bottom is given an id so we can click
// on it later.
function populateDom() {
for (var x = 0; x < 30; x++) {
var select = document.createElement('select');
for (var y = 0; y < 4; ++y) {
var option = document.createElement('option');
option.innerText = y;
select.appendChild(option);
}
if (x == 24) {
select.id = 'select';
}
document.body.appendChild(select);
}
}
// Javascript execution starts here. This will populate the iframe
// with a bunch of select elements, then post a message to the
// outer iframe to tell it to scroll.
window.onload = function() {
populateDom();
parent.postMessage('', '*');
};
</script>
</head>
<body>
</body>
<!DOCTYPE html>
<html>
<head>
<style>
iframe {
height: 900px;
}
div {
height: 300px;
overflow: auto;
border: 1px solid black;
}
</style>
<script>
// We expect to get a message from the inner frame to tell us when
// the inner frame's DOM is all set up. We need to scroll down from
// this frame, and then, unfortunately, transfer control back to the
// inner frame so that it can click on one of the select elements.
window.onmessage = function() {
document.getElementById('scrollable').scrollTop = 500;
document.getElementById('frame').contentWindow.postMessage('', '*');
};
</script>
</head>
<body>
<div id='scrollable'>
<iframe id='frame' src='update-widget-positions-on-nested-frames-and-scrollers-inner-frame.html'></iframe>
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<style>
iframe {
top: 0;
left: 0;
height: 500px;
width: 500px;
border: 2px solid black;
}
</style>
<script>
if (window.testRunner)
testRunner.waitUntilDone();
if (window.internals)
window.internals.settings.setPreferCompositingToLCDTextEnabled(true);
</script>
</head>
<!--
This test scrolls a nested iframe down, then clicks on a select element. If
updateWidgetPositions() hasn't been called properly, this will cause the frame
to scroll to where it thinks the element being clicked on is. Javascript
execution will start in the onload handler in
resources/update-widget-positions-on-nested-frames-and-scrollers-inner-frame.html.
-->
<body>
<iframe src="resources/update-widget-positions-on-nested-frames-and-scrollers-outer-frame.html"></iframe>
</body>
</html>
layer at (0,0) size 800x600
RenderView at (0,0) size 800x600
layer at (0,0) size 800x525
RenderBlock {HTML} at (0,0) size 800x525
RenderBody {BODY} at (8,8) size 784x509
RenderText {#text} at (0,0) size 0x0
layer at (8,8) size 504x504
RenderPartObject {IFRAME} at (0,0) size 504x504 [border: (2px solid #000000)]
layer at (0,0) size 500x500
RenderView at (0,0) size 500x500
layer at (0,0) size 500x318
RenderBlock {HTML} at (0,0) size 500x318
RenderBody {BODY} at (8,8) size 484x302
layer at (8,8) size 484x302 clip at (9,9) size 467x300 scrollY 500.00 scrollHeight 909
RenderBlock {DIV} at (0,0) size 484x302 [border: (1px solid #000000)]
RenderText {#text} at (0,0) size 0x0
layer at (9,-491) size 304x904 backgroundClip at (9,9) size 467x300 clip at (9,9) size 467x300 outlineClip at (9,9) size 467x300
RenderPartObject {IFRAME} at (1,1) size 304x904 [border: (2px inset #EEEEEE)]
layer at (0,0) size 300x900
RenderView at (0,0) size 300x900
layer at (0,0) size 300x761
RenderBlock {HTML} at (0,0) size 300x761
RenderBody {BODY} at (8,8) size 284x745
RenderMenuList {SELECT} at (5,0) size 32x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
RenderBlock (anonymous) at (1,1) size 30x18
RenderText at (4,1) size 7x16
text run at (4,1) width 7: "0"
RenderMenuList {SELECT} at (5,25) size 32x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
RenderBlock (anonymous) at (1,1) size 30x18
RenderText at (4,1) size 7x16
text run at (4,1) width 7: "0"
RenderMenuList {SELECT} at (5,50) size 32x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
RenderBlock (anonymous) at (1,1) size 30x18
RenderText at (4,1) size 7x16
text run at (4,1) width 7: "0"
RenderMenuList {SELECT} at (5,75) size 32x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
RenderBlock (anonymous) at (1,1) size 30x18
RenderText at (4,1) size 7x16
text run at (4,1) width 7: "0"
RenderMenuList {SELECT} at (5,100) size 32x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
RenderBlock (anonymous) at (1,1) size 30x18
RenderText at (4,1) size 7x16
text run at (4,1) width 7: "0"
RenderMenuList {SELECT} at (5,125) size 32x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
RenderBlock (anonymous) at (1,1) size 30x18
RenderText at (4,1) size 7x16
text run at (4,1) width 7: "0"
RenderMenuList {SELECT} at (5,150) size 32x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
RenderBlock (anonymous) at (1,1) size 30x18
RenderText at (4,1) size 7x16
text run at (4,1) width 7: "0"
RenderMenuList {SELECT} at (5,175) size 32x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
RenderBlock (anonymous) at (1,1) size 30x18
RenderText at (4,1) size 7x16
text run at (4,1) width 7: "0"
RenderMenuList {SELECT} at (5,200) size 32x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
RenderBlock (anonymous) at (1,1) size 30x18
RenderText at (4,1) size 7x16
text run at (4,1) width 7: "0"
RenderMenuList {SELECT} at (5,225) size 32x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
RenderBlock (anonymous) at (1,1) size 30x18
RenderText at (4,1) size 7x16
text run at (4,1) width 7: "0"
RenderMenuList {SELECT} at (5,250) size 32x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
RenderBlock (anonymous) at (1,1) size 30x18
RenderText at (4,1) size 7x16
text run at (4,1) width 7: "0"
RenderMenuList {SELECT} at (5,275) size 32x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
RenderBlock (anonymous) at (1,1) size 30x18
RenderText at (4,1) size 7x16
text run at (4,1) width 7: "0"
RenderMenuList {SELECT} at (5,300) size 32x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
RenderBlock (anonymous) at (1,1) size 30x18
RenderText at (4,1) size 7x16
text run at (4,1) width 7: "0"
RenderMenuList {SELECT} at (5,325) size 32x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
RenderBlock (anonymous) at (1,1) size 30x18
RenderText at (4,1) size 7x16
text run at (4,1) width 7: "0"
RenderMenuList {SELECT} at (5,350) size 32x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
RenderBlock (anonymous) at (1,1) size 30x18
RenderText at (4,1) size 7x16
text run at (4,1) width 7: "0"
RenderMenuList {SELECT} at (5,375) size 32x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
RenderBlock (anonymous) at (1,1) size 30x18
RenderText at (4,1) size 7x16
text run at (4,1) width 7: "0"
RenderMenuList {SELECT} at (5,400) size 32x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
RenderBlock (anonymous) at (1,1) size 30x18
RenderText at (4,1) size 7x16
text run at (4,1) width 7: "0"
RenderMenuList {SELECT} at (5,425) size 32x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
RenderBlock (anonymous) at (1,1) size 30x18
RenderText at (4,1) size 7x16
text run at (4,1) width 7: "0"
RenderMenuList {SELECT} at (5,450) size 32x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
RenderBlock (anonymous) at (1,1) size 30x18
RenderText at (4,1) size 7x16
text run at (4,1) width 7: "0"
RenderMenuList {SELECT} at (5,475) size 32x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
RenderBlock (anonymous) at (1,1) size 30x18
RenderText at (4,1) size 7x16
text run at (4,1) width 7: "0"
RenderMenuList {SELECT} at (5,500) size 32x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
RenderBlock (anonymous) at (1,1) size 30x18
RenderText at (4,1) size 7x16
text run at (4,1) width 7: "0"
RenderMenuList {SELECT} at (5,525) size 32x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
RenderBlock (anonymous) at (1,1) size 30x18
RenderText at (4,1) size 7x16
text run at (4,1) width 7: "0"
RenderMenuList {SELECT} at (5,550) size 32x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
RenderBlock (anonymous) at (1,1) size 30x18
RenderText at (4,1) size 7x16
text run at (4,1) width 7: "0"
RenderMenuList {SELECT} at (5,575) size 32x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
RenderBlock (anonymous) at (1,1) size 30x18
RenderText at (4,1) size 7x16
text run at (4,1) width 7: "0"
RenderMenuList {SELECT} at (5,600) size 32x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
RenderBlock (anonymous) at (1,1) size 30x18
RenderText at (4,1) size 7x16
text run at (4,1) width 7: "0"
RenderMenuList {SELECT} at (5,625) size 32x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
RenderBlock (anonymous) at (1,1) size 30x18
RenderText at (4,1) size 7x16
text run at (4,1) width 7: "0"
RenderMenuList {SELECT} at (5,650) size 32x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
RenderBlock (anonymous) at (1,1) size 30x18
RenderText at (4,1) size 7x16
text run at (4,1) width 7: "0"
RenderMenuList {SELECT} at (5,675) size 32x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
RenderBlock (anonymous) at (1,1) size 30x18
RenderText at (4,1) size 7x16
text run at (4,1) width 7: "0"
RenderMenuList {SELECT} at (5,700) size 32x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
RenderBlock (anonymous) at (1,1) size 30x18
RenderText at (4,1) size 7x16
text run at (4,1) width 7: "0"
RenderMenuList {SELECT} at (5,725) size 32x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
RenderBlock (anonymous) at (1,1) size 30x18
RenderText at (4,1) size 7x16
text run at (4,1) width 7: "0"
......@@ -2538,8 +2538,6 @@ void FrameView::updateLayoutAndStyleForPainting()
updateLayoutAndStyleIfNeededRecursive();
updateWidgetPositionsIfNeeded();
RenderView* view = renderView();
if (view) {
TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateLayerTree", "frame", m_frame.get());
......@@ -2611,6 +2609,7 @@ void FrameView::updateLayoutAndStyleIfNeededRecursive()
m_frame->document()->renderView()->assertRendererLaidOut();
#endif
updateWidgetPositionsIfNeeded();
}
void FrameView::invalidateTreeIfNeededRecursive()
......
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