// ==UserScript==
// @name Linkify·改了又改
// @version 1.0.0
// @author Hmjz100、极品小猫
// @description 在页面中查找类似URL但没有超链接的内容,并将其转换为可单击的链接。改这个只是为了在原脚本的基础上加个开关指示器和修复不显示图片的Bug以及支持DOM更新而已...
// @include *://*/*
// @exclude http*://www.baidu.com/*
// @exclude http*://www.google.com/*
// @exclude http*://pan.baidu.com/*
// @exclude http*://yun.baidu.com/*
// @exclude http*://vscode.dev/*
// @require https://unpkg.com/jquery@3.6.0/dist/jquery.min.js
// @run-at document-idle
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_addStyle
// @grant GM_notification
// @grant GM_registerMenuCommand
// @grant unsafeWindow
// @namespace https://github.com/hmjz100/
// @license GPL-3.0
// @downloadURL none
// ==/UserScript==
// 获取本地保存的数值(仅用于 Greasemonkey)
function getValue(name) {
return GM_getValue(name);
}
// 修改本地保存的数值(仅用于 Greasemonkey)
function setValue(name, value) {
GM_setValue(name, value);
}
function Linkify() {
GM_addStyle(`
.newhref {
border: 2px dashed #A099F0 !important;
}
.newhref:hover {
border-color: #7367f080 !important;
}
`);
let urlRegexRule=[ //协议规则,正则模式,\需要转义\\
'https?:\\/\\/[^\\s+"\\\'<>,\\[\\]()\:\\*\\u4E00-\\u9FFF]+', //ALL,http通用规则
'(?:https?:\\/\\/)?\\w+(%E7%82%B9|点)\\w+(%E7%82%B9|点)\\w+\\/[^\\s+"\\\'<>,\\[\\]()\:\\*\\u4E00-\\u9FFF]+', //域名中包含中文 . → 点
'https?:\\/\\/mega.nz\\/#!\w+![^\\s+"\'<>,\\]]+', //mega 专用规则
'ed2k:\\/\\/\\|file\\|[^\\|]+\\|\\d+\\|\\w{32}\\|(?:h=\\w{32}\\|)?\\/', //ed2k专用规则
'magnet:\\?xt=urn:btih:\\w{40}(&[\\w\\s]+)?' //magnet 专用规则
], urlRegexStr=urlRegexRule.join('|');
var urlRegex=new RegExp(`\\b(${urlRegexStr})`,'ig'); //协议规则,正则模式,\需要转义\\
//ed2k://|file|mura-041616_381.mp4|1874185231|E7D60A7A854CF7AE0FF77AC306808760|h=SYGOH7KKTWHJNA4OBVAEOANW27FT5RJE|/
// tags we will scan looking for un-hyperlinked urls
var allowedParents = [ //允许处理的文本的父标签
"body",
"code", "blockquote",
"abbr", "acronym", "address", "applet", "b", "bdo", "big",
"caption", "center", "cite", "dd", "del", "div", "dfn", "dt", "em",
"fieldset", "font", "form", "i", "iframe",
"ins", "kdb", "li", "object", "pre[not(contains(@class, 'brush'))]", "p", "q", "samp", "small", "span", "strike", "font",
"s", "strong", "sub", "sup", "td", "th", "tt", "u", "var",
"h1", "h2", "h3", "h4", "h5", "h6",
'url','img'
];
//[not(contains(@class, "brush"))],避免与 SyntaxHighlighter 高亮插件冲突
let allowedParentsRule = allowedParents.join(" or parent::");
let xpath = `//text()[(parent::${allowedParentsRule}) and (contains(translate(., 'HTTP', 'http'), 'http') or contains(translate(., 'MAGNET', 'magnet'), 'magnet') or contains(translate(., 'ED2K', 'ed2k'), 'ed2k'))]`;
var candidates = document.evaluate(xpath, document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
for (var cand = null, i = 0; (cand = candidates.snapshotItem(i)); i++) {
if (urlRegex.test(cand.nodeValue)) {
var span = document.createElement("span"); //为超链接创建span标签作为容器
var source = cand.nodeValue;
//console.log(cand);
cand.parentNode.replaceChild(span, cand);
urlRegex.lastIndex = 0;
for (var match = null, lastLastIndex = 0; (match = urlRegex.exec(source)); )
{
span.appendChild(document.createTextNode(source.substring(lastLastIndex, match.index)));
//console.log(match);
if(/\.(?:gif|jpg|png|bmp|webp)(?:\?.+?)?$/.test(match[0])){//如果是图片链接,则创建有图片地址的连接
span.innerHTML='
';
}
var Mtxt=match[0]; //取得链接
var Rtxt=/paco-\d{6}_\d{3}/i.test(Mtxt) ? Mtxt.replace(/paco-(\d{6}_\d{3})/i,'pacopacomama $1') : Mtxt; //替换链接内容
var a = document.createElement("a");
a.href=Rtxt;
a.className='newhref';
a.target="blank";
a.appendChild(document.createTextNode(decodeURIComponent(Rtxt)));
span.appendChild(a);
lastLastIndex = urlRegex.lastIndex;
}
span.appendChild(document.createTextNode(source.substring(lastLastIndex)));
span.normalize();
}
}
}
function ViewIMG() {
var oA = document.getElementsByTagName('a');
for (var i = 0; i < oA.length; i++) {
var imgElements = oA[i].getElementsByTagName('img');
if (imgElements.length === 0) {
if (/\.(?:jpg|png|gif)$/i.test(oA[i].href)) {
oA[i].innerHTML += '
';
}
}
}
}
function ViewVideo(){
$('a[href*=".mp4"], a[href*=".m3u8"]').each(function(){
$('