| 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 3831b25430f942f5a9b09408216f6cd1142b852e..d151f86379fc836a645b02d36faf14bb1800b7d3 100644
|
| --- a/third_party/WebKit/Source/core/dom/ContainerNode.cpp
|
| +++ b/third_party/WebKit/Source/core/dom/ContainerNode.cpp
|
| @@ -412,48 +412,80 @@ Node* ContainerNode::ReplaceChild(Node* new_child,
|
| return nullptr;
|
| }
|
|
|
| - // Make sure replacing the old child with the new is OK.
|
| + // 1. If parent is not a Document, DocumentFragment, or Element node, throw a
|
| + // HierarchyRequestError.
|
| + // 2. If node is a host-including inclusive ancestor of parent, throw a
|
| + // HierarchyRequestError.
|
| + // 4. If node is not a DocumentFragment, DocumentType, Element, Text,
|
| + // ProcessingInstruction, or Comment node, throw a HierarchyRequestError.
|
| + // 5. If either node is a Text node and parent is a document, or node is a
|
| + // doctype and parent is not a document, throw a HierarchyRequestError.
|
| + // 6. If parent is a document, and any of the statements below, switched on
|
| + // node, are true, throw a HierarchyRequestError.
|
| if (!CheckAcceptChild(new_child, old_child, exception_state))
|
| return old_child;
|
|
|
| - // NotFoundError: Raised if oldChild is not a child of this node.
|
| + // 3. If child’s parent is not parent, then throw a NotFoundError.
|
| if (old_child->parentNode() != this) {
|
| exception_state.ThrowDOMException(
|
| kNotFoundError, "The node to be replaced is not a child of this node.");
|
| return nullptr;
|
| }
|
|
|
| - ChildListMutationScope mutation(*this);
|
| // 7. Let reference child be child’s next sibling.
|
| Node* next = old_child->nextSibling();
|
| // 8. If reference child is node, set it to node’s next sibling.
|
| if (next == new_child)
|
| next = new_child->nextSibling();
|
|
|
| - // TODO(tkent): According to the specification, we should remove |newChild|
|
| - // from its parent here, and create a separated mutation record for it.
|
| - // Refer to external/wpt/dom/nodes/MutationObserver-childList.html.
|
| + // 10. Adopt node into parent’s node document.
|
| + // TODO(tkent): Actually we do only RemoveChild() as a part of 'adopt'
|
| + // operation.
|
| + // Though the following CollectChildrenAndRemoveFromOldParentWithCheck() also
|
| + // calls RemoveChild(), we'd like to call RemoveChild() here to make a
|
| + // separated MutationRecord.
|
| + if (ContainerNode* new_child_parent = new_child->parentNode()) {
|
| + new_child_parent->RemoveChild(new_child, exception_state);
|
| + if (exception_state.HadException())
|
| + return nullptr;
|
| + }
|
| +
|
| + // 9. Let previousSibling be child’s previous sibling.
|
| + // 11. Let removedNodes be the empty list.
|
| + // 15. Queue a mutation record of "childList" for target parent with
|
| + // addedNodes nodes, removedNodes removedNodes, nextSibling reference child,
|
| + // and previousSibling previousSibling.
|
| + ChildListMutationScope mutation(*this);
|
|
|
| // 12. If child’s parent is not null, run these substeps:
|
| // 1. Set removedNodes to a list solely containing child.
|
| // 2. Remove child from its parent with the suppress observers flag set.
|
| - RemoveChild(old_child, exception_state);
|
| - if (exception_state.HadException())
|
| - return nullptr;
|
| + if (ContainerNode* old_child_parent = old_child->parentNode()) {
|
| + old_child_parent->RemoveChild(old_child, exception_state);
|
| + if (exception_state.HadException())
|
| + return nullptr;
|
| + }
|
|
|
| // Does this one more time because removeChild() fires a MutationEvent.
|
| if (!CheckAcceptChild(new_child, old_child, exception_state))
|
| return old_child;
|
|
|
| + // 13. Let nodes be node’s children if node is a DocumentFragment node, and a
|
| + // list containing solely node otherwise.
|
| NodeVector targets;
|
| if (!CollectChildrenAndRemoveFromOldParentWithCheck(
|
| next, old_child, *new_child, targets, exception_state))
|
| return old_child;
|
|
|
| + // 10. Adopt node into parent’s node document.
|
| + // 14. Insert node into parent before reference child with the suppress
|
| + // observers flag set.
|
| if (next)
|
| InsertNodeVector(targets, next, AdoptAndInsertBefore());
|
| else
|
| InsertNodeVector(targets, nullptr, AdoptAndAppendChild());
|
| +
|
| + // 16. Return child.
|
| return old_child;
|
| }
|
|
|
|
|