<!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>[174085] trunk</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/174085">174085</a></dd>
<dt>Author</dt> <dd>hyatt@apple.com</dd>
<dt>Date</dt> <dd>2014-09-29 13:54:02 -0700 (Mon, 29 Sep 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>REGRESSION (<a href="http://trac.webkit.org/projects/webkit/changeset/168046">r168046</a>): Confused column spans when combined with dynamic animations
https://bugs.webkit.org/show_bug.cgi?id=134048.

Reviewed by Dean Jackson.

Source/WebCore:

Added fast/multicol/multicol-fieldset-span-changes.html

* rendering/RenderMultiColumnFlowThread.cpp:
(WebCore::RenderMultiColumnFlowThread::processPossibleSpannerDescendant):
Refactor handling of insertions into the multicolumn flow thread into
a helper function, processPossibleSpannerDescendant. This makes it easier
to call the code from more than one place.

(WebCore::RenderMultiColumnFlowThread::flowThreadDescendantInserted):
Modify the nested columns span shifting code to avoid problems. The
new code suppresses notifications and does the move of the spanner back
into the original spot *before* removing the placeholder. This ensures that
the placeholder parent still exists.
        
The stale placeholder is then removed and destroyed after the spanner has been put back
into place.

(WebCore::RenderMultiColumnFlowThread::handleSpannerRemoval):
(WebCore::RenderMultiColumnFlowThread::flowThreadRelativeWillBeRemoved):
Refactor the removal notifications for spanners into a helper function so that it can
be called to do cleanup from the code that cleans up stale placeholders on a shift.

* rendering/RenderMultiColumnFlowThread.h:
Modified to add the new helpers.

LayoutTests:

* fast/multicol/multicol-fieldset-span-changes-expected.txt: Added.
* fast/multicol/multicol-fieldset-span-changes.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderMultiColumnFlowThreadcpp">trunk/Source/WebCore/rendering/RenderMultiColumnFlowThread.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderMultiColumnFlowThreadh">trunk/Source/WebCore/rendering/RenderMultiColumnFlowThread.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastmulticolmulticolfieldsetspanchangesexpectedtxt">trunk/LayoutTests/fast/multicol/multicol-fieldset-span-changes-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastmulticolmulticolfieldsetspanchangeshtml">trunk/LayoutTests/fast/multicol/multicol-fieldset-span-changes.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (174084 => 174085)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-09-29 20:50:45 UTC (rev 174084)
+++ trunk/LayoutTests/ChangeLog        2014-09-29 20:54:02 UTC (rev 174085)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2014-09-29  David Hyatt  &lt;hyatt@apple.com&gt;
+
+        REGRESSION (r168046): Confused column spans when combined with dynamic animations
+        https://bugs.webkit.org/show_bug.cgi?id=134048.
+
+        Reviewed by Dean Jackson.
+
+        * fast/multicol/multicol-fieldset-span-changes-expected.txt: Added.
+        * fast/multicol/multicol-fieldset-span-changes.html: Added.
+
</ins><span class="cx"> 2014-09-29  Roger Fong  &lt;roger_fong@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [Windows] Skip some failing inspector tests following r174020.
</span></span></pre></div>
<a id="trunkLayoutTestsfastmulticolmulticolfieldsetspanchangesexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/multicol/multicol-fieldset-span-changes-expected.txt (0 => 174085)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/multicol/multicol-fieldset-span-changes-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/multicol/multicol-fieldset-span-changes-expected.txt        2014-09-29 20:54:02 UTC (rev 174085)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+This test passes if it doesn't crash. ':
</ins></span></pre></div>
<a id="trunkLayoutTestsfastmulticolmulticolfieldsetspanchangeshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/multicol/multicol-fieldset-span-changes.html (0 => 174085)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/multicol/multicol-fieldset-span-changes.html                                (rev 0)
+++ trunk/LayoutTests/fast/multicol/multicol-fieldset-span-changes.html        2014-09-29 20:54:02 UTC (rev 174085)
</span><span class="lines">@@ -0,0 +1,20 @@
</span><ins>+&lt;p&gt;This test passes if it doesn't crash. '&lt;a id=&quot;a&quot;&gt;&lt;/a&gt;:
+&lt;script&gt;
+if (window.testRunner)
+        testRunner.dumpAsText();
+document.getElementById(&quot;a&quot;).appendChild(document.createElement(&quot;fieldset&quot;)).setAttribute(&quot;style&quot;,&quot;-webkit-column-span:all;&quot;);
+head = document.getElementsByTagName(&quot;head&quot;)[0];
+var style = document.createElement(&quot;style&quot;);
+var rule = document.createTextNode(&quot;:first-of-type { \n\
+-webkit-animation-name: name1; \n\
+-webkit-animation-duration: 6s; \n\
+} \n\
+@-webkit-keyframes name1 { \n\
+  from { \n\
+  } \n\
+  to { \n\
+    -webkit-column-width: auto \n\
+&quot;);
+style.appendChild(rule);
+head.appendChild(style);
+&lt;/script&gt;
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (174084 => 174085)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-09-29 20:50:45 UTC (rev 174084)
+++ trunk/Source/WebCore/ChangeLog        2014-09-29 20:54:02 UTC (rev 174085)
</span><span class="lines">@@ -1,3 +1,35 @@
</span><ins>+2014-09-29  David Hyatt  &lt;hyatt@apple.com&gt;
+
+        REGRESSION (r168046): Confused column spans when combined with dynamic animations
+        https://bugs.webkit.org/show_bug.cgi?id=134048.
+
+        Reviewed by Dean Jackson.
+
+        Added fast/multicol/multicol-fieldset-span-changes.html
+
+        * rendering/RenderMultiColumnFlowThread.cpp:
+        (WebCore::RenderMultiColumnFlowThread::processPossibleSpannerDescendant):
+        Refactor handling of insertions into the multicolumn flow thread into
+        a helper function, processPossibleSpannerDescendant. This makes it easier
+        to call the code from more than one place.
+
+        (WebCore::RenderMultiColumnFlowThread::flowThreadDescendantInserted):
+        Modify the nested columns span shifting code to avoid problems. The
+        new code suppresses notifications and does the move of the spanner back
+        into the original spot *before* removing the placeholder. This ensures that
+        the placeholder parent still exists.
+        
+        The stale placeholder is then removed and destroyed after the spanner has been put back
+        into place.
+
+        (WebCore::RenderMultiColumnFlowThread::handleSpannerRemoval):
+        (WebCore::RenderMultiColumnFlowThread::flowThreadRelativeWillBeRemoved):
+        Refactor the removal notifications for spanners into a helper function so that it can
+        be called to do cleanup from the code that cleans up stale placeholders on a shift.
+
+        * rendering/RenderMultiColumnFlowThread.h:
+        Modified to add the new helpers.
+
</ins><span class="cx"> 2014-09-29  Christophe Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Use SPECIALIZE_TYPE_TRAITS_*() macro for MathMLElement
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderMultiColumnFlowThreadcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderMultiColumnFlowThread.cpp (174084 => 174085)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderMultiColumnFlowThread.cpp        2014-09-29 20:50:45 UTC (rev 174084)
+++ trunk/Source/WebCore/rendering/RenderMultiColumnFlowThread.cpp        2014-09-29 20:54:02 UTC (rev 174085)
</span><span class="lines">@@ -279,6 +279,87 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+RenderObject* RenderMultiColumnFlowThread::processPossibleSpannerDescendant(RenderObject*&amp; subtreeRoot, RenderObject* descendant)
+{
+    RenderBlockFlow* multicolContainer = multiColumnBlockFlow();
+    RenderObject* nextRendererInFlowThread = descendant-&gt;nextInPreOrderAfterChildren(this);
+    RenderObject* insertBeforeMulticolChild = nullptr;
+    RenderObject* nextDescendant = descendant;
+
+    if (isValidColumnSpanner(this, descendant)) {
+        // This is a spanner (column-span:all). Such renderers are moved from where they would
+        // otherwise occur in the render tree to becoming a direct child of the multicol container,
+        // so that they live among the column sets. This simplifies the layout implementation, and
+        // basically just relies on regular block layout done by the RenderBlockFlow that
+        // establishes the multicol container.
+        RenderBlockFlow* container = toRenderBlockFlow(descendant-&gt;parent());
+        RenderMultiColumnSet* setToSplit = nullptr;
+        if (nextRendererInFlowThread) {
+            setToSplit = findSetRendering(descendant);
+            if (setToSplit) {
+                setToSplit-&gt;setNeedsLayout();
+                insertBeforeMulticolChild = setToSplit-&gt;nextSibling();
+            }
+        }
+        // Moving a spanner's renderer so that it becomes a sibling of the column sets requires us
+        // to insert an anonymous placeholder in the tree where the spanner's renderer otherwise
+        // would have been. This is needed for a two reasons: We need a way of separating inline
+        // content before and after the spanner, so that it becomes separate line boxes. Secondly,
+        // this placeholder serves as a break point for column sets, so that, when encountered, we
+        // end flowing one column set and move to the next one.
+        RenderMultiColumnSpannerPlaceholder* placeholder = RenderMultiColumnSpannerPlaceholder::createAnonymous(this, toRenderBox(descendant), &amp;container-&gt;style());
+        container-&gt;addChild(placeholder, descendant-&gt;nextSibling());
+        container-&gt;removeChild(*descendant);
+        
+        // This is a guard to stop an ancestor flow thread from processing the spanner.
+        gShiftingSpanner = true;
+        multicolContainer-&gt;RenderBlock::addChild(descendant, insertBeforeMulticolChild);
+        gShiftingSpanner = false;
+        
+        // The spanner has now been moved out from the flow thread, but we don't want to
+        // examine its children anyway. They are all part of the spanner and shouldn't trigger
+        // creation of column sets or anything like that. Continue at its original position in
+        // the tree, i.e. where the placeholder was just put.
+        if (subtreeRoot == descendant)
+            subtreeRoot = placeholder;
+        nextDescendant = placeholder;
+    } else {
+        // This is regular multicol content, i.e. not part of a spanner.
+        if (nextRendererInFlowThread &amp;&amp; nextRendererInFlowThread-&gt;isRenderMultiColumnSpannerPlaceholder()) {
+            // Inserted right before a spanner. Is there a set for us there?
+            RenderMultiColumnSpannerPlaceholder* placeholder = toRenderMultiColumnSpannerPlaceholder(nextRendererInFlowThread);
+            if (RenderObject* previous = placeholder-&gt;spanner()-&gt;previousSibling()) {
+                if (previous-&gt;isRenderMultiColumnSet())
+                    return nextDescendant; // There's already a set there. Nothing to do.
+            }
+            insertBeforeMulticolChild = placeholder-&gt;spanner();
+        } else if (RenderMultiColumnSet* lastSet = lastMultiColumnSet()) {
+            // This child is not an immediate predecessor of a spanner, which means that if this
+            // child precedes a spanner at all, there has to be a column set created for us there
+            // already. If it doesn't precede any spanner at all, on the other hand, we need a
+            // column set at the end of the multicol container. We don't really check here if the
+            // child inserted precedes any spanner or not (as that's an expensive operation). Just
+            // make sure we have a column set at the end. It's no big deal if it remains unused.
+            if (!lastSet-&gt;nextSibling())
+                return nextDescendant;
+        }
+    }
+    // Need to create a new column set when there's no set already created. We also always insert
+    // another column set after a spanner. Even if it turns out that there are no renderers
+    // following the spanner, there may be bottom margins there, which take up space.
+    RenderMultiColumnSet* newSet = new RenderMultiColumnSet(*this, RenderStyle::createAnonymousStyleWithDisplay(&amp;multicolContainer-&gt;style(), BLOCK));
+    newSet-&gt;initializeStyle();
+    multicolContainer-&gt;RenderBlock::addChild(newSet, insertBeforeMulticolChild);
+    invalidateRegions();
+
+    // We cannot handle immediate column set siblings at the moment (and there's no need for
+    // it, either). There has to be at least one spanner separating them.
+    ASSERT(!previousColumnSetOrSpannerSiblingOf(newSet) || !previousColumnSetOrSpannerSiblingOf(newSet)-&gt;isRenderMultiColumnSet());
+    ASSERT(!nextColumnSetOrSpannerSiblingOf(newSet) || !nextColumnSetOrSpannerSiblingOf(newSet)-&gt;isRenderMultiColumnSet());
+    
+    return nextDescendant;
+}
+
</ins><span class="cx"> void RenderMultiColumnFlowThread::flowThreadDescendantInserted(RenderObject* descendant)
</span><span class="cx"> {
</span><span class="cx">     if (gShiftingSpanner || m_beingEvacuated || descendant-&gt;isInFlowRenderFlowThread())
</span><span class="lines">@@ -296,33 +377,19 @@
</span><span class="cx">                 // and get the spanner content back into this flow thread.
</span><span class="cx">                 RenderBox* spanner = placeholder-&gt;spanner();
</span><span class="cx">                 
</span><del>-                // Get info for the move of the original content back into our flow thread.
-                RenderBoxModelObject* placeholderParent = toRenderBoxModelObject(placeholder-&gt;parent());
-            
</del><ins>+                // Insert after the placeholder, but don't let a notification happen.
+                gShiftingSpanner = true;
+                RenderBlockFlow* ancestorBlock = toRenderBlockFlow(spanner-&gt;parent());
+                ancestorBlock-&gt;moveChildTo(placeholder-&gt;parentBox(), spanner, placeholder-&gt;nextSibling(), true);
+                gShiftingSpanner = false;
+                
</ins><span class="cx">                 // We have to nuke the placeholder, since the ancestor already lost the mapping to it when
</span><span class="cx">                 // we shifted the placeholder down into this flow thread.
</span><del>-                RenderObject* placeholderNextSibling = placeholderParent-&gt;removeChild(*placeholder);
-
-                // Get the ancestor multicolumn flow thread to clean up its mess.
-                RenderBlockFlow* ancestorBlock = toRenderBlockFlow(spanner-&gt;parent());
-                ancestorBlock-&gt;multiColumnFlowThread()-&gt;flowThreadRelativeWillBeRemoved(spanner);
</del><ins>+                ancestorBlock-&gt;multiColumnFlowThread()-&gt;handleSpannerRemoval(spanner);
+                placeholder-&gt;destroy();
</ins><span class="cx">                 
</span><del>-                // Now move the original content into our flow thread. It will end up calling flowThreadDescendantInserted
-                // on the new content only, and everything will get set up properly.
-                ancestorBlock-&gt;moveChildTo(placeholderParent, spanner, placeholderNextSibling, true);
-                
-                // Advance descendant.
-                descendant = placeholderNextSibling;
-                
-                // If the spanner was the subtree root, then we're done, since there is nothing else left to insert.
-                if (!descendant)
-                    return;
-
-                // Now that we have done this, we can continue past the spanning content, since we advanced
-                // descendant already.
-                if (descendant)
-                    descendant = descendant-&gt;previousInPreOrder(subtreeRoot);
-
</del><ins>+                // Now we process the spanner.
+                descendant = processPossibleSpannerDescendant(subtreeRoot, spanner);
</ins><span class="cx">                 continue;
</span><span class="cx">             }
</span><span class="cx">             
</span><span class="lines">@@ -331,79 +398,27 @@
</span><span class="cx">             ASSERT(!placeholder-&gt;firstChild()); // There should be no children here, but if there are, we ought to skip them.
</span><span class="cx">             continue;
</span><span class="cx">         }
</span><del>-        RenderBlockFlow* multicolContainer = multiColumnBlockFlow();
-        RenderObject* nextRendererInFlowThread = descendant-&gt;nextInPreOrderAfterChildren(this);
-        RenderObject* insertBeforeMulticolChild = nullptr;
-        if (isValidColumnSpanner(this, descendant)) {
-            // This is a spanner (column-span:all). Such renderers are moved from where they would
-            // otherwise occur in the render tree to becoming a direct child of the multicol container,
-            // so that they live among the column sets. This simplifies the layout implementation, and
-            // basically just relies on regular block layout done by the RenderBlockFlow that
-            // establishes the multicol container.
-            RenderBlockFlow* container = toRenderBlockFlow(descendant-&gt;parent());
-            RenderMultiColumnSet* setToSplit = nullptr;
-            if (nextRendererInFlowThread) {
-                setToSplit = findSetRendering(descendant);
-                if (setToSplit) {
-                    setToSplit-&gt;setNeedsLayout();
-                    insertBeforeMulticolChild = setToSplit-&gt;nextSibling();
-                }
</del><ins>+        
+        descendant = processPossibleSpannerDescendant(subtreeRoot, descendant);
+    }
+}
+
+void RenderMultiColumnFlowThread::handleSpannerRemoval(RenderObject* spanner)
+{
+     // The placeholder may already have been removed, but if it hasn't, do so now.
+    if (RenderMultiColumnSpannerPlaceholder* placeholder = m_spannerMap.get(toRenderBox(spanner))) {
+        placeholder-&gt;parent()-&gt;removeChild(*placeholder);
+        m_spannerMap.remove(toRenderBox(spanner));
+    }
+
+    if (RenderObject* next = spanner-&gt;nextSibling()) {
+        if (RenderObject* previous = spanner-&gt;previousSibling()) {
+            if (previous-&gt;isRenderMultiColumnSet() &amp;&amp; next-&gt;isRenderMultiColumnSet()) {
+                // Merge two sets that no longer will be separated by a spanner.
+                next-&gt;destroy();
+                previous-&gt;setNeedsLayout();
</ins><span class="cx">             }
</span><del>-            // Moving a spanner's renderer so that it becomes a sibling of the column sets requires us
-            // to insert an anonymous placeholder in the tree where the spanner's renderer otherwise
-            // would have been. This is needed for a two reasons: We need a way of separating inline
-            // content before and after the spanner, so that it becomes separate line boxes. Secondly,
-            // this placeholder serves as a break point for column sets, so that, when encountered, we
-            // end flowing one column set and move to the next one.
-            RenderMultiColumnSpannerPlaceholder* placeholder = RenderMultiColumnSpannerPlaceholder::createAnonymous(this, toRenderBox(descendant), &amp;container-&gt;style());
-            container-&gt;addChild(placeholder, descendant-&gt;nextSibling());
-            container-&gt;removeChild(*descendant);
-            
-            // This is a guard to stop an ancestor flow thread from processing the spanner.
-            gShiftingSpanner = true;
-            multicolContainer-&gt;RenderBlock::addChild(descendant, insertBeforeMulticolChild);
-            gShiftingSpanner = false;
-            
-            // The spanner has now been moved out from the flow thread, but we don't want to
-            // examine its children anyway. They are all part of the spanner and shouldn't trigger
-            // creation of column sets or anything like that. Continue at its original position in
-            // the tree, i.e. where the placeholder was just put.
-            if (subtreeRoot == descendant)
-                subtreeRoot = placeholder;
-            descendant = placeholder;
-        } else {
-            // This is regular multicol content, i.e. not part of a spanner.
-            if (nextRendererInFlowThread &amp;&amp; nextRendererInFlowThread-&gt;isRenderMultiColumnSpannerPlaceholder()) {
-                // Inserted right before a spanner. Is there a set for us there?
-                RenderMultiColumnSpannerPlaceholder* placeholder = toRenderMultiColumnSpannerPlaceholder(nextRendererInFlowThread);
-                if (RenderObject* previous = placeholder-&gt;spanner()-&gt;previousSibling()) {
-                    if (previous-&gt;isRenderMultiColumnSet())
-                        continue; // There's already a set there. Nothing to do.
-                }
-                insertBeforeMulticolChild = placeholder-&gt;spanner();
-            } else if (RenderMultiColumnSet* lastSet = lastMultiColumnSet()) {
-                // This child is not an immediate predecessor of a spanner, which means that if this
-                // child precedes a spanner at all, there has to be a column set created for us there
-                // already. If it doesn't precede any spanner at all, on the other hand, we need a
-                // column set at the end of the multicol container. We don't really check here if the
-                // child inserted precedes any spanner or not (as that's an expensive operation). Just
-                // make sure we have a column set at the end. It's no big deal if it remains unused.
-                if (!lastSet-&gt;nextSibling())
-                    continue;
-            }
</del><span class="cx">         }
</span><del>-        // Need to create a new column set when there's no set already created. We also always insert
-        // another column set after a spanner. Even if it turns out that there are no renderers
-        // following the spanner, there may be bottom margins there, which take up space.
-        RenderMultiColumnSet* newSet = new RenderMultiColumnSet(*this, RenderStyle::createAnonymousStyleWithDisplay(&amp;multicolContainer-&gt;style(), BLOCK));
-        newSet-&gt;initializeStyle();
-        multicolContainer-&gt;RenderBlock::addChild(newSet, insertBeforeMulticolChild);
-        invalidateRegions();
-
-        // We cannot handle immediate column set siblings at the moment (and there's no need for
-        // it, either). There has to be at least one spanner separating them.
-        ASSERT(!previousColumnSetOrSpannerSiblingOf(newSet) || !previousColumnSetOrSpannerSiblingOf(newSet)-&gt;isRenderMultiColumnSet());
-        ASSERT(!nextColumnSetOrSpannerSiblingOf(newSet) || !nextColumnSetOrSpannerSiblingOf(newSet)-&gt;isRenderMultiColumnSet());
</del><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -423,22 +438,8 @@
</span><span class="cx">     if (relative-&gt;style().columnSpan() == ColumnSpanAll) {
</span><span class="cx">         if (relative-&gt;parent() != parent())
</span><span class="cx">             return; // not a valid spanner.
</span><del>-
-        // The placeholder may already have been removed, but if it hasn't, do so now.
-        if (RenderMultiColumnSpannerPlaceholder* placeholder = m_spannerMap.get(toRenderBox(relative))) {
-            placeholder-&gt;parent()-&gt;removeChild(*placeholder);
-            m_spannerMap.remove(toRenderBox(relative));
-        }
-
-        if (RenderObject* next = relative-&gt;nextSibling()) {
-            if (RenderObject* previous = relative-&gt;previousSibling()) {
-                if (previous-&gt;isRenderMultiColumnSet() &amp;&amp; next-&gt;isRenderMultiColumnSet()) {
-                    // Merge two sets that no longer will be separated by a spanner.
-                    next-&gt;destroy();
-                    previous-&gt;setNeedsLayout();
-                }
-            }
-        }
</del><ins>+        
+        handleSpannerRemoval(relative);
</ins><span class="cx">     }
</span><span class="cx">     // Note that we might end up with empty column sets if all column content is removed. That's no
</span><span class="cx">     // big deal though (and locating them would be expensive), and they will be found and re-used if
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderMultiColumnFlowThreadh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderMultiColumnFlowThread.h (174084 => 174085)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderMultiColumnFlowThread.h        2014-09-29 20:50:45 UTC (rev 174084)
+++ trunk/Source/WebCore/rendering/RenderMultiColumnFlowThread.h        2014-09-29 20:54:02 UTC (rev 174085)
</span><span class="lines">@@ -132,6 +132,9 @@
</span><span class="cx">     virtual bool addForcedRegionBreak(const RenderBlock*, LayoutUnit, RenderBox* breakChild, bool isBefore, LayoutUnit* offsetBreakAdjustment = 0) override;
</span><span class="cx">     virtual bool isPageLogicalHeightKnown() const override;
</span><span class="cx"> 
</span><ins>+    void handleSpannerRemoval(RenderObject* spanner);
+    RenderObject* processPossibleSpannerDescendant(RenderObject*&amp; subtreeRoot, RenderObject* descendant);
+    
</ins><span class="cx"> private:
</span><span class="cx">     typedef HashMap&lt;RenderBox*, RenderMultiColumnSpannerPlaceholder*&gt; SpannerMap;
</span><span class="cx">     SpannerMap m_spannerMap;
</span></span></pre>
</div>
</div>

</body>
</html>