Title: [86865] branches/chromium/742
Revision
86865
Author
[email protected]
Date
2011-05-19 11:43:52 -0700 (Thu, 19 May 2011)

Log Message

Merge 86358 - 2011-05-12  Carol Szabo  <[email protected]>

        Reviewed by David Hyatt.

        Fix reparenting and destruction of counter nodes. 
        https://bugs.webkit.org/show_bug.cgi?id=57929

        Fixed several issues related to not met assertions.
        See below in the per file description.

        Test: fast/css/counters/element-removal-crash.xhtml

        * dom/ContainerNode.cpp:
        (WebCore::ContainerNode::removeChildren):
        Fixed the fact that Node::detach() used to be called
        while the DOM tree was in an inconsistent state.
        * rendering/RenderCounter.cpp:
        (WebCore::RenderCounter::rendererRemovedFromTree):
        Introduced this function to remove counters from
        descendents of renderers removed from the renderer
        tree not only from the removed renderers themselves.
        * rendering/RenderCounter.h:
        * rendering/RenderObjectChildList.cpp:
        (WebCore::RenderObjectChildList::removeChildNode):
        Changed to call RenderCounter::rendererRemovedFromTree
        instead of RenderCounter::destroyCounters.

BUG=78572
Review URL: http://codereview.chromium.org/7049017

Modified Paths

Added Paths

Diff

Copied: branches/chromium/742/LayoutTests/fast/css/counters/element-removal-crash-expected.txt (from rev 86358, trunk/LayoutTests/fast/css/counters/element-removal-crash-expected.txt) (0 => 86865)


--- branches/chromium/742/LayoutTests/fast/css/counters/element-removal-crash-expected.txt	                        (rev 0)
+++ branches/chromium/742/LayoutTests/fast/css/counters/element-removal-crash-expected.txt	2011-05-19 18:43:52 UTC (rev 86865)
@@ -0,0 +1 @@
+PASS

Copied: branches/chromium/742/LayoutTests/fast/css/counters/element-removal-crash.xhtml (from rev 86358, trunk/LayoutTests/fast/css/counters/element-removal-crash.xhtml) (0 => 86865)


--- branches/chromium/742/LayoutTests/fast/css/counters/element-removal-crash.xhtml	                        (rev 0)
+++ branches/chromium/742/LayoutTests/fast/css/counters/element-removal-crash.xhtml	2011-05-19 18:43:52 UTC (rev 86865)
@@ -0,0 +1,31 @@
+<span xmlns="http://www.w3.org/1999/xhtml">
+<span/>
+<style>
+    span 
+    {
+        counter-increment: counter;
+    }
+    span:before
+    {
+        content: counter(counter);
+    }
+</style>
+<script>
+    if (window.layoutTestController) 
+    {
+        layoutTestController.dumpAsText();
+        layoutTestController.waitUntilDone();
+    }
+
+    function runTest()
+    {
+        document.documentElement.textContent = "PASS";
+
+        if (window.layoutTestController)
+            layoutTestController.notifyDone();
+    }
+
+    setTimeout('runTest()', 0);
+</script>
+<span/>
+

Modified: branches/chromium/742/Source/WebCore/dom/ContainerNode.cpp (86864 => 86865)


--- branches/chromium/742/Source/WebCore/dom/ContainerNode.cpp	2011-05-19 18:40:31 UTC (rev 86864)
+++ branches/chromium/742/Source/WebCore/dom/ContainerNode.cpp	2011-05-19 18:43:52 UTC (rev 86865)
@@ -534,21 +534,31 @@
         m_firstChild = next;
         if (n == m_lastChild)
             m_lastChild = 0;
+        removedChildren.append(n.release());
+    }
 
-        if (n->attached())
-            n->detach();
+    size_t removedChildrenCount = removedChildren.size();
+    size_t i;
 
-        removedChildren.append(n.release());
+    // Detach the nodes only after properly removed from the tree because
+    // a. detaching requires a proper DOM tree (for counters and quotes for
+    // example) and during the previous loop the next sibling still points to
+    // the node being removed while the node being removed does not point back
+    // and does not point to the same parent as its next sibling.
+    // b. destroying Renderers of standalone nodes is sometimes faster.
+    for (i = 0; i < removedChildrenCount; ++i) {
+        Node* removedChild = removedChildren[i].get();
+        if (removedChild->attached())
+            removedChild->detach();
     }
+
     allowEventDispatch();
 
-    size_t removedChildrenCount = removedChildren.size();
-
     // Dispatch a single post-removal mutation event denoting a modified subtree.
     childrenChanged(false, 0, 0, -static_cast<int>(removedChildrenCount));
     dispatchSubtreeModifiedEvent();
 
-    for (size_t i = 0; i < removedChildrenCount; ++i) {
+    for (i = 0; i < removedChildrenCount; ++i) {
         Node* removedChild = removedChildren[i].get();
         if (removedChild->inDocument())
             removedChild->removedFromDocument();

Modified: branches/chromium/742/Source/WebCore/rendering/RenderCounter.cpp (86864 => 86865)


--- branches/chromium/742/Source/WebCore/rendering/RenderCounter.cpp	2011-05-19 18:40:31 UTC (rev 86864)
+++ branches/chromium/742/Source/WebCore/rendering/RenderCounter.cpp	2011-05-19 18:43:52 UTC (rev 86865)
@@ -575,6 +575,19 @@
     // map associated with a renderer, so there is no risk in leaking the map.
 }
 
+void RenderCounter::rendererRemovedFromTree(RenderObject* removedRenderer)
+{
+    RenderObject* currentRenderer = removedRenderer->lastLeafChild();
+    if (!currentRenderer)
+        currentRenderer = removedRenderer;
+    while (true) {
+        destroyCounterNodes(currentRenderer);
+        if (currentRenderer == removedRenderer)
+            break;
+        currentRenderer = currentRenderer->previousInPreOrder();
+    }
+}
+
 static void updateCounters(RenderObject* renderer)
 {
     ASSERT(renderer->style());

Modified: branches/chromium/742/Source/WebCore/rendering/RenderCounter.h (86864 => 86865)


--- branches/chromium/742/Source/WebCore/rendering/RenderCounter.h	2011-05-19 18:40:31 UTC (rev 86864)
+++ branches/chromium/742/Source/WebCore/rendering/RenderCounter.h	2011-05-19 18:43:52 UTC (rev 86865)
@@ -37,6 +37,7 @@
     static void destroyCounterNodes(RenderObject*);
     static void destroyCounterNode(RenderObject*, const AtomicString& identifier);
     static void rendererSubtreeAttached(RenderObject*);
+    static void rendererRemovedFromTree(RenderObject*);
     static void rendererStyleChanged(RenderObject*, const RenderStyle* oldStyle, const RenderStyle* newStyle);
 
 private:

Modified: branches/chromium/742/Source/WebCore/rendering/RenderObjectChildList.cpp (86864 => 86865)


--- branches/chromium/742/Source/WebCore/rendering/RenderObjectChildList.cpp	2011-05-19 18:40:31 UTC (rev 86864)
+++ branches/chromium/742/Source/WebCore/rendering/RenderObjectChildList.cpp	2011-05-19 18:43:52 UTC (rev 86865)
@@ -129,8 +129,7 @@
     oldChild->setNextSibling(0);
     oldChild->setParent(0);
 
-    if (oldChild->m_hasCounterNodeMap)
-        RenderCounter::destroyCounterNodes(oldChild);
+    RenderCounter::rendererRemovedFromTree(oldChild);
     RenderQuote::rendererRemovedFromTree(oldChild);
 
     if (AXObjectCache::accessibilityEnabled())
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to