Youtube restore slim tubnails

Restore slim tubnails on home and subs pages. Disable autoplay on unsub channel's home.

当前为 2021-11-19 提交的版本,查看 最新版本

// ==UserScript==
// @name         Youtube restore slim tubnails
// @namespace    http://tampermonkey.net/
// @version      0.4.1
// @description  Restore slim tubnails on home and subs pages. Disable autoplay on unsub channel's home.
// @author       me
// @match        https://www.youtube.com/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    //https://stackoverflow.com/a/52809105----
    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);

    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);

    window.addEventListener('popstate',()=>{
        window.dispatchEvent(new Event('locationchange'))
    });

    //https://stackoverflow.com/a/45956628----
    //youtube wtf events
    //new layout > 2017
    window.addEventListener("yt-navigate-finish", function(event) {
        window.dispatchEvent(new Event('locationchange'))
    });

    //old layout < 2017
    window.addEventListener("spfdone", function(e) {
        window.dispatchEvent(new Event('locationchange'))
    });

    //should made portable my settings
    const getRelative = () => {
        var p = document.createElement("p");
        p.innerHTML = "test";
        p.style.fontSize = "16px";
        document.body.appendChild(p);
        var relative = 19/p.offsetHeight;
        p.innerHTML = "";
        return relative;
    }

    const disableAutoplayUnsubChannel = () => {
        if(interval != null){
            clearInterval(interval);
        }
        //(c|channel|user|u) wtf youtube!
        if(document.URL.match(/^(https:\/\/www\.youtube\.com)\/(c|channel|user|u)\/([a-z0-9_]*)(\/featured)?$/i) != null){
            var interval = setInterval(() => {
                var videos = document.getElementsByClassName("video-stream html5-main-video");
                if( videos != null){
                    videos[videos.length-1].addEventListener("play", () => {
                        videos[videos.length-1].pause();
                    }, {once: true});
                    videos[videos.length-1].pause();
                    clearInterval(interval);
                }
            },100);
        }
    }

    const restoreSlimTubnails = () => {
        //work only on www.youtube.com and www.youtube.com/feed/subscriptions. If run on video's page it causes cpu load
        if(!firstRun || document.URL.match(/^(https:\/\/www\.youtube\.com)(\/|\/feed\/subscriptions)?$/i) == null) return;
        var relative = getRelative();
        var itemWidth = 240*relative;
        var postWidth = 350*relative;
        var subsWidth = 214;
        var padding = 48;
        var fontSize = 1.4*relative;
        var lineHeight = 1.8*relative;
        let parentSize = document.createElement("style");
        var parent = document.getElementById("page-manager");

        if(parent == null) return;

        const updateParentSize = () => {
            parentSize.innerHTML = ":root{--how-many-items:"+parseInt(parent.offsetWidth/itemWidth)+";"+
                "--how-many-posts:"+parseInt(parent.offsetWidth/postWidth)+";"+
                "--variable-columns-width:"+parseInt((parent.offsetWidth-padding)/subsWidth)*subsWidth+"px}";
        }

        updateParentSize();

        let style = document.createElement("style");
        style.innerHTML = "ytd-rich-grid-renderer.ytd-two-column-browse-results-renderer{"+
            "--ytd-rich-grid-items-per-row:var(--how-many-items) !important;"+
            "--ytd-rich-grid-posts-per-row:var(--how-many-posts) !important;"+
            "--ytd-rich-grid-movies-per-row:11 !important;}"+

            "#metadata-line.ytd-video-meta-block,ytd-channel-name{"+
            "max-height: 7.1rem !important;"+
            "font-size:"+fontSize+"rem !important;"+
            "line-height:"+lineHeight+"rem !important}"+

            "ytd-two-column-browse-results-renderer[page-subtype='subscriptions']{"+
            "width:var(--variable-columns-width) !important;"+
            "max-width:var(--variable-columns-width) !important}"+
            
            //new fix
            "ytd-rich-section-renderer[align-within-rich-grid] #content.ytd-rich-section-renderer{margin:0 8px !important}"+
            "ytd-rich-grid-renderer>#contents{max-width: calc( var(--ytd-rich-grid-items-per-row) * (var(--ytd-rich-grid-item-max-width) + var(--ytd-rich-grid-item-margin)) - var(--ytd-rich-grid-item-margin) );"+
            "padding: 0 24px;}";
        document.body.appendChild(parentSize);
        document.body.appendChild(style);
        new ResizeObserver(updateParentSize).observe(parent);
        firstRun = false;
        
        //new fix after some youtube changes
        var grid_renderer_contents = document.querySelectorAll("ytd-rich-grid-renderer>#contents")[0];
        const fixThubnails = function(){
            document.querySelectorAll("ytd-rich-grid-renderer>#contents > ytd-rich-grid-row > #contents > ytd-rich-item-renderer").forEach(
                function(element){element.parentNode.parentNode.insertAdjacentElement('beforebegin',element);}
            );
            document.querySelectorAll("ytd-rich-grid-renderer>#contents > ytd-rich-grid-row").forEach(
                function(element){element.remove()}
            );
        }
        fixThubnails();
        new MutationObserver(function (mutationList,observer){
            observer.disconnect();
            fixThubnails();
            observer.observe(grid_renderer_contents,{childList: true});
        }).observe(grid_renderer_contents,{childList: true});
    }


    var firstRun = true;
    const run = () => {
        disableAutoplayUnsubChannel();
        restoreSlimTubnails();
    }

    run();

    window.addEventListener('locationchange', run);
})();