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

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

Issue 2384013002: Push animation value 'inherit' handling into SVGAnimateElement (Closed)
Patch Set: Created 4 years, 2 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
1 /* 1 /*
2 * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> 2 * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org>
3 * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org> 3 * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org>
4 * Copyright (C) 2008 Apple Inc. All rights reserved. 4 * Copyright (C) 2008 Apple Inc. All rights reserved.
5 * Copyright (C) Research In Motion Limited 2011. All rights reserved. 5 * Copyright (C) Research In Motion Limited 2011. All rights reserved.
6 * 6 *
7 * This library is free software; you can redistribute it and/or 7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public 8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
11 * 11 *
12 * This library is distributed in the hope that it will be useful, 12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details. 15 * Library General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU Library General Public License 17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to 18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA. 20 * Boston, MA 02110-1301, USA.
21 */ 21 */
22 22
23 #include "core/svg/SVGAnimateElement.h" 23 #include "core/svg/SVGAnimateElement.h"
24 24
25 #include "core/CSSPropertyNames.h" 25 #include "core/CSSPropertyNames.h"
26 #include "core/css/CSSComputedStyleDeclaration.h"
26 #include "core/css/StylePropertySet.h" 27 #include "core/css/StylePropertySet.h"
27 #include "core/dom/Document.h" 28 #include "core/dom/Document.h"
28 #include "core/dom/QualifiedName.h" 29 #include "core/dom/QualifiedName.h"
29 #include "core/dom/StyleChangeReason.h" 30 #include "core/dom/StyleChangeReason.h"
30 #include "core/svg/SVGAnimatedTypeAnimator.h"
31 #include "core/svg/properties/SVGProperty.h" 31 #include "core/svg/properties/SVGProperty.h"
32 32
33 namespace blink { 33 namespace blink {
34 34
35 namespace {
36
37 String computeCSSPropertyValue(SVGElement* element, CSSPropertyID id) {
38 DCHECK(element);
39 // TODO(fs): StyleEngine doesn't support document without a frame.
40 // Refer to comment in Element::computedStyle.
41 DCHECK(element->inActiveDocument());
42
43 // Don't include any properties resulting from CSS Transitions/Animations or
44 // SMIL animations, as we want to retrieve the "base value".
45 element->setUseOverrideComputedStyle(true);
46 String value =
47 CSSComputedStyleDeclaration::create(element)->getPropertyValue(id);
48 element->setUseOverrideComputedStyle(false);
49 return value;
50 }
51
52 AnimatedPropertyValueType propertyValueType(const QualifiedName& attributeName,
53 const String& value) {
54 DEFINE_STATIC_LOCAL(const AtomicString, inherit, ("inherit"));
55 if (value.isEmpty() || value != inherit ||
56 !SVGElement::isAnimatableCSSProperty(attributeName))
57 return RegularPropertyValue;
58 return InheritValue;
59 }
60
61 } // unnamed namespace
62
35 SVGAnimateElement::SVGAnimateElement(const QualifiedName& tagName, 63 SVGAnimateElement::SVGAnimateElement(const QualifiedName& tagName,
36 Document& document) 64 Document& document)
37 : SVGAnimationElement(tagName, document), m_animator(this) {} 65 : SVGAnimationElement(tagName, document),
66 m_animator(this),
67 m_fromPropertyValueType(RegularPropertyValue),
68 m_toPropertyValueType(RegularPropertyValue) {}
38 69
39 SVGAnimateElement* SVGAnimateElement::create(Document& document) { 70 SVGAnimateElement* SVGAnimateElement::create(Document& document) {
40 return new SVGAnimateElement(SVGNames::animateTag, document); 71 return new SVGAnimateElement(SVGNames::animateTag, document);
41 } 72 }
42 73
43 SVGAnimateElement::~SVGAnimateElement() {} 74 SVGAnimateElement::~SVGAnimateElement() {}
44 75
45 bool SVGAnimateElement::isSVGAnimationAttributeSettingJavaScriptURL( 76 bool SVGAnimateElement::isSVGAnimationAttributeSettingJavaScriptURL(
46 const Attribute& attribute) const { 77 const Attribute& attribute) const {
47 if ((attribute.name() == SVGNames::fromAttr || 78 if ((attribute.name() == SVGNames::fromAttr ||
(...skipping 26 matching lines...) Expand all
74 105
75 bool SVGAnimateElement::hasValidAttributeType() { 106 bool SVGAnimateElement::hasValidAttributeType() {
76 SVGElement* targetElement = this->targetElement(); 107 SVGElement* targetElement = this->targetElement();
77 if (!targetElement) 108 if (!targetElement)
78 return false; 109 return false;
79 110
80 return animatedPropertyType() != AnimatedUnknown && 111 return animatedPropertyType() != AnimatedUnknown &&
81 !hasInvalidCSSAttributeType(); 112 !hasInvalidCSSAttributeType();
82 } 113 }
83 114
84 namespace { 115 SVGPropertyBase* SVGAnimateElement::adjustForInheritance(
85 116 SVGPropertyBase* propertyValue,
86 class ParsePropertyFromString { 117 AnimatedPropertyValueType valueType) const {
87 STACK_ALLOCATED(); 118 if (valueType != InheritValue)
88 119 return propertyValue;
89 public: 120 // TODO(fs): At the moment the computed style gets returned as a String and
90 explicit ParsePropertyFromString(SVGAnimatedTypeAnimator* animator) 121 // needs to get parsed again. In the future we might want to work with the
91 : m_animator(animator) {} 122 // value type directly to avoid the String parsing.
92 123 DCHECK(targetElement());
93 SVGPropertyBase* operator()(SVGAnimationElement*, const String& value) { 124 Element* parent = targetElement()->parentElement();
94 return m_animator->createPropertyForAnimation(value); 125 if (!parent || !parent->isSVGElement())
95 } 126 return propertyValue;
96 127 SVGElement* svgParent = toSVGElement(parent);
97 private: 128 // Replace 'inherit' by its computed property value.
98 SVGAnimatedTypeAnimator* m_animator; 129 String value = computeCSSPropertyValue(
99 }; 130 svgParent, cssPropertyID(attributeName().localName()));
131 return m_animator.createPropertyForAnimation(value);
100 } 132 }
101 133
102 void SVGAnimateElement::calculateAnimatedValue(float percentage, 134 void SVGAnimateElement::calculateAnimatedValue(float percentage,
103 unsigned repeatCount, 135 unsigned repeatCount,
104 SVGSMILElement* resultElement) { 136 SVGSMILElement* resultElement) {
105 ASSERT(resultElement); 137 ASSERT(resultElement);
106 SVGElement* targetElement = this->targetElement(); 138 SVGElement* targetElement = this->targetElement();
107 if (!targetElement || !isSVGAnimateElement(*resultElement)) 139 if (!targetElement || !isSVGAnimateElement(*resultElement))
108 return; 140 return;
109 141
(...skipping 23 matching lines...) Expand all
133 // Values-animation accumulates using the last values entry corresponding to 165 // Values-animation accumulates using the last values entry corresponding to
134 // the end of duration time. 166 // the end of duration time.
135 SVGPropertyBase* animatedValue = resultAnimationElement->m_animatedProperty; 167 SVGPropertyBase* animatedValue = resultAnimationElement->m_animatedProperty;
136 SVGPropertyBase* toAtEndOfDurationValue = 168 SVGPropertyBase* toAtEndOfDurationValue =
137 m_toAtEndOfDurationProperty ? m_toAtEndOfDurationProperty : m_toProperty; 169 m_toAtEndOfDurationProperty ? m_toAtEndOfDurationProperty : m_toProperty;
138 SVGPropertyBase* fromValue = 170 SVGPropertyBase* fromValue =
139 getAnimationMode() == ToAnimation ? animatedValue : m_fromProperty.get(); 171 getAnimationMode() == ToAnimation ? animatedValue : m_fromProperty.get();
140 SVGPropertyBase* toValue = m_toProperty; 172 SVGPropertyBase* toValue = m_toProperty;
141 173
142 // Apply CSS inheritance rules. 174 // Apply CSS inheritance rules.
143 ParsePropertyFromString parsePropertyFromString(&m_animator); 175 fromValue = adjustForInheritance(fromValue, m_fromPropertyValueType);
144 adjustForInheritance<SVGPropertyBase*, ParsePropertyFromString>( 176 toValue = adjustForInheritance(toValue, m_toPropertyValueType);
145 parsePropertyFromString, fromPropertyValueType(), fromValue,
146 targetElement);
147 adjustForInheritance<SVGPropertyBase*, ParsePropertyFromString>(
148 parsePropertyFromString, toPropertyValueType(), toValue, targetElement);
149 177
150 animatedValue->calculateAnimatedValue(this, percentage, repeatCount, 178 animatedValue->calculateAnimatedValue(this, percentage, repeatCount,
151 fromValue, toValue, 179 fromValue, toValue,
152 toAtEndOfDurationValue, targetElement); 180 toAtEndOfDurationValue, targetElement);
153 } 181 }
154 182
155 bool SVGAnimateElement::calculateToAtEndOfDurationValue( 183 bool SVGAnimateElement::calculateToAtEndOfDurationValue(
156 const String& toAtEndOfDurationString) { 184 const String& toAtEndOfDurationString) {
157 if (toAtEndOfDurationString.isEmpty()) 185 if (toAtEndOfDurationString.isEmpty())
158 return false; 186 return false;
159 m_toAtEndOfDurationProperty = 187 m_toAtEndOfDurationProperty =
160 m_animator.createPropertyForAnimation(toAtEndOfDurationString); 188 m_animator.createPropertyForAnimation(toAtEndOfDurationString);
161 return true; 189 return true;
162 } 190 }
163 191
164 bool SVGAnimateElement::calculateFromAndToValues(const String& fromString, 192 bool SVGAnimateElement::calculateFromAndToValues(const String& fromString,
165 const String& toString) { 193 const String& toString) {
166 SVGElement* targetElement = this->targetElement(); 194 SVGElement* targetElement = this->targetElement();
167 if (!targetElement) 195 if (!targetElement)
168 return false; 196 return false;
169 197
170 determinePropertyValueTypes(fromString, toString);
171 m_fromProperty = m_animator.createPropertyForAnimation(fromString); 198 m_fromProperty = m_animator.createPropertyForAnimation(fromString);
199 m_fromPropertyValueType = propertyValueType(attributeName(), fromString);
172 m_toProperty = m_animator.createPropertyForAnimation(toString); 200 m_toProperty = m_animator.createPropertyForAnimation(toString);
201 m_toPropertyValueType = propertyValueType(attributeName(), toString);
173 return true; 202 return true;
174 } 203 }
175 204
176 bool SVGAnimateElement::calculateFromAndByValues(const String& fromString, 205 bool SVGAnimateElement::calculateFromAndByValues(const String& fromString,
177 const String& byString) { 206 const String& byString) {
178 SVGElement* targetElement = this->targetElement(); 207 SVGElement* targetElement = this->targetElement();
179 if (!targetElement) 208 if (!targetElement)
180 return false; 209 return false;
181 210
182 if (getAnimationMode() == ByAnimation && !isAdditive()) 211 if (getAnimationMode() == ByAnimation && !isAdditive())
183 return false; 212 return false;
184 213
185 // from-by animation may only be used with attributes that support addition (e .g. most numeric attributes). 214 // from-by animation may only be used with attributes that support addition
215 // (e.g. most numeric attributes).
186 if (getAnimationMode() == FromByAnimation && 216 if (getAnimationMode() == FromByAnimation &&
187 !animatedPropertyTypeSupportsAddition()) 217 !animatedPropertyTypeSupportsAddition())
188 return false; 218 return false;
189 219
190 ASSERT(!isSVGSetElement(*this)); 220 DCHECK(!isSVGSetElement(*this));
191 221
192 determinePropertyValueTypes(fromString, byString);
193 m_fromProperty = m_animator.createPropertyForAnimation(fromString); 222 m_fromProperty = m_animator.createPropertyForAnimation(fromString);
223 m_fromPropertyValueType = propertyValueType(attributeName(), fromString);
194 m_toProperty = m_animator.createPropertyForAnimation(byString); 224 m_toProperty = m_animator.createPropertyForAnimation(byString);
225 m_toPropertyValueType = propertyValueType(attributeName(), byString);
195 m_toProperty->add(m_fromProperty, targetElement); 226 m_toProperty->add(m_fromProperty, targetElement);
196 return true; 227 return true;
197 } 228 }
198 229
199 void SVGAnimateElement::resetAnimatedType() { 230 void SVGAnimateElement::resetAnimatedType() {
200 SVGElement* targetElement = this->targetElement(); 231 SVGElement* targetElement = this->targetElement();
201 const QualifiedName& attributeName = this->attributeName(); 232 const QualifiedName& attributeName = this->attributeName();
202 233
203 m_animator.reset(targetElement); 234 m_animator.reset(targetElement);
204 235
205 ShouldApplyAnimationType shouldApply = 236 ShouldApplyAnimationType shouldApply =
206 shouldApplyAnimation(targetElement, attributeName); 237 shouldApplyAnimation(targetElement, attributeName);
207 if (shouldApply == DontApplyAnimation) 238 if (shouldApply == DontApplyAnimation)
208 return; 239 return;
209 if (shouldApply == ApplyXMLAnimation || 240 if (shouldApply == ApplyXMLAnimation ||
210 shouldApply == ApplyXMLandCSSAnimation) { 241 shouldApply == ApplyXMLandCSSAnimation) {
211 // SVG DOM animVal animation code-path. 242 // SVG DOM animVal animation code-path.
212 m_animatedProperty = m_animator.createAnimatedValue(); 243 m_animatedProperty = m_animator.createAnimatedValue();
213 targetElement->setAnimatedAttribute(attributeName, m_animatedProperty); 244 targetElement->setAnimatedAttribute(attributeName, m_animatedProperty);
214 return; 245 return;
215 } 246 }
216 DCHECK_EQ(shouldApply, ApplyCSSAnimation); 247 DCHECK_EQ(shouldApply, ApplyCSSAnimation);
217 248
218 // CSS properties animation code-path. 249 // CSS properties animation code-path.
219 String baseValue;
220 DCHECK(isTargetAttributeCSSProperty(targetElement, attributeName)); 250 DCHECK(isTargetAttributeCSSProperty(targetElement, attributeName));
221 computeCSSPropertyValue(targetElement, 251 String baseValue = computeCSSPropertyValue(
222 cssPropertyID(attributeName.localName()), baseValue); 252 targetElement, cssPropertyID(attributeName.localName()));
223
224 m_animatedProperty = m_animator.createPropertyForAnimation(baseValue); 253 m_animatedProperty = m_animator.createPropertyForAnimation(baseValue);
225 } 254 }
226 255
227 void SVGAnimateElement::clearAnimatedType() { 256 void SVGAnimateElement::clearAnimatedType() {
228 if (!m_animatedProperty) 257 if (!m_animatedProperty)
229 return; 258 return;
230 259
231 // The animated property lock is held for the "result animation" (see SMILTime Container::updateAnimations()) 260 // The animated property lock is held for the "result animation" (see
232 // while we're processing an animation group. We will very likely crash later if we clear the animated type 261 // SMILTimeContainer::updateAnimations()) while we're processing an animation
233 // while the lock is held. See crbug.com/581546. 262 // group. We will very likely crash later if we clear the animated type while
263 // the lock is held. See crbug.com/581546.
234 DCHECK(!animatedTypeIsLocked()); 264 DCHECK(!animatedTypeIsLocked());
235 265
236 SVGElement* targetElement = this->targetElement(); 266 SVGElement* targetElement = this->targetElement();
237 if (!targetElement) { 267 if (!targetElement) {
238 m_animatedProperty.clear(); 268 m_animatedProperty.clear();
239 return; 269 return;
240 } 270 }
241 271
242 ShouldApplyAnimationType shouldApply = 272 ShouldApplyAnimationType shouldApply =
243 shouldApplyAnimation(targetElement, attributeName()); 273 shouldApplyAnimation(targetElement, attributeName());
(...skipping 18 matching lines...) Expand all
262 292
263 m_animatedProperty.clear(); 293 m_animatedProperty.clear();
264 m_animator.clear(); 294 m_animator.clear();
265 } 295 }
266 296
267 void SVGAnimateElement::applyResultsToTarget() { 297 void SVGAnimateElement::applyResultsToTarget() {
268 ASSERT(animatedPropertyType() != AnimatedTransformList || 298 ASSERT(animatedPropertyType() != AnimatedTransformList ||
269 isSVGAnimateTransformElement(*this)); 299 isSVGAnimateTransformElement(*this));
270 ASSERT(animatedPropertyType() != AnimatedUnknown); 300 ASSERT(animatedPropertyType() != AnimatedUnknown);
271 301
272 // Early exit if our animated type got destructed by a previous endedActiveInt erval(). 302 // Early exit if our animated type got destructed by a previous
303 // endedActiveInterval().
273 if (!m_animatedProperty) 304 if (!m_animatedProperty)
274 return; 305 return;
275 306
276 // We do update the style and the animation property independent of each other . 307 // We do update the style and the animation property independent of each
308 // other.
277 ShouldApplyAnimationType shouldApply = 309 ShouldApplyAnimationType shouldApply =
278 shouldApplyAnimation(targetElement(), attributeName()); 310 shouldApplyAnimation(targetElement(), attributeName());
279 if (shouldApply == DontApplyAnimation) 311 if (shouldApply == DontApplyAnimation)
280 return; 312 return;
281 if (shouldApply == ApplyXMLandCSSAnimation || 313 if (shouldApply == ApplyXMLandCSSAnimation ||
282 m_animator.isAnimatingCSSProperty()) { 314 m_animator.isAnimatingCSSProperty()) {
283 // CSS properties animation code-path. 315 // CSS properties animation code-path.
284 // Convert the result of the animation to a String and apply it as CSS prope rty on the target. 316 // Convert the result of the animation to a String and apply it as CSS
317 // property on the target.
285 CSSPropertyID id = cssPropertyID(attributeName().localName()); 318 CSSPropertyID id = cssPropertyID(attributeName().localName());
286 MutableStylePropertySet* propertySet = 319 MutableStylePropertySet* propertySet =
287 targetElement()->ensureAnimatedSMILStyleProperties(); 320 targetElement()->ensureAnimatedSMILStyleProperties();
288 if (propertySet->setProperty(id, m_animatedProperty->valueAsString(), false, 321 if (propertySet->setProperty(id, m_animatedProperty->valueAsString(), false,
289 0)) 322 0))
290 targetElement()->setNeedsStyleRecalc( 323 targetElement()->setNeedsStyleRecalc(
291 LocalStyleChange, 324 LocalStyleChange,
292 StyleChangeReasonForTracing::create(StyleChangeReason::Animation)); 325 StyleChangeReasonForTracing::create(StyleChangeReason::Animation));
293 } 326 }
294 if (shouldApply == ApplyXMLandCSSAnimation || 327 if (shouldApply == ApplyXMLandCSSAnimation ||
295 m_animator.isAnimatingSVGDom()) { 328 m_animator.isAnimatingSVGDom()) {
296 // SVG DOM animVal animation code-path. 329 // SVG DOM animVal animation code-path.
297 // At this point the SVG DOM values are already changed, unlike for CSS. 330 // At this point the SVG DOM values are already changed, unlike for CSS.
298 // We only have to trigger update notifications here. 331 // We only have to trigger update notifications here.
299 targetElement()->invalidateAnimatedAttribute(attributeName()); 332 targetElement()->invalidateAnimatedAttribute(attributeName());
300 } 333 }
301 } 334 }
302 335
303 bool SVGAnimateElement::animatedPropertyTypeSupportsAddition() { 336 bool SVGAnimateElement::animatedPropertyTypeSupportsAddition() {
304 // Spec: http://www.w3.org/TR/SVG/animate.html#AnimationAttributesAndPropertie s. 337 // http://www.w3.org/TR/SVG/animate.html#AnimationAttributesAndProperties.
305 switch (animatedPropertyType()) { 338 switch (animatedPropertyType()) {
306 case AnimatedBoolean: 339 case AnimatedBoolean:
307 case AnimatedEnumeration: 340 case AnimatedEnumeration:
308 case AnimatedPreserveAspectRatio: 341 case AnimatedPreserveAspectRatio:
309 case AnimatedString: 342 case AnimatedString:
310 case AnimatedUnknown: 343 case AnimatedUnknown:
311 return false; 344 return false;
312 default: 345 default:
313 return true; 346 return true;
314 } 347 }
315 } 348 }
316 349
317 bool SVGAnimateElement::isAdditive() { 350 bool SVGAnimateElement::isAdditive() {
318 if (getAnimationMode() == ByAnimation || 351 if (getAnimationMode() == ByAnimation ||
319 getAnimationMode() == FromByAnimation) { 352 getAnimationMode() == FromByAnimation) {
320 if (!animatedPropertyTypeSupportsAddition()) 353 if (!animatedPropertyTypeSupportsAddition())
321 return false; 354 return false;
322 } 355 }
323 356
324 return SVGAnimationElement::isAdditive(); 357 return SVGAnimationElement::isAdditive();
325 } 358 }
326 359
327 float SVGAnimateElement::calculateDistance(const String& fromString, 360 float SVGAnimateElement::calculateDistance(const String& fromString,
328 const String& toString) { 361 const String& toString) {
329 // FIXME: A return value of float is not enough to support paced animations on lists. 362 // FIXME: A return value of float is not enough to support paced animations on
363 // lists.
330 SVGElement* targetElement = this->targetElement(); 364 SVGElement* targetElement = this->targetElement();
331 if (!targetElement) 365 if (!targetElement)
332 return -1; 366 return -1;
333 SVGPropertyBase* fromValue = 367 SVGPropertyBase* fromValue =
334 m_animator.createPropertyForAnimation(fromString); 368 m_animator.createPropertyForAnimation(fromString);
335 SVGPropertyBase* toValue = m_animator.createPropertyForAnimation(toString); 369 SVGPropertyBase* toValue = m_animator.createPropertyForAnimation(toString);
336 return fromValue->calculateDistance(toValue, targetElement); 370 return fromValue->calculateDistance(toValue, targetElement);
337 } 371 }
338 372
339 void SVGAnimateElement::setTargetElement(SVGElement* target) { 373 void SVGAnimateElement::setTargetElement(SVGElement* target) {
(...skipping 17 matching lines...) Expand all
357 DEFINE_TRACE(SVGAnimateElement) { 391 DEFINE_TRACE(SVGAnimateElement) {
358 visitor->trace(m_fromProperty); 392 visitor->trace(m_fromProperty);
359 visitor->trace(m_toProperty); 393 visitor->trace(m_toProperty);
360 visitor->trace(m_toAtEndOfDurationProperty); 394 visitor->trace(m_toAtEndOfDurationProperty);
361 visitor->trace(m_animatedProperty); 395 visitor->trace(m_animatedProperty);
362 visitor->trace(m_animator); 396 visitor->trace(m_animator);
363 SVGAnimationElement::trace(visitor); 397 SVGAnimationElement::trace(visitor);
364 } 398 }
365 399
366 } // namespace blink 400 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/svg/SVGAnimateElement.h ('k') | third_party/WebKit/Source/core/svg/SVGAnimationElement.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698