// ==UserScript== // @name Spoiler-free Crunchyroll // @description Hide name, image, and description of episodes // @author TimeBomb // @namespace https://greasyfork.org/users/160017 // @version 0.7 // @copyright 2018 // @run-at document-start // @match https://*.crunchyroll.com/* // @downloadURL none // ==/UserScript== // USER CONFIGS BEGIN var USER_CONFIG = { EPISODE_IMAGES: true, // true: Blur episode images on Continue Watching and Your Watchlist and Series pages and Next/Previous episode EPISODE_NAMES: true, // true: Blur episode names on Continue Watching and Your Watchlist and Series pages and Next/Previous episode PLAYER_EPISODE_NAME: true, // true: Blur episode name that you're currently watching TITLE_EPISODE_NAME: true, // true: Censors series+episode name from the title of the page (visible in your browser tab) }; // USER CONFIGS END, DO NOT EDIT ANYTHING BELOW var DEBUG = true; // We very briefly hide the tag here, to ensure the user doesn't see unfiltered content // The performance impact of applying our custom CSS is so minimal that users shouldn't notice this // Once we finish applying our CSS below, we show the page and apply some final filters to truncate episode names that contain the episode number or link document.documentElement.style.display = 'none'; // Developer Note: // We are extra performant because most of our filters are just CSS we apply to the prior to loading. // We avoid jQuery and try to avoid function calls for performance's sake. // Previous, less optimized versions of this script noticably slowed down the page; our performance is great as of 0.3 though. // Super fragile custom CSS incoming, good luck if Crunchyroll changes their DOM. var cssE = ''; if (USER_CONFIG.EPISODE_IMAGES) { cssE = cssE + '.card figure { filter: blur(20px) }'; cssE = cssE + '[data-t="watch-list-card"] figure { filter: blur(20px) }'; cssE = cssE + '[data-t="playable-card-mini"] figure { filter: blur(20px); }' } if (USER_CONFIG.EPISODE_NAMES) { cssE = cssE + '.card h4 a { filter: blur(20px) }'; cssE = cssE + '[data-t="watch-list-card"] h5 { filter: blur(6px) }'; cssE = cssE + '[data-t="playable-card-mini"] h4 a { filter: blur(10px); }' } if (USER_CONFIG.PLAYER_EPISODE_NAME) { cssE = cssE + '.current-media-wrapper h1 { filter: blur(12px) }'; } try { var $newStyleE = document.createElement('style'); var cssNodeE = document.createTextNode(cssE); $newStyleE.appendChild(cssNodeE); document.head.appendChild($newStyleE); } catch (e) { if (DEBUG) { console.error('CSS Error:', e); } } document.documentElement.style.display = 'inherit'; if (USER_CONFIG.TITLE_EPISODE_NAME) { const episodeRegex = /Watch on Crunchyroll$/; const censoredTitle = '[Episode Name Censored] - Watch on Crunchyroll'; function censorDocTitle() { if (document.title !== censoredTitle && episodeRegex.test(document.title)) { document.title = '[Episode Name Censored] - Watch on Crunchyroll'; } } // Observe when document title changes var target = document.querySelector('head > title'); var observer = new MutationObserver(censorDocTitle); observer.observe(target, { subtree: true, characterData: true, childList: true }); censorDocTitle(); }