Text To link

把文字链接转换为可点击链接, Make text links clickable

当前为 2015-02-08 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Text To link
  3. // @description 把文字链接转换为可点击链接, Make text links clickable
  4. // @author lkytal
  5. // @namespace Lkytal
  6. // @homepage http://lkytal.github.io/
  7. // @include *
  8. // @exclude *pan.baidu.com/*
  9. // @exclude *renren.com/*
  10. // @exclude *exhentai.org/*
  11. // @version 2.6.1
  12. // @icon http://lkytal.qiniudn.com/ic.ico
  13. // @grant unsafeWindow
  14. // @homepageURL https://git.oschina.net/coldfire/GM
  15. // ==/UserScript==
  16.  
  17. "use strict";
  18. var excludedTags, filter, linkMixInit, linkPack, linkify, observePage, observer, setHttp, setLink, url_regexp, xpath;
  19.  
  20. url_regexp = /((https?:\/\/|www\.)[\x21-\x7e]+\w|(\w[\w._-]+\.(com|cn|org|net|info|tv|cc))(\/[\x21-\x7e]*\w)?|ed2k:\/\/[\x21-\x7e]+\|\/|thunder:\/\/[\x21-\x7e]+=)/gi;
  21.  
  22. setHttp = function(event) {
  23. var url;
  24. url = event.target.getAttribute("href");
  25. if (url.indexOf("http") !== 0 && url.indexOf("ed2k://") !== 0 && url.indexOf("thunder://") !== 0) {
  26. return event.target.setAttribute("href", "http://" + url);
  27. }
  28. };
  29.  
  30. if (typeof exportFunction !== "undefined" && exportFunction !== null) {
  31. exportFunction(setHttp, unsafeWindow, {
  32. defineAs: "setHttp"
  33. });
  34. } else {
  35. unsafeWindow.setHttp = setHttp;
  36. }
  37.  
  38. setLink = function(candidate) {
  39. var span, text;
  40. if ((candidate == null) || candidate.nodeName === "#cdata-section") {
  41. return;
  42. }
  43. text = candidate.textContent.replace(url_regexp, '<a href="$1" target="_blank" onmouseover="setHttp(event);">$1</a>');
  44. if (candidate.textContent.length === text.length) {
  45. return;
  46. }
  47. span = document.createElement("span");
  48. span.innerHTML = text;
  49. return candidate.parentNode.replaceChild(span, candidate);
  50. };
  51.  
  52. excludedTags = "a,svg,canvas,applet,input,button,area,pre,embed,frame,frameset,head,iframe,img,map,meta,noscript,object,option,param,script,select,style,textarea,code".split(",");
  53.  
  54. xpath = "//text()[not(ancestor::" + (excludedTags.join(') and not(ancestor::')) + ")]";
  55.  
  56. filter = new RegExp("^(" + (excludedTags.join('|')) + ")$", "i");
  57.  
  58. linkPack = function(result, start) {
  59. var i, _i, _j, _ref, _ref1;
  60. if (start + 10000 < result.snapshotLength) {
  61. for (i = _i = start, _ref = start + 10000; start <= _ref ? _i <= _ref : _i >= _ref; i = start <= _ref ? ++_i : --_i) {
  62. setLink(result.snapshotItem(i));
  63. }
  64. setTimeout(function() {
  65. return linkPack(result, start + 10000);
  66. }, 20);
  67. } else {
  68. for (i = _j = start, _ref1 = result.snapshotLength; start <= _ref1 ? _j <= _ref1 : _j >= _ref1; i = start <= _ref1 ? ++_j : --_j) {
  69. setLink(result.snapshotItem(i));
  70. }
  71. }
  72. };
  73.  
  74. linkify = function(doc) {
  75. var result;
  76. result = document.evaluate(xpath, doc, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
  77. return linkPack(result, 0);
  78. };
  79.  
  80. observePage = function(root) {
  81. var tW;
  82. tW = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {
  83. acceptNode: function(a) {
  84. if (!filter.test(a.parentNode.localName)) {
  85. return NodeFilter.FILTER_ACCEPT;
  86. }
  87. }
  88. }, false);
  89. while (tW.nextNode()) {
  90. setLink(tW.currentNode);
  91. }
  92. };
  93.  
  94. observer = new window.MutationObserver(function(mutations) {
  95. var Node, mutation, _i, _j, _len, _len1, _ref;
  96. for (_i = 0, _len = mutations.length; _i < _len; _i++) {
  97. mutation = mutations[_i];
  98. if (mutation.type === "childList") {
  99. _ref = mutation.addedNodes;
  100. for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
  101. Node = _ref[_j];
  102. observePage(Node);
  103. }
  104. }
  105. }
  106. });
  107.  
  108. linkMixInit = function() {
  109. if (window !== window.top || window.document.title === "") {
  110. return;
  111. }
  112. linkify(document.body);
  113. return observer.observe(document.body, {
  114. childList: true,
  115. subtree: true
  116. });
  117. };
  118.  
  119. setTimeout(linkMixInit, 100);