InlineBox* RenderSVGInline::createInlineBox(bool makePlaceHolderBox, bool isRootLineBox, bool isOnlyRun)
{
    ASSERT(!(!isRootLineBox && (isReplaced() || makePlaceHolderBox)));
    ASSERT(isInlineFlow());

    InlineFlowBox* flowBox = new (renderArena()) SVGInlineFlowBox(this);

    if (!m_firstLineBox)
        m_firstLineBox = m_lastLineBox = flowBox;
    else {
        m_lastLineBox->setNextLineBox(flowBox);
        flowBox->setPreviousLineBox(m_lastLineBox);
        m_lastLineBox = flowBox;
    }
        
    return flowBox;
}
예제 #2
0
void RenderWidget::destroy()
{
    // We can't call the base class's destroy because we don't
    // want to unconditionally delete ourselves (we're ref-counted).
    // So the code below includes copied and pasted contents of
    // both RenderBox::destroy() and RenderObject::destroy().
    // Fix originally made for <rdar://problem/4228818>.
    animation()->cancelAnimations(this);

    if (RenderView* v = view())
        v->removeWidget(this);

    if (AXObjectCache::accessibilityEnabled()) {
        document()->axObjectCache()->childrenChanged(this->parent());
        document()->axObjectCache()->remove(this);
    }
    remove();

    if (m_widget) {
        if (m_view)
            m_view->removeChild(m_widget);
        widgetRendererMap().remove(m_widget);
    }
    
    // removes from override size map
    if (hasOverrideSize())
        setOverrideSize(-1);

    RenderArena* arena = renderArena();

    if (hasLayer())
        layer()->clearClipRects();

    if (style() && (style()->height().isPercent() || style()->minHeight().isPercent() || style()->maxHeight().isPercent()))
        RenderBlock::removePercentHeightDescendant(this);

    setNode(0);

    if (hasLayer())
        layer()->destroy(arena);

    deref(arena);
}
void RenderSVGShadowTreeRootContainer::updateFromElement()
{
    bool hadExistingTree = m_shadowRoot;

    SVGUseElement* useElement = static_cast<SVGUseElement*>(node());
    if (!m_shadowRoot) {
        ASSERT(!m_recreateTree);
        m_shadowRoot = new SVGShadowTreeRootElement(document(), useElement);
        useElement->buildPendingResource();
    }

    ASSERT(m_shadowRoot->shadowParentNode() == useElement);

    bool shouldRecreateTree = m_recreateTree;
    if (m_recreateTree) {
        ASSERT(hadExistingTree);

        if (m_shadowRoot->attached())
            m_shadowRoot->detach();

        m_shadowRoot->removeAllChildren();
        m_recreateTree = false;
    }

    // Only rebuild the shadow tree, if we a) never had a tree or b) we were specifically asked to do so
    // If the use element is a pending resource, and a) or b) is true, do nothing, and wait for the use
    // element to be asked to buildPendingResource(), this will call us again, with m_recreateTrue=true.
    if ((shouldRecreateTree || !hadExistingTree) && !useElement->isPendingResource()) {
        useElement->buildShadowAndInstanceTree(m_shadowRoot.get());

        // Attach shadow root element
        m_shadowRoot->attachElement(style(), renderArena());

        // Attach subtree, as if it was a regular non-shadow tree
        for (Node* child = m_shadowRoot->firstChild(); child; child = child->nextSibling())
            child->attach();
    }

    ASSERT(!m_recreateTree);
    RenderSVGTransformableContainer::updateFromElement();
}
예제 #4
0
RenderFlowThread* RenderView::renderFlowThreadWithName(const AtomicString& flowThread)
{
    if (!m_renderFlowThreadList)
        m_renderFlowThreadList = adoptPtr(new RenderFlowThreadList());
    else {
        for (RenderFlowThreadList::iterator iter = m_renderFlowThreadList->begin(); iter != m_renderFlowThreadList->end(); ++iter) {
            RenderFlowThread* flowRenderer = *iter;
            if (flowRenderer->flowThread() == flowThread)
                return flowRenderer;
        }
    }

    RenderFlowThread* flowRenderer = new (renderArena()) RenderFlowThread(document(), flowThread);
    flowRenderer->setStyle(RenderFlowThread::createFlowThreadStyle(style()));
    addChild(flowRenderer);
    
    m_renderFlowThreadList->add(flowRenderer);
    setIsRenderFlowThreadOrderDirty(true);

    return flowRenderer;
}
예제 #5
0
void RenderWidget::destroy()
{
    // We can't call the base class's destroy because we don't
    // want to unconditionally delete ourselves (we're ref-counted).
    // So the code below includes copied and pasted contents of
    // both RenderBox::destroy() and RenderObject::destroy().
    // Fix originally made for <rdar://problem/4228818>.
    animation()->cancelImplicitAnimations(this);

    if (RenderView* v = view())
        v->removeWidget(this);

    if (AXObjectCache::accessibilityEnabled())
        document()->axObjectCache()->remove(this);

    remove();

    if (m_widget) {
        if (m_view)
            m_view->removeChild(m_widget);
        widgetRendererMap().remove(m_widget);
    }
    
    // removes from override size map
    if (hasOverrideSize())
        setOverrideSize(-1);

    RenderLayer* layer = m_layer;
    RenderArena* arena = renderArena();

    if (layer)
        layer->clearClipRect();

    setNode(0);
    deref(arena);

    if (layer)
        layer->destroy(arena);
}
void RenderInline::addChildToFlow(RenderObject* newChild, RenderObject* beforeChild)
{
    // Make sure we don't append things after :after-generated content if we have it.
    if (!beforeChild && isAfterContent(lastChild()))
        beforeChild = lastChild();

    if (!newChild->isInline() && !newChild->isFloatingOrPositioned()) {
        // We are placing a block inside an inline. We have to perform a split of this
        // inline into continuations.  This involves creating an anonymous block box to hold
        // |newChild|.  We then make that block box a continuation of this inline.  We take all of
        // the children after |beforeChild| and put them in a clone of this object.
        RefPtr<RenderStyle> newStyle = RenderStyle::create();
        newStyle->inheritFrom(style());
        newStyle->setDisplay(BLOCK);

        RenderBlock* newBox = new (renderArena()) RenderBlock(document() /* anonymous box */);
        newBox->setStyle(newStyle.release());
        RenderFlow* oldContinuation = continuation();
        setContinuation(newBox);

        // Someone may have put a <p> inside a <q>, causing a split.  When this happens, the :after content
        // has to move into the inline continuation.  Call updateBeforeAfterContent to ensure that our :after
        // content gets properly destroyed.
        bool isLastChild = (beforeChild == lastChild());
        if (document()->usesBeforeAfterRules())
            updateBeforeAfterContent(RenderStyle::AFTER);
        if (isLastChild && beforeChild != lastChild())
            beforeChild = 0; // We destroyed the last child, so now we need to update our insertion
                             // point to be 0.  It's just a straight append now.

        splitFlow(beforeChild, newBox, newChild, oldContinuation);
        return;
    }

    RenderContainer::addChild(newChild, beforeChild);

    newChild->setNeedsLayoutAndPrefWidthsRecalc();
}
InlineFlowBox* RenderSVGInline::createInlineFlowBox()
{
    InlineFlowBox* box = new (renderArena()) SVGInlineFlowBox(this);
    box->setHasVirtualLogicalHeight();
    return box;
}
예제 #8
0
RootInlineBox* RenderSVGText::createRootInlineBox() 
{
    RootInlineBox* box = new (renderArena()) SVGRootInlineBox(this);
    box->setHasVirtualHeight();
    return box;
}
예제 #9
0
void RenderView::pushLayoutState(RenderFlowThread* flowThread, bool regionsChanged)
{
    m_layoutState = new (renderArena()) LayoutState(m_layoutState, flowThread, regionsChanged);
}
예제 #10
0
InlineTextBox* RenderSVGInlineText::createInlineTextBox()
{
    return new (renderArena()) SVGInlineTextBox(this);
}
예제 #11
0
InlineTextBox* RenderSVGInlineText::createTextBox()
{
    InlineTextBox* box = new (renderArena()) SVGInlineTextBox(this);
    box->setHasVirtualHeight();
    return box;
}
예제 #12
0
void RenderContainer::updateBeforeAfterContentForContainer(RenderStyle::PseudoId type, RenderContainer* styledObject)
{
    // In CSS2, before/after pseudo-content cannot nest.  Check this first.
    if (style()->styleType() == RenderStyle::BEFORE || style()->styleType() == RenderStyle::AFTER)
        return;

    RenderStyle* pseudoElementStyle = styledObject->getCachedPseudoStyle(type);
    RenderObject* child = beforeAfterContainer(type);

    // Whether or not we currently have generated content attached.
    bool oldContentPresent = child;

    // Whether or not we now want generated content.
    bool newContentWanted = pseudoElementStyle && pseudoElementStyle->display() != NONE;

    // For <q><p/></q>, if this object is the inline continuation of the <q>, we only want to generate
    // :after content and not :before content.
    if (newContentWanted && type == RenderStyle::BEFORE && isInlineContinuation())
        newContentWanted = false;

    // Similarly, if we're the beginning of a <q>, and there's an inline continuation for our object,
    // then we don't generate the :after content.
    if (newContentWanted && type == RenderStyle::AFTER && isRenderInline() && continuation())
        newContentWanted = false;

    // If we don't want generated content any longer, or if we have generated content, but it's no longer
    // identical to the new content data we want to build render objects for, then we nuke all
    // of the old generated content.
    if (!newContentWanted || (oldContentPresent && !child->style()->contentDataEquivalent(pseudoElementStyle))) {
        // Nuke the child.
        if (child && child->style()->styleType() == type) {
            oldContentPresent = false;
            child->destroy();
            child = (type == RenderStyle::BEFORE) ? m_firstChild : m_lastChild;
        }
    }

    // If we have no pseudo-element style or if the pseudo-element style's display type is NONE, then we
    // have no generated content and can now return.
    if (!newContentWanted)
        return;

    if (isInlineFlow() && !pseudoElementStyle->isDisplayInlineType() && pseudoElementStyle->floating() == FNONE &&
            !(pseudoElementStyle->position() == AbsolutePosition || pseudoElementStyle->position() == FixedPosition))
        // According to the CSS2 spec (the end of section 12.1), the only allowed
        // display values for the pseudo style are NONE and INLINE for inline flows.
        // FIXME: CSS2.1 lifted this restriction, but block display types will crash.
        // For now we at least relax the restriction to allow all inline types like inline-block
        // and inline-table.
        pseudoElementStyle->setDisplay(INLINE);

    if (oldContentPresent) {
        if (child && child->style()->styleType() == type) {
            // We have generated content present still.  We want to walk this content and update our
            // style information with the new pseudo-element style.
            child->setStyle(pseudoElementStyle);

            // Note that if we ever support additional types of generated content (which should be way off
            // in the future), this code will need to be patched.
            for (RenderObject* genChild = child->firstChild(); genChild; genChild = genChild->nextSibling()) {
                if (genChild->isText())
                    // Generated text content is a child whose style also needs to be set to the pseudo-element style.
                    genChild->setStyle(pseudoElementStyle);
                else if (genChild->isImage()) {
                    // Images get an empty style that inherits from the pseudo.
                    RefPtr<RenderStyle> style = RenderStyle::create();
                    style->inheritFrom(pseudoElementStyle);
                    genChild->setStyle(style.release());
                } else
                    // Must be a first-letter container. updateFirstLetter() will take care of it.
                    ASSERT(genChild->style()->styleType() == RenderStyle::FIRST_LETTER);
            }
        }
        return; // We've updated the generated content. That's all we needed to do.
    }

    RenderObject* insertBefore = (type == RenderStyle::BEFORE) ? firstChild() : 0;

    // Generated content consists of a single container that houses multiple children (specified
    // by the content property).  This generated content container gets the pseudo-element style set on it.
    RenderObject* generatedContentContainer = 0;

    // Walk our list of generated content and create render objects for each.
    for (const ContentData* content = pseudoElementStyle->contentData(); content; content = content->m_next) {
        RenderObject* renderer = 0;
        switch (content->m_type) {
        case CONTENT_NONE:
            break;
        case CONTENT_TEXT:
            renderer = new (renderArena()) RenderTextFragment(document() /* anonymous object */, content->m_content.m_text);
            renderer->setStyle(pseudoElementStyle);
            break;
        case CONTENT_OBJECT: {
            RenderImageGeneratedContent* image = new (renderArena()) RenderImageGeneratedContent(document()); // anonymous object
            RefPtr<RenderStyle> style = RenderStyle::create();
            style->inheritFrom(pseudoElementStyle);
            image->setStyle(style.release());
            if (StyleImage* styleImage = content->m_content.m_image)
                image->setStyleImage(styleImage);
            renderer = image;
            break;
        }
        case CONTENT_COUNTER:
            renderer = new (renderArena()) RenderCounter(document(), *content->m_content.m_counter);
            renderer->setStyle(pseudoElementStyle);
            break;
        }

        if (renderer) {
            if (!generatedContentContainer) {
                // Make a generated box that might be any display type now that we are able to drill down into children
                // to find the original content properly.
                generatedContentContainer = RenderObject::createObject(document(), pseudoElementStyle);
                generatedContentContainer->setStyle(pseudoElementStyle);
            }
            generatedContentContainer->addChild(renderer);
        }
    }

    // Add the pseudo after we've installed all our content so that addChild will be able to find the text
    // inside the inline for e.g., first-letter styling.
    if (generatedContentContainer)
        addChild(generatedContentContainer, insertBefore);
}