Title: [243259] trunk/Source/WebCore
Revision
243259
Author
[email protected]
Date
2019-03-20 16:51:47 -0700 (Wed, 20 Mar 2019)

Log Message

Remove the SVG tear off objects for SVGColorAnimator
https://bugs.webkit.org/show_bug.cgi?id=196025

Reviewed by Simon Fraser.

SVG attributes like "fill" and "stroke" do not have reflecting properties
in SVGElement but they are animatable by SMIL. Animating such attributes
is different from animating the SVG animated properties. These new classes
will be added to handle the first type of this kind of attribute: the Color:

-- SVGPropertyAnimatorCreator is added to SVGElement. It is responsible 
   for creating SVGPropertyAnimators for the attribute which do not have
   reflecting animated properties stored by SVGElement. It will maintain
   a HashMap for the animated values for these attributes which is indexed
   by the attribute name. The animated values has to be RefCounted because
   the same attribute can be animated by multiple animators. So the values
   of this HashMap will be of type Ref<SVGProperty>, e.g.
    <circle cx="80" cy="120" r="35">
        <animate attributeName="fill" values="#080" begin="2s" />
        <animate attributeName="fill" values="#602;#004" begin="4s" dur="5s"/>
    </circle>

-- SVGPropertyAnimator is the a new type which animates an attribute with
   no reflecting animated property.

-- SVGPrimitivePropertyAnimator is a template class which is responsible
   for animating attributes with primitive types, e.g. Color, string and 
   float. It is derived form SVGPropertyAnimator and it is initialized 
   with a Ref<SVGValueProperty<PropertyType>> which is created and maintained
   by SVGPropertyAnimatorFactory.

-- SVGAnimationColorFunction is the animation function that animates the
   attributes whose type are Color. Note the conversion form String to 
   Color in this class has to handle the case when its value is "attributeName="
   e.g. <animate attributeName="fill" from="attributeName="r"/>

-- SVGColorAnimator will be defined to be
   SVGPrimitivePropertyAnimator<Color, SVGAnimationColorFunction>.

The life cycle of the RefCounted properties can be explained as follows:

-- SVGPropertyAnimatorFactory checks whether its HashMap has an entry
   for the given attribute name. If it does not have, it will create a
   new value through the value creation method for this attribute.

-- SVGPropertyAnimatorFactory passes the shared animated value to the
   animator creation method. So multiple animators will be accessing the
   same value through their RefCounted pointers.

-- When the animator is about to be deleted, it will notify the target
   SVGElement which will notify its SVGPropertyAnimatorFactory.
   SVGPropertyAnimatorFactory will check its HashMap and retrieves the
   entry for the given attribute name. If the refCount is 2, it is going
   to remove the entry form the HashMap.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* svg/SVGAnimateColorElement.cpp:
(WebCore::attributeValueIsCurrentColor): Deleted.
(WebCore::SVGAnimateColorElement::determinePropertyValueTypes): Deleted.
* svg/SVGAnimateColorElement.h:
* svg/SVGAnimateElementBase.cpp:
(WebCore::SVGAnimateElementBase::attributeAnimationController):
* svg/SVGAnimatedColor.cpp: Removed.
* svg/SVGAnimatedColor.h: Removed.
* svg/SVGAnimatorFactory.h:
(WebCore::SVGAnimatorFactory::create):
* svg/SVGAttributeAnimationController.cpp:
(WebCore::SVGAttributeAnimationController::~SVGAttributeAnimationController):
* svg/SVGAttributeAnimationController.h:
* svg/SVGElement.cpp:
(WebCore::SVGElement::SVGElement):
(WebCore::SVGElement::isAnimatedAttribute const):
(WebCore::SVGElement::createAnimator):
(WebCore::SVGElement::animatorWillBeDeleted):
* svg/SVGElement.h:
(WebCore::SVGElement::propertyAnimatorFactory):
* svg/SVGFitToViewBox.h:
* svg/SVGMPathElement.cpp:
* svg/graphics/filters/SVGFEImage.h:
* svg/properties/SVGAnimationAdditiveValueFunctionImpl.cpp: Added.
(WebCore::SVGAnimationColorFunction::colorFromString):
* svg/properties/SVGAnimationAdditiveValueFunctionImpl.h:
(WebCore::SVGAnimationColorFunction::progress):
* svg/properties/SVGAnimationFunction.h:
* svg/properties/SVGAttributeAnimator.cpp:
(WebCore::SVGAttributeAnimator::applyAnimatedStylePropertyChange):
(WebCore::SVGAttributeAnimator::removeAnimatedStyleProperty):
* svg/properties/SVGAttributeAnimator.h:
* svg/properties/SVGPrimitivePropertyAnimator.h: Added.
(WebCore::SVGPrimitivePropertyAnimator::create):
(WebCore::SVGPrimitivePropertyAnimator::SVGPrimitivePropertyAnimator):
* svg/properties/SVGPrimitivePropertyAnimatorImpl.h: Added.
* svg/properties/SVGPropertyAnimator.h: Added.
(WebCore::SVGPropertyAnimator::SVGPropertyAnimator):
(WebCore::SVGPropertyAnimator::adjustForInheritance const):
(WebCore::SVGPropertyAnimator::computeCSSPropertyValue const):
(WebCore::SVGPropertyAnimator::computeInheritedCSSPropertyValue const):
* svg/properties/SVGPropertyAnimatorFactory.h: Added.
(WebCore::SVGPropertyAnimatorFactory::isKnownAttribute):
(WebCore::SVGPropertyAnimatorFactory::createAnimator):
(WebCore::SVGPropertyAnimatorFactory::animatorWillBeDeleted):
(WebCore::SVGPropertyAnimatorFactory::createColorAnimator):
(WebCore::SVGPropertyAnimatorFactory::attributeAnimatorCreator):

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (243258 => 243259)


--- trunk/Source/WebCore/ChangeLog	2019-03-20 23:37:54 UTC (rev 243258)
+++ trunk/Source/WebCore/ChangeLog	2019-03-20 23:51:47 UTC (rev 243259)
@@ -1,3 +1,110 @@
+2019-03-20  Said Abou-Hallawa  <[email protected]>
+
+        Remove the SVG tear off objects for SVGColorAnimator
+        https://bugs.webkit.org/show_bug.cgi?id=196025
+
+        Reviewed by Simon Fraser.
+
+        SVG attributes like "fill" and "stroke" do not have reflecting properties
+        in SVGElement but they are animatable by SMIL. Animating such attributes
+        is different from animating the SVG animated properties. These new classes
+        will be added to handle the first type of this kind of attribute: the Color:
+
+        -- SVGPropertyAnimatorCreator is added to SVGElement. It is responsible 
+           for creating SVGPropertyAnimators for the attribute which do not have
+           reflecting animated properties stored by SVGElement. It will maintain
+           a HashMap for the animated values for these attributes which is indexed
+           by the attribute name. The animated values has to be RefCounted because
+           the same attribute can be animated by multiple animators. So the values
+           of this HashMap will be of type Ref<SVGProperty>, e.g.
+            <circle cx="80" cy="120" r="35">
+                <animate attributeName="fill" values="#080" begin="2s" />
+                <animate attributeName="fill" values="#602;#004" begin="4s" dur="5s"/>
+            </circle>
+
+        -- SVGPropertyAnimator is the a new type which animates an attribute with
+           no reflecting animated property.
+
+        -- SVGPrimitivePropertyAnimator is a template class which is responsible
+           for animating attributes with primitive types, e.g. Color, string and 
+           float. It is derived form SVGPropertyAnimator and it is initialized 
+           with a Ref<SVGValueProperty<PropertyType>> which is created and maintained
+           by SVGPropertyAnimatorFactory.
+
+        -- SVGAnimationColorFunction is the animation function that animates the
+           attributes whose type are Color. Note the conversion form String to 
+           Color in this class has to handle the case when its value is "attributeName="
+           e.g. <animate attributeName="fill" from="attributeName="r"/>
+
+        -- SVGColorAnimator will be defined to be
+           SVGPrimitivePropertyAnimator<Color, SVGAnimationColorFunction>.
+
+        The life cycle of the RefCounted properties can be explained as follows:
+
+        -- SVGPropertyAnimatorFactory checks whether its HashMap has an entry
+           for the given attribute name. If it does not have, it will create a
+           new value through the value creation method for this attribute.
+
+        -- SVGPropertyAnimatorFactory passes the shared animated value to the
+           animator creation method. So multiple animators will be accessing the
+           same value through their RefCounted pointers.
+
+        -- When the animator is about to be deleted, it will notify the target
+           SVGElement which will notify its SVGPropertyAnimatorFactory.
+           SVGPropertyAnimatorFactory will check its HashMap and retrieves the
+           entry for the given attribute name. If the refCount is 2, it is going
+           to remove the entry form the HashMap.
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * svg/SVGAnimateColorElement.cpp:
+        (WebCore::attributeValueIsCurrentColor): Deleted.
+        (WebCore::SVGAnimateColorElement::determinePropertyValueTypes): Deleted.
+        * svg/SVGAnimateColorElement.h:
+        * svg/SVGAnimateElementBase.cpp:
+        (WebCore::SVGAnimateElementBase::attributeAnimationController):
+        * svg/SVGAnimatedColor.cpp: Removed.
+        * svg/SVGAnimatedColor.h: Removed.
+        * svg/SVGAnimatorFactory.h:
+        (WebCore::SVGAnimatorFactory::create):
+        * svg/SVGAttributeAnimationController.cpp:
+        (WebCore::SVGAttributeAnimationController::~SVGAttributeAnimationController):
+        * svg/SVGAttributeAnimationController.h:
+        * svg/SVGElement.cpp:
+        (WebCore::SVGElement::SVGElement):
+        (WebCore::SVGElement::isAnimatedAttribute const):
+        (WebCore::SVGElement::createAnimator):
+        (WebCore::SVGElement::animatorWillBeDeleted):
+        * svg/SVGElement.h:
+        (WebCore::SVGElement::propertyAnimatorFactory):
+        * svg/SVGFitToViewBox.h:
+        * svg/SVGMPathElement.cpp:
+        * svg/graphics/filters/SVGFEImage.h:
+        * svg/properties/SVGAnimationAdditiveValueFunctionImpl.cpp: Added.
+        (WebCore::SVGAnimationColorFunction::colorFromString):
+        * svg/properties/SVGAnimationAdditiveValueFunctionImpl.h:
+        (WebCore::SVGAnimationColorFunction::progress):
+        * svg/properties/SVGAnimationFunction.h:
+        * svg/properties/SVGAttributeAnimator.cpp:
+        (WebCore::SVGAttributeAnimator::applyAnimatedStylePropertyChange):
+        (WebCore::SVGAttributeAnimator::removeAnimatedStyleProperty):
+        * svg/properties/SVGAttributeAnimator.h:
+        * svg/properties/SVGPrimitivePropertyAnimator.h: Added.
+        (WebCore::SVGPrimitivePropertyAnimator::create):
+        (WebCore::SVGPrimitivePropertyAnimator::SVGPrimitivePropertyAnimator):
+        * svg/properties/SVGPrimitivePropertyAnimatorImpl.h: Added.
+        * svg/properties/SVGPropertyAnimator.h: Added.
+        (WebCore::SVGPropertyAnimator::SVGPropertyAnimator):
+        (WebCore::SVGPropertyAnimator::adjustForInheritance const):
+        (WebCore::SVGPropertyAnimator::computeCSSPropertyValue const):
+        (WebCore::SVGPropertyAnimator::computeInheritedCSSPropertyValue const):
+        * svg/properties/SVGPropertyAnimatorFactory.h: Added.
+        (WebCore::SVGPropertyAnimatorFactory::isKnownAttribute):
+        (WebCore::SVGPropertyAnimatorFactory::createAnimator):
+        (WebCore::SVGPropertyAnimatorFactory::animatorWillBeDeleted):
+        (WebCore::SVGPropertyAnimatorFactory::createColorAnimator):
+        (WebCore::SVGPropertyAnimatorFactory::attributeAnimatorCreator):
+
 2019-03-20  Alex Christensen  <[email protected]>
 
         Use WeakPtr instead of storing raw pointers in WebSocket code

Modified: trunk/Source/WebCore/Sources.txt (243258 => 243259)


--- trunk/Source/WebCore/Sources.txt	2019-03-20 23:37:54 UTC (rev 243258)
+++ trunk/Source/WebCore/Sources.txt	2019-03-20 23:51:47 UTC (rev 243259)
@@ -2270,7 +2270,6 @@
 svg/SVGAnimateMotionElement.cpp
 svg/SVGAnimateTransformElement.cpp
 svg/SVGAnimatedAngle.cpp
-svg/SVGAnimatedColor.cpp
 svg/SVGAnimatedEnumeration.cpp
 svg/SVGAnimatedLength.cpp
 svg/SVGAnimatedLengthList.cpp
@@ -2422,6 +2421,7 @@
 
 svg/properties/SVGAnimatedPathSegListPropertyTearOff.cpp
 svg/properties/SVGAnimatedProperty.cpp
+svg/properties/SVGAnimationAdditiveValueFunctionImpl.cpp
 svg/properties/SVGAttributeAnimator.cpp
 svg/properties/SVGAttributeOwnerProxy.cpp
 svg/properties/SVGLegacyAnimatedProperty.cpp

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (243258 => 243259)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2019-03-20 23:37:54 UTC (rev 243258)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2019-03-20 23:51:47 UTC (rev 243259)
@@ -1223,7 +1223,6 @@
 		439D334313A6911C00C20F4F /* SVGAnimatedType.h in Headers */ = {isa = PBXBuildFile; fileRef = 439D334013A6911C00C20F4F /* SVGAnimatedType.h */; };
 		439D334413A6911C00C20F4F /* SVGAnimatedTypeAnimator.h in Headers */ = {isa = PBXBuildFile; fileRef = 439D334113A6911C00C20F4F /* SVGAnimatedTypeAnimator.h */; };
 		439D334513A6911C00C20F4F /* SVGAnimatorFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 439D334213A6911C00C20F4F /* SVGAnimatorFactory.h */; };
-		43A625F813B3304000AC94B8 /* SVGAnimatedColor.h in Headers */ = {isa = PBXBuildFile; fileRef = 43A625F613B3304000AC94B8 /* SVGAnimatedColor.h */; };
 		43B85ED418CBEC5200E31AF4 /* SelectorPseudoClassAndCompatibilityElementMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43B85ED218CBEC5200E31AF4 /* SelectorPseudoClassAndCompatibilityElementMap.cpp */; };
 		43B9336913B261B1004584BF /* SVGAnimatedPointList.h in Headers */ = {isa = PBXBuildFile; fileRef = 43B9336713B261B1004584BF /* SVGAnimatedPointList.h */; };
 		43C092BC12D9E4EE00A989C3 /* RenderSVGForeignObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 43C092BA12D9E4EE00A989C3 /* RenderSVGForeignObject.h */; };
@@ -7671,8 +7670,6 @@
 		439D334113A6911C00C20F4F /* SVGAnimatedTypeAnimator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGAnimatedTypeAnimator.h; sourceTree = "<group>"; };
 		439D334213A6911C00C20F4F /* SVGAnimatorFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGAnimatorFactory.h; sourceTree = "<group>"; };
 		43A0F0B013AC7D6D00A5F0A7 /* SVGAnimatedNumber.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGAnimatedNumber.cpp; sourceTree = "<group>"; };
-		43A625F613B3304000AC94B8 /* SVGAnimatedColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGAnimatedColor.h; sourceTree = "<group>"; };
-		43A625F713B3304000AC94B8 /* SVGAnimatedColor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGAnimatedColor.cpp; sourceTree = "<group>"; };
 		43A6266613B3D11000AC94B8 /* SVGAnimatedString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGAnimatedString.cpp; sourceTree = "<group>"; };
 		43B85ED018CBEACE00E31AF4 /* makeSelectorPseudoClassAndCompatibilityElementMap.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = makeSelectorPseudoClassAndCompatibilityElementMap.py; sourceTree = "<group>"; };
 		43B85ED218CBEC5200E31AF4 /* SelectorPseudoClassAndCompatibilityElementMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SelectorPseudoClassAndCompatibilityElementMap.cpp; path = DerivedSources/WebCore/SelectorPseudoClassAndCompatibilityElementMap.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -9527,6 +9524,11 @@
 		724ED3301A3A8B2300F5F13C /* JSEXTBlendMinMax.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSEXTBlendMinMax.h; sourceTree = "<group>"; };
 		724EE54E1DC7F25B00A91FFB /* ActivityState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ActivityState.h; sourceTree = "<group>"; };
 		724EE54F1DC7F25B00A91FFB /* ActivityStateChangeObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ActivityStateChangeObserver.h; sourceTree = "<group>"; };
+		7266F0132241BCE200833975 /* SVGPropertyAnimatorFactory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SVGPropertyAnimatorFactory.h; sourceTree = "<group>"; };
+		7266F0142241BFB200833975 /* SVGPrimitivePropertyAnimatorImpl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SVGPrimitivePropertyAnimatorImpl.h; sourceTree = "<group>"; };
+		7266F0152241C09800833975 /* SVGPrimitivePropertyAnimator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SVGPrimitivePropertyAnimator.h; sourceTree = "<group>"; };
+		7266F0162241C0FE00833975 /* SVGPropertyAnimator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SVGPropertyAnimator.h; sourceTree = "<group>"; };
+		7266F01822429CFD00833975 /* SVGAnimationAdditiveValueFunctionImpl.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = SVGAnimationAdditiveValueFunctionImpl.cpp; sourceTree = "<group>"; };
 		727AFED11A2EA6A0000442E8 /* EXTsRGB.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EXTsRGB.cpp; sourceTree = "<group>"; };
 		727AFED21A2EA6A0000442E8 /* EXTsRGB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EXTsRGB.h; sourceTree = "<group>"; };
 		727AFED31A2EA6A0000442E8 /* EXTsRGB.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = EXTsRGB.idl; sourceTree = "<group>"; };
@@ -16235,6 +16237,7 @@
 				721443452240C8BA00F12FF7 /* SVGAnimatedValueProperty.h */,
 				55BE025F223B29C50032F08A /* SVGAnimationAdditiveFunction.h */,
 				55EE535E223B2A0E00FBA944 /* SVGAnimationAdditiveValueFunction.h */,
+				7266F01822429CFD00833975 /* SVGAnimationAdditiveValueFunctionImpl.cpp */,
 				55BE0259223B29C10032F08A /* SVGAnimationAdditiveValueFunctionImpl.h */,
 				55DCC51D2240615500C26E32 /* SVGAnimationDiscreteFunction.h */,
 				55DCC51C2240605E00C26E32 /* SVGAnimationDiscreteFunctionImpl.h */,
@@ -16257,9 +16260,13 @@
 				55EE5354223B29E900FBA944 /* SVGMemberAccessor.h */,
 				55BE025A223B29C20032F08A /* SVGPointerMemberAccessor.h */,
 				55DCC5252240749E00C26E32 /* SVGPrimitiveList.h */,
+				7266F0152241C09800833975 /* SVGPrimitivePropertyAnimator.h */,
+				7266F0142241BFB200833975 /* SVGPrimitivePropertyAnimatorImpl.h */,
 				55EE5363223B2A2400FBA944 /* SVGProperty.h */,
 				55DCC526224074FA00C26E32 /* SVGPropertyAccessor.h */,
 				55DCC5272240750B00C26E32 /* SVGPropertyAccessorImpl.h */,
+				7266F0162241C0FE00833975 /* SVGPropertyAnimator.h */,
+				7266F0132241BCE200833975 /* SVGPropertyAnimatorFactory.h */,
 				55EE5360223B2A2100FBA944 /* SVGPropertyOwner.h */,
 				55BE025C223B29C30032F08A /* SVGPropertyOwnerRegistry.h */,
 				55BE0257223B29C00032F08A /* SVGPropertyRegistry.h */,
@@ -24129,8 +24136,6 @@
 				087B84951272CEC700A14417 /* SVGAnimatedAngle.h */,
 				B22277E60D00BF1F0071B782 /* SVGAnimatedAngle.idl */,
 				B22277E70D00BF1F0071B782 /* SVGAnimatedBoolean.idl */,
-				43A625F713B3304000AC94B8 /* SVGAnimatedColor.cpp */,
-				43A625F613B3304000AC94B8 /* SVGAnimatedColor.h */,
 				71CC7A1F152A0BFE009EEAF9 /* SVGAnimatedEnumeration.cpp */,
 				08D46CE2127AD5FC0089694B /* SVGAnimatedEnumeration.h */,
 				B22277E80D00BF1F0071B782 /* SVGAnimatedEnumeration.idl */,
@@ -31921,7 +31926,6 @@
 				B22279770D00BF220071B782 /* SVGAngle.h in Headers */,
 				B222797A0D00BF220071B782 /* SVGAnimateColorElement.h in Headers */,
 				087B84961272CEC800A14417 /* SVGAnimatedAngle.h in Headers */,
-				43A625F813B3304000AC94B8 /* SVGAnimatedColor.h in Headers */,
 				08D46CE3127AD5FC0089694B /* SVGAnimatedEnumeration.h in Headers */,
 				71FB967B1383D64600AC8A4C /* SVGAnimatedEnumerationPropertyTearOff.h in Headers */,
 				089021A9126EF5DE0092D5EA /* SVGAnimatedLength.h in Headers */,

Modified: trunk/Source/WebCore/svg/SVGAnimateColorElement.cpp (243258 => 243259)


--- trunk/Source/WebCore/svg/SVGAnimateColorElement.cpp	2019-03-20 23:37:54 UTC (rev 243258)
+++ trunk/Source/WebCore/svg/SVGAnimateColorElement.cpp	2019-03-20 23:51:47 UTC (rev 243259)
@@ -40,19 +40,4 @@
     return adoptRef(*new SVGAnimateColorElement(tagName, document));
 }
 
-static bool attributeValueIsCurrentColor(const String& value)
-{
-    static NeverDestroyed<const AtomicString> currentColor("currentColor", AtomicString::ConstructFromLiteral);
-    return value == currentColor;
 }
-
-void SVGAnimateColorElement::determinePropertyValueTypes(const String& from, const String& to)
-{
-    SVGAnimateElementBase::determinePropertyValueTypes(from, to);
-    if (attributeValueIsCurrentColor(from))
-        m_fromPropertyValueType = CurrentColorValue;
-    if (attributeValueIsCurrentColor(to))
-        m_toPropertyValueType = CurrentColorValue;
-}
-
-}

Modified: trunk/Source/WebCore/svg/SVGAnimateColorElement.h (243258 => 243259)


--- trunk/Source/WebCore/svg/SVGAnimateColorElement.h	2019-03-20 23:37:54 UTC (rev 243258)
+++ trunk/Source/WebCore/svg/SVGAnimateColorElement.h	2019-03-20 23:51:47 UTC (rev 243259)
@@ -32,7 +32,6 @@
 
 private:
     SVGAnimateColorElement(const QualifiedName&, Document&);
-    void determinePropertyValueTypes(const String& from, const String& to) override;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/svg/SVGAnimateElementBase.cpp (243258 => 243259)


--- trunk/Source/WebCore/svg/SVGAnimateElementBase.cpp	2019-03-20 23:37:54 UTC (rev 243258)
+++ trunk/Source/WebCore/svg/SVGAnimateElementBase.cpp	2019-03-20 23:51:47 UTC (rev 243259)
@@ -49,7 +49,7 @@
     ASSERT(!hasInvalidCSSAttributeType());
 
     if (!m_attributeAnimationController) {
-        if (targetElement()->isAnimatedPropertyAttribute(attributeName()))
+        if (targetElement()->isAnimatedAttribute(attributeName()))
             m_attributeAnimationController = std::make_unique<SVGAttributeAnimationController>(*this, *targetElement());
         else
             m_attributeAnimationController = std::make_unique<SVGLegacyAttributeAnimationController>(*this, *targetElement());

Deleted: trunk/Source/WebCore/svg/SVGAnimatedColor.cpp (243258 => 243259)


--- trunk/Source/WebCore/svg/SVGAnimatedColor.cpp	2019-03-20 23:37:54 UTC (rev 243258)
+++ trunk/Source/WebCore/svg/SVGAnimatedColor.cpp	2019-03-20 23:51:47 UTC (rev 243259)
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2011. All rights reserved.
- * Copyright (C) 2018 Apple Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-#include "SVGAnimatedColor.h"
-
-#include "CSSParser.h"
-#include "RenderElement.h"
-#include "SVGAnimateElementBase.h"
-
-namespace WebCore {
-
-SVGAnimatedColorAnimator::SVGAnimatedColorAnimator(SVGAnimationElement& animationElement, SVGElement& contextElement)
-    : SVGAnimatedTypeAnimator(AnimatedColor, &animationElement, &contextElement)
-{
-}
-
-std::unique_ptr<SVGAnimatedType> SVGAnimatedColorAnimator::constructFromString(const String& string)
-{
-    return SVGAnimatedType::create(SVGPropertyTraits<Color>::fromString(string));
-}
-
-void SVGAnimatedColorAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimatedType* to)
-{
-    ASSERT(from);
-    ASSERT(to);
-    ASSERT(from->type() == AnimatedColor);
-    ASSERT(to->type() == AnimatedColor);
-
-    // Ignores any alpha and sets alpha on result to 100% opaque.
-    const auto& fromColor = from->as<Color>();
-    auto& toColor = to->as<Color>();
-    toColor = { roundAndClampColorChannel(toColor.red() + fromColor.red()),
-        roundAndClampColorChannel(toColor.green() + fromColor.green()),
-        roundAndClampColorChannel(toColor.blue() + fromColor.blue()) };
-}
-
-static inline Color currentColor(SVGElement& targetElement)
-{
-    RenderElement* targetRenderer = targetElement.renderer();
-    if (!targetRenderer)
-        return { };
-    return targetRenderer->style().visitedDependentColor(CSSPropertyColor);
-}
-
-static Color parseColorFromString(SVGAnimationElement*, const String& string)
-{
-    return CSSParser::parseColor(string.stripWhiteSpace());
-}
-
-void SVGAnimatedColorAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated)
-{
-    ASSERT(m_animationElement);
-    ASSERT(m_contextElement);
-
-    auto fromColor = (m_animationElement->animationMode() == AnimationMode::To ? animated : from)->as<Color>();
-    auto toColor = to->as<Color>();
-
-    // Apply CSS inheritance rules.
-    m_animationElement->adjustForInheritance<Color>(parseColorFromString, m_animationElement->fromPropertyValueType(), fromColor, m_contextElement);
-    m_animationElement->adjustForInheritance<Color>(parseColorFromString, m_animationElement->toPropertyValueType(), toColor, m_contextElement);
-
-    // Apply <animateColor> rules.
-    if (m_animationElement->fromPropertyValueType() == CurrentColorValue)
-        fromColor = currentColor(*m_contextElement);
-    if (m_animationElement->toPropertyValueType() == CurrentColorValue)
-        toColor = currentColor(*m_contextElement);
-
-    const auto& toAtEndOfDurationColor = toAtEndOfDuration->as<Color>();
-    auto& animatedColor = animated->as<Color>();
-
-    // FIXME: ExtendedColor - this will need to handle blending between colors in different color spaces,
-    // as well as work with non [0-255] Colors.
-    float red = animatedColor.red();
-    m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.red(), toColor.red(), toAtEndOfDurationColor.red(), red);
-
-    float green = animatedColor.green();
-    m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.green(), toColor.green(), toAtEndOfDurationColor.green(), green);
-
-    float blue = animatedColor.blue();
-    m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.blue(), toColor.blue(), toAtEndOfDurationColor.blue(), blue);
-
-    float alpha = animatedColor.alpha();
-    m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.alpha(), toColor.alpha(), toAtEndOfDurationColor.alpha(), alpha);
-
-    animatedColor = { roundAndClampColorChannel(red), roundAndClampColorChannel(green), roundAndClampColorChannel(blue), roundAndClampColorChannel(alpha) };
-}
-
-float SVGAnimatedColorAnimator::calculateDistance(const String& fromString, const String& toString)
-{
-    Color from = CSSParser::parseColor(fromString.stripWhiteSpace());
-    if (!from.isValid())
-        return -1;
-    Color to = CSSParser::parseColor(toString.stripWhiteSpace());
-    if (!to.isValid())
-        return -1;
-    float red = from.red() - to.red();
-    float green = from.green() - to.green();
-    float blue = from.blue() - to.blue();
-    return sqrtf(red * red + green * green + blue * blue);
-}
-
-}

Deleted: trunk/Source/WebCore/svg/SVGAnimatedColor.h (243258 => 243259)


--- trunk/Source/WebCore/svg/SVGAnimatedColor.h	2019-03-20 23:37:54 UTC (rev 243258)
+++ trunk/Source/WebCore/svg/SVGAnimatedColor.h	2019-03-20 23:51:47 UTC (rev 243259)
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2011. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#pragma once
-
-#include "SVGAnimatedTypeAnimator.h"
-
-namespace WebCore {
-
-class SVGAnimatedColorAnimator final : public SVGAnimatedTypeAnimator {
-public:
-    SVGAnimatedColorAnimator(SVGAnimationElement&, SVGElement&);
-
-private:
-    std::unique_ptr<SVGAnimatedType> constructFromString(const String&) final;
-    std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) final { return nullptr; }
-    void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) final { }
-    void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType&) final { }
-    void animValWillChange(const SVGElementAnimatedPropertyList&) final { }
-    void animValDidChange(const SVGElementAnimatedPropertyList&) final { }
-    void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) final;
-    void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) final;
-    float calculateDistance(const String& fromString, const String& toString) final;
-};
-
-} // namespace WebCore

Modified: trunk/Source/WebCore/svg/SVGAnimatorFactory.h (243258 => 243259)


--- trunk/Source/WebCore/svg/SVGAnimatorFactory.h	2019-03-20 23:37:54 UTC (rev 243258)
+++ trunk/Source/WebCore/svg/SVGAnimatorFactory.h	2019-03-20 23:51:47 UTC (rev 243259)
@@ -20,7 +20,6 @@
 #pragma once
 
 #include "SVGAnimatedAngle.h"
-#include "SVGAnimatedColor.h"
 #include "SVGAnimatedEnumeration.h"
 #include "SVGAnimatedLength.h"
 #include "SVGAnimatedLengthList.h"
@@ -44,18 +43,18 @@
         ASSERT(contextElement);
 
         switch (attributeType) {
-        case AnimatedAngle:
-            return std::make_unique<SVGAnimatedAngleAnimator>(animationElement, contextElement);
         case AnimatedBoolean:
-            return nullptr;
         case AnimatedColor:
-            return std::make_unique<SVGAnimatedColorAnimator>(*animationElement, *contextElement);
-        case AnimatedEnumeration:
-            return std::make_unique<SVGAnimatedEnumerationAnimator>(animationElement, contextElement);
         case AnimatedInteger:
-            return nullptr;
         case AnimatedIntegerOptionalInteger:
+        case AnimatedPreserveAspectRatio:
+        case AnimatedRect:
             return nullptr;
+
+        case AnimatedAngle:
+            return std::make_unique<SVGAnimatedAngleAnimator>(animationElement, contextElement);
+        case AnimatedEnumeration:
+            return std::make_unique<SVGAnimatedEnumerationAnimator>(animationElement, contextElement);
         case AnimatedLength:
             return std::make_unique<SVGAnimatedLengthAnimator>(animationElement, contextElement);
         case AnimatedLengthList:
@@ -70,10 +69,6 @@
             return std::make_unique<SVGAnimatedPathAnimator>(animationElement, contextElement);
         case AnimatedPoints:
             return std::make_unique<SVGAnimatedPointListAnimator>(animationElement, contextElement);
-        case AnimatedPreserveAspectRatio:
-            return nullptr;
-        case AnimatedRect:
-            return nullptr;
         case AnimatedString:
             return std::make_unique<SVGAnimatedStringAnimator>(animationElement, contextElement);
         case AnimatedTransformList:

Modified: trunk/Source/WebCore/svg/SVGAttributeAnimationController.cpp (243258 => 243259)


--- trunk/Source/WebCore/svg/SVGAttributeAnimationController.cpp	2019-03-20 23:37:54 UTC (rev 243258)
+++ trunk/Source/WebCore/svg/SVGAttributeAnimationController.cpp	2019-03-20 23:51:47 UTC (rev 243259)
@@ -37,6 +37,12 @@
     : SVGAttributeAnimationControllerBase(animationElement, targetElement)
 {
 }
+    
+SVGAttributeAnimationController::~SVGAttributeAnimationController()
+{
+    if (m_animator)
+        m_targetElement.animatorWillBeDeleted(m_animationElement.attributeName());
+}
 
 SVGAttributeAnimator* SVGAttributeAnimationController::animator() const
 {

Modified: trunk/Source/WebCore/svg/SVGAttributeAnimationController.h (243258 => 243259)


--- trunk/Source/WebCore/svg/SVGAttributeAnimationController.h	2019-03-20 23:37:54 UTC (rev 243258)
+++ trunk/Source/WebCore/svg/SVGAttributeAnimationController.h	2019-03-20 23:51:47 UTC (rev 243259)
@@ -37,6 +37,7 @@
 class SVGAttributeAnimationController : public SVGAttributeAnimationControllerBase {
 public:
     SVGAttributeAnimationController(SVGAnimationElement&, SVGElement&);
+    ~SVGAttributeAnimationController();
     
 private:
     SVGAttributeAnimator* animator() const;

Modified: trunk/Source/WebCore/svg/SVGElement.cpp (243258 => 243259)


--- trunk/Source/WebCore/svg/SVGElement.cpp	2019-03-20 23:37:54 UTC (rev 243258)
+++ trunk/Source/WebCore/svg/SVGElement.cpp	2019-03-20 23:51:47 UTC (rev 243259)
@@ -44,6 +44,7 @@
 #include "SVGGraphicsElement.h"
 #include "SVGImageElement.h"
 #include "SVGNames.h"
+#include "SVGPropertyAnimatorFactory.h"
 #include "SVGRenderStyle.h"
 #include "SVGRenderSupport.h"
 #include "SVGSVGElement.h"
@@ -275,6 +276,7 @@
 SVGElement::SVGElement(const QualifiedName& tagName, Document& document)
     : StyledElement(tagName, document, CreateSVGElement)
     , SVGLangSpace(this)
+    , m_propertyAnimatorFactory(std::make_unique<SVGPropertyAnimatorFactory>())
 {
     registerAttributes();
 }
@@ -756,11 +758,16 @@
 
 bool SVGElement::isAnimatedAttribute(const QualifiedName& attributeName) const
 {
-    return isAnimatedPropertyAttribute(attributeName);
+    return SVGPropertyAnimatorFactory::isKnownAttribute(attributeName) || isAnimatedPropertyAttribute(attributeName);
 }
 
 std::unique_ptr<SVGAttributeAnimator> SVGElement::createAnimator(const QualifiedName& attributeName, AnimationMode animationMode, CalcMode calcMode, bool isAccumulated, bool isAdditive)
 {
+    // Property animator, e.g. "fill" or "fill-opacity".
+    if (auto animator = propertyAnimatorFactory().createAnimator(attributeName, animationMode, calcMode, isAccumulated, isAdditive))
+        return animator;
+    
+    // Animated property animator.
     auto animator = propertyRegistry().createAnimator(attributeName, animationMode, calcMode, isAccumulated, isAdditive);
     if (!animator)
         return animator;
@@ -768,6 +775,11 @@
         instance->propertyRegistry().appendAnimatedInstance(attributeName, *animator);
     return animator;
 }
+    
+void SVGElement::animatorWillBeDeleted(const QualifiedName& attributeName)
+{
+    propertyAnimatorFactory().animatorWillBeDeleted(attributeName);
+}
 
 Optional<ElementStyle> SVGElement::resolveCustomStyle(const RenderStyle& parentStyle, const RenderStyle*)
 {

Modified: trunk/Source/WebCore/svg/SVGElement.h (243258 => 243259)


--- trunk/Source/WebCore/svg/SVGElement.h	2019-03-20 23:37:54 UTC (rev 243258)
+++ trunk/Source/WebCore/svg/SVGElement.h	2019-03-20 23:51:47 UTC (rev 243259)
@@ -42,6 +42,7 @@
 class Document;
 class SVGDocumentExtensions;
 class SVGElementRareData;
+class SVGPropertyAnimatorFactory;
 class SVGSVGElement;
 class SVGUseElement;
 
@@ -161,7 +162,9 @@
     void commitPropertyChange(SVGAnimatedProperty&);
 
     const SVGElement* attributeContextElement() const override { return this; }
+    SVGPropertyAnimatorFactory& propertyAnimatorFactory() { return *m_propertyAnimatorFactory; }
     std::unique_ptr<SVGAttributeAnimator> createAnimator(const QualifiedName&, AnimationMode, CalcMode, bool isAccumulated, bool isAdditive);
+    void animatorWillBeDeleted(const QualifiedName&);
 
     // These are needed for the RenderTree, animation and DOM.
     const auto& className() const { return m_className.currentValue(attributeOwnerProxy()); }
@@ -215,6 +218,8 @@
 
     HashSet<SVGElement*> m_elementsWithRelativeLengths;
 
+    std::unique_ptr<SVGPropertyAnimatorFactory> m_propertyAnimatorFactory;
+
     AttributeOwnerProxy m_attributeOwnerProxy { *this };
     PropertyRegistry m_propertyRegistry { *this };
     SVGAnimatedStringAttribute m_className;

Modified: trunk/Source/WebCore/svg/SVGFitToViewBox.h (243258 => 243259)


--- trunk/Source/WebCore/svg/SVGFitToViewBox.h	2019-03-20 23:37:54 UTC (rev 243258)
+++ trunk/Source/WebCore/svg/SVGFitToViewBox.h	2019-03-20 23:51:47 UTC (rev 243259)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <[email protected]>
  * Copyright (C) 2004, 2005, 2006, 2007, 2010 Rob Buis <[email protected]>
- * Copyright (C) 2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2018-2019 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -23,9 +23,12 @@
 
 #include "FloatRect.h"
 #include "QualifiedName.h"
+#include "SVGAnimatedPropertyImpl.h"
+#include "SVGAttributeOwnerProxyImpl.h"
 #include "SVGAttributeRegistry.h"
 #include "SVGNames.h"
 #include "SVGPreserveAspectRatio.h"
+#include "SVGPropertyOwnerRegistry.h"
 #include <wtf/HashSet.h>
 
 namespace WebCore {

Modified: trunk/Source/WebCore/svg/SVGMPathElement.cpp (243258 => 243259)


--- trunk/Source/WebCore/svg/SVGMPathElement.cpp	2019-03-20 23:37:54 UTC (rev 243258)
+++ trunk/Source/WebCore/svg/SVGMPathElement.cpp	2019-03-20 23:51:47 UTC (rev 243259)
@@ -26,6 +26,7 @@
 #include "SVGDocumentExtensions.h"
 #include "SVGNames.h"
 #include "SVGPathElement.h"
+#include <wtf/IsoMallocInlines.h>
 
 namespace WebCore {
 

Modified: trunk/Source/WebCore/svg/graphics/filters/SVGFEImage.h (243258 => 243259)


--- trunk/Source/WebCore/svg/graphics/filters/SVGFEImage.h	2019-03-20 23:37:54 UTC (rev 243258)
+++ trunk/Source/WebCore/svg/graphics/filters/SVGFEImage.h	2019-03-20 23:51:47 UTC (rev 243259)
@@ -30,6 +30,7 @@
 class Document;
 class Image;
 class RenderElement;
+class TreeScope;
 
 class FEImage final : public FilterEffect {
 public:

Added: trunk/Source/WebCore/svg/properties/SVGAnimationAdditiveValueFunctionImpl.cpp (0 => 243259)


--- trunk/Source/WebCore/svg/properties/SVGAnimationAdditiveValueFunctionImpl.cpp	                        (rev 0)
+++ trunk/Source/WebCore/svg/properties/SVGAnimationAdditiveValueFunctionImpl.cpp	2019-03-20 23:51:47 UTC (rev 243259)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2019 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SVGAnimationAdditiveValueFunctionImpl.h"
+
+#include "RenderElement.h"
+#include "SVGElement.h"
+
+namespace WebCore {
+
+Color SVGAnimationColorFunction::colorFromString(SVGElement* targetElement, const String& string)
+{
+    static NeverDestroyed<const AtomicString> currentColor("currentColor", AtomicString::ConstructFromLiteral);
+
+    if (string != currentColor.get())
+        return SVGPropertyTraits<Color>::fromString(string);
+
+    if (auto* renderer = targetElement->renderer())
+        return renderer->style().visitedDependentColor(CSSPropertyColor);
+
+    return { };
+}
+
+}

Modified: trunk/Source/WebCore/svg/properties/SVGAnimationAdditiveValueFunctionImpl.h (243258 => 243259)


--- trunk/Source/WebCore/svg/properties/SVGAnimationAdditiveValueFunctionImpl.h	2019-03-20 23:37:54 UTC (rev 243258)
+++ trunk/Source/WebCore/svg/properties/SVGAnimationAdditiveValueFunctionImpl.h	2019-03-20 23:51:47 UTC (rev 243259)
@@ -30,6 +30,62 @@
 
 namespace WebCore {
 
+class SVGAnimationColorFunction : public SVGAnimationAdditiveValueFunction<Color> {
+public:
+    using Base = SVGAnimationAdditiveValueFunction<Color>;
+    using Base::Base;
+
+    void setFromAndToValues(SVGElement* targetElement, const String& from, const String& to) override
+    {
+        m_from = colorFromString(targetElement, from);
+        m_to = colorFromString(targetElement, to);
+    }
+
+    void setToAtEndOfDurationValue(const String& toAtEndOfDuration) override
+    {
+        m_toAtEndOfDuration = SVGPropertyTraits<Color>::fromString(toAtEndOfDuration);
+    }
+
+    void progress(SVGElement*, float percentage, unsigned repeatCount, Color& animated)
+    {
+        Color from = m_animationMode == AnimationMode::To ? animated : m_from;
+        
+        float red = Base::progress(percentage, repeatCount, from.red(), m_to.red(), toAtEndOfDuration().red(), animated.red());
+        float green = Base::progress(percentage, repeatCount, from.green(), m_to.green(), toAtEndOfDuration().green(), animated.green());
+        float blue = Base::progress(percentage, repeatCount, from.blue(), m_to.blue(), toAtEndOfDuration().blue(), animated.blue());
+        float alpha = Base::progress(percentage, repeatCount, from.alpha(), m_to.alpha(), toAtEndOfDuration().alpha(), animated.alpha());
+        
+        animated = { roundAndClampColorChannel(red), roundAndClampColorChannel(green), roundAndClampColorChannel(blue), roundAndClampColorChannel(alpha) };
+    }
+
+    float calculateDistance(SVGElement*, const String& from, const String& to) const override
+    {
+        Color fromColor = CSSParser::parseColor(from.stripWhiteSpace());
+        if (!fromColor.isValid())
+            return -1;
+        Color toColor = CSSParser::parseColor(to.stripWhiteSpace());
+        if (!toColor.isValid())
+            return -1;
+        float red = fromColor.red() - toColor.red();
+        float green = fromColor.green() - toColor.green();
+        float blue = fromColor.blue() - toColor.blue();
+        return sqrtf(red * red + green * green + blue * blue);
+    }
+
+private:
+    void addFromAndToValues(SVGElement*) override
+    {
+        // Ignores any alpha and sets alpha on result to 100% opaque.
+        m_to = {
+            roundAndClampColorChannel(m_to.red() + m_from.red()),
+            roundAndClampColorChannel(m_to.green() + m_from.green()),
+            roundAndClampColorChannel(m_to.blue() + m_from.blue())
+        };
+    }
+
+    static Color colorFromString(SVGElement*, const String&);
+};
+
 class SVGAnimationIntegerFunction : public SVGAnimationAdditiveValueFunction<int> {
     friend class SVGAnimatedIntegerPairAnimator;
 

Modified: trunk/Source/WebCore/svg/properties/SVGAnimationFunction.h (243258 => 243259)


--- trunk/Source/WebCore/svg/properties/SVGAnimationFunction.h	2019-03-20 23:37:54 UTC (rev 243258)
+++ trunk/Source/WebCore/svg/properties/SVGAnimationFunction.h	2019-03-20 23:51:47 UTC (rev 243259)
@@ -25,8 +25,12 @@
 
 #pragma once
 
+#include "SVGAttributeAnimator.h"
+
 namespace WebCore {
 
+class SVGElement;
+
 class SVGAnimationFunction {
 public:
     virtual ~SVGAnimationFunction() = default;

Modified: trunk/Source/WebCore/svg/properties/SVGAttributeAnimator.cpp (243258 => 243259)


--- trunk/Source/WebCore/svg/properties/SVGAttributeAnimator.cpp	2019-03-20 23:37:54 UTC (rev 243258)
+++ trunk/Source/WebCore/svg/properties/SVGAttributeAnimator.cpp	2019-03-20 23:51:47 UTC (rev 243259)
@@ -32,6 +32,63 @@
 
 namespace WebCore {
 
+void SVGAttributeAnimator::applyAnimatedStylePropertyChange(SVGElement* element, CSSPropertyID id, const String& value)
+{
+    ASSERT(element);
+    ASSERT(!element->m_deletionHasBegun);
+    
+    if (!element->ensureAnimatedSMILStyleProperties().setProperty(id, value, false))
+        return;
+    element->invalidateStyle();
+}
+
+void SVGAttributeAnimator::applyAnimatedStylePropertyChange(SVGElement* targetElement, const String& value)
+{
+    ASSERT(targetElement);
+    ASSERT(m_attributeName != anyQName());
+    
+    // FIXME: Do we really need to check both isConnected and !parentNode?
+    if (!targetElement->isConnected() || !targetElement->parentNode())
+        return;
+    
+    CSSPropertyID id = cssPropertyID(m_attributeName.localName());
+    
+    SVGElement::InstanceUpdateBlocker blocker(*targetElement);
+    applyAnimatedStylePropertyChange(targetElement, id, value);
+    
+    // If the target element has instances, update them as well, w/o requiring the <use> tree to be rebuilt.
+    for (auto* instance : targetElement->instances())
+        applyAnimatedStylePropertyChange(instance, id, value);
+}
+    
+void SVGAttributeAnimator::removeAnimatedStyleProperty(SVGElement* element, CSSPropertyID id)
+{
+    ASSERT(element);
+    ASSERT(!element->m_deletionHasBegun);
+
+    element->ensureAnimatedSMILStyleProperties().removeProperty(id);
+    element->invalidateStyle();
+}
+
+void SVGAttributeAnimator::removeAnimatedStyleProperty(SVGElement* targetElement)
+{
+    ASSERT(targetElement);
+    ASSERT(m_attributeName != anyQName());
+
+    // FIXME: Do we really need to check both isConnected and !parentNode?
+    if (!targetElement->isConnected() || !targetElement->parentNode())
+        return;
+
+    CSSPropertyID id = cssPropertyID(m_attributeName.localName());
+
+    SVGElement::InstanceUpdateBlocker blocker(*targetElement);
+    removeAnimatedStyleProperty(targetElement, id);
+
+    // If the target element has instances, update them as well, w/o requiring the <use> tree to be rebuilt.
+    for (auto* instance : targetElement->instances())
+        removeAnimatedStyleProperty(instance, id);
+}
+    
 void SVGAttributeAnimator::applyAnimatedPropertyChange(SVGElement* element, const QualifiedName& attributeName)
 {
     ASSERT(!element->m_deletionHasBegun);

Modified: trunk/Source/WebCore/svg/properties/SVGAttributeAnimator.h (243258 => 243259)


--- trunk/Source/WebCore/svg/properties/SVGAttributeAnimator.h	2019-03-20 23:37:54 UTC (rev 243258)
+++ trunk/Source/WebCore/svg/properties/SVGAttributeAnimator.h	2019-03-20 23:51:47 UTC (rev 243259)
@@ -74,8 +74,12 @@
     virtual float calculateDistance(SVGElement*, const String&, const String&) const { return -1; }
 
 protected:
+    static void applyAnimatedStylePropertyChange(SVGElement*, CSSPropertyID, const String& value);
+    static void removeAnimatedStyleProperty(SVGElement*, CSSPropertyID);
     static void applyAnimatedPropertyChange(SVGElement*, const QualifiedName&);
 
+    void applyAnimatedStylePropertyChange(SVGElement*, const String& value);
+    void removeAnimatedStyleProperty(SVGElement*);
     void applyAnimatedPropertyChange(SVGElement*);
 
     const QualifiedName& m_attributeName;

Added: trunk/Source/WebCore/svg/properties/SVGPrimitivePropertyAnimator.h (0 => 243259)


--- trunk/Source/WebCore/svg/properties/SVGPrimitivePropertyAnimator.h	                        (rev 0)
+++ trunk/Source/WebCore/svg/properties/SVGPrimitivePropertyAnimator.h	2019-03-20 23:51:47 UTC (rev 243259)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2019 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "SVGPropertyAnimator.h"
+#include "SVGPropertyTraits.h"
+#include "SVGValueProperty.h"
+
+namespace WebCore {
+
+template<typename PropertyType, typename AnimationFunction>
+class SVGPrimitivePropertyAnimator : public SVGPropertyAnimator<AnimationFunction> {
+    using Base = SVGPropertyAnimator<AnimationFunction>;
+    using ValuePropertyType = SVGValueProperty<PropertyType>;
+    using Base::Base;
+    using Base::applyAnimatedStylePropertyChange;
+    using Base::computeCSSPropertyValue;
+    using Base::m_attributeName;
+    using Base::m_function;
+    
+public:
+    static auto create(const QualifiedName& attributeName, Ref<SVGProperty>&& property, AnimationMode animationMode, CalcMode calcMode, bool isAccumulated, bool isAdditive)
+    {
+        return std::make_unique<SVGPrimitivePropertyAnimator>(attributeName, WTFMove(property), animationMode, calcMode, isAccumulated, isAdditive);
+    }
+    
+    template<typename... Arguments>
+    SVGPrimitivePropertyAnimator(const QualifiedName& attributeName, Ref<SVGProperty>&& property, Arguments&&... arguments)
+        : Base(attributeName, std::forward<Arguments>(arguments)...)
+        , m_property(static_reference_cast<ValuePropertyType>(WTFMove(property)))
+    {
+    }
+
+    void start(SVGElement* targetElement) override
+    {
+        String baseValue = computeCSSPropertyValue(targetElement, cssPropertyID(m_attributeName.localName()));
+        m_property->setValue(SVGPropertyTraits<PropertyType>::fromString(baseValue));
+    }
+
+    void progress(SVGElement* targetElement, float percentage, unsigned repeatCount) override
+    {
+        PropertyType& animated = m_property->value();
+        m_function.progress(targetElement, percentage, repeatCount, animated);
+    }
+
+    void apply(SVGElement* targetElement) override
+    {
+        applyAnimatedStylePropertyChange(targetElement, SVGPropertyTraits<PropertyType>::toString(m_property->value()));
+    }
+
+protected:
+    Ref<ValuePropertyType> m_property;
+};
+    
+}

Added: trunk/Source/WebCore/svg/properties/SVGPrimitivePropertyAnimatorImpl.h (0 => 243259)


--- trunk/Source/WebCore/svg/properties/SVGPrimitivePropertyAnimatorImpl.h	                        (rev 0)
+++ trunk/Source/WebCore/svg/properties/SVGPrimitivePropertyAnimatorImpl.h	2019-03-20 23:51:47 UTC (rev 243259)
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2019 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "SVGAnimationFunction.h"
+#include "SVGPrimitivePropertyAnimator.h"
+
+namespace WebCore {
+
+using SVGColorAnimator = SVGPrimitivePropertyAnimator<Color, SVGAnimationColorFunction>;
+
+}

Added: trunk/Source/WebCore/svg/properties/SVGPropertyAnimator.h (0 => 243259)


--- trunk/Source/WebCore/svg/properties/SVGPropertyAnimator.h	                        (rev 0)
+++ trunk/Source/WebCore/svg/properties/SVGPropertyAnimator.h	2019-03-20 23:51:47 UTC (rev 243259)
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2019 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CSSComputedStyleDeclaration.h"
+#include "CSSPropertyParser.h"
+#include "SVGAttributeAnimator.h"
+#include "SVGElement.h"
+
+namespace WebCore {
+    
+template<typename AnimationFunction>
+class SVGPropertyAnimator : public SVGAttributeAnimator {
+public:
+    bool isDiscrete() const override { return m_function.isDiscrete(); }
+
+    void setFromAndToValues(SVGElement* targetElement, const String& from, const String& to) override
+    {
+        m_function.setFromAndToValues(targetElement, adjustForInheritance(targetElement, from), adjustForInheritance(targetElement, to));
+    }
+
+    void setFromAndByValues(SVGElement* targetElement, const String& from, const String& by) override
+    {
+        m_function.setFromAndByValues(targetElement, from, by);
+    }
+
+    void setToAtEndOfDurationValue(const String& toAtEndOfDuration) override
+    {
+        m_function.setToAtEndOfDurationValue(toAtEndOfDuration);
+    }
+
+protected:
+    template<typename... Arguments>
+    SVGPropertyAnimator(const QualifiedName& attributeName, Arguments&&... arguments)
+        : SVGAttributeAnimator(attributeName)
+        , m_function(std::forward<Arguments>(arguments)...)
+    {
+    }
+
+    void stop(SVGElement* targetElement) override
+    {
+        removeAnimatedStyleProperty(targetElement);
+    }
+
+    float calculateDistance(SVGElement* targetElement, const String& from, const String& to) const override
+    {
+        return m_function.calculateDistance(targetElement, from, to);
+    }
+
+    String adjustForInheritance(SVGElement* targetElement, const String& value) const
+    {
+        static NeverDestroyed<const AtomicString> inherit("inherit", AtomicString::ConstructFromLiteral);
+        return value == inherit ? computeInheritedCSSPropertyValue(targetElement) : value;
+    }
+
+    String computeCSSPropertyValue(SVGElement* targetElement, CSSPropertyID id) const
+    {
+        ASSERT(targetElement);
+
+        // Don't include any properties resulting from CSS Transitions/Animations or SMIL animations, as we want to retrieve the "base value".
+        targetElement->setUseOverrideComputedStyle(true);
+        RefPtr<CSSValue> value = ComputedStyleExtractor(targetElement).propertyValue(id);
+        targetElement->setUseOverrideComputedStyle(false);
+        return value ? value->cssText() : String();
+    }
+
+    String computeInheritedCSSPropertyValue(SVGElement* targetElement) const
+    {
+        ASSERT(targetElement);
+        auto parent = makeRefPtr(targetElement->parentElement());
+        if (!parent || !parent->isSVGElement())
+            return emptyString();
+        
+        SVGElement& svgParent = downcast<SVGElement>(*parent);
+        return computeCSSPropertyValue(&svgParent, cssPropertyID(m_attributeName.localName()));
+    }
+
+    AnimationFunction m_function;
+};
+    
+}

Added: trunk/Source/WebCore/svg/properties/SVGPropertyAnimatorFactory.h (0 => 243259)


--- trunk/Source/WebCore/svg/properties/SVGPropertyAnimatorFactory.h	                        (rev 0)
+++ trunk/Source/WebCore/svg/properties/SVGPropertyAnimatorFactory.h	2019-03-20 23:51:47 UTC (rev 243259)
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2019 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "SVGNames.h"
+#include "SVGPrimitivePropertyAnimatorImpl.h"
+
+namespace WebCore {
+
+class SVGPropertyAnimatorFactory {
+public:
+    SVGPropertyAnimatorFactory() = default;
+
+    static bool isKnownAttribute(const QualifiedName& attributeName)
+    {
+        return attributeAnimatorCreator().contains(attributeName.impl());
+    }
+
+    std::unique_ptr<SVGAttributeAnimator> createAnimator(const QualifiedName& attributeName, AnimationMode animationMode, CalcMode calcMode, bool isAccumulated, bool isAdditive)
+    {
+        auto iterator = attributeAnimatorCreator().find(attributeName.impl());
+        if (iterator == attributeAnimatorCreator().end())
+            return nullptr;
+
+        auto addResult = m_attributeProperty.ensure(attributeName, [&iterator]() {
+            return iterator->value.first();
+        });
+        
+        return iterator->value.second(attributeName, addResult.iterator->value.copyRef(), animationMode, calcMode, isAccumulated, isAdditive);
+    }
+
+    void animatorWillBeDeleted(const QualifiedName& attributeName)
+    {
+        auto iterator = m_attributeProperty.find(attributeName);
+        if (iterator == m_attributeProperty.end())
+            return;
+
+        // If refCount = 1 (in the animator) + 1 (in m_attributeProperty) = 2, the entry can be deleted.
+        if (iterator->value->refCount() == 2)
+            m_attributeProperty.remove(iterator);
+    }
+
+private:
+    // This HashMap maps an attribute name to a pair of static methods. The first one creates a shared
+    // Ref<SVGProperty> for the value type of this attribute. The second creates the animator given the
+    // attribute name and the shared Ref<SVGProperty>.
+    using AttributeAnimatorCreator = HashMap<
+        QualifiedName::QualifiedNameImpl*,
+        std::pair<
+            std::function<Ref<SVGProperty>()>,
+            std::function<std::unique_ptr<SVGAttributeAnimator>(const QualifiedName&, Ref<SVGProperty>&&, AnimationMode, CalcMode, bool, bool)>
+        >
+    >;
+
+    static auto createColorAnimator(const QualifiedName& attributeName, Ref<SVGProperty>&& property, AnimationMode animationMode, CalcMode calcMode, bool isAccumulated, bool isAdditive)
+    {
+        return SVGColorAnimator::create(attributeName, WTFMove(property), animationMode, calcMode, isAccumulated, isAdditive);
+    }
+
+    static const AttributeAnimatorCreator& attributeAnimatorCreator()
+    {
+        static NeverDestroyed<AttributeAnimatorCreator> map = AttributeAnimatorCreator({
+            { SVGNames::colorAttr->impl(),          std::make_pair(SVGValueProperty<Color>::create, SVGPropertyAnimatorFactory::createColorAnimator) },
+            { SVGNames::fillAttr->impl(),           std::make_pair(SVGValueProperty<Color>::create, SVGPropertyAnimatorFactory::createColorAnimator) },
+            { SVGNames::flood_colorAttr->impl(),    std::make_pair(SVGValueProperty<Color>::create, SVGPropertyAnimatorFactory::createColorAnimator) },
+            { SVGNames::lighting_colorAttr->impl(), std::make_pair(SVGValueProperty<Color>::create, SVGPropertyAnimatorFactory::createColorAnimator) },
+            { SVGNames::stop_colorAttr->impl(),     std::make_pair(SVGValueProperty<Color>::create, SVGPropertyAnimatorFactory::createColorAnimator) },
+            { SVGNames::strokeAttr->impl(),         std::make_pair(SVGValueProperty<Color>::create, SVGPropertyAnimatorFactory::createColorAnimator) },
+        });
+        return map;
+    }
+
+    using AttributeProperty = HashMap<QualifiedName, Ref<SVGProperty>>;
+    AttributeProperty m_attributeProperty;
+};
+    
+}
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to