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