Index: third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceContainer.cpp |
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceContainer.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceContainer.cpp |
index 0a419cf9d5d14b97968e0463a88c5df04c0c2aa6..1a224e9fb3144af0216c03b69f4a7aff36387370 100644 |
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceContainer.cpp |
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceContainer.cpp |
@@ -27,17 +27,22 @@ |
namespace blink { |
-static inline SVGTreeScopeResources& SvgTreeScopeResourcesFromElement( |
- Element* element) { |
- DCHECK(element); |
- return element->GetTreeScope().EnsureSVGTreeScopedResources(); |
+namespace { |
+ |
+SVGTreeScopeResources::Resource* ResourceForContainer( |
+ const LayoutSVGResourceContainer& resource_container) { |
+ const SVGElement& element = *resource_container.GetElement(); |
+ return element.GetTreeScope() |
+ .EnsureSVGTreeScopedResources() |
+ .ExistingResourceForId(element.GetIdAttribute()); |
} |
+} // namespace |
+ |
LayoutSVGResourceContainer::LayoutSVGResourceContainer(SVGElement* node) |
: LayoutSVGHiddenContainer(node), |
is_in_layout_(false), |
invalidation_mask_(0), |
- registered_(false), |
is_invalidating_(false) {} |
LayoutSVGResourceContainer::~LayoutSVGResourceContainer() {} |
@@ -68,45 +73,42 @@ void LayoutSVGResourceContainer::NotifyContentChanged() { |
void LayoutSVGResourceContainer::WillBeDestroyed() { |
LayoutSVGHiddenContainer::WillBeDestroyed(); |
- SvgTreeScopeResourcesFromElement(GetElement()) |
- .RemoveResource(GetElement()->GetIdAttribute(), this); |
- DCHECK(clients_.IsEmpty()); |
+ // The resource is being torn down. If we have any clients, move those to be |
+ // pending on the resource (if one exists.) |
+ if (SVGTreeScopeResources::Resource* resource = ResourceForContainer(*this)) |
+ MakeClientsPending(*resource); |
} |
void LayoutSVGResourceContainer::StyleDidChange( |
StyleDifference diff, |
const ComputedStyle* old_style) { |
LayoutSVGHiddenContainer::StyleDidChange(diff, old_style); |
- SvgTreeScopeResourcesFromElement(GetElement()) |
- .UpdateResource(GetElement()->GetIdAttribute(), this); |
+ // The resource has (read: may have) been attached. Notify any pending |
+ // clients that they can now try to add themselves as clients to the |
+ // resource. |
+ if (SVGTreeScopeResources::Resource* resource = ResourceForContainer(*this)) { |
+ if (resource->Target() == GetElement()) |
+ resource->NotifyResourceClients(); |
+ } |
} |
-void LayoutSVGResourceContainer::DetachAllClients(const AtomicString& to_id) { |
+void LayoutSVGResourceContainer::MakeClientsPending( |
+ SVGTreeScopeResources::Resource& resource) { |
RemoveAllClientsFromCache(); |
for (auto* client : clients_) { |
- // Unlink the resource from the client's SVGResources. (The actual |
- // removal will be signaled after processing all the clients.) |
+ // Unlink the resource from the client's SVGResources. |
SVGResources* resources = |
SVGResourcesCache::CachedResourcesForLayoutObject(client); |
// Or else the client wouldn't be in the list in the first place. |
DCHECK(resources); |
resources->ResourceDestroyed(this); |
- // Add a pending resolution based on the id of the old resource. |
- Element* client_element = ToElement(client->GetNode()); |
- SvgTreeScopeResourcesFromElement(client_element) |
- .AddPendingResource(to_id, *client_element); |
+ resource.AddWatch(ToSVGElement(*client->GetNode())); |
} |
clients_.clear(); |
} |
-void LayoutSVGResourceContainer::IdChanged(const AtomicString& old_id, |
- const AtomicString& new_id) { |
- SvgTreeScopeResourcesFromElement(GetElement()) |
- .UpdateResource(old_id, new_id, this); |
-} |
- |
void LayoutSVGResourceContainer::MarkAllClientsForInvalidation( |
InvalidationMode mode) { |
if (is_invalidating_) |
@@ -177,10 +179,11 @@ void LayoutSVGResourceContainer::AddClient(LayoutObject* client) { |
ClearInvalidationMask(); |
} |
-void LayoutSVGResourceContainer::RemoveClient(LayoutObject* client) { |
+bool LayoutSVGResourceContainer::RemoveClient(LayoutObject* client) { |
DCHECK(client); |
RemoveClientFromCache(client, false); |
clients_.erase(client); |
+ return clients_.IsEmpty(); |
} |
void LayoutSVGResourceContainer::InvalidateCacheAndMarkForLayout( |