2008-04-01 Darin Adler <darin@apple.com>
[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 ContainerNode* ContainerNode::addChild(PassRefPtr<Node> newChild)
578 {
579     // This function is only used during parsing.
580     // It does not send any DOM mutation events.
581
582     // Check for consistency with DTD, but only when parsing HTML.
583     if (document()->isHTMLDocument() && !childAllowed(newChild.get()))
584         return 0;
585
586     forbidEventDispatch();
587     newChild->setParent(this);
588     Node* last = m_lastChild;
589     if (m_lastChild) {
590         newChild->setPreviousSibling(m_lastChild);
591         m_lastChild->setNextSibling(newChild.get());
592     } else
593         m_firstChild = newChild.get();
594     m_lastChild = newChild.get();
595     allowEventDispatch();
596
597     document()->incDOMTreeVersion();
598     if (inDocument())
599         newChild->insertedIntoDocument();
600     childrenChanged(true, last, 0, 1);
601     
602     if (newChild->isElementNode())
603         return static_cast<ContainerNode*>(newChild.get());
604     return this;
605 }
606
607 void ContainerNode::suspendPostAttachCallbacks()
608 {
609     ++s_attachDepth;
610 }
611
612 void ContainerNode::resumePostAttachCallbacks()
613 {
614     if (s_attachDepth == 1 && s_postAttachCallbackQueue)
615         dispatchPostAttachCallbacks();
616     --s_attachDepth;
617 }
618
619 void ContainerNode::queuePostAttachCallback(NodeCallback callback, Node* node)
620 {
621     if (!s_postAttachCallbackQueue)
622         s_postAttachCallbackQueue = new NodeCallbackQueue;
623     
624     s_postAttachCallbackQueue->append(std::pair<NodeCallback, RefPtr<Node> >(callback, node));
625 }
626
627 void ContainerNode::dispatchPostAttachCallbacks()
628 {
629     // We recalculate size() each time through the loop because a callback
630     // can add more callbacks to the end of the queue.
631     for (size_t i = 0; i < s_postAttachCallbackQueue->size(); ++i) {
632         std::pair<NodeCallback, RefPtr<Node> >& pair = (*s_postAttachCallbackQueue)[i];
633         NodeCallback callback = pair.first;
634         Node* node = pair.second.get();
635
636         callback(node);
637     }
638     s_postAttachCallbackQueue->clear();
639 }
640
641 void ContainerNode::attach()
642 {
643     ++s_attachDepth;
644
645     for (Node* child = m_firstChild; child; child = child->nextSibling())
646         child->attach();
647     EventTargetNode::attach();
648
649     if (s_attachDepth == 1 && s_postAttachCallbackQueue)
650         dispatchPostAttachCallbacks();
651     --s_attachDepth;
652 }
653
654 void ContainerNode::detach()
655 {
656     for (Node* child = m_firstChild; child; child = child->nextSibling())
657         child->detach();
658     EventTargetNode::detach();
659 }
660
661 void ContainerNode::insertedIntoDocument()
662 {
663     EventTargetNode::insertedIntoDocument();
664     for (Node *child = m_firstChild; child; child = child->nextSibling())
665         child->insertedIntoDocument();
666 }
667
668 void ContainerNode::removedFromDocument()
669 {
670     EventTargetNode::removedFromDocument();
671     for (Node *child = m_firstChild; child; child = child->nextSibling())
672         child->removedFromDocument();
673 }
674
675 void ContainerNode::insertedIntoTree(bool deep)
676 {
677     EventTargetNode::insertedIntoTree(deep);
678     if (deep) {
679         for (Node *child = m_firstChild; child; child = child->nextSibling())
680             child->insertedIntoTree(deep);
681     }
682 }
683
684 void ContainerNode::removedFromTree(bool deep)
685 {
686     EventTargetNode::removedFromTree(deep);
687     if (deep) {
688         for (Node *child = m_firstChild; child; child = child->nextSibling())
689             child->removedFromTree(deep);
690     }
691 }
692
693 void ContainerNode::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
694 {
695     Node::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
696     if (!changedByParser && childCountDelta)
697         document()->nodeChildrenChanged(this);
698     if (document()->hasNodeListCaches())
699         notifyNodeListsChildrenChanged();
700 }
701
702 void ContainerNode::cloneChildNodes(ContainerNode *clone)
703 {
704     // disable the delete button so it's elements are not serialized into the markup
705     if (document()->frame())
706         document()->frame()->editor()->deleteButtonController()->disable();
707     ExceptionCode ec = 0;
708     for (Node* n = firstChild(); n && !ec; n = n->nextSibling())
709         clone->appendChild(n->cloneNode(true), ec);
710     if (document()->frame())
711         document()->frame()->editor()->deleteButtonController()->enable();
712 }
713
714 bool ContainerNode::getUpperLeftCorner(int &xPos, int &yPos) const
715 {
716     if (!renderer())
717         return false;
718     RenderObject *o = renderer();
719     RenderObject *p = o;
720
721     xPos = yPos = 0;
722     if (!o->isInline() || o->isReplaced()) {
723         o->absolutePosition(xPos, yPos);
724         return true;
725     }
726
727     // find the next text/image child, to get a position
728     while(o) {
729         p = o;
730         if (o->firstChild())
731             o = o->firstChild();
732         else if(o->nextSibling())
733             o = o->nextSibling();
734         else {
735             RenderObject *next = 0;
736             while (!next && o->parent()) {
737                 o = o->parent();
738                 next = o->nextSibling();
739             }
740             o = next;
741
742             if (!o)
743                 break;
744         }
745
746         if (!o->isInline() || o->isReplaced()) {
747             o->absolutePosition(xPos, yPos);
748             return true;
749         }
750
751         if (p->element() && p->element() == this && o->isText() && !o->isBR() && !static_cast<RenderText*>(o)->firstTextBox()) {
752                 // do nothing - skip unrendered whitespace that is a child or next sibling of the anchor
753         } else if ((o->isText() && !o->isBR()) || o->isReplaced()) {
754             o->container()->absolutePosition(xPos, yPos);
755             if (o->isText() && static_cast<RenderText *>(o)->firstTextBox()) {
756                 xPos += static_cast<RenderText *>(o)->minXPos();
757                 yPos += static_cast<RenderText *>(o)->firstTextBox()->root()->topOverflow();
758             } else {
759                 xPos += o->xPos();
760                 yPos += o->yPos();
761             }
762             return true;
763         }
764     }
765     
766     // If the target doesn't have any children or siblings that could be used to calculate the scroll position, we must be
767     // at the end of the document.  Scroll to the bottom.
768     if (!o && document()->view()) {
769         yPos += document()->view()->contentsHeight();
770         return true;
771     }
772     return false;
773 }
774
775 bool ContainerNode::getLowerRightCorner(int &xPos, int &yPos) const
776 {
777     if (!renderer())
778         return false;
779
780     RenderObject *o = renderer();
781     xPos = yPos = 0;
782     if (!o->isInline() || o->isReplaced())
783     {
784         o->absolutePosition(xPos, yPos);
785         xPos += o->width();
786         yPos += o->height() + o->borderTopExtra() + o->borderBottomExtra();
787         return true;
788     }
789     // find the last text/image child, to get a position
790     while(o) {
791         if(o->lastChild())
792             o = o->lastChild();
793         else if(o->previousSibling())
794             o = o->previousSibling();
795         else {
796             RenderObject *prev = 0;
797             while(!prev) {
798                 o = o->parent();
799                 if(!o) return false;
800                 prev = o->previousSibling();
801             }
802             o = prev;
803         }
804         if (o->isText() || o->isReplaced()) {
805             o->container()->absolutePosition(xPos, yPos);
806             if (o->isText())
807                 xPos += static_cast<RenderText *>(o)->minXPos() + o->width();
808             else
809                 xPos += o->xPos()+o->width();
810             yPos += o->yPos()+o->height();
811             return true;
812         }
813     }
814     return true;
815 }
816
817 IntRect ContainerNode::getRect() const
818 {
819     int xPos = 0, yPos = 0, xEnd = 0, yEnd = 0;
820     bool foundUpperLeft = getUpperLeftCorner(xPos,yPos);
821     bool foundLowerRight = getLowerRightCorner(xEnd,yEnd);
822     
823     // If we've found one corner, but not the other,
824     // then we should just return a point at the corner that we did find.
825     if (foundUpperLeft != foundLowerRight)
826     {
827         if (foundUpperLeft) {
828             xEnd = xPos;
829             yEnd = yPos;
830         } else {
831             xPos = xEnd;
832             yPos = yEnd;
833         }
834     } 
835
836     if (xEnd < xPos)
837         xEnd = xPos;
838     if (yEnd < yPos)
839         yEnd = yPos;
840         
841     return IntRect(xPos, yPos, xEnd - xPos, yEnd - yPos);
842 }
843
844 void ContainerNode::setFocus(bool received)
845 {
846     if (m_focused == received) return;
847
848     EventTargetNode::setFocus(received);
849
850     // note that we need to recalc the style
851     setChanged();
852 }
853
854 void ContainerNode::setActive(bool down, bool pause)
855 {
856     if (down == active()) return;
857
858     EventTargetNode::setActive(down);
859
860     // note that we need to recalc the style
861     // FIXME: Move to Element
862     if (renderer()) {
863         bool reactsToPress = renderer()->style()->affectedByActiveRules();
864         if (reactsToPress)
865             setChanged();
866         if (renderer() && renderer()->style()->hasAppearance()) {
867             if (theme()->stateChanged(renderer(), PressedState))
868                 reactsToPress = true;
869         }
870         if (reactsToPress && pause) {
871             // The delay here is subtle.  It relies on an assumption, namely that the amount of time it takes
872             // to repaint the "down" state of the control is about the same time as it would take to repaint the
873             // "up" state.  Once you assume this, you can just delay for 100ms - that time (assuming that after you
874             // leave this method, it will be about that long before the flush of the up state happens again).
875 #ifdef HAVE_FUNC_USLEEP
876             double startTime = currentTime();
877 #endif
878
879             // Ensure there are no pending changes
880             Document::updateDocumentsRendering();
881             // Do an immediate repaint.
882             if (renderer())
883                 renderer()->repaint(true);
884             
885             // FIXME: Find a substitute for usleep for Win32.
886             // Better yet, come up with a way of doing this that doesn't use this sort of thing at all.            
887 #ifdef HAVE_FUNC_USLEEP
888             // Now pause for a small amount of time (1/10th of a second from before we repainted in the pressed state)
889             double remainingTime = 0.1 - (currentTime() - startTime);
890             if (remainingTime > 0)
891                 usleep(static_cast<useconds_t>(remainingTime * 1000000.0));
892 #endif
893         }
894     }
895 }
896
897 void ContainerNode::setHovered(bool over)
898 {
899     if (over == hovered()) return;
900
901     EventTargetNode::setHovered(over);
902
903     // note that we need to recalc the style
904     // FIXME: Move to Element
905     if (renderer()) {
906         if (renderer()->style()->affectedByHoverRules())
907             setChanged();
908         if (renderer() && renderer()->style()->hasAppearance())
909             theme()->stateChanged(renderer(), HoverState);
910     }
911 }
912
913 unsigned ContainerNode::childNodeCount() const
914 {
915     unsigned count = 0;
916     Node *n;
917     for (n = firstChild(); n; n = n->nextSibling())
918         count++;
919     return count;
920 }
921
922 Node *ContainerNode::childNode(unsigned index) const
923 {
924     unsigned i;
925     Node *n = firstChild();
926     for (i = 0; n != 0 && i < index; i++)
927         n = n->nextSibling();
928     return n;
929 }
930
931 static void dispatchChildInsertionEvents(Node* child, ExceptionCode& ec)
932 {
933     ASSERT(!eventDispatchForbidden());
934
935     RefPtr<Node> c = child;
936     DocPtr<Document> doc = child->document();
937
938     if (c->parentNode() && c->parentNode()->inDocument())
939         c->insertedIntoDocument();
940     else
941         c->insertedIntoTree(true);
942
943     if (c->parentNode() && 
944         doc->hasListenerType(Document::DOMNODEINSERTED_LISTENER) &&
945         c->isEventTargetNode()) {
946         ec = 0;
947         EventTargetNodeCast(c.get())->dispatchEvent(new MutationEvent(DOMNodeInsertedEvent, true, false,
948             c->parentNode(), String(), String(), String(), 0), ec, true);
949         if (ec)
950             return;
951     }
952
953     // dispatch the DOMNodeInsertedIntoDocument event to all descendants
954     if (c->inDocument() && doc->hasListenerType(Document::DOMNODEINSERTEDINTODOCUMENT_LISTENER))
955         for (; c; c = c->traverseNextNode(child)) {
956             if (!c->isEventTargetNode())
957                 continue;
958           
959             ec = 0;
960             EventTargetNodeCast(c.get())->dispatchEvent(new MutationEvent(DOMNodeInsertedIntoDocumentEvent, false, false,
961                 0, String(), String(), String(), 0), ec, true);
962             if (ec)
963                 return;
964         }
965 }
966
967 static void dispatchChildRemovalEvents(Node* child, ExceptionCode& ec)
968 {
969     RefPtr<Node> c = child;
970     DocPtr<Document> doc = child->document();
971
972     // update auxiliary doc info (e.g. iterators) to note that node is being removed
973     doc->nodeWillBeRemoved(child);
974
975     // dispatch pre-removal mutation events
976     if (c->parentNode() && 
977         doc->hasListenerType(Document::DOMNODEREMOVED_LISTENER) &&
978         c->isEventTargetNode()) {
979         ec = 0;
980         EventTargetNodeCast(c.get())->dispatchEvent(new MutationEvent(DOMNodeRemovedEvent, true, false,
981             c->parentNode(), String(), String(), String(), 0), ec, true);
982         if (ec)
983             return;
984     }
985
986     // dispatch the DOMNodeRemovedFromDocument event to all descendants
987     if (c->inDocument() && doc->hasListenerType(Document::DOMNODEREMOVEDFROMDOCUMENT_LISTENER))
988         for (; c; c = c->traverseNextNode(child)) {
989             if (!c->isEventTargetNode())
990                 continue;
991             ec = 0;
992             EventTargetNodeCast(c.get())->dispatchEvent(new MutationEvent(DOMNodeRemovedFromDocumentEvent, false, false,
993                 0, String(), String(), String(), 0), ec, true);
994             if (ec)
995                 return;
996         }
997 }
998
999 }