18f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian/*
2967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
3967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch * Copyright (C) Research In Motion Limited 2010. All rights reserved.
48f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian *
58f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * Redistribution and use in source and binary forms, with or without
68f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * modification, are permitted provided that the following conditions
78f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * are met:
88f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * 1. Redistributions of source code must retain the above copyright
98f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian *    notice, this list of conditions and the following disclaimer.
108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * 2. Redistributions in binary form must reproduce the above copyright
118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian *    notice, this list of conditions and the following disclaimer in the
128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian *    documentation and/or other materials provided with the distribution.
138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian *
148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian */
268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "config.h"
288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "RenderObjectChildList.h"
298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "AXObjectCache.h"
3165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "ContentData.h"
328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "RenderBlock.h"
338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "RenderCounter.h"
345ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "RenderImage.h"
355ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "RenderImageResourceStyleImage.h"
368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "RenderInline.h"
378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "RenderLayer.h"
388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "RenderListItem.h"
3981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "RenderQuote.h"
408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "RenderStyle.h"
418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "RenderTextFragment.h"
428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "RenderView.h"
438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qiannamespace WebCore {
458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderObjectChildList::destroyLeftoverChildren()
478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    while (firstChild()) {
498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (firstChild()->isListMarker() || (firstChild()->style()->styleType() == FIRST_LETTER && !firstChild()->isText()))
508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            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.
51967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        else if (firstChild()->isRunIn() && firstChild()->node()) {
52967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            firstChild()->node()->setRenderer(0);
53967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            firstChild()->node()->setNeedsStyleRecalc();
54967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            firstChild()->destroy();
55967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        } else {
568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // 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.
578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (firstChild()->node())
588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                firstChild()->node()->setRenderer(0);
598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            firstChild()->destroy();
608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianRenderObject* RenderObjectChildList::removeChildNode(RenderObject* owner, RenderObject* oldChild, bool fullRemove)
658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT(oldChild->parent() == owner);
678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // So that we'll get the appropriate dirty bit set (either that a normal flow child got yanked or
698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // that a positioned child got yanked).  We also repaint, so that the area exposed when the child
708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // disappears gets repainted properly.
718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!owner->documentBeingDestroyed() && fullRemove && oldChild->m_everHadLayout) {
728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        oldChild->setNeedsLayoutAndPrefWidthsRecalc();
73967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        if (oldChild->isBody())
74967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            owner->view()->repaint();
75967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        else
76967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            oldChild->repaint();
778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
78967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // If we have a line box wrapper, delete it.
808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (oldChild->isBox())
818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        toRenderBox(oldChild)->deleteLineBoxWrapper();
828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!owner->documentBeingDestroyed() && fullRemove) {
848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // if we remove visible child from an invisible parent, we don't know the layer visibility any more
858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RenderLayer* layer = 0;
868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (owner->style()->visibility() != VISIBLE && oldChild->style()->visibility() == VISIBLE && !oldChild->hasLayer()) {
878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            layer = owner->enclosingLayer();
888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            layer->dirtyVisibleContentStatus();
898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian         // Keep our layer hierarchy updated.
928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (oldChild->firstChild() || oldChild->hasLayer()) {
938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (!layer)
948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                layer = owner->enclosingLayer();
958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            oldChild->removeLayers(layer);
968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
97dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (oldChild->isListItem())
99dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            toRenderListItem(oldChild)->updateListMarkerNumbers();
100dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
1018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (oldChild->isPositioned() && owner->childrenInline())
1028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            owner->dirtyLinesFromChangedChild(oldChild);
1035ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
1045ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#if ENABLE(SVG)
1055ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        // Update cached boundaries in SVG renderers, if a child is removed.
1065ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        owner->setNeedsBoundariesUpdate();
1075ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#endif
1088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
1098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // If oldChild is the start or end of the selection, then clear the selection to
1118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // avoid problems of invalid pointers.
1128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // FIXME: The SelectionController should be responsible for this when it
1138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // is notified of DOM mutations.
1148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!owner->documentBeingDestroyed() && oldChild->isSelectionBorder())
1158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        owner->view()->clearSelection();
1168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // remove the child
1188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (oldChild->previousSibling())
1198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());
1208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (oldChild->nextSibling())
1218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling());
1228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (firstChild() == oldChild)
1248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        setFirstChild(oldChild->nextSibling());
1258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (lastChild() == oldChild)
1268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        setLastChild(oldChild->previousSibling());
1278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    oldChild->setPreviousSibling(0);
1298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    oldChild->setNextSibling(0);
1308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    oldChild->setParent(0);
1318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
13254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    RenderCounter::rendererRemovedFromTree(oldChild);
13381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    RenderQuote::rendererRemovedFromTree(oldChild);
1342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (AXObjectCache::accessibilityEnabled())
1368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        owner->document()->axObjectCache()->childrenChanged(owner);
1378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return oldChild;
1398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
1408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderObjectChildList::appendChildNode(RenderObject* owner, RenderObject* newChild, bool fullAppend)
1428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
1438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT(newChild->parent() == 0);
1448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT(!owner->isBlockFlow() || (!newChild->isTableSection() && !newChild->isTableRow() && !newChild->isTableCell()));
1458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    newChild->setParent(owner);
1478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderObject* lChild = lastChild();
1488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (lChild) {
1508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        newChild->setPreviousSibling(lChild);
1518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        lChild->setNextSibling(newChild);
1528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    } else
1538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        setFirstChild(newChild);
1548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    setLastChild(newChild);
1568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (fullAppend) {
1588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // Keep our layer hierarchy updated.  Optimize for the common case where we don't have any children
1598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // and don't have a layer attached to ourselves.
1608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RenderLayer* layer = 0;
1618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (newChild->firstChild() || newChild->hasLayer()) {
1628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            layer = owner->enclosingLayer();
1638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            newChild->addLayers(layer, newChild);
1648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
1658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // if the new child is visible but this object was not, tell the layer it has some visible content
1678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // that needs to be drawn and layer visibility optimization can't be used
1688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (owner->style()->visibility() != VISIBLE && newChild->style()->visibility() == VISIBLE && !newChild->hasLayer()) {
1698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (!layer)
1708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                layer = owner->enclosingLayer();
1718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (layer)
1728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                layer->setHasVisibleContent(true);
1738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
174dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
175dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (newChild->isListItem())
176dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            toRenderListItem(newChild)->updateListMarkerNumbers();
177dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
1788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (!newChild->isFloatingOrPositioned() && owner->childrenInline())
1798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            owner->dirtyLinesFromChangedChild(newChild);
1808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
1812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    RenderCounter::rendererSubtreeAttached(newChild);
18281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    RenderQuote::rendererSubtreeAttached(newChild);
1838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    newChild->setNeedsLayoutAndPrefWidthsRecalc(); // Goes up the containing block hierarchy.
1848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!owner->normalChildNeedsLayout())
1858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        owner->setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child.
1868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (AXObjectCache::accessibilityEnabled())
1888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        owner->document()->axObjectCache()->childrenChanged(owner);
1898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
1908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderObjectChildList::insertChildNode(RenderObject* owner, RenderObject* child, RenderObject* beforeChild, bool fullInsert)
1928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
1938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!beforeChild) {
1945af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        appendChildNode(owner, child, fullInsert);
1958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
1968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
1978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT(!child->parent());
1998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    while (beforeChild->parent() != owner && beforeChild->parent()->isAnonymousBlock())
2008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        beforeChild = beforeChild->parent();
2018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT(beforeChild->parent() == owner);
2028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT(!owner->isBlockFlow() || (!child->isTableSection() && !child->isTableRow() && !child->isTableCell()));
2048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (beforeChild == firstChild())
2068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        setFirstChild(child);
2078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderObject* prev = beforeChild->previousSibling();
2098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    child->setNextSibling(beforeChild);
2108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    beforeChild->setPreviousSibling(child);
2118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (prev)
2128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        prev->setNextSibling(child);
2138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    child->setPreviousSibling(prev);
2148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    child->setParent(owner);
2168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (fullInsert) {
2188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // Keep our layer hierarchy updated.  Optimize for the common case where we don't have any children
2198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // and don't have a layer attached to ourselves.
2208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RenderLayer* layer = 0;
2218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (child->firstChild() || child->hasLayer()) {
2228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            layer = owner->enclosingLayer();
2238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            child->addLayers(layer, child);
2248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
2258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // if the new child is visible but this object was not, tell the layer it has some visible content
2278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // that needs to be drawn and layer visibility optimization can't be used
2288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (owner->style()->visibility() != VISIBLE && child->style()->visibility() == VISIBLE && !child->hasLayer()) {
2298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (!layer)
2308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                layer = owner->enclosingLayer();
2318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (layer)
2328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                layer->setHasVisibleContent(true);
2338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
2348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
235dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (child->isListItem())
236dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            toRenderListItem(child)->updateListMarkerNumbers();
237dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
2388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (!child->isFloating() && owner->childrenInline())
2398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            owner->dirtyLinesFromChangedChild(child);
2408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
2418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    RenderCounter::rendererSubtreeAttached(child);
24381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    RenderQuote::rendererSubtreeAttached(child);
2448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    child->setNeedsLayoutAndPrefWidthsRecalc();
2458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!owner->normalChildNeedsLayout())
2468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        owner->setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child.
2478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (AXObjectCache::accessibilityEnabled())
2498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        owner->document()->axObjectCache()->childrenChanged(owner);
2508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
2518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic RenderObject* findBeforeAfterParent(RenderObject* object)
2538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
2548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Only table parts need to search for the :before or :after parent
2558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!(object->isTable() || object->isTableSection() || object->isTableRow()))
2568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return object;
2578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderObject* beforeAfterParent = object;
2598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    while (beforeAfterParent && !(beforeAfterParent->isText() || beforeAfterParent->isImage()))
2608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        beforeAfterParent = beforeAfterParent->firstChild();
261d3a21b5683eb14a1c0c880a30488578f484e8ccaSteve Block    return beforeAfterParent ? beforeAfterParent->parent() : 0;
2628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
2638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2642fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockRenderObject* RenderObjectChildList::beforePseudoElementRenderer(const RenderObject* owner) const
2652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
2662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // An anonymous (generated) inline run-in that has PseudoId BEFORE must come from a grandparent.
2672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // Therefore we should skip these generated run-ins when checking our immediate children.
2682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // If we don't find our :before child immediately, then we should check if we own a
2692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // generated inline run-in in the next level of children.
2702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    RenderObject* first = const_cast<RenderObject*>(owner);
2712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    do {
2722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        first = first->firstChild();
2739a26d18f4c7e98b479be700575d003f873214550John Reck        // Skip list markers and generated run-ins.
2749a26d18f4c7e98b479be700575d003f873214550John Reck        while (first && (first->isListMarker() || (first->isRenderInline() && first->isRunIn())))
2759a26d18f4c7e98b479be700575d003f873214550John Reck            first = first->nextInPreOrderAfterChildren(owner);
2762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    } while (first && first->isAnonymous() && first->style()->styleType() == NOPSEUDO);
2772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
2782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!first)
2792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return 0;
2802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
2812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (first->style()->styleType() == BEFORE)
2822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return first;
2832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
2842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // Check for a possible generated run-in, using run-in positioning rules.
2852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    first = owner->firstChild();
2862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!first->isRenderBlock())
2872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return 0;
2889a26d18f4c7e98b479be700575d003f873214550John Reck
2899a26d18f4c7e98b479be700575d003f873214550John Reck    first = first->firstChild();
2909a26d18f4c7e98b479be700575d003f873214550John Reck    // We still need to skip any list markers that could exist before the run-in.
2919a26d18f4c7e98b479be700575d003f873214550John Reck    while (first && first->isListMarker())
2922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        first = first->nextSibling();
2939a26d18f4c7e98b479be700575d003f873214550John Reck    if (first && first->style()->styleType() == BEFORE && first->isRenderInline() && first->isRunIn())
2949a26d18f4c7e98b479be700575d003f873214550John Reck        return first;
2959a26d18f4c7e98b479be700575d003f873214550John Reck
2962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return 0;
2972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
2982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
2992fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockRenderObject* RenderObjectChildList::afterPseudoElementRenderer(const RenderObject* owner) const
3002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
3012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    RenderObject* last = const_cast<RenderObject*>(owner);
3022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    do {
3032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        last = last->lastChild();
3042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    } while (last && last->isAnonymous() && last->style()->styleType() == NOPSEUDO && !last->isListMarker());
3052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (last && last->style()->styleType() != AFTER)
3062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return 0;
3072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return last;
3082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
3092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
3102fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid RenderObjectChildList::updateBeforeAfterContent(RenderObject* owner, PseudoId type, const RenderObject* styledObject)
3118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
3128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Double check that the document did in fact use generated content rules.  Otherwise we should not have been called.
3138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT(owner->document()->usesBeforeAfterRules());
3148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // In CSS2, before/after pseudo-content cannot nest.  Check this first.
3168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (owner->style()->styleType() == BEFORE || owner->style()->styleType() == AFTER)
3178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
3188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!styledObject)
3208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        styledObject = owner;
3218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderStyle* pseudoElementStyle = styledObject->getCachedPseudoStyle(type);
3232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    RenderObject* child;
3242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    switch (type) {
3252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    case BEFORE:
3262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        child = beforePseudoElementRenderer(owner);
3272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        break;
3282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    case AFTER:
3292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        child = afterPseudoElementRenderer(owner);
3302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        break;
3312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    default:
3322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        ASSERT_NOT_REACHED();
3332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return;
3342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
3358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Whether or not we currently have generated content attached.
3378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool oldContentPresent = child;
3388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
339dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Whether or not we now want generated content.
3408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool newContentWanted = pseudoElementStyle && pseudoElementStyle->display() != NONE;
3418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // For <q><p/></q>, if this object is the inline continuation of the <q>, we only want to generate
3438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // :after content and not :before content.
344e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (newContentWanted && type == BEFORE && owner->isElementContinuation())
3458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        newContentWanted = false;
3468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Similarly, if we're the beginning of a <q>, and there's an inline continuation for our object,
3488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // then we don't generate the :after content.
349e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (newContentWanted && type == AFTER && owner->virtualContinuation())
3508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        newContentWanted = false;
3518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // If we don't want generated content any longer, or if we have generated content, but it's no longer
3538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // identical to the new content data we want to build render objects for, then we nuke all
3548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // of the old generated content.
355dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (oldContentPresent && (!newContentWanted || Node::diff(child->style(), pseudoElementStyle) == Node::Detach)) {
3568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // Nuke the child.
357dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (child->style()->styleType() == type) {
3588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            oldContentPresent = false;
3598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            child->destroy();
3608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            child = (type == BEFORE) ? owner->virtualChildren()->firstChild() : owner->virtualChildren()->lastChild();
3618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
3628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
3638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // If we have no pseudo-element style or if the pseudo-element style's display type is NONE, then we
3658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // have no generated content and can now return.
3668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!newContentWanted)
3678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
3688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (owner->isRenderInline() && !pseudoElementStyle->isDisplayInlineType() && pseudoElementStyle->floating() == FNONE &&
3708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        !(pseudoElementStyle->position() == AbsolutePosition || pseudoElementStyle->position() == FixedPosition))
3718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // According to the CSS2 spec (the end of section 12.1), the only allowed
3728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // display values for the pseudo style are NONE and INLINE for inline flows.
3738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // FIXME: CSS2.1 lifted this restriction, but block display types will crash.
3748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // For now we at least relax the restriction to allow all inline types like inline-block
3758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // and inline-table.
3768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        pseudoElementStyle->setDisplay(INLINE);
3778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (oldContentPresent) {
3798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (child && child->style()->styleType() == type) {
3808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // We have generated content present still.  We want to walk this content and update our
3818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // style information with the new pseudo-element style.
3828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            child->setStyle(pseudoElementStyle);
3838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            RenderObject* beforeAfterParent = findBeforeAfterParent(child);
3858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (!beforeAfterParent)
3868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                return;
3878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // Note that if we ever support additional types of generated content (which should be way off
3898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // in the future), this code will need to be patched.
3908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            for (RenderObject* genChild = beforeAfterParent->firstChild(); genChild; genChild = genChild->nextSibling()) {
3918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                if (genChild->isText())
3928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    // Generated text content is a child whose style also needs to be set to the pseudo-element style.
3938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    genChild->setStyle(pseudoElementStyle);
3948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                else if (genChild->isImage()) {
3958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    // Images get an empty style that inherits from the pseudo.
3968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    RefPtr<RenderStyle> style = RenderStyle::create();
3978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    style->inheritFrom(pseudoElementStyle);
3988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    genChild->setStyle(style.release());
399643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                } else {
400643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                    // RenderListItem may insert a list marker here. We do not need to care about this case.
401643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                    // Otherwise, genChild must be a first-letter container. updateFirstLetter() will take care of it.
402643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                    ASSERT(genChild->isListMarker() || genChild->style()->styleType() == FIRST_LETTER);
403643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                }
4048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            }
4058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
4068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return; // We've updated the generated content. That's all we needed to do.
4078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
4088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderObject* insertBefore = (type == BEFORE) ? owner->virtualChildren()->firstChild() : 0;
4108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Generated content consists of a single container that houses multiple children (specified
4128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // by the content property).  This generated content container gets the pseudo-element style set on it.
4138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderObject* generatedContentContainer = 0;
4148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Walk our list of generated content and create render objects for each.
4168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    for (const ContentData* content = pseudoElementStyle->contentData(); content; content = content->next()) {
4178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RenderObject* renderer = 0;
4188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        switch (content->type()) {
4198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            case CONTENT_NONE:
4208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                break;
4218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            case CONTENT_TEXT:
4228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                renderer = new (owner->renderArena()) RenderTextFragment(owner->document() /* anonymous object */, content->text());
4238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                renderer->setStyle(pseudoElementStyle);
4248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                break;
4258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            case CONTENT_OBJECT: {
4265ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                RenderImage* image = new (owner->renderArena()) RenderImage(owner->document()); // anonymous object
4278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                RefPtr<RenderStyle> style = RenderStyle::create();
4288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                style->inheritFrom(pseudoElementStyle);
4298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                image->setStyle(style.release());
4308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                if (StyleImage* styleImage = content->image())
4315ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                    image->setImageResource(RenderImageResourceStyleImage::create(styleImage));
4325ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                else
4335ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                    image->setImageResource(RenderImageResource::create());
4348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                renderer = image;
4358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                break;
4368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            }
43781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        case CONTENT_COUNTER:
43881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            renderer = new (owner->renderArena()) RenderCounter(owner->document(), *content->counter());
43981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            renderer->setStyle(pseudoElementStyle);
44081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            break;
44181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        case CONTENT_QUOTE:
44281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            renderer = new (owner->renderArena()) RenderQuote(owner->document(), content->quote());
44381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            renderer->setStyle(pseudoElementStyle);
44481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            break;
4458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
4468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (renderer) {
4488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (!generatedContentContainer) {
4498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                // Make a generated box that might be any display type now that we are able to drill down into children
4508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                // to find the original content properly.
4518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                generatedContentContainer = RenderObject::createObject(owner->document(), pseudoElementStyle);
4522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                ASSERT(styledObject->node()); // The styled object cannot be anonymous or else it could not have ':before' or ':after' pseudo elements.
4532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                generatedContentContainer->setNode(styledObject->node()); // This allows access to the generatingNode.
4548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                generatedContentContainer->setStyle(pseudoElementStyle);
4552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                if (!owner->isChildAllowed(generatedContentContainer, pseudoElementStyle)) {
4562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                    // The generated content container is not allowed here -> abort.
4572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                    generatedContentContainer->destroy();
4582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                    renderer->destroy();
4592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                    return;
4602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                }
4618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                owner->addChild(generatedContentContainer, insertBefore);
4628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            }
463a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (generatedContentContainer->isChildAllowed(renderer, pseudoElementStyle))
464a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                generatedContentContainer->addChild(renderer);
465a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            else
466a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                renderer->destroy();
4678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
4688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
4698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
4708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} // namespace WebCore
472