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