static void updateContainerSize(SVGUseElement* useElement, SVGElementInstance* targetInstance) { // Depth-first used to write the method in early exit style, no particular other reason. for (SVGElementInstance* instance = targetInstance->firstChild(); instance; instance = instance->nextSibling()) updateContainerSize(useElement, instance); SVGElement* correspondingElement = targetInstance->correspondingElement(); ASSERT(correspondingElement); bool isSymbolTag = correspondingElement->hasTagName(SVGNames::symbolTag); if (!correspondingElement->hasTagName(SVGNames::svgTag) && !isSymbolTag) return; SVGElement* shadowTreeElement = targetInstance->shadowTreeElement(); ASSERT(shadowTreeElement); ASSERT(shadowTreeElement->hasTagName(SVGNames::svgTag)); // Spec (<use> on <symbol>): This generated 'svg' will always have explicit values for attributes width and height. // If attributes width and/or height are provided on the 'use' element, then these attributes // will be transferred to the generated 'svg'. If attributes width and/or height are not specified, // the generated 'svg' element will use values of 100% for these attributes. // Spec (<use> on <svg>): If attributes width and/or height are provided on the 'use' element, then these // values will override the corresponding attributes on the 'svg' in the generated tree. if (useElement->hasAttribute(SVGNames::widthAttr)) shadowTreeElement->setAttribute(SVGNames::widthAttr, useElement->getAttribute(SVGNames::widthAttr)); else if (isSymbolTag && shadowTreeElement->hasAttribute(SVGNames::widthAttr)) shadowTreeElement->setAttribute(SVGNames::widthAttr, "100%"); if (useElement->hasAttribute(SVGNames::heightAttr)) shadowTreeElement->setAttribute(SVGNames::heightAttr, useElement->getAttribute(SVGNames::heightAttr)); else if (isSymbolTag && shadowTreeElement->hasAttribute(SVGNames::heightAttr)) shadowTreeElement->setAttribute(SVGNames::heightAttr, "100%"); }