| 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 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 public: | 259 public: |
| 260 inline void operator()(ContainerNode& container, Node& child, Node*) const { | 260 inline void operator()(ContainerNode& container, Node& child, Node*) const { |
| 261 container.treeScope().adoptIfNeeded(child); | 261 container.treeScope().adoptIfNeeded(child); |
| 262 container.appendChildCommon(child); | 262 container.appendChildCommon(child); |
| 263 } | 263 } |
| 264 }; | 264 }; |
| 265 | 265 |
| 266 Node* ContainerNode::insertBefore(Node* newChild, | 266 Node* ContainerNode::insertBefore(Node* newChild, |
| 267 Node* refChild, | 267 Node* refChild, |
| 268 ExceptionState& exceptionState) { | 268 ExceptionState& exceptionState) { |
| 269 // https://dom.spec.whatwg.org/#concept-node-pre-insert |
| 270 |
| 269 // insertBefore(node, 0) is equivalent to appendChild(node) | 271 // insertBefore(node, 0) is equivalent to appendChild(node) |
| 270 if (!refChild) | 272 if (!refChild) |
| 271 return appendChild(newChild, exceptionState); | 273 return appendChild(newChild, exceptionState); |
| 272 | 274 |
| 273 // Make sure adding the new child is OK. | 275 // Make sure adding the new child is OK. |
| 274 if (!checkAcceptChild(newChild, 0, exceptionState)) | 276 if (!checkAcceptChild(newChild, 0, exceptionState)) |
| 275 return newChild; | 277 return newChild; |
| 276 DCHECK(newChild); | 278 DCHECK(newChild); |
| 277 | 279 |
| 278 // NotFoundError: Raised if refChild is not a child of this node | 280 // NotFoundError: Raised if refChild is not a child of this node |
| 279 if (refChild->parentNode() != this) { | 281 if (refChild->parentNode() != this) { |
| 280 exceptionState.throwDOMException(NotFoundError, | 282 exceptionState.throwDOMException(NotFoundError, |
| 281 "The node before which the new node is to " | 283 "The node before which the new node is to " |
| 282 "be inserted is not a child of this " | 284 "be inserted is not a child of this " |
| 283 "node."); | 285 "node."); |
| 284 return nullptr; | 286 return nullptr; |
| 285 } | 287 } |
| 286 | 288 |
| 287 // Nothing to do. | 289 // 3. If reference child is node, set it to node’s next sibling. |
| 288 if (refChild->previousSibling() == newChild || refChild == newChild) | 290 if (refChild == newChild) { |
| 289 return newChild; | 291 refChild = newChild->nextSibling(); |
| 292 if (!refChild) |
| 293 return appendChild(newChild, exceptionState); |
| 294 } |
| 290 | 295 |
| 291 NodeVector targets; | 296 NodeVector targets; |
| 292 if (!collectChildrenAndRemoveFromOldParentWithCheck( | 297 if (!collectChildrenAndRemoveFromOldParentWithCheck( |
| 293 refChild, nullptr, *newChild, targets, exceptionState)) | 298 refChild, nullptr, *newChild, targets, exceptionState)) |
| 294 return newChild; | 299 return newChild; |
| 295 | 300 |
| 296 ChildListMutationScope mutation(*this); | 301 ChildListMutationScope mutation(*this); |
| 297 insertNodeVector(targets, refChild, AdoptAndInsertBefore()); | 302 insertNodeVector(targets, refChild, AdoptAndInsertBefore()); |
| 298 return newChild; | 303 return newChild; |
| 299 } | 304 } |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 384 DCHECK_EQ(newChild->connectedSubframeCount(), 0u); | 389 DCHECK_EQ(newChild->connectedSubframeCount(), 0u); |
| 385 ChildListMutationScope(*this).childAdded(*newChild); | 390 ChildListMutationScope(*this).childAdded(*newChild); |
| 386 } | 391 } |
| 387 | 392 |
| 388 notifyNodeInserted(*newChild, ChildrenChangeSourceParser); | 393 notifyNodeInserted(*newChild, ChildrenChangeSourceParser); |
| 389 } | 394 } |
| 390 | 395 |
| 391 Node* ContainerNode::replaceChild(Node* newChild, | 396 Node* ContainerNode::replaceChild(Node* newChild, |
| 392 Node* oldChild, | 397 Node* oldChild, |
| 393 ExceptionState& exceptionState) { | 398 ExceptionState& exceptionState) { |
| 394 if (oldChild == newChild) // Nothing to do. | 399 // https://dom.spec.whatwg.org/#concept-node-replace |
| 395 return oldChild; | |
| 396 | 400 |
| 397 if (!oldChild) { | 401 if (!oldChild) { |
| 398 exceptionState.throwDOMException(NotFoundError, | 402 exceptionState.throwDOMException(NotFoundError, |
| 399 "The node to be replaced is null."); | 403 "The node to be replaced is null."); |
| 400 return nullptr; | 404 return nullptr; |
| 401 } | 405 } |
| 402 | 406 |
| 403 // Make sure replacing the old child with the new is OK. | 407 // Make sure replacing the old child with the new is OK. |
| 404 if (!checkAcceptChild(newChild, oldChild, exceptionState)) | 408 if (!checkAcceptChild(newChild, oldChild, exceptionState)) |
| 405 return oldChild; | 409 return oldChild; |
| 406 | 410 |
| 407 // NotFoundError: Raised if oldChild is not a child of this node. | 411 // NotFoundError: Raised if oldChild is not a child of this node. |
| 408 if (oldChild->parentNode() != this) { | 412 if (oldChild->parentNode() != this) { |
| 409 exceptionState.throwDOMException( | 413 exceptionState.throwDOMException( |
| 410 NotFoundError, "The node to be replaced is not a child of this node."); | 414 NotFoundError, "The node to be replaced is not a child of this node."); |
| 411 return nullptr; | 415 return nullptr; |
| 412 } | 416 } |
| 413 | 417 |
| 414 ChildListMutationScope mutation(*this); | 418 ChildListMutationScope mutation(*this); |
| 419 // 7. Let reference child be child’s next sibling. |
| 415 Node* next = oldChild->nextSibling(); | 420 Node* next = oldChild->nextSibling(); |
| 421 // 8. If reference child is node, set it to node’s next sibling. |
| 422 if (next == newChild) |
| 423 next = newChild->nextSibling(); |
| 416 | 424 |
| 417 // Remove the node we're replacing. | 425 // TODO(tkent): According to the specification, we should remove |newChild| |
| 426 // from its parent here, and create a separated mutation record for it. |
| 427 // Refer to imported/wpt/dom/nodes/MutationObserver-childList.html. |
| 428 |
| 429 // 12. If child’s parent is not null, run these substeps: |
| 430 // 1. Set removedNodes to a list solely containing child. |
| 431 // 2. Remove child from its parent with the suppress observers flag set. |
| 418 removeChild(oldChild, exceptionState); | 432 removeChild(oldChild, exceptionState); |
| 419 if (exceptionState.hadException()) | 433 if (exceptionState.hadException()) |
| 420 return nullptr; | 434 return nullptr; |
| 421 | 435 |
| 422 if (next && (next->previousSibling() == newChild || | |
| 423 next == newChild)) // nothing to do | |
| 424 return oldChild; | |
| 425 | |
| 426 // Does this one more time because removeChild() fires a MutationEvent. | 436 // Does this one more time because removeChild() fires a MutationEvent. |
| 427 if (!checkAcceptChild(newChild, oldChild, exceptionState)) | 437 if (!checkAcceptChild(newChild, oldChild, exceptionState)) |
| 428 return oldChild; | 438 return oldChild; |
| 429 | 439 |
| 430 NodeVector targets; | 440 NodeVector targets; |
| 431 if (!collectChildrenAndRemoveFromOldParentWithCheck(next, oldChild, *newChild, | 441 if (!collectChildrenAndRemoveFromOldParentWithCheck(next, oldChild, *newChild, |
| 432 targets, exceptionState)) | 442 targets, exceptionState)) |
| 433 return oldChild; | 443 return oldChild; |
| 434 | 444 |
| 435 if (next) | 445 if (next) |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 642 dispatchSubtreeModifiedEvent(); | 652 dispatchSubtreeModifiedEvent(); |
| 643 } | 653 } |
| 644 | 654 |
| 645 Node* ContainerNode::appendChild(Node* newChild, | 655 Node* ContainerNode::appendChild(Node* newChild, |
| 646 ExceptionState& exceptionState) { | 656 ExceptionState& exceptionState) { |
| 647 // Make sure adding the new child is ok | 657 // Make sure adding the new child is ok |
| 648 if (!checkAcceptChild(newChild, 0, exceptionState)) | 658 if (!checkAcceptChild(newChild, 0, exceptionState)) |
| 649 return newChild; | 659 return newChild; |
| 650 DCHECK(newChild); | 660 DCHECK(newChild); |
| 651 | 661 |
| 652 if (newChild == m_lastChild) // nothing to do | |
| 653 return newChild; | |
| 654 | |
| 655 NodeVector targets; | 662 NodeVector targets; |
| 656 if (!collectChildrenAndRemoveFromOldParentWithCheck( | 663 if (!collectChildrenAndRemoveFromOldParentWithCheck( |
| 657 nullptr, nullptr, *newChild, targets, exceptionState)) | 664 nullptr, nullptr, *newChild, targets, exceptionState)) |
| 658 return newChild; | 665 return newChild; |
| 659 | 666 |
| 660 ChildListMutationScope mutation(*this); | 667 ChildListMutationScope mutation(*this); |
| 661 insertNodeVector(targets, nullptr, AdoptAndAppendChild()); | 668 insertNodeVector(targets, nullptr, AdoptAndAppendChild()); |
| 662 return newChild; | 669 return newChild; |
| 663 } | 670 } |
| 664 | 671 |
| (...skipping 805 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1470 return true; | 1477 return true; |
| 1471 | 1478 |
| 1472 if (node->isElementNode() && toElement(node)->shadow()) | 1479 if (node->isElementNode() && toElement(node)->shadow()) |
| 1473 return true; | 1480 return true; |
| 1474 | 1481 |
| 1475 return false; | 1482 return false; |
| 1476 } | 1483 } |
| 1477 #endif | 1484 #endif |
| 1478 | 1485 |
| 1479 } // namespace blink | 1486 } // namespace blink |
| OLD | NEW |