NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Reddit custom theme // @namespace https://github.com/Farow/userscripts // @description Applies a subreddit stylesheet everywhere // @include https://*.reddit.com/* // @version 1.0.0 // @grant GM_xmlhttpRequest // @connect reddit.com // @connect redditmedia.com // @run-at document-start // ==/UserScript== /* changelog: 2016-05-28 - 1.0.0 - initial release */ /* subreddit template */ let subreddit = 'carbon_beta'; /* custom reddit logo */ let snoo_logo = '//i.imgur.com/4vikRBL.png'; /* css that is applied after the stylesheet */ let custom_css = '.md p { color: #aaaaaa; } [hidden] { display: none !important; }'; let observer = new MutationObserver(head_monitor); let stylesheet_url = localStorage.getItem('custom_css_theme'); try { init(); } catch (error) { console.log(error); } function init () { let link = document.createElement('link'); let observe = 1; link.id = 'custom_css_theme'; link.rel = 'stylesheet'; link.type = 'text/css'; link.href = stylesheet_url ? stylesheet_url : '/r/' + subreddit + '/stylesheet/'; link.title = 'applied_subreddit_stylesheet'; /* append the custom stylesheet */ document.head.appendChild(link); /* check if subreddit stylesheet has already been loaded */ for (let node of document.head.children) { if (is_stylesheet(node) && node.title == 'applied_subreddit_stylesheet') { node.remove(); observe = 0; break; } } /* check for changes to the stylesheet url */ GM_xmlhttpRequest({ method: 'GET', url: '/r/' + subreddit + '/stylesheet/', onload: update_stylesheet_url, }); /* subreddit stylesheet hasn't been added yet */ if (observe) { observer.observe(document.head, { childList: true }); } /* apply final touches after dom loads */ document.addEventListener('DOMContentLoaded', dom_load); } function head_monitor (mutations) { for (let mutation of mutations) { for (let node of mutation.addedNodes) { if (is_stylesheet(node)) { /* reddit default theme, move custom theme below it */ if (node.href.startsWith(window.location.protocol + '//www.redditstatic.com')) { let custom_css_theme = document.getElementById('custom_css_theme'); document.head.appendChild(custom_css_theme); } /* subreddit theme, remove it */ else if (node.title == 'applied_subreddit_stylesheet') { node.remove(); } } } } } function update_stylesheet_url (response) { if (response.status != 200 || stylesheet_url == response.finalUrl) { return; } localStorage.setItem('custom_css_theme', response.finalUrl); if (!stylesheet_url) { return; } /* old url was cached, update with new */ let custom_css_theme = document.getElementById('custom_css_theme'); if (custom_css_theme) { custom_css_theme.href = response.finalUrl; } } function dom_load () { /* no need to monitor <head> anymore */ observer.disconnect(); /* reddit's logo image is not part of a subreddit stylesheet, so we need to fix it */ let header = document.getElementById('header-img'); if (header) { /* on subreddits the logo is an <img> */ if (header.nodeName == 'IMG') { header.src = snoo_logo; } /* on other pages it's a link with a background image */ else if (header.nodeName == 'A') { header.style.setProperty('background', 'url(' + snoo_logo + ') 0% 0%'); } } /* apply custom/user CSS for fixups */ if (custom_css) { add_style(custom_css); } } function is_stylesheet (node) { return node.nodeName == 'LINK' && node.rel == 'stylesheet' && node.id != 'custom_css_theme' ; } function add_style (css) { let style = document.createElement('style'); style.type = 'text/css'; style.appendChild(document.createTextNode(css)); document.head.appendChild(style); return style; }