// ==UserScript==
// @name Textlink to Hyperlink
// @name:zh-CN 文本链接自动识别为超链接
// @version 0.1.4
// @description Recognize links in text by regular expression, and convert to hyperlinks
// @description:zh-CN 通过正则表达式识别文本中的链接,并转换为超链接
// @author DreamNya
// @match *://*/*
// @grant none
// @run-at document-start
// @license MIT
// @namespace https://greasyfork.org/users/809466
// @downloadURL none
// ==/UserScript==
//文本链接识别正则
const reg = /https?:\/\/[\w\.-]+\.\w+(:\d{1,5})?(\/[#%\w?&.=\-@]+)*/g;
//忽略标签类型
const ignore = ['SCRIPT', 'STYLE', 'A', 'TEXTAREA', 'NOSCRIPT', 'CODE'];
//脚本运行时遍历所有节点
queryElement(document)
//后续通过观察器监视
let obs = new MutationObserver(m => {
m.forEach(mm => {
formatHref(mm.target, mm.addedNodes)
mm.addedNodes.forEach(i => queryElement(i))
})
});
obs.observe(document, { subtree: true, childList: true });
function queryElement(element) {
//用了点语法糖
[...(element.querySelectorAll?.("*") ?? [])].forEach(i => formatHref(i, i.childNodes))
}
function formatHref(target, childNodes) {
//忽略标签
if (ignore.find(n => n == target.nodeName) || target.translate == false) return
let mark = false;
//文本链接构造为a标签
[...childNodes].forEach(c => {
if (c.nodeName == '#text' && c.textContent.match(reg)) {
c.textContent = c.textContent.replace(reg, (m) => { return `${m}` })
mark = true
}
})
//格式化标签
if (mark) {
//console.log(target,target.nodeName, target.translate)
target.innerHTML = target.innerHTML.replace(/<a /g, "").replace(/' target='_blank'>/g, "' target='_blank'>")
}
}