Title: [167714] trunk/Source/WebCore
Revision
167714
Author
hy...@apple.com
Date
2014-04-23 11:05:33 -0700 (Wed, 23 Apr 2014)

Log Message

[New Multicolumn] Nested columns not working at all.
https://bugs.webkit.org/show_bug.cgi?id=131805

Reviewed by Dean Jackson.

Add support for nested pagination contexts, allowing for an arbitrary level
of nesting of multicolumn layouts. There were a number of things that had to
be patched in order for this to work.

* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::regionAtBlockOffset):
Make sure RenderMultiColumnFlowThreads just return null for regions at any
block offset. Individual region sets will be created as you cross ancestor
regions eventually, so this is just getting in the way.

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::enclosingPaginationLayerInSubtree):
Add a new helper method for obtaining an enclosingPaginationLayer when
constrained by some root. This function ensures you don't accidentally
cross your subtree root when looking for enclosing pagination layers.

(WebCore::RenderLayer::collectFragments):
Patch collectFragments to know how to recur to collect ancestor fragments
in order to apply nested splitting as you cross pagination boundaries.

(WebCore::RenderLayer::updatePaintingInfoForFragments):
(WebCore::RenderLayer::calculateClipRects):
* rendering/RenderLayer.h:
(WebCore::LayerFragment::LayerFragment):
(WebCore::LayerFragment::setRects):
(WebCore::LayerFragment::moveBy):
(WebCore::LayerFragment::intersect):
Improve the LayerFragment so that it caches transformed bounding boxes as
well. This is needed to fix intersectsDamageRect so that it doesn't grab
the wrong bounding box when checking inline layers that are paginated.

* rendering/RenderMultiColumnFlowThread.cpp:
(WebCore::RenderMultiColumnFlowThread::flowThreadDescendantInserted):
Ignore inserted flow threads inside an ancestor flow thread, since we only
care about what the sets do.
        
* rendering/RenderObject.cpp:
(WebCore::RenderObject::insertedIntoTree):
Make sure that nested flow thread layers return themselves when a child
is inserted directly under them.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (167713 => 167714)


--- trunk/Source/WebCore/ChangeLog	2014-04-23 17:49:40 UTC (rev 167713)
+++ trunk/Source/WebCore/ChangeLog	2014-04-23 18:05:33 UTC (rev 167714)
@@ -1,3 +1,51 @@
+2014-04-22  David Hyatt  <hy...@apple.com>
+
+        [New Multicolumn] Nested columns not working at all.
+        https://bugs.webkit.org/show_bug.cgi?id=131805
+
+        Reviewed by Dean Jackson.
+
+        Add support for nested pagination contexts, allowing for an arbitrary level
+        of nesting of multicolumn layouts. There were a number of things that had to
+        be patched in order for this to work.
+
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::regionAtBlockOffset):
+        Make sure RenderMultiColumnFlowThreads just return null for regions at any
+        block offset. Individual region sets will be created as you cross ancestor
+        regions eventually, so this is just getting in the way.
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::enclosingPaginationLayerInSubtree):
+        Add a new helper method for obtaining an enclosingPaginationLayer when
+        constrained by some root. This function ensures you don't accidentally
+        cross your subtree root when looking for enclosing pagination layers.
+
+        (WebCore::RenderLayer::collectFragments):
+        Patch collectFragments to know how to recur to collect ancestor fragments
+        in order to apply nested splitting as you cross pagination boundaries.
+
+        (WebCore::RenderLayer::updatePaintingInfoForFragments):
+        (WebCore::RenderLayer::calculateClipRects):
+        * rendering/RenderLayer.h:
+        (WebCore::LayerFragment::LayerFragment):
+        (WebCore::LayerFragment::setRects):
+        (WebCore::LayerFragment::moveBy):
+        (WebCore::LayerFragment::intersect):
+        Improve the LayerFragment so that it caches transformed bounding boxes as
+        well. This is needed to fix intersectsDamageRect so that it doesn't grab
+        the wrong bounding box when checking inline layers that are paginated.
+
+        * rendering/RenderMultiColumnFlowThread.cpp:
+        (WebCore::RenderMultiColumnFlowThread::flowThreadDescendantInserted):
+        Ignore inserted flow threads inside an ancestor flow thread, since we only
+        care about what the sets do.
+        
+        * rendering/RenderObject.cpp:
+        (WebCore::RenderObject::insertedIntoTree):
+        Make sure that nested flow thread layers return themselves when a child
+        is inserted directly under them.
+
 2014-04-22  Myles C. Maxfield  <mmaxfi...@apple.com>
 
         [OS X] Make checking if a font is the system font more robust

Modified: trunk/Source/WebCore/rendering/RenderBlock.cpp (167713 => 167714)


--- trunk/Source/WebCore/rendering/RenderBlock.cpp	2014-04-23 17:49:40 UTC (rev 167713)
+++ trunk/Source/WebCore/rendering/RenderBlock.cpp	2014-04-23 18:05:33 UTC (rev 167714)
@@ -4828,6 +4828,9 @@
 
 RenderRegion* RenderBlock::regionAtBlockOffset(LayoutUnit blockOffset) const
 {
+    if (isInFlowRenderFlowThread())
+        return 0;
+
     RenderFlowThread* flowThread = flowThreadContainingBlock();
     if (!flowThread || !flowThread->hasValidRegionInfo())
         return 0;

Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (167713 => 167714)


--- trunk/Source/WebCore/rendering/RenderLayer.cpp	2014-04-23 17:49:40 UTC (rev 167713)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp	2014-04-23 18:05:33 UTC (rev 167714)
@@ -4240,11 +4240,35 @@
     }
 }
 
+RenderLayer* RenderLayer::enclosingPaginationLayerInSubtree(const RenderLayer* rootLayer) const
+{
+    // If we don't have an enclosing layer, or if the root layer is the same as the enclosing layer,
+    // then just return the enclosing pagination layer (it will be 0 in the former case and the rootLayer in the latter case).
+    if (!m_enclosingPaginationLayer || rootLayer == m_enclosingPaginationLayer)
+        return m_enclosingPaginationLayer;
+    
+    // Walk up the layer tree and see which layer we hit first. If it's the root, then the enclosing pagination
+    // layer isn't in our subtree and we return 0. If we hit the enclosing pagination layer first, then
+    // we can return it.
+    for (const RenderLayer* layer = this; layer; layer = layer->parent()) {
+        if (layer == rootLayer)
+            return 0;
+        if (layer == m_enclosingPaginationLayer)
+            return m_enclosingPaginationLayer;
+    }
+    
+    // This should never be reached, since an enclosing layer should always either be the rootLayer or be
+    // our enclosing pagination layer.
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
 void RenderLayer::collectFragments(LayerFragments& fragments, const RenderLayer* rootLayer, RenderRegion* region, const LayoutRect& dirtyRect,
     ClipRectsType clipRectsType, OverlayScrollbarSizeRelevancy inOverlayScrollbarSizeRelevancy, ShouldRespectOverflowClip respectOverflowClip, const LayoutPoint* offsetFromRoot,
-    const LayoutRect* layerBoundingBox)
+    const LayoutRect* layerBoundingBox, ShouldApplyRootOffsetToFragments applyRootOffsetToFragments)
 {
-    if (!enclosingPaginationLayer() || hasTransform()) {
+    RenderLayer* paginationLayer = enclosingPaginationLayerInSubtree(rootLayer);
+    if (!paginationLayer || hasTransform()) {
         // For unpaginated layers, there is only one fragment.
         LayerFragment fragment;
         ClipRectsContext clipRectsContext(rootLayer, region, clipRectsType, inOverlayScrollbarSizeRelevancy, respectOverflowClip);
@@ -4255,11 +4279,11 @@
     
     // Compute our offset within the enclosing pagination layer.
     LayoutPoint offsetWithinPaginatedLayer;
-    convertToLayerCoords(enclosingPaginationLayer(), offsetWithinPaginatedLayer);
+    convertToLayerCoords(paginationLayer, offsetWithinPaginatedLayer);
     
     // Calculate clip rects relative to the enclosingPaginationLayer. The purpose of this call is to determine our bounds clipped to intermediate
     // layers between us and the pagination context. It's important to minimize the number of fragments we need to create and this helps with that.
-    ClipRectsContext paginationClipRectsContext(enclosingPaginationLayer(), region, clipRectsType, inOverlayScrollbarSizeRelevancy, respectOverflowClip);
+    ClipRectsContext paginationClipRectsContext(paginationLayer, region, clipRectsType, inOverlayScrollbarSizeRelevancy, respectOverflowClip);
     LayoutRect layerBoundsInFlowThread;
     ClipRect backgroundRectInFlowThread;
     ClipRect foregroundRectInFlowThread;
@@ -4268,9 +4292,68 @@
         outlineRectInFlowThread, &offsetWithinPaginatedLayer);
     
     // Take our bounding box within the flow thread and clip it.
-    LayoutRect layerBoundingBoxInFlowThread = layerBoundingBox ? *layerBoundingBox : boundingBox(enclosingPaginationLayer(), 0, &offsetWithinPaginatedLayer);
+    LayoutRect layerBoundingBoxInFlowThread = layerBoundingBox ? *layerBoundingBox : boundingBox(paginationLayer, 0, &offsetWithinPaginatedLayer);
     layerBoundingBoxInFlowThread.intersect(backgroundRectInFlowThread.rect());
+    
+    RenderFlowThread& enclosingFlowThread = toRenderFlowThread(paginationLayer->renderer());
+    RenderLayer* parentPaginationLayer = paginationLayer->parent()->enclosingPaginationLayerInSubtree(rootLayer);
+    LayerFragments ancestorFragments;
+    if (parentPaginationLayer) {
+        // Compute a bounding box accounting for fragments.
+        LayoutRect layerFragmentBoundingBoxInParentPaginationLayer = enclosingFlowThread.fragmentsBoundingBox(layerBoundingBoxInFlowThread);
+        
+        // Convert to be in the ancestor pagination context's coordinate space.
+        LayoutPoint offsetWithinParentPaginatedLayer;
+        paginationLayer->convertToLayerCoords(parentPaginationLayer, offsetWithinParentPaginatedLayer);
+        layerFragmentBoundingBoxInParentPaginationLayer.moveBy(offsetWithinParentPaginatedLayer);
+        
+        // Now collect ancestor fragments.
+        parentPaginationLayer->collectFragments(ancestorFragments, rootLayer, region, dirtyRect, clipRectsType, inOverlayScrollbarSizeRelevancy, respectOverflowClip, nullptr, &layerFragmentBoundingBoxInParentPaginationLayer, ApplyRootOffsetToFragments);
+        
+        if (ancestorFragments.isEmpty())
+            return;
+        
+        for (auto& ancestorFragment : ancestorFragments) {
+            // Shift the dirty rect into flow thread coordinates.
+            LayoutRect dirtyRectInFlowThread(dirtyRect);
+            dirtyRectInFlowThread.moveBy(-offsetWithinParentPaginatedLayer + -ancestorFragment.paginationOffset);
+            
+            size_t oldSize = fragments.size();
+            
+            // Tell the flow thread to collect the fragments. We pass enough information to create a minimal number of fragments based off the pages/columns
+            // that intersect the actual dirtyRect as well as the pages/columns that intersect our layer's bounding box.
+            enclosingFlowThread.collectLayerFragments(fragments, layerBoundingBoxInFlowThread, dirtyRectInFlowThread);
+            
+            size_t newSize = fragments.size();
+            
+            if (oldSize == newSize)
+                continue;
 
+            for (size_t i = oldSize; i < newSize; ++i) {
+                LayerFragment& fragment = fragments.at(i);
+                
+                // Set our four rects with all clipping applied that was internal to the flow thread.
+                fragment.setRects(layerBoundsInFlowThread, backgroundRectInFlowThread, foregroundRectInFlowThread, outlineRectInFlowThread, &layerBoundingBoxInFlowThread);
+                
+                // Shift to the root-relative physical position used when painting the flow thread in this fragment.
+                fragment.moveBy(ancestorFragment.paginationOffset + fragment.paginationOffset + offsetWithinParentPaginatedLayer);
+
+                // Intersect the fragment with our ancestor's background clip so that e.g., columns in an overflow:hidden block are
+                // properly clipped by the overflow.
+                fragment.intersect(ancestorFragment.paginationClip);
+                
+                // Now intersect with our pagination clip. This will typically mean we're just intersecting the dirty rect with the column
+                // clip, so the column clip ends up being all we apply.
+                fragment.intersect(fragment.paginationClip);
+                
+                if (applyRootOffsetToFragments == ApplyRootOffsetToFragments)
+                    fragment.paginationOffset = fragment.paginationOffset + offsetWithinParentPaginatedLayer;
+            }
+        }
+        
+        return;
+    }
+    
     // Shift the dirty rect into flow thread coordinates.
     LayoutPoint offsetOfPaginationLayerFromRoot;
     enclosingPaginationLayer()->convertToLayerCoords(rootLayer, offsetOfPaginationLayerFromRoot);
@@ -4279,7 +4362,6 @@
 
     // Tell the flow thread to collect the fragments. We pass enough information to create a minimal number of fragments based off the pages/columns
     // that intersect the actual dirtyRect as well as the pages/columns that intersect our layer's bounding box.
-    RenderFlowThread& enclosingFlowThread = toRenderFlowThread(enclosingPaginationLayer()->renderer());
     enclosingFlowThread.collectLayerFragments(fragments, layerBoundingBoxInFlowThread, dirtyRectInFlowThread);
     
     if (fragments.isEmpty())
@@ -4287,9 +4369,9 @@
     
     // Get the parent clip rects of the pagination layer, since we need to intersect with that when painting column contents.
     ClipRect ancestorClipRect = dirtyRect;
-    if (enclosingPaginationLayer()->parent()) {
+    if (paginationLayer->parent()) {
         ClipRectsContext clipRectsContext(rootLayer, region, clipRectsType, inOverlayScrollbarSizeRelevancy, respectOverflowClip);
-        ancestorClipRect = enclosingPaginationLayer()->backgroundClipRect(clipRectsContext);
+        ancestorClipRect = paginationLayer->backgroundClipRect(clipRectsContext);
         ancestorClipRect.intersect(dirtyRect);
     }
 
@@ -4297,7 +4379,7 @@
         LayerFragment& fragment = fragments.at(i);
         
         // Set our four rects with all clipping applied that was internal to the flow thread.
-        fragment.setRects(layerBoundsInFlowThread, backgroundRectInFlowThread, foregroundRectInFlowThread, outlineRectInFlowThread);
+        fragment.setRects(layerBoundsInFlowThread, backgroundRectInFlowThread, foregroundRectInFlowThread, outlineRectInFlowThread, &layerBoundingBoxInFlowThread);
         
         // Shift to the root-relative physical position used when painting the flow thread in this fragment.
         fragment.moveBy(fragment.paginationOffset + offsetOfPaginationLayerFromRoot);
@@ -4309,6 +4391,9 @@
         // Now intersect with our pagination clip. This will typically mean we're just intersecting the dirty rect with the column
         // clip, so the column clip ends up being all we apply.
         fragment.intersect(fragment.paginationClip);
+        
+        if (applyRootOffsetToFragments == ApplyRootOffsetToFragments)
+            fragment.paginationOffset = fragment.paginationOffset + offsetOfPaginationLayerFromRoot;
     }
 }
 
@@ -4321,7 +4406,7 @@
         fragment.shouldPaintContent = shouldPaintContent;
         if (this != localPaintingInfo.rootLayer || !(localPaintFlags & PaintLayerPaintingOverflowContents)) {
             LayoutPoint newOffsetFromRoot = *offsetFromRoot + fragment.paginationOffset;
-            fragment.shouldPaintContent &= intersectsDamageRect(fragment.layerBounds, fragment.backgroundRect.rect(), localPaintingInfo.rootLayer, &newOffsetFromRoot, localPaintingInfo.renderNamedFlowFragment);
+            fragment.shouldPaintContent &= intersectsDamageRect(fragment.layerBounds, fragment.backgroundRect.rect(), localPaintingInfo.rootLayer, &newOffsetFromRoot, localPaintingInfo.renderNamedFlowFragment, fragment.hasBoundingBox ? &fragment.boundingBox : 0);
         }
     }
 }
@@ -5650,7 +5735,7 @@
         renderer().repaintRectangle(rect);
 }
 
-bool RenderLayer::intersectsDamageRect(const LayoutRect& layerBounds, const LayoutRect& damageRect, const RenderLayer* rootLayer, const LayoutPoint* offsetFromRoot, RenderRegion* region) const
+bool RenderLayer::intersectsDamageRect(const LayoutRect& layerBounds, const LayoutRect& damageRect, const RenderLayer* rootLayer, const LayoutPoint* offsetFromRoot, RenderRegion* region, const LayoutRect* cachedBoundingBox) const
 {
     // Always examine the canvas and the root.
     // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView
@@ -5678,9 +5763,13 @@
         if (b.intersects(damageRect))
             return true;
     }
-
+    
     // Otherwise we need to compute the bounding box of this single layer and see if it intersects
-    // the damage rect.
+    // the damage rect. It's possible the fragment computed the bounding box already, in which case we
+    // can use the cached value.
+    if (cachedBoundingBox)
+        return cachedBoundingBox->intersects(damageRect);
+    
     return boundingBox(rootLayer, 0, offsetFromRoot).intersects(damageRect);
 }
 
@@ -5734,26 +5823,32 @@
         renderBox()->flipForWritingMode(result);
     else
         renderer().containingBlock()->flipForWritingMode(result);
-
-    if (enclosingPaginationLayer() && (flags & UseFragmentBoxes)) {
+    
+    const RenderLayer* paginationLayer = (flags & UseFragmentBoxes) ? enclosingPaginationLayerInSubtree(ancestorLayer) : 0;
+    const RenderLayer* childLayer = this;
+    bool isPaginated = paginationLayer;
+    
+    while (paginationLayer) {
         // Split our box up into the actual fragment boxes that render in the columns/pages and unite those together to
         // get our true bounding box.
         LayoutPoint offsetWithinPaginationLayer;
-        convertToLayerCoords(enclosingPaginationLayer(), offsetWithinPaginationLayer);        
+        childLayer->convertToLayerCoords(paginationLayer, offsetWithinPaginationLayer);
         result.moveBy(offsetWithinPaginationLayer);
 
-        RenderFlowThread& enclosingFlowThread = toRenderFlowThread(enclosingPaginationLayer()->renderer());
+        RenderFlowThread& enclosingFlowThread = toRenderFlowThread(paginationLayer->renderer());
         result = enclosingFlowThread.fragmentsBoundingBox(result);
         
+        childLayer = paginationLayer;
+        paginationLayer = paginationLayer->parent()->enclosingPaginationLayerInSubtree(ancestorLayer);
+    }
+
+    if (isPaginated) {
         LayoutPoint delta;
-        if (offsetFromRoot)
-            delta = *offsetFromRoot;
-        else
-            enclosingPaginationLayer()->convertToLayerCoords(ancestorLayer, delta);
+        childLayer->convertToLayerCoords(ancestorLayer, delta);
         result.moveBy(delta);
         return result;
     }
-
+    
     LayoutPoint delta;
     if (offsetFromRoot)
         delta = *offsetFromRoot;

Modified: trunk/Source/WebCore/rendering/RenderLayer.h (167713 => 167714)


--- trunk/Source/WebCore/rendering/RenderLayer.h	2014-04-23 17:49:40 UTC (rev 167713)
+++ trunk/Source/WebCore/rendering/RenderLayer.h	2014-04-23 18:05:33 UTC (rev 167714)
@@ -236,6 +236,11 @@
     RespectOverflowClip
 };
 
+enum ShouldApplyRootOffsetToFragments {
+    ApplyRootOffsetToFragments,
+    IgnoreRootOffsetForFragments
+};
+
 struct ClipRectsCache {
     WTF_MAKE_FAST_ALLOCATED;
 public:
@@ -273,14 +278,19 @@
 public:
     LayerFragment()
         : shouldPaintContent(false)
+        , hasBoundingBox(false)
     { }
 
-    void setRects(const LayoutRect& bounds, const ClipRect& background, const ClipRect& foreground, const ClipRect& outline)
+    void setRects(const LayoutRect& bounds, const ClipRect& background, const ClipRect& foreground, const ClipRect& outline, const LayoutRect* bbox)
     {
         layerBounds = bounds;
         backgroundRect = background;
         foregroundRect = foreground;
         outlineRect = outline;
+        if (bbox) {
+            boundingBox = *bbox;
+            hasBoundingBox = true;
+        }
     }
     
     void moveBy(const LayoutPoint& offset)
@@ -290,6 +300,7 @@
         foregroundRect.moveBy(offset);
         outlineRect.moveBy(offset);
         paginationClip.moveBy(offset);
+        boundingBox.moveBy(offset);
     }
     
     void intersect(const LayoutRect& rect)
@@ -297,13 +308,16 @@
         backgroundRect.intersect(rect);
         foregroundRect.intersect(rect);
         outlineRect.intersect(rect);
+        boundingBox.intersect(rect);
     }
     
     bool shouldPaintContent;
+    bool hasBoundingBox;
     LayoutRect layerBounds;
     ClipRect backgroundRect;
     ClipRect foregroundRect;
     ClipRect outlineRect;
+    LayoutRect boundingBox;
     
     // Unique to paginated fragments. The physical translation to apply to shift the layer when painting/hit-testing.
     LayoutPoint paginationOffset;
@@ -696,7 +710,7 @@
     LayoutRect localClipRect(bool& clipExceedsBounds) const; // Returns the background clip rect of the layer in the local coordinate space.
 
     // Pass offsetFromRoot if known.
-    bool intersectsDamageRect(const LayoutRect& layerBounds, const LayoutRect& damageRect, const RenderLayer* rootLayer, const LayoutPoint* offsetFromRoot = 0, RenderRegion* = 0) const;
+    bool intersectsDamageRect(const LayoutRect& layerBounds, const LayoutRect& damageRect, const RenderLayer* rootLayer, const LayoutPoint* offsetFromRoot = 0, RenderRegion* = 0, const LayoutRect* cachedBoundingBox = 0) const;
 
     enum CalculateLayerBoundsFlag {
         IncludeSelfTransform = 1 << 0,
@@ -933,6 +947,8 @@
 
     IntSize clampScrollOffset(const IntSize&) const;
 
+    RenderLayer* enclosingPaginationLayerInSubtree(const RenderLayer* rootLayer) const;
+
     void setNextSibling(RenderLayer* next) { m_next = next; }
     void setPreviousSibling(RenderLayer* prev) { m_previous = prev; }
     void setParent(RenderLayer* parent);
@@ -984,7 +1000,7 @@
 
     void collectFragments(LayerFragments&, const RenderLayer* rootLayer, RenderRegion*, const LayoutRect& dirtyRect,
         ClipRectsType, OverlayScrollbarSizeRelevancy inOverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize,
-        ShouldRespectOverflowClip = RespectOverflowClip, const LayoutPoint* offsetFromRoot = 0, const LayoutRect* layerBoundingBox = 0);
+        ShouldRespectOverflowClip = RespectOverflowClip, const LayoutPoint* offsetFromRoot = 0, const LayoutRect* layerBoundingBox = 0, ShouldApplyRootOffsetToFragments = IgnoreRootOffsetForFragments);
     void updatePaintingInfoForFragments(LayerFragments&, const LayerPaintingInfo&, PaintLayerFlags, bool shouldPaintContent, const LayoutPoint* offsetFromRoot);
     void paintBackgroundForFragments(const LayerFragments&, GraphicsContext*, GraphicsContext* transparencyLayerContext,
         const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer);

Modified: trunk/Source/WebCore/rendering/RenderMultiColumnFlowThread.cpp (167713 => 167714)


--- trunk/Source/WebCore/rendering/RenderMultiColumnFlowThread.cpp	2014-04-23 17:49:40 UTC (rev 167713)
+++ trunk/Source/WebCore/rendering/RenderMultiColumnFlowThread.cpp	2014-04-23 18:05:33 UTC (rev 167714)
@@ -266,7 +266,7 @@
 
 void RenderMultiColumnFlowThread::flowThreadDescendantInserted(RenderObject* descendant)
 {
-    if (m_beingEvacuated)
+    if (m_beingEvacuated || descendant->isInFlowRenderFlowThread())
         return;
     RenderObject* subtreeRoot = descendant;
     for (; descendant; descendant = descendant->nextInPreOrder(subtreeRoot)) {

Modified: trunk/Source/WebCore/rendering/RenderObject.cpp (167713 => 167714)


--- trunk/Source/WebCore/rendering/RenderObject.cpp	2014-04-23 17:49:40 UTC (rev 167713)
+++ trunk/Source/WebCore/rendering/RenderObject.cpp	2014-04-23 18:05:33 UTC (rev 167714)
@@ -1924,8 +1924,10 @@
 
     if (!isFloating() && parent()->childrenInline())
         parent()->dirtyLinesFromChangedChild(this);
-
-    if (RenderFlowThread* flowThread = parent()->flowThreadContainingBlock())
+    
+    if (parent()->isRenderFlowThread())
+        toRenderFlowThread(parent())->flowThreadDescendantInserted(this);
+    else if (RenderFlowThread* flowThread = parent()->flowThreadContainingBlock())
         flowThread->flowThreadDescendantInserted(this);
 }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to