Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
[UserScript] GitHub: White favicon
// ==UserScript==
// @name GitHub: White favicon
// @version 1.8.0
// @author tobbez
// @match https://github.community/*
// @match https://*.github.com/*
// @match https://github.com/*
// @match https://github.blog/*
// @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
// ==/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)}`], // docs.github.com
['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
]);
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"])');
let mutobs = new MutationObserver(update_favicon);
mutobs.observe(icon_link, {
attributes: true,
});
update_favicon();
})();
@jtagcat
Copy link

jtagcat commented Mar 31, 2020

Does not work anymore. Firefox 75, Tampermonkey v4.10.6105

Works on github.community
Doesn't on github.com

I guess it's something github did.

@tobbez
Copy link
Author

tobbez commented Apr 1, 2020

The script has been updated to account for GitHub's changes (they now serve favicon images as svg).

Also replaced the images the script uses with new ones based on GitHub's SVG images (instead of the old ones derived from GitHub's bitmaps).

@simistern
Copy link

simistern commented Apr 3, 2020

How would I exchange the white icon for the black one instead? (I use dark theme with light tabs) I have tried replacing the base64 string but it doesn't seem to be working

@jtagcat
Copy link

jtagcat commented Apr 3, 2020

How would I exchange the white icon for the black one instead? (I use dark theme with light tabs) I have tried replacing the base64 string but it doesn't seem to be working

Pardon, why do you need this userscript at all then?
Just uninstall/remove/disable the userscript and you should be fine.

@simistern
Copy link

simistern commented Apr 5, 2020

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

But specifically, it is still not good visibility for me, I would like more contrast

Screen Shot 2020-04-05 at 2 56 02 PM

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

@simistern
Copy link

simistern commented Apr 5, 2020

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

simistern commented Apr 6, 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.

@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

dreamca4er commented Apr 8, 2020

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

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