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