OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * (C) 2001 Dirk Mueller (mueller@kde.org) | 4 * (C) 2001 Dirk Mueller (mueller@kde.org) |
5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc. All rights | 5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc. All rights |
6 * reserved. | 6 * reserved. |
7 * | 7 * |
8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 Node* old_child, | 405 Node* old_child, |
406 ExceptionState& exception_state) { | 406 ExceptionState& exception_state) { |
407 // https://dom.spec.whatwg.org/#concept-node-replace | 407 // https://dom.spec.whatwg.org/#concept-node-replace |
408 | 408 |
409 if (!old_child) { | 409 if (!old_child) { |
410 exception_state.ThrowDOMException(kNotFoundError, | 410 exception_state.ThrowDOMException(kNotFoundError, |
411 "The node to be replaced is null."); | 411 "The node to be replaced is null."); |
412 return nullptr; | 412 return nullptr; |
413 } | 413 } |
414 | 414 |
415 // Make sure replacing the old child with the new is OK. | 415 // 1. If parent is not a Document, DocumentFragment, or Element node, throw a |
| 416 // HierarchyRequestError. |
| 417 // 2. If node is a host-including inclusive ancestor of parent, throw a |
| 418 // HierarchyRequestError. |
| 419 // 4. If node is not a DocumentFragment, DocumentType, Element, Text, |
| 420 // ProcessingInstruction, or Comment node, throw a HierarchyRequestError. |
| 421 // 5. If either node is a Text node and parent is a document, or node is a |
| 422 // doctype and parent is not a document, throw a HierarchyRequestError. |
| 423 // 6. If parent is a document, and any of the statements below, switched on |
| 424 // node, are true, throw a HierarchyRequestError. |
416 if (!CheckAcceptChild(new_child, old_child, exception_state)) | 425 if (!CheckAcceptChild(new_child, old_child, exception_state)) |
417 return old_child; | 426 return old_child; |
418 | 427 |
419 // NotFoundError: Raised if oldChild is not a child of this node. | 428 // 3. If child’s parent is not parent, then throw a NotFoundError. |
420 if (old_child->parentNode() != this) { | 429 if (old_child->parentNode() != this) { |
421 exception_state.ThrowDOMException( | 430 exception_state.ThrowDOMException( |
422 kNotFoundError, "The node to be replaced is not a child of this node."); | 431 kNotFoundError, "The node to be replaced is not a child of this node."); |
423 return nullptr; | 432 return nullptr; |
424 } | 433 } |
425 | 434 |
426 ChildListMutationScope mutation(*this); | |
427 // 7. Let reference child be child’s next sibling. | 435 // 7. Let reference child be child’s next sibling. |
428 Node* next = old_child->nextSibling(); | 436 Node* next = old_child->nextSibling(); |
429 // 8. If reference child is node, set it to node’s next sibling. | 437 // 8. If reference child is node, set it to node’s next sibling. |
430 if (next == new_child) | 438 if (next == new_child) |
431 next = new_child->nextSibling(); | 439 next = new_child->nextSibling(); |
432 | 440 |
433 // TODO(tkent): According to the specification, we should remove |newChild| | 441 // 10. Adopt node into parent’s node document. |
434 // from its parent here, and create a separated mutation record for it. | 442 // TODO(tkent): Actually we do only RemoveChild() as a part of 'adopt' |
435 // Refer to external/wpt/dom/nodes/MutationObserver-childList.html. | 443 // operation. |
| 444 // Though the following CollectChildrenAndRemoveFromOldParentWithCheck() also |
| 445 // calls RemoveChild(), we'd like to call RemoveChild() here to make a |
| 446 // separated MutationRecord. |
| 447 if (ContainerNode* new_child_parent = new_child->parentNode()) { |
| 448 new_child_parent->RemoveChild(new_child, exception_state); |
| 449 if (exception_state.HadException()) |
| 450 return nullptr; |
| 451 } |
| 452 |
| 453 // 9. Let previousSibling be child’s previous sibling. |
| 454 // 11. Let removedNodes be the empty list. |
| 455 // 15. Queue a mutation record of "childList" for target parent with |
| 456 // addedNodes nodes, removedNodes removedNodes, nextSibling reference child, |
| 457 // and previousSibling previousSibling. |
| 458 ChildListMutationScope mutation(*this); |
436 | 459 |
437 // 12. If child’s parent is not null, run these substeps: | 460 // 12. If child’s parent is not null, run these substeps: |
438 // 1. Set removedNodes to a list solely containing child. | 461 // 1. Set removedNodes to a list solely containing child. |
439 // 2. Remove child from its parent with the suppress observers flag set. | 462 // 2. Remove child from its parent with the suppress observers flag set. |
440 RemoveChild(old_child, exception_state); | 463 if (ContainerNode* old_child_parent = old_child->parentNode()) { |
441 if (exception_state.HadException()) | 464 old_child_parent->RemoveChild(old_child, exception_state); |
442 return nullptr; | 465 if (exception_state.HadException()) |
| 466 return nullptr; |
| 467 } |
443 | 468 |
444 // Does this one more time because removeChild() fires a MutationEvent. | 469 // Does this one more time because removeChild() fires a MutationEvent. |
445 if (!CheckAcceptChild(new_child, old_child, exception_state)) | 470 if (!CheckAcceptChild(new_child, old_child, exception_state)) |
446 return old_child; | 471 return old_child; |
447 | 472 |
| 473 // 13. Let nodes be node’s children if node is a DocumentFragment node, and a |
| 474 // list containing solely node otherwise. |
448 NodeVector targets; | 475 NodeVector targets; |
449 if (!CollectChildrenAndRemoveFromOldParentWithCheck( | 476 if (!CollectChildrenAndRemoveFromOldParentWithCheck( |
450 next, old_child, *new_child, targets, exception_state)) | 477 next, old_child, *new_child, targets, exception_state)) |
451 return old_child; | 478 return old_child; |
452 | 479 |
| 480 // 10. Adopt node into parent’s node document. |
| 481 // 14. Insert node into parent before reference child with the suppress |
| 482 // observers flag set. |
453 if (next) | 483 if (next) |
454 InsertNodeVector(targets, next, AdoptAndInsertBefore()); | 484 InsertNodeVector(targets, next, AdoptAndInsertBefore()); |
455 else | 485 else |
456 InsertNodeVector(targets, nullptr, AdoptAndAppendChild()); | 486 InsertNodeVector(targets, nullptr, AdoptAndAppendChild()); |
| 487 |
| 488 // 16. Return child. |
457 return old_child; | 489 return old_child; |
458 } | 490 } |
459 | 491 |
460 void ContainerNode::WillRemoveChild(Node& child) { | 492 void ContainerNode::WillRemoveChild(Node& child) { |
461 DCHECK_EQ(child.parentNode(), this); | 493 DCHECK_EQ(child.parentNode(), this); |
462 ChildListMutationScope(*this).WillRemoveChild(child); | 494 ChildListMutationScope(*this).WillRemoveChild(child); |
463 child.NotifyMutationObserversNodeWillDetach(); | 495 child.NotifyMutationObserversNodeWillDetach(); |
464 DispatchChildRemovalEvents(child); | 496 DispatchChildRemovalEvents(child); |
465 ChildFrameDisconnector(child).Disconnect(); | 497 ChildFrameDisconnector(child).Disconnect(); |
466 if (GetDocument() != child.GetDocument()) { | 498 if (GetDocument() != child.GetDocument()) { |
(...skipping 1071 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1538 return true; | 1570 return true; |
1539 | 1571 |
1540 if (node->IsElementNode() && ToElement(node)->Shadow()) | 1572 if (node->IsElementNode() && ToElement(node)->Shadow()) |
1541 return true; | 1573 return true; |
1542 | 1574 |
1543 return false; | 1575 return false; |
1544 } | 1576 } |
1545 #endif | 1577 #endif |
1546 | 1578 |
1547 } // namespace blink | 1579 } // namespace blink |
OLD | NEW |