User:DoktorGrym/common.js

Note: After saving, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Go to Menu → Settings (Opera → Preferences on a Mac) and then to Privacy & security → Clear browsing data → Cached images and files.

/*! Dark mode switcheroo | MIT License | jrvs.io/darkmode */

(function () {
  // improve variable mangling when minifying
  var win = window;
  var doc = win.document;
  var body = doc.body;
  var classes = body.classList;
  var storage = localStorage;

  // check for preset `dark_mode_pref` preference in local storage
  var pref_key = 'dark_mode_pref';
  var pref = storage.getItem(pref_key);

  // change CSS via these <body> classes:
  var dark = 'dark';
  var light = 'light';

  // which class is <body> set to initially?
  var default_theme = dark;

  // use an element with class `dark-mode-toggle` to trigger swap when clicked
  var toggle = doc.querySelector('.dark-mode-toggle');

  // keep track of current state no matter how we got there
  var active = (default_theme === dark);

  // receives a class name and switches <body> to it
  var activateTheme = function (theme) {
    classes.remove(dark, light);
    classes.add(theme);
    active = (theme === dark);
  };

  // if user already explicitly toggled in the past, restore their preference
  if (pref === dark) activateTheme(dark);
  if (pref === light) activateTheme(light);

  // user has never clicked the button, so go by their OS preference until/if they do so
  if (!pref) {
    // returns media query selector syntax
    var prefers = function (theme) {
      return '(prefers-color-scheme: ' + theme + ')';
    };

    // check for OS dark/light mode preference and switch accordingly
    // default to `default_theme` set above if unsupported
    if (win.matchMedia(prefers(dark)).matches)
      activateTheme(dark);
    else if (win.matchMedia(prefers(light)).matches)
      activateTheme(dark);
    else
      activateTheme(dark);

    // real-time switching if supported by OS/browser
    win.matchMedia(prefers(dark)).addListener(function (e) { if (e.matches) activateTheme(dark); });
    win.matchMedia(prefers(light)).addListener(function (e) { if (e.matches) activateTheme(dark); });
  }

  // don't freak out if page happens not to have a toggle
  if (toggle) {
    // toggle re-appears now that we know user has JS enabled
    toggle.style.visibility = 'visible';

    // handle toggle click
    toggle.addEventListener('click', function () {
      // switch to the opposite theme & save preference in local storage
      if (active) {
        activateTheme(light);
        storage.setItem(pref_key, light);
      } else {
        activateTheme(dark);
        storage.setItem(pref_key, dark);
      }
    }, true);
  }
})();