<!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>[186336] releases/WebKitGTK/webkit-2.8</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/186336">186336</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2015-07-06 03:05:01 -0700 (Mon, 06 Jul 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/184885">r184885</a> - Overhanging float sets are not cleaned up properly when floating renderer is destroyed.
https://bugs.webkit.org/show_bug.cgi?id=145323
rdar://problem/20980628

Reviewed by Dave Hyatt.

This patch ensures when an overhanging float renderer is destroyed,
all the sibling containers' floating object set(m_floatingObjects) gets properly cleaned up.

When an overhanging float is present, we cache the renderer on the parent and on the affected
sibling containers too. (RenderBlockFlow::m_floatingObjects) These caches(sets) get cleared and repopulated
during ::layout(). In order to have a float renderer removed from a set, a layout needs to be initiated on the container.
This is normally done through RenderBlockFlow::markSiblingsWithFloatsForLayout() and RenderBlockFlow::markAllDescendantsWithFloatsForLayout().
However, when the float container's parent's writing direction changes (and we promote the children containers to new formatting contexts),
the layout propagation through siblings does not work anymore.

The avoidsFloats() check in RenderBlockFlow::markSiblingsWithFloatsForLayout() has very little performance gain, but it prevents us
from propagating layout to siblings when certain properties of the parent container changes.

Source/WebCore:

Test: fast/block/float/crash-when-floating-object-is-removed.xhtml

* rendering/RenderBlockFlow.cpp:
(WebCore::RenderBlockFlow::markSiblingsWithFloatsForLayout):
* rendering/RenderBox.cpp:
(WebCore::outermostBlockContainingFloatingObject):
(WebCore::RenderBox::removeFloatingOrPositionedChildFromBlockLists):
(WebCore::RenderBox::outermostBlockContainingFloatingObject): Deleted.
* rendering/RenderBox.h:

LayoutTests:

* fast/block/float/crash-when-floating-object-is-removed-expected.txt: Added.
* fast/block/float/crash-when-floating-object-is-removed.xhtml: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit28LayoutTestsChangeLog">releases/WebKitGTK/webkit-2.8/LayoutTests/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit28SourceWebCoreChangeLog">releases/WebKitGTK/webkit-2.8/Source/WebCore/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit28SourceWebCorerenderingRenderBlockFlowcpp">releases/WebKitGTK/webkit-2.8/Source/WebCore/rendering/RenderBlockFlow.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit28SourceWebCorerenderingRenderBoxcpp">releases/WebKitGTK/webkit-2.8/Source/WebCore/rendering/RenderBox.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit28SourceWebCorerenderingRenderBoxh">releases/WebKitGTK/webkit-2.8/Source/WebCore/rendering/RenderBox.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit28LayoutTestsfastblockfloatcrashwhenfloatingobjectisremovedexpectedtxt">releases/WebKitGTK/webkit-2.8/LayoutTests/fast/block/float/crash-when-floating-object-is-removed-expected.txt</a></li>
<li><a href="#releasesWebKitGTKwebkit28LayoutTestsfastblockfloatcrashwhenfloatingobjectisremovedxhtml">releases/WebKitGTK/webkit-2.8/LayoutTests/fast/block/float/crash-when-floating-object-is-removed.xhtml</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="releasesWebKitGTKwebkit28LayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.8/LayoutTests/ChangeLog (186335 => 186336)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.8/LayoutTests/ChangeLog        2015-07-06 09:56:44 UTC (rev 186335)
+++ releases/WebKitGTK/webkit-2.8/LayoutTests/ChangeLog        2015-07-06 10:05:01 UTC (rev 186336)
</span><span class="lines">@@ -1,3 +1,27 @@
</span><ins>+2015-05-26  Zalan Bujtas  &lt;zalan@apple.com&gt;
+
+        Overhanging float sets are not cleaned up properly when floating renderer is destroyed.
+        https://bugs.webkit.org/show_bug.cgi?id=145323
+        rdar://problem/20980628
+
+        Reviewed by Dave Hyatt.
+
+        This patch ensures when an overhanging float renderer is destroyed,
+        all the sibling containers' floating object set(m_floatingObjects) gets properly cleaned up.
+
+        When an overhanging float is present, we cache the renderer on the parent and on the affected
+        sibling containers too. (RenderBlockFlow::m_floatingObjects) These caches(sets) get cleared and repopulated
+        during ::layout(). In order to have a float renderer removed from a set, a layout needs to be initiated on the container.
+        This is normally done through RenderBlockFlow::markSiblingsWithFloatsForLayout() and RenderBlockFlow::markAllDescendantsWithFloatsForLayout().
+        However, when the float container's parent's writing direction changes (and we promote the children containers to new formatting contexts),
+        the layout propagation through siblings does not work anymore.
+
+        The avoidsFloats() check in RenderBlockFlow::markSiblingsWithFloatsForLayout() has very little performance gain, but it prevents us
+        from propagating layout to siblings when certain properties of the parent container changes.
+
+        * fast/block/float/crash-when-floating-object-is-removed-expected.txt: Added.
+        * fast/block/float/crash-when-floating-object-is-removed.xhtml: Added.
+
</ins><span class="cx"> 2015-05-26  Said Abou-Hallawa  &lt;sabouhallawa@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         SVG fragment identifier rendering issue
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit28LayoutTestsfastblockfloatcrashwhenfloatingobjectisremovedexpectedtxt"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.8/LayoutTests/fast/block/float/crash-when-floating-object-is-removed-expected.txt (0 => 186336)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.8/LayoutTests/fast/block/float/crash-when-floating-object-is-removed-expected.txt                                (rev 0)
+++ releases/WebKitGTK/webkit-2.8/LayoutTests/fast/block/float/crash-when-floating-object-is-removed-expected.txt        2015-07-06 10:05:01 UTC (rev 186336)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+ PASS if no crash or ASSERT in debug.
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit28LayoutTestsfastblockfloatcrashwhenfloatingobjectisremovedxhtml"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.8/LayoutTests/fast/block/float/crash-when-floating-object-is-removed.xhtml (0 => 186336)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.8/LayoutTests/fast/block/float/crash-when-floating-object-is-removed.xhtml                                (rev 0)
+++ releases/WebKitGTK/webkit-2.8/LayoutTests/fast/block/float/crash-when-floating-object-is-removed.xhtml        2015-07-06 10:05:01 UTC (rev 186336)
</span><span class="lines">@@ -0,0 +1,45 @@
</span><ins>+&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
+&lt;head&gt;
+&lt;title&gt;This tests that sets for overhanging floating objects are cleaned up properly when the floating object is destroyed.&lt;/title&gt;
+&lt;script&gt;
+  if (window.testRunner)
+    testRunner.dumpAsText();
+&lt;/script&gt;
+&lt;style&gt;
+  html {
+    position: absolute;
+  }
+  
+  .float { 
+    float: left; 
+  }
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;head id=&quot;head1&quot; style=&quot;-webkit-writing-mode: horizontal-bt;&quot;&gt;&lt;/head&gt;
+
+&lt;i&gt;
+  &lt;button id=&quot;button1&quot;&gt;PASS if no crash or ASSERT in debug.&lt;/button&gt;
+&lt;/i&gt;
+&lt;td id=&quot;td1&quot;&gt;
+  &lt;body&gt;&lt;/body&gt;
+&lt;/td&gt;
+&lt;i&gt;&lt;/i&gt;
+
+&lt;script&gt;
+var docElement = document.documentElement;
+function crash() {
+    button1 = document.getElementById(&quot;button1&quot;);
+    button1.classList.toggle(&quot;float&quot;);
+
+    head1 = document.getElementById(&quot;head1&quot;);
+    td1 = document.getElementById(&quot;td1&quot;);
+    head1.appendChild(td1);
+
+    docElement.offsetTop;
+    head1.style.display = &quot;list-item&quot;;
+    docElement.offsetTop;
+    button1.classList.toggle(&quot;float&quot;);
+}
+document.addEventListener(&quot;DOMContentLoaded&quot;, crash, false);
+&lt;/script&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit28SourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.8/Source/WebCore/ChangeLog (186335 => 186336)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.8/Source/WebCore/ChangeLog        2015-07-06 09:56:44 UTC (rev 186335)
+++ releases/WebKitGTK/webkit-2.8/Source/WebCore/ChangeLog        2015-07-06 10:05:01 UTC (rev 186336)
</span><span class="lines">@@ -1,3 +1,34 @@
</span><ins>+2015-05-26  Zalan Bujtas  &lt;zalan@apple.com&gt;
+
+        Overhanging float sets are not cleaned up properly when floating renderer is destroyed.
+        https://bugs.webkit.org/show_bug.cgi?id=145323
+        rdar://problem/20980628
+
+        Reviewed by Dave Hyatt.
+
+        This patch ensures when an overhanging float renderer is destroyed,
+        all the sibling containers' floating object set(m_floatingObjects) gets properly cleaned up.
+
+        When an overhanging float is present, we cache the renderer on the parent and on the affected
+        sibling containers too. (RenderBlockFlow::m_floatingObjects) These caches(sets) get cleared and repopulated
+        during ::layout(). In order to have a float renderer removed from a set, a layout needs to be initiated on the container.
+        This is normally done through RenderBlockFlow::markSiblingsWithFloatsForLayout() and RenderBlockFlow::markAllDescendantsWithFloatsForLayout().
+        However, when the float container's parent's writing direction changes (and we promote the children containers to new formatting contexts),
+        the layout propagation through siblings does not work anymore.
+
+        The avoidsFloats() check in RenderBlockFlow::markSiblingsWithFloatsForLayout() has very little performance gain, but it prevents us
+        from propagating layout to siblings when certain properties of the parent container changes.
+
+        Test: fast/block/float/crash-when-floating-object-is-removed.xhtml
+
+        * rendering/RenderBlockFlow.cpp:
+        (WebCore::RenderBlockFlow::markSiblingsWithFloatsForLayout):
+        * rendering/RenderBox.cpp:
+        (WebCore::outermostBlockContainingFloatingObject):
+        (WebCore::RenderBox::removeFloatingOrPositionedChildFromBlockLists):
+        (WebCore::RenderBox::outermostBlockContainingFloatingObject): Deleted.
+        * rendering/RenderBox.h:
+
</ins><span class="cx"> 2015-05-26  Said Abou-Hallawa  &lt;sabouhallawa@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         SVG fragment identifier rendering issue
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit28SourceWebCorerenderingRenderBlockFlowcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.8/Source/WebCore/rendering/RenderBlockFlow.cpp (186335 => 186336)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.8/Source/WebCore/rendering/RenderBlockFlow.cpp        2015-07-06 09:56:44 UTC (rev 186335)
+++ releases/WebKitGTK/webkit-2.8/Source/WebCore/rendering/RenderBlockFlow.cpp        2015-07-06 10:05:01 UTC (rev 186336)
</span><span class="lines">@@ -2746,7 +2746,7 @@
</span><span class="cx">     auto end = floatingObjectSet.end();
</span><span class="cx"> 
</span><span class="cx">     for (RenderObject* next = nextSibling(); next; next = next-&gt;nextSibling()) {
</span><del>-        if (!is&lt;RenderBlockFlow&gt;(*next) || next-&gt;isFloatingOrOutOfFlowPositioned() || downcast&lt;RenderBlockFlow&gt;(*next).avoidsFloats())
</del><ins>+        if (!is&lt;RenderBlockFlow&gt;(*next) || next-&gt;isFloatingOrOutOfFlowPositioned())
</ins><span class="cx">             continue;
</span><span class="cx"> 
</span><span class="cx">         RenderBlockFlow&amp; nextBlock = downcast&lt;RenderBlockFlow&gt;(*next);
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit28SourceWebCorerenderingRenderBoxcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.8/Source/WebCore/rendering/RenderBox.cpp (186335 => 186336)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.8/Source/WebCore/rendering/RenderBox.cpp        2015-07-06 09:56:44 UTC (rev 186335)
+++ releases/WebKitGTK/webkit-2.8/Source/WebCore/rendering/RenderBox.cpp        2015-07-06 10:05:01 UTC (rev 186336)
</span><span class="lines">@@ -263,14 +263,14 @@
</span><span class="cx">     return LayoutRect(0, logicalLeft, width(), logicalWidth);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RenderBlockFlow* RenderBox::outermostBlockContainingFloatingObject()
</del><ins>+static RenderBlockFlow* outermostBlockContainingFloatingObject(RenderBox&amp; box)
</ins><span class="cx"> {
</span><del>-    ASSERT(isFloating());
</del><ins>+    ASSERT(box.isFloating());
</ins><span class="cx">     RenderBlockFlow* parentBlock = nullptr;
</span><del>-    for (auto&amp; ancestor : ancestorsOfType&lt;RenderBlockFlow&gt;(*this)) {
</del><ins>+    for (auto&amp; ancestor : ancestorsOfType&lt;RenderBlockFlow&gt;(box)) {
</ins><span class="cx">         if (ancestor.isRenderView())
</span><span class="cx">             break;
</span><del>-        if (!parentBlock || ancestor.containsFloat(*this))
</del><ins>+        if (!parentBlock || ancestor.containsFloat(box))
</ins><span class="cx">             parentBlock = &amp;ancestor;
</span><span class="cx">     }
</span><span class="cx">     return parentBlock;
</span><span class="lines">@@ -284,7 +284,7 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     if (isFloating()) {
</span><del>-        if (RenderBlockFlow* parentBlock = outermostBlockContainingFloatingObject()) {
</del><ins>+        if (RenderBlockFlow* parentBlock = outermostBlockContainingFloatingObject(*this)) {
</ins><span class="cx">             parentBlock-&gt;markSiblingsWithFloatsForLayout(this);
</span><span class="cx">             parentBlock-&gt;markAllDescendantsWithFloatsForLayout(this, false);
</span><span class="cx">         }
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit28SourceWebCorerenderingRenderBoxh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.8/Source/WebCore/rendering/RenderBox.h (186335 => 186336)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.8/Source/WebCore/rendering/RenderBox.h        2015-07-06 09:56:44 UTC (rev 186335)
+++ releases/WebKitGTK/webkit-2.8/Source/WebCore/rendering/RenderBox.h        2015-07-06 10:05:01 UTC (rev 186336)
</span><span class="lines">@@ -516,8 +516,6 @@
</span><span class="cx"> 
</span><span class="cx">     virtual VisiblePosition positionForPoint(const LayoutPoint&amp;, const RenderRegion*) override;
</span><span class="cx"> 
</span><del>-    RenderBlockFlow* outermostBlockContainingFloatingObject();
-
</del><span class="cx">     void removeFloatingOrPositionedChildFromBlockLists();
</span><span class="cx">     
</span><span class="cx">     RenderLayer* enclosingFloatPaintingLayer() const;
</span></span></pre>
</div>
</div>

</body>
</html>