リンク化
by
htsign
2016-10-09 [2016/10/09 02:11:46]
httpやttpやtpなリンクのないURLにリンクを付ける(どこにでもあるやつだけど、標準技術のみで実装している自己満足ver)
@@ -6,50 +6,73 @@
*/
-// 【直近の変更】
+// 【最近の変更】
// ・正規表現を更に少し変更
// ・httpsのURLに対応
// ・scriptタグの中身は変更しないようにした(誤爆しやすいみたいなので)
+// ・構造を大幅に変更
-
-(function(){
- var filter = function(node) {
- var isAnchorOrScript = node.parentNode && ["A", "SCRIPT"].indexOf(node.parentNode.nodeName) !== -1;
- return isAnchorOrScript ? NodeFilter.FILTER_SKIP : NodeFilter.FILTER_ACCEPT;
- };
- var iter = document.createNodeIterator(document.body, NodeFilter.SHOW_TEXT, filter, false), current;
- var range = document.createRange();
- var pattern = /(?:h?t?tp(s?):\/\/(?:[\w-]+|[^ -~。-゚]+)\.[a-zA-Z]{2,4}[^\s "']*)|(?:[^/\s"'((「【『]*?(?:[\w-]+|[^ -~。-゚]+)\.(?:com|org|net|edu|gov|jp|to|tv|fm|info|(?:co|or|ne|ac|go)\.(?:jp|uk|fr|de))[^\s "'))」】』]*)/g;
+(function() {
- while (current = iter.nextNode()) {
- var regRes, matchStack = [];
-
- while (regRes = pattern.exec(current.data)) { // マッチがなくなるまでループしてスタック
- matchStack.push({
- mUrl : "http" + (regRes[1] || "") + "://" + getPathname(regRes[0]),
- pStart : regRes.index,
- pEnd : pattern.lastIndex,
- });
+ var ElementFactory = (function() {
+ function ElementFactory(tagName, attrs) {
+ this.template = document.createElement(tagName);
+ for (var i = 0; i < attrs.length; ++i) {
+ var attr = attrs[i].attr, value = attrs[i].value;
+ this.template[attr] = value;
+ }
}
- while (matchStack.length > 0) { // 後ろから1つずつ取り出して変更を適用
- var item = matchStack.pop();
- var a = createAnchor(item.mUrl);
+ ElementFactory.prototype.create = function(attrs) {
+ var elem = this.template.cloneNode(true);
+ for (var i = 0; i < attrs.length; ++i) {
+ var attr = attrs[i].attr, value = attrs[i].value;
+ elem[attr] = value;
+ }
+ return elem;
+ };
+ return ElementFactory;
+ })();
+
+
+ var pattern = /(?:h?t?tp(s?):\/\/(?:[\w-]+|[^ -~。-゚]+)\.[a-zA-Z]{2,4}[^\s "']*)|(?:[^/\s"'((「【『]*?(?:[\w-]+|[^ -~。-゚]+)\.(?:com|org|net|edu|gov|jp|to|tv|fm|info|(?:co|or|ne|ac|go)\.(?:jp|uk|fr|de))[^\s "'))」】』]*)/g;
+ var anchorFactory = new ElementFactory("a", [{ attr: "target", value: "_blank" }]);
+
+ convertTextToLink(document.body);
+
+
+ function convertTextToLink(rootNode) {
+ var filter = function(node) {
+ var isAnchorOrScript = node.parentNode && ["A", "SCRIPT"].indexOf(node.parentNode.nodeName) !== -1;
+ return isAnchorOrScript ? NodeFilter.FILTER_SKIP : NodeFilter.FILTER_ACCEPT;
+ };
+ var iter = document.createNodeIterator(rootNode, NodeFilter.SHOW_TEXT, filter, false);
+ var range = document.createRange();
+
+ var current;
+ while (current = iter.nextNode()) {
+ var getPathname = function(url) {
+ var pattern2 = /:\/\//g;
+ return pattern2.exec(url) ? url.slice(pattern2.lastIndex) : url;
+ };
+ var regRes, matchStack = [];
- range.setStart (current, item.pStart);
- range.setEnd (current, item.pEnd );
- range.surroundContents(a);
+ while (regRes = pattern.exec(current.data)) { // マッチがなくなるまでループしてスタック
+ matchStack.push({
+ mUrl : "http" + (regRes[1] || "") + "://" + getPathname(regRes[0]),
+ pStart : regRes.index,
+ pEnd : pattern.lastIndex,
+ });
+ }
+ while (matchStack.length > 0) { // 後ろから1つずつ取り出して変更を適用
+ var item = matchStack.pop();
+ var a = anchorFactory.create([{ attr: "href", value: item.mUrl }]);
+
+ range.setStart (current, item.pStart);
+ range.setEnd (current, item.pEnd );
+ range.surroundContents(a);
+ }
}
+ range.detach();
}
- range.detach();
- function getPathname(url) {
- var pattern = /:\/\//g;
- return pattern.exec(url) ? url.slice(pattern.lastIndex) : url;
- }
- function createAnchor(url) {
- var a = document.createElement("a");
- a.href = url;
- a.target = "_blank";
- return a;
- }
-})();
+})();
/*
* @title リンク化
* @description httpやttpやtpなリンクのないURLにリンクを付ける(どこにでもあるやつだけど、標準技術のみで実装している自己満足ver)
* @include http://*
* @license MIT License
*/
// 【最近の変更】
// ・正規表現を更に少し変更
// ・httpsのURLに対応
// ・scriptタグの中身は変更しないようにした(誤爆しやすいみたいなので)
// ・構造を大幅に変更
(function() {
var ElementFactory = (function() {
function ElementFactory(tagName, attrs) {
this.template = document.createElement(tagName);
for (var i = 0; i < attrs.length; ++i) {
var attr = attrs[i].attr, value = attrs[i].value;
this.template[attr] = value;
}
}
ElementFactory.prototype.create = function(attrs) {
var elem = this.template.cloneNode(true);
for (var i = 0; i < attrs.length; ++i) {
var attr = attrs[i].attr, value = attrs[i].value;
elem[attr] = value;
}
return elem;
};
return ElementFactory;
})();
var pattern = /(?:h?t?tp(s?):\/\/(?:[\w-]+|[^ -~。-゚]+)\.[a-zA-Z]{2,4}[^\s "']*)|(?:[^/\s"'((「【『]*?(?:[\w-]+|[^ -~。-゚]+)\.(?:com|org|net|edu|gov|jp|to|tv|fm|info|(?:co|or|ne|ac|go)\.(?:jp|uk|fr|de))[^\s "'))」】』]*)/g;
var anchorFactory = new ElementFactory("a", [{ attr: "target", value: "_blank" }]);
convertTextToLink(document.body);
function convertTextToLink(rootNode) {
var filter = function(node) {
var isAnchorOrScript = node.parentNode && ["A", "SCRIPT"].indexOf(node.parentNode.nodeName) !== -1;
return isAnchorOrScript ? NodeFilter.FILTER_SKIP : NodeFilter.FILTER_ACCEPT;
};
var iter = document.createNodeIterator(rootNode, NodeFilter.SHOW_TEXT, filter, false);
var range = document.createRange();
var current;
while (current = iter.nextNode()) {
var getPathname = function(url) {
var pattern2 = /:\/\//g;
return pattern2.exec(url) ? url.slice(pattern2.lastIndex) : url;
};
var regRes, matchStack = [];
while (regRes = pattern.exec(current.data)) { // マッチがなくなるまでループしてスタック
matchStack.push({
mUrl : "http" + (regRes[1] || "") + "://" + getPathname(regRes[0]),
pStart : regRes.index,
pEnd : pattern.lastIndex,
});
}
while (matchStack.length > 0) { // 後ろから1つずつ取り出して変更を適用
var item = matchStack.pop();
var a = anchorFactory.create([{ attr: "href", value: item.mUrl }]);
range.setStart (current, item.pStart);
range.setEnd (current, item.pEnd );
range.surroundContents(a);
}
}
range.detach();
}
})();
- Permalink
- このページへの個別リンクです。
- RAW
- 書かれたコードへの直接のリンクです。
- Packed
- 文字列が圧縮された書かれたコードへのリンクです。
- Userscript
- Greasemonkey 等で利用する場合の .user.js へのリンクです。
- Loader
- @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
- Metadata
- コード中にコメントで @xxx と書かれたメタデータの JSON です。