Example #1
0
void SVGUseElement::buildInstanceTree(SVGElement* target, SVGElementInstance* targetInstance, bool& foundProblem)
{
    ASSERT(target);
    ASSERT(targetInstance);

    // A general description from the SVG spec, describing what buildInstanceTree() actually does.
    //
    // Spec: If the 'use' element references a 'g' which contains two 'rect' elements, then the instance tree
    // contains three SVGElementInstance objects, a root SVGElementInstance object whose correspondingElement
    // is the SVGGElement object for the 'g', and then two child SVGElementInstance objects, each of which has
    // its correspondingElement that is an SVGRectElement object.

    for (Node* node = target->firstChild(); node; node = node->nextSibling()) {
        SVGElement* element = 0;
        if (node->isSVGElement())
            element = static_cast<SVGElement*>(node);

        // Skip any non-svg nodes or any disallowed element.
        if (!element || isDisallowedElement(element))
            continue;

        // Create SVGElementInstance object, for both container/non-container nodes.
        SVGElementInstance* instancePtr = new SVGElementInstance(this, element);

        RefPtr<SVGElementInstance> instance = instancePtr;
        targetInstance->appendChild(instance.release());

        // Enter recursion, appending new instance tree nodes to the "instance" object.
        if (element->hasChildNodes())
            buildInstanceTree(element, instancePtr, foundProblem);

        // Spec: If the referenced object is itself a 'use', or if there are 'use' subelements within the referenced
        // object, the instance tree will contain recursive expansion of the indirect references to form a complete tree.
        if (element->hasTagName(SVGNames::useTag))
            handleDeepUseReferencing(element, instancePtr, foundProblem);
    }

    // Spec: If the referenced object is itself a 'use', or if there are 'use' subelements within the referenced
    // object, the instance tree will contain recursive expansion of the indirect references to form a complete tree.
    if (target->hasTagName(SVGNames::useTag))
        handleDeepUseReferencing(target, targetInstance, foundProblem);
}