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