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