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