tor-browser

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

browser_rules_light_dark.js (4550B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 // Test for light-dark() in rule view.
      7 
      8 const TEST_URI = `data:text/html,<meta charset=utf8>
      9  <style>
     10    @media not (prefers-color-scheme: dark) {
     11      html {
     12        color-scheme: light;
     13      }
     14    }
     15 
     16    @media (prefers-color-scheme: dark) {
     17      html {
     18        color-scheme: dark;
     19      }
     20    }
     21 
     22    h1 {
     23      background-color: light-dark(gold, tomato);
     24    }
     25 
     26    .light {
     27      color-scheme: light;
     28      color: light-dark(red, blue);
     29      border-color: light-dark(pink, cyan);
     30    }
     31 
     32    .dark {
     33      color-scheme: dark;
     34      background: linear-gradient(
     35        light-dark(blue, darkblue),
     36        light-dark(red, darkred)
     37      );
     38    }
     39  </style>
     40  <h1>Hello</h1>
     41  <div class="light">
     42    <pre>color-scheme: light</pre>
     43    <div class="dark">
     44      <pre>color-scheme: dark</pre>
     45    </div>
     46  </div>`;
     47 
     48 add_task(async function () {
     49  await addTab(TEST_URI);
     50  const { inspector, view } = await openRuleView();
     51 
     52  info("Select node with color-scheme: light");
     53  await selectNode(".light", inspector);
     54 
     55  // `color: light-dark(red, blue)`
     56  assertColorSpans(view, ".light", "color", [
     57    { color: "red", matched: true },
     58    { color: "blue", matched: false },
     59  ]);
     60 
     61  // `border-color: light-dark(pink, cyan)`
     62  assertColorSpans(view, ".light", "border-color", [
     63    { color: "pink", matched: true },
     64    { color: "cyan", matched: false },
     65  ]);
     66 
     67  info("Select node with color-scheme: dark");
     68  await selectNode(".dark", inspector);
     69 
     70  // `background: linear-gradient(light-dark(blue, darkblue),light-dark(red, darkred))`
     71  assertColorSpans(view, ".dark", "background", [
     72    { color: "blue", matched: false },
     73    { color: "darkblue", matched: true },
     74    { color: "red", matched: false },
     75    { color: "darkred", matched: true },
     76  ]);
     77 
     78  // We show the inherited rule for color, which is matched by `.light`, so here, even if
     79  // the node has a dark color scheme, light-dark should mark second parameters as unmatched
     80  // `color: light-dark(red, blue)`
     81  assertColorSpans(view, ".light", "color", [
     82    { color: "red", matched: true },
     83    { color: "blue", matched: false },
     84  ]);
     85 
     86  info("Select node without explicit color-scheme property");
     87  // h1 has no color-scheme so it inherits from the html one, which depends on the actual
     88  // media query value. light-dark in the associated rule should be updated when toggling
     89  // simulation.
     90  await selectNode("h1", inspector);
     91 
     92  // Read the color scheme to know if we should click on the light or dark button
     93  // to trigger a change.
     94  info("Enable light mode simulation if needed");
     95  const isDarkScheme = await SpecialPowers.spawn(
     96    gBrowser.selectedBrowser,
     97    [],
     98    () => {
     99      return content.matchMedia("(prefers-color-scheme: dark)").matches;
    100    }
    101  );
    102  if (isDarkScheme) {
    103    const onRuleViewRefreshed = view.once("ruleview-refreshed");
    104    inspector.panelDoc
    105      .querySelector("#color-scheme-simulation-light-toggle")
    106      .click();
    107    await onRuleViewRefreshed;
    108  }
    109 
    110  // `background-color: light-dark(gold, tomato)`
    111  assertColorSpans(view, "h1", "background-color", [
    112    { color: "gold", matched: true },
    113    { color: "tomato", matched: false },
    114  ]);
    115 
    116  info("Trigger dark mode simulation");
    117  const onRuleViewRefreshed = view.once("ruleview-refreshed");
    118  inspector.panelDoc
    119    .querySelector("#color-scheme-simulation-dark-toggle")
    120    .click();
    121  await onRuleViewRefreshed;
    122 
    123  // `background-color: light-dark(gold, tomato)`
    124  assertColorSpans(view, "h1", "background-color", [
    125    { color: "gold", matched: false },
    126    { color: "tomato", matched: true },
    127  ]);
    128 });
    129 
    130 function assertColorSpans(view, ruleSelector, propertyName, expectedColors) {
    131  const colorSpans = getRuleViewProperty(
    132    view,
    133    ruleSelector,
    134    propertyName
    135  ).valueSpan.querySelectorAll("span:has(> .ruleview-color)");
    136  is(
    137    colorSpans.length,
    138    expectedColors.length,
    139    "Got expected number of color spans"
    140  );
    141  for (let i = 0; i < expectedColors.length; i++) {
    142    const colorSpan = colorSpans[i];
    143    const expectedColorData = expectedColors[i];
    144    is(
    145      colorSpan.textContent,
    146      expectedColorData.color,
    147      `Expected color ${i} for ${ruleSelector} ${propertyName}`
    148    );
    149    is(
    150      !colorSpan.classList.contains("inspector-unmatched"),
    151      expectedColorData.matched,
    152      `Color ${i} for ${ruleSelector} ${propertyName} is ${
    153        expectedColorData.matched ? "matched" : "unmatched"
    154      }`
    155    );
    156  }
    157 }