| <!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"> |
| <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 checkFocusMatch() { |
| if (defaultFocus.matches(':focus')) { |
| focusedDefault = true; |
| didFocusDefault(); |
| } else |
| setTimeout(checkFocusMatch, 100); |
| } |
| defaultFocus.addEventListener('focus', checkFocusMatch); |
| |
| function prepare(test) |
| { |
| test.add_cleanup(() => { |
| defaultFocus.focus(); |
| container.textContent = ''; |
| }); |
| return new Promise((resolve) => { |
| if (focusedDefault) |
| resolve(); |
| else |
| didFocusDefault = resolve; |
| }); |
| } |
| |
| function testInMode(mode) { |
| promise_test(async function () { |
| await prepare(this); |
| const host = document.createElement('div'); |
| container.appendChild(host); |
| const shadowRoot = host.attachShadow({mode}); |
| 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 ${mode} mode 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}); |
| 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 ${mode} mode 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}); |
| 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 ${mode} mode shadow root contains the focused element assigned to a slot`); |
| |
| } |
| |
| testInMode('open'); |
| testInMode('closed'); |
| |
| </script> |
| </body> |
| </html> |