Remove the SVG tear off objects for SVGAngle, SVGAnimatedAngle and SVGAnimatedEnumeration
https://bugs.webkit.org/show_bug.cgi?id=196087

Patch by Said Abou-Hallawa <sabouhallawa@apple.com> on 2019-03-25
Reviewed by Simon Fraser.

Source/WebCore:

In this patch, the tear off objects for SVGAnimatedEnumeration will be
removed. Because the angle is paired with the orient type so its tear
off objects have to be removed as well. Here is what this patch does:

-- SVGAngle is now a superclass of SVGValueProperty<SVGAngleValue>. Its
relationship with its owner will be managed by the owner of its base
class SVGProperty.

-- SVGAnimatedAngle is now defined to be SVGAnimatedValueProperty<
SVGAngle>. All the DOM interfaces will be handled by the base class
given its baseVal and animVal are of type SVGAngle.

-- SVGAnimatedEnumeration is now defined to be
SVGAnimatedDecoratedProperty<SVGDecoratedEnumeration, unsigned>.
This can be read: SVGAnimatedEnumeration is an SVGAnimatedProperty which
decorates the "SVGDecoratedEnumeration" type to "unsigned". The reason
for this complication is the IDL of SVGAnimatedEnumeration defines the
baseVal and animVal are of type unsigned. However SVGAnimatedEnumeration
should be able to convert a string to its enum value and vice versa.

-- SVGAnimatedDecoratedProperty is a template class which maps from
DecoratedProperty to DecorationType. The DecoratedProperty is actually
a template class which exposes a property of type DecorationType.

-- SVGDecoratedProperty is an abstract class which manages setting and
getting a property in DecorationType regardless of how it is actually
stored.

-- SVGDecoratedPrimitive is a superclass of SVGDecoratedProperty which
stores a primitive property whose type is PropertyType but can decorate
it to the callers as DecorationType.

-- SVGDecoratedEnumeration is a superclass of SVGDecoratedPrimitive
which stores a primitive type DecorationType like "BlendMode" but
decorates it as "unsigned"

To get the mechanics of this change correct, new accessors, animators
and animation functions need to be added for SVGAnimatedAngle,
SVGAnimatedEnumeration and SVGAnimatedOrientType. But since angle and
the orient type are paired under a single attribute, a pair accessor and
animator are also needed for the pair { angle, orientType }.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* svg/SVGAngle.h:
(WebCore::SVGAngle::create):
(WebCore::SVGAngle::unitType):
(WebCore::SVGAngle::setValueForBindings):
(WebCore::SVGAngle::valueForBindings):
(WebCore::SVGAngle::setValueInSpecifiedUnits):
(WebCore::SVGAngle::valueInSpecifiedUnits):
(WebCore::SVGAngle::setValueAsString):
(WebCore::SVGAngle::newValueSpecifiedUnits):
(WebCore::SVGAngle::convertToSpecifiedUnits):
(WebCore::SVGAngle::valueAsString): Deleted.
(WebCore::SVGAngle::SVGAngle): Deleted.
* svg/SVGAnimatedAngle.cpp: Removed.
* svg/SVGAnimatedAngle.h: Removed.
* svg/SVGAnimatedEnumeration.cpp: Removed.
* svg/SVGAnimatedEnumeration.h: Removed.
* svg/SVGAnimatedType.h:
(WebCore::SVGAnimatedType::type const):
* svg/SVGAnimatorFactory.h:
(WebCore::SVGAnimatorFactory::create):
* svg/SVGClipPathElement.cpp:
(WebCore::SVGClipPathElement::SVGClipPathElement):
(WebCore::SVGClipPathElement::parseAttribute):
(WebCore::SVGClipPathElement::svgAttributeChanged):
(WebCore::SVGClipPathElement::registerAttributes): Deleted.
* svg/SVGClipPathElement.h:
* svg/SVGComponentTransferFunctionElement.cpp:
(WebCore::SVGComponentTransferFunctionElement::SVGComponentTransferFunctionElement):
(WebCore::SVGComponentTransferFunctionElement::parseAttribute):
(WebCore::SVGComponentTransferFunctionElement::registerAttributes): Deleted.
* svg/SVGComponentTransferFunctionElement.h:
(WebCore::SVGComponentTransferFunctionElement::type const):
(WebCore::SVGComponentTransferFunctionElement::typeAnimated):
(WebCore::SVGComponentTransferFunctionElement::attributeRegistry): Deleted.
(WebCore::SVGComponentTransferFunctionElement::isKnownAttribute): Deleted.
* svg/SVGElement.cpp:
(WebCore::SVGElement::commitPropertyChange):
* svg/SVGFEBlendElement.cpp:
(WebCore::SVGFEBlendElement::SVGFEBlendElement):
(WebCore::SVGFEBlendElement::parseAttribute):
(WebCore::SVGFEBlendElement::registerAttributes): Deleted.
* svg/SVGFEBlendElement.h:
(WebCore::SVGPropertyTraits<BlendMode>::fromString):
* svg/SVGFEColorMatrixElement.cpp:
(WebCore::SVGFEColorMatrixElement::SVGFEColorMatrixElement):
(WebCore::SVGFEColorMatrixElement::parseAttribute):
(WebCore::SVGFEColorMatrixElement::registerAttributes): Deleted.
* svg/SVGFEColorMatrixElement.h:
* svg/SVGFECompositeElement.cpp:
(WebCore::SVGFECompositeElement::SVGFECompositeElement):
(WebCore::SVGFECompositeElement::parseAttribute):
(WebCore::SVGFECompositeElement::registerAttributes): Deleted.
* svg/SVGFECompositeElement.h:
* svg/SVGFEConvolveMatrixElement.cpp:
(WebCore::SVGFEConvolveMatrixElement::SVGFEConvolveMatrixElement):
(WebCore::SVGFEConvolveMatrixElement::parseAttribute):
(WebCore::SVGFEConvolveMatrixElement::registerAttributes): Deleted.
* svg/SVGFEConvolveMatrixElement.h:
* svg/SVGFEDisplacementMapElement.cpp:
(WebCore::SVGFEDisplacementMapElement::SVGFEDisplacementMapElement):
(WebCore::SVGFEDisplacementMapElement::parseAttribute):
(WebCore::SVGFEDisplacementMapElement::registerAttributes): Deleted.
* svg/SVGFEDisplacementMapElement.h:
* svg/SVGFEGaussianBlurElement.cpp:
(WebCore::SVGFEGaussianBlurElement::SVGFEGaussianBlurElement):
(WebCore::SVGFEGaussianBlurElement::parseAttribute):
(WebCore::SVGFEGaussianBlurElement::svgAttributeChanged):
(WebCore::SVGFEGaussianBlurElement::registerAttributes): Deleted.
* svg/SVGFEGaussianBlurElement.h:
* svg/SVGFEMorphologyElement.cpp:
(WebCore::SVGFEMorphologyElement::SVGFEMorphologyElement):
(WebCore::SVGFEMorphologyElement::parseAttribute):
(WebCore::SVGFEMorphologyElement::registerAttributes): Deleted.
* svg/SVGFEMorphologyElement.h:
* svg/SVGFETurbulenceElement.cpp:
(WebCore::SVGFETurbulenceElement::SVGFETurbulenceElement):
(WebCore::SVGFETurbulenceElement::parseAttribute):
(WebCore::SVGFETurbulenceElement::svgAttributeChanged):
(WebCore::SVGFETurbulenceElement::registerAttributes): Deleted.
* svg/SVGFETurbulenceElement.h:
* svg/SVGFilterElement.cpp:
(WebCore::SVGFilterElement::SVGFilterElement):
(WebCore::SVGFilterElement::registerAttributes):
(WebCore::SVGFilterElement::parseAttribute):
* svg/SVGFilterElement.h:
* svg/SVGGradientElement.cpp:
(WebCore::SVGGradientElement::SVGGradientElement):
(WebCore::SVGGradientElement::registerAttributes):
(WebCore::SVGGradientElement::parseAttribute):
* svg/SVGGradientElement.h:
(WebCore::SVGGradientElement::spreadMethod const):
(WebCore::SVGGradientElement::gradientUnits const):
(WebCore::SVGGradientElement::spreadMethodAnimated):
(WebCore::SVGGradientElement::gradientUnitsAnimated):
* svg/SVGMarkerElement.cpp:
(WebCore::SVGMarkerElement::SVGMarkerElement):
(WebCore::SVGMarkerElement::registerAttributes):
(WebCore::SVGMarkerElement::parseAttribute):
(WebCore::SVGMarkerElement::setOrient):
(WebCore::SVGMarkerElement::setOrientToAngle):
(WebCore::SVGMarkerElement::orientTypeIdentifier): Deleted.
(WebCore::SVGMarkerElement::orientAngleIdentifier): Deleted.
* svg/SVGMarkerElement.h:
* svg/SVGMarkerTypes.h:
(WebCore::SVGPropertyTraits<SVGMarkerOrientType>::autoString):
(WebCore::SVGPropertyTraits<SVGMarkerOrientType>::autoStartReverseString):
(WebCore::SVGPropertyTraits<SVGMarkerOrientType>::fromString):
(WebCore::SVGPropertyTraits<SVGMarkerOrientType>::toString):
* svg/SVGMaskElement.cpp:
(WebCore::SVGMaskElement::SVGMaskElement):
(WebCore::SVGMaskElement::registerAttributes):
(WebCore::SVGMaskElement::parseAttribute):
* svg/SVGMaskElement.h:
* svg/SVGPatternElement.cpp:
(WebCore::SVGPatternElement::SVGPatternElement):
(WebCore::SVGPatternElement::registerAttributes):
(WebCore::SVGPatternElement::parseAttribute):
* svg/SVGPatternElement.h:
* svg/SVGSVGElement.cpp:
* svg/SVGScriptElement.cpp:
* svg/SVGTextContentElement.cpp:
(WebCore::SVGTextContentElement::SVGTextContentElement):
(WebCore::SVGTextContentElement::registerAttributes):
(WebCore::SVGTextContentElement::parseAttribute):
* svg/SVGTextContentElement.h:
(WebCore::SVGTextContentElement::lengthAdjust const):
(WebCore::SVGTextContentElement::lengthAdjustAnimated):
* svg/SVGTextPathElement.cpp:
(WebCore::SVGTextPathElement::SVGTextPathElement):
(WebCore::SVGTextPathElement::registerAttributes):
(WebCore::SVGTextPathElement::parseAttribute):
* svg/SVGTextPathElement.h:
* svg/SVGValue.h:
* svg/properties/SVGAnimatedDecoratedProperty.h: Added.
(WebCore::SVGAnimatedDecoratedProperty::create):
(WebCore::SVGAnimatedDecoratedProperty::SVGAnimatedDecoratedProperty):
(WebCore::SVGAnimatedDecoratedProperty::setBaseVal):
(WebCore::SVGAnimatedDecoratedProperty::setBaseValInternal):
(WebCore::SVGAnimatedDecoratedProperty::baseVal const):
(WebCore::SVGAnimatedDecoratedProperty::setAnimVal):
(WebCore::SVGAnimatedDecoratedProperty::animVal const):
(WebCore::SVGAnimatedDecoratedProperty::currentValue const):
* svg/properties/SVGAnimatedEnumerationPropertyTearOff.h: Removed.
* svg/properties/SVGAnimatedPropertyAccessorImpl.h:
* svg/properties/SVGAnimatedPropertyAnimatorImpl.h:
* svg/properties/SVGAnimatedPropertyImpl.h:
(WebCore::SVGAnimatedOrientType::create):
* svg/properties/SVGAnimatedPropertyPairAccessorImpl.h:
* svg/properties/SVGAnimatedPropertyPairAnimator.h:
(WebCore::SVGAnimatedPropertyPairAnimator::appendAnimatedInstance):
* svg/properties/SVGAnimatedPropertyPairAnimatorImpl.h:
* svg/properties/SVGAnimatedStaticPropertyTearOff.h: Removed.
* svg/properties/SVGAnimationAdditiveValueFunctionImpl.h:
(WebCore::SVGAnimationAngleFunction::progress):
* svg/properties/SVGAnimationDiscreteFunctionImpl.h:
* svg/properties/SVGAttributeRegistry.h:
* svg/properties/SVGDecoratedEnumeration.h: Added.
(WebCore::SVGDecoratedEnumeration::create):
* svg/properties/SVGDecoratedPrimitive.h: Added.
(WebCore::SVGDecoratedPrimitive::SVGDecoratedPrimitive):
* svg/properties/SVGDecoratedProperty.h: Added.
(WebCore::SVGDecoratedProperty::setValue):
(WebCore::SVGDecoratedProperty::value const):
* svg/properties/SVGPropertyOwnerRegistry.h:
(WebCore::SVGPropertyOwnerRegistry::registerProperty):
(WebCore::SVGPropertyOwnerRegistry::isAnimatedLengthAttribute):
* svg/properties/SVGPropertyRegistry.h:
* svg/properties/SVGStaticPropertyTearOff.h: Removed.

LayoutTests:

* svg/dom/SVGAnimatedEnumeration-SVGMarkerElement-expected.txt:
* svg/dom/SVGAnimatedEnumeration-SVGMarkerElement.html:
Fixes cases that the tear off objects could not handle correctly for the
paired { angle, orientType }. Also when setting the orient type to "auto"
or "auto-start-reverse", the orient angle should be reset to
SVG_ANGLETYPE_UNSPECIFIED and is not suppsed to keep its original value.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@243478 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 878cd4b..54352b0 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,17 @@
+2019-03-25  Said Abou-Hallawa  <sabouhallawa@apple.com>
+
+        Remove the SVG tear off objects for SVGAngle, SVGAnimatedAngle and SVGAnimatedEnumeration
+        https://bugs.webkit.org/show_bug.cgi?id=196087
+
+        Reviewed by Simon Fraser.
+
+        * svg/dom/SVGAnimatedEnumeration-SVGMarkerElement-expected.txt:
+        * svg/dom/SVGAnimatedEnumeration-SVGMarkerElement.html:
+        Fixes cases that the tear off objects could not handle correctly for the
+        paired { angle, orientType }. Also when setting the orient type to "auto"
+        or "auto-start-reverse", the orient angle should be reset to
+        SVG_ANGLETYPE_UNSPECIFIED and is not suppsed to keep its original value.
+
 2019-03-25  Shawn Roberts  <sroberts@apple.com>
 
         fast/visual-viewport/ios/min-scale-greater-than-one.html is a flaky failure
diff --git a/LayoutTests/svg/dom/SVGAnimatedEnumeration-SVGMarkerElement-expected.txt b/LayoutTests/svg/dom/SVGAnimatedEnumeration-SVGMarkerElement-expected.txt
index a1249f9..bfe4858 100644
--- a/LayoutTests/svg/dom/SVGAnimatedEnumeration-SVGMarkerElement-expected.txt
+++ b/LayoutTests/svg/dom/SVGAnimatedEnumeration-SVGMarkerElement-expected.txt
@@ -101,16 +101,16 @@
 
 Test case sensitivity of attributes - try setting invalid values
 PASS markerElement.setAttribute('orient', 'AUTO-START-REVERSE') did not throw exception.
-FAIL markerElement.getAttribute('orient') should be AUTO-START-REVERSE. Was 10deg.
-PASS markerElement.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE
+PASS markerElement.getAttribute('orient') is "AUTO-START-REVERSE"
+PASS markerElement.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_UNKNOWN
 PASS markerElement.setAttribute('orient', 'AUTO') did not throw exception.
-FAIL markerElement.getAttribute('orient') should be AUTO. Was 10deg.
-PASS markerElement.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE
+PASS markerElement.getAttribute('orient') is "AUTO"
+PASS markerElement.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_UNKNOWN
 
 Switch back to 'auto' value
 PASS markerElement.orientType.baseVal = SVGMarkerElement.SVG_MARKER_ORIENT_AUTO is SVGMarkerElement.SVG_MARKER_ORIENT_AUTO
-PASS markerElement.orientAngle.baseVal.value is 10
-PASS markerElement.orientAngle.baseVal.unitType is SVGAngle.SVG_ANGLETYPE_DEG
+PASS markerElement.orientAngle.baseVal.value is 0
+PASS markerElement.orientAngle.baseVal.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
 PASS markerElement.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_AUTO
 PASS markerElement.getAttribute('orient') is "auto"
 
diff --git a/LayoutTests/svg/dom/SVGAnimatedEnumeration-SVGMarkerElement.html b/LayoutTests/svg/dom/SVGAnimatedEnumeration-SVGMarkerElement.html
index c0cda19..2c5e670 100644
--- a/LayoutTests/svg/dom/SVGAnimatedEnumeration-SVGMarkerElement.html
+++ b/LayoutTests/svg/dom/SVGAnimatedEnumeration-SVGMarkerElement.html
@@ -132,24 +132,18 @@
 debug("");
 debug("Test case sensitivity of attributes - try setting invalid values");
 shouldNotThrow("markerElement.setAttribute('orient', 'AUTO-START-REVERSE')");
-// The line below fails as a result of https://bugs.webkit.org/show_bug.cgi?id=154141
-// The attribute value is not updated to the invalid value.
-// The expected result recognises this and should be updated when the above bug
-// is resolved.
-// What's important here though is that the DOM values are unchanged, and this
-// is demonstrated correctly.
 shouldBeEqualToString("markerElement.getAttribute('orient')", "AUTO-START-REVERSE");
-shouldBe("markerElement.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE");
+shouldBe("markerElement.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_UNKNOWN");
 
 shouldNotThrow("markerElement.setAttribute('orient', 'AUTO')");
 shouldBeEqualToString("markerElement.getAttribute('orient')", "AUTO");
-shouldBe("markerElement.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE"); 
+shouldBe("markerElement.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_UNKNOWN"); 
 
 debug("");
 debug("Switch back to 'auto' value");
 shouldBe("markerElement.orientType.baseVal = SVGMarkerElement.SVG_MARKER_ORIENT_AUTO", "SVGMarkerElement.SVG_MARKER_ORIENT_AUTO");
-shouldBe("markerElement.orientAngle.baseVal.value", "10");
-shouldBe("markerElement.orientAngle.baseVal.unitType", "SVGAngle.SVG_ANGLETYPE_DEG");
+shouldBe("markerElement.orientAngle.baseVal.value", "0");
+shouldBe("markerElement.orientAngle.baseVal.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
 shouldBe("markerElement.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_AUTO");
 shouldBeEqualToString("markerElement.getAttribute('orient')", "auto");
 
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index c0749ba..211f51f 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,223 @@
+2019-03-25  Said Abou-Hallawa  <sabouhallawa@apple.com>
+
+        Remove the SVG tear off objects for SVGAngle, SVGAnimatedAngle and SVGAnimatedEnumeration
+        https://bugs.webkit.org/show_bug.cgi?id=196087
+
+        Reviewed by Simon Fraser.
+
+        In this patch, the tear off objects for SVGAnimatedEnumeration will be 
+        removed. Because the angle is paired with the orient type so its tear
+        off objects have to be removed as well. Here is what this patch does:
+
+        -- SVGAngle is now a superclass of SVGValueProperty<SVGAngleValue>. Its 
+        relationship with its owner will be managed by the owner of its base
+        class SVGProperty.
+
+        -- SVGAnimatedAngle is now defined to be SVGAnimatedValueProperty<
+        SVGAngle>. All the DOM interfaces will be handled by the base class
+        given its baseVal and animVal are of type SVGAngle.
+
+        -- SVGAnimatedEnumeration is now defined to be
+        SVGAnimatedDecoratedProperty<SVGDecoratedEnumeration, unsigned>.
+        This can be read: SVGAnimatedEnumeration is an SVGAnimatedProperty which
+        decorates the "SVGDecoratedEnumeration" type to "unsigned". The reason
+        for this complication is the IDL of SVGAnimatedEnumeration defines the
+        baseVal and animVal are of type unsigned. However SVGAnimatedEnumeration
+        should be able to convert a string to its enum value and vice versa.
+
+        -- SVGAnimatedDecoratedProperty is a template class which maps from
+        DecoratedProperty to DecorationType. The DecoratedProperty is actually
+        a template class which exposes a property of type DecorationType.
+
+        -- SVGDecoratedProperty is an abstract class which manages setting and
+        getting a property in DecorationType regardless of how it is actually
+        stored. 
+
+        -- SVGDecoratedPrimitive is a superclass of SVGDecoratedProperty which
+        stores a primitive property whose type is PropertyType but can decorate
+        it to the callers as DecorationType.
+
+        -- SVGDecoratedEnumeration is a superclass of SVGDecoratedPrimitive
+        which stores a primitive type DecorationType like "BlendMode" but
+        decorates it as "unsigned"
+
+        To get the mechanics of this change correct, new accessors, animators
+        and animation functions need to be added for SVGAnimatedAngle,
+        SVGAnimatedEnumeration and SVGAnimatedOrientType. But since angle and
+        the orient type are paired under a single attribute, a pair accessor and
+        animator are also needed for the pair { angle, orientType }.
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * svg/SVGAngle.h:
+        (WebCore::SVGAngle::create):
+        (WebCore::SVGAngle::unitType):
+        (WebCore::SVGAngle::setValueForBindings):
+        (WebCore::SVGAngle::valueForBindings):
+        (WebCore::SVGAngle::setValueInSpecifiedUnits):
+        (WebCore::SVGAngle::valueInSpecifiedUnits):
+        (WebCore::SVGAngle::setValueAsString):
+        (WebCore::SVGAngle::newValueSpecifiedUnits):
+        (WebCore::SVGAngle::convertToSpecifiedUnits):
+        (WebCore::SVGAngle::valueAsString): Deleted.
+        (WebCore::SVGAngle::SVGAngle): Deleted.
+        * svg/SVGAnimatedAngle.cpp: Removed.
+        * svg/SVGAnimatedAngle.h: Removed.
+        * svg/SVGAnimatedEnumeration.cpp: Removed.
+        * svg/SVGAnimatedEnumeration.h: Removed.
+        * svg/SVGAnimatedType.h:
+        (WebCore::SVGAnimatedType::type const):
+        * svg/SVGAnimatorFactory.h:
+        (WebCore::SVGAnimatorFactory::create):
+        * svg/SVGClipPathElement.cpp:
+        (WebCore::SVGClipPathElement::SVGClipPathElement):
+        (WebCore::SVGClipPathElement::parseAttribute):
+        (WebCore::SVGClipPathElement::svgAttributeChanged):
+        (WebCore::SVGClipPathElement::registerAttributes): Deleted.
+        * svg/SVGClipPathElement.h:
+        * svg/SVGComponentTransferFunctionElement.cpp:
+        (WebCore::SVGComponentTransferFunctionElement::SVGComponentTransferFunctionElement):
+        (WebCore::SVGComponentTransferFunctionElement::parseAttribute):
+        (WebCore::SVGComponentTransferFunctionElement::registerAttributes): Deleted.
+        * svg/SVGComponentTransferFunctionElement.h:
+        (WebCore::SVGComponentTransferFunctionElement::type const):
+        (WebCore::SVGComponentTransferFunctionElement::typeAnimated):
+        (WebCore::SVGComponentTransferFunctionElement::attributeRegistry): Deleted.
+        (WebCore::SVGComponentTransferFunctionElement::isKnownAttribute): Deleted.
+        * svg/SVGElement.cpp:
+        (WebCore::SVGElement::commitPropertyChange):
+        * svg/SVGFEBlendElement.cpp:
+        (WebCore::SVGFEBlendElement::SVGFEBlendElement):
+        (WebCore::SVGFEBlendElement::parseAttribute):
+        (WebCore::SVGFEBlendElement::registerAttributes): Deleted.
+        * svg/SVGFEBlendElement.h:
+        (WebCore::SVGPropertyTraits<BlendMode>::fromString):
+        * svg/SVGFEColorMatrixElement.cpp:
+        (WebCore::SVGFEColorMatrixElement::SVGFEColorMatrixElement):
+        (WebCore::SVGFEColorMatrixElement::parseAttribute):
+        (WebCore::SVGFEColorMatrixElement::registerAttributes): Deleted.
+        * svg/SVGFEColorMatrixElement.h:
+        * svg/SVGFECompositeElement.cpp:
+        (WebCore::SVGFECompositeElement::SVGFECompositeElement):
+        (WebCore::SVGFECompositeElement::parseAttribute):
+        (WebCore::SVGFECompositeElement::registerAttributes): Deleted.
+        * svg/SVGFECompositeElement.h:
+        * svg/SVGFEConvolveMatrixElement.cpp:
+        (WebCore::SVGFEConvolveMatrixElement::SVGFEConvolveMatrixElement):
+        (WebCore::SVGFEConvolveMatrixElement::parseAttribute):
+        (WebCore::SVGFEConvolveMatrixElement::registerAttributes): Deleted.
+        * svg/SVGFEConvolveMatrixElement.h:
+        * svg/SVGFEDisplacementMapElement.cpp:
+        (WebCore::SVGFEDisplacementMapElement::SVGFEDisplacementMapElement):
+        (WebCore::SVGFEDisplacementMapElement::parseAttribute):
+        (WebCore::SVGFEDisplacementMapElement::registerAttributes): Deleted.
+        * svg/SVGFEDisplacementMapElement.h:
+        * svg/SVGFEGaussianBlurElement.cpp:
+        (WebCore::SVGFEGaussianBlurElement::SVGFEGaussianBlurElement):
+        (WebCore::SVGFEGaussianBlurElement::parseAttribute):
+        (WebCore::SVGFEGaussianBlurElement::svgAttributeChanged):
+        (WebCore::SVGFEGaussianBlurElement::registerAttributes): Deleted.
+        * svg/SVGFEGaussianBlurElement.h:
+        * svg/SVGFEMorphologyElement.cpp:
+        (WebCore::SVGFEMorphologyElement::SVGFEMorphologyElement):
+        (WebCore::SVGFEMorphologyElement::parseAttribute):
+        (WebCore::SVGFEMorphologyElement::registerAttributes): Deleted.
+        * svg/SVGFEMorphologyElement.h:
+        * svg/SVGFETurbulenceElement.cpp:
+        (WebCore::SVGFETurbulenceElement::SVGFETurbulenceElement):
+        (WebCore::SVGFETurbulenceElement::parseAttribute):
+        (WebCore::SVGFETurbulenceElement::svgAttributeChanged):
+        (WebCore::SVGFETurbulenceElement::registerAttributes): Deleted.
+        * svg/SVGFETurbulenceElement.h:
+        * svg/SVGFilterElement.cpp:
+        (WebCore::SVGFilterElement::SVGFilterElement):
+        (WebCore::SVGFilterElement::registerAttributes):
+        (WebCore::SVGFilterElement::parseAttribute):
+        * svg/SVGFilterElement.h:
+        * svg/SVGGradientElement.cpp:
+        (WebCore::SVGGradientElement::SVGGradientElement):
+        (WebCore::SVGGradientElement::registerAttributes):
+        (WebCore::SVGGradientElement::parseAttribute):
+        * svg/SVGGradientElement.h:
+        (WebCore::SVGGradientElement::spreadMethod const):
+        (WebCore::SVGGradientElement::gradientUnits const):
+        (WebCore::SVGGradientElement::spreadMethodAnimated):
+        (WebCore::SVGGradientElement::gradientUnitsAnimated):
+        * svg/SVGMarkerElement.cpp:
+        (WebCore::SVGMarkerElement::SVGMarkerElement):
+        (WebCore::SVGMarkerElement::registerAttributes):
+        (WebCore::SVGMarkerElement::parseAttribute):
+        (WebCore::SVGMarkerElement::setOrient):
+        (WebCore::SVGMarkerElement::setOrientToAngle):
+        (WebCore::SVGMarkerElement::orientTypeIdentifier): Deleted.
+        (WebCore::SVGMarkerElement::orientAngleIdentifier): Deleted.
+        * svg/SVGMarkerElement.h:
+        * svg/SVGMarkerTypes.h:
+        (WebCore::SVGPropertyTraits<SVGMarkerOrientType>::autoString):
+        (WebCore::SVGPropertyTraits<SVGMarkerOrientType>::autoStartReverseString):
+        (WebCore::SVGPropertyTraits<SVGMarkerOrientType>::fromString):
+        (WebCore::SVGPropertyTraits<SVGMarkerOrientType>::toString):
+        * svg/SVGMaskElement.cpp:
+        (WebCore::SVGMaskElement::SVGMaskElement):
+        (WebCore::SVGMaskElement::registerAttributes):
+        (WebCore::SVGMaskElement::parseAttribute):
+        * svg/SVGMaskElement.h:
+        * svg/SVGPatternElement.cpp:
+        (WebCore::SVGPatternElement::SVGPatternElement):
+        (WebCore::SVGPatternElement::registerAttributes):
+        (WebCore::SVGPatternElement::parseAttribute):
+        * svg/SVGPatternElement.h:
+        * svg/SVGSVGElement.cpp:
+        * svg/SVGScriptElement.cpp:
+        * svg/SVGTextContentElement.cpp:
+        (WebCore::SVGTextContentElement::SVGTextContentElement):
+        (WebCore::SVGTextContentElement::registerAttributes):
+        (WebCore::SVGTextContentElement::parseAttribute):
+        * svg/SVGTextContentElement.h:
+        (WebCore::SVGTextContentElement::lengthAdjust const):
+        (WebCore::SVGTextContentElement::lengthAdjustAnimated):
+        * svg/SVGTextPathElement.cpp:
+        (WebCore::SVGTextPathElement::SVGTextPathElement):
+        (WebCore::SVGTextPathElement::registerAttributes):
+        (WebCore::SVGTextPathElement::parseAttribute):
+        * svg/SVGTextPathElement.h:
+        * svg/SVGValue.h:
+        * svg/properties/SVGAnimatedDecoratedProperty.h: Added.
+        (WebCore::SVGAnimatedDecoratedProperty::create):
+        (WebCore::SVGAnimatedDecoratedProperty::SVGAnimatedDecoratedProperty):
+        (WebCore::SVGAnimatedDecoratedProperty::setBaseVal):
+        (WebCore::SVGAnimatedDecoratedProperty::setBaseValInternal):
+        (WebCore::SVGAnimatedDecoratedProperty::baseVal const):
+        (WebCore::SVGAnimatedDecoratedProperty::setAnimVal):
+        (WebCore::SVGAnimatedDecoratedProperty::animVal const):
+        (WebCore::SVGAnimatedDecoratedProperty::currentValue const):
+        * svg/properties/SVGAnimatedEnumerationPropertyTearOff.h: Removed.
+        * svg/properties/SVGAnimatedPropertyAccessorImpl.h:
+        * svg/properties/SVGAnimatedPropertyAnimatorImpl.h:
+        * svg/properties/SVGAnimatedPropertyImpl.h:
+        (WebCore::SVGAnimatedOrientType::create):
+        * svg/properties/SVGAnimatedPropertyPairAccessorImpl.h:
+        * svg/properties/SVGAnimatedPropertyPairAnimator.h:
+        (WebCore::SVGAnimatedPropertyPairAnimator::appendAnimatedInstance):
+        * svg/properties/SVGAnimatedPropertyPairAnimatorImpl.h:
+        * svg/properties/SVGAnimatedStaticPropertyTearOff.h: Removed.
+        * svg/properties/SVGAnimationAdditiveValueFunctionImpl.h:
+        (WebCore::SVGAnimationAngleFunction::progress):
+        * svg/properties/SVGAnimationDiscreteFunctionImpl.h:
+        * svg/properties/SVGAttributeRegistry.h:
+        * svg/properties/SVGDecoratedEnumeration.h: Added.
+        (WebCore::SVGDecoratedEnumeration::create):
+        * svg/properties/SVGDecoratedPrimitive.h: Added.
+        (WebCore::SVGDecoratedPrimitive::SVGDecoratedPrimitive):
+        * svg/properties/SVGDecoratedProperty.h: Added.
+        (WebCore::SVGDecoratedProperty::setValue):
+        (WebCore::SVGDecoratedProperty::value const):
+        * svg/properties/SVGPropertyOwnerRegistry.h:
+        (WebCore::SVGPropertyOwnerRegistry::registerProperty):
+        (WebCore::SVGPropertyOwnerRegistry::isAnimatedLengthAttribute):
+        * svg/properties/SVGPropertyRegistry.h:
+        * svg/properties/SVGStaticPropertyTearOff.h: Removed.
+
 2019-03-25  Fujii Hironori  <Hironori.Fujii@sony.com>
 
         [iOS] Break a reference cycle between PreviewLoader and ResourceLoader
diff --git a/Source/WebCore/Sources.txt b/Source/WebCore/Sources.txt
index f0c31ac..5e2df88 100644
--- a/Source/WebCore/Sources.txt
+++ b/Source/WebCore/Sources.txt
@@ -2267,8 +2267,6 @@
 svg/SVGAnimateElementBase.cpp
 svg/SVGAnimateMotionElement.cpp
 svg/SVGAnimateTransformElement.cpp
-svg/SVGAnimatedAngle.cpp
-svg/SVGAnimatedEnumeration.cpp
 svg/SVGAnimatedLength.cpp
 svg/SVGAnimatedLengthList.cpp
 svg/SVGAnimatedPath.cpp
diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
index 3d44885..5ba5bff 100644
--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -237,7 +237,6 @@
 		080E49281255F3BD00EFCA27 /* SVGTextLayoutEngineSpacing.h in Headers */ = {isa = PBXBuildFile; fileRef = 080E49241255F3BD00EFCA27 /* SVGTextLayoutEngineSpacing.h */; };
 		0810764412828556007C63BA /* SVGListProperty.h in Headers */ = {isa = PBXBuildFile; fileRef = 0810764312828556007C63BA /* SVGListProperty.h */; };
 		081093DC1255F0E700ED9D29 /* SVGTextLayoutAttributesBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 081093DA1255F0E700ED9D29 /* SVGTextLayoutAttributesBuilder.h */; };
-		0813A4EA1284132600992511 /* SVGStaticPropertyTearOff.h in Headers */ = {isa = PBXBuildFile; fileRef = 0813A4E91284132600992511 /* SVGStaticPropertyTearOff.h */; };
 		081668D4125603BF006F25DE /* SVGTextChunkBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 081668D2125603BF006F25DE /* SVGTextChunkBuilder.h */; };
 		081668DA125603D5006F25DE /* SVGTextLayoutEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 081668D8125603D5006F25DE /* SVGTextLayoutEngine.h */; };
 		081AA8DA1111237E002AB06E /* SVGElementRareData.h in Headers */ = {isa = PBXBuildFile; fileRef = 081AA8D91111237E002AB06E /* SVGElementRareData.h */; };
@@ -247,7 +246,6 @@
 		083DAEA70F01A7FB00342754 /* RenderTextControlMultiLine.h in Headers */ = {isa = PBXBuildFile; fileRef = 083DAEA30F01A7FB00342754 /* RenderTextControlMultiLine.h */; };
 		083DAEA90F01A7FB00342754 /* RenderTextControlSingleLine.h in Headers */ = {isa = PBXBuildFile; fileRef = 083DAEA50F01A7FB00342754 /* RenderTextControlSingleLine.h */; };
 		0845680812B90DA600960A9F /* FontMetrics.h in Headers */ = {isa = PBXBuildFile; fileRef = 0845680712B90DA600960A9F /* FontMetrics.h */; settings = {ATTRIBUTES = (Private, ); }; };
-		08525E631278C00100A84778 /* SVGAnimatedStaticPropertyTearOff.h in Headers */ = {isa = PBXBuildFile; fileRef = 08525E621278C00100A84778 /* SVGAnimatedStaticPropertyTearOff.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0854B0151255E4E600B9CDD0 /* RenderSVGInline.h in Headers */ = {isa = PBXBuildFile; fileRef = 0854B0031255E4E600B9CDD0 /* RenderSVGInline.h */; };
 		0854B0171255E4E600B9CDD0 /* RenderSVGInlineText.h in Headers */ = {isa = PBXBuildFile; fileRef = 0854B0051255E4E600B9CDD0 /* RenderSVGInlineText.h */; };
 		0854B0191255E4E600B9CDD0 /* RenderSVGText.h in Headers */ = {isa = PBXBuildFile; fileRef = 0854B0071255E4E600B9CDD0 /* RenderSVGText.h */; };
@@ -264,7 +262,6 @@
 		086BBD0F136039C2008B15D8 /* Glyph.h in Headers */ = {isa = PBXBuildFile; fileRef = 086BBD0E136039C2008B15D8 /* Glyph.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0873B86B136064EA00A522C2 /* GlyphPage.h in Headers */ = {isa = PBXBuildFile; fileRef = 0873B86A136064EA00A522C2 /* GlyphPage.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		087558C613B4A57D00F49307 /* SurrogatePairAwareTextIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = 087558C413B4A57D00F49307 /* SurrogatePairAwareTextIterator.h */; settings = {ATTRIBUTES = (Private, ); }; };
-		087B84961272CEC800A14417 /* SVGAnimatedAngle.h in Headers */ = {isa = PBXBuildFile; fileRef = 087B84951272CEC700A14417 /* SVGAnimatedAngle.h */; };
 		0885067F11DA045B00182B98 /* PaintInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0885067D11DA045B00182B98 /* PaintInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0885068011DA045B00182B98 /* PaintPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0885067E11DA045B00182B98 /* PaintPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		088A0E04126EF1DB00978F7A /* SVGAnimatedListPropertyTearOff.h in Headers */ = {isa = PBXBuildFile; fileRef = 088A0DFB126EF1DB00978F7A /* SVGAnimatedListPropertyTearOff.h */; };
@@ -282,7 +279,6 @@
 		08C7A2C710DC7462002D368B /* SVGNames.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = 656581E909D1508D000E61D7 /* SVGNames.h */; };
 		08C9251A0FCC7C4A00480DEC /* FilterEffect.h in Headers */ = {isa = PBXBuildFile; fileRef = 08C925180FCC7C4A00480DEC /* FilterEffect.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		08CA3D4412894A3800FFF260 /* SVGMatrixTearOff.h in Headers */ = {isa = PBXBuildFile; fileRef = 08CA3D4312894A3800FFF260 /* SVGMatrixTearOff.h */; };
-		08D46CE3127AD5FC0089694B /* SVGAnimatedEnumeration.h in Headers */ = {isa = PBXBuildFile; fileRef = 08D46CE2127AD5FC0089694B /* SVGAnimatedEnumeration.h */; };
 		08EDE19F12A50B8E00B95797 /* SVGRect.h in Headers */ = {isa = PBXBuildFile; fileRef = 08EDE19E12A50B8E00B95797 /* SVGRect.h */; };
 		08F0BFC31255C53C00075185 /* SVGTextChunk.h in Headers */ = {isa = PBXBuildFile; fileRef = 08F0BFBE1255C53C00075185 /* SVGTextChunk.h */; };
 		08F0BFC41255C53C00075185 /* SVGTextFragment.h in Headers */ = {isa = PBXBuildFile; fileRef = 08F0BFBF1255C53C00075185 /* SVGTextFragment.h */; };
@@ -2131,7 +2127,6 @@
 		71E2C42621C935280024F8C8 /* AnimationEffectPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 71E2C42421C9351D0024F8C8 /* AnimationEffectPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		71EADCD822087E720065A45F /* PointerID.h in Headers */ = {isa = PBXBuildFile; fileRef = 71EADCD622087E6D0065A45F /* PointerID.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		71EFCEDC202B38A900D7C411 /* AnimationEffect.h in Headers */ = {isa = PBXBuildFile; fileRef = 71EFCED7202B388D00D7C411 /* AnimationEffect.h */; settings = {ATTRIBUTES = (Private, ); }; };
-		71FB967B1383D64600AC8A4C /* SVGAnimatedEnumerationPropertyTearOff.h in Headers */ = {isa = PBXBuildFile; fileRef = 71FB967A1383D64600AC8A4C /* SVGAnimatedEnumerationPropertyTearOff.h */; };
 		72144331223EC85400F12FF7 /* (null) in Headers */ = {isa = PBXBuildFile; settings = {ATTRIBUTES = (Private, ); }; };
 		72144332223EC85F00F12FF7 /* (null) in Headers */ = {isa = PBXBuildFile; settings = {ATTRIBUTES = (Private, ); }; };
 		72144333223EC8B000F12FF7 /* SVGProperty.h in Headers */ = {isa = PBXBuildFile; fileRef = 55EE5363223B2A2400FBA944 /* SVGProperty.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -5593,7 +5588,6 @@
 		0810764312828556007C63BA /* SVGListProperty.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGListProperty.h; sourceTree = "<group>"; };
 		081093D91255F0E700ED9D29 /* SVGTextLayoutAttributesBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGTextLayoutAttributesBuilder.cpp; sourceTree = "<group>"; };
 		081093DA1255F0E700ED9D29 /* SVGTextLayoutAttributesBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGTextLayoutAttributesBuilder.h; sourceTree = "<group>"; };
-		0813A4E91284132600992511 /* SVGStaticPropertyTearOff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGStaticPropertyTearOff.h; sourceTree = "<group>"; };
 		081668D1125603BF006F25DE /* SVGTextChunkBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGTextChunkBuilder.cpp; sourceTree = "<group>"; };
 		081668D2125603BF006F25DE /* SVGTextChunkBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGTextChunkBuilder.h; sourceTree = "<group>"; };
 		081668D7125603D5006F25DE /* SVGTextLayoutEngine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGTextLayoutEngine.cpp; sourceTree = "<group>"; };
@@ -5608,7 +5602,6 @@
 		083DAEA40F01A7FB00342754 /* RenderTextControlSingleLine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderTextControlSingleLine.cpp; sourceTree = "<group>"; };
 		083DAEA50F01A7FB00342754 /* RenderTextControlSingleLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderTextControlSingleLine.h; sourceTree = "<group>"; };
 		0845680712B90DA600960A9F /* FontMetrics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FontMetrics.h; sourceTree = "<group>"; };
-		08525E621278C00100A84778 /* SVGAnimatedStaticPropertyTearOff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGAnimatedStaticPropertyTearOff.h; sourceTree = "<group>"; };
 		0854B0021255E4E600B9CDD0 /* RenderSVGInline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSVGInline.cpp; sourceTree = "<group>"; };
 		0854B0031255E4E600B9CDD0 /* RenderSVGInline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGInline.h; sourceTree = "<group>"; };
 		0854B0041255E4E600B9CDD0 /* RenderSVGInlineText.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSVGInlineText.cpp; sourceTree = "<group>"; };
@@ -5637,7 +5630,6 @@
 		0873B86A136064EA00A522C2 /* GlyphPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GlyphPage.h; sourceTree = "<group>"; };
 		087558C313B4A57D00F49307 /* SurrogatePairAwareTextIterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SurrogatePairAwareTextIterator.cpp; sourceTree = "<group>"; };
 		087558C413B4A57D00F49307 /* SurrogatePairAwareTextIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SurrogatePairAwareTextIterator.h; sourceTree = "<group>"; };
-		087B84951272CEC700A14417 /* SVGAnimatedAngle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGAnimatedAngle.h; sourceTree = "<group>"; };
 		0885067D11DA045B00182B98 /* PaintInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PaintInfo.h; sourceTree = "<group>"; };
 		0885067E11DA045B00182B98 /* PaintPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PaintPhase.h; sourceTree = "<group>"; };
 		088A0DFB126EF1DB00978F7A /* SVGAnimatedListPropertyTearOff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGAnimatedListPropertyTearOff.h; sourceTree = "<group>"; };
@@ -5658,7 +5650,6 @@
 		08C925170FCC7C4A00480DEC /* FilterEffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FilterEffect.cpp; sourceTree = "<group>"; };
 		08C925180FCC7C4A00480DEC /* FilterEffect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FilterEffect.h; sourceTree = "<group>"; };
 		08CA3D4312894A3800FFF260 /* SVGMatrixTearOff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGMatrixTearOff.h; sourceTree = "<group>"; };
-		08D46CE2127AD5FC0089694B /* SVGAnimatedEnumeration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGAnimatedEnumeration.h; sourceTree = "<group>"; };
 		08EDE19E12A50B8E00B95797 /* SVGRect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGRect.h; sourceTree = "<group>"; };
 		08F0BFBD1255C53C00075185 /* SVGTextChunk.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGTextChunk.cpp; sourceTree = "<group>"; };
 		08F0BFBE1255C53C00075185 /* SVGTextChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGTextChunk.h; sourceTree = "<group>"; };
@@ -7576,7 +7567,6 @@
 		4358E8821360A33B00E4748C /* SVGFEDropShadowElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGFEDropShadowElement.cpp; sourceTree = "<group>"; };
 		4358E8831360A33B00E4748C /* SVGFEDropShadowElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGFEDropShadowElement.h; sourceTree = "<group>"; };
 		4358E8841360A33B00E4748C /* SVGFEDropShadowElement.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = SVGFEDropShadowElement.idl; sourceTree = "<group>"; };
-		4362C7B813AC6F1A00344BEB /* SVGAnimatedAngle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGAnimatedAngle.cpp; sourceTree = "<group>"; };
 		4367088112D9CA4A00044234 /* RenderSVGBlock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSVGBlock.cpp; sourceTree = "<group>"; };
 		4367088212D9CA4A00044234 /* RenderSVGBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGBlock.h; sourceTree = "<group>"; };
 		4367088312D9CA4A00044234 /* RenderSVGContainer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSVGContainer.cpp; sourceTree = "<group>"; };
@@ -8639,6 +8629,10 @@
 		554675781FD1FC1A003B10B0 /* ImageSource.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImageSource.h; sourceTree = "<group>"; };
 		5550CB411E955E3C00111AA0 /* ImageTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageTypes.h; sourceTree = "<group>"; };
 		555130001E7CCCCA00A69E38 /* DecodingOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DecodingOptions.h; sourceTree = "<group>"; };
+		5553592022441A16008F5EC9 /* SVGAnimatedDecoratedProperty.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SVGAnimatedDecoratedProperty.h; sourceTree = "<group>"; };
+		5553592122441B97008F5EC9 /* SVGDecoratedEnumeration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SVGDecoratedEnumeration.h; sourceTree = "<group>"; };
+		5553592222441BE9008F5EC9 /* SVGDecoratedPrimitive.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SVGDecoratedPrimitive.h; sourceTree = "<group>"; };
+		5553592322441C18008F5EC9 /* SVGDecoratedProperty.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SVGDecoratedProperty.h; sourceTree = "<group>"; };
 		555B87EA1CAAF0AB00349425 /* ImageDecoderCG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageDecoderCG.cpp; sourceTree = "<group>"; };
 		555B87EB1CAAF0AB00349425 /* ImageDecoderCG.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageDecoderCG.h; sourceTree = "<group>"; };
 		5576A5621D88A70800CCC04C /* ImageFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageFrame.cpp; sourceTree = "<group>"; };
@@ -9469,7 +9463,6 @@
 		71C29E31203CE76C008F36D2 /* CSSAnimation.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CSSAnimation.idl; sourceTree = "<group>"; };
 		71C5BB1B1FB611EA0007A2AE /* Animatable.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Animatable.idl; sourceTree = "<group>"; };
 		71C916071D1483A300ACA47D /* UserInterfaceLayoutDirection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserInterfaceLayoutDirection.h; sourceTree = "<group>"; };
-		71CC7A1F152A0BFE009EEAF9 /* SVGAnimatedEnumeration.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGAnimatedEnumeration.cpp; sourceTree = "<group>"; };
 		71CE2C512209DC7F00C494BD /* MouseEventIOS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MouseEventIOS.cpp; sourceTree = "<group>"; };
 		71D02D901DB55C4E00DD5CF5 /* main.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = main.js; sourceTree = "<group>"; };
 		71D02D921DB55C4E00DD5CF5 /* media-controller.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "media-controller.js"; sourceTree = "<group>"; };
@@ -9496,7 +9489,6 @@
 		71EFCEDA202B388F00D7C411 /* AnimationEffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AnimationEffect.cpp; sourceTree = "<group>"; };
 		71EFCEDE202B39C700D7C411 /* JSAnimationEffectCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSAnimationEffectCustom.cpp; sourceTree = "<group>"; };
 		71F936F71DD4F99B00922CC7 /* tracks-support.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "tracks-support.js"; sourceTree = "<group>"; };
-		71FB967A1383D64600AC8A4C /* SVGAnimatedEnumerationPropertyTearOff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGAnimatedEnumerationPropertyTearOff.h; sourceTree = "<group>"; };
 		721443452240C8BA00F12FF7 /* SVGAnimatedValueProperty.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SVGAnimatedValueProperty.h; sourceTree = "<group>"; };
 		721443462240CAD200F12FF7 /* SVGValueProperty.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SVGValueProperty.h; sourceTree = "<group>"; };
 		723F97BC2238EE08007F079C /* SVGAttributeAnimationController.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = SVGAttributeAnimationController.cpp; sourceTree = "<group>"; };
@@ -9734,8 +9726,6 @@
 		7C33F3601B4A050400502CAF /* JSDocumentFragmentCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDocumentFragmentCustom.cpp; sourceTree = "<group>"; };
 		7C39C3621DDA864900FEFB29 /* SVGLengthListValues.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGLengthListValues.cpp; sourceTree = "<group>"; };
 		7C39C3631DDA864900FEFB29 /* SVGLengthListValues.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGLengthListValues.h; sourceTree = "<group>"; };
-		7C39C3681DDB86D300FEFB29 /* SVGNumberListValues.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGNumberListValues.cpp; sourceTree = "<group>"; };
-		7C39C3691DDB86D300FEFB29 /* SVGNumberListValues.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGNumberListValues.h; sourceTree = "<group>"; };
 		7C39C36C1DDB8BB000FEFB29 /* SVGTransformListValues.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGTransformListValues.cpp; sourceTree = "<group>"; };
 		7C39C36D1DDB8BB000FEFB29 /* SVGTransformListValues.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGTransformListValues.h; sourceTree = "<group>"; };
 		7C39C36E1DDBA3E000FEFB29 /* SVGPathSegListValues.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGPathSegListValues.cpp; sourceTree = "<group>"; };
@@ -16207,7 +16197,7 @@
 		081CDFBD126ECFE800D215CA /* properties */ = {
 			isa = PBXGroup;
 			children = (
-				71FB967A1383D64600AC8A4C /* SVGAnimatedEnumerationPropertyTearOff.h */,
+				5553592022441A16008F5EC9 /* SVGAnimatedDecoratedProperty.h */,
 				088A0DFB126EF1DB00978F7A /* SVGAnimatedListPropertyTearOff.h */,
 				55FA7FFC2110F813005AEFE7 /* SVGAnimatedPathSegListPropertyTearOff.cpp */,
 				089A8E06128D8B3D00E7A534 /* SVGAnimatedPathSegListPropertyTearOff.h */,
@@ -16227,7 +16217,6 @@
 				55EE535B223B2A0C00FBA944 /* SVGAnimatedPropertyPairAnimatorImpl.h */,
 				088A0DFF126EF1DB00978F7A /* SVGAnimatedPropertyTearOff.h */,
 				55FA7FFE21110E6E005AEFE7 /* SVGAnimatedPropertyType.h */,
-				08525E621278C00100A84778 /* SVGAnimatedStaticPropertyTearOff.h */,
 				085A15921289A8DD002710E3 /* SVGAnimatedTransformListPropertyTearOff.h */,
 				721443452240C8BA00F12FF7 /* SVGAnimatedValueProperty.h */,
 				55BE025F223B29C50032F08A /* SVGAnimationAdditiveFunction.h */,
@@ -16247,6 +16236,9 @@
 				55346AF021150FAF0059BCDD /* SVGAttributeOwnerProxy.h */,
 				55346AFA2117FFAF0059BCDD /* SVGAttributeOwnerProxyImpl.h */,
 				55FA7FF6210FBE3E005AEFE7 /* SVGAttributeRegistry.h */,
+				5553592122441B97008F5EC9 /* SVGDecoratedEnumeration.h */,
+				5553592222441BE9008F5EC9 /* SVGDecoratedPrimitive.h */,
+				5553592322441C18008F5EC9 /* SVGDecoratedProperty.h */,
 				55D70D21223B00BB00044B8E /* SVGLegacyAnimatedProperty.cpp */,
 				55D70D20223B009100044B8E /* SVGLegacyAnimatedProperty.h */,
 				55D70D22223B00EA00044B8E /* SVGLegacyProperty.h */,
@@ -16270,7 +16262,6 @@
 				55BE0257223B29C00032F08A /* SVGPropertyRegistry.h */,
 				088A0E02126EF1DB00978F7A /* SVGPropertyTearOff.h */,
 				088A0E03126EF1DB00978F7A /* SVGPropertyTraits.h */,
-				0813A4E91284132600992511 /* SVGStaticPropertyTearOff.h */,
 				721443462240CAD200F12FF7 /* SVGValueProperty.h */,
 				7266F02522430F8C00833975 /* SVGValuePropertyList.h */,
 			);
@@ -24135,12 +24126,8 @@
 				B22277E30D00BF1F0071B782 /* SVGAnimateColorElement.cpp */,
 				B22277E40D00BF1F0071B782 /* SVGAnimateColorElement.h */,
 				B22277E50D00BF1F0071B782 /* SVGAnimateColorElement.idl */,
-				4362C7B813AC6F1A00344BEB /* SVGAnimatedAngle.cpp */,
-				087B84951272CEC700A14417 /* SVGAnimatedAngle.h */,
 				B22277E60D00BF1F0071B782 /* SVGAnimatedAngle.idl */,
 				B22277E70D00BF1F0071B782 /* SVGAnimatedBoolean.idl */,
-				71CC7A1F152A0BFE009EEAF9 /* SVGAnimatedEnumeration.cpp */,
-				08D46CE2127AD5FC0089694B /* SVGAnimatedEnumeration.h */,
 				B22277E80D00BF1F0071B782 /* SVGAnimatedEnumeration.idl */,
 				B22277E90D00BF1F0071B782 /* SVGAnimatedInteger.idl */,
 				4381763A13A697D4007D1187 /* SVGAnimatedLength.cpp */,
@@ -24150,8 +24137,6 @@
 				089021AC126EF5E90092D5EA /* SVGAnimatedLengthList.h */,
 				B22277EB0D00BF1F0071B782 /* SVGAnimatedLengthList.idl */,
 				B22277EC0D00BF1F0071B782 /* SVGAnimatedNumber.idl */,
-				4331AC7713B6870000A9E5AE /* SVGAnimatedNumberList.cpp */,
-				08B35B16127B6A88005314DD /* SVGAnimatedNumberList.h */,
 				B22277ED0D00BF1F0071B782 /* SVGAnimatedNumberList.idl */,
 				0863951313B5FE5700BB344D /* SVGAnimatedPath.cpp */,
 				0863951413B5FE5700BB344D /* SVGAnimatedPath.h */,
@@ -31917,19 +31902,14 @@
 				24D912B813CA9A6900D21915 /* SVGAltGlyphItemElement.h in Headers */,
 				B22279770D00BF220071B782 /* SVGAngle.h in Headers */,
 				B222797A0D00BF220071B782 /* SVGAnimateColorElement.h in Headers */,
-				087B84961272CEC800A14417 /* SVGAnimatedAngle.h in Headers */,
-				08D46CE3127AD5FC0089694B /* SVGAnimatedEnumeration.h in Headers */,
-				71FB967B1383D64600AC8A4C /* SVGAnimatedEnumerationPropertyTearOff.h in Headers */,
 				089021A9126EF5DE0092D5EA /* SVGAnimatedLength.h in Headers */,
 				089021AD126EF5E90092D5EA /* SVGAnimatedLengthList.h in Headers */,
 				088A0E04126EF1DB00978F7A /* SVGAnimatedListPropertyTearOff.h in Headers */,
-				08B35B17127B6A88005314DD /* SVGAnimatedNumberList.h in Headers */,
 				0863951613B5FE5700BB344D /* SVGAnimatedPath.h in Headers */,
 				089A8E07128D8B3D00E7A534 /* SVGAnimatedPathSegListPropertyTearOff.h in Headers */,
 				088A0E06126EF1DB00978F7A /* SVGAnimatedPropertyDescription.h in Headers */,
 				088A0E08126EF1DB00978F7A /* SVGAnimatedPropertyTearOff.h in Headers */,
 				55FA7FFF21110E6E005AEFE7 /* SVGAnimatedPropertyType.h in Headers */,
-				08525E631278C00100A84778 /* SVGAnimatedStaticPropertyTearOff.h in Headers */,
 				08250939128BD4D800E2ED8E /* SVGAnimatedTransformList.h in Headers */,
 				085A15931289A8DD002710E3 /* SVGAnimatedTransformListPropertyTearOff.h in Headers */,
 				439D334313A6911C00C20F4F /* SVGAnimatedType.h in Headers */,
@@ -32108,7 +32088,6 @@
 				B2227AA30D00BF220071B782 /* SVGScriptElement.h in Headers */,
 				B2227AA60D00BF220071B782 /* SVGSetElement.h in Headers */,
 				E4AFD0100DAF335500F5F55C /* SVGSMILElement.h in Headers */,
-				0813A4EA1284132600992511 /* SVGStaticPropertyTearOff.h in Headers */,
 				B2227AA90D00BF220071B782 /* SVGStopElement.h in Headers */,
 				B2227AAC0D00BF220071B782 /* SVGStringList.h in Headers */,
 				B2227AB80D00BF220071B782 /* SVGStyleElement.h in Headers */,
diff --git a/Source/WebCore/svg/SVGAngle.h b/Source/WebCore/svg/SVGAngle.h
index 46af5df..9c61732 100644
--- a/Source/WebCore/svg/SVGAngle.h
+++ b/Source/WebCore/svg/SVGAngle.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-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
@@ -26,32 +26,37 @@
 #pragma once
 
 #include "SVGAngleValue.h"
-#include "SVGPropertyTearOff.h"
+#include "SVGValueProperty.h"
 
 namespace WebCore {
 
-class SVGAngle : public SVGPropertyTearOff<SVGAngleValue> {
+class SVGAngle : public SVGValueProperty<SVGAngleValue> {
+    using Base = SVGValueProperty<SVGAngleValue>;
+    using Base::Base;
+    using Base::m_value;
+
 public:
-    static Ref<SVGAngle> create(SVGLegacyAnimatedProperty& animatedProperty, SVGPropertyRole role, SVGAngleValue& value)
+    static Ref<SVGAngle> create(const SVGAngleValue& value = { })
     {
-        return adoptRef(*new SVGAngle(animatedProperty, role, value));
+        return adoptRef(*new SVGAngle(value));
     }
 
-    static Ref<SVGAngle> create(const SVGAngleValue& initialValue = { })
+    static Ref<SVGAngle> create(SVGPropertyOwner* owner, SVGPropertyAccess access, const SVGAngleValue& value = { })
     {
-        return adoptRef(*new SVGAngle(initialValue));
+        return adoptRef(*new SVGAngle(owner, access, value));
     }
 
-    template<typename T> static ExceptionOr<Ref<SVGAngle>> create(ExceptionOr<T>&& initialValue)
+    template<typename T>
+    static ExceptionOr<Ref<SVGAngle>> create(ExceptionOr<T>&& value)
     {
-        if (initialValue.hasException())
-            return initialValue.releaseException();
-        return create(initialValue.releaseReturnValue());
+        if (value.hasException())
+            return value.releaseException();
+        return adoptRef(*new SVGAngle(value.releaseReturnValue()));
     }
 
     SVGAngleValue::Type unitType()
     {
-        return propertyReference().unitType();
+        return m_value.unitType();
     }
 
     ExceptionOr<void> setValueForBindings(float value)
@@ -59,15 +64,14 @@
         if (isReadOnly())
             return Exception { NoModificationAllowedError };
 
-        propertyReference().setValue(value);
+        m_value.setValue(value);
         commitChange();
-
         return { };
     }
     
     float valueForBindings()
     {
-        return propertyReference().value();
+        return m_value.value();
     }
 
     ExceptionOr<void> setValueInSpecifiedUnits(float valueInSpecifiedUnits)
@@ -75,15 +79,14 @@
         if (isReadOnly())
             return Exception { NoModificationAllowedError };
 
-        propertyReference().setValueInSpecifiedUnits(valueInSpecifiedUnits);
+        m_value.setValueInSpecifiedUnits(valueInSpecifiedUnits);
         commitChange();
-        
         return { };
     }
     
     float valueInSpecifiedUnits()
     {
-        return propertyReference().valueInSpecifiedUnits();
+        return m_value.valueInSpecifiedUnits();
     }
 
     ExceptionOr<void> setValueAsString(const String& value)
@@ -91,7 +94,7 @@
         if (isReadOnly())
             return Exception { NoModificationAllowedError };
 
-        auto result = propertyReference().setValueAsString(value);
+        auto result = m_value.setValueAsString(value);
         if (result.hasException())
             return result;
         
@@ -99,9 +102,9 @@
         return result;
     }
 
-    String valueAsString()
+    String valueAsString() const override
     {
-        return propertyReference().valueAsString();
+        return m_value.valueAsString();
     }
 
     ExceptionOr<void> newValueSpecifiedUnits(unsigned short unitType, float valueInSpecifiedUnits)
@@ -109,7 +112,7 @@
         if (isReadOnly())
             return Exception { NoModificationAllowedError };
 
-        auto result = propertyReference().newValueSpecifiedUnits(unitType, valueInSpecifiedUnits);
+        auto result = m_value.newValueSpecifiedUnits(unitType, valueInSpecifiedUnits);
         if (result.hasException())
             return result;
         
@@ -122,24 +125,13 @@
         if (isReadOnly())
             return Exception { NoModificationAllowedError };
 
-        auto result = propertyReference().convertToSpecifiedUnits(unitType);
+        auto result = m_value.convertToSpecifiedUnits(unitType);
         if (result.hasException())
             return result;
         
         commitChange();
         return result;
     }
-
-private:
-    SVGAngle(SVGLegacyAnimatedProperty& animatedProperty, SVGPropertyRole role, SVGAngleValue& value)
-        : SVGPropertyTearOff<SVGAngleValue>(&animatedProperty, role, value)
-    {
-    }
-
-    explicit SVGAngle(const SVGAngleValue& initialValue)
-        : SVGPropertyTearOff<SVGAngleValue>(initialValue)
-    {
-    }
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/svg/SVGAnimatedAngle.cpp b/Source/WebCore/svg/SVGAnimatedAngle.cpp
deleted file mode 100644
index 5621d74..0000000
--- a/Source/WebCore/svg/SVGAnimatedAngle.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2011, 2012. 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 "SVGAnimatedAngle.h"
-
-#include "SVGAnimateElementBase.h"
-#include "SVGMarkerElement.h"
-
-namespace WebCore {
-
-SVGAnimatedAngleAnimator::SVGAnimatedAngleAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement)
-    : SVGAnimatedTypeAnimator(AnimatedAngle, animationElement, contextElement)
-{
-}
-
-std::unique_ptr<SVGAnimatedType> SVGAnimatedAngleAnimator::constructFromString(const String& string)
-{
-    return SVGAnimatedType::create(SVGPropertyTraits<std::pair<SVGAngleValue, unsigned>>::fromString(string));
-}
-
-std::unique_ptr<SVGAnimatedType> SVGAnimatedAngleAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
-    return constructFromBaseValues<SVGAnimatedAngle, SVGAnimatedEnumeration>(animatedTypes);
-}
-
-void SVGAnimatedAngleAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
-    stopAnimValAnimationForTypes<SVGAnimatedAngle, SVGAnimatedEnumeration>(animatedTypes);
-}
-
-void SVGAnimatedAngleAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType& type)
-{
-    resetFromBaseValues<SVGAnimatedAngle, SVGAnimatedEnumeration>(animatedTypes, type);
-}
-
-void SVGAnimatedAngleAnimator::animValWillChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
-    animValWillChangeForTypes<SVGAnimatedAngle, SVGAnimatedEnumeration>(animatedTypes);
-}
-
-void SVGAnimatedAngleAnimator::animValDidChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
-    animValDidChangeForTypes<SVGAnimatedAngle, SVGAnimatedEnumeration>(animatedTypes);
-}
-
-void SVGAnimatedAngleAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimatedType* to)
-{
-    ASSERT(from->type() == AnimatedAngle);
-    ASSERT(from->type() == to->type());
-
-    const auto& fromAngleAndEnumeration = from->as<std::pair<SVGAngleValue, unsigned>>();
-    auto& toAngleAndEnumeration = to->as<std::pair<SVGAngleValue, unsigned>>();
-    // Only respect by animations, if from and by are both specified in angles (and not eg. 'auto').
-    if (fromAngleAndEnumeration.second != toAngleAndEnumeration.second || fromAngleAndEnumeration.second != SVGMarkerOrientAngle)
-        return;
-    const auto& fromAngle = fromAngleAndEnumeration.first;
-    auto& toAngle = toAngleAndEnumeration.first;
-    toAngle.setValue(toAngle.value() + fromAngle.value());
-}
-
-void SVGAnimatedAngleAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated)
-{
-    ASSERT(m_animationElement);
-    ASSERT(m_contextElement);
-
-    const auto& fromAngleAndEnumeration = (m_animationElement->animationMode() == AnimationMode::To ? animated : from)->as<std::pair<SVGAngleValue, unsigned>>();
-    auto& toAngleAndEnumeration = to->as<std::pair<SVGAngleValue, unsigned>>();
-    auto& toAtEndOfDurationAngleAndEnumeration = toAtEndOfDuration->as<std::pair<SVGAngleValue, unsigned>>();
-    auto& animatedAngleAndEnumeration = animated->as<std::pair<SVGAngleValue, unsigned>>();
-
-    if (fromAngleAndEnumeration.second != toAngleAndEnumeration.second) {
-        // Discrete animation - no linear interpolation possible between values (e.g. auto to angle).
-        if (percentage < 0.5f) {
-            animatedAngleAndEnumeration.second = fromAngleAndEnumeration.second;
-            if (fromAngleAndEnumeration.second == SVGMarkerOrientAngle)
-                animatedAngleAndEnumeration.first = fromAngleAndEnumeration.first;
-            else
-                animatedAngleAndEnumeration.first.setValue(0);
-            return;
-        }
-        animatedAngleAndEnumeration.second = toAngleAndEnumeration.second;
-        if (toAngleAndEnumeration.second == SVGMarkerOrientAngle)
-            animatedAngleAndEnumeration.first = toAngleAndEnumeration.first;
-        else
-            animatedAngleAndEnumeration.first.setValue(0);
-        return;
-    }
-
-    if (fromAngleAndEnumeration.second == SVGMarkerOrientAngle) {
-        // Regular from angle to angle animation, with support for smooth interpolation, and additive and accumulated animation.
-        animatedAngleAndEnumeration.second = SVGMarkerOrientAngle;
-
-        auto& animatedSVGAngle = animatedAngleAndEnumeration.first;
-        const auto& toAtEndOfDurationSVGAngle = toAtEndOfDurationAngleAndEnumeration.first;
-        float animatedAngle = animatedSVGAngle.value();
-        m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromAngleAndEnumeration.first.value(), toAngleAndEnumeration.first.value(), toAtEndOfDurationSVGAngle.value(), animatedAngle);
-        animatedSVGAngle.setValue(animatedAngle);
-        return;
-    }
-
-    // auto, auto-start-reverse, or unknown.
-    animatedAngleAndEnumeration.first.setValue(0);
-
-    if (fromAngleAndEnumeration.second == SVGMarkerOrientAuto || fromAngleAndEnumeration.second == SVGMarkerOrientAutoStartReverse)
-        animatedAngleAndEnumeration.second = fromAngleAndEnumeration.second;
-    else
-        animatedAngleAndEnumeration.second = SVGMarkerOrientUnknown;
-}
-
-float SVGAnimatedAngleAnimator::calculateDistance(const String& fromString, const String& toString)
-{
-    auto from = SVGAngleValue();
-    from.setValueAsString(fromString);
-    auto to = SVGAngleValue();
-    to.setValueAsString(toString);
-    return fabsf(to.value() - from.value());
-}
-
-}
diff --git a/Source/WebCore/svg/SVGAnimatedAngle.h b/Source/WebCore/svg/SVGAnimatedAngle.h
deleted file mode 100644
index d491568..0000000
--- a/Source/WebCore/svg/SVGAnimatedAngle.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010. 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.
- */
-
-#pragma once
-
-#include "SVGAngle.h"
-#include "SVGAnimatedPropertyTearOff.h"
-#include "SVGAnimatedTypeAnimator.h"
-#include "SVGAttribute.h"
-
-namespace WebCore {
-
-class SVGAnimationElement;
-
-using SVGAnimatedAngle = SVGAnimatedPropertyTearOff<SVGAngle>;
-using SVGAnimatedAngleAttribute = SVGAnimatedAttribute<SVGAnimatedAngle>;
-
-class SVGAnimatedAngleAnimator final : public SVGAnimatedTypeAnimator {
-public:
-    SVGAnimatedAngleAnimator(SVGAnimationElement*, SVGElement*);
-
-    std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override;
-    std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override;
-    void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override;
-    void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType&) override;
-    void animValWillChange(const SVGElementAnimatedPropertyList&) override;
-    void animValDidChange(const SVGElementAnimatedPropertyList&) override;
-
-    void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override;
-
-    void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override;
-    float calculateDistance(const String& fromString, const String& toString) override;
-};
-
-} // namespace WebCore
diff --git a/Source/WebCore/svg/SVGAnimatedEnumeration.cpp b/Source/WebCore/svg/SVGAnimatedEnumeration.cpp
deleted file mode 100644
index 836440a..0000000
--- a/Source/WebCore/svg/SVGAnimatedEnumeration.cpp
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2012. 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 "SVGAnimatedEnumeration.h"
-
-#include "SVGAnimationElement.h"
-#include "SVGComponentTransferFunctionElement.h"
-#include "SVGFEBlendElement.h"
-#include "SVGFEColorMatrixElement.h"
-#include "SVGFECompositeElement.h"
-#include "SVGFEConvolveMatrixElement.h"
-#include "SVGFEDisplacementMapElement.h"
-#include "SVGFEMorphologyElement.h"
-#include "SVGFETurbulenceElement.h"
-#include "SVGGradientElement.h"
-#include "SVGMarkerElement.h"
-#include "SVGNames.h"
-#include "SVGTextContentElement.h"
-#include "SVGTextPathElement.h"
-#include "SVGUnitTypes.h"
-
-namespace WebCore {
-
-static inline unsigned enumerationValueForTargetAttribute(SVGElement* targetElement, const QualifiedName& attrName, const String& value)
-{
-    ASSERT(targetElement);
-    if (attrName == SVGNames::clipPathUnitsAttr
-        || attrName == SVGNames::filterUnitsAttr
-        || attrName == SVGNames::gradientUnitsAttr
-        || attrName == SVGNames::maskContentUnitsAttr
-        || attrName == SVGNames::maskUnitsAttr
-        || attrName == SVGNames::patternContentUnitsAttr
-        || attrName == SVGNames::patternUnitsAttr
-        || attrName == SVGNames::primitiveUnitsAttr)
-        return SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
-
-    if (attrName == SVGNames::lengthAdjustAttr)
-        return SVGPropertyTraits<SVGLengthAdjustType>::fromString(value);
-    if (attrName == SVGNames::markerUnitsAttr)
-        return SVGPropertyTraits<SVGMarkerUnitsType>::fromString(value);
-    if (attrName == SVGNames::methodAttr)
-        return SVGPropertyTraits<SVGTextPathMethodType>::fromString(value);
-    if (attrName == SVGNames::spacingAttr)
-        return SVGPropertyTraits<SVGTextPathSpacingType>::fromString(value);
-    if (attrName == SVGNames::spreadMethodAttr)
-        return SVGPropertyTraits<SVGSpreadMethodType>::fromString(value);
-
-    if (attrName == SVGNames::edgeModeAttr)
-        return SVGPropertyTraits<EdgeModeType>::fromString(value);
-
-    if (attrName == SVGNames::operatorAttr) {
-        if (targetElement->hasTagName(SVGNames::feCompositeTag))
-            return SVGPropertyTraits<CompositeOperationType>::fromString(value);
-        ASSERT(targetElement->hasTagName(SVGNames::feMorphologyTag));
-        return SVGPropertyTraits<MorphologyOperatorType>::fromString(value);
-    }
-
-    if (attrName == SVGNames::typeAttr) {
-        if (targetElement->hasTagName(SVGNames::feColorMatrixTag))
-            return SVGPropertyTraits<ColorMatrixType>::fromString(value);
-        if (targetElement->hasTagName(SVGNames::feTurbulenceTag))
-            return static_cast<unsigned>(SVGPropertyTraits<TurbulenceType>::fromString(value));
-
-        ASSERT(targetElement->hasTagName(SVGNames::feFuncATag)
-               || targetElement->hasTagName(SVGNames::feFuncBTag)
-               || targetElement->hasTagName(SVGNames::feFuncGTag)
-               || targetElement->hasTagName(SVGNames::feFuncRTag));
-        return SVGPropertyTraits<ComponentTransferType>::fromString(value);
-    }
-
-    if (attrName == SVGNames::modeAttr) {
-        BlendMode mode = BlendMode::Normal;
-        parseBlendMode(value, mode);
-        return static_cast<unsigned>(mode);
-    }
-    if (attrName == SVGNames::stitchTilesAttr)
-        return SVGPropertyTraits<SVGStitchOptions>::fromString(value);
-    if (attrName == SVGNames::xChannelSelectorAttr)
-        return SVGPropertyTraits<ChannelSelectorType>::fromString(value);
-    if (attrName == SVGNames::yChannelSelectorAttr)
-        return SVGPropertyTraits<ChannelSelectorType>::fromString(value);
-
-    ASSERT_NOT_REACHED();
-    return 0;
-}
-
-SVGAnimatedEnumerationAnimator::SVGAnimatedEnumerationAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement)
-    : SVGAnimatedTypeAnimator(AnimatedEnumeration, animationElement, contextElement)
-{
-}
-
-std::unique_ptr<SVGAnimatedType> SVGAnimatedEnumerationAnimator::constructFromString(const String& string)
-{
-    ASSERT(m_animationElement);
-    return SVGAnimatedType::create(enumerationValueForTargetAttribute(m_animationElement->targetElement(), m_animationElement->attributeName(), string));
-}
-
-std::unique_ptr<SVGAnimatedType> SVGAnimatedEnumerationAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
-    return constructFromBaseValue<SVGAnimatedEnumeration>(animatedTypes);
-}
-
-void SVGAnimatedEnumerationAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
-    stopAnimValAnimationForType<SVGAnimatedEnumeration>(animatedTypes);
-}
-
-void SVGAnimatedEnumerationAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType& type)
-{
-    resetFromBaseValue<SVGAnimatedEnumeration>(animatedTypes, type);
-}
-
-void SVGAnimatedEnumerationAnimator::animValWillChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
-    animValWillChangeForType<SVGAnimatedEnumeration>(animatedTypes);
-}
-
-void SVGAnimatedEnumerationAnimator::animValDidChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
-    animValDidChangeForType<SVGAnimatedEnumeration>(animatedTypes);
-}
-
-void SVGAnimatedEnumerationAnimator::addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*)
-{
-    ASSERT_NOT_REACHED();
-}
-
-void SVGAnimatedEnumerationAnimator::calculateAnimatedValue(float percentage, unsigned, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType*, SVGAnimatedType* animated)
-{
-    ASSERT(m_animationElement);
-    ASSERT(m_contextElement);
-
-    const auto fromEnumeration = (m_animationElement->animationMode() == AnimationMode::To ? animated : from)->as<unsigned>();
-    const auto toEnumeration = to->as<unsigned>();
-    auto& animatedEnumeration = animated->as<unsigned>();
-
-    m_animationElement->animateDiscreteType<unsigned>(percentage, fromEnumeration, toEnumeration, animatedEnumeration);
-}
-
-float SVGAnimatedEnumerationAnimator::calculateDistance(const String&, const String&)
-{
-    // No paced animations for enumerations.
-    return -1;
-}
-
-}
diff --git a/Source/WebCore/svg/SVGAnimatedEnumeration.h b/Source/WebCore/svg/SVGAnimatedEnumeration.h
deleted file mode 100644
index 488ab89..0000000
--- a/Source/WebCore/svg/SVGAnimatedEnumeration.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010, 2012. 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.
- */
-
-#pragma once
-
-#include "SVGAnimatedEnumerationPropertyTearOff.h"
-#include "SVGAnimatedTypeAnimator.h"
-#include "SVGAttributeAccessor.h"
-
-namespace WebCore {
-
-class SVGAnimationElement;
-
-using SVGAnimatedEnumeration = SVGAnimatedStaticPropertyTearOff<unsigned>;
-
-template<typename EnumType>
-using SVGAnimatedEnumerationAttribute = SVGAnimatedAttribute<SVGAnimatedEnumerationPropertyTearOff<EnumType>>;
-
-template<typename OwnerType, typename EnumType>
-using SVGAnimatedEnumerationAttributeAccessor = SVGAnimatedAttributeAccessor<OwnerType, SVGAnimatedEnumerationAttribute<EnumType>, AnimatedEnumeration>;
-
-class SVGAnimatedEnumerationAnimator final : public SVGAnimatedTypeAnimator {
-public:
-    SVGAnimatedEnumerationAnimator(SVGAnimationElement*, SVGElement*);
-
-    std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override;
-    std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override;
-    void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override;
-    void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType&) override;
-    void animValWillChange(const SVGElementAnimatedPropertyList&) override;
-    void animValDidChange(const SVGElementAnimatedPropertyList&) override;
-
-    void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override;
-    void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override;
-    float calculateDistance(const String& fromString, const String& toString) override;
-};
-
-} // namespace WebCore
diff --git a/Source/WebCore/svg/SVGAnimatedType.h b/Source/WebCore/svg/SVGAnimatedType.h
index 69e86f5..a119d315 100644
--- a/Source/WebCore/svg/SVGAnimatedType.h
+++ b/Source/WebCore/svg/SVGAnimatedType.h
@@ -45,24 +45,6 @@
         return std::make_unique<SVGAnimatedType>(WTFMove(property));
     }
 
-    template<typename PropertyType1, typename PropertyType2>
-    static std::unique_ptr<SVGAnimatedType> create()
-    {
-        return std::make_unique<SVGAnimatedType>(SVGPropertyTraits<std::pair<PropertyType1, PropertyType2>>::initialValue());
-    }
-
-    template<typename PropertyType1, typename PropertyType2>
-    static std::unique_ptr<SVGAnimatedType> create(const std::pair<PropertyType1, PropertyType2>& properties)
-    {
-        return std::make_unique<SVGAnimatedType>(properties);
-    }
-
-    template<typename PropertyType1, typename PropertyType2>
-    static std::unique_ptr<SVGAnimatedType> create(std::pair<PropertyType1, PropertyType2>&& properties)
-    {
-        return std::make_unique<SVGAnimatedType>(WTFMove(properties));
-    }
-
     template<typename PropertyType>
     SVGAnimatedType(const PropertyType& property)
         : m_value(std::make_unique<PropertyType>(property).release())
@@ -75,18 +57,6 @@
     {
     }
 
-    template<typename PropertyType1, typename PropertyType2>
-    SVGAnimatedType(const std::pair<PropertyType1, PropertyType2>& properties)
-        : m_value(std::make_unique<std::pair<PropertyType1, PropertyType2>>(properties).release())
-    {
-    }
-
-    template<typename PropertyType1, typename PropertyType2>
-    SVGAnimatedType(std::pair<PropertyType1, PropertyType2>&& properties)
-        : m_value(std::make_unique<std::pair<PropertyType1, PropertyType2>>(WTFMove(properties)).release())
-    {
-    }
-
     ~SVGAnimatedType()
     {
         WTF::visit([](auto& value) {
@@ -111,8 +81,6 @@
     AnimatedPropertyType type() const
     {
         static AnimatedPropertyType animatedTypes[] = {
-            AnimatedAngle,
-            AnimatedEnumeration,
             AnimatedLength,
             AnimatedLengthList,
             AnimatedPath,
diff --git a/Source/WebCore/svg/SVGAnimatorFactory.h b/Source/WebCore/svg/SVGAnimatorFactory.h
index c94457d..948ea74 100644
--- a/Source/WebCore/svg/SVGAnimatorFactory.h
+++ b/Source/WebCore/svg/SVGAnimatorFactory.h
@@ -19,8 +19,6 @@
 
 #pragma once
 
-#include "SVGAnimatedAngle.h"
-#include "SVGAnimatedEnumeration.h"
 #include "SVGAnimatedLength.h"
 #include "SVGAnimatedLengthList.h"
 #include "SVGAnimatedPath.h"
@@ -38,8 +36,10 @@
         ASSERT(contextElement);
 
         switch (attributeType) {
+        case AnimatedAngle:
         case AnimatedBoolean:
         case AnimatedColor:
+        case AnimatedEnumeration:
         case AnimatedInteger:
         case AnimatedIntegerOptionalInteger:
         case AnimatedNumber:
@@ -51,10 +51,6 @@
         case AnimatedString:
             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:
diff --git a/Source/WebCore/svg/SVGClipPathElement.cpp b/Source/WebCore/svg/SVGClipPathElement.cpp
index bdd35d7..e104c59 100644
--- a/Source/WebCore/svg/SVGClipPathElement.cpp
+++ b/Source/WebCore/svg/SVGClipPathElement.cpp
@@ -39,28 +39,23 @@
     , SVGExternalResourcesRequired(this)
 {
     ASSERT(hasTagName(SVGNames::clipPathTag));
-    registerAttributes();
-}
+
+    static std::once_flag onceFlag;
+    std::call_once(onceFlag, [] {
+        PropertyRegistry::registerProperty<SVGNames::clipPathUnitsAttr, SVGUnitTypes::SVGUnitType, &SVGClipPathElement::m_clipPathUnits>();
+    });}
 
 Ref<SVGClipPathElement> SVGClipPathElement::create(const QualifiedName& tagName, Document& document)
 {
     return adoptRef(*new SVGClipPathElement(tagName, document));
 }
 
-void SVGClipPathElement::registerAttributes()
-{
-    auto& registry = attributeRegistry();
-    if (!registry.isEmpty())
-        return;
-    registry.registerAttribute<SVGNames::clipPathUnitsAttr, SVGUnitTypes::SVGUnitType, &SVGClipPathElement::m_clipPathUnits>();
-}
-
 void SVGClipPathElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     if (name == SVGNames::clipPathUnitsAttr) {
         auto propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
         if (propertyValue > 0)
-            m_clipPathUnits.setValue(propertyValue);
+            m_clipPathUnits->setBaseValInternal<SVGUnitTypes::SVGUnitType>(propertyValue);
         return;
     }
 
@@ -70,7 +65,7 @@
 
 void SVGClipPathElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    if (isKnownAttribute(attrName)) {
+    if (PropertyRegistry::isKnownAttribute(attrName)) {
         InstanceInvalidationGuard guard(*this);
 
         if (RenderObject* object = renderer())
diff --git a/Source/WebCore/svg/SVGClipPathElement.h b/Source/WebCore/svg/SVGClipPathElement.h
index 03c1add..cf805f1 100644
--- a/Source/WebCore/svg/SVGClipPathElement.h
+++ b/Source/WebCore/svg/SVGClipPathElement.h
@@ -21,7 +21,6 @@
 
 #pragma once
 
-#include "SVGAnimatedEnumeration.h"
 #include "SVGExternalResourcesRequired.h"
 #include "SVGGraphicsElement.h"
 #include "SVGUnitTypes.h"
@@ -35,25 +34,18 @@
 public:
     static Ref<SVGClipPathElement> create(const QualifiedName&, Document&);
 
-    SVGUnitTypes::SVGUnitType clipPathUnits() const { return m_clipPathUnits.currentValue(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedEnumeration> clipPathUnitsAnimated() { return m_clipPathUnits.animatedProperty(attributeOwnerProxy()); }
+    SVGUnitTypes::SVGUnitType clipPathUnits() const { return m_clipPathUnits->currentValue<SVGUnitTypes::SVGUnitType>(); }
+    SVGAnimatedEnumeration& clipPathUnitsAnimated() { return m_clipPathUnits; }
 
 private:
     SVGClipPathElement(const QualifiedName&, Document&);
 
     using AttributeOwnerProxy = SVGAttributeOwnerProxyImpl<SVGClipPathElement, SVGGraphicsElement, SVGExternalResourcesRequired>;
-    static AttributeOwnerProxy::AttributeRegistry& attributeRegistry() { return AttributeOwnerProxy::attributeRegistry(); }
-    static void registerAttributes();
     const SVGAttributeOwnerProxy& attributeOwnerProxy() const final { return m_attributeOwnerProxy; }
 
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGClipPathElement, SVGGraphicsElement, SVGExternalResourcesRequired>;
     const SVGPropertyRegistry& propertyRegistry() const final { return m_propertyRegistry; }
 
-    static bool isKnownAttribute(const QualifiedName& attributeName)
-    {
-        return AttributeOwnerProxy::isKnownAttribute(attributeName) || PropertyRegistry::isKnownAttribute(attributeName);
-    }
-
     void parseAttribute(const QualifiedName&, const AtomicString&) final;
     void svgAttributeChanged(const QualifiedName&) final;
     void childrenChanged(const ChildChange&) final;
@@ -66,7 +58,7 @@
 
     AttributeOwnerProxy m_attributeOwnerProxy { *this };
     PropertyRegistry m_propertyRegistry { *this };
-    SVGAnimatedEnumerationAttribute<SVGUnitTypes::SVGUnitType> m_clipPathUnits { SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE };
+    Ref<SVGAnimatedEnumeration> m_clipPathUnits { SVGAnimatedEnumeration::create(this, SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) };
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/svg/SVGComponentTransferFunctionElement.cpp b/Source/WebCore/svg/SVGComponentTransferFunctionElement.cpp
index 531a2c2..01c0329 100644
--- a/Source/WebCore/svg/SVGComponentTransferFunctionElement.cpp
+++ b/Source/WebCore/svg/SVGComponentTransferFunctionElement.cpp
@@ -34,10 +34,9 @@
 SVGComponentTransferFunctionElement::SVGComponentTransferFunctionElement(const QualifiedName& tagName, Document& document)
     : SVGElement(tagName, document)
 {
-    registerAttributes();
-    
     static std::once_flag onceFlag;
     std::call_once(onceFlag, [] {
+        PropertyRegistry::registerProperty<SVGNames::typeAttr, ComponentTransferType, &SVGComponentTransferFunctionElement::m_type>();
         PropertyRegistry::registerProperty<SVGNames::tableValuesAttr, &SVGComponentTransferFunctionElement::m_tableValues>();
         PropertyRegistry::registerProperty<SVGNames::slopeAttr, &SVGComponentTransferFunctionElement::m_slope>();
         PropertyRegistry::registerProperty<SVGNames::interceptAttr, &SVGComponentTransferFunctionElement::m_intercept>();
@@ -47,20 +46,12 @@
     });
 }
 
-void SVGComponentTransferFunctionElement::registerAttributes()
-{
-    auto& registry = attributeRegistry();
-    if (!registry.isEmpty())
-        return;
-    registry.registerAttribute<SVGNames::typeAttr, ComponentTransferType, &SVGComponentTransferFunctionElement::m_type>();
-}
-
 void SVGComponentTransferFunctionElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     if (name == SVGNames::typeAttr) {
         ComponentTransferType propertyValue = SVGPropertyTraits<ComponentTransferType>::fromString(value);
         if (propertyValue > 0)
-            m_type.setValue(propertyValue);
+            m_type->setBaseValInternal<ComponentTransferType>(propertyValue);
         return;
     }
 
diff --git a/Source/WebCore/svg/SVGComponentTransferFunctionElement.h b/Source/WebCore/svg/SVGComponentTransferFunctionElement.h
index 5bfad18..f9d9a5b 100644
--- a/Source/WebCore/svg/SVGComponentTransferFunctionElement.h
+++ b/Source/WebCore/svg/SVGComponentTransferFunctionElement.h
@@ -22,7 +22,6 @@
 #pragma once
 
 #include "FEComponentTransfer.h"
-#include "SVGAnimatedEnumeration.h"
 #include "SVGElement.h"
 
 namespace WebCore {
@@ -73,7 +72,7 @@
 public:
     ComponentTransferFunction transferFunction() const;
 
-    ComponentTransferType type() const { return m_type.currentValue(attributeOwnerProxy()); }
+    ComponentTransferType type() const { return m_type->currentValue<ComponentTransferType>(); }
     const SVGNumberList& tableValues() const { return m_tableValues->currentValue(); }
     float slope() const { return m_slope->currentValue(); }
     float intercept() const { return m_intercept->currentValue(); }
@@ -81,7 +80,7 @@
     float exponent() const { return m_exponent->currentValue(); }
     float offset() const { return m_offset->currentValue(); }
 
-    RefPtr<SVGAnimatedEnumeration> typeAnimated() { return m_type.animatedProperty(attributeOwnerProxy()); }
+    SVGAnimatedEnumeration& typeAnimated() { return m_type; }
     SVGAnimatedNumberList& tableValuesAnimated() { return m_tableValues; }
     SVGAnimatedNumber& slopeAnimated() { return m_slope; }
     SVGAnimatedNumber& interceptAnimated() { return m_intercept; }
@@ -93,18 +92,11 @@
     SVGComponentTransferFunctionElement(const QualifiedName&, Document&);
 
     using AttributeOwnerProxy = SVGAttributeOwnerProxyImpl<SVGComponentTransferFunctionElement, SVGElement>;
-    static AttributeOwnerProxy::AttributeRegistry& attributeRegistry() { return AttributeOwnerProxy::attributeRegistry(); }
-    static void registerAttributes();
     const SVGAttributeOwnerProxy& attributeOwnerProxy() const override { return m_attributeOwnerProxy; }
 
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGComponentTransferFunctionElement, SVGElement>;
     const SVGPropertyRegistry& propertyRegistry() const override { return m_propertyRegistry; }
 
-    static bool isKnownAttribute(const QualifiedName& attributeName)
-    {
-        return AttributeOwnerProxy::isKnownAttribute(attributeName) || PropertyRegistry::isKnownAttribute(attributeName);
-    }
-
     void parseAttribute(const QualifiedName&, const AtomicString&) override;
     void svgAttributeChanged(const QualifiedName&) override;
 
@@ -113,7 +105,7 @@
 private:
     AttributeOwnerProxy m_attributeOwnerProxy { *this };
     PropertyRegistry m_propertyRegistry { *this };
-    SVGAnimatedEnumerationAttribute<ComponentTransferType> m_type { FECOMPONENTTRANSFER_TYPE_IDENTITY };
+    Ref<SVGAnimatedEnumeration> m_type { SVGAnimatedEnumeration::create(this, FECOMPONENTTRANSFER_TYPE_IDENTITY) };
     Ref<SVGAnimatedNumberList> m_tableValues { SVGAnimatedNumberList::create(this) };
     Ref<SVGAnimatedNumber> m_slope { SVGAnimatedNumber::create(this, 1) };
     Ref<SVGAnimatedNumber> m_intercept { SVGAnimatedNumber::create(this) };
diff --git a/Source/WebCore/svg/SVGElement.cpp b/Source/WebCore/svg/SVGElement.cpp
index 2c1f2fd..1cebfb3 100644
--- a/Source/WebCore/svg/SVGElement.cpp
+++ b/Source/WebCore/svg/SVGElement.cpp
@@ -740,7 +740,13 @@
 void SVGElement::commitPropertyChange(SVGAnimatedProperty& animatedProperty)
 {
     QualifiedName attributeName = propertyRegistry().animatedPropertyAttributeName(animatedProperty);
-    setSynchronizedLazyAttribute(attributeName, animatedProperty.baseValAsString());
+
+    // A change in a style property, e.g SVGRectElement::x should be serialized to
+    // the attribute immediately. Otherwise it is okay to be lazy in this regard.
+    if (!propertyRegistry().isAnimatedStylePropertyAttribute(attributeName))
+        animatedProperty.setDirty();
+    else
+        setSynchronizedLazyAttribute(attributeName, animatedProperty.baseValAsString());
 
     invalidateSVGAttributes();
     svgAttributeChanged(attributeName);
diff --git a/Source/WebCore/svg/SVGFEBlendElement.cpp b/Source/WebCore/svg/SVGFEBlendElement.cpp
index 4108312..3308dc7 100644
--- a/Source/WebCore/svg/SVGFEBlendElement.cpp
+++ b/Source/WebCore/svg/SVGFEBlendElement.cpp
@@ -37,10 +37,10 @@
     : SVGFilterPrimitiveStandardAttributes(tagName, document)
 {
     ASSERT(hasTagName(SVGNames::feBlendTag));
-    registerAttributes();
     
     static std::once_flag onceFlag;
     std::call_once(onceFlag, [] {
+        PropertyRegistry::registerProperty<SVGNames::modeAttr, BlendMode, &SVGFEBlendElement::m_mode>();
         PropertyRegistry::registerProperty<SVGNames::inAttr, &SVGFEBlendElement::m_in1>();
         PropertyRegistry::registerProperty<SVGNames::in2Attr, &SVGFEBlendElement::m_in2>();
     });
@@ -51,20 +51,12 @@
     return adoptRef(*new SVGFEBlendElement(tagName, document));
 }
     
-void SVGFEBlendElement::registerAttributes()
-{
-    auto& registry = attributeRegistry();
-    if (!registry.isEmpty())
-        return;
-    registry.registerAttribute<SVGNames::modeAttr, BlendMode, &SVGFEBlendElement::m_mode>();
-}
-
 void SVGFEBlendElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     if (name == SVGNames::modeAttr) {
         BlendMode mode = BlendMode::Normal;
         if (parseBlendMode(value, mode))
-            m_mode.setValue(mode);
+            m_mode->setBaseValInternal<BlendMode>(mode);
         return;
     }
 
diff --git a/Source/WebCore/svg/SVGFEBlendElement.h b/Source/WebCore/svg/SVGFEBlendElement.h
index 2bf7f85..92d8f12 100644
--- a/Source/WebCore/svg/SVGFEBlendElement.h
+++ b/Source/WebCore/svg/SVGFEBlendElement.h
@@ -23,7 +23,6 @@
 #pragma once
 
 #include "GraphicsTypes.h"
-#include "SVGAnimatedEnumeration.h"
 #include "SVGFilterPrimitiveStandardAttributes.h"
 
 namespace WebCore {
@@ -32,6 +31,13 @@
 struct SVGPropertyTraits<BlendMode> {
     static unsigned highestEnumValue() { return static_cast<unsigned>(BlendMode::Luminosity); }
 
+    static BlendMode fromString(const String& string)
+    {
+        BlendMode mode = BlendMode::Normal;
+        parseBlendMode(string, mode);
+        return mode;
+    }
+
     static String toString(BlendMode type)
     {
         if (type < BlendMode::PlusDarker)
@@ -48,28 +54,21 @@
 
     String in1() const { return m_in1->currentValue(); }
     String in2() const { return m_in2->currentValue(); }
-    BlendMode mode() const { return m_mode.currentValue(attributeOwnerProxy()); }
+    BlendMode mode() const { return m_mode->currentValue<BlendMode>(); }
 
     SVGAnimatedString& in1Animated() { return m_in1; }
     SVGAnimatedString& in2Animated() { return m_in2; }
-    RefPtr<SVGAnimatedEnumeration> modeAnimated() { return m_mode.animatedProperty(attributeOwnerProxy()); }
+    SVGAnimatedEnumeration& modeAnimated() { return m_mode; }
 
 private:
     SVGFEBlendElement(const QualifiedName&, Document&);
 
     using AttributeOwnerProxy = SVGAttributeOwnerProxyImpl<SVGFEBlendElement, SVGFilterPrimitiveStandardAttributes>;
-    static AttributeOwnerProxy::AttributeRegistry& attributeRegistry() { return AttributeOwnerProxy::attributeRegistry(); }
-    static void registerAttributes();
     const SVGAttributeOwnerProxy& attributeOwnerProxy() const final { return m_attributeOwnerProxy; }
 
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGFEBlendElement, SVGFilterPrimitiveStandardAttributes>;
     const SVGPropertyRegistry& propertyRegistry() const final { return m_propertyRegistry; }
 
-    static bool isKnownAttribute(const QualifiedName& attributeName)
-    {
-        return AttributeOwnerProxy::isKnownAttribute(attributeName) || PropertyRegistry::isKnownAttribute(attributeName);
-    }
-
     void parseAttribute(const QualifiedName&, const AtomicString&) override;
     void svgAttributeChanged(const QualifiedName&) override;
 
@@ -80,7 +79,7 @@
     PropertyRegistry m_propertyRegistry { *this };
     Ref<SVGAnimatedString> m_in1 { SVGAnimatedString::create(this) };
     Ref<SVGAnimatedString> m_in2 { SVGAnimatedString::create(this) };
-    SVGAnimatedEnumerationAttribute<BlendMode> m_mode { BlendMode::Normal };
+    Ref<SVGAnimatedEnumeration> m_mode { SVGAnimatedEnumeration::create(this, BlendMode::Normal) };
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/svg/SVGFEColorMatrixElement.cpp b/Source/WebCore/svg/SVGFEColorMatrixElement.cpp
index 8afcbde..6597672 100644
--- a/Source/WebCore/svg/SVGFEColorMatrixElement.cpp
+++ b/Source/WebCore/svg/SVGFEColorMatrixElement.cpp
@@ -35,11 +35,11 @@
     : SVGFilterPrimitiveStandardAttributes(tagName, document)
 {
     ASSERT(hasTagName(SVGNames::feColorMatrixTag));
-    registerAttributes();
-    
+
     static std::once_flag onceFlag;
     std::call_once(onceFlag, [] {
         PropertyRegistry::registerProperty<SVGNames::inAttr, &SVGFEColorMatrixElement::m_in1>();
+        PropertyRegistry::registerProperty<SVGNames::typeAttr, ColorMatrixType, &SVGFEColorMatrixElement::m_type>();
         PropertyRegistry::registerProperty<SVGNames::valuesAttr, &SVGFEColorMatrixElement::m_values>();
     });
 }
@@ -49,20 +49,12 @@
     return adoptRef(*new SVGFEColorMatrixElement(tagName, document));
 }
 
-void SVGFEColorMatrixElement::registerAttributes()
-{
-    auto& registry = attributeRegistry();
-    if (!registry.isEmpty())
-        return;
-    registry.registerAttribute<SVGNames::typeAttr, ColorMatrixType, &SVGFEColorMatrixElement::m_type>();
-}
-
 void SVGFEColorMatrixElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     if (name == SVGNames::typeAttr) {
         auto propertyValue = SVGPropertyTraits<ColorMatrixType>::fromString(value);
         if (propertyValue > 0)
-            m_type.setValue(propertyValue);
+            m_type->setBaseValInternal<ColorMatrixType>(propertyValue);
         return;
     }
 
diff --git a/Source/WebCore/svg/SVGFEColorMatrixElement.h b/Source/WebCore/svg/SVGFEColorMatrixElement.h
index 4a153c1..46de369 100644
--- a/Source/WebCore/svg/SVGFEColorMatrixElement.h
+++ b/Source/WebCore/svg/SVGFEColorMatrixElement.h
@@ -22,7 +22,6 @@
 #pragma once
 
 #include "FEColorMatrix.h"
-#include "SVGAnimatedEnumeration.h"
 #include "SVGFilterPrimitiveStandardAttributes.h"
 
 namespace WebCore {
@@ -70,29 +69,22 @@
     static Ref<SVGFEColorMatrixElement> create(const QualifiedName&, Document&);
 
     String in1() const { return m_in1->currentValue(); }
-    ColorMatrixType type() const { return m_type.currentValue(attributeOwnerProxy()); }
+    ColorMatrixType type() const { return m_type->currentValue<ColorMatrixType>(); }
     const SVGNumberList& values() const { return m_values->currentValue(); }
 
     SVGAnimatedString& in1Animated() { return m_in1; }
-    RefPtr<SVGAnimatedEnumeration> typeAnimated() { return m_type.animatedProperty(attributeOwnerProxy()); }
+    SVGAnimatedEnumeration& typeAnimated() { return m_type; }
     SVGAnimatedNumberList& valuesAnimated() { return m_values; }
 
 private:
     SVGFEColorMatrixElement(const QualifiedName&, Document&);
 
     using AttributeOwnerProxy = SVGAttributeOwnerProxyImpl<SVGFEColorMatrixElement, SVGFilterPrimitiveStandardAttributes>;
-    static AttributeOwnerProxy::AttributeRegistry& attributeRegistry() { return AttributeOwnerProxy::attributeRegistry(); }
-    static void registerAttributes();
     const SVGAttributeOwnerProxy& attributeOwnerProxy() const final { return m_attributeOwnerProxy; }
 
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGFEColorMatrixElement, SVGFilterPrimitiveStandardAttributes>;
     const SVGPropertyRegistry& propertyRegistry() const final { return m_propertyRegistry; }
 
-    static bool isKnownAttribute(const QualifiedName& attributeName)
-    {
-        return AttributeOwnerProxy::isKnownAttribute(attributeName) || PropertyRegistry::isKnownAttribute(attributeName);
-    }
-
     void parseAttribute(const QualifiedName&, const AtomicString&) override;
     void svgAttributeChanged(const QualifiedName&) override;
 
@@ -102,7 +94,7 @@
     AttributeOwnerProxy m_attributeOwnerProxy { *this };
     PropertyRegistry m_propertyRegistry { *this };
     Ref<SVGAnimatedString> m_in1 { SVGAnimatedString::create(this) };
-    SVGAnimatedEnumerationAttribute<ColorMatrixType> m_type { FECOLORMATRIX_TYPE_MATRIX };
+    Ref<SVGAnimatedEnumeration> m_type { SVGAnimatedEnumeration::create(this, FECOLORMATRIX_TYPE_MATRIX) };
     Ref<SVGAnimatedNumberList> m_values { SVGAnimatedNumberList::create(this) };
 };
 
diff --git a/Source/WebCore/svg/SVGFECompositeElement.cpp b/Source/WebCore/svg/SVGFECompositeElement.cpp
index 4af3900..90880ab 100644
--- a/Source/WebCore/svg/SVGFECompositeElement.cpp
+++ b/Source/WebCore/svg/SVGFECompositeElement.cpp
@@ -35,12 +35,12 @@
     : SVGFilterPrimitiveStandardAttributes(tagName, document)
 {
     ASSERT(hasTagName(SVGNames::feCompositeTag));
-    registerAttributes();
-    
+
     static std::once_flag onceFlag;
     std::call_once(onceFlag, [] {
         PropertyRegistry::registerProperty<SVGNames::inAttr, &SVGFECompositeElement::m_in1>();
         PropertyRegistry::registerProperty<SVGNames::in2Attr, &SVGFECompositeElement::m_in2>();
+        PropertyRegistry::registerProperty<SVGNames::operatorAttr, CompositeOperationType, &SVGFECompositeElement::m_svgOperator>();
         PropertyRegistry::registerProperty<SVGNames::k1Attr, &SVGFECompositeElement::m_k1>();
         PropertyRegistry::registerProperty<SVGNames::k2Attr, &SVGFECompositeElement::m_k2>();
         PropertyRegistry::registerProperty<SVGNames::k3Attr, &SVGFECompositeElement::m_k3>();
@@ -53,20 +53,12 @@
     return adoptRef(*new SVGFECompositeElement(tagName, document));
 }
 
-void SVGFECompositeElement::registerAttributes()
-{
-    auto& registry = attributeRegistry();
-    if (!registry.isEmpty())
-        return;
-    registry.registerAttribute<SVGNames::operatorAttr, CompositeOperationType, &SVGFECompositeElement::m_svgOperator>();
-}
-
 void SVGFECompositeElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     if (name == SVGNames::operatorAttr) {
         CompositeOperationType propertyValue = SVGPropertyTraits<CompositeOperationType>::fromString(value);
         if (propertyValue > 0)
-            m_svgOperator.setValue(propertyValue);
+            m_svgOperator->setBaseValInternal<CompositeOperationType>(propertyValue);
         return;
     }
 
diff --git a/Source/WebCore/svg/SVGFECompositeElement.h b/Source/WebCore/svg/SVGFECompositeElement.h
index cee8103..7355820 100644
--- a/Source/WebCore/svg/SVGFECompositeElement.h
+++ b/Source/WebCore/svg/SVGFECompositeElement.h
@@ -22,7 +22,6 @@
 #pragma once
 
 #include "FEComposite.h"
-#include "SVGAnimatedEnumeration.h"
 #include "SVGFilterPrimitiveStandardAttributes.h"
 
 namespace WebCore {
@@ -86,7 +85,7 @@
 
     String in1() const { return m_in1->currentValue(); }
     String in2() const { return m_in2->currentValue(); }
-    CompositeOperationType svgOperator() const { return m_svgOperator.currentValue(attributeOwnerProxy()); }
+    CompositeOperationType svgOperator() const { return m_svgOperator->currentValue<CompositeOperationType>(); }
     float k1() const { return m_k1->currentValue(); }
     float k2() const { return m_k2->currentValue(); }
     float k3() const { return m_k3->currentValue(); }
@@ -94,7 +93,7 @@
 
     SVGAnimatedString& in1Animated() { return m_in1; }
     SVGAnimatedString& in2Animated() { return m_in2; }
-    RefPtr<SVGAnimatedEnumeration> svgOperatorAnimated() { return m_svgOperator.animatedProperty(attributeOwnerProxy()); }
+    SVGAnimatedEnumeration& svgOperatorAnimated() { return m_svgOperator; }
     SVGAnimatedNumber& k1Animated() { return m_k1; }
     SVGAnimatedNumber& k2Animated() { return m_k2; }
     SVGAnimatedNumber& k3Animated() { return m_k3; }
@@ -104,18 +103,11 @@
     SVGFECompositeElement(const QualifiedName&, Document&);
 
     using AttributeOwnerProxy = SVGAttributeOwnerProxyImpl<SVGFECompositeElement, SVGFilterPrimitiveStandardAttributes>;
-    static AttributeOwnerProxy::AttributeRegistry& attributeRegistry() { return AttributeOwnerProxy::attributeRegistry(); }
-    static void registerAttributes();
     const SVGAttributeOwnerProxy& attributeOwnerProxy() const final { return m_attributeOwnerProxy; }
 
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGFECompositeElement, SVGFilterPrimitiveStandardAttributes>;
     const SVGPropertyRegistry& propertyRegistry() const final { return m_propertyRegistry; }
 
-    static bool isKnownAttribute(const QualifiedName& attributeName)
-    {
-        return AttributeOwnerProxy::isKnownAttribute(attributeName) || PropertyRegistry::isKnownAttribute(attributeName);
-    }
-
     void parseAttribute(const QualifiedName&, const AtomicString&) override;
     void svgAttributeChanged(const QualifiedName&) override;
 
@@ -126,7 +118,7 @@
     PropertyRegistry m_propertyRegistry { *this };
     Ref<SVGAnimatedString> m_in1 { SVGAnimatedString::create(this) };
     Ref<SVGAnimatedString> m_in2 { SVGAnimatedString::create(this) };
-    SVGAnimatedEnumerationAttribute<CompositeOperationType> m_svgOperator { FECOMPOSITE_OPERATOR_OVER };
+    Ref<SVGAnimatedEnumeration> m_svgOperator { SVGAnimatedEnumeration::create(this, FECOMPOSITE_OPERATOR_OVER) };
     Ref<SVGAnimatedNumber> m_k1 { SVGAnimatedNumber::create(this) };
     Ref<SVGAnimatedNumber> m_k2 { SVGAnimatedNumber::create(this) };
     Ref<SVGAnimatedNumber> m_k3 { SVGAnimatedNumber::create(this) };
diff --git a/Source/WebCore/svg/SVGFEConvolveMatrixElement.cpp b/Source/WebCore/svg/SVGFEConvolveMatrixElement.cpp
index 800c740..eb914fa 100644
--- a/Source/WebCore/svg/SVGFEConvolveMatrixElement.cpp
+++ b/Source/WebCore/svg/SVGFEConvolveMatrixElement.cpp
@@ -38,7 +38,6 @@
     : SVGFilterPrimitiveStandardAttributes(tagName, document)
 {
     ASSERT(hasTagName(SVGNames::feConvolveMatrixTag));
-    registerAttributes();
 
     static std::once_flag onceFlag;
     std::call_once(onceFlag, [] {
@@ -49,6 +48,7 @@
         PropertyRegistry::registerProperty<SVGNames::biasAttr, &SVGFEConvolveMatrixElement::m_bias>();
         PropertyRegistry::registerProperty<SVGNames::targetXAttr, &SVGFEConvolveMatrixElement::m_targetX>();
         PropertyRegistry::registerProperty<SVGNames::targetYAttr, &SVGFEConvolveMatrixElement::m_targetY>();
+        PropertyRegistry::registerProperty<SVGNames::edgeModeAttr, EdgeModeType, &SVGFEConvolveMatrixElement::m_edgeMode>();
         PropertyRegistry::registerProperty<SVGNames::kernelUnitLengthAttr, &SVGFEConvolveMatrixElement::m_kernelUnitLengthX, &SVGFEConvolveMatrixElement::m_kernelUnitLengthY>();
         PropertyRegistry::registerProperty<SVGNames::preserveAlphaAttr, &SVGFEConvolveMatrixElement::m_preserveAlpha>();
     });
@@ -59,14 +59,6 @@
     return adoptRef(*new SVGFEConvolveMatrixElement(tagName, document));
 }
 
-void SVGFEConvolveMatrixElement::registerAttributes()
-{
-    auto& registry = attributeRegistry();
-    if (!registry.isEmpty())
-        return;
-    registry.registerAttribute<SVGNames::edgeModeAttr, EdgeModeType, &SVGFEConvolveMatrixElement::m_edgeMode>();
-}
-
 void SVGFEConvolveMatrixElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     if (name == SVGNames::inAttr) {
@@ -87,7 +79,7 @@
     if (name == SVGNames::edgeModeAttr) {
         EdgeModeType propertyValue = SVGPropertyTraits<EdgeModeType>::fromString(value);
         if (propertyValue > 0)
-            m_edgeMode.setValue(propertyValue);
+            m_edgeMode->setBaseValInternal<EdgeModeType>(propertyValue);
         else
             document().accessSVGExtensions().reportWarning("feConvolveMatrix: problem parsing edgeMode=\"" + value + "\". Filtered element will not be displayed.");
         return;
diff --git a/Source/WebCore/svg/SVGFEConvolveMatrixElement.h b/Source/WebCore/svg/SVGFEConvolveMatrixElement.h
index 5cc801f..c8ab5bc 100644
--- a/Source/WebCore/svg/SVGFEConvolveMatrixElement.h
+++ b/Source/WebCore/svg/SVGFEConvolveMatrixElement.h
@@ -75,7 +75,7 @@
     float bias() const { return m_bias->currentValue(); }
     int targetX() const { return m_targetX->currentValue(); }
     int targetY() const { return m_targetY->currentValue(); }
-    EdgeModeType edgeMode() const { return m_edgeMode.currentValue(attributeOwnerProxy()); }
+    EdgeModeType edgeMode() const { return m_edgeMode->currentValue<EdgeModeType>(); }
     float kernelUnitLengthX() const { return m_kernelUnitLengthX->currentValue(); }
     float kernelUnitLengthY() const { return m_kernelUnitLengthY->currentValue(); }
     bool preserveAlpha() const { return m_preserveAlpha->currentValue(); }
@@ -88,7 +88,7 @@
     SVGAnimatedNumber& biasAnimated() { return m_bias; }
     SVGAnimatedInteger& targetXAnimated() { return m_targetX; }
     SVGAnimatedInteger& targetYAnimated() { return m_targetY; }
-    RefPtr<SVGAnimatedEnumeration> edgeModeAnimated() { return m_edgeMode.animatedProperty(attributeOwnerProxy()); }
+    SVGAnimatedEnumeration& edgeModeAnimated() { return m_edgeMode; }
     SVGAnimatedNumber& kernelUnitLengthXAnimated() { return m_kernelUnitLengthX; }
     SVGAnimatedNumber& kernelUnitLengthYAnimated() { return m_kernelUnitLengthY; }
     SVGAnimatedBoolean& preserveAlphaAnimated() { return m_preserveAlpha; }
@@ -97,18 +97,11 @@
     SVGFEConvolveMatrixElement(const QualifiedName&, Document&);
 
     using AttributeOwnerProxy = SVGAttributeOwnerProxyImpl<SVGFEConvolveMatrixElement, SVGFilterPrimitiveStandardAttributes>;
-    static AttributeOwnerProxy::AttributeRegistry& attributeRegistry() { return AttributeOwnerProxy::attributeRegistry(); }
-    static void registerAttributes();
     const SVGAttributeOwnerProxy& attributeOwnerProxy() const final { return m_attributeOwnerProxy; }
 
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGFEConvolveMatrixElement, SVGFilterPrimitiveStandardAttributes>;
     const SVGPropertyRegistry& propertyRegistry() const final { return m_propertyRegistry; }
 
-    static bool isKnownAttribute(const QualifiedName& attributeName)
-    {
-        return AttributeOwnerProxy::isKnownAttribute(attributeName) || PropertyRegistry::isKnownAttribute(attributeName);
-    }
-
     void parseAttribute(const QualifiedName&, const AtomicString&) override;
     void svgAttributeChanged(const QualifiedName&) override;
 
@@ -125,7 +118,7 @@
     Ref<SVGAnimatedNumber> m_bias { SVGAnimatedNumber::create(this) };
     Ref<SVGAnimatedInteger> m_targetX { SVGAnimatedInteger::create(this) };
     Ref<SVGAnimatedInteger> m_targetY { SVGAnimatedInteger::create(this) };
-    SVGAnimatedEnumerationAttribute<EdgeModeType> m_edgeMode { EDGEMODE_DUPLICATE };
+    Ref<SVGAnimatedEnumeration> m_edgeMode { SVGAnimatedEnumeration::create(this, EDGEMODE_DUPLICATE) };
     Ref<SVGAnimatedNumber> m_kernelUnitLengthX { SVGAnimatedNumber::create(this) };
     Ref<SVGAnimatedNumber> m_kernelUnitLengthY { SVGAnimatedNumber::create(this) };
     Ref<SVGAnimatedBoolean> m_preserveAlpha { SVGAnimatedBoolean::create(this) };
diff --git a/Source/WebCore/svg/SVGFEDisplacementMapElement.cpp b/Source/WebCore/svg/SVGFEDisplacementMapElement.cpp
index e7bfc9e..84bea0b 100644
--- a/Source/WebCore/svg/SVGFEDisplacementMapElement.cpp
+++ b/Source/WebCore/svg/SVGFEDisplacementMapElement.cpp
@@ -34,12 +34,13 @@
     : SVGFilterPrimitiveStandardAttributes(tagName, document)
 {
     ASSERT(hasTagName(SVGNames::feDisplacementMapTag));
-    registerAttributes();
-    
+
     static std::once_flag onceFlag;
     std::call_once(onceFlag, [] {
         PropertyRegistry::registerProperty<SVGNames::inAttr, &SVGFEDisplacementMapElement::m_in1>();
         PropertyRegistry::registerProperty<SVGNames::in2Attr, &SVGFEDisplacementMapElement::m_in2>();
+        PropertyRegistry::registerProperty<SVGNames::xChannelSelectorAttr, ChannelSelectorType, &SVGFEDisplacementMapElement::m_xChannelSelector>();
+        PropertyRegistry::registerProperty<SVGNames::yChannelSelectorAttr, ChannelSelectorType, &SVGFEDisplacementMapElement::m_yChannelSelector>();
         PropertyRegistry::registerProperty<SVGNames::scaleAttr, &SVGFEDisplacementMapElement::m_scale>();
     });
 }
@@ -49,28 +50,19 @@
     return adoptRef(*new SVGFEDisplacementMapElement(tagName, document));
 }
 
-void SVGFEDisplacementMapElement::registerAttributes()
-{
-    auto& registry = attributeRegistry();
-    if (!registry.isEmpty())
-        return;
-    registry.registerAttribute<SVGNames::xChannelSelectorAttr, ChannelSelectorType, &SVGFEDisplacementMapElement::m_xChannelSelector>();
-    registry.registerAttribute<SVGNames::yChannelSelectorAttr, ChannelSelectorType, &SVGFEDisplacementMapElement::m_yChannelSelector>();
-}
-
 void SVGFEDisplacementMapElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     if (name == SVGNames::xChannelSelectorAttr) {
         auto propertyValue = SVGPropertyTraits<ChannelSelectorType>::fromString(value);
         if (propertyValue > 0)
-            m_xChannelSelector.setValue(propertyValue);
+            m_xChannelSelector->setBaseValInternal<ChannelSelectorType>(propertyValue);
         return;
     }
 
     if (name == SVGNames::yChannelSelectorAttr) {
         auto propertyValue = SVGPropertyTraits<ChannelSelectorType>::fromString(value);
         if (propertyValue > 0)
-            m_yChannelSelector.setValue(propertyValue);
+            m_yChannelSelector->setBaseValInternal<ChannelSelectorType>(propertyValue);
         return;
     }
 
diff --git a/Source/WebCore/svg/SVGFEDisplacementMapElement.h b/Source/WebCore/svg/SVGFEDisplacementMapElement.h
index 754fab1..e746d23 100644
--- a/Source/WebCore/svg/SVGFEDisplacementMapElement.h
+++ b/Source/WebCore/svg/SVGFEDisplacementMapElement.h
@@ -21,7 +21,6 @@
 #pragma once
 
 #include "FEDisplacementMap.h"
-#include "SVGAnimatedEnumeration.h"
 #include "SVGFilterPrimitiveStandardAttributes.h"
 
 namespace WebCore {
@@ -72,32 +71,25 @@
 
     String in1() const { return m_in1->currentValue(); }
     String in2() const { return m_in2->currentValue(); }
-    ChannelSelectorType xChannelSelector() const { return m_xChannelSelector.currentValue(attributeOwnerProxy()); }
-    ChannelSelectorType yChannelSelector() const { return m_yChannelSelector.currentValue(attributeOwnerProxy()); }
+    ChannelSelectorType xChannelSelector() const { return m_xChannelSelector->currentValue<ChannelSelectorType>(); }
+    ChannelSelectorType yChannelSelector() const { return m_yChannelSelector->currentValue<ChannelSelectorType>(); }
     float scale() const { return m_scale->currentValue(); }
 
     SVGAnimatedString& in1Animated() { return m_in1; }
     SVGAnimatedString& in2Animated() { return m_in2; }
-    RefPtr<SVGAnimatedEnumeration> xChannelSelectorAnimated() { return m_xChannelSelector.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedEnumeration> yChannelSelectorAnimated() { return m_yChannelSelector.animatedProperty(attributeOwnerProxy()); }
+    SVGAnimatedEnumeration& xChannelSelectorAnimated() { return m_xChannelSelector; }
+    SVGAnimatedEnumeration& yChannelSelectorAnimated() { return m_yChannelSelector; }
     SVGAnimatedNumber& scaleAnimated() { return m_scale; }
 
 private:
     SVGFEDisplacementMapElement(const QualifiedName& tagName, Document&);
 
     using AttributeOwnerProxy = SVGAttributeOwnerProxyImpl<SVGFEDisplacementMapElement, SVGFilterPrimitiveStandardAttributes>;
-    static AttributeOwnerProxy::AttributeRegistry& attributeRegistry() { return AttributeOwnerProxy::attributeRegistry(); }
-    static void registerAttributes();
     const SVGAttributeOwnerProxy& attributeOwnerProxy() const final { return m_attributeOwnerProxy; }
 
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGFEDisplacementMapElement, SVGFilterPrimitiveStandardAttributes>;
     const SVGPropertyRegistry& propertyRegistry() const final { return m_propertyRegistry; }
 
-    static bool isKnownAttribute(const QualifiedName& attributeName)
-    {
-        return AttributeOwnerProxy::isKnownAttribute(attributeName);
-    }
-
     void parseAttribute(const QualifiedName&, const AtomicString&) override;
     void svgAttributeChanged(const QualifiedName&) override;
 
@@ -108,8 +100,8 @@
     PropertyRegistry m_propertyRegistry { *this };
     Ref<SVGAnimatedString> m_in1 { SVGAnimatedString::create(this) };
     Ref<SVGAnimatedString> m_in2 { SVGAnimatedString::create(this) };
-    SVGAnimatedEnumerationAttribute<ChannelSelectorType> m_xChannelSelector { CHANNEL_A };
-    SVGAnimatedEnumerationAttribute<ChannelSelectorType> m_yChannelSelector { CHANNEL_A };
+    Ref<SVGAnimatedEnumeration> m_xChannelSelector { SVGAnimatedEnumeration::create(this, CHANNEL_A) };
+    Ref<SVGAnimatedEnumeration> m_yChannelSelector { SVGAnimatedEnumeration::create(this, CHANNEL_A) };
     Ref<SVGAnimatedNumber> m_scale { SVGAnimatedNumber::create(this) };
 };
 
diff --git a/Source/WebCore/svg/SVGFEGaussianBlurElement.cpp b/Source/WebCore/svg/SVGFEGaussianBlurElement.cpp
index 6eebaac..95b6683 100644
--- a/Source/WebCore/svg/SVGFEGaussianBlurElement.cpp
+++ b/Source/WebCore/svg/SVGFEGaussianBlurElement.cpp
@@ -36,12 +36,12 @@
     : SVGFilterPrimitiveStandardAttributes(tagName, document)
 {
     ASSERT(hasTagName(SVGNames::feGaussianBlurTag));
-    registerAttributes();
 
     static std::once_flag onceFlag;
     std::call_once(onceFlag, [] {
         PropertyRegistry::registerProperty<SVGNames::inAttr, &SVGFEGaussianBlurElement::m_in1>();
         PropertyRegistry::registerProperty<SVGNames::stdDeviationAttr, &SVGFEGaussianBlurElement::m_stdDeviationX, &SVGFEGaussianBlurElement::m_stdDeviationY>();
+        PropertyRegistry::registerProperty<SVGNames::edgeModeAttr, EdgeModeType, &SVGFEGaussianBlurElement::m_edgeMode>();
     });
 }
 
@@ -57,14 +57,6 @@
     invalidate();
 }
 
-void SVGFEGaussianBlurElement::registerAttributes()
-{
-    auto& registry = attributeRegistry();
-    if (!registry.isEmpty())
-        return;
-    registry.registerAttribute<SVGNames::edgeModeAttr, EdgeModeType, &SVGFEGaussianBlurElement::m_edgeMode>();
-}
-
 void SVGFEGaussianBlurElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     if (name == SVGNames::stdDeviationAttr) {
@@ -84,7 +76,7 @@
     if (name == SVGNames::edgeModeAttr) {
         auto propertyValue = SVGPropertyTraits<EdgeModeType>::fromString(value);
         if (propertyValue > 0)
-            m_edgeMode.setValue(propertyValue);
+            m_edgeMode->setBaseValInternal<EdgeModeType>(propertyValue);
         else
             document().accessSVGExtensions().reportWarning("feGaussianBlur: problem parsing edgeMode=\"" + value + "\". Filtered element will not be displayed.");
         return;
@@ -95,7 +87,7 @@
 
 void SVGFEGaussianBlurElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    if (isKnownAttribute(attrName)) {
+    if (PropertyRegistry::isKnownAttribute(attrName)) {
         InstanceInvalidationGuard guard(*this);
         invalidate();
         return;
diff --git a/Source/WebCore/svg/SVGFEGaussianBlurElement.h b/Source/WebCore/svg/SVGFEGaussianBlurElement.h
index 5d3e6df..4abf6b3 100644
--- a/Source/WebCore/svg/SVGFEGaussianBlurElement.h
+++ b/Source/WebCore/svg/SVGFEGaussianBlurElement.h
@@ -22,7 +22,6 @@
 #pragma once
 
 #include "FEGaussianBlur.h"
-#include "SVGAnimatedEnumeration.h"
 #include "SVGFEConvolveMatrixElement.h"
 #include "SVGFilterPrimitiveStandardAttributes.h"
 
@@ -38,29 +37,22 @@
     String in1() const { return m_in1->currentValue(); }
     float stdDeviationX() const { return m_stdDeviationX->currentValue(); }
     float stdDeviationY() const { return m_stdDeviationY->currentValue(); }
-    EdgeModeType edgeMode() const { return m_edgeMode.currentValue(attributeOwnerProxy()); }
+    EdgeModeType edgeMode() const { return m_edgeMode->currentValue<EdgeModeType>(); }
 
     SVGAnimatedString& in1Animated() { return m_in1; }
     SVGAnimatedNumber& stdDeviationXAnimated() { return m_stdDeviationX; }
     SVGAnimatedNumber& stdDeviationYAnimated() { return m_stdDeviationY; }
-    RefPtr<SVGAnimatedEnumeration> edgeModeAnimated() { return m_edgeMode.animatedProperty(attributeOwnerProxy()); }
+    SVGAnimatedEnumeration& edgeModeAnimated() { return m_edgeMode; }
 
 private:
     SVGFEGaussianBlurElement(const QualifiedName&, Document&);
 
     using AttributeOwnerProxy = SVGAttributeOwnerProxyImpl<SVGFEGaussianBlurElement, SVGFilterPrimitiveStandardAttributes>;
-    static AttributeOwnerProxy::AttributeRegistry& attributeRegistry() { return AttributeOwnerProxy::attributeRegistry(); }
-    static void registerAttributes();
     const SVGAttributeOwnerProxy& attributeOwnerProxy() const final { return m_attributeOwnerProxy; }
 
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGFEGaussianBlurElement, SVGFilterPrimitiveStandardAttributes>;
     const SVGPropertyRegistry& propertyRegistry() const final { return m_propertyRegistry; }
 
-    static bool isKnownAttribute(const QualifiedName& attributeName)
-    {
-        return AttributeOwnerProxy::isKnownAttribute(attributeName) || PropertyRegistry::isKnownAttribute(attributeName);
-    }
-
     void parseAttribute(const QualifiedName&, const AtomicString&) override;
     void svgAttributeChanged(const QualifiedName&) override;
 
@@ -71,7 +63,7 @@
     Ref<SVGAnimatedString> m_in1 { SVGAnimatedString::create(this) };
     Ref<SVGAnimatedNumber> m_stdDeviationX { SVGAnimatedNumber::create(this) };
     Ref<SVGAnimatedNumber> m_stdDeviationY { SVGAnimatedNumber::create(this) };
-    SVGAnimatedEnumerationAttribute<EdgeModeType> m_edgeMode { EDGEMODE_NONE };
+    Ref<SVGAnimatedEnumeration> m_edgeMode { SVGAnimatedEnumeration::create(this, EDGEMODE_NONE) };
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/svg/SVGFEMorphologyElement.cpp b/Source/WebCore/svg/SVGFEMorphologyElement.cpp
index 9376dd8..176305c 100644
--- a/Source/WebCore/svg/SVGFEMorphologyElement.cpp
+++ b/Source/WebCore/svg/SVGFEMorphologyElement.cpp
@@ -35,11 +35,11 @@
     : SVGFilterPrimitiveStandardAttributes(tagName, document)
 {
     ASSERT(hasTagName(SVGNames::feMorphologyTag));
-    registerAttributes();
     
     static std::once_flag onceFlag;
     std::call_once(onceFlag, [] {
         PropertyRegistry::registerProperty<SVGNames::inAttr, &SVGFEMorphologyElement::m_in1>();
+        PropertyRegistry::registerProperty<SVGNames::operatorAttr, MorphologyOperatorType, &SVGFEMorphologyElement::m_svgOperator>();
         PropertyRegistry::registerProperty<SVGNames::radiusAttr, &SVGFEMorphologyElement::m_radiusX, &SVGFEMorphologyElement::m_radiusY>();
     });
 }
@@ -56,20 +56,12 @@
     invalidate();
 }
 
-void SVGFEMorphologyElement::registerAttributes()
-{
-    auto& registry = attributeRegistry();
-    if (!registry.isEmpty())
-        return;
-    registry.registerAttribute<SVGNames::operatorAttr, MorphologyOperatorType, &SVGFEMorphologyElement::m_svgOperator>();
-}
-
 void SVGFEMorphologyElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     if (name == SVGNames::operatorAttr) {
         MorphologyOperatorType propertyValue = SVGPropertyTraits<MorphologyOperatorType>::fromString(value);
         if (propertyValue > 0)
-            m_svgOperator.setValue(propertyValue);
+            m_svgOperator->setBaseValInternal<MorphologyOperatorType>(propertyValue);
         return;
     }
 
diff --git a/Source/WebCore/svg/SVGFEMorphologyElement.h b/Source/WebCore/svg/SVGFEMorphologyElement.h
index 61f44c5..82b7d56 100644
--- a/Source/WebCore/svg/SVGFEMorphologyElement.h
+++ b/Source/WebCore/svg/SVGFEMorphologyElement.h
@@ -21,7 +21,6 @@
 #pragma once
 
 #include "FEMorphology.h"
-#include "SVGAnimatedEnumeration.h"
 #include "SVGFilterPrimitiveStandardAttributes.h"
 
 namespace WebCore {
@@ -63,12 +62,12 @@
     void setRadius(float radiusX, float radiusY);
 
     String in1() const { return m_in1->currentValue(); }
-    MorphologyOperatorType svgOperator() const { return m_svgOperator.currentValue(attributeOwnerProxy()); }
+    MorphologyOperatorType svgOperator() const { return m_svgOperator->currentValue<MorphologyOperatorType>(); }
     float radiusX() const { return m_radiusX->currentValue(); }
     float radiusY() const { return m_radiusY->currentValue(); }
 
     SVGAnimatedString& in1Animated() { return m_in1; }
-    RefPtr<SVGAnimatedEnumeration> svgOperatorAnimated() { return m_svgOperator.animatedProperty(attributeOwnerProxy()); }
+    SVGAnimatedEnumeration& svgOperatorAnimated() { return m_svgOperator; }
     SVGAnimatedNumber& radiusXAnimated() { return m_radiusX; }
     SVGAnimatedNumber& radiusYAnimated() { return m_radiusY; }
 
@@ -97,7 +96,7 @@
     AttributeOwnerProxy m_attributeOwnerProxy { *this };
     PropertyRegistry m_propertyRegistry { *this };
     Ref<SVGAnimatedString> m_in1 { SVGAnimatedString::create(this) };
-    SVGAnimatedEnumerationAttribute<MorphologyOperatorType> m_svgOperator { FEMORPHOLOGY_OPERATOR_ERODE };
+    Ref<SVGAnimatedEnumeration> m_svgOperator { SVGAnimatedEnumeration::create(this, FEMORPHOLOGY_OPERATOR_ERODE) };
     Ref<SVGAnimatedNumber> m_radiusX { SVGAnimatedNumber::create(this) };
     Ref<SVGAnimatedNumber> m_radiusY { SVGAnimatedNumber::create(this) };
 };
diff --git a/Source/WebCore/svg/SVGFETurbulenceElement.cpp b/Source/WebCore/svg/SVGFETurbulenceElement.cpp
index 0e2c48e..3e35d22 100644
--- a/Source/WebCore/svg/SVGFETurbulenceElement.cpp
+++ b/Source/WebCore/svg/SVGFETurbulenceElement.cpp
@@ -34,13 +34,14 @@
     : SVGFilterPrimitiveStandardAttributes(tagName, document)
 {
     ASSERT(hasTagName(SVGNames::feTurbulenceTag));
-    registerAttributes();
-    
+
     static std::once_flag onceFlag;
     std::call_once(onceFlag, [] {
         PropertyRegistry::registerProperty<SVGNames::baseFrequencyAttr, &SVGFETurbulenceElement::m_baseFrequencyX, &SVGFETurbulenceElement::m_baseFrequencyY>();
         PropertyRegistry::registerProperty<SVGNames::numOctavesAttr, &SVGFETurbulenceElement::m_numOctaves>();
         PropertyRegistry::registerProperty<SVGNames::seedAttr, &SVGFETurbulenceElement::m_seed>();
+        PropertyRegistry::registerProperty<SVGNames::stitchTilesAttr, SVGStitchOptions, &SVGFETurbulenceElement::m_stitchTiles>();
+        PropertyRegistry::registerProperty<SVGNames::typeAttr, TurbulenceType, &SVGFETurbulenceElement::m_type>();
     });
 }
 
@@ -49,28 +50,19 @@
     return adoptRef(*new SVGFETurbulenceElement(tagName, document));
 }
 
-void SVGFETurbulenceElement::registerAttributes()
-{
-    auto& registry = attributeRegistry();
-    if (!registry.isEmpty())
-        return;
-    registry.registerAttribute<SVGNames::stitchTilesAttr, SVGStitchOptions, &SVGFETurbulenceElement::m_stitchTiles>();
-    registry.registerAttribute<SVGNames::typeAttr, TurbulenceType, &SVGFETurbulenceElement::m_type>();
-}
-
 void SVGFETurbulenceElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     if (name == SVGNames::typeAttr) {
         TurbulenceType propertyValue = SVGPropertyTraits<TurbulenceType>::fromString(value);
         if (propertyValue != TurbulenceType::Unknown)
-            m_type.setValue(propertyValue);
+            m_type->setBaseValInternal<TurbulenceType>(propertyValue);
         return;
     }
 
     if (name == SVGNames::stitchTilesAttr) {
         SVGStitchOptions propertyValue = SVGPropertyTraits<SVGStitchOptions>::fromString(value);
         if (propertyValue > 0)
-            m_stitchTiles.setValue(propertyValue);
+            m_stitchTiles->setBaseValInternal<SVGStitchOptions>(propertyValue);
         return;
     }
 
@@ -116,7 +108,7 @@
 
 void SVGFETurbulenceElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    if (isKnownAttribute(attrName)) {
+    if (PropertyRegistry::isKnownAttribute(attrName)) {
         InstanceInvalidationGuard guard(*this);
         primitiveAttributeChanged(attrName);
         return;
diff --git a/Source/WebCore/svg/SVGFETurbulenceElement.h b/Source/WebCore/svg/SVGFETurbulenceElement.h
index 9796a53..79c3328 100644
--- a/Source/WebCore/svg/SVGFETurbulenceElement.h
+++ b/Source/WebCore/svg/SVGFETurbulenceElement.h
@@ -22,7 +22,6 @@
 #pragma once
 
 #include "FETurbulence.h"
-#include "SVGAnimatedEnumeration.h"
 #include "SVGFilterPrimitiveStandardAttributes.h"
 
 namespace WebCore {
@@ -100,32 +99,25 @@
     float baseFrequencyY() const { return m_baseFrequencyY->currentValue(); }
     int numOctaves() const { return m_numOctaves->currentValue(); }
     float seed() const { return m_seed->currentValue(); }
-    SVGStitchOptions stitchTiles() const { return m_stitchTiles.currentValue(attributeOwnerProxy()); }
-    TurbulenceType type() const { return m_type.currentValue(attributeOwnerProxy()); }
+    SVGStitchOptions stitchTiles() const { return m_stitchTiles->currentValue<SVGStitchOptions>(); }
+    TurbulenceType type() const { return m_type->currentValue<TurbulenceType>(); }
 
     SVGAnimatedNumber& baseFrequencyXAnimated() { return m_baseFrequencyX; }
     SVGAnimatedNumber& baseFrequencyYAnimated() { return m_baseFrequencyY; }
     SVGAnimatedInteger& numOctavesAnimated() { return m_numOctaves; }
     SVGAnimatedNumber& seedAnimated() { return m_seed; }
-    RefPtr<SVGAnimatedEnumeration> stitchTilesAnimated() { return m_stitchTiles.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedEnumeration> typeAnimated() { return m_type.animatedProperty(attributeOwnerProxy()); }
+    SVGAnimatedEnumeration& stitchTilesAnimated() { return m_stitchTiles; }
+    SVGAnimatedEnumeration& typeAnimated() { return m_type; }
 
 private:
     SVGFETurbulenceElement(const QualifiedName&, Document&);
 
     using AttributeOwnerProxy = SVGAttributeOwnerProxyImpl<SVGFETurbulenceElement, SVGFilterPrimitiveStandardAttributes>;
-    static AttributeOwnerProxy::AttributeRegistry& attributeRegistry() { return AttributeOwnerProxy::attributeRegistry(); }
-    static void registerAttributes();
     const SVGAttributeOwnerProxy& attributeOwnerProxy() const final { return m_attributeOwnerProxy; }
 
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGFETurbulenceElement, SVGFilterPrimitiveStandardAttributes>;
     const SVGPropertyRegistry& propertyRegistry() const final { return m_propertyRegistry; }
 
-    static bool isKnownAttribute(const QualifiedName& attributeName)
-    {
-        return AttributeOwnerProxy::isKnownAttribute(attributeName) || PropertyRegistry::isKnownAttribute(attributeName);
-    }
-
     void parseAttribute(const QualifiedName&, const AtomicString&) override;
     void svgAttributeChanged(const QualifiedName&) override;
 
@@ -138,8 +130,8 @@
     Ref<SVGAnimatedNumber> m_baseFrequencyY { SVGAnimatedNumber::create(this) };
     Ref<SVGAnimatedInteger> m_numOctaves { SVGAnimatedInteger::create(this, 1) };
     Ref<SVGAnimatedNumber> m_seed { SVGAnimatedNumber::create(this) };
-    SVGAnimatedEnumerationAttribute<SVGStitchOptions> m_stitchTiles { SVG_STITCHTYPE_NOSTITCH };
-    SVGAnimatedEnumerationAttribute<TurbulenceType> m_type { TurbulenceType::Turbulence };
+    Ref<SVGAnimatedEnumeration> m_stitchTiles { SVGAnimatedEnumeration::create(this, SVG_STITCHTYPE_NOSTITCH) };
+    Ref<SVGAnimatedEnumeration> m_type { SVGAnimatedEnumeration::create(this, TurbulenceType::Turbulence) };
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/svg/SVGFilterElement.cpp b/Source/WebCore/svg/SVGFilterElement.cpp
index cdeaa38..b994301 100644
--- a/Source/WebCore/svg/SVGFilterElement.cpp
+++ b/Source/WebCore/svg/SVGFilterElement.cpp
@@ -5,7 +5,7 @@
  * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
  * Copyright (C) 2014 Adobe Systems Incorporated. All rights reserved.
- * 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
@@ -47,6 +47,12 @@
     // Spec: If the width/height attribute is not specified, the effect is as if a value of "120%" were specified.
     ASSERT(hasTagName(SVGNames::filterTag));
     registerAttributes();
+
+    static std::once_flag onceFlag;
+    std::call_once(onceFlag, [] {
+        PropertyRegistry::registerProperty<SVGNames::filterUnitsAttr, SVGUnitTypes::SVGUnitType, &SVGFilterElement::m_filterUnits>();
+        PropertyRegistry::registerProperty<SVGNames::primitiveUnitsAttr, SVGUnitTypes::SVGUnitType, &SVGFilterElement::m_primitiveUnits>();
+    });
 }
 
 Ref<SVGFilterElement> SVGFilterElement::create(const QualifiedName& tagName, Document& document)
@@ -59,8 +65,6 @@
     auto& registry = attributeRegistry();
     if (!registry.isEmpty())
         return;
-    registry.registerAttribute<SVGNames::filterUnitsAttr, SVGUnitTypes::SVGUnitType, &SVGFilterElement::m_filterUnits>();
-    registry.registerAttribute<SVGNames::primitiveUnitsAttr, SVGUnitTypes::SVGUnitType, &SVGFilterElement::m_primitiveUnits>();
     registry.registerAttribute<SVGNames::xAttr, &SVGFilterElement::m_x>();
     registry.registerAttribute<SVGNames::yAttr, &SVGFilterElement::m_y>();
     registry.registerAttribute<SVGNames::widthAttr, &SVGFilterElement::m_width>();
@@ -74,11 +78,11 @@
     if (name == SVGNames::filterUnitsAttr) {
         SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
         if (propertyValue > 0)
-            m_filterUnits.setValue(propertyValue);
+            m_filterUnits->setBaseValInternal<SVGUnitTypes::SVGUnitType>(propertyValue);
     } else if (name == SVGNames::primitiveUnitsAttr) {
         SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
         if (propertyValue > 0)
-            m_primitiveUnits.setValue(propertyValue);
+            m_primitiveUnits->setBaseValInternal<SVGUnitTypes::SVGUnitType>(propertyValue);
     } else if (name == SVGNames::xAttr)
         m_x.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError));
     else if (name == SVGNames::yAttr)
diff --git a/Source/WebCore/svg/SVGFilterElement.h b/Source/WebCore/svg/SVGFilterElement.h
index 8b49899..9f8fb30 100644
--- a/Source/WebCore/svg/SVGFilterElement.h
+++ b/Source/WebCore/svg/SVGFilterElement.h
@@ -23,7 +23,6 @@
 
 #pragma once
 
-#include "SVGAnimatedEnumeration.h"
 #include "SVGAnimatedLength.h"
 #include "SVGElement.h"
 #include "SVGExternalResourcesRequired.h"
@@ -37,15 +36,15 @@
 public:
     static Ref<SVGFilterElement> create(const QualifiedName&, Document&);
 
-    SVGUnitTypes::SVGUnitType filterUnits() const { return m_filterUnits.currentValue(attributeOwnerProxy()); }
-    SVGUnitTypes::SVGUnitType primitiveUnits() const { return m_primitiveUnits.currentValue(attributeOwnerProxy()); }
+    SVGUnitTypes::SVGUnitType filterUnits() const { return m_filterUnits->currentValue<SVGUnitTypes::SVGUnitType>(); }
+    SVGUnitTypes::SVGUnitType primitiveUnits() const { return m_primitiveUnits->currentValue<SVGUnitTypes::SVGUnitType>(); }
     const SVGLengthValue& x() const { return m_x.currentValue(attributeOwnerProxy()); }
     const SVGLengthValue& y() const { return m_y.currentValue(attributeOwnerProxy()); }
     const SVGLengthValue& width() const { return m_width.currentValue(attributeOwnerProxy()); }
     const SVGLengthValue& height() const { return m_height.currentValue(attributeOwnerProxy()); }
 
-    RefPtr<SVGAnimatedEnumeration> filterUnitsAnimated() { return m_filterUnits.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedEnumeration> primitiveUnitsAnimated() { return m_primitiveUnits.animatedProperty(attributeOwnerProxy()); }
+    SVGAnimatedEnumeration& filterUnitsAnimated() { return m_filterUnits; }
+    SVGAnimatedEnumeration& primitiveUnitsAnimated() { return m_primitiveUnits; }
     RefPtr<SVGAnimatedLength> xAnimated() { return m_x.animatedProperty(attributeOwnerProxy()); }
     RefPtr<SVGAnimatedLength> yAnimated() { return m_y.animatedProperty(attributeOwnerProxy()); }
     RefPtr<SVGAnimatedLength> widthAnimated() { return m_width.animatedProperty(attributeOwnerProxy()); }
@@ -82,8 +81,8 @@
 
     AttributeOwnerProxy m_attributeOwnerProxy { *this };
     PropertyRegistry m_propertyRegistry { *this };
-    SVGAnimatedEnumerationAttribute<SVGUnitTypes::SVGUnitType> m_filterUnits { SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX };
-    SVGAnimatedEnumerationAttribute<SVGUnitTypes::SVGUnitType> m_primitiveUnits { SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE };
+    Ref<SVGAnimatedEnumeration> m_filterUnits { SVGAnimatedEnumeration::create(this, SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) };
+    Ref<SVGAnimatedEnumeration> m_primitiveUnits { SVGAnimatedEnumeration::create(this, SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) };
     SVGAnimatedLengthAttribute m_x { LengthModeWidth, "-10%" };
     SVGAnimatedLengthAttribute m_y { LengthModeHeight, "-10%" };
     SVGAnimatedLengthAttribute m_width { LengthModeWidth, "120%" };
diff --git a/Source/WebCore/svg/SVGGradientElement.cpp b/Source/WebCore/svg/SVGGradientElement.cpp
index 8c8c2af..0b40d42 100644
--- a/Source/WebCore/svg/SVGGradientElement.cpp
+++ b/Source/WebCore/svg/SVGGradientElement.cpp
@@ -45,6 +45,12 @@
     , SVGURIReference(this)
 {
     registerAttributes();
+
+    static std::once_flag onceFlag;
+    std::call_once(onceFlag, [] {
+        PropertyRegistry::registerProperty<SVGNames::spreadMethodAttr, SVGSpreadMethodType, &SVGGradientElement::m_spreadMethod>();
+        PropertyRegistry::registerProperty<SVGNames::gradientUnitsAttr, SVGUnitTypes::SVGUnitType, &SVGGradientElement::m_gradientUnits>();
+    });
 }
 
 void SVGGradientElement::registerAttributes()
@@ -52,8 +58,6 @@
     auto& registry = attributeRegistry();
     if (!registry.isEmpty())
         return;
-    registry.registerAttribute<SVGNames::spreadMethodAttr, SVGSpreadMethodType, &SVGGradientElement::m_spreadMethod>();
-    registry.registerAttribute<SVGNames::gradientUnitsAttr, SVGUnitTypes::SVGUnitType, &SVGGradientElement::m_gradientUnits>();
     registry.registerAttribute<SVGNames::gradientTransformAttr, &SVGGradientElement::m_gradientTransform>();
 }
 
@@ -62,7 +66,7 @@
     if (name == SVGNames::gradientUnitsAttr) {
         auto propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
         if (propertyValue > 0)
-            m_gradientUnits.setValue(propertyValue);
+            m_gradientUnits->setBaseValInternal<SVGUnitTypes::SVGUnitType>(propertyValue);
         return;
     }
 
@@ -77,7 +81,7 @@
     if (name == SVGNames::spreadMethodAttr) {
         auto propertyValue = SVGPropertyTraits<SVGSpreadMethodType>::fromString(value);
         if (propertyValue > 0)
-            m_spreadMethod.setValue(propertyValue);
+            m_spreadMethod->setBaseValInternal<SVGSpreadMethodType>(propertyValue);
         return;
     }
 
diff --git a/Source/WebCore/svg/SVGGradientElement.h b/Source/WebCore/svg/SVGGradientElement.h
index 377c45e..8d857d3 100644
--- a/Source/WebCore/svg/SVGGradientElement.h
+++ b/Source/WebCore/svg/SVGGradientElement.h
@@ -22,7 +22,6 @@
 #pragma once
 
 #include "Gradient.h"
-#include "SVGAnimatedEnumeration.h"
 #include "SVGAnimatedTransformList.h"
 #include "SVGElement.h"
 #include "SVGExternalResourcesRequired.h"
@@ -89,12 +88,12 @@
 
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGGradientElement, SVGElement, SVGExternalResourcesRequired, SVGURIReference>;
 
-    SVGSpreadMethodType spreadMethod() const { return m_spreadMethod.currentValue(attributeOwnerProxy()); }
-    SVGUnitTypes::SVGUnitType gradientUnits() const { return m_gradientUnits.currentValue(attributeOwnerProxy()); }
+    SVGSpreadMethodType spreadMethod() const { return m_spreadMethod->currentValue<SVGSpreadMethodType>(); }
+    SVGUnitTypes::SVGUnitType gradientUnits() const { return m_gradientUnits->currentValue<SVGUnitTypes::SVGUnitType>(); }
     const SVGTransformListValues& gradientTransform() const { return m_gradientTransform.currentValue(attributeOwnerProxy()); }
 
-    RefPtr<SVGAnimatedEnumeration> spreadMethodAnimated() { return m_spreadMethod.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedEnumeration> gradientUnitsAnimated() { return m_gradientUnits.animatedProperty(attributeOwnerProxy()); }
+    SVGAnimatedEnumeration& spreadMethodAnimated() { return m_spreadMethod; }
+    SVGAnimatedEnumeration& gradientUnitsAnimated() { return m_gradientUnits; }
     RefPtr<SVGAnimatedTransformList> gradientTransformAnimated() { return m_gradientTransform.animatedProperty(attributeOwnerProxy()); }
 
 protected:
@@ -119,8 +118,8 @@
 
     AttributeOwnerProxy m_attributeOwnerProxy { *this };
     PropertyRegistry m_propertyRegistry { *this };
-    SVGAnimatedEnumerationAttribute<SVGSpreadMethodType> m_spreadMethod { SVGSpreadMethodPad };
-    SVGAnimatedEnumerationAttribute<SVGUnitTypes::SVGUnitType> m_gradientUnits { SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX };
+    Ref<SVGAnimatedEnumeration> m_spreadMethod { SVGAnimatedEnumeration::create(this, SVGSpreadMethodPad) };
+    Ref<SVGAnimatedEnumeration> m_gradientUnits { SVGAnimatedEnumeration::create(this, SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) };
     SVGAnimatedTransformListAttribute m_gradientTransform;
 };
 
diff --git a/Source/WebCore/svg/SVGMarkerElement.cpp b/Source/WebCore/svg/SVGMarkerElement.cpp
index 6ab2b7f..a1fe7b5 100644
--- a/Source/WebCore/svg/SVGMarkerElement.cpp
+++ b/Source/WebCore/svg/SVGMarkerElement.cpp
@@ -2,7 +2,7 @@
  * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
  * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
  * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
- * 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
@@ -41,6 +41,12 @@
     // Spec: If the markerWidth/markerHeight attribute is not specified, the effect is as if a value of "3" were specified.
     ASSERT(hasTagName(SVGNames::markerTag));
     registerAttributes();
+
+    static std::once_flag onceFlag;
+    std::call_once(onceFlag, [] {
+        PropertyRegistry::registerProperty<SVGNames::markerUnitsAttr, SVGMarkerUnitsType, &SVGMarkerElement::m_markerUnits>();
+        PropertyRegistry::registerProperty<SVGNames::orientAttr, &SVGMarkerElement::m_orientAngle, &SVGMarkerElement::m_orientType>();
+    });
 }
 
 Ref<SVGMarkerElement> SVGMarkerElement::create(const QualifiedName& tagName, Document& document)
@@ -48,18 +54,6 @@
     return adoptRef(*new SVGMarkerElement(tagName, document));
 }
 
-const AtomicString& SVGMarkerElement::orientTypeIdentifier()
-{
-    static NeverDestroyed<AtomicString> s_identifier("SVGOrientType", AtomicString::ConstructFromLiteral);
-    return s_identifier;
-}
-
-const AtomicString& SVGMarkerElement::orientAngleIdentifier()
-{
-    static NeverDestroyed<AtomicString> s_identifier("SVGOrientAngle", AtomicString::ConstructFromLiteral);
-    return s_identifier;
-}
-
 AffineTransform SVGMarkerElement::viewBoxToViewTransform(float viewWidth, float viewHeight) const
 {
     return SVGFitToViewBox::viewBoxToViewTransform(viewBox(), preserveAspectRatio(), viewWidth, viewHeight);
@@ -74,10 +68,6 @@
     registry.registerAttribute<SVGNames::refYAttr, &SVGMarkerElement::m_refY>();
     registry.registerAttribute<SVGNames::markerWidthAttr, &SVGMarkerElement::m_markerWidth>();
     registry.registerAttribute<SVGNames::markerHeightAttr, &SVGMarkerElement::m_markerHeight>();
-    registry.registerAttribute<SVGNames::markerUnitsAttr, SVGMarkerUnitsType, &SVGMarkerElement::m_markerUnits>();
-    registry.registerAttribute(SVGAnimatedCustomAngleAttributeAccessor::singleton<SVGNames::orientAttr,
-        &SVGMarkerElement::orientAngleIdentifier, &SVGMarkerElement::m_orientAngle,
-        &SVGMarkerElement::orientTypeIdentifier, &SVGMarkerElement::m_orientType>());
 }
 
 void SVGMarkerElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
@@ -85,17 +75,14 @@
     if (name == SVGNames::markerUnitsAttr) {
         auto propertyValue = SVGPropertyTraits<SVGMarkerUnitsType>::fromString(value);
         if (propertyValue > 0)
-            m_markerUnits.setValue(propertyValue);
+            m_markerUnits->setBaseValInternal<SVGMarkerUnitsType>(propertyValue);
         return;
     }
 
     if (name == SVGNames::orientAttr) {
-        SVGAngleValue angle;
-        auto orientType = SVGPropertyTraits<SVGMarkerOrientType>::fromString(value, angle);
-        if (orientType > 0)
-            m_orientType.setValue(orientType);
-        if (orientType == SVGMarkerOrientAngle)
-            m_orientAngle.setValue(angle);
+        auto pair = SVGPropertyTraits<std::pair<SVGAngleValue, SVGMarkerOrientType>>::fromString(value);
+        m_orientAngle->setBaseValInternal(pair.first);
+        m_orientType->setBaseValInternal(pair.second);
         return;
     }
 
@@ -151,14 +138,9 @@
 
 void SVGMarkerElement::setOrient(SVGMarkerOrientType orientType, const SVGAngleValue& angle)
 {
-    m_orientType.setValue(orientType);
-    m_orientAngle.setValue(angle);
-
-    // Mark orientAttr dirty - the next XML DOM access of that attribute kicks in synchronization.
-    m_orientAngle.setShouldSynchronize(true);
-    m_orientType.setShouldSynchronize(true);
-    invalidateSVGAttributes();
-    svgAttributeChanged(SVGNames::orientAttr);
+    m_orientType->setBaseValInternal(orientType);
+    m_orientAngle->setBaseValInternal(angle);
+    m_orientAngle->baseVal()->commitChange();
 }
 
 void SVGMarkerElement::setOrientToAuto()
@@ -168,7 +150,7 @@
 
 void SVGMarkerElement::setOrientToAngle(SVGAngle& angle)
 {
-    setOrient(SVGMarkerOrientAngle, angle.propertyReference());
+    setOrient(SVGMarkerOrientAngle, angle.value());
 }
 
 RenderPtr<RenderElement> SVGMarkerElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&)
diff --git a/Source/WebCore/svg/SVGMarkerElement.h b/Source/WebCore/svg/SVGMarkerElement.h
index 1076657..7cd511b 100644
--- a/Source/WebCore/svg/SVGMarkerElement.h
+++ b/Source/WebCore/svg/SVGMarkerElement.h
@@ -21,8 +21,6 @@
 
 #pragma once
 
-#include "SVGAnimatedAngle.h"
-#include "SVGAnimatedEnumeration.h"
 #include "SVGAnimatedLength.h"
 #include "SVGElement.h"
 #include "SVGExternalResourcesRequired.h"
@@ -59,17 +57,17 @@
     const SVGLengthValue& refY() const { return m_refY.currentValue(attributeOwnerProxy()); }
     const SVGLengthValue& markerWidth() const { return m_markerWidth.currentValue(attributeOwnerProxy()); }
     const SVGLengthValue& markerHeight() const { return m_markerHeight.currentValue(attributeOwnerProxy()); }
-    SVGMarkerUnitsType markerUnits() const { return m_markerUnits.currentValue(attributeOwnerProxy()); }
-    const SVGAngleValue& orientAngle() const { return m_orientAngle.currentValue(attributeOwnerProxy()); }
-    SVGMarkerOrientType orientType() const { return m_orientType.currentValue(attributeOwnerProxy()); }
+    SVGMarkerUnitsType markerUnits() const { return m_markerUnits->currentValue<SVGMarkerUnitsType>(); }
+    const SVGAngleValue& orientAngle() const { return m_orientAngle->currentValue(); }
+    SVGMarkerOrientType orientType() const { return m_orientType->currentValue<SVGMarkerOrientType>(); }
 
     RefPtr<SVGAnimatedLength> refXAnimated() { return m_refX.animatedProperty(attributeOwnerProxy()); }
     RefPtr<SVGAnimatedLength> refYAnimated() { return m_refY.animatedProperty(attributeOwnerProxy()); }
     RefPtr<SVGAnimatedLength> markerWidthAnimated() { return m_markerWidth.animatedProperty(attributeOwnerProxy()); }
     RefPtr<SVGAnimatedLength> markerHeightAnimated() { return m_markerHeight.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedEnumeration> markerUnitsAnimated() { return m_markerUnits.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedAngle> orientAngleAnimated() { return m_orientAngle.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedEnumeration> orientTypeAnimated() { return m_orientType.animatedProperty(attributeOwnerProxy()); }
+    SVGAnimatedEnumeration& markerUnitsAnimated() { return m_markerUnits; }
+    SVGAnimatedAngle& orientAngleAnimated() { return m_orientAngle; }
+    Ref<SVGAnimatedEnumeration> orientTypeAnimated() { return m_orientType.copyRef(); }
 
 private:
     SVGMarkerElement(const QualifiedName&, Document&);
@@ -101,43 +99,16 @@
 
     void setOrient(SVGMarkerOrientType, const SVGAngleValue&);
 
-    static const AtomicString& orientTypeIdentifier();
-    static const AtomicString& orientAngleIdentifier();
-
     AttributeOwnerProxy m_attributeOwnerProxy { *this };
 
-    class SVGAnimatedCustomOrientTypeAttribute : public SVGAnimatedEnumerationAttribute<SVGMarkerOrientType> {
-    public:
-        using Base = SVGAnimatedEnumerationAttribute<SVGMarkerOrientType>;
-
-        SVGAnimatedCustomOrientTypeAttribute(SVGMarkerOrientType baseValue)
-            : Base(baseValue)
-        {
-        }
-        void synchronize(Element& element, const QualifiedName& attributeName)
-        {
-            static const NeverDestroyed<String> autoString = MAKE_STATIC_STRING_IMPL("auto");
-            static const NeverDestroyed<String> autoStartReverseString = MAKE_STATIC_STRING_IMPL("auto-start-reverse");
-
-            if (!shouldSynchronize())
-                return;
-            if (value() == SVGMarkerOrientAuto)
-                element.setSynchronizedLazyAttribute(attributeName, autoString.get());
-            else if (value() == SVGMarkerOrientAutoStartReverse)
-                element.setSynchronizedLazyAttribute(attributeName, autoStartReverseString.get());
-        }
-    };
-
-    using SVGAnimatedCustomAngleAttributeAccessor = SVGAnimatedPairAttributeAccessor<SVGMarkerElement, SVGAnimatedAngleAttribute, AnimatedAngle, SVGAnimatedCustomOrientTypeAttribute, AnimatedEnumeration>;
-
     PropertyRegistry m_propertyRegistry { *this };
     SVGAnimatedLengthAttribute m_refX { LengthModeWidth };
     SVGAnimatedLengthAttribute m_refY { LengthModeHeight };
     SVGAnimatedLengthAttribute m_markerWidth { LengthModeWidth, "3" };
     SVGAnimatedLengthAttribute m_markerHeight { LengthModeHeight, "3" };
-    SVGAnimatedEnumerationAttribute<SVGMarkerUnitsType> m_markerUnits { SVGMarkerUnitsStrokeWidth };
-    SVGAnimatedAngleAttribute m_orientAngle;
-    SVGAnimatedCustomOrientTypeAttribute m_orientType { SVGMarkerOrientAngle };
+    Ref<SVGAnimatedEnumeration> m_markerUnits { SVGAnimatedEnumeration::create(this, SVGMarkerUnitsStrokeWidth) };
+    Ref<SVGAnimatedAngle> m_orientAngle { SVGAnimatedAngle::create(this) };
+    Ref<SVGAnimatedOrientType> m_orientType { SVGAnimatedOrientType::create(this, SVGMarkerOrientAngle) };
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/svg/SVGMarkerTypes.h b/Source/WebCore/svg/SVGMarkerTypes.h
index e510895..b811d2e 100644
--- a/Source/WebCore/svg/SVGMarkerTypes.h
+++ b/Source/WebCore/svg/SVGMarkerTypes.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 Apple Inc.  All rights reserved.
+ * Copyright (C) 2018-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
@@ -75,17 +75,32 @@
 
 template<>
 struct SVGPropertyTraits<SVGMarkerOrientType> {
-    static unsigned highestEnumValue() { return SVGMarkerOrientAutoStartReverse; }
-    static SVGMarkerOrientType fromString(const String& value, SVGAngleValue& angle)
+    static const String autoString()
     {
-        if (value == "auto")
+        static const NeverDestroyed<String> autoString = MAKE_STATIC_STRING_IMPL("auto");
+        return autoString;
+    }
+    static const String autoStartReverseString()
+    {
+        static const NeverDestroyed<String> autoStartReverseString = MAKE_STATIC_STRING_IMPL("auto-start-reverse");
+        return autoStartReverseString;
+    }
+    static unsigned highestEnumValue() { return SVGMarkerOrientAutoStartReverse; }
+    static SVGMarkerOrientType fromString(const String& string)
+    {
+        if (string == autoString())
             return SVGMarkerOrientAuto;
-        if (value == "auto-start-reverse")
+        if (string == autoStartReverseString())
             return SVGMarkerOrientAutoStartReverse;
-        auto setValueResult = angle.setValueAsString(value);
-        if (setValueResult.hasException())
-            return SVGMarkerOrientUnknown;
-        return SVGMarkerOrientAngle;
+        return SVGMarkerOrientUnknown;
+    }
+    static String toString(SVGMarkerOrientType type)
+    {
+        if (type == SVGMarkerOrientAuto)
+            return autoString();
+        if (type == SVGMarkerOrientAutoStartReverse)
+            return autoStartReverseString();
+        return emptyString();
     }
 };
 
@@ -93,18 +108,18 @@
 inline unsigned SVGIDLEnumLimits<SVGMarkerOrientType>::highestExposedEnumValue() { return SVGMarkerOrientAngle; }
 
 template<>
-struct SVGPropertyTraits<std::pair<SVGAngleValue, unsigned>> {
-    static std::pair<SVGAngleValue, unsigned> initialValue() { return { }; }
-    static std::pair<SVGAngleValue, unsigned> fromString(const String& string)
+struct SVGPropertyTraits<std::pair<SVGAngleValue, SVGMarkerOrientType>> {
+    static std::pair<SVGAngleValue, SVGMarkerOrientType> fromString(const String& string)
     {
         SVGAngleValue angle;
-        SVGMarkerOrientType orientType = SVGPropertyTraits<SVGMarkerOrientType>::fromString(string, angle);
-        if (orientType != SVGMarkerOrientAngle)
-            angle = { };
-        return std::pair<SVGAngleValue, unsigned>(angle, orientType);
+        SVGMarkerOrientType orientType = SVGPropertyTraits<SVGMarkerOrientType>::fromString(string);
+        if (orientType == SVGMarkerOrientUnknown) {
+            auto result = angle.setValueAsString(string);
+            if (!result.hasException())
+                orientType = SVGMarkerOrientAngle;
+        }
+        return std::make_pair(angle, orientType);
     }
-    static Optional<std::pair<SVGAngleValue, unsigned>> parse(const QualifiedName&, const String&) { ASSERT_NOT_REACHED(); return initialValue(); }
-    static String toString(const std::pair<SVGAngleValue, unsigned>&) { ASSERT_NOT_REACHED(); return emptyString(); }
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/svg/SVGMaskElement.cpp b/Source/WebCore/svg/SVGMaskElement.cpp
index cd43fa6..f377158 100644
--- a/Source/WebCore/svg/SVGMaskElement.cpp
+++ b/Source/WebCore/svg/SVGMaskElement.cpp
@@ -48,6 +48,12 @@
     // Spec: If the width/height attribute is not specified, the effect is as if a value of "120%" were specified.
     ASSERT(hasTagName(SVGNames::maskTag));
     registerAttributes();
+
+    static std::once_flag onceFlag;
+    std::call_once(onceFlag, [] {
+        PropertyRegistry::registerProperty<SVGNames::maskUnitsAttr, SVGUnitTypes::SVGUnitType, &SVGMaskElement::m_maskUnits>();
+        PropertyRegistry::registerProperty<SVGNames::maskContentUnitsAttr, SVGUnitTypes::SVGUnitType, &SVGMaskElement::m_maskContentUnits>();
+    });
 }
 
 Ref<SVGMaskElement> SVGMaskElement::create(const QualifiedName& tagName, Document& document)
@@ -64,8 +70,6 @@
     registry.registerAttribute<SVGNames::yAttr, &SVGMaskElement::m_y>();
     registry.registerAttribute<SVGNames::widthAttr, &SVGMaskElement::m_width>();
     registry.registerAttribute<SVGNames::heightAttr, &SVGMaskElement::m_height>();
-    registry.registerAttribute<SVGNames::maskUnitsAttr, SVGUnitTypes::SVGUnitType, &SVGMaskElement::m_maskUnits>();
-    registry.registerAttribute<SVGNames::maskContentUnitsAttr, SVGUnitTypes::SVGUnitType, &SVGMaskElement::m_maskContentUnits>();
 }
 
 void SVGMaskElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
@@ -73,13 +77,13 @@
     if (name == SVGNames::maskUnitsAttr) {
         auto propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
         if (propertyValue > 0)
-            m_maskUnits.setValue(propertyValue);
+            m_maskUnits->setBaseValInternal<SVGUnitTypes::SVGUnitType>(propertyValue);
         return;
     }
     if (name == SVGNames::maskContentUnitsAttr) {
         auto propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
         if (propertyValue > 0)
-            m_maskContentUnits.setValue(propertyValue);
+            m_maskContentUnits->setBaseValInternal<SVGUnitTypes::SVGUnitType>(propertyValue);
         return;
     }
 
diff --git a/Source/WebCore/svg/SVGMaskElement.h b/Source/WebCore/svg/SVGMaskElement.h
index d86f623..392a13c 100644
--- a/Source/WebCore/svg/SVGMaskElement.h
+++ b/Source/WebCore/svg/SVGMaskElement.h
@@ -20,7 +20,6 @@
 
 #pragma once
 
-#include "SVGAnimatedEnumeration.h"
 #include "SVGAnimatedLength.h"
 #include "SVGElement.h"
 #include "SVGExternalResourcesRequired.h"
@@ -39,15 +38,15 @@
     const SVGLengthValue& y() const { return m_y.currentValue(attributeOwnerProxy()); }
     const SVGLengthValue& width() const { return m_width.currentValue(attributeOwnerProxy()); }
     const SVGLengthValue& height() const { return m_height.currentValue(attributeOwnerProxy()); }
-    SVGUnitTypes::SVGUnitType maskUnits() const { return m_maskUnits.currentValue(attributeOwnerProxy()); }
-    SVGUnitTypes::SVGUnitType maskContentUnits() const { return m_maskContentUnits.currentValue(attributeOwnerProxy()); }
+    SVGUnitTypes::SVGUnitType maskUnits() const { return m_maskUnits->currentValue<SVGUnitTypes::SVGUnitType>(); }
+    SVGUnitTypes::SVGUnitType maskContentUnits() const { return m_maskContentUnits->currentValue<SVGUnitTypes::SVGUnitType>(); }
 
     RefPtr<SVGAnimatedLength> xAnimated() { return m_x.animatedProperty(attributeOwnerProxy()); }
     RefPtr<SVGAnimatedLength> yAnimated() { return m_y.animatedProperty(attributeOwnerProxy()); }
     RefPtr<SVGAnimatedLength> widthAnimated() { return m_width.animatedProperty(attributeOwnerProxy()); }
     RefPtr<SVGAnimatedLength> heightAnimated() { return m_height.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedEnumeration> maskUnitsAnimated() { return m_maskUnits.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedEnumeration> maskContentUnitsAnimated() { return m_maskContentUnits.animatedProperty(attributeOwnerProxy()); }
+    SVGAnimatedEnumeration& maskUnitsAnimated() { return m_maskUnits; }
+    SVGAnimatedEnumeration& maskContentUnitsAnimated() { return m_maskContentUnits; }
 
 private:
     SVGMaskElement(const QualifiedName&, Document&);
@@ -82,8 +81,8 @@
     SVGAnimatedLengthAttribute m_y { LengthModeHeight, "-10%" };
     SVGAnimatedLengthAttribute m_width { LengthModeWidth, "120%" };
     SVGAnimatedLengthAttribute m_height { LengthModeHeight, "120%" };
-    SVGAnimatedEnumerationAttribute<SVGUnitTypes::SVGUnitType> m_maskUnits { SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX };
-    SVGAnimatedEnumerationAttribute<SVGUnitTypes::SVGUnitType> m_maskContentUnits { SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE };
+    Ref<SVGAnimatedEnumeration> m_maskUnits { SVGAnimatedEnumeration::create(this, SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) };
+    Ref<SVGAnimatedEnumeration> m_maskContentUnits { SVGAnimatedEnumeration::create(this, SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) };
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/svg/SVGPatternElement.cpp b/Source/WebCore/svg/SVGPatternElement.cpp
index 700f26b..a3cb785 100644
--- a/Source/WebCore/svg/SVGPatternElement.cpp
+++ b/Source/WebCore/svg/SVGPatternElement.cpp
@@ -3,7 +3,7 @@
  * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
  * Copyright (C) 2014 Adobe Systems Incorporated. All rights reserved.
- * 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
@@ -54,6 +54,12 @@
 {
     ASSERT(hasTagName(SVGNames::patternTag));
     registerAttributes();
+
+    static std::once_flag onceFlag;
+    std::call_once(onceFlag, [] {
+        PropertyRegistry::registerProperty<SVGNames::patternUnitsAttr, SVGUnitTypes::SVGUnitType, &SVGPatternElement::m_patternUnits>();
+        PropertyRegistry::registerProperty<SVGNames::patternContentUnitsAttr, SVGUnitTypes::SVGUnitType, &SVGPatternElement::m_patternContentUnits>();
+    });
 }
 
 Ref<SVGPatternElement> SVGPatternElement::create(const QualifiedName& tagName, Document& document)
@@ -70,8 +76,6 @@
     registry.registerAttribute<SVGNames::yAttr, &SVGPatternElement::m_y>();
     registry.registerAttribute<SVGNames::widthAttr, &SVGPatternElement::m_width>();
     registry.registerAttribute<SVGNames::heightAttr, &SVGPatternElement::m_height>();
-    registry.registerAttribute<SVGNames::patternUnitsAttr, SVGUnitTypes::SVGUnitType, &SVGPatternElement::m_patternUnits>();
-    registry.registerAttribute<SVGNames::patternContentUnitsAttr, SVGUnitTypes::SVGUnitType, &SVGPatternElement::m_patternContentUnits>();
     registry.registerAttribute<SVGNames::patternTransformAttr, &SVGPatternElement::m_patternTransform>();
 }
 
@@ -80,13 +84,13 @@
     if (name == SVGNames::patternUnitsAttr) {
         auto propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
         if (propertyValue > 0)
-            m_patternUnits.setValue(propertyValue);
+            m_patternUnits->setBaseValInternal<SVGUnitTypes::SVGUnitType>(propertyValue);
         return;
     }
     if (name == SVGNames::patternContentUnitsAttr) {
         auto propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
         if (propertyValue > 0)
-            m_patternContentUnits.setValue(propertyValue);
+            m_patternContentUnits->setBaseValInternal<SVGUnitTypes::SVGUnitType>(propertyValue);
         return;
     }
     if (name == SVGNames::patternTransformAttr) {
diff --git a/Source/WebCore/svg/SVGPatternElement.h b/Source/WebCore/svg/SVGPatternElement.h
index 3214ab5..4cc0ac1 100644
--- a/Source/WebCore/svg/SVGPatternElement.h
+++ b/Source/WebCore/svg/SVGPatternElement.h
@@ -21,7 +21,6 @@
 
 #pragma once
 
-#include "SVGAnimatedEnumeration.h"
 #include "SVGAnimatedLength.h"
 #include "SVGAnimatedTransformList.h"
 #include "SVGElement.h"
@@ -49,16 +48,16 @@
     const SVGLengthValue& y() const { return m_y.currentValue(attributeOwnerProxy()); }
     const SVGLengthValue& width() const { return m_width.currentValue(attributeOwnerProxy()); }
     const SVGLengthValue& height() const { return m_height.currentValue(attributeOwnerProxy()); }
-    SVGUnitTypes::SVGUnitType patternUnits() const { return m_patternUnits.currentValue(attributeOwnerProxy()); }
-    SVGUnitTypes::SVGUnitType patternContentUnits() const { return m_patternContentUnits.currentValue(attributeOwnerProxy()); }
+    SVGUnitTypes::SVGUnitType patternUnits() const { return m_patternUnits->currentValue<SVGUnitTypes::SVGUnitType>(); }
+    SVGUnitTypes::SVGUnitType patternContentUnits() const { return m_patternContentUnits->currentValue<SVGUnitTypes::SVGUnitType>(); }
     const SVGTransformListValues& patternTransform() const { return m_patternTransform.currentValue(attributeOwnerProxy()); }
 
     RefPtr<SVGAnimatedLength> xAnimated() { return m_x.animatedProperty(attributeOwnerProxy()); }
     RefPtr<SVGAnimatedLength> yAnimated() { return m_y.animatedProperty(attributeOwnerProxy()); }
     RefPtr<SVGAnimatedLength> widthAnimated() { return m_width.animatedProperty(attributeOwnerProxy()); }
     RefPtr<SVGAnimatedLength> heightAnimated() { return m_height.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedEnumeration> patternUnitsAnimated() { return m_patternUnits.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedEnumeration> patternContentUnitsAnimated() { return m_patternContentUnits.animatedProperty(attributeOwnerProxy()); }
+    SVGAnimatedEnumeration& patternUnitsAnimated() { return m_patternUnits; }
+    SVGAnimatedEnumeration& patternContentUnitsAnimated() { return m_patternContentUnits; }
     RefPtr<SVGAnimatedTransformList> patternTransformAnimated() { return m_patternTransform.animatedProperty(attributeOwnerProxy()); }
 
 private:
@@ -94,8 +93,8 @@
     SVGAnimatedLengthAttribute m_y { LengthModeHeight };
     SVGAnimatedLengthAttribute m_width { LengthModeWidth };
     SVGAnimatedLengthAttribute m_height { LengthModeHeight };
-    SVGAnimatedEnumerationAttribute<SVGUnitTypes::SVGUnitType> m_patternUnits { SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX };
-    SVGAnimatedEnumerationAttribute<SVGUnitTypes::SVGUnitType> m_patternContentUnits { SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE };
+    Ref<SVGAnimatedEnumeration> m_patternUnits { SVGAnimatedEnumeration::create(this, SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) };
+    Ref<SVGAnimatedEnumeration> m_patternContentUnits { SVGAnimatedEnumeration::create(this, SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) };
     SVGAnimatedTransformListAttribute m_patternTransform;
 };
 
diff --git a/Source/WebCore/svg/SVGSVGElement.cpp b/Source/WebCore/svg/SVGSVGElement.cpp
index 48425fd..05d92f0 100644
--- a/Source/WebCore/svg/SVGSVGElement.cpp
+++ b/Source/WebCore/svg/SVGSVGElement.cpp
@@ -41,7 +41,6 @@
 #include "SVGNumber.h"
 #include "SVGPoint.h"
 #include "SVGRect.h"
-#include "SVGStaticPropertyTearOff.h"
 #include "SVGTransform.h"
 #include "SVGViewElement.h"
 #include "SVGViewSpec.h"
diff --git a/Source/WebCore/svg/SVGScriptElement.cpp b/Source/WebCore/svg/SVGScriptElement.cpp
index 9c333ed1..1e09454 100644
--- a/Source/WebCore/svg/SVGScriptElement.cpp
+++ b/Source/WebCore/svg/SVGScriptElement.cpp
@@ -24,7 +24,6 @@
 
 #include "Document.h"
 #include "Event.h"
-#include "SVGAnimatedStaticPropertyTearOff.h"
 #include <wtf/IsoMallocInlines.h>
 
 namespace WebCore {
diff --git a/Source/WebCore/svg/SVGTextContentElement.cpp b/Source/WebCore/svg/SVGTextContentElement.cpp
index 8be5605..2f3a0e3 100644
--- a/Source/WebCore/svg/SVGTextContentElement.cpp
+++ b/Source/WebCore/svg/SVGTextContentElement.cpp
@@ -48,6 +48,11 @@
     , SVGExternalResourcesRequired(this)
 {
     registerAttributes();
+
+    static std::once_flag onceFlag;
+    std::call_once(onceFlag, [] {
+        PropertyRegistry::registerProperty<SVGNames::lengthAdjustAttr, SVGLengthAdjustType, &SVGTextContentElement::m_lengthAdjust>();
+    });
 }
 
 unsigned SVGTextContentElement::getNumberOfChars()
@@ -164,7 +169,6 @@
     if (!registry.isEmpty())
         return;
     registry.registerAttribute(SVGAnimatedCustomLengthAttributeAccessor::singleton<SVGNames::textLengthAttr, &SVGTextContentElement::m_textLength>());
-    registry.registerAttribute<SVGNames::lengthAdjustAttr, SVGLengthAdjustType, &SVGTextContentElement::m_lengthAdjust>();
 }
 
 void SVGTextContentElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
@@ -174,7 +178,7 @@
     if (name == SVGNames::lengthAdjustAttr) {
         auto propertyValue = SVGPropertyTraits<SVGLengthAdjustType>::fromString(value);
         if (propertyValue > 0)
-            m_lengthAdjust.setValue(propertyValue);
+            m_lengthAdjust->setBaseValInternal<SVGLengthAdjustType>(propertyValue);
     } else if (name == SVGNames::textLengthAttr)
         m_textLength.setValue(SVGLengthValue::construct(LengthModeOther, value, parseError, ForbidNegativeLengths));
 
diff --git a/Source/WebCore/svg/SVGTextContentElement.h b/Source/WebCore/svg/SVGTextContentElement.h
index 2b12838..be9461f 100644
--- a/Source/WebCore/svg/SVGTextContentElement.h
+++ b/Source/WebCore/svg/SVGTextContentElement.h
@@ -21,7 +21,6 @@
 
 #pragma once
 
-#include "SVGAnimatedEnumeration.h"
 #include "SVGAnimatedLength.h"
 #include "SVGExternalResourcesRequired.h"
 #include "SVGGraphicsElement.h"
@@ -92,10 +91,10 @@
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGTextContentElement, SVGGraphicsElement, SVGExternalResourcesRequired>;
 
     const SVGLengthValue& textLength() const { return m_textLength.currentValue(attributeOwnerProxy()); }
-    SVGLengthAdjustType lengthAdjust() const { return m_lengthAdjust.currentValue(attributeOwnerProxy()); }
+    SVGLengthAdjustType lengthAdjust() const { return m_lengthAdjust->currentValue<SVGLengthAdjustType>(); }
 
     RefPtr<SVGAnimatedLength> textLengthAnimated() { return m_textLength.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedEnumeration> lengthAdjustAnimated() { return m_lengthAdjust.animatedProperty(attributeOwnerProxy()); }
+    SVGAnimatedEnumeration& lengthAdjustAnimated() { return m_lengthAdjust; }
 
 protected:
     SVGTextContentElement(const QualifiedName&, Document&);
@@ -159,7 +158,7 @@
     AttributeOwnerProxy m_attributeOwnerProxy { *this };
     PropertyRegistry m_propertyRegistry { *this };
     SVGAnimatedCustomLengthAttribute m_textLength { *this, LengthModeOther };
-    SVGAnimatedEnumerationAttribute<SVGLengthAdjustType> m_lengthAdjust { SVGLengthAdjustSpacing };
+    Ref<SVGAnimatedEnumeration> m_lengthAdjust { SVGAnimatedEnumeration::create(this, SVGLengthAdjustSpacing) };
     SVGLengthValue m_specifiedTextLength { LengthModeOther };
 };
 
diff --git a/Source/WebCore/svg/SVGTextPathElement.cpp b/Source/WebCore/svg/SVGTextPathElement.cpp
index 55895a9..65b40e5 100644
--- a/Source/WebCore/svg/SVGTextPathElement.cpp
+++ b/Source/WebCore/svg/SVGTextPathElement.cpp
@@ -39,6 +39,12 @@
 {
     ASSERT(hasTagName(SVGNames::textPathTag));
     registerAttributes();
+
+    static std::once_flag onceFlag;
+    std::call_once(onceFlag, [] {
+        PropertyRegistry::registerProperty<SVGNames::methodAttr, SVGTextPathMethodType, &SVGTextPathElement::m_method>();
+        PropertyRegistry::registerProperty<SVGNames::spacingAttr, SVGTextPathSpacingType, &SVGTextPathElement::m_spacing>();
+    });
 }
 
 Ref<SVGTextPathElement> SVGTextPathElement::create(const QualifiedName& tagName, Document& document)
@@ -62,8 +68,6 @@
     if (!registry.isEmpty())
         return;
     registry.registerAttribute<SVGNames::startOffsetAttr, &SVGTextPathElement::m_startOffset>();
-    registry.registerAttribute<SVGNames::methodAttr, SVGTextPathMethodType, &SVGTextPathElement::m_method>();
-    registry.registerAttribute<SVGNames::spacingAttr, SVGTextPathSpacingType, &SVGTextPathElement::m_spacing>();
 }
 
 void SVGTextPathElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
@@ -75,11 +79,11 @@
     else if (name == SVGNames::methodAttr) {
         SVGTextPathMethodType propertyValue = SVGPropertyTraits<SVGTextPathMethodType>::fromString(value);
         if (propertyValue > 0)
-            m_method.setValue(propertyValue);
+            m_method->setBaseValInternal<SVGTextPathMethodType>(propertyValue);
     } else if (name == SVGNames::spacingAttr) {
         SVGTextPathSpacingType propertyValue = SVGPropertyTraits<SVGTextPathSpacingType>::fromString(value);
         if (propertyValue > 0)
-            m_spacing.setValue(propertyValue);
+            m_spacing->setBaseValInternal<SVGTextPathSpacingType>(propertyValue);
     }
 
     reportAttributeParsingError(parseError, name, value);
diff --git a/Source/WebCore/svg/SVGTextPathElement.h b/Source/WebCore/svg/SVGTextPathElement.h
index 3931502..a57b722 100644
--- a/Source/WebCore/svg/SVGTextPathElement.h
+++ b/Source/WebCore/svg/SVGTextPathElement.h
@@ -112,12 +112,12 @@
     static Ref<SVGTextPathElement> create(const QualifiedName&, Document&);
 
     const SVGLengthValue& startOffset() const { return m_startOffset.currentValue(attributeOwnerProxy()); }
-    SVGTextPathMethodType method() const { return m_method.currentValue(attributeOwnerProxy()); }
-    SVGTextPathSpacingType spacing() const { return m_spacing.currentValue(attributeOwnerProxy()); }
+    SVGTextPathMethodType method() const { return m_method->currentValue<SVGTextPathMethodType>(); }
+    SVGTextPathSpacingType spacing() const { return m_spacing->currentValue<SVGTextPathSpacingType>(); }
 
     RefPtr<SVGAnimatedLength> startOffsetAnimated() { return m_startOffset.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedEnumeration> methodAnimated() { return m_method.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedEnumeration> spacingAnimated() { return m_spacing.animatedProperty(attributeOwnerProxy()); }
+    SVGAnimatedEnumeration& methodAnimated() { return m_method; }
+    SVGAnimatedEnumeration& spacingAnimated() { return m_spacing; }
 
 protected:
     void didFinishInsertingNode() override;
@@ -156,8 +156,8 @@
     AttributeOwnerProxy m_attributeOwnerProxy { *this };
     PropertyRegistry m_propertyRegistry { *this };
     SVGAnimatedLengthAttribute m_startOffset { LengthModeOther };
-    SVGAnimatedEnumerationAttribute<SVGTextPathMethodType> m_method { SVGTextPathMethodAlign };
-    SVGAnimatedEnumerationAttribute<SVGTextPathSpacingType> m_spacing { SVGTextPathSpacingExact };
+    Ref<SVGAnimatedEnumeration> m_method { SVGAnimatedEnumeration::create(this, SVGTextPathMethodAlign) };
+    Ref<SVGAnimatedEnumeration> m_spacing { SVGAnimatedEnumeration::create(this, SVGTextPathSpacingExact) };
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/svg/SVGValue.h b/Source/WebCore/svg/SVGValue.h
index 7d0d98e..d3624c2 100644
--- a/Source/WebCore/svg/SVGValue.h
+++ b/Source/WebCore/svg/SVGValue.h
@@ -25,15 +25,9 @@
 
 #pragma once
 
-#include "Color.h"
-#include "FloatRect.h"
-#include "SVGAngleValue.h"
 #include "SVGLengthListValues.h"
 #include "SVGLengthValue.h"
-#include "SVGMarkerTypes.h"
 #include "SVGPathByteStream.h"
-#include "SVGPreserveAspectRatioValue.h"
-#include "SVGPropertyTraits.h"
 #include "SVGTransformListValues.h"
 
 #include <wtf/Variant.h>
@@ -41,8 +35,6 @@
 namespace WebCore {
 
 using SVGValueVariant = Variant<
-    std::pair<SVGAngleValue, unsigned>*,
-    unsigned*,
     SVGLengthValue*,
     SVGLengthListValues*,
     SVGPathByteStream*,
diff --git a/Source/WebCore/svg/properties/SVGAnimatedDecoratedProperty.h b/Source/WebCore/svg/properties/SVGAnimatedDecoratedProperty.h
new file mode 100644
index 0000000..e5efaae
--- /dev/null
+++ b/Source/WebCore/svg/properties/SVGAnimatedDecoratedProperty.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2018-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 "SVGAnimatedProperty.h"
+#include "SVGDecoratedProperty.h"
+
+namespace WebCore {
+
+template<template <typename, typename> class DecoratedProperty, typename DecorationType>
+class SVGAnimatedDecoratedProperty : public SVGAnimatedProperty {
+public:
+    template<typename PropertyType, typename AnimatedProperty = SVGAnimatedDecoratedProperty>
+    static Ref<AnimatedProperty> create(SVGElement* contextElement)
+    {
+        return adoptRef(*new AnimatedProperty(contextElement, std::make_unique<DecoratedProperty<DecorationType, PropertyType>>()));
+    }
+
+    template<typename PropertyType, typename AnimatedProperty = SVGAnimatedDecoratedProperty>
+    static Ref<AnimatedProperty> create(SVGElement* contextElement, const PropertyType& value)
+    {
+        return adoptRef(*new AnimatedProperty(contextElement, DecoratedProperty<DecorationType, PropertyType>::create(value)));
+    }
+
+    SVGAnimatedDecoratedProperty(SVGElement* contextElement, std::unique_ptr<SVGDecoratedProperty<DecorationType>>&& baseVal)
+        : SVGAnimatedProperty(contextElement)
+        , m_baseVal(WTFMove(baseVal))
+    {
+    }
+
+    // Used by the DOM.
+    ExceptionOr<void> setBaseVal(const DecorationType& baseVal)
+    {
+        if (!m_baseVal->setValue(baseVal))
+            return Exception { TypeError };
+        commitPropertyChange(nullptr);
+        return { };
+    }
+
+    // Used by SVGElement::parseAttribute().
+    template<typename PropertyType>
+    void setBaseValInternal(const PropertyType& baseVal)
+    {
+        m_baseVal->setValueInternal(static_cast<DecorationType>(baseVal));
+        if (m_animVal)
+            m_animVal->setValueInternal(static_cast<DecorationType>(baseVal));
+    }
+
+    DecorationType baseVal() const { return m_baseVal->value(); }
+
+    // Used by SVGAnimator::progress.
+    template<typename PropertyType>
+    void setAnimVal(const PropertyType& animVal)
+    {
+        ASSERT(isAnimating() && m_animVal);
+        m_animVal->setValueInternal(static_cast<DecorationType>(animVal));
+    }
+
+    template<typename PropertyType = DecorationType>
+    PropertyType animVal() const
+    {
+        ASSERT_IMPLIES(isAnimating(), m_animVal);
+        return static_cast<PropertyType>((isAnimating() ? m_animVal : m_baseVal)->value());
+    }
+
+    // Used when committing a change from the SVGAnimatedProperty to the attribute.
+    String baseValAsString() const override { return m_baseVal->valueAsString(); }
+
+    // Used to apply the SVGAnimator change to the target element.
+    String animValAsString() const override
+    {
+        ASSERT(isAnimating() && !!m_animVal);
+        return m_animVal->valueAsString();
+    }
+
+    // Managing the relationship with the owner.
+    void setDirty() override { m_state = SVGPropertyState::Dirty; }
+    bool isDirty() const override { return m_state == SVGPropertyState::Dirty; }
+    Optional<String> synchronize() override
+    {
+        if (m_state == SVGPropertyState::Clean)
+            return WTF::nullopt;
+        m_state = SVGPropertyState::Clean;
+        return baseValAsString();
+    }
+
+    // Used by RenderSVGElements and DumpRenderTree.
+    template<typename PropertyType>
+    PropertyType currentValue() const
+    {
+        return static_cast<PropertyType>((isAnimating() ? m_animVal : m_baseVal)->valueInternal());
+    }
+
+    // Controlling the animation.
+    void startAnimation() override
+    {
+        if (isAnimating())
+            return;
+        m_animVal = m_baseVal->clone();
+        SVGAnimatedProperty::startAnimation();
+    }
+    void stopAnimation() override
+    {
+        if (!isAnimating())
+            return;
+        m_animVal = nullptr;
+        SVGAnimatedProperty::stopAnimation();
+    }
+
+protected:
+    std::unique_ptr<SVGDecoratedProperty<DecorationType>> m_baseVal;
+    std::unique_ptr<SVGDecoratedProperty<DecorationType>> m_animVal;
+    SVGPropertyState m_state { SVGPropertyState::Clean };
+};
+
+}
diff --git a/Source/WebCore/svg/properties/SVGAnimatedEnumerationPropertyTearOff.h b/Source/WebCore/svg/properties/SVGAnimatedEnumerationPropertyTearOff.h
deleted file mode 100644
index 5683af8..0000000
--- a/Source/WebCore/svg/properties/SVGAnimatedEnumerationPropertyTearOff.h
+++ /dev/null
@@ -1,86 +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 "SVGAnimatedStaticPropertyTearOff.h"
-#include "SVGPropertyTraits.h"
-
-namespace WebCore {
-
-template<typename EnumType>
-class SVGAnimatedEnumerationPropertyTearOff final : public SVGAnimatedStaticPropertyTearOff<unsigned> {
-public:
-    using ContentType = EnumType;
-
-    const unsigned& baseVal() final
-    {
-        const unsigned& baseVal = SVGAnimatedStaticPropertyTearOff::baseVal();
-
-        if (baseVal > SVGIDLEnumLimits<EnumType>::highestExposedEnumValue())
-            return m_outOfRangeEnumValue;
-
-        return baseVal;
-    }
-
-    const unsigned& animVal() final
-    {
-        const unsigned& animVal = SVGAnimatedStaticPropertyTearOff::animVal();
-
-        if (animVal > SVGIDLEnumLimits<EnumType>::highestExposedEnumValue())
-            return m_outOfRangeEnumValue;
-
-        return animVal;
-    }
-
-    ExceptionOr<void> setBaseVal(const unsigned& property) final
-    {
-        // All SVG enumeration values, that are allowed to be set via SVG DOM start with 1, 0 corresponds to unknown and is not settable through SVG DOM.
-        if (!property || property > SVGIDLEnumLimits<EnumType>::highestExposedEnumValue())
-            return Exception { TypeError };
-        return SVGAnimatedStaticPropertyTearOff<unsigned>::setBaseVal(property);
-    }
-
-    static Ref<SVGAnimatedEnumerationPropertyTearOff<EnumType>> create(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, EnumType& property)
-    {
-        ASSERT(contextElement);
-        return adoptRef(*new SVGAnimatedEnumerationPropertyTearOff<EnumType>(contextElement, attributeName, animatedPropertyType, reinterpret_cast<unsigned&>(property)));
-    }
-
-    EnumType& currentAnimatedValue()
-    {
-        unsigned& animatedValue = SVGAnimatedStaticPropertyTearOff<unsigned>::currentAnimatedValue();
-        ASSERT(animatedValue <= SVGPropertyTraits<EnumType>::highestEnumValue());
-        return reinterpret_cast<EnumType&>(animatedValue);
-    }
-
-private:
-    SVGAnimatedEnumerationPropertyTearOff(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, unsigned& property)
-        : SVGAnimatedStaticPropertyTearOff<unsigned>(contextElement, attributeName, animatedPropertyType, property)
-    {
-    }
-
-    static unsigned m_outOfRangeEnumValue;
-};
-
-// By convention, all enum values that represent UNKNOWN in SVG are equal to zero.
-template<typename EnumType>
-unsigned SVGAnimatedEnumerationPropertyTearOff<EnumType>::m_outOfRangeEnumValue = 0;
-
-} // namespace WebCore
diff --git a/Source/WebCore/svg/properties/SVGAnimatedPropertyAccessorImpl.h b/Source/WebCore/svg/properties/SVGAnimatedPropertyAccessorImpl.h
index a48503c..70f19fd 100644
--- a/Source/WebCore/svg/properties/SVGAnimatedPropertyAccessorImpl.h
+++ b/Source/WebCore/svg/properties/SVGAnimatedPropertyAccessorImpl.h
@@ -33,6 +33,16 @@
 namespace WebCore {
 
 template<typename OwnerType>
+class SVGAnimatedAngleAccessor final : public SVGAnimatedPropertyAccessor<OwnerType, SVGAnimatedAngle> {
+    using Base = SVGAnimatedPropertyAccessor<OwnerType, SVGAnimatedAngle>;
+
+public:
+    using Base::Base;
+    template<Ref<SVGAnimatedAngle> OwnerType::*property>
+    constexpr static const SVGMemberAccessor<OwnerType>& singleton() { return Base::template singleton<SVGAnimatedAngleAccessor, property>(); }
+};
+
+template<typename OwnerType>
 class SVGAnimatedBooleanAccessor final : public SVGAnimatedPropertyAccessor<OwnerType, SVGAnimatedBoolean> {
     using Base = SVGAnimatedPropertyAccessor<OwnerType, SVGAnimatedBoolean>;
     using Base::property;
@@ -54,6 +64,28 @@
     }
 };
 
+template<typename OwnerType, typename EnumType>
+class SVGAnimatedEnumerationAccessor final : public SVGAnimatedPropertyAccessor<OwnerType, SVGAnimatedEnumeration> {
+    using Base = SVGAnimatedPropertyAccessor<OwnerType, SVGAnimatedEnumeration>;
+    using Base::property;
+
+public:
+    using Base::Base;
+    template<Ref<SVGAnimatedEnumeration> OwnerType::*property>
+    constexpr static const SVGMemberAccessor<OwnerType>& singleton() { return Base::template singleton<SVGAnimatedEnumerationAccessor, property>(); }
+
+private:
+    std::unique_ptr<SVGAttributeAnimator> createAnimator(OwnerType& owner, const QualifiedName& attributeName, AnimationMode animationMode, CalcMode calcMode, bool isAccumulated, bool isAdditive) const final
+    {
+        return SVGAnimatedEnumerationAnimator<EnumType>::create(attributeName, property(owner), animationMode, calcMode, isAccumulated, isAdditive);
+    }
+
+    void appendAnimatedInstance(OwnerType& owner, SVGAttributeAnimator& animator) const final
+    {
+        static_cast<SVGAnimatedEnumerationAnimator<EnumType>&>(animator).appendAnimatedInstance(property(owner));
+    }
+};
+
 template<typename OwnerType>
 class SVGAnimatedIntegerAccessor final : public SVGAnimatedPropertyAccessor<OwnerType, SVGAnimatedInteger> {
     using Base = SVGAnimatedPropertyAccessor<OwnerType, SVGAnimatedInteger>;
@@ -143,6 +175,16 @@
 };
     
 template<typename OwnerType>
+class SVGAnimatedOrientTypeAccessor final : public SVGAnimatedPropertyAccessor<OwnerType, SVGAnimatedOrientType> {
+    using Base = SVGAnimatedPropertyAccessor<OwnerType, SVGAnimatedOrientType>;
+
+public:
+    using Base::Base;
+    template<Ref<SVGAnimatedOrientType> OwnerType::*property>
+    constexpr static const SVGMemberAccessor<OwnerType>& singleton() {return Base::template singleton<SVGAnimatedOrientTypeAccessor, property>(); }
+};
+
+template<typename OwnerType>
 class SVGAnimatedPreserveAspectRatioAccessor final : public SVGAnimatedPropertyAccessor<OwnerType, SVGAnimatedPreserveAspectRatio> {
     using Base = SVGAnimatedPropertyAccessor<OwnerType, SVGAnimatedPreserveAspectRatio>;
     using Base::property;
diff --git a/Source/WebCore/svg/properties/SVGAnimatedPropertyAnimatorImpl.h b/Source/WebCore/svg/properties/SVGAnimatedPropertyAnimatorImpl.h
index 5d9125f..a7f35d3 100644
--- a/Source/WebCore/svg/properties/SVGAnimatedPropertyAnimatorImpl.h
+++ b/Source/WebCore/svg/properties/SVGAnimatedPropertyAnimatorImpl.h
@@ -33,11 +33,32 @@
 
 namespace WebCore {
 
+class SVGAnimatedAngleAnimator;
 class SVGAnimatedIntegerPairAnimator;
+class SVGAnimatedOrientTypeAnimator;
 
 template<typename AnimatedPropertyAnimator1, typename AnimatedPropertyAnimator2>
 class SVGAnimatedPropertyPairAnimator;
 
+class SVGAnimatedAngleAnimator final : public SVGAnimatedPropertyAnimator<SVGAnimatedAngle, SVGAnimationAngleFunction> {
+    friend class SVGAnimatedPropertyPairAnimator<SVGAnimatedAngleAnimator, SVGAnimatedOrientTypeAnimator>;
+    friend class SVGAnimatedAngleOrientAnimator;
+    using Base = SVGAnimatedPropertyAnimator<SVGAnimatedAngle, SVGAnimationAngleFunction>;
+    using Base::Base;
+
+public:
+    static auto create(const QualifiedName& attributeName, Ref<SVGAnimatedAngle>& animated, AnimationMode animationMode, CalcMode calcMode, bool isAccumulated, bool isAdditive)
+    {
+        return std::make_unique<SVGAnimatedAngleAnimator>(attributeName, animated, animationMode, calcMode, isAccumulated, isAdditive);
+    }
+
+private:
+    void progress(SVGElement* targetElement, float percentage, unsigned repeatCount) final
+    {
+        m_function.progress(targetElement, percentage, repeatCount, m_animated->animVal()->value());
+    }
+};
+
 class SVGAnimatedBooleanAnimator final : public SVGAnimatedPropertyAnimator<SVGAnimatedBoolean, SVGAnimationBooleanFunction>  {
     using Base = SVGAnimatedPropertyAnimator<SVGAnimatedBoolean, SVGAnimationBooleanFunction>;
 
@@ -57,6 +78,28 @@
     }
 };
 
+template<typename EnumType>
+class SVGAnimatedEnumerationAnimator final : public SVGAnimatedPropertyAnimator<SVGAnimatedEnumeration, SVGAnimationEnumerationFunction<EnumType>> {
+    using Base = SVGAnimatedPropertyAnimator<SVGAnimatedEnumeration, SVGAnimationEnumerationFunction<EnumType>>;
+    using Base::Base;
+    using Base::m_animated;
+    using Base::m_function;
+
+public:
+    static auto create(const QualifiedName& attributeName, Ref<SVGAnimatedEnumeration>& animated, AnimationMode animationMode, CalcMode calcMode, bool isAccumulated, bool isAdditive)
+    {
+        return std::make_unique<SVGAnimatedEnumerationAnimator<EnumType>>(attributeName, animated, animationMode, calcMode, isAccumulated, isAdditive);
+    }
+
+private:
+    void progress(SVGElement* targetElement, float percentage, unsigned repeatCount) final
+    {
+        EnumType animated;
+        m_function.progress(targetElement, percentage, repeatCount, animated);
+        m_animated->template setAnimVal<EnumType>(animated);
+    }
+};
+
 class SVGAnimatedIntegerAnimator final : public SVGAnimatedPropertyAnimator<SVGAnimatedInteger, SVGAnimationIntegerFunction> {
     friend class SVGAnimatedPropertyPairAnimator<SVGAnimatedIntegerAnimator, SVGAnimatedIntegerAnimator>;
     friend class SVGAnimatedIntegerPairAnimator;
@@ -86,7 +129,7 @@
 public:
     static auto create(const QualifiedName& attributeName, Ref<SVGAnimatedNumber>& animated, AnimationMode animationMode, CalcMode calcMode, bool isAccumulated, bool isAdditive)
     {
-        return std::unique_ptr<SVGAnimatedNumberAnimator>(new SVGAnimatedNumberAnimator(attributeName, animated, animationMode, calcMode, isAccumulated, isAdditive));
+        return std::make_unique<SVGAnimatedNumberAnimator>(attributeName, animated, animationMode, calcMode, isAccumulated, isAdditive);
     }
 
 private:
@@ -130,6 +173,27 @@
     }
 };
 
+class SVGAnimatedOrientTypeAnimator final : public SVGAnimatedPropertyAnimator<SVGAnimatedOrientType, SVGAnimationOrientTypeFunction> {
+    friend class SVGAnimatedPropertyPairAnimator<SVGAnimatedAngleAnimator, SVGAnimatedOrientTypeAnimator>;
+    friend class SVGAnimatedAngleOrientAnimator;
+    using Base = SVGAnimatedPropertyAnimator<SVGAnimatedOrientType, SVGAnimationOrientTypeFunction>;
+    using Base::Base;
+
+public:
+    static auto create(const QualifiedName& attributeName, Ref<SVGAnimatedOrientType>& animated, AnimationMode animationMode, CalcMode calcMode, bool isAccumulated, bool isAdditive)
+    {
+        return std::make_unique<SVGAnimatedOrientTypeAnimator>(attributeName, animated, animationMode, calcMode, isAccumulated, isAdditive);
+    }
+
+private:
+    void progress(SVGElement* targetElement, float percentage, unsigned repeatCount) final
+    {
+        SVGMarkerOrientType animated;
+        m_function.progress(targetElement, percentage, repeatCount, animated);
+        m_animated->setAnimVal(animated);
+    }
+};
+
 class SVGAnimatedPreserveAspectRatioAnimator final : public SVGAnimatedPropertyAnimator<SVGAnimatedPreserveAspectRatio, SVGAnimationPreserveAspectRatioFunction> {
     using Base = SVGAnimatedPropertyAnimator<SVGAnimatedPreserveAspectRatio, SVGAnimationPreserveAspectRatioFunction>;
     using Base::Base;
diff --git a/Source/WebCore/svg/properties/SVGAnimatedPropertyImpl.h b/Source/WebCore/svg/properties/SVGAnimatedPropertyImpl.h
index 3a67622..96120fd 100644
--- a/Source/WebCore/svg/properties/SVGAnimatedPropertyImpl.h
+++ b/Source/WebCore/svg/properties/SVGAnimatedPropertyImpl.h
@@ -25,14 +25,16 @@
 
 #pragma once
 
-#include "SVGAnimatedAngle.h"
-#include "SVGAnimatedEnumeration.h"
+#include "SVGAngle.h"
+#include "SVGAnimatedDecoratedProperty.h"
 #include "SVGAnimatedLength.h"
 #include "SVGAnimatedLengthList.h"
 #include "SVGAnimatedPrimitiveProperty.h"
 #include "SVGAnimatedPropertyList.h"
 #include "SVGAnimatedTransformList.h"
 #include "SVGAnimatedValueProperty.h"
+#include "SVGDecoratedEnumeration.h"
+#include "SVGMarkerTypes.h"
 #include "SVGNumberList.h"
 #include "SVGPointList.h"
 #include "SVGPreserveAspectRatio.h"
@@ -45,10 +47,23 @@
 using SVGAnimatedNumber = SVGAnimatedPrimitiveProperty<float>;
 using SVGAnimatedString = SVGAnimatedPrimitiveProperty<String>;
 
+using SVGAnimatedEnumeration = SVGAnimatedDecoratedProperty<SVGDecoratedEnumeration, unsigned>;
+
+using SVGAnimatedAngle = SVGAnimatedValueProperty<SVGAngle>;
 using SVGAnimatedRect = SVGAnimatedValueProperty<SVGRect>;
 using SVGAnimatedPreserveAspectRatio = SVGAnimatedValueProperty<SVGPreserveAspectRatio>;
 
 using SVGAnimatedNumberList = SVGAnimatedPropertyList<SVGNumberList>;
 using SVGAnimatedPointList = SVGAnimatedPropertyList<SVGPointList>;
 
+class SVGAnimatedOrientType : public SVGAnimatedEnumeration {
+public:
+    using SVGAnimatedEnumeration::SVGAnimatedEnumeration;
+
+    static Ref<SVGAnimatedOrientType> create(SVGElement* contextElement, SVGMarkerOrientType baseValue)
+    {
+        return SVGAnimatedEnumeration::create<SVGMarkerOrientType, SVGAnimatedOrientType>(contextElement, baseValue);
+    }
+};
+
 }
diff --git a/Source/WebCore/svg/properties/SVGAnimatedPropertyPairAccessorImpl.h b/Source/WebCore/svg/properties/SVGAnimatedPropertyPairAccessorImpl.h
index 5669015..d47e4ae 100644
--- a/Source/WebCore/svg/properties/SVGAnimatedPropertyPairAccessorImpl.h
+++ b/Source/WebCore/svg/properties/SVGAnimatedPropertyPairAccessorImpl.h
@@ -35,6 +35,43 @@
 namespace WebCore {
 
 template<typename OwnerType>
+class SVGAnimatedAngleOrientAccessor final : public SVGAnimatedPropertyPairAccessor<OwnerType, SVGAnimatedAngleAccessor<OwnerType>, SVGAnimatedOrientTypeAccessor<OwnerType>> {
+    using Base = SVGAnimatedPropertyPairAccessor<OwnerType, SVGAnimatedAngleAccessor<OwnerType>, SVGAnimatedOrientTypeAccessor<OwnerType>>;
+    using Base::property1;
+    using Base::property2;
+
+public:
+    using Base::Base;
+    template<Ref<SVGAnimatedAngle> OwnerType::*property1, Ref<SVGAnimatedOrientType> OwnerType::*property2>
+    constexpr static const SVGMemberAccessor<OwnerType>& singleton() { return Base::template singleton<SVGAnimatedAngleOrientAccessor, property1, property2>(); }
+
+private:
+    Optional<String> synchronize(const OwnerType& owner) const final
+    {
+        bool dirty1 = property1(owner)->isDirty();
+        bool dirty2 = property2(owner)->isDirty();
+        if (!(dirty1 || dirty2))
+            return WTF::nullopt;
+
+        auto type = property2(owner)->baseVal();
+
+        String string1 = dirty1 ? *property1(owner)->synchronize() : property1(owner)->baseValAsString();
+        String string2 = dirty2 ? *property2(owner)->synchronize() : property2(owner)->baseValAsString();
+        return type == SVGMarkerOrientAuto || type == SVGMarkerOrientAutoStartReverse ? string2 : string1;
+    }
+
+    std::unique_ptr<SVGAttributeAnimator> createAnimator(OwnerType& owner, const QualifiedName& attributeName, AnimationMode animationMode, CalcMode calcMode, bool isAccumulated, bool isAdditive) const final
+    {
+        return SVGAnimatedAngleOrientAnimator::create(attributeName, property1(owner), property2(owner), animationMode, calcMode, isAccumulated, isAdditive);
+    }
+
+    void appendAnimatedInstance(OwnerType& owner, SVGAttributeAnimator& animator) const final
+    {
+        static_cast<SVGAnimatedAngleOrientAnimator&>(animator).appendAnimatedInstance(property1(owner), property2(owner));
+    }
+};
+
+template<typename OwnerType>
 class SVGAnimatedIntegerPairAccessor final : public SVGAnimatedPropertyPairAccessor<OwnerType, SVGAnimatedIntegerAccessor<OwnerType>, SVGAnimatedIntegerAccessor<OwnerType>> {
     using Base = SVGAnimatedPropertyPairAccessor<OwnerType, SVGAnimatedIntegerAccessor<OwnerType>, SVGAnimatedIntegerAccessor<OwnerType>>;
     using Base::property1;
diff --git a/Source/WebCore/svg/properties/SVGAnimatedPropertyPairAnimator.h b/Source/WebCore/svg/properties/SVGAnimatedPropertyPairAnimator.h
index 923488d..dce65ac 100644
--- a/Source/WebCore/svg/properties/SVGAnimatedPropertyPairAnimator.h
+++ b/Source/WebCore/svg/properties/SVGAnimatedPropertyPairAnimator.h
@@ -37,13 +37,6 @@
     using AnimatedProperty1 = typename AnimatedPropertyAnimator1::AnimatorAnimatedProperty;
     using AnimatedProperty2 = typename AnimatedPropertyAnimator2::AnimatorAnimatedProperty;
 
-    void appendAnimatedInstance(Ref<AnimatedProperty1>& animated1, Ref<AnimatedProperty2>& animated2)
-    {
-        m_animatedPropertyAnimator1->appendAnimatedInstance(animated1);
-        m_animatedPropertyAnimator2->appendAnimatedInstance(animated2);
-    }
-
-protected:
     SVGAnimatedPropertyPairAnimator(const QualifiedName& attributeName, Ref<AnimatedProperty1>& animated1, Ref<AnimatedProperty2>& animated2, AnimationMode animationMode, CalcMode calcMode, bool isAccumulated, bool isAdditive)
         : SVGAttributeAnimator(attributeName)
         , m_animatedPropertyAnimator1(AnimatedPropertyAnimator1::create(attributeName, animated1, animationMode, calcMode, isAccumulated, isAdditive))
@@ -51,6 +44,13 @@
     {
     }
 
+    void appendAnimatedInstance(Ref<AnimatedProperty1>& animated1, Ref<AnimatedProperty2>& animated2)
+    {
+        m_animatedPropertyAnimator1->appendAnimatedInstance(animated1);
+        m_animatedPropertyAnimator2->appendAnimatedInstance(animated2);
+    }
+
+protected:
     void start(SVGElement* targetElement) override
     {
         m_animatedPropertyAnimator1->start(targetElement);
diff --git a/Source/WebCore/svg/properties/SVGAnimatedPropertyPairAnimatorImpl.h b/Source/WebCore/svg/properties/SVGAnimatedPropertyPairAnimatorImpl.h
index e1f98e4..14aa21a 100644
--- a/Source/WebCore/svg/properties/SVGAnimatedPropertyPairAnimatorImpl.h
+++ b/Source/WebCore/svg/properties/SVGAnimatedPropertyPairAnimatorImpl.h
@@ -33,6 +33,79 @@
 
 class SVGElement;
 
+class SVGAnimatedAngleOrientAnimator final : public SVGAnimatedPropertyPairAnimator<SVGAnimatedAngleAnimator, SVGAnimatedOrientTypeAnimator> {
+    using Base = SVGAnimatedPropertyPairAnimator<SVGAnimatedAngleAnimator, SVGAnimatedOrientTypeAnimator>;
+    using Base::Base;
+
+public:
+    static auto create(const QualifiedName& attributeName, Ref<SVGAnimatedAngle>& animated1, Ref<SVGAnimatedOrientType>& animated2, AnimationMode animationMode, CalcMode calcMode, bool isAccumulated, bool isAdditive)
+    {
+        return std::make_unique<SVGAnimatedAngleOrientAnimator>(attributeName, animated1, animated2, animationMode, calcMode, isAccumulated, isAdditive);
+    }
+
+private:
+    void setFromAndToValues(SVGElement*, const String& from, const String& to) final
+    {
+        auto pairFrom = SVGPropertyTraits<std::pair<SVGAngleValue, SVGMarkerOrientType>>::fromString(from);
+        auto pairTo = SVGPropertyTraits<std::pair<SVGAngleValue, SVGMarkerOrientType>>::fromString(to);
+
+        m_animatedPropertyAnimator1->m_function.m_from = pairFrom.first;
+        m_animatedPropertyAnimator1->m_function.m_to = pairTo.first;
+
+        m_animatedPropertyAnimator2->m_function.m_from = pairFrom.second;
+        m_animatedPropertyAnimator2->m_function.m_to = pairTo.second;
+    }
+
+    void setFromAndByValues(SVGElement* targetElement, const String& from, const String& by) final
+    {
+        setFromAndToValues(targetElement, from, by);
+        if (m_animatedPropertyAnimator2->m_function.m_from != SVGMarkerOrientAngle || m_animatedPropertyAnimator2->m_function.m_to != SVGMarkerOrientAngle)
+            return;
+        m_animatedPropertyAnimator1->m_function.addFromAndToValues(targetElement);
+    }
+
+    void progress(SVGElement* targetElement, float percentage, unsigned repeatCount) final
+    {
+        if (m_animatedPropertyAnimator2->m_function.m_from != m_animatedPropertyAnimator2->m_function.m_to) {
+            // Discrete animation - no linear interpolation possible between values (e.g. auto to angle).
+            m_animatedPropertyAnimator2->progress(targetElement, percentage, repeatCount);
+
+            SVGAngleValue animatedAngle;
+            if (percentage < 0.5f && m_animatedPropertyAnimator2->m_function.m_from == SVGMarkerOrientAngle)
+                animatedAngle = m_animatedPropertyAnimator1->m_function.m_from;
+            else if (percentage >= 0.5f && m_animatedPropertyAnimator2->m_function.m_to == SVGMarkerOrientAngle)
+                animatedAngle = m_animatedPropertyAnimator1->m_function.m_to;
+
+            m_animatedPropertyAnimator1->m_animated->setAnimVal(animatedAngle);
+            return;
+        }
+
+        if (m_animatedPropertyAnimator2->m_function.m_from == SVGMarkerOrientAngle) {
+            // Regular from- toangle animation, with support for smooth interpolation, and additive and accumulated animation.
+            m_animatedPropertyAnimator2->m_animated->setAnimVal(SVGMarkerOrientAngle);
+
+            m_animatedPropertyAnimator1->progress(targetElement, percentage, repeatCount);
+            return;
+        }
+
+        // auto, auto-start-reverse, or unknown.
+        m_animatedPropertyAnimator1->m_animated->animVal()->value().setValue(0);
+
+        if (m_animatedPropertyAnimator2->m_function.m_from == SVGMarkerOrientAuto || m_animatedPropertyAnimator2->m_function.m_from == SVGMarkerOrientAutoStartReverse)
+            m_animatedPropertyAnimator2->m_animated->setAnimVal(m_animatedPropertyAnimator2->m_function.m_from);
+        else
+            m_animatedPropertyAnimator2->m_animated->setAnimVal(SVGMarkerOrientUnknown);
+    }
+
+    void stop(SVGElement* targetElement) final
+    {
+        if (!m_animatedPropertyAnimator1->m_animated->isAnimating())
+            return;
+        apply(targetElement);
+        Base::stop(targetElement);
+    }
+};
+
 class SVGAnimatedIntegerPairAnimator final : public SVGAnimatedPropertyPairAnimator<SVGAnimatedIntegerAnimator, SVGAnimatedIntegerAnimator> {
     using Base = SVGAnimatedPropertyPairAnimator<SVGAnimatedIntegerAnimator, SVGAnimatedIntegerAnimator>;
     using Base::Base;
@@ -40,7 +113,7 @@
 public:
     static auto create(const QualifiedName& attributeName, Ref<SVGAnimatedInteger>& animated1, Ref<SVGAnimatedInteger>& animated2, AnimationMode animationMode, CalcMode calcMode, bool isAccumulated, bool isAdditive)
     {
-        return std::unique_ptr<SVGAnimatedIntegerPairAnimator>(new SVGAnimatedIntegerPairAnimator(attributeName, animated1, animated2, animationMode, calcMode, isAccumulated, isAdditive));
+        return std::make_unique<SVGAnimatedIntegerPairAnimator>(attributeName, animated1, animated2, animationMode, calcMode, isAccumulated, isAdditive);
     }
 
 private:
@@ -83,7 +156,7 @@
 public:
     static auto create(const QualifiedName& attributeName, Ref<SVGAnimatedNumber>& animated1, Ref<SVGAnimatedNumber>& animated2, AnimationMode animationMode, CalcMode calcMode, bool isAccumulated, bool isAdditive)
     {
-        return std::unique_ptr<SVGAnimatedNumberPairAnimator>(new SVGAnimatedNumberPairAnimator(attributeName, animated1, animated2, animationMode, calcMode, isAccumulated, isAdditive));
+        return std::make_unique<SVGAnimatedNumberPairAnimator>(attributeName, animated1, animated2, animationMode, calcMode, isAccumulated, isAdditive);
     }
 
 private:
diff --git a/Source/WebCore/svg/properties/SVGAnimatedStaticPropertyTearOff.h b/Source/WebCore/svg/properties/SVGAnimatedStaticPropertyTearOff.h
deleted file mode 100644
index 90c6b32..0000000
--- a/Source/WebCore/svg/properties/SVGAnimatedStaticPropertyTearOff.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010-2012. All rights reserved.
- * Copyright (C) 2016 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.
- */
-
-#pragma once
-
-#include "ExceptionOr.h"
-#include "SVGLegacyAnimatedProperty.h"
-
-namespace WebCore {
-
-template<typename PropertyType>
-class SVGAnimatedStaticPropertyTearOff : public SVGLegacyAnimatedProperty {
-public:
-    typedef PropertyType ContentType;
-
-    virtual const PropertyType& baseVal()
-    {
-        return m_property;
-    }
-
-    virtual const PropertyType& animVal()
-    {
-        if (m_animatedProperty)
-            return *m_animatedProperty;
-        return m_property;
-    }
-
-    virtual ExceptionOr<void> setBaseVal(const PropertyType& property)
-    {
-        m_property = property;
-        commitChange();
-        return { };
-    }
-
-    bool isAnimating() const override { return m_animatedProperty; }
-
-    static Ref<SVGAnimatedStaticPropertyTearOff<PropertyType>> create(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, PropertyType& property)
-    {
-        ASSERT(contextElement);
-        return adoptRef(*new SVGAnimatedStaticPropertyTearOff<PropertyType>(contextElement, attributeName, animatedPropertyType, property));
-    }
-
-    PropertyType& currentAnimatedValue()
-    {
-        ASSERT(isAnimating());
-        return *m_animatedProperty;
-    }
-
-    const PropertyType& currentBaseValue() const
-    {
-        return m_property;
-    }
-
-    void animationStarted(PropertyType* newAnimVal)
-    {
-        ASSERT(!isAnimating());
-        ASSERT(newAnimVal);
-        m_animatedProperty = newAnimVal;
-    }
-
-    void animationEnded()
-    {
-        ASSERT(isAnimating());
-        m_animatedProperty = nullptr;
-    }
-
-    void animValWillChange()
-    {
-        // no-op for non list types.
-        ASSERT(isAnimating());
-    }
-
-    void animValDidChange()
-    {
-        // no-op for non list types.
-        ASSERT(isAnimating());
-    }
-
-    void synchronizeWrappersIfNeeded()
-    {
-        // no-op
-    }
-
-protected:
-    SVGAnimatedStaticPropertyTearOff(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, PropertyType& property)
-        : SVGLegacyAnimatedProperty(contextElement, attributeName, animatedPropertyType)
-        , m_property(property)
-        , m_animatedProperty(nullptr)
-    {
-    }
-
-private:
-    PropertyType& m_property;
-    PropertyType* m_animatedProperty;
-};
-
-}
diff --git a/Source/WebCore/svg/properties/SVGAnimationAdditiveValueFunctionImpl.h b/Source/WebCore/svg/properties/SVGAnimationAdditiveValueFunctionImpl.h
index ef2ce6d..51de92d 100644
--- a/Source/WebCore/svg/properties/SVGAnimationAdditiveValueFunctionImpl.h
+++ b/Source/WebCore/svg/properties/SVGAnimationAdditiveValueFunctionImpl.h
@@ -30,6 +30,33 @@
 
 namespace WebCore {
 
+class SVGAnimationAngleFunction : public SVGAnimationAdditiveValueFunction<SVGAngleValue> {
+public:
+    using Base = SVGAnimationAdditiveValueFunction<SVGAngleValue>;
+    using Base::Base;
+
+    void setFromAndToValues(SVGElement*, const String&, const String&) override
+    {
+        // Values will be set by SVGAnimatedAngleOrientAnimator.
+        ASSERT_NOT_REACHED();
+    }
+
+    void progress(SVGElement*, float percentage, unsigned repeatCount, SVGAngleValue& animated)
+    {
+        float number = animated.value();
+        number = Base::progress(percentage, repeatCount, m_from.value(), m_to.value(), toAtEndOfDuration().value(), number);
+        animated.setValue(number);
+    }
+
+private:
+    friend class SVGAnimatedAngleOrientAnimator;
+
+    void addFromAndToValues(SVGElement*) override
+    {
+        m_to.setValue(m_to.value() + m_from.value());
+    }
+};
+
 class SVGAnimationColorFunction : public SVGAnimationAdditiveValueFunction<Color> {
 public:
     using Base = SVGAnimationAdditiveValueFunction<Color>;
diff --git a/Source/WebCore/svg/properties/SVGAnimationDiscreteFunctionImpl.h b/Source/WebCore/svg/properties/SVGAnimationDiscreteFunctionImpl.h
index 2755c39..aaecd18 100644
--- a/Source/WebCore/svg/properties/SVGAnimationDiscreteFunctionImpl.h
+++ b/Source/WebCore/svg/properties/SVGAnimationDiscreteFunctionImpl.h
@@ -42,6 +42,37 @@
     }
 };
 
+template<typename EnumType>
+class SVGAnimationEnumerationFunction : public SVGAnimationDiscreteFunction<EnumType> {
+    using Base = SVGAnimationDiscreteFunction<EnumType>;
+    using Base::m_from;
+    using Base::m_to;
+
+public:
+    using Base::Base;
+
+    void setFromAndToValues(SVGElement*, const String& from, const String& to) override
+    {
+        m_from = SVGPropertyTraits<EnumType>::fromString(from);
+        m_to = SVGPropertyTraits<EnumType>::fromString(to);
+    }
+};
+
+class SVGAnimationOrientTypeFunction : public SVGAnimationDiscreteFunction<SVGMarkerOrientType> {
+public:
+    using Base = SVGAnimationDiscreteFunction<SVGMarkerOrientType>;
+    using Base::Base;
+
+    void setFromAndToValues(SVGElement*, const String&, const String&) override
+    {
+        // Values will be set by SVGAnimatedAngleOrientAnimator.
+        ASSERT_NOT_REACHED();
+    }
+
+private:
+    friend class SVGAnimatedAngleOrientAnimator;
+};
+
 class SVGAnimationPreserveAspectRatioFunction : public SVGAnimationDiscreteFunction<SVGPreserveAspectRatioValue> {
 public:
     using Base = SVGAnimationDiscreteFunction<SVGPreserveAspectRatioValue>;
diff --git a/Source/WebCore/svg/properties/SVGAttributeRegistry.h b/Source/WebCore/svg/properties/SVGAttributeRegistry.h
index 042891c..e57ec16 100644
--- a/Source/WebCore/svg/properties/SVGAttributeRegistry.h
+++ b/Source/WebCore/svg/properties/SVGAttributeRegistry.h
@@ -25,7 +25,6 @@
 
 #pragma once
 
-#include "SVGAnimatedEnumeration.h"
 #include "SVGAnimatedLength.h"
 #include "SVGAnimatedLengthList.h"
 #include "SVGAnimatedTransformList.h"
@@ -52,12 +51,6 @@
     }
 
     // Animatable attributes
-    template<const LazyNeverDestroyed<const QualifiedName>& attributeName, typename EnumType, SVGAnimatedEnumerationAttribute<EnumType> OwnerType::*attribute>
-    void registerAttribute()
-    {
-        registerAttribute(SVGAnimatedEnumerationAttributeAccessor<OwnerType, EnumType>::template singleton<attributeName, attribute>());
-    }
-
     template<const LazyNeverDestroyed<const QualifiedName>& attributeName, SVGAnimatedLengthAttribute OwnerType::*attribute>
     void registerAttribute()
     {
diff --git a/Source/WebCore/svg/properties/SVGDecoratedEnumeration.h b/Source/WebCore/svg/properties/SVGDecoratedEnumeration.h
new file mode 100644
index 0000000..264c36b
--- /dev/null
+++ b/Source/WebCore/svg/properties/SVGDecoratedEnumeration.h
@@ -0,0 +1,69 @@
+/*
+ * 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 "SVGDecoratedPrimitive.h"
+
+namespace WebCore {
+
+template<typename DecorationType, typename EnumType>
+class SVGDecoratedEnumeration : public SVGDecoratedPrimitive<DecorationType, EnumType> {
+    using Base = SVGDecoratedPrimitive<DecorationType, EnumType>;
+    using Base::Base;
+    using Base::m_value;
+
+public:
+    static auto create(const EnumType& value)
+    {
+        static_assert(std::is_integral<DecorationType>::value, "DecorationType form enum should be integral.");
+        return std::make_unique<SVGDecoratedEnumeration>(value);
+    }
+
+private:
+    bool setValue(const DecorationType& value) override
+    {
+        if (!value || value > SVGIDLEnumLimits<EnumType>::highestExposedEnumValue())
+            return false;
+        Base::setValueInternal(value);
+        return true;
+    }
+
+    DecorationType value() const override
+    {
+        if (Base::value() > SVGIDLEnumLimits<EnumType>::highestExposedEnumValue())
+            return m_outOfRangeEnumValue;
+        return Base::value();
+    }
+
+    std::unique_ptr<SVGDecoratedProperty<DecorationType>> clone() override
+    {
+        return create(m_value);
+    }
+
+    static const DecorationType m_outOfRangeEnumValue = 0;
+};
+
+}
diff --git a/Source/WebCore/svg/properties/SVGDecoratedPrimitive.h b/Source/WebCore/svg/properties/SVGDecoratedPrimitive.h
new file mode 100644
index 0000000..e2a5243
--- /dev/null
+++ b/Source/WebCore/svg/properties/SVGDecoratedPrimitive.h
@@ -0,0 +1,53 @@
+/*
+ * 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 "SVGDecoratedProperty.h"
+
+namespace WebCore {
+
+template<typename DecorationType, typename PropertyType>
+class SVGDecoratedPrimitive : public SVGDecoratedProperty<DecorationType> {
+    using Base = SVGDecoratedProperty<DecorationType>;
+
+public:
+    SVGDecoratedPrimitive(const PropertyType& value)
+        : m_value(value)
+    {
+    }
+
+protected:
+    using Base::Base;
+
+    void setValueInternal(const DecorationType& value) override { m_value = static_cast<PropertyType>(value); }
+    DecorationType valueInternal() const override { return static_cast<DecorationType>(m_value); }
+
+    String valueAsString() const override { return SVGPropertyTraits<PropertyType>::toString(m_value); }
+
+    PropertyType m_value;
+};
+
+}
diff --git a/Source/WebCore/svg/properties/SVGDecoratedProperty.h b/Source/WebCore/svg/properties/SVGDecoratedProperty.h
new file mode 100644
index 0000000..e4ab037
--- /dev/null
+++ b/Source/WebCore/svg/properties/SVGDecoratedProperty.h
@@ -0,0 +1,53 @@
+/*
+ * 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
+
+namespace WebCore {
+
+template<typename DecorationType>
+class SVGDecoratedProperty {
+public:
+    SVGDecoratedProperty() = default;
+    virtual ~SVGDecoratedProperty() = default;
+
+    virtual void setValueInternal(const DecorationType&) = 0;
+    virtual bool setValue(const DecorationType& value)
+    {
+        setValueInternal(value);
+        return true;
+    }
+
+    // Used internally. It doesn't check for highestExposedEnumValue for example.
+    virtual DecorationType valueInternal() const = 0;
+
+    // Used by the DOM APIs.
+    virtual DecorationType value() const { return valueInternal(); }
+
+    virtual String valueAsString() const = 0;
+    virtual std::unique_ptr<SVGDecoratedProperty<DecorationType>> clone() = 0;
+};
+
+}
diff --git a/Source/WebCore/svg/properties/SVGPropertyOwnerRegistry.h b/Source/WebCore/svg/properties/SVGPropertyOwnerRegistry.h
index 074c652..57f7985 100644
--- a/Source/WebCore/svg/properties/SVGPropertyOwnerRegistry.h
+++ b/Source/WebCore/svg/properties/SVGPropertyOwnerRegistry.h
@@ -55,6 +55,12 @@
         registerProperty(attributeName, SVGAnimatedBooleanAccessor<OwnerType>::template singleton<property>());
     }
 
+    template<const LazyNeverDestroyed<const QualifiedName>& attributeName, typename EnumType, Ref<SVGAnimatedEnumeration> OwnerType::*property>
+    static void registerProperty()
+    {
+        registerProperty(attributeName, SVGAnimatedEnumerationAccessor<OwnerType, EnumType>::template singleton<property>());
+    }
+
     template<const LazyNeverDestroyed<const QualifiedName>& attributeName, Ref<SVGAnimatedInteger> OwnerType::*property>
     static void registerProperty()
     {
@@ -73,6 +79,12 @@
         registerProperty(attributeName, SVGAnimatedNumberListAccessor<OwnerType>::template singleton<property>());
     }
 
+    template<const LazyNeverDestroyed<const QualifiedName>& attributeName, Ref<SVGAnimatedAngle> OwnerType::*property1, Ref<SVGAnimatedOrientType> OwnerType::*property2>
+    static void registerProperty()
+    {
+        registerProperty(attributeName, SVGAnimatedAngleOrientAccessor<OwnerType>::template singleton<property1, property2>());
+    }
+
     template<const LazyNeverDestroyed<const QualifiedName>& attributeName, Ref<SVGAnimatedPointList> OwnerType::*property>
     static void registerProperty()
     {
@@ -127,6 +139,15 @@
         return findAccessor(attributeName);
     }
 
+    // Returns true if OwnerType owns a property whose name is attributeName
+    // and its type is SVGAnimatedLength.
+    static bool isAnimatedLengthAttribute(const QualifiedName& attributeName)
+    {
+        if (const auto* accessor = findAccessor(attributeName))
+            return accessor->isAnimatedLength();
+        return false;
+    }
+
     QualifiedName propertyAttributeName(const SVGProperty& property) const override
     {
         QualifiedName attributeName = nullQName();
@@ -199,6 +220,22 @@
         return isAnimatedPropertyAttribute;
     }
 
+    bool isAnimatedStylePropertyAttribute(const QualifiedName& attributeName) const override
+    {
+        static NeverDestroyed<HashSet<QualifiedName::QualifiedNameImpl*>> animatedStyleAttributes = std::initializer_list<QualifiedName::QualifiedNameImpl*> {
+            SVGNames::cxAttr->impl(),
+            SVGNames::cyAttr->impl(),
+            SVGNames::rAttr->impl(),
+            SVGNames::rxAttr->impl(),
+            SVGNames::ryAttr->impl(),
+            SVGNames::heightAttr->impl(),
+            SVGNames::widthAttr->impl(),
+            SVGNames::xAttr->impl(),
+            SVGNames::yAttr->impl()
+        };
+        return isAnimatedLengthAttribute(attributeName) && animatedStyleAttributes.get().contains(attributeName.impl());
+    }
+
     std::unique_ptr<SVGAttributeAnimator> createAnimator(const QualifiedName& attributeName, AnimationMode animationMode, CalcMode calcMode, bool isAccumulated, bool isAdditive) const override
     {
         std::unique_ptr<SVGAttributeAnimator> animator;
diff --git a/Source/WebCore/svg/properties/SVGPropertyRegistry.h b/Source/WebCore/svg/properties/SVGPropertyRegistry.h
index 53a0345..92f7ab0 100644
--- a/Source/WebCore/svg/properties/SVGPropertyRegistry.h
+++ b/Source/WebCore/svg/properties/SVGPropertyRegistry.h
@@ -43,6 +43,7 @@
     virtual HashMap<QualifiedName, String> synchronizeAllAttributes() const = 0;
 
     virtual bool isAnimatedPropertyAttribute(const QualifiedName&) const = 0;
+    virtual bool isAnimatedStylePropertyAttribute(const QualifiedName&) const = 0;
     virtual std::unique_ptr<SVGAttributeAnimator> createAnimator(const QualifiedName&, AnimationMode, CalcMode, bool isAccumulated, bool isAdditive) const = 0;
     virtual void appendAnimatedInstance(const QualifiedName& attributeName, SVGAttributeAnimator&) const = 0;
 };
diff --git a/Source/WebCore/svg/properties/SVGStaticPropertyTearOff.h b/Source/WebCore/svg/properties/SVGStaticPropertyTearOff.h
deleted file mode 100644
index 5e2ca09..0000000
--- a/Source/WebCore/svg/properties/SVGStaticPropertyTearOff.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010. 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
-
-namespace WebCore {
-
-#if COMPILER(MSVC)
-// UpdateMethod is 12 bytes. We have to pack to a size greater than or equal to that to avoid an
-// alignment warning (C4121). 16 is the next-largest size allowed for packing, so we use that.
-#pragma pack(push, 16)
-#endif
-template<typename ContextElement, typename PropertyTearOff>
-class SVGStaticPropertyTearOff final : public PropertyTearOff {
-public:
-    using Self = SVGStaticPropertyTearOff<ContextElement, PropertyTearOff>;
-    using PropertyType = typename PropertyTearOff::PropertyType;
-
-    typedef void (ContextElement::*UpdateMethod)();
-
-    // Used for non-animated POD types that are not associated with a SVGAnimatedProperty object, nor with a XML DOM attribute
-    // (for example: SVGSVGElement::currentTranslate).
-    static Ref<Self> create(ContextElement& contextElement, PropertyType& value, UpdateMethod update)
-    {
-        return adoptRef(*new Self(contextElement, value, update));
-    }
-
-    void commitChange() final { (m_contextElement.get()->*m_update)(); }
-
-private:
-    SVGStaticPropertyTearOff(ContextElement& contextElement, PropertyType& value, UpdateMethod update)
-        : PropertyTearOff(UndefinedRole, value)
-        , m_update(update)
-        , m_contextElement(&contextElement)
-    {
-    }
-
-    UpdateMethod m_update;
-    RefPtr<ContextElement> m_contextElement;
-};
-#if COMPILER(MSVC)
-#pragma pack(pop)
-#endif
-
-} // namespace WebCore