Title: [96150] trunk/Source/WebCore
Revision
96150
Author
rn...@webkit.org
Date
2011-09-27 13:51:24 -0700 (Tue, 27 Sep 2011)

Log Message

CompositeEditCommand::prune should remove subtree at once
https://bugs.webkit.org/show_bug.cgi?id=68866

Reviewed by Darin Adler.

Extracted the logic to find the highest ancestor to remove as highestNodeToRemoveInPruning from prune.
This reduces the number of node removals from O(n) to O(1) where n is the depth of the tree.

* editing/CompositeEditCommand.cpp:
(WebCore::hasARenderedDescendant): Takes excludedNode in addition to node. excludedNode is used to ignore
the child node from which we climbed up the tree in highestNodeToRemoveInPruning.
(WebCore::highestNodeToRemoveInPruning): Extracted from prune.
(WebCore::CompositeEditCommand::prune):
(WebCore::CompositeEditCommand::breakOutOfEmptyMailBlockquotedParagraph):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (96149 => 96150)


--- trunk/Source/WebCore/ChangeLog	2011-09-27 20:39:57 UTC (rev 96149)
+++ trunk/Source/WebCore/ChangeLog	2011-09-27 20:51:24 UTC (rev 96150)
@@ -1,3 +1,20 @@
+2011-09-27  Ryosuke Niwa  <rn...@webkit.org>
+
+        CompositeEditCommand::prune should remove subtree at once
+        https://bugs.webkit.org/show_bug.cgi?id=68866
+
+        Reviewed by Darin Adler.
+
+        Extracted the logic to find the highest ancestor to remove as highestNodeToRemoveInPruning from prune.
+        This reduces the number of node removals from O(n) to O(1) where n is the depth of the tree.
+
+        * editing/CompositeEditCommand.cpp:
+        (WebCore::hasARenderedDescendant): Takes excludedNode in addition to node. excludedNode is used to ignore
+        the child node from which we climbed up the tree in highestNodeToRemoveInPruning.
+        (WebCore::highestNodeToRemoveInPruning): Extracted from prune.
+        (WebCore::CompositeEditCommand::prune):
+        (WebCore::CompositeEditCommand::breakOutOfEmptyMailBlockquotedParagraph):
+
 2011-09-27  David Hyatt  <hy...@apple.com>
 
         https://bugs.webkit.org/show_bug.cgi?id=68922

Modified: trunk/Source/WebCore/editing/CompositeEditCommand.cpp (96149 => 96150)


--- trunk/Source/WebCore/editing/CompositeEditCommand.cpp	2011-09-27 20:39:57 UTC (rev 96149)
+++ trunk/Source/WebCore/editing/CompositeEditCommand.cpp	2011-09-27 20:51:24 UTC (rev 96150)
@@ -247,10 +247,13 @@
     return command->spanElement();
 }
 
-static bool hasARenderedDescendant(Node* node)
+static bool hasARenderedDescendant(Node* node, Node* excludedNode)
 {
-    Node* n = node->firstChild();
-    while (n) {
+    for (Node* n = node->firstChild(); n;) {
+        if (n == excludedNode) {
+            n = n->traverseNextSibling(node);
+            continue;
+        }
         if (n->renderer())
             return true;
         n = n->traverseNextNode(node);
@@ -258,22 +261,26 @@
     return false;
 }
 
-void CompositeEditCommand::prune(PassRefPtr<Node> prpNode)
+static Node* highestNodeToRemoveInPruning(Node* node)
 {
-    RefPtr<Node> node = prpNode;
-
-    while (node) {
-        // If you change this rule you may have to add an updateLayout() here.
-        RenderObject* renderer = node->renderer();
-        if (renderer && (!renderer->canHaveChildren() || hasARenderedDescendant(node.get()) || node->rootEditableElement() == node))
-            return;
-            
-        RefPtr<ContainerNode> next = node->parentNode();
-        removeNode(node);
-        node = next;
+    Node* previousNode = 0;
+    Node* rootEditableElement = node ? node->rootEditableElement() : 0;
+    for (; node; node = node->parentNode()) {
+        if (RenderObject* renderer = node->renderer()) {
+            if (!renderer->canHaveChildren() || hasARenderedDescendant(node, previousNode) || rootEditableElement == node)
+                return previousNode;
+        }
+        previousNode = node;
     }
+    return 0;
 }
 
+void CompositeEditCommand::prune(PassRefPtr<Node> node)
+{
+    if (RefPtr<Node> highestNodeToRemove = highestNodeToRemoveInPruning(node.get()))
+        removeNode(highestNodeToRemove.release());
+}
+
 void CompositeEditCommand::splitTextNode(PassRefPtr<Text> node, unsigned offset)
 {
     applyCommandToComposite(SplitTextNodeCommand::create(node, offset));
@@ -1165,11 +1172,9 @@
     // A line break is either a br or a preserved newline.
     ASSERT(caretPos.deprecatedNode()->hasTagName(brTag) || (caretPos.deprecatedNode()->isTextNode() && caretPos.deprecatedNode()->renderer()->style()->preserveNewline()));
     
-    if (caretPos.deprecatedNode()->hasTagName(brTag)) {
-        Position beforeBR(positionInParentBeforeNode(caretPos.deprecatedNode()));
-        removeNode(caretPos.deprecatedNode());
-        prune(beforeBR.deprecatedNode());
-    } else if (caretPos.deprecatedNode()->isTextNode()) {
+    if (caretPos.deprecatedNode()->hasTagName(brTag))
+        removeNodeAndPruneAncestors(caretPos.deprecatedNode());
+    else if (caretPos.deprecatedNode()->isTextNode()) {
         ASSERT(caretPos.deprecatedEditingOffset() == 0);
         Text* textNode = static_cast<Text*>(caretPos.deprecatedNode());
         ContainerNode* parentNode = textNode->parentNode();
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to