| 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 f449147d68e725b0572e83348094a954857bb73f..de1192136934d869f1f74cd6602f43880f15b91a 100644
|
| --- a/third_party/WebKit/Source/core/svg/SVGUseElement.cpp
|
| +++ b/third_party/WebKit/Source/core/svg/SVGUseElement.cpp
|
| @@ -39,6 +39,7 @@
|
| #include "core/svg/SVGGElement.h"
|
| #include "core/svg/SVGLengthContext.h"
|
| #include "core/svg/SVGSVGElement.h"
|
| +#include "core/svg/SVGSymbolElement.h"
|
| #include "core/xml/parser/XMLDocumentParser.h"
|
| #include "wtf/Vector.h"
|
|
|
| @@ -423,14 +424,14 @@ void SVGUseElement::buildShadowAndInstanceTree(SVGElement* target)
|
|
|
| // Expand all <use> elements in the shadow tree.
|
| // Expand means: replace the actual <use> element by what it references.
|
| - if (!expandUseElementsInShadowTree(m_targetElementInstance.get())) {
|
| + if (!expandUseElementsInShadowTree()) {
|
| clearShadowTree();
|
| return;
|
| }
|
|
|
| // Expand all <symbol> elements in the shadow tree.
|
| // Expand means: replace the actual <symbol> element by the <svg> element.
|
| - expandSymbolElementsInShadowTree(toSVGElement(shadowTreeRootElement->firstChild()));
|
| + expandSymbolElementsInShadowTree();
|
|
|
| m_targetElementInstance = toSVGElement(shadowTreeRootElement->firstChild());
|
| transferUseWidthAndHeightIfNeeded(*this, m_targetElementInstance.get(), *m_targetElementInstance->correspondingElement());
|
| @@ -584,9 +585,8 @@ static inline void removeDisallowedElementsFromSubtree(Element& subtree)
|
| }
|
| }
|
|
|
| -bool SVGUseElement::expandUseElementsInShadowTree(SVGElement* element)
|
| +bool SVGUseElement::expandUseElementsInShadowTree()
|
| {
|
| - ASSERT(element);
|
| // Why expand the <use> elements in the shadow tree here, and not just
|
| // do this directly in buildShadowTree, if we encounter a <use> element?
|
| //
|
| @@ -594,12 +594,12 @@ bool SVGUseElement::expandUseElementsInShadowTree(SVGElement* element)
|
| // contains <use> tags, we'd miss them. So once we're done with setting up the
|
| // actual shadow tree (after the special case modification for svg/symbol) we have
|
| // to walk it completely and expand all <use> elements.
|
| - if (isSVGUseElement(*element)) {
|
| - SVGUseElement* use = toSVGUseElement(element);
|
| + ShadowRoot* shadowRoot = userAgentShadowRoot();
|
| + for (RefPtrWillBeRawPtr<SVGUseElement> use = Traversal<SVGUseElement>::firstWithin(*shadowRoot); use; ) {
|
| ASSERT(!use->resourceIsStillLoading());
|
|
|
| SVGElement* target = 0;
|
| - if (hasCycleUseReferencing(toSVGUseElement(use->correspondingElement()), use, target))
|
| + if (hasCycleUseReferencing(toSVGUseElement(use->correspondingElement()), use.get(), target))
|
| return false;
|
|
|
| if (target && isDisallowedElement(target))
|
| @@ -618,7 +618,7 @@ bool SVGUseElement::expandUseElementsInShadowTree(SVGElement* element)
|
|
|
| // 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.
|
| - transferUseAttributesToReplacedElement(use, cloneParent.get());
|
| + transferUseAttributesToReplacedElement(use.get(), cloneParent.get());
|
|
|
| if (target) {
|
| RefPtrWillBeRawPtr<Node> newChild = cloneNodeAndAssociate(*target);
|
| @@ -638,29 +638,17 @@ bool SVGUseElement::expandUseElementsInShadowTree(SVGElement* element)
|
| RefPtrWillBeRawPtr<SVGElement> replacingElement(cloneParent.get());
|
|
|
| // Replace <use> with referenced content.
|
| - ASSERT(use->parentNode());
|
| use->parentNode()->replaceChild(cloneParent.release(), use);
|
|
|
| - // Expand the siblings because the *element* is replaced and we will
|
| - // lose the sibling chain when we are back from recursion.
|
| - element = replacingElement.get();
|
| - for (RefPtrWillBeRawPtr<SVGElement> sibling = Traversal<SVGElement>::nextSibling(*element); sibling; sibling = Traversal<SVGElement>::nextSibling(*sibling)) {
|
| - if (!expandUseElementsInShadowTree(sibling.get()))
|
| - return false;
|
| - }
|
| - }
|
| -
|
| - for (RefPtrWillBeRawPtr<SVGElement> child = Traversal<SVGElement>::firstChild(*element); child; child = Traversal<SVGElement>::nextSibling(*child)) {
|
| - if (!expandUseElementsInShadowTree(child.get()))
|
| - return false;
|
| + use = Traversal<SVGUseElement>::next(*replacingElement, shadowRoot);
|
| }
|
| return true;
|
| }
|
|
|
| -void SVGUseElement::expandSymbolElementsInShadowTree(SVGElement* element)
|
| +void SVGUseElement::expandSymbolElementsInShadowTree()
|
| {
|
| - ASSERT(element);
|
| - if (isSVGSymbolElement(*element)) {
|
| + 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
|
| @@ -670,11 +658,11 @@ void SVGUseElement::expandSymbolElementsInShadowTree(SVGElement* element)
|
| ASSERT(referencedScope());
|
| RefPtrWillBeRawPtr<SVGSVGElement> svgElement = SVGSVGElement::create(referencedScope()->document());
|
| // Transfer all data (attributes, etc.) from <symbol> to the new <svg> element.
|
| - svgElement->cloneDataFromElement(*element);
|
| - svgElement->setCorrespondingElement(element->correspondingElement());
|
| + svgElement->cloneDataFromElement(*symbol);
|
| + svgElement->setCorrespondingElement(symbol->correspondingElement());
|
|
|
| // Move already cloned elements to the new <svg> element
|
| - for (RefPtrWillBeRawPtr<Node> child = element->firstChild(); child; ) {
|
| + for (RefPtrWillBeRawPtr<Node> child = symbol->firstChild(); child; ) {
|
| RefPtrWillBeRawPtr<Node> nextChild = child->nextSibling();
|
| svgElement->appendChild(child);
|
| child = nextChild.release();
|
| @@ -691,18 +679,10 @@ void SVGUseElement::expandSymbolElementsInShadowTree(SVGElement* element)
|
| RefPtrWillBeRawPtr<SVGElement> replacingElement(svgElement.get());
|
|
|
| // Replace <symbol> with <svg>.
|
| - ASSERT(element->parentNode());
|
| - element->parentNode()->replaceChild(svgElement.release(), element);
|
| -
|
| - // Expand the siblings because the *element* is replaced and we will
|
| - // lose the sibling chain when we are back from recursion.
|
| - element = replacingElement.get();
|
| - for (RefPtrWillBeRawPtr<SVGElement> sibling = Traversal<SVGElement>::nextSibling(*element); sibling; sibling = Traversal<SVGElement>::nextSibling(*sibling))
|
| - expandSymbolElementsInShadowTree(sibling.get());
|
| - }
|
| + symbol->parentNode()->replaceChild(svgElement.release(), symbol);
|
|
|
| - for (RefPtrWillBeRawPtr<SVGElement> child = Traversal<SVGElement>::firstChild(*element); child; child = Traversal<SVGElement>::nextSibling(*child))
|
| - expandSymbolElementsInShadowTree(child.get());
|
| + symbol = Traversal<SVGSymbolElement>::next(*replacingElement, shadowRoot);
|
| + }
|
| }
|
|
|
| void SVGUseElement::invalidateShadowTree()
|
|
|