tor-browser

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

pointerevent_pointerrawupdate_remove_target.https.html (5546B)


      1 <!doctype html>
      2 <html>
      3 <head>
      4 <meta charset="utf-8">
      5 <meta name="viewport" content="width=device-width, initial-scale:1">
      6 <title>If a `pointerrawupdate` listener removes the target, `pointermove` should be fired its connected ancestor</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 /**
     16 * `pointerrawupdate` is defined as:
     17 * > The target of pointerrawupdate events might be different from the
     18 * > pointermove events due to the fact that pointermove events might get
     19 * > delayed or coalesced, and the final position of the event which is used
     20 * > for finding the target could be different from its coalesced events.
     21 *
     22 * This checks whether `pointermove` is fired on the latest element underneath
     23 * the pointer when the `pointerrawupdate` event listener removes its target.
     24 */
     25 
     26 addEventListener("DOMContentLoaded", () => {
     27  const testContainer = document.getElementById("testContainer");
     28  let events = [];
     29  function logEvent(event) {
     30    if (event.eventPhase != Event.AT_TARGET) {
     31      return;
     32    }
     33    events.push(`${event.type}@${event.target.id ? event.target.id : `<${event.target.nodeName}>`}`);
     34  }
     35  promise_test(async () => {
     36    testContainer.innerHTML = "<div id=container><div id=init></div><div id=target></div></div>";
     37    const initialDiv = document.getElementById("init");
     38    await new test_driver.Actions()
     39      .pointerMove(0, 0, {origin: initialDiv})
     40      .send();
     41    const target = document.getElementById("target");
     42    for (const type of ["pointerrawupdate", "pointermove", "pointerover"]) {
     43      target.addEventListener(type, logEvent);
     44    }
     45    const container = document.getElementById("container");
     46    for (const type of ["pointerrawupdate", "pointermove", "pointerover"]) {
     47      container.addEventListener(type, logEvent);
     48    }
     49    target.addEventListener("pointerrawupdate", () => {
     50      target.remove();
     51    }, {once: true});
     52    events = [];
     53    await new test_driver.Actions()
     54      .pointerMove(0, 0, {origin: target})
     55      .send();
     56    assert_equals(
     57      events.join(","),
     58      [
     59        "pointerover@target",
     60        "pointerrawupdate@target",
     61        "pointerover@container",
     62        "pointermove@container",
     63      ].join(",")
     64    );
     65  }, `"pointermove" and its preceding boundary events should be fired on parent if "pointerrawupdate" event listener removes its target`);
     66 
     67  promise_test(async () => {
     68    testContainer.innerHTML =
     69      "<div id=container><div id=container2><div id=init></div><div id=target></div></div></div>";
     70    const initialDiv = document.getElementById("init");
     71    await new test_driver.Actions()
     72      .pointerMove(0, 0, {origin: initialDiv})
     73      .send();
     74    const target = document.getElementById("target");
     75    for (const type of ["pointerrawupdate", "pointermove", "pointerover"]) {
     76      target.addEventListener(type, logEvent);
     77    }
     78    const container = document.getElementById("container");
     79    for (const type of ["pointerrawupdate", "pointermove", "pointerover"]) {
     80      container.addEventListener(type, logEvent);
     81    }
     82    target.addEventListener("pointerrawupdate", () => {
     83      target.parentNode.remove();
     84    }, {once: true});
     85    events = [];
     86    await new test_driver.Actions()
     87      .pointerMove(0, 0, {origin: target})
     88      .send();
     89    assert_equals(
     90      events.join(","),
     91      [
     92        "pointerover@target",
     93        "pointerrawupdate@target",
     94        "pointerover@container",
     95        "pointermove@container",
     96      ].join(",")
     97    );
     98  }, `"pointermove" and its preceding boundary events should be fired on ancestor if "pointerrawupdate" event listener removes its target parent`);
     99 
    100  promise_test(async () => {
    101    testContainer.innerHTML =
    102      "<div id=container><div id=init></div><iframe srcdoc='<div id=target style=height:64px></div>'></iframe></div>";
    103    const iframe = document.querySelector("iframe");
    104    if (iframe.contentDocument.readyState != "complete") {
    105      await new Promise(resolve => iframe.addEventListener("load", resolve, {once: true}));
    106    }
    107    const initialDiv = document.getElementById("init");
    108    await new test_driver.Actions()
    109      .pointerMove(0, 0, {origin: initialDiv})
    110      .send();
    111    const target = iframe.contentDocument.getElementById("target");
    112    for (const type of ["pointerrawupdate", "pointermove", "pointerover"]) {
    113      target.addEventListener(type, logEvent);
    114    }
    115    const container = document.getElementById("container");
    116    for (const type of ["pointerrawupdate", "pointermove", "pointerover"]) {
    117      container.addEventListener(type, logEvent);
    118    }
    119    target.addEventListener("pointerrawupdate", () => {
    120      iframe.remove();
    121    }, {once: true});
    122    events = [];
    123    await new test_driver.Actions()
    124      .pointerMove(0, 0, {origin: target})
    125      .send();
    126    assert_equals(
    127      events.join(", "),
    128      [
    129        "pointerover@target",
    130        "pointerrawupdate@target",
    131        "pointerover@container",
    132        "pointermove@container",
    133      ].join(", ")
    134    );
    135  }, `"pointermove" and its preceding boundary events should be fired on parent if "pointerrawupdate" event listener removes its document`);
    136 }, {once: true});
    137 </script>
    138 <style>
    139 #container, #container2 {
    140  min-height: 200px;
    141 }
    142 #target, #init {
    143  width: 64px;
    144  height: 64px;
    145 }
    146 
    147 </style>
    148 <body><div id="testContainer"></div></body>
    149 </html>