Example #1
0
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);
}
Example #3
0
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);
}
Example #4
0
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();
    }
}
Example #5
0
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;
}