Example #1
0
static inline void removeDisallowedElementsFromSubtree(SVGElement& subtree)
{
    ASSERT(!subtree.inDocument());
    Vector<Element*> toRemove;
    auto it = descendantsOfType<Element>(subtree).begin();
    auto end = descendantsOfType<Element>(subtree).end();
    while (it != end) {
        if (isDisallowedElement(*it)) {
            toRemove.append(&*it);
            it.traverseNextSkippingChildren();
            continue;
        }
        ++it;
    }
    // The subtree is not in document so this won't generate events that could mutate the tree.
    for (unsigned i = 0; i < toRemove.size(); ++i)
        toRemove[i]->parentNode()->removeChild(toRemove[i]);
}
void SVGSMILElement::buildPendingResource()
{
    clearResourceAndEventBaseReferences();

    if (!inDocument()) {
        // Reset the target element if we are no longer in the document.
        setTargetElement(nullptr);
        return;
    }

    AtomicString id;
    const AtomicString& href = SVGURIReference::legacyHrefString(*this);
    Element* target;
    if (href.isEmpty())
        target = parentNode() && parentNode()->isElementNode() ? toElement(parentNode()) : nullptr;
    else
        target = SVGURIReference::targetElementFromIRIString(href, treeScope(), &id);
    SVGElement* svgTarget = target && target->isSVGElement() ? toSVGElement(target) : nullptr;

    if (svgTarget && !svgTarget->inDocument())
        svgTarget = nullptr;

    if (svgTarget != targetElement())
        setTargetElement(svgTarget);

    if (!svgTarget) {
        // Do not register as pending if we are already pending this resource.
        if (document().accessSVGExtensions().isElementPendingResource(this, id))
            return;

        if (!id.isEmpty()) {
            document().accessSVGExtensions().addPendingResource(id, this);
            ASSERT(hasPendingResources());
        }
    } else {
        // Register us with the target in the dependencies map. Any change of hrefElement
        // that leads to relayout/repainting now informs us, so we can react to it.
        addReferenceTo(svgTarget);
    }
    connectEventBaseConditions();
}
void SVGSMILElement::buildPendingResource()
{
    clearResourceReferences();

    if (!inDocument()) {
        // Reset the target element if we are no longer in the document.
        setTargetElement(0);
        return;
    }

    String id;
    String href = getAttribute(XLinkNames::hrefAttr);
    Element* target;
    if (href.isEmpty())
        target = parentNode() && parentNode()->isElementNode() ? toElement(parentNode()) : 0;
    else
        target = SVGURIReference::targetElementFromIRIString(href, document(), &id);
    SVGElement* svgTarget = target && target->isSVGElement() ? toSVGElement(target) : 0;

    if (svgTarget && !svgTarget->inDocument())
        svgTarget = 0;

    if (svgTarget != targetElement())
        setTargetElement(svgTarget);

    if (!svgTarget) {
        // Do not register as pending if we are already pending this resource.
        if (document()->accessSVGExtensions()->isElementPendingResource(this, id))
            return;

        if (!id.isEmpty()) {
            document()->accessSVGExtensions()->addPendingResource(id, this);
            ASSERT(hasPendingResources());
        }
    } else {
        // Register us with the target in the dependencies map. Any change of hrefElement
        // that leads to relayout/repainting now informs us, so we can react to it.
        document()->accessSVGExtensions()->addElementReferencingTarget(this, svgTarget);
    }
}
Example #4
0
static void removeDisallowedElementsFromSubtree(SVGElement& subtree)
{
    // Remove disallowed elements after the fact rather than not cloning them in the first place.
    // This optimizes for the normal case where none of those elements are present.

    // This function is used only on elements in subtrees that are not yet in documents, so
    // mutation events are not a factor; there are no event listeners to handle those events.
    // Assert that it's not in a document to make sure callers are still using it this way.
    ASSERT(!subtree.inDocument());

    Vector<Element*> disallowedElements;
    auto descendants = descendantsOfType<Element>(subtree);
    for (auto it = descendants.begin(), end = descendants.end(); it != end; ) {
        if (isDisallowedElement(*it)) {
            disallowedElements.append(&*it);
            it.traverseNextSkippingChildren();
            continue;
        }
        ++it;
    }
    for (auto* element : disallowedElements)
        element->parentNode()->removeChild(element);
}