Text To link 修改

Turn plain text URLs into clickable links

  1. // ==UserScript==
  2. // @name Text To link 修改
  3. // @description Turn plain text URLs into clickable links
  4. // @description:zh 把文字链接转换为可点击链接
  5. // @author lkytal
  6. // @namespace Lkytal
  7. // @version 2.8.7
  8. // @homepage https://lkytal.github.io/
  9. // @homepageURL https://lkytal.github.io/GM
  10. // @license AGPL
  11. // include *
  12. // @include *://*.52pojie.cn/*
  13. // @include *://*.csdn.net/*
  14. // @include *://*.kanxue.com/*
  15. // @include *://*.bilibili.com/opus/*
  16. // @include *://wldxh.com/*
  17. // @include *://bbs.binmt.cc/*
  18.  
  19. // @exclude *pan.baidu.com/*
  20. // @exclude *renren.com/*
  21. // @exclude *exhentai.org/*
  22. // @exclude *music.google.com/*
  23. // @exclude *play.google.com/music/*
  24. // @exclude *mail.google.com/*
  25. // @exclude *docs.google.com/*
  26. // @exclude *www.google.*
  27. // @exclude *acid3.acidtests.org/*
  28. // @exclude *.163.com/*
  29. // @exclude *.alipay.com/*
  30. // @run-at document-end
  31. // @icon https://github.com/lkytal/GM/raw/master/icons/link.png
  32. // @grant unsafeWindow
  33. // @charset UTF-8
  34. // @supportURL https://github.com/lkytal/GM/issues
  35. // ==/UserScript==
  36.  
  37. "use strict";
  38. ;
  39. var clearLink, excludedTags, linkFilter, linkMixInit, linkPack, linkify, observePage, observer, setLink, urlPrefixes, url_regexp, xPath;
  40.  
  41. url_regexp = /((https?:\/\/|www\.)[\x21-\x7e]+[\w\/=]|\w([\w._-])+@\w[\w\._-]+\.(com|cn|org|net|info|tv|cc|gov|edu)|(\w[\w._-]+\.(com|cn|org|net|info|tv|cc|gov|edu))(\/[\x21-\x7e]*[\w\/])?|ed2k:\/\/[\x21-\x7e]+\|\/|thunder:\/\/[\x21-\x7e]+=)/gi;
  42.  
  43. urlPrefixes = ['http://', 'https://', 'ftp://', 'thunder://', 'ed2k://', 'mailto://', 'file://'];
  44.  
  45. clearLink = function (event) {
  46. var j, len, link, prefix, ref, ref1, url;
  47. link = (ref = event.originalTarget) != null ? ref : event.target;
  48. if (!(link != null && link.localName === "a" && ((ref1 = link.className) != null ? ref1.indexOf("textToLink") : void 0) !== -1)) {
  49. return;
  50. }
  51. url = link.getAttribute("href");
  52. //console.log url
  53. for (j = 0, len = urlPrefixes.length; j < len; j++) {
  54. prefix = urlPrefixes[j];
  55. if (url.indexOf(prefix) === 0) {
  56. return;
  57. }
  58. }
  59. if (url.indexOf('@') !== -1) {
  60. return link.setAttribute("href", "mailto://" + url);
  61. } else {
  62. return link.setAttribute("href", "http://" + url);
  63. }
  64. };
  65.  
  66. document.addEventListener("mouseover", clearLink);
  67.  
  68. setLink = function (candidate) {
  69. var ref, ref1, ref2, span, text;
  70. if (candidate == null || ((ref = candidate.parentNode) != null ? (ref1 = ref.className) != null ? typeof ref1.indexOf === "function" ? ref1.indexOf("textToLink") : void 0 : void 0 : void 0) !== -1 || candidate.nodeName === "#cdata-section") {
  71. return;
  72. }
  73. text = candidate.textContent.replace(url_regexp, '<a href="$1" target="_blank" class="textToLink">$1</a>');
  74. if (((ref2 = candidate.textContent) != null ? ref2.length : void 0) === text.length) {
  75. return;
  76. }
  77. span = document.createElement("span");
  78. span.innerHTML = text;
  79. return candidate.parentNode.replaceChild(span, candidate);
  80. };
  81.  
  82. excludedTags = "a,svg,canvas,applet,input,button,area,pre,embed,frame,frameset,head,iframe,img,option,map,meta,noscript,object,script,style,textarea,code".split(",");
  83.  
  84. xPath = `//text()[not(ancestor::${excludedTags.join(') and not(ancestor::')})]`;
  85.  
  86. linkPack = function (result, start) {
  87. var i, j, k, ref, ref1, ref2, ref3, startTime;
  88. startTime = Date.now();
  89. while (start + 10000 < result.snapshotLength) {
  90. for (i = j = ref = start, ref1 = start + 10000; ref <= ref1 ? j <= ref1 : j >= ref1; i = ref <= ref1 ? ++j : --j) {
  91. setLink(result.snapshotItem(i));
  92. }
  93. start += 10000;
  94. if (Date.now() - startTime > 2500) {
  95. return;
  96. }
  97. }
  98. for (i = k = ref2 = start, ref3 = result.snapshotLength; ref2 <= ref3 ? k <= ref3 : k >= ref3; i = ref2 <= ref3 ? ++k : --k) {
  99. setLink(result.snapshotItem(i));
  100. }
  101. };
  102.  
  103. linkify = function (node) {
  104. var result;
  105. result = document.evaluate(xPath, node, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
  106. return linkPack(result, 0);
  107. };
  108.  
  109. linkFilter = function (node) {
  110. var j, len, tag;
  111. for (j = 0, len = excludedTags.length; j < len; j++) {
  112. tag = excludedTags[j];
  113. if (tag === node.parentNode.localName.toLowerCase()) {
  114. return NodeFilter.FILTER_REJECT;
  115. }
  116. }
  117. return NodeFilter.FILTER_ACCEPT;
  118. };
  119.  
  120. observePage = function (root) {
  121. var tW;
  122. tW = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, { //+ NodeFilter.SHOW_ELEMENT,
  123. acceptNode: linkFilter
  124. }, false);
  125. while (tW.nextNode()) {
  126. setLink(tW.currentNode);
  127. }
  128. };
  129.  
  130. observer = new window.MutationObserver(function (mutations) {
  131. var Node, j, k, len, len1, mutation, ref;
  132. for (j = 0, len = mutations.length; j < len; j++) {
  133. mutation = mutations[j];
  134. if (mutation.type === "childList") {
  135. ref = mutation.addedNodes;
  136. for (k = 0, len1 = ref.length; k < len1; k++) {
  137. Node = ref[k];
  138. observePage(Node);
  139. }
  140. }
  141. }
  142. });
  143.  
  144. linkMixInit = function () {
  145. if (window !== window.top || window.document.title === "") {
  146. return;
  147. }
  148. //console.time('a')
  149. linkify(document.body);
  150. //console.timeEnd('a')
  151. return observer.observe(document.body, {
  152. childList: true,
  153. subtree: true
  154. });
  155. };
  156.  
  157. setTimeout(linkMixInit, 100);

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址