| Index: Source/core/svg/SVGUseElement.cpp
|
| diff --git a/Source/core/svg/SVGUseElement.cpp b/Source/core/svg/SVGUseElement.cpp
|
| index ecdea38ef69b5fd4692b2d62d0236f271d2b4403..82701d0b4c2d78767fd02c75f80906475ed450ca 100644
|
| --- a/Source/core/svg/SVGUseElement.cpp
|
| +++ b/Source/core/svg/SVGUseElement.cpp
|
| @@ -194,6 +194,30 @@ Document* SVGUseElement::externalDocument() const
|
| return 0;
|
| }
|
|
|
| +void transferUseWidthAndHeightIfNeeded(const SVGUseElement& use, SVGElement* shadowElement, const SVGElement& originalElement)
|
| +{
|
| + ASSERT(shadowElement);
|
| + if (isSVGSymbolElement(*shadowElement)) {
|
| + // 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.
|
| + shadowElement->setAttribute(SVGNames::widthAttr, use.width()->isSpecified() ? AtomicString(use.width()->currentValue()->valueAsString()) : "100%");
|
| + shadowElement->setAttribute(SVGNames::heightAttr, use.height()->isSpecified() ? AtomicString(use.height()->currentValue()->valueAsString()) : "100%");
|
| + } else if (isSVGSVGElement(*shadowElement)) {
|
| + // 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 (use.width()->isSpecified())
|
| + shadowElement->setAttribute(SVGNames::widthAttr, AtomicString(use.width()->currentValue()->valueAsString()));
|
| + else
|
| + shadowElement->setAttribute(SVGNames::widthAttr, originalElement.getAttribute(SVGNames::widthAttr));
|
| + if (use.height()->isSpecified())
|
| + shadowElement->setAttribute(SVGNames::heightAttr, AtomicString(use.height()->currentValue()->valueAsString()));
|
| + else
|
| + shadowElement->setAttribute(SVGNames::heightAttr, originalElement.getAttribute(SVGNames::heightAttr));
|
| + }
|
| +}
|
| +
|
| void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName)
|
| {
|
| if (!isSupportedAttribute(attrName)) {
|
| @@ -209,6 +233,10 @@ void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName)
|
| || attrName == SVGNames::widthAttr
|
| || attrName == SVGNames::heightAttr) {
|
| updateRelativeLengthsInformation();
|
| + if (m_targetElementInstance) {
|
| + ASSERT(m_targetElementInstance->correspondingElement());
|
| + transferUseWidthAndHeightIfNeeded(*this, m_targetElementInstance->shadowTreeElement(), *m_targetElementInstance->correspondingElement());
|
| + }
|
| if (renderer)
|
| RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
|
| return;
|
| @@ -467,6 +495,9 @@ void SVGUseElement::buildShadowAndInstanceTree(SVGElement* target)
|
| // shadow tree elements <-> instances in the instance tree.
|
| associateInstancesWithShadowTreeElements(shadowTreeRootElement->firstChild(), m_targetElementInstance.get());
|
|
|
| + ASSERT(m_targetElementInstance->correspondingElement());
|
| + transferUseWidthAndHeightIfNeeded(*this, m_targetElementInstance->shadowTreeElement(), *m_targetElementInstance->correspondingElement());
|
| +
|
| // If no shadow tree element is present, this means that the reference root
|
| // element was removed, as it is disallowed (ie. <use> on <foreignObject>)
|
| // Do NOT leave an inconsistent instance tree around, instead destruct it.
|
| @@ -702,6 +733,7 @@ void SVGUseElement::expandUseElementsInShadowTree(Node* element)
|
| if (target && !isDisallowedElement(target)) {
|
| RefPtr<Element> newChild = target->cloneElementWithChildren();
|
| ASSERT(newChild->isSVGElement());
|
| + transferUseWidthAndHeightIfNeeded(*use, toSVGElement(newChild.get()), *target);
|
| cloneParent->appendChild(newChild.release());
|
| }
|
|
|
|
|