| 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 6ae9e76bf4708410819abeec3cb8acc8c562d460..ca7d9571a75eccc6cc91bcecf7002f44c747269f 100644
|
| --- a/third_party/WebKit/Source/core/svg/SVGUseElement.cpp
|
| +++ b/third_party/WebKit/Source/core/svg/SVGUseElement.cpp
|
| @@ -59,6 +59,7 @@ inline SVGUseElement::SVGUseElement(Document& document)
|
| , m_y(SVGAnimatedLength::create(this, SVGNames::yAttr, SVGLength::create(SVGLengthMode::Height)))
|
| , m_width(SVGAnimatedLength::create(this, SVGNames::widthAttr, SVGLength::create(SVGLengthMode::Width)))
|
| , m_height(SVGAnimatedLength::create(this, SVGNames::heightAttr, SVGLength::create(SVGLengthMode::Height)))
|
| + , m_elementIdentifierIsLocal(true)
|
| , m_haveFiredLoadEvent(false)
|
| , m_needsShadowTreeRecreation(false)
|
| {
|
| @@ -131,15 +132,6 @@ void SVGUseElement::removedFrom(ContainerNode* rootParent)
|
| }
|
| }
|
|
|
| -Document* SVGUseElement::externalDocument() const
|
| -{
|
| - // Gracefully handle error condition.
|
| - if (!resourceIsValid())
|
| - return nullptr;
|
| - ASSERT(m_resource->document());
|
| - return m_resource->document();
|
| -}
|
| -
|
| static void transferUseWidthAndHeightIfNeeded(const SVGUseElement& use, SVGElement& shadowElement, const SVGElement& originalElement)
|
| {
|
| DEFINE_STATIC_LOCAL(const AtomicString, hundredPercentString, ("100%"));
|
| @@ -192,6 +184,23 @@ void SVGUseElement::collectStyleForPresentationAttribute(const QualifiedName& na
|
| SVGGraphicsElement::collectStyleForPresentationAttribute(name, value, style);
|
| }
|
|
|
| +void SVGUseElement::updateTargetReference()
|
| +{
|
| + KURL resolvedUrl = document().completeURL(hrefString());
|
| + m_elementIdentifier = AtomicString(resolvedUrl.fragmentIdentifier());
|
| + m_elementIdentifierIsLocal = resolvedUrl.isNull()
|
| + || equalIgnoringFragmentIdentifier(resolvedUrl, document().url());
|
| + if (m_elementIdentifierIsLocal) {
|
| + setDocumentResource(nullptr);
|
| + return;
|
| + }
|
| + if (m_elementIdentifier.isEmpty()
|
| + || (m_resource && equalIgnoringFragmentIdentifier(resolvedUrl, m_resource->url())))
|
| + return;
|
| + FetchRequest request(ResourceRequest(resolvedUrl), localName());
|
| + setDocumentResource(DocumentResource::fetchSVGDocument(request, document().fetcher()));
|
| +}
|
| +
|
| void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName)
|
| {
|
| if (attrName == SVGNames::xAttr
|
| @@ -221,19 +230,8 @@ void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName)
|
|
|
| if (SVGURIReference::isKnownAttribute(attrName)) {
|
| SVGElement::InvalidationGuard invalidationGuard(this);
|
| - if (isStructurallyExternal()) {
|
| - KURL url = document().completeURL(hrefString());
|
| - const KURL& existingURL = m_resource ? m_resource->url() : KURL();
|
| - if (url.hasFragmentIdentifier() && !equalIgnoringFragmentIdentifier(url, existingURL)) {
|
| - FetchRequest request(ResourceRequest(url), localName());
|
| - setDocumentResource(DocumentResource::fetchSVGDocument(request, document().fetcher()));
|
| - }
|
| - } else {
|
| - setDocumentResource(nullptr);
|
| - }
|
| -
|
| + updateTargetReference();
|
| invalidateShadowTree();
|
| -
|
| return;
|
| }
|
|
|
| @@ -305,6 +303,29 @@ void SVGUseElement::clearShadowTree()
|
| removeAllOutgoingReferences();
|
| }
|
|
|
| +Element* SVGUseElement::resolveTargetElement()
|
| +{
|
| + if (m_elementIdentifier.isEmpty())
|
| + return nullptr;
|
| + const TreeScope* lookupScope = nullptr;
|
| + if (m_elementIdentifierIsLocal)
|
| + lookupScope = &treeScope();
|
| + else if (resourceIsValid())
|
| + lookupScope = m_resource->document();
|
| + else
|
| + return nullptr;
|
| + Element* target = lookupScope->getElementById(m_elementIdentifier);
|
| + // TODO(fs): Why would the Element not be "connected" at this point?
|
| + if (target && target->isConnected())
|
| + return target;
|
| + // Don't record any pending references for external resources.
|
| + if (!m_resource) {
|
| + document().accessSVGExtensions().addPendingResource(m_elementIdentifier, this);
|
| + DCHECK(hasPendingResources());
|
| + }
|
| + return nullptr;
|
| +}
|
| +
|
| void SVGUseElement::buildPendingResource()
|
| {
|
| if (inUseShadowTree())
|
| @@ -313,26 +334,8 @@ void SVGUseElement::buildPendingResource()
|
| cancelShadowTreeRecreation();
|
| if (!isConnected())
|
| return;
|
| - Document* externalDocument = this->externalDocument();
|
| - if (isStructurallyExternal() && !externalDocument)
|
| - return;
|
| -
|
| - AtomicString id;
|
| - Element* target = targetElementFromIRIString(hrefString(), treeScope(), &id, externalDocument);
|
| - if (!target || !target->isConnected()) {
|
| - // If we can't find the target of an external element, just give up.
|
| - // We can't observe if the target somewhen enters the external document, nor should we do it.
|
| - if (externalDocument)
|
| - return;
|
| - if (id.isEmpty())
|
| - return;
|
| -
|
| - document().accessSVGExtensions().addPendingResource(id, this);
|
| - ASSERT(hasPendingResources());
|
| - return;
|
| - }
|
| -
|
| - if (target->isSVGElement()) {
|
| + Element* target = resolveTargetElement();
|
| + if (target && target->isSVGElement()) {
|
| buildShadowAndInstanceTree(toSVGElement(*target));
|
| invalidateDependentShadowTrees();
|
| }
|
|
|