tor-browser

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

browser_test_simple_transform.js (7484B)


      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 loadScripts({ name: "role.js", dir: MOCHITESTS_DIR });
      8 
      9 add_setup(async function () {
     10  await SpecialPowers.pushPrefEnv({
     11    set: [["test.wait300msAfterTabSwitch", true]],
     12  });
     13 });
     14 
     15 // test basic translation
     16 addAccessibleTask(
     17  `<p id="translate">hello world</p>`,
     18  async function (browser, iframeDocAcc) {
     19    ok(iframeDocAcc, "IFRAME document accessible is present");
     20    await testBoundsWithContent(iframeDocAcc, "translate", browser);
     21 
     22    await invokeContentTask(browser, [], () => {
     23      let p = content.document.getElementById("translate");
     24      p.style = "transform: translate(100px, 100px);";
     25    });
     26 
     27    await waitForContentPaint(browser);
     28    await testBoundsWithContent(iframeDocAcc, "translate", browser);
     29  },
     30  { topLevel: true, iframe: true, remoteIframe: true }
     31 );
     32 
     33 // Test translation with two children.
     34 addAccessibleTask(
     35  `
     36 <div role="main" style="translate: 0 300px;">
     37  <p id="p1">hello</p>
     38  <p id="p2">world</p>
     39 </div>
     40  `,
     41  async function (browser, docAcc) {
     42    await testBoundsWithContent(docAcc, "p1", browser);
     43    await testBoundsWithContent(docAcc, "p2", browser);
     44  },
     45  { topLevel: true, iframe: true, remoteIframe: true }
     46 );
     47 
     48 // test basic rotation
     49 addAccessibleTask(
     50  `<p id="rotate">hello world</p>`,
     51  async function (browser, iframeDocAcc) {
     52    ok(iframeDocAcc, "IFRAME document accessible is present");
     53    await testBoundsWithContent(iframeDocAcc, "rotate", browser);
     54 
     55    await invokeContentTask(browser, [], () => {
     56      let p = content.document.getElementById("rotate");
     57      p.style = "transform: rotate(-40deg);";
     58    });
     59 
     60    await waitForContentPaint(browser);
     61    await testBoundsWithContent(iframeDocAcc, "rotate", browser);
     62  },
     63  { topLevel: true, iframe: true, remoteIframe: true }
     64 );
     65 
     66 // test basic scale
     67 addAccessibleTask(
     68  `<p id="scale">hello world</p>`,
     69  async function (browser, iframeDocAcc) {
     70    ok(iframeDocAcc, "IFRAME document accessible is present");
     71    await testBoundsWithContent(iframeDocAcc, "scale", browser);
     72 
     73    await invokeContentTask(browser, [], () => {
     74      let p = content.document.getElementById("scale");
     75      p.style = "transform: scale(2);";
     76    });
     77 
     78    await waitForContentPaint(browser);
     79    await testBoundsWithContent(iframeDocAcc, "scale", browser);
     80  },
     81  { topLevel: true, iframe: true, remoteIframe: true }
     82 );
     83 
     84 // Test will-change: transform with no transform.
     85 addAccessibleTask(
     86  `
     87 <div id="willChangeTop" style="will-change: transform;">
     88  <p>hello</p>
     89  <p id="willChangeTopP2">world</p>
     90 </div>
     91 <div role="group">
     92  <div id="willChangeInner" style="will-change: transform;">
     93    <p>hello</p>
     94    <p id="willChangeInnerP2">world</p>
     95  </div>
     96 </div>
     97  `,
     98  async function (browser, docAcc) {
     99    // Even though willChangeTop has no transform, it has
    100    // will-change: transform, which means nsIFrame::IsTransformed returns
    101    // true. We don't cache identity matrices, but because there is an offset
    102    // to the root frame, layout includes this in the returned transform
    103    // matrix. That means we get a non-identity matrix and thus we cache it.
    104    // This is why we only test the identity matrix cache optimization for
    105    // willChangeInner.
    106    let hasTransform;
    107    try {
    108      const willChangeInner = findAccessibleChildByID(
    109        docAcc,
    110        "willChangeInner"
    111      );
    112      willChangeInner.cache.getStringProperty("transform");
    113      hasTransform = true;
    114    } catch (e) {
    115      hasTransform = false;
    116    }
    117    ok(!hasTransform, "willChangeInner has no cached transform");
    118    await testBoundsWithContent(docAcc, "willChangeTopP2", browser);
    119    await testBoundsWithContent(docAcc, "willChangeInnerP2", browser);
    120  },
    121  { topLevel: true, iframe: true, remoteIframe: true }
    122 );
    123 
    124 // Verify that a transform forces creation of an accessible.
    125 addAccessibleTask(
    126  `
    127 <div id="container">
    128  <div style="transform:translate(100px,100px);">
    129    <p>test</p>
    130  </div>
    131 </div>
    132 
    133 <div id="div-presentational" role="presentation" style="transform:translate(100px,100px);">
    134  <p>test</p>
    135 </div>
    136  `,
    137  async function (browser, docAcc) {
    138    const tree = { TEXT_CONTAINER: [{ PARAGRAPH: [{ TEXT_LEAF: [] }] }] };
    139 
    140    const divWithTransform = findAccessibleChildByID(
    141      docAcc,
    142      "container"
    143    ).firstChild;
    144    testAccessibleTree(divWithTransform, tree);
    145    // testBoundsWithContent takes an id, but divWithTransform doesn't have one,
    146    // so we can't test the bounds for it.
    147 
    148    // An accessible should still be created, even if the role is "presentation."
    149    const divPresentational = findAccessibleChildByID(
    150      docAcc,
    151      "div-presentational"
    152    );
    153    testAccessibleTree(divPresentational, tree);
    154    await testBoundsWithContent(docAcc, "div-presentational", browser);
    155  },
    156  { topLevel: true, iframe: true, remoteIframe: true }
    157 );
    158 
    159 // Verify that adding a transform on the fly forces creation of an accessible.
    160 addAccessibleTask(
    161  `
    162 <div id="div-to-transform" role="none" style="position: absolute; width: 300px; height: 300px;">
    163  <p>test</p>
    164 </div>
    165  `,
    166  async function (browser, docAcc) {
    167    let divToTransform = findAccessibleChildByID(docAcc, "div-to-transform");
    168    ok(!divToTransform, "There should not be a div accessible.");
    169 
    170    // Translate the div.
    171    await invokeContentTask(browser, [], () => {
    172      let div = content.document.getElementById("div-to-transform");
    173      div.style.transform = "translate(100%, 100%)";
    174    });
    175    await waitForContentPaint(browser);
    176 
    177    // Verify that the SECTION accessible appeared after we gave it a transform.
    178    divToTransform = findAccessibleChildByID(docAcc, "div-to-transform");
    179    const tree = {
    180      TEXT_CONTAINER: [{ PARAGRAPH: [{ TEXT_LEAF: [] }] }],
    181    };
    182    testAccessibleTree(divToTransform, tree);
    183 
    184    // Verify that the bounds of the div are correctly modified.
    185    await testBoundsWithContent(docAcc, "div-to-transform", browser);
    186  },
    187  { topLevel: true, iframe: true, remoteIframe: true }
    188 );
    189 
    190 // Test translated, position: absolute Accessible in a container.
    191 addAccessibleTask(
    192  `
    193 <div id="container">
    194  <div id="transform" style="position: absolute; transform: translate(100px, 100px);">
    195    <p id="p">test</p>
    196  </div>
    197 </div>
    198  `,
    199  async function (browser, docAcc) {
    200    await testBoundsWithContent(docAcc, "transform", browser);
    201    await testBoundsWithContent(docAcc, "p", browser);
    202  },
    203  { topLevel: true, iframe: true, remoteIframe: true }
    204 );
    205 
    206 // Test bounds of a rotated element after scroll.
    207 addAccessibleTask(
    208  `
    209 <div id="scrollable" style="transform: rotate(180deg); overflow: scroll; height: 500px;">
    210  <p id="test">hello world</p><hr style="height: 100vh;">
    211 </div>
    212  `,
    213  async function (browser, docAcc) {
    214    info(
    215      "Testing that the unscrolled bounds of a transformed element are correct."
    216    );
    217    await testBoundsWithContent(docAcc, "test", browser);
    218 
    219    await invokeContentTask(browser, [], () => {
    220      // Scroll the scrollable region down (scrolls up due to the transform).
    221      let elem = content.document.getElementById("scrollable");
    222      elem.scrollTo(0, elem.scrollHeight);
    223    });
    224 
    225    info(
    226      "Testing that the scrolled bounds of a transformed element are correct."
    227    );
    228    await testBoundsWithContent(docAcc, "test", browser);
    229  },
    230  { topLevel: true, iframe: true, remoteIframe: true }
    231 );