| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 2 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
| 3 * | 3 * |
| 4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
| 5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
| 6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
| 7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
| 8 * | 8 * |
| 9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 12 * Library General Public License for more details. | 12 * Library General Public License for more details. |
| 13 * | 13 * |
| 14 * You should have received a copy of the GNU Library General Public License | 14 * You should have received a copy of the GNU Library General Public License |
| 15 * along with this library; see the file COPYING.LIB. If not, write to | 15 * along with this library; see the file COPYING.LIB. If not, write to |
| 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 17 * Boston, MA 02110-1301, USA. | 17 * Boston, MA 02110-1301, USA. |
| 18 */ | 18 */ |
| 19 | 19 |
| 20 #include "core/layout/svg/LayoutSVGResourceContainer.h" | 20 #include "core/layout/svg/LayoutSVGResourceContainer.h" |
| 21 | 21 |
| 22 #include "core/layout/svg/SVGResources.h" | 22 #include "core/layout/svg/SVGResources.h" |
| 23 #include "core/layout/svg/SVGResourcesCache.h" | 23 #include "core/layout/svg/SVGResourcesCache.h" |
| 24 #include "core/svg/SVGElementProxy.h" | 24 #include "core/svg/SVGElementProxy.h" |
| 25 #include "core/svg/SVGTreeScopeResources.h" | 25 #include "core/svg/SVGTreeScopeResources.h" |
| 26 #include "platform/wtf/AutoReset.h" | 26 #include "platform/wtf/AutoReset.h" |
| 27 | 27 |
| 28 namespace blink { | 28 namespace blink { |
| 29 | 29 |
| 30 static inline SVGTreeScopeResources& SvgTreeScopeResourcesFromElement( | 30 namespace { |
| 31 Element* element) { | 31 |
| 32 DCHECK(element); | 32 SVGTreeScopeResources::Resource* ResourceForContainer( |
| 33 return element->GetTreeScope().EnsureSVGTreeScopedResources(); | 33 const LayoutSVGResourceContainer& resource_container) { |
| 34 const SVGElement& element = *resource_container.GetElement(); |
| 35 return element.GetTreeScope() |
| 36 .EnsureSVGTreeScopedResources() |
| 37 .ExistingResourceForId(element.GetIdAttribute()); |
| 34 } | 38 } |
| 35 | 39 |
| 40 } // namespace |
| 41 |
| 36 LayoutSVGResourceContainer::LayoutSVGResourceContainer(SVGElement* node) | 42 LayoutSVGResourceContainer::LayoutSVGResourceContainer(SVGElement* node) |
| 37 : LayoutSVGHiddenContainer(node), | 43 : LayoutSVGHiddenContainer(node), |
| 38 is_in_layout_(false), | 44 is_in_layout_(false), |
| 39 invalidation_mask_(0), | 45 invalidation_mask_(0), |
| 40 registered_(false), | |
| 41 is_invalidating_(false) {} | 46 is_invalidating_(false) {} |
| 42 | 47 |
| 43 LayoutSVGResourceContainer::~LayoutSVGResourceContainer() {} | 48 LayoutSVGResourceContainer::~LayoutSVGResourceContainer() {} |
| 44 | 49 |
| 45 void LayoutSVGResourceContainer::UpdateLayout() { | 50 void LayoutSVGResourceContainer::UpdateLayout() { |
| 46 // FIXME: Investigate a way to detect and break resource layout dependency | 51 // FIXME: Investigate a way to detect and break resource layout dependency |
| 47 // cycles early. Then we can remove this method altogether, and fall back onto | 52 // cycles early. Then we can remove this method altogether, and fall back onto |
| 48 // LayoutSVGHiddenContainer::layout(). | 53 // LayoutSVGHiddenContainer::layout(). |
| 49 DCHECK(NeedsLayout()); | 54 DCHECK(NeedsLayout()); |
| 50 if (is_in_layout_) | 55 if (is_in_layout_) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 61 return GetElement()->ElementProxySet(); | 66 return GetElement()->ElementProxySet(); |
| 62 } | 67 } |
| 63 | 68 |
| 64 void LayoutSVGResourceContainer::NotifyContentChanged() { | 69 void LayoutSVGResourceContainer::NotifyContentChanged() { |
| 65 if (SVGElementProxySet* proxy_set = ElementProxySet()) | 70 if (SVGElementProxySet* proxy_set = ElementProxySet()) |
| 66 proxy_set->NotifyContentChanged(GetElement()->GetTreeScope()); | 71 proxy_set->NotifyContentChanged(GetElement()->GetTreeScope()); |
| 67 } | 72 } |
| 68 | 73 |
| 69 void LayoutSVGResourceContainer::WillBeDestroyed() { | 74 void LayoutSVGResourceContainer::WillBeDestroyed() { |
| 70 LayoutSVGHiddenContainer::WillBeDestroyed(); | 75 LayoutSVGHiddenContainer::WillBeDestroyed(); |
| 71 SvgTreeScopeResourcesFromElement(GetElement()) | 76 // The resource is being torn down. If we have any clients, move those to be |
| 72 .RemoveResource(GetElement()->GetIdAttribute(), this); | 77 // pending on the resource (if one exists.) |
| 73 DCHECK(clients_.IsEmpty()); | 78 if (SVGTreeScopeResources::Resource* resource = ResourceForContainer(*this)) |
| 79 MakeClientsPending(*resource); |
| 74 } | 80 } |
| 75 | 81 |
| 76 void LayoutSVGResourceContainer::StyleDidChange( | 82 void LayoutSVGResourceContainer::StyleDidChange( |
| 77 StyleDifference diff, | 83 StyleDifference diff, |
| 78 const ComputedStyle* old_style) { | 84 const ComputedStyle* old_style) { |
| 79 LayoutSVGHiddenContainer::StyleDidChange(diff, old_style); | 85 LayoutSVGHiddenContainer::StyleDidChange(diff, old_style); |
| 80 SvgTreeScopeResourcesFromElement(GetElement()) | 86 // The resource has (read: may have) been attached. Notify any pending |
| 81 .UpdateResource(GetElement()->GetIdAttribute(), this); | 87 // clients that they can now try to add themselves as clients to the |
| 88 // resource. |
| 89 if (SVGTreeScopeResources::Resource* resource = ResourceForContainer(*this)) { |
| 90 if (resource->Target() == GetElement()) |
| 91 resource->NotifyResourceClients(); |
| 92 } |
| 82 } | 93 } |
| 83 | 94 |
| 84 void LayoutSVGResourceContainer::DetachAllClients(const AtomicString& to_id) { | 95 void LayoutSVGResourceContainer::MakeClientsPending( |
| 96 SVGTreeScopeResources::Resource& resource) { |
| 85 RemoveAllClientsFromCache(); | 97 RemoveAllClientsFromCache(); |
| 86 | 98 |
| 87 for (auto* client : clients_) { | 99 for (auto* client : clients_) { |
| 88 // Unlink the resource from the client's SVGResources. (The actual | 100 // Unlink the resource from the client's SVGResources. |
| 89 // removal will be signaled after processing all the clients.) | |
| 90 SVGResources* resources = | 101 SVGResources* resources = |
| 91 SVGResourcesCache::CachedResourcesForLayoutObject(client); | 102 SVGResourcesCache::CachedResourcesForLayoutObject(client); |
| 92 // Or else the client wouldn't be in the list in the first place. | 103 // Or else the client wouldn't be in the list in the first place. |
| 93 DCHECK(resources); | 104 DCHECK(resources); |
| 94 resources->ResourceDestroyed(this); | 105 resources->ResourceDestroyed(this); |
| 95 | 106 |
| 96 // Add a pending resolution based on the id of the old resource. | 107 resource.AddWatch(ToSVGElement(*client->GetNode())); |
| 97 Element* client_element = ToElement(client->GetNode()); | |
| 98 SvgTreeScopeResourcesFromElement(client_element) | |
| 99 .AddPendingResource(to_id, *client_element); | |
| 100 } | 108 } |
| 101 clients_.clear(); | 109 clients_.clear(); |
| 102 } | 110 } |
| 103 | 111 |
| 104 void LayoutSVGResourceContainer::IdChanged(const AtomicString& old_id, | |
| 105 const AtomicString& new_id) { | |
| 106 SvgTreeScopeResourcesFromElement(GetElement()) | |
| 107 .UpdateResource(old_id, new_id, this); | |
| 108 } | |
| 109 | |
| 110 void LayoutSVGResourceContainer::MarkAllClientsForInvalidation( | 112 void LayoutSVGResourceContainer::MarkAllClientsForInvalidation( |
| 111 InvalidationMode mode) { | 113 InvalidationMode mode) { |
| 112 if (is_invalidating_) | 114 if (is_invalidating_) |
| 113 return; | 115 return; |
| 114 SVGElementProxySet* proxy_set = ElementProxySet(); | 116 SVGElementProxySet* proxy_set = ElementProxySet(); |
| 115 if (clients_.IsEmpty() && (!proxy_set || proxy_set->IsEmpty())) | 117 if (clients_.IsEmpty() && (!proxy_set || proxy_set->IsEmpty())) |
| 116 return; | 118 return; |
| 117 if (invalidation_mask_ & mode) | 119 if (invalidation_mask_ & mode) |
| 118 return; | 120 return; |
| 119 | 121 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 170 break; | 172 break; |
| 171 } | 173 } |
| 172 } | 174 } |
| 173 | 175 |
| 174 void LayoutSVGResourceContainer::AddClient(LayoutObject* client) { | 176 void LayoutSVGResourceContainer::AddClient(LayoutObject* client) { |
| 175 DCHECK(client); | 177 DCHECK(client); |
| 176 clients_.insert(client); | 178 clients_.insert(client); |
| 177 ClearInvalidationMask(); | 179 ClearInvalidationMask(); |
| 178 } | 180 } |
| 179 | 181 |
| 180 void LayoutSVGResourceContainer::RemoveClient(LayoutObject* client) { | 182 bool LayoutSVGResourceContainer::RemoveClient(LayoutObject* client) { |
| 181 DCHECK(client); | 183 DCHECK(client); |
| 182 RemoveClientFromCache(client, false); | 184 RemoveClientFromCache(client, false); |
| 183 clients_.erase(client); | 185 clients_.erase(client); |
| 186 return clients_.IsEmpty(); |
| 184 } | 187 } |
| 185 | 188 |
| 186 void LayoutSVGResourceContainer::InvalidateCacheAndMarkForLayout( | 189 void LayoutSVGResourceContainer::InvalidateCacheAndMarkForLayout( |
| 187 SubtreeLayoutScope* layout_scope) { | 190 SubtreeLayoutScope* layout_scope) { |
| 188 if (SelfNeedsLayout()) | 191 if (SelfNeedsLayout()) |
| 189 return; | 192 return; |
| 190 | 193 |
| 191 SetNeedsLayoutAndFullPaintInvalidation( | 194 SetNeedsLayoutAndFullPaintInvalidation( |
| 192 LayoutInvalidationReason::kSvgResourceInvalidated, kMarkContainerChain, | 195 LayoutInvalidationReason::kSvgResourceInvalidated, kMarkContainerChain, |
| 193 layout_scope); | 196 layout_scope); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 256 // This will process the rest of the ancestors. | 259 // This will process the rest of the ancestors. |
| 257 ToLayoutSVGResourceContainer(current)->RemoveAllClientsFromCache(); | 260 ToLayoutSVGResourceContainer(current)->RemoveAllClientsFromCache(); |
| 258 break; | 261 break; |
| 259 } | 262 } |
| 260 | 263 |
| 261 current = current->Parent(); | 264 current = current->Parent(); |
| 262 } | 265 } |
| 263 } | 266 } |
| 264 | 267 |
| 265 } // namespace blink | 268 } // namespace blink |
| OLD | NEW |