Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/css/CSSComputedStyleDeclaration.h" | 25 #include "core/css/CSSComputedStyleDeclaration.h" |
| 26 #include "core/css/StylePropertySet.h" | 26 #include "core/css/StylePropertySet.h" |
| 27 #include "core/dom/Document.h" | 27 #include "core/dom/Document.h" |
| 28 #include "core/dom/QualifiedName.h" | 28 #include "core/dom/QualifiedName.h" |
| 29 #include "core/dom/StyleChangeReason.h" | 29 #include "core/dom/StyleChangeReason.h" |
| 30 #include "core/svg/SVGAnimatedColor.h" | |
| 31 #include "core/svg/SVGLength.h" | |
| 32 #include "core/svg/SVGLengthList.h" | |
| 33 #include "core/svg/SVGNumber.h" | |
| 34 #include "core/svg/SVGString.h" | |
| 35 #include "core/svg/properties/SVGAnimatedProperty.h" | |
| 30 #include "core/svg/properties/SVGProperty.h" | 36 #include "core/svg/properties/SVGProperty.h" |
| 31 | 37 |
| 32 namespace blink { | 38 namespace blink { |
| 33 | 39 |
| 34 namespace { | 40 namespace { |
| 35 | 41 |
| 36 bool isTargetAttributeCSSProperty(const SVGElement& targetElement, | 42 bool isTargetAttributeCSSProperty(const SVGElement& targetElement, |
| 37 const QualifiedName& attributeName) { | 43 const QualifiedName& attributeName) { |
| 38 return SVGElement::isAnimatableCSSProperty(attributeName) || | 44 return SVGElement::isAnimatableCSSProperty(attributeName) || |
| 39 targetElement.isPresentationAttribute(attributeName); | 45 targetElement.isPresentationAttribute(attributeName); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 61 !SVGElement::isAnimatableCSSProperty(attributeName)) | 67 !SVGElement::isAnimatableCSSProperty(attributeName)) |
| 62 return RegularPropertyValue; | 68 return RegularPropertyValue; |
| 63 return InheritValue; | 69 return InheritValue; |
| 64 } | 70 } |
| 65 | 71 |
| 66 } // unnamed namespace | 72 } // unnamed namespace |
| 67 | 73 |
| 68 SVGAnimateElement::SVGAnimateElement(const QualifiedName& tagName, | 74 SVGAnimateElement::SVGAnimateElement(const QualifiedName& tagName, |
| 69 Document& document) | 75 Document& document) |
| 70 : SVGAnimationElement(tagName, document), | 76 : SVGAnimationElement(tagName, document), |
| 71 m_animator(this), | 77 m_type(AnimatedUnknown), |
| 78 m_cssPropertyId(CSSPropertyInvalid), | |
| 72 m_fromPropertyValueType(RegularPropertyValue), | 79 m_fromPropertyValueType(RegularPropertyValue), |
| 73 m_toPropertyValueType(RegularPropertyValue), | 80 m_toPropertyValueType(RegularPropertyValue), |
| 74 m_attributeType(AttributeTypeAuto), | 81 m_attributeType(AttributeTypeAuto), |
| 75 m_hasInvalidCSSAttributeType(false) {} | 82 m_hasInvalidCSSAttributeType(false) {} |
| 76 | 83 |
| 77 SVGAnimateElement* SVGAnimateElement::create(Document& document) { | 84 SVGAnimateElement* SVGAnimateElement::create(Document& document) { |
| 78 return new SVGAnimateElement(SVGNames::animateTag, document); | 85 return new SVGAnimateElement(SVGNames::animateTag, document); |
| 79 } | 86 } |
| 80 | 87 |
| 81 SVGAnimateElement::~SVGAnimateElement() {} | 88 SVGAnimateElement::~SVGAnimateElement() {} |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 113 } | 120 } |
| 114 | 121 |
| 115 void SVGAnimateElement::svgAttributeChanged(const QualifiedName& attrName) { | 122 void SVGAnimateElement::svgAttributeChanged(const QualifiedName& attrName) { |
| 116 if (attrName == SVGNames::attributeTypeAttr) { | 123 if (attrName == SVGNames::attributeTypeAttr) { |
| 117 animationAttributeChanged(); | 124 animationAttributeChanged(); |
| 118 return; | 125 return; |
| 119 } | 126 } |
| 120 SVGAnimationElement::svgAttributeChanged(attrName); | 127 SVGAnimationElement::svgAttributeChanged(attrName); |
| 121 } | 128 } |
| 122 | 129 |
| 130 void SVGAnimateElement::resolveTargetProperty() { | |
| 131 DCHECK(targetElement()); | |
| 132 m_targetProperty = targetElement()->propertyFromAttribute(attributeName()); | |
| 133 if (m_targetProperty) { | |
| 134 m_type = m_targetProperty->type(); | |
| 135 m_cssPropertyId = m_targetProperty->cssPropertyId(); | |
| 136 | |
| 137 // Only <animateTransform> is allowed to animate AnimatedTransformList. | |
| 138 // http://www.w3.org/TR/SVG/animate.html#AnimationAttributesAndProperties | |
| 139 if (m_type == AnimatedTransformList) { | |
| 140 m_type = AnimatedUnknown; | |
| 141 m_cssPropertyId = CSSPropertyInvalid; | |
| 142 } | |
| 143 } else { | |
| 144 m_type = SVGElement::animatedPropertyTypeForCSSAttribute(attributeName()); | |
| 145 m_cssPropertyId = m_type != AnimatedUnknown | |
| 146 ? cssPropertyID(attributeName().localName()) | |
| 147 : CSSPropertyInvalid; | |
| 148 } | |
| 149 DCHECK(m_type != AnimatedPoint && m_type != AnimatedStringList && | |
| 150 m_type != AnimatedTransform && m_type != AnimatedTransformList); | |
| 151 } | |
| 152 | |
| 153 void SVGAnimateElement::clearTargetProperty() { | |
| 154 m_targetProperty = nullptr; | |
| 155 m_type = AnimatedUnknown; | |
| 156 m_cssPropertyId = CSSPropertyInvalid; | |
| 157 } | |
| 158 | |
| 123 AnimatedPropertyType SVGAnimateElement::animatedPropertyType() { | 159 AnimatedPropertyType SVGAnimateElement::animatedPropertyType() { |
| 124 if (!targetElement()) | 160 if (!targetElement()) |
| 125 return AnimatedUnknown; | 161 return AnimatedUnknown; |
| 126 | 162 resolveTargetProperty(); |
| 127 m_animator.reset(*targetElement()); | 163 return m_type; |
| 128 return m_animator.type(); | |
| 129 } | 164 } |
| 130 | 165 |
| 131 bool SVGAnimateElement::hasValidTarget() { | 166 bool SVGAnimateElement::hasValidTarget() { |
| 132 return SVGAnimationElement::hasValidTarget() && hasValidAttributeName() && | 167 return SVGAnimationElement::hasValidTarget() && hasValidAttributeName() && |
| 133 hasValidAttributeType(); | 168 hasValidAttributeType(); |
| 134 } | 169 } |
| 135 | 170 |
| 136 bool SVGAnimateElement::hasValidAttributeName() const { | 171 bool SVGAnimateElement::hasValidAttributeName() const { |
| 137 return attributeName() != anyQName(); | 172 return attributeName() != anyQName(); |
| 138 } | 173 } |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 153 // Always animate CSS properties using the ApplyCSSAnimation code path, | 188 // Always animate CSS properties using the ApplyCSSAnimation code path, |
| 154 // regardless of the attributeType value. | 189 // regardless of the attributeType value. |
| 155 if (isTargetAttributeCSSProperty(targetElement, attributeName)) | 190 if (isTargetAttributeCSSProperty(targetElement, attributeName)) |
| 156 return true; | 191 return true; |
| 157 | 192 |
| 158 // If attributeType="CSS" and attributeName doesn't point to a CSS property, | 193 // If attributeType="CSS" and attributeName doesn't point to a CSS property, |
| 159 // ignore the animation. | 194 // ignore the animation. |
| 160 return getAttributeType() != AttributeTypeCSS; | 195 return getAttributeType() != AttributeTypeCSS; |
| 161 } | 196 } |
| 162 | 197 |
| 198 SVGPropertyBase* SVGAnimateElement::createPropertyForAttributeAnimation( | |
| 199 const String& value) const { | |
| 200 // SVG DOM animVal animation code-path. | |
| 201 // TransformList must be animated via <animateTransform>, and its | |
| 202 // {from,by,to} attribute values needs to be parsed w.r.t. its "type" | |
| 203 // attribute. Spec: | |
| 204 // http://www.w3.org/TR/SVG/single-page.html#animate-AnimateTransformElement | |
| 205 DCHECK_NE(m_type, AnimatedTransformList); | |
| 206 DCHECK(m_targetProperty); | |
| 207 return m_targetProperty->currentValueBase()->cloneForAnimation(value); | |
| 208 } | |
| 209 | |
| 210 SVGPropertyBase* SVGAnimateElement::createPropertyForCSSAnimation( | |
| 211 const String& value) const { | |
| 212 // CSS properties animation code-path. | |
| 213 // Create a basic instance of the corresponding SVG property. | |
| 214 // The instance will not have full context info. (e.g. SVGLengthMode) | |
| 215 switch (m_type) { | |
| 216 case AnimatedColor: | |
| 217 return SVGColorProperty::create(value); | |
| 218 case AnimatedNumber: { | |
| 219 SVGNumber* property = SVGNumber::create(); | |
| 220 property->setValueAsString(value); | |
| 221 return property; | |
| 222 } | |
| 223 case AnimatedLength: { | |
| 224 SVGLength* property = SVGLength::create(); | |
| 225 property->setValueAsString(value); | |
| 226 return property; | |
| 227 } | |
| 228 case AnimatedLengthList: { | |
| 229 SVGLengthList* property = SVGLengthList::create(); | |
| 230 property->setValueAsString(value); | |
| 231 return property; | |
| 232 } | |
| 233 case AnimatedString: { | |
| 234 SVGString* property = SVGString::create(); | |
| 235 property->setValueAsString(value); | |
| 236 return property; | |
| 237 } | |
| 238 // These types don't appear in the table in | |
| 239 // SVGElement::animatedPropertyTypeForCSSAttribute() and thus don't need | |
| 240 // support. | |
| 241 case AnimatedAngle: | |
| 242 case AnimatedBoolean: | |
| 243 case AnimatedEnumeration: | |
| 244 case AnimatedInteger: | |
| 245 case AnimatedIntegerOptionalInteger: | |
| 246 case AnimatedNumberList: | |
| 247 case AnimatedNumberOptionalNumber: | |
| 248 case AnimatedPath: | |
| 249 case AnimatedPoint: | |
| 250 case AnimatedPoints: | |
| 251 case AnimatedPreserveAspectRatio: | |
| 252 case AnimatedRect: | |
| 253 case AnimatedStringList: | |
| 254 case AnimatedTransform: | |
| 255 case AnimatedTransformList: | |
| 256 case AnimatedUnknown: | |
| 257 break; | |
| 258 default: | |
| 259 break; | |
| 260 } | |
| 261 NOTREACHED(); | |
| 262 return nullptr; | |
| 263 } | |
| 264 | |
| 265 SVGPropertyBase* SVGAnimateElement::createPropertyForAnimation( | |
| 266 const String& value) const { | |
| 267 if (isAnimatingSVGDom()) | |
| 268 return createPropertyForAttributeAnimation(value); | |
| 269 DCHECK(isAnimatingCSSProperty()); | |
| 270 return createPropertyForCSSAnimation(value); | |
| 271 } | |
| 272 | |
| 163 SVGPropertyBase* SVGAnimateElement::adjustForInheritance( | 273 SVGPropertyBase* SVGAnimateElement::adjustForInheritance( |
| 164 SVGPropertyBase* propertyValue, | 274 SVGPropertyBase* propertyValue, |
| 165 AnimatedPropertyValueType valueType) const { | 275 AnimatedPropertyValueType valueType) const { |
| 166 if (valueType != InheritValue) | 276 if (valueType != InheritValue) |
| 167 return propertyValue; | 277 return propertyValue; |
| 168 // TODO(fs): At the moment the computed style gets returned as a String and | 278 // TODO(fs): At the moment the computed style gets returned as a String and |
| 169 // needs to get parsed again. In the future we might want to work with the | 279 // needs to get parsed again. In the future we might want to work with the |
| 170 // value type directly to avoid the String parsing. | 280 // value type directly to avoid the String parsing. |
| 171 DCHECK(targetElement()); | 281 DCHECK(targetElement()); |
| 172 Element* parent = targetElement()->parentElement(); | 282 Element* parent = targetElement()->parentElement(); |
| 173 if (!parent || !parent->isSVGElement()) | 283 if (!parent || !parent->isSVGElement()) |
| 174 return propertyValue; | 284 return propertyValue; |
| 175 SVGElement* svgParent = toSVGElement(parent); | 285 SVGElement* svgParent = toSVGElement(parent); |
| 176 // Replace 'inherit' by its computed property value. | 286 // Replace 'inherit' by its computed property value. |
| 177 String value = computeCSSPropertyValue(svgParent, m_animator.cssProperty()); | 287 String value = computeCSSPropertyValue(svgParent, m_cssPropertyId); |
| 178 return m_animator.createPropertyForAnimation(value); | 288 return createPropertyForAnimation(value); |
| 179 } | 289 } |
| 180 | 290 |
| 181 void SVGAnimateElement::calculateAnimatedValue(float percentage, | 291 void SVGAnimateElement::calculateAnimatedValue(float percentage, |
| 182 unsigned repeatCount, | 292 unsigned repeatCount, |
| 183 SVGSMILElement* resultElement) { | 293 SVGSMILElement* resultElement) { |
| 184 DCHECK(resultElement); | 294 DCHECK(resultElement); |
| 185 DCHECK(targetElement()); | 295 DCHECK(targetElement()); |
| 186 if (!isSVGAnimateElement(*resultElement)) | 296 if (!isSVGAnimateElement(*resultElement)) |
| 187 return; | 297 return; |
| 188 | 298 |
| 189 ASSERT(percentage >= 0 && percentage <= 1); | 299 ASSERT(percentage >= 0 && percentage <= 1); |
|
Stephen Chennney
2016/12/22 20:07:25
I wonder how we got in a state where there are DCH
fs
2016/12/22 20:25:31
That's most likely an artifact of whoever changed
fs
2016/12/22 21:45:49
Done.
| |
| 190 ASSERT(animatedPropertyType() != AnimatedTransformList || | 300 DCHECK(animatedPropertyType() != AnimatedUnknown); |
| 191 isSVGAnimateTransformElement(*this)); | |
| 192 ASSERT(animatedPropertyType() != AnimatedUnknown); | |
| 193 ASSERT(m_fromProperty); | 301 ASSERT(m_fromProperty); |
| 194 ASSERT(m_fromProperty->type() == animatedPropertyType()); | 302 ASSERT(m_fromProperty->type() == animatedPropertyType()); |
| 195 ASSERT(m_toProperty); | 303 ASSERT(m_toProperty); |
| 196 | 304 |
| 197 SVGAnimateElement* resultAnimationElement = | 305 SVGAnimateElement* resultAnimationElement = |
| 198 toSVGAnimateElement(resultElement); | 306 toSVGAnimateElement(resultElement); |
| 199 ASSERT(resultAnimationElement->m_animatedProperty); | 307 DCHECK(resultAnimationElement->m_animatedValue); |
| 200 ASSERT(resultAnimationElement->animatedPropertyType() == | 308 ASSERT(resultAnimationElement->animatedPropertyType() == |
| 201 animatedPropertyType()); | 309 animatedPropertyType()); |
| 202 | 310 |
| 203 if (isSVGSetElement(*this)) | 311 if (isSVGSetElement(*this)) |
| 204 percentage = 1; | 312 percentage = 1; |
| 205 | 313 |
| 206 if (getCalcMode() == CalcModeDiscrete) | 314 if (getCalcMode() == CalcModeDiscrete) |
| 207 percentage = percentage < 0.5 ? 0 : 1; | 315 percentage = percentage < 0.5 ? 0 : 1; |
| 208 | 316 |
| 209 // Target element might have changed. | 317 // Target element might have changed. |
| 210 SVGElement* targetElement = this->targetElement(); | 318 SVGElement* targetElement = this->targetElement(); |
| 211 | 319 |
| 212 // Values-animation accumulates using the last values entry corresponding to | 320 // Values-animation accumulates using the last values entry corresponding to |
| 213 // the end of duration time. | 321 // the end of duration time. |
| 214 SVGPropertyBase* animatedValue = resultAnimationElement->m_animatedProperty; | 322 SVGPropertyBase* animatedValue = resultAnimationElement->m_animatedValue; |
| 215 SVGPropertyBase* toAtEndOfDurationValue = | 323 SVGPropertyBase* toAtEndOfDurationValue = |
| 216 m_toAtEndOfDurationProperty ? m_toAtEndOfDurationProperty : m_toProperty; | 324 m_toAtEndOfDurationProperty ? m_toAtEndOfDurationProperty : m_toProperty; |
| 217 SVGPropertyBase* fromValue = | 325 SVGPropertyBase* fromValue = |
| 218 getAnimationMode() == ToAnimation ? animatedValue : m_fromProperty.get(); | 326 getAnimationMode() == ToAnimation ? animatedValue : m_fromProperty.get(); |
| 219 SVGPropertyBase* toValue = m_toProperty; | 327 SVGPropertyBase* toValue = m_toProperty; |
| 220 | 328 |
| 221 // Apply CSS inheritance rules. | 329 // Apply CSS inheritance rules. |
| 222 fromValue = adjustForInheritance(fromValue, m_fromPropertyValueType); | 330 fromValue = adjustForInheritance(fromValue, m_fromPropertyValueType); |
| 223 toValue = adjustForInheritance(toValue, m_toPropertyValueType); | 331 toValue = adjustForInheritance(toValue, m_toPropertyValueType); |
| 224 | 332 |
| 225 animatedValue->calculateAnimatedValue(this, percentage, repeatCount, | 333 animatedValue->calculateAnimatedValue(this, percentage, repeatCount, |
| 226 fromValue, toValue, | 334 fromValue, toValue, |
| 227 toAtEndOfDurationValue, targetElement); | 335 toAtEndOfDurationValue, targetElement); |
| 228 } | 336 } |
| 229 | 337 |
| 230 bool SVGAnimateElement::calculateToAtEndOfDurationValue( | 338 bool SVGAnimateElement::calculateToAtEndOfDurationValue( |
| 231 const String& toAtEndOfDurationString) { | 339 const String& toAtEndOfDurationString) { |
| 232 if (toAtEndOfDurationString.isEmpty()) | 340 if (toAtEndOfDurationString.isEmpty()) |
| 233 return false; | 341 return false; |
| 234 m_toAtEndOfDurationProperty = | 342 m_toAtEndOfDurationProperty = |
| 235 m_animator.createPropertyForAnimation(toAtEndOfDurationString); | 343 createPropertyForAnimation(toAtEndOfDurationString); |
| 236 return true; | 344 return true; |
| 237 } | 345 } |
| 238 | 346 |
| 239 bool SVGAnimateElement::calculateFromAndToValues(const String& fromString, | 347 bool SVGAnimateElement::calculateFromAndToValues(const String& fromString, |
| 240 const String& toString) { | 348 const String& toString) { |
| 241 DCHECK(targetElement()); | 349 DCHECK(targetElement()); |
| 242 m_fromProperty = m_animator.createPropertyForAnimation(fromString); | 350 m_fromProperty = createPropertyForAnimation(fromString); |
| 243 m_fromPropertyValueType = propertyValueType(attributeName(), fromString); | 351 m_fromPropertyValueType = propertyValueType(attributeName(), fromString); |
| 244 m_toProperty = m_animator.createPropertyForAnimation(toString); | 352 m_toProperty = createPropertyForAnimation(toString); |
| 245 m_toPropertyValueType = propertyValueType(attributeName(), toString); | 353 m_toPropertyValueType = propertyValueType(attributeName(), toString); |
| 246 return true; | 354 return true; |
| 247 } | 355 } |
| 248 | 356 |
| 249 bool SVGAnimateElement::calculateFromAndByValues(const String& fromString, | 357 bool SVGAnimateElement::calculateFromAndByValues(const String& fromString, |
| 250 const String& byString) { | 358 const String& byString) { |
| 251 DCHECK(targetElement()); | 359 DCHECK(targetElement()); |
| 252 | 360 |
| 253 if (getAnimationMode() == ByAnimation && !isAdditive()) | 361 if (getAnimationMode() == ByAnimation && !isAdditive()) |
| 254 return false; | 362 return false; |
| 255 | 363 |
| 256 // from-by animation may only be used with attributes that support addition | 364 // from-by animation may only be used with attributes that support addition |
| 257 // (e.g. most numeric attributes). | 365 // (e.g. most numeric attributes). |
| 258 if (getAnimationMode() == FromByAnimation && | 366 if (getAnimationMode() == FromByAnimation && |
| 259 !animatedPropertyTypeSupportsAddition()) | 367 !animatedPropertyTypeSupportsAddition()) |
| 260 return false; | 368 return false; |
| 261 | 369 |
| 262 DCHECK(!isSVGSetElement(*this)); | 370 DCHECK(!isSVGSetElement(*this)); |
| 263 | 371 |
| 264 m_fromProperty = m_animator.createPropertyForAnimation(fromString); | 372 m_fromProperty = createPropertyForAnimation(fromString); |
| 265 m_fromPropertyValueType = propertyValueType(attributeName(), fromString); | 373 m_fromPropertyValueType = propertyValueType(attributeName(), fromString); |
| 266 m_toProperty = m_animator.createPropertyForAnimation(byString); | 374 m_toProperty = createPropertyForAnimation(byString); |
| 267 m_toPropertyValueType = propertyValueType(attributeName(), byString); | 375 m_toPropertyValueType = propertyValueType(attributeName(), byString); |
| 268 m_toProperty->add(m_fromProperty, targetElement()); | 376 m_toProperty->add(m_fromProperty, targetElement()); |
| 269 return true; | 377 return true; |
| 270 } | 378 } |
| 271 | 379 |
| 272 void SVGAnimateElement::resetAnimatedType() { | 380 void SVGAnimateElement::resetAnimatedType() { |
| 381 resolveTargetProperty(); | |
| 382 | |
| 273 SVGElement* targetElement = this->targetElement(); | 383 SVGElement* targetElement = this->targetElement(); |
| 274 const QualifiedName& attributeName = this->attributeName(); | 384 const QualifiedName& attributeName = this->attributeName(); |
| 275 | 385 |
| 276 m_animator.reset(*targetElement); | |
| 277 | |
| 278 if (!shouldApplyAnimation(*targetElement, attributeName)) | 386 if (!shouldApplyAnimation(*targetElement, attributeName)) |
| 279 return; | 387 return; |
| 280 if (m_animator.isAnimatingSVGDom()) { | 388 if (isAnimatingSVGDom()) { |
| 281 // SVG DOM animVal animation code-path. | 389 // SVG DOM animVal animation code-path. |
| 282 m_animatedProperty = m_animator.createAnimatedValue(); | 390 m_animatedValue = m_targetProperty->createAnimatedValue(); |
| 283 targetElement->setAnimatedAttribute(attributeName, m_animatedProperty); | 391 DCHECK_EQ(m_animatedValue->type(), m_type); |
| 392 targetElement->setAnimatedAttribute(attributeName, m_animatedValue); | |
| 284 return; | 393 return; |
| 285 } | 394 } |
| 286 DCHECK(m_animator.isAnimatingCSSProperty()); | 395 DCHECK(isAnimatingCSSProperty()); |
| 287 // Presentation attributes which has an SVG DOM representation should use the | 396 // Presentation attributes which has an SVG DOM representation should use the |
| 288 // "SVG DOM" code-path (above.) | 397 // "SVG DOM" code-path (above.) |
| 289 DCHECK(SVGElement::isAnimatableCSSProperty(attributeName)); | 398 DCHECK(SVGElement::isAnimatableCSSProperty(attributeName)); |
| 290 | 399 |
| 291 // CSS properties animation code-path. | 400 // CSS properties animation code-path. |
| 292 String baseValue = | 401 String baseValue = computeCSSPropertyValue(targetElement, m_cssPropertyId); |
| 293 computeCSSPropertyValue(targetElement, m_animator.cssProperty()); | 402 m_animatedValue = createPropertyForAnimation(baseValue); |
| 294 m_animatedProperty = m_animator.createPropertyForAnimation(baseValue); | |
| 295 } | 403 } |
| 296 | 404 |
| 297 void SVGAnimateElement::clearAnimatedType() { | 405 void SVGAnimateElement::clearAnimatedType() { |
| 298 if (!m_animatedProperty) | 406 if (!m_animatedValue) |
| 299 return; | 407 return; |
| 300 | 408 |
| 301 // The animated property lock is held for the "result animation" (see | 409 // The animated property lock is held for the "result animation" (see |
| 302 // SMILTimeContainer::updateAnimations()) while we're processing an animation | 410 // SMILTimeContainer::updateAnimations()) while we're processing an animation |
| 303 // group. We will very likely crash later if we clear the animated type while | 411 // group. We will very likely crash later if we clear the animated type while |
| 304 // the lock is held. See crbug.com/581546. | 412 // the lock is held. See crbug.com/581546. |
| 305 DCHECK(!animatedTypeIsLocked()); | 413 DCHECK(!animatedTypeIsLocked()); |
| 306 | 414 |
| 307 SVGElement* targetElement = this->targetElement(); | 415 SVGElement* targetElement = this->targetElement(); |
| 308 if (!targetElement) { | 416 if (!targetElement) { |
| 309 m_animatedProperty.clear(); | 417 m_animatedValue.clear(); |
| 310 return; | 418 return; |
| 311 } | 419 } |
| 312 | 420 |
| 313 bool shouldApply = shouldApplyAnimation(*targetElement, attributeName()); | 421 bool shouldApply = shouldApplyAnimation(*targetElement, attributeName()); |
| 314 if (m_animator.isAnimatingCSSProperty()) { | 422 if (isAnimatingCSSProperty()) { |
| 315 // CSS properties animation code-path. | 423 // CSS properties animation code-path. |
| 316 if (shouldApply) { | 424 if (shouldApply) { |
| 317 MutableStylePropertySet* propertySet = | 425 MutableStylePropertySet* propertySet = |
| 318 targetElement->ensureAnimatedSMILStyleProperties(); | 426 targetElement->ensureAnimatedSMILStyleProperties(); |
| 319 if (propertySet->removeProperty(m_animator.cssProperty())) { | 427 if (propertySet->removeProperty(m_cssPropertyId)) { |
| 320 targetElement->setNeedsStyleRecalc( | 428 targetElement->setNeedsStyleRecalc( |
| 321 LocalStyleChange, | 429 LocalStyleChange, |
| 322 StyleChangeReasonForTracing::create(StyleChangeReason::Animation)); | 430 StyleChangeReasonForTracing::create(StyleChangeReason::Animation)); |
| 323 } | 431 } |
| 324 } | 432 } |
| 325 } | 433 } |
| 326 if (m_animator.isAnimatingSVGDom()) { | 434 if (isAnimatingSVGDom()) { |
| 327 // SVG DOM animVal animation code-path. | 435 // SVG DOM animVal animation code-path. |
| 328 targetElement->clearAnimatedAttribute(attributeName()); | 436 targetElement->clearAnimatedAttribute(attributeName()); |
| 329 if (shouldApply) | 437 if (shouldApply) |
| 330 targetElement->invalidateAnimatedAttribute(attributeName()); | 438 targetElement->invalidateAnimatedAttribute(attributeName()); |
| 331 } | 439 } |
| 332 | 440 |
| 333 m_animatedProperty.clear(); | 441 m_animatedValue.clear(); |
| 334 m_animator.clear(); | 442 clearTargetProperty(); |
| 335 } | 443 } |
| 336 | 444 |
| 337 void SVGAnimateElement::applyResultsToTarget() { | 445 void SVGAnimateElement::applyResultsToTarget() { |
| 338 ASSERT(animatedPropertyType() != AnimatedTransformList || | 446 DCHECK(animatedPropertyType() != AnimatedUnknown); |
| 339 isSVGAnimateTransformElement(*this)); | |
| 340 ASSERT(animatedPropertyType() != AnimatedUnknown); | |
| 341 | 447 |
| 342 // Early exit if our animated type got destructed by a previous | 448 // Early exit if our animated type got destructed by a previous |
| 343 // endedActiveInterval(). | 449 // endedActiveInterval(). |
| 344 if (!m_animatedProperty) | 450 if (!m_animatedValue) |
| 345 return; | 451 return; |
| 346 | 452 |
| 347 if (!shouldApplyAnimation(*targetElement(), attributeName())) | 453 if (!shouldApplyAnimation(*targetElement(), attributeName())) |
| 348 return; | 454 return; |
| 349 | 455 |
| 350 // We do update the style and the animation property independent of each | 456 // We do update the style and the animation property independent of each |
| 351 // other. | 457 // other. |
| 352 if (m_animator.isAnimatingCSSProperty()) { | 458 if (isAnimatingCSSProperty()) { |
| 353 // CSS properties animation code-path. | 459 // CSS properties animation code-path. |
| 354 // Convert the result of the animation to a String and apply it as CSS | 460 // Convert the result of the animation to a String and apply it as CSS |
| 355 // property on the target. | 461 // property on the target. |
| 356 MutableStylePropertySet* propertySet = | 462 MutableStylePropertySet* propertySet = |
| 357 targetElement()->ensureAnimatedSMILStyleProperties(); | 463 targetElement()->ensureAnimatedSMILStyleProperties(); |
| 358 if (propertySet | 464 if (propertySet |
| 359 ->setProperty(m_animator.cssProperty(), | 465 ->setProperty(m_cssPropertyId, m_animatedValue->valueAsString(), |
| 360 m_animatedProperty->valueAsString(), false, 0) | 466 false, 0) |
| 361 .didChange) { | 467 .didChange) { |
| 362 targetElement()->setNeedsStyleRecalc( | 468 targetElement()->setNeedsStyleRecalc( |
| 363 LocalStyleChange, | 469 LocalStyleChange, |
| 364 StyleChangeReasonForTracing::create(StyleChangeReason::Animation)); | 470 StyleChangeReasonForTracing::create(StyleChangeReason::Animation)); |
| 365 } | 471 } |
| 366 } | 472 } |
| 367 if (m_animator.isAnimatingSVGDom()) { | 473 if (isAnimatingSVGDom()) { |
| 368 // SVG DOM animVal animation code-path. | 474 // SVG DOM animVal animation code-path. |
| 369 // At this point the SVG DOM values are already changed, unlike for CSS. | 475 // At this point the SVG DOM values are already changed, unlike for CSS. |
| 370 // We only have to trigger update notifications here. | 476 // We only have to trigger update notifications here. |
| 371 targetElement()->invalidateAnimatedAttribute(attributeName()); | 477 targetElement()->invalidateAnimatedAttribute(attributeName()); |
| 372 } | 478 } |
| 373 } | 479 } |
| 374 | 480 |
| 375 bool SVGAnimateElement::animatedPropertyTypeSupportsAddition() { | 481 bool SVGAnimateElement::animatedPropertyTypeSupportsAddition() { |
| 376 // http://www.w3.org/TR/SVG/animate.html#AnimationAttributesAndProperties. | 482 // http://www.w3.org/TR/SVG/animate.html#AnimationAttributesAndProperties. |
| 377 switch (animatedPropertyType()) { | 483 switch (animatedPropertyType()) { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 394 } | 500 } |
| 395 | 501 |
| 396 return SVGAnimationElement::isAdditive(); | 502 return SVGAnimationElement::isAdditive(); |
| 397 } | 503 } |
| 398 | 504 |
| 399 float SVGAnimateElement::calculateDistance(const String& fromString, | 505 float SVGAnimateElement::calculateDistance(const String& fromString, |
| 400 const String& toString) { | 506 const String& toString) { |
| 401 DCHECK(targetElement()); | 507 DCHECK(targetElement()); |
| 402 // FIXME: A return value of float is not enough to support paced animations on | 508 // FIXME: A return value of float is not enough to support paced animations on |
| 403 // lists. | 509 // lists. |
| 404 SVGPropertyBase* fromValue = | 510 SVGPropertyBase* fromValue = createPropertyForAnimation(fromString); |
| 405 m_animator.createPropertyForAnimation(fromString); | 511 SVGPropertyBase* toValue = createPropertyForAnimation(toString); |
| 406 SVGPropertyBase* toValue = m_animator.createPropertyForAnimation(toString); | |
| 407 return fromValue->calculateDistance(toValue, targetElement()); | 512 return fromValue->calculateDistance(toValue, targetElement()); |
| 408 } | 513 } |
| 409 | 514 |
| 410 void SVGAnimateElement::setTargetElement(SVGElement* target) { | 515 void SVGAnimateElement::setTargetElement(SVGElement* target) { |
| 411 SVGAnimationElement::setTargetElement(target); | 516 SVGAnimationElement::setTargetElement(target); |
| 412 checkInvalidCSSAttributeType(); | 517 checkInvalidCSSAttributeType(); |
| 413 resetAnimatedPropertyType(); | 518 resetAnimatedPropertyType(); |
| 414 } | 519 } |
| 415 | 520 |
| 416 void SVGAnimateElement::setAttributeName(const QualifiedName& attributeName) { | 521 void SVGAnimateElement::setAttributeName(const QualifiedName& attributeName) { |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 444 if (!hasInvalidCSSAttributeType) | 549 if (!hasInvalidCSSAttributeType) |
| 445 schedule(); | 550 schedule(); |
| 446 } | 551 } |
| 447 | 552 |
| 448 // Clear values that may depend on the previous target. | 553 // Clear values that may depend on the previous target. |
| 449 if (targetElement()) | 554 if (targetElement()) |
| 450 clearAnimatedType(); | 555 clearAnimatedType(); |
| 451 } | 556 } |
| 452 | 557 |
| 453 void SVGAnimateElement::resetAnimatedPropertyType() { | 558 void SVGAnimateElement::resetAnimatedPropertyType() { |
| 454 ASSERT(!m_animatedProperty); | 559 DCHECK(!m_animatedValue); |
| 455 m_fromProperty.clear(); | 560 m_fromProperty.clear(); |
| 456 m_toProperty.clear(); | 561 m_toProperty.clear(); |
| 457 m_toAtEndOfDurationProperty.clear(); | 562 m_toAtEndOfDurationProperty.clear(); |
| 458 m_animator.clear(); | 563 clearTargetProperty(); |
| 459 } | 564 } |
| 460 | 565 |
| 461 DEFINE_TRACE(SVGAnimateElement) { | 566 DEFINE_TRACE(SVGAnimateElement) { |
| 462 visitor->trace(m_fromProperty); | 567 visitor->trace(m_fromProperty); |
| 463 visitor->trace(m_toProperty); | 568 visitor->trace(m_toProperty); |
| 464 visitor->trace(m_toAtEndOfDurationProperty); | 569 visitor->trace(m_toAtEndOfDurationProperty); |
| 465 visitor->trace(m_animatedProperty); | 570 visitor->trace(m_animatedValue); |
| 466 visitor->trace(m_animator); | 571 visitor->trace(m_targetProperty); |
| 467 SVGAnimationElement::trace(visitor); | 572 SVGAnimationElement::trace(visitor); |
| 468 } | 573 } |
| 469 | 574 |
| 470 } // namespace blink | 575 } // namespace blink |
| OLD | NEW |