Greasy Fork is available in English.
Replace youtube redirect links with direct links and extend links text to its full length
当前为
// ==UserScript==
// @name Replace youtube redirect links
// @description Replace youtube redirect links with direct links and extend links text to its full length
// @author MK
// @namespace max44
// @homepage http://greasyfork.icu/en/users/309172-max44
// @match *://*.youtube.com/*
// @match *://*.youtu.be/*
// @icon https://cdn.icon-icons.com/icons2/1488/PNG/512/5295-youtube-i_102568.png
// @version 1.3
// @license MIT
// @require https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
// @run-at document-idle
// ==/UserScript==
(function() {
'use strict';
const rootCallback = function (mutationsList, observer) {
document.querySelectorAll("a[href*='/redirect?']").forEach(replaceRedirect);
document.querySelectorAll("a:not([expanded-by-script])").forEach(showFullLink);
document.querySelectorAll("div#below span.yt-core-attributed-string > span > span.yt-core-attributed-string--highlight-text-decorator:not([expanded-by-script]) > a[href*='/watch?']").forEach(showFullVideoName);
document.querySelectorAll("div#below span.yt-core-attributed-string > span > span.yt-core-attributed-string--highlight-text-decorator:not([expanded-by-script]) > a[href*='/shorts/']").forEach(showFullVideoName);
}
const rootNode = document.querySelector("body");
if (rootNode != null) {
const rootObserver = new MutationObserver(rootCallback);
rootObserver.observe(rootNode, {childList: true, subtree: true});
}
function replaceRedirect(link) { //Remove redirection
link.href = decodeURIComponent(link.href.replace (/^.*\?(.*&)q=([^&]+)(&.*)?$/, '$2'));
const wrpLink = link.wrappedJSObject || link;
if (wrpLink.data && wrpLink.data.urlEndpoint) {
wrpLink.data.urlEndpoint.url = link.href;
}
showFullLink(link);
}
function showFullLink(link) { //Expand link to full length
if (link.innerText.substring(0, 20) == link.href.substring(0, 20) && link.innerText.substring(link.innerText.length-3, link.innerText.length) === "...") {
link.innerText = link.href;
link.setAttribute("expanded-by-script", "true");
} else link.setAttribute("expanded-by-script", "false");
}
function showFullVideoName(link) { //Expand short video name to full one, taken from previous text
link.parentElement.setAttribute("expanded-by-script", "false");
const rangeBefore = document.createRange(); //Create a range from the start of the parent till the target element
rangeBefore.setStart(link.parentElement.parentElement.parentElement, 0);
rangeBefore.setEndBefore(link.parentElement.parentElement);
var strFullName = rangeBefore.toString();
//console.log("strFullName long: " + strFullName);
strFullName = strFullName.replace(/.*[\n](?!$)/g, ""); //Remove all text except the last line
//console.log("strFullName short: " + strFullName);
if (strFullName.length > 0) {
var strHTML = link.parentElement.parentElement.parentElement.outerHTML;
strHTML = strHTML.replace(strFullName, ""); //Remove full video name from text
strHTML = strHTML.replace(/yt-core-image--content-mode-scale-to-fill"><\/span>/gi, "yt-core-image--content-mode-scale-to-fill yt-core-image--loaded\" src=\"https://www.gstatic.com/youtube/img/watch/yt_favicon.png\"></span>"); //Add YT icon if missed
link.parentElement.parentElement.parentElement.outerHTML = strHTML;
strFullName = strFullName.replace(/[\n]/g, ""); //Remove \n
strFullName = strFullName.replace(/[ ]+$/g, ""); //Remove trailing spaces
strFullName = strFullName.replace(/[ ]*:+$/g, ""); //Remove trailing semicolon and spaces
var newLink = document.querySelector("div#below span.yt-core-attributed-string > span > span.yt-core-attributed-string--highlight-text-decorator[expanded-by-script='false'] > a"); //New query, because previous setting of outerHTML rebuilded this node in DOM
if (newLink != null) {
newLink.parentElement.setAttribute("expanded-by-script", "true");
var strHTML2 = newLink.parentElement.outerHTML;
//console.log("strHTML: " + strHTML2);
strHTML2 = strHTML2.replace(/<\/span> • .* <\/a><\/span>/gi, "</span> • " + strFullName + " </a></span>"); //Add full video name to link
//strHTML2 = strHTML2.replace(/yt-core-image--content-mode-scale-to-fill"><\/span>/gi, "yt-core-image--content-mode-scale-to-fill yt-core-image--loaded\" src=\"https://www.gstatic.com/youtube/img/watch/yt_favicon.png\"></span>"); //Add YT icon if missed
newLink.parentElement.outerHTML = strHTML2;
}
}
}
})();