Index: third_party/WebKit/Source/core/svg/SVGUseElement.cpp |
diff --git a/third_party/WebKit/Source/core/svg/SVGUseElement.cpp b/third_party/WebKit/Source/core/svg/SVGUseElement.cpp |
index c7cc2a1c8f75c12e48ba7f68d46d31ff4086c945..ce48c2928c8e6d8df2098bdb6d09e1f3ba6983cf 100644 |
--- a/third_party/WebKit/Source/core/svg/SVGUseElement.cpp |
+++ b/third_party/WebKit/Source/core/svg/SVGUseElement.cpp |
@@ -380,10 +380,37 @@ static inline void removeDisallowedElementsFromSubtree(SVGElement& subtree) |
} |
} |
+static void moveChildrenToReplacementElement(ContainerNode& sourceRoot, ContainerNode& destinationRoot) |
+{ |
+ for (RefPtrWillBeRawPtr<Node> child = sourceRoot.firstChild(); child; ) { |
+ RefPtrWillBeRawPtr<Node> nextChild = child->nextSibling(); |
+ destinationRoot.appendChild(child); |
+ child = nextChild.release(); |
+ } |
+} |
+ |
PassRefPtrWillBeRawPtr<Element> SVGUseElement::createInstanceTree(SVGElement& targetRoot) const |
{ |
RefPtrWillBeRawPtr<Element> instanceRoot = targetRoot.cloneElementWithChildren(); |
ASSERT(instanceRoot->isSVGElement()); |
+ if (isSVGSymbolElement(targetRoot)) { |
+ // Spec: The referenced 'symbol' and its contents are deep-cloned into |
+ // the generated tree, with the exception that the 'symbol' is replaced |
+ // by an 'svg'. 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. |
+ RefPtrWillBeRawPtr<SVGSVGElement> svgElement = SVGSVGElement::create(targetRoot.document()); |
+ // Transfer all data (attributes, etc.) from the <symbol> to the new |
+ // <svg> element. |
+ svgElement->cloneDataFromElement(*instanceRoot); |
+ // Move already cloned elements to the new <svg> element. |
+ moveChildrenToReplacementElement(*instanceRoot, *svgElement); |
+ instanceRoot = svgElement.release(); |
+ } |
+ transferUseWidthAndHeightIfNeeded(*this, toSVGElement(*instanceRoot), targetRoot); |
associateCorrespondingElements(targetRoot, toSVGElement(*instanceRoot)); |
removeDisallowedElementsFromSubtree(toSVGElement(*instanceRoot)); |
return instanceRoot.release(); |
@@ -430,16 +457,13 @@ void SVGUseElement::buildShadowAndInstanceTree(SVGElement& target) |
return; |
} |
- // Expand all <symbol> elements in the shadow tree. |
- // Expand means: replace the actual <symbol> element by the <svg> element. |
- expandSymbolElementsInShadowTree(); |
- |
+ // If the instance root was a <use>, it could have been replaced now, so |
+ // reset |m_targetElementInstance|. |
m_targetElementInstance = toSVGElement(shadowTreeRootElement->firstChild()); |
- transferUseWidthAndHeightIfNeeded(*this, *m_targetElementInstance, *m_targetElementInstance->correspondingElement()); |
- cloneNonMarkupEventListeners(); |
- |
ASSERT(m_targetElementInstance->parentNode() == shadowTreeRootElement); |
+ cloneNonMarkupEventListeners(); |
+ |
// Update relative length information. |
updateRelativeLengthsInformation(); |
} |
@@ -550,15 +574,6 @@ bool SVGUseElement::hasCycleUseReferencing(const SVGUseElement& use, const Conta |
return false; |
} |
-static void moveChildrenToReplacementElement(ContainerNode& sourceRoot, ContainerNode& destinationRoot) |
-{ |
- for (RefPtrWillBeRawPtr<Node> child = sourceRoot.firstChild(); child; ) { |
- RefPtrWillBeRawPtr<Node> nextChild = child->nextSibling(); |
- destinationRoot.appendChild(child); |
- child = nextChild.release(); |
- } |
-} |
- |
// Spec: In the generated content, the 'use' will be replaced by 'g', where all |
// attributes from the 'use' element except for x, y, width, height and |
// xlink:href are transferred to the generated 'g' element. |
@@ -604,11 +619,8 @@ bool SVGUseElement::expandUseElementsInShadowTree() |
// Move already cloned elements to the new <g> element. |
moveChildrenToReplacementElement(*use, *cloneParent); |
- if (target) { |
- RefPtrWillBeRawPtr<Element> instanceRoot = use->createInstanceTree(*target); |
- transferUseWidthAndHeightIfNeeded(*use, toSVGElement(*instanceRoot), *target); |
- cloneParent->appendChild(instanceRoot.release()); |
- } |
+ if (target) |
+ cloneParent->appendChild(use->createInstanceTree(*target)); |
RefPtrWillBeRawPtr<SVGElement> replacingElement(cloneParent.get()); |
@@ -620,34 +632,6 @@ bool SVGUseElement::expandUseElementsInShadowTree() |
return true; |
} |
-void SVGUseElement::expandSymbolElementsInShadowTree() |
-{ |
- ShadowRoot* shadowRoot = userAgentShadowRoot(); |
- for (RefPtrWillBeRawPtr<SVGSymbolElement> symbol = Traversal<SVGSymbolElement>::firstWithin(*shadowRoot); symbol; ) { |
- // Spec: The referenced 'symbol' and its contents are deep-cloned into the generated tree, |
- // with the exception that the 'symbol' is replaced by an 'svg'. 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. |
- SVGElement& originalSymbol = *symbol->correspondingElement(); |
- RefPtrWillBeRawPtr<SVGSVGElement> svgElement = SVGSVGElement::create(originalSymbol.document()); |
- // Transfer all data (attributes, etc.) from <symbol> to the new <svg> element. |
- svgElement->cloneDataFromElement(*symbol); |
- svgElement->setCorrespondingElement(&originalSymbol); |
- |
- // Move already cloned elements to the new <svg> element. |
- moveChildrenToReplacementElement(*symbol, *svgElement); |
- |
- RefPtrWillBeRawPtr<SVGElement> replacingElement(svgElement.get()); |
- |
- // Replace <symbol> with <svg>. |
- symbol->parentNode()->replaceChild(svgElement.release(), symbol); |
- |
- symbol = Traversal<SVGSymbolElement>::next(*replacingElement, shadowRoot); |
- } |
-} |
- |
void SVGUseElement::invalidateShadowTree() |
{ |
if (!inActiveDocument() || m_needsShadowTreeRecreation) |