Greasy Fork is available in English.

Youtube: Hide Video

Make Youtube Video and Images Opacity Lower.

As of 2020-04-17. See the latest version.

// ==UserScript==
// @name         Youtube: Hide Video
// @version      1.0.1
// @description  Make Youtube Video and Images Opacity Lower.
// @author       Hayao-Gai
// @namespace	 https://github.com/HayaoGai
// @icon         https://upload.wikimedia.org/wikipedia/commons/4/4c/YouTube_icon.png
// @include      http*://www.youtube.com/*
// @grant        GM_getValue
// @grant        GM_setValue
// ==/UserScript==

/* jshint esversion: 6 */

(function() {
    'use strict';

    // Icons made by https://www.flaticon.com/authors/pixel-perfect
    const off1 = `<svg width="35" height="35" viewBox="0 -107 512 512"><path d="m362.667969 298.667969h-213.335938c-82.34375 0-149.332031-67.007813-149.332031-149.335938 0-82.324219 66.988281-149.332031 149.332031-149.332031h213.335938c82.34375 0 149.332031 67.007812 149.332031 149.332031 0 82.328125-66.988281 149.335938-149.332031 149.335938zm-213.335938-266.667969c-64.703125 0-117.332031 52.652344-117.332031 117.332031 0 64.683594 52.628906 117.335938 117.332031 117.335938h213.335938c64.703125 0 117.332031-52.652344 117.332031-117.335938 0-64.679687-52.628906-117.332031-117.332031-117.332031zm0 0"/><path d="m149.332031 234.667969c-47.058593 0-85.332031-38.273438-85.332031-85.335938 0-47.058593 38.273438-85.332031 85.332031-85.332031 47.0625 0 85.335938 38.273438 85.335938 85.332031 0 47.0625-38.273438 85.335938-85.335938 85.335938zm0-138.667969c-29.394531 0-53.332031 23.914062-53.332031 53.332031 0 29.421875 23.9375 53.335938 53.332031 53.335938 29.398438 0 53.335938-23.914063 53.335938-53.335938 0-29.417969-23.9375-53.332031-53.335938-53.332031zm0 0"/></svg>`;
    const off2 = `<svg width="35" height="35" viewBox="0 -107 512 512"><path d="m362.667969 0h-213.335938c-82.324219 0-149.332031 66.988281-149.332031 149.332031 0 82.347657 67.007812 149.335938 149.332031 149.335938h213.335938c82.324219 0 149.332031-66.988281 149.332031-149.335938 0-82.34375-67.007812-149.332031-149.332031-149.332031zm-213.335938 234.667969c-47.058593 0-85.332031-38.273438-85.332031-85.335938 0-47.058593 38.273438-85.332031 85.332031-85.332031 47.0625 0 85.335938 38.273438 85.335938 85.332031 0 47.0625-38.273438 85.335938-85.335938 85.335938zm0 0"/></svg>`;
    const on1 = `<svg width="35" height="35" viewBox="0 -107 512 512"><path d="m0 149.332031c0 82.347657 67.007812 149.335938 149.332031 149.335938h213.335938c82.324219 0 149.332031-66.988281 149.332031-149.335938 0-82.34375-67.007812-149.332031-149.332031-149.332031h-213.335938c-82.324219 0-149.332031 66.988281-149.332031 149.332031zm277.332031 0c0-47.058593 38.273438-85.332031 85.335938-85.332031 47.058593 0 85.332031 38.273438 85.332031 85.332031 0 47.0625-38.273438 85.335938-85.332031 85.335938-47.0625 0-85.335938-38.273438-85.335938-85.335938zm0 0"/></svg>`;
    const on2 = `<svg width="35" height="35" viewBox="0 -107 512 512"><path d="m362.667969 298.667969h-213.335938c-82.34375 0-149.332031-67.007813-149.332031-149.335938 0-82.324219 66.988281-149.332031 149.332031-149.332031h213.335938c82.34375 0 149.332031 67.007812 149.332031 149.332031 0 82.328125-66.988281 149.335938-149.332031 149.335938zm-213.335938-266.667969c-64.703125 0-117.332031 52.652344-117.332031 117.332031 0 64.683594 52.628906 117.335938 117.332031 117.335938h213.335938c64.703125 0 117.332031-52.652344 117.332031-117.335938 0-64.679687-52.628906-117.332031-117.332031-117.332031zm0 0"/><path d="m362.667969 234.667969c-47.0625 0-85.335938-38.273438-85.335938-85.335938 0-47.058593 38.273438-85.332031 85.335938-85.332031 47.058593 0 85.332031 38.273438 85.332031 85.332031 0 47.0625-38.273438 85.335938-85.332031 85.335938zm0-138.667969c-29.398438 0-53.335938 23.914062-53.335938 53.332031 0 29.421875 23.9375 53.335938 53.335938 53.335938 29.394531 0 53.332031-23.914063 53.332031-53.335938 0-29.417969-23.9375-53.332031-53.332031-53.332031zm0 0"/></svg>`;

    css();
    detectUrl();

    window.addEventListener("load", init);

    function init() {
        addButton();
        hideTarget("img", 0);
        hideTarget("video", 0);
        keyListener();
        observeReady(0);
    }

    function addButton() {
        // get
        const logo = isCurrent() ? document.querySelector("ytd-topbar-logo-renderer#logo:not(added)") : document.querySelector(".yt-masthead-logo-container:not(added)");
        if (!logo) return;
        logo.classList.add("added");
        // set
        const button = document.createElement("span");
        button.classList.add("switch");
        // dark theme
        const attDark = document.createAttribute("dark");
        attDark.value = isDark();
        button.setAttributeNode(attDark);
        // svg
        button.innerHTML = switchSVG();
        // append
        logo.parentNode.insertBefore(button, logo.nextSibling);
        // listener
        button.addEventListener("click", () => {
            setToggle(!getToggle());
            button.innerHTML = switchSVG();
        });
    }

    function hideTarget(target, retry) {
        // get
        if (document.querySelectorAll(target).length === 0) {
            if (retry < 10) {
                retry++;
                setTimeout(() => hideTarget(target, retry), 500);
                return;
            } else {
                return;
            }
        }
        // set
        if (getToggle()) {
            document.querySelectorAll(target).forEach(t => t.classList.add("hide"));
        } else {
            document.querySelectorAll(target).forEach(t => t.classList.remove("hide"));
        }
    }

    function manualDark() {
        const button = document.querySelector("span.switch");
        button.setAttribute("dark", window.location.href.includes("watch?v=") ? true : isDark());
        button.innerHTML = switchSVG();
    }

    function keyListener() {
        document.addEventListener("keydown", e => {
            if (e.keyCode === 72) {
                const button = document.querySelector(".switch");
                if (!button) return;
                setToggle(!getToggle());
                button.innerHTML = switchSVG();
            }
        });
    }

    function setToggle(value) {
        GM_setValue("switch", value);
        hideTarget("img", 0);
        hideTarget("video", 0);
    }

    function getToggle() {
        return GM_getValue("switch", false);
    }

    function switchSVG() {
        //const on = (!isDark() && !window.location.href.includes("watch?v=")) ? on1 : on2;
        //const off = (!isDark() && !window.location.href.includes("watch?v=")) ? off1 : off2;
        return getToggle() ? on2 : off2;
    }

    function isCurrent() {
        if (!!document.querySelector(".yt-masthead-logo-container:not(added)")) {
            return false;
        } else {
            return true;
        }
    }

    function isDark() {
        if (!isCurrent()) {
            //return false;
            return true;
        } else {
            return document.querySelector("html").getAttribute("dark");
        }
    }

    function observeReady(retry) {
        const target1 = document.querySelector("html");
        const target2 = isCurrent ? document.querySelector("ytd-item-section-renderer#sections") : document.head;
        const target3 = document.querySelector("ytd-section-list-renderer");
        if (!target1 || (window.location.href.includes("watch?v=") && !target2)) {
            if (retry < 10) {
                retry++;
                setTimeout(() => observeReady(retry), 500);
            } else {
                console.log("Error: Can't get the specific node.");
            }
        } else {
            observeSystem(target1, target2);
        }
    }

    function observeSystem(target1, target2) {
        const Mutation = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
        const observer1 = new Mutation(manualDark);
        const observer2 = new Mutation(() => hideTarget("img", 0));
        const config = { attributes: true, childList: true, characterData: true };
        if (target1) observer1.observe(target1, config);
        if (target2) observer2.observe(target2, config);
    }

    function detectUrl() {
        window.addEventListener('locationchange', init);
        // situation 1
        history.pushState = ( f => function pushState(){
            var ret = f.apply(this, arguments);
            window.dispatchEvent(new Event('pushState'));
            window.dispatchEvent(new Event('locationchange'));
            return ret;
        })(history.pushState);
        // situation 2
        history.replaceState = ( f => function replaceState(){
            var ret = f.apply(this, arguments);
            window.dispatchEvent(new Event('replaceState'));
            window.dispatchEvent(new Event('locationchange'));
            return ret;
        })(history.replaceState);
        // situation 3
        window.addEventListener('popstate', () => window.dispatchEvent(new Event('locationchange')));
    }

    function css() {
        const style = document.createElement("style");
        style.type = "text/css";
        style.innerHTML =
            `.switch {
                 position: absolute;
                 left: 190px;
                 top: 8px;
             }
             .switch[dark="true"] {
                 position: absolute;
                 left: 190px;
                 top: 8px;
                 fill: white;
             }
             .hide {
                 transition: opacity 0.3s;
                 opacity: 0.1;
             }`;
        document.head.appendChild(style);
    }

})();