Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1323)

Unified Diff: Source/core/layout/LayoutMultiColumnFlowThread.cpp

Issue 1162253006: An object may become a column spanner or cease to be one even if column-span doesn't change. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/core/layout/LayoutMultiColumnFlowThread.cpp
diff --git a/Source/core/layout/LayoutMultiColumnFlowThread.cpp b/Source/core/layout/LayoutMultiColumnFlowThread.cpp
index eb55299f7c228df950acc4daddbf5c9ffd99570a..16203d6ff17d8ed4a43672b7c07237a42d1c4cb3 100644
--- a/Source/core/layout/LayoutMultiColumnFlowThread.cpp
+++ b/Source/core/layout/LayoutMultiColumnFlowThread.cpp
@@ -361,6 +361,25 @@ void LayoutMultiColumnFlowThread::columnRuleStyleDidChange()
columnSet->setShouldDoFullPaintInvalidation(PaintInvalidationStyleChange);
}
+bool LayoutMultiColumnFlowThread::removeSpannerPlaceholderIfNoLongerValid(LayoutBox* spannerObjectInFlowThread)
+{
+ ASSERT(spannerObjectInFlowThread->spannerPlaceholder());
+ if (descendantIsValidColumnSpanner(spannerObjectInFlowThread))
+ return false; // Still a valid spanner.
+
+ // No longer a valid spanner. Get rid of the placeholder.
+ destroySpannerPlaceholder(spannerObjectInFlowThread->spannerPlaceholder());
+ ASSERT(!spannerObjectInFlowThread->spannerPlaceholder());
+
+ // We may have a new containing block, since we're no longer a spanner. Mark it for relayout.
+ spannerObjectInFlowThread->containingBlock()->setNeedsLayoutAndPrefWidthsRecalc(LayoutInvalidationReason::ColumnsChanged);
+
+ // Now generate a column set for this ex-spanner, if needed and none is there for us already.
+ flowThreadDescendantWasInserted(spannerObjectInFlowThread);
+
+ return true;
+}
+
void LayoutMultiColumnFlowThread::calculateColumnCountAndWidth(LayoutUnit& width, unsigned& count) const
{
LayoutBlock* columnBlock = multiColumnBlockFlow();
@@ -458,13 +477,15 @@ void LayoutMultiColumnFlowThread::destroySpannerPlaceholder(LayoutMultiColumnSpa
bool LayoutMultiColumnFlowThread::descendantIsValidColumnSpanner(LayoutObject* descendant) const
{
+ // This method needs to behave correctly in the following situations:
+ // - When the descendant doesn't have a spanner placeholder but should have one (return true)
+ // - When the descendant doesn't have a spanner placeholder and still should not have one (return false)
+ // - When the descendant has a spanner placeholder but should no longer have one (return false)
+ // - When the descendant has a spanner placeholder and should still have one (return true)
+
// We assume that we're inside the flow thread. This function is not to be called otherwise.
ASSERT(descendant->isDescendantOf(this));
- // We're evaluating if the descendant should be turned into a proper spanner. It shouldn't
- // already be one.
- ASSERT(!descendant->spannerPlaceholder());
-
// The spec says that column-span only applies to in-flow block-level elements.
if (descendant->style()->columnSpan() != ColumnSpanAll || !descendant->isBox() || descendant->isInline() || descendant->isFloatingOrOutOfFlowPositioned())
return false;
@@ -475,7 +496,7 @@ bool LayoutMultiColumnFlowThread::descendantIsValidColumnSpanner(LayoutObject* d
}
// This looks like a spanner, but if we're inside something unbreakable, it's not to be treated as one.
- for (LayoutBlock* ancestor = descendant->containingBlock(); ancestor; ancestor = ancestor->containingBlock()) {
+ for (LayoutBox* ancestor = toLayoutBox(descendant)->parentBox(); ancestor; ancestor = ancestor->containingBlock()) {
if (ancestor->isLayoutFlowThread()) {
ASSERT(ancestor == this);
return true;
@@ -712,8 +733,27 @@ void LayoutMultiColumnFlowThread::flowThreadDescendantStyleDidChange(LayoutObjec
// of the multicol is bad.
return;
}
- if (oldStyle.hasOutOfFlowPosition() && !styleRef().hasOutOfFlowPosition())
+ if (styleRef().hasOutOfFlowPosition())
+ return;
+
+ // We're not out of flow.
+ if (oldStyle.hasOutOfFlowPosition()) {
+ // ... but we used to be out of flow. So we might need to insert a column set (or
+ // spanner placeholder, in case this descendant is now a valid column spanner).
flowThreadDescendantWasInserted(descendant);
+ return;
+ }
+ if (descendantIsValidColumnSpanner(descendant)) {
+ // We went from being regular column content to becoming a spanner.
+ ASSERT(!toLayoutBox(descendant)->spannerPlaceholder());
+
+ // First remove this as regular column content. Note that this will walk the entire subtree
+ // of |descendant|. There might be spanners there (which won't be spanners anymore, since
+ // we're not allowed to nest spanners), whose placeholders must die.
+ flowThreadDescendantWillBeRemoved(descendant);
+
+ createAndInsertSpannerPlaceholder(toLayoutBox(descendant), nextInPreOrderAfterChildrenSkippingOutOfFlow(this, descendant));
+ }
}
void LayoutMultiColumnFlowThread::computePreferredLogicalWidths()
« no previous file with comments | « Source/core/layout/LayoutMultiColumnFlowThread.h ('k') | Source/core/layout/LayoutMultiColumnSpannerPlaceholder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698