15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org>
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org>
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2008 Apple Inc. All rights reserved.
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) Research In Motion Limited 2011. All rights reserved.
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version.
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful,
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details.
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA.
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/svg/SVGAnimateElement.h"
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
275d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/CSSPropertyNames.h"
2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/StylePropertySet.h"
297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/css/parser/CSSParser.h"
305d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/dom/Document.h"
3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/QualifiedName.h"
32e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "core/svg/SVGAnimatedTypeAnimator.h"
33f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)#include "core/svg/SVGDocumentExtensions.h"
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
35c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
378abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)SVGAnimateElement::SVGAnimateElement(const QualifiedName& tagName, Document& document)
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : SVGAnimationElement(tagName, document)
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
42d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)PassRefPtrWillBeRawPtr<SVGAnimateElement> SVGAnimateElement::create(Document& document)
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
445d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    return adoptRefWillBeNoop(new SVGAnimateElement(SVGNames::animateTag, document));
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)SVGAnimateElement::~SVGAnimateElement()
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
51f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)AnimatedPropertyType SVGAnimateElement::animatedPropertyType()
52f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
53f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    return ensureAnimator()->type();
54f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
55f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool SVGAnimateElement::hasValidAttributeType()
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SVGElement* targetElement = this->targetElement();
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!targetElement)
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
62f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    return animatedPropertyType() != AnimatedUnknown && !hasInvalidCSSAttributeType();
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGSMILElement* resultElement)
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(resultElement);
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SVGElement* targetElement = this->targetElement();
6909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (!targetElement || !isSVGAnimateElement(*resultElement))
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(percentage >= 0 && percentage <= 1);
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_animator);
74f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    ASSERT(animatedPropertyType() != AnimatedTransformList || isSVGAnimateTransformElement(*this));
75f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    ASSERT(animatedPropertyType() != AnimatedUnknown);
76d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(m_fromProperty);
77f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    ASSERT(m_fromProperty->type() == animatedPropertyType());
78d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(m_toProperty);
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
80e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    SVGAnimateElement* resultAnimationElement = toSVGAnimateElement(resultElement);
81d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(resultAnimationElement->m_animatedProperty);
82f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    ASSERT(resultAnimationElement->animatedPropertyType() == animatedPropertyType());
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
84d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (isSVGSetElement(*this))
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        percentage = 1;
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (calcMode() == CalcModeDiscrete)
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        percentage = percentage < 0.5 ? 0 : 1;
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Target element might have changed.
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_animator->setContextElement(targetElement);
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Values-animation accumulates using the last values entry corresponding to the end of duration time.
9407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    SVGPropertyBase* toAtEndOfDurationProperty = m_toAtEndOfDurationProperty ? m_toAtEndOfDurationProperty.get() : m_toProperty.get();
95d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_animator->calculateAnimatedValue(percentage, repeatCount, m_fromProperty.get(), m_toProperty.get(), toAtEndOfDurationProperty, resultAnimationElement->m_animatedProperty.get());
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool SVGAnimateElement::calculateToAtEndOfDurationValue(const String& toAtEndOfDurationString)
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (toAtEndOfDurationString.isEmpty())
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
102d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_toAtEndOfDurationProperty = ensureAnimator()->constructFromString(toAtEndOfDurationString);
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return true;
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool SVGAnimateElement::calculateFromAndToValues(const String& fromString, const String& toString)
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SVGElement* targetElement = this->targetElement();
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!targetElement)
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    determinePropertyValueTypes(fromString, toString);
113d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ensureAnimator()->calculateFromAndToValues(m_fromProperty, m_toProperty, fromString, toString);
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return true;
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool SVGAnimateElement::calculateFromAndByValues(const String& fromString, const String& byString)
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SVGElement* targetElement = this->targetElement();
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!targetElement)
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (animationMode() == ByAnimation && !isAdditive())
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1269bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    // from-by animation may only be used with attributes that support addition (e.g. most numeric attributes).
1279bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    if (animationMode() == FromByAnimation && !animatedPropertyTypeSupportsAddition())
1289bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        return false;
1299bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
130d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(!isSVGSetElement(*this));
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    determinePropertyValueTypes(fromString, byString);
133d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ensureAnimator()->calculateFromAndByValues(m_fromProperty, m_toProperty, fromString, byString);
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return true;
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
137d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)namespace {
138d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
139d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)WillBeHeapVector<RawPtrWillBeMember<SVGElement> > findElementInstances(SVGElement* targetElement)
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
141d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(targetElement);
142d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    WillBeHeapVector<RawPtrWillBeMember<SVGElement> > animatedElements;
143d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
144d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    animatedElements.append(targetElement);
145d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
146323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >& instances = targetElement->instancesForElement();
147323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator end = instances.end();
148323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    for (WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator it = instances.begin(); it != end; ++it) {
149323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        if (SVGElement* shadowTreeElement = *it)
150d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            animatedElements.append(shadowTreeElement);
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
153d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return animatedElements;
154d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
155d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGAnimateElement::resetAnimatedType()
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SVGAnimatedTypeAnimator* animator = ensureAnimator();
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SVGElement* targetElement = this->targetElement();
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const QualifiedName& attributeName = this->attributeName();
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ShouldApplyAnimation shouldApply = shouldApplyAnimation(targetElement, attributeName);
165fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
166fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch    if (shouldApply == DontApplyAnimation)
167fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch        return;
168fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (shouldApply == ApplyXMLAnimation) {
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // SVG DOM animVal animation code-path.
171d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        WillBeHeapVector<RawPtrWillBeMember<SVGElement> > animatedElements = findElementInstances(targetElement);
172d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        ASSERT(!animatedElements.isEmpty());
173d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
174d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        WillBeHeapVector<RawPtrWillBeMember<SVGElement> >::const_iterator end = animatedElements.end();
175d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        for (WillBeHeapVector<RawPtrWillBeMember<SVGElement> >::const_iterator it = animatedElements.begin(); it != end; ++it)
176197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            addReferenceTo(*it);
177d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
178d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (!m_animatedProperty)
179d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            m_animatedProperty = animator->startAnimValAnimation(animatedElements);
180d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        else
181d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            m_animatedProperty = animator->resetAnimValToBaseVal(animatedElements);
182d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // CSS properties animation code-path.
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String baseValue;
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (shouldApply == ApplyCSSAnimation) {
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(SVGAnimationElement::isTargetAttributeCSSProperty(targetElement, attributeName));
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        computeCSSPropertyValue(targetElement, cssPropertyID(attributeName.localName()), baseValue);
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
194d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_animatedProperty = animator->constructFromString(baseValue);
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline void applyCSSPropertyToTarget(SVGElement* targetElement, CSSPropertyID id, const String& value)
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
199323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)#if !ENABLE(OILPAN)
2001e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ASSERT_WITH_SECURITY_IMPLICATION(!targetElement->m_deletionHasBegun);
201323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)#endif
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    MutableStylePropertySet* propertySet = targetElement->ensureAnimatedSMILStyleProperties();
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!propertySet->setProperty(id, value, false, 0))
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
207e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    targetElement->setNeedsStyleRecalc(LocalStyleChange);
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline void removeCSSPropertyFromTarget(SVGElement* targetElement, CSSPropertyID id)
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
212323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)#if !ENABLE(OILPAN)
2131e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ASSERT_WITH_SECURITY_IMPLICATION(!targetElement->m_deletionHasBegun);
214323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)#endif
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    targetElement->ensureAnimatedSMILStyleProperties()->removeProperty(id);
216e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    targetElement->setNeedsStyleRecalc(LocalStyleChange);
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline void applyCSSPropertyToTargetAndInstances(SVGElement* targetElement, const QualifiedName& attributeName, const String& valueAsString)
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(targetElement);
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (attributeName == anyQName() || !targetElement->inDocument() || !targetElement->parentNode())
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSPropertyID id = cssPropertyID(attributeName.localName());
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
227323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    SVGElement::InstanceUpdateBlocker blocker(targetElement);
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    applyCSSPropertyToTarget(targetElement, id, valueAsString);
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If the target element has instances, update them as well, w/o requiring the <use> tree to be rebuilt.
231323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >& instances = targetElement->instancesForElement();
232323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator end = instances.end();
233323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    for (WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator it = instances.begin(); it != end; ++it) {
234323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        if (SVGElement* shadowTreeElement = *it)
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            applyCSSPropertyToTarget(shadowTreeElement, id, valueAsString);
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline void removeCSSPropertyFromTargetAndInstances(SVGElement* targetElement, const QualifiedName& attributeName)
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(targetElement);
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (attributeName == anyQName() || !targetElement->inDocument() || !targetElement->parentNode())
2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CSSPropertyID id = cssPropertyID(attributeName.localName());
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
247323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    SVGElement::InstanceUpdateBlocker blocker(targetElement);
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    removeCSSPropertyFromTarget(targetElement, id);
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If the target element has instances, update them as well, w/o requiring the <use> tree to be rebuilt.
251323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >& instances = targetElement->instancesForElement();
252323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator end = instances.end();
253323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    for (WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator it = instances.begin(); it != end; ++it) {
254323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        if (SVGElement* shadowTreeElement = *it)
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            removeCSSPropertyFromTarget(shadowTreeElement, id);
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline void notifyTargetAboutAnimValChange(SVGElement* targetElement, const QualifiedName& attributeName)
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
261323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)#if !ENABLE(OILPAN)
2621e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ASSERT_WITH_SECURITY_IMPLICATION(!targetElement->m_deletionHasBegun);
263323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)#endif
264d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    targetElement->invalidateSVGAttributes();
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    targetElement->svgAttributeChanged(attributeName);
2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline void notifyTargetAndInstancesAboutAnimValChange(SVGElement* targetElement, const QualifiedName& attributeName)
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(targetElement);
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (attributeName == anyQName() || !targetElement->inDocument() || !targetElement->parentNode())
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
274323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    SVGElement::InstanceUpdateBlocker blocker(targetElement);
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    notifyTargetAboutAnimValChange(targetElement, attributeName);
2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If the target element has instances, update them as well, w/o requiring the <use> tree to be rebuilt.
278323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >& instances = targetElement->instancesForElement();
279323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator end = instances.end();
280323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    for (WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator it = instances.begin(); it != end; ++it) {
281d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        notifyTargetAboutAnimValChange(*it, attributeName);
2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGAnimateElement::clearAnimatedType(SVGElement* targetElement)
2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
287d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!m_animatedProperty)
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!targetElement) {
291d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_animatedProperty.clear();
2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
295d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if (ensureAnimator()->isAnimatingCSSProperty()) {
2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // CSS properties animation code-path.
2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        removeCSSPropertyFromTargetAndInstances(targetElement, attributeName());
298d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_animatedProperty.clear();
2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // SVG DOM animVal animation code-path.
3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_animator) {
304d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        WillBeHeapVector<RawPtrWillBeMember<SVGElement> > animatedElements = findElementInstances(targetElement);
305d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        m_animator->stopAnimValAnimation(animatedElements);
3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        notifyTargetAndInstancesAboutAnimValChange(targetElement, attributeName());
3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
309d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_animatedProperty.clear();
3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGAnimateElement::applyResultsToTarget()
3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_animator);
315f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    ASSERT(animatedPropertyType() != AnimatedTransformList || isSVGAnimateTransformElement(*this));
316f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    ASSERT(animatedPropertyType() != AnimatedUnknown);
3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Early exit if our animated type got destructed by a previous endedActiveInterval().
319d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!m_animatedProperty)
3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
322f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    if (m_animator->isAnimatingCSSProperty()) {
3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // CSS properties animation code-path.
3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Convert the result of the animation to a String and apply it as CSS property on the target & all instances.
325d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        applyCSSPropertyToTargetAndInstances(targetElement(), attributeName(), m_animatedProperty->valueAsString());
3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // SVG DOM animVal animation code-path.
3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // At this point the SVG DOM values are already changed, unlike for CSS.
3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // We only have to trigger update notifications here.
3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    notifyTargetAndInstancesAboutAnimValChange(targetElement(), attributeName());
3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
335f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)bool SVGAnimateElement::animatedPropertyTypeSupportsAddition()
3369bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles){
3379bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    // Spec: http://www.w3.org/TR/SVG/animate.html#AnimationAttributesAndProperties.
338f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    switch (animatedPropertyType()) {
3399bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    case AnimatedBoolean:
3409bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    case AnimatedEnumeration:
3419bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    case AnimatedPreserveAspectRatio:
3429bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    case AnimatedString:
3439bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    case AnimatedUnknown:
3449bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        return false;
3459bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    default:
3469bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        return true;
3479bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    }
3489bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)}
3499bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
350f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)bool SVGAnimateElement::isAdditive()
3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3529bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    if (animationMode() == ByAnimation || animationMode() == FromByAnimation)
3539bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        if (!animatedPropertyTypeSupportsAddition())
3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return false;
3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return SVGAnimationElement::isAdditive();
3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float SVGAnimateElement::calculateDistance(const String& fromString, const String& toString)
3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: A return value of float is not enough to support paced animations on lists.
3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SVGElement* targetElement = this->targetElement();
3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!targetElement)
3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return -1;
3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return ensureAnimator()->calculateDistance(fromString, toString);
3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
369926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void SVGAnimateElement::setTargetElement(SVGElement* target)
3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
371926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    SVGAnimationElement::setTargetElement(target);
372926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    resetAnimatedPropertyType();
373926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
375926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void SVGAnimateElement::setAttributeName(const QualifiedName& attributeName)
376926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
377926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    SVGAnimationElement::setAttributeName(attributeName);
378926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    resetAnimatedPropertyType();
379926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
380926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
381926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void SVGAnimateElement::resetAnimatedPropertyType()
382926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
383d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(!m_animatedProperty);
384d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_fromProperty.clear();
385d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_toProperty.clear();
386d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_toAtEndOfDurationProperty.clear();
3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_animator.clear();
3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)SVGAnimatedTypeAnimator* SVGAnimateElement::ensureAnimator()
3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_animator)
393f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        m_animator = SVGAnimatedTypeAnimator::create(this, targetElement());
3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_animator.get();
3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
397d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void SVGAnimateElement::trace(Visitor* visitor)
398d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){
399d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    visitor->trace(m_animator);
400d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    SVGAnimationElement::trace(visitor);
401d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)}
402d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
404