tor-browser

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

mouseevents-after-touchend.tentative.html (9800B)


      1 <!doctype html>
      2 <html>
      3 <head>
      4 <meta charset="utf-8">
      5 <meta name="timeout" content="long">
      6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
      7 <title>Mouse events for compatibility after a tap</title>
      8 <script src="/resources/testharness.js"></script>
      9 <script src="/resources/testharnessreport.js"></script>
     10 <script src="/resources/testdriver.js"></script>
     11 <script src="/resources/testdriver-actions.js"></script>
     12 <script src="/resources/testdriver-vendor.js"></script>
     13 <style>
     14 #parent, #child {
     15  width: 300px;
     16  height: 64px;
     17  padding: 16px;
     18 }
     19 #parent {
     20  background-color: black;
     21 }
     22 #child {
     23  background-color: gray;
     24 }
     25 </style>
     26 <script>
     27 "use strict";
     28 
     29 addEventListener("load", t => {
     30  let events = [];
     31  for (const type of ["mousemove",
     32                      "mousedown",
     33                      "mouseup",
     34                      "click",
     35                      "dblclick",
     36                      "contextmenu",
     37                      "touchend"]) {
     38    if (type == "touchend") {
     39      addEventListener(type, event => {
     40        events.push({type: type, target: event.target});
     41      }, {capture: true});
     42    } else {
     43      addEventListener(type, event => {
     44        events.push({
     45          type: event.type,
     46          target: event.target,
     47          detail: event.detail,
     48          button: event.button,
     49          buttons: event.buttons,
     50        });
     51      }, {capture: true});
     52    }
     53  }
     54 
     55  function stringifyEvents(arrayOfEvents) {
     56    if (!arrayOfEvents.length) {
     57      return "[]";
     58    }
     59    function stringifyEvent(event) {
     60      return `{ type: ${event.type}, target: ${
     61        event.target.id || event.target.nodeName
     62      }${
     63        event.detail !== undefined ? `, detail: ${event.detail}` : ""
     64      }${
     65        event.button !== undefined ? `, button: ${event.button}` : ""
     66      }${
     67        event.buttons !== undefined ? `, buttons: ${event.buttons}` : ""
     68      } }`;
     69    }
     70    let ret = "";
     71    for (const event of arrayOfEvents) {
     72      if (ret === "") {
     73        ret = "[ ";
     74      } else {
     75        ret += ", ";
     76      }
     77      ret += stringifyEvent(event);
     78    }
     79    return ret + " ]";
     80  }
     81  const child = document.getElementById("child");
     82  const parent = child.parentNode;
     83 
     84  function promiseInitPointer() {
     85    return new test_driver.Actions()
     86      .addPointer("touchPointer", "touch")
     87      .pointerMove(0, 0, {origin: document.body})
     88      .send();
     89  }
     90  promise_test(async () => {
     91    await promiseInitPointer();
     92    events = [];
     93    await new test_driver.Actions()
     94      .addPointer("touchPointer", "touch")
     95      .pointerMove(5, 5, {origin: child})
     96      .pointerDown()
     97      .pointerUp()
     98      .send();
     99    assert_equals(
    100      stringifyEvents(events),
    101      stringifyEvents([
    102        { type: "touchend", target: child },
    103        { type: "mousemove", target: child, detail: 0, button: 0, buttons: 0 },
    104        { type: "mousedown", target: child, detail: 1, button: 0, buttons: 1 },
    105        { type: "mouseup", target: child, detail: 1, button: 0, buttons: 0 },
    106        { type: "click", target: child, detail: 1, button: 0, buttons: 0 },
    107      ])
    108    );
    109  }, "Single tap should cause a click");
    110 
    111  promise_test(async () => {
    112    await promiseInitPointer();
    113    events = [];
    114    child.addEventListener("touchstart", event => {
    115      event.preventDefault();
    116    }, {once: true});
    117    await new test_driver.Actions()
    118      .addPointer("touchPointer", "touch")
    119      .pointerMove(105, 5, {origin: child})
    120      .pointerDown()
    121      .pointerUp()
    122      .send();
    123    assert_equals(
    124      stringifyEvents(events),
    125      stringifyEvents([
    126        { type: "touchend", target: child },
    127      ])
    128    );
    129  }, "Single tap whose touchstart is consumed should not cause a click");
    130 
    131  promise_test(async () => {
    132    await promiseInitPointer();
    133    events = [];
    134    child.addEventListener("touchend", event => {
    135      event.preventDefault();
    136    }, {once: true});
    137    await new test_driver.Actions()
    138      .addPointer("touchPointer", "touch")
    139      .pointerMove(105, 5, {origin: child})
    140      .pointerDown()
    141      .pointerUp()
    142      .send();
    143    assert_equals(
    144      stringifyEvents(events),
    145      stringifyEvents([
    146        { type: "touchend", target: child },
    147      ])
    148    );
    149  }, "Single tap whose touchend is consumed should not cause a click");
    150 
    151  promise_test(async () => {
    152    await promiseInitPointer();
    153    events = [];
    154    await new test_driver.Actions()
    155      .addPointer("touchPointer", "touch")
    156      .pointerMove(5, 5, {origin: child})
    157      .pointerDown()
    158      .pointerUp()
    159      .pointerDown()
    160      .pointerUp()
    161      .send();
    162    assert_in_array(
    163      stringifyEvents(events),
    164      [
    165        // Currently, WebDriver does not have a strict way to synthesize a
    166        // double click, therefore, it's fine either single click twice or
    167        // a set of a double-click.
    168        stringifyEvents([
    169          { type: "touchend", target: child },
    170          { type: "mousemove", target: child, detail: 0, button: 0, buttons: 0 },
    171          { type: "mousedown", target: child, detail: 1, button: 0, buttons: 1 },
    172          { type: "mouseup", target: child, detail: 1, button: 0, buttons: 0 },
    173          { type: "click", target: child, detail: 1, button: 0, buttons: 0 },
    174          { type: "touchend", target: child },
    175          { type: "mousemove", target: child, detail: 0, button: 0, buttons: 0 },
    176          { type: "mousedown", target: child, detail: 1, button: 0, buttons: 1 },
    177          { type: "mouseup", target: child, detail: 1, button: 0, buttons: 0 },
    178          { type: "click", target: child, detail: 1, button: 0, buttons: 0 },
    179        ]),
    180        stringifyEvents([
    181          { type: "touchend", target: child },
    182          { type: "mousemove", target: child, detail: 0, button: 0, buttons: 0 },
    183          { type: "mousedown", target: child, detail: 1, button: 0, buttons: 1 },
    184          { type: "mouseup", target: child, detail: 1, button: 0, buttons: 0 },
    185          { type: "click", target: child, detail: 1, button: 0, buttons: 0 },
    186          { type: "touchend", target: child },
    187          { type: "mousemove", target: child, detail: 0, button: 0, buttons: 0 },
    188          { type: "mousedown", target: child, detail: 2, button: 0, buttons: 1 },
    189          { type: "mouseup", target: child, detail: 2, button: 0, buttons: 0 },
    190          { type: "click", target: child, detail: 2, button: 0, buttons: 0 },
    191          { type: "dblclick", target: child, detail: 2, button: 0, buttons: 0 },
    192        ]),
    193      ],
    194    );
    195  }, "Double tap should cause single-click twice or a double-click");
    196 
    197  promise_test(async () => {
    198    await promiseInitPointer();
    199    events = [];
    200    await new test_driver.Actions()
    201      .addPointer("touchPointer", "touch")
    202      .pointerMove(105, 5, {origin: child})
    203      .pointerDown()
    204      .pointerUp()
    205      .pause(1000)
    206      .pointerDown()
    207      .pointerUp()
    208      .send();
    209    assert_equals(
    210      stringifyEvents(events),
    211      stringifyEvents([
    212        { type: "touchend", target: child },
    213        { type: "mousemove", target: child, detail: 0, button: 0, buttons: 0 },
    214        { type: "mousedown", target: child, detail: 1, button: 0, buttons: 1 },
    215        { type: "mouseup", target: child, detail: 1, button: 0, buttons: 0 },
    216        { type: "click", target: child, detail: 1, button: 0, buttons: 0 },
    217        { type: "touchend", target: child },
    218        { type: "mousemove", target: child, detail: 0, button: 0, buttons: 0 },
    219        { type: "mousedown", target: child, detail: 1, button: 0, buttons: 1 },
    220        { type: "mouseup", target: child, detail: 1, button: 0, buttons: 0 },
    221        { type: "click", target: child, detail: 1, button: 0, buttons: 0 },
    222      ])
    223    );
    224  }, "Tapping twice slowly should not cause a dblclick");
    225 
    226  promise_test(async () => {
    227    await promiseInitPointer();
    228    events = [];
    229    await new test_driver.Actions()
    230      .addPointer("touchPointer", "touch")
    231      .pointerMove(5, 5, {origin: child})
    232      .pointerDown()
    233      .pointerUp()
    234      .pointerMove(100, 5, {origin: child})
    235      .pointerDown()
    236      .pointerUp()
    237      .send();
    238    assert_equals(
    239      stringifyEvents(events),
    240      stringifyEvents([
    241        { type: "touchend", target: child },
    242        { type: "mousemove", target: child, detail: 0, button: 0, buttons: 0 },
    243        { type: "mousedown", target: child, detail: 1, button: 0, buttons: 1 },
    244        { type: "mouseup", target: child, detail: 1, button: 0, buttons: 0 },
    245        { type: "click", target: child, detail: 1, button: 0, buttons: 0 },
    246        { type: "touchend", target: child },
    247        { type: "mousemove", target: child, detail: 0, button: 0, buttons: 0 },
    248        { type: "mousedown", target: child, detail: 1, button: 0, buttons: 1 },
    249        { type: "mouseup", target: child, detail: 1, button: 0, buttons: 0 },
    250        { type: "click", target: child, detail: 1, button: 0, buttons: 0 },
    251      ])
    252    );
    253  }, "Tapping too far points should not cause a dblclick");
    254 
    255  promise_test(async () => {
    256    await promiseInitPointer();
    257    events = [];
    258    await new test_driver.Actions()
    259      .addPointer("touchPointer", "touch")
    260      .addPointer("touchPointer2", "touch")
    261      .pointerMove(5, 5, {origin: child, sourceName: "touchPointer"})
    262      .pointerMove(25, 25, {origin: child, sourceName: "touchPointer2"})
    263      .pointerDown({sourceName: "touchPointer"})
    264      .pointerDown({sourceName: "touchPointer2"})
    265      .pointerUp({sourceName: "touchPointer"})
    266      .pointerUp({sourceName: "touchPointer2"})
    267      .send();
    268    assert_equals(
    269      stringifyEvents(events),
    270      stringifyEvents([
    271        { type: "touchend", target: child },
    272        { type: "touchend", target: child },
    273      ])
    274    );
    275  }, "Multi tap should not cause mouse events");
    276 }, {once: true});
    277 </script>
    278 </head>
    279 <body><div id="parent"><div id="child"></div></div></body>
    280 </html>