// ==UserScript== // @name Text To link // @description 把文字链接转换为可点击链接 // @namespace Lkytal // @include * // @exclude *pan.baidu.com/* // @exclude *.renren.com/* // @exclude *userscripts.org/scripts/review/* // @version 2.3.9 // @icon http://lkytal.qiniudn.com/ic.ico // @grant unsafeWindow // @downloadURL none // ==/UserScript== if (window != window.top || window.document.title == "") return; var LinkPage, excludedTags, filter, linkify, observer, setLink, url_regexp, xpath; url_regexp = new RegExp("((https?://|www\\.|magnet\\:\\?)[\x21-\x7e]+|(\\w[\\x21-\\x2e\\x30-\\x7e]+\\.(com|cn|org|net|info|tv)))(/[\\x21-\\x7e]*)?", "gi"); setLink = function(candidate) { var a, lastLastIndex, match, span, text, url; if ((candidate == null) || candidate.nodeName === "#cdata-section") { return; } text = candidate.textContent; lastLastIndex = 0; match = url_regexp.exec(text); if (match) { span = document.createElement("span"); while (match) { span.appendChild(document.createTextNode(text.substring(lastLastIndex, match.index))); url = match[0]; if (url.indexOf("http") !== 0 && url.indexOf("magnet") !== 0) { url = "http://" + url; } a = document.createElement("a"); a.setAttribute("href", url); a.setAttribute("target", "_blank"); a.appendChild(document.createTextNode(match[0])); span.appendChild(a); lastLastIndex = url_regexp.lastIndex; match = url_regexp.exec(text); } span.appendChild(document.createTextNode(text.substring(lastLastIndex))); return candidate.parentNode.replaceChild(span, candidate); } }; excludedTags = "a,applet,input,button,area,embed,frame,frameset,head,iframe,img,map,meta,noscript,object,option,param,script,select,style,textarea,code".split(","); xpath = "//text()[not(ancestor::" + excludedTags.join(') and not(ancestor::') + ")]"; filter = new RegExp("^(textarea|input|button|select|option|meta|link|noscript|a|html|head|object|embed|script|style|frameset|frame|iframe|img|code)$", "i"); linkify = function(doc) { var i, result, _i, _ref; result = document.evaluate(xpath, doc, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); for (i = _i = 0, _ref = result.snapshotLength; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) { setLink(result.snapshotItem(i)); } }; LinkPage = function(root) { var tW; tW = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, { acceptNode: function(a) { if (!filter.test(a.parentNode.localName)) { return NodeFilter.FILTER_ACCEPT; } } }, false); while (tW.nextNode()) { setLink(tW.currentNode); } }; window._bodyHeight = document.body.clientHeight; observer = new window.MutationObserver(function(mutations) { if (document.body.clientHeight < window._bodyHeight) { return; } window._bodyHeight = document.body.clientHeight; return mutations.forEach(function(mutation) { var Node, _i, _len, _ref; _ref = mutation.addedNodes; for (_i = 0, _len = _ref.length; _i < _len; _i++) { Node = _ref[_i]; LinkPage(Node); } }); }); observer.observe(document.body, { childList: true, subtree: true }); setTimeout((function() { return linkify(document.body); }), 200);