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