Chromium Code Reviews| Index: third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp |
| diff --git a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp |
| index f1dcccba117936202cc44c501da8d5e0a59315b8..219f1b5a2dc86f37ab7d86f43b2419ea86ae7e54 100644 |
| --- a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp |
| +++ b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp |
| @@ -33,6 +33,12 @@ |
| namespace blink { |
| +#if DCHECK_IS_ON() |
| +const LayoutBox* LayoutMultiColumnFlowThread::s_styleChangedBox; |
| +#endif |
| +bool LayoutMultiColumnFlowThread::s_couldContainSpanners; |
| +bool LayoutMultiColumnFlowThread::s_toggleSpannersIfNeeded; |
|
mstensho (USE GERRIT)
2016/11/04 20:09:42
This is similar to the static bool s_affectsParent
|
| + |
| LayoutMultiColumnFlowThread::LayoutMultiColumnFlowThread() |
| : m_lastSetWorkedOn(nullptr), |
| m_columnCount(1), |
| @@ -1099,14 +1105,30 @@ void LayoutMultiColumnFlowThread::flowThreadDescendantStyleWillChange( |
| LayoutBox* descendant, |
| StyleDifference diff, |
| const ComputedStyle& newStyle) { |
| - if (needsToRemoveFromFlowThread(descendant->styleRef(), newStyle)) |
| + s_toggleSpannersIfNeeded = false; |
| + if (needsToRemoveFromFlowThread(descendant->styleRef(), newStyle)) { |
| flowThreadDescendantWillBeRemoved(descendant); |
| + return; |
| + } |
| +#if DCHECK_IS_ON() |
| + s_styleChangedBox = descendant; |
| +#endif |
| + // Keep track of whether this object was of such a type that it could contain |
| + // column-span:all descendants. If the style change in progress changes this |
| + // state, we need to look for spanners to add or remove in the subtree of |
| + // |descendant|. |
| + s_toggleSpannersIfNeeded = true; |
| + s_couldContainSpanners = |
| + canContainSpannerInParentFragmentationContext(*descendant); |
| } |
| void LayoutMultiColumnFlowThread::flowThreadDescendantStyleDidChange( |
| LayoutBox* descendant, |
| StyleDifference diff, |
| const ComputedStyle& oldStyle) { |
| + bool toggleSpannersIfNeeded = s_toggleSpannersIfNeeded; |
| + s_toggleSpannersIfNeeded = false; |
| + |
| if (needsToInsertIntoFlowThread(oldStyle, descendant->styleRef())) { |
| flowThreadDescendantWasInserted(descendant); |
| return; |
| @@ -1124,6 +1146,57 @@ void LayoutMultiColumnFlowThread::flowThreadDescendantStyleDidChange( |
| createAndInsertSpannerPlaceholder( |
| descendant, |
| nextInPreOrderAfterChildrenSkippingOutOfFlow(this, descendant)); |
| + return; |
| + } |
| + |
| + if (!toggleSpannersIfNeeded) |
| + return; |
| +#if DCHECK_IS_ON() |
| + // Make sure that we were preceded by a call to |
| + // flowThreadDescendantStyleWillChange() with the same descendant as we have |
| + // now. |
| + DCHECK(s_styleChangedBox == descendant); |
| +#endif |
| + |
| + if (s_couldContainSpanners != |
| + canContainSpannerInParentFragmentationContext(*descendant)) |
| + toggleSpannersInSubtree(descendant); |
| +} |
| + |
| +void LayoutMultiColumnFlowThread::toggleSpannersInSubtree( |
| + LayoutBox* descendant) { |
| + DCHECK(s_couldContainSpanners != |
| + canContainSpannerInParentFragmentationContext(*descendant)); |
| + |
| + // If there are no spanners at all in this multicol container, there's no |
| + // need to look for any to remove. |
| + if (s_couldContainSpanners && !hasAnyColumnSpanners(*this)) |
| + return; |
| + |
| + bool walkChildren; |
| + for (LayoutObject* object = descendant->nextInPreOrder(descendant); object; |
| + object = walkChildren |
| + ? object->nextInPreOrder(descendant) |
| + : object->nextInPreOrderAfterChildren(descendant)) { |
| + walkChildren = false; |
| + if (!object->isBox()) |
| + continue; |
| + LayoutBox& box = toLayoutBox(*object); |
| + if (s_couldContainSpanners) { |
| + // Remove all spanners (turn them into regular column content), as we can |
| + // no longer contain them. |
| + if (box.isColumnSpanAll()) { |
| + destroySpannerPlaceholder(box.spannerPlaceholder()); |
| + continue; |
| + } |
| + } else if (descendantIsValidColumnSpanner(object)) { |
| + // We can now contain spanners, and we found a candidate. Turn it into a |
| + // spanner. |
| + createAndInsertSpannerPlaceholder( |
| + &box, nextInPreOrderAfterChildrenSkippingOutOfFlow(this, &box)); |
| + continue; |
| + } |
| + walkChildren = canContainSpannerInParentFragmentationContext(box); |
| } |
| } |