tor-browser

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

mouseover-at-removing-mousedown-target.html (2855B)


      1 <!doctype html>
      2 <html>
      3 <head>
      4 <meta charset="utf-8">
      5 <meta name="timeout" content="long">
      6 <meta name="variant" content="?duration=16"> <!-- 60fps -->
      7 <meta name="variant" content="?duration=42"> <!-- 24fps -->
      8 <title>Check whether `mouseup` events are fired after pending boundary events</title>
      9 <script src=/resources/testharness.js></script>
     10 <script src=/resources/testharnessreport.js></script>
     11 <script src=/resources/testdriver.js></script>
     12 <script src=/resources/testdriver-actions.js></script>
     13 <script src=/resources/testdriver-vendor.js></script>
     14 <style>
     15 div#parent {
     16  width: 100%;
     17  height: 50px;
     18  background-color: gray;
     19 }
     20 div#child {
     21  width: 100%;
     22  height: 40px;
     23  background-color: lime;
     24 }
     25 </style>
     26 </head>
     27 <body>
     28 <div id="parent"><div id="child"></div></div>
     29 <script>
     30 "use strict";
     31 
     32 const searchParams = new URLSearchParams(document.location.search);
     33 const duration = parseInt(searchParams.get("duration"));
     34 
     35 async function runTest(t) {
     36  const parent = document.getElementById("parent");
     37  const child = document.getElementById("child");
     38  const mouseEvents = [];
     39  function onMouseOverOrUp(event) {
     40    // Ignore events before `mousedown` to make this test simpler.
     41    if (mouseEvents[0]?.startsWith("mousedown")) {
     42      mouseEvents.push(`${event.type}@${event.target.localName}${event.target.id ? `#${event.target.id}` : ""}`);
     43    }
     44  }
     45  try {
     46    child.getBoundingClientRect(); // flush layout
     47    child.addEventListener("mousedown", event => {
     48      event.target.remove();
     49      mouseEvents.push("mousedown@div#child");
     50    }, {once: true});
     51    document.addEventListener("mouseover", onMouseOverOrUp, {capture: true});
     52    document.addEventListener("mouseup", onMouseOverOrUp, {once: true, capture: true});
     53    const actions = new test_driver.Actions(duration);
     54    await actions.pointerMove(10, 10, {origin: child})
     55                .pointerDown({button: actions.ButtonType.LEFT})
     56                .pointerUp({button: actions.ButtonType.LEFT})
     57                .send();
     58    await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
     59    assert_equals(
     60      mouseEvents.toString(),
     61      "mousedown@div#child,mouseover@div#parent,mouseup@div#parent",
     62      t.name
     63    );
     64  } finally {
     65    document.removeEventListener("mouseover", onMouseOverOrUp, {capture: true});
     66    parent.appendChild(child);
     67  }
     68 }
     69 
     70 // This test tries to detect intermittent case that mouseout might be fired
     71 // after a while from a DOM tree change.  Therefore, trying same test 30 times.
     72 for (let i = 0; i < 30; i++) {
     73  promise_test(async t => {
     74    await runTest(t);
     75    // Make things stabler to start next test.
     76    await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
     77  }, `mouseover should be fired before mouseup if mousedown target is removed (${i})`);
     78 }
     79 </script>
     80 </body>
     81 </html>