jtagcat / GitHub: Black favicon

// ==UserScript==
// @name         GitHub: Black favicon
// @description  Change GitHub's White favicon to black. Forked from the opposite version of this: https://gist.github.com/tobbez/017bc8b455095f8e4b4f973b09d33ce2
// @version      1.3
// @author       tobbez
// @collaborator jtagcat
// @icon         https://github.githubassets.com/favicons/favicon.svg
// @match        https://github.community/*
// @match        https://*.github.com/*
// @match        https://github.com/*
// @grant        none
// @downloadURL  https://openuserjs.org/install/jtagcat/GitHub_Black_favicon.user.js
// @updateURL    https://openuserjs.org/meta/jtagcat/GitHub_Black_favicon.meta.js
// @licence      MIT
// ==/UserScript==

/*
 * Replaces the icon for github sites with a white one.
 *
 * This is for browsers with the dark theme enabled.
 *
 * To install this script, first get the Violentmonkey or
 * Tampermonkey addon, then click the 'Raw' link.
 */

function get_url_filename(url) {
  let u = new URL(url);
  let p = u.pathname.split('/');
  return p[p.length - 1];
}

(function() {
  'use strict';

  let icon_data = "PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9u" +
                  "ZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJl" +
                  "dmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xNiAwQzcuMTYgMCAwIDcuMTYgMCAxNkMw" +
                  "IDIzLjA4IDQuNTggMjkuMDYgMTAuOTQgMzEuMThDMTEuNzQgMzEuMzIgMTIuMDQgMzAuODQgMTIu" +
                  "MDQgMzAuNDJDMTIuMDQgMzAuMDQgMTIuMDIgMjguNzggMTIuMDIgMjcuNDRDOCAyOC4xOCA2Ljk2" +
                  "IDI2LjQ2IDYuNjQgMjUuNTZDNi40NiAyNS4xIDUuNjggMjMuNjggNSAyMy4zQzQuNDQgMjMgMy42" +
                  "NCAyMi4yNiA0Ljk4IDIyLjI0QzYuMjQgMjIuMjIgNy4xNCAyMy40IDcuNDQgMjMuODhDOC44OCAy" +
                  "Ni4zIDExLjE4IDI1LjYyIDEyLjEgMjUuMkMxMi4yNCAyNC4xNiAxMi42NiAyMy40NiAxMy4xMiAy" +
                  "My4wNkM5LjU2IDIyLjY2IDUuODQgMjEuMjggNS44NCAxNS4xNkM1Ljg0IDEzLjQyIDYuNDYgMTEu" +
                  "OTggNy40OCAxMC44NkM3LjMyIDEwLjQ2IDYuNzYgOC44MiA3LjY0IDYuNjJDNy42NCA2LjYyIDgu" +
                  "OTggNi4yIDEyLjA0IDguMjZDMTMuMzIgNy45IDE0LjY4IDcuNzIgMTYuMDQgNy43MkMxNy40IDcu" +
                  "NzIgMTguNzYgNy45IDIwLjA0IDguMjZDMjMuMSA2LjE4IDI0LjQ0IDYuNjIgMjQuNDQgNi42MkMy" +
                  "NS4zMiA4LjgyIDI0Ljc2IDEwLjQ2IDI0LjYgMTAuODZDMjUuNjIgMTEuOTggMjYuMjQgMTMuNCAy" +
                  "Ni4yNCAxNS4xNkMyNi4yNCAyMS4zIDIyLjUgMjIuNjYgMTguOTQgMjMuMDZDMTkuNTIgMjMuNTYg" +
                  "MjAuMDIgMjQuNTIgMjAuMDIgMjYuMDJDMjAuMDIgMjguMTYgMjAgMjkuODggMjAgMzAuNDJDMjAg" +
                  "MzAuODQgMjAuMyAzMS4zNCAyMS4xIDMxLjE4QzI3LjQyIDI5LjA2IDMyIDIzLjA2IDMyIDE2QzMy" +
                  "IDcuMTYgMjQuODQgMCAxNiAwVjBaIiBmaWxsPSIjMDAwMDAwIi8+Cjwvc3ZnPgo=";


  let icon_data_success = "PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9u" +
                          "ZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTAgMTZDMCA3" +
                          "LjE2IDcuMTYgMCAxNiAwQzIzLjAzNyAwIDI5LjAwOTQgNC41MzcxMiAzMS4xNTI5IDEwLjg0NzFM" +
                          "MjYuMjI3MSAxNS43NzNDMjYuMjM1NiAxNS41NzQxIDI2LjI0IDE1LjM2OTggMjYuMjQgMTUuMTZD" +
                          "MjYuMjQgMTMuNCAyNS42MiAxMS45OCAyNC42IDEwLjg2QzI0Ljc2IDEwLjQ2IDI1LjMyIDguODIg" +
                          "MjQuNDQgNi42MkMyNC40NCA2LjYyIDIzLjEgNi4xOCAyMC4wNCA4LjI2QzE4Ljc2IDcuOSAxNy40" +
                          "IDcuNzIgMTYuMDQgNy43MkMxNC42OCA3LjcyIDEzLjMyIDcuOSAxMi4wNCA4LjI2QzguOTggNi4y" +
                          "IDcuNjQgNi42MiA3LjY0IDYuNjJDNi43NiA4LjgyIDcuMzIgMTAuNDYgNy40OCAxMC44NkM2LjQ2" +
                          "IDExLjk4IDUuODQgMTMuNDIgNS44NCAxNS4xNkM1Ljg0IDIwLjYzODcgOC44MjExOSAyMi4zMTg3" +
                          "IDEyIDIyLjg5NzZWMjUuMjQ0MkMxMS4wMjI0IDI1LjY2MzIgOC44MzAzNSAyNi4yMTY2IDcuNDQg" +
                          "MjMuODhDNy4xNCAyMy40IDYuMjQgMjIuMjIgNC45OCAyMi4yNEMzLjY0IDIyLjI2IDQuNDQgMjMg" +
                          "NSAyMy4zQzUuNjggMjMuNjggNi40NiAyNS4xIDYuNjQgMjUuNTZDNi45NTk0NyAyNi40NTg1IDcu" +
                          "OTk2NTUgMjguMTc0MyAxMiAyNy40NDM3VjMwLjY4MTRDMTEuODk1MSAzMS4wMTE2IDExLjU3NTEg" +
                          "MzEuMjkxMSAxMC45NCAzMS4xOEM0LjU4IDI5LjA2IDAgMjMuMDggMCAxNloiIGZpbGw9IiMwMDAw" +
                          "MDAiLz4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0z" +
                          "MC43MDcxIDIxLjIwNzFMMjAuNSAzMS40MTQyTDE1LjI5MjkgMjYuMjA3MUwxNi43MDcxIDI0Ljc5" +
                          "MjlMMjAuNSAyOC41ODU4TDI5LjI5MjkgMTkuNzkyOUwzMC43MDcxIDIxLjIwNzFaIiBmaWxsPSIj" +
                          "MDA3OTFDIi8+Cjwvc3ZnPgo=";


  let icon_data_failure = "PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9u" +
                          "ZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTAgMTZDMCA3" +
                          "LjE2IDcuMTYgMCAxNiAwQzI0LjE2MjYgMCAzMC44OTI5IDYuMTA0NzkgMzEuODc2NCAxNEgyNi4x" +
                          "NDQ0QzI1LjkzMzkgMTIuNzYzMiAyNS4zODU2IDExLjcyMjYgMjQuNiAxMC44NkMyNC43NiAxMC40" +
                          "NiAyNS4zMiA4LjgyIDI0LjQ0IDYuNjJDMjQuNDQgNi42MiAyMy4xIDYuMTggMjAuMDQgOC4yNkMx" +
                          "OC43NiA3LjkgMTcuNCA3LjcyIDE2LjA0IDcuNzJDMTQuNjggNy43MiAxMy4zMiA3LjkgMTIuMDQg" +
                          "OC4yNkM4Ljk4IDYuMiA3LjY0IDYuNjIgNy42NCA2LjYyQzYuNzYgOC44MiA3LjMyIDEwLjQ2IDcu" +
                          "NDggMTAuODZDNi40NiAxMS45OCA1Ljg0IDEzLjQyIDUuODQgMTUuMTZDNS44NCAyMC42Mzg3IDgu" +
                          "ODIxMTkgMjIuMzE4NyAxMiAyMi44OTc2VjI1LjI0NDJDMTEuMDIyNCAyNS42NjMyIDguODMwMzUg" +
                          "MjYuMjE2NiA3LjQ0IDIzLjg4QzcuMTQgMjMuNCA2LjI0IDIyLjIyIDQuOTggMjIuMjRDMy42NCAy" +
                          "Mi4yNiA0LjQ0IDIzIDUgMjMuM0M1LjY4IDIzLjY4IDYuNDYgMjUuMSA2LjY0IDI1LjU2QzYuOTU5" +
                          "NDcgMjYuNDU4NSA3Ljk5NjU1IDI4LjE3NDMgMTIgMjcuNDQzN1YzMC42ODE0QzExLjg5NTEgMzEu" +
                          "MDExNiAxMS41NzUxIDMxLjI5MTEgMTAuOTQgMzEuMThDNC41OCAyOS4wNiAwIDIzLjA4IDAgMTZa" +
                          "IiBmaWxsPSIjMDAwMDAwIi8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJl" +
                          "dmVub2RkIiBkPSJNMjMuMDg1OCAyNC41TDE4LjI5MjkgMjkuMjkyOUwxOS43MDcxIDMwLjcwNzFM" +
                          "MjQuNSAyNS45MTQyTDI5LjI5MjkgMzAuNzA3MUwzMC43MDcxIDI5LjI5MjlMMjUuOTE0MiAyNC41" +
                          "TDMwLjcwNzEgMTkuNzA3MUwyOS4yOTI5IDE4LjI5MjlMMjQuNSAyMy4wODU4TDE5LjcwNzEgMTgu" +
                          "MjkyOUwxOC4yOTI5IDE5LjcwNzFMMjMuMDg1OCAyNC41WiIgZmlsbD0iI0FCMDAwRCIvPgo8L3N2" +
                          "Zz4K";


  let icon_map = new Map([
    ['favicon.svg', `data:image/svg+xml;base64,${icon_data}`],
    ['favicon-success.svg', `data:image/svg+xml;base64,${icon_data_success}`],
    ['favicon-failure.svg', `data:image/svg+xml;base64,${icon_data_failure}`],
    ['favicon.ico', `data:image/svg+xml;base64,${icon_data}`], // github.community
  ]);

  function update_favicon () {
    let icon_link = document.querySelector('link[rel="icon"]');

    if (icon_link) {
      let fname = icon_map.get(get_url_filename(icon_link.href));
      if (fname !== undefined) {
        icon_link.setAttribute('href', fname);
      }
    }
  }

  let icon_link = document.querySelector('link[rel="icon"]');
  let mutobs = new MutationObserver(update_favicon);
  mutobs.observe(icon_link, {
    attributes: true,
  });

  update_favicon();
})();