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