はてブにダイアリーのリンク付けるグリモンの添削
はてブユーザのストーキングを加速させるgreasemonkey(はてブしてるひとのダイアリーへのリンクを付加する) - Cherenkovの暗中模索にっきを勝手に添削する。
まず、気をつけたほうがいいもの。
// ==UserScript== // @name hateb_link_user_diary // @namespace http://d.hatena.ne.jp/Cherenkov/ // @include http://b.hatena.ne.jp/entry/* // ==/UserScript== (function(){ // 最近のグリモンは無名関数で囲う必要がない(Operaのuser.jsとかは必要) var h = document.evaluate('//a[@class="hatena-id-icon"]', document, null, 7, null); for(i=0;i<h.snapshotLength;i++){ // iがグローバルになってる var diary = document.createElement('a'); diary.href = h.snapshotItem(i).href.replace(/b.hatena.ne.jp/,'d.hatena.ne.jp'); //正規表現をエスケープしてない var img = document.createElement('img'); img.src = 'http://d.hatena.ne.jp/images/de_favicon.ico'; diary.appendChild(img); h.snapshotItem(i).parentNode.insertBefore(diary,h.snapshotItem(i).parentNode.childNodes[3]); // snapshotItemを何度も呼んでる } })();
このへんを踏まえて修正する。空白とかは勝手に入れた。
// ==UserScript== // @name hateb_link_user_diary // @namespace http://d.hatena.ne.jp/Cherenkov/ // @include http://b.hatena.ne.jp/entry/* // ==/UserScript== var h = document.evaluate('//a[@class="hatena-id-icon"]', document, null, 7, null); for (var i = 0;i < h.snapshotLength;i++) { var icon = h.snapshotItem(i); var diary = document.createElement('a'); diary.href = icon.href.replace("b.hatena.ne.jp", "d.hatena.ne.jp"); var img = document.createElement('img'); img.src = 'http://d.hatena.ne.jp/images/de_favicon.ico'; diary.appendChild(img); icon.parentNode.insertBefore(diary, icon.parentNode.childNodes[3]); }
/b.hatena.ne.jp/だとbxhatenaxnexjpとかにもマッチしてしまうので、/b\.hatena\.ne\.jp/か、必要がなければ文字列にするべき。
で、細かいこと。
まず、document.evaluateの引数の7は、対応する定数がある(Introduction to using XPath in JavaScript - MDN)ので、それを使うといいかもしれない。7の代わりにXPathResult.ORDERED_NODE_SNAPSHOT_TYPE。
XPathとclass属性は相性が悪い(特定のclass属性を持った任意の要素にマッチするXPath | 3.14)ので、ターゲットがFirefox3ならdocument.getElementsByClassNameを使うのも手。
ループ内でdocument.createElementとappendChildを使って毎回似た構造のものを作るのは速度的に不利なので、ループの外側でテンプレートを作って、cloneNodeするといい。
あと、childNodes[3]だと、サイト構造の変化に弱いので、iconの位置に対する相対的な指定にするといい。
これを踏まえて書き直すと、下のような感じになる。
// ==UserScript== // @name hateb_link_user_diary // @namespace http://d.hatena.ne.jp/Cherenkov/ // @include http://b.hatena.ne.jp/entry/* // ==/UserScript== var icons = document.getElementsByClassName('hatena-id-icon'), link = document.createElement('a'), img = document.createElement('img'); img.src = 'http://d.hatena.ne.jp/images/de_favicon.ico'; link.appendChild(img); for (var i = 0, len = icons.length;i < len;++i) { var icon = icons[i]; if (!/a/i.test(icon.nodeName)) continue; // skip <img class="hatena-id-icon"> var elem = link.cloneNode(true); elem.href = icon.href.replace('b', 'd'); icon.parentNode.insertBefore(elem, icon.nextSibling); }
以上。おせっかいだったらごめんなさい。