tor-browser

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

prefer-targeted-element-main-frame-target.html (5257B)


      1 <!DOCTYPE html>
      2 <html>
      3 <body>
      4  <style>
      5    #space {
      6      height: 300vh;
      7      width: 300vw;
      8      position: absolute;
      9    }
     10    #scroller {
     11      overflow-y: scroll;
     12      scroll-snap-type: y mandatory;
     13      width: 450px;
     14      height: 450px;
     15      border: solid 1px black;
     16      position: relative;
     17    }
     18    .box {
     19      height: 200px;
     20      width: 200px;
     21      position: absolute;
     22      background-color: green;
     23      scroll-snap-align: start;
     24    }
     25    .box:target {
     26      background-color: red;
     27    }
     28    .toprow { top: 0px; }
     29    .midrow { top: 210px; }
     30    .bottomrow { top: 420px; }
     31    .leftcol { left: 0px; }
     32    .midcol { left: 210px; }
     33    .rightcol { left: 420px; }
     34  </style>
     35  <div id="scroller">
     36    <div id="space"></div>
     37    <div class="leftcol toprow box" id="box1"></div>
     38    <div class="midcol toprow box" id="box2"></div>
     39    <div class="rightcol toprow box" id="box3"></div>
     40    <div class="leftcol midrow box" id="box4"></div>
     41    <div class="midcol midrow box" id="box5"></div>
     42    <div class="rightcol midrow box" id="box6"></div>
     43    <div class="leftcol bottomrow box" id="box7"></div>
     44    <div class="midcol bottomrow box" id="box8"></div>
     45    <div class="rightcol bottomrow box" id="box9"></div>
     46  </div>
     47  <script>
     48    // This test sets up a 3x3 grid within scroller:
     49    // -------------------------
     50    // | Box 1 | Box 2 | Box 3 |
     51    // ------------------------
     52    // | Box 4 | Box 5 | Box 6 |
     53    // -------------------------
     54    // | Box 7 | Box 8 | Box 9 |
     55    // -------------------------
     56    // This function just gets the boxes beside boxn on each row.
     57    // E.g. box4: 4%3 = 1; so the boxes we want are box5 (4+1) and box6 (4+2).
     58    function getAlignedBoxes(n) {
     59      n = parseInt(n);
     60      const mod_3 = n % 3;
     61      let n1 = n - 1, n2 = n - 2;
     62      if (mod_3 == 1) {
     63        n1 = n + 1;
     64        n2 = n + 2;
     65      } else if (mod_3 == 2) {
     66        n1 = n - 1;
     67        n2 = n + 1;
     68      }
     69      return [document.getElementById(`box${n1}`),
     70              document.getElementById(`box${n2}`)];
     71    }
     72 
     73    function stashResult(key, result) {
     74      fetch(`/css/css-scroll-snap/snap-after-relayout` +
     75        `/multiple-aligned-targets/stash.py?key=${key}`, {
     76        method: "POST",
     77        body: JSON.stringify(result)
     78      }).then(() => {
     79        window.close();
     80      });
     81    }
     82 
     83    function assert_equals(test_number, v1, v2, description) {
     84      if (v1 != v2) {
     85        throw new Error(
     86          `Test ${n} expected equality of ${v1} and ${v2}, ` +
     87          `Description: ${description}`);
     88      }
     89    }
     90 
     91    async function waitForScrollReset(scroller, x = 0, y = 0) {
     92      return new Promise((resolve) => {
     93        if (scroller.scrollLeft == x && scroller.scrollTop == y) {
     94          resolve();
     95        } else {
     96          scroller.addEventListener("scrollend", resolve);
     97          scroller.scrollTo(x, y);
     98        }
     99      });
    100    }
    101 
    102    async function setLocationHash(id) {
    103      return new Promise((resolve) => {
    104        if (location.hash === `#${id}`) {
    105          resolve();
    106        } else {
    107          window.addEventListener("hashchange", resolve);
    108          location.hash = `#${id}`;
    109        }
    110      });
    111    }
    112 
    113    let result = {
    114      passed: 0,
    115      errors: "",
    116    };
    117 
    118    async function test(n) {
    119      try {
    120        const target_id = `box${n}`;
    121        const target = document.getElementById(target_id);
    122 
    123        // Make boxn the targeted element.
    124        await setLocationHash(target_id);
    125 
    126        // Reset the scroll position.
    127        await waitForScrollReset(scroller);
    128 
    129        const aligned_boxes = getAlignedBoxes(n);
    130        // Make sure all the boxes are equally aligned.
    131        assert_equals(n, aligned_boxes[0].offsetTop, target.offsetTop,
    132          `${aligned_boxes[0].id} is at offset ${target.offsetTop}`);
    133        assert_equals(n, aligned_boxes[1].offsetTop, target.offsetTop,
    134          `${aligned_boxes[1].id} is at offset ${target.offsetTop}`);
    135 
    136        // Scroll to the aligned boxes.
    137        await waitForScrollReset(scroller, 0, target.offsetTop);
    138        assert_equals(n, scroller.scrollTop, target.offsetTop,
    139          `scrolled to ${target.id} at offset ${target.offsetTop}`);
    140 
    141        // Save target's original top.
    142        const original_top = getComputedStyle(target).top;
    143        const original_offset_top = target.offsetTop;
    144 
    145        // Move target along the y axis.
    146        target.style.top = `${target.offsetTop + 100}px`;
    147 
    148        // Assert that scroller followed target as it moved down.
    149        assert_equals(n, scroller.scrollTop, target.offsetTop,
    150          `scrolled followed ${target.id} to offset ${target.offsetTop}`);
    151 
    152        // Cleanup: undo style change.
    153        target.style.top = original_top;
    154        assert_equals(n, target.offsetTop, original_offset_top,
    155          `${target.id} is put back to offset ${original_offset_top}`);
    156 
    157        // Record the result.
    158        result.passed += 1;
    159      } catch (error) {
    160        result.errors = [result.errors, error.message].join();
    161      }
    162    }
    163 
    164    window.onload = async () => {
    165      let key = (new URL(document.location)).searchParams.get("key");
    166 
    167      for (const n of [1, 2, 3, 4, 5, 6, 7, 8, 9]) {
    168        await test(n);
    169      }
    170 
    171      stashResult(key, result);
    172    }
    173  </script>
    174 </body>
    175 
    176 </html>