click-focus-delegatesFocus-click.html (4982B)
1 <!DOCTYPE html> 2 <meta charset="utf-8"> 3 <title>HTML Test: click on shadow host with delegatesFocus</title> 4 <script src="/resources/testharness.js"></script> 5 <script src="/resources/testharnessreport.js"></script> 6 <script src="/resources/testdriver.js"></script> 7 <script src="/resources/testdriver-vendor.js"></script> 8 <script src="resources/shadow-utils.js"></script> 9 10 <body> 11 <div id="host"> 12 <div id="slotted">slotted</div> 13 </div> 14 <div id="outside">outside</div> 15 </body> 16 17 <script> 18 const host = document.getElementById("host"); 19 const slotted = document.getElementById("slotted"); 20 21 const shadowRoot = host.attachShadow({ mode: "open", delegatesFocus: true }); 22 const aboveSlot = document.createElement("div"); 23 aboveSlot.innerText = "aboveSlot"; 24 const slot = document.createElement("slot"); 25 shadowRoot.appendChild(aboveSlot); 26 shadowRoot.appendChild(slot); 27 28 const elementsInFlatTreeOrder = [host, aboveSlot, slot, slotted, outside]; 29 30 // Final structure: 31 // <div #host> (delegatesFocus=true) 32 // #shadowRoot 33 // <div #aboveSlot> 34 // <slot #slot> 35 // (slotted) <div #slotted> 36 // <div #outside> 37 38 function setAllTabIndex(value) { 39 setTabIndex(elementsInFlatTreeOrder, value); 40 } 41 42 function removeAllTabIndex() { 43 removeTabIndex(elementsInFlatTreeOrder); 44 } 45 46 function resetTabIndexAndFocus() { 47 removeAllTabIndex(); 48 resetFocus(document); 49 resetFocus(shadowRoot); 50 } 51 52 test(() => { 53 resetTabIndexAndFocus(); 54 setAllTabIndex(0); 55 host.click(); 56 assert_equals(shadowRoot.activeElement, null); 57 assert_equals(document.activeElement, document.body); 58 }, "call click() on host with delegatesFocus, all tabindex=0"); 59 60 test(() => { 61 resetTabIndexAndFocus(); 62 setAllTabIndex(0); 63 slotted.click(); 64 assert_equals(shadowRoot.activeElement, null); 65 assert_equals(document.activeElement, document.body); 66 }, "call click() on slotted element in delegatesFocus shadow tree, all tabindex=0"); 67 68 function createNestedHosts(outerDelegatesFocus, innerDelegatesFocus) { 69 // Structure: 70 // <div> outerHost 71 // <input> outerLightChild 72 // #shadowRoot outerShadow delegatesFocus=true 73 // <div> spacer 74 // <span> innerHost 75 // #shadowRoot innerShadow delegatesFocus=true/false 76 // <input> innerShadowChild 77 // <input> outerShadowChild 78 const outerHost = document.createElement('div'); 79 const outerLightChild = document.createElement('input'); 80 outerHost.appendChild(outerLightChild); 81 const innerHost = document.createElement('span'); 82 const outerShadow = outerHost.attachShadow({mode: 'closed', delegatesFocus:outerDelegatesFocus}); 83 84 const spacer = document.createElement("div"); 85 spacer.style = "height: 1000px;"; 86 outerShadow.appendChild(spacer); 87 88 outerShadow.appendChild(innerHost); 89 const outerShadowChild = document.createElement('input'); 90 outerShadow.appendChild(outerShadowChild); 91 92 const innerShadow = innerHost.attachShadow({mode: 'closed', delegatesFocus:innerDelegatesFocus}); 93 const innerShadowChild = document.createElement('input'); 94 innerShadow.appendChild(innerShadowChild); 95 96 document.body.insertBefore(outerHost, document.body.firstChild); 97 return {outerHost: outerHost, 98 outerLightChild: outerLightChild, 99 outerShadow: outerShadow, 100 outerShadowChild: outerShadowChild, 101 innerHost: innerHost, 102 innerShadow: innerShadow, 103 innerShadowChild: innerShadowChild}; 104 } 105 106 promise_test(async function() { 107 const dom = createNestedHosts(true, true); 108 await test_driver.click(dom.outerHost); 109 assert_equals(document.activeElement, dom.outerHost); 110 assert_equals(dom.outerShadow.activeElement, dom.innerHost); 111 assert_equals(dom.innerShadow.activeElement, dom.innerShadowChild); 112 }, "click on the host with delegatesFocus with another host with delegatesFocus and a focusable child"); 113 114 promise_test(async function() { 115 const dom = createNestedHosts(true, false); 116 await test_driver.click(dom.outerHost); 117 assert_equals(document.activeElement, dom.outerHost); 118 assert_equals(dom.outerShadow.activeElement, dom.outerShadowChild); 119 assert_equals(dom.innerShadow.activeElement, null); 120 }, "click on the host with delegatesFocus with another host with no delegatesFocus and a focusable child"); 121 122 promise_test(async function() { 123 const dom = createNestedHosts(false, true); 124 await test_driver.click(dom.outerHost); 125 assert_equals(document.activeElement, document.body); 126 assert_equals(dom.outerShadow.activeElement, null); 127 assert_equals(dom.innerShadow.activeElement, null); 128 }, "click on the host with no delegatesFocus with another host with delegatesFocus and a focusable child"); 129 130 promise_test(async function() { 131 const dom = createNestedHosts(false, false); 132 await test_driver.click(dom.outerHost); 133 assert_equals(document.activeElement, document.body); 134 assert_equals(dom.outerShadow.activeElement, null); 135 assert_equals(dom.innerShadow.activeElement, null); 136 }, "click on the host with no delegatesFocus with another host with no delegatesFocus and a focusable child"); 137 138 </script>