[SVG2] Add the 'orient' property of the interface SVGMarkerElement
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 14 Nov 2019 02:21:47 +0000 (02:21 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 14 Nov 2019 02:21:47 +0000 (02:21 +0000)
https://bugs.webkit.org/show_bug.cgi?id=203646

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

LayoutTests/imported/w3c:

* web-platform-tests/svg/idlharness.window-expected.txt:
* web-platform-tests/svg/types/scripted/SVGAnimatedEnumeration-SVGMarkerElement-expected.txt:

Source/WebCore:

This patch does the following:

1. Adding the 'orient' property of the interface SVGMarkerElement:
   The specs link is:
   https://www.w3.org/TR/SVG2/painting.html#InterfaceSVGMarkerElement

2. Keeping the pair properties <orientAngle, orientType> in sync when
   when one of them changes to keep them in consistent state.

3. Setting the value of SVGMarkerOrientAutoStartReverse: The specs
   https://www.w3.org/TR/SVG2/painting.html#__svg__SVGMarkerElement__orient
   says that when setting the 'orient' attribute to "auto-start-reverse",
   the value of orientType should be SVG_MARKER_ORIENT_UNKNOWN. Therefore
   SVGMarkerOrientAutoStartReverse has to be equal to SVGMarkerOrientUnknown.

* svg/SVGAngle.h:
(WebCore::SVGAngle::unitType const):
(WebCore::SVGAngle::valueForBindings const):
(WebCore::SVGAngle::valueInSpecifiedUnits const):
(WebCore::SVGAngle::unitType): Deleted.
(WebCore::SVGAngle::valueForBindings): Deleted.
(WebCore::SVGAngle::valueInSpecifiedUnits): Deleted.
Make these functions const.

* svg/SVGElement.cpp:
(WebCore::SVGElement::commitPropertyChange):
Calling SVGPropertyRegistry::setAnimatedPropertDirty() to set the dirty
flag of the animated  property through its accessor.

* svg/SVGMarkerElement.cpp:
(WebCore::SVGMarkerElement::orient const):
(WebCore::SVGMarkerElement::setOrient):
Add the new property handlers.

(WebCore::SVGMarkerElement::setOrientToAuto):
(WebCore::SVGMarkerElement::setOrientToAngle):
Fix the bug of not setting the unitType of the SVGAngle in orientAngle.

* svg/SVGMarkerElement.h:
Delete unused enum value SVG_MARKER_ORIENT_AUTOSTARTREVERSE.

* svg/SVGMarkerElement.idl:

* svg/SVGMarkerTypes.h:
(WebCore::SVGPropertyTraits<SVGMarkerOrientType>::highestEnumValue):
(WebCore::SVGIDLEnumLimits<SVGMarkerOrientType>::highestExposedEnumValue): Deleted.
Fix the value of SVGMarkerOrientAutoStartReverse. No need for
highestExposedEnumValue() since all the enum values are now exposed.

* svg/properties/SVGAnimatedPropertyPairAccessorImpl.h:
Keep the pair properties <orientAngle, orientType> in sync.

* svg/properties/SVGMemberAccessor.h:
(WebCore::SVGMemberAccessor::setDirty const):
This is what SVGElement::commitPropertyChange() used to do for all properties.

* svg/properties/SVGPropertyOwnerRegistry.h:
* svg/properties/SVGPropertyRegistry.h:

LayoutTests:

The pair properties <orientAngle, orientType> are now in sync. Fix the
tests which were assuming that these properties can change independently.

* svg/dom/SVGAnimatedEnumeration-SVGMarkerElement-expected.txt:
* svg/dom/SVGAnimatedEnumeration-SVGMarkerElement.html:
* svg/dynamic-updates/SVGMarkerElement-dom-orient-attr-expected.txt:
* svg/dynamic-updates/SVGMarkerElement-dom-orient-attr.html:

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

19 files changed:
LayoutTests/ChangeLog
LayoutTests/imported/w3c/ChangeLog
LayoutTests/imported/w3c/web-platform-tests/svg/idlharness.window-expected.txt
LayoutTests/imported/w3c/web-platform-tests/svg/types/scripted/SVGAnimatedEnumeration-SVGMarkerElement-expected.txt
LayoutTests/svg/dom/SVGAnimatedEnumeration-SVGMarkerElement-expected.txt
LayoutTests/svg/dom/SVGAnimatedEnumeration-SVGMarkerElement.html
LayoutTests/svg/dynamic-updates/SVGMarkerElement-dom-orient-attr-expected.txt
LayoutTests/svg/dynamic-updates/SVGMarkerElement-dom-orient-attr.html
Source/WebCore/ChangeLog
Source/WebCore/svg/SVGAngle.h
Source/WebCore/svg/SVGElement.cpp
Source/WebCore/svg/SVGMarkerElement.cpp
Source/WebCore/svg/SVGMarkerElement.h
Source/WebCore/svg/SVGMarkerElement.idl
Source/WebCore/svg/SVGMarkerTypes.h
Source/WebCore/svg/properties/SVGAnimatedPropertyPairAccessorImpl.h
Source/WebCore/svg/properties/SVGMemberAccessor.h
Source/WebCore/svg/properties/SVGPropertyOwnerRegistry.h
Source/WebCore/svg/properties/SVGPropertyRegistry.h

index 2a32104..09751b3 100644 (file)
@@ -1,3 +1,18 @@
+2019-11-13  Said Abou-Hallawa  <sabouhallawa@apple.com>
+
+        [SVG2] Add the 'orient' property of the interface SVGMarkerElement
+        https://bugs.webkit.org/show_bug.cgi?id=203646
+
+        Reviewed by Simon Fraser.
+
+        The pair properties <orientAngle, orientType> are now in sync. Fix the
+        tests which were assuming that these properties can change independently.
+
+        * svg/dom/SVGAnimatedEnumeration-SVGMarkerElement-expected.txt:
+        * svg/dom/SVGAnimatedEnumeration-SVGMarkerElement.html:
+        * svg/dynamic-updates/SVGMarkerElement-dom-orient-attr-expected.txt:
+        * svg/dynamic-updates/SVGMarkerElement-dom-orient-attr.html:
+
 2019-11-13  Fujii Hironori  <Hironori.Fujii@sony.com>
 
         [Win][DumpRenderTree][WebKitTestRunner] eventSender.keyDown should support function keys
index 249c814..b3b01f0 100644 (file)
@@ -1,3 +1,13 @@
+2019-11-13  Said Abou-Hallawa  <sabouhallawa@apple.com>
+
+        [SVG2] Add the 'orient' property of the interface SVGMarkerElement
+        https://bugs.webkit.org/show_bug.cgi?id=203646
+
+        Reviewed by Simon Fraser.
+
+        * web-platform-tests/svg/idlharness.window-expected.txt:
+        * web-platform-tests/svg/types/scripted/SVGAnimatedEnumeration-SVGMarkerElement-expected.txt:
+
 2019-11-13  youenn fablet  <youenn@apple.com>
 
         Layout Tests in imported/w3c/web-platform-tests/websockets/ are flakey failures after r246406
index d83c56d..9c8e0b9 100644 (file)
@@ -1375,7 +1375,7 @@ PASS SVGMarkerElement interface: attribute markerWidth
 PASS SVGMarkerElement interface: attribute markerHeight 
 PASS SVGMarkerElement interface: attribute orientType 
 PASS SVGMarkerElement interface: attribute orientAngle 
-FAIL SVGMarkerElement interface: attribute orient assert_true: The prototype object must have a property "orient" expected true got false
+PASS SVGMarkerElement interface: attribute orient 
 PASS SVGMarkerElement interface: operation setOrientToAuto() 
 PASS SVGMarkerElement interface: operation setOrientToAngle(SVGAngle) 
 PASS SVGMarkerElement interface: attribute viewBox 
@@ -1395,7 +1395,7 @@ PASS SVGMarkerElement interface: objects.marker must inherit property "markerWid
 PASS SVGMarkerElement interface: objects.marker must inherit property "markerHeight" with the proper type 
 PASS SVGMarkerElement interface: objects.marker must inherit property "orientType" with the proper type 
 PASS SVGMarkerElement interface: objects.marker must inherit property "orientAngle" with the proper type 
-FAIL SVGMarkerElement interface: objects.marker must inherit property "orient" with the proper type assert_inherits: property "orient" not found in prototype chain
+PASS SVGMarkerElement interface: objects.marker must inherit property "orient" with the proper type 
 PASS SVGMarkerElement interface: objects.marker must inherit property "setOrientToAuto()" with the proper type 
 PASS SVGMarkerElement interface: objects.marker must inherit property "setOrientToAngle(SVGAngle)" with the proper type 
 PASS SVGMarkerElement interface: calling setOrientToAngle(SVGAngle) on objects.marker with too few arguments must throw TypeError 
index bfe4858..3f77c1c 100644 (file)
@@ -76,13 +76,14 @@ PASS markerElement.getAttribute('orient') is "10deg"
 
 Switch to 'auto' value - by modifying orientType, this shouldn't change the orientAngle, but change the 'orient' attribute
 PASS markerElement.orientType.baseVal = SVGMarkerElement.SVG_MARKER_ORIENT_AUTO is SVGMarkerElement.SVG_MARKER_ORIENT_AUTO
-PASS markerElement.orientAngle.baseVal.value is 10
-PASS markerElement.orientAngle.baseVal.unitType is SVGAngle.SVG_ANGLETYPE_DEG
+PASS markerElement.orientAngle.baseVal.value is 0
+PASS markerElement.orientAngle.baseVal.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
 PASS markerElement.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_AUTO
 PASS markerElement.getAttribute('orient') is "auto"
 
 Switch to '10deg' value - by modifying orientType to be angle again, the 10deg should be preserved in the orientAngle, and the 'orient' attribute should change
 PASS markerElement.orientType.baseVal = SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE
+PASS markerElement.orientAngle.baseVal.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG, 10) is undefined.
 PASS markerElement.orientAngle.baseVal.value is 10
 PASS markerElement.orientAngle.baseVal.unitType is SVGAngle.SVG_ANGLETYPE_DEG
 PASS markerElement.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE
@@ -118,8 +119,8 @@ Switch to '100grad' value - only touch orientAngle, shouldn't change orientType
 PASS markerElement.orientAngle.baseVal.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_GRAD, 100) is undefined.
 PASS markerElement.orientAngle.baseVal.value is 90
 PASS markerElement.orientAngle.baseVal.unitType is SVGAngle.SVG_ANGLETYPE_GRAD
-PASS markerElement.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_AUTO
-PASS markerElement.getAttribute('orient') is "auto"
+PASS markerElement.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE
+PASS markerElement.getAttribute('orient') is "100grad"
 
 Finish switching to '100grad' value - by modifying the orientType to angle
 PASS markerElement.orientType.baseVal = SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE
index 2c5e670..44dab42 100644 (file)
@@ -102,14 +102,15 @@ shouldBeEqualToString("markerElement.getAttribute('orient')", "10deg");
 debug("");
 debug("Switch to 'auto' value - by modifying orientType, this shouldn't change the orientAngle, but change the 'orient' attribute");
 shouldBe("markerElement.orientType.baseVal = SVGMarkerElement.SVG_MARKER_ORIENT_AUTO", "SVGMarkerElement.SVG_MARKER_ORIENT_AUTO");
-shouldBe("markerElement.orientAngle.baseVal.value", "10");
-shouldBe("markerElement.orientAngle.baseVal.unitType", "SVGAngle.SVG_ANGLETYPE_DEG");
+shouldBe("markerElement.orientAngle.baseVal.value", "0");
+shouldBe("markerElement.orientAngle.baseVal.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
 shouldBe("markerElement.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_AUTO");
 shouldBeEqualToString("markerElement.getAttribute('orient')", "auto");
 
 debug("");
 debug("Switch to '10deg' value - by modifying orientType to be angle again, the 10deg should be preserved in the orientAngle, and the 'orient' attribute should change");
 shouldBe("markerElement.orientType.baseVal = SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE");
+shouldBeUndefined("markerElement.orientAngle.baseVal.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_DEG, 10)");
 shouldBe("markerElement.orientAngle.baseVal.value", "10");
 shouldBe("markerElement.orientAngle.baseVal.unitType", "SVGAngle.SVG_ANGLETYPE_DEG");
 shouldBe("markerElement.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE");
@@ -152,8 +153,8 @@ debug("Switch to '100grad' value - only touch orientAngle, shouldn't change orie
 shouldBeUndefined("markerElement.orientAngle.baseVal.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_GRAD, 100)");
 shouldBe("markerElement.orientAngle.baseVal.value", "90");
 shouldBe("markerElement.orientAngle.baseVal.unitType", "SVGAngle.SVG_ANGLETYPE_GRAD");
-shouldBe("markerElement.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_AUTO");
-shouldBeEqualToString("markerElement.getAttribute('orient')", "auto");
+shouldBe("markerElement.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE");
+shouldBeEqualToString("markerElement.getAttribute('orient')", "100grad");
 
 debug("");
 debug("Finish switching to '100grad' value - by modifying the orientType to angle");
index f6c14c1..9ea2f12 100644 (file)
@@ -5,7 +5,77 @@ Tests dynamic updates of the 'orient' attribute of the SVGMarkerElement object
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
+
+Test initial state
+PASS markerElement.orient is "45"
+PASS markerElement.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE
+PASS markerElement.orientAngle.baseVal.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
+PASS markerElement.orientAngle.baseVal.value is 45
 PASS markerElement.getAttribute('orient') is "45"
+
+Test the 'orient' property
+PASS markerElement.orient = 'auto' is "auto"
+PASS markerElement.orient is "auto"
+PASS markerElement.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_AUTO
+PASS markerElement.orientAngle.baseVal.value is 0
+PASS markerElement.getAttribute('orient') is "auto"
+
+PASS markerElement.orient = 'auto-start-reverse' is "auto-start-reverse"
+PASS markerElement.orient is "auto-start-reverse"
+PASS markerElement.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_UNKNOWN
+PASS markerElement.orientAngle.baseVal.value is 0
+PASS markerElement.getAttribute('orient') is "auto-start-reverse"
+
+PASS markerElement.orient = '45deg' is "45deg"
+PASS markerElement.orient is "45deg"
+PASS markerElement.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE
+PASS markerElement.orientAngle.baseVal.unitType is SVGAngle.SVG_ANGLETYPE_DEG
+PASS markerElement.orientAngle.baseVal.value is 45
+PASS markerElement.getAttribute('orient') is "45deg"
+
+Test the method setOrientToAngle()
+PASS markerElement.setOrientToAngle(angle) is undefined.
+PASS markerElement.orient is "1.57rad"
+PASS markerElement.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE
+PASS markerElement.orientAngle.baseVal.unitType is SVGAngle.SVG_ANGLETYPE_RAD
+PASS markerElement.orientAngle.baseVal.value.toFixed(1) is "90.0"
+PASS markerElement.getAttribute('orient') is "1.57rad"
+
+Test the method setOrientToAuto()
+PASS markerElement.setOrientToAuto() is undefined.
+PASS markerElement.orient is "auto"
+PASS markerElement.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_AUTO
+PASS markerElement.orientAngle.baseVal.value is 0
+PASS markerElement.getAttribute('orient') is "auto"
+
+Test the animated property 'orientAngle'
+PASS markerElement.orientAngle.baseVal.value = 45 is 45
+PASS markerElement.orient is "45"
+PASS markerElement.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE
+PASS markerElement.orientAngle.baseVal.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
+PASS markerElement.orientAngle.baseVal.value is 45
+PASS markerElement.getAttribute('orient') is "45"
+
+Test the animated property 'orientType'
+PASS markerElement.orientType.baseVal = SVGMarkerElement.SVG_MARKER_ORIENT_AUTO is SVGMarkerElement.SVG_MARKER_ORIENT_AUTO
+PASS markerElement.orient is "auto"
+PASS markerElement.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_AUTO
+PASS markerElement.orientAngle.baseVal.value is 0
+PASS markerElement.getAttribute('orient') is "auto"
+
+PASS markerElement.orientType.baseVal = SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE
+PASS markerElement.orientAngle.baseVal.value = -45 is -45
+PASS markerElement.orient is "-45"
+PASS markerElement.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE
+PASS markerElement.orientAngle.baseVal.unitType is SVGAngle.SVG_ANGLETYPE_UNSPECIFIED
+PASS markerElement.orientAngle.baseVal.value is -45
+PASS markerElement.getAttribute('orient') is "-45"
+
+Test the 'orient' attribute
+PASS markerElement.setAttribute('orient', '0') is undefined.
+PASS markerElement.orient is "0"
+PASS markerElement.orientType.baseVal is SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE
+PASS markerElement.orientAngle.baseVal.value is 0
 PASS markerElement.getAttribute('orient') is "0"
 PASS successfullyParsed is true
 
index 5449f58..31fa05a 100644 (file)
@@ -44,10 +44,90 @@ pathElement.setAttribute("marker-end", "url(#marker)");
 pathElement.setAttribute("d", "M 130 135 L 180 135 L 180 185");
 rootSVGElement.appendChild(pathElement);
 
+var angle = createSVGElement("svg").createSVGAngle();
+angle.newValueSpecifiedUnits(SVGAngle.SVG_ANGLETYPE_RAD, (Math.PI / 2).toFixed(2));
+
+debug("");
+debug("Test initial state");
+shouldBeEqualToString("markerElement.orient", "45");
+shouldBe("markerElement.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE");
+shouldBe("markerElement.orientAngle.baseVal.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
+shouldBe("markerElement.orientAngle.baseVal.value", "45");
+shouldBeEqualToString("markerElement.getAttribute('orient')", "45");
+
+debug("");
+debug("Test the 'orient' property");
+shouldBeEqualToString("markerElement.orient = 'auto'", "auto");
+shouldBeEqualToString("markerElement.orient", "auto");
+shouldBe("markerElement.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_AUTO");
+shouldBe("markerElement.orientAngle.baseVal.value", "0");
+shouldBeEqualToString("markerElement.getAttribute('orient')", "auto");
+
+debug("");
+shouldBeEqualToString("markerElement.orient = 'auto-start-reverse'", "auto-start-reverse");
+shouldBeEqualToString("markerElement.orient", "auto-start-reverse");
+shouldBe("markerElement.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_UNKNOWN");
+shouldBe("markerElement.orientAngle.baseVal.value", "0");
+shouldBeEqualToString("markerElement.getAttribute('orient')", "auto-start-reverse");
+
+debug("");
+shouldBeEqualToString("markerElement.orient = '45deg'", "45deg");
+shouldBeEqualToString("markerElement.orient", "45deg");
+shouldBe("markerElement.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE");
+shouldBe("markerElement.orientAngle.baseVal.unitType", "SVGAngle.SVG_ANGLETYPE_DEG");
+shouldBe("markerElement.orientAngle.baseVal.value", "45");
+shouldBeEqualToString("markerElement.getAttribute('orient')", "45deg");
+
+debug("");
+debug("Test the method setOrientToAngle()");
+shouldBeUndefined("markerElement.setOrientToAngle(angle)");
+shouldBeEqualToString("markerElement.orient", (Math.PI / 2).toFixed(2) + "rad");
+shouldBe("markerElement.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE");
+shouldBe("markerElement.orientAngle.baseVal.unitType", "SVGAngle.SVG_ANGLETYPE_RAD");
+shouldBeEqualToString("markerElement.orientAngle.baseVal.value.toFixed(1)", "90.0");
+shouldBeEqualToString("markerElement.getAttribute('orient')", (Math.PI / 2).toFixed(2) + "rad");
+
+debug("");
+debug("Test the method setOrientToAuto()");
+shouldBeUndefined("markerElement.setOrientToAuto()");
+shouldBeEqualToString("markerElement.orient", "auto");
+shouldBe("markerElement.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_AUTO");
+shouldBe("markerElement.orientAngle.baseVal.value", "0");
+shouldBeEqualToString("markerElement.getAttribute('orient')", "auto");
+
+debug("");
+debug("Test the animated property 'orientAngle'");
+shouldBe("markerElement.orientAngle.baseVal.value = 45", "45");
+shouldBeEqualToString("markerElement.orient", "45");
+shouldBe("markerElement.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE");
+shouldBe("markerElement.orientAngle.baseVal.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
+shouldBe("markerElement.orientAngle.baseVal.value", "45");
 shouldBeEqualToString("markerElement.getAttribute('orient')", "45");
 
+debug("");
+debug("Test the animated property 'orientType'");
+shouldBe("markerElement.orientType.baseVal = SVGMarkerElement.SVG_MARKER_ORIENT_AUTO", "SVGMarkerElement.SVG_MARKER_ORIENT_AUTO");
+shouldBeEqualToString("markerElement.orient", "auto");
+shouldBe("markerElement.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_AUTO");
+shouldBe("markerElement.orientAngle.baseVal.value", "0");
+shouldBeEqualToString("markerElement.getAttribute('orient')", "auto");
+
+debug("");
+shouldBe("markerElement.orientType.baseVal = SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE");
+shouldBe("markerElement.orientAngle.baseVal.value = -45", "-45");
+shouldBeEqualToString("markerElement.orient", "-45");
+shouldBe("markerElement.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE");
+shouldBe("markerElement.orientAngle.baseVal.unitType", "SVGAngle.SVG_ANGLETYPE_UNSPECIFIED");
+shouldBe("markerElement.orientAngle.baseVal.value", "-45");
+shouldBeEqualToString("markerElement.getAttribute('orient')", "-45");
+
 function repaintTest() {
-    markerElement.setAttribute("orient", "0");
+       debug("");
+       debug("Test the 'orient' attribute");
+    shouldBeUndefined("markerElement.setAttribute('orient', '0')");
+    shouldBeEqualToString("markerElement.orient", "0");
+    shouldBe("markerElement.orientType.baseVal", "SVGMarkerElement.SVG_MARKER_ORIENT_ANGLE");
+    shouldBe("markerElement.orientAngle.baseVal.value", "0");
     shouldBeEqualToString("markerElement.getAttribute('orient')", "0");
 
     completeTest();
index 6b8f36a..f2822a5 100644 (file)
@@ -1,3 +1,69 @@
+2019-11-13  Said Abou-Hallawa  <sabouhallawa@apple.com>
+
+        [SVG2] Add the 'orient' property of the interface SVGMarkerElement
+        https://bugs.webkit.org/show_bug.cgi?id=203646
+
+        Reviewed by Simon Fraser.
+
+        This patch does the following:
+
+        1. Adding the 'orient' property of the interface SVGMarkerElement:
+           The specs link is:
+           https://www.w3.org/TR/SVG2/painting.html#InterfaceSVGMarkerElement
+
+        2. Keeping the pair properties <orientAngle, orientType> in sync when
+           when one of them changes to keep them in consistent state.
+
+        3. Setting the value of SVGMarkerOrientAutoStartReverse: The specs
+           https://www.w3.org/TR/SVG2/painting.html#__svg__SVGMarkerElement__orient
+           says that when setting the 'orient' attribute to "auto-start-reverse",
+           the value of orientType should be SVG_MARKER_ORIENT_UNKNOWN. Therefore
+           SVGMarkerOrientAutoStartReverse has to be equal to SVGMarkerOrientUnknown.
+
+        * svg/SVGAngle.h:
+        (WebCore::SVGAngle::unitType const):
+        (WebCore::SVGAngle::valueForBindings const):
+        (WebCore::SVGAngle::valueInSpecifiedUnits const):
+        (WebCore::SVGAngle::unitType): Deleted.
+        (WebCore::SVGAngle::valueForBindings): Deleted.
+        (WebCore::SVGAngle::valueInSpecifiedUnits): Deleted.
+        Make these functions const.
+
+        * svg/SVGElement.cpp:
+        (WebCore::SVGElement::commitPropertyChange):
+        Calling SVGPropertyRegistry::setAnimatedPropertDirty() to set the dirty
+        flag of the animated  property through its accessor.
+
+        * svg/SVGMarkerElement.cpp:
+        (WebCore::SVGMarkerElement::orient const):
+        (WebCore::SVGMarkerElement::setOrient):
+        Add the new property handlers.
+
+        (WebCore::SVGMarkerElement::setOrientToAuto):
+        (WebCore::SVGMarkerElement::setOrientToAngle):
+        Fix the bug of not setting the unitType of the SVGAngle in orientAngle.
+
+        * svg/SVGMarkerElement.h:
+        Delete unused enum value SVG_MARKER_ORIENT_AUTOSTARTREVERSE.
+
+        * svg/SVGMarkerElement.idl:
+
+        * svg/SVGMarkerTypes.h:
+        (WebCore::SVGPropertyTraits<SVGMarkerOrientType>::highestEnumValue):
+        (WebCore::SVGIDLEnumLimits<SVGMarkerOrientType>::highestExposedEnumValue): Deleted.
+        Fix the value of SVGMarkerOrientAutoStartReverse. No need for 
+        highestExposedEnumValue() since all the enum values are now exposed.
+
+        * svg/properties/SVGAnimatedPropertyPairAccessorImpl.h:
+        Keep the pair properties <orientAngle, orientType> in sync.
+
+        * svg/properties/SVGMemberAccessor.h:
+        (WebCore::SVGMemberAccessor::setDirty const):
+        This is what SVGElement::commitPropertyChange() used to do for all properties.
+
+        * svg/properties/SVGPropertyOwnerRegistry.h:
+        * svg/properties/SVGPropertyRegistry.h:
+
 2019-11-13  Jer Noble  <jer.noble@apple.com>
 
         Link mediaDataLoadsAutomatically setting to AutoplayPolicy
index 9c61732..666ddc5 100644 (file)
@@ -54,7 +54,7 @@ public:
         return adoptRef(*new SVGAngle(value.releaseReturnValue()));
     }
 
-    SVGAngleValue::Type unitType()
+    SVGAngleValue::Type unitType() const
     {
         return m_value.unitType();
     }
@@ -69,7 +69,7 @@ public:
         return { };
     }
     
-    float valueForBindings()
+    float valueForBindings() const
     {
         return m_value.value();
     }
@@ -84,7 +84,7 @@ public:
         return { };
     }
     
-    float valueInSpecifiedUnits()
+    float valueInSpecifiedUnits() const
     {
         return m_value.valueInSpecifiedUnits();
     }
index 2b9ff84..87fd5da 100644 (file)
@@ -550,7 +550,7 @@ void SVGElement::commitPropertyChange(SVGAnimatedProperty& animatedProperty)
     // A change in a style property, e.g SVGRectElement::x should be serialized to
     // the attribute immediately. Otherwise it is okay to be lazy in this regard.
     if (!propertyRegistry().isAnimatedStylePropertyAttribute(attributeName))
-        animatedProperty.setDirty();
+        propertyRegistry().setAnimatedPropertDirty(attributeName, animatedProperty);
     else
         setSynchronizedLazyAttribute(attributeName, animatedProperty.baseValAsString());
 
index 98ab588..82fa919 100644 (file)
@@ -123,21 +123,24 @@ void SVGMarkerElement::childrenChanged(const ChildChange& change)
         object->setNeedsLayout();
 }
 
-void SVGMarkerElement::setOrient(SVGMarkerOrientType orientType, const SVGAngleValue& angle)
+String SVGMarkerElement::orient() const
 {
-    m_orientType->setBaseValInternal(orientType);
-    m_orientAngle->setBaseValInternal(angle);
-    m_orientAngle->baseVal()->commitChange();
+    return getAttribute(SVGNames::orientAttr);
+}
+
+void SVGMarkerElement::setOrient(const String& orient)
+{
+    setAttribute(SVGNames::orientAttr, orient);
 }
 
 void SVGMarkerElement::setOrientToAuto()
 {
-    setOrient(SVGMarkerOrientAuto, { });
+    m_orientType->setBaseVal(SVGMarkerOrientAuto);
 }
 
-void SVGMarkerElement::setOrientToAngle(SVGAngle& angle)
+void SVGMarkerElement::setOrientToAngle(const SVGAngle& angle)
 {
-    setOrient(SVGMarkerOrientAngle, angle.value());
+    m_orientAngle->baseVal()->newValueSpecifiedUnits(angle.unitType(), angle.valueInSpecifiedUnits());
 }
 
 RenderPtr<RenderElement> SVGMarkerElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&)
index 7110953..5a136e3 100644 (file)
@@ -40,17 +40,13 @@ public:
     enum {
         SVG_MARKER_ORIENT_UNKNOWN = SVGMarkerOrientUnknown,
         SVG_MARKER_ORIENT_AUTO = SVGMarkerOrientAuto,
-        SVG_MARKER_ORIENT_ANGLE = SVGMarkerOrientAngle,
-        SVG_MARKER_ORIENT_AUTOSTARTREVERSE = SVGMarkerOrientAutoStartReverse
+        SVG_MARKER_ORIENT_ANGLE = SVGMarkerOrientAngle
     };
 
     static Ref<SVGMarkerElement> create(const QualifiedName&, Document&);
 
     AffineTransform viewBoxToViewTransform(float viewWidth, float viewHeight) const;
 
-    void setOrientToAuto();
-    void setOrientToAngle(SVGAngle&);
-
     const SVGLengthValue& refX() const { return m_refX->currentValue(); }
     const SVGLengthValue& refY() const { return m_refY->currentValue(); }
     const SVGLengthValue& markerWidth() const { return m_markerWidth->currentValue(); }
@@ -67,6 +63,12 @@ public:
     SVGAnimatedAngle& orientAngleAnimated() { return m_orientAngle; }
     Ref<SVGAnimatedEnumeration> orientTypeAnimated() { return m_orientType.copyRef(); }
 
+    String orient() const;
+    void setOrient(const String&);
+
+    void setOrientToAuto();
+    void setOrientToAngle(const SVGAngle&);
+
 private:
     SVGMarkerElement(const QualifiedName&, Document&);
 
@@ -84,8 +86,6 @@ private:
 
     bool selfHasRelativeLengths() const override;
 
-    void setOrient(SVGMarkerOrientType, const SVGAngleValue&);
-
     PropertyRegistry m_propertyRegistry { *this };
     Ref<SVGAnimatedLength> m_refX { SVGAnimatedLength::create(this, SVGLengthMode::Width) };
     Ref<SVGAnimatedLength> m_refY { SVGAnimatedLength::create(this, SVGLengthMode::Height) };
index 0337dc6..26e93f5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-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
@@ -34,13 +34,15 @@ interface SVGMarkerElement : SVGElement {
     const unsigned short SVG_MARKER_ORIENT_AUTO         = 1;
     const unsigned short SVG_MARKER_ORIENT_ANGLE        = 2;
 
-    readonly attribute SVGAnimatedLength      refX;
-    readonly attribute SVGAnimatedLength      refY;
-    readonly attribute SVGAnimatedEnumeration markerUnits;
-    readonly attribute SVGAnimatedLength      markerWidth;
-    readonly attribute SVGAnimatedLength      markerHeight;
-    readonly attribute SVGAnimatedEnumeration orientType;
-    readonly attribute SVGAnimatedAngle       orientAngle;
+    [SameObject] readonly attribute SVGAnimatedLength      refX;
+    [SameObject] readonly attribute SVGAnimatedLength      refY;
+    [SameObject] readonly attribute SVGAnimatedEnumeration markerUnits;
+    [SameObject] readonly attribute SVGAnimatedLength      markerWidth;
+    [SameObject] readonly attribute SVGAnimatedLength      markerHeight;
+    [SameObject] readonly attribute SVGAnimatedEnumeration orientType;
+    [SameObject] readonly attribute SVGAnimatedAngle       orientAngle;
+
+    attribute DOMString orient;
 
     void setOrientToAuto();
     void setOrientToAngle(SVGAngle angle);
index b811d2e..0670341 100644 (file)
@@ -40,10 +40,10 @@ enum SVGMarkerOrientType {
     SVGMarkerOrientUnknown = 0,
     SVGMarkerOrientAuto,
     SVGMarkerOrientAngle,
-    SVGMarkerOrientAutoStartReverse,
-    
-    // Add new elements before here.
-    SVGMarkerOrientMax
+
+    // The DOM can't set the property 'orientType' to this value. It is used only
+    // internally when setting the 'orient' attribute to "auto-start-reverse".
+    SVGMarkerOrientAutoStartReverse = SVGMarkerOrientUnknown
 };
     
 template<>
@@ -85,7 +85,7 @@ struct SVGPropertyTraits<SVGMarkerOrientType> {
         static const NeverDestroyed<String> autoStartReverseString = MAKE_STATIC_STRING_IMPL("auto-start-reverse");
         return autoStartReverseString;
     }
-    static unsigned highestEnumValue() { return SVGMarkerOrientAutoStartReverse; }
+    static unsigned highestEnumValue() { return SVGMarkerOrientAngle; }
     static SVGMarkerOrientType fromString(const String& string)
     {
         if (string == autoString())
@@ -105,9 +105,6 @@ struct SVGPropertyTraits<SVGMarkerOrientType> {
 };
 
 template<>
-inline unsigned SVGIDLEnumLimits<SVGMarkerOrientType>::highestExposedEnumValue() { return SVGMarkerOrientAngle; }
-
-template<>
 struct SVGPropertyTraits<std::pair<SVGAngleValue, SVGMarkerOrientType>> {
     static std::pair<SVGAngleValue, SVGMarkerOrientType> fromString(const String& string)
     {
index 4a269fa..57e9c49 100644 (file)
@@ -39,6 +39,8 @@ class SVGAnimatedAngleOrientAccessor final : public SVGAnimatedPropertyPairAcces
     using Base = SVGAnimatedPropertyPairAccessor<OwnerType, SVGAnimatedAngleAccessor<OwnerType>, SVGAnimatedOrientTypeAccessor<OwnerType>>;
     using Base::property1;
     using Base::property2;
+    using Base::m_accessor1;
+    using Base::m_accessor2;
 
 public:
     using Base::Base;
@@ -46,6 +48,16 @@ public:
     constexpr static const SVGMemberAccessor<OwnerType>& singleton() { return Base::template singleton<SVGAnimatedAngleOrientAccessor, property1, property2>(); }
 
 private:
+    void setDirty(const OwnerType& owner, SVGAnimatedProperty& animatedProperty) const final
+    {
+        auto type = property2(owner)->baseVal();
+        if (m_accessor1.matches(owner, animatedProperty) && type != SVGMarkerOrientAngle)
+            property2(owner)->setBaseValInternal(SVGMarkerOrientAngle);
+        else if (m_accessor2.matches(owner, animatedProperty) && type != SVGMarkerOrientAngle)
+            property1(owner)->setBaseValInternal({ });
+        animatedProperty.setDirty();
+    }
+
     Optional<String> synchronize(const OwnerType& owner) const final
     {
         bool dirty1 = property1(owner)->isDirty();
index f7bba6a..3a76f91 100644 (file)
 #pragma once
 
 #include "QualifiedName.h"
+#include "SVGAnimatedProperty.h"
 #include "SVGAttributeAnimator.h"
 
 namespace WebCore {
 
-class SVGAnimatedProperty;
 class SVGProperty;
 
 template<typename OwnerType>
@@ -45,6 +45,7 @@ public:
 
     virtual bool matches(const OwnerType&, const SVGProperty&) const { return false; }
     virtual bool matches(const OwnerType&, const SVGAnimatedProperty&) const { return false; }
+    virtual void setDirty(const OwnerType&, SVGAnimatedProperty& animatedProperty) const { animatedProperty.setDirty(); }
     virtual Optional<String> synchronize(const OwnerType&) const { return WTF::nullopt; }
 
     virtual RefPtr<SVGAttributeAnimator> createAnimator(OwnerType&, const QualifiedName&, AnimationMode, CalcMode, bool, bool) const { return nullptr; }
index a5f7136..d42cb15 100644 (file)
@@ -202,6 +202,16 @@ public:
         return attributeName;
     }
 
+    void setAnimatedPropertDirty(const QualifiedName& attributeName, SVGAnimatedProperty& animatedProperty) const override
+    {
+        enumerateRecursively([&](const auto& entry) -> bool {
+            if (!entry.key.matches(attributeName))
+                return true;
+            entry.value->setDirty(m_owner, animatedProperty);
+            return false;
+        });
+    }
+
     // Detach all the properties recursively from their OwnerTypes.
     void detachAllProperties() const override
     {
index 24fe642..fea93cf 100644 (file)
@@ -39,6 +39,7 @@ public:
     virtual void detachAllProperties() const = 0;
     virtual QualifiedName propertyAttributeName(const SVGProperty&) const = 0;
     virtual QualifiedName animatedPropertyAttributeName(const SVGAnimatedProperty&) const = 0;
+    virtual void setAnimatedPropertDirty(const QualifiedName&, SVGAnimatedProperty&) const = 0;
     virtual Optional<String> synchronize(const QualifiedName&) const = 0;
     virtual HashMap<QualifiedName, String> synchronizeAllAttributes() const = 0;