Use smart pointers for creating, adding and removing renderers
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 30 Sep 2017 06:45:59 +0000 (06:45 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 30 Sep 2017 06:45:59 +0000 (06:45 +0000)
https://bugs.webkit.org/show_bug.cgi?id=177603

Reviewed by Zalan Bujtas.

With this patch RenderObject ownership is consistently managed using RenderPtrs. It also
clarifies that in-tree renderers are always owned by the parent renderer.

- renderers are constructed with createRenderer<> which returns RenderPtr
- addChild and related functions take RenderPtrs
- removeChild is replaced with takeChild that returns a RenderPtr
- only addChildInternal/takeChildInternal deal with raw ownder renderer pointers.

There are still a few exception left, noted below, to be fixed later.

* dom/Document.cpp:
(WebCore::Document::webkitWillEnterFullScreenForElement):
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::addChildToContinuation):
(WebCore::RenderBlock::addChild):
(WebCore::RenderBlock::addChildIgnoringContinuation):
(WebCore::RenderBlock::makeChildrenNonInline):
(WebCore::RenderBlock::dropAnonymousBoxChild):
(WebCore::RenderBlock::takeChild):
(WebCore::RenderBlock::createAnonymousBlockWithStyleAndDisplay):
(WebCore::RenderBlock::removeChild): Deleted.
* rendering/RenderBlock.h:
(WebCore::RenderBlock::createAnonymousWithParentRendererAndDisplay):
(WebCore::RenderBlock::createAnonymousBoxWithSameTypeAs const):
(WebCore::RenderBlock::createAnonymousBlock const):
* rendering/RenderBlockFlow.cpp:
(WebCore::RenderBlockFlow::addChild):
(WebCore::RenderBlockFlow::takeChild):
(WebCore::RenderBlockFlow::removeChild): Deleted.
* rendering/RenderBlockFlow.h:
* rendering/RenderBox.cpp:
(WebCore::RenderBox::splitAnonymousBoxesAroundChild):
* rendering/RenderBox.h:
(WebCore::RenderBox::createAnonymousBoxWithSameTypeAs const):
* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::moveChildTo):
* rendering/RenderButton.cpp:
(WebCore::RenderButton::addChild):
(WebCore::RenderButton::takeChild):
(WebCore::RenderButton::setText):
(WebCore::RenderButton::removeChild): Deleted.
* rendering/RenderButton.h:
* rendering/RenderElement.cpp:
(WebCore::RenderElement::addChild):
(WebCore::RenderElement::takeChild):
(WebCore::RenderElement::removeAndDestroyChild):
(WebCore::RenderElement::destroyLeftoverChildren):

    Keep the existing behavior and leak the firstLetter renderer. The comment claims they get destroyed by RenderTextFragment.
    To be cleaned up later.

(WebCore::RenderElement::insertChildInternal):
(WebCore::RenderElement::takeChildInternal):
(WebCore::RenderElement::handleDynamicFloatPositionChange):
(WebCore::RenderElement::removeChild): Deleted.
(WebCore::RenderElement::removeChildInternal): Deleted.
* rendering/RenderElement.h:
(WebCore::RenderElement::addChildIgnoringContinuation):
* rendering/RenderFullScreen.cpp:
(WebCore::RenderFullScreen::willBeDestroyed):
(WebCore::RenderFullScreen::wrapNewRenderer):
(WebCore::RenderFullScreen::wrapExistingRenderer):

    Split wrapRenderer() into two functions, wrapNewRenderer() and wrapExistingRenderer().
    The first one deals with adding new renderers to the tree while the latter mutates
    existing render tree in-place.

(WebCore::RenderFullScreen::unwrapRenderer):
(WebCore::RenderFullScreen::createPlaceholder):
(WebCore::RenderFullScreen::wrapRenderer): Deleted.
* rendering/RenderFullScreen.h:
* rendering/RenderGrid.cpp:
(WebCore::RenderGrid::addChild):
(WebCore::RenderGrid::takeChild):
(WebCore::RenderGrid::removeChild): Deleted.
* rendering/RenderGrid.h:
* rendering/RenderInline.cpp:
(WebCore::RenderInline::addChild):
(WebCore::RenderInline::addChildIgnoringContinuation):
(WebCore::RenderInline::splitInlines):
(WebCore::RenderInline::splitFlow):
(WebCore::RenderInline::addChildToContinuation):
(WebCore::RenderInline::childBecameNonInline):
* rendering/RenderInline.h:
* rendering/RenderMenuList.cpp:
(WebCore::RenderMenuList::createInnerBlock):
(RenderMenuList::addChild):
(RenderMenuList::takeChild):
(RenderMenuList::setText):
(RenderMenuList::removeChild): Deleted.
* rendering/RenderMenuList.h:
* rendering/RenderMultiColumnFlow.cpp:
(WebCore::RenderMultiColumnFlow::evacuateAndDestroy):
(WebCore::RenderMultiColumnFlow::processPossibleSpannerDescendant):
(WebCore::RenderMultiColumnFlow::fragmentedFlowDescendantInserted):

    Keep the existing behavior and leak the placeholder renderer.
    To be cleaned up later.

(WebCore::RenderMultiColumnFlow::handleSpannerRemoval):

    Keep the existing behavior and leak the placeholder renderer.
    To be cleaned up later.

* rendering/RenderMultiColumnSpannerPlaceholder.cpp:
(WebCore::RenderMultiColumnSpannerPlaceholder::createAnonymous):
* rendering/RenderMultiColumnSpannerPlaceholder.h:
* rendering/RenderObject.cpp:
(WebCore::RenderObject::removeFromParentAndDestroy):
(WebCore::RenderObject::willBeDestroyed):
(WebCore::RenderObject::destroy):
(WebCore::RenderObject::removeFromParent): Deleted.
* rendering/RenderObject.h:
* rendering/RenderQuote.cpp:
(WebCore::RenderQuote::updateTextRenderer):
* rendering/RenderRuby.cpp:
(WebCore::createAnonymousRubyInlineBlock):
(WebCore::RenderRubyAsInline::addChild):
(WebCore::RenderRubyAsInline::takeChild):
(WebCore::RenderRubyAsBlock::addChild):
(WebCore::RenderRubyAsBlock::takeChild):
(WebCore::RenderRubyAsInline::removeChild): Deleted.
(WebCore::RenderRubyAsBlock::removeChild): Deleted.
* rendering/RenderRuby.h:
* rendering/RenderRubyBase.cpp:
(WebCore::RenderRubyBase::moveInlineChildren):
* rendering/RenderRubyRun.cpp:
(WebCore::RenderRubyRun::rubyBaseSafe):
(WebCore::RenderRubyRun::addChild):
(WebCore::RenderRubyRun::takeChild):
(WebCore::RenderRubyRun::createRubyBase const):
(WebCore::RenderRubyRun::staticCreateRubyRun):
(WebCore::RenderRubyRun::removeChild): Deleted.
* rendering/RenderRubyRun.h:
* rendering/RenderTable.cpp:
(WebCore::RenderTable::addChild):
(WebCore::RenderTable::createTableWithStyle):
(WebCore::RenderTable::createAnonymousWithParentRenderer):
* rendering/RenderTable.h:
(WebCore::RenderTable::createAnonymousBoxWithSameTypeAs const):
* rendering/RenderTableCell.cpp:
(WebCore::RenderTableCell::createTableCellWithStyle):
(WebCore::RenderTableCell::createAnonymousWithParentRenderer):
* rendering/RenderTableCell.h:
(WebCore::RenderTableCell::createAnonymousBoxWithSameTypeAs const):
* rendering/RenderTableRow.cpp:
(WebCore::RenderTableRow::addChild):
(WebCore::RenderTableRow::createTableRowWithStyle):
(WebCore::RenderTableRow::createAnonymousWithParentRenderer):
* rendering/RenderTableRow.h:
(WebCore::RenderTableRow::createAnonymousBoxWithSameTypeAs const):
* rendering/RenderTableSection.cpp:
(WebCore::RenderTableSection::addChild):
(WebCore::RenderTableSection::createTableSectionWithStyle):
(WebCore::RenderTableSection::createAnonymousWithParentRenderer):
* rendering/RenderTableSection.h:
(WebCore::RenderTableSection::createAnonymousBoxWithSameTypeAs const):
* rendering/mathml/RenderMathMLFenced.cpp:
(WebCore::RenderMathMLFenced::makeFences):
(WebCore::RenderMathMLFenced::addChild):
* rendering/mathml/RenderMathMLFenced.h:
* rendering/svg/RenderSVGContainer.cpp:
(WebCore::RenderSVGContainer::addChild):
(WebCore::RenderSVGContainer::takeChild):
(WebCore::RenderSVGContainer::removeChild): Deleted.
* rendering/svg/RenderSVGContainer.h:
* rendering/svg/RenderSVGInline.cpp:
(WebCore::RenderSVGInline::addChild):
(WebCore::RenderSVGInline::takeChild):
(WebCore::RenderSVGInline::removeChild): Deleted.
* rendering/svg/RenderSVGInline.h:
* rendering/svg/RenderSVGRoot.cpp:
(WebCore::RenderSVGRoot::addChild):
(WebCore::RenderSVGRoot::takeChild):
(WebCore::RenderSVGRoot::removeChild): Deleted.
* rendering/svg/RenderSVGRoot.h:
* rendering/svg/RenderSVGText.cpp:
(WebCore::RenderSVGText::addChild):
(WebCore::RenderSVGText::takeChild):
(WebCore::RenderSVGText::removeChild): Deleted.
* rendering/svg/RenderSVGText.h:
* style/RenderTreePosition.h:
(WebCore::RenderTreePosition::insert):
* style/RenderTreeUpdater.cpp:
(WebCore::RenderTreeUpdater::createRenderer):
(WebCore::createTextRenderer):
* style/RenderTreeUpdaterFirstLetter.cpp:
(WebCore::updateFirstLetterStyle):
(WebCore::createFirstLetterRenderer):
* style/RenderTreeUpdaterGeneratedContent.cpp:
(WebCore::createContentRenderers):
* style/RenderTreeUpdaterListItem.cpp:
(WebCore::RenderTreeUpdater::ListItem::updateMarker):
* style/RenderTreeUpdaterMultiColumn.cpp:
(WebCore::RenderTreeUpdater::MultiColumn::createFragmentedFlow):

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

56 files changed:
Source/WebCore/ChangeLog
Source/WebCore/dom/Document.cpp
Source/WebCore/rendering/RenderBlock.cpp
Source/WebCore/rendering/RenderBlock.h
Source/WebCore/rendering/RenderBlockFlow.cpp
Source/WebCore/rendering/RenderBlockFlow.h
Source/WebCore/rendering/RenderBox.cpp
Source/WebCore/rendering/RenderBox.h
Source/WebCore/rendering/RenderBoxModelObject.cpp
Source/WebCore/rendering/RenderButton.cpp
Source/WebCore/rendering/RenderButton.h
Source/WebCore/rendering/RenderElement.cpp
Source/WebCore/rendering/RenderElement.h
Source/WebCore/rendering/RenderFullScreen.cpp
Source/WebCore/rendering/RenderFullScreen.h
Source/WebCore/rendering/RenderGrid.cpp
Source/WebCore/rendering/RenderGrid.h
Source/WebCore/rendering/RenderInline.cpp
Source/WebCore/rendering/RenderInline.h
Source/WebCore/rendering/RenderMenuList.cpp
Source/WebCore/rendering/RenderMenuList.h
Source/WebCore/rendering/RenderMultiColumnFlow.cpp
Source/WebCore/rendering/RenderMultiColumnSpannerPlaceholder.cpp
Source/WebCore/rendering/RenderMultiColumnSpannerPlaceholder.h
Source/WebCore/rendering/RenderObject.cpp
Source/WebCore/rendering/RenderObject.h
Source/WebCore/rendering/RenderQuote.cpp
Source/WebCore/rendering/RenderRuby.cpp
Source/WebCore/rendering/RenderRuby.h
Source/WebCore/rendering/RenderRubyBase.cpp
Source/WebCore/rendering/RenderRubyRun.cpp
Source/WebCore/rendering/RenderRubyRun.h
Source/WebCore/rendering/RenderTable.cpp
Source/WebCore/rendering/RenderTable.h
Source/WebCore/rendering/RenderTableCell.cpp
Source/WebCore/rendering/RenderTableCell.h
Source/WebCore/rendering/RenderTableRow.cpp
Source/WebCore/rendering/RenderTableRow.h
Source/WebCore/rendering/RenderTableSection.cpp
Source/WebCore/rendering/RenderTableSection.h
Source/WebCore/rendering/mathml/RenderMathMLFenced.cpp
Source/WebCore/rendering/mathml/RenderMathMLFenced.h
Source/WebCore/rendering/svg/RenderSVGContainer.cpp
Source/WebCore/rendering/svg/RenderSVGContainer.h
Source/WebCore/rendering/svg/RenderSVGInline.cpp
Source/WebCore/rendering/svg/RenderSVGInline.h
Source/WebCore/rendering/svg/RenderSVGRoot.cpp
Source/WebCore/rendering/svg/RenderSVGRoot.h
Source/WebCore/rendering/svg/RenderSVGText.cpp
Source/WebCore/rendering/svg/RenderSVGText.h
Source/WebCore/style/RenderTreePosition.h
Source/WebCore/style/RenderTreeUpdater.cpp
Source/WebCore/style/RenderTreeUpdaterFirstLetter.cpp
Source/WebCore/style/RenderTreeUpdaterGeneratedContent.cpp
Source/WebCore/style/RenderTreeUpdaterListItem.cpp
Source/WebCore/style/RenderTreeUpdaterMultiColumn.cpp

index 1be1834..bbe3228 100644 (file)
@@ -1,3 +1,206 @@
+2017-09-29  Antti Koivisto  <antti@apple.com>
+
+        Use smart pointers for creating, adding and removing renderers
+        https://bugs.webkit.org/show_bug.cgi?id=177603
+
+        Reviewed by Zalan Bujtas.
+
+        With this patch RenderObject ownership is consistently managed using RenderPtrs. It also
+        clarifies that in-tree renderers are always owned by the parent renderer.
+
+        - renderers are constructed with createRenderer<> which returns RenderPtr
+        - addChild and related functions take RenderPtrs
+        - removeChild is replaced with takeChild that returns a RenderPtr
+        - only addChildInternal/takeChildInternal deal with raw ownder renderer pointers.
+
+        There are still a few exception left, noted below, to be fixed later.
+
+        * dom/Document.cpp:
+        (WebCore::Document::webkitWillEnterFullScreenForElement):
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::addChildToContinuation):
+        (WebCore::RenderBlock::addChild):
+        (WebCore::RenderBlock::addChildIgnoringContinuation):
+        (WebCore::RenderBlock::makeChildrenNonInline):
+        (WebCore::RenderBlock::dropAnonymousBoxChild):
+        (WebCore::RenderBlock::takeChild):
+        (WebCore::RenderBlock::createAnonymousBlockWithStyleAndDisplay):
+        (WebCore::RenderBlock::removeChild): Deleted.
+        * rendering/RenderBlock.h:
+        (WebCore::RenderBlock::createAnonymousWithParentRendererAndDisplay):
+        (WebCore::RenderBlock::createAnonymousBoxWithSameTypeAs const):
+        (WebCore::RenderBlock::createAnonymousBlock const):
+        * rendering/RenderBlockFlow.cpp:
+        (WebCore::RenderBlockFlow::addChild):
+        (WebCore::RenderBlockFlow::takeChild):
+        (WebCore::RenderBlockFlow::removeChild): Deleted.
+        * rendering/RenderBlockFlow.h:
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::splitAnonymousBoxesAroundChild):
+        * rendering/RenderBox.h:
+        (WebCore::RenderBox::createAnonymousBoxWithSameTypeAs const):
+        * rendering/RenderBoxModelObject.cpp:
+        (WebCore::RenderBoxModelObject::moveChildTo):
+        * rendering/RenderButton.cpp:
+        (WebCore::RenderButton::addChild):
+        (WebCore::RenderButton::takeChild):
+        (WebCore::RenderButton::setText):
+        (WebCore::RenderButton::removeChild): Deleted.
+        * rendering/RenderButton.h:
+        * rendering/RenderElement.cpp:
+        (WebCore::RenderElement::addChild):
+        (WebCore::RenderElement::takeChild):
+        (WebCore::RenderElement::removeAndDestroyChild):
+        (WebCore::RenderElement::destroyLeftoverChildren):
+
+            Keep the existing behavior and leak the firstLetter renderer. The comment claims they get destroyed by RenderTextFragment.
+            To be cleaned up later.
+
+        (WebCore::RenderElement::insertChildInternal):
+        (WebCore::RenderElement::takeChildInternal):
+        (WebCore::RenderElement::handleDynamicFloatPositionChange):
+        (WebCore::RenderElement::removeChild): Deleted.
+        (WebCore::RenderElement::removeChildInternal): Deleted.
+        * rendering/RenderElement.h:
+        (WebCore::RenderElement::addChildIgnoringContinuation):
+        * rendering/RenderFullScreen.cpp:
+        (WebCore::RenderFullScreen::willBeDestroyed):
+        (WebCore::RenderFullScreen::wrapNewRenderer):
+        (WebCore::RenderFullScreen::wrapExistingRenderer):
+
+            Split wrapRenderer() into two functions, wrapNewRenderer() and wrapExistingRenderer().
+            The first one deals with adding new renderers to the tree while the latter mutates
+            existing render tree in-place.
+
+        (WebCore::RenderFullScreen::unwrapRenderer):
+        (WebCore::RenderFullScreen::createPlaceholder):
+        (WebCore::RenderFullScreen::wrapRenderer): Deleted.
+        * rendering/RenderFullScreen.h:
+        * rendering/RenderGrid.cpp:
+        (WebCore::RenderGrid::addChild):
+        (WebCore::RenderGrid::takeChild):
+        (WebCore::RenderGrid::removeChild): Deleted.
+        * rendering/RenderGrid.h:
+        * rendering/RenderInline.cpp:
+        (WebCore::RenderInline::addChild):
+        (WebCore::RenderInline::addChildIgnoringContinuation):
+        (WebCore::RenderInline::splitInlines):
+        (WebCore::RenderInline::splitFlow):
+        (WebCore::RenderInline::addChildToContinuation):
+        (WebCore::RenderInline::childBecameNonInline):
+        * rendering/RenderInline.h:
+        * rendering/RenderMenuList.cpp:
+        (WebCore::RenderMenuList::createInnerBlock):
+        (RenderMenuList::addChild):
+        (RenderMenuList::takeChild):
+        (RenderMenuList::setText):
+        (RenderMenuList::removeChild): Deleted.
+        * rendering/RenderMenuList.h:
+        * rendering/RenderMultiColumnFlow.cpp:
+        (WebCore::RenderMultiColumnFlow::evacuateAndDestroy):
+        (WebCore::RenderMultiColumnFlow::processPossibleSpannerDescendant):
+        (WebCore::RenderMultiColumnFlow::fragmentedFlowDescendantInserted):
+
+            Keep the existing behavior and leak the placeholder renderer.
+            To be cleaned up later.
+
+        (WebCore::RenderMultiColumnFlow::handleSpannerRemoval):
+
+            Keep the existing behavior and leak the placeholder renderer.
+            To be cleaned up later.
+
+        * rendering/RenderMultiColumnSpannerPlaceholder.cpp:
+        (WebCore::RenderMultiColumnSpannerPlaceholder::createAnonymous):
+        * rendering/RenderMultiColumnSpannerPlaceholder.h:
+        * rendering/RenderObject.cpp:
+        (WebCore::RenderObject::removeFromParentAndDestroy):
+        (WebCore::RenderObject::willBeDestroyed):
+        (WebCore::RenderObject::destroy):
+        (WebCore::RenderObject::removeFromParent): Deleted.
+        * rendering/RenderObject.h:
+        * rendering/RenderQuote.cpp:
+        (WebCore::RenderQuote::updateTextRenderer):
+        * rendering/RenderRuby.cpp:
+        (WebCore::createAnonymousRubyInlineBlock):
+        (WebCore::RenderRubyAsInline::addChild):
+        (WebCore::RenderRubyAsInline::takeChild):
+        (WebCore::RenderRubyAsBlock::addChild):
+        (WebCore::RenderRubyAsBlock::takeChild):
+        (WebCore::RenderRubyAsInline::removeChild): Deleted.
+        (WebCore::RenderRubyAsBlock::removeChild): Deleted.
+        * rendering/RenderRuby.h:
+        * rendering/RenderRubyBase.cpp:
+        (WebCore::RenderRubyBase::moveInlineChildren):
+        * rendering/RenderRubyRun.cpp:
+        (WebCore::RenderRubyRun::rubyBaseSafe):
+        (WebCore::RenderRubyRun::addChild):
+        (WebCore::RenderRubyRun::takeChild):
+        (WebCore::RenderRubyRun::createRubyBase const):
+        (WebCore::RenderRubyRun::staticCreateRubyRun):
+        (WebCore::RenderRubyRun::removeChild): Deleted.
+        * rendering/RenderRubyRun.h:
+        * rendering/RenderTable.cpp:
+        (WebCore::RenderTable::addChild):
+        (WebCore::RenderTable::createTableWithStyle):
+        (WebCore::RenderTable::createAnonymousWithParentRenderer):
+        * rendering/RenderTable.h:
+        (WebCore::RenderTable::createAnonymousBoxWithSameTypeAs const):
+        * rendering/RenderTableCell.cpp:
+        (WebCore::RenderTableCell::createTableCellWithStyle):
+        (WebCore::RenderTableCell::createAnonymousWithParentRenderer):
+        * rendering/RenderTableCell.h:
+        (WebCore::RenderTableCell::createAnonymousBoxWithSameTypeAs const):
+        * rendering/RenderTableRow.cpp:
+        (WebCore::RenderTableRow::addChild):
+        (WebCore::RenderTableRow::createTableRowWithStyle):
+        (WebCore::RenderTableRow::createAnonymousWithParentRenderer):
+        * rendering/RenderTableRow.h:
+        (WebCore::RenderTableRow::createAnonymousBoxWithSameTypeAs const):
+        * rendering/RenderTableSection.cpp:
+        (WebCore::RenderTableSection::addChild):
+        (WebCore::RenderTableSection::createTableSectionWithStyle):
+        (WebCore::RenderTableSection::createAnonymousWithParentRenderer):
+        * rendering/RenderTableSection.h:
+        (WebCore::RenderTableSection::createAnonymousBoxWithSameTypeAs const):
+        * rendering/mathml/RenderMathMLFenced.cpp:
+        (WebCore::RenderMathMLFenced::makeFences):
+        (WebCore::RenderMathMLFenced::addChild):
+        * rendering/mathml/RenderMathMLFenced.h:
+        * rendering/svg/RenderSVGContainer.cpp:
+        (WebCore::RenderSVGContainer::addChild):
+        (WebCore::RenderSVGContainer::takeChild):
+        (WebCore::RenderSVGContainer::removeChild): Deleted.
+        * rendering/svg/RenderSVGContainer.h:
+        * rendering/svg/RenderSVGInline.cpp:
+        (WebCore::RenderSVGInline::addChild):
+        (WebCore::RenderSVGInline::takeChild):
+        (WebCore::RenderSVGInline::removeChild): Deleted.
+        * rendering/svg/RenderSVGInline.h:
+        * rendering/svg/RenderSVGRoot.cpp:
+        (WebCore::RenderSVGRoot::addChild):
+        (WebCore::RenderSVGRoot::takeChild):
+        (WebCore::RenderSVGRoot::removeChild): Deleted.
+        * rendering/svg/RenderSVGRoot.h:
+        * rendering/svg/RenderSVGText.cpp:
+        (WebCore::RenderSVGText::addChild):
+        (WebCore::RenderSVGText::takeChild):
+        (WebCore::RenderSVGText::removeChild): Deleted.
+        * rendering/svg/RenderSVGText.h:
+        * style/RenderTreePosition.h:
+        (WebCore::RenderTreePosition::insert):
+        * style/RenderTreeUpdater.cpp:
+        (WebCore::RenderTreeUpdater::createRenderer):
+        (WebCore::createTextRenderer):
+        * style/RenderTreeUpdaterFirstLetter.cpp:
+        (WebCore::updateFirstLetterStyle):
+        (WebCore::createFirstLetterRenderer):
+        * style/RenderTreeUpdaterGeneratedContent.cpp:
+        (WebCore::createContentRenderers):
+        * style/RenderTreeUpdaterListItem.cpp:
+        (WebCore::RenderTreeUpdater::ListItem::updateMarker):
+        * style/RenderTreeUpdaterMultiColumn.cpp:
+        (WebCore::RenderTreeUpdater::MultiColumn::createFragmentedFlow):
+
 2017-09-29  Zalan Bujtas  <zalan@apple.com>
 
         Remove redundant RenderObject::selectionRoot and dependencies
index 855fd19..ef5ff0d 100644 (file)
@@ -6048,8 +6048,8 @@ void Document::webkitWillEnterFullScreenForElement(Element* element)
         m_savedPlaceholderRenderStyle = RenderStyle::clonePtr(renderer->style());
     }
 
-    if (m_fullScreenElement != documentElement())
-        RenderFullScreen::wrapRenderer(renderer, renderer ? renderer->parent() : nullptr, *this);
+    if (m_fullScreenElement != documentElement() && renderer)
+        RenderFullScreen::wrapExistingRenderer(*renderer, *this);
 
     m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(true);
 
index ac2a051..5ab1332 100644 (file)
@@ -475,7 +475,7 @@ RenderBlock* RenderBlock::continuationBefore(RenderObject* beforeChild)
     return last;
 }
 
-void RenderBlock::addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild)
+void RenderBlock::addChildToContinuation(RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
     RenderBlock* flow = continuationBefore(beforeChild);
     ASSERT(!beforeChild || is<RenderBlock>(*beforeChild->parent()));
@@ -491,7 +491,7 @@ void RenderBlock::addChildToContinuation(RenderObject* newChild, RenderObject* b
     }
 
     if (newChild->isFloatingOrOutOfFlowPositioned()) {
-        beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
+        beforeChildParent->addChildIgnoringContinuation(WTFMove(newChild), beforeChild);
         return;
     }
 
@@ -500,21 +500,21 @@ void RenderBlock::addChildToContinuation(RenderObject* newChild, RenderObject* b
     bool flowIsNormal = flow->isInline() || !flow->style().columnSpan();
 
     if (flow == beforeChildParent) {
-        flow->addChildIgnoringContinuation(newChild, beforeChild);
+        flow->addChildIgnoringContinuation(WTFMove(newChild), beforeChild);
         return;
     }
     
     // The goal here is to match up if we can, so that we can coalesce and create the
     // minimal # of continuations needed for the inline.
     if (childIsNormal == bcpIsNormal) {
-        beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
+        beforeChildParent->addChildIgnoringContinuation(WTFMove(newChild), beforeChild);
         return;
     }
     if (flowIsNormal == childIsNormal) {
-        flow->addChildIgnoringContinuation(newChild, 0); // Just treat like an append.
+        flow->addChildIgnoringContinuation(WTFMove(newChild), 0); // Just treat like an append.
         return;
     }
-    beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
+    beforeChildParent->addChildIgnoringContinuation(WTFMove(newChild), beforeChild);
 }
 
 RenderPtr<RenderBlock> RenderBlock::clone() const
@@ -537,15 +537,15 @@ RenderPtr<RenderBlock> RenderBlock::clone() const
     return cloneBlock;
 }
 
-void RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild)
+void RenderBlock::addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
     if (continuation() && !isAnonymousBlock())
-        addChildToContinuation(newChild, beforeChild);
+        addChildToContinuation(WTFMove(newChild), beforeChild);
     else
-        addChildIgnoringContinuation(newChild, beforeChild);
+        addChildIgnoringContinuation(WTFMove(newChild), beforeChild);
 }
 
-void RenderBlock::addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild)
+void RenderBlock::addChildIgnoringContinuation(RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
     if (beforeChild && beforeChild->parent() != this) {
         RenderElement* beforeChildContainer = beforeChild->parent();
@@ -566,16 +566,16 @@ void RenderBlock::addChildIgnoringContinuation(RenderObject* newChild, RenderObj
                 ) {
                 // Insert the child into the anonymous block box instead of here.
                 if (newChild->isInline() || beforeChild->parent()->firstChild() != beforeChild)
-                    beforeChild->parent()->addChild(newChild, beforeChild);
+                    beforeChild->parent()->addChild(WTFMove(newChild), beforeChild);
                 else
-                    addChild(newChild, beforeChild->parent());
+                    addChild(WTFMove(newChild), beforeChild->parent());
                 return;
             }
 
             ASSERT(beforeChildAnonymousContainer->isTable());
             if (newChild->isTablePart()) {
                 // Insert into the anonymous table.
-                beforeChildAnonymousContainer->addChild(newChild, beforeChild);
+                beforeChildAnonymousContainer->addChild(WTFMove(newChild), beforeChild);
                 return;
             }
 
@@ -612,22 +612,23 @@ void RenderBlock::addChildIgnoringContinuation(RenderObject* newChild, RenderObj
         RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : lastChild();
 
         if (afterChild && afterChild->isAnonymousBlock()) {
-            downcast<RenderBlock>(*afterChild).addChild(newChild);
+            downcast<RenderBlock>(*afterChild).addChild(WTFMove(newChild));
             return;
         }
 
         if (newChild->isInline()) {
             // No suitable existing anonymous box - create a new one.
-            RenderBlock* newBox = createAnonymousBlock();
-            RenderBox::addChild(newBox, beforeChild);
-            newBox->addChild(newChild);
+            auto newBox = createAnonymousBlock();
+            auto& box = *newBox;
+            RenderBox::addChild(WTFMove(newBox), beforeChild);
+            box.addChild(WTFMove(newChild));
             return;
         }
     }
 
     invalidateLineLayoutPath();
 
-    RenderBox::addChild(newChild, beforeChild);
+    RenderBox::addChild(WTFMove(newChild), beforeChild);
  
     if (madeBoxesNonInline && is<RenderBlock>(parent()) && isAnonymousBlock())
         downcast<RenderBlock>(*parent()).removeLeftoverAnonymousBlock(this);
@@ -710,9 +711,10 @@ void RenderBlock::makeChildrenNonInline(RenderObject* insertionPoint)
 
         child = inlineRunEnd->nextSibling();
 
-        RenderBlock* block = createAnonymousBlock();
-        insertChildInternal(block, inlineRunStart, NotifyChildren);
-        moveChildrenTo(block, inlineRunStart, child);
+        auto newBlock = createAnonymousBlock();
+        auto& block = *newBlock;
+        insertChildInternal(WTFMove(newBlock), inlineRunStart, NotifyChildren);
+        moveChildrenTo(&block, inlineRunStart, child);
     }
 
 #ifndef NDEBUG
@@ -811,21 +813,19 @@ void RenderBlock::dropAnonymousBoxChild(RenderBlock& parent, RenderBlock& child)
     parent.setNeedsLayoutAndPrefWidthsRecalc();
     parent.setChildrenInline(child.childrenInline());
     RenderObject* nextSibling = child.nextSibling();
-    parent.removeChildInternal(child, child.hasLayer() ? NotifyChildren : DontNotifyChildren);
+
+    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();
-    child.destroy();
 }
 
-void RenderBlock::removeChild(RenderObject& oldChild)
+RenderPtr<RenderObject> RenderBlock::takeChild(RenderObject& oldChild)
 {
     // No need to waste time in merging or removing empty anonymous blocks.
     // We can just bail out if our document is getting destroyed.
-    if (renderTreeBeingDestroyed()) {
-        RenderBox::removeChild(oldChild);
-        return;
-    }
+    if (renderTreeBeingDestroyed())
+        return RenderBox::takeChild(oldChild);
 
     // If this child is a block, and if our previous and next siblings are both anonymous blocks
     // with inline content, then we can fold the inline content back together.
@@ -849,11 +849,11 @@ void RenderBlock::removeChild(RenderObject& oldChild)
             // Cache this value as it might get changed in setStyle() call.
             bool inlineChildrenBlockHasLayer = inlineChildrenBlock.hasLayer();
             inlineChildrenBlock.setStyle(RenderStyle::createAnonymousStyleWithDisplay(style(), BLOCK));
-            removeChildInternal(inlineChildrenBlock, inlineChildrenBlockHasLayer ? NotifyChildren : DontNotifyChildren);
+            auto blockToMove = takeChildInternal(inlineChildrenBlock, inlineChildrenBlockHasLayer ? NotifyChildren : DontNotifyChildren);
             
             // Now just put the inlineChildrenBlock inside the blockChildrenBlock.
             RenderObject* beforeChild = prev == &inlineChildrenBlock ? blockChildrenBlock.firstChild() : nullptr;
-            blockChildrenBlock.insertChildInternal(&inlineChildrenBlock, beforeChild,
+            blockChildrenBlock.insertChildInternal(WTFMove(blockToMove), beforeChild,
                 (inlineChildrenBlockHasLayer || blockChildrenBlock.hasLayer()) ? NotifyChildren : DontNotifyChildren);
             next->setNeedsLayoutAndPrefWidthsRecalc();
             
@@ -877,7 +877,7 @@ void RenderBlock::removeChild(RenderObject& oldChild)
 
     invalidateLineLayoutPath();
 
-    RenderBox::removeChild(oldChild);
+    auto takenChild = RenderBox::takeChild(oldChild);
 
     RenderObject* child = prev ? prev : next;
     if (canMergeAnonymousBlocks && child && !child->previousSibling() && !child->nextSibling() && canDropAnonymousBlockChild()) {
@@ -934,6 +934,7 @@ void RenderBlock::removeChild(RenderObject& oldChild)
             destroy();
         }
     }
+    return takenChild;
 }
 
 bool RenderBlock::childrenPreventSelfCollapsing() const
@@ -3340,14 +3341,14 @@ void RenderBlock::addFocusRingRects(Vector<LayoutRect>& rects, const LayoutPoint
         inlineElementContinuation()->addFocusRingRects(rects, flooredLayoutPoint(LayoutPoint(additionalOffset + inlineElementContinuation()->containingBlock()->location() - location())), paintContainer);
 }
 
-std::unique_ptr<RenderBlock> RenderBlock::createAnonymousBlockWithStyleAndDisplay(Document& document, const RenderStyle& style, EDisplay display)
+RenderPtr<RenderBlock> RenderBlock::createAnonymousBlockWithStyleAndDisplay(Document& document, const RenderStyle& style, EDisplay display)
 {
     // FIXME: Do we need to convert all our inline displays to block-type in the anonymous logic ?
-    std::unique_ptr<RenderBlock> newBox;
+    RenderPtr<RenderBlock> newBox;
     if (display == FLEX || display == INLINE_FLEX)
-        newBox = std::make_unique<RenderFlexibleBox>(document, RenderStyle::createAnonymousStyleWithDisplay(style, FLEX));
+        newBox = createRenderer<RenderFlexibleBox>(document, RenderStyle::createAnonymousStyleWithDisplay(style, FLEX));
     else
-        newBox = std::make_unique<RenderBlockFlow>(document, RenderStyle::createAnonymousStyleWithDisplay(style, BLOCK));
+        newBox = createRenderer<RenderBlockFlow>(document, RenderStyle::createAnonymousStyleWithDisplay(style, BLOCK));
     
     newBox->initializeStyle();
     return newBox;
index d7d4d3b..2917ae4 100644 (file)
@@ -72,8 +72,8 @@ public:
     // FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
     virtual void deleteLines();
 
-    void addChild(RenderObject* newChild, RenderObject* beforeChild = 0) override;
-    void removeChild(RenderObject&) override;
+    void addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild = 0) override;
+    RenderPtr<RenderObject> takeChild(RenderObject&) override;
 
     virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0);
 
@@ -196,11 +196,11 @@ public:
     using RenderBoxModelObject::continuation;
     using RenderBoxModelObject::setContinuation;
 
-    static std::unique_ptr<RenderBlock> createAnonymousWithParentRendererAndDisplay(const RenderBox& parent, EDisplay = BLOCK);
-    RenderBlock* createAnonymousBlock(EDisplay = BLOCK) const;
+    static RenderPtr<RenderBlock> createAnonymousWithParentRendererAndDisplay(const RenderBox& parent, EDisplay = BLOCK);
+    RenderPtr<RenderBlock> createAnonymousBlock(EDisplay = BLOCK) const;
     static void dropAnonymousBoxChild(RenderBlock& parent, RenderBlock& child);
 
-    std::unique_ptr<RenderBox> createAnonymousBoxWithSameTypeAs(const RenderBox&) const override;
+    RenderPtr<RenderBox> createAnonymousBoxWithSameTypeAs(const RenderBox&) const override;
 
     static bool shouldSkipCreatingRunsForObject(RenderObject& obj)
     {
@@ -428,7 +428,7 @@ protected:
     void blockWillBeDestroyed();
 
 private:
-    static std::unique_ptr<RenderBlock> createAnonymousBlockWithStyleAndDisplay(Document&, const RenderStyle&, EDisplay);
+    static RenderPtr<RenderBlock> createAnonymousBlockWithStyleAndDisplay(Document&, const RenderStyle&, EDisplay);
 
     // FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
     virtual LayoutUnit logicalRightFloatOffsetForLine(LayoutUnit, LayoutUnit fixedOffset, LayoutUnit) const { return fixedOffset; };
@@ -447,8 +447,8 @@ private:
     // FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
     virtual void moveAllChildrenIncludingFloatsTo(RenderBlock& toBlock, bool fullRemoveInsert) { moveAllChildrenTo(&toBlock, fullRemoveInsert); }
 
-    void addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild);
-    void addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild) override;
+    void addChildToContinuation(RenderPtr<RenderObject> newChild, RenderObject* beforeChild);
+    void addChildIgnoringContinuation(RenderPtr<RenderObject> newChild, RenderObject* beforeChild) override;
 
     bool isSelfCollapsingBlock() const override;
     virtual bool childrenPreventSelfCollapsing() const;
@@ -547,19 +547,19 @@ LayoutUnit blockDirectionOffset(RenderBlock& rootBlock, const LayoutSize& offset
 LayoutUnit inlineDirectionOffset(RenderBlock& rootBlock, const LayoutSize& offsetFromRootBlock);
 VisiblePosition positionForPointRespectingEditingBoundaries(RenderBlock&, RenderBox&, const LayoutPoint&);
 
-inline std::unique_ptr<RenderBlock> RenderBlock::createAnonymousWithParentRendererAndDisplay(const RenderBox& parent, EDisplay display)
+inline RenderPtr<RenderBlock> RenderBlock::createAnonymousWithParentRendererAndDisplay(const RenderBox& parent, EDisplay display)
 {
     return createAnonymousBlockWithStyleAndDisplay(parent.document(), parent.style(), display);
 }
 
-inline std::unique_ptr<RenderBox> RenderBlock::createAnonymousBoxWithSameTypeAs(const RenderBox& renderer) const
+inline RenderPtr<RenderBox> RenderBlock::createAnonymousBoxWithSameTypeAs(const RenderBox& renderer) const
 {
     return createAnonymousBlockWithStyleAndDisplay(document(), renderer.style(), style().display());
 }
 
-inline RenderBlock* RenderBlock::createAnonymousBlock(EDisplay display) const
+inline RenderPtr<RenderBlock> RenderBlock::createAnonymousBlock(EDisplay display) const
 {
-    return createAnonymousBlockWithStyleAndDisplay(document(), style(), display).release();
+    return createAnonymousBlockWithStyleAndDisplay(document(), style(), display);
 }
 
 } // namespace WebCore
index 62c3856..de14ef6 100644 (file)
@@ -3835,24 +3835,24 @@ void RenderBlockFlow::layoutExcludedChildren(bool relayoutChildren)
     determineLogicalLeftPositionForChild(*fragmentedFlow);
 }
 
-void RenderBlockFlow::addChild(RenderObject* newChild, RenderObject* beforeChild)
+void RenderBlockFlow::addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
     if (multiColumnFlow() && (!isFieldset() || !newChild->isLegend()))
-        return multiColumnFlow()->addChild(newChild, beforeChild);
+        return multiColumnFlow()->addChild(WTFMove(newChild), beforeChild);
     auto* beforeChildOrPlaceholder = beforeChild;
     if (auto* containingFragmentedFlow = enclosingFragmentedFlow())
         beforeChildOrPlaceholder = containingFragmentedFlow->resolveMovedChild(beforeChild);
-    RenderBlock::addChild(newChild, beforeChildOrPlaceholder);
+    RenderBlock::addChild(WTFMove(newChild), beforeChildOrPlaceholder);
 }
 
-void RenderBlockFlow::removeChild(RenderObject& oldChild)
+RenderPtr<RenderObject> RenderBlockFlow::takeChild(RenderObject& oldChild)
 {
     if (!renderTreeBeingDestroyed()) {
         RenderFragmentedFlow* fragmentedFlow = multiColumnFlow();
         if (fragmentedFlow && fragmentedFlow != &oldChild)
             fragmentedFlow->fragmentedFlowRelativeWillBeRemoved(oldChild);
     }
-    RenderBlock::removeChild(oldChild);
+    return RenderBlock::takeChild(oldChild);
 }
 
 void RenderBlockFlow::checkForPaginationLogicalHeightChange(bool& relayoutChildren, LayoutUnit& pageLogicalHeight, bool& pageLogicalHeightChanged)
index 6c8dada..940f7be 100644 (file)
@@ -382,8 +382,8 @@ public:
     LayoutUnit logicalHeightForChildForFragmentation(const RenderBox& child) const;
     bool hasNextPage(LayoutUnit logicalOffset, PageBoundaryRule = ExcludePageBoundary) const;
 
-    void addChild(RenderObject* newChild, RenderObject* beforeChild = 0) override;
-    void removeChild(RenderObject&) override;
+    void addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild = 0) override;
+    RenderPtr<RenderObject> takeChild(RenderObject&) override;
 
     void updateColumnProgressionFromStyle(RenderStyle&);
     void updateStylesForColumnChildren();
index 29ddd5d..b8e929b 100644 (file)
@@ -4931,20 +4931,21 @@ RenderObject* RenderBox::splitAnonymousBoxesAroundChild(RenderObject* beforeChil
 
             // We have to split the parent box into two boxes and move children
             // from |beforeChild| to end into the new post box.
-            auto* postBox = boxToSplit.createAnonymousBoxWithSameTypeAs(*this).release();
-            postBox->setChildrenInline(boxToSplit.childrenInline());
+            auto newPostBox = boxToSplit.createAnonymousBoxWithSameTypeAs(*this);
+            auto& postBox = *newPostBox;
+            postBox.setChildrenInline(boxToSplit.childrenInline());
             RenderBox* parentBox = downcast<RenderBox>(boxToSplit.parent());
             // We need to invalidate the |parentBox| before inserting the new node
             // so that the table repainting logic knows the structure is dirty.
             // See for example RenderTableCell:clippedOverflowRectForRepaint.
             markBoxForRelayoutAfterSplit(*parentBox);
-            parentBox->insertChildInternal(postBox, boxToSplit.nextSibling(), NotifyChildren);
-            boxToSplit.moveChildrenTo(postBox, beforeChild, nullptr, true);
+            parentBox->insertChildInternal(WTFMove(newPostBox), boxToSplit.nextSibling(), NotifyChildren);
+            boxToSplit.moveChildrenTo(&postBox, beforeChild, nullptr, true);
 
             markBoxForRelayoutAfterSplit(boxToSplit);
-            markBoxForRelayoutAfterSplit(*postBox);
+            markBoxForRelayoutAfterSplit(postBox);
 
-            beforeChild = postBox;
+            beforeChild = &postBox;
         } else
             beforeChild = &boxToSplit;
     }
index a418ec8..c215952 100644 (file)
@@ -592,7 +592,7 @@ public:
         return layoutOverflowRect.y() < y() || layoutOverflowRect.maxY() > y() + logicalHeight();
     }
 
-    virtual std::unique_ptr<RenderBox> createAnonymousBoxWithSameTypeAs(const RenderBox&) const
+    virtual RenderPtr<RenderBox> createAnonymousBoxWithSameTypeAs(const RenderBox&) const
     {
         ASSERT_NOT_REACHED();
         return nullptr;
index 603813e..1e583ad 100644 (file)
@@ -2596,12 +2596,12 @@ void RenderBoxModelObject::moveChildTo(RenderBoxModelObject* toBoxModelObject, R
     if (fullRemoveInsert && (toBoxModelObject->isRenderBlock() || toBoxModelObject->isRenderInline())) {
         // Takes care of adding the new child correctly if toBlock and fromBlock
         // have different kind of children (block vs inline).
-        removeChildInternal(*child, NotifyChildren);
-        toBoxModelObject->addChild(child, beforeChild);
+        auto childToMove = takeChildInternal(*child, NotifyChildren);
+        toBoxModelObject->addChild(WTFMove(childToMove), beforeChild);
     } else {
         NotifyChildrenType notifyType = fullRemoveInsert ? NotifyChildren : DontNotifyChildren;
-        removeChildInternal(*child, notifyType);
-        toBoxModelObject->insertChildInternal(child, beforeChild, notifyType);
+        auto childToMove = takeChildInternal(*child, notifyType);
+        toBoxModelObject->insertChildInternal(WTFMove(childToMove), beforeChild, notifyType);
     }
 }
 
index 22252d6..f552344 100644 (file)
@@ -63,30 +63,31 @@ bool RenderButton::hasLineIfEmpty() const
     return is<HTMLInputElement>(formControlElement());
 }
 
-void RenderButton::addChild(RenderObject* newChild, RenderObject* beforeChild)
+void RenderButton::addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
     if (!m_inner) {
         // Create an anonymous block.
         ASSERT(!firstChild());
-        m_inner = createAnonymousBlock(style().display());
-        updateAnonymousChildStyle(*m_inner, m_inner->mutableStyle());
-        RenderFlexibleBox::addChild(m_inner);
+        auto newInner = createAnonymousBlock(style().display());
+        updateAnonymousChildStyle(*newInner, newInner->mutableStyle());
+        m_inner = newInner.get();
+        RenderFlexibleBox::addChild(WTFMove(newInner));
     }
     
-    m_inner->addChild(newChild, beforeChild);
+    m_inner->addChild(WTFMove(newChild), beforeChild);
 }
 
-void RenderButton::removeChild(RenderObject& oldChild)
+RenderPtr<RenderObject> RenderButton::takeChild(RenderObject& oldChild)
 {
     // m_inner should be the only child, but checking for direct children who
     // are not m_inner prevents security problems when that assumption is
     // violated.
     if (&oldChild == m_inner || !m_inner || oldChild.parent() == this) {
         ASSERT(&oldChild == m_inner || !m_inner);
-        RenderFlexibleBox::removeChild(oldChild);
         m_inner = nullptr;
-    } else
-        m_inner->removeChild(oldChild);
+        return RenderFlexibleBox::takeChild(oldChild);
+    }
+    return m_inner->takeChild(oldChild);
 }
     
 void RenderButton::updateAnonymousChildStyle(const RenderObject& child, RenderStyle& childStyle) const
@@ -128,8 +129,9 @@ void RenderButton::setText(const String& str)
         if (m_buttonText)
             m_buttonText->setText(str.impl());
         else {
-            m_buttonText = new RenderTextFragment(document(), str);
-            addChild(m_buttonText);
+            auto newButtonText = createRenderer<RenderTextFragment>(document(), str);
+            m_buttonText = newButtonText.get();
+            addChild(WTFMove(newButtonText));
         }
     }
 }
index 61ef7cc..286de78 100644 (file)
@@ -40,8 +40,8 @@ public:
 
     bool canBeSelectionLeaf() const override;
 
-    void addChild(RenderObject* newChild, RenderObject *beforeChild = 0) override;
-    void removeChild(RenderObject&) override;
+    void addChild(RenderPtr<RenderObject> newChild, RenderObject *beforeChild = 0) override;
+    RenderPtr<RenderObject> takeChild(RenderObject&) override;
     void removeLeftoverAnonymousBlock(RenderBlock*) override { }
     bool createsAnonymousWrapper() const override { return true; }
 
index 9a2a532..a4d34de 100644 (file)
@@ -455,23 +455,26 @@ bool RenderElement::childRequiresTable(const RenderObject& child) const
     return false;
 }
 
-void RenderElement::addChild(RenderObject* newChild, RenderObject* beforeChild)
+void RenderElement::addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
-    if (childRequiresTable(*newChild)) {
+    auto& child = *newChild;
+    if (childRequiresTable(child)) {
         RenderTable* table;
         RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : m_lastChild;
         if (afterChild && afterChild->isAnonymous() && is<RenderTable>(*afterChild) && !afterChild->isBeforeContent())
             table = downcast<RenderTable>(afterChild);
         else {
-            table = RenderTable::createAnonymousWithParentRenderer(*this).release();
-            addChild(table, beforeChild);
+            auto newTable =  RenderTable::createAnonymousWithParentRenderer(*this);
+            table = newTable.get();
+            addChild(WTFMove(newTable), beforeChild);
         }
-        table->addChild(newChild);
+
+        table->addChild(WTFMove(newChild));
     } else
-        insertChildInternal(newChild, beforeChild, NotifyChildren);
+        insertChildInternal(WTFMove(newChild), beforeChild, NotifyChildren);
 
-    if (is<RenderText>(*newChild))
-        downcast<RenderText>(*newChild).styleDidChange(StyleDifferenceEqual, nullptr);
+    if (is<RenderText>(child))
+        downcast<RenderText>(child).styleDidChange(StyleDifferenceEqual, nullptr);
 
     // SVG creates renderers for <g display="none">, as SVG requires children of hidden
     // <g>s to have renderers - at least that's how our implementation works. Consider:
@@ -481,22 +484,30 @@ void RenderElement::addChild(RenderObject* newChild, RenderObject* beforeChild)
     //   know that it's inside a "hidden SVG subtree", and thus paints, even if it shouldn't.
     // To avoid the problem alltogether, detect early if we're inside a hidden SVG subtree
     // and stop creating layers at all for these cases - they're not used anyways.
-    if (newChild->hasLayer() && !layerCreationAllowedForSubtree())
-        downcast<RenderLayerModelObject>(*newChild).layer()->removeOnlyThisLayer();
+    if (child.hasLayer() && !layerCreationAllowedForSubtree())
+        downcast<RenderLayerModelObject>(child).layer()->removeOnlyThisLayer();
+
+    SVGRenderSupport::childAdded(*this, child);
+}
 
-    SVGRenderSupport::childAdded(*this, *newChild);
+RenderPtr<RenderObject> RenderElement::takeChild(RenderObject& oldChild)
+{
+    return takeChildInternal(oldChild, NotifyChildren);
 }
 
-void RenderElement::removeChild(RenderObject& oldChild)
+void RenderElement::removeAndDestroyChild(RenderObject& oldChild)
 {
-    removeChildInternal(oldChild, NotifyChildren);
+    auto toDestroy = takeChild(oldChild);
 }
 
 void RenderElement::destroyLeftoverChildren()
 {
     while (m_firstChild) {
         if (m_firstChild->style().styleType() == FIRST_LETTER && !m_firstChild->isText()) {
-            m_firstChild->removeFromParent(); // :first-letter fragment renderers are destroyed by their remaining text fragment.
+            // FIXME: Memory management.
+            auto firstLetter = takeChild(*m_firstChild); // :first-letter fragment renderers are destroyed by their remaining text fragment.
+            auto* leakedPtr = firstLetter.leakPtr();
+            UNUSED_PARAM(leakedPtr);
         } else {
             // Destroy any anonymous children remaining in the render tree, as well as implicit (shadow) DOM elements like those used in the engine-based text fields.
             if (m_firstChild->node())
@@ -506,24 +517,21 @@ void RenderElement::destroyLeftoverChildren()
     }
 }
 
-void RenderElement::insertChildInternal(RenderObject* newChild, RenderObject* beforeChild, NotifyChildrenType notifyChildren)
+void RenderElement::insertChildInternal(RenderPtr<RenderObject> newChildPtr, RenderObject* beforeChild, NotifyChildrenType notifyChildren)
 {
     RELEASE_ASSERT_WITH_MESSAGE(!view().layoutState(), "Layout must not mutate render tree");
 
     ASSERT(canHaveChildren() || canHaveGeneratedChildren());
-    ASSERT(!newChild->parent());
-    ASSERT(!isRenderBlockFlow() || (!newChild->isTableSection() && !newChild->isTableRow() && !newChild->isTableCell()));
+    ASSERT(!newChildPtr->parent());
+    ASSERT(!isRenderBlockFlow() || (!newChildPtr->isTableSection() && !newChildPtr->isTableRow() && !newChildPtr->isTableCell()));
 
     while (beforeChild && beforeChild->parent() && beforeChild->parent() != this)
         beforeChild = beforeChild->parent();
 
-    // This should never happen, but if it does prevent render tree corruption
-    // where child->parent() ends up being owner but child->nextSibling()->parent()
-    // is not owner.
-    if (beforeChild && beforeChild->parent() != this) {
-        ASSERT_NOT_REACHED();
-        return;
-    }
+    ASSERT(!beforeChild || beforeChild->parent() == this);
+
+    // Take the ownership.
+    auto* newChild = newChildPtr.leakPtr();
 
     newChild->setParent(this);
 
@@ -565,7 +573,7 @@ void RenderElement::insertChildInternal(RenderObject* newChild, RenderObject* be
         newChild->setHasOutlineAutoAncestor();
 }
 
-void RenderElement::removeChildInternal(RenderObject& oldChild, NotifyChildrenType notifyChildren)
+RenderPtr<RenderObject> RenderElement::takeChildInternal(RenderObject& oldChild, NotifyChildrenType notifyChildren)
 {
     RELEASE_ASSERT_WITH_MESSAGE(!view().layoutState(), "Layout must not mutate render tree");
 
@@ -638,6 +646,8 @@ void RenderElement::removeChildInternal(RenderObject& oldChild, NotifyChildrenTy
     if (is<RenderListMarker>(oldChild))
         ASSERT(m_reparentingChild || !downcast<RenderListMarker>(oldChild).listItem().inLayout());
 #endif
+
+    return RenderPtr<RenderObject>(&oldChild);
 }
 
 RenderBlock* RenderElement::containingBlockForFixedPosition() const
@@ -937,10 +947,11 @@ void RenderElement::handleDynamicFloatPositionChange()
             downcast<RenderBoxModelObject>(*parent()).childBecameNonInline(*this);
         else {
             // An anonymous block must be made to wrap this inline.
-            RenderBlock* block = downcast<RenderBlock>(*parent()).createAnonymousBlock();
-            parent()->insertChildInternal(block, this, RenderElement::NotifyChildren);
-            parent()->removeChildInternal(*this, RenderElement::NotifyChildren);
-            block->insertChildInternal(this, nullptr, RenderElement::NotifyChildren);
+            auto newBlock = downcast<RenderBlock>(*parent()).createAnonymousBlock();
+            auto& block = *newBlock;
+            parent()->insertChildInternal(WTFMove(newBlock), this, RenderElement::NotifyChildren);
+            auto thisToMove = parent()->takeChildInternal(*this, RenderElement::NotifyChildren);
+            block.insertChildInternal(WTFMove(thisToMove), nullptr, RenderElement::NotifyChildren);
         }
     }
 }
index 27a806a..b294ddf 100644 (file)
@@ -85,9 +85,10 @@ public:
     bool isRenderInline() const;
 
     virtual bool isChildAllowed(const RenderObject&, const RenderStyle&) const { return true; }
-    virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = nullptr);
-    virtual void addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild = nullptr) { return addChild(newChild, beforeChild); }
-    virtual void removeChild(RenderObject&);
+    virtual void addChild(RenderPtr<RenderObject>, RenderObject* beforeChild = nullptr);
+    virtual void addChildIgnoringContinuation(RenderPtr<RenderObject> newChild, RenderObject* beforeChild = nullptr) { addChild(WTFMove(newChild), beforeChild); }
+    virtual RenderPtr<RenderObject> takeChild(RenderObject&) WARN_UNUSED_RETURN;
+    void removeAndDestroyChild(RenderObject&);
 
     // The following functions are used when the render tree hierarchy changes to make sure layers get
     // properly added and removed. Since containership can be implemented by any subclass, and since a hierarchy
@@ -98,8 +99,8 @@ public:
     RenderLayer* findNextLayer(RenderLayer* parentLayer, RenderObject* startPoint, bool checkParent = true);
 
     enum NotifyChildrenType { NotifyChildren, DontNotifyChildren };
-    void insertChildInternal(RenderObject*, RenderObject* beforeChild, NotifyChildrenType);
-    void removeChildInternal(RenderObject&, NotifyChildrenType);
+    void insertChildInternal(RenderPtr<RenderObject>, RenderObject* beforeChild, NotifyChildrenType);
+    RenderPtr<RenderObject> takeChildInternal(RenderObject&, NotifyChildrenType) WARN_UNUSED_RETURN;
 
     virtual RenderElement* hoverAncestor() const;
 
index afacfbc..364c3ae 100644 (file)
@@ -64,7 +64,6 @@ RenderFullScreen::RenderFullScreen(Document& document, RenderStyle&& style)
 void RenderFullScreen::willBeDestroyed()
 {
     if (m_placeholder) {
-        removeFromParent();
         if (!m_placeholder->beingDestroyed())
             m_placeholder->destroy();
         ASSERT(!m_placeholder);
@@ -104,38 +103,53 @@ static RenderStyle createFullScreenStyle()
     return fullscreenStyle;
 }
 
-RenderFullScreen* RenderFullScreen::wrapRenderer(RenderObject* object, RenderElement* parent, Document& document)
+RenderPtr<RenderFullScreen> RenderFullScreen::wrapNewRenderer(RenderPtr<RenderElement> renderer, RenderElement& parent, Document& document)
 {
-    RenderFullScreen* fullscreenRenderer = new RenderFullScreen(document, createFullScreenStyle());
-    fullscreenRenderer->initializeStyle();
-    if (parent && !parent->isChildAllowed(*fullscreenRenderer, fullscreenRenderer->style())) {
-        fullscreenRenderer->destroy();
-        return 0;
-    }
-    if (object) {
-        // |object->parent()| can be null if the object is not yet attached
-        // to |parent|.
-        if (RenderElement* parent = object->parent()) {
-            RenderBlock* containingBlock = object->containingBlock();
-            ASSERT(containingBlock);
-            // Since we are moving the |object| to a new parent |fullscreenRenderer|,
-            // the line box tree underneath our |containingBlock| is not longer valid.
-            containingBlock->deleteLines();
-
-            parent->addChild(fullscreenRenderer, object);
-            object->removeFromParent();
-            
-            // Always just do a full layout to ensure that line boxes get deleted properly.
-            // Because objects moved from |parent| to |fullscreenRenderer|, we want to
-            // make new line boxes instead of leaving the old ones around.
-            parent->setNeedsLayoutAndPrefWidthsRecalc();
-            containingBlock->setNeedsLayoutAndPrefWidthsRecalc();
-        }
-        fullscreenRenderer->addChild(object);
-        fullscreenRenderer->setNeedsLayoutAndPrefWidthsRecalc();
-    }
-    document.setFullScreenRenderer(fullscreenRenderer);
-    return fullscreenRenderer;
+    auto newFullscreenRenderer = createRenderer<RenderFullScreen>(document, createFullScreenStyle());
+    newFullscreenRenderer->initializeStyle();
+
+    auto& fullscreenRenderer = *newFullscreenRenderer;
+    if (!parent.isChildAllowed(fullscreenRenderer, fullscreenRenderer.style()))
+        return nullptr;
+
+    fullscreenRenderer.addChild(WTFMove(renderer));
+    fullscreenRenderer.setNeedsLayoutAndPrefWidthsRecalc();
+
+    document.setFullScreenRenderer(&fullscreenRenderer);
+
+    return newFullscreenRenderer;
+}
+
+void RenderFullScreen::wrapExistingRenderer(RenderElement& renderer, Document& document)
+{
+    auto newFullscreenRenderer = createRenderer<RenderFullScreen>(document, createFullScreenStyle());
+    newFullscreenRenderer->initializeStyle();
+
+    auto& fullscreenRenderer = *newFullscreenRenderer;
+    auto& parent = *renderer.parent();
+    if (!parent.isChildAllowed(fullscreenRenderer, fullscreenRenderer.style()))
+        return;
+
+    RenderBlock* containingBlock = renderer.containingBlock();
+    ASSERT(containingBlock);
+    // Since we are moving the |object| to a new parent |fullscreenRenderer|,
+    // the line box tree underneath our |containingBlock| is not longer valid.
+    containingBlock->deleteLines();
+
+    parent.addChild(WTFMove(newFullscreenRenderer), &renderer);
+
+    auto toMove = parent.takeChild(renderer);
+
+    // Always just do a full layout to ensure that line boxes get deleted properly.
+    // Because objects moved from |parent| to |fullscreenRenderer|, we want to
+    // make new line boxes instead of leaving the old ones around.
+    parent.setNeedsLayoutAndPrefWidthsRecalc();
+    containingBlock->setNeedsLayoutAndPrefWidthsRecalc();
+
+    fullscreenRenderer.addChild(WTFMove(toMove));
+    fullscreenRenderer.setNeedsLayoutAndPrefWidthsRecalc();
+
+    document.setFullScreenRenderer(&fullscreenRenderer);
 }
 
 void RenderFullScreen::unwrapRenderer(bool& requiresRenderTreeRebuild)
@@ -159,8 +173,7 @@ void RenderFullScreen::unwrapRenderer(bool& requiresRenderTreeRebuild)
                 if (auto* nonAnonymousChild = downcast<RenderBlock>(*child).firstChild())
                     child = nonAnonymousChild;
                 else {
-                    child->removeFromParent();
-                    child->destroy();
+                    child->removeFromParentAndDestroy();
                     continue;
                 }
             }
@@ -169,15 +182,18 @@ void RenderFullScreen::unwrapRenderer(bool& requiresRenderTreeRebuild)
             // lying around on the child.
             if (is<RenderBox>(*child))
                 downcast<RenderBox>(*child).clearOverrideSize();
-            child->removeFromParent();
-            parent()->addChild(child, this);
+            auto childToMove = child->parent()->takeChild(*child);
+            parent()->addChild(WTFMove(childToMove), this);
             parent()->setNeedsLayoutAndPrefWidthsRecalc();
         }
     }
     if (placeholder())
-        placeholder()->removeFromParent();
-    removeFromParent();
-    document().setFullScreenRenderer(0);
+        placeholder()->removeFromParentAndDestroy();
+    ASSERT(!placeholder());
+
+    removeFromParentAndDestroy();
+    
+    ASSERT(!document().fullScreenRenderer());
 }
 
 void RenderFullScreen::setPlaceholder(RenderBlock* placeholder)
@@ -197,12 +213,16 @@ void RenderFullScreen::createPlaceholder(std::unique_ptr<RenderStyle> style, con
         return;
     }
 
-    m_placeholder = new RenderFullScreenPlaceholder(*this, WTFMove(*style));
-    m_placeholder->initializeStyle();
-    if (parent()) {
-        parent()->addChild(m_placeholder, this);
-        parent()->setNeedsLayoutAndPrefWidthsRecalc();
-    }
+    if (!parent())
+        return;
+
+    auto newPlaceholder = createRenderer<RenderFullScreenPlaceholder>(*this, WTFMove(*style));
+    newPlaceholder->initializeStyle();
+
+    m_placeholder = newPlaceholder.get();
+
+    parent()->addChild(WTFMove(newPlaceholder), this);
+    parent()->setNeedsLayoutAndPrefWidthsRecalc();
 }
 
 }
index c3e8562..337fcd7 100644 (file)
@@ -40,7 +40,8 @@ public:
     RenderBlock* placeholder() { return m_placeholder; }
     void createPlaceholder(std::unique_ptr<RenderStyle>, const LayoutRect& frameRect);
 
-    static RenderFullScreen* wrapRenderer(RenderObject*, RenderElement*, Document&);
+    static RenderPtr<RenderFullScreen> wrapNewRenderer(RenderPtr<RenderElement>, RenderElement& parent, Document&);
+    static void wrapExistingRenderer(RenderElement&, Document&);
     void unwrapRenderer(bool& requiresRenderTreeRebuild);
 
     ItemPosition selfAlignmentNormalBehavior(const RenderBox* = nullptr) const override { return ItemPositionCenter; }
index 2faa9ed..87fda34 100644 (file)
@@ -66,13 +66,14 @@ RenderGrid::~RenderGrid()
 {
 }
 
-void RenderGrid::addChild(RenderObject* newChild, RenderObject* beforeChild)
+void RenderGrid::addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
-    RenderBlock::addChild(newChild, beforeChild);
+    auto& child = *newChild;
+    RenderBlock::addChild(WTFMove(newChild), beforeChild);
 
     // Positioned grid items do not take up space or otherwise participate in the layout of the grid,
     // for that reason we don't need to mark the grid as dirty when they are added.
-    if (newChild->isOutOfFlowPositioned())
+    if (child.isOutOfFlowPositioned())
         return;
 
     // The grid needs to be recomputed as it might contain auto-placed items that
@@ -80,18 +81,19 @@ void RenderGrid::addChild(RenderObject* newChild, RenderObject* beforeChild)
     dirtyGrid();
 }
 
-void RenderGrid::removeChild(RenderObject& child)
+RenderPtr<RenderObject> RenderGrid::takeChild(RenderObject& child)
 {
-    RenderBlock::removeChild(child);
+    auto takenChild = RenderBlock::takeChild(child);
 
     // Positioned grid items do not take up space or otherwise participate in the layout of the grid,
     // for that reason we don't need to mark the grid as dirty when they are removed.
     if (child.isOutOfFlowPositioned())
-        return;
+        return takenChild;
 
     // The grid needs to be recomputed as it might contain auto-placed items that
     // will change their position.
     dirtyGrid();
+    return takenChild;
 }
 
 StyleSelfAlignmentData RenderGrid::selfAlignmentForChild(GridAxis axis, const RenderBox& child, const RenderStyle* gridStyle) const
index ca025e6..67b8e42 100644 (file)
@@ -79,8 +79,8 @@ private:
     bool isRenderGrid() const override { return true; }
     void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const override;
 
-    void addChild(RenderObject* newChild, RenderObject* beforeChild) final;
-    void removeChild(RenderObject&) final;
+    void addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild) final;
+    RenderPtr<RenderObject> takeChild(RenderObject&) final;
 
     StyleSelfAlignmentData selfAlignmentForChild(GridAxis, const RenderBox&, const RenderStyle* = nullptr) const;
     bool selfAlignmentChangedToStretch(GridAxis, const RenderStyle& oldStyle, const RenderStyle& newStyle, const RenderBox&) const;
index 72f805f..b054ca4 100644 (file)
@@ -270,14 +270,16 @@ LayoutRect RenderInline::localCaretRect(InlineBox* inlineBox, unsigned, LayoutUn
     return caretRect;
 }
 
-void RenderInline::addChild(RenderObject* newChild, RenderObject* beforeChild)
+void RenderInline::addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
     auto* beforeChildOrPlaceholder = beforeChild;
     if (auto* fragmentedFlow = enclosingFragmentedFlow())
         beforeChildOrPlaceholder = fragmentedFlow->resolveMovedChild(beforeChild);
-    if (continuation())
-        return addChildToContinuation(newChild, beforeChildOrPlaceholder);
-    return addChildIgnoringContinuation(newChild, beforeChildOrPlaceholder);
+    if (continuation()) {
+        addChildToContinuation(WTFMove(newChild), beforeChildOrPlaceholder);
+        return;
+    }
+    addChildIgnoringContinuation(WTFMove(newChild), beforeChildOrPlaceholder);
 }
 
 static RenderBoxModelObject* nextContinuation(RenderObject* renderer)
@@ -318,7 +320,7 @@ static bool newChildIsInline(const RenderObject& newChild, const RenderInline& p
     return newChild.isInline() | (parent.childRequiresTable(newChild) && parent.style().display() == INLINE);
 }
 
-void RenderInline::addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild)
+void RenderInline::addChildIgnoringContinuation(RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
     // Make sure we don't append things after :after-generated content if we have it.
     if (!beforeChild && isAfterContent(lastChild()))
@@ -338,17 +340,18 @@ void RenderInline::addChildIgnoringContinuation(RenderObject* newChild, RenderOb
         if (auto positionedAncestor = inFlowPositionedInlineAncestor(this))
             newStyle.setPosition(positionedAncestor->style().position());
 
-        RenderBlock* newBox = new RenderBlockFlow(document(), WTFMove(newStyle));
+        auto newBox = createRenderer<RenderBlockFlow>(document(), WTFMove(newStyle));
         newBox->initializeStyle();
         RenderBoxModelObject* oldContinuation = continuation();
-        setContinuation(newBox);
+        setContinuation(newBox.get());
 
-        splitFlow(beforeChild, newBox, newChild, oldContinuation);
+        splitFlow(beforeChild, WTFMove(newBox), WTFMove(newChild), oldContinuation);
         return;
     }
-    
-    RenderBoxModelObject::addChild(newChild, beforeChild);
-    newChild->setNeedsLayoutAndPrefWidthsRecalc();
+
+    auto& child = *newChild;
+    RenderBoxModelObject::addChild(WTFMove(newChild), beforeChild);
+    child.setNeedsLayoutAndPrefWidthsRecalc();
 }
 
 RenderPtr<RenderInline> RenderInline::clone() const
@@ -407,8 +410,8 @@ void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
             // FIXME: When the anonymous wrapper has multiple children, we end up traversing up to the topmost wrapper
             // every time, which is a bit wasteful.
         }
-        rendererToMove->parent()->removeChildInternal(*rendererToMove, NotifyChildren);
-        cloneInline->addChildIgnoringContinuation(rendererToMove);
+        auto childToMove = rendererToMove->parent()->takeChildInternal(*rendererToMove, NotifyChildren);
+        cloneInline->addChildIgnoringContinuation(WTFMove(childToMove));
         rendererToMove->setNeedsLayoutAndPrefWidthsRecalc();
         rendererToMove = nextSibling;
     }
@@ -435,7 +438,7 @@ void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
             cloneInline = downcast<RenderInline>(*current).clone();
 
             // Insert our child clone as the first child.
-            cloneInline->addChildIgnoringContinuation(cloneChild.leakPtr());
+            cloneInline->addChildIgnoringContinuation(WTFMove(cloneChild));
 
             // Hook the clone up as a continuation of |curr|.
             RenderInline& currentInline = downcast<RenderInline>(*current);
@@ -447,8 +450,8 @@ void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
             // *after* currentChild and append them all to the clone.
             for (auto* current = currentChild->nextSibling(); current;) {
                 auto* next = current->nextSibling();
-                currentInline.removeChildInternal(*current, NotifyChildren);
-                cloneInline->addChildIgnoringContinuation(current);
+                auto childToMove = currentInline.takeChildInternal(*current, NotifyChildren);
+                cloneInline->addChildIgnoringContinuation(WTFMove(childToMove));
                 current->setNeedsLayoutAndPrefWidthsRecalc();
                 current = next;
             }
@@ -465,27 +468,28 @@ void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
         cloneBlockChild.resetEnclosingFragmentedFlowAndChildInfoIncludingDescendants();
 
     // Now we are at the block level. We need to put the clone into the toBlock.
-    toBlock->insertChildInternal(cloneInline.leakPtr(), nullptr, NotifyChildren);
+    toBlock->insertChildInternal(WTFMove(cloneInline), nullptr, NotifyChildren);
 
     // Now take all the children after currentChild and remove them from the fromBlock
     // and put them in the toBlock.
     for (auto* current = currentChild->nextSibling(); current;) {
         auto* next = current->nextSibling();
-        fromBlock->removeChildInternal(*current, NotifyChildren);
-        toBlock->insertChildInternal(current, nullptr, NotifyChildren);
+        auto childToMove = fromBlock->takeChildInternal(*current, NotifyChildren);
+        toBlock->insertChildInternal(WTFMove(childToMove), nullptr, NotifyChildren);
         current = next;
     }
 }
 
-void RenderInline::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
-                             RenderObject* newChild, RenderBoxModelObject* oldCont)
+void RenderInline::splitFlow(RenderObject* beforeChild, RenderPtr<RenderBlock> newBlockBox, RenderPtr<RenderObject> newChild, RenderBoxModelObject* oldCont)
 {
+    auto& addedBlockBox = *newBlockBox;
     RenderBlock* pre = nullptr;
     RenderBlock* block = containingBlock();
-    
+
     // Delete our line boxes before we do the inline split into continuations.
     block->deleteLines();
-    
+
+    RenderPtr<RenderBlock> createdPre;
     bool madeNewBeforeBlock = false;
     if (block->isAnonymousBlock() && (!block->parent() || !block->parent()->createsAnonymousWrapper())) {
         // We can reuse this block and make it the preBlock of the next continuation.
@@ -499,17 +503,19 @@ void RenderInline::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox
         block = block->containingBlock();
     } else {
         // No anonymous block available for use.  Make one.
-        pre = block->createAnonymousBlock();
+        createdPre = block->createAnonymousBlock();
+        pre = createdPre.get();
         madeNewBeforeBlock = true;
     }
 
-    auto& post = downcast<RenderBlock>(*pre->createAnonymousBoxWithSameTypeAs(*block).release());
+    auto createdPost = pre->createAnonymousBoxWithSameTypeAs(*block);
+    auto& post = downcast<RenderBlock>(*createdPost);
 
     RenderObject* boxFirst = madeNewBeforeBlock ? block->firstChild() : pre->nextSibling();
-    if (madeNewBeforeBlock)
-        block->insertChildInternal(pre, boxFirst, NotifyChildren);
-    block->insertChildInternal(newBlockBox, boxFirst, NotifyChildren);
-    block->insertChildInternal(&post, boxFirst, NotifyChildren);
+    if (createdPre)
+        block->insertChildInternal(WTFMove(createdPre), boxFirst, NotifyChildren);
+    block->insertChildInternal(WTFMove(newBlockBox), boxFirst, NotifyChildren);
+    block->insertChildInternal(WTFMove(createdPost), boxFirst, NotifyChildren);
     block->setChildrenInline(false);
     
     if (madeNewBeforeBlock) {
@@ -517,22 +523,22 @@ void RenderInline::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox
         while (o) {
             RenderObject* no = o;
             o = no->nextSibling();
-            block->removeChildInternal(*no, NotifyChildren);
-            pre->insertChildInternal(no, nullptr, NotifyChildren);
+            auto childToMove = block->takeChildInternal(*no, NotifyChildren);
+            pre->insertChildInternal(WTFMove(childToMove), nullptr, NotifyChildren);
             no->setNeedsLayoutAndPrefWidthsRecalc();
         }
     }
 
-    splitInlines(pre, &post, newBlockBox, beforeChild, oldCont);
+    splitInlines(pre, &post, &addedBlockBox, beforeChild, oldCont);
 
     // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
     // time in makeChildrenNonInline by just setting this explicitly up front.
-    newBlockBox->setChildrenInline(false);
+    addedBlockBox.setChildrenInline(false);
 
     // We delayed adding the newChild until now so that the |newBlockBox| would be fully
     // connected, thus allowing newChild access to a renderArena should it need
     // to wrap itself in additional boxes (e.g., table construction).
-    newBlockBox->addChild(newChild);
+    addedBlockBox.addChild(WTFMove(newChild));
 
     // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
     // get deleted properly.  Because objects moves from the pre block into the post block, we want to
@@ -553,7 +559,7 @@ static bool canUseAsParentForContinuation(const RenderObject* renderer)
     return true;
 }
 
-void RenderInline::addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild)
+void RenderInline::addChildToContinuation(RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
     auto* flow = continuationBefore(beforeChild);
     // It may or may not be the direct parent of the beforeChild.
@@ -578,20 +584,20 @@ void RenderInline::addChildToContinuation(RenderObject* newChild, RenderObject*
         ASSERT_NOT_REACHED();
 
     if (newChild->isFloatingOrOutOfFlowPositioned())
-        return beforeChildAncestor->addChildIgnoringContinuation(newChild, beforeChild);
+        return beforeChildAncestor->addChildIgnoringContinuation(WTFMove(newChild), beforeChild);
 
     if (flow == beforeChildAncestor)
-        return flow->addChildIgnoringContinuation(newChild, beforeChild);
+        return flow->addChildIgnoringContinuation(WTFMove(newChild), beforeChild);
     // A continuation always consists of two potential candidates: an inline or an anonymous
     // block box holding block children.
     bool childInline = newChildIsInline(*newChild, *this);
     // The goal here is to match up if we can, so that we can coalesce and create the
     // minimal # of continuations needed for the inline.
     if (childInline == beforeChildAncestor->isInline())
-        return beforeChildAncestor->addChildIgnoringContinuation(newChild, beforeChild);
+        return beforeChildAncestor->addChildIgnoringContinuation(WTFMove(newChild), beforeChild);
     if (flow->isInline() == childInline)
-        return flow->addChildIgnoringContinuation(newChild); // Just treat like an append.
-    return beforeChildAncestor->addChildIgnoringContinuation(newChild, beforeChild);
+        return flow->addChildIgnoringContinuation(WTFMove(newChild)); // Just treat like an append.
+    return beforeChildAncestor->addChildIgnoringContinuation(WTFMove(newChild), beforeChild);
 }
 
 void RenderInline::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
@@ -1368,12 +1374,12 @@ void RenderInline::updateDragState(bool dragOn)
 void RenderInline::childBecameNonInline(RenderElement& child)
 {
     // We have to split the parent flow.
-    RenderBlock* newBox = containingBlock()->createAnonymousBlock();
+    auto newBox = containingBlock()->createAnonymousBlock();
     RenderBoxModelObject* oldContinuation = continuation();
-    setContinuation(newBox);
+    setContinuation(newBox.get());
     RenderObject* beforeChild = child.nextSibling();
-    removeChildInternal(child, NotifyChildren);
-    splitFlow(beforeChild, newBox, &child, oldContinuation);
+    auto removedChild = takeChildInternal(child, NotifyChildren);
+    splitFlow(beforeChild, WTFMove(newBox), WTFMove(removedChild), oldContinuation);
 }
 
 void RenderInline::updateHitTestResult(HitTestResult& result, const LayoutPoint& point)
index 7904e2f..46b40cd 100644 (file)
@@ -36,7 +36,7 @@ public:
     RenderInline(Element&, RenderStyle&&);
     RenderInline(Document&, RenderStyle&&);
 
-    void addChild(RenderObject* newChild, RenderObject* beforeChild = 0) override;
+    void addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild = 0) override;
 
     LayoutUnit marginLeft() const final;
     LayoutUnit marginRight() const final;
@@ -121,13 +121,11 @@ private:
     template<typename GeneratorContext>
     void generateCulledLineBoxRects(GeneratorContext& yield, const RenderInline* container) const;
 
-    void addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild);
-    void addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild = nullptr) final;
+    void addChildToContinuation(RenderPtr<RenderObject> newChild, RenderObject* beforeChild);
+    void addChildIgnoringContinuation(RenderPtr<RenderObject> newChild, RenderObject* beforeChild = nullptr) final;
 
-    void splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock, RenderBlock* middleBlock,
-                      RenderObject* beforeChild, RenderBoxModelObject* oldCont);
-    void splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
-                   RenderObject* newChild, RenderBoxModelObject* oldCont);
+    void splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock, RenderBlock* middleBlock, RenderObject* beforeChild, RenderBoxModelObject* oldCont);
+    void splitFlow(RenderObject* beforeChild, RenderPtr<RenderBlock> newBlockBox, RenderPtr<RenderObject> newChild, RenderBoxModelObject* oldCont);
 
     void layout() final { ASSERT_NOT_REACHED(); } // Do nothing for layout()
 
index bbcfce4..06ac234 100644 (file)
@@ -107,9 +107,10 @@ void RenderMenuList::createInnerBlock()
 
     // Create an anonymous block.
     ASSERT(!firstChild());
-    m_innerBlock = createAnonymousBlock();
+    auto newInnerBlock = createAnonymousBlock();
+    m_innerBlock = newInnerBlock.get();
     adjustInnerStyle();
-    RenderFlexibleBox::addChild(m_innerBlock);
+    RenderFlexibleBox::addChild(WTFMove(newInnerBlock));
 }
 
 void RenderMenuList::adjustInnerStyle()
@@ -171,23 +172,24 @@ HTMLSelectElement& RenderMenuList::selectElement() const
     return downcast<HTMLSelectElement>(nodeForNonAnonymous());
 }
 
-void RenderMenuList::addChild(RenderObject* newChild, RenderObject* beforeChild)
+void RenderMenuList::addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
     createInnerBlock();
-    m_innerBlock->addChild(newChild, beforeChild);
+    auto& child = *newChild;
+    m_innerBlock->addChild(WTFMove(newChild), beforeChild);
     ASSERT(m_innerBlock == firstChild());
 
     if (AXObjectCache* cache = document().existingAXObjectCache())
-        cache->childrenChanged(this, newChild);
+        cache->childrenChanged(this, &child);
 }
 
-void RenderMenuList::removeChild(RenderObject& oldChild)
+RenderPtr<RenderObject> RenderMenuList::takeChild(RenderObject& oldChild)
 {
     if (&oldChild == m_innerBlock || !m_innerBlock) {
-        RenderFlexibleBox::removeChild(oldChild);
         m_innerBlock = 0;
-    } else
-        m_innerBlock->removeChild(oldChild);
+        return RenderFlexibleBox::takeChild(oldChild);
+    }
+    return m_innerBlock->takeChild(oldChild);
 }
 
 void RenderMenuList::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
@@ -294,9 +296,11 @@ void RenderMenuList::setText(const String& s)
     if (m_buttonText)
         m_buttonText->setText(textToUse.impl(), true);
     else {
-        m_buttonText = new RenderText(document(), textToUse);
-        addChild(m_buttonText);
+        auto newButtonText = createRenderer<RenderText>(document(), textToUse);
+        m_buttonText = newButtonText.get();
+        addChild(WTFMove(newButtonText));
     }
+
     adjustInnerStyle();
 }
 
index eea015f..fa5a618 100644 (file)
@@ -66,8 +66,8 @@ private:
 
     bool isMenuList() const override { return true; }
 
-    void addChild(RenderObject* newChild, RenderObject* beforeChild = 0) override;
-    void removeChild(RenderObject&) override;
+    void addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild = 0) override;
+    RenderPtr<RenderObject> takeChild(RenderObject&) override;
     bool createsAnonymousWrapper() const override { return true; }
 
     void updateFromElement() override;
index 2fbf79e..4a9d9d5 100644 (file)
@@ -184,11 +184,11 @@ void RenderMultiColumnFlow::evacuateAndDestroy()
     SpannerMap::iterator it;
     while ((it = m_spannerMap.begin()) != m_spannerMap.end()) {
         RenderBox* spanner = it->key;
-        multicolContainer->removeChild(*spanner);
+        auto takenSpanner = multicolContainer->takeChild(*spanner);
         ASSERT(it->value.get());
         if (RenderMultiColumnSpannerPlaceholder* placeholder = it->value.get()) {
             RenderBlockFlow& originalContainer = downcast<RenderBlockFlow>(*placeholder->parent());
-            originalContainer.addChild(spanner, placeholder);
+            originalContainer.addChild(WTFMove(takenSpanner), placeholder);
             placeholder->destroy();
         }
         m_spannerMap.remove(it);
@@ -348,14 +348,14 @@ RenderObject* RenderMultiColumnFlow::processPossibleSpannerDescendant(RenderObje
         // 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,
-            downcast<RenderBox>(descendant), &container->style());
-        container->addChild(placeholder, descendant.nextSibling());
-        container->removeChild(descendant);
+        auto newPlaceholder = RenderMultiColumnSpannerPlaceholder::createAnonymous(this, downcast<RenderBox>(descendant), &container->style());
+        auto& placeholder = *newPlaceholder;
+        container->addChild(WTFMove(newPlaceholder), descendant.nextSibling());
+        auto takenDescendant = container->takeChild(descendant);
         
         // This is a guard to stop an ancestor flow thread from processing the spanner.
         gShiftingSpanner = true;
-        multicolContainer->RenderBlock::addChild(&descendant, insertBeforeMulticolChild);
+        multicolContainer->RenderBlock::addChild(WTFMove(takenDescendant), insertBeforeMulticolChild);
         gShiftingSpanner = false;
         
         // The spanner has now been moved out from the flow thread, but we don't want to
@@ -363,8 +363,8 @@ RenderObject* RenderMultiColumnFlow::processPossibleSpannerDescendant(RenderObje
         // 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;
+            subtreeRoot = &placeholder;
+        nextDescendant = &placeholder;
     } else {
         // This is regular multicol content, i.e. not part of a spanner.
         if (is<RenderMultiColumnSpannerPlaceholder>(nextRendererInFragmentedFlow)) {
@@ -389,15 +389,16 @@ RenderObject* RenderMultiColumnFlow::processPossibleSpannerDescendant(RenderObje
     // 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));
+    auto newSet = createRenderer<RenderMultiColumnSet>(*this, RenderStyle::createAnonymousStyleWithDisplay(multicolContainer->style(), BLOCK));
     newSet->initializeStyle();
-    multicolContainer->RenderBlock::addChild(newSet, insertBeforeMulticolChild);
+    auto& set = *newSet;
+    multicolContainer->RenderBlock::addChild(WTFMove(newSet), insertBeforeMulticolChild);
     invalidateFragments();
 
     // 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());
+    ASSERT_UNUSED(set, !previousColumnSetOrSpannerSiblingOf(&set) || !previousColumnSetOrSpannerSiblingOf(&set)->isRenderMultiColumnSet());
+    ASSERT(!nextColumnSetOrSpannerSiblingOf(&set) || !nextColumnSetOrSpannerSiblingOf(&set)->isRenderMultiColumnSet());
     
     return nextDescendant;
 }
@@ -428,7 +429,11 @@ void RenderMultiColumnFlow::fragmentedFlowDescendantInserted(RenderObject& newDe
                 // We have to nuke the placeholder, since the ancestor already lost the mapping to it when
                 // we shifted the placeholder down into this flow thread.
                 placeholder.fragmentedFlow()->m_spannerMap.remove(spanner);
-                placeholder.parent()->removeChild(placeholder);
+
+                auto takenChild = placeholder.parent()->takeChild(placeholder);
+                // FIXME: Memory management.
+                auto* leakenPtr = takenChild.leakPtr();
+                UNUSED_PARAM(leakenPtr);
 
                 if (subtreeRoot == descendant)
                     subtreeRoot = spanner;
@@ -450,7 +455,11 @@ void RenderMultiColumnFlow::handleSpannerRemoval(RenderObject& spanner)
 {
     // The placeholder may already have been removed, but if it hasn't, do so now.
     if (RenderMultiColumnSpannerPlaceholder* placeholder = m_spannerMap.get(&downcast<RenderBox>(spanner)).get()) {
-        placeholder->parent()->removeChild(*placeholder);
+        auto takenChild = placeholder->parent()->takeChild(*placeholder);
+        // FIXME: Memory management.
+        auto* leakenPtr = takenChild.leakPtr();
+        UNUSED_PARAM(leakenPtr);
+
         m_spannerMap.remove(&downcast<RenderBox>(spanner));
     }
 
index c512377..f6ebf28 100644 (file)
 
 namespace WebCore {
 
-RenderMultiColumnSpannerPlaceholder* RenderMultiColumnSpannerPlaceholder::createAnonymous(RenderMultiColumnFlow* fragmentedFlow, RenderBox& spanner, const RenderStyle* parentStyle)
+RenderPtr<RenderMultiColumnSpannerPlaceholder> RenderMultiColumnSpannerPlaceholder::createAnonymous(RenderMultiColumnFlow* fragmentedFlow, RenderBox& spanner, const RenderStyle* parentStyle)
 {
     auto newStyle = RenderStyle::createAnonymousStyleWithDisplay(*parentStyle, BLOCK);
     newStyle.setClear(CBOTH); // We don't want floats in the row preceding the spanner to continue on the other side.
-    auto placeholder = new RenderMultiColumnSpannerPlaceholder(fragmentedFlow, spanner, WTFMove(newStyle));
+    auto placeholder = createRenderer<RenderMultiColumnSpannerPlaceholder>(fragmentedFlow, spanner, WTFMove(newStyle));
     placeholder->initializeStyle();
     return placeholder;
 }
index 8daca26..40511e7 100644 (file)
@@ -37,12 +37,14 @@ class RenderMultiColumnFlow;
 
 class RenderMultiColumnSpannerPlaceholder final : public RenderBox {
 public:
-    static RenderMultiColumnSpannerPlaceholder* createAnonymous(RenderMultiColumnFlow*, RenderBox& spanner, const RenderStyle* parentStyle);
+    static RenderPtr<RenderMultiColumnSpannerPlaceholder> createAnonymous(RenderMultiColumnFlow*, RenderBox& spanner, const RenderStyle* parentStyle);
 
     RenderBox* spanner() const { return m_spanner; }
     RenderMultiColumnFlow* fragmentedFlow() const { return m_fragmentedFlow; }
 
 private:
+    template<class T, class... Args> friend RenderPtr<T> createRenderer(Args&&...);
+
     RenderMultiColumnSpannerPlaceholder(RenderMultiColumnFlow*, RenderBox& spanner, RenderStyle&&);
     bool isRenderMultiColumnSpannerPlaceholder() const override { return true; }
 
index 6147384..8bbc289 100644 (file)
@@ -241,10 +241,10 @@ void RenderObject::setParent(RenderElement* parent)
     m_parent = parent;
 }
 
-void RenderObject::removeFromParent()
+void RenderObject::removeFromParentAndDestroy()
 {
-    if (parent())
-        parent()->removeChild(*this);
+    ASSERT(m_parent);
+    m_parent->removeAndDestroyChild(*this);
 }
 
 RenderObject* RenderObject::nextInPreOrder() const
@@ -1428,7 +1428,12 @@ void RenderObject::willBeDestroyed()
     if (AXObjectCache* cache = document().existingAXObjectCache())
         cache->childrenChanged(this->parent());
 
-    removeFromParent();
+    if (m_parent) {
+        // FIXME: We should have always been removed from the parent before being destroyed.
+        auto takenThis = m_parent->takeChild(*this);
+        auto* leakedPtr = takenThis.leakPtr();
+        UNUSED_PARAM(leakedPtr);
+    }
 
     ASSERT(renderTreeBeingDestroyed() || !is<RenderElement>(*this) || !view().frameView().hasSlowRepaintObject(downcast<RenderElement>(*this)));
 
@@ -1498,6 +1503,7 @@ void RenderObject::destroyAndCleanupAnonymousWrappers()
 
 void RenderObject::destroy()
 {
+    ASSERT(!m_bitfields.beingDestroyed());
     m_bitfields.setBeingDestroyed(true);
 
 #if PLATFORM(IOS)
index 5792c92..39aa741 100644 (file)
@@ -752,7 +752,7 @@ public:
     void imageChanged(CachedImage*, const IntRect* = nullptr) override;
     virtual void imageChanged(WrappedImagePtr, const IntRect* = nullptr) { }
 
-    void removeFromParent();
+    void removeFromParentAndDestroy();
 
     CSSAnimationController& animation() const;
 
index ae14fd9..5abcc96 100644 (file)
@@ -361,7 +361,7 @@ void RenderQuote::updateTextRenderer()
         renderText->dirtyLineBoxes(false);
         return;
     }
-    addChild(new RenderTextFragment(document(), m_text));
+    addChild(createRenderer<RenderTextFragment>(document(), m_text));
 }
 
 String RenderQuote::computeText() const
index 3cf9c6e..d53f74a 100644 (file)
@@ -96,9 +96,9 @@ static inline RenderBlock* rubyAfterBlock(const RenderElement* ruby)
     return isRubyAfterBlock(child) ? downcast<RenderBlock>(child) : nullptr;
 }
 
-static RenderBlock* createAnonymousRubyInlineBlock(RenderObject& ruby)
+static auto createAnonymousRubyInlineBlock(RenderObject& ruby)
 {
-    RenderBlock* newBlock = new RenderBlockFlow(ruby.document(), RenderStyle::createAnonymousStyleWithDisplay(ruby.style(), INLINE_BLOCK));
+    auto newBlock = createRenderer<RenderBlockFlow>(ruby.document(), RenderStyle::createAnonymousStyleWithDisplay(ruby.style(), INLINE_BLOCK));
     newBlock->initializeStyle();
     return newBlock;
 }
@@ -137,43 +137,45 @@ void RenderRubyAsInline::styleDidChange(StyleDifference diff, const RenderStyle*
     propagateStyleToAnonymousChildren(PropagateToAllChildren);
 }
 
-void RenderRubyAsInline::addChild(RenderObject* child, RenderObject* beforeChild)
+void RenderRubyAsInline::addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild)
 {
     // Insert :before and :after content before/after the RenderRubyRun(s)
     if (child->isBeforeContent()) {
         if (child->isInline()) {
             // Add generated inline content normally
-            RenderInline::addChild(child, firstChild());
+            RenderInline::addChild(WTFMove(child), firstChild());
         } else {
             // Wrap non-inline content with an anonymous inline-block.
             RenderBlock* beforeBlock = rubyBeforeBlock(this);
             if (!beforeBlock) {
-                beforeBlock = createAnonymousRubyInlineBlock(*this);
-                RenderInline::addChild(beforeBlock, firstChild());
+                auto newBlock = createAnonymousRubyInlineBlock(*this);
+                beforeBlock = newBlock.get();
+                RenderInline::addChild(WTFMove(newBlock), firstChild());
             }
-            beforeBlock->addChild(child);
+            beforeBlock->addChild(WTFMove(child));
         }
         return;
     }
     if (child->isAfterContent()) {
         if (child->isInline()) {
             // Add generated inline content normally
-            RenderInline::addChild(child);
+            RenderInline::addChild(WTFMove(child));
         } else {
             // Wrap non-inline content with an anonymous inline-block.
             RenderBlock* afterBlock = rubyAfterBlock(this);
             if (!afterBlock) {
-                afterBlock = createAnonymousRubyInlineBlock(*this);
-                RenderInline::addChild(afterBlock);
+                auto newBlock = createAnonymousRubyInlineBlock(*this);
+                afterBlock = newBlock.get();
+                RenderInline::addChild(WTFMove(newBlock));
             }
-            afterBlock->addChild(child);
+            afterBlock->addChild(WTFMove(child));
         }
         return;
     }
 
     // If the child is a ruby run, just add it normally.
     if (child->isRubyRun()) {
-        RenderInline::addChild(child, beforeChild);
+        RenderInline::addChild(WTFMove(child), beforeChild);
         return;
     }
 
@@ -184,7 +186,7 @@ void RenderRubyAsInline::addChild(RenderObject* child, RenderObject* beforeChild
         while (run && !run->isRubyRun())
             run = run->parent();
         if (run) {
-            run->addChild(child, beforeChild);
+            run->addChild(WTFMove(child), beforeChild);
             return;
         }
         ASSERT_NOT_REACHED(); // beforeChild should always have a run as parent!
@@ -196,13 +198,14 @@ void RenderRubyAsInline::addChild(RenderObject* child, RenderObject* beforeChild
     // (The RenderRubyRun object will handle the details)
     RenderRubyRun* lastRun = lastRubyRun(this);
     if (!lastRun || lastRun->hasRubyText()) {
-        lastRun = RenderRubyRun::staticCreateRubyRun(this);
-        RenderInline::addChild(lastRun, beforeChild);
+        auto newRun = RenderRubyRun::staticCreateRubyRun(this);
+        lastRun = newRun.get();
+        RenderInline::addChild(WTFMove(newRun), beforeChild);
     }
-    lastRun->addChild(child);
+    lastRun->addChild(WTFMove(child));
 }
 
-void RenderRubyAsInline::removeChild(RenderObject& child)
+RenderPtr<RenderObject> RenderRubyAsInline::takeChild(RenderObject& child)
 {
     // If the child's parent is *this (must be a ruby run or generated content or anonymous block),
     // just use the normal remove method.
@@ -210,20 +213,20 @@ void RenderRubyAsInline::removeChild(RenderObject& child)
 #ifndef ASSERT_DISABLED
         ASSERT(isRubyChildForNormalRemoval(child));
 #endif
-        RenderInline::removeChild(child);
-        return;
+        return RenderInline::takeChild(child);
     }
     // If the child's parent is an anoymous block (must be generated :before/:after content)
     // just use the block's remove method.
     if (isAnonymousRubyInlineBlock(child.parent())) {
         ASSERT(child.isBeforeContent() || child.isAfterContent());
-        child.parent()->removeChild(child);
-        removeChild(*child.parent());
-        return;
+        auto& parent = *child.parent();
+        auto takenChild = parent.takeChild(child);
+        parent.removeFromParentAndDestroy();
+        return takenChild;
     }
 
     // Otherwise find the containing run and remove it from there.
-    findRubyRunParent(child).removeChild(child);
+    return findRubyRunParent(child).takeChild(child);
 }
 
 //=== ruby as block object ===
@@ -243,43 +246,45 @@ void RenderRubyAsBlock::styleDidChange(StyleDifference diff, const RenderStyle*
     propagateStyleToAnonymousChildren(PropagateToAllChildren);
 }
 
-void RenderRubyAsBlock::addChild(RenderObject* child, RenderObject* beforeChild)
+void RenderRubyAsBlock::addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild)
 {
     // Insert :before and :after content before/after the RenderRubyRun(s)
     if (child->isBeforeContent()) {
         if (child->isInline()) {
             // Add generated inline content normally
-            RenderBlockFlow::addChild(child, firstChild());
+            RenderBlockFlow::addChild(WTFMove(child), firstChild());
         } else {
             // Wrap non-inline content with an anonymous inline-block.
             RenderBlock* beforeBlock = rubyBeforeBlock(this);
             if (!beforeBlock) {
-                beforeBlock = createAnonymousRubyInlineBlock(*this);
-                RenderBlockFlow::addChild(beforeBlock, firstChild());
+                auto newBlock = createAnonymousRubyInlineBlock(*this);
+                beforeBlock = newBlock.get();
+                RenderBlockFlow::addChild(WTFMove(newBlock), firstChild());
             }
-            beforeBlock->addChild(child);
+            beforeBlock->addChild(WTFMove(child));
         }
         return;
     }
     if (child->isAfterContent()) {
         if (child->isInline()) {
             // Add generated inline content normally
-            RenderBlockFlow::addChild(child);
+            RenderBlockFlow::addChild(WTFMove(child));
         } else {
             // Wrap non-inline content with an anonymous inline-block.
             RenderBlock* afterBlock = rubyAfterBlock(this);
             if (!afterBlock) {
-                afterBlock = createAnonymousRubyInlineBlock(*this);
-                RenderBlockFlow::addChild(afterBlock);
+                auto newBlock = createAnonymousRubyInlineBlock(*this);
+                afterBlock = newBlock.get();
+                RenderBlockFlow::addChild(WTFMove(newBlock));
             }
-            afterBlock->addChild(child);
+            afterBlock->addChild(WTFMove(child));
         }
         return;
     }
 
     // If the child is a ruby run, just add it normally.
     if (child->isRubyRun()) {
-        RenderBlockFlow::addChild(child, beforeChild);
+        RenderBlockFlow::addChild(WTFMove(child), beforeChild);
         return;
     }
 
@@ -290,7 +295,7 @@ void RenderRubyAsBlock::addChild(RenderObject* child, RenderObject* beforeChild)
         while (run && !run->isRubyRun())
             run = run->parent();
         if (run) {
-            run->addChild(child, beforeChild);
+            run->addChild(WTFMove(child), beforeChild);
             return;
         }
         ASSERT_NOT_REACHED(); // beforeChild should always have a run as parent!
@@ -302,13 +307,14 @@ void RenderRubyAsBlock::addChild(RenderObject* child, RenderObject* beforeChild)
     // (The RenderRubyRun object will handle the details)
     RenderRubyRun* lastRun = lastRubyRun(this);
     if (!lastRun || lastRun->hasRubyText()) {
-        lastRun = RenderRubyRun::staticCreateRubyRun(this);
-        RenderBlockFlow::addChild(lastRun, beforeChild);
+        auto newRun = RenderRubyRun::staticCreateRubyRun(this);
+        lastRun = newRun.get();
+        RenderBlockFlow::addChild(WTFMove(newRun), beforeChild);
     }
-    lastRun->addChild(child);
+    lastRun->addChild(WTFMove(child));
 }
 
-void RenderRubyAsBlock::removeChild(RenderObject& child)
+RenderPtr<RenderObject> RenderRubyAsBlock::takeChild(RenderObject& child)
 {
     // If the child's parent is *this (must be a ruby run or generated content or anonymous block),
     // just use the normal remove method.
@@ -316,20 +322,20 @@ void RenderRubyAsBlock::removeChild(RenderObject& child)
 #ifndef ASSERT_DISABLED
         ASSERT(isRubyChildForNormalRemoval(child));
 #endif
-        RenderBlockFlow::removeChild(child);
-        return;
+        return RenderBlockFlow::takeChild(child);
     }
     // If the child's parent is an anoymous block (must be generated :before/:after content)
     // just use the block's remove method.
     if (isAnonymousRubyInlineBlock(child.parent())) {
         ASSERT(child.isBeforeContent() || child.isAfterContent());
-        child.parent()->removeChild(child);
-        removeChild(*child.parent());
-        return;
+        auto& parent = *child.parent();
+        auto takenChild = parent.takeChild(child);
+        parent.removeFromParentAndDestroy();
+        return takenChild;
     }
 
     // Otherwise find the containing run and remove it from there.
-    findRubyRunParent(child).removeChild(child);
+    return findRubyRunParent(child).takeChild(child);
 }
 
 } // namespace WebCore
index e6550fa..ce74193 100644 (file)
@@ -55,8 +55,8 @@ public:
     RenderRubyAsInline(Element&, RenderStyle&&);
     virtual ~RenderRubyAsInline();
 
-    void addChild(RenderObject* child, RenderObject* beforeChild = 0) override;
-    void removeChild(RenderObject& child) override;
+    void addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild = 0) override;
+    RenderPtr<RenderObject> takeChild(RenderObject& child) override;
 
 protected:
     void styleDidChange(StyleDifference, const RenderStyle* oldStyle) override;
@@ -75,8 +75,8 @@ public:
 
     Element& element() const { return downcast<Element>(nodeForNonAnonymous()); }
 
-    void addChild(RenderObject* child, RenderObject* beforeChild = 0) override;
-    void removeChild(RenderObject& child) override;
+    void addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild = 0) override;
+    RenderPtr<RenderObject> takeChild(RenderObject& child) override;
 
 protected:
     void styleDidChange(StyleDifference, const RenderStyle* oldStyle) override;
index d3ebe98..a7c00c8 100644 (file)
@@ -96,8 +96,9 @@ void RenderRubyBase::moveInlineChildren(RenderRubyBase* toBase, RenderObject* be
         if (lastChild && lastChild->isAnonymousBlock() && lastChild->childrenInline())
             toBlock = downcast<RenderBlock>(lastChild);
         else {
-            toBlock = toBase->createAnonymousBlock();
-            toBase->insertChildInternal(toBlock, nullptr, NotifyChildren);
+            auto newToBlock = toBase->createAnonymousBlock();
+            toBlock = newToBlock.get();
+            toBase->insertChildInternal(WTFMove(newToBlock), nullptr, NotifyChildren);
         }
     }
     // Move our inline children into the target block we determined above.
index 0ffb243..801cd0e 100644 (file)
@@ -90,8 +90,9 @@ RenderRubyBase* RenderRubyRun::rubyBaseSafe()
 {
     RenderRubyBase* base = rubyBase();
     if (!base) {
-        base = createRubyBase();
-        RenderBlockFlow::addChild(base);
+        auto newBase = createRubyBase();
+        base = newBase.get();
+        RenderBlockFlow::addChild(WTFMove(newBase));
     }
     return base;
 }
@@ -106,7 +107,7 @@ bool RenderRubyRun::isChildAllowed(const RenderObject& child, const RenderStyle&
     return child.isInline() || child.isRubyText();
 }
 
-void RenderRubyRun::addChild(RenderObject* child, RenderObject* beforeChild)
+void RenderRubyRun::addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild)
 {
     ASSERT(child);
 
@@ -115,7 +116,7 @@ void RenderRubyRun::addChild(RenderObject* child, RenderObject* beforeChild)
             // RenderRuby has already ascertained that we can add the child here.
             ASSERT(!hasRubyText());
             // prepend ruby texts as first child
-            RenderBlockFlow::addChild(child, firstChild());
+            RenderBlockFlow::addChild(WTFMove(child), firstChild());
         }  else if (beforeChild->isRubyText()) {
             // New text is inserted just before another.
             // In this case the new text takes the place of the old one, and
@@ -123,34 +124,35 @@ void RenderRubyRun::addChild(RenderObject* child, RenderObject* beforeChild)
             ASSERT(beforeChild->parent() == this);
             RenderElement* ruby = parent();
             ASSERT(isRuby(ruby));
-            RenderBlock* newRun = staticCreateRubyRun(ruby);
-            ruby->addChild(newRun, nextSibling());
+            auto newRun = staticCreateRubyRun(ruby);
+            ruby->addChild(WTFMove(newRun), nextSibling());
             // Add the new ruby text and move the old one to the new run
             // Note: Doing it in this order and not using RenderRubyRun's methods,
             // in order to avoid automatic removal of the ruby run in case there is no
             // other child besides the old ruby text.
-            RenderBlockFlow::addChild(child, beforeChild);
-            RenderBlockFlow::removeChild(*beforeChild);
-            newRun->addChild(beforeChild);
+            RenderBlockFlow::addChild(WTFMove(child), beforeChild);
+            auto takenBeforeChild = RenderBlockFlow::takeChild(*beforeChild);
+            newRun->addChild(WTFMove(takenBeforeChild));
         } else if (hasRubyBase()) {
             // Insertion before a ruby base object.
             // In this case we need insert a new run before the current one and split the base.
             RenderElement* ruby = parent();
-            RenderRubyRun* newRun = staticCreateRubyRun(ruby);
-            ruby->addChild(newRun, this);
-            newRun->addChild(child);
-            rubyBaseSafe()->moveChildren(newRun->rubyBaseSafe(), beforeChild);
+            auto newRun = staticCreateRubyRun(ruby);
+            auto& run = *newRun;
+            ruby->addChild(WTFMove(newRun), this);
+            run.addChild(WTFMove(child));
+            rubyBaseSafe()->moveChildren(run.rubyBaseSafe(), beforeChild);
         }
     } else {
         // child is not a text -> insert it into the base
         // (append it instead if beforeChild is the ruby text)
         if (beforeChild && beforeChild->isRubyText())
             beforeChild = 0;
-        rubyBaseSafe()->addChild(child, beforeChild);
+        rubyBaseSafe()->addChild(WTFMove(child), beforeChild);
     }
 }
 
-void RenderRubyRun::removeChild(RenderObject& child)
+RenderPtr<RenderObject> RenderRubyRun::takeChild(RenderObject& child)
 {
     // If the child is a ruby text, then merge the ruby base with the base of
     // the right sibling run, if possible.
@@ -172,39 +174,39 @@ void RenderRubyRun::removeChild(RenderObject& child)
         }
     }
 
-    RenderBlockFlow::removeChild(child);
+    auto takenChild = RenderBlockFlow::takeChild(child);
 
     if (!beingDestroyed() && !renderTreeBeingDestroyed()) {
         // Check if our base (if any) is now empty. If so, destroy it.
         RenderBlock* base = rubyBase();
         if (base && !base->firstChild()) {
-            RenderBlockFlow::removeChild(*base);
+            auto takenBase = RenderBlockFlow::takeChild(*base);
             base->deleteLines();
-            base->destroy();
         }
 
         // If any of the above leaves the run empty, destroy it as well.
         if (!hasRubyText() && !hasRubyBase()) {
-            parent()->removeChild(*this);
+            auto takenThis = parent()->takeChild(*this);
             deleteLines();
-            destroy();
         }
     }
+
+    return takenChild;
 }
 
-RenderRubyBase* RenderRubyRun::createRubyBase() const
+RenderPtr<RenderRubyBase> RenderRubyRun::createRubyBase() const
 {
     auto newStyle = RenderStyle::createAnonymousStyleWithDisplay(style(), BLOCK);
     newStyle.setTextAlign(CENTER); // FIXME: use WEBKIT_CENTER?
-    auto renderer = new RenderRubyBase(document(), WTFMove(newStyle));
+    auto renderer = createRenderer<RenderRubyBase>(document(), WTFMove(newStyle));
     renderer->initializeStyle();
     return renderer;
 }
 
-RenderRubyRun* RenderRubyRun::staticCreateRubyRun(const RenderObject* parentRuby)
+RenderPtr<RenderRubyRun> RenderRubyRun::staticCreateRubyRun(const RenderObject* parentRuby)
 {
     ASSERT(isRuby(parentRuby));
-    auto renderer = new RenderRubyRun(parentRuby->document(), RenderStyle::createAnonymousStyleWithDisplay(parentRuby->style(), INLINE_BLOCK));
+    auto renderer = createRenderer<RenderRubyRun>(parentRuby->document(), RenderStyle::createAnonymousStyleWithDisplay(parentRuby->style(), INLINE_BLOCK));
     renderer->initializeStyle();
     return renderer;
 }
index de69e95..1c86941 100644 (file)
@@ -56,14 +56,14 @@ public:
     void layoutBlock(bool relayoutChildren, LayoutUnit pageHeight = 0) override;
 
     bool isChildAllowed(const RenderObject&, const RenderStyle&) const override;
-    void addChild(RenderObject* child, RenderObject* beforeChild = 0) override;
-    void removeChild(RenderObject&) override;
+    void addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild = 0) override;
+    RenderPtr<RenderObject> takeChild(RenderObject&) override;
 
     RenderBlock* firstLineBlock() const override;
 
     void getOverhang(bool firstLine, RenderObject* startRenderer, RenderObject* endRenderer, float& startOverhang, float& endOverhang) const;
 
-    static RenderRubyRun* staticCreateRubyRun(const RenderObject* parentRuby);
+    static RenderPtr<RenderRubyRun> staticCreateRubyRun(const RenderObject* parentRuby);
     
     void updatePriorContextFromCachedBreakIterator(LazyLineBreakIterator&) const;
     void setCachedPriorCharacters(UChar last, UChar secondToLast)
@@ -74,7 +74,7 @@ public:
     bool canBreakBefore(const LazyLineBreakIterator&) const;
     
 protected:
-    RenderRubyBase* createRubyBase() const;
+    RenderPtr<RenderRubyBase> createRubyBase() const;
 
 private:
     bool isRubyRun() const override { return true; }
index 723ed59..a6916a7 100644 (file)
@@ -136,7 +136,7 @@ static inline void resetSectionPointerIfNotBefore(RenderTableSection*& ptr, Rend
         ptr = 0;
 }
 
-void RenderTable::addChild(RenderObject* child, RenderObject* beforeChild)
+void RenderTable::addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild)
 {
     bool wrapInAnonymousSection = !child->isOutOfFlowPositioned();
 
@@ -150,18 +150,18 @@ void RenderTable::addChild(RenderObject* child, RenderObject* beforeChild)
             case TABLE_HEADER_GROUP:
                 resetSectionPointerIfNotBefore(m_head, beforeChild);
                 if (!m_head) {
-                    m_head = downcast<RenderTableSection>(child);
+                    m_head = downcast<RenderTableSection>(child.get());
                 } else {
                     resetSectionPointerIfNotBefore(m_firstBody, beforeChild);
                     if (!m_firstBody) 
-                        m_firstBody = downcast<RenderTableSection>(child);
+                        m_firstBody = downcast<RenderTableSection>(child.get());
                 }
                 wrapInAnonymousSection = false;
                 break;
             case TABLE_FOOTER_GROUP:
                 resetSectionPointerIfNotBefore(m_foot, beforeChild);
                 if (!m_foot) {
-                    m_foot = downcast<RenderTableSection>(child);
+                    m_foot = downcast<RenderTableSection>(child.get());
                     wrapInAnonymousSection = false;
                     break;
                 }
@@ -169,7 +169,7 @@ void RenderTable::addChild(RenderObject* child, RenderObject* beforeChild)
             case TABLE_ROW_GROUP:
                 resetSectionPointerIfNotBefore(m_firstBody, beforeChild);
                 if (!m_firstBody)
-                    m_firstBody = downcast<RenderTableSection>(child);
+                    m_firstBody = downcast<RenderTableSection>(child.get());
                 wrapInAnonymousSection = false;
                 break;
             default:
@@ -187,19 +187,19 @@ void RenderTable::addChild(RenderObject* child, RenderObject* beforeChild)
         if (beforeChild && beforeChild->parent() != this)
             beforeChild = splitAnonymousBoxesAroundChild(beforeChild);
 
-        RenderBox::addChild(child, beforeChild);
+        RenderBox::addChild(WTFMove(child), beforeChild);
         return;
     }
 
     if (!beforeChild && is<RenderTableSection>(lastChild()) && lastChild()->isAnonymous() && !lastChild()->isBeforeContent()) {
-        downcast<RenderTableSection>(*lastChild()).addChild(child);
+        downcast<RenderTableSection>(*lastChild()).addChild(WTFMove(child));
         return;
     }
 
     if (beforeChild && !beforeChild->isAnonymous() && beforeChild->parent() == this) {
         RenderObject* section = beforeChild->previousSibling();
         if (is<RenderTableSection>(section) && section->isAnonymous()) {
-            downcast<RenderTableSection>(*section).addChild(child);
+            downcast<RenderTableSection>(*section).addChild(WTFMove(child));
             return;
         }
     }
@@ -211,16 +211,17 @@ void RenderTable::addChild(RenderObject* child, RenderObject* beforeChild)
         RenderTableSection& section = downcast<RenderTableSection>(*lastBox);
         if (beforeChild == &section)
             beforeChild = section.firstRow();
-        section.addChild(child, beforeChild);
+        section.addChild(WTFMove(child), beforeChild);
         return;
     }
 
     if (beforeChild && !is<RenderTableSection>(*beforeChild) && beforeChild->style().display() != TABLE_CAPTION && beforeChild->style().display() != TABLE_COLUMN_GROUP)
         beforeChild = nullptr;
 
-    auto section = RenderTableSection::createAnonymousWithParentRenderer(*this).release();
-    addChild(section, beforeChild);
-    section->addChild(child);
+    auto newSection = RenderTableSection::createAnonymousWithParentRenderer(*this);
+    auto& section = *newSection;
+    addChild(WTFMove(newSection), beforeChild);
+    section.addChild(WTFMove(child));
 }
 
 void RenderTable::addCaption(const RenderTableCaption* caption)
@@ -1577,14 +1578,14 @@ bool RenderTable::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
     return false;
 }
 
-std::unique_ptr<RenderTable> RenderTable::createTableWithStyle(Document& document, const RenderStyle& style)
+RenderPtr<RenderTable> RenderTable::createTableWithStyle(Document& document, const RenderStyle& style)
 {
-    auto table = std::make_unique<RenderTable>(document, RenderStyle::createAnonymousStyleWithDisplay(style, style.display() == INLINE ? INLINE_TABLE : TABLE));
+    auto table = createRenderer<RenderTable>(document, RenderStyle::createAnonymousStyleWithDisplay(style, style.display() == INLINE ? INLINE_TABLE : TABLE));
     table->initializeStyle();
     return table;
 }
 
-std::unique_ptr<RenderTable> RenderTable::createAnonymousWithParentRenderer(const RenderElement& parent)
+RenderPtr<RenderTable> RenderTable::createAnonymousWithParentRenderer(const RenderElement& parent)
 {
     return RenderTable::createTableWithStyle(parent.document(), parent.style());
 }
index fbd436e..3c8bdc5 100644 (file)
@@ -126,7 +126,7 @@ public:
     LayoutUnit calcBorderEnd() const;
     void recalcBordersInRowDirection();
 
-    void addChild(RenderObject* child, RenderObject* beforeChild = 0) final;
+    void addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild = 0) final;
 
     struct ColumnStruct {
         explicit ColumnStruct(unsigned initialSpan = 1)
@@ -250,8 +250,8 @@ public:
             recalcSections();
     }
 
-    static std::unique_ptr<RenderTable> createAnonymousWithParentRenderer(const RenderElement&);
-    std::unique_ptr<RenderBox> createAnonymousBoxWithSameTypeAs(const RenderBox& renderer) const override;
+    static RenderPtr<RenderTable> createAnonymousWithParentRenderer(const RenderElement&);
+    RenderPtr<RenderBox> createAnonymousBoxWithSameTypeAs(const RenderBox& renderer) const override;
 
     const BorderValue& tableStartBorderAdjoiningCell(const RenderTableCell&) const;
     const BorderValue& tableEndBorderAdjoiningCell(const RenderTableCell&) const;
@@ -273,7 +273,7 @@ protected:
     void simplifiedNormalFlowLayout() final;
 
 private:
-    static std::unique_ptr<RenderTable> createTableWithStyle(Document&, const RenderStyle&);
+    static RenderPtr<RenderTable> createTableWithStyle(Document&, const RenderStyle&);
 
     const char* renderName() const override { return "RenderTable"; }
 
@@ -380,7 +380,7 @@ inline RenderTableSection* RenderTable::topSection() const
 
 inline bool isDirectionSame(const RenderBox* tableItem, const RenderBox* otherTableItem) { return tableItem && otherTableItem ? tableItem->style().direction() == otherTableItem->style().direction() : true; }
 
-inline std::unique_ptr<RenderBox> RenderTable::createAnonymousBoxWithSameTypeAs(const RenderBox& renderer) const
+inline RenderPtr<RenderBox> RenderTable::createAnonymousBoxWithSameTypeAs(const RenderBox& renderer) const
 {
     return RenderTable::createTableWithStyle(renderer.document(), renderer.style());
 }
index 99ef381..3328ee1 100644 (file)
@@ -1365,14 +1365,14 @@ void RenderTableCell::scrollbarsChanged(bool horizontalScrollbarChanged, bool ve
         setIntrinsicPaddingAfter(intrinsicPaddingAfter() - scrollbarHeight);
 }
 
-std::unique_ptr<RenderTableCell> RenderTableCell::createTableCellWithStyle(Document& document, const RenderStyle& style)
+RenderPtr<RenderTableCell> RenderTableCell::createTableCellWithStyle(Document& document, const RenderStyle& style)
 {
-    auto cell = std::make_unique<RenderTableCell>(document, RenderStyle::createAnonymousStyleWithDisplay(style, TABLE_CELL));
+    auto cell = createRenderer<RenderTableCell>(document, RenderStyle::createAnonymousStyleWithDisplay(style, TABLE_CELL));
     cell->initializeStyle();
     return cell;
 }
 
-std::unique_ptr<RenderTableCell> RenderTableCell::createAnonymousWithParentRenderer(const RenderTableRow& parent)
+RenderPtr<RenderTableCell> RenderTableCell::createAnonymousWithParentRenderer(const RenderTableRow& parent)
 {
     return RenderTableCell::createTableCellWithStyle(parent.document(), parent.style());
 }
index 6a77f18..88422e0 100644 (file)
@@ -108,8 +108,8 @@ public:
     bool cellWidthChanged() const { return m_cellWidthChanged; }
     void setCellWidthChanged(bool b = true) { m_cellWidthChanged = b; }
 
-    static std::unique_ptr<RenderTableCell> createAnonymousWithParentRenderer(const RenderTableRow&);
-    std::unique_ptr<RenderBox> createAnonymousBoxWithSameTypeAs(const RenderBox&) const override;
+    static RenderPtr<RenderTableCell> createAnonymousWithParentRenderer(const RenderTableRow&);
+    RenderPtr<RenderBox> createAnonymousBoxWithSameTypeAs(const RenderBox&) const override;
 
     // This function is used to unify which table part's style we use for computing direction and
     // writing mode. Writing modes are not allowed on row group and row but direction is.
@@ -138,7 +138,7 @@ protected:
     void computePreferredLogicalWidths() override;
 
 private:
-    static std::unique_ptr<RenderTableCell> createTableCellWithStyle(Document&, const RenderStyle&);
+    static RenderPtr<RenderTableCell> createTableCellWithStyle(Document&, const RenderStyle&);
 
     const char* renderName() const override { return (isAnonymous() || isPseudoElement()) ? "RenderTableCell (anonymous)" : "RenderTableCell"; }
 
@@ -375,7 +375,7 @@ inline void RenderTableCell::invalidateHasEmptyCollapsedBorders()
     m_hasEmptyCollapsedEndBorder = false;
 }
 
-inline std::unique_ptr<RenderBox> RenderTableCell::createAnonymousBoxWithSameTypeAs(const RenderBox& renderer) const
+inline RenderPtr<RenderBox> RenderTableCell::createAnonymousBoxWithSameTypeAs(const RenderBox& renderer) const
 {
     return RenderTableCell::createTableCellWithStyle(renderer.document(), renderer.style());
 }
index 9ed1f6a..9d9c7f9 100644 (file)
@@ -106,7 +106,7 @@ const BorderValue& RenderTableRow::borderAdjoiningEndCell(const RenderTableCell&
     return style().borderEnd();
 }
 
-void RenderTableRow::addChild(RenderObject* child, RenderObject* beforeChild)
+void RenderTableRow::addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild)
 {
     if (!is<RenderTableCell>(*child)) {
         RenderObject* last = beforeChild;
@@ -116,14 +116,14 @@ void RenderTableRow::addChild(RenderObject* child, RenderObject* beforeChild)
             RenderTableCell& cell = downcast<RenderTableCell>(*last);
             if (beforeChild == &cell)
                 beforeChild = cell.firstChild();
-            cell.addChild(child, beforeChild);
+            cell.addChild(WTFMove(child), beforeChild);
             return;
         }
 
         if (beforeChild && !beforeChild->isAnonymous() && beforeChild->parent() == this) {
             RenderObject* cell = beforeChild->previousSibling();
             if (is<RenderTableCell>(cell) && cell->isAnonymous()) {
-                downcast<RenderTableCell>(*cell).addChild(child);
+                downcast<RenderTableCell>(*cell).addChild(WTFMove(child));
                 return;
             }
         }
@@ -132,21 +132,23 @@ void RenderTableRow::addChild(RenderObject* child, RenderObject* beforeChild)
         if (last && last->parent() && last->parent()->isAnonymous() && !last->parent()->isBeforeOrAfterContent()) {
             // If beforeChild is inside an anonymous cell, insert into the cell.
             if (!is<RenderTableCell>(*last)) {
-                last->parent()->addChild(child, beforeChild);
+                last->parent()->addChild(WTFMove(child), beforeChild);
                 return;
             }
             // If beforeChild is inside an anonymous row, insert into the row.
             auto& parent = *last->parent();
             if (is<RenderTableRow>(parent)) {
-                auto* cell = RenderTableCell::createAnonymousWithParentRenderer(*this).release();
-                parent.addChild(cell, beforeChild);
-                cell->addChild(child);
+                auto newCell = RenderTableCell::createAnonymousWithParentRenderer(*this);
+                auto& cell = *newCell;
+                parent.addChild(WTFMove(newCell), beforeChild);
+                cell.addChild(WTFMove(child));
                 return;
             }
         }
-        auto* cell = RenderTableCell::createAnonymousWithParentRenderer(*this).release();
-        addChild(cell, beforeChild);
-        cell->addChild(child);
+        auto newCell = RenderTableCell::createAnonymousWithParentRenderer(*this);
+        auto& cell = *newCell;
+        addChild(WTFMove(newCell), beforeChild);
+        cell.addChild(WTFMove(child));
         return;
     } 
 
@@ -160,7 +162,7 @@ void RenderTableRow::addChild(RenderObject* child, RenderObject* beforeChild)
         section->addCell(&cell, this);
 
     ASSERT(!beforeChild || is<RenderTableCell>(*beforeChild));
-    RenderBox::addChild(&cell, beforeChild);
+    RenderBox::addChild(WTFMove(child), beforeChild);
 
     if (beforeChild || nextRow())
         section()->setNeedsCellRecalc();
@@ -270,14 +272,14 @@ void RenderTableRow::imageChanged(WrappedImagePtr, const IntRect*)
     repaint();
 }
 
-std::unique_ptr<RenderTableRow> RenderTableRow::createTableRowWithStyle(Document& document, const RenderStyle& style)
+RenderPtr<RenderTableRow> RenderTableRow::createTableRowWithStyle(Document& document, const RenderStyle& style)
 {
-    auto row = std::make_unique<RenderTableRow>(document, RenderStyle::createAnonymousStyleWithDisplay(style, TABLE_ROW));
+    auto row = createRenderer<RenderTableRow>(document, RenderStyle::createAnonymousStyleWithDisplay(style, TABLE_ROW));
     row->initializeStyle();
     return row;
 }
 
-std::unique_ptr<RenderTableRow> RenderTableRow::createAnonymousWithParentRenderer(const RenderTableSection& parent)
+RenderPtr<RenderTableRow> RenderTableRow::createAnonymousWithParentRenderer(const RenderTableSection& parent)
 {
     return RenderTableRow::createTableRowWithStyle(parent.document(), parent.style());
 }
index 0830c3b..8f6f99e 100644 (file)
@@ -46,8 +46,8 @@ public:
 
     void paintOutlineForRowIfNeeded(PaintInfo&, const LayoutPoint&);
 
-    static std::unique_ptr<RenderTableRow> createAnonymousWithParentRenderer(const RenderTableSection&);
-    std::unique_ptr<RenderBox> createAnonymousBoxWithSameTypeAs(const RenderBox&) const override;
+    static RenderPtr<RenderTableRow> createAnonymousWithParentRenderer(const RenderTableSection&);
+    RenderPtr<RenderBox> createAnonymousBoxWithSameTypeAs(const RenderBox&) const override;
 
     void setRowIndex(unsigned);
     bool rowIndexWasSet() const { return m_rowIndex != unsetRowIndex; }
@@ -58,14 +58,14 @@ public:
     const BorderValue& borderAdjoiningStartCell(const RenderTableCell&) const;
     const BorderValue& borderAdjoiningEndCell(const RenderTableCell&) const;
 
-    void addChild(RenderObject* child, RenderObject* beforeChild = 0) override;
+    void addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild = 0) override;
 
     bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) override;
 
     void destroyAndCollapseAnonymousSiblingRows();
 
 private:
-    static std::unique_ptr<RenderTableRow> createTableRowWithStyle(Document&, const RenderStyle&);
+    static RenderPtr<RenderTableRow> createTableRowWithStyle(Document&, const RenderStyle&);
 
     const char* renderName() const override { return (isAnonymous() || isPseudoElement()) ? "RenderTableRow (anonymous)" : "RenderTableRow"; }
 
@@ -150,7 +150,7 @@ inline RenderTableRow* RenderTableSection::lastRow() const
     return downcast<RenderTableRow>(RenderBox::lastChild());
 }
 
-inline std::unique_ptr<RenderBox> RenderTableRow::createAnonymousBoxWithSameTypeAs(const RenderBox& renderer) const
+inline RenderPtr<RenderBox> RenderTableRow::createAnonymousBoxWithSameTypeAs(const RenderBox& renderer) const
 {
     return RenderTableRow::createTableRowWithStyle(renderer.document(), renderer.style());
 }
index 899cc8d..1a94cb8 100644 (file)
@@ -118,7 +118,7 @@ void RenderTableSection::willBeRemovedFromTree()
     setNeedsCellRecalc();
 }
 
-void RenderTableSection::addChild(RenderObject* child, RenderObject* beforeChild)
+void RenderTableSection::addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild)
 {
     if (!is<RenderTableRow>(*child)) {
         RenderObject* last = beforeChild;
@@ -128,14 +128,14 @@ void RenderTableSection::addChild(RenderObject* child, RenderObject* beforeChild
             RenderTableRow& row = downcast<RenderTableRow>(*last);
             if (beforeChild == &row)
                 beforeChild = row.firstCell();
-            row.addChild(child, beforeChild);
+            row.addChild(WTFMove(child), beforeChild);
             return;
         }
 
         if (beforeChild && !beforeChild->isAnonymous() && beforeChild->parent() == this) {
             RenderObject* row = beforeChild->previousSibling();
             if (is<RenderTableRow>(row) && row->isAnonymous()) {
-                downcast<RenderTableRow>(*row).addChild(child);
+                downcast<RenderTableRow>(*row).addChild(WTFMove(child));
                 return;
             }
         }
@@ -146,13 +146,14 @@ void RenderTableSection::addChild(RenderObject* child, RenderObject* beforeChild
         while (lastBox && lastBox->parent()->isAnonymous() && !is<RenderTableRow>(*lastBox))
             lastBox = lastBox->parent();
         if (lastBox && lastBox->isAnonymous() && !lastBox->isBeforeOrAfterContent()) {
-            downcast<RenderTableRow>(*lastBox).addChild(child, beforeChild);
+            downcast<RenderTableRow>(*lastBox).addChild(WTFMove(child), beforeChild);
             return;
         }
 
-        auto* row = RenderTableRow::createAnonymousWithParentRenderer(*this).release();
-        addChild(row, beforeChild);
-        row->addChild(child);
+        auto newRow = RenderTableRow::createAnonymousWithParentRenderer(*this);
+        auto& row = *newRow;
+        addChild(WTFMove(newRow), beforeChild);
+        row.addChild(WTFMove(child));
         return;
     }
 
@@ -176,7 +177,7 @@ void RenderTableSection::addChild(RenderObject* child, RenderObject* beforeChild
         beforeChild = splitAnonymousBoxesAroundChild(beforeChild);
 
     ASSERT(!beforeChild || is<RenderTableRow>(*beforeChild));
-    RenderBox::addChild(child, beforeChild);
+    RenderBox::addChild(WTFMove(child), beforeChild);
 }
 
 void RenderTableSection::ensureRows(unsigned numRows)
@@ -1590,14 +1591,14 @@ CollapsedBorderValue RenderTableSection::cachedCollapsedBorder(const RenderTable
     return it->value;
 }
 
-std::unique_ptr<RenderTableSection> RenderTableSection::createTableSectionWithStyle(Document& document, const RenderStyle& style)
+RenderPtr<RenderTableSection> RenderTableSection::createTableSectionWithStyle(Document& document, const RenderStyle& style)
 {
-    auto section = std::make_unique<RenderTableSection>(document, RenderStyle::createAnonymousStyleWithDisplay(style, TABLE_ROW_GROUP));
+    auto section = createRenderer<RenderTableSection>(document, RenderStyle::createAnonymousStyleWithDisplay(style, TABLE_ROW_GROUP));
     section->initializeStyle();
     return section;
 }
 
-std::unique_ptr<RenderTableSection> RenderTableSection::createAnonymousWithParentRenderer(const RenderTable& parent)
+RenderPtr<RenderTableSection> RenderTableSection::createAnonymousWithParentRenderer(const RenderTable& parent)
 {
     return RenderTableSection::createTableSectionWithStyle(parent.document(), parent.style());
 }
index 7126b6a..45c6cde 100644 (file)
@@ -61,7 +61,7 @@ public:
     RenderTableRow* firstRow() const;
     RenderTableRow* lastRow() const;
 
-    void addChild(RenderObject* child, RenderObject* beforeChild = 0) override;
+    void addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild = 0) override;
 
     std::optional<int> firstLineBaseline() const override;
 
@@ -142,8 +142,8 @@ public:
     // FIXME: We may want to introduce a structure holding the in-flux layout information.
     LayoutUnit distributeExtraLogicalHeightToRows(LayoutUnit extraLogicalHeight);
 
-    static std::unique_ptr<RenderTableSection> createAnonymousWithParentRenderer(const RenderTable&);
-    std::unique_ptr<RenderBox> createAnonymousBoxWithSameTypeAs(const RenderBox&) const override;
+    static RenderPtr<RenderTableSection> createAnonymousWithParentRenderer(const RenderTable&);
+    RenderPtr<RenderBox> createAnonymousBoxWithSameTypeAs(const RenderBox&) const override;
     
     void paint(PaintInfo&, const LayoutPoint&) override;
 
@@ -151,7 +151,7 @@ protected:
     void styleDidChange(StyleDifference, const RenderStyle* oldStyle) override;
 
 private:
-    static std::unique_ptr<RenderTableSection> createTableSectionWithStyle(Document&, const RenderStyle&);
+    static RenderPtr<RenderTableSection> createTableSectionWithStyle(Document&, const RenderStyle&);
 
     enum ShouldIncludeAllIntersectingCells {
         IncludeAllIntersectingCells,
@@ -334,7 +334,7 @@ inline CellSpan RenderTableSection::fullTableRowSpan() const
     return CellSpan(0, m_grid.size());
 }
 
-inline std::unique_ptr<RenderBox> RenderTableSection::createAnonymousBoxWithSameTypeAs(const RenderBox& renderer) const
+inline RenderPtr<RenderBox> RenderTableSection::createAnonymousBoxWithSameTypeAs(const RenderBox& renderer) const
 {
     return RenderTableSection::createTableSectionWithStyle(renderer.document(), renderer.style());
 }
index 6f166a7..a30df99 100644 (file)
@@ -93,15 +93,15 @@ RenderPtr<RenderMathMLFencedOperator> RenderMathMLFenced::createMathMLOperator(c
 
 void RenderMathMLFenced::makeFences()
 {
-    RenderPtr<RenderMathMLFencedOperator> openFence = createMathMLOperator(m_open, MathMLOperatorDictionary::Prefix, MathMLOperatorDictionary::Fence);
-    RenderMathMLRow::addChild(openFence.leakPtr(), firstChild());
+    auto openFence = createMathMLOperator(m_open, MathMLOperatorDictionary::Prefix, MathMLOperatorDictionary::Fence);
+    RenderMathMLRow::addChild(WTFMove(openFence), firstChild());
 
-    RenderPtr<RenderMathMLFencedOperator> closeFence = createMathMLOperator(m_close, MathMLOperatorDictionary::Postfix, MathMLOperatorDictionary::Fence);
+    auto closeFence = createMathMLOperator(m_close, MathMLOperatorDictionary::Postfix, MathMLOperatorDictionary::Fence);
     m_closeFenceRenderer = closeFence.get();
-    RenderMathMLRow::addChild(closeFence.leakPtr());
+    RenderMathMLRow::addChild(WTFMove(closeFence));
 }
 
-void RenderMathMLFenced::addChild(RenderObject* child, RenderObject* beforeChild)
+void RenderMathMLFenced::addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild)
 {
     // make the fences if the render object is empty
     if (!firstChild())
@@ -139,14 +139,14 @@ void RenderMathMLFenced::addChild(RenderObject* child, RenderObject* beforeChild
 
     if (beforeChild) {
         // Adding |x| before an existing |y| e.g. in element (y) - first insert our new child |x|, then its separator, to get (x, y).
-        RenderMathMLRow::addChild(child, beforeChild);
+        RenderMathMLRow::addChild(WTFMove(child), beforeChild);
         if (separatorRenderer)
-            RenderMathMLRow::addChild(separatorRenderer.leakPtr(), beforeChild);
+            RenderMathMLRow::addChild(WTFMove(separatorRenderer), beforeChild);
     } else {
         // Adding |y| at the end of an existing element e.g. (x) - insert the separator first before the closing fence, then |y|, to get (x, y).
         if (separatorRenderer)
-            RenderMathMLRow::addChild(separatorRenderer.leakPtr(), m_closeFenceRenderer);
-        RenderMathMLRow::addChild(child, m_closeFenceRenderer);
+            RenderMathMLRow::addChild(WTFMove(separatorRenderer), m_closeFenceRenderer);
+        RenderMathMLRow::addChild(WTFMove(child), m_closeFenceRenderer);
     }
 }
 
index dc0b9f9..c17e0db 100644 (file)
@@ -41,7 +41,7 @@ public:
 private:
     bool isRenderMathMLFenced() const final { return true; }
     const char* renderName() const final { return "RenderMathMLFenced"; }
-    void addChild(RenderObject* child, RenderObject* beforeChild) final;
+    void addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild) final;
     void updateFromElement() final;
 
     RenderPtr<RenderMathMLFencedOperator> createMathMLOperator(const String& operatorString, MathMLOperatorDictionary::Form, MathMLOperatorDictionary::Flag);
index 83e918e..08251d5 100644 (file)
@@ -88,19 +88,19 @@ void RenderSVGContainer::layout()
     clearNeedsLayout();
 }
 
-void RenderSVGContainer::addChild(RenderObject* child, RenderObject* beforeChild)
+void RenderSVGContainer::addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
-    RenderSVGModelObject::addChild(child, beforeChild);
-    SVGResourcesCache::clientWasAddedToTree(*child);
+    auto& child = *newChild;
+    RenderSVGModelObject::addChild(WTFMove(newChild), beforeChild);
+    SVGResourcesCache::clientWasAddedToTree(child);
 }
 
-void RenderSVGContainer::removeChild(RenderObject& child)
+RenderPtr<RenderObject> RenderSVGContainer::takeChild(RenderObject& child)
 {
     SVGResourcesCache::clientWillBeRemovedFromTree(child);
-    RenderSVGModelObject::removeChild(child);
+    return RenderSVGModelObject::takeChild(child);
 }
 
-
 bool RenderSVGContainer::selfWillPaint()
 {
     auto* resources = SVGResourcesCache::cachedResourcesForRenderer(*this);
index bffbfef..4d30a9a 100644 (file)
@@ -47,8 +47,8 @@ protected:
 
     void layout() override;
 
-    void addChild(RenderObject* child, RenderObject* beforeChild = 0) final;
-    void removeChild(RenderObject&) final;
+    void addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild = 0) final;
+    RenderPtr<RenderObject> takeChild(RenderObject&) final;
     void addFocusRingRects(Vector<LayoutRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) final;
 
     FloatRect objectBoundingBox() const final { return m_objectBoundingBox; }
index 71489ad..c95c972 100644 (file)
@@ -120,29 +120,29 @@ void RenderSVGInline::updateFromStyle()
     setInline(true);
 }
 
-void RenderSVGInline::addChild(RenderObject* child, RenderObject* beforeChild)
+void RenderSVGInline::addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
-    RenderInline::addChild(child, beforeChild);
-    SVGResourcesCache::clientWasAddedToTree(*child);
+    auto& child = *newChild;
+    RenderInline::addChild(WTFMove(newChild), beforeChild);
+    SVGResourcesCache::clientWasAddedToTree(child);
 
     if (auto* textAncestor = RenderSVGText::locateRenderSVGTextAncestor(*this))
-        textAncestor->subtreeChildWasAdded(child);
+        textAncestor->subtreeChildWasAdded(&child);
 }
 
-void RenderSVGInline::removeChild(RenderObject& child)
+RenderPtr<RenderObject> RenderSVGInline::takeChild(RenderObject& child)
 {
     SVGResourcesCache::clientWillBeRemovedFromTree(child);
 
     auto* textAncestor = RenderSVGText::locateRenderSVGTextAncestor(*this);
-    if (!textAncestor) {
-        RenderInline::removeChild(child);
-        return;
-    }
+    if (!textAncestor)
+        return RenderInline::takeChild(child);
 
     Vector<SVGTextLayoutAttributes*, 2> affectedAttributes;
     textAncestor->subtreeChildWillBeRemoved(&child, affectedAttributes);
-    RenderInline::removeChild(child);
+    auto takenChild = RenderInline::takeChild(child);
     textAncestor->subtreeChildWasRemoved(affectedAttributes);
+    return takenChild;
 }
 
 }
index 07dd950..8b8bcee 100644 (file)
@@ -60,8 +60,8 @@ private:
     void willBeDestroyed() final;
     void styleDidChange(StyleDifference, const RenderStyle* oldStyle) final;
 
-    void addChild(RenderObject* child, RenderObject* beforeChild = nullptr) final;
-    void removeChild(RenderObject&) final;
+    void addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild = nullptr) final;
+    RenderPtr<RenderObject> takeChild(RenderObject&) final;
 };
 
 } // namespace WebCore
index b025ea9..a786fca 100644 (file)
@@ -300,16 +300,17 @@ void RenderSVGRoot::styleDidChange(StyleDifference diff, const RenderStyle* oldS
     SVGResourcesCache::clientStyleChanged(*this, diff, style());
 }
 
-void RenderSVGRoot::addChild(RenderObject* child, RenderObject* beforeChild)
+void RenderSVGRoot::addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
-    RenderReplaced::addChild(child, beforeChild);
-    SVGResourcesCache::clientWasAddedToTree(*child);
+    auto& child = *newChild;
+    RenderReplaced::addChild(WTFMove(newChild), beforeChild);
+    SVGResourcesCache::clientWasAddedToTree(child);
 }
 
-void RenderSVGRoot::removeChild(RenderObject& child)
+RenderPtr<RenderObject> RenderSVGRoot::takeChild(RenderObject& child)
 {
     SVGResourcesCache::clientWillBeRemovedFromTree(child);
-    RenderReplaced::removeChild(child);
+    return RenderReplaced::takeChild(child);
 }
 
 // RenderBox methods will expect coordinates w/o any transforms in coordinates
index ecff184..d4bd390 100644 (file)
@@ -81,8 +81,8 @@ private:
     void willBeRemovedFromTree() override;
 
     void styleDidChange(StyleDifference, const RenderStyle* oldStyle) override;
-    void addChild(RenderObject* child, RenderObject* beforeChild = 0) override;
-    void removeChild(RenderObject&) override;
+    void addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild = 0) override;
+    RenderPtr<RenderObject> takeChild(RenderObject&) override;
 
     const AffineTransform& localToParentTransform() const override;
 
index 43e0464..991d3b4 100644 (file)
@@ -517,22 +517,24 @@ FloatRect RenderSVGText::repaintRectInLocalCoordinates() const
     return repaintRect;
 }
 
-void RenderSVGText::addChild(RenderObject* child, RenderObject* beforeChild)
+void RenderSVGText::addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
-    RenderSVGBlock::addChild(child, beforeChild);
+    auto& child = *newChild;
+    RenderSVGBlock::addChild(WTFMove(newChild), beforeChild);
 
-    SVGResourcesCache::clientWasAddedToTree(*child);
-    subtreeChildWasAdded(child);
+    SVGResourcesCache::clientWasAddedToTree(child);
+    subtreeChildWasAdded(&child);
 }
 
-void RenderSVGText::removeChild(RenderObject& child)
+RenderPtr<RenderObject> RenderSVGText::takeChild(RenderObject& child)
 {
     SVGResourcesCache::clientWillBeRemovedFromTree(child);
 
     Vector<SVGTextLayoutAttributes*, 2> affectedAttributes;
     subtreeChildWillBeRemoved(&child, affectedAttributes);
-    RenderSVGBlock::removeChild(child);
+    auto takenChild = RenderSVGBlock::takeChild(child);
     subtreeChildWasRemoved(affectedAttributes);
+    return takenChild;
 }
 
 // Fix for <rdar://problem/8048875>. We should not render :first-line CSS Style
index c5e1fdb..158671a 100644 (file)
@@ -82,8 +82,8 @@ private:
 
     void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags, bool* wasFixed) const override;
     const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const override;
-    void addChild(RenderObject* child, RenderObject* beforeChild = nullptr) override;
-    void removeChild(RenderObject&) override;
+    void addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild = nullptr) override;
+    RenderPtr<RenderObject> takeChild(RenderObject&) override;
     void willBeDestroyed() override;
 
     const AffineTransform& localToParentTransform() const override { return m_localTransform; }
index 1d7fb79..66d3d2f 100644 (file)
@@ -46,7 +46,7 @@ public:
     }
 
     RenderElement& parent() const { return m_parent; }
-    void insert(RenderObject&);
+    void insert(RenderPtr<RenderObject>);
     bool canInsert(RenderElement&) const;
     bool canInsert(RenderText&) const;
 
@@ -78,10 +78,10 @@ inline bool RenderTreePosition::canInsert(RenderText& renderer) const
     return m_parent.isChildAllowed(renderer, m_parent.style());
 }
 
-inline void RenderTreePosition::insert(RenderObject& renderer)
+inline void RenderTreePosition::insert(RenderPtr<RenderObject> renderer)
 {
     ASSERT(m_hasValidNextSibling);
-    m_parent.addChild(&renderer, m_nextSibling);
+    m_parent.addChild(WTFMove(renderer), m_nextSibling);
 }
 
 } // namespace WebCore
index 924ea62..8da55fb 100644 (file)
@@ -359,27 +359,25 @@ void RenderTreeUpdater::createRenderer(Element& element, RenderStyle&& style)
         return;
 
     RenderTreePosition insertionPosition = computeInsertionPosition();
-    RenderElement* newRenderer = element.createElementRenderer(WTFMove(style), insertionPosition).leakPtr();
+    auto newRenderer = element.createElementRenderer(WTFMove(style), insertionPosition);
     if (!newRenderer)
         return;
-    if (!insertionPosition.canInsert(*newRenderer)) {
-        newRenderer->destroy();
+    if (!insertionPosition.canInsert(*newRenderer))
         return;
-    }
 
-    element.setRenderer(newRenderer);
+    element.setRenderer(newRenderer.get());
 
     newRenderer->initializeStyle();
 
 #if ENABLE(FULLSCREEN_API)
     if (m_document.webkitIsFullScreen() && m_document.webkitCurrentFullScreenElement() == &element) {
-        newRenderer = RenderFullScreen::wrapRenderer(newRenderer, &insertionPosition.parent(), m_document);
+        newRenderer = RenderFullScreen::wrapNewRenderer(WTFMove(newRenderer), insertionPosition.parent(), m_document);
         if (!newRenderer)
             return;
     }
 #endif
-    // Note: Adding newRenderer instead of renderer(). renderer() may be a child of newRenderer.
-    insertionPosition.insert(*newRenderer);
+
+    insertionPosition.insert(WTFMove(newRenderer));
 
     if (AXObjectCache* cache = m_document.axObjectCache())
         cache->updateCacheAfterNodeIsAttached(&element);
@@ -441,7 +439,7 @@ static void createTextRenderer(Text& textNode, RenderTreePosition& renderTreePos
         return;
 
     textNode.setRenderer(newRenderer.get());
-    renderTreePosition.insert(*newRenderer.leakPtr());
+    renderTreePosition.insert(WTFMove(newRenderer));
 }
 
 void RenderTreeUpdater::updateTextRenderer(Text& text, const Style::TextUpdate* textUpdate)
index 9cfeb93..eeb5a17 100644 (file)
@@ -108,11 +108,11 @@ static void updateFirstLetterStyle(RenderElement& firstLetterBlock, RenderObject
 
     if (Style::determineChange(firstLetter->style(), pseudoStyle) == Style::Detach) {
         // The first-letter renderer needs to be replaced. Create a new renderer of the right type.
-        RenderBoxModelObject* newFirstLetter;
+        RenderPtr<RenderBoxModelObject> newFirstLetter;
         if (pseudoStyle.display() == INLINE)
-            newFirstLetter = new RenderInline(firstLetterBlock.document(), WTFMove(pseudoStyle));
+            newFirstLetter = createRenderer<RenderInline>(firstLetterBlock.document(), WTFMove(pseudoStyle));
         else
-            newFirstLetter = new RenderBlockFlow(firstLetterBlock.document(), WTFMove(pseudoStyle));
+            newFirstLetter = createRenderer<RenderBlockFlow>(firstLetterBlock.document(), WTFMove(pseudoStyle));
         newFirstLetter->initializeStyle();
 
         // Move the first letter into the new renderer.
@@ -120,8 +120,8 @@ static void updateFirstLetterStyle(RenderElement& firstLetterBlock, RenderObject
         while (RenderObject* child = firstLetter->firstChild()) {
             if (is<RenderText>(*child))
                 downcast<RenderText>(*child).removeAndDestroyTextBoxes();
-            firstLetter->removeChild(*child);
-            newFirstLetter->addChild(child, nullptr);
+            auto toMove = firstLetter->takeChild(*child);
+            newFirstLetter->addChild(WTFMove(toMove));
         }
 
         RenderObject* nextSibling = firstLetter->nextSibling();
@@ -131,12 +131,8 @@ static void updateFirstLetterStyle(RenderElement& firstLetterBlock, RenderObject
             remainingText->setFirstLetter(*newFirstLetter);
             newFirstLetter->setFirstLetterRemainingText(remainingText);
         }
-        // To prevent removal of single anonymous block in RenderBlock::removeChild and causing
-        // |nextSibling| to go stale, we remove the old first letter using removeChildNode first.
-        firstLetterContainer->removeChildInternal(*firstLetter, RenderElement::NotifyChildren);
-        firstLetter->destroy();
-        firstLetter = newFirstLetter;
-        firstLetterContainer->addChild(firstLetter, nextSibling);
+        firstLetterContainer->removeAndDestroyChild(*firstLetter);
+        firstLetterContainer->addChild(WTFMove(newFirstLetter), nextSibling);
     } else
         firstLetter->setStyle(WTFMove(pseudoStyle));
 }
@@ -145,13 +141,14 @@ static void createFirstLetterRenderer(RenderElement& firstLetterBlock, RenderTex
 {
     RenderElement* firstLetterContainer = currentTextChild.parent();
     auto pseudoStyle = styleForFirstLetter(firstLetterBlock, *firstLetterContainer);
-    RenderBoxModelObject* firstLetter = nullptr;
+    RenderPtr<RenderBoxModelObject> newFirstLetter;
     if (pseudoStyle.display() == INLINE)
-        firstLetter = new RenderInline(firstLetterBlock.document(), WTFMove(pseudoStyle));
+        newFirstLetter = createRenderer<RenderInline>(firstLetterBlock.document(), WTFMove(pseudoStyle));
     else
-        firstLetter = new RenderBlockFlow(firstLetterBlock.document(), WTFMove(pseudoStyle));
-    firstLetter->initializeStyle();
-    firstLetterContainer->addChild(firstLetter, &currentTextChild);
+        newFirstLetter = createRenderer<RenderBlockFlow>(firstLetterBlock.document(), WTFMove(pseudoStyle));
+    newFirstLetter->initializeStyle();
+    auto& firstLetter = *newFirstLetter;
+    firstLetterContainer->addChild(WTFMove(newFirstLetter), &currentTextChild);
 
     // The original string is going to be either a generated content string or a DOM node's
     // string. We want the original string before it got transformed in case first-letter has
@@ -183,30 +180,29 @@ static void createFirstLetterRenderer(RenderElement& firstLetterBlock, RenderTex
 
         // Construct a text fragment for the text after the first letter.
         // This text fragment might be empty.
-        RenderTextFragment* remainingText;
+        RenderPtr<RenderTextFragment> newRemainingText;
         if (currentTextChild.textNode())
-            remainingText = new RenderTextFragment(*currentTextChild.textNode(), oldText, length, oldText.length() - length);
+            newRemainingText = createRenderer<RenderTextFragment>(*currentTextChild.textNode(), oldText, length, oldText.length() - length);
         else
-            remainingText = new RenderTextFragment(firstLetterBlock.document(), oldText, length, oldText.length() - length);
+            newRemainingText = createRenderer<RenderTextFragment>(firstLetterBlock.document(), oldText, length, oldText.length() - length);
 
-        if (remainingText->textNode())
-            remainingText->textNode()->setRenderer(remainingText);
+        if (newRemainingText->textNode())
+            newRemainingText->textNode()->setRenderer(newRemainingText.get());
 
-        firstLetterContainer->addChild(remainingText, &currentTextChild);
-        firstLetterContainer->removeChild(currentTextChild);
-        remainingText->setFirstLetter(*firstLetter);
-        firstLetter->setFirstLetterRemainingText(remainingText);
+        RenderTextFragment& remainingText = *newRemainingText;
+        firstLetterContainer->addChild(WTFMove(newRemainingText), &currentTextChild);
+        firstLetterContainer->removeAndDestroyChild(currentTextChild);
+        remainingText.setFirstLetter(firstLetter);
+        firstLetter.setFirstLetterRemainingText(&remainingText);
 
         // construct text fragment for the first letter
-        RenderTextFragment* letter;
-        if (remainingText->textNode())
-            letter = new RenderTextFragment(*remainingText->textNode(), oldText, 0, length);
+        RenderPtr<RenderTextFragment> letter;
+        if (remainingText.textNode())
+            letter = createRenderer<RenderTextFragment>(*remainingText.textNode(), oldText, 0, length);
         else
-            letter = new RenderTextFragment(firstLetterBlock.document(), oldText, 0, length);
+            letter = createRenderer<RenderTextFragment>(firstLetterBlock.document(), oldText, 0, length);
 
-        firstLetter->addChild(letter);
-
-        currentTextChild.destroy();
+        firstLetter.addChild(WTFMove(letter));
     }
 }
 
index 976ea92..0f5840a 100644 (file)
@@ -87,7 +87,7 @@ static void createContentRenderers(RenderElement& renderer)
     for (const ContentData* content = style.contentData(); content; content = content->next()) {
         auto child = content->createContentRenderer(renderer.document(), style);
         if (renderer.isChildAllowed(*child, style))
-            renderer.addChild(child.leakPtr());
+            renderer.addChild(WTFMove(child));
     }
 }
 
index ccdeee7..cf0a064 100644 (file)
@@ -84,12 +84,14 @@ void RenderTreeUpdater::ListItem::updateMarker(RenderListItem& listItemRenderer)
     }
 
     auto newStyle = listItemRenderer.computeMarkerStyle();
+    RenderPtr<RenderListMarker> newMarkerRenderer;
     auto* markerRenderer = listItemRenderer.markerRenderer();
     if (markerRenderer)
         markerRenderer->setStyle(WTFMove(newStyle));
     else {
-        markerRenderer = WebCore::createRenderer<RenderListMarker>(listItemRenderer, WTFMove(newStyle)).leakPtr();
-        markerRenderer->initializeStyle();
+        newMarkerRenderer = WebCore::createRenderer<RenderListMarker>(listItemRenderer, WTFMove(newStyle));
+        newMarkerRenderer->initializeStyle();
+        markerRenderer = newMarkerRenderer.get();
         listItemRenderer.setMarkerRenderer(markerRenderer);
     }
 
@@ -109,8 +111,11 @@ void RenderTreeUpdater::ListItem::updateMarker(RenderListItem& listItemRenderer)
     }
 
     if (newParent != currentParent) {
-        markerRenderer->removeFromParent();
-        newParent->addChild(markerRenderer, firstNonMarkerChild(*newParent));
+        if (currentParent)
+            newParent->addChild(currentParent->takeChild(*markerRenderer), firstNonMarkerChild(*newParent));
+        else
+            newParent->addChild(WTFMove(newMarkerRenderer), firstNonMarkerChild(*newParent));
+
         // If current parent is an anonymous block that has lost all its children, destroy it.
         if (currentParent && currentParent->isAnonymousBlock() && !currentParent->firstChild() && !downcast<RenderBlock>(*currentParent).continuation())
             currentParent->destroy();
index de43338..64e8321 100644 (file)
@@ -46,13 +46,14 @@ void RenderTreeUpdater::MultiColumn::update(RenderBlockFlow& flow)
 
 void RenderTreeUpdater::MultiColumn::createFragmentedFlow(RenderBlockFlow& flow)
 {
-    RenderMultiColumnFlow* fragmentedFlow = new RenderMultiColumnFlow(flow.document(), RenderStyle::createAnonymousStyleWithDisplay(flow.style(), BLOCK));
-    fragmentedFlow->initializeStyle();
+    auto newFragmentedFlow = WebCore::createRenderer<RenderMultiColumnFlow>(flow.document(), RenderStyle::createAnonymousStyleWithDisplay(flow.style(), BLOCK));
+    newFragmentedFlow->initializeStyle();
     flow.setChildrenInline(false); // Do this to avoid wrapping inline children that are just going to move into the flow thread.
     flow.deleteLines();
-    flow.RenderBlock::addChild(fragmentedFlow);
-    fragmentedFlow->populate(); // Called after the flow thread is inserted so that we are reachable by the flow thread.
-    flow.setMultiColumnFlow(fragmentedFlow);
+    auto& fragmentedFlow = *newFragmentedFlow;
+    flow.RenderBlock::addChild(WTFMove(newFragmentedFlow));
+    fragmentedFlow.populate(); // Called after the flow thread is inserted so that we are reachable by the flow thread.
+    flow.setMultiColumnFlow(&fragmentedFlow);
 }