diff options
Diffstat (limited to 'Source/WebCore/dom/ContainerNode.cpp')
-rw-r--r-- | Source/WebCore/dom/ContainerNode.cpp | 47 |
1 files changed, 39 insertions, 8 deletions
diff --git a/Source/WebCore/dom/ContainerNode.cpp b/Source/WebCore/dom/ContainerNode.cpp index 2d22fa9..5574aa5 100644 --- a/Source/WebCore/dom/ContainerNode.cpp +++ b/Source/WebCore/dom/ContainerNode.cpp @@ -3,6 +3,7 @@ * (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) 2012 The Linux Foundation 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 @@ -74,6 +75,7 @@ static void collectTargetNodes(Node* node, NodeVector& nodes) void ContainerNode::removeAllChildren() { removeAllChildrenInContainer<Node, ContainerNode>(this); + updateNextNode(); } void ContainerNode::takeAllChildrenFrom(ContainerNode* oldParent) @@ -208,6 +210,8 @@ void ContainerNode::insertBeforeCommon(Node* nextChild, Node* newChild) newChild->setParent(this); newChild->setPreviousSibling(prev); newChild->setNextSibling(nextChild); + newChild->updatePreviousNode(); + newChild->lastDescendantNode(true)->updateNextNode(); allowEventDispatch(); } @@ -335,6 +339,9 @@ bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, Exce child->setParent(this); child->setPreviousSibling(prev.get()); child->setNextSibling(next); + child->updatePreviousNode(); + child->lastDescendantNode(true)->updateNextNode(); + allowEventDispatch(); childrenChanged(false, prev.get(), next, 1); @@ -362,12 +369,13 @@ bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, Exce void ContainerNode::willRemove() { - Vector<RefPtr<Node>, 10> nodes; - nodes.reserveInitialCapacity(childNodeCount()); - for (Node* n = m_lastChild; n; n = n->previousSibling()) - nodes.append(n); - for (; nodes.size(); nodes.removeLast()) - nodes.last().get()->willRemove(); + Node* next; + Node* child = m_firstChild; + while (child) { + next = child->nextSibling(); + child->willRemove(); + child = next; + } Node::willRemove(); } @@ -468,6 +476,8 @@ void ContainerNode::removeBetween(Node* previousChild, Node* nextChild, Node* ol if (oldChild->attached()) oldChild->detach(); + Node* previousNode = oldChild->traversePreviousNodeFastPath(); + if (nextChild) nextChild->setPreviousSibling(previousChild); if (previousChild) @@ -480,6 +490,10 @@ void ContainerNode::removeBetween(Node* previousChild, Node* nextChild, Node* ol oldChild->setPreviousSibling(0); oldChild->setNextSibling(0); oldChild->setParent(0); + oldChild->setPreviousNode(0); + oldChild->lastDescendantNode(true)->setNextNode(0); + if (previousNode) + previousNode->updateNextNode(); allowEventDispatch(); } @@ -530,6 +544,8 @@ void ContainerNode::removeChildren() n->setPreviousSibling(0); n->setNextSibling(0); n->setParent(0); + n->lastDescendantNode(true)->setNextNode(0); + n->setPreviousNode(0); m_firstChild = next; if (n == m_lastChild) @@ -552,6 +568,7 @@ void ContainerNode::removeChildren() removedChild->detach(); } + updateNextNode(); allowEventDispatch(); // Dispatch a single post-removal mutation event denoting a modified subtree. @@ -621,6 +638,8 @@ bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bo } else m_firstChild = child; m_lastChild = child; + child->updatePreviousNode(); + child->lastDescendantNode(true)->updateNextNode(); allowEventDispatch(); // Send notification about the children change. @@ -658,6 +677,10 @@ void ContainerNode::parserAddChild(PassRefPtr<Node> newChild) Node* last = m_lastChild; // FIXME: This method should take a PassRefPtr. appendChildToContainer<Node, ContainerNode>(newChild.get(), this); + if (last) + last->updateNextNode(); + newChild->updatePreviousNode(); + newChild->lastDescendantNode(true)->updateNextNode(); allowEventDispatch(); // FIXME: Why doesn't this use notifyChildInserted(newChild) instead? @@ -1070,8 +1093,12 @@ static void dispatchChildInsertionEvents(Node* child) // dispatch the DOMNodeInsertedIntoDocument event to all descendants if (c->inDocument() && document->hasListenerType(Document::DOMNODEINSERTEDINTODOCUMENT_LISTENER)) { - for (; c; c = c->traverseNextNode(child)) + Node* last = child->lastDescendantNode(true); + for (; c; c = c->traverseNextNodeFastPath()) { c->dispatchScopedEvent(MutationEvent::create(eventNames().DOMNodeInsertedIntoDocumentEvent, false)); + if (last == c) + break; + } } } @@ -1092,8 +1119,12 @@ static void dispatchChildRemovalEvents(Node* child) // dispatch the DOMNodeRemovedFromDocument event to all descendants if (c->inDocument() && document->hasListenerType(Document::DOMNODEREMOVEDFROMDOCUMENT_LISTENER)) { - for (; c; c = c->traverseNextNode(child)) + Node* last = c->lastDescendantNode(true); + for (; c; c = c->traverseNextNodeFastPath()) { c->dispatchScopedEvent(MutationEvent::create(eventNames().DOMNodeRemovedFromDocumentEvent, false)); + if (last == c) + break; + } } } |