Unreviewed, rolling out r156254.
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 23 Sep 2013 06:35:47 +0000 (06:35 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 23 Sep 2013 06:35:47 +0000 (06:35 +0000)
http://trac.webkit.org/changeset/156254
https://bugs.webkit.org/show_bug.cgi?id=121779

Caused assertions in fast/regions tests (Requested by ap on
#webkit).

* CMakeLists.txt:
* GNUmakefile.list.am:
* Target.pri:
* WebCore.vcxproj/WebCore.vcxproj:
* WebCore.xcodeproj/project.pbxproj:
* rendering/AutoTableLayout.cpp:
(WebCore::AutoTableLayout::recalcColumn):
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::willBeDestroyed):
(WebCore::RenderBlock::addChildToAnonymousColumnBlocks):
(WebCore::RenderBlock::splitBlocks):
(WebCore::RenderBlock::splitFlow):
(WebCore::RenderBlock::makeChildrenAnonymousColumnBlocks):
(WebCore::RenderBlock::makeChildrenNonInline):
(WebCore::RenderBlock::removeLeftoverAnonymousBlock):
(WebCore::RenderBlock::collapseAnonymousBoxChild):
(WebCore::RenderBlock::removeChild):
(WebCore::RenderBlock::updateFirstLetterStyle):
* rendering/RenderBlock.h:
(WebCore::RenderBlock::firstChild):
(WebCore::RenderBlock::lastChild):
* rendering/RenderBox.cpp:
(WebCore::RenderBox::splitAnonymousBoxesAroundChild):
* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::moveChildTo):
* rendering/RenderElement.cpp:
(WebCore::RenderElement::RenderElement):
(WebCore::RenderElement::addChild):
(WebCore::RenderElement::removeChild):
* rendering/RenderElement.h:
* rendering/RenderEmbeddedObject.cpp:
(WebCore::RenderEmbeddedObject::layout):
* rendering/RenderEmbeddedObject.h:
* rendering/RenderFrameSet.h:
* rendering/RenderInline.cpp:
(WebCore::RenderInline::willBeDestroyed):
(WebCore::RenderInline::splitInlines):
(WebCore::RenderInline::splitFlow):
(WebCore::RenderInline::childBecameNonInline):
* rendering/RenderInline.h:
(WebCore::RenderInline::firstChild):
(WebCore::RenderInline::lastChild):
* rendering/RenderLayerModelObject.cpp:
(WebCore::RenderLayerModelObject::willBeDestroyed):
* rendering/RenderLineBreak.h:
* rendering/RenderListMarker.h:
* rendering/RenderMedia.cpp:
(WebCore::RenderMedia::layout):
* rendering/RenderMedia.h:
(WebCore::RenderMedia::firstChild):
(WebCore::RenderMedia::lastChild):
* rendering/RenderObject.cpp:
(WebCore::RenderObject::handleDynamicFloatPositionChange):
(WebCore::RenderObject::willBeDestroyed):
(WebCore::RenderObject::removeFromRenderFlowThreadRecursive):
* rendering/RenderObject.h:
(WebCore::RenderObject::firstChild):
(WebCore::RenderObject::lastChild):
(WebCore::RenderObject::children):
(WebCore::RenderObject::canHaveChildren):
* rendering/RenderObjectChildList.cpp: Added.
(WebCore::RenderObjectChildList::destroyLeftoverChildren):
(WebCore::RenderObjectChildList::removeChildNode):
(WebCore::RenderObjectChildList::insertChildNode):
* rendering/RenderObjectChildList.h: Copied from Source/WebCore/rendering/RenderMedia.h.
(WebCore::RenderObjectChildList::RenderObjectChildList):
(WebCore::RenderObjectChildList::firstChild):
(WebCore::RenderObjectChildList::lastChild):
(WebCore::RenderObjectChildList::setFirstChild):
(WebCore::RenderObjectChildList::setLastChild):
(WebCore::RenderObjectChildList::appendChildNode):
* rendering/RenderReplaced.h:
(WebCore::RenderReplaced::canHaveChildren):
* rendering/RenderReplica.h:
* rendering/RenderRubyBase.cpp:
(WebCore::RenderRubyBase::moveInlineChildren):
(WebCore::RenderRubyBase::moveBlockChildren):
* rendering/RenderTableCol.h:
* rendering/RenderTableRow.h:
* rendering/RenderTableSection.h:
* rendering/RenderText.h:
* rendering/RenderingAllInOne.cpp:
* rendering/mathml/RenderMathMLOperator.cpp:
(WebCore::RenderMathMLOperator::updateFromElement):
* rendering/svg/RenderSVGContainer.h:
(WebCore::RenderSVGContainer::firstChild):
(WebCore::RenderSVGContainer::lastChild):
* rendering/svg/RenderSVGGradientStop.h:
* rendering/svg/RenderSVGImage.h:
* rendering/svg/RenderSVGModelObject.cpp:
(WebCore::RenderSVGModelObject::willBeDestroyed):
* rendering/svg/RenderSVGRoot.h:
* rendering/svg/RenderSVGShape.h:

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

42 files changed:
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/GNUmakefile.list.am
Source/WebCore/Target.pri
Source/WebCore/WebCore.vcxproj/WebCore.vcxproj
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/rendering/AutoTableLayout.cpp
Source/WebCore/rendering/RenderBlock.cpp
Source/WebCore/rendering/RenderBlock.h
Source/WebCore/rendering/RenderBox.cpp
Source/WebCore/rendering/RenderBoxModelObject.cpp
Source/WebCore/rendering/RenderElement.cpp
Source/WebCore/rendering/RenderElement.h
Source/WebCore/rendering/RenderEmbeddedObject.cpp
Source/WebCore/rendering/RenderEmbeddedObject.h
Source/WebCore/rendering/RenderFrameSet.h
Source/WebCore/rendering/RenderInline.cpp
Source/WebCore/rendering/RenderInline.h
Source/WebCore/rendering/RenderLayerModelObject.cpp
Source/WebCore/rendering/RenderLineBreak.h
Source/WebCore/rendering/RenderListMarker.h
Source/WebCore/rendering/RenderMedia.cpp
Source/WebCore/rendering/RenderMedia.h
Source/WebCore/rendering/RenderObject.cpp
Source/WebCore/rendering/RenderObject.h
Source/WebCore/rendering/RenderObjectChildList.cpp [new file with mode: 0644]
Source/WebCore/rendering/RenderObjectChildList.h [new file with mode: 0644]
Source/WebCore/rendering/RenderReplaced.h
Source/WebCore/rendering/RenderReplica.h
Source/WebCore/rendering/RenderRubyBase.cpp
Source/WebCore/rendering/RenderTableCol.h
Source/WebCore/rendering/RenderTableRow.h
Source/WebCore/rendering/RenderTableSection.h
Source/WebCore/rendering/RenderText.h
Source/WebCore/rendering/RenderingAllInOne.cpp
Source/WebCore/rendering/mathml/RenderMathMLOperator.cpp
Source/WebCore/rendering/svg/RenderSVGContainer.h
Source/WebCore/rendering/svg/RenderSVGGradientStop.h
Source/WebCore/rendering/svg/RenderSVGImage.h
Source/WebCore/rendering/svg/RenderSVGModelObject.cpp
Source/WebCore/rendering/svg/RenderSVGRoot.h
Source/WebCore/rendering/svg/RenderSVGShape.h

index d3ddb6e..642990e 100644 (file)
@@ -2172,6 +2172,7 @@ set(WebCore_SOURCES
     rendering/RenderMultiColumnSet.cpp
     rendering/RenderNamedFlowThread.cpp
     rendering/RenderObject.cpp
+    rendering/RenderObjectChildList.cpp
     rendering/RenderProgress.cpp
     rendering/RenderQuote.cpp
     rendering/RenderRegion.cpp
index b9ecd29..9e3c0c9 100644 (file)
@@ -1,5 +1,108 @@
 2013-09-22  Commit Queue  <commit-queue@webkit.org>
 
+        Unreviewed, rolling out r156254.
+        http://trac.webkit.org/changeset/156254
+        https://bugs.webkit.org/show_bug.cgi?id=121779
+
+        Caused assertions in fast/regions tests (Requested by ap on
+        #webkit).
+
+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * Target.pri:
+        * WebCore.vcxproj/WebCore.vcxproj:
+        * WebCore.xcodeproj/project.pbxproj:
+        * rendering/AutoTableLayout.cpp:
+        (WebCore::AutoTableLayout::recalcColumn):
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::willBeDestroyed):
+        (WebCore::RenderBlock::addChildToAnonymousColumnBlocks):
+        (WebCore::RenderBlock::splitBlocks):
+        (WebCore::RenderBlock::splitFlow):
+        (WebCore::RenderBlock::makeChildrenAnonymousColumnBlocks):
+        (WebCore::RenderBlock::makeChildrenNonInline):
+        (WebCore::RenderBlock::removeLeftoverAnonymousBlock):
+        (WebCore::RenderBlock::collapseAnonymousBoxChild):
+        (WebCore::RenderBlock::removeChild):
+        (WebCore::RenderBlock::updateFirstLetterStyle):
+        * rendering/RenderBlock.h:
+        (WebCore::RenderBlock::firstChild):
+        (WebCore::RenderBlock::lastChild):
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::splitAnonymousBoxesAroundChild):
+        * rendering/RenderBoxModelObject.cpp:
+        (WebCore::RenderBoxModelObject::moveChildTo):
+        * rendering/RenderElement.cpp:
+        (WebCore::RenderElement::RenderElement):
+        (WebCore::RenderElement::addChild):
+        (WebCore::RenderElement::removeChild):
+        * rendering/RenderElement.h:
+        * rendering/RenderEmbeddedObject.cpp:
+        (WebCore::RenderEmbeddedObject::layout):
+        * rendering/RenderEmbeddedObject.h:
+        * rendering/RenderFrameSet.h:
+        * rendering/RenderInline.cpp:
+        (WebCore::RenderInline::willBeDestroyed):
+        (WebCore::RenderInline::splitInlines):
+        (WebCore::RenderInline::splitFlow):
+        (WebCore::RenderInline::childBecameNonInline):
+        * rendering/RenderInline.h:
+        (WebCore::RenderInline::firstChild):
+        (WebCore::RenderInline::lastChild):
+        * rendering/RenderLayerModelObject.cpp:
+        (WebCore::RenderLayerModelObject::willBeDestroyed):
+        * rendering/RenderLineBreak.h:
+        * rendering/RenderListMarker.h:
+        * rendering/RenderMedia.cpp:
+        (WebCore::RenderMedia::layout):
+        * rendering/RenderMedia.h:
+        (WebCore::RenderMedia::firstChild):
+        (WebCore::RenderMedia::lastChild):
+        * rendering/RenderObject.cpp:
+        (WebCore::RenderObject::handleDynamicFloatPositionChange):
+        (WebCore::RenderObject::willBeDestroyed):
+        (WebCore::RenderObject::removeFromRenderFlowThreadRecursive):
+        * rendering/RenderObject.h:
+        (WebCore::RenderObject::firstChild):
+        (WebCore::RenderObject::lastChild):
+        (WebCore::RenderObject::children):
+        (WebCore::RenderObject::canHaveChildren):
+        * rendering/RenderObjectChildList.cpp: Added.
+        (WebCore::RenderObjectChildList::destroyLeftoverChildren):
+        (WebCore::RenderObjectChildList::removeChildNode):
+        (WebCore::RenderObjectChildList::insertChildNode):
+        * rendering/RenderObjectChildList.h: Copied from Source/WebCore/rendering/RenderMedia.h.
+        (WebCore::RenderObjectChildList::RenderObjectChildList):
+        (WebCore::RenderObjectChildList::firstChild):
+        (WebCore::RenderObjectChildList::lastChild):
+        (WebCore::RenderObjectChildList::setFirstChild):
+        (WebCore::RenderObjectChildList::setLastChild):
+        (WebCore::RenderObjectChildList::appendChildNode):
+        * rendering/RenderReplaced.h:
+        (WebCore::RenderReplaced::canHaveChildren):
+        * rendering/RenderReplica.h:
+        * rendering/RenderRubyBase.cpp:
+        (WebCore::RenderRubyBase::moveInlineChildren):
+        (WebCore::RenderRubyBase::moveBlockChildren):
+        * rendering/RenderTableCol.h:
+        * rendering/RenderTableRow.h:
+        * rendering/RenderTableSection.h:
+        * rendering/RenderText.h:
+        * rendering/RenderingAllInOne.cpp:
+        * rendering/mathml/RenderMathMLOperator.cpp:
+        (WebCore::RenderMathMLOperator::updateFromElement):
+        * rendering/svg/RenderSVGContainer.h:
+        (WebCore::RenderSVGContainer::firstChild):
+        (WebCore::RenderSVGContainer::lastChild):
+        * rendering/svg/RenderSVGGradientStop.h:
+        * rendering/svg/RenderSVGImage.h:
+        * rendering/svg/RenderSVGModelObject.cpp:
+        (WebCore::RenderSVGModelObject::willBeDestroyed):
+        * rendering/svg/RenderSVGRoot.h:
+        * rendering/svg/RenderSVGShape.h:
+
+2013-09-22  Commit Queue  <commit-queue@webkit.org>
+
         Unreviewed, rolling out r156253.
         http://trac.webkit.org/changeset/156253
         https://bugs.webkit.org/show_bug.cgi?id=121778
index 83cbd22..238f6d0 100644 (file)
@@ -4504,6 +4504,8 @@ webcore_sources += \
        Source/WebCore/rendering/RenderMultiColumnSet.h \
        Source/WebCore/rendering/RenderNamedFlowThread.cpp \
        Source/WebCore/rendering/RenderNamedFlowThread.h \
+       Source/WebCore/rendering/RenderObjectChildList.cpp \
+       Source/WebCore/rendering/RenderObjectChildList.h \
        Source/WebCore/rendering/RenderObject.cpp \
        Source/WebCore/rendering/RenderObject.h \
        Source/WebCore/rendering/RenderOverflow.h \
index 6d9e4b0..2c4d881 100644 (file)
@@ -1194,6 +1194,7 @@ SOURCES += \
     rendering/RenderMultiColumnSet.cpp \
     rendering/RenderNamedFlowThread.cpp \
     rendering/RenderObject.cpp \
+    rendering/RenderObjectChildList.cpp \
     rendering/RenderProgress.cpp \
     rendering/RenderQuote.cpp \
     rendering/RenderRegion.cpp \
@@ -2460,6 +2461,7 @@ HEADERS += \
     rendering/RenderMenuList.h \
     rendering/RenderMeter.h \
     rendering/RenderMultiColumnBlock.h \
+    rendering/RenderObjectChildList.h \
     rendering/RenderObject.h \
     rendering/RenderProgress.h \
     rendering/RenderQuote.h \
index 5d94417..5569571 100644 (file)
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|x64'">true</ExcludedFromBuild>
     </ClCompile>
+    <ClCompile Include="..\rendering\RenderObjectChildList.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|x64'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="..\rendering\RenderProgress.cpp">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
     <ClInclude Include="..\rendering\RenderMultiColumnSet.h" />
     <ClInclude Include="..\rendering\RenderNamedFlowThread.h" />
     <ClInclude Include="..\rendering\RenderObject.h" />
+    <ClInclude Include="..\rendering\RenderObjectChildList.h" />
     <ClInclude Include="..\rendering\RenderProgress.h" />
     <ClInclude Include="..\rendering\RenderQuote.h" />
     <ClInclude Include="..\rendering\RenderRegion.h" />
index 8d3531b..60e84f4 100644 (file)
                BC29935D17A1DD5800BCE880 /* ColorInputType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC29935C17A1DD5800BCE880 /* ColorInputType.cpp */; };
                BC2CBF4E140F1ABD003879BE /* JSWebGLContextEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = BC2CBF4B140F1A65003879BE /* JSWebGLContextEvent.h */; };
                BC2CBF7B140F1D58003879BE /* JSWebGLContextEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC2CBF7A140F1D58003879BE /* JSWebGLContextEvent.cpp */; };
+               BC2CC8DF0F32881000A9DF26 /* RenderObjectChildList.h in Headers */ = {isa = PBXBuildFile; fileRef = BC2CC8DE0F32881000A9DF26 /* RenderObjectChildList.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BC2ED5550C6B9BD300920BFF /* JSElementCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC2ED5540C6B9BD300920BFF /* JSElementCustom.cpp */; };
                BC2ED6BC0C6BD2F000920BFF /* JSAttrCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC2ED6BB0C6BD2F000920BFF /* JSAttrCustom.cpp */; };
                BC2ED7A50C6C0F3600920BFF /* JSHTMLFrameElementCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC2ED7A40C6C0F3600920BFF /* JSHTMLFrameElementCustom.cpp */; };
                BC60DA5B0D2A31F700B9918F /* XPathException.h in Headers */ = {isa = PBXBuildFile; fileRef = BC60DA590D2A31F700B9918F /* XPathException.h */; };
                BC60DB490D2A3D1E00B9918F /* JSXPathException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC60DB470D2A3D1E00B9918F /* JSXPathException.cpp */; };
                BC60DB4A0D2A3D1E00B9918F /* JSXPathException.h in Headers */ = {isa = PBXBuildFile; fileRef = BC60DB480D2A3D1E00B9918F /* JSXPathException.h */; };
+               BC60EFB70F33A0E700812A93 /* RenderObjectChildList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC60EFB60F33A0E700812A93 /* RenderObjectChildList.cpp */; };
                BC64640911D7F304006455B0 /* DOMStringMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC64640711D7F304006455B0 /* DOMStringMap.cpp */; };
                BC64640A11D7F304006455B0 /* DOMStringMap.h in Headers */ = {isa = PBXBuildFile; fileRef = BC64640811D7F304006455B0 /* DOMStringMap.h */; };
                BC64641C11D7F416006455B0 /* DatasetDOMStringMap.h in Headers */ = {isa = PBXBuildFile; fileRef = BC64641A11D7F416006455B0 /* DatasetDOMStringMap.h */; };
                BC29935C17A1DD5800BCE880 /* ColorInputType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ColorInputType.cpp; sourceTree = "<group>"; };
                BC2CBF4B140F1A65003879BE /* JSWebGLContextEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWebGLContextEvent.h; sourceTree = "<group>"; };
                BC2CBF7A140F1D58003879BE /* JSWebGLContextEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWebGLContextEvent.cpp; sourceTree = "<group>"; };
+               BC2CC8DE0F32881000A9DF26 /* RenderObjectChildList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderObjectChildList.h; sourceTree = "<group>"; };
                BC2ED5540C6B9BD300920BFF /* JSElementCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSElementCustom.cpp; sourceTree = "<group>"; };
                BC2ED6BB0C6BD2F000920BFF /* JSAttrCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSAttrCustom.cpp; sourceTree = "<group>"; };
                BC2ED7A40C6C0F3600920BFF /* JSHTMLFrameElementCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLFrameElementCustom.cpp; sourceTree = "<group>"; };
                BC60DA5A0D2A31F700B9918F /* XPathException.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = XPathException.idl; sourceTree = "<group>"; };
                BC60DB470D2A3D1E00B9918F /* JSXPathException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSXPathException.cpp; sourceTree = "<group>"; };
                BC60DB480D2A3D1E00B9918F /* JSXPathException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSXPathException.h; sourceTree = "<group>"; };
+               BC60EFB60F33A0E700812A93 /* RenderObjectChildList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderObjectChildList.cpp; sourceTree = "<group>"; };
                BC64640711D7F304006455B0 /* DOMStringMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DOMStringMap.cpp; sourceTree = "<group>"; };
                BC64640811D7F304006455B0 /* DOMStringMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMStringMap.h; sourceTree = "<group>"; };
                BC64641A11D7F416006455B0 /* DatasetDOMStringMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DatasetDOMStringMap.h; sourceTree = "<group>"; };
                                BC85F23C151915E000BC17BE /* RenderNamedFlowThread.h */,
                                BCEA4840097D93020094C9E4 /* RenderObject.cpp */,
                                BCEA4841097D93020094C9E4 /* RenderObject.h */,
+                               BC60EFB60F33A0E700812A93 /* RenderObjectChildList.cpp */,
+                               BC2CC8DE0F32881000A9DF26 /* RenderObjectChildList.h */,
                                BCFA930710333193007B25D1 /* RenderOverflow.h */,
                                A43BF59A1149292800C643CA /* RenderProgress.cpp */,
                                A43BF59B1149292800C643CA /* RenderProgress.h */,
                                BCE32B9C1517C0B200F542EC /* RenderMultiColumnSet.h in Headers */,
                                BC85F23D151915E000BC17BE /* RenderNamedFlowThread.h in Headers */,
                                BCEA4880097D93020094C9E4 /* RenderObject.h in Headers */,
+                               BC2CC8DF0F32881000A9DF26 /* RenderObjectChildList.h in Headers */,
                                BCFA930810333193007B25D1 /* RenderOverflow.h in Headers */,
                                A43BF59D1149292800C643CA /* RenderProgress.h in Headers */,
                                5A574F25131DB93900471B88 /* RenderQuote.h in Headers */,
                                BCE32B9E1517C22700F542EC /* RenderMultiColumnSet.cpp in Sources */,
                                1A3FF9C315265359002288A1 /* RenderNamedFlowThread.cpp in Sources */,
                                BCEA487F097D93020094C9E4 /* RenderObject.cpp in Sources */,
+                               BC60EFB70F33A0E700812A93 /* RenderObjectChildList.cpp in Sources */,
                                A43BF59C1149292800C643CA /* RenderProgress.cpp in Sources */,
                                5A574F24131DB93900471B88 /* RenderQuote.cpp in Sources */,
                                B5B7A17017C10AA800E4AA0A /* ElementData.cpp in Sources */,
index cd11f25..6675e3f 100644 (file)
@@ -49,7 +49,7 @@ void AutoTableLayout::recalcColumn(unsigned effCol)
     RenderTableCell* fixedContributor = 0;
     RenderTableCell* maxContributor = 0;
 
-    for (RenderObject* child = m_table->firstChild(); child; child = child->nextSibling()) {
+    for (RenderObject* child = m_table->children()->firstChild(); child; child = child->nextSibling()) {
         if (child->isRenderTableCol()){
             // RenderTableCols don't have the concept of preferred logical width, but we need to clear their dirty bits
             // so that if we call setPreferredWidthsDirty(true) on a col or one of its descendants, we'll mark it's
@@ -65,7 +65,7 @@ void AutoTableLayout::recalcColumn(unsigned effCol)
                 if (current.inColSpan || !cell)
                     continue;
 
-                bool cellHasContent = cell->firstChild() || cell->style()->hasBorder() || cell->style()->hasPadding();
+                bool cellHasContent = cell->children()->firstChild() || cell->style()->hasBorder() || cell->style()->hasPadding();
                 if (cellHasContent)
                     columnLayout.emptyCellsOnly = false;
 
index fcb5cce..5bdf138 100644 (file)
@@ -84,6 +84,7 @@ using namespace HTMLNames;
 
 struct SameSizeAsRenderBlock : public RenderBox {
     void* pointers[2];
+    RenderObjectChildList children;
     RenderLineBoxList lineBoxes;
     uint32_t bitfields;
 };
@@ -212,7 +213,7 @@ void RenderBlock::willBeDestroyed()
 
     // Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will
     // properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise.
-    destroyLeftoverChildren();
+    children()->destroyLeftoverChildren();
 
     // Destroy our continuation before anything other than anonymous children.
     // The reason we don't destroy it before anonymous children is that they may
@@ -467,7 +468,7 @@ void RenderBlock::addChildToAnonymousColumnBlocks(RenderObject* newChild, Render
     if (!beforeChild) {
         // Create a new block of the correct type.
         RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock() : createAnonymousColumnsBlock();
-        insertChildInternal(newBox, nullptr, NotifyChildren);
+        children()->appendChildNode(this, newBox);
         newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0);
         return;
     }
@@ -490,7 +491,7 @@ void RenderBlock::addChildToAnonymousColumnBlocks(RenderObject* newChild, Render
     
     // Create a new anonymous box of the appropriate type.
     RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock() : createAnonymousColumnsBlock();
-    insertChildInternal(newBox, newBeforeChild, NotifyChildren);
+    children()->insertChildNode(this, newBox, newBeforeChild);
     newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0);
     return;
 }
@@ -607,7 +608,7 @@ void RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock,
     }
 
     // Now we are at the columns block level. We need to put the clone into the toBlock.
-    toBlock->insertChildInternal(cloneBlock, nullptr, NotifyChildren);
+    toBlock->children()->appendChildNode(toBlock, cloneBlock);
 
     // Now take all the children after currChild and remove them from the fromBlock
     // and put them in the toBlock.
@@ -642,9 +643,9 @@ void RenderBlock::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
 
     RenderObject* boxFirst = madeNewBeforeBlock ? block->firstChild() : pre->nextSibling();
     if (madeNewBeforeBlock)
-        block->insertChildInternal(pre, boxFirst, NotifyChildren);
-    block->insertChildInternal(newBlockBox, boxFirst, NotifyChildren);
-    block->insertChildInternal(post, boxFirst, NotifyChildren);
+        block->children()->insertChildNode(block, pre, boxFirst);
+    block->children()->insertChildNode(block, newBlockBox, boxFirst);
+    block->children()->insertChildNode(block, post, boxFirst);
     block->setChildrenInline(false);
     
     if (madeNewBeforeBlock)
@@ -694,10 +695,10 @@ void RenderBlock::makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, R
 
     RenderObject* boxFirst = block->firstChild();
     if (pre)
-        block->insertChildInternal(pre, boxFirst, NotifyChildren);
-    block->insertChildInternal(newBlockBox, boxFirst, NotifyChildren);
+        block->children()->insertChildNode(block, pre, boxFirst);
+    block->children()->insertChildNode(block, newBlockBox, boxFirst);
     if (post)
-        block->insertChildInternal(post, boxFirst, NotifyChildren);
+        block->children()->insertChildNode(block, post, boxFirst);
     block->setChildrenInline(false);
     
     // The pre/post blocks always have layers, so we know to always do a full insert/remove (so we pass true as the last argument).
@@ -1004,7 +1005,7 @@ void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
         child = inlineRunEnd->nextSibling();
 
         RenderBlock* block = createAnonymousBlock();
-        insertChildInternal(block, inlineRunStart, NotifyChildren);
+        children()->insertChildNode(this, block, inlineRunStart);
         moveChildrenTo(block, inlineRunStart, child);
     }
 
@@ -1024,8 +1025,8 @@ void RenderBlock::removeLeftoverAnonymousBlock(RenderBlock* child)
     if (child->continuation() || (child->firstChild() && (child->isAnonymousColumnSpanBlock() || child->isAnonymousColumnsBlock())))
         return;
     
-    RenderObject* firstAnChild = child->firstChild();
-    RenderObject* lastAnChild = child->lastChild();
+    RenderObject* firstAnChild = child->m_children.firstChild();
+    RenderObject* lastAnChild = child->m_children.lastChild();
     if (firstAnChild) {
         RenderObject* o = firstAnChild;
         while (o) {
@@ -1039,15 +1040,15 @@ void RenderBlock::removeLeftoverAnonymousBlock(RenderBlock* child)
         if (child->nextSibling())
             child->nextSibling()->setPreviousSibling(lastAnChild);
             
-        if (child == firstChild())
-            setFirstChild(firstAnChild);
-        if (child == lastChild())
-            setLastChild(lastAnChild);
+        if (child == m_children.firstChild())
+            m_children.setFirstChild(firstAnChild);
+        if (child == m_children.lastChild())
+            m_children.setLastChild(lastAnChild);
     } else {
-        if (child == firstChild())
-            setFirstChild(child->nextSibling());
-        if (child == lastChild())
-            setLastChild(child->previousSibling());
+        if (child == m_children.firstChild())
+            m_children.setFirstChild(child->nextSibling());
+        if (child == m_children.lastChild())
+            m_children.setLastChild(child->previousSibling());
 
         if (child->previousSibling())
             child->previousSibling()->setNextSibling(child->nextSibling());
@@ -1055,7 +1056,7 @@ void RenderBlock::removeLeftoverAnonymousBlock(RenderBlock* child)
             child->nextSibling()->setPreviousSibling(child->previousSibling());
     }
 
-    child->setFirstChild(0);
+    child->children()->setFirstChild(0);
     child->m_next = 0;
 
     // Remove all the information in the flow thread associated with the leftover anonymous block.
@@ -1093,7 +1094,7 @@ static bool canMergeContiguousAnonymousBlocks(RenderObject* oldChild, RenderObje
            && prev->isAnonymousColumnSpanBlock() == next->isAnonymousColumnSpanBlock();
 }
 
-void RenderBlock::collapseAnonymousBoxChild(RenderBlock* parent, RenderBlock* child)
+void RenderBlock::collapseAnonymousBoxChild(RenderBlock* parent, RenderObject* child)
 {
     parent->setNeedsLayoutAndPrefWidthsRecalc();
     parent->setChildrenInline(child->childrenInline());
@@ -1101,14 +1102,14 @@ void RenderBlock::collapseAnonymousBoxChild(RenderBlock* parent, RenderBlock* ch
 
     RenderFlowThread* childFlowThread = child->flowThreadContainingBlock();
     CurrentRenderFlowThreadMaintainer flowThreadMaintainer(childFlowThread);
-
-    parent->removeChildInternal(child, child->hasLayer() ? NotifyChildren : DontNotifyChildren);
-    child->moveAllChildrenTo(parent, nextSibling, child->hasLayer());
+    
+    RenderBlock* anonBlock = toRenderBlock(parent->children()->removeChildNode(parent, child, child->hasLayer()));
+    anonBlock->moveAllChildrenTo(parent, nextSibling, child->hasLayer());
     // Delete the now-empty block's lines and nuke it.
-    child->deleteLineBoxTree();
+    anonBlock->deleteLineBoxTree();
     if (childFlowThread && childFlowThread->isRenderNamedFlowThread())
-        toRenderNamedFlowThread(childFlowThread)->removeFlowChildInfo(child);
-    child->destroy();
+        toRenderNamedFlowThread(childFlowThread)->removeFlowChildInfo(anonBlock);
+    anonBlock->destroy();
 }
 
 void RenderBlock::moveAllChildrenIncludingFloatsTo(RenderBlock* toBlock, bool fullRemoveInsert)
@@ -1187,12 +1188,11 @@ void RenderBlock::removeChild(RenderObject* oldChild)
             // Cache this value as it might get changed in setStyle() call.
             bool inlineChildrenBlockHasLayer = inlineChildrenBlock->hasLayer();
             inlineChildrenBlock->setStyle(newStyle);
-            removeChildInternal(inlineChildrenBlock, inlineChildrenBlockHasLayer ? NotifyChildren : DontNotifyChildren);
+            children()->removeChildNode(this, inlineChildrenBlock, inlineChildrenBlockHasLayer);
             
             // Now just put the inlineChildrenBlock inside the blockChildrenBlock.
-            RenderObject* beforeChild = prev == inlineChildrenBlock ? blockChildrenBlock->firstChild() : nullptr;
-            blockChildrenBlock->insertChildInternal(inlineChildrenBlock, beforeChild,
-                (inlineChildrenBlockHasLayer || blockChildrenBlock->hasLayer()) ? NotifyChildren : DontNotifyChildren);
+            blockChildrenBlock->children()->insertChildNode(blockChildrenBlock, inlineChildrenBlock, prev == inlineChildrenBlock ? blockChildrenBlock->firstChild() : 0,
+                                                            inlineChildrenBlockHasLayer || blockChildrenBlock->hasLayer());
             next->setNeedsLayoutAndPrefWidthsRecalc();
             
             // inlineChildrenBlock got reparented to blockChildrenBlock, so it is no longer a child
@@ -1220,7 +1220,7 @@ void RenderBlock::removeChild(RenderObject* oldChild)
         // The removal has knocked us down to containing only a single anonymous
         // box.  We can go ahead and pull the content right back up into our
         // box.
-        collapseAnonymousBoxChild(this, toRenderBlock(child));
+        collapseAnonymousBoxChild(this, child);
     } else if (((prev && prev->isAnonymousBlock()) || (next && next->isAnonymousBlock())) && canCollapseAnonymousBlockChild()) {
         // It's possible that the removal has knocked us down to a single anonymous
         // block with pseudo-style element siblings (e.g. first-letter). If these
@@ -5845,7 +5845,7 @@ void RenderBlock::updateFirstLetterStyle(RenderObject* firstLetterBlock, RenderO
         }
         // To prevent removal of single anonymous block in RenderBlock::removeChild and causing
         // |nextSibling| to go stale, we remove the old first letter using removeChildNode first.
-        firstLetterContainer->removeChildInternal(firstLetter, NotifyChildren);
+        firstLetterContainer->children()->removeChildNode(firstLetterContainer, firstLetter);
         firstLetter->destroy();
         firstLetter = newFirstLetter;
         firstLetterContainer->addChild(firstLetter, nextSibling);
index 98ad3fa..67ab3b9 100644 (file)
@@ -104,6 +104,12 @@ protected:
 public:
     static RenderBlock* createAnonymous(Document&);
 
+    RenderObject* firstChild() const { return m_children.firstChild(); }
+    RenderObject* lastChild() const { return m_children.lastChild(); }
+
+    virtual const RenderObjectChildList* children() const OVERRIDE FINAL { return &m_children; }
+    virtual RenderObjectChildList* children() OVERRIDE FINAL { return &m_children; }
+
     bool beingDestroyed() const { return m_beingDestroyed; }
 
     // These two functions are overridden for inline-block.
@@ -286,7 +292,7 @@ public:
     RenderBlock* createAnonymousBlock(EDisplay display = BLOCK) const { return createAnonymousWithParentRendererAndDisplay(this, display); }
     RenderBlock* createAnonymousColumnsBlock() const { return createAnonymousColumnsWithParentRenderer(this); }
     RenderBlock* createAnonymousColumnSpanBlock() const { return createAnonymousColumnSpanWithParentRenderer(this); }
-    static void collapseAnonymousBoxChild(RenderBlock* parent, RenderBlock* child);
+    static void collapseAnonymousBoxChild(RenderBlock* parent, RenderObject* child);
 
     virtual RenderBox* createAnonymousBoxWithSameTypeAs(const RenderObject* parent) const OVERRIDE;
 
@@ -565,7 +571,6 @@ private:
 
     virtual bool isRenderBlock() const OVERRIDE FINAL { return true; }
     virtual bool isInlineBlockOrInlineTable() const OVERRIDE FINAL { return isInline() && isReplaced(); }
-    virtual bool canHaveChildren() const OVERRIDE { return true; }
 
     void makeChildrenNonInline(RenderObject* insertionPoint = 0);
     virtual void removeLeftoverAnonymousBlock(RenderBlock* child);
@@ -873,6 +878,7 @@ protected:
     OwnPtr<FloatingObjects> m_floatingObjects;
     OwnPtr<RenderBlockRareData> m_rareData;
 
+    RenderObjectChildList m_children;
     RenderLineBoxList m_lineBoxes;   // All of the root line boxes created for this block flow.  For example, <div>Hello<br>world.</div> will have two total lines for the <div>.
 
     mutable signed m_lineHeight : 27;
index af30119..668a8ab 100644 (file)
@@ -4644,7 +4644,7 @@ RenderObject* RenderBox::splitAnonymousBoxesAroundChild(RenderObject* beforeChil
             // so that the table repainting logic knows the structure is dirty.
             // See for example RenderTableCell:clippedOverflowRectForRepaint.
             markBoxForRelayoutAfterSplit(parentBox);
-            parentBox->insertChildInternal(postBox, boxToSplit->nextSibling(), NotifyChildren);
+            parentBox->children()->insertChildNode(parentBox, postBox, boxToSplit->nextSibling());
             boxToSplit->moveChildrenTo(postBox, beforeChild, 0, true);
 
             markBoxForRelayoutAfterSplit(boxToSplit);
index 3237d1c..618fadd 100644 (file)
@@ -2781,13 +2781,9 @@ void RenderBoxModelObject::moveChildTo(RenderBoxModelObject* toBoxModelObject, R
     if (fullRemoveInsert && (toBoxModelObject->isRenderBlock() || toBoxModelObject->isRenderInline())) {
         // Takes care of adding the new child correctly if toBlock and fromBlock
         // have different kind of children (block vs inline).
-        removeChildInternal(child, NotifyChildren);
-        toBoxModelObject->addChild(child, beforeChild);
-    } else {
-        NotifyChildrenType notifyType = fullRemoveInsert ? NotifyChildren : DontNotifyChildren;
-        removeChildInternal(child, notifyType);
-        toBoxModelObject->insertChildInternal(child, beforeChild, notifyType);
-    }
+        toBoxModelObject->addChild(children()->removeChildNode(this, child), beforeChild);
+    } else
+        toBoxModelObject->children()->insertChildNode(toBoxModelObject, children()->removeChildNode(this, child, fullRemoveInsert), beforeChild, fullRemoveInsert);
 }
 
 void RenderBoxModelObject::moveChildrenTo(RenderBoxModelObject* toBoxModelObject, RenderObject* startChild, RenderObject* endChild, RenderObject* beforeChild, bool fullRemoveInsert)
index f7019da..cffec15 100644 (file)
 #include "config.h"
 #include "RenderElement.h"
 
-#include "AXObjectCache.h"
 #include "ContentData.h"
-#include "RenderCounter.h"
 #include "RenderDeprecatedFlexibleBox.h"
 #include "RenderFlexibleBox.h"
 #include "RenderGrid.h"
 #include "RenderImage.h"
 #include "RenderImageResourceStyleImage.h"
 #include "RenderLayer.h"
-#include "RenderLineBreak.h"
 #include "RenderListItem.h"
 #include "RenderMultiColumnBlock.h"
 #include "RenderRegion.h"
 #include "RenderTableCol.h"
 #include "RenderTableRow.h"
 #include "RenderText.h"
-#include "RenderView.h"
 #include "SVGRenderSupport.h"
 
 namespace WebCore {
 
 RenderElement::RenderElement(Element* element)
     : RenderObject(element)
-    , m_firstChild(nullptr)
-    , m_lastChild(nullptr)
 {
 }
 
@@ -142,6 +136,9 @@ RenderElement* RenderElement::createFor(Element& element, RenderStyle& style)
 
 void RenderElement::addChild(RenderObject* newChild, RenderObject* beforeChild)
 {
+    ASSERT(children());
+    RenderObjectChildList& children = *this->children();
+
     bool needsTable = false;
 
     if (newChild->isRenderTableCol()) {
@@ -159,7 +156,7 @@ void RenderElement::addChild(RenderObject* newChild, RenderObject* beforeChild)
 
     if (needsTable) {
         RenderTable* table;
-        RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : m_lastChild;
+        RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : children.lastChild();
         if (afterChild && afterChild->isAnonymous() && afterChild->isTable() && !afterChild->isBeforeContent())
             table = toRenderTable(afterChild);
         else {
@@ -168,7 +165,7 @@ void RenderElement::addChild(RenderObject* newChild, RenderObject* beforeChild)
         }
         table->addChild(newChild);
     } else
-        insertChildInternal(newChild, beforeChild, NotifyChildren);
+        children.insertChildNode(this, newChild, beforeChild);
 
     if (newChild->isText() && newChild->style()->textTransform() == CAPITALIZE)
         toRenderText(newChild)->transformText();
@@ -191,139 +188,8 @@ void RenderElement::addChild(RenderObject* newChild, RenderObject* beforeChild)
 
 void RenderElement::removeChild(RenderObject* oldChild)
 {
-    removeChildInternal(oldChild, NotifyChildren);
-}
-
-void RenderElement::destroyLeftoverChildren()
-{
-    while (firstChild()) {
-        if (firstChild()->isListMarker() || (firstChild()->style()->styleType() == FIRST_LETTER && !firstChild()->isText()))
-            firstChild()->removeFromParent(); // List markers are owned by their enclosing list and so don't get destroyed by this container. Similarly, first letters are destroyed by their remaining text fragment.
-        else if (firstChild()->isRunIn() && firstChild()->node()) {
-            firstChild()->node()->setRenderer(0);
-            firstChild()->node()->setNeedsStyleRecalc();
-            firstChild()->destroy();
-        } else {
-            // Destroy any anonymous children remaining in the render tree, as well as implicit (shadow) DOM elements like those used in the engine-based text fields.
-            if (firstChild()->node())
-                firstChild()->node()->setRenderer(0);
-            firstChild()->destroy();
-        }
-    }
-}
-
-void RenderElement::insertChildInternal(RenderObject* newChild, RenderObject* beforeChild, NotifyChildrenType notifyChildren)
-{
-    ASSERT(canHaveChildren());
-    ASSERT(!newChild->parent());
-    ASSERT(!isRenderBlockFlow() || (!newChild->isTableSection() && !newChild->isTableRow() && !newChild->isTableCell()));
-
-    while (beforeChild && beforeChild->parent() && beforeChild->parent() != this)
-        beforeChild = beforeChild->parent();
-
-    // This should never happen, but if it does prevent render tree corruption
-    // where child->parent() ends up being owner but child->nextSibling()->parent()
-    // is not owner.
-    if (beforeChild && beforeChild->parent() != this) {
-        ASSERT_NOT_REACHED();
-        return;
-    }
-
-    newChild->setParent(this);
-
-    if (m_firstChild == beforeChild)
-        m_firstChild = newChild;
-
-    if (beforeChild) {
-        RenderObject* previousSibling = beforeChild->previousSibling();
-        if (previousSibling)
-            previousSibling->setNextSibling(newChild);
-        newChild->setPreviousSibling(previousSibling);
-        newChild->setNextSibling(beforeChild);
-        beforeChild->setPreviousSibling(newChild);
-    } else {
-        if (lastChild())
-            lastChild()->setNextSibling(newChild);
-        newChild->setPreviousSibling(lastChild());
-        m_lastChild = newChild;
-    }
-
-    if (!documentBeingDestroyed()) {
-        if (notifyChildren == NotifyChildren)
-            newChild->insertedIntoTree();
-        RenderCounter::rendererSubtreeAttached(newChild);
-    }
-
-    newChild->setNeedsLayoutAndPrefWidthsRecalc();
-    setPreferredLogicalWidthsDirty(true);
-    if (!normalChildNeedsLayout())
-        setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child.
-
-    if (AXObjectCache* cache = document().axObjectCache())
-        cache->childrenChanged(this);
-}
-
-void RenderElement::removeChildInternal(RenderObject* oldChild, NotifyChildrenType notifyChildren)
-{
-    ASSERT(canHaveChildren());
-    ASSERT(oldChild->parent() == this);
-
-    if (oldChild->isFloatingOrOutOfFlowPositioned())
-        toRenderBox(oldChild)->removeFloatingOrPositionedChildFromBlockLists();
-
-    // So that we'll get the appropriate dirty bit set (either that a normal flow child got yanked or
-    // that a positioned child got yanked). We also repaint, so that the area exposed when the child
-    // disappears gets repainted properly.
-    if (!documentBeingDestroyed() && notifyChildren == NotifyChildren && oldChild->everHadLayout()) {
-        oldChild->setNeedsLayoutAndPrefWidthsRecalc();
-        // We only repaint |oldChild| if we have a RenderLayer as its visual overflow may not be tracked by its parent.
-        if (oldChild->isBody())
-            view().repaintRootContents();
-        else
-            oldChild->repaint();
-    }
-
-    // If we have a line box wrapper, delete it.
-    if (oldChild->isBox())
-        toRenderBox(oldChild)->deleteLineBoxWrapper();
-    else if (oldChild->isLineBreak())
-        toRenderLineBreak(oldChild)->deleteInlineBoxWrapper();
-
-    // If oldChild is the start or end of the selection, then clear the selection to
-    // avoid problems of invalid pointers.
-    // FIXME: The FrameSelection should be responsible for this when it
-    // is notified of DOM mutations.
-    if (!documentBeingDestroyed() && oldChild->isSelectionBorder())
-        view().clearSelection();
-
-    if (!documentBeingDestroyed() && notifyChildren == NotifyChildren)
-        oldChild->willBeRemovedFromTree();
-
-    // WARNING: There should be no code running between willBeRemovedFromTree and the actual removal below.
-    // This is needed to avoid race conditions where willBeRemovedFromTree would dirty the tree's structure
-    // and the code running here would force an untimely rebuilding, leaving |oldChild| dangling.
-
-    if (oldChild->previousSibling())
-        oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());
-    if (oldChild->nextSibling())
-        oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling());
-
-    if (m_firstChild == oldChild)
-        m_firstChild = oldChild->nextSibling();
-    if (m_lastChild == oldChild)
-        m_lastChild = oldChild->previousSibling();
-
-    oldChild->setPreviousSibling(0);
-    oldChild->setNextSibling(0);
-    oldChild->setParent(0);
-
-    // rendererRemovedFromTree walks the whole subtree. We can improve performance
-    // by skipping this step when destroying the entire tree.
-    if (!documentBeingDestroyed())
-        RenderCounter::rendererRemovedFromTree(oldChild);
-
-    if (AXObjectCache* cache = document().existingAXObjectCache())
-        cache->childrenChanged(this);
+    ASSERT(children());
+    children()->removeChildNode(this, oldChild);
 }
 
 static void addLayers(RenderObject* obj, RenderLayer* parentLayer, RenderElement*& newObject, RenderLayer*& beforeChild)
@@ -480,11 +346,5 @@ void RenderElement::willBeRemovedFromTree()
     RenderObject::willBeRemovedFromTree();
 }
 
-void RenderElement::willBeDestroyed()
-{
-    destroyLeftoverChildren();
-
-    RenderObject::willBeDestroyed();
-}
 
 }
index bb9b033..bef6fa5 100644 (file)
@@ -38,9 +38,6 @@ public:
     Element* nonPseudoElement() const { return toElement(RenderObject::nonPseudoNode()); }
     Element* generatingElement() const { return toElement(RenderObject::generatingNode()); }
 
-    virtual RenderObject* firstChild() const FINAL { return m_firstChild; }
-    virtual RenderObject* lastChild() const FINAL { return m_lastChild; }
-
     virtual bool isChildAllowed(RenderObject*, RenderStyle*) const { return true; }
     virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0);
     virtual void addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild = 0) { return addChild(newChild, beforeChild); }
@@ -54,10 +51,6 @@ public:
     void moveLayers(RenderLayer* oldParent, RenderLayer* newParent);
     RenderLayer* findNextLayer(RenderLayer* parentLayer, RenderObject* startPoint, bool checkParent = true);
 
-    enum NotifyChildrenType { NotifyChildren, DontNotifyChildren };
-    void insertChildInternal(RenderObject*, RenderObject* beforeChild, NotifyChildrenType);
-    void removeChildInternal(RenderObject*, NotifyChildrenType);
-
 protected:
     explicit RenderElement(Element*);
 
@@ -66,22 +59,14 @@ protected:
     LayoutUnit valueForLength(const Length&, LayoutUnit maximumValue, bool roundPercentages = false) const;
     LayoutUnit minimumValueForLength(const Length&, LayoutUnit maximumValue, bool roundPercentages = false) const;
 
-    void setFirstChild(RenderObject* child) { m_firstChild = child; }
-    void setLastChild(RenderObject* child) { m_lastChild = child; }
-    void destroyLeftoverChildren();
-
     virtual void insertedIntoTree() OVERRIDE;
     virtual void willBeRemovedFromTree() OVERRIDE;
-    virtual void willBeDestroyed() OVERRIDE;
 
 private:
     void node() const WTF_DELETED_FUNCTION;
     void nonPseudoNode() const WTF_DELETED_FUNCTION;
     void generatingNode() const WTF_DELETED_FUNCTION;
     void isText() const WTF_DELETED_FUNCTION;
-
-    RenderObject* m_firstChild;
-    RenderObject* m_lastChild;
 };
 
 inline LayoutUnit RenderElement::valueForLength(const Length& length, LayoutUnit maximumValue, bool roundPercentages) const
index 57d7ffc..3d15068 100644 (file)
@@ -494,7 +494,7 @@ void RenderEmbeddedObject::layout()
         return;
 
     // This code copied from RenderMedia::layout().
-    RenderObject* child = firstChild();
+    RenderObject* child = m_children.firstChild();
 
     if (!child)
         return;
index b6e4419..4138b1d 100644 (file)
@@ -72,6 +72,9 @@ protected:
 
     virtual CursorDirective getCursor(const LayoutPoint&, Cursor&) const OVERRIDE;
 
+    virtual const RenderObjectChildList* children() const OVERRIDE FINAL { return &m_children; }
+    virtual RenderObjectChildList* children() OVERRIDE FINAL { return &m_children; }
+
 protected:
     virtual void layout() OVERRIDE;
 
@@ -100,6 +103,7 @@ private:
     LayoutRect unavailablePluginIndicatorBounds(const LayoutPoint&) const;
 
     virtual bool canHaveChildren() const OVERRIDE FINAL;
+    
     virtual bool canHaveWidget() const { return true; }
 
     bool m_hasFallbackContent; // FIXME: This belongs on HTMLObjectElement.
@@ -110,6 +114,7 @@ private:
     String m_unavailablePluginReplacementText;
     bool m_unavailablePluginIndicatorIsPressed;
     bool m_mouseDownWasInUnavailablePluginIndicator;
+    RenderObjectChildList m_children;
     String m_unavailabilityDescription;
 };
 
index d44faed..d595474 100644 (file)
@@ -60,6 +60,12 @@ public:
 
     HTMLFrameSetElement& frameSetElement() const;
 
+    RenderObject* firstChild() const { return m_children.firstChild(); }
+    RenderObject* lastChild() const { return m_children.lastChild(); }
+
+    virtual const RenderObjectChildList* children() const OVERRIDE { return &m_children; }
+    virtual RenderObjectChildList* children() OVERRIDE { return &m_children; }
+
     FrameEdgeInfo edgeInfo() const;
 
     bool userResize(MouseEvent*);
@@ -96,7 +102,6 @@ private:
 
     virtual void layout() OVERRIDE;
     virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE;
-    virtual bool canHaveChildren() const OVERRIDE { return true; }
     virtual bool isChildAllowed(RenderObject*, RenderStyle*) const OVERRIDE;
     virtual CursorDirective getCursor(const LayoutPoint&, Cursor&) const OVERRIDE;
 
@@ -119,6 +124,8 @@ private:
     void paintRowBorder(const PaintInfo&, const IntRect&);
     void paintColumnBorder(const PaintInfo&, const IntRect&);
 
+    RenderObjectChildList m_children;
+
     GridAxis m_rows;
     GridAxis m_cols;
 
index 8573434..c4f7c79 100644 (file)
@@ -81,7 +81,7 @@ void RenderInline::willBeDestroyed()
 
     // Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will
     // properly dirty line boxes that they are removed from.  Effects that do :before/:after only on hover could crash otherwise.
-    destroyLeftoverChildren();
+    children()->destroyLeftoverChildren();
 
     // Destroy our continuation before anything other than anonymous children.
     // The reason we don't destroy it before anonymous children is that they may
@@ -366,8 +366,7 @@ void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
     while (o) {
         RenderObject* tmp = o;
         o = tmp->nextSibling();
-        removeChildInternal(tmp, NotifyChildren);
-        cloneInline->addChildIgnoringContinuation(tmp, 0);
+        cloneInline->addChildIgnoringContinuation(children()->removeChildNode(this, tmp), 0);
         tmp->setNeedsLayoutAndPrefWidthsRecalc();
     }
 
@@ -408,8 +407,7 @@ void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
             while (o) {
                 RenderObject* tmp = o;
                 o = tmp->nextSibling();
-                inlineCurr->removeChildInternal(tmp, NotifyChildren);
-                cloneInline->addChildIgnoringContinuation(tmp, 0);
+                cloneInline->addChildIgnoringContinuation(inlineCurr->children()->removeChildNode(curr, tmp), 0);
                 tmp->setNeedsLayoutAndPrefWidthsRecalc();
             }
         }
@@ -421,7 +419,7 @@ void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
     }
 
     // Now we are at the block level. We need to put the clone into the toBlock.
-    toBlock->insertChildInternal(cloneInline, nullptr, NotifyChildren);
+    toBlock->children()->appendChildNode(toBlock, cloneInline);
 
     // Now take all the children after currChild and remove them from the fromBlock
     // and put them in the toBlock.
@@ -429,8 +427,7 @@ void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
     while (o) {
         RenderObject* tmp = o;
         o = tmp->nextSibling();
-        fromBlock->removeChildInternal(tmp, NotifyChildren);
-        toBlock->insertChildInternal(tmp, nullptr, NotifyChildren);
+        toBlock->children()->appendChildNode(toBlock, fromBlock->children()->removeChildNode(fromBlock, tmp));
     }
 }
 
@@ -460,9 +457,9 @@ void RenderInline::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox
 
     RenderObject* boxFirst = madeNewBeforeBlock ? block->firstChild() : pre->nextSibling();
     if (madeNewBeforeBlock)
-        block->insertChildInternal(pre, boxFirst, NotifyChildren);
-    block->insertChildInternal(newBlockBox, boxFirst, NotifyChildren);
-    block->insertChildInternal(post, boxFirst, NotifyChildren);
+        block->children()->insertChildNode(block, pre, boxFirst);
+    block->children()->insertChildNode(block, newBlockBox, boxFirst);
+    block->children()->insertChildNode(block, post, boxFirst);
     block->setChildrenInline(false);
     
     if (madeNewBeforeBlock) {
@@ -470,8 +467,7 @@ void RenderInline::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox
         while (o) {
             RenderObject* no = o;
             o = no->nextSibling();
-            block->removeChildInternal(no, NotifyChildren);
-            pre->insertChildInternal(no, nullptr, NotifyChildren);
+            pre->children()->appendChildNode(pre, block->children()->removeChildNode(block, no));
             no->setNeedsLayoutAndPrefWidthsRecalc();
         }
     }
@@ -1265,7 +1261,7 @@ void RenderInline::childBecameNonInline(RenderObject* child)
     RenderBoxModelObject* oldContinuation = continuation();
     setContinuation(newBox);
     RenderObject* beforeChild = child->nextSibling();
-    removeChildInternal(child, NotifyChildren);
+    children()->removeChildNode(this, child);
     splitFlow(beforeChild, newBox, child, oldContinuation);
 }
 
index 7e5f790..487b03e 100644 (file)
@@ -37,6 +37,9 @@ public:
 
     static RenderInline* createAnonymous(Document&);
 
+    RenderObject* firstChild() const { return m_children.firstChild(); }
+    RenderObject* lastChild() const { return m_children.lastChild(); }
+
     virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0) OVERRIDE;
 
     virtual LayoutUnit marginLeft() const OVERRIDE FINAL;
@@ -96,10 +99,12 @@ protected:
     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
 
 private:
+    virtual const RenderObjectChildList* children() const OVERRIDE FINAL { return &m_children; }
+    virtual RenderObjectChildList* children() OVERRIDE FINAL { return &m_children; }
+
     virtual const char* renderName() const OVERRIDE;
 
     virtual bool isRenderInline() const OVERRIDE FINAL { return true; }
-    virtual bool canHaveChildren() const OVERRIDE FINAL { return true; }
 
     LayoutRect culledInlineVisualOverflowBoundingBox() const;
     InlineBox* culledInlineFirstLineBox() const;
@@ -173,6 +178,7 @@ private:
                              const LayoutRect& nextLine, const Color);
     RenderBoxModelObject* continuationBefore(RenderObject* beforeChild);
 
+    RenderObjectChildList m_children;
     RenderLineBoxList m_lineBoxes;   // All of the line boxes created for this inline flow.  For example, <i>Hello<br>world.</i> will have two <i> line boxes.
 
     bool m_alwaysCreateLineBoxes : 1;
index 97353be..39f18ee 100644 (file)
@@ -81,7 +81,7 @@ void RenderLayerModelObject::willBeDestroyed()
     }
 
     // RenderObject::willBeDestroyed calls back to destroyLayer() for layer destruction
-    RenderElement::willBeDestroyed();
+    RenderObject::willBeDestroyed();
 }
 
 void RenderLayerModelObject::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
index dfc9c64..ad1c153 100644 (file)
@@ -54,8 +54,6 @@ public:
 private:
     void node() const WTF_DELETED_FUNCTION;
 
-    virtual bool canHaveChildren() const OVERRIDE { return false; }
-
     virtual VisiblePosition positionForPoint(const LayoutPoint&) OVERRIDE;
     virtual int caretMinOffset() const OVERRIDE;
     virtual int caretMaxOffset() const OVERRIDE;
index 0f97480..00011f1 100644 (file)
@@ -55,7 +55,6 @@ private:
     virtual void computePreferredLogicalWidths() OVERRIDE;
 
     virtual bool isListMarker() const { return true; }
-    virtual bool canHaveChildren() const OVERRIDE { return false; }
 
     virtual void paint(PaintInfo&, const LayoutPoint&);
 
index d38c5b2..f49baa4 100644 (file)
@@ -58,7 +58,7 @@ void RenderMedia::layout()
 
     RenderImage::layout();
 
-    RenderBox* controlsRenderer = toRenderBox(firstChild());
+    RenderBox* controlsRenderer = toRenderBox(m_children.firstChild());
     if (!controlsRenderer)
         return;
 
index 4c847a9..93c8764 100644 (file)
@@ -41,6 +41,12 @@ public:
 
     HTMLMediaElement& mediaElement() const { return toHTMLMediaElement(nodeForNonAnonymous()); }
 
+    RenderObject* firstChild() const { return m_children.firstChild(); }
+    RenderObject* lastChild() const { return m_children.lastChild(); }
+
+    virtual const RenderObjectChildList* children() const OVERRIDE FINAL { return &m_children; }
+    virtual RenderObjectChildList* children() OVERRIDE FINAL { return &m_children; }
+
 protected:
     virtual void layout();
 
@@ -55,6 +61,8 @@ private:
     virtual void paintReplaced(PaintInfo&, const LayoutPoint&) OVERRIDE;
 
     virtual bool requiresForcedStyleRecalcPropagation() const OVERRIDE FINAL { return true; }
+
+    RenderObjectChildList m_children;
 };
 
 inline RenderMedia* toRenderMedia(RenderObject* object)
index a86733f..f77f5ec 100644 (file)
@@ -1663,9 +1663,9 @@ void RenderObject::handleDynamicFloatPositionChange()
         else {
             // An anonymous block must be made to wrap this inline.
             RenderBlock* block = toRenderBlock(parent())->createAnonymousBlock();
-            parent()->insertChildInternal(block, this, RenderElement::NotifyChildren);
-            parent()->removeChildInternal(this, RenderElement::NotifyChildren);
-            block->insertChildInternal(this, nullptr, RenderElement::NotifyChildren);
+            RenderObjectChildList* childlist = parent()->children();
+            childlist->insertChildNode(parent(), block, this);
+            block->children()->appendChildNode(block, childlist->removeChildNode(parent(), this));
         }
     }
 }
@@ -2410,6 +2410,11 @@ inline void RenderObject::clearLayoutRootIfNeeded() const
 
 void RenderObject::willBeDestroyed()
 {
+    // Destroy any leftover anonymous children.
+    RenderObjectChildList* children = this->children();
+    if (children)
+        children->destroyLeftoverChildren();
+
     // If this renderer is being autoscrolled, stop the autoscroll timer
     
     // FIXME: RenderObject::destroy should not get called with a renderer whose document
@@ -2515,9 +2520,11 @@ void RenderObject::removeFromRenderFlowThread()
 
 void RenderObject::removeFromRenderFlowThreadRecursive(RenderFlowThread* renderFlowThread)
 {
-    for (RenderObject* child = firstChild(); child; child = child->nextSibling())
-        child->removeFromRenderFlowThreadRecursive(renderFlowThread);
-
+    if (const RenderObjectChildList* children = this->children()) {
+        for (RenderObject* child = children->firstChild(); child; child = child->nextSibling())
+            child->removeFromRenderFlowThreadRecursive(renderFlowThread);
+    }
+    
     RenderFlowThread* localFlowThread = renderFlowThread;
     if (flowThreadState() == InsideInFlowThread)
         localFlowThread = flowThreadContainingBlock(); // We have to ask. We can't just assume we are in the same flow thread.
index 9aba921..8069240 100644 (file)
@@ -32,6 +32,7 @@
 #include "FloatQuad.h"
 #include "LayoutRect.h"
 #include "PaintPhase.h"
+#include "RenderObjectChildList.h"
 #include "RenderStyle.h"
 #include "ScrollBehavior.h"
 #include "StyleInheritedData.h"
@@ -146,8 +147,8 @@ const int showTreeCharacterOffset = 39;
 class RenderObject : public CachedImageClient {
     friend class RenderBlock;
     friend class RenderBlockFlow;
-    friend class RenderElement;
     friend class RenderLayer;
+    friend class RenderObjectChildList;
 public:
     // Anonymous objects should pass the document as their node, and they will then automatically be
     // marked as anonymous in the constructor.
@@ -165,9 +166,25 @@ public:
     RenderObject* nextSibling() const { return m_next; }
 
     // FIXME: These should be renamed slowFirstChild, slowLastChild, etc.
-    // to discourage their use.
-    virtual RenderObject* firstChild() const { return nullptr; }
-    virtual RenderObject* lastChild() const { return nullptr; }
+    // to discourage their use. The virtual call to children inside these
+    // can be slow for hot code paths.
+    // Derived classes like RenderBlock override these non-virtual
+    // functions to make them fast when we already have a more specific pointer type.
+    RenderObject* firstChild() const
+    {
+        if (const RenderObjectChildList* children = this->children())
+            return children->firstChild();
+        return 0;
+    }
+    RenderObject* lastChild() const
+    {
+        if (const RenderObjectChildList* children = this->children())
+            return children->lastChild();
+        return 0;
+    }
+
+    virtual RenderObjectChildList* children() { return 0; }
+    virtual const RenderObjectChildList* children() const { return 0; }
 
     RenderObject* nextInPreOrder() const;
     RenderObject* nextInPreOrder(const RenderObject* stayWithin) const;
@@ -253,7 +270,7 @@ public:
     
     // RenderObject tree manipulation
     //////////////////////////////////////////
-    virtual bool canHaveChildren() const = 0;
+    virtual bool canHaveChildren() const { return children(); }
     virtual bool canHaveGeneratedChildren() const;
     virtual bool createsAnonymousWrapper() const { return false; }
     //////////////////////////////////////////
diff --git a/Source/WebCore/rendering/RenderObjectChildList.cpp b/Source/WebCore/rendering/RenderObjectChildList.cpp
new file mode 100644 (file)
index 0000000..1963ca1
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) Research In Motion Limited 2010. 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 COMPUTER, INC. ``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 COMPUTER, INC. OR
+ * 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 "RenderObjectChildList.h"
+
+#include "AXObjectCache.h"
+#include "RenderCounter.h"
+#include "RenderElement.h"
+#include "RenderLineBreak.h"
+#include "RenderStyle.h"
+#include "RenderView.h"
+
+namespace WebCore {
+
+void RenderObjectChildList::destroyLeftoverChildren()
+{
+    while (firstChild()) {
+        if (firstChild()->isListMarker() || (firstChild()->style()->styleType() == FIRST_LETTER && !firstChild()->isText()))
+            firstChild()->removeFromParent(); // List markers are owned by their enclosing list and so don't get destroyed by this container. Similarly, first letters are destroyed by their remaining text fragment.
+        else if (firstChild()->isRunIn() && firstChild()->node()) {
+            firstChild()->node()->setRenderer(0);
+            firstChild()->node()->setNeedsStyleRecalc();
+            firstChild()->destroy();
+        } else {
+            // Destroy any anonymous children remaining in the render tree, as well as implicit (shadow) DOM elements like those used in the engine-based text fields.
+            if (firstChild()->node())
+                firstChild()->node()->setRenderer(0);
+            firstChild()->destroy();
+        }
+    }
+}
+
+RenderObject* RenderObjectChildList::removeChildNode(RenderElement* owner, RenderObject* oldChild, bool notifyRenderer)
+{
+    ASSERT(oldChild->parent() == owner);
+
+    if (oldChild->isFloatingOrOutOfFlowPositioned())
+        toRenderBox(oldChild)->removeFloatingOrPositionedChildFromBlockLists();
+
+    // So that we'll get the appropriate dirty bit set (either that a normal flow child got yanked or
+    // that a positioned child got yanked). We also repaint, so that the area exposed when the child
+    // disappears gets repainted properly.
+    if (!owner->documentBeingDestroyed() && notifyRenderer && oldChild->everHadLayout()) {
+        oldChild->setNeedsLayoutAndPrefWidthsRecalc();
+        // We only repaint |oldChild| if we have a RenderLayer as its visual overflow may not be tracked by its parent.
+        if (oldChild->isBody())
+            owner->view().repaintRootContents();
+        else
+            oldChild->repaint();
+    }
+
+    // If we have a line box wrapper, delete it.
+    if (oldChild->isBox())
+        toRenderBox(oldChild)->deleteLineBoxWrapper();
+    else if (oldChild->isLineBreak())
+        toRenderLineBreak(oldChild)->deleteInlineBoxWrapper();
+
+    // If oldChild is the start or end of the selection, then clear the selection to
+    // avoid problems of invalid pointers.
+    // FIXME: The FrameSelection should be responsible for this when it
+    // is notified of DOM mutations.
+    if (!owner->documentBeingDestroyed() && oldChild->isSelectionBorder())
+        owner->view().clearSelection();
+
+    if (!owner->documentBeingDestroyed() && notifyRenderer)
+        oldChild->willBeRemovedFromTree();
+
+    // WARNING: There should be no code running between willBeRemovedFromTree and the actual removal below.
+    // This is needed to avoid race conditions where willBeRemovedFromTree would dirty the tree's structure
+    // and the code running here would force an untimely rebuilding, leaving |oldChild| dangling.
+
+    if (oldChild->previousSibling())
+        oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());
+    if (oldChild->nextSibling())
+        oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling());
+
+    if (firstChild() == oldChild)
+        setFirstChild(oldChild->nextSibling());
+    if (lastChild() == oldChild)
+        setLastChild(oldChild->previousSibling());
+
+    oldChild->setPreviousSibling(0);
+    oldChild->setNextSibling(0);
+    oldChild->setParent(0);
+
+    // rendererRemovedFromTree walks the whole subtree. We can improve performance
+    // by skipping this step when destroying the entire tree.
+    if (!owner->documentBeingDestroyed())
+        RenderCounter::rendererRemovedFromTree(oldChild);
+
+    if (AXObjectCache* cache = owner->document().existingAXObjectCache())
+        cache->childrenChanged(owner);
+
+    return oldChild;
+}
+
+void RenderObjectChildList::insertChildNode(RenderElement* owner, RenderObject* newChild, RenderObject* beforeChild, bool notifyRenderer)
+{
+    ASSERT(!newChild->parent());
+    ASSERT(!owner->isRenderBlockFlow() || (!newChild->isTableSection() && !newChild->isTableRow() && !newChild->isTableCell()));
+
+    while (beforeChild && beforeChild->parent() && beforeChild->parent() != owner)
+        beforeChild = beforeChild->parent();
+
+    // This should never happen, but if it does prevent render tree corruption
+    // where child->parent() ends up being owner but child->nextSibling()->parent()
+    // is not owner.
+    if (beforeChild && beforeChild->parent() != owner) {
+        ASSERT_NOT_REACHED();
+        return;
+    }
+
+    newChild->setParent(owner);
+
+    if (firstChild() == beforeChild)
+        setFirstChild(newChild);
+
+    if (beforeChild) {
+        RenderObject* previousSibling = beforeChild->previousSibling();
+        if (previousSibling)
+            previousSibling->setNextSibling(newChild);
+        newChild->setPreviousSibling(previousSibling);
+        newChild->setNextSibling(beforeChild);
+        beforeChild->setPreviousSibling(newChild);
+    } else {
+        if (lastChild())
+            lastChild()->setNextSibling(newChild);
+        newChild->setPreviousSibling(lastChild());
+        setLastChild(newChild);
+    }
+
+    if (!owner->documentBeingDestroyed() && notifyRenderer)
+        newChild->insertedIntoTree();
+
+    if (!owner->documentBeingDestroyed()) {
+        RenderCounter::rendererSubtreeAttached(newChild);
+    }
+
+    newChild->setNeedsLayoutAndPrefWidthsRecalc();
+    owner->setPreferredLogicalWidthsDirty(true);
+    if (!owner->normalChildNeedsLayout())
+        owner->setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child.
+
+    if (AXObjectCache* cache = owner->document().axObjectCache())
+        cache->childrenChanged(owner);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/rendering/RenderObjectChildList.h b/Source/WebCore/rendering/RenderObjectChildList.h
new file mode 100644 (file)
index 0000000..65c9ff1
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2009 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 COMPUTER, INC. ``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 COMPUTER, INC. OR
+ * 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. 
+ */
+
+#ifndef RenderObjectChildList_h
+#define RenderObjectChildList_h
+
+#include <wtf/Forward.h>
+
+namespace WebCore {
+
+class RenderElement;
+class RenderObject;
+
+class RenderObjectChildList {
+public:
+    RenderObjectChildList()
+        : m_firstChild(0)
+        , m_lastChild(0)
+    {
+    }
+
+    RenderObject* firstChild() const { return m_firstChild; }
+    RenderObject* lastChild() const { return m_lastChild; }
+
+    // FIXME: Temporary while RenderBox still exists. Eventually this will just happen during insert/append/remove methods on the child list, and nobody
+    // will need to manipulate firstChild or lastChild directly.
+    void setFirstChild(RenderObject* child) { m_firstChild = child; }
+    void setLastChild(RenderObject* child) { m_lastChild = child; }
+
+    void destroyLeftoverChildren();
+
+    RenderObject* removeChildNode(RenderElement* owner, RenderObject*, bool notifyRenderer = true);
+    void insertChildNode(RenderElement* owner, RenderObject* newChild, RenderObject* beforeChild, bool notifyRenderer = true);
+    void appendChildNode(RenderElement* owner, RenderObject* newChild, bool notifyRenderer = true)
+    {
+        insertChildNode(owner, newChild, 0, notifyRenderer);
+    }
+
+private:
+    RenderObject* m_firstChild;
+    RenderObject* m_lastChild;
+};
+
+} // namespace WebCore
+
+#endif // RenderObjectChildList_h
index 960d7b1..5bdd0bc 100644 (file)
@@ -72,7 +72,7 @@ private:
     virtual RenderBox* embeddedContentBox() const { return 0; }
     virtual const char* renderName() const OVERRIDE { return "RenderReplaced"; }
 
-    virtual bool canHaveChildren() const OVERRIDE { return false; }
+    virtual bool canHaveChildren() const { return false; }
 
     virtual void computePreferredLogicalWidths() OVERRIDE FINAL;
     virtual void paintReplaced(PaintInfo&, const LayoutPoint&) { }
index ad407c4..217a8cb 100644 (file)
@@ -50,9 +50,8 @@ public:
 private:
     RenderReplica();
 
-    virtual bool isReplica() const OVERRIDE { return true; }
-    virtual bool canHaveChildren() const OVERRIDE { return false; }
-    virtual void computePreferredLogicalWidths() OVERRIDE;
+    virtual bool isReplica() const { return true; }
+    virtual void computePreferredLogicalWidths();
 
 };
 
index 8557762..f01dcf3 100644 (file)
@@ -98,7 +98,7 @@ void RenderRubyBase::moveInlineChildren(RenderRubyBase* toBase, RenderObject* be
             toBlock = toRenderBlock(lastChild);
         else {
             toBlock = toBase->createAnonymousBlock();
-            toBase->insertChildInternal(toBlock, nullptr, NotifyChildren);
+            toBase->children()->appendChildNode(toBase, toBlock);
         }
     }
     // Move our inline children into the target block we determined above.
@@ -123,7 +123,7 @@ void RenderRubyBase::moveBlockChildren(RenderRubyBase* toBase, RenderObject* bef
             && lastChildThere && lastChildThere->isAnonymousBlock() && lastChildThere->childrenInline()) {            
         RenderBlock* anonBlockHere = toRenderBlock(firstChildHere);
         RenderBlock* anonBlockThere = toRenderBlock(lastChildThere);
-        anonBlockHere->moveAllChildrenTo(anonBlockThere, true);
+        anonBlockHere->moveAllChildrenTo(anonBlockThere, anonBlockThere->children());
         anonBlockHere->deleteLineBoxTree();
         anonBlockHere->destroy();
     }
index e810090..764ede6 100644 (file)
@@ -38,6 +38,12 @@ public:
     explicit RenderTableCol(Element&);
     Element& element() const { return toElement(nodeForNonAnonymous()); }
 
+    RenderObject* firstChild() const { return m_children.firstChild(); }
+    RenderObject* lastChild() const { return m_children.lastChild(); }
+
+    virtual const RenderObjectChildList* children() const OVERRIDE { return &m_children; }
+    virtual RenderObjectChildList* children() OVERRIDE { return &m_children; }
+
     void clearPreferredLogicalWidthsDirtyBits();
 
     unsigned span() const { return m_span; }
@@ -91,6 +97,7 @@ private:
 
     RenderTable* table() const;
 
+    RenderObjectChildList m_children;
     unsigned m_span;
 };
 
index fe484f7..a9f2883 100644 (file)
@@ -36,6 +36,12 @@ class RenderTableRow FINAL : public RenderBox {
 public:
     explicit RenderTableRow(Element*);
 
+    RenderObject* firstChild() const { return m_children.firstChild(); }
+    RenderObject* lastChild() const { return m_children.lastChild(); }
+
+    virtual const RenderObjectChildList* children() const OVERRIDE { return &m_children; }
+    virtual RenderObjectChildList* children() OVERRIDE { return &m_children; }
+
     RenderTableSection* section() const { return toRenderTableSection(parent()); }
     RenderTable* table() const { return toRenderTable(parent()->parent()); }
 
@@ -89,7 +95,6 @@ private:
 
     virtual bool isTableRow() const OVERRIDE { return true; }
 
-    virtual bool canHaveChildren() const OVERRIDE { return true; }
     virtual void willBeRemovedFromTree() OVERRIDE;
 
     virtual void layout() OVERRIDE;
@@ -104,6 +109,7 @@ private:
 
     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
 
+    RenderObjectChildList m_children;
     unsigned m_rowIndex : 31;
 };
 
index f74897b..98c465e 100644 (file)
@@ -65,6 +65,12 @@ public:
     explicit RenderTableSection(Element*);
     virtual ~RenderTableSection();
 
+    RenderObject* firstChild() const { return m_children.firstChild(); }
+    RenderObject* lastChild() const { return m_children.lastChild(); }
+
+    virtual const RenderObjectChildList* children() const OVERRIDE { return &m_children; }
+    virtual RenderObjectChildList* children() OVERRIDE { return &m_children; }
+
     virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0) OVERRIDE;
 
     virtual int firstLineBoxBaseline() const OVERRIDE;
@@ -198,8 +204,6 @@ protected:
 private:
     virtual const char* renderName() const OVERRIDE { return (isAnonymous() || isPseudoElement()) ? "RenderTableSection (anonymous)" : "RenderTableSection"; }
 
-    virtual bool canHaveChildren() const OVERRIDE { return true; }
-
     virtual bool isTableSection() const OVERRIDE { return true; }
 
     virtual void willBeRemovedFromTree() OVERRIDE;
@@ -238,6 +242,8 @@ private:
 
     void setLogicalPositionForCell(RenderTableCell*, unsigned effectiveColumn) const;
 
+    RenderObjectChildList m_children;
+
     Vector<RowStruct> m_grid;
     Vector<int> m_rowPos;
 
index 8b5f3a7..217f45e 100644 (file)
@@ -158,8 +158,6 @@ protected:
     virtual InlineTextBox* createTextBox(); // Subclassed by SVG.
 
 private:
-    virtual bool canHaveChildren() const OVERRIDE FINAL { return false; }
-
     void computePreferredLogicalWidths(float leadWidth, HashSet<const SimpleFontData*>& fallbackFonts, GlyphOverflow&);
 
     bool computeCanUseSimpleFontCodePath() const;
index e94e7f6..31d35cf 100644 (file)
@@ -84,6 +84,7 @@
 #include "RenderMultiColumnFlowThread.cpp"
 #include "RenderMultiColumnSet.cpp"
 #include "RenderObject.cpp"
+#include "RenderObjectChildList.cpp"
 #include "RenderProgress.cpp"
 #include "RenderQuote.cpp"
 #include "RenderReplaced.cpp"
index a8cda5a..810fc54 100644 (file)
@@ -139,7 +139,7 @@ void RenderMathMLOperator::updateFromElement()
     RenderObject* savedRenderer = element()->renderer();
 
     // Destroy our current children
-    destroyLeftoverChildren();
+    children()->destroyLeftoverChildren();
 
     // Since we share a node with our children, destroying our children may set our node's
     // renderer to 0, so we need to restore it.
index 6c0808b..c3f5760 100644 (file)
@@ -35,6 +35,12 @@ class RenderSVGContainer : public RenderSVGModelObject {
 public:
     virtual ~RenderSVGContainer();
 
+    RenderObject* firstChild() const { return m_children.firstChild(); }
+    RenderObject* lastChild() const { return m_children.lastChild(); }
+
+    virtual const RenderObjectChildList* children() const OVERRIDE FINAL { return &m_children; }
+    virtual RenderObjectChildList* children() OVERRIDE FINAL { return &m_children; }
+
     virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE;
     virtual void setNeedsBoundariesUpdate() OVERRIDE FINAL { m_needsBoundariesUpdate = true; }
     virtual bool needsBoundariesUpdate() OVERRIDE FINAL { return m_needsBoundariesUpdate; }
@@ -47,8 +53,6 @@ protected:
     virtual bool isSVGContainer() const OVERRIDE FINAL { return true; }
     virtual const char* renderName() const OVERRIDE { return "RenderSVGContainer"; }
 
-    virtual bool canHaveChildren() const OVERRIDE FINAL { return true; }
-
     virtual void layout() OVERRIDE;
 
     virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0) OVERRIDE FINAL;
@@ -75,6 +79,7 @@ protected:
     void updateCachedBoundaries();
 
 private:
+    RenderObjectChildList m_children;
     FloatRect m_objectBoundingBox;
     bool m_objectBoundingBoxValid;
     FloatRect m_strokeBoundingBox;
index 57d336c..3bf1548 100644 (file)
@@ -53,8 +53,6 @@ protected:
     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
 
 private:
-    virtual bool canHaveChildren() const OVERRIDE { return false; }
-
     SVGGradientElement* gradientElement() const;
 };
 
index 314fa74..3151bce 100644 (file)
@@ -59,7 +59,6 @@ private:
 
     virtual const char* renderName() const { return "RenderSVGImage"; }
     virtual bool isSVGImage() const OVERRIDE { return true; }
-    virtual bool canHaveChildren() const OVERRIDE { return false; }
 
     virtual const AffineTransform& localToParentTransform() const { return m_localTransform; }
 
index 40867e8..4c1c5fb 100644 (file)
@@ -95,7 +95,7 @@ void RenderSVGModelObject::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixe
 void RenderSVGModelObject::willBeDestroyed()
 {
     SVGResourcesCache::clientDestroyed(this);
-    RenderElement::willBeDestroyed();
+    RenderObject::willBeDestroyed();
 }
 
 void RenderSVGModelObject::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
index 73729db..cd8e1bf 100644 (file)
@@ -46,6 +46,12 @@ public:
 
     virtual void computeIntrinsicRatioInformation(FloatSize& intrinsicSize, double& intrinsicRatio, bool& isPercentageIntrinsicSize) const OVERRIDE;
 
+    RenderObject* firstChild() const { return m_children.firstChild(); }
+    RenderObject* lastChild() const { return m_children.lastChild(); }
+
+    virtual const RenderObjectChildList* children() const OVERRIDE { return &m_children; }
+    virtual RenderObjectChildList* children() OVERRIDE { return &m_children; }
+
     bool isLayoutSizeChanged() const { return m_isLayoutSizeChanged; }
     virtual void setNeedsBoundariesUpdate() OVERRIDE { m_needsBoundariesOrTransformUpdate = true; }
     virtual bool needsBoundariesUpdate() OVERRIDE { return m_needsBoundariesOrTransformUpdate; }
@@ -109,6 +115,7 @@ private:
     void updateCachedBoundaries();
     void buildLocalToBorderBoxTransform();
 
+    RenderObjectChildList m_children;
     IntSize m_containerSize;
     FloatRect m_objectBoundingBox;
     bool m_objectBoundingBoxValid;
index 891c42a..b15375e 100644 (file)
@@ -115,7 +115,6 @@ private:
     virtual AffineTransform localTransform() const OVERRIDE FINAL { return m_localTransform; }
 
     virtual bool isSVGShape() const OVERRIDE FINAL { return true; }
-    virtual bool canHaveChildren() const OVERRIDE FINAL { return false; }
     virtual const char* renderName() const { return "RenderSVGShape"; }
 
     virtual void layout() OVERRIDE FINAL;