Introduce RenderTreeBuilder
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 15 Dec 2017 12:35:03 +0000 (12:35 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 15 Dec 2017 12:35:03 +0000 (12:35 +0000)
https://bugs.webkit.org/show_bug.cgi?id=180817

Reviewed by Zalan Bujtas.

RenderTreeBuilder is responsible of building the render tree, including construction of various anonymous
renderers. Renderer subtype specific render tree construction code will eventually move there.

This patch adds RenderTreeBuilder class and passes it as a parameter for all addChild implementations.
Future patches can then mechanically move the building code from renderers to RenderTreeBuilder.

It also moves one addChild implementation (RenderRuby::addChild -> RenderTreeBuilder::rubyRunInsertChild)
to RenderTreeBuilder as a test.

* WebCore.xcodeproj/project.pbxproj:
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::addChildToContinuation):
(WebCore::RenderBlock::addChild):
(WebCore::RenderBlock::addChildIgnoringContinuation):
* rendering/RenderBlock.h:
* rendering/RenderBlockFlow.cpp:
(WebCore::RenderBlockFlow::addChild):
* rendering/RenderBlockFlow.h:
* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::moveChildTo):
* rendering/RenderButton.cpp:
(WebCore::RenderButton::addChild):
(WebCore::RenderButton::setText):
* rendering/RenderButton.h:
* rendering/RenderElement.cpp:
(WebCore::RenderElement::addChild):
* rendering/RenderElement.h:
(WebCore::RenderElement::addChildIgnoringContinuation):
* rendering/RenderFullScreen.cpp:
(WebCore::RenderFullScreen::wrapNewRenderer):
(WebCore::RenderFullScreen::wrapExistingRenderer):
(WebCore::RenderFullScreen::unwrapRenderer):
(WebCore::RenderFullScreen::createPlaceholder):
* rendering/RenderGrid.cpp:
(WebCore::RenderGrid::addChild):
* 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::setText):
* rendering/RenderMenuList.h:
* rendering/RenderMultiColumnFlow.cpp:
(WebCore::RenderMultiColumnFlow::processPossibleSpannerDescendant):
* rendering/RenderQuote.cpp:
(WebCore::RenderQuote::updateTextRenderer):
(WebCore::RenderQuote::updateRenderer):
* rendering/RenderQuote.h:
* rendering/RenderRuby.cpp:
(WebCore::RenderRubyAsInline::addChild):
(WebCore::RenderRubyAsBlock::addChild):
* rendering/RenderRuby.h:
* rendering/RenderRubyBase.h:
* rendering/RenderRubyRun.cpp:
(WebCore::RenderRubyRun::rubyBaseSafe):
(WebCore::RenderRubyRun::addChild): Deleted.
* rendering/RenderRubyRun.h:
* rendering/RenderTable.cpp:
(WebCore::RenderTable::addChild):
* rendering/RenderTable.h:
* rendering/RenderTableRow.cpp:
(WebCore::RenderTableRow::addChild):
* rendering/RenderTableRow.h:
* rendering/RenderTableSection.cpp:
(WebCore::RenderTableSection::addChild):
* rendering/RenderTableSection.h:
* rendering/RenderTreeBuilder.cpp: Added.
(WebCore::RenderTreeBuilder::RenderTreeBuilder):
(WebCore::RenderTreeBuilder::~RenderTreeBuilder):
(WebCore::RenderTreeBuilder::insertChild):
(WebCore::RenderTreeBuilder::rubyRunInsertChild):
* rendering/RenderTreeBuilder.h: Added.
(WebCore::RenderTreeBuilder::current):
* rendering/TextAutoSizing.cpp:
(WebCore::TextAutoSizingValue::adjustTextNodeSizes):
* rendering/mathml/RenderMathMLFenced.cpp:
(WebCore::RenderMathMLFenced::updateFromElement):
(WebCore::RenderMathMLFenced::makeFences):
(WebCore::RenderMathMLFenced::addChild):
* rendering/mathml/RenderMathMLFenced.h:
* rendering/svg/RenderSVGContainer.cpp:
(WebCore::RenderSVGContainer::addChild):
* rendering/svg/RenderSVGContainer.h:
* rendering/svg/RenderSVGInline.cpp:
(WebCore::RenderSVGInline::addChild):
* rendering/svg/RenderSVGInline.h:
* rendering/svg/RenderSVGRoot.cpp:
(WebCore::RenderSVGRoot::addChild):
* rendering/svg/RenderSVGRoot.h:
* rendering/svg/RenderSVGText.cpp:
(WebCore::RenderSVGText::addChild):
* rendering/svg/RenderSVGText.h:
* style/RenderTreePosition.cpp:
(WebCore::RenderTreePosition::insert): Deleted.
* style/RenderTreePosition.h:
(WebCore::RenderTreePosition::RenderTreePosition):
(WebCore::RenderTreePosition::nextSibling const):
(WebCore::RenderTreePosition::canInsert const): Deleted.
* style/RenderTreeUpdater.cpp:
(WebCore::RenderTreeUpdater::updateAfterDescendants):
(WebCore::RenderTreeUpdater::createRenderer):
(WebCore::RenderTreeUpdater::createTextRenderer):
(WebCore::RenderTreeUpdater::updateTextRenderer):
(WebCore::createTextRenderer): Deleted.
* style/RenderTreeUpdater.h:
* style/RenderTreeUpdaterFirstLetter.cpp:
(WebCore::updateFirstLetterStyle):
(WebCore::createFirstLetterRenderer):
* style/RenderTreeUpdaterGeneratedContent.cpp:
(WebCore::RenderTreeUpdater::GeneratedContent::updateQuotesUpTo):
(WebCore::createContentRenderers):
(WebCore::RenderTreeUpdater::GeneratedContent::updatePseudoElement):
* style/RenderTreeUpdaterListItem.cpp:
(WebCore::RenderTreeUpdater::ListItem::updateMarker):
* style/RenderTreeUpdaterListItem.h:
* style/RenderTreeUpdaterMultiColumn.cpp:
(WebCore::RenderTreeUpdater::MultiColumn::createFragmentedFlow):
(WebCore::RenderTreeUpdater::MultiColumn::destroyFragmentedFlow):

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

59 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Sources.txt
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/dom/Element.cpp
Source/WebCore/dom/Element.h
Source/WebCore/rendering/RenderBlock.cpp
Source/WebCore/rendering/RenderBlock.h
Source/WebCore/rendering/RenderBlockFlow.cpp
Source/WebCore/rendering/RenderBlockFlow.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/RenderQuote.cpp
Source/WebCore/rendering/RenderQuote.h
Source/WebCore/rendering/RenderRuby.cpp
Source/WebCore/rendering/RenderRuby.h
Source/WebCore/rendering/RenderRubyBase.h
Source/WebCore/rendering/RenderRubyRun.cpp
Source/WebCore/rendering/RenderRubyRun.h
Source/WebCore/rendering/RenderTable.cpp
Source/WebCore/rendering/RenderTable.h
Source/WebCore/rendering/RenderTableRow.cpp
Source/WebCore/rendering/RenderTableRow.h
Source/WebCore/rendering/RenderTableSection.cpp
Source/WebCore/rendering/RenderTableSection.h
Source/WebCore/rendering/RenderTreeBuilder.cpp [new file with mode: 0644]
Source/WebCore/rendering/RenderTreeBuilder.h [new file with mode: 0644]
Source/WebCore/rendering/TextAutoSizing.cpp
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.cpp
Source/WebCore/style/RenderTreePosition.h
Source/WebCore/style/RenderTreeUpdater.cpp
Source/WebCore/style/RenderTreeUpdater.h
Source/WebCore/style/RenderTreeUpdaterFirstLetter.cpp
Source/WebCore/style/RenderTreeUpdaterGeneratedContent.cpp
Source/WebCore/style/RenderTreeUpdaterGeneratedContent.h
Source/WebCore/style/RenderTreeUpdaterListItem.cpp
Source/WebCore/style/RenderTreeUpdaterListItem.h
Source/WebCore/style/RenderTreeUpdaterMultiColumn.cpp

index 1e87e23..8cb2376 100644 (file)
@@ -1,3 +1,136 @@
+2017-12-15  Antti Koivisto  <antti@apple.com>
+
+        Introduce RenderTreeBuilder
+        https://bugs.webkit.org/show_bug.cgi?id=180817
+
+        Reviewed by Zalan Bujtas.
+
+        RenderTreeBuilder is responsible of building the render tree, including construction of various anonymous
+        renderers. Renderer subtype specific render tree construction code will eventually move there.
+
+        This patch adds RenderTreeBuilder class and passes it as a parameter for all addChild implementations.
+        Future patches can then mechanically move the building code from renderers to RenderTreeBuilder.
+
+        It also moves one addChild implementation (RenderRuby::addChild -> RenderTreeBuilder::rubyRunInsertChild)
+        to RenderTreeBuilder as a test.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::addChildToContinuation):
+        (WebCore::RenderBlock::addChild):
+        (WebCore::RenderBlock::addChildIgnoringContinuation):
+        * rendering/RenderBlock.h:
+        * rendering/RenderBlockFlow.cpp:
+        (WebCore::RenderBlockFlow::addChild):
+        * rendering/RenderBlockFlow.h:
+        * rendering/RenderBoxModelObject.cpp:
+        (WebCore::RenderBoxModelObject::moveChildTo):
+        * rendering/RenderButton.cpp:
+        (WebCore::RenderButton::addChild):
+        (WebCore::RenderButton::setText):
+        * rendering/RenderButton.h:
+        * rendering/RenderElement.cpp:
+        (WebCore::RenderElement::addChild):
+        * rendering/RenderElement.h:
+        (WebCore::RenderElement::addChildIgnoringContinuation):
+        * rendering/RenderFullScreen.cpp:
+        (WebCore::RenderFullScreen::wrapNewRenderer):
+        (WebCore::RenderFullScreen::wrapExistingRenderer):
+        (WebCore::RenderFullScreen::unwrapRenderer):
+        (WebCore::RenderFullScreen::createPlaceholder):
+        * rendering/RenderGrid.cpp:
+        (WebCore::RenderGrid::addChild):
+        * 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::setText):
+        * rendering/RenderMenuList.h:
+        * rendering/RenderMultiColumnFlow.cpp:
+        (WebCore::RenderMultiColumnFlow::processPossibleSpannerDescendant):
+        * rendering/RenderQuote.cpp:
+        (WebCore::RenderQuote::updateTextRenderer):
+        (WebCore::RenderQuote::updateRenderer):
+        * rendering/RenderQuote.h:
+        * rendering/RenderRuby.cpp:
+        (WebCore::RenderRubyAsInline::addChild):
+        (WebCore::RenderRubyAsBlock::addChild):
+        * rendering/RenderRuby.h:
+        * rendering/RenderRubyBase.h:
+        * rendering/RenderRubyRun.cpp:
+        (WebCore::RenderRubyRun::rubyBaseSafe):
+        (WebCore::RenderRubyRun::addChild): Deleted.
+        * rendering/RenderRubyRun.h:
+        * rendering/RenderTable.cpp:
+        (WebCore::RenderTable::addChild):
+        * rendering/RenderTable.h:
+        * rendering/RenderTableRow.cpp:
+        (WebCore::RenderTableRow::addChild):
+        * rendering/RenderTableRow.h:
+        * rendering/RenderTableSection.cpp:
+        (WebCore::RenderTableSection::addChild):
+        * rendering/RenderTableSection.h:
+        * rendering/RenderTreeBuilder.cpp: Added.
+        (WebCore::RenderTreeBuilder::RenderTreeBuilder):
+        (WebCore::RenderTreeBuilder::~RenderTreeBuilder):
+        (WebCore::RenderTreeBuilder::insertChild):
+        (WebCore::RenderTreeBuilder::rubyRunInsertChild):
+        * rendering/RenderTreeBuilder.h: Added.
+        (WebCore::RenderTreeBuilder::current):
+        * rendering/TextAutoSizing.cpp:
+        (WebCore::TextAutoSizingValue::adjustTextNodeSizes):
+        * rendering/mathml/RenderMathMLFenced.cpp:
+        (WebCore::RenderMathMLFenced::updateFromElement):
+        (WebCore::RenderMathMLFenced::makeFences):
+        (WebCore::RenderMathMLFenced::addChild):
+        * rendering/mathml/RenderMathMLFenced.h:
+        * rendering/svg/RenderSVGContainer.cpp:
+        (WebCore::RenderSVGContainer::addChild):
+        * rendering/svg/RenderSVGContainer.h:
+        * rendering/svg/RenderSVGInline.cpp:
+        (WebCore::RenderSVGInline::addChild):
+        * rendering/svg/RenderSVGInline.h:
+        * rendering/svg/RenderSVGRoot.cpp:
+        (WebCore::RenderSVGRoot::addChild):
+        * rendering/svg/RenderSVGRoot.h:
+        * rendering/svg/RenderSVGText.cpp:
+        (WebCore::RenderSVGText::addChild):
+        * rendering/svg/RenderSVGText.h:
+        * style/RenderTreePosition.cpp:
+        (WebCore::RenderTreePosition::insert): Deleted.
+        * style/RenderTreePosition.h:
+        (WebCore::RenderTreePosition::RenderTreePosition):
+        (WebCore::RenderTreePosition::nextSibling const):
+        (WebCore::RenderTreePosition::canInsert const): Deleted.
+        * style/RenderTreeUpdater.cpp:
+        (WebCore::RenderTreeUpdater::updateAfterDescendants):
+        (WebCore::RenderTreeUpdater::createRenderer):
+        (WebCore::RenderTreeUpdater::createTextRenderer):
+        (WebCore::RenderTreeUpdater::updateTextRenderer):
+        (WebCore::createTextRenderer): Deleted.
+        * style/RenderTreeUpdater.h:
+        * style/RenderTreeUpdaterFirstLetter.cpp:
+        (WebCore::updateFirstLetterStyle):
+        (WebCore::createFirstLetterRenderer):
+        * style/RenderTreeUpdaterGeneratedContent.cpp:
+        (WebCore::RenderTreeUpdater::GeneratedContent::updateQuotesUpTo):
+        (WebCore::createContentRenderers):
+        (WebCore::RenderTreeUpdater::GeneratedContent::updatePseudoElement):
+        * style/RenderTreeUpdaterListItem.cpp:
+        (WebCore::RenderTreeUpdater::ListItem::updateMarker):
+        * style/RenderTreeUpdaterListItem.h:
+        * style/RenderTreeUpdaterMultiColumn.cpp:
+        (WebCore::RenderTreeUpdater::MultiColumn::createFragmentedFlow):
+        (WebCore::RenderTreeUpdater::MultiColumn::destroyFragmentedFlow):
+
 2017-12-14  Youenn Fablet  <youenn@apple.com>
 
         Implement <iframe allow="camera; microphone">
 2017-12-14  Youenn Fablet  <youenn@apple.com>
 
         Implement <iframe allow="camera; microphone">
index 177d0de..b029278 100644 (file)
@@ -1844,6 +1844,7 @@ rendering/RenderTextFragment.cpp
 rendering/RenderTextLineBoxes.cpp
 rendering/RenderTheme.cpp
 rendering/RenderTreeAsText.cpp
 rendering/RenderTextLineBoxes.cpp
 rendering/RenderTheme.cpp
 rendering/RenderTreeAsText.cpp
+rendering/RenderTreeBuilder.cpp
 rendering/RenderVTTCue.cpp
 rendering/RenderVideo.cpp
 rendering/RenderView.cpp
 rendering/RenderVTTCue.cpp
 rendering/RenderVideo.cpp
 rendering/RenderView.cpp
index b8c9095..294e07f 100644 (file)
                E4E9B1191810916F003ACCDF /* SimpleLineLayoutResolver.h in Headers */ = {isa = PBXBuildFile; fileRef = E4E9B1181810916F003ACCDF /* SimpleLineLayoutResolver.h */; };
                E4E9B11D1814569C003ACCDF /* SimpleLineLayoutFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = E4E9B11C1814569C003ACCDF /* SimpleLineLayoutFunctions.h */; };
                E4F9EEF3156DA00700D23E7E /* StyleSheetContents.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F9EEF1156D84C400D23E7E /* StyleSheetContents.h */; settings = {ATTRIBUTES = (Private, ); }; };
                E4E9B1191810916F003ACCDF /* SimpleLineLayoutResolver.h in Headers */ = {isa = PBXBuildFile; fileRef = E4E9B1181810916F003ACCDF /* SimpleLineLayoutResolver.h */; };
                E4E9B11D1814569C003ACCDF /* SimpleLineLayoutFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = E4E9B11C1814569C003ACCDF /* SimpleLineLayoutFunctions.h */; };
                E4F9EEF3156DA00700D23E7E /* StyleSheetContents.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F9EEF1156D84C400D23E7E /* StyleSheetContents.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               E4FC009B1FE00B90006A073E /* RenderTreeBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = E4FC009A1FE00B8F006A073E /* RenderTreeBuilder.h */; };
                E5BA7D63151437CA00FE1E3F /* LengthFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = E5BA7D62151437CA00FE1E3F /* LengthFunctions.h */; settings = {ATTRIBUTES = (Private, ); }; };
                EBF5121C1696496C0056BD25 /* JSTypeConversions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EBF5121A1696496C0056BD25 /* JSTypeConversions.cpp */; };
                EBF5121D1696496C0056BD25 /* JSTypeConversions.h in Headers */ = {isa = PBXBuildFile; fileRef = EBF5121B1696496C0056BD25 /* JSTypeConversions.h */; };
                E5BA7D63151437CA00FE1E3F /* LengthFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = E5BA7D62151437CA00FE1E3F /* LengthFunctions.h */; settings = {ATTRIBUTES = (Private, ); }; };
                EBF5121C1696496C0056BD25 /* JSTypeConversions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EBF5121A1696496C0056BD25 /* JSTypeConversions.cpp */; };
                EBF5121D1696496C0056BD25 /* JSTypeConversions.h in Headers */ = {isa = PBXBuildFile; fileRef = EBF5121B1696496C0056BD25 /* JSTypeConversions.h */; };
                7C7903B01F86F95C00463A70 /* ImageBitmapRenderingContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImageBitmapRenderingContext.h; sourceTree = "<group>"; };
                7C7903B11F86F95C00463A70 /* ImageBitmapRenderingContext.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ImageBitmapRenderingContext.cpp; sourceTree = "<group>"; };
                7C7903B21F86F95C00463A70 /* ImageBitmapRenderingContext.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = ImageBitmapRenderingContext.idl; sourceTree = "<group>"; };
                7C7903B01F86F95C00463A70 /* ImageBitmapRenderingContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImageBitmapRenderingContext.h; sourceTree = "<group>"; };
                7C7903B11F86F95C00463A70 /* ImageBitmapRenderingContext.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ImageBitmapRenderingContext.cpp; sourceTree = "<group>"; };
                7C7903B21F86F95C00463A70 /* ImageBitmapRenderingContext.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = ImageBitmapRenderingContext.idl; sourceTree = "<group>"; };
-               7C7903B71F86FDE400463A70 /* JSImageBitmapRenderingContext.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JSImageBitmapRenderingContext.cpp; sourceTree = "<group>"; };
-               7C7903B81F86FDE600463A70 /* JSImageBitmapRenderingContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSImageBitmapRenderingContext.h; sourceTree = "<group>"; };
                7C7903B51F86FDE400463A70 /* JSImageBitmapRenderingContextSettings.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JSImageBitmapRenderingContextSettings.cpp; sourceTree = "<group>"; };
                7C7903B61F86FDE600463A70 /* JSImageBitmapRenderingContextSettings.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSImageBitmapRenderingContextSettings.h; sourceTree = "<group>"; };
                7C7903B51F86FDE400463A70 /* JSImageBitmapRenderingContextSettings.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JSImageBitmapRenderingContextSettings.cpp; sourceTree = "<group>"; };
                7C7903B61F86FDE600463A70 /* JSImageBitmapRenderingContextSettings.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSImageBitmapRenderingContextSettings.h; sourceTree = "<group>"; };
+               7C7903B71F86FDE400463A70 /* JSImageBitmapRenderingContext.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JSImageBitmapRenderingContext.cpp; sourceTree = "<group>"; };
+               7C7903B81F86FDE600463A70 /* JSImageBitmapRenderingContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSImageBitmapRenderingContext.h; sourceTree = "<group>"; };
                7C7903BA1F86FF3300463A70 /* PlaceholderRenderingContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlaceholderRenderingContext.cpp; sourceTree = "<group>"; };
                7C7903BC1F86FF3400463A70 /* PlaceholderRenderingContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlaceholderRenderingContext.h; sourceTree = "<group>"; };
                7C7941E21C56C29300A4C58E /* DataDetectorsCoreSoftLink.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DataDetectorsCoreSoftLink.mm; sourceTree = "<group>"; };
                7C7903BA1F86FF3300463A70 /* PlaceholderRenderingContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlaceholderRenderingContext.cpp; sourceTree = "<group>"; };
                7C7903BC1F86FF3400463A70 /* PlaceholderRenderingContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlaceholderRenderingContext.h; sourceTree = "<group>"; };
                7C7941E21C56C29300A4C58E /* DataDetectorsCoreSoftLink.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DataDetectorsCoreSoftLink.mm; sourceTree = "<group>"; };
                E4E9B11C1814569C003ACCDF /* SimpleLineLayoutFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleLineLayoutFunctions.h; sourceTree = "<group>"; };
                E4F9EEF0156D84C400D23E7E /* StyleSheetContents.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleSheetContents.cpp; sourceTree = "<group>"; };
                E4F9EEF1156D84C400D23E7E /* StyleSheetContents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleSheetContents.h; sourceTree = "<group>"; };
                E4E9B11C1814569C003ACCDF /* SimpleLineLayoutFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleLineLayoutFunctions.h; sourceTree = "<group>"; };
                E4F9EEF0156D84C400D23E7E /* StyleSheetContents.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleSheetContents.cpp; sourceTree = "<group>"; };
                E4F9EEF1156D84C400D23E7E /* StyleSheetContents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleSheetContents.h; sourceTree = "<group>"; };
+               E4FC00971FE00B83006A073E /* RenderTreeBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderTreeBuilder.cpp; sourceTree = "<group>"; };
+               E4FC009A1FE00B8F006A073E /* RenderTreeBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderTreeBuilder.h; sourceTree = "<group>"; };
                E51A81DE17298D7700BFCA61 /* JSPerformance.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPerformance.cpp; sourceTree = "<group>"; };
                E526AF3E1727F8F200E41781 /* Performance.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Performance.cpp; sourceTree = "<group>"; };
                E55F4979151B888000BB67DB /* LengthFunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LengthFunctions.cpp; sourceTree = "<group>"; };
                E51A81DE17298D7700BFCA61 /* JSPerformance.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPerformance.cpp; sourceTree = "<group>"; };
                E526AF3E1727F8F200E41781 /* Performance.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Performance.cpp; sourceTree = "<group>"; };
                E55F4979151B888000BB67DB /* LengthFunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LengthFunctions.cpp; sourceTree = "<group>"; };
                                BCEA4849097D93020094C9E4 /* RenderThemeMac.mm */,
                                93955A4203D72932008635CE /* RenderTreeAsText.cpp */,
                                93955A4103D72932008635CE /* RenderTreeAsText.h */,
                                BCEA4849097D93020094C9E4 /* RenderThemeMac.mm */,
                                93955A4203D72932008635CE /* RenderTreeAsText.cpp */,
                                93955A4103D72932008635CE /* RenderTreeAsText.h */,
+                               E4FC00971FE00B83006A073E /* RenderTreeBuilder.cpp */,
+                               E4FC009A1FE00B8F006A073E /* RenderTreeBuilder.h */,
                                E4B41E330CBFB60900AF2ECE /* RenderVideo.cpp */,
                                E4B41E340CBFB60900AF2ECE /* RenderVideo.h */,
                                BCEA4828097D93020094C9E4 /* RenderView.cpp */,
                                E4B41E330CBFB60900AF2ECE /* RenderVideo.cpp */,
                                E4B41E340CBFB60900AF2ECE /* RenderVideo.h */,
                                BCEA4828097D93020094C9E4 /* RenderView.cpp */,
                                416E6FE81BBD12DF000A6043 /* ReadableByteStreamInternalsBuiltins.h in Headers */,
                                416E6FE91BBD12E5000A6043 /* ReadableStreamBuiltins.h in Headers */,
                                4129C9A91F59C56B009D7403 /* ReadableStreamDefaultController.h in Headers */,
                                416E6FE81BBD12DF000A6043 /* ReadableByteStreamInternalsBuiltins.h in Headers */,
                                416E6FE91BBD12E5000A6043 /* ReadableStreamBuiltins.h in Headers */,
                                4129C9A91F59C56B009D7403 /* ReadableStreamDefaultController.h in Headers */,
+                               E4FC009B1FE00B90006A073E /* RenderTreeBuilder.h in Headers */,
                                416E6FE81BBD12DF000A3F64 /* ReadableStreamInternalsBuiltins.h in Headers */,
                                4129C9AF1F59CF5B009D7403 /* ReadableStreamSink.h in Headers */,
                                4129C9AB1F59C573009D7403 /* ReadableStreamSource.h in Headers */,
                                416E6FE81BBD12DF000A3F64 /* ReadableStreamInternalsBuiltins.h in Headers */,
                                4129C9AF1F59CF5B009D7403 /* ReadableStreamSink.h in Headers */,
                                4129C9AB1F59C573009D7403 /* ReadableStreamSource.h in Headers */,
index adb67c1..336f425 100644 (file)
@@ -2916,8 +2916,7 @@ static void disconnectPseudoElement(PseudoElement* pseudoElement)
 {
     if (!pseudoElement)
         return;
 {
     if (!pseudoElement)
         return;
-    if (pseudoElement->renderer())
-        RenderTreeUpdater::tearDownRenderers(*pseudoElement);
+    ASSERT(!pseudoElement->renderer());
     ASSERT(pseudoElement->hostElement());
     pseudoElement->clearHostElement();
 }
     ASSERT(pseudoElement->hostElement());
     pseudoElement->clearHostElement();
 }
@@ -3395,12 +3394,6 @@ void Element::resetStyleRelations()
     elementRareData()->resetStyleRelations();
 }
 
     elementRareData()->resetStyleRelations();
 }
 
-void Element::clearStyleDerivedDataBeforeDetachingRenderer()
-{
-    clearBeforePseudoElement();
-    clearAfterPseudoElement();
-}
-
 void Element::clearHoverAndActiveStatusBeforeDetachingRenderer()
 {
     if (!isUserActionElement())
 void Element::clearHoverAndActiveStatusBeforeDetachingRenderer()
 {
     if (!isUserActionElement())
index 215c95f..a128d27 100644 (file)
@@ -515,7 +515,6 @@ public:
     void clearAfterPseudoElement();
     void resetComputedStyle();
     void resetStyleRelations();
     void clearAfterPseudoElement();
     void resetComputedStyle();
     void resetStyleRelations();
-    void clearStyleDerivedDataBeforeDetachingRenderer();
     void clearHoverAndActiveStatusBeforeDetachingRenderer();
 
     WEBCORE_EXPORT URL absoluteLinkURL() const;
     void clearHoverAndActiveStatusBeforeDetachingRenderer();
 
     WEBCORE_EXPORT URL absoluteLinkURL() const;
index f492f18..e0aec8b 100644 (file)
@@ -61,6 +61,7 @@
 #include "RenderTableCell.h"
 #include "RenderTextFragment.h"
 #include "RenderTheme.h"
 #include "RenderTableCell.h"
 #include "RenderTextFragment.h"
 #include "RenderTheme.h"
+#include "RenderTreeBuilder.h"
 #include "RenderTreePosition.h"
 #include "RenderView.h"
 #include "Settings.h"
 #include "RenderTreePosition.h"
 #include "RenderView.h"
 #include "Settings.h"
@@ -468,7 +469,7 @@ RenderBlock* RenderBlock::continuationBefore(RenderObject* beforeChild)
     return last;
 }
 
     return last;
 }
 
-void RenderBlock::addChildToContinuation(RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
+void RenderBlock::addChildToContinuation(RenderTreeBuilder& builder, RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
     RenderBlock* flow = continuationBefore(beforeChild);
     ASSERT(!beforeChild || is<RenderBlock>(*beforeChild->parent()));
 {
     RenderBlock* flow = continuationBefore(beforeChild);
     ASSERT(!beforeChild || is<RenderBlock>(*beforeChild->parent()));
@@ -484,7 +485,7 @@ void RenderBlock::addChildToContinuation(RenderPtr<RenderObject> newChild, Rende
     }
 
     if (newChild->isFloatingOrOutOfFlowPositioned()) {
     }
 
     if (newChild->isFloatingOrOutOfFlowPositioned()) {
-        beforeChildParent->addChildIgnoringContinuation(WTFMove(newChild), beforeChild);
+        beforeChildParent->addChildIgnoringContinuation(builder, WTFMove(newChild), beforeChild);
         return;
     }
 
         return;
     }
 
@@ -493,21 +494,21 @@ void RenderBlock::addChildToContinuation(RenderPtr<RenderObject> newChild, Rende
     bool flowIsNormal = flow->isInline() || !flow->style().columnSpan();
 
     if (flow == beforeChildParent) {
     bool flowIsNormal = flow->isInline() || !flow->style().columnSpan();
 
     if (flow == beforeChildParent) {
-        flow->addChildIgnoringContinuation(WTFMove(newChild), beforeChild);
+        flow->addChildIgnoringContinuation(builder, 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) {
         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(WTFMove(newChild), beforeChild);
+        beforeChildParent->addChildIgnoringContinuation(builder, WTFMove(newChild), beforeChild);
         return;
     }
     if (flowIsNormal == childIsNormal) {
         return;
     }
     if (flowIsNormal == childIsNormal) {
-        flow->addChildIgnoringContinuation(WTFMove(newChild), 0); // Just treat like an append.
+        flow->addChildIgnoringContinuation(builder, WTFMove(newChild), 0); // Just treat like an append.
         return;
     }
         return;
     }
-    beforeChildParent->addChildIgnoringContinuation(WTFMove(newChild), beforeChild);
+    beforeChildParent->addChildIgnoringContinuation(builder, WTFMove(newChild), beforeChild);
 }
 
 RenderPtr<RenderBlock> RenderBlock::clone() const
 }
 
 RenderPtr<RenderBlock> RenderBlock::clone() const
@@ -530,15 +531,15 @@ RenderPtr<RenderBlock> RenderBlock::clone() const
     return cloneBlock;
 }
 
     return cloneBlock;
 }
 
-void RenderBlock::addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
+void RenderBlock::addChild(RenderTreeBuilder& builder, RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
     if (continuation() && !isAnonymousBlock())
 {
     if (continuation() && !isAnonymousBlock())
-        addChildToContinuation(WTFMove(newChild), beforeChild);
+        addChildToContinuation(builder, WTFMove(newChild), beforeChild);
     else
     else
-        addChildIgnoringContinuation(WTFMove(newChild), beforeChild);
+        addChildIgnoringContinuation(builder, WTFMove(newChild), beforeChild);
 }
 
 }
 
-void RenderBlock::addChildIgnoringContinuation(RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
+void RenderBlock::addChildIgnoringContinuation(RenderTreeBuilder& builder, RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
     if (beforeChild && beforeChild->parent() != this) {
         RenderElement* beforeChildContainer = beforeChild->parent();
 {
     if (beforeChild && beforeChild->parent() != this) {
         RenderElement* beforeChildContainer = beforeChild->parent();
@@ -561,9 +562,9 @@ void RenderBlock::addChildIgnoringContinuation(RenderPtr<RenderObject> newChild,
                 ) {
                 // Insert the child into the anonymous block box instead of here.
                 if (newChild->isInline() || beforeChild->parent()->firstChild() != beforeChild)
                 ) {
                 // Insert the child into the anonymous block box instead of here.
                 if (newChild->isInline() || beforeChild->parent()->firstChild() != beforeChild)
-                    beforeChild->parent()->addChild(WTFMove(newChild), beforeChild);
+                    beforeChild->parent()->addChild(builder, WTFMove(newChild), beforeChild);
                 else
                 else
-                    addChild(WTFMove(newChild), beforeChild->parent());
+                    addChild(builder, WTFMove(newChild), beforeChild->parent());
                 return;
             }
 
                 return;
             }
 
@@ -571,7 +572,7 @@ void RenderBlock::addChildIgnoringContinuation(RenderPtr<RenderObject> newChild,
 
             if (newChild->isTablePart()) {
                 // Insert into the anonymous table.
 
             if (newChild->isTablePart()) {
                 // Insert into the anonymous table.
-                beforeChildAnonymousContainer->addChild(WTFMove(newChild), beforeChild);
+                beforeChildAnonymousContainer->addChild(builder, WTFMove(newChild), beforeChild);
                 return;
             }
 
                 return;
             }
 
@@ -603,7 +604,7 @@ void RenderBlock::addChildIgnoringContinuation(RenderPtr<RenderObject> newChild,
         RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : lastChild();
 
         if (afterChild && afterChild->isAnonymousBlock()) {
         RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : lastChild();
 
         if (afterChild && afterChild->isAnonymousBlock()) {
-            downcast<RenderBlock>(*afterChild).addChild(WTFMove(newChild));
+            builder.insertChild(downcast<RenderBlock>(*afterChild), WTFMove(newChild));
             return;
         }
 
             return;
         }
 
@@ -611,15 +612,15 @@ void RenderBlock::addChildIgnoringContinuation(RenderPtr<RenderObject> newChild,
             // No suitable existing anonymous box - create a new one.
             auto newBox = createAnonymousBlock();
             auto& box = *newBox;
             // No suitable existing anonymous box - create a new one.
             auto newBox = createAnonymousBlock();
             auto& box = *newBox;
-            RenderBox::addChild(WTFMove(newBox), beforeChild);
-            box.addChild(WTFMove(newChild));
+            RenderBox::addChild(builder, WTFMove(newBox), beforeChild);
+            builder.insertChild(box, WTFMove(newChild));
             return;
         }
     }
 
     invalidateLineLayoutPath();
 
             return;
         }
     }
 
     invalidateLineLayoutPath();
 
-    RenderBox::addChild(WTFMove(newChild), beforeChild);
+    RenderBox::addChild(builder, WTFMove(newChild), beforeChild);
  
     if (madeBoxesNonInline && is<RenderBlock>(parent()) && isAnonymousBlock())
         downcast<RenderBlock>(*parent()).removeLeftoverAnonymousBlock(this);
  
     if (madeBoxesNonInline && is<RenderBlock>(parent()) && isAnonymousBlock())
         downcast<RenderBlock>(*parent()).removeLeftoverAnonymousBlock(this);
index de7bfc4..ba5bac3 100644 (file)
@@ -73,7 +73,7 @@ public:
     // FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
     virtual void deleteLines();
 
     // FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
     virtual void deleteLines();
 
-    void addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild = 0) override;
+    void addChild(RenderTreeBuilder&, RenderPtr<RenderObject> newChild, RenderObject* beforeChild = 0) override;
     RenderPtr<RenderObject> takeChild(RenderObject&) override;
 
     virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0);
     RenderPtr<RenderObject> takeChild(RenderObject&) override;
 
     virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0);
@@ -440,8 +440,8 @@ private:
     // FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
     virtual void moveAllChildrenIncludingFloatsTo(RenderBlock& toBlock, RenderBoxModelObject::NormalizeAfterInsertion normalizeAfterInsertion) { moveAllChildrenTo(&toBlock, normalizeAfterInsertion); }
 
     // FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
     virtual void moveAllChildrenIncludingFloatsTo(RenderBlock& toBlock, RenderBoxModelObject::NormalizeAfterInsertion normalizeAfterInsertion) { moveAllChildrenTo(&toBlock, normalizeAfterInsertion); }
 
-    void addChildToContinuation(RenderPtr<RenderObject> newChild, RenderObject* beforeChild);
-    void addChildIgnoringContinuation(RenderPtr<RenderObject> newChild, RenderObject* beforeChild) override;
+    void addChildToContinuation(RenderTreeBuilder&, RenderPtr<RenderObject> newChild, RenderObject* beforeChild);
+    void addChildIgnoringContinuation(RenderTreeBuilder&, RenderPtr<RenderObject> newChild, RenderObject* beforeChild) override;
 
     bool isSelfCollapsingBlock() const override;
     virtual bool childrenPreventSelfCollapsing() const;
 
     bool isSelfCollapsingBlock() const override;
     virtual bool childrenPreventSelfCollapsing() const;
index 985a744..bc8f58f 100644 (file)
@@ -48,6 +48,7 @@
 #include "RenderMultiColumnSet.h"
 #include "RenderTableCell.h"
 #include "RenderText.h"
 #include "RenderMultiColumnSet.h"
 #include "RenderTableCell.h"
 #include "RenderText.h"
+#include "RenderTreeBuilder.h"
 #include "RenderView.h"
 #include "Settings.h"
 #include "SimpleLineLayoutFunctions.h"
 #include "RenderView.h"
 #include "Settings.h"
 #include "SimpleLineLayoutFunctions.h"
@@ -3828,14 +3829,14 @@ void RenderBlockFlow::layoutExcludedChildren(bool relayoutChildren)
     determineLogicalLeftPositionForChild(*fragmentedFlow);
 }
 
     determineLogicalLeftPositionForChild(*fragmentedFlow);
 }
 
-void RenderBlockFlow::addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
+void RenderBlockFlow::addChild(RenderTreeBuilder& builder, RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
     if (multiColumnFlow() && (!isFieldset() || !newChild->isLegend()))
 {
     if (multiColumnFlow() && (!isFieldset() || !newChild->isLegend()))
-        return multiColumnFlow()->addChild(WTFMove(newChild), beforeChild);
+        return builder.insertChild(*multiColumnFlow(), WTFMove(newChild), beforeChild);
     auto* beforeChildOrPlaceholder = beforeChild;
     if (auto* containingFragmentedFlow = enclosingFragmentedFlow())
         beforeChildOrPlaceholder = containingFragmentedFlow->resolveMovedChild(beforeChild);
     auto* beforeChildOrPlaceholder = beforeChild;
     if (auto* containingFragmentedFlow = enclosingFragmentedFlow())
         beforeChildOrPlaceholder = containingFragmentedFlow->resolveMovedChild(beforeChild);
-    RenderBlock::addChild(WTFMove(newChild), beforeChildOrPlaceholder);
+    RenderBlock::addChild(builder, WTFMove(newChild), beforeChildOrPlaceholder);
 }
 
 RenderPtr<RenderObject> RenderBlockFlow::takeChild(RenderObject& oldChild)
 }
 
 RenderPtr<RenderObject> RenderBlockFlow::takeChild(RenderObject& oldChild)
index 97a9204..14f0970 100644 (file)
@@ -378,7 +378,7 @@ public:
     LayoutUnit logicalHeightForChildForFragmentation(const RenderBox& child) const;
     bool hasNextPage(LayoutUnit logicalOffset, PageBoundaryRule = ExcludePageBoundary) const;
 
     LayoutUnit logicalHeightForChildForFragmentation(const RenderBox& child) const;
     bool hasNextPage(LayoutUnit logicalOffset, PageBoundaryRule = ExcludePageBoundary) const;
 
-    void addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild = 0) override;
+    void addChild(RenderTreeBuilder&, RenderPtr<RenderObject> newChild, RenderObject* beforeChild = 0) override;
     RenderPtr<RenderObject> takeChild(RenderObject&) override;
 
     void updateColumnProgressionFromStyle(RenderStyle&);
     RenderPtr<RenderObject> takeChild(RenderObject&) override;
 
     void updateColumnProgressionFromStyle(RenderStyle&);
index a8a1120..e4f5886 100644 (file)
@@ -53,6 +53,7 @@
 #include "RenderTableRow.h"
 #include "RenderText.h"
 #include "RenderTextFragment.h"
 #include "RenderTableRow.h"
 #include "RenderText.h"
 #include "RenderTextFragment.h"
+#include "RenderTreeBuilder.h"
 #include "RenderView.h"
 #include "ScrollingConstraints.h"
 #include "Settings.h"
 #include "RenderView.h"
 #include "ScrollingConstraints.h"
 #include "Settings.h"
@@ -2696,7 +2697,7 @@ void RenderBoxModelObject::moveChildTo(RenderBoxModelObject* toBoxModelObject, R
         // Takes care of adding the new child correctly if toBlock and fromBlock
         // have different kind of children (block vs inline).
         auto childToMove = takeChildInternal(*child);
         // Takes care of adding the new child correctly if toBlock and fromBlock
         // have different kind of children (block vs inline).
         auto childToMove = takeChildInternal(*child);
-        toBoxModelObject->addChild(WTFMove(childToMove), beforeChild);
+        RenderTreeBuilder::current()->insertChild(*toBoxModelObject, WTFMove(childToMove), beforeChild);
     } else {
         auto childToMove = takeChildInternal(*child);
         toBoxModelObject->insertChildInternal(WTFMove(childToMove), beforeChild);
     } else {
         auto childToMove = takeChildInternal(*child);
         toBoxModelObject->insertChildInternal(WTFMove(childToMove), beforeChild);
index 22dc477..df3e5c7 100644 (file)
@@ -27,6 +27,7 @@
 #include "HTMLNames.h"
 #include "RenderTextFragment.h"
 #include "RenderTheme.h"
 #include "HTMLNames.h"
 #include "RenderTextFragment.h"
 #include "RenderTheme.h"
+#include "RenderTreeBuilder.h"
 #include "StyleInheritedData.h"
 #include <wtf/IsoMallocInlines.h>
 
 #include "StyleInheritedData.h"
 #include <wtf/IsoMallocInlines.h>
 
@@ -62,7 +63,7 @@ bool RenderButton::hasLineIfEmpty() const
     return is<HTMLInputElement>(formControlElement());
 }
 
     return is<HTMLInputElement>(formControlElement());
 }
 
-void RenderButton::addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
+void RenderButton::addChild(RenderTreeBuilder& builder, RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
     if (!m_inner) {
         // Create an anonymous block.
 {
     if (!m_inner) {
         // Create an anonymous block.
@@ -70,9 +71,9 @@ void RenderButton::addChild(RenderPtr<RenderObject> newChild, RenderObject* befo
         auto newInner = createAnonymousBlock(style().display());
         updateAnonymousChildStyle(*newInner, newInner->mutableStyle());
         m_inner = makeWeakPtr(*newInner);
         auto newInner = createAnonymousBlock(style().display());
         updateAnonymousChildStyle(*newInner, newInner->mutableStyle());
         m_inner = makeWeakPtr(*newInner);
-        RenderFlexibleBox::addChild(WTFMove(newInner));
+        RenderFlexibleBox::addChild(builder, WTFMove(newInner));
     }    
     }    
-    m_inner->addChild(WTFMove(newChild), beforeChild);
+    builder.insertChild(*m_inner, WTFMove(newChild), beforeChild);
 }
 
 RenderPtr<RenderObject> RenderButton::takeChild(RenderObject& oldChild)
 }
 
 RenderPtr<RenderObject> RenderButton::takeChild(RenderObject& oldChild)
@@ -122,7 +123,7 @@ void RenderButton::setText(const String& str)
     if (!m_buttonText) {
         auto newButtonText = createRenderer<RenderTextFragment>(document(), str);
         m_buttonText = makeWeakPtr(*newButtonText);
     if (!m_buttonText) {
         auto newButtonText = createRenderer<RenderTextFragment>(document(), str);
         m_buttonText = makeWeakPtr(*newButtonText);
-        addChild(WTFMove(newButtonText));
+        RenderTreeBuilder::current()->insertChild(*this, WTFMove(newButtonText));
         return;
     }
 
         return;
     }
 
index 7d40716..6ef043d 100644 (file)
@@ -41,7 +41,7 @@ public:
 
     bool canBeSelectionLeaf() const override;
 
 
     bool canBeSelectionLeaf() const override;
 
-    void addChild(RenderPtr<RenderObject> newChild, RenderObject *beforeChild = 0) override;
+    void addChild(RenderTreeBuilder&, RenderPtr<RenderObject> newChild, RenderObject *beforeChild = 0) override;
     RenderPtr<RenderObject> takeChild(RenderObject&) override;
     void removeLeftoverAnonymousBlock(RenderBlock*) override { }
     bool createsAnonymousWrapper() const override { return true; }
     RenderPtr<RenderObject> takeChild(RenderObject&) override;
     void removeLeftoverAnonymousBlock(RenderBlock*) override { }
     bool createsAnonymousWrapper() const override { return true; }
index 9d22d57..31a3611 100644 (file)
@@ -66,6 +66,7 @@
 #include "RenderTableRow.h"
 #include "RenderText.h"
 #include "RenderTheme.h"
 #include "RenderTableRow.h"
 #include "RenderText.h"
 #include "RenderTheme.h"
+#include "RenderTreeBuilder.h"
 #include "RenderView.h"
 #include "SVGRenderSupport.h"
 #include "Settings.h"
 #include "RenderView.h"
 #include "SVGRenderSupport.h"
 #include "Settings.h"
@@ -475,7 +476,7 @@ bool RenderElement::childRequiresTable(const RenderObject& child) const
     return false;
 }
 
     return false;
 }
 
-void RenderElement::addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
+void RenderElement::addChild(RenderTreeBuilder& builder, RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
     auto& child = *newChild;
     if (childRequiresTable(child)) {
 {
     auto& child = *newChild;
     if (childRequiresTable(child)) {
@@ -484,12 +485,12 @@ void RenderElement::addChild(RenderPtr<RenderObject> newChild, RenderObject* bef
         if (afterChild && afterChild->isAnonymous() && is<RenderTable>(*afterChild) && !afterChild->isBeforeContent())
             table = downcast<RenderTable>(afterChild);
         else {
         if (afterChild && afterChild->isAnonymous() && is<RenderTable>(*afterChild) && !afterChild->isBeforeContent())
             table = downcast<RenderTable>(afterChild);
         else {
-            auto newTable =  RenderTable::createAnonymousWithParentRenderer(*this);
+            auto newTable = RenderTable::createAnonymousWithParentRenderer(*this);
             table = newTable.get();
             table = newTable.get();
-            addChild(WTFMove(newTable), beforeChild);
+            builder.insertChild(*this, WTFMove(newTable), beforeChild);
         }
 
         }
 
-        table->addChild(WTFMove(newChild));
+        builder.insertChild(*table, WTFMove(newChild));
     } else
         insertChildInternal(WTFMove(newChild), beforeChild);
 
     } else
         insertChildInternal(WTFMove(newChild), beforeChild);
 
index a867d2d..5e66e51 100644 (file)
@@ -29,6 +29,7 @@ namespace WebCore {
 
 class ControlStates;
 class RenderBlock;
 
 class ControlStates;
 class RenderBlock;
+class RenderTreeBuilder;
 
 class RenderElement : public RenderObject {
     WTF_MAKE_ISO_ALLOCATED(RenderElement);
 
 class RenderElement : public RenderObject {
     WTF_MAKE_ISO_ALLOCATED(RenderElement);
@@ -86,8 +87,8 @@ public:
     bool isRenderInline() const;
 
     virtual bool isChildAllowed(const RenderObject&, const RenderStyle&) const { return true; }
     bool isRenderInline() const;
 
     virtual bool isChildAllowed(const RenderObject&, const RenderStyle&) const { return true; }
-    virtual void addChild(RenderPtr<RenderObject>, RenderObject* beforeChild = nullptr);
-    virtual void addChildIgnoringContinuation(RenderPtr<RenderObject> newChild, RenderObject* beforeChild = nullptr) { addChild(WTFMove(newChild), beforeChild); }
+    virtual void addChild(RenderTreeBuilder&, RenderPtr<RenderObject>, RenderObject* beforeChild);
+    virtual void addChildIgnoringContinuation(RenderTreeBuilder& builder, RenderPtr<RenderObject> newChild, RenderObject* beforeChild = nullptr) { addChild(builder, WTFMove(newChild), beforeChild); }
     virtual RenderPtr<RenderObject> takeChild(RenderObject&) WARN_UNUSED_RETURN;
     void removeAndDestroyChild(RenderObject&);
 
     virtual RenderPtr<RenderObject> takeChild(RenderObject&) WARN_UNUSED_RETURN;
     void removeAndDestroyChild(RenderObject&);
 
index 451d5fa..431a307 100644 (file)
@@ -31,6 +31,7 @@
 #include "RenderBlockFlow.h"
 #include "RenderLayer.h"
 #include "RenderLayerCompositor.h"
 #include "RenderBlockFlow.h"
 #include "RenderLayer.h"
 #include "RenderLayerCompositor.h"
+#include "RenderTreeBuilder.h"
 #include <wtf/IsoMallocInlines.h>
 
 namespace WebCore {
 #include <wtf/IsoMallocInlines.h>
 
 namespace WebCore {
@@ -93,7 +94,7 @@ static RenderStyle createFullScreenStyle()
     return fullscreenStyle;
 }
 
     return fullscreenStyle;
 }
 
-RenderPtr<RenderFullScreen> RenderFullScreen::wrapNewRenderer(RenderPtr<RenderElement> renderer, RenderElement& parent, Document& document)
+RenderPtr<RenderFullScreen> RenderFullScreen::wrapNewRenderer(RenderTreeBuilder& builder, RenderPtr<RenderElement> renderer, RenderElement& parent, Document& document)
 {
     auto newFullscreenRenderer = createRenderer<RenderFullScreen>(document, createFullScreenStyle());
     newFullscreenRenderer->initializeStyle();
 {
     auto newFullscreenRenderer = createRenderer<RenderFullScreen>(document, createFullScreenStyle());
     newFullscreenRenderer->initializeStyle();
@@ -102,7 +103,7 @@ RenderPtr<RenderFullScreen> RenderFullScreen::wrapNewRenderer(RenderPtr<RenderEl
     if (!parent.isChildAllowed(fullscreenRenderer, fullscreenRenderer.style()))
         return nullptr;
 
     if (!parent.isChildAllowed(fullscreenRenderer, fullscreenRenderer.style()))
         return nullptr;
 
-    fullscreenRenderer.addChild(WTFMove(renderer));
+    builder.insertChild(fullscreenRenderer, WTFMove(renderer));
     fullscreenRenderer.setNeedsLayoutAndPrefWidthsRecalc();
 
     document.setFullScreenRenderer(&fullscreenRenderer);
     fullscreenRenderer.setNeedsLayoutAndPrefWidthsRecalc();
 
     document.setFullScreenRenderer(&fullscreenRenderer);
@@ -112,6 +113,9 @@ RenderPtr<RenderFullScreen> RenderFullScreen::wrapNewRenderer(RenderPtr<RenderEl
 
 void RenderFullScreen::wrapExistingRenderer(RenderElement& renderer, Document& document)
 {
 
 void RenderFullScreen::wrapExistingRenderer(RenderElement& renderer, Document& document)
 {
+    // FIXME: This should be done by RenderTreeUpdater.
+    RenderTreeBuilder builder;
+
     auto newFullscreenRenderer = createRenderer<RenderFullScreen>(document, createFullScreenStyle());
     newFullscreenRenderer->initializeStyle();
 
     auto newFullscreenRenderer = createRenderer<RenderFullScreen>(document, createFullScreenStyle());
     newFullscreenRenderer->initializeStyle();
 
@@ -126,7 +130,7 @@ void RenderFullScreen::wrapExistingRenderer(RenderElement& renderer, Document& d
     // the line box tree underneath our |containingBlock| is not longer valid.
     containingBlock->deleteLines();
 
     // the line box tree underneath our |containingBlock| is not longer valid.
     containingBlock->deleteLines();
 
-    parent.addChild(WTFMove(newFullscreenRenderer), &renderer);
+    builder.insertChild(parent, WTFMove(newFullscreenRenderer), &renderer);
 
     auto toMove = parent.takeChild(renderer);
 
 
     auto toMove = parent.takeChild(renderer);
 
@@ -136,7 +140,7 @@ void RenderFullScreen::wrapExistingRenderer(RenderElement& renderer, Document& d
     parent.setNeedsLayoutAndPrefWidthsRecalc();
     containingBlock->setNeedsLayoutAndPrefWidthsRecalc();
 
     parent.setNeedsLayoutAndPrefWidthsRecalc();
     containingBlock->setNeedsLayoutAndPrefWidthsRecalc();
 
-    fullscreenRenderer.addChild(WTFMove(toMove));
+    builder.insertChild(fullscreenRenderer, WTFMove(toMove));
     fullscreenRenderer.setNeedsLayoutAndPrefWidthsRecalc();
 
     document.setFullScreenRenderer(&fullscreenRenderer);
     fullscreenRenderer.setNeedsLayoutAndPrefWidthsRecalc();
 
     document.setFullScreenRenderer(&fullscreenRenderer);
@@ -144,6 +148,8 @@ void RenderFullScreen::wrapExistingRenderer(RenderElement& renderer, Document& d
 
 void RenderFullScreen::unwrapRenderer(bool& requiresRenderTreeRebuild)
 {
 
 void RenderFullScreen::unwrapRenderer(bool& requiresRenderTreeRebuild)
 {
+    RenderTreeBuilder builder;
+
     requiresRenderTreeRebuild = false;
     if (parent()) {
         auto* child = firstChild();
     requiresRenderTreeRebuild = false;
     if (parent()) {
         auto* child = firstChild();
@@ -173,7 +179,7 @@ void RenderFullScreen::unwrapRenderer(bool& requiresRenderTreeRebuild)
             if (is<RenderBox>(*child))
                 downcast<RenderBox>(*child).clearOverrideSize();
             auto childToMove = child->parent()->takeChild(*child);
             if (is<RenderBox>(*child))
                 downcast<RenderBox>(*child).clearOverrideSize();
             auto childToMove = child->parent()->takeChild(*child);
-            parent()->addChild(WTFMove(childToMove), this);
+            builder.insertChild(*parent(), WTFMove(childToMove), this);
             parent()->setNeedsLayoutAndPrefWidthsRecalc();
         }
     }
             parent()->setNeedsLayoutAndPrefWidthsRecalc();
         }
     }
@@ -204,7 +210,7 @@ void RenderFullScreen::createPlaceholder(std::unique_ptr<RenderStyle> style, con
 
     m_placeholder = makeWeakPtr(*newPlaceholder);
 
 
     m_placeholder = makeWeakPtr(*newPlaceholder);
 
-    parent()->addChild(WTFMove(newPlaceholder), this);
+    RenderTreeBuilder::current()->insertChild(*parent(), WTFMove(newPlaceholder), this);
     parent()->setNeedsLayoutAndPrefWidthsRecalc();
 }
 
     parent()->setNeedsLayoutAndPrefWidthsRecalc();
 }
 
index dce83ac..5f9c129 100644 (file)
@@ -40,7 +40,7 @@ public:
     RenderBlock* placeholder() { return m_placeholder.get(); }
     void createPlaceholder(std::unique_ptr<RenderStyle>, const LayoutRect& frameRect);
 
     RenderBlock* placeholder() { return m_placeholder.get(); }
     void createPlaceholder(std::unique_ptr<RenderStyle>, const LayoutRect& frameRect);
 
-    static RenderPtr<RenderFullScreen> wrapNewRenderer(RenderPtr<RenderElement>, RenderElement& parent, Document&);
+    static RenderPtr<RenderFullScreen> wrapNewRenderer(RenderTreeBuilder&, RenderPtr<RenderElement>, RenderElement& parent, Document&);
     static void wrapExistingRenderer(RenderElement&, Document&);
     void unwrapRenderer(bool& requiresRenderTreeRebuild);
 
     static void wrapExistingRenderer(RenderElement&, Document&);
     void unwrapRenderer(bool& requiresRenderTreeRebuild);
 
index c1ec915..7765420 100644 (file)
@@ -69,10 +69,10 @@ RenderGrid::RenderGrid(Element& element, RenderStyle&& style)
 
 RenderGrid::~RenderGrid() = default;
 
 
 RenderGrid::~RenderGrid() = default;
 
-void RenderGrid::addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
+void RenderGrid::addChild(RenderTreeBuilder& builder, RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
     auto& child = *newChild;
 {
     auto& child = *newChild;
-    RenderBlock::addChild(WTFMove(newChild), beforeChild);
+    RenderBlock::addChild(builder, 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.
 
     // 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.
index 7a303c8..2a495fd 100644 (file)
@@ -79,7 +79,7 @@ private:
     bool isRenderGrid() const override { return true; }
     void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const override;
 
     bool isRenderGrid() const override { return true; }
     void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const override;
 
-    void addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild) final;
+    void addChild(RenderTreeBuilder&, RenderPtr<RenderObject> newChild, RenderObject* beforeChild) final;
     RenderPtr<RenderObject> takeChild(RenderObject&) final;
 
     StyleSelfAlignmentData selfAlignmentForChild(GridAxis, const RenderBox&, const RenderStyle* = nullptr) const;
     RenderPtr<RenderObject> takeChild(RenderObject&) final;
 
     StyleSelfAlignmentData selfAlignmentForChild(GridAxis, const RenderBox&, const RenderStyle* = nullptr) const;
index f6fb45b..944a89a 100644 (file)
@@ -42,6 +42,7 @@
 #include "RenderListMarker.h"
 #include "RenderTable.h"
 #include "RenderTheme.h"
 #include "RenderListMarker.h"
 #include "RenderTable.h"
 #include "RenderTheme.h"
+#include "RenderTreeBuilder.h"
 #include "RenderView.h"
 #include "Settings.h"
 #include "StyleInheritedData.h"
 #include "RenderView.h"
 #include "Settings.h"
 #include "StyleInheritedData.h"
@@ -254,16 +255,16 @@ LayoutRect RenderInline::localCaretRect(InlineBox* inlineBox, unsigned, LayoutUn
     return caretRect;
 }
 
     return caretRect;
 }
 
-void RenderInline::addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
+void RenderInline::addChild(RenderTreeBuilder& builder, RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
     auto* beforeChildOrPlaceholder = beforeChild;
     if (auto* fragmentedFlow = enclosingFragmentedFlow())
         beforeChildOrPlaceholder = fragmentedFlow->resolveMovedChild(beforeChild);
     if (continuation()) {
 {
     auto* beforeChildOrPlaceholder = beforeChild;
     if (auto* fragmentedFlow = enclosingFragmentedFlow())
         beforeChildOrPlaceholder = fragmentedFlow->resolveMovedChild(beforeChild);
     if (continuation()) {
-        addChildToContinuation(WTFMove(newChild), beforeChildOrPlaceholder);
+        addChildToContinuation(builder, WTFMove(newChild), beforeChildOrPlaceholder);
         return;
     }
         return;
     }
-    addChildIgnoringContinuation(WTFMove(newChild), beforeChildOrPlaceholder);
+    addChildIgnoringContinuation(builder, WTFMove(newChild), beforeChildOrPlaceholder);
 }
 
 static RenderBoxModelObject* nextContinuation(RenderObject* renderer)
 }
 
 static RenderBoxModelObject* nextContinuation(RenderObject* renderer)
@@ -304,7 +305,7 @@ static bool newChildIsInline(const RenderObject& newChild, const RenderInline& p
     return newChild.isInline() | (parent.childRequiresTable(newChild) && parent.style().display() == INLINE);
 }
 
     return newChild.isInline() | (parent.childRequiresTable(newChild) && parent.style().display() == INLINE);
 }
 
-void RenderInline::addChildIgnoringContinuation(RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
+void RenderInline::addChildIgnoringContinuation(RenderTreeBuilder& builder, RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
     // Make sure we don't append things after :after-generated content if we have it.
     if (!beforeChild && isAfterContent(lastChild()))
 {
     // Make sure we don't append things after :after-generated content if we have it.
     if (!beforeChild && isAfterContent(lastChild()))
@@ -332,12 +333,12 @@ void RenderInline::addChildIgnoringContinuation(RenderPtr<RenderObject> newChild
             oldContinuation->removeFromContinuationChain();
         newBox->insertIntoContinuationChainAfter(*this);
 
             oldContinuation->removeFromContinuationChain();
         newBox->insertIntoContinuationChainAfter(*this);
 
-        splitFlow(beforeChild, WTFMove(newBox), WTFMove(newChild), oldContinuation);
+        splitFlow(builder, beforeChild, WTFMove(newBox), WTFMove(newChild), oldContinuation);
         return;
     }
 
     auto& child = *newChild;
         return;
     }
 
     auto& child = *newChild;
-    RenderBoxModelObject::addChild(WTFMove(newChild), beforeChild);
+    RenderBoxModelObject::addChild(builder, WTFMove(newChild), beforeChild);
     child.setNeedsLayoutAndPrefWidthsRecalc();
 }
 
     child.setNeedsLayoutAndPrefWidthsRecalc();
 }
 
@@ -351,7 +352,7 @@ RenderPtr<RenderInline> RenderInline::cloneAsContinuation() const
     return cloneInline;
 }
 
     return cloneInline;
 }
 
-void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
+void RenderInline::splitInlines(RenderTreeBuilder& builder, RenderBlock* fromBlock, RenderBlock* toBlock,
                                 RenderBlock* middleBlock,
                                 RenderObject* beforeChild, RenderBoxModelObject* oldCont)
 {
                                 RenderBlock* middleBlock,
                                 RenderObject* beforeChild, RenderBoxModelObject* oldCont)
 {
@@ -399,7 +400,7 @@ void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
             // every time, which is a bit wasteful.
         }
         auto childToMove = rendererToMove->parent()->takeChildInternal(*rendererToMove);
             // every time, which is a bit wasteful.
         }
         auto childToMove = rendererToMove->parent()->takeChildInternal(*rendererToMove);
-        cloneInline->addChildIgnoringContinuation(WTFMove(childToMove));
+        cloneInline->addChildIgnoringContinuation(builder, WTFMove(childToMove));
         rendererToMove->setNeedsLayoutAndPrefWidthsRecalc();
         rendererToMove = nextSibling;
     }
         rendererToMove->setNeedsLayoutAndPrefWidthsRecalc();
         rendererToMove = nextSibling;
     }
@@ -427,7 +428,7 @@ void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
             cloneInline = downcast<RenderInline>(*current).cloneAsContinuation();
 
             // Insert our child clone as the first child.
             cloneInline = downcast<RenderInline>(*current).cloneAsContinuation();
 
             // Insert our child clone as the first child.
-            cloneInline->addChildIgnoringContinuation(WTFMove(cloneChild));
+            cloneInline->addChildIgnoringContinuation(builder, WTFMove(cloneChild));
 
             // Hook the clone up as a continuation of |curr|.
             cloneInline->insertIntoContinuationChainAfter(*current);
 
             // Hook the clone up as a continuation of |curr|.
             cloneInline->insertIntoContinuationChainAfter(*current);
@@ -437,7 +438,7 @@ void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
             for (auto* sibling = currentChild->nextSibling(); sibling;) {
                 auto* next = sibling->nextSibling();
                 auto childToMove = current->takeChildInternal(*sibling);
             for (auto* sibling = currentChild->nextSibling(); sibling;) {
                 auto* next = sibling->nextSibling();
                 auto childToMove = current->takeChildInternal(*sibling);
-                cloneInline->addChildIgnoringContinuation(WTFMove(childToMove));
+                cloneInline->addChildIgnoringContinuation(builder, WTFMove(childToMove));
                 sibling->setNeedsLayoutAndPrefWidthsRecalc();
                 sibling = next;
             }
                 sibling->setNeedsLayoutAndPrefWidthsRecalc();
                 sibling = next;
             }
@@ -466,7 +467,7 @@ void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
     }
 }
 
     }
 }
 
-void RenderInline::splitFlow(RenderObject* beforeChild, RenderPtr<RenderBlock> newBlockBox, RenderPtr<RenderObject> newChild, RenderBoxModelObject* oldCont)
+void RenderInline::splitFlow(RenderTreeBuilder& builder, RenderObject* beforeChild, RenderPtr<RenderBlock> newBlockBox, RenderPtr<RenderObject> newChild, RenderBoxModelObject* oldCont)
 {
     auto& addedBlockBox = *newBlockBox;
     RenderBlock* pre = nullptr;
 {
     auto& addedBlockBox = *newBlockBox;
     RenderBlock* pre = nullptr;
@@ -515,7 +516,7 @@ void RenderInline::splitFlow(RenderObject* beforeChild, RenderPtr<RenderBlock> n
         }
     }
 
         }
     }
 
-    splitInlines(pre, &post, &addedBlockBox, beforeChild, oldCont);
+    splitInlines(builder, 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.
 
     // 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.
@@ -524,7 +525,7 @@ void RenderInline::splitFlow(RenderObject* beforeChild, RenderPtr<RenderBlock> n
     // 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).
     // 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).
-    addedBlockBox.addChild(WTFMove(newChild));
+    builder.insertChild(addedBlockBox, 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
 
     // 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
@@ -545,7 +546,7 @@ static bool canUseAsParentForContinuation(const RenderObject* renderer)
     return true;
 }
 
     return true;
 }
 
-void RenderInline::addChildToContinuation(RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
+void RenderInline::addChildToContinuation(RenderTreeBuilder& builder, RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
     auto* flow = continuationBefore(beforeChild);
     // It may or may not be the direct parent of the beforeChild.
 {
     auto* flow = continuationBefore(beforeChild);
     // It may or may not be the direct parent of the beforeChild.
@@ -570,20 +571,20 @@ void RenderInline::addChildToContinuation(RenderPtr<RenderObject> newChild, Rend
         ASSERT_NOT_REACHED();
 
     if (newChild->isFloatingOrOutOfFlowPositioned())
         ASSERT_NOT_REACHED();
 
     if (newChild->isFloatingOrOutOfFlowPositioned())
-        return beforeChildAncestor->addChildIgnoringContinuation(WTFMove(newChild), beforeChild);
+        return beforeChildAncestor->addChildIgnoringContinuation(builder, WTFMove(newChild), beforeChild);
 
     if (flow == beforeChildAncestor)
 
     if (flow == beforeChildAncestor)
-        return flow->addChildIgnoringContinuation(WTFMove(newChild), beforeChild);
+        return flow->addChildIgnoringContinuation(builder, 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())
     // 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(WTFMove(newChild), beforeChild);
+        return beforeChildAncestor->addChildIgnoringContinuation(builder, WTFMove(newChild), beforeChild);
     if (flow->isInline() == childInline)
     if (flow->isInline() == childInline)
-        return flow->addChildIgnoringContinuation(WTFMove(newChild)); // Just treat like an append.
-    return beforeChildAncestor->addChildIgnoringContinuation(WTFMove(newChild), beforeChild);
+        return flow->addChildIgnoringContinuation(builder, WTFMove(newChild)); // Just treat like an append.
+    return beforeChildAncestor->addChildIgnoringContinuation(builder, WTFMove(newChild), beforeChild);
 }
 
 void RenderInline::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
 }
 
 void RenderInline::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
@@ -1368,7 +1369,7 @@ void RenderInline::childBecameNonInline(RenderElement& child)
     newBox->insertIntoContinuationChainAfter(*this);
     RenderObject* beforeChild = child.nextSibling();
     auto removedChild = takeChildInternal(child);
     newBox->insertIntoContinuationChainAfter(*this);
     RenderObject* beforeChild = child.nextSibling();
     auto removedChild = takeChildInternal(child);
-    splitFlow(beforeChild, WTFMove(newBox), WTFMove(removedChild), oldContinuation);
+    splitFlow(*RenderTreeBuilder::current(), beforeChild, WTFMove(newBox), WTFMove(removedChild), oldContinuation);
 }
 
 void RenderInline::updateHitTestResult(HitTestResult& result, const LayoutPoint& point)
 }
 
 void RenderInline::updateHitTestResult(HitTestResult& result, const LayoutPoint& point)
index 757556c..827f6e6 100644 (file)
@@ -37,7 +37,7 @@ public:
     RenderInline(Element&, RenderStyle&&);
     RenderInline(Document&, RenderStyle&&);
 
     RenderInline(Element&, RenderStyle&&);
     RenderInline(Document&, RenderStyle&&);
 
-    void addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild = 0) override;
+    void addChild(RenderTreeBuilder&, RenderPtr<RenderObject> newChild, RenderObject* beforeChild = 0) override;
 
     LayoutUnit marginLeft() const final;
     LayoutUnit marginRight() const final;
 
     LayoutUnit marginLeft() const final;
     LayoutUnit marginRight() const final;
@@ -116,11 +116,11 @@ private:
     template<typename GeneratorContext>
     void generateCulledLineBoxRects(GeneratorContext& yield, const RenderInline* container) const;
 
     template<typename GeneratorContext>
     void generateCulledLineBoxRects(GeneratorContext& yield, const RenderInline* container) const;
 
-    void addChildToContinuation(RenderPtr<RenderObject> newChild, RenderObject* beforeChild);
-    void addChildIgnoringContinuation(RenderPtr<RenderObject> newChild, RenderObject* beforeChild = nullptr) final;
+    void addChildToContinuation(RenderTreeBuilder&, RenderPtr<RenderObject> newChild, RenderObject* beforeChild);
+    void addChildIgnoringContinuation(RenderTreeBuilder&, RenderPtr<RenderObject> newChild, RenderObject* beforeChild = nullptr) final;
 
 
-    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 splitInlines(RenderTreeBuilder&, RenderBlock* fromBlock, RenderBlock* toBlock, RenderBlock* middleBlock, RenderObject* beforeChild, RenderBoxModelObject* oldCont);
+    void splitFlow(RenderTreeBuilder&, RenderObject* beforeChild, RenderPtr<RenderBlock> newBlockBox, RenderPtr<RenderObject> newChild, RenderBoxModelObject* oldCont);
 
     void layout() final { ASSERT_NOT_REACHED(); } // Do nothing for layout()
 
 
     void layout() final { ASSERT_NOT_REACHED(); } // Do nothing for layout()
 
index 24cd323..b60ef8b 100644 (file)
@@ -42,6 +42,7 @@
 #include "RenderScrollbar.h"
 #include "RenderText.h"
 #include "RenderTheme.h"
 #include "RenderScrollbar.h"
 #include "RenderText.h"
 #include "RenderTheme.h"
+#include "RenderTreeBuilder.h"
 #include "RenderView.h"
 #include "StyleResolver.h"
 #include "TextRun.h"
 #include "RenderView.h"
 #include "StyleResolver.h"
 #include "TextRun.h"
@@ -112,7 +113,7 @@ void RenderMenuList::createInnerBlock()
     auto newInnerBlock = createAnonymousBlock();
     m_innerBlock = makeWeakPtr(*newInnerBlock.get());
     adjustInnerStyle();
     auto newInnerBlock = createAnonymousBlock();
     m_innerBlock = makeWeakPtr(*newInnerBlock.get());
     adjustInnerStyle();
-    RenderFlexibleBox::addChild(WTFMove(newInnerBlock));
+    RenderFlexibleBox::addChild(*RenderTreeBuilder::current(), WTFMove(newInnerBlock));
 }
 
 void RenderMenuList::adjustInnerStyle()
 }
 
 void RenderMenuList::adjustInnerStyle()
@@ -174,11 +175,11 @@ HTMLSelectElement& RenderMenuList::selectElement() const
     return downcast<HTMLSelectElement>(nodeForNonAnonymous());
 }
 
     return downcast<HTMLSelectElement>(nodeForNonAnonymous());
 }
 
-void RenderMenuList::addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
+void RenderMenuList::addChild(RenderTreeBuilder& builder, RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
     createInnerBlock();
     auto& child = *newChild;
 {
     createInnerBlock();
     auto& child = *newChild;
-    m_innerBlock->addChild(WTFMove(newChild), beforeChild);
+    builder.insertChild(*m_innerBlock, WTFMove(newChild), beforeChild);
     ASSERT(m_innerBlock == firstChild());
 
     if (AXObjectCache* cache = document().existingAXObjectCache())
     ASSERT(m_innerBlock == firstChild());
 
     if (AXObjectCache* cache = document().existingAXObjectCache())
@@ -298,7 +299,7 @@ void RenderMenuList::setText(const String& s)
     else {
         auto newButtonText = createRenderer<RenderText>(document(), textToUse);
         m_buttonText = makeWeakPtr(*newButtonText);
     else {
         auto newButtonText = createRenderer<RenderText>(document(), textToUse);
         m_buttonText = makeWeakPtr(*newButtonText);
-        addChild(WTFMove(newButtonText));
+        RenderTreeBuilder::current()->insertChild(*this, WTFMove(newButtonText));
     }
 
     adjustInnerStyle();
     }
 
     adjustInnerStyle();
index 3b16cc5..acf60aa 100644 (file)
@@ -66,7 +66,7 @@ private:
 
     bool isMenuList() const override { return true; }
 
 
     bool isMenuList() const override { return true; }
 
-    void addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild = 0) override;
+    void addChild(RenderTreeBuilder&, RenderPtr<RenderObject> newChild, RenderObject* beforeChild = 0) override;
     RenderPtr<RenderObject> takeChild(RenderObject&) override;
     bool createsAnonymousWrapper() const override { return true; }
 
     RenderPtr<RenderObject> takeChild(RenderObject&) override;
     bool createsAnonymousWrapper() const override { return true; }
 
index a374224..c274812 100644 (file)
@@ -31,6 +31,7 @@
 #include "RenderIterator.h"
 #include "RenderMultiColumnSet.h"
 #include "RenderMultiColumnSpannerPlaceholder.h"
 #include "RenderIterator.h"
 #include "RenderMultiColumnSet.h"
 #include "RenderMultiColumnSpannerPlaceholder.h"
+#include "RenderTreeBuilder.h"
 #include "RenderView.h"
 #include "TransformState.h"
 #include <wtf/IsoMallocInlines.h>
 #include "RenderView.h"
 #include "TransformState.h"
 #include <wtf/IsoMallocInlines.h>
@@ -292,12 +293,12 @@ RenderObject* RenderMultiColumnFlow::processPossibleSpannerDescendant(RenderObje
         // end flowing one column set and move to the next one.
         auto newPlaceholder = RenderMultiColumnSpannerPlaceholder::createAnonymous(*this, downcast<RenderBox>(descendant), container->style());
         auto& placeholder = *newPlaceholder;
         // end flowing one column set and move to the next one.
         auto newPlaceholder = RenderMultiColumnSpannerPlaceholder::createAnonymous(*this, downcast<RenderBox>(descendant), container->style());
         auto& placeholder = *newPlaceholder;
-        container->addChild(WTFMove(newPlaceholder), descendant.nextSibling());
+        RenderTreeBuilder::current()->insertChild(*container, 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;
         auto takenDescendant = container->takeChild(descendant);
         
         // This is a guard to stop an ancestor flow thread from processing the spanner.
         gShiftingSpanner = true;
-        multicolContainer->RenderBlock::addChild(WTFMove(takenDescendant), insertBeforeMulticolChild);
+        multicolContainer->RenderBlock::addChild(*RenderTreeBuilder::current(), WTFMove(takenDescendant), insertBeforeMulticolChild);
         gShiftingSpanner = false;
         
         // The spanner has now been moved out from the flow thread, but we don't want to
         gShiftingSpanner = false;
         
         // The spanner has now been moved out from the flow thread, but we don't want to
@@ -334,7 +335,7 @@ RenderObject* RenderMultiColumnFlow::processPossibleSpannerDescendant(RenderObje
     auto newSet = createRenderer<RenderMultiColumnSet>(*this, RenderStyle::createAnonymousStyleWithDisplay(multicolContainer->style(), BLOCK));
     newSet->initializeStyle();
     auto& set = *newSet;
     auto newSet = createRenderer<RenderMultiColumnSet>(*this, RenderStyle::createAnonymousStyleWithDisplay(multicolContainer->style(), BLOCK));
     newSet->initializeStyle();
     auto& set = *newSet;
-    multicolContainer->RenderBlock::addChild(WTFMove(newSet), insertBeforeMulticolChild);
+    multicolContainer->RenderBlock::addChild(*RenderTreeBuilder::current(), WTFMove(newSet), insertBeforeMulticolChild);
     invalidateFragments();
 
     // We cannot handle immediate column set siblings at the moment (and there's no need for
     invalidateFragments();
 
     // We cannot handle immediate column set siblings at the moment (and there's no need for
index dd02ec3..797318e 100644 (file)
 
 #include "QuotesData.h"
 #include "RenderTextFragment.h"
 
 #include "QuotesData.h"
 #include "RenderTextFragment.h"
+#include "RenderTreeBuilder.h"
 #include "RenderView.h"
 #include <wtf/IsoMallocInlines.h>
 #include <wtf/unicode/CharacterNames.h>
 
 #include "RenderView.h"
 #include <wtf/IsoMallocInlines.h>
 #include <wtf/unicode/CharacterNames.h>
 
-
 namespace WebCore {
 using namespace WTF::Unicode;
 
 namespace WebCore {
 using namespace WTF::Unicode;
 
@@ -350,7 +350,7 @@ static RenderTextFragment* quoteTextRenderer(RenderObject* lastChild)
     return downcast<RenderTextFragment>(lastChild);
 }
 
     return downcast<RenderTextFragment>(lastChild);
 }
 
-void RenderQuote::updateTextRenderer()
+void RenderQuote::updateTextRenderer(RenderTreeBuilder& builder)
 {
     ASSERT_WITH_SECURITY_IMPLICATION(document().inRenderTreeUpdate());
     String text = computeText();
 {
     ASSERT_WITH_SECURITY_IMPLICATION(document().inRenderTreeUpdate());
     String text = computeText();
@@ -362,7 +362,7 @@ void RenderQuote::updateTextRenderer()
         renderText->dirtyLineBoxes(false);
         return;
     }
         renderText->dirtyLineBoxes(false);
         return;
     }
-    addChild(createRenderer<RenderTextFragment>(document(), m_text));
+    builder.insertChild(*this, createRenderer<RenderTextFragment>(document(), m_text));
 }
 
 String RenderQuote::computeText() const
 }
 
 String RenderQuote::computeText() const
@@ -403,7 +403,7 @@ bool RenderQuote::isOpen() const
     return false;
 }
 
     return false;
 }
 
-void RenderQuote::updateRenderer(RenderQuote* previousQuote)
+void RenderQuote::updateRenderer(RenderTreeBuilder& builder, RenderQuote* previousQuote)
 {
     ASSERT_WITH_SECURITY_IMPLICATION(document().inRenderTreeUpdate());
     int depth = -1;
 {
     ASSERT_WITH_SECURITY_IMPLICATION(document().inRenderTreeUpdate());
     int depth = -1;
@@ -423,7 +423,7 @@ void RenderQuote::updateRenderer(RenderQuote* previousQuote)
 
     m_depth = depth;
     m_needsTextUpdate = false;
 
     m_depth = depth;
     m_needsTextUpdate = false;
-    updateTextRenderer();
+    updateTextRenderer(builder);
 }
 
 } // namespace WebCore
 }
 
 } // namespace WebCore
index 50e956f..ad18782 100644 (file)
@@ -32,7 +32,7 @@ public:
     RenderQuote(Document&, RenderStyle&&, QuoteType);
     virtual ~RenderQuote();
 
     RenderQuote(Document&, RenderStyle&&, QuoteType);
     virtual ~RenderQuote();
 
-    void updateRenderer(RenderQuote* previousQuote);
+    void updateRenderer(RenderTreeBuilder&, RenderQuote* previousQuote);
 
 private:
     const char* renderName() const override { return "RenderQuote"; }
 
 private:
     const char* renderName() const override { return "RenderQuote"; }
@@ -43,7 +43,7 @@ private:
     void willBeRemovedFromTree() override;
 
     String computeText() const;
     void willBeRemovedFromTree() override;
 
     String computeText() const;
-    void updateTextRenderer();
+    void updateTextRenderer(RenderTreeBuilder&);
 
     const QuoteType m_type;
     int m_depth { -1 };
 
     const QuoteType m_type;
     int m_depth { -1 };
index 518c0bd..c5dff07 100644 (file)
@@ -35,6 +35,7 @@
 #include "RenderIterator.h"
 #include "RenderRubyRun.h"
 #include "RenderStyle.h"
 #include "RenderIterator.h"
 #include "RenderRubyRun.h"
 #include "RenderStyle.h"
+#include "RenderTreeBuilder.h"
 #include "StyleInheritedData.h"
 #include <wtf/IsoMallocInlines.h>
 #include <wtf/RefPtr.h>
 #include "StyleInheritedData.h"
 #include <wtf/IsoMallocInlines.h>
 #include <wtf/RefPtr.h>
@@ -139,45 +140,45 @@ void RenderRubyAsInline::styleDidChange(StyleDifference diff, const RenderStyle*
     propagateStyleToAnonymousChildren(PropagateToAllChildren);
 }
 
     propagateStyleToAnonymousChildren(PropagateToAllChildren);
 }
 
-void RenderRubyAsInline::addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild)
+void RenderRubyAsInline::addChild(RenderTreeBuilder& builder, 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
 {
     // Insert :before and :after content before/after the RenderRubyRun(s)
     if (child->isBeforeContent()) {
         if (child->isInline()) {
             // Add generated inline content normally
-            RenderInline::addChild(WTFMove(child), firstChild());
+            RenderInline::addChild(builder, WTFMove(child), firstChild());
         } else {
             // Wrap non-inline content with an anonymous inline-block.
             RenderBlock* beforeBlock = rubyBeforeBlock(this);
             if (!beforeBlock) {
                 auto newBlock = createAnonymousRubyInlineBlock(*this);
                 beforeBlock = newBlock.get();
         } else {
             // Wrap non-inline content with an anonymous inline-block.
             RenderBlock* beforeBlock = rubyBeforeBlock(this);
             if (!beforeBlock) {
                 auto newBlock = createAnonymousRubyInlineBlock(*this);
                 beforeBlock = newBlock.get();
-                RenderInline::addChild(WTFMove(newBlock), firstChild());
+                RenderInline::addChild(builder, WTFMove(newBlock), firstChild());
             }
             }
-            beforeBlock->addChild(WTFMove(child));
+            builder.insertChild(*beforeBlock, WTFMove(child));
         }
         return;
     }
     if (child->isAfterContent()) {
         if (child->isInline()) {
             // Add generated inline content normally
         }
         return;
     }
     if (child->isAfterContent()) {
         if (child->isInline()) {
             // Add generated inline content normally
-            RenderInline::addChild(WTFMove(child));
+            RenderInline::addChild(builder, WTFMove(child));
         } else {
             // Wrap non-inline content with an anonymous inline-block.
             RenderBlock* afterBlock = rubyAfterBlock(this);
             if (!afterBlock) {
                 auto newBlock = createAnonymousRubyInlineBlock(*this);
                 afterBlock = newBlock.get();
         } else {
             // Wrap non-inline content with an anonymous inline-block.
             RenderBlock* afterBlock = rubyAfterBlock(this);
             if (!afterBlock) {
                 auto newBlock = createAnonymousRubyInlineBlock(*this);
                 afterBlock = newBlock.get();
-                RenderInline::addChild(WTFMove(newBlock));
+                RenderInline::addChild(builder, WTFMove(newBlock));
             }
             }
-            afterBlock->addChild(WTFMove(child));
+            builder.insertChild(*afterBlock, WTFMove(child));
         }
         return;
     }
 
     // If the child is a ruby run, just add it normally.
     if (child->isRubyRun()) {
         }
         return;
     }
 
     // If the child is a ruby run, just add it normally.
     if (child->isRubyRun()) {
-        RenderInline::addChild(WTFMove(child), beforeChild);
+        RenderInline::addChild(builder, WTFMove(child), beforeChild);
         return;
     }
 
         return;
     }
 
@@ -188,7 +189,7 @@ void RenderRubyAsInline::addChild(RenderPtr<RenderObject> child, RenderObject* b
         while (run && !run->isRubyRun())
             run = run->parent();
         if (run) {
         while (run && !run->isRubyRun())
             run = run->parent();
         if (run) {
-            run->addChild(WTFMove(child), beforeChild);
+            builder.insertChild(*run, WTFMove(child), beforeChild);
             return;
         }
         ASSERT_NOT_REACHED(); // beforeChild should always have a run as parent!
             return;
         }
         ASSERT_NOT_REACHED(); // beforeChild should always have a run as parent!
@@ -202,9 +203,9 @@ void RenderRubyAsInline::addChild(RenderPtr<RenderObject> child, RenderObject* b
     if (!lastRun || lastRun->hasRubyText()) {
         auto newRun = RenderRubyRun::staticCreateRubyRun(this);
         lastRun = newRun.get();
     if (!lastRun || lastRun->hasRubyText()) {
         auto newRun = RenderRubyRun::staticCreateRubyRun(this);
         lastRun = newRun.get();
-        RenderInline::addChild(WTFMove(newRun), beforeChild);
+        RenderInline::addChild(builder, WTFMove(newRun), beforeChild);
     }
     }
-    lastRun->addChild(WTFMove(child));
+    builder.insertChild(*lastRun, WTFMove(child));
 }
 
 RenderPtr<RenderObject> RenderRubyAsInline::takeChild(RenderObject& child)
 }
 
 RenderPtr<RenderObject> RenderRubyAsInline::takeChild(RenderObject& child)
@@ -246,45 +247,45 @@ void RenderRubyAsBlock::styleDidChange(StyleDifference diff, const RenderStyle*
     propagateStyleToAnonymousChildren(PropagateToAllChildren);
 }
 
     propagateStyleToAnonymousChildren(PropagateToAllChildren);
 }
 
-void RenderRubyAsBlock::addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild)
+void RenderRubyAsBlock::addChild(RenderTreeBuilder& builder, 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
 {
     // Insert :before and :after content before/after the RenderRubyRun(s)
     if (child->isBeforeContent()) {
         if (child->isInline()) {
             // Add generated inline content normally
-            RenderBlockFlow::addChild(WTFMove(child), firstChild());
+            RenderBlockFlow::addChild(builder, WTFMove(child), firstChild());
         } else {
             // Wrap non-inline content with an anonymous inline-block.
             RenderBlock* beforeBlock = rubyBeforeBlock(this);
             if (!beforeBlock) {
                 auto newBlock = createAnonymousRubyInlineBlock(*this);
                 beforeBlock = newBlock.get();
         } else {
             // Wrap non-inline content with an anonymous inline-block.
             RenderBlock* beforeBlock = rubyBeforeBlock(this);
             if (!beforeBlock) {
                 auto newBlock = createAnonymousRubyInlineBlock(*this);
                 beforeBlock = newBlock.get();
-                RenderBlockFlow::addChild(WTFMove(newBlock), firstChild());
+                RenderBlockFlow::addChild(builder, WTFMove(newBlock), firstChild());
             }
             }
-            beforeBlock->addChild(WTFMove(child));
+            builder.insertChild(*beforeBlock, WTFMove(child));
         }
         return;
     }
     if (child->isAfterContent()) {
         if (child->isInline()) {
             // Add generated inline content normally
         }
         return;
     }
     if (child->isAfterContent()) {
         if (child->isInline()) {
             // Add generated inline content normally
-            RenderBlockFlow::addChild(WTFMove(child));
+            RenderBlockFlow::addChild(builder, WTFMove(child));
         } else {
             // Wrap non-inline content with an anonymous inline-block.
             RenderBlock* afterBlock = rubyAfterBlock(this);
             if (!afterBlock) {
                 auto newBlock = createAnonymousRubyInlineBlock(*this);
                 afterBlock = newBlock.get();
         } else {
             // Wrap non-inline content with an anonymous inline-block.
             RenderBlock* afterBlock = rubyAfterBlock(this);
             if (!afterBlock) {
                 auto newBlock = createAnonymousRubyInlineBlock(*this);
                 afterBlock = newBlock.get();
-                RenderBlockFlow::addChild(WTFMove(newBlock));
+                RenderBlockFlow::addChild(builder, WTFMove(newBlock));
             }
             }
-            afterBlock->addChild(WTFMove(child));
+            builder.insertChild(*afterBlock, WTFMove(child));
         }
         return;
     }
 
     // If the child is a ruby run, just add it normally.
     if (child->isRubyRun()) {
         }
         return;
     }
 
     // If the child is a ruby run, just add it normally.
     if (child->isRubyRun()) {
-        RenderBlockFlow::addChild(WTFMove(child), beforeChild);
+        RenderBlockFlow::addChild(builder, WTFMove(child), beforeChild);
         return;
     }
 
         return;
     }
 
@@ -295,7 +296,7 @@ void RenderRubyAsBlock::addChild(RenderPtr<RenderObject> child, RenderObject* be
         while (run && !run->isRubyRun())
             run = run->parent();
         if (run) {
         while (run && !run->isRubyRun())
             run = run->parent();
         if (run) {
-            run->addChild(WTFMove(child), beforeChild);
+            builder.insertChild(*run, WTFMove(child), beforeChild);
             return;
         }
         ASSERT_NOT_REACHED(); // beforeChild should always have a run as parent!
             return;
         }
         ASSERT_NOT_REACHED(); // beforeChild should always have a run as parent!
@@ -309,9 +310,9 @@ void RenderRubyAsBlock::addChild(RenderPtr<RenderObject> child, RenderObject* be
     if (!lastRun || lastRun->hasRubyText()) {
         auto newRun = RenderRubyRun::staticCreateRubyRun(this);
         lastRun = newRun.get();
     if (!lastRun || lastRun->hasRubyText()) {
         auto newRun = RenderRubyRun::staticCreateRubyRun(this);
         lastRun = newRun.get();
-        RenderBlockFlow::addChild(WTFMove(newRun), beforeChild);
+        RenderBlockFlow::addChild(builder, WTFMove(newRun), beforeChild);
     }
     }
-    lastRun->addChild(WTFMove(child));
+    builder.insertChild(*lastRun, WTFMove(child));
 }
 
 RenderPtr<RenderObject> RenderRubyAsBlock::takeChild(RenderObject& child)
 }
 
 RenderPtr<RenderObject> RenderRubyAsBlock::takeChild(RenderObject& child)
index a53b59c..19c195e 100644 (file)
@@ -56,7 +56,7 @@ public:
     RenderRubyAsInline(Element&, RenderStyle&&);
     virtual ~RenderRubyAsInline();
 
     RenderRubyAsInline(Element&, RenderStyle&&);
     virtual ~RenderRubyAsInline();
 
-    void addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild = 0) override;
+    void addChild(RenderTreeBuilder&, RenderPtr<RenderObject> child, RenderObject* beforeChild = 0) override;
     RenderPtr<RenderObject> takeChild(RenderObject& child) override;
 
 protected:
     RenderPtr<RenderObject> takeChild(RenderObject& child) override;
 
 protected:
@@ -77,7 +77,7 @@ public:
 
     Element& element() const { return downcast<Element>(nodeForNonAnonymous()); }
 
 
     Element& element() const { return downcast<Element>(nodeForNonAnonymous()); }
 
-    void addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild = 0) override;
+    void addChild(RenderTreeBuilder&, RenderPtr<RenderObject> child, RenderObject* beforeChild = 0) override;
     RenderPtr<RenderObject> takeChild(RenderObject& child) override;
 
 protected:
     RenderPtr<RenderObject> takeChild(RenderObject& child) override;
 
 protected:
index 92212bb..8e402bb 100644 (file)
@@ -59,6 +59,8 @@ public:
     
     void cachePriorCharactersIfNeeded(const LazyLineBreakIterator&) override;
 
     
     void cachePriorCharactersIfNeeded(const LazyLineBreakIterator&) override;
 
+    void moveChildren(RenderRubyBase* toBase, RenderObject* beforeChild = 0);
+
 private:
     bool isRubyBase() const override { return true; }
     bool isChildAllowed(const RenderObject&, const RenderStyle&) const override;
 private:
     bool isRubyBase() const override { return true; }
     bool isChildAllowed(const RenderObject&, const RenderStyle&) const override;
@@ -66,7 +68,6 @@ private:
     void adjustInlineDirectionLineBounds(int expansionOpportunityCount, float& logicalLeft, float& logicalWidth) const override;
     void mergeChildrenWithBase(RenderRubyBase& toBlock);
 
     void adjustInlineDirectionLineBounds(int expansionOpportunityCount, float& logicalLeft, float& logicalWidth) const override;
     void mergeChildrenWithBase(RenderRubyBase& toBlock);
 
-    void moveChildren(RenderRubyBase* toBase, RenderObject* beforeChild = 0);
     void moveInlineChildren(RenderRubyBase* toBase, RenderObject* beforeChild = 0);
     void moveBlockChildren(RenderRubyBase* toBase, RenderObject* beforeChild = 0);
 
     void moveInlineChildren(RenderRubyBase* toBase, RenderObject* beforeChild = 0);
     void moveBlockChildren(RenderRubyBase* toBase, RenderObject* beforeChild = 0);
 
index 7d5cd35..f1b0024 100644 (file)
@@ -93,7 +93,7 @@ RenderRubyBase* RenderRubyRun::rubyBaseSafe()
     if (!base) {
         auto newBase = createRubyBase();
         base = newBase.get();
     if (!base) {
         auto newBase = createRubyBase();
         base = newBase.get();
-        RenderBlockFlow::addChild(WTFMove(newBase));
+        RenderBlockFlow::addChild(*RenderTreeBuilder::current(), WTFMove(newBase));
     }
     return base;
 }
     }
     return base;
 }
@@ -108,51 +108,6 @@ bool RenderRubyRun::isChildAllowed(const RenderObject& child, const RenderStyle&
     return child.isInline() || child.isRubyText();
 }
 
     return child.isInline() || child.isRubyText();
 }
 
-void RenderRubyRun::addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild)
-{
-    ASSERT(child);
-
-    if (child->isRubyText()) {
-        if (!beforeChild) {
-            // RenderRuby has already ascertained that we can add the child here.
-            ASSERT(!hasRubyText());
-            // prepend ruby texts as first child
-            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
-            // the old text goes into a new run that is inserted as next sibling.
-            ASSERT(beforeChild->parent() == this);
-            RenderElement* ruby = parent();
-            ASSERT(isRuby(ruby));
-            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(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();
-            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(WTFMove(child), beforeChild);
-    }
-}
-
 RenderPtr<RenderObject> RenderRubyRun::takeChild(RenderObject& child)
 {
     // If the child is a ruby text, then merge the ruby base with the base of
 RenderPtr<RenderObject> RenderRubyRun::takeChild(RenderObject& child)
 {
     // If the child is a ruby text, then merge the ruby base with the base of
index febf3c3..e26f14b 100644 (file)
@@ -57,7 +57,6 @@ public:
     void layoutBlock(bool relayoutChildren, LayoutUnit pageHeight = 0) override;
 
     bool isChildAllowed(const RenderObject&, const RenderStyle&) const override;
     void layoutBlock(bool relayoutChildren, LayoutUnit pageHeight = 0) override;
 
     bool isChildAllowed(const RenderObject&, const RenderStyle&) const override;
-    void addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild = 0) override;
     RenderPtr<RenderObject> takeChild(RenderObject&) override;
 
     RenderBlock* firstLineBlock() const override;
     RenderPtr<RenderObject> takeChild(RenderObject&) override;
 
     RenderBlock* firstLineBlock() const override;
index 5bda411..c21b9af 100644 (file)
@@ -45,6 +45,7 @@
 #include "RenderTableCell.h"
 #include "RenderTableCol.h"
 #include "RenderTableSection.h"
 #include "RenderTableCell.h"
 #include "RenderTableCol.h"
 #include "RenderTableSection.h"
+#include "RenderTreeBuilder.h"
 #include "RenderView.h"
 #include "StyleInheritedData.h"
 #include <wtf/IsoMallocInlines.h>
 #include "RenderView.h"
 #include "StyleInheritedData.h"
 #include <wtf/IsoMallocInlines.h>
@@ -132,7 +133,7 @@ static inline void resetSectionPointerIfNotBefore(WeakPtr<RenderTableSection>& s
         section.clear();
 }
 
         section.clear();
 }
 
-void RenderTable::addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild)
+void RenderTable::addChild(RenderTreeBuilder& builder, RenderPtr<RenderObject> child, RenderObject* beforeChild)
 {
     bool wrapInAnonymousSection = !child->isOutOfFlowPositioned();
 
 {
     bool wrapInAnonymousSection = !child->isOutOfFlowPositioned();
 
@@ -183,19 +184,19 @@ void RenderTable::addChild(RenderPtr<RenderObject> child, RenderObject* beforeCh
         if (beforeChild && beforeChild->parent() != this)
             beforeChild = splitAnonymousBoxesAroundChild(beforeChild);
 
         if (beforeChild && beforeChild->parent() != this)
             beforeChild = splitAnonymousBoxesAroundChild(beforeChild);
 
-        RenderBox::addChild(WTFMove(child), beforeChild);
+        RenderBox::addChild(builder, WTFMove(child), beforeChild);
         return;
     }
 
     if (!beforeChild && is<RenderTableSection>(lastChild()) && lastChild()->isAnonymous() && !lastChild()->isBeforeContent()) {
         return;
     }
 
     if (!beforeChild && is<RenderTableSection>(lastChild()) && lastChild()->isAnonymous() && !lastChild()->isBeforeContent()) {
-        downcast<RenderTableSection>(*lastChild()).addChild(WTFMove(child));
+        builder.insertChild(downcast<RenderTableSection>(*lastChild()), WTFMove(child));
         return;
     }
 
     if (beforeChild && !beforeChild->isAnonymous() && beforeChild->parent() == this) {
         RenderObject* section = beforeChild->previousSibling();
         if (is<RenderTableSection>(section) && section->isAnonymous()) {
         return;
     }
 
     if (beforeChild && !beforeChild->isAnonymous() && beforeChild->parent() == this) {
         RenderObject* section = beforeChild->previousSibling();
         if (is<RenderTableSection>(section) && section->isAnonymous()) {
-            downcast<RenderTableSection>(*section).addChild(WTFMove(child));
+            builder.insertChild(downcast<RenderTableSection>(*section), WTFMove(child));
             return;
         }
     }
             return;
         }
     }
@@ -207,7 +208,7 @@ void RenderTable::addChild(RenderPtr<RenderObject> child, RenderObject* beforeCh
         RenderTableSection& section = downcast<RenderTableSection>(*lastBox);
         if (beforeChild == &section)
             beforeChild = section.firstRow();
         RenderTableSection& section = downcast<RenderTableSection>(*lastBox);
         if (beforeChild == &section)
             beforeChild = section.firstRow();
-        section.addChild(WTFMove(child), beforeChild);
+        builder.insertChild(section, WTFMove(child), beforeChild);
         return;
     }
 
         return;
     }
 
@@ -216,8 +217,8 @@ void RenderTable::addChild(RenderPtr<RenderObject> child, RenderObject* beforeCh
 
     auto newSection = RenderTableSection::createAnonymousWithParentRenderer(*this);
     auto& section = *newSection;
 
     auto newSection = RenderTableSection::createAnonymousWithParentRenderer(*this);
     auto& section = *newSection;
-    addChild(WTFMove(newSection), beforeChild);
-    section.addChild(WTFMove(child));
+    builder.insertChild(*this, WTFMove(newSection), beforeChild);
+    builder.insertChild(section, WTFMove(child));
 }
 
 void RenderTable::addCaption(RenderTableCaption& caption)
 }
 
 void RenderTable::addCaption(RenderTableCaption& caption)
index 01ccc5d..40c6c8a 100644 (file)
@@ -127,7 +127,7 @@ public:
     LayoutUnit calcBorderEnd() const;
     void recalcBordersInRowDirection();
 
     LayoutUnit calcBorderEnd() const;
     void recalcBordersInRowDirection();
 
-    void addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild = 0) final;
+    void addChild(RenderTreeBuilder&, RenderPtr<RenderObject> child, RenderObject* beforeChild = 0) final;
 
     struct ColumnStruct {
         explicit ColumnStruct(unsigned initialSpan = 1)
 
     struct ColumnStruct {
         explicit ColumnStruct(unsigned initialSpan = 1)
index ef22379..05a493e 100644 (file)
@@ -31,6 +31,7 @@
 #include "LayoutState.h"
 #include "PaintInfo.h"
 #include "RenderTableCell.h"
 #include "LayoutState.h"
 #include "PaintInfo.h"
 #include "RenderTableCell.h"
+#include "RenderTreeBuilder.h"
 #include "RenderView.h"
 #include "StyleInheritedData.h"
 #include <wtf/IsoMallocInlines.h>
 #include "RenderView.h"
 #include "StyleInheritedData.h"
 #include <wtf/IsoMallocInlines.h>
@@ -110,7 +111,7 @@ const BorderValue& RenderTableRow::borderAdjoiningEndCell(const RenderTableCell&
     return style().borderEnd();
 }
 
     return style().borderEnd();
 }
 
-void RenderTableRow::addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild)
+void RenderTableRow::addChild(RenderTreeBuilder& builder, RenderPtr<RenderObject> child, RenderObject* beforeChild)
 {
     if (!is<RenderTableCell>(*child)) {
         RenderObject* last = beforeChild;
 {
     if (!is<RenderTableCell>(*child)) {
         RenderObject* last = beforeChild;
@@ -120,14 +121,14 @@ void RenderTableRow::addChild(RenderPtr<RenderObject> child, RenderObject* befor
             RenderTableCell& cell = downcast<RenderTableCell>(*last);
             if (beforeChild == &cell)
                 beforeChild = cell.firstChild();
             RenderTableCell& cell = downcast<RenderTableCell>(*last);
             if (beforeChild == &cell)
                 beforeChild = cell.firstChild();
-            cell.addChild(WTFMove(child), beforeChild);
+            builder.insertChild(cell, WTFMove(child), beforeChild);
             return;
         }
 
         if (beforeChild && !beforeChild->isAnonymous() && beforeChild->parent() == this) {
             RenderObject* cell = beforeChild->previousSibling();
             if (is<RenderTableCell>(cell) && cell->isAnonymous()) {
             return;
         }
 
         if (beforeChild && !beforeChild->isAnonymous() && beforeChild->parent() == this) {
             RenderObject* cell = beforeChild->previousSibling();
             if (is<RenderTableCell>(cell) && cell->isAnonymous()) {
-                downcast<RenderTableCell>(*cell).addChild(WTFMove(child));
+                builder.insertChild(downcast<RenderTableCell>(*cell), WTFMove(child));
                 return;
             }
         }
                 return;
             }
         }
@@ -136,7 +137,7 @@ void RenderTableRow::addChild(RenderPtr<RenderObject> child, RenderObject* befor
         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)) {
         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(WTFMove(child), beforeChild);
+                builder.insertChild(*last->parent(), WTFMove(child), beforeChild);
                 return;
             }
             // If beforeChild is inside an anonymous row, insert into the row.
                 return;
             }
             // If beforeChild is inside an anonymous row, insert into the row.
@@ -144,15 +145,15 @@ void RenderTableRow::addChild(RenderPtr<RenderObject> child, RenderObject* befor
             if (is<RenderTableRow>(parent)) {
                 auto newCell = RenderTableCell::createAnonymousWithParentRenderer(*this);
                 auto& cell = *newCell;
             if (is<RenderTableRow>(parent)) {
                 auto newCell = RenderTableCell::createAnonymousWithParentRenderer(*this);
                 auto& cell = *newCell;
-                parent.addChild(WTFMove(newCell), beforeChild);
-                cell.addChild(WTFMove(child));
+                builder.insertChild(parent, WTFMove(newCell), beforeChild);
+                builder.insertChild(cell, WTFMove(child));
                 return;
             }
         }
         auto newCell = RenderTableCell::createAnonymousWithParentRenderer(*this);
         auto& cell = *newCell;
                 return;
             }
         }
         auto newCell = RenderTableCell::createAnonymousWithParentRenderer(*this);
         auto& cell = *newCell;
-        addChild(WTFMove(newCell), beforeChild);
-        cell.addChild(WTFMove(child));
+        builder.insertChild(*this, WTFMove(newCell), beforeChild);
+        builder.insertChild(cell, WTFMove(child));
         return;
     } 
 
         return;
     } 
 
@@ -166,7 +167,7 @@ void RenderTableRow::addChild(RenderPtr<RenderObject> child, RenderObject* befor
         section->addCell(&cell, this);
 
     ASSERT(!beforeChild || is<RenderTableCell>(*beforeChild));
         section->addCell(&cell, this);
 
     ASSERT(!beforeChild || is<RenderTableCell>(*beforeChild));
-    RenderBox::addChild(WTFMove(child), beforeChild);
+    RenderBox::addChild(builder, WTFMove(child), beforeChild);
 
     if (beforeChild || nextRow())
         section()->setNeedsCellRecalc();
 
     if (beforeChild || nextRow())
         section()->setNeedsCellRecalc();
index 9e54771..8dbff55 100644 (file)
@@ -59,7 +59,7 @@ public:
     const BorderValue& borderAdjoiningStartCell(const RenderTableCell&) const;
     const BorderValue& borderAdjoiningEndCell(const RenderTableCell&) const;
 
     const BorderValue& borderAdjoiningStartCell(const RenderTableCell&) const;
     const BorderValue& borderAdjoiningEndCell(const RenderTableCell&) const;
 
-    void addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild = 0) override;
+    void addChild(RenderTreeBuilder&, RenderPtr<RenderObject> child, RenderObject* beforeChild = 0) override;
 
     bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) override;
 
 
     bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) override;
 
index 810b032..3a465f8 100644 (file)
@@ -35,6 +35,7 @@
 #include "RenderTableCol.h"
 #include "RenderTableRow.h"
 #include "RenderTextControl.h"
 #include "RenderTableCol.h"
 #include "RenderTableRow.h"
 #include "RenderTextControl.h"
+#include "RenderTreeBuilder.h"
 #include "RenderView.h"
 #include "StyleInheritedData.h"
 #include <limits>
 #include "RenderView.h"
 #include "StyleInheritedData.h"
 #include <limits>
@@ -120,7 +121,7 @@ void RenderTableSection::willBeRemovedFromTree()
     setNeedsCellRecalc();
 }
 
     setNeedsCellRecalc();
 }
 
-void RenderTableSection::addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild)
+void RenderTableSection::addChild(RenderTreeBuilder& builder, RenderPtr<RenderObject> child, RenderObject* beforeChild)
 {
     if (!is<RenderTableRow>(*child)) {
         RenderObject* last = beforeChild;
 {
     if (!is<RenderTableRow>(*child)) {
         RenderObject* last = beforeChild;
@@ -130,14 +131,14 @@ void RenderTableSection::addChild(RenderPtr<RenderObject> child, RenderObject* b
             RenderTableRow& row = downcast<RenderTableRow>(*last);
             if (beforeChild == &row)
                 beforeChild = row.firstCell();
             RenderTableRow& row = downcast<RenderTableRow>(*last);
             if (beforeChild == &row)
                 beforeChild = row.firstCell();
-            row.addChild(WTFMove(child), beforeChild);
+            builder.insertChild(row, WTFMove(child), beforeChild);
             return;
         }
 
         if (beforeChild && !beforeChild->isAnonymous() && beforeChild->parent() == this) {
             RenderObject* row = beforeChild->previousSibling();
             if (is<RenderTableRow>(row) && row->isAnonymous()) {
             return;
         }
 
         if (beforeChild && !beforeChild->isAnonymous() && beforeChild->parent() == this) {
             RenderObject* row = beforeChild->previousSibling();
             if (is<RenderTableRow>(row) && row->isAnonymous()) {
-                downcast<RenderTableRow>(*row).addChild(WTFMove(child));
+                builder.insertChild(downcast<RenderTableRow>(*row), WTFMove(child));
                 return;
             }
         }
                 return;
             }
         }
@@ -148,14 +149,14 @@ void RenderTableSection::addChild(RenderPtr<RenderObject> child, RenderObject* b
         while (lastBox && lastBox->parent()->isAnonymous() && !is<RenderTableRow>(*lastBox))
             lastBox = lastBox->parent();
         if (is<RenderTableRow>(lastBox) && lastBox->isAnonymous() && !lastBox->isBeforeOrAfterContent()) {
         while (lastBox && lastBox->parent()->isAnonymous() && !is<RenderTableRow>(*lastBox))
             lastBox = lastBox->parent();
         if (is<RenderTableRow>(lastBox) && lastBox->isAnonymous() && !lastBox->isBeforeOrAfterContent()) {
-            downcast<RenderTableRow>(*lastBox).addChild(WTFMove(child), beforeChild);
+            builder.insertChild(downcast<RenderTableRow>(*lastBox), WTFMove(child), beforeChild);
             return;
         }
 
         auto newRow = RenderTableRow::createAnonymousWithParentRenderer(*this);
         auto& row = *newRow;
             return;
         }
 
         auto newRow = RenderTableRow::createAnonymousWithParentRenderer(*this);
         auto& row = *newRow;
-        addChild(WTFMove(newRow), beforeChild);
-        row.addChild(WTFMove(child));
+        builder.insertChild(*this, WTFMove(newRow), beforeChild);
+        builder.insertChild(row, WTFMove(child));
         return;
     }
 
         return;
     }
 
@@ -179,7 +180,7 @@ void RenderTableSection::addChild(RenderPtr<RenderObject> child, RenderObject* b
         beforeChild = splitAnonymousBoxesAroundChild(beforeChild);
 
     ASSERT(!beforeChild || is<RenderTableRow>(*beforeChild));
         beforeChild = splitAnonymousBoxesAroundChild(beforeChild);
 
     ASSERT(!beforeChild || is<RenderTableRow>(*beforeChild));
-    RenderBox::addChild(WTFMove(child), beforeChild);
+    RenderBox::addChild(builder, WTFMove(child), beforeChild);
 }
 
 void RenderTableSection::ensureRows(unsigned numRows)
 }
 
 void RenderTableSection::ensureRows(unsigned numRows)
index 1ce473e..037d804 100644 (file)
@@ -62,7 +62,7 @@ public:
     RenderTableRow* firstRow() const;
     RenderTableRow* lastRow() const;
 
     RenderTableRow* firstRow() const;
     RenderTableRow* lastRow() const;
 
-    void addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild = 0) override;
+    void addChild(RenderTreeBuilder&, RenderPtr<RenderObject> child, RenderObject* beforeChild = 0) override;
 
     std::optional<int> firstLineBaseline() const override;
 
 
     std::optional<int> firstLineBaseline() const override;
 
diff --git a/Source/WebCore/rendering/RenderTreeBuilder.cpp b/Source/WebCore/rendering/RenderTreeBuilder.cpp
new file mode 100644 (file)
index 0000000..25c6ced
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "RenderTreeBuilder.h"
+
+#include "RenderElement.h"
+#include "RenderRuby.h"
+#include "RenderRubyBase.h"
+#include "RenderRubyRun.h"
+#include "RenderText.h"
+#include "RenderTreeUpdater.h"
+
+namespace WebCore {
+
+RenderTreeBuilder* RenderTreeBuilder::m_current;
+
+RenderTreeBuilder::RenderTreeBuilder()
+{
+    RELEASE_ASSERT(!m_current);
+    m_current = this;
+}
+
+RenderTreeBuilder::~RenderTreeBuilder()
+{
+    m_current = nullptr;
+}
+
+void RenderTreeBuilder::insertChild(RenderElement& parent, RenderPtr<RenderObject> child, RenderObject* beforeChild)
+{
+    // We don't yet have any local access, ensure we are still called with non-null this ptr.
+    ASSERT(this);
+
+    if (is<RenderText>(beforeChild)) {
+        if (auto* wrapperInline = downcast<RenderText>(*beforeChild).inlineWrapperForDisplayContents())
+            beforeChild = wrapperInline;
+    }
+
+    if (is<RenderRubyRun>(parent)) {
+        rubyRunInsertChild(downcast<RenderRubyRun>(parent), WTFMove(child), beforeChild);
+        return;
+    }
+
+    parent.addChild(*this, WTFMove(child), beforeChild);
+}
+
+void RenderTreeBuilder::insertChild(RenderTreePosition& position, RenderPtr<RenderObject> child)
+{
+    insertChild(position.parent(), WTFMove(child), position.nextSibling());
+}
+
+void RenderTreeBuilder::rubyRunInsertChild(RenderRubyRun& parent, RenderPtr<RenderObject> child, RenderObject* beforeChild)
+{
+    if (child->isRubyText()) {
+        if (!beforeChild) {
+            // RenderRuby has already ascertained that we can add the child here.
+            ASSERT(!parent.hasRubyText());
+            // prepend ruby texts as first child
+            parent.addChild(*this, WTFMove(child), parent.firstChild());
+            return;
+        }
+        if (beforeChild->isRubyText()) {
+            // New text is inserted just before another.
+            // In this case the new text takes the place of the old one, and
+            // the old text goes into a new run that is inserted as next sibling.
+            ASSERT(beforeChild->parent() == &parent);
+            RenderElement* ruby = parent.parent();
+            ASSERT(isRuby(ruby));
+            auto newRun = RenderRubyRun::staticCreateRubyRun(ruby);
+            insertChild(*ruby, WTFMove(newRun), parent.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.
+            parent.addChild(*this, WTFMove(child), beforeChild);
+            auto takenBeforeChild = parent.RenderBlockFlow::takeChild(*beforeChild);
+            insertChild(*newRun, WTFMove(takenBeforeChild));
+            return;
+        }
+        if (parent.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.parent();
+            auto newRun = RenderRubyRun::staticCreateRubyRun(ruby);
+            auto& run = *newRun;
+            insertChild(*ruby, WTFMove(newRun), &parent);
+            insertChild(run, WTFMove(child));
+            parent.rubyBaseSafe()->moveChildren(run.rubyBaseSafe(), beforeChild);
+        }
+        return;
+    }
+    // child is not a text -> insert it into the base
+    // (append it instead if beforeChild is the ruby text)
+    if (beforeChild && beforeChild->isRubyText())
+        beforeChild = nullptr;
+    insertChild(*parent.rubyBaseSafe(), WTFMove(child), beforeChild);
+}
+
+}
diff --git a/Source/WebCore/rendering/RenderTreeBuilder.h b/Source/WebCore/rendering/RenderTreeBuilder.h
new file mode 100644 (file)
index 0000000..2da4f74
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "RenderTreePosition.h"
+
+namespace WebCore {
+
+class RenderRubyRun;
+class RenderTreeUpdater;
+
+class RenderTreeBuilder {
+public:
+    RenderTreeBuilder();
+    ~RenderTreeBuilder();
+
+    void insertChild(RenderElement& parent, RenderPtr<RenderObject>, RenderObject* beforeChild = nullptr);
+    void insertChild(RenderTreePosition&, RenderPtr<RenderObject>);
+
+    // This avoids having to convert all sites that need RenderTreeBuilder in one go.
+    // FIXME: Remove.
+    static RenderTreeBuilder* current() { return m_current; }
+
+private:
+    void rubyRunInsertChild(RenderRubyRun&, RenderPtr<RenderObject> child, RenderObject* beforeChild);
+
+    static RenderTreeBuilder* m_current;
+};
+
+}
index db44f41..f6802d4 100644 (file)
@@ -36,6 +36,7 @@
 #include "RenderListMarker.h"
 #include "RenderText.h"
 #include "RenderTextFragment.h"
 #include "RenderListMarker.h"
 #include "RenderText.h"
 #include "RenderTextFragment.h"
+#include "RenderTreeBuilder.h"
 #include "RenderTreeUpdaterFirstLetter.h"
 #include "RenderTreeUpdaterListItem.h"
 #include "StyleResolver.h"
 #include "RenderTreeUpdaterFirstLetter.h"
 #include "RenderTreeUpdaterListItem.h"
 #include "StyleResolver.h"
@@ -98,6 +99,9 @@ auto TextAutoSizingValue::adjustTextNodeSizes() -> StillHasNodes
 
     float averageSize = std::round(cumulativeSize / m_autoSizedNodes.size());
 
 
     float averageSize = std::round(cumulativeSize / m_autoSizedNodes.size());
 
+    // FIXME: Figure out how to make this code use RenderTreeUpdater/Builder properly.
+    RenderTreeBuilder builder;
+
     // Adjust sizes.
     bool firstPass = true;
     for (auto& node : m_autoSizedNodes) {
     // Adjust sizes.
     bool firstPass = true;
     for (auto& node : m_autoSizedNodes) {
@@ -159,7 +163,7 @@ auto TextAutoSizingValue::adjustTextNodeSizes() -> StillHasNodes
         parentRenderer->setStyle(WTFMove(newParentStyle));
 
         if (is<RenderListItem>(*parentRenderer))
         parentRenderer->setStyle(WTFMove(newParentStyle));
 
         if (is<RenderListItem>(*parentRenderer))
-            RenderTreeUpdater::ListItem::updateMarker(downcast<RenderListItem>(*parentRenderer));
+            RenderTreeUpdater::ListItem::updateMarker(builder, downcast<RenderListItem>(*parentRenderer));
     }
 
     for (auto& node : m_autoSizedNodes) {
     }
 
     for (auto& node : m_autoSizedNodes) {
index 28fafdb..47c0ade 100644 (file)
@@ -76,9 +76,7 @@ void RenderMathMLFenced::updateFromElement()
         m_separators = StringImpl::create(",");
     }
 
         m_separators = StringImpl::create(",");
     }
 
-    if (!firstChild())
-        makeFences();
-    else {
+    if (firstChild()) {
         // FIXME: The mfenced element fails to update dynamically when its open, close and separators attributes are changed (https://bugs.webkit.org/show_bug.cgi?id=57696).
         if (is<RenderMathMLFencedOperator>(*firstChild()))
             downcast<RenderMathMLFencedOperator>(*firstChild()).updateOperatorContent(m_open);
         // FIXME: The mfenced element fails to update dynamically when its open, close and separators attributes are changed (https://bugs.webkit.org/show_bug.cgi?id=57696).
         if (is<RenderMathMLFencedOperator>(*firstChild()))
             downcast<RenderMathMLFencedOperator>(*firstChild()).updateOperatorContent(m_open);
@@ -93,21 +91,23 @@ RenderPtr<RenderMathMLFencedOperator> RenderMathMLFenced::createMathMLOperator(c
     return newOperator;
 }
 
     return newOperator;
 }
 
-void RenderMathMLFenced::makeFences()
+void RenderMathMLFenced::makeFences(RenderTreeBuilder& builder)
 {
     auto openFence = createMathMLOperator(m_open, MathMLOperatorDictionary::Prefix, MathMLOperatorDictionary::Fence);
 {
     auto openFence = createMathMLOperator(m_open, MathMLOperatorDictionary::Prefix, MathMLOperatorDictionary::Fence);
-    RenderMathMLRow::addChild(WTFMove(openFence), firstChild());
+    RenderMathMLRow::addChild(builder, WTFMove(openFence), firstChild());
 
     auto closeFence = createMathMLOperator(m_close, MathMLOperatorDictionary::Postfix, MathMLOperatorDictionary::Fence);
     m_closeFenceRenderer = makeWeakPtr(*closeFence);
 
     auto closeFence = createMathMLOperator(m_close, MathMLOperatorDictionary::Postfix, MathMLOperatorDictionary::Fence);
     m_closeFenceRenderer = makeWeakPtr(*closeFence);
-    RenderMathMLRow::addChild(WTFMove(closeFence));
+    RenderMathMLRow::addChild(builder, WTFMove(closeFence));
 }
 
 }
 
-void RenderMathMLFenced::addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild)
+void RenderMathMLFenced::addChild(RenderTreeBuilder& builder, RenderPtr<RenderObject> child, RenderObject* beforeChild)
 {
     // make the fences if the render object is empty
 {
     // make the fences if the render object is empty
-    if (!firstChild())
+    if (!firstChild()) {
         updateFromElement();
         updateFromElement();
+        makeFences(builder);
+    }
 
     // FIXME: Adding or removing a child should possibly cause all later separators to shift places if they're different, as later child positions change by +1 or -1. This should also handle surrogate pairs. See https://bugs.webkit.org/show_bug.cgi?id=125938.
 
 
     // FIXME: Adding or removing a child should possibly cause all later separators to shift places if they're different, as later child positions change by +1 or -1. This should also handle surrogate pairs. See https://bugs.webkit.org/show_bug.cgi?id=125938.
 
@@ -133,22 +133,22 @@ void RenderMathMLFenced::addChild(RenderPtr<RenderObject> child, RenderObject* b
             else
                 separator = (*m_separators.get())[count - 1];
 
             else
                 separator = (*m_separators.get())[count - 1];
 
-            StringBuilder builder;
-            builder.append(separator);
-            separatorRenderer = createMathMLOperator(builder.toString(), MathMLOperatorDictionary::Infix, MathMLOperatorDictionary::Separator);
+            StringBuilder stringBuilder;
+            stringBuilder.append(separator);
+            separatorRenderer = createMathMLOperator(stringBuilder.toString(), MathMLOperatorDictionary::Infix, MathMLOperatorDictionary::Separator);
         }
     }
 
     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).
         }
     }
 
     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(WTFMove(child), beforeChild);
+        RenderMathMLRow::addChild(builder, WTFMove(child), beforeChild);
         if (separatorRenderer)
         if (separatorRenderer)
-            RenderMathMLRow::addChild(WTFMove(separatorRenderer), beforeChild);
+            RenderMathMLRow::addChild(builder, 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)
     } 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(WTFMove(separatorRenderer), m_closeFenceRenderer.get());
-        RenderMathMLRow::addChild(WTFMove(child), m_closeFenceRenderer.get());
+            RenderMathMLRow::addChild(builder, WTFMove(separatorRenderer), m_closeFenceRenderer.get());
+        RenderMathMLRow::addChild(builder, WTFMove(child), m_closeFenceRenderer.get());
     }
 }
 
     }
 }
 
index 77a63c9..ef6ec96 100644 (file)
@@ -42,11 +42,11 @@ public:
 private:
     bool isRenderMathMLFenced() const final { return true; }
     const char* renderName() const final { return "RenderMathMLFenced"; }
 private:
     bool isRenderMathMLFenced() const final { return true; }
     const char* renderName() const final { return "RenderMathMLFenced"; }
-    void addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild) final;
-    void updateFromElement() final;
+    void addChild(RenderTreeBuilder&, RenderPtr<RenderObject> child, RenderObject* beforeChild) final;
+    void updateFromElement();
 
     RenderPtr<RenderMathMLFencedOperator> createMathMLOperator(const String& operatorString, MathMLOperatorDictionary::Form, MathMLOperatorDictionary::Flag);
 
     RenderPtr<RenderMathMLFencedOperator> createMathMLOperator(const String& operatorString, MathMLOperatorDictionary::Form, MathMLOperatorDictionary::Flag);
-    void makeFences();
+    void makeFences(RenderTreeBuilder&);
 
     String m_open;
     String m_close;
 
     String m_open;
     String m_close;
index 814361f..f09e380 100644 (file)
@@ -89,10 +89,10 @@ void RenderSVGContainer::layout()
     clearNeedsLayout();
 }
 
     clearNeedsLayout();
 }
 
-void RenderSVGContainer::addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
+void RenderSVGContainer::addChild(RenderTreeBuilder& builder, RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
     auto& child = *newChild;
 {
     auto& child = *newChild;
-    RenderSVGModelObject::addChild(WTFMove(newChild), beforeChild);
+    RenderSVGModelObject::addChild(builder, WTFMove(newChild), beforeChild);
     SVGResourcesCache::clientWasAddedToTree(child);
 }
 
     SVGResourcesCache::clientWasAddedToTree(child);
 }
 
index 307f511..43feda1 100644 (file)
@@ -48,7 +48,7 @@ protected:
 
     void layout() override;
 
 
     void layout() override;
 
-    void addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild = 0) final;
+    void addChild(RenderTreeBuilder&, RenderPtr<RenderObject> child, RenderObject* beforeChild = 0) final;
     RenderPtr<RenderObject> takeChild(RenderObject&) final;
     void addFocusRingRects(Vector<LayoutRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) final;
 
     RenderPtr<RenderObject> takeChild(RenderObject&) final;
     void addFocusRingRects(Vector<LayoutRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) final;
 
index 2839a7f..3029c78 100644 (file)
@@ -123,10 +123,10 @@ void RenderSVGInline::updateFromStyle()
     setInline(true);
 }
 
     setInline(true);
 }
 
-void RenderSVGInline::addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
+void RenderSVGInline::addChild(RenderTreeBuilder& builder, RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
     auto& child = *newChild;
 {
     auto& child = *newChild;
-    RenderInline::addChild(WTFMove(newChild), beforeChild);
+    RenderInline::addChild(builder, WTFMove(newChild), beforeChild);
     SVGResourcesCache::clientWasAddedToTree(child);
 
     if (auto* textAncestor = RenderSVGText::locateRenderSVGTextAncestor(*this))
     SVGResourcesCache::clientWasAddedToTree(child);
 
     if (auto* textAncestor = RenderSVGText::locateRenderSVGTextAncestor(*this))
index af9e23b..69b9d84 100644 (file)
@@ -61,7 +61,7 @@ private:
     void willBeDestroyed() final;
     void styleDidChange(StyleDifference, const RenderStyle* oldStyle) final;
 
     void willBeDestroyed() final;
     void styleDidChange(StyleDifference, const RenderStyle* oldStyle) final;
 
-    void addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild = nullptr) final;
+    void addChild(RenderTreeBuilder&, RenderPtr<RenderObject> child, RenderObject* beforeChild = nullptr) final;
     RenderPtr<RenderObject> takeChild(RenderObject&) final;
 };
 
     RenderPtr<RenderObject> takeChild(RenderObject&) final;
 };
 
index 8d53d8d..18794eb 100644 (file)
@@ -302,10 +302,10 @@ void RenderSVGRoot::styleDidChange(StyleDifference diff, const RenderStyle* oldS
     SVGResourcesCache::clientStyleChanged(*this, diff, style());
 }
 
     SVGResourcesCache::clientStyleChanged(*this, diff, style());
 }
 
-void RenderSVGRoot::addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
+void RenderSVGRoot::addChild(RenderTreeBuilder& builder, RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
     auto& child = *newChild;
 {
     auto& child = *newChild;
-    RenderReplaced::addChild(WTFMove(newChild), beforeChild);
+    RenderReplaced::addChild(builder, WTFMove(newChild), beforeChild);
     SVGResourcesCache::clientWasAddedToTree(child);
 }
 
     SVGResourcesCache::clientWasAddedToTree(child);
 }
 
index 4984262..374ed5e 100644 (file)
@@ -82,7 +82,7 @@ private:
     void willBeRemovedFromTree() override;
 
     void styleDidChange(StyleDifference, const RenderStyle* oldStyle) override;
     void willBeRemovedFromTree() override;
 
     void styleDidChange(StyleDifference, const RenderStyle* oldStyle) override;
-    void addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild = 0) override;
+    void addChild(RenderTreeBuilder&, RenderPtr<RenderObject> child, RenderObject* beforeChild = 0) override;
     RenderPtr<RenderObject> takeChild(RenderObject&) override;
 
     const AffineTransform& localToParentTransform() const override;
     RenderPtr<RenderObject> takeChild(RenderObject&) override;
 
     const AffineTransform& localToParentTransform() const override;
index a52c07e..b75b48e 100644 (file)
@@ -520,10 +520,10 @@ FloatRect RenderSVGText::repaintRectInLocalCoordinates() const
     return repaintRect;
 }
 
     return repaintRect;
 }
 
-void RenderSVGText::addChild(RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
+void RenderSVGText::addChild(RenderTreeBuilder& builder, RenderPtr<RenderObject> newChild, RenderObject* beforeChild)
 {
     auto& child = *newChild;
 {
     auto& child = *newChild;
-    RenderSVGBlock::addChild(WTFMove(newChild), beforeChild);
+    RenderSVGBlock::addChild(builder, WTFMove(newChild), beforeChild);
 
     SVGResourcesCache::clientWasAddedToTree(child);
     subtreeChildWasAdded(&child);
 
     SVGResourcesCache::clientWasAddedToTree(child);
     subtreeChildWasAdded(&child);
index 4fee655..5e1ddde 100644 (file)
@@ -83,7 +83,7 @@ private:
 
     void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags, bool* wasFixed) const override;
     const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const override;
 
     void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags, bool* wasFixed) const override;
     const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const override;
-    void addChild(RenderPtr<RenderObject> child, RenderObject* beforeChild = nullptr) override;
+    void addChild(RenderTreeBuilder&, RenderPtr<RenderObject> child, RenderObject* beforeChild = nullptr) override;
     RenderPtr<RenderObject> takeChild(RenderObject&) override;
     void willBeDestroyed() override;
 
     RenderPtr<RenderObject> takeChild(RenderObject&) override;
     void willBeDestroyed() override;
 
index 067a763..b3e86dd 100644 (file)
 
 namespace WebCore {
 
 
 namespace WebCore {
 
-void RenderTreePosition::insert(RenderPtr<RenderObject> renderer)
-{
-    ASSERT(m_hasValidNextSibling);
-    auto* insertBefore = m_nextSibling;
-    if (is<RenderText>(insertBefore)) {
-        if (auto* wrapperInline = downcast<RenderText>(*insertBefore).inlineWrapperForDisplayContents())
-            insertBefore = wrapperInline;
-    }
-    m_parent.addChild(WTFMove(renderer), insertBefore);
-}
-
 void RenderTreePosition::computeNextSibling(const Node& node)
 {
     ASSERT(!node.renderer());
 void RenderTreePosition::computeNextSibling(const Node& node)
 {
     ASSERT(!node.renderer());
index 8d89fae..e0e09c0 100644 (file)
@@ -38,11 +38,15 @@ public:
         : m_parent(parent)
     {
     }
         : m_parent(parent)
     {
     }
+    RenderTreePosition(RenderElement& parent, RenderObject* nextSibling)
+        : m_parent(parent)
+        , m_nextSibling(nextSibling)
+        , m_hasValidNextSibling(true)
+    {
+    }
 
     RenderElement& parent() const { return m_parent; }
 
     RenderElement& parent() const { return m_parent; }
-    void insert(RenderPtr<RenderObject>);
-    bool canInsert(RenderElement&) const;
-    bool canInsert(RenderText&) const;
+    RenderObject* nextSibling() const { ASSERT(m_hasValidNextSibling); return m_nextSibling; }
 
     void computeNextSibling(const Node&);
     void moveToLastChild();
 
     void computeNextSibling(const Node&);
     void moveToLastChild();
@@ -66,16 +70,4 @@ inline void RenderTreePosition::moveToLastChild()
     m_hasValidNextSibling = true;
 }
 
     m_hasValidNextSibling = true;
 }
 
-inline bool RenderTreePosition::canInsert(RenderElement& renderer) const
-{
-    ASSERT(!renderer.parent());
-    return m_parent.isChildAllowed(renderer, renderer.style());
-}
-
-inline bool RenderTreePosition::canInsert(RenderText& renderer) const
-{
-    ASSERT(!renderer.parent());
-    return m_parent.isChildAllowed(renderer, m_parent.style());
-}
-
 } // namespace WebCore
 } // namespace WebCore
index cc39f22..c11ab6c 100644 (file)
@@ -274,7 +274,7 @@ void RenderTreeUpdater::updateAfterDescendants(Element& element, const Style::El
     if (is<RenderBlock>(*renderer))
         FirstLetter::update(downcast<RenderBlock>(*renderer));
     if (is<RenderListItem>(*renderer))
     if (is<RenderBlock>(*renderer))
         FirstLetter::update(downcast<RenderBlock>(*renderer));
     if (is<RenderListItem>(*renderer))
-        ListItem::updateMarker(downcast<RenderListItem>(*renderer));
+        ListItem::updateMarker(m_builder, downcast<RenderListItem>(*renderer));
     if (is<RenderBlockFlow>(*renderer))
         MultiColumn::update(downcast<RenderBlockFlow>(*renderer));
 
     if (is<RenderBlockFlow>(*renderer))
         MultiColumn::update(downcast<RenderBlockFlow>(*renderer));
 
@@ -376,7 +376,8 @@ void RenderTreeUpdater::createRenderer(Element& element, RenderStyle&& style)
     auto newRenderer = element.createElementRenderer(WTFMove(style), insertionPosition);
     if (!newRenderer)
         return;
     auto newRenderer = element.createElementRenderer(WTFMove(style), insertionPosition);
     if (!newRenderer)
         return;
-    if (!insertionPosition.canInsert(*newRenderer))
+
+    if (!insertionPosition.parent().isChildAllowed(*newRenderer, newRenderer->style()))
         return;
 
     element.setRenderer(newRenderer.get());
         return;
 
     element.setRenderer(newRenderer.get());
@@ -385,13 +386,13 @@ void RenderTreeUpdater::createRenderer(Element& element, RenderStyle&& style)
 
 #if ENABLE(FULLSCREEN_API)
     if (m_document.webkitIsFullScreen() && m_document.webkitCurrentFullScreenElement() == &element) {
 
 #if ENABLE(FULLSCREEN_API)
     if (m_document.webkitIsFullScreen() && m_document.webkitCurrentFullScreenElement() == &element) {
-        newRenderer = RenderFullScreen::wrapNewRenderer(WTFMove(newRenderer), insertionPosition.parent(), m_document);
+        newRenderer = RenderFullScreen::wrapNewRenderer(m_builder, WTFMove(newRenderer), insertionPosition.parent(), m_document);
         if (!newRenderer)
             return;
     }
 #endif
 
         if (!newRenderer)
             return;
     }
 #endif
 
-    insertionPosition.insert(WTFMove(newRenderer));
+    m_builder.insertChild(insertionPosition, WTFMove(newRenderer));
 
     if (AXObjectCache* cache = m_document.axObjectCache())
         cache->updateCacheAfterNodeIsAttached(&element);
 
     if (AXObjectCache* cache = m_document.axObjectCache())
         cache->updateCacheAfterNodeIsAttached(&element);
@@ -445,15 +446,16 @@ bool RenderTreeUpdater::textRendererIsNeeded(const Text& textNode)
     return true;
 }
 
     return true;
 }
 
-static void createTextRenderer(Text& textNode, RenderTreePosition& renderTreePosition, const Style::TextUpdate* textUpdate)
+void RenderTreeUpdater::createTextRenderer(Text& textNode, const Style::TextUpdate* textUpdate)
 {
     ASSERT(!textNode.renderer());
 
 {
     ASSERT(!textNode.renderer());
 
+    auto& renderTreePosition = this->renderTreePosition();
     auto textRenderer = textNode.createTextRenderer(renderTreePosition.parent().style());
 
     renderTreePosition.computeNextSibling(textNode);
 
     auto textRenderer = textNode.createTextRenderer(renderTreePosition.parent().style());
 
     renderTreePosition.computeNextSibling(textNode);
 
-    if (!renderTreePosition.canInsert(*textRenderer))
+    if (!renderTreePosition.parent().isChildAllowed(*textRenderer, renderTreePosition.parent().style()))
         return;
 
     textNode.setRenderer(textRenderer.get());
         return;
 
     textNode.setRenderer(textRenderer.get());
@@ -461,17 +463,17 @@ static void createTextRenderer(Text& textNode, RenderTreePosition& renderTreePos
     if (textUpdate && textUpdate->inheritedDisplayContentsStyle && *textUpdate->inheritedDisplayContentsStyle) {
         // Wrap text renderer into anonymous inline so we can give it a style.
         // This is to support "<div style='display:contents;color:green'>text</div>" type cases
     if (textUpdate && textUpdate->inheritedDisplayContentsStyle && *textUpdate->inheritedDisplayContentsStyle) {
         // Wrap text renderer into anonymous inline so we can give it a style.
         // This is to support "<div style='display:contents;color:green'>text</div>" type cases
-        auto newDisplayContentsAnonymousWrapper = createRenderer<RenderInline>(textNode.document(), RenderStyle::clone(**textUpdate->inheritedDisplayContentsStyle));
+        auto newDisplayContentsAnonymousWrapper = WebCore::createRenderer<RenderInline>(textNode.document(), RenderStyle::clone(**textUpdate->inheritedDisplayContentsStyle));
         newDisplayContentsAnonymousWrapper->initializeStyle();
         auto& displayContentsAnonymousWrapper = *newDisplayContentsAnonymousWrapper;
         newDisplayContentsAnonymousWrapper->initializeStyle();
         auto& displayContentsAnonymousWrapper = *newDisplayContentsAnonymousWrapper;
-        renderTreePosition.insert(WTFMove(newDisplayContentsAnonymousWrapper));
+        m_builder.insertChild(renderTreePosition, WTFMove(newDisplayContentsAnonymousWrapper));
 
         textRenderer->setInlineWrapperForDisplayContents(&displayContentsAnonymousWrapper);
 
         textRenderer->setInlineWrapperForDisplayContents(&displayContentsAnonymousWrapper);
-        displayContentsAnonymousWrapper.addChild(WTFMove(textRenderer));
+        m_builder.insertChild(displayContentsAnonymousWrapper, WTFMove(textRenderer));
         return;
     }
 
         return;
     }
 
-    renderTreePosition.insert(WTFMove(textRenderer));
+    m_builder.insertChild(renderTreePosition, WTFMove(textRenderer));
 }
 
 void RenderTreeUpdater::updateTextRenderer(Text& text, const Style::TextUpdate* textUpdate)
 }
 
 void RenderTreeUpdater::updateTextRenderer(Text& text, const Style::TextUpdate* textUpdate)
@@ -482,7 +484,7 @@ void RenderTreeUpdater::updateTextRenderer(Text& text, const Style::TextUpdate*
     if (existingRenderer && textUpdate && textUpdate->inheritedDisplayContentsStyle) {
         if (existingRenderer->inlineWrapperForDisplayContents() || *textUpdate->inheritedDisplayContentsStyle) {
             // FIXME: We could update without teardown.
     if (existingRenderer && textUpdate && textUpdate->inheritedDisplayContentsStyle) {
         if (existingRenderer->inlineWrapperForDisplayContents() || *textUpdate->inheritedDisplayContentsStyle) {
             // FIXME: We could update without teardown.
-            tearDownRenderer(text);
+            tearDownTextRenderer(text);
             existingRenderer = nullptr;
         }
     }
             existingRenderer = nullptr;
         }
     }
@@ -493,13 +495,13 @@ void RenderTreeUpdater::updateTextRenderer(Text& text, const Style::TextUpdate*
                 existingRenderer->setTextWithOffset(text.data(), textUpdate->offset, textUpdate->length);
             return;
         }
                 existingRenderer->setTextWithOffset(text.data(), textUpdate->offset, textUpdate->length);
             return;
         }
-        tearDownRenderer(text);
+        tearDownTextRenderer(text);
         renderingParent().didCreateOrDestroyChildRenderer = true;
         return;
     }
     if (!needsRenderer)
         return;
         renderingParent().didCreateOrDestroyChildRenderer = true;
         return;
     }
     if (!needsRenderer)
         return;
-    createTextRenderer(text, renderTreePosition(), textUpdate);
+    createTextRenderer(text, textUpdate);
     renderingParent().didCreateOrDestroyChildRenderer = true;
 }
 
     renderingParent().didCreateOrDestroyChildRenderer = true;
 }
 
@@ -514,9 +516,16 @@ void RenderTreeUpdater::storePreviousRenderer(Node& node)
 
 void RenderTreeUpdater::tearDownRenderers(Element& root)
 {
 
 void RenderTreeUpdater::tearDownRenderers(Element& root)
 {
+    RenderTreeBuilder builder;
     tearDownRenderers(root, TeardownType::Full);
 }
 
     tearDownRenderers(root, TeardownType::Full);
 }
 
+void RenderTreeUpdater::tearDownRenderer(Text& text)
+{
+    RenderTreeBuilder builder;
+    tearDownTextRenderer(text);
+}
+
 void RenderTreeUpdater::tearDownRenderers(Element& root, TeardownType teardownType)
 {
     WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
 void RenderTreeUpdater::tearDownRenderers(Element& root, TeardownType teardownType)
 {
     WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
@@ -541,7 +550,8 @@ void RenderTreeUpdater::tearDownRenderers(Element& root, TeardownType teardownTy
             if (teardownType == TeardownType::Full)
                 element.clearHoverAndActiveStatusBeforeDetachingRenderer();
 
             if (teardownType == TeardownType::Full)
                 element.clearHoverAndActiveStatusBeforeDetachingRenderer();
 
-            element.clearStyleDerivedDataBeforeDetachingRenderer();
+            GeneratedContent::removeBeforePseudoElement(element);
+            GeneratedContent::removeAfterPseudoElement(element);
 
             if (auto* renderer = element.renderer()) {
                 renderer->removeFromParentAndDestroyCleaningUpAnonymousWrappers();
 
             if (auto* renderer = element.renderer()) {
                 renderer->removeFromParentAndDestroyCleaningUpAnonymousWrappers();
@@ -559,7 +569,7 @@ void RenderTreeUpdater::tearDownRenderers(Element& root, TeardownType teardownTy
         pop(it.depth());
 
         if (is<Text>(*it)) {
         pop(it.depth());
 
         if (is<Text>(*it)) {
-            tearDownRenderer(downcast<Text>(*it));
+            tearDownTextRenderer(downcast<Text>(*it));
             continue;
         }
 
             continue;
         }
 
@@ -569,7 +579,7 @@ void RenderTreeUpdater::tearDownRenderers(Element& root, TeardownType teardownTy
     pop(0);
 }
 
     pop(0);
 }
 
-void RenderTreeUpdater::tearDownRenderer(Text& text)
+void RenderTreeUpdater::tearDownTextRenderer(Text& text)
 {
     auto* renderer = text.renderer();
     if (!renderer)
 {
     auto* renderer = text.renderer();
     if (!renderer)
index ca4000b..afe5647 100644 (file)
@@ -25,6 +25,7 @@
 
 #pragma once
 
 
 #pragma once
 
+#include "RenderTreeBuilder.h"
 #include "RenderTreePosition.h"
 #include "StyleChange.h"
 #include "StyleUpdate.h"
 #include "RenderTreePosition.h"
 #include "StyleChange.h"
 #include "StyleUpdate.h"
@@ -59,6 +60,7 @@ private:
 
     void updateRenderTree(ContainerNode& root);
     void updateTextRenderer(Text&, const Style::TextUpdate*);
 
     void updateRenderTree(ContainerNode& root);
     void updateTextRenderer(Text&, const Style::TextUpdate*);
+    void createTextRenderer(Text&, const Style::TextUpdate*);
     void updateElementRenderer(Element&, const Style::ElementUpdate&);
     void createRenderer(Element&, RenderStyle&&);
     void updateBeforeDescendants(Element&, const Style::ElementUpdates*);
     void updateElementRenderer(Element&, const Style::ElementUpdate&);
     void createRenderer(Element&, RenderStyle&&);
     void updateBeforeDescendants(Element&, const Style::ElementUpdates*);
@@ -89,6 +91,7 @@ private:
 
     enum class TeardownType { Full, RendererUpdate, RendererUpdateCancelingAnimations };
     static void tearDownRenderers(Element&, TeardownType);
 
     enum class TeardownType { Full, RendererUpdate, RendererUpdateCancelingAnimations };
     static void tearDownRenderers(Element&, TeardownType);
+    static void tearDownTextRenderer(Text&);
 
     RenderView& renderView();
 
 
     RenderView& renderView();
 
@@ -98,6 +101,8 @@ private:
     Vector<Parent> m_parentStack;
 
     std::unique_ptr<GeneratedContent> m_generatedContent;
     Vector<Parent> m_parentStack;
 
     std::unique_ptr<GeneratedContent> m_generatedContent;
+
+    RenderTreeBuilder m_builder;
 };
 
 } // namespace WebCore
 };
 
 } // namespace WebCore
index 476f4d7..9b7d4e8 100644 (file)
@@ -33,6 +33,7 @@
 #include "RenderStyle.h"
 #include "RenderTable.h"
 #include "RenderTextFragment.h"
 #include "RenderStyle.h"
 #include "RenderTable.h"
 #include "RenderTextFragment.h"
+#include "RenderTreeBuilder.h"
 
 namespace WebCore {
 
 
 namespace WebCore {
 
@@ -124,7 +125,7 @@ static void updateFirstLetterStyle(RenderBlock& firstLetterBlock, RenderObject&
             if (is<RenderText>(*child))
                 downcast<RenderText>(*child).removeAndDestroyTextBoxes();
             auto toMove = firstLetter->takeChild(*child);
             if (is<RenderText>(*child))
                 downcast<RenderText>(*child).removeAndDestroyTextBoxes();
             auto toMove = firstLetter->takeChild(*child);
-            newFirstLetter->addChild(WTFMove(toMove));
+            RenderTreeBuilder::current()->insertChild(*newFirstLetter, WTFMove(toMove));
         }
 
         RenderObject* nextSibling = firstLetter->nextSibling();
         }
 
         RenderObject* nextSibling = firstLetter->nextSibling();
@@ -135,7 +136,7 @@ static void updateFirstLetterStyle(RenderBlock& firstLetterBlock, RenderObject&
             newFirstLetter->setFirstLetterRemainingText(*remainingText);
         }
         firstLetterContainer->removeAndDestroyChild(*firstLetter);
             newFirstLetter->setFirstLetterRemainingText(*remainingText);
         }
         firstLetterContainer->removeAndDestroyChild(*firstLetter);
-        firstLetterContainer->addChild(WTFMove(newFirstLetter), nextSibling);
+        RenderTreeBuilder::current()->insertChild(*firstLetterContainer, WTFMove(newFirstLetter), nextSibling);
     } else
         firstLetter->setStyle(WTFMove(pseudoStyle));
 }
     } else
         firstLetter->setStyle(WTFMove(pseudoStyle));
 }
@@ -153,7 +154,7 @@ static void createFirstLetterRenderer(RenderBlock& firstLetterBlock, RenderText&
     newFirstLetter->setIsFirstLetter();
 
     auto& firstLetter = *newFirstLetter;
     newFirstLetter->setIsFirstLetter();
 
     auto& firstLetter = *newFirstLetter;
-    firstLetterContainer->addChild(WTFMove(newFirstLetter), &currentTextChild);
+    RenderTreeBuilder::current()->insertChild(*firstLetterContainer, 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
 
     // 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
@@ -197,14 +198,14 @@ static void createFirstLetterRenderer(RenderBlock& firstLetterBlock, RenderText&
             newRemainingText = createRenderer<RenderTextFragment>(firstLetterBlock.document(), oldText, length, oldText.length() - length);
 
         RenderTextFragment& remainingText = *newRemainingText;
             newRemainingText = createRenderer<RenderTextFragment>(firstLetterBlock.document(), oldText, length, oldText.length() - length);
 
         RenderTextFragment& remainingText = *newRemainingText;
-        firstLetterContainer->addChild(WTFMove(newRemainingText), beforeChild);
+        RenderTreeBuilder::current()->insertChild(*firstLetterContainer, WTFMove(newRemainingText), beforeChild);
         remainingText.setFirstLetter(firstLetter);
         firstLetter.setFirstLetterRemainingText(remainingText);
 
         // construct text fragment for the first letter
         auto letter = createRenderer<RenderTextFragment>(firstLetterBlock.document(), oldText, 0, length);
 
         remainingText.setFirstLetter(firstLetter);
         firstLetter.setFirstLetterRemainingText(remainingText);
 
         // construct text fragment for the first letter
         auto letter = createRenderer<RenderTextFragment>(firstLetterBlock.document(), oldText, 0, length);
 
-        firstLetter.addChild(WTFMove(letter));
+        RenderTreeBuilder::current()->insertChild(firstLetter, WTFMove(letter));
     }
 }
 
     }
 }
 
index 05b3643..9446b5a 100644 (file)
@@ -61,7 +61,7 @@ void RenderTreeUpdater::GeneratedContent::updateQuotesUpTo(RenderQuote* lastQuot
     for (; it != end; ++it) {
         auto& quote = *it;
         // Quote character depends on quote depth so we chain the updates.
     for (; it != end; ++it) {
         auto& quote = *it;
         // Quote character depends on quote depth so we chain the updates.
-        quote.updateRenderer(m_previousUpdatedQuote);
+        quote.updateRenderer(m_updater.m_builder, m_previousUpdatedQuote);
         m_previousUpdatedQuote = &quote;
         if (&quote == lastQuote)
             return;
         m_previousUpdatedQuote = &quote;
         if (&quote == lastQuote)
             return;
@@ -69,14 +69,14 @@ void RenderTreeUpdater::GeneratedContent::updateQuotesUpTo(RenderQuote* lastQuot
     ASSERT(!lastQuote);
 }
 
     ASSERT(!lastQuote);
 }
 
-static void createContentRenderers(RenderElement& pseudoRenderer, const RenderStyle& style)
+static void createContentRenderers(RenderTreeBuilder& builder, RenderElement& pseudoRenderer, const RenderStyle& style)
 {
     ASSERT(style.contentData());
 
     for (const ContentData* content = style.contentData(); content; content = content->next()) {
         auto child = content->createContentRenderer(pseudoRenderer.document(), style);
         if (pseudoRenderer.isChildAllowed(*child, style))
 {
     ASSERT(style.contentData());
 
     for (const ContentData* content = style.contentData(); content; content = content->next()) {
         auto child = content->createContentRenderer(pseudoRenderer.document(), style);
         if (pseudoRenderer.isChildAllowed(*child, style))
-            pseudoRenderer.addChild(WTFMove(child));
+            builder.insertChild(pseudoRenderer, WTFMove(child));
     }
 }
 
     }
 }
 
@@ -100,9 +100,9 @@ void RenderTreeUpdater::GeneratedContent::updatePseudoElement(Element& current,
     if (!needsPseudoElement(update)) {
         if (pseudoElement) {
             if (pseudoId == BEFORE)
     if (!needsPseudoElement(update)) {
         if (pseudoElement) {
             if (pseudoId == BEFORE)
-                current.clearBeforePseudoElement();
+                removeBeforePseudoElement(current);
             else
             else
-                current.clearAfterPseudoElement();
+                removeAfterPseudoElement(current);
         }
         return;
     }
         }
         return;
     }
@@ -144,7 +144,7 @@ void RenderTreeUpdater::GeneratedContent::updatePseudoElement(Element& current,
         return;
 
     if (update->change == Style::Detach)
         return;
 
     if (update->change == Style::Detach)
-        createContentRenderers(*pseudoElementRenderer, *update->style);
+        createContentRenderers(m_updater.m_builder, *pseudoElementRenderer, *update->style);
     else
         updateStyleForContentRenderers(*pseudoElementRenderer, *update->style);
 
     else
         updateStyleForContentRenderers(*pseudoElementRenderer, *update->style);
 
@@ -153,7 +153,7 @@ void RenderTreeUpdater::GeneratedContent::updatePseudoElement(Element& current,
             updateQuotesUpTo(&child);
     }
     if (is<RenderListItem>(*pseudoElementRenderer))
             updateQuotesUpTo(&child);
     }
     if (is<RenderListItem>(*pseudoElementRenderer))
-        ListItem::updateMarker(downcast<RenderListItem>(*pseudoElementRenderer));
+        ListItem::updateMarker(m_updater.m_builder, downcast<RenderListItem>(*pseudoElementRenderer));
 }
 
 bool RenderTreeUpdater::GeneratedContent::needsPseudoElement(const std::optional<Style::ElementUpdate>& update)
 }
 
 bool RenderTreeUpdater::GeneratedContent::needsPseudoElement(const std::optional<Style::ElementUpdate>& update)
@@ -167,4 +167,22 @@ bool RenderTreeUpdater::GeneratedContent::needsPseudoElement(const std::optional
     return true;
 }
 
     return true;
 }
 
+void RenderTreeUpdater::GeneratedContent::removeBeforePseudoElement(Element& element)
+{
+    auto* pseudoElement = element.beforePseudoElement();
+    if (!pseudoElement)
+        return;
+    tearDownRenderers(*pseudoElement, TeardownType::Full);
+    element.clearBeforePseudoElement();
+}
+
+void RenderTreeUpdater::GeneratedContent::removeAfterPseudoElement(Element& element)
+{
+    auto* pseudoElement = element.afterPseudoElement();
+    if (!pseudoElement)
+        return;
+    tearDownRenderers(*pseudoElement, TeardownType::Full);
+    element.clearAfterPseudoElement();
+}
+
 }
 }
index d1c2914..6bb134e 100644 (file)
@@ -40,6 +40,9 @@ public:
     void updatePseudoElement(Element&, const std::optional<Style::ElementUpdate>&, PseudoId);
     void updateRemainingQuotes();
 
     void updatePseudoElement(Element&, const std::optional<Style::ElementUpdate>&, PseudoId);
     void updateRemainingQuotes();
 
+    static void removeBeforePseudoElement(Element&);
+    static void removeAfterPseudoElement(Element&);
+
 private:
     void updateQuotesUpTo(RenderQuote*);
     
 private:
     void updateQuotesUpTo(RenderQuote*);
     
index d1fab6f..2362b34 100644 (file)
@@ -69,7 +69,7 @@ static RenderObject* firstNonMarkerChild(RenderBlock& parent)
     return child;
 }
 
     return child;
 }
 
-void RenderTreeUpdater::ListItem::updateMarker(RenderListItem& listItemRenderer)
+void RenderTreeUpdater::ListItem::updateMarker(RenderTreeBuilder& builder, RenderListItem& listItemRenderer)
 {
     ASSERT_WITH_SECURITY_IMPLICATION(!listItemRenderer.view().frameView().layoutContext().layoutState());
 
 {
     ASSERT_WITH_SECURITY_IMPLICATION(!listItemRenderer.view().frameView().layoutContext().layoutState());
 
@@ -110,9 +110,9 @@ void RenderTreeUpdater::ListItem::updateMarker(RenderListItem& listItemRenderer)
 
     if (newParent != currentParent) {
         if (currentParent)
 
     if (newParent != currentParent) {
         if (currentParent)
-            newParent->addChild(currentParent->takeChild(*markerRenderer), firstNonMarkerChild(*newParent));
+            builder.insertChild(*newParent, currentParent->takeChild(*markerRenderer), firstNonMarkerChild(*newParent));
         else
         else
-            newParent->addChild(WTFMove(newMarkerRenderer), firstNonMarkerChild(*newParent));
+            builder.insertChild(*newParent, 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())
 
         // 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())
index 40b4063..56db047 100644 (file)
@@ -32,7 +32,7 @@ namespace WebCore {
 
 class RenderTreeUpdater::ListItem {
 public:
 
 class RenderTreeUpdater::ListItem {
 public:
-    static void updateMarker(RenderListItem&);
+    static void updateMarker(RenderTreeBuilder&, RenderListItem&);
 };
 
 }
 };
 
 }
index 2e1f712..630a5c8 100644 (file)
@@ -29,6 +29,7 @@
 #include "RenderMultiColumnFlow.h"
 #include "RenderMultiColumnSet.h"
 #include "RenderMultiColumnSpannerPlaceholder.h"
 #include "RenderMultiColumnFlow.h"
 #include "RenderMultiColumnSet.h"
 #include "RenderMultiColumnSpannerPlaceholder.h"
+#include "RenderTreeBuilder.h"
 
 namespace WebCore {
 
 
 namespace WebCore {
 
@@ -73,14 +74,14 @@ void RenderTreeUpdater::MultiColumn::createFragmentedFlow(RenderBlockFlow& flow)
             auto& spannerOriginalParent = *placeholder->parent();
             // Detaching the spanner takes care of removing the placeholder (and merges the RenderMultiColumnSets).
             auto spannerToReInsert = spanner->parent()->takeChild(*spanner);
             auto& spannerOriginalParent = *placeholder->parent();
             // Detaching the spanner takes care of removing the placeholder (and merges the RenderMultiColumnSets).
             auto spannerToReInsert = spanner->parent()->takeChild(*spanner);
-            spannerOriginalParent.addChild(WTFMove(spannerToReInsert));
+            RenderTreeBuilder::current()->insertChild(spannerOriginalParent, WTFMove(spannerToReInsert));
         }
     }
 
     auto newFragmentedFlow = WebCore::createRenderer<RenderMultiColumnFlow>(flow.document(), RenderStyle::createAnonymousStyleWithDisplay(flow.style(), BLOCK));
     newFragmentedFlow->initializeStyle();
     auto& fragmentedFlow = *newFragmentedFlow;
         }
     }
 
     auto newFragmentedFlow = WebCore::createRenderer<RenderMultiColumnFlow>(flow.document(), RenderStyle::createAnonymousStyleWithDisplay(flow.style(), BLOCK));
     newFragmentedFlow->initializeStyle();
     auto& fragmentedFlow = *newFragmentedFlow;
-    flow.RenderBlock::addChild(WTFMove(newFragmentedFlow));
+    flow.RenderBlock::addChild(*RenderTreeBuilder::current(), WTFMove(newFragmentedFlow));
 
     // Reparent children preceding the fragmented flow into the fragmented flow.
     flow.moveChildrenTo(&fragmentedFlow, flow.firstChild(), &fragmentedFlow, RenderBoxModelObject::NormalizeAfterInsertion::Yes);
 
     // Reparent children preceding the fragmented flow into the fragmented flow.
     flow.moveChildrenTo(&fragmentedFlow, flow.firstChild(), &fragmentedFlow, RenderBoxModelObject::NormalizeAfterInsertion::Yes);
@@ -121,7 +122,7 @@ void RenderTreeUpdater::MultiColumn::destroyFragmentedFlow(RenderBlockFlow& flow
     multiColumnFlow.moveAllChildrenTo(&flow, RenderBoxModelObject::NormalizeAfterInsertion::Yes);
     multiColumnFlow.removeFromParentAndDestroy();
     for (auto& parentAndSpanner : parentAndSpannerList)
     multiColumnFlow.moveAllChildrenTo(&flow, RenderBoxModelObject::NormalizeAfterInsertion::Yes);
     multiColumnFlow.removeFromParentAndDestroy();
     for (auto& parentAndSpanner : parentAndSpannerList)
-        parentAndSpanner.first->addChild(WTFMove(parentAndSpanner.second));
+        RenderTreeBuilder::current()->insertChild(*parentAndSpanner.first, WTFMove(parentAndSpanner.second));
 }
 
 }
 }
 
 }