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