18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *           (C) 1999 Antti Koivisto (koivisto@kde.org)
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *           (C) 2001 Dirk Mueller (mueller@kde.org)
58f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version.
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful,
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details.
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB.  If not, write to
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA.
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ContainerNode.h"
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "BeforeLoadEvent.h"
2728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu#include "MemoryCache.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ContainerNodeAlgorithms.h"
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "DeleteButtonController.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "EventNames.h"
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ExceptionCode.h"
32635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "FloatRect.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Frame.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameView.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "InlineTextBox.h"
36a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "InspectorInstrumentation.h"
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "MutationEvent.h"
386b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#include "ResourceLoadScheduler.h"
398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "Page.h"
40545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch#include "RenderBox.h"
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderTheme.h"
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RootInlineBox.h"
43635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <wtf/CurrentTime.h>
44dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include <wtf/Vector.h>
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockstatic void notifyChildInserted(Node*);
49231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic void dispatchChildInsertionEvents(Node*);
50231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic void dispatchChildRemovalEvents(Node*);
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttypedef Vector<std::pair<NodeCallback, RefPtr<Node> > > NodeCallbackQueue;
53dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blocktypedef Vector<RefPtr<Node>, 1> NodeVector;
548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic NodeCallbackQueue* s_postAttachCallbackQueue;
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic size_t s_attachDepth;
578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic bool s_shouldReEnableMemoryCacheCallsAfterAttach;
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic inline void collectNodes(Node* node, NodeVector& nodes)
602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    for (Node* child = node->firstChild(); child; child = child->nextSibling())
622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        nodes.append(child);
632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
65dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockstatic void collectTargetNodes(Node* node, NodeVector& nodes)
66dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
67dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (node->nodeType() != Node::DOCUMENT_FRAGMENT_NODE) {
68dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        nodes.append(node);
69dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return;
70dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    collectNodes(node, nodes);
72dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
73dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ContainerNode::removeAllChildren()
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    removeAllChildrenInContainer<Node, ContainerNode>(this);
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
795ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenvoid ContainerNode::takeAllChildrenFrom(ContainerNode* oldParent)
805ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
815ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    NodeVector children;
822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    collectNodes(oldParent, children);
835ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    oldParent->removeAllChildren();
845ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
855ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    for (unsigned i = 0; i < children.size(); ++i) {
865ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        ExceptionCode ec = 0;
8768513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (children[i]->attached())
8868513a70bcd92384395513322f1b801e7bf9c729Steve Block            children[i]->detach();
895ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        // FIXME: We need a no mutation event version of adoptNode.
905ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        RefPtr<Node> child = document()->adoptNode(children[i].release(), ec);
915ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        ASSERT(!ec);
9268513a70bcd92384395513322f1b801e7bf9c729Steve Block        parserAddChild(child.get());
9368513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (attached() && !child->attached())
9468513a70bcd92384395513322f1b801e7bf9c729Steve Block            child->attach();
955ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    }
965ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
975ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectContainerNode::~ContainerNode()
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    removeAllChildren();
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode& ec, bool shouldLazyAttach)
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Check that this node is not "floating".
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If it is, it can be deleted as a side effect of sending mutation events.
1072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    ASSERT(refCount() || parentOrHostNode());
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ec = 0;
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // insertBefore(node, 0) is equivalent to appendChild(node)
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!refChild)
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return appendChild(newChild, ec, shouldLazyAttach);
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Make sure adding the new child is OK.
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    checkAddChild(newChild.get(), ec);
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ec)
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // NOT_FOUND_ERR: Raised if refChild is not a child of this node
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (refChild->parentNode() != this) {
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = NOT_FOUND_ERR;
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
126dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    NodeVector targets;
127dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    collectTargetNodes(newChild.get(), targets);
128dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (targets.isEmpty())
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Now actually add the child(ren)
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (refChild->previousSibling() == newChild || refChild == newChild) // nothing to do
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Node> next = refChild;
1368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RefPtr<Node> refChildPreviousSibling = refChild->previousSibling();
137dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); ++it) {
138dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        Node* child = it->get();
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // If child is already present in the tree, first remove it from the old location.
141a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (ContainerNode* oldParent = child->parentNode())
142dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            oldParent->removeChild(child, ec);
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (ec)
144dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return false;
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // FIXME: After sending the mutation events, "this" could be destroyed.
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We can prevent that by doing a "ref", but first we have to make sure
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // that no callers call with ref count == 0 and parent = 0 (as of this
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // writing, there are definitely callers who call that way).
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Due to arbitrary code running in response to a DOM mutation event it's
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // possible that "next" is no longer a child of "this".
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // It's also possible that "child" has been inserted elsewhere.
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // In either of those cases, we'll just stop.
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (next->parentNode() != this)
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (child->parentNode())
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
160bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if ENABLE(INSPECTOR)
161a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        InspectorInstrumentation::willInsertDOMNode(document(), child, this);
162bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#endif
1635abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
1642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        child->setTreeScopeRecursively(treeScope());
1652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
166e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        insertBeforeCommon(next.get(), child);
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
168dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // Send notification about the children change.
1698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        childrenChanged(false, refChildPreviousSibling.get(), next.get(), 1);
170dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        notifyChildInserted(child);
171e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Add child to the rendering tree.
1736b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        if (attached() && !child->attached() && child->parentNode() == this) {
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (shouldLazyAttach)
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                child->lazyAttach();
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            else
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                child->attach();
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
180dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // Now that the child is attached to the render tree, dispatch
181dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // the relevant mutation events.
182dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        dispatchChildInsertionEvents(child);
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    dispatchSubtreeModifiedEvent();
1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
189e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid ContainerNode::insertBeforeCommon(Node* nextChild, Node* newChild)
190e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{
191e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    ASSERT(newChild);
1926b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    ASSERT(!newChild->parentNode()); // Use insertBefore if you need to handle reparenting (and want DOM mutation events).
193e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    ASSERT(!newChild->nextSibling());
194e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    ASSERT(!newChild->previousSibling());
195e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
196e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    forbidEventDispatch();
197e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    Node* prev = nextChild->previousSibling();
198e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    ASSERT(m_lastChild != prev);
199e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    nextChild->setPreviousSibling(newChild);
200e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    if (prev) {
201e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        ASSERT(m_firstChild != nextChild);
202e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        ASSERT(prev->nextSibling() == nextChild);
203e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        prev->setNextSibling(newChild);
204e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    } else {
205e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        ASSERT(m_firstChild == nextChild);
206e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        m_firstChild = newChild;
207e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    }
208e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    newChild->setParent(this);
209e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    newChild->setPreviousSibling(prev);
210e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    newChild->setNextSibling(nextChild);
211e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    allowEventDispatch();
212e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block}
213e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
214e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid ContainerNode::parserInsertBefore(PassRefPtr<Node> newChild, Node* nextChild)
215e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{
216e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    ASSERT(newChild);
217e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    ASSERT(nextChild);
218e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    ASSERT(nextChild->parentNode() == this);
219e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
220e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    NodeVector targets;
221e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    collectTargetNodes(newChild.get(), targets);
222e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    if (targets.isEmpty())
223e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        return;
224e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
225e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    if (nextChild->previousSibling() == newChild || nextChild == newChild) // nothing to do
226e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        return;
227e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
228e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    RefPtr<Node> next = nextChild;
229e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    RefPtr<Node> nextChildPreviousSibling = nextChild->previousSibling();
230e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); ++it) {
231e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        Node* child = it->get();
232e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
233bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if ENABLE(INSPECTOR)
234a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        InspectorInstrumentation::willInsertDOMNode(document(), child, this);
235bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#endif
2365abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
237e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        insertBeforeCommon(next.get(), child);
238e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
239e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        childrenChanged(true, nextChildPreviousSibling.get(), nextChild, 1);
240e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        notifyChildInserted(child);
241e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    }
242e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block}
243e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode& ec, bool shouldLazyAttach)
2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Check that this node is not "floating".
2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If it is, it can be deleted as a side effect of sending mutation events.
2482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    ASSERT(refCount() || parentOrHostNode());
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ec = 0;
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (oldChild == newChild) // nothing to do
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Make sure replacing the old child with the new is ok
2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    checkReplaceChild(newChild.get(), oldChild, ec);
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ec)
2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // NOT_FOUND_ERR: Raised if oldChild is not a child of this node.
2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!oldChild || oldChild->parentNode() != this) {
2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = NOT_FOUND_ERR;
2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Node> prev = oldChild->previousSibling();
2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Node> next = oldChild->nextSibling();
2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Remove the node we're replacing
2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Node> removedChild = oldChild;
2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    removeChild(oldChild, ec);
2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ec)
2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: After sending the mutation events, "this" could be destroyed.
2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We can prevent that by doing a "ref", but first we have to make sure
2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // that no callers call with ref count == 0 and parent = 0 (as of this
2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // writing, there are definitely callers who call that way).
2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool isFragment = newChild->nodeType() == DOCUMENT_FRAGMENT_NODE;
2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Add the new child(ren)
2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Node> child = isFragment ? newChild->firstChild() : newChild;
2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (child) {
2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // If the new child is already in the right place, we're done.
2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (prev && (prev == child || prev == child->previousSibling()))
2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // For a fragment we have more children to do.
2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RefPtr<Node> nextChild = isFragment ? child->nextSibling() : 0;
2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Remove child from its old position.
293a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (ContainerNode* oldParent = child->parentNode())
2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            oldParent->removeChild(child.get(), ec);
2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (ec)
2968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return false;
2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Due to arbitrary code running in response to a DOM mutation event it's
2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // possible that "prev" is no longer a child of "this".
3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // It's also possible that "child" has been inserted elsewhere.
3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // In either of those cases, we'll just stop.
3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (prev && prev->parentNode() != this)
3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (child->parentNode())
3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(!child->nextSibling());
3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(!child->previousSibling());
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
310bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if ENABLE(INSPECTOR)
311a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        InspectorInstrumentation::willInsertDOMNode(document(), child.get(), this);
312bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#endif
3135abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
3142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        child->setTreeScopeRecursively(treeScope());
31581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Add child after "prev".
3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        forbidEventDispatch();
3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Node* next;
3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (prev) {
3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            next = prev->nextSibling();
3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(m_firstChild != next);
3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            prev->setNextSibling(child.get());
3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            next = m_firstChild;
3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_firstChild = child.get();
3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (next) {
3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(m_lastChild != prev);
3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(next->previousSibling() == prev);
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            next->setPreviousSibling(child.get());
3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(m_lastChild == prev);
3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_lastChild = child.get();
3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        child->setParent(this);
3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        child->setPreviousSibling(prev.get());
3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        child->setNextSibling(next);
3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        allowEventDispatch();
3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
340967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        childrenChanged(false, prev.get(), next, 1);
341dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        notifyChildInserted(child.get());
3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Add child to the rendering tree
3446b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        if (attached() && !child->attached() && child->parentNode() == this) {
3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (shouldLazyAttach)
3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                child->lazyAttach();
3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            else
3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                child->attach();
3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
351dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // Now that the child is attached to the render tree, dispatch
352dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // the relevant mutation events.
353dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        dispatchChildInsertionEvents(child.get());
354dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        prev = child;
3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        child = nextChild.release();
3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    dispatchSubtreeModifiedEvent();
3608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
3618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ContainerNode::willRemove()
3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
36581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Vector<RefPtr<Node>, 10> nodes;
36681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    nodes.reserveInitialCapacity(childNodeCount());
3676b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    for (Node* n = m_lastChild; n; n = n->previousSibling())
3686b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        nodes.append(n);
3696b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    for (; nodes.size(); nodes.removeLast())
3706b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        nodes.last().get()->willRemove();
3718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    Node::willRemove();
3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3746c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenstatic void willRemoveChild(Node* child)
3758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3766c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    // update auxiliary doc info (e.g. iterators) to note that node is being removed
3776c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    child->document()->nodeWillBeRemoved(child);
3786c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    child->document()->incDOMTreeVersion();
3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // fire removed from document mutation events.
381231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    dispatchChildRemovalEvents(child);
38268513a70bcd92384395513322f1b801e7bf9c729Steve Block    child->willRemove();
3836c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen}
3846c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
3856c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenstatic void willRemoveChildren(ContainerNode* container)
3866c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen{
3876c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    container->document()->nodeChildrenWillBeRemoved(container);
3886c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    container->document()->incDOMTreeVersion();
3896c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
390f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    NodeVector children;
3912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    collectNodes(container, children);
392f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
393f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    for (NodeVector::const_iterator it = children.begin(); it != children.end(); it++) {
394f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        Node* child = it->get();
3956c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        // fire removed from document mutation events.
396f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        dispatchChildRemovalEvents(child);
39768513a70bcd92384395513322f1b801e7bf9c729Steve Block        child->willRemove();
3986c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    }
3998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool ContainerNode::removeChild(Node* oldChild, ExceptionCode& ec)
4028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Check that this node is not "floating".
4048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If it is, it can be deleted as a side effect of sending mutation events.
4052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    ASSERT(refCount() || parentOrHostNode());
4068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ec = 0;
4088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isReadOnlyNode()) {
4118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = NO_MODIFICATION_ALLOWED_ERR;
4128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
4138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // NOT_FOUND_ERR: Raised if oldChild is not a child of this node.
4168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!oldChild || oldChild->parentNode() != this) {
4178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = NOT_FOUND_ERR;
4188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
4198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Node> child = oldChild;
4226c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    willRemoveChild(child.get());
4238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Mutation events might have moved this child into a different parent.
4258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (child->parentNode() != this) {
4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = NOT_FOUND_ERR;
4278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
4288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    document()->removeFocusedNodeOfSubtree(child.get());
431dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
432dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Events fired when blurring currently focused node might have moved this
433dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // child into a different parent.
434dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (child->parentNode() != this) {
435dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        ec = NOT_FOUND_ERR;
436dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return false;
437dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
438dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
4398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: After sending the mutation events, "this" could be destroyed.
4408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We can prevent that by doing a "ref", but first we have to make sure
4418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // that no callers call with ref count == 0 and parent = 0 (as of this
4428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // writing, there are definitely callers who call that way).
4438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
444e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    Node* prev = child->previousSibling();
445e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    Node* next = child->nextSibling();
446e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    removeBetween(prev, next, child.get());
4478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Dispatch post-removal mutation events
4498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    childrenChanged(false, prev, next, -1);
4508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    dispatchSubtreeModifiedEvent();
4518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (child->inDocument())
4538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        child->removedFromDocument();
4548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
4558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        child->removedFromTree(true);
4568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return child;
4588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
460e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid ContainerNode::removeBetween(Node* previousChild, Node* nextChild, Node* oldChild)
461e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{
462e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    ASSERT(oldChild);
463e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    ASSERT(oldChild->parentNode() == this);
464e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
465e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    forbidEventDispatch();
466e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
467e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    // Remove from rendering tree
468e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    if (oldChild->attached())
469e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        oldChild->detach();
470e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
471e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    if (nextChild)
472e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        nextChild->setPreviousSibling(previousChild);
473e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    if (previousChild)
474e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        previousChild->setNextSibling(nextChild);
475e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    if (m_firstChild == oldChild)
476e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        m_firstChild = nextChild;
477e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    if (m_lastChild == oldChild)
478e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        m_lastChild = previousChild;
479e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
480e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    oldChild->setPreviousSibling(0);
481e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    oldChild->setNextSibling(0);
482e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    oldChild->setParent(0);
483e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
484e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    allowEventDispatch();
485e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block}
486e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
487e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid ContainerNode::parserRemoveChild(Node* oldChild)
488e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{
489e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    ASSERT(oldChild);
490e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    ASSERT(oldChild->parentNode() == this);
491e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
492e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    Node* prev = oldChild->previousSibling();
493e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    Node* next = oldChild->nextSibling();
494e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
495e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    removeBetween(prev, next, oldChild);
496e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
497e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    childrenChanged(true, prev, next, -1);
498e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    if (oldChild->inDocument())
499e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        oldChild->removedFromDocument();
500e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    else
501e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        oldChild->removedFromTree(true);
502e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block}
503e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
5048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// this differs from other remove functions because it forcibly removes all the children,
5058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// regardless of read-only status or event exceptions, e.g.
506a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid ContainerNode::removeChildren()
5078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_firstChild)
509a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return;
5108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // The container node can be removed from event handlers.
5126c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    RefPtr<ContainerNode> protect(this);
5136c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
5148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Do any prep work needed before actually starting to detach
5158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // and remove... e.g. stop loading frames, fire unload events.
5166c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    willRemoveChildren(protect.get());
5176c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
5188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // exclude this node when looking for removed focusedNode since only children will be removed
5198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    document()->removeFocusedNodeOfSubtree(this, true);
5208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    forbidEventDispatch();
52281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Vector<RefPtr<Node>, 10> removedChildren;
52381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    removedChildren.reserveInitialCapacity(childNodeCount());
5248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    while (RefPtr<Node> n = m_firstChild) {
5258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        Node* next = n->nextSibling();
52681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
527dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // Remove the node from the tree before calling detach or removedFromDocument (4427024, 4129744).
528dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // removeChild() does this after calling detach(). There is no explanation for
529dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // this discrepancy between removeChild() and its optimized version removeChildren().
5308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        n->setPreviousSibling(0);
5318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        n->setNextSibling(0);
5328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        n->setParent(0);
533dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
5348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_firstChild = next;
5358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (n == m_lastChild)
5368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_lastChild = 0;
537dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        removedChildren.append(n.release());
5388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
540dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    size_t removedChildrenCount = removedChildren.size();
54154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    size_t i;
54254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
54354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    // Detach the nodes only after properly removed from the tree because
54454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    // a. detaching requires a proper DOM tree (for counters and quotes for
54554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    // example) and during the previous loop the next sibling still points to
54654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    // the node being removed while the node being removed does not point back
54754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    // and does not point to the same parent as its next sibling.
54854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    // b. destroying Renderers of standalone nodes is sometimes faster.
54954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    for (i = 0; i < removedChildrenCount; ++i) {
55054cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        Node* removedChild = removedChildren[i].get();
55154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        if (removedChild->attached())
55254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block            removedChild->detach();
55354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    }
55454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
55554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    allowEventDispatch();
556dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
5578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Dispatch a single post-removal mutation event denoting a modified subtree.
558dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    childrenChanged(false, 0, 0, -static_cast<int>(removedChildrenCount));
5598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    dispatchSubtreeModifiedEvent();
5608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
56154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    for (i = 0; i < removedChildrenCount; ++i) {
562dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        Node* removedChild = removedChildren[i].get();
563dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (removedChild->inDocument())
564dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            removedChild->removedFromDocument();
565dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // removeChild() calls removedFromTree(true) if the child was not in the
566dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // document. There is no explanation for this discrepancy between removeChild()
567dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // and its optimized version removeChildren().
568dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
5698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bool shouldLazyAttach)
5728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Check that this node is not "floating".
5748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If it is, it can be deleted as a side effect of sending mutation events.
5752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    ASSERT(refCount() || parentOrHostNode());
5768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ec = 0;
5788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Make sure adding the new child is ok
5808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    checkAddChild(newChild.get(), ec);
5818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ec)
582dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return false;
583dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
5848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (newChild == m_lastChild) // nothing to do
5858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return newChild;
5868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
587dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    NodeVector targets;
588dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    collectTargetNodes(newChild.get(), targets);
589dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (targets.isEmpty())
5908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
5918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Now actually add the child(ren)
5938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Node> prev = lastChild();
594dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); ++it) {
595dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        Node* child = it->get();
5968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // If child is already present in the tree, first remove it
597a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (ContainerNode* oldParent = child->parentNode()) {
598dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            oldParent->removeChild(child, ec);
5998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (ec)
600dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                return false;
601dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
6028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // If the child has a parent again, just stop what we're doing, because
6038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // that means someone is doing something with DOM mutation -- can't re-parent
6048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // a child that already has a parent.
6058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (child->parentNode())
6068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
6078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
6088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
609bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if ENABLE(INSPECTOR)
610a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        InspectorInstrumentation::willInsertDOMNode(document(), child, this);
611bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#endif
6125abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
6132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        child->setTreeScopeRecursively(treeScope());
61481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
6158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Append child to the end of the list
6168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        forbidEventDispatch();
6178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        child->setParent(this);
6188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_lastChild) {
6198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            child->setPreviousSibling(m_lastChild);
620dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            m_lastChild->setNextSibling(child);
6218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else
622dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            m_firstChild = child;
623dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_lastChild = child;
6248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        allowEventDispatch();
6258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
626dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // Send notification about the children change.
6278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        childrenChanged(false, prev.get(), 0, 1);
628dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        notifyChildInserted(child);
6298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Add child to the rendering tree
6316b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        if (attached() && !child->attached() && child->parentNode() == this) {
6328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (shouldLazyAttach)
6338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                child->lazyAttach();
6348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            else
6358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                child->attach();
6368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
637dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
638dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // Now that the child is attached to the render tree, dispatch
639dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // the relevant mutation events.
640dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        dispatchChildInsertionEvents(child);
641967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        prev = child;
6428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    dispatchSubtreeModifiedEvent();
6458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
6468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
648e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid ContainerNode::parserAddChild(PassRefPtr<Node> newChild)
649ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{
650e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    ASSERT(newChild);
6516b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    ASSERT(!newChild->parentNode()); // Use appendChild if you need to handle reparenting (and want DOM mutation events).
652e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
653bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if ENABLE(INSPECTOR)
654a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    InspectorInstrumentation::willInsertDOMNode(document(), newChild.get(), this);
655bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#endif
6565abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
657ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    forbidEventDispatch();
658ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    Node* last = m_lastChild;
659ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    // FIXME: This method should take a PassRefPtr.
660e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    appendChildToContainer<Node, ContainerNode>(newChild.get(), this);
661ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    allowEventDispatch();
662ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
663e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    // FIXME: Why doesn't this use notifyChildInserted(newChild) instead?
664ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    document()->incDOMTreeVersion();
665ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    if (inDocument())
666ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        newChild->insertedIntoDocument();
667ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    childrenChanged(true, last, 0, 1);
668ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
669ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
670e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid ContainerNode::deprecatedParserAddChild(PassRefPtr<Node> node)
671ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{
672e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    parserAddChild(node);
6738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ContainerNode::suspendPostAttachCallbacks()
6768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!s_attachDepth) {
6788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        ASSERT(!s_shouldReEnableMemoryCacheCallsAfterAttach);
6798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (Page* page = document()->page()) {
6808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (page->areMemoryCacheClientCallsEnabled()) {
6818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                page->setMemoryCacheClientCallsEnabled(false);
6828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                s_shouldReEnableMemoryCacheCallsAfterAttach = true;
6838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            }
6848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
6856b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        resourceLoadScheduler()->suspendPendingRequests();
6868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
6878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ++s_attachDepth;
6888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ContainerNode::resumePostAttachCallbacks()
6918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (s_attachDepth == 1) {
6938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (s_postAttachCallbackQueue)
6948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            dispatchPostAttachCallbacks();
6958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (s_shouldReEnableMemoryCacheCallsAfterAttach) {
6968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            s_shouldReEnableMemoryCacheCallsAfterAttach = false;
6978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (Page* page = document()->page())
6988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                page->setMemoryCacheClientCallsEnabled(true);
6998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
7006b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        resourceLoadScheduler()->resumePendingRequests();
7018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
7028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    --s_attachDepth;
7038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ContainerNode::queuePostAttachCallback(NodeCallback callback, Node* node)
7068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!s_postAttachCallbackQueue)
7088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        s_postAttachCallbackQueue = new NodeCallbackQueue;
7098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    s_postAttachCallbackQueue->append(std::pair<NodeCallback, RefPtr<Node> >(callback, node));
7118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
713e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkebool ContainerNode::postAttachCallbacksAreSuspended()
714e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
715e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    return s_attachDepth;
716e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
717e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
7188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ContainerNode::dispatchPostAttachCallbacks()
7198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We recalculate size() each time through the loop because a callback
7218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // can add more callbacks to the end of the queue.
7228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (size_t i = 0; i < s_postAttachCallbackQueue->size(); ++i) {
7238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        std::pair<NodeCallback, RefPtr<Node> >& pair = (*s_postAttachCallbackQueue)[i];
7248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        NodeCallback callback = pair.first;
7258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Node* node = pair.second.get();
7268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        callback(node);
7288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    s_postAttachCallbackQueue->clear();
7308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ContainerNode::attach()
7338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (Node* child = m_firstChild; child; child = child->nextSibling())
7358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        child->attach();
7368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    Node::attach();
7378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ContainerNode::detach()
7408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (Node* child = m_firstChild; child; child = child->nextSibling())
7428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        child->detach();
74321939df44de1705786c545cd1bf519d47250322dBen Murdoch    clearChildNeedsStyleRecalc();
7448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    Node::detach();
7458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ContainerNode::insertedIntoDocument()
7488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    Node::insertedIntoDocument();
7508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    insertedIntoTree(false);
7512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
7522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // Determine set of children before operating on any of them.
7532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    NodeVector children;
7542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    collectNodes(this, children);
7552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
7562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    NodeVector::iterator it;
7572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    for (it = children.begin(); it != children.end() && inDocument(); ++it) {
7582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        Node* child = it->get();
7598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        child->insertedIntoDocument();
7602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
7618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ContainerNode::removedFromDocument()
7648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    Node::removedFromDocument();
7660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (document()->cssTarget() == this)
7670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        document()->setCSSTarget(0);
76821939df44de1705786c545cd1bf519d47250322dBen Murdoch    clearInDocument();
7698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    removedFromTree(false);
7708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    for (Node* child = m_firstChild; child; child = child->nextSibling())
7718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        child->removedFromDocument();
7728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ContainerNode::insertedIntoTree(bool deep)
7758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!deep)
7778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
7788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    for (Node* child = m_firstChild; child; child = child->nextSibling())
7798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        child->insertedIntoTree(true);
7808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ContainerNode::removedFromTree(bool deep)
7838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!deep)
7858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
7868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    for (Node* child = m_firstChild; child; child = child->nextSibling())
7878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        child->removedFromTree(true);
7888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ContainerNode::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
7918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
7938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!changedByParser && childCountDelta)
7948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        document()->nodeChildrenChanged(this);
7958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (document()->hasNodeListCaches())
7968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        notifyNodeListsChildrenChanged();
7978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ContainerNode::cloneChildNodes(ContainerNode *clone)
8008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // disable the delete button so it's elements are not serialized into the markup
8022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    bool isEditorEnabled = false;
8032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (document()->frame() && document()->frame()->editor()->canEdit()) {
8042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        SelectionController* selection = document()->frame()->selection();
8052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        Element* root = selection ? selection->rootEditableElement() : 0;
8062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        isEditorEnabled = root && isDescendantOf(root);
8072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
8082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (isEditorEnabled)
8092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            document()->frame()->editor()->deleteButtonController()->disable();
8102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
8112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
8128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ExceptionCode ec = 0;
8138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (Node* n = firstChild(); n && !ec; n = n->nextSibling())
8148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        clone->appendChild(n->cloneNode(true), ec);
8150617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    if (isEditorEnabled && document()->frame())
8168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        document()->frame()->editor()->deleteButtonController()->enable();
8178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
819635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool ContainerNode::getUpperLeftCorner(FloatPoint& point) const
8208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!renderer())
8228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
823635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // What is this code really trying to do?
8248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject *o = renderer();
8258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject *p = o;
8268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!o->isInline() || o->isReplaced()) {
828967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        point = o->localToAbsolute(FloatPoint(), false, true);
8298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
8308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
8318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // find the next text/image child, to get a position
833635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    while (o) {
8348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        p = o;
8358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (o->firstChild())
8368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            o = o->firstChild();
837635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        else if (o->nextSibling())
8388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            o = o->nextSibling();
8398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else {
8408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            RenderObject *next = 0;
8418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            while (!next && o->parent()) {
8428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                o = o->parent();
8438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                next = o->nextSibling();
8448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
8458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            o = next;
8468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!o)
8488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
8498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
8508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        ASSERT(o);
8518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!o->isInline() || o->isReplaced()) {
853967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            point = o->localToAbsolute(FloatPoint(), false, true);
8548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return true;
8558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
8568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (p->node() && p->node() == this && o->isText() && !o->isBR() && !toRenderText(o)->firstTextBox()) {
8588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // do nothing - skip unrendered whitespace that is a child or next sibling of the anchor
8598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if ((o->isText() && !o->isBR()) || o->isReplaced()) {
860967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            point = FloatPoint();
861635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (o->isText() && toRenderText(o)->firstTextBox()) {
862635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                point.move(toRenderText(o)->linesBoundingBox().x(),
863231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                           toRenderText(o)->firstTextBox()->root()->lineTop());
864635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            } else if (o->isBox()) {
865635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                RenderBox* box = toRenderBox(o);
866635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                point.move(box->x(), box->y());
8678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
868967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            point = o->container()->localToAbsolute(point, false, true);
8698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return true;
8708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
8718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
8728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If the target doesn't have any children or siblings that could be used to calculate the scroll position, we must be
874635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // at the end of the document.  Scroll to the bottom. FIXME: who said anything about scrolling?
8758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!o && document()->view()) {
876635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        point = FloatPoint(0, document()->view()->contentsHeight());
8778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
8788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
8798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
8808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
882635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// FIXME: This doesn't work correctly with transforms.
883635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool ContainerNode::getLowerRightCorner(FloatPoint& point) const
8848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!renderer())
8868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
8878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderObject* o = renderer();
8898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!o->isInline() || o->isReplaced()) {
890635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        RenderBox* box = toRenderBox(o);
891967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        point = o->localToAbsolute(FloatPoint(), false, true);
892635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        point.move(box->width(), box->height());
8938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
8948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
895635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
8968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // find the last text/image child, to get a position
897635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    while (o) {
898635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (o->lastChild())
8998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            o = o->lastChild();
900635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        else if (o->previousSibling())
9018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            o = o->previousSibling();
9028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else {
9038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            RenderObject* prev = 0;
9048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            while (!prev) {
9058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                o = o->parent();
906635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                if (!o)
907635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    return false;
9088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                prev = o->previousSibling();
9098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
9108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            o = prev;
9118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
9128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        ASSERT(o);
9138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (o->isText() || o->isReplaced()) {
914967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            point = FloatPoint();
915635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (o->isText()) {
916635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                RenderText* text = toRenderText(o);
917635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                IntRect linesBox = text->linesBoundingBox();
9186b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                if (!linesBox.x() && !linesBox.width() && !linesBox.y() && !linesBox.height())
9196b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                    continue;
9208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                point.move(linesBox.x() + linesBox.width(), linesBox.y() + linesBox.height());
921635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            } else {
922635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                RenderBox* box = toRenderBox(o);
923635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                point.move(box->x() + box->width(), box->y() + box->height());
924635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            }
925967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            point = o->container()->localToAbsolute(point, false, true);
9268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return true;
9278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
9288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
9308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectIntRect ContainerNode::getRect() const
9338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
934635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    FloatPoint  upperLeft, lowerRight;
935635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    bool foundUpperLeft = getUpperLeftCorner(upperLeft);
936635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    bool foundLowerRight = getLowerRightCorner(lowerRight);
9378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If we've found one corner, but not the other,
9398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // then we should just return a point at the corner that we did find.
9408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (foundUpperLeft != foundLowerRight) {
941635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (foundUpperLeft)
942635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            lowerRight = upperLeft;
943635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        else
944635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            upperLeft = lowerRight;
9458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
947635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    lowerRight.setX(max(upperLeft.x(), lowerRight.x()));
948635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    lowerRight.setY(max(upperLeft.y(), lowerRight.y()));
949635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
950635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return enclosingIntRect(FloatRect(upperLeft, lowerRight - upperLeft));
9518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ContainerNode::setFocus(bool received)
9548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (focused() == received)
9568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
9578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    Node::setFocus(received);
9598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // note that we need to recalc the style
9615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    setNeedsStyleRecalc();
9628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ContainerNode::setActive(bool down, bool pause)
9658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (down == active()) return;
9678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    Node::setActive(down);
9698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // note that we need to recalc the style
9718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: Move to Element
9728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (renderer()) {
9738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool reactsToPress = renderer()->style()->affectedByActiveRules();
9748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (reactsToPress)
9755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            setNeedsStyleRecalc();
9768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (renderer() && renderer()->style()->hasAppearance()) {
9770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            if (renderer()->theme()->stateChanged(renderer(), PressedState))
9788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                reactsToPress = true;
9798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
9808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (reactsToPress && pause) {
9818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // The delay here is subtle.  It relies on an assumption, namely that the amount of time it takes
9828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // to repaint the "down" state of the control is about the same time as it would take to repaint the
9838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // "up" state.  Once you assume this, you can just delay for 100ms - that time (assuming that after you
9848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // leave this method, it will be about that long before the flush of the up state happens again).
9858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef HAVE_FUNC_USLEEP
9868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            double startTime = currentTime();
9878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
9888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Ensure there are no pending changes
9905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            Document::updateStyleForAllDocuments();
9918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Do an immediate repaint.
9928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (renderer())
9938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                renderer()->repaint(true);
9948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // FIXME: Find a substitute for usleep for Win32.
9968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Better yet, come up with a way of doing this that doesn't use this sort of thing at all.
9978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef HAVE_FUNC_USLEEP
9988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Now pause for a small amount of time (1/10th of a second from before we repainted in the pressed state)
9998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            double remainingTime = 0.1 - (currentTime() - startTime);
10008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (remainingTime > 0)
10018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                usleep(static_cast<useconds_t>(remainingTime * 1000000.0));
10028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
10038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
10048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ContainerNode::setHovered(bool over)
10088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (over == hovered()) return;
10108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    Node::setHovered(over);
10128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // note that we need to recalc the style
10148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: Move to Element
10158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (renderer()) {
10168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (renderer()->style()->affectedByHoverRules())
10175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            setNeedsStyleRecalc();
10188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (renderer() && renderer()->style()->hasAppearance())
10190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            renderer()->theme()->stateChanged(renderer(), HoverState);
10208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectunsigned ContainerNode::childNodeCount() const
10248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned count = 0;
10268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node *n;
10278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (n = firstChild(); n; n = n->nextSibling())
10288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        count++;
10298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return count;
10308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNode *ContainerNode::childNode(unsigned index) const
10338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned i;
10358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node *n = firstChild();
10368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (i = 0; n != 0 && i < index; i++)
10378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        n = n->nextSibling();
10388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return n;
10398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1041dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockstatic void notifyChildInserted(Node* child)
10428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!eventDispatchForbidden());
10448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1045bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if ENABLE(INSPECTOR)
1046a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    InspectorInstrumentation::didInsertDOMNode(child->document(), child);
1047bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#endif
1048d0825bca7fe65beaee391d30da42e937db621564Steve Block
10498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Node> c = child;
1050231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    RefPtr<Document> document = child->document();
10518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10526b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    Node* parentOrHostNode = c->parentOrHostNode();
10536b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (parentOrHostNode && parentOrHostNode->inDocument())
10548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        c->insertedIntoDocument();
10558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
10568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        c->insertedIntoTree(true);
10578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1058231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    document->incDOMTreeVersion();
1059dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
1060dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
1061dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockstatic void dispatchChildInsertionEvents(Node* child)
1062dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
1063dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    ASSERT(!eventDispatchForbidden());
1064dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
1065dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    RefPtr<Node> c = child;
1066dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    RefPtr<Document> document = child->document();
10678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1068231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (c->parentNode() && document->hasListenerType(Document::DOMNODEINSERTED_LISTENER))
1069f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        c->dispatchScopedEvent(MutationEvent::create(eventNames().DOMNodeInsertedEvent, true, c->parentNode()));
10708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // dispatch the DOMNodeInsertedIntoDocument event to all descendants
1072231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (c->inDocument() && document->hasListenerType(Document::DOMNODEINSERTEDINTODOCUMENT_LISTENER)) {
1073231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        for (; c; c = c->traverseNextNode(child))
1074f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            c->dispatchScopedEvent(MutationEvent::create(eventNames().DOMNodeInsertedIntoDocumentEvent, false));
1075231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
10768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1078231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic void dispatchChildRemovalEvents(Node* child)
10798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10806c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    ASSERT(!eventDispatchForbidden());
10816c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
1082bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if ENABLE(INSPECTOR)
1083a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    InspectorInstrumentation::willRemoveDOMNode(child->document(), child);
1084bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#endif
1085d0825bca7fe65beaee391d30da42e937db621564Steve Block
10868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Node> c = child;
1087231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    RefPtr<Document> document = child->document();
10888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // dispatch pre-removal mutation events
1090231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (c->parentNode() && document->hasListenerType(Document::DOMNODEREMOVED_LISTENER))
1091f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        c->dispatchScopedEvent(MutationEvent::create(eventNames().DOMNodeRemovedEvent, true, c->parentNode()));
10928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // dispatch the DOMNodeRemovedFromDocument event to all descendants
1094231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (c->inDocument() && document->hasListenerType(Document::DOMNODEREMOVEDFROMDOCUMENT_LISTENER)) {
1095231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        for (; c; c = c->traverseNextNode(child))
1096f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            c->dispatchScopedEvent(MutationEvent::create(eventNames().DOMNodeRemovedFromDocumentEvent, false));
1097231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
10988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1100231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockbool ContainerNode::dispatchBeforeLoadEvent(const String& sourceURL)
1101231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
1102cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    if (!document()->hasListenerType(Document::BEFORELOAD_LISTENER))
1103cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        return true;
1104cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
1105231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    RefPtr<ContainerNode> protector(this);
1106231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    RefPtr<BeforeLoadEvent> beforeLoadEvent = BeforeLoadEvent::create(sourceURL);
1107231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    dispatchEvent(beforeLoadEvent.get());
1108cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    return !beforeLoadEvent->defaultPrevented();
11098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1110231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1111231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} // namespace WebCore
1112