Chromium Code Reviews| Index: Source/core/svg/SVGUseElement.cpp |
| diff --git a/Source/core/svg/SVGUseElement.cpp b/Source/core/svg/SVGUseElement.cpp |
| index ecdea38ef69b5fd4692b2d62d0236f271d2b4403..6a14989c1925effbb5910c13f995c59c181f583a 100644 |
| --- a/Source/core/svg/SVGUseElement.cpp |
| +++ b/Source/core/svg/SVGUseElement.cpp |
| @@ -194,6 +194,31 @@ Document* SVGUseElement::externalDocument() const |
| return 0; |
| } |
| +inline void transferUseWidthAndHeightIfNeeded(const SVGUseElement& use, SVGElement* shadowElement, SVGElement* originalElement) |
|
pdr.
2014/05/02 23:03:51
I still don't understand why this is inline.
pdr.
2014/05/02 23:03:51
Nit: can originalElement be a const reference?
|
| +{ |
| + ASSERT(shadowElement); |
| + ASSERT(originalElement); |
| + 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 +234,8 @@ void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName) |
| || attrName == SVGNames::widthAttr |
| || attrName == SVGNames::heightAttr) { |
| updateRelativeLengthsInformation(); |
| + if (m_targetElementInstance) |
| + transferUseWidthAndHeightIfNeeded(*this, m_targetElementInstance->shadowTreeElement(), m_targetElementInstance->correspondingElement()); |
| if (renderer) |
| RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); |
| return; |
| @@ -467,6 +494,8 @@ void SVGUseElement::buildShadowAndInstanceTree(SVGElement* target) |
| // shadow tree elements <-> instances in the instance tree. |
| associateInstancesWithShadowTreeElements(shadowTreeRootElement->firstChild(), m_targetElementInstance.get()); |
| + 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 +731,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()); |
| } |