Home | History | Annotate | Download | only in dom
      1 /*
      2  * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org)
      3  *           (C) 1999 Antti Koivisto (koivisto (at) kde.org)
      4  *           (C) 2001 Dirk Mueller (mueller (at) 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 
     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 inline void collectNodes(Node* node, NodeVector& nodes)
     60 {
     61     for (Node* child = node->firstChild(); child; child = child->nextSibling())
     62         nodes.append(child);
     63 }
     64 
     65 static 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 
     74 void ContainerNode::removeAllChildren()
     75 {
     76     removeAllChildrenInContainer<Node, ContainerNode>(this);
     77 }
     78 
     79 void 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 
     98 ContainerNode::~ContainerNode()
     99 {
    100     removeAllChildren();
    101 }
    102 
    103 bool 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 
    189 void 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 
    214 void 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 
    244 bool 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 
    363 void 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 
    374 static 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 
    385 static 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 
    401 bool 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 
    460 void 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 
    487 void 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.
    506 void 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 
    571 bool 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 
    648 void 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 
    670 void ContainerNode::deprecatedParserAddChild(PassRefPtr<Node> node)
    671 {
    672     parserAddChild(node);
    673 }
    674 
    675 void 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 
    690 void 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 
    705 void 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 
    713 bool ContainerNode::postAttachCallbacksAreSuspended()
    714 {
    715     return s_attachDepth;
    716 }
    717 
    718 void 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 
    732 void ContainerNode::attach()
    733 {
    734     for (Node* child = m_firstChild; child; child = child->nextSibling())
    735         child->attach();
    736     Node::attach();
    737 }
    738 
    739 void ContainerNode::detach()
    740 {
    741     for (Node* child = m_firstChild; child; child = child->nextSibling())
    742         child->detach();
    743     clearChildNeedsStyleRecalc();
    744     Node::detach();
    745 }
    746 
    747 void 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 
    763 void 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 
    774 void 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 
    782 void 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 
    790 void 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 
    799 void 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 
    819 bool 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.
    883 bool 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 
    932 IntRect 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 
    953 void 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 
    964 void 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 
   1007 void 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 
   1023 unsigned 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 
   1032 Node *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 
   1041 static 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 
   1061 static 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 
   1078 static 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 
   1100 bool 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