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