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