void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName) { SVGStyledTransformableElement::svgAttributeChanged(attrName); bool isXYAttribute = attrName == SVGNames::xAttr || attrName == SVGNames::yAttr; bool isWidthHeightAttribute = attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr; if (isXYAttribute || isWidthHeightAttribute) updateRelativeLengthsInformation(); if (SVGTests::handleAttributeChange(this, attrName)) return; RenderObject* object = renderer(); if (!object) return; if (SVGURIReference::isKnownAttribute(attrName)) { if (hasPendingResources()) { OwnPtr<SVGDocumentExtensions::SVGPendingElements> clients(document()->accessSVGExtensions()->removePendingResource(m_resourceId)); ASSERT(!clients->isEmpty()); const SVGDocumentExtensions::SVGPendingElements::const_iterator end = clients->end(); for (SVGDocumentExtensions::SVGPendingElements::const_iterator it = clients->begin(); it != end; ++it) { ASSERT((*it)->hasPendingResources()); (*it)->setHasPendingResources(false); } m_resourceId = String(); setHasPendingResources(false); } invalidateShadowTree(); return; } if (isXYAttribute) { updateContainerOffsets(); return; } if (isWidthHeightAttribute) { updateContainerSizes(); return; } // Be very careful here, if svgAttributeChanged() has been called because a SVG CSS property changed, we do NOT want to reclone the tree! if (SVGStyledElement::isKnownAttribute(attrName)) { setNeedsStyleRecalc(); return; } if (SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) invalidateShadowTree(); }
void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName) { SVGStyledTransformableElement::svgAttributeChanged(attrName); bool isXYAttribute = attrName == SVGNames::xAttr || attrName == SVGNames::yAttr; bool isWidthHeightAttribute = attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr; if (isXYAttribute || isWidthHeightAttribute) updateRelativeLengthsInformation(); if (SVGTests::handleAttributeChange(this, attrName)) return; RenderObject* object = renderer(); if (!object) return; if (SVGURIReference::isKnownAttribute(attrName)) { if (m_isPendingResource) { document()->accessSVGExtensions()->removePendingResource(m_resourceId); m_resourceId = String(); m_isPendingResource = false; } invalidateShadowTree(); return; } if (isXYAttribute) { updateContainerOffsets(); return; } if (isWidthHeightAttribute) { updateContainerSizes(); return; } // Be very careful here, if svgAttributeChanged() has been called because a SVG CSS property changed, we do NOT want to reclone the tree! if (SVGStyledElement::isKnownAttribute(attrName)) { setNeedsStyleRecalc(); return; } if (SVGStyledTransformableElement::isKnownAttribute(attrName)) { object->setNeedsTransformUpdate(); RenderSVGResource::markForLayoutAndParentResourceInvalidation(object); return; } if (SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) invalidateShadowTree(); }
void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName) { if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr || attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr) { SVGElement::InvalidationGuard invalidationGuard(this); if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr) { invalidateSVGPresentationAttributeStyle(); setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracing::fromAttribute(attrName)); } updateRelativeLengthsInformation(); if (m_targetElementInstance) { ASSERT(m_targetElementInstance->correspondingElement()); transferUseWidthAndHeightIfNeeded( *this, *m_targetElementInstance, *m_targetElementInstance->correspondingElement()); } LayoutObject* object = this->layoutObject(); if (object) markForLayoutAndParentResourceInvalidation(object); return; } if (SVGURIReference::isKnownAttribute(attrName)) { SVGElement::InvalidationGuard invalidationGuard(this); updateTargetReference(); invalidateShadowTree(); return; } SVGGraphicsElement::svgAttributeChanged(attrName); }
void SVGUseElement::buildPendingResource() { // If we're called the first time (during shadow tree root creation from RenderSVGShadowTreeRootContainer) // we either determine that our target is available or not - then we add ourselves to the pending resource list // Once the pending resource appears, it will call buildPendingResource(), so we're called a second time. String id = SVGURIReference::getTarget(href()); Element* targetElement = document()->getElementById(id); ASSERT(!m_targetElementInstance); if (!targetElement) { if (m_isPendingResource || id.isEmpty()) return; m_isPendingResource = true; m_resourceId = id; document()->accessSVGExtensions()->addPendingResource(id, this); return; } if (m_isPendingResource) { ASSERT(!m_targetElementInstance); m_isPendingResource = false; invalidateShadowTree(); } }
void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName) { SVGStyledTransformableElement::svgAttributeChanged(attrName); if (!renderer()) return; if (SVGURIReference::isKnownAttribute(attrName)) { if (m_isPendingResource) { document()->accessSVGExtensions()->removePendingResource(m_resourceId); m_resourceId = String(); m_isPendingResource = false; } invalidateShadowTree(); return; } if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr) { updateContainerOffsets(); return; } if (attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr) { updateContainerSizes(); return; } // Be very careful here, if svgAttributeChanged() has been called because a SVG CSS property changed, we do NOT want to reclone the tree! if (SVGStyledElement::isKnownAttribute(attrName)) { setNeedsStyleRecalc(); return; } if (SVGStyledTransformableElement::isKnownAttribute(attrName)) { renderer()->setNeedsTransformUpdate(); renderer()->setNeedsLayout(true); return; } if (SVGTests::isKnownAttribute(attrName) || SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) invalidateShadowTree(); }
Node::InsertionNotificationRequest SVGUseElement::insertedInto(ContainerNode* rootParent) { // This functions exists to assure assumptions made in the code regarding SVGElementInstance creation/destruction are satisfied. SVGGraphicsElement::insertedInto(rootParent); if (!rootParent->inDocument()) return InsertionDone; ASSERT(!m_targetElementInstance || !isWellFormedDocument(&document())); ASSERT(!hasPendingResources() || !isWellFormedDocument(&document())); invalidateShadowTree(); return InsertionDone; }
void SVGUseElement::notifyFinished(CachedResource* resource) { if (!inDocument()) return; invalidateShadowTree(); if (resource->errorOccurred()) dispatchEvent(Event::create(eventNames().errorEvent, false, false)); else if (!resource->wasCanceled()) SVGExternalResourcesRequired::dispatchLoadEvent(this); }
void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName) { if (!isSupportedAttribute(attrName)) { SVGGraphicsElement::svgAttributeChanged(attrName); return; } SVGElementInstance::InvalidationGuard invalidationGuard(this); auto renderer = this->renderer(); if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr || attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr) { updateRelativeLengthsInformation(); if (renderer) RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); return; } if (SVGExternalResourcesRequired::handleAttributeChange(this, attrName)) return; if (SVGURIReference::isKnownAttribute(attrName)) { bool isExternalReference = isExternalURIReference(href(), document()); if (isExternalReference) { URL url = document().completeURL(href()); if (url.hasFragmentIdentifier()) { CachedResourceRequest request(ResourceRequest(url.string())); request.setInitiator(this); setCachedDocument(document().cachedResourceLoader()->requestSVGDocument(request)); } } else setCachedDocument(0); if (!m_wasInsertedByParser) buildPendingResource(); return; } if (SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) { invalidateShadowTree(); return; } ASSERT_NOT_REACHED(); }
void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName) { if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr || attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr) { SVGElement::InvalidationGuard invalidationGuard(this); if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr) { invalidateSVGPresentationAttributeStyle(); setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracing::fromAttribute(attrName)); } updateRelativeLengthsInformation(); if (m_targetElementInstance) { ASSERT(m_targetElementInstance->correspondingElement()); transferUseWidthAndHeightIfNeeded(*this, m_targetElementInstance.get(), *m_targetElementInstance->correspondingElement()); } LayoutObject* object = this->layoutObject(); if (object) markForLayoutAndParentResourceInvalidation(object); return; } 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); } invalidateShadowTree(); return; } SVGGraphicsElement::svgAttributeChanged(attrName); }
void SVGUseElement::notifyFinished(Resource* resource) { if (!inDocument()) return; invalidateShadowTree(); if (resource->errorOccurred()) { dispatchEvent(Event::create(EventTypeNames::error)); } else if (!resource->wasCanceled()) { if (m_haveFiredLoadEvent) return; if (!isStructurallyExternal()) return; ASSERT(!m_haveFiredLoadEvent); m_haveFiredLoadEvent = true; svgUseLoadEventSender().dispatchEventSoon(this); } }