您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Convert links and optionally URL text which points to a YouTube video, into embedded YouTube frame. For URL text, it can be converted to a link only. The main function can be configured for on-demand-only for slow computers. If enabled, the main function can be executed via bookmarklet using this URL: javascript:yte_ujs()
// ==UserScript== // @name YouTube Embedder // @namespace https://greasyfork.org/en/users/85671-jcunews // @description Convert links and optionally URL text which points to a YouTube video, into embedded YouTube frame. For URL text, it can be converted to a link only. The main function can be configured for on-demand-only for slow computers. If enabled, the main function can be executed via bookmarklet using this URL: javascript:yte_ujs() // @author jcunews // @version 1.0.6 // @license GNU AGPLv3 // @match *://*/* // @exclude *://www.youtube.com/embed/* // @grant none // ==/UserScript== (function(xe, fe, ce, rx, trx, trxg, hrx, lo, qu) { //===== CONFIGURATION BEGIN ===== //The minimum width & height of the container element where the link or URL text is found, in order to apply the conversion. var minimumWidth = 256; var minimumHeight = 144; //Embedded YouTube frame width in pixels (should be multiplication of 16). //If zero, the width is the container element width of the link or URL text, and the height is calculated using 16:9 ratio (widescreen video dimension). //If the final width is smaller than the minimum width setting, and if the source is an URL text, it will be converted to a link instead. var frameWidth = 0; //Enable URL text to YouTube frame converter (aside from links). var convertUrlText = true; //Convert to link only, when on these domains. var convertToLinkOnlyDomains = /somesite\.info|subnet\d+\.other\.net/i; //Delay between processing each node scanning queue. Lower value means faster scanning, but more CPU intensive. //Higher value means lesser CPU usage, but also means slower scanning. var queueDelay = 50; //in milliseconds. 1000ms = 1 second. //Number of nodes to process at a time. Adjust this and queueDelay settings to find the best performance without triggering the web browser's busy dialog. //Lower value means lesser CPU usage, but also means slower scanning. var nodesPerProcessing = 5; //The onDemandOnlyDomains makes the main function available on-demand-only for specific or all sites. //If enabled, it's accessible via bookmarklet using this URL: javascript:yte_ujs() //This setting is for slow computers, since the main function is CPU intensive. var onDemandOnlyDomains = /somesite\.info|subnet\d+\.other\.net/i; //===== CONFIGURATION END ===== function linkToFrame(node, m, pn, w, h, a) { if (node.ytebd_nocovert || !node.offsetWidth || !node.offsetHeight) return; if (!lo && (m = node.href.match(rx))) { m = "https://www.youtube.com/embed/" + m[1]; pn = node.parentNode; while (pn) { if (pn.scrollHeight > pn.offsetHeight) break; pn = pn.parentNode; } h = ((pn || node.parentNode).offsetHeight * 0.9) >> 0; w = frameWidth > 0 ? frameWidth : node.parentNode.offsetWidth; if ((pn = (w / 16 * 9) >> 0) > h) { w = (h / 9 * 16) >> 0; } else h = pn; if ((w >= minimumWidth) && (h >= minimumHeight)) { c = document.createElement("IFRAME"); c.src = m; c.allowFullscreen = true; c.referrerPolicy = "no-referrer"; c.style.border = "none"; c.width = w; c.height = h; c.ytebd_nocovert = 1; node.replaceWith(c); } else if (w && h) node.ytebd_nocovert = 1; } else node.ytebd_nocovert = 1; } function processNode(node, c, m, w, h, pn) { switch (node.nodeType) { case Node.ELEMENT_NODE: case Node.DOCUMENT_NODE: if (node.ytebd_nocovert) break; if (node.nodeName === "A") { linkToFrame(node); node = null; } if (node && (xe.indexOf(node.nodeName) < 0)) { if (fe.indexOf(node.nodeName) >= 0) { m = (m = node.src.match(/:\/\/(.*?)\//)) && (m[1] === location.hostname); } else m = true; if (m && ((node.nodeName !== "A") || convertUrlText)) { node.childNodes.forEach(queue); } } break; case Node.TEXT_NODE: if (convertUrlText && (m = node.nodeValue.match(trx))) { w = node.nodeValue; h = -1; a = []; while (c = trxg.exec(w)) { if (c.index > 0) a.push(w.substring(h, c.index)); a.push(c); h = c.index + c[0].length; } if ((h > 0) && (h < w.length)) a.push(w.substr(h)); for (c = a.length - 1; c >= 0; c--) { if (!Array.isArray(a[c]) && !a[c].replace(/^\s+|\s+$/g, "")) a.splice(c, 1); } if (node.parentNode.nodeName === "A") { if (a.length === 1) { node.href = "https://www.youtube.com/embed/" + a[0][1]; node.rel = "nofollow noopener noreferrer"; node.target = "_blank"; } a = null; } if (a) { pn = node.parentNode; c = node.nextSibling; a.forEach(function(v, i, n) { if (!Array.isArray(v)) { n = document.createTextNode(v); } else { n = document.createElement("A"); n.textContent = v[0]; n.title = v[1]; n.href = "https://www.youtube.com/embed/" + v[1]; n.rel = "nofollow noopener noreferrer"; n.target = "_blank"; } if (i > 0) { pn.insertBefore(n, c); } else { node.replaceWith(n); } linkToFrame(n); }); } } } } function processQueue() { setTimeout(function(nodes) { nodes.forEach(processNode); if (qu.length) setTimeout(processQueue, queueDelay); }, queueDelay, qu.splice(0, nodesPerProcessing)); } function queue(node) { qu.push(node); if (qu.length === 1) setTimeout(processQueue, queueDelay); } xe = ["BUTTON", "INPUT", "SCRIPT", "SELECT", "STYLE"]; fe = ["FRAME", "IFRAME"]; rx = /^(?:https?:\/\/)?(?:(?:(?:www\.)?youtube\.com\/)(?:embed\/|watch\?.*v=)|youtu\.be\/)([0-9a-z_\-]{11})/i; trx = /(?:https?:\/\/)?(?:(?:(?:www\.)?youtube\.com\/)(?:embed\/|watch\?.*v=)|youtu\.be\/)([0-9a-z_\-]{11})[^\s,'")\]}>]*/i; trxg = /(?:https?:\/\/)?(?:(?:(?:www\.)?youtube\.com\/)(?:embed\/|watch\?.*v=)|youtu\.be\/)([0-9a-z_\-]{11})[^\s,'")\]}>]*/gi; hrx = /^(?:(?:www\.)?youtube\.com|youtu\.be)$/i; lo = convertToLinkOnlyDomains.test(location.hostname); qu = []; if (nodesPerProcessing <= 0) nodesPerProcessing = 1; if (!document.body) return; if (onDemandOnlyDomains.test(location.hostname)) { window.yte_ujs = function() { queue(document.body); return undefined; }; } else { if (document.body) queue(document.body); (new MutationObserver(function(records) { records.forEach(function(record) { if (record.type === "childList") { record.addedNodes.forEach(queue); } else queue(record.target); }); })).observe(document.body, {attributes: true, attributeFilter: ["class", "style"], childList: true, subtree: true}); } })();