Chromium Code Reviews| 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 848977a8c55afef5d40533597c9cc9bee470dcb2..3677fc8a0d38bc2966714ed627c48bb02e38558c 100644 |
| --- a/third_party/WebKit/Source/core/svg/SVGUseElement.cpp |
| +++ b/third_party/WebKit/Source/core/svg/SVGUseElement.cpp |
| @@ -305,6 +305,21 @@ static bool subtreeContainsDisallowedElement(const Node* start) |
| return false; |
| } |
| +static inline void removeSymbolElementsFromSubtree(SVGElement& subtreeRoot) |
| +{ |
| + Element* element = ElementTraversal::firstWithin(subtreeRoot); |
| + while (element) { |
| + if (isSVGSymbolElement(element)) { |
| + Element* next = ElementTraversal::nextSkippingChildren(*element, &subtreeRoot); |
| + // The subtree is not in document so this won't generate events that could mutate the tree. |
|
pdr.
2016/02/29 23:45:40
Can you assert this here and/or above--that the su
|
| + element->parentNode()->removeChild(element); |
| + element = next; |
| + } else { |
| + element = ElementTraversal::next(*element, &subtreeRoot); |
| + } |
| + } |
| +} |
| + |
| void SVGUseElement::scheduleShadowTreeRecreation() |
| { |
| if (inUseShadowTree()) |
| @@ -403,18 +418,26 @@ void SVGUseElement::buildShadowAndInstanceTree(SVGElement* target) |
| // Set up root SVG element in shadow tree. |
| RefPtrWillBeRawPtr<Element> newChild = target->cloneElementWithoutChildren(); |
| - m_targetElementInstance = toSVGElement(newChild.get()); |
| - ShadowRoot* shadowTreeRootElement = userAgentShadowRoot(); |
| - shadowTreeRootElement->appendChild(newChild.release()); |
| + ASSERT(newChild->isSVGElement()); |
| // Clone the target subtree into the shadow tree, not handling <use> and <symbol> yet. |
| // SVG specification does not say a word about <use> & cycles. My view on this is: just ignore it! |
| // Non-appearing <use> content is easier to debug, then half-appearing content. |
| - if (!buildShadowTree(target, m_targetElementInstance.get(), false)) { |
| + if (!buildShadowTree(target, toSVGElement(newChild.get()), false)) { |
| clearShadowTree(); |
| return; |
| } |
| + // Remove any <symbol> elements from the clone, because if not, they'll be |
| + // replaced by <svg> elements which will appear in the rendered result (and |
| + // <symbol>s that are not a direct target of a <use> should not be |
| + // rendered.) |
| + removeSymbolElementsFromSubtree(toSVGElement(*newChild)); |
|
pdr.
2016/02/29 23:45:40
expandSymbolElementsInShadowTree is called below a
|
| + |
| + // Attach the new clone to our shadow root. |
| + m_targetElementInstance = toSVGElement(newChild.get()); |
| + ShadowRoot* shadowTreeRootElement = userAgentShadowRoot(); |
| + shadowTreeRootElement->appendChild(newChild.release()); |
| if (instanceTreeIsLoading(m_targetElementInstance.get())) |
| return; |
| @@ -622,6 +645,11 @@ bool SVGUseElement::expandUseElementsInShadowTree(SVGElement* element) |
| if (target) { |
| RefPtrWillBeRawPtr<Node> newChild = cloneNodeAndAssociate(*target); |
| ASSERT(newChild->isSVGElement()); |
| + // Remove any <symbol> elements from the clone, because if not, |
|
pdr.
2016/02/29 23:45:40
I like how webkit wraps this complexity into a sin
|
| + // they'll be replaced by <svg> elements which will appear in the |
| + // rendered result (and <symbol>s that are not a direct target of a |
| + // <use> should not be rendered.) |
| + removeSymbolElementsFromSubtree(toSVGElement(*newChild)); |
| transferUseWidthAndHeightIfNeeded(*use, toSVGElement(newChild.get()), *target); |
| cloneParent->appendChild(newChild.release()); |
| } |