// ==UserScript== // @name Youtube Anti Shorts // @name:zh Youtube Anti Shorts 反短片 // @namespace Anong0u0 // @version 0.4.2 // @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/arrive@2.4.1/minified/arrive.min.js // @license MIT // @downloadURL none // ==/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){return (times > 0) ? this.parentElement.getParentElement(times-1):this;} 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(async () => { if(!timeLock) { timeLock = true; delay(200).then(()=>{timeLock = false;}); document.querySelectorAll("a[href^='/shorts']").forEach(f); } if (oldHref == window.location.href) return; oldHref = window.location.href; if(window.location.pathname.indexOf("/shorts/")!=-1) window.location.replace(window.location.href.replace("/shorts/","/watch?v=")); }) 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: async ()=> { if(Redirect_Shorts_URL) { if(window.location.pathname.indexOf("/shorts/")!=-1) window.location.replace(window.location.href.replace("/shorts/","/watch?v=")); pageUpdateObserver.observe(await waitElementLoad("yt-page-navigation-progress",false,0,100), {attributes: true}); } else pageUpdateObserver.disconnect(); } } 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(); console.log("Anti Shorts loaded");