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