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

Side by Side Diff: third_party/WebKit/Source/core/svg/SVGAnimationElement.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
« no previous file with comments | « third_party/WebKit/Source/core/svg/SVGAnimationElement.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) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> 2 * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org>
3 * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> 3 * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
4 * Copyright (C) 2007 Eric Seidel <eric@webkit.org> 4 * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
5 * Copyright (C) 2008 Apple Inc. All rights reserved. 5 * Copyright (C) 2008 Apple Inc. All rights reserved.
6 * Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au> 6 * Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au>
7 * Copyright (C) Research In Motion Limited 2010. All rights reserved. 7 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
8 * 8 *
9 * This library is free software; you can redistribute it and/or 9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public 10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either 11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version. 12 * version 2 of the License, or (at your option) any later version.
13 * 13 *
14 * This library is distributed in the hope that it will be useful, 14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details. 17 * Library General Public License for more details.
18 * 18 *
19 * You should have received a copy of the GNU Library General Public License 19 * You should have received a copy of the GNU Library General Public License
20 * along with this library; see the file COPYING.LIB. If not, write to 20 * along with this library; see the file COPYING.LIB. If not, write to
21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA. 22 * Boston, MA 02110-1301, USA.
23 */ 23 */
24 24
25 #include "core/svg/SVGAnimationElement.h" 25 #include "core/svg/SVGAnimationElement.h"
26 26
27 #include "bindings/core/v8/ExceptionState.h" 27 #include "bindings/core/v8/ExceptionState.h"
28 #include "core/CSSPropertyNames.h"
29 #include "core/SVGNames.h" 28 #include "core/SVGNames.h"
30 #include "core/css/CSSComputedStyleDeclaration.h"
31 #include "core/css/parser/CSSParser.h"
32 #include "core/frame/UseCounter.h" 29 #include "core/frame/UseCounter.h"
33 #include "core/svg/SVGAnimateElement.h" 30 #include "core/svg/SVGAnimateElement.h"
34 #include "core/svg/SVGElement.h"
35 #include "core/svg/SVGParserUtilities.h" 31 #include "core/svg/SVGParserUtilities.h"
36 #include "wtf/MathExtras.h" 32 #include "wtf/MathExtras.h"
37 33
38 namespace blink { 34 namespace blink {
39 35
40 SVGAnimationElement::SVGAnimationElement(const QualifiedName& tagName, 36 SVGAnimationElement::SVGAnimationElement(const QualifiedName& tagName,
41 Document& document) 37 Document& document)
42 : SVGSMILElement(tagName, document), 38 : SVGSMILElement(tagName, document),
43 m_fromPropertyValueType(RegularPropertyValue),
44 m_toPropertyValueType(RegularPropertyValue),
45 m_animationValid(false), 39 m_animationValid(false),
46 m_attributeType(AttributeTypeAuto), 40 m_attributeType(AttributeTypeAuto),
47 m_hasInvalidCSSAttributeType(false), 41 m_hasInvalidCSSAttributeType(false),
48 m_calcMode(CalcModeLinear), 42 m_calcMode(CalcModeLinear),
49 m_animationMode(NoAnimation) { 43 m_animationMode(NoAnimation) {
50 ASSERT(RuntimeEnabledFeatures::smilEnabled()); 44 ASSERT(RuntimeEnabledFeatures::smilEnabled());
51 UseCounter::count(document, UseCounter::SVGAnimationElement); 45 UseCounter::count(document, UseCounter::SVGAnimationElement);
52 } 46 }
53 47
54 bool SVGAnimationElement::parseValues(const String& value, 48 bool SVGAnimationElement::parseValues(const String& value,
55 Vector<String>& result) { 49 Vector<String>& result) {
56 // Per the SMIL specification, leading and trailing white space, 50 // Per the SMIL specification, leading and trailing white space, and white
57 // and white space before and after semicolon separators, is allowed and will be ignored. 51 // space before and after semicolon separators, is allowed and will be
52 // ignored.
58 // http://www.w3.org/TR/SVG11/animate.html#ValuesAttribute 53 // http://www.w3.org/TR/SVG11/animate.html#ValuesAttribute
59 result.clear(); 54 result.clear();
60 Vector<String> parseList; 55 Vector<String> parseList;
61 value.split(';', true, parseList); 56 value.split(';', true, parseList);
62 unsigned last = parseList.size() - 1; 57 unsigned last = parseList.size() - 1;
63 for (unsigned i = 0; i <= last; ++i) { 58 for (unsigned i = 0; i <= last; ++i) {
64 if (parseList[i].isEmpty()) { 59 if (parseList[i].isEmpty()) {
65 // Tolerate trailing ';' 60 // Tolerate trailing ';'
66 if (i < last) 61 if (i < last)
67 goto fail; 62 goto fail;
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 } 167 }
173 168
174 if (name == SVGNames::keyTimesAttr) { 169 if (name == SVGNames::keyTimesAttr) {
175 if (!parseKeyTimes(value, m_keyTimes, true)) 170 if (!parseKeyTimes(value, m_keyTimes, true))
176 reportAttributeParsingError(SVGParseStatus::ParsingFailed, name, value); 171 reportAttributeParsingError(SVGParseStatus::ParsingFailed, name, value);
177 return; 172 return;
178 } 173 }
179 174
180 if (name == SVGNames::keyPointsAttr) { 175 if (name == SVGNames::keyPointsAttr) {
181 if (isSVGAnimateMotionElement(*this)) { 176 if (isSVGAnimateMotionElement(*this)) {
182 // This is specified to be an animateMotion attribute only but it is simpl er to put it here 177 // This is specified to be an animateMotion attribute only but it is
183 // where the other timing calculatations are. 178 // simpler to put it here where the other timing calculatations are.
184 if (!parseKeyTimes(value, m_keyPoints, false)) 179 if (!parseKeyTimes(value, m_keyPoints, false))
185 reportAttributeParsingError(SVGParseStatus::ParsingFailed, name, value); 180 reportAttributeParsingError(SVGParseStatus::ParsingFailed, name, value);
186 } 181 }
187 return; 182 return;
188 } 183 }
189 184
190 if (name == SVGNames::keySplinesAttr) { 185 if (name == SVGNames::keySplinesAttr) {
191 if (!parseKeySplines(value, m_keySplines)) 186 if (!parseKeySplines(value, m_keySplines))
192 reportAttributeParsingError(SVGParseStatus::ParsingFailed, name, value); 187 reportAttributeParsingError(SVGParseStatus::ParsingFailed, name, value);
193 return; 188 return;
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 } 358 }
364 359
365 SVGAnimationElement::ShouldApplyAnimationType 360 SVGAnimationElement::ShouldApplyAnimationType
366 SVGAnimationElement::shouldApplyAnimation(SVGElement* targetElement, 361 SVGAnimationElement::shouldApplyAnimation(SVGElement* targetElement,
367 const QualifiedName& attributeName) { 362 const QualifiedName& attributeName) {
368 if (!hasValidAttributeType() || attributeName == anyQName() || 363 if (!hasValidAttributeType() || attributeName == anyQName() ||
369 !targetElement || !targetElement->inActiveDocument() || 364 !targetElement || !targetElement->inActiveDocument() ||
370 !targetElement->parentNode()) 365 !targetElement->parentNode())
371 return DontApplyAnimation; 366 return DontApplyAnimation;
372 367
373 // Always animate CSS properties, using the ApplyCSSAnimation code path, regar dless of the attributeType value. 368 // Always animate CSS properties using the ApplyCSSAnimation code path,
369 // regardless of the attributeType value.
374 if (isTargetAttributeCSSProperty(targetElement, attributeName)) { 370 if (isTargetAttributeCSSProperty(targetElement, attributeName)) {
375 if (targetElement->isPresentationAttributeWithSVGDOM(attributeName)) 371 if (targetElement->isPresentationAttributeWithSVGDOM(attributeName))
376 return ApplyXMLandCSSAnimation; 372 return ApplyXMLandCSSAnimation;
377 373
378 return ApplyCSSAnimation; 374 return ApplyCSSAnimation;
379 } 375 }
380 // If attributeType="CSS" and attributeName doesn't point to a CSS property, i gnore the animation. 376 // If attributeType="CSS" and attributeName doesn't point to a CSS property,
377 // ignore the animation.
381 if (getAttributeType() == AttributeTypeCSS) 378 if (getAttributeType() == AttributeTypeCSS)
382 return DontApplyAnimation; 379 return DontApplyAnimation;
383 380
384 return ApplyXMLAnimation; 381 return ApplyXMLAnimation;
385 } 382 }
386 383
387 void SVGAnimationElement::calculateKeyTimesForCalcModePaced() { 384 void SVGAnimationElement::calculateKeyTimesForCalcModePaced() {
388 ASSERT(getCalcMode() == CalcModePaced); 385 ASSERT(getCalcMode() == CalcModePaced);
389 ASSERT(getAnimationMode() == ValuesAnimation); 386 ASSERT(getAnimationMode() == ValuesAnimation);
390 387
391 unsigned valuesCount = m_values.size(); 388 unsigned valuesCount = m_values.size();
392 ASSERT(valuesCount >= 1); 389 ASSERT(valuesCount >= 1);
393 if (valuesCount == 1) 390 if (valuesCount == 1)
394 return; 391 return;
395 392
396 // FIXME, webkit.org/b/109010: m_keyTimes should not be modified in this funct ion. 393 // FIXME, webkit.org/b/109010: m_keyTimes should not be modified in this
394 // function.
397 m_keyTimes.clear(); 395 m_keyTimes.clear();
398 396
399 Vector<float> keyTimesForPaced; 397 Vector<float> keyTimesForPaced;
400 float totalDistance = 0; 398 float totalDistance = 0;
401 keyTimesForPaced.append(0); 399 keyTimesForPaced.append(0);
402 for (unsigned n = 0; n < valuesCount - 1; ++n) { 400 for (unsigned n = 0; n < valuesCount - 1; ++n) {
403 // Distance in any units 401 // Distance in any units
404 float distance = calculateDistance(m_values[n], m_values[n + 1]); 402 float distance = calculateDistance(m_values[n], m_values[n + 1]);
405 if (distance < 0) 403 if (distance < 0)
406 return; 404 return;
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
604 return; 602 return;
605 if ((animationMode == FromToAnimation || animationMode == FromByAnimation || 603 if ((animationMode == FromToAnimation || animationMode == FromByAnimation ||
606 animationMode == ToAnimation || animationMode == ByAnimation) && 604 animationMode == ToAnimation || animationMode == ByAnimation) &&
607 (fastHasAttribute(SVGNames::keyPointsAttr) && 605 (fastHasAttribute(SVGNames::keyPointsAttr) &&
608 fastHasAttribute(SVGNames::keyTimesAttr) && 606 fastHasAttribute(SVGNames::keyTimesAttr) &&
609 (m_keyTimes.size() < 2 || m_keyTimes.size() != m_keyPoints.size()))) 607 (m_keyTimes.size() < 2 || m_keyTimes.size() != m_keyPoints.size())))
610 return; 608 return;
611 if (animationMode == FromToAnimation) { 609 if (animationMode == FromToAnimation) {
612 m_animationValid = calculateFromAndToValues(from, to); 610 m_animationValid = calculateFromAndToValues(from, to);
613 } else if (animationMode == ToAnimation) { 611 } else if (animationMode == ToAnimation) {
614 // For to-animations the from value is the current accumulated value from lo wer priority animations. 612 // For to-animations the from value is the current accumulated value from
613 // lower priority animations.
615 // The value is not static and is determined during the animation. 614 // The value is not static and is determined during the animation.
616 m_animationValid = calculateFromAndToValues(emptyString(), to); 615 m_animationValid = calculateFromAndToValues(emptyString(), to);
617 } else if (animationMode == FromByAnimation) { 616 } else if (animationMode == FromByAnimation) {
618 m_animationValid = calculateFromAndByValues(from, by); 617 m_animationValid = calculateFromAndByValues(from, by);
619 } else if (animationMode == ByAnimation) { 618 } else if (animationMode == ByAnimation) {
620 m_animationValid = calculateFromAndByValues(emptyString(), by); 619 m_animationValid = calculateFromAndByValues(emptyString(), by);
621 } else if (animationMode == ValuesAnimation) { 620 } else if (animationMode == ValuesAnimation) {
622 m_animationValid = 621 m_animationValid =
623 m_values.size() >= 1 && (calcMode == CalcModePaced || 622 m_values.size() >= 1 && (calcMode == CalcModePaced ||
624 !fastHasAttribute(SVGNames::keyTimesAttr) || 623 !fastHasAttribute(SVGNames::keyTimesAttr) ||
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 effectivePercent = 673 effectivePercent =
675 calculatePercentForSpline(percent, calculateKeyTimesIndex(percent)); 674 calculatePercentForSpline(percent, calculateKeyTimesIndex(percent));
676 else if (animationMode == FromToAnimation || animationMode == ToAnimation) 675 else if (animationMode == FromToAnimation || animationMode == ToAnimation)
677 effectivePercent = calculatePercentForFromTo(percent); 676 effectivePercent = calculatePercentForFromTo(percent);
678 else 677 else
679 effectivePercent = percent; 678 effectivePercent = percent;
680 679
681 calculateAnimatedValue(effectivePercent, repeatCount, resultElement); 680 calculateAnimatedValue(effectivePercent, repeatCount, resultElement);
682 } 681 }
683 682
684 void SVGAnimationElement::computeCSSPropertyValue(SVGElement* element,
685 CSSPropertyID id,
686 String& value) {
687 ASSERT(element);
688 // FIXME: StyleEngine doesn't support document without a frame.
689 // Refer to comment in Element::computedStyle.
690 ASSERT(element->inActiveDocument());
691
692 // Don't include any properties resulting from CSS Transitions/Animations or S MIL animations, as we want to retrieve the "base value".
693 element->setUseOverrideComputedStyle(true);
694 value = CSSComputedStyleDeclaration::create(element)->getPropertyValue(id);
695 element->setUseOverrideComputedStyle(false);
696 }
697
698 void SVGAnimationElement::adjustForInheritance(
699 SVGElement* targetElement,
700 const QualifiedName& attributeName,
701 String& value) {
702 // FIXME: At the moment the computed style gets returned as a String and needs to get parsed again.
703 // In the future we might want to work with the value type directly to avoid t he String parsing.
704 ASSERT(targetElement);
705
706 Element* parent = targetElement->parentElement();
707 if (!parent || !parent->isSVGElement())
708 return;
709
710 SVGElement* svgParent = toSVGElement(parent);
711 computeCSSPropertyValue(svgParent, cssPropertyID(attributeName.localName()),
712 value);
713 }
714
715 static bool inheritsFromProperty(SVGElement* targetElement,
716 const QualifiedName& attributeName,
717 const String& value) {
718 ASSERT(targetElement);
719 DEFINE_STATIC_LOCAL(const AtomicString, inherit, ("inherit"));
720
721 if (value.isEmpty() || value != inherit)
722 return false;
723 return SVGElement::isAnimatableCSSProperty(attributeName);
724 }
725
726 void SVGAnimationElement::determinePropertyValueTypes(const String& from,
727 const String& to) {
728 SVGElement* targetElement = this->targetElement();
729 ASSERT(targetElement);
730
731 const QualifiedName& attributeName = this->attributeName();
732 if (inheritsFromProperty(targetElement, attributeName, from))
733 m_fromPropertyValueType = InheritValue;
734 if (inheritsFromProperty(targetElement, attributeName, to))
735 m_toPropertyValueType = InheritValue;
736 }
737
738 void SVGAnimationElement::setTargetElement(SVGElement* target) { 683 void SVGAnimationElement::setTargetElement(SVGElement* target) {
739 SVGSMILElement::setTargetElement(target); 684 SVGSMILElement::setTargetElement(target);
740 checkInvalidCSSAttributeType(); 685 checkInvalidCSSAttributeType();
741 } 686 }
742 687
743 void SVGAnimationElement::setAttributeName(const QualifiedName& attributeName) { 688 void SVGAnimationElement::setAttributeName(const QualifiedName& attributeName) {
744 SVGSMILElement::setAttributeName(attributeName); 689 SVGSMILElement::setAttributeName(attributeName);
745 checkInvalidCSSAttributeType(); 690 checkInvalidCSSAttributeType();
746 } 691 }
747 692
(...skipping 12 matching lines...) Expand all
760 if (!hasInvalidCSSAttributeType) 705 if (!hasInvalidCSSAttributeType)
761 schedule(); 706 schedule();
762 } 707 }
763 708
764 // Clear values that may depend on the previous target. 709 // Clear values that may depend on the previous target.
765 if (targetElement()) 710 if (targetElement())
766 clearAnimatedType(); 711 clearAnimatedType();
767 } 712 }
768 713
769 } // namespace blink 714 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/svg/SVGAnimationElement.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698