Skip to content

Instantly share code, notes, and snippets.

@tobbez
Last active September 16, 2023 19:11
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tobbez/017bc8b455095f8e4b4f973b09d33ce2 to your computer and use it in GitHub Desktop.
Save tobbez/017bc8b455095f8e4b4f973b09d33ce2 to your computer and use it in GitHub Desktop.
[UserScript] GitHub: White favicon
// ==UserScript==
// @name GitHub: White favicon
// @version 1.10.0
// @author tobbez
// @match https://support.github.com/*
// @match https://github.blog/*
// @match https://opensource.guide/*
// @match https://www.githubstatus.com/*
// @match https://services.github.com/*
// @match https://desktop.github.com/*
// @match https://partner.github.com/*
// @match https://resources.github.com/*
// @match https://cli.github.com/*
// @match https://thegithubshop.com/*
// @grant none
// @downloadURL https://gist.github.com/tobbez/017bc8b455095f8e4b4f973b09d33ce2/raw/github_white_favicon.user.js
// @updateURL https://gist.github.com/tobbez/017bc8b455095f8e4b4f973b09d33ce2/raw/github_white_favicon.user.js
// @icon https://github.githubassets.com/favicons/favicon-dark.png
// ==/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 = `\
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M16 0C7.16 0 0 7.16 0 16C0 23.08 4.58 29.06 10.94 31.18C11.74 31.32 12.04 30.84 12.04 30.42C12.04 30.04 12.02 28.78 12.02 27.44C8 28.18 6.96 26.46 6.64 25.56C6.46 25.1 5.68 23.68 5 23.3C4.44 23 3.64 22.26 4.98 22.24C6.24 22.22 7.14 23.4 7.44 23.88C8.88 26.3 11.18 25.62 12.1 25.2C12.24 24.16 12.66 23.46 13.12 23.06C9.56 22.66 5.84 21.28 5.84 15.16C5.84 13.42 6.46 11.98 7.48 10.86C7.32 10.46 6.76 8.82 7.64 6.62C7.64 6.62 8.98 6.2 12.04 8.26C13.32 7.9 14.68 7.72 16.04 7.72C17.4 7.72 18.76 7.9 20.04 8.26C23.1 6.18 24.44 6.62 24.44 6.62C25.32 8.82 24.76 10.46 24.6 10.86C25.62 11.98 26.24 13.4 26.24 15.16C26.24 21.3 22.5 22.66 18.94 23.06C19.52 23.56 20.02 24.52 20.02 26.02C20.02 28.16 20 29.88 20 30.42C20 30.84 20.3 31.34 21.1 31.18C27.42 29.06 32 23.06 32 16C32 7.16 24.84 0 16 0V0Z" fill="#FFFFFF"/>
</svg>`;
let icon_data_pending = `\
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 16C0 7.16 7.16 0 16 0C24.84 0 32 7.16 32 16C32 16.3358 31.9896 16.6693 31.9692 17H26.1121C26.1957 16.44 26.24 15.8283 26.24 15.16C26.24 13.4 25.62 11.98 24.6 10.86C24.76 10.46 25.32 8.82 24.44 6.62C24.44 6.62 23.1 6.18 20.04 8.26C18.76 7.9 17.4 7.72 16.04 7.72C14.68 7.72 13.32 7.9 12.04 8.26C8.98 6.2 7.64 6.62 7.64 6.62C6.76 8.82 7.32 10.46 7.48 10.86C6.46 11.98 5.84 13.42 5.84 15.16C5.84 20.6387 8.82119 22.3187 12 22.8976V25.2442C11.0224 25.6632 8.83035 26.2166 7.44 23.88C7.14 23.4 6.24 22.22 4.98 22.24C3.64 22.26 4.44 23 5 23.3C5.68 23.68 6.46 25.1 6.64 25.56C6.95947 26.4585 7.99655 28.1743 12 27.4437V30.6814C11.8951 31.0116 11.5751 31.2911 10.94 31.18C4.58 29.06 0 23.08 0 16Z" fill="#FFFFFF"/>
<circle cx="26" cy="26" r="5" fill="#B78F05"/>
</svg>`;
let icon_data_success = `\
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 16C0 7.16 7.16 0 16 0C23.037 0 29.0094 4.53712 31.1529 10.8471L26.2271 15.773C26.2356 15.5741 26.24 15.3698 26.24 15.16C26.24 13.4 25.62 11.98 24.6 10.86C24.76 10.46 25.32 8.82 24.44 6.62C24.44 6.62 23.1 6.18 20.04 8.26C18.76 7.9 17.4 7.72 16.04 7.72C14.68 7.72 13.32 7.9 12.04 8.26C8.98 6.2 7.64 6.62 7.64 6.62C6.76 8.82 7.32 10.46 7.48 10.86C6.46 11.98 5.84 13.42 5.84 15.16C5.84 20.6387 8.82119 22.3187 12 22.8976V25.2442C11.0224 25.6632 8.83035 26.2166 7.44 23.88C7.14 23.4 6.24 22.22 4.98 22.24C3.64 22.26 4.44 23 5 23.3C5.68 23.68 6.46 25.1 6.64 25.56C6.95947 26.4585 7.99655 28.1743 12 27.4437V30.6814C11.8951 31.0116 11.5751 31.2911 10.94 31.18C4.58 29.06 0 23.08 0 16Z" fill="#FFFFFF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M30.7071 21.2071L20.5 31.4142L15.2929 26.2071L16.7071 24.7929L20.5 28.5858L29.2929 19.7929L30.7071 21.2071Z" fill="#00791C"/>
</svg>`;
let icon_data_failure = `\
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 16C0 7.16 7.16 0 16 0C24.1626 0 30.8929 6.10479 31.8764 14H26.1444C25.9339 12.7632 25.3856 11.7226 24.6 10.86C24.76 10.46 25.32 8.82 24.44 6.62C24.44 6.62 23.1 6.18 20.04 8.26C18.76 7.9 17.4 7.72 16.04 7.72C14.68 7.72 13.32 7.9 12.04 8.26C8.98 6.2 7.64 6.62 7.64 6.62C6.76 8.82 7.32 10.46 7.48 10.86C6.46 11.98 5.84 13.42 5.84 15.16C5.84 20.6387 8.82119 22.3187 12 22.8976V25.2442C11.0224 25.6632 8.83035 26.2166 7.44 23.88C7.14 23.4 6.24 22.22 4.98 22.24C3.64 22.26 4.44 23 5 23.3C5.68 23.68 6.46 25.1 6.64 25.56C6.95947 26.4585 7.99655 28.1743 12 27.4437V30.6814C11.8951 31.0116 11.5751 31.2911 10.94 31.18C4.58 29.06 0 23.08 0 16Z" fill="#FFFFFF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M23.0858 24.5L18.2929 29.2929L19.7071 30.7071L24.5 25.9142L29.2929 30.7071L30.7071 29.2929L25.9142 24.5L30.7071 19.7071L29.2929 18.2929L24.5 23.0858L19.7071 18.2929L18.2929 19.7071L23.0858 24.5Z" fill="#AB000D"/>
</svg>`;
let icon_map = new Map([
['favicon.svg', `data:image/svg+xml;base64,${btoa(icon_data)}`],
['favicon-pending.svg', `data:image/svg+xml;base64,${btoa(icon_data_pending)}`],
['favicon-success.svg', `data:image/svg+xml;base64,${btoa(icon_data_success)}`],
['favicon-failure.svg', `data:image/svg+xml;base64,${btoa(icon_data_failure)}`],
['25b1992f021c82f730efb5822ae795665d2e20d7_2_32x32.png', `data:image/svg+xml;base64,${btoa(icon_data)}`], // github.community
['favicon.ico', `data:image/svg+xml;base64,${btoa(icon_data)}`], // opensource.guide
['favicon-3dcd2c977a91b2e3f396b300c5ff0d572295ca632ddb7ba1adcacc1ea68dd5c0.ico', `data:image/svg+xml;base64,${btoa(icon_data)}`], // support.github.com
['cropped-github-favicon-512.png', `data:image/svg+xml;base64,${btoa(icon_data)}`], // github.blog
['favicon-success.png', `data:image/svg+xml;base64,${btoa(icon_data_success)}`], // githubstatus.com
['favicon-pending.png', `data:image/svg+xml;base64,${btoa(icon_data_pending)}`], // githubstatus.com (?)
['favicon-failure.png', `data:image/svg+xml;base64,${btoa(icon_data_failure)}`], // githubstatus.com (?)
['GitHub-Mark-120px-plus_32x32.png', `data:image/svg+xml;base64,${btoa(icon_data)}`], // thegithubshop.com
]);
function update_favicon () {
let icon_links = document.querySelectorAll('link[rel~="icon"]:not([rel~="alternate"])');
for (let icon_link of icon_links) {
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"]:not([rel~="alternate"])');
if (icon_link === null) { // no favicon element on https://services.github.com/
let icon = document.createElement('link');
icon.setAttribute('rel', 'icon');
icon.setAttribute('href', `data:image/svg+xml;base64,${btoa(icon_data)}`);
document.head.appendChild(icon);
}
let mutobs = new MutationObserver(update_favicon);
mutobs.observe(icon_link, {
attributes: true,
});
update_favicon();
})();
@simistern
Copy link

particularly if I have the tab selected:

Screen Shot 2020-04-05 at 2 57 51 PM

@jtagcat
Copy link

jtagcat commented Apr 6, 2020

@simistern the github favicon is already black. This userscript makes it white.

Have you tried not using this userscript and just using the default github favicon instead?

I'm not trying to answer your question (of base64 encoding the black logo), if your problem is caused by something else in the first place.

@simistern
Copy link

I think there is some miscommunication here :)

On my browser, the favicon is default as white.

I would like to change this to black.

I found your script in my quest to do so, and was asking why I couldn't replace the base64 string with something else to get any other image as a favicon.

@jtagcat
Copy link

jtagcat commented Apr 7, 2020

I think there is some miscommunication here :)

On my browser, the favicon is default as white.

I would like to change this to black.

I found your script in my quest to do so, and was asking why I couldn't replace the base64 string with something else to get any other image as a favicon.

Ok, but why is it white? Do you have something what makes favicons white? Any special dark mode? What browser are you using? If FF, could I get the about:config part of your about:support page? (I'm interested why it's white myself as well now..)

Also, I don't have an environment to test in (my default is black). I'll try to make it purple and then see.

Well, In general i am curious why I can't make it work with any other base64 encoded image :)

How did you try to make it work? Did you throw a random black github logos in there? From my perspective the fastest would be to reverse-engineer.

Give me a moment.

@jtagcat
Copy link

jtagcat commented Apr 7, 2020

Reverse-engineered (decoded) svg:
Started by find and replacing " \+\n\s*" to nothing. Additionally, removed the double quotes at the beginning and end. Moved the base64 data to a diff file.

% base64 -d ./decode-me > decoded.svg
% base64 ./decoded-changed.svg > encoded-changed.svg
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M16 0C7.16 0 0 7.16 0 16C0 23.08 4.58 29.06 10.94 31.18C11.74 31.32 12.04 30.84 12.04 30.42C12.04 30.04 12.02 28.78 12.02 27.44C8 28.18 6.96 26.46 6.64 25.56C6.46 25.1 5.68 23.68 5 23.3C4.44 23 3.64 22.26 4.98 22.24C6.24 22.22 7.14 23.4 7.44 23.88C8.88 26.3 11.18 25.62 12.1 25.2C12.24 24.16 12.66 23.46 13.12 23.06C9.56 22.66 5.84 21.28 5.84 15.16C5.84 13.42 6.46 11.98 7.48 10.86C7.32 10.46 6.76 8.82 7.64 6.62C7.64 6.62 8.98 6.2 12.04 8.26C13.32 7.9 14.68 7.72 16.04 7.72C17.4 7.72 18.76 7.9 20.04 8.26C23.1 6.18 24.44 6.62 24.44 6.62C25.32 8.82 24.76 10.46 24.6 10.86C25.62 11.98 26.24 13.4 26.24 15.16C26.24 21.3 22.5 22.66 18.94 23.06C19.52 23.56 20.02 24.52 20.02 26.02C20.02 28.16 20 29.88 20 30.42C20 30.84 20.3 31.34 21.1 31.18C27.42 29.06 32 23.06 32 16C32 7.16 24.84 0 16 0V0Z" fill="#FFFFFF"/>
</svg>

I say let's find and replace (to also make it work with the chekmark and x logos) #FFFFFF with #B300BB

Now we do all the steps in reverse. And there we have it, the purple icon in code:

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

Let's load it up and see!
image

Proof of concept works, now let's do all 3 icons in black, essentially blindly.

@jtagcat
Copy link

jtagcat commented Apr 7, 2020

I would encourage you to try doing it yourself (to find what you missed and learn).

..but I'm on a spree. https://openuserjs.org/scripts/jtagcat/GitHub_Black_favicon

Have a nice morning.

@dreamca4er
Copy link

Checks pending icon

  let icon_data_pending = "PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9uZ" +
                          "SIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTAgMTZDMCA3Lj" +
                          "E2IDcuMTYgMCAxNiAwQzI0Ljg0IDAgMzIgNy4xNiAzMiAxNkMzMiAxNi4zMzU4IDMxLjk4OTYgMTY" +
                          "uNjY5MyAzMS45NjkyIDE3SDI2LjExMjFDMjYuMTk1NyAxNi40NCAyNi4yNCAxNS44MjgzIDI2LjI0" +
                          "IDE1LjE2QzI2LjI0IDEzLjQgMjUuNjIgMTEuOTggMjQuNiAxMC44NkMyNC43NiAxMC40NiAyNS4zM" +
                          "iA4LjgyIDI0LjQ0IDYuNjJDMjQuNDQgNi42MiAyMy4xIDYuMTggMjAuMDQgOC4yNkMxOC43NiA3Lj" +
                          "kgMTcuNCA3LjcyIDE2LjA0IDcuNzJDMTQuNjggNy43MiAxMy4zMiA3LjkgMTIuMDQgOC4yNkM4Ljk" +
                          "4IDYuMiA3LjY0IDYuNjIgNy42NCA2LjYyQzYuNzYgOC44MiA3LjMyIDEwLjQ2IDcuNDggMTAuODZD" +
                          "Ni40NiAxMS45OCA1Ljg0IDEzLjQyIDUuODQgMTUuMTZDNS44NCAyMC42Mzg3IDguODIxMTkgMjIuM" +
                          "zE4NyAxMiAyMi44OTc2VjI1LjI0NDJDMTEuMDIyNCAyNS42NjMyIDguODMwMzUgMjYuMjE2NiA3Lj" +
                          "Q0IDIzLjg4QzcuMTQgMjMuNCA2LjI0IDIyLjIyIDQuOTggMjIuMjRDMy42NCAyMi4yNiA0LjQ0IDI" +
                          "zIDUgMjMuM0M1LjY4IDIzLjY4IDYuNDYgMjUuMSA2LjY0IDI1LjU2QzYuOTU5NDcgMjYuNDU4NSA3" +
                          "Ljk5NjU1IDI4LjE3NDMgMTIgMjcuNDQzN1YzMC42ODE0QzExLjg5NTEgMzEuMDExNiAxMS41NzUxI" +
                          "DMxLjI5MTEgMTAuOTQgMzEuMThDNC41OCAyOS4wNiAwIDIzLjA4IDAgMTZaIiBmaWxsPSIjRkZGRk" +
                          "ZGIi8+CjxjaXJjbGUgY3g9IjI2IiBjeT0iMjYiIHI9IjUiIGZpbGw9IiNCNzhGMDUiLz4KPC9zdmc" +
                          "+Cg==";

  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-pending.svg', `data:image/svg+xml;base64,${icon_data_pending}`],
    ['favicon-failure.svg', `data:image/svg+xml;base64,${icon_data_failure}`],
    ['favicon.ico', `data:image/svg+xml;base64,${icon_data}`], // github.community
  ]);

@tobbez
Copy link
Author

tobbez commented Apr 8, 2020

Script updated (1.4.0). Changes:

  • Pending icon variant added
  • SVGs are now stored as plain text in the script

@sjpotter
Copy link

sjpotter commented Feb 3, 2022

so I've added this, as I've added a pinned github tab where seeing the favicon is important. but now the favicon isn't visible if the tab is focused

perhaps something like this can be added

https://marian-caikovski.medium.com/dynamic-favicon-depending-on-tab-focus-a-use-case-for-promises-and-object-urls-f0ec9e4216da

@tobbez
Copy link
Author

tobbez commented Feb 6, 2022

On most of their domains, GitHub will now use a white favicon in browsers preferring a dark theme.

I have updated the script to remove all those domains, and added a couple new ones (githubstatus.com, opensource.guide).

GitHub's code for switching the icon and this script's code could sometimes interfere, causing no favicon to show at all.

@sjpotter
Copy link

sjpotter commented Feb 6, 2022

at least for me, that didn't seem to help. the dark default firefox theme bar shows my pinned github tab now as black and transparent, which makes it not visible when the tab isn't focused (as opposed to what I commented that before its colors where white and transparent, so visible when not focused, but not visible when focused).

@jtagcat
Copy link

jtagcat commented Feb 7, 2022

github.com/*; *.github.com, and github.community were removed in 1.9.0..? (I did not update)

@vcheeney
Copy link

vcheeney commented Feb 9, 2022

I have similar issues here. I'm using the "Just Black" theme on Chrome, Windows, and the favicon stopped working recently. I'll try downgrading whenever I get a chance to see if it resolves the problem.

Edit: Well, seems to have resolved my problem for now!

@tobbez
Copy link
Author

tobbez commented Feb 10, 2022

As already stated here when I made the update, those domains were removed because they will already use a white favicon in browsers using a dark theme.

Since GitHub's code for switching the favicon and this script interfere sometimes, causing no favicon to be displayed at all, they had to be removed. That issue could likely be fixed, but it's not something I will spend time on.

If you need the old behavior, I suggest you fork the script (or edit it locally) and re-add the @match directives that were removed in 1.9.0.

@jtagcat
Copy link

jtagcat commented Feb 11, 2022

Yeah, will do. I'm using dark for browser elements, and light for webpages.

@tharward-r7
Copy link

tharward-r7 commented Apr 12, 2023

Is there a way to force Github to use a light-mode (dark) favicon even if it thinks the browser prefers dark mode? Whatever logic they use is applying the white icon to any chrome color scheme other than the default, even if that color scheme is light.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment