tor-browser

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

browser_inspector_pseudoclass-lock.js (7057B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 /* globals getHighlighterTestFrontWithoutToolbox */
      4 "use strict";
      5 
      6 // Test that locking the pseudoclass displays correctly in the ruleview
      7 
      8 const PSEUDO = ":hover";
      9 const TEST_URL =
     10  "data:text/html;charset=UTF-8," +
     11  "<head>" +
     12  "  <style>div {color:red;} div:hover {color:blue;}</style>" +
     13  "</head>" +
     14  "<body>" +
     15  '  <div id="parent-div">' +
     16  '    <div id="div-1">test div</div>' +
     17  '    <div id="div-2">test div2</div>' +
     18  "  </div>" +
     19  "</body>";
     20 
     21 add_task(async function () {
     22  info("Creating the test tab and opening the rule-view");
     23  let { tab, toolbox, inspector, highlighterTestFront } =
     24    await openInspectorForURL(TEST_URL);
     25 
     26  info("Selecting the ruleview sidebar");
     27  inspector.sidebar.select("ruleview");
     28 
     29  const view = inspector.getPanel("ruleview").view;
     30 
     31  info("Selecting the test node");
     32  await selectNode("#div-1", inspector);
     33 
     34  await togglePseudoClass(inspector);
     35  await assertPseudoAddedToNode(
     36    inspector,
     37    highlighterTestFront,
     38    view,
     39    "#div-1"
     40  );
     41 
     42  await togglePseudoClass(inspector);
     43  await assertPseudoRemovedFromNode(highlighterTestFront, "#div-1");
     44  await assertPseudoRemovedFromView(
     45    inspector,
     46    highlighterTestFront,
     47    view,
     48    "#div-1"
     49  );
     50 
     51  await togglePseudoClass(inspector);
     52  await testNavigate(inspector);
     53 
     54  info("Toggle pseudo on the parent and ensure everything is toggled off");
     55  await selectNode("#parent-div", inspector);
     56  await togglePseudoClass(inspector);
     57  await assertPseudoRemovedFromNode(highlighterTestFront, "#div-1");
     58  await assertPseudoRemovedFromView(
     59    inspector,
     60    highlighterTestFront,
     61    view,
     62    "#div-1"
     63  );
     64 
     65  await togglePseudoClass(inspector);
     66  info("Assert pseudo is dismissed when toggling it on a sibling node");
     67  await selectNode("#div-2", inspector);
     68  await togglePseudoClass(inspector);
     69  await assertPseudoAddedToNode(
     70    inspector,
     71    highlighterTestFront,
     72    view,
     73    "#div-2"
     74  );
     75  const hasLock = await hasPseudoClassLock("#div-1", PSEUDO);
     76  ok(
     77    !hasLock,
     78    "pseudo-class lock has been removed for the previous locked node"
     79  );
     80 
     81  info("Destroying the toolbox");
     82  await toolbox.destroy();
     83 
     84  // As the toolbox get destroyed, we need to fetch a new test-actor
     85  highlighterTestFront = await getHighlighterTestFrontWithoutToolbox(tab);
     86 
     87  await assertPseudoRemovedFromNode(highlighterTestFront, "#div-1");
     88  await assertPseudoRemovedFromNode(highlighterTestFront, "#div-2");
     89 });
     90 
     91 async function togglePseudoClass(inspector) {
     92  info("Toggle the pseudoclass, wait for it to be applied");
     93 
     94  // Give the inspector panels a chance to update when the pseudoclass changes
     95  const onPseudo = inspector.selection.once("pseudoclass");
     96  const onRefresh = inspector.once("rule-view-refreshed");
     97 
     98  // Walker uses SDK-events so calling walker.once does not return a promise.
     99  const onMutations = once(inspector.walker, "mutations");
    100 
    101  await inspector.togglePseudoClass(PSEUDO);
    102 
    103  await onPseudo;
    104  await onRefresh;
    105  await onMutations;
    106 }
    107 
    108 async function testNavigate(inspector) {
    109  await selectNode("#parent-div", inspector);
    110 
    111  info("Make sure the pseudoclass is still on after navigating to a parent");
    112 
    113  ok(
    114    await hasPseudoClassLock("#div-1", PSEUDO),
    115    "pseudo-class lock is still applied after inspecting ancestor"
    116  );
    117 
    118  await selectNode("#div-2", inspector);
    119 
    120  info(
    121    "Make sure the pseudoclass is still set after navigating to a " +
    122      "non-hierarchy node"
    123  );
    124  ok(
    125    await hasPseudoClassLock("#div-1", PSEUDO),
    126    "pseudo-class lock is still on after inspecting sibling node"
    127  );
    128 
    129  await selectNode("#div-1", inspector);
    130 }
    131 
    132 async function assertPseudoAddedToNode(
    133  inspector,
    134  highlighterTestFront,
    135  ruleview,
    136  selector
    137 ) {
    138  info(
    139    "Make sure the pseudoclass lock is applied to " +
    140      selector +
    141      " and its ancestors"
    142  );
    143 
    144  let hasLock = await hasPseudoClassLock(selector, PSEUDO);
    145  ok(hasLock, "pseudo-class lock has been applied");
    146  hasLock = await hasPseudoClassLock("#parent-div", PSEUDO);
    147  ok(hasLock, "pseudo-class lock has been applied");
    148  hasLock = await hasPseudoClassLock("body", PSEUDO);
    149  ok(hasLock, "pseudo-class lock has been applied");
    150 
    151  info("Check that the ruleview contains the pseudo-class rule");
    152  const rules = ruleview.element.querySelectorAll(".ruleview-rule");
    153  is(
    154    rules.length,
    155    3,
    156    "rule view is showing 3 rules for pseudo-class locked div"
    157  );
    158  is(
    159    rules[1]._ruleEditor.rule.selectorText,
    160    "div:hover",
    161    "rule view is showing " + PSEUDO + " rule"
    162  );
    163 
    164  info("Show the highlighter on " + selector);
    165  const nodeFront = await getNodeFront(selector, inspector);
    166  await inspector.highlighters.showHighlighterTypeForNode(
    167    inspector.highlighters.TYPES.BOXMODEL,
    168    nodeFront
    169  );
    170 
    171  info("Check that the infobar selector contains the pseudo-class");
    172  const value = await highlighterTestFront.getHighlighterNodeTextContent(
    173    "box-model-infobar-pseudo-classes"
    174  );
    175  is(value, PSEUDO, "pseudo-class in infobar selector");
    176  await inspector.highlighters.hideHighlighterType(
    177    inspector.highlighters.TYPES.BOXMODEL
    178  );
    179 }
    180 
    181 async function assertPseudoRemovedFromNode(highlighterTestFront, selector) {
    182  info(
    183    "Make sure the pseudoclass lock is removed from #div-1 and its " +
    184      "ancestors"
    185  );
    186 
    187  let hasLock = await hasPseudoClassLock(selector, PSEUDO);
    188  ok(!hasLock, "pseudo-class lock has been removed");
    189  hasLock = await hasPseudoClassLock("#parent-div", PSEUDO);
    190  ok(!hasLock, "pseudo-class lock has been removed");
    191  hasLock = await hasPseudoClassLock("body", PSEUDO);
    192  ok(!hasLock, "pseudo-class lock has been removed");
    193 }
    194 
    195 async function assertPseudoRemovedFromView(
    196  inspector,
    197  highlighterTestFront,
    198  ruleview,
    199  selector
    200 ) {
    201  info("Check that the ruleview no longer contains the pseudo-class rule");
    202  const rules = ruleview.element.querySelectorAll(".ruleview-rule");
    203  is(rules.length, 2, "rule view is showing 2 rules after removing lock");
    204 
    205  const nodeFront = await getNodeFront(selector, inspector);
    206  await inspector.highlighters.showHighlighterTypeForNode(
    207    inspector.highlighters.TYPES.BOXMODEL,
    208    nodeFront
    209  );
    210 
    211  const value = await highlighterTestFront.getHighlighterNodeTextContent(
    212    "box-model-infobar-pseudo-classes"
    213  );
    214  is(value, "", "pseudo-class removed from infobar selector");
    215  await inspector.highlighters.hideHighlighterType(
    216    inspector.highlighters.TYPES.BOXMODEL
    217  );
    218 }
    219 
    220 /**
    221 * Check that an element currently has a pseudo-class lock.
    222 *
    223 * @param {string} selector The node selector to get the pseudo-class from
    224 * @param {string} pseudo The pseudoclass to check for
    225 * @return {Promise<boolean>}
    226 */
    227 function hasPseudoClassLock(selector, pseudoClass) {
    228  return SpecialPowers.spawn(
    229    gBrowser.selectedBrowser,
    230    [selector, pseudoClass],
    231    (_selector, _pseudoClass) => {
    232      const element = content.document.querySelector(_selector);
    233      return InspectorUtils.hasPseudoClassLock(element, _pseudoClass);
    234    }
    235  );
    236 }