diff options
Diffstat (limited to 'testing/web-platform/tests/shadow-dom/focus/focus-autofocus.html')
-rw-r--r-- | testing/web-platform/tests/shadow-dom/focus/focus-autofocus.html | 338 |
1 files changed, 338 insertions, 0 deletions
diff --git a/testing/web-platform/tests/shadow-dom/focus/focus-autofocus.html b/testing/web-platform/tests/shadow-dom/focus/focus-autofocus.html new file mode 100644 index 0000000000..75a50b84c6 --- /dev/null +++ b/testing/web-platform/tests/shadow-dom/focus/focus-autofocus.html @@ -0,0 +1,338 @@ +<!DOCTYPE html> +<html> +<head> +<meta name="author" title="Sean Feng" href="mailto:sefeng@mozilla.com"> +<meta name="assert" content="Elements with autofocus should have high precedence over other elements for delegates focus"> +<link rel="help" href="https://github.com/whatwg/html/pull/6990"> +<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="resources/shadow-utils.js"></script> +</head> + +<body> + <script> + function createShadowDOMTree() { + // <div #host> (delegatesFocus = true) + // #shadowRoot + // <div #firstOuterDiv> + // <div #innertHost> + // #shadowRoot + // <div #firstInnerDiv> + // <div #secondInnerDiv> + // <div #secondOuterDiv> + const host = document.createElement("div"); + host.setAttribute("id", "host"); + const outerRoot = host.attachShadow({mode: "open", delegatesFocus: true}); + + const firstOuterDiv = document.createElement("div"); + + const innerHost = document.createElement("div"); + const innerRoot = innerHost.attachShadow({mode: "open"}); + const firstInnerDiv = document.createElement("div"); + const secondInnerDiv = document.createElement("div"); + innerRoot.appendChild(firstInnerDiv); + innerRoot.appendChild(secondInnerDiv); + + const secondOuterDiv = document.createElement("div"); + + outerRoot.appendChild(firstOuterDiv); + outerRoot.appendChild(innerHost); + outerRoot.appendChild(secondOuterDiv); + document.body.appendChild(host); + return [ + host, + outerRoot, + firstOuterDiv, + secondOuterDiv, + innerHost, + innerRoot, + firstInnerDiv, + secondInnerDiv + ] + } + + function resetShadowDOMTree() { + const host = document.getElementById("host"); + if (host) { + host.remove(); + } + return createShadowDOMTree(); + } + + function resetTabIndexAndFocus( + firstOuterDiv, + secondOuterDiv, + firstInnerDiv, + secondInnerDiv, + outerRoot, + innerRoot + ) { + firstOuterDiv.removeAttribute("tabindex"); + firstOuterDiv.removeAttribute("autofocus"); + + secondOuterDiv.removeAttribute("tabindex"); + secondOuterDiv.removeAttribute("autofocus"); + + firstInnerDiv.removeAttribute("tabindex"); + firstInnerDiv.removeAttribute("autofocus"); + + secondInnerDiv.removeAttribute("tabindex"); + secondInnerDiv.removeAttribute("autofocus"); + + resetFocus(document); + resetFocus(outerRoot); + resetFocus(innerRoot); + } + + function setAllTabIndexTo( + firstOuterDiv, + secondOuterDiv, + firstInnerDiv, + secondInnerDiv, + tabIndex + ) { + firstOuterDiv.tabIndex = tabIndex; + secondOuterDiv.tabIndex = tabIndex; + firstInnerDiv.tabIndex = tabIndex; + secondInnerDiv.tabIndex = tabIndex; + } + + test(function() { + const [ + host, + outerRoot, + firstOuterDiv, + secondOuterDiv, + innerHost, + innerRoot, + firstInnerDiv, + secondInnerDiv + ] = resetShadowDOMTree(); + + resetTabIndexAndFocus( + firstOuterDiv, + secondOuterDiv, + firstInnerDiv, + secondInnerDiv, + outerRoot, + innerRoot + ); + + setAllTabIndexTo( + firstOuterDiv, + secondOuterDiv, + firstInnerDiv, + secondInnerDiv, + 0 + ); + + // <div #host> (delegatesFocus = true) + // #shadowRoot + // <div tabIndex=0 #firstOuterDiv> + // <div #innertHost> + // #shadowRoot + // <div tabIndex=0 #firstInnerDiv> + // <div tabIndex=0 #secondInnerDiv> + // <div tabIndex=0 autofocus #secondOuterDiv> + secondOuterDiv.autofocus = true; + secondOuterDiv.setAttribute("autofocus", true); + + host.focus(); + + assert_equals(document.activeElement, host); + assert_equals(outerRoot.activeElement, secondOuterDiv); + }, "The second input should be focused since it has autofocus"); + + test(function() { + const [ + host, + outerRoot, + firstOuterDiv, + secondOuterDiv, + innerHost, + innerRoot, + firstInnerDiv, + secondInnerDiv + ] = resetShadowDOMTree(); + + resetTabIndexAndFocus( + firstOuterDiv, + secondOuterDiv, + firstInnerDiv, + secondInnerDiv, + outerRoot, + innerRoot + ); + + // <div #host> (delegatesFocus = true) + // #shadowRoot + // <div #firstOuterDiv> + // <div #innertHost> + // #shadowRoot + // <div tabIndex=0 #firstInnerDiv> + // <div tabIndex=0 autofocus #secondInnerDiv> + // <div #secondOuterDiv> + firstInnerDiv.tabIndex = 0; + secondInnerDiv.tabIndex = 0; + secondInnerDiv.setAttribute("autofocus", true); + + host.focus(); + assert_equals(document.activeElement, document.body); + assert_equals(outerRoot.activeElement, null); + }, "Focus should not be delegated to the autofocus element because the inner host doesn't have delegates focus"); + + test(function() { + const [ + host, + outerRoot, + firstOuterDiv, + secondOuterDiv, + innerHost, + innerRoot, + firstInnerDiv, + secondInnerDiv + ] = resetShadowDOMTree(); + + resetTabIndexAndFocus( + firstOuterDiv, + secondOuterDiv, + firstInnerDiv, + secondInnerDiv, + outerRoot, + innerRoot + ); + + const newInnerHost = document.createElement("div"); + const newInnerRoot = newInnerHost.attachShadow({mode: "open", delegatesFocus: true}); + const newFirstInnerDiv = document.createElement("div"); + const newSecondInnerDiv = document.createElement("div"); + newFirstInnerDiv.setAttribute("tabIndex", 0); + newSecondInnerDiv.setAttribute("tabIndex", 0); + + newSecondInnerDiv.setAttribute("autofocus", true); + newInnerRoot.appendChild(newFirstInnerDiv); + newInnerRoot.appendChild(newSecondInnerDiv); + + // <div #host> (delegatesFocus = true) + // #shadowRoot + // <div #firstOuterDiv> + // <div #innertHost> (delegatesFocus = true) + // #shadowRoot + // <div tabIndex=0 #newFirstInnerDiv> + // <div tabIndex=0 autofocus #newSecondInnerDiv> + // <div #secondOuterDiv> + outerRoot.replaceChild(newInnerHost, innerHost); + + host.focus(); + + assert_equals(document.activeElement, host); + assert_equals(outerRoot.activeElement, newInnerHost); + assert_equals(newInnerRoot.activeElement, newSecondInnerDiv); + }, "Focus should be delegated to the autofocus element when the inner host has delegates focus"); + + test(function() { + const [ + host, + outerRoot, + firstOuterDiv, + secondOuterDiv, + innerHost, + innerRoot, + firstInnerDiv, + secondInnerDiv + ] = resetShadowDOMTree(); + + resetTabIndexAndFocus( + firstOuterDiv, + secondOuterDiv, + firstInnerDiv, + secondInnerDiv, + outerRoot, + innerRoot + ); + + // <div #host> (delegatesFocus = true) + // #shadowRoot + // <slot> + // (slotted) <div autofocus tabIndex=0 #slottedAutofocus></div> + // <div tabIndex=0 #firstOuterDiv> + // <div #innertHost> + // #shadowRoot + // <div tabIndex=0 #firstInnerDiv> + // <div tabIndex=0 autofocus #secondInnerDiv> + // <div #secondOuterDiv> + + const slottedAutofocus = document.createElement("div"); + slottedAutofocus.tabIndex = 0; + slottedAutofocus.setAttribute("autofocus", true); + host.appendChild(slottedAutofocus); + + const slot = document.createElement("slot"); + outerRoot.insertBefore(slot, firstOuterDiv); + + firstOuterDiv.tabIndex = 0; + + host.focus(); + assert_equals(document.activeElement, host); + assert_equals(outerRoot.activeElement, firstOuterDiv); + }, "Focus should not be delegated to the slotted elements"); + + test(function() { + const [ + host, + outerRoot, + firstOuterDiv, + secondOuterDiv, + innerHost, + innerRoot, + firstInnerDiv, + secondInnerDiv + ] = resetShadowDOMTree(); + + resetTabIndexAndFocus( + firstOuterDiv, + secondOuterDiv, + firstInnerDiv, + secondInnerDiv, + outerRoot, + innerRoot + ); + + // <div #host> (delegatesFocus = true) + // #shadowRoot + // <div #firstOuterDiv> + // <div tabIndex=0 #firstNestedDiv> + // <div tabIndex=0 #secondNestedDiv> + // <div tabIndex=0 autofocus #thirdNestedDiv> + // <div #innertHost> + // #shadowRoot + // <div #firstInnerDiv> + // <div #secondInnerDiv> + // <div autofocus tabIndex=0 #secondOuterDiv> + + secondInnerDiv.tabIndex = 0; + secondInnerDiv.setAttribute("autofocus", true); + + const firstNestedDiv = document.createElement("div"); + const secondNestedDiv = document.createElement("div"); + const thirdNestedDiv = document.createElement("div"); + + firstNestedDiv.tabIndex = 0; + secondNestedDiv.tabIndex = 0; + thirdNestedDiv.tabIndex = 0; + thirdNestedDiv.setAttribute("autofocus", true); + + firstOuterDiv.appendChild(firstNestedDiv); + firstNestedDiv.appendChild(secondNestedDiv); + secondNestedDiv.appendChild(thirdNestedDiv); + + host.focus(); + + assert_equals(document.activeElement, host); + assert_equals(outerRoot.activeElement, thirdNestedDiv); + }, "Focus should be delegated to the nested div which has autofocus based on the tree order"); + </script> +</body> +</html> |