Index: third_party/WebKit/Source/core/dom/ContainerNode.cpp |
diff --git a/third_party/WebKit/Source/core/dom/ContainerNode.cpp b/third_party/WebKit/Source/core/dom/ContainerNode.cpp |
index 34ea3c648ad960c9b12c453150eff5b0bf9e85af..6160b8d499216b53917f18d5369c6c82cbaf3266 100644 |
--- a/third_party/WebKit/Source/core/dom/ContainerNode.cpp |
+++ b/third_party/WebKit/Source/core/dom/ContainerNode.cpp |
@@ -63,7 +63,7 @@ static void dispatchChildRemovalEvents(Node&); |
// This dispatches various events; DOM mutation events, blur events, IFRAME |
// unload events, etc. |
-static void collectChildrenAndRemoveFromOldParent(Node& node, NodeVector& nodes, ExceptionState& exceptionState) |
+static inline void collectChildrenAndRemoveFromOldParent(Node& node, NodeVector& nodes, ExceptionState& exceptionState) |
{ |
if (node.isDocumentFragment()) { |
DocumentFragment& fragment = toDocumentFragment(node); |
@@ -158,13 +158,11 @@ bool ContainerNode::checkAcceptChildGuaranteedNodeTypes(const Node& newChild, co |
return true; |
} |
-void ContainerNode::collectChildrenAndRemoveFromOldParentWithCheck(const Node* next, const Node* oldChild, Node& newChild, NodeVector& newChildren, ExceptionState& exceptionState) const |
+bool ContainerNode::collectChildrenAndRemoveFromOldParentWithCheck(const Node* next, const Node* oldChild, Node& newChild, NodeVector& newChildren, ExceptionState& exceptionState) const |
{ |
collectChildrenAndRemoveFromOldParent(newChild, newChildren, exceptionState); |
- if (exceptionState.hadException()) |
- return; |
- if (newChildren.isEmpty()) |
- return; |
+ if (exceptionState.hadException() || newChildren.isEmpty()) |
+ return false; |
// We need this extra check because collectChildrenAndRemoveFromOldParent() |
// can fire various events. |
@@ -172,16 +170,16 @@ void ContainerNode::collectChildrenAndRemoveFromOldParentWithCheck(const Node* n |
if (child->parentNode()) { |
// A new child was added to another parent before adding to this |
// node. Firefox and Edge don't throw in this case. |
- newChildren.clear(); |
- return; |
+ return false; |
} |
if (!checkAcceptChildGuaranteedNodeTypes(*child, oldChild, exceptionState)) |
- return; |
+ return false; |
} |
if (next && next->parentNode() != this) { |
exceptionState.throwDOMException(NotFoundError, "The node before which the new node is to be inserted is not a child of this node."); |
- return; |
+ return false; |
} |
+ return true; |
} |
template <typename Functor> |
@@ -240,16 +238,12 @@ public: |
Node* ContainerNode::insertBefore(Node* newChild, Node* refChild, ExceptionState& exceptionState) |
{ |
// insertBefore(node, 0) is equivalent to appendChild(node) |
- if (!refChild) { |
+ if (!refChild) |
return appendChild(newChild, exceptionState); |
- } |
// Make sure adding the new child is OK. |
- if (!checkAcceptChild(newChild, 0, exceptionState)) { |
- if (exceptionState.hadException()) |
- return nullptr; |
+ if (!checkAcceptChild(newChild, 0, exceptionState)) |
return newChild; |
- } |
DCHECK(newChild); |
// NotFoundError: Raised if refChild is not a child of this node |
@@ -262,25 +256,21 @@ Node* ContainerNode::insertBefore(Node* newChild, Node* refChild, ExceptionState |
if (refChild->previousSibling() == newChild || refChild == newChild) |
return newChild; |
- Node* next = refChild; |
- |
NodeVector targets; |
- collectChildrenAndRemoveFromOldParentWithCheck(next, nullptr, *newChild, targets, exceptionState); |
- if (exceptionState.hadException()) |
- return nullptr; |
- if (targets.isEmpty()) |
+ if (!collectChildrenAndRemoveFromOldParentWithCheck(refChild, nullptr, *newChild, targets, exceptionState)) |
return newChild; |
ChildListMutationScope mutation(*this); |
- insertNodeVector(targets, next, AdoptAndInsertBefore()); |
+ insertNodeVector(targets, refChild, AdoptAndInsertBefore()); |
return newChild; |
} |
void ContainerNode::insertBeforeCommon(Node& nextChild, Node& newChild) |
{ |
- EventDispatchForbiddenScope assertNoEventDispatch; |
- ScriptForbiddenScope forbidScript; |
- |
+#if DCHECK_IS_ON() |
+ DCHECK(EventDispatchForbiddenScope::isEventDispatchForbidden()); |
+#endif |
+ DCHECK(ScriptForbiddenScope::isScriptForbidden()); |
DCHECK(!newChild.parentNode()); // Use insertBefore if you need to handle reparenting (and want DOM mutation events). |
DCHECK(!newChild.nextSibling()); |
DCHECK(!newChild.previousSibling()); |
@@ -304,15 +294,18 @@ void ContainerNode::insertBeforeCommon(Node& nextChild, Node& newChild) |
void ContainerNode::appendChildCommon(Node& child) |
{ |
- child.setParentOrShadowHostNode(this); |
+#if DCHECK_IS_ON() |
+ DCHECK(EventDispatchForbiddenScope::isEventDispatchForbidden()); |
+#endif |
+ DCHECK(ScriptForbiddenScope::isScriptForbidden()); |
+ child.setParentOrShadowHostNode(this); |
if (m_lastChild) { |
child.setPreviousSibling(m_lastChild); |
m_lastChild->setNextSibling(&child); |
} else { |
setFirstChild(&child); |
} |
- |
setLastChild(&child); |
} |
@@ -354,8 +347,7 @@ void ContainerNode::parserInsertBefore(Node* newChild, Node& nextChild) |
EventDispatchForbiddenScope assertNoEventDispatch; |
ScriptForbiddenScope forbidScript; |
- treeScope().adoptIfNeeded(*newChild); |
- insertBeforeCommon(nextChild, *newChild); |
+ AdoptAndInsertBefore()(*this, *newChild, &nextChild); |
DCHECK_EQ(newChild->connectedSubframeCount(), 0u); |
ChildListMutationScope(*this).childAdded(*newChild); |
} |
@@ -373,52 +365,40 @@ Node* ContainerNode::replaceChild(Node* newChild, Node* oldChild, ExceptionState |
return nullptr; |
} |
- Node* child = oldChild; |
- |
// Make sure replacing the old child with the new is OK. |
- if (!checkAcceptChild(newChild, child, exceptionState)) { |
- if (exceptionState.hadException()) |
- return nullptr; |
- return child; |
- } |
+ if (!checkAcceptChild(newChild, oldChild, exceptionState)) |
+ return oldChild; |
// NotFoundError: Raised if oldChild is not a child of this node. |
- if (child->parentNode() != this) { |
+ if (oldChild->parentNode() != this) { |
exceptionState.throwDOMException(NotFoundError, "The node to be replaced is not a child of this node."); |
return nullptr; |
} |
ChildListMutationScope mutation(*this); |
- |
- Node* next = child->nextSibling(); |
+ Node* next = oldChild->nextSibling(); |
// Remove the node we're replacing. |
- removeChild(child, exceptionState); |
+ removeChild(oldChild, exceptionState); |
if (exceptionState.hadException()) |
return nullptr; |
if (next && (next->previousSibling() == newChild || next == newChild)) // nothing to do |
- return child; |
+ return oldChild; |
// Does this one more time because removeChild() fires a MutationEvent. |
- if (!checkAcceptChild(newChild, child, exceptionState)) { |
- if (exceptionState.hadException()) |
- return nullptr; |
- return child; |
- } |
+ if (!checkAcceptChild(newChild, oldChild, exceptionState)) |
+ return oldChild; |
NodeVector targets; |
- collectChildrenAndRemoveFromOldParentWithCheck(next, child, *newChild, targets, exceptionState); |
- if (exceptionState.hadException()) |
- return nullptr; |
- if (targets.isEmpty()) |
- return child; |
+ if (!collectChildrenAndRemoveFromOldParentWithCheck(next, oldChild, *newChild, targets, exceptionState)) |
+ return oldChild; |
if (next) |
insertNodeVector(targets, next, AdoptAndInsertBefore()); |
else |
insertNodeVector(targets, nullptr, AdoptAndAppendChild()); |
- return child; |
+ return oldChild; |
} |
void ContainerNode::willRemoveChild(Node& child) |
@@ -619,23 +599,16 @@ void ContainerNode::removeChildren(SubtreeModificationAction action) |
Node* ContainerNode::appendChild(Node* newChild, ExceptionState& exceptionState) |
{ |
- |
// Make sure adding the new child is ok |
- if (!checkAcceptChild(newChild, 0, exceptionState)) { |
- if (exceptionState.hadException()) |
- return nullptr; |
+ if (!checkAcceptChild(newChild, 0, exceptionState)) |
return newChild; |
- } |
DCHECK(newChild); |
if (newChild == m_lastChild) // nothing to do |
return newChild; |
NodeVector targets; |
- collectChildrenAndRemoveFromOldParentWithCheck(nullptr, nullptr, *newChild, targets, exceptionState); |
- if (exceptionState.hadException()) |
- return nullptr; |
- if (targets.isEmpty()) |
+ if (!collectChildrenAndRemoveFromOldParentWithCheck(nullptr, nullptr, *newChild, targets, exceptionState)) |
return newChild; |
ChildListMutationScope mutation(*this); |
@@ -665,8 +638,7 @@ void ContainerNode::parserAppendChild(Node* newChild) |
EventDispatchForbiddenScope assertNoEventDispatch; |
ScriptForbiddenScope forbidScript; |
- treeScope().adoptIfNeeded(*newChild); |
- appendChildCommon(*newChild); |
+ AdoptAndAppendChild()(*this, *newChild, nullptr); |
DCHECK_EQ(newChild->connectedSubframeCount(), 0u); |
ChildListMutationScope(*this).childAdded(*newChild); |
} |
@@ -1099,8 +1071,7 @@ HTMLCollection* ContainerNode::children() |
unsigned ContainerNode::countChildren() const |
{ |
unsigned count = 0; |
- Node* n; |
- for (n = firstChild(); n; n = n->nextSibling()) |
+ for (Node* node = firstChild(); node; node = node->nextSibling()) |
count++; |
return count; |
} |