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); }