void RenderSVGResourceContainer::registerResource() { SVGDocumentExtensions& extensions = svgExtensionsFromElement(element()); if (!extensions.hasPendingResource(m_id)) { extensions.addResource(m_id, this); return; } OwnPtr<SVGDocumentExtensions::SVGPendingElements> clients(extensions.removePendingResource(m_id)); // Cache us with the new id. extensions.addResource(m_id, this); // Update cached resources of pending clients. const SVGDocumentExtensions::SVGPendingElements::const_iterator end = clients->end(); for (SVGDocumentExtensions::SVGPendingElements::const_iterator it = clients->begin(); it != end; ++it) { ASSERT((*it)->hasPendingResources()); extensions.clearHasPendingResourcesIfPossible(*it); RenderObject* renderer = (*it)->renderer(); if (!renderer) continue; StyleDifference diff; diff.setNeedsFullLayout(); SVGResourcesCache::clientStyleChanged(renderer, diff, renderer->style()); renderer->setNeedsLayoutAndFullPaintInvalidation(); } }
void RenderSVGResourceContainer::idChanged() { // Invalidate all our current clients. removeAllClientsFromCache(); // Remove old id, that is guaranteed to be present in cache. svgExtensionsFromElement(element()).removeResource(m_id); m_id = element().getIdAttribute(); registerResource(); }
void LayoutSVGResourceContainer::willBeDestroyed() { // Detach all clients referring to this resource. If the resource itself is // a client, it will be detached from any such resources by the call to // LayoutSVGHiddenContainer::willBeDestroyed() below. detachAllClients(); for (SVGResourceClient* client : m_resourceClients) client->filterWillBeDestroyed(toSVGFilterElement(element())); m_resourceClients.clear(); LayoutSVGHiddenContainer::willBeDestroyed(); if (m_registered) svgExtensionsFromElement(element()).removeResource(m_id); }
void LayoutSVGResourceContainer::detachAllClients() { for (auto* client : m_clients) { // Unlink the resource from the client's SVGResources. (The actual // removal will be signaled after processing all the clients.) SVGResources* resources = SVGResourcesCache::cachedResourcesForLayoutObject(client); ASSERT(resources); // Or else the client wouldn't be in the list in the first place. resources->resourceDestroyed(this); // Add a pending resolution based on the id of the old resource. Element* clientElement = toElement(client->node()); svgExtensionsFromElement(clientElement).addPendingResource(m_id, clientElement); } removeAllClientsFromCache(); }
void LayoutSVGResourceContainer::registerResource() { SVGDocumentExtensions& extensions = svgExtensionsFromElement(element()); if (!extensions.hasPendingResource(m_id)) { extensions.addResource(m_id, this); return; } SVGDocumentExtensions::SVGPendingElements* clients(extensions.removePendingResource(m_id)); // Cache us with the new id. extensions.addResource(m_id, this); // Update cached resources of pending clients. for (const auto& pendingClient : *clients) { ASSERT(pendingClient->hasPendingResources()); extensions.clearHasPendingResourcesIfPossible(pendingClient); LayoutObject* layoutObject = pendingClient->layoutObject(); if (!layoutObject) continue; const ComputedStyle& style = layoutObject->styleRef(); // If the client has a layer (is a non-SVGElement) we need to signal // invalidation in the same way as is done in markAllResourceClientsForInvalidation above. if (layoutObject->hasLayer() && resourceType() == FilterResourceType) { if (style.hasFilter()) toLayoutBoxModelObject(layoutObject)->layer()->filterNeedsPaintInvalidation(); // If this is the SVG root, we could have both 'filter' and // '-webkit-filter' applied, so we need to do the invalidation // below as well, unless we can optimistically determine that // 'filter' does not apply to the element in question. if (!layoutObject->isSVGRoot() || !style.svgStyle().hasFilter()) continue; } StyleDifference diff; diff.setNeedsFullLayout(); SVGResourcesCache::clientStyleChanged(layoutObject, diff, style); layoutObject->setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReason::SvgResourceInvalidated); } }
RenderSVGResourceContainer::~RenderSVGResourceContainer() { if (m_registered) svgExtensionsFromElement(element()).removeResource(m_id); }