void PseudoElement::attach(const AttachContext& context) { ASSERT(!renderer()); Element::attach(context); RenderObject* renderer = this->renderer(); if (!renderer) return; RenderStyle* style = renderer->style(); if (style->hasFlowFrom()) return; if (style->styleType() != BEFORE && style->styleType() != AFTER) return; ASSERT(style->contentData()); for (const ContentData* content = style->contentData(); content; content = content->next()) { RenderObject* child = content->createRenderer(document(), style); if (renderer->isChildAllowed(child, style)) { renderer->addChild(child); if (child->isQuote()) toRenderQuote(child)->attachQuote(); } else child->destroy(); } }
void RenderQuote::attachQuote() { ASSERT(view()); ASSERT(!m_attached); ASSERT(!m_next && !m_previous); ASSERT(isRooted()); if (!view()->renderQuoteHead()) { view()->setRenderQuoteHead(this); m_attached = true; return; } for (RenderObject* predecessor = previousInPreOrder(); predecessor; predecessor = predecessor->previousInPreOrder()) { // Skip unattached predecessors to avoid having stale m_previous pointers // if the previous node is never attached and is then destroyed. if (!predecessor->isQuote() || !toRenderQuote(predecessor)->isAttached()) continue; m_previous = toRenderQuote(predecessor); m_next = m_previous->m_next; m_previous->m_next = this; if (m_next) m_next->m_previous = this; break; } if (!m_previous) { m_next = view()->renderQuoteHead(); view()->setRenderQuoteHead(this); if (m_next) m_next->m_previous = this; } m_attached = true; for (RenderQuote* quote = this; quote; quote = quote->m_next) quote->updateDepth(); ASSERT(!m_next || m_next->m_attached); ASSERT(!m_next || m_next->m_previous == this); ASSERT(!m_previous || m_previous->m_attached); ASSERT(!m_previous || m_previous->m_next == this); }
void RenderQuote::attachQuote() { ASSERT(!m_isAttached); ASSERT(!m_next); ASSERT(!m_previous); ASSERT(isRooted()); // Optimize case where this is the first quote in a RenderView by not searching for predecessors in that case. if (view().renderQuoteHead()) { for (RenderObject* predecessor = previousInPreOrder(); predecessor; predecessor = predecessor->previousInPreOrder()) { // Skip unattached predecessors to avoid having stale m_previous pointers // if the previous node is never attached and is then destroyed. if (!predecessor->isQuote() || !toRenderQuote(predecessor)->m_isAttached) continue; m_previous = toRenderQuote(predecessor); m_next = m_previous->m_next; m_previous->m_next = this; if (m_next) m_next->m_previous = this; break; } } if (!m_previous) { m_next = view().renderQuoteHead(); view().setRenderQuoteHead(this); if (m_next) m_next->m_previous = this; } m_isAttached = true; for (RenderQuote* quote = this; quote; quote = quote->m_next) quote->updateDepth(); ASSERT(!m_next || m_next->m_isAttached); ASSERT(!m_next || m_next->m_previous == this); ASSERT(!m_previous || m_previous->m_isAttached); ASSERT(!m_previous || m_previous->m_next == this); }
void PseudoElement::didAttachRenderers() { RenderObject* renderer = this->renderer(); if (!renderer || !renderer->style()->regionThread().isEmpty()) return; RenderStyle* style = renderer->style(); ASSERT(style->contentData()); for (const ContentData* content = style->contentData(); content; content = content->next()) { RenderObject* child = content->createRenderer(document(), style); if (renderer->isChildAllowed(child, style)) { renderer->addChild(child); if (child->isQuote()) toRenderQuote(child)->attachQuote(); } else child->destroy(); } }
RenderObject* RenderObjectChildList::removeChildNode(RenderObject* owner, RenderObject* oldChild, bool fullRemove) { ASSERT(oldChild->parent() == owner); if (oldChild->isFloatingOrOutOfFlowPositioned()) toRenderBox(oldChild)->removeFloatingOrPositionedChildFromBlockLists(); // So that we'll get the appropriate dirty bit set (either that a normal flow child got yanked or // that a positioned child got yanked). We also repaint, so that the area exposed when the child // disappears gets repainted properly. if (!owner->documentBeingDestroyed() && fullRemove && oldChild->everHadLayout()) { oldChild->setNeedsLayoutAndPrefWidthsRecalc(); if (oldChild->isBody()) owner->view()->repaint(); else oldChild->repaint(); } // If we have a line box wrapper, delete it. if (oldChild->isBox()) toRenderBox(oldChild)->deleteLineBoxWrapper(); if (!owner->documentBeingDestroyed() && fullRemove) { // if we remove visible child from an invisible parent, we don't know the layer visibility any more RenderLayer* layer = 0; if (owner->style()->visibility() != VISIBLE && oldChild->style()->visibility() == VISIBLE && !oldChild->hasLayer()) { if ((layer = owner->enclosingLayer())) layer->dirtyVisibleContentStatus(); } // Keep our layer hierarchy updated. if (oldChild->firstChild() || oldChild->hasLayer()) { if (!layer) layer = owner->enclosingLayer(); oldChild->removeLayers(layer); } if (oldChild->isListItem()) toRenderListItem(oldChild)->updateListMarkerNumbers(); if (oldChild->isOutOfFlowPositioned() && owner->childrenInline()) owner->dirtyLinesFromChangedChild(oldChild); if (oldChild->isRenderRegion()) toRenderRegion(oldChild)->detachRegion(); if (oldChild->isQuote()) toRenderQuote(oldChild)->detachQuote(); if (oldChild->inRenderFlowThread()) { if (oldChild->isBox()) oldChild->enclosingRenderFlowThread()->removeRenderBoxRegionInfo(toRenderBox(oldChild)); oldChild->enclosingRenderFlowThread()->clearRenderObjectCustomStyle(oldChild); } if (RenderNamedFlowThread* containerFlowThread = renderNamedFlowThreadContainer(owner)) containerFlowThread->removeFlowChild(oldChild); #if ENABLE(SVG) // Update cached boundaries in SVG renderers, if a child is removed. owner->setNeedsBoundariesUpdate(); #endif } // If oldChild is the start or end of the selection, then clear the selection to // avoid problems of invalid pointers. // FIXME: The FrameSelection should be responsible for this when it // is notified of DOM mutations. if (!owner->documentBeingDestroyed() && oldChild->isSelectionBorder()) owner->view()->clearSelection(); // remove the child if (oldChild->previousSibling()) oldChild->previousSibling()->setNextSibling(oldChild->nextSibling()); if (oldChild->nextSibling()) oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling()); if (firstChild() == oldChild) setFirstChild(oldChild->nextSibling()); if (lastChild() == oldChild) setLastChild(oldChild->previousSibling()); oldChild->setPreviousSibling(0); oldChild->setNextSibling(0); oldChild->setParent(0); // rendererRemovedFromTree walks the whole subtree. We can improve performance // by skipping this step when destroying the entire tree. if (!owner->documentBeingDestroyed()) { RenderCounter::rendererRemovedFromTree(oldChild); } if (AXObjectCache::accessibilityEnabled()) owner->document()->axObjectCache()->childrenChanged(owner); return oldChild; }