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