summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/dom/ContainerNode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/dom/ContainerNode.cpp')
-rw-r--r--Source/WebCore/dom/ContainerNode.cpp54
1 files changed, 36 insertions, 18 deletions
diff --git a/Source/WebCore/dom/ContainerNode.cpp b/Source/WebCore/dom/ContainerNode.cpp
index 4014cca..276df56 100644
--- a/Source/WebCore/dom/ContainerNode.cpp
+++ b/Source/WebCore/dom/ContainerNode.cpp
@@ -56,15 +56,19 @@ static NodeCallbackQueue* s_postAttachCallbackQueue;
static size_t s_attachDepth;
static bool s_shouldReEnableMemoryCacheCallsAfterAttach;
+static inline void collectNodes(Node* node, NodeVector& nodes)
+{
+ for (Node* child = node->firstChild(); child; child = child->nextSibling())
+ nodes.append(child);
+}
+
static void collectTargetNodes(Node* node, NodeVector& nodes)
{
if (node->nodeType() != Node::DOCUMENT_FRAGMENT_NODE) {
nodes.append(node);
return;
}
-
- for (Node* child = node->firstChild(); child; child = child->nextSibling())
- nodes.append(child);
+ collectNodes(node, nodes);
}
void ContainerNode::removeAllChildren()
@@ -75,8 +79,7 @@ void ContainerNode::removeAllChildren()
void ContainerNode::takeAllChildrenFrom(ContainerNode* oldParent)
{
NodeVector children;
- for (Node* child = oldParent->firstChild(); child; child = child->nextSibling())
- children.append(child);
+ collectNodes(oldParent, children);
oldParent->removeAllChildren();
for (unsigned i = 0; i < children.size(); ++i) {
@@ -101,7 +104,7 @@ bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce
{
// Check that this node is not "floating".
// If it is, it can be deleted as a side effect of sending mutation events.
- ASSERT(refCount() || parentNode());
+ ASSERT(refCount() || parentOrHostNode());
ec = 0;
@@ -158,7 +161,8 @@ bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce
InspectorInstrumentation::willInsertDOMNode(document(), child, this);
#endif
- child->setDocumentRecursively(document());
+ child->setTreeScopeRecursively(treeScope());
+
insertBeforeCommon(next.get(), child);
// Send notification about the children change.
@@ -241,7 +245,7 @@ bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, Exce
{
// Check that this node is not "floating".
// If it is, it can be deleted as a side effect of sending mutation events.
- ASSERT(refCount() || parentNode());
+ ASSERT(refCount() || parentOrHostNode());
ec = 0;
@@ -307,7 +311,7 @@ bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, Exce
InspectorInstrumentation::willInsertDOMNode(document(), child.get(), this);
#endif
- child->setDocumentRecursively(document());
+ child->setTreeScopeRecursively(treeScope());
// Add child after "prev".
forbidEventDispatch();
@@ -384,8 +388,7 @@ static void willRemoveChildren(ContainerNode* container)
container->document()->incDOMTreeVersion();
NodeVector children;
- for (Node* n = container->firstChild(); n; n = n->nextSibling())
- children.append(n);
+ collectNodes(container, children);
for (NodeVector::const_iterator it = children.begin(); it != children.end(); it++) {
Node* child = it->get();
@@ -399,7 +402,7 @@ bool ContainerNode::removeChild(Node* oldChild, ExceptionCode& ec)
{
// Check that this node is not "floating".
// If it is, it can be deleted as a side effect of sending mutation events.
- ASSERT(refCount() || parentNode());
+ ASSERT(refCount() || parentOrHostNode());
ec = 0;
@@ -559,7 +562,7 @@ bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bo
{
// Check that this node is not "floating".
// If it is, it can be deleted as a side effect of sending mutation events.
- ASSERT(refCount() || parentNode());
+ ASSERT(refCount() || parentOrHostNode());
ec = 0;
@@ -597,7 +600,7 @@ bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bo
InspectorInstrumentation::willInsertDOMNode(document(), child, this);
#endif
- child->setDocumentRecursively(document());
+ child->setTreeScopeRecursively(treeScope());
// Append child to the end of the list
forbidEventDispatch();
@@ -735,8 +738,16 @@ void ContainerNode::insertedIntoDocument()
{
Node::insertedIntoDocument();
insertedIntoTree(false);
- for (Node* child = m_firstChild; child && inDocument(); child = child->nextSibling())
+
+ // Determine set of children before operating on any of them.
+ NodeVector children;
+ collectNodes(this, children);
+
+ NodeVector::iterator it;
+ for (it = children.begin(); it != children.end() && inDocument(); ++it) {
+ Node* child = it->get();
child->insertedIntoDocument();
+ }
}
void ContainerNode::removedFromDocument()
@@ -778,9 +789,16 @@ void ContainerNode::childrenChanged(bool changedByParser, Node* beforeChange, No
void ContainerNode::cloneChildNodes(ContainerNode *clone)
{
// disable the delete button so it's elements are not serialized into the markup
- bool isEditorEnabled = document()->frame() && document()->frame()->editor()->canEdit();
- if (isEditorEnabled)
- document()->frame()->editor()->deleteButtonController()->disable();
+ bool isEditorEnabled = false;
+ if (document()->frame() && document()->frame()->editor()->canEdit()) {
+ SelectionController* selection = document()->frame()->selection();
+ Element* root = selection ? selection->rootEditableElement() : 0;
+ isEditorEnabled = root && isDescendantOf(root);
+
+ if (isEditorEnabled)
+ document()->frame()->editor()->deleteButtonController()->disable();
+ }
+
ExceptionCode ec = 0;
for (Node* n = firstChild(); n && !ec; n = n->nextSibling())
clone->appendChild(n->cloneNode(true), ec);