tor-browser

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

browser_treeWidget_mouse_interaction.js (4746B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 // Tests that mouse interaction works fine with tree widget
      7 
      8 const TEST_URI =
      9  "data:text/html;charset=utf-8,<head>" +
     10  "<link rel='stylesheet' type='text/css' href='chrome://devtools/skin/widg" +
     11  "ets.css'></head><body><div></div><span></span></body>";
     12 const {
     13  TreeWidget,
     14 } = require("resource://devtools/client/shared/widgets/TreeWidget.js");
     15 
     16 add_task(async function () {
     17  await SpecialPowers.pushPrefEnv({
     18    set: [["security.allow_unsafe_parent_loads", true]],
     19  });
     20 
     21  await addTab("about:blank");
     22  const { host, doc } = await createHost("bottom", TEST_URI);
     23 
     24  // Creating a host is not correctly waiting when DevTools run in content frame
     25  // See Bug 1571421.
     26  await wait(1000);
     27 
     28  const tree = new TreeWidget(doc.querySelector("div"), {
     29    defaultType: "store",
     30  });
     31 
     32  populateTree(tree, doc);
     33  await testMouseInteraction(tree);
     34 
     35  tree.destroy();
     36  host.destroy();
     37  gBrowser.removeCurrentTab();
     38 });
     39 
     40 function populateTree(tree, doc) {
     41  tree.add([
     42    {
     43      id: "level1",
     44      label: "Level 1",
     45    },
     46    {
     47      id: "level2-1",
     48      label: "Level 2",
     49    },
     50    {
     51      id: "level3-1",
     52      label: "Level 3 - Child 1",
     53      type: "dir",
     54    },
     55  ]);
     56  tree.add([
     57    "level1",
     58    "level2-1",
     59    { id: "level3-2", label: "Level 3 - Child 2" },
     60  ]);
     61  tree.add([
     62    "level1",
     63    "level2-1",
     64    { id: "level3-3", label: "Level 3 - Child 3" },
     65  ]);
     66  tree.add([
     67    "level1",
     68    {
     69      id: "level2-2",
     70      label: "Level 2.1",
     71    },
     72    {
     73      id: "level3-1",
     74      label: "Level 3.1",
     75    },
     76  ]);
     77  tree.add([
     78    {
     79      id: "level1",
     80      label: "Level 1",
     81    },
     82    {
     83      id: "level2",
     84      label: "Level 2",
     85    },
     86    {
     87      id: "level3",
     88      label: "Level 3",
     89      type: "js",
     90    },
     91  ]);
     92  tree.add(["level1.1", "level2", { id: "level3", type: "url" }]);
     93 
     94  // Adding a new non text item in the tree.
     95  const node = doc.createElement("div");
     96  node.textContent = "Foo Bar";
     97  node.className = "foo bar";
     98  tree.add([
     99    {
    100      id: "level1.2",
    101      node,
    102      attachment: {
    103        foo: "bar",
    104      },
    105    },
    106  ]);
    107 }
    108 
    109 // Sends a click event on the passed DOM node in an async manner
    110 function click(node) {
    111  const win = node.ownerDocument.defaultView;
    112  executeSoon(() => EventUtils.synthesizeMouseAtCenter(node, {}, win));
    113 }
    114 
    115 /**
    116 * Tests if clicking the tree items does the expected behavior
    117 */
    118 async function testMouseInteraction(tree) {
    119  info("Testing mouse interaction with the tree");
    120  const waitForSelect = () =>
    121    new Promise(resolve => {
    122      tree.once("select", (d, a) => resolve({ data: d, attachment: a }));
    123    });
    124 
    125  ok(!tree.selectedItem, "Nothing should be selected beforehand");
    126 
    127  let onTreeSelect = waitForSelect();
    128  const node = tree.root.children.firstChild.firstChild;
    129  info("clicking on first top level item");
    130  ok(
    131    !node.classList.contains("theme-selected"),
    132    "Node should not have selected class before clicking"
    133  );
    134  click(node);
    135  let { data, attachment } = await onTreeSelect;
    136  ok(
    137    node.classList.contains("theme-selected"),
    138    "Node has selected class after click"
    139  );
    140  is(data[0], "level1.2", "Correct tree path is emitted");
    141  ok(attachment && attachment.foo, "Correct attachment is emitted");
    142  is(attachment.foo, "bar", "Correct attachment value is emitted");
    143 
    144  info("clicking second top level item with children to check if it expands");
    145  const node2 = tree.root.children.firstChild.nextSibling.firstChild;
    146  // node should not have selected class
    147  ok(
    148    !node2.classList.contains("theme-selected"),
    149    "New node should not have selected class before clicking"
    150  );
    151  ok(
    152    !node2.hasAttribute("expanded"),
    153    "New node is not expanded before clicking"
    154  );
    155  onTreeSelect = waitForSelect();
    156  click(node2);
    157  ({ data, attachment } = await onTreeSelect);
    158  ok(
    159    node2.classList.contains("theme-selected"),
    160    "New node has selected class after clicking"
    161  );
    162  is(data[0], "level1", "Correct tree path is emitted for new node");
    163  ok(!attachment, "null attachment should be emitted for new node");
    164  ok(node2.hasAttribute("expanded"), "New node expanded after click");
    165 
    166  ok(
    167    !node.classList.contains("theme-selected"),
    168    "Old node should not have selected class after the click on new node"
    169  );
    170 
    171  // clicking again should just collapse
    172  // this will not emit "select" event
    173  const onClick = new Promise(resolve => {
    174    node2.addEventListener(
    175      "click",
    176      () => {
    177        executeSoon(() => resolve(null));
    178      },
    179      { once: true }
    180    );
    181  });
    182  click(node2);
    183  await onClick;
    184  ok(!node2.hasAttribute("expanded"), "New node collapsed after click again");
    185 }