Allow implicit conversion from Ref<T> to T&
[WebKit-https.git] / Source / WebCore / dom / ContainerNode.cpp
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2001 Dirk Mueller (mueller@kde.org)
5  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public License
18  * along with this library; see the file COPYING.LIB.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22
23 #include "config.h"
24 #include "ContainerNode.h"
25
26 #include "AXObjectCache.h"
27 #include "ChildListMutationScope.h"
28 #include "Chrome.h"
29 #include "ChromeClient.h"
30 #include "ClassNodeList.h"
31 #include "ContainerNodeAlgorithms.h"
32 #include "Editor.h"
33 #include "FloatRect.h"
34 #include "FrameView.h"
35 #include "InlineTextBox.h"
36 #include "InsertionPoint.h"
37 #include "JSLazyEventListener.h"
38 #include "JSNode.h"
39 #include "LabelsNodeList.h"
40 #include "MutationEvent.h"
41 #include "NameNodeList.h"
42 #include "NodeRareData.h"
43 #include "NodeRenderStyle.h"
44 #include "RadioNodeList.h"
45 #include "RenderBox.h"
46 #include "RenderTheme.h"
47 #include "RenderWidget.h"
48 #include "ResourceLoadScheduler.h"
49 #include "RootInlineBox.h"
50 #include "SVGDocumentExtensions.h"
51 #include "SVGElement.h"
52 #include "SVGNames.h"
53 #include "SelectorQuery.h"
54 #include "TemplateContentDocumentFragment.h"
55 #include <wtf/CurrentTime.h>
56
57 #if ENABLE(DELETION_UI)
58 #include "DeleteButtonController.h"
59 #endif
60
61 namespace WebCore {
62
63 static void dispatchChildInsertionEvents(Node&);
64 static void dispatchChildRemovalEvents(Node&);
65
66 ChildNodesLazySnapshot* ChildNodesLazySnapshot::latestSnapshot = 0;
67
68 #ifndef NDEBUG
69 unsigned NoEventDispatchAssertion::s_count = 0;
70 #endif
71
72 static void collectChildrenAndRemoveFromOldParent(Node& node, NodeVector& nodes, ExceptionCode& ec)
73 {
74     if (!is<DocumentFragment>(node)) {
75         nodes.append(node);
76         if (ContainerNode* oldParent = node.parentNode())
77             oldParent->removeChild(&node, ec);
78         return;
79     }
80
81     getChildNodes(node, nodes);
82     downcast<DocumentFragment>(node).removeChildren();
83 }
84
85 // FIXME: This function must get a new name.
86 // It removes all children, not just a category called "detached children".
87 // So this name is terribly confusing.
88 void ContainerNode::removeDetachedChildren()
89 {
90     if (connectedSubframeCount()) {
91         for (Node* child = firstChild(); child; child = child->nextSibling())
92             child->updateAncestorConnectedSubframeCountForRemoval();
93     }
94     // FIXME: We should be able to ASSERT(!attached()) here: https://bugs.webkit.org/show_bug.cgi?id=107801
95     removeDetachedChildrenInContainer<Node, ContainerNode>(*this);
96 }
97
98 static inline void destroyRenderTreeIfNeeded(Node& child)
99 {
100     // FIXME: Get rid of the named flow test.
101     if (!child.renderer() && !child.isNamedFlowContentNode())
102         return;
103     if (is<Element>(child))
104         Style::detachRenderTree(downcast<Element>(child));
105     else if (is<Text>(child))
106         Style::detachTextRenderer(downcast<Text>(child));
107 }
108
109 void ContainerNode::takeAllChildrenFrom(ContainerNode* oldParent)
110 {
111     ASSERT(oldParent);
112
113     NodeVector children;
114     getChildNodes(*oldParent, children);
115
116     if (oldParent->document().hasMutationObserversOfType(MutationObserver::ChildList)) {
117         ChildListMutationScope mutation(*oldParent);
118         for (auto& child : children)
119             mutation.willRemoveChild(child);
120     }
121
122     // FIXME: We need to do notifyMutationObserversNodeWillDetach() for each child,
123     // probably inside removeDetachedChildrenInContainer.
124
125     oldParent->removeDetachedChildren();
126
127     for (auto& child : children) {
128         destroyRenderTreeIfNeeded(child);
129
130         // FIXME: We need a no mutation event version of adoptNode.
131         RefPtr<Node> adoptedChild = document().adoptNode(&child.get(), ASSERT_NO_EXCEPTION);
132         parserAppendChild(adoptedChild.get());
133         // FIXME: Together with adoptNode above, the tree scope might get updated recursively twice
134         // (if the document changed or oldParent was in a shadow tree, AND *this is in a shadow tree).
135         // Can we do better?
136         treeScope().adoptIfNeeded(adoptedChild.get());
137     }
138 }
139
140 ContainerNode::~ContainerNode()
141 {
142     if (!isDocumentNode())
143         willBeDeletedFrom(document());
144     removeDetachedChildren();
145 }
146
147 static inline bool isChildTypeAllowed(ContainerNode* newParent, Node* child)
148 {
149     if (!child->isDocumentFragment())
150         return newParent->childTypeAllowed(child->nodeType());
151
152     for (Node* node = child->firstChild(); node; node = node->nextSibling()) {
153         if (!newParent->childTypeAllowed(node->nodeType()))
154             return false;
155     }
156     return true;
157 }
158
159 static inline bool isInTemplateContent(const Node* node)
160 {
161 #if ENABLE(TEMPLATE_ELEMENT)
162     Document& document = node->document();
163     return &document == document.templateDocument();
164 #else
165     UNUSED_PARAM(node);
166     return false;
167 #endif
168 }
169
170 static inline bool containsConsideringHostElements(const Node* newChild, const Node* newParent)
171 {
172     return (newParent->isInShadowTree() || isInTemplateContent(newParent))
173         ? newChild->containsIncludingHostElements(newParent)
174         : newChild->contains(newParent);
175 }
176
177 static inline ExceptionCode checkAcceptChild(ContainerNode* newParent, Node* newChild, Node* oldChild)
178 {
179     // Not mentioned in spec: throw NOT_FOUND_ERR if newChild is null
180     if (!newChild)
181         return NOT_FOUND_ERR;
182
183     // Use common case fast path if possible.
184     if ((newChild->isElementNode() || newChild->isTextNode()) && newParent->isElementNode()) {
185         ASSERT(!newParent->isReadOnlyNode());
186         ASSERT(!newParent->isDocumentTypeNode());
187         ASSERT(isChildTypeAllowed(newParent, newChild));
188         if (containsConsideringHostElements(newChild, newParent))
189             return HIERARCHY_REQUEST_ERR;
190         return 0;
191     }
192
193     // This should never happen, but also protect release builds from tree corruption.
194     ASSERT(!newChild->isPseudoElement());
195     if (newChild->isPseudoElement())
196         return HIERARCHY_REQUEST_ERR;
197
198     if (newParent->isReadOnlyNode())
199         return NO_MODIFICATION_ALLOWED_ERR;
200     if (containsConsideringHostElements(newChild, newParent))
201         return HIERARCHY_REQUEST_ERR;
202
203     if (oldChild && is<Document>(*newParent)) {
204         if (!downcast<Document>(*newParent).canReplaceChild(newChild, oldChild))
205             return HIERARCHY_REQUEST_ERR;
206     } else if (!isChildTypeAllowed(newParent, newChild))
207         return HIERARCHY_REQUEST_ERR;
208
209     return 0;
210 }
211
212 static inline bool checkAcceptChildGuaranteedNodeTypes(ContainerNode* newParent, Node* newChild, ExceptionCode& ec)
213 {
214     ASSERT(!newParent->isReadOnlyNode());
215     ASSERT(!newParent->isDocumentTypeNode());
216     ASSERT(isChildTypeAllowed(newParent, newChild));
217     if (newChild->contains(newParent)) {
218         ec = HIERARCHY_REQUEST_ERR;
219         return false;
220     }
221
222     return true;
223 }
224
225 static inline bool checkAddChild(ContainerNode* newParent, Node* newChild, ExceptionCode& ec)
226 {
227     ec = checkAcceptChild(newParent, newChild, 0);
228     if (ec)
229         return false;
230
231     return true;
232 }
233
234 static inline bool checkReplaceChild(ContainerNode* newParent, Node* newChild, Node* oldChild, ExceptionCode& ec)
235 {
236     ec = checkAcceptChild(newParent, newChild, oldChild);
237     if (ec)
238         return false;
239
240     return true;
241 }
242
243 bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode& ec)
244 {
245     // Check that this node is not "floating".
246     // If it is, it can be deleted as a side effect of sending mutation events.
247     ASSERT(refCount() || parentOrShadowHostNode());
248
249     Ref<ContainerNode> protect(*this);
250
251     ec = 0;
252
253     // insertBefore(node, 0) is equivalent to appendChild(node)
254     if (!refChild)
255         return appendChild(newChild, ec);
256
257     // Make sure adding the new child is OK.
258     if (!checkAddChild(this, newChild.get(), ec))
259         return false;
260
261     // NOT_FOUND_ERR: Raised if refChild is not a child of this node
262     if (refChild->parentNode() != this) {
263         ec = NOT_FOUND_ERR;
264         return false;
265     }
266
267     if (refChild->previousSibling() == newChild || refChild == newChild) // nothing to do
268         return true;
269
270     Ref<Node> next(*refChild);
271
272     NodeVector targets;
273     collectChildrenAndRemoveFromOldParent(*newChild.get(), targets, ec);
274     if (ec)
275         return false;
276     if (targets.isEmpty())
277         return true;
278
279     // We need this extra check because collectChildrenAndRemoveFromOldParent() can fire mutation events.
280     if (!checkAcceptChildGuaranteedNodeTypes(this, newChild.get(), ec))
281         return false;
282
283     InspectorInstrumentation::willInsertDOMNode(&document(), this);
284
285     ChildListMutationScope mutation(*this);
286     for (auto it = targets.begin(), end = targets.end(); it != end; ++it) {
287         Node& child = it->get();
288
289         // Due to arbitrary code running in response to a DOM mutation event it's
290         // possible that "next" is no longer a child of "this".
291         // It's also possible that "child" has been inserted elsewhere.
292         // In either of those cases, we'll just stop.
293         if (next->parentNode() != this)
294             break;
295         if (child.parentNode())
296             break;
297
298         treeScope().adoptIfNeeded(&child);
299
300         insertBeforeCommon(next, child);
301
302         updateTreeAfterInsertion(child);
303     }
304
305     dispatchSubtreeModifiedEvent();
306     return true;
307 }
308
309 void ContainerNode::insertBeforeCommon(Node& nextChild, Node& newChild)
310 {
311     NoEventDispatchAssertion assertNoEventDispatch;
312
313     ASSERT(!newChild.parentNode()); // Use insertBefore if you need to handle reparenting (and want DOM mutation events).
314     ASSERT(!newChild.nextSibling());
315     ASSERT(!newChild.previousSibling());
316     ASSERT(!newChild.isShadowRoot());
317
318     Node* prev = nextChild.previousSibling();
319     ASSERT(m_lastChild != prev);
320     nextChild.setPreviousSibling(&newChild);
321     if (prev) {
322         ASSERT(m_firstChild != &nextChild);
323         ASSERT(prev->nextSibling() == &nextChild);
324         prev->setNextSibling(&newChild);
325     } else {
326         ASSERT(m_firstChild == &nextChild);
327         m_firstChild = &newChild;
328     }
329     newChild.setParentNode(this);
330     newChild.setPreviousSibling(prev);
331     newChild.setNextSibling(&nextChild);
332 }
333
334 void ContainerNode::notifyChildInserted(Node& child, ChildChangeSource source)
335 {
336     ChildChange change;
337     change.type = child.isElementNode() ? ElementInserted : child.isTextNode() ? TextInserted : NonContentsChildChanged;
338     change.previousSiblingElement = ElementTraversal::previousSibling(&child);
339     change.nextSiblingElement = ElementTraversal::nextSibling(&child);
340     change.source = source;
341
342     childrenChanged(change);
343 }
344
345 void ContainerNode::notifyChildRemoved(Node& child, Node* previousSibling, Node* nextSibling, ChildChangeSource source)
346 {
347     ChildChange change;
348     change.type = is<Element>(child) ? ElementRemoved : is<Text>(child) ? TextRemoved : NonContentsChildChanged;
349     change.previousSiblingElement = (!previousSibling || is<Element>(*previousSibling)) ? downcast<Element>(previousSibling) : ElementTraversal::previousSibling(previousSibling);
350     change.nextSiblingElement = (!nextSibling || is<Element>(*nextSibling)) ? downcast<Element>(nextSibling) : ElementTraversal::nextSibling(nextSibling);
351     change.source = source;
352
353     childrenChanged(change);
354 }
355
356 void ContainerNode::parserInsertBefore(PassRefPtr<Node> newChild, Node* nextChild)
357 {
358     ASSERT(newChild);
359     ASSERT(nextChild);
360     ASSERT(nextChild->parentNode() == this);
361     ASSERT(!newChild->isDocumentFragment());
362 #if ENABLE(TEMPLATE_ELEMENT)
363     ASSERT(!hasTagName(HTMLNames::templateTag));
364 #endif
365
366     if (nextChild->previousSibling() == newChild || nextChild == newChild) // nothing to do
367         return;
368
369     if (&document() != &newChild->document())
370         document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION);
371
372     insertBeforeCommon(*nextChild, *newChild.get());
373
374     newChild->updateAncestorConnectedSubframeCountForInsertion();
375
376     ChildListMutationScope(*this).childAdded(*newChild);
377
378     notifyChildInserted(*newChild, ChildChangeSourceParser);
379
380     ChildNodeInsertionNotifier(*this).notify(*newChild);
381
382     newChild->setNeedsStyleRecalc(ReconstructRenderTree);
383 }
384
385 bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode& ec)
386 {
387     // Check that this node is not "floating".
388     // If it is, it can be deleted as a side effect of sending mutation events.
389     ASSERT(refCount() || parentOrShadowHostNode());
390
391     Ref<ContainerNode> protect(*this);
392
393     ec = 0;
394
395     if (oldChild == newChild) // nothing to do
396         return true;
397
398     if (!oldChild) {
399         ec = NOT_FOUND_ERR;
400         return false;
401     }
402
403     // Make sure replacing the old child with the new is ok
404     if (!checkReplaceChild(this, newChild.get(), oldChild, ec))
405         return false;
406
407     // NOT_FOUND_ERR: Raised if oldChild is not a child of this node.
408     if (oldChild->parentNode() != this) {
409         ec = NOT_FOUND_ERR;
410         return false;
411     }
412
413     ChildListMutationScope mutation(*this);
414
415     RefPtr<Node> next = oldChild->nextSibling();
416
417     // Remove the node we're replacing
418     Ref<Node> removedChild(*oldChild);
419     removeChild(oldChild, ec);
420     if (ec)
421         return false;
422
423     if (next && (next->previousSibling() == newChild || next == newChild)) // nothing to do
424         return true;
425
426     // Does this one more time because removeChild() fires a MutationEvent.
427     if (!checkReplaceChild(this, newChild.get(), oldChild, ec))
428         return false;
429
430     NodeVector targets;
431     collectChildrenAndRemoveFromOldParent(*newChild.get(), targets, ec);
432     if (ec)
433         return false;
434
435     // Does this yet another check because collectChildrenAndRemoveFromOldParent() fires a MutationEvent.
436     if (!checkReplaceChild(this, newChild.get(), oldChild, ec))
437         return false;
438
439     InspectorInstrumentation::willInsertDOMNode(&document(), this);
440
441     // Add the new child(ren)
442     for (auto it = targets.begin(), end = targets.end(); it != end; ++it) {
443         Node& child = it->get();
444
445         // Due to arbitrary code running in response to a DOM mutation event it's
446         // possible that "next" is no longer a child of "this".
447         // It's also possible that "child" has been inserted elsewhere.
448         // In either of those cases, we'll just stop.
449         if (next && next->parentNode() != this)
450             break;
451         if (child.parentNode())
452             break;
453
454         treeScope().adoptIfNeeded(&child);
455
456         // Add child before "next".
457         {
458             NoEventDispatchAssertion assertNoEventDispatch;
459             if (next)
460                 insertBeforeCommon(*next, child);
461             else
462                 appendChildToContainer(&child, *this);
463         }
464
465         updateTreeAfterInsertion(child);
466     }
467
468     dispatchSubtreeModifiedEvent();
469     return true;
470 }
471
472 void ContainerNode::willRemoveChild(Node& child)
473 {
474     ASSERT(child.parentNode());
475
476     ChildListMutationScope(*child.parentNode()).willRemoveChild(child);
477     child.notifyMutationObserversNodeWillDetach();
478     dispatchChildRemovalEvents(child);
479
480     if (child.parentNode() != this)
481         return;
482
483     child.document().nodeWillBeRemoved(&child); // e.g. mutation event listener can create a new range.
484     if (is<ContainerNode>(child))
485         disconnectSubframesIfNeeded(downcast<ContainerNode>(child), RootAndDescendants);
486 }
487
488 static void willRemoveChildren(ContainerNode& container)
489 {
490     NodeVector children;
491     getChildNodes(container, children);
492
493     ChildListMutationScope mutation(container);
494     for (auto it = children.begin(); it != children.end(); ++it) {
495         Node& child = it->get();
496         mutation.willRemoveChild(child);
497         child.notifyMutationObserversNodeWillDetach();
498
499         // fire removed from document mutation events.
500         dispatchChildRemovalEvents(child);
501     }
502
503     container.document().nodeChildrenWillBeRemoved(container);
504
505     disconnectSubframesIfNeeded(container, DescendantsOnly);
506 }
507
508 void ContainerNode::disconnectDescendantFrames()
509 {
510     disconnectSubframesIfNeeded(*this, RootAndDescendants);
511 }
512
513 bool ContainerNode::removeChild(Node* oldChild, ExceptionCode& ec)
514 {
515     // Check that this node is not "floating".
516     // If it is, it can be deleted as a side effect of sending mutation events.
517     ASSERT(refCount() || parentOrShadowHostNode());
518
519     Ref<ContainerNode> protect(*this);
520
521     ec = 0;
522
523     // NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
524     if (isReadOnlyNode()) {
525         ec = NO_MODIFICATION_ALLOWED_ERR;
526         return false;
527     }
528
529     // NOT_FOUND_ERR: Raised if oldChild is not a child of this node.
530     if (!oldChild || oldChild->parentNode() != this) {
531         ec = NOT_FOUND_ERR;
532         return false;
533     }
534
535     Ref<Node> child(*oldChild);
536
537     document().removeFocusedNodeOfSubtree(&child.get());
538
539 #if ENABLE(FULLSCREEN_API)
540     document().removeFullScreenElementOfSubtree(&child.get());
541 #endif
542
543     // Events fired when blurring currently focused node might have moved this
544     // child into a different parent.
545     if (child->parentNode() != this) {
546         ec = NOT_FOUND_ERR;
547         return false;
548     }
549
550     willRemoveChild(child);
551
552     // Mutation events might have moved this child into a different parent.
553     if (child->parentNode() != this) {
554         ec = NOT_FOUND_ERR;
555         return false;
556     }
557
558     {
559         WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
560
561         Node* prev = child->previousSibling();
562         Node* next = child->nextSibling();
563         removeBetween(prev, next, child);
564
565         notifyChildRemoved(child, prev, next, ChildChangeSourceAPI);
566
567         ChildNodeRemovalNotifier(*this).notify(child);
568     }
569
570
571     if (document().svgExtensions()) {
572         Element* shadowHost = this->shadowHost();
573         if (!shadowHost || !shadowHost->hasTagName(SVGNames::useTag))
574             document().accessSVGExtensions().rebuildElements();
575     }
576
577     dispatchSubtreeModifiedEvent();
578
579     return true;
580 }
581
582 void ContainerNode::removeBetween(Node* previousChild, Node* nextChild, Node& oldChild)
583 {
584     InspectorInstrumentation::didRemoveDOMNode(&oldChild.document(), &oldChild);
585
586     NoEventDispatchAssertion assertNoEventDispatch;
587
588     ASSERT(oldChild.parentNode() == this);
589
590     destroyRenderTreeIfNeeded(oldChild);
591
592     if (nextChild)
593         nextChild->setPreviousSibling(previousChild);
594     if (previousChild)
595         previousChild->setNextSibling(nextChild);
596     if (m_firstChild == &oldChild)
597         m_firstChild = nextChild;
598     if (m_lastChild == &oldChild)
599         m_lastChild = previousChild;
600
601     oldChild.setPreviousSibling(0);
602     oldChild.setNextSibling(0);
603     oldChild.setParentNode(0);
604
605     document().adoptIfNeeded(&oldChild);
606 }
607
608 void ContainerNode::parserRemoveChild(Node& oldChild)
609 {
610     ASSERT(oldChild.parentNode() == this);
611     ASSERT(!oldChild.isDocumentFragment());
612
613     Node* prev = oldChild.previousSibling();
614     Node* next = oldChild.nextSibling();
615
616     oldChild.updateAncestorConnectedSubframeCountForRemoval();
617
618     ChildListMutationScope(*this).willRemoveChild(oldChild);
619     oldChild.notifyMutationObserversNodeWillDetach();
620
621     removeBetween(prev, next, oldChild);
622
623     notifyChildRemoved(oldChild, prev, next, ChildChangeSourceParser);
624
625     ChildNodeRemovalNotifier(*this).notify(oldChild);
626 }
627
628 // this differs from other remove functions because it forcibly removes all the children,
629 // regardless of read-only status or event exceptions, e.g.
630 void ContainerNode::removeChildren()
631 {
632     if (!m_firstChild)
633         return;
634
635     // The container node can be removed from event handlers.
636     Ref<ContainerNode> protect(*this);
637
638     // exclude this node when looking for removed focusedNode since only children will be removed
639     document().removeFocusedNodeOfSubtree(this, true);
640
641 #if ENABLE(FULLSCREEN_API)
642     document().removeFullScreenElementOfSubtree(this, true);
643 #endif
644
645     // Do any prep work needed before actually starting to detach
646     // and remove... e.g. stop loading frames, fire unload events.
647     willRemoveChildren(*this);
648
649     NodeVector removedChildren;
650     {
651         WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
652         {
653             NoEventDispatchAssertion assertNoEventDispatch;
654             removedChildren.reserveInitialCapacity(countChildNodes());
655             while (RefPtr<Node> n = m_firstChild) {
656                 removedChildren.append(*m_firstChild);
657                 removeBetween(0, m_firstChild->nextSibling(), *m_firstChild);
658             }
659         }
660
661         ChildChange change = { AllChildrenRemoved, nullptr, nullptr, ChildChangeSourceAPI };
662         childrenChanged(change);
663         
664         for (auto& removedChild : removedChildren)
665             ChildNodeRemovalNotifier(*this).notify(removedChild);
666     }
667
668     if (document().svgExtensions()) {
669         Element* shadowHost = this->shadowHost();
670         if (!shadowHost || !shadowHost->hasTagName(SVGNames::useTag))
671             document().accessSVGExtensions().rebuildElements();
672     }
673
674     dispatchSubtreeModifiedEvent();
675 }
676
677 bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec)
678 {
679     Ref<ContainerNode> protect(*this);
680
681     // Check that this node is not "floating".
682     // If it is, it can be deleted as a side effect of sending mutation events.
683     ASSERT(refCount() || parentOrShadowHostNode());
684
685     ec = 0;
686
687     // Make sure adding the new child is ok
688     if (!checkAddChild(this, newChild.get(), ec))
689         return false;
690
691     if (newChild == m_lastChild) // nothing to do
692         return newChild;
693
694     NodeVector targets;
695     collectChildrenAndRemoveFromOldParent(*newChild.get(), targets, ec);
696     if (ec)
697         return false;
698
699     if (targets.isEmpty())
700         return true;
701
702     // We need this extra check because collectChildrenAndRemoveFromOldParent() can fire mutation events.
703     if (!checkAcceptChildGuaranteedNodeTypes(this, newChild.get(), ec))
704         return false;
705
706     InspectorInstrumentation::willInsertDOMNode(&document(), this);
707
708     // Now actually add the child(ren)
709     ChildListMutationScope mutation(*this);
710     for (auto it = targets.begin(), end = targets.end(); it != end; ++it) {
711         Node& child = it->get();
712
713         // If the child has a parent again, just stop what we're doing, because
714         // that means someone is doing something with DOM mutation -- can't re-parent
715         // a child that already has a parent.
716         if (child.parentNode())
717             break;
718
719         treeScope().adoptIfNeeded(&child);
720
721         // Append child to the end of the list
722         {
723             NoEventDispatchAssertion assertNoEventDispatch;
724             appendChildToContainer(&child, *this);
725         }
726
727         updateTreeAfterInsertion(child);
728     }
729
730     dispatchSubtreeModifiedEvent();
731     return true;
732 }
733
734 void ContainerNode::parserAppendChild(PassRefPtr<Node> newChild)
735 {
736     ASSERT(newChild);
737     ASSERT(!newChild->parentNode()); // Use appendChild if you need to handle reparenting (and want DOM mutation events).
738     ASSERT(!newChild->isDocumentFragment());
739 #if ENABLE(TEMPLATE_ELEMENT)
740     ASSERT(!hasTagName(HTMLNames::templateTag));
741 #endif
742
743     if (&document() != &newChild->document())
744         document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION);
745
746     {
747         NoEventDispatchAssertion assertNoEventDispatch;
748         // FIXME: This method should take a PassRefPtr.
749         appendChildToContainer(newChild.get(), *this);
750         treeScope().adoptIfNeeded(newChild.get());
751     }
752
753     newChild->updateAncestorConnectedSubframeCountForInsertion();
754
755     ChildListMutationScope(*this).childAdded(*newChild);
756
757     notifyChildInserted(*newChild, ChildChangeSourceParser);
758
759     ChildNodeInsertionNotifier(*this).notify(*newChild);
760
761     newChild->setNeedsStyleRecalc(ReconstructRenderTree);
762 }
763
764 void ContainerNode::childrenChanged(const ChildChange& change)
765 {
766     document().incDOMTreeVersion();
767     if (change.source == ChildChangeSourceAPI && change.type != TextChanged)
768         document().updateRangesAfterChildrenChanged(*this);
769     invalidateNodeListAndCollectionCachesInAncestors();
770 }
771
772 inline static void cloneChildNodesAvoidingDeleteButton(ContainerNode* parent, ContainerNode* clonedParent, HTMLElement* deleteButtonContainerElement)
773 {
774     ExceptionCode ec = 0;
775     for (Node* child = parent->firstChild(); child && !ec; child = child->nextSibling()) {
776
777 #if ENABLE(DELETION_UI)
778         if (child == deleteButtonContainerElement)
779             continue;
780 #else
781         UNUSED_PARAM(deleteButtonContainerElement);
782 #endif
783
784         RefPtr<Node> clonedChild = child->cloneNode(false);
785         clonedParent->appendChild(clonedChild, ec);
786
787         if (!ec && is<ContainerNode>(child))
788             cloneChildNodesAvoidingDeleteButton(downcast<ContainerNode>(child), downcast<ContainerNode>(clonedChild.get()), deleteButtonContainerElement);
789     }
790 }
791
792 void ContainerNode::cloneChildNodes(ContainerNode *clone)
793 {
794 #if ENABLE(DELETION_UI)
795     HTMLElement* deleteButtonContainerElement = 0;
796     if (Frame* frame = document().frame())
797         deleteButtonContainerElement = frame->editor().deleteButtonController().containerElement();
798     cloneChildNodesAvoidingDeleteButton(this, clone, deleteButtonContainerElement);
799 #else
800     cloneChildNodesAvoidingDeleteButton(this, clone, 0);
801 #endif
802 }
803
804 bool ContainerNode::getUpperLeftCorner(FloatPoint& point) const
805 {
806     if (!renderer())
807         return false;
808     // What is this code really trying to do?
809     RenderObject* o = renderer();
810     if (!o->isInline() || o->isReplaced()) {
811         point = o->localToAbsolute(FloatPoint(), UseTransforms);
812         return true;
813     }
814
815     // find the next text/image child, to get a position
816     while (o) {
817         RenderObject* p = o;
818         if (RenderObject* child = o->firstChildSlow())
819             o = child;
820         else if (o->nextSibling())
821             o = o->nextSibling();
822         else {
823             RenderObject* next = 0;
824             while (!next && o->parent()) {
825                 o = o->parent();
826                 next = o->nextSibling();
827             }
828             o = next;
829
830             if (!o)
831                 break;
832         }
833         ASSERT(o);
834
835         if (!o->isInline() || o->isReplaced()) {
836             point = o->localToAbsolute(FloatPoint(), UseTransforms);
837             return true;
838         }
839
840         if (p->node() && p->node() == this && is<RenderText>(*o) && !downcast<RenderText>(*o).firstTextBox()) {
841             // do nothing - skip unrendered whitespace that is a child or next sibling of the anchor
842         } else if (is<RenderText>(*o) || o->isReplaced()) {
843             point = FloatPoint();
844             if (is<RenderText>(*o) && downcast<RenderText>(*o).firstTextBox())
845                 point.move(downcast<RenderText>(*o).linesBoundingBox().x(), downcast<RenderText>(*o).firstTextBox()->root().lineTop());
846             else if (is<RenderBox>(*o))
847                 point.moveBy(downcast<RenderBox>(*o).location());
848             point = o->container()->localToAbsolute(point, UseTransforms);
849             return true;
850         }
851     }
852     
853     // If the target doesn't have any children or siblings that could be used to calculate the scroll position, we must be
854     // at the end of the document. Scroll to the bottom. FIXME: who said anything about scrolling?
855     if (!o && document().view()) {
856         point = FloatPoint(0, document().view()->contentsHeight());
857         return true;
858     }
859     return false;
860 }
861
862 bool ContainerNode::getLowerRightCorner(FloatPoint& point) const
863 {
864     if (!renderer())
865         return false;
866
867     RenderObject* o = renderer();
868     if (!o->isInline() || o->isReplaced()) {
869         point = o->localToAbsolute(LayoutPoint(downcast<RenderBox>(*o).size()), UseTransforms);
870         return true;
871     }
872
873     // find the last text/image child, to get a position
874     while (o) {
875         if (RenderObject* child = o->lastChildSlow())
876             o = child;
877         else if (o->previousSibling())
878             o = o->previousSibling();
879         else {
880             RenderObject* prev = 0;
881             while (!prev) {
882                 o = o->parent();
883                 if (!o)
884                     return false;
885                 prev = o->previousSibling();
886             }
887             o = prev;
888         }
889         ASSERT(o);
890         if (is<RenderText>(*o) || o->isReplaced()) {
891             point = FloatPoint();
892             if (is<RenderText>(*o)) {
893                 IntRect linesBox = downcast<RenderText>(*o).linesBoundingBox();
894                 if (!linesBox.maxX() && !linesBox.maxY())
895                     continue;
896                 point.moveBy(linesBox.maxXMaxYCorner());
897             } else
898                 point.moveBy(downcast<RenderBox>(*o).frameRect().maxXMaxYCorner());
899             point = o->container()->localToAbsolute(point, UseTransforms);
900             return true;
901         }
902     }
903     return true;
904 }
905
906 LayoutRect ContainerNode::boundingBox() const
907 {
908     FloatPoint upperLeft, lowerRight;
909     bool foundUpperLeft = getUpperLeftCorner(upperLeft);
910     bool foundLowerRight = getLowerRightCorner(lowerRight);
911     
912     // If we've found one corner, but not the other,
913     // then we should just return a point at the corner that we did find.
914     if (foundUpperLeft != foundLowerRight) {
915         if (foundUpperLeft)
916             lowerRight = upperLeft;
917         else
918             upperLeft = lowerRight;
919     } 
920
921     return enclosingLayoutRect(FloatRect(upperLeft, lowerRight.expandedTo(upperLeft) - upperLeft));
922 }
923
924 unsigned ContainerNode::countChildNodes() const
925 {
926     unsigned count = 0;
927     for (Node* child = firstChild(); child; child = child->nextSibling())
928         ++count;
929     return count;
930 }
931
932 Node* ContainerNode::traverseToChildAt(unsigned index) const
933 {
934     Node* child = firstChild();
935     for (; child && index > 0; --index)
936         child = child->nextSibling();
937     return child;
938 }
939
940 static void dispatchChildInsertionEvents(Node& child)
941 {
942     if (child.isInShadowTree())
943         return;
944
945     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
946
947     RefPtr<Node> c = &child;
948     Ref<Document> document(child.document());
949
950     if (c->parentNode() && document->hasListenerType(Document::DOMNODEINSERTED_LISTENER))
951         c->dispatchScopedEvent(MutationEvent::create(eventNames().DOMNodeInsertedEvent, true, c->parentNode()));
952
953     // dispatch the DOMNodeInsertedIntoDocument event to all descendants
954     if (c->inDocument() && document->hasListenerType(Document::DOMNODEINSERTEDINTODOCUMENT_LISTENER)) {
955         for (; c; c = NodeTraversal::next(c.get(), &child))
956             c->dispatchScopedEvent(MutationEvent::create(eventNames().DOMNodeInsertedIntoDocumentEvent, false));
957     }
958 }
959
960 static void dispatchChildRemovalEvents(Node& child)
961 {
962     if (child.isInShadowTree()) {
963         InspectorInstrumentation::willRemoveDOMNode(&child.document(), &child);
964         return;
965     }
966
967     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
968
969     willCreatePossiblyOrphanedTreeByRemoval(&child);
970     InspectorInstrumentation::willRemoveDOMNode(&child.document(), &child);
971
972     RefPtr<Node> c = &child;
973     Ref<Document> document(child.document());
974
975     // dispatch pre-removal mutation events
976     if (c->parentNode() && document->hasListenerType(Document::DOMNODEREMOVED_LISTENER))
977         c->dispatchScopedEvent(MutationEvent::create(eventNames().DOMNodeRemovedEvent, true, c->parentNode()));
978
979     // dispatch the DOMNodeRemovedFromDocument event to all descendants
980     if (c->inDocument() && document->hasListenerType(Document::DOMNODEREMOVEDFROMDOCUMENT_LISTENER)) {
981         for (; c; c = NodeTraversal::next(c.get(), &child))
982             c->dispatchScopedEvent(MutationEvent::create(eventNames().DOMNodeRemovedFromDocumentEvent, false));
983     }
984 }
985
986 void ContainerNode::updateTreeAfterInsertion(Node& child)
987 {
988     ASSERT(child.refCount());
989
990     ChildListMutationScope(*this).childAdded(child);
991
992     notifyChildInserted(child, ChildChangeSourceAPI);
993
994     ChildNodeInsertionNotifier(*this).notify(child);
995
996     child.setNeedsStyleRecalc(ReconstructRenderTree);
997
998     dispatchChildInsertionEvents(child);
999 }
1000
1001 void ContainerNode::setAttributeEventListener(const AtomicString& eventType, const QualifiedName& attributeName, const AtomicString& attributeValue)
1002 {
1003     setAttributeEventListener(eventType, JSLazyEventListener::createForNode(*this, attributeName, attributeValue));
1004 }
1005
1006 Element* ContainerNode::querySelector(const String& selectors, ExceptionCode& ec)
1007 {
1008     if (SelectorQuery* selectorQuery = document().selectorQueryForString(selectors, ec))
1009         return selectorQuery->queryFirst(*this);
1010     return nullptr;
1011 }
1012
1013 RefPtr<NodeList> ContainerNode::querySelectorAll(const String& selectors, ExceptionCode& ec)
1014 {
1015     if (SelectorQuery* selectorQuery = document().selectorQueryForString(selectors, ec))
1016         return selectorQuery->queryAll(*this);
1017     return nullptr;
1018 }
1019
1020 PassRefPtr<NodeList> ContainerNode::getElementsByTagName(const AtomicString& localName)
1021 {
1022     if (localName.isNull())
1023         return 0;
1024
1025     if (document().isHTMLDocument())
1026         return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLTagNodeList>(*this, localName);
1027     return ensureRareData().ensureNodeLists().addCacheWithAtomicName<TagNodeList>(*this, localName);
1028 }
1029
1030 PassRefPtr<NodeList> ContainerNode::getElementsByTagNameNS(const AtomicString& namespaceURI, const AtomicString& localName)
1031 {
1032     if (localName.isNull())
1033         return 0;
1034
1035     if (namespaceURI == starAtom)
1036         return getElementsByTagName(localName);
1037
1038     return ensureRareData().ensureNodeLists().addCacheWithQualifiedName(*this, namespaceURI.isEmpty() ? nullAtom : namespaceURI, localName);
1039 }
1040
1041 PassRefPtr<NodeList> ContainerNode::getElementsByName(const String& elementName)
1042 {
1043     return ensureRareData().ensureNodeLists().addCacheWithAtomicName<NameNodeList>(*this, elementName);
1044 }
1045
1046 PassRefPtr<NodeList> ContainerNode::getElementsByClassName(const AtomicString& classNames)
1047 {
1048     return ensureRareData().ensureNodeLists().addCacheWithAtomicName<ClassNodeList>(*this, classNames);
1049 }
1050
1051 PassRefPtr<RadioNodeList> ContainerNode::radioNodeList(const AtomicString& name)
1052 {
1053     ASSERT(hasTagName(HTMLNames::formTag) || hasTagName(HTMLNames::fieldsetTag));
1054     return ensureRareData().ensureNodeLists().addCacheWithAtomicName<RadioNodeList>(*this, name);
1055 }
1056
1057 } // namespace WebCore