cloneChildNodes looks for deleteButtonController in each level of recursion
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Apr 2013 18:33:22 +0000 (18:33 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Apr 2013 18:33:22 +0000 (18:33 +0000)
https://bugs.webkit.org/show_bug.cgi?id=115146

Reviewed by Andreas Kling.

Obtain the delete button controller upfront, and shallow copy descendents of each child
so that we don't look for the delete button controller inside cloneNode called on each child.

Performance Tests: DOM/CloneNodes.html

* dom/ContainerNode.cpp:
(WebCore::cloneChildNodesAvoidingDeleteButon): Extracted.
(WebCore::ContainerNode::cloneChildNodes):

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

Source/WebCore/ChangeLog
Source/WebCore/dom/ContainerNode.cpp

index 66148d25487375c5baaa8f1dadc23c5e9f7961e0..851e76d1f71f663f4a162755b10d7d16e45f4d22 100644 (file)
@@ -1,3 +1,19 @@
+2013-04-25  Ryosuke Niwa  <rniwa@webkit.org>
+
+        cloneChildNodes looks for deleteButtonController in each level of recursion
+        https://bugs.webkit.org/show_bug.cgi?id=115146
+
+        Reviewed by Andreas Kling.
+
+        Obtain the delete button controller upfront, and shallow copy descendents of each child
+        so that we don't look for the delete button controller inside cloneNode called on each child.
+
+        Performance Tests: DOM/CloneNodes.html
+
+        * dom/ContainerNode.cpp:
+        (WebCore::cloneChildNodesAvoidingDeleteButon): Extracted.
+        (WebCore::ContainerNode::cloneChildNodes):
+
 2013-04-25  Ryosuke Niwa  <rniwa@webkit.org>
 
         HTMLOptionsCollection's namedItem and name getter should return the first item
 2013-04-25  Ryosuke Niwa  <rniwa@webkit.org>
 
         HTMLOptionsCollection's namedItem and name getter should return the first item
index 14e41fb8db75b71845103e7616b5bcfe7e119702..a0be88aa5b37e7ec4e31f6fc3e67d8bec00bbf01 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
  *           (C) 2001 Dirk Mueller (mueller@kde.org)
  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
  *           (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -831,21 +831,36 @@ void ContainerNode::childrenChanged(bool changedByParser, Node*, Node*, int chil
     invalidateNodeListCachesInAncestors();
 }
 
     invalidateNodeListCachesInAncestors();
 }
 
+inline static void cloneChildNodesAvoidingDeleteButton(ContainerNode* parent, ContainerNode* clonedParent, HTMLElement* deleteButtonContainerElement)
+{
+    ExceptionCode ec = 0;
+    for (Node* child = parent->firstChild(); child && !ec; child = child->nextSibling()) {
+
+#if ENABLE(DELETION_UI)
+        if (child == deleteButtonContainerElement)
+            continue;
+#else
+        UNUSED_PARAM(deleteButtonContainerElement);
+#endif
+
+        RefPtr<Node> clonedChild = child->cloneNode(false);
+        clonedParent->appendChild(clonedChild, ec);
+
+        if (!ec && child->isContainerNode())
+            cloneChildNodesAvoidingDeleteButton(toContainerNode(child), toContainerNode(clonedChild.get()), deleteButtonContainerElement);
+    }
+}
+
 void ContainerNode::cloneChildNodes(ContainerNode *clone)
 {
 #if ENABLE(DELETION_UI)
     HTMLElement* deleteButtonContainerElement = 0;
     if (Frame* frame = document()->frame())
         deleteButtonContainerElement = frame->editor()->deleteButtonController()->containerElement();
 void ContainerNode::cloneChildNodes(ContainerNode *clone)
 {
 #if ENABLE(DELETION_UI)
     HTMLElement* deleteButtonContainerElement = 0;
     if (Frame* frame = document()->frame())
         deleteButtonContainerElement = frame->editor()->deleteButtonController()->containerElement();
+    cloneChildNodesAvoidingDeleteButton(this, clone, deleteButtonContainerElement);
+#else
+    cloneChildNodesAvoidingDeleteButton(this, clone, 0);
 #endif
 #endif
-    ExceptionCode ec = 0;
-    for (Node* n = firstChild(); n && !ec; n = n->nextSibling()) {
-#if ENABLE(DELETION_UI)
-        if (n == deleteButtonContainerElement)
-            continue;
-#endif
-        clone->appendChild(n->cloneNode(true), ec);
-    }
 }
 
 bool ContainerNode::getUpperLeftCorner(FloatPoint& point) const
 }
 
 bool ContainerNode::getUpperLeftCorner(FloatPoint& point) const