15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) Research In Motion Limited 2010. All rights reserved.
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met:
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer in the
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    documentation and/or other materials provided with the distribution.
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderObjectChildList.h"
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/accessibility/AXObjectCache.h"
3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderCounter.h"
3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderObject.h"
3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderView.h"
3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/style/RenderStyle.h"
355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore {
375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderObjectChildList::destroyLeftoverChildren()
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (firstChild()) {
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (firstChild()->isListMarker() || (firstChild()->style()->styleType() == FIRST_LETTER && !firstChild()->isText()))
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            firstChild()->remove();  // List markers are owned by their enclosing list and so don't get destroyed by this container. Similarly, first letters are destroyed by their remaining text fragment.
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else if (firstChild()->isRunIn() && firstChild()->node()) {
44926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            firstChild()->node()->setRenderer(0);
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            firstChild()->node()->setNeedsStyleRecalc();
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            firstChild()->destroy();
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else {
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Destroy any anonymous children remaining in the render tree, as well as implicit (shadow) DOM elements like those used in the engine-based text fields.
49926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            if (firstChild()->node())
50926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                firstChild()->node()->setRenderer(0);
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            firstChild()->destroy();
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderObject* RenderObjectChildList::removeChildNode(RenderObject* owner, RenderObject* oldChild, bool notifyRenderer)
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(oldChild->parent() == owner);
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (oldChild->isFloatingOrOutOfFlowPositioned())
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        toRenderBox(oldChild)->removeFloatingOrPositionedChildFromBlockLists();
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // So that we'll get the appropriate dirty bit set (either that a normal flow child got yanked or
64926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // that a positioned child got yanked). We also repaint, so that the area exposed when the child
65926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // disappears gets repainted properly.
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!owner->documentBeingDestroyed() && notifyRenderer && oldChild->everHadLayout()) {
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        oldChild->setNeedsLayoutAndPrefWidthsRecalc();
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // We only repaint |oldChild| if we have a RenderLayer as its visual overflow may not be tracked by its parent.
69926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (oldChild->isBody())
70926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            owner->view()->repaint();
71926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        else
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            oldChild->repaint();
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If we have a line box wrapper, delete it.
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (oldChild->isBox())
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        toRenderBox(oldChild)->deleteLineBoxWrapper();
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If oldChild is the start or end of the selection, then clear the selection to
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // avoid problems of invalid pointers.
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: The FrameSelection should be responsible for this when it
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // is notified of DOM mutations.
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!owner->documentBeingDestroyed() && oldChild->isSelectionBorder())
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        owner->view()->clearSelection();
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!owner->documentBeingDestroyed() && notifyRenderer)
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        oldChild->willBeRemovedFromTree();
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // WARNING: There should be no code running between willBeRemovedFromTree and the actual removal below.
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // This is needed to avoid race conditions where willBeRemovedFromTree would dirty the tree's structure
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // and the code running here would force an untimely rebuilding, leaving |oldChild| dangling.
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (oldChild->previousSibling())
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (oldChild->nextSibling())
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling());
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (firstChild() == oldChild)
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        setFirstChild(oldChild->nextSibling());
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (lastChild() == oldChild)
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        setLastChild(oldChild->previousSibling());
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    oldChild->setPreviousSibling(0);
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    oldChild->setNextSibling(0);
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    oldChild->setParent(0);
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // rendererRemovedFromTree walks the whole subtree. We can improve performance
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // by skipping this step when destroying the entire tree.
109926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!owner->documentBeingDestroyed())
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderCounter::rendererRemovedFromTree(oldChild);
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
112926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (AXObjectCache* cache = owner->document()->existingAXObjectCache())
113926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        cache->childrenChanged(owner);
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return oldChild;
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
118926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void RenderObjectChildList::insertChildNode(RenderObject* owner, RenderObject* newChild, RenderObject* beforeChild, bool notifyRenderer)
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
120926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ASSERT(!newChild->parent());
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!owner->isBlockFlow() || (!newChild->isTableSection() && !newChild->isTableRow() && !newChild->isTableCell()));
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
123926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    while (beforeChild && beforeChild->parent() && beforeChild->parent() != owner)
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        beforeChild = beforeChild->parent();
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
126926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // This should never happen, but if it does prevent render tree corruption
127926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // where child->parent() ends up being owner but child->nextSibling()->parent()
128926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // is not owner.
129926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (beforeChild && beforeChild->parent() != owner) {
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT_NOT_REACHED();
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
134926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    newChild->setParent(owner);
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
136926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (firstChild() == beforeChild)
137926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        setFirstChild(newChild);
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
139926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (beforeChild) {
140926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        RenderObject* previousSibling = beforeChild->previousSibling();
141926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (previousSibling)
142926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            previousSibling->setNextSibling(newChild);
143926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        newChild->setPreviousSibling(previousSibling);
144926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        newChild->setNextSibling(beforeChild);
145926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        beforeChild->setPreviousSibling(newChild);
146926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    } else {
147926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (lastChild())
148926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            lastChild()->setNextSibling(newChild);
149926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        newChild->setPreviousSibling(lastChild());
150926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        setLastChild(newChild);
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
153926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!owner->documentBeingDestroyed() && notifyRenderer)
154926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        newChild->insertedIntoTree();
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
156926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!owner->documentBeingDestroyed()) {
157926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        RenderCounter::rendererSubtreeAttached(newChild);
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
160926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    newChild->setNeedsLayoutAndPrefWidthsRecalc();
161926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!owner->normalChildNeedsLayout())
162d24c94b5090b6aa121f0f82325c9379004dc3196Ben Murdoch        owner->setChildNeedsLayout(); // We may supply the static position for an absolute positioned child.
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
164926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (AXObjectCache* cache = owner->document()->axObjectCache())
165926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        cache->childrenChanged(owner);
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore
169