summaryrefslogtreecommitdiffstats
path: root/WebCore/dom/ContainerNode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/dom/ContainerNode.cpp')
-rw-r--r--WebCore/dom/ContainerNode.cpp180
1 files changed, 108 insertions, 72 deletions
diff --git a/WebCore/dom/ContainerNode.cpp b/WebCore/dom/ContainerNode.cpp
index e559ba7..ef62b38 100644
--- a/WebCore/dom/ContainerNode.cpp
+++ b/WebCore/dom/ContainerNode.cpp
@@ -134,31 +134,12 @@ bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce
if (child->parentNode())
break;
- ASSERT(!child->nextSibling());
- ASSERT(!child->previousSibling());
-
- // Add child before "next".
- forbidEventDispatch();
- Node* prev = next->previousSibling();
- ASSERT(m_lastChild != prev);
- next->setPreviousSibling(child);
- if (prev) {
- ASSERT(m_firstChild != next);
- ASSERT(prev->nextSibling() == next);
- prev->setNextSibling(child);
- } else {
- ASSERT(m_firstChild == next);
- m_firstChild = child;
- }
- child->setParent(this);
- child->setPreviousSibling(prev);
- child->setNextSibling(next.get());
- allowEventDispatch();
+ insertBeforeCommon(next.get(), child);
// Send notification about the children change.
childrenChanged(false, refChildPreviousSibling.get(), next.get(), 1);
notifyChildInserted(child);
-
+
// Add child to the rendering tree.
if (attached() && !child->attached() && child->parent() == this) {
if (shouldLazyAttach)
@@ -176,6 +157,57 @@ bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce
return true;
}
+void ContainerNode::insertBeforeCommon(Node* nextChild, Node* newChild)
+{
+ ASSERT(newChild);
+ ASSERT(!newChild->parent()); // Use insertBefore if you need to handle reparenting (and want DOM mutation events).
+ ASSERT(!newChild->nextSibling());
+ ASSERT(!newChild->previousSibling());
+
+ forbidEventDispatch();
+ Node* prev = nextChild->previousSibling();
+ ASSERT(m_lastChild != prev);
+ nextChild->setPreviousSibling(newChild);
+ if (prev) {
+ ASSERT(m_firstChild != nextChild);
+ ASSERT(prev->nextSibling() == nextChild);
+ prev->setNextSibling(newChild);
+ } else {
+ ASSERT(m_firstChild == nextChild);
+ m_firstChild = newChild;
+ }
+ newChild->setParent(this);
+ newChild->setPreviousSibling(prev);
+ newChild->setNextSibling(nextChild);
+ allowEventDispatch();
+}
+
+void ContainerNode::parserInsertBefore(PassRefPtr<Node> newChild, Node* nextChild)
+{
+ ASSERT(newChild);
+ ASSERT(nextChild);
+ ASSERT(nextChild->parentNode() == this);
+
+ NodeVector targets;
+ collectTargetNodes(newChild.get(), targets);
+ if (targets.isEmpty())
+ return;
+
+ if (nextChild->previousSibling() == newChild || nextChild == newChild) // nothing to do
+ return;
+
+ RefPtr<Node> next = nextChild;
+ RefPtr<Node> nextChildPreviousSibling = nextChild->previousSibling();
+ for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); ++it) {
+ Node* child = it->get();
+
+ insertBeforeCommon(next.get(), child);
+
+ childrenChanged(true, nextChildPreviousSibling.get(), nextChild, 1);
+ notifyChildInserted(child);
+ }
+}
+
bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode& ec, bool shouldLazyAttach)
{
// Check that this node is not "floating".
@@ -367,31 +399,9 @@ bool ContainerNode::removeChild(Node* oldChild, ExceptionCode& ec)
// that no callers call with ref count == 0 and parent = 0 (as of this
// writing, there are definitely callers who call that way).
- forbidEventDispatch();
-
- // Remove from rendering tree
- if (child->attached())
- child->detach();
-
- // Remove the child
- Node *prev, *next;
- prev = child->previousSibling();
- next = child->nextSibling();
-
- if (next)
- next->setPreviousSibling(prev);
- if (prev)
- prev->setNextSibling(next);
- if (m_firstChild == child)
- m_firstChild = next;
- if (m_lastChild == child)
- m_lastChild = prev;
-
- child->setPreviousSibling(0);
- child->setNextSibling(0);
- child->setParent(0);
-
- allowEventDispatch();
+ Node* prev = child->previousSibling();
+ Node* next = child->nextSibling();
+ removeBetween(prev, next, child.get());
// Dispatch post-removal mutation events
childrenChanged(false, prev, next, -1);
@@ -405,6 +415,50 @@ bool ContainerNode::removeChild(Node* oldChild, ExceptionCode& ec)
return child;
}
+void ContainerNode::removeBetween(Node* previousChild, Node* nextChild, Node* oldChild)
+{
+ ASSERT(oldChild);
+ ASSERT(oldChild->parentNode() == this);
+
+ forbidEventDispatch();
+
+ // Remove from rendering tree
+ if (oldChild->attached())
+ oldChild->detach();
+
+ if (nextChild)
+ nextChild->setPreviousSibling(previousChild);
+ if (previousChild)
+ previousChild->setNextSibling(nextChild);
+ if (m_firstChild == oldChild)
+ m_firstChild = nextChild;
+ if (m_lastChild == oldChild)
+ m_lastChild = previousChild;
+
+ oldChild->setPreviousSibling(0);
+ oldChild->setNextSibling(0);
+ oldChild->setParent(0);
+
+ allowEventDispatch();
+}
+
+void ContainerNode::parserRemoveChild(Node* oldChild)
+{
+ ASSERT(oldChild);
+ ASSERT(oldChild->parentNode() == this);
+
+ Node* prev = oldChild->previousSibling();
+ Node* next = oldChild->nextSibling();
+
+ removeBetween(prev, next, oldChild);
+
+ childrenChanged(true, prev, next, -1);
+ if (oldChild->inDocument())
+ oldChild->removedFromDocument();
+ else
+ oldChild->removedFromTree(true);
+}
+
// this differs from other remove functions because it forcibly removes all the children,
// regardless of read-only status or event exceptions, e.g.
bool ContainerNode::removeChildren()
@@ -534,45 +588,27 @@ bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bo
return true;
}
-void ContainerNode::addChildCommon(Node* newChild)
+void ContainerNode::parserAddChild(PassRefPtr<Node> newChild)
{
- ASSERT(!newChild->parent()); // Use appendChild if you need to handle reparenting.
+ ASSERT(newChild);
+ ASSERT(!newChild->parent()); // Use appendChild if you need to handle reparenting (and want DOM mutation events).
+
forbidEventDispatch();
Node* last = m_lastChild;
// FIXME: This method should take a PassRefPtr.
- appendChildToContainer<Node, ContainerNode>(newChild, this);
+ appendChildToContainer<Node, ContainerNode>(newChild.get(), this);
allowEventDispatch();
+ // FIXME: Why doesn't this use notifyChildInserted(newChild) instead?
document()->incDOMTreeVersion();
if (inDocument())
newChild->insertedIntoDocument();
childrenChanged(true, last, 0, 1);
}
-void ContainerNode::parserAddChild(PassRefPtr<Node> newChild)
+void ContainerNode::deprecatedParserAddChild(PassRefPtr<Node> node)
{
- ASSERT(newChild);
- // This function is only used during parsing.
- // It does not send any DOM mutation events or handle reparenting.
-
- addChildCommon(newChild.get());
-}
-
-ContainerNode* ContainerNode::legacyParserAddChild(PassRefPtr<Node> newChild)
-{
- ASSERT(newChild);
- // This function is only used during parsing.
- // It does not send any DOM mutation events.
-
- // Check for consistency with DTD, but only when parsing HTML.
- if (document()->isHTMLDocument() && !childAllowed(newChild.get()))
- return 0;
-
- addChildCommon(newChild.get());
-
- if (newChild->isElementNode())
- return static_cast<ContainerNode*>(newChild.get());
- return this;
+ parserAddChild(node);
}
void ContainerNode::suspendPostAttachCallbacks()