18f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian/*
28f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * Copyright (C) 2009 Apple Inc.  All rights reserved.
3440c0366ae0192fb737c7dd87dc2d7156266b3f7Steve Block * 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"
318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "RenderBlock.h"
328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "RenderCounter.h"
338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "RenderImageGeneratedContent.h"
348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "RenderInline.h"
358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "RenderLayer.h"
368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "RenderListItem.h"
378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "RenderStyle.h"
388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "RenderTextFragment.h"
398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "RenderView.h"
408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qiannamespace WebCore {
428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic void updateListMarkerNumbers(RenderObject* child)
448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    for (RenderObject* sibling = child; sibling; sibling = sibling->nextSibling()) {
460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (sibling->isListItem())
470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            toRenderListItem(sibling)->updateValue();
488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderObjectChildList::destroyLeftoverChildren()
528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    while (firstChild()) {
548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (firstChild()->isListMarker() || (firstChild()->style()->styleType() == FIRST_LETTER && !firstChild()->isText()))
558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng 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.
56440c0366ae0192fb737c7dd87dc2d7156266b3f7Steve Block        else if (firstChild()->isRunIn() && firstChild()->node()) {
57440c0366ae0192fb737c7dd87dc2d7156266b3f7Steve Block            firstChild()->node()->setRenderer(0);
58440c0366ae0192fb737c7dd87dc2d7156266b3f7Steve Block            firstChild()->node()->setNeedsStyleRecalc();
59440c0366ae0192fb737c7dd87dc2d7156266b3f7Steve Block            firstChild()->destroy();
60440c0366ae0192fb737c7dd87dc2d7156266b3f7Steve Block        } else {
618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng 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.
628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (firstChild()->node())
638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                firstChild()->node()->setRenderer(0);
648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            firstChild()->destroy();
658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianRenderObject* RenderObjectChildList::removeChildNode(RenderObject* owner, RenderObject* oldChild, bool fullRemove)
708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT(oldChild->parent() == owner);
728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // So that we'll get the appropriate dirty bit set (either that a normal flow child got yanked or
748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // that a positioned child got yanked).  We also repaint, so that the area exposed when the child
758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // disappears gets repainted properly.
768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!owner->documentBeingDestroyed() && fullRemove && oldChild->m_everHadLayout) {
778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        oldChild->setNeedsLayoutAndPrefWidthsRecalc();
788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        oldChild->repaint();
798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // If we have a line box wrapper, delete it.
828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (oldChild->isBox())
838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        toRenderBox(oldChild)->deleteLineBoxWrapper();
848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!owner->documentBeingDestroyed() && fullRemove) {
868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // if we remove visible child from an invisible parent, we don't know the layer visibility any more
878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RenderLayer* layer = 0;
888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (owner->style()->visibility() != VISIBLE && oldChild->style()->visibility() == VISIBLE && !oldChild->hasLayer()) {
898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            layer = owner->enclosingLayer();
908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            layer->dirtyVisibleContentStatus();
918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian         // Keep our layer hierarchy updated.
948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (oldChild->firstChild() || oldChild->hasLayer()) {
958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (!layer)
968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                layer = owner->enclosingLayer();
978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            oldChild->removeLayers(layer);
988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // renumber ordered lists
1018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (oldChild->isListItem())
1028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            updateListMarkerNumbers(oldChild->nextSibling());
1038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (oldChild->isPositioned() && owner->childrenInline())
1058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            owner->dirtyLinesFromChangedChild(oldChild);
1068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
1078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // If oldChild is the start or end of the selection, then clear the selection to
1098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // avoid problems of invalid pointers.
1108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // FIXME: The SelectionController should be responsible for this when it
1118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // is notified of DOM mutations.
1128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!owner->documentBeingDestroyed() && oldChild->isSelectionBorder())
1138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        owner->view()->clearSelection();
1148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // remove the child
1168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (oldChild->previousSibling())
1178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());
1188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (oldChild->nextSibling())
1198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling());
1208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (firstChild() == oldChild)
1228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        setFirstChild(oldChild->nextSibling());
1238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (lastChild() == oldChild)
1248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        setLastChild(oldChild->previousSibling());
1258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    oldChild->setPreviousSibling(0);
1278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    oldChild->setNextSibling(0);
1288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    oldChild->setParent(0);
1298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (AXObjectCache::accessibilityEnabled())
1318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        owner->document()->axObjectCache()->childrenChanged(owner);
1328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return oldChild;
1348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
1358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderObjectChildList::appendChildNode(RenderObject* owner, RenderObject* newChild, bool fullAppend)
1378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
1388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT(newChild->parent() == 0);
1398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT(!owner->isBlockFlow() || (!newChild->isTableSection() && !newChild->isTableRow() && !newChild->isTableCell()));
1408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    newChild->setParent(owner);
1428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderObject* lChild = lastChild();
1438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (lChild) {
1458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        newChild->setPreviousSibling(lChild);
1468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        lChild->setNextSibling(newChild);
1478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    } else
1488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        setFirstChild(newChild);
1498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    setLastChild(newChild);
1518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (fullAppend) {
1538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // Keep our layer hierarchy updated.  Optimize for the common case where we don't have any children
1548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // and don't have a layer attached to ourselves.
1558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RenderLayer* layer = 0;
1568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (newChild->firstChild() || newChild->hasLayer()) {
1578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            layer = owner->enclosingLayer();
1588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            newChild->addLayers(layer, newChild);
1598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
1608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // if the new child is visible but this object was not, tell the layer it has some visible content
1628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // that needs to be drawn and layer visibility optimization can't be used
1638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (owner->style()->visibility() != VISIBLE && newChild->style()->visibility() == VISIBLE && !newChild->hasLayer()) {
1648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (!layer)
1658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                layer = owner->enclosingLayer();
1668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (layer)
1678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                layer->setHasVisibleContent(true);
1688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
1698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (!newChild->isFloatingOrPositioned() && owner->childrenInline())
1718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            owner->dirtyLinesFromChangedChild(newChild);
1728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
1738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    newChild->setNeedsLayoutAndPrefWidthsRecalc(); // Goes up the containing block hierarchy.
1758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!owner->normalChildNeedsLayout())
1768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        owner->setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child.
1778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (AXObjectCache::accessibilityEnabled())
1798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        owner->document()->axObjectCache()->childrenChanged(owner);
1808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
1818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderObjectChildList::insertChildNode(RenderObject* owner, RenderObject* child, RenderObject* beforeChild, bool fullInsert)
1838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
1848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!beforeChild) {
1858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        appendChildNode(owner, child);
1868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
1878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
1888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT(!child->parent());
1908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    while (beforeChild->parent() != owner && beforeChild->parent()->isAnonymousBlock())
1918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        beforeChild = beforeChild->parent();
1928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT(beforeChild->parent() == owner);
1938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT(!owner->isBlockFlow() || (!child->isTableSection() && !child->isTableRow() && !child->isTableCell()));
1958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (beforeChild == firstChild())
1978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        setFirstChild(child);
1988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderObject* prev = beforeChild->previousSibling();
2008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    child->setNextSibling(beforeChild);
2018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    beforeChild->setPreviousSibling(child);
2028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (prev)
2038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        prev->setNextSibling(child);
2048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    child->setPreviousSibling(prev);
2058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    child->setParent(owner);
2078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (fullInsert) {
2098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // Keep our layer hierarchy updated.  Optimize for the common case where we don't have any children
2108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // and don't have a layer attached to ourselves.
2118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RenderLayer* layer = 0;
2128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (child->firstChild() || child->hasLayer()) {
2138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            layer = owner->enclosingLayer();
2148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            child->addLayers(layer, child);
2158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
2168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // if the new child is visible but this object was not, tell the layer it has some visible content
2188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // that needs to be drawn and layer visibility optimization can't be used
2198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (owner->style()->visibility() != VISIBLE && child->style()->visibility() == VISIBLE && !child->hasLayer()) {
2208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (!layer)
2218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                layer = owner->enclosingLayer();
2228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (layer)
2238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                layer->setHasVisibleContent(true);
2248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
2258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (!child->isFloating() && owner->childrenInline())
2288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            owner->dirtyLinesFromChangedChild(child);
2298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
2308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    child->setNeedsLayoutAndPrefWidthsRecalc();
2328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!owner->normalChildNeedsLayout())
2338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        owner->setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child.
2348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (AXObjectCache::accessibilityEnabled())
2368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        owner->document()->axObjectCache()->childrenChanged(owner);
2378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
2388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic RenderObject* beforeAfterContainer(RenderObject* container, PseudoId type)
2408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
2418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (type == BEFORE) {
2428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RenderObject* first = container;
2438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        do {
2448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // Skip list markers.
2458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            first = first->firstChild();
2468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            while (first && first->isListMarker())
2478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                first = first->nextSibling();
2488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } while (first && first->isAnonymous() && first->style()->styleType() == NOPSEUDO);
2498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (first && first->style()->styleType() != type)
2508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return 0;
2518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return first;
2528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
2538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (type == AFTER) {
2548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RenderObject* last = container;
2558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        do {
2568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            last = last->lastChild();
2578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } while (last && last->isAnonymous() && last->style()->styleType() == NOPSEUDO && !last->isListMarker());
2588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (last && last->style()->styleType() != type)
2598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return 0;
2608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return last;
2618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
2628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT_NOT_REACHED();
2648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return 0;
2658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
2668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic RenderObject* findBeforeAfterParent(RenderObject* object)
2688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
2698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Only table parts need to search for the :before or :after parent
2708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!(object->isTable() || object->isTableSection() || object->isTableRow()))
2718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return object;
2728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderObject* beforeAfterParent = object;
2748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    while (beforeAfterParent && !(beforeAfterParent->isText() || beforeAfterParent->isImage()))
2758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        beforeAfterParent = beforeAfterParent->firstChild();
2768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return beforeAfterParent;
2778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
2788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
279643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic void invalidateCountersInContainer(RenderObject* container, const AtomicString& identifier)
2808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
2818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!container)
2828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
2838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    container = findBeforeAfterParent(container);
2848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!container)
2858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
286643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // Sometimes the counter is attached directly on the container.
287643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (container->isCounter()) {
288643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        toRenderCounter(container)->invalidate(identifier);
289643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return;
290643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
2918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    for (RenderObject* content = container->firstChild(); content; content = content->nextSibling()) {
2928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (content->isCounter())
293643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            toRenderCounter(content)->invalidate(identifier);
2948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
2958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
2968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
297643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid RenderObjectChildList::invalidateCounters(RenderObject* owner, const AtomicString& identifier)
2988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
2998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT(!owner->documentBeingDestroyed());
300643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    invalidateCountersInContainer(beforeAfterContainer(owner, BEFORE), identifier);
301643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    invalidateCountersInContainer(beforeAfterContainer(owner, AFTER), identifier);
3028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
3038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderObjectChildList::updateBeforeAfterContent(RenderObject* owner, PseudoId type, RenderObject* styledObject)
3058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
3068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Double check that the document did in fact use generated content rules.  Otherwise we should not have been called.
3078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT(owner->document()->usesBeforeAfterRules());
3088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // In CSS2, before/after pseudo-content cannot nest.  Check this first.
3108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (owner->style()->styleType() == BEFORE || owner->style()->styleType() == AFTER)
3118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
3128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!styledObject)
3148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        styledObject = owner;
3158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderStyle* pseudoElementStyle = styledObject->getCachedPseudoStyle(type);
3178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderObject* child = beforeAfterContainer(owner, type);
3188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Whether or not we currently have generated content attached.
3208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool oldContentPresent = child;
3218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Whether or not we now want generated content.
3238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool newContentWanted = pseudoElementStyle && pseudoElementStyle->display() != NONE;
3248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // For <q><p/></q>, if this object is the inline continuation of the <q>, we only want to generate
3268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // :after content and not :before content.
3278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (newContentWanted && type == BEFORE && owner->isRenderInline() && toRenderInline(owner)->isInlineContinuation())
3288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        newContentWanted = false;
3298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Similarly, if we're the beginning of a <q>, and there's an inline continuation for our object,
3318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // then we don't generate the :after content.
3328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (newContentWanted && type == AFTER && owner->isRenderInline() && toRenderInline(owner)->continuation())
3338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        newContentWanted = false;
3348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // If we don't want generated content any longer, or if we have generated content, but it's no longer
3368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // identical to the new content data we want to build render objects for, then we nuke all
3378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // of the old generated content.
3388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!newContentWanted || (oldContentPresent && Node::diff(child->style(), pseudoElementStyle) == Node::Detach)) {
3398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // Nuke the child.
3408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (child && child->style()->styleType() == type) {
3418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            oldContentPresent = false;
3428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            child->destroy();
3438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            child = (type == BEFORE) ? owner->virtualChildren()->firstChild() : owner->virtualChildren()->lastChild();
3448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
3458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
3468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // If we have no pseudo-element style or if the pseudo-element style's display type is NONE, then we
3488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // have no generated content and can now return.
3498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!newContentWanted)
3508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
3518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (owner->isRenderInline() && !pseudoElementStyle->isDisplayInlineType() && pseudoElementStyle->floating() == FNONE &&
3538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        !(pseudoElementStyle->position() == AbsolutePosition || pseudoElementStyle->position() == FixedPosition))
3548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // According to the CSS2 spec (the end of section 12.1), the only allowed
3558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // display values for the pseudo style are NONE and INLINE for inline flows.
3568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // FIXME: CSS2.1 lifted this restriction, but block display types will crash.
3578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // For now we at least relax the restriction to allow all inline types like inline-block
3588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // and inline-table.
3598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        pseudoElementStyle->setDisplay(INLINE);
3608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (oldContentPresent) {
3628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (child && child->style()->styleType() == type) {
3638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // We have generated content present still.  We want to walk this content and update our
3648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // style information with the new pseudo-element style.
3658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            child->setStyle(pseudoElementStyle);
3668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            RenderObject* beforeAfterParent = findBeforeAfterParent(child);
3688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (!beforeAfterParent)
3698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                return;
3708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // Note that if we ever support additional types of generated content (which should be way off
3728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // in the future), this code will need to be patched.
3738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            for (RenderObject* genChild = beforeAfterParent->firstChild(); genChild; genChild = genChild->nextSibling()) {
3748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                if (genChild->isText())
3758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    // Generated text content is a child whose style also needs to be set to the pseudo-element style.
3768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    genChild->setStyle(pseudoElementStyle);
3778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                else if (genChild->isImage()) {
3788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    // Images get an empty style that inherits from the pseudo.
3798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    RefPtr<RenderStyle> style = RenderStyle::create();
3808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    style->inheritFrom(pseudoElementStyle);
3818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    genChild->setStyle(style.release());
382643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                } else {
383643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                    // RenderListItem may insert a list marker here. We do not need to care about this case.
384643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                    // Otherwise, genChild must be a first-letter container. updateFirstLetter() will take care of it.
385643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                    ASSERT(genChild->isListMarker() || genChild->style()->styleType() == FIRST_LETTER);
386643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                }
3878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            }
3888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
3898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return; // We've updated the generated content. That's all we needed to do.
3908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
3918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderObject* insertBefore = (type == BEFORE) ? owner->virtualChildren()->firstChild() : 0;
3938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Generated content consists of a single container that houses multiple children (specified
3958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // by the content property).  This generated content container gets the pseudo-element style set on it.
3968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderObject* generatedContentContainer = 0;
3978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Walk our list of generated content and create render objects for each.
3998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    for (const ContentData* content = pseudoElementStyle->contentData(); content; content = content->next()) {
4008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RenderObject* renderer = 0;
4018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        switch (content->type()) {
4028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            case CONTENT_NONE:
4038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                break;
4048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            case CONTENT_TEXT:
4058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                renderer = new (owner->renderArena()) RenderTextFragment(owner->document() /* anonymous object */, content->text());
4068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                renderer->setStyle(pseudoElementStyle);
4078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                break;
4088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            case CONTENT_OBJECT: {
4098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                RenderImageGeneratedContent* image = new (owner->renderArena()) RenderImageGeneratedContent(owner->document()); // anonymous object
4108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                RefPtr<RenderStyle> style = RenderStyle::create();
4118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                style->inheritFrom(pseudoElementStyle);
4128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                image->setStyle(style.release());
4138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                if (StyleImage* styleImage = content->image())
4148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    image->setStyleImage(styleImage);
4158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                renderer = image;
4168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                break;
4178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            }
4188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            case CONTENT_COUNTER:
4198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                renderer = new (owner->renderArena()) RenderCounter(owner->document(), *content->counter());
4208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                renderer->setStyle(pseudoElementStyle);
4218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                break;
4228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
4238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (renderer) {
4258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (!generatedContentContainer) {
4268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                // Make a generated box that might be any display type now that we are able to drill down into children
4278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                // to find the original content properly.
4288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                generatedContentContainer = RenderObject::createObject(owner->document(), pseudoElementStyle);
4298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                generatedContentContainer->setStyle(pseudoElementStyle);
4308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                owner->addChild(generatedContentContainer, insertBefore);
4318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            }
432a7b8ec708c2566cc6e69c0b464e416c018227b02Ben Murdoch            if (generatedContentContainer->isChildAllowed(renderer, pseudoElementStyle))
433a7b8ec708c2566cc6e69c0b464e416c018227b02Ben Murdoch                generatedContentContainer->addChild(renderer);
434a7b8ec708c2566cc6e69c0b464e416c018227b02Ben Murdoch            else
435a7b8ec708c2566cc6e69c0b464e416c018227b02Ben Murdoch                renderer->destroy();
4368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
4378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
4388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
4398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} // namespace WebCore
441