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