<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[195196] releases/WebKitGTK/webkit-2.10</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/195196">195196</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2016-01-18 03:36:45 -0800 (Mon, 18 Jan 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/194405">r194405</a> - REGRESSION (<a href="http://trac.webkit.org/projects/webkit/changeset/187593">r187593</a>): Scroll position jumps when selecting text in an iframe
https://bugs.webkit.org/show_bug.cgi?id=152541
rdar://problem/23886181

Reviewed by Tim Horton.

Source/WebCore:

<a href="http://trac.webkit.org/projects/webkit/changeset/154382">r154382</a> added code that modifies parentLayer traversal, looking for ancestor
scrollable layers. However, it confusingly added another code path in which
the ancestor layer traversal cross a frame boundary, when RenderLayer::scrollRectToVisible()
already has one. I fixed this new location to adjust the rect coordinates in <a href="http://trac.webkit.org/projects/webkit/changeset/187593">r187593</a>,
but then code that hit both crossing points double-mapped the coordinates, causing
autoscroll jumping.

Fix by reverting <a href="http://trac.webkit.org/projects/webkit/changeset/154382">r154382</a> and <a href="http://trac.webkit.org/projects/webkit/changeset/187593">r187593</a>, going back to doing the ancestor walk in
one place. Re-fix <a href="http://trac.webkit.org/projects/webkit/changeset/154382">r154382</a> by implementing RenderLayer::allowsCurrentScroll(),
which contains the logic for line clamp, autoscroll and ensuring that overflow:hidden
can be programmatically scrolled.

Form controls are special; they can have overflow:hidden but still be user-scrollable
during autoscroll; this is handled via the confusingly-named canBeProgramaticallyScrolled().
RenderTextControlSingleLine implements this to ensure that readonly text inputs
autoscroll (which is exercised by a test).

The frame-to-parent-frame rect mapping in RenderLayer::scrollRectToVisible() is
fixed to use the coordinate mapping functions from Widget/ScrollView, with the
addition of a new utility function contentsToContainingViewContents().

A &quot;Scrolling&quot; logging channel is added with a few log points.

Test: fast/events/autoscroll-in-iframe-body.html

* page/scrolling/ScrollingCoordinator.cpp:
(WebCore::ScrollingCoordinator::absoluteNonFastScrollableRegionForFrame):
use contentsToContainingViewContents().
* platform/Logging.h:
* platform/ScrollView.cpp:
(WebCore::ScrollView::contentsToContainingViewContents):
* platform/ScrollView.h:
* platform/graphics/IntPoint.cpp:
(WebCore::IntPoint::constrainedBetween): New helper to constrain a point between
two other points.
* platform/graphics/IntPoint.h:
(WebCore::IntPoint::expandedTo):
(WebCore::IntPoint::shrunkTo):
* rendering/RenderBox.cpp:
* rendering/RenderLayer.cpp:
(WebCore::parentLayerCrossFrame):
(WebCore::RenderLayer::enclosingScrollableLayer):
(WebCore::frameElementAndViewPermitScroll):
(WebCore::RenderLayer::allowsCurrentScroll):
(WebCore::RenderLayer::scrollRectToVisible):
* rendering/RenderLayer.h:
* rendering/RenderTextControlSingleLine.h:

LayoutTests:

New test for autoscrolling iframe contents (an existing test scrolled an overflow:scroll
inside an iframe, and didn't catch the bug).

* fast/events/autoscroll-in-iframe-body-expected.txt: Added.
* fast/events/autoscroll-in-iframe-body.html: Added.
* fast/forms/input-readonly-autoscroll.html: Fix a missing double quote.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit210LayoutTestsChangeLog">releases/WebKitGTK/webkit-2.10/LayoutTests/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit210LayoutTestsfastformsinputreadonlyautoscrollhtml">releases/WebKitGTK/webkit-2.10/LayoutTests/fast/forms/input-readonly-autoscroll.html</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceWebCoreChangeLog">releases/WebKitGTK/webkit-2.10/Source/WebCore/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceWebCorepagescrollingScrollingCoordinatorcpp">releases/WebKitGTK/webkit-2.10/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceWebCoreplatformLoggingh">releases/WebKitGTK/webkit-2.10/Source/WebCore/platform/Logging.h</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceWebCoreplatformScrollViewcpp">releases/WebKitGTK/webkit-2.10/Source/WebCore/platform/ScrollView.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceWebCoreplatformScrollViewh">releases/WebKitGTK/webkit-2.10/Source/WebCore/platform/ScrollView.h</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceWebCoreplatformgraphicsIntPointcpp">releases/WebKitGTK/webkit-2.10/Source/WebCore/platform/graphics/IntPoint.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceWebCoreplatformgraphicsIntPointh">releases/WebKitGTK/webkit-2.10/Source/WebCore/platform/graphics/IntPoint.h</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceWebCorerenderingRenderBoxcpp">releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/RenderBox.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceWebCorerenderingRenderLayercpp">releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/RenderLayer.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceWebCorerenderingRenderLayerh">releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/RenderLayer.h</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceWebCorerenderingRenderTextControlSingleLineh">releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/RenderTextControlSingleLine.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit210LayoutTestsfasteventsautoscrolliniframebodyexpectedtxt">releases/WebKitGTK/webkit-2.10/LayoutTests/fast/events/autoscroll-in-iframe-body-expected.txt</a></li>
<li><a href="#releasesWebKitGTKwebkit210LayoutTestsfasteventsautoscrolliniframebodyhtml">releases/WebKitGTK/webkit-2.10/LayoutTests/fast/events/autoscroll-in-iframe-body.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="releasesWebKitGTKwebkit210LayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/LayoutTests/ChangeLog (195195 => 195196)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/LayoutTests/ChangeLog        2016-01-18 11:36:08 UTC (rev 195195)
+++ releases/WebKitGTK/webkit-2.10/LayoutTests/ChangeLog        2016-01-18 11:36:45 UTC (rev 195196)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2015-12-23  Simon Fraser  &lt;simon.fraser@apple.com&gt;
+
+        REGRESSION (r187593): Scroll position jumps when selecting text in an iframe
+        https://bugs.webkit.org/show_bug.cgi?id=152541
+        rdar://problem/23886181
+
+        Reviewed by Tim Horton.
+        
+        New test for autoscrolling iframe contents (an existing test scrolled an overflow:scroll
+        inside an iframe, and didn't catch the bug).
+
+        * fast/events/autoscroll-in-iframe-body-expected.txt: Added.
+        * fast/events/autoscroll-in-iframe-body.html: Added.
+        * fast/forms/input-readonly-autoscroll.html: Fix a missing double quote.
+
</ins><span class="cx"> 2015-12-22  Simon Fraser  &lt;simon.fraser@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Minor cleanup in RenderBox::canBeProgramaticallyScrolled()
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210LayoutTestsfasteventsautoscrolliniframebodyexpectedtxt"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.10/LayoutTests/fast/events/autoscroll-in-iframe-body-expected.txt (0 => 195196)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/LayoutTests/fast/events/autoscroll-in-iframe-body-expected.txt                                (rev 0)
+++ releases/WebKitGTK/webkit-2.10/LayoutTests/fast/events/autoscroll-in-iframe-body-expected.txt        2016-01-18 11:36:45 UTC (rev 195196)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+
+PASSED: selecting in the iframe did not scroll the page.
+
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit210LayoutTestsfasteventsautoscrolliniframebodyhtml"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.10/LayoutTests/fast/events/autoscroll-in-iframe-body.html (0 => 195196)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/LayoutTests/fast/events/autoscroll-in-iframe-body.html                                (rev 0)
+++ releases/WebKitGTK/webkit-2.10/LayoutTests/fast/events/autoscroll-in-iframe-body.html        2016-01-18 11:36:45 UTC (rev 195196)
</span><span class="lines">@@ -0,0 +1,96 @@
</span><ins>+&lt;html&gt;
+    &lt;head&gt;
+        &lt;style&gt;
+            body {
+                height: 2000px;
+            }
+            iframe {
+                position: absolute;
+                top: 800px;
+            }
+        &lt;/style&gt;
+        &lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+        &lt;script&gt;
+
+        if (window.testRunner) {
+            testRunner.waitUntilDone();
+            testRunner.dumpAsText();
+        }
+
+        function log(msg)
+        {
+            document.getElementById('console').appendChild(document.createTextNode(msg + '\n'));
+        }
+        
+        var verticalScrollOffset;
+        var iframe;
+        var mainFrameScrollOffset = 400;
+        
+        function getDragStart()
+        {
+            iframe = document.getElementById('targetFrame');
+            // Start dragging near the bottom of the iframe.
+            return {
+                'x' : iframe.clientLeft + iframe.clientWidth / 2,
+                'y' : iframe.clientTop + iframe.clientHeight - 10
+            };
+        }
+
+        function doTest()
+        {
+            document.scrollingElement.scrollTop = mainFrameScrollOffset;
+            if (document.scrollingElement.scrollTop != mainFrameScrollOffset)
+                log(&quot;FAILED: failed to scroll by &quot; + mainFrameScrollOffset + &quot;px&quot;);
+
+            iframe = document.getElementById('targetFrame');
+            // Start dragging near the bottom of the iframe.
+            var startPoint = getDragStart();
+            if (window.eventSender) {
+                eventSender.dragMode = false;
+                eventSender.mouseMoveTo(startPoint.x, startPoint.y);
+                eventSender.mouseDown();
+                eventSender.mouseUp();
+            }
+            setTimeout(autoscrollTestPart1, 0);
+        }
+
+        function autoscrollTestPart1()
+        {
+            var mainDocumentTop = document.scrollingElement.scrollTop;
+            if (mainDocumentTop != mainFrameScrollOffset)
+                log(&quot;FAILED: Clicking in the iframe scrolled the page (window.scrollTop is &quot; + mainDocumentTop + &quot;)&quot;);
+
+            if (window.eventSender) {
+                var startPoint = getDragStart();
+                eventSender.dragMode = false;
+                eventSender.mouseMoveTo(startPoint.x, startPoint.y);
+                eventSender.mouseDown();
+                eventSender.mouseMoveTo(startPoint.x + 10, startPoint.y);
+            }
+            setTimeout(autoscrollTestPart2, 100);
+        }
+
+        function autoscrollTestPart2()
+        {
+            if (window.eventSender)
+                eventSender.mouseUp();
+
+            var mainDocumentTop = document.scrollingElement.scrollTop;
+            if (mainDocumentTop == mainFrameScrollOffset)
+                log(&quot;PASSED: selecting in the iframe did not scroll the page.&quot;);
+            else
+                log(&quot;FAILED: the page autoscrolled (window.scrollTop is &quot; + mainDocumentTop + &quot;).&quot;);
+
+            if (window.testRunner)
+                testRunner.notifyDone();
+        }
+        
+        window.addEventListener('load', doTest, false);
+        &lt;/script&gt;
+    &lt;/head&gt;
+&lt;body&gt;
+    &lt;iframe id=&quot;targetFrame&quot; src=&quot;data:text/html,Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, c
 onsectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.&quot;&gt;&lt;/iframe&gt;
+    &lt;div id=&quot;console&quot;&gt;&lt;/div&gt;
+&lt;/body&gt;
+&lt;/html&gt;
+
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit210LayoutTestsfastformsinputreadonlyautoscrollhtml"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/LayoutTests/fast/forms/input-readonly-autoscroll.html (195195 => 195196)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/LayoutTests/fast/forms/input-readonly-autoscroll.html        2016-01-18 11:36:08 UTC (rev 195195)
+++ releases/WebKitGTK/webkit-2.10/LayoutTests/fast/forms/input-readonly-autoscroll.html        2016-01-18 11:36:45 UTC (rev 195196)
</span><span class="lines">@@ -38,7 +38,7 @@
</span><span class="cx">         &lt;/script&gt;
</span><span class="cx">     &lt;/head&gt;
</span><span class="cx">     &lt;body onload=&quot;test()&quot;&gt;
</span><del>-        &lt;p&gt;Test for &lt;a href=http://bugs.webkit.org/show_bug.cgi?id=11534&quot;&gt;bug 11534&lt;/a&gt;.&lt;/p&gt;
</del><ins>+        &lt;p&gt;Test for &lt;a href=&quot;http://bugs.webkit.org/show_bug.cgi?id=11534&quot;&gt;bug 11534&lt;/a&gt;.&lt;/p&gt;
</ins><span class="cx">         &lt;p&gt;Readonly text fields don't scroll when selecting content.&lt;/p&gt;
</span><span class="cx">         &lt;input id=&quot;tf&quot; readonly value=&quot;abcdefghijklmnopqrstuvwxyz&quot;&gt;&lt;/input&gt;
</span><span class="cx">         &lt;div id=&quot;res&quot;&gt;&lt;/div&gt;
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/ChangeLog (195195 => 195196)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/WebCore/ChangeLog        2016-01-18 11:36:08 UTC (rev 195195)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/ChangeLog        2016-01-18 11:36:45 UTC (rev 195196)
</span><span class="lines">@@ -1,3 +1,59 @@
</span><ins>+2015-12-23  Simon Fraser  &lt;simon.fraser@apple.com&gt;
+
+        REGRESSION (r187593): Scroll position jumps when selecting text in an iframe
+        https://bugs.webkit.org/show_bug.cgi?id=152541
+        rdar://problem/23886181
+
+        Reviewed by Tim Horton.
+        
+        r154382 added code that modifies parentLayer traversal, looking for ancestor
+        scrollable layers. However, it confusingly added another code path in which
+        the ancestor layer traversal cross a frame boundary, when RenderLayer::scrollRectToVisible()
+        already has one. I fixed this new location to adjust the rect coordinates in r187593,
+        but then code that hit both crossing points double-mapped the coordinates, causing
+        autoscroll jumping.
+        
+        Fix by reverting r154382 and r187593, going back to doing the ancestor walk in
+        one place. Re-fix r154382 by implementing RenderLayer::allowsCurrentScroll(),
+        which contains the logic for line clamp, autoscroll and ensuring that overflow:hidden
+        can be programmatically scrolled.
+        
+        Form controls are special; they can have overflow:hidden but still be user-scrollable
+        during autoscroll; this is handled via the confusingly-named canBeProgramaticallyScrolled().
+        RenderTextControlSingleLine implements this to ensure that readonly text inputs
+        autoscroll (which is exercised by a test).
+        
+        The frame-to-parent-frame rect mapping in RenderLayer::scrollRectToVisible() is
+        fixed to use the coordinate mapping functions from Widget/ScrollView, with the
+        addition of a new utility function contentsToContainingViewContents().
+        
+        A &quot;Scrolling&quot; logging channel is added with a few log points.
+
+        Test: fast/events/autoscroll-in-iframe-body.html
+
+        * page/scrolling/ScrollingCoordinator.cpp:
+        (WebCore::ScrollingCoordinator::absoluteNonFastScrollableRegionForFrame):
+        use contentsToContainingViewContents().
+        * platform/Logging.h:
+        * platform/ScrollView.cpp:
+        (WebCore::ScrollView::contentsToContainingViewContents):
+        * platform/ScrollView.h:
+        * platform/graphics/IntPoint.cpp:
+        (WebCore::IntPoint::constrainedBetween): New helper to constrain a point between
+        two other points.
+        * platform/graphics/IntPoint.h:
+        (WebCore::IntPoint::expandedTo):
+        (WebCore::IntPoint::shrunkTo):
+        * rendering/RenderBox.cpp:
+        * rendering/RenderLayer.cpp:
+        (WebCore::parentLayerCrossFrame):
+        (WebCore::RenderLayer::enclosingScrollableLayer):
+        (WebCore::frameElementAndViewPermitScroll):
+        (WebCore::RenderLayer::allowsCurrentScroll):
+        (WebCore::RenderLayer::scrollRectToVisible):
+        * rendering/RenderLayer.h:
+        * rendering/RenderTextControlSingleLine.h:
+
</ins><span class="cx"> 2015-12-22  Simon Fraser  &lt;simon.fraser@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Minor cleanup in RenderBox::canBeProgramaticallyScrolled()
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceWebCorepagescrollingScrollingCoordinatorcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp (195195 => 195196)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp        2016-01-18 11:36:08 UTC (rev 195195)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp        2016-01-18 11:36:45 UTC (rev 195196)
</span><span class="lines">@@ -155,9 +155,7 @@
</span><span class="cx"> 
</span><span class="cx">         Region subframeRegion = absoluteNonFastScrollableRegionForFrame(*subframe);
</span><span class="cx">         // Map from the frame document to our document.
</span><del>-        IntPoint offset = subframeView-&gt;contentsToView(IntPoint());
-        offset = subframeView-&gt;convertToContainingView(offset);
-        offset = frameView-&gt;viewToContents(offset);
</del><ins>+        IntPoint offset = subframeView-&gt;contentsToContainingViewContents(IntPoint());
</ins><span class="cx"> 
</span><span class="cx">         // FIXME: this translation ignores non-trival transforms on the frame.
</span><span class="cx">         subframeRegion.translate(toIntSize(offset));
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceWebCoreplatformLoggingh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/platform/Logging.h (195195 => 195196)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/WebCore/platform/Logging.h        2016-01-18 11:36:08 UTC (rev 195195)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/platform/Logging.h        2016-01-18 11:36:45 UTC (rev 195196)
</span><span class="lines">@@ -70,6 +70,7 @@
</span><span class="cx">     M(SQLDatabase) \
</span><span class="cx">     M(SVG) \
</span><span class="cx">     M(Services) \
</span><ins>+    M(Scrolling) \
</ins><span class="cx">     M(SpellingAndGrammar) \
</span><span class="cx">     M(StorageAPI) \
</span><span class="cx">     M(Threading) \
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceWebCoreplatformScrollViewcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/platform/ScrollView.cpp (195195 => 195196)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/WebCore/platform/ScrollView.cpp        2016-01-18 11:36:08 UTC (rev 195195)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/platform/ScrollView.cpp        2016-01-18 11:36:45 UTC (rev 195196)
</span><span class="lines">@@ -29,11 +29,13 @@
</span><span class="cx"> #include &quot;GraphicsContext.h&quot;
</span><span class="cx"> #include &quot;GraphicsLayer.h&quot;
</span><span class="cx"> #include &quot;HostWindow.h&quot;
</span><ins>+#include &quot;Logging.h&quot;
</ins><span class="cx"> #include &quot;PlatformMouseEvent.h&quot;
</span><span class="cx"> #include &quot;PlatformWheelEvent.h&quot;
</span><span class="cx"> #include &quot;ScrollAnimator.h&quot;
</span><span class="cx"> #include &quot;Scrollbar.h&quot;
</span><span class="cx"> #include &quot;ScrollbarTheme.h&quot;
</span><ins>+#include &quot;TextStream.h&quot;
</ins><span class="cx"> #include &lt;wtf/StdLibExtras.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -877,6 +879,26 @@
</span><span class="cx">     return rect;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+IntPoint ScrollView::contentsToContainingViewContents(const IntPoint&amp; point) const
+{
+    if (const ScrollView* parentScrollView = parent()) {
+        IntPoint pointInContainingView = convertToContainingView(contentsToView(point));
+        return parentScrollView-&gt;viewToContents(pointInContainingView);
+    }
+
+    return contentsToView(point);
+}
+
+IntRect ScrollView::contentsToContainingViewContents(IntRect rect) const
+{
+    if (const ScrollView* parentScrollView = parent()) {
+        IntRect rectInContainingView = convertToContainingView(contentsToView(rect));
+        return parentScrollView-&gt;viewToContents(rectInContainingView);
+    }
+
+    return contentsToView(rect);
+}
+
</ins><span class="cx"> IntPoint ScrollView::rootViewToContents(const IntPoint&amp; rootViewPoint) const
</span><span class="cx"> {
</span><span class="cx">     if (delegatesScrolling())
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceWebCoreplatformScrollViewh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/platform/ScrollView.h (195195 => 195196)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/WebCore/platform/ScrollView.h        2016-01-18 11:36:08 UTC (rev 195195)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/platform/ScrollView.h        2016-01-18 11:36:45 UTC (rev 195196)
</span><span class="lines">@@ -294,6 +294,9 @@
</span><span class="cx">     IntRect viewToContents(IntRect) const;
</span><span class="cx">     IntRect contentsToView(IntRect) const;
</span><span class="cx"> 
</span><ins>+    IntPoint contentsToContainingViewContents(const IntPoint&amp;) const;
+    IntRect contentsToContainingViewContents(IntRect) const;
+
</ins><span class="cx">     WEBCORE_EXPORT IntPoint rootViewToTotalContents(const IntPoint&amp;) const;
</span><span class="cx"> 
</span><span class="cx">     // Event coordinates are assumed to be in the coordinate space of a window that contains
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceWebCoreplatformgraphicsIntPointcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/platform/graphics/IntPoint.cpp (195195 => 195196)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/WebCore/platform/graphics/IntPoint.cpp        2016-01-18 11:36:08 UTC (rev 195195)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/platform/graphics/IntPoint.cpp        2016-01-18 11:36:45 UTC (rev 195196)
</span><span class="lines">@@ -42,4 +42,12 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+IntPoint IntPoint::constrainedBetween(const IntPoint&amp; min, const IntPoint&amp; max) const
+{
+    return {
+        std::max(min.x(), std::min(max.x(), m_x)),
+        std::max(min.y(), std::min(max.y(), m_y))
+    };
</ins><span class="cx"> }
</span><ins>+
+}
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceWebCoreplatformgraphicsIntPointh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/platform/graphics/IntPoint.h (195195 => 195196)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/WebCore/platform/graphics/IntPoint.h        2016-01-18 11:36:08 UTC (rev 195195)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/platform/graphics/IntPoint.h        2016-01-18 11:36:45 UTC (rev 195196)
</span><span class="lines">@@ -83,16 +83,22 @@
</span><span class="cx">     
</span><span class="cx">     IntPoint expandedTo(const IntPoint&amp; other) const
</span><span class="cx">     {
</span><del>-        return IntPoint(m_x &gt; other.m_x ? m_x : other.m_x,
-            m_y &gt; other.m_y ? m_y : other.m_y);
</del><ins>+        return {
+            m_x &gt; other.m_x ? m_x : other.m_x,
+            m_y &gt; other.m_y ? m_y : other.m_y
+        };
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     IntPoint shrunkTo(const IntPoint&amp; other) const
</span><span class="cx">     {
</span><del>-        return IntPoint(m_x &lt; other.m_x ? m_x : other.m_x,
-            m_y &lt; other.m_y ? m_y : other.m_y);
</del><ins>+        return {
+            m_x &lt; other.m_x ? m_x : other.m_x,
+            m_y &lt; other.m_y ? m_y : other.m_y
+        };
</ins><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    IntPoint constrainedBetween(const IntPoint&amp; min, const IntPoint&amp; max) const;
+
</ins><span class="cx">     int distanceSquaredToPoint(const IntPoint&amp;) const;
</span><span class="cx"> 
</span><span class="cx">     void clampNegativeToZero()
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceWebCorerenderingRenderBoxcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/RenderBox.cpp (195195 => 195196)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/RenderBox.cpp        2016-01-18 11:36:08 UTC (rev 195195)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/RenderBox.cpp        2016-01-18 11:36:45 UTC (rev 195196)
</span><span class="lines">@@ -915,6 +915,7 @@
</span><span class="cx">     return canBeScrolledAndHasScrollableArea();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+// FIXME: This is badly named. overflow:hidden can be programmatically scrolled, yet this returns false in that case.
</ins><span class="cx"> bool RenderBox::canBeProgramaticallyScrolled() const
</span><span class="cx"> {
</span><span class="cx">     if (isRenderView())
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceWebCorerenderingRenderLayercpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/RenderLayer.cpp (195195 => 195196)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/RenderLayer.cpp        2016-01-18 11:36:08 UTC (rev 195195)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/RenderLayer.cpp        2016-01-18 11:36:45 UTC (rev 195196)
</span><span class="lines">@@ -1449,7 +1449,7 @@
</span><span class="cx">     return curr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static RenderLayer* parentLayerCrossFrame(const RenderLayer&amp; layer, LayoutRect* rect = nullptr)
</del><ins>+static RenderLayer* parentLayerCrossFrame(const RenderLayer&amp; layer)
</ins><span class="cx"> {
</span><span class="cx">     if (layer.parent())
</span><span class="cx">         return layer.parent();
</span><span class="lines">@@ -1462,18 +1462,12 @@
</span><span class="cx">     if (!ownerRenderer)
</span><span class="cx">         return nullptr;
</span><span class="cx"> 
</span><del>-    // Convert the rect into the coordinate space of the parent frame's document.
-    if (rect) {
-        IntRect viewRect = layer.renderer().frame().view()-&gt;convertToContainingView(enclosingIntRect(*rect));
-        *rect = ownerRenderer-&gt;frame().view()-&gt;viewToContents(viewRect);
-    }
-
</del><span class="cx">     return ownerRenderer-&gt;enclosingLayer();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RenderLayer* RenderLayer::enclosingScrollableLayer(LayoutRect* rect) const
</del><ins>+RenderLayer* RenderLayer::enclosingScrollableLayer() const
</ins><span class="cx"> {
</span><del>-    for (RenderLayer* nextLayer = parentLayerCrossFrame(*this, rect); nextLayer; nextLayer = parentLayerCrossFrame(*nextLayer, rect)) {
</del><ins>+    for (RenderLayer* nextLayer = parentLayerCrossFrame(*this); nextLayer; nextLayer = parentLayerCrossFrame(*nextLayer)) {
</ins><span class="cx">         if (is&lt;RenderBox&gt;(nextLayer-&gt;renderer()) &amp;&amp; downcast&lt;RenderBox&gt;(nextLayer-&gt;renderer()).canBeScrolledAndHasScrollableArea())
</span><span class="cx">             return nextLayer;
</span><span class="cx">     }
</span><span class="lines">@@ -2278,6 +2272,7 @@
</span><span class="cx">     scrollByRecursively(adjustedScrollDelta(delta), ScrollOffsetClamped);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+// FIXME: unify with the scrollRectToVisible() code below.
</ins><span class="cx"> void RenderLayer::scrollByRecursively(const IntSize&amp; delta, ScrollOffsetClamping clamp, ScrollableArea** scrolledArea)
</span><span class="cx"> {
</span><span class="cx">     if (delta.isZero())
</span><span class="lines">@@ -2434,21 +2429,44 @@
</span><span class="cx">     view.frameView().viewportContentsChanged();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static inline bool frameElementAndViewPermitScroll(HTMLFrameElementBase* frameElementBase, FrameView* frameView) 
</del><ins>+static inline bool frameElementAndViewPermitScroll(HTMLFrameElementBase* frameElementBase, FrameView&amp; frameView)
</ins><span class="cx"> {
</span><span class="cx">     // If scrollbars aren't explicitly forbidden, permit scrolling.
</span><span class="cx">     if (frameElementBase &amp;&amp; frameElementBase-&gt;scrollingMode() != ScrollbarAlwaysOff)
</span><span class="cx">         return true;
</span><span class="cx"> 
</span><span class="cx">     // If scrollbars are forbidden, user initiated scrolls should obviously be ignored.
</span><del>-    if (frameView-&gt;wasScrolledByUser())
</del><ins>+    if (frameView.wasScrolledByUser())
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     // Forbid autoscrolls when scrollbars are off, but permits other programmatic scrolls,
</span><span class="cx">     // like navigation to an anchor.
</span><del>-    return !frameView-&gt;frame().eventHandler().autoscrollInProgress();
</del><ins>+    return !frameView.frame().eventHandler().autoscrollInProgress();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool RenderLayer::allowsCurrentScroll() const
+{
+    if (!renderer().hasOverflowClip())
+        return false;
+
+    // Don't scroll to reveal an overflow layer that is restricted by the -webkit-line-clamp property.
+    // FIXME: Is this still needed? It used to be relevant for Safari RSS.
+    if (renderer().parent() &amp;&amp; !renderer().parent()-&gt;style().lineClamp().isNone())
+        return false;
+
+    RenderBox* box = renderBox();
+    ASSERT(box); // Only boxes can have overflowClip set.
+
+    if (renderer().frame().eventHandler().autoscrollInProgress()) {
+        // The &quot;programmatically&quot; here is misleading; this asks whether the box has scrollable overflow,
+        // or is a special case like a form control.
+        return box-&gt;canBeProgramaticallyScrolled();
+    }
+
+    // Programmatic scrolls can scroll overflow:hidden.
+    return box-&gt;hasHorizontalOverflow() || box-&gt;hasVerticalOverflow();
+}
+
</ins><span class="cx"> void RenderLayer::scrollRectToVisible(const LayoutRect&amp; rect, const ScrollAlignment&amp; alignX, const ScrollAlignment&amp; alignY)
</span><span class="cx"> {
</span><span class="cx">     RenderLayer* parentLayer = nullptr;
</span><span class="lines">@@ -2458,13 +2476,10 @@
</span><span class="cx">     // the end of the function since they could delete the layer or the layer's renderer().
</span><span class="cx">     FrameView&amp; frameView = renderer().view().frameView();
</span><span class="cx"> 
</span><del>-    bool restrictedByLineClamp = false;
-    if (renderer().parent()) {
</del><ins>+    if (renderer().parent())
</ins><span class="cx">         parentLayer = renderer().parent()-&gt;enclosingLayer();
</span><del>-        restrictedByLineClamp = !renderer().parent()-&gt;style().lineClamp().isNone();
-    }
</del><span class="cx"> 
</span><del>-    if (renderer().hasOverflowClip() &amp;&amp; !restrictedByLineClamp) {
</del><ins>+    if (allowsCurrentScroll()) {
</ins><span class="cx">         // Don't scroll to reveal an overflow layer that is restricted by the -webkit-line-clamp property.
</span><span class="cx">         // This will prevent us from revealing text hidden by the slider in Safari RSS.
</span><span class="cx">         RenderBox* box = renderBox();
</span><span class="lines">@@ -2481,7 +2496,7 @@
</span><span class="cx">             localExposeRect.move(-scrollOffsetDifference);
</span><span class="cx">             newRect = LayoutRect(box-&gt;localToAbsoluteQuad(FloatQuad(FloatRect(localExposeRect)), UseTransforms).boundingBox());
</span><span class="cx">         }
</span><del>-    } else if (!parentLayer &amp;&amp; renderer().isBox() &amp;&amp; renderBox()-&gt;canBeProgramaticallyScrolled()) {
</del><ins>+    } else if (!parentLayer &amp;&amp; renderer().isRenderView()) {
</ins><span class="cx">         HTMLFrameOwnerElement* ownerElement = renderer().document().ownerElement();
</span><span class="cx"> 
</span><span class="cx">         if (ownerElement &amp;&amp; ownerElement-&gt;renderer()) {
</span><span class="lines">@@ -2490,23 +2505,19 @@
</span><span class="cx">             if (is&lt;HTMLFrameElementBase&gt;(*ownerElement))
</span><span class="cx">                 frameElementBase = downcast&lt;HTMLFrameElementBase&gt;(ownerElement);
</span><span class="cx"> 
</span><del>-            if (frameElementAndViewPermitScroll(frameElementBase, &amp;frameView)) {
</del><ins>+            if (frameElementAndViewPermitScroll(frameElementBase, frameView)) {
</ins><span class="cx">                 LayoutRect viewRect = frameView.visibleContentRect(LegacyIOSDocumentVisibleRect);
</span><span class="cx">                 LayoutRect exposeRect = getRectToExpose(viewRect, viewRect, rect, alignX, alignY);
</span><span class="cx"> 
</span><del>-                int xOffset = roundToInt(exposeRect.x());
-                int yOffset = roundToInt(exposeRect.y());
</del><ins>+                IntPoint scrollOffset(roundedIntPoint(exposeRect.location()));
</ins><span class="cx">                 // Adjust offsets if they're outside of the allowable range.
</span><del>-                xOffset = std::max(0, std::min(frameView.contentsWidth(), xOffset));
-                yOffset = std::max(0, std::min(frameView.contentsHeight(), yOffset));
</del><ins>+                scrollOffset = scrollOffset.constrainedBetween(IntPoint(), IntPoint(frameView.contentsSize()));
+                frameView.setScrollPosition(scrollOffset);
</ins><span class="cx"> 
</span><del>-                frameView.setScrollPosition(IntPoint(xOffset, yOffset));
</del><span class="cx">                 if (frameView.safeToPropagateScrollToParent()) {
</span><span class="cx">                     parentLayer = ownerElement-&gt;renderer()-&gt;enclosingLayer();
</span><del>-                    // FIXME: This doesn't correctly convert the rect to
-                    // absolute coordinates in the parent.
-                    newRect.setX(rect.x() - frameView.scrollX() + frameView.x());
-                    newRect.setY(rect.y() - frameView.scrollY() + frameView.y());
</del><ins>+                    // Convert the rect into the coordinate space of the parent frame's document.
+                    newRect = frameView.contentsToContainingViewContents(enclosingIntRect(newRect));
</ins><span class="cx">                 } else
</span><span class="cx">                     parentLayer = nullptr;
</span><span class="cx">             }
</span><span class="lines">@@ -2535,9 +2546,6 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    if (renderer().frame().eventHandler().autoscrollInProgress())
-        parentLayer = enclosingScrollableLayer(&amp;newRect);
-
</del><span class="cx">     if (parentLayer)
</span><span class="cx">         parentLayer-&gt;scrollRectToVisible(newRect, alignX, alignY);
</span><span class="cx"> }
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceWebCorerenderingRenderLayerh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/RenderLayer.h (195195 => 195196)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/RenderLayer.h        2016-01-18 11:36:08 UTC (rev 195195)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/RenderLayer.h        2016-01-18 11:36:45 UTC (rev 195196)
</span><span class="lines">@@ -404,7 +404,7 @@
</span><span class="cx">     RenderLayer* enclosingAncestorForPosition(EPosition) const;
</span><span class="cx"> 
</span><span class="cx">     // Returns the nearest enclosing layer that is scrollable.
</span><del>-    RenderLayer* enclosingScrollableLayer(LayoutRect* = nullptr) const;
</del><ins>+    RenderLayer* enclosingScrollableLayer() const;
</ins><span class="cx"> 
</span><span class="cx">     // The layer relative to which clipping rects for this layer are computed.
</span><span class="cx">     RenderLayer* clippingRootForPainting() const;
</span><span class="lines">@@ -897,6 +897,8 @@
</span><span class="cx">     IntSize scrollbarOffset(const Scrollbar*) const;
</span><span class="cx">     
</span><span class="cx">     void updateScrollableAreaSet(bool hasOverflow);
</span><ins>+    
+    bool allowsCurrentScroll() const;
</ins><span class="cx"> 
</span><span class="cx">     void dirtyAncestorChainVisibleDescendantStatus();
</span><span class="cx">     void setAncestorChainHasVisibleDescendant();
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceWebCorerenderingRenderTextControlSingleLineh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/RenderTextControlSingleLine.h (195195 => 195196)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/RenderTextControlSingleLine.h        2016-01-18 11:36:08 UTC (rev 195195)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/RenderTextControlSingleLine.h        2016-01-18 11:36:45 UTC (rev 195196)
</span><span class="lines">@@ -105,6 +105,7 @@
</span><span class="cx"> private:
</span><span class="cx">     virtual bool hasLineIfEmpty() const override { return true; }
</span><span class="cx">     virtual bool isTextControlInnerBlock() const override { return true; }
</span><ins>+    virtual bool canBeProgramaticallyScrolled() const override { return true; }
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre>
</div>
</div>

</body>
</html>