tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

focus-navigation-with-delegatesFocus.html (9283B)


      1 <!DOCTYPE html>
      2 <meta name="timeout" content="long">
      3 <script src="/resources/testharness.js"></script>
      4 <script src="/resources/testharnessreport.js"></script>
      5 <script src="/resources/testdriver.js"></script>
      6 <script src="/resources/testdriver-vendor.js"></script>
      7 <script src="/resources/testdriver-actions.js"></script>
      8 <script src="resources/shadow-dom.js"></script>
      9 <script src="resources/focus-utils.js"></script>
     10 
     11 <p>This tests TAB focus navigation with delegatesFocus flag on shadow hosts</p>
     12 <pre id="console"></pre>
     13 <div id="sandbox"></div>
     14 <script>
     15 
     16 function prepareDOMTree(parent, mode, tabindex, delegatesFocus) {
     17    parent.innerHTML = `
     18      <div id="testform">
     19        <input id="input-before">
     20        <div id="host-div">
     21          <input id="inner-input">
     22        </div>
     23        <input id="input-after">
     24      </div>
     25    `;
     26    const hostDiv = document.getElementById('host-div');
     27    const shadowRoot = hostDiv.attachShadow({ mode, delegatesFocus });
     28 
     29    const inputBefore = document.getElementById('input-before');
     30    const innerInput = document.getElementById('inner-input');
     31    const inputAfter = document.getElementById('input-after');
     32    shadowRoot.appendChild(innerInput);
     33 
     34    if (tabindex !== null)
     35      hostDiv.tabIndex = tabindex;
     36 
     37    return {
     38      hostDiv,
     39      shadowRoot,
     40      inputBefore,
     41      innerInput,
     42      inputAfter,
     43    };
     44 
     45 }
     46 
     47 promise_test(async () => {
     48  const { shadowRoot, hostDiv } = prepareDOMTree(sandbox, 'open', null, false);
     49  assert_false(shadowRoot.delegatesFocus);
     50  assert_equals(hostDiv.tabIndex, -1);
     51 
     52  const elements = [
     53    'input-before',
     54    'host-div/inner-input',
     55    'input-after',
     56  ];
     57 
     58  await assert_focus_navigation_bidirectional(elements);
     59 }, 'Testing tab navigation order with mode open, no tabindex and delegatesFocus=false.');
     60 
     61 promise_test(async () => {
     62  const { shadowRoot, hostDiv } = prepareDOMTree(sandbox, 'open', null, true);
     63  assert_true(shadowRoot.delegatesFocus);
     64  assert_equals(hostDiv.tabIndex, -1);
     65 
     66  const elements = [
     67    'input-before',
     68    'host-div/inner-input',
     69    'input-after',
     70  ];
     71 
     72  await assert_focus_navigation_bidirectional(elements);
     73 }, 'Testing tab navigation order with mode open, no tabindex and delegatesFocus=true.');
     74 
     75 promise_test(async () => {
     76  const { shadowRoot, hostDiv } = prepareDOMTree(sandbox, 'open', 0, false);
     77  assert_false(shadowRoot.delegatesFocus);
     78  assert_equals(hostDiv.tabIndex, 0);
     79 
     80  const elements = [
     81    'input-before',
     82    'host-div',
     83    'host-div/inner-input',
     84    'input-after',
     85  ];
     86 
     87  await assert_focus_navigation_bidirectional(elements);
     88 }, 'Testing tab navigation order with mode open, tabindex=0 and delegatesFocus=false.');
     89 
     90 promise_test(async () => {
     91  const { shadowRoot, hostDiv } = prepareDOMTree(sandbox, 'open', 0, true);
     92  assert_true(shadowRoot.delegatesFocus);
     93  assert_equals(hostDiv.tabIndex, 0);
     94 
     95  const elements = [
     96    'input-before',
     97    // 'host-div', // should skip host when delegatesFocus=true
     98    'host-div/inner-input',
     99    'input-after',
    100  ];
    101 
    102  await assert_focus_navigation_bidirectional(elements);
    103 }, 'Testing tab navigation order with mode open, tabindex=0 and delegatesFocus=true.');
    104 
    105 promise_test(async () => {
    106  const { shadowRoot, hostDiv } = prepareDOMTree(sandbox, 'open', -1, false);
    107  assert_false(shadowRoot.delegatesFocus);
    108  assert_equals(hostDiv.tabIndex, -1);
    109 
    110  const elements = [
    111    'input-before',
    112    'input-after',
    113  ];
    114 
    115  await assert_focus_navigation_bidirectional(elements);
    116 }, 'Testing tab navigation order with mode open, tabindex=-1 and delegatesFocus=false.');
    117 
    118 promise_test(async () => {
    119  const { shadowRoot, hostDiv } = prepareDOMTree(sandbox, 'open', -1, true);
    120  assert_true(shadowRoot.delegatesFocus);
    121  assert_equals(hostDiv.tabIndex, -1);
    122 
    123  const elements = [
    124    'input-before',
    125    // 'host-div/inner-input', // The whole shadow tree should be skipped
    126    'input-after',
    127  ];
    128 
    129  await assert_focus_navigation_bidirectional(elements);
    130 }, 'Testing tab navigation order with mode open, tabindex=-1 and delegatesFocus=true.');
    131 
    132 promise_test(async () => {
    133  const { shadowRoot, hostDiv } = prepareDOMTree(sandbox, 'open', 1, false);
    134  assert_false(shadowRoot.delegatesFocus);
    135  assert_equals(hostDiv.tabIndex, 1);
    136 
    137  const elements = [
    138    'host-div',
    139    'host-div/inner-input',
    140    'input-before',
    141    'input-after',
    142  ];
    143 
    144  await assert_focus_navigation_bidirectional(elements);
    145 }, 'Testing tab navigation order with mode open, tabindex=1 and delegatesFocus=false.');
    146 
    147 promise_test(async () => {
    148  const { shadowRoot, hostDiv } = prepareDOMTree(sandbox, 'open', 1, true);
    149  assert_true(shadowRoot.delegatesFocus);
    150  assert_equals(hostDiv.tabIndex, 1);
    151 
    152  const elements = [
    153    // 'host-div', // should skip host when delegatesFocus=true
    154    'host-div/inner-input',
    155    'input-before',
    156    'input-after',
    157  ];
    158 
    159  await assert_focus_navigation_bidirectional(elements);
    160 }, 'Testing tab navigation order with mode open, tabindex=1 and delegatesFocus=true.');
    161 
    162 
    163 promise_test(async () => {
    164  const {
    165    hostDiv,
    166    shadowRoot,
    167    inputBefore,
    168    innerInput,
    169    inputAfter,
    170  } = prepareDOMTree(sandbox, 'closed', null, false);
    171  assert_false(shadowRoot.delegatesFocus);
    172  assert_equals(hostDiv.tabIndex, -1);
    173 
    174  const elements = [
    175    [inputBefore],
    176    [innerInput, shadowRoot],
    177    [inputAfter],
    178  ];
    179 
    180  await assert_focus_navigation_bidirectional_with_shadow_root(elements, false);
    181 }, 'Testing tab navigation order with mode closed, no tabindex and delegatesFocus=false.');
    182 
    183 promise_test(async () => {
    184  const {
    185    hostDiv,
    186    shadowRoot,
    187    inputBefore,
    188    innerInput,
    189    inputAfter,
    190  } = prepareDOMTree(sandbox, 'closed', null, true);
    191  assert_true(shadowRoot.delegatesFocus);
    192  assert_equals(hostDiv.tabIndex, -1);
    193 
    194  const elements = [
    195    [inputBefore],
    196    [innerInput, shadowRoot],
    197    [inputAfter],
    198  ];
    199 
    200  await assert_focus_navigation_bidirectional_with_shadow_root(elements, false);
    201 }, 'Testing tab navigation order with mode closed, no tabindex and delegatesFocus=true.');
    202 
    203 promise_test(async () => {
    204  const {
    205    hostDiv,
    206    shadowRoot,
    207    inputBefore,
    208    innerInput,
    209    inputAfter,
    210  } = prepareDOMTree(sandbox, 'closed', 0, false);
    211  assert_false(shadowRoot.delegatesFocus);
    212  assert_equals(hostDiv.tabIndex, 0);
    213 
    214  const elements = [
    215    [inputBefore],
    216    [hostDiv],
    217    [innerInput, shadowRoot],
    218    [inputAfter],
    219  ];
    220 
    221  await assert_focus_navigation_bidirectional_with_shadow_root(elements, false);
    222 }, 'Testing tab navigation order with mode closed, tabindex=0 and delegatesFocus=false.');
    223 
    224 promise_test(async () => {
    225  const {
    226    hostDiv,
    227    shadowRoot,
    228    inputBefore,
    229    innerInput,
    230    inputAfter,
    231  } = prepareDOMTree(sandbox, 'closed', 0, true);
    232  assert_true(shadowRoot.delegatesFocus);
    233  assert_equals(hostDiv.tabIndex, 0);
    234 
    235  const elements = [
    236    [inputBefore],
    237    // [hostDiv], // should skip host when delegatesFocus=true
    238    [innerInput, shadowRoot],
    239    [inputAfter],
    240  ];
    241 
    242  await assert_focus_navigation_bidirectional_with_shadow_root(elements, false);
    243 }, 'Testing tab navigation order with mode closed, tabindex=0 and delegatesFocus=true.');
    244 
    245 promise_test(async () => {
    246  const {
    247    hostDiv,
    248    shadowRoot,
    249    inputBefore,
    250    innerInput,
    251    inputAfter,
    252  } = prepareDOMTree(sandbox, 'closed', -1, false);
    253  assert_false(shadowRoot.delegatesFocus);
    254  assert_equals(hostDiv.tabIndex, -1);
    255 
    256  const elements = [
    257    [inputBefore],
    258    [inputAfter],
    259  ];
    260 
    261  await assert_focus_navigation_bidirectional_with_shadow_root(elements, false);
    262 }, 'Testing tab navigation order with mode closed, tabindex=-1 and delegatesFocus=false.');
    263 
    264 promise_test(async () => {
    265  const {
    266    hostDiv,
    267    shadowRoot,
    268    inputBefore,
    269    innerInput,
    270    inputAfter,
    271  } = prepareDOMTree(sandbox, 'closed', -1, true);
    272  assert_true(shadowRoot.delegatesFocus);
    273  assert_equals(hostDiv.tabIndex, -1);
    274 
    275  const elements = [
    276    [inputBefore],
    277    // [innerInput, shadowRoot], // The whole shadow tree should be skipped
    278    [inputAfter],
    279  ];
    280 
    281  await assert_focus_navigation_bidirectional_with_shadow_root(elements, false);
    282 }, 'Testing tab navigation order with mode closed, tabindex=-1 and delegatesFocus=true.');
    283 
    284 promise_test(async () => {
    285  const {
    286    hostDiv,
    287    shadowRoot,
    288    inputBefore,
    289    innerInput,
    290    inputAfter,
    291  } = prepareDOMTree(sandbox, 'closed', 1, false);
    292  assert_false(shadowRoot.delegatesFocus);
    293  assert_equals(hostDiv.tabIndex, 1);
    294 
    295  const elements = [
    296    [hostDiv],
    297    [innerInput, shadowRoot],
    298    [inputBefore],
    299    [inputAfter],
    300  ];
    301 
    302  await assert_focus_navigation_bidirectional_with_shadow_root(elements, false);
    303 }, 'Testing tab navigation order with mode closed, tabindex=1 and delegatesFocus=false.');
    304 
    305 promise_test(async () => {
    306  const {
    307    hostDiv,
    308    shadowRoot,
    309    inputBefore,
    310    innerInput,
    311    inputAfter,
    312  } = prepareDOMTree(sandbox, 'closed', 1, true);
    313  assert_true(shadowRoot.delegatesFocus);
    314  assert_equals(hostDiv.tabIndex, 1);
    315 
    316  const elements = [
    317    // [hostDiv], // should skip host when delegatesFocus=true
    318    [innerInput, shadowRoot],
    319    [inputBefore],
    320    [inputAfter],
    321  ];
    322 
    323  await assert_focus_navigation_bidirectional_with_shadow_root(elements, false);
    324 }, 'Testing tab navigation order with mode closed, tabindex=1 and delegatesFocus=true.');
    325 
    326 
    327 </script>