tor-browser

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

browser_shadowdom.js (4112B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 "use strict";
      6 
      7 /* import-globals-from ../../mochitest/role.js */
      8 loadScripts({ name: "role.js", dir: MOCHITESTS_DIR });
      9 
     10 const REORDER = { expected: [[EVENT_REORDER, "container"]] };
     11 
     12 // Dynamically inserted slotted accessible elements should be in
     13 // the accessible tree.
     14 const snippet = `
     15 <script>
     16 customElements.define("x-el", class extends HTMLElement {
     17  constructor() {
     18    super();
     19    this.attachShadow({ mode: "open" });
     20    this.shadowRoot.innerHTML =
     21      "<div role='presentation'><slot></slot></div>";
     22  }
     23 });
     24 </script>
     25 <x-el id="container" role="group"><label id="l1">label1</label></x-el>
     26 `;
     27 
     28 addAccessibleTask(snippet, async function (browser, accDoc) {
     29  let container = findAccessibleChildByID(accDoc, "container");
     30 
     31  testChildrenIds(container, ["l1"]);
     32 
     33  await contentSpawnMutation(browser, REORDER, function () {
     34    let labelEl = content.document.createElement("label");
     35    labelEl.id = "l2";
     36 
     37    let containerEl = content.document.getElementById("container");
     38    containerEl.appendChild(labelEl);
     39  });
     40 
     41  testChildrenIds(container, ["l1", "l2"]);
     42 });
     43 
     44 // Dynamically inserted not accessible custom element containing an accessible
     45 // in its shadow DOM.
     46 const snippet2 = `
     47 <script>
     48 customElements.define("x-el2", class extends HTMLElement {
     49  constructor() {
     50    super();
     51    this.attachShadow({ mode: "open" });
     52    this.shadowRoot.innerHTML = "<input id='input'>";
     53  }
     54 });
     55 </script>
     56 <div role="group" id="container"></div>
     57 `;
     58 
     59 addAccessibleTask(snippet2, async function (browser, accDoc) {
     60  let container = findAccessibleChildByID(accDoc, "container");
     61 
     62  await contentSpawnMutation(browser, REORDER, function () {
     63    content.document.getElementById("container").innerHTML = "<x-el2></x-el2>";
     64  });
     65 
     66  testChildrenIds(container, ["input"]);
     67 });
     68 
     69 /**
     70 * Ensure that changing the slot on the body while moving the body doesn't
     71 * try to remove the DocAccessible. We test this here instead of in
     72 * accessible/tests/mochitest/treeupdate/test_shadow_slots.html because this
     73 * messes with the body element and we don't want that to impact other tests.
     74 */
     75 addAccessibleTask(
     76  `<div id="host"></div>`,
     77  async function (browser, docAcc) {
     78    info("Moving body and setting slot on body");
     79    let reordered = waitForEvent(EVENT_REORDER, docAcc);
     80    await invokeContentTask(browser, [], () => {
     81      const host = content.document.getElementById("host");
     82      const emptyScript = content.document.getElementById("emptyScript");
     83      const body = content.document.body;
     84      emptyScript.append(host);
     85      host.append(body);
     86      body.slot = "";
     87    });
     88    await reordered;
     89    is(docAcc.childCount, 0, "document has no children after body move");
     90  },
     91  {
     92    chrome: true,
     93    topLevel: true,
     94    iframe: true,
     95    remoteIframe: true,
     96    contentSetup: async function contentSetup() {
     97      const doc = content.document;
     98      const host = doc.getElementById("host");
     99      host.attachShadow({ mode: "open" });
    100      const emptyScript = doc.createElement("script");
    101      emptyScript.id = "emptyScript";
    102      doc.head.append(emptyScript);
    103    },
    104  }
    105 );
    106 
    107 addAccessibleTask(
    108  `
    109    <marquee id="container"><span><button>Help</button></span></marquee>
    110  `,
    111  async function (browser, docAcc) {
    112    info("A slotted inline");
    113    const container = findAccessibleChildByID(docAcc, "container");
    114 
    115    testAccessibleTree(container, {
    116      TEXT_CONTAINER: [{ TEXT_CONTAINER: [{ PUSHBUTTON: { name: "Help" } }] }],
    117    });
    118 
    119    const SLOT_REORDER = {
    120      expected: [
    121        [
    122          EVENT_REORDER,
    123          evt => getAccessibleDOMNodeID(evt.accessible.parent) == "container",
    124        ],
    125      ],
    126    };
    127    await contentSpawnMutation(browser, SLOT_REORDER, function () {
    128      content.document.getElementById("container").firstElementChild.slot =
    129        "foo";
    130    });
    131 
    132    testAccessibleTree(container, {
    133      TEXT_CONTAINER: [{ TEXT_CONTAINER: [] }],
    134    });
    135  }
    136 );