diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /testing/web-platform/tests/svg/interact | |
parent | Initial commit. (diff) | |
download | firefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/svg/interact')
17 files changed, 1053 insertions, 0 deletions
diff --git a/testing/web-platform/tests/svg/interact/inheritance.svg b/testing/web-platform/tests/svg/interact/inheritance.svg new file mode 100644 index 0000000000..e67f19ed43 --- /dev/null +++ b/testing/web-platform/tests/svg/interact/inheritance.svg @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg xmlns="http://www.w3.org/2000/svg" + xmlns:h="http://www.w3.org/1999/xhtml" + width="800px" height="8000px"> + <title>Inheritance of pointer-events</title> + <metadata> + <h:link rel="help" href="https://svgwg.org/svg2-draft/interact.html#PointerEventsProperty"/> + <h:meta name="assert" content="pointer-events inherits according to the spec."/> + <h:meta name="assert" content="pointer-events has initial value auto."/> + </metadata> + <g id="container"> + <g id="target"></g> + </g> + <h:script src="/resources/testharness.js"/> + <h:script src="/resources/testharnessreport.js"/> + <h:script src="/css/support/inheritance-testcommon.js"/> + <script><![CDATA[ + +assert_inherited('pointer-events', 'auto', 'none'); + + ]]></script> +</svg> diff --git a/testing/web-platform/tests/svg/interact/manual/event-attribute-001-manual.svg b/testing/web-platform/tests/svg/interact/manual/event-attribute-001-manual.svg new file mode 100644 index 0000000000..af22470b9a --- /dev/null +++ b/testing/web-platform/tests/svg/interact/manual/event-attribute-001-manual.svg @@ -0,0 +1,27 @@ +<?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%" viewBox="0 0 480 360"> + <title>Event attributes - onwheel</title> + <metadata> + <h:link rel="help" href="https://svgwg.org/svg2-draft/interact.html#EventAttributes"/> + <h:link rel="help" href="https://svgwg.org/svg2-draft/attindex.html#RegularAttributes"/> + <h:meta name="assert" content="onwheel attribute runs script in response to wheel events"/> + </metadata> + <style> + text { + font-size: 12px; + } + #target { + fill: yellow; + } + </style> + <script> + 'use strict'; + function complete() { + document.getElementById('target').style.fill = 'lime'; + } + </script> + <text x="30" y="30">Select the box, use the mouse wheel and check that the box become green.</text> + <rect id="target" x="140" y="160" width="200" height="200" onwheel="complete()" /> +</svg> diff --git a/testing/web-platform/tests/svg/interact/parsing/pointer-events-computed.svg b/testing/web-platform/tests/svg/interact/parsing/pointer-events-computed.svg new file mode 100644 index 0000000000..e168d6d9b5 --- /dev/null +++ b/testing/web-platform/tests/svg/interact/parsing/pointer-events-computed.svg @@ -0,0 +1,28 @@ +<svg xmlns="http://www.w3.org/2000/svg" + xmlns:h="http://www.w3.org/1999/xhtml" + width="800px" height="8000px"> + <title>SVG Scripting and Interactivity: getComputedStyle().pointerEvents</title> + <metadata> + <h:link rel="help" href="https://svgwg.org/svg2-draft/interact.html#PointerEventsProperty"/> + <h:meta name="assert" content="pointer-events computed value is as specified."/> + </metadata> + <g id="target"></g> + <h:script src="/resources/testharness.js"/> + <h:script src="/resources/testharnessreport.js"/> + <h:script src="/css/support/computed-testcommon.js"/> + <script><![CDATA[ + +test_computed_value("pointer-events", "auto"); +test_computed_value("pointer-events", "bounding-box"); +test_computed_value("pointer-events", "visiblepainted"); +test_computed_value("pointer-events", "visiblefill"); +test_computed_value("pointer-events", "visiblestroke"); +test_computed_value("pointer-events", "visible"); +test_computed_value("pointer-events", "painted"); +test_computed_value("pointer-events", "fill"); +test_computed_value("pointer-events", "stroke"); +test_computed_value("pointer-events", "all"); +test_computed_value("pointer-events", "none"); + + ]]></script> +</svg> diff --git a/testing/web-platform/tests/svg/interact/parsing/pointer-events-invalid.svg b/testing/web-platform/tests/svg/interact/parsing/pointer-events-invalid.svg new file mode 100644 index 0000000000..12f1c48ece --- /dev/null +++ b/testing/web-platform/tests/svg/interact/parsing/pointer-events-invalid.svg @@ -0,0 +1,20 @@ +<svg xmlns="http://www.w3.org/2000/svg" + xmlns:h="http://www.w3.org/1999/xhtml" + width="800px" height="8000px"> + <title>SVG Scripting and Interactivity: parsing pointer-events with invalid values</title> + <metadata> + <h:link rel="help" href="https://svgwg.org/svg2-draft/interact.html#PointerEventsProperty"/> + <h:meta name="assert" content="pointer-events supports only the grammar 'auto | bounding-box | visiblePainted | visibleFill | visibleStroke | visible | painted | fill | stroke | all | none'."/> + </metadata> + <g id="target"></g> + <h:script src="/resources/testharness.js"/> + <h:script src="/resources/testharnessreport.js"/> + <h:script src="/css/support/parsing-testcommon.js"/> + <script><![CDATA[ + +test_invalid_value("pointer-events", "markers"); +test_invalid_value("pointer-events", "0"); +test_invalid_value("pointer-events", "visiblePainted visibleFill"); + + ]]></script> +</svg> diff --git a/testing/web-platform/tests/svg/interact/parsing/pointer-events-valid.svg b/testing/web-platform/tests/svg/interact/parsing/pointer-events-valid.svg new file mode 100644 index 0000000000..d72aee6273 --- /dev/null +++ b/testing/web-platform/tests/svg/interact/parsing/pointer-events-valid.svg @@ -0,0 +1,28 @@ +<svg xmlns="http://www.w3.org/2000/svg" + xmlns:h="http://www.w3.org/1999/xhtml" + width="800px" height="8000px"> + <title>SVG Scripting and Interactivity: parsing pointer-events with valid values</title> + <metadata> + <h:link rel="help" href="https://svgwg.org/svg2-draft/interact.html#PointerEventsProperty"/> + <h:meta name="assert" content="pointer-events supports the full grammar 'auto | bounding-box | visiblePainted | visibleFill | visibleStroke | visible | painted | fill | stroke | all | none'."/> + </metadata> + <g id="target"></g> + <h:script src="/resources/testharness.js"/> + <h:script src="/resources/testharnessreport.js"/> + <h:script src="/css/support/parsing-testcommon.js"/> + <script><![CDATA[ + +test_valid_value("pointer-events", "auto"); +test_valid_value("pointer-events", "bounding-box"); +test_valid_value("pointer-events", "visiblePainted", "visiblepainted"); +test_valid_value("pointer-events", "visibleFill", "visiblefill"); +test_valid_value("pointer-events", "visibleStroke", "visiblestroke"); +test_valid_value("pointer-events", "visible"); +test_valid_value("pointer-events", "painted"); +test_valid_value("pointer-events", "fill"); +test_valid_value("pointer-events", "stroke"); +test_valid_value("pointer-events", "all"); +test_valid_value("pointer-events", "none"); + + ]]></script> +</svg> diff --git a/testing/web-platform/tests/svg/interact/script-common.html b/testing/web-platform/tests/svg/interact/script-common.html new file mode 100644 index 0000000000..fc2ae3ba01 --- /dev/null +++ b/testing/web-platform/tests/svg/interact/script-common.html @@ -0,0 +1,55 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test: </title> +<link rel="help" href="https://svgwg.org/svg2-draft/interact.html#ScriptElement"> +<meta name="assert" content="The same scripts can work on both HTML and SVG elements."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script>var total = 0;</script> +<script>function s0() { total += 100; return s1(); }</script> +<svg> + <script>function s1() { total += 20; return s2(); }</script> + <g> + <script>function s2() { return s3(); }</script> + <circle id="spot"><clipPath id="spot-first-child"/> + <script>function s3() { return s4(); }</script> + </circle> + </g> + <desc> + <script>function s4() { return s5(); }</script> + </desc> + <filter> + <script>function s5() { return s6(); }</script> + <feFlood> + <script>function s6() { return s7(); }</script> + </feFlood> + </filter> + <text> + <script>function s7() { return s8(); }</script> + <tspan> + <script>function s8() { return s9(); }</script> + </tspan> + </text> + <use href="spot"> + <script>function s9() { return s10(); }</script> + </use> +</svg> +<div id="box"><script id="box-first-child">function s10() { total += 3; return s11(); }</script> + <span> + <script>function s11() { return 'same'; }</script> + </span> +</div> + +<script> +test(function(){ + assert_equals(s0(), 'same'); + assert_equals(total, 123); + + for (let elementName of ['spot', 'box']) { + let element = document.getElementById(elementName); + let firstChild = element.firstChild; + assert_equals(firstChild.id, elementName + '-first-child'); + } +}, 'The same scripts work on both HTML and SVG elements'); +</script> diff --git a/testing/web-platform/tests/svg/interact/script-content.svg b/testing/web-platform/tests/svg/interact/script-content.svg new file mode 100644 index 0000000000..94836f7c03 --- /dev/null +++ b/testing/web-platform/tests/svg/interact/script-content.svg @@ -0,0 +1,239 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg xmlns="http://www.w3.org/2000/svg" + xmlns:h="http://www.w3.org/1999/xhtml"> + <h:link rel="help" href="https://svgwg.org/svg2-draft/interact.html#ScriptElement"/> + <h:meta name="assert" content="The script element is in the content model of all elements."/> + <h:script src="/resources/testharness.js"/> + <h:script src="/resources/testharnessreport.js"/> + +<script>function s0() { return s1(); }</script> + +<a> + <script>function s1() { return s2(); }</script> +</a> + +<g> + <script>function s2() { return s3(); }</script> +</g> + +<animate> + <script>function s3() { return s4(); }</script> +</animate> + +<animateMotion> + <script>function s4() { return s5(); }</script> + <mPath> + <script>function s5() { return s6(); }</script> + </mPath> +</animateMotion> + +<animateTransform> + <script>function s6() { return s7(); }</script> +</animateTransform> + +<circle> + <script>function s7() { return s8(); }</script> + <clipPath> + <script>function s8() { return s9(); }</script> + </clipPath> +</circle> + +<defs> + <script>function s9() { return s10(); }</script> +</defs> + +<desc> + <script>function s10() { return s11(); }</script> +</desc> + +<!-- Becomes https://svgwg.org/svg2-draft/struct.html#UnknownElement + if the implementation does not support <discard> --> +<discard> + <script>function s11() { return s12(); }</script> +</discard> + +<ellipse> + <script>function s12() { return s13(); }</script> +</ellipse> + +<filter> + <script>function s13() { return s14(); }</script> + <feBlend> + <script>function s14() { return s15(); }</script> + </feBlend> + <feColorMatrix> + <script>function s15() { return s16(); }</script> + </feColorMatrix> + <feComponentTransfer> + <script>function s16() { return s17(); }</script> + </feComponentTransfer> + <feComposite> + <script>function s17() { return s18(); }</script> + </feComposite> + <feConvolveMatrix> + <script>function s18() { return s19(); }</script> + </feConvolveMatrix> + <feDiffuseLighting> + <script>function s19() { return s20(); }</script> + </feDiffuseLighting> + <feDisplacementMap> + <script>function s20() { return s21(); }</script> + </feDisplacementMap> + <feDistantLight> + <script>function s21() { return s22(); }</script> + </feDistantLight> + <feDropShadow> + <script>function s22() { return s23(); }</script> + </feDropShadow> + <feFlood> + <script>function s23() { return s24(); }</script> + </feFlood> + <feFuncA> + <script>function s24() { return s25(); }</script> + </feFuncA> + <feFuncB> + <script>function s25() { return s26(); }</script> + </feFuncB> + <feFuncG> + <script>function s26() { return s27(); }</script> + </feFuncG> + <feFuncR> + <script>function s27() { return s28(); }</script> + </feFuncR> + <feGaussianBlur> + <script>function s28() { return s29(); }</script> + </feGaussianBlur> + <feImage> + <script>function s29() { return s30(); }</script> + </feImage> + <feMerge> + <script>function s30() { return s31(); }</script> + </feMerge> + <feMergeNode> + <script>function s31() { return s32(); }</script> + </feMergeNode> + <feMorphology> + <script>function s32() { return s33(); }</script> + </feMorphology> + <feOffset> + <script>function s33() { return s34(); }</script> + </feOffset> + <fePointLight> + <script>function s34() { return s35(); }</script> + </fePointLight> + <feSpecularLighting> + <script>function s35() { return s36(); }</script> + </feSpecularLighting> + <feSpotLight> + <script>function s36() { return s37(); }</script> + </feSpotLight> + <feTile> + <script>function s37() { return s38(); }</script> + </feTile> + <feTurbulence> + <script>function s38() { return s39(); }</script> + </feTurbulence> +</filter> + +<foreignObject> + <script>function s39() { return s40(); }</script> +</foreignObject> + +<g> + <script>function s40() { return s41(); }</script> +</g> + +<image> + <script>function s41() { return s42(); }</script> +</image> + +<line> + <script>function s42() { return s43(); }</script> +</line> + +<linearGradient> + <script>function s43() { return s44(); }</script> +</linearGradient> + +<marker> + <script>function s44() { return s45(); }</script> +</marker> + +<mask> + <script>function s45() { return s46(); }</script> +</mask> + +<path> + <script>function s46() { return s47(); }</script> +</path> + +<pattern> + <script>function s47() { return s48(); }</script> +</pattern> + +<polygon> + <script>function s48() { return s49(); }</script> +</polygon> + +<polyline> + <script>function s49() { return s50(); }</script> +</polyline> + +<radialGradient> + <script>function s50() { return s51(); }</script> +</radialGradient> + +<rect> + <script>function s51() { return s52(); }</script> +</rect> + +<set> + <script>function s52() { return s53(); }</script> +</set> + +<stop> + <script>function s53() { return s54(); }</script> +</stop> + +<svg> + <script>function s54() { return s55(); }</script> +</svg> + +<symbol> + <script>function s55() { return s56(); }</script> +</symbol> + +<text> + <script>function s56() { return s57(); }</script> +</text> + +<textPath> + <script>function s57() { return s58(); }</script> +</textPath> + +<title> + <script>function s58() { return s59(); }</script> +</title> + +<tspan> + <script>function s59() { return s60(); }</script> +</tspan> + +<use> + <script>function s60() { return s61(); }</script> +</use> + +<view> + <script>function s61() { return s62(); }</script> +</view> + +<script> +function s62() { + return 'success'; +} + +test(function(){ + assert_equals(s0(), 'success'); +}, "script element is in elements' content model"); +</script> +</svg> diff --git a/testing/web-platform/tests/svg/interact/scripted/composed.window.svg b/testing/web-platform/tests/svg/interact/scripted/composed.window.svg new file mode 100644 index 0000000000..b63dcf0244 --- /dev/null +++ b/testing/web-platform/tests/svg/interact/scripted/composed.window.svg @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg xmlns="http://www.w3.org/2000/svg" + xmlns:h="http://www.w3.org/1999/xhtml"> + <title>Focus events are composed</title> + <metadata> + <h:link rel="help" href="https://svgwg.org/svg2-draft/interact.html#Focus"/> + </metadata> + <a id="a1" href="#"></a> + <h:script src="/resources/testharness.js"/> + <h:script src="/resources/testharnessreport.js"/> + <script><![CDATA[ + async_test(t => { + const anchor = document.getElementById("a1"); + let happened = false; + anchor.onfocus = t.step_func(e => { + happened = true; + assert_equals(e.type, "focus"); + assert_true(e.composed); + }); + anchor.focus(); + anchor.onblur = t.step_func_done(e => { + assert_true(happened); + assert_equals(e.type, "blur"); + assert_true(e.composed); + }); + anchor.blur(); + }, "Focus events are composed"); + ]]></script> +</svg>
\ No newline at end of file diff --git a/testing/web-platform/tests/svg/interact/scripted/ellipse-hittest.html b/testing/web-platform/tests/svg/interact/scripted/ellipse-hittest.html new file mode 100644 index 0000000000..70b54e0726 --- /dev/null +++ b/testing/web-platform/tests/svg/interact/scripted/ellipse-hittest.html @@ -0,0 +1,76 @@ +<!DOCTYPE html> +<title>elementFromPoint(...) on <ellipse>s with continuous strokes</title> +<link rel="help" href="https://svgwg.org/svg2-draft/interact.html#hit-testing"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +#ell1:hover, +#ell2:hover, +#ell3:hover { + stroke: #9f9; +} +</style> +<svg id="svg" width="450" height="300"> + <rect id="border" x="0.5" y="0.5" width="449" height="299" stroke="#000" stroke-width="1" fill="none"/> + + <ellipse id="ell1" cx="130" cy="30" rx="100" ry="15" stroke="#ccf" fill="none" stroke-width="20"/> + <ellipse pointer-events="none" cx="130" cy="30" rx="110" ry="25" stroke="gray" fill="none"/> + <ellipse pointer-events="none" cx="130" cy="30" rx="90" ry="5" stroke="gray" fill="none"/> + + <ellipse id="ell2" cx="130" cy="180" rx="100" ry="100" stroke="#ccf" fill="none" stroke-width="30"/> + <ellipse pointer-events="none" cx="130" cy="180" rx="115" ry="115" stroke="gray" fill="none"/> + <ellipse pointer-events="none" cx="130" cy="180" rx="85" ry="85" stroke="gray" fill="none"/> + + <ellipse id="ell3" cx="340" cy="155" rx="15" ry="100" stroke="#ccf" fill="none" stroke-width="20" transform="rotate(30 340 155)"/> + <ellipse pointer-events="none" cx="340" cy="155" rx="25" ry="110" stroke="gray" fill="none" transform="rotate(30 340 155)"/> + <ellipse pointer-events="none" cx="340" cy="155" rx="5" ry="90" stroke="gray" fill="none" transform="rotate(30 340 155)"/> +</svg> +<script> +// Points are relative to the client rect of the <svg> root. +const tests = [ + { x: 27, y: 46, expectedElemId: "svg" }, + { x: 98, y: 33, expectedElemId: "svg" }, + { x: 202, y: 53, expectedElemId: "svg" }, + { x: 98, y: 142, expectedElemId: "svg" }, + { x: 130, y: 180, expectedElemId: "svg" }, + { x: 91, y: 247, expectedElemId: "svg" }, + { x: 27, y: 240, expectedElemId: "svg" }, + { x: 336, y: 166, expectedElemId: "svg" }, + { x: 337, y: 214, expectedElemId: "svg" }, + + { x: 31, y: 18, expectedElemId: "ell1" }, + { x: 209, y: 31, expectedElemId: "ell1" }, + { x: 132, y: 47, expectedElemId: "ell1" }, + { x: 229, y: 43, expectedElemId: "ell1" }, + + { x: 245, y: 180, expectedElemId: "ell2" }, + { x: 45, y: 180, expectedElemId: "ell2" }, + { x: 130, y: 95, expectedElemId: "ell2" }, + { x: 130, y: 295, expectedElemId: "ell2" }, + { x: 212, y: 255, expectedElemId: "ell2" }, + + { x: 280, y: 235, expectedElemId: "ell3" }, + { x: 301, y: 247, expectedElemId: "ell3" }, + { x: 378, y: 88, expectedElemId: "ell3" }, + { x: 335, y: 122, expectedElemId: "ell3" }, + { x: 333, y: 190, expectedElemId: "ell3" }, + { x: 377, y: 66, expectedElemId: "ell3" } +]; + +setup(() => { + const svg = document.getElementById("svg"); + const svgBounds = svg.getBoundingClientRect(); + window.svgOrigin = { + x: svgBounds.left << 0, + y: svgBounds.top << 0, + }; +}); + +tests.forEach(testcase => { + test(t => { + const expectedElem = document.getElementById(testcase.expectedElemId); + const hitElem = document.elementFromPoint(svgOrigin.x + testcase.x, svgOrigin.y + testcase.y); + assert_equals(hitElem, expectedElem); + }, `${document.title}, element at (${testcase.x}, ${testcase.y})`); +}); +</script> diff --git a/testing/web-platform/tests/svg/interact/scripted/focus-events.svg b/testing/web-platform/tests/svg/interact/scripted/focus-events.svg new file mode 100644 index 0000000000..bf307b79fd --- /dev/null +++ b/testing/web-platform/tests/svg/interact/scripted/focus-events.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"> + <title>Focus management</title> + <metadata> + <h:link rel="help" href="https://svgwg.org/svg2-draft/interact.html#Focus"/> + </metadata> + <a id="a1" href="#"></a> + <a id="a2" href="#"></a> + <h:script src="/resources/testharness.js"/> + <h:script src="/resources/testharnessreport.js"/> + <script><![CDATA[ + var a1 = document.getElementById('a1'), + a2 = document.getElementById('a2'), + t1 = async_test("focusing on a focusable element fires a focus event at the element"), + t2 = async_test("focusing on a focusable element fires a blur event at the previous focussed element"); + + a2.onfocus = t1.step_func_done(function(e){ + assert_true(e.isTrusted, "focus event is trusted"); + assert_false(e.bubbles, "focus event doesn't bubble"); + assert_false(e.cancelable, "focus event is not cancelable"); + assert_equals(document.activeElement, a2); + }); + + a1.onblur = t2.step_func_done(function(e){ + assert_true(e.isTrusted, "blur event is trusted"); + assert_false(e.bubbles, "blur event doesn't bubble"); + assert_false(e.cancelable, "blur event is not cancelable"); + }); + + a1.focus(); + a2.focus(); + ]]></script> +</svg>
\ No newline at end of file diff --git a/testing/web-platform/tests/svg/interact/scripted/focus-tabindex-default-value.svg b/testing/web-platform/tests/svg/interact/scripted/focus-tabindex-default-value.svg new file mode 100644 index 0000000000..3af1acffd8 --- /dev/null +++ b/testing/web-platform/tests/svg/interact/scripted/focus-tabindex-default-value.svg @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg xmlns="http://www.w3.org/2000/svg" + xmlns:h="http://www.w3.org/1999/xhtml"> + <title>SVG Test: focus - default value of tabindex</title> + <metadata> + <h:link rel="help" href="https://svgwg.org/svg2-draft/interact.html#Focus"/> + </metadata> + <a id="test1" href="#"></a> + <rect id="test2"></rect> + <h:script src="/resources/testharness.js"/> + <h:script src="/resources/testharnessreport.js"/> + <script><![CDATA[ + test(function() { + assert_equals(document.getElementById("test1").tabIndex, 0, "The value of tabIndex attribute should be 0."); + }, "The default value of tabIndex attribute must be 0 for elements that are focusable"); + + test(function() { + assert_equals(document.getElementById("test2").tabIndex, -1, "The value of tabIndex attribute should be -1."); + }, "The default value of tabIndex attribute must be -1 for elements that are not focusable"); + ]]></script> +</svg>
\ No newline at end of file diff --git a/testing/web-platform/tests/svg/interact/scripted/rect-hittest-001.html b/testing/web-platform/tests/svg/interact/scripted/rect-hittest-001.html new file mode 100644 index 0000000000..4256628bc6 --- /dev/null +++ b/testing/web-platform/tests/svg/interact/scripted/rect-hittest-001.html @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<title>elementFromPoint(...) on <rect>s</title> +<link rel="help" href="https://svgwg.org/svg2-draft/interact.html#hit-testing"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<svg id="svg" width="420" height="300"> + <rect id="border" x="0.5" y="0.5" width="419" height="299" stroke="#000" stroke-width="1" fill="none"/> + + <rect id="rect1" x="40" y="30" width="20" height="20"/> +</svg> +<script> +// Points are relative to the client rect of the <svg> root. +const tests = [ + // Points on the edge. + { x: 50, y: 30, expectedElemId: "rect1" }, + { x: 60, y: 40, expectedElemId: "rect1" }, + { x: 50, y: 50, expectedElemId: "rect1" }, + { x: 40, y: 40, expectedElemId: "rect1" }, +]; + +setup(() => { + const svg = document.getElementById("svg"); + const svgBounds = svg.getBoundingClientRect(); + window.svgOrigin = { + x: svgBounds.left << 0, + y: svgBounds.top << 0, + }; +}); + +tests.forEach(testcase => { + test(t => { + const expectedElem = document.getElementById(testcase.expectedElemId); + const hitElem = document.elementFromPoint(svgOrigin.x + testcase.x, svgOrigin.y + testcase.y); + assert_equals(hitElem, expectedElem); + }, `${document.title}, element at (${testcase.x}, ${testcase.y})`); +}); +</script> diff --git a/testing/web-platform/tests/svg/interact/scripted/rect-hittest-002.html b/testing/web-platform/tests/svg/interact/scripted/rect-hittest-002.html new file mode 100644 index 0000000000..7eb70f8530 --- /dev/null +++ b/testing/web-platform/tests/svg/interact/scripted/rect-hittest-002.html @@ -0,0 +1,109 @@ +<!DOCTYPE html> +<title>elementFromPoint(...) on <rect>s with simple strokes</title> +<link rel="help" href="https://svgwg.org/svg2-draft/interact.html#hit-testing"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +#rect1:hover, +#rect2:hover, +#rect3:hover, +#rect4:hover, +#rect5:hover, +#rect6:hover { + stroke: #00f; +} +</style> +<svg id="svg" width="420" height="300" version="1.1"> + <rect id="border" x="0.5" y="0.5" width="419" height="299" stroke="#000" stroke-width="1" fill="none"/> + + <rect id="rect1" x="70" y="30" width="100" height="80" stroke="#000" stroke-width="20" fill="none"/> + <rect id="rect2" x="40" y="150" width="50" height="120" stroke="#000" stroke-width="20" fill="none" transform="rotate(20 65 210)"/> + <rect id="rect3" x="140" y="200" width="150" height="70" stroke="#000" stroke-width="20" fill="none"/> + <rect id="rect4" x="220" y="50" width="60" height="10" stroke="#000" stroke-width="20" fill="none"/> + <rect id="rect5" x="230" y="100" width="10" height="60" stroke="#000" stroke-width="20" fill="none" transform="rotate(-45 235 130)"/> + <rect id="rect6" x="310" y="130" width="10" height="10" stroke="#000" stroke-width="20" fill="none"/> +</svg> +<script> +// Points are relative to the client rect of the <svg> root. +const tests = [ + { x: 30, y: 12, expectedElemId: "svg" }, + { x: 118, y: 10, expectedElemId: "svg" }, + { x: 197, y: 12, expectedElemId: "svg" }, + { x: 201, y: 28, expectedElemId: "svg" }, + { x: 15, y: 70, expectedElemId: "svg" }, + { x: 97, y: 52, expectedElemId: "svg" }, + { x: 149, y: 49, expectedElemId: "svg" }, + { x: 85, y: 82, expectedElemId: "svg" }, + { x: 122, y: 98, expectedElemId: "svg" }, + { x: 154, y: 75, expectedElemId: "svg" }, + { x: 72, y: 130, expectedElemId: "svg" }, + { x: 48, y: 145, expectedElemId: "svg" }, + { x: 31, y: 279, expectedElemId: "svg" }, + { x: 28, y: 201, expectedElemId: "svg" }, + { x: 71, y: 179, expectedElemId: "svg" }, + { x: 43, y: 244, expectedElemId: "svg" }, + { x: 74, y: 219, expectedElemId: "svg" }, + { x: 94, y: 261, expectedElemId: "svg" }, + { x: 126, y: 231, expectedElemId: "svg" }, + { x: 146, y: 185, expectedElemId: "svg" }, + { x: 173, y: 216, expectedElemId: "svg" }, + { x: 225, y: 258, expectedElemId: "svg" }, + { x: 247, y: 284, expectedElemId: "svg" }, + { x: 286, y: 174, expectedElemId: "svg" }, + { x: 254, y: 120, expectedElemId: "svg" }, + { x: 203, y: 96, expectedElemId: "svg" }, + { x: 244, y: 163, expectedElemId: "svg" }, + { x: 300, y: 37, expectedElemId: "svg" }, + { x: 335, y: 136, expectedElemId: "svg" }, + + // Test all four outer corner points of #rect1 + { x: 60, y: 20, expectedElemId: "rect1" }, + { x: 180, y: 20, expectedElemId: "rect1" }, + { x: 180, y: 120, expectedElemId: "rect1" }, + { x: 60, y: 120, expectedElemId: "rect1" }, + // Test all four interior corner points of #rect1 + { x: 80, y: 40, expectedElemId: "rect1" }, + { x: 160, y: 40, expectedElemId: "rect1" }, + { x: 160, y: 100, expectedElemId: "rect1" }, + { x: 80, y: 100, expectedElemId: "rect1" }, + + { x: 67, y: 56, expectedElemId: "rect1" }, + { x: 146, y: 27, expectedElemId: "rect1" }, + { x: 173, y: 111, expectedElemId: "rect1" }, + + { x: 28, y: 242, expectedElemId: "rect2" }, + { x: 51, y: 182, expectedElemId: "rect2" }, + { x: 89, y: 155, expectedElemId: "rect2" }, + + { x: 136, y: 198, expectedElemId: "rect3" }, + { x: 177, y: 270, expectedElemId: "rect3" }, + { x: 275, y: 197, expectedElemId: "rect3" }, + { x: 297, y: 233, expectedElemId: "rect3" }, + + { x: 235, y: 47, expectedElemId: "rect4" }, + { x: 272, y: 61, expectedElemId: "rect4" }, + { x: 290, y: 70, expectedElemId: "rect4" }, + + { x: 233, y: 140, expectedElemId: "rect5" }, + + { x: 312, y: 128, expectedElemId: "rect6" }, + { x: 330, y: 150, expectedElemId: "rect6" } +]; + +setup(() => { + const svg = document.getElementById("svg"); + const svgBounds = svg.getBoundingClientRect(); + window.svgOrigin = { + x: svgBounds.left << 0, + y: svgBounds.top << 0, + }; +}); + +tests.forEach(testcase => { + test(t => { + const expectedElem = document.getElementById(testcase.expectedElemId); + const hitElem = document.elementFromPoint(svgOrigin.x + testcase.x, svgOrigin.y + testcase.y); + assert_equals(hitElem, expectedElem); + }, `${document.title}, element at (${testcase.x}, ${testcase.y})`); +}); +</script> diff --git a/testing/web-platform/tests/svg/interact/scripted/resources/blank.htm b/testing/web-platform/tests/svg/interact/scripted/resources/blank.htm new file mode 100644 index 0000000000..18ecdcb795 --- /dev/null +++ b/testing/web-platform/tests/svg/interact/scripted/resources/blank.htm @@ -0,0 +1 @@ +<html></html> diff --git a/testing/web-platform/tests/svg/interact/scripted/svg-pointer-events-bbox.html b/testing/web-platform/tests/svg/interact/scripted/svg-pointer-events-bbox.html new file mode 100644 index 0000000000..8db9149c23 --- /dev/null +++ b/testing/web-platform/tests/svg/interact/scripted/svg-pointer-events-bbox.html @@ -0,0 +1,155 @@ +<!DOCTYPE html> +<title>pointer-events: bounding-box</title> +<link rel="help" href="https://svgwg.org/svg2-draft/interact.html#PointerEventsProp"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style type="text/css"> + #svgRoot { + margin: 0px; + padding: 0px; + position: absolute; + top: 0px; + left: 0px; + font: 10px/1 Ahem; + } + + .test { fill: blue; pointer-events: bounding-box; } + .test:hover { fill: green; visibility: visible; } +</style> +<svg id="svgRoot" width="800px" height="360px" viewBox="0 0 800 360" opacity="0"> + <g class="test" id="test1" transform="rotate(15)"> + <circle id="circle1" cx="50" cy="50" r="10"/> + <circle cx="150" cy="150" r="10"/> + </g> + <circle class="test" id="circle2" cx="400" cy="150" r="50" visibility="hidden"/> + <text class="test" id="text1" x="100" y="20">Text should change color when mouse is within <tspan id="tspan1" dy="3em">the bbox.</tspan></text> + <text class="test" id="text2" x="150" y="100" transform="rotate(15)">Text should change color when mouse is within <tspan id="tspan2" dy="3em">the bbox.</tspan></text> + <text class="test" id="text3" x="200" y="280" transform="rotate(5)">Text should end here.<tspan id="tspan3" dy="2em" display="none">invisible</tspan></text> + <image class="test" id="image1" xlink:href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 50 30'><rect x='10' y='10' width='20' height='10' fill='blue'/></svg>" + width="50" height="30" visibility="hidden" transform="translate(0,200)"/> +</svg> +<script> +const group1 = document.getElementById("test1"); +const circle1 = document.getElementById("circle1"); +const circle2 = document.getElementById("circle2"); +const text1 = document.getElementById("text1"); +const tspan1 = document.getElementById("tspan1"); +const text2 = document.getElementById("text2"); +const tspan2 = document.getElementById("tspan2"); +const text3 = document.getElementById("text3"); +const tspan3 = document.getElementById("tspan3"); +const image1 = document.getElementById("image1"); + +const pointsOnCircle1 = [ + {x: 36, y: 60}, + {x: 42, y: 67} +]; + +const pointsNotOnCircle1 = [ + {x: 50, y: 50}, + {x: 50, y: 55} +]; + +const pointsInsideBBoxOfCircle1 = [ + {x: 100, y: 100}, + {x: 137, y: 84}, + {x: 51, y: 156}, + {x:70, y:120} +]; + +const pointsOnCircle2 = [ + {x: 400, y: 150}, + {x: 432, y: 182}, + {x: 361, y: 122} +]; + +const pointsInsideBBoxOfCircle2 = [ + {x: 438, y: 103}, + {x: 450, y: 200} +]; + +const pointsOnText1 = [ + {x: 134, y: 16} +]; + +const pointsOnTspan1 = [ + {x: 579, y: 46} +]; + +const pointsNotOnText1 = [ + {x: 395, y: 73}, + {x: 74, y: 5} +]; + +const pointsInsideBBoxOfText1 = [ + {x: 435, y: 32}, + {x: 115, y: 46} +]; + +const pointsOnText2 = [ + {x: 178, y: 146} +]; + +const pointsOnTspan2 = [ + {x: 568, y: 283} +]; + +const pointsNotOnText2 = [ + {x: 319, y: 161}, + {x: 179, y: 131} +]; + +const pointsInsideBBoxOfText2 = [ + {x: 295, y: 214}, + {x: 444, y: 222} +]; + +const pointsOnText3 = [ + {x: 198, y: 291}, + {x: 286, y: 301} +]; + +const pointsNotOnText3 = [ + {x: 302, y: 337}, + {x: 348, y: 335} +]; + +const pointsOnImage1 = [ + {x: 19, y: 215}, + {x: 45, y: 225} +]; + +function hitTest(point, element, shouldContain, optionalLabel) { + const label = optionalLabel || element.id; + test(() => { + const contain = element.contains(document.elementFromPoint(point.x, point.y)); + if (shouldContain) + assert_true(contain); + else + assert_false(contain); + }, `${label} ${shouldContain ? 'contains' : 'does not contain'} point at (${point.x}, ${point.y})`); +} + +pointsOnCircle1.forEach(point => hitTest(point, circle1, true)); +pointsNotOnCircle1.forEach(point => hitTest(point, circle1, false)); +pointsInsideBBoxOfCircle1.forEach(point => hitTest(point, group1, true, 'group1')); + +pointsOnCircle2.forEach(point => hitTest(point, circle2, true)); +pointsInsideBBoxOfCircle2.forEach(point => hitTest(point, circle2, true, 'bbox of circle2')); + +pointsOnText1.forEach(point => hitTest(point, text1, true)); +pointsOnTspan1.forEach(point => hitTest(point, tspan1, true)); +pointsNotOnText1.forEach(point => hitTest(point, text1, false)); +pointsInsideBBoxOfText1.forEach(point => hitTest(point, text1, true, 'bbox of text1')); + +pointsOnText2.forEach(point => hitTest(point, text2, true)); +pointsOnTspan2.forEach(point => hitTest(point, tspan2, true)); +pointsNotOnText2.forEach(point => hitTest(point, text2, false)); +pointsInsideBBoxOfText2.forEach(point => hitTest(point, text2, true, 'bbox of text2')); + +pointsOnText3.forEach(point => hitTest(point, text3, true)); +pointsNotOnText3.forEach(point => hitTest(point, text3, false)); + +pointsOnImage1.forEach(point => hitTest(point, image1, true)); +</script> diff --git a/testing/web-platform/tests/svg/interact/scripted/svg-small-big-path.html b/testing/web-platform/tests/svg/interact/scripted/svg-small-big-path.html new file mode 100644 index 0000000000..ba0e403f6d --- /dev/null +++ b/testing/web-platform/tests/svg/interact/scripted/svg-small-big-path.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<title>Hit-test on a path whose x/y ranges have different magnitude</title> +<link rel="help" href="https://svgwg.org/svg2-draft/interact.html#hit-testing"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> + svg { + margin: 0px; + padding: 0px; + position: absolute; + top: 0px; + left: 0px; + } +</style> +<svg> + <svg x="-250000" width="500000" height="500"> + <path id="path" d="M 250005 104 l 19 0 l 3 3 l -3 3 l -19 0 z"/> + </svg> +</svg> +<script> +const pointsInPath = [ + {x: 5, y: 104}, + {x: 5, y: 107}, + {x: 5, y: 110} +]; + +const pointsNotInPath = [ + {x: 5, y: 103}, + {x: 5, y: 111} +]; + +setup(() => { + window.pathElement = document.getElementById("path"); +}); + +pointsInPath.forEach(point => { + test(t => { + assert_equals(pathElement, document.elementFromPoint(point.x, point.y)); + }, `${document.title}, path contains point at (${point.x}, ${point.y})`); +}); + +pointsNotInPath.forEach(point => { + test(t => { + assert_not_equals(pathElement, document.elementFromPoint(point.x, point.y)); + }, `${document.title}, path does not contain point at (${point.x}, ${point.y})`); +}); +</script> diff --git a/testing/web-platform/tests/svg/interact/scripted/tabindex-focus-flag.svg b/testing/web-platform/tests/svg/interact/scripted/tabindex-focus-flag.svg new file mode 100644 index 0000000000..29ba209b2b --- /dev/null +++ b/testing/web-platform/tests/svg/interact/scripted/tabindex-focus-flag.svg @@ -0,0 +1,125 @@ +<?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/interact.html#Focus"/> + </metadata> + <g id="default-samples"> + <!-- non-default focusable renderable element --> + <rect></rect> + <svg></svg> + <!-- for compatibility with SVG Tiny 1.2 focusable attribute, user agents should treat an element with a value of true for that attribute as focusable --> + <rect focusable="true"></rect> + <!-- anchors need a href to be focusable --> + <a></a> + <a href=""></a> + <!-- Remove default focus behaviour with focusable="false" (SVG Tiny 1.2 compatibility) --> + <a href="" focusable="false"></a> + <!-- iframe, and audio/video with controls are default focusable --> + <h:iframe src="resources/blank.htm"></h:iframe> + <h:audio controls="controls"></h:audio> + <h:video controls="controls"></h:video> + <!-- non-default focusable renderable element with valid tabindex --> + <h:canvas tabindex="0"></h:canvas> + <circle tabindex="0"></circle> + <ellipse tabindex="0"></ellipse> + <foreignObject tabindex="0"></foreignObject> + <g tabindex="0"></g> + <image tabindex="0"></image> + <line tabindex="0"></line> + <mesh tabindex="0"></mesh> + <path tabindex="0"></path> + <polygon tabindex="0"></polygon> + <rect tabindex="0"></rect> + <svg tabindex="0"></svg> + <switch tabindex="0"></switch> + <text tabindex="0"> + <textPath tabindex="0"></textPath> + <tspan tabindex="0"></tspan> + </text> + <unknown tabindex="0"></unknown> + <use tabindex="0"></use> + <!-- never-rendered element with valid tabindex --> + <clipPath tabindex="0"></clipPath> + <defs tabindex="0"></defs> + <desc tabindex="0"></desc> + <hatch tabindex="0"></hatch> + <linearGradient tabindex="0"></linearGradient> + <marker tabindex="0"></marker> + <mask tabindex="0"></mask> + <meshgradient tabindex="0"></meshgradient> + <metadata tabindex="0"></metadata> + <pattern tabindex="0"></pattern> + <radialGradient tabindex="0"></radialGradient> + <script tabindex="0"></script> + <style tabindex="0"></style> + <title tabindex="0"></title> + <symbol tabindex="0"></symbol> + </g> + <h:script src="/resources/testharness.js"/> + <h:script src="/resources/testharnessreport.js"/> + <script><![CDATA[ + var root = document.querySelector("svg"); + + test(() => { + root.focus(); + assert_equals(document.activeElement, root); + }, 'The document root element should be focusable.'); + + const defaultList = [ + ['rect', false], + ['svg', false], + ['rect[focusable=true]', true], + ['a', false], + ['a[href]', true], + ['a[focusable=false]', false], + ['iframe', true], + ['audio[controls]', true], + ['video[controls]', true], + ['canvas[tabindex]', true], + ['circle[tabindex]', true], + ['ellipse[tabindex]', true], + ['foreignObject[tabindex]', true], + ['g[tabindex]', true], + ['image[tabindex]', true], + ['line[tabindex]', true], + ['mesh[tabindex]', true], + ['path[tabindex]', true], + ['polygon[tabindex]', true], + ['rect[tabindex]', true], + ['svg[tabindex]', true], + ['switch[tabindex]', true], + ['text[tabindex]', true], + ['textPath[tabindex]', true], + ['tspan[tabindex]', true], + ['unknown[tabindex]', true], + ['use[tabindex]', true], + ['clipPath[tabindex]', false], + ['defs[tabindex]', false], + ['desc[tabindex]', false], + ['hatch[tabindex]', false], + ['linearGradient[tabindex]', false], + ['marker[tabindex]', false], + ['mask[tabindex]', false], + ['meshgradient[tabindex]', false], + ['metadata[tabindex]', false], + ['pattern[tabindex]', false], + ['radialGradient[tabindex]', false], + ['script[tabindex]', false], + ['style[tabindex]', false], + ['title[tabindex]', false], + ['symbol[tabindex]', false], + ]; + + for (entry of defaultList) { + test(() => { + var element = document.querySelector('#default-samples ' + entry[0]); + element.focus(); + if (entry[1]) + assert_equals(document.activeElement, element); + else + assert_not_equals(document.activeElement, element); + }, entry[0] + ' should ' + (entry[1] ? '' : 'not ') + 'be focusable.'); + } + ]]></script> +</svg>
\ No newline at end of file |