void SVGElement::removedFrom(ContainerNode* rootParent)
{
    bool wasInDocument = rootParent->inDocument();

    if (wasInDocument && hasRelativeLengths()) {
        // The root of the subtree being removed should take itself out from its parent's relative
        // length set. For the other nodes in the subtree we don't need to do anything: they will
        // get their own removedFrom() notification and just clear their sets.
        if (rootParent->isSVGElement() && !parentNode()) {
            ASSERT(toSVGElement(rootParent)->m_elementsWithRelativeLengths.contains(this));
            toSVGElement(rootParent)->updateRelativeLengthsInformation(false, this);
        }

        m_elementsWithRelativeLengths.clear();
    }

    ASSERT_WITH_SECURITY_IMPLICATION(!rootParent->isSVGElement() || !toSVGElement(rootParent)->m_elementsWithRelativeLengths.contains(this));

    Element::removedFrom(rootParent);

    if (wasInDocument) {
        rebuildAllIncomingReferences();
        removeAllIncomingReferences();
    }

    invalidateInstances();
}
Example #2
0
SVGElement::~SVGElement()
{
    ASSERT(inDocument() || !hasRelativeLengths());

    if (!hasSVGRareData())
        ASSERT(!SVGElementRareData::rareDataMap().contains(this));
    else {
        SVGElementRareData::SVGElementRareDataMap& rareDataMap = SVGElementRareData::rareDataMap();
        SVGElementRareData::SVGElementRareDataMap::iterator it = rareDataMap.find(this);
        ASSERT_WITH_SECURITY_IMPLICATION(it != rareDataMap.end());

        SVGElementRareData* rareData = it->value;
        rareData->destroyAnimatedSMILStyleProperties();
        if (SVGCursorElement* cursorElement = rareData->cursorElement())
            cursorElement->removeClient(this);
        if (CSSCursorImageValue* cursorImageValue = rareData->cursorImageValue())
            cursorImageValue->removeReferencedElement(this);

        delete rareData;

        // The rare data cleanup may have caused other SVG nodes to be deleted,
        // modifying the rare data map. Do not rely on the existing iterator.
        ASSERT(rareDataMap.contains(this));
        rareDataMap.remove(this);
        // Clear HasSVGRareData flag now so that we are in a consistent state when
        // calling rebuildAllElementReferencesForTarget() and
        // removeAllElementReferencesForTarget() below.
        clearHasSVGRareData();
    }
    document().accessSVGExtensions().rebuildAllElementReferencesForTarget(this);
    document().accessSVGExtensions().removeAllElementReferencesForTarget(this);
}
void SVGElement::invalidateRelativeLengthClients(SubtreeLayoutScope* layoutScope)
{
    if (!inDocument())
        return;

    ASSERT(!m_inRelativeLengthClientsInvalidation);
#if ENABLE(ASSERT)
    TemporaryChange<bool> inRelativeLengthClientsInvalidationChange(m_inRelativeLengthClientsInvalidation, true);
#endif

    if (LayoutObject* layoutObject = this->layoutObject()) {
        if (hasRelativeLengths() && layoutObject->isSVGResourceContainer())
            toLayoutSVGResourceContainer(layoutObject)->invalidateCacheAndMarkForLayout(layoutScope);
        else if (selfHasRelativeLengths())
            layoutObject->setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReason::Unknown, MarkContainerChain, layoutScope);
    }

    for (SVGElement* element : m_elementsWithRelativeLengths) {
        if (element != this)
            element->invalidateRelativeLengthClients(layoutScope);
    }
}
Example #4
0
SVGElement::~SVGElement()
{
    ASSERT(inDocument() || !hasRelativeLengths());

    // The below teardown is all handled by weak pointer processing in oilpan.
#if !ENABLE(OILPAN)
    if (hasSVGRareData()) {
        if (SVGCursorElement* cursorElement = svgRareData()->cursorElement())
            cursorElement->removeReferencedElement(this);
        if (CSSCursorImageValue* cursorImageValue = svgRareData()->cursorImageValue())
            cursorImageValue->removeReferencedElement(this);
        // Clear the rare data now so that we are in a consistent state when
        // calling rebuildAllElementReferencesForTarget() below.
        m_SVGRareData.clear();
    }

    // With Oilpan, either removedFrom has been called or the document is dead
    // as well and there is no reason to clear out the references.
    document().accessSVGExtensions().rebuildAllElementReferencesForTarget(this);
    document().accessSVGExtensions().removeAllElementReferencesForTarget(this);
#endif
}