Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(529)

Unified Diff: third_party/WebKit/Source/core/svg/SVGTreeScopeResources.cpp

Issue 2107153002: SVG object with same idrefs get conflicted even they are under different shadow root Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rename the method in TreeScope class Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/svg/SVGTreeScopeResources.cpp
diff --git a/third_party/WebKit/Source/core/svg/SVGTreeScopeResources.cpp b/third_party/WebKit/Source/core/svg/SVGTreeScopeResources.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..64ff103328242e0dca02052e5e4783e9bcd6d585
--- /dev/null
+++ b/third_party/WebKit/Source/core/svg/SVGTreeScopeResources.cpp
@@ -0,0 +1,194 @@
+#include "core/svg/SVGTreeScopeResources.h"
+
+#include "core/dom/Element.h"
+#include "core/dom/TreeScope.h"
+#include "wtf/text/AtomicString.h"
+
+namespace blink {
+
+SVGTreeScopeResources::SVGTreeScopeResources(TreeScope* treeScope)
+ : m_treeScope(treeScope)
+{
+ // Whenever an object of SVGTreeScopeResources is created, to keep the code behave as before,
+ // the document should also have an instance of SVGDocumentExtensions created.
+ // Thus below lines are added
+ if (!treeScope->document().svgExtensions())
+ treeScope->document().accessSVGExtensions();
+}
+SVGTreeScopeResources::~SVGTreeScopeResources()
+{
+}
+void SVGTreeScopeResources::addResource(const AtomicString& id, LayoutSVGResourceContainer* resource)
+{
+ DCHECK(resource);
+
+ if (id.isEmpty())
+ return;
+ // Replaces resource if already present, to handle potential id changes
+ m_resources.set(id, resource);
+}
+
+void SVGTreeScopeResources::removeResource(const AtomicString& id)
+{
+ if (id.isEmpty())
+ return;
+
+ m_resources.remove(id);
+}
+
+LayoutSVGResourceContainer* SVGTreeScopeResources::resourceById(const AtomicString& id) const
+{
+ if (id.isEmpty())
+ return nullptr;
+ return m_resources.get(id);
+}
+void SVGTreeScopeResources::addPendingResource(const AtomicString& id, blink::Element* element)
+{
+ DCHECK(element);
+ DCHECK(element->inShadowIncludingDocument());
+
+ if (id.isEmpty())
+ return;
+
+ HeapHashMap<AtomicString, Member<SVGPendingElements>>::AddResult result = m_pendingResources.add(id, nullptr);
+ if (result.isNewEntry)
+ result.storedValue->value = new SVGPendingElements;
+ result.storedValue->value->add(element);
+
+ element->setHasPendingResources();
+}
+
+bool SVGTreeScopeResources::hasPendingResource(const AtomicString& id) const
+{
+ if (id.isEmpty())
+ return false;
+
+ return m_pendingResources.contains(id);
+}
+
+bool SVGTreeScopeResources::isElementPendingResources(Element* element) const
+{
+ // This algorithm takes time proportional to the number of pending resources and need not.
+ // If performance becomes an issue we can keep a counted set of elements and answer the question efficiently.
+
+ DCHECK(element);
+
+ for (const auto& entry : m_pendingResources) {
+ SVGPendingElements* elements = entry.value.get();
+ DCHECK(elements);
+
+ if (elements->contains(element))
+ return true;
+ }
+ return false;
+}
+
+bool SVGTreeScopeResources::isElementPendingResource(Element* element, const AtomicString& id) const
+{
+ DCHECK(element);
+
+ if (!hasPendingResource(id))
+ return false;
+
+ return m_pendingResources.get(id)->contains(element);
+}
+
+void SVGTreeScopeResources::clearHasPendingResourcesIfPossible(Element* element)
+{
+ if (!isElementPendingResources(element))
+ element->clearHasPendingResources();
+}
+
+void SVGTreeScopeResources::removeElementFromPendingResources(Element* element)
+{
+ DCHECK(element);
+
+ // Remove the element from pending resources.
+ if (!m_pendingResources.isEmpty() && element->hasPendingResources()) {
+ Vector<AtomicString> toBeRemoved;
+ for (const auto& entry : m_pendingResources) {
+ SVGPendingElements* elements = entry.value.get();
+ DCHECK(elements);
+ DCHECK(!elements->isEmpty());
+
+ elements->remove(element);
+ if (elements->isEmpty())
+ toBeRemoved.append(entry.key);
+ }
+
+ clearHasPendingResourcesIfPossible(element);
+
+ // We use the removePendingResource function here because it deals with set lifetime correctly.
+ for (const AtomicString& id : toBeRemoved)
+ removePendingResource(id);
+ }
+
+ // Remove the element from pending resources that were scheduled for removal.
+ if (!m_pendingResourcesForRemoval.isEmpty()) {
+ Vector<AtomicString> toBeRemoved;
+ for (const auto& entry : m_pendingResourcesForRemoval) {
+ SVGPendingElements* elements = entry.value.get();
+ DCHECK(elements);
+ DCHECK(!elements->isEmpty());
+
+ elements->remove(element);
+ if (elements->isEmpty())
+ toBeRemoved.append(entry.key);
+ }
+
+ // We use the removePendingResourceForRemoval function here because it deals with set lifetime correctly.
+ for (const AtomicString& id : toBeRemoved)
+ removePendingResourceForRemoval(id);
+ }
+}
+
+SVGTreeScopeResources::SVGPendingElements* SVGTreeScopeResources::removePendingResource(const AtomicString& id)
+{
+ DCHECK(m_pendingResources.contains(id));
+ return m_pendingResources.take(id);
+}
+
+SVGTreeScopeResources::SVGPendingElements* SVGTreeScopeResources::removePendingResourceForRemoval(const AtomicString& id)
+{
+ DCHECK(m_pendingResourcesForRemoval.contains(id));
+ return m_pendingResourcesForRemoval.take(id);
+}
+
+void SVGTreeScopeResources::markPendingResourcesForRemoval(const AtomicString& id)
+{
+ if (id.isEmpty())
+ return;
+
+ DCHECK(!m_pendingResourcesForRemoval.contains(id));
+
+ Member<SVGPendingElements> existing = m_pendingResources.take(id);
+ if (existing && !existing->isEmpty())
+ m_pendingResourcesForRemoval.add(id, existing.release());
+}
+
+Element* SVGTreeScopeResources::removeElementFromPendingResourcesForRemoval(const AtomicString& id)
+{
+ if (id.isEmpty())
+ return nullptr;
+
+ SVGPendingElements* resourceSet = m_pendingResourcesForRemoval.get(id);
+ if (!resourceSet || resourceSet->isEmpty())
+ return nullptr;
+
+ SVGPendingElements::iterator firstElement = resourceSet->begin();
+ Element* element = *firstElement;
+
+ resourceSet->remove(firstElement);
+
+ if (resourceSet->isEmpty())
+ removePendingResourceForRemoval(id);
+
+ return element;
+}
+DEFINE_TRACE(SVGTreeScopeResources)
+{
+ visitor->trace(m_treeScope);
+ visitor->trace(m_pendingResources);
+ visitor->trace(m_pendingResourcesForRemoval);
+}
+}
« no previous file with comments | « third_party/WebKit/Source/core/svg/SVGTreeScopeResources.h ('k') | third_party/WebKit/Source/core/svg/SVGUseElement.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698