Remove the SVG tear off objects for SVGLength, SVGLengthList and SVGAnimatedLengthList
authorsaid@apple.com <said@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 26 Mar 2019 20:14:32 +0000 (20:14 +0000)
committersaid@apple.com <said@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 26 Mar 2019 20:14:32 +0000 (20:14 +0000)
https://bugs.webkit.org/show_bug.cgi?id=196083

Reviewed by Simon Fraser.

Source/WebCore:

-- SVGLength will be a superclass of SVGValueProperty<SVGLengthValue>. It
   is a wrapper of SVGLengthValue. It will be provide the DOM methods. It
   can setValueAsString() and return valueAsString().

-- SVGLengthList will be a superclass of SVGValuePropertyList<SVGLength>.
   The base class will provide all the DOM methods. SVGLengthList will be
   responsible for parsing a String to a SVGLength items. It can also
   build a string representing the stored items.

-- SVGAnimatedLengthList will be defined as SVGAnimatedPropertyList<SVGLengthList>.
   Like SVGAnimatedPointList, all the required methods and attributes
   will be handled by SVGAnimatedPropertyList.

-- SVGAnimatedLengthAccessor and SVGAnimatedLengthListAccessor will be
   added to access the members of types SVGAnimatedLength and
   SVGAnimatedLengthList.

-- SVGAnimatedLengthAnimator and SVGAnimatedLengthListAnimator will be
   created by the the new accessors to animate attributes of types
   SVGAnimatedLength and SVGAnimatedLengthList.

-- SVGAnimationLengthFunction and SVGAnimationLengthListFunction will be
   responsible for progressing the animVal() of attributes of types
   SVGAnimatedLength and SVGAnimatedLengthList.

-- SVGValuePropertyAnimator is a new template class which can animate a
   none reflecting attribute which should be backed by a value property,
   e.g. SVGLength.

-- SVGValuePropertyListAnimator is a new template class which can animate a
   none reflecting attribute which should be backed by a value property
   list, e.g. SVGLengthList.

Notes:

    -- SVGElement::isAnimatedStyleAttribute() will return true if the
       attribute is known by SVGPropertyAnimatorFactory. Or it's has
       a reflecting SVGAnimatedPropertyLength property and its name is
       one of the names listed in isAnimatedStylePropertyAttribute() of
       the propertyRegistry() of the SVGElement.

    -- SVGElement::commitPropertyChange() has to handle the attributes
       for which isAnimatedStylePropertyAttribute() returns true different
       from the other ones. styleReclac() needs updated attributes since
       it does not access the reflecting properties in the SVGELement.

    -- SVGTextContentElement does not need a customized SVGAnimatedLength.
       All SVGTextContentElement::textLengthAnimated() needs to know is
       whether m_textLength->baseVal() holds an empty SVGLength. If it
       does, it sets its value to getComputedTextLength().

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* rendering/svg/SVGTextLayoutAttributesBuilder.cpp:
(WebCore::updateCharacterData):
(WebCore::SVGTextLayoutAttributesBuilder::fillCharacterDataMap):
* svg/SVGAnimateElementBase.cpp:
(WebCore::SVGAnimateElementBase::hasValidAttributeType const):
* svg/SVGAnimatedLength.cpp: Removed.
* svg/SVGAnimatedLength.h: Removed.
* svg/SVGAnimatedLengthList.cpp: Removed.
* svg/SVGAnimatedLengthList.h: Removed.
* svg/SVGAnimatedType.h:
(WebCore::SVGAnimatedType::type const):
* svg/SVGAnimationElement.cpp:
(WebCore::SVGAnimationElement::isTargetAttributeCSSProperty):
(WebCore::inheritsFromProperty):
* svg/SVGAnimatorFactory.h:
(WebCore::SVGAnimatorFactory::isSupportedAttribute):
(WebCore::SVGAnimatorFactory::create):
These changes were required because some of the tests were trying to
animated unsupported attributes. To differentiate between between the
these two cases:
    1) the attribute is animate-able by the legacy controller.
    2) animating the attribute or the attribute itself is not supported
       by the element.

We want SVGAnimatorFactory tell us whether it can create an animator for
a given attribute or not.

* svg/SVGCircleElement.cpp:
(WebCore::SVGCircleElement::SVGCircleElement):
(WebCore::SVGCircleElement::parseAttribute):
(WebCore::SVGCircleElement::svgAttributeChanged):
(WebCore::SVGCircleElement::registerAttributes): Deleted.
* svg/SVGCircleElement.h:
* svg/SVGCursorElement.cpp:
(WebCore::SVGCursorElement::SVGCursorElement):
(WebCore::SVGCursorElement::parseAttribute):
(WebCore::SVGCursorElement::svgAttributeChanged):
(WebCore::SVGCursorElement::registerAttributes): Deleted.
* svg/SVGCursorElement.h:
* svg/SVGElement.cpp:
(WebCore::SVGElement::commitPropertyChange):
(WebCore::SVGElement::isAnimatedStyleAttribute const):
* svg/SVGElement.h:
* svg/SVGEllipseElement.cpp:
(WebCore::SVGEllipseElement::SVGEllipseElement):
(WebCore::SVGEllipseElement::parseAttribute):
(WebCore::SVGEllipseElement::svgAttributeChanged):
(WebCore::SVGEllipseElement::registerAttributes): Deleted.
* svg/SVGEllipseElement.h:
* svg/SVGFilterElement.cpp:
(WebCore::SVGFilterElement::SVGFilterElement):
(WebCore::SVGFilterElement::registerAttributes):
(WebCore::SVGFilterElement::parseAttribute):
* svg/SVGFilterElement.h:
* svg/SVGFilterPrimitiveStandardAttributes.cpp:
(WebCore::SVGFilterPrimitiveStandardAttributes::SVGFilterPrimitiveStandardAttributes):
(WebCore::SVGFilterPrimitiveStandardAttributes::parseAttribute):
(WebCore::SVGFilterPrimitiveStandardAttributes::registerAttributes): Deleted.
* svg/SVGFilterPrimitiveStandardAttributes.h:
(WebCore::SVGFilterPrimitiveStandardAttributes::x const):
(WebCore::SVGFilterPrimitiveStandardAttributes::y const):
(WebCore::SVGFilterPrimitiveStandardAttributes::width const):
(WebCore::SVGFilterPrimitiveStandardAttributes::height const):
(WebCore::SVGFilterPrimitiveStandardAttributes::xAnimated):
(WebCore::SVGFilterPrimitiveStandardAttributes::yAnimated):
(WebCore::SVGFilterPrimitiveStandardAttributes::widthAnimated):
(WebCore::SVGFilterPrimitiveStandardAttributes::heightAnimated):
(WebCore::SVGFilterPrimitiveStandardAttributes::isKnownAttribute): Deleted.
* svg/SVGForeignObjectElement.cpp:
(WebCore::SVGForeignObjectElement::SVGForeignObjectElement):
(WebCore::SVGForeignObjectElement::parseAttribute):
(WebCore::SVGForeignObjectElement::registerAttributes): Deleted.
* svg/SVGForeignObjectElement.h:
* svg/SVGImageElement.cpp:
(WebCore::SVGImageElement::SVGImageElement):
(WebCore::SVGImageElement::parseAttribute):
(WebCore::SVGImageElement::registerAttributes): Deleted.
* svg/SVGImageElement.h:
* svg/SVGLength.h:
(WebCore::SVGLength::create):
(WebCore::SVGLength::clone const):
(WebCore::SVGLength::unitType):
(WebCore::SVGLength::valueForBindings):
(WebCore::SVGLength::setValueForBindings):
(WebCore::SVGLength::valueInSpecifiedUnits):
(WebCore::SVGLength::setValueInSpecifiedUnits):
(WebCore::SVGLength::setValueAsString):
(WebCore::SVGLength::newValueSpecifiedUnits):
(WebCore::SVGLength::convertToSpecifiedUnits):
(WebCore::SVGLength::valueAsString): Deleted.
(WebCore::SVGLength::SVGLength): Deleted.
* svg/SVGLengthList.h:
(WebCore::SVGLengthList::create):
(WebCore::SVGLengthList::lengthMode const):
(WebCore::SVGLengthList::parse):
(WebCore::SVGLengthList::SVGLengthList):
* svg/SVGLengthListValues.cpp: Removed.
* svg/SVGLengthListValues.h: Removed.
* svg/SVGLineElement.cpp:
(WebCore::SVGLineElement::SVGLineElement):
(WebCore::SVGLineElement::parseAttribute):
(WebCore::SVGLineElement::svgAttributeChanged):
(WebCore::SVGLineElement::registerAttributes): Deleted.
* svg/SVGLineElement.h:
* svg/SVGLinearGradientElement.cpp:
(WebCore::SVGLinearGradientElement::SVGLinearGradientElement):
(WebCore::SVGLinearGradientElement::parseAttribute):
(WebCore::SVGLinearGradientElement::svgAttributeChanged):
(WebCore::SVGLinearGradientElement::registerAttributes): Deleted.
* svg/SVGLinearGradientElement.h:
* svg/SVGMarkerElement.cpp:
(WebCore::SVGMarkerElement::SVGMarkerElement):
(WebCore::SVGMarkerElement::registerAttributes):
(WebCore::SVGMarkerElement::parseAttribute):
* svg/SVGMarkerElement.h:
* svg/SVGMaskElement.cpp:
(WebCore::SVGMaskElement::SVGMaskElement):
(WebCore::SVGMaskElement::registerAttributes):
(WebCore::SVGMaskElement::parseAttribute):
(WebCore::SVGMaskElement::svgAttributeChanged):
* svg/SVGMaskElement.h:
* svg/SVGPatternElement.cpp:
(WebCore::SVGPatternElement::SVGPatternElement):
(WebCore::SVGPatternElement::registerAttributes):
(WebCore::SVGPatternElement::parseAttribute):
* svg/SVGPatternElement.h:
* svg/SVGPoint.h:
* svg/SVGRadialGradientElement.cpp:
(WebCore::SVGRadialGradientElement::SVGRadialGradientElement):
(WebCore::SVGRadialGradientElement::parseAttribute):
(WebCore::SVGRadialGradientElement::svgAttributeChanged):
(WebCore::SVGRadialGradientElement::registerAttributes): Deleted.
* svg/SVGRadialGradientElement.h:
* svg/SVGRectElement.cpp:
(WebCore::SVGRectElement::SVGRectElement):
(WebCore::SVGRectElement::parseAttribute):
(WebCore::SVGRectElement::svgAttributeChanged):
(WebCore::SVGRectElement::registerAttributes): Deleted.
* svg/SVGRectElement.h:
* svg/SVGSVGElement.cpp:
(WebCore::SVGSVGElement::SVGSVGElement):
(WebCore::SVGSVGElement::parseAttribute):
(WebCore::SVGSVGElement::svgAttributeChanged):
(WebCore::SVGSVGElement::registerAttributes): Deleted.
* svg/SVGSVGElement.h:
* svg/SVGTextContentElement.cpp:
(WebCore::SVGTextContentElement::SVGTextContentElement):
(WebCore::SVGTextContentElement::registerAttributes):
(WebCore::SVGTextContentElement::parseAttribute):
(WebCore::SVGTextContentElement::svgAttributeChanged):
(WebCore::SVGTextContentElement::textLengthAnimated):
* svg/SVGTextContentElement.h:
(WebCore::SVGTextContentElement::specifiedTextLength const):
(WebCore::SVGTextContentElement::textLength const):
(WebCore::SVGTextContentElement::specifiedTextLength): Deleted.
(WebCore::SVGTextContentElement::textLengthAnimated): Deleted.
(WebCore::SVGTextContentElement::SVGAnimatedCustomLengthAttribute::SVGAnimatedCustomLengthAttribute): Deleted.
(WebCore::SVGTextContentElement::SVGAnimatedCustomLengthAttribute::synchronize): Deleted.
(WebCore::SVGTextContentElement::SVGAnimatedCustomLengthAttribute::animatedProperty): Deleted.
* svg/SVGTextPathElement.cpp:
(WebCore::SVGTextPathElement::SVGTextPathElement):
(WebCore::SVGTextPathElement::registerAttributes):
(WebCore::SVGTextPathElement::parseAttribute):
* svg/SVGTextPathElement.h:
* svg/SVGTextPositioningElement.cpp:
(WebCore::SVGTextPositioningElement::SVGTextPositioningElement):
(WebCore::SVGTextPositioningElement::parseAttribute):
(WebCore::SVGTextPositioningElement::svgAttributeChanged):
(WebCore::SVGTextPositioningElement::registerAttributes): Deleted.
* svg/SVGTextPositioningElement.h:
(WebCore::SVGTextPositioningElement::x const):
(WebCore::SVGTextPositioningElement::y const):
(WebCore::SVGTextPositioningElement::dx const):
(WebCore::SVGTextPositioningElement::dy const):
(WebCore::SVGTextPositioningElement::xAnimated):
(WebCore::SVGTextPositioningElement::yAnimated):
(WebCore::SVGTextPositioningElement::dxAnimated):
(WebCore::SVGTextPositioningElement::dyAnimated):
(WebCore::SVGTextPositioningElement::isKnownAttribute): Deleted.
* svg/SVGUseElement.cpp:
(WebCore::SVGUseElement::SVGUseElement):
(WebCore::SVGUseElement::parseAttribute):
(WebCore::SVGUseElement::svgAttributeChanged):
(WebCore::SVGUseElement::registerAttributes): Deleted.
* svg/SVGUseElement.h:
* svg/SVGValue.h:
* svg/properties/SVGAnimatedPropertyAccessorImpl.h:
* svg/properties/SVGAnimatedPropertyAnimator.h:
* svg/properties/SVGAnimatedPropertyAnimatorImpl.h:
* svg/properties/SVGAnimatedPropertyImpl.h:
* svg/properties/SVGAnimationAdditiveListFunctionImpl.h:
(WebCore::SVGAnimationLengthListFunction::SVGAnimationLengthListFunction):
(WebCore::SVGAnimationLengthListFunction::progress):
(WebCore::SVGAnimationNumberListFunction::progress):
(WebCore::SVGAnimationPointListFunction::progress):
* svg/properties/SVGAnimationAdditiveValueFunctionImpl.h:
(WebCore::SVGAnimationLengthFunction::SVGAnimationLengthFunction):
(WebCore::SVGAnimationLengthFunction::progress):
* svg/properties/SVGAttributeAnimator.cpp:
(WebCore::SVGAttributeAnimator::isAnimatedStylePropertyAniamtor const):
* svg/properties/SVGAttributeAnimator.h:
* svg/properties/SVGAttributeRegistry.h:
* svg/properties/SVGPropertyAnimatorFactory.h:
(WebCore::SVGPropertyAnimatorFactory::createLengthAnimator):
(WebCore::SVGPropertyAnimatorFactory::createLengthListAnimator):
(WebCore::SVGPropertyAnimatorFactory::attributeAnimatorCreator):
* svg/properties/SVGPropertyOwnerRegistry.h:
(WebCore::SVGPropertyOwnerRegistry::registerProperty):
(WebCore::SVGPropertyOwnerRegistry::isAnimatedLengthAttribute):
* svg/properties/SVGPropertyRegistry.h:
* svg/properties/SVGValuePropertyAnimator.h: Added.
(WebCore::SVGValuePropertyAnimator::SVGValuePropertyAnimator):
* svg/properties/SVGValuePropertyAnimatorImpl.h: Added.
* svg/properties/SVGValuePropertyListAnimator.h: Added.
(WebCore::SVGValuePropertyListAnimator::SVGValuePropertyListAnimator):
* svg/properties/SVGValuePropertyListAnimatorImpl.h: Added.

LayoutTests:

* platform/win/TestExpectations:
* svg/animations/svglength-element-removed-crash.svg:
* svg/dom/SVGLengthList-appendItem-expected.txt:
* svg/dom/SVGLengthList-appendItem.xhtml:
* svg/dom/SVGLengthList-basics-expected.txt:
* svg/dom/SVGLengthList-basics.xhtml:
* svg/dom/SVGLengthList-initialize-expected.txt:
* svg/dom/SVGLengthList-initialize.xhtml:
* svg/dom/SVGLengthList-insertItemBefore-expected.txt:
* svg/dom/SVGLengthList-insertItemBefore.xhtml:
* svg/dom/SVGLengthList-removeItem-expected.txt:
* svg/dom/SVGLengthList-removeItem.xhtml:
* svg/dom/SVGLengthList-replaceItem-expected.txt:
* svg/dom/SVGLengthList-replaceItem.xhtml:
This changes are required because SVGLengthList will be following the SVG2
specs regarding adding new items to the list.

See https://www.w3.org/TR/SVG/types.html#TermListInterface.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@243515 268f45cc-cd09-0410-ab3c-d52691b4dbfc

88 files changed:
LayoutTests/ChangeLog
LayoutTests/platform/win/TestExpectations
LayoutTests/svg/animations/svglength-element-removed-crash.svg
LayoutTests/svg/dom/SVGLengthList-appendItem-expected.txt
LayoutTests/svg/dom/SVGLengthList-appendItem.xhtml
LayoutTests/svg/dom/SVGLengthList-basics-expected.txt
LayoutTests/svg/dom/SVGLengthList-basics.xhtml
LayoutTests/svg/dom/SVGLengthList-initialize-expected.txt
LayoutTests/svg/dom/SVGLengthList-initialize.xhtml
LayoutTests/svg/dom/SVGLengthList-insertItemBefore-expected.txt
LayoutTests/svg/dom/SVGLengthList-insertItemBefore.xhtml
LayoutTests/svg/dom/SVGLengthList-removeItem-expected.txt
LayoutTests/svg/dom/SVGLengthList-removeItem.xhtml
LayoutTests/svg/dom/SVGLengthList-replaceItem-expected.txt
LayoutTests/svg/dom/SVGLengthList-replaceItem.xhtml
Source/WebCore/ChangeLog
Source/WebCore/Sources.txt
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.cpp
Source/WebCore/svg/SVGAnimateElementBase.cpp
Source/WebCore/svg/SVGAnimatedLength.cpp [deleted file]
Source/WebCore/svg/SVGAnimatedLength.h [deleted file]
Source/WebCore/svg/SVGAnimatedLengthList.cpp [deleted file]
Source/WebCore/svg/SVGAnimatedLengthList.h [deleted file]
Source/WebCore/svg/SVGAnimatedType.h
Source/WebCore/svg/SVGAnimationElement.cpp
Source/WebCore/svg/SVGAnimatorFactory.h
Source/WebCore/svg/SVGCircleElement.cpp
Source/WebCore/svg/SVGCircleElement.h
Source/WebCore/svg/SVGCursorElement.cpp
Source/WebCore/svg/SVGCursorElement.h
Source/WebCore/svg/SVGElement.cpp
Source/WebCore/svg/SVGElement.h
Source/WebCore/svg/SVGEllipseElement.cpp
Source/WebCore/svg/SVGEllipseElement.h
Source/WebCore/svg/SVGFilterElement.cpp
Source/WebCore/svg/SVGFilterElement.h
Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp
Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h
Source/WebCore/svg/SVGForeignObjectElement.cpp
Source/WebCore/svg/SVGForeignObjectElement.h
Source/WebCore/svg/SVGImageElement.cpp
Source/WebCore/svg/SVGImageElement.h
Source/WebCore/svg/SVGLength.h
Source/WebCore/svg/SVGLengthList.h
Source/WebCore/svg/SVGLengthListValues.cpp [deleted file]
Source/WebCore/svg/SVGLengthListValues.h [deleted file]
Source/WebCore/svg/SVGLineElement.cpp
Source/WebCore/svg/SVGLineElement.h
Source/WebCore/svg/SVGLinearGradientElement.cpp
Source/WebCore/svg/SVGLinearGradientElement.h
Source/WebCore/svg/SVGMarkerElement.cpp
Source/WebCore/svg/SVGMarkerElement.h
Source/WebCore/svg/SVGMaskElement.cpp
Source/WebCore/svg/SVGMaskElement.h
Source/WebCore/svg/SVGPatternElement.cpp
Source/WebCore/svg/SVGPatternElement.h
Source/WebCore/svg/SVGPoint.h
Source/WebCore/svg/SVGRadialGradientElement.cpp
Source/WebCore/svg/SVGRadialGradientElement.h
Source/WebCore/svg/SVGRectElement.cpp
Source/WebCore/svg/SVGRectElement.h
Source/WebCore/svg/SVGSVGElement.cpp
Source/WebCore/svg/SVGSVGElement.h
Source/WebCore/svg/SVGTextContentElement.cpp
Source/WebCore/svg/SVGTextContentElement.h
Source/WebCore/svg/SVGTextPathElement.cpp
Source/WebCore/svg/SVGTextPathElement.h
Source/WebCore/svg/SVGTextPositioningElement.cpp
Source/WebCore/svg/SVGTextPositioningElement.h
Source/WebCore/svg/SVGUseElement.cpp
Source/WebCore/svg/SVGUseElement.h
Source/WebCore/svg/SVGValue.h
Source/WebCore/svg/properties/SVGAnimatedPropertyAccessorImpl.h
Source/WebCore/svg/properties/SVGAnimatedPropertyAnimator.h
Source/WebCore/svg/properties/SVGAnimatedPropertyAnimatorImpl.h
Source/WebCore/svg/properties/SVGAnimatedPropertyImpl.h
Source/WebCore/svg/properties/SVGAnimationAdditiveListFunctionImpl.h
Source/WebCore/svg/properties/SVGAnimationAdditiveValueFunctionImpl.h
Source/WebCore/svg/properties/SVGAttributeAnimator.cpp
Source/WebCore/svg/properties/SVGAttributeAnimator.h
Source/WebCore/svg/properties/SVGAttributeRegistry.h
Source/WebCore/svg/properties/SVGPropertyAnimatorFactory.h
Source/WebCore/svg/properties/SVGPropertyOwnerRegistry.h
Source/WebCore/svg/properties/SVGValuePropertyAnimator.h [new file with mode: 0644]
Source/WebCore/svg/properties/SVGValuePropertyAnimatorImpl.h [new file with mode: 0644]
Source/WebCore/svg/properties/SVGValuePropertyListAnimator.h [new file with mode: 0644]
Source/WebCore/svg/properties/SVGValuePropertyListAnimatorImpl.h [new file with mode: 0644]

index 01c1f07..69c91be 100644 (file)
@@ -1,3 +1,29 @@
+2019-03-26  Said Abou-Hallawa  <said@apple.com>
+
+        Remove the SVG tear off objects for SVGLength, SVGLengthList and SVGAnimatedLengthList
+        https://bugs.webkit.org/show_bug.cgi?id=196083
+
+        Reviewed by Simon Fraser.
+
+        * platform/win/TestExpectations:
+        * svg/animations/svglength-element-removed-crash.svg:
+        * svg/dom/SVGLengthList-appendItem-expected.txt:
+        * svg/dom/SVGLengthList-appendItem.xhtml:
+        * svg/dom/SVGLengthList-basics-expected.txt:
+        * svg/dom/SVGLengthList-basics.xhtml:
+        * svg/dom/SVGLengthList-initialize-expected.txt:
+        * svg/dom/SVGLengthList-initialize.xhtml:
+        * svg/dom/SVGLengthList-insertItemBefore-expected.txt:
+        * svg/dom/SVGLengthList-insertItemBefore.xhtml:
+        * svg/dom/SVGLengthList-removeItem-expected.txt:
+        * svg/dom/SVGLengthList-removeItem.xhtml:
+        * svg/dom/SVGLengthList-replaceItem-expected.txt:
+        * svg/dom/SVGLengthList-replaceItem.xhtml:
+        This changes are required because SVGLengthList will be following the SVG2
+        specs regarding adding new items to the list. 
+
+        See https://www.w3.org/TR/SVG/types.html#TermListInterface.
+
 2019-03-26  Simon Fraser  <simon.fraser@apple.com>
 
         [iOS WK2] position:fixed inside oveflow:scroll is jumpy
index d16f6e1..be74e6c 100644 (file)
@@ -1954,6 +1954,9 @@ imported/mozilla/svg/svg-effects-area-zoomed-in.xhtml
 imported/mozilla/svg/svg-effects-area-zoomed-out.xhtml
 svg/filters/feImage-self-and-other-referencing.html
 
+# GCController.collect() issues.
+svg/animations/svglength-element-removed-crash.svg [ Failure ]
+
 ################################################################################
 ###################          End SVG Issues              #######################
 ################################################################################
index 511cd63..b132c76 100644 (file)
@@ -32,8 +32,8 @@ function load() {
     // The rest of this test should FAIL without requiring gmalloc if this test has regressed.
     var liveDelta = window.internals.numberOfLiveNodes() - originalLiveElements;
     
-    // Make sure that the <rect> is still alive; if it's not, liveDelta will be -1.
-    if (liveDelta == 0)
+    // Make sure that the <rect> is deleted; if it's not, liveDelta will be 0.
+    if (liveDelta == -1)
         log(" PASS");
     else
         log(" FAIL: " + liveDelta + " extra live node(s)");
index d45a994..e6a69d9 100644 (file)
@@ -27,7 +27,8 @@ PASS text2.x.baseVal.getItem(2).value is 1000
 PASS text2.x.baseVal.getItem(3) threw exception IndexSizeError: The index is not in the allowed range..
 
 Append fourth item x=900 to the text1 x list
-PASS text1.x.baseVal.appendItem(text1.x.baseVal.getItem(3)) is text1.x.baseVal.getItem(4)
+PASS text1.x.baseVal.appendItem(text1.x.baseVal.getItem(3)) is text1.x.baseVal.getItem(5)
+PASS text1.x.baseVal.removeItem(3).toString() is "[object SVGLength]"
 PASS text1.x.baseVal.numberOfItems is 5
 PASS text1.x.baseVal.getItem(0).value is 500
 PASS text1.x.baseVal.getItem(1).value is 50
@@ -37,7 +38,8 @@ PASS text1.x.baseVal.getItem(4).value is 900
 PASS text1.x.baseVal.getItem(5) threw exception IndexSizeError: The index is not in the allowed range..
 
 Append first item x=500 to the text1 x list
-PASS text1.x.baseVal.appendItem(text1.x.baseVal.getItem(0)) is text1.x.baseVal.getItem(4)
+PASS text1.x.baseVal.appendItem(text1.x.baseVal.getItem(0)) is text1.x.baseVal.getItem(5)
+PASS text1.x.baseVal.removeItem(0).toString() is "[object SVGLength]"
 PASS text1.x.baseVal.numberOfItems is 5
 PASS text1.x.baseVal.getItem(0).value is 50
 PASS text1.x.baseVal.getItem(1).value is 100
@@ -59,7 +61,9 @@ PASS text1.x.baseVal.getItem(6) threw exception IndexSizeError: The index is not
 
 Append third and fourth item of the text1 x list to the text2 x list
 PASS text2.x.baseVal.appendItem(text1.x.baseVal.getItem(2)).value is 1000
+PASS text1.x.baseVal.removeItem(2).toString() is "[object SVGLength]"
 PASS text2.x.baseVal.appendItem(text1.x.baseVal.getItem(2)).value is 900
+PASS text1.x.baseVal.removeItem(2).toString() is "[object SVGLength]"
 PASS text1.x.baseVal.numberOfItems is 4
 PASS text1.x.baseVal.getItem(0).value is 50
 PASS text1.x.baseVal.getItem(1).value is 100
@@ -77,10 +81,14 @@ PASS newLength2.value is 150
 
 Shuffle around items in text1 and text2 list using appendItem, to get x=50,100,150,... in both lists
 PASS text1.x.baseVal.appendItem(text1.x.baseVal.getItem(2)).value is 500
+PASS text1.x.baseVal.removeItem(2).toString() is "[object SVGLength]"
 PASS text2.x.baseVal.appendItem(newLength2).value is 150
 PASS text2.x.baseVal.appendItem(text2.x.baseVal.getItem(2)).value is 1000
+PASS text2.x.baseVal.removeItem(2).toString() is "[object SVGLength]"
 PASS text2.x.baseVal.appendItem(text2.x.baseVal.getItem(3)).value is 900
+PASS text2.x.baseVal.removeItem(3).toString() is "[object SVGLength]"
 PASS text2.x.baseVal.appendItem(text2.x.baseVal.getItem(2)).value is 1000
+PASS text2.x.baseVal.removeItem(2).toString() is "[object SVGLength]"
 PASS text1.x.baseVal.numberOfItems is 4
 PASS text1.x.baseVal.getItem(0).value is 50
 PASS text1.x.baseVal.getItem(1).value is 100
index 49ec802..eb54b95 100644 (file)
@@ -46,7 +46,8 @@
 
     debug("");
     debug("Append fourth item x=900 to the text1 x list");
-    shouldBe("text1.x.baseVal.appendItem(text1.x.baseVal.getItem(3))", "text1.x.baseVal.getItem(4)");
+    shouldBe("text1.x.baseVal.appendItem(text1.x.baseVal.getItem(3))", "text1.x.baseVal.getItem(5)");
+    shouldBeEqualToString("text1.x.baseVal.removeItem(3).toString()", "[object SVGLength]");
     shouldBe("text1.x.baseVal.numberOfItems", "5");
     shouldBe("text1.x.baseVal.getItem(0).value", "500");
     shouldBe("text1.x.baseVal.getItem(1).value", "50");
@@ -57,7 +58,8 @@
 
     debug("");
     debug("Append first item x=500 to the text1 x list");
-    shouldBe("text1.x.baseVal.appendItem(text1.x.baseVal.getItem(0))", "text1.x.baseVal.getItem(4)");
+    shouldBe("text1.x.baseVal.appendItem(text1.x.baseVal.getItem(0))", "text1.x.baseVal.getItem(5)");
+    shouldBeEqualToString("text1.x.baseVal.removeItem(0).toString()", "[object SVGLength]");
     shouldBe("text1.x.baseVal.numberOfItems", "5");
     shouldBe("text1.x.baseVal.getItem(0).value", "50");
     shouldBe("text1.x.baseVal.getItem(1).value", "100");
@@ -81,7 +83,9 @@
     debug("");
     debug("Append third and fourth item of the text1 x list to the text2 x list");
     shouldBe("text2.x.baseVal.appendItem(text1.x.baseVal.getItem(2)).value", "1000");
+    shouldBeEqualToString("text1.x.baseVal.removeItem(2).toString()", "[object SVGLength]");
     shouldBe("text2.x.baseVal.appendItem(text1.x.baseVal.getItem(2)).value", "900");
+    shouldBeEqualToString("text1.x.baseVal.removeItem(2).toString()", "[object SVGLength]");
     shouldBe("text1.x.baseVal.numberOfItems", "4");
     shouldBe("text1.x.baseVal.getItem(0).value", "50");
     shouldBe("text1.x.baseVal.getItem(1).value", "100");
     debug("");
     debug("Shuffle around items in text1 and text2 list using appendItem, to get x=50,100,150,... in both lists");
     shouldBe("text1.x.baseVal.appendItem(text1.x.baseVal.getItem(2)).value", "500");
+    shouldBeEqualToString("text1.x.baseVal.removeItem(2).toString()", "[object SVGLength]");
     shouldBe("text2.x.baseVal.appendItem(newLength2).value", "150");
     shouldBe("text2.x.baseVal.appendItem(text2.x.baseVal.getItem(2)).value", "1000");
+    shouldBeEqualToString("text2.x.baseVal.removeItem(2).toString()", "[object SVGLength]");
     shouldBe("text2.x.baseVal.appendItem(text2.x.baseVal.getItem(3)).value", "900");
+    shouldBeEqualToString("text2.x.baseVal.removeItem(3).toString()", "[object SVGLength]");
     shouldBe("text2.x.baseVal.appendItem(text2.x.baseVal.getItem(2)).value", "1000");
+    shouldBeEqualToString("text2.x.baseVal.removeItem(2).toString()", "[object SVGLength]");
     shouldBe("text1.x.baseVal.numberOfItems", "4");
     shouldBe("text1.x.baseVal.getItem(0).value", "50");
     shouldBe("text1.x.baseVal.getItem(1).value", "100");
index 70256c8..aff90b2 100644 (file)
@@ -29,24 +29,28 @@ PASS text1.x.baseVal.insertItemBefore('aString') threw exception TypeError: Not
 PASS text1.x.baseVal.insertItemBefore(text1) threw exception TypeError: Not enough arguments.
 PASS text1.x.baseVal.insertItemBefore(null) threw exception TypeError: Not enough arguments.
 PASS text1.x.baseVal.insertItemBefore(text1.x.baseVal.getItem(1), 'aString') is text1.x.baseVal.getItem(0)
+PASS text1.x.baseVal.removeItem(2).toString() is "[object SVGLength]"
 PASS text1.x.baseVal.numberOfItems is 3
 PASS text1.x.baseVal.getItem(0).value is 1000
 PASS text1.x.baseVal.getItem(1).value is 500
 PASS text1.x.baseVal.getItem(2).value is 1500
 PASS text1.getAttribute('x') is "1000 500 1500"
 PASS text1.x.baseVal.insertItemBefore(text1.x.baseVal.getItem(1), text1) is text1.x.baseVal.getItem(0)
+PASS text1.x.baseVal.removeItem(2).toString() is "[object SVGLength]"
 PASS text1.x.baseVal.numberOfItems is 3
 PASS text1.x.baseVal.getItem(0).value is 500
 PASS text1.x.baseVal.getItem(1).value is 1000
 PASS text1.x.baseVal.getItem(2).value is 1500
 PASS text1.getAttribute('x') is "500 1000 1500"
 PASS text1.x.baseVal.insertItemBefore(text1.x.baseVal.getItem(1), null) is text1.x.baseVal.getItem(0)
+PASS text1.x.baseVal.removeItem(2).toString() is "[object SVGLength]"
 PASS text1.x.baseVal.numberOfItems is 3
 PASS text1.x.baseVal.getItem(0).value is 1000
 PASS text1.x.baseVal.getItem(1).value is 500
 PASS text1.x.baseVal.getItem(2).value is 1500
 PASS text1.getAttribute('x') is "1000 500 1500"
 PASS text1.x.baseVal.insertItemBefore(text1.x.baseVal.getItem(1), 0) is text1.x.baseVal.getItem(0)
+PASS text1.x.baseVal.removeItem(2).toString() is "[object SVGLength]"
 PASS text1.x.baseVal.numberOfItems is 3
 PASS text1.x.baseVal.getItem(0).value is 500
 PASS text1.x.baseVal.getItem(1).value is 1000
@@ -62,10 +66,13 @@ PASS text1.setAttribute('x', '1 2 3 4') is undefined.
 
 Test edge cases for insertItemBefore()
 PASS text1.x.baseVal.insertItemBefore(text1.x.baseVal.getItem(3), 3) is text1.x.baseVal.getItem(3)
+PASS text1.x.baseVal.removeItem(4).toString() is "[object SVGLength]"
 PASS text1.getAttribute('x') is "1 2 3 4"
-PASS text1.x.baseVal.insertItemBefore(text1.x.baseVal.getItem(1), 5) is text1.x.baseVal.getItem(3)
+PASS text1.x.baseVal.insertItemBefore(text1.x.baseVal.getItem(1), 5) is text1.x.baseVal.getItem(4)
+PASS text1.x.baseVal.removeItem(1).toString() is "[object SVGLength]"
 PASS text1.getAttribute('x') is "1 3 4 2"
 PASS text1.x.baseVal.insertItemBefore(text1.x.baseVal.getItem(1), 0) is text1.x.baseVal.getItem(0)
+PASS text1.x.baseVal.removeItem(2).toString() is "[object SVGLength]"
 PASS text1.getAttribute('x') is "3 1 4 2"
 
 Set x='1 2 3 4' for text1
@@ -111,7 +118,8 @@ Test edge cases for replaceItem()
 PASS text1.x.baseVal.replaceItem(text1.x.baseVal.getItem(3), 3) is text1.x.baseVal.getItem(3)
 PASS text1.x.baseVal.numberOfItems is 4
 PASS text1.getAttribute('x') is "1 2 3 4"
-PASS text1.x.baseVal.replaceItem(text1.x.baseVal.getItem(1), 3) is text1.x.baseVal.getItem(2)
+PASS text1.x.baseVal.replaceItem(text1.x.baseVal.getItem(1), 3) is text1.x.baseVal.getItem(3)
+PASS text1.x.baseVal.removeItem(1).toString() is "[object SVGLength]"
 PASS text1.x.baseVal.numberOfItems is 3
 PASS text1.getAttribute('x') is "1 3 2"
 PASS text1.x.baseVal.replaceItem(text1.x.baseVal.getItem(3), 4) threw exception IndexSizeError: The index is not in the allowed range..
@@ -120,13 +128,16 @@ Set x='1 2 3 4' for text1
 PASS text1.setAttribute('x', '1 2 3 4') is undefined.
 
 Test overlapping edge cases for replaceItem()
-PASS text1.x.baseVal.replaceItem(text1.x.baseVal.getItem(0), 3) is text1.x.baseVal.getItem(2)
+PASS text1.x.baseVal.replaceItem(text1.x.baseVal.getItem(0), 3) is text1.x.baseVal.getItem(3)
+PASS text1.x.baseVal.removeItem(0).toString() is "[object SVGLength]"
 PASS text1.x.baseVal.numberOfItems is 3
 PASS text1.x.baseVal.getItem(2).value is 2
-PASS text1.x.baseVal.replaceItem(text1.x.baseVal.getItem(0), 2) is text1.x.baseVal.getItem(1)
+PASS text1.x.baseVal.replaceItem(text1.x.baseVal.getItem(0), 2) is text1.x.baseVal.getItem(2)
+PASS text1.x.baseVal.removeItem(0).toString() is "[object SVGLength]"
 PASS text1.x.baseVal.numberOfItems is 2
 PASS text1.x.baseVal.getItem(1).value is 4
-PASS text1.x.baseVal.replaceItem(text1.x.baseVal.getItem(0), 1) is text1.x.baseVal.getItem(0)
+PASS text1.x.baseVal.replaceItem(text1.x.baseVal.getItem(0), 1) is text1.x.baseVal.getItem(1)
+PASS text1.x.baseVal.removeItem(1).toString() is "[object SVGLength]"
 PASS text1.x.baseVal.numberOfItems is 1
 PASS text1.x.baseVal.getItem(0).value is 6
 PASS text1.x.baseVal.replaceItem(text1.x.baseVal.getItem(0), 0) is text1.x.baseVal.getItem(0)
index 415ed90..a783101 100644 (file)
@@ -50,6 +50,7 @@
     shouldThrow("text1.x.baseVal.insertItemBefore(null)");
 
     shouldBe("text1.x.baseVal.insertItemBefore(text1.x.baseVal.getItem(1), 'aString')", "text1.x.baseVal.getItem(0)");
+    shouldBeEqualToString("text1.x.baseVal.removeItem(2).toString()", "[object SVGLength]");
     shouldBe("text1.x.baseVal.numberOfItems", "3");
     shouldBe("text1.x.baseVal.getItem(0).value", "1000");
     shouldBe("text1.x.baseVal.getItem(1).value", "500");
@@ -57,6 +58,7 @@
     shouldBeEqualToString("text1.getAttribute('x')", "1000 500 1500");
 
     shouldBe("text1.x.baseVal.insertItemBefore(text1.x.baseVal.getItem(1), text1)", "text1.x.baseVal.getItem(0)");
+    shouldBeEqualToString("text1.x.baseVal.removeItem(2).toString()", "[object SVGLength]");
     shouldBe("text1.x.baseVal.numberOfItems", "3");
     shouldBe("text1.x.baseVal.getItem(0).value", "500");
     shouldBe("text1.x.baseVal.getItem(1).value", "1000");
@@ -64,6 +66,7 @@
     shouldBeEqualToString("text1.getAttribute('x')", "500 1000 1500");
 
     shouldBe("text1.x.baseVal.insertItemBefore(text1.x.baseVal.getItem(1), null)", "text1.x.baseVal.getItem(0)");
+    shouldBeEqualToString("text1.x.baseVal.removeItem(2).toString()", "[object SVGLength]");
     shouldBe("text1.x.baseVal.numberOfItems", "3");
     shouldBe("text1.x.baseVal.getItem(0).value", "1000");
     shouldBe("text1.x.baseVal.getItem(1).value", "500");
@@ -71,6 +74,7 @@
     shouldBeEqualToString("text1.getAttribute('x')", "1000 500 1500");
 
     shouldBe("text1.x.baseVal.insertItemBefore(text1.x.baseVal.getItem(1), 0)", "text1.x.baseVal.getItem(0)");
+    shouldBeEqualToString("text1.x.baseVal.removeItem(2).toString()", "[object SVGLength]");
     shouldBe("text1.x.baseVal.numberOfItems", "3");
     shouldBe("text1.x.baseVal.getItem(0).value", "500");
     shouldBe("text1.x.baseVal.getItem(1).value", "1000");
     debug("");
     debug("Test edge cases for insertItemBefore()");
     shouldBe("text1.x.baseVal.insertItemBefore(text1.x.baseVal.getItem(3), 3)", "text1.x.baseVal.getItem(3)");
+    shouldBeEqualToString("text1.x.baseVal.removeItem(4).toString()", "[object SVGLength]");
     shouldBeEqualToString("text1.getAttribute('x')", "1 2 3 4");
-    shouldBe("text1.x.baseVal.insertItemBefore(text1.x.baseVal.getItem(1), 5)", "text1.x.baseVal.getItem(3)");
+    shouldBe("text1.x.baseVal.insertItemBefore(text1.x.baseVal.getItem(1), 5)", "text1.x.baseVal.getItem(4)");
+    shouldBeEqualToString("text1.x.baseVal.removeItem(1).toString()", "[object SVGLength]");
     shouldBeEqualToString("text1.getAttribute('x')", "1 3 4 2");
     shouldBe("text1.x.baseVal.insertItemBefore(text1.x.baseVal.getItem(1), 0)", "text1.x.baseVal.getItem(0)");
+    shouldBeEqualToString("text1.x.baseVal.removeItem(2).toString()", "[object SVGLength]");
     shouldBeEqualToString("text1.getAttribute('x')", "3 1 4 2");
 
     debug("");
     shouldBe("text1.x.baseVal.replaceItem(text1.x.baseVal.getItem(3), 3)", "text1.x.baseVal.getItem(3)");
     shouldBe("text1.x.baseVal.numberOfItems", "4");
     shouldBeEqualToString("text1.getAttribute('x')", "1 2 3 4");
-    shouldBe("text1.x.baseVal.replaceItem(text1.x.baseVal.getItem(1), 3)", "text1.x.baseVal.getItem(2)");
+    shouldBe("text1.x.baseVal.replaceItem(text1.x.baseVal.getItem(1), 3)", "text1.x.baseVal.getItem(3)");
+    shouldBeEqualToString("text1.x.baseVal.removeItem(1).toString()", "[object SVGLength]");
     shouldBe("text1.x.baseVal.numberOfItems", "3");
     shouldBeEqualToString("text1.getAttribute('x')", "1 3 2");
     shouldThrow("text1.x.baseVal.replaceItem(text1.x.baseVal.getItem(3), 4)");
     debug("");
     debug("Test overlapping edge cases for replaceItem()");
     var item = text1.x.baseVal.getItem(3);
-    shouldBe("text1.x.baseVal.replaceItem(text1.x.baseVal.getItem(0), 3)", "text1.x.baseVal.getItem(2)");
+    shouldBe("text1.x.baseVal.replaceItem(text1.x.baseVal.getItem(0), 3)", "text1.x.baseVal.getItem(3)");
+    shouldBeEqualToString("text1.x.baseVal.removeItem(0).toString()", "[object SVGLength]");
     shouldBe("text1.x.baseVal.numberOfItems", "3");    
     item = text1.x.baseVal.getItem(2);
     item.newValueSpecifiedUnits(item.unitType, item.value * 2);
     shouldBe("text1.x.baseVal.getItem(2).value", "2");
-    shouldBe("text1.x.baseVal.replaceItem(text1.x.baseVal.getItem(0), 2)", "text1.x.baseVal.getItem(1)");
+    shouldBe("text1.x.baseVal.replaceItem(text1.x.baseVal.getItem(0), 2)", "text1.x.baseVal.getItem(2)");
+    shouldBeEqualToString("text1.x.baseVal.removeItem(0).toString()", "[object SVGLength]");
     shouldBe("text1.x.baseVal.numberOfItems", "2");
     item = text1.x.baseVal.getItem(1);
     item.newValueSpecifiedUnits(item.unitType, item.value * 2);
     shouldBe("text1.x.baseVal.getItem(1).value", "4");
-    shouldBe("text1.x.baseVal.replaceItem(text1.x.baseVal.getItem(0), 1)", "text1.x.baseVal.getItem(0)");
+    shouldBe("text1.x.baseVal.replaceItem(text1.x.baseVal.getItem(0), 1)", "text1.x.baseVal.getItem(1)");
+    shouldBeEqualToString("text1.x.baseVal.removeItem(1).toString()", "[object SVGLength]");
     shouldBe("text1.x.baseVal.numberOfItems", "1");
     item = text1.x.baseVal.getItem(0);
     item.newValueSpecifiedUnits(item.unitType, item.value * 2);
index 8c6fe2d..9d9006e 100644 (file)
@@ -45,7 +45,8 @@ PASS text2.x.baseVal.getItem(1).value is 500
 PASS text2.x.baseVal.getItem(1).value is 50
 
 Override the third text elements x list with the item x=50 from the second text element, where it should be removed afterwards
-PASS text3.x.baseVal.initialize(itemInAnotherList) is itemInAnotherList
+PASS text3.x.baseVal.initialize(itemInAnotherList) is text3.x.baseVal.getItem(0)
+PASS text2.x.baseVal.removeItem(1).toString() is "[object SVGLength]"
 PASS text3.x.baseVal.getItem(0).value is 50
 PASS text2.x.baseVal.getItem(0).value is 50
 PASS text2.x.baseVal.getItem(1) threw exception IndexSizeError: The index is not in the allowed range..
@@ -59,7 +60,8 @@ PASS itemInAnotherList.value is 50
 PASS text3.x.baseVal.getItem(0).value is 50
 
 Move item from text3 to text4
-PASS text4.x.baseVal.initialize(text3.x.baseVal.getItem(0)) is itemInAnotherList
+PASS text4.x.baseVal.initialize(text3.x.baseVal.getItem(0)) is text4.x.baseVal.getItem(0)
+PASS text3.x.baseVal.removeItem(0).toString() is "[object SVGLength]"
 PASS text4.x.baseVal.getItem(0).value is 50
 PASS text3.x.baseVal.getItem(0) threw exception IndexSizeError: The index is not in the allowed range..
 
index 63ebf3f..ed27d04 100644 (file)
     itemInAnotherList.value = 50;
     shouldBe("text2.x.baseVal.getItem(1).value", "50");
 
-    // Spec: If the inserted item is already in a list, it is removed from its previous list before it is inserted into this list.
-    //       The inserted item is the item itself and not a copy.
+    // Spec: If the inserted item is already in a list, a copy of the item will be inserted.
     debug("");
     debug("Override the third text elements x list with the item x=50 from the second text element, where it should be removed afterwards");
-    shouldBe("text3.x.baseVal.initialize(itemInAnotherList)", "itemInAnotherList");
+    shouldBe("text3.x.baseVal.initialize(itemInAnotherList)", "text3.x.baseVal.getItem(0)");
+    shouldBeEqualToString("text2.x.baseVal.removeItem(1).toString()", "[object SVGLength]");
+    itemInAnotherList = text3.x.baseVal.getItem(0);
     shouldBe("text3.x.baseVal.getItem(0).value", "50");
     shouldBe("text2.x.baseVal.getItem(0).value", "50");
     shouldThrow("text2.x.baseVal.getItem(1)");
@@ -91,7 +92,8 @@
 
     debug("");
     debug("Move item from text3 to text4");
-    shouldBe("text4.x.baseVal.initialize(text3.x.baseVal.getItem(0))", "itemInAnotherList");
+    shouldBe("text4.x.baseVal.initialize(text3.x.baseVal.getItem(0))", "text4.x.baseVal.getItem(0)");
+    shouldBeEqualToString("text3.x.baseVal.removeItem(0).toString()", "[object SVGLength]");
     shouldBe("text4.x.baseVal.getItem(0).value", "50");
     shouldThrow("text3.x.baseVal.getItem(0)");
 
index 191f346..ba825bf 100644 (file)
@@ -62,7 +62,8 @@ PASS text1.x.baseVal.getItem(5).value is 50
 PASS text1.x.baseVal.getItem(6) threw exception IndexSizeError: The index is not in the allowed range..
 
 Insert item 'newLength3' at position=1, between '100' and '500', remove it from the old position=2 afterwards.
-PASS text1.x.baseVal.insertItemBefore(newLength3, 1) is newLength3
+PASS text1.x.baseVal.insertItemBefore(newLength3, 1) is text1.x.baseVal.getItem(1)
+PASS text1.x.baseVal.removeItem(3).toString() is "[object SVGLength]"
 PASS text1.x.baseVal.numberOfItems is 6
 PASS text1.x.baseVal.getItem(0).value is 100
 PASS text1.x.baseVal.getItem(1).value is 150
@@ -73,7 +74,8 @@ PASS text1.x.baseVal.getItem(5).value is 50
 PASS text1.x.baseVal.getItem(6) threw exception IndexSizeError: The index is not in the allowed range..
 
 Insert item 'newLength3' at position=0, before '100', remove it from the old position=5 afterwards.
-PASS text1.x.baseVal.insertItemBefore(newLength1, 0) is newLength1
+PASS text1.x.baseVal.insertItemBefore(newLength1, 0) is text1.x.baseVal.getItem(0)
+PASS text1.x.baseVal.removeItem(6).toString() is "[object SVGLength]"
 PASS text1.x.baseVal.numberOfItems is 6
 PASS text1.x.baseVal.getItem(0).value is 50
 PASS text1.x.baseVal.getItem(1).value is 100
index e1dfe18..ac678ea 100644 (file)
     shouldBe("text1.x.baseVal.getItem(5).value", "50");
     shouldThrow("text1.x.baseVal.getItem(6)");
 
-    // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list.
-    // Spec: If the item is already in this list, note that the index of the item to insert before is before the removal of the item. 
+    // Spec: If newItem is already in a list, a clone of newItem inserted into this list.
     debug("");
     debug("Insert item 'newLength3' at position=1, between '100' and '500', remove it from the old position=2 afterwards.");
-    shouldBe("text1.x.baseVal.insertItemBefore(newLength3, 1)", "newLength3");
+    shouldBe("text1.x.baseVal.insertItemBefore(newLength3, 1)", "text1.x.baseVal.getItem(1)");
+    shouldBeEqualToString("text1.x.baseVal.removeItem(3).toString()", "[object SVGLength]");
     shouldBe("text1.x.baseVal.numberOfItems", "6");
     shouldBe("text1.x.baseVal.getItem(0).value", "100");
     shouldBe("text1.x.baseVal.getItem(1).value", "150");
 
     debug("");
     debug("Insert item 'newLength3' at position=0, before '100', remove it from the old position=5 afterwards.");
-    shouldBe("text1.x.baseVal.insertItemBefore(newLength1, 0)", "newLength1");
+    shouldBe("text1.x.baseVal.insertItemBefore(newLength1, 0)", "text1.x.baseVal.getItem(0)");
+    shouldBeEqualToString("text1.x.baseVal.removeItem(6).toString()", "[object SVGLength]");
     shouldBe("text1.x.baseVal.numberOfItems", "6");
     shouldBe("text1.x.baseVal.getItem(0).value", "50");
     shouldBe("text1.x.baseVal.getItem(1).value", "100");
index d45a994..e6a69d9 100644 (file)
@@ -27,7 +27,8 @@ PASS text2.x.baseVal.getItem(2).value is 1000
 PASS text2.x.baseVal.getItem(3) threw exception IndexSizeError: The index is not in the allowed range..
 
 Append fourth item x=900 to the text1 x list
-PASS text1.x.baseVal.appendItem(text1.x.baseVal.getItem(3)) is text1.x.baseVal.getItem(4)
+PASS text1.x.baseVal.appendItem(text1.x.baseVal.getItem(3)) is text1.x.baseVal.getItem(5)
+PASS text1.x.baseVal.removeItem(3).toString() is "[object SVGLength]"
 PASS text1.x.baseVal.numberOfItems is 5
 PASS text1.x.baseVal.getItem(0).value is 500
 PASS text1.x.baseVal.getItem(1).value is 50
@@ -37,7 +38,8 @@ PASS text1.x.baseVal.getItem(4).value is 900
 PASS text1.x.baseVal.getItem(5) threw exception IndexSizeError: The index is not in the allowed range..
 
 Append first item x=500 to the text1 x list
-PASS text1.x.baseVal.appendItem(text1.x.baseVal.getItem(0)) is text1.x.baseVal.getItem(4)
+PASS text1.x.baseVal.appendItem(text1.x.baseVal.getItem(0)) is text1.x.baseVal.getItem(5)
+PASS text1.x.baseVal.removeItem(0).toString() is "[object SVGLength]"
 PASS text1.x.baseVal.numberOfItems is 5
 PASS text1.x.baseVal.getItem(0).value is 50
 PASS text1.x.baseVal.getItem(1).value is 100
@@ -59,7 +61,9 @@ PASS text1.x.baseVal.getItem(6) threw exception IndexSizeError: The index is not
 
 Append third and fourth item of the text1 x list to the text2 x list
 PASS text2.x.baseVal.appendItem(text1.x.baseVal.getItem(2)).value is 1000
+PASS text1.x.baseVal.removeItem(2).toString() is "[object SVGLength]"
 PASS text2.x.baseVal.appendItem(text1.x.baseVal.getItem(2)).value is 900
+PASS text1.x.baseVal.removeItem(2).toString() is "[object SVGLength]"
 PASS text1.x.baseVal.numberOfItems is 4
 PASS text1.x.baseVal.getItem(0).value is 50
 PASS text1.x.baseVal.getItem(1).value is 100
@@ -77,10 +81,14 @@ PASS newLength2.value is 150
 
 Shuffle around items in text1 and text2 list using appendItem, to get x=50,100,150,... in both lists
 PASS text1.x.baseVal.appendItem(text1.x.baseVal.getItem(2)).value is 500
+PASS text1.x.baseVal.removeItem(2).toString() is "[object SVGLength]"
 PASS text2.x.baseVal.appendItem(newLength2).value is 150
 PASS text2.x.baseVal.appendItem(text2.x.baseVal.getItem(2)).value is 1000
+PASS text2.x.baseVal.removeItem(2).toString() is "[object SVGLength]"
 PASS text2.x.baseVal.appendItem(text2.x.baseVal.getItem(3)).value is 900
+PASS text2.x.baseVal.removeItem(3).toString() is "[object SVGLength]"
 PASS text2.x.baseVal.appendItem(text2.x.baseVal.getItem(2)).value is 1000
+PASS text2.x.baseVal.removeItem(2).toString() is "[object SVGLength]"
 PASS text1.x.baseVal.numberOfItems is 4
 PASS text1.x.baseVal.getItem(0).value is 50
 PASS text1.x.baseVal.getItem(1).value is 100
index 49ec802..eb54b95 100644 (file)
@@ -46,7 +46,8 @@
 
     debug("");
     debug("Append fourth item x=900 to the text1 x list");
-    shouldBe("text1.x.baseVal.appendItem(text1.x.baseVal.getItem(3))", "text1.x.baseVal.getItem(4)");
+    shouldBe("text1.x.baseVal.appendItem(text1.x.baseVal.getItem(3))", "text1.x.baseVal.getItem(5)");
+    shouldBeEqualToString("text1.x.baseVal.removeItem(3).toString()", "[object SVGLength]");
     shouldBe("text1.x.baseVal.numberOfItems", "5");
     shouldBe("text1.x.baseVal.getItem(0).value", "500");
     shouldBe("text1.x.baseVal.getItem(1).value", "50");
@@ -57,7 +58,8 @@
 
     debug("");
     debug("Append first item x=500 to the text1 x list");
-    shouldBe("text1.x.baseVal.appendItem(text1.x.baseVal.getItem(0))", "text1.x.baseVal.getItem(4)");
+    shouldBe("text1.x.baseVal.appendItem(text1.x.baseVal.getItem(0))", "text1.x.baseVal.getItem(5)");
+    shouldBeEqualToString("text1.x.baseVal.removeItem(0).toString()", "[object SVGLength]");
     shouldBe("text1.x.baseVal.numberOfItems", "5");
     shouldBe("text1.x.baseVal.getItem(0).value", "50");
     shouldBe("text1.x.baseVal.getItem(1).value", "100");
@@ -81,7 +83,9 @@
     debug("");
     debug("Append third and fourth item of the text1 x list to the text2 x list");
     shouldBe("text2.x.baseVal.appendItem(text1.x.baseVal.getItem(2)).value", "1000");
+    shouldBeEqualToString("text1.x.baseVal.removeItem(2).toString()", "[object SVGLength]");
     shouldBe("text2.x.baseVal.appendItem(text1.x.baseVal.getItem(2)).value", "900");
+    shouldBeEqualToString("text1.x.baseVal.removeItem(2).toString()", "[object SVGLength]");
     shouldBe("text1.x.baseVal.numberOfItems", "4");
     shouldBe("text1.x.baseVal.getItem(0).value", "50");
     shouldBe("text1.x.baseVal.getItem(1).value", "100");
     debug("");
     debug("Shuffle around items in text1 and text2 list using appendItem, to get x=50,100,150,... in both lists");
     shouldBe("text1.x.baseVal.appendItem(text1.x.baseVal.getItem(2)).value", "500");
+    shouldBeEqualToString("text1.x.baseVal.removeItem(2).toString()", "[object SVGLength]");
     shouldBe("text2.x.baseVal.appendItem(newLength2).value", "150");
     shouldBe("text2.x.baseVal.appendItem(text2.x.baseVal.getItem(2)).value", "1000");
+    shouldBeEqualToString("text2.x.baseVal.removeItem(2).toString()", "[object SVGLength]");
     shouldBe("text2.x.baseVal.appendItem(text2.x.baseVal.getItem(3)).value", "900");
+    shouldBeEqualToString("text2.x.baseVal.removeItem(3).toString()", "[object SVGLength]");
     shouldBe("text2.x.baseVal.appendItem(text2.x.baseVal.getItem(2)).value", "1000");
+    shouldBeEqualToString("text2.x.baseVal.removeItem(2).toString()", "[object SVGLength]");
     shouldBe("text1.x.baseVal.numberOfItems", "4");
     shouldBe("text1.x.baseVal.getItem(0).value", "50");
     shouldBe("text1.x.baseVal.getItem(1).value", "100");
index b138916..5ba6103 100644 (file)
@@ -46,6 +46,7 @@ PASS text2.x.baseVal.getItem(4) threw exception IndexSizeError: The index is not
 
 Replace the first item in text2 x list with the third item in the list
 PASS text2.x.baseVal.replaceItem(text2.x.baseVal.getItem(2), 0).value is 50
+PASS text2.x.baseVal.removeItem(2).toString() is "[object SVGLength]"
 PASS text2.x.baseVal.numberOfItems is 3
 PASS text2.x.baseVal.getItem(0).value is 50
 PASS text2.x.baseVal.getItem(1).value is 100
@@ -70,6 +71,7 @@ PASS text4.x.baseVal.getItem(4) threw exception IndexSizeError: The index is not
 
 Replace the first item in text4 x list with the second item in the text3 x list
 PASS text4.x.baseVal.replaceItem(text3.x.baseVal.getItem(1), 0).value is 50
+PASS text3.x.baseVal.removeItem(1).toString() is "[object SVGLength]"
 PASS text3.x.baseVal.numberOfItems is 4
 PASS text3.x.baseVal.getItem(0).value is 50
 PASS text3.x.baseVal.getItem(1).value is 100
@@ -85,6 +87,7 @@ PASS text4.x.baseVal.getItem(4) threw exception IndexSizeError: The index is not
 
 Replace the second item in text4 x list with the second item in the text4 x list
 PASS text4.x.baseVal.replaceItem(text3.x.baseVal.getItem(2), 1).value is 100
+PASS text3.x.baseVal.removeItem(2).toString() is "[object SVGLength]"
 PASS text4.x.baseVal.numberOfItems is 4
 PASS text4.x.baseVal.getItem(0).value is 50
 PASS text4.x.baseVal.getItem(1).value is 100
index b6824a4..cb74d43 100644 (file)
@@ -75,6 +75,7 @@
     debug("");
     debug("Replace the first item in text2 x list with the third item in the list");
     shouldBe("text2.x.baseVal.replaceItem(text2.x.baseVal.getItem(2), 0).value", "50");
+    shouldBeEqualToString("text2.x.baseVal.removeItem(2).toString()", "[object SVGLength]");
     shouldBe("text2.x.baseVal.numberOfItems", "3");
     shouldBe("text2.x.baseVal.getItem(0).value", "50");
     shouldBe("text2.x.baseVal.getItem(1).value", "100");
     debug("");
     debug("Replace the first item in text4 x list with the second item in the text3 x list");
     shouldBe("text4.x.baseVal.replaceItem(text3.x.baseVal.getItem(1), 0).value", "50");
+    shouldBeEqualToString("text3.x.baseVal.removeItem(1).toString()", "[object SVGLength]");
     shouldBe("text3.x.baseVal.numberOfItems", "4");
     shouldBe("text3.x.baseVal.getItem(0).value", "50");
     shouldBe("text3.x.baseVal.getItem(1).value", "100");
     debug("");
     debug("Replace the second item in text4 x list with the second item in the text4 x list");
     shouldBe("text4.x.baseVal.replaceItem(text3.x.baseVal.getItem(2), 1).value", "100");
+    shouldBeEqualToString("text3.x.baseVal.removeItem(2).toString()", "[object SVGLength]");
     shouldBe("text4.x.baseVal.numberOfItems", "4");
     shouldBe("text4.x.baseVal.getItem(0).value", "50");
     shouldBe("text4.x.baseVal.getItem(1).value", "100");
index 540b390..52e3956 100644 (file)
@@ -1,3 +1,280 @@
+2019-03-26  Said Abou-Hallawa  <said@apple.com>
+
+        Remove the SVG tear off objects for SVGLength, SVGLengthList and SVGAnimatedLengthList
+        https://bugs.webkit.org/show_bug.cgi?id=196083
+
+        Reviewed by Simon Fraser.
+
+        -- SVGLength will be a superclass of SVGValueProperty<SVGLengthValue>. It
+           is a wrapper of SVGLengthValue. It will be provide the DOM methods. It
+           can setValueAsString() and return valueAsString().
+
+        -- SVGLengthList will be a superclass of SVGValuePropertyList<SVGLength>.
+           The base class will provide all the DOM methods. SVGLengthList will be
+           responsible for parsing a String to a SVGLength items. It can also 
+           build a string representing the stored items.
+
+        -- SVGAnimatedLengthList will be defined as SVGAnimatedPropertyList<SVGLengthList>.
+           Like SVGAnimatedPointList, all the required methods and attributes
+           will be handled by SVGAnimatedPropertyList.
+
+        -- SVGAnimatedLengthAccessor and SVGAnimatedLengthListAccessor will be
+           added to access the members of types SVGAnimatedLength and 
+           SVGAnimatedLengthList.
+
+        -- SVGAnimatedLengthAnimator and SVGAnimatedLengthListAnimator will be
+           created by the the new accessors to animate attributes of types
+           SVGAnimatedLength and SVGAnimatedLengthList.
+
+        -- SVGAnimationLengthFunction and SVGAnimationLengthListFunction will be
+           responsible for progressing the animVal() of attributes of types
+           SVGAnimatedLength and SVGAnimatedLengthList.
+
+        -- SVGValuePropertyAnimator is a new template class which can animate a
+           none reflecting attribute which should be backed by a value property,
+           e.g. SVGLength.
+
+        -- SVGValuePropertyListAnimator is a new template class which can animate a
+           none reflecting attribute which should be backed by a value property
+           list, e.g. SVGLengthList.
+
+        Notes:
+
+            -- SVGElement::isAnimatedStyleAttribute() will return true if the
+               attribute is known by SVGPropertyAnimatorFactory. Or it's has 
+               a reflecting SVGAnimatedPropertyLength property and its name is
+               one of the names listed in isAnimatedStylePropertyAttribute() of
+               the propertyRegistry() of the SVGElement.
+
+            -- SVGElement::commitPropertyChange() has to handle the attributes
+               for which isAnimatedStylePropertyAttribute() returns true different
+               from the other ones. styleReclac() needs updated attributes since
+               it does not access the reflecting properties in the SVGELement.
+
+            -- SVGTextContentElement does not need a customized SVGAnimatedLength.
+               All SVGTextContentElement::textLengthAnimated() needs to know is
+               whether m_textLength->baseVal() holds an empty SVGLength. If it
+               does, it sets its value to getComputedTextLength().
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * rendering/svg/SVGTextLayoutAttributesBuilder.cpp:
+        (WebCore::updateCharacterData):
+        (WebCore::SVGTextLayoutAttributesBuilder::fillCharacterDataMap):
+        * svg/SVGAnimateElementBase.cpp:
+        (WebCore::SVGAnimateElementBase::hasValidAttributeType const):
+        * svg/SVGAnimatedLength.cpp: Removed.
+        * svg/SVGAnimatedLength.h: Removed.
+        * svg/SVGAnimatedLengthList.cpp: Removed.
+        * svg/SVGAnimatedLengthList.h: Removed.
+        * svg/SVGAnimatedType.h:
+        (WebCore::SVGAnimatedType::type const):
+        * svg/SVGAnimationElement.cpp:
+        (WebCore::SVGAnimationElement::isTargetAttributeCSSProperty):
+        (WebCore::inheritsFromProperty):
+        * svg/SVGAnimatorFactory.h:
+        (WebCore::SVGAnimatorFactory::isSupportedAttribute):
+        (WebCore::SVGAnimatorFactory::create):
+        These changes were required because some of the tests were trying to
+        animated unsupported attributes. To differentiate between between the
+        these two cases:
+            1) the attribute is animate-able by the legacy controller.
+            2) animating the attribute or the attribute itself is not supported
+               by the element.
+
+        We want SVGAnimatorFactory tell us whether it can create an animator for
+        a given attribute or not.
+
+        * svg/SVGCircleElement.cpp:
+        (WebCore::SVGCircleElement::SVGCircleElement):
+        (WebCore::SVGCircleElement::parseAttribute):
+        (WebCore::SVGCircleElement::svgAttributeChanged):
+        (WebCore::SVGCircleElement::registerAttributes): Deleted.
+        * svg/SVGCircleElement.h:
+        * svg/SVGCursorElement.cpp:
+        (WebCore::SVGCursorElement::SVGCursorElement):
+        (WebCore::SVGCursorElement::parseAttribute):
+        (WebCore::SVGCursorElement::svgAttributeChanged):
+        (WebCore::SVGCursorElement::registerAttributes): Deleted.
+        * svg/SVGCursorElement.h:
+        * svg/SVGElement.cpp:
+        (WebCore::SVGElement::commitPropertyChange):
+        (WebCore::SVGElement::isAnimatedStyleAttribute const):
+        * svg/SVGElement.h:
+        * svg/SVGEllipseElement.cpp:
+        (WebCore::SVGEllipseElement::SVGEllipseElement):
+        (WebCore::SVGEllipseElement::parseAttribute):
+        (WebCore::SVGEllipseElement::svgAttributeChanged):
+        (WebCore::SVGEllipseElement::registerAttributes): Deleted.
+        * svg/SVGEllipseElement.h:
+        * svg/SVGFilterElement.cpp:
+        (WebCore::SVGFilterElement::SVGFilterElement):
+        (WebCore::SVGFilterElement::registerAttributes):
+        (WebCore::SVGFilterElement::parseAttribute):
+        * svg/SVGFilterElement.h:
+        * svg/SVGFilterPrimitiveStandardAttributes.cpp:
+        (WebCore::SVGFilterPrimitiveStandardAttributes::SVGFilterPrimitiveStandardAttributes):
+        (WebCore::SVGFilterPrimitiveStandardAttributes::parseAttribute):
+        (WebCore::SVGFilterPrimitiveStandardAttributes::registerAttributes): Deleted.
+        * svg/SVGFilterPrimitiveStandardAttributes.h:
+        (WebCore::SVGFilterPrimitiveStandardAttributes::x const):
+        (WebCore::SVGFilterPrimitiveStandardAttributes::y const):
+        (WebCore::SVGFilterPrimitiveStandardAttributes::width const):
+        (WebCore::SVGFilterPrimitiveStandardAttributes::height const):
+        (WebCore::SVGFilterPrimitiveStandardAttributes::xAnimated):
+        (WebCore::SVGFilterPrimitiveStandardAttributes::yAnimated):
+        (WebCore::SVGFilterPrimitiveStandardAttributes::widthAnimated):
+        (WebCore::SVGFilterPrimitiveStandardAttributes::heightAnimated):
+        (WebCore::SVGFilterPrimitiveStandardAttributes::isKnownAttribute): Deleted.
+        * svg/SVGForeignObjectElement.cpp:
+        (WebCore::SVGForeignObjectElement::SVGForeignObjectElement):
+        (WebCore::SVGForeignObjectElement::parseAttribute):
+        (WebCore::SVGForeignObjectElement::registerAttributes): Deleted.
+        * svg/SVGForeignObjectElement.h:
+        * svg/SVGImageElement.cpp:
+        (WebCore::SVGImageElement::SVGImageElement):
+        (WebCore::SVGImageElement::parseAttribute):
+        (WebCore::SVGImageElement::registerAttributes): Deleted.
+        * svg/SVGImageElement.h:
+        * svg/SVGLength.h:
+        (WebCore::SVGLength::create):
+        (WebCore::SVGLength::clone const):
+        (WebCore::SVGLength::unitType):
+        (WebCore::SVGLength::valueForBindings):
+        (WebCore::SVGLength::setValueForBindings):
+        (WebCore::SVGLength::valueInSpecifiedUnits):
+        (WebCore::SVGLength::setValueInSpecifiedUnits):
+        (WebCore::SVGLength::setValueAsString):
+        (WebCore::SVGLength::newValueSpecifiedUnits):
+        (WebCore::SVGLength::convertToSpecifiedUnits):
+        (WebCore::SVGLength::valueAsString): Deleted.
+        (WebCore::SVGLength::SVGLength): Deleted.
+        * svg/SVGLengthList.h:
+        (WebCore::SVGLengthList::create):
+        (WebCore::SVGLengthList::lengthMode const):
+        (WebCore::SVGLengthList::parse):
+        (WebCore::SVGLengthList::SVGLengthList):
+        * svg/SVGLengthListValues.cpp: Removed.
+        * svg/SVGLengthListValues.h: Removed.
+        * svg/SVGLineElement.cpp:
+        (WebCore::SVGLineElement::SVGLineElement):
+        (WebCore::SVGLineElement::parseAttribute):
+        (WebCore::SVGLineElement::svgAttributeChanged):
+        (WebCore::SVGLineElement::registerAttributes): Deleted.
+        * svg/SVGLineElement.h:
+        * svg/SVGLinearGradientElement.cpp:
+        (WebCore::SVGLinearGradientElement::SVGLinearGradientElement):
+        (WebCore::SVGLinearGradientElement::parseAttribute):
+        (WebCore::SVGLinearGradientElement::svgAttributeChanged):
+        (WebCore::SVGLinearGradientElement::registerAttributes): Deleted.
+        * svg/SVGLinearGradientElement.h:
+        * svg/SVGMarkerElement.cpp:
+        (WebCore::SVGMarkerElement::SVGMarkerElement):
+        (WebCore::SVGMarkerElement::registerAttributes):
+        (WebCore::SVGMarkerElement::parseAttribute):
+        * svg/SVGMarkerElement.h:
+        * svg/SVGMaskElement.cpp:
+        (WebCore::SVGMaskElement::SVGMaskElement):
+        (WebCore::SVGMaskElement::registerAttributes):
+        (WebCore::SVGMaskElement::parseAttribute):
+        (WebCore::SVGMaskElement::svgAttributeChanged):
+        * svg/SVGMaskElement.h:
+        * svg/SVGPatternElement.cpp:
+        (WebCore::SVGPatternElement::SVGPatternElement):
+        (WebCore::SVGPatternElement::registerAttributes):
+        (WebCore::SVGPatternElement::parseAttribute):
+        * svg/SVGPatternElement.h:
+        * svg/SVGPoint.h:
+        * svg/SVGRadialGradientElement.cpp:
+        (WebCore::SVGRadialGradientElement::SVGRadialGradientElement):
+        (WebCore::SVGRadialGradientElement::parseAttribute):
+        (WebCore::SVGRadialGradientElement::svgAttributeChanged):
+        (WebCore::SVGRadialGradientElement::registerAttributes): Deleted.
+        * svg/SVGRadialGradientElement.h:
+        * svg/SVGRectElement.cpp:
+        (WebCore::SVGRectElement::SVGRectElement):
+        (WebCore::SVGRectElement::parseAttribute):
+        (WebCore::SVGRectElement::svgAttributeChanged):
+        (WebCore::SVGRectElement::registerAttributes): Deleted.
+        * svg/SVGRectElement.h:
+        * svg/SVGSVGElement.cpp:
+        (WebCore::SVGSVGElement::SVGSVGElement):
+        (WebCore::SVGSVGElement::parseAttribute):
+        (WebCore::SVGSVGElement::svgAttributeChanged):
+        (WebCore::SVGSVGElement::registerAttributes): Deleted.
+        * svg/SVGSVGElement.h:
+        * svg/SVGTextContentElement.cpp:
+        (WebCore::SVGTextContentElement::SVGTextContentElement):
+        (WebCore::SVGTextContentElement::registerAttributes):
+        (WebCore::SVGTextContentElement::parseAttribute):
+        (WebCore::SVGTextContentElement::svgAttributeChanged):
+        (WebCore::SVGTextContentElement::textLengthAnimated):
+        * svg/SVGTextContentElement.h:
+        (WebCore::SVGTextContentElement::specifiedTextLength const):
+        (WebCore::SVGTextContentElement::textLength const):
+        (WebCore::SVGTextContentElement::specifiedTextLength): Deleted.
+        (WebCore::SVGTextContentElement::textLengthAnimated): Deleted.
+        (WebCore::SVGTextContentElement::SVGAnimatedCustomLengthAttribute::SVGAnimatedCustomLengthAttribute): Deleted.
+        (WebCore::SVGTextContentElement::SVGAnimatedCustomLengthAttribute::synchronize): Deleted.
+        (WebCore::SVGTextContentElement::SVGAnimatedCustomLengthAttribute::animatedProperty): Deleted.
+        * svg/SVGTextPathElement.cpp:
+        (WebCore::SVGTextPathElement::SVGTextPathElement):
+        (WebCore::SVGTextPathElement::registerAttributes):
+        (WebCore::SVGTextPathElement::parseAttribute):
+        * svg/SVGTextPathElement.h:
+        * svg/SVGTextPositioningElement.cpp:
+        (WebCore::SVGTextPositioningElement::SVGTextPositioningElement):
+        (WebCore::SVGTextPositioningElement::parseAttribute):
+        (WebCore::SVGTextPositioningElement::svgAttributeChanged):
+        (WebCore::SVGTextPositioningElement::registerAttributes): Deleted.
+        * svg/SVGTextPositioningElement.h:
+        (WebCore::SVGTextPositioningElement::x const):
+        (WebCore::SVGTextPositioningElement::y const):
+        (WebCore::SVGTextPositioningElement::dx const):
+        (WebCore::SVGTextPositioningElement::dy const):
+        (WebCore::SVGTextPositioningElement::xAnimated):
+        (WebCore::SVGTextPositioningElement::yAnimated):
+        (WebCore::SVGTextPositioningElement::dxAnimated):
+        (WebCore::SVGTextPositioningElement::dyAnimated):
+        (WebCore::SVGTextPositioningElement::isKnownAttribute): Deleted.
+        * svg/SVGUseElement.cpp:
+        (WebCore::SVGUseElement::SVGUseElement):
+        (WebCore::SVGUseElement::parseAttribute):
+        (WebCore::SVGUseElement::svgAttributeChanged):
+        (WebCore::SVGUseElement::registerAttributes): Deleted.
+        * svg/SVGUseElement.h:
+        * svg/SVGValue.h:
+        * svg/properties/SVGAnimatedPropertyAccessorImpl.h:
+        * svg/properties/SVGAnimatedPropertyAnimator.h:
+        * svg/properties/SVGAnimatedPropertyAnimatorImpl.h:
+        * svg/properties/SVGAnimatedPropertyImpl.h:
+        * svg/properties/SVGAnimationAdditiveListFunctionImpl.h:
+        (WebCore::SVGAnimationLengthListFunction::SVGAnimationLengthListFunction):
+        (WebCore::SVGAnimationLengthListFunction::progress):
+        (WebCore::SVGAnimationNumberListFunction::progress):
+        (WebCore::SVGAnimationPointListFunction::progress):
+        * svg/properties/SVGAnimationAdditiveValueFunctionImpl.h:
+        (WebCore::SVGAnimationLengthFunction::SVGAnimationLengthFunction):
+        (WebCore::SVGAnimationLengthFunction::progress):
+        * svg/properties/SVGAttributeAnimator.cpp:
+        (WebCore::SVGAttributeAnimator::isAnimatedStylePropertyAniamtor const):
+        * svg/properties/SVGAttributeAnimator.h:
+        * svg/properties/SVGAttributeRegistry.h:
+        * svg/properties/SVGPropertyAnimatorFactory.h:
+        (WebCore::SVGPropertyAnimatorFactory::createLengthAnimator):
+        (WebCore::SVGPropertyAnimatorFactory::createLengthListAnimator):
+        (WebCore::SVGPropertyAnimatorFactory::attributeAnimatorCreator):
+        * svg/properties/SVGPropertyOwnerRegistry.h:
+        (WebCore::SVGPropertyOwnerRegistry::registerProperty):
+        (WebCore::SVGPropertyOwnerRegistry::isAnimatedLengthAttribute):
+        * svg/properties/SVGPropertyRegistry.h:
+        * svg/properties/SVGValuePropertyAnimator.h: Added.
+        (WebCore::SVGValuePropertyAnimator::SVGValuePropertyAnimator):
+        * svg/properties/SVGValuePropertyAnimatorImpl.h: Added.
+        * svg/properties/SVGValuePropertyListAnimator.h: Added.
+        (WebCore::SVGValuePropertyListAnimator::SVGValuePropertyListAnimator):
+        * svg/properties/SVGValuePropertyListAnimatorImpl.h: Added.
+
 2019-03-26  Simon Fraser  <simon.fraser@apple.com>
 
         [iOS WK2] position:fixed inside oveflow:scroll is jumpy
index 5e2df88..8872a32 100644 (file)
@@ -2267,8 +2267,6 @@ svg/SVGAnimateElement.cpp
 svg/SVGAnimateElementBase.cpp
 svg/SVGAnimateMotionElement.cpp
 svg/SVGAnimateTransformElement.cpp
-svg/SVGAnimatedLength.cpp
-svg/SVGAnimatedLengthList.cpp
 svg/SVGAnimatedPath.cpp
 svg/SVGAnimatedTransformList.cpp
 svg/SVGAnimatedTypeAnimator.cpp
@@ -2334,7 +2332,6 @@ svg/SVGImageLoader.cpp
 svg/SVGLangSpace.cpp
 svg/SVGLegacyAttributeAnimationController.cpp
 svg/SVGLengthContext.cpp
-svg/SVGLengthListValues.cpp
 svg/SVGLengthValue.cpp
 svg/SVGLineElement.cpp
 svg/SVGLinearGradientElement.cpp
index 630af3a..bbc1883 100644 (file)
                088A0E0B126EF1DB00978F7A /* SVGPropertyTearOff.h in Headers */ = {isa = PBXBuildFile; fileRef = 088A0E02126EF1DB00978F7A /* SVGPropertyTearOff.h */; };
                088A0E0C126EF1DB00978F7A /* SVGPropertyTraits.h in Headers */ = {isa = PBXBuildFile; fileRef = 088A0E03126EF1DB00978F7A /* SVGPropertyTraits.h */; settings = {ATTRIBUTES = (Private, ); }; };
                088C2F7A12390081003D65CE /* SVGTextLayoutAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = 088C2F7612390080003D65CE /* SVGTextLayoutAttributes.h */; };
-               089021A9126EF5DE0092D5EA /* SVGAnimatedLength.h in Headers */ = {isa = PBXBuildFile; fileRef = 089021A8126EF5DE0092D5EA /* SVGAnimatedLength.h */; };
-               089021AD126EF5E90092D5EA /* SVGAnimatedLengthList.h in Headers */ = {isa = PBXBuildFile; fileRef = 089021AC126EF5E90092D5EA /* SVGAnimatedLengthList.h */; };
                089582560E857A7E00F82C83 /* ImageLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 089582540E857A7E00F82C83 /* ImageLoader.h */; settings = {ATTRIBUTES = (Private, ); }; };
                089A8E07128D8B3D00E7A534 /* SVGAnimatedPathSegListPropertyTearOff.h in Headers */ = {isa = PBXBuildFile; fileRef = 089A8E06128D8B3D00E7A534 /* SVGAnimatedPathSegListPropertyTearOff.h */; };
                08A484780E5272C500C3FE76 /* ScriptElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 08A484760E5272C500C3FE76 /* ScriptElement.h */; settings = {ATTRIBUTES = (Private, ); }; };
                7C30D9861F815AEC00268356 /* JSAbortSignal.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C30D9811F815AC100268356 /* JSAbortSignal.h */; };
                7C330A021DF8FAC600D3395C /* GraphicsContext3DAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C330A011DF8FAC600D3395C /* GraphicsContext3DAttributes.h */; settings = {ATTRIBUTES = (Private, ); }; };
                7C330A081DF9F95100D3395C /* JSPositionOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C330A061DF9F95100D3395C /* JSPositionOptions.h */; };
-               7C39C3651DDA865200FEFB29 /* SVGLengthListValues.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C39C3631DDA864900FEFB29 /* SVGLengthListValues.h */; };
                7C3A91E61C963B8800D1A7E3 /* ClipboardAccessPolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C3A91E51C963B8800D1A7E3 /* ClipboardAccessPolicy.h */; settings = {ATTRIBUTES = (Private, ); }; };
                7C3B79711908757B00B47A2D /* UserMessageHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C3B796F1908757B00B47A2D /* UserMessageHandler.cpp */; };
                7C3B79721908757B00B47A2D /* UserMessageHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C3B79701908757B00B47A2D /* UserMessageHandler.h */; settings = {ATTRIBUTES = (Private, ); }; };
                088A0E03126EF1DB00978F7A /* SVGPropertyTraits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGPropertyTraits.h; sourceTree = "<group>"; };
                088C2F7512390080003D65CE /* SVGTextLayoutAttributes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGTextLayoutAttributes.cpp; sourceTree = "<group>"; };
                088C2F7612390080003D65CE /* SVGTextLayoutAttributes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGTextLayoutAttributes.h; sourceTree = "<group>"; };
-               089021A8126EF5DE0092D5EA /* SVGAnimatedLength.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGAnimatedLength.h; sourceTree = "<group>"; };
-               089021AC126EF5E90092D5EA /* SVGAnimatedLengthList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGAnimatedLengthList.h; sourceTree = "<group>"; };
                089582530E857A7E00F82C83 /* ImageLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageLoader.cpp; sourceTree = "<group>"; };
                089582540E857A7E00F82C83 /* ImageLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageLoader.h; sourceTree = "<group>"; };
                089A8E06128D8B3D00E7A534 /* SVGAnimatedPathSegListPropertyTearOff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGAnimatedPathSegListPropertyTearOff.h; sourceTree = "<group>"; };
                427DA71B13735DFA007C57FB /* JSServiceWorkerInternals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSServiceWorkerInternals.cpp; sourceTree = "<group>"; };
                427DA71C13735DFA007C57FB /* JSServiceWorkerInternals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSServiceWorkerInternals.h; sourceTree = "<group>"; };
                43107BE118CC19DE00CC18E8 /* SelectorPseudoTypeMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectorPseudoTypeMap.h; sourceTree = "<group>"; };
-               431A2FD613B7707A007791E4 /* SVGAnimatedLengthList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGAnimatedLengthList.cpp; sourceTree = "<group>"; };
                432D3FE718A8658400D7DC03 /* SelectorCheckerTestFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectorCheckerTestFunctions.h; sourceTree = "<group>"; };
                4358E87A1360A2EE00E4748C /* JSSVGFEDropShadowElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSVGFEDropShadowElement.cpp; sourceTree = "<group>"; };
                4358E87B1360A2EE00E4748C /* JSSVGFEDropShadowElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSSVGFEDropShadowElement.h; sourceTree = "<group>"; };
                436708B912D9CA4B00044234 /* SVGResourcesCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGResourcesCache.h; sourceTree = "<group>"; };
                436708BA12D9CA4B00044234 /* SVGResourcesCycleSolver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGResourcesCycleSolver.cpp; sourceTree = "<group>"; };
                436708BB12D9CA4B00044234 /* SVGResourcesCycleSolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGResourcesCycleSolver.h; sourceTree = "<group>"; };
-               4381763A13A697D4007D1187 /* SVGAnimatedLength.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGAnimatedLength.cpp; sourceTree = "<group>"; };
                439046C312DA25E800AF80A2 /* RenderMathMLBlock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderMathMLBlock.cpp; sourceTree = "<group>"; };
                439046C412DA25E800AF80A2 /* RenderMathMLBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderMathMLBlock.h; sourceTree = "<group>"; };
                439046C512DA25E800AF80A2 /* RenderMathMLFenced.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderMathMLFenced.cpp; sourceTree = "<group>"; };
                72F1ADA11A3904C300014E18 /* EXTFragDepth.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = EXTFragDepth.idl; sourceTree = "<group>"; };
                72F1ADA31A390B9F00014E18 /* JSEXTFragDepth.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSEXTFragDepth.cpp; sourceTree = "<group>"; };
                72F1ADA41A390B9F00014E18 /* JSEXTFragDepth.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSEXTFragDepth.h; sourceTree = "<group>"; };
+               72FB238422497AD4007E5AC7 /* SVGValuePropertyAnimatorImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGValuePropertyAnimatorImpl.h; sourceTree = "<group>"; };
+               72FB238622497AD5007E5AC7 /* SVGValuePropertyAnimator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGValuePropertyAnimator.h; sourceTree = "<group>"; };
+               72FB238722497B15007E5AC7 /* SVGValuePropertyListAnimatorImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGValuePropertyListAnimatorImpl.h; sourceTree = "<group>"; };
+               72FB238822497B15007E5AC7 /* SVGValuePropertyListAnimator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGValuePropertyListAnimator.h; sourceTree = "<group>"; };
                7553CFE6108F473F00EA281E /* TimelineRecordFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TimelineRecordFactory.h; sourceTree = "<group>"; };
                7553CFE7108F473F00EA281E /* TimelineRecordFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TimelineRecordFactory.cpp; sourceTree = "<group>"; };
                75793E800D0CE0B3007FC0AC /* MessageEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MessageEvent.cpp; sourceTree = "<group>"; };
                                088A0E02126EF1DB00978F7A /* SVGPropertyTearOff.h */,
                                088A0E03126EF1DB00978F7A /* SVGPropertyTraits.h */,
                                721443462240CAD200F12FF7 /* SVGValueProperty.h */,
+                               72FB238622497AD5007E5AC7 /* SVGValuePropertyAnimator.h */,
+                               72FB238422497AD4007E5AC7 /* SVGValuePropertyAnimatorImpl.h */,
                                7266F02522430F8C00833975 /* SVGValuePropertyList.h */,
+                               72FB238822497B15007E5AC7 /* SVGValuePropertyListAnimator.h */,
+                               72FB238722497B15007E5AC7 /* SVGValuePropertyListAnimatorImpl.h */,
                        );
                        path = properties;
                        sourceTree = "<group>";
                                7134496C146941B300720312 /* SVGLengthContext.h */,
                                B22278A00D00BF200071B782 /* SVGLengthList.h */,
                                B22278A10D00BF200071B782 /* SVGLengthList.idl */,
-                               7C39C3621DDA864900FEFB29 /* SVGLengthListValues.cpp */,
-                               7C39C3631DDA864900FEFB29 /* SVGLengthListValues.h */,
                                7CE58D521DD7B09300128552 /* SVGLengthValue.cpp */,
                                7CE58D531DD7B09300128552 /* SVGLengthValue.h */,
                                B22278A20D00BF200071B782 /* SVGLinearGradientElement.cpp */,
                                55D70D23223B017C00044B8E /* SVGLegacyAnimatedProperty.h in Headers */,
                                7134496E146941B300720312 /* SVGLengthContext.h in Headers */,
                                B2227A360D00BF220071B782 /* SVGLengthList.h in Headers */,
-                               7C39C3651DDA865200FEFB29 /* SVGLengthListValues.h in Headers */,
                                7CCEBFC01DD8F6AB002C40B8 /* SVGLengthValue.h in Headers */,
                                B2227A390D00BF220071B782 /* SVGLinearGradientElement.h in Headers */,
                                B2227A3C0D00BF220071B782 /* SVGLineElement.h in Headers */,
index 8a57185..84f0427 100644 (file)
@@ -160,16 +160,16 @@ void SVGTextLayoutAttributesBuilder::buildCharacterDataMap(RenderSVGText& textRo
         fillCharacterDataMap(m_textPositions[i]);
 }
 
-static inline void updateCharacterData(unsigned i, float& lastRotation, SVGCharacterData& data, const SVGLengthContext& lengthContext, const SVGLengthListValues* xList, const SVGLengthListValues* yList, const SVGLengthListValues* dxList, const SVGLengthListValues* dyList, const SVGNumberList* rotateList)
+static inline void updateCharacterData(unsigned i, float& lastRotation, SVGCharacterData& data, const SVGLengthContext& lengthContext, const SVGLengthList* xList, const SVGLengthList* yList, const SVGLengthList* dxList, const SVGLengthList* dyList, const SVGNumberList* rotateList)
 {
     if (xList)
-        data.x = xList->at(i).value(lengthContext);
+        data.x = xList->items()[i]->value().value(lengthContext);
     if (yList)
-        data.y = yList->at(i).value(lengthContext);
+        data.y = yList->items()[i]->value().value(lengthContext);
     if (dxList)
-        data.dx = dxList->at(i).value(lengthContext);
+        data.dx = dxList->items()[i]->value().value(lengthContext);
     if (dyList)
-        data.dy = dyList->at(i).value(lengthContext);
+        data.dy = dyList->items()[i]->value().value(lengthContext);
     if (rotateList) {
         data.rotate = rotateList->items()[i]->value();
         lastRotation = data.rotate;
@@ -195,10 +195,10 @@ void SVGTextLayoutAttributesBuilder::fillCharacterDataMap(const TextPosition& po
     float lastRotation = SVGTextLayoutAttributes::emptyValue();
     SVGLengthContext lengthContext(position.element);
     for (unsigned i = 0; i < position.length; ++i) {
-        const SVGLengthListValues* xListPtr = i < xListSize ? &xList : 0;
-        const SVGLengthListValues* yListPtr = i < yListSize ? &yList : 0;
-        const SVGLengthListValues* dxListPtr = i < dxListSize ? &dxList : 0;
-        const SVGLengthListValues* dyListPtr = i < dyListSize ? &dyList : 0;
+        const SVGLengthList* xListPtr = i < xListSize ? &xList : nullptr;
+        const SVGLengthList* yListPtr = i < yListSize ? &yList : nullptr;
+        const SVGLengthList* dxListPtr = i < dxListSize ? &dxList : nullptr;
+        const SVGLengthList* dyListPtr = i < dyListSize ? &dyList : nullptr;
         const SVGNumberList* rotateListPtr = i < rotateListSize ? &rotateList : nullptr;
         if (!xListPtr && !yListPtr && !dxListPtr && !dyListPtr && !rotateListPtr)
             break;
index 04d35a0..834a929 100644 (file)
@@ -25,6 +25,7 @@
 #include "SVGAnimateElementBase.h"
 
 #include "QualifiedName.h"
+#include "SVGAnimatorFactory.h"
 #include "SVGAttributeAnimationController.h"
 #include "SVGElement.h"
 #include "SVGLegacyAttributeAnimationController.h"
@@ -63,7 +64,7 @@ bool SVGAnimateElementBase::hasValidAttributeType() const
     if (!targetElement() || hasInvalidCSSAttributeType())
         return false;
 
-    if (determineAnimatedPropertyType(*targetElement()) != AnimatedUnknown)
+    if (SVGAnimatorFactory::isSupportedAttributeType(determineAnimatedPropertyType(*targetElement())))
         return true;
 
     return targetElement()->isAnimatedAttribute(attributeName());
diff --git a/Source/WebCore/svg/SVGAnimatedLength.cpp b/Source/WebCore/svg/SVGAnimatedLength.cpp
deleted file mode 100644 (file)
index 58f1003..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2011. All rights reserved.
- * Copyright (C) 2018 Apple Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-#include "SVGAnimatedLength.h"
-
-#include "SVGAnimateElementBase.h"
-
-namespace WebCore {
-
-SVGAnimatedLengthAnimator::SVGAnimatedLengthAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement)
-    : SVGAnimatedTypeAnimator(AnimatedLength, animationElement, contextElement)
-    , m_lengthMode(SVGLengthValue::lengthModeForAnimatedLengthAttribute(animationElement->attributeName()))
-{
-}
-
-std::unique_ptr<SVGAnimatedType> SVGAnimatedLengthAnimator::constructFromString(const String& string)
-{
-    return SVGAnimatedType::create(SVGLengthValue(m_lengthMode, string));
-}
-
-std::unique_ptr<SVGAnimatedType> SVGAnimatedLengthAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
-    return constructFromBaseValue<SVGAnimatedLength>(animatedTypes);
-}
-
-void SVGAnimatedLengthAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
-    stopAnimValAnimationForType<SVGAnimatedLength>(animatedTypes);
-}
-
-void SVGAnimatedLengthAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType& type)
-{
-    resetFromBaseValue<SVGAnimatedLength>(animatedTypes, type);
-}
-
-void SVGAnimatedLengthAnimator::animValWillChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
-    animValWillChangeForType<SVGAnimatedLength>(animatedTypes);
-}
-
-void SVGAnimatedLengthAnimator::animValDidChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
-    animValDidChangeForType<SVGAnimatedLength>(animatedTypes);
-}
-
-void SVGAnimatedLengthAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimatedType* to)
-{
-    ASSERT(from->type() == AnimatedLength);
-    ASSERT(from->type() == to->type());
-
-    SVGLengthContext lengthContext(m_contextElement);
-    const auto& fromLength = from->as<SVGLengthValue>();
-    auto& toLength = to->as<SVGLengthValue>();
-
-    toLength.setValue(toLength.value(lengthContext) + fromLength.value(lengthContext), lengthContext);
-}
-
-static SVGLengthValue parseLengthFromString(SVGAnimationElement* animationElement, const String& string)
-{
-    SVGLengthValue length;
-    length.setValueAsString(string, SVGLengthValue::lengthModeForAnimatedLengthAttribute(animationElement->attributeName()));
-    return length;
-}
-
-void SVGAnimatedLengthAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated)
-{
-    ASSERT(m_animationElement);
-    ASSERT(m_contextElement);
-
-    auto fromSVGLength = (m_animationElement->animationMode() == AnimationMode::To ? animated : from)->as<SVGLengthValue>();
-    auto toSVGLength = to->as<SVGLengthValue>();
-    const auto& toAtEndOfDurationSVGLength = toAtEndOfDuration->as<SVGLengthValue>();
-    auto& animatedSVGLength = animated->as<SVGLengthValue>();
-
-    // Apply CSS inheritance rules.
-    m_animationElement->adjustForInheritance<SVGLengthValue>(parseLengthFromString, m_animationElement->fromPropertyValueType(), fromSVGLength, m_contextElement);
-    m_animationElement->adjustForInheritance<SVGLengthValue>(parseLengthFromString, m_animationElement->toPropertyValueType(), toSVGLength, m_contextElement);
-
-    SVGLengthContext lengthContext(m_contextElement);
-    float animatedNumber = animatedSVGLength.value(lengthContext);
-    SVGLengthType unitType = percentage < 0.5 ? fromSVGLength.unitType() : toSVGLength.unitType();
-    m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromSVGLength.value(lengthContext), toSVGLength.value(lengthContext), toAtEndOfDurationSVGLength.value(lengthContext), animatedNumber);
-
-    animatedSVGLength.setValue(lengthContext, animatedNumber, m_lengthMode, unitType);
-}
-
-float SVGAnimatedLengthAnimator::calculateDistance(const String& fromString, const String& toString)
-{
-    ASSERT(m_animationElement);
-    ASSERT(m_contextElement);
-    auto lengthMode = SVGLengthValue::lengthModeForAnimatedLengthAttribute(m_animationElement->attributeName());
-    auto from = SVGLengthValue(lengthMode, fromString);
-    auto to = SVGLengthValue(lengthMode, toString);
-    SVGLengthContext lengthContext(m_contextElement);
-    return fabsf(to.value(lengthContext) - from.value(lengthContext));
-}
-
-}
diff --git a/Source/WebCore/svg/SVGAnimatedLength.h b/Source/WebCore/svg/SVGAnimatedLength.h
deleted file mode 100644 (file)
index 1004ec5..0000000
+++ /dev/null
@@ -1,57 +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 "SVGAnimatedPropertyTearOff.h"
-#include "SVGAnimatedTypeAnimator.h"
-#include "SVGAttributeAccessor.h"
-#include "SVGLength.h"
-
-namespace WebCore {
-
-class SVGAnimationElement;
-
-using SVGAnimatedLength = SVGAnimatedPropertyTearOff<SVGLength>;
-using SVGAnimatedLengthAttribute = SVGAnimatedAttribute<SVGAnimatedLength>;
-
-template<typename OwnerType>
-using SVGAnimatedLengthAttributeAccessor = SVGAnimatedAttributeAccessor<OwnerType, SVGAnimatedLengthAttribute, AnimatedLength>;
-
-class SVGAnimatedLengthAnimator final : public SVGAnimatedTypeAnimator {
-public:
-    SVGAnimatedLengthAnimator(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;
-
-private:
-    SVGLengthMode m_lengthMode;
-};
-
-} // namespace WebCore
diff --git a/Source/WebCore/svg/SVGAnimatedLengthList.cpp b/Source/WebCore/svg/SVGAnimatedLengthList.cpp
deleted file mode 100644 (file)
index 3a7ddff..0000000
+++ /dev/null
@@ -1,131 +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.
- */
-
-#include "config.h"
-#include "SVGAnimatedLengthList.h"
-
-#include "SVGAnimateElementBase.h"
-
-namespace WebCore {
-
-SVGAnimatedLengthListAnimator::SVGAnimatedLengthListAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement)
-    : SVGAnimatedTypeAnimator(AnimatedLengthList, animationElement, contextElement)
-    , m_lengthMode(SVGLengthValue::lengthModeForAnimatedLengthAttribute(animationElement->attributeName()))
-{
-}
-
-std::unique_ptr<SVGAnimatedType> SVGAnimatedLengthListAnimator::constructFromString(const String& string)
-{
-    return SVGAnimatedType::create(SVGPropertyTraits<SVGLengthListValues>::fromString(string, m_lengthMode));
-}
-
-std::unique_ptr<SVGAnimatedType> SVGAnimatedLengthListAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
-    return constructFromBaseValue<SVGAnimatedLengthList>(animatedTypes);
-}
-
-void SVGAnimatedLengthListAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
-    stopAnimValAnimationForType<SVGAnimatedLengthList>(animatedTypes);
-}
-
-void SVGAnimatedLengthListAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType& type)
-{
-    resetFromBaseValue<SVGAnimatedLengthList>(animatedTypes, type);
-}
-
-void SVGAnimatedLengthListAnimator::animValWillChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
-    animValWillChangeForType<SVGAnimatedLengthList>(animatedTypes);
-}
-
-void SVGAnimatedLengthListAnimator::animValDidChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
-    animValDidChangeForType<SVGAnimatedLengthList>(animatedTypes);
-}
-
-void SVGAnimatedLengthListAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimatedType* to)
-{
-    ASSERT(from->type() == AnimatedLengthList);
-    ASSERT(from->type() == to->type());
-
-    const auto& fromLengthList = from->as<SVGLengthListValues>();
-    auto& toLengthList = to->as<SVGLengthListValues>();
-
-    unsigned fromLengthListSize = fromLengthList.size();
-    if (!fromLengthListSize || fromLengthListSize != toLengthList.size())
-        return;
-
-    SVGLengthContext lengthContext(m_contextElement);
-    for (unsigned i = 0; i < fromLengthListSize; ++i)
-        toLengthList[i].setValue(toLengthList[i].value(lengthContext) + fromLengthList[i].value(lengthContext), lengthContext);
-}
-
-static SVGLengthListValues parseLengthListFromString(SVGAnimationElement* animationElement, const String& string)
-{
-    SVGLengthListValues lengthList;
-    lengthList.parse(string, SVGLengthValue::lengthModeForAnimatedLengthAttribute(animationElement->attributeName()));
-    return lengthList;
-}
-
-void SVGAnimatedLengthListAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated)
-{
-    ASSERT(m_animationElement);
-    ASSERT(m_contextElement);
-
-    auto fromLengthList = (m_animationElement->animationMode() == AnimationMode::To ? animated : from)->as<SVGLengthListValues>();
-    auto toLengthList = to->as<SVGLengthListValues>();
-    const auto& toAtEndOfDurationLengthList = toAtEndOfDuration->as<SVGLengthListValues>();
-    auto& animatedLengthList = animated->as<SVGLengthListValues>();
-
-    // Apply CSS inheritance rules.
-    m_animationElement->adjustForInheritance<SVGLengthListValues>(parseLengthListFromString, m_animationElement->fromPropertyValueType(), fromLengthList, m_contextElement);
-    m_animationElement->adjustForInheritance<SVGLengthListValues>(parseLengthListFromString, m_animationElement->toPropertyValueType(), toLengthList, m_contextElement);
-
-    if (!m_animationElement->adjustFromToListValues<SVGLengthListValues>(fromLengthList, toLengthList, animatedLengthList, percentage))
-        return;
-
-    unsigned fromLengthListSize = fromLengthList.size();
-    unsigned toLengthListSize = toLengthList.size();
-    unsigned toAtEndOfDurationListSize = toAtEndOfDurationLengthList.size();
-
-    SVGLengthContext lengthContext(m_contextElement);
-    for (unsigned i = 0; i < toLengthListSize; ++i) {
-        float animatedNumber = animatedLengthList[i].value(lengthContext);
-        SVGLengthType unitType = toLengthList[i].unitType();
-        float effectiveFrom = 0;
-        if (fromLengthListSize) {
-            if (percentage < 0.5)
-                unitType = fromLengthList[i].unitType();
-            effectiveFrom = fromLengthList[i].value(lengthContext);
-        }
-        float effectiveToAtEnd = i < toAtEndOfDurationListSize ? toAtEndOfDurationLengthList[i].value(lengthContext) : 0;
-
-        m_animationElement->animateAdditiveNumber(percentage, repeatCount, effectiveFrom, toLengthList[i].value(lengthContext), effectiveToAtEnd, animatedNumber);
-        animatedLengthList[i].setValue(lengthContext, animatedNumber, m_lengthMode, unitType);
-    }
-}
-
-float SVGAnimatedLengthListAnimator::calculateDistance(const String&, const String&)
-{
-    // FIXME: Distance calculation is not possible for SVGLengthListValues right now. We need the distance for every single value.
-    return -1;
-}
-
-}
diff --git a/Source/WebCore/svg/SVGAnimatedLengthList.h b/Source/WebCore/svg/SVGAnimatedLengthList.h
deleted file mode 100644 (file)
index 165bc48..0000000
+++ /dev/null
@@ -1,58 +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 "SVGAnimatedListPropertyTearOff.h"
-#include "SVGAnimatedTypeAnimator.h"
-#include "SVGAttributeAccessor.h"
-#include "SVGLength.h"
-#include "SVGLengthList.h"
-
-namespace WebCore {
-
-class SVGAnimationElement;
-
-using SVGAnimatedLengthList = SVGAnimatedListPropertyTearOff<SVGLengthListValues>;
-using SVGAnimatedLengthListAttribute = SVGAnimatedAttributeList<SVGAnimatedLengthList>;
-
-template<typename OwnerType>
-using SVGAnimatedLengthListAttributeAccessor = SVGAnimatedAttributeAccessor<OwnerType, SVGAnimatedLengthListAttribute, AnimatedLengthList>;
-
-class SVGAnimatedLengthListAnimator final : public SVGAnimatedTypeAnimator {
-public:
-    SVGAnimatedLengthListAnimator(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;
-
-private:
-    SVGLengthMode m_lengthMode;
-};
-
-} // namespace WebCore
index a119d31..85dfc04 100644 (file)
@@ -81,8 +81,6 @@ public:
     AnimatedPropertyType type() const
     {
         static AnimatedPropertyType animatedTypes[] = {
-            AnimatedLength,
-            AnimatedLengthList,
             AnimatedPath,
             AnimatedTransformList
         };
index 2982c43..26dd3a4 100644 (file)
@@ -336,13 +336,9 @@ bool SVGAnimationElement::isAccumulated() const
     return value == sum && animationMode() != AnimationMode::To;
 }
 
-bool SVGAnimationElement::isTargetAttributeCSSProperty(SVGElement* element, const QualifiedName& attributeName)
+bool SVGAnimationElement::isTargetAttributeCSSProperty(SVGElement* targetElement, const QualifiedName& attributeName)
 {
-    if (element->isTextContent()
-        && (attributeName == SVGNames::xAttr || attributeName == SVGNames::yAttr))
-        return false;
-
-    return SVGElement::isAnimatableCSSProperty(attributeName);
+    return targetElement->isAnimatedStyleAttribute(attributeName);
 }
 
 SVGAnimationElement::ShouldApplyAnimation SVGAnimationElement::shouldApplyAnimation(SVGElement* targetElement, const QualifiedName& attributeName)
@@ -645,13 +641,13 @@ void SVGAnimationElement::adjustForInheritance(SVGElement* targetElement, const
     computeCSSPropertyValue(&svgParent, cssPropertyID(attributeName.localName()), value);
 }
 
-static bool inheritsFromProperty(SVGElement*, const QualifiedName& attributeName, const String& value)
+static bool inheritsFromProperty(SVGElement* targetElement, const QualifiedName& attributeName, const String& value)
 {
     static NeverDestroyed<const AtomicString> inherit("inherit", AtomicString::ConstructFromLiteral);
     
     if (value.isEmpty() || value != inherit)
         return false;
-    return SVGElement::isAnimatableCSSProperty(attributeName);
+    return targetElement->isAnimatedStyleAttribute(attributeName);
 }
 
 void SVGAnimationElement::determinePropertyValueTypes(const String& from, const String& to)
index 948ea74..19e50c4 100644 (file)
@@ -19,8 +19,6 @@
 
 #pragma once
 
-#include "SVGAnimatedLength.h"
-#include "SVGAnimatedLengthList.h"
 #include "SVGAnimatedPath.h"
 #include "SVGAnimatedTransformList.h"
 
@@ -30,6 +28,33 @@ class SVGAnimationElement;
 
 class SVGAnimatorFactory {
 public:
+    static bool isSupportedAttributeType(AnimatedPropertyType attributeType)
+    {
+        switch (attributeType) {
+        case AnimatedAngle:
+        case AnimatedBoolean:
+        case AnimatedColor:
+        case AnimatedEnumeration:
+        case AnimatedInteger:
+        case AnimatedIntegerOptionalInteger:
+        case AnimatedLength:
+        case AnimatedLengthList:
+        case AnimatedNumber:
+        case AnimatedNumberList:
+        case AnimatedNumberOptionalNumber:
+        case AnimatedPoints:
+        case AnimatedPreserveAspectRatio:
+        case AnimatedRect:
+        case AnimatedString:
+        case AnimatedUnknown:
+            return false;
+
+        case AnimatedPath:
+        case AnimatedTransformList:
+            return true;
+        }
+    }
+
     static std::unique_ptr<SVGAnimatedTypeAnimator> create(SVGAnimationElement* animationElement, SVGElement* contextElement, AnimatedPropertyType attributeType)
     {
         ASSERT(animationElement);
@@ -42,6 +67,8 @@ public:
         case AnimatedEnumeration:
         case AnimatedInteger:
         case AnimatedIntegerOptionalInteger:
+        case AnimatedLength:
+        case AnimatedLengthList:
         case AnimatedNumber:
         case AnimatedNumberList:
         case AnimatedNumberOptionalNumber:
@@ -49,18 +76,13 @@ public:
         case AnimatedPreserveAspectRatio:
         case AnimatedRect:
         case AnimatedString:
-            return nullptr;
+        case AnimatedUnknown:
+            break;
 
-        case AnimatedLength:
-            return std::make_unique<SVGAnimatedLengthAnimator>(animationElement, contextElement);
-        case AnimatedLengthList:
-            return std::make_unique<SVGAnimatedLengthListAnimator>(animationElement, contextElement);
         case AnimatedPath:
             return std::make_unique<SVGAnimatedPathAnimator>(animationElement, contextElement);
         case AnimatedTransformList:
             return std::make_unique<SVGAnimatedTransformListAnimator>(animationElement, contextElement);
-        case AnimatedUnknown:
-            break;
         }
 
         ASSERT_NOT_REACHED();
index ef3daa6..0be6827 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org>
  * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
- * 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
@@ -35,7 +35,13 @@ inline SVGCircleElement::SVGCircleElement(const QualifiedName& tagName, Document
     , SVGExternalResourcesRequired(this)
 {
     ASSERT(hasTagName(SVGNames::circleTag));
-    registerAttributes();
+
+    static std::once_flag onceFlag;
+    std::call_once(onceFlag, [] {
+        PropertyRegistry::registerProperty<SVGNames::cxAttr, &SVGCircleElement::m_cx>();
+        PropertyRegistry::registerProperty<SVGNames::cyAttr, &SVGCircleElement::m_cy>();
+        PropertyRegistry::registerProperty<SVGNames::rAttr, &SVGCircleElement::m_r>();
+    });
 }
 
 Ref<SVGCircleElement> SVGCircleElement::create(const QualifiedName& tagName, Document& document)
@@ -43,26 +49,16 @@ Ref<SVGCircleElement> SVGCircleElement::create(const QualifiedName& tagName, Doc
     return adoptRef(*new SVGCircleElement(tagName, document));
 }
 
-void SVGCircleElement::registerAttributes()
-{
-    auto& registry = attributeRegistry();
-    if (!registry.isEmpty())
-        return;
-    registry.registerAttribute<SVGNames::cxAttr, &SVGCircleElement::m_cx>();
-    registry.registerAttribute<SVGNames::cyAttr, &SVGCircleElement::m_cy>();
-    registry.registerAttribute<SVGNames::rAttr, &SVGCircleElement::m_r>();
-}
-
 void SVGCircleElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     SVGParsingError parseError = NoError;
 
     if (name == SVGNames::cxAttr)
-        m_cx.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError));
+        m_cx->setBaseValInternal(SVGLengthValue::construct(LengthModeWidth, value, parseError));
     else if (name == SVGNames::cyAttr)
-        m_cy.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError));
+        m_cy->setBaseValInternal(SVGLengthValue::construct(LengthModeHeight, value, parseError));
     else if (name == SVGNames::rAttr)
-        m_r.setValue(SVGLengthValue::construct(LengthModeOther, value, parseError, ForbidNegativeLengths));
+        m_r->setBaseValInternal(SVGLengthValue::construct(LengthModeOther, value, parseError, ForbidNegativeLengths));
 
     reportAttributeParsingError(parseError, name, value);
 
@@ -72,7 +68,7 @@ void SVGCircleElement::parseAttribute(const QualifiedName& name, const AtomicStr
 
 void SVGCircleElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    if (isKnownAttribute(attrName)) {
+    if (PropertyRegistry::isKnownAttribute(attrName)) {
         InstanceInvalidationGuard guard(*this);
         invalidateSVGPresentationAttributeStyle();
         return;
index 5fe063b..93cd60d 100644 (file)
@@ -21,7 +21,6 @@
 
 #pragma once
 
-#include "SVGAnimatedLength.h"
 #include "SVGExternalResourcesRequired.h"
 #include "SVGGeometryElement.h"
 #include "SVGNames.h"
@@ -33,30 +32,23 @@ class SVGCircleElement final : public SVGGeometryElement, public SVGExternalReso
 public:
     static Ref<SVGCircleElement> create(const QualifiedName&, Document&);
 
-    const SVGLengthValue& cx() const { return m_cx.currentValue(attributeOwnerProxy()); }
-    const SVGLengthValue& cy() const { return m_cy.currentValue(attributeOwnerProxy()); }
-    const SVGLengthValue& r() const { return m_r.currentValue(attributeOwnerProxy()); }
+    const SVGLengthValue& cx() const { return m_cx->currentValue(); }
+    const SVGLengthValue& cy() const { return m_cy->currentValue(); }
+    const SVGLengthValue& r() const { return m_r->currentValue(); }
 
-    RefPtr<SVGAnimatedLength> cxAnimated() { return m_cx.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedLength> cyAnimated() { return m_cy.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedLength> rAnimated() { return m_r.animatedProperty(attributeOwnerProxy()); }
+    SVGAnimatedLength& cxAnimated() { return m_cx; }
+    SVGAnimatedLength& cyAnimated() { return m_cy; }
+    SVGAnimatedLength& rAnimated() { return m_r; }
 
 private:
     SVGCircleElement(const QualifiedName&, Document&);
 
     using AttributeOwnerProxy = SVGAttributeOwnerProxyImpl<SVGCircleElement, SVGGeometryElement, SVGExternalResourcesRequired>;
-    static auto& attributeRegistry() { return AttributeOwnerProxy::attributeRegistry(); }
-    static void registerAttributes();
     const SVGAttributeOwnerProxy& attributeOwnerProxy() const final { return m_attributeOwnerProxy; }
 
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGCircleElement, SVGGeometryElement, 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;
 
@@ -67,9 +59,9 @@ private:
 
     AttributeOwnerProxy m_attributeOwnerProxy { *this };
     PropertyRegistry m_propertyRegistry { *this };
-    SVGAnimatedLengthAttribute m_cx { LengthModeWidth };
-    SVGAnimatedLengthAttribute m_cy { LengthModeHeight };
-    SVGAnimatedLengthAttribute m_r { LengthModeOther };
+    Ref<SVGAnimatedLength> m_cx { SVGAnimatedLength::create(this, LengthModeWidth) };
+    Ref<SVGAnimatedLength> m_cy { SVGAnimatedLength::create(this, LengthModeHeight) };
+    Ref<SVGAnimatedLength> m_r { SVGAnimatedLength::create(this, LengthModeOther) };
 };
 
 } // namespace WebCore
index cd808c9..d20a3a4 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org>
  * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
- * 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
@@ -40,7 +40,12 @@ inline SVGCursorElement::SVGCursorElement(const QualifiedName& tagName, Document
     , SVGURIReference(this)
 {
     ASSERT(hasTagName(SVGNames::cursorTag));
-    registerAttributes();
+
+    static std::once_flag onceFlag;
+    std::call_once(onceFlag, [] {
+        PropertyRegistry::registerProperty<SVGNames::xAttr, &SVGCursorElement::m_x>();
+        PropertyRegistry::registerProperty<SVGNames::yAttr, &SVGCursorElement::m_y>();
+    });
 }
 
 Ref<SVGCursorElement> SVGCursorElement::create(const QualifiedName& tagName, Document& document)
@@ -54,23 +59,14 @@ SVGCursorElement::~SVGCursorElement()
         client->cursorElementRemoved(*this);
 }
 
-void SVGCursorElement::registerAttributes()
-{
-    auto& registry = attributeRegistry();
-    if (!registry.isEmpty())
-        return;
-    registry.registerAttribute<SVGNames::xAttr, &SVGCursorElement::m_x>();
-    registry.registerAttribute<SVGNames::yAttr, &SVGCursorElement::m_y>();
-}
-
 void SVGCursorElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     SVGParsingError parseError = NoError;
 
     if (name == SVGNames::xAttr)
-        m_x.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError));
+        m_x->setBaseValInternal(SVGLengthValue::construct(LengthModeWidth, value, parseError));
     else if (name == SVGNames::yAttr)
-        m_y.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError));
+        m_y->setBaseValInternal(SVGLengthValue::construct(LengthModeHeight, value, parseError));
 
     reportAttributeParsingError(parseError, name, value);
 
@@ -92,7 +88,7 @@ void SVGCursorElement::removeClient(CSSCursorImageValue& value)
 
 void SVGCursorElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    if (isKnownAttribute(attrName)) {
+    if (PropertyRegistry::isKnownAttribute(attrName)) {
         InstanceInvalidationGuard guard(*this);
         for (auto& client : m_clients)
             client->cursorElementChanged(*this);
index 6451ece..e12f24c 100644 (file)
@@ -21,7 +21,6 @@
 
 #pragma once
 
-#include "SVGAnimatedLength.h"
 #include "SVGElement.h"
 #include "SVGExternalResourcesRequired.h"
 #include "SVGTests.h"
@@ -41,28 +40,21 @@ public:
     void addClient(CSSCursorImageValue&);
     void removeClient(CSSCursorImageValue&);
 
-    const SVGLengthValue& x() const { return m_x.currentValue(attributeOwnerProxy()); }
-    const SVGLengthValue& y() const { return m_y.currentValue(attributeOwnerProxy()); }
+    const SVGLengthValue& x() const { return m_x->currentValue(); }
+    const SVGLengthValue& y() const { return m_y->currentValue(); }
 
-    RefPtr<SVGAnimatedLength> xAnimated() { return m_x.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedLength> yAnimated() { return m_y.animatedProperty(attributeOwnerProxy()); }
+    SVGAnimatedLength& xAnimated() { return m_x; }
+    SVGAnimatedLength& yAnimated() { return m_y; }
 
 private:
     SVGCursorElement(const QualifiedName&, Document&);
 
     using AttributeOwnerProxy = SVGAttributeOwnerProxyImpl<SVGCursorElement, SVGElement, SVGExternalResourcesRequired, SVGTests, SVGURIReference>;
-    static AttributeOwnerProxy::AttributeRegistry& attributeRegistry() { return AttributeOwnerProxy::attributeRegistry(); }
-    static void registerAttributes();
     const SVGAttributeOwnerProxy& attributeOwnerProxy() const final { return m_attributeOwnerProxy; }
 
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGCursorElement, SVGElement, SVGExternalResourcesRequired, SVGTests, SVGURIReference>;
     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;
 
@@ -73,8 +65,8 @@ private:
 
     AttributeOwnerProxy m_attributeOwnerProxy { *this };
     PropertyRegistry m_propertyRegistry { *this };
-    SVGAnimatedLengthAttribute m_x { LengthModeWidth };
-    SVGAnimatedLengthAttribute m_y { LengthModeHeight };
+    Ref<SVGAnimatedLength> m_x { SVGAnimatedLength::create(this, LengthModeWidth) };
+    Ref<SVGAnimatedLength> m_y { SVGAnimatedLength::create(this, LengthModeHeight) };
     HashSet<CSSCursorImageValue*> m_clients;
 };
 
index 1cebfb3..aa10e82 100644 (file)
@@ -762,6 +762,11 @@ bool SVGElement::isAnimatedAttribute(const QualifiedName& attributeName) const
     return SVGPropertyAnimatorFactory::isKnownAttribute(attributeName) || isAnimatedPropertyAttribute(attributeName);
 }
 
+bool SVGElement::isAnimatedStyleAttribute(const QualifiedName& attributeName) const
+{
+    return SVGPropertyAnimatorFactory::isKnownAttribute(attributeName) || propertyRegistry().isAnimatedStylePropertyAttribute(attributeName);
+}
+
 std::unique_ptr<SVGAttributeAnimator> SVGElement::createAnimator(const QualifiedName& attributeName, AnimationMode animationMode, CalcMode calcMode, bool isAccumulated, bool isAdditive)
 {
     // Property animator, e.g. "fill" or "fill-opacity".
index 0f75e90..e82bdba 100644 (file)
@@ -156,6 +156,7 @@ public:
 
     bool isAnimatedPropertyAttribute(const QualifiedName&) const;
     bool isAnimatedAttribute(const QualifiedName&) const;
+    bool isAnimatedStyleAttribute(const QualifiedName&) const;
 
     void commitPropertyChange(SVGProperty*) override;
     void commitPropertyChange(SVGAnimatedProperty&);
index 0a54b18..23e4ada 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org>
  * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
- * 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
@@ -35,7 +35,14 @@ inline SVGEllipseElement::SVGEllipseElement(const QualifiedName& tagName, Docume
     , SVGExternalResourcesRequired(this)
 {
     ASSERT(hasTagName(SVGNames::ellipseTag));
-    registerAttributes();
+
+    static std::once_flag onceFlag;
+    std::call_once(onceFlag, [] {
+        PropertyRegistry::registerProperty<SVGNames::cxAttr, &SVGEllipseElement::m_cx>();
+        PropertyRegistry::registerProperty<SVGNames::cyAttr, &SVGEllipseElement::m_cy>();
+        PropertyRegistry::registerProperty<SVGNames::rxAttr, &SVGEllipseElement::m_rx>();
+        PropertyRegistry::registerProperty<SVGNames::ryAttr, &SVGEllipseElement::m_ry>();
+    });
 }    
 
 Ref<SVGEllipseElement> SVGEllipseElement::create(const QualifiedName& tagName, Document& document)
@@ -43,29 +50,18 @@ Ref<SVGEllipseElement> SVGEllipseElement::create(const QualifiedName& tagName, D
     return adoptRef(*new SVGEllipseElement(tagName, document));
 }
 
-void SVGEllipseElement::registerAttributes()
-{
-    auto& registry = attributeRegistry();
-    if (!registry.isEmpty())
-        return;
-    registry.registerAttribute<SVGNames::cxAttr, &SVGEllipseElement::m_cx>();
-    registry.registerAttribute<SVGNames::cyAttr, &SVGEllipseElement::m_cy>();
-    registry.registerAttribute<SVGNames::rxAttr, &SVGEllipseElement::m_rx>();
-    registry.registerAttribute<SVGNames::ryAttr, &SVGEllipseElement::m_ry>();
-}
-
 void SVGEllipseElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     SVGParsingError parseError = NoError;
 
     if (name == SVGNames::cxAttr)
-        m_cx.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError));
+        m_cx->setBaseValInternal(SVGLengthValue::construct(LengthModeWidth, value, parseError));
     else if (name == SVGNames::cyAttr)
-        m_cy.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError));
+        m_cy->setBaseValInternal(SVGLengthValue::construct(LengthModeHeight, value, parseError));
     else if (name == SVGNames::rxAttr)
-        m_rx.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths));
+        m_rx->setBaseValInternal(SVGLengthValue::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths));
     else if (name == SVGNames::ryAttr)
-        m_ry.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths));
+        m_ry->setBaseValInternal(SVGLengthValue::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths));
 
     reportAttributeParsingError(parseError, name, value);
 
@@ -75,7 +71,7 @@ void SVGEllipseElement::parseAttribute(const QualifiedName& name, const AtomicSt
 
 void SVGEllipseElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    if (isKnownAttribute(attrName)) {
+    if (PropertyRegistry::isKnownAttribute(attrName)) {
         InstanceInvalidationGuard guard(*this);
         invalidateSVGPresentationAttributeStyle();
         return;
index 3c9bcfc..712a388 100644 (file)
@@ -21,7 +21,6 @@
 
 #pragma once
 
-#include "SVGAnimatedLength.h"
 #include "SVGExternalResourcesRequired.h"
 #include "SVGGeometryElement.h"
 #include "SVGNames.h"
@@ -33,32 +32,25 @@ class SVGEllipseElement final : public SVGGeometryElement, public SVGExternalRes
 public:
     static Ref<SVGEllipseElement> create(const QualifiedName&, Document&);
 
-    const SVGLengthValue& cx() const { return m_cx.currentValue(attributeOwnerProxy()); }
-    const SVGLengthValue& cy() const { return m_cy.currentValue(attributeOwnerProxy()); }
-    const SVGLengthValue& rx() const { return m_rx.currentValue(attributeOwnerProxy()); }
-    const SVGLengthValue& ry() const { return m_ry.currentValue(attributeOwnerProxy()); }
+    const SVGLengthValue& cx() const { return m_cx->currentValue(); }
+    const SVGLengthValue& cy() const { return m_cy->currentValue(); }
+    const SVGLengthValue& rx() const { return m_rx->currentValue(); }
+    const SVGLengthValue& ry() const { return m_ry->currentValue(); }
 
-    RefPtr<SVGAnimatedLength> cxAnimated() { return m_cx.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedLength> cyAnimated() { return m_cy.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedLength> rxAnimated() { return m_rx.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedLength> ryAnimated() { return m_ry.animatedProperty(attributeOwnerProxy()); }
+    SVGAnimatedLength& cxAnimated() { return m_cx; }
+    SVGAnimatedLength& cyAnimated() { return m_cy; }
+    SVGAnimatedLength& rxAnimated() { return m_rx; }
+    SVGAnimatedLength& ryAnimated() { return m_ry; }
 
 private:
     SVGEllipseElement(const QualifiedName&, Document&);
 
     using AttributeOwnerProxy = SVGAttributeOwnerProxyImpl<SVGEllipseElement, SVGGeometryElement, SVGExternalResourcesRequired>;
-    static AttributeOwnerProxy::AttributeRegistry& attributeRegistry() { return AttributeOwnerProxy::attributeRegistry(); }
-    static void registerAttributes();
     const SVGAttributeOwnerProxy& attributeOwnerProxy() const final { return m_attributeOwnerProxy; }
     
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGEllipseElement, SVGGeometryElement, 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;
 
@@ -69,10 +61,10 @@ private:
 
     AttributeOwnerProxy m_attributeOwnerProxy { *this };
     PropertyRegistry m_propertyRegistry { *this };
-    SVGAnimatedLengthAttribute m_cx { LengthModeWidth };
-    SVGAnimatedLengthAttribute m_cy { LengthModeHeight };
-    SVGAnimatedLengthAttribute m_rx { LengthModeWidth };
-    SVGAnimatedLengthAttribute m_ry { LengthModeHeight };
+    Ref<SVGAnimatedLength> m_cx { SVGAnimatedLength::create(this, LengthModeWidth) };
+    Ref<SVGAnimatedLength> m_cy { SVGAnimatedLength::create(this, LengthModeHeight) };
+    Ref<SVGAnimatedLength> m_rx { SVGAnimatedLength::create(this, LengthModeWidth) };
+    Ref<SVGAnimatedLength> m_ry { SVGAnimatedLength::create(this, LengthModeHeight) };
 };
 
 } // namespace WebCore
index b994301..7655c07 100644 (file)
@@ -46,12 +46,15 @@ inline SVGFilterElement::SVGFilterElement(const QualifiedName& tagName, Document
     // Spec: If the x/y attribute is not specified, the effect is as if a value of "-10%" were specified.
     // 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>();
+        PropertyRegistry::registerProperty<SVGNames::xAttr, &SVGFilterElement::m_x>();
+        PropertyRegistry::registerProperty<SVGNames::yAttr, &SVGFilterElement::m_y>();
+        PropertyRegistry::registerProperty<SVGNames::widthAttr, &SVGFilterElement::m_width>();
+        PropertyRegistry::registerProperty<SVGNames::heightAttr, &SVGFilterElement::m_height>();
     });
 }
 
@@ -60,17 +63,6 @@ Ref<SVGFilterElement> SVGFilterElement::create(const QualifiedName& tagName, Doc
     return adoptRef(*new SVGFilterElement(tagName, document));
 }
 
-void SVGFilterElement::registerAttributes()
-{
-    auto& registry = attributeRegistry();
-    if (!registry.isEmpty())
-        return;
-    registry.registerAttribute<SVGNames::xAttr, &SVGFilterElement::m_x>();
-    registry.registerAttribute<SVGNames::yAttr, &SVGFilterElement::m_y>();
-    registry.registerAttribute<SVGNames::widthAttr, &SVGFilterElement::m_width>();
-    registry.registerAttribute<SVGNames::heightAttr, &SVGFilterElement::m_height>();
-}
-
 void SVGFilterElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     SVGParsingError parseError = NoError;
@@ -84,13 +76,13 @@ void SVGFilterElement::parseAttribute(const QualifiedName& name, const AtomicStr
         if (propertyValue > 0)
             m_primitiveUnits->setBaseValInternal<SVGUnitTypes::SVGUnitType>(propertyValue);
     } else if (name == SVGNames::xAttr)
-        m_x.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError));
+        m_x->setBaseValInternal(SVGLengthValue::construct(LengthModeWidth, value, parseError));
     else if (name == SVGNames::yAttr)
-        m_y.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError));
+        m_y->setBaseValInternal(SVGLengthValue::construct(LengthModeHeight, value, parseError));
     else if (name == SVGNames::widthAttr)
-        m_width.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError));
+        m_width->setBaseValInternal(SVGLengthValue::construct(LengthModeWidth, value, parseError));
     else if (name == SVGNames::heightAttr)
-        m_height.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError));
+        m_height->setBaseValInternal(SVGLengthValue::construct(LengthModeHeight, value, parseError));
 
     reportAttributeParsingError(parseError, name, value);
 
@@ -101,13 +93,13 @@ void SVGFilterElement::parseAttribute(const QualifiedName& name, const AtomicStr
 
 void SVGFilterElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    if (isAnimatedLengthAttribute(attrName)) {
+    if (PropertyRegistry::isAnimatedLengthAttribute(attrName)) {
         InstanceInvalidationGuard guard(*this);
         invalidateSVGPresentationAttributeStyle();
         return;
     }
 
-    if (isKnownAttribute(attrName) || SVGURIReference::isKnownAttribute(attrName)) {
+    if (PropertyRegistry::isKnownAttribute(attrName) || SVGURIReference::isKnownAttribute(attrName)) {
         if (auto* renderer = this->renderer())
             renderer->setNeedsLayout();
         return;
index 9f8fb30..1a76bd0 100644 (file)
@@ -23,7 +23,6 @@
 
 #pragma once
 
-#include "SVGAnimatedLength.h"
 #include "SVGElement.h"
 #include "SVGExternalResourcesRequired.h"
 #include "SVGURIReference.h"
@@ -38,36 +37,27 @@ public:
 
     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()); }
+    const SVGLengthValue& x() const { return m_x->currentValue(); }
+    const SVGLengthValue& y() const { return m_y->currentValue(); }
+    const SVGLengthValue& width() const { return m_width->currentValue(); }
+    const SVGLengthValue& height() const { return m_height->currentValue(); }
 
     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()); }
-    RefPtr<SVGAnimatedLength> heightAnimated() { return m_height.animatedProperty(attributeOwnerProxy()); }
+    SVGAnimatedLength& xAnimated() { return m_x; }
+    SVGAnimatedLength& yAnimated() { return m_y; }
+    SVGAnimatedLength& widthAnimated() { return m_width; }
+    SVGAnimatedLength& heightAnimated() { return m_height; }
 
 private:
     SVGFilterElement(const QualifiedName&, Document&);
 
     using AttributeOwnerProxy = SVGAttributeOwnerProxyImpl<SVGFilterElement, SVGElement, SVGExternalResourcesRequired, SVGURIReference>;
-    static AttributeOwnerProxy::AttributeRegistry& attributeRegistry() { return AttributeOwnerProxy::attributeRegistry(); }
-    static void registerAttributes();
     const SVGAttributeOwnerProxy& attributeOwnerProxy() const final { return m_attributeOwnerProxy; }
 
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGFilterElement, SVGElement, SVGExternalResourcesRequired, SVGURIReference>;
     const SVGPropertyRegistry& propertyRegistry() const final { return m_propertyRegistry; }
 
-    static bool isKnownAttribute(const QualifiedName& attributeName)
-    {
-        return AttributeOwnerProxy::isKnownAttribute(attributeName) || PropertyRegistry::isKnownAttribute(attributeName);
-    }
-
-    static bool isAnimatedLengthAttribute(const QualifiedName& attributeName) { return AttributeOwnerProxy::isAnimatedLengthAttribute(attributeName); }
-
     void parseAttribute(const QualifiedName&, const AtomicString&) final;
     void svgAttributeChanged(const QualifiedName&) final;
     void childrenChanged(const ChildChange&) final;
@@ -83,10 +73,10 @@ private:
     PropertyRegistry m_propertyRegistry { *this };
     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%" };
-    SVGAnimatedLengthAttribute m_height { LengthModeHeight, "120%" };
+    Ref<SVGAnimatedLength> m_x { SVGAnimatedLength::create(this, LengthModeWidth, "-10%") };
+    Ref<SVGAnimatedLength> m_y { SVGAnimatedLength::create(this, LengthModeHeight, "-10%") };
+    Ref<SVGAnimatedLength> m_width { SVGAnimatedLength::create(this, LengthModeWidth, "120%") };
+    Ref<SVGAnimatedLength> m_height { SVGAnimatedLength::create(this, LengthModeHeight, "120%") };
 };
 
 } // namespace WebCore
index 75fede3..35cec9c 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
  * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org>
  * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
- * 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
@@ -36,37 +36,28 @@ WTF_MAKE_ISO_ALLOCATED_IMPL(SVGFilterPrimitiveStandardAttributes);
 SVGFilterPrimitiveStandardAttributes::SVGFilterPrimitiveStandardAttributes(const QualifiedName& tagName, Document& document)
     : SVGElement(tagName, document)
 {
-    registerAttributes();
-
     static std::once_flag onceFlag;
     std::call_once(onceFlag, [] {
+        PropertyRegistry::registerProperty<SVGNames::xAttr, &SVGFilterPrimitiveStandardAttributes::m_x>();
+        PropertyRegistry::registerProperty<SVGNames::yAttr, &SVGFilterPrimitiveStandardAttributes::m_y>();
+        PropertyRegistry::registerProperty<SVGNames::widthAttr, &SVGFilterPrimitiveStandardAttributes::m_width>();
+        PropertyRegistry::registerProperty<SVGNames::heightAttr, &SVGFilterPrimitiveStandardAttributes::m_height>();
         PropertyRegistry::registerProperty<SVGNames::resultAttr, &SVGFilterPrimitiveStandardAttributes::m_result>();
     });
 }
 
-void SVGFilterPrimitiveStandardAttributes::registerAttributes()
-{
-    auto& registry = attributeRegistry();
-    if (!registry.isEmpty())
-        return;
-    registry.registerAttribute<SVGNames::xAttr, &SVGFilterPrimitiveStandardAttributes::m_x>();
-    registry.registerAttribute<SVGNames::yAttr, &SVGFilterPrimitiveStandardAttributes::m_y>();
-    registry.registerAttribute<SVGNames::widthAttr, &SVGFilterPrimitiveStandardAttributes::m_width>();
-    registry.registerAttribute<SVGNames::heightAttr, &SVGFilterPrimitiveStandardAttributes::m_height>();
-}
-
 void SVGFilterPrimitiveStandardAttributes::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     SVGParsingError parseError = NoError;
 
     if (name == SVGNames::xAttr)
-        m_x.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError));
+        m_x->setBaseValInternal(SVGLengthValue::construct(LengthModeWidth, value, parseError));
     else if (name == SVGNames::yAttr)
-        m_y.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError));
+        m_y->setBaseValInternal(SVGLengthValue::construct(LengthModeHeight, value, parseError));
     else if (name == SVGNames::widthAttr)
-        m_width.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError));
+        m_width->setBaseValInternal(SVGLengthValue::construct(LengthModeWidth, value, parseError));
     else if (name == SVGNames::heightAttr)
-        m_height.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError));
+        m_height->setBaseValInternal(SVGLengthValue::construct(LengthModeHeight, value, parseError));
     else if (name == SVGNames::resultAttr)
         m_result->setBaseValInternal(value);
 
index a81bb0d..1433b25 100644 (file)
@@ -23,7 +23,6 @@
 
 #include "RenderSVGResourceFilter.h"
 #include "RenderSVGResourceFilterPrimitive.h"
-#include "SVGAnimatedLength.h"
 #include "SVGElement.h"
 #include "SVGNames.h"
 #include <wtf/RefPtr.h>
@@ -48,16 +47,16 @@ public:
 
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGFilterPrimitiveStandardAttributes, SVGElement>;
 
-    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()); }
+    const SVGLengthValue& x() const { return m_x->currentValue(); }
+    const SVGLengthValue& y() const { return m_y->currentValue(); }
+    const SVGLengthValue& width() const { return m_width->currentValue(); }
+    const SVGLengthValue& height() const { return m_height->currentValue(); }
     String result() const { return m_result->currentValue(); }
 
-    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()); }
+    SVGAnimatedLength& xAnimated() { return m_x; }
+    SVGAnimatedLength& yAnimated() { return m_y; }
+    SVGAnimatedLength& widthAnimated() { return m_width; }
+    SVGAnimatedLength& heightAnimated() { return m_height; }
     SVGAnimatedString& resultAnimated() { return m_result; }
 
 protected:
@@ -71,16 +70,9 @@ protected:
     void primitiveAttributeChanged(const QualifiedName& attributeName);
 
 private:
-    static void registerAttributes();
     const SVGAttributeOwnerProxy& attributeOwnerProxy() const override { return m_attributeOwnerProxy; }
-
     const SVGPropertyRegistry& propertyRegistry() const override { return m_propertyRegistry; }
 
-    static bool isKnownAttribute(const QualifiedName& attributeName)
-    {
-        return AttributeOwnerProxy::isKnownAttribute(attributeName) || PropertyRegistry::isKnownAttribute(attributeName);
-    }
-
     bool isFilterEffect() const override { return true; }
 
     RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) override;
@@ -91,10 +83,10 @@ private:
     PropertyRegistry m_propertyRegistry { *this };
     // Spec: If the x/y attribute is not specified, the effect is as if a value of "0%" were specified.
     // Spec: If the width/height attribute is not specified, the effect is as if a value of "100%" were specified.
-    SVGAnimatedLengthAttribute m_x { LengthModeWidth, "0%" };
-    SVGAnimatedLengthAttribute m_y { LengthModeHeight, "0%" };
-    SVGAnimatedLengthAttribute m_width { LengthModeWidth, "100%" };
-    SVGAnimatedLengthAttribute m_height { LengthModeHeight, "100%" };
+    Ref<SVGAnimatedLength> m_x { SVGAnimatedLength::create(this, LengthModeWidth, "0%") };
+    Ref<SVGAnimatedLength> m_y { SVGAnimatedLength::create(this, LengthModeHeight, "0%") };
+    Ref<SVGAnimatedLength> m_width { SVGAnimatedLength::create(this, LengthModeWidth, "100%") };
+    Ref<SVGAnimatedLength> m_height { SVGAnimatedLength::create(this, LengthModeHeight, "100%") };
     Ref<SVGAnimatedString> m_result { SVGAnimatedString::create(this) };
 };
 
index 006a773..ba690ed 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2019 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
  * Copyright (C) 2014 Adobe Systems Incorporated. All rights reserved.
  *
@@ -40,7 +40,13 @@ inline SVGForeignObjectElement::SVGForeignObjectElement(const QualifiedName& tag
     , SVGExternalResourcesRequired(this)
 {
     ASSERT(hasTagName(SVGNames::foreignObjectTag));
-    registerAttributes();
+    static std::once_flag onceFlag;
+    std::call_once(onceFlag, [] {
+        PropertyRegistry::registerProperty<SVGNames::xAttr, &SVGForeignObjectElement::m_x>();
+        PropertyRegistry::registerProperty<SVGNames::yAttr, &SVGForeignObjectElement::m_y>();
+        PropertyRegistry::registerProperty<SVGNames::widthAttr, &SVGForeignObjectElement::m_width>();
+        PropertyRegistry::registerProperty<SVGNames::heightAttr, &SVGForeignObjectElement::m_height>();
+    });
 }
 
 Ref<SVGForeignObjectElement> SVGForeignObjectElement::create(const QualifiedName& tagName, Document& document)
@@ -48,29 +54,18 @@ Ref<SVGForeignObjectElement> SVGForeignObjectElement::create(const QualifiedName
     return adoptRef(*new SVGForeignObjectElement(tagName, document));
 }
 
-void SVGForeignObjectElement::registerAttributes()
-{
-    auto& registry = attributeRegistry();
-    if (!registry.isEmpty())
-        return;
-    registry.registerAttribute<SVGNames::xAttr, &SVGForeignObjectElement::m_x>();
-    registry.registerAttribute<SVGNames::yAttr, &SVGForeignObjectElement::m_y>();
-    registry.registerAttribute<SVGNames::widthAttr, &SVGForeignObjectElement::m_width>();
-    registry.registerAttribute<SVGNames::heightAttr, &SVGForeignObjectElement::m_height>();
-}
-
 void SVGForeignObjectElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     SVGParsingError parseError = NoError;
 
     if (name == SVGNames::xAttr)
-        m_x.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError));
+        m_x->setBaseValInternal(SVGLengthValue::construct(LengthModeWidth, value, parseError));
     else if (name == SVGNames::yAttr)
-        m_y.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError));
+        m_y->setBaseValInternal(SVGLengthValue::construct(LengthModeHeight, value, parseError));
     else if (name == SVGNames::widthAttr)
-        m_width.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError));
+        m_width->setBaseValInternal(SVGLengthValue::construct(LengthModeWidth, value, parseError));
     else if (name == SVGNames::heightAttr)
-        m_height.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError));
+        m_height->setBaseValInternal(SVGLengthValue::construct(LengthModeHeight, value, parseError));
 
     reportAttributeParsingError(parseError, name, value);
 
index 799fc82..52bd41e 100644 (file)
@@ -19,7 +19,6 @@
 
 #pragma once
 
-#include "SVGAnimatedLength.h"
 #include "SVGExternalResourcesRequired.h"
 #include "SVGGraphicsElement.h"
 #include "SVGNames.h"
@@ -32,32 +31,25 @@ class SVGForeignObjectElement final : public SVGGraphicsElement, public SVGExter
 public:
     static Ref<SVGForeignObjectElement> create(const QualifiedName&, Document&);
 
-    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()); }
+    const SVGLengthValue& x() const { return m_x->currentValue(); }
+    const SVGLengthValue& y() const { return m_y->currentValue(); }
+    const SVGLengthValue& width() const { return m_width->currentValue(); }
+    const SVGLengthValue& height() const { return m_height->currentValue(); }
 
-    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()); }
+    SVGAnimatedLength& xAnimated() { return m_x; }
+    SVGAnimatedLength& yAnimated() { return m_y; }
+    SVGAnimatedLength& widthAnimated() { return m_width; }
+    SVGAnimatedLength& heightAnimated() { return m_height; }
 
 private:
     SVGForeignObjectElement(const QualifiedName&, Document&);
 
     using AttributeOwnerProxy = SVGAttributeOwnerProxyImpl<SVGForeignObjectElement, SVGGraphicsElement, SVGExternalResourcesRequired>;
-    static AttributeOwnerProxy::AttributeRegistry& attributeRegistry() { return AttributeOwnerProxy::attributeRegistry(); }
-    static void registerAttributes();
     const SVGAttributeOwnerProxy& attributeOwnerProxy() const final { return m_attributeOwnerProxy; }
 
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGForeignObjectElement, 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;
 
@@ -70,10 +62,10 @@ private:
 
     AttributeOwnerProxy m_attributeOwnerProxy { *this };
     PropertyRegistry m_propertyRegistry { *this };
-    SVGAnimatedLengthAttribute m_x { LengthModeWidth };
-    SVGAnimatedLengthAttribute m_y { LengthModeHeight };
-    SVGAnimatedLengthAttribute m_width { LengthModeWidth };
-    SVGAnimatedLengthAttribute m_height { LengthModeHeight };
+    Ref<SVGAnimatedLength> m_x { SVGAnimatedLength::create(this, LengthModeWidth) };
+    Ref<SVGAnimatedLength> m_y { SVGAnimatedLength::create(this, LengthModeHeight) };
+    Ref<SVGAnimatedLength> m_width { SVGAnimatedLength::create(this, LengthModeWidth) };
+    Ref<SVGAnimatedLength> m_height { SVGAnimatedLength::create(this, LengthModeHeight) };
 };
 
 } // namespace WebCore
index d2b14a5..caa6562 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Rob Buis <buis@kde.org>
  * Copyright (C) 2006 Alexander Kellett <lypanov@kde.org>
  * 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
@@ -43,10 +43,12 @@ inline SVGImageElement::SVGImageElement(const QualifiedName& tagName, Document&
     , SVGURIReference(this)
     , m_imageLoader(*this)
 {
-    registerAttributes();
-
     static std::once_flag onceFlag;
     std::call_once(onceFlag, [] {
+        PropertyRegistry::registerProperty<SVGNames::xAttr, &SVGImageElement::m_x>();
+        PropertyRegistry::registerProperty<SVGNames::yAttr, &SVGImageElement::m_y>();
+        PropertyRegistry::registerProperty<SVGNames::widthAttr, &SVGImageElement::m_width>();
+        PropertyRegistry::registerProperty<SVGNames::heightAttr, &SVGImageElement::m_height>();
         PropertyRegistry::registerProperty<SVGNames::preserveAspectRatioAttr, &SVGImageElement::m_preserveAspectRatio>();
     });
 }
@@ -65,17 +67,6 @@ bool SVGImageElement::hasSingleSecurityOrigin() const
     return !image || image->hasSingleSecurityOrigin();
 }
 
-void SVGImageElement::registerAttributes()
-{
-    auto& registry = attributeRegistry();
-    if (!registry.isEmpty())
-        return;
-    registry.registerAttribute<SVGNames::xAttr, &SVGImageElement::m_x>();
-    registry.registerAttribute<SVGNames::yAttr, &SVGImageElement::m_y>();
-    registry.registerAttribute<SVGNames::widthAttr, &SVGImageElement::m_width>();
-    registry.registerAttribute<SVGNames::heightAttr, &SVGImageElement::m_height>();
-}
-
 void SVGImageElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     if (name == SVGNames::preserveAspectRatioAttr) {
@@ -88,13 +79,13 @@ void SVGImageElement::parseAttribute(const QualifiedName& name, const AtomicStri
     SVGParsingError parseError = NoError;
 
     if (name == SVGNames::xAttr)
-        m_x.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError));
+        m_x->setBaseValInternal(SVGLengthValue::construct(LengthModeWidth, value, parseError));
     else if (name == SVGNames::yAttr)
-        m_y.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError));
+        m_y->setBaseValInternal(SVGLengthValue::construct(LengthModeHeight, value, parseError));
     else if (name == SVGNames::widthAttr)
-        m_width.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths));
+        m_width->setBaseValInternal(SVGLengthValue::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths));
     else if (name == SVGNames::heightAttr)
-        m_height.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths));
+        m_height->setBaseValInternal(SVGLengthValue::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths));
 
     reportAttributeParsingError(parseError, name, value);
 
index ecfc6b6..5c40752 100644 (file)
@@ -21,7 +21,6 @@
 
 #pragma once
 
-#include "SVGAnimatedLength.h"
 #include "SVGExternalResourcesRequired.h"
 #include "SVGGraphicsElement.h"
 #include "SVGImageLoader.h"
@@ -37,34 +36,27 @@ public:
     bool hasSingleSecurityOrigin() const;
     const AtomicString& imageSourceURL() const final;
 
-    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()); }
+    const SVGLengthValue& x() const { return m_x->currentValue(); }
+    const SVGLengthValue& y() const { return m_y->currentValue(); }
+    const SVGLengthValue& width() const { return m_width->currentValue(); }
+    const SVGLengthValue& height() const { return m_height->currentValue(); }
     const SVGPreserveAspectRatioValue& preserveAspectRatio() const { return m_preserveAspectRatio->currentValue(); }
 
-    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()); }
+    SVGAnimatedLength& xAnimated() { return m_x; }
+    SVGAnimatedLength& yAnimated() { return m_y; }
+    SVGAnimatedLength& widthAnimated() { return m_width; }
+    SVGAnimatedLength& heightAnimated() { return m_height; }
     SVGAnimatedPreserveAspectRatio& preserveAspectRatioAnimated() { return m_preserveAspectRatio; }
 
 private:
     SVGImageElement(const QualifiedName&, Document&);
     
     using AttributeOwnerProxy = SVGAttributeOwnerProxyImpl<SVGImageElement, SVGGraphicsElement, SVGExternalResourcesRequired, SVGURIReference>;
-    static AttributeOwnerProxy::AttributeRegistry& attributeRegistry() { return AttributeOwnerProxy::attributeRegistry(); }
-    static void registerAttributes();
     const SVGAttributeOwnerProxy& attributeOwnerProxy() const final { return m_attributeOwnerProxy; }
 
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGImageElement, SVGGraphicsElement, SVGExternalResourcesRequired, SVGURIReference>;
     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;
 
@@ -81,10 +73,10 @@ private:
 
     AttributeOwnerProxy m_attributeOwnerProxy { *this };
     PropertyRegistry m_propertyRegistry { *this };
-    SVGAnimatedLengthAttribute m_x { LengthModeWidth };
-    SVGAnimatedLengthAttribute m_y { LengthModeHeight };
-    SVGAnimatedLengthAttribute m_width { LengthModeWidth };
-    SVGAnimatedLengthAttribute m_height { LengthModeHeight };
+    Ref<SVGAnimatedLength> m_x { SVGAnimatedLength::create(this, LengthModeWidth) };
+    Ref<SVGAnimatedLength> m_y { SVGAnimatedLength::create(this, LengthModeHeight) };
+    Ref<SVGAnimatedLength> m_width { SVGAnimatedLength::create(this, LengthModeWidth) };
+    Ref<SVGAnimatedLength> m_height { SVGAnimatedLength::create(this, LengthModeHeight) };
     Ref<SVGAnimatedPreserveAspectRatio> m_preserveAspectRatio { SVGAnimatedPreserveAspectRatio::create(this) };
     SVGImageLoader m_imageLoader;
 };
index 11a7cfa..ff0fd35 100644 (file)
@@ -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
 #pragma once
 
 #include "SVGLengthValue.h"
-#include "SVGPropertyTearOff.h"
+#include "SVGValueProperty.h"
 
 namespace WebCore {
 
-class SVGLength : public SVGPropertyTearOff<SVGLengthValue> {
+class SVGLength : public SVGValueProperty<SVGLengthValue> {
+    using Base = SVGValueProperty<SVGLengthValue>;
+    using Base::Base;
+    using Base::m_value;
+
 public:
     // Forward declare these enums in the w3c naming scheme, for IDL generation
     enum {
@@ -47,31 +51,42 @@ public:
         SVG_LENGTHTYPE_PC = LengthTypePC
     };
 
-    static Ref<SVGLength> create(SVGLegacyAnimatedProperty& animatedProperty, SVGPropertyRole role, SVGLengthValue& value)
+    static Ref<SVGLength> create()
+    {
+        return adoptRef(*new SVGLength());
+    }
+
+    static Ref<SVGLength> create(const SVGLengthValue& value)
     {
-        return adoptRef(*new SVGLength(animatedProperty, role, value));
+        return adoptRef(*new SVGLength(value));
     }
 
-    static Ref<SVGLength> create(const SVGLengthValue& initialValue = { })
+    static Ref<SVGLength> create(SVGPropertyOwner* owner, SVGPropertyAccess access, const SVGLengthValue& value = { })
     {
-        return adoptRef(*new SVGLength(initialValue));
+        return adoptRef(*new SVGLength(owner, access, value));
     }
 
-    template<typename T> static ExceptionOr<Ref<SVGLength>> create(ExceptionOr<T>&& initialValue)
+    template<typename T>
+    static ExceptionOr<Ref<SVGLength>> create(ExceptionOr<T>&& value)
     {
-        if (initialValue.hasException())
-            return initialValue.releaseException();
-        return create(initialValue.releaseReturnValue());
+        if (value.hasException())
+            return value.releaseException();
+        return adoptRef(*new SVGLength(value.releaseReturnValue()));
+    }
+
+    Ref<SVGLength> clone() const
+    {
+        return SVGLength::create(m_value);
     }
 
     unsigned short unitType()
     {
-        return propertyReference().unitType();
+        return m_value.unitType();
     }
 
     ExceptionOr<float> valueForBindings()
     {
-        return propertyReference().valueForBindings(SVGLengthContext { contextElement() });
+        return m_value.valueForBindings(SVGLengthContext { contextElement() });
     }
 
     ExceptionOr<void> setValueForBindings(float value)
@@ -79,7 +94,7 @@ public:
         if (isReadOnly())
             return Exception { NoModificationAllowedError };
 
-        auto result = propertyReference().setValue(value, SVGLengthContext { contextElement() });
+        auto result = m_value.setValue(value, SVGLengthContext { contextElement() });
         if (result.hasException())
             return result;
         
@@ -89,7 +104,7 @@ public:
     
     float valueInSpecifiedUnits()
     {
-        return propertyReference().valueInSpecifiedUnits();
+        return m_value.valueInSpecifiedUnits();
     }
 
     ExceptionOr<void> setValueInSpecifiedUnits(float valueInSpecifiedUnits)
@@ -97,23 +112,17 @@ public:
         if (isReadOnly())
             return Exception { NoModificationAllowedError };
 
-        propertyReference().setValueInSpecifiedUnits(valueInSpecifiedUnits);
+        m_value.setValueInSpecifiedUnits(valueInSpecifiedUnits);
         commitChange();
-        
         return { };
     }
     
-    String valueAsString()
-    {
-        return propertyReference().valueAsString();
-    }
-
     ExceptionOr<void> setValueAsString(const String& value)
     {
         if (isReadOnly())
             return Exception { NoModificationAllowedError };
 
-        auto result = propertyReference().setValueAsString(value);
+        auto result = m_value.setValueAsString(value);
         if (result.hasException())
             return result;
         
@@ -126,7 +135,7 @@ public:
         if (isReadOnly())
             return Exception { NoModificationAllowedError };
 
-        auto result = propertyReference().newValueSpecifiedUnits(unitType, valueInSpecifiedUnits);
+        auto result = m_value.newValueSpecifiedUnits(unitType, valueInSpecifiedUnits);
         if (result.hasException())
             return result;
         
@@ -139,23 +148,17 @@ public:
         if (isReadOnly())
             return Exception { NoModificationAllowedError };
 
-        auto result = propertyReference().convertToSpecifiedUnits(unitType, SVGLengthContext { contextElement() });
+        auto result = m_value.convertToSpecifiedUnits(unitType, SVGLengthContext { contextElement() });
         if (result.hasException())
             return result;
         
         commitChange();
         return result;
     }
-
-private:
-    SVGLength(SVGLegacyAnimatedProperty& animatedProperty, SVGPropertyRole role, SVGLengthValue& value)
-        : SVGPropertyTearOff<SVGLengthValue>(&animatedProperty, role, value)
-    {
-    }
-
-    explicit SVGLength(const SVGLengthValue& initialValue)
-        : SVGPropertyTearOff<SVGLengthValue>(initialValue)
+    
+    String valueAsString() const override
     {
+        return m_value.valueAsString();
     }
 };
 
index 9abaa4f..b0147fa 100644 (file)
@@ -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
 
 #pragma once
 
-#include "SVGAnimatedListPropertyTearOff.h"
-#include "SVGLengthListValues.h"
-#include "SVGListPropertyTearOff.h"
+#include "SVGLength.h"
+#include "SVGValuePropertyList.h"
 
 namespace WebCore {
 
-class SVGLengthList : public SVGListPropertyTearOff<SVGLengthListValues> {
+class SVGLengthList : public SVGValuePropertyList<SVGLength> {
+    using Base = SVGValuePropertyList<SVGLength>;
+    using Base::Base;
+
 public:
-    using AnimatedListPropertyTearOff = SVGAnimatedListPropertyTearOff<SVGLengthListValues>;
-    using ListWrapperCache = AnimatedListPropertyTearOff::ListWrapperCache;
+    static Ref<SVGLengthList> create(SVGLengthMode lengthMode = LengthModeOther)
+    {
+        return adoptRef(*new SVGLengthList(lengthMode));
+    }
 
-    static Ref<SVGLengthList> create(AnimatedListPropertyTearOff& animatedProperty, SVGPropertyRole role, SVGLengthListValues& values, ListWrapperCache& wrappers)
+    static Ref<SVGLengthList> create(SVGPropertyOwner* owner, SVGPropertyAccess access, SVGLengthMode lengthMode)
     {
-        return adoptRef(*new SVGLengthList(animatedProperty, role, values, wrappers));
+        return adoptRef(*new SVGLengthList(owner, access, lengthMode));
+    }
+
+    static Ref<SVGLengthList> create(const SVGLengthList& other, SVGPropertyAccess access)
+    {
+        return adoptRef(*new SVGLengthList(other, access));
+    }
+
+    SVGLengthMode lengthMode() const { return m_lengthMode; }
+
+    bool parse(const String& value)
+    {
+        clearItems();
+
+        auto upconvertedCharacters = StringView(value).upconvertedCharacters();
+        const UChar* ptr = upconvertedCharacters;
+        const UChar* end = ptr + value.length();
+        while (ptr < end) {
+            const UChar* start = ptr;
+            while (ptr < end && *ptr != ',' && !isSVGSpace(*ptr))
+                ptr++;
+            if (ptr == start)
+                break;
+
+            String valueString(start, ptr - start);
+            SVGLengthValue value(m_lengthMode);
+            if (value.setValueAsString(valueString).hasException())
+                break;
+
+            append(SVGLength::create(value));
+            skipOptionalSVGSpacesOrDelimiter(ptr, end);
+        }
+
+        return ptr == end;
     }
 
+    String valueAsString() const override
+    {
+        StringBuilder builder;
+
+        for (const auto& length : m_items) {
+            if (builder.length())
+                builder.append(' ');
+
+            builder.append(length->value().valueAsString());
+        }
+
+        return builder.toString();
+    }
+    
 private:
-    SVGLengthList(AnimatedListPropertyTearOff& animatedProperty, SVGPropertyRole role, SVGLengthListValues& values, ListWrapperCache& wrappers)
-        : SVGListPropertyTearOff<SVGLengthListValues>(animatedProperty, role, values, wrappers)
+    SVGLengthList(SVGLengthMode lengthMode)
+        : m_lengthMode(lengthMode)
     {
     }
+
+    SVGLengthList(SVGPropertyOwner* owner, SVGPropertyAccess access, SVGLengthMode lengthMode)
+        : Base(owner, access)
+        , m_lengthMode(lengthMode)
+    {
+    }
+
+    SVGLengthList(const SVGLengthList& other, SVGPropertyAccess access)
+        : Base(other, access)
+        , m_lengthMode(other.lengthMode())
+    {
+    }
+
+    SVGLengthMode m_lengthMode { LengthModeOther };
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/svg/SVGLengthListValues.cpp b/Source/WebCore/svg/SVGLengthListValues.cpp
deleted file mode 100644 (file)
index ba20648..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org>
- *
- * 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 "SVGLengthListValues.h"
-
-#include "SVGParserUtilities.h"
-#include <wtf/text/StringBuilder.h>
-
-namespace WebCore {
-
-void SVGLengthListValues::parse(const String& value, SVGLengthMode mode)
-{
-    clear();
-
-    auto upconvertedCharacters = StringView(value).upconvertedCharacters();
-    const UChar* ptr = upconvertedCharacters;
-    const UChar* end = ptr + value.length();
-    while (ptr < end) {
-        const UChar* start = ptr;
-        while (ptr < end && *ptr != ',' && !isSVGSpace(*ptr))
-            ptr++;
-        if (ptr == start)
-            break;
-
-        SVGLengthValue length(mode);
-        String valueString(start, ptr - start);
-        if (valueString.isEmpty())
-            return;
-        if (length.setValueAsString(valueString).hasException())
-            return;
-        append(length);
-        skipOptionalSVGSpacesOrDelimiter(ptr, end);
-    }
-}
-
-String SVGLengthListValues::valueAsString() const
-{
-    StringBuilder builder;
-
-    unsigned size = this->size();
-    for (unsigned i = 0; i < size; ++i) {
-        if (i > 0)
-            builder.append(' ');
-
-        builder.append(at(i).valueAsString());
-    }
-
-    return builder.toString();
-}
-
-}
diff --git a/Source/WebCore/svg/SVGLengthListValues.h b/Source/WebCore/svg/SVGLengthListValues.h
deleted file mode 100644 (file)
index 4842e7c..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org>
- *
- * 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 "SVGLengthValue.h"
-#include <wtf/Vector.h>
-
-namespace WebCore {
-
-class SVGLength;
-class SVGLengthList;
-
-class SVGLengthListValues final : public Vector<SVGLengthValue> {
-public:
-    void parse(const String& value, SVGLengthMode);
-    String valueAsString() const;
-};
-
-template<>
-struct SVGPropertyTraits<SVGLengthListValues> {
-    static SVGLengthListValues initialValue() { return { }; }
-    static SVGLengthListValues fromString(const String& string, SVGLengthMode lengthMode)
-    {
-        SVGLengthListValues list;
-        list.parse(string, lengthMode);
-        return list;
-    }
-    static Optional<SVGLengthListValues> parse(const QualifiedName& attrName, const String& string)
-    {
-        SVGLengthListValues list;
-        list.parse(string, SVGLengthValue::lengthModeForAnimatedLengthAttribute(attrName));
-        return list;
-    }
-    static String toString(const SVGLengthListValues& type) { return type.valueAsString(); }
-
-    using ListItemType = SVGLengthValue;
-    using ListItemTearOff = SVGLength;
-    using ListPropertyTearOff = SVGLengthList;
-};
-
-} // namespace WebCore
index da54067..897344c 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org>
  * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
- * 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
@@ -35,7 +35,14 @@ inline SVGLineElement::SVGLineElement(const QualifiedName& tagName, Document& do
     , SVGExternalResourcesRequired(this)
 {
     ASSERT(hasTagName(SVGNames::lineTag));
-    registerAttributes();
+
+    static std::once_flag onceFlag;
+    std::call_once(onceFlag, [] {
+        PropertyRegistry::registerProperty<SVGNames::x1Attr, &SVGLineElement::m_x1>();
+        PropertyRegistry::registerProperty<SVGNames::y1Attr, &SVGLineElement::m_y1>();
+        PropertyRegistry::registerProperty<SVGNames::x2Attr, &SVGLineElement::m_x2>();
+        PropertyRegistry::registerProperty<SVGNames::y2Attr, &SVGLineElement::m_y2>();
+    });
 }
 
 Ref<SVGLineElement> SVGLineElement::create(const QualifiedName& tagName, Document& document)
@@ -43,29 +50,18 @@ Ref<SVGLineElement> SVGLineElement::create(const QualifiedName& tagName, Documen
     return adoptRef(*new SVGLineElement(tagName, document));
 }
 
-void SVGLineElement::registerAttributes()
-{
-    auto& registry = attributeRegistry();
-    if (!registry.isEmpty())
-        return;
-    registry.registerAttribute<SVGNames::x1Attr, &SVGLineElement::m_x1>();
-    registry.registerAttribute<SVGNames::y1Attr, &SVGLineElement::m_y1>();
-    registry.registerAttribute<SVGNames::x2Attr, &SVGLineElement::m_x2>();
-    registry.registerAttribute<SVGNames::y2Attr, &SVGLineElement::m_y2>();
-}
-
 void SVGLineElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     SVGParsingError parseError = NoError;
 
     if (name == SVGNames::x1Attr)
-        m_x1.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError));
+        m_x1->setBaseValInternal(SVGLengthValue::construct(LengthModeWidth, value, parseError));
     else if (name == SVGNames::y1Attr)
-        m_y1.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError));
+        m_y1->setBaseValInternal(SVGLengthValue::construct(LengthModeHeight, value, parseError));
     else if (name == SVGNames::x2Attr)
-        m_x2.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError));
+        m_x2->setBaseValInternal(SVGLengthValue::construct(LengthModeWidth, value, parseError));
     else if (name == SVGNames::y2Attr)
-        m_y2.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError));
+        m_y2->setBaseValInternal(SVGLengthValue::construct(LengthModeHeight, value, parseError));
 
     reportAttributeParsingError(parseError, name, value);
 
@@ -75,7 +71,7 @@ void SVGLineElement::parseAttribute(const QualifiedName& name, const AtomicStrin
 
 void SVGLineElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    if (isKnownAttribute(attrName)) {
+    if (PropertyRegistry::isKnownAttribute(attrName)) {
         InstanceInvalidationGuard guard(*this);
         updateRelativeLengthsInformation();
 
index 1752ec8..0801407 100644 (file)
@@ -21,7 +21,6 @@
 
 #pragma once
 
-#include "SVGAnimatedLength.h"
 #include "SVGExternalResourcesRequired.h"
 #include "SVGGeometryElement.h"
 #include "SVGNames.h"
@@ -33,32 +32,25 @@ class SVGLineElement final : public SVGGeometryElement, public SVGExternalResour
 public:
     static Ref<SVGLineElement> create(const QualifiedName&, Document&);
 
-    const SVGLengthValue& x1() const { return m_x1.currentValue(attributeOwnerProxy()); }
-    const SVGLengthValue& y1() const { return m_y1.currentValue(attributeOwnerProxy()); }
-    const SVGLengthValue& x2() const { return m_x2.currentValue(attributeOwnerProxy()); }
-    const SVGLengthValue& y2() const { return m_y2.currentValue(attributeOwnerProxy()); }
+    const SVGLengthValue& x1() const { return m_x1->currentValue(); }
+    const SVGLengthValue& y1() const { return m_y1->currentValue(); }
+    const SVGLengthValue& x2() const { return m_x2->currentValue(); }
+    const SVGLengthValue& y2() const { return m_y2->currentValue(); }
 
-    RefPtr<SVGAnimatedLength> x1Animated() { return m_x1.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedLength> y1Animated() { return m_y1.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedLength> x2Animated() { return m_x2.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedLength> y2Animated() { return m_y2.animatedProperty(attributeOwnerProxy()); }
+    SVGAnimatedLength& x1Animated() { return m_x1; }
+    SVGAnimatedLength& y1Animated() { return m_y1; }
+    SVGAnimatedLength& x2Animated() { return m_x2; }
+    SVGAnimatedLength& y2Animated() { return m_y2; }
 
 private:
     SVGLineElement(const QualifiedName&, Document&);
 
     using AttributeOwnerProxy = SVGAttributeOwnerProxyImpl<SVGLineElement, SVGGeometryElement, SVGExternalResourcesRequired>;
-    static AttributeOwnerProxy::AttributeRegistry& attributeRegistry() { return AttributeOwnerProxy::attributeRegistry(); }
-    static void registerAttributes();
     const SVGAttributeOwnerProxy& attributeOwnerProxy() const final { return m_attributeOwnerProxy; }
 
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGLineElement, SVGGeometryElement, 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;
 
@@ -68,10 +60,10 @@ private:
 
     AttributeOwnerProxy m_attributeOwnerProxy { *this };
     PropertyRegistry m_propertyRegistry { *this };
-    SVGAnimatedLengthAttribute m_x1 { LengthModeWidth };
-    SVGAnimatedLengthAttribute m_y1 { LengthModeHeight };
-    SVGAnimatedLengthAttribute m_x2 { LengthModeWidth };
-    SVGAnimatedLengthAttribute m_y2 { LengthModeHeight };
+    Ref<SVGAnimatedLength> m_x1 { SVGAnimatedLength::create(this, LengthModeWidth) };
+    Ref<SVGAnimatedLength> m_y1 { SVGAnimatedLength::create(this, LengthModeHeight) };
+    Ref<SVGAnimatedLength> m_x2 { SVGAnimatedLength::create(this, LengthModeWidth) };
+    Ref<SVGAnimatedLength> m_y2 { SVGAnimatedLength::create(this, LengthModeHeight) };
 };
 
 } // namespace WebCore
index eefdfb5..71b95e3 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
  * Copyright (C) 2008 Dirk Schulze <krit@webkit.org>
  * Copyright (C) Research In Motion Limited 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
@@ -44,7 +44,14 @@ inline SVGLinearGradientElement::SVGLinearGradientElement(const QualifiedName& t
 {
     // Spec: If the x2 attribute is not specified, the effect is as if a value of "100%" were specified.
     ASSERT(hasTagName(SVGNames::linearGradientTag));
-    registerAttributes();
+
+    static std::once_flag onceFlag;
+    std::call_once(onceFlag, [] {
+        PropertyRegistry::registerProperty<SVGNames::x1Attr, &SVGLinearGradientElement::m_x1>();
+        PropertyRegistry::registerProperty<SVGNames::y1Attr, &SVGLinearGradientElement::m_y1>();
+        PropertyRegistry::registerProperty<SVGNames::x2Attr, &SVGLinearGradientElement::m_x2>();
+        PropertyRegistry::registerProperty<SVGNames::y2Attr, &SVGLinearGradientElement::m_y2>();
+    });
 }
 
 Ref<SVGLinearGradientElement> SVGLinearGradientElement::create(const QualifiedName& tagName, Document& document)
@@ -52,29 +59,18 @@ Ref<SVGLinearGradientElement> SVGLinearGradientElement::create(const QualifiedNa
     return adoptRef(*new SVGLinearGradientElement(tagName, document));
 }
 
-void SVGLinearGradientElement::registerAttributes()
-{
-    auto& registry = attributeRegistry();
-    if (!registry.isEmpty())
-        return;
-    registry.registerAttribute<SVGNames::x1Attr, &SVGLinearGradientElement::m_x1>();
-    registry.registerAttribute<SVGNames::y1Attr, &SVGLinearGradientElement::m_y1>();
-    registry.registerAttribute<SVGNames::x2Attr, &SVGLinearGradientElement::m_x2>();
-    registry.registerAttribute<SVGNames::y2Attr, &SVGLinearGradientElement::m_y2>();
-}
-
 void SVGLinearGradientElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     SVGParsingError parseError = NoError;
 
     if (name == SVGNames::x1Attr)
-        m_x1.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError));
+        m_x1->setBaseValInternal(SVGLengthValue::construct(LengthModeWidth, value, parseError));
     else if (name == SVGNames::y1Attr)
-        m_y1.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError));
+        m_y1->setBaseValInternal(SVGLengthValue::construct(LengthModeHeight, value, parseError));
     else if (name == SVGNames::x2Attr)
-        m_x2.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError));
+        m_x2->setBaseValInternal(SVGLengthValue::construct(LengthModeWidth, value, parseError));
     else if (name == SVGNames::y2Attr)
-        m_y2.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError));
+        m_y2->setBaseValInternal(SVGLengthValue::construct(LengthModeHeight, value, parseError));
 
     reportAttributeParsingError(parseError, name, value);
 
@@ -83,7 +79,7 @@ void SVGLinearGradientElement::parseAttribute(const QualifiedName& name, const A
 
 void SVGLinearGradientElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    if (isKnownAttribute(attrName)) {
+    if (PropertyRegistry::isKnownAttribute(attrName)) {
         InstanceInvalidationGuard guard(*this);
         updateRelativeLengthsInformation();
         if (RenderObject* object = renderer())
index 920cdd1..83c5dd3 100644 (file)
@@ -21,7 +21,6 @@
 
 #pragma once
 
-#include "SVGAnimatedLength.h"
 #include "SVGGradientElement.h"
 #include "SVGNames.h"
 
@@ -36,32 +35,25 @@ public:
 
     bool collectGradientAttributes(LinearGradientAttributes&);
 
-    const SVGLengthValue& x1() const { return m_x1.currentValue(attributeOwnerProxy()); }
-    const SVGLengthValue& y1() const { return m_y1.currentValue(attributeOwnerProxy()); }
-    const SVGLengthValue& x2() const { return m_x2.currentValue(attributeOwnerProxy()); }
-    const SVGLengthValue& y2() const { return m_y2.currentValue(attributeOwnerProxy()); }
+    const SVGLengthValue& x1() const { return m_x1->currentValue(); }
+    const SVGLengthValue& y1() const { return m_y1->currentValue(); }
+    const SVGLengthValue& x2() const { return m_x2->currentValue(); }
+    const SVGLengthValue& y2() const { return m_y2->currentValue(); }
 
-    RefPtr<SVGAnimatedLength> x1Animated() { return m_x1.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedLength> y1Animated() { return m_y1.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedLength> x2Animated() { return m_x2.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedLength> y2Animated() { return m_y2.animatedProperty(attributeOwnerProxy()); }
+    SVGAnimatedLength& x1Animated() { return m_x1; }
+    SVGAnimatedLength& y1Animated() { return m_y1; }
+    SVGAnimatedLength& x2Animated() { return m_x2; }
+    SVGAnimatedLength& y2Animated() { return m_y2; }
 
 private:
     SVGLinearGradientElement(const QualifiedName&, Document&);
 
     using AttributeOwnerProxy = SVGAttributeOwnerProxyImpl<SVGLinearGradientElement, SVGGradientElement>;
-    static AttributeOwnerProxy::AttributeRegistry& attributeRegistry() { return AttributeOwnerProxy::attributeRegistry(); }
-    static void registerAttributes();
     const SVGAttributeOwnerProxy& attributeOwnerProxy() const final { return m_attributeOwnerProxy; }
 
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGLinearGradientElement, SVGGradientElement>;
     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,10 +63,10 @@ private:
 
     AttributeOwnerProxy m_attributeOwnerProxy { *this };
     PropertyRegistry m_propertyRegistry { *this };
-    SVGAnimatedLengthAttribute m_x1 { LengthModeWidth };
-    SVGAnimatedLengthAttribute m_y1 { LengthModeHeight };
-    SVGAnimatedLengthAttribute m_x2 { LengthModeWidth, "100%" };
-    SVGAnimatedLengthAttribute m_y2 { LengthModeHeight };
+    Ref<SVGAnimatedLength> m_x1 { SVGAnimatedLength::create(this, LengthModeWidth) };
+    Ref<SVGAnimatedLength> m_y1 { SVGAnimatedLength::create(this, LengthModeHeight) };
+    Ref<SVGAnimatedLength> m_x2 { SVGAnimatedLength::create(this, LengthModeWidth, "100%") };
+    Ref<SVGAnimatedLength> m_y2 { SVGAnimatedLength::create(this, LengthModeHeight) };
 };
 
 } // namespace WebCore
index a1fe7b5..8b6a12e 100644 (file)
@@ -40,10 +40,13 @@ inline SVGMarkerElement::SVGMarkerElement(const QualifiedName& tagName, Document
 {
     // 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::refXAttr, &SVGMarkerElement::m_refX>();
+        PropertyRegistry::registerProperty<SVGNames::refYAttr, &SVGMarkerElement::m_refY>();
+        PropertyRegistry::registerProperty<SVGNames::markerWidthAttr, &SVGMarkerElement::m_markerWidth>();
+        PropertyRegistry::registerProperty<SVGNames::markerHeightAttr, &SVGMarkerElement::m_markerHeight>();
         PropertyRegistry::registerProperty<SVGNames::markerUnitsAttr, SVGMarkerUnitsType, &SVGMarkerElement::m_markerUnits>();
         PropertyRegistry::registerProperty<SVGNames::orientAttr, &SVGMarkerElement::m_orientAngle, &SVGMarkerElement::m_orientType>();
     });
@@ -59,17 +62,6 @@ AffineTransform SVGMarkerElement::viewBoxToViewTransform(float viewWidth, float
     return SVGFitToViewBox::viewBoxToViewTransform(viewBox(), preserveAspectRatio(), viewWidth, viewHeight);
 }
 
-void SVGMarkerElement::registerAttributes()
-{
-    auto& registry = attributeRegistry();
-    if (!registry.isEmpty())
-        return;
-    registry.registerAttribute<SVGNames::refXAttr, &SVGMarkerElement::m_refX>();
-    registry.registerAttribute<SVGNames::refYAttr, &SVGMarkerElement::m_refY>();
-    registry.registerAttribute<SVGNames::markerWidthAttr, &SVGMarkerElement::m_markerWidth>();
-    registry.registerAttribute<SVGNames::markerHeightAttr, &SVGMarkerElement::m_markerHeight>();
-}
-
 void SVGMarkerElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     if (name == SVGNames::markerUnitsAttr) {
@@ -89,13 +81,13 @@ void SVGMarkerElement::parseAttribute(const QualifiedName& name, const AtomicStr
     SVGParsingError parseError = NoError;
 
     if (name == SVGNames::refXAttr)
-        m_refX.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError));
+        m_refX->setBaseValInternal(SVGLengthValue::construct(LengthModeWidth, value, parseError));
     else if (name == SVGNames::refYAttr)
-        m_refY.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError));
+        m_refY->setBaseValInternal(SVGLengthValue::construct(LengthModeHeight, value, parseError));
     else if (name == SVGNames::markerWidthAttr)
-        m_markerWidth.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError));
+        m_markerWidth->setBaseValInternal(SVGLengthValue::construct(LengthModeWidth, value, parseError));
     else if (name == SVGNames::markerHeightAttr)
-        m_markerHeight.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError));
+        m_markerHeight->setBaseValInternal(SVGLengthValue::construct(LengthModeHeight, value, parseError));
 
     reportAttributeParsingError(parseError, name, value);
 
@@ -106,9 +98,9 @@ void SVGMarkerElement::parseAttribute(const QualifiedName& name, const AtomicStr
 
 void SVGMarkerElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    if (isKnownAttribute(attrName)) {
+    if (PropertyRegistry::isKnownAttribute(attrName)) {
         InstanceInvalidationGuard guard(*this);
-        if (isAnimatedLengthAttribute(attrName))
+        if (PropertyRegistry::isAnimatedLengthAttribute(attrName))
             updateRelativeLengthsInformation();
         if (RenderObject* object = renderer())
             object->setNeedsLayout();
index 7cd511b..ef360e9 100644 (file)
@@ -21,7 +21,6 @@
 
 #pragma once
 
-#include "SVGAnimatedLength.h"
 #include "SVGElement.h"
 #include "SVGExternalResourcesRequired.h"
 #include "SVGFitToViewBox.h"
@@ -53,18 +52,18 @@ public:
     void setOrientToAuto();
     void setOrientToAngle(SVGAngle&);
 
-    const SVGLengthValue& refX() const { return m_refX.currentValue(attributeOwnerProxy()); }
-    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()); }
+    const SVGLengthValue& refX() const { return m_refX->currentValue(); }
+    const SVGLengthValue& refY() const { return m_refY->currentValue(); }
+    const SVGLengthValue& markerWidth() const { return m_markerWidth->currentValue(); }
+    const SVGLengthValue& markerHeight() const { return m_markerHeight->currentValue(); }
     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()); }
+    SVGAnimatedLength& refXAnimated() { return m_refX; }
+    SVGAnimatedLength& refYAnimated() { return m_refY; }
+    SVGAnimatedLength& markerWidthAnimated() { return m_markerWidth; }
+    SVGAnimatedLength& markerHeightAnimated() { return m_markerHeight; }
     SVGAnimatedEnumeration& markerUnitsAnimated() { return m_markerUnits; }
     SVGAnimatedAngle& orientAngleAnimated() { return m_orientAngle; }
     Ref<SVGAnimatedEnumeration> orientTypeAnimated() { return m_orientType.copyRef(); }
@@ -73,19 +72,11 @@ private:
     SVGMarkerElement(const QualifiedName&, Document&);
 
     using AttributeOwnerProxy = SVGAttributeOwnerProxyImpl<SVGMarkerElement, SVGElement, SVGExternalResourcesRequired, SVGFitToViewBox>;
-    static AttributeOwnerProxy::AttributeRegistry& attributeRegistry() { return AttributeOwnerProxy::attributeRegistry(); }
-    static void registerAttributes();
     const SVGAttributeOwnerProxy& attributeOwnerProxy() const final { return m_attributeOwnerProxy; }
 
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGMarkerElement, SVGElement, SVGExternalResourcesRequired, SVGFitToViewBox>;
     const SVGPropertyRegistry& propertyRegistry() const final { return m_propertyRegistry; }
 
-    static bool isAnimatedLengthAttribute(const QualifiedName& attributeName) { return AttributeOwnerProxy::isAnimatedLengthAttribute(attributeName); }
-    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;
     void childrenChanged(const ChildChange&) override;
@@ -102,10 +93,10 @@ private:
     AttributeOwnerProxy m_attributeOwnerProxy { *this };
 
     PropertyRegistry m_propertyRegistry { *this };
-    SVGAnimatedLengthAttribute m_refX { LengthModeWidth };
-    SVGAnimatedLengthAttribute m_refY { LengthModeHeight };
-    SVGAnimatedLengthAttribute m_markerWidth { LengthModeWidth, "3" };
-    SVGAnimatedLengthAttribute m_markerHeight { LengthModeHeight, "3" };
+    Ref<SVGAnimatedLength> m_refX { SVGAnimatedLength::create(this, LengthModeWidth) };
+    Ref<SVGAnimatedLength> m_refY { SVGAnimatedLength::create(this, LengthModeHeight) };
+    Ref<SVGAnimatedLength> m_markerWidth { SVGAnimatedLength::create(this, LengthModeWidth, "3") };
+    Ref<SVGAnimatedLength> m_markerHeight { SVGAnimatedLength::create(this, LengthModeHeight, "3") };
     Ref<SVGAnimatedEnumeration> m_markerUnits { SVGAnimatedEnumeration::create(this, SVGMarkerUnitsStrokeWidth) };
     Ref<SVGAnimatedAngle> m_orientAngle { SVGAnimatedAngle::create(this) };
     Ref<SVGAnimatedOrientType> m_orientType { SVGAnimatedOrientType::create(this, SVGMarkerOrientAngle) };
index f377158..56e0cd1 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
  * Copyright (C) Research In Motion Limited 2009-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,10 +47,13 @@ inline SVGMaskElement::SVGMaskElement(const QualifiedName& tagName, Document& do
     // Spec: If the x/y attribute is not specified, the effect is as if a value of "-10%" were specified.
     // 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::xAttr, &SVGMaskElement::m_x>();
+        PropertyRegistry::registerProperty<SVGNames::yAttr, &SVGMaskElement::m_y>();
+        PropertyRegistry::registerProperty<SVGNames::widthAttr, &SVGMaskElement::m_width>();
+        PropertyRegistry::registerProperty<SVGNames::heightAttr, &SVGMaskElement::m_height>();
         PropertyRegistry::registerProperty<SVGNames::maskUnitsAttr, SVGUnitTypes::SVGUnitType, &SVGMaskElement::m_maskUnits>();
         PropertyRegistry::registerProperty<SVGNames::maskContentUnitsAttr, SVGUnitTypes::SVGUnitType, &SVGMaskElement::m_maskContentUnits>();
     });
@@ -61,17 +64,6 @@ Ref<SVGMaskElement> SVGMaskElement::create(const QualifiedName& tagName, Documen
     return adoptRef(*new SVGMaskElement(tagName, document));
 }
 
-void SVGMaskElement::registerAttributes()
-{
-    auto& registry = attributeRegistry();
-    if (!registry.isEmpty())
-        return;
-    registry.registerAttribute<SVGNames::xAttr, &SVGMaskElement::m_x>();
-    registry.registerAttribute<SVGNames::yAttr, &SVGMaskElement::m_y>();
-    registry.registerAttribute<SVGNames::widthAttr, &SVGMaskElement::m_width>();
-    registry.registerAttribute<SVGNames::heightAttr, &SVGMaskElement::m_height>();
-}
-
 void SVGMaskElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     if (name == SVGNames::maskUnitsAttr) {
@@ -90,13 +82,13 @@ void SVGMaskElement::parseAttribute(const QualifiedName& name, const AtomicStrin
     SVGParsingError parseError = NoError;
 
     if (name == SVGNames::xAttr)
-        m_x.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError));
+        m_x->setBaseValInternal(SVGLengthValue::construct(LengthModeWidth, value, parseError));
     else if (name == SVGNames::yAttr)
-        m_y.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError));
+        m_y->setBaseValInternal(SVGLengthValue::construct(LengthModeHeight, value, parseError));
     else if (name == SVGNames::widthAttr)
-        m_width.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError));
+        m_width->setBaseValInternal(SVGLengthValue::construct(LengthModeWidth, value, parseError));
     else if (name == SVGNames::heightAttr)
-        m_height.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError));
+        m_height->setBaseValInternal(SVGLengthValue::construct(LengthModeHeight, value, parseError));
 
     reportAttributeParsingError(parseError, name, value);
 
@@ -107,13 +99,13 @@ void SVGMaskElement::parseAttribute(const QualifiedName& name, const AtomicStrin
 
 void SVGMaskElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    if (isAnimatedLengthAttribute(attrName)) {
+    if (PropertyRegistry::isAnimatedLengthAttribute(attrName)) {
         InstanceInvalidationGuard guard(*this);
         invalidateSVGPresentationAttributeStyle();
         return;
     }
 
-    if (isKnownAttribute(attrName)) {
+    if (PropertyRegistry::isKnownAttribute(attrName)) {
         if (auto* renderer = this->renderer())
             renderer->setNeedsLayout();
         return;
index 392a13c..ab1760b 100644 (file)
@@ -20,7 +20,6 @@
 
 #pragma once
 
-#include "SVGAnimatedLength.h"
 #include "SVGElement.h"
 #include "SVGExternalResourcesRequired.h"
 #include "SVGNames.h"
@@ -34,17 +33,17 @@ class SVGMaskElement final : public SVGElement, public SVGExternalResourcesRequi
 public:
     static Ref<SVGMaskElement> create(const QualifiedName&, Document&);
 
-    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()); }
+    const SVGLengthValue& x() const { return m_x->currentValue(); }
+    const SVGLengthValue& y() const { return m_y->currentValue(); }
+    const SVGLengthValue& width() const { return m_width->currentValue(); }
+    const SVGLengthValue& height() const { return m_height->currentValue(); }
     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()); }
+    SVGAnimatedLength& xAnimated() { return m_x; }
+    SVGAnimatedLength& yAnimated() { return m_y; }
+    SVGAnimatedLength& widthAnimated() { return m_width; }
+    SVGAnimatedLength& heightAnimated() { return m_height; }
     SVGAnimatedEnumeration& maskUnitsAnimated() { return m_maskUnits; }
     SVGAnimatedEnumeration& maskContentUnitsAnimated() { return m_maskContentUnits; }
 
@@ -59,7 +58,6 @@ private:
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGMaskElement, SVGElement, SVGExternalResourcesRequired, SVGTests>;
     const SVGPropertyRegistry& propertyRegistry() const final { return m_propertyRegistry; }
 
-    static bool isAnimatedLengthAttribute(const QualifiedName& attributeName) { return AttributeOwnerProxy::isAnimatedLengthAttribute(attributeName); }
     static bool isKnownAttribute(const QualifiedName& attributeName)
     {
         return AttributeOwnerProxy::isKnownAttribute(attributeName) || PropertyRegistry::isKnownAttribute(attributeName);
@@ -77,10 +75,10 @@ private:
 
     AttributeOwnerProxy m_attributeOwnerProxy { *this };
     PropertyRegistry m_propertyRegistry { *this };
-    SVGAnimatedLengthAttribute m_x { LengthModeWidth, "-10%" };
-    SVGAnimatedLengthAttribute m_y { LengthModeHeight, "-10%" };
-    SVGAnimatedLengthAttribute m_width { LengthModeWidth, "120%" };
-    SVGAnimatedLengthAttribute m_height { LengthModeHeight, "120%" };
+    Ref<SVGAnimatedLength> m_x { SVGAnimatedLength::create(this, LengthModeWidth, "-10%") };
+    Ref<SVGAnimatedLength> m_y { SVGAnimatedLength::create(this, LengthModeHeight, "-10%") };
+    Ref<SVGAnimatedLength> m_width { SVGAnimatedLength::create(this, LengthModeWidth, "120%") };
+    Ref<SVGAnimatedLength> m_height { SVGAnimatedLength::create(this, LengthModeHeight, "120%") };
     Ref<SVGAnimatedEnumeration> m_maskUnits { SVGAnimatedEnumeration::create(this, SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) };
     Ref<SVGAnimatedEnumeration> m_maskContentUnits { SVGAnimatedEnumeration::create(this, SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) };
 };
index a3cb785..a0553c6 100644 (file)
@@ -57,6 +57,10 @@ inline SVGPatternElement::SVGPatternElement(const QualifiedName& tagName, Docume
 
     static std::once_flag onceFlag;
     std::call_once(onceFlag, [] {
+        PropertyRegistry::registerProperty<SVGNames::xAttr, &SVGPatternElement::m_x>();
+        PropertyRegistry::registerProperty<SVGNames::yAttr, &SVGPatternElement::m_y>();
+        PropertyRegistry::registerProperty<SVGNames::widthAttr, &SVGPatternElement::m_width>();
+        PropertyRegistry::registerProperty<SVGNames::heightAttr, &SVGPatternElement::m_height>();
         PropertyRegistry::registerProperty<SVGNames::patternUnitsAttr, SVGUnitTypes::SVGUnitType, &SVGPatternElement::m_patternUnits>();
         PropertyRegistry::registerProperty<SVGNames::patternContentUnitsAttr, SVGUnitTypes::SVGUnitType, &SVGPatternElement::m_patternContentUnits>();
     });
@@ -72,10 +76,6 @@ void SVGPatternElement::registerAttributes()
     auto& registry = attributeRegistry();
     if (!registry.isEmpty())
         return;
-    registry.registerAttribute<SVGNames::xAttr, &SVGPatternElement::m_x>();
-    registry.registerAttribute<SVGNames::yAttr, &SVGPatternElement::m_y>();
-    registry.registerAttribute<SVGNames::widthAttr, &SVGPatternElement::m_width>();
-    registry.registerAttribute<SVGNames::heightAttr, &SVGPatternElement::m_height>();
     registry.registerAttribute<SVGNames::patternTransformAttr, &SVGPatternElement::m_patternTransform>();
 }
 
@@ -104,13 +104,13 @@ void SVGPatternElement::parseAttribute(const QualifiedName& name, const AtomicSt
     SVGParsingError parseError = NoError;
 
     if (name == SVGNames::xAttr)
-        m_x.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError));
+        m_x->setBaseValInternal(SVGLengthValue::construct(LengthModeWidth, value, parseError));
     else if (name == SVGNames::yAttr)
-        m_y.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError));
+        m_y->setBaseValInternal(SVGLengthValue::construct(LengthModeHeight, value, parseError));
     else if (name == SVGNames::widthAttr)
-        m_width.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths));
+        m_width->setBaseValInternal(SVGLengthValue::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths));
     else if (name == SVGNames::heightAttr)
-        m_height.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths));
+        m_height->setBaseValInternal(SVGLengthValue::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths));
 
     reportAttributeParsingError(parseError, name, value);
 
@@ -123,7 +123,7 @@ void SVGPatternElement::parseAttribute(const QualifiedName& name, const AtomicSt
 
 void SVGPatternElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    if (isAnimatedLengthAttribute(attrName)) {
+    if (PropertyRegistry::isAnimatedLengthAttribute(attrName)) {
         InstanceInvalidationGuard guard(*this);
         invalidateSVGPresentationAttributeStyle();
         return;
index 4cc0ac1..fdc26e5 100644 (file)
@@ -21,7 +21,6 @@
 
 #pragma once
 
-#include "SVGAnimatedLength.h"
 #include "SVGAnimatedTransformList.h"
 #include "SVGElement.h"
 #include "SVGExternalResourcesRequired.h"
@@ -44,18 +43,18 @@ public:
 
     AffineTransform localCoordinateSpaceTransform(SVGLocatable::CTMScope) const final;
 
-    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()); }
+    const SVGLengthValue& x() const { return m_x->currentValue(); }
+    const SVGLengthValue& y() const { return m_y->currentValue(); }
+    const SVGLengthValue& width() const { return m_width->currentValue(); }
+    const SVGLengthValue& height() const { return m_height->currentValue(); }
     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()); }
+    SVGAnimatedLength& xAnimated() { return m_x; }
+    SVGAnimatedLength& yAnimated() { return m_y; }
+    SVGAnimatedLength& widthAnimated() { return m_width; }
+    SVGAnimatedLength& heightAnimated() { return m_height; }
     SVGAnimatedEnumeration& patternUnitsAnimated() { return m_patternUnits; }
     SVGAnimatedEnumeration& patternContentUnitsAnimated() { return m_patternContentUnits; }
     RefPtr<SVGAnimatedTransformList> patternTransformAnimated() { return m_patternTransform.animatedProperty(attributeOwnerProxy()); }
@@ -71,7 +70,6 @@ private:
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGPatternElement, SVGElement, SVGExternalResourcesRequired, SVGFitToViewBox, SVGTests, SVGURIReference>;
     const SVGPropertyRegistry& propertyRegistry() const final { return m_propertyRegistry; }
 
-    static bool isAnimatedLengthAttribute(const QualifiedName& attributeName) { return AttributeOwnerProxy::isAnimatedLengthAttribute(attributeName); }
     static bool isKnownAttribute(const QualifiedName& attributeName)
     {
         return AttributeOwnerProxy::isKnownAttribute(attributeName) || PropertyRegistry::isKnownAttribute(attributeName);
@@ -89,10 +87,10 @@ private:
 
     AttributeOwnerProxy m_attributeOwnerProxy { *this };
     PropertyRegistry m_propertyRegistry { *this };
-    SVGAnimatedLengthAttribute m_x { LengthModeWidth };
-    SVGAnimatedLengthAttribute m_y { LengthModeHeight };
-    SVGAnimatedLengthAttribute m_width { LengthModeWidth };
-    SVGAnimatedLengthAttribute m_height { LengthModeHeight };
+    Ref<SVGAnimatedLength> m_x { SVGAnimatedLength::create(this, LengthModeWidth) };
+    Ref<SVGAnimatedLength> m_y { SVGAnimatedLength::create(this, LengthModeHeight) };
+    Ref<SVGAnimatedLength> m_width { SVGAnimatedLength::create(this, LengthModeWidth) };
+    Ref<SVGAnimatedLength> m_height { SVGAnimatedLength::create(this, LengthModeHeight) };
     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;
index 526529b..2dd5e2e 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "FloatPoint.h"
 #include "SVGMatrix.h"
+#include "SVGPropertyTraits.h"
 #include "SVGValueProperty.h"
 
 namespace WebCore {
index b88dd56..2b6a893 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
  * Copyright (C) 2008 Dirk Schulze <krit@webkit.org>
  * Copyright (C) Research In Motion Limited 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
@@ -44,7 +44,16 @@ inline SVGRadialGradientElement::SVGRadialGradientElement(const QualifiedName& t
 {
     // Spec: If the cx/cy/r/fr attribute is not specified, the effect is as if a value of "50%" were specified.
     ASSERT(hasTagName(SVGNames::radialGradientTag));
-    registerAttributes();
+
+    static std::once_flag onceFlag;
+    std::call_once(onceFlag, [] {
+        PropertyRegistry::registerProperty<SVGNames::cxAttr, &SVGRadialGradientElement::m_cx>();
+        PropertyRegistry::registerProperty<SVGNames::cyAttr, &SVGRadialGradientElement::m_cy>();
+        PropertyRegistry::registerProperty<SVGNames::rAttr, &SVGRadialGradientElement::m_r>();
+        PropertyRegistry::registerProperty<SVGNames::fxAttr, &SVGRadialGradientElement::m_fx>();
+        PropertyRegistry::registerProperty<SVGNames::fyAttr, &SVGRadialGradientElement::m_fy>();
+        PropertyRegistry::registerProperty<SVGNames::frAttr, &SVGRadialGradientElement::m_fr>();
+    });
 }
 
 Ref<SVGRadialGradientElement> SVGRadialGradientElement::create(const QualifiedName& tagName, Document& document)
@@ -52,35 +61,22 @@ Ref<SVGRadialGradientElement> SVGRadialGradientElement::create(const QualifiedNa
     return adoptRef(*new SVGRadialGradientElement(tagName, document));
 }
 
-void SVGRadialGradientElement::registerAttributes()
-{
-    auto& registry = attributeRegistry();
-    if (!registry.isEmpty())
-        return;
-    registry.registerAttribute<SVGNames::cxAttr, &SVGRadialGradientElement::m_cx>();
-    registry.registerAttribute<SVGNames::cyAttr, &SVGRadialGradientElement::m_cy>();
-    registry.registerAttribute<SVGNames::rAttr, &SVGRadialGradientElement::m_r>();
-    registry.registerAttribute<SVGNames::fxAttr, &SVGRadialGradientElement::m_fx>();
-    registry.registerAttribute<SVGNames::fyAttr, &SVGRadialGradientElement::m_fy>();
-    registry.registerAttribute<SVGNames::frAttr, &SVGRadialGradientElement::m_fr>();
-}
-
 void SVGRadialGradientElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     SVGParsingError parseError = NoError;
 
     if (name == SVGNames::cxAttr)
-        m_cx.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError));
+        m_cx->setBaseValInternal(SVGLengthValue::construct(LengthModeWidth, value, parseError));
     else if (name == SVGNames::cyAttr)
-        m_cy.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError));
+        m_cy->setBaseValInternal(SVGLengthValue::construct(LengthModeHeight, value, parseError));
     else if (name == SVGNames::rAttr)
-        m_r.setValue(SVGLengthValue::construct(LengthModeOther, value, parseError, ForbidNegativeLengths));
+        m_r->setBaseValInternal(SVGLengthValue::construct(LengthModeOther, value, parseError, ForbidNegativeLengths));
     else if (name == SVGNames::fxAttr)
-        m_fx.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError));
+        m_fx->setBaseValInternal(SVGLengthValue::construct(LengthModeWidth, value, parseError));
     else if (name == SVGNames::fyAttr)
-        m_fy.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError));
+        m_fy->setBaseValInternal(SVGLengthValue::construct(LengthModeHeight, value, parseError));
     else if (name == SVGNames::frAttr)
-        m_fr.setValue(SVGLengthValue::construct(LengthModeOther, value, parseError, ForbidNegativeLengths));
+        m_fr->setBaseValInternal(SVGLengthValue::construct(LengthModeOther, value, parseError, ForbidNegativeLengths));
 
     reportAttributeParsingError(parseError, name, value);
 
@@ -89,7 +85,7 @@ void SVGRadialGradientElement::parseAttribute(const QualifiedName& name, const A
 
 void SVGRadialGradientElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    if (isKnownAttribute(attrName)) {
+    if (PropertyRegistry::isKnownAttribute(attrName)) {
         InstanceInvalidationGuard guard(*this);
         updateRelativeLengthsInformation();
         if (RenderObject* object = renderer())
index 54e8e1c..685f1ba 100644 (file)
@@ -21,7 +21,6 @@
 
 #pragma once
 
-#include "SVGAnimatedLength.h"
 #include "SVGGradientElement.h"
 #include "SVGNames.h"
 
@@ -36,26 +35,24 @@ public:
 
     bool collectGradientAttributes(RadialGradientAttributes&);
 
-    const SVGLengthValue& cx() const { return m_cx.currentValue(attributeOwnerProxy()); }
-    const SVGLengthValue& cy() const { return m_cy.currentValue(attributeOwnerProxy()); }
-    const SVGLengthValue& r() const { return m_r.currentValue(attributeOwnerProxy()); }
-    const SVGLengthValue& fx() const { return m_fx.currentValue(attributeOwnerProxy()); }
-    const SVGLengthValue& fy() const { return m_fy.currentValue(attributeOwnerProxy()); }
-    const SVGLengthValue& fr() const { return m_fr.currentValue(attributeOwnerProxy()); }
+    const SVGLengthValue& cx() const { return m_cx->currentValue(); }
+    const SVGLengthValue& cy() const { return m_cy->currentValue(); }
+    const SVGLengthValue& r() const { return m_r->currentValue(); }
+    const SVGLengthValue& fx() const { return m_fx->currentValue(); }
+    const SVGLengthValue& fy() const { return m_fy->currentValue(); }
+    const SVGLengthValue& fr() const { return m_fr->currentValue(); }
 
-    RefPtr<SVGAnimatedLength> cxAnimated() { return m_cx.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedLength> cyAnimated() { return m_cy.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedLength> rAnimated() { return m_r.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedLength> fxAnimated() { return m_fx.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedLength> fyAnimated() { return m_fy.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedLength> frAnimated() { return m_fr.animatedProperty(attributeOwnerProxy()); }
+    SVGAnimatedLength& cxAnimated() { return m_cx; }
+    SVGAnimatedLength& cyAnimated() { return m_cy; }
+    SVGAnimatedLength& rAnimated() { return m_r; }
+    SVGAnimatedLength& fxAnimated() { return m_fx; }
+    SVGAnimatedLength& fyAnimated() { return m_fy; }
+    SVGAnimatedLength& frAnimated() { return m_fr; }
 
 private:
     SVGRadialGradientElement(const QualifiedName&, Document&);
 
     using AttributeOwnerProxy = SVGAttributeOwnerProxyImpl<SVGRadialGradientElement, SVGGradientElement>;
-    static AttributeOwnerProxy::AttributeRegistry& attributeRegistry() { return AttributeOwnerProxy::attributeRegistry(); }
-    static void registerAttributes();
     const SVGAttributeOwnerProxy& attributeOwnerProxy() const final { return m_attributeOwnerProxy; }
     
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGRadialGradientElement, SVGGradientElement>;
@@ -70,12 +67,12 @@ private:
 
     AttributeOwnerProxy m_attributeOwnerProxy { *this };
     PropertyRegistry m_propertyRegistry { *this };
-    SVGAnimatedLengthAttribute m_cx { LengthModeWidth, "50%" };
-    SVGAnimatedLengthAttribute m_cy { LengthModeHeight, "50%" };
-    SVGAnimatedLengthAttribute m_r { LengthModeOther, "50%" };
-    SVGAnimatedLengthAttribute m_fx { LengthModeWidth };
-    SVGAnimatedLengthAttribute m_fy { LengthModeHeight };
-    SVGAnimatedLengthAttribute m_fr { LengthModeOther, "0%" };
+    Ref<SVGAnimatedLength> m_cx { SVGAnimatedLength::create(this, LengthModeWidth, "50%") };
+    Ref<SVGAnimatedLength> m_cy { SVGAnimatedLength::create(this, LengthModeHeight, "50%") };
+    Ref<SVGAnimatedLength> m_r { SVGAnimatedLength::create(this, LengthModeOther, "50%") };
+    Ref<SVGAnimatedLength> m_fx { SVGAnimatedLength::create(this, LengthModeWidth) };
+    Ref<SVGAnimatedLength> m_fy { SVGAnimatedLength::create(this, LengthModeHeight) };
+    Ref<SVGAnimatedLength> m_fr { SVGAnimatedLength::create(this, LengthModeOther, "0%") };
 };
 
 } // namespace WebCore
index cfdf196..4e14cc6 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org>
  * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
  * 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
@@ -36,7 +36,16 @@ inline SVGRectElement::SVGRectElement(const QualifiedName& tagName, Document& do
     , SVGExternalResourcesRequired(this)
 {
     ASSERT(hasTagName(SVGNames::rectTag));
-    registerAttributes();
+
+    static std::once_flag onceFlag;
+    std::call_once(onceFlag, [] {
+        PropertyRegistry::registerProperty<SVGNames::xAttr, &SVGRectElement::m_x>();
+        PropertyRegistry::registerProperty<SVGNames::yAttr, &SVGRectElement::m_y>();
+        PropertyRegistry::registerProperty<SVGNames::widthAttr, &SVGRectElement::m_width>();
+        PropertyRegistry::registerProperty<SVGNames::heightAttr, &SVGRectElement::m_height>();
+        PropertyRegistry::registerProperty<SVGNames::rxAttr, &SVGRectElement::m_rx>();
+        PropertyRegistry::registerProperty<SVGNames::ryAttr, &SVGRectElement::m_ry>();
+    });
 }
 
 Ref<SVGRectElement> SVGRectElement::create(const QualifiedName& tagName, Document& document)
@@ -44,35 +53,22 @@ Ref<SVGRectElement> SVGRectElement::create(const QualifiedName& tagName, Documen
     return adoptRef(*new SVGRectElement(tagName, document));
 }
 
-void SVGRectElement::registerAttributes()
-{
-    auto& registry = attributeRegistry();
-    if (!registry.isEmpty())
-        return;
-    registry.registerAttribute<SVGNames::xAttr, &SVGRectElement::m_x>();
-    registry.registerAttribute<SVGNames::yAttr, &SVGRectElement::m_y>();
-    registry.registerAttribute<SVGNames::widthAttr, &SVGRectElement::m_width>();
-    registry.registerAttribute<SVGNames::heightAttr, &SVGRectElement::m_height>();
-    registry.registerAttribute<SVGNames::rxAttr, &SVGRectElement::m_rx>();
-    registry.registerAttribute<SVGNames::ryAttr, &SVGRectElement::m_ry>();
-}
-
 void SVGRectElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     SVGParsingError parseError = NoError;
 
     if (name == SVGNames::xAttr)
-        m_x.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError));
+        m_x->setBaseValInternal(SVGLengthValue::construct(LengthModeWidth, value, parseError));
     else if (name == SVGNames::yAttr)
-        m_y.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError));
+        m_y->setBaseValInternal(SVGLengthValue::construct(LengthModeHeight, value, parseError));
     else if (name == SVGNames::rxAttr)
-        m_rx.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths));
+        m_rx->setBaseValInternal(SVGLengthValue::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths));
     else if (name == SVGNames::ryAttr)
-        m_ry.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths));
+        m_ry->setBaseValInternal(SVGLengthValue::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths));
     else if (name == SVGNames::widthAttr)
-        m_width.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths));
+        m_width->setBaseValInternal(SVGLengthValue::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths));
     else if (name == SVGNames::heightAttr)
-        m_height.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths));
+        m_height->setBaseValInternal(SVGLengthValue::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths));
 
     reportAttributeParsingError(parseError, name, value);
 
@@ -82,7 +78,7 @@ void SVGRectElement::parseAttribute(const QualifiedName& name, const AtomicStrin
 
 void SVGRectElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    if (isKnownAttribute(attrName)) {
+    if (PropertyRegistry::isKnownAttribute(attrName)) {
         InstanceInvalidationGuard guard(*this);
         invalidateSVGPresentationAttributeStyle();
         return;
index a69747c..57269aa 100644 (file)
@@ -21,7 +21,6 @@
 
 #pragma once
 
-#include "SVGAnimatedLength.h"
 #include "SVGExternalResourcesRequired.h"
 #include "SVGGeometryElement.h"
 #include "SVGNames.h"
@@ -33,36 +32,29 @@ class SVGRectElement final : public SVGGeometryElement, public SVGExternalResour
 public:
     static Ref<SVGRectElement> create(const QualifiedName&, Document&);
 
-    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()); }
-    const SVGLengthValue& rx() const { return m_rx.currentValue(attributeOwnerProxy()); }
-    const SVGLengthValue& ry() const { return m_ry.currentValue(attributeOwnerProxy()); }
+    const SVGLengthValue& x() const { return m_x->currentValue(); }
+    const SVGLengthValue& y() const { return m_y->currentValue(); }
+    const SVGLengthValue& width() const { return m_width->currentValue(); }
+    const SVGLengthValue& height() const { return m_height->currentValue(); }
+    const SVGLengthValue& rx() const { return m_rx->currentValue(); }
+    const SVGLengthValue& ry() const { return m_ry->currentValue(); }
 
-    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<SVGAnimatedLength> rxAnimated() { return m_rx.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedLength> ryAnimated() { return m_ry.animatedProperty(attributeOwnerProxy()); }
+    SVGAnimatedLength& xAnimated() { return m_x; }
+    SVGAnimatedLength& yAnimated() { return m_y; }
+    SVGAnimatedLength& widthAnimated() { return m_width; }
+    SVGAnimatedLength& heightAnimated() { return m_height; }
+    SVGAnimatedLength& rxAnimated() { return m_rx; }
+    SVGAnimatedLength& ryAnimated() { return m_ry; }
 
 private:
     SVGRectElement(const QualifiedName&, Document&);
 
     using AttributeOwnerProxy = SVGAttributeOwnerProxyImpl<SVGRectElement, SVGGeometryElement, SVGExternalResourcesRequired>;
-    static auto& attributeRegistry() { return AttributeOwnerProxy::attributeRegistry(); }
-    static void registerAttributes();
     const SVGAttributeOwnerProxy& attributeOwnerProxy() const final { return m_attributeOwnerProxy; }
 
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGRectElement, SVGGeometryElement, 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;
 
@@ -73,12 +65,12 @@ private:
 
     AttributeOwnerProxy m_attributeOwnerProxy { *this };
     PropertyRegistry m_propertyRegistry { *this };
-    SVGAnimatedLengthAttribute m_x { LengthModeWidth };
-    SVGAnimatedLengthAttribute m_y { LengthModeHeight };
-    SVGAnimatedLengthAttribute m_width { LengthModeWidth };
-    SVGAnimatedLengthAttribute m_height { LengthModeHeight };
-    SVGAnimatedLengthAttribute m_rx { LengthModeWidth };
-    SVGAnimatedLengthAttribute m_ry { LengthModeHeight};
+    Ref<SVGAnimatedLength> m_x { SVGAnimatedLength::create(this, LengthModeWidth) };
+    Ref<SVGAnimatedLength> m_y { SVGAnimatedLength::create(this, LengthModeHeight) };
+    Ref<SVGAnimatedLength> m_width { SVGAnimatedLength::create(this, LengthModeWidth) };
+    Ref<SVGAnimatedLength> m_height { SVGAnimatedLength::create(this, LengthModeHeight) };
+    Ref<SVGAnimatedLength> m_rx { SVGAnimatedLength::create(this, LengthModeWidth) };
+    Ref<SVGAnimatedLength> m_ry { SVGAnimatedLength::create(this, LengthModeHeight) };
 };
 
 } // namespace WebCore
index 05d92f0..6c7de02 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org>
  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010 Rob Buis <buis@kde.org>
- * Copyright (C) 2007-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2007-2019 Apple Inc. All rights reserved.
  * Copyright (C) 2014 Adobe Systems Incorporated. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
@@ -58,8 +58,15 @@ inline SVGSVGElement::SVGSVGElement(const QualifiedName& tagName, Document& docu
     , m_timeContainer(SMILTimeContainer::create(*this))
 {
     ASSERT(hasTagName(SVGNames::svgTag));
-    registerAttributes();
     document.registerForDocumentSuspensionCallbacks(*this);
+
+    static std::once_flag onceFlag;
+    std::call_once(onceFlag, [] {
+        PropertyRegistry::registerProperty<SVGNames::xAttr, &SVGSVGElement::m_x>();
+        PropertyRegistry::registerProperty<SVGNames::yAttr, &SVGSVGElement::m_y>();
+        PropertyRegistry::registerProperty<SVGNames::widthAttr, &SVGSVGElement::m_width>();
+        PropertyRegistry::registerProperty<SVGNames::heightAttr, &SVGSVGElement::m_height>();
+    });
 }
 
 Ref<SVGSVGElement> SVGSVGElement::create(const QualifiedName& tagName, Document& document)
@@ -186,17 +193,6 @@ void SVGSVGElement::updateCurrentTranslate()
         document().renderView()->repaint();
 }
 
-void SVGSVGElement::registerAttributes()
-{
-    auto& registry = attributeRegistry();
-    if (!registry.isEmpty())
-        return;
-    registry.registerAttribute<SVGNames::xAttr, &SVGSVGElement::m_x>();
-    registry.registerAttribute<SVGNames::yAttr, &SVGSVGElement::m_y>();
-    registry.registerAttribute<SVGNames::widthAttr, &SVGSVGElement::m_width>();
-    registry.registerAttribute<SVGNames::heightAttr, &SVGSVGElement::m_height>();
-}
-
 void SVGSVGElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     if (!nearestViewportElement()) {
@@ -235,9 +231,9 @@ void SVGSVGElement::parseAttribute(const QualifiedName& name, const AtomicString
     SVGParsingError parseError = NoError;
 
     if (name == SVGNames::xAttr)
-        m_x.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError));
+        m_x->setBaseValInternal(SVGLengthValue::construct(LengthModeWidth, value, parseError));
     else if (name == SVGNames::yAttr)
-        m_y.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError));
+        m_y->setBaseValInternal(SVGLengthValue::construct(LengthModeHeight, value, parseError));
     else if (name == SVGNames::widthAttr) {
         auto length = SVGLengthValue::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths);
         if (parseError != NoError || value.isEmpty()) {
@@ -245,7 +241,7 @@ void SVGSVGElement::parseAttribute(const QualifiedName& name, const AtomicString
             // Not sure it's correct for the empty string or for something that can't be parsed.
             length = SVGLengthValue(LengthModeWidth, "100%"_s);
         }
-        m_width.setValue(length);
+        m_width->setBaseValInternal(length);
     } else if (name == SVGNames::heightAttr) {
         auto length = SVGLengthValue::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths);
         if (parseError != NoError || value.isEmpty()) {
@@ -253,7 +249,7 @@ void SVGSVGElement::parseAttribute(const QualifiedName& name, const AtomicString
             // Not sure it's correct for the empty string or for something that can't be parsed.
             length = SVGLengthValue(LengthModeHeight, "100%"_s);
         }
-        m_height.setValue(length);
+        m_height->setBaseValInternal(length);
     }
 
     reportAttributeParsingError(parseError, name, value);
@@ -266,7 +262,7 @@ void SVGSVGElement::parseAttribute(const QualifiedName& name, const AtomicString
 
 void SVGSVGElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    if (isKnownAttribute(attrName)) {
+    if (PropertyRegistry::isKnownAttribute(attrName)) {
         InstanceInvalidationGuard guard(*this);
         invalidateSVGPresentationAttributeStyle();
 
index b0d94fc..f2f945e 100644 (file)
@@ -22,7 +22,6 @@
 #pragma once
 
 #include "FloatPoint.h"
-#include "SVGAnimatedLength.h"
 #include "SVGExternalResourcesRequired.h"
 #include "SVGFitToViewBox.h"
 #include "SVGGraphicsElement.h"
@@ -118,33 +117,26 @@ public:
 
     AffineTransform viewBoxToViewTransform(float viewWidth, float viewHeight) const;
 
-    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()); }
+    const SVGLengthValue& x() const { return m_x->currentValue(); }
+    const SVGLengthValue& y() const { return m_y->currentValue(); }
+    const SVGLengthValue& width() const { return m_width->currentValue(); }
+    const SVGLengthValue& height() const { return m_height->currentValue(); }
 
-    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()); }
+    SVGAnimatedLength& xAnimated() { return m_x; }
+    SVGAnimatedLength& yAnimated() { return m_y; }
+    SVGAnimatedLength& widthAnimated() { return m_width; }
+    SVGAnimatedLength& heightAnimated() { return m_height; }
 
 private:
     SVGSVGElement(const QualifiedName&, Document&);
     virtual ~SVGSVGElement();
 
     using AttributeOwnerProxy = SVGAttributeOwnerProxyImpl<SVGSVGElement, SVGGraphicsElement, SVGExternalResourcesRequired, SVGFitToViewBox>;
-    static AttributeOwnerProxy::AttributeRegistry& attributeRegistry() { return AttributeOwnerProxy::attributeRegistry(); }
-    static void registerAttributes();
     const SVGAttributeOwnerProxy& attributeOwnerProxy() const final { return m_attributeOwnerProxy; }
     
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGSVGElement, SVGGraphicsElement, SVGExternalResourcesRequired, SVGFitToViewBox>;
     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;
     bool selfHasRelativeLengths() const override;
@@ -176,10 +168,10 @@ private:
 
     AttributeOwnerProxy m_attributeOwnerProxy { *this };
     PropertyRegistry m_propertyRegistry { *this };
-    SVGAnimatedLengthAttribute m_x { LengthModeWidth };
-    SVGAnimatedLengthAttribute m_y { LengthModeHeight};
-    SVGAnimatedLengthAttribute m_width { LengthModeWidth, "100%"_s };
-    SVGAnimatedLengthAttribute m_height { LengthModeHeight, "100%"_s };
+    Ref<SVGAnimatedLength> m_x { SVGAnimatedLength::create(this, LengthModeWidth) };
+    Ref<SVGAnimatedLength> m_y { SVGAnimatedLength::create(this, LengthModeHeight) };
+    Ref<SVGAnimatedLength> m_width { SVGAnimatedLength::create(this, LengthModeWidth, "100%"_s) };
+    Ref<SVGAnimatedLength> m_height { SVGAnimatedLength::create(this, LengthModeHeight, "100%"_s) };
 };
 
 } // namespace WebCore
index 2f3a0e3..26dc64e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2004, 2005, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
  * Copyright (C) 2004, 2005, 2006, 2007, 2008 Rob Buis <buis@kde.org>
- * 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,10 +47,9 @@ SVGTextContentElement::SVGTextContentElement(const QualifiedName& tagName, Docum
     : SVGGraphicsElement(tagName, document)
     , SVGExternalResourcesRequired(this)
 {
-    registerAttributes();
-
     static std::once_flag onceFlag;
     std::call_once(onceFlag, [] {
+        PropertyRegistry::registerProperty<SVGNames::textLengthAttr, &SVGTextContentElement::m_textLength>();
         PropertyRegistry::registerProperty<SVGNames::lengthAdjustAttr, SVGLengthAdjustType, &SVGTextContentElement::m_lengthAdjust>();
     });
 }
@@ -163,14 +162,6 @@ void SVGTextContentElement::collectStyleForPresentationAttribute(const Qualified
     SVGGraphicsElement::collectStyleForPresentationAttribute(name, value, style);
 }
 
-void SVGTextContentElement::registerAttributes()
-{
-    auto& registry = attributeRegistry();
-    if (!registry.isEmpty())
-        return;
-    registry.registerAttribute(SVGAnimatedCustomLengthAttributeAccessor::singleton<SVGNames::textLengthAttr, &SVGTextContentElement::m_textLength>());
-}
-
 void SVGTextContentElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     SVGParsingError parseError = NoError;
@@ -180,7 +171,7 @@ void SVGTextContentElement::parseAttribute(const QualifiedName& name, const Atom
         if (propertyValue > 0)
             m_lengthAdjust->setBaseValInternal<SVGLengthAdjustType>(propertyValue);
     } else if (name == SVGNames::textLengthAttr)
-        m_textLength.setValue(SVGLengthValue::construct(LengthModeOther, value, parseError, ForbidNegativeLengths));
+        m_textLength->setBaseValInternal(SVGLengthValue::construct(LengthModeOther, value, parseError, ForbidNegativeLengths));
 
     reportAttributeParsingError(parseError, name, value);
 
@@ -190,9 +181,9 @@ void SVGTextContentElement::parseAttribute(const QualifiedName& name, const Atom
 
 void SVGTextContentElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    if (isKnownAttribute(attrName)) {
+    if (PropertyRegistry::isKnownAttribute(attrName)) {
         if (attrName == SVGNames::textLengthAttr)
-            m_specifiedTextLength = m_textLength.value();
+            m_specifiedTextLength = m_textLength->baseVal()->value();
 
         if (auto renderer = this->renderer()) {
             InstanceInvalidationGuard guard(*this);
@@ -205,6 +196,14 @@ void SVGTextContentElement::svgAttributeChanged(const QualifiedName& attrName)
     SVGExternalResourcesRequired::svgAttributeChanged(attrName);
 }
 
+SVGAnimatedLength& SVGTextContentElement::textLengthAnimated()
+{
+    static NeverDestroyed<SVGLengthValue> defaultTextLength(LengthModeOther);
+    if (m_textLength->baseVal()->value() == defaultTextLength)
+        m_textLength->baseVal()->value().newValueSpecifiedUnits(LengthTypeNumber, getComputedTextLength());
+    return m_textLength;
+}
+
 bool SVGTextContentElement::selfHasRelativeLengths() const
 {
     // Any element of the <text> subtree is advertized as using relative lengths.
index be9461f..6ed78d3 100644 (file)
@@ -21,7 +21,6 @@
 
 #pragma once
 
-#include "SVGAnimatedLength.h"
 #include "SVGExternalResourcesRequired.h"
 #include "SVGGraphicsElement.h"
 
@@ -83,17 +82,17 @@ public:
     ExceptionOr<void> selectSubString(unsigned charnum, unsigned nchars);
 
     static SVGTextContentElement* elementFromRenderer(RenderObject*);
-    const SVGLengthValue& specifiedTextLength() { return m_specifiedTextLength; }
 
     using AttributeOwnerProxy = SVGAttributeOwnerProxyImpl<SVGTextContentElement, SVGGraphicsElement, SVGExternalResourcesRequired>;
     static AttributeOwnerProxy::AttributeRegistry& attributeRegistry() { return AttributeOwnerProxy::attributeRegistry(); }
     
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGTextContentElement, SVGGraphicsElement, SVGExternalResourcesRequired>;
 
-    const SVGLengthValue& textLength() const { return m_textLength.currentValue(attributeOwnerProxy()); }
+    const SVGLengthValue& specifiedTextLength() const { return m_specifiedTextLength; }
+    const SVGLengthValue& textLength() const { return m_textLength->currentValue(); }
     SVGLengthAdjustType lengthAdjust() const { return m_lengthAdjust->currentValue<SVGLengthAdjustType>(); }
 
-    RefPtr<SVGAnimatedLength> textLengthAnimated() { return m_textLength.animatedProperty(attributeOwnerProxy()); }
+    SVGAnimatedLength& textLengthAnimated();
     SVGAnimatedEnumeration& lengthAdjustAnimated() { return m_lengthAdjust; }
 
 protected:
@@ -112,52 +111,11 @@ private:
     bool isTextContent() const final { return true; }
 
     const SVGAttributeOwnerProxy& attributeOwnerProxy() const override { return m_attributeOwnerProxy; }
-    static void registerAttributes();
-
     const SVGPropertyRegistry& propertyRegistry() const override { return m_propertyRegistry; }
 
-    static bool isKnownAttribute(const QualifiedName& attributeName)
-    {
-        return AttributeOwnerProxy::isKnownAttribute(attributeName) || PropertyRegistry::isKnownAttribute(attributeName);
-    }
-
-    class SVGAnimatedCustomLengthAttribute : public SVGAnimatedLengthAttribute {
-    public:
-        using SVGAnimatedLengthAttribute::operator=;
-
-        SVGAnimatedCustomLengthAttribute(SVGTextContentElement& element, SVGLengthMode lengthMode)
-            : SVGAnimatedLengthAttribute(lengthMode)
-            , m_element(element)
-        {
-        }
-
-        void synchronize(Element&, const QualifiedName& attributeName)
-        {
-            if (!shouldSynchronize())
-                return;
-            String string(SVGPropertyTraits<SVGLengthValue>::toString(m_element.m_specifiedTextLength));
-            static_cast<Element&>(m_element).setSynchronizedLazyAttribute(attributeName, string);
-        }
-
-        RefPtr<SVGAnimatedLength> animatedProperty(const SVGAttributeOwnerProxy& attributeOwnerProxy)
-        {
-            static NeverDestroyed<SVGLengthValue> defaultTextLength(LengthModeOther);
-            if (m_element.m_specifiedTextLength == defaultTextLength)
-                m_element.m_textLength.value().newValueSpecifiedUnits(LengthTypeNumber, m_element.getComputedTextLength());
-
-            setShouldSynchronize(true);
-            return static_reference_cast<SVGAnimatedLength>(attributeOwnerProxy.lookupOrCreateAnimatedProperty(*this).releaseNonNull());
-        }
-
-    private:
-        SVGTextContentElement& m_element;
-    };
-
-    using SVGAnimatedCustomLengthAttributeAccessor = SVGAnimatedAttributeAccessor<SVGTextContentElement, SVGAnimatedCustomLengthAttribute, AnimatedLength>;
-
     AttributeOwnerProxy m_attributeOwnerProxy { *this };
     PropertyRegistry m_propertyRegistry { *this };
-    SVGAnimatedCustomLengthAttribute m_textLength { *this, LengthModeOther };
+    Ref<SVGAnimatedLength> m_textLength { SVGAnimatedLength::create(this, LengthModeOther) };
     Ref<SVGAnimatedEnumeration> m_lengthAdjust { SVGAnimatedEnumeration::create(this, SVGLengthAdjustSpacing) };
     SVGLengthValue m_specifiedTextLength { LengthModeOther };
 };
index 65b40e5..f20c67b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
  * Copyright (C) 2010 Rob Buis <rwlbuis@gmail.com>
- * 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
@@ -38,10 +38,10 @@ inline SVGTextPathElement::SVGTextPathElement(const QualifiedName& tagName, Docu
     , SVGURIReference(this)
 {
     ASSERT(hasTagName(SVGNames::textPathTag));
-    registerAttributes();
 
     static std::once_flag onceFlag;
     std::call_once(onceFlag, [] {
+        PropertyRegistry::registerProperty<SVGNames::startOffsetAttr, &SVGTextPathElement::m_startOffset>();
         PropertyRegistry::registerProperty<SVGNames::methodAttr, SVGTextPathMethodType, &SVGTextPathElement::m_method>();
         PropertyRegistry::registerProperty<SVGNames::spacingAttr, SVGTextPathSpacingType, &SVGTextPathElement::m_spacing>();
     });
@@ -62,20 +62,12 @@ void SVGTextPathElement::clearResourceReferences()
     document().accessSVGExtensions().removeAllTargetReferencesForElement(*this);
 }
 
-void SVGTextPathElement::registerAttributes()
-{
-    auto& registry = attributeRegistry();
-    if (!registry.isEmpty())
-        return;
-    registry.registerAttribute<SVGNames::startOffsetAttr, &SVGTextPathElement::m_startOffset>();
-}
-
 void SVGTextPathElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     SVGParsingError parseError = NoError;
 
     if (name == SVGNames::startOffsetAttr)
-        m_startOffset.setValue(SVGLengthValue::construct(LengthModeOther, value, parseError));
+        m_startOffset->setBaseValInternal(SVGLengthValue::construct(LengthModeOther, value, parseError));
     else if (name == SVGNames::methodAttr) {
         SVGTextPathMethodType propertyValue = SVGPropertyTraits<SVGTextPathMethodType>::fromString(value);
         if (propertyValue > 0)
@@ -94,7 +86,7 @@ void SVGTextPathElement::parseAttribute(const QualifiedName& name, const AtomicS
 
 void SVGTextPathElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    if (isKnownAttribute(attrName)) {
+    if (PropertyRegistry::isKnownAttribute(attrName)) {
         InstanceInvalidationGuard guard(*this);
 
         if (attrName == SVGNames::startOffsetAttr)
index a57b722..18fe5a3 100644 (file)
@@ -111,11 +111,11 @@ public:
 
     static Ref<SVGTextPathElement> create(const QualifiedName&, Document&);
 
-    const SVGLengthValue& startOffset() const { return m_startOffset.currentValue(attributeOwnerProxy()); }
+    const SVGLengthValue& startOffset() const { return m_startOffset->currentValue(); }
     SVGTextPathMethodType method() const { return m_method->currentValue<SVGTextPathMethodType>(); }
     SVGTextPathSpacingType spacing() const { return m_spacing->currentValue<SVGTextPathSpacingType>(); }
 
-    RefPtr<SVGAnimatedLength> startOffsetAnimated() { return m_startOffset.animatedProperty(attributeOwnerProxy()); }
+    SVGAnimatedLength& startOffsetAnimated() { return m_startOffset; }
     SVGAnimatedEnumeration& methodAnimated() { return m_method; }
     SVGAnimatedEnumeration& spacingAnimated() { return m_spacing; }
 
@@ -127,18 +127,11 @@ private:
     virtual ~SVGTextPathElement();
 
     using AttributeOwnerProxy = SVGAttributeOwnerProxyImpl<SVGTextPathElement, SVGTextContentElement, SVGURIReference>;
-    static AttributeOwnerProxy::AttributeRegistry& attributeRegistry() { return AttributeOwnerProxy::attributeRegistry(); }
-    static void registerAttributes();
     const SVGAttributeOwnerProxy& attributeOwnerProxy() const final { return m_attributeOwnerProxy; }
 
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGTextPathElement, SVGTextContentElement, SVGURIReference>;
     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;
 
@@ -155,7 +148,7 @@ private:
 
     AttributeOwnerProxy m_attributeOwnerProxy { *this };
     PropertyRegistry m_propertyRegistry { *this };
-    SVGAnimatedLengthAttribute m_startOffset { LengthModeOther };
+    Ref<SVGAnimatedLength> m_startOffset { SVGAnimatedLength::create(this, LengthModeOther) };
     Ref<SVGAnimatedEnumeration> m_method { SVGAnimatedEnumeration::create(this, SVGTextPathMethodAlign) };
     Ref<SVGAnimatedEnumeration> m_spacing { SVGAnimatedEnumeration::create(this, SVGTextPathSpacingExact) };
 };
index 4496466..a6642a0 100644 (file)
@@ -27,7 +27,6 @@
 #include "RenderSVGResource.h"
 #include "RenderSVGText.h"
 #include "SVGAltGlyphElement.h"
-#include "SVGLengthListValues.h"
 #include "SVGNames.h"
 #include "SVGTRefElement.h"
 #include "SVGTSpanElement.h"
@@ -41,56 +40,35 @@ WTF_MAKE_ISO_ALLOCATED_IMPL(SVGTextPositioningElement);
 SVGTextPositioningElement::SVGTextPositioningElement(const QualifiedName& tagName, Document& document)
     : SVGTextContentElement(tagName, document)
 {
-    registerAttributes();
-    
     static std::once_flag onceFlag;
     std::call_once(onceFlag, [] {
+        PropertyRegistry::registerProperty<SVGNames::xAttr, &SVGTextPositioningElement::m_x>();
+        PropertyRegistry::registerProperty<SVGNames::yAttr, &SVGTextPositioningElement::m_y>();
+        PropertyRegistry::registerProperty<SVGNames::dxAttr, &SVGTextPositioningElement::m_dx>();
+        PropertyRegistry::registerProperty<SVGNames::dyAttr, &SVGTextPositioningElement::m_dy>();
         PropertyRegistry::registerProperty<SVGNames::rotateAttr, &SVGTextPositioningElement::m_rotate>();
     });
 }
 
-void SVGTextPositioningElement::registerAttributes()
-{
-    auto& registry = attributeRegistry();
-    if (!registry.isEmpty())
-        return;
-    registry.registerAttribute<SVGNames::xAttr, &SVGTextPositioningElement::m_x>();
-    registry.registerAttribute<SVGNames::yAttr, &SVGTextPositioningElement::m_y>();
-    registry.registerAttribute<SVGNames::dxAttr, &SVGTextPositioningElement::m_dx>();
-    registry.registerAttribute<SVGNames::dyAttr, &SVGTextPositioningElement::m_dy>();
-}
-
 void SVGTextPositioningElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     if (name == SVGNames::xAttr) {
-        SVGLengthListValues newList;
-        newList.parse(value, LengthModeWidth);
-        m_x.detachAnimatedListWrappers(attributeOwnerProxy(), newList.size());
-        m_x.setValue(WTFMove(newList));
+        m_x->baseVal()->parse(value);
         return;
     }
 
     if (name == SVGNames::yAttr) {
-        SVGLengthListValues newList;
-        newList.parse(value, LengthModeHeight);
-        m_y.detachAnimatedListWrappers(attributeOwnerProxy(), newList.size());
-        m_y.setValue(WTFMove(newList));
+        m_y->baseVal()->parse(value);
         return;
     }
 
     if (name == SVGNames::dxAttr) {
-        SVGLengthListValues newList;
-        newList.parse(value, LengthModeWidth);
-        m_dx.detachAnimatedListWrappers(attributeOwnerProxy(), newList.size());
-        m_dx.setValue(WTFMove(newList));
+        m_dx->baseVal()->parse(value);
         return;
     }
 
     if (name == SVGNames::dyAttr) {
-        SVGLengthListValues newList;
-        newList.parse(value, LengthModeHeight);
-        m_dy.detachAnimatedListWrappers(attributeOwnerProxy(), newList.size());
-        m_dy.setValue(WTFMove(newList));
+        m_dy->baseVal()->parse(value);
         return;
     }
 
@@ -118,7 +96,7 @@ bool SVGTextPositioningElement::isPresentationAttribute(const QualifiedName& nam
 
 void SVGTextPositioningElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    if (isKnownAttribute(attrName)) {
+    if (PropertyRegistry::isKnownAttribute(attrName)) {
         InstanceInvalidationGuard guard(*this);
 
         if (attrName != SVGNames::rotateAttr)
index 38ba4c0..45d5c93 100644 (file)
@@ -21,7 +21,6 @@
 
 #pragma once
 
-#include "SVGAnimatedLengthList.h"
 #include "SVGTextContentElement.h"
 
 namespace WebCore {
@@ -36,16 +35,16 @@ public:
     
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGTextPositioningElement, SVGTextContentElement>;
 
-    const SVGLengthListValues& x() const { return m_x.currentValue(attributeOwnerProxy()); }
-    const SVGLengthListValues& y() const { return m_y.currentValue(attributeOwnerProxy()); }
-    const SVGLengthListValues& dx() const { return m_dx.currentValue(attributeOwnerProxy()); }
-    const SVGLengthListValues& dy() const { return m_dy.currentValue(attributeOwnerProxy()); }
+    const SVGLengthList& x() const { return m_x->currentValue(); }
+    const SVGLengthList& y() const { return m_y->currentValue(); }
+    const SVGLengthList& dx() const { return m_dx->currentValue(); }
+    const SVGLengthList& dy() const { return m_dy->currentValue(); }
     const SVGNumberList& rotate() const { return m_rotate->currentValue(); }
 
-    RefPtr<SVGAnimatedLengthList> xAnimated() { return m_x.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedLengthList> yAnimated() { return m_y.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedLengthList> dxAnimated() { return m_dx.animatedProperty(attributeOwnerProxy()); }
-    RefPtr<SVGAnimatedLengthList> dyAnimated() { return m_dy.animatedProperty(attributeOwnerProxy()); }
+    SVGAnimatedLengthList& xAnimated() { return m_x; }
+    SVGAnimatedLengthList& yAnimated() { return m_y; }
+    SVGAnimatedLengthList& dxAnimated() { return m_dx; }
+    SVGAnimatedLengthList& dyAnimated() { return m_dy; }
     SVGAnimatedNumberList& rotateAnimated() { return m_rotate; }
 
 protected:
@@ -59,21 +58,14 @@ private:
     void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) final;
 
     const SVGAttributeOwnerProxy& attributeOwnerProxy() const override { return m_attributeOwnerProxy; }
-    static void registerAttributes();
-
     const SVGPropertyRegistry& propertyRegistry() const override { return m_propertyRegistry; }
 
-    static bool isKnownAttribute(const QualifiedName& attributeName)
-    {
-        return AttributeOwnerProxy::isKnownAttribute(attributeName) || PropertyRegistry::isKnownAttribute(attributeName);
-    }
-
     AttributeOwnerProxy m_attributeOwnerProxy { *this };
     PropertyRegistry m_propertyRegistry { *this };
-    SVGAnimatedLengthListAttribute m_x;
-    SVGAnimatedLengthListAttribute m_y;
-    SVGAnimatedLengthListAttribute m_dx;
-    SVGAnimatedLengthListAttribute m_dy;
+    Ref<SVGAnimatedLengthList> m_x { SVGAnimatedLengthList::create(this, LengthModeWidth) };
+    Ref<SVGAnimatedLengthList> m_y { SVGAnimatedLengthList::create(this, LengthModeHeight) };
+    Ref<SVGAnimatedLengthList> m_dx { SVGAnimatedLengthList::create(this, LengthModeWidth) };
+    Ref<SVGAnimatedLengthList> m_dy { SVGAnimatedLengthList::create(this, LengthModeHeight) };
     Ref<SVGAnimatedNumberList> m_rotate { SVGAnimatedNumberList::create(this) };
 };
 
index 06142a4..a9ae353 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (C) 2011 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
  * Copyright (C) 2012 University of Szeged
  * Copyright (C) 2012 Renata Hodovan <reni@webkit.org>
- * Copyright (C) 2015-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-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,7 +54,14 @@ inline SVGUseElement::SVGUseElement(const QualifiedName& tagName, Document& docu
 {
     ASSERT(hasCustomStyleResolveCallbacks());
     ASSERT(hasTagName(SVGNames::useTag));
-    registerAttributes();
+
+    static std::once_flag onceFlag;
+    std::call_once(onceFlag, [] {
+        PropertyRegistry::registerProperty<SVGNames::xAttr, &SVGUseElement::m_x>();
+        PropertyRegistry::registerProperty<SVGNames::yAttr, &SVGUseElement::m_y>();
+        PropertyRegistry::registerProperty<SVGNames::widthAttr, &SVGUseElement::m_width>();
+        PropertyRegistry::registerProperty<SVGNames::heightAttr, &SVGUseElement::m_height>();
+    });
 }
 
 Ref<SVGUseElement> SVGUseElement::create(const QualifiedName& tagName, Document& document)
@@ -68,29 +75,18 @@ SVGUseElement::~SVGUseElement()
         m_externalDocument->removeClient(*this);
 }
 
-void SVGUseElement::registerAttributes()
-{
-    auto& registry = attributeRegistry();
-    if (!registry.isEmpty())
-        return;
-    registry.registerAttribute<SVGNames::xAttr, &SVGUseElement::m_x>();
-    registry.registerAttribute<SVGNames::yAttr, &SVGUseElement::m_y>();
-    registry.registerAttribute<SVGNames::widthAttr, &SVGUseElement::m_width>();
-    registry.registerAttribute<SVGNames::heightAttr, &SVGUseElement::m_height>();
-}
-
 void SVGUseElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     SVGParsingError parseError = NoError;
 
     if (name == SVGNames::xAttr)
-        m_x.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError));
+        m_x->setBaseValInternal(SVGLengthValue::construct(LengthModeWidth, value, parseError));
     else if (name == SVGNames::yAttr)
-        m_y.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError));
+        m_y->setBaseValInternal(SVGLengthValue::construct(LengthModeHeight, value, parseError));
     else if (name == SVGNames::widthAttr)
-        m_width.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths));
+        m_width->setBaseValInternal(SVGLengthValue::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths));
     else if (name == SVGNames::heightAttr)
-        m_height.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths));
+        m_height->setBaseValInternal(SVGLengthValue::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths));
 
     reportAttributeParsingError(parseError, name, value);
 
@@ -163,7 +159,7 @@ void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName)
 {
     InstanceInvalidationGuard guard(*this);
 
-    if (isKnownAttribute(attrName)) {
+    if (PropertyRegistry::isKnownAttribute(attrName)) {
         updateRelativeLengthsInformation();
         if (attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr) {
             // FIXME: It's unnecessarily inefficient to update both width and height each time either is changed.
index d6edafe..621ce59 100644 (file)
@@ -23,7 +23,6 @@
 
 #include "CachedResourceHandle.h"
 #include "CachedSVGDocumentClient.h"
-#include "SVGAnimatedLength.h"
 #include "SVGExternalResourcesRequired.h"
 #include "SVGGraphicsElement.h"
 #include "SVGURIReference.h"
@@ -45,15 +44,15 @@ public:
 
     RenderElement* rendererClipChild() const;
 
-    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()); }
+    const SVGLengthValue& x() const { return m_x->currentValue(); }
+    const SVGLengthValue& y() const { return m_y->currentValue(); }
+    const SVGLengthValue& width() const { return m_width->currentValue(); }
+    const SVGLengthValue& height() const { return m_height->currentValue(); }
 
-    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()); }
+    SVGAnimatedLength& xAnimated() { return m_x; }
+    SVGAnimatedLength& yAnimated() { return m_y; }
+    SVGAnimatedLength& widthAnimated() { return m_width; }
+    SVGAnimatedLength& heightAnimated() { return m_height; }
 
 private:
     SVGUseElement(const QualifiedName&, Document&);
@@ -65,18 +64,11 @@ private:
     void buildPendingResource() override;
 
     using AttributeOwnerProxy = SVGAttributeOwnerProxyImpl<SVGUseElement, SVGGraphicsElement, SVGExternalResourcesRequired, SVGURIReference>;
-    static AttributeOwnerProxy::AttributeRegistry& attributeRegistry() { return AttributeOwnerProxy::attributeRegistry(); }
-    static void registerAttributes();
     const SVGAttributeOwnerProxy& attributeOwnerProxy() const final { return m_attributeOwnerProxy; }
 
     using PropertyRegistry = SVGPropertyOwnerRegistry<SVGUseElement, SVGGraphicsElement, SVGExternalResourcesRequired, SVGURIReference>;
     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;
 
@@ -108,10 +100,10 @@ private:
 
     AttributeOwnerProxy m_attributeOwnerProxy { *this };
     PropertyRegistry m_propertyRegistry { *this };
-    SVGAnimatedLengthAttribute m_x { LengthModeWidth };
-    SVGAnimatedLengthAttribute m_y { LengthModeHeight };
-    SVGAnimatedLengthAttribute m_width { LengthModeWidth };
-    SVGAnimatedLengthAttribute m_height { LengthModeHeight };
+    Ref<SVGAnimatedLength> m_x { SVGAnimatedLength::create(this, LengthModeWidth) };
+    Ref<SVGAnimatedLength> m_y { SVGAnimatedLength::create(this, LengthModeHeight) };
+    Ref<SVGAnimatedLength> m_width { SVGAnimatedLength::create(this, LengthModeWidth) };
+    Ref<SVGAnimatedLength> m_height { SVGAnimatedLength::create(this, LengthModeHeight) };
 
     bool m_haveFiredLoadEvent { false };
     bool m_shadowTreeNeedsUpdate { true };
index d3624c2..79fd2fc 100644 (file)
@@ -25,8 +25,6 @@
 
 #pragma once
 
-#include "SVGLengthListValues.h"
-#include "SVGLengthValue.h"
 #include "SVGPathByteStream.h"
 #include "SVGTransformListValues.h"
 
@@ -35,8 +33,6 @@
 namespace WebCore {
 
 using SVGValueVariant = Variant<
-    SVGLengthValue*,
-    SVGLengthListValues*,
     SVGPathByteStream*,
     SVGTransformListValues*
 >;
index 70f19fd..a766a27 100644 (file)
@@ -109,6 +109,53 @@ private:
 };
 
 template<typename OwnerType>
+class SVGAnimatedLengthAccessor final : public SVGAnimatedPropertyAccessor<OwnerType, SVGAnimatedLength> {
+    using Base = SVGAnimatedPropertyAccessor<OwnerType, SVGAnimatedLength>;
+    using Base::property;
+
+public:
+    using Base::Base;
+    template<Ref<SVGAnimatedLength> OwnerType::*property>
+    constexpr static const SVGMemberAccessor<OwnerType>& singleton() { return Base::template singleton<SVGAnimatedLengthAccessor, property>(); }
+
+private:
+    bool isAnimatedLength() const override { return true; }
+
+    std::unique_ptr<SVGAttributeAnimator> createAnimator(OwnerType& owner, const QualifiedName& attributeName, AnimationMode animationMode, CalcMode calcMode, bool isAccumulated, bool isAdditive) const final
+    {
+        SVGLengthMode lengthMode = property(owner)->baseVal()->value().unitMode();
+        return SVGAnimatedLengthAnimator::create(attributeName, property(owner), animationMode, calcMode, isAccumulated, isAdditive, lengthMode);
+    }
+
+    void appendAnimatedInstance(OwnerType& owner, SVGAttributeAnimator& animator) const final
+    {
+        static_cast<SVGAnimatedLengthAnimator&>(animator).appendAnimatedInstance(property(owner));
+    }
+};
+
+template<typename OwnerType>
+class SVGAnimatedLengthListAccessor final : public SVGAnimatedPropertyAccessor<OwnerType, SVGAnimatedLengthList> {
+    using Base = SVGAnimatedPropertyAccessor<OwnerType, SVGAnimatedLengthList>;
+    using Base::property;
+
+public:
+    using Base::Base;
+    template<Ref<SVGAnimatedLengthList> OwnerType::*property>
+    constexpr static const SVGMemberAccessor<OwnerType>& singleton() { return Base::template singleton<SVGAnimatedLengthListAccessor, property>(); }
+
+private:
+    std::unique_ptr<SVGAttributeAnimator> createAnimator(OwnerType& owner, const QualifiedName& attributeName, AnimationMode animationMode, CalcMode calcMode, bool isAccumulated, bool isAdditive) const final
+    {
+        return SVGAnimatedLengthListAnimator::create(attributeName, property(owner), animationMode, calcMode, isAccumulated, isAdditive, LengthModeWidth);
+    }
+
+    void appendAnimatedInstance(OwnerType& owner, SVGAttributeAnimator& animator) const final
+    {
+        static_cast<SVGAnimatedLengthListAnimator&>(animator).appendAnimatedInstance(property(owner));
+    }
+};
+
+template<typename OwnerType>
 class SVGAnimatedNumberAccessor final : public SVGAnimatedPropertyAccessor<OwnerType, SVGAnimatedNumber> {
     using Base = SVGAnimatedPropertyAccessor<OwnerType, SVGAnimatedNumber>;
 
index 8d4aa6b..a197941 100644 (file)
@@ -75,6 +75,8 @@ public:
 
     void apply(SVGElement* targetElement) override
     {
+        if (isAnimatedStylePropertyAniamtor(targetElement))
+            applyAnimatedStylePropertyChange(targetElement, m_animated->animValAsString());
         applyAnimatedPropertyChange(targetElement);
     }
 
@@ -88,6 +90,8 @@ public:
             instance->instanceStopAnimation();
 
         applyAnimatedPropertyChange(targetElement);
+        if (isAnimatedStylePropertyAniamtor(targetElement))
+            removeAnimatedStyleProperty(targetElement);
     }
 
     float calculateDistance(SVGElement* targetElement, const String& from, const String& to) const override
index a7f35d3..95bcbd6 100644 (file)
@@ -120,6 +120,48 @@ private:
     }
 };
 
+class SVGAnimatedLengthAnimator final : public SVGAnimatedPropertyAnimator<SVGAnimatedLength, SVGAnimationLengthFunction> {
+    using Base = SVGAnimatedPropertyAnimator<SVGAnimatedLength, SVGAnimationLengthFunction>;
+
+public:
+    SVGAnimatedLengthAnimator(const QualifiedName& attributeName, Ref<SVGAnimatedLength>& animated, AnimationMode animationMode, CalcMode calcMode, bool isAccumulated, bool isAdditive, SVGLengthMode lengthMode)
+        : Base(attributeName, animated, animationMode, calcMode, isAccumulated, isAdditive, lengthMode)
+    {
+    }
+
+    static auto create(const QualifiedName& attributeName, Ref<SVGAnimatedLength>& animated, AnimationMode animationMode, CalcMode calcMode, bool isAccumulated, bool isAdditive, SVGLengthMode lengthMode)
+    {
+        return std::make_unique<SVGAnimatedLengthAnimator>(attributeName, animated, animationMode, calcMode, isAccumulated, isAdditive, lengthMode);
+    }
+
+private:
+    void progress(SVGElement* targetElement, float percentage, unsigned repeatCount) final
+    {
+        m_function.progress(targetElement, percentage, repeatCount, m_animated->animVal()->value());
+    }
+};
+
+class SVGAnimatedLengthListAnimator final : public SVGAnimatedPropertyAnimator<SVGAnimatedLengthList, SVGAnimationLengthListFunction> {
+    using Base = SVGAnimatedPropertyAnimator<SVGAnimatedLengthList, SVGAnimationLengthListFunction>;
+
+public:
+    SVGAnimatedLengthListAnimator(const QualifiedName& attributeName, Ref<SVGAnimatedLengthList>& animated, AnimationMode animationMode, CalcMode calcMode, bool isAccumulated, bool isAdditive, SVGLengthMode lengthMode)
+        : Base(attributeName, animated, animationMode, calcMode, isAccumulated, isAdditive, lengthMode)
+    {
+    }
+
+    static auto create(const QualifiedName& attributeName, Ref<SVGAnimatedLengthList>& animated, AnimationMode animationMode, CalcMode calcMode, bool isAccumulated, bool isAdditive, SVGLengthMode lengthMode)
+    {
+        return std::make_unique<SVGAnimatedLengthListAnimator>(attributeName, animated, animationMode, calcMode, isAccumulated, isAdditive, lengthMode);
+    }
+
+private:
+    void progress(SVGElement* targetElement, float percentage, unsigned repeatCount) final
+    {
+        m_function.progress(targetElement, percentage, repeatCount, m_animated->animVal());
+    }
+};
+
 class SVGAnimatedNumberAnimator final : public SVGAnimatedPropertyAnimator<SVGAnimatedNumber, SVGAnimationNumberFunction> {
     friend class SVGAnimatedPropertyPairAnimator<SVGAnimatedNumberAnimator, SVGAnimatedNumberAnimator>;
     friend class SVGAnimatedNumberPairAnimator;
index 96120fd..fe2be1a 100644 (file)
 
 #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 "SVGLength.h"
+#include "SVGLengthList.h"
 #include "SVGMarkerTypes.h"
 #include "SVGNumberList.h"
 #include "SVGPointList.h"
@@ -50,9 +50,11 @@ using SVGAnimatedString = SVGAnimatedPrimitiveProperty<String>;
 using SVGAnimatedEnumeration = SVGAnimatedDecoratedProperty<SVGDecoratedEnumeration, unsigned>;
 
 using SVGAnimatedAngle = SVGAnimatedValueProperty<SVGAngle>;
+using SVGAnimatedLength = SVGAnimatedValueProperty<SVGLength>;
 using SVGAnimatedRect = SVGAnimatedValueProperty<SVGRect>;
 using SVGAnimatedPreserveAspectRatio = SVGAnimatedValueProperty<SVGPreserveAspectRatio>;
 
+using SVGAnimatedLengthList = SVGAnimatedPropertyList<SVGLengthList>;
 using SVGAnimatedNumberList = SVGAnimatedPropertyList<SVGNumberList>;
 using SVGAnimatedPointList = SVGAnimatedPropertyList<SVGPointList>;
 
index 48ffa87..8fd9543 100644 (file)
 #pragma once
 
 #include "SVGAnimationAdditiveListFunction.h"
+#include "SVGLengthList.h"
 #include "SVGPointList.h"
 
 namespace WebCore {
 
 class SVGElement;
 
+class SVGAnimationLengthListFunction : public SVGAnimationAdditiveListFunction<SVGLengthList> {
+    using Base = SVGAnimationAdditiveListFunction<SVGLengthList>;
+
+public:
+    SVGAnimationLengthListFunction(AnimationMode animationMode, CalcMode calcMode, bool isAccumulated, bool isAdditive, SVGLengthMode lengthMode)
+        : Base(animationMode, calcMode, isAccumulated, isAdditive, lengthMode)
+    {
+    }
+
+    void setFromAndToValues(SVGElement*, const String& from, const String& to) override
+    {
+        m_from->parse(from);
+        m_to->parse(to);
+    }
+
+    void setToAtEndOfDurationValue(const String& toAtEndOfDuration) override
+    {
+        m_toAtEndOfDuration->parse(toAtEndOfDuration);
+    }
+
+    void progress(SVGElement* targetElement, float percentage, unsigned repeatCount, RefPtr<SVGLengthList>& animated)
+    {
+        if (!adjustAnimatedList(m_animationMode, percentage, animated))
+            return;
+
+        const Vector<Ref<SVGLength>>& fromItems = m_animationMode == AnimationMode::To ? animated->items() : m_from->items();
+        const Vector<Ref<SVGLength>>& toItems = m_to->items();
+        const Vector<Ref<SVGLength>>& toAtEndOfDurationItems = toAtEndOfDuration()->items();
+        Vector<Ref<SVGLength>>& animatedItems = animated->items();
+        SVGLengthMode lengthMode = animated->lengthMode();
+
+        SVGLengthContext lengthContext(targetElement);
+        for (unsigned i = 0; i < toItems.size(); ++i) {
+            SVGLengthType unitType = (i < fromItems.size() && percentage < 0.5 ? fromItems : toItems)[i]->value().unitType();
+
+            float from = i < fromItems.size() ? fromItems[i]->value().value(lengthContext) : 0;
+            float to = toItems[i]->value().value(lengthContext);
+            float toAtEndOfDuration = i < toAtEndOfDurationItems.size() ? toAtEndOfDurationItems[i]->value().value(lengthContext) : 0;
+            float value = animatedItems[i]->value().value(lengthContext);
+
+            value = Base::progress(percentage, repeatCount, from, to, toAtEndOfDuration, value);
+            animatedItems[i]->value().setValue(lengthContext, value, lengthMode, unitType);
+        }
+    }
+
+private:
+    void addFromAndToValues(SVGElement* targetElement) override
+    {
+        const Vector<Ref<SVGLength>>& fromItems = m_from->items();
+        const Vector<Ref<SVGLength>>& toItems = m_to->items();
+
+        if (!fromItems.size() || fromItems.size() != toItems.size())
+            return;
+
+        SVGLengthContext lengthContext(targetElement);
+        for (unsigned i = 0; i < fromItems.size(); ++i) {
+            const SVGLengthValue& fromValue = fromItems[i]->value();
+            SVGLengthValue& toValue = toItems[i]->value();
+            toValue.setValue(toValue.value(lengthContext) + fromValue.value(lengthContext), lengthContext);
+        }
+    }
+};
+
 class SVGAnimationNumberListFunction : public SVGAnimationAdditiveListFunction<SVGNumberList> {
 public:
     using Base = SVGAnimationAdditiveListFunction<SVGNumberList>;
index 51de92d..6dc5f6d 100644 (file)
@@ -148,6 +148,59 @@ private:
     }
 };
 
+class SVGAnimationLengthFunction : public SVGAnimationAdditiveValueFunction<SVGLengthValue> {
+    using Base = SVGAnimationAdditiveValueFunction<SVGLengthValue>;
+
+public:
+    SVGAnimationLengthFunction(AnimationMode animationMode, CalcMode calcMode, bool isAccumulated, bool isAdditive, SVGLengthMode lengthMode)
+        : Base(animationMode, calcMode, isAccumulated, isAdditive)
+        , m_lengthMode(lengthMode)
+    {
+    }
+
+    void setFromAndToValues(SVGElement*, const String& from, const String& to) override
+    {
+        m_from = SVGLengthValue(m_lengthMode, from);
+        m_to = SVGLengthValue(m_lengthMode, to);
+    }
+
+    void setToAtEndOfDurationValue(const String& toAtEndOfDuration) override
+    {
+        m_toAtEndOfDuration = SVGLengthValue(m_lengthMode, toAtEndOfDuration);
+    }
+
+    void progress(SVGElement* targetElement, float percentage, unsigned repeatCount, SVGLengthValue& animated)
+    {
+        SVGLengthContext lengthContext(targetElement);
+        SVGLengthType unitType = percentage < 0.5 ? m_from.unitType() : m_to.unitType();
+
+        float from = (m_animationMode == AnimationMode::To ? animated : m_from).value(lengthContext);
+        float to = m_to.value(lengthContext);
+        float toAtEndOfDuration = this->toAtEndOfDuration().value(lengthContext);
+        float value = animated.value(lengthContext);
+
+        value = Base::progress(percentage, repeatCount, from, to, toAtEndOfDuration, value);
+        animated = { lengthContext, value, m_lengthMode, unitType };
+    }
+
+    float calculateDistance(SVGElement* targetElement, const String& from, const String& to) const override
+    {
+        SVGLengthContext lengthContext(targetElement);
+        auto fromLength = SVGLengthValue(m_lengthMode, from);
+        auto toLength = SVGLengthValue(m_lengthMode, to);
+        return fabsf(toLength.value(lengthContext) - fromLength.value(lengthContext));
+    }
+
+private:
+    void addFromAndToValues(SVGElement* targetElement) override
+    {
+        SVGLengthContext lengthContext(targetElement);
+        m_to.setValue(m_to.value(lengthContext) + m_from.value(lengthContext), lengthContext);
+    }
+
+    SVGLengthMode m_lengthMode;
+};
+
 class SVGAnimationNumberFunction : public SVGAnimationAdditiveValueFunction<float> {
     friend class SVGAnimatedNumberPairAnimator;
 
index dc46a0f..256afd0 100644 (file)
 
 namespace WebCore {
 
+bool SVGAttributeAnimator::isAnimatedStylePropertyAniamtor(const SVGElement* targetElement) const
+{
+    return targetElement->isAnimatedStyleAttribute(m_attributeName);
+}
+
 void SVGAttributeAnimator::applyAnimatedStylePropertyChange(SVGElement* element, CSSPropertyID id, const String& value)
 {
     ASSERT(element);
index 894d5e7..827826e 100644 (file)
@@ -74,6 +74,8 @@ public:
     virtual float calculateDistance(SVGElement*, const String&, const String&) const { return -1; }
 
 protected:
+    bool isAnimatedStylePropertyAniamtor(const SVGElement*) const;
+
     static void applyAnimatedStylePropertyChange(SVGElement*, CSSPropertyID, const String& value);
     static void removeAnimatedStyleProperty(SVGElement*, CSSPropertyID);
     static void applyAnimatedPropertyChange(SVGElement*, const QualifiedName&);
index e57ec16..194f639 100644 (file)
@@ -25,8 +25,6 @@
 
 #pragma once
 
-#include "SVGAnimatedLength.h"
-#include "SVGAnimatedLengthList.h"
 #include "SVGAnimatedTransformList.h"
 #include "SVGAttributeAccessor.h"
 #include "SVGLegacyAnimatedProperty.h"
@@ -51,18 +49,6 @@ public:
     }
 
     // Animatable attributes
-    template<const LazyNeverDestroyed<const QualifiedName>& attributeName, SVGAnimatedLengthAttribute OwnerType::*attribute>
-    void registerAttribute()
-    {
-        registerAttribute(SVGAnimatedLengthAttributeAccessor<OwnerType>::template singleton<attributeName, attribute>());
-    }
-
-    template<const LazyNeverDestroyed<const QualifiedName>& attributeName, SVGAnimatedLengthListAttribute OwnerType::*attribute>
-    void registerAttribute()
-    {
-        registerAttribute(SVGAnimatedLengthListAttributeAccessor<OwnerType>::template singleton<attributeName, attribute>());
-    }
-
     template<const LazyNeverDestroyed<const QualifiedName>& attributeName, SVGAnimatedTransformListAttribute OwnerType::*attribute>
     void registerAttribute()
     {
index 539d46a..ad50d42 100644 (file)
 
 #pragma once
 
+#include "SVGLength.h"
 #include "SVGNames.h"
 #include "SVGPrimitivePropertyAnimatorImpl.h"
+#include "SVGValuePropertyAnimatorImpl.h"
+#include "SVGValuePropertyListAnimatorImpl.h"
 
 namespace WebCore {
 
@@ -80,6 +83,16 @@ private:
         return SVGColorAnimator::create(attributeName, WTFMove(property), animationMode, calcMode, isAccumulated, isAdditive);
     }
 
+    static auto createLengthAnimator(const QualifiedName& attributeName, Ref<SVGProperty>&& property, AnimationMode animationMode, CalcMode calcMode, bool isAccumulated, bool isAdditive)
+    {
+        return SVGLengthAnimator::create(attributeName, WTFMove(property), animationMode, calcMode, isAccumulated, isAdditive);
+    }
+
+    static auto createLengthListAnimator(const QualifiedName& attributeName, Ref<SVGProperty>&& property, AnimationMode animationMode, CalcMode calcMode, bool isAccumulated, bool isAdditive)
+    {
+        return SVGLengthListAnimator::create(attributeName, WTFMove(property), animationMode, calcMode, isAccumulated, isAdditive);
+    }
+
     static auto createNumberAnimator(const QualifiedName& attributeName, Ref<SVGProperty>&& property, AnimationMode animationMode, CalcMode calcMode, bool isAccumulated, bool isAdditive)
     {
         return SVGNumberAnimator::create(attributeName,  WTFMove(property), animationMode, calcMode, isAccumulated, isAdditive);
@@ -93,13 +106,22 @@ private:
     static const AttributeAnimatorCreator& attributeAnimatorCreator()
     {
         static NeverDestroyed<AttributeAnimatorCreator> map = AttributeAnimatorCreator({
-            { SVGNames::colorAttr->impl(),          std::make_pair(SVGValueProperty<Color>::create, SVGPropertyAnimatorFactory::createColorAnimator) },
-            { SVGNames::fillAttr->impl(),           std::make_pair(SVGValueProperty<Color>::create, SVGPropertyAnimatorFactory::createColorAnimator) },
-            { SVGNames::flood_colorAttr->impl(),    std::make_pair(SVGValueProperty<Color>::create, SVGPropertyAnimatorFactory::createColorAnimator) },
-            { SVGNames::lighting_colorAttr->impl(), std::make_pair(SVGValueProperty<Color>::create, SVGPropertyAnimatorFactory::createColorAnimator) },
-            { SVGNames::stop_colorAttr->impl(),     std::make_pair(SVGValueProperty<Color>::create, SVGPropertyAnimatorFactory::createColorAnimator) },
-            { SVGNames::strokeAttr->impl(),         std::make_pair(SVGValueProperty<Color>::create, SVGPropertyAnimatorFactory::createColorAnimator) },
+            { SVGNames::colorAttr->impl(),              std::make_pair(SVGValueProperty<Color>::create, SVGPropertyAnimatorFactory::createColorAnimator) },
+            { SVGNames::fillAttr->impl(),               std::make_pair(SVGValueProperty<Color>::create, SVGPropertyAnimatorFactory::createColorAnimator) },
+            { SVGNames::flood_colorAttr->impl(),        std::make_pair(SVGValueProperty<Color>::create, SVGPropertyAnimatorFactory::createColorAnimator) },
+            { SVGNames::lighting_colorAttr->impl(),     std::make_pair(SVGValueProperty<Color>::create, SVGPropertyAnimatorFactory::createColorAnimator) },
+            { SVGNames::stop_colorAttr->impl(),         std::make_pair(SVGValueProperty<Color>::create, SVGPropertyAnimatorFactory::createColorAnimator) },
+            { SVGNames::strokeAttr->impl(),             std::make_pair(SVGValueProperty<Color>::create, SVGPropertyAnimatorFactory::createColorAnimator) },
 
+            { SVGNames::font_sizeAttr->impl(),          std::make_pair([]() { return SVGLength::create(); }, SVGPropertyAnimatorFactory::createLengthAnimator) },
+            { SVGNames::kerningAttr->impl(),            std::make_pair([]() { return SVGLength::create(); }, SVGPropertyAnimatorFactory::createLengthAnimator) },
+            { SVGNames::letter_spacingAttr->impl(),     std::make_pair([]() { return SVGLength::create(); }, SVGPropertyAnimatorFactory::createLengthAnimator) },
+            { SVGNames::stroke_dashoffsetAttr->impl(),  std::make_pair([]() { return SVGLength::create(); }, SVGPropertyAnimatorFactory::createLengthAnimator) },
+            { SVGNames::stroke_widthAttr->impl(),       std::make_pair([]() { return SVGLength::create(); }, SVGPropertyAnimatorFactory::createLengthAnimator) },
+            { SVGNames::word_spacingAttr->impl(),       std::make_pair([]() { return SVGLength::create(); }, SVGPropertyAnimatorFactory::createLengthAnimator) },
+
+            { SVGNames::stroke_dasharrayAttr->impl(),   std::make_pair([]() { return SVGLengthList::create(); }, SVGPropertyAnimatorFactory::createLengthListAnimator) },
+            
             { SVGNames::fill_opacityAttr->impl(),       std::make_pair(SVGValueProperty<float>::create, SVGPropertyAnimatorFactory::createNumberAnimator) },
             { SVGNames::flood_opacityAttr->impl(),      std::make_pair(SVGValueProperty<float>::create, SVGPropertyAnimatorFactory::createNumberAnimator) },
             { SVGNames::opacityAttr->impl(),            std::make_pair(SVGValueProperty<float>::create, SVGPropertyAnimatorFactory::createNumberAnimator) },
index 57f7985..d1b93a2 100644 (file)
@@ -66,6 +66,18 @@ public:
     {
         registerProperty(attributeName, SVGAnimatedIntegerAccessor<OwnerType>::template singleton<property>());
     }
+    
+    template<const LazyNeverDestroyed<const QualifiedName>& attributeName, Ref<SVGAnimatedLength> OwnerType::*property>
+    static void registerProperty()
+    {
+        registerProperty(attributeName, SVGAnimatedLengthAccessor<OwnerType>::template singleton<property>());
+    }
+
+    template<const LazyNeverDestroyed<const QualifiedName>& attributeName, Ref<SVGAnimatedLengthList> OwnerType::*property>
+    static void registerProperty()
+    {
+        registerProperty(attributeName, SVGAnimatedLengthListAccessor<OwnerType>::template singleton<property>());
+    }
 
     template<const LazyNeverDestroyed<const QualifiedName>& attributeName, Ref<SVGAnimatedNumber> OwnerType::*property>
     static void registerProperty()
diff --git a/Source/WebCore/svg/properties/SVGValuePropertyAnimator.h b/Source/WebCore/svg/properties/SVGValuePropertyAnimator.h
new file mode 100644 (file)
index 0000000..53798d1
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * 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 "SVGPropertyAnimator.h"
+
+namespace WebCore {
+
+template<typename PropertyType, typename AnimationFunction>
+class SVGValuePropertyAnimator : public SVGPropertyAnimator<AnimationFunction> {
+    using Base = SVGPropertyAnimator<AnimationFunction>;
+    using Base::Base;
+    using Base::applyAnimatedStylePropertyChange;
+    using Base::m_function;
+
+public:
+    template<typename... Arguments>
+    SVGValuePropertyAnimator(const QualifiedName& attributeName, Ref<SVGProperty>&& property, Arguments&&... arguments)
+        : Base(attributeName, std::forward<Arguments>(arguments)...)
+        , m_property(static_reference_cast<PropertyType>(WTFMove(property)))
+    {
+    }
+
+    void progress(SVGElement* targetElement, float percentage, unsigned repeatCount) override
+    {
+        m_function.progress(targetElement, percentage, repeatCount, m_property->value());
+    }
+
+    void apply(SVGElement* targetElement) override
+    {
+        applyAnimatedStylePropertyChange(targetElement, m_property->valueAsString());
+    }
+
+protected:
+    using Base::computeCSSPropertyValue;
+    using Base::m_attributeName;
+
+    Ref<PropertyType> m_property;
+};
+
+}
diff --git a/Source/WebCore/svg/properties/SVGValuePropertyAnimatorImpl.h b/Source/WebCore/svg/properties/SVGValuePropertyAnimatorImpl.h
new file mode 100644 (file)
index 0000000..118886c
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 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 "SVGAnimationFunction.h"
+#include "SVGValuePropertyAnimator.h"
+
+namespace WebCore {
+
+class SVGLengthAnimator final : public SVGValuePropertyAnimator<SVGLength, SVGAnimationLengthFunction> {
+    using Base = SVGValuePropertyAnimator<SVGLength, SVGAnimationLengthFunction>;
+    using Base::Base;
+    using Base::m_attributeName;
+    using Base::m_property;
+
+public:
+    static auto create(const QualifiedName& attributeName, Ref<SVGProperty>&& property, AnimationMode animationMode, CalcMode calcMode, bool isAccumulated, bool isAdditive)
+    {
+        return std::make_unique<SVGLengthAnimator>(attributeName, WTFMove(property), animationMode, calcMode, isAccumulated, isAdditive, LengthModeOther);
+    }
+
+    void start(SVGElement* targetElement) override
+    {
+        String baseValue = computeCSSPropertyValue(targetElement, cssPropertyID(m_attributeName.localName()));
+        SVGLengthValue value(LengthModeOther);
+        if (!value.setValueAsString(baseValue).hasException())
+            m_property->setValue(value);
+    }
+};
+
+}
+
diff --git a/Source/WebCore/svg/properties/SVGValuePropertyListAnimator.h b/Source/WebCore/svg/properties/SVGValuePropertyListAnimator.h
new file mode 100644 (file)
index 0000000..f274f18
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * 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 "SVGPropertyAnimator.h"
+
+namespace WebCore {
+
+template<typename ListType, typename AnimationFunction>
+class SVGValuePropertyListAnimator : public SVGPropertyAnimator<AnimationFunction> {
+    using Base = SVGPropertyAnimator<AnimationFunction>;
+    using Base::Base;
+    using Base::applyAnimatedStylePropertyChange;
+    using Base::m_function;
+
+public:
+    template<typename... Arguments>
+    SVGValuePropertyListAnimator(const QualifiedName& attributeName, Ref<SVGProperty>&& property, Arguments&&... arguments)
+        : Base(attributeName, std::forward<Arguments>(arguments)...)
+        , m_list(static_reference_cast<ListType>(WTFMove(property)))
+    {
+    }
+
+    void progress(SVGElement* targetElement, float percentage, unsigned repeatCount) override
+    {
+        m_function.progress(targetElement, percentage, repeatCount, m_list);
+    }
+
+    void apply(SVGElement* targetElement) override
+    {
+        applyAnimatedStylePropertyChange(targetElement, m_list->valueAsString());
+    }
+
+protected:
+    using Base::computeCSSPropertyValue;
+    using Base::m_attributeName;
+
+    RefPtr<ListType> m_list;
+};
+
+}
diff --git a/Source/WebCore/svg/properties/SVGValuePropertyListAnimatorImpl.h b/Source/WebCore/svg/properties/SVGValuePropertyListAnimatorImpl.h
new file mode 100644 (file)
index 0000000..5ee8ac3
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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 "SVGAnimationFunction.h"
+#include "SVGValuePropertyListAnimator.h"
+
+namespace WebCore {
+
+class SVGLengthListAnimator final : public SVGValuePropertyListAnimator<SVGLengthList, SVGAnimationLengthListFunction> {
+    using Base = SVGValuePropertyListAnimator<SVGLengthList, SVGAnimationLengthListFunction>;
+    using Base::Base;
+    using Base::m_attributeName;
+    using Base::m_list;
+
+public:
+    static auto create(const QualifiedName& attributeName, Ref<SVGProperty>&& property, AnimationMode animationMode, CalcMode calcMode, bool isAccumulated, bool isAdditive)
+    {
+        return std::make_unique<SVGLengthListAnimator>(attributeName, WTFMove(property), animationMode, calcMode, isAccumulated, isAdditive, LengthModeOther);
+    }
+
+    void start(SVGElement* targetElement) override
+    {
+        String baseValue = computeCSSPropertyValue(targetElement, cssPropertyID(m_attributeName.localName()));
+        if (!m_list->parse(baseValue))
+            m_list->clearItems();
+    }
+};
+
+}