Youtube Anti Shorts

shorts is a shit, fuck you youtube

目前為 2023-01-21 提交的版本,檢視 最新版本

// ==UserScript==
// @name                Youtube Anti Shorts
// @name:zh             Youtube Anti Shorts 反短片
// @namespace           Anong0u0
// @version             0.4.5
// @description         shorts is a shit, fuck you youtube
// @description:zh      短片就是坨屎,去你的youtube
// @author              Anong0u0
// @match               *://*.youtube.com/*
// @icon                https://www.google.com/s2/favicons?sz=64&domain=youtube.com
// @grant               GM_setValue
// @grant               GM_getValue
// @grant               GM_registerMenuCommand
// @grant               GM_unregisterMenuCommand
// @require             https://cdn.jsdelivr.net/npm/[email protected]/minified/arrive.min.js
// @license             MIT
// ==/UserScript==


let Hide_Shorts_Renderer = GM_getValue("Hide_Shorts_Renderer", true);
let Hide_Shorts_Video = GM_getValue("Hide_Shorts_Video", true);
let Redirect_Shorts_URL = GM_getValue("Redirect_Shorts_URL", true);

Node.prototype.getParentElement = function(times = 0){let e=this;for(let i=0;i<times;i++)e=e.parentElement;return e;}

const delay = (ms = 0) => {return new Promise((r)=>{setTimeout(r, ms)})}

const waitElementLoad = (elementSelector, isSelectAll, tryTimes = 1, interval = 0) =>
{
    return new Promise(async (resolve, reject)=>
    {
        let t = 1, result;
        while(true)
        {
            if(isSelectAll) {if((result = document.querySelectorAll(elementSelector)).length > 0) break;}
            else {if(result = document.querySelector(elementSelector)) break;}

            if(tryTimes>0 && ++t>tryTimes) {reject(new Error("Wait Timeout"));}
            await delay(interval);
        }
        resolve(result);
    })
}

let videos = [], menuID = [], oldHref = null, timeLock = false;

const css = document.createElement("style");
css.innerHTML = `
ytd-reel-shelf-renderer.style-scope.ytd-item-section-renderer,
ytd-mini-guide-entry-renderer[aria-label='Shorts'],
ytd-rich-shelf-renderer[is-shorts],
a.yt-simple-endpoint.style-scope.ytd-guide-entry-renderer[title='Shorts']
{display:none !important}`;

const f = (e)=>
{
    let t = e.getParentElement(3);
    videos.push(t);
    t.hidden=true;
}

const pageUpdateObserver = new MutationObserver(() => // onPageUpdate
{
    if(Hide_Shorts_Video && !timeLock)
    {
        timeLock = true;
        delay(200).then(()=>{timeLock = false;});
        videos.forEach((e)=>{e.hidden=false;})
        videos = [];
        document.querySelectorAll("a[href^='/shorts']").forEach(f);
    }

    if (oldHref == window.location.href) return;
    oldHref = window.location.href;

    toggle.redirect();
})

const toggle =
{
    renderer: ()=>
    {
        if(Hide_Shorts_Renderer) document.documentElement.append(css);
        else css.remove();
    },

    video: ()=>
    {
        if(Hide_Shorts_Video)
        {
            document.querySelectorAll("a[href^='/shorts']").forEach(f);
            document.arrive("a[href^='/shorts']", f);
        }
        else
        {
            document.unbindArrive("a[href^='/shorts']");
            videos.forEach((e)=>{e.hidden=false;})
            videos = [];
        }
    },

    redirect: ()=>
    {
        if(Redirect_Shorts_URL && window.location.pathname.indexOf("/shorts/")!=-1) window.location.replace(window.location.href.replace("/shorts/","/watch?v="));
    }
}

const setMenu = ()=>
{
    menuID.forEach((e)=>{GM_unregisterMenuCommand(e)})
    menuID = [];
    menuID.push(GM_registerMenuCommand(`${Hide_Shorts_Renderer?"Dis":"En"}able "Hide Shorts Renderer"`, ()=>
    {
        Hide_Shorts_Renderer = !Hide_Shorts_Renderer;
        GM_setValue("Hide_Shorts_Renderer", Hide_Shorts_Renderer);
        toggle.renderer();
        setMenu();
    }))
    menuID.push(GM_registerMenuCommand(`${Hide_Shorts_Video?"Dis":"En"}able "Hide Shorts Video"`, ()=>
    {
        Hide_Shorts_Video = !Hide_Shorts_Video;
        GM_setValue("Hide_Shorts_Video", Hide_Shorts_Video);
        toggle.video();
        setMenu();
    }))
    menuID.push(GM_registerMenuCommand(`${Redirect_Shorts_URL?"Dis":"En"}able "Redirect Shorts URL"`, ()=>
    {
        Redirect_Shorts_URL = !Redirect_Shorts_URL;
        GM_setValue("Redirect_Shorts_URL", Redirect_Shorts_URL);
        toggle.redirect();
        setMenu();
    }))
}

toggle.redirect();
toggle.renderer();
toggle.video();
setMenu();
waitElementLoad("yt-page-navigation-progress",false,0,100).then((e)=>{pageUpdateObserver.observe(e, {attributes: true});})
console.log("Anti Shorts loaded");