tor-browser

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

browser_theme_switching.js (3714B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 const THEME_PREF = "devtools.theme";
      7 
      8 add_task(async function () {
      9  await pushPref(THEME_PREF, "light");
     10  await pushPref("devtools.high-contrast-mode-support", true);
     11  // force HCM
     12  await pushPref("browser.display.document_color_use", 2);
     13  await pushPref("ui.useAccessibilityTheme", 1);
     14 
     15  // For some reason, mochitest spawn a very special default tab,
     16  // whose WindowGlobal is still the initial about:blank document.
     17  // This seems to be specific to mochitest, this doesn't reproduce
     18  // in regular firefox run. Even having about:blank as home page,
     19  // force loading another final about:blank document (which isn't the initial one)
     20  //
     21  // To workaround this, force opening a dedicated test tab
     22  const tab = await addTab("data:text/html;charset=utf-8,Test page");
     23 
     24  const toolbox = await gDevTools.showToolboxForTab(tab);
     25  const doc = toolbox.doc;
     26  const root = doc.documentElement;
     27 
     28  const platform = root.getAttribute("platform");
     29  const expectedPlatform = getPlatform();
     30  is(platform, expectedPlatform, ":root[platform] is correct");
     31  checkTheme(root, {
     32    theme: "light",
     33    className: "theme-light",
     34    forcedColorsActive: false,
     35  });
     36 
     37  await switchTheme(root, "dark");
     38  checkTheme(root, {
     39    theme: "dark",
     40    className: "theme-dark",
     41    forcedColorsActive: false,
     42  });
     43 
     44  // When setting theme to "auto", we rely on Services.appinfo.chromeColorSchemeIsDark.
     45  const isDark = Services.appinfo.chromeColorSchemeIsDark;
     46  await switchTheme(root, "auto", isDark ? "dark" : "light");
     47  checkTheme(root, {
     48    theme: isDark ? "dark" : "light",
     49    className: isDark ? "theme-dark" : "theme-light",
     50    forcedColorsActive: true,
     51  });
     52 
     53  info(
     54    "Check that disabling HCM will remove the forced-colors-active attribute"
     55  );
     56  await pushPref("browser.display.document_color_use", 0);
     57  await pushPref("ui.useAccessibilityTheme", 0);
     58  checkTheme(root, {
     59    theme: isDark ? "dark" : "light",
     60    className: isDark ? "theme-dark" : "theme-light",
     61    forcedColorsActive: false,
     62  });
     63 
     64  await toolbox.destroy();
     65 });
     66 
     67 function switchTheme(root, themePrefValue, appliedTheme = themePrefValue) {
     68  const ac = new AbortController();
     69  const onThemeSwitched = new Promise(res =>
     70    gDevTools.on(
     71      "theme-switched",
     72      (win, newTheme) => {
     73        if (win === root.ownerGlobal && newTheme === appliedTheme) {
     74          res();
     75          ac.abort();
     76        }
     77      },
     78      { signal: ac.signal }
     79    )
     80  );
     81  pushPref(THEME_PREF, themePrefValue);
     82  return onThemeSwitched;
     83 }
     84 
     85 function checkTheme(root, { theme, className, forcedColorsActive }) {
     86  const themePrefValue = Services.prefs.getCharPref(THEME_PREF);
     87  ok(
     88    root.classList.contains(className),
     89    `:root has ${className} class for ${themePrefValue} theme (${root.className})`
     90  );
     91 
     92  is(
     93    root.hasAttribute("forced-colors-active"),
     94    forcedColorsActive,
     95    `high contrast mode is ${
     96      !forcedColorsActive ? "not " : ""
     97    }supported in ${themePrefValue} theme`
     98  );
     99 
    100  const sheetsInDOM = Array.from(
    101    root.ownerDocument.querySelectorAll("link[rel='stylesheet']"),
    102    l => l.href
    103  );
    104 
    105  const sheetsFromTheme = gDevTools.getThemeDefinition(theme).stylesheets;
    106  info("Checking for existence of " + sheetsInDOM.length + " sheets");
    107  for (const themeSheet of sheetsFromTheme) {
    108    ok(
    109      sheetsInDOM.some(s => s.includes(themeSheet)),
    110      "There is a stylesheet for " + themeSheet
    111    );
    112  }
    113 }
    114 
    115 function getPlatform() {
    116  const { OS } = Services.appinfo;
    117  if (OS == "WINNT") {
    118    return "win";
    119  } else if (OS == "Darwin") {
    120    return "mac";
    121  }
    122  return "linux";
    123 }