Skip to content

Instantly share code, notes, and snippets.

@zmasek
Last active September 29, 2018 16:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zmasek/fb4af125f837feddac83eb6bafa5c689 to your computer and use it in GitHub Desktop.
Save zmasek/fb4af125f837feddac83eb6bafa5c689 to your computer and use it in GitHub Desktop.
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 updateFavorites = () => {
const favoriteElements = document.querySelectorAll('[id^="focus-fav"]');
for (const element of favoriteElements) {
FAVORITES.add(element.getAttribute('href'));
}
colorize();
}
const init = () => {
const findLink = () => {
const linkNode = document.querySelector('[id^="focus-fav"]');
if (linkNode) {
clearInterval(intervalFind);
updateFavorites();
const hamburgerNode = linkNode.parentNode;
const hamburgerCallback = (mutationsList) => {
for (const mutation of mutationsList) {
if (mutation.addedNodes[0] !== undefined) {
if (mutation.addedNodes[0].nodeName === 'A' && mutation.addedNodes[0].id.startsWith("focus-fav")) {
updateFavorites();
}
}
if (mutation.removedNodes[0] !== undefined) {
if (mutation.removedNodes[0].nodeName === 'A' && mutation.removedNodes[0].id.startsWith("focus-fav")) {
FAVORITES.delete(mutation.removedNodes[0].getAttribute('href'));
removeColor(mutation.removedNodes[0].getAttribute('href'));
}
}
}
}
const hamburgerObserver = new MutationObserver(hamburgerCallback);
hamburgerObserver.observe(hamburgerNode, {
childList: true,
subtree: true
});
const listCallback = (mutationsList) => {
if (FAVORITES.size) {
colorize();
}
}
const listNode = document.querySelector('div[data-redditstyle]').nextSibling;
const listObserver = new MutationObserver(listCallback);
listObserver.observe(listNode, {
childList: true,
subtree: true
});
}
}
const intervalFind = setInterval(findLink, 1000);
}
init();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment