はてダのブログモードでコメントを常に表示するGreasemonkey

まるごとJSに載っていたcho45さん作のSeemore seemoreがかなり便利で常用してるんだけど、ブログモードのコメントも常に表示されればいいのに!と思ったのでXPathの仕様を見ながら$X関数を使いまくって書いてみた。

// ==UserScript==
// @name           Hatena::Diary blog mode comment extender
// @namespace      http://shinten.info/
// @author         watta
// @include        http://d.hatena.ne.jp/*
// ==/UserScript==

(function() {
    var base = 'http://d.hatena.ne.jp';

    if ($X('count(//form[@class="comment"]) > 0')) return;

    $X('//p[@class="sectionfooter"]').forEach(function (sf) {
        var href = $X('string(./a[2][contains(@href, "#c")][not(contains(., "(0)"))]/@href)', sf);
        if (href) {
            var url = base + href;
            GM_xmlhttpRequest({
                method: 'GET',
                url: url,
                onload: function (req) {
                    var d = document.createElement('div');
                    d.innerHTML = req.responseText;
                    $X('.//div[@class="commentshort"]/p[position() < last()]', d).forEach(function (p) {
                        p.style.textAlign = 'left';
                        sf.appendChild(p);
                    });
                },
                onerror: function (req) {
                    l([req.status, ' ', req.statusText].join(''));
                }
            });
        }
    });

    function l(s) {
        return unsafeWindow.console ? unsafeWindow.console.log(s) : GM_log(s);
    }

    // Thanks to cho45 san
    function $X(exp, context) {
        if (!context) context = document;
        var resolver = function (prefix) {
            var o = document.createNSResolver(context)(prefix);
            return o ? o : (document.contentType == "text/html") ? "" : "http://www.w3.org/1999/xhtml";
        }
        var exp = document.createExpression(exp, resolver);
        var result = exp.evaluate(context, XPathResult.ANY_TYPE, null);
        switch (result.resultType) {
            case XPathResult.STRING_TYPE : return result.stringValue;
            case XPathResult.NUMBER_TYPE : return result.numberValue;
            case XPathResult.BOOLEAN_TYPE: return result.booleanValue;
            case XPathResult.UNORDERED_NODE_ITERATOR_TYPE: {
                result = exp.evaluate(context,
                                      XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
                var ret = [];
                for (var i = 0, len = result.snapshotLength; i < len ; i++) {
                    ret.push(result.snapshotItem(i));
                }
                return ret;
            }
        }
        return null;
    }
})();

まるごとJavaScript & Ajax ! Vol.1

まるごとJavaScript & Ajax ! Vol.1