Greasy Fork

Spoiler-free Crunchyroll

Hide name, image, and description of episodes

当前为 2022-10-08 提交的版本,查看 最新版本

// ==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/*
// ==/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 <html> 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 <head> 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();
}