tor-browser

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

test_shadow_slots.html (20266B)


      1 <!DOCTYPE html>
      2 <html>
      3 
      4 <head>
      5  <title>Test shadow roots with slots</title>
      6 
      7  <link rel="stylesheet" type="text/css"
      8        href="chrome://mochikit/content/tests/SimpleTest/test.css" />
      9 
     10  <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
     11 
     12  <script type="application/javascript"
     13          src="../common.js"></script>
     14  <script type="application/javascript"
     15          src="../role.js"></script>
     16  <script type="application/javascript"
     17          src="../promisified-events.js"></script>
     18 
     19  <script type="application/javascript">
     20    async function _dynamicShadowTest(name, mutationFunc, expectedTree, reorder_targets) {
     21      info(name);
     22 
     23      let container = getNode(name);
     24      let host = container.querySelector('.host');
     25 
     26      document.body.offsetTop;
     27      let event = reorder_targets ?
     28        waitForEvents(reorder_targets.map(target => [EVENT_REORDER, target, name])) :
     29        waitForEvent(EVENT_REORDER, host, name);
     30 
     31      mutationFunc(container, host);
     32 
     33      await event;
     34 
     35      testAccessibleTree(container, expectedTree);
     36 
     37      return true;
     38    }
     39 
     40    async function attachFlatShadow() {
     41      await _dynamicShadowTest("attachFlatShadow",
     42        (container, host) => {
     43          host.attachShadow({ mode: "open" })
     44            .appendChild(container.querySelector('.shadowtree').content.cloneNode(true));
     45        }, { SECTION: [{ SECTION: [{ name: "red"} ] }] });
     46    }
     47 
     48    async function attachOneDeepShadow() {
     49      await _dynamicShadowTest("attachOneDeepShadow",
     50        (container, host) => {
     51          host.attachShadow({ mode: "open" })
     52            .appendChild(container.querySelector('.shadowtree').content.cloneNode(true));
     53        }, { SECTION: [{ SECTION: [{ SECTION: [{ name: "red"} ] }] }] });
     54    }
     55 
     56    async function changeSlotFlat() {
     57      await _dynamicShadowTest("changeSlotFlat",
     58        (container) => {
     59          container.querySelector('.red').removeAttribute('slot');
     60          container.querySelector('.green').setAttribute('slot', 'myslot');
     61        }, { SECTION: [{ SECTION: [{ name: "green"} ] }] });
     62    }
     63 
     64    async function changeSlotOneDeep() {
     65      await _dynamicShadowTest("changeSlotOneDeep",
     66        (container) => {
     67          container.querySelector('.red').removeAttribute('slot');
     68          container.querySelector('.green').setAttribute('slot', 'myslot');
     69        }, { SECTION: [{ SECTION: [{ SECTION: [{ name: "green"} ] }] }] }, ["shadowdiv"]);
     70    }
     71 
     72    // Nested roots and slots
     73    async function changeSlotNested() {
     74      await _dynamicShadowTest("changeSlotNested",
     75        (container) => {
     76          testAccessibleTree(getNode("changeSlotNested"),
     77            { SECTION: [{ SECTION: [{ SECTION: [{ name: "red"} ] }] }] });
     78          container.querySelector('.red').removeAttribute('slot');
     79          container.querySelector('.green').setAttribute('slot', 'myslot');
     80        }, { SECTION: [{ SECTION: [{ SECTION: [{ name: "green"} ] }] }] }, ["shadowdiv"]);
     81    }
     82 
     83    async function changeSlotSingleChild() {
     84      await _dynamicShadowTest("changeSlotSingleChild",
     85        (container) => {
     86          container.querySelector('.red').setAttribute('slot', 'invalid');
     87        }, { SECTION: [{ SECTION: [] }] });
     88    }
     89 
     90    async function changeSlotNoShadow() {
     91      await _dynamicShadowTest("changeSlotNoShadow",
     92        (container) => {
     93          // Make sure changing the slot attribute doesn't remove an element
     94          // even when it remains in the flat tree.
     95          container.querySelector('.red').setAttribute('slot', 'invalid');
     96          // We need a reorder to know when we're done here, so remove another
     97          // child.
     98          container.querySelector('.green').remove();
     99        }, { SECTION: [{ SECTION: [{ name: "red"} ] }] });
    100    }
    101 
    102    // Dynamic mutations to both shadow root and shadow host subtrees
    103    // testing/web-platform/tests/css/css-scoping/shadow-assign-dynamic-001.html
    104    async function assignSlotDynamic() {
    105      await _dynamicShadowTest("assignSlotDynamic",
    106        (container, host) => {
    107          host.shadowRoot.appendChild(container.querySelector('.shadowtree').content.cloneNode(true));
    108          host.appendChild(container.querySelector('.lighttree').content.cloneNode(true));
    109        }, { SECTION: [{ SECTION: [{ name: "slot1"}, { name: "slot2" } ] }] });
    110    }
    111 
    112    // testing/web-platform/tests/css/css-scoping/shadow-fallback-dynamic-001.html
    113    async function shadowFallbackDynamic_1() {
    114      await _dynamicShadowTest("shadowFallbackDynamic_1",
    115        (container, host) => {
    116          host.firstElementChild.remove();
    117        }, { SECTION: [{ SECTION: [{ name: "green"} ] }] });
    118    }
    119 
    120    // testing/web-platform/tests/css/css-scoping/shadow-fallback-dynamic-002.html
    121    async function shadowFallbackDynamic_2() {
    122      await _dynamicShadowTest("shadowFallbackDynamic_2",
    123        (container, host) => {
    124          host.firstElementChild.removeAttribute("slot");
    125        }, { SECTION: [{ SECTION: [{ name: "green"} ] }] });
    126    }
    127 
    128    // testing/web-platform/tests/css/css-scoping/shadow-fallback-dynamic-003.html
    129    async function shadowFallbackDynamic_3() {
    130      await _dynamicShadowTest("shadowFallbackDynamic_3",
    131        (container, host) => {
    132          host.appendChild(container.querySelector(".lighttree").content.cloneNode(true));
    133        }, { SECTION: [{ SECTION: [{ name: "green"} ] }] });
    134    }
    135 
    136    // testing/web-platform/tests/css/css-scoping/shadow-fallback-dynamic-004.html
    137    async function shadowFallbackDynamic_4() {
    138      await _dynamicShadowTest("shadowFallbackDynamic_4",
    139        (container, host) => {
    140          host.shadowRoot.insertBefore(
    141            container.querySelector(".moreshadowtree").
    142              content.cloneNode(true), host.shadowRoot.firstChild);
    143        }, { SECTION: [{ SECTION: [{ name: "slotparent2", children: [{ name: "green"} ] }, { name: "slotparent1" } ] }] });
    144    }
    145 
    146    // testing/web-platform/tests/css/css-scoping/shadow-fallback-dynamic-004.html
    147    // This tests a case when the the slotted element would remain in the same accessible container
    148    async function shadowFallbackDynamic_4_1() {
    149      await _dynamicShadowTest("shadowFallbackDynamic_4_1",
    150        (container, host) => {
    151          host.shadowRoot.insertBefore(
    152            container.querySelector(".moreshadowtree").
    153              content.cloneNode(true), host.shadowRoot.firstChild);
    154        }, { SECTION: [{ SECTION: [ { name: "green"}, { SEPARATOR: [] } ] }] });
    155    }
    156 
    157    // testing/web-platform/tests/css/css-scoping/shadow-fallback-dynamic-005.html
    158    async function shadowFallbackDynamic_5() {
    159      await _dynamicShadowTest("shadowFallbackDynamic_5",
    160        (container, host) => {
    161          host.firstElementChild.setAttribute("slot", "myotherslot");
    162        }, { SECTION: [{ SECTION: [{ name: "green"} ] }] });
    163    }
    164 
    165    // testing/web-platform/tests/css/css-scoping/shadow-reassign-dynamic-002.html
    166    async function shadowReassignDynamic_2() {
    167      await _dynamicShadowTest("shadowReassignDynamic_2",
    168        (container, host) => {
    169          host.shadowRoot.querySelector("slot").setAttribute("name", "myslot");
    170        }, { SECTION: [{ SECTION: [{ name: "green"} ] }] });
    171    }
    172 
    173    // testing/web-platform/tests/css/css-scoping/shadow-reassign-dynamic-003.html
    174    async function shadowReassignDynamic_3() {
    175      await _dynamicShadowTest("shadowReassignDynamic_3",
    176        (container, host) => {
    177          testAccessibleTree(container, { SECTION: [{ SECTION: [{ name: "green"}, { name: "red", children: [ { PUSHBUTTON: [] }]} ] }] });
    178          host.shadowRoot.querySelector("slot[name]").removeAttribute("name");
    179 
    180        }, { SECTION: [{ SECTION: [{ name: "green", children: [ { PUSHBUTTON: [] }]}, { name: "red"} ] }] },
    181        [evt => evt.accessible.name == "green", evt => evt.accessible.name == "red"]);
    182    }
    183 
    184    // testing/web-platform/tests/css/css-scoping/shadow-reassign-dynamic-004.html
    185    async function shadowReassignDynamic_4() {
    186      await _dynamicShadowTest("shadowReassignDynamic_4",
    187        (container, host) => {
    188          host.shadowRoot.getElementById("slot").remove();
    189      }, { SECTION: [{ SECTION: [{ name: "green"} ] }] });
    190    }
    191 
    192    function shadowProcessInvalidation() {
    193      testAccessibleTree("shadowProcessInvalidation",
    194      { SECTION: [{
    195          SECTION: [{
    196            SECTION: [{ TEXT_LEAF: { name: "Hello "} },
    197                      { TEXT: [{ TEXT_LEAF: { name: "World"} }] },
    198                      { PUSHBUTTON: { name: "World"} }]
    199          }]
    200        }]
    201      });
    202    }
    203 
    204    async function justAttachShadow() {
    205      await _dynamicShadowTest("justAttachShadow",
    206        (container, host) => {
    207          host.attachShadow({ mode: "open" });
    208        }, { SECTION: [{ SECTION: [] }] });
    209    }
    210 
    211    async function doTest() {
    212      await attachFlatShadow();
    213 
    214      await attachOneDeepShadow();
    215 
    216      await changeSlotFlat();
    217 
    218      await changeSlotOneDeep();
    219 
    220      await changeSlotNested();
    221 
    222      await changeSlotSingleChild();
    223 
    224      await changeSlotNoShadow();
    225 
    226      await assignSlotDynamic();
    227 
    228      await shadowFallbackDynamic_1();
    229 
    230      await shadowFallbackDynamic_2();
    231 
    232      await shadowFallbackDynamic_3();
    233 
    234      await shadowFallbackDynamic_4();
    235 
    236      await shadowFallbackDynamic_4_1();
    237 
    238      await shadowFallbackDynamic_5();
    239 
    240      await shadowReassignDynamic_2();
    241 
    242      await shadowReassignDynamic_3();
    243 
    244      await shadowReassignDynamic_4();
    245 
    246      shadowProcessInvalidation();
    247 
    248      await justAttachShadow();
    249 
    250      SimpleTest.finish();
    251    }
    252 
    253    SimpleTest.waitForExplicitFinish();
    254    addA11yLoadEvent(doTest);
    255  </script>
    256 </head>
    257 <body>
    258 
    259  <p id="display"></p>
    260  <div id="content" style="display: none"></div>
    261  <pre id="test">
    262  </pre>
    263  <div id="attachFlatShadow">
    264    <template class="shadowtree">
    265      <style>::slotted(div) { width: 100px; height: 100px }</style>
    266      <slot name="myslot">FAIL</slot>
    267    </template>
    268    <section class="host">
    269      <div style="background: green" aria-label="green"></div>
    270      <div style="background: red" aria-label="red" slot="myslot"></div>
    271    </section>
    272  </div>
    273 
    274  <div id="attachOneDeepShadow">
    275    <template class="shadowtree">
    276      <style>::slotted(div) { width: 100px; height: 100px }</style>
    277      <div id="shadowdiv">
    278        <slot name="myslot">FAIL</slot>
    279      </div>
    280    </template>
    281    <section class="host">
    282      <div style="background: green" aria-label="green"></div>
    283      <div style="background: red" aria-label="red" slot="myslot"></div>
    284    </section>
    285  </div>
    286 
    287  <div id="changeSlotFlat">
    288    <template class="shadowtree">
    289      <style>::slotted(div) { width: 100px; height: 100px }</style>
    290      <slot name="myslot">FAIL</slot>
    291    </template>
    292    <section class="host">
    293      <div class="green" style="background: green" aria-label="green"></div>
    294      <div class="red" style="background: red" aria-label="red" slot="myslot"></div>
    295    </section>
    296    <script>
    297      document.querySelector("#changeSlotFlat > .host")
    298        .attachShadow({ mode: "open" })
    299        .appendChild(document.querySelector("#changeSlotFlat > .shadowtree").content.cloneNode(true));
    300    </script>
    301  </div>
    302 
    303  <div id="changeSlotOneDeep">
    304    <template class="shadowtree">
    305      <style>::slotted(div) { width: 100px; height: 100px }</style>
    306      <div id="shadowdiv">
    307        <slot name="myslot">FAIL</slot>
    308      </div>
    309    </template>
    310    <section class="host">
    311      <div class="green" style="background: green" aria-label="green"></div>
    312      <div class="red" style="background: red" aria-label="red" slot="myslot"></div>
    313    </section>
    314    <script>
    315      document.querySelector("#changeSlotOneDeep > .host")
    316        .attachShadow({ mode: "open" })
    317        .appendChild(document.querySelector("#changeSlotOneDeep > .shadowtree").content.cloneNode(true));
    318    </script>
    319  </div>
    320 
    321  <div id="changeSlotNested">
    322    <template class="shadowtree outer">
    323      <div id="shadowdiv">
    324        <slot name="myslot">FAIL</slot>
    325      </div>
    326    </template>
    327    <template class="shadowtree inner">
    328      <style>::slotted(div) { width: 100px; height: 100px }</style>
    329      <slot>FAIL</slot>
    330    </template>
    331    <section class="host">
    332      <div class="green" style="background: green" aria-label="green"></div>
    333      <div class="red" style="background: red" aria-label="red" slot="myslot"></div>
    334    </section>
    335    <script>
    336      (function foo() {
    337        let outerShadow =
    338          document.querySelector("#changeSlotNested > .host").
    339            attachShadow({ mode: "open" });
    340        outerShadow.appendChild(
    341          document.querySelector("#changeSlotNested > .shadowtree.outer").
    342            content.cloneNode(true));
    343        let innerShadow =
    344          outerShadow.querySelector("#shadowdiv").
    345            attachShadow({ mode: "open" });
    346        innerShadow.appendChild(
    347          document.querySelector("#changeSlotNested > .shadowtree.inner").
    348            content.cloneNode(true));
    349      })();
    350    </script>
    351  </div>
    352 
    353  <div id="changeSlotSingleChild">
    354    <template class="shadowtree">
    355      <style>::slotted(div) { width: 100px; height: 100px }</style>
    356      <slot></slot>
    357    </template>
    358    <section class="host">
    359      <div class="red" style="background: red" aria-label="red"></div>
    360    </section>
    361    <script>
    362      document.querySelector("#changeSlotSingleChild > .host")
    363        .attachShadow({ mode: "open" })
    364        .appendChild(document.querySelector("#changeSlotSingleChild > .shadowtree").content.cloneNode(true));
    365    </script>
    366  </div>
    367 
    368  <div id="changeSlotNoShadow">
    369    <section class="host">
    370      <div class="red" style="background: red; width: 100px; height: 100px;" aria-label="red"></div>
    371      <div class="green" style="background: green; width: 100px; height: 100px;" aria-label="green"></div>
    372    </section>
    373  </div>
    374 
    375  <div id="assignSlotDynamic">
    376    <template class="shadowtree">
    377      <style>::slotted(div) { width: 50px; height: 100px }</style>
    378      <slot name="slot1">FAIL</slot>
    379      <slot name="slot2">FAIL</slot>
    380    </template>
    381    <template class="lighttree">
    382      <div aria-label="slot1" slot="slot1"></div>
    383      <div aria-label="slot2" slot="slot2"></div>
    384    </template>
    385    <section class="host"></section>
    386    <script>
    387      document.querySelector("#assignSlotDynamic > .host").attachShadow({ mode: "open" });
    388    </script>
    389  </div>
    390 
    391  <div id="shadowFallbackDynamic_1">
    392    <template class="shadowtree">
    393      <slot name="myslot">
    394        <div aria-label="green" style="width: 100px; height: 100px; background: green"></div>
    395      </slot>
    396    </template>
    397    <section class="host"><span slot="myslot">FAIL</span></section>
    398    <script>
    399      document.querySelector("#shadowFallbackDynamic_1 > .host")
    400        .attachShadow({ mode: "open" })
    401        .appendChild(document.querySelector("#shadowFallbackDynamic_1 > .shadowtree").content.cloneNode(true));
    402    </script>
    403  </div>
    404 
    405  <div id="shadowFallbackDynamic_2">
    406    <template class="shadowtree">
    407      <slot name="myslot">
    408        <div aria-label="green" style="width: 100px; height: 100px; background: green"></div>
    409      </slot>
    410    </template>
    411    <section class="host"><span slot="myslot">FAIL</span></section>
    412    <script>
    413      document.querySelector("#shadowFallbackDynamic_2 > .host")
    414        .attachShadow({ mode: "open" })
    415        .appendChild(document.querySelector("#shadowFallbackDynamic_2 > .shadowtree").content.cloneNode(true));
    416    </script>
    417  </div>
    418 
    419  <div id="shadowFallbackDynamic_3">
    420    <template class="shadowtree">
    421      <slot name="myslot">FAIL</slot>
    422    </template>
    423    <template class="lighttree">
    424      <div aria-label="green" slot="myslot" style="width: 100px; height: 100px; background: green"></div>
    425    </template>
    426    <section class="host"></section>
    427    <script>
    428      document.querySelector("#shadowFallbackDynamic_3 > .host")
    429        .attachShadow({ mode: "open" })
    430        .appendChild(document.querySelector("#shadowFallbackDynamic_3 > .shadowtree").content.cloneNode(true));
    431    </script>
    432  </div>
    433 
    434  <div id="shadowFallbackDynamic_4">
    435    <template class="shadowtree">
    436      <div aria-label="slotparent1"><slot name="myslot"></slot></div>
    437    </template>
    438    <template class="moreshadowtree">
    439      <div aria-label="slotparent2"><slot name="myslot">FAIL</slot></div>
    440    </template>
    441    <section class="host">
    442      <div slot="myslot" aria-label="green" style="width: 100px; height: 100px; background: green"></div>
    443    </section>
    444    <script>
    445      document.querySelector("#shadowFallbackDynamic_4 > .host")
    446        .attachShadow({ mode: "open" })
    447        .appendChild(document.querySelector("#shadowFallbackDynamic_4 > .shadowtree").content.cloneNode(true));
    448    </script>
    449  </div>
    450 
    451  <div id="shadowFallbackDynamic_4_1">
    452    <template class="shadowtree">
    453      <hr>
    454      <slot name="myslot"></slot>
    455    </template>
    456    <template class="moreshadowtree">
    457      <slot name="myslot">FAIL</slot>
    458    </template>
    459    <section class="host">
    460      <div slot="myslot" aria-label="green" style="width: 100px; height: 100px; background: green"></div>
    461    </section>
    462    <script>
    463      document.querySelector("#shadowFallbackDynamic_4_1 > .host")
    464        .attachShadow({ mode: "open" })
    465        .appendChild(document.querySelector("#shadowFallbackDynamic_4_1 > .shadowtree").content.cloneNode(true));
    466    </script>
    467  </div>
    468 
    469  <div id="shadowFallbackDynamic_5">
    470    <template class="shadowtree">
    471      <slot name="myslot"></slot>
    472      <slot name="myotherslot">FAIL</slot>
    473    </template>
    474    <section class="host">
    475      <div slot="myslot" aria-label="green" style="width: 100px; height: 100px; background: green"></div>
    476    </section>
    477    <script>
    478      document.querySelector("#shadowFallbackDynamic_5 > .host")
    479        .attachShadow({ mode: "open" })
    480        .appendChild(document.querySelector("#shadowFallbackDynamic_5 > .shadowtree").content.cloneNode(true));
    481    </script>
    482  </div>
    483 
    484  <div id="shadowReassignDynamic_2">
    485    <template class="shadowtree">
    486      <style>::slotted(div) { width: 100px; height: 100px }</style>
    487      <slot>FAIL</slot>
    488    </template>
    489    <section class="host">
    490      <div slot="myslot" aria-label="green" style="width: 100px; height: 100px; background: green"></div>
    491    </section>
    492    <script>
    493      document.querySelector("#shadowReassignDynamic_2 > .host")
    494        .attachShadow({ mode: "open" })
    495        .appendChild(document.querySelector("#shadowReassignDynamic_2 > .shadowtree").content.cloneNode(true));
    496    </script>
    497  </div>
    498 
    499  <div id="shadowReassignDynamic_3">
    500    <template class="shadowtree">
    501      <div aria-label="green"><slot name="nomatch"></slot></div>
    502      <div aria-label="red"><slot></slot></div>
    503    </template>
    504    <section class="host">
    505      <div role="button"></div>
    506    </section>
    507    <script>
    508      document.querySelector("#shadowReassignDynamic_3 > .host")
    509        .attachShadow({ mode: "open" })
    510        .appendChild(document.querySelector("#shadowReassignDynamic_3 > .shadowtree").content.cloneNode(true));
    511    </script>
    512  </div>
    513 
    514  <div id="shadowReassignDynamic_4">
    515    <template class="shadowtree">
    516      <style>::slotted(div),div { width: 100px; height: 100px }</style>
    517      <slot id="slot"></slot>
    518      <slot>
    519        <div aria-label="red" style="background: red"></div>
    520      </slot>
    521    </template>
    522    <section class="host">
    523      <div aria-label="green" style="background: green"></div>
    524    </section>
    525    <script>
    526      document.querySelector("#shadowReassignDynamic_4 > .host")
    527        .attachShadow({ mode: "open" })
    528        .appendChild(document.querySelector("#shadowReassignDynamic_4 > .shadowtree").content.cloneNode(true));
    529    </script>
    530  </div>
    531 
    532  <div id="shadowProcessInvalidation">
    533    <template class="shadowtree">
    534      <div id="shadowdiv">
    535        <slot></slot>
    536      </div>
    537    </template>
    538    <section class="host">Hello <span id="c">World</span><button aria-labelledby="c"></button></section>
    539    <script>
    540      document.querySelector("#shadowProcessInvalidation > .host")
    541        .attachShadow({ mode: "open" })
    542        .appendChild(document.querySelector("#shadowProcessInvalidation > .shadowtree").content.cloneNode(true));
    543    </script>
    544  </div>
    545 
    546  <div id="justAttachShadow">
    547    <section class="host">
    548      <button></button>
    549    </section>
    550  </div>
    551 
    552  <div id="eventdump"></div>
    553 </body>
    554 </html>