Unreviewed, rolling out r224273 and r224278.
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 1 Nov 2017 16:28:17 +0000 (16:28 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 1 Nov 2017 16:28:17 +0000 (16:28 +0000)
https://bugs.webkit.org/show_bug.cgi?id=179120

Some crashes under guard malloc (Requested by anttik on
#webkit).

Reverted changesets:

"Remove empty continuations in
RenderObject::removeFromParentAndDestroyCleaningUpAnonymousWrappers"
https://bugs.webkit.org/show_bug.cgi?id=179014
https://trac.webkit.org/changeset/224273

"Fix ContinuationChainNode::insertAfter assertion."
https://bugs.webkit.org/show_bug.cgi?id=179115
https://trac.webkit.org/changeset/224278

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@224279 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/ruby/float-overhang-from-ruby-text-expected.txt
LayoutTests/platform/mac/fast/ruby/rubyDOM-remove-rt1-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/accessibility/AccessibilityRenderObject.cpp
Source/WebCore/rendering/RenderBlock.cpp
Source/WebCore/rendering/RenderBlock.h
Source/WebCore/rendering/RenderBoxModelObject.cpp
Source/WebCore/rendering/RenderBoxModelObject.h
Source/WebCore/rendering/RenderElement.cpp
Source/WebCore/rendering/RenderElement.h
Source/WebCore/rendering/RenderInline.cpp
Source/WebCore/rendering/RenderInline.h
Source/WebCore/rendering/RenderObject.cpp

index 1ac5a63..2021e12 100644 (file)
@@ -1,3 +1,22 @@
+2017-11-01  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r224273 and r224278.
+        https://bugs.webkit.org/show_bug.cgi?id=179120
+
+        Some crashes under guard malloc (Requested by anttik on
+        #webkit).
+
+        Reverted changesets:
+
+        "Remove empty continuations in
+        RenderObject::removeFromParentAndDestroyCleaningUpAnonymousWrappers"
+        https://bugs.webkit.org/show_bug.cgi?id=179014
+        https://trac.webkit.org/changeset/224273
+
+        "Fix ContinuationChainNode::insertAfter assertion."
+        https://bugs.webkit.org/show_bug.cgi?id=179115
+        https://trac.webkit.org/changeset/224278
+
 2017-11-01  Antti Koivisto  <antti@apple.com>
 
         Remove empty continuations in RenderObject::removeFromParentAndDestroyCleaningUpAnonymousWrappers
index 0e9a2e7..bbff5f5 100644 (file)
@@ -17,6 +17,7 @@ layer at (0,0) size 800x600
       RenderBlock {DIV} at (0,75) size 784x50
         RenderRuby (inline) {RUBY} at (0,0) size 100x50
           RenderRubyRun (anonymous) at (0,0) size 100x50
-            RenderText {#text} at (0,0) size 100x50
-              text run at (0,0) width 100: "aa"
+            RenderRubyBase (anonymous) at (0,0) size 100x50
+              RenderText {#text} at (0,0) size 100x50
+                text run at (0,0) width 100: "aa"
         RenderText {#text} at (0,0) size 0x0
index af8c365..8c9c6aa 100644 (file)
@@ -24,8 +24,9 @@ layer at (0,0) size 800x600
               RenderText {#text} at (30,0) size 47x18
                 text run at (30,0) width 47: "HTML"
           RenderRubyRun (anonymous) at (259,10) size 9x18
-            RenderText {#text} at (0,0) size 8x18
-              text run at (0,0) width 8: "5"
+            RenderRubyBase (anonymous) at (0,0) size 8x18
+              RenderText {#text} at (0,0) size 8x18
+                text run at (0,0) width 8: "5"
         RenderText {#text} at (267,10) size 38x18
           text run at (267,10) width 38: " spec."
       RenderBlock {P} at (0,164) size 784x28
index 02eaddc..6bdca30 100644 (file)
@@ -1,3 +1,22 @@
+2017-11-01  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r224273 and r224278.
+        https://bugs.webkit.org/show_bug.cgi?id=179120
+
+        Some crashes under guard malloc (Requested by anttik on
+        #webkit).
+
+        Reverted changesets:
+
+        "Remove empty continuations in
+        RenderObject::removeFromParentAndDestroyCleaningUpAnonymousWrappers"
+        https://bugs.webkit.org/show_bug.cgi?id=179014
+        https://trac.webkit.org/changeset/224273
+
+        "Fix ContinuationChainNode::insertAfter assertion."
+        https://bugs.webkit.org/show_bug.cgi?id=179115
+        https://trac.webkit.org/changeset/224278
+
 2017-11-01  Emilio Cobos Ãlvarez  <emilio@crisal.io>
 
         Fix ContinuationChainNode::insertAfter assertion.
index 6096d4b..6159ee3 100644 (file)
@@ -163,7 +163,7 @@ static inline bool isInlineWithContinuation(RenderObject& object)
 
 static inline RenderObject* firstChildInContinuation(RenderInline& renderer)
 {
-    auto* continuation = renderer.continuation();
+    auto continuation = renderer.continuation();
 
     while (continuation) {
         if (is<RenderBlock>(*continuation))
index 68635c3..47ee5d8 100644 (file)
@@ -435,10 +435,14 @@ void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldSty
         adjustFragmentedFlowStateOnContainingBlockChangeIfNeeded();
 
     auto& newStyle = style();
-    if (!isAnonymousBlock() && !isContinuation()) {
+    if (!isAnonymousBlock()) {
         // Ensure that all of our continuation blocks pick up the new style.
-        for (RenderBlock* currCont = blockElementContinuation(); currCont; currCont = currCont->blockElementContinuation())
+        for (RenderBlock* currCont = blockElementContinuation(); currCont; currCont = currCont->blockElementContinuation()) {
+            RenderBoxModelObject* nextCont = currCont->continuation();
+            currCont->setContinuation(0);
             currCont->setStyle(RenderStyle::clone(newStyle));
+            currCont->setContinuation(nextCont);
+        }
     }
 
     propagateStyleToAnonymousChildren(PropagateToBlockChildrenOnly);
@@ -814,14 +818,14 @@ static bool canMergeContiguousAnonymousBlocks(RenderObject& oldChild, RenderObje
     return true;
 }
 
-void RenderBlock::dropAnonymousBoxChild(RenderBlock& child)
+void RenderBlock::dropAnonymousBoxChild(RenderBlock& parent, RenderBlock& child)
 {
-    setNeedsLayoutAndPrefWidthsRecalc();
-    setChildrenInline(child.childrenInline());
+    parent.setNeedsLayoutAndPrefWidthsRecalc();
+    parent.setChildrenInline(child.childrenInline());
     RenderObject* nextSibling = child.nextSibling();
 
-    auto toBeDeleted = takeChildInternal(child, child.hasLayer() ? NotifyChildren : DontNotifyChildren);
-    child.moveAllChildrenTo(this, nextSibling, child.hasLayer());
+    auto toBeDeleted = parent.takeChildInternal(child, child.hasLayer() ? NotifyChildren : DontNotifyChildren);
+    child.moveAllChildrenTo(&parent, nextSibling, child.hasLayer());
     // Delete the now-empty block's lines and nuke it.
     child.deleteLines();
 }
@@ -889,7 +893,7 @@ RenderPtr<RenderObject> RenderBlock::takeChild(RenderObject& oldChild)
     if (canMergeAnonymousBlocks && child && !child->previousSibling() && !child->nextSibling() && canDropAnonymousBlockChild()) {
         // The removal has knocked us down to containing only a single anonymous
         // box. We can pull the content right back up into our box.
-        dropAnonymousBoxChild(downcast<RenderBlock>(*child));
+        dropAnonymousBoxChild(*this, downcast<RenderBlock>(*child));
     } else if (((prev && prev->isAnonymousBlock()) || (next && next->isAnonymousBlock())) && canDropAnonymousBlockChild()) {
         // It's possible that the removal has knocked us down to a single anonymous
         // block with floating siblings.
@@ -905,7 +909,7 @@ RenderPtr<RenderObject> RenderBlock::takeChild(RenderObject& oldChild)
                 }
             }
             if (dropAnonymousBlock)
-                dropAnonymousBoxChild(anonBlock);
+                dropAnonymousBoxChild(*this, anonBlock);
         }
     }
 
@@ -913,6 +917,31 @@ RenderPtr<RenderObject> RenderBlock::takeChild(RenderObject& oldChild)
         // If this was our last child be sure to clear out our line boxes.
         if (childrenInline())
             deleteLines();
+
+        // If we are an empty anonymous block in the continuation chain,
+        // we need to remove ourself and fix the continuation chain.
+        if (!beingDestroyed() && isAnonymousBlockContinuation() && !oldChild.isListMarker()) {
+            auto containingBlockIgnoringAnonymous = containingBlock();
+            while (containingBlockIgnoringAnonymous && containingBlockIgnoringAnonymous->isAnonymousBlock())
+                containingBlockIgnoringAnonymous = containingBlockIgnoringAnonymous->containingBlock();
+            for (RenderObject* current = this; current; current = current->previousInPreOrder(containingBlockIgnoringAnonymous)) {
+                if (!is<RenderBoxModelObject>(current) || downcast<RenderBoxModelObject>(*current).continuation() != this)
+                    continue;
+                // Found our previous continuation. We just need to point it to
+                // |this|'s next continuation.
+                auto* nextContinuation = continuation();
+                if (is<RenderInline>(*current))
+                    downcast<RenderInline>(*current).setContinuation(nextContinuation);
+                else if (is<RenderBlock>(*current))
+                    downcast<RenderBlock>(*current).setContinuation(nextContinuation);
+                else
+                    ASSERT_NOT_REACHED();
+                break;
+            }
+            setContinuation(nullptr);
+            // FIXME: This is dangerous.
+            removeFromParentAndDestroy();
+        }
     }
     return takenChild;
 }
index c8b3e65..881ea0c 100644 (file)
@@ -192,9 +192,12 @@ public:
     WEBCORE_EXPORT RenderInline* inlineElementContinuation() const;
     RenderBlock* blockElementContinuation() const;
 
+    using RenderBoxModelObject::continuation;
+    using RenderBoxModelObject::setContinuation;
+
     static RenderPtr<RenderBlock> createAnonymousWithParentRendererAndDisplay(const RenderBox& parent, EDisplay = BLOCK);
     RenderPtr<RenderBlock> createAnonymousBlock(EDisplay = BLOCK) const;
-    void dropAnonymousBoxChild(RenderBlock& child);
+    static void dropAnonymousBoxChild(RenderBlock& parent, RenderBlock& child);
 
     RenderPtr<RenderBox> createAnonymousBoxWithSameTypeAs(const RenderBox&) const override;
 
index c6c6bfd..cc65754 100644 (file)
@@ -77,54 +77,10 @@ using namespace HTMLNames;
 // an anonymous block (that houses other blocks) or it will be an inline flow.
 // <b><i><p>Hello</p></i></b>. In this example the <i> will have a block as
 // its continuation but the <b> will just have an inline as its continuation.
-
-struct RenderBoxModelObject::ContinuationChainNode {
-    WeakPtr<RenderBoxModelObject> renderer;
-    ContinuationChainNode* previous { nullptr };
-    ContinuationChainNode* next { nullptr };
-
-    ContinuationChainNode(RenderBoxModelObject&);
-    ~ContinuationChainNode();
-
-    void insertAfter(ContinuationChainNode&);
-
-    WTF_MAKE_FAST_ALLOCATED;
-};
-
-RenderBoxModelObject::ContinuationChainNode::ContinuationChainNode(RenderBoxModelObject& renderer)
-    : renderer(makeWeakPtr(renderer))
-{
-}
-
-RenderBoxModelObject::ContinuationChainNode::~ContinuationChainNode()
+typedef HashMap<const RenderBoxModelObject*, WeakPtr<RenderBoxModelObject>> ContinuationMap;
+static ContinuationMap& continuationMap()
 {
-    if (next) {
-        ASSERT(previous);
-        ASSERT(next->previous == this);
-        next->previous = previous;
-    }
-    if (previous) {
-        ASSERT(previous->next == this);
-        previous->next = next;
-    }
-}
-
-void RenderBoxModelObject::ContinuationChainNode::insertAfter(ContinuationChainNode& after)
-{
-    ASSERT(!previous);
-    ASSERT(!next);
-    if ((next = after.next)) {
-        ASSERT(next->previous == &after);
-        next->previous = this;
-    }
-    previous = &after;
-    after.next = this;
-}
-
-typedef HashMap<const RenderBoxModelObject*, std::unique_ptr<RenderBoxModelObject::ContinuationChainNode>> ContinuationChainNodeMap;
-static ContinuationChainNodeMap& continuationChainNodeMap()
-{
-    static NeverDestroyed<ContinuationChainNodeMap> map;
+    static NeverDestroyed<ContinuationMap> map;
     return map;
 }
 
@@ -231,12 +187,10 @@ RenderBoxModelObject::~RenderBoxModelObject()
 
 void RenderBoxModelObject::willBeDestroyed()
 {
-    if (continuation() && !isContinuation()) {
-        removeAndDestroyAllContinuations();
-        ASSERT(!continuation());
+    if (hasContinuation()) {
+        continuation()->removeFromParentAndDestroy();
+        setContinuation(nullptr);
     }
-    if (hasContinuationChainNode())
-        removeFromContinuationChain();
 
     // If this is a first-letter object with a remaining text fragment then the
     // entry needs to be cleared from the map.
@@ -2493,49 +2447,19 @@ LayoutUnit RenderBoxModelObject::containingBlockLogicalWidthForContent() const
 
 RenderBoxModelObject* RenderBoxModelObject::continuation() const
 {
-    if (!hasContinuationChainNode())
-        return nullptr;
-
-    auto& continuationChainNode = *continuationChainNodeMap().get(this);
-    if (!continuationChainNode.next)
+    if (!hasContinuation())
         return nullptr;
-    return continuationChainNode.next->renderer.get();
-}
-
-void RenderBoxModelObject::insertIntoContinuationChainAfter(RenderBoxModelObject& afterRenderer)
-{
-    ASSERT(isContinuation());
-    ASSERT(!continuationChainNodeMap().contains(this));
-
-    auto& after = afterRenderer.ensureContinuationChainNode();
-    ensureContinuationChainNode().insertAfter(after);
-}
-
-void RenderBoxModelObject::removeFromContinuationChain()
-{
-    ASSERT(hasContinuationChainNode());
-    ASSERT(continuationChainNodeMap().contains(this));
-    setHasContinuationChainNode(false);
-    continuationChainNodeMap().remove(this);
-}
-
-auto RenderBoxModelObject::ensureContinuationChainNode() -> ContinuationChainNode&
-{
-    setHasContinuationChainNode(true);
-    return *continuationChainNodeMap().ensure(this, [&] {
-        return std::make_unique<ContinuationChainNode>(*this);
-    }).iterator->value;
+    return continuationMap().get(this).get();
 }
 
-void RenderBoxModelObject::removeAndDestroyAllContinuations()
+void RenderBoxModelObject::setContinuation(RenderBoxModelObject* continuation)
 {
-    ASSERT(!isContinuation());
-    ASSERT(hasContinuationChainNode());
-    ASSERT(continuationChainNodeMap().contains(this));
-    auto& continuationChainNode = *continuationChainNodeMap().get(this);
-    while (continuationChainNode.next)
-        continuationChainNode.next->renderer->removeFromParentAndDestroy();
-    removeFromContinuationChain();
+    ASSERT(!continuation || continuation->isContinuation());
+    if (continuation)
+        continuationMap().set(this, makeWeakPtr(continuation));
+    else if (hasContinuation())
+        continuationMap().remove(this);
+    setHasContinuation(!!continuation);
 }
 
 RenderTextFragment* RenderBoxModelObject::firstLetterRemainingText() const
index 1b044cc..ff07211 100644 (file)
@@ -235,9 +235,6 @@ public:
     void suspendAnimations(double time = 0);
 
     RenderBoxModelObject* continuation() const;
-    
-    void insertIntoContinuationChainAfter(RenderBoxModelObject&);
-    void removeFromContinuationChain();
 
     virtual LayoutRect paintRectToClipOutFromBorder(const LayoutRect&) { return LayoutRect(); };
     
@@ -259,6 +256,8 @@ protected:
 
     InterpolationQuality chooseInterpolationQuality(GraphicsContext&, Image&, const void*, const LayoutSize&);
 
+    void setContinuation(RenderBoxModelObject*);
+
     LayoutRect localCaretRectForEmptyElement(LayoutUnit width, LayoutUnit textIndentOffset);
 
     static bool shouldAntialiasLines(GraphicsContext&);
@@ -302,12 +301,7 @@ public:
 
     RenderBlock* containingBlockForAutoHeightDetection(Length logicalHeight) const;
 
-    struct ContinuationChainNode;
-
 private:
-    ContinuationChainNode& ensureContinuationChainNode();
-    void removeAndDestroyAllContinuations();
-
     LayoutUnit computedCSSPadding(const Length&) const;
     
     virtual LayoutRect frameRectForStickyPositioning() const = 0;
index 83b4c96..dd9cc1b 100644 (file)
@@ -101,7 +101,7 @@ inline RenderElement::RenderElement(ContainerNode& elementOrDocument, RenderStyl
     , m_renderBoxNeedsLazyRepaint(false)
     , m_hasPausedImageAnimations(false)
     , m_hasCounterNodeMap(false)
-    , m_hasContinuationChainNode(false)
+    , m_hasContinuation(false)
     , m_isContinuation(false)
     , m_hasValidCachedFirstLineStyle(false)
     , m_renderBlockHasMarginBeforeQuirk(false)
@@ -961,11 +961,8 @@ void RenderElement::handleDynamicFloatPositionChange()
 
 void RenderElement::removeAnonymousWrappersForInlinesIfNecessary()
 {
-    // FIXME: Move to RenderBlock.
-    if (!is<RenderBlock>(*this))
-        return;
-    RenderBlock& thisBlock = downcast<RenderBlock>(*this);
-    if (!thisBlock.canDropAnonymousBlockChild())
+    RenderBlock& parentBlock = downcast<RenderBlock>(*parent());
+    if (!parentBlock.canDropAnonymousBlockChild())
         return;
 
     // We have changed to floated or out-of-flow positioning so maybe all our parent's
@@ -973,18 +970,18 @@ void RenderElement::removeAnonymousWrappersForInlinesIfNecessary()
     // otherwise we can proceed to stripping solitary anonymous wrappers from the inlines.
     // FIXME: We should also handle split inlines here - we exclude them at the moment by returning
     // if we find a continuation.
-    RenderObject* current = firstChild();
-    while (current && ((current->isAnonymousBlock() && !downcast<RenderBlock>(*current).isContinuation()) || current->style().isFloating() || current->style().hasOutOfFlowPosition()))
+    RenderObject* current = parent()->firstChild();
+    while (current && ((current->isAnonymousBlock() && !downcast<RenderBlock>(*current).isAnonymousBlockContinuation()) || current->style().isFloating() || current->style().hasOutOfFlowPosition()))
         current = current->nextSibling();
 
     if (current)
         return;
 
     RenderObject* next;
-    for (current = firstChild(); current; current = next) {
+    for (current = parent()->firstChild(); current; current = next) {
         next = current->nextSibling();
         if (current->isAnonymousBlock())
-            thisBlock.dropAnonymousBoxChild(downcast<RenderBlock>(*current));
+            parentBlock.dropAnonymousBoxChild(parentBlock, downcast<RenderBlock>(*current));
     }
 }
 
@@ -1013,7 +1010,7 @@ void RenderElement::styleDidChange(StyleDifference diff, const RenderStyle* oldS
         handleDynamicFloatPositionChange();
 
     if (s_noLongerAffectsParentBlock)
-        parent()->removeAnonymousWrappersForInlinesIfNecessary();
+        removeAnonymousWrappersForInlinesIfNecessary();
 
     SVGRenderSupport::styleChanged(*this, oldStyle);
 
@@ -2155,10 +2152,8 @@ void RenderElement::updateOutlineAutoAncestor(bool hasOutlineAuto)
             continue;
         downcast<RenderElement>(child).updateOutlineAutoAncestor(hasOutlineAuto);
     }
-    if (is<RenderBoxModelObject>(*this)) {
-        if (auto* continuation = downcast<RenderBoxModelObject>(*this).continuation())
-            continuation->updateOutlineAutoAncestor(hasOutlineAuto);
-    }
+    if (hasContinuation())
+        downcast<RenderBoxModelObject>(*this).continuation()->updateOutlineAutoAncestor(hasOutlineAuto);
 }
 
 bool RenderElement::hasOutlineAnnotation() const
index b92e70d..fea0eb3 100644 (file)
@@ -221,9 +221,7 @@ public:
     // the child.
     virtual void updateAnonymousChildStyle(const RenderObject&, RenderStyle&) const { };
 
-    void removeAnonymousWrappersForInlinesIfNecessary();
-
-    bool hasContinuationChainNode() const { return m_hasContinuationChainNode; }
+    bool hasContinuation() const { return m_hasContinuation; }
     bool isContinuation() const { return m_isContinuation; }
     void setIsContinuation() { m_isContinuation = true; }
     bool isElementContinuation() const { return isContinuation() && !isAnonymous(); }
@@ -266,7 +264,7 @@ protected:
     void setRenderInlineAlwaysCreatesLineBoxes(bool b) { m_renderInlineAlwaysCreatesLineBoxes = b; }
     bool renderInlineAlwaysCreatesLineBoxes() const { return m_renderInlineAlwaysCreatesLineBoxes; }
 
-    void setHasContinuationChainNode(bool b) { m_hasContinuationChainNode = b; }
+    void setHasContinuation(bool b) { m_hasContinuation = b; }
 
     void setRenderBlockHasMarginBeforeQuirk(bool b) { m_renderBlockHasMarginBeforeQuirk = b; }
     void setRenderBlockHasMarginAfterQuirk(bool b) { m_renderBlockHasMarginAfterQuirk = b; }
@@ -305,6 +303,7 @@ private:
     // again.  We have to make sure the render tree updates as needed to accommodate the new
     // normal flow object.
     void handleDynamicFloatPositionChange();
+    void removeAnonymousWrappersForInlinesIfNecessary();
 
     bool shouldRepaintForStyleDifference(StyleDifference) const;
     bool hasImmediateNonWhitespaceTextChildOrBorderOrOutline() const;
@@ -337,7 +336,7 @@ private:
     unsigned m_renderBoxNeedsLazyRepaint : 1;
     unsigned m_hasPausedImageAnimations : 1;
     unsigned m_hasCounterNodeMap : 1;
-    unsigned m_hasContinuationChainNode : 1;
+    unsigned m_hasContinuation : 1;
     unsigned m_isContinuation : 1;
     mutable unsigned m_hasValidCachedFirstLineStyle : 1;
 
index f5c444d..82039c6 100644 (file)
@@ -189,9 +189,13 @@ void RenderInline::styleDidChange(StyleDifference diff, const RenderStyle* oldSt
     // need to pass its style on to anyone else.
     auto& newStyle = style();
     RenderInline* continuation = inlineElementContinuation();
-    if (continuation && !isContinuation()) {
-        for (RenderInline* currCont = continuation; currCont; currCont = currCont->inlineElementContinuation())
+    if (continuation) {
+        for (RenderInline* currCont = continuation; currCont; currCont = currCont->inlineElementContinuation()) {
+            RenderBoxModelObject* nextCont = currCont->continuation();
+            currCont->setContinuation(nullptr);
             currCont->setStyle(RenderStyle::clone(newStyle));
+            currCont->setContinuation(nextCont);
+        }
         // If an inline's in-flow positioning has changed and it is part of an active continuation as a descendant of an anonymous containing block,
         // then any descendant blocks will need to change their in-flow positioning accordingly.
         // Do this by updating the position of the descendant blocks' containing anonymous blocks - there may be more than one.
@@ -340,9 +344,7 @@ void RenderInline::addChildIgnoringContinuation(RenderPtr<RenderObject> newChild
         newBox->initializeStyle();
         newBox->setIsContinuation();
         RenderBoxModelObject* oldContinuation = continuation();
-        if (oldContinuation)
-            oldContinuation->removeFromContinuationChain();
-        newBox->insertIntoContinuationChainAfter(*this);
+        setContinuation(newBox.get());
 
         splitFlow(beforeChild, WTFMove(newBox), WTFMove(newChild), oldContinuation);
         return;
@@ -415,10 +417,9 @@ void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
         rendererToMove->setNeedsLayoutAndPrefWidthsRecalc();
         rendererToMove = nextSibling;
     }
+    cloneInline->setContinuation(oldCont);
     // Hook |clone| up as the continuation of the middle block.
-    cloneInline->insertIntoContinuationChainAfter(*middleBlock);
-    if (oldCont)
-        oldCont->insertIntoContinuationChainAfter(*cloneInline);
+    middleBlock->setContinuation(cloneInline.get());
 
     // We have been reparented and are now under the fromBlock.  We need
     // to walk up our inline parent chain until we hit the containing block.
@@ -442,16 +443,19 @@ void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
             cloneInline->addChildIgnoringContinuation(WTFMove(cloneChild));
 
             // Hook the clone up as a continuation of |curr|.
-            cloneInline->insertIntoContinuationChainAfter(*current);
+            RenderInline& currentInline = downcast<RenderInline>(*current);
+            oldCont = currentInline.continuation();
+            currentInline.setContinuation(cloneInline.get());
+            cloneInline->setContinuation(oldCont);
 
             // Now we need to take all of the children starting from the first child
             // *after* currentChild and append them all to the clone.
-            for (auto* sibling = currentChild->nextSibling(); sibling;) {
-                auto* next = sibling->nextSibling();
-                auto childToMove = current->takeChildInternal(*sibling, NotifyChildren);
+            for (auto* current = currentChild->nextSibling(); current;) {
+                auto* next = current->nextSibling();
+                auto childToMove = currentInline.takeChildInternal(*current, NotifyChildren);
                 cloneInline->addChildIgnoringContinuation(WTFMove(childToMove));
-                sibling->setNeedsLayoutAndPrefWidthsRecalc();
-                sibling = next;
+                current->setNeedsLayoutAndPrefWidthsRecalc();
+                current = next;
             }
         }
         
@@ -572,7 +576,7 @@ void RenderInline::addChildToContinuation(RenderPtr<RenderObject> newChild, Rend
         auto* parent = beforeChild->parent();
         while (parent && parent->parent() && parent->parent()->isAnonymous()) {
             // The ancestor candidate needs to be inside the continuation.
-            if (parent->isContinuation())
+            if (parent->hasContinuation())
                 break;
             parent = parent->parent();
         }
@@ -1375,9 +1379,7 @@ void RenderInline::childBecameNonInline(RenderElement& child)
     auto newBox = containingBlock()->createAnonymousBlock();
     newBox->setIsContinuation();
     RenderBoxModelObject* oldContinuation = continuation();
-    if (oldContinuation)
-        oldContinuation->removeFromContinuationChain();
-    newBox->insertIntoContinuationChainAfter(*this);
+    setContinuation(newBox.get());
     RenderObject* beforeChild = child.nextSibling();
     auto removedChild = takeChildInternal(child, NotifyChildren);
     splitFlow(beforeChild, WTFMove(newBox), WTFMove(removedChild), oldContinuation);
index 7090f95..5137aa5 100644 (file)
@@ -87,6 +87,9 @@ public:
     void addFocusRingRects(Vector<LayoutRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) final;
     void paintOutline(PaintInfo&, const LayoutPoint&);
 
+    using RenderBoxModelObject::continuation;
+    using RenderBoxModelObject::setContinuation;
+
     bool alwaysCreateLineBoxes() const { return renderInlineAlwaysCreatesLineBoxes(); }
     void setAlwaysCreateLineBoxes() { setRenderInlineAlwaysCreatesLineBoxes(true); }
     void updateAlwaysCreateLineBoxes(bool fullLayout);
index 2a1ca4a..a63a0bf 100644 (file)
@@ -824,7 +824,7 @@ void RenderObject::propagateRepaintToParentWithOutlineAutoIfNeeded(const RenderL
         bool rendererHasOutlineAutoAncestor = renderer->hasOutlineAutoAncestor();
         ASSERT(rendererHasOutlineAutoAncestor
             || renderer->outlineStyleForRepaint().outlineStyleIsAuto()
-            || (is<RenderBoxModelObject>(*renderer) && downcast<RenderBoxModelObject>(*renderer).isContinuation()));
+            || (is<RenderElement>(*renderer) && downcast<RenderElement>(*renderer).hasContinuation()));
         if (renderer == &repaintContainer && rendererHasOutlineAutoAncestor)
             repaintRectNeedsConverting = true;
         if (rendererHasOutlineAutoAncestor)
@@ -1175,7 +1175,7 @@ void RenderObject::outputRenderObject(TextStream& stream, bool mark, int depth)
     }
     if (is<RenderBoxModelObject>(*this)) {
         auto& renderer = downcast<RenderBoxModelObject>(*this);
-        if (renderer.continuation())
+        if (renderer.hasContinuation())
             stream << " continuation->(" << renderer.continuation() << ")";
     }
     outputRegionsInformation(stream);
@@ -1466,6 +1466,9 @@ static RenderObject& findDestroyRootIncludingAnonymous(RenderObject& renderer)
             break;
         if (destroyRootParent->isRenderFragmentedFlow())
             break;
+        // FIXME: Destroy continuations here too.
+        if (destroyRootParent->isContinuation())
+            break;
         bool destroyingOnlyChild = destroyRootParent->firstChild() == destroyRoot && destroyRootParent->lastChild() == destroyRoot;
         if (!destroyingOnlyChild)
             break;
@@ -1487,9 +1490,7 @@ void RenderObject::removeFromParentAndDestroyCleaningUpAnonymousWrappers()
     if (is<RenderTableRow>(destroyRoot))
         downcast<RenderTableRow>(destroyRoot).collapseAndDestroyAnonymousSiblingRows();
 
-    auto& destroyRootParent = *destroyRoot.parent();
-    destroyRootParent.removeAndDestroyChild(destroyRoot);
-    destroyRootParent.removeAnonymousWrappersForInlinesIfNecessary();
+    destroyRoot.removeFromParentAndDestroy();
     // WARNING: |this| is deleted here.
 }