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