276df56c74b4718fd083980f5fa94c9b017b4eed
[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 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 "BeforeLoadEvent.h"
27 #include "MemoryCache.h"
28 #include "ContainerNodeAlgorithms.h"
29 #include "DeleteButtonController.h"
30 #include "EventNames.h"
31 #include "ExceptionCode.h"
32 #include "FloatRect.h"
33 #include "Frame.h"
34 #include "FrameView.h"
35 #include "InlineTextBox.h"
36 #include "InspectorInstrumentation.h"
37 #include "MutationEvent.h"
38 #include "ResourceLoadScheduler.h"
39 #include "Page.h"
40 #include "RenderBox.h"
41 #include "RenderTheme.h"
42 #include "RootInlineBox.h"
43 #include <wtf/CurrentTime.h>
44 #include <wtf/Vector.h>
45
46 namespace WebCore {
47
48 static void notifyChildInserted(Node*);
49 static void dispatchChildInsertionEvents(Node*);
50 static void dispatchChildRemovalEvents(Node*);
51
52 typedef Vector<std::pair<NodeCallback, RefPtr<Node> > > NodeCallbackQueue;
53 typedef Vector<RefPtr<Node>, 1> NodeVector;
54 static NodeCallbackQueue* s_postAttachCallbackQueue;
55
56 static size_t s_attachDepth;
57 static bool s_shouldReEnableMemoryCacheCallsAfterAttach;
58
59 static inline void collectNodes(Node* node, NodeVector& nodes)
60 {
61     for (Node* child = node->firstChild(); child; child = child->nextSibling())
62         nodes.append(child);
63 }
64
65 static void collectTargetNodes(Node* node, NodeVector& nodes)
66 {
67     if (node->nodeType() != Node::DOCUMENT_FRAGMENT_NODE) {
68         nodes.append(node);
69         return;
70     }
71     collectNodes(node, nodes);
72 }
73
74 void ContainerNode::removeAllChildren()
75 {
76     removeAllChildrenInContainer<Node, ContainerNode>(this);
77 }
78
79 void ContainerNode::takeAllChildrenFrom(ContainerNode* oldParent)
80 {
81     NodeVector children;
82     collectNodes(oldParent, children);
83     oldParent->removeAllChildren();
84
85     for (unsigned i = 0; i < children.size(); ++i) {
86         ExceptionCode ec = 0;
87         if (children[i]->attached())
88             children[i]->detach();
89         // FIXME: We need a no mutation event version of adoptNode.
90         RefPtr<Node> child = document()->adoptNode(children[i].release(), ec);
91         ASSERT(!ec);
92         parserAddChild(child.get());
93         if (attached() && !child->attached())
94             child->attach();
95     }
96 }
97
98 ContainerNode::~ContainerNode()
99 {
100     removeAllChildren();
101 }
102
103 bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode& ec, bool shouldLazyAttach)
104 {
105     // Check that this node is not "floating".
106     // If it is, it can be deleted as a side effect of sending mutation events.
107     ASSERT(refCount() || parentOrHostNode());
108
109     ec = 0;
110
111     // insertBefore(node, 0) is equivalent to appendChild(node)
112     if (!refChild)
113         return appendChild(newChild, ec, shouldLazyAttach);
114
115     // Make sure adding the new child is OK.
116     checkAddChild(newChild.get(), ec);
117     if (ec)
118         return false;
119
120     // NOT_FOUND_ERR: Raised if refChild is not a child of this node
121     if (refChild->parentNode() != this) {
122         ec = NOT_FOUND_ERR;
123         return false;
124     }
125
126     NodeVector targets;
127     collectTargetNodes(newChild.get(), targets);
128     if (targets.isEmpty())
129         return true;
130
131     // Now actually add the child(ren)
132     if (refChild->previousSibling() == newChild || refChild == newChild) // nothing to do
133         return true;
134
135     RefPtr<Node> next = refChild;
136     RefPtr<Node> refChildPreviousSibling = refChild->previousSibling();
137     for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); ++it) {
138         Node* child = it->get();
139
140         // If child is already present in the tree, first remove it from the old location.
141         if (ContainerNode* oldParent = child->parentNode())
142             oldParent->removeChild(child, ec);
143         if (ec)
144             return false;
145
146         // FIXME: After sending the mutation events, "this" could be destroyed.
147         // We can prevent that by doing a "ref", but first we have to make sure
148         // that no callers call with ref count == 0 and parent = 0 (as of this
149         // writing, there are definitely callers who call that way).
150
151         // Due to arbitrary code running in response to a DOM mutation event it's
152         // possible that "next" is no longer a child of "this".
153         // It's also possible that "child" has been inserted elsewhere.
154         // In either of those cases, we'll just stop.
155         if (next->parentNode() != this)
156             break;
157         if (child->parentNode())
158             break;
159
160 #if ENABLE(INSPECTOR)
161         InspectorInstrumentation::willInsertDOMNode(document(), child, this);
162 #endif
163
164         child->setTreeScopeRecursively(treeScope());
165
166         insertBeforeCommon(next.get(), child);
167
168         // Send notification about the children change.
169         childrenChanged(false, refChildPreviousSibling.get(), next.get(), 1);
170         notifyChildInserted(child);
171
172         // Add child to the rendering tree.
173         if (attached() && !child->attached() && child->parentNode() == this) {
174             if (shouldLazyAttach)
175                 child->lazyAttach();
176             else
177                 child->attach();
178         }
179
180         // Now that the child is attached to the render tree, dispatch
181         // the relevant mutation events.
182         dispatchChildInsertionEvents(child);
183     }
184
185     dispatchSubtreeModifiedEvent();
186     return true;
187 }
188
189 void ContainerNode::insertBeforeCommon(Node* nextChild, Node* newChild)
190 {
191     ASSERT(newChild);
192     ASSERT(!newChild->parentNode()); // Use insertBefore if you need to handle reparenting (and want DOM mutation events).
193     ASSERT(!newChild->nextSibling());
194     ASSERT(!newChild->previousSibling());
195
196     forbidEventDispatch();
197     Node* prev = nextChild->previousSibling();
198     ASSERT(m_lastChild != prev);
199     nextChild->setPreviousSibling(newChild);
200     if (prev) {
201         ASSERT(m_firstChild != nextChild);
202         ASSERT(prev->nextSibling() == nextChild);
203         prev->setNextSibling(newChild);
204     } else {
205         ASSERT(m_firstChild == nextChild);
206         m_firstChild = newChild;
207     }
208     newChild->setParent(this);
209     newChild->setPreviousSibling(prev);
210     newChild->setNextSibling(nextChild);
211     allowEventDispatch();
212 }
213
214 void ContainerNode::parserInsertBefore(PassRefPtr<Node> newChild, Node* nextChild)
215 {
216     ASSERT(newChild);
217     ASSERT(nextChild);
218     ASSERT(nextChild->parentNode() == this);
219
220     NodeVector targets;
221     collectTargetNodes(newChild.get(), targets);
222     if (targets.isEmpty())
223         return;
224
225     if (nextChild->previousSibling() == newChild || nextChild == newChild) // nothing to do
226         return;
227
228     RefPtr<Node> next = nextChild;
229     RefPtr<Node> nextChildPreviousSibling = nextChild->previousSibling();
230     for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); ++it) {
231         Node* child = it->get();
232
233 #if ENABLE(INSPECTOR)
234         InspectorInstrumentation::willInsertDOMNode(document(), child, this);
235 #endif
236
237         insertBeforeCommon(next.get(), child);
238
239         childrenChanged(true, nextChildPreviousSibling.get(), nextChild, 1);
240         notifyChildInserted(child);
241     }
242 }
243
244 bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode& ec, bool shouldLazyAttach)
245 {
246     // Check that this node is not "floating".
247     // If it is, it can be deleted as a side effect of sending mutation events.
248     ASSERT(refCount() || parentOrHostNode());
249
250     ec = 0;
251
252     if (oldChild == newChild) // nothing to do
253         return true;
254     
255     // Make sure replacing the old child with the new is ok
256     checkReplaceChild(newChild.get(), oldChild, ec);
257     if (ec)
258         return false;
259
260     // NOT_FOUND_ERR: Raised if oldChild is not a child of this node.
261     if (!oldChild || oldChild->parentNode() != this) {
262         ec = NOT_FOUND_ERR;
263         return false;
264     }
265
266     RefPtr<Node> prev = oldChild->previousSibling();
267     RefPtr<Node> next = oldChild->nextSibling();
268
269     // Remove the node we're replacing
270     RefPtr<Node> removedChild = oldChild;
271     removeChild(oldChild, ec);
272     if (ec)
273         return false;
274
275     // FIXME: After sending the mutation events, "this" could be destroyed.
276     // We can prevent that by doing a "ref", but first we have to make sure
277     // that no callers call with ref count == 0 and parent = 0 (as of this
278     // writing, there are definitely callers who call that way).
279
280     bool isFragment = newChild->nodeType() == DOCUMENT_FRAGMENT_NODE;
281
282     // Add the new child(ren)
283     RefPtr<Node> child = isFragment ? newChild->firstChild() : newChild;
284     while (child) {
285         // If the new child is already in the right place, we're done.
286         if (prev && (prev == child || prev == child->previousSibling()))
287             break;
288
289         // For a fragment we have more children to do.
290         RefPtr<Node> nextChild = isFragment ? child->nextSibling() : 0;
291
292         // Remove child from its old position.
293         if (ContainerNode* oldParent = child->parentNode())
294             oldParent->removeChild(child.get(), ec);
295         if (ec)
296             return false;
297
298         // Due to arbitrary code running in response to a DOM mutation event it's
299         // possible that "prev" is no longer a child of "this".
300         // It's also possible that "child" has been inserted elsewhere.
301         // In either of those cases, we'll just stop.
302         if (prev && prev->parentNode() != this)
303             break;
304         if (child->parentNode())
305             break;
306
307         ASSERT(!child->nextSibling());
308         ASSERT(!child->previousSibling());
309
310 #if ENABLE(INSPECTOR)
311         InspectorInstrumentation::willInsertDOMNode(document(), child.get(), this);
312 #endif
313
314         child->setTreeScopeRecursively(treeScope());
315
316         // Add child after "prev".
317         forbidEventDispatch();
318         Node* next;
319         if (prev) {
320             next = prev->nextSibling();
321             ASSERT(m_firstChild != next);
322             prev->setNextSibling(child.get());
323         } else {
324             next = m_firstChild;
325             m_firstChild = child.get();
326         }
327         if (next) {
328             ASSERT(m_lastChild != prev);
329             ASSERT(next->previousSibling() == prev);
330             next->setPreviousSibling(child.get());
331         } else {
332             ASSERT(m_lastChild == prev);
333             m_lastChild = child.get();
334         }
335         child->setParent(this);
336         child->setPreviousSibling(prev.get());
337         child->setNextSibling(next);
338         allowEventDispatch();
339
340         childrenChanged(false, prev.get(), next, 1);
341         notifyChildInserted(child.get());
342                 
343         // Add child to the rendering tree
344         if (attached() && !child->attached() && child->parentNode() == this) {
345             if (shouldLazyAttach)
346                 child->lazyAttach();
347             else
348                 child->attach();
349         }
350
351         // Now that the child is attached to the render tree, dispatch
352         // the relevant mutation events.
353         dispatchChildInsertionEvents(child.get());
354
355         prev = child;
356         child = nextChild.release();
357     }
358
359     dispatchSubtreeModifiedEvent();
360     return true;
361 }
362
363 void ContainerNode::willRemove()
364 {
365     Vector<RefPtr<Node>, 10> nodes;
366     nodes.reserveInitialCapacity(childNodeCount());
367     for (Node* n = m_lastChild; n; n = n->previousSibling())
368         nodes.append(n);
369     for (; nodes.size(); nodes.removeLast())
370         nodes.last().get()->willRemove();
371     Node::willRemove();
372 }
373
374 static void willRemoveChild(Node* child)
375 {
376     // update auxiliary doc info (e.g. iterators) to note that node is being removed
377     child->document()->nodeWillBeRemoved(child);
378     child->document()->incDOMTreeVersion();
379
380     // fire removed from document mutation events.
381     dispatchChildRemovalEvents(child);
382     child->willRemove();
383 }
384
385 static void willRemoveChildren(ContainerNode* container)
386 {
387     container->document()->nodeChildrenWillBeRemoved(container);
388     container->document()->incDOMTreeVersion();
389
390     NodeVector children;
391     collectNodes(container, children);
392
393     for (NodeVector::const_iterator it = children.begin(); it != children.end(); it++) {
394         Node* child = it->get();
395         // fire removed from document mutation events.
396         dispatchChildRemovalEvents(child);
397         child->willRemove();
398     }
399 }
400
401 bool ContainerNode::removeChild(Node* oldChild, ExceptionCode& ec)
402 {
403     // Check that this node is not "floating".
404     // If it is, it can be deleted as a side effect of sending mutation events.
405     ASSERT(refCount() || parentOrHostNode());
406
407     ec = 0;
408
409     // NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
410     if (isReadOnlyNode()) {
411         ec = NO_MODIFICATION_ALLOWED_ERR;
412         return false;
413     }
414
415     // NOT_FOUND_ERR: Raised if oldChild is not a child of this node.
416     if (!oldChild || oldChild->parentNode() != this) {
417         ec = NOT_FOUND_ERR;
418         return false;
419     }
420
421     RefPtr<Node> child = oldChild;
422     willRemoveChild(child.get());
423
424     // Mutation events might have moved this child into a different parent.
425     if (child->parentNode() != this) {
426         ec = NOT_FOUND_ERR;
427         return false;
428     }
429
430     document()->removeFocusedNodeOfSubtree(child.get());
431
432     // Events fired when blurring currently focused node might have moved this
433     // child into a different parent.
434     if (child->parentNode() != this) {
435         ec = NOT_FOUND_ERR;
436         return false;
437     }
438
439     // FIXME: After sending the mutation events, "this" could be destroyed.
440     // We can prevent that by doing a "ref", but first we have to make sure
441     // that no callers call with ref count == 0 and parent = 0 (as of this
442     // writing, there are definitely callers who call that way).
443
444     Node* prev = child->previousSibling();
445     Node* next = child->nextSibling();
446     removeBetween(prev, next, child.get());
447
448     // Dispatch post-removal mutation events
449     childrenChanged(false, prev, next, -1);
450     dispatchSubtreeModifiedEvent();
451
452     if (child->inDocument())
453         child->removedFromDocument();
454     else
455         child->removedFromTree(true);
456
457     return child;
458 }
459
460 void ContainerNode::removeBetween(Node* previousChild, Node* nextChild, Node* oldChild)
461 {
462     ASSERT(oldChild);
463     ASSERT(oldChild->parentNode() == this);
464
465     forbidEventDispatch();
466
467     // Remove from rendering tree
468     if (oldChild->attached())
469         oldChild->detach();
470
471     if (nextChild)
472         nextChild->setPreviousSibling(previousChild);
473     if (previousChild)
474         previousChild->setNextSibling(nextChild);
475     if (m_firstChild == oldChild)
476         m_firstChild = nextChild;
477     if (m_lastChild == oldChild)
478         m_lastChild = previousChild;
479
480     oldChild->setPreviousSibling(0);
481     oldChild->setNextSibling(0);
482     oldChild->setParent(0);
483
484     allowEventDispatch();
485 }
486
487 void ContainerNode::parserRemoveChild(Node* oldChild)
488 {
489     ASSERT(oldChild);
490     ASSERT(oldChild->parentNode() == this);
491
492     Node* prev = oldChild->previousSibling();
493     Node* next = oldChild->nextSibling();
494
495     removeBetween(prev, next, oldChild);
496
497     childrenChanged(true, prev, next, -1);
498     if (oldChild->inDocument())
499         oldChild->removedFromDocument();
500     else
501         oldChild->removedFromTree(true);
502 }
503
504 // this differs from other remove functions because it forcibly removes all the children,
505 // regardless of read-only status or event exceptions, e.g.
506 void ContainerNode::removeChildren()
507 {
508     if (!m_firstChild)
509         return;
510
511     // The container node can be removed from event handlers.
512     RefPtr<ContainerNode> protect(this);
513
514     // Do any prep work needed before actually starting to detach
515     // and remove... e.g. stop loading frames, fire unload events.
516     willRemoveChildren(protect.get());
517
518     // exclude this node when looking for removed focusedNode since only children will be removed
519     document()->removeFocusedNodeOfSubtree(this, true);
520
521     forbidEventDispatch();
522     Vector<RefPtr<Node>, 10> removedChildren;
523     removedChildren.reserveInitialCapacity(childNodeCount());
524     while (RefPtr<Node> n = m_firstChild) {
525         Node* next = n->nextSibling();
526
527         // Remove the node from the tree before calling detach or removedFromDocument (4427024, 4129744).
528         // removeChild() does this after calling detach(). There is no explanation for
529         // this discrepancy between removeChild() and its optimized version removeChildren().
530         n->setPreviousSibling(0);
531         n->setNextSibling(0);
532         n->setParent(0);
533
534         m_firstChild = next;
535         if (n == m_lastChild)
536             m_lastChild = 0;
537
538         if (n->attached())
539             n->detach();
540
541         removedChildren.append(n.release());
542     }
543     allowEventDispatch();
544
545     size_t removedChildrenCount = removedChildren.size();
546
547     // Dispatch a single post-removal mutation event denoting a modified subtree.
548     childrenChanged(false, 0, 0, -static_cast<int>(removedChildrenCount));
549     dispatchSubtreeModifiedEvent();
550
551     for (size_t i = 0; i < removedChildrenCount; ++i) {
552         Node* removedChild = removedChildren[i].get();
553         if (removedChild->inDocument())
554             removedChild->removedFromDocument();
555         // removeChild() calls removedFromTree(true) if the child was not in the
556         // document. There is no explanation for this discrepancy between removeChild()
557         // and its optimized version removeChildren().
558     }
559 }
560
561 bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bool shouldLazyAttach)
562 {
563     // Check that this node is not "floating".
564     // If it is, it can be deleted as a side effect of sending mutation events.
565     ASSERT(refCount() || parentOrHostNode());
566
567     ec = 0;
568
569     // Make sure adding the new child is ok
570     checkAddChild(newChild.get(), ec);
571     if (ec)
572         return false;
573
574     if (newChild == m_lastChild) // nothing to do
575         return newChild;
576
577     NodeVector targets;
578     collectTargetNodes(newChild.get(), targets);
579     if (targets.isEmpty())
580         return true;
581
582     // Now actually add the child(ren)
583     RefPtr<Node> prev = lastChild();
584     for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); ++it) {
585         Node* child = it->get();
586         // If child is already present in the tree, first remove it
587         if (ContainerNode* oldParent = child->parentNode()) {
588             oldParent->removeChild(child, ec);
589             if (ec)
590                 return false;
591
592             // If the child has a parent again, just stop what we're doing, because
593             // that means someone is doing something with DOM mutation -- can't re-parent
594             // a child that already has a parent.
595             if (child->parentNode())
596                 break;
597         }
598
599 #if ENABLE(INSPECTOR)
600         InspectorInstrumentation::willInsertDOMNode(document(), child, this);
601 #endif
602
603         child->setTreeScopeRecursively(treeScope());
604
605         // Append child to the end of the list
606         forbidEventDispatch();
607         child->setParent(this);
608         if (m_lastChild) {
609             child->setPreviousSibling(m_lastChild);
610             m_lastChild->setNextSibling(child);
611         } else
612             m_firstChild = child;
613         m_lastChild = child;
614         allowEventDispatch();
615
616         // Send notification about the children change.
617         childrenChanged(false, prev.get(), 0, 1);
618         notifyChildInserted(child);
619
620         // Add child to the rendering tree
621         if (attached() && !child->attached() && child->parentNode() == this) {
622             if (shouldLazyAttach)
623                 child->lazyAttach();
624             else
625                 child->attach();
626         }
627
628         // Now that the child is attached to the render tree, dispatch
629         // the relevant mutation events.
630         dispatchChildInsertionEvents(child);
631         prev = child;
632     }
633
634     dispatchSubtreeModifiedEvent();
635     return true;
636 }
637
638 void ContainerNode::parserAddChild(PassRefPtr<Node> newChild)
639 {
640     ASSERT(newChild);
641     ASSERT(!newChild->parentNode()); // Use appendChild if you need to handle reparenting (and want DOM mutation events).
642
643 #if ENABLE(INSPECTOR)
644     InspectorInstrumentation::willInsertDOMNode(document(), newChild.get(), this);
645 #endif
646
647     forbidEventDispatch();
648     Node* last = m_lastChild;
649     // FIXME: This method should take a PassRefPtr.
650     appendChildToContainer<Node, ContainerNode>(newChild.get(), this);
651     allowEventDispatch();
652
653     // FIXME: Why doesn't this use notifyChildInserted(newChild) instead?
654     document()->incDOMTreeVersion();
655     if (inDocument())
656         newChild->insertedIntoDocument();
657     childrenChanged(true, last, 0, 1);
658 }
659
660 void ContainerNode::deprecatedParserAddChild(PassRefPtr<Node> node)
661 {
662     parserAddChild(node);
663 }
664
665 void ContainerNode::suspendPostAttachCallbacks()
666 {
667     if (!s_attachDepth) {
668         ASSERT(!s_shouldReEnableMemoryCacheCallsAfterAttach);
669         if (Page* page = document()->page()) {
670             if (page->areMemoryCacheClientCallsEnabled()) {
671                 page->setMemoryCacheClientCallsEnabled(false);
672                 s_shouldReEnableMemoryCacheCallsAfterAttach = true;
673             }
674         }
675         resourceLoadScheduler()->suspendPendingRequests();
676     }
677     ++s_attachDepth;
678 }
679
680 void ContainerNode::resumePostAttachCallbacks()
681 {
682     if (s_attachDepth == 1) {
683         if (s_postAttachCallbackQueue)
684             dispatchPostAttachCallbacks();
685         if (s_shouldReEnableMemoryCacheCallsAfterAttach) {
686             s_shouldReEnableMemoryCacheCallsAfterAttach = false;
687             if (Page* page = document()->page())
688                 page->setMemoryCacheClientCallsEnabled(true);
689         }
690         resourceLoadScheduler()->resumePendingRequests();
691     }
692     --s_attachDepth;
693 }
694
695 void ContainerNode::queuePostAttachCallback(NodeCallback callback, Node* node)
696 {
697     if (!s_postAttachCallbackQueue)
698         s_postAttachCallbackQueue = new NodeCallbackQueue;
699     
700     s_postAttachCallbackQueue->append(std::pair<NodeCallback, RefPtr<Node> >(callback, node));
701 }
702
703 bool ContainerNode::postAttachCallbacksAreSuspended()
704 {
705     return s_attachDepth;
706 }
707
708 void ContainerNode::dispatchPostAttachCallbacks()
709 {
710     // We recalculate size() each time through the loop because a callback
711     // can add more callbacks to the end of the queue.
712     for (size_t i = 0; i < s_postAttachCallbackQueue->size(); ++i) {
713         std::pair<NodeCallback, RefPtr<Node> >& pair = (*s_postAttachCallbackQueue)[i];
714         NodeCallback callback = pair.first;
715         Node* node = pair.second.get();
716
717         callback(node);
718     }
719     s_postAttachCallbackQueue->clear();
720 }
721
722 void ContainerNode::attach()
723 {
724     for (Node* child = m_firstChild; child; child = child->nextSibling())
725         child->attach();
726     Node::attach();
727 }
728
729 void ContainerNode::detach()
730 {
731     for (Node* child = m_firstChild; child; child = child->nextSibling())
732         child->detach();
733     clearChildNeedsStyleRecalc();
734     Node::detach();
735 }
736
737 void ContainerNode::insertedIntoDocument()
738 {
739     Node::insertedIntoDocument();
740     insertedIntoTree(false);
741
742     // Determine set of children before operating on any of them.
743     NodeVector children;
744     collectNodes(this, children);
745
746     NodeVector::iterator it;
747     for (it = children.begin(); it != children.end() && inDocument(); ++it) {
748         Node* child = it->get();
749         child->insertedIntoDocument();
750     }
751 }
752
753 void ContainerNode::removedFromDocument()
754 {
755     Node::removedFromDocument();
756     if (document()->cssTarget() == this) 
757         document()->setCSSTarget(0); 
758     clearInDocument();
759     removedFromTree(false);
760     for (Node* child = m_firstChild; child; child = child->nextSibling())
761         child->removedFromDocument();
762 }
763
764 void ContainerNode::insertedIntoTree(bool deep)
765 {
766     if (!deep)
767         return;
768     for (Node* child = m_firstChild; child; child = child->nextSibling())
769         child->insertedIntoTree(true);
770 }
771
772 void ContainerNode::removedFromTree(bool deep)
773 {
774     if (!deep)
775         return;
776     for (Node* child = m_firstChild; child; child = child->nextSibling())
777         child->removedFromTree(true);
778 }
779
780 void ContainerNode::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
781 {
782     Node::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
783     if (!changedByParser && childCountDelta)
784         document()->nodeChildrenChanged(this);
785     if (document()->hasNodeListCaches())
786         notifyNodeListsChildrenChanged();
787 }
788
789 void ContainerNode::cloneChildNodes(ContainerNode *clone)
790 {
791     // disable the delete button so it's elements are not serialized into the markup
792     bool isEditorEnabled = false;
793     if (document()->frame() && document()->frame()->editor()->canEdit()) {
794         SelectionController* selection = document()->frame()->selection();
795         Element* root = selection ? selection->rootEditableElement() : 0;
796         isEditorEnabled = root && isDescendantOf(root);
797
798         if (isEditorEnabled)
799             document()->frame()->editor()->deleteButtonController()->disable();
800     }
801     
802     ExceptionCode ec = 0;
803     for (Node* n = firstChild(); n && !ec; n = n->nextSibling())
804         clone->appendChild(n->cloneNode(true), ec);
805     if (isEditorEnabled && document()->frame())
806         document()->frame()->editor()->deleteButtonController()->enable();
807 }
808
809 bool ContainerNode::getUpperLeftCorner(FloatPoint& point) const
810 {
811     if (!renderer())
812         return false;
813     // What is this code really trying to do?
814     RenderObject *o = renderer();
815     RenderObject *p = o;
816
817     if (!o->isInline() || o->isReplaced()) {
818         point = o->localToAbsolute(FloatPoint(), false, true);
819         return true;
820     }
821
822     // find the next text/image child, to get a position
823     while (o) {
824         p = o;
825         if (o->firstChild())
826             o = o->firstChild();
827         else if (o->nextSibling())
828             o = o->nextSibling();
829         else {
830             RenderObject *next = 0;
831             while (!next && o->parent()) {
832                 o = o->parent();
833                 next = o->nextSibling();
834             }
835             o = next;
836
837             if (!o)
838                 break;
839         }
840         ASSERT(o);
841
842         if (!o->isInline() || o->isReplaced()) {
843             point = o->localToAbsolute(FloatPoint(), false, true);
844             return true;
845         }
846
847         if (p->node() && p->node() == this && o->isText() && !o->isBR() && !toRenderText(o)->firstTextBox()) {
848                 // do nothing - skip unrendered whitespace that is a child or next sibling of the anchor
849         } else if ((o->isText() && !o->isBR()) || o->isReplaced()) {
850             point = FloatPoint();
851             if (o->isText() && toRenderText(o)->firstTextBox()) {
852                 point.move(toRenderText(o)->linesBoundingBox().x(),
853                            toRenderText(o)->firstTextBox()->root()->lineTop());
854             } else if (o->isBox()) {
855                 RenderBox* box = toRenderBox(o);
856                 point.move(box->x(), box->y());
857             }
858             point = o->container()->localToAbsolute(point, false, true);
859             return true;
860         }
861     }
862     
863     // If the target doesn't have any children or siblings that could be used to calculate the scroll position, we must be
864     // at the end of the document.  Scroll to the bottom. FIXME: who said anything about scrolling?
865     if (!o && document()->view()) {
866         point = FloatPoint(0, document()->view()->contentsHeight());
867         return true;
868     }
869     return false;
870 }
871
872 // FIXME: This doesn't work correctly with transforms.
873 bool ContainerNode::getLowerRightCorner(FloatPoint& point) const
874 {
875     if (!renderer())
876         return false;
877
878     RenderObject* o = renderer();
879     if (!o->isInline() || o->isReplaced()) {
880         RenderBox* box = toRenderBox(o);
881         point = o->localToAbsolute(FloatPoint(), false, true);
882         point.move(box->width(), box->height());
883         return true;
884     }
885
886     // find the last text/image child, to get a position
887     while (o) {
888         if (o->lastChild())
889             o = o->lastChild();
890         else if (o->previousSibling())
891             o = o->previousSibling();
892         else {
893             RenderObject* prev = 0;
894             while (!prev) {
895                 o = o->parent();
896                 if (!o)
897                     return false;
898                 prev = o->previousSibling();
899             }
900             o = prev;
901         }
902         ASSERT(o);
903         if (o->isText() || o->isReplaced()) {
904             point = FloatPoint();
905             if (o->isText()) {
906                 RenderText* text = toRenderText(o);
907                 IntRect linesBox = text->linesBoundingBox();
908                 if (!linesBox.x() && !linesBox.width() && !linesBox.y() && !linesBox.height())
909                     continue;
910                 point.move(linesBox.x() + linesBox.width(), linesBox.y() + linesBox.height());
911             } else {
912                 RenderBox* box = toRenderBox(o);
913                 point.move(box->x() + box->width(), box->y() + box->height());
914             }
915             point = o->container()->localToAbsolute(point, false, true);
916             return true;
917         }
918     }
919     return true;
920 }
921
922 IntRect ContainerNode::getRect() const
923 {
924     FloatPoint  upperLeft, lowerRight;
925     bool foundUpperLeft = getUpperLeftCorner(upperLeft);
926     bool foundLowerRight = getLowerRightCorner(lowerRight);
927     
928     // If we've found one corner, but not the other,
929     // then we should just return a point at the corner that we did find.
930     if (foundUpperLeft != foundLowerRight) {
931         if (foundUpperLeft)
932             lowerRight = upperLeft;
933         else
934             upperLeft = lowerRight;
935     } 
936
937     lowerRight.setX(max(upperLeft.x(), lowerRight.x()));
938     lowerRight.setY(max(upperLeft.y(), lowerRight.y()));
939     
940     return enclosingIntRect(FloatRect(upperLeft, lowerRight - upperLeft));
941 }
942
943 void ContainerNode::setFocus(bool received)
944 {
945     if (focused() == received)
946         return;
947
948     Node::setFocus(received);
949
950     // note that we need to recalc the style
951     setNeedsStyleRecalc();
952 }
953
954 void ContainerNode::setActive(bool down, bool pause)
955 {
956     if (down == active()) return;
957
958     Node::setActive(down);
959
960     // note that we need to recalc the style
961     // FIXME: Move to Element
962     if (renderer()) {
963         bool reactsToPress = renderer()->style()->affectedByActiveRules();
964         if (reactsToPress)
965             setNeedsStyleRecalc();
966         if (renderer() && renderer()->style()->hasAppearance()) {
967             if (renderer()->theme()->stateChanged(renderer(), PressedState))
968                 reactsToPress = true;
969         }
970         if (reactsToPress && pause) {
971             // The delay here is subtle.  It relies on an assumption, namely that the amount of time it takes
972             // to repaint the "down" state of the control is about the same time as it would take to repaint the
973             // "up" state.  Once you assume this, you can just delay for 100ms - that time (assuming that after you
974             // leave this method, it will be about that long before the flush of the up state happens again).
975 #ifdef HAVE_FUNC_USLEEP
976             double startTime = currentTime();
977 #endif
978
979             // Ensure there are no pending changes
980             Document::updateStyleForAllDocuments();
981             // Do an immediate repaint.
982             if (renderer())
983                 renderer()->repaint(true);
984             
985             // FIXME: Find a substitute for usleep for Win32.
986             // Better yet, come up with a way of doing this that doesn't use this sort of thing at all.            
987 #ifdef HAVE_FUNC_USLEEP
988             // Now pause for a small amount of time (1/10th of a second from before we repainted in the pressed state)
989             double remainingTime = 0.1 - (currentTime() - startTime);
990             if (remainingTime > 0)
991                 usleep(static_cast<useconds_t>(remainingTime * 1000000.0));
992 #endif
993         }
994     }
995 }
996
997 void ContainerNode::setHovered(bool over)
998 {
999     if (over == hovered()) return;
1000
1001     Node::setHovered(over);
1002
1003     // note that we need to recalc the style
1004     // FIXME: Move to Element
1005     if (renderer()) {
1006         if (renderer()->style()->affectedByHoverRules())
1007             setNeedsStyleRecalc();
1008         if (renderer() && renderer()->style()->hasAppearance())
1009             renderer()->theme()->stateChanged(renderer(), HoverState);
1010     }
1011 }
1012
1013 unsigned ContainerNode::childNodeCount() const
1014 {
1015     unsigned count = 0;
1016     Node *n;
1017     for (n = firstChild(); n; n = n->nextSibling())
1018         count++;
1019     return count;
1020 }
1021
1022 Node *ContainerNode::childNode(unsigned index) const
1023 {
1024     unsigned i;
1025     Node *n = firstChild();
1026     for (i = 0; n != 0 && i < index; i++)
1027         n = n->nextSibling();
1028     return n;
1029 }
1030
1031 static void notifyChildInserted(Node* child)
1032 {
1033     ASSERT(!eventDispatchForbidden());
1034
1035 #if ENABLE(INSPECTOR)
1036     InspectorInstrumentation::didInsertDOMNode(child->document(), child);
1037 #endif
1038
1039     RefPtr<Node> c = child;
1040     RefPtr<Document> document = child->document();
1041
1042     Node* parentOrHostNode = c->parentOrHostNode();
1043     if (parentOrHostNode && parentOrHostNode->inDocument())
1044         c->insertedIntoDocument();
1045     else
1046         c->insertedIntoTree(true);
1047
1048     document->incDOMTreeVersion();
1049 }
1050
1051 static void dispatchChildInsertionEvents(Node* child)
1052 {
1053     ASSERT(!eventDispatchForbidden());
1054
1055     RefPtr<Node> c = child;
1056     RefPtr<Document> document = child->document();
1057
1058     if (c->parentNode() && document->hasListenerType(Document::DOMNODEINSERTED_LISTENER))
1059         c->dispatchScopedEvent(MutationEvent::create(eventNames().DOMNodeInsertedEvent, true, c->parentNode()));
1060
1061     // dispatch the DOMNodeInsertedIntoDocument event to all descendants
1062     if (c->inDocument() && document->hasListenerType(Document::DOMNODEINSERTEDINTODOCUMENT_LISTENER)) {
1063         for (; c; c = c->traverseNextNode(child))
1064             c->dispatchScopedEvent(MutationEvent::create(eventNames().DOMNodeInsertedIntoDocumentEvent, false));
1065     }
1066 }
1067
1068 static void dispatchChildRemovalEvents(Node* child)
1069 {
1070     ASSERT(!eventDispatchForbidden());
1071
1072 #if ENABLE(INSPECTOR)
1073     InspectorInstrumentation::willRemoveDOMNode(child->document(), child);
1074 #endif
1075
1076     RefPtr<Node> c = child;
1077     RefPtr<Document> document = child->document();
1078
1079     // dispatch pre-removal mutation events
1080     if (c->parentNode() && document->hasListenerType(Document::DOMNODEREMOVED_LISTENER))
1081         c->dispatchScopedEvent(MutationEvent::create(eventNames().DOMNodeRemovedEvent, true, c->parentNode()));
1082
1083     // dispatch the DOMNodeRemovedFromDocument event to all descendants
1084     if (c->inDocument() && document->hasListenerType(Document::DOMNODEREMOVEDFROMDOCUMENT_LISTENER)) {
1085         for (; c; c = c->traverseNextNode(child))
1086             c->dispatchScopedEvent(MutationEvent::create(eventNames().DOMNodeRemovedFromDocumentEvent, false));
1087     }
1088 }
1089
1090 bool ContainerNode::dispatchBeforeLoadEvent(const String& sourceURL)
1091 {
1092     if (!document()->hasListenerType(Document::BEFORELOAD_LISTENER))
1093         return true;
1094
1095     RefPtr<ContainerNode> protector(this);
1096     RefPtr<BeforeLoadEvent> beforeLoadEvent = BeforeLoadEvent::create(sourceURL);
1097     dispatchEvent(beforeLoadEvent.get());
1098     return !beforeLoadEvent->defaultPrevented();
1099 }
1100
1101 } // namespace WebCore