Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Colorize favorite Reddit subs on homepage
// ==UserScript==
// @name Reddit favorites coloring
// @version 1
// @description Color favorite sub threads on homepage
// @include /^https?://www\.reddit\.com/.*$/
// @run-at document-end
// @author Zlatko Masek
// @grant none
// ==/UserScript==
const FAVORITES = new Set();
const ALPHA = '0.2';
const HEX_LENGTH = 6;
const convertStringToArrayBuffer = (str) => {
let bytes = new Uint8Array(str.length);
for (let iii = 0; iii < str.length; iii++) {
bytes[iii] = str.charCodeAt(iii);
}
return bytes;
}
const convertArrayBufferToHexaDecimal = (buffer) => {
let data_view = new DataView(buffer);
let iii, len, hex = '',
c;
for (iii = 0, len = data_view.byteLength; iii < len; iii += 1) {
c = data_view.getUint8(iii).toString(16);
if (c.length < 2) {
c = '0' + c;
}
hex += c;
}
return hex;
}
const hexToRgbA = (hex) => {
if (hex.length === 3) {
hex = [hex[0], hex[0], hex[1], hex[1], hex[2], hex[2]];
} else {
hex = hex.split('');
}
hex = `0x${hex.join('')}`;
return `rgba(${[(hex >> 16) & 255, (hex >> 8) & 255, hex & 255, ALPHA].join(', ')})`;
}
const colorize = () => {
for (const favorite of FAVORITES) {
const favoriteElements = document.querySelectorAll(`a[href="${favorite}"]`);
const promise = window.crypto.subtle.digest({
name: 'SHA-1'
}, convertStringToArrayBuffer(favorite));
promise.then((result) => {
const hex = convertArrayBufferToHexaDecimal(result).substring(0, HEX_LENGTH);
for (const element of favoriteElements) {
const el = element.parentElement.parentElement.parentElement.parentElement;
if (el.hasAttribute('class')) {
el.style['background-color'] = hexToRgbA(hex);
}
}
});
}
}
const removeColor = (favorite) => {
const favoriteElements = document.querySelectorAll(`a[href="${favorite}"]`);
for (const element of favoriteElements) {
const el = element.parentElement.parentElement.parentElement.parentElement;
if (el.hasAttribute('class') && el.hasAttribute('style')) {
el.removeAttribute('style');
}
}
}
const init = () => {
const hamburgerNode = document.getElementById('hamburgers');
const hamburgerCallback = (mutationsList) => {
for (const mutation of mutationsList) {
if (mutation.addedNodes[0] !== undefined) {
if (mutation.addedNodes[0].nodeName === 'DIV') {
for (const node of mutation.addedNodes[0].childNodes[0].childNodes[1].childNodes) {
FAVORITES.add(node.childNodes[0].getAttribute('href'));
}
}
if (mutation.addedNodes[0].nodeName === 'LI') {
FAVORITES.add(mutation.addedNodes[0].childNodes[0].getAttribute('href'));
colorize();
}
}
if (mutation.removedNodes[0] !== undefined) {
if (mutation.removedNodes[0].nodeName === 'LI') {
FAVORITES.delete(mutation.removedNodes[0].childNodes[0].getAttribute('href'));
removeColor(mutation.removedNodes[0].childNodes[0].getAttribute('href'));
}
}
}
}
const hamburgerObserver = new MutationObserver(hamburgerCallback);
hamburgerObserver.observe(hamburgerNode, {
childList: true,
subtree: true
});
const listCallback = (mutationsList) => {
if (FAVORITES.size) {
colorize();
}
}
const listObserver = new MutationObserver(listCallback);
listObserver.observe(hamburgerNode.nextSibling, {
childList: true,
subtree: true
});
}
init();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment