summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/svg/path/property
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/svg/path/property')
-rw-r--r--testing/web-platform/tests/svg/path/property/d-interpolation-discrete.svg43
-rw-r--r--testing/web-platform/tests/svg/path/property/d-interpolation-relative-absolute.svg122
-rw-r--r--testing/web-platform/tests/svg/path/property/d-interpolation-single.svg245
-rw-r--r--testing/web-platform/tests/svg/path/property/getComputedStyle.svg48
-rw-r--r--testing/web-platform/tests/svg/path/property/marker-path-ref.svg42
-rw-r--r--testing/web-platform/tests/svg/path/property/marker-path.svg47
-rw-r--r--testing/web-platform/tests/svg/path/property/mpath-ref.svg5
-rw-r--r--testing/web-platform/tests/svg/path/property/mpath.svg18
-rw-r--r--testing/web-platform/tests/svg/path/property/priority-ref.svg11
-rw-r--r--testing/web-platform/tests/svg/path/property/priority.svg20
-rw-r--r--testing/web-platform/tests/svg/path/property/resources/interpolation-test-common.js71
-rw-r--r--testing/web-platform/tests/svg/path/property/serialization.svg34
-rw-r--r--testing/web-platform/tests/svg/path/property/test_style_flush_on_dom_api_with_d_property.html80
13 files changed, 786 insertions, 0 deletions
diff --git a/testing/web-platform/tests/svg/path/property/d-interpolation-discrete.svg b/testing/web-platform/tests/svg/path/property/d-interpolation-discrete.svg
new file mode 100644
index 0000000000..5b20a589bb
--- /dev/null
+++ b/testing/web-platform/tests/svg/path/property/d-interpolation-discrete.svg
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg"
+ xmlns:h="http://www.w3.org/1999/xhtml">
+ <metadata>
+ <h:link rel="help" href="https://svgwg.org/svg2-draft/paths.html#TheDProperty"/>
+ <h:meta name="assert" content="d falls back to step interpolation when no interpolation is possible."/>
+ </metadata>
+
+ <g id="container"/>
+
+ <h:script src="/resources/testharness.js"/>
+ <h:script src="/resources/testharnessreport.js"/>
+ <h:script src="resources/interpolation-test-common.js"/>
+ <script><![CDATA[
+ 'use strict';
+
+ // Distinct number of path segments
+ test_no_interpolation({
+ property: 'd',
+ from: 'path("M 0 0 H 1 H 2")',
+ to: 'path("M 0 0 H 3")'
+ });
+
+ test_no_interpolation({
+ property: 'd',
+ from: 'path("M 1 2 L 3 4 Z")',
+ to: "none"
+ });
+
+ // Distinct segment types
+ test_no_interpolation({
+ property: 'd',
+ from: 'path("M 10 0 H 11")',
+ to: 'path("M 20 0 V 2")'
+ });
+
+ test_no_interpolation({
+ property: 'd',
+ from: 'path("M 1 2 L 4 6 Z")',
+ to: 'path("M 1 2 H 4 V 6")'
+ });
+ ]]></script>
+</svg>
diff --git a/testing/web-platform/tests/svg/path/property/d-interpolation-relative-absolute.svg b/testing/web-platform/tests/svg/path/property/d-interpolation-relative-absolute.svg
new file mode 100644
index 0000000000..09d4c70712
--- /dev/null
+++ b/testing/web-platform/tests/svg/path/property/d-interpolation-relative-absolute.svg
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg"
+ xmlns:h="http://www.w3.org/1999/xhtml">
+ <metadata>
+ <h:link rel="help" href="https://svgwg.org/svg2-draft/paths.html#TheDProperty"/>
+ <h:meta name="assert" content="d can interpolate between absolute and relative paths."/>
+ </metadata>
+
+ <g id="container"/>
+
+ <h:script src="/resources/testharness.js"/>
+ <h:script src="/resources/testharnessreport.js"/>
+ <h:script src="resources/interpolation-test-common.js"/>
+ <script><![CDATA[
+ 'use strict';
+
+ // Mix relative and non-relative
+ test_interpolation({
+ property: 'd',
+ from: 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z")',
+ to: 'path("M 0 0 L 100 100 m 0 100 l 100 0 z l 300 100 z")'
+ }, [
+ {at: -1, expect: 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 0 -100 Z")'},
+ {at: 0, expect: 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z")'},
+ {at: 0.125, expect: 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 225 125 Z")'},
+ {at: 0.875, expect: 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 375 275 Z")'},
+ {at: 1, expect: 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 400 300 Z")'},
+ {at: 2, expect: 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 600 500 Z")'},
+ ]);
+
+ test_interpolation({
+ property: 'd',
+ from: 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z")',
+ to: 'path("M 0 0 L 100 100 m 0 100 l 100 0 z l 100 -100 z")'
+ }, [
+ {at: -1, expect: 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z")'},
+ {at: 0, expect: 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z")'},
+ {at: 0.125, expect: 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z")'},
+ {at: 0.875, expect: 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z")'},
+ {at: 1, expect: 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z")'},
+ {at: 2, expect: 'path("M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z")'},
+ ]);
+
+ test_interpolation({
+ property: 'd',
+ from: 'path("m 10 20 l 40 50 z l 40 60 z m 60 70 l 90 60 z t 70 130")',
+ to: 'path("M 210 220 L 170 190 Z L 90 120 Z M 110 130 L 200 230 Z T 220 220")'
+ }, [
+ {at: -1, expect: 'path("M -190 -180 L -70 -50 Z L 10 40 Z M 30 50 L 120 70 Z T 60 220")'},
+ {at: 0, expect: 'path("M 10 20 L 50 70 Z L 50 80 Z M 70 90 L 160 150 Z T 140 220")'},
+ {at: 0.125, expect: 'path("M 35 45 L 65 85 Z L 55 85 Z M 75 95 L 165 160 Z T 150 220")'},
+ {at: 0.875, expect: 'path("M 185 195 L 155 175 Z L 85 115 Z M 105 125 L 195 220 Z T 210 220")'},
+ {at: 1, expect: 'path("M 210 220 L 170 190 Z L 90 120 Z M 110 130 L 200 230 Z T 220 220")'},
+ {at: 2, expect: 'path("M 410 420 L 290 310 Z L 130 160 Z M 150 170 L 240 310 Z T 300 220")'}
+ ]);
+
+ test_interpolation({
+ property: 'd',
+ from: 'path("m 10 20 c 40 50 30 60 80 70 c 120 130 170 140 110 160")',
+ to: 'path("M 130 100 C 130 150 120 160 210 170 C 290 300 340 310 320 330")'
+ }, [
+ {at: -1, expect: 'path("M -110 -60 C -30 -10 -40 0 -30 10 C 130 140 180 150 80 170")'},
+ {at: 0, expect: 'path("M 10 20 C 50 70 40 80 90 90 C 210 220 260 230 200 250")'},
+ {at: 0.125, expect: 'path("M 25 30 C 60 80 50 90 105 100 C 220 230 270 240 215 260")'},
+ {at: 0.875, expect: 'path("M 115 90 C 120 140 110 150 195 160 C 280 290 330 300 305 320")'},
+ {at: 1, expect: 'path("M 130 100 C 130 150 120 160 210 170 C 290 300 340 310 320 330")'},
+ {at: 2, expect: 'path("M 250 180 C 210 230 200 240 330 250 C 370 380 420 390 440 410")'}
+ ]);
+
+ test_interpolation({
+ property: 'd',
+ from: 'path("m 10 20 q 30 60 40 50 q 110 80 90 80")',
+ to: 'path("M 130 100 Q 120 160 130 150 Q 200 150 180 190")'
+ }, [
+ {at: -1, expect: 'path("M -110 -60 Q -40 0 -30 -10 Q 120 150 100 110")'},
+ {at: 0, expect: 'path("M 10 20 Q 40 80 50 70 Q 160 150 140 150")'},
+ {at: 0.125, expect: 'path("M 25 30 Q 50 90 60 80 Q 165 150 145 155")'},
+ {at: 0.875, expect: 'path("M 115 90 Q 110 150 120 140 Q 195 150 175 185")'},
+ {at: 1, expect: 'path("M 130 100 Q 120 160 130 150 Q 200 150 180 190")'},
+ {at: 2, expect: 'path("M 250 180 Q 200 240 210 230 Q 240 150 220 230")'}
+ ]);
+
+ test_interpolation({
+ property: 'd',
+ from: 'path("m 10 20 s 30 60 40 50 s 110 60 90 70")',
+ to: 'path("M 130 140 S 120 160 130 150 S 200 170 140 180")'
+ }, [
+ {at: -1, expect: 'path("M -110 -100 S -40 0 -30 -10 S 120 90 140 100")'},
+ {at: 0, expect: 'path("M 10 20 S 40 80 50 70 S 160 130 140 140")'},
+ {at: 0.125, expect: 'path("M 25 35 S 50 90 60 80 S 165 135 140 145")'},
+ {at: 0.875, expect: 'path("M 115 125 S 110 150 120 140 S 195 165 140 175")'},
+ {at: 1, expect: 'path("M 130 140 S 120 160 130 150 S 200 170 140 180")'},
+ {at: 2, expect: 'path("M 250 260 S 200 240 210 230 S 240 210 140 220")'}
+ ]);
+
+ test_interpolation({
+ property: 'd',
+ from: 'path("m 10 20 h 30 v 60 h 10 v -10 l 110 60 Z")',
+ to: 'path("M 130 140 H 120 V 160 H 130 V 150 L 200 170 Z")'
+ }, [
+ {at: -1, expect: 'path("M -110 -100 H -40 V 0 H -30 V -10 L 120 90 Z")'},
+ {at: 0, expect: 'path("M 10 20 H 40 V 80 H 50 V 70 L 160 130 Z")'},
+ {at: 0.125, expect: 'path("M 25 35 H 50 V 90 H 60 V 80 L 165 135 Z")'},
+ {at: 0.875, expect: 'path("M 115 125 H 110 V 150 H 120 V 140 L 195 165 Z")'},
+ {at: 1, expect: 'path("M 130 140 H 120 V 160 H 130 V 150 L 200 170 Z")'},
+ {at: 2, expect: 'path("M 250 260 H 200 V 240 H 210 V 230 L 240 210 Z")'}
+ ]);
+
+ test_interpolation({
+ property: 'd',
+ from: 'path("m 10 20 a 10 20 30 1 0 40 50 a 110 120 30 1 1 140 50")',
+ to: 'path("M 18 12 A 50 100 70 0 1 90 110 A 150 160 70 0 1 70 80")'
+ }, [
+ {at: -1, expect: 'path("M 2 28 A -30 -60 -10 1 0 10 30 A 70 80 -10 1 1 310 160")'},
+ {at: 0, expect: 'path("M 10 20 A 10 20 30 1 0 50 70 A 110 120 30 1 1 190 120")'},
+ {at: 0.125, expect: 'path("M 11 19 A 15 30 35 1 0 55 75 A 115 125 35 1 1 175 115")'},
+ {at: 0.875, expect: 'path("M 17 13 A 45 90 65 0 1 85 105 A 145 155 65 0 1 85 85")'},
+ {at: 1, expect: 'path("M 18 12 A 50 100 70 0 1 90 110 A 150 160 70 0 1 70 80")'},
+ {at: 2, expect: 'path("M 26 4 A 90 180 110 0 1 130 150 A 190 200 110 0 1 -50 40")'}
+ ]);
+ ]]></script>
+</svg>
diff --git a/testing/web-platform/tests/svg/path/property/d-interpolation-single.svg b/testing/web-platform/tests/svg/path/property/d-interpolation-single.svg
new file mode 100644
index 0000000000..107b607bec
--- /dev/null
+++ b/testing/web-platform/tests/svg/path/property/d-interpolation-single.svg
@@ -0,0 +1,245 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg"
+ xmlns:h="http://www.w3.org/1999/xhtml">
+ <metadata>
+ <h:link rel="help" href="https://svgwg.org/svg2-draft/paths.html#TheDProperty"/>
+ <h:meta name="assert" content="Each path command interpolates."/>
+ </metadata>
+
+ <g id="container"/>
+
+ <h:script src="/resources/testharness.js"/>
+ <h:script src="/resources/testharnessreport.js"/>
+ <h:script src="resources/interpolation-test-common.js"/>
+ <script><![CDATA[
+ 'use strict';
+
+ // Exercise each segment type
+ test_interpolation({
+ property: 'd',
+ from: 'path("M 20 70")',
+ to: 'path("M 100 30")'
+ }, [
+ {at: -1, expect: 'path("M -60 110")'},
+ {at: 0, expect: 'path("M 20 70")'},
+ {at: 0.125, expect: 'path("M 30 65")'},
+ {at: 0.875, expect: 'path("M 90 35")'},
+ {at: 1, expect: 'path("M 100 30")'},
+ {at: 2, expect: 'path("M 180 -10")'}
+ ]);
+
+ test_interpolation({
+ property: 'd',
+ from: 'path("m 20 70")',
+ to: 'path("m 100 30")'
+ }, [
+ {at: -1, expect: 'path("M -60 110")'},
+ {at: 0, expect: 'path("M 20 70")'},
+ {at: 0.125, expect: 'path("M 30 65")'},
+ {at: 0.875, expect: 'path("M 90 35")'},
+ {at: 1, expect: 'path("M 100 30")'},
+ {at: 2, expect: 'path("M 180 -10")'}
+ ]);
+
+ test_interpolation({
+ property: 'd',
+ from: 'path("m 100 200 L 120 270")',
+ to: 'path("m 100 200 L 200 230")'
+ }, [
+ {at: -1, expect: 'path("M 100 200 L 40 310")'},
+ {at: 0, expect: 'path("M 100 200 L 120 270")'},
+ {at: 0.125, expect: 'path("M 100 200 L 130 265")'},
+ {at: 0.875, expect: 'path("M 100 200 L 190 235")'},
+ {at: 1, expect: 'path("M 100 200 L 200 230")'},
+ {at: 2, expect: 'path("M 100 200 L 280 190")'}
+ ]);
+
+ test_interpolation({
+ property: 'd',
+ from: 'path("m 100 200 l 20 70")',
+ to: 'path("m 100 200 l 100 30")'
+ }, [
+ {at: -1, expect: 'path("M 100 200 L 40 310")'},
+ {at: 0, expect: 'path("M 100 200 L 120 270")'},
+ {at: 0.125, expect: 'path("M 100 200 L 130 265")'},
+ {at: 0.875, expect: 'path("M 100 200 L 190 235")'},
+ {at: 1, expect: 'path("M 100 200 L 200 230")'},
+ {at: 2, expect: 'path("M 100 200 L 280 190")'}
+ ]);
+
+ test_interpolation({
+ property: 'd',
+ from: 'path("M 20 10 C 32 42 52 62 120 2200")',
+ to: 'path("M 20 10 C 40 50 60 70 200 3000")',
+ }, [
+ {at: -1, expect: 'path("M 20 10 C 24 34 44 54 40 1400")'},
+ {at: 0, expect: 'path("M 20 10 C 32 42 52 62 120 2200")'},
+ {at: 0.125, expect: 'path("M 20 10 C 33 43 53 63 130 2300")'},
+ {at: 0.875, expect: 'path("M 20 10 C 39 49 59 69 190 2900")'},
+ {at: 1, expect: 'path("M 20 10 C 40 50 60 70 200 3000")'},
+ {at: 2, expect: 'path("M 20 10 C 48 58 68 78 280 3800")'}
+ ]);
+ test_interpolation({
+ property: 'd',
+ from: 'path("m 20 10 c 12 32 32 52 100 2190")',
+ to: 'path("m 20 10 c 20 40 40 60 180 2990")'
+ }, [
+ {at: -1, expect: 'path("M 20 10 C 24 34 44 54 40 1400")'},
+ {at: 0, expect: 'path("M 20 10 C 32 42 52 62 120 2200")'},
+ {at: 0.125, expect: 'path("M 20 10 C 33 43 53 63 130 2300")'},
+ {at: 0.875, expect: 'path("M 20 10 C 39 49 59 69 190 2900")'},
+ {at: 1, expect: 'path("M 20 10 C 40 50 60 70 200 3000")'},
+ {at: 2, expect: 'path("M 20 10 C 48 58 68 78 280 3800")'}
+ ]);
+
+ test_interpolation({
+ property: 'd',
+ from: 'path("M 20 10 Q 32 42 120 2200")',
+ to: 'path("M 20 10 Q 40 50 200 3000")'
+ }, [
+ {at: -1, expect: 'path("M 20 10 Q 24 34 40 1400")'},
+ {at: 0, expect: 'path("M 20 10 Q 32 42 120 2200")'},
+ {at: 0.125, expect: 'path("M 20 10 Q 33 43 130 2300")'},
+ {at: 0.875, expect: 'path("M 20 10 Q 39 49 190 2900")'},
+ {at: 1, expect: 'path("M 20 10 Q 40 50 200 3000")'},
+ {at: 2, expect: 'path("M 20 10 Q 48 58 280 3800")'}
+ ]);
+ test_interpolation({
+ property: 'd',
+ from: 'path("m 20 10 q 12 32 100 2190")',
+ to: 'path("m 20 10 q 20 40 180 2990")'
+ }, [
+ {at: -1, expect: 'path("M 20 10 Q 24 34 40 1400")'},
+ {at: 0, expect: 'path("M 20 10 Q 32 42 120 2200")'},
+ {at: 0.125, expect: 'path("M 20 10 Q 33 43 130 2300")'},
+ {at: 0.875, expect: 'path("M 20 10 Q 39 49 190 2900")'},
+ {at: 1, expect: 'path("M 20 10 Q 40 50 200 3000")'},
+ {at: 2, expect: 'path("M 20 10 Q 48 58 280 3800")'}
+ ]);
+
+ test_interpolation({
+ property: 'd',
+ from: 'path("M 100 400 A 10 20 30 1 0 140 450")',
+ to: 'path("M 300 200 A 50 60 70 0 1 380 290")'
+ }, [
+ {at: -1, expect: 'path("M -100 600 A -30 -20 -10 1 0 -100 610")'},
+ {at: 0, expect: 'path("M 100 400 A 10 20 30 1 0 140 450")'},
+ {at: 0.125, expect: 'path("M 125 375 A 15 25 35 1 0 170 430")'},
+ {at: 0.875, expect: 'path("M 275 225 A 45 55 65 0 1 350 310")'},
+ {at: 1, expect: 'path("M 300 200 A 50 60 70 0 1 380 290")'},
+ {at: 2, expect: 'path("M 500 0 A 90 100 110 0 1 620 130")'}
+ ]);
+ test_interpolation({
+ property: 'd',
+ from: 'path("m 100 400 a 10 20 30 1 0 40 50")',
+ to: 'path("m 300 200 a 50 60 70 0 1 80 90")'
+ }, [
+ {at: -1, expect: 'path("M -100 600 A -30 -20 -10 1 0 -100 610")'},
+ {at: 0, expect: 'path("M 100 400 A 10 20 30 1 0 140 450")'},
+ {at: 0.125, expect: 'path("M 125 375 A 15 25 35 1 0 170 430")'},
+ {at: 0.875, expect: 'path("M 275 225 A 45 55 65 0 1 350 310")'},
+ {at: 1, expect: 'path("M 300 200 A 50 60 70 0 1 380 290")'},
+ {at: 2, expect: 'path("M 500 0 A 90 100 110 0 1 620 130")'}
+ ]);
+
+ test_interpolation({
+ property: 'd',
+ from: 'path("M 50 60 H 70")',
+ to: 'path("M 10 140 H 270")'
+ }, [
+ {at: -1, expect: 'path("M 90 -20 H -130")'},
+ {at: 0, expect: 'path("M 50 60 H 70")'},
+ {at: 0.125, expect: 'path("M 45 70 H 95")'},
+ {at: 0.875, expect: 'path("M 15 130 H 245")'},
+ {at: 1, expect: 'path("M 10 140 H 270")'},
+ {at: 2, expect: 'path("M -30 220 H 470")'}
+ ]);
+ test_interpolation({
+ property: 'd',
+ from: 'path("m 50 60 h 20")',
+ to: 'path("m 10 140 h 260")'
+ }, [
+ {at: -1, expect: 'path("M 90 -20 H -130")'},
+ {at: 0, expect: 'path("M 50 60 H 70")'},
+ {at: 0.125, expect: 'path("M 45 70 H 95")'},
+ {at: 0.875, expect: 'path("M 15 130 H 245")'},
+ {at: 1, expect: 'path("M 10 140 H 270")'},
+ {at: 2, expect: 'path("M -30 220 H 470")'}
+ ]);
+
+ test_interpolation({
+ property: 'd',
+ from: 'path("M 50 60 V 70")',
+ to: 'path("M 10 140 V 270")'
+ }, [
+ {at: -1, expect: 'path("M 90 -20 V -130")'},
+ {at: 0, expect: 'path("M 50 60 V 70")'},
+ {at: 0.125, expect: 'path("M 45 70 V 95")'},
+ {at: 0.875, expect: 'path("M 15 130 V 245")'},
+ {at: 1, expect: 'path("M 10 140 V 270")'},
+ {at: 2, expect: 'path("M -30 220 V 470")'}
+ ]);
+ test_interpolation({
+ property: 'd',
+ from: 'path("m 50 60 v 10")',
+ to: 'path("m 10 140 v 130")'
+ }, [
+ {at: -1, expect: 'path("M 90 -20 V -130")'},
+ {at: 0, expect: 'path("M 50 60 V 70")'},
+ {at: 0.125, expect: 'path("M 45 70 V 95")'},
+ {at: 0.875, expect: 'path("M 15 130 V 245")'},
+ {at: 1, expect: 'path("M 10 140 V 270")'},
+ {at: 2, expect: 'path("M -30 220 V 470")'}
+ ]);
+
+ test_interpolation({
+ property: 'd',
+ from: 'path("M 12 34 S 45 67 89 123")',
+ to: 'path("M 20 26 S 61 51 113 99")'
+ }, [
+ {at: -1, expect: 'path("M 4 42 S 29 83 65 147")'},
+ {at: 0, expect: 'path("M 12 34 S 45 67 89 123")'},
+ {at: 0.125, expect: 'path("M 13 33 S 47 65 92 120")'},
+ {at: 0.875, expect: 'path("M 19 27 S 59 53 110 102")'},
+ {at: 1, expect: 'path("M 20 26 S 61 51 113 99")'},
+ {at: 2, expect: 'path("M 28 18 S 77 35 137 75")'},
+ ]);
+ test_interpolation({
+ property: 'd',
+ from: 'path("m 12 34 s 33 33 77 89")',
+ to: 'path("m 20 26 s 41 25 93 73")'
+ }, [
+ {at: -1, expect: 'path("M 4 42 S 29 83 65 147")'},
+ {at: 0, expect: 'path("M 12 34 S 45 67 89 123")'},
+ {at: 0.125, expect: 'path("M 13 33 S 47 65 92 120")'},
+ {at: 0.875, expect: 'path("M 19 27 S 59 53 110 102")'},
+ {at: 1, expect: 'path("M 20 26 S 61 51 113 99")'},
+ {at: 2, expect: 'path("M 28 18 S 77 35 137 75")'},
+ ]);
+
+ test_interpolation({
+ property: 'd',
+ from: 'path("M 12 34 T 45 67")',
+ to: 'path("M 20 26 T 61 51")'
+ }, [
+ {at: -1, expect: 'path("M 4 42 T 29 83")'},
+ {at: 0, expect: 'path("M 12 34 T 45 67")'},
+ {at: 0.125, expect: 'path("M 13 33 T 47 65")'},
+ {at: 0.875, expect: 'path("M 19 27 T 59 53")'},
+ {at: 1, expect: 'path("M 20 26 T 61 51")'},
+ {at: 2, expect: 'path("M 28 18 T 77 35")'},
+ ]);
+ test_interpolation({
+ property: 'd',
+ from: 'path("m 12 34 t 33 33")',
+ to: 'path("m 20 26 t 41 25")'
+ }, [
+ {at: -1, expect: 'path("M 4 42 T 29 83")'},
+ {at: 0, expect: 'path("M 12 34 T 45 67")'},
+ {at: 0.125, expect: 'path("M 13 33 T 47 65")'},
+ {at: 0.875, expect: 'path("M 19 27 T 59 53")'},
+ {at: 1, expect: 'path("M 20 26 T 61 51")'},
+ {at: 2, expect: 'path("M 28 18 T 77 35")'},
+ ]);
+ ]]></script>
+</svg>
diff --git a/testing/web-platform/tests/svg/path/property/getComputedStyle.svg b/testing/web-platform/tests/svg/path/property/getComputedStyle.svg
new file mode 100644
index 0000000000..400f92ec84
--- /dev/null
+++ b/testing/web-platform/tests/svg/path/property/getComputedStyle.svg
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg"
+ xmlns:h="http://www.w3.org/1999/xhtml">
+ <metadata>
+ <h:link rel="help" href="https://svgwg.org/svg2-draft/paths.html#TheDProperty"/>
+ <h:meta name="assert" content="d is a property"/>
+ </metadata>
+ <style>
+ .p3 {
+ d: path('M 10 3 H 30');
+ }
+ .g5 {
+ d: path('m 10 5 h 40');
+ }
+ .p6 {
+ d: inherit;
+ }
+ </style>
+ <g id="g0">
+ <path id="p1"></path>
+ <path id="p2" d="M 10 2 H 20"></path>
+ <path id="p3" class="p3"></path>
+ <path id="p4" style="d: path('M 10 4 H 40')"></path>
+ </g>
+ <g id="g5" class="g5">
+ <path id="p6" class="p6"></path>
+ <path id="p7"></path>
+ </g>
+ <h:script src="/resources/testharness.js"/>
+ <h:script src="/resources/testharnessreport.js"/>
+ <script><![CDATA[
+ function test_computed_value_of_d(id, expected) {
+ test(function() {
+ let target = document.getElementById(id);
+ assert_equals(getComputedStyle(target).d, expected);
+ }, `d property of ${id} should be ${expected}.`);
+ }
+
+ test_computed_value_of_d('g0', 'none');
+ test_computed_value_of_d('p1', 'none');
+ test_computed_value_of_d('p2', 'path("M 10 2 H 20")');
+ test_computed_value_of_d('p3', 'path("M 10 3 H 30")');
+ test_computed_value_of_d('p4', 'path("M 10 4 H 40")');
+ test_computed_value_of_d('g5', 'path("M 10 5 H 50")');
+ test_computed_value_of_d('p6', 'path("M 10 5 H 50")');
+ test_computed_value_of_d('p7', 'none');
+ ]]></script>
+</svg>
diff --git a/testing/web-platform/tests/svg/path/property/marker-path-ref.svg b/testing/web-platform/tests/svg/path/property/marker-path-ref.svg
new file mode 100644
index 0000000000..8cd5c8ea48
--- /dev/null
+++ b/testing/web-platform/tests/svg/path/property/marker-path-ref.svg
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg"
+ xmlns:h="http://www.w3.org/1999/xhtml" width="300" height="300">
+ <defs>
+ <marker id="Start"
+ viewBox="0 0 10 10" refX="0" refY="5"
+ markerUnits="strokeWidth"
+ markerWidth="10"
+ markerHeight="10"
+ orient="auto"
+ overflow="visible"
+ fill="green">
+ <path d="M 0 0 L 10 5 L 0 10 z"/>
+ </marker>
+ <marker id="Mid"
+ viewBox="0 0 10 10" refX="0" refY="5"
+ markerUnits="strokeWidth"
+ markerWidth="10"
+ markerHeight="10"
+ orient="auto"
+ overflow="visible"
+ fill="orange">
+ <path d="M 0 0 L 10 5 L 0 10 z"/>
+ </marker>
+ <marker id="End"
+ viewBox="0 0 10 10" refX="0" refY="5"
+ markerUnits="strokeWidth"
+ markerWidth="10"
+ markerHeight="10"
+ orient="auto"
+ overflow="visible"
+ fill="blue">
+ <path d="M 0 0 L 10 5 L 0 10 z"/>
+ </marker>
+ </defs>
+
+ <g style="fill:none;stroke:black;stroke-width:2;marker-start:url(#Start);marker-mid:url(#Mid);marker-end:url(#End)">
+ <path d="M 50,50 l 50,0 l 50,0 l 50,0"/>
+ <path d="M 50,100 l 50,20 l 50,-20 l 50,20"/>
+ <path d="M 50,150 h 50 v 50 h 50"/>
+ </g>
+</svg>
diff --git a/testing/web-platform/tests/svg/path/property/marker-path.svg b/testing/web-platform/tests/svg/path/property/marker-path.svg
new file mode 100644
index 0000000000..c03e9c515c
--- /dev/null
+++ b/testing/web-platform/tests/svg/path/property/marker-path.svg
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg"
+ xmlns:h="http://www.w3.org/1999/xhtml" width="300" height="300">
+ <metadata>
+ <h:link rel="help" href="https://svgwg.org/svg2-draft/paths.html#TheDProperty"/>
+ <h:link rel="match" href="marker-path-ref.svg"/>
+ <h:meta name="assert" content="d property is used for SVG markers."/>
+ </metadata>
+ <defs>
+ <marker id="Start"
+ viewBox="0 0 10 10" refX="0" refY="5"
+ markerUnits="strokeWidth"
+ markerWidth="10"
+ markerHeight="10"
+ orient="auto"
+ overflow="visible"
+ fill="green">
+ <path d="M 0 0 L 10 5 L 0 10 z"/>
+ </marker>
+ <marker id="Mid"
+ viewBox="0 0 10 10" refX="0" refY="5"
+ markerUnits="strokeWidth"
+ markerWidth="10"
+ markerHeight="10"
+ orient="auto"
+ overflow="visible"
+ fill="orange">
+ <path d="M 0 0 L 10 5 L 0 10 z"/>
+ </marker>
+ <marker id="End"
+ viewBox="0 0 10 10" refX="0" refY="5"
+ markerUnits="strokeWidth"
+ markerWidth="10"
+ markerHeight="10"
+ orient="auto"
+ overflow="visible"
+ fill="blue">
+ <path d="M 0 0 L 10 5 L 0 10 z"/>
+ </marker>
+ </defs>
+
+ <g style="fill:none;stroke:black;stroke-width:2;marker-start:url(#Start);marker-mid:url(#Mid);marker-end:url(#End)">
+ <path style='d: path("M 50,50 l 50,0 l 50,0 l 50,0");'/>
+ <path style='d: path("M 50,100 l 50,20 l 50,-20 l 50,20");'/>
+ <path style='d: path("M 50,150 h 50 v 50 h 50");'/>
+ </g>
+</svg>
diff --git a/testing/web-platform/tests/svg/path/property/mpath-ref.svg b/testing/web-platform/tests/svg/path/property/mpath-ref.svg
new file mode 100644
index 0000000000..db281c33da
--- /dev/null
+++ b/testing/web-platform/tests/svg/path/property/mpath-ref.svg
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100">
+ <path d="M20,50 h100" fill="none" stroke="black"/>
+ <circle r="5" fill="red" transform="translate(70 50)"/>
+</svg>
diff --git a/testing/web-platform/tests/svg/path/property/mpath.svg b/testing/web-platform/tests/svg/path/property/mpath.svg
new file mode 100644
index 0000000000..c4233b1705
--- /dev/null
+++ b/testing/web-platform/tests/svg/path/property/mpath.svg
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:h="http://www.w3.org/1999/xhtml" width="200" height="100">
+ <metadata>
+ <h:link rel="help" href="https://svgwg.org/svg2-draft/paths.html#TheDProperty"/>
+ <h:link rel="match" href="mpath-ref.svg"/>
+ <h:meta name="assert" content="d property is used for SVG mpath ref path."/>
+ </metadata>
+ <path style='d: path("M20,50 h100");' fill="none" stroke="black" id="path_ref"/>
+
+ <circle r="5" fill="red">
+ <!-- The red circle should always be in the middle of the path -->
+ <animateMotion dur="10s" repeatCount="indefinite" keyPoints="0.5;0.5" keyTimes="0;1">
+ <mpath xlink:href="#path_ref"/>
+ </animateMotion>
+ </circle>
+</svg>
diff --git a/testing/web-platform/tests/svg/path/property/priority-ref.svg b/testing/web-platform/tests/svg/path/property/priority-ref.svg
new file mode 100644
index 0000000000..cbc7c385f6
--- /dev/null
+++ b/testing/web-platform/tests/svg/path/property/priority-ref.svg
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
+ <style>
+ path {
+ stroke-width: 3;
+ stroke: blue;
+ }
+ </style>
+ <path d="M 20 10 h 70" />
+ <path d="M 20 80 h 70" />
+</svg>
diff --git a/testing/web-platform/tests/svg/path/property/priority.svg b/testing/web-platform/tests/svg/path/property/priority.svg
new file mode 100644
index 0000000000..ef187c1913
--- /dev/null
+++ b/testing/web-platform/tests/svg/path/property/priority.svg
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg"
+ xmlns:h="http://www.w3.org/1999/xhtml" width="100" height="100">
+ <metadata>
+ <h:link rel="help" href="https://svgwg.org/svg2-draft/paths.html#TheDProperty"/>
+ <h:link rel="match" href="priority-ref.svg"/>
+ <h:meta name="assert" content="Property overrides attribute."/>
+ </metadata>
+ <style>
+ path {
+ stroke-width: 3;
+ stroke: blue;
+ }
+ #top {
+ d: path('M 20 10 h 70');
+ }
+ </style>
+ <path id="top" d="M 10 20 h 70" />
+ <path d="M 10 90 h 70" style="d: path('M 20 80 h 70')" />
+</svg>
diff --git a/testing/web-platform/tests/svg/path/property/resources/interpolation-test-common.js b/testing/web-platform/tests/svg/path/property/resources/interpolation-test-common.js
new file mode 100644
index 0000000000..b7f8cd308d
--- /dev/null
+++ b/testing/web-platform/tests/svg/path/property/resources/interpolation-test-common.js
@@ -0,0 +1,71 @@
+'use strict';
+function test_interpolation(settings, expectations) {
+
+ test(function(){
+ assert_true(CSS.supports(settings.property, settings.from), 'Value "' + settings.from + '" is supported by ' + settings.property);
+ assert_true(CSS.supports(settings.property, settings.to), 'Value "' + settings.to + '" is supported by ' + settings.property);
+ }, '"' + settings.from + '" and "' + settings.to + '" are valid ' + settings.property + ' values');
+
+ const container = document.getElementById('container');
+ for (let i = 0; i < expectations.length; ++i) {
+ const progress = expectations[i].at;
+ const expectation = expectations[i].expect;
+ const animationId = 'anim' + i;
+ const targetId = 'target' + i;
+ const referenceId = 'reference' + i;
+
+ test(function(){
+ assert_true(CSS.supports(settings.property, expectation), 'Value "' + expectation + '" is supported by ' + settings.property);
+
+ const target = document.createElementNS('http://www.w3.org/2000/svg', 'g');
+ target.id = targetId;
+ container.appendChild(target);
+
+ const reference = document.createElementNS('http://www.w3.org/2000/svg', 'g');
+ reference.id = referenceId;
+ container.appendChild(reference);
+
+ assert_equals(getComputedStyle(target)[settings.property], getComputedStyle(reference)[settings.property]);
+
+ // Create an animation of length 2s that starts at -1s so the current time of 0s is
+ // exactly halfway through the animation. A cubic bezier timing function is used that
+ // evaluates to |progress| at the current time (halfway through the animation).
+
+ // Cubic bezier evaluates to |progress| at 50%.
+ const y = (8 * progress - 1) / 6;
+ const timing_function = 'cubic-bezier(0, ' + y + ', 1, ' + y + ')';
+
+ const stylesheet = document.createElementNS('http://www.w3.org/2000/svg', 'style');
+ stylesheet.textContent =
+ '#' + targetId + ' {\n' +
+ ' animation: 2s ' + timing_function + ' -1s paused ' + animationId + ';\n' +
+ '}\n' +
+ '@keyframes ' + animationId + ' {\n' +
+ ' 0% { ' + settings.property + ': ' + settings.from + '; }\n' +
+ ' 100% { ' + settings.property + ': ' + settings.to + '; }\n' +
+ '}\n' +
+ '#' + referenceId + ' {\n' +
+ ' ' + settings.property + ': ' + expectation + ';\n' +
+ '}\n';
+ container.appendChild(stylesheet);
+
+ assert_equals(getComputedStyle(target)[settings.property], getComputedStyle(reference)[settings.property]);
+ assert_equals(getComputedStyle(target)[settings.property], expectation);
+
+ container.removeChild(target);
+ container.removeChild(reference);
+ container.removeChild(stylesheet);
+ }, 'Animation between "' + settings.from + '" and "' + settings.to + '" at progress ' + progress);
+ }
+}
+
+function test_no_interpolation(settings) {
+ const expectFrom = [-1, 0, 0.125].map(function (progress) {
+ return {at: progress, expect: settings.from};
+ });
+ const expectTo = [0.875, 1, 2].map(function (progress) {
+ return {at: progress, expect: settings.to};
+ });
+
+ test_interpolation(settings, expectFrom.concat(expectTo));
+}
diff --git a/testing/web-platform/tests/svg/path/property/serialization.svg b/testing/web-platform/tests/svg/path/property/serialization.svg
new file mode 100644
index 0000000000..3199beb92b
--- /dev/null
+++ b/testing/web-platform/tests/svg/path/property/serialization.svg
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg"
+ xmlns:h="http://www.w3.org/1999/xhtml">
+ <metadata>
+ <h:link rel="help" href="https://svgwg.org/svg2-draft/paths.html#TheDProperty"/>
+ <h:meta name="assert" content="computed d is serialized using absolute commands"/>
+ </metadata>
+ <path id="target"></path>
+ <h:script src="/resources/testharness.js"/>
+ <h:script src="/resources/testharnessreport.js"/>
+ <h:script src="/css/support/parsing-testcommon.js"/>
+ <h:script src="/css/support/computed-testcommon.js"/>
+ <script><![CDATA[
+ let test1 = 'path("m 10 20 q 30 60 40 50 q 100 70 90 80")';
+ test_valid_value('d', test1);
+ test_computed_value('d', test1, 'path("M 10 20 Q 40 80 50 70 Q 150 140 140 150")');
+
+ let test2 = 'path("M 0 0 L 100 100 m 0 100 l 100 0 Z l 160 20 Z")';
+ test_valid_value('d', test2);
+ test_computed_value('d', test2);
+
+ let test3 = 'path("m 10 20 l 20 30 Z l 50 60 Z m 70 80 l 90 60 Z t 70 120")';
+ test_valid_value('d', test3, 'path("m 10 20 l 20 30 Z l 50 60 Z m 70 80 l 90 60 Z t 70 120")');
+ test_computed_value('d', test3, 'path("M 10 20 L 30 50 Z L 60 80 Z M 80 100 L 170 160 Z T 150 220")');
+
+ let test4 = 'path("m 10.0 170.0 h 90.00 v 30.00 m 0 0 s 1 2 3 4 z c 9 8 7 6 5 4")';
+ test_valid_value('d', test4, 'path("m 10 170 h 90 v 30 m 0 0 s 1 2 3 4 Z c 9 8 7 6 5 4")');
+ test_computed_value('d', test4, 'path("M 10 170 H 100 V 200 M 100 200 S 101 202 103 204 Z C 109 208 107 206 105 204")');
+
+ let test5 = ' path( "m 10 20 a 10 20 30 1 0 40 50 a 110 120 30 1 1 140 50" )';
+ test_valid_value('d', test5, 'path("m 10 20 a 10 20 30 1 0 40 50 a 110 120 30 1 1 140 50")');
+ test_computed_value('d', test5, 'path("M 10 20 A 10 20 30 1 0 50 70 A 110 120 30 1 1 190 120")');
+ ]]></script>
+</svg>
diff --git a/testing/web-platform/tests/svg/path/property/test_style_flush_on_dom_api_with_d_property.html b/testing/web-platform/tests/svg/path/property/test_style_flush_on_dom_api_with_d_property.html
new file mode 100644
index 0000000000..248118443b
--- /dev/null
+++ b/testing/web-platform/tests/svg/path/property/test_style_flush_on_dom_api_with_d_property.html
@@ -0,0 +1,80 @@
+<!DOCTYPE html>
+<title>Test DOM APIs which flush the style properly, with d property</title>
+<meta charset=utf-8>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<style>
+svg {
+ width: 10%;
+ height: 10%;
+ background: #eee;
+}
+svg path {
+ fill: none;
+ stroke: #000;
+}
+</style>
+
+<div id="log"></div>
+
+<svg viewBox="0 0 20 20" id="svgroot"></svg>
+
+<script>
+'use strict';
+
+function createPath(t) {
+ const target = document.createElementNS("http://www.w3.org/2000/svg", "path");
+ document.getElementById('svgroot').appendChild(target);
+
+ if (t && typeof t.add_cleanup === "function") {
+ t.add_cleanup(function() {
+ target.remove();
+ });
+ }
+
+ // Set an initial d and flush style first to make sure the following DOM APIs
+ // do flush again.
+ target.style.d = 'path("M 0 0")';
+ assert_equals(getComputedStyle(target).d, 'path("M 0 0")', "the initial d");
+ return target;
+}
+
+test(function(t) {
+ const target = createPath(t);
+ target.style.d = 'path("M5,5 L10,5 L10,10")';
+ assert_equals(target.getTotalLength(), 10, "the total length");
+}, "getTotalLength() with d property");
+
+test(function(t) {
+ const target = createPath(t);
+ target.style.d = 'path("M5,5 L10,5 L10,10")';
+ // The first segment of path is (5,5) to (10,5), its length is 5.
+ // The second segment of path is (10,5) to (10,10), its length is 5.
+ // So, the length 8 is on the 2nd segment, at (10,8).
+ const point = target.getPointAtLength(8);
+ assert_equals(point.x, 10, "x-axis position");
+ assert_equals(point.y, 8, "y-axis position");
+}, "getPointAtLength() with d property");
+
+test(function(t) {
+ const target = createPath(t);
+ const svgPoint = document.getElementById("svgroot").createSVGPoint();
+ svgPoint.x = 10;
+ svgPoint.y = 8;
+
+ target.style.d = 'path("M5,5 L10,5 L10,10")';
+ assert_equals(target.isPointInFill(svgPoint), true);
+}, "isPointInFill() with d property");
+
+test(function(t) {
+ const target = createPath(t);
+ const svgPoint = document.getElementById("svgroot").createSVGPoint();
+ svgPoint.x = 10;
+ svgPoint.y = 8;
+
+ target.style.d = 'path("M5,5 L10,5 L10,10")';
+ assert_equals(target.isPointInStroke(svgPoint), true);
+}, "isPointInStroke() with d property");
+
+</script>