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