tor-browser

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

browser_aria_owns.js (8138B)


      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 let NO_MOVE = { unexpected: [[EVENT_REORDER, "container"]] };
      8 let MOVE = { expected: [[EVENT_REORDER, "container"]] };
      9 
     10 // Set last ordinal child as aria-owned, should produce no reorder.
     11 addAccessibleTask(
     12  `<ul id="container"><li id="a">Test</li></ul>`,
     13  async function (browser, accDoc) {
     14    let containerAcc = findAccessibleChildByID(accDoc, "container");
     15 
     16    testChildrenIds(containerAcc, ["a"]);
     17 
     18    await contentSpawnMutation(browser, NO_MOVE, function () {
     19      // aria-own ordinal child in place, should be a no-op.
     20      content.document
     21        .getElementById("container")
     22        .setAttribute("aria-owns", "a");
     23    });
     24 
     25    testChildrenIds(containerAcc, ["a"]);
     26  }
     27 );
     28 
     29 // Add a new ordinal child to a container with an aria-owned child.
     30 // Order should respect aria-owns.
     31 addAccessibleTask(
     32  `<ul id="container"><li id="a">Test</li></ul>`,
     33  async function (browser, accDoc) {
     34    let containerAcc = findAccessibleChildByID(accDoc, "container");
     35 
     36    testChildrenIds(containerAcc, ["a"]);
     37 
     38    await contentSpawnMutation(browser, MOVE, function () {
     39      let container = content.document.getElementById("container");
     40      container.setAttribute("aria-owns", "a");
     41 
     42      let aa = content.document.createElement("li");
     43      aa.id = "aa";
     44      container.appendChild(aa);
     45    });
     46 
     47    testChildrenIds(containerAcc, ["aa", "a"]);
     48 
     49    await contentSpawnMutation(browser, MOVE, function () {
     50      content.document.getElementById("container").removeAttribute("aria-owns");
     51    });
     52 
     53    testChildrenIds(containerAcc, ["a", "aa"]);
     54  }
     55 );
     56 
     57 // Remove a no-move aria-owns attribute, should result in a no-move.
     58 addAccessibleTask(
     59  `<ul id="container" aria-owns="a"><li id="a">Test</li></ul>`,
     60  async function (browser, accDoc) {
     61    let containerAcc = findAccessibleChildByID(accDoc, "container");
     62 
     63    testChildrenIds(containerAcc, ["a"]);
     64 
     65    await contentSpawnMutation(browser, NO_MOVE, function () {
     66      // remove aria-owned child that is already ordinal, should be no-op.
     67      content.document.getElementById("container").removeAttribute("aria-owns");
     68    });
     69 
     70    testChildrenIds(containerAcc, ["a"]);
     71  }
     72 );
     73 
     74 // Attempt to steal an aria-owned child. The attempt should fail.
     75 addAccessibleTask(
     76  `
     77  <ul>
     78    <li id="a">Test</li>
     79  </ul>
     80  <ul aria-owns="a"></ul>
     81  <ul id="container"></ul>`,
     82  async function (browser, accDoc) {
     83    let containerAcc = findAccessibleChildByID(accDoc, "container");
     84 
     85    testChildrenIds(containerAcc, []);
     86 
     87    await contentSpawnMutation(browser, NO_MOVE, function () {
     88      content.document
     89        .getElementById("container")
     90        .setAttribute("aria-owns", "a");
     91    });
     92 
     93    testChildrenIds(containerAcc, []);
     94  }
     95 );
     96 
     97 // Don't aria-own children of <select>
     98 addAccessibleTask(
     99  `
    100  <div id="container" role="group" aria-owns="b"></div>
    101  <select id="select">
    102    <option id="a"></option>
    103    <option id="b"></option>
    104  </select>`,
    105  async function (browser, accDoc) {
    106    let containerAcc = findAccessibleChildByID(accDoc, "container");
    107    let selectAcc = findAccessibleChildByID(accDoc, "select");
    108 
    109    testChildrenIds(containerAcc, []);
    110    testChildrenIds(selectAcc.firstChild, ["a", "b"]);
    111  }
    112 );
    113 
    114 // Don't allow <select> to aria-own
    115 addAccessibleTask(
    116  `
    117  <div id="container" role="group">
    118    <div id="a"></div>
    119    <div id="b"></div>
    120  </div>
    121  <select id="select" aria-owns="a">
    122    <option id="c"></option>
    123  </select>`,
    124  async function (browser, accDoc) {
    125    let containerAcc = findAccessibleChildByID(accDoc, "container");
    126    let selectAcc = findAccessibleChildByID(accDoc, "select");
    127 
    128    testChildrenIds(containerAcc, ["a", "b"]);
    129    testChildrenIds(selectAcc.firstChild, ["c"]);
    130  }
    131 );
    132 
    133 // Don't allow one <select> to aria-own an <option> from another <select>.
    134 addAccessibleTask(
    135  `
    136  <select id="select1" aria-owns="c">
    137    <option id="a"></option>
    138    <option id="b"></option>
    139  </select>
    140  <select id="select2">
    141    <option id="c"></option>
    142  </select>`,
    143  async function (browser, accDoc) {
    144    let selectAcc1 = findAccessibleChildByID(accDoc, "select1");
    145    let selectAcc2 = findAccessibleChildByID(accDoc, "select2");
    146 
    147    testChildrenIds(selectAcc1.firstChild, ["a", "b"]);
    148    testChildrenIds(selectAcc2.firstChild, ["c"]);
    149  }
    150 );
    151 
    152 // Don't allow a <select> to reorder its children with aria-owns.
    153 addAccessibleTask(
    154  `
    155  <select id="container" aria-owns="c b a">
    156    <option id="a"></option>
    157    <option id="b"></option>
    158    <option id="c"></option>
    159  </select>`,
    160  async function (browser, accDoc) {
    161    let containerAcc = findAccessibleChildByID(accDoc, "container");
    162 
    163    testChildrenIds(containerAcc.firstChild, ["a", "b", "c"]);
    164 
    165    await contentSpawnMutation(browser, NO_MOVE, function () {
    166      content.document
    167        .getElementById("container")
    168        .setAttribute("aria-owns", "a c b");
    169    });
    170 
    171    testChildrenIds(containerAcc.firstChild, ["a", "b", "c"]);
    172  }
    173 );
    174 
    175 // Don't crash if ID in aria-owns does not exist
    176 addAccessibleTask(
    177  `
    178  <select id="container" aria-owns="boom" multiple></select>`,
    179  async function () {
    180    ok(true, "Did not crash");
    181  }
    182 );
    183 
    184 addAccessibleTask(
    185  `
    186  <ul id="one">
    187    <li id="a">Test</li>
    188    <li id="b">Test 2</li>
    189    <li id="c">Test 3</li>
    190  </ul>
    191  <ul id="two"></ul>`,
    192  async function (browser, accDoc) {
    193    let one = findAccessibleChildByID(accDoc, "one");
    194    let two = findAccessibleChildByID(accDoc, "two");
    195 
    196    let waitfor = {
    197      expected: [
    198        [EVENT_REORDER, "one"],
    199        [EVENT_REORDER, "two"],
    200      ],
    201    };
    202 
    203    await contentSpawnMutation(browser, waitfor, function () {
    204      // Put same id twice in aria-owns
    205      content.document.getElementById("two").setAttribute("aria-owns", "a a");
    206    });
    207 
    208    testChildrenIds(one, ["b", "c"]);
    209    testChildrenIds(two, ["a"]);
    210 
    211    await contentSpawnMutation(browser, waitfor, function () {
    212      // If the previous double-id aria-owns worked correctly, we should
    213      // be in a good state and all is fine..
    214      content.document.getElementById("two").setAttribute("aria-owns", "a b");
    215    });
    216 
    217    testChildrenIds(one, ["c"]);
    218    testChildrenIds(two, ["a", "b"]);
    219  }
    220 );
    221 
    222 addAccessibleTask(
    223  `<div id="a"></div><div id="b"></div>`,
    224  async function (browser, accDoc) {
    225    testChildrenIds(accDoc, ["a", "b"]);
    226 
    227    let waitFor = {
    228      expected: [[EVENT_REORDER, e => e.accessible == accDoc]],
    229    };
    230 
    231    await contentSpawnMutation(browser, waitFor, function () {
    232      content.document.documentElement.style.display = "none";
    233      content.document.documentElement.getBoundingClientRect();
    234      content.document.body.setAttribute("aria-owns", "b a");
    235      content.document.documentElement.remove();
    236    });
    237 
    238    testChildrenIds(accDoc, []);
    239  }
    240 );
    241 
    242 // Don't allow ordinal child to be placed after aria-owned child (bug 1405796)
    243 addAccessibleTask(
    244  `<div id="container"><div id="a">Hello</div></div>
    245                   <div><div id="c">There</div><div id="d">There</div></div>`,
    246  async function (browser, accDoc) {
    247    let containerAcc = findAccessibleChildByID(accDoc, "container");
    248 
    249    testChildrenIds(containerAcc, ["a"]);
    250 
    251    await contentSpawnMutation(browser, MOVE, function () {
    252      content.document
    253        .getElementById("container")
    254        .setAttribute("aria-owns", "c");
    255    });
    256 
    257    testChildrenIds(containerAcc, ["a", "c"]);
    258 
    259    await contentSpawnMutation(browser, MOVE, function () {
    260      let span = content.document.createElement("span");
    261      content.document.getElementById("container").appendChild(span);
    262 
    263      let b = content.document.createElement("div");
    264      b.id = "b";
    265      content.document.getElementById("container").appendChild(b);
    266    });
    267 
    268    testChildrenIds(containerAcc, ["a", "b", "c"]);
    269 
    270    await contentSpawnMutation(browser, MOVE, function () {
    271      content.document
    272        .getElementById("container")
    273        .setAttribute("aria-owns", "c d");
    274    });
    275 
    276    testChildrenIds(containerAcc, ["a", "b", "c", "d"]);
    277  }
    278 );