<!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 <hyatt@apple.com>
+
+ 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 <roger_fong@apple.com>
</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>+<p>This test passes if it doesn't crash. '<a id="a"></a>:
+<script>
+if (window.testRunner)
+ testRunner.dumpAsText();
+document.getElementById("a").appendChild(document.createElement("fieldset")).setAttribute("style","-webkit-column-span:all;");
+head = document.getElementsByTagName("head")[0];
+var style = document.createElement("style");
+var rule = document.createTextNode(":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\
+");
+style.appendChild(rule);
+head.appendChild(style);
+</script>
</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 <hyatt@apple.com>
+
+ 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 <cdumez@apple.com>
</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*& subtreeRoot, RenderObject* descendant)
+{
+ RenderBlockFlow* multicolContainer = multiColumnBlockFlow();
+ RenderObject* nextRendererInFlowThread = descendant->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->parent());
+ RenderMultiColumnSet* setToSplit = nullptr;
+ if (nextRendererInFlowThread) {
+ setToSplit = findSetRendering(descendant);
+ if (setToSplit) {
+ setToSplit->setNeedsLayout();
+ insertBeforeMulticolChild = setToSplit->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), &container->style());
+ container->addChild(placeholder, descendant->nextSibling());
+ container->removeChild(*descendant);
+
+ // This is a guard to stop an ancestor flow thread from processing the spanner.
+ gShiftingSpanner = true;
+ multicolContainer->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 && nextRendererInFlowThread->isRenderMultiColumnSpannerPlaceholder()) {
+ // Inserted right before a spanner. Is there a set for us there?
+ RenderMultiColumnSpannerPlaceholder* placeholder = toRenderMultiColumnSpannerPlaceholder(nextRendererInFlowThread);
+ if (RenderObject* previous = placeholder->spanner()->previousSibling()) {
+ if (previous->isRenderMultiColumnSet())
+ return nextDescendant; // There's already a set there. Nothing to do.
+ }
+ insertBeforeMulticolChild = placeholder->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->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(&multicolContainer->style(), BLOCK));
+ newSet->initializeStyle();
+ multicolContainer->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)->isRenderMultiColumnSet());
+ ASSERT(!nextColumnSetOrSpannerSiblingOf(newSet) || !nextColumnSetOrSpannerSiblingOf(newSet)->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->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->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->parent());
-
</del><ins>+ // Insert after the placeholder, but don't let a notification happen.
+ gShiftingSpanner = true;
+ RenderBlockFlow* ancestorBlock = toRenderBlockFlow(spanner->parent());
+ ancestorBlock->moveChildTo(placeholder->parentBox(), spanner, placeholder->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->removeChild(*placeholder);
-
- // Get the ancestor multicolumn flow thread to clean up its mess.
- RenderBlockFlow* ancestorBlock = toRenderBlockFlow(spanner->parent());
- ancestorBlock->multiColumnFlowThread()->flowThreadRelativeWillBeRemoved(spanner);
</del><ins>+ ancestorBlock->multiColumnFlowThread()->handleSpannerRemoval(spanner);
+ placeholder->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->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->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->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->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->parent());
- RenderMultiColumnSet* setToSplit = nullptr;
- if (nextRendererInFlowThread) {
- setToSplit = findSetRendering(descendant);
- if (setToSplit) {
- setToSplit->setNeedsLayout();
- insertBeforeMulticolChild = setToSplit->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->parent()->removeChild(*placeholder);
+ m_spannerMap.remove(toRenderBox(spanner));
+ }
+
+ if (RenderObject* next = spanner->nextSibling()) {
+ if (RenderObject* previous = spanner->previousSibling()) {
+ if (previous->isRenderMultiColumnSet() && next->isRenderMultiColumnSet()) {
+ // Merge two sets that no longer will be separated by a spanner.
+ next->destroy();
+ previous->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), &container->style());
- container->addChild(placeholder, descendant->nextSibling());
- container->removeChild(*descendant);
-
- // This is a guard to stop an ancestor flow thread from processing the spanner.
- gShiftingSpanner = true;
- multicolContainer->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 && nextRendererInFlowThread->isRenderMultiColumnSpannerPlaceholder()) {
- // Inserted right before a spanner. Is there a set for us there?
- RenderMultiColumnSpannerPlaceholder* placeholder = toRenderMultiColumnSpannerPlaceholder(nextRendererInFlowThread);
- if (RenderObject* previous = placeholder->spanner()->previousSibling()) {
- if (previous->isRenderMultiColumnSet())
- continue; // There's already a set there. Nothing to do.
- }
- insertBeforeMulticolChild = placeholder->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->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(&multicolContainer->style(), BLOCK));
- newSet->initializeStyle();
- multicolContainer->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)->isRenderMultiColumnSet());
- ASSERT(!nextColumnSetOrSpannerSiblingOf(newSet) || !nextColumnSetOrSpannerSiblingOf(newSet)->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->style().columnSpan() == ColumnSpanAll) {
</span><span class="cx"> if (relative->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->parent()->removeChild(*placeholder);
- m_spannerMap.remove(toRenderBox(relative));
- }
-
- if (RenderObject* next = relative->nextSibling()) {
- if (RenderObject* previous = relative->previousSibling()) {
- if (previous->isRenderMultiColumnSet() && next->isRenderMultiColumnSet()) {
- // Merge two sets that no longer will be separated by a spanner.
- next->destroy();
- previous->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*& subtreeRoot, RenderObject* descendant);
+
</ins><span class="cx"> private:
</span><span class="cx"> typedef HashMap<RenderBox*, RenderMultiColumnSpannerPlaceholder*> SpannerMap;
</span><span class="cx"> SpannerMap m_spannerMap;
</span></span></pre>
</div>
</div>
</body>
</html>