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