tor-browser

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

pointerevent_boundary_events_on_image_map.html (14290B)


      1 <!doctype html>
      2 <html>
      3 <head>
      4 <meta charset="utf-8">
      5 <meta name="viewport" content="width=device-width, user-scalable=no">
      6 <title>Event targets of boundary events over an image map</title>
      7 <script src="/resources/testharness.js"></script>
      8 <script src="/resources/testharnessreport.js"></script>
      9 <script src="/resources/testdriver.js"></script>
     10 <script src="/resources/testdriver-actions.js"></script>
     11 <script src="/resources/testdriver-vendor.js"></script>
     12 <script>
     13 "use strict";
     14 
     15 addEventListener("load", () => {
     16  const initialDiv = document.getElementById("init");
     17  const container = document.getElementById("container");
     18  const img1 = document.getElementById("img1");
     19  const img2 = document.getElementById("img2");
     20  const area1_1 = document.getElementById("area1-1");
     21  const area1_2 = document.createElement("area");
     22  area1_2.setAttribute("id", "area1-2");
     23  area1_2.setAttribute("shape", "rect");
     24  area1_2.setAttribute("coords", "0,0,100,100");
     25  area1_2.setAttribute("href", "#");
     26  const area2_1 = document.getElementById("area2-1");
     27  const map1 = document.getElementById("map1");
     28  const map2 = document.getElementById("map2");
     29 
     30  function stringifyEvents(arrayOfEvents) {
     31    function stringifyEvent(event) {
     32      return `${event.type}@${event.target.localName}${
     33        event.target.id ? `#${event.target.id}` : ""
     34      }`
     35    }
     36    let str = "[";
     37    for (const event of arrayOfEvents) {
     38      if (str != "[") {
     39        str += ", ";
     40      }
     41      str += stringifyEvent(event);
     42    }
     43    return str + "]";
     44  }
     45 
     46  let events = [];
     47  function pushEvent(event) {
     48    events.push(event);
     49  }
     50  for (const type of ["pointermove", "pointerover", "pointerenter", "pointerout", "pointerleave"]) {
     51    container.addEventListener(type, pushEvent, {capture: true});
     52  }
     53 
     54  promise_test(async () => {
     55    events = [];
     56    await new test_driver.Actions()
     57      .pointerMove(0, 0, {origin: initialDiv})
     58      .pointerMove(0, 0, {origin: img1}) // actually moved over area1-1
     59      .pointerMove(0, 0, {origin: initialDiv})
     60      .send();
     61    assert_equals(
     62      stringifyEvents(events),
     63      stringifyEvents([
     64        {type: "pointerover",  target: area1_1},
     65        {type: "pointerenter", target: container},
     66        {type: "pointerenter", target: map1},
     67        {type: "pointerenter", target: area1_1},
     68        {type: "pointermove",  target: area1_1},
     69        {type: "pointerout",   target: area1_1},
     70        {type: "pointerleave", target: area1_1},
     71        {type: "pointerleave", target: map1},
     72        {type: "pointerleave", target: container},
     73      ])
     74    );
     75  }, "pointer boundary events when simple over/out");
     76 
     77  promise_test(async () => {
     78    events = [];
     79    await new test_driver.Actions()
     80      .pointerMove(0, 0, {origin: initialDiv})
     81      .pointerMove(0, 0, {origin: img1}) // actually moved over area1-1
     82      .pointerMove(0, 0, {origin: img2}) // actually moved in area1-1
     83      .pointerMove(0, 0, {origin: initialDiv})
     84      .send();
     85    assert_equals(
     86      stringifyEvents(events),
     87      stringifyEvents([
     88        {type: "pointerover",  target: area1_1},
     89        {type: "pointerenter", target: container},
     90        {type: "pointerenter", target: map1},
     91        {type: "pointerenter", target: area1_1},
     92        {type: "pointermove",  target: area1_1},
     93        // boundary events shouldn't be fired when moving from img1 to img2
     94        {type: "pointermove",  target: area1_1},
     95        {type: "pointerout",   target: area1_1},
     96        {type: "pointerleave", target: area1_1},
     97        {type: "pointerleave", target: map1},
     98        {type: "pointerleave", target: container},
     99      ])
    100    );
    101  }, "pointer boundary events when moved from an <area> to the same <area> shared by another <img>");
    102 
    103  promise_test(async t => {
    104    events = [];
    105    function shrinkArea1_1() {
    106      area1_1.setAttribute("coords", "0,0,10,10");
    107      t.add_cleanup(() => {
    108        area1_1.setAttribute("coords", "0,0,100,100");
    109      });
    110    }
    111    area1_1.addEventListener("pointermove", shrinkArea1_1, {once: true});
    112    t.add_cleanup(() => area1_1.removeEventListener("pointermove", shrinkArea1_1));
    113    await new test_driver.Actions()
    114      .pointerMove(0, 0, {origin: initialDiv})
    115      .pointerMove(0, 0, {origin: img1}) // actually moved over area1-1
    116      .addTick(100) // now, over the <img>
    117      .addTick() // for Firefox bug 1994340
    118      .pointerMove(0, 0, {origin: initialDiv})
    119      .send();
    120    assert_equals(
    121      stringifyEvents(events),
    122      stringifyEvents([
    123        {type: "pointerover",  target: area1_1},
    124        {type: "pointerenter", target: container},
    125        {type: "pointerenter", target: map1},
    126        {type: "pointerenter", target: area1_1},
    127        {type: "pointermove",  target: area1_1},
    128        // Now, the <area> is shrunken and the cursor is not over the <area>.
    129        {type: "pointerout",   target: area1_1},
    130        {type: "pointerleave", target: area1_1},
    131        {type: "pointerleave", target: map1},
    132        {type: "pointerover",  target: img1},
    133        {type: "pointerenter", target: img1},
    134        // Then, move out from the <img>.
    135        {type: "pointerout",   target: img1},
    136        {type: "pointerleave", target: img1},
    137        {type: "pointerleave", target: container},
    138      ])
    139    );
    140  }, "pointer boundary events when the <area> is resized");
    141 
    142  promise_test(async t => {
    143    events = [];
    144    function shrinkArea1_1() {
    145      area1_1.setAttribute("coords", "0,0,10,10");
    146      img1.setAttribute("width", "200");
    147      img1.getBoundingClientRect();
    148      t.add_cleanup(() => {
    149        img1.setAttribute("width", "100");
    150        area1_1.setAttribute("coords", "0,0,100,100");
    151        img1.getBoundingClientRect();
    152      });
    153    }
    154    area1_1.addEventListener("pointermove", shrinkArea1_1, {once: true});
    155    t.add_cleanup(() => area1_1.removeEventListener("pointermove", shrinkArea1_1));
    156    await new test_driver.Actions()
    157      .pointerMove(0, 0, {origin: initialDiv})
    158      .pointerMove(0, 0, {origin: img1}) // actually moved over area1-1
    159      .addTick() // now over the <img>
    160      .pointerMove(0, 0, {origin: initialDiv})
    161      .send();
    162    assert_equals(
    163      stringifyEvents(events),
    164      stringifyEvents([
    165        {type: "pointerover",  target: area1_1},
    166        {type: "pointerenter", target: container},
    167        {type: "pointerenter", target: map1},
    168        {type: "pointerenter", target: area1_1},
    169        {type: "pointermove",  target: area1_1},
    170        // Now, the <area> is shrunken and the cursor is not over the <area>.
    171        {type: "pointerout",   target: area1_1},
    172        {type: "pointerleave", target: area1_1},
    173        {type: "pointerleave", target: map1},
    174        {type: "pointerover",  target: img1},
    175        {type: "pointerenter", target: img1},
    176        // Then, move out from the <img>.
    177        {type: "pointerout",   target: img1},
    178        {type: "pointerleave", target: img1},
    179        {type: "pointerleave", target: container},
    180      ])
    181    );
    182  }, "pointer boundary events when both <area> and <img> are resized");
    183 
    184  promise_test(async t => {
    185    events = [];
    186    function switchMap() {
    187      img1.setAttribute("usemap", "#map2");
    188      t.add_cleanup(() => {
    189        img1.setAttribute("usemap", "#map1");
    190      });
    191    }
    192    area1_1.addEventListener("pointermove", switchMap, {once: true});
    193    t.add_cleanup(() => area1_1.removeEventListener("pointermove", switchMap));
    194    await new test_driver.Actions()
    195      .pointerMove(0, 0, {origin: initialDiv})
    196      .pointerMove(0, 0, {origin: img1}) // actually moved over area1-1
    197      .addTick(100) // now over area2-1
    198      .addTick() // for Firefox bug 1994340
    199      .pointerMove(0, 0, {origin: initialDiv})
    200      .send();
    201    assert_equals(
    202      stringifyEvents(events),
    203      stringifyEvents([
    204        {type: "pointerover",  target: area1_1},
    205        {type: "pointerenter", target: container},
    206        {type: "pointerenter", target: map1},
    207        {type: "pointerenter", target: area1_1},
    208        {type: "pointermove",  target: area1_1},
    209        // Now, the #map2 is the image map definition and over its area2-1
    210        {type: "pointerout",   target: area1_1},
    211        {type: "pointerleave", target: area1_1},
    212        {type: "pointerleave", target: map1},
    213        {type: "pointerover",  target: area2_1},
    214        {type: "pointerenter", target: map2},
    215        {type: "pointerenter", target: area2_1},
    216        // Then, move out from the <area>.
    217        {type: "pointerout",   target: area2_1},
    218        {type: "pointerleave", target: area2_1},
    219        {type: "pointerleave", target: map2},
    220        {type: "pointerleave", target: container},
    221      ])
    222    );
    223  }, "pointer boundary events when usemap is modified");
    224 
    225  promise_test(async t => {
    226    events = [];
    227    function switchMap() {
    228      img1.setAttribute("usemap", "#map2");
    229      img1.setAttribute("width", "200");
    230      img1.getBoundingClientRect();
    231      t.add_cleanup(() => {
    232        img1.setAttribute("usemap", "#map1");
    233        img1.setAttribute("width", "100");
    234        img1.getBoundingClientRect();
    235      });
    236    }
    237    area1_1.addEventListener("pointermove", switchMap, {once: true});
    238    t.add_cleanup(() => area1_1.removeEventListener("pointermove", switchMap));
    239    await new test_driver.Actions()
    240      .pointerMove(0, 0, {origin: initialDiv})
    241      .pointerMove(0, 0, {origin: img1}) // actually moved over area1-1
    242      .addTick() // now over area2-1
    243      .pointerMove(0, 0, {origin: initialDiv})
    244      .send();
    245    assert_equals(
    246      stringifyEvents(events),
    247      stringifyEvents([
    248        {type: "pointerover",  target: area1_1},
    249        {type: "pointerenter", target: container},
    250        {type: "pointerenter", target: map1},
    251        {type: "pointerenter", target: area1_1},
    252        {type: "pointermove",  target: area1_1},
    253        // Now, the #map2 is the image map definition and over its area2-1
    254        {type: "pointerout",   target: area1_1},
    255        {type: "pointerleave", target: area1_1},
    256        {type: "pointerleave", target: map1},
    257        {type: "pointerover",  target: area2_1},
    258        {type: "pointerenter", target: map2},
    259        {type: "pointerenter", target: area2_1},
    260        // Then, move out from the <area>.
    261        {type: "pointerout",   target: area2_1},
    262        {type: "pointerleave", target: area2_1},
    263        {type: "pointerleave", target: map2},
    264        {type: "pointerleave", target: container},
    265      ])
    266    );
    267  }, "pointer boundary events when usemap is modified and <img> is resized");
    268 
    269  promise_test(async t => {
    270    events = [];
    271    function appendArea1_2() {
    272      map1.insertBefore(area1_2, area1_1);
    273      t.add_cleanup(() => {
    274        area1_2.remove();
    275      });
    276    }
    277    area1_1.addEventListener("pointermove", appendArea1_2, {once: true});
    278    t.add_cleanup(() => area1_1.removeEventListener("pointermove", appendArea1_2));
    279    await new test_driver.Actions()
    280      .pointerMove(0, 0, {origin: initialDiv})
    281      .pointerMove(0, 0, {origin: img1}) // actually moved over area1-1
    282      .addTick(100) // now, over the area1-2
    283      .addTick() // for Firefox bug 1994340
    284      .pointerMove(0, 0, {origin: initialDiv})
    285      .send();
    286    assert_equals(
    287      stringifyEvents(events),
    288      stringifyEvents([
    289        {type: "pointerover",  target: area1_1},
    290        {type: "pointerenter", target: container},
    291        {type: "pointerenter", target: map1},
    292        {type: "pointerenter", target: area1_1},
    293        {type: "pointermove",  target: area1_1},
    294        // Now, new <area> is inserted and it's the top-most.
    295        {type: "pointerout",   target: area1_1},
    296        {type: "pointerleave", target: area1_1},
    297        {type: "pointerover",  target: area1_2},
    298        {type: "pointerenter", target: area1_2},
    299        // Then, move out from the <img>.
    300        {type: "pointerout",   target: area1_2},
    301        {type: "pointerleave", target: area1_2},
    302        {type: "pointerleave", target: map1},
    303        {type: "pointerleave", target: container},
    304      ])
    305    );
    306  }, "pointer boundary events when new <area> is available");
    307 
    308  promise_test(async t => {
    309    events = [];
    310    function appendArea1_2() {
    311      map1.insertBefore(area1_2, area1_1);
    312      img1.setAttribute("width", "200");
    313      img1.getBoundingClientRect();
    314      t.add_cleanup(() => {
    315        area1_2.remove();
    316        img1.setAttribute("width", "100");
    317        img1.getBoundingClientRect();
    318      });
    319    }
    320    area1_1.addEventListener("pointermove", appendArea1_2, {once: true});
    321    t.add_cleanup(() => area1_1.removeEventListener("pointermove", appendArea1_2));
    322    await new test_driver.Actions()
    323      .pointerMove(0, 0, {origin: initialDiv})
    324      .pointerMove(0, 0, {origin: img1}) // actually moved over area1-1
    325      .addTick() // now, over the area1-2
    326      .pointerMove(0, 0, {origin: initialDiv})
    327      .send();
    328    assert_equals(
    329      stringifyEvents(events),
    330      stringifyEvents([
    331        {type: "pointerover",  target: area1_1},
    332        {type: "pointerenter", target: container},
    333        {type: "pointerenter", target: map1},
    334        {type: "pointerenter", target: area1_1},
    335        {type: "pointermove",  target: area1_1},
    336        // Now, new <area> is inserted and it's the top-most.
    337        {type: "pointerout",   target: area1_1},
    338        {type: "pointerleave", target: area1_1},
    339        {type: "pointerover",  target: area1_2},
    340        {type: "pointerenter", target: area1_2},
    341        // Then, move out from the <img>.
    342        {type: "pointerout",   target: area1_2},
    343        {type: "pointerleave", target: area1_2},
    344        {type: "pointerleave", target: map1},
    345        {type: "pointerleave", target: container},
    346      ])
    347    );
    348  }, "pointer boundary events when new <area> is available and the <img> is resized");
    349 }, {once: true});
    350 </script>
    351 <style>
    352 img {
    353  margin: 0;
    354  border: none;
    355 }
    356 div {
    357  margin: 0;
    358  width: 200px;
    359  white-space: nowrap;
    360 }
    361 </style>
    362 </head>
    363 <body>
    364  <div id="init">initial position</div>
    365  <div id="container">
    366    <map id="map1">
    367      <area id="area1-1" shape="rect" coords="0,0,100,100" href="#">
    368    </map>
    369    <map id="map2">
    370      <area id="area2-1" shape="rect" coords="0,0,100,100" href="#">
    371    </map>
    372    <img id="img1" usemap="#map1" src="../images/green-16x16.png" width="100" height="100">
    373    <img id="img2" usemap="#map1" src="../images/green-16x16.png" width="100" height="100">
    374  </div>
    375 </body>
    376 </html>