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