// lineBreak.js/** * @file * UAで長い半角英数記号文字列が自動途中改行されるように変更する. * '.','/','\'の直後、'&','%','-'の直前、更には特定文字数毎に&shy;文字(0xAD)を * 挿入する. * 但し、&shy;非対応なGeckoの場合は<wbr>を挿入する. * * @par 使用法 * 適用する(X)HTML文章のbody要素を閉じる直前にscript要素で参照する. * * @par このスクリプトについて * このスクリプトは、 * bookmarklet: Wrap! ― 長い1byte文字列を折り返す（Mozilla） - airhead の日記 * (http://slashdot.jp/journal.pl?op=display&uid=13423&id=270308) * の複行リストに手を加えたものである。 * * @par 参考 * +bookmarklet: Wrap! ― 長い1byte文字列を折り返す（Mozilla） - airhead の日記 *  http://slashdot.jp/journal.pl?op=display&uid=13423&id=270308 * +url_breaker - あすかぜ・ねっと *  http://www.asukaze.net/soft/url_breaker/ * +shyなやつ - 徒書 *  http://www.akatsukinishisu.net/itazuragaki/id/soft_hyphen * +長い文字列の改行方法 - wbr, &shy;, css - World Wide Walker *  http://yoosee.net/d/archives/2005/01/04/002.html * * @warning * Geckoの場合に非標準要素である<wbr>を入れているので、その場合のみ * 処理後の(X)HTML文章はinvalidなものになる. * 又、Internet Explorer(ver6.0以下)はNodeFilter.SHOW_TEXTに対応していない為、 * 動作しない(エラーとなる). */(function () {    // 処理を行う文字列の条件.    var threshold = new RegExp(/[\x21-\xff]{50}/);    // 改行許可する条件($1=改行許可直前の文字, $2=改行許可直後の文字)    var wrapChr = new RegExp(/([\.\/\?])|([&%\-])/g);    // 処理を行わないHTML要素.    var avoidElm        = new RegExp(/SCRIPT|INPUT|TEXTAREA|OPTION|PRE|XMP|PLAINTEXT/);    // 必ず改行許可を与える文字数.    var lineMin = 16;    var walker = document.createTreeWalker(        document.body, NodeFilter.SHOW_TEXT, null, true);    while (cNode = walker.nextNode()) {        s1 = cNode.nodeValue;        pNode = cNode.parentNode;        pNodeName = pNode.nodeName;        if (!pNodeName.match(avoidElm) && s1.match(threshold)) {            s1 = s1.replace(wrapChr, '$1<dummyWBR>$2');            s2 = s1.split('<dummyWBR>');            // 長い文字列は分割            for(var i = 0; i < s2.length; i++) {                var s2Sub;                if(s2[i].length > lineMin) {                    var s2Current = s2[i];                    var s2Tail = s2.slice(i + 1);   // 最後NULLになる?                    s2 = s2.slice(0, i);                    var partsNum = parseInt(s2Current.length / lineMin)                        + ((s2Current.length % lineMin) != 0);                    s2Sub = new Array(partsNum);                    for(var j = 0; j < partsNum; j++) {                        s2Sub[j] = s2Current.substr(lineMin * j, lineMin);                    }                    s2 = s2.concat(s2Sub);                    s2 = s2.concat(s2Tail);                    i += (s2Sub.length - 1);    // forカウンタ分マイナス                }            }            cNode.nodeValue = s2.pop();            for (i=0; i<s2.length; i++) {                nNode = document.createTextNode(s2[i]);                pNode.insertBefore(nNode, cNode);                // UA別に処理を振り分け                if(navigator.userAgent.indexOf("Gecko") == -1) {                    nNode = document.createTextNode("\xad");    // &shy;                } else {                    nNode = document.createElement('WBR');                }                pNode.insertBefore(nNode, cNode);            }        }    }    // ページ再計算をさせる為にwidthを定義しなおす.    var width = document.body.style.width;    if(!width) width = '99%';   // 100%だと横に長くなるので    document.body.style.width = width;    focus();})();