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
reserved. | 5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc. All rights
reserved. |
6 * | 6 * |
7 * This library is free software; you can redistribute it and/or | 7 * This library is free software; you can redistribute it and/or |
8 * modify it under the terms of the GNU Library General Public | 8 * modify it under the terms of the GNU Library General Public |
9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
10 * version 2 of the License, or (at your option) any later version. | 10 * version 2 of the License, or (at your option) any later version. |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
311 newChild->updateAncestorConnectedSubframeCountForInsertion(); | 311 newChild->updateAncestorConnectedSubframeCountForInsertion(); |
312 | 312 |
313 ChildListMutationScope(*this).childAdded(*newChild); | 313 ChildListMutationScope(*this).childAdded(*newChild); |
314 | 314 |
315 ChildrenChange change = {ChildInserted, newChild->previousSibling(), &nextCh
ild, ChildrenChangeSourceParser}; | 315 ChildrenChange change = {ChildInserted, newChild->previousSibling(), &nextCh
ild, ChildrenChangeSourceParser}; |
316 childrenChanged(change); | 316 childrenChanged(change); |
317 | 317 |
318 notifyNodeInserted(*newChild); | 318 notifyNodeInserted(*newChild); |
319 } | 319 } |
320 | 320 |
321 void ContainerNode::replaceChild(PassRefPtrWillBeRawPtr<Node> newChild, Node* ol
dChild, ExceptionState& exceptionState) | 321 PassRefPtrWillBeRawPtr<Node> ContainerNode::replaceChild(PassRefPtrWillBeRawPtr<
Node> newChild, PassRefPtrWillBeRawPtr<Node> oldChild, ExceptionState& exception
State) |
322 { | 322 { |
323 #if !ENABLE(OILPAN) | 323 #if !ENABLE(OILPAN) |
324 // Check that this node is not "floating". | 324 // Check that this node is not "floating". |
325 // If it is, it can be deleted as a side effect of sending mutation events. | 325 // If it is, it can be deleted as a side effect of sending mutation events. |
326 ASSERT(refCount() || parentOrShadowHostNode()); | 326 ASSERT(refCount() || parentOrShadowHostNode()); |
327 #endif | 327 #endif |
328 | 328 |
329 RefPtrWillBeRawPtr<Node> protect(this); | 329 RefPtrWillBeRawPtr<Node> protect(this); |
330 | 330 |
331 if (oldChild == newChild) // nothing to do | 331 if (oldChild == newChild) // nothing to do |
332 return; | 332 return oldChild; |
333 | 333 |
334 if (!oldChild) { | 334 if (!oldChild) { |
335 exceptionState.throwDOMException(NotFoundError, "The node to be replaced
is null."); | 335 exceptionState.throwDOMException(NotFoundError, "The node to be replaced
is null."); |
336 return; | 336 return nullptr; |
337 } | 337 } |
338 | 338 |
| 339 RefPtrWillBeRawPtr<Node> child = oldChild; |
| 340 |
339 // Make sure replacing the old child with the new is ok | 341 // Make sure replacing the old child with the new is ok |
340 if (!checkAcceptChild(newChild.get(), oldChild, exceptionState)) | 342 if (!checkAcceptChild(newChild.get(), child.get(), exceptionState)) { |
341 return; | 343 if (exceptionState.hadException()) |
| 344 return nullptr; |
| 345 return child; |
| 346 } |
342 | 347 |
343 // NotFoundError: Raised if oldChild is not a child of this node. | 348 // NotFoundError: Raised if oldChild is not a child of this node. |
344 if (oldChild->parentNode() != this) { | 349 if (child->parentNode() != this) { |
345 exceptionState.throwDOMException(NotFoundError, "The node to be replaced
is not a child of this node."); | 350 exceptionState.throwDOMException(NotFoundError, "The node to be replaced
is not a child of this node."); |
346 return; | 351 return nullptr; |
347 } | 352 } |
348 | 353 |
349 ChildListMutationScope mutation(*this); | 354 ChildListMutationScope mutation(*this); |
350 | 355 |
351 RefPtrWillBeRawPtr<Node> next = oldChild->nextSibling(); | 356 RefPtrWillBeRawPtr<Node> next = child->nextSibling(); |
352 | 357 |
353 // Remove the node we're replacing | 358 // Remove the node we're replacing |
354 RefPtrWillBeRawPtr<Node> protectRemovedChild = oldChild; | 359 removeChild(child, exceptionState); |
355 ASSERT_UNUSED(protectRemovedChild, protectRemovedChild); | |
356 removeChild(oldChild, exceptionState); | |
357 if (exceptionState.hadException()) | 360 if (exceptionState.hadException()) |
358 return; | 361 return nullptr; |
359 | 362 |
360 if (next && (next->previousSibling() == newChild || next == newChild)) // no
thing to do | 363 if (next && (next->previousSibling() == newChild || next == newChild)) // no
thing to do |
361 return; | 364 return child; |
362 | 365 |
363 // Does this one more time because removeChild() fires a MutationEvent. | 366 // Does this one more time because removeChild() fires a MutationEvent. |
364 if (!checkAcceptChild(newChild.get(), oldChild, exceptionState)) | 367 if (!checkAcceptChild(newChild.get(), child.get(), exceptionState)) { |
365 return; | 368 if (exceptionState.hadException()) |
| 369 return nullptr; |
| 370 return child; |
| 371 } |
366 | 372 |
367 NodeVector targets; | 373 NodeVector targets; |
368 collectChildrenAndRemoveFromOldParent(*newChild, targets, exceptionState); | 374 collectChildrenAndRemoveFromOldParent(*newChild, targets, exceptionState); |
369 if (exceptionState.hadException()) | 375 if (exceptionState.hadException()) |
370 return; | 376 return nullptr; |
371 | 377 |
372 // Does this yet another check because collectChildrenAndRemoveFromOldParent
() fires a MutationEvent. | 378 // Does this yet another check because collectChildrenAndRemoveFromOldParent
() fires a MutationEvent. |
373 if (!checkAcceptChild(newChild.get(), oldChild, exceptionState)) | 379 if (!checkAcceptChild(newChild.get(), child.get(), exceptionState)) { |
374 return; | 380 if (exceptionState.hadException()) |
| 381 return nullptr; |
| 382 return child; |
| 383 } |
375 | 384 |
376 InspectorInstrumentation::willInsertDOMNode(this); | 385 InspectorInstrumentation::willInsertDOMNode(this); |
377 | 386 |
378 // Add the new child(ren) | 387 // Add the new child(ren) |
379 for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); +
+it) { | 388 for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); +
+it) { |
380 ASSERT(*it); | 389 ASSERT(*it); |
381 Node& child = **it; | 390 Node& child = **it; |
382 | 391 |
383 // Due to arbitrary code running in response to a DOM mutation event it'
s | 392 // Due to arbitrary code running in response to a DOM mutation event it'
s |
384 // possible that "next" is no longer a child of "this". | 393 // possible that "next" is no longer a child of "this". |
(...skipping 12 matching lines...) Expand all Loading... |
397 if (next) | 406 if (next) |
398 insertBeforeCommon(*next, child); | 407 insertBeforeCommon(*next, child); |
399 else | 408 else |
400 appendChildCommon(child); | 409 appendChildCommon(child); |
401 } | 410 } |
402 | 411 |
403 updateTreeAfterInsertion(child); | 412 updateTreeAfterInsertion(child); |
404 } | 413 } |
405 | 414 |
406 dispatchSubtreeModifiedEvent(); | 415 dispatchSubtreeModifiedEvent(); |
| 416 return child; |
407 } | 417 } |
408 | 418 |
409 void ContainerNode::willRemoveChild(Node& child) | 419 void ContainerNode::willRemoveChild(Node& child) |
410 { | 420 { |
411 ASSERT(child.parentNode() == this); | 421 ASSERT(child.parentNode() == this); |
412 ChildListMutationScope(*this).willRemoveChild(child); | 422 ChildListMutationScope(*this).willRemoveChild(child); |
413 child.notifyMutationObserversNodeWillDetach(); | 423 child.notifyMutationObserversNodeWillDetach(); |
414 dispatchChildRemovalEvents(child); | 424 dispatchChildRemovalEvents(child); |
415 document().nodeWillBeRemoved(child); // e.g. mutation event listener can cre
ate a new range. | 425 document().nodeWillBeRemoved(child); // e.g. mutation event listener can cre
ate a new range. |
416 ChildFrameDisconnector(child).disconnect(); | 426 ChildFrameDisconnector(child).disconnect(); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
504 ChildFrameDisconnector(*this).disconnect(); | 514 ChildFrameDisconnector(*this).disconnect(); |
505 } | 515 } |
506 | 516 |
507 void ContainerNode::trace(Visitor* visitor) | 517 void ContainerNode::trace(Visitor* visitor) |
508 { | 518 { |
509 visitor->trace(m_firstChild); | 519 visitor->trace(m_firstChild); |
510 visitor->trace(m_lastChild); | 520 visitor->trace(m_lastChild); |
511 Node::trace(visitor); | 521 Node::trace(visitor); |
512 } | 522 } |
513 | 523 |
514 void ContainerNode::removeChild(Node* oldChild, ExceptionState& exceptionState) | 524 PassRefPtrWillBeRawPtr<Node> ContainerNode::removeChild(PassRefPtrWillBeRawPtr<N
ode> oldChild, ExceptionState& exceptionState) |
515 { | 525 { |
516 #if !ENABLE(OILPAN) | 526 #if !ENABLE(OILPAN) |
517 // Check that this node is not "floating". | 527 // Check that this node is not "floating". |
518 // If it is, it can be deleted as a side effect of sending mutation events. | 528 // If it is, it can be deleted as a side effect of sending mutation events. |
519 ASSERT(refCount() || parentOrShadowHostNode()); | 529 ASSERT(refCount() || parentOrShadowHostNode()); |
520 #endif | 530 #endif |
521 | 531 |
522 RefPtrWillBeRawPtr<Node> protect(this); | 532 RefPtrWillBeRawPtr<Node> protect(this); |
523 | 533 |
524 // NotFoundError: Raised if oldChild is not a child of this node. | 534 // NotFoundError: Raised if oldChild is not a child of this node. |
525 // FIXME: We should never really get PseudoElements in here, but editing wil
l sometimes | 535 // FIXME: We should never really get PseudoElements in here, but editing wil
l sometimes |
526 // attempt to remove them still. We should fix that and enable this ASSERT. | 536 // attempt to remove them still. We should fix that and enable this ASSERT. |
527 // ASSERT(!oldChild->isPseudoElement()) | 537 // ASSERT(!oldChild->isPseudoElement()) |
528 if (!oldChild || oldChild->parentNode() != this || oldChild->isPseudoElement
()) { | 538 if (!oldChild || oldChild->parentNode() != this || oldChild->isPseudoElement
()) { |
529 exceptionState.throwDOMException(NotFoundError, "The node to be removed
is not a child of this node."); | 539 exceptionState.throwDOMException(NotFoundError, "The node to be removed
is not a child of this node."); |
530 return; | 540 return nullptr; |
531 } | 541 } |
532 | 542 |
533 RefPtrWillBeRawPtr<Node> child = oldChild; | 543 RefPtrWillBeRawPtr<Node> child = oldChild; |
534 | 544 |
535 document().removeFocusedElementOfSubtree(child.get()); | 545 document().removeFocusedElementOfSubtree(child.get()); |
536 | 546 |
537 if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExist
s(document())) | 547 if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExist
s(document())) |
538 fullscreen->removeFullScreenElementOfSubtree(child.get()); | 548 fullscreen->removeFullScreenElementOfSubtree(child.get()); |
539 | 549 |
540 // Events fired when blurring currently focused node might have moved this | 550 // Events fired when blurring currently focused node might have moved this |
541 // child into a different parent. | 551 // child into a different parent. |
542 if (child->parentNode() != this) { | 552 if (child->parentNode() != this) { |
543 exceptionState.throwDOMException(NotFoundError, "The node to be removed
is no longer a child of this node. Perhaps it was moved in a 'blur' event handle
r?"); | 553 exceptionState.throwDOMException(NotFoundError, "The node to be removed
is no longer a child of this node. Perhaps it was moved in a 'blur' event handle
r?"); |
544 return; | 554 return nullptr; |
545 } | 555 } |
546 | 556 |
547 willRemoveChild(*child); | 557 willRemoveChild(*child); |
548 | 558 |
549 // Mutation events might have moved this child into a different parent. | 559 // Mutation events might have moved this child into a different parent. |
550 if (child->parentNode() != this) { | 560 if (child->parentNode() != this) { |
551 exceptionState.throwDOMException(NotFoundError, "The node to be removed
is no longer a child of this node. Perhaps it was moved in response to a mutatio
n?"); | 561 exceptionState.throwDOMException(NotFoundError, "The node to be removed
is no longer a child of this node. Perhaps it was moved in response to a mutatio
n?"); |
552 return; | 562 return nullptr; |
553 } | 563 } |
554 | 564 |
555 { | 565 { |
556 HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates; | 566 HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates; |
557 | 567 |
558 Node* prev = child->previousSibling(); | 568 Node* prev = child->previousSibling(); |
559 Node* next = child->nextSibling(); | 569 Node* next = child->nextSibling(); |
560 removeBetween(prev, next, *child); | 570 removeBetween(prev, next, *child); |
561 ChildrenChange change = {ChildRemoved, prev, next, ChildrenChangeSourceA
PI}; | 571 ChildrenChange change = {ChildRemoved, prev, next, ChildrenChangeSourceA
PI}; |
562 childrenChanged(change); | 572 childrenChanged(change); |
563 notifyNodeRemoved(*child); | 573 notifyNodeRemoved(*child); |
564 } | 574 } |
565 dispatchSubtreeModifiedEvent(); | 575 dispatchSubtreeModifiedEvent(); |
| 576 return child; |
566 } | 577 } |
567 | 578 |
568 void ContainerNode::removeBetween(Node* previousChild, Node* nextChild, Node& ol
dChild) | 579 void ContainerNode::removeBetween(Node* previousChild, Node* nextChild, Node& ol
dChild) |
569 { | 580 { |
570 NoEventDispatchAssertion assertNoEventDispatch; | 581 NoEventDispatchAssertion assertNoEventDispatch; |
571 | 582 |
572 ASSERT(oldChild.parentNode() == this); | 583 ASSERT(oldChild.parentNode() == this); |
573 | 584 |
574 if (!oldChild.needsAttach()) | 585 if (!oldChild.needsAttach()) |
575 oldChild.detach(); | 586 oldChild.detach(); |
(...skipping 798 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1374 return true; | 1385 return true; |
1375 | 1386 |
1376 if (node->isElementNode() && toElement(node)->shadow()) | 1387 if (node->isElementNode() && toElement(node)->shadow()) |
1377 return true; | 1388 return true; |
1378 | 1389 |
1379 return false; | 1390 return false; |
1380 } | 1391 } |
1381 #endif | 1392 #endif |
1382 | 1393 |
1383 } // namespace WebCore | 1394 } // namespace WebCore |
OLD | NEW |