リンク化

    @@ -7,58 +7,55 @@ // 【直近の変更】 -// ・URL生成ロジックにバグがあったので修正 -// ・正規表現パターンをさらに変更 +// ・NodeIteratorを使ってコード内の探査を簡略化 (function(){ - // Rangeが使えなければ意味が無いので、ここで一旦判定をしています。 - if (!document.createRange) - return window.alert("このスクリプトを実行するために必要なAPIが使用できません。"); - - var range = document.createRange(); - - (function(currentNode){ - var childs = currentNode.childNodes; + // NodeIteratorとRangeを使う必要があるので、ここで一旦判定をしています。 + if (!document.createNodeIterator || !document.createRange) + return window.alert("このスクリプトを実行するために必要なAPIが使用できません。"); + + var filter = function(node) { + var isAnchor = node.parentNode && node.parentNode.nodeName.toLowerCase() === "a"; + return isAnchor ? NodeFilter.FILTER_SKIP : NodeFilter.FILTER_ACCEPT; + }; + var iter = document.createNodeIterator(document.body, NodeFilter.SHOW_TEXT, filter, false); + var current; + var range = document.createRange(); var pattern = /(h?t?tps?:\/\/(?:[\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 regRes = []; - for (var i = 0, l = childs.length; i < l; i++) { - var self = childs[i]; - if (self.childNodes && self.childNodes.length) { // 子ノードがいる場合は再帰 - arguments.callee(self); - } + while (current = iter.nextNode()) { + var regRes, matchStack = []; - if (self.nodeType !== 3) continue; // テキストノードでなければ次へ - - var matchStack = []; - - while (regRes = pattern.exec(self.textContent)) { // マッチがなくなるまでループしてスタック - matchStack.push({ - "mUrl" : "http://" + getPathname(regRes[0]), - "pStart" : regRes.index, - "pEnd" : pattern.lastIndex - }); - } - while (matchStack.length >= 1) { // 後ろから1つずつ取り出して変更を適用 - var item = matchStack.pop(); - var a = document.createElement("a"); - a.href = item.mUrl; - a.target = "_blank"; - range.setStart(self, item.pStart); - range.setEnd(self, item.pEnd); - range.surroundContents(a); - } + while (regRes = pattern.exec(current.data)) { // マッチがなくなるまでループしてスタック + matchStack.push({ + "mUrl" : "http://" + getPathname(regRes[0]), + "pStart" : regRes.index, + "pEnd" : pattern.lastIndex + }); + } + while (matchStack.length >= 1) { // 後ろから1つずつ取り出して変更を適用 + var item = matchStack.pop(); + var a = createAnchor(item.mUrl); + + range.setStart (current, item.pStart); + range.setEnd (current, item.pEnd ); + range.surroundContents(a); + } } - })(document.body); - - range.detach(); + range.detach(); - function getPathname(url){ - var pattern = /:\/\//g; - if (pattern.exec(url)) { - return url.slice(pattern.lastIndex); + function getPathname(url){ + var pattern = /:\/\//g; + if (pattern.exec(url)) { + return url.slice(pattern.lastIndex); + } + return url; + } + function createAnchor(url) { + var a = document.createElement("a"); + a.href = url; + a.target = "_blank"; + return a; } - return url; - } })();
  • /*
     * @title リンク化
     * @description httpやttpやtpなリンクのないURLにリンクを付ける(どこにでもあるやつだけど、標準技術のみで実装している自己満足ver)
     * @include http://*
     * @license MIT License
     */
    
    
    // 【直近の変更】
    // ・NodeIteratorを使ってコード内の探査を簡略化
    
    
    (function(){
        // NodeIteratorとRangeを使う必要があるので、ここで一旦判定をしています。
        if (!document.createNodeIterator || !document.createRange)
            return window.alert("このスクリプトを実行するために必要なAPIが使用できません。");
        
        var filter = function(node) {
            var isAnchor = node.parentNode && node.parentNode.nodeName.toLowerCase() === "a";
            return isAnchor ? NodeFilter.FILTER_SKIP : NodeFilter.FILTER_ACCEPT;
        };
        var iter  = document.createNodeIterator(document.body, NodeFilter.SHOW_TEXT, filter, false);
        var current;
        var range = document.createRange();
        var pattern = /(h?t?tps?:\/\/(?:[\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;
        
        while (current = iter.nextNode()) {
            var regRes, matchStack = [];
    
            while (regRes = pattern.exec(current.data)) { // マッチがなくなるまでループしてスタック
                matchStack.push({
                    "mUrl"   : "http://" + getPathname(regRes[0]),
                    "pStart" : regRes.index,
                    "pEnd"   : pattern.lastIndex
                });
            }
            while (matchStack.length >= 1) { // 後ろから1つずつ取り出して変更を適用
                var item = matchStack.pop();
                var a = createAnchor(item.mUrl);
                
                range.setStart (current, item.pStart);
                range.setEnd   (current, item.pEnd  );
                range.surroundContents(a);
            }
        }
        range.detach();
        
        function getPathname(url){
            var pattern = /:\/\//g;
            if (pattern.exec(url)) {
                return url.slice(pattern.lastIndex);
            }
            return url;
        }
        function createAnchor(url) {
            var a = document.createElement("a");
            a.href   = url;
            a.target = "_blank";
            return a;
        }
    })();
  • Permalink
    このページへの個別リンクです。
    RAW
    書かれたコードへの直接のリンクです。
    Packed
    文字列が圧縮された書かれたコードへのリンクです。
    Userscript
    Greasemonkey 等で利用する場合の .user.js へのリンクです。
    Loader
    @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
    Metadata
    コード中にコメントで @xxx と書かれたメタデータの JSON です。

History

  1. 2016/10/09 02:11:46 - 2016-10-09
  2. 2016/10/09 00:21:01 - 2016-10-09
  3. 2016/10/09 00:20:24 - 2016-10-09
  4. 2016/10/06 20:50:44 - 2016-10-06
  5. 2016/10/06 20:49:13 - 2016-10-06
  6. 2016/03/12 13:34:43 - 2016-03-12
  7. 2016/03/12 13:31:01 - 2016-03-12
  8. 2013/12/17 21:48:36 - 2013-12-17
  9. 2013/12/17 21:41:23 - 2013-12-17
  10. 2013/12/17 21:40:51 - 2013-12-17
  11. 2013/12/15 04:41:41 - 2013-12-15
  12. 2013/12/15 04:39:19 - 2013-12-15
  13. 2013/07/26 22:12:08 - 2013-07-26
  14. 2013/04/23 02:20:03 - 2013-04-23
  15. 2013/04/22 10:19:35 - 2013-04-22
  16. 2013/04/22 10:18:02 - 2013-04-22
  17. 2013/04/22 10:15:27 - 2013-04-22