Title: [111449] trunk/Source/WebCore
Revision
111449
Author
[email protected]
Date
2012-03-20 15:10:37 -0700 (Tue, 20 Mar 2012)

Log Message

Refactor ContainerNode::replaceChild to match other mutation methods and share code
https://bugs.webkit.org/show_bug.cgi?id=81579

Reviewed by Ojan Vafai.

Originally landed as r111310, this fixes a bug in replaceChild
introduced when switching to the insert-before logic.

A future change will make use of the consistency among insertBefore/appendChild/replaceChild
to handle insertion of DocumentFragments more cleanly.

No new tests, no change in behavior.

* dom/ContainerNode.cpp:
(WebCore::ContainerNode::replaceChild): Use collectTargetNodes rather than walking through DocumentFragment children.
Insert before rather than inserting after. Dispatch to other methods to update parent/sibling pointers.
(WebCore::ContainerNode::appendChild): Call appendChildToContainer to update parent/sibling pointers.
(WebCore::ContainerNode::parserAddChild): Use type inference in call to appendChildToContainer.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (111448 => 111449)


--- trunk/Source/WebCore/ChangeLog	2012-03-20 22:07:57 UTC (rev 111448)
+++ trunk/Source/WebCore/ChangeLog	2012-03-20 22:10:37 UTC (rev 111449)
@@ -1,3 +1,24 @@
+2012-03-20  Adam Klein  <[email protected]>
+
+        Refactor ContainerNode::replaceChild to match other mutation methods and share code
+        https://bugs.webkit.org/show_bug.cgi?id=81579
+
+        Reviewed by Ojan Vafai.
+
+        Originally landed as r111310, this fixes a bug in replaceChild
+        introduced when switching to the insert-before logic.
+
+        A future change will make use of the consistency among insertBefore/appendChild/replaceChild
+        to handle insertion of DocumentFragments more cleanly.
+
+        No new tests, no change in behavior.
+
+        * dom/ContainerNode.cpp:
+        (WebCore::ContainerNode::replaceChild): Use collectTargetNodes rather than walking through DocumentFragment children.
+        Insert before rather than inserting after. Dispatch to other methods to update parent/sibling pointers.
+        (WebCore::ContainerNode::appendChild): Call appendChildToContainer to update parent/sibling pointers.
+        (WebCore::ContainerNode::parserAddChild): Use type inference in call to appendChildToContainer.
+
 2012-03-20  Jon Lee  <[email protected]>
 
         Restrict access to notifications for unique origins and file URLs with no local file access

Modified: trunk/Source/WebCore/dom/ContainerNode.cpp (111448 => 111449)


--- trunk/Source/WebCore/dom/ContainerNode.cpp	2012-03-20 22:07:57 UTC (rev 111448)
+++ trunk/Source/WebCore/dom/ContainerNode.cpp	2012-03-20 22:10:37 UTC (rev 111449)
@@ -284,29 +284,28 @@
     if (ec)
         return false;
 
-    bool isFragment = newChild->nodeType() == DOCUMENT_FRAGMENT_NODE && !newChild->isShadowRoot();
+    NodeVector targets;
+    collectTargetNodes(newChild.get(), targets);
 
     // Add the new child(ren)
-    RefPtr<Node> child = isFragment ? newChild->firstChild() : newChild;
-    while (child) {
+    for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); ++it) {
+        Node* child = it->get();
+
         // If the new child is already in the right place, we're done.
         if (prev && (prev == child || prev == child->previousSibling()))
             break;
 
-        // For a fragment we have more children to do.
-        RefPtr<Node> nextChild = isFragment ? child->nextSibling() : 0;
-
         // Remove child from its old position.
         if (ContainerNode* oldParent = child->parentNode())
-            oldParent->removeChild(child.get(), ec);
+            oldParent->removeChild(child, ec);
         if (ec)
             return false;
 
         // Due to arbitrary code running in response to a DOM mutation event it's
-        // possible that "prev" is no longer a child of "this".
+        // possible that "next" is no longer a child of "this".
         // It's also possible that "child" has been inserted elsewhere.
         // In either of those cases, we'll just stop.
-        if (prev && prev->parentNode() != this)
+        if (next && next->parentNode() != this)
             break;
         if (child->parentNode())
             break;
@@ -315,38 +314,22 @@
         ASSERT(!child->previousSibling());
 
 #if ENABLE(INSPECTOR)
-        InspectorInstrumentation::willInsertDOMNode(document(), child.get(), this);
+        InspectorInstrumentation::willInsertDOMNode(document(), child, this);
 #endif
 
-        treeScope()->adoptIfNeeded(child.get());
+        treeScope()->adoptIfNeeded(child);
 
-        // Add child after "prev".
+        // Add child before "next".
         forbidEventDispatch();
-        Node* next;
-        if (prev) {
-            next = prev->nextSibling();
-            ASSERT(m_firstChild != next);
-            prev->setNextSibling(child.get());
-        } else {
-            next = m_firstChild;
-            m_firstChild = child.get();
-        }
-        if (next) {
-            ASSERT(m_lastChild != prev);
-            ASSERT(next->previousSibling() == prev);
-            next->setPreviousSibling(child.get());
-        } else {
-            ASSERT(m_lastChild == prev);
-            m_lastChild = child.get();
-        }
-        child->setParent(this);
-        child->setPreviousSibling(prev.get());
-        child->setNextSibling(next);
+        if (next)
+            insertBeforeCommon(next.get(), child);
+        else
+            appendChildToContainer(child, this);
         allowEventDispatch();
 
-        childrenChanged(false, prev.get(), next, 1);
-        notifyChildInserted(child.get());
-                
+        childrenChanged(false, prev.get(), next.get(), 1);
+        notifyChildInserted(child);
+
         // Add child to the rendering tree
         if (attached() && !child->attached() && child->parentNode() == this) {
             if (shouldLazyAttach)
@@ -357,10 +340,8 @@
 
         // Now that the child is attached to the render tree, dispatch
         // the relevant mutation events.
-        dispatchChildInsertionEvents(child.get());
-
+        dispatchChildInsertionEvents(child);
         prev = child;
-        child = nextChild.release();
     }
 
     dispatchSubtreeModifiedEvent();
@@ -639,13 +620,7 @@
 
         // Append child to the end of the list
         forbidEventDispatch();
-        child->setParent(this);
-        if (m_lastChild) {
-            child->setPreviousSibling(m_lastChild);
-            m_lastChild->setNextSibling(child);
-        } else
-            m_firstChild = child;
-        m_lastChild = child;
+        appendChildToContainer(child, this);
         allowEventDispatch();
 
         // Send notification about the children change.
@@ -678,7 +653,7 @@
     forbidEventDispatch();
     Node* last = m_lastChild;
     // FIXME: This method should take a PassRefPtr.
-    appendChildToContainer<Node, ContainerNode>(newChild.get(), this);
+    appendChildToContainer(newChild.get(), this);
     treeScope()->adoptIfNeeded(newChild.get());
     
     allowEventDispatch();
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to