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

Side by Side Diff: third_party/WebKit/Source/core/svg/animation/SVGSMILElement.cpp

Issue 2737403003: Use IdTargetObserver in SVGSMILElement (Closed)
Patch Set: Rebase; always attempt to unobserve Created 3 years, 9 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
« no previous file with comments | « third_party/WebKit/Source/core/svg/animation/SVGSMILElement.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2008 Apple Inc. All rights reserved. 2 * Copyright (C) 2008 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * 12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */ 24 */
25 25
26 #include "core/svg/animation/SVGSMILElement.h" 26 #include "core/svg/animation/SVGSMILElement.h"
27 27
28 #include <algorithm>
28 #include "bindings/core/v8/ScriptEventListener.h" 29 #include "bindings/core/v8/ScriptEventListener.h"
29 #include "core/XLinkNames.h" 30 #include "core/XLinkNames.h"
30 #include "core/dom/Document.h" 31 #include "core/dom/Document.h"
32 #include "core/dom/IdTargetObserver.h"
31 #include "core/dom/TaskRunnerHelper.h" 33 #include "core/dom/TaskRunnerHelper.h"
32 #include "core/events/Event.h" 34 #include "core/events/Event.h"
33 #include "core/events/EventListener.h" 35 #include "core/events/EventListener.h"
34 #include "core/svg/SVGSVGElement.h" 36 #include "core/svg/SVGSVGElement.h"
35 #include "core/svg/SVGTreeScopeResources.h"
36 #include "core/svg/SVGURIReference.h" 37 #include "core/svg/SVGURIReference.h"
37 #include "core/svg/animation/SMILTimeContainer.h" 38 #include "core/svg/animation/SMILTimeContainer.h"
38 #include "platform/heap/Handle.h" 39 #include "platform/heap/Handle.h"
39 #include "wtf/MathExtras.h" 40 #include "wtf/MathExtras.h"
40 #include "wtf/StdLibExtras.h" 41 #include "wtf/StdLibExtras.h"
41 #include "wtf/Vector.h" 42 #include "wtf/Vector.h"
42 #include <algorithm>
43 43
44 namespace blink { 44 namespace blink {
45 45
46 class RepeatEvent final : public Event { 46 class RepeatEvent final : public Event {
47 public: 47 public:
48 static RepeatEvent* create(const AtomicString& type, int repeat) { 48 static RepeatEvent* create(const AtomicString& type, int repeat) {
49 return new RepeatEvent(type, false, false, repeat); 49 return new RepeatEvent(type, false, false, repeat);
50 } 50 }
51 51
52 ~RepeatEvent() override {} 52 ~RepeatEvent() override {}
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 m_beginOrEnd(beginOrEnd), 138 m_beginOrEnd(beginOrEnd),
139 m_baseID(baseID), 139 m_baseID(baseID),
140 m_name(name), 140 m_name(name),
141 m_offset(offset), 141 m_offset(offset),
142 m_repeat(repeat) {} 142 m_repeat(repeat) {}
143 143
144 SVGSMILElement::Condition::~Condition() = default; 144 SVGSMILElement::Condition::~Condition() = default;
145 145
146 DEFINE_TRACE(SVGSMILElement::Condition) { 146 DEFINE_TRACE(SVGSMILElement::Condition) {
147 visitor->trace(m_baseElement); 147 visitor->trace(m_baseElement);
148 visitor->trace(m_baseIdObserver);
148 visitor->trace(m_eventListener); 149 visitor->trace(m_eventListener);
149 } 150 }
150 151
151 void SVGSMILElement::Condition::connectSyncBase(SVGSMILElement& timedElement) { 152 void SVGSMILElement::Condition::connectSyncBase(SVGSMILElement& timedElement) {
152 DCHECK(!m_baseID.isEmpty()); 153 DCHECK(!m_baseID.isEmpty());
153 DCHECK_EQ(m_type, Syncbase); 154 DCHECK_EQ(m_type, Syncbase);
154 Element* element = timedElement.treeScope().getElementById(m_baseID); 155 Element* element = timedElement.treeScope().getElementById(m_baseID);
155 if (!element || !isSVGSMILElement(*element)) { 156 if (!element || !isSVGSMILElement(*element)) {
156 m_baseElement = nullptr; 157 m_baseElement = nullptr;
157 return; 158 return;
158 } 159 }
159 m_baseElement = toSVGSMILElement(element); 160 m_baseElement = toSVGSMILElement(element);
160 toSVGSMILElement(*element).addSyncBaseDependent(timedElement); 161 toSVGSMILElement(*element).addSyncBaseDependent(timedElement);
161 } 162 }
162 163
163 void SVGSMILElement::Condition::disconnectSyncBase( 164 void SVGSMILElement::Condition::disconnectSyncBase(
164 SVGSMILElement& timedElement) { 165 SVGSMILElement& timedElement) {
165 DCHECK_EQ(m_type, Syncbase); 166 DCHECK_EQ(m_type, Syncbase);
166 if (!m_baseElement) 167 if (!m_baseElement)
167 return; 168 return;
168 toSVGSMILElement(*m_baseElement).removeSyncBaseDependent(timedElement); 169 toSVGSMILElement(*m_baseElement).removeSyncBaseDependent(timedElement);
169 m_baseElement = nullptr; 170 m_baseElement = nullptr;
170 } 171 }
171 172
172 SVGElement* SVGSMILElement::Condition::lookupEventBase(
173 SVGSMILElement& timedElement) const {
174 Element* eventBase = m_baseID.isEmpty()
175 ? timedElement.targetElement()
176 : timedElement.treeScope().getElementById(m_baseID);
177 if (!eventBase || !eventBase->isSVGElement())
178 return nullptr;
179 return toSVGElement(eventBase);
180 }
181
182 void SVGSMILElement::Condition::connectEventBase(SVGSMILElement& timedElement) { 173 void SVGSMILElement::Condition::connectEventBase(SVGSMILElement& timedElement) {
183 DCHECK_EQ(m_type, EventBase); 174 DCHECK_EQ(m_type, EventBase);
184 DCHECK(!m_baseElement); 175 DCHECK(!m_baseElement);
185 SVGElement* eventBase = lookupEventBase(timedElement); 176 Element* target;
186 if (!eventBase) { 177 if (m_baseID.isEmpty()) {
187 if (m_baseID.isEmpty()) 178 target = timedElement.targetElement();
188 return; 179 } else {
189 SVGTreeScopeResources& treeScopeResources = 180 target = SVGURIReference::observeTarget(
190 timedElement.treeScope().ensureSVGTreeScopedResources(); 181 m_baseIdObserver, timedElement.treeScope(), m_baseID,
191 if (!treeScopeResources.isElementPendingResource(timedElement, m_baseID)) 182 WTF::bind(&SVGSMILElement::buildPendingResource,
192 treeScopeResources.addPendingResource(m_baseID, timedElement); 183 wrapWeakPersistent(&timedElement)));
184 }
185 if (!target || !target->isSVGElement())
193 return; 186 return;
194 }
195 DCHECK(!m_eventListener); 187 DCHECK(!m_eventListener);
196 m_eventListener = ConditionEventListener::create(&timedElement, this); 188 m_eventListener = ConditionEventListener::create(&timedElement, this);
197 m_baseElement = eventBase; 189 m_baseElement = toSVGElement(target);
198 m_baseElement->addEventListener(m_name, m_eventListener, false); 190 m_baseElement->addEventListener(m_name, m_eventListener, false);
199 timedElement.addReferenceTo(m_baseElement); 191 timedElement.addReferenceTo(m_baseElement);
200 } 192 }
201 193
202 void SVGSMILElement::Condition::disconnectEventBase( 194 void SVGSMILElement::Condition::disconnectEventBase(
203 SVGSMILElement& timedElement) { 195 SVGSMILElement& timedElement) {
204 DCHECK_EQ(m_type, EventBase); 196 DCHECK_EQ(m_type, EventBase);
197 SVGURIReference::unobserveTarget(m_baseIdObserver);
205 if (!m_eventListener) 198 if (!m_eventListener)
206 return; 199 return;
207 m_baseElement->removeEventListener(m_name, m_eventListener, false); 200 m_baseElement->removeEventListener(m_name, m_eventListener, false);
208 m_baseElement = nullptr; 201 m_baseElement = nullptr;
209 m_eventListener->disconnectAnimation(); 202 m_eventListener->disconnectAnimation();
210 m_eventListener = nullptr; 203 m_eventListener = nullptr;
211 } 204 }
212 205
213 SVGSMILElement::SVGSMILElement(const QualifiedName& tagName, Document& doc) 206 SVGSMILElement::SVGSMILElement(const QualifiedName& tagName, Document& doc)
214 : SVGElement(tagName, doc), 207 : SVGElement(tagName, doc),
(...skipping 15 matching lines...) Expand all
230 m_cachedRepeatDur(invalidCachedTime), 223 m_cachedRepeatDur(invalidCachedTime),
231 m_cachedRepeatCount(invalidCachedTime), 224 m_cachedRepeatCount(invalidCachedTime),
232 m_cachedMin(invalidCachedTime), 225 m_cachedMin(invalidCachedTime),
233 m_cachedMax(invalidCachedTime) { 226 m_cachedMax(invalidCachedTime) {
234 resolveFirstInterval(); 227 resolveFirstInterval();
235 } 228 }
236 229
237 SVGSMILElement::~SVGSMILElement() {} 230 SVGSMILElement::~SVGSMILElement() {}
238 231
239 void SVGSMILElement::clearResourceAndEventBaseReferences() { 232 void SVGSMILElement::clearResourceAndEventBaseReferences() {
233 SVGURIReference::unobserveTarget(m_targetIdObserver);
240 removeAllOutgoingReferences(); 234 removeAllOutgoingReferences();
241 } 235 }
242 236
243 void SVGSMILElement::clearConditions() { 237 void SVGSMILElement::clearConditions() {
244 disconnectSyncBaseConditions(); 238 disconnectSyncBaseConditions();
245 disconnectEventBaseConditions(); 239 disconnectEventBaseConditions();
246 m_conditions.clear(); 240 m_conditions.clear();
247 } 241 }
248 242
249 void SVGSMILElement::buildPendingResource() { 243 void SVGSMILElement::buildPendingResource() {
250 clearResourceAndEventBaseReferences(); 244 clearResourceAndEventBaseReferences();
245 disconnectEventBaseConditions();
251 246
252 if (!isConnected()) { 247 if (!isConnected()) {
253 // Reset the target element if we are no longer in the document. 248 // Reset the target element if we are no longer in the document.
254 setTargetElement(nullptr); 249 setTargetElement(nullptr);
255 return; 250 return;
256 } 251 }
257 252
258 AtomicString id;
259 const AtomicString& href = SVGURIReference::legacyHrefString(*this); 253 const AtomicString& href = SVGURIReference::legacyHrefString(*this);
260 Element* target; 254 Element* target;
261 if (href.isEmpty()) 255 if (href.isEmpty()) {
262 target = parentNode() && parentNode()->isElementNode() 256 target = parentElement();
263 ? toElement(parentNode()) 257 } else {
264 : nullptr; 258 target = SVGURIReference::observeTarget(m_targetIdObserver, *this, href);
265 else 259 }
266 target =
267 SVGURIReference::targetElementFromIRIString(href, treeScope(), &id);
268 SVGElement* svgTarget = 260 SVGElement* svgTarget =
269 target && target->isSVGElement() ? toSVGElement(target) : nullptr; 261 target && target->isSVGElement() ? toSVGElement(target) : nullptr;
270 262
271 if (svgTarget && !svgTarget->isConnected()) 263 if (svgTarget && !svgTarget->isConnected())
272 svgTarget = nullptr; 264 svgTarget = nullptr;
273 265
274 if (svgTarget != targetElement()) 266 if (svgTarget != targetElement())
275 setTargetElement(svgTarget); 267 setTargetElement(svgTarget);
276 268
277 if (!svgTarget) { 269 if (svgTarget) {
278 // Do not register as pending if we are already pending this resource.
279 if (treeScope().ensureSVGTreeScopedResources().isElementPendingResource(
280 *this, id))
281 return;
282 if (!id.isEmpty()) {
283 treeScope().ensureSVGTreeScopedResources().addPendingResource(id, *this);
284 DCHECK(hasPendingResources());
285 }
286 } else {
287 // Register us with the target in the dependencies map. Any change of 270 // Register us with the target in the dependencies map. Any change of
288 // hrefElement that leads to relayout/repainting now informs us, so we can 271 // hrefElement that leads to relayout/repainting now informs us, so we can
289 // react to it. 272 // react to it.
290 addReferenceTo(svgTarget); 273 addReferenceTo(svgTarget);
291 } 274 }
292 connectEventBaseConditions(); 275 connectEventBaseConditions();
293 } 276 }
294 277
295 static inline void clearTimesWithDynamicOrigins( 278 static inline void clearTimesWithDynamicOrigins(
296 Vector<SMILTimeWithOrigin>& timeList) { 279 Vector<SMILTimeWithOrigin>& timeList) {
(...skipping 985 matching lines...) Expand 10 before | Expand all | Expand 10 after
1282 return; 1265 return;
1283 1266
1284 DCHECK(m_timeContainer); 1267 DCHECK(m_timeContainer);
1285 DCHECK(m_targetElement); 1268 DCHECK(m_targetElement);
1286 m_timeContainer->unschedule(this, m_targetElement, m_attributeName); 1269 m_timeContainer->unschedule(this, m_targetElement, m_attributeName);
1287 m_isScheduled = false; 1270 m_isScheduled = false;
1288 } 1271 }
1289 1272
1290 DEFINE_TRACE(SVGSMILElement) { 1273 DEFINE_TRACE(SVGSMILElement) {
1291 visitor->trace(m_targetElement); 1274 visitor->trace(m_targetElement);
1275 visitor->trace(m_targetIdObserver);
1292 visitor->trace(m_timeContainer); 1276 visitor->trace(m_timeContainer);
1293 visitor->trace(m_conditions); 1277 visitor->trace(m_conditions);
1294 visitor->trace(m_syncBaseDependents); 1278 visitor->trace(m_syncBaseDependents);
1295 SVGElement::trace(visitor); 1279 SVGElement::trace(visitor);
1296 SVGTests::trace(visitor); 1280 SVGTests::trace(visitor);
1297 } 1281 }
1298 1282
1299 } // namespace blink 1283 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/svg/animation/SVGSMILElement.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698