summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/shadow-dom/focus/focus-pseudo-matches-on-shadow-host.html
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /testing/web-platform/tests/shadow-dom/focus/focus-pseudo-matches-on-shadow-host.html
parentInitial commit. (diff)
downloadthunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz
thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/shadow-dom/focus/focus-pseudo-matches-on-shadow-host.html')
-rw-r--r--testing/web-platform/tests/shadow-dom/focus/focus-pseudo-matches-on-shadow-host.html122
1 files changed, 122 insertions, 0 deletions
diff --git a/testing/web-platform/tests/shadow-dom/focus/focus-pseudo-matches-on-shadow-host.html b/testing/web-platform/tests/shadow-dom/focus/focus-pseudo-matches-on-shadow-host.html
new file mode 100644
index 0000000000..34f8c01294
--- /dev/null
+++ b/testing/web-platform/tests/shadow-dom/focus/focus-pseudo-matches-on-shadow-host.html
@@ -0,0 +1,122 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
+<meta name="assert" content=":focus should match a shadow host which contains the focused element">
+<link rel="help" href="https://html.spec.whatwg.org/#element-has-the-focus">
+<link rel="help=" href="https://bugs.webkit.org/show_bug.cgi?id=202432">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<input id="defaultFocus" autofocus>
+<div id="log"></div>
+<div id="container"></div>
+<script>
+
+let focusedDefault = false;
+function didFocusDefault() { }
+function handleFocus() {
+ if (!focusedDefault) {
+ // Use step_timeout here to avoid nested focusing steps.
+ // For example, <input id="defaultFocus" autofocus> could run scripts
+ // while it's autofocusing which may run the tests, so that the
+ // focus() usage in the tests becomes nested focusing steps.
+ step_timeout(function() {
+ testInMode('open', false);
+ testInMode('open', true);
+ testInMode('closed', false);
+ testInMode('closed', true);
+ }, 0);
+ }
+ focusedDefault = true;
+ didFocusDefault();
+}
+defaultFocus.addEventListener('focus', handleFocus);
+
+function prepare(test)
+{
+ test.add_cleanup(() => {
+ defaultFocus.focus();
+ container.textContent = '';
+ });
+ return new Promise((resolve) => {
+ if (focusedDefault)
+ resolve();
+ else
+ didFocusDefault = resolve;
+ });
+}
+
+function testInMode(mode, delegatesFocus) {
+ const modeString = `{mode:${mode}, delegatesFocus:${delegatesFocus}}`;
+ promise_test(async function () {
+ await prepare(this);
+ const host = document.createElement('div');
+ container.appendChild(host);
+ const shadowRoot = host.attachShadow({mode, delegatesFocus});
+ shadowRoot.innerHTML = '<input>';
+ assert_equals(document.activeElement, defaultFocus);
+ assert_equals(shadowRoot.activeElement, null);
+ assert_false(host.matches(':focus'));
+ }, `:focus must not match a shadow host with ${modeString} shadow root that does not contain the focused element`);
+
+ promise_test(async function () {
+ await prepare(this);
+ const host = document.createElement('div');
+ document.body.appendChild(host);
+ const shadowRoot = host.attachShadow({mode, delegatesFocus});
+ shadowRoot.innerHTML = '<input>';
+ shadowRoot.firstChild.focus();
+ assert_equals(document.activeElement, host);
+ assert_equals(shadowRoot.activeElement, shadowRoot.firstChild);
+ assert_true(host.matches(':focus'));
+ }, `:focus must match a shadow host with ${modeString} shadow root that contains the focused element`);
+
+ promise_test(async function () {
+ await prepare(this);
+ const host = document.createElement('div');
+ container.appendChild(host);
+ const shadowRoot = host.attachShadow({mode, delegatesFocus});
+ shadowRoot.innerHTML = '<slot>';
+ host.innerHTML = '<input>';
+ host.firstChild.focus();
+ assert_equals(document.activeElement, host.firstChild);
+ assert_equals(shadowRoot.activeElement, null);
+ assert_false(host.matches(':focus'));
+ }, `:focus must not match a shadow host with ${modeString} shadow root contains the focused element assigned to a slot`);
+
+ promise_test(async function() {
+ await prepare(this);
+ const host1 = document.body.appendChild(document.createElement('div'));
+ const shadowRoot1 = host1.attachShadow({mode, delegatesFocus});
+ const host2 = shadowRoot1.appendChild(document.createElement('div'));
+ const shadowRoot2 = host2.attachShadow({mode, delegatesFocus});
+ shadowRoot2.innerHTML = '<input>';
+ shadowRoot2.firstChild.focus();
+ assert_equals(document.activeElement, host1);
+ assert_equals(shadowRoot1.activeElement, host2);
+ assert_equals(shadowRoot2.activeElement, shadowRoot2.firstChild);
+ assert_true(host1.matches(':focus'));
+ assert_true(host2.matches(':focus'));
+ }, `:focus must match all shadow hosts which are ancestors of a foccused element; ${modeString}`);
+
+ promise_test(async function() {
+ await prepare(this);
+ const host = document.body.appendChild(document.createElement('div'));
+ const shadowRoot = host.attachShadow({mode, delegatesFocus});
+ shadowRoot.innerHTML = '<input>';
+ const input = shadowRoot.firstChild;
+ const outer = document.body.appendChild(document.createElement('div'));
+
+ assert_false(host.matches(':focus'));
+ input.focus();
+ assert_true(host.matches(':focus'));
+ outer.appendChild(input);
+ assert_false(host.matches(':focus'));
+ }, `:focus behavior on tree structure changes; ${modeString}`);
+}
+
+</script>
+</body>
+</html>