diff options
Diffstat (limited to 'testing/web-platform/tests/html')
330 files changed, 11111 insertions, 1720 deletions
diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/disable_bfcache.js b/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/disable_bfcache.js new file mode 100644 index 0000000000..dea70ef4bd --- /dev/null +++ b/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/disable_bfcache.js @@ -0,0 +1,15 @@ +// Try to disable BFCache by acquiring and never releasing a Web Lock. +// This requires HTTPS. +// Note: This is a workaround depending on non-specified WebLock+BFCache +// behavior, and doesn't work on Safari. We might want to introduce a +// test-only BFCache-disabling API instead in the future. +// https://github.com/web-platform-tests/wpt/issues/16359#issuecomment-795004780 +// https://crbug.com/1298336 +window.disableBFCache = () => { + return new Promise(resolve => { + navigator.locks.request("disablebfcache", () => { + resolve(); + return new Promise(() => {}); + }); + }); +}; diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor-pushstate.html b/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor-pushstate.html index dcf4a798d0..3dd8f341f1 100644 --- a/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor-pushstate.html +++ b/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor-pushstate.html @@ -11,3 +11,4 @@ window.isLoadedFromPushState = true; </script> <script src="executor.js" type="module"></script> +<script src="disable_bfcache.js" type="module"></script> diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor.html b/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor.html index 2d118bbe2b..c3af5f6ba8 100644 --- a/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor.html +++ b/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor.html @@ -3,3 +3,4 @@ <script src="event-recorder.js" type="module"></script> <script src="worker-helper.js" type="module"></script> <script src="executor.js" type="module"></script> +<script src="disable_bfcache.js" type="module"></script> diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor.js b/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor.js index 67ce068130..5137616d85 100644 --- a/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor.js +++ b/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/executor.js @@ -45,20 +45,3 @@ window.prepareNavigation = function(callback) { {once: true}); executor.suspend(callback); } - -// Try to disable BFCache by acquiring and never releasing a Web Lock. -// This requires HTTPS. -// Note: This is a workaround depending on non-specified WebLock+BFCache -// behavior, and doesn't work on Safari. We might want to introduce a -// test-only BFCache-disabling API instead in the future. -// https://github.com/web-platform-tests/wpt/issues/16359#issuecomment-795004780 -// https://crbug.com/1298336 -window.disableBFCache = () => { - return new Promise(resolve => { - // Use page's UUID as a unique lock name. - navigator.locks.request(uuid, () => { - resolve(); - return new Promise(() => {}); - }); - }); -}; diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js b/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js index 80c164f560..ad2119b738 100644 --- a/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js +++ b/testing/web-platform/tests/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js @@ -41,13 +41,14 @@ function sorted(s) { return Array.from(s).sort(); } -// Assert expected reasons and the reported reasons match. +// Assert expected reasons are all present. Note that the extra reasons are allowed +// as UAs might block bfcache for their specific reasons. function matchReasons(expectedNotRestoredReasonsSet, notRestoredReasonsSet) { const missing = setMinus( expectedNotRestoredReasonsSet, notRestoredReasonsSet, 'Missing reasons'); const extra = setMinus( notRestoredReasonsSet, expectedNotRestoredReasonsSet, 'Extra reasons'); - assert_true(missing.size + extra.size == 0, `Expected: ${sorted(expectedNotRestoredReasonsSet)}\n` + + assert_true(missing.size == 0, `Expected: ${sorted(expectedNotRestoredReasonsSet)}\n` + `Got: ${sorted(notRestoredReasonsSet)}\n` + `Missing: ${sorted(missing)}\n` + `Extra: ${sorted(extra)}\n`); diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-cross-origin.sub.html b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-cross-origin.sub.html new file mode 100644 index 0000000000..4b68c32378 --- /dev/null +++ b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-cross-origin.sub.html @@ -0,0 +1,65 @@ +<!DOCTYPE HTML> +<title>Tests pageswap for cross-origin navigations</title> +<link rel="author" title="Khushal Sagar" href="mailto:khushalsagar@chromium.org"> +<link rel="help" href="https://html.spec.whatwg.org/"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<script> +const expectedUrl = get_host_info().HTTPS_REMOTE_ORIGIN + "/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-cross-origin.sub.html?new"; + +const params = new URLSearchParams(location.search); +// The page the popup navigates to. +const is_new_page = params.has('new'); +// The initial page in the popup. +const is_popup_page = params.has('popup'); +// The test page itself. +const is_test_page = !is_popup_page && !is_new_page; + +const channel = new BroadcastChannel("testchannel"); + +if (is_test_page) { + const expectedUrl = location.href + "?new"; + const expectedEvents = ["pageswap", "pagehide"]; + + promise_test(async t => { + let popup; + onload = () => { + window.events = []; + popup = window.open("?popup"); + }; + + await new Promise(resolve => { + channel.addEventListener( + "message", t.step_func(async (e) => { + if (e.data === "nav") { + assert_array_equals(window.events, expectedEvents, 'incorrect event order'); + popup.close(); + resolve(); + } + })); + }); + }, `pageswap on navigation from script`); +} else if (is_popup_page) { + onload = () => { + requestAnimationFrame(() => requestAnimationFrame(() => { + location.href = expectedUrl; + })); + + onpageswap = (e) => { + window.opener.events.push("pageswap"); + if (e.activation != null) + window.opener.events.push("activation"); + if (e.viewTransition != null) + window.opener.events.push("transition"); + }; + + onpagehide = () => { + window.opener.events.push("pagehide"); + channel.postMessage("nav"); + }; + }; +} +</script> diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-iframe.html b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-iframe.html new file mode 100644 index 0000000000..05ca1a9428 --- /dev/null +++ b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-iframe.html @@ -0,0 +1,45 @@ +<!DOCTYPE HTML> +<title>Tests pageswap dispatch on iframe Documents</title> +<link rel="author" title="Khushal Sagar" href="mailto:khushalsagar@chromium.org"> +<link rel="help" href="https://html.spec.whatwg.org/"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script> +setup({explicit_done: true}); + +function runTest(frame) { + let frameWindow = frame.contentWindow; + + let pageswapfired = false; + let expectedUrl = frameWindow.location.href + '?new'; + frameWindow.onpageswap = (e) => { + assert_equals(e.activation.entry.url, expectedUrl, 'activation url incorrect in pageswap'); + assert_equals(e.activation.navigationType, "push", 'navigation type incorrect in pageswap'); + assert_equals(e.activation.from, frameWindow.navigation.currentEntry, 'from entry incorrect in pageswap'); + assert_false(e.activation.entry.sameDocument, 'new entry must be cross-document'); + pageswapfired = true; + } + + frameWindow.onpagehide = (e) => { + assert_true(pageswapfired, 'pageswap not fired'); + done(); + } + + frame.src = expectedUrl; +} + +promise_test(async t => { + onload = () => { + let frame = document.createElement('iframe'); + frame.src = "/resources/blank.html"; + frame.onload = () => { + frame.contentWindow.requestAnimationFrame(() => { + runTest(frame); + }); + } + document.body.appendChild(frame); + }; +}); +</script> diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-initial-navigation.html b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-initial-navigation.html new file mode 100644 index 0000000000..5483b9394d --- /dev/null +++ b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-initial-navigation.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<title>Tests pageswap dispatch on initial doc navigation</title> +<link rel="author" title="Khushal Sagar" href="mailto:khushalsagar@chromium.org"> +<link rel="help" href="https://html.spec.whatwg.org/"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script> +setup({explicit_done: true}); + +function runTest(frame) { + let frameWindow = frame.contentWindow; + + let pageswapfired = false; + frameWindow.onpageswap = (e) => { + pageswapfired = true; + } + + frameWindow.onpagehide = (e) => { + assert_true(pageswapfired, 'pageswap fired'); + done(); + } + + frame.srcdoc = '<html></html>'; +} + +promise_test(async t => { + onload = () => { + let frame = document.createElement('iframe'); + document.body.appendChild(frame); + runTest(frame); + }; +}); +</script> diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-from-click.html b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-from-click.html new file mode 100644 index 0000000000..936158cd47 --- /dev/null +++ b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-from-click.html @@ -0,0 +1,74 @@ +<!DOCTYPE html> +<title>pageswap navigationactivation for push navigations from user click</title> +<link rel="help" href="https://html.spec.whatwg.org/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script> +const expectedUrl = location.href + '?new'; + +const params = new URLSearchParams(location.search); +// The page the popup navigates to. +const is_new_page = params.has('new'); +// The initial page in the popup. +const is_popup_page = params.has('popup'); +// The test page itself. +const is_test_page = !is_popup_page && !is_new_page; + +const channel = new BroadcastChannel("testchannel"); + +if (is_test_page) { + const expectedUrl = location.href + "?new"; + const expectedEvents = ["pageswap", expectedUrl, "push","from", "pagehide"]; + + promise_test(async t => { + let popup; + onload = () => { + document.getElementById('nav_link').remove(); + window.events = []; + popup = window.open("?popup"); + + popup.addEventListener("load", () => { + popup.requestAnimationFrame( + () => popup.requestAnimationFrame(() => { + let nav_link = popup.document.getElementById('nav_link'); + test_driver + .click(nav_link) + .catch(() => assert_unreached("click failed")); + })); + }); + }; + + await new Promise(resolve => { + channel.addEventListener( + "message", t.step_func(async (e) => { + if (e.data === "nav") { + assert_array_equals(window.events, expectedEvents, 'incorrect event order'); + popup.close(); + resolve(); + } + })); + }); + }, `pageswap on navigation from user click`); +} else if (is_popup_page) { + onpageswap = (e) => { + window.opener.events.push("pageswap"); + if (e.viewTransition != null) + window.opener.events.push("transition"); + window.opener.events.push(e.activation.entry.url); + window.opener.events.push(e.activation.navigationType); + if (e.activation.from == navigation.currentEntry) + window.opener.events.push("from"); + }; + + onpagehide = () => { + window.opener.events.push("pagehide"); + channel.postMessage("nav"); + }; +} +</script> +<body> + <a id="nav_link" href='/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-from-click.html?new'>Click me</a> + </body> diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-navigation-hidden-document.html b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-navigation-hidden-document.html new file mode 100644 index 0000000000..0a699232f0 --- /dev/null +++ b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-navigation-hidden-document.html @@ -0,0 +1,68 @@ +<!DOCTYPE html> +<title>Tests pageswap dispatch on hidden Documents</title> +<link rel="author" title="Khushal Sagar" href="mailto:khushalsagar@chromium.org"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script> +const expectedUrl = location.href + '?new'; + +const params = new URLSearchParams(location.search); +// The page the popup navigates to. +const is_new_page = params.has('new'); +// The initial page in the popup. +const is_popup_page = params.has('popup'); +// The test page itself. +const is_test_page = !is_popup_page && !is_new_page; + +const channel = new BroadcastChannel("testchannel"); + +if (is_test_page) { + const expectedUrl = location.href + "?new"; + const expectedEvents = ["pageswap", expectedUrl, "push","from", "pagehide"]; + + promise_test(async t => { + let popup; + onload = async () => { + window.events = []; + popup = window.open("?popup"); + }; + + await new Promise(resolve => { + channel.addEventListener( + "message", t.step_func(async (e) => { + if (e.data === "nav") { + assert_array_equals(window.events, expectedEvents, 'incorrect event order'); + popup.close(); + resolve(); + } + })); + }); + }, `pageswap on navigation from script`); +} else if (is_popup_page) { + onload = async () => { + await test_driver.minimize_window(); + assert_equals(document.visibilityState, "hidden"); + assert_equals(document.hidden, true); + + location.href = location.href.split('?')[0] + '?new'; + }; + + onpageswap = (e) => { + window.opener.events.push("pageswap"); + if (e.viewTransition != null) + window.opener.events.push("transition"); + window.opener.events.push(e.activation.entry.url); + window.opener.events.push(e.activation.navigationType); + if (e.activation.from == navigation.currentEntry) + window.opener.events.push("from"); + }; + + onpagehide = () => { + window.opener.events.push("pagehide"); + channel.postMessage("nav"); + }; + } +</script> diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-navigation.html b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-navigation.html new file mode 100644 index 0000000000..4542d7cae2 --- /dev/null +++ b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-navigation.html @@ -0,0 +1,64 @@ +<!DOCTYPE html> +<title>pageswap navigationactivation for push navigations</title> +<link rel="help" href="https://html.spec.whatwg.org/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +const expectedUrl = location.href + '?new'; + +const params = new URLSearchParams(location.search); +// The page the popup navigates to. +const is_new_page = params.has('new'); +// The initial page in the popup. +const is_popup_page = params.has('popup'); +// The test page itself. +const is_test_page = !is_popup_page && !is_new_page; + +const channel = new BroadcastChannel("testchannel"); + +if (is_test_page) { + const expectedUrl = location.href + "?new"; + const expectedEvents = ["pageswap", expectedUrl, "push","from", "pagehide"]; + + promise_test(async t => { + let popup; + onload = () => { + window.events = []; + popup = window.open("?popup"); + }; + + await new Promise(resolve => { + channel.addEventListener( + "message", t.step_func(async (e) => { + if (e.data === "nav") { + assert_array_equals(window.events, expectedEvents, 'incorrect event order'); + popup.close(); + resolve(); + } + })); + }); + }, `pageswap on navigation from script`); +} else if (is_popup_page) { + onload = () => { + requestAnimationFrame(() => requestAnimationFrame(() => { + location.href = location.href.split('?')[0] + '?new'; + })); + + onpageswap = (e) => { + window.opener.events.push("pageswap"); + if (e.viewTransition != null) + window.opener.events.push("transition"); + window.opener.events.push(e.activation.entry.url); + window.opener.events.push(e.activation.navigationType); + if (e.activation.from == navigation.currentEntry) + window.opener.events.push("from"); + }; + + onpagehide = () => { + window.opener.events.push("pagehide"); + channel.postMessage("nav"); + }; + }; +} +</script> diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-with-cross-origin-redirect.sub.html b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-with-cross-origin-redirect.sub.html new file mode 100644 index 0000000000..8ecf920b51 --- /dev/null +++ b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-with-cross-origin-redirect.sub.html @@ -0,0 +1,69 @@ +<!DOCTYPE html> +<title>pageswap navigationactivation for push navigations with a same-origin final url with cross-origin redirects</title> +<link rel="help" href="https://html.spec.whatwg.org/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<script> +const params = new URLSearchParams(location.search); +// The page the popup navigates to. +const is_new_page = params.has('new'); +// The initial page in the popup. +const is_popup_page = params.has('popup'); +// The test page itself. +const is_test_page = !is_popup_page && !is_new_page; + +const channel = new BroadcastChannel("testchannel"); + +if (is_test_page) { + const expectedUrl = location.href + "?new"; + const expectedEvents = ["pageswap", "pagehide", "pagereveal", "activation"]; + + promise_test(async t => { + let popup; + onload = () => { + window.events = []; + popup = window.open("?popup"); + }; + + await new Promise(resolve => { + channel.addEventListener( + "message", t.step_func(async (e) => { + if (e.data === "nav") { + assert_array_equals(window.events, expectedEvents, 'incorrect event order'); + popup.close(); + resolve(); + } + })); + }); + }, `pageswap on navigation with same-origin redirect`); +} else if (is_popup_page) { + onload = () => { + requestAnimationFrame(() => requestAnimationFrame(() => { + let newUrl = get_host_info().HTTPS_REMOTE_ORIGIN + "/common/redirect.py?location=" + location.href.split('?')[0] + "?new"; + location.href = newUrl + })); + + onpageswap = (e) => { + window.opener.events.push("pageswap"); + if (e.viewTransition != null) + window.opener.events.push("transition"); + if (e.activation != null) + window.opener.events.push("activation"); + }; + + onpagehide = () => { + window.opener.events.push("pagehide"); + }; + }; +} else { + assert_true(is_new_page); + onpageshow = () => { + window.opener.events.push("pagereveal"); + if (navigation.activation.from != null) + window.opener.events.push("activation"); + channel.postMessage("nav"); + } +} +</script> diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-with-redirect.html b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-with-redirect.html new file mode 100644 index 0000000000..8252fff84d --- /dev/null +++ b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-with-redirect.html @@ -0,0 +1,64 @@ +<!DOCTYPE html> +<title>pageswap navigationactivation for push navigations with a same-origin redirect</title> +<link rel="help" href="https://html.spec.whatwg.org/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +const expectedUrl = location.href + '?new'; + +const params = new URLSearchParams(location.search); +// The page the popup navigates to. +const is_new_page = params.has('new'); +// The initial page in the popup. +const is_popup_page = params.has('popup'); +// The test page itself. +const is_test_page = !is_popup_page && !is_new_page; + +const channel = new BroadcastChannel("testchannel"); + +if (is_test_page) { + const expectedUrl = location.href + "?new"; + const expectedEvents = ["pageswap", expectedUrl, "push","from", "pagehide"]; + + promise_test(async t => { + let popup; + onload = () => { + window.events = []; + popup = window.open("?popup"); + }; + + await new Promise(resolve => { + channel.addEventListener( + "message", t.step_func(async (e) => { + if (e.data === "nav") { + assert_array_equals(window.events, expectedEvents, 'incorrect event order'); + popup.close(); + resolve(); + } + })); + }); + }, `pageswap on navigation with same-origin redirect`); +} else if (is_popup_page) { + onload = () => { + requestAnimationFrame(() => requestAnimationFrame(() => { + location.href = "/common/redirect.py?location=/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-push-with-redirect.html?new"; + })); + + onpageswap = (e) => { + window.opener.events.push("pageswap"); + if (e.viewTransition != null) + window.opener.events.push("transition"); + window.opener.events.push(e.activation.entry.url); + window.opener.events.push(e.activation.navigationType); + if (e.activation.from == navigation.currentEntry) + window.opener.events.push("from"); + }; + + onpagehide = () => { + window.opener.events.push("pagehide"); + channel.postMessage("nav"); + }; + }; +} +</script> diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-reload-navigation.html b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-reload-navigation.html new file mode 100644 index 0000000000..f7539ebc47 --- /dev/null +++ b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-reload-navigation.html @@ -0,0 +1,65 @@ +<!DOCTYPE html> +<title>pageswap navigationactivation for replace navigations</title> +<link rel="help" href="https://html.spec.whatwg.org/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +const expectedUrl = location.href + '?new'; + +const params = new URLSearchParams(location.search); +// The initial page in the popup. +const is_popup_page = params.has('popup') && !window.opener.didreload; +// The test page itself. +const is_test_page = !params.has('popup'); + +const channel = new BroadcastChannel("testchannel"); + +if (is_test_page) { + const expectedUrl = location.href.split('?')[0] + "?popup"; + const expectedEvents = ["pageswap", "entry", "reload","from", "pagehide"]; + + promise_test(async t => { + let popup; + onload = () => { + window.events = []; + window.didreload = false; + popup = window.open("?popup"); + }; + + await new Promise(resolve => { + channel.addEventListener( + "message", t.step_func(async (e) => { + if (e.data === "nav") { + assert_array_equals(window.events, expectedEvents, 'incorrect event order'); + popup.close(); + resolve(); + } + })); + }); + }, `pageswap on replace navigation from script`); +} else if (is_popup_page) { + onload = () => { + requestAnimationFrame(() => requestAnimationFrame(() => { + window.opener.didreload = true; + location.reload(); + })); + + onpageswap = (e) => { + window.opener.events.push("pageswap"); + if (e.viewTransition != null) + window.opener.events.push("transition"); + if (e.activation.entry == navigation.currentEntry) + window.opener.events.push("entry"); + window.opener.events.push(e.activation.navigationType); + if (e.activation.from == navigation.currentEntry) + window.opener.events.push("from"); + }; + + onpagehide = () => { + window.opener.events.push("pagehide"); + channel.postMessage("nav"); + }; + }; +} +</script> diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-replace-navigation.html b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-replace-navigation.html new file mode 100644 index 0000000000..f6b3f7408c --- /dev/null +++ b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-replace-navigation.html @@ -0,0 +1,64 @@ +<!DOCTYPE html> +<title>pageswap navigationactivation for replace navigations</title> +<link rel="help" href="https://html.spec.whatwg.org/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +const expectedUrl = location.href + '?new'; + +const params = new URLSearchParams(location.search); +// The page the popup navigates to. +const is_new_page = params.has('new'); +// The initial page in the popup. +const is_popup_page = params.has('popup'); +// The test page itself. +const is_test_page = !is_popup_page && !is_new_page; + +const channel = new BroadcastChannel("testchannel"); + +if (is_test_page) { + const expectedUrl = location.href.split('?')[0] + "?new"; + const expectedEvents = ["pageswap", expectedUrl, "replace","from", "pagehide"]; + + promise_test(async t => { + let popup; + onload = () => { + window.events = []; + popup = window.open("?popup"); + }; + + await new Promise(resolve => { + channel.addEventListener( + "message", t.step_func(async (e) => { + if (e.data === "nav") { + assert_array_equals(window.events, expectedEvents, 'incorrect event order'); + popup.close(); + resolve(); + } + })); + }); + }, `pageswap on replace navigation from script`); +} else if (is_popup_page) { + onload = () => { + requestAnimationFrame(() => requestAnimationFrame(() => { + location.replace(location.href.split('?')[0] + '?new'); + })); + + onpageswap = (e) => { + window.opener.events.push("pageswap"); + if (e.viewTransition != null) + window.opener.events.push("transition"); + window.opener.events.push(e.activation.entry.url); + window.opener.events.push(e.activation.navigationType); + if (e.activation.from == navigation.currentEntry) + window.opener.events.push("from"); + }; + + onpagehide = () => { + window.opener.events.push("pagehide"); + channel.postMessage("nav"); + }; + }; +} +</script> diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-replace-with-cross-origin-redirect.sub.html b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-replace-with-cross-origin-redirect.sub.html new file mode 100644 index 0000000000..c6ced62057 --- /dev/null +++ b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-replace-with-cross-origin-redirect.sub.html @@ -0,0 +1,69 @@ +<!DOCTYPE html> +<title>pageswap navigationactivation for replace navigations with a same-origin final url with cross-origin redirects</title> +<link rel="help" href="https://html.spec.whatwg.org/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<script> +const params = new URLSearchParams(location.search); +// The page the popup navigates to. +const is_new_page = params.has('new'); +// The initial page in the popup. +const is_popup_page = params.has('popup'); +// The test page itself. +const is_test_page = !is_popup_page && !is_new_page; + +const channel = new BroadcastChannel("testchannel"); + +if (is_test_page) { + const expectedUrl = location.href + "?new"; + const expectedEvents = ["pageswap", "pagehide", "pagereveal", "activation"]; + + promise_test(async t => { + let popup; + onload = () => { + window.events = []; + popup = window.open("?popup"); + }; + + await new Promise(resolve => { + channel.addEventListener( + "message", t.step_func(async (e) => { + if (e.data === "nav") { + assert_array_equals(window.events, expectedEvents, 'incorrect event order'); + popup.close(); + resolve(); + } + })); + }); + }, `pageswap on navigation with same-origin redirect`); +} else if (is_popup_page) { + onload = () => { + requestAnimationFrame(() => requestAnimationFrame(() => { + let newUrl = get_host_info().HTTPS_REMOTE_ORIGIN + "/common/redirect.py?location=" + location.href.split('?')[0] + "?new"; + location.replace(newUrl); + })); + + onpageswap = (e) => { + window.opener.events.push("pageswap"); + if (e.viewTransition != null) + window.opener.events.push("transition"); + if (e.activation != null) + window.opener.events.push("activation"); + }; + + onpagehide = () => { + window.opener.events.push("pagehide"); + }; + }; +} else { + assert_true(is_new_page); + onpageshow = () => { + window.opener.events.push("pagereveal"); + if (navigation.activation.from != null) + window.opener.events.push("activation"); + channel.postMessage("nav"); + } +} +</script> diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-traverse-navigation-cross-origin-redirect-no-bfcache.https.sub.html b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-traverse-navigation-cross-origin-redirect-no-bfcache.https.sub.html new file mode 100644 index 0000000000..5543830721 --- /dev/null +++ b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-traverse-navigation-cross-origin-redirect-no-bfcache.https.sub.html @@ -0,0 +1,77 @@ +<!DOCTYPE html> +<title>pageswap navigationactivation for traverse navigation when original navigation has cross-origin redirect</title> +<link rel="help" href="https://html.spec.whatwg.org/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/common.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<script src="/html/browsers/browsing-the-web/back-forward-cache/resources/disable_bfcache.js"></script> +<style></style> +<script> +const channel = new BroadcastChannel("testchannel"); + +const params = new URLSearchParams(location.search); +const is_initial_page_first_navigation = params.has('popup') && navigation.entries().length == 1; +const is_new_page = params.has('new'); +const is_test_page = !params.has('popup') && !params.has('new'); + +// The test page which opens a popup for the navigation sequence. +if (is_test_page) { + const expectedUrl = location.href.split('?')[0] + "?popup"; + const expectedEvents = ["pageswap", expectedUrl, "traverse","from", "pagehide"]; + + promise_test(async t => { + let popup; + onload = () => { + window.events = []; + popup = window.open("?popup"); + }; + + await new Promise(resolve => { + channel.addEventListener( + "message", t.step_func(async (e) => { + if (e.data === "nav") { + assert_array_equals(window.events, expectedEvents, 'incorrect event order'); + popup.close(); + resolve(); + } + })); + }); + }, `pageswap on traverse navigation from script`); +} else if (is_initial_page_first_navigation) { + // The popup page which the user navigates back to. + onload = async () => { + await disableBFCache(); + requestAnimationFrame(() => requestAnimationFrame(() => { + let newUrl = get_host_info().HTTPS_REMOTE_ORIGIN + "/common/redirect.py?location=" + location.href.split('?')[0] + "?new"; + location.href = newUrl + })); + }; + + onpageshow = (e) => { + assert_false(e.persisted, 'the test should run without BFCache'); + } +} else if (is_new_page) { + onload = () => { + requestAnimationFrame(() => requestAnimationFrame(() => { + navigation.back(); + })); + }; + + onpageswap = (e) => { + window.opener.events.push("pageswap"); + if (e.viewTransition != null) + window.opener.events.push("transition"); + window.opener.events.push(e.activation.entry.url); + window.opener.events.push(e.activation.navigationType); + if (e.activation.from == navigation.currentEntry) + window.opener.events.push("from"); + }; + + onpagehide = () => { + window.opener.events.push("pagehide"); + channel.postMessage("nav"); + }; +} +</script> diff --git a/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-traverse-navigation-no-bfcache.https.html b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-traverse-navigation-no-bfcache.https.html new file mode 100644 index 0000000000..9e8c0e100e --- /dev/null +++ b/testing/web-platform/tests/html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-traverse-navigation-no-bfcache.https.html @@ -0,0 +1,75 @@ +<!DOCTYPE html> +<title>pageswap navigationactivation for traverse navigations</title> +<link rel="help" href="https://html.spec.whatwg.org/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/common.js"></script> +<script src="/html/browsers/browsing-the-web/back-forward-cache/resources/disable_bfcache.js"></script> +<style></style> +<script> +const channel = new BroadcastChannel("testchannel"); + +const params = new URLSearchParams(location.search); +const is_initial_page_first_navigation = params.has('popup') && navigation.entries().length == 1; +const is_new_page = params.has('new'); +const is_test_page = !params.has('popup') && !params.has('new'); + +// The test page which opens a popup for the navigation sequence. +if (is_test_page) { + const expectedUrl = location.href.split('?')[0] + "?popup"; + const expectedEvents = ["pageswap", expectedUrl, "traverse","from", "pagehide"]; + + promise_test(async t => { + let popup; + onload = () => { + window.events = []; + popup = window.open("?popup"); + }; + + await new Promise(resolve => { + channel.addEventListener( + "message", t.step_func(async (e) => { + if (e.data === "nav") { + assert_array_equals(window.events, expectedEvents, 'incorrect event order'); + popup.close(); + resolve(); + } + })); + }); + }, `pageswap on traverse navigation from script`); +} else if (is_initial_page_first_navigation) { + // The popup page which the user navigates back to. + onload = async () => { + await disableBFCache(); + requestAnimationFrame(() => requestAnimationFrame(() => { + location.href = location.href.split('?')[0] + '?new'; + })); + }; + + onpageshow = (e) => { + assert_false(e.persisted, 'the test should run without BFCache'); + } +} else if (is_new_page) { + onload = () => { + requestAnimationFrame(() => requestAnimationFrame(() => { + navigation.back(); + })); + }; + + onpageswap = (e) => { + window.opener.events.push("pageswap"); + if (e.viewTransition != null) + window.opener.events.push("transition"); + window.opener.events.push(e.activation.entry.url); + window.opener.events.push(e.activation.navigationType); + if (e.activation.from == navigation.currentEntry) + window.opener.events.push("from"); + }; + + onpagehide = () => { + window.opener.events.push("pagehide"); + channel.postMessage("nav"); + }; +} +</script> diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/history_reload_referrer-1.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_reload_referrer-1.html new file mode 100644 index 0000000000..d083a2a1d3 --- /dev/null +++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_reload_referrer-1.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html> + <head> + <title> + Ensure referrer header persists after + history.pushState/replaceState/fragment navigation and reload + </title> + </head> + <body> + <noscript><p>Enable JavaScript and reload</p></noscript> + <div id="log"></div> + <script type="text/javascript"> + location.href = "history_reload_referrer-2.html?pipe=sub"; + </script> + </body> +</html> diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/history_reload_referrer-2.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_reload_referrer-2.html new file mode 100644 index 0000000000..d85517a15f --- /dev/null +++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_reload_referrer-2.html @@ -0,0 +1,56 @@ +<!DOCTYPE html> +<html> + <head> + <title> + Ensure referrer header persists after + history.pushState/replaceState/fragment navigation and reload + </title> + </head> + <body> + <a id="fragment" href="#fragment">fragment</a> + <noscript><p>Enable JavaScript and reload</p></noscript> + <div id="log"></div> + <script type="text/javascript"> + const step = localStorage.getItem("history_reload_referrer_step") || "1"; + localStorage.setItem("history_reload_referrer_step", parseInt(step) + 1); + + var httpReferer = unescape("{{headers[referer]}}"); + var expectedReferrer = location.href.replace( + /\/[^\/]*$/, + "\/history_reload_referrer-1.html" + ); + + parent.test(function () { + parent.assert_equals(httpReferer, expectedReferrer); + }, `Step ${step}: Checking HTTP referrer (is "${httpReferer}")`); + parent.test(function () { + parent.assert_equals(document.referrer, expectedReferrer); + }, `Step ${step}: Checking document.referrer (is "${httpReferer}")`); + + switch (step) { + case "1": + history.pushState("", "", location); + location.reload(); + break; + + case "2": + history.replaceState("", "", location); + location.reload(); + break; + + case "3": + document.getElementById("fragment").click(); + location.reload(); + break; + + case "4": + localStorage.removeItem("history_reload_referrer_step"); + parent.done(); + break; + + default: + throw new Error(`Unexpected step "${step}"`); + } + </script> + </body> +</html> diff --git a/testing/web-platform/tests/html/browsers/history/the-history-interface/history_reload_referrer.html b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_reload_referrer.html new file mode 100644 index 0000000000..d11ee89702 --- /dev/null +++ b/testing/web-platform/tests/html/browsers/history/the-history-interface/history_reload_referrer.html @@ -0,0 +1,26 @@ +<!DOCTYPE html> +<html> + <head> + <title> + Ensure referrer header persists after + history.pushState/replaceState/fragment navigation and reload + </title> + <script type="text/javascript" src="/resources/testharness.js"></script> + <script + type="text/javascript" + src="/resources/testharnessreport.js" + ></script> + </head> + <body> + <noscript><p>Enable JavaScript and reload</p></noscript> + <div id="log"></div> + <script type="text/javascript"> + setup({ explicit_done: true }); + var iframe = document.createElement("iframe"); + window.onload = function () { + iframe.setAttribute("src", "history_reload_referrer-1.html"); + document.body.appendChild(iframe); + }; + </script> + </body> +</html> diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/assign-replace-from-iframe.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/assign-replace-from-iframe.html new file mode 100644 index 0000000000..a0cd9f25ef --- /dev/null +++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/assign-replace-from-iframe.html @@ -0,0 +1,31 @@ +<!DOCTYPE HTML> +<html> + <head> + <title>Referer with location.replace and location.assign</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + </head> + <body> + <iframe src="/resources/blank.html" hidden></iframe> + <script> + async_test(function(t) { + function on_message(e) { + const referrer = e.data; + assert_equals(referrer, window.location.href); + t.done(); + } + window.addEventListener('message', t.step_func(on_message), false); + document.querySelector("iframe").contentWindow.location.replace("resources/iframe-contents.sub.html?replace"); + }, "Browser sends Referer header in iframe request when location.replace is called from an iframe"); + async_test(function(t) { + function on_message(e) { + const referrer = e.data; + assert_equals(referrer, window.location.href); + t.done(); + } + window.addEventListener('message', t.step_func(on_message), false); + document.querySelector("iframe").contentWindow.location.assign("resources/iframe-contents.sub.html?assign"); + }, "Browser sends Referer header in iframe request when location.assign is called from an iframe"); + </script> + </body> +</html> diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/assign-replace-from-top-to-nested-iframe.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/assign-replace-from-top-to-nested-iframe.html new file mode 100644 index 0000000000..eb6e4960dc --- /dev/null +++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/assign-replace-from-top-to-nested-iframe.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML> +<html> + <head> + <title>Referer with location.replace and location.assign with nested iframes</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + </head> + <body> + <iframe src="resources/iframe-with-iframe.html" hidden></iframe> + <script> + const iframe = document.querySelector("iframe"); + async_test(function(t) { + function on_message(e) { + const referrer = e.data; + assert_equals(referrer, iframe.contentWindow.location.href); + t.done(); + } + window.addEventListener('message', t.step_func(on_message), false); + window.addEventListener('load', function () { + iframe.contentDocument.querySelector("iframe").contentWindow.location.replace("/resources/blank.html"); + }, false); + }, "Browser sends Referer header in nested iframe request when location.replace is called on an iframe"); + async_test(function(t) { + function on_message(e) { + const referrer = e.data; + assert_equals(referrer, iframe.contentWindow.location.href); + t.done(); + } + window.addEventListener('message', t.step_func(on_message), false); + window.addEventListener('load', function () { + iframe.contentDocument.querySelector("iframe").contentWindow.location.replace("/resources/blank.html"); + }, false); + }, "Browser sends Referer header in nested iframe request when location.assign is called on an iframe"); + </script> + </body> +</html> diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/assign-with-nested-iframe.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/assign-with-nested-iframe.html new file mode 100644 index 0000000000..e043623c08 --- /dev/null +++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/assign-with-nested-iframe.html @@ -0,0 +1,21 @@ +<!DOCTYPE HTML> +<html> + <head> + <title>Referer with location.assign and nested frames</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + </head> + <body> + <iframe src="resources/replace-or-assign-call-on-iframe.html?assign" hidden></iframe> + <script> + async_test(function(t) { + function on_message(e) { + const nestedIframeReferrer = e.data; + assert_equals(nestedIframeReferrer, document.querySelector("iframe").contentWindow.location.href); + t.done(); + } + window.addEventListener('message', t.step_func(on_message), false); + }, "Browser sends Referer header when location.assign is called in iframe document on another nested iframe element"); + </script> + </body> +</html> diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/replace-with-nested-iframe.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/replace-with-nested-iframe.html new file mode 100644 index 0000000000..e6620bd29c --- /dev/null +++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/replace-with-nested-iframe.html @@ -0,0 +1,21 @@ +<!DOCTYPE HTML> +<html> + <head> + <title>Referer with location.replace and nested frames</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + </head> + <body> + <iframe src="resources/replace-or-assign-call-on-iframe.html?replace" hidden></iframe> + <script> + async_test(function(t) { + function on_message(e) { + const nestedIframeReferrer = e.data; + assert_equals(nestedIframeReferrer, document.querySelector("iframe").contentWindow.location.href); + t.done(); + } + window.addEventListener('message', t.step_func(on_message), false); + }, "Browser sends Referer header when location.replace is called in iframe document on another nested iframe element"); + </script> + </body> +</html> diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/resources/iframe-contents.sub.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/resources/iframe-contents.sub.html new file mode 100644 index 0000000000..8ac0a264db --- /dev/null +++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/resources/iframe-contents.sub.html @@ -0,0 +1,14 @@ +<!DOCTYPE HTML> +<html> + <head> + <title>Resource file for test of Referer with location.replace</title> + </head> + <body> + <div></div> + <script> + const referer = "{{header_or_default(referer, missing)}}" + window.parent.postMessage(referer); + document.querySelector("div").textContent = `Referer header: ${referer}`; + </script> + </body> +</html> diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/resources/iframe-postmessage-to-parent-parent.sub.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/resources/iframe-postmessage-to-parent-parent.sub.html new file mode 100644 index 0000000000..25c4af19a3 --- /dev/null +++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/resources/iframe-postmessage-to-parent-parent.sub.html @@ -0,0 +1,14 @@ +<!DOCTYPE HTML> +<html> + <head> + <title>Resource file for test of Referer with location.replace</title> + </head> + <body> + <div></div> + <script> + const referer = "{{header_or_default(referer, missing)}}" + window.parent.parent.postMessage(referer); + document.querySelector("div").textContent = `Referer header: ${referer}`; + </script> + </body> +</html> diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/resources/iframe-with-iframe.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/resources/iframe-with-iframe.html new file mode 100644 index 0000000000..675f293ffa --- /dev/null +++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/resources/iframe-with-iframe.html @@ -0,0 +1,9 @@ +<!DOCTYPE HTML> +<html> + <head> + <title>Resource file for test of Referer with location.replace and location.assign</title> + </head> + <body> + <iframe src="iframe-postmessage-to-parent-parent.sub.html"></iframe> + </body> +</html> diff --git a/testing/web-platform/tests/html/browsers/history/the-location-interface/resources/replace-or-assign-call-on-iframe.html b/testing/web-platform/tests/html/browsers/history/the-location-interface/resources/replace-or-assign-call-on-iframe.html new file mode 100644 index 0000000000..bdad8334a5 --- /dev/null +++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/resources/replace-or-assign-call-on-iframe.html @@ -0,0 +1,20 @@ +<!DOCTYPE HTML> +<html> + <head> + <title>Referer with location.replace and location.assign</title> + </head> + <body> + <iframe src="/resources/blank.html" hidden></iframe> + <script> + window.addEventListener('message', function (e) { + const referrer = e.data; + window.parent.postMessage(referrer); + }); + if (window.location.search === "?replace") { + document.querySelector("iframe").contentWindow.location.replace("iframe-contents.sub.html?replace"); + } else if (window.location.search === "?assign") { + document.querySelector("iframe").contentWindow.location.assign("iframe-contents.sub.html?assign"); + } + </script> + </body> +</html> diff --git a/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.detachedcanvas.html b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.detachedcanvas.html new file mode 100644 index 0000000000..e301537330 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.detachedcanvas.html @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.drawImage.detachedcanvas</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> +<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css"> +<body class="show_output"> + +<h1>2d.drawImage.detachedcanvas</h1> +<p class="desc">drawImage with detached OffscreenCanvas as the source should throw exception</p> + + +<p class="output">Actual output:</p> +<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas> + +<ul id="d"></ul> +<script> +var t = async_test("drawImage with detached OffscreenCanvas as the source should throw exception"); +_addTest(function(canvas, ctx) { + + var canvas2 = new OffscreenCanvas(80, 80); + (new MessageChannel()).port1.postMessage(canvas2, [canvas2]); + assert_throws_dom("INVALID_STATE_ERR", function() { ctx.drawImage(canvas2, 0, 0); }); + +}); +</script> + diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.blur.exceptions.tentative.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.blur.exceptions.tentative.html index 42fb1ee8f8..dc94792867 100644 --- a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.blur.exceptions.tentative.html +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.blur.exceptions.tentative.html @@ -8,7 +8,7 @@ <body class="show_output"> <h1>2d.filter.canvasFilterObject.blur.exceptions.tentative</h1> -<p class="desc">Test exceptions on CanvasFilter() blur.object</p> +<p class="desc">Test exceptions on gaussianBlur filter</p> <p class="output">Actual output:</p> @@ -16,15 +16,21 @@ <ul id="d"></ul> <script> -var t = async_test("Test exceptions on CanvasFilter() blur.object"); +var t = async_test("Test exceptions on gaussianBlur filter"); _addTest(function(canvas, ctx) { - assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur'}); }); - assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: undefined}); }); - assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: 'foo'}); }); - assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: [1,2,3]}); }); - assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: NaN}); }); - assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: {}}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'gaussianBlur'}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'gaussianBlur', stdDeviation: undefined}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'gaussianBlur', stdDeviation: 'foo'}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'gaussianBlur', stdDeviation: [1,2,3]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'gaussianBlur', stdDeviation: NaN}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'gaussianBlur', stdDeviation: {}}); }); }); </script> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.colorMatrix.tentative.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.colorMatrix.tentative.html index b2f6a6ac97..56cf1bf0b1 100644 --- a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.colorMatrix.tentative.html +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.colorMatrix.tentative.html @@ -8,7 +8,7 @@ <body class="show_output"> <h1>2d.filter.canvasFilterObject.colorMatrix.tentative</h1> -<p class="desc">Test the functionality of ColorMatrix filters in CanvasFilter objects</p> +<p class="desc">Test the functionality of ColorMatrix filters</p> <p class="output">Actual output:</p> @@ -16,41 +16,70 @@ <ul id="d"></ul> <script> -var t = async_test("Test the functionality of ColorMatrix filters in CanvasFilter objects"); +var t = async_test("Test the functionality of ColorMatrix filters"); _addTest(function(canvas, ctx) { - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: undefined}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: 'foo'}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: null}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: [1, 2, 3]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 'a']}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, Infinity]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'colorMatrix', values: undefined}); }); + + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'colorMatrix', values: 'foo'}); }); + + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'colorMatrix', values: null}); }); + + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'colorMatrix', values: [1, 2, 3]}); }); + + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'colorMatrix', + values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 'a']}); }); + + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'colorMatrix', + values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, Infinity]}); }); + ctx.fillStyle = '#f00'; - ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 0}); + ctx.filter = new CanvasFilter( + {name: 'colorMatrix', type: 'hueRotate', values: 0}); ctx.fillRect(0, 0, 100, 50); _assertPixelApprox(canvas, 10,10, 255,0,0,255, 2); - ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 90}); + + ctx.filter = new CanvasFilter( + {name: 'colorMatrix', type: 'hueRotate', values: 90}); ctx.fillRect(0, 0, 100, 50); _assertPixelApprox(canvas, 10,10, 0,91,0,255, 2); - ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 180}); + + ctx.filter = new CanvasFilter( + {name: 'colorMatrix', type: 'hueRotate', values: 180}); ctx.fillRect(0, 0, 100, 50); _assertPixelApprox(canvas, 10,10, 0,109,109,255, 2); - ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 270}); + + ctx.filter = new CanvasFilter( + {name: 'colorMatrix', type: 'hueRotate', values: 270}); ctx.fillRect(0, 0, 100, 50); _assertPixelApprox(canvas, 10,10, 109,18,255,255, 2); - ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'saturate', values: 0.5}); + + ctx.filter = new CanvasFilter( + {name: 'colorMatrix', type: 'saturate', values: 0.5}); ctx.fillRect(0, 0, 100, 50); _assertPixelApprox(canvas, 10,10, 155,27,27,255, 2); + ctx.clearRect(0, 0, 100, 50); - ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'luminanceToAlpha'}); + ctx.filter = new CanvasFilter( + {name: 'colorMatrix', type: 'luminanceToAlpha'}); ctx.fillRect(0, 0, 100, 50); _assertPixelApprox(canvas, 10,10, 0,0,0,54, 2); - ctx.filter = new CanvasFilter({name: 'colorMatrix', values: [ - 0, 0, 0, 0, 0, - 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0 - ]}); + + ctx.filter = new CanvasFilter( + {name: 'colorMatrix', values: [ + 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0 + ]}); ctx.fillRect(0, 0, 50, 25); ctx.fillStyle = '#0f0'; ctx.fillRect(50, 0, 50, 25); diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative-expected.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative-expected.html new file mode 100644 index 0000000000..2b1c1c1c07 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative-expected.html @@ -0,0 +1,50 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.canvasFilterObject.componentTransfer.discrete.tentative</title> +<h1>2d.filter.canvasFilterObject.componentTransfer.discrete.tentative</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with discrete type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement + function getTransformedValue(C, V) { + // Get the right interval + const n = V.length; + const k = C == 1 ? n - 1 : Math.floor(C * n); + return V[k]; + } + + function getColor(inputColor, tableValues) { + const result = [0, 0, 0]; + for (const i in inputColor) { + const C = inputColor[i]/255; + const Cprime = getTransformedValue(C, tableValues[i]); + result[i] = Math.max(0, Math.min(1, Cprime)) * 255; + } + return result; + } + + tableValuesR = [0, 0, 1, 1]; + tableValuesG = [2, 0, 0.5, 3]; + tableValuesB = [1, -1, 5, 0]; + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + let outputColor = getColor( + color, [tableValuesR, tableValuesG, tableValuesB]); + ctx.fillStyle = `rgb(${outputColor[0]}, ${outputColor[1]}, + ${outputColor[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } +</script> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative.html index b392b189f2..0a4830568b 100644 --- a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative.html +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative.html @@ -1,41 +1,16 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.filter.canvasFilterObject.componentTransfer.discrete.tentative-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-500"> <title>Canvas test: 2d.filter.canvasFilterObject.componentTransfer.discrete.tentative</title> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/html/canvas/resources/canvas-tests.js"></script> -<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css"> -<body class="show_output"> - <h1>2d.filter.canvasFilterObject.componentTransfer.discrete.tentative</h1> <p class="desc">Test pixels on CanvasFilter() componentTransfer with discrete type</p> - - -<p class="output">Actual output:</p> -<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas> - -<ul id="d"></ul> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> <script> -var t = async_test("Test pixels on CanvasFilter() componentTransfer with discrete type"); -_addTest(function(canvas, ctx) { - - // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement - function getTransformedValue(C, V) { - // Get the right interval - const n = V.length; - const k = C == 1 ? n - 1 : Math.floor(C * n); - return V[k]; - } - - function getColor(inputColor, tableValues) { - const result = [0, 0, 0]; - for (const i in inputColor) { - const C = inputColor[i]/255; - const Cprime = getTransformedValue(C, tableValues[i]); - result[i] = Math.max(0, Math.min(1, Cprime)) * 255; - } - return result; - } + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); tableValuesR = [0, 0, 1, 1]; tableValuesG = [2, 0, 0.5, 3]; @@ -54,13 +29,9 @@ _addTest(function(canvas, ctx) { [50, 68, 87], ]; - for (const color of inputColors) { - let outputColor = getColor(color, [tableValuesR, tableValuesG, tableValuesB]); + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; - ctx.fillRect(0, 0, 10, 10); - _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2); + ctx.fillRect(i * 10, i * 10, 10, 10); } - -}); </script> - diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative-expected.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative-expected.html new file mode 100644 index 0000000000..5adc9f53e2 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative-expected.html @@ -0,0 +1,44 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.canvasFilterObject.componentTransfer.gamma.tentative</title> +<h1>2d.filter.canvasFilterObject.componentTransfer.gamma.tentative</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with gamma type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement + function getColor(inputColor, amplitude, exponent, offset) { + return [ + Math.max(0, Math.min(1, Math.pow(inputColor[0]/255, + exponent[0]) * amplitude[0] + offset[0])) * 255, + Math.max(0, Math.min(1, Math.pow(inputColor[1]/255, + exponent[1]) * amplitude[1] + offset[1])) * 255, + Math.max(0, Math.min(1, Math.pow(inputColor[2]/255, + exponent[2]) * amplitude[2] + offset[2])) * 255, + ]; + } + + const amplitudes = [2, 1.1, 0.5]; + const exponents = [5, 3, 1]; + const offsets = [0.25, 0, 0.5]; + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + let outputColor = getColor(color, amplitudes, exponents, offsets); + ctx.fillStyle = `rgb(${outputColor[0]}, ${outputColor[1]}, + ${outputColor[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } +</script> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative.html index e5bff7e44d..22e3abe624 100644 --- a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative.html +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative.html @@ -1,40 +1,27 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.filter.canvasFilterObject.componentTransfer.gamma.tentative-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-500"> <title>Canvas test: 2d.filter.canvasFilterObject.componentTransfer.gamma.tentative</title> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/html/canvas/resources/canvas-tests.js"></script> -<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css"> -<body class="show_output"> - <h1>2d.filter.canvasFilterObject.componentTransfer.gamma.tentative</h1> <p class="desc">Test pixels on CanvasFilter() componentTransfer with gamma type</p> - - -<p class="output">Actual output:</p> -<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas> - -<ul id="d"></ul> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> <script> -var t = async_test("Test pixels on CanvasFilter() componentTransfer with gamma type"); -_addTest(function(canvas, ctx) { - - // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement - function getColor(inputColor, amplitude, exponent, offset) { - return [ - Math.max(0, Math.min(1, Math.pow(inputColor[0]/255, exponent[0]) * amplitude[0] + offset[0])) * 255, - Math.max(0, Math.min(1, Math.pow(inputColor[1]/255, exponent[1]) * amplitude[1] + offset[1])) * 255, - Math.max(0, Math.min(1, Math.pow(inputColor[2]/255, exponent[2]) * amplitude[2] + offset[2])) * 255, - ]; - } + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); const amplitudes = [2, 1.1, 0.5]; const exponents = [5, 3, 1]; const offsets = [0.25, 0, 0.5]; ctx.filter = new CanvasFilter({name: 'componentTransfer', - funcR: {type: 'gamma', amplitude: amplitudes[0], exponent: exponents[0], offset: offsets[0]}, - funcG: {type: 'gamma', amplitude: amplitudes[1], exponent: exponents[1], offset: offsets[1]}, - funcB: {type: 'gamma', amplitude: amplitudes[2], exponent: exponents[2], offset: offsets[2]}, + funcR: {type: 'gamma', amplitude: amplitudes[0], + exponent: exponents[0], offset: offsets[0]}, + funcG: {type: 'gamma', amplitude: amplitudes[1], + exponent: exponents[1], offset: offsets[1]}, + funcB: {type: 'gamma', amplitude: amplitudes[2], + exponent: exponents[2], offset: offsets[2]}, }); const inputColors = [ @@ -45,13 +32,9 @@ _addTest(function(canvas, ctx) { [50, 68, 87], ]; - for (const color of inputColors) { - let outputColor = getColor(color, amplitudes, exponents, offsets); + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; - ctx.fillRect(0, 0, 10, 10); - _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2); + ctx.fillRect(i * 10, i * 10, 10, 10); } - -}); </script> - diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative-expected.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative-expected.html new file mode 100644 index 0000000000..895d531206 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative-expected.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.canvasFilterObject.componentTransfer.identity.tentative</title> +<h1>2d.filter.canvasFilterObject.componentTransfer.identity.tentative</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with identity type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + let outputColor = inputColors[i]; + ctx.fillStyle = `rgb(${outputColor[0]}, ${outputColor[1]}, + ${outputColor[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } +</script> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative.html index ecd3830be3..17761ce31a 100644 --- a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative.html +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative.html @@ -1,23 +1,15 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.filter.canvasFilterObject.componentTransfer.identity.tentative-expected.html"> <title>Canvas test: 2d.filter.canvasFilterObject.componentTransfer.identity.tentative</title> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/html/canvas/resources/canvas-tests.js"></script> -<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css"> -<body class="show_output"> - <h1>2d.filter.canvasFilterObject.componentTransfer.identity.tentative</h1> <p class="desc">Test pixels on CanvasFilter() componentTransfer with identity type</p> - - -<p class="output">Actual output:</p> -<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas> - -<ul id="d"></ul> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> <script> -var t = async_test("Test pixels on CanvasFilter() componentTransfer with identity type"); -_addTest(function(canvas, ctx) { + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); ctx.filter = new CanvasFilter({name: 'componentTransfer', funcR: {type: 'identity'}, @@ -33,12 +25,9 @@ _addTest(function(canvas, ctx) { [50, 68, 87], ]; - for (const color of inputColors) { - ctx.fillStyle = `rgba(${color[0]}, ${color[1]}, ${color[2]}, 1)`, - ctx.fillRect(0, 0, 10, 10); - _assertPixel(canvas, 5, 5, color[0],color[1],color[2],255); + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); } - -}); </script> - diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative-expected.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative-expected.html new file mode 100644 index 0000000000..c4ad790d56 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative-expected.html @@ -0,0 +1,43 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.canvasFilterObject.componentTransfer.linear.tentative</title> +<h1>2d.filter.canvasFilterObject.componentTransfer.linear.tentative</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with linear type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement + function getColor(inputColor, slopes, intercepts) { + return [ + Math.max(0, Math.min(1, + inputColor[0]/255 * slopes[0] + intercepts[0])) * 255, + Math.max(0, Math.min(1, + inputColor[1]/255 * slopes[1] + intercepts[1])) * 255, + Math.max(0, Math.min(1, + inputColor[2]/255 * slopes[2] + intercepts[2])) * 255, + ]; + } + + const slopes = [0.5, 1.2, -0.2]; + const intercepts = [0.25, 0, 0.5]; + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + let outputColor = getColor(color, slopes, intercepts); + ctx.fillStyle = `rgb(${outputColor[0]}, ${outputColor[1]}, + ${outputColor[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } +</script> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative.html index 8708887f6a..5ea5f8e0e3 100644 --- a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative.html +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative.html @@ -1,32 +1,16 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.filter.canvasFilterObject.componentTransfer.linear.tentative-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-500"> <title>Canvas test: 2d.filter.canvasFilterObject.componentTransfer.linear.tentative</title> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/html/canvas/resources/canvas-tests.js"></script> -<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css"> -<body class="show_output"> - <h1>2d.filter.canvasFilterObject.componentTransfer.linear.tentative</h1> <p class="desc">Test pixels on CanvasFilter() componentTransfer with linear type</p> - - -<p class="output">Actual output:</p> -<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas> - -<ul id="d"></ul> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> <script> -var t = async_test("Test pixels on CanvasFilter() componentTransfer with linear type"); -_addTest(function(canvas, ctx) { - - // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement - function getColor(inputColor, slopes, intercepts) { - return [ - Math.max(0, Math.min(1, inputColor[0]/255 * slopes[0] + intercepts[0])) * 255, - Math.max(0, Math.min(1, inputColor[1]/255 * slopes[1] + intercepts[1])) * 255, - Math.max(0, Math.min(1, inputColor[2]/255 * slopes[2] + intercepts[2])) * 255, - ]; - } + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); const slopes = [0.5, 1.2, -0.2]; const intercepts = [0.25, 0, 0.5]; @@ -44,13 +28,9 @@ _addTest(function(canvas, ctx) { [50, 68, 87], ]; - for (const color of inputColors) { - let outputColor = getColor(color, slopes, intercepts); + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; - ctx.fillRect(0, 0, 10, 10); - _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2); + ctx.fillRect(i * 10, i * 10, 10, 10); } - -}); </script> - diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative-expected.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative-expected.html new file mode 100644 index 0000000000..29e250614c --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative-expected.html @@ -0,0 +1,51 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.canvasFilterObject.componentTransfer.table.tentative</title> +<h1>2d.filter.canvasFilterObject.componentTransfer.table.tentative</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with table type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement + function getTransformedValue(C, V) { + // Get the right interval + const n = V.length - 1; + const k = C == 1 ? n - 1 : Math.floor(C * n); + return V[k] + (C - k/n) * n * (V[k + 1] - V[k]); + } + + function getColor(inputColor, tableValues) { + const result = [0, 0, 0]; + for (const i in inputColor) { + const C = inputColor[i]/255; + const Cprime = getTransformedValue(C, tableValues[i]); + result[i] = Math.max(0, Math.min(1, Cprime)) * 255; + } + return result; + } + + tableValuesR = [0, 0, 1, 1]; + tableValuesG = [2, 0, 0.5, 3]; + tableValuesB = [1, -1, 5, 0]; + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + let outputColor = getColor( + color, [tableValuesR, tableValuesG, tableValuesB]); + ctx.fillStyle = `rgb(${outputColor[0]}, ${outputColor[1]}, + ${outputColor[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } +</script> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative.html index 4b296d9fd7..0f74d9c3bf 100644 --- a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative.html +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative.html @@ -1,41 +1,16 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.filter.canvasFilterObject.componentTransfer.table.tentative-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-500"> <title>Canvas test: 2d.filter.canvasFilterObject.componentTransfer.table.tentative</title> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/html/canvas/resources/canvas-tests.js"></script> -<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css"> -<body class="show_output"> - <h1>2d.filter.canvasFilterObject.componentTransfer.table.tentative</h1> <p class="desc">Test pixels on CanvasFilter() componentTransfer with table type</p> - - -<p class="output">Actual output:</p> -<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas> - -<ul id="d"></ul> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> <script> -var t = async_test("Test pixels on CanvasFilter() componentTransfer with table type"); -_addTest(function(canvas, ctx) { - - // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement - function getTransformedValue(C, V) { - // Get the right interval - const n = V.length - 1; - const k = C == 1 ? n - 1 : Math.floor(C * n); - return V[k] + (C - k/n) * n * (V[k + 1] - V[k]); - } - - function getColor(inputColor, tableValues) { - const result = [0, 0, 0]; - for (const i in inputColor) { - const C = inputColor[i]/255; - const Cprime = getTransformedValue(C, tableValues[i]); - result[i] = Math.max(0, Math.min(1, Cprime)) * 255; - } - return result; - } + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); tableValuesR = [0, 0, 1, 1]; tableValuesG = [2, 0, 0.5, 3]; @@ -54,13 +29,9 @@ _addTest(function(canvas, ctx) { [50, 68, 87], ]; - for (const color of inputColors) { - let outputColor = getColor(color, [tableValuesR, tableValuesG, tableValuesB]); + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; - ctx.fillRect(0, 0, 10, 10); - _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2); + ctx.fillRect(i * 10, i * 10, 10, 10); } - -}); </script> - diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative.html index b80600c141..a288541057 100644 --- a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative.html +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative.html @@ -19,23 +19,39 @@ var t = async_test("Test exceptions on CanvasFilter() convolveMatrix"); _addTest(function(canvas, ctx) { - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix'}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', divisor: 2}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: null}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: 1}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 0], [0]]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 'a'], [0]]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 0], 0]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 0], [0, Infinity]]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: []}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [1]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [1, 2, 3, 4]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[], []]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 2], []]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[], [1, 2]]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix'}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', divisor: 2}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: null}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: 1}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [[1, 0], [0]]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [[1, 'a'], [0]]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [[1, 0], 0]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [[1, 0], [0, Infinity]]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: []}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [1]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [1, 2, 3, 4]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [[], []]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [[1, 2], []]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [[], [1, 2]]}); }); // This should not throw an error - ctx.filter = new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[]]}); - ctx.filter = new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1]]}); + ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [[]]}); + ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [[1]]}); }); </script> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.exceptions.tentative.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.exceptions.tentative.html index 8c07a72b2b..05984a47f8 100644 --- a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.exceptions.tentative.html +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.exceptions.tentative.html @@ -19,104 +19,250 @@ var t = async_test("Test exceptions on CanvasFilter() dropShadow object"); _addTest(function(canvas, ctx) { + // Should not throw an error. // dx - _assert(new CanvasFilter({name: 'dropShadow', dx: 10}), "new CanvasFilter({name: 'dropShadow', dx: 10})"); - _assert(new CanvasFilter({name: 'dropShadow', dx: -1}), "new CanvasFilter({name: 'dropShadow', dx: -1})"); - _assert(new CanvasFilter({name: 'dropShadow', dx: 0.5}), "new CanvasFilter({name: 'dropShadow', dx: 0.5})"); - _assert(new CanvasFilter({name: 'dropShadow', dx: null}), "new CanvasFilter({name: 'dropShadow', dx: null})"); - _assert(new CanvasFilter({name: 'dropShadow', dx: true}), "new CanvasFilter({name: 'dropShadow', dx: true})"); - _assert(new CanvasFilter({name: 'dropShadow', dx: false}), "new CanvasFilter({name: 'dropShadow', dx: false})"); - _assert(new CanvasFilter({name: 'dropShadow', dx: []}), "new CanvasFilter({name: 'dropShadow', dx: []})"); - _assert(new CanvasFilter({name: 'dropShadow', dx: [20]}), "new CanvasFilter({name: 'dropShadow', dx: [\""+(20)+"\"]})"); - _assert(new CanvasFilter({name: 'dropShadow', dx: '30'}), "new CanvasFilter({name: 'dropShadow', dx: '30'})"); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: 10}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: -1}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: 0.5}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: null}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: true}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: false}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: []}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: [20]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: '30'}); // dy - _assert(new CanvasFilter({name: 'dropShadow', dy: 10}), "new CanvasFilter({name: 'dropShadow', dy: 10})"); - _assert(new CanvasFilter({name: 'dropShadow', dy: -1}), "new CanvasFilter({name: 'dropShadow', dy: -1})"); - _assert(new CanvasFilter({name: 'dropShadow', dy: 0.5}), "new CanvasFilter({name: 'dropShadow', dy: 0.5})"); - _assert(new CanvasFilter({name: 'dropShadow', dy: null}), "new CanvasFilter({name: 'dropShadow', dy: null})"); - _assert(new CanvasFilter({name: 'dropShadow', dy: true}), "new CanvasFilter({name: 'dropShadow', dy: true})"); - _assert(new CanvasFilter({name: 'dropShadow', dy: false}), "new CanvasFilter({name: 'dropShadow', dy: false})"); - _assert(new CanvasFilter({name: 'dropShadow', dy: []}), "new CanvasFilter({name: 'dropShadow', dy: []})"); - _assert(new CanvasFilter({name: 'dropShadow', dy: [20]}), "new CanvasFilter({name: 'dropShadow', dy: [\""+(20)+"\"]})"); - _assert(new CanvasFilter({name: 'dropShadow', dy: '30'}), "new CanvasFilter({name: 'dropShadow', dy: '30'})"); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: 10}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: -1}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: 0.5}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: null}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: true}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: false}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: []}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: [20]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: '30'}); // floodOpacity - _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: 10}), "new CanvasFilter({name: 'dropShadow', floodOpacity: 10})"); - _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: -1}), "new CanvasFilter({name: 'dropShadow', floodOpacity: -1})"); - _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: 0.5}), "new CanvasFilter({name: 'dropShadow', floodOpacity: 0.5})"); - _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: null}), "new CanvasFilter({name: 'dropShadow', floodOpacity: null})"); - _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: true}), "new CanvasFilter({name: 'dropShadow', floodOpacity: true})"); - _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: false}), "new CanvasFilter({name: 'dropShadow', floodOpacity: false})"); - _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: []}), "new CanvasFilter({name: 'dropShadow', floodOpacity: []})"); - _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: [20]}), "new CanvasFilter({name: 'dropShadow', floodOpacity: [\""+(20)+"\"]})"); - _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: '30'}), "new CanvasFilter({name: 'dropShadow', floodOpacity: '30'})"); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: 10}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: -1}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: 0.5}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: null}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: true}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: false}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: []}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: [20]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: '30'}); + // dx + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: 10}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: -1}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: 0.5}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: null}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: true}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: false}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: []}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: [20]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: '30'}); + // dy + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: 10}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: -1}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: 0.5}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: null}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: true}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: false}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: []}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: [20]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: '30'}); + // floodOpacity + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: 10}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: -1}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: 0.5}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: null}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: true}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: false}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: []}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: [20]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: '30'}); // stdDeviation - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: 10}), "new CanvasFilter({name: 'dropShadow', stdDeviation: 10})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: -1}), "new CanvasFilter({name: 'dropShadow', stdDeviation: -1})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: 0.5}), "new CanvasFilter({name: 'dropShadow', stdDeviation: 0.5})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: null}), "new CanvasFilter({name: 'dropShadow', stdDeviation: null})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: true}), "new CanvasFilter({name: 'dropShadow', stdDeviation: true})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: false}), "new CanvasFilter({name: 'dropShadow', stdDeviation: false})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: []}), "new CanvasFilter({name: 'dropShadow', stdDeviation: []})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: [20]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: [\""+(20)+"\"]})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: '30'}), "new CanvasFilter({name: 'dropShadow', stdDeviation: '30'})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: [10, -1]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: [10, -1]})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: [0.5, null]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: [0.5, null]})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: [true, false]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: [true, false]})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: [[], [20]]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: [[], [\""+(20)+"\"]]})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: ['30', ['40']]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: ['30', ['40']]})"); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: 10}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: -1}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: 0.5}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: null}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: true}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: false}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: []}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [20]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: '30'}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [10, -1]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [0.5, null]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [true, false]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [[], [20]]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: ['30', ['40']]}); // floodColor - _assert(new CanvasFilter({name: 'dropShadow', floodColor: 'red'}), "new CanvasFilter({name: 'dropShadow', floodColor: 'red'})"); - _assert(new CanvasFilter({name: 'dropShadow', floodColor: 'canvas'}), "new CanvasFilter({name: 'dropShadow', floodColor: 'canvas'})"); - _assert(new CanvasFilter({name: 'dropShadow', floodColor: 'rgba(4, -3, 0.5, 1)'}), "new CanvasFilter({name: 'dropShadow', floodColor: 'rgba(4, -3, 0.5, 1)'})"); - _assert(new CanvasFilter({name: 'dropShadow', floodColor: '#aabbccdd'}), "new CanvasFilter({name: 'dropShadow', floodColor: '#aabbccdd'})"); - _assert(new CanvasFilter({name: 'dropShadow', floodColor: '#abcd'}), "new CanvasFilter({name: 'dropShadow', floodColor: '#abcd'})"); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: 'red'}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: 'canvas'}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: 'rgba(4, -3, 0.5, 1)'}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: '#aabbccdd'}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: '#abcd'}); + // Should throw a TypeError. // dx - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: NaN}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: Infinity}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: -Infinity}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: undefined}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: 'test'}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: {}}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: [1, 2]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: NaN}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: Infinity}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: -Infinity}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: undefined}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: 'test'}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: {}}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: [1, 2]}); }); // dy - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: NaN}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: Infinity}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: -Infinity}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: undefined}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: 'test'}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: {}}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: [1, 2]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: NaN}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: Infinity}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: -Infinity}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: undefined}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: 'test'}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: {}}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: [1, 2]}); }); // floodOpacity - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: NaN}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: Infinity}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: -Infinity}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: undefined}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: 'test'}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: {}}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: [1, 2]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: NaN}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: Infinity}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: -Infinity}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: undefined}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: 'test'}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: {}}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: [1, 2]}); }); // stdDeviation - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: NaN}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: Infinity}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: -Infinity}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: undefined}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: 'test'}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: {}}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, 2, 3]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, NaN]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, Infinity]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, -Infinity]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, undefined]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, 'test']}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, {}]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, [2, 3]]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: NaN}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: Infinity}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: -Infinity}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: undefined}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: 'test'}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: {}}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [1, 2, 3]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [1, NaN]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [1, Infinity]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [1, -Infinity]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [1, undefined]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [1, 'test']}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [1, {}]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [1, [2, 3]]}); }); // floodColor - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: 'test'}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: 'rgba(NaN, 3, 2, 1)'}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: 10}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: undefined}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: null}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: NaN}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: 'test'}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: 'rgba(NaN, 3, 2, 1)'}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: 10}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: undefined}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: null}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: NaN}); }); }); </script> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.tentative.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.tentative.html index 47bb891b3f..d6e7066473 100644 --- a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.tentative.html +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.tentative.html @@ -22,86 +22,58 @@ // Parameter defaults. ctx.filter = new CanvasFilter({name: 'dropShadow'}); ctx.fillRect(10, 10, 80, 80); - // All parameters specified. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5, floodColor: 'purple', floodOpacity: 0.7}); ctx.fillRect(110, 10, 80, 80); - // Named color. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, floodColor: 'purple'}); ctx.fillRect(10, 110, 80, 80); - // System color. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, floodColor: 'LinkText'}); ctx.fillRect(110, 110, 80, 80); - // Numerical color. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, floodColor: 'rgba(20, 50, 130, 1)'}); ctx.fillRect(210, 110, 80, 80); - // Transparent floodColor. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, floodColor: 'rgba(20, 50, 130, 0.7)'}); ctx.fillRect(310, 110, 80, 80); - // Transparent floodColor and floodOpacity. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, floodColor: 'rgba(20, 50, 130, 0.7)', floodOpacity: 0.7}); ctx.fillRect(410, 110, 80, 80); - // No blur. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 0, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 0, floodColor: 'purple'}); ctx.fillRect(10, 210, 80, 80); - // Single float blur. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5, floodColor: 'purple'}); ctx.fillRect(110, 210, 80, 80); - // Single negative float blur. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: -5, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: -5, floodColor: 'purple'}); ctx.fillRect(210, 210, 80, 80); - // Two floats (X&Y) blur. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: [3, 5], + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: [3, 5], floodColor: 'purple'}); ctx.fillRect(310, 210, 80, 80); - // Two negative floats (X&Y) blur. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: [-3, -5], + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: [-3, -5], floodColor: 'purple'}); ctx.fillRect(410, 210, 80, 80); - // Degenerate parameter values. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: [-5], dy: [], stdDeviation: null, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: [-5], dy: [], stdDeviation: null, floodColor: 'purple', floodOpacity: [2]}); ctx.fillRect(10, 310, 80, 80); - - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: null, dy: '5', stdDeviation: [[-5], ['3']], + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: null, dy: '5', stdDeviation: [[-5], ['3']], floodColor: 'purple', floodOpacity: '0.8'}); ctx.fillRect(110, 310, 80, 80); - - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: true, dy: ['10'], stdDeviation: false, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: true, dy: ['10'], stdDeviation: false, floodColor: 'purple', floodOpacity: ['0.4']}); ctx.fillRect(210, 310, 80, 80); </script> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic-expected.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.isotropic.tentative-expected.html index f9571f208e..dac31c97f1 100644 --- a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic-expected.html +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.isotropic.tentative-expected.html @@ -1,7 +1,7 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> -<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic</title> -<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic</h1> +<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.isotropic.tentative</title> +<h1>2d.filter.canvasFilterObject.gaussianBlur.isotropic.tentative</h1> <p class="desc">Test CanvasFilter() with gaussianBlur.</p> <svg xmlns="http://www.w3.org/2000/svg" diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.isotropic.tentative.html index 6376d07b0e..f4c8c1033a 100644 --- a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic.html +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.isotropic.tentative.html @@ -1,8 +1,8 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> -<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic-expected.html"> -<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic</title> -<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic</h1> +<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.isotropic.tentative-expected.html"> +<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.isotropic.tentative</title> +<h1>2d.filter.canvasFilterObject.gaussianBlur.isotropic.tentative</h1> <p class="desc">Test CanvasFilter() with gaussianBlur.</p> <canvas id="canvas" width="100" height="100"> <p class="fallback">FAIL (fallback content)</p> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x-expected.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.mostly-x.tentative-expected.html index e76613271f..88d0cb2de2 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x-expected.html +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.mostly-x.tentative-expected.html @@ -1,7 +1,7 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> -<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x</title> -<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x</h1> +<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.mostly-x.tentative</title> +<h1>2d.filter.canvasFilterObject.gaussianBlur.mostly-x.tentative</h1> <p class="desc">Test CanvasFilter() with gaussianBlur.</p> <svg xmlns="http://www.w3.org/2000/svg" diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.mostly-x.tentative.html index 145cb32757..b3efcb8c3e 100644 --- a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x.html +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.mostly-x.tentative.html @@ -1,8 +1,8 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> -<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x-expected.html"> -<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x</title> -<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x</h1> +<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.mostly-x.tentative-expected.html"> +<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.mostly-x.tentative</title> +<h1>2d.filter.canvasFilterObject.gaussianBlur.mostly-x.tentative</h1> <p class="desc">Test CanvasFilter() with gaussianBlur.</p> <canvas id="canvas" width="100" height="100"> <p class="fallback">FAIL (fallback content)</p> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y-expected.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.mostly-y.tentative-expected.html index 0f214fca9f..744983d4ae 100644 --- a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y-expected.html +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.mostly-y.tentative-expected.html @@ -1,7 +1,7 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> -<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y</title> -<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y</h1> +<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.mostly-y.tentative</title> +<h1>2d.filter.canvasFilterObject.gaussianBlur.mostly-y.tentative</h1> <p class="desc">Test CanvasFilter() with gaussianBlur.</p> <svg xmlns="http://www.w3.org/2000/svg" diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.mostly-y.tentative.html index e921e0eaa6..d5cc6e0058 100644 --- a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y.html +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.mostly-y.tentative.html @@ -1,8 +1,8 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> -<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y-expected.html"> -<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y</title> -<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y</h1> +<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.mostly-y.tentative-expected.html"> +<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.mostly-y.tentative</title> +<h1>2d.filter.canvasFilterObject.gaussianBlur.mostly-y.tentative</h1> <p class="desc">Test CanvasFilter() with gaussianBlur.</p> <canvas id="canvas" width="100" height="100"> <p class="fallback">FAIL (fallback content)</p> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only-expected.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.x-only.tentative-expected.html index 285a641726..e611113e42 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only-expected.html +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.x-only.tentative-expected.html @@ -1,7 +1,7 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> -<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only</title> -<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only</h1> +<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.x-only.tentative</title> +<h1>2d.filter.canvasFilterObject.gaussianBlur.x-only.tentative</h1> <p class="desc">Test CanvasFilter() with gaussianBlur.</p> <svg xmlns="http://www.w3.org/2000/svg" diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.x-only.tentative.html index fd6ac687f9..4e8576fe74 100644 --- a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only.html +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.x-only.tentative.html @@ -1,8 +1,8 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> -<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only-expected.html"> -<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only</title> -<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only</h1> +<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.x-only.tentative-expected.html"> +<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.x-only.tentative</title> +<h1>2d.filter.canvasFilterObject.gaussianBlur.x-only.tentative</h1> <p class="desc">Test CanvasFilter() with gaussianBlur.</p> <canvas id="canvas" width="100" height="100"> <p class="fallback">FAIL (fallback content)</p> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only-expected.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.y-only.tentative-expected.html index d59945b5da..c6d915cb07 100644 --- a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only-expected.html +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.y-only.tentative-expected.html @@ -1,7 +1,7 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> -<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only</title> -<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only</h1> +<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.y-only.tentative</title> +<h1>2d.filter.canvasFilterObject.gaussianBlur.y-only.tentative</h1> <p class="desc">Test CanvasFilter() with gaussianBlur.</p> <svg xmlns="http://www.w3.org/2000/svg" diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.y-only.tentative.html index 6442433e7c..ec0a2353cf 100644 --- a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only.html +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.y-only.tentative.html @@ -1,8 +1,8 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> -<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only-expected.html"> -<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only</title> -<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only</h1> +<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.y-only.tentative-expected.html"> +<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.y-only.tentative</title> +<h1>2d.filter.canvasFilterObject.gaussianBlur.y-only.tentative</h1> <p class="desc">Test CanvasFilter() with gaussianBlur.</p> <canvas id="canvas" width="100" height="100"> <p class="fallback">FAIL (fallback content)</p> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.turbulence.inputTypes.tentative.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.turbulence.inputTypes.tentative.html index c24cfd2398..b85add4b66 100644 --- a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.turbulence.inputTypes.tentative.html +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.turbulence.inputTypes.tentative.html @@ -116,12 +116,12 @@ _addTest(function(canvas, ctx) { for (testCase of errorTestCases) { const filterOptions = {...{name: 'turbulence'}, ...testCase}; - assert_throws_js(TypeError, function() { new CanvasFilter(filterOptions); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter(filterOptions); }); } for (testCase of workingTestCases) { const filterOptions = {...{name: 'turbulence'}, ...testCase}; - _assert(new CanvasFilter(filterOptions) != null, "new CanvasFilter(filterOptions) != null"); + ctx.filter = new CanvasFilter(filterOptions); } }); diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.blur.exceptions.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.blur.exceptions.html new file mode 100644 index 0000000000..7176a7d0a4 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.blur.exceptions.html @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.layers.blur.exceptions</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> +<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css"> +<body class="show_output"> + +<h1>2d.filter.layers.blur.exceptions</h1> +<p class="desc">Test exceptions on gaussianBlur filter</p> + + +<p class="output">Actual output:</p> +<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas> + +<ul id="d"></ul> +<script> +var t = async_test("Test exceptions on gaussianBlur filter"); +_addTest(function(canvas, ctx) { + + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'gaussianBlur'}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'gaussianBlur', stdDeviation: undefined}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'gaussianBlur', stdDeviation: 'foo'}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'gaussianBlur', stdDeviation: [1,2,3]}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'gaussianBlur', stdDeviation: NaN}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'gaussianBlur', stdDeviation: {}}}); }); + +}); +</script> + diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.colorMatrix.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.colorMatrix.html new file mode 100644 index 0000000000..ef0ae0f949 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.colorMatrix.html @@ -0,0 +1,104 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.layers.colorMatrix</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> +<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css"> +<body class="show_output"> + +<h1>2d.filter.layers.colorMatrix</h1> +<p class="desc">Test the functionality of ColorMatrix filters</p> + + +<p class="output">Actual output:</p> +<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas> + +<ul id="d"></ul> +<script> +var t = async_test("Test the functionality of ColorMatrix filters"); +_addTest(function(canvas, ctx) { + + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'colorMatrix', values: undefined}}); }); + + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'colorMatrix', values: 'foo'}}); }); + + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'colorMatrix', values: null}}); }); + + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'colorMatrix', values: [1, 2, 3]}}); }); + + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'colorMatrix', + values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 'a']}}); }); + + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'colorMatrix', + values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, Infinity]}}); }); + + ctx.fillStyle = '#f00'; + ctx.beginLayer({filter: + {name: 'colorMatrix', type: 'hueRotate', values: 0}}); + ctx.fillRect(0, 0, 100, 50); + ctx.endLayer(); + _assertPixelApprox(canvas, 10,10, 255,0,0,255, 2); + + ctx.beginLayer({filter: + {name: 'colorMatrix', type: 'hueRotate', values: 90}}); + ctx.fillRect(0, 0, 100, 50); + ctx.endLayer(); + _assertPixelApprox(canvas, 10,10, 0,91,0,255, 2); + + ctx.beginLayer({filter: + {name: 'colorMatrix', type: 'hueRotate', values: 180}}); + ctx.fillRect(0, 0, 100, 50); + ctx.endLayer(); + _assertPixelApprox(canvas, 10,10, 0,109,109,255, 2); + + ctx.beginLayer({filter: + {name: 'colorMatrix', type: 'hueRotate', values: 270}}); + ctx.fillRect(0, 0, 100, 50); + ctx.endLayer(); + _assertPixelApprox(canvas, 10,10, 109,18,255,255, 2); + + ctx.beginLayer({filter: + {name: 'colorMatrix', type: 'saturate', values: 0.5}}); + ctx.fillRect(0, 0, 100, 50); + ctx.endLayer(); + _assertPixelApprox(canvas, 10,10, 155,27,27,255, 2); + + ctx.clearRect(0, 0, 100, 50); + ctx.beginLayer({filter: + {name: 'colorMatrix', type: 'luminanceToAlpha'}}); + ctx.fillRect(0, 0, 100, 50); + ctx.endLayer(); + _assertPixelApprox(canvas, 10,10, 0,0,0,54, 2); + + ctx.beginLayer({filter: + {name: 'colorMatrix', values: [ + 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0 + ]}}); + ctx.fillRect(0, 0, 50, 25); + ctx.fillStyle = '#0f0'; + ctx.fillRect(50, 0, 50, 25); + ctx.fillStyle = '#00f'; + ctx.fillRect(0, 25, 50, 25); + ctx.fillStyle = '#fff'; + ctx.fillRect(50, 25, 50, 25); + ctx.endLayer(); + _assertPixelApprox(canvas, 10,10, 0,255,0,255, 2); + _assertPixelApprox(canvas, 60,10, 0,255,0,255, 2); + _assertPixelApprox(canvas, 10,30, 0,255,0,255, 2); + _assertPixelApprox(canvas, 60,30, 0,255,0,255, 2); + +}); +</script> + diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.componentTransfer.discrete-expected.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.componentTransfer.discrete-expected.html new file mode 100644 index 0000000000..8419953b3d --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.componentTransfer.discrete-expected.html @@ -0,0 +1,50 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.layers.componentTransfer.discrete</title> +<h1>2d.filter.layers.componentTransfer.discrete</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with discrete type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement + function getTransformedValue(C, V) { + // Get the right interval + const n = V.length; + const k = C == 1 ? n - 1 : Math.floor(C * n); + return V[k]; + } + + function getColor(inputColor, tableValues) { + const result = [0, 0, 0]; + for (const i in inputColor) { + const C = inputColor[i]/255; + const Cprime = getTransformedValue(C, tableValues[i]); + result[i] = Math.max(0, Math.min(1, Cprime)) * 255; + } + return result; + } + + tableValuesR = [0, 0, 1, 1]; + tableValuesG = [2, 0, 0.5, 3]; + tableValuesB = [1, -1, 5, 0]; + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + let outputColor = getColor( + color, [tableValuesR, tableValuesG, tableValuesB]); + ctx.fillStyle = `rgb(${outputColor[0]}, ${outputColor[1]}, + ${outputColor[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } +</script> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.componentTransfer.discrete.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.componentTransfer.discrete.html new file mode 100644 index 0000000000..ef9db79547 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.componentTransfer.discrete.html @@ -0,0 +1,38 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.filter.layers.componentTransfer.discrete-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-500"> +<title>Canvas test: 2d.filter.layers.componentTransfer.discrete</title> +<h1>2d.filter.layers.componentTransfer.discrete</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with discrete type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + tableValuesR = [0, 0, 1, 1]; + tableValuesG = [2, 0, 0.5, 3]; + tableValuesB = [1, -1, 5, 0]; + ctx.beginLayer({filter: {name: 'componentTransfer', + funcR: {type: 'discrete', tableValues: tableValuesR}, + funcG: {type: 'discrete', tableValues: tableValuesG}, + funcB: {type: 'discrete', tableValues: tableValuesB}, + }}); + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } + ctx.endLayer(); +</script> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.componentTransfer.gamma-expected.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.componentTransfer.gamma-expected.html new file mode 100644 index 0000000000..3e5d980896 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.componentTransfer.gamma-expected.html @@ -0,0 +1,44 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.layers.componentTransfer.gamma</title> +<h1>2d.filter.layers.componentTransfer.gamma</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with gamma type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement + function getColor(inputColor, amplitude, exponent, offset) { + return [ + Math.max(0, Math.min(1, Math.pow(inputColor[0]/255, + exponent[0]) * amplitude[0] + offset[0])) * 255, + Math.max(0, Math.min(1, Math.pow(inputColor[1]/255, + exponent[1]) * amplitude[1] + offset[1])) * 255, + Math.max(0, Math.min(1, Math.pow(inputColor[2]/255, + exponent[2]) * amplitude[2] + offset[2])) * 255, + ]; + } + + const amplitudes = [2, 1.1, 0.5]; + const exponents = [5, 3, 1]; + const offsets = [0.25, 0, 0.5]; + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + let outputColor = getColor(color, amplitudes, exponents, offsets); + ctx.fillStyle = `rgb(${outputColor[0]}, ${outputColor[1]}, + ${outputColor[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } +</script> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.componentTransfer.gamma.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.componentTransfer.gamma.html new file mode 100644 index 0000000000..cccd07e92b --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.componentTransfer.gamma.html @@ -0,0 +1,41 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.filter.layers.componentTransfer.gamma-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-500"> +<title>Canvas test: 2d.filter.layers.componentTransfer.gamma</title> +<h1>2d.filter.layers.componentTransfer.gamma</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with gamma type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + const amplitudes = [2, 1.1, 0.5]; + const exponents = [5, 3, 1]; + const offsets = [0.25, 0, 0.5]; + ctx.beginLayer({filter: {name: 'componentTransfer', + funcR: {type: 'gamma', amplitude: amplitudes[0], + exponent: exponents[0], offset: offsets[0]}, + funcG: {type: 'gamma', amplitude: amplitudes[1], + exponent: exponents[1], offset: offsets[1]}, + funcB: {type: 'gamma', amplitude: amplitudes[2], + exponent: exponents[2], offset: offsets[2]}, + }}); + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } + ctx.endLayer(); +</script> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.componentTransfer.identity-expected.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.componentTransfer.identity-expected.html new file mode 100644 index 0000000000..9f1439f37b --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.componentTransfer.identity-expected.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.layers.componentTransfer.identity</title> +<h1>2d.filter.layers.componentTransfer.identity</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with identity type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + let outputColor = inputColors[i]; + ctx.fillStyle = `rgb(${outputColor[0]}, ${outputColor[1]}, + ${outputColor[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } +</script> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.componentTransfer.identity.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.componentTransfer.identity.html new file mode 100644 index 0000000000..3a06353849 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.componentTransfer.identity.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.filter.layers.componentTransfer.identity-expected.html"> +<title>Canvas test: 2d.filter.layers.componentTransfer.identity</title> +<h1>2d.filter.layers.componentTransfer.identity</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with identity type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + ctx.beginLayer({filter: {name: 'componentTransfer', + funcR: {type: 'identity'}, + funcG: {type: 'identity'}, + funcB: {type: 'identity'}, + }}); + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } + ctx.endLayer(); +</script> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.componentTransfer.linear-expected.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.componentTransfer.linear-expected.html new file mode 100644 index 0000000000..f922055ff2 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.componentTransfer.linear-expected.html @@ -0,0 +1,44 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.layers.componentTransfer.linear</title> +<h1>2d.filter.layers.componentTransfer.linear</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with linear type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement + function getColor(inputColor, slopes, intercepts) { + return [ + Math.max(0, Math.min(1, + inputColor[0]/255 * slopes[0] + intercepts[0])) * 255, + Math.max(0, Math.min(1, + inputColor[1]/255 * slopes[1] + intercepts[1])) * 255, + Math.max(0, Math.min(1, + inputColor[2]/255 * slopes[2] + intercepts[2])) * 255, + ]; + } + + const slopes = [0.5, 1.2, -0.2]; + const intercepts = [0.25, 0, 0.5]; + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + let outputColor = getColor(color, slopes, intercepts); + ctx.fillStyle = `rgb(${outputColor[0]}, ${outputColor[1]}, + ${outputColor[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } + ctx.endLayer(); +</script> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.componentTransfer.linear.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.componentTransfer.linear.html new file mode 100644 index 0000000000..c9e744ebef --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.componentTransfer.linear.html @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.filter.layers.componentTransfer.linear-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-500"> +<title>Canvas test: 2d.filter.layers.componentTransfer.linear</title> +<h1>2d.filter.layers.componentTransfer.linear</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with linear type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + const slopes = [0.5, 1.2, -0.2]; + const intercepts = [0.25, 0, 0.5]; + ctx.beginLayer({filter: {name: 'componentTransfer', + funcR: {type: 'linear', slope: slopes[0], intercept: intercepts[0]}, + funcG: {type: 'linear', slope: slopes[1], intercept: intercepts[1]}, + funcB: {type: 'linear', slope: slopes[2], intercept: intercepts[2]}, + }}); + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } + ctx.endLayer(); +</script> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.componentTransfer.table-expected.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.componentTransfer.table-expected.html new file mode 100644 index 0000000000..0f6736d87d --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.componentTransfer.table-expected.html @@ -0,0 +1,51 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.layers.componentTransfer.table</title> +<h1>2d.filter.layers.componentTransfer.table</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with table type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement + function getTransformedValue(C, V) { + // Get the right interval + const n = V.length - 1; + const k = C == 1 ? n - 1 : Math.floor(C * n); + return V[k] + (C - k/n) * n * (V[k + 1] - V[k]); + } + + function getColor(inputColor, tableValues) { + const result = [0, 0, 0]; + for (const i in inputColor) { + const C = inputColor[i]/255; + const Cprime = getTransformedValue(C, tableValues[i]); + result[i] = Math.max(0, Math.min(1, Cprime)) * 255; + } + return result; + } + + tableValuesR = [0, 0, 1, 1]; + tableValuesG = [2, 0, 0.5, 3]; + tableValuesB = [1, -1, 5, 0]; + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + let outputColor = getColor( + color, [tableValuesR, tableValuesG, tableValuesB]); + ctx.fillStyle = `rgb(${outputColor[0]}, ${outputColor[1]}, + ${outputColor[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } +</script> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.componentTransfer.table.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.componentTransfer.table.html new file mode 100644 index 0000000000..eae036b142 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.componentTransfer.table.html @@ -0,0 +1,38 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.filter.layers.componentTransfer.table-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-500"> +<title>Canvas test: 2d.filter.layers.componentTransfer.table</title> +<h1>2d.filter.layers.componentTransfer.table</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with table type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + tableValuesR = [0, 0, 1, 1]; + tableValuesG = [2, 0, 0.5, 3]; + tableValuesB = [1, -1, 5, 0]; + ctx.beginLayer({filter: {name: 'componentTransfer', + funcR: {type: 'table', tableValues: tableValuesR}, + funcG: {type: 'table', tableValues: tableValuesG}, + funcB: {type: 'table', tableValues: tableValuesB}, + }}); + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } + ctx.endLayer(); +</script> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.convolveMatrix.exceptions.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.convolveMatrix.exceptions.html new file mode 100644 index 0000000000..ae45cb865c --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.convolveMatrix.exceptions.html @@ -0,0 +1,60 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.layers.convolveMatrix.exceptions</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> +<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css"> +<body class="show_output"> + +<h1>2d.filter.layers.convolveMatrix.exceptions</h1> +<p class="desc">Test exceptions on CanvasFilter() convolveMatrix</p> + + +<p class="output">Actual output:</p> +<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas> + +<ul id="d"></ul> +<script> +var t = async_test("Test exceptions on CanvasFilter() convolveMatrix"); +_addTest(function(canvas, ctx) { + + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix'}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', divisor: 2}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: null}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: 1}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [[1, 0], [0]]}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [[1, 'a'], [0]]}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [[1, 0], 0]}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [[1, 0], [0, Infinity]]}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: []}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [1]}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [1, 2, 3, 4]}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [[], []]}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [[1, 2], []]}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [[], [1, 2]]}}); }); + // This should not throw an error + ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [[]]}}); + ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [[1]]}}); + ctx.endLayer(); + +}); +</script> + diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.dropShadow-expected.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.dropShadow-expected.html new file mode 100644 index 0000000000..1719d99b4a --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.dropShadow-expected.html @@ -0,0 +1,57 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.layers.dropShadow</title> +<h1>2d.filter.layers.dropShadow</h1> +<p class="desc">Test CanvasFilter() dropShadow object.</p> + +<svg xmlns="http://www.w3.org/2000/svg" + width=520 height=420 + color-interpolation-filters="sRGB"> + <rect x=0 y=0 width=100% height=50 fill="teal" /> + <rect x=0 y=100 width=100% height=50 fill="teal" /> + <rect x=0 y=200 width=100% height=50 fill="teal" /> + <rect x=0 y=300 width=100% height=50 fill="teal" /> + + <rect x=10 y=10 width=80 height=80 fill="crimson" + filter="drop-shadow(2px 2px 2px black)"/> + <rect x=110 y=10 width=80 height=80 fill="crimson" + filter="drop-shadow(9px 12px 5px rgba(128, 0, 128, 0.7))"/> + + <rect x=10 y=110 width=80 height=80 fill="crimson" + filter="drop-shadow(9px 12px 3px purple)"/> + <rect x=110 y=110 width=80 height=80 fill="crimson" + filter="drop-shadow(9px 12px 3px LinkText)"/> + <rect x=210 y=110 width=80 height=80 fill="crimson" + filter="drop-shadow(9px 12px 3px rgba(20, 50, 130, 1))"/> + <rect x=310 y=110 width=80 height=80 fill="crimson" + filter="drop-shadow(9px 12px 3px rgba(20, 50, 130, 0.7))"/> + <rect x=410 y=110 width=80 height=80 fill="crimson" + filter="drop-shadow(9px 12px 3px rgba(20, 50, 130, 0.49))"/> + + <rect x=10 y=210 width=80 height=80 fill="crimson" + filter="drop-shadow(9px 12px 0px purple)"/> + <rect x=110 y=210 width=80 height=80 fill="crimson" + filter="drop-shadow(9px 12px 5px purple)"/> + <rect x=210 y=210 width=80 height=80 fill="crimson" + filter="drop-shadow(9px 12px 0px purple)"/> + <filter id="separable-filter" + x="-100%" y="-100%" width="300%" height="300%"> + <feDropShadow dx=9 dy=12 stdDeviation="3 5" flood-color="purple"/> + </filter> + <rect x=310 y=210 width=80 height=80 fill="crimson" + filter="url(#separable-filter)"/> + <rect x=410 y=210 width=80 height=80 fill="crimson" + filter="drop-shadow(9px 12px 0px purple)"/> + + <rect x=10 y=310 width=80 height=80 fill="crimson" + filter="drop-shadow(-5px 0px 0px purple)"/> + <filter id="separable-filter-degenerate" + x="-100%" y="-100%" width="300%" height="300%"> + <feDropShadow dx=0 dy=5 stdDeviation="0 3" + flood-color="rgba(128, 0, 128, 0.8)"/> + </filter> + <rect x=110 y=310 width=80 height=80 fill="crimson" + filter="url(#separable-filter-degenerate)"/> + <rect x=210 y=310 width=80 height=80 fill="crimson" + filter="drop-shadow(1px 10px 0px rgba(128, 0, 128, 0.4))"/> +</svg> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.dropShadow.exceptions.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.dropShadow.exceptions.html new file mode 100644 index 0000000000..df5e0c7dc3 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.dropShadow.exceptions.html @@ -0,0 +1,269 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.layers.dropShadow.exceptions</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> +<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css"> +<body class="show_output"> + +<h1>2d.filter.layers.dropShadow.exceptions</h1> +<p class="desc">Test exceptions on CanvasFilter() dropShadow object</p> + + +<p class="output">Actual output:</p> +<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas> + +<ul id="d"></ul> +<script> +var t = async_test("Test exceptions on CanvasFilter() dropShadow object"); +_addTest(function(canvas, ctx) { + + // Should not throw an error. + // dx + ctx.beginLayer({filter: + {name: 'dropShadow', dx: 10}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: -1}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: 0.5}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: null}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: true}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: false}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: []}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: [20]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: '30'}}); ctx.endLayer(); + // dy + ctx.beginLayer({filter: + {name: 'dropShadow', dy: 10}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: -1}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: 0.5}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: null}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: true}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: false}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: []}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: [20]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: '30'}}); ctx.endLayer(); + // floodOpacity + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: 10}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: -1}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: 0.5}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: null}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: true}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: false}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: []}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: [20]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: '30'}}); ctx.endLayer(); + // dx + ctx.beginLayer({filter: + {name: 'dropShadow', dx: 10}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: -1}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: 0.5}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: null}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: true}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: false}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: []}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: [20]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: '30'}}); ctx.endLayer(); + // dy + ctx.beginLayer({filter: + {name: 'dropShadow', dy: 10}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: -1}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: 0.5}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: null}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: true}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: false}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: []}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: [20]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: '30'}}); ctx.endLayer(); + // floodOpacity + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: 10}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: -1}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: 0.5}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: null}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: true}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: false}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: []}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: [20]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: '30'}}); ctx.endLayer(); + // stdDeviation + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: 10}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: -1}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: 0.5}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: null}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: true}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: false}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: []}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [20]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: '30'}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [10, -1]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [0.5, null]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [true, false]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [[], [20]]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: ['30', ['40']]}}); ctx.endLayer(); + // floodColor + ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: 'red'}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: 'canvas'}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: 'rgba(4, -3, 0.5, 1)'}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: '#aabbccdd'}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: '#abcd'}}); ctx.endLayer(); + + // Should throw a TypeError. + // dx + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dx: NaN}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dx: Infinity}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dx: -Infinity}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dx: undefined}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dx: 'test'}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dx: {}}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dx: [1, 2]}}); ctx.endLayer(); }); + // dy + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dy: NaN}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dy: Infinity}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dy: -Infinity}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dy: undefined}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dy: 'test'}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dy: {}}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dy: [1, 2]}}); ctx.endLayer(); }); + // floodOpacity + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: NaN}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: Infinity}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: -Infinity}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: undefined}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: 'test'}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: {}}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: [1, 2]}}); ctx.endLayer(); }); + // stdDeviation + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: NaN}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: Infinity}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: -Infinity}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: undefined}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: 'test'}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: {}}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [1, 2, 3]}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [1, NaN]}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [1, Infinity]}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [1, -Infinity]}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [1, undefined]}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [1, 'test']}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [1, {}]}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [1, [2, 3]]}}); ctx.endLayer(); }); + // floodColor + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: 'test'}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: 'rgba(NaN, 3, 2, 1)'}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: 10}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: undefined}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: null}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: NaN}}); ctx.endLayer(); }); + +}); +</script> + diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.dropShadow.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.dropShadow.html new file mode 100644 index 0000000000..ceb20bb9eb --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.dropShadow.html @@ -0,0 +1,94 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.filter.layers.dropShadow-expected.html"> +<title>Canvas test: 2d.filter.layers.dropShadow</title> +<h1>2d.filter.layers.dropShadow</h1> +<p class="desc">Test CanvasFilter() dropShadow object.</p> +<canvas id="canvas" width="520" height="420"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'teal'; + ctx.fillRect(0, 0, 520, 50); + ctx.fillRect(0, 100, 520, 50); + ctx.fillRect(0, 200, 520, 50); + ctx.fillRect(0, 300, 520, 50); + + ctx.fillStyle = 'crimson'; + + // Parameter defaults. + ctx.beginLayer({filter: {name: 'dropShadow'}}); + ctx.fillRect(10, 10, 80, 80); + ctx.endLayer(); + // All parameters specified. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5, + floodColor: 'purple', floodOpacity: 0.7}}); + ctx.fillRect(110, 10, 80, 80); + ctx.endLayer(); + // Named color. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + floodColor: 'purple'}}); + ctx.fillRect(10, 110, 80, 80); + ctx.endLayer(); + // System color. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + floodColor: 'LinkText'}}); + ctx.fillRect(110, 110, 80, 80); + ctx.endLayer(); + // Numerical color. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + floodColor: 'rgba(20, 50, 130, 1)'}}); + ctx.fillRect(210, 110, 80, 80); + ctx.endLayer(); + // Transparent floodColor. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + floodColor: 'rgba(20, 50, 130, 0.7)'}}); + ctx.fillRect(310, 110, 80, 80); + ctx.endLayer(); + // Transparent floodColor and floodOpacity. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + floodColor: 'rgba(20, 50, 130, 0.7)', floodOpacity: 0.7}}); + ctx.fillRect(410, 110, 80, 80); + ctx.endLayer(); + // No blur. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 0, + floodColor: 'purple'}}); + ctx.fillRect(10, 210, 80, 80); + ctx.endLayer(); + // Single float blur. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5, + floodColor: 'purple'}}); + ctx.fillRect(110, 210, 80, 80); + ctx.endLayer(); + // Single negative float blur. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: -5, + floodColor: 'purple'}}); + ctx.fillRect(210, 210, 80, 80); + ctx.endLayer(); + // Two floats (X&Y) blur. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: [3, 5], + floodColor: 'purple'}}); + ctx.fillRect(310, 210, 80, 80); + ctx.endLayer(); + // Two negative floats (X&Y) blur. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: [-3, -5], + floodColor: 'purple'}}); + ctx.fillRect(410, 210, 80, 80); + ctx.endLayer(); + // Degenerate parameter values. + ctx.beginLayer({filter: {name: 'dropShadow', dx: [-5], dy: [], stdDeviation: null, + floodColor: 'purple', floodOpacity: [2]}}); + ctx.fillRect(10, 310, 80, 80); + ctx.endLayer(); + ctx.beginLayer({filter: {name: 'dropShadow', dx: null, dy: '5', stdDeviation: [[-5], ['3']], + floodColor: 'purple', floodOpacity: '0.8'}}); + ctx.fillRect(110, 310, 80, 80); + ctx.endLayer(); + ctx.beginLayer({filter: {name: 'dropShadow', dx: true, dy: ['10'], stdDeviation: false, + floodColor: 'purple', floodOpacity: ['0.4']}}); + ctx.fillRect(210, 310, 80, 80); + ctx.endLayer(); +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic-expected.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.gaussianBlur.isotropic-expected.html index f9571f208e..4f93754862 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic-expected.html +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.gaussianBlur.isotropic-expected.html @@ -1,7 +1,7 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> -<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic</title> -<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic</h1> +<title>Canvas test: 2d.filter.layers.gaussianBlur.isotropic</title> +<h1>2d.filter.layers.gaussianBlur.isotropic</h1> <p class="desc">Test CanvasFilter() with gaussianBlur.</p> <svg xmlns="http://www.w3.org/2000/svg" diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.gaussianBlur.isotropic.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.gaussianBlur.isotropic.html new file mode 100644 index 0000000000..a2cc098896 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.gaussianBlur.isotropic.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.filter.layers.gaussianBlur.isotropic-expected.html"> +<title>Canvas test: 2d.filter.layers.gaussianBlur.isotropic</title> +<h1>2d.filter.layers.gaussianBlur.isotropic</h1> +<p class="desc">Test CanvasFilter() with gaussianBlur.</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'teal'; + ctx.beginLayer({filter: { + name: 'gaussianBlur', + stdDeviation: [4, 4], + }}); + ctx.fillRect(25, 25, 50, 50); + ctx.endLayer(); +</script> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.gaussianBlur.mostly-x-expected.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.gaussianBlur.mostly-x-expected.html new file mode 100644 index 0000000000..255270c192 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.gaussianBlur.mostly-x-expected.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.layers.gaussianBlur.mostly-x</title> +<h1>2d.filter.layers.gaussianBlur.mostly-x</h1> +<p class="desc">Test CanvasFilter() with gaussianBlur.</p> + +<svg xmlns="http://www.w3.org/2000/svg" + width="100" height="100" + color-interpolation-filters="sRGB"> + <filter id="blur" x="-50%" y="-50%" width="200%" height="200%"> + <feGaussianBlur stdDeviation="4 1" /> + </filter> + <rect x="25" y="25" width="50" height="50" + fill="teal" filter="url(#blur)" /> +</svg> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.gaussianBlur.mostly-x.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.gaussianBlur.mostly-x.html new file mode 100644 index 0000000000..0090e0e71e --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.gaussianBlur.mostly-x.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.filter.layers.gaussianBlur.mostly-x-expected.html"> +<title>Canvas test: 2d.filter.layers.gaussianBlur.mostly-x</title> +<h1>2d.filter.layers.gaussianBlur.mostly-x</h1> +<p class="desc">Test CanvasFilter() with gaussianBlur.</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'teal'; + ctx.beginLayer({filter: { + name: 'gaussianBlur', + stdDeviation: [4, 1], + }}); + ctx.fillRect(25, 25, 50, 50); + ctx.endLayer(); +</script> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.gaussianBlur.mostly-y-expected.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.gaussianBlur.mostly-y-expected.html new file mode 100644 index 0000000000..76a46b1533 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.gaussianBlur.mostly-y-expected.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.layers.gaussianBlur.mostly-y</title> +<h1>2d.filter.layers.gaussianBlur.mostly-y</h1> +<p class="desc">Test CanvasFilter() with gaussianBlur.</p> + +<svg xmlns="http://www.w3.org/2000/svg" + width="100" height="100" + color-interpolation-filters="sRGB"> + <filter id="blur" x="-50%" y="-50%" width="200%" height="200%"> + <feGaussianBlur stdDeviation="1 4" /> + </filter> + <rect x="25" y="25" width="50" height="50" + fill="teal" filter="url(#blur)" /> +</svg> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.gaussianBlur.mostly-y.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.gaussianBlur.mostly-y.html new file mode 100644 index 0000000000..5c481cbe25 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.gaussianBlur.mostly-y.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.filter.layers.gaussianBlur.mostly-y-expected.html"> +<title>Canvas test: 2d.filter.layers.gaussianBlur.mostly-y</title> +<h1>2d.filter.layers.gaussianBlur.mostly-y</h1> +<p class="desc">Test CanvasFilter() with gaussianBlur.</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'teal'; + ctx.beginLayer({filter: { + name: 'gaussianBlur', + stdDeviation: [1, 4], + }}); + ctx.fillRect(25, 25, 50, 50); + ctx.endLayer(); +</script> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.gaussianBlur.x-only-expected.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.gaussianBlur.x-only-expected.html new file mode 100644 index 0000000000..26741f9847 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.gaussianBlur.x-only-expected.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.layers.gaussianBlur.x-only</title> +<h1>2d.filter.layers.gaussianBlur.x-only</h1> +<p class="desc">Test CanvasFilter() with gaussianBlur.</p> + +<svg xmlns="http://www.w3.org/2000/svg" + width="100" height="100" + color-interpolation-filters="sRGB"> + <filter id="blur" x="-50%" y="-50%" width="200%" height="200%"> + <feGaussianBlur stdDeviation="4 0" /> + </filter> + <rect x="25" y="25" width="50" height="50" + fill="teal" filter="url(#blur)" /> +</svg> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.gaussianBlur.x-only.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.gaussianBlur.x-only.html new file mode 100644 index 0000000000..f7940eb921 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.gaussianBlur.x-only.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.filter.layers.gaussianBlur.x-only-expected.html"> +<title>Canvas test: 2d.filter.layers.gaussianBlur.x-only</title> +<h1>2d.filter.layers.gaussianBlur.x-only</h1> +<p class="desc">Test CanvasFilter() with gaussianBlur.</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'teal'; + ctx.beginLayer({filter: { + name: 'gaussianBlur', + stdDeviation: [4, 0], + }}); + ctx.fillRect(25, 25, 50, 50); + ctx.endLayer(); +</script> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.gaussianBlur.y-only-expected.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.gaussianBlur.y-only-expected.html new file mode 100644 index 0000000000..d00eec6b57 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.gaussianBlur.y-only-expected.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.layers.gaussianBlur.y-only</title> +<h1>2d.filter.layers.gaussianBlur.y-only</h1> +<p class="desc">Test CanvasFilter() with gaussianBlur.</p> + +<svg xmlns="http://www.w3.org/2000/svg" + width="100" height="100" + color-interpolation-filters="sRGB"> + <filter id="blur" x="-50%" y="-50%" width="200%" height="200%"> + <feGaussianBlur stdDeviation="0 4" /> + </filter> + <rect x="25" y="25" width="50" height="50" + fill="teal" filter="url(#blur)" /> +</svg> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.gaussianBlur.y-only.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.gaussianBlur.y-only.html new file mode 100644 index 0000000000..59421a1ff3 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.gaussianBlur.y-only.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.filter.layers.gaussianBlur.y-only-expected.html"> +<title>Canvas test: 2d.filter.layers.gaussianBlur.y-only</title> +<h1>2d.filter.layers.gaussianBlur.y-only</h1> +<p class="desc">Test CanvasFilter() with gaussianBlur.</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'teal'; + ctx.beginLayer({filter: { + name: 'gaussianBlur', + stdDeviation: [0, 4], + }}); + ctx.fillRect(25, 25, 50, 50); + ctx.endLayer(); +</script> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.turbulence.inputTypes.html b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.turbulence.inputTypes.html new file mode 100644 index 0000000000..26dceaae16 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/filters/2d.filter.layers.turbulence.inputTypes.html @@ -0,0 +1,130 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.layers.turbulence.inputTypes</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> +<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css"> +<body class="show_output"> + +<h1>2d.filter.layers.turbulence.inputTypes</h1> +<p class="desc">Test exceptions on CanvasFilter() turbulence object</p> + + +<p class="output">Actual output:</p> +<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas> + +<ul id="d"></ul> +<script> +var t = async_test("Test exceptions on CanvasFilter() turbulence object"); +_addTest(function(canvas, ctx) { + + const errorTestCases = [ + {baseFrequency: {}}, + {baseFrequency: -1}, + {baseFrequency: [0, -1]}, + {baseFrequency: NaN}, + {baseFrequency: Infinity}, + {baseFrequency: undefined}, + {baseFrequency: -Infinity}, + {baseFrequency: 'test'}, + + {numOctaves: {}}, + {numOctaves: -1}, + {numOctaves: NaN}, + {numOctaves: Infinity}, + {numOctaves: undefined}, + {numOctaves: -Infinity}, + {numOctaves: [1, 1]}, + {numOctaves: 'test'}, + + {seed: {}}, + {seed: NaN}, + {seed: Infinity}, + {seed: undefined}, + {seed: -Infinity}, + {seed: [1, 1]}, + {seed: 'test'}, + + {stitchTiles: {}}, + {stitchTiles: NaN}, + {stitchTiles: Infinity}, + {stitchTiles: undefined}, + {stitchTiles: -Infinity}, + {stitchTiles: [1, 1]}, + {stitchTiles: 'test'}, + {stitchTiles: null}, + {stitchTiles: []}, + {stitchTiles: [10]}, + {stitchTiles: 30}, + {stitchTiles: false}, + {stitchTiles: true}, + {stitchTiles: '10'}, + {stitchTiles: -1}, + + {type: {}}, + {type: NaN}, + {type: Infinity}, + {type: undefined}, + {type: -Infinity}, + {type: [1, 1]}, + {type: 'test'}, + {type: null}, + {type: []}, + {type: [10]}, + {type: 30}, + {type: false}, + {type: true}, + {type: '10'}, + {type: -1}, + ] + + // null and [] = 0 when parsed as number + const workingTestCases = [ + {baseFrequency: null}, + {baseFrequency: []}, + {baseFrequency: [10]}, + {baseFrequency: [10, 3]}, + {baseFrequency: 30}, + {baseFrequency: false}, + {baseFrequency: true}, + {baseFrequency: '10'}, + + {numOctaves: null}, + {numOctaves: []}, + {numOctaves: [10]}, + {numOctaves: 30}, + {numOctaves: false}, + {numOctaves: true}, + {numOctaves: '10'}, + + {seed: null}, + {seed: []}, + {seed: [10]}, + {seed: 30}, + {seed: false}, + {seed: true}, + {seed: '10'}, + {seed: -1}, + + {stitchTiles: 'stitch'}, + {stitchTiles: 'noStitch'}, + + {type: 'fractalNoise'}, + {type: 'turbulence'}, + ] + + for (testCase of errorTestCases) { + const filterOptions = {...{name: 'turbulence'}, ...testCase}; + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: filterOptions}); }); + } + + for (testCase of workingTestCases) { + const filterOptions = {...{name: 'turbulence'}, ...testCase}; + ctx.beginLayer({filter: filterOptions}); + ctx.endLayer(); + } + +}); +</script> + diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.ctm.filter-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.ctm.filter-expected.html new file mode 100644 index 0000000000..5fc1ac9acd --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.ctm.filter-expected.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.layer.ctm.filter</title> +<h1>2d.layer.ctm.filter</h1> +<p class="desc">Checks that parent transforms affect layer filters.</p> + +<svg xmlns="http://www.w3.org/2000/svg" + width="200" height="200" + color-interpolation-filters="sRGB"> + <filter id="filter" x="-100%" y="-100%" width="300%" height="300%"> + <feDropShadow dx="5" dy="5" stdDeviation="0" flood-color="grey" /> + </filter> + + <g filter="url(#filter)"> + <g transform="translate(30, 90) scale(2) rotate(90)"> + <rect x="-30" y="-5" width=60 height=10></rect> + </g> + </g> + + <g transform="translate(80, 90) scale(2) rotate(90)"> + <g filter="url(#filter)"> + <rect x="-30" y="-5" width=60 height=10></rect> + </g> + </g> +</svg> diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.ctm.filter.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.ctm.filter.html new file mode 100644 index 0000000000..3d56ac3601 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.ctm.filter.html @@ -0,0 +1,29 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.layer.ctm.filter-expected.html"> +<title>Canvas test: 2d.layer.ctm.filter</title> +<h1>2d.layer.ctm.filter</h1> +<p class="desc">Checks that parent transforms affect layer filters.</p> +<canvas id="canvas" width="200" height="200"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + // Transforms inside the layer should not apply to the layer's filter. + ctx.beginLayer({filter: 'drop-shadow(5px 5px 0px grey)'}); + ctx.translate(30, 90); + ctx.scale(2, 2); + ctx.rotate(Math.PI / 2); + ctx.fillRect(-30, -5, 60, 10); + ctx.endLayer(); + + // Transforms in the layer's parent should apply to the layer's filter. + ctx.translate(80, 90); + ctx.scale(2, 2); + ctx.rotate(Math.PI / 2); + ctx.beginLayer({filter: 'drop-shadow(5px 5px 0px grey)'}); + ctx.fillRect(-30, -5, 60, 10); + ctx.endLayer(); +</script> diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.ctm.getTransform.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.ctm.getTransform.html new file mode 100644 index 0000000000..7a69c59527 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.ctm.getTransform.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.layer.ctm.getTransform</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> +<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css"> +<body class="show_output"> + +<h1>2d.layer.ctm.getTransform</h1> +<p class="desc">Tests getTransform inside layers.</p> + + +<p class="output">Actual output:</p> +<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas> + +<ul id="d"></ul> +<script> +var t = async_test("Tests getTransform inside layers."); +_addTest(function(canvas, ctx) { + + ctx.translate(10, 20); + ctx.beginLayer(); + ctx.scale(2, 3); + const m = ctx.getTransform(); + assert_array_equals([m.a, m.b, m.c, m.d, m.e, m.f], [2, 0, 0, 3, 10, 20]); + ctx.endLayer(); + +}); +</script> + diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.ctm.resetTransform-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.ctm.resetTransform-expected.html new file mode 100644 index 0000000000..fd4c1746c7 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.ctm.resetTransform-expected.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.layer.ctm.resetTransform</title> +<h1>2d.layer.ctm.resetTransform</h1> +<p class="desc">Tests resetTransform inside layers.</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'blue'; + ctx.fillRect(0, 0, 20, 20); + + ctx.translate(40, 0); + ctx.fillStyle = 'green'; + ctx.fillRect(0, 0, 20, 20); +</script> diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.ctm.resetTransform.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.ctm.resetTransform.html new file mode 100644 index 0000000000..9291f8f3f2 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.ctm.resetTransform.html @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.layer.ctm.resetTransform-expected.html"> +<title>Canvas test: 2d.layer.ctm.resetTransform</title> +<h1>2d.layer.ctm.resetTransform</h1> +<p class="desc">Tests resetTransform inside layers.</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + ctx.translate(40, 0); + + ctx.beginLayer(); + ctx.rotate(2); + ctx.beginLayer(); + ctx.scale(5, 6); + ctx.resetTransform(); + ctx.fillStyle = 'blue'; + ctx.fillRect(0, 0, 20, 20); + ctx.endLayer(); + ctx.endLayer(); + + ctx.fillStyle = 'green'; + ctx.fillRect(0, 0, 20, 20); +</script> diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.ctm.setTransform-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.ctm.setTransform-expected.html new file mode 100644 index 0000000000..45a3d095e1 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.ctm.setTransform-expected.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.layer.ctm.setTransform</title> +<h1>2d.layer.ctm.setTransform</h1> +<p class="desc">Tests setTransform inside layers.</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + ctx.translate(80, 0); + ctx.fillStyle = 'green'; + ctx.fillRect(0, 0, 20, 20); + + ctx.setTransform(4, 0, 0, 2, 20, 10); + ctx.fillStyle = 'blue'; + ctx.fillRect(0, 0, 10, 10); +</script> diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.ctm.setTransform.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.ctm.setTransform.html new file mode 100644 index 0000000000..b5d98ba45f --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.ctm.setTransform.html @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.layer.ctm.setTransform-expected.html"> +<title>Canvas test: 2d.layer.ctm.setTransform</title> +<h1>2d.layer.ctm.setTransform</h1> +<p class="desc">Tests setTransform inside layers.</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + ctx.translate(80, 0); + + ctx.beginLayer(); + ctx.rotate(2); + ctx.beginLayer(); + ctx.scale(5, 6); + ctx.setTransform(4, 0, 0, 2, 20, 10); + ctx.fillStyle = 'blue'; + ctx.fillRect(0, 0, 10, 10); + ctx.endLayer(); + ctx.endLayer(); + + ctx.fillStyle = 'green'; + ctx.fillRect(0, 0, 20, 20); +</script> diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.ctm.shadow-in-transformed-layer-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.ctm.shadow-in-transformed-layer-expected.html new file mode 100644 index 0000000000..312ca19b4c --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.ctm.shadow-in-transformed-layer-expected.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.layer.ctm.shadow-in-transformed-layer</title> +<h1>2d.layer.ctm.shadow-in-transformed-layer</h1> +<p class="desc">Check shadows inside of a transformed layer.</p> +<canvas id="canvas" width="200" height="200"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + ctx.translate(80, 90); + ctx.scale(2, 2); + ctx.rotate(Math.PI / 2); + + ctx.shadowOffsetX = 10; + ctx.shadowOffsetY = 10; + ctx.shadowColor = 'grey'; + ctx.fillRect(-30, -5, 60, 10); + + const canvas2 = new OffscreenCanvas(100, 100); + const ctx2 = canvas2.getContext('2d'); + ctx2.fillStyle = 'blue'; + ctx2.fillRect(0, 0, 40, 10); + ctx.drawImage(canvas2, -30, -30); +</script> diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.ctm.shadow-in-transformed-layer.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.ctm.shadow-in-transformed-layer.html new file mode 100644 index 0000000000..f047bd30b2 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.ctm.shadow-in-transformed-layer.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.layer.ctm.shadow-in-transformed-layer-expected.html"> +<title>Canvas test: 2d.layer.ctm.shadow-in-transformed-layer</title> +<h1>2d.layer.ctm.shadow-in-transformed-layer</h1> +<p class="desc">Check shadows inside of a transformed layer.</p> +<canvas id="canvas" width="200" height="200"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + ctx.translate(80, 90); + ctx.scale(2, 2); + ctx.rotate(Math.PI / 2); + + ctx.beginLayer(); + ctx.shadowOffsetX = 10; + ctx.shadowOffsetY = 10; + ctx.shadowColor = 'grey'; + ctx.fillRect(-30, -5, 60, 10); + + const canvas2 = new OffscreenCanvas(100, 100); + const ctx2 = canvas2.getContext('2d'); + ctx2.fillStyle = 'blue'; + ctx2.fillRect(0, 0, 40, 10); + ctx.drawImage(canvas2, -30, -30); + + ctx.endLayer(); +</script> diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.drawImage-expected.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.drawImage-expected.html new file mode 100644 index 0000000000..26f6e75214 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.drawImage-expected.html @@ -0,0 +1,29 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.layer.drawImage</title> +<h1>2d.layer.drawImage</h1> +<p class="desc">Checks that drawImage writes the image to the layer and not the parent directly.</p> +<canvas id="canvas" width="200" height="200"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'skyblue'; + ctx.fillRect(0, 0, 100, 100); + + ctx.beginLayer({filter: {name: 'dropShadow', dx: -10, dy: -10, + stdDeviation: 0, floodColor: 'navy'}}); + + ctx.fillStyle = 'maroon'; + ctx.fillRect(20, 20, 50, 50); + + ctx.globalCompositeOperation = 'xor'; + + // Should xor only with the layer content, not the parents'. + ctx.fillStyle = 'pink'; + ctx.fillRect(40, 40, 50, 50); + + ctx.endLayer(); +</script> diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.drawImage.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.drawImage.html new file mode 100644 index 0000000000..58206c3eb8 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.drawImage.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.layer.drawImage-expected.html"> +<title>Canvas test: 2d.layer.drawImage</title> +<h1>2d.layer.drawImage</h1> +<p class="desc">Checks that drawImage writes the image to the layer and not the parent directly.</p> +<canvas id="canvas" width="200" height="200"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'skyblue'; + ctx.fillRect(0, 0, 100, 100); + + ctx.beginLayer({filter: {name: 'dropShadow', dx: -10, dy: -10, + stdDeviation: 0, floodColor: 'navy'}}); + + ctx.fillStyle = 'maroon'; + ctx.fillRect(20, 20, 50, 50); + + ctx.globalCompositeOperation = 'xor'; + + // The image should xor only with the layer content, not the parents'. + const canvas_image = new OffscreenCanvas(200,200); + const ctx_image = canvas_image.getContext("2d"); + ctx_image.fillStyle = 'pink'; + ctx_image.fillRect(40, 40, 50, 50); + ctx.drawImage(canvas_image, 0, 0); + + ctx.endLayer(); +</script> diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.blending.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.blending.html index 17e0f0c8c5..98ea67e9e9 100644 --- a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.blending.html +++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.blending.html @@ -1,6 +1,7 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> <link rel="match" href="2d.layer.global-states.filter.alpha.blending-expected.html"> +<meta name=fuzzy content="maxDifference=0-1; totalPixels=0-2453"> <title>Canvas test: 2d.layer.global-states.filter.alpha.blending</title> <h1>2d.layer.global-states.filter.alpha.blending</h1> <p class="desc">Checks that layers with filters correctly use global render states.</p> diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.composite.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.composite.html index 71a27cf710..29041d4933 100644 --- a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.composite.html +++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.composite.html @@ -1,6 +1,7 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> <link rel="match" href="2d.layer.global-states.filter.alpha.composite-expected.html"> +<meta name=fuzzy content="maxDifference=0-1; totalPixels=0-5204"> <title>Canvas test: 2d.layer.global-states.filter.alpha.composite</title> <h1>2d.layer.global-states.filter.alpha.composite</h1> <p class="desc">Checks that layers with filters correctly use global render states.</p> diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.html index 5133aa170e..85718cffba 100644 --- a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.html +++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.html @@ -1,6 +1,7 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> <link rel="match" href="2d.layer.global-states.filter.alpha-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-6766"> <title>Canvas test: 2d.layer.global-states.filter.alpha</title> <h1>2d.layer.global-states.filter.alpha</h1> <p class="desc">Checks that layers with filters correctly use global render states.</p> diff --git a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.shadow.html b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.shadow.html index 6aa8e75a95..aaeb167ccf 100644 --- a/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.shadow.html +++ b/testing/web-platform/tests/html/canvas/element/layers/2d.layer.global-states.filter.alpha.shadow.html @@ -1,6 +1,7 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> <link rel="match" href="2d.layer.global-states.filter.alpha.shadow-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-6311"> <title>Canvas test: 2d.layer.global-states.filter.alpha.shadow</title> <h1>2d.layer.global-states.filter.alpha.shadow</h1> <p class="desc">Checks that layers with filters correctly use global render states.</p> diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence-expected.html b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence-expected.html index ff0eebe2e0..ea5600b006 100644 --- a/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence-expected.html +++ b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence-expected.html @@ -1,28 +1,28 @@ <body> <svg style="display:none">> <filter id="base"> - <feTurbulence baseFrequency="0.025"/> + <feTurbulence baseFrequency="0.03125"/> </filter> <filter id="base2d"> - <feTurbulence baseFrequency="0.025, 0.1"/> + <feTurbulence baseFrequency="0.03125, 0.125"/> </filter> <filter id="highFrequency"> - <feTurbulence baseFrequency="0.05"/> + <feTurbulence baseFrequency="0.0625"/> </filter> <filter id="seed"> - <feTurbulence baseFrequency="0.025" seed="100"/> + <feTurbulence baseFrequency="0.03125" seed="100"/> </filter> <filter id="numOctaves"> - <feTurbulence baseFrequency="0.025" numOctaves="2"/> + <feTurbulence baseFrequency="0.03125" numOctaves="2"/> </filter> <filter id="empty"> <feTurbulence/> </filter> <filter id="fractalNoise"> - <feTurbulence baseFrequency="0.025" type="fractalNoise"/> + <feTurbulence baseFrequency="0.03125" type="fractalNoise"/> </filter> <filter id="stitchTiles"> - <feTurbulence baseFrequency="0.025" stitchTiles="noStitch"/> + <feTurbulence baseFrequency="0.03125" stitchTiles="noStitch"/> </filter> </body> <script> @@ -34,4 +34,4 @@ ctx.filter = `url(#${tc.id})`; ctx.fillRect(0, 0, 1, 1); } -</script>
\ No newline at end of file +</script> diff --git a/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence.html b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence.html index b5b494825e..eb0803e42e 100644 --- a/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence.html +++ b/testing/web-platform/tests/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence.html @@ -5,14 +5,14 @@ </body> <script> const testCases = [ - {baseFrequency: 0.025}, - {baseFrequency: [0.025, 0.1]}, - {baseFrequency: 0.05}, - {baseFrequency: 0.025, seed: 100}, - {baseFrequency: 0.025, numOctaves: 2}, + {baseFrequency: 0.03125}, + {baseFrequency: [0.03125, 0.125]}, + {baseFrequency: 0.0625}, + {baseFrequency: 0.03125, seed: 100}, + {baseFrequency: 0.03125, numOctaves: 2}, {}, - {baseFrequency: 0.025, type: "fractalNoise"}, - {baseFrequency: 0.025, stitchTiles: "stitch"}, + {baseFrequency: 0.03125, type: "fractalNoise"}, + {baseFrequency: 0.03125, stitchTiles: "stitch"}, ] for (tc of testCases) { diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.blur.exceptions.tentative.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.blur.exceptions.tentative.html index d8f14529c5..e7461eacdb 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.blur.exceptions.tentative.html +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.blur.exceptions.tentative.html @@ -6,11 +6,11 @@ <script src="/html/canvas/resources/canvas-tests.js"></script> <h1>2d.filter.canvasFilterObject.blur.exceptions.tentative</h1> -<p class="desc">Test exceptions on CanvasFilter() blur.object</p> +<p class="desc">Test exceptions on gaussianBlur filter</p> <script> -var t = async_test("Test exceptions on CanvasFilter() blur.object"); +var t = async_test("Test exceptions on gaussianBlur filter"); var t_pass = t.done.bind(t); var t_fail = t.step_func(function(reason) { throw reason; @@ -20,12 +20,18 @@ t.step(function() { var canvas = new OffscreenCanvas(100, 50); var ctx = canvas.getContext('2d'); - assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur'}); }); - assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: undefined}); }); - assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: 'foo'}); }); - assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: [1,2,3]}); }); - assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: NaN}); }); - assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: {}}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'gaussianBlur'}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'gaussianBlur', stdDeviation: undefined}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'gaussianBlur', stdDeviation: 'foo'}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'gaussianBlur', stdDeviation: [1,2,3]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'gaussianBlur', stdDeviation: NaN}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'gaussianBlur', stdDeviation: {}}); }); t.done(); }); diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.blur.exceptions.tentative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.blur.exceptions.tentative.worker.js index 9b3fb3c04c..1c27168968 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.blur.exceptions.tentative.worker.js +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.blur.exceptions.tentative.worker.js @@ -1,12 +1,12 @@ // DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. // OffscreenCanvas test in a worker:2d.filter.canvasFilterObject.blur.exceptions.tentative -// Description:Test exceptions on CanvasFilter() blur.object +// Description:Test exceptions on gaussianBlur filter // Note: importScripts("/resources/testharness.js"); importScripts("/html/canvas/resources/canvas-tests.js"); -var t = async_test("Test exceptions on CanvasFilter() blur.object"); +var t = async_test("Test exceptions on gaussianBlur filter"); var t_pass = t.done.bind(t); var t_fail = t.step_func(function(reason) { throw reason; @@ -16,12 +16,18 @@ t.step(function() { var canvas = new OffscreenCanvas(100, 50); var ctx = canvas.getContext('2d'); - assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur'}); }); - assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: undefined}); }); - assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: 'foo'}); }); - assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: [1,2,3]}); }); - assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: NaN}); }); - assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: {}}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'gaussianBlur'}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'gaussianBlur', stdDeviation: undefined}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'gaussianBlur', stdDeviation: 'foo'}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'gaussianBlur', stdDeviation: [1,2,3]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'gaussianBlur', stdDeviation: NaN}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'gaussianBlur', stdDeviation: {}}); }); t.done(); }); done(); diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.colorMatrix.tentative.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.colorMatrix.tentative.html index 242094d9f9..0370c1387b 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.colorMatrix.tentative.html +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.colorMatrix.tentative.html @@ -6,11 +6,11 @@ <script src="/html/canvas/resources/canvas-tests.js"></script> <h1>2d.filter.canvasFilterObject.colorMatrix.tentative</h1> -<p class="desc">Test the functionality of ColorMatrix filters in CanvasFilter objects</p> +<p class="desc">Test the functionality of ColorMatrix filters</p> <script> -var t = async_test("Test the functionality of ColorMatrix filters in CanvasFilter objects"); +var t = async_test("Test the functionality of ColorMatrix filters"); var t_pass = t.done.bind(t); var t_fail = t.step_func(function(reason) { throw reason; @@ -20,38 +20,67 @@ t.step(function() { var canvas = new OffscreenCanvas(100, 50); var ctx = canvas.getContext('2d'); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: undefined}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: 'foo'}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: null}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: [1, 2, 3]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 'a']}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, Infinity]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'colorMatrix', values: undefined}); }); + + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'colorMatrix', values: 'foo'}); }); + + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'colorMatrix', values: null}); }); + + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'colorMatrix', values: [1, 2, 3]}); }); + + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'colorMatrix', + values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 'a']}); }); + + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'colorMatrix', + values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, Infinity]}); }); + ctx.fillStyle = '#f00'; - ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 0}); + ctx.filter = new CanvasFilter( + {name: 'colorMatrix', type: 'hueRotate', values: 0}); ctx.fillRect(0, 0, 100, 50); _assertPixelApprox(canvas, 10,10, 255,0,0,255, 2); - ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 90}); + + ctx.filter = new CanvasFilter( + {name: 'colorMatrix', type: 'hueRotate', values: 90}); ctx.fillRect(0, 0, 100, 50); _assertPixelApprox(canvas, 10,10, 0,91,0,255, 2); - ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 180}); + + ctx.filter = new CanvasFilter( + {name: 'colorMatrix', type: 'hueRotate', values: 180}); ctx.fillRect(0, 0, 100, 50); _assertPixelApprox(canvas, 10,10, 0,109,109,255, 2); - ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 270}); + + ctx.filter = new CanvasFilter( + {name: 'colorMatrix', type: 'hueRotate', values: 270}); ctx.fillRect(0, 0, 100, 50); _assertPixelApprox(canvas, 10,10, 109,18,255,255, 2); - ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'saturate', values: 0.5}); + + ctx.filter = new CanvasFilter( + {name: 'colorMatrix', type: 'saturate', values: 0.5}); ctx.fillRect(0, 0, 100, 50); _assertPixelApprox(canvas, 10,10, 155,27,27,255, 2); + ctx.clearRect(0, 0, 100, 50); - ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'luminanceToAlpha'}); + ctx.filter = new CanvasFilter( + {name: 'colorMatrix', type: 'luminanceToAlpha'}); ctx.fillRect(0, 0, 100, 50); _assertPixelApprox(canvas, 10,10, 0,0,0,54, 2); - ctx.filter = new CanvasFilter({name: 'colorMatrix', values: [ - 0, 0, 0, 0, 0, - 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0 - ]}); + + ctx.filter = new CanvasFilter( + {name: 'colorMatrix', values: [ + 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0 + ]}); ctx.fillRect(0, 0, 50, 25); ctx.fillStyle = '#0f0'; ctx.fillRect(50, 0, 50, 25); diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.colorMatrix.tentative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.colorMatrix.tentative.worker.js index d214e1d836..62e4582efd 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.colorMatrix.tentative.worker.js +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.colorMatrix.tentative.worker.js @@ -1,12 +1,12 @@ // DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. // OffscreenCanvas test in a worker:2d.filter.canvasFilterObject.colorMatrix.tentative -// Description:Test the functionality of ColorMatrix filters in CanvasFilter objects +// Description:Test the functionality of ColorMatrix filters // Note: importScripts("/resources/testharness.js"); importScripts("/html/canvas/resources/canvas-tests.js"); -var t = async_test("Test the functionality of ColorMatrix filters in CanvasFilter objects"); +var t = async_test("Test the functionality of ColorMatrix filters"); var t_pass = t.done.bind(t); var t_fail = t.step_func(function(reason) { throw reason; @@ -16,38 +16,67 @@ t.step(function() { var canvas = new OffscreenCanvas(100, 50); var ctx = canvas.getContext('2d'); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: undefined}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: 'foo'}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: null}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: [1, 2, 3]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 'a']}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'colorMatrix', values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, Infinity]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'colorMatrix', values: undefined}); }); + + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'colorMatrix', values: 'foo'}); }); + + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'colorMatrix', values: null}); }); + + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'colorMatrix', values: [1, 2, 3]}); }); + + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'colorMatrix', + values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 'a']}); }); + + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'colorMatrix', + values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, Infinity]}); }); + ctx.fillStyle = '#f00'; - ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 0}); + ctx.filter = new CanvasFilter( + {name: 'colorMatrix', type: 'hueRotate', values: 0}); ctx.fillRect(0, 0, 100, 50); _assertPixelApprox(canvas, 10,10, 255,0,0,255, 2); - ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 90}); + + ctx.filter = new CanvasFilter( + {name: 'colorMatrix', type: 'hueRotate', values: 90}); ctx.fillRect(0, 0, 100, 50); _assertPixelApprox(canvas, 10,10, 0,91,0,255, 2); - ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 180}); + + ctx.filter = new CanvasFilter( + {name: 'colorMatrix', type: 'hueRotate', values: 180}); ctx.fillRect(0, 0, 100, 50); _assertPixelApprox(canvas, 10,10, 0,109,109,255, 2); - ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 270}); + + ctx.filter = new CanvasFilter( + {name: 'colorMatrix', type: 'hueRotate', values: 270}); ctx.fillRect(0, 0, 100, 50); _assertPixelApprox(canvas, 10,10, 109,18,255,255, 2); - ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'saturate', values: 0.5}); + + ctx.filter = new CanvasFilter( + {name: 'colorMatrix', type: 'saturate', values: 0.5}); ctx.fillRect(0, 0, 100, 50); _assertPixelApprox(canvas, 10,10, 155,27,27,255, 2); + ctx.clearRect(0, 0, 100, 50); - ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'luminanceToAlpha'}); + ctx.filter = new CanvasFilter( + {name: 'colorMatrix', type: 'luminanceToAlpha'}); ctx.fillRect(0, 0, 100, 50); _assertPixelApprox(canvas, 10,10, 0,0,0,54, 2); - ctx.filter = new CanvasFilter({name: 'colorMatrix', values: [ - 0, 0, 0, 0, 0, - 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0 - ]}); + + ctx.filter = new CanvasFilter( + {name: 'colorMatrix', values: [ + 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0 + ]}); ctx.fillRect(0, 0, 50, 25); ctx.fillStyle = '#0f0'; ctx.fillRect(50, 0, 50, 25); diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative-expected.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative-expected.html new file mode 100644 index 0000000000..2b1c1c1c07 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative-expected.html @@ -0,0 +1,50 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.canvasFilterObject.componentTransfer.discrete.tentative</title> +<h1>2d.filter.canvasFilterObject.componentTransfer.discrete.tentative</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with discrete type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement + function getTransformedValue(C, V) { + // Get the right interval + const n = V.length; + const k = C == 1 ? n - 1 : Math.floor(C * n); + return V[k]; + } + + function getColor(inputColor, tableValues) { + const result = [0, 0, 0]; + for (const i in inputColor) { + const C = inputColor[i]/255; + const Cprime = getTransformedValue(C, tableValues[i]); + result[i] = Math.max(0, Math.min(1, Cprime)) * 255; + } + return result; + } + + tableValuesR = [0, 0, 1, 1]; + tableValuesG = [2, 0, 0.5, 3]; + tableValuesB = [1, -1, 5, 0]; + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + let outputColor = getColor( + color, [tableValuesR, tableValuesG, tableValuesB]); + ctx.fillStyle = `rgb(${outputColor[0]}, ${outputColor[1]}, + ${outputColor[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative.html index ff1de6bc9c..491d073efb 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative.html +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative.html @@ -1,42 +1,16 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> -<title>OffscreenCanvas test: 2d.filter.canvasFilterObject.componentTransfer.discrete.tentative</title> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/html/canvas/resources/canvas-tests.js"></script> - +<link rel="match" href="2d.filter.canvasFilterObject.componentTransfer.discrete.tentative-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-500"> +<title>Canvas test: 2d.filter.canvasFilterObject.componentTransfer.discrete.tentative</title> <h1>2d.filter.canvasFilterObject.componentTransfer.discrete.tentative</h1> <p class="desc">Test pixels on CanvasFilter() componentTransfer with discrete type</p> - - +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> <script> -var t = async_test("Test pixels on CanvasFilter() componentTransfer with discrete type"); -var t_pass = t.done.bind(t); -var t_fail = t.step_func(function(reason) { - throw reason; -}); -t.step(function() { - - var canvas = new OffscreenCanvas(100, 50); - var ctx = canvas.getContext('2d'); - - // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement - function getTransformedValue(C, V) { - // Get the right interval - const n = V.length; - const k = C == 1 ? n - 1 : Math.floor(C * n); - return V[k]; - } - - function getColor(inputColor, tableValues) { - const result = [0, 0, 0]; - for (const i in inputColor) { - const C = inputColor[i]/255; - const Cprime = getTransformedValue(C, tableValues[i]); - result[i] = Math.max(0, Math.min(1, Cprime)) * 255; - } - return result; - } + const canvas = new OffscreenCanvas(100, 100); + const ctx = canvas.getContext('2d'); tableValuesR = [0, 0, 1, 1]; tableValuesG = [2, 0, 0.5, 3]; @@ -55,13 +29,12 @@ t.step(function() { [50, 68, 87], ]; - for (const color of inputColors) { - let outputColor = getColor(color, [tableValuesR, tableValuesG, tableValuesB]); + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; - ctx.fillRect(0, 0, 10, 10); - _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2); + ctx.fillRect(i * 10, i * 10, 10, 10); } - t.done(); -}); + const outputCanvas = document.getElementById("canvas"); + outputCanvas.getContext('2d').drawImage(canvas, 0, 0); </script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative.w.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative.w.html new file mode 100644 index 0000000000..d3a999a242 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative.w.html @@ -0,0 +1,54 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<html class="reftest-wait"> +<link rel="match" href="2d.filter.canvasFilterObject.componentTransfer.discrete.tentative-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-500"> +<title>Canvas test: 2d.filter.canvasFilterObject.componentTransfer.discrete.tentative</title> +<h1>2d.filter.canvasFilterObject.componentTransfer.discrete.tentative</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with discrete type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script id='myWorker' type='text/worker'> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(100, 100); + const ctx = canvas.getContext('2d'); + + tableValuesR = [0, 0, 1, 1]; + tableValuesG = [2, 0, 0.5, 3]; + tableValuesB = [1, -1, 5, 0]; + ctx.filter = new CanvasFilter({name: 'componentTransfer', + funcR: {type: 'discrete', tableValues: tableValuesR}, + funcG: {type: 'discrete', tableValues: tableValuesG}, + funcB: {type: 'discrete', tableValues: tableValuesB}, + }); + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; +</script> +<script> + const blob = new Blob([document.getElementById('myWorker').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCtx = document.getElementById("canvas").getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + document.documentElement.classList.remove("reftest-wait"); + }); + worker.postMessage(null); +</script> +</html> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative.worker.js deleted file mode 100644 index 0e68f4899f..0000000000 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.discrete.tentative.worker.js +++ /dev/null @@ -1,62 +0,0 @@ -// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -// OffscreenCanvas test in a worker:2d.filter.canvasFilterObject.componentTransfer.discrete.tentative -// Description:Test pixels on CanvasFilter() componentTransfer with discrete type -// Note: - -importScripts("/resources/testharness.js"); -importScripts("/html/canvas/resources/canvas-tests.js"); - -var t = async_test("Test pixels on CanvasFilter() componentTransfer with discrete type"); -var t_pass = t.done.bind(t); -var t_fail = t.step_func(function(reason) { - throw reason; -}); -t.step(function() { - - var canvas = new OffscreenCanvas(100, 50); - var ctx = canvas.getContext('2d'); - - // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement - function getTransformedValue(C, V) { - // Get the right interval - const n = V.length; - const k = C == 1 ? n - 1 : Math.floor(C * n); - return V[k]; - } - - function getColor(inputColor, tableValues) { - const result = [0, 0, 0]; - for (const i in inputColor) { - const C = inputColor[i]/255; - const Cprime = getTransformedValue(C, tableValues[i]); - result[i] = Math.max(0, Math.min(1, Cprime)) * 255; - } - return result; - } - - tableValuesR = [0, 0, 1, 1]; - tableValuesG = [2, 0, 0.5, 3]; - tableValuesB = [1, -1, 5, 0]; - ctx.filter = new CanvasFilter({name: 'componentTransfer', - funcR: {type: 'discrete', tableValues: tableValuesR}, - funcG: {type: 'discrete', tableValues: tableValuesG}, - funcB: {type: 'discrete', tableValues: tableValuesB}, - }); - - const inputColors = [ - [255, 255, 255], - [0, 0, 0], - [127, 0, 34], - [252, 186, 3], - [50, 68, 87], - ]; - - for (const color of inputColors) { - let outputColor = getColor(color, [tableValuesR, tableValuesG, tableValuesB]); - ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; - ctx.fillRect(0, 0, 10, 10); - _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2); - } - t.done(); -}); -done(); diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative-expected.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative-expected.html new file mode 100644 index 0000000000..5adc9f53e2 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative-expected.html @@ -0,0 +1,44 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.canvasFilterObject.componentTransfer.gamma.tentative</title> +<h1>2d.filter.canvasFilterObject.componentTransfer.gamma.tentative</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with gamma type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement + function getColor(inputColor, amplitude, exponent, offset) { + return [ + Math.max(0, Math.min(1, Math.pow(inputColor[0]/255, + exponent[0]) * amplitude[0] + offset[0])) * 255, + Math.max(0, Math.min(1, Math.pow(inputColor[1]/255, + exponent[1]) * amplitude[1] + offset[1])) * 255, + Math.max(0, Math.min(1, Math.pow(inputColor[2]/255, + exponent[2]) * amplitude[2] + offset[2])) * 255, + ]; + } + + const amplitudes = [2, 1.1, 0.5]; + const exponents = [5, 3, 1]; + const offsets = [0.25, 0, 0.5]; + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + let outputColor = getColor(color, amplitudes, exponents, offsets); + ctx.fillStyle = `rgb(${outputColor[0]}, ${outputColor[1]}, + ${outputColor[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative.html index 64c30fc417..b262f3b1d3 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative.html +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative.html @@ -1,41 +1,27 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> -<title>OffscreenCanvas test: 2d.filter.canvasFilterObject.componentTransfer.gamma.tentative</title> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/html/canvas/resources/canvas-tests.js"></script> - +<link rel="match" href="2d.filter.canvasFilterObject.componentTransfer.gamma.tentative-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-500"> +<title>Canvas test: 2d.filter.canvasFilterObject.componentTransfer.gamma.tentative</title> <h1>2d.filter.canvasFilterObject.componentTransfer.gamma.tentative</h1> <p class="desc">Test pixels on CanvasFilter() componentTransfer with gamma type</p> - - +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> <script> -var t = async_test("Test pixels on CanvasFilter() componentTransfer with gamma type"); -var t_pass = t.done.bind(t); -var t_fail = t.step_func(function(reason) { - throw reason; -}); -t.step(function() { - - var canvas = new OffscreenCanvas(100, 50); - var ctx = canvas.getContext('2d'); - - // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement - function getColor(inputColor, amplitude, exponent, offset) { - return [ - Math.max(0, Math.min(1, Math.pow(inputColor[0]/255, exponent[0]) * amplitude[0] + offset[0])) * 255, - Math.max(0, Math.min(1, Math.pow(inputColor[1]/255, exponent[1]) * amplitude[1] + offset[1])) * 255, - Math.max(0, Math.min(1, Math.pow(inputColor[2]/255, exponent[2]) * amplitude[2] + offset[2])) * 255, - ]; - } + const canvas = new OffscreenCanvas(100, 100); + const ctx = canvas.getContext('2d'); const amplitudes = [2, 1.1, 0.5]; const exponents = [5, 3, 1]; const offsets = [0.25, 0, 0.5]; ctx.filter = new CanvasFilter({name: 'componentTransfer', - funcR: {type: 'gamma', amplitude: amplitudes[0], exponent: exponents[0], offset: offsets[0]}, - funcG: {type: 'gamma', amplitude: amplitudes[1], exponent: exponents[1], offset: offsets[1]}, - funcB: {type: 'gamma', amplitude: amplitudes[2], exponent: exponents[2], offset: offsets[2]}, + funcR: {type: 'gamma', amplitude: amplitudes[0], + exponent: exponents[0], offset: offsets[0]}, + funcG: {type: 'gamma', amplitude: amplitudes[1], + exponent: exponents[1], offset: offsets[1]}, + funcB: {type: 'gamma', amplitude: amplitudes[2], + exponent: exponents[2], offset: offsets[2]}, }); const inputColors = [ @@ -46,13 +32,12 @@ t.step(function() { [50, 68, 87], ]; - for (const color of inputColors) { - let outputColor = getColor(color, amplitudes, exponents, offsets); + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; - ctx.fillRect(0, 0, 10, 10); - _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2); + ctx.fillRect(i * 10, i * 10, 10, 10); } - t.done(); -}); + const outputCanvas = document.getElementById("canvas"); + outputCanvas.getContext('2d').drawImage(canvas, 0, 0); </script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative.w.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative.w.html new file mode 100644 index 0000000000..1fe346eacf --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative.w.html @@ -0,0 +1,57 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<html class="reftest-wait"> +<link rel="match" href="2d.filter.canvasFilterObject.componentTransfer.gamma.tentative-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-500"> +<title>Canvas test: 2d.filter.canvasFilterObject.componentTransfer.gamma.tentative</title> +<h1>2d.filter.canvasFilterObject.componentTransfer.gamma.tentative</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with gamma type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script id='myWorker' type='text/worker'> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(100, 100); + const ctx = canvas.getContext('2d'); + + const amplitudes = [2, 1.1, 0.5]; + const exponents = [5, 3, 1]; + const offsets = [0.25, 0, 0.5]; + ctx.filter = new CanvasFilter({name: 'componentTransfer', + funcR: {type: 'gamma', amplitude: amplitudes[0], + exponent: exponents[0], offset: offsets[0]}, + funcG: {type: 'gamma', amplitude: amplitudes[1], + exponent: exponents[1], offset: offsets[1]}, + funcB: {type: 'gamma', amplitude: amplitudes[2], + exponent: exponents[2], offset: offsets[2]}, + }); + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; +</script> +<script> + const blob = new Blob([document.getElementById('myWorker').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCtx = document.getElementById("canvas").getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + document.documentElement.classList.remove("reftest-wait"); + }); + worker.postMessage(null); +</script> +</html> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative.worker.js deleted file mode 100644 index d59bc699df..0000000000 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.gamma.tentative.worker.js +++ /dev/null @@ -1,53 +0,0 @@ -// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -// OffscreenCanvas test in a worker:2d.filter.canvasFilterObject.componentTransfer.gamma.tentative -// Description:Test pixels on CanvasFilter() componentTransfer with gamma type -// Note: - -importScripts("/resources/testharness.js"); -importScripts("/html/canvas/resources/canvas-tests.js"); - -var t = async_test("Test pixels on CanvasFilter() componentTransfer with gamma type"); -var t_pass = t.done.bind(t); -var t_fail = t.step_func(function(reason) { - throw reason; -}); -t.step(function() { - - var canvas = new OffscreenCanvas(100, 50); - var ctx = canvas.getContext('2d'); - - // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement - function getColor(inputColor, amplitude, exponent, offset) { - return [ - Math.max(0, Math.min(1, Math.pow(inputColor[0]/255, exponent[0]) * amplitude[0] + offset[0])) * 255, - Math.max(0, Math.min(1, Math.pow(inputColor[1]/255, exponent[1]) * amplitude[1] + offset[1])) * 255, - Math.max(0, Math.min(1, Math.pow(inputColor[2]/255, exponent[2]) * amplitude[2] + offset[2])) * 255, - ]; - } - - const amplitudes = [2, 1.1, 0.5]; - const exponents = [5, 3, 1]; - const offsets = [0.25, 0, 0.5]; - ctx.filter = new CanvasFilter({name: 'componentTransfer', - funcR: {type: 'gamma', amplitude: amplitudes[0], exponent: exponents[0], offset: offsets[0]}, - funcG: {type: 'gamma', amplitude: amplitudes[1], exponent: exponents[1], offset: offsets[1]}, - funcB: {type: 'gamma', amplitude: amplitudes[2], exponent: exponents[2], offset: offsets[2]}, - }); - - const inputColors = [ - [255, 255, 255], - [0, 0, 0], - [127, 0, 34], - [252, 186, 3], - [50, 68, 87], - ]; - - for (const color of inputColors) { - let outputColor = getColor(color, amplitudes, exponents, offsets); - ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; - ctx.fillRect(0, 0, 10, 10); - _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2); - } - t.done(); -}); -done(); diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative-expected.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative-expected.html new file mode 100644 index 0000000000..895d531206 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative-expected.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.canvasFilterObject.componentTransfer.identity.tentative</title> +<h1>2d.filter.canvasFilterObject.componentTransfer.identity.tentative</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with identity type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + let outputColor = inputColors[i]; + ctx.fillStyle = `rgb(${outputColor[0]}, ${outputColor[1]}, + ${outputColor[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative.html index e0d628952e..26b6e4c702 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative.html +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative.html @@ -1,24 +1,15 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> -<title>OffscreenCanvas test: 2d.filter.canvasFilterObject.componentTransfer.identity.tentative</title> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/html/canvas/resources/canvas-tests.js"></script> - +<link rel="match" href="2d.filter.canvasFilterObject.componentTransfer.identity.tentative-expected.html"> +<title>Canvas test: 2d.filter.canvasFilterObject.componentTransfer.identity.tentative</title> <h1>2d.filter.canvasFilterObject.componentTransfer.identity.tentative</h1> <p class="desc">Test pixels on CanvasFilter() componentTransfer with identity type</p> - - +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> <script> -var t = async_test("Test pixels on CanvasFilter() componentTransfer with identity type"); -var t_pass = t.done.bind(t); -var t_fail = t.step_func(function(reason) { - throw reason; -}); -t.step(function() { - - var canvas = new OffscreenCanvas(100, 50); - var ctx = canvas.getContext('2d'); + const canvas = new OffscreenCanvas(100, 100); + const ctx = canvas.getContext('2d'); ctx.filter = new CanvasFilter({name: 'componentTransfer', funcR: {type: 'identity'}, @@ -34,12 +25,12 @@ t.step(function() { [50, 68, 87], ]; - for (const color of inputColors) { - ctx.fillStyle = `rgba(${color[0]}, ${color[1]}, ${color[2]}, 1)`, - ctx.fillRect(0, 0, 10, 10); - _assertPixel(canvas, 5, 5, color[0],color[1],color[2],255); + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); } - t.done(); -}); + const outputCanvas = document.getElementById("canvas"); + outputCanvas.getContext('2d').drawImage(canvas, 0, 0); </script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative.w.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative.w.html new file mode 100644 index 0000000000..d2216d1647 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative.w.html @@ -0,0 +1,50 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<html class="reftest-wait"> +<link rel="match" href="2d.filter.canvasFilterObject.componentTransfer.identity.tentative-expected.html"> +<title>Canvas test: 2d.filter.canvasFilterObject.componentTransfer.identity.tentative</title> +<h1>2d.filter.canvasFilterObject.componentTransfer.identity.tentative</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with identity type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script id='myWorker' type='text/worker'> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(100, 100); + const ctx = canvas.getContext('2d'); + + ctx.filter = new CanvasFilter({name: 'componentTransfer', + funcR: {type: 'identity'}, + funcG: {type: 'identity'}, + funcB: {type: 'identity'}, + }); + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; +</script> +<script> + const blob = new Blob([document.getElementById('myWorker').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCtx = document.getElementById("canvas").getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + document.documentElement.classList.remove("reftest-wait"); + }); + worker.postMessage(null); +</script> +</html> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative.worker.js deleted file mode 100644 index 1b714b58ff..0000000000 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.identity.tentative.worker.js +++ /dev/null @@ -1,40 +0,0 @@ -// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -// OffscreenCanvas test in a worker:2d.filter.canvasFilterObject.componentTransfer.identity.tentative -// Description:Test pixels on CanvasFilter() componentTransfer with identity type -// Note: - -importScripts("/resources/testharness.js"); -importScripts("/html/canvas/resources/canvas-tests.js"); - -var t = async_test("Test pixels on CanvasFilter() componentTransfer with identity type"); -var t_pass = t.done.bind(t); -var t_fail = t.step_func(function(reason) { - throw reason; -}); -t.step(function() { - - var canvas = new OffscreenCanvas(100, 50); - var ctx = canvas.getContext('2d'); - - ctx.filter = new CanvasFilter({name: 'componentTransfer', - funcR: {type: 'identity'}, - funcG: {type: 'identity'}, - funcB: {type: 'identity'}, - }); - - const inputColors = [ - [255, 255, 255], - [0, 0, 0], - [127, 0, 34], - [252, 186, 3], - [50, 68, 87], - ]; - - for (const color of inputColors) { - ctx.fillStyle = `rgba(${color[0]}, ${color[1]}, ${color[2]}, 1)`, - ctx.fillRect(0, 0, 10, 10); - _assertPixel(canvas, 5, 5, color[0],color[1],color[2],255); - } - t.done(); -}); -done(); diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative-expected.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative-expected.html new file mode 100644 index 0000000000..c4ad790d56 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative-expected.html @@ -0,0 +1,43 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.canvasFilterObject.componentTransfer.linear.tentative</title> +<h1>2d.filter.canvasFilterObject.componentTransfer.linear.tentative</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with linear type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement + function getColor(inputColor, slopes, intercepts) { + return [ + Math.max(0, Math.min(1, + inputColor[0]/255 * slopes[0] + intercepts[0])) * 255, + Math.max(0, Math.min(1, + inputColor[1]/255 * slopes[1] + intercepts[1])) * 255, + Math.max(0, Math.min(1, + inputColor[2]/255 * slopes[2] + intercepts[2])) * 255, + ]; + } + + const slopes = [0.5, 1.2, -0.2]; + const intercepts = [0.25, 0, 0.5]; + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + let outputColor = getColor(color, slopes, intercepts); + ctx.fillStyle = `rgb(${outputColor[0]}, ${outputColor[1]}, + ${outputColor[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative.html index adbe557fd9..3fc3bd9eec 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative.html +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative.html @@ -1,33 +1,16 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> -<title>OffscreenCanvas test: 2d.filter.canvasFilterObject.componentTransfer.linear.tentative</title> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/html/canvas/resources/canvas-tests.js"></script> - +<link rel="match" href="2d.filter.canvasFilterObject.componentTransfer.linear.tentative-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-500"> +<title>Canvas test: 2d.filter.canvasFilterObject.componentTransfer.linear.tentative</title> <h1>2d.filter.canvasFilterObject.componentTransfer.linear.tentative</h1> <p class="desc">Test pixels on CanvasFilter() componentTransfer with linear type</p> - - +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> <script> -var t = async_test("Test pixels on CanvasFilter() componentTransfer with linear type"); -var t_pass = t.done.bind(t); -var t_fail = t.step_func(function(reason) { - throw reason; -}); -t.step(function() { - - var canvas = new OffscreenCanvas(100, 50); - var ctx = canvas.getContext('2d'); - - // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement - function getColor(inputColor, slopes, intercepts) { - return [ - Math.max(0, Math.min(1, inputColor[0]/255 * slopes[0] + intercepts[0])) * 255, - Math.max(0, Math.min(1, inputColor[1]/255 * slopes[1] + intercepts[1])) * 255, - Math.max(0, Math.min(1, inputColor[2]/255 * slopes[2] + intercepts[2])) * 255, - ]; - } + const canvas = new OffscreenCanvas(100, 100); + const ctx = canvas.getContext('2d'); const slopes = [0.5, 1.2, -0.2]; const intercepts = [0.25, 0, 0.5]; @@ -45,13 +28,12 @@ t.step(function() { [50, 68, 87], ]; - for (const color of inputColors) { - let outputColor = getColor(color, slopes, intercepts); + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; - ctx.fillRect(0, 0, 10, 10); - _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2); + ctx.fillRect(i * 10, i * 10, 10, 10); } - t.done(); -}); + const outputCanvas = document.getElementById("canvas"); + outputCanvas.getContext('2d').drawImage(canvas, 0, 0); </script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative.w.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative.w.html new file mode 100644 index 0000000000..054dbce929 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative.w.html @@ -0,0 +1,53 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<html class="reftest-wait"> +<link rel="match" href="2d.filter.canvasFilterObject.componentTransfer.linear.tentative-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-500"> +<title>Canvas test: 2d.filter.canvasFilterObject.componentTransfer.linear.tentative</title> +<h1>2d.filter.canvasFilterObject.componentTransfer.linear.tentative</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with linear type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script id='myWorker' type='text/worker'> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(100, 100); + const ctx = canvas.getContext('2d'); + + const slopes = [0.5, 1.2, -0.2]; + const intercepts = [0.25, 0, 0.5]; + ctx.filter = new CanvasFilter({name: 'componentTransfer', + funcR: {type: 'linear', slope: slopes[0], intercept: intercepts[0]}, + funcG: {type: 'linear', slope: slopes[1], intercept: intercepts[1]}, + funcB: {type: 'linear', slope: slopes[2], intercept: intercepts[2]}, + }); + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; +</script> +<script> + const blob = new Blob([document.getElementById('myWorker').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCtx = document.getElementById("canvas").getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + document.documentElement.classList.remove("reftest-wait"); + }); + worker.postMessage(null); +</script> +</html> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative.worker.js deleted file mode 100644 index fb2e01876f..0000000000 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.linear.tentative.worker.js +++ /dev/null @@ -1,52 +0,0 @@ -// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -// OffscreenCanvas test in a worker:2d.filter.canvasFilterObject.componentTransfer.linear.tentative -// Description:Test pixels on CanvasFilter() componentTransfer with linear type -// Note: - -importScripts("/resources/testharness.js"); -importScripts("/html/canvas/resources/canvas-tests.js"); - -var t = async_test("Test pixels on CanvasFilter() componentTransfer with linear type"); -var t_pass = t.done.bind(t); -var t_fail = t.step_func(function(reason) { - throw reason; -}); -t.step(function() { - - var canvas = new OffscreenCanvas(100, 50); - var ctx = canvas.getContext('2d'); - - // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement - function getColor(inputColor, slopes, intercepts) { - return [ - Math.max(0, Math.min(1, inputColor[0]/255 * slopes[0] + intercepts[0])) * 255, - Math.max(0, Math.min(1, inputColor[1]/255 * slopes[1] + intercepts[1])) * 255, - Math.max(0, Math.min(1, inputColor[2]/255 * slopes[2] + intercepts[2])) * 255, - ]; - } - - const slopes = [0.5, 1.2, -0.2]; - const intercepts = [0.25, 0, 0.5]; - ctx.filter = new CanvasFilter({name: 'componentTransfer', - funcR: {type: 'linear', slope: slopes[0], intercept: intercepts[0]}, - funcG: {type: 'linear', slope: slopes[1], intercept: intercepts[1]}, - funcB: {type: 'linear', slope: slopes[2], intercept: intercepts[2]}, - }); - - const inputColors = [ - [255, 255, 255], - [0, 0, 0], - [127, 0, 34], - [252, 186, 3], - [50, 68, 87], - ]; - - for (const color of inputColors) { - let outputColor = getColor(color, slopes, intercepts); - ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; - ctx.fillRect(0, 0, 10, 10); - _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2); - } - t.done(); -}); -done(); diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative-expected.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative-expected.html new file mode 100644 index 0000000000..29e250614c --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative-expected.html @@ -0,0 +1,51 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.canvasFilterObject.componentTransfer.table.tentative</title> +<h1>2d.filter.canvasFilterObject.componentTransfer.table.tentative</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with table type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement + function getTransformedValue(C, V) { + // Get the right interval + const n = V.length - 1; + const k = C == 1 ? n - 1 : Math.floor(C * n); + return V[k] + (C - k/n) * n * (V[k + 1] - V[k]); + } + + function getColor(inputColor, tableValues) { + const result = [0, 0, 0]; + for (const i in inputColor) { + const C = inputColor[i]/255; + const Cprime = getTransformedValue(C, tableValues[i]); + result[i] = Math.max(0, Math.min(1, Cprime)) * 255; + } + return result; + } + + tableValuesR = [0, 0, 1, 1]; + tableValuesG = [2, 0, 0.5, 3]; + tableValuesB = [1, -1, 5, 0]; + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + let outputColor = getColor( + color, [tableValuesR, tableValuesG, tableValuesB]); + ctx.fillStyle = `rgb(${outputColor[0]}, ${outputColor[1]}, + ${outputColor[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative.html index 47048b68a1..ef2da126eb 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative.html +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative.html @@ -1,42 +1,16 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> -<title>OffscreenCanvas test: 2d.filter.canvasFilterObject.componentTransfer.table.tentative</title> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/html/canvas/resources/canvas-tests.js"></script> - +<link rel="match" href="2d.filter.canvasFilterObject.componentTransfer.table.tentative-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-500"> +<title>Canvas test: 2d.filter.canvasFilterObject.componentTransfer.table.tentative</title> <h1>2d.filter.canvasFilterObject.componentTransfer.table.tentative</h1> <p class="desc">Test pixels on CanvasFilter() componentTransfer with table type</p> - - +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> <script> -var t = async_test("Test pixels on CanvasFilter() componentTransfer with table type"); -var t_pass = t.done.bind(t); -var t_fail = t.step_func(function(reason) { - throw reason; -}); -t.step(function() { - - var canvas = new OffscreenCanvas(100, 50); - var ctx = canvas.getContext('2d'); - - // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement - function getTransformedValue(C, V) { - // Get the right interval - const n = V.length - 1; - const k = C == 1 ? n - 1 : Math.floor(C * n); - return V[k] + (C - k/n) * n * (V[k + 1] - V[k]); - } - - function getColor(inputColor, tableValues) { - const result = [0, 0, 0]; - for (const i in inputColor) { - const C = inputColor[i]/255; - const Cprime = getTransformedValue(C, tableValues[i]); - result[i] = Math.max(0, Math.min(1, Cprime)) * 255; - } - return result; - } + const canvas = new OffscreenCanvas(100, 100); + const ctx = canvas.getContext('2d'); tableValuesR = [0, 0, 1, 1]; tableValuesG = [2, 0, 0.5, 3]; @@ -55,13 +29,12 @@ t.step(function() { [50, 68, 87], ]; - for (const color of inputColors) { - let outputColor = getColor(color, [tableValuesR, tableValuesG, tableValuesB]); + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; - ctx.fillRect(0, 0, 10, 10); - _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2); + ctx.fillRect(i * 10, i * 10, 10, 10); } - t.done(); -}); + const outputCanvas = document.getElementById("canvas"); + outputCanvas.getContext('2d').drawImage(canvas, 0, 0); </script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative.w.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative.w.html new file mode 100644 index 0000000000..f39723da8e --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative.w.html @@ -0,0 +1,54 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<html class="reftest-wait"> +<link rel="match" href="2d.filter.canvasFilterObject.componentTransfer.table.tentative-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-500"> +<title>Canvas test: 2d.filter.canvasFilterObject.componentTransfer.table.tentative</title> +<h1>2d.filter.canvasFilterObject.componentTransfer.table.tentative</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with table type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script id='myWorker' type='text/worker'> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(100, 100); + const ctx = canvas.getContext('2d'); + + tableValuesR = [0, 0, 1, 1]; + tableValuesG = [2, 0, 0.5, 3]; + tableValuesB = [1, -1, 5, 0]; + ctx.filter = new CanvasFilter({name: 'componentTransfer', + funcR: {type: 'table', tableValues: tableValuesR}, + funcG: {type: 'table', tableValues: tableValuesG}, + funcB: {type: 'table', tableValues: tableValuesB}, + }); + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; +</script> +<script> + const blob = new Blob([document.getElementById('myWorker').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCtx = document.getElementById("canvas").getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + document.documentElement.classList.remove("reftest-wait"); + }); + worker.postMessage(null); +</script> +</html> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative.worker.js deleted file mode 100644 index 0799e73a58..0000000000 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.componentTransfer.table.tentative.worker.js +++ /dev/null @@ -1,62 +0,0 @@ -// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -// OffscreenCanvas test in a worker:2d.filter.canvasFilterObject.componentTransfer.table.tentative -// Description:Test pixels on CanvasFilter() componentTransfer with table type -// Note: - -importScripts("/resources/testharness.js"); -importScripts("/html/canvas/resources/canvas-tests.js"); - -var t = async_test("Test pixels on CanvasFilter() componentTransfer with table type"); -var t_pass = t.done.bind(t); -var t_fail = t.step_func(function(reason) { - throw reason; -}); -t.step(function() { - - var canvas = new OffscreenCanvas(100, 50); - var ctx = canvas.getContext('2d'); - - // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement - function getTransformedValue(C, V) { - // Get the right interval - const n = V.length - 1; - const k = C == 1 ? n - 1 : Math.floor(C * n); - return V[k] + (C - k/n) * n * (V[k + 1] - V[k]); - } - - function getColor(inputColor, tableValues) { - const result = [0, 0, 0]; - for (const i in inputColor) { - const C = inputColor[i]/255; - const Cprime = getTransformedValue(C, tableValues[i]); - result[i] = Math.max(0, Math.min(1, Cprime)) * 255; - } - return result; - } - - tableValuesR = [0, 0, 1, 1]; - tableValuesG = [2, 0, 0.5, 3]; - tableValuesB = [1, -1, 5, 0]; - ctx.filter = new CanvasFilter({name: 'componentTransfer', - funcR: {type: 'table', tableValues: tableValuesR}, - funcG: {type: 'table', tableValues: tableValuesG}, - funcB: {type: 'table', tableValues: tableValuesB}, - }); - - const inputColors = [ - [255, 255, 255], - [0, 0, 0], - [127, 0, 34], - [252, 186, 3], - [50, 68, 87], - ]; - - for (const color of inputColors) { - let outputColor = getColor(color, [tableValuesR, tableValuesG, tableValuesB]); - ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; - ctx.fillRect(0, 0, 10, 10); - _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2); - } - t.done(); -}); -done(); diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative.html index 301d11f888..08f8860e99 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative.html +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative.html @@ -20,23 +20,39 @@ t.step(function() { var canvas = new OffscreenCanvas(100, 50); var ctx = canvas.getContext('2d'); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix'}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', divisor: 2}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: null}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: 1}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 0], [0]]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 'a'], [0]]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 0], 0]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 0], [0, Infinity]]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: []}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [1]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [1, 2, 3, 4]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[], []]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 2], []]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[], [1, 2]]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix'}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', divisor: 2}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: null}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: 1}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [[1, 0], [0]]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [[1, 'a'], [0]]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [[1, 0], 0]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [[1, 0], [0, Infinity]]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: []}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [1]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [1, 2, 3, 4]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [[], []]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [[1, 2], []]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [[], [1, 2]]}); }); // This should not throw an error - ctx.filter = new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[]]}); - ctx.filter = new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1]]}); + ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [[]]}); + ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [[1]]}); t.done(); }); diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative.worker.js index b4ce4d76b2..105ed67a75 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative.worker.js +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative.worker.js @@ -16,23 +16,39 @@ t.step(function() { var canvas = new OffscreenCanvas(100, 50); var ctx = canvas.getContext('2d'); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix'}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', divisor: 2}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: null}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: 1}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 0], [0]]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 'a'], [0]]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 0], 0]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 0], [0, Infinity]]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: []}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [1]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [1, 2, 3, 4]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[], []]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 2], []]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[], [1, 2]]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix'}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', divisor: 2}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: null}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: 1}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [[1, 0], [0]]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [[1, 'a'], [0]]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [[1, 0], 0]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [[1, 0], [0, Infinity]]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: []}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [1]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [1, 2, 3, 4]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [[], []]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [[1, 2], []]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [[], [1, 2]]}); }); // This should not throw an error - ctx.filter = new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[]]}); - ctx.filter = new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1]]}); + ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [[]]}); + ctx.filter = new CanvasFilter( + {name: 'convolveMatrix', kernelMatrix: [[1]]}); t.done(); }); done(); diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.exceptions.tentative.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.exceptions.tentative.html index 3e55e97e54..cdd501ba8e 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.exceptions.tentative.html +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.exceptions.tentative.html @@ -20,104 +20,250 @@ t.step(function() { var canvas = new OffscreenCanvas(100, 50); var ctx = canvas.getContext('2d'); + // Should not throw an error. // dx - _assert(new CanvasFilter({name: 'dropShadow', dx: 10}), "new CanvasFilter({name: 'dropShadow', dx: 10})"); - _assert(new CanvasFilter({name: 'dropShadow', dx: -1}), "new CanvasFilter({name: 'dropShadow', dx: -1})"); - _assert(new CanvasFilter({name: 'dropShadow', dx: 0.5}), "new CanvasFilter({name: 'dropShadow', dx: 0.5})"); - _assert(new CanvasFilter({name: 'dropShadow', dx: null}), "new CanvasFilter({name: 'dropShadow', dx: null})"); - _assert(new CanvasFilter({name: 'dropShadow', dx: true}), "new CanvasFilter({name: 'dropShadow', dx: true})"); - _assert(new CanvasFilter({name: 'dropShadow', dx: false}), "new CanvasFilter({name: 'dropShadow', dx: false})"); - _assert(new CanvasFilter({name: 'dropShadow', dx: []}), "new CanvasFilter({name: 'dropShadow', dx: []})"); - _assert(new CanvasFilter({name: 'dropShadow', dx: [20]}), "new CanvasFilter({name: 'dropShadow', dx: [\""+(20)+"\"]})"); - _assert(new CanvasFilter({name: 'dropShadow', dx: '30'}), "new CanvasFilter({name: 'dropShadow', dx: '30'})"); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: 10}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: -1}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: 0.5}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: null}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: true}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: false}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: []}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: [20]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: '30'}); // dy - _assert(new CanvasFilter({name: 'dropShadow', dy: 10}), "new CanvasFilter({name: 'dropShadow', dy: 10})"); - _assert(new CanvasFilter({name: 'dropShadow', dy: -1}), "new CanvasFilter({name: 'dropShadow', dy: -1})"); - _assert(new CanvasFilter({name: 'dropShadow', dy: 0.5}), "new CanvasFilter({name: 'dropShadow', dy: 0.5})"); - _assert(new CanvasFilter({name: 'dropShadow', dy: null}), "new CanvasFilter({name: 'dropShadow', dy: null})"); - _assert(new CanvasFilter({name: 'dropShadow', dy: true}), "new CanvasFilter({name: 'dropShadow', dy: true})"); - _assert(new CanvasFilter({name: 'dropShadow', dy: false}), "new CanvasFilter({name: 'dropShadow', dy: false})"); - _assert(new CanvasFilter({name: 'dropShadow', dy: []}), "new CanvasFilter({name: 'dropShadow', dy: []})"); - _assert(new CanvasFilter({name: 'dropShadow', dy: [20]}), "new CanvasFilter({name: 'dropShadow', dy: [\""+(20)+"\"]})"); - _assert(new CanvasFilter({name: 'dropShadow', dy: '30'}), "new CanvasFilter({name: 'dropShadow', dy: '30'})"); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: 10}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: -1}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: 0.5}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: null}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: true}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: false}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: []}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: [20]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: '30'}); // floodOpacity - _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: 10}), "new CanvasFilter({name: 'dropShadow', floodOpacity: 10})"); - _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: -1}), "new CanvasFilter({name: 'dropShadow', floodOpacity: -1})"); - _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: 0.5}), "new CanvasFilter({name: 'dropShadow', floodOpacity: 0.5})"); - _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: null}), "new CanvasFilter({name: 'dropShadow', floodOpacity: null})"); - _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: true}), "new CanvasFilter({name: 'dropShadow', floodOpacity: true})"); - _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: false}), "new CanvasFilter({name: 'dropShadow', floodOpacity: false})"); - _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: []}), "new CanvasFilter({name: 'dropShadow', floodOpacity: []})"); - _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: [20]}), "new CanvasFilter({name: 'dropShadow', floodOpacity: [\""+(20)+"\"]})"); - _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: '30'}), "new CanvasFilter({name: 'dropShadow', floodOpacity: '30'})"); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: 10}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: -1}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: 0.5}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: null}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: true}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: false}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: []}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: [20]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: '30'}); + // dx + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: 10}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: -1}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: 0.5}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: null}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: true}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: false}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: []}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: [20]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: '30'}); + // dy + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: 10}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: -1}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: 0.5}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: null}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: true}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: false}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: []}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: [20]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: '30'}); + // floodOpacity + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: 10}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: -1}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: 0.5}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: null}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: true}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: false}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: []}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: [20]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: '30'}); // stdDeviation - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: 10}), "new CanvasFilter({name: 'dropShadow', stdDeviation: 10})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: -1}), "new CanvasFilter({name: 'dropShadow', stdDeviation: -1})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: 0.5}), "new CanvasFilter({name: 'dropShadow', stdDeviation: 0.5})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: null}), "new CanvasFilter({name: 'dropShadow', stdDeviation: null})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: true}), "new CanvasFilter({name: 'dropShadow', stdDeviation: true})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: false}), "new CanvasFilter({name: 'dropShadow', stdDeviation: false})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: []}), "new CanvasFilter({name: 'dropShadow', stdDeviation: []})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: [20]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: [\""+(20)+"\"]})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: '30'}), "new CanvasFilter({name: 'dropShadow', stdDeviation: '30'})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: [10, -1]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: [10, -1]})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: [0.5, null]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: [0.5, null]})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: [true, false]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: [true, false]})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: [[], [20]]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: [[], [\""+(20)+"\"]]})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: ['30', ['40']]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: ['30', ['40']]})"); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: 10}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: -1}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: 0.5}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: null}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: true}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: false}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: []}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [20]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: '30'}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [10, -1]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [0.5, null]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [true, false]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [[], [20]]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: ['30', ['40']]}); // floodColor - _assert(new CanvasFilter({name: 'dropShadow', floodColor: 'red'}), "new CanvasFilter({name: 'dropShadow', floodColor: 'red'})"); - _assert(new CanvasFilter({name: 'dropShadow', floodColor: 'canvas'}), "new CanvasFilter({name: 'dropShadow', floodColor: 'canvas'})"); - _assert(new CanvasFilter({name: 'dropShadow', floodColor: 'rgba(4, -3, 0.5, 1)'}), "new CanvasFilter({name: 'dropShadow', floodColor: 'rgba(4, -3, 0.5, 1)'})"); - _assert(new CanvasFilter({name: 'dropShadow', floodColor: '#aabbccdd'}), "new CanvasFilter({name: 'dropShadow', floodColor: '#aabbccdd'})"); - _assert(new CanvasFilter({name: 'dropShadow', floodColor: '#abcd'}), "new CanvasFilter({name: 'dropShadow', floodColor: '#abcd'})"); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: 'red'}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: 'canvas'}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: 'rgba(4, -3, 0.5, 1)'}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: '#aabbccdd'}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: '#abcd'}); + // Should throw a TypeError. // dx - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: NaN}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: Infinity}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: -Infinity}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: undefined}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: 'test'}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: {}}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: [1, 2]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: NaN}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: Infinity}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: -Infinity}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: undefined}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: 'test'}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: {}}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: [1, 2]}); }); // dy - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: NaN}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: Infinity}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: -Infinity}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: undefined}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: 'test'}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: {}}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: [1, 2]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: NaN}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: Infinity}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: -Infinity}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: undefined}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: 'test'}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: {}}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: [1, 2]}); }); // floodOpacity - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: NaN}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: Infinity}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: -Infinity}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: undefined}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: 'test'}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: {}}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: [1, 2]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: NaN}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: Infinity}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: -Infinity}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: undefined}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: 'test'}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: {}}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: [1, 2]}); }); // stdDeviation - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: NaN}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: Infinity}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: -Infinity}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: undefined}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: 'test'}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: {}}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, 2, 3]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, NaN]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, Infinity]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, -Infinity]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, undefined]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, 'test']}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, {}]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, [2, 3]]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: NaN}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: Infinity}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: -Infinity}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: undefined}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: 'test'}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: {}}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [1, 2, 3]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [1, NaN]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [1, Infinity]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [1, -Infinity]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [1, undefined]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [1, 'test']}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [1, {}]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [1, [2, 3]]}); }); // floodColor - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: 'test'}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: 'rgba(NaN, 3, 2, 1)'}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: 10}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: undefined}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: null}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: NaN}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: 'test'}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: 'rgba(NaN, 3, 2, 1)'}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: 10}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: undefined}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: null}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: NaN}); }); t.done(); }); diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.exceptions.tentative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.exceptions.tentative.worker.js index bd18524f28..1d56865e68 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.exceptions.tentative.worker.js +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.exceptions.tentative.worker.js @@ -16,104 +16,250 @@ t.step(function() { var canvas = new OffscreenCanvas(100, 50); var ctx = canvas.getContext('2d'); + // Should not throw an error. // dx - _assert(new CanvasFilter({name: 'dropShadow', dx: 10}), "new CanvasFilter({name: 'dropShadow', dx: 10})"); - _assert(new CanvasFilter({name: 'dropShadow', dx: -1}), "new CanvasFilter({name: 'dropShadow', dx: -1})"); - _assert(new CanvasFilter({name: 'dropShadow', dx: 0.5}), "new CanvasFilter({name: 'dropShadow', dx: 0.5})"); - _assert(new CanvasFilter({name: 'dropShadow', dx: null}), "new CanvasFilter({name: 'dropShadow', dx: null})"); - _assert(new CanvasFilter({name: 'dropShadow', dx: true}), "new CanvasFilter({name: 'dropShadow', dx: true})"); - _assert(new CanvasFilter({name: 'dropShadow', dx: false}), "new CanvasFilter({name: 'dropShadow', dx: false})"); - _assert(new CanvasFilter({name: 'dropShadow', dx: []}), "new CanvasFilter({name: 'dropShadow', dx: []})"); - _assert(new CanvasFilter({name: 'dropShadow', dx: [20]}), "new CanvasFilter({name: 'dropShadow', dx: [\""+(20)+"\"]})"); - _assert(new CanvasFilter({name: 'dropShadow', dx: '30'}), "new CanvasFilter({name: 'dropShadow', dx: '30'})"); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: 10}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: -1}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: 0.5}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: null}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: true}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: false}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: []}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: [20]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: '30'}); // dy - _assert(new CanvasFilter({name: 'dropShadow', dy: 10}), "new CanvasFilter({name: 'dropShadow', dy: 10})"); - _assert(new CanvasFilter({name: 'dropShadow', dy: -1}), "new CanvasFilter({name: 'dropShadow', dy: -1})"); - _assert(new CanvasFilter({name: 'dropShadow', dy: 0.5}), "new CanvasFilter({name: 'dropShadow', dy: 0.5})"); - _assert(new CanvasFilter({name: 'dropShadow', dy: null}), "new CanvasFilter({name: 'dropShadow', dy: null})"); - _assert(new CanvasFilter({name: 'dropShadow', dy: true}), "new CanvasFilter({name: 'dropShadow', dy: true})"); - _assert(new CanvasFilter({name: 'dropShadow', dy: false}), "new CanvasFilter({name: 'dropShadow', dy: false})"); - _assert(new CanvasFilter({name: 'dropShadow', dy: []}), "new CanvasFilter({name: 'dropShadow', dy: []})"); - _assert(new CanvasFilter({name: 'dropShadow', dy: [20]}), "new CanvasFilter({name: 'dropShadow', dy: [\""+(20)+"\"]})"); - _assert(new CanvasFilter({name: 'dropShadow', dy: '30'}), "new CanvasFilter({name: 'dropShadow', dy: '30'})"); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: 10}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: -1}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: 0.5}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: null}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: true}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: false}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: []}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: [20]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: '30'}); // floodOpacity - _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: 10}), "new CanvasFilter({name: 'dropShadow', floodOpacity: 10})"); - _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: -1}), "new CanvasFilter({name: 'dropShadow', floodOpacity: -1})"); - _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: 0.5}), "new CanvasFilter({name: 'dropShadow', floodOpacity: 0.5})"); - _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: null}), "new CanvasFilter({name: 'dropShadow', floodOpacity: null})"); - _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: true}), "new CanvasFilter({name: 'dropShadow', floodOpacity: true})"); - _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: false}), "new CanvasFilter({name: 'dropShadow', floodOpacity: false})"); - _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: []}), "new CanvasFilter({name: 'dropShadow', floodOpacity: []})"); - _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: [20]}), "new CanvasFilter({name: 'dropShadow', floodOpacity: [\""+(20)+"\"]})"); - _assert(new CanvasFilter({name: 'dropShadow', floodOpacity: '30'}), "new CanvasFilter({name: 'dropShadow', floodOpacity: '30'})"); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: 10}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: -1}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: 0.5}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: null}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: true}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: false}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: []}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: [20]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: '30'}); + // dx + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: 10}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: -1}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: 0.5}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: null}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: true}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: false}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: []}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: [20]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: '30'}); + // dy + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: 10}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: -1}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: 0.5}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: null}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: true}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: false}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: []}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: [20]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: '30'}); + // floodOpacity + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: 10}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: -1}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: 0.5}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: null}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: true}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: false}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: []}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: [20]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: '30'}); // stdDeviation - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: 10}), "new CanvasFilter({name: 'dropShadow', stdDeviation: 10})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: -1}), "new CanvasFilter({name: 'dropShadow', stdDeviation: -1})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: 0.5}), "new CanvasFilter({name: 'dropShadow', stdDeviation: 0.5})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: null}), "new CanvasFilter({name: 'dropShadow', stdDeviation: null})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: true}), "new CanvasFilter({name: 'dropShadow', stdDeviation: true})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: false}), "new CanvasFilter({name: 'dropShadow', stdDeviation: false})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: []}), "new CanvasFilter({name: 'dropShadow', stdDeviation: []})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: [20]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: [\""+(20)+"\"]})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: '30'}), "new CanvasFilter({name: 'dropShadow', stdDeviation: '30'})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: [10, -1]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: [10, -1]})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: [0.5, null]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: [0.5, null]})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: [true, false]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: [true, false]})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: [[], [20]]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: [[], [\""+(20)+"\"]]})"); - _assert(new CanvasFilter({name: 'dropShadow', stdDeviation: ['30', ['40']]}), "new CanvasFilter({name: 'dropShadow', stdDeviation: ['30', ['40']]})"); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: 10}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: -1}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: 0.5}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: null}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: true}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: false}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: []}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [20]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: '30'}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [10, -1]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [0.5, null]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [true, false]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [[], [20]]}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: ['30', ['40']]}); // floodColor - _assert(new CanvasFilter({name: 'dropShadow', floodColor: 'red'}), "new CanvasFilter({name: 'dropShadow', floodColor: 'red'})"); - _assert(new CanvasFilter({name: 'dropShadow', floodColor: 'canvas'}), "new CanvasFilter({name: 'dropShadow', floodColor: 'canvas'})"); - _assert(new CanvasFilter({name: 'dropShadow', floodColor: 'rgba(4, -3, 0.5, 1)'}), "new CanvasFilter({name: 'dropShadow', floodColor: 'rgba(4, -3, 0.5, 1)'})"); - _assert(new CanvasFilter({name: 'dropShadow', floodColor: '#aabbccdd'}), "new CanvasFilter({name: 'dropShadow', floodColor: '#aabbccdd'})"); - _assert(new CanvasFilter({name: 'dropShadow', floodColor: '#abcd'}), "new CanvasFilter({name: 'dropShadow', floodColor: '#abcd'})"); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: 'red'}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: 'canvas'}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: 'rgba(4, -3, 0.5, 1)'}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: '#aabbccdd'}); + ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: '#abcd'}); + // Should throw a TypeError. // dx - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: NaN}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: Infinity}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: -Infinity}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: undefined}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: 'test'}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: {}}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dx: [1, 2]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: NaN}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: Infinity}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: -Infinity}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: undefined}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: 'test'}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: {}}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dx: [1, 2]}); }); // dy - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: NaN}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: Infinity}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: -Infinity}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: undefined}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: 'test'}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: {}}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', dy: [1, 2]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: NaN}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: Infinity}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: -Infinity}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: undefined}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: 'test'}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: {}}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', dy: [1, 2]}); }); // floodOpacity - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: NaN}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: Infinity}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: -Infinity}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: undefined}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: 'test'}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: {}}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodOpacity: [1, 2]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: NaN}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: Infinity}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: -Infinity}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: undefined}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: 'test'}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: {}}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodOpacity: [1, 2]}); }); // stdDeviation - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: NaN}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: Infinity}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: -Infinity}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: undefined}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: 'test'}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: {}}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, 2, 3]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, NaN]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, Infinity]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, -Infinity]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, undefined]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, 'test']}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, {}]}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', stdDeviation: [1, [2, 3]]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: NaN}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: Infinity}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: -Infinity}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: undefined}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: 'test'}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: {}}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [1, 2, 3]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [1, NaN]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [1, Infinity]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [1, -Infinity]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [1, undefined]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [1, 'test']}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [1, {}]}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', stdDeviation: [1, [2, 3]]}); }); // floodColor - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: 'test'}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: 'rgba(NaN, 3, 2, 1)'}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: 10}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: undefined}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: null}); }); - assert_throws_js(TypeError, function() { new CanvasFilter({name: 'dropShadow', floodColor: NaN}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: 'test'}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: 'rgba(NaN, 3, 2, 1)'}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: 10}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: undefined}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: null}); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter( + {name: 'dropShadow', floodColor: NaN}); }); t.done(); }); done(); diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.tentative.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.tentative.html index 81eb1eae45..7569304b95 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.tentative.html +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.tentative.html @@ -22,86 +22,58 @@ // Parameter defaults. ctx.filter = new CanvasFilter({name: 'dropShadow'}); ctx.fillRect(10, 10, 80, 80); - // All parameters specified. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5, floodColor: 'purple', floodOpacity: 0.7}); ctx.fillRect(110, 10, 80, 80); - // Named color. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, floodColor: 'purple'}); ctx.fillRect(10, 110, 80, 80); - // System color. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, floodColor: 'LinkText'}); ctx.fillRect(110, 110, 80, 80); - // Numerical color. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, floodColor: 'rgba(20, 50, 130, 1)'}); ctx.fillRect(210, 110, 80, 80); - // Transparent floodColor. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, floodColor: 'rgba(20, 50, 130, 0.7)'}); ctx.fillRect(310, 110, 80, 80); - // Transparent floodColor and floodOpacity. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, floodColor: 'rgba(20, 50, 130, 0.7)', floodOpacity: 0.7}); ctx.fillRect(410, 110, 80, 80); - // No blur. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 0, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 0, floodColor: 'purple'}); ctx.fillRect(10, 210, 80, 80); - // Single float blur. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5, floodColor: 'purple'}); ctx.fillRect(110, 210, 80, 80); - // Single negative float blur. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: -5, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: -5, floodColor: 'purple'}); ctx.fillRect(210, 210, 80, 80); - // Two floats (X&Y) blur. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: [3, 5], + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: [3, 5], floodColor: 'purple'}); ctx.fillRect(310, 210, 80, 80); - // Two negative floats (X&Y) blur. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: [-3, -5], + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: [-3, -5], floodColor: 'purple'}); ctx.fillRect(410, 210, 80, 80); - // Degenerate parameter values. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: [-5], dy: [], stdDeviation: null, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: [-5], dy: [], stdDeviation: null, floodColor: 'purple', floodOpacity: [2]}); ctx.fillRect(10, 310, 80, 80); - - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: null, dy: '5', stdDeviation: [[-5], ['3']], + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: null, dy: '5', stdDeviation: [[-5], ['3']], floodColor: 'purple', floodOpacity: '0.8'}); ctx.fillRect(110, 310, 80, 80); - - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: true, dy: ['10'], stdDeviation: false, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: true, dy: ['10'], stdDeviation: false, floodColor: 'purple', floodOpacity: ['0.4']}); ctx.fillRect(210, 310, 80, 80); diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.tentative.w.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.tentative.w.html index fe9087244a..2a26af4ec3 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.tentative.w.html +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.tentative.w.html @@ -24,86 +24,58 @@ // Parameter defaults. ctx.filter = new CanvasFilter({name: 'dropShadow'}); ctx.fillRect(10, 10, 80, 80); - // All parameters specified. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5, floodColor: 'purple', floodOpacity: 0.7}); ctx.fillRect(110, 10, 80, 80); - // Named color. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, floodColor: 'purple'}); ctx.fillRect(10, 110, 80, 80); - // System color. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, floodColor: 'LinkText'}); ctx.fillRect(110, 110, 80, 80); - // Numerical color. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, floodColor: 'rgba(20, 50, 130, 1)'}); ctx.fillRect(210, 110, 80, 80); - // Transparent floodColor. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, floodColor: 'rgba(20, 50, 130, 0.7)'}); ctx.fillRect(310, 110, 80, 80); - // Transparent floodColor and floodOpacity. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, floodColor: 'rgba(20, 50, 130, 0.7)', floodOpacity: 0.7}); ctx.fillRect(410, 110, 80, 80); - // No blur. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 0, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 0, floodColor: 'purple'}); ctx.fillRect(10, 210, 80, 80); - // Single float blur. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5, floodColor: 'purple'}); ctx.fillRect(110, 210, 80, 80); - // Single negative float blur. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: -5, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: -5, floodColor: 'purple'}); ctx.fillRect(210, 210, 80, 80); - // Two floats (X&Y) blur. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: [3, 5], + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: [3, 5], floodColor: 'purple'}); ctx.fillRect(310, 210, 80, 80); - // Two negative floats (X&Y) blur. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: [-3, -5], + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: 9, dy: 12, stdDeviation: [-3, -5], floodColor: 'purple'}); ctx.fillRect(410, 210, 80, 80); - // Degenerate parameter values. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: [-5], dy: [], stdDeviation: null, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: [-5], dy: [], stdDeviation: null, floodColor: 'purple', floodOpacity: [2]}); ctx.fillRect(10, 310, 80, 80); - - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: null, dy: '5', stdDeviation: [[-5], ['3']], + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: null, dy: '5', stdDeviation: [[-5], ['3']], floodColor: 'purple', floodOpacity: '0.8'}); ctx.fillRect(110, 310, 80, 80); - - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: true, dy: ['10'], stdDeviation: false, + ctx.filter = new CanvasFilter({name: 'dropShadow', dx: true, dy: ['10'], stdDeviation: false, floodColor: 'purple', floodOpacity: ['0.4']}); ctx.fillRect(210, 310, 80, 80); diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.isotropic.tentative-expected.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.isotropic.tentative-expected.html new file mode 100644 index 0000000000..dac31c97f1 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.isotropic.tentative-expected.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.isotropic.tentative</title> +<h1>2d.filter.canvasFilterObject.gaussianBlur.isotropic.tentative</h1> +<p class="desc">Test CanvasFilter() with gaussianBlur.</p> + +<svg xmlns="http://www.w3.org/2000/svg" + width="100" height="100" + color-interpolation-filters="sRGB"> + <filter id="blur" x="-50%" y="-50%" width="200%" height="200%"> + <feGaussianBlur stdDeviation="4 4" /> + </filter> + <rect x="25" y="25" width="50" height="50" + fill="teal" filter="url(#blur)" /> +</svg> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.isotropic.tentative.html index 4417a1917c..801e6fdb8c 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic.html +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.isotropic.tentative.html @@ -1,8 +1,8 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> -<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic-expected.html"> -<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic</title> -<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic</h1> +<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.isotropic.tentative-expected.html"> +<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.isotropic.tentative</title> +<h1>2d.filter.canvasFilterObject.gaussianBlur.isotropic.tentative</h1> <p class="desc">Test CanvasFilter() with gaussianBlur.</p> <canvas id="canvas" width="100" height="100"> <p class="fallback">FAIL (fallback content)</p> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic.w.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.isotropic.tentative.w.html index d2024ad205..6c7c7f7649 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic.w.html +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.isotropic.tentative.w.html @@ -1,9 +1,9 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> <html class="reftest-wait"> -<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic-expected.html"> -<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic</title> -<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.isotropic</h1> +<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.isotropic.tentative-expected.html"> +<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.isotropic.tentative</title> +<h1>2d.filter.canvasFilterObject.gaussianBlur.isotropic.tentative</h1> <p class="desc">Test CanvasFilter() with gaussianBlur.</p> <canvas id="canvas" width="100" height="100"> <p class="fallback">FAIL (fallback content)</p> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x-expected.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.mostly-x.tentative-expected.html index e76613271f..88d0cb2de2 100644 --- a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x-expected.html +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.mostly-x.tentative-expected.html @@ -1,7 +1,7 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> -<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x</title> -<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x</h1> +<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.mostly-x.tentative</title> +<h1>2d.filter.canvasFilterObject.gaussianBlur.mostly-x.tentative</h1> <p class="desc">Test CanvasFilter() with gaussianBlur.</p> <svg xmlns="http://www.w3.org/2000/svg" diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.mostly-x.tentative.html index 2ea26359fe..ba986d8e7b 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x.html +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.mostly-x.tentative.html @@ -1,8 +1,8 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> -<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x-expected.html"> -<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x</title> -<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x</h1> +<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.mostly-x.tentative-expected.html"> +<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.mostly-x.tentative</title> +<h1>2d.filter.canvasFilterObject.gaussianBlur.mostly-x.tentative</h1> <p class="desc">Test CanvasFilter() with gaussianBlur.</p> <canvas id="canvas" width="100" height="100"> <p class="fallback">FAIL (fallback content)</p> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x.w.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.mostly-x.tentative.w.html index fa49ea4682..86fe086327 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x.w.html +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.mostly-x.tentative.w.html @@ -1,9 +1,9 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> <html class="reftest-wait"> -<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x-expected.html"> -<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x</title> -<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-x</h1> +<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.mostly-x.tentative-expected.html"> +<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.mostly-x.tentative</title> +<h1>2d.filter.canvasFilterObject.gaussianBlur.mostly-x.tentative</h1> <p class="desc">Test CanvasFilter() with gaussianBlur.</p> <canvas id="canvas" width="100" height="100"> <p class="fallback">FAIL (fallback content)</p> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y-expected.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.mostly-y.tentative-expected.html index 0f214fca9f..744983d4ae 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y-expected.html +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.mostly-y.tentative-expected.html @@ -1,7 +1,7 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> -<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y</title> -<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y</h1> +<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.mostly-y.tentative</title> +<h1>2d.filter.canvasFilterObject.gaussianBlur.mostly-y.tentative</h1> <p class="desc">Test CanvasFilter() with gaussianBlur.</p> <svg xmlns="http://www.w3.org/2000/svg" diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.mostly-y.tentative.html index a9783ccb6a..0265cfa6c4 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y.html +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.mostly-y.tentative.html @@ -1,8 +1,8 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> -<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y-expected.html"> -<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y</title> -<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y</h1> +<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.mostly-y.tentative-expected.html"> +<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.mostly-y.tentative</title> +<h1>2d.filter.canvasFilterObject.gaussianBlur.mostly-y.tentative</h1> <p class="desc">Test CanvasFilter() with gaussianBlur.</p> <canvas id="canvas" width="100" height="100"> <p class="fallback">FAIL (fallback content)</p> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y.w.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.mostly-y.tentative.w.html index ab83f50ea0..c22b320857 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y.w.html +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.mostly-y.tentative.w.html @@ -1,9 +1,9 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> <html class="reftest-wait"> -<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y-expected.html"> -<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y</title> -<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.mostly-y</h1> +<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.mostly-y.tentative-expected.html"> +<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.mostly-y.tentative</title> +<h1>2d.filter.canvasFilterObject.gaussianBlur.mostly-y.tentative</h1> <p class="desc">Test CanvasFilter() with gaussianBlur.</p> <canvas id="canvas" width="100" height="100"> <p class="fallback">FAIL (fallback content)</p> diff --git a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only-expected.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.x-only.tentative-expected.html index 285a641726..e611113e42 100644 --- a/testing/web-platform/tests/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only-expected.html +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.x-only.tentative-expected.html @@ -1,7 +1,7 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> -<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only</title> -<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only</h1> +<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.x-only.tentative</title> +<h1>2d.filter.canvasFilterObject.gaussianBlur.x-only.tentative</h1> <p class="desc">Test CanvasFilter() with gaussianBlur.</p> <svg xmlns="http://www.w3.org/2000/svg" diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.x-only.tentative.html index 3028c2a700..3ed8e9ddf9 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only.html +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.x-only.tentative.html @@ -1,8 +1,8 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> -<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only-expected.html"> -<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only</title> -<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only</h1> +<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.x-only.tentative-expected.html"> +<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.x-only.tentative</title> +<h1>2d.filter.canvasFilterObject.gaussianBlur.x-only.tentative</h1> <p class="desc">Test CanvasFilter() with gaussianBlur.</p> <canvas id="canvas" width="100" height="100"> <p class="fallback">FAIL (fallback content)</p> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only.w.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.x-only.tentative.w.html index e8482cf3ed..35cbc1b365 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only.w.html +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.x-only.tentative.w.html @@ -1,9 +1,9 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> <html class="reftest-wait"> -<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only-expected.html"> -<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only</title> -<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.x-only</h1> +<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.x-only.tentative-expected.html"> +<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.x-only.tentative</title> +<h1>2d.filter.canvasFilterObject.gaussianBlur.x-only.tentative</h1> <p class="desc">Test CanvasFilter() with gaussianBlur.</p> <canvas id="canvas" width="100" height="100"> <p class="fallback">FAIL (fallback content)</p> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only-expected.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.y-only.tentative-expected.html index d59945b5da..c6d915cb07 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only-expected.html +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.y-only.tentative-expected.html @@ -1,7 +1,7 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> -<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only</title> -<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only</h1> +<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.y-only.tentative</title> +<h1>2d.filter.canvasFilterObject.gaussianBlur.y-only.tentative</h1> <p class="desc">Test CanvasFilter() with gaussianBlur.</p> <svg xmlns="http://www.w3.org/2000/svg" diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.y-only.tentative.html index fca324716b..f563ad9d77 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only.html +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.y-only.tentative.html @@ -1,8 +1,8 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> -<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only-expected.html"> -<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only</title> -<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only</h1> +<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.y-only.tentative-expected.html"> +<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.y-only.tentative</title> +<h1>2d.filter.canvasFilterObject.gaussianBlur.y-only.tentative</h1> <p class="desc">Test CanvasFilter() with gaussianBlur.</p> <canvas id="canvas" width="100" height="100"> <p class="fallback">FAIL (fallback content)</p> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only.w.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.y-only.tentative.w.html index 50cfb3083a..171a41caa8 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only.w.html +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.y-only.tentative.w.html @@ -1,9 +1,9 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> <html class="reftest-wait"> -<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only-expected.html"> -<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only</title> -<h1>2d.filter.canvasFilterObject.gaussianBlur.tentative.y-only</h1> +<link rel="match" href="2d.filter.canvasFilterObject.gaussianBlur.y-only.tentative-expected.html"> +<title>Canvas test: 2d.filter.canvasFilterObject.gaussianBlur.y-only.tentative</title> +<h1>2d.filter.canvasFilterObject.gaussianBlur.y-only.tentative</h1> <p class="desc">Test CanvasFilter() with gaussianBlur.</p> <canvas id="canvas" width="100" height="100"> <p class="fallback">FAIL (fallback content)</p> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.turbulence.inputTypes.tentative.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.turbulence.inputTypes.tentative.html index 040c62a96b..8ad2a5ccfb 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.turbulence.inputTypes.tentative.html +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.turbulence.inputTypes.tentative.html @@ -117,12 +117,12 @@ t.step(function() { for (testCase of errorTestCases) { const filterOptions = {...{name: 'turbulence'}, ...testCase}; - assert_throws_js(TypeError, function() { new CanvasFilter(filterOptions); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter(filterOptions); }); } for (testCase of workingTestCases) { const filterOptions = {...{name: 'turbulence'}, ...testCase}; - _assert(new CanvasFilter(filterOptions) != null, "new CanvasFilter(filterOptions) != null"); + ctx.filter = new CanvasFilter(filterOptions); } t.done(); diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.turbulence.inputTypes.tentative.worker.js b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.turbulence.inputTypes.tentative.worker.js index 1a950a9207..16199cb0ec 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.turbulence.inputTypes.tentative.worker.js +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.turbulence.inputTypes.tentative.worker.js @@ -113,12 +113,12 @@ t.step(function() { for (testCase of errorTestCases) { const filterOptions = {...{name: 'turbulence'}, ...testCase}; - assert_throws_js(TypeError, function() { new CanvasFilter(filterOptions); }); + assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter(filterOptions); }); } for (testCase of workingTestCases) { const filterOptions = {...{name: 'turbulence'}, ...testCase}; - _assert(new CanvasFilter(filterOptions) != null, "new CanvasFilter(filterOptions) != null"); + ctx.filter = new CanvasFilter(filterOptions); } t.done(); }); diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.blur.exceptions.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.blur.exceptions.html new file mode 100644 index 0000000000..36dd856456 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.blur.exceptions.html @@ -0,0 +1,38 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>OffscreenCanvas test: 2d.filter.layers.blur.exceptions</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> + +<h1>2d.filter.layers.blur.exceptions</h1> +<p class="desc">Test exceptions on gaussianBlur filter</p> + + +<script> +var t = async_test("Test exceptions on gaussianBlur filter"); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + + var canvas = new OffscreenCanvas(100, 50); + var ctx = canvas.getContext('2d'); + + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'gaussianBlur'}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'gaussianBlur', stdDeviation: undefined}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'gaussianBlur', stdDeviation: 'foo'}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'gaussianBlur', stdDeviation: [1,2,3]}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'gaussianBlur', stdDeviation: NaN}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'gaussianBlur', stdDeviation: {}}}); }); + t.done(); + +}); +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.blur.exceptions.worker.js b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.blur.exceptions.worker.js new file mode 100644 index 0000000000..a053b8113c --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.blur.exceptions.worker.js @@ -0,0 +1,33 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.filter.layers.blur.exceptions +// Description:Test exceptions on gaussianBlur filter +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +var t = async_test("Test exceptions on gaussianBlur filter"); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + + var canvas = new OffscreenCanvas(100, 50); + var ctx = canvas.getContext('2d'); + + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'gaussianBlur'}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'gaussianBlur', stdDeviation: undefined}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'gaussianBlur', stdDeviation: 'foo'}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'gaussianBlur', stdDeviation: [1,2,3]}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'gaussianBlur', stdDeviation: NaN}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'gaussianBlur', stdDeviation: {}}}); }); + t.done(); +}); +done(); diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.colorMatrix.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.colorMatrix.html new file mode 100644 index 0000000000..9e12acbbe0 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.colorMatrix.html @@ -0,0 +1,105 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>OffscreenCanvas test: 2d.filter.layers.colorMatrix</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> + +<h1>2d.filter.layers.colorMatrix</h1> +<p class="desc">Test the functionality of ColorMatrix filters</p> + + +<script> +var t = async_test("Test the functionality of ColorMatrix filters"); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + + var canvas = new OffscreenCanvas(100, 50); + var ctx = canvas.getContext('2d'); + + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'colorMatrix', values: undefined}}); }); + + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'colorMatrix', values: 'foo'}}); }); + + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'colorMatrix', values: null}}); }); + + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'colorMatrix', values: [1, 2, 3]}}); }); + + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'colorMatrix', + values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 'a']}}); }); + + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'colorMatrix', + values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, Infinity]}}); }); + + ctx.fillStyle = '#f00'; + ctx.beginLayer({filter: + {name: 'colorMatrix', type: 'hueRotate', values: 0}}); + ctx.fillRect(0, 0, 100, 50); + ctx.endLayer(); + _assertPixelApprox(canvas, 10,10, 255,0,0,255, 2); + + ctx.beginLayer({filter: + {name: 'colorMatrix', type: 'hueRotate', values: 90}}); + ctx.fillRect(0, 0, 100, 50); + ctx.endLayer(); + _assertPixelApprox(canvas, 10,10, 0,91,0,255, 2); + + ctx.beginLayer({filter: + {name: 'colorMatrix', type: 'hueRotate', values: 180}}); + ctx.fillRect(0, 0, 100, 50); + ctx.endLayer(); + _assertPixelApprox(canvas, 10,10, 0,109,109,255, 2); + + ctx.beginLayer({filter: + {name: 'colorMatrix', type: 'hueRotate', values: 270}}); + ctx.fillRect(0, 0, 100, 50); + ctx.endLayer(); + _assertPixelApprox(canvas, 10,10, 109,18,255,255, 2); + + ctx.beginLayer({filter: + {name: 'colorMatrix', type: 'saturate', values: 0.5}}); + ctx.fillRect(0, 0, 100, 50); + ctx.endLayer(); + _assertPixelApprox(canvas, 10,10, 155,27,27,255, 2); + + ctx.clearRect(0, 0, 100, 50); + ctx.beginLayer({filter: + {name: 'colorMatrix', type: 'luminanceToAlpha'}}); + ctx.fillRect(0, 0, 100, 50); + ctx.endLayer(); + _assertPixelApprox(canvas, 10,10, 0,0,0,54, 2); + + ctx.beginLayer({filter: + {name: 'colorMatrix', values: [ + 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0 + ]}}); + ctx.fillRect(0, 0, 50, 25); + ctx.fillStyle = '#0f0'; + ctx.fillRect(50, 0, 50, 25); + ctx.fillStyle = '#00f'; + ctx.fillRect(0, 25, 50, 25); + ctx.fillStyle = '#fff'; + ctx.fillRect(50, 25, 50, 25); + ctx.endLayer(); + _assertPixelApprox(canvas, 10,10, 0,255,0,255, 2); + _assertPixelApprox(canvas, 60,10, 0,255,0,255, 2); + _assertPixelApprox(canvas, 10,30, 0,255,0,255, 2); + _assertPixelApprox(canvas, 60,30, 0,255,0,255, 2); + t.done(); + +}); +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.colorMatrix.worker.js b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.colorMatrix.worker.js new file mode 100644 index 0000000000..12cdff3868 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.colorMatrix.worker.js @@ -0,0 +1,100 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.filter.layers.colorMatrix +// Description:Test the functionality of ColorMatrix filters +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +var t = async_test("Test the functionality of ColorMatrix filters"); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + + var canvas = new OffscreenCanvas(100, 50); + var ctx = canvas.getContext('2d'); + + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'colorMatrix', values: undefined}}); }); + + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'colorMatrix', values: 'foo'}}); }); + + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'colorMatrix', values: null}}); }); + + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'colorMatrix', values: [1, 2, 3]}}); }); + + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'colorMatrix', + values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 'a']}}); }); + + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'colorMatrix', + values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, Infinity]}}); }); + + ctx.fillStyle = '#f00'; + ctx.beginLayer({filter: + {name: 'colorMatrix', type: 'hueRotate', values: 0}}); + ctx.fillRect(0, 0, 100, 50); + ctx.endLayer(); + _assertPixelApprox(canvas, 10,10, 255,0,0,255, 2); + + ctx.beginLayer({filter: + {name: 'colorMatrix', type: 'hueRotate', values: 90}}); + ctx.fillRect(0, 0, 100, 50); + ctx.endLayer(); + _assertPixelApprox(canvas, 10,10, 0,91,0,255, 2); + + ctx.beginLayer({filter: + {name: 'colorMatrix', type: 'hueRotate', values: 180}}); + ctx.fillRect(0, 0, 100, 50); + ctx.endLayer(); + _assertPixelApprox(canvas, 10,10, 0,109,109,255, 2); + + ctx.beginLayer({filter: + {name: 'colorMatrix', type: 'hueRotate', values: 270}}); + ctx.fillRect(0, 0, 100, 50); + ctx.endLayer(); + _assertPixelApprox(canvas, 10,10, 109,18,255,255, 2); + + ctx.beginLayer({filter: + {name: 'colorMatrix', type: 'saturate', values: 0.5}}); + ctx.fillRect(0, 0, 100, 50); + ctx.endLayer(); + _assertPixelApprox(canvas, 10,10, 155,27,27,255, 2); + + ctx.clearRect(0, 0, 100, 50); + ctx.beginLayer({filter: + {name: 'colorMatrix', type: 'luminanceToAlpha'}}); + ctx.fillRect(0, 0, 100, 50); + ctx.endLayer(); + _assertPixelApprox(canvas, 10,10, 0,0,0,54, 2); + + ctx.beginLayer({filter: + {name: 'colorMatrix', values: [ + 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0 + ]}}); + ctx.fillRect(0, 0, 50, 25); + ctx.fillStyle = '#0f0'; + ctx.fillRect(50, 0, 50, 25); + ctx.fillStyle = '#00f'; + ctx.fillRect(0, 25, 50, 25); + ctx.fillStyle = '#fff'; + ctx.fillRect(50, 25, 50, 25); + ctx.endLayer(); + _assertPixelApprox(canvas, 10,10, 0,255,0,255, 2); + _assertPixelApprox(canvas, 60,10, 0,255,0,255, 2); + _assertPixelApprox(canvas, 10,30, 0,255,0,255, 2); + _assertPixelApprox(canvas, 60,30, 0,255,0,255, 2); + t.done(); +}); +done(); diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.discrete-expected.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.discrete-expected.html new file mode 100644 index 0000000000..8419953b3d --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.discrete-expected.html @@ -0,0 +1,50 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.layers.componentTransfer.discrete</title> +<h1>2d.filter.layers.componentTransfer.discrete</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with discrete type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement + function getTransformedValue(C, V) { + // Get the right interval + const n = V.length; + const k = C == 1 ? n - 1 : Math.floor(C * n); + return V[k]; + } + + function getColor(inputColor, tableValues) { + const result = [0, 0, 0]; + for (const i in inputColor) { + const C = inputColor[i]/255; + const Cprime = getTransformedValue(C, tableValues[i]); + result[i] = Math.max(0, Math.min(1, Cprime)) * 255; + } + return result; + } + + tableValuesR = [0, 0, 1, 1]; + tableValuesG = [2, 0, 0.5, 3]; + tableValuesB = [1, -1, 5, 0]; + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + let outputColor = getColor( + color, [tableValuesR, tableValuesG, tableValuesB]); + ctx.fillStyle = `rgb(${outputColor[0]}, ${outputColor[1]}, + ${outputColor[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.discrete.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.discrete.html new file mode 100644 index 0000000000..459c2f2850 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.discrete.html @@ -0,0 +1,41 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.filter.layers.componentTransfer.discrete-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-500"> +<title>Canvas test: 2d.filter.layers.componentTransfer.discrete</title> +<h1>2d.filter.layers.componentTransfer.discrete</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with discrete type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = new OffscreenCanvas(100, 100); + const ctx = canvas.getContext('2d'); + + tableValuesR = [0, 0, 1, 1]; + tableValuesG = [2, 0, 0.5, 3]; + tableValuesB = [1, -1, 5, 0]; + ctx.beginLayer({filter: {name: 'componentTransfer', + funcR: {type: 'discrete', tableValues: tableValuesR}, + funcG: {type: 'discrete', tableValues: tableValuesG}, + funcB: {type: 'discrete', tableValues: tableValuesB}, + }}); + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } + ctx.endLayer(); + + const outputCanvas = document.getElementById("canvas"); + outputCanvas.getContext('2d').drawImage(canvas, 0, 0); +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.discrete.w.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.discrete.w.html new file mode 100644 index 0000000000..86e1d54fb7 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.discrete.w.html @@ -0,0 +1,55 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<html class="reftest-wait"> +<link rel="match" href="2d.filter.layers.componentTransfer.discrete-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-500"> +<title>Canvas test: 2d.filter.layers.componentTransfer.discrete</title> +<h1>2d.filter.layers.componentTransfer.discrete</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with discrete type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script id='myWorker' type='text/worker'> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(100, 100); + const ctx = canvas.getContext('2d'); + + tableValuesR = [0, 0, 1, 1]; + tableValuesG = [2, 0, 0.5, 3]; + tableValuesB = [1, -1, 5, 0]; + ctx.beginLayer({filter: {name: 'componentTransfer', + funcR: {type: 'discrete', tableValues: tableValuesR}, + funcG: {type: 'discrete', tableValues: tableValuesG}, + funcB: {type: 'discrete', tableValues: tableValuesB}, + }}); + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } + ctx.endLayer(); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; +</script> +<script> + const blob = new Blob([document.getElementById('myWorker').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCtx = document.getElementById("canvas").getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + document.documentElement.classList.remove("reftest-wait"); + }); + worker.postMessage(null); +</script> +</html> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.gamma-expected.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.gamma-expected.html new file mode 100644 index 0000000000..3e5d980896 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.gamma-expected.html @@ -0,0 +1,44 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.layers.componentTransfer.gamma</title> +<h1>2d.filter.layers.componentTransfer.gamma</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with gamma type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement + function getColor(inputColor, amplitude, exponent, offset) { + return [ + Math.max(0, Math.min(1, Math.pow(inputColor[0]/255, + exponent[0]) * amplitude[0] + offset[0])) * 255, + Math.max(0, Math.min(1, Math.pow(inputColor[1]/255, + exponent[1]) * amplitude[1] + offset[1])) * 255, + Math.max(0, Math.min(1, Math.pow(inputColor[2]/255, + exponent[2]) * amplitude[2] + offset[2])) * 255, + ]; + } + + const amplitudes = [2, 1.1, 0.5]; + const exponents = [5, 3, 1]; + const offsets = [0.25, 0, 0.5]; + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + let outputColor = getColor(color, amplitudes, exponents, offsets); + ctx.fillStyle = `rgb(${outputColor[0]}, ${outputColor[1]}, + ${outputColor[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.gamma.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.gamma.html new file mode 100644 index 0000000000..9012115adf --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.gamma.html @@ -0,0 +1,44 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.filter.layers.componentTransfer.gamma-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-500"> +<title>Canvas test: 2d.filter.layers.componentTransfer.gamma</title> +<h1>2d.filter.layers.componentTransfer.gamma</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with gamma type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = new OffscreenCanvas(100, 100); + const ctx = canvas.getContext('2d'); + + const amplitudes = [2, 1.1, 0.5]; + const exponents = [5, 3, 1]; + const offsets = [0.25, 0, 0.5]; + ctx.beginLayer({filter: {name: 'componentTransfer', + funcR: {type: 'gamma', amplitude: amplitudes[0], + exponent: exponents[0], offset: offsets[0]}, + funcG: {type: 'gamma', amplitude: amplitudes[1], + exponent: exponents[1], offset: offsets[1]}, + funcB: {type: 'gamma', amplitude: amplitudes[2], + exponent: exponents[2], offset: offsets[2]}, + }}); + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } + ctx.endLayer(); + + const outputCanvas = document.getElementById("canvas"); + outputCanvas.getContext('2d').drawImage(canvas, 0, 0); +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.gamma.w.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.gamma.w.html new file mode 100644 index 0000000000..767bcc58e5 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.gamma.w.html @@ -0,0 +1,58 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<html class="reftest-wait"> +<link rel="match" href="2d.filter.layers.componentTransfer.gamma-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-500"> +<title>Canvas test: 2d.filter.layers.componentTransfer.gamma</title> +<h1>2d.filter.layers.componentTransfer.gamma</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with gamma type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script id='myWorker' type='text/worker'> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(100, 100); + const ctx = canvas.getContext('2d'); + + const amplitudes = [2, 1.1, 0.5]; + const exponents = [5, 3, 1]; + const offsets = [0.25, 0, 0.5]; + ctx.beginLayer({filter: {name: 'componentTransfer', + funcR: {type: 'gamma', amplitude: amplitudes[0], + exponent: exponents[0], offset: offsets[0]}, + funcG: {type: 'gamma', amplitude: amplitudes[1], + exponent: exponents[1], offset: offsets[1]}, + funcB: {type: 'gamma', amplitude: amplitudes[2], + exponent: exponents[2], offset: offsets[2]}, + }}); + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } + ctx.endLayer(); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; +</script> +<script> + const blob = new Blob([document.getElementById('myWorker').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCtx = document.getElementById("canvas").getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + document.documentElement.classList.remove("reftest-wait"); + }); + worker.postMessage(null); +</script> +</html> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.identity-expected.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.identity-expected.html new file mode 100644 index 0000000000..9f1439f37b --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.identity-expected.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.layers.componentTransfer.identity</title> +<h1>2d.filter.layers.componentTransfer.identity</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with identity type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + let outputColor = inputColors[i]; + ctx.fillStyle = `rgb(${outputColor[0]}, ${outputColor[1]}, + ${outputColor[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.identity.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.identity.html new file mode 100644 index 0000000000..901dae3bed --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.identity.html @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.filter.layers.componentTransfer.identity-expected.html"> +<title>Canvas test: 2d.filter.layers.componentTransfer.identity</title> +<h1>2d.filter.layers.componentTransfer.identity</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with identity type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = new OffscreenCanvas(100, 100); + const ctx = canvas.getContext('2d'); + + ctx.beginLayer({filter: {name: 'componentTransfer', + funcR: {type: 'identity'}, + funcG: {type: 'identity'}, + funcB: {type: 'identity'}, + }}); + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } + ctx.endLayer(); + + const outputCanvas = document.getElementById("canvas"); + outputCanvas.getContext('2d').drawImage(canvas, 0, 0); +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.identity.w.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.identity.w.html new file mode 100644 index 0000000000..2e45018755 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.identity.w.html @@ -0,0 +1,51 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<html class="reftest-wait"> +<link rel="match" href="2d.filter.layers.componentTransfer.identity-expected.html"> +<title>Canvas test: 2d.filter.layers.componentTransfer.identity</title> +<h1>2d.filter.layers.componentTransfer.identity</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with identity type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script id='myWorker' type='text/worker'> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(100, 100); + const ctx = canvas.getContext('2d'); + + ctx.beginLayer({filter: {name: 'componentTransfer', + funcR: {type: 'identity'}, + funcG: {type: 'identity'}, + funcB: {type: 'identity'}, + }}); + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } + ctx.endLayer(); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; +</script> +<script> + const blob = new Blob([document.getElementById('myWorker').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCtx = document.getElementById("canvas").getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + document.documentElement.classList.remove("reftest-wait"); + }); + worker.postMessage(null); +</script> +</html> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.linear-expected.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.linear-expected.html new file mode 100644 index 0000000000..f922055ff2 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.linear-expected.html @@ -0,0 +1,44 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.layers.componentTransfer.linear</title> +<h1>2d.filter.layers.componentTransfer.linear</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with linear type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement + function getColor(inputColor, slopes, intercepts) { + return [ + Math.max(0, Math.min(1, + inputColor[0]/255 * slopes[0] + intercepts[0])) * 255, + Math.max(0, Math.min(1, + inputColor[1]/255 * slopes[1] + intercepts[1])) * 255, + Math.max(0, Math.min(1, + inputColor[2]/255 * slopes[2] + intercepts[2])) * 255, + ]; + } + + const slopes = [0.5, 1.2, -0.2]; + const intercepts = [0.25, 0, 0.5]; + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + let outputColor = getColor(color, slopes, intercepts); + ctx.fillStyle = `rgb(${outputColor[0]}, ${outputColor[1]}, + ${outputColor[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } + ctx.endLayer(); +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.linear.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.linear.html new file mode 100644 index 0000000000..f418b72ad5 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.linear.html @@ -0,0 +1,40 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.filter.layers.componentTransfer.linear-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-500"> +<title>Canvas test: 2d.filter.layers.componentTransfer.linear</title> +<h1>2d.filter.layers.componentTransfer.linear</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with linear type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = new OffscreenCanvas(100, 100); + const ctx = canvas.getContext('2d'); + + const slopes = [0.5, 1.2, -0.2]; + const intercepts = [0.25, 0, 0.5]; + ctx.beginLayer({filter: {name: 'componentTransfer', + funcR: {type: 'linear', slope: slopes[0], intercept: intercepts[0]}, + funcG: {type: 'linear', slope: slopes[1], intercept: intercepts[1]}, + funcB: {type: 'linear', slope: slopes[2], intercept: intercepts[2]}, + }}); + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } + ctx.endLayer(); + + const outputCanvas = document.getElementById("canvas"); + outputCanvas.getContext('2d').drawImage(canvas, 0, 0); +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.linear.w.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.linear.w.html new file mode 100644 index 0000000000..fbc29c86c1 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.linear.w.html @@ -0,0 +1,54 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<html class="reftest-wait"> +<link rel="match" href="2d.filter.layers.componentTransfer.linear-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-500"> +<title>Canvas test: 2d.filter.layers.componentTransfer.linear</title> +<h1>2d.filter.layers.componentTransfer.linear</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with linear type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script id='myWorker' type='text/worker'> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(100, 100); + const ctx = canvas.getContext('2d'); + + const slopes = [0.5, 1.2, -0.2]; + const intercepts = [0.25, 0, 0.5]; + ctx.beginLayer({filter: {name: 'componentTransfer', + funcR: {type: 'linear', slope: slopes[0], intercept: intercepts[0]}, + funcG: {type: 'linear', slope: slopes[1], intercept: intercepts[1]}, + funcB: {type: 'linear', slope: slopes[2], intercept: intercepts[2]}, + }}); + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } + ctx.endLayer(); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; +</script> +<script> + const blob = new Blob([document.getElementById('myWorker').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCtx = document.getElementById("canvas").getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + document.documentElement.classList.remove("reftest-wait"); + }); + worker.postMessage(null); +</script> +</html> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.table-expected.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.table-expected.html new file mode 100644 index 0000000000..0f6736d87d --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.table-expected.html @@ -0,0 +1,51 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.layers.componentTransfer.table</title> +<h1>2d.filter.layers.componentTransfer.table</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with table type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement + function getTransformedValue(C, V) { + // Get the right interval + const n = V.length - 1; + const k = C == 1 ? n - 1 : Math.floor(C * n); + return V[k] + (C - k/n) * n * (V[k + 1] - V[k]); + } + + function getColor(inputColor, tableValues) { + const result = [0, 0, 0]; + for (const i in inputColor) { + const C = inputColor[i]/255; + const Cprime = getTransformedValue(C, tableValues[i]); + result[i] = Math.max(0, Math.min(1, Cprime)) * 255; + } + return result; + } + + tableValuesR = [0, 0, 1, 1]; + tableValuesG = [2, 0, 0.5, 3]; + tableValuesB = [1, -1, 5, 0]; + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + let outputColor = getColor( + color, [tableValuesR, tableValuesG, tableValuesB]); + ctx.fillStyle = `rgb(${outputColor[0]}, ${outputColor[1]}, + ${outputColor[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.table.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.table.html new file mode 100644 index 0000000000..ef5e0f847b --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.table.html @@ -0,0 +1,41 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.filter.layers.componentTransfer.table-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-500"> +<title>Canvas test: 2d.filter.layers.componentTransfer.table</title> +<h1>2d.filter.layers.componentTransfer.table</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with table type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = new OffscreenCanvas(100, 100); + const ctx = canvas.getContext('2d'); + + tableValuesR = [0, 0, 1, 1]; + tableValuesG = [2, 0, 0.5, 3]; + tableValuesB = [1, -1, 5, 0]; + ctx.beginLayer({filter: {name: 'componentTransfer', + funcR: {type: 'table', tableValues: tableValuesR}, + funcG: {type: 'table', tableValues: tableValuesG}, + funcB: {type: 'table', tableValues: tableValuesB}, + }}); + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } + ctx.endLayer(); + + const outputCanvas = document.getElementById("canvas"); + outputCanvas.getContext('2d').drawImage(canvas, 0, 0); +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.table.w.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.table.w.html new file mode 100644 index 0000000000..b11f0ef6f3 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.componentTransfer.table.w.html @@ -0,0 +1,55 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<html class="reftest-wait"> +<link rel="match" href="2d.filter.layers.componentTransfer.table-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-500"> +<title>Canvas test: 2d.filter.layers.componentTransfer.table</title> +<h1>2d.filter.layers.componentTransfer.table</h1> +<p class="desc">Test pixels on CanvasFilter() componentTransfer with table type</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script id='myWorker' type='text/worker'> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(100, 100); + const ctx = canvas.getContext('2d'); + + tableValuesR = [0, 0, 1, 1]; + tableValuesG = [2, 0, 0.5, 3]; + tableValuesB = [1, -1, 5, 0]; + ctx.beginLayer({filter: {name: 'componentTransfer', + funcR: {type: 'table', tableValues: tableValuesR}, + funcG: {type: 'table', tableValues: tableValuesG}, + funcB: {type: 'table', tableValues: tableValuesB}, + }}); + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } + ctx.endLayer(); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; +</script> +<script> + const blob = new Blob([document.getElementById('myWorker').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCtx = document.getElementById("canvas").getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + document.documentElement.classList.remove("reftest-wait"); + }); + worker.postMessage(null); +</script> +</html> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.convolveMatrix.exceptions.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.convolveMatrix.exceptions.html new file mode 100644 index 0000000000..798822f104 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.convolveMatrix.exceptions.html @@ -0,0 +1,61 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>OffscreenCanvas test: 2d.filter.layers.convolveMatrix.exceptions</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> + +<h1>2d.filter.layers.convolveMatrix.exceptions</h1> +<p class="desc">Test exceptions on CanvasFilter() convolveMatrix</p> + + +<script> +var t = async_test("Test exceptions on CanvasFilter() convolveMatrix"); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + + var canvas = new OffscreenCanvas(100, 50); + var ctx = canvas.getContext('2d'); + + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix'}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', divisor: 2}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: null}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: 1}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [[1, 0], [0]]}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [[1, 'a'], [0]]}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [[1, 0], 0]}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [[1, 0], [0, Infinity]]}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: []}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [1]}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [1, 2, 3, 4]}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [[], []]}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [[1, 2], []]}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [[], [1, 2]]}}); }); + // This should not throw an error + ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [[]]}}); + ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [[1]]}}); + ctx.endLayer(); + t.done(); + +}); +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.convolveMatrix.exceptions.worker.js b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.convolveMatrix.exceptions.worker.js new file mode 100644 index 0000000000..fa3be89ba2 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.convolveMatrix.exceptions.worker.js @@ -0,0 +1,56 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.filter.layers.convolveMatrix.exceptions +// Description:Test exceptions on CanvasFilter() convolveMatrix +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +var t = async_test("Test exceptions on CanvasFilter() convolveMatrix"); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + + var canvas = new OffscreenCanvas(100, 50); + var ctx = canvas.getContext('2d'); + + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix'}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', divisor: 2}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: null}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: 1}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [[1, 0], [0]]}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [[1, 'a'], [0]]}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [[1, 0], 0]}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [[1, 0], [0, Infinity]]}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: []}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [1]}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [1, 2, 3, 4]}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [[], []]}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [[1, 2], []]}}); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [[], [1, 2]]}}); }); + // This should not throw an error + ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [[]]}}); + ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'convolveMatrix', kernelMatrix: [[1]]}}); + ctx.endLayer(); + t.done(); +}); +done(); diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.dropShadow-expected.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.dropShadow-expected.html new file mode 100644 index 0000000000..1719d99b4a --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.dropShadow-expected.html @@ -0,0 +1,57 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.layers.dropShadow</title> +<h1>2d.filter.layers.dropShadow</h1> +<p class="desc">Test CanvasFilter() dropShadow object.</p> + +<svg xmlns="http://www.w3.org/2000/svg" + width=520 height=420 + color-interpolation-filters="sRGB"> + <rect x=0 y=0 width=100% height=50 fill="teal" /> + <rect x=0 y=100 width=100% height=50 fill="teal" /> + <rect x=0 y=200 width=100% height=50 fill="teal" /> + <rect x=0 y=300 width=100% height=50 fill="teal" /> + + <rect x=10 y=10 width=80 height=80 fill="crimson" + filter="drop-shadow(2px 2px 2px black)"/> + <rect x=110 y=10 width=80 height=80 fill="crimson" + filter="drop-shadow(9px 12px 5px rgba(128, 0, 128, 0.7))"/> + + <rect x=10 y=110 width=80 height=80 fill="crimson" + filter="drop-shadow(9px 12px 3px purple)"/> + <rect x=110 y=110 width=80 height=80 fill="crimson" + filter="drop-shadow(9px 12px 3px LinkText)"/> + <rect x=210 y=110 width=80 height=80 fill="crimson" + filter="drop-shadow(9px 12px 3px rgba(20, 50, 130, 1))"/> + <rect x=310 y=110 width=80 height=80 fill="crimson" + filter="drop-shadow(9px 12px 3px rgba(20, 50, 130, 0.7))"/> + <rect x=410 y=110 width=80 height=80 fill="crimson" + filter="drop-shadow(9px 12px 3px rgba(20, 50, 130, 0.49))"/> + + <rect x=10 y=210 width=80 height=80 fill="crimson" + filter="drop-shadow(9px 12px 0px purple)"/> + <rect x=110 y=210 width=80 height=80 fill="crimson" + filter="drop-shadow(9px 12px 5px purple)"/> + <rect x=210 y=210 width=80 height=80 fill="crimson" + filter="drop-shadow(9px 12px 0px purple)"/> + <filter id="separable-filter" + x="-100%" y="-100%" width="300%" height="300%"> + <feDropShadow dx=9 dy=12 stdDeviation="3 5" flood-color="purple"/> + </filter> + <rect x=310 y=210 width=80 height=80 fill="crimson" + filter="url(#separable-filter)"/> + <rect x=410 y=210 width=80 height=80 fill="crimson" + filter="drop-shadow(9px 12px 0px purple)"/> + + <rect x=10 y=310 width=80 height=80 fill="crimson" + filter="drop-shadow(-5px 0px 0px purple)"/> + <filter id="separable-filter-degenerate" + x="-100%" y="-100%" width="300%" height="300%"> + <feDropShadow dx=0 dy=5 stdDeviation="0 3" + flood-color="rgba(128, 0, 128, 0.8)"/> + </filter> + <rect x=110 y=310 width=80 height=80 fill="crimson" + filter="url(#separable-filter-degenerate)"/> + <rect x=210 y=310 width=80 height=80 fill="crimson" + filter="drop-shadow(1px 10px 0px rgba(128, 0, 128, 0.4))"/> +</svg> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.dropShadow.exceptions.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.dropShadow.exceptions.html new file mode 100644 index 0000000000..10392dea5a --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.dropShadow.exceptions.html @@ -0,0 +1,270 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>OffscreenCanvas test: 2d.filter.layers.dropShadow.exceptions</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> + +<h1>2d.filter.layers.dropShadow.exceptions</h1> +<p class="desc">Test exceptions on CanvasFilter() dropShadow object</p> + + +<script> +var t = async_test("Test exceptions on CanvasFilter() dropShadow object"); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + + var canvas = new OffscreenCanvas(100, 50); + var ctx = canvas.getContext('2d'); + + // Should not throw an error. + // dx + ctx.beginLayer({filter: + {name: 'dropShadow', dx: 10}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: -1}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: 0.5}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: null}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: true}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: false}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: []}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: [20]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: '30'}}); ctx.endLayer(); + // dy + ctx.beginLayer({filter: + {name: 'dropShadow', dy: 10}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: -1}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: 0.5}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: null}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: true}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: false}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: []}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: [20]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: '30'}}); ctx.endLayer(); + // floodOpacity + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: 10}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: -1}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: 0.5}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: null}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: true}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: false}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: []}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: [20]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: '30'}}); ctx.endLayer(); + // dx + ctx.beginLayer({filter: + {name: 'dropShadow', dx: 10}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: -1}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: 0.5}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: null}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: true}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: false}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: []}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: [20]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: '30'}}); ctx.endLayer(); + // dy + ctx.beginLayer({filter: + {name: 'dropShadow', dy: 10}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: -1}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: 0.5}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: null}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: true}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: false}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: []}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: [20]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: '30'}}); ctx.endLayer(); + // floodOpacity + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: 10}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: -1}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: 0.5}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: null}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: true}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: false}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: []}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: [20]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: '30'}}); ctx.endLayer(); + // stdDeviation + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: 10}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: -1}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: 0.5}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: null}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: true}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: false}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: []}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [20]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: '30'}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [10, -1]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [0.5, null]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [true, false]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [[], [20]]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: ['30', ['40']]}}); ctx.endLayer(); + // floodColor + ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: 'red'}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: 'canvas'}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: 'rgba(4, -3, 0.5, 1)'}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: '#aabbccdd'}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: '#abcd'}}); ctx.endLayer(); + + // Should throw a TypeError. + // dx + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dx: NaN}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dx: Infinity}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dx: -Infinity}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dx: undefined}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dx: 'test'}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dx: {}}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dx: [1, 2]}}); ctx.endLayer(); }); + // dy + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dy: NaN}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dy: Infinity}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dy: -Infinity}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dy: undefined}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dy: 'test'}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dy: {}}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dy: [1, 2]}}); ctx.endLayer(); }); + // floodOpacity + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: NaN}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: Infinity}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: -Infinity}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: undefined}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: 'test'}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: {}}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: [1, 2]}}); ctx.endLayer(); }); + // stdDeviation + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: NaN}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: Infinity}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: -Infinity}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: undefined}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: 'test'}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: {}}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [1, 2, 3]}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [1, NaN]}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [1, Infinity]}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [1, -Infinity]}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [1, undefined]}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [1, 'test']}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [1, {}]}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [1, [2, 3]]}}); ctx.endLayer(); }); + // floodColor + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: 'test'}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: 'rgba(NaN, 3, 2, 1)'}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: 10}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: undefined}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: null}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: NaN}}); ctx.endLayer(); }); + t.done(); + +}); +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.dropShadow.exceptions.worker.js b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.dropShadow.exceptions.worker.js new file mode 100644 index 0000000000..86b8c56af6 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.dropShadow.exceptions.worker.js @@ -0,0 +1,265 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.filter.layers.dropShadow.exceptions +// Description:Test exceptions on CanvasFilter() dropShadow object +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +var t = async_test("Test exceptions on CanvasFilter() dropShadow object"); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + + var canvas = new OffscreenCanvas(100, 50); + var ctx = canvas.getContext('2d'); + + // Should not throw an error. + // dx + ctx.beginLayer({filter: + {name: 'dropShadow', dx: 10}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: -1}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: 0.5}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: null}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: true}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: false}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: []}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: [20]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: '30'}}); ctx.endLayer(); + // dy + ctx.beginLayer({filter: + {name: 'dropShadow', dy: 10}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: -1}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: 0.5}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: null}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: true}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: false}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: []}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: [20]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: '30'}}); ctx.endLayer(); + // floodOpacity + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: 10}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: -1}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: 0.5}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: null}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: true}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: false}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: []}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: [20]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: '30'}}); ctx.endLayer(); + // dx + ctx.beginLayer({filter: + {name: 'dropShadow', dx: 10}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: -1}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: 0.5}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: null}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: true}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: false}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: []}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: [20]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dx: '30'}}); ctx.endLayer(); + // dy + ctx.beginLayer({filter: + {name: 'dropShadow', dy: 10}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: -1}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: 0.5}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: null}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: true}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: false}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: []}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: [20]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', dy: '30'}}); ctx.endLayer(); + // floodOpacity + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: 10}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: -1}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: 0.5}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: null}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: true}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: false}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: []}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: [20]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: '30'}}); ctx.endLayer(); + // stdDeviation + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: 10}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: -1}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: 0.5}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: null}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: true}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: false}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: []}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [20]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: '30'}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [10, -1]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [0.5, null]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [true, false]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [[], [20]]}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: ['30', ['40']]}}); ctx.endLayer(); + // floodColor + ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: 'red'}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: 'canvas'}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: 'rgba(4, -3, 0.5, 1)'}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: '#aabbccdd'}}); ctx.endLayer(); + ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: '#abcd'}}); ctx.endLayer(); + + // Should throw a TypeError. + // dx + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dx: NaN}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dx: Infinity}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dx: -Infinity}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dx: undefined}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dx: 'test'}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dx: {}}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dx: [1, 2]}}); ctx.endLayer(); }); + // dy + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dy: NaN}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dy: Infinity}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dy: -Infinity}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dy: undefined}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dy: 'test'}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dy: {}}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', dy: [1, 2]}}); ctx.endLayer(); }); + // floodOpacity + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: NaN}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: Infinity}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: -Infinity}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: undefined}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: 'test'}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: {}}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodOpacity: [1, 2]}}); ctx.endLayer(); }); + // stdDeviation + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: NaN}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: Infinity}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: -Infinity}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: undefined}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: 'test'}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: {}}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [1, 2, 3]}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [1, NaN]}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [1, Infinity]}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [1, -Infinity]}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [1, undefined]}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [1, 'test']}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [1, {}]}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', stdDeviation: [1, [2, 3]]}}); ctx.endLayer(); }); + // floodColor + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: 'test'}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: 'rgba(NaN, 3, 2, 1)'}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: 10}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: undefined}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: null}}); ctx.endLayer(); }); + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: + {name: 'dropShadow', floodColor: NaN}}); ctx.endLayer(); }); + t.done(); +}); +done(); diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.dropShadow.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.dropShadow.html new file mode 100644 index 0000000000..1ecf309fc4 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.dropShadow.html @@ -0,0 +1,97 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.filter.layers.dropShadow-expected.html"> +<title>Canvas test: 2d.filter.layers.dropShadow</title> +<h1>2d.filter.layers.dropShadow</h1> +<p class="desc">Test CanvasFilter() dropShadow object.</p> +<canvas id="canvas" width="520" height="420"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = new OffscreenCanvas(520, 420); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'teal'; + ctx.fillRect(0, 0, 520, 50); + ctx.fillRect(0, 100, 520, 50); + ctx.fillRect(0, 200, 520, 50); + ctx.fillRect(0, 300, 520, 50); + + ctx.fillStyle = 'crimson'; + + // Parameter defaults. + ctx.beginLayer({filter: {name: 'dropShadow'}}); + ctx.fillRect(10, 10, 80, 80); + ctx.endLayer(); + // All parameters specified. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5, + floodColor: 'purple', floodOpacity: 0.7}}); + ctx.fillRect(110, 10, 80, 80); + ctx.endLayer(); + // Named color. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + floodColor: 'purple'}}); + ctx.fillRect(10, 110, 80, 80); + ctx.endLayer(); + // System color. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + floodColor: 'LinkText'}}); + ctx.fillRect(110, 110, 80, 80); + ctx.endLayer(); + // Numerical color. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + floodColor: 'rgba(20, 50, 130, 1)'}}); + ctx.fillRect(210, 110, 80, 80); + ctx.endLayer(); + // Transparent floodColor. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + floodColor: 'rgba(20, 50, 130, 0.7)'}}); + ctx.fillRect(310, 110, 80, 80); + ctx.endLayer(); + // Transparent floodColor and floodOpacity. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + floodColor: 'rgba(20, 50, 130, 0.7)', floodOpacity: 0.7}}); + ctx.fillRect(410, 110, 80, 80); + ctx.endLayer(); + // No blur. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 0, + floodColor: 'purple'}}); + ctx.fillRect(10, 210, 80, 80); + ctx.endLayer(); + // Single float blur. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5, + floodColor: 'purple'}}); + ctx.fillRect(110, 210, 80, 80); + ctx.endLayer(); + // Single negative float blur. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: -5, + floodColor: 'purple'}}); + ctx.fillRect(210, 210, 80, 80); + ctx.endLayer(); + // Two floats (X&Y) blur. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: [3, 5], + floodColor: 'purple'}}); + ctx.fillRect(310, 210, 80, 80); + ctx.endLayer(); + // Two negative floats (X&Y) blur. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: [-3, -5], + floodColor: 'purple'}}); + ctx.fillRect(410, 210, 80, 80); + ctx.endLayer(); + // Degenerate parameter values. + ctx.beginLayer({filter: {name: 'dropShadow', dx: [-5], dy: [], stdDeviation: null, + floodColor: 'purple', floodOpacity: [2]}}); + ctx.fillRect(10, 310, 80, 80); + ctx.endLayer(); + ctx.beginLayer({filter: {name: 'dropShadow', dx: null, dy: '5', stdDeviation: [[-5], ['3']], + floodColor: 'purple', floodOpacity: '0.8'}}); + ctx.fillRect(110, 310, 80, 80); + ctx.endLayer(); + ctx.beginLayer({filter: {name: 'dropShadow', dx: true, dy: ['10'], stdDeviation: false, + floodColor: 'purple', floodOpacity: ['0.4']}}); + ctx.fillRect(210, 310, 80, 80); + ctx.endLayer(); + + const outputCanvas = document.getElementById("canvas"); + outputCanvas.getContext('2d').drawImage(canvas, 0, 0); +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.dropShadow.w.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.dropShadow.w.html new file mode 100644 index 0000000000..e73b573779 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.dropShadow.w.html @@ -0,0 +1,111 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<html class="reftest-wait"> +<link rel="match" href="2d.filter.layers.dropShadow-expected.html"> +<title>Canvas test: 2d.filter.layers.dropShadow</title> +<h1>2d.filter.layers.dropShadow</h1> +<p class="desc">Test CanvasFilter() dropShadow object.</p> +<canvas id="canvas" width="520" height="420"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script id='myWorker' type='text/worker'> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(520, 420); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'teal'; + ctx.fillRect(0, 0, 520, 50); + ctx.fillRect(0, 100, 520, 50); + ctx.fillRect(0, 200, 520, 50); + ctx.fillRect(0, 300, 520, 50); + + ctx.fillStyle = 'crimson'; + + // Parameter defaults. + ctx.beginLayer({filter: {name: 'dropShadow'}}); + ctx.fillRect(10, 10, 80, 80); + ctx.endLayer(); + // All parameters specified. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5, + floodColor: 'purple', floodOpacity: 0.7}}); + ctx.fillRect(110, 10, 80, 80); + ctx.endLayer(); + // Named color. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + floodColor: 'purple'}}); + ctx.fillRect(10, 110, 80, 80); + ctx.endLayer(); + // System color. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + floodColor: 'LinkText'}}); + ctx.fillRect(110, 110, 80, 80); + ctx.endLayer(); + // Numerical color. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + floodColor: 'rgba(20, 50, 130, 1)'}}); + ctx.fillRect(210, 110, 80, 80); + ctx.endLayer(); + // Transparent floodColor. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + floodColor: 'rgba(20, 50, 130, 0.7)'}}); + ctx.fillRect(310, 110, 80, 80); + ctx.endLayer(); + // Transparent floodColor and floodOpacity. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + floodColor: 'rgba(20, 50, 130, 0.7)', floodOpacity: 0.7}}); + ctx.fillRect(410, 110, 80, 80); + ctx.endLayer(); + // No blur. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 0, + floodColor: 'purple'}}); + ctx.fillRect(10, 210, 80, 80); + ctx.endLayer(); + // Single float blur. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5, + floodColor: 'purple'}}); + ctx.fillRect(110, 210, 80, 80); + ctx.endLayer(); + // Single negative float blur. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: -5, + floodColor: 'purple'}}); + ctx.fillRect(210, 210, 80, 80); + ctx.endLayer(); + // Two floats (X&Y) blur. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: [3, 5], + floodColor: 'purple'}}); + ctx.fillRect(310, 210, 80, 80); + ctx.endLayer(); + // Two negative floats (X&Y) blur. + ctx.beginLayer({filter: {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: [-3, -5], + floodColor: 'purple'}}); + ctx.fillRect(410, 210, 80, 80); + ctx.endLayer(); + // Degenerate parameter values. + ctx.beginLayer({filter: {name: 'dropShadow', dx: [-5], dy: [], stdDeviation: null, + floodColor: 'purple', floodOpacity: [2]}}); + ctx.fillRect(10, 310, 80, 80); + ctx.endLayer(); + ctx.beginLayer({filter: {name: 'dropShadow', dx: null, dy: '5', stdDeviation: [[-5], ['3']], + floodColor: 'purple', floodOpacity: '0.8'}}); + ctx.fillRect(110, 310, 80, 80); + ctx.endLayer(); + ctx.beginLayer({filter: {name: 'dropShadow', dx: true, dy: ['10'], stdDeviation: false, + floodColor: 'purple', floodOpacity: ['0.4']}}); + ctx.fillRect(210, 310, 80, 80); + ctx.endLayer(); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; +</script> +<script> + const blob = new Blob([document.getElementById('myWorker').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCtx = document.getElementById("canvas").getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + document.documentElement.classList.remove("reftest-wait"); + }); + worker.postMessage(null); +</script> +</html> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.isotropic-expected.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.isotropic-expected.html new file mode 100644 index 0000000000..4f93754862 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.isotropic-expected.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.layers.gaussianBlur.isotropic</title> +<h1>2d.filter.layers.gaussianBlur.isotropic</h1> +<p class="desc">Test CanvasFilter() with gaussianBlur.</p> + +<svg xmlns="http://www.w3.org/2000/svg" + width="100" height="100" + color-interpolation-filters="sRGB"> + <filter id="blur" x="-50%" y="-50%" width="200%" height="200%"> + <feGaussianBlur stdDeviation="4 4" /> + </filter> + <rect x="25" y="25" width="50" height="50" + fill="teal" filter="url(#blur)" /> +</svg> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.isotropic.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.isotropic.html new file mode 100644 index 0000000000..50a98df1be --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.isotropic.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.filter.layers.gaussianBlur.isotropic-expected.html"> +<title>Canvas test: 2d.filter.layers.gaussianBlur.isotropic</title> +<h1>2d.filter.layers.gaussianBlur.isotropic</h1> +<p class="desc">Test CanvasFilter() with gaussianBlur.</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = new OffscreenCanvas(100, 100); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'teal'; + ctx.beginLayer({filter: { + name: 'gaussianBlur', + stdDeviation: [4, 4], + }}); + ctx.fillRect(25, 25, 50, 50); + ctx.endLayer(); + + const outputCanvas = document.getElementById("canvas"); + outputCanvas.getContext('2d').drawImage(canvas, 0, 0); +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.isotropic.w.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.isotropic.w.html new file mode 100644 index 0000000000..a68b8e78a2 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.isotropic.w.html @@ -0,0 +1,38 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<html class="reftest-wait"> +<link rel="match" href="2d.filter.layers.gaussianBlur.isotropic-expected.html"> +<title>Canvas test: 2d.filter.layers.gaussianBlur.isotropic</title> +<h1>2d.filter.layers.gaussianBlur.isotropic</h1> +<p class="desc">Test CanvasFilter() with gaussianBlur.</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script id='myWorker' type='text/worker'> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(100, 100); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'teal'; + ctx.beginLayer({filter: { + name: 'gaussianBlur', + stdDeviation: [4, 4], + }}); + ctx.fillRect(25, 25, 50, 50); + ctx.endLayer(); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; +</script> +<script> + const blob = new Blob([document.getElementById('myWorker').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCtx = document.getElementById("canvas").getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + document.documentElement.classList.remove("reftest-wait"); + }); + worker.postMessage(null); +</script> +</html> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.mostly-x-expected.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.mostly-x-expected.html new file mode 100644 index 0000000000..255270c192 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.mostly-x-expected.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.layers.gaussianBlur.mostly-x</title> +<h1>2d.filter.layers.gaussianBlur.mostly-x</h1> +<p class="desc">Test CanvasFilter() with gaussianBlur.</p> + +<svg xmlns="http://www.w3.org/2000/svg" + width="100" height="100" + color-interpolation-filters="sRGB"> + <filter id="blur" x="-50%" y="-50%" width="200%" height="200%"> + <feGaussianBlur stdDeviation="4 1" /> + </filter> + <rect x="25" y="25" width="50" height="50" + fill="teal" filter="url(#blur)" /> +</svg> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.mostly-x.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.mostly-x.html new file mode 100644 index 0000000000..efc634796c --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.mostly-x.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.filter.layers.gaussianBlur.mostly-x-expected.html"> +<title>Canvas test: 2d.filter.layers.gaussianBlur.mostly-x</title> +<h1>2d.filter.layers.gaussianBlur.mostly-x</h1> +<p class="desc">Test CanvasFilter() with gaussianBlur.</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = new OffscreenCanvas(100, 100); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'teal'; + ctx.beginLayer({filter: { + name: 'gaussianBlur', + stdDeviation: [4, 1], + }}); + ctx.fillRect(25, 25, 50, 50); + ctx.endLayer(); + + const outputCanvas = document.getElementById("canvas"); + outputCanvas.getContext('2d').drawImage(canvas, 0, 0); +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.mostly-x.w.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.mostly-x.w.html new file mode 100644 index 0000000000..7d20d78503 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.mostly-x.w.html @@ -0,0 +1,38 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<html class="reftest-wait"> +<link rel="match" href="2d.filter.layers.gaussianBlur.mostly-x-expected.html"> +<title>Canvas test: 2d.filter.layers.gaussianBlur.mostly-x</title> +<h1>2d.filter.layers.gaussianBlur.mostly-x</h1> +<p class="desc">Test CanvasFilter() with gaussianBlur.</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script id='myWorker' type='text/worker'> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(100, 100); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'teal'; + ctx.beginLayer({filter: { + name: 'gaussianBlur', + stdDeviation: [4, 1], + }}); + ctx.fillRect(25, 25, 50, 50); + ctx.endLayer(); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; +</script> +<script> + const blob = new Blob([document.getElementById('myWorker').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCtx = document.getElementById("canvas").getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + document.documentElement.classList.remove("reftest-wait"); + }); + worker.postMessage(null); +</script> +</html> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.mostly-y-expected.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.mostly-y-expected.html new file mode 100644 index 0000000000..76a46b1533 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.mostly-y-expected.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.layers.gaussianBlur.mostly-y</title> +<h1>2d.filter.layers.gaussianBlur.mostly-y</h1> +<p class="desc">Test CanvasFilter() with gaussianBlur.</p> + +<svg xmlns="http://www.w3.org/2000/svg" + width="100" height="100" + color-interpolation-filters="sRGB"> + <filter id="blur" x="-50%" y="-50%" width="200%" height="200%"> + <feGaussianBlur stdDeviation="1 4" /> + </filter> + <rect x="25" y="25" width="50" height="50" + fill="teal" filter="url(#blur)" /> +</svg> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.mostly-y.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.mostly-y.html new file mode 100644 index 0000000000..bdc6e66fe5 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.mostly-y.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.filter.layers.gaussianBlur.mostly-y-expected.html"> +<title>Canvas test: 2d.filter.layers.gaussianBlur.mostly-y</title> +<h1>2d.filter.layers.gaussianBlur.mostly-y</h1> +<p class="desc">Test CanvasFilter() with gaussianBlur.</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = new OffscreenCanvas(100, 100); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'teal'; + ctx.beginLayer({filter: { + name: 'gaussianBlur', + stdDeviation: [1, 4], + }}); + ctx.fillRect(25, 25, 50, 50); + ctx.endLayer(); + + const outputCanvas = document.getElementById("canvas"); + outputCanvas.getContext('2d').drawImage(canvas, 0, 0); +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.mostly-y.w.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.mostly-y.w.html new file mode 100644 index 0000000000..dfd6438b19 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.mostly-y.w.html @@ -0,0 +1,38 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<html class="reftest-wait"> +<link rel="match" href="2d.filter.layers.gaussianBlur.mostly-y-expected.html"> +<title>Canvas test: 2d.filter.layers.gaussianBlur.mostly-y</title> +<h1>2d.filter.layers.gaussianBlur.mostly-y</h1> +<p class="desc">Test CanvasFilter() with gaussianBlur.</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script id='myWorker' type='text/worker'> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(100, 100); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'teal'; + ctx.beginLayer({filter: { + name: 'gaussianBlur', + stdDeviation: [1, 4], + }}); + ctx.fillRect(25, 25, 50, 50); + ctx.endLayer(); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; +</script> +<script> + const blob = new Blob([document.getElementById('myWorker').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCtx = document.getElementById("canvas").getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + document.documentElement.classList.remove("reftest-wait"); + }); + worker.postMessage(null); +</script> +</html> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.x-only-expected.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.x-only-expected.html new file mode 100644 index 0000000000..26741f9847 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.x-only-expected.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.layers.gaussianBlur.x-only</title> +<h1>2d.filter.layers.gaussianBlur.x-only</h1> +<p class="desc">Test CanvasFilter() with gaussianBlur.</p> + +<svg xmlns="http://www.w3.org/2000/svg" + width="100" height="100" + color-interpolation-filters="sRGB"> + <filter id="blur" x="-50%" y="-50%" width="200%" height="200%"> + <feGaussianBlur stdDeviation="4 0" /> + </filter> + <rect x="25" y="25" width="50" height="50" + fill="teal" filter="url(#blur)" /> +</svg> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.x-only.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.x-only.html new file mode 100644 index 0000000000..0d42acb8b5 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.x-only.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.filter.layers.gaussianBlur.x-only-expected.html"> +<title>Canvas test: 2d.filter.layers.gaussianBlur.x-only</title> +<h1>2d.filter.layers.gaussianBlur.x-only</h1> +<p class="desc">Test CanvasFilter() with gaussianBlur.</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = new OffscreenCanvas(100, 100); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'teal'; + ctx.beginLayer({filter: { + name: 'gaussianBlur', + stdDeviation: [4, 0], + }}); + ctx.fillRect(25, 25, 50, 50); + ctx.endLayer(); + + const outputCanvas = document.getElementById("canvas"); + outputCanvas.getContext('2d').drawImage(canvas, 0, 0); +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.x-only.w.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.x-only.w.html new file mode 100644 index 0000000000..b235c7ad38 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.x-only.w.html @@ -0,0 +1,38 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<html class="reftest-wait"> +<link rel="match" href="2d.filter.layers.gaussianBlur.x-only-expected.html"> +<title>Canvas test: 2d.filter.layers.gaussianBlur.x-only</title> +<h1>2d.filter.layers.gaussianBlur.x-only</h1> +<p class="desc">Test CanvasFilter() with gaussianBlur.</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script id='myWorker' type='text/worker'> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(100, 100); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'teal'; + ctx.beginLayer({filter: { + name: 'gaussianBlur', + stdDeviation: [4, 0], + }}); + ctx.fillRect(25, 25, 50, 50); + ctx.endLayer(); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; +</script> +<script> + const blob = new Blob([document.getElementById('myWorker').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCtx = document.getElementById("canvas").getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + document.documentElement.classList.remove("reftest-wait"); + }); + worker.postMessage(null); +</script> +</html> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.y-only-expected.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.y-only-expected.html new file mode 100644 index 0000000000..d00eec6b57 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.y-only-expected.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.filter.layers.gaussianBlur.y-only</title> +<h1>2d.filter.layers.gaussianBlur.y-only</h1> +<p class="desc">Test CanvasFilter() with gaussianBlur.</p> + +<svg xmlns="http://www.w3.org/2000/svg" + width="100" height="100" + color-interpolation-filters="sRGB"> + <filter id="blur" x="-50%" y="-50%" width="200%" height="200%"> + <feGaussianBlur stdDeviation="0 4" /> + </filter> + <rect x="25" y="25" width="50" height="50" + fill="teal" filter="url(#blur)" /> +</svg> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.y-only.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.y-only.html new file mode 100644 index 0000000000..c9bc85d699 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.y-only.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.filter.layers.gaussianBlur.y-only-expected.html"> +<title>Canvas test: 2d.filter.layers.gaussianBlur.y-only</title> +<h1>2d.filter.layers.gaussianBlur.y-only</h1> +<p class="desc">Test CanvasFilter() with gaussianBlur.</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = new OffscreenCanvas(100, 100); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'teal'; + ctx.beginLayer({filter: { + name: 'gaussianBlur', + stdDeviation: [0, 4], + }}); + ctx.fillRect(25, 25, 50, 50); + ctx.endLayer(); + + const outputCanvas = document.getElementById("canvas"); + outputCanvas.getContext('2d').drawImage(canvas, 0, 0); +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.y-only.w.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.y-only.w.html new file mode 100644 index 0000000000..5deb96c255 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.y-only.w.html @@ -0,0 +1,38 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<html class="reftest-wait"> +<link rel="match" href="2d.filter.layers.gaussianBlur.y-only-expected.html"> +<title>Canvas test: 2d.filter.layers.gaussianBlur.y-only</title> +<h1>2d.filter.layers.gaussianBlur.y-only</h1> +<p class="desc">Test CanvasFilter() with gaussianBlur.</p> +<canvas id="canvas" width="100" height="100"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script id='myWorker' type='text/worker'> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(100, 100); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'teal'; + ctx.beginLayer({filter: { + name: 'gaussianBlur', + stdDeviation: [0, 4], + }}); + ctx.fillRect(25, 25, 50, 50); + ctx.endLayer(); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; +</script> +<script> + const blob = new Blob([document.getElementById('myWorker').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCtx = document.getElementById("canvas").getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + document.documentElement.classList.remove("reftest-wait"); + }); + worker.postMessage(null); +</script> +</html> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.turbulence.inputTypes.html b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.turbulence.inputTypes.html new file mode 100644 index 0000000000..27f7748c84 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.turbulence.inputTypes.html @@ -0,0 +1,131 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>OffscreenCanvas test: 2d.filter.layers.turbulence.inputTypes</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> + +<h1>2d.filter.layers.turbulence.inputTypes</h1> +<p class="desc">Test exceptions on CanvasFilter() turbulence object</p> + + +<script> +var t = async_test("Test exceptions on CanvasFilter() turbulence object"); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + + var canvas = new OffscreenCanvas(100, 50); + var ctx = canvas.getContext('2d'); + + const errorTestCases = [ + {baseFrequency: {}}, + {baseFrequency: -1}, + {baseFrequency: [0, -1]}, + {baseFrequency: NaN}, + {baseFrequency: Infinity}, + {baseFrequency: undefined}, + {baseFrequency: -Infinity}, + {baseFrequency: 'test'}, + + {numOctaves: {}}, + {numOctaves: -1}, + {numOctaves: NaN}, + {numOctaves: Infinity}, + {numOctaves: undefined}, + {numOctaves: -Infinity}, + {numOctaves: [1, 1]}, + {numOctaves: 'test'}, + + {seed: {}}, + {seed: NaN}, + {seed: Infinity}, + {seed: undefined}, + {seed: -Infinity}, + {seed: [1, 1]}, + {seed: 'test'}, + + {stitchTiles: {}}, + {stitchTiles: NaN}, + {stitchTiles: Infinity}, + {stitchTiles: undefined}, + {stitchTiles: -Infinity}, + {stitchTiles: [1, 1]}, + {stitchTiles: 'test'}, + {stitchTiles: null}, + {stitchTiles: []}, + {stitchTiles: [10]}, + {stitchTiles: 30}, + {stitchTiles: false}, + {stitchTiles: true}, + {stitchTiles: '10'}, + {stitchTiles: -1}, + + {type: {}}, + {type: NaN}, + {type: Infinity}, + {type: undefined}, + {type: -Infinity}, + {type: [1, 1]}, + {type: 'test'}, + {type: null}, + {type: []}, + {type: [10]}, + {type: 30}, + {type: false}, + {type: true}, + {type: '10'}, + {type: -1}, + ] + + // null and [] = 0 when parsed as number + const workingTestCases = [ + {baseFrequency: null}, + {baseFrequency: []}, + {baseFrequency: [10]}, + {baseFrequency: [10, 3]}, + {baseFrequency: 30}, + {baseFrequency: false}, + {baseFrequency: true}, + {baseFrequency: '10'}, + + {numOctaves: null}, + {numOctaves: []}, + {numOctaves: [10]}, + {numOctaves: 30}, + {numOctaves: false}, + {numOctaves: true}, + {numOctaves: '10'}, + + {seed: null}, + {seed: []}, + {seed: [10]}, + {seed: 30}, + {seed: false}, + {seed: true}, + {seed: '10'}, + {seed: -1}, + + {stitchTiles: 'stitch'}, + {stitchTiles: 'noStitch'}, + + {type: 'fractalNoise'}, + {type: 'turbulence'}, + ] + + for (testCase of errorTestCases) { + const filterOptions = {...{name: 'turbulence'}, ...testCase}; + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: filterOptions}); }); + } + + for (testCase of workingTestCases) { + const filterOptions = {...{name: 'turbulence'}, ...testCase}; + ctx.beginLayer({filter: filterOptions}); + ctx.endLayer(); + } + t.done(); + +}); +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.turbulence.inputTypes.worker.js b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.turbulence.inputTypes.worker.js new file mode 100644 index 0000000000..3728566c99 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/filters/2d.filter.layers.turbulence.inputTypes.worker.js @@ -0,0 +1,126 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.filter.layers.turbulence.inputTypes +// Description:Test exceptions on CanvasFilter() turbulence object +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +var t = async_test("Test exceptions on CanvasFilter() turbulence object"); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + + var canvas = new OffscreenCanvas(100, 50); + var ctx = canvas.getContext('2d'); + + const errorTestCases = [ + {baseFrequency: {}}, + {baseFrequency: -1}, + {baseFrequency: [0, -1]}, + {baseFrequency: NaN}, + {baseFrequency: Infinity}, + {baseFrequency: undefined}, + {baseFrequency: -Infinity}, + {baseFrequency: 'test'}, + + {numOctaves: {}}, + {numOctaves: -1}, + {numOctaves: NaN}, + {numOctaves: Infinity}, + {numOctaves: undefined}, + {numOctaves: -Infinity}, + {numOctaves: [1, 1]}, + {numOctaves: 'test'}, + + {seed: {}}, + {seed: NaN}, + {seed: Infinity}, + {seed: undefined}, + {seed: -Infinity}, + {seed: [1, 1]}, + {seed: 'test'}, + + {stitchTiles: {}}, + {stitchTiles: NaN}, + {stitchTiles: Infinity}, + {stitchTiles: undefined}, + {stitchTiles: -Infinity}, + {stitchTiles: [1, 1]}, + {stitchTiles: 'test'}, + {stitchTiles: null}, + {stitchTiles: []}, + {stitchTiles: [10]}, + {stitchTiles: 30}, + {stitchTiles: false}, + {stitchTiles: true}, + {stitchTiles: '10'}, + {stitchTiles: -1}, + + {type: {}}, + {type: NaN}, + {type: Infinity}, + {type: undefined}, + {type: -Infinity}, + {type: [1, 1]}, + {type: 'test'}, + {type: null}, + {type: []}, + {type: [10]}, + {type: 30}, + {type: false}, + {type: true}, + {type: '10'}, + {type: -1}, + ] + + // null and [] = 0 when parsed as number + const workingTestCases = [ + {baseFrequency: null}, + {baseFrequency: []}, + {baseFrequency: [10]}, + {baseFrequency: [10, 3]}, + {baseFrequency: 30}, + {baseFrequency: false}, + {baseFrequency: true}, + {baseFrequency: '10'}, + + {numOctaves: null}, + {numOctaves: []}, + {numOctaves: [10]}, + {numOctaves: 30}, + {numOctaves: false}, + {numOctaves: true}, + {numOctaves: '10'}, + + {seed: null}, + {seed: []}, + {seed: [10]}, + {seed: 30}, + {seed: false}, + {seed: true}, + {seed: '10'}, + {seed: -1}, + + {stitchTiles: 'stitch'}, + {stitchTiles: 'noStitch'}, + + {type: 'fractalNoise'}, + {type: 'turbulence'}, + ] + + for (testCase of errorTestCases) { + const filterOptions = {...{name: 'turbulence'}, ...testCase}; + assert_throws_js(TypeError, function() { ctx.beginLayer({filter: filterOptions}); }); + } + + for (testCase of workingTestCases) { + const filterOptions = {...{name: 'turbulence'}, ...testCase}; + ctx.beginLayer({filter: filterOptions}); + ctx.endLayer(); + } + t.done(); +}); +done(); diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.filter-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.filter-expected.html new file mode 100644 index 0000000000..5fc1ac9acd --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.filter-expected.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.layer.ctm.filter</title> +<h1>2d.layer.ctm.filter</h1> +<p class="desc">Checks that parent transforms affect layer filters.</p> + +<svg xmlns="http://www.w3.org/2000/svg" + width="200" height="200" + color-interpolation-filters="sRGB"> + <filter id="filter" x="-100%" y="-100%" width="300%" height="300%"> + <feDropShadow dx="5" dy="5" stdDeviation="0" flood-color="grey" /> + </filter> + + <g filter="url(#filter)"> + <g transform="translate(30, 90) scale(2) rotate(90)"> + <rect x="-30" y="-5" width=60 height=10></rect> + </g> + </g> + + <g transform="translate(80, 90) scale(2) rotate(90)"> + <g filter="url(#filter)"> + <rect x="-30" y="-5" width=60 height=10></rect> + </g> + </g> +</svg> diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.filter.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.filter.html new file mode 100644 index 0000000000..e5efc24bcc --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.filter.html @@ -0,0 +1,32 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.layer.ctm.filter-expected.html"> +<title>Canvas test: 2d.layer.ctm.filter</title> +<h1>2d.layer.ctm.filter</h1> +<p class="desc">Checks that parent transforms affect layer filters.</p> +<canvas id="canvas" width="200" height="200"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = new OffscreenCanvas(200, 200); + const ctx = canvas.getContext('2d'); + + // Transforms inside the layer should not apply to the layer's filter. + ctx.beginLayer({filter: 'drop-shadow(5px 5px 0px grey)'}); + ctx.translate(30, 90); + ctx.scale(2, 2); + ctx.rotate(Math.PI / 2); + ctx.fillRect(-30, -5, 60, 10); + ctx.endLayer(); + + // Transforms in the layer's parent should apply to the layer's filter. + ctx.translate(80, 90); + ctx.scale(2, 2); + ctx.rotate(Math.PI / 2); + ctx.beginLayer({filter: 'drop-shadow(5px 5px 0px grey)'}); + ctx.fillRect(-30, -5, 60, 10); + ctx.endLayer(); + + const outputCanvas = document.getElementById("canvas"); + outputCanvas.getContext('2d').drawImage(canvas, 0, 0); +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.filter.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.filter.w.html new file mode 100644 index 0000000000..760a65e2c8 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.filter.w.html @@ -0,0 +1,46 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<html class="reftest-wait"> +<link rel="match" href="2d.layer.ctm.filter-expected.html"> +<title>Canvas test: 2d.layer.ctm.filter</title> +<h1>2d.layer.ctm.filter</h1> +<p class="desc">Checks that parent transforms affect layer filters.</p> +<canvas id="canvas" width="200" height="200"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script id='myWorker' type='text/worker'> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(200, 200); + const ctx = canvas.getContext('2d'); + + // Transforms inside the layer should not apply to the layer's filter. + ctx.beginLayer({filter: 'drop-shadow(5px 5px 0px grey)'}); + ctx.translate(30, 90); + ctx.scale(2, 2); + ctx.rotate(Math.PI / 2); + ctx.fillRect(-30, -5, 60, 10); + ctx.endLayer(); + + // Transforms in the layer's parent should apply to the layer's filter. + ctx.translate(80, 90); + ctx.scale(2, 2); + ctx.rotate(Math.PI / 2); + ctx.beginLayer({filter: 'drop-shadow(5px 5px 0px grey)'}); + ctx.fillRect(-30, -5, 60, 10); + ctx.endLayer(); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; +</script> +<script> + const blob = new Blob([document.getElementById('myWorker').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCtx = document.getElementById("canvas").getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + document.documentElement.classList.remove("reftest-wait"); + }); + worker.postMessage(null); +</script> +</html> diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.getTransform.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.getTransform.html new file mode 100644 index 0000000000..b2306d95ac --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.getTransform.html @@ -0,0 +1,32 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>OffscreenCanvas test: 2d.layer.ctm.getTransform</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/canvas/resources/canvas-tests.js"></script> + +<h1>2d.layer.ctm.getTransform</h1> +<p class="desc">Tests getTransform inside layers.</p> + + +<script> +var t = async_test("Tests getTransform inside layers."); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + + var canvas = new OffscreenCanvas(100, 50); + var ctx = canvas.getContext('2d'); + + ctx.translate(10, 20); + ctx.beginLayer(); + ctx.scale(2, 3); + const m = ctx.getTransform(); + assert_array_equals([m.a, m.b, m.c, m.d, m.e, m.f], [2, 0, 0, 3, 10, 20]); + ctx.endLayer(); + t.done(); + +}); +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.getTransform.worker.js b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.getTransform.worker.js new file mode 100644 index 0000000000..54b1fee5d0 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.getTransform.worker.js @@ -0,0 +1,27 @@ +// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. +// OffscreenCanvas test in a worker:2d.layer.ctm.getTransform +// Description:Tests getTransform inside layers. +// Note: + +importScripts("/resources/testharness.js"); +importScripts("/html/canvas/resources/canvas-tests.js"); + +var t = async_test("Tests getTransform inside layers."); +var t_pass = t.done.bind(t); +var t_fail = t.step_func(function(reason) { + throw reason; +}); +t.step(function() { + + var canvas = new OffscreenCanvas(100, 50); + var ctx = canvas.getContext('2d'); + + ctx.translate(10, 20); + ctx.beginLayer(); + ctx.scale(2, 3); + const m = ctx.getTransform(); + assert_array_equals([m.a, m.b, m.c, m.d, m.e, m.f], [2, 0, 0, 3, 10, 20]); + ctx.endLayer(); + t.done(); +}); +done(); diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.resetTransform-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.resetTransform-expected.html new file mode 100644 index 0000000000..fd4c1746c7 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.resetTransform-expected.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.layer.ctm.resetTransform</title> +<h1>2d.layer.ctm.resetTransform</h1> +<p class="desc">Tests resetTransform inside layers.</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'blue'; + ctx.fillRect(0, 0, 20, 20); + + ctx.translate(40, 0); + ctx.fillStyle = 'green'; + ctx.fillRect(0, 0, 20, 20); +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.resetTransform.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.resetTransform.html new file mode 100644 index 0000000000..9508b34044 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.resetTransform.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.layer.ctm.resetTransform-expected.html"> +<title>Canvas test: 2d.layer.ctm.resetTransform</title> +<h1>2d.layer.ctm.resetTransform</h1> +<p class="desc">Tests resetTransform inside layers.</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = new OffscreenCanvas(100, 50); + const ctx = canvas.getContext('2d'); + + ctx.translate(40, 0); + + ctx.beginLayer(); + ctx.rotate(2); + ctx.beginLayer(); + ctx.scale(5, 6); + ctx.resetTransform(); + ctx.fillStyle = 'blue'; + ctx.fillRect(0, 0, 20, 20); + ctx.endLayer(); + ctx.endLayer(); + + ctx.fillStyle = 'green'; + ctx.fillRect(0, 0, 20, 20); + + const outputCanvas = document.getElementById("canvas"); + outputCanvas.getContext('2d').drawImage(canvas, 0, 0); +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.resetTransform.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.resetTransform.w.html new file mode 100644 index 0000000000..7bf63e1473 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.resetTransform.w.html @@ -0,0 +1,45 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<html class="reftest-wait"> +<link rel="match" href="2d.layer.ctm.resetTransform-expected.html"> +<title>Canvas test: 2d.layer.ctm.resetTransform</title> +<h1>2d.layer.ctm.resetTransform</h1> +<p class="desc">Tests resetTransform inside layers.</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script id='myWorker' type='text/worker'> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(100, 50); + const ctx = canvas.getContext('2d'); + + ctx.translate(40, 0); + + ctx.beginLayer(); + ctx.rotate(2); + ctx.beginLayer(); + ctx.scale(5, 6); + ctx.resetTransform(); + ctx.fillStyle = 'blue'; + ctx.fillRect(0, 0, 20, 20); + ctx.endLayer(); + ctx.endLayer(); + + ctx.fillStyle = 'green'; + ctx.fillRect(0, 0, 20, 20); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; +</script> +<script> + const blob = new Blob([document.getElementById('myWorker').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCtx = document.getElementById("canvas").getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + document.documentElement.classList.remove("reftest-wait"); + }); + worker.postMessage(null); +</script> +</html> diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.setTransform-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.setTransform-expected.html new file mode 100644 index 0000000000..45a3d095e1 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.setTransform-expected.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.layer.ctm.setTransform</title> +<h1>2d.layer.ctm.setTransform</h1> +<p class="desc">Tests setTransform inside layers.</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + ctx.translate(80, 0); + ctx.fillStyle = 'green'; + ctx.fillRect(0, 0, 20, 20); + + ctx.setTransform(4, 0, 0, 2, 20, 10); + ctx.fillStyle = 'blue'; + ctx.fillRect(0, 0, 10, 10); +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.setTransform.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.setTransform.html new file mode 100644 index 0000000000..91034943b6 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.setTransform.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.layer.ctm.setTransform-expected.html"> +<title>Canvas test: 2d.layer.ctm.setTransform</title> +<h1>2d.layer.ctm.setTransform</h1> +<p class="desc">Tests setTransform inside layers.</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = new OffscreenCanvas(100, 50); + const ctx = canvas.getContext('2d'); + + ctx.translate(80, 0); + + ctx.beginLayer(); + ctx.rotate(2); + ctx.beginLayer(); + ctx.scale(5, 6); + ctx.setTransform(4, 0, 0, 2, 20, 10); + ctx.fillStyle = 'blue'; + ctx.fillRect(0, 0, 10, 10); + ctx.endLayer(); + ctx.endLayer(); + + ctx.fillStyle = 'green'; + ctx.fillRect(0, 0, 20, 20); + + const outputCanvas = document.getElementById("canvas"); + outputCanvas.getContext('2d').drawImage(canvas, 0, 0); +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.setTransform.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.setTransform.w.html new file mode 100644 index 0000000000..8b1ea1ce51 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.setTransform.w.html @@ -0,0 +1,45 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<html class="reftest-wait"> +<link rel="match" href="2d.layer.ctm.setTransform-expected.html"> +<title>Canvas test: 2d.layer.ctm.setTransform</title> +<h1>2d.layer.ctm.setTransform</h1> +<p class="desc">Tests setTransform inside layers.</p> +<canvas id="canvas" width="100" height="50"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script id='myWorker' type='text/worker'> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(100, 50); + const ctx = canvas.getContext('2d'); + + ctx.translate(80, 0); + + ctx.beginLayer(); + ctx.rotate(2); + ctx.beginLayer(); + ctx.scale(5, 6); + ctx.setTransform(4, 0, 0, 2, 20, 10); + ctx.fillStyle = 'blue'; + ctx.fillRect(0, 0, 10, 10); + ctx.endLayer(); + ctx.endLayer(); + + ctx.fillStyle = 'green'; + ctx.fillRect(0, 0, 20, 20); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; +</script> +<script> + const blob = new Blob([document.getElementById('myWorker').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCtx = document.getElementById("canvas").getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + document.documentElement.classList.remove("reftest-wait"); + }); + worker.postMessage(null); +</script> +</html> diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.shadow-in-transformed-layer-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.shadow-in-transformed-layer-expected.html new file mode 100644 index 0000000000..312ca19b4c --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.shadow-in-transformed-layer-expected.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.layer.ctm.shadow-in-transformed-layer</title> +<h1>2d.layer.ctm.shadow-in-transformed-layer</h1> +<p class="desc">Check shadows inside of a transformed layer.</p> +<canvas id="canvas" width="200" height="200"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + ctx.translate(80, 90); + ctx.scale(2, 2); + ctx.rotate(Math.PI / 2); + + ctx.shadowOffsetX = 10; + ctx.shadowOffsetY = 10; + ctx.shadowColor = 'grey'; + ctx.fillRect(-30, -5, 60, 10); + + const canvas2 = new OffscreenCanvas(100, 100); + const ctx2 = canvas2.getContext('2d'); + ctx2.fillStyle = 'blue'; + ctx2.fillRect(0, 0, 40, 10); + ctx.drawImage(canvas2, -30, -30); +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.shadow-in-transformed-layer.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.shadow-in-transformed-layer.html new file mode 100644 index 0000000000..59305076f0 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.shadow-in-transformed-layer.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.layer.ctm.shadow-in-transformed-layer-expected.html"> +<title>Canvas test: 2d.layer.ctm.shadow-in-transformed-layer</title> +<h1>2d.layer.ctm.shadow-in-transformed-layer</h1> +<p class="desc">Check shadows inside of a transformed layer.</p> +<canvas id="canvas" width="200" height="200"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = new OffscreenCanvas(200, 200); + const ctx = canvas.getContext('2d'); + + ctx.translate(80, 90); + ctx.scale(2, 2); + ctx.rotate(Math.PI / 2); + + ctx.beginLayer(); + ctx.shadowOffsetX = 10; + ctx.shadowOffsetY = 10; + ctx.shadowColor = 'grey'; + ctx.fillRect(-30, -5, 60, 10); + + const canvas2 = new OffscreenCanvas(100, 100); + const ctx2 = canvas2.getContext('2d'); + ctx2.fillStyle = 'blue'; + ctx2.fillRect(0, 0, 40, 10); + ctx.drawImage(canvas2, -30, -30); + + ctx.endLayer(); + + const outputCanvas = document.getElementById("canvas"); + outputCanvas.getContext('2d').drawImage(canvas, 0, 0); +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.shadow-in-transformed-layer.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.shadow-in-transformed-layer.w.html new file mode 100644 index 0000000000..486a028335 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.ctm.shadow-in-transformed-layer.w.html @@ -0,0 +1,48 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<html class="reftest-wait"> +<link rel="match" href="2d.layer.ctm.shadow-in-transformed-layer-expected.html"> +<title>Canvas test: 2d.layer.ctm.shadow-in-transformed-layer</title> +<h1>2d.layer.ctm.shadow-in-transformed-layer</h1> +<p class="desc">Check shadows inside of a transformed layer.</p> +<canvas id="canvas" width="200" height="200"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script id='myWorker' type='text/worker'> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(200, 200); + const ctx = canvas.getContext('2d'); + + ctx.translate(80, 90); + ctx.scale(2, 2); + ctx.rotate(Math.PI / 2); + + ctx.beginLayer(); + ctx.shadowOffsetX = 10; + ctx.shadowOffsetY = 10; + ctx.shadowColor = 'grey'; + ctx.fillRect(-30, -5, 60, 10); + + const canvas2 = new OffscreenCanvas(100, 100); + const ctx2 = canvas2.getContext('2d'); + ctx2.fillStyle = 'blue'; + ctx2.fillRect(0, 0, 40, 10); + ctx.drawImage(canvas2, -30, -30); + + ctx.endLayer(); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; +</script> +<script> + const blob = new Blob([document.getElementById('myWorker').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCtx = document.getElementById("canvas").getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + document.documentElement.classList.remove("reftest-wait"); + }); + worker.postMessage(null); +</script> +</html> diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.drawImage-expected.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.drawImage-expected.html new file mode 100644 index 0000000000..26f6e75214 --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.drawImage-expected.html @@ -0,0 +1,29 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<title>Canvas test: 2d.layer.drawImage</title> +<h1>2d.layer.drawImage</h1> +<p class="desc">Checks that drawImage writes the image to the layer and not the parent directly.</p> +<canvas id="canvas" width="200" height="200"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = document.getElementById("canvas"); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'skyblue'; + ctx.fillRect(0, 0, 100, 100); + + ctx.beginLayer({filter: {name: 'dropShadow', dx: -10, dy: -10, + stdDeviation: 0, floodColor: 'navy'}}); + + ctx.fillStyle = 'maroon'; + ctx.fillRect(20, 20, 50, 50); + + ctx.globalCompositeOperation = 'xor'; + + // Should xor only with the layer content, not the parents'. + ctx.fillStyle = 'pink'; + ctx.fillRect(40, 40, 50, 50); + + ctx.endLayer(); +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.drawImage.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.drawImage.html new file mode 100644 index 0000000000..37718f6f2c --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.drawImage.html @@ -0,0 +1,36 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<link rel="match" href="2d.layer.drawImage-expected.html"> +<title>Canvas test: 2d.layer.drawImage</title> +<h1>2d.layer.drawImage</h1> +<p class="desc">Checks that drawImage writes the image to the layer and not the parent directly.</p> +<canvas id="canvas" width="200" height="200"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script> + const canvas = new OffscreenCanvas(200, 200); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'skyblue'; + ctx.fillRect(0, 0, 100, 100); + + ctx.beginLayer({filter: {name: 'dropShadow', dx: -10, dy: -10, + stdDeviation: 0, floodColor: 'navy'}}); + + ctx.fillStyle = 'maroon'; + ctx.fillRect(20, 20, 50, 50); + + ctx.globalCompositeOperation = 'xor'; + + // The image should xor only with the layer content, not the parents'. + const canvas_image = new OffscreenCanvas(200,200); + const ctx_image = canvas_image.getContext("2d"); + ctx_image.fillStyle = 'pink'; + ctx_image.fillRect(40, 40, 50, 50); + ctx.drawImage(canvas_image, 0, 0); + + ctx.endLayer(); + + const outputCanvas = document.getElementById("canvas"); + outputCanvas.getContext('2d').drawImage(canvas, 0, 0); +</script> diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.drawImage.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.drawImage.w.html new file mode 100644 index 0000000000..78a235597d --- /dev/null +++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.drawImage.w.html @@ -0,0 +1,50 @@ +<!DOCTYPE html> +<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> +<html class="reftest-wait"> +<link rel="match" href="2d.layer.drawImage-expected.html"> +<title>Canvas test: 2d.layer.drawImage</title> +<h1>2d.layer.drawImage</h1> +<p class="desc">Checks that drawImage writes the image to the layer and not the parent directly.</p> +<canvas id="canvas" width="200" height="200"> + <p class="fallback">FAIL (fallback content)</p> +</canvas> +<script id='myWorker' type='text/worker'> + self.onmessage = function(e) { + const canvas = new OffscreenCanvas(200, 200); + const ctx = canvas.getContext('2d'); + + ctx.fillStyle = 'skyblue'; + ctx.fillRect(0, 0, 100, 100); + + ctx.beginLayer({filter: {name: 'dropShadow', dx: -10, dy: -10, + stdDeviation: 0, floodColor: 'navy'}}); + + ctx.fillStyle = 'maroon'; + ctx.fillRect(20, 20, 50, 50); + + ctx.globalCompositeOperation = 'xor'; + + // The image should xor only with the layer content, not the parents'. + const canvas_image = new OffscreenCanvas(200,200); + const ctx_image = canvas_image.getContext("2d"); + ctx_image.fillStyle = 'pink'; + ctx_image.fillRect(40, 40, 50, 50); + ctx.drawImage(canvas_image, 0, 0); + + ctx.endLayer(); + + const bitmap = canvas.transferToImageBitmap(); + self.postMessage(bitmap, bitmap); + }; +</script> +<script> + const blob = new Blob([document.getElementById('myWorker').textContent]); + const worker = new Worker(URL.createObjectURL(blob)); + worker.addEventListener('message', msg => { + const outputCtx = document.getElementById("canvas").getContext('2d'); + outputCtx.drawImage(msg.data, 0, 0); + document.documentElement.classList.remove("reftest-wait"); + }); + worker.postMessage(null); +</script> +</html> diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending.html index be6f962b33..0e48cb49f7 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending.html +++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending.html @@ -1,6 +1,7 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> <link rel="match" href="2d.layer.global-states.filter.alpha.blending-expected.html"> +<meta name=fuzzy content="maxDifference=0-1; totalPixels=0-2453"> <title>Canvas test: 2d.layer.global-states.filter.alpha.blending</title> <h1>2d.layer.global-states.filter.alpha.blending</h1> <p class="desc">Checks that layers with filters correctly use global render states.</p> diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending.w.html index 2b53ad7c1e..3887ed4485 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending.w.html +++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.blending.w.html @@ -2,6 +2,7 @@ <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> <html class="reftest-wait"> <link rel="match" href="2d.layer.global-states.filter.alpha.blending-expected.html"> +<meta name=fuzzy content="maxDifference=0-1; totalPixels=0-2453"> <title>Canvas test: 2d.layer.global-states.filter.alpha.blending</title> <h1>2d.layer.global-states.filter.alpha.blending</h1> <p class="desc">Checks that layers with filters correctly use global render states.</p> diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite.html index 087fea88af..1a9bc8b733 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite.html +++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite.html @@ -1,6 +1,7 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> <link rel="match" href="2d.layer.global-states.filter.alpha.composite-expected.html"> +<meta name=fuzzy content="maxDifference=0-1; totalPixels=0-5204"> <title>Canvas test: 2d.layer.global-states.filter.alpha.composite</title> <h1>2d.layer.global-states.filter.alpha.composite</h1> <p class="desc">Checks that layers with filters correctly use global render states.</p> diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite.w.html index 6aa83a3278..5c90fe95aa 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite.w.html +++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.composite.w.html @@ -2,6 +2,7 @@ <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> <html class="reftest-wait"> <link rel="match" href="2d.layer.global-states.filter.alpha.composite-expected.html"> +<meta name=fuzzy content="maxDifference=0-1; totalPixels=0-5204"> <title>Canvas test: 2d.layer.global-states.filter.alpha.composite</title> <h1>2d.layer.global-states.filter.alpha.composite</h1> <p class="desc">Checks that layers with filters correctly use global render states.</p> diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.html index f1d631c25c..f64e8925f0 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.html +++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.html @@ -1,6 +1,7 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> <link rel="match" href="2d.layer.global-states.filter.alpha-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-6766"> <title>Canvas test: 2d.layer.global-states.filter.alpha</title> <h1>2d.layer.global-states.filter.alpha</h1> <p class="desc">Checks that layers with filters correctly use global render states.</p> diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.shadow.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.shadow.html index 2548c21181..5e8911ee17 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.shadow.html +++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.shadow.html @@ -1,6 +1,7 @@ <!DOCTYPE html> <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> <link rel="match" href="2d.layer.global-states.filter.alpha.shadow-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-6311"> <title>Canvas test: 2d.layer.global-states.filter.alpha.shadow</title> <h1>2d.layer.global-states.filter.alpha.shadow</h1> <p class="desc">Checks that layers with filters correctly use global render states.</p> diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.shadow.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.shadow.w.html index 5e1494422e..b3be7e1ac8 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.shadow.w.html +++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.shadow.w.html @@ -2,6 +2,7 @@ <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> <html class="reftest-wait"> <link rel="match" href="2d.layer.global-states.filter.alpha.shadow-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-6311"> <title>Canvas test: 2d.layer.global-states.filter.alpha.shadow</title> <h1>2d.layer.global-states.filter.alpha.shadow</h1> <p class="desc">Checks that layers with filters correctly use global render states.</p> diff --git a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.w.html b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.w.html index e75d668ad5..21e55f856c 100644 --- a/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.w.html +++ b/testing/web-platform/tests/html/canvas/offscreen/layers/2d.layer.global-states.filter.alpha.w.html @@ -2,6 +2,7 @@ <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. --> <html class="reftest-wait"> <link rel="match" href="2d.layer.global-states.filter.alpha-expected.html"> +<meta name=fuzzy content="maxDifference=0-2; totalPixels=0-6766"> <title>Canvas test: 2d.layer.global-states.filter.alpha</title> <h1>2d.layer.global-states.filter.alpha</h1> <p class="desc">Checks that layers with filters correctly use global render states.</p> diff --git a/testing/web-platform/tests/html/canvas/tools/gentestutilsunion.py b/testing/web-platform/tests/html/canvas/tools/gentestutilsunion.py index cf141f2f07..d7042810be 100644 --- a/testing/web-platform/tests/html/canvas/tools/gentestutilsunion.py +++ b/testing/web-platform/tests/html/canvas/tools/gentestutilsunion.py @@ -28,7 +28,7 @@ # # * Test the tests, add new ones to Git, remove deleted ones from Git, etc. -from typing import Any, List, Mapping, Optional, Set, Tuple +from typing import Any, DefaultDict, List, Mapping, Optional, Set, Tuple import re import collections @@ -184,6 +184,10 @@ def _remove_extra_newlines(text: str) -> str: return text def _expand_test_code(code: str) -> str: + code = re.sub(r' @moz-todo', '', code) + + code = re.sub(r'@moz-UniversalBrowserRead;', '', code) + code = _remove_extra_newlines(code) # Unroll expressions with a cross-product-style parameter expansion. @@ -202,11 +206,13 @@ def _expand_test_code(code: str) -> str: code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+) \+/- (\d+);', r'_assertPixelApprox(canvas, \1, \2, \3);', code) - code = re.sub(r'@assert throws (\S+_ERR) (.*);', - r'assert_throws_dom("\1", function() { \2; });', code) + code = re.sub(r'@assert throws (\S+_ERR) (.*?);$', + r'assert_throws_dom("\1", function() { \2; });', code, + flags=re.MULTILINE | re.DOTALL) - code = re.sub(r'@assert throws (\S+Error) (.*);', - r'assert_throws_js(\1, function() { \2; });', code) + code = re.sub(r'@assert throws (\S+Error) (.*?);$', + r'assert_throws_js(\1, function() { \2; });', code, + flags=re.MULTILINE | re.DOTALL) code = re.sub( r'@assert (.*) === (.*);', lambda m: '_assertSame(%s, %s, "%s", "%s");' @@ -226,10 +232,6 @@ def _expand_test_code(code: str) -> str: r'@assert (.*);', lambda m: '_assert(%s, "%s");' % (m.group( 1), _escapeJS(m.group(1))), code) - code = re.sub(r' @moz-todo', '', code) - - code = re.sub(r'@moz-UniversalBrowserRead;', '', code) - assert ('@' not in code) return code @@ -376,45 +378,50 @@ def _write_testharness_test(jinja_env: jinja2.Environment, 'utf-8') +def _generate_expected_image(expected: str, name: str, sub_dir: str, + enabled_canvas_types: Set[CanvasType], + html_canvas_cfg: TestConfig, + offscreen_canvas_cfg: TestConfig) -> str: + """Creates a reference image using Cairo and returns the file location.""" + if expected == 'green': + return '/images/green-100x50.png' + if expected == 'clear': + return '/images/clear-100x50.png' + if ';' in expected: + print('Found semicolon in %s' % name) + expected = re.sub( + r'^size (\d+) (\d+)', + r'surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, \1, \2)' + r'\ncr = cairo.Context(surface)', expected) + + if CanvasType.HTML_CANVAS in enabled_canvas_types: + expected_canvas = ( + expected + "\nsurface.write_to_png('%s.png')\n" % + os.path.join(html_canvas_cfg.image_out_dir, sub_dir, name)) + eval(compile(expected_canvas, '<test %s>' % name, 'exec'), {}, + {'cairo': cairo}) + + if {CanvasType.OFFSCREEN_CANVAS, CanvasType.WORKER} & enabled_canvas_types: + expected_offscreen = ( + expected + "\nsurface.write_to_png('%s.png')\n" % + os.path.join(offscreen_canvas_cfg.image_out_dir, sub_dir, name)) + eval(compile(expected_offscreen, '<test %s>' % name, 'exec'), {}, + {'cairo': cairo}) + + return '%s.png' % name + + def _generate_test(test: Mapping[str, Any], jinja_env: jinja2.Environment, - sub_dir: str, enabled_tests: Set[CanvasType], + name_to_sub_dir: Mapping[str, str], + used_tests: DefaultDict[str, Set[CanvasType]], html_canvas_cfg: TestConfig, offscreen_canvas_cfg: TestConfig) -> None: _validate_test(test) name = test['name'] - expected_img = None - if 'expected' in test and test['expected'] is not None: - expected = test['expected'] - if expected == 'green': - expected_img = '/images/green-100x50.png' - elif expected == 'clear': - expected_img = '/images/clear-100x50.png' - else: - if ';' in expected: - print('Found semicolon in %s' % name) - expected = re.sub( - r'^size (\d+) (\d+)', - r'surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, \1, \2)' - r'\ncr = cairo.Context(surface)', expected) - - if CanvasType.HTML_CANVAS in enabled_tests: - expected_canvas = ( - expected + "\nsurface.write_to_png('%s.png')\n" % - os.path.join(html_canvas_cfg.image_out_dir, sub_dir, name)) - eval(compile(expected_canvas, '<test %s>' % name, 'exec'), {}, - {'cairo': cairo}) - - if {CanvasType.OFFSCREEN_CANVAS, CanvasType.WORKER} & enabled_tests: - expected_offscreen = ( - expected + - "\nsurface.write_to_png('%s.png')\n" % os.path.join( - offscreen_canvas_cfg.image_out_dir, sub_dir, name)) - eval(compile(expected_offscreen, '<test %s>' % name, 'exec'), - {}, {'cairo': cairo}) - - expected_img = '%s.png' % name + sub_dir = _get_test_sub_dir(name, name_to_sub_dir) + enabled_canvas_types = _get_enabled_canvas_types(test) # Defaults: params = { @@ -423,11 +430,29 @@ def _generate_test(test: Mapping[str, Any], jinja_env: jinja2.Environment, } params.update(test) + + # Render parameters used in the test name. + name = jinja_env.from_string(name).render(params) + print('\r(%s)' % name, ' ' * 32, '\t') + + expected_img = None + if 'expected' in test and test['expected'] is not None: + expected_img = _generate_expected_image(test['expected'], name, + sub_dir, enabled_canvas_types, + html_canvas_cfg, + offscreen_canvas_cfg) + params.update({ 'code': _expand_test_code(test['code']), 'expected_img': expected_img }) + already_tested = used_tests[name].intersection(enabled_canvas_types) + if already_tested: + raise InvalidTestDefinitionError( + f'Test {name} is defined twice for types {already_tested}') + used_tests[name].update(enabled_canvas_types) + canvas_path = os.path.join(html_canvas_cfg.out_dir, sub_dir, name) offscreen_path = os.path.join(offscreen_canvas_cfg.out_dir, sub_dir, name) if 'manual' in test: @@ -435,11 +460,55 @@ def _generate_test(test: Mapping[str, Any], jinja_env: jinja2.Environment, offscreen_path += '-manual' if 'reference' in test or 'html_reference' in test: - _write_reference_test(jinja_env, params, enabled_tests, + _write_reference_test(jinja_env, params, enabled_canvas_types, canvas_path, offscreen_path) else: - _write_testharness_test(jinja_env, params, enabled_tests, canvas_path, - offscreen_path) + _write_testharness_test(jinja_env, params, enabled_canvas_types, + canvas_path, offscreen_path) + + +def _recursive_expand_variant_matrix(test_list: List[Mapping[str, Any]], + variant_matrix: List[Mapping[str, Any]], + current_selection: List[Tuple[str, Any]], + original_test: Mapping[str, Any]): + if len(current_selection) == len(variant_matrix): + # Selection for each variant is done, so add a new test to test_list. + test = original_test.copy() + variant_name_list = [] + should_append_variant_names = original_test.get( + 'append_variants_to_name', True) + for variant_name, variant_params in current_selection: + variant_name_list.append(variant_name) + # Append variant name. Variant names starting with '_' are + # not appended, which is useful to create variants with the same + # name in different folders (element vs. offscreen). + if (should_append_variant_names + and not variant_name.startswith('_')): + test['name'] += '.' + variant_name + test.update(variant_params) + # Expose variant names as a list so they can be used from the yaml + # files, which helps with better naming of tests. + test.update({'variant_names': variant_name_list}) + test_list.append(test) + else: + # Continue the recursion with each possible selection for the current + # variant. + variant = variant_matrix[len(current_selection)] + for variant_options in variant.items(): + current_selection.append(variant_options) + _recursive_expand_variant_matrix(test_list, variant_matrix, + current_selection, original_test) + current_selection.pop() + + +def _expand_variant_matrix( + variant_matrix: List[Mapping[str, Any]], + original_test: Mapping[str, Any]) -> List[Mapping[str, Any]]: + current_selection = [] + matrix_tests = [] + _recursive_expand_variant_matrix(matrix_tests, variant_matrix, + current_selection, original_test) + return matrix_tests def genTestUtils_union(NAME2DIRFILE: str) -> None: @@ -495,41 +564,25 @@ def genTestUtils_union(NAME2DIRFILE: str) -> None: pass # Ignore if it already exists, used_tests = collections.defaultdict(set) - for original_test in tests: - variants = original_test.get('variants', {'': dict()}) - for variant_name, variant_params in variants.items(): - test = original_test.copy() - if variant_name or variant_params: - # Append variant name. Variant names starting with '_' are - # not appended, which is useful to create variants with the same - # name in different folders (element vs. offscreen). - if not variant_name.startswith('_'): - test['name'] += '.' + variant_name - test.update(variant_params) - - name = test['name'] - print('\r(%s)' % name, ' ' * 32, '\t') - - enabled_canvas_types = _get_enabled_canvas_types(test) - - already_tested = used_tests[name].intersection( - enabled_canvas_types) - if already_tested: - raise InvalidTestDefinitionError( - f'Test {name} is defined twice for types {already_tested}') - used_tests[name].update(enabled_canvas_types) - - sub_dir = _get_test_sub_dir(name, name_to_sub_dir) - _generate_test( - test, - jinja_env, - sub_dir, - enabled_canvas_types, - html_canvas_cfg=TestConfig( - out_dir=CANVASOUTPUTDIR, - image_out_dir=CANVASIMAGEOUTPUTDIR), - offscreen_canvas_cfg=TestConfig( - out_dir=OFFSCREENCANVASOUTPUTDIR, - image_out_dir=OFFSCREENCANVASIMAGEOUTPUTDIR)) + for test in tests: + if 'variant_matrix' in test: + variants = _expand_variant_matrix(test['variant_matrix'], test) + elif 'variants' in test: + variant_matrix = [test['variants']] + variants = _expand_variant_matrix(variant_matrix, test) + else: + variants = [test] + + for variant in variants: + _generate_test(variant, + jinja_env, + name_to_sub_dir, + used_tests, + html_canvas_cfg=TestConfig( + out_dir=CANVASOUTPUTDIR, + image_out_dir=CANVASIMAGEOUTPUTDIR), + offscreen_canvas_cfg=TestConfig( + out_dir=OFFSCREENCANVASOUTPUTDIR, + image_out_dir=OFFSCREENCANVASIMAGEOUTPUTDIR)) print() diff --git a/testing/web-platform/tests/html/canvas/tools/name2dir-offscreen.yaml b/testing/web-platform/tests/html/canvas/tools/name2dir-offscreen.yaml index c52acb793b..6e4b3f42b2 100644 --- a/testing/web-platform/tests/html/canvas/tools/name2dir-offscreen.yaml +++ b/testing/web-platform/tests/html/canvas/tools/name2dir-offscreen.yaml @@ -19,4 +19,4 @@ 2d.missingargs: "conformance-requirements" 2d.voidreturn: "conformance-requirements" 2d.canvas.host: "canvas-host" -2d.canvas.context: "canvas-context"
\ No newline at end of file +2d.canvas.context: "canvas-context" diff --git a/testing/web-platform/tests/html/canvas/tools/yaml-new/drawing-images-to-the-canvas.yaml b/testing/web-platform/tests/html/canvas/tools/yaml-new/drawing-images-to-the-canvas.yaml index 93c556288d..09e9e00186 100644 --- a/testing/web-platform/tests/html/canvas/tools/yaml-new/drawing-images-to-the-canvas.yaml +++ b/testing/web-platform/tests/html/canvas/tools/yaml-new/drawing-images-to-the-canvas.yaml @@ -638,3 +638,11 @@ @nonfinite ctx.drawImage(<bitmap>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>); @assert pixel 50,25 == 0,255,0,255; expected: green + +- name: 2d.drawImage.detachedcanvas + desc: drawImage with detached OffscreenCanvas as the source should throw exception + canvasType: ['HTMLCanvas'] + code: | + var canvas2 = new OffscreenCanvas(80, 80); + (new MessageChannel()).port1.postMessage(canvas2, [canvas2]); + @assert throws INVALID_STATE_ERR ctx.drawImage(canvas2, 0, 0); diff --git a/testing/web-platform/tests/html/canvas/tools/yaml-new/filters.yaml b/testing/web-platform/tests/html/canvas/tools/yaml-new/filters.yaml index 01c83a33e2..f327b9fe94 100644 --- a/testing/web-platform/tests/html/canvas/tools/yaml-new/filters.yaml +++ b/testing/web-platform/tests/html/canvas/tools/yaml-new/filters.yaml @@ -89,51 +89,102 @@ ctx.filter = 'this string is not a filter and should do nothing'; @assert ctx.filter.toString() == '[object CanvasFilter]'; -- name: 2d.filter.canvasFilterObject.blur.exceptions.tentative - desc: Test exceptions on CanvasFilter() blur.object +- name: 2d.filter.{{ variant_names[0] }}.blur.exceptions{{ tentative }} + desc: Test exceptions on gaussianBlur filter code: | - @assert throws TypeError ctx.filter = new CanvasFilter({name: 'gaussianBlur'}); - @assert throws TypeError ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: undefined}); - @assert throws TypeError ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: 'foo'}); - @assert throws TypeError ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: [1,2,3]}); - @assert throws TypeError ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: NaN}); - @assert throws TypeError ctx.filter = new CanvasFilter({name: 'gaussianBlur', stdDeviation: {}}); - -- name: 2d.filter.canvasFilterObject.colorMatrix.tentative - desc: Test the functionality of ColorMatrix filters in CanvasFilter objects + @assert throws TypeError {{ filter_declaration | replace("param", + "{name: 'gaussianBlur'}") }}; + @assert throws TypeError {{ filter_declaration | replace("param", + "{name: 'gaussianBlur', stdDeviation: undefined}") }}; + @assert throws TypeError {{ filter_declaration | replace("param", + "{name: 'gaussianBlur', stdDeviation: 'foo'}") }}; + @assert throws TypeError {{ filter_declaration | replace("param", + "{name: 'gaussianBlur', stdDeviation: [1,2,3]}") }}; + @assert throws TypeError {{ filter_declaration | replace("param", + "{name: 'gaussianBlur', stdDeviation: NaN}") }}; + @assert throws TypeError {{ filter_declaration | replace("param", + "{name: 'gaussianBlur', stdDeviation: {}}") }}; + append_variants_to_name: false + variants: + layers: + filter_declaration: |- + ctx.beginLayer({filter: + param}) + canvasFilterObject: + filter_declaration: |- + ctx.filter = new CanvasFilter( + param) + tentative: .tentative + +- name: 2d.filter.{{ variant_names[0] }}.colorMatrix{{ tentative }} + desc: Test the functionality of ColorMatrix filters code: | - @assert throws TypeError new CanvasFilter({name: 'colorMatrix', values: undefined}); - @assert throws TypeError new CanvasFilter({name: 'colorMatrix', values: 'foo'}); - @assert throws TypeError new CanvasFilter({name: 'colorMatrix', values: null}); - @assert throws TypeError new CanvasFilter({name: 'colorMatrix', values: [1, 2, 3]}); - @assert throws TypeError new CanvasFilter({name: 'colorMatrix', values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 'a']}); - @assert throws TypeError new CanvasFilter({name: 'colorMatrix', values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, Infinity]}); + @assert throws TypeError {{ filter_declaration | replace("param", + "{name: 'colorMatrix', values: undefined}") }}; + + @assert throws TypeError {{ filter_declaration | replace("param", + "{name: 'colorMatrix', values: 'foo'}") }}; + + @assert throws TypeError {{ filter_declaration | replace("param", + "{name: 'colorMatrix', values: null}") }}; + + @assert throws TypeError {{ filter_declaration | replace("param", + "{name: 'colorMatrix', values: [1, 2, 3]}") }}; + + @assert throws TypeError {{ filter_declaration | replace("param", + "{name: 'colorMatrix', + values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 'a']}") }}; + + @assert throws TypeError {{ filter_declaration | replace("param", + "{name: 'colorMatrix', + values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, Infinity]}") }}; + ctx.fillStyle = '#f00'; - ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 0}); + {{ filter_declaration | replace("param", + "{name: 'colorMatrix', type: 'hueRotate', values: 0}") }}; ctx.fillRect(0, 0, 100, 50); + {{ close_layer -}} @assert pixel 10,10 ==~ 255,0,0,255; - ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 90}); + + {{ filter_declaration | replace("param", + "{name: 'colorMatrix', type: 'hueRotate', values: 90}") }}; ctx.fillRect(0, 0, 100, 50); + {{ close_layer -}} @assert pixel 10,10 ==~ 0,91,0,255; - ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 180}); + + {{ filter_declaration | replace("param", + "{name: 'colorMatrix', type: 'hueRotate', values: 180}") }}; ctx.fillRect(0, 0, 100, 50); + {{ close_layer -}} @assert pixel 10,10 ==~ 0,109,109,255; - ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'hueRotate', values: 270}); + + {{ filter_declaration | replace("param", + "{name: 'colorMatrix', type: 'hueRotate', values: 270}") }}; ctx.fillRect(0, 0, 100, 50); + {{ close_layer -}} @assert pixel 10,10 ==~ 109,18,255,255; - ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'saturate', values: 0.5}); + + {{ filter_declaration | replace("param", + "{name: 'colorMatrix', type: 'saturate', values: 0.5}") }}; ctx.fillRect(0, 0, 100, 50); + {{ close_layer -}} @assert pixel 10,10 ==~ 155,27,27,255; + ctx.clearRect(0, 0, 100, 50); - ctx.filter = new CanvasFilter({name: 'colorMatrix', type: 'luminanceToAlpha'}); + {{ filter_declaration | replace("param", + "{name: 'colorMatrix', type: 'luminanceToAlpha'}") }}; ctx.fillRect(0, 0, 100, 50); + {{ close_layer -}} @assert pixel 10,10 ==~ 0,0,0,54; - ctx.filter = new CanvasFilter({name: 'colorMatrix', values: [ - 0, 0, 0, 0, 0, - 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0 - ]}); + + {{ filter_declaration | replace("param", "{name: 'colorMatrix', values: [ + 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0 + ]}") }}; ctx.fillRect(0, 0, 50, 25); ctx.fillStyle = '#0f0'; ctx.fillRect(50, 0, 50, 25); @@ -141,51 +192,120 @@ ctx.fillRect(0, 25, 50, 25); ctx.fillStyle = '#fff'; ctx.fillRect(50, 25, 50, 25); + {{ close_layer -}} @assert pixel 10,10 ==~ 0,255,0,255; @assert pixel 60,10 ==~ 0,255,0,255; @assert pixel 10,30 ==~ 0,255,0,255; @assert pixel 60,30 ==~ 0,255,0,255; - -- name: 2d.filter.canvasFilterObject.convolveMatrix.exceptions.tentative + append_variants_to_name: false + variants: + layers: + filter_declaration: |- + ctx.beginLayer({filter: + param}) + close_layer: | + ctx.endLayer(); + canvasFilterObject: + filter_declaration: |- + ctx.filter = new CanvasFilter( + param) + tentative: .tentative + +- name: 2d.filter.{{ variant_names[0] }}.convolveMatrix.exceptions{{ tentative }} desc: Test exceptions on CanvasFilter() convolveMatrix code: | - @assert throws TypeError new CanvasFilter({name: 'convolveMatrix'}); - @assert throws TypeError new CanvasFilter({name: 'convolveMatrix', divisor: 2}); - @assert throws TypeError new CanvasFilter({name: 'convolveMatrix', kernelMatrix: null}); - @assert throws TypeError new CanvasFilter({name: 'convolveMatrix', kernelMatrix: 1}); - @assert throws TypeError new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 0], [0]]}); - @assert throws TypeError new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 'a'], [0]]}); - @assert throws TypeError new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 0], 0]}); - @assert throws TypeError new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 0], [0, Infinity]]}); - @assert throws TypeError new CanvasFilter({name: 'convolveMatrix', kernelMatrix: []}); - @assert throws TypeError new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [1]}); - @assert throws TypeError new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [1, 2, 3, 4]}); - @assert throws TypeError new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[], []]}); - @assert throws TypeError new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1, 2], []]}); - @assert throws TypeError new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[], [1, 2]]}); + @assert throws TypeError {{ filter_declaration | replace("param", + "{name: 'convolveMatrix'}") }}; + @assert throws TypeError {{ filter_declaration | replace("param", + "{name: 'convolveMatrix', divisor: 2}") }}; + @assert throws TypeError {{ filter_declaration | replace("param", + "{name: 'convolveMatrix', kernelMatrix: null}") }}; + @assert throws TypeError {{ filter_declaration | replace("param", + "{name: 'convolveMatrix', kernelMatrix: 1}") }}; + @assert throws TypeError {{ filter_declaration | replace("param", + "{name: 'convolveMatrix', kernelMatrix: [[1, 0], [0]]}") }}; + @assert throws TypeError {{ filter_declaration | replace("param", + "{name: 'convolveMatrix', kernelMatrix: [[1, 'a'], [0]]}") }}; + @assert throws TypeError {{ filter_declaration | replace("param", + "{name: 'convolveMatrix', kernelMatrix: [[1, 0], 0]}") }}; + @assert throws TypeError {{ filter_declaration | replace("param", + "{name: 'convolveMatrix', kernelMatrix: [[1, 0], [0, Infinity]]}") }}; + @assert throws TypeError {{ filter_declaration | replace("param", + "{name: 'convolveMatrix', kernelMatrix: []}") }}; + @assert throws TypeError {{ filter_declaration | replace("param", + "{name: 'convolveMatrix', kernelMatrix: [1]}") }}; + @assert throws TypeError {{ filter_declaration | replace("param", + "{name: 'convolveMatrix', kernelMatrix: [1, 2, 3, 4]}") }}; + @assert throws TypeError {{ filter_declaration | replace("param", + "{name: 'convolveMatrix', kernelMatrix: [[], []]}") }}; + @assert throws TypeError {{ filter_declaration | replace("param", + "{name: 'convolveMatrix', kernelMatrix: [[1, 2], []]}") }}; + @assert throws TypeError {{ filter_declaration | replace("param", + "{name: 'convolveMatrix', kernelMatrix: [[], [1, 2]]}") }}; // This should not throw an error - ctx.filter = new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[]]}); - ctx.filter = new CanvasFilter({name: 'convolveMatrix', kernelMatrix: [[1]]}); - -- name: 2d.filter.canvasFilterObject.componentTransfer.linear.tentative + {{ filter_declaration | replace("param", + "{name: 'convolveMatrix', kernelMatrix: [[]]}") }}; + {{ close_layer -}} + {{ filter_declaration | replace("param", + "{name: 'convolveMatrix', kernelMatrix: [[1]]}") }}; + {{ close_layer -}} + append_variants_to_name: false + variants: + layers: + filter_declaration: |- + ctx.beginLayer({filter: + param}) + close_layer: | + ctx.endLayer(); + canvasFilterObject: + filter_declaration: |- + ctx.filter = new CanvasFilter( + param) + tentative: .tentative + +- name: >- + 2d.filter.{{ variant_names[0] }}.componentTransfer.linear{{ tentative }} desc: Test pixels on CanvasFilter() componentTransfer with linear type + size: [100, 100] + fuzzy: maxDifference=0-2; totalPixels=0-500 code: | + const slopes = [0.5, 1.2, -0.2]; + const intercepts = [0.25, 0, 0.5]; + {{ filter_declaration | replace("param", "{name: 'componentTransfer', + funcR: {type: 'linear', slope: slopes[0], intercept: intercepts[0]}, + funcG: {type: 'linear', slope: slopes[1], intercept: intercepts[1]}, + funcB: {type: 'linear', slope: slopes[2], intercept: intercepts[2]}, + }") }}; + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } + {{ close_layer }} + reference: | // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement function getColor(inputColor, slopes, intercepts) { return [ - Math.max(0, Math.min(1, inputColor[0]/255 * slopes[0] + intercepts[0])) * 255, - Math.max(0, Math.min(1, inputColor[1]/255 * slopes[1] + intercepts[1])) * 255, - Math.max(0, Math.min(1, inputColor[2]/255 * slopes[2] + intercepts[2])) * 255, + Math.max(0, Math.min(1, + inputColor[0]/255 * slopes[0] + intercepts[0])) * 255, + Math.max(0, Math.min(1, + inputColor[1]/255 * slopes[1] + intercepts[1])) * 255, + Math.max(0, Math.min(1, + inputColor[2]/255 * slopes[2] + intercepts[2])) * 255, ]; } const slopes = [0.5, 1.2, -0.2]; const intercepts = [0.25, 0, 0.5]; - ctx.filter = new CanvasFilter({name: 'componentTransfer', - funcR: {type: 'linear', slope: slopes[0], intercept: intercepts[0]}, - funcG: {type: 'linear', slope: slopes[1], intercept: intercepts[1]}, - funcB: {type: 'linear', slope: slopes[2], intercept: intercepts[2]}, - }); const inputColors = [ [255, 255, 255], @@ -195,21 +315,35 @@ [50, 68, 87], ]; - for (const color of inputColors) { + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; let outputColor = getColor(color, slopes, intercepts); - ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; - ctx.fillRect(0, 0, 10, 10); - _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2); + ctx.fillStyle = `rgb(${outputColor[0]}, ${outputColor[1]}, + ${outputColor[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); } - -- name: 2d.filter.canvasFilterObject.componentTransfer.identity.tentative + {{ close_layer }} + append_variants_to_name: false + variants: + layers: + filter_declaration: |- + ctx.beginLayer({filter: param}) + close_layer: ctx.endLayer(); + canvasFilterObject: + filter_declaration: |- + ctx.filter = new CanvasFilter(param) + tentative: .tentative + +- name: >- + 2d.filter.{{ variant_names[0] }}.componentTransfer.identity{{ tentative }} desc: Test pixels on CanvasFilter() componentTransfer with identity type + size: [100, 100] code: | - ctx.filter = new CanvasFilter({name: 'componentTransfer', + {{ filter_declaration | replace("param", "{name: 'componentTransfer', funcR: {type: 'identity'}, funcG: {type: 'identity'}, funcB: {type: 'identity'}, - }); + }") }}; const inputColors = [ [255, 255, 255], @@ -219,32 +353,86 @@ [50, 68, 87], ]; - for (const color of inputColors) { - ctx.fillStyle = `rgba(${color[0]}, ${color[1]}, ${color[2]}, 1)`, - ctx.fillRect(0, 0, 10, 10); - _assertPixel(canvas, 5, 5, color[0],color[1],color[2],255); + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); } + {{ close_layer }} + reference: | + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; -- name: 2d.filter.canvasFilterObject.componentTransfer.gamma.tentative + for (let i = 0 ; i < inputColors.length ; ++i) { + let outputColor = inputColors[i]; + ctx.fillStyle = `rgb(${outputColor[0]}, ${outputColor[1]}, + ${outputColor[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } + append_variants_to_name: false + variants: + layers: + filter_declaration: |- + ctx.beginLayer({filter: param}) + close_layer: ctx.endLayer(); + canvasFilterObject: + filter_declaration: |- + ctx.filter = new CanvasFilter(param) + tentative: .tentative + +- name: >- + 2d.filter.{{ variant_names[0] }}.componentTransfer.gamma{{ tentative }} desc: Test pixels on CanvasFilter() componentTransfer with gamma type + size: [100, 100] + fuzzy: maxDifference=0-2; totalPixels=0-500 code: | + const amplitudes = [2, 1.1, 0.5]; + const exponents = [5, 3, 1]; + const offsets = [0.25, 0, 0.5]; + {{ filter_declaration | replace("param", "{name: 'componentTransfer', + funcR: {type: 'gamma', amplitude: amplitudes[0], + exponent: exponents[0], offset: offsets[0]}, + funcG: {type: 'gamma', amplitude: amplitudes[1], + exponent: exponents[1], offset: offsets[1]}, + funcB: {type: 'gamma', amplitude: amplitudes[2], + exponent: exponents[2], offset: offsets[2]}, + }") }}; + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } + {{ close_layer }} + reference: | // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement function getColor(inputColor, amplitude, exponent, offset) { return [ - Math.max(0, Math.min(1, Math.pow(inputColor[0]/255, exponent[0]) * amplitude[0] + offset[0])) * 255, - Math.max(0, Math.min(1, Math.pow(inputColor[1]/255, exponent[1]) * amplitude[1] + offset[1])) * 255, - Math.max(0, Math.min(1, Math.pow(inputColor[2]/255, exponent[2]) * amplitude[2] + offset[2])) * 255, + Math.max(0, Math.min(1, Math.pow(inputColor[0]/255, + exponent[0]) * amplitude[0] + offset[0])) * 255, + Math.max(0, Math.min(1, Math.pow(inputColor[1]/255, + exponent[1]) * amplitude[1] + offset[1])) * 255, + Math.max(0, Math.min(1, Math.pow(inputColor[2]/255, + exponent[2]) * amplitude[2] + offset[2])) * 255, ]; } const amplitudes = [2, 1.1, 0.5]; const exponents = [5, 3, 1]; const offsets = [0.25, 0, 0.5]; - ctx.filter = new CanvasFilter({name: 'componentTransfer', - funcR: {type: 'gamma', amplitude: amplitudes[0], exponent: exponents[0], offset: offsets[0]}, - funcG: {type: 'gamma', amplitude: amplitudes[1], exponent: exponents[1], offset: offsets[1]}, - funcB: {type: 'gamma', amplitude: amplitudes[2], exponent: exponents[2], offset: offsets[2]}, - }); const inputColors = [ [255, 255, 255], @@ -254,16 +442,54 @@ [50, 68, 87], ]; - for (const color of inputColors) { + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; let outputColor = getColor(color, amplitudes, exponents, offsets); - ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; - ctx.fillRect(0, 0, 10, 10); - _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2); + ctx.fillStyle = `rgb(${outputColor[0]}, ${outputColor[1]}, + ${outputColor[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); } - -- name: 2d.filter.canvasFilterObject.componentTransfer.table.tentative + append_variants_to_name: false + variants: + layers: + filter_declaration: |- + ctx.beginLayer({filter: param}) + close_layer: ctx.endLayer(); + canvasFilterObject: + filter_declaration: |- + ctx.filter = new CanvasFilter(param) + tentative: .tentative + +- name: >- + 2d.filter.{{ variant_names[0] }}.componentTransfer.table{{ tentative }} desc: Test pixels on CanvasFilter() componentTransfer with table type + size: [100, 100] + fuzzy: maxDifference=0-2; totalPixels=0-500 code: | + tableValuesR = [0, 0, 1, 1]; + tableValuesG = [2, 0, 0.5, 3]; + tableValuesB = [1, -1, 5, 0]; + {{ filter_declaration | replace("param", "{name: 'componentTransfer', + funcR: {type: 'table', tableValues: tableValuesR}, + funcG: {type: 'table', tableValues: tableValuesG}, + funcB: {type: 'table', tableValues: tableValuesB}, + }") }}; + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } + {{ close_layer }} + reference: | // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement function getTransformedValue(C, V) { // Get the right interval @@ -285,11 +511,6 @@ tableValuesR = [0, 0, 1, 1]; tableValuesG = [2, 0, 0.5, 3]; tableValuesB = [1, -1, 5, 0]; - ctx.filter = new CanvasFilter({name: 'componentTransfer', - funcR: {type: 'table', tableValues: tableValuesR}, - funcG: {type: 'table', tableValues: tableValuesG}, - funcB: {type: 'table', tableValues: tableValuesB}, - }); const inputColors = [ [255, 255, 255], @@ -299,16 +520,55 @@ [50, 68, 87], ]; - for (const color of inputColors) { - let outputColor = getColor(color, [tableValuesR, tableValuesG, tableValuesB]); - ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; - ctx.fillRect(0, 0, 10, 10); - _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2); + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + let outputColor = getColor( + color, [tableValuesR, tableValuesG, tableValuesB]); + ctx.fillStyle = `rgb(${outputColor[0]}, ${outputColor[1]}, + ${outputColor[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); } - -- name: 2d.filter.canvasFilterObject.componentTransfer.discrete.tentative + append_variants_to_name: false + variants: + layers: + filter_declaration: |- + ctx.beginLayer({filter: param}) + close_layer: ctx.endLayer(); + canvasFilterObject: + filter_declaration: |- + ctx.filter = new CanvasFilter(param) + tentative: .tentative + +- name: >- + 2d.filter.{{ variant_names[0] }}.componentTransfer.discrete{{ tentative }} desc: Test pixels on CanvasFilter() componentTransfer with discrete type + size: [100, 100] + fuzzy: maxDifference=0-2; totalPixels=0-500 code: | + tableValuesR = [0, 0, 1, 1]; + tableValuesG = [2, 0, 0.5, 3]; + tableValuesB = [1, -1, 5, 0]; + {{ filter_declaration | replace("param", "{name: 'componentTransfer', + funcR: {type: 'discrete', tableValues: tableValuesR}, + funcG: {type: 'discrete', tableValues: tableValuesG}, + funcB: {type: 'discrete', tableValues: tableValuesB}, + }") }}; + + const inputColors = [ + [255, 255, 255], + [0, 0, 0], + [127, 0, 34], + [252, 186, 3], + [50, 68, 87], + ]; + + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); + } + {{ close_layer }} + reference: | // From https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement function getTransformedValue(C, V) { // Get the right interval @@ -330,11 +590,6 @@ tableValuesR = [0, 0, 1, 1]; tableValuesG = [2, 0, 0.5, 3]; tableValuesB = [1, -1, 5, 0]; - ctx.filter = new CanvasFilter({name: 'componentTransfer', - funcR: {type: 'discrete', tableValues: tableValuesR}, - funcG: {type: 'discrete', tableValues: tableValuesG}, - funcB: {type: 'discrete', tableValues: tableValuesB}, - }); const inputColors = [ [255, 255, 255], @@ -343,24 +598,38 @@ [252, 186, 3], [50, 68, 87], ]; - - for (const color of inputColors) { - let outputColor = getColor(color, [tableValuesR, tableValuesG, tableValuesB]); - ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; - ctx.fillRect(0, 0, 10, 10); - _assertPixelApprox(canvas, 5, 5, outputColor[0],outputColor[1],outputColor[2],255, 2); + for (let i = 0 ; i < inputColors.length ; ++i) { + const color = inputColors[i]; + let outputColor = getColor( + color, [tableValuesR, tableValuesG, tableValuesB]); + ctx.fillStyle = `rgb(${outputColor[0]}, ${outputColor[1]}, + ${outputColor[2]})`; + ctx.fillRect(i * 10, i * 10, 10, 10); } - -- name: 2d.filter.canvasFilterObject.gaussianBlur.tentative + append_variants_to_name: false + variants: + layers: + filter_declaration: |- + ctx.beginLayer({filter: param}) + close_layer: ctx.endLayer(); + canvasFilterObject: + filter_declaration: |- + ctx.filter = new CanvasFilter(param) + tentative: .tentative + +- name: >- + 2d.filter.{{ variant_names[0] }}.gaussianBlur.{{ variant_names[1] }}{{ + tentative }} desc: Test CanvasFilter() with gaussianBlur. size: [100, 100] code: | ctx.fillStyle = 'teal'; - ctx.filter = new CanvasFilter({ + {{ filter_declaration | replace("param", "{ name: 'gaussianBlur', stdDeviation: [{{ blur_x }}, {{blur_y}}], - }); + }") }} ctx.fillRect(25, 25, 50, 50); + {{ close_layer }} html_reference: | <svg xmlns="http://www.w3.org/2000/svg" width="{{ size[0] }}" height="{{ size[1] }}" @@ -371,24 +640,33 @@ <rect x="25" y="25" width="50" height="50" fill="teal" filter="url(#blur)" /> </svg> - variants: - x-only: - blur_x: 4 - blur_y: 0 - mostly-x: - blur_x: 4 - blur_y: 1 - isotropic: - blur_x: 4 - blur_y: 4 - mostly-y: - blur_x: 1 - blur_y: 4 - y-only: - blur_x: 0 - blur_y: 4 - -- name: 2d.filter.canvasFilterObject.dropShadow.tentative + append_variants_to_name: false + variant_matrix: + - layers: + filter_declaration: |- + ctx.beginLayer({filter: param}); + close_layer: ctx.endLayer(); + canvasFilterObject: + filter_declaration: |- + ctx.filter = new CanvasFilter(param); + tentative: .tentative + - x-only: + blur_x: 4 + blur_y: 0 + mostly-x: + blur_x: 4 + blur_y: 1 + isotropic: + blur_x: 4 + blur_y: 4 + mostly-y: + blur_x: 1 + blur_y: 4 + y-only: + blur_x: 0 + blur_y: 4 + +- name: 2d.filter.{{ variant_names[0] }}.dropShadow{{ tentative }} desc: Test CanvasFilter() dropShadow object. size: [520, 420] code: | @@ -401,90 +679,91 @@ ctx.fillStyle = 'crimson'; // Parameter defaults. - ctx.filter = new CanvasFilter({name: 'dropShadow'}); + {{ filter_declaration | replace("param", "{name: 'dropShadow'}") }} ctx.fillRect(10, 10, 80, 80); + {{ close_layer -}} // All parameters specified. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5, - floodColor: 'purple', floodOpacity: 0.7}); + {{ filter_declaration | replace("param", "{name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5, + floodColor: 'purple', floodOpacity: 0.7}") }} ctx.fillRect(110, 10, 80, 80); + {{ close_layer -}} // Named color. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, - floodColor: 'purple'}); + {{ filter_declaration | replace("param", "{name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + floodColor: 'purple'}") }} ctx.fillRect(10, 110, 80, 80); + {{ close_layer -}} // System color. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, - floodColor: 'LinkText'}); + {{ filter_declaration | replace("param", "{name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + floodColor: 'LinkText'}") }} ctx.fillRect(110, 110, 80, 80); + {{ close_layer -}} // Numerical color. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, - floodColor: 'rgba(20, 50, 130, 1)'}); + {{ filter_declaration | replace("param", "{name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + floodColor: 'rgba(20, 50, 130, 1)'}") }} ctx.fillRect(210, 110, 80, 80); + {{ close_layer -}} // Transparent floodColor. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, - floodColor: 'rgba(20, 50, 130, 0.7)'}); + {{ filter_declaration | replace("param", "{name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + floodColor: 'rgba(20, 50, 130, 0.7)'}") }} ctx.fillRect(310, 110, 80, 80); + {{ close_layer -}} // Transparent floodColor and floodOpacity. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, - floodColor: 'rgba(20, 50, 130, 0.7)', floodOpacity: 0.7}); + {{ filter_declaration | replace("param", "{name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 3, + floodColor: 'rgba(20, 50, 130, 0.7)', floodOpacity: 0.7}") }} ctx.fillRect(410, 110, 80, 80); + {{ close_layer -}} // No blur. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 0, - floodColor: 'purple'}); + {{ filter_declaration | replace("param", "{name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 0, + floodColor: 'purple'}") }} ctx.fillRect(10, 210, 80, 80); + {{ close_layer -}} // Single float blur. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5, - floodColor: 'purple'}); + {{ filter_declaration | replace("param", "{name: 'dropShadow', dx: 9, dy: 12, stdDeviation: 5, + floodColor: 'purple'}") }} ctx.fillRect(110, 210, 80, 80); + {{ close_layer -}} // Single negative float blur. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: -5, - floodColor: 'purple'}); + {{ filter_declaration | replace("param", "{name: 'dropShadow', dx: 9, dy: 12, stdDeviation: -5, + floodColor: 'purple'}") }} ctx.fillRect(210, 210, 80, 80); + {{ close_layer -}} // Two floats (X&Y) blur. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: [3, 5], - floodColor: 'purple'}); + {{ filter_declaration | replace("param", "{name: 'dropShadow', dx: 9, dy: 12, stdDeviation: [3, 5], + floodColor: 'purple'}") }} ctx.fillRect(310, 210, 80, 80); + {{ close_layer -}} // Two negative floats (X&Y) blur. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: 9, dy: 12, stdDeviation: [-3, -5], - floodColor: 'purple'}); + {{ filter_declaration | replace("param", "{name: 'dropShadow', dx: 9, dy: 12, stdDeviation: [-3, -5], + floodColor: 'purple'}") }} ctx.fillRect(410, 210, 80, 80); + {{ close_layer -}} // Degenerate parameter values. - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: [-5], dy: [], stdDeviation: null, - floodColor: 'purple', floodOpacity: [2]}); + {{ filter_declaration | replace("param", "{name: 'dropShadow', dx: [-5], dy: [], stdDeviation: null, + floodColor: 'purple', floodOpacity: [2]}") }} ctx.fillRect(10, 310, 80, 80); + {{ close_layer -}} - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: null, dy: '5', stdDeviation: [[-5], ['3']], - floodColor: 'purple', floodOpacity: '0.8'}); + {{ filter_declaration | replace("param", "{name: 'dropShadow', dx: null, dy: '5', stdDeviation: [[-5], ['3']], + floodColor: 'purple', floodOpacity: '0.8'}") }} ctx.fillRect(110, 310, 80, 80); + {{ close_layer -}} - ctx.filter = new CanvasFilter( - {name: 'dropShadow', dx: true, dy: ['10'], stdDeviation: false, - floodColor: 'purple', floodOpacity: ['0.4']}); + {{ filter_declaration | replace("param", "{name: 'dropShadow', dx: true, dy: ['10'], stdDeviation: false, + floodColor: 'purple', floodOpacity: ['0.4']}") }} ctx.fillRect(210, 310, 80, 80); + {{ close_layer -}} html_reference: | <svg xmlns="http://www.w3.org/2000/svg" width={{ size[0] }} height={{ size[1] }} @@ -537,41 +816,70 @@ <rect x=210 y=310 width=80 height=80 fill="crimson" filter="drop-shadow(1px 10px 0px rgba(128, 0, 128, 0.4))"/> </svg> - -- name: 2d.filter.canvasFilterObject.dropShadow.exceptions.tentative + append_variants_to_name: false + variants: + layers: + filter_declaration: |- + ctx.beginLayer({filter: param}); + close_layer: | + ctx.endLayer(); + canvasFilterObject: + filter_declaration: |- + ctx.filter = new CanvasFilter(param); + tentative: .tentative + +- name: 2d.filter.{{ variant_names[0] }}.dropShadow.exceptions{{ tentative }} desc: Test exceptions on CanvasFilter() dropShadow object code: | - @unroll @assert new CanvasFilter({\- + // Should not throw an error. + @unroll {{ filter_declaration | replace("param", "{\- name: 'dropShadow', \- <dx | dy | floodOpacity>: \- - <10 | -1 | 0.5 | null | true | false | [] | [20] | '30'>}); - @unroll @assert new CanvasFilter({\- + <10 | -1 | 0.5 | null | true | false | [] | [20] | '30'>}") }}; + @unroll {{ filter_declaration | replace("param", "{\- + name: 'dropShadow', \- + <dx | dy | floodOpacity>: \- + <10 | -1 | 0.5 | null | true | false | [] | [20] | '30'>}") }}; + @unroll {{ filter_declaration | replace("param", "{\- name: 'dropShadow', \- <stdDeviation>: \- <10 | -1 | 0.5 | null | true | false | [] | [20] | '30' | \- [10, -1] | [0.5, null] | [true, false] | [[], [20]] | \- - ['30', ['40']]>}); - @unroll @assert new CanvasFilter({\- + ['30', ['40']]>}") }}; + @unroll {{ filter_declaration | replace("param", "{\- name: 'dropShadow', \- <floodColor>: \- - <'red' | 'canvas' | 'rgba(4, -3, 0.5, 1)' | '#aabbccdd' | '#abcd'>}); + <'red' | 'canvas' | 'rgba(4, -3, 0.5, 1)' | '#aabbccdd' | + '#abcd'>}") }}; - @unroll @assert throws TypeError new CanvasFilter({\- - name: 'dropShadow', \- + // Should throw a TypeError. + @unroll @assert throws TypeError {{ filter_declaration | replace("param", \- + "{name: 'dropShadow', \- <dx | dy | floodOpacity>: \- - <NaN | Infinity | -Infinity | undefined | 'test' | {} | [1, 2]>}); - @unroll @assert throws TypeError new CanvasFilter({\- - name: 'dropShadow', \- + <NaN | Infinity | -Infinity | undefined | 'test' | {} | [1, 2]>}") }}; + @unroll @assert throws TypeError {{ filter_declaration | replace("param", \- + "{name: 'dropShadow', \- <stdDeviation>: \- <NaN | Infinity | -Infinity | undefined | 'test' | {} | [1, 2, 3] | \- [1, NaN] | [1, Infinity] | [1, -Infinity] | [1, undefined] | \- - [1, 'test'] | [1, {}] | [1, [2, 3]]>}); - @unroll @assert throws TypeError new CanvasFilter({\- - name: 'dropShadow', \- + [1, 'test'] | [1, {}] | [1, [2, 3]]>}") }}; + @unroll @assert throws TypeError {{ filter_declaration | replace("param", \- + "{name: 'dropShadow', \- <floodColor>: \- - <'test' | 'rgba(NaN, 3, 2, 1)' | 10 | undefined | null | NaN>}); - -- name: 2d.filter.canvasFilterObject.turbulence.inputTypes.tentative + <'test' | 'rgba(NaN, 3, 2, 1)' | 10 | undefined | null | NaN>}") }}; + append_variants_to_name: false + variants: + layers: + filter_declaration: |- + ctx.beginLayer({filter: + param}); ctx.endLayer() + canvasFilterObject: + filter_declaration: |- + ctx.filter = new CanvasFilter( + param) + tentative: .tentative + +- name: 2d.filter.{{ variant_names[0] }}.turbulence.inputTypes{{ tentative }} desc: Test exceptions on CanvasFilter() turbulence object code: | const errorTestCases = [ @@ -671,10 +979,22 @@ for (testCase of errorTestCases) { const filterOptions = {...{name: 'turbulence'}, ...testCase}; - @assert throws TypeError new CanvasFilter(filterOptions); + @assert throws TypeError {{ filter_declaration | + replace("param", "filterOptions") }}; } for (testCase of workingTestCases) { const filterOptions = {...{name: 'turbulence'}, ...testCase}; - @assert new CanvasFilter(filterOptions) != null; + {{ filter_declaration | replace("param", "filterOptions") }}; + {{- close_layer }} } + append_variants_to_name: false + variants: + layers: + filter_declaration: |- + ctx.beginLayer({filter: param}) + close_layer: "\n ctx.endLayer();" + canvasFilterObject: + filter_declaration: |- + ctx.filter = new CanvasFilter(param) + tentative: .tentative diff --git a/testing/web-platform/tests/html/canvas/tools/yaml-new/layers.yaml b/testing/web-platform/tests/html/canvas/tools/yaml-new/layers.yaml index a44cb2ea2c..437a70c3f7 100644 --- a/testing/web-platform/tests/html/canvas/tools/yaml-new/layers.yaml +++ b/testing/web-platform/tests/html/canvas/tools/yaml-new/layers.yaml @@ -44,7 +44,7 @@ variants: &global-state-variants no-global-states: render_states: // No global states. - alpha: + alpha: &global-state-alpha render_states: ctx.globalAlpha = 0.6; blending: render_states: ctx.globalCompositeOperation = 'multiply'; @@ -56,15 +56,15 @@ ctx.shadowOffsetY = 10; ctx.shadowColor = 'rgba(255, 165, 0, 0.5)'; ctx.shadowBlur = 3; - alpha.blending: + alpha.blending: &global-state-alpha-blending render_states: |- ctx.globalAlpha = 0.6; ctx.globalCompositeOperation = 'multiply'; - alpha.composite: + alpha.composite: &global-state-alpha-composite render_states: |- ctx.globalAlpha = 0.6; ctx.globalCompositeOperation = 'source-in'; - alpha.shadow: + alpha.shadow: &global-state-alpha-shadow render_states: |- ctx.globalAlpha = 0.5; ctx.shadowOffsetX = -10; @@ -167,7 +167,20 @@ ctx.drawImage(img, 0, 0); }; img.src = 'data:image/svg+xml;base64,' + btoa(svg); - variants: *global-state-variants + variants: + <<: *global-state-variants + alpha: + <<: *global-state-alpha + fuzzy: maxDifference=0-2; totalPixels=0-6766 + alpha.blending: + <<: *global-state-alpha-blending + fuzzy: maxDifference=0-1; totalPixels=0-2453 + alpha.composite: + <<: *global-state-alpha-composite + fuzzy: maxDifference=0-1; totalPixels=0-5204 + alpha.shadow: + <<: *global-state-alpha-shadow + fuzzy: maxDifference=0-2; totalPixels=0-6311 - name: 2d.layer.global-filter desc: Tests that layers ignore the global context filter. @@ -334,6 +347,144 @@ ctx.drawImage(canvas2, 0, 0); +- name: 2d.layer.ctm.filter + desc: Checks that parent transforms affect layer filters. + size: [200, 200] + code: | + // Transforms inside the layer should not apply to the layer's filter. + ctx.beginLayer({filter: 'drop-shadow(5px 5px 0px grey)'}); + ctx.translate(30, 90); + ctx.scale(2, 2); + ctx.rotate(Math.PI / 2); + ctx.fillRect(-30, -5, 60, 10); + ctx.endLayer(); + + // Transforms in the layer's parent should apply to the layer's filter. + ctx.translate(80, 90); + ctx.scale(2, 2); + ctx.rotate(Math.PI / 2); + ctx.beginLayer({filter: 'drop-shadow(5px 5px 0px grey)'}); + ctx.fillRect(-30, -5, 60, 10); + ctx.endLayer(); + html_reference: | + <svg xmlns="http://www.w3.org/2000/svg" + width="{{ size[0] }}" height="{{ size[1] }}" + color-interpolation-filters="sRGB"> + <filter id="filter" x="-100%" y="-100%" width="300%" height="300%"> + <feDropShadow dx="5" dy="5" stdDeviation="0" flood-color="grey" /> + </filter> + + <g filter="url(#filter)"> + <g transform="translate(30, 90) scale(2) rotate(90)"> + <rect x="-30" y="-5" width=60 height=10></rect> + </g> + </g> + + <g transform="translate(80, 90) scale(2) rotate(90)"> + <g filter="url(#filter)"> + <rect x="-30" y="-5" width=60 height=10></rect> + </g> + </g> + </svg> + +- name: 2d.layer.ctm.shadow-in-transformed-layer + desc: Check shadows inside of a transformed layer. + size: [200, 200] + code: | + ctx.translate(80, 90); + ctx.scale(2, 2); + ctx.rotate(Math.PI / 2); + + ctx.beginLayer(); + ctx.shadowOffsetX = 10; + ctx.shadowOffsetY = 10; + ctx.shadowColor = 'grey'; + ctx.fillRect(-30, -5, 60, 10); + + const canvas2 = new OffscreenCanvas(100, 100); + const ctx2 = canvas2.getContext('2d'); + ctx2.fillStyle = 'blue'; + ctx2.fillRect(0, 0, 40, 10); + ctx.drawImage(canvas2, -30, -30); + + ctx.endLayer(); + reference: | + ctx.translate(80, 90); + ctx.scale(2, 2); + ctx.rotate(Math.PI / 2); + + ctx.shadowOffsetX = 10; + ctx.shadowOffsetY = 10; + ctx.shadowColor = 'grey'; + ctx.fillRect(-30, -5, 60, 10); + + const canvas2 = new OffscreenCanvas(100, 100); + const ctx2 = canvas2.getContext('2d'); + ctx2.fillStyle = 'blue'; + ctx2.fillRect(0, 0, 40, 10); + ctx.drawImage(canvas2, -30, -30); + +- name: 2d.layer.ctm.getTransform + desc: Tests getTransform inside layers. + code: | + ctx.translate(10, 20); + ctx.beginLayer(); + ctx.scale(2, 3); + const m = ctx.getTransform(); + assert_array_equals([m.a, m.b, m.c, m.d, m.e, m.f], [2, 0, 0, 3, 10, 20]); + ctx.endLayer(); + +- name: 2d.layer.ctm.setTransform + desc: Tests setTransform inside layers. + code: | + ctx.translate(80, 0); + + ctx.beginLayer(); + ctx.rotate(2); + ctx.beginLayer(); + ctx.scale(5, 6); + ctx.setTransform(4, 0, 0, 2, 20, 10); + ctx.fillStyle = 'blue'; + ctx.fillRect(0, 0, 10, 10); + ctx.endLayer(); + ctx.endLayer(); + + ctx.fillStyle = 'green'; + ctx.fillRect(0, 0, 20, 20); + reference: | + ctx.translate(80, 0); + ctx.fillStyle = 'green'; + ctx.fillRect(0, 0, 20, 20); + + ctx.setTransform(4, 0, 0, 2, 20, 10); + ctx.fillStyle = 'blue'; + ctx.fillRect(0, 0, 10, 10); + +- name: 2d.layer.ctm.resetTransform + desc: Tests resetTransform inside layers. + code: | + ctx.translate(40, 0); + + ctx.beginLayer(); + ctx.rotate(2); + ctx.beginLayer(); + ctx.scale(5, 6); + ctx.resetTransform(); + ctx.fillStyle = 'blue'; + ctx.fillRect(0, 0, 20, 20); + ctx.endLayer(); + ctx.endLayer(); + + ctx.fillStyle = 'green'; + ctx.fillRect(0, 0, 20, 20); + reference: | + ctx.fillStyle = 'blue'; + ctx.fillRect(0, 0, 20, 20); + + ctx.translate(40, 0); + ctx.fillStyle = 'green'; + ctx.fillRect(0, 0, 20, 20); + - name: 2d.layer.clip-inside desc: Check clipping set inside the layer size: [100, 100] @@ -627,6 +778,49 @@ ctx.fillStyle = 'blue'; ctx.fillRect(10, 10, 80, 50); +- name: 2d.layer.drawImage + size: [200, 200] + desc: >- + Checks that drawImage writes the image to the layer and not the parent + directly. + code: | + ctx.fillStyle = 'skyblue'; + ctx.fillRect(0, 0, 100, 100); + + ctx.beginLayer({filter: {name: 'dropShadow', dx: -10, dy: -10, + stdDeviation: 0, floodColor: 'navy'}}); + + ctx.fillStyle = 'maroon'; + ctx.fillRect(20, 20, 50, 50); + + ctx.globalCompositeOperation = 'xor'; + + // The image should xor only with the layer content, not the parents'. + const canvas_image = new OffscreenCanvas(200,200); + const ctx_image = canvas_image.getContext("2d"); + ctx_image.fillStyle = 'pink'; + ctx_image.fillRect(40, 40, 50, 50); + ctx.drawImage(canvas_image, 0, 0); + + ctx.endLayer(); + reference: | + ctx.fillStyle = 'skyblue'; + ctx.fillRect(0, 0, 100, 100); + + ctx.beginLayer({filter: {name: 'dropShadow', dx: -10, dy: -10, + stdDeviation: 0, floodColor: 'navy'}}); + + ctx.fillStyle = 'maroon'; + ctx.fillRect(20, 20, 50, 50); + + ctx.globalCompositeOperation = 'xor'; + + // Should xor only with the layer content, not the parents'. + ctx.fillStyle = 'pink'; + ctx.fillRect(40, 40, 50, 50); + + ctx.endLayer(); + - name: 2d.layer.valid-calls desc: No exception raised on {{ variant_desc }}. variants: diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-assorted.window.js b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-assorted.window.js index 0d4e4b82d9..2017269f0b 100644 --- a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-assorted.window.js +++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-assorted.window.js @@ -90,10 +90,11 @@ for (const bdi_test of [ { markup: "<bdi dir=rtl></bdi>", expected: "rtl", desc: "dir=rtl empty" }, { markup: "<bdi dir=auto>A</bdi>", expected: "ltr", desc: "dir=auto with LTR contents" }, { markup: "<bdi dir=auto>\u05d0</bdi>", expected: "rtl", desc: "dir=auto with RTL contents" }, - { markup: "<bdi dir=auto></bdi>", expected: "parent", desc: "dir=auto empty" }, + { markup: "<bdi dir=auto></bdi>", expected: "ltr", desc: "dir=auto empty" }, + { markup: "<bdi dir=auto>123</bdi>", expected: "ltr", desc: "dir=auto numbers" }, { markup: "<bdi>A</bdi>", expected: "ltr", desc: "no dir attribute with LTR contents" }, { markup: "<bdi>\u05d0</bdi>", expected: "rtl", desc: "no dir attribute with RTL contents" }, - { markup: "<bdi></bdi>", expected: "parent", desc: "no dir attribute empty" }, + { markup: "<bdi></bdi>", expected: "ltr", desc: "no dir attribute empty" }, ]) { for (const parent_dir of [ "ltr", "rtl" ]) { test(() => { diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-auto-dynamic-simple-dataChange.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-auto-dynamic-simple-dataChange.html new file mode 100644 index 0000000000..ded136a3ae --- /dev/null +++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-auto-dynamic-simple-dataChange.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<meta charset="utf-8"> +<title>Dynamic changes with textContent and dir=auto</title> +<link rel="match" href="dir-auto-dynamic-simple-ref.html"> +<div>Test for elements with dir="auto" whose content changes between directional and neutral</div> +<div dir="auto" id="from_ltr_to_ltr">abc</div> +<div dir="auto" id="from_ltr_to_rtl">abc</div> +<div dir="auto" id="from_ltr_to_neutral">abc</div> +<div dir="auto" id="from_rtl_to_ltr">אבג</div> +<div dir="auto" id="from_rtl_to_rtl">אבג</div> +<div dir="auto" id="from_rtl_to_neutral">אבג</div> +<div dir="auto" id="from_neutral_to_ltr">123</div> +<div dir="auto" id="from_neutral_to_rtl">123</div> +<div dir="auto" id="from_neutral_to_neutral">123</div> +<script> +function changeContent() { + var directionalTexts = {ltr:"xyz", rtl:"ابج", neutral:"456"}; + + for (var dirFrom in directionalTexts) { + for (var dirTo in directionalTexts) { + var element = document.getElementById("from_" + dirFrom + + "_to_" + dirTo); + element.firstChild.data = directionalTexts[dirTo]; + } + } + document.documentElement.removeAttribute("class"); +} + +document.addEventListener("TestRendered", changeContent); +</script> diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-auto-dynamic-simple-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-auto-dynamic-simple-ref.html new file mode 100644 index 0000000000..5a9a2f2484 --- /dev/null +++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-auto-dynamic-simple-ref.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Dynamic changes and dir=auto</title> +<div>Test for elements with dir="auto" whose content changes between directional and neutral</div> +<div dir="auto">xyz</div> +<div dir="auto">ابج</div> +<div dir="auto">456</div> +<div dir="auto">xyz</div> +<div dir="auto">ابج</div> +<div dir="auto">456</div> +<div dir="auto">xyz</div> +<div dir="auto">ابج</div> +<div dir="auto">456</div> diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-auto-dynamic-simple-replace.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-auto-dynamic-simple-replace.html new file mode 100644 index 0000000000..6d785f08b8 --- /dev/null +++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-auto-dynamic-simple-replace.html @@ -0,0 +1,32 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<meta charset="utf-8"> +<title>Dynamic changes with textContent and dir=auto</title> +<link rel="match" href="dir-auto-dynamic-simple-ref.html"> +<div>Test for elements with dir="auto" whose content changes between directional and neutral</div> +<div dir="auto" id="from_ltr_to_ltr">abc</div> +<div dir="auto" id="from_ltr_to_rtl">abc</div> +<div dir="auto" id="from_ltr_to_neutral">abc</div> +<div dir="auto" id="from_rtl_to_ltr">אבג</div> +<div dir="auto" id="from_rtl_to_rtl">אבג</div> +<div dir="auto" id="from_rtl_to_neutral">אבג</div> +<div dir="auto" id="from_neutral_to_ltr">123</div> +<div dir="auto" id="from_neutral_to_rtl">123</div> +<div dir="auto" id="from_neutral_to_neutral">123</div> +<script> +function changeContent() { + var directionalTexts = {ltr:"xyz", rtl:"ابج", neutral:"456"}; + + for (var dirFrom in directionalTexts) { + for (var dirTo in directionalTexts) { + var element = document.getElementById("from_" + dirFrom + + "_to_" + dirTo); + element.firstChild.remove(); + element.appendChild(document.createTextNode(directionalTexts[dirTo])); + } + } + document.documentElement.removeAttribute("class"); +} + +document.addEventListener("TestRendered", changeContent); +</script> diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-auto-dynamic-simple-textContent.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-auto-dynamic-simple-textContent.html new file mode 100644 index 0000000000..3b644908ab --- /dev/null +++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-auto-dynamic-simple-textContent.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<meta charset="utf-8"> +<title>Dynamic changes with textContent and dir=auto</title> +<link rel="match" href="dir-auto-dynamic-simple-ref.html"> +<div>Test for elements with dir="auto" whose content changes between directional and neutral</div> +<div dir="auto" id="from_ltr_to_ltr">abc</div> +<div dir="auto" id="from_ltr_to_rtl">abc</div> +<div dir="auto" id="from_ltr_to_neutral">abc</div> +<div dir="auto" id="from_rtl_to_ltr">אבג</div> +<div dir="auto" id="from_rtl_to_rtl">אבג</div> +<div dir="auto" id="from_rtl_to_neutral">אבג</div> +<div dir="auto" id="from_neutral_to_ltr">123</div> +<div dir="auto" id="from_neutral_to_rtl">123</div> +<div dir="auto" id="from_neutral_to_neutral">123</div> +<script> +function changeContent() { + var directionalTexts = {ltr:"xyz", rtl:"ابج", neutral:"456"}; + + for (var dirFrom in directionalTexts) { + for (var dirTo in directionalTexts) { + var element = document.getElementById("from_" + dirFrom + + "_to_" + dirTo); + element.textContent = directionalTexts[dirTo]; + } + } + document.documentElement.removeAttribute("class"); +} + +document.addEventListener("TestRendered", changeContent); +</script> diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-41-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-41-ref.html index b52e08df20..79b844edbe 100644 --- a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-41-ref.html +++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-41-ref.html @@ -18,7 +18,7 @@ span {border: 1px solid silver;} <p>`dir=rtl` on a div in the shadow tree, `dir=ltr` on the shadow host, no slotted text in the light or dark trees</p> <div id="host" dir="ltr"><div dir="rtl"><span></span></div></div> -<p id="result">The HTML direction / computed CSS `direction` value is: rtl / rtl (on the slot).</p> +<p id="result">The HTML direction / computed CSS `direction` value is: ltr / ltr (on the slot).</p> </body> </html> diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-42-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-42-ref.html new file mode 100644 index 0000000000..8ea1100246 --- /dev/null +++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-42-ref.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>[dir] and shadow slots: dir=ltr on a div in the shadow tree, dir=rtl on the shadow host, no slotted text in the light or dark trees</title> +<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com"> +<link rel="author" title="L. David Baron" href="mailto:dbaron@chromium.org"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute"> +<link rel="help" href="https://github.com/whatwg/html/issues/3699"> +<link rel="help" href="https://github.com/whatwg/html/pull/9796"> +<style type="text/css"> +body {width: 600px;} +#host {border: 1px solid gray; margin: 1em; padding: 0.25em;} +span {border: 1px solid silver;} + +</style> +</head> +<body> + +<p>`dir=ltr` on a div in the shadow tree, `dir=rtl` on the shadow host, no slotted text in the light or dark trees</p> +<div id="host" dir="rtl"><div dir="ltr"><span></span></div></div> +<p id="result">The HTML direction / computed CSS `direction` value is: ltr / ltr (on the slot).</p> + +</body> +</html> diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-42.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-42.html new file mode 100644 index 0000000000..b9697678cb --- /dev/null +++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-42.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"/> +<title>[dir] and shadow slots: dir=ltr on a div in the shadow tree, dir=rtl on the shadow host, no slotted text in the light or dark trees</title> +<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com"> +<link rel="author" title="L. David Baron" href="mailto:dbaron@chromium.org"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute"> +<link rel="help" href="https://github.com/whatwg/html/issues/3699"> +<link rel="help" href="https://github.com/whatwg/html/pull/9796"> +<link rel="match" href="dir-shadow-42-ref.html"> +<style type="text/css"> +body {width: 600px;} +#host {border: 1px solid gray; margin: 1em; padding: 0.25em;} +span {border: 1px solid silver;} + +</style> +<script src="dir-shadow-utils.js"></script> +</head> +<body> + +<p>`dir=ltr` on a div in the shadow tree, `dir=rtl` on the shadow host, no slotted text in the light or dark trees</p> +<div id="host" dir="rtl"><span slot="x1"></span></div> +<p id="result">The HTML direction / computed CSS `direction` value is: </p> + +<script type="text/javascript"> + let root = host.attachShadow({mode:"open"}); + root.innerHTML = `<div dir="ltr"><slot dir="auto" name="x1"></slot></div>`; + result.innerHTML += html_direction(root.querySelector("div[dir=ltr]").firstChild) + " / " + getComputedStyle(root.querySelector("div[dir=ltr]").firstChild).direction + " (on the " + root.querySelector("div[dir=ltr]").firstChild.localName + ').'; +</script> + +</body> +</html> diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN-ref.html index 0d938b2e16..496d699d73 100644 --- a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN-ref.html +++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN-ref.html @@ -10,7 +10,7 @@ <meta name="assert" content=" When dir='auto', the direction is set according to the first strong character of the text, ignoring neutrals and numbers. - If there is no strong character, as in this test, the direction defaults to the parent." /> + If there is no strong character, as in this test, the direction defaults to LTR." /> <style> input, textarea { font-size:1em; @@ -35,7 +35,7 @@ <p dir="ltr">@123!</p> </div> <div dir="rtl"> - <p dir="rtl">@123!</p> + <p dir="ltr">@123!</p> </div> </div> <div class="ref"> @@ -43,7 +43,7 @@ <p dir="ltr">@123!</p> </div> <div dir="rtl"> - <p dir="rtl">@123!</p> + <p dir="ltr">@123!</p> </div> </div> </body> diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN.html index 467b4d0939..5d948d3456 100644 --- a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN.html +++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN.html @@ -11,7 +11,7 @@ <meta name="assert" content=" When dir='auto', the direction is set according to the first strong character of the text, ignoring neutrals and numbers. - If there is no strong character, as in this test, the direction defaults to the parent." /> + If there is no strong character, as in this test, the direction defaults to LTR." /> <style> input, textarea { font-size:1em; @@ -44,7 +44,7 @@ <p dir="ltr">@123!</p> </div> <div dir="rtl"> - <p dir="rtl">@123!</p> + <p dir="ltr">@123!</p> </div> </div> </body> diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-001.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-001.html index 36567f9d54..36567f9d54 100644 --- a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-001.tentative.html +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-001.html diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-002.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-002.html index 3c907597f7..3c907597f7 100644 --- a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-002.tentative.html +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-002.html diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-003.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-003.html index 2858798a35..2858798a35 100644 --- a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-003.tentative.html +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-003.html diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-004.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-004.html index f45f558720..f45f558720 100644 --- a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-004.tentative.html +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-004.html diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-005.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-005.html index 098a3c5767..098a3c5767 100644 --- a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-005.tentative.html +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-005.html diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-006.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-006.html index 223e42109e..223e42109e 100644 --- a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-006.tentative.html +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-006.html diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-007.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-007.html index 9aa0aeea79..9aa0aeea79 100644 --- a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-007.tentative.html +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-007.html diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-008.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-008.html index e671dda19c..e671dda19c 100644 --- a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-008.tentative.html +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-008.html diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-009.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-009.html index 8498816ea5..8498816ea5 100644 --- a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-009.tentative.html +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-009.html diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-010.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-010.html index ef6f709012..ef6f709012 100644 --- a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-010.tentative.html +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-010.html diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-011.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-011.html index dee82d8c59..dee82d8c59 100644 --- a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-011.tentative.html +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-011.html diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-012.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-012.html index 4110e54c5f..4110e54c5f 100644 --- a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-012.tentative.html +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-012.html diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-013.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-013.html index ecd97be86a..ecd97be86a 100644 --- a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-013.tentative.html +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-013.html diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-014.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-014.html index ea8948de42..ea8948de42 100644 --- a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-014.tentative.html +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-014.html diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-015.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-015.html index a775ee4174..a775ee4174 100644 --- a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-015.tentative.html +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-015.html diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-016.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-016.html index 8968c5dacd..8968c5dacd 100644 --- a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-016.tentative.html +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-016.html diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-017.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-017.html index 2d3b574721..2d3b574721 100644 --- a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-017.tentative.html +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-017.html diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-018.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-018.html index 76e6394b5b..76e6394b5b 100644 --- a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-018.tentative.html +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-018.html diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-019.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-019.html index 80a7019edc..80a7019edc 100644 --- a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-019.tentative.html +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-019.html diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-020.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-020.html index 10019c943f..10019c943f 100644 --- a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-020.tentative.html +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-020.html diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-021.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-021.html index 1ca2114689..1ca2114689 100644 --- a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-021.tentative.html +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-021.html diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-022.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-022.html index 5dfbcac30a..5dfbcac30a 100644 --- a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-022.tentative.html +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-022.html diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-023.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-023.html index 8fe8b6a8c8..8fe8b6a8c8 100644 --- a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-023.tentative.html +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-023.html diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-024.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-024.html index 19e4020fb7..19e4020fb7 100644 --- a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-024.tentative.html +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-024.html diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-025.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-025.html index 689ae69f45..689ae69f45 100644 --- a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-025.tentative.html +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-025.html diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-026.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-026.html index 6abfc43b8b..6abfc43b8b 100644 --- a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-026.tentative.html +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-026.html diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-027.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-027.html index 56f88e0fc2..56f88e0fc2 100644 --- a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-027.tentative.html +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-027.html diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-028.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-028.html index a64d542c4a..a64d542c4a 100644 --- a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-028.tentative.html +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-028.html diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-029.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-029.html new file mode 100644 index 0000000000..44dff3cb84 --- /dev/null +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-029.html @@ -0,0 +1,29 @@ +<!DOCTYPE html> +<head> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="support/utils.js"></script> +<title>`link rel=expect` supports <a name></title> + +<link rel=expect href="#second" blocking="render"> +<script> +async_test((t) => { + requestAnimationFrame(() => { + t.step(() => assert_true(!!document.getElementsByName("second")), "the second element should unblock rendering"); + t.step(() => assert_false(!!document.getElementById("last"))); + t.done(); + }); +}, "blocking defers frames until full parsing"); +</script> +</head> +<body> + <div id="first"></div> + <script> + generateParserDelay(); + </script> + <a name="second"></a> + <script> + generateParserDelay(); + </script> + <div id="last"></div> +</body> diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-030.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-030.html new file mode 100644 index 0000000000..307c2d303d --- /dev/null +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-030.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<head> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="support/utils.js"></script> +<title><a name> should only unblock when finished parsing children</title> + +<link rel=expect href="#fold" blocking="render"> +<script> +async_test((t) => { + requestAnimationFrame(() => { + t.step(() => assert_true(!!document.getElementsByName("second"))); + t.step(() => assert_false(!!document.getElementById("last")), "the second element should already unblock rendering"); + t.done(); + }); +}, "blocking defers frames until full parsing"); +</script> +</head> +<body> + <div id="first"></div> + <script> + generateParserDelay(); + </script> + <a name="fold"> + <script> + generateParserDelay(); + </script> + <div id="second"></div> + </a> + <script> + generateParserDelay(); + </script> + <div id="last"></div> +</body> diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-031.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-031.html new file mode 100644 index 0000000000..2098483a06 --- /dev/null +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-031.html @@ -0,0 +1,32 @@ +<!DOCTYPE html> +<head> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="support/utils.js"></script> +<title>`link rel=expect` supports dynamically changed <a name></title> + +<link rel=expect href="#second" blocking="render"> +<script> +async_test((t) => { + requestAnimationFrame(() => { + t.step(() => assert_true(!!document.getElementsByName("second"))); + t.step(() => assert_false(!!document.getElementById("last")), "the second element should already unblock rendering"); + t.done(); + }); +}, "blocking defers frames until full parsing"); +</script> +</head> +<body> + <div id="first"></div> + <script> + generateParserDelay(); + </script> + <a id="fold"></a> + <script> + document.getElementById("fold").setAttribute("name", "second"); + </script> + <script> + generateParserDelay(); + </script> + <div id="last"></div> +</body> diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-032.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-032.html new file mode 100644 index 0000000000..307c2d303d --- /dev/null +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-032.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<head> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="support/utils.js"></script> +<title><a name> should only unblock when finished parsing children</title> + +<link rel=expect href="#fold" blocking="render"> +<script> +async_test((t) => { + requestAnimationFrame(() => { + t.step(() => assert_true(!!document.getElementsByName("second"))); + t.step(() => assert_false(!!document.getElementById("last")), "the second element should already unblock rendering"); + t.done(); + }); +}, "blocking defers frames until full parsing"); +</script> +</head> +<body> + <div id="first"></div> + <script> + generateParserDelay(); + </script> + <a name="fold"> + <script> + generateParserDelay(); + </script> + <div id="second"></div> + </a> + <script> + generateParserDelay(); + </script> + <div id="last"></div> +</body> diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-033.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-033.html new file mode 100644 index 0000000000..59d41c08c0 --- /dev/null +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-033.html @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<head> +<meta charset="utf8"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="support/utils.js"></script> +<title>link rel=expect should support percent encoding</title> + +<link rel=expect href="#se%F0%9F%98%8Fcond" blocking="render"> +<script> +async_test((t) => { + requestAnimationFrame(() => { + t.step(() => assert_true(!!document.getElementById("se😏cond"))); + t.step(() => assert_false(!!document.getElementById("last")), "the second element should already unblock rendering"); + t.done(); + }); +}, "blocking defers frames until full parsing"); +</script> +</head> +<body> + <div id="first"></div> + <script> + generateParserDelay(); + </script> + <div id="se😏cond"></div> + <script> + generateParserDelay(); + </script> + <div id="last"></div> +</body> diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-034.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-034.html new file mode 100644 index 0000000000..a505de4875 --- /dev/null +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-034.html @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<head> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="support/utils.js"></script> +<title>link rel=expect should allow relative URLs</title> + +<link rel=expect href="../render-blocking/element-render-blocking-034.html#second" blocking="render"> +<script> +async_test((t) => { + requestAnimationFrame(() => { + t.step(() => assert_true(!!document.getElementById("second"))); + t.step(() => assert_false(!!document.getElementById("last")), "the second element should already unblock rendering"); + t.done(); + }); +}, "relative URLs that match this document are OK"); +</script> +</head> +<body> + <div id="first"></div> + <script> + generateParserDelay(); + </script> + <div id="second"> + </div> + <script> + generateParserDelay(); + </script> + <div id="last"></div> +</body> diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-035.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-035.html new file mode 100644 index 0000000000..050244c7a6 --- /dev/null +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-035.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<head> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="support/utils.js"></script> +<title>link rel=expect: base URL should be OK with relative URLs</title> + +<base href="dummy.html"> +<link rel=expect href="../render-blocking/element-render-blocking-035.html#second" blocking="render"> +<script> +async_test((t) => { + requestAnimationFrame(() => { + t.step(() => assert_true(!!document.getElementById("second"))); + t.step(() => assert_false(!!document.getElementById("last")), "the second element should already unblock rendering"); + t.done(); + }); +}, "relative URLs that match this document are OK, regarless of <base>"); +</script> +</head> +<body> + <div id="first"></div> + <script> + generateParserDelay(); + </script> + <div id="second"> + </div> + <script> + generateParserDelay(); + </script> + <div id="last"></div> +</body> diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-036.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-036.html new file mode 100644 index 0000000000..83637b3a08 --- /dev/null +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-036.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<head> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="support/utils.js"></script> +<title>link rel=expect: base URL mismatch causes link to not block</title> + +<base href="dummy.html"> +<link rel=expect href="#second" blocking="render"> +<script> +async_test((t) => { + requestAnimationFrame(() => { + t.step(() => assert_true(!!document.getElementById("first"))); + t.step(() => assert_false(!!document.getElementById("second")), "the first element should already unblock rendering"); + t.done(); + }); +}, "link URLs are relative to base URL, not to document URL"); +</script> +</head> +<body> + <div id="first"></div> + <script> + generateParserDelay(); + </script> + <div id="second"> + </div> + <script> + generateParserDelay(); + </script> + <div id="last"></div> +</body> diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-037.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-037.html new file mode 100644 index 0000000000..5fe469a2fd --- /dev/null +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-037.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<head> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="support/utils.js"></script> +<title>link rel=expect: base URL should be OK with relative URLs</title> + +<base href="dummy.html"> +<link rel=expect href="../render-blocking/element-render-blocking-037.html#second" blocking="render"> +<script> +async_test((t) => { + requestAnimationFrame(() => { + t.step(() => assert_true(!!document.getElementById("second"))); + t.step(() => assert_false(!!document.getElementById("last")), "the second element should already unblock rendering"); + t.done(); + }); +}, "relative URLs that match this document are OK, regarless of <base>"); +</script> +</head> +<body> + <div id="first"></div> + <script> + generateParserDelay(); + </script> + <div id="second"> + </div> + <script> + generateParserDelay(); + </script> + <div id="last"></div> +</body> diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-038.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-038.html new file mode 100644 index 0000000000..c7fabe7f32 --- /dev/null +++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-038.html @@ -0,0 +1,35 @@ +<!DOCTYPE html> +<head> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="support/utils.js"></script> +<title>link rel=expect: only connected elements are eligible</title> + +<link rel=expect href="#second" blocking="render"> +<script> +async_test((t) => { + requestAnimationFrame(() => { + t.step(() => assert_true(!!document.getElementById("second"), "The second element should be there")); + t.step(() => assert_false(!!document.getElementById("last"), "The last element should not be there yet, even though it's created (in a shadow root)")); + t.done(); + }); +}, ""); +</script> +</head> +<body> + <div id="first"></div> + <script> + generateParserDelay(); + </script> + <div id="second"> + <custom-element> + <template shadowrootmode="open"> + <div id="last"></div> + </template> + </custom-element> + </div> + <script> + generateParserDelay(); + </script> + <div id="last"></div> +</body> diff --git a/testing/web-platform/tests/html/editing/editing-0/writing-suggestions/writingsuggestions.html b/testing/web-platform/tests/html/editing/editing-0/writing-suggestions/writingsuggestions.html index 49e75000d3..664659d90a 100644 --- a/testing/web-platform/tests/html/editing/editing-0/writing-suggestions/writingsuggestions.html +++ b/testing/web-platform/tests/html/editing/editing-0/writing-suggestions/writingsuggestions.html @@ -29,13 +29,33 @@ test(function() { assert_true('writingSuggestions' in document.createElement('test-custom-element')); }, 'Test that the writingsuggestions attribute is available on custom elements.'); +test(function() { + let input = document.createElement('input'); + input.type = 'color'; + assert_true('writingSuggestions' in input); +}, 'Test that the writingsuggestions attribute is available on an input type which the attribute doesn\'t apply. The User Agent is responsible that writing suggestions are not applied to the element.'); + +test(function() { + let textarea = document.createElement('textarea'); + textarea.disabled = true; + assert_true('writingSuggestions' in textarea); +}, 'Test that the writingsuggestions attribute is available on a disabled element. The User Agent is responsible that writing suggestions are not applied to the element.'); + function testSetAttributeDirectly(IDLValue, contentValue, expectedIDLValue, expectedContentValue, testDescription) { test(function() { + let input_color = document.createElement('input'); + input_color.type = 'color'; + + let disabled_textarea = document.createElement('textarea'); + disabled_textarea.disabled = true; + const elements = [document.createElement('input'), document.createElement('textarea'), document.createElement('div'), document.createElement('span'), - document.createElement('test-custom-element') ]; + document.createElement('test-custom-element'), + disabled_textarea, + input_color ]; elements.forEach(function(element) { if (IDLValue != undefined) { @@ -55,7 +75,7 @@ testSetAttributeDirectly('true', undefined, 'true', 'true', 'Test setting the `w testSetAttributeDirectly(undefined, 'true', 'true', 'true', 'Test setting the `writingsuggestions` content attribute to `true` directly on the target element.'); testSetAttributeDirectly(true, undefined, 'true', 'true', 'Test setting the `writingsuggestions` IDL attribute to boolean `true` directly on the target element.'); testSetAttributeDirectly(undefined, true, 'true', 'true', 'Test setting the `writingsuggestions` content attribute to boolean `true` directly on the target element.'); -testSetAttributeDirectly('TrUe', undefined, 'true', 'true', 'Test setting the `writingsuggestions` IDL attribute to `TrUe` directly on the target element.'); +testSetAttributeDirectly('TrUe', undefined, 'true', 'TrUe', 'Test setting the `writingsuggestions` IDL attribute to `TrUe` directly on the target element.'); testSetAttributeDirectly(undefined, 'TrUe', 'true', 'TrUe', 'Test setting the `writingsuggestions` content attribute to `TrUe` directly on the target element.'); // Test setting either the `writingsuggestions` IDL or content attribute to some variation of 'false' directly on the target element. @@ -63,15 +83,15 @@ testSetAttributeDirectly('false', undefined, 'false', 'false', 'Test setting the testSetAttributeDirectly(undefined, 'false', 'false', 'false', 'Test setting the `writingsuggestions` content attribute to `false` directly on the target element.'); testSetAttributeDirectly(false, undefined, 'false', 'false', 'Test setting the `writingsuggestions` IDL attribute to boolean `false` directly on the target element.'); testSetAttributeDirectly(undefined, false, 'false', 'false', 'Test setting the `writingsuggestions` content attribute to boolean `false` directly on the target element.'); -testSetAttributeDirectly('FaLsE', undefined, 'false', 'false', 'Test setting the `writingsuggestions` IDL attribute to `FaLsE` directly on the target element.'); +testSetAttributeDirectly('FaLsE', undefined, 'false', 'FaLsE', 'Test setting the `writingsuggestions` IDL attribute to `FaLsE` directly on the target element.'); testSetAttributeDirectly(undefined, 'FaLsE', 'false', 'FaLsE', 'Test setting the `writingsuggestions` content attribute to `FaLsE` directly on the target element.'); // Test setting either the `writingsuggestions` IDL or content attribute to the empty string directly on the target element. -testSetAttributeDirectly('', undefined, 'true', 'true', 'Test setting the `writingsuggestions` IDL attribute to the empty string directly on the target element.'); +testSetAttributeDirectly('', undefined, 'true', '', 'Test setting the `writingsuggestions` IDL attribute to the empty string directly on the target element.'); testSetAttributeDirectly(undefined, '', 'true', '', 'Test setting the `writingsuggestions` content attribute to the empty string directly on the target element.'); // Test setting either the `writingsuggestions` IDL or content attribute to an invalid value directly on the target element. -testSetAttributeDirectly('foo', undefined, 'true', 'true', 'Test setting the `writingsuggestions` IDL attribute to an invalid value directly on the target element.'); +testSetAttributeDirectly('foo', undefined, 'true', 'foo', 'Test setting the `writingsuggestions` IDL attribute to an invalid value directly on the target element.'); testSetAttributeDirectly(undefined, 'foo', 'true', 'foo', 'Test setting the `writingsuggestions` content attribute to an invalid value directly on the target element.'); // Test setting neither the `writingsuggestions` IDL nor content attribute directly on the target element. @@ -98,7 +118,9 @@ test(function() { const elements = [ new DOMParser().parseFromString('<input writingsuggestions />', 'text/html').body.firstElementChild, new DOMParser().parseFromString('<textarea writingsuggestions></textarea>', 'text/html').body.firstElementChild, new DOMParser().parseFromString('<div writingsuggestions></div>', 'text/html').body.firstElementChild, - new DOMParser().parseFromString('<span writingsuggestions></span>', 'text/html').body.firstElementChild ]; + new DOMParser().parseFromString('<span writingsuggestions></span>', 'text/html').body.firstElementChild, + new DOMParser().parseFromString('<input type="color" writingsuggestions />', 'text/html').body.firstElementChild, + new DOMParser().parseFromString('<textarea disabled writingsuggestions></textarea>', 'text/html').body.firstElementChild ]; elements.forEach(function(element) { assert_equals(element.writingSuggestions, 'true'); @@ -110,7 +132,9 @@ test(function() { const elements = [ new DOMParser().parseFromString('<html><body writingsuggestions="true"><input /></body></html>', 'text/html').body.firstElementChild, new DOMParser().parseFromString('<html><body writingsuggestions="true"><textarea></textarea></body></html>', 'text/html').body.firstElementChild, new DOMParser().parseFromString('<html><body writingsuggestions="true"><div></div></body></html>', 'text/html').body.firstElementChild, - new DOMParser().parseFromString('<html><body writingsuggestions="true"><span></span></body></html>', 'text/html').body.firstElementChild ]; + new DOMParser().parseFromString('<html><body writingsuggestions="true"><span></span></body></html>', 'text/html').body.firstElementChild, + new DOMParser().parseFromString('<html><body writingsuggestions="true"><input type="color"/></body></html>', 'text/html').body.firstElementChild, + new DOMParser().parseFromString('<html><body writingsuggestions="true"><textarea disabled></textarea></body></html>', 'text/html').body.firstElementChild ]; elements.forEach(function(element) { assert_equals(element.parentElement.writingSuggestions, 'true'); @@ -124,7 +148,9 @@ test(function() { const elements = [ new DOMParser().parseFromString('<html><body writingsuggestions=""><input /></body></html>', 'text/html').body.firstElementChild, new DOMParser().parseFromString('<html><body writingsuggestions=""><textarea></textarea></body></html>', 'text/html').body.firstElementChild, new DOMParser().parseFromString('<html><body writingsuggestions=""><div></div></body></html>', 'text/html').body.firstElementChild, - new DOMParser().parseFromString('<html><body writingsuggestions=""><span></span></body></html>', 'text/html').body.firstElementChild ]; + new DOMParser().parseFromString('<html><body writingsuggestions=""><span></span></body></html>', 'text/html').body.firstElementChild, + new DOMParser().parseFromString('<html><body writingsuggestions=""><input type="color"/></body></html>', 'text/html').body.firstElementChild, + new DOMParser().parseFromString('<html><body writingsuggestions=""><textarea disabled></textarea></body></html>', 'text/html').body.firstElementChild ]; elements.forEach(function(element) { assert_equals(element.parentElement.writingSuggestions, 'true'); @@ -138,7 +164,9 @@ test(function() { const elements = [ new DOMParser().parseFromString('<html><body writingsuggestions="false"><input /></body></html>', 'text/html').body.firstElementChild, new DOMParser().parseFromString('<html><body writingsuggestions="false"><textarea></textarea></body></html>', 'text/html').body.firstElementChild, new DOMParser().parseFromString('<html><body writingsuggestions="false"><div></div></body></html>', 'text/html').body.firstElementChild, - new DOMParser().parseFromString('<html><body writingsuggestions="false"><span></span></body></html>', 'text/html').body.firstElementChild ]; + new DOMParser().parseFromString('<html><body writingsuggestions="false"><span></span></body></html>', 'text/html').body.firstElementChild, + new DOMParser().parseFromString('<html><body writingsuggestions="false"><input type="color"/></body></html>', 'text/html').body.firstElementChild, + new DOMParser().parseFromString('<html><body writingsuggestions="false"><textarea disabled></textarea></body></html>', 'text/html').body.firstElementChild ]; elements.forEach(function(element) { assert_equals(element.parentElement.writingSuggestions, 'false'); @@ -152,7 +180,9 @@ test(function() { const elements = [ new DOMParser().parseFromString('<html><body writingsuggestions="foo"><input /></body></html>', 'text/html').body.firstElementChild, new DOMParser().parseFromString('<html><body writingsuggestions="foo"><textarea></textarea></body></html>', 'text/html').body.firstElementChild, new DOMParser().parseFromString('<html><body writingsuggestions="foo"><div></div></body></html>', 'text/html').body.firstElementChild, - new DOMParser().parseFromString('<html><body writingsuggestions="foo"><span></span></body></html>', 'text/html').body.firstElementChild ]; + new DOMParser().parseFromString('<html><body writingsuggestions="foo"><span></span></body></html>', 'text/html').body.firstElementChild, + new DOMParser().parseFromString('<html><body writingsuggestions="foo"><input type="color"/></body></html>', 'text/html').body.firstElementChild, + new DOMParser().parseFromString('<html><body writingsuggestions="foo"><textarea disabled></textarea></body></html>', 'text/html').body.firstElementChild ]; elements.forEach(function(element) { assert_equals(element.parentElement.writingSuggestions, 'true'); @@ -163,10 +193,12 @@ test(function() { }, 'Test setting the `writingsuggestions` attribute to an invalid value on a parent element.'); test(function() { - const elements = [ new DOMParser().parseFromString('<html><body writingsuggestions="true"><input writingsuggestions="false" /></body></html>', 'text/html').body.firstElementChild, + const elements = [ new DOMParser().parseFromString('<html><body writingsuggestions="true"><input writingsuggestions="false"/></body></html>', 'text/html').body.firstElementChild, new DOMParser().parseFromString('<html><body writingsuggestions="true"><textarea writingsuggestions="false"></textarea></body></html>', 'text/html').body.firstElementChild, new DOMParser().parseFromString('<html><body writingsuggestions="true"><div writingsuggestions="false"></div></body></html>', 'text/html').body.firstElementChild, - new DOMParser().parseFromString('<html><body writingsuggestions="true"><span writingsuggestions="false"></span></body></html>', 'text/html').body.firstElementChild ]; + new DOMParser().parseFromString('<html><body writingsuggestions="true"><span writingsuggestions="false"></span></body></html>', 'text/html').body.firstElementChild, + new DOMParser().parseFromString('<html><body writingsuggestions="true"><input type="color" writingsuggestions="false"/></body></html>', 'text/html').body.firstElementChild, + new DOMParser().parseFromString('<html><body writingsuggestions="true"><textarea disabled writingsuggestions="false"></textarea></body></html>', 'text/html').body.firstElementChild ]; elements.forEach(function(element) { assert_equals(element.parentElement.writingSuggestions, 'true'); @@ -177,10 +209,12 @@ test(function() { }, 'Test overriding the parent element\'s `writingsuggestions` attribute from "true" to "false".'); test(function() { - const elements = [ new DOMParser().parseFromString('<html><body writingsuggestions=""><input writingsuggestions="false" /></body></html>', 'text/html').body.firstElementChild, + const elements = [ new DOMParser().parseFromString('<html><body writingsuggestions=""><input writingsuggestions="false"/></body></html>', 'text/html').body.firstElementChild, new DOMParser().parseFromString('<html><body writingsuggestions=""><textarea writingsuggestions="false"></textarea></body></html>', 'text/html').body.firstElementChild, new DOMParser().parseFromString('<html><body writingsuggestions=""><div writingsuggestions="false"></div></body></html>', 'text/html').body.firstElementChild, - new DOMParser().parseFromString('<html><body writingsuggestions=""><span writingsuggestions="false"></span></body></html>', 'text/html').body.firstElementChild ]; + new DOMParser().parseFromString('<html><body writingsuggestions=""><span writingsuggestions="false"></span></body></html>', 'text/html').body.firstElementChild, + new DOMParser().parseFromString('<html><body writingsuggestions=""><input type="color" writingsuggestions="false"/></body></html>', 'text/html').body.firstElementChild, + new DOMParser().parseFromString('<html><body writingsuggestions=""><textarea disabled writingsuggestions="false"></textarea></body></html>', 'text/html').body.firstElementChild ]; elements.forEach(function(element) { assert_equals(element.parentElement.writingSuggestions, 'true'); @@ -194,7 +228,9 @@ test(function() { const elements = [ new DOMParser().parseFromString('<html><body writingsuggestions="false"><input writingsuggestions="true" /></body></html>', 'text/html').body.firstElementChild, new DOMParser().parseFromString('<html><body writingsuggestions="false"><textarea writingsuggestions="true"></textarea></body></html>', 'text/html').body.firstElementChild, new DOMParser().parseFromString('<html><body writingsuggestions="false"><div writingsuggestions="true"></div></body></html>', 'text/html').body.firstElementChild, - new DOMParser().parseFromString('<html><body writingsuggestions="false"><span writingsuggestions="true"></span></body></html>', 'text/html').body.firstElementChild ]; + new DOMParser().parseFromString('<html><body writingsuggestions="false"><span writingsuggestions="true"></span></body></html>', 'text/html').body.firstElementChild, + new DOMParser().parseFromString('<html><body writingsuggestions="false"><input type="color" writingsuggestions="true"/></body></html>', 'text/html').body.firstElementChild, + new DOMParser().parseFromString('<html><body writingsuggestions="false"><textarea disabled writingsuggestions="true"></textarea></body></html>', 'text/html').body.firstElementChild, ]; elements.forEach(function(element) { assert_equals(element.parentElement.writingSuggestions, 'false'); @@ -208,7 +244,9 @@ test(function() { const elements = [ new DOMParser().parseFromString('<html><body writingsuggestions="false"><input writingsuggestions="foo" /></body></html>', 'text/html').body.firstElementChild, new DOMParser().parseFromString('<html><body writingsuggestions="false"><textarea writingsuggestions="foo"></textarea></body></html>', 'text/html').body.firstElementChild, new DOMParser().parseFromString('<html><body writingsuggestions="false"><div writingsuggestions="foo"></div></body></html>', 'text/html').body.firstElementChild, - new DOMParser().parseFromString('<html><body writingsuggestions="false"><span writingsuggestions="foo"></span></body></html>', 'text/html').body.firstElementChild ]; + new DOMParser().parseFromString('<html><body writingsuggestions="false"><span writingsuggestions="foo"></span></body></html>', 'text/html').body.firstElementChild, + new DOMParser().parseFromString('<html><body writingsuggestions="false"><input type="color" writingsuggestions="foo"/></body></html>', 'text/html').body.firstElementChild, + new DOMParser().parseFromString('<html><body writingsuggestions="false"><textarea disabled writingsuggestions="foo"></textarea></body></html>', 'text/html').body.firstElementChild ]; elements.forEach(function(element) { assert_equals(element.parentElement.writingSuggestions, 'false'); @@ -222,7 +260,9 @@ test(function() { const elements = [ new DOMParser().parseFromString('<html><body writingsuggestions="false"><input writingsuggestions="" /></body></html>', 'text/html').body.firstElementChild, new DOMParser().parseFromString('<html><body writingsuggestions="false"><textarea writingsuggestions=""></textarea></body></html>', 'text/html').body.firstElementChild, new DOMParser().parseFromString('<html><body writingsuggestions="false"><div writingsuggestions=""></div></body></html>', 'text/html').body.firstElementChild, - new DOMParser().parseFromString('<html><body writingsuggestions="false"><span writingsuggestions=""></span></body></html>', 'text/html').body.firstElementChild ]; + new DOMParser().parseFromString('<html><body writingsuggestions="false"><span writingsuggestions=""></span></body></html>', 'text/html').body.firstElementChild, + new DOMParser().parseFromString('<html><body writingsuggestions="false"><input type="color" writingsuggestions=""/></body></html>', 'text/html').body.firstElementChild, + new DOMParser().parseFromString('<html><body writingsuggestions="false"><textarea disabled writingsuggestions=""></textarea></body></html>', 'text/html').body.firstElementChild ]; elements.forEach(function(element) { assert_equals(element.parentElement.writingSuggestions, 'false'); @@ -233,13 +273,15 @@ test(function() { }, 'Test overriding the parent element\'s `writingsuggestions` attribute from "false" to the empty string.'); test(function() { - const doc = new DOMParser().parseFromString('<html writingsuggestions="false"><body><input /><textarea></textarea><div></div><span></span></body></html>', 'text/html'); + const doc = new DOMParser().parseFromString('<html writingsuggestions="false"><body><input /><textarea></textarea><div></div><span></span><input type="color"/><textarea disabled></textarea></body></html>', 'text/html'); assert_equals(doc.documentElement.writingSuggestions, 'false'); assert_equals(doc.body.writingSuggestions, 'false'); - assert_equals(doc.querySelector('input').writingSuggestions, 'false'); - assert_equals(doc.querySelector('textarea').writingSuggestions, 'false'); + assert_equals(doc.querySelectorAll('input')[0].writingSuggestions, 'false'); + assert_equals(doc.querySelectorAll('textarea')[0].writingSuggestions, 'false'); assert_equals(doc.querySelector('div').writingSuggestions, 'false'); assert_equals(doc.querySelector('span').writingSuggestions, 'false'); + assert_equals(doc.querySelectorAll('input')[1].writingSuggestions, 'false'); + assert_equals(doc.querySelectorAll('textarea')[1].writingSuggestions, 'false'); }, 'Test turning off writing suggestions for an entire document.'); test(function() { @@ -283,6 +325,26 @@ test(function() { }, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on a span element from "false" to "true".'); test(function() { + const doc = new DOMParser().parseFromString('<html writingsuggestions="false"><body><input type="color" writingsuggestions="true"><textarea></textarea><div></div><span></span></body></html>', 'text/html'); + assert_equals(doc.documentElement.writingSuggestions, 'false'); + assert_equals(doc.body.writingSuggestions, 'false'); + assert_equals(doc.querySelector('input').writingSuggestions, 'true'); + assert_equals(doc.querySelector('textarea').writingSuggestions, 'false'); + assert_equals(doc.querySelector('div').writingSuggestions, 'false'); + assert_equals(doc.querySelector('span').writingSuggestions, 'false'); +}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on an input type which the attribute doesn\'t apply from "false" to "true". The User Agent is responsible that writing suggestions are not applied to the element'); + +test(function() { + const doc = new DOMParser().parseFromString('<html writingsuggestions="false"><body><input><textarea disabled writingsuggestions="true"></textarea><div></div><span></span></body></html>', 'text/html'); + assert_equals(doc.documentElement.writingSuggestions, 'false'); + assert_equals(doc.body.writingSuggestions, 'false'); + assert_equals(doc.querySelector('input').writingSuggestions, 'false'); + assert_equals(doc.querySelector('textarea').writingSuggestions, 'true'); + assert_equals(doc.querySelector('div').writingSuggestions, 'false'); + assert_equals(doc.querySelector('span').writingSuggestions, 'false'); +}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on a disabled textarea element from "false" to "true". The User Agent is responsible that writing suggestions are not applied to the element'); + +test(function() { const doc = new DOMParser().parseFromString('<html writingsuggestions="false"><body><input writingsuggestions=""><textarea></textarea><div></div><span></span></body></html>', 'text/html'); assert_equals(doc.documentElement.writingSuggestions, 'false'); assert_equals(doc.body.writingSuggestions, 'false'); @@ -323,6 +385,26 @@ test(function() { }, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on a span element from "false" to the empty string.'); test(function() { + const doc = new DOMParser().parseFromString('<html writingsuggestions="false"><body><input type="color" writingsuggestions=""><textarea></textarea><div></div><span></span></body></html>', 'text/html'); + assert_equals(doc.documentElement.writingSuggestions, 'false'); + assert_equals(doc.body.writingSuggestions, 'false'); + assert_equals(doc.querySelector('input').writingSuggestions, 'true'); + assert_equals(doc.querySelector('textarea').writingSuggestions, 'false'); + assert_equals(doc.querySelector('div').writingSuggestions, 'false'); + assert_equals(doc.querySelector('span').writingSuggestions, 'false'); +}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on an input type which the attribute doesn\'t apply from "false" to the empty string. The User Agent is responsible that writing suggestions are not applied to the element.'); + +test(function() { + const doc = new DOMParser().parseFromString('<html writingsuggestions="false"><body><input><textarea disabled writingsuggestions=""></textarea><div></div><span></span></body></html>', 'text/html'); + assert_equals(doc.documentElement.writingSuggestions, 'false'); + assert_equals(doc.body.writingSuggestions, 'false'); + assert_equals(doc.querySelector('input').writingSuggestions, 'false'); + assert_equals(doc.querySelector('textarea').writingSuggestions, 'true'); + assert_equals(doc.querySelector('div').writingSuggestions, 'false'); + assert_equals(doc.querySelector('span').writingSuggestions, 'false'); +}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on a disabled textarea element from "false" to the empty string. The User Agent is responsible that writing suggestions are not applied to the element.'); + +test(function() { const doc = new DOMParser().parseFromString('<html writingsuggestions="false"><body><input writingsuggestions="foo"><textarea></textarea><div></div><span></span></body></html>', 'text/html'); assert_equals(doc.documentElement.writingSuggestions, 'false'); assert_equals(doc.body.writingSuggestions, 'false'); @@ -363,6 +445,26 @@ test(function() { }, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on a span element from "false" to an invalid value.'); test(function() { + const doc = new DOMParser().parseFromString('<html writingsuggestions="false"><body><input type="color" writingsuggestions="foo"><textarea></textarea><div></div><span></span></body></html>', 'text/html'); + assert_equals(doc.documentElement.writingSuggestions, 'false'); + assert_equals(doc.body.writingSuggestions, 'false'); + assert_equals(doc.querySelector('input').writingSuggestions, 'true'); + assert_equals(doc.querySelector('textarea').writingSuggestions, 'false'); + assert_equals(doc.querySelector('div').writingSuggestions, 'false'); + assert_equals(doc.querySelector('span').writingSuggestions, 'false'); +}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on an input type which the attribute doesn\'t apply from "false" to an invalid value. The User Agent is responsible that writing suggestions are not applied to the element.'); + +test(function() { + const doc = new DOMParser().parseFromString('<html writingsuggestions="false"><body><input><textarea disabled writingsuggestions="foo"></textarea><div></div><span></span></body></html>', 'text/html'); + assert_equals(doc.documentElement.writingSuggestions, 'false'); + assert_equals(doc.body.writingSuggestions, 'false'); + assert_equals(doc.querySelector('input').writingSuggestions, 'false'); + assert_equals(doc.querySelector('textarea').writingSuggestions, 'true'); + assert_equals(doc.querySelector('div').writingSuggestions, 'false'); + assert_equals(doc.querySelector('span').writingSuggestions, 'false'); +}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on a disabled textarea element from "false" to an invalid value. The User Agent is responsible that writing suggestions are not applied to the element.'); + +test(function() { const doc = new DOMParser().parseFromString('<html writingsuggestions="true"><body><input writingsuggestions="false"><textarea></textarea><div></div><span></span></body></html>', 'text/html'); assert_equals(doc.documentElement.writingSuggestions, 'true'); assert_equals(doc.body.writingSuggestions, 'true'); @@ -403,6 +505,26 @@ test(function() { }, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on a span element from "true" to "false".'); test(function() { + const doc = new DOMParser().parseFromString('<html writingsuggestions="true"><body><input type="color" writingsuggestions="false"><textarea></textarea><div></div><span></span></body></html>', 'text/html'); + assert_equals(doc.documentElement.writingSuggestions, 'true'); + assert_equals(doc.body.writingSuggestions, 'true'); + assert_equals(doc.querySelector('input').writingSuggestions, 'false'); + assert_equals(doc.querySelector('textarea').writingSuggestions, 'true'); + assert_equals(doc.querySelector('div').writingSuggestions, 'true'); + assert_equals(doc.querySelector('span').writingSuggestions, 'true'); +}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on an input type which the attribute doesn\'t apply from "true" to "false". The User Agent is responsible that writing suggestions are not applied to the element.'); + +test(function() { + const doc = new DOMParser().parseFromString('<html writingsuggestions="true"><body><input><textarea disabled writingsuggestions="false"></textarea><div></div><span></span></body></html>', 'text/html'); + assert_equals(doc.documentElement.writingSuggestions, 'true'); + assert_equals(doc.body.writingSuggestions, 'true'); + assert_equals(doc.querySelector('input').writingSuggestions, 'true'); + assert_equals(doc.querySelector('textarea').writingSuggestions, 'false'); + assert_equals(doc.querySelector('div').writingSuggestions, 'true'); + assert_equals(doc.querySelector('span').writingSuggestions, 'true'); +}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on a disabled textarea element from "true" to "false". The User Agent is responsible that writing suggestions are not applied to the element.'); + +test(function() { const doc = new DOMParser().parseFromString('<html writingsuggestions=""><body><input writingsuggestions="false"><textarea></textarea><div></div><span></span></body></html>', 'text/html'); assert_equals(doc.documentElement.writingSuggestions, 'true'); assert_equals(doc.body.writingSuggestions, 'true'); @@ -443,6 +565,26 @@ test(function() { }, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on a span element from the empty string to "false".'); test(function() { + const doc = new DOMParser().parseFromString('<html writingsuggestions=""><body><input type="color" writingsuggestions="false"><textarea></textarea><div></div><span></span></body></html>', 'text/html'); + assert_equals(doc.documentElement.writingSuggestions, 'true'); + assert_equals(doc.body.writingSuggestions, 'true'); + assert_equals(doc.querySelector('input').writingSuggestions, 'false'); + assert_equals(doc.querySelector('textarea').writingSuggestions, 'true'); + assert_equals(doc.querySelector('div').writingSuggestions, 'true'); + assert_equals(doc.querySelector('span').writingSuggestions, 'true'); +}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on an input type which the attribute doesn\'t apply from the empty string to "false". The User Agent is responsible that writing suggestions are not applied to the element.'); + +test(function() { + const doc = new DOMParser().parseFromString('<html writingsuggestions=""><body><input><textarea disabled writingsuggestions="false"></textarea><div></div><span></span></body></html>', 'text/html'); + assert_equals(doc.documentElement.writingSuggestions, 'true'); + assert_equals(doc.body.writingSuggestions, 'true'); + assert_equals(doc.querySelector('input').writingSuggestions, 'true'); + assert_equals(doc.querySelector('textarea').writingSuggestions, 'false'); + assert_equals(doc.querySelector('div').writingSuggestions, 'true'); + assert_equals(doc.querySelector('span').writingSuggestions, 'true'); +}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on a disabled textarea element from the empty string to "false". The User Agent is responsible that writing suggestions are not applied to the element.'); + +test(function() { const doc = new DOMParser().parseFromString('<html writingsuggestions="true"><body><div contenteditable="true"><span>Writing suggestions allowed.</span> <span writingsuggestions="false">Writing suggestions not allowed.</span></div></body></html>', 'text/html'); const div = doc.querySelector('div'); const span1 = doc.querySelector('span'); diff --git a/testing/web-platform/tests/html/rendering/bidi-rendering/unicode-bidi-ua-rules.html b/testing/web-platform/tests/html/rendering/bidi-rendering/unicode-bidi-ua-rules.html index 78bfb80e6f..00f4c96317 100644 --- a/testing/web-platform/tests/html/rendering/bidi-rendering/unicode-bidi-ua-rules.html +++ b/testing/web-platform/tests/html/rendering/bidi-rendering/unicode-bidi-ua-rules.html @@ -4,22 +4,104 @@ <link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#bidi-rendering"> <script src=/resources/testharness.js></script> <script src=/resources/testharnessreport.js></script> +<script src='../../resources/common.js'></script> <body> <script> - const elements = ['address', 'blockquote', 'center', 'div', 'figure', + function getUnicodeBidi(el) { + return window.getComputedStyle(el, "").unicodeBidi; + } + + // These elements should have `unicode-bidi: isolate` in the UA stylesheet: + const isolateElements = ['address', 'blockquote', 'center', 'div', 'figure', 'figcaption', 'footer', 'form', 'header', 'hr', 'legend', 'listing', 'main', 'p', 'plaintext', 'pre', 'summary', 'xmp', 'article', 'aside', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hgroup', 'nav', 'section', 'search', 'table', 'caption', 'colgroup', 'col', 'thead', 'tbody', 'tfoot', 'tr', 'td', 'th', 'dir', 'dd', 'dl', 'dt', 'menu', 'ol', 'ul', 'li', 'bdi', 'output']; - for(let tagname of elements) { + const allButSeparateTests = HTML5_ELEMENTS.filter(el => (!['bdo','input','textarea','pre'].includes(el))); + for(let tagname of allButSeparateTests) { + test((t) => { + const element = document.createElement(tagname); + t.add_cleanup(() => element.remove()); + document.body.appendChild(element); + const expectation = isolateElements.includes(tagname) ? 'isolate' : 'normal'; + assert_equals(getUnicodeBidi(element),expectation); + + element.setAttribute('dir','ltr'); + assert_equals(getUnicodeBidi(element),'isolate','with dir=ltr'); + element.setAttribute('dir','LtR'); + assert_equals(getUnicodeBidi(element),'isolate','with dir=LtR (case insensitive)'); + element.setAttribute('dir','rtl'); + assert_equals(getUnicodeBidi(element),'isolate','with dir=rtl'); + element.setAttribute('dir','auto'); + assert_equals(getUnicodeBidi(element),'isolate','with dir=auto'); + element.setAttribute('dir','INVALID'); + assert_equals(getUnicodeBidi(element),expectation,'invalid dir value goes back to normal defaults'); + },`UA stylesheet rule for unicode-bidi, for <${tagname}>`); + } + + test((t) => { + const element = document.createElement('bdo'); + t.add_cleanup(() => element.remove()); + document.body.appendChild(element); + assert_equals(getUnicodeBidi(element),'isolate-override'); + element.setAttribute('dir','ltr'); + assert_equals(getUnicodeBidi(element),'isolate-override','with dir=ltr'); + element.setAttribute('dir','LtR'); + assert_equals(getUnicodeBidi(element),'isolate-override','with dir=LtR (case insensitive)'); + element.setAttribute('dir','rtl'); + assert_equals(getUnicodeBidi(element),'isolate-override','with dir=rtl'); + element.setAttribute('dir','auto'); + assert_equals(getUnicodeBidi(element),'isolate-override','with dir=auto'); + element.setAttribute('dir','INVALID'); + assert_equals(getUnicodeBidi(element),'isolate-override','invalid dir value'); + },`UA stylesheet rule for unicode-bidi, for <bdo>`); + + const shouldBePlaintext = ['search','tel','url','email']; + for(let type of HTML5_INPUT_TYPES) { + test((t) => { + const element = document.createElement('input'); + t.add_cleanup(() => element.remove()); + element.type = type; + document.body.appendChild(element); + const autoExpectation = shouldBePlaintext.includes(type) ? 'plaintext' : 'isolate'; + assert_equals(getUnicodeBidi(element),'normal'); + element.setAttribute('dir','ltr'); + assert_equals(getUnicodeBidi(element),'isolate','with dir=ltr'); + element.setAttribute('dir','LtR'); + assert_equals(getUnicodeBidi(element),'isolate','with dir=LtR (case insensitive)'); + element.setAttribute('dir','rtl'); + assert_equals(getUnicodeBidi(element),'isolate','with dir=rtl'); + element.setAttribute('dir','auto'); + assert_equals(getUnicodeBidi(element),autoExpectation,'with dir=auto'); + element.setAttribute('dir','AuTo'); + assert_equals(getUnicodeBidi(element),autoExpectation,'with dir=auto (case insensitive)'); + element.setAttribute('dir','INVALID'); + assert_equals(getUnicodeBidi(element),'normal','invalid dir value'); + },`UA stylesheet rule for unicode-bidi, for <input type=${type}>`); + } + + for(let tagname of ['textarea','pre']) { test((t) => { const element = document.createElement(tagname); t.add_cleanup(() => element.remove()); document.body.appendChild(element); - assert_equals(window.getComputedStyle(element, "").unicodeBidi,'isolate'); + const expectation = tagname === 'textarea' ? 'normal' : 'isolate'; + assert_equals(getUnicodeBidi(element),expectation); + element.setAttribute('dir','ltr'); + assert_equals(getUnicodeBidi(element),'isolate','with dir=ltr'); + element.setAttribute('dir','LtR'); + assert_equals(getUnicodeBidi(element),'isolate','with dir=LtR (case insensitive)'); + element.setAttribute('dir','rtl'); + assert_equals(getUnicodeBidi(element),'isolate','with dir=rtl'); + element.setAttribute('dir','auto'); + assert_equals(getUnicodeBidi(element),'plaintext','with dir=auto'); + element.setAttribute('dir','AuTo'); + assert_equals(getUnicodeBidi(element),'plaintext','with dir=auto (case insensitive)'); + element.setAttribute('dir','INVALID'); + assert_equals(getUnicodeBidi(element),expectation,'invalid dir value'); },`UA stylesheet rule for unicode-bidi, for <${tagname}>`); } </script> diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/sections-and-headings/headings-styles-no-h1-in-section.tentative.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/sections-and-headings/headings-styles-no-h1-in-section.tentative.html new file mode 100644 index 0000000000..61610c2fd6 --- /dev/null +++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/sections-and-headings/headings-styles-no-h1-in-section.tentative.html @@ -0,0 +1,147 @@ +<!doctype html> +<title>default styles for h1..h6, hgroup, article, aside, nav, section (no h1 in section UA styles)</title> +<meta name="viewport" content="width=device-width"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/html/rendering/support/test-ua-stylesheet.js"></script> +<link rel="help" href="https://github.com/whatwg/html/issues/7867"> +<style> +/* Specify this bogus namespace, so the rules in this stylesheet only apply to the `fakeClone`d elements in #refs, not the HTML elements in #tests. */ +@namespace url(urn:not-html); + +article, aside, h1, h2, h3, h4, h5, h6, hgroup, nav, section { + display: block; +} + +h1 { margin-block: 0.67em; font-size: 2.00em; font-weight: bold; } +h2 { margin-block: 0.83em; font-size: 1.50em; font-weight: bold; } +h3 { margin-block: 1.00em; font-size: 1.17em; font-weight: bold; } +h4 { margin-block: 1.33em; font-size: 1.00em; font-weight: bold; } +h5 { margin-block: 1.67em; font-size: 0.83em; font-weight: bold; } +h6 { margin-block: 2.33em; font-size: 0.67em; font-weight: bold; } + +</style> + +<div id="log"></div> + +<div id="tests"> + <h1></h1> + <h2></h2> + <h3></h3> + <h4></h4> + <h5></h5> + <h6></h6> + <hgroup></hgroup> + <article></article> + <aside></aside> + <nav></nav> + <section></section> + <article data-skip> + <h1></h1> + <article data-skip> + <h1></h1> + <article data-skip> + <h1></h1> + <article data-skip> + <h1></h1> + <article data-skip> + <h1></h1> + <hgroup data-skip> + <h1></h1> + <h2></h2> + <h3></h3> + <h4></h4> + <h5></h5> + </hgroup> + </article> + </article> + </article> + </article> + </article> + <aside data-skip> + <h1></h1> + <aside data-skip> + <h1></h1> + <aside data-skip> + <h1></h1> + <aside data-skip> + <h1></h1> + <aside data-skip> + <h1></h1> + <hgroup data-skip> + <h1></h1> + <h2></h2> + <h3></h3> + <h4></h4> + <h5></h5> + </hgroup> + </aside> + </aside> + </aside> + </aside> + </aside> + <nav data-skip> + <h1></h1> + <nav data-skip> + <h1></h1> + <nav data-skip> + <h1></h1> + <nav data-skip> + <h1></h1> + <nav data-skip> + <h1></h1> + <hgroup data-skip> + <h1></h1> + <h2></h2> + <h3></h3> + <h4></h4> + <h5></h5> + </hgroup> + </nav> + </nav> + </nav> + </nav> + </nav> + <section data-skip> + <h1></h1> + <section data-skip> + <h1></h1> + <section data-skip> + <h1></h1> + <section data-skip> + <h1></h1> + <section data-skip> + <h1></h1> + <hgroup data-skip> + <h1></h1> + <h2></h2> + <h3></h3> + <h4></h4> + <h5></h5> + </hgroup> + </section> + </section> + </section> + </section> + </section> +</div> + +<div id="refs"></div> + +<script> + const props = [ + 'display', + 'margin-top', + 'margin-right', + 'margin-bottom', + 'margin-left', + 'padding-top', + 'padding-right', + 'padding-bottom', + 'padding-left', + 'font-size', + 'font-weight', + ]; + runUAStyleTests(props); + +</script> diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/sections-and-headings/headings-styles.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/sections-and-headings/headings-styles.html index 63e6a83e88..be531adfcf 100644 --- a/testing/web-platform/tests/html/rendering/non-replaced-elements/sections-and-headings/headings-styles.html +++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/sections-and-headings/headings-styles.html @@ -12,18 +12,18 @@ article, aside, h1, h2, h3, h4, h5, h6, hgroup, nav, section { display: block; } -h1 { margin-block-start: 0.67em; margin-block-end: 0.67em; font-size: 2.00em; font-weight: bold; } -h2 { margin-block-start: 0.83em; margin-block-end: 0.83em; font-size: 1.50em; font-weight: bold; } -h3 { margin-block-start: 1.00em; margin-block-end: 1.00em; font-size: 1.17em; font-weight: bold; } -h4 { margin-block-start: 1.33em; margin-block-end: 1.33em; font-size: 1.00em; font-weight: bold; } -h5 { margin-block-start: 1.67em; margin-block-end: 1.67em; font-size: 0.83em; font-weight: bold; } -h6 { margin-block-start: 2.33em; margin-block-end: 2.33em; font-size: 0.67em; font-weight: bold; } +h1 { margin-block: 0.67em; font-size: 2.00em; font-weight: bold; } +h2 { margin-block: 0.83em; font-size: 1.50em; font-weight: bold; } +h3 { margin-block: 1.00em; font-size: 1.17em; font-weight: bold; } +h4 { margin-block: 1.33em; font-size: 1.00em; font-weight: bold; } +h5 { margin-block: 1.67em; font-size: 0.83em; font-weight: bold; } +h6 { margin-block: 2.33em; font-size: 0.67em; font-weight: bold; } -:is(article, aside, nav, section) h1 { margin-block-start: 0.83em; margin-block-end: 0.83em; font-size: 1.50em; } -:is(article, aside, nav, section) :is(article, aside, nav, section) h1 { margin-block-start: 1.00em; margin-block-end: 1.00em; font-size: 1.17em; } -:is(article, aside, nav, section) :is(article, aside, nav, section) :is(article, aside, nav, section) h1 { margin-block-start: 1.33em; margin-block-end: 1.33em; font-size: 1.00em; } -:is(article, aside, nav, section) :is(article, aside, nav, section) :is(article, aside, nav, section) :is(article, aside, nav, section) h1 { margin-block-start: 1.67em; margin-block-end: 1.67em; font-size: 0.83em; } -:is(article, aside, nav, section) :is(article, aside, nav, section) :is(article, aside, nav, section) :is(article, aside, nav, section) :is(article, aside, nav, section) h1 { margin-block-start: 2.33em; margin-block-end: 2.33em; font-size: 0.67em; } +:is(article, aside, nav, section) h1 { margin-block: 0.83em; font-size: 1.50em; } +:is(article, aside, nav, section) :is(article, aside, nav, section) h1 { margin-block: 1.00em; font-size: 1.17em; } +:is(article, aside, nav, section) :is(article, aside, nav, section) :is(article, aside, nav, section) h1 { margin-block: 1.33em; font-size: 1.00em; } +:is(article, aside, nav, section) :is(article, aside, nav, section) :is(article, aside, nav, section) :is(article, aside, nav, section) h1 { margin-block: 1.67em; font-size: 0.83em; } +:is(article, aside, nav, section) :is(article, aside, nav, section) :is(article, aside, nav, section) :is(article, aside, nav, section) :is(article, aside, nav, section) h1 { margin-block: 2.33em; font-size: 0.67em; } </style> diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow.html index 83813f9020..089b0d9300 100644 --- a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow.html +++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow.html @@ -1,5 +1,6 @@ <!DOCTYPE HTML> <title>fieldset overflow</title> +<meta name="fuzzy" content="1;0-50"> <link rel=match href=fieldset-overflow-ref.html> <style> fieldset, legend { diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-button-min-height-001-ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-button-min-height-001-ref.html new file mode 100644 index 0000000000..c35ad5fc42 --- /dev/null +++ b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-button-min-height-001-ref.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Test Reference</title> +<style> + select, input, button { height: 100px; } +</style> +<div> + <select><option>Select</option></select> + <button>Button</button> + <input type="button" value="Input"> +</div> diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-button-min-height-001.html b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-button-min-height-001.html new file mode 100644 index 0000000000..c099105076 --- /dev/null +++ b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-button-min-height-001.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>min-height and height both trigger same rendering for select and buttons by default</title> +<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io"> +<link rel="author" title="Mozilla" href="https://mozilla.org"> +<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1362907"> +<link rel="match" href="select-button-min-height-001-ref.html"> +<style> + select, input, button { min-height: 100px; } +</style> +<div> + <select><option>Select</option></select> + <button>Button</button> + <input type="button" value="Input"> +</div> diff --git a/testing/web-platform/tests/html/rendering/widgets/field-sizing-textarea.html b/testing/web-platform/tests/html/rendering/widgets/field-sizing-textarea.html index f8d90dc659..114d60c72d 100644 --- a/testing/web-platform/tests/html/rendering/widgets/field-sizing-textarea.html +++ b/testing/web-platform/tests/html/rendering/widgets/field-sizing-textarea.html @@ -3,6 +3,10 @@ <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <style> +textarea { + font-family: monospace; +} + .disable-default { field-sizing: content; } diff --git a/testing/web-platform/tests/html/resources/common.js b/testing/web-platform/tests/html/resources/common.js index 4f9ec54dde..fd4529e80a 100644 --- a/testing/web-platform/tests/html/resources/common.js +++ b/testing/web-platform/tests/html/resources/common.js @@ -49,6 +49,12 @@ const HTML5_DEPRECATED_ELEMENTS = [ 'rtc', 'shadow', 'spacer', 'strike', 'tt', 'xmp' ]; +const HTML5_INPUT_TYPES = [ + 'hidden', 'text', 'search', 'tel', 'url', 'email', 'password', 'date', + 'time', 'datetime-local', 'number', 'range', 'color', 'checkbox', 'radio', + 'file', 'submit', 'image', 'reset', 'button' +]; + function newDocument() { var d = document.implementation.createDocument(); return d; diff --git a/testing/web-platform/tests/html/semantics/disabled-elements/event-propagate-disabled.tentative.html b/testing/web-platform/tests/html/semantics/disabled-elements/event-propagate-disabled.tentative.html index e3dcd43a17..2be6dc72fe 100644 --- a/testing/web-platform/tests/html/semantics/disabled-elements/event-propagate-disabled.tentative.html +++ b/testing/web-platform/tests/html/semantics/disabled-elements/event-propagate-disabled.tentative.html @@ -1,6 +1,7 @@ <!DOCTYPE html> <meta charset="utf8"> <meta name="timeout" content="long"> +<meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Event propagation on disabled form elements</title> <link rel="author" href="mailto:krosylight@mozilla.com"> <link rel="help" href="https://github.com/whatwg/html/issues/2368"> diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/resources/302-no-Location-header-text-css.asis b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/resources/302-no-Location-header-text-css.asis new file mode 100644 index 0000000000..ddf4898d3f --- /dev/null +++ b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/resources/302-no-Location-header-text-css.asis @@ -0,0 +1,4 @@ +HTTP/1.1 302 Found +Content-Type: text/css + +body { background-color: red; } diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/resources/stylesheet-bad-mime-type-empty.css b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/resources/stylesheet-bad-mime-type-empty.css new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/resources/stylesheet-bad-mime-type-empty.css diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/resources/stylesheet-bad-mime-type-empty.css.headers b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/resources/stylesheet-bad-mime-type-empty.css.headers new file mode 100644 index 0000000000..156209f9c8 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/resources/stylesheet-bad-mime-type-empty.css.headers @@ -0,0 +1 @@ +Content-Type: text/html diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/resources/stylesheet-bad-mime-type.css b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/resources/stylesheet-bad-mime-type.css new file mode 100644 index 0000000000..e1b2552ffe --- /dev/null +++ b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/resources/stylesheet-bad-mime-type.css @@ -0,0 +1,3 @@ +body { + background-color: green; +} diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/resources/stylesheet-bad-mime-type.css.headers b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/resources/stylesheet-bad-mime-type.css.headers new file mode 100644 index 0000000000..156209f9c8 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/resources/stylesheet-bad-mime-type.css.headers @@ -0,0 +1 @@ +Content-Type: text/html diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/stylesheet-bad-mime-type.html b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/stylesheet-bad-mime-type.html new file mode 100644 index 0000000000..08176d6cd2 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/stylesheet-bad-mime-type.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>stylesheets served with bad MIME types</title> +<link rel="author" title="Michael[tm] Smith" href="mailto:mike@w3.org"> +<link rel="help" href="https://html.spec.whatwg.org/#link-type-stylesheet:process-the-linked-resource"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + async_test((t) => { + const link = document.createElement("link"); + link.rel = "stylesheet"; + link.href = "resources/stylesheet-bad-mime-type.css"; + link.onload = t.unreached_func(); + link.onerror = t.step_func_done(); + document.head.append(link); + }, "'load' event does not fire at link@rel=stylesheet having non-empty resource with bad MIME type"); + async_test((t) => { + t.step_timeout(() => { + const link = document.createElement("link"); + link.rel = "stylesheet"; + link.href = "resources/stylesheet-bad-mime-type-empty.css"; + link.onload = t.unreached_func(); + link.onerror = t.step_func_done(); + document.head.append(link); + }, 2000); + }, "'load' event does not fire at link@rel=stylesheet having empty resource with bad MIME type"); +</script> diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/stylesheet-non-OK-status.html b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/stylesheet-non-OK-status.html new file mode 100644 index 0000000000..28ac55ff1a --- /dev/null +++ b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/stylesheet-non-OK-status.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>stylesheet served with non-OK status</title> +<link rel="author" title="Michael[tm] Smith" href="mailto:mike@w3.org"> +<link rel="help" href="https://html.spec.whatwg.org/#fetching-and-processing-a-resource-from-a-link-element:processresponseconsumebody"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + async_test((t) => { + const link = document.createElement("link"); + link.rel = "stylesheet"; + link.href = "resources/302-no-Location-header-text-css.asis"; + link.onload = t.unreached_func(); + link.onerror = t.step_func_done(); + document.head.append(link); + }, "'load' event does not fire at link@rel=stylesheet having resource with non-OK response status"); +</script> diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/offsets-into-the-media-resource/currentTime-move-within-document.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/offsets-into-the-media-resource/currentTime-move-within-document.html new file mode 100644 index 0000000000..22b579d720 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/offsets-into-the-media-resource/currentTime-move-within-document.html @@ -0,0 +1,31 @@ +<!doctype html> +<title>playback should not reset when moving within a document</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/media.js"></script> +<div id="log"></div> +<video autoplay muted hidden></video> +<div id="elsewhere"></div> +<script> +async_test(t => { + const v = document.querySelector('video'); + v.src = getVideoURI('/media/movie_300'); + v.currentTime = 0; + v.onplaying = t.step_func(() => { + v.currentTime = 10; + t.step_timeout(() => { + assert_greater_than_equal(v.currentTime, 10); + document.getElementById('elsewhere').appendChild(v); + assert_false(v.paused, 'paused after moving'); + assert_greater_than_equal(v.currentTime, 10); + t.step_timeout(() => { + assert_greater_than_equal(v.currentTime, 10); + t.done(); + }, 0); + }, 0); + + }); + v.play(); + v.onpause = t.step_func(function() { assert_unreached(); }); +}); +</script> diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-nested-2.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-nested-2.html index d080831175..9eec621c89 100644 --- a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-nested-2.html +++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-nested-2.html @@ -31,7 +31,7 @@ <div id=scroller2> <div id="spacer"></div> <div id="scroller"> - <iframe> + <iframe id="target" src="resources/subframe.html" loading="lazy" diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_navigation_download_allow_downloads.sub.tentative.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_navigation_download_allow_downloads.sub.tentative.https.html index 6b3b3104ef..6b3b3104ef 100644 --- a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_navigation_download_allow_downloads.sub.tentative.html +++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_navigation_download_allow_downloads.sub.tentative.https.html diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_window_open_download_allow_downloads.tentative.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_window_open_download_allow_downloads.tentative.https.html index 158fc4f947..158fc4f947 100644 --- a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_window_open_download_allow_downloads.tentative.html +++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_window_open_download_allow_downloads.tentative.https.html diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/resources/sandbox-top-navigation-helper.js b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/resources/sandbox-top-navigation-helper.sub.js index 413f392dfc..bec8f6a64a 100644 --- a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/resources/sandbox-top-navigation-helper.js +++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/resources/sandbox-top-navigation-helper.sub.js @@ -5,7 +5,7 @@ // // META: script=/resources/testdriver.js // // META: script=/resources/testdriver-vendor.js // // META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js -// // META: script=./resources/sandbox-top-navigation-helper.js +// // META: script=./resources/sandbox-top-navigation-helper.sub.js // Helper file that provides various functions to test top-level navigation // with various frame and sandbox flag configurations. @@ -27,18 +27,28 @@ async function createNestedIframe(parent, origin, frame_sandbox, header_sandbox) origin: origin, scripts: [ '/resources/testdriver.js', - '/resources/testdriver-driver.js', - '/resources/testdriver-vendor.js' + '/resources/testdriver-vendor.js', ], headers: headers, }, iframe_attributes); } +async function navigateFrameTo(frame, origin) { + return frame.navigateToNew({ + origin: origin, + scripts: [ + '/resources/testdriver.js', + '/resources/testdriver-vendor.js', + ], + }); +} + async function attemptTopNavigation(iframe, should_succeed) { let did_succeed; try { await iframe.executeScript(() => { - window.top.location.href = "https://google.com"; + window.top.location.href = + 'http://{{hosts[alt][www2]}}:{{ports[http][0]}}'; }); did_succeed = true; } catch (e) { diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/sandbox-top-navigation-child-cross-origin.tentative.sub.window.js b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/sandbox-top-navigation-child-cross-origin.tentative.sub.window.js new file mode 100644 index 0000000000..95d53e1fe3 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/sandbox-top-navigation-child-cross-origin.tentative.sub.window.js @@ -0,0 +1,28 @@ +// META: title=Top-level navigation tests with cross origin & user activated child frames +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/get-host-info.sub.js +// META: script=/common/utils.js +// META: script=/resources/testdriver.js +// META: script=/resources/testdriver-vendor.js +// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js +// META: script=./resources/sandbox-top-navigation-helper.sub.js + +'use strict'; + +// /* ---------------------- CROSS ORIGIN (A -> B) TESTS ---------------------- */ + +promise_test(async t => { + const main = await setupTest(); + const iframe_1 = await createNestedIframe(main, + "HTTP_REMOTE_ORIGIN", "allow-top-navigation", ""); + + await attemptTopNavigation(iframe_1, true); +}, "A cross-origin frame with frame sandbox flags can navigate top"); + +promise_test(async t => { + const main = await setupTest(); + const iframe_1 = await createNestedIframe(main, + "HTTP_REMOTE_ORIGIN", "", "allow-top-navigation"); + + await attemptTopNavigation(iframe_1, false); +}, "A cross-origin frame with delivered sandbox flags can not navigate top"); diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/sandbox-top-navigation-child.tentative.sub.window.js b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/sandbox-top-navigation-child.tentative.sub.window.js index 53faa99a40..1d5ea93830 100644 --- a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/sandbox-top-navigation-child.tentative.sub.window.js +++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/sandbox-top-navigation-child.tentative.sub.window.js @@ -5,7 +5,7 @@ // META: script=/resources/testdriver.js // META: script=/resources/testdriver-vendor.js // META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js -// META: script=./resources/sandbox-top-navigation-helper.js +// META: script=./resources/sandbox-top-navigation-helper.sub.js 'use strict'; diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/sandbox-top-navigation-cross-site.tentative.sub.window.js b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/sandbox-top-navigation-cross-site.tentative.sub.window.js new file mode 100644 index 0000000000..26db4eeaca --- /dev/null +++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/sandbox-top-navigation-cross-site.tentative.sub.window.js @@ -0,0 +1,43 @@ +// META: title=Top-level navigation tests with cross origin & user activated child frames +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/get-host-info.sub.js +// META: script=/common/utils.js +// META: script=/resources/testdriver.js +// META: script=/resources/testdriver-actions.js +// META: script=/resources/testdriver-vendor.js +// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js +// META: script=./resources/sandbox-top-navigation-helper.sub.js + +'use strict'; + +promise_test(async t => { + const main = await setupTest(); + + const iframe = await createNestedIframe(main, "HTTP_ORIGIN", "", ""); + await activate(iframe); + + const new_iframe = await navigateFrameTo(iframe, "HTTPS_REMOTE_ORIGIN"); + await attemptTopNavigation(new_iframe, false); +}, "A cross-site unsandboxed iframe navigation consumes user activation and " + + "disallows top-level navigation."); + +promise_test(async t => { + const main = await setupTest(); + + const iframe = await createNestedIframe(main, "HTTP_ORIGIN", "", ""); + await activate(iframe); + + const new_iframe = await navigateFrameTo(iframe, "HTTP_REMOTE_ORIGIN"); + await attemptTopNavigation(new_iframe, true); +}, "A same-site unsandboxed iframe navigation does not consume user " + + "activation and allows top-level navigation."); + +promise_test(async t => { + const main = await setupTest(); + + const iframe = await createNestedIframe(main, "HTTP_ORIGIN", "", ""); + + const new_iframe = await navigateFrameTo(iframe, "HTTP_REMOTE_ORIGIN"); + await attemptTopNavigation(new_iframe, false); +}, "A same-site unsandboxed iframe navigation without sticky user activation " + + "does not allow top-level navigation."); diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/sandbox-top-navigation-escalate-privileges.tentative.sub.window.js b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/sandbox-top-navigation-escalate-privileges.tentative.sub.window.js index a5cda9b0b9..2ea0ba606e 100644 --- a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/sandbox-top-navigation-escalate-privileges.tentative.sub.window.js +++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/sandbox-top-navigation-escalate-privileges.tentative.sub.window.js @@ -5,7 +5,7 @@ // META: script=/resources/testdriver.js // META: script=/resources/testdriver-vendor.js // META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js -// META: script=./resources/sandbox-top-navigation-helper.js +// META: script=./resources/sandbox-top-navigation-helper.sub.js 'use strict'; diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/sandbox-top-navigation-grandchild.tentative.sub.window.js b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/sandbox-top-navigation-grandchild.tentative.sub.window.js index a07148f802..326c1dd54a 100644 --- a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/sandbox-top-navigation-grandchild.tentative.sub.window.js +++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/sandbox-top-navigation-grandchild.tentative.sub.window.js @@ -5,7 +5,7 @@ // META: script=/resources/testdriver.js // META: script=/resources/testdriver-vendor.js // META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js -// META: script=./resources/sandbox-top-navigation-helper.js +// META: script=./resources/sandbox-top-navigation-helper.sub.js 'use strict'; diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/sandbox-top-navigation-child-special-cases.tentative.sub.window.js b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/sandbox-top-navigation-user-activation.tentative.sub.window.js index 8681411dd7..5079c8ad14 100644 --- a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/sandbox-top-navigation-child-special-cases.tentative.sub.window.js +++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/sandbox-top-navigation-user-activation.tentative.sub.window.js @@ -3,9 +3,10 @@ // META: script=/common/get-host-info.sub.js // META: script=/common/utils.js // META: script=/resources/testdriver.js +// META: script=/resources/testdriver-actions.js // META: script=/resources/testdriver-vendor.js // META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js -// META: script=./resources/sandbox-top-navigation-helper.js +// META: script=./resources/sandbox-top-navigation-helper.sub.js 'use strict'; @@ -27,21 +28,3 @@ promise_test(async t => { await attemptTopNavigation(iframe_1, false); }, "allow-top-navigation-by-user-activation set but no sticky activation"); - -/* ---------------------- CROSS ORIGIN (A -> B) TESTS ---------------------- */ - -promise_test(async t => { - const main = await setupTest(); - const iframe_1 = await createNestedIframe(main, - "HTTP_REMOTE_ORIGIN", "allow-top-navigation", ""); - - await attemptTopNavigation(iframe_1, true); -}, "A cross-origin frame with frame sandbox flags can navigate top"); - -promise_test(async t => { - const main = await setupTest(); - const iframe_1 = await createNestedIframe(main, - "HTTP_REMOTE_ORIGIN", "", "allow-top-navigation"); - - await attemptTopNavigation(iframe_1, false); -}, "A cross-origin frame with delivered sandbox flags can not navigate top"); diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/select-attribute-crash.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-attribute-crash.html new file mode 100644 index 0000000000..5330411a5d --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-attribute-crash.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html class=test-wait> +<link rel=author href="mailto:jarhar@chromium.org"> +<link rel=help href="https://issues.chromium.org/324325525"> + +<!-- Attempting to slot a child of <select> after initial slot assignment should not crash. --> + +<select size=1> + <optgroup></optgroup> +</select> +<script> +requestAnimationFrame(() => { + document.querySelector('optgroup').setAttribute('slot', 'slot1'); + requestAnimationFrame(() => { + document.documentElement.classList.remove('test-wait'); + }); +}); +</script> diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/select-child-button-and-datalist-invalidation.tentative.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-child-button-and-datalist-invalidation.tentative.html new file mode 100644 index 0000000000..f71c1e52fc --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-child-button-and-datalist-invalidation.tentative.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html class=reftest-wait> +<link rel=author href="mailto:jarhar@chromium.org"> +<link rel=help href="https://github.com/whatwg/html/issues/9799"> +<link rel=match href="select-child-button-and-datalist-ref.html"> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> + +<select> + <button type=popover>button</button> + <datalist> + <option>one</option> + <option>two</option> + </datalist> +</select> + +<script> +requestAnimationFrame(() => { + document.querySelector('select').style = 'appearance:bikeshed'; + document.querySelector('button').click(); + document.documentElement.classList.remove('reftest-wait'); +}); +</script> diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/select-child-button-and-datalist.tentative.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-child-button-and-datalist.tentative.html index b74957feed..54785ace95 100644 --- a/testing/web-platform/tests/html/semantics/forms/the-select-element/select-child-button-and-datalist.tentative.html +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-child-button-and-datalist.tentative.html @@ -5,7 +5,7 @@ <script src="/resources/testdriver.js"></script> <script src="/resources/testdriver-vendor.js"></script> -<select> +<select style="appearance:bikeshed"> <button type=popover>button</button> <datalist> <option>one</option> diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/select-datalist-options-idl.tentative.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-datalist-options-idl.tentative.html new file mode 100644 index 0000000000..993f6e126c --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-datalist-options-idl.tentative.html @@ -0,0 +1,81 @@ +<!DOCTYPE html> +<link rel=author href="mailto:jarhar@chromium.org"> +<link rel=help href="https://github.com/whatwg/html/issues/9799"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<select> + <datalist> + <option class=one>one</option> + <div> + <option class=two>two</option> + </div> + <option class=three>three</option> + </datalist> +</select> + +<script> +const select = document.querySelector('select'); + +function runTest() { + const datalist = select.querySelector('datalist'); + const firstOption = select.querySelector('option.one'); + const secondOption = select.querySelector('option.two'); + const thirdOption = select.querySelector('option.three'); + const datalistChildDiv = datalist.querySelector('div'); + + let selectChildDiv = document.querySelector('select > div'); + if (!selectChildDiv) { + selectChildDiv = document.createElement('div'); + select.appendChild(selectChildDiv); + } + + assert_equals(select.length, 3, 'select.length'); + assert_equals(select.options.length, 3, 'select.options.length'); + assert_equals(select.options[0], firstOption, 'select.options[0]'); + assert_equals(select.options[1], secondOption, 'select.options[1]'); + assert_equals(select.options[2], thirdOption, 'select.options[2]'); + + assert_equals(select.value, 'one', 'initial select.value'); + select.value = 'two'; + assert_equals(select.value, 'two', 'select.value after modifying'); + + secondOption.remove(); + assert_equals(select.length, 2, 'select.length after removing an option'); + assert_equals(select.options.length, 2, 'select.options.length after removing an option'); + assert_equals(select.options[0], firstOption, 'select.options[0] after removing an option'); + assert_equals(select.options[1], thirdOption, 'select.options[1] after removing an option'); + + datalist.appendChild(secondOption); + assert_equals(select.length, 3, 'select.length after re-adding an option'); + assert_equals(select.options.length, 3, 'select.options.length after re-adding an option'); + assert_equals(select.options[0], firstOption, 'select.options[0] after re-adding an option'); + assert_equals(select.options[1], thirdOption, 'select.options[1] after re-adding an option'); + assert_equals(select.options[2], secondOption, 'select.options[2] after re-adding an option'); + + selectChildDiv.appendChild(secondOption); + assert_equals(select.length, 2, 'select.length after moving option to child div'); + assert_equals(select.options.length, 2, 'select.options.length after moving option to child div'); + assert_equals(select.options[0], firstOption, 'select.options[0] after moving option to child div'); + assert_equals(select.options[1], thirdOption, 'select.options[1] after moving option to child div'); + + // reset back to normal for the next test + datalistChildDiv.appendChild(secondOption); + select.value = 'one'; +} + +test(() => { + runTest(); +}, 'Option elements should work if they are a descendant of a selects datalist.'); + +test(() => { + select.setAttribute('multiple', ''); + runTest(); +}, 'Options in datalist should still work when the multiple attribute is added.'); + +test(() => { + select.innerHTML = select.innerHTML; + select.value = 'one'; + runTest(); +}, 'Options in datalist in multiple should work after re-parsing and re-attaching.'); +</script> diff --git a/testing/web-platform/tests/html/semantics/interactive-elements/the-dialog-element/dialog-canceling.html b/testing/web-platform/tests/html/semantics/interactive-elements/the-dialog-element/dialog-canceling.html index e368bde6fb..db757861e7 100644 --- a/testing/web-platform/tests/html/semantics/interactive-elements/the-dialog-element/dialog-canceling.html +++ b/testing/web-platform/tests/html/semantics/interactive-elements/the-dialog-element/dialog-canceling.html @@ -66,6 +66,7 @@ promise_test(async () => { event.preventDefault(); }); + await test_driver.bless(); bottomDialog.showModal(); await blessTopLayer(bottomDialog); topDialog.showModal(); diff --git a/testing/web-platform/tests/html/semantics/interactive-elements/the-dialog-element/dialog-open.html b/testing/web-platform/tests/html/semantics/interactive-elements/the-dialog-element/dialog-open.html index e1f4c6ab82..bcd6ebebc1 100644 --- a/testing/web-platform/tests/html/semantics/interactive-elements/the-dialog-element/dialog-open.html +++ b/testing/web-platform/tests/html/semantics/interactive-elements/the-dialog-element/dialog-open.html @@ -37,7 +37,9 @@ // close event is async, give it a chance to be fired t.step_timeout(function() { - t.done(); + requestAnimationFrame(() => { + t.done(); + }); }, 0); }, "On setting it to false, the close event should not be fired"); </script> diff --git a/testing/web-platform/tests/html/semantics/interactive-elements/the-summary-element/interactive-content.html b/testing/web-platform/tests/html/semantics/interactive-elements/the-summary-element/interactive-content.html new file mode 100644 index 0000000000..94869dc9b6 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/interactive-elements/the-summary-element/interactive-content.html @@ -0,0 +1,232 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>summary element: interactive content</title> +<link rel="author" title="Michael[tm] Smith" href="mailto:mike@w3.org"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/interactive-elements.html#the-summary-element"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> + +<details> + <summary id=summary> + <a id=a href="#">anchor element</a> + <svg style="width: 160px; height: 100px" viewBox="0 0 100 100"> + <a href="#" id="svg_a"><text id="svg_text" x="50" y="90" text-anchor="middle">SVG anchor element</text></a> + </svg> + <svg style="width: 100px; height: 200px" viewBox="0 0 100 100"> + <foreignObject x="0" y="60" width="100" height="200" text-anchor="middle"> + <a xmlns="http://www.w3.org/1999/xhtml" href="#" id="svg_foreignObject_a">SVG foreignObject with HTML anchor element</a> + </foreignObject> + </svg> + <audio id="audio" controls src=/media/sound_5.mp3></audio> + <button id=button>button element</button> + <embed id=embed src="/images/blue.png" height="100" width="100"> + <iframe id=iframe srcdoc="iframe element"></iframe> + <img id=img_usemap usemap src=/media/poster.png></img> + <img id=img src=/media/poster.png></img> + <input type="text" value="input@type=text" id="input_text"> + <input type="search" value="input@type=search" id="input_search"> + <input type="tel" value="input@type=tel" id="input_tel"> + <input type="url" value="input@type=url" id="input_url"> + <input type="email" value="input@type=email" id="input_email"> + <input type="password" value="input@type=password" id="input_password"> + <input type="button" value="input@type=button" id="input_button"> + <input type="reset" id="input_reset"> + <input type="submit" id="input_submit"> + <input type="date" value="input@type=date" id="input_date"> + <input type="month" value="input@type=month" id="input_month"> + <input type="week" value="input@type=week" id="input_week"> + <input type="time" id="input_time"> + <input type="datetime-local" id="input_datetime-local"> + <input type="color" id="input_color"> + <input type="number" value="1337" id="input_number"> + <input type="range" id="input_range"> + <input type="checkbox" id="input_checkbox"> + <input type="radio" id="input_radio" disabled> + <input type="file" id="input_file"> + <input type="image" id="input_image" src=/media/poster.png> + <label id=label style="display: block">label element</label> + <textarea value="textarea" id="textarea">textarea element</textarea> + <video id="video" controls> + <source src="/media/test-1s.mp4" type="video/mp4"> + <source src="/media/test-1s.webm" type="video/webm"> + </video> + <div id="non-interactive">This is clickable summary text</div> + </summary> +</details> + +<script> +const details = document.querySelector("details"); + +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("non-interactive")); + assert_true(details.open) +}, "Clicking on non-interactive child of a <summary> opens its <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("a")); + assert_false(details.open) +}, "Clicking an <a> link doesn't open <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("svg_a")); + assert_false(details.open) +}, "Clicking an SVG <a> link doesn't open <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("svg_foreignObject_a")); + assert_false(details.open) +}, "Clicking an HTML <a> link in an SVG <foreignObject> doesn't open <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("audio")); + assert_false(details.open) +}, "Clicking an <audio> element doesn't open <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("button")); + assert_false(details.open) +}, "Clicking a <button> doesn't open <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("embed")); + assert_false(details.open) +}, "Clicking the content of an <embed> doesn't open <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("iframe")); + assert_false(details.open) +}, "Clicking in an <iframe> doesn't open <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("img_usemap")); + assert_false(details.open) +}, "Clicking an <img> with a 'usemap' attribute doesn't open <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("img")); + assert_true(details.open) +}, "Clicking an <img> without a 'usemap' attribute opens <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("input_button")); + assert_false(details.open) +}, "Clicking an <input type=button> doesn't open <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("input_reset")); + assert_false(details.open) +}, "Clicking an <input type=reset> doesn't open <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("input_submit")); + assert_false(details.open) +}, "Clicking an <input type=submit> doesn't open <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("input_text")); + assert_false(details.open) +}, "Clicking an <input type=text> doesn't open <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("input_search")); + assert_false(details.open) +}, "Clicking an <input type=search> doesn't open <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("input_tel")); + assert_false(details.open) +}, "Clicking an <input type=tel> doesn't open <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("input_url")); + assert_false(details.open) +}, "Clicking an <input type=url> doesn't open <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("input_email")); + assert_false(details.open) +}, "Clicking an <input type=email> doesn't open <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("input_password")); + assert_false(details.open) +}, "Clicking an <input type=password> doesn't open <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("input_date")); + assert_false(details.open) +}, "Clicking an <input type=date> doesn't open <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("input_month")); + assert_false(details.open) +}, "Clicking an <input type=month> doesn't open <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("input_week")); + assert_false(details.open) +}, "Clicking an <input type=week> doesn't open <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("input_time")); + assert_false(details.open) +}, "Clicking an <input type=time> doesn't open <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("input_datetime-local")); + assert_false(details.open) +}, "Clicking an <input type=datetime-local> doesn't open <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("input_number")); + assert_false(details.open) +}, "Clicking an <input type=number> doesn't open <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("input_range")); + assert_false(details.open) +}, "Clicking an <input type=range> doesn't open <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("input_color")); + assert_false(details.open) +}, "Clicking an <input type=color> doesn't open <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("input_checkbox")); + assert_false(details.open) +}, "Clicking an <input type=checkbox> doesn't open <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("input_radio")); + assert_false(details.open) +}, "Clicking an <input type=radio> doesn't open <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("input_file")); + assert_false(details.open) +}, "Clicking an <input type=file> doesn't open <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("input_image")); + assert_false(details.open) +}, "Clicking an <input type=image> doesn't open <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("label")); + assert_false(details.open) +}, "Clicking a <label> doesn't open <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("textarea")); + assert_false(details.open) +}, "Clicking in a <textarea> doesn't open <details>"); +promise_test(async () => { + details.open = false; + await test_driver.click(document.getElementById("video")); + assert_false(details.open) +}, "Clicking a <video> doesn't open <details>"); +</script> diff --git a/testing/web-platform/tests/html/semantics/invokers/interestelement-interface.tentative.html b/testing/web-platform/tests/html/semantics/invokers/interestelement-interface.tentative.html new file mode 100644 index 0000000000..dc119de833 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/invokers/interestelement-interface.tentative.html @@ -0,0 +1,164 @@ +<!doctype html> +<meta charset="utf-8" /> +<meta name="author" title="Luke Warlow" href="mailto:lwarlow@igalia.com" /> +<link rel="help" href="https://open-ui.org/components/interest-invokers.explainer/" /> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<button id="buttonInvoker" interesttarget="interestee"></button> +<a id="aInvoker" interesttarget="interestee"></a> +<input type="button" id="inputInvoker" interesttarget="interestee" /> +<div id="interestee"></div> + +<script> + test(function () { + assert_equals(buttonInvoker.interestTargetElement, interestee); + assert_equals(aInvoker.interestTargetElement, interestee); + assert_equals(inputInvoker.interestTargetElement, interestee); + }, "interestTargetElement reflects interestee HTML element"); + + test(function () { + const div = document.body.appendChild(document.createElement("div")); + buttonInvoker.interestTargetElement = div; + aInvoker.interestTargetElement = div; + inputInvoker.interestTargetElement = div; + assert_equals(buttonInvoker.interestTargetElement, div); + assert_equals(buttonInvoker.getAttribute("interesttarget"), ""); + assert_equals(aInvoker.interestTargetElement, div); + assert_equals(aInvoker.getAttribute("interesttarget"), ""); + assert_equals(inputInvoker.interestTargetElement, div); + assert_equals(inputInvoker.getAttribute("interesttarget"), ""); + }, "interestTargetElement reflects set value"); + + test(function () { + const host = document.body.appendChild(document.createElement("div")); + const shadow = host.attachShadow({ mode: "open" }); + const button = shadow.appendChild(document.createElement("button")); + button.interestTargetElement = interestee; + assert_equals(button.interestTargetElement, interestee); + assert_equals(buttonInvoker.getAttribute("interesttarget"), ""); + }, "interestTargetElement reflects set value across shadow root into light dom"); + + test(function () { + const host = document.body.appendChild(document.createElement("div")); + const shadow = host.attachShadow({ mode: "open" }); + const div = shadow.appendChild(document.createElement("div")); + buttonInvoker.interestTargetElement = div; + assert_equals(buttonInvoker.interestTargetElement, null); + assert_equals(buttonInvoker.getAttribute("interesttarget"), ""); + }, "interestTargetElement does not reflect set value inside shadowroot"); + + test(function () { + buttonInvoker.setAttribute('interesttarget', 'invalid'); + assert_equals(buttonInvoker.interestTargetElement, null); + assert_equals(buttonInvoker.getAttribute("interesttarget"), "invalid"); + aInvoker.setAttribute('interesttarget', 'invalid'); + assert_equals(aInvoker.interestTargetElement, null); + assert_equals(aInvoker.getAttribute("interesttarget"), "invalid"); + inputInvoker.setAttribute('interesttarget', 'invalid'); + assert_equals(inputInvoker.interestTargetElement, null); + assert_equals(inputInvoker.getAttribute("interesttarget"), "invalid"); + }, "interestTargetElement does not reflect invalid value"); + + test(function () { + assert_throws_js( + TypeError, + function () { + buttonInvoker.interestTargetElement = {}; + }, + "interestTargetElement attribute value must be an instance of Element", + ); + assert_throws_js( + TypeError, + function () { + aInvoker.interestTargetElement = {}; + }, + "interestTargetElement attribute value must be an instance of Element", + ); + assert_throws_js( + TypeError, + function () { + inputInvoker.interestTargetElement = {}; + }, + "interestTargetElement attribute value must be an instance of Element", + ); + }, "interestTargetElement throws error on assignment of non Element"); + + test(function () { + assert_false(buttonInvoker.hasAttribute("interestaction")); + assert_equals(buttonInvoker.interestAction, ""); + assert_false(aInvoker.hasAttribute("interestaction")); + assert_equals(aInvoker.interestAction, ""); + assert_false(inputInvoker.hasAttribute("interestaction")); + assert_equals(inputInvoker.interestAction, ""); + }, "interestAction reflects '' when attribute not present"); + + test(function () { + buttonInvoker.setAttribute("interestaction", ""); + assert_equals(buttonInvoker.getAttribute("interestaction"), ""); + assert_equals(buttonInvoker.interestAction, ""); + aInvoker.setAttribute("interestaction", ""); + assert_equals(aInvoker.getAttribute("interestaction"), ""); + assert_equals(aInvoker.interestAction, ""); + inputInvoker.setAttribute("interestaction", ""); + assert_equals(inputInvoker.getAttribute("interestaction"), ""); + assert_equals(inputInvoker.interestAction, ""); + }, "interestAction reflects '' when attribute empty, setAttribute version"); + + test(function () { + buttonInvoker.interestAction = ""; + assert_equals(buttonInvoker.getAttribute("interestaction"), ""); + assert_equals(buttonInvoker.interestAction, ""); + aInvoker.interestAction = ""; + assert_equals(aInvoker.getAttribute("interestaction"), ""); + assert_equals(aInvoker.interestAction, ""); + inputInvoker.interestAction = ""; + assert_equals(inputInvoker.getAttribute("interestaction"), ""); + assert_equals(inputInvoker.interestAction, ""); + }, "interestAction reflects '' when attribute empty, IDL setter version"); + + test(function () { + buttonInvoker.interestAction = "fooBarBaz"; + assert_equals(buttonInvoker.getAttribute("interestaction"), "fooBarBaz"); + assert_equals(buttonInvoker.interestAction, "fooBarBaz"); + aInvoker.interestAction = "fooBarBaz"; + assert_equals(aInvoker.getAttribute("interestaction"), "fooBarBaz"); + assert_equals(aInvoker.interestAction, "fooBarBaz"); + inputInvoker.interestAction = "fooBarBaz"; + assert_equals(inputInvoker.getAttribute("interestaction"), "fooBarBaz"); + assert_equals(inputInvoker.interestAction, "fooBarBaz"); + }, "interestAction reflects same casing"); + + test(function () { + buttonInvoker.interestAction = []; + assert_equals(buttonInvoker.getAttribute("interestaction"), ""); + assert_equals(buttonInvoker.interestAction, ""); + aInvoker.interestAction = []; + assert_equals(aInvoker.getAttribute("interestaction"), ""); + assert_equals(aInvoker.interestAction, ""); + inputInvoker.interestAction = []; + assert_equals(inputInvoker.getAttribute("interestaction"), ""); + assert_equals(inputInvoker.interestAction, ""); + }, "interestAction reflects '' when attribute set to []"); + + test(function () { + buttonInvoker.interestAction = [1, 2, 3]; + assert_equals(buttonInvoker.getAttribute("interestaction"), "1,2,3"); + assert_equals(buttonInvoker.interestAction, "1,2,3"); + aInvoker.interestAction = [1, 2, 3]; + assert_equals(aInvoker.getAttribute("interestaction"), "1,2,3"); + assert_equals(aInvoker.interestAction, "1,2,3"); + inputInvoker.interestAction = [1, 2, 3]; + assert_equals(inputInvoker.getAttribute("interestaction"), "1,2,3"); + assert_equals(inputInvoker.interestAction, "1,2,3"); + }, "interestAction reflects tostring value"); + + test(function () { + buttonInvoker.interestAction = {}; + assert_equals(buttonInvoker.interestAction, "[object Object]"); + aInvoker.interestAction = {}; + assert_equals(aInvoker.interestAction, "[object Object]"); + inputInvoker.interestAction = {}; + assert_equals(inputInvoker.interestAction, "[object Object]"); + }, "interestAction reflects tostring value 2"); +</script> diff --git a/testing/web-platform/tests/html/semantics/invokers/invokeelement-interface.tentative.html b/testing/web-platform/tests/html/semantics/invokers/invokeelement-interface.tentative.html index b003daf20d..5a2854fe31 100644 --- a/testing/web-platform/tests/html/semantics/invokers/invokeelement-interface.tentative.html +++ b/testing/web-platform/tests/html/semantics/invokers/invokeelement-interface.tentative.html @@ -53,14 +53,14 @@ test(function () { assert_false(invoker.hasAttribute("invokeaction")); - assert_equals(invoker.invokeAction, "auto"); - }, "invokeAction reflects 'auto' when attribute not present"); + assert_equals(invoker.invokeAction, ""); + }, "invokeAction reflects '' when attribute not present"); test(function () { invoker.setAttribute("invokeaction", ""); assert_equals(invoker.getAttribute("invokeaction"), ""); - assert_equals(invoker.invokeAction, "auto"); - }, "invokeAction reflects 'auto' when attribute empty"); + assert_equals(invoker.invokeAction, ""); + }, "invokeAction reflects '' when attribute empty, setAttribute version"); test(function () { invoker.invokeAction = "fooBarBaz"; @@ -71,8 +71,8 @@ test(function () { invoker.invokeAction = ""; assert_equals(invoker.getAttribute("invokeaction"), ""); - assert_equals(invoker.invokeAction, "auto"); - }, "invokeAction reflects 'auto' when attribute empty 2"); + assert_equals(invoker.invokeAction, ""); + }, "invokeAction reflects '' when attribute empty, IDL version"); test(function () { invoker.invokeAction = [1, 2, 3]; @@ -83,8 +83,8 @@ test(function () { invoker.invokeAction = []; assert_equals(invoker.getAttribute("invokeaction"), ""); - assert_equals(invoker.invokeAction, "auto"); - }, "invokeAction reflects 'auto' when attribute set to []"); + assert_equals(invoker.invokeAction, ""); + }, "invokeAction reflects '' when attribute set to []"); test(function () { invoker.invokeAction = {}; diff --git a/testing/web-platform/tests/html/semantics/invokers/invokeevent-interface.tentative.html b/testing/web-platform/tests/html/semantics/invokers/invokeevent-interface.tentative.html index 82910b3d44..382f808071 100644 --- a/testing/web-platform/tests/html/semantics/invokers/invokeevent-interface.tentative.html +++ b/testing/web-platform/tests/html/semantics/invokers/invokeevent-interface.tentative.html @@ -15,9 +15,9 @@ <script> test(function () { const event = new InvokeEvent("test"); - assert_equals(event.action, "auto"); + assert_equals(event.action, ""); assert_readonly(event, "action", "readonly attribute value"); - }, "action is a readonly defaulting to 'auto'"); + }, "action is a readonly defaulting to ''"); test(function () { const event = new InvokeEvent("test"); @@ -32,7 +32,7 @@ test(function () { const event = new InvokeEvent("test", { action: undefined }); - assert_equals(event.action, "auto"); + assert_equals(event.action, ""); }, "action set to undefined"); test(function () { diff --git a/testing/web-platform/tests/html/semantics/invokers/invoketarget-button-event-dispatch.tentative.html b/testing/web-platform/tests/html/semantics/invokers/invoketarget-button-event-dispatch.tentative.html index b19c1d3adc..d8d9c04022 100644 --- a/testing/web-platform/tests/html/semantics/invokers/invoketarget-button-event-dispatch.tentative.html +++ b/testing/web-platform/tests/html/semantics/invokers/invoketarget-button-event-dispatch.tentative.html @@ -22,7 +22,7 @@ assert_equals(event.bubbles, false, "bubbles"); assert_equals(event.composed, true, "composed"); assert_equals(event.isTrusted, true, "isTrusted"); - assert_equals(event.action, "auto", "action"); + assert_equals(event.action, "", "action"); assert_equals(event.target, invokee, "target"); assert_equals(event.invoker, invokerbutton, "invoker"); }, "event dispatches on click"); @@ -107,6 +107,7 @@ "invoke", (event) => { eventInvoker = event.invoker; + eventTarget = event.target; called = true; }, { once: true }, @@ -114,6 +115,7 @@ invokerbutton.invokeTargetElement = svgInvokee; await clickOn(invokerbutton); assert_true(called, "event was called"); - assert_true(eventInvoker == svgInvokee, "event invoker is set to right element"); - }, "event dispatches if invoker is non-HTML Element"); + assert_equals(eventInvoker, invokerbutton, "event.invoker is set to right element"); + assert_equals(eventTarget, svgInvokee, "event.target is set to right element"); + }, "event dispatches if invokee is non-HTML Element"); </script> diff --git a/testing/web-platform/tests/html/semantics/invokers/invoketarget-on-dialog-behavior.tentative.html b/testing/web-platform/tests/html/semantics/invokers/invoketarget-on-dialog-behavior.tentative.html new file mode 100644 index 0000000000..774d308703 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/invokers/invoketarget-on-dialog-behavior.tentative.html @@ -0,0 +1,455 @@ +<!doctype html> +<meta charset="utf-8" /> +<meta name="author" title="Keith Cirkel" href="mailto:wpt@keithcirkel.co.uk" /> +<meta name="timeout" content="long"> +<link rel="help" href="https://open-ui.org/components/invokers.explainer/" /> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="resources/invoker-utils.js"></script> + +<dialog id="invokee"> + <button id="containedinvoker" invoketarget="invokee"></button> +</dialog> +<button id="invokerbutton" invoketarget="invokee"></button> + +<script> + function resetState() { + invokee.close(); + try { invokee.hidePopover(); } catch {} + invokee.removeAttribute("popover"); + invokerbutton.removeAttribute("invokeaction"); + containedinvoker.removeAttribute("invokeaction"); + } + + // opening a dialog + + [null, "", "showmodal", /* test case sensitivity */ "sHoWmOdAl"].forEach( + (action) => { + ["property", "attribute"].forEach((setType) => { + promise_test( + async function (t) { + t.add_cleanup(resetState); + assert_false(invokee.open, "invokee.open"); + assert_false(invokee.matches(":modal"), "invokee :modal"); + if (typeof action === "string") { + if (setType === "property") { + invokerbutton.invokeaction = action; + } else { + invokerbutton.setAttribute("invokeaction", action); + } + } + await clickOn(invokerbutton); + assert_true(invokee.open, "invokee.open"); + assert_true(invokee.matches(":modal"), "invokee :modal"); + }, + `invoking (with invokeaction ${setType} as ${ + action == null ? "auto" : action || "explicit empty" + }) closed dialog opens as modal`, + ); + + promise_test( + async function (t) { + t.add_cleanup(resetState); + assert_false(invokee.open, "invokee.open"); + assert_false(invokee.matches(":modal"), "invokee :modal"); + invokee.addEventListener("invoke", (e) => e.preventDefault(), { + once: true, + }); + if (typeof action === "string") { + if (setType === "property") { + invokerbutton.invokeaction = action; + } else { + invokerbutton.setAttribute("invokeaction", action); + } + } + await clickOn(invokerbutton); + assert_false(invokee.open, "invokee.open"); + assert_false(invokee.matches(":modal"), "invokee :modal"); + }, + `invoking (with invokeaction ${setType} as ${ + action == null ? "auto" : action || "explicit empty" + }) closed dialog with preventDefault is noop`, + ); + + promise_test( + async function (t) { + t.add_cleanup(resetState); + assert_false(invokee.open, "invokee.open"); + assert_false(invokee.matches(":modal"), "invokee :modal"); + invokee.addEventListener( + "invoke", + (e) => { + invokerbutton.setAttribute("invokeaction", "close"); + }, + { once: true }, + ); + if (typeof action === "string") { + if (setType === "property") { + invokerbutton.invokeaction = action; + } else { + invokerbutton.setAttribute("invokeaction", action); + } + } + await clickOn(invokerbutton); + assert_true(invokee.open, "invokee.open"); + assert_true(invokee.matches(":modal"), "invokee :modal"); + }, + `invoking (with invokeaction ${setType} as ${ + action == null ? "auto" : action || "explicit empty" + }) while changing action still opens as modal`, + ); + }); + }, + ); + + // closing an already open dialog + + [null, "", "close", /* test case sensitivity */ "cLoSe"].forEach((action) => { + ["property", "attribute"].forEach((setType) => { + promise_test( + async function (t) { + t.add_cleanup(resetState); + invokee.show(); + assert_true(invokee.open, "invokee.open"); + assert_false(invokee.matches(":modal"), "invokee :modal"); + if (typeof action === "string") { + if (setType === "property") { + containedinvoker.invokeaction = action; + } else { + containedinvoker.setAttribute("invokeaction", action); + } + } + await clickOn(containedinvoker); + assert_false(invokee.open, "invokee.open"); + assert_false(invokee.matches(":modal"), "invokee :modal"); + }, + `invoking to close (with invokeaction ${setType} as ${ + action == null ? "auto" : action || "explicit empty" + }) open dialog closes`, + ); + + promise_test( + async function (t) { + t.add_cleanup(resetState); + invokee.show(); + assert_true(invokee.open, "invokee.open"); + assert_false(invokee.matches(":modal"), "invokee :modal"); + if (typeof action === "string") { + if (setType === "property") { + containedinvoker.invokeaction = action; + } else { + containedinvoker.setAttribute("invokeaction", action); + } + } + invokee.addEventListener("invoke", (e) => e.preventDefault(), { + once: true, + }); + await clickOn(containedinvoker); + assert_true(invokee.open, "invokee.open"); + assert_false(invokee.matches(":modal"), "invokee :modal"); + }, + `invoking to close (with invokeaction ${setType} as ${ + action == null ? "auto" : action || "explicit empty" + }) open dialog with preventDefault is no-op`, + ); + + promise_test( + async function (t) { + t.add_cleanup(resetState); + invokee.showModal(); + assert_true(invokee.open, "invokee.open"); + assert_true(invokee.matches(":modal"), "invokee :modal"); + if (typeof action === "string") { + if (setType === "property") { + containedinvoker.invokeaction = action; + } else { + containedinvoker.setAttribute("invokeaction", action); + } + } + invokee.addEventListener("invoke", (e) => e.preventDefault(), { + once: true, + }); + await clickOn(containedinvoker); + assert_true(invokee.open, "invokee.open"); + assert_true(invokee.matches(":modal"), "invokee :modal"); + }, + `invoking to close (with invokeaction ${setType} as ${ + action == null ? "auto" : action || "explicit empty" + }) open modal dialog with preventDefault is no-op`, + ); + + promise_test( + async function (t) { + t.add_cleanup(resetState); + invokee.show(); + assert_true(invokee.open, "invokee.open"); + assert_false(invokee.matches(":modal"), "invokee :modal"); + if (typeof action === "string") { + if (setType === "property") { + containedinvoker.invokeaction = action; + } else { + containedinvoker.setAttribute("invokeaction", action); + } + } + invokee.addEventListener( + "invoke", + (e) => { + containedinvoker.setAttribute("invokeaction", "show"); + }, + { once: true }, + ); + await clickOn(containedinvoker); + assert_false(invokee.open, "invokee.open"); + assert_false(invokee.matches(":modal"), "invokee :modal"); + }, + `invoking to close (with invokeaction ${setType} as ${ + action == null ? "auto" : action || "explicit empty" + }) open dialog while changing action still closes`, + ); + + promise_test( + async function (t) { + t.add_cleanup(resetState); + invokee.showModal(); + assert_true(invokee.open, "invokee.open"); + assert_true(invokee.matches(":modal"), "invokee :modal"); + if (typeof action === "string") { + if (setType === "property") { + containedinvoker.invokeaction = action; + } else { + containedinvoker.setAttribute("invokeaction", action); + } + } + invokee.addEventListener( + "invoke", + (e) => { + containedinvoker.setAttribute("invokeaction", "show"); + }, + { once: true }, + ); + await clickOn(containedinvoker); + assert_false(invokee.open, "invokee.open"); + assert_false(invokee.matches(":modal"), "invokee :modal"); + }, + `invoking to close (with invokeaction ${setType} as ${ + action == null ? "auto" : action || "explicit empty" + }) open modal dialog while changing action still closes`, + ); + }); + }); + + // showmodal explicit behaviours + + promise_test(async function (t) { + t.add_cleanup(resetState); + containedinvoker.setAttribute("invokeaction", "showModal"); + invokee.show(); + assert_true(invokee.open, "invokee.open"); + assert_false(invokee.matches(":modal"), "invokee :modal"); + await clickOn(containedinvoker); + assert_true(invokee.open, "invokee.open"); + assert_false(invokee.matches(":modal"), "invokee :modal"); + }, "invoking (as showmodal) open dialog is noop"); + + promise_test(async function (t) { + t.add_cleanup(resetState); + containedinvoker.setAttribute("invokeaction", "showmodal"); + invokee.showModal(); + assert_true(invokee.open, "invokee.open"); + assert_true(invokee.matches(":modal"), "invokee :modal"); + invokee.addEventListener( + "invoke", + (e) => { + containedinvoker.setAttribute("invokeaction", "close"); + }, + { once: true }, + ); + await clickOn(invokerbutton); + assert_true(invokee.open, "invokee.open"); + assert_true(invokee.matches(":modal"), "invokee :modal"); + }, "invoking (as showmodal) open modal, while changing action still a no-op"); + + promise_test(async function (t) { + t.add_cleanup(resetState); + invokerbutton.setAttribute("invokeaction", "showmodal"); + assert_false(invokee.open, "invokee.open"); + assert_false(invokee.matches(":modal"), "invokee :modal"); + invokee.setAttribute("popover", "auto"); + await clickOn(invokerbutton); + assert_true(invokee.open, "invokee.open"); + assert_true(invokee.matches(":modal"), "invokee :modal"); + }, "invoking (as showmodal) closed popover dialog opens as modal"); + + // close explicit behaviours + + promise_test(async function (t) { + t.add_cleanup(resetState); + invokerbutton.setAttribute("invokeaction", "close"); + assert_false(invokee.open, "invokee.open"); + assert_false(invokee.matches(":modal"), "invokee :modal"); + await clickOn(containedinvoker); + assert_false(invokee.open, "invokee.open"); + assert_false(invokee.matches(":modal"), "invokee :modal"); + }, "invoking (as close) already closed dialog is noop"); + + // invalid + [ + "foo", + "foo-bar", + "auto", + "showpopover", + "hidepopover", + "togglepopover", + "showpicker", + ].forEach((action) => { + promise_test(async function (t) { + t.add_cleanup(resetState); + invokerbutton.setAttribute("invokeaction", action); + assert_false(invokee.open, "invokee.open"); + assert_false(invokee.matches(":modal"), "invokee :modal"); + await clickOn(invokerbutton); + assert_false(invokee.open, "invokee.open"); + assert_false(invokee.matches(":modal"), "invokee :modal"); + }, `invoking (as ${action}) on dialog does nothing`); + + promise_test(async function (t) { + t.add_cleanup(resetState); + containedinvoker.setAttribute("invokeaction", action); + invokee.show(); + assert_true(invokee.open, "invokee.open"); + assert_false(invokee.matches(":modal"), "invokee :modal"); + await clickOn(containedinvoker); + assert_true(invokee.open, "invokee.open"); + assert_false(invokee.matches(":modal"), "invokee :modal"); + }, `invoking (as ${action}) on open dialog does nothing`); + + promise_test(async function (t) { + t.add_cleanup(resetState); + containedinvoker.setAttribute("invokeaction", action); + invokee.showModal(); + assert_true(invokee.open, "invokee.open"); + assert_true(invokee.matches(":modal"), "invokee :modal"); + await clickOn(containedinvoker); + assert_true(invokee.open, "invokee.open"); + assert_true(invokee.matches(":modal"), "invokee :modal"); + }, `invoking (as ${action}) on open modal dialog does nothing`); + + promise_test(async function (t) { + t.add_cleanup(resetState); + containedinvoker.setAttribute("invokeaction", action); + invokee.showModal(); + assert_true(invokee.open, "invokee.open"); + assert_true(invokee.matches(":modal"), "invokee :modal"); + invokee.addEventListener( + "invoke", + (e) => { + containedinvoker.setAttribute("invokeaction", ""); + }, + { once: true }, + ); + await clickOn(containedinvoker); + assert_true(invokee.open, "invokee.open"); + assert_true(invokee.matches(":modal"), "invokee :modal"); + }, `invoking (as ${action}) on open modal while changing the attributer does nothing`); + }); + + // Open Popovers using Dialog actions + ["showmodal", "close", ""].forEach((action) => { + ["manual", "auto"].forEach((popoverState) => { + promise_test( + async function (t) { + t.add_cleanup(resetState); + invokee.setAttribute("popover", popoverState); + invokee.showPopover(); + containedinvoker.setAttribute("invokeaction", action); + assert_true( + invokee.matches(":popover-open"), + "invokee :popover-open", + ); + assert_false(invokee.open, "invokee.open"); + assert_false(invokee.matches(":modal"), "invokee :modal"); + invokee.addEventListener("invoke", (e) => e.preventDefault(), { + once: true, + }); + await clickOn(containedinvoker); + assert_true( + invokee.matches(":popover-open"), + "invokee :popover-open", + ); + assert_false(invokee.open, "invokee.open"); + assert_false(invokee.matches(":modal"), "invokee :modal"); + }, + `invoking (as ${ + action || "explicit empty" + }) dialog as open popover=${popoverState} is noop`, + ); + }); + }); + + // Elements being disconnected during invoke steps + ["showmodal", "close", ""].forEach((action) => { + promise_test( + async function (t) { + t.add_cleanup(() => { + document.body.prepend(invokee); + resetState(); + }); + const invokee = document.querySelector("#invokee"); + invokerbutton.setAttribute("invokeaction", action); + assert_false(invokee.open, "invokee.open"); + assert_false(invokee.matches(":modal"), "invokee :modal"); + invokee.addEventListener( + "invoke", + (e) => { + invokee.remove(); + }, + { + once: true, + }, + ); + await clickOn(invokerbutton); + assert_false(invokee.open, "invokee.open"); + assert_false(invokee.matches(":modal"), "invokee :modal"); + }, + `invoking (as ${ + action || "explicit empty" + }) dialog that is removed is noop`, + ); + + promise_test( + async function (t) { + const invokerbutton = document.createElement("button"); + invokerbutton.invokeTargetElement = invokee; + invokerbutton.setAttribute("invokeaction", action); + assert_false(invokee.open, "invokee.open"); + assert_false(invokee.matches(":modal"), "invokee :modal"); + await clickOn(invokerbutton); + assert_false(invokee.open, "invokee.open"); + assert_false(invokee.matches(":modal"), "invokee :modal"); + }, + `invoking (as ${ + action || "explicit empty" + }) dialog from a detached invoker`, + ); + + promise_test( + async function (t) { + const invokerbutton = document.createElement("button"); + const invokee = document.createElement("dialog"); + invokerbutton.invokeTargetElement = invokee; + invokerbutton.setAttribute("invokeaction", action); + assert_false(invokee.open, "invokee.open"); + assert_false(invokee.matches(":modal"), "invokee :modal"); + await clickOn(invokerbutton); + assert_false(invokee.open, "invokee.open"); + assert_false(invokee.matches(":modal"), "invokee :modal"); + }, + `invoking (as ${ + action || "explicit empty" + }) detached dialog from a detached invoker`, + ); + }); +</script> diff --git a/testing/web-platform/tests/html/semantics/invokers/invoketarget-on-popover-behavior.tentative.html b/testing/web-platform/tests/html/semantics/invokers/invoketarget-on-popover-behavior.tentative.html index 03eba22285..2bddfa7621 100644 --- a/testing/web-platform/tests/html/semantics/invokers/invoketarget-on-popover-behavior.tentative.html +++ b/testing/web-platform/tests/html/semantics/invokers/invoketarget-on-popover-behavior.tentative.html @@ -10,7 +10,7 @@ <script src="resources/invoker-utils.js"></script> <div id="invokee" popover> - <button id="invokerbutton2" invoketarget="invokee"></button> + <button id="containedinvoker" invoketarget="invokee"></button> </div> <button id="invokerbutton" invoketarget="invokee"></button> @@ -44,7 +44,7 @@ promise_test(async function (t) { invokee.showPopover(); assert_true(invokee.matches(":popover-open")); - await clickOn(invokerbutton2); + await clickOn(containedinvoker); assert_false(invokee.matches(":popover-open")); }, "invoking (as auto) from within open popover closes"); @@ -55,7 +55,7 @@ once: true, }); assert_true(invokee.matches(":popover-open")); - await clickOn(invokerbutton2); + await clickOn(containedinvoker); assert_true(invokee.matches(":popover-open")); }, "invoking (as auto) open popover with preventDefault does not close"); @@ -93,8 +93,8 @@ promise_test(async function (t) { invokee.showPopover(); - invokerbutton2.setAttribute("invokeaction", "togglepopover"); - t.add_cleanup(() => invokerbutton2.removeAttribute("invokeaction")); + containedinvoker.setAttribute("invokeaction", "togglepopover"); + t.add_cleanup(() => containedinvoker.removeAttribute("invokeaction")); assert_true(invokee.matches(":popover-open")); await clickOn(invokerbutton); assert_false(invokee.matches(":popover-open")); @@ -102,23 +102,23 @@ promise_test(async function (t) { invokee.showPopover(); - invokerbutton2.setAttribute("invokeaction", "togglepopover"); - t.add_cleanup(() => invokerbutton2.removeAttribute("invokeaction")); + containedinvoker.setAttribute("invokeaction", "togglepopover"); + t.add_cleanup(() => containedinvoker.removeAttribute("invokeaction")); assert_true(invokee.matches(":popover-open")); - await clickOn(invokerbutton2); + await clickOn(containedinvoker); assert_false(invokee.matches(":popover-open")); }, "invoking (as togglepopover) from within open popover closes"); promise_test(async function (t) { invokee.showPopover(); t.add_cleanup(() => invokee.hidePopover()); - invokerbutton2.setAttribute("invokeaction", "togglepopover"); - t.add_cleanup(() => invokerbutton2.removeAttribute("invokeaction")); + containedinvoker.setAttribute("invokeaction", "togglepopover"); + t.add_cleanup(() => containedinvoker.removeAttribute("invokeaction")); invokee.addEventListener("invoke", (e) => e.preventDefault(), { once: true, }); assert_true(invokee.matches(":popover-open")); - await clickOn(invokerbutton2); + await clickOn(containedinvoker); assert_true(invokee.matches(":popover-open")); }, "invoking (as togglepopover) open popover with preventDefault does not close"); @@ -175,35 +175,59 @@ }, "invoking (as hidepopover) closed popover is noop"); promise_test(async function (t) { - invokerbutton2.setAttribute("invokeaction", "hidepopover"); - t.add_cleanup(() => invokerbutton2.removeAttribute("invokeaction")); + containedinvoker.setAttribute("invokeaction", "hidepopover"); + t.add_cleanup(() => containedinvoker.removeAttribute("invokeaction")); invokee.showPopover(); assert_true(invokee.matches(":popover-open")); - await clickOn(invokerbutton2); + await clickOn(containedinvoker); t.add_cleanup(() => invokee.hidePopover()); assert_false(invokee.matches(":popover-open")); }, "invoking (as hidepopover) open popover closes"); promise_test(async function (t) { - invokerbutton2.setAttribute("invokeaction", "hIdEpOpOvEr"); - t.add_cleanup(() => invokerbutton2.removeAttribute("invokeaction")); + containedinvoker.setAttribute("invokeaction", "hIdEpOpOvEr"); + t.add_cleanup(() => containedinvoker.removeAttribute("invokeaction")); invokee.showPopover(); assert_true(invokee.matches(":popover-open")); - await clickOn(invokerbutton2); + await clickOn(containedinvoker); t.add_cleanup(() => invokee.hidePopover()); assert_false(invokee.matches(":popover-open")); }, "invoking (as hidepopover - case insensitive) open popover closes"); promise_test(async function (t) { - invokerbutton2.setAttribute("invokeaction", "hidepopover"); - t.add_cleanup(() => invokerbutton2.removeAttribute("invokeaction")); + containedinvoker.setAttribute("invokeaction", "hidepopover"); + t.add_cleanup(() => containedinvoker.removeAttribute("invokeaction")); invokee.showPopover(); t.add_cleanup(() => invokee.hidePopover()); assert_true(invokee.matches(":popover-open")); invokee.addEventListener("invoke", (e) => e.preventDefault(), { once: true, }); - await clickOn(invokerbutton2); + await clickOn(containedinvoker); assert_true(invokee.matches(":popover-open")); }, "invoking (as hidepopover) open popover with preventDefault does not close"); + + // invalid + + ["foo", "togglemodal", "showpicker", "toggle", "open", "close"].forEach(action => { + promise_test(async function (t) { + invokerbutton.setAttribute("invokeaction", action); + t.add_cleanup(() => invokerbutton.removeAttribute("invokeaction")); + assert_false(invokee.matches(":popover-open")); + await clickOn(invokerbutton); + assert_false(invokee.matches(":popover-open")); + }, `invoking (as ${action}) on popover does nothing`); + + promise_test(async function (t) { + invokerbutton.setAttribute("invokeaction", action); + t.add_cleanup(() => { + invokerbutton.removeAttribute("invokeaction") + invokee.hidePopover(); + }); + invokee.showPopover() + assert_true(invokee.matches(":popover-open")); + await clickOn(invokerbutton); + assert_true(invokee.matches(":popover-open")); + }, `invoking (as ${action}) on open popover does nothing`); + }) </script> diff --git a/testing/web-platform/tests/html/semantics/invokers/resources/invoker-utils.js b/testing/web-platform/tests/html/semantics/invokers/resources/invoker-utils.js index 317945502d..8420f24b6f 100644 --- a/testing/web-platform/tests/html/semantics/invokers/resources/invoker-utils.js +++ b/testing/web-platform/tests/html/semantics/invokers/resources/invoker-utils.js @@ -2,9 +2,13 @@ function waitForRender() { return new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve))); } async function clickOn(element) { - const actions = new test_driver.Actions(); await waitForRender(); - await actions.pointerMove(0, 0, {origin: element}) + let rect = element.getBoundingClientRect(); + let actions = new test_driver.Actions(); + // FIXME: Switch to pointerMove(0, 0, {origin: element}) once + // https://github.com/web-platform-tests/wpt/issues/41257 is fixed. + await actions + .pointerMove(Math.round(rect.x + rect.width / 2), Math.round(rect.y + rect.height / 2), {}) .pointerDown({button: actions.ButtonType.LEFT}) .pointerUp({button: actions.ButtonType.LEFT}) .send(); diff --git a/testing/web-platform/tests/html/semantics/permission-element/bounded-css-properties.html b/testing/web-platform/tests/html/semantics/permission-element/bounded-css-properties.html new file mode 100644 index 0000000000..98c3d70e98 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/permission-element/bounded-css-properties.html @@ -0,0 +1,38 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<body> +<!--The permission element should have some limits for specific properties: + * font-weight is adjusted to be at least 200. + * font-style should only have "normal" or "italic" values. +--> +<style> + #id1 { + font-weight: 100; + font-style: oblique 30deg; + } + #id2 { + font-weight: 300; + font-style: italic; + } +</style> + + +<permission id="id1" type="geolocation"> +<permission id="id2" type="camera"> + +<script> + test(function(){ + var el_outside_bounds = document.getElementById("id1"); + assert_equals(getComputedStyle(el_outside_bounds).fontWeight, "200", "font-weight"); + assert_equals(getComputedStyle(el_outside_bounds).fontStyle, "normal", "font-style"); + }, "Properties with out-of-bounds values should be corrected"); + + test(function(){ + var el_inside_bounds = document.getElementById("id2"); + assert_equals(getComputedStyle(el_inside_bounds).fontWeight, "300", "font-weight"); + assert_equals(getComputedStyle(el_inside_bounds).fontStyle, "italic", "font-style"); + }, "Properties with values in bounds should not be modified"); +</script> +</body>
\ No newline at end of file diff --git a/testing/web-platform/tests/html/semantics/permission-element/invalid-css-properties.html b/testing/web-platform/tests/html/semantics/permission-element/invalid-css-properties.html new file mode 100644 index 0000000000..c7186563f0 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/permission-element/invalid-css-properties.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<body> +<!--The permission element does not allow certain CSS properties +--> +<style> + #id1 { + border-image: url('test-url'); + background-image: url('test-url'); + clip-path: circle(10px); + filter: blur(10px); + mask: url('test-url'); + padding-left: 10px; + transform: rotate(10); + } +</style> + +<permission id="id1" type="geolocation"> + +<script> + test(function(){ + var el_with_negatives = document.getElementById("id1"); + assert_equals(getComputedStyle(el_with_negatives).borderImage, "none", "border-image"); + assert_equals(getComputedStyle(el_with_negatives).backgroundImage, "none", "background-image"); + assert_equals(getComputedStyle(el_with_negatives).clipPath, "none", "clip-path"); + assert_equals(getComputedStyle(el_with_negatives).filter, "none", "filter"); + assert_equals(getComputedStyle(el_with_negatives).mask, "none", "mask"); + assert_equals(getComputedStyle(el_with_negatives).paddingLeft, "0px", "padding-left"); + assert_equals(getComputedStyle(el_with_negatives).transform, "none", "transform"); + }, "None of the listed properties should be applied"); +</script> +</body>
\ No newline at end of file diff --git a/testing/web-platform/tests/html/semantics/permission-element/negative-offset-and-margin.html b/testing/web-platform/tests/html/semantics/permission-element/negative-offset-and-margin.html new file mode 100644 index 0000000000..97290bb4df --- /dev/null +++ b/testing/web-platform/tests/html/semantics/permission-element/negative-offset-and-margin.html @@ -0,0 +1,67 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<body> +<!--The permission element should not allow setting negative margins or outline-offset +--> +<style> + #id1 { + outline-offset: -50px; + margin-top: -50px; + margin-left: -50px; + margin-bottom: -50px; + margin-right: -50px; + } + #id2 { + outline-offset: 50px; + margin-top: 50px; + margin-left: 50px; + margin-bottom: 50px; + margin-right: 50px; + } + + /* These various expressions all result in a negative value when calculated */ + #id3 { + outline-offset: min(-50px, 50px); + margin-top: min(10%, -50px); + margin-left: clamp(-100px, 1vw, -50px); + margin-bottom: 1% - 10000px; + margin-right: max(min(-1em, 10em), -5%); + } +</style> + + +<permission id="id1" type="geolocation"> +<permission id="id2" type="camera"> +<permission id="id3" type="microphone"> + +<script> + test(function(){ + var el_with_negatives = document.getElementById("id1"); + assert_equals(getComputedStyle(el_with_negatives).outlineOffset, "0px", "outline-offset"); + assert_equals(getComputedStyle(el_with_negatives).marginLeft, "0px", "margin-left"); + assert_equals(getComputedStyle(el_with_negatives).marginRight, "0px", "margin-right"); + assert_equals(getComputedStyle(el_with_negatives).marginTop, "0px", "margin-top"); + assert_equals(getComputedStyle(el_with_negatives).marginBottom, "0px", "margin-bottom"); + }, "Negative margins/offset should be changed to 0px"); + + test(function(){ + var el_with_positives = document.getElementById("id2"); + assert_equals(getComputedStyle(el_with_positives).outlineOffset, "50px", "outline-offset"); + assert_equals(getComputedStyle(el_with_positives).marginLeft, "50px", "margin-left"); + assert_equals(getComputedStyle(el_with_positives).marginRight, "50px", "margin-right"); + assert_equals(getComputedStyle(el_with_positives).marginTop, "50px", "margin-top"); + assert_equals(getComputedStyle(el_with_positives).marginBottom, "50px", "margin-bottom"); + }, "Positive margins/offset are unaffected"); + + test(function(){ + var el_with_negative_expr = document.getElementById("id3"); + assert_equals(getComputedStyle(el_with_negative_expr).outlineOffset, "0px", "outline-offset"); + assert_equals(getComputedStyle(el_with_negative_expr).marginLeft, "0px", "margin-left"); + assert_equals(getComputedStyle(el_with_negative_expr).marginRight, "0px", "margin-right"); + assert_equals(getComputedStyle(el_with_negative_expr).marginTop, "0px", "margin-top"); + assert_equals(getComputedStyle(el_with_negative_expr).marginBottom, "0px", "margin-bottom"); + }, "Expressions margins/offset should always return at least 0px"); +</script> +</body>
\ No newline at end of file diff --git a/testing/web-platform/tests/html/semantics/popovers/popover-shadow-dom-anchor.tentative.html b/testing/web-platform/tests/html/semantics/popovers/popover-shadow-dom-anchor.tentative.html new file mode 100644 index 0000000000..7c87d2d039 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/popovers/popover-shadow-dom-anchor.tentative.html @@ -0,0 +1,99 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<link rel="author" href="mailto:masonf@chromium.org"> +<link rel=help href="https://open-ui.org/components/popover.research.explainer"> +<link rel=help href="https://html.spec.whatwg.org/multipage/popover.html"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/popover-utils.js"></script> + +<!-- Once anchor positioning lands in the spec, the tests in this file can + be re-inserted into popover-shadow-dom.html. --> + +<script> + function findPopovers(root) { + let popovers = []; + if (!root) + return popovers; + if (root instanceof Element && root.matches('[popover]')) + popovers.push(root); + popovers.push(...findPopovers(root.shadowRoot)); + root.childNodes.forEach(child => { + popovers.push(...findPopovers(child)); + }) + return popovers; + } + function getPopoverReferences(testId) { + const testRoot = document.querySelector(`#${testId}`); + assert_true(!!testRoot); + return findPopovers(testRoot); + } +</script> + +<div id=test1> + <button id=t2b1>Test 1 Popover 1</button> + <div popover anchor=t2b1 style="top: 200px;"> + <p>Popover 1</p> + <button id=t2b2>Test 1 Popover 2</button> + </div> + <my-element> + <template shadowrootmode=open> + <div popover anchor=t2b2 style="top: 400px;"> + <p>Hiding this popover will hide *all* open popovers,</p> + <p>because t2b2 doesn't exist in this context.</p> + </div> + </template> + </my-element> +</div> + +<script> + test(function() { + const [popover1,popover2] = getPopoverReferences('test1'); + popover1.showPopover(); + assert_true(popover1.matches(':popover-open')); + assert_true(isElementVisible(popover1)); + popover2.showPopover(); + assert_false(popover1.matches(':popover-open'), 'popover1 open'); // P1 was closed by P2 + assert_false(isElementVisible(popover1), 'popover1 visible'); + assert_true(popover2.matches(':popover-open'), 'popover2 open'); // P2 is open + assert_true(isElementVisible(popover2), 'popover2 visible'); + popover2.hidePopover(); // Cleanup + }, "anchor references do not cross shadow boundaries"); +</script> + + +<div id=test2> + <my-element> + <template shadowrootmode=open> + <button id=t3b1>Test 2 Popover 1</button> + <div popover anchor=t3b1> + <p>This popover will stay open when popover2 shows.</p> + <slot></slot> + </div> + </template> + <button id=t3b2>Test 2 Popover 2</button> + </my-element> + <div popover anchor=t3b2>Popover 2</div> +</div> + +<script> + promise_test(async function() { + const [popover1,popover2] = getPopoverReferences('test2'); + popover1.showPopover(); + assert_true(popover1.matches(':popover-open')); + assert_true(isElementVisible(popover1)); + // Showing popover2 should not close popover1, since it is a flat + // tree ancestor of popover2's anchor button. + popover2.showPopover(); + assert_true(popover2.matches(':popover-open')); + assert_true(isElementVisible(popover2)); + assert_true(popover1.matches(':popover-open')); + assert_true(isElementVisible(popover1)); + popover1.hidePopover(); + await waitForRender(); + assert_false(popover1.matches(':popover-open')); + assert_false(isElementVisible(popover1)); + assert_false(popover2.matches(':popover-open')); + assert_false(isElementVisible(popover2)); + }, "anchor references use the flat tree not the DOM tree"); +</script> diff --git a/testing/web-platform/tests/html/semantics/popovers/popover-shadow-dom.html b/testing/web-platform/tests/html/semantics/popovers/popover-shadow-dom.html index 62aa135b56..18ac500270 100644 --- a/testing/web-platform/tests/html/semantics/popovers/popover-shadow-dom.html +++ b/testing/web-platform/tests/html/semantics/popovers/popover-shadow-dom.html @@ -8,17 +8,6 @@ <script src="resources/popover-utils.js"></script> <script> - function ensureShadowDom(host) { - host.querySelectorAll('my-element').forEach(host => { - if (host.shadowRoot) - return; // Declarative Shadow DOM is enabled - const template = host.firstElementChild; - assert_true(template instanceof HTMLTemplateElement); - const shadow = host.attachShadow({mode: 'open'}); - shadow.appendChild(template.content); - template.remove(); - }) - } function findPopovers(root) { let popovers = []; if (!root) @@ -34,16 +23,12 @@ function getPopoverReferences(testId) { const testRoot = document.querySelector(`#${testId}`); assert_true(!!testRoot); - ensureShadowDom(testRoot); return findPopovers(testRoot); } - function showTestPopover(testId,popoverNum) { - getPopoverReferences(testId)[popoverNum].showPopover(); - } </script> <div id=test1> - <button onclick='showTestPopover("test1",0)'>Test1 Popover</button> + <button>Test1 Popover</button> <my-element> <template shadowrootmode=open> <div popover> @@ -64,83 +49,14 @@ </script> -<div id=test2> - <button id=t2b1 onclick='showTestPopover("test2",0)'>Test 2 Popover 1</button> - <div popover anchor=t2b1 style="top: 200px;"> - <p>Popover 1</p> - <button id=t2b2 onclick='showTestPopover("test2",1)'>Test 2 Popover 2</button> - </div> - <my-element> - <template shadowrootmode=open> - <div popover anchor=t2b2 style="top: 400px;"> - <p>Hiding this popover will hide *all* open popovers,</p> - <p>because t2b2 doesn't exist in this context.</p> - </div> - </template> - </my-element> -</div> - -<script> - test(function() { - const [popover1,popover2] = getPopoverReferences('test2'); - popover1.showPopover(); - assert_true(popover1.matches(':popover-open')); - assert_true(isElementVisible(popover1)); - popover2.showPopover(); - assert_false(popover1.matches(':popover-open'), 'popover1 open'); // P1 was closed by P2 - assert_false(isElementVisible(popover1), 'popover1 visible'); - assert_true(popover2.matches(':popover-open'), 'popover2 open'); // P2 is open - assert_true(isElementVisible(popover2), 'popover2 visible'); - popover2.hidePopover(); // Cleanup - }, "anchor references do not cross shadow boundaries"); -</script> - - -<div id=test3> - <my-element> - <template shadowrootmode=open> - <button id=t3b1 onclick='showTestPopover("test3",0)'>Test 3 Popover 1</button> - <div popover anchor=t3b1> - <p>This popover will stay open when popover2 shows.</p> - <slot></slot> - </div> - </template> - <button id=t3b2 onclick='showTestPopover("test3",1)'>Test 3 Popover 2</button> - </my-element> - <div popover anchor=t3b2>Popover 2</div> -</div> - -<script> - promise_test(async function() { - const [popover1,popover2] = getPopoverReferences('test3'); - popover1.showPopover(); - assert_true(popover1.matches(':popover-open')); - assert_true(isElementVisible(popover1)); - // Showing popover2 should not close popover1, since it is a flat - // tree ancestor of popover2's anchor button. - popover2.showPopover(); - assert_true(popover2.matches(':popover-open')); - assert_true(isElementVisible(popover2)); - assert_true(popover1.matches(':popover-open')); - assert_true(isElementVisible(popover1)); - popover1.hidePopover(); - await waitForRender(); - assert_false(popover1.matches(':popover-open')); - assert_false(isElementVisible(popover1)); - assert_false(popover2.matches(':popover-open')); - assert_false(isElementVisible(popover2)); - }, "anchor references use the flat tree not the DOM tree"); -</script> - - <div id=test4> - <button id=t4b1 onclick='showTestPopover("test4",0)'>Test 4 Popover 1</button> - <div popover anchor=t4b1> + <button>Test 4 Popover 1</button> + <div popover> <p>This should not get hidden when popover2 opens.</p> <my-element> <template shadowrootmode=open> - <button id=t4b2 onclick='showTestPopover("test4",1)'>Test 4 Popover 2</button> - <div popover anchor=t4b2> + <button id=t4b2>Test 4 Popover 2</button> + <div popover> <p>This should not hide popover1.</p> </div> </template> diff --git a/testing/web-platform/tests/html/semantics/popovers/popovertarget-reflection.html b/testing/web-platform/tests/html/semantics/popovers/popovertarget-reflection.html index d0750fdd4c..b4f99631ab 100644 --- a/testing/web-platform/tests/html/semantics/popovers/popovertarget-reflection.html +++ b/testing/web-platform/tests/html/semantics/popovers/popovertarget-reflection.html @@ -11,7 +11,7 @@ <script> test(() => { - assert_equals(mybutton.popoverTargetElement.id, "mypopover", + assert_equals(mybutton.popoverTargetElement.id, "mypopover", 'Setting element.popoverTargetElement to a valid element should work'); mybutton.popoverTargetElement = null; @@ -33,13 +33,13 @@ test(() => { 'Assigning to element.popoverTargetElement should set the popovertarget attribute.'); mybutton.setAttribute("popovertarget", 'invalid'); - assert_equals(mybutton.popoverTargetElement, null, + assert_equals(mybutton.popoverTargetElement, null, 'Setting the popovertarget attribute to a localName that is not attr should remove the existing element from element.popoverTargetElement.'); mybutton.popoverTargetElement = mypopover; mybutton.setAttribute("popovertarget", ""); - assert_equals(mybutton.popoverTargetElement.id, "mypopover", - 'Setting the popovertarget attribute to empty string right after explicitly setting attribute element should have no effect.'); + assert_equals(mybutton.popoverTargetElement, null, + 'Setting the popovertarget attribute to empty string right after setting explicit element does remove the explicit element.'); mybutton.setAttribute("popovertarget", "mypopover"); assert_equals(mybutton.popoverTargetElement.id, "mypopover", diff --git a/testing/web-platform/tests/html/semantics/popovers/resources/popover-utils.js b/testing/web-platform/tests/html/semantics/popovers/resources/popover-utils.js index bfc1f89ec1..96ac7e03f0 100644 --- a/testing/web-platform/tests/html/semantics/popovers/resources/popover-utils.js +++ b/testing/web-platform/tests/html/semantics/popovers/resources/popover-utils.js @@ -7,9 +7,13 @@ function waitForTick() { } async function clickOn(element) { - const actions = new test_driver.Actions(); await waitForRender(); - await actions.pointerMove(0, 0, {origin: element}) + let rect = element.getBoundingClientRect(); + let actions = new test_driver.Actions(); + // FIXME: Switch to pointerMove(0, 0, {origin: element}) once + // https://github.com/web-platform-tests/wpt/issues/41257 is fixed. + await actions + .pointerMove(Math.round(rect.x + rect.width / 2), Math.round(rect.y + rect.height / 2), {}) .pointerDown({button: actions.ButtonType.LEFT}) .pointerUp({button: actions.ButtonType.LEFT}) .send(); diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-1.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-1.html index 50933da2c1..3645279d61 100644 --- a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-1.html +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-1.html @@ -9,7 +9,7 @@ window.log = []; window.addEventListener("error", ev => log.push(ev.error)); - window.addEventListener("onunhandledrejection", unreachable); + window.addEventListener("unhandledrejection", unreachable); const test_load = async_test( "Parse errors in different files should be reported " + diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-2.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-2.html index 51adb09d11..d40aaba8df 100644 --- a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-2.html +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-2.html @@ -9,7 +9,7 @@ window.log = []; window.addEventListener("error", ev => log.push(ev.error)); - window.addEventListener("onunhandledrejection", unreachable); + window.addEventListener("unhandledrejection", unreachable); const test_load = async_test( "Instantiation errors in different files should be reported " + diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-3.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-3.html index bc52119bfe..2d74af864b 100644 --- a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-3.html +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/choice-of-error-3.html @@ -9,7 +9,7 @@ window.log = []; window.addEventListener("error", ev => log.push(ev.error)); - window.addEventListener("onunhandledrejection", unreachable); + window.addEventListener("unhandledrejection", unreachable); const test_load = async_test( "Evaluation errors are cached in intermediate module scripts"); diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-1.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-1.html index 2480a60d6d..0484b614ab 100644 --- a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-1.html +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-1.html @@ -9,7 +9,7 @@ window.log = []; window.addEventListener("error", ev => log.push(ev.error)); - window.addEventListener("onunhandledrejection", unreachable); + window.addEventListener("unhandledrejection", unreachable); const test_load = async_test( "network error has higher priority than parse error"); diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-2.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-2.html index 673bf28ca2..7303a838a5 100644 --- a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-2.html +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-2.html @@ -9,7 +9,7 @@ window.log = []; window.addEventListener("error", ev => log.push(ev.error)); - window.addEventListener("onunhandledrejection", unreachable); + window.addEventListener("unhandledrejection", unreachable); const test_load = async_test( "parse error has higher priority than instantiation error"); diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-3.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-3.html index 8a16266f4c..f80f74cbe4 100644 --- a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-3.html +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/error-type-3.html @@ -9,7 +9,7 @@ window.log = []; window.addEventListener("error", ev => log.push(ev.error)); - window.addEventListener("onunhandledrejection", unreachable); + window.addEventListener("unhandledrejection", unreachable); const test_load = async_test( "instantiation error has higher priority than evaluation error"); diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-1.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-1.html index 3f2bb35f4e..b12d178fb5 100644 --- a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-1.html +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-1.html @@ -9,7 +9,7 @@ window.log = []; window.addEventListener("error", ev => log.push(ev.error)); - window.addEventListener("onunhandledrejection", unreachable); + window.addEventListener("unhandledrejection", unreachable); const test_load = async_test( "Test that exceptions during evaluation lead to error events on " + diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-2.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-2.html index 4f2b3c5a74..a890ca6457 100644 --- a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-2.html +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-2.html @@ -9,7 +9,7 @@ window.log = []; window.addEventListener("error", ev => log.push(ev.error)); - window.addEventListener("onunhandledrejection", unreachable); + window.addEventListener("unhandledrejection", unreachable); const test_load = async_test( "Test that ill-founded cyclic dependencies cause ReferenceError " + diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-3.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-3.html index 9bfb5df2cf..4062bc8a3a 100644 --- a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-3.html +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-3.html @@ -9,7 +9,7 @@ window.log = []; window.addEventListener("error", ev => log.push(ev.error)); - window.addEventListener("onunhandledrejection", unreachable); + window.addEventListener("unhandledrejection", unreachable); const test_load = async_test( "Test that exceptions during evaluation lead to error events on " + diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-4.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-4.html index 0b4b7d1662..256aea508e 100644 --- a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-4.html +++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/module/evaluation-error-4.html @@ -9,7 +9,7 @@ window.log = []; window.addEventListener("error", ev => log.push(ev.error)); - window.addEventListener("onunhandledrejection", unreachable); + window.addEventListener("unhandledrejection", unreachable); const test_load = async_test( "Test that exceptions during evaluation lead to error events on " + diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-auto-dir-default.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-auto-dir-default.html index 3a9d90c76b..e658500a4e 100644 --- a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-auto-dir-default.html +++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-auto-dir-default.html @@ -30,13 +30,13 @@ ‭ - The LRO (left-to-right override) formatting character. ‬ - The PDF (pop directional formatting) formatting character; closes LRO. In each DIV of the test: - - the first BDI, having no characters with strong direction, should inherit the parent direction; + - the first BDI, having no characters with strong direction, should be LTR by default; - the second BDI, having an LTR character first, should be LTR by default; - the third BDI, having an RTL character first, should be RTL by default. </div> <div class="test"> <div dir="ltr"><bdi>[:)]</bdi>, <bdi>[+- a ב]</bdi>, <bdi>[1 ג d]</bdi>...</div> - <div dir="rtl"><bdi>[(:]</bdi>, <bdi>[+- a ב]</bdi>, <bdi>[1 ג d]</bdi>...</div> + <div dir="rtl"><bdi>[:)]</bdi>, <bdi>[+- a ב]</bdi>, <bdi>[1 ג d]</bdi>...</div> </div> <div class="ref"> <div dir="ltr">‭[:)], [+- a ב], [d ג 1]...‬</div> diff --git a/testing/web-platform/tests/html/syntax/speculative-parsing/tools/generate.py b/testing/web-platform/tests/html/syntax/speculative-parsing/tools/generate.py index 3457f94d70..f0db885814 100755 --- a/testing/web-platform/tests/html/syntax/speculative-parsing/tools/generate.py +++ b/testing/web-platform/tests/html/syntax/speculative-parsing/tools/generate.py @@ -680,7 +680,7 @@ def generate_tests(testcase, tentative): html_testcase_markup = template_testcase_markup.format(url_wptserve_sub) html_nonspeculative_testcase_markup = template_nonspeculative_testcase_markup.format(url_wptserve_sub) - js_testcase_markup = template_testcase_markup.format(url_js_sub).replace(u"</script>", u"<\/script>").replace(u"<meta charset", u"<meta\ charset") + js_testcase_markup = template_testcase_markup.format(url_js_sub).replace(u"</script>", u"<\\/script>").replace(u"<meta charset", u"<meta\\ charset") if test_nonspeculative == u'true': nonspeculative = template_nonspeculative.format(preamble=preamble, encoding_decl=encoding_decl, title=title, nonspeculative_testcase_markup=html_nonspeculative_testcase_markup, delay=delay) diff --git a/testing/web-platform/tests/html/webappapis/system-state-and-capabilities/the-navigator-object/navigator_user_agent.https.html b/testing/web-platform/tests/html/webappapis/system-state-and-capabilities/the-navigator-object/navigator_user_agent.https.html index 10b3dd2249..3fbe3eaa62 100644 --- a/testing/web-platform/tests/html/webappapis/system-state-and-capabilities/the-navigator-object/navigator_user_agent.https.html +++ b/testing/web-platform/tests/html/webappapis/system-state-and-capabilities/the-navigator-object/navigator_user_agent.https.html @@ -20,14 +20,14 @@ assert_equals(typeof uaData.mobile, "boolean", "mobile should be a boolean"); const highEntropyData = await uaData.getHighEntropyValues([ - "platformVersion", "architecture", "model", "uaFullVersion", "fullVersionList", "formFactor"]); + "platformVersion", "architecture", "model", "uaFullVersion", "fullVersionList", "formFactors"]); assert_equals(typeof highEntropyData["platform"], "string", "Platform brand should be a string"); assert_equals(typeof highEntropyData["platformVersion"], "string", "Platform version should be a string"); assert_equals(typeof highEntropyData["architecture"], "string", "Architecture should be a string"); assert_equals(typeof highEntropyData["model"], "string", "Model should be a string"); assert_equals(typeof highEntropyData["uaFullVersion"], "string", "UAFullVersion should be a string"); - for (formFactor of highEntropyData['formFactor']) { - assert_equals(typeof formFactor, "string", "Each FormFactor should be a string"); + for (formFactor of highEntropyData['formFactors']) { + assert_equals(typeof formFactor, "string", "Each FormFactors value should be a string"); } for (brandVersionPair of highEntropyData['fullVersionList']) { assert_equals(typeof brandVersionPair.brand, "string", "brand should be a string"); @@ -40,7 +40,7 @@ assert_false("architecture" in highEntropyData2, "Architecture should be an empty string"); assert_false("model" in highEntropyData2, "Model should be an empty string"); assert_false("uaFullVersion" in highEntropyData2, "UAFullVersion should be an empty string"); - assert_false("formFactor" in highEntropyData2, "FormFactor should be an empty string"); + assert_false("formFactors" in highEntropyData2, "FormFactors should be an empty array"); assert_false("fullVersionList" in highEntropyData2, "fullVersionList should not be present"); let finalPromise = uaData.getHighEntropyValues([]).then(() => { assert_true(didMicrotaskRun, "getHighEntropyValues queued on a task"); |