SMIL animations of SVG <view> element have no effect
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 10 Sep 2019 19:57:21 +0000 (19:57 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 10 Sep 2019 19:57:21 +0000 (19:57 +0000)
https://bugs.webkit.org/show_bug.cgi?id=201536

Patch by Nikolas Zimmermann <zimmermann@kde.org> on 2019-09-10
Reviewed by Rob Buis.

Added a new layout test to verify that navigating to different anchors within the same
external SVG does not cause reloads. Instead scrollToAnchor() is used which causes an
in-place navigation in the same document. The new test verifies that the SVGSVGElement
is preserved when navigating between anchors, which indicates that no new document was
created. Verify that the SVGViewSpec API works as intended, across navigations.

* svg/dom/SVGViewSpec-multiple-views-expected.txt: Added.
* svg/dom/SVGViewSpec-multiple-views.html: Added.
* svg/dom/resources/multiple-view-elements.svg: Added.

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

LayoutTests/ChangeLog
LayoutTests/svg/dom/SVGViewSpec-multiple-views-expected.txt [new file with mode: 0644]
LayoutTests/svg/dom/SVGViewSpec-multiple-views.html [new file with mode: 0644]
LayoutTests/svg/dom/resources/multiple-view-elements.svg [new file with mode: 0644]

index 165b404..33b88df 100644 (file)
@@ -1,3 +1,20 @@
+2019-09-10  Nikolas Zimmermann  <zimmermann@kde.org>
+
+        SMIL animations of SVG <view> element have no effect
+        https://bugs.webkit.org/show_bug.cgi?id=201536
+
+        Reviewed by Rob Buis.
+
+        Added a new layout test to verify that navigating to different anchors within the same
+        external SVG does not cause reloads. Instead scrollToAnchor() is used which causes an
+        in-place navigation in the same document. The new test verifies that the SVGSVGElement
+        is preserved when navigating between anchors, which indicates that no new document was
+        created. Verify that the SVGViewSpec API works as intended, across navigations.
+
+        * svg/dom/SVGViewSpec-multiple-views-expected.txt: Added.
+        * svg/dom/SVGViewSpec-multiple-views.html: Added.
+        * svg/dom/resources/multiple-view-elements.svg: Added.
+
 2019-09-10  Chris Dumez  <cdumez@apple.com>
 
         Unreviewed, re-skip service worker test that was unskipped in r249716.
diff --git a/LayoutTests/svg/dom/SVGViewSpec-multiple-views-expected.txt b/LayoutTests/svg/dom/SVGViewSpec-multiple-views-expected.txt
new file mode 100644 (file)
index 0000000..bffbd97
--- /dev/null
@@ -0,0 +1,94 @@
+This test checks the SVGViewSpec API using multiple elements
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+Loading external SVG resources/multiple-view-elements.svg#view1...
+
+
+Check transform value
+PASS currentView.transformString is ""
+PASS currentView.transform.numberOfItems is 0
+
+Check viewTarget value
+PASS currentView.viewTargetString is ""
+PASS currentView.viewTarget is null
+
+Check zoomAndPan value
+PASS currentView.zoomAndPan is SVGViewElement.SVG_ZOOMANDPAN_MAGNIFY
+
+Check viewBox value
+PASS currentView.viewBox.baseVal.x is 0
+PASS currentView.viewBox.baseVal.y is 0
+PASS currentView.viewBox.baseVal.width is 10
+PASS currentView.viewBox.baseVal.height is 10
+PASS currentView.viewBoxString is "0 0 10 10"
+
+Check preserveAspectRatio value
+PASS currentView.preserveAspectRatioString is "xMidYMid meet"
+PASS currentView.preserveAspectRatio.baseVal.align is SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMID
+PASS currentView.preserveAspectRatio.baseVal.meetOrSlice is SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET
+
+Loading external SVG resources/multiple-view-elements.svg#view2...
+
+Verify that no load was performed, but only a different view was set on the same document
+PASS iframeElement.contentDocument.documentElement is firstDocumentElement
+
+Check transform value
+PASS currentView.transformString is ""
+PASS currentView.transform.numberOfItems is 0
+
+Check viewTarget value
+PASS currentView.viewTargetString is ""
+PASS currentView.viewTarget is null
+
+Check zoomAndPan value
+PASS currentView.zoomAndPan is SVGViewElement.SVG_ZOOMANDPAN_MAGNIFY
+
+Check viewBox value
+PASS currentView.viewBox.baseVal.x is 40
+PASS currentView.viewBox.baseVal.y is 0
+PASS currentView.viewBox.baseVal.width is 20
+PASS currentView.viewBox.baseVal.height is 10
+PASS currentView.viewBoxString is "40 0 20 10"
+
+Check preserveAspectRatio value
+PASS currentView.preserveAspectRatioString is "xMidYMax slice"
+PASS currentView.preserveAspectRatio.baseVal.align is SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMAX
+PASS currentView.preserveAspectRatio.baseVal.meetOrSlice is SVGPreserveAspectRatio.SVG_MEETORSLICE_SLICE
+
+Loading external SVG resources/multiple-view-elements.svg#svgView(viewBox(0 0 10 15);transform(scale(2 2));preserveAspectRatio(xMinYMax meet))...
+
+Verify that no load was performed, but only a different view was set on the same document
+PASS iframeElement.contentDocument.documentElement is firstDocumentElement
+
+Check transform value
+PASS currentView.transformString is "scale(2 2)"
+PASS currentView.transform.numberOfItems is 1
+PASS currentView.transform.getItem(0).type is SVGTransform.SVG_TRANSFORM_SCALE
+PASS currentView.transform.getItem(0).angle is 0
+PASS matrixToString(currentView.transform.getItem(0).matrix) is "[2.00 0.00 0.00 2.00 0.00 0.00]"
+
+Check viewTarget value
+PASS currentView.viewTargetString is ""
+PASS currentView.viewTarget is null
+
+Check zoomAndPan value
+PASS currentView.zoomAndPan is SVGViewElement.SVG_ZOOMANDPAN_MAGNIFY
+
+Check viewBox value
+PASS currentView.viewBox.baseVal.x is 0
+PASS currentView.viewBox.baseVal.y is 0
+PASS currentView.viewBox.baseVal.width is 10
+PASS currentView.viewBox.baseVal.height is 15
+PASS currentView.viewBoxString is "0 0 10 15"
+
+Check preserveAspectRatio value
+PASS currentView.preserveAspectRatioString is "xMinYMax meet"
+PASS currentView.preserveAspectRatio.baseVal.align is SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMINYMAX
+PASS currentView.preserveAspectRatio.baseVal.meetOrSlice is SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/svg/dom/SVGViewSpec-multiple-views.html b/LayoutTests/svg/dom/SVGViewSpec-multiple-views.html
new file mode 100644 (file)
index 0000000..62a3349
--- /dev/null
@@ -0,0 +1,170 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script>
+description("This test checks the SVGViewSpec API using multiple <view> elements");
+jsTestIsAsync = true;
+
+var externalSVGFileName = "resources/multiple-view-elements.svg";
+
+function matrixToString(matrix) {
+    return "[" + matrix.a.toFixed(2) + " " + matrix.b.toFixed(2) + " " + matrix.c.toFixed(2) + " " + matrix.d.toFixed(2) + " " + matrix.e.toFixed(2) + " " + matrix.f.toFixed(2) + "]";
+}
+
+var firstDocumentElement;
+
+function testFirstViewElement() {
+
+    iframeElement = document.getElementById("iframe");
+    currentDocumentElement = iframeElement.contentDocument.documentElement;
+    firstDocumentElement = currentDocumentElement;
+    currentView = currentDocumentElement.currentView;
+
+    debug("");
+    debug("Check transform value");
+    shouldBeEmptyString("currentView.transformString");
+    shouldBe("currentView.transform.numberOfItems", "0");
+
+    debug("");
+    debug("Check viewTarget value");
+    shouldBeEmptyString("currentView.viewTargetString");
+    shouldBeNull("currentView.viewTarget");
+
+    debug("");
+    debug("Check zoomAndPan value");
+    shouldBe("currentView.zoomAndPan", "SVGViewElement.SVG_ZOOMANDPAN_MAGNIFY");
+
+    debug("");
+    debug("Check viewBox value");
+    shouldBe("currentView.viewBox.baseVal.x", "0");
+    shouldBe("currentView.viewBox.baseVal.y", "0");
+    shouldBe("currentView.viewBox.baseVal.width", "10");
+    shouldBe("currentView.viewBox.baseVal.height", "10");
+    shouldBeEqualToString("currentView.viewBoxString", "0 0 10 10");
+
+    debug("");
+    debug("Check preserveAspectRatio value");
+    shouldBeEqualToString("currentView.preserveAspectRatioString", "xMidYMid meet");
+    shouldBe("currentView.preserveAspectRatio.baseVal.align", "SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMID");
+    shouldBe("currentView.preserveAspectRatio.baseVal.meetOrSlice", "SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET");
+
+    nextView = "#view2";
+    debug("");
+    debug("Loading external SVG " + externalSVGFileName + nextView + "...");
+    debug("");
+
+    iframeElement.src = externalSVGFileName + nextView;
+    testSecondViewElement();
+}
+
+function testSecondViewElement() {
+
+    iframeElement = document.getElementById("iframe");
+    currentView = iframeElement.contentDocument.documentElement.currentView;
+
+    debug("Verify that no load was performed, but only a different view was set on the same document");
+    shouldBe("iframeElement.contentDocument.documentElement", "firstDocumentElement");
+
+    debug("");
+    debug("Check transform value");
+    shouldBeEmptyString("currentView.transformString");
+    shouldBe("currentView.transform.numberOfItems", "0");
+
+    debug("");
+    debug("Check viewTarget value");
+    shouldBeEmptyString("currentView.viewTargetString");
+    shouldBeNull("currentView.viewTarget");
+
+    debug("");
+    debug("Check zoomAndPan value");
+    shouldBe("currentView.zoomAndPan", "SVGViewElement.SVG_ZOOMANDPAN_MAGNIFY");
+
+    debug("");
+    debug("Check viewBox value");
+    shouldBe("currentView.viewBox.baseVal.x", "40");
+    shouldBe("currentView.viewBox.baseVal.y", "0");
+    shouldBe("currentView.viewBox.baseVal.width", "20");
+    shouldBe("currentView.viewBox.baseVal.height", "10");
+    shouldBeEqualToString("currentView.viewBoxString", "40 0 20 10");
+
+    debug("");
+    debug("Check preserveAspectRatio value");
+    shouldBeEqualToString("currentView.preserveAspectRatioString", "xMidYMax slice");
+    shouldBe("currentView.preserveAspectRatio.baseVal.align", "SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMAX");
+    shouldBe("currentView.preserveAspectRatio.baseVal.meetOrSlice", "SVGPreserveAspectRatio.SVG_MEETORSLICE_SLICE");
+
+    nextView = "#svgView(viewBox(0 0 10 15);transform(scale(2 2));preserveAspectRatio(xMinYMax meet))";
+    debug("");
+    debug("Loading external SVG " + externalSVGFileName + nextView + "...");
+    debug("");
+
+    iframeElement.src = externalSVGFileName + nextView;
+    testCustomViewSpec();
+}
+
+function testCustomViewSpec() {
+
+    iframeElement = document.getElementById("iframe");
+    currentView = iframeElement.contentDocument.documentElement.currentView;
+
+    debug("Verify that no load was performed, but only a different view was set on the same document");
+    shouldBe("iframeElement.contentDocument.documentElement", "firstDocumentElement");
+
+    debug("");
+    debug("Check transform value");
+    shouldBeEqualToString("currentView.transformString", "scale(2 2)");
+    shouldBe("currentView.transform.numberOfItems", "1");
+
+    shouldBe("currentView.transform.getItem(0).type", "SVGTransform.SVG_TRANSFORM_SCALE");
+    shouldBe("currentView.transform.getItem(0).angle", "0");
+    shouldBeEqualToString("matrixToString(currentView.transform.getItem(0).matrix)", "[2.00 0.00 0.00 2.00 0.00 0.00]");
+
+    debug("");
+    debug("Check viewTarget value");
+    shouldBeEmptyString("currentView.viewTargetString");
+    shouldBeNull("currentView.viewTarget");
+
+    debug("");
+    debug("Check zoomAndPan value");
+    shouldBe("currentView.zoomAndPan", "SVGViewElement.SVG_ZOOMANDPAN_MAGNIFY");
+
+    debug("");
+    debug("Check viewBox value");
+    shouldBe("currentView.viewBox.baseVal.x", "0");
+    shouldBe("currentView.viewBox.baseVal.y", "0");
+    shouldBe("currentView.viewBox.baseVal.width", "10");
+    shouldBe("currentView.viewBox.baseVal.height", "15");
+    shouldBeEqualToString("currentView.viewBoxString", "0 0 10 15");
+
+    debug("");
+    debug("Check preserveAspectRatio value");
+    shouldBeEqualToString("currentView.preserveAspectRatioString", "xMinYMax meet");
+    shouldBe("currentView.preserveAspectRatio.baseVal.align", "SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMINYMAX");
+    shouldBe("currentView.preserveAspectRatio.baseVal.meetOrSlice", "SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET");
+
+    finishJSTest();
+}
+
+nextView = "#view1";
+debug("");
+debug("Loading external SVG " + externalSVGFileName + nextView + "...");
+debug("");
+
+var iframeElement = document.createElement("iframe");
+iframeElement.setAttribute("id", "iframe");
+iframeElement.setAttribute("width", "120px");
+iframeElement.setAttribute("height", "120px");
+iframeElement.setAttribute("onload", "setTimeout(testFirstViewElement, 0)");
+iframeElement.src = externalSVGFileName + "#view1";
+document.getElementById("console").appendChild(iframeElement);
+
+successfullyParsed = true;
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/svg/dom/resources/multiple-view-elements.svg b/LayoutTests/svg/dom/resources/multiple-view-elements.svg
new file mode 100644 (file)
index 0000000..a1bc861
--- /dev/null
@@ -0,0 +1,9 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">
+  <rect x="0" y="0" width="10" height="10" fill="green"/>
+  <rect x="15" y="0" width="20" height="20" fill="red"/>
+  <rect x="40" y="0" width="20" height="10" fill="green"/>
+  <rect x="65" y="0" width="20" height="15" fill="red"/>
+
+  <view id="view1" viewBox="0 0 10 10"/>
+  <view id="view2" viewBox="40 0 20 10" preserveAspectRatio="xMidYMax slice"/>
+</svg>