2009-02-02 Sam Weinig <sam@webkit.org>
authorweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 Feb 2009 06:45:48 +0000 (06:45 +0000)
committerweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 Feb 2009 06:45:48 +0000 (06:45 +0000)
        Reviewed by David "The Barnabas Jones" Hyatt.

        Move removeChildNode, appendChildNode and insertChildNode from
        RenderContainer into RenderObjectChildList.  Make moveChildNode
        static in RenderBlock, as that was the only user.

        * rendering/RenderBlock.cpp:
        (WebCore::moveChild):
        (WebCore::RenderBlock::makeChildrenNonInline):
        (WebCore::RenderBlock::removeChild):
        (WebCore::RenderBlock::handleRunInChild):
        * rendering/RenderContainer.cpp:
        (WebCore::RenderContainer::addChild):
        (WebCore::RenderContainer::removeChild):
        * rendering/RenderContainer.h:
        * rendering/RenderInline.cpp:
        (WebCore::RenderInline::splitInlines):
        (WebCore::RenderInline::splitFlow):
        (WebCore::RenderInline::childBecameNonInline):
        * rendering/RenderObject.cpp:
        (WebCore::RenderObject::handleDynamicFloatPositionChange):
        * rendering/RenderObject.h:
        (WebCore::RenderObject::createsAnonymousWrapper):
        * rendering/RenderObjectChildList.cpp:
        (WebCore::updateListMarkerNumbers):
        (WebCore::RenderObjectChildList::removeChildNode):
        (WebCore::RenderObjectChildList::appendChildNode):
        (WebCore::RenderObjectChildList::insertChildNode):
        * rendering/RenderObjectChildList.h:
        * rendering/RenderSVGContainer.cpp:
        (WebCore::RenderSVGContainer::addChild):
        (WebCore::RenderSVGContainer::removeChild):
        * rendering/RenderSVGContainer.h:
        * rendering/RenderTable.cpp:
        (WebCore::RenderTable::removeChild):
        * rendering/RenderTable.h:
        * rendering/RenderTableSection.cpp:
        (WebCore::RenderTableSection::removeChild):
        * rendering/RenderTableSection.h:

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

15 files changed:
WebCore/ChangeLog
WebCore/rendering/RenderBlock.cpp
WebCore/rendering/RenderContainer.cpp
WebCore/rendering/RenderContainer.h
WebCore/rendering/RenderInline.cpp
WebCore/rendering/RenderObject.cpp
WebCore/rendering/RenderObject.h
WebCore/rendering/RenderObjectChildList.cpp
WebCore/rendering/RenderObjectChildList.h
WebCore/rendering/RenderSVGContainer.cpp
WebCore/rendering/RenderSVGContainer.h
WebCore/rendering/RenderTable.cpp
WebCore/rendering/RenderTable.h
WebCore/rendering/RenderTableSection.cpp
WebCore/rendering/RenderTableSection.h

index 991a0db66fa5903554333b1659465b6ad94a739f..e930a405e51b8645ba515ff2a787dc530a2d2011 100644 (file)
@@ -1,3 +1,45 @@
+2009-02-02  Sam Weinig  <sam@webkit.org>
+
+        Reviewed by David "The Barnabas Jones" Hyatt.
+
+        Move removeChildNode, appendChildNode and insertChildNode from 
+        RenderContainer into RenderObjectChildList.  Make moveChildNode
+        static in RenderBlock, as that was the only user.
+
+        * rendering/RenderBlock.cpp:
+        (WebCore::moveChild):
+        (WebCore::RenderBlock::makeChildrenNonInline):
+        (WebCore::RenderBlock::removeChild):
+        (WebCore::RenderBlock::handleRunInChild):
+        * rendering/RenderContainer.cpp:
+        (WebCore::RenderContainer::addChild):
+        (WebCore::RenderContainer::removeChild):
+        * rendering/RenderContainer.h:
+        * rendering/RenderInline.cpp:
+        (WebCore::RenderInline::splitInlines):
+        (WebCore::RenderInline::splitFlow):
+        (WebCore::RenderInline::childBecameNonInline):
+        * rendering/RenderObject.cpp:
+        (WebCore::RenderObject::handleDynamicFloatPositionChange):
+        * rendering/RenderObject.h:
+        (WebCore::RenderObject::createsAnonymousWrapper):
+        * rendering/RenderObjectChildList.cpp:
+        (WebCore::updateListMarkerNumbers):
+        (WebCore::RenderObjectChildList::removeChildNode):
+        (WebCore::RenderObjectChildList::appendChildNode):
+        (WebCore::RenderObjectChildList::insertChildNode):
+        * rendering/RenderObjectChildList.h:
+        * rendering/RenderSVGContainer.cpp:
+        (WebCore::RenderSVGContainer::addChild):
+        (WebCore::RenderSVGContainer::removeChild):
+        * rendering/RenderSVGContainer.h:
+        * rendering/RenderTable.cpp:
+        (WebCore::RenderTable::removeChild):
+        * rendering/RenderTable.h:
+        * rendering/RenderTableSection.cpp:
+        (WebCore::RenderTableSection::removeChild):
+        * rendering/RenderTableSection.h:
+
 2009-02-02  Alexey Proskuryakov  <ap@webkit.org>
 
         Reviewed by Darin Alder.
index 99758308ea731099e412d6125b9d3ef86e736e10..9863d3db75b69f3629e7f2cb78fec47a42299317 100644 (file)
@@ -55,6 +55,12 @@ const int verticalLineClickFudgeFactor= 3;
 
 using namespace HTMLNames;
 
+static void moveChild(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* from, RenderObjectChildList* fromChildList, RenderObject* child)
+{
+    ASSERT(from == child->parent());
+    toChildList->appendChildNode(to, fromChildList->removeChildNode(from, child, false), false);
+}
+
 struct ColumnInfo {
     ColumnInfo()
         : m_desiredColumnWidth(0)
@@ -430,16 +436,16 @@ void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
 
         child = inlineRunEnd->nextSibling();
 
-        RenderBlock* box = createAnonymousBlock();
-        insertChildNode(box, inlineRunStart);
+        RenderBlock* block = createAnonymousBlock();
+        children()->insertChildNode(this, block, inlineRunStart);
         RenderObject* o = inlineRunStart;
-        while(o != inlineRunEnd)
-        {
+        while (o != inlineRunEnd) {
             RenderObject* no = o;
             o = no->nextSibling();
-            box->moveChildNode(no);
+            
+            moveChild(block, block->children(), this, children(), no);
         }
-        box->moveChildNode(inlineRunEnd);
+        moveChild(block, block->children(), this, children(), inlineRunEnd);
     }
 
 #ifndef NDEBUG
@@ -508,13 +514,15 @@ void RenderBlock::removeChild(RenderObject* oldChild)
         // the |prev| block.
         prev->setNeedsLayoutAndPrefWidthsRecalc();
         RenderObject* o = next->firstChild();
+    
+        RenderBlock* nextBlock = toRenderBlock(next);
+        RenderBlock* prevBlock = toRenderBlock(prev);
         while (o) {
             RenderObject* no = o;
             o = no->nextSibling();
-            prev->moveChildNode(no);
+            moveChild(prevBlock, prevBlock->children(), nextBlock, nextBlock->children(), no);
         }
  
-        RenderBlock* nextBlock = toRenderBlock(next);
         nextBlock->deleteLineBoxTree();
         
         // Nuke the now-empty block.
@@ -529,13 +537,13 @@ void RenderBlock::removeChild(RenderObject* oldChild)
         // box.  We can go ahead and pull the content right back up into our
         // box.
         setNeedsLayoutAndPrefWidthsRecalc();
-        RenderBlock* anonBlock = toRenderBlock(removeChildNode(child, false));
+        RenderBlock* anonBlock = toRenderBlock(children()->removeChildNode(this, child, false));
         setChildrenInline(true);
         RenderObject* o = anonBlock->firstChild();
         while (o) {
             RenderObject* no = o;
             o = no->nextSibling();
-            moveChildNode(no);
+            moveChild(this, children(), anonBlock, anonBlock->children(), no);
         }
 
         // Delete the now-empty block's lines and nuke it.
@@ -971,24 +979,27 @@ RenderBox* RenderBlock::handleFloatingChild(RenderBox* child, const MarginInfo&
     return 0;
 }
 
-RenderBox* RenderBlock::handleRunInChild(RenderBox* blockRunIn, bool& handled)
+RenderBox* RenderBlock::handleRunInChild(RenderBox* child, bool& handled)
 {
     // See if we have a run-in element with inline children.  If the
     // children aren't inline, then just treat the run-in as a normal
     // block.
-    if (blockRunIn->isRunIn() && (blockRunIn->childrenInline() || blockRunIn->isReplaced())) {
+    if (child->isRunIn() && (child->childrenInline() || child->isReplaced())) {
+        RenderBlock* blockRunIn = toRenderBlock(child);
         // Get the next non-positioned/non-floating RenderBlock.
         RenderObject* curr = blockRunIn->nextSibling();
         while (curr && curr->isFloatingOrPositioned())
             curr = curr->nextSibling();
         if (curr && (curr->isRenderBlock() && curr->childrenInline() && !curr->isRunIn())) {
+            RenderBlock* currBlock = toRenderBlock(curr);
+        
             // The block acts like an inline, so just null out its
             // position.
             handled = true;
             
             // Remove the old child.
             RenderBox* next = blockRunIn->nextSiblingBox();
-            removeChildNode(blockRunIn);
+            children()->removeChildNode(this, blockRunIn);
 
             // Create an inline.
             RenderInline* inlineRunIn = new (renderArena()) RenderInline(blockRunIn->node());
@@ -996,10 +1007,10 @@ RenderBox* RenderBlock::handleRunInChild(RenderBox* blockRunIn, bool& handled)
 
             // Move the nodes from the old child to the new child.
             for (RenderObject* runInChild = blockRunIn->firstChild(); runInChild; runInChild = runInChild->nextSibling())
-                inlineRunIn->moveChildNode(runInChild);
+                moveChild(inlineRunIn, inlineRunIn->children(), blockRunIn, blockRunIn->children(), runInChild);
 
-            // Now insert the new child under |curr|.
-            curr->insertChildNode(inlineRunIn, curr->firstChild());
+            // Now insert the new child under |currBlock|.
+            currBlock->children()->insertChildNode(currBlock, inlineRunIn, currBlock->firstChild());
             
             // If the run-in had an element, we need to set the new renderer.
             if (blockRunIn->element())
index b28f48be77304ab1b1adbceec68e8404b59e9616..a863d07c2f5c520cd5636d5e59ad61bfde285d73 100644 (file)
@@ -96,7 +96,7 @@ void RenderContainer::addChild(RenderObject* newChild, RenderObject* beforeChild
         table->addChild(newChild);
     } else {
         // just add it...
-        insertChildNode(newChild, beforeChild);
+        children()->insertChildNode(this, newChild, beforeChild);
     }
     
     if (newChild->isText() && newChild->style()->textTransform() == CAPITALIZE) {
@@ -106,181 +106,13 @@ void RenderContainer::addChild(RenderObject* newChild, RenderObject* beforeChild
     }
 }
 
-RenderObject* RenderContainer::removeChildNode(RenderObject* oldChild, bool fullRemove)
-{
-    ASSERT(oldChild->parent() == this);
-
-    // 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() && fullRemove && oldChild->m_everHadLayout) {
-        oldChild->setNeedsLayoutAndPrefWidthsRecalc();
-        oldChild->repaint();
-    }
-        
-    // If we have a line box wrapper, delete it.
-    oldChild->deleteLineBoxWrapper();
-
-    if (!documentBeingDestroyed() && fullRemove) {
-        // if we remove visible child from an invisible parent, we don't know the layer visibility any more
-        RenderLayer* layer = 0;
-        if (m_style->visibility() != VISIBLE && oldChild->style()->visibility() == VISIBLE && !oldChild->hasLayer()) {
-            layer = enclosingLayer();
-            layer->dirtyVisibleContentStatus();
-        }
-
-         // Keep our layer hierarchy updated.
-        if (oldChild->firstChild() || oldChild->hasLayer()) {
-            if (!layer) layer = enclosingLayer();            
-            oldChild->removeLayers(layer);
-        }
-        
-        // renumber ordered lists
-        if (oldChild->isListItem())
-            updateListMarkerNumbers(oldChild->nextSibling());
-        
-        if (oldChild->isPositioned() && childrenInline())
-            dirtyLinesFromChangedChild(oldChild);
-    }
-    
-    // If oldChild is the start or end of the selection, then clear the selection to
-    // avoid problems of invalid pointers.
-    // FIXME: The SelectionController should be responsible for this when it
-    // is notified of DOM mutations.
-    if (!documentBeingDestroyed() && oldChild->isSelectionBorder())
-        view()->clearSelection();
-
-    // remove the child
-    if (oldChild->previousSibling())
-        oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());
-    if (oldChild->nextSibling())
-        oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling());
-
-    if (children()->firstChild() == oldChild)
-        children()->setFirstChild(oldChild->nextSibling());
-    if (children()->lastChild() == oldChild)
-        children()->setLastChild(oldChild->previousSibling());
-
-    oldChild->setPreviousSibling(0);
-    oldChild->setNextSibling(0);
-    oldChild->setParent(0);
-
-    if (AXObjectCache::accessibilityEnabled())
-        document()->axObjectCache()->childrenChanged(this);
-
-    return oldChild;
-}
-
 void RenderContainer::removeChild(RenderObject* oldChild)
 {
     // We do this here instead of in removeChildNode, since the only extremely low-level uses of remove/appendChildNode
     // cannot affect the positioned object list, and the floating object list is irrelevant (since the list gets cleared on
     // layout anyway).
     oldChild->removeFromObjectLists();
-    
-    removeChildNode(oldChild);
-}
-
-void RenderContainer::appendChildNode(RenderObject* newChild, bool fullAppend)
-{
-    ASSERT(newChild->parent() == 0);
-    ASSERT(!isBlockFlow() || (!newChild->isTableSection() && !newChild->isTableRow() && !newChild->isTableCell()));
-
-    newChild->setParent(this);
-    RenderObject* lChild = children()->lastChild();
-
-    if (lChild) {
-        newChild->setPreviousSibling(lChild);
-        lChild->setNextSibling(newChild);
-    } else
-        children()->setFirstChild(newChild);
-
-    children()->setLastChild(newChild);
-    
-    if (fullAppend) {
-        // Keep our layer hierarchy updated.  Optimize for the common case where we don't have any children
-        // and don't have a layer attached to ourselves.
-        RenderLayer* layer = 0;
-        if (newChild->firstChild() || newChild->hasLayer()) {
-            layer = enclosingLayer();
-            newChild->addLayers(layer, newChild);
-        }
-
-        // if the new child is visible but this object was not, tell the layer it has some visible content
-        // that needs to be drawn and layer visibility optimization can't be used
-        if (style()->visibility() != VISIBLE && newChild->style()->visibility() == VISIBLE && !newChild->hasLayer()) {
-            if (!layer)
-                layer = enclosingLayer();
-            if (layer)
-                layer->setHasVisibleContent(true);
-        }
-        
-        if (!newChild->isFloatingOrPositioned() && childrenInline())
-            dirtyLinesFromChangedChild(newChild);
-    }
-
-    newChild->setNeedsLayoutAndPrefWidthsRecalc(); // Goes up the containing block hierarchy.
-    if (!normalChildNeedsLayout())
-        setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child.
-    
-    if (AXObjectCache::accessibilityEnabled())
-        document()->axObjectCache()->childrenChanged(this);
-}
-
-void RenderContainer::insertChildNode(RenderObject* child, RenderObject* beforeChild, bool fullInsert)
-{
-    if (!beforeChild) {
-        appendChildNode(child);
-        return;
-    }
-
-    ASSERT(!child->parent());
-    while (beforeChild->parent() != this && beforeChild->parent()->isAnonymousBlock())
-        beforeChild = beforeChild->parent();
-    ASSERT(beforeChild->parent() == this);
-
-    ASSERT(!isBlockFlow() || (!child->isTableSection() && !child->isTableRow() && !child->isTableCell()));
-
-    if (beforeChild == children()->firstChild())
-        children()->setFirstChild(child);
-
-    RenderObject* prev = beforeChild->previousSibling();
-    child->setNextSibling(beforeChild);
-    beforeChild->setPreviousSibling(child);
-    if(prev) prev->setNextSibling(child);
-    child->setPreviousSibling(prev);
-
-    child->setParent(this);
-    
-    if (fullInsert) {
-        // Keep our layer hierarchy updated.  Optimize for the common case where we don't have any children
-        // and don't have a layer attached to ourselves.
-        RenderLayer* layer = 0;
-        if (child->firstChild() || child->hasLayer()) {
-            layer = enclosingLayer();
-            child->addLayers(layer, child);
-        }
-
-        // if the new child is visible but this object was not, tell the layer it has some visible content
-        // that needs to be drawn and layer visibility optimization can't be used
-        if (style()->visibility() != VISIBLE && child->style()->visibility() == VISIBLE && !child->hasLayer()) {
-            if (!layer)
-                layer = enclosingLayer();
-            if (layer)
-                layer->setHasVisibleContent(true);
-        }
-
-        
-        if (!child->isFloating() && childrenInline())
-            dirtyLinesFromChangedChild(child);
-    }
-
-    child->setNeedsLayoutAndPrefWidthsRecalc();
-    if (!normalChildNeedsLayout())
-        setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child.
-    
-    if (AXObjectCache::accessibilityEnabled())
-        document()->axObjectCache()->childrenChanged(this);
+    m_children.removeChildNode(this, oldChild);
 }
 
 void RenderContainer::addLineBoxRects(Vector<IntRect>& rects, unsigned start, unsigned end, bool)
index 7e723c011dbe187bdbee1c301978282bd6ca475a..b253af3221bc8d6075ac0a22e55a7e8e432b05d8 100644 (file)
@@ -40,14 +40,6 @@ public:
     virtual void addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild = 0) { return addChild(newChild, beforeChild); }
     virtual void removeChild(RenderObject*);
 
-    virtual RenderObject* removeChildNode(RenderObject*, bool fullRemove = true);
-    virtual void appendChildNode(RenderObject*, bool fullAppend = true);
-    virtual void insertChildNode(RenderObject* child, RenderObject* before, bool fullInsert = true);
-    
-    // Designed for speed.  Don't waste time doing a bunch of work like layer updating and repainting when we know that our
-    // change in parentage is not going to affect anything.
-    virtual void moveChildNode(RenderObject* child) { appendChildNode(child->parent()->removeChildNode(child, false), false); }
-
     virtual void addLineBoxRects(Vector<IntRect>&, unsigned startOffset = 0, unsigned endOffset = UINT_MAX, bool useSelectionHeight = false);
     virtual void collectAbsoluteLineBoxQuads(Vector<FloatQuad>&, unsigned startOffset = 0, unsigned endOffset = UINT_MAX, bool useSelectionHeight = false);
 
index bd8cd6b48ca0a4a12888e04eab1389a18691e1bf..501c16fb59c41218acbee48f0eb08179b3e492fb 100644 (file)
@@ -234,7 +234,7 @@ void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
     while (o) {
         RenderObject* tmp = o;
         o = tmp->nextSibling();
-        clone->addChildIgnoringContinuation(removeChildNode(tmp), 0);
+        clone->addChildIgnoringContinuation(children()->removeChildNode(this, tmp), 0);
         tmp->setNeedsLayoutAndPrefWidthsRecalc();
     }
 
@@ -281,7 +281,7 @@ void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
             while (o) {
                 RenderObject* tmp = o;
                 o = tmp->nextSibling();
-                clone->addChildIgnoringContinuation(curr->removeChildNode(tmp), 0);
+                clone->addChildIgnoringContinuation(curr->children()->removeChildNode(curr, tmp), 0);
                 tmp->setNeedsLayoutAndPrefWidthsRecalc();
             }
         }
@@ -293,7 +293,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->appendChildNode(clone);
+    toBlock->children()->appendChildNode(toBlock, clone);
 
     // Now take all the children after currChild and remove them from the fromBlock
     // and put them in the toBlock.
@@ -301,7 +301,7 @@ void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
     while (o) {
         RenderObject* tmp = o;
         o = tmp->nextSibling();
-        toBlock->appendChildNode(fromBlock->removeChildNode(tmp));
+        toBlock->children()->appendChildNode(toBlock, fromBlock->children()->removeChildNode(fromBlock, tmp));
     }
 }
 
@@ -329,9 +329,9 @@ void RenderInline::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox
 
     RenderObject* boxFirst = madeNewBeforeBlock ? block->firstChild() : pre->nextSibling();
     if (madeNewBeforeBlock)
-        block->insertChildNode(pre, boxFirst);
-    block->insertChildNode(newBlockBox, boxFirst);
-    block->insertChildNode(post, boxFirst);
+        block->children()->insertChildNode(block, pre, boxFirst);
+    block->children()->insertChildNode(block, newBlockBox, boxFirst);
+    block->children()->insertChildNode(block, post, boxFirst);
     block->setChildrenInline(false);
     
     if (madeNewBeforeBlock) {
@@ -339,7 +339,7 @@ void RenderInline::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox
         while (o) {
             RenderObject* no = o;
             o = no->nextSibling();
-            pre->appendChildNode(block->removeChildNode(no));
+            pre->children()->appendChildNode(pre, block->children()->removeChildNode(block, no));
             no->setNeedsLayoutAndPrefWidthsRecalc();
         }
     }
@@ -602,7 +602,7 @@ void RenderInline::childBecameNonInline(RenderObject* child)
     RenderContainer* oldContinuation = continuation();
     setContinuation(newBox);
     RenderObject* beforeChild = child->nextSibling();
-    removeChildNode(child);
+    children()->removeChildNode(this, child);
     splitFlow(beforeChild, newBox, child, oldContinuation);
 }
 
index 312d703d836f4643a14f3d66a69fd2707b81f088..1c660d601ca15eadd13a2c9ff930b5bbb2bbe982 100644 (file)
@@ -234,32 +234,11 @@ void RenderObject::addChild(RenderObject*, RenderObject*)
     ASSERT_NOT_REACHED();
 }
 
-RenderObject* RenderObject::removeChildNode(RenderObject*, bool)
-{
-    ASSERT_NOT_REACHED();
-    return 0;
-}
-
 void RenderObject::removeChild(RenderObject*)
 {
     ASSERT_NOT_REACHED();
 }
 
-void RenderObject::moveChildNode(RenderObject*)
-{
-    ASSERT_NOT_REACHED();
-}
-
-void RenderObject::appendChildNode(RenderObject*, bool)
-{
-    ASSERT_NOT_REACHED();
-}
-
-void RenderObject::insertChildNode(RenderObject*, RenderObject*, bool)
-{
-    ASSERT_NOT_REACHED();
-}
-
 RenderObject* RenderObject::nextInPreOrder() const
 {
     if (RenderObject* o = firstChild())
@@ -1880,12 +1859,13 @@ void RenderObject::handleDynamicFloatPositionChange()
     setInline(style()->isDisplayInlineType());
     if (isInline() != parent()->childrenInline()) {
         if (!isInline())
-            static_cast<RenderBox*>(parent())->childBecameNonInline(this);
+            toRenderBox(parent())->childBecameNonInline(this);
         else {
             // An anonymous block must be made to wrap this inline.
-            RenderBlock* box = createAnonymousBlock();
-            parent()->insertChildNode(box, this);
-            box->appendChildNode(parent()->removeChildNode(this));
+            RenderBlock* block = createAnonymousBlock();
+            RenderObjectChildList* childlist = parent()->virtualChildren();
+            childlist->insertChildNode(parent(), block, this);
+            block->children()->appendChildNode(block, childlist->removeChildNode(parent(), this));
         }
     }
 }
index 2bd9bcf6246f8d9b0092c7622765e16d4902c0c1..5965a1e1901be19514e7e4e6a8cff1bbdd9ff2a4 100644 (file)
@@ -115,6 +115,7 @@ class RenderObject : public CachedResourceClient {
     friend class RenderBlock;
     friend class RenderContainer;
     friend class RenderLayer;
+    friend class RenderObjectChildList;
     friend class RenderSVGContainer;
 public:
     // Anonymous objects should pass the document as their node, and they will then automatically be
@@ -213,14 +214,6 @@ public:
     virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0);
     virtual void removeChild(RenderObject*);
     virtual bool createsAnonymousWrapper() const { return false; }
-
-    // raw tree manipulation
-    virtual RenderObject* removeChildNode(RenderObject*, bool fullRemove = true);
-    virtual void appendChildNode(RenderObject*, bool fullAppend = true);
-    virtual void insertChildNode(RenderObject* child, RenderObject* before, bool fullInsert = true);
-    // Designed for speed.  Don't waste time doing a bunch of work like layer updating and repainting when we know that our
-    // change in parentage is not going to affect anything.
-    virtual void moveChildNode(RenderObject*);
     //////////////////////////////////////////
 
 protected:
index 1189e4b434118330ba555a363b943d3abd7323b1..19c2d21890d3e251d33657e430a1ca9fa6a75224 100644 (file)
 #include "config.h"
 #include "RenderObjectChildList.h"
 
+#include "AXObjectCache.h"
 #include "RenderBlock.h"
 #include "RenderCounter.h"
 #include "RenderImageGeneratedContent.h"
 #include "RenderInline.h"
+#include "RenderLayer.h"
+#include "RenderListItem.h"
+#include "RenderStyle.h"
 #include "RenderTextFragment.h"
+#include "RenderView.h"
 
 namespace WebCore {
 
+static void updateListMarkerNumbers(RenderObject* child)
+{
+    for (RenderObject* r = child; r; r = r->nextSibling()) {
+        if (r->isListItem())
+            static_cast<RenderListItem*>(r)->updateValue();
+    }
+}
+
+
 void RenderObjectChildList::destroyLeftoverChildren()
 {
     while (firstChild()) {
@@ -48,6 +62,175 @@ void RenderObjectChildList::destroyLeftoverChildren()
     }
 }
 
+RenderObject* RenderObjectChildList::removeChildNode(RenderObject* owner, RenderObject* oldChild, bool fullRemove)
+{
+    ASSERT(oldChild->parent() == owner);
+
+    // 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() && fullRemove && oldChild->m_everHadLayout) {
+        oldChild->setNeedsLayoutAndPrefWidthsRecalc();
+        oldChild->repaint();
+    }
+        
+    // If we have a line box wrapper, delete it.
+    oldChild->deleteLineBoxWrapper();
+
+    if (!owner->documentBeingDestroyed() && fullRemove) {
+        // if we remove visible child from an invisible parent, we don't know the layer visibility any more
+        RenderLayer* layer = 0;
+        if (owner->style()->visibility() != VISIBLE && oldChild->style()->visibility() == VISIBLE && !oldChild->hasLayer()) {
+            layer = owner->enclosingLayer();
+            layer->dirtyVisibleContentStatus();
+        }
+
+         // Keep our layer hierarchy updated.
+        if (oldChild->firstChild() || oldChild->hasLayer()) {
+            if (!layer)
+                layer = owner->enclosingLayer();
+            oldChild->removeLayers(layer);
+        }
+        
+        // renumber ordered lists
+        if (oldChild->isListItem())
+            updateListMarkerNumbers(oldChild->nextSibling());
+        
+        if (oldChild->isPositioned() && owner->childrenInline())
+            owner->dirtyLinesFromChangedChild(oldChild);
+    }
+    
+    // If oldChild is the start or end of the selection, then clear the selection to
+    // avoid problems of invalid pointers.
+    // FIXME: The SelectionController should be responsible for this when it
+    // is notified of DOM mutations.
+    if (!owner->documentBeingDestroyed() && oldChild->isSelectionBorder())
+        owner->view()->clearSelection();
+
+    // remove the child
+    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);
+
+    if (AXObjectCache::accessibilityEnabled())
+        owner->document()->axObjectCache()->childrenChanged(owner);
+
+    return oldChild;
+}
+
+void RenderObjectChildList::appendChildNode(RenderObject* owner, RenderObject* newChild, bool fullAppend)
+{
+    ASSERT(newChild->parent() == 0);
+    ASSERT(!owner->isBlockFlow() || (!newChild->isTableSection() && !newChild->isTableRow() && !newChild->isTableCell()));
+
+    newChild->setParent(owner);
+    RenderObject* lChild = lastChild();
+
+    if (lChild) {
+        newChild->setPreviousSibling(lChild);
+        lChild->setNextSibling(newChild);
+    } else
+        setFirstChild(newChild);
+
+    setLastChild(newChild);
+    
+    if (fullAppend) {
+        // Keep our layer hierarchy updated.  Optimize for the common case where we don't have any children
+        // and don't have a layer attached to ourselves.
+        RenderLayer* layer = 0;
+        if (newChild->firstChild() || newChild->hasLayer()) {
+            layer = owner->enclosingLayer();
+            newChild->addLayers(layer, newChild);
+        }
+
+        // if the new child is visible but this object was not, tell the layer it has some visible content
+        // that needs to be drawn and layer visibility optimization can't be used
+        if (owner->style()->visibility() != VISIBLE && newChild->style()->visibility() == VISIBLE && !newChild->hasLayer()) {
+            if (!layer)
+                layer = owner->enclosingLayer();
+            if (layer)
+                layer->setHasVisibleContent(true);
+        }
+        
+        if (!newChild->isFloatingOrPositioned() && owner->childrenInline())
+            owner->dirtyLinesFromChangedChild(newChild);
+    }
+
+    newChild->setNeedsLayoutAndPrefWidthsRecalc(); // Goes up the containing block hierarchy.
+    if (!owner->normalChildNeedsLayout())
+        owner->setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child.
+    
+    if (AXObjectCache::accessibilityEnabled())
+        owner->document()->axObjectCache()->childrenChanged(owner);
+}
+
+void RenderObjectChildList::insertChildNode(RenderObject* owner, RenderObject* child, RenderObject* beforeChild, bool fullInsert)
+{
+    if (!beforeChild) {
+        appendChildNode(owner, child);
+        return;
+    }
+
+    ASSERT(!child->parent());
+    while (beforeChild->parent() != owner && beforeChild->parent()->isAnonymousBlock())
+        beforeChild = beforeChild->parent();
+    ASSERT(beforeChild->parent() == owner);
+
+    ASSERT(!owner->isBlockFlow() || (!child->isTableSection() && !child->isTableRow() && !child->isTableCell()));
+
+    if (beforeChild == firstChild())
+        setFirstChild(child);
+
+    RenderObject* prev = beforeChild->previousSibling();
+    child->setNextSibling(beforeChild);
+    beforeChild->setPreviousSibling(child);
+    if (prev)
+        prev->setNextSibling(child);
+    child->setPreviousSibling(prev);
+
+    child->setParent(owner);
+    
+    if (fullInsert) {
+        // Keep our layer hierarchy updated.  Optimize for the common case where we don't have any children
+        // and don't have a layer attached to ourselves.
+        RenderLayer* layer = 0;
+        if (child->firstChild() || child->hasLayer()) {
+            layer = owner->enclosingLayer();
+            child->addLayers(layer, child);
+        }
+
+        // if the new child is visible but this object was not, tell the layer it has some visible content
+        // that needs to be drawn and layer visibility optimization can't be used
+        if (owner->style()->visibility() != VISIBLE && child->style()->visibility() == VISIBLE && !child->hasLayer()) {
+            if (!layer)
+                layer = owner->enclosingLayer();
+            if (layer)
+                layer->setHasVisibleContent(true);
+        }
+
+        
+        if (!child->isFloating() && owner->childrenInline())
+            owner->dirtyLinesFromChangedChild(child);
+    }
+
+    child->setNeedsLayoutAndPrefWidthsRecalc();
+    if (!owner->normalChildNeedsLayout())
+        owner->setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child.
+    
+    if (AXObjectCache::accessibilityEnabled())
+        owner->document()->axObjectCache()->childrenChanged(owner);
+}
+
 static RenderObject* beforeAfterContainer(RenderObject* container, RenderStyle::PseudoId type)
 {
     if (type == RenderStyle::BEFORE) {
@@ -239,4 +422,4 @@ void RenderObjectChildList::updateBeforeAfterContent(RenderObject* owner, Render
     }
 }
 
-}
+} // namespace WebCore
index 9759659665464ce3b5584dfdc8ce9082519b02fd..3f6f6e6fdd949c8a8dba939511dfbe933c1dca8d 100644 (file)
@@ -50,6 +50,10 @@ public:
     
     void destroyLeftoverChildren();
 
+    RenderObject* removeChildNode(RenderObject* owner, RenderObject*, bool fullRemove = true);
+    void appendChildNode(RenderObject* owner, RenderObject*, bool fullAppend = true);
+    void insertChildNode(RenderObject* owner, RenderObject* child, RenderObject* before, bool fullInsert = true);
+
     void updateBeforeAfterContent(RenderObject* owner, RenderStyle::PseudoId type, RenderObject* styledObject = 0);
     void invalidateCounters(RenderObject* owner);
 
index d6e2adc11274ee641e620ca54371f118dcc248f9..0e09fbeccad051c82d8d2a3db25de6e9579ecf0e 100644 (file)
@@ -51,7 +51,7 @@ RenderSVGContainer::~RenderSVGContainer()
 
 void RenderSVGContainer::addChild(RenderObject* newChild, RenderObject* beforeChild)
 {
-    insertChildNode(newChild, beforeChild);
+    children()->insertChildNode(this, newChild, beforeChild);
 }
 
 void RenderSVGContainer::removeChild(RenderObject* oldChild)
@@ -61,7 +61,7 @@ void RenderSVGContainer::removeChild(RenderObject* oldChild)
     // layout anyway).
     oldChild->removeFromObjectLists();
 
-    removeChildNode(oldChild);
+    children()->removeChildNode(this, oldChild);
 }
 
 void RenderSVGContainer::destroy()
@@ -70,106 +70,6 @@ void RenderSVGContainer::destroy()
     RenderObject::destroy();
 }
 
-RenderObject* RenderSVGContainer::removeChildNode(RenderObject* oldChild, bool fullRemove)
-{
-    ASSERT(oldChild->parent() == this);
-
-    // 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() && fullRemove) {
-        oldChild->setNeedsLayoutAndPrefWidthsRecalc();
-        oldChild->repaint();
-    }
-
-    // If we have a line box wrapper, delete it.
-    oldChild->deleteLineBoxWrapper();
-
-    if (!documentBeingDestroyed() && fullRemove) {
-        // If oldChild is the start or end of the selection, then clear the selection to
-        // avoid problems of invalid pointers.
-        // FIXME: The SelectionController should be responsible for this when it
-        // is notified of DOM mutations.
-        if (oldChild->isSelectionBorder())
-            view()->clearSelection();
-    }
-
-    // remove the child
-    if (oldChild->previousSibling())
-        oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());
-    if (oldChild->nextSibling())
-        oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling());
-
-    if (children()->firstChild() == oldChild)
-        children()->setFirstChild(oldChild->nextSibling());
-    if (children()->lastChild() == oldChild)
-        children()->setLastChild(oldChild->previousSibling());
-
-    oldChild->setPreviousSibling(0);
-    oldChild->setNextSibling(0);
-    oldChild->setParent(0);
-
-    if (AXObjectCache::accessibilityEnabled())
-        document()->axObjectCache()->childrenChanged(this);
-
-    return oldChild;
-}
-
-void RenderSVGContainer::appendChildNode(RenderObject* newChild, bool)
-{
-    ASSERT(!newChild->parent());
-    ASSERT(newChild->element()->isSVGElement());
-
-    newChild->setParent(this);
-    RenderObject* lChild = children()->lastChild();
-
-    if (lChild) {
-        newChild->setPreviousSibling(lChild);
-        lChild->setNextSibling(newChild);
-    } else
-        children()->setFirstChild(newChild);
-
-    children()->setLastChild(newChild);
-
-    newChild->setNeedsLayoutAndPrefWidthsRecalc(); // Goes up the containing block hierarchy.
-    if (!normalChildNeedsLayout())
-        setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child.
-
-    if (AXObjectCache::accessibilityEnabled())
-        document()->axObjectCache()->childrenChanged(this);
-}
-
-void RenderSVGContainer::insertChildNode(RenderObject* child, RenderObject* beforeChild, bool)
-{
-    if (!beforeChild) {
-        appendChildNode(child);
-        return;
-    }
-
-    ASSERT(!child->parent());
-    ASSERT(beforeChild->parent() == this);
-    ASSERT(child->element()->isSVGElement());
-
-    if (beforeChild == children()->firstChild())
-        children()->setFirstChild(child);
-
-    RenderObject* prev = beforeChild->previousSibling();
-    child->setNextSibling(beforeChild);
-    beforeChild->setPreviousSibling(child);
-    if (prev)
-        prev->setNextSibling(child);
-    child->setPreviousSibling(prev);
-
-    child->setParent(this);
-
-    child->setNeedsLayoutAndPrefWidthsRecalc();
-    if (!normalChildNeedsLayout())
-        setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child.
-
-    if (AXObjectCache::accessibilityEnabled())
-        document()->axObjectCache()->childrenChanged(this);
-}
-
 bool RenderSVGContainer::drawsContents() const
 {
     return m_drawsContents;
index 2d91d4538e62ee1a49de2f99d254bdfd55764448..b46221bd2020572f4740ed3c57188e00cb3345d3 100644 (file)
@@ -50,14 +50,6 @@ public:
 
     virtual void destroy();
 
-    virtual RenderObject* removeChildNode(RenderObject*, bool fullRemove = true);
-    virtual void appendChildNode(RenderObject*, bool fullAppend = true);
-    virtual void insertChildNode(RenderObject* child, RenderObject* before, bool fullInsert = true);
-
-    // Designed for speed.  Don't waste time doing a bunch of work like layer updating and repainting when we know that our
-    // change in parentage is not going to affect anything.
-    virtual void moveChildNode(RenderObject* child) { appendChildNode(child->parent()->removeChildNode(child, false), false); }
-
     // Some containers do not want it's children
     // to be drawn, because they may be 'referenced'
     // Example: <marker> children in SVG
index 697126cb5bff2cd3f3fd2c6cb409c855b393d2a3..38836b4cc86b5ad572850c9d1f01e8ba96b85517 100644 (file)
@@ -201,6 +201,12 @@ void RenderTable::addChild(RenderObject* child, RenderObject* beforeChild)
     section->addChild(child);
 }
 
+void RenderTable::removeChild(RenderObject* oldChild)
+{
+    RenderContainer::removeChild(oldChild);
+    setNeedsSectionRecalc();
+}
+
 void RenderTable::calcWidth()
 {
     if (isPositioned())
@@ -710,12 +716,6 @@ void RenderTable::recalcSections() const
     m_needsSectionRecalc = false;
 }
 
-RenderObject* RenderTable::removeChildNode(RenderObject* child, bool fullRemove)
-{
-    setNeedsSectionRecalc();
-    return RenderContainer::removeChildNode(child, fullRemove);
-}
-
 int RenderTable::calcBorderLeft() const
 {
     if (collapseBorders()) {
index db3caa8121526d9417b2c029b86890b505c0adc1..9b10c501d45345138df3a477d3e2ded3210a3f18 100644 (file)
@@ -72,6 +72,8 @@ public:
 
     // overrides
     virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
+    virtual void removeChild(RenderObject* oldChild);
+
     virtual void paint(PaintInfo&, int tx, int ty);
     virtual void paintBoxDecorations(PaintInfo&, int tx, int ty);
     virtual void paintMask(PaintInfo& paintInfo, int tx, int ty);
@@ -147,8 +149,6 @@ public:
         setNeedsLayout(true);
     }
 
-    virtual RenderObject* removeChildNode(RenderObject*, bool fullRemove = true);
-
     RenderTableSection* sectionAbove(const RenderTableSection*, bool skipEmptySections = false) const;
     RenderTableSection* sectionBelow(const RenderTableSection*, bool skipEmptySections = false) const;
 
index 4e415472a0f8298ea3deed6134e8a37d9ea79f24..41951d1b2b8899de0a93adef4fc4292eae1b64a0 100644 (file)
@@ -147,6 +147,12 @@ void RenderTableSection::addChild(RenderObject* child, RenderObject* beforeChild
     RenderContainer::addChild(child, beforeChild);
 }
 
+void RenderTableSection::removeChild(RenderObject* oldChild)
+{
+    setNeedsCellRecalc();
+    RenderContainer::removeChild(oldChild);
+}
+
 bool RenderTableSection::ensureRows(int numRows)
 {
     int nRows = m_gridRows;
@@ -1082,12 +1088,6 @@ void RenderTableSection::splitColumn(int pos, int newSize)
     }
 }
 
-RenderObject* RenderTableSection::removeChildNode(RenderObject* child, bool fullRemove)
-{
-    setNeedsCellRecalc();
-    return RenderContainer::removeChildNode(child, fullRemove);
-}
-
 // Hit Testing
 bool RenderTableSection::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int xPos, int yPos, int tx, int ty, HitTestAction action)
 {
index 524e59dfff0faa2b1a6a2fa766f20726df3a20d3..57cfb5d51ab5ca3ec727cc736c091a66c3896ac1 100644 (file)
@@ -49,6 +49,7 @@ public:
     virtual void layout();
 
     virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
+    virtual void removeChild(RenderObject* oldChild);
 
     virtual int getBaselineOfFirstLineBox() const;
 
@@ -121,8 +122,6 @@ public:
 
     int getBaseline(int row) { return m_grid[row].baseline; }
 
-    virtual RenderObject* removeChildNode(RenderObject*, bool fullRemove = true);
-
     virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
 
 private: