tor-browser

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

browser_canvasframe_helper_05.js (4380B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 // Test some edge cases of the CanvasFrameAnonymousContentHelper event handling
      7 // mechanism.
      8 
      9 const TEST_URL =
     10  "data:text/html;charset=utf-8,CanvasFrameAnonymousContentHelper test";
     11 
     12 add_task(async function () {
     13  const tab = await addTab(TEST_URL);
     14  await SpecialPowers.spawn(tab.linkedBrowser, [], async function () {
     15    const { require } = ChromeUtils.importESModule(
     16      "resource://devtools/shared/loader/Loader.sys.mjs"
     17    );
     18    const {
     19      HighlighterEnvironment,
     20    } = require("resource://devtools/server/actors/highlighters.js");
     21    const {
     22      CanvasFrameAnonymousContentHelper,
     23    } = require("resource://devtools/server/actors/highlighters/utils/markup.js");
     24    const doc = content.document;
     25 
     26    const nodeBuilder = () => {
     27      const root = doc.createElement("div");
     28 
     29      const parent = doc.createElement("div");
     30      parent.style =
     31        "pointer-events:auto;width:300px;height:300px;background:yellow;";
     32      parent.id = "parent-element";
     33      root.appendChild(parent);
     34 
     35      const child = doc.createElement("div");
     36      child.style =
     37        "pointer-events:auto;width:200px;height:200px;background:red;";
     38      child.id = "child-element";
     39      parent.appendChild(child);
     40 
     41      return root;
     42    };
     43 
     44    info("Building the helper");
     45    const env = new HighlighterEnvironment();
     46    env.initFromWindow(doc.defaultView);
     47    const helper = new CanvasFrameAnonymousContentHelper(env, nodeBuilder);
     48    await helper.initialize();
     49 
     50    info("Getting the parent and child elements");
     51    const parentEl = helper.getElement("parent-element");
     52    const childEl = helper.getElement("child-element");
     53 
     54    info("Adding an event listener on both elements");
     55    let mouseDownHandled = [];
     56    function onMouseDown(e, id) {
     57      mouseDownHandled.push(id);
     58    }
     59    parentEl.addEventListener("mousedown", onMouseDown);
     60    childEl.addEventListener("mousedown", onMouseDown);
     61 
     62    function once(target, event) {
     63      return new Promise(done => {
     64        target.addEventListener(event, done, { once: true });
     65      });
     66    }
     67 
     68    info("Synthesizing an event on the child element");
     69    let onDocMouseDown = once(doc, "mousedown");
     70    synthesizeMouseDown(100, 100, doc.defaultView);
     71    await onDocMouseDown;
     72 
     73    is(mouseDownHandled.length, 2, "The mousedown event was handled twice");
     74    is(
     75      mouseDownHandled[0],
     76      "child-element",
     77      "The mousedown event was handled on the child element"
     78    );
     79    is(
     80      mouseDownHandled[1],
     81      "parent-element",
     82      "The mousedown event was handled on the parent element"
     83    );
     84 
     85    info("Synthesizing an event on the parent, outside of the child element");
     86    mouseDownHandled = [];
     87    onDocMouseDown = once(doc, "mousedown");
     88    synthesizeMouseDown(250, 250, doc.defaultView);
     89    await onDocMouseDown;
     90 
     91    is(mouseDownHandled.length, 1, "The mousedown event was handled only once");
     92    is(
     93      mouseDownHandled[0],
     94      "parent-element",
     95      "The mousedown event was handled on the parent element"
     96    );
     97 
     98    info("Removing the event listener");
     99    parentEl.removeEventListener("mousedown", onMouseDown);
    100    childEl.removeEventListener("mousedown", onMouseDown);
    101 
    102    info("Adding an event listener on the parent element only");
    103    mouseDownHandled = [];
    104    parentEl.addEventListener("mousedown", onMouseDown);
    105 
    106    info("Synthesizing an event on the child element");
    107    onDocMouseDown = once(doc, "mousedown");
    108    synthesizeMouseDown(100, 100, doc.defaultView);
    109    await onDocMouseDown;
    110 
    111    is(mouseDownHandled.length, 1, "The mousedown event was handled once");
    112    is(
    113      mouseDownHandled[0],
    114      "parent-element",
    115      "The mousedown event did bubble to the parent element"
    116    );
    117 
    118    info("Removing the parent listener");
    119    parentEl.removeEventListener("mousedown", onMouseDown);
    120 
    121    env.destroy();
    122    helper.destroy();
    123 
    124    function synthesizeMouseDown(x, y, win) {
    125      // We need to make sure the inserted anonymous content can be targeted by the
    126      // event right after having been inserted, and so we need to force a sync
    127      // reflow.
    128      win.document.documentElement.offsetWidth;
    129      EventUtils.synthesizeMouseAtPoint(x, y, { type: "mousedown" }, win);
    130    }
    131  });
    132 
    133  gBrowser.removeCurrentTab();
    134 });