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

Side by Side 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: 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 unified diff | Download patch
OLDNEW
(Empty)
1 #include "core/svg/SVGTreeScopeResources.h"
2
3 #include "core/dom/Element.h"
4 #include "core/dom/TreeScope.h"
5 #include "wtf/text/AtomicString.h"
6
7 namespace blink {
8
9 SVGTreeScopeResources::SVGTreeScopeResources(TreeScope* treeScope)
10 : m_treeScope(treeScope)
11 {
12 }
13 SVGTreeScopeResources::~SVGTreeScopeResources()
14 {
15 }
16 void SVGTreeScopeResources::addResource(const AtomicString& id, LayoutSVGResourc eContainer* resource)
17 {
18 DCHECK(resource);
19
20 if (id.isEmpty())
21 return;
22 // Replaces resource if already present, to handle potential id changes
23 m_resources.set(id, resource);
24 }
25
26 void SVGTreeScopeResources::removeResource(const AtomicString& id)
27 {
28 if (id.isEmpty())
29 return;
30
31 m_resources.remove(id);
32 }
33
34 LayoutSVGResourceContainer* SVGTreeScopeResources::resourceById(const AtomicStri ng& id) const
35 {
36 if (id.isEmpty())
37 return nullptr;
38 return m_resources.get(id);
39 }
40 void SVGTreeScopeResources::addPendingResource(const AtomicString& id, blink::El ement* element)
41 {
42 DCHECK(element);
43 DCHECK(element->inShadowIncludingDocument());
44
45 if (id.isEmpty())
46 return;
47
48 HeapHashMap<AtomicString, Member<SVGPendingElements>>::AddResult result = m_ pendingResources.add(id, nullptr);
49 if (result.isNewEntry)
50 result.storedValue->value = new SVGPendingElements;
51 result.storedValue->value->add(element);
52
53 element->setHasPendingResources();
54 }
55
56 bool SVGTreeScopeResources::hasPendingResource(const AtomicString& id) const
57 {
58 if (id.isEmpty())
59 return false;
60
61 return m_pendingResources.contains(id);
62 }
63
64 bool SVGTreeScopeResources::isElementPendingResources(Element* element) const
65 {
66 // This algorithm takes time proportional to the number of pending resources and need not.
67 // If performance becomes an issue we can keep a counted set of elements and answer the question efficiently.
68
69 DCHECK(element);
70
71 for (const auto& entry : m_pendingResources) {
72 SVGPendingElements* elements = entry.value.get();
73 DCHECK(elements);
74
75 if (elements->contains(element))
76 return true;
77 }
78 return false;
79 }
80
81 bool SVGTreeScopeResources::isElementPendingResource(Element* element, const Ato micString& id) const
82 {
83 DCHECK(element);
84
85 if (!hasPendingResource(id))
86 return false;
87
88 return m_pendingResources.get(id)->contains(element);
89 }
90
91 void SVGTreeScopeResources::clearHasPendingResourcesIfPossible(Element* element)
92 {
93 if (!isElementPendingResources(element))
94 element->clearHasPendingResources();
95 }
96
97 void SVGTreeScopeResources::removeElementFromPendingResources(Element* element)
98 {
99 DCHECK(element);
100
101 // Remove the element from pending resources.
102 if (!m_pendingResources.isEmpty() && element->hasPendingResources()) {
103 Vector<AtomicString> toBeRemoved;
104 for (const auto& entry : m_pendingResources) {
105 SVGPendingElements* elements = entry.value.get();
106 DCHECK(elements);
107 DCHECK(!elements->isEmpty());
108
109 elements->remove(element);
110 if (elements->isEmpty())
111 toBeRemoved.append(entry.key);
112 }
113
114 clearHasPendingResourcesIfPossible(element);
115
116 // We use the removePendingResource function here because it deals with set lifetime correctly.
117 for (const AtomicString& id : toBeRemoved)
118 removePendingResource(id);
119 }
120
121 // Remove the element from pending resources that were scheduled for removal .
122 if (!m_pendingResourcesForRemoval.isEmpty()) {
123 Vector<AtomicString> toBeRemoved;
124 for (const auto& entry : m_pendingResourcesForRemoval) {
125 SVGPendingElements* elements = entry.value.get();
126 DCHECK(elements);
127 DCHECK(!elements->isEmpty());
128
129 elements->remove(element);
130 if (elements->isEmpty())
131 toBeRemoved.append(entry.key);
132 }
133
134 // We use the removePendingResourceForRemoval function here because it d eals with set lifetime correctly.
135 for (const AtomicString& id : toBeRemoved)
136 removePendingResourceForRemoval(id);
137 }
138 }
139
140 SVGTreeScopeResources::SVGPendingElements* SVGTreeScopeResources::removePendingR esource(const AtomicString& id)
141 {
142 DCHECK(m_pendingResources.contains(id));
143 return m_pendingResources.take(id);
144 }
145
146 SVGTreeScopeResources::SVGPendingElements* SVGTreeScopeResources::removePendingR esourceForRemoval(const AtomicString& id)
147 {
148 DCHECK(m_pendingResourcesForRemoval.contains(id));
149 return m_pendingResourcesForRemoval.take(id);
150 }
151
152 void SVGTreeScopeResources::markPendingResourcesForRemoval(const AtomicString& i d)
153 {
154 if (id.isEmpty())
155 return;
156
157 DCHECK(!m_pendingResourcesForRemoval.contains(id));
158
159 Member<SVGPendingElements> existing = m_pendingResources.take(id);
160 if (existing && !existing->isEmpty())
161 m_pendingResourcesForRemoval.add(id, existing.release());
162 }
163
164 Element* SVGTreeScopeResources::removeElementFromPendingResourcesForRemoval(cons t AtomicString& id)
165 {
166 if (id.isEmpty())
167 return nullptr;
168
169 SVGPendingElements* resourceSet = m_pendingResourcesForRemoval.get(id);
170 if (!resourceSet || resourceSet->isEmpty())
171 return nullptr;
172
173 SVGPendingElements::iterator firstElement = resourceSet->begin();
174 Element* element = *firstElement;
175
176 resourceSet->remove(firstElement);
177
178 if (resourceSet->isEmpty())
179 removePendingResourceForRemoval(id);
180
181 return element;
182 }
183 DEFINE_TRACE(SVGTreeScopeResources)
184 {
185 visitor->trace(m_treeScope);
186 visitor->trace(m_pendingResources);
187 visitor->trace(m_pendingResourcesForRemoval);
188 }
189 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698