您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Redirects YouTube Shorts to regular pages.
// ==UserScript== // @name YouTube Unshortifier // @match https://www.youtube.com/* // @grant none // @version 1.0 // @author lucasm // @namespace luluco250.YouTubeUnshortifier // @license CC0 // @description Redirects YouTube Shorts to regular pages. // ==/UserScript== (() => { "use strict"; const shortsLinkRegex = /\/shorts\/([A-z0-9_-]+)/; function isObject(value) { return !!value && typeof value === "object" && !Array.isArray(value); } function forObjectInArray(array, callback) { for (const item of array) { if (!item || typeof item !== "object") continue; if (Array.isArray(item)) { forObjectInArray(item, callback); continue; } callback(item); } } /** * Recursively look for a property of a specific name in an object. * If it is found, it is returned as an array of the object that contains it and its value. * Otherwise it returns null. */ function forEachProp(obj, propName, callback) { for (const [key, value] of Object.entries(obj)) { if (key === propName) { callback(obj, value); continue; } if (!value || typeof value !== "object") continue; if (Array.isArray(value)) { forObjectInArray(value, x => forEachProp(x, propName, callback)); continue; } forEachProp(value, propName, callback); } } function tryGetShortId(uri) { if (!uri) return null; const match = uri.match(shortsLinkRegex); return match === null ? null : match[1]; } function tryUnshortify(uri, callback) { const id = tryGetShortId(uri); if (id === null) { return false; } console.log(`Unshortifying ${id}`); callback(`/watch?v=${id}`); return true; } function unshortifyMany(anchorNodes) { if (!anchorNodes) { return; } for (const a of anchorNodes) { const href = a.getAttribute("href"); tryUnshortify(href, x => a.setAttribute("href", x)); } } new MutationObserver(mutations => { unshortifyMany(mutations.map(x => x.target)); }).observe(document.body, { subtree: true, attributeFilter: ["href"], }); window.addEventListener("load", () => { console.log("YouTube Unshortifier initialized."); console.log("Unshortifying existing anchors..."); unshortifyMany(document.getElementsByTagName("a")); if (window.hasOwnProperty("ytInitialData")) { forEachProp(ytInitialData, "url", (obj, url) => { if (tryUnshortify(url, x => obj.url = x)) { obj.webPageType = "WEB_PAGE_TYPE_WATCH"; } }); } }); })();