2008-12-26

[]Hatena::Bookmark::24H::Chart

修正:いい加減&が変換されるのを何とかしてほしい

解説:Hatena::Bookmark::24H(http://hatebu24h.ashitano.in/)に、トップエントリの獲得したブックマーク数の推移のチャートを加えます。

// ==UserScript==
// @name           chart of Hatena::Bookmark::24H
// @namespace      http://anond.hatelabo.jp/
// @include        http://hatebu24h.ashitano.in/*
// ==/UserScript==

var url = unescape("http://chart.apis.google.com/chart?chs=160x60%26cht=ls%26chd=t:");
url = url + $X("//div[@class='clocktxt']", Array).map(function(s){return s.firstChild.nodeValue}).join(",");
//var id = $X("//h3/a/@href")[0].nodeValue;
//url = url + $X("//div[@class='entrytitle' or @class='entrytitle2'][.//a[@href='"+id+"']]/../preceding-sibling::div[1]", Array).map(function(s){return s.textContent.match(/\d+/)}).join(",");
var before = makeElements({
    nodeName: "div",
    className: "sidebox",
    childNodes: [{
        nodeName: "div",
        className: "sidetitle",
        innerHTML: "Recent top entry chart"
      },{
        nodeName: "div",
        className: "sidetitle",
        childNodes: {
            nodeName: "img",
            src: url
        }
    }]
});
var after = $X("//div[@class='sidebox']", Array)[0];
after.parentNode.insertBefore(before, after);

// util

// var 0.01
function makeElements(obj) {
    if (typeof obj != "object")
        return document.createTextNode(obj);
    if (obj instanceof Array)
        return obj.map(makeElements);
    var node = document.createElement(obj.nodeName);
    delete obj.nodeName;
    if (obj.childNodes) {
        [].concat(makeElements(obj.childNodes)).forEach(node.appendChild, node);
        delete obj.childNodes;
    }
    function extend(dst, src) {
        for (var i in src) {
            if (typeof src[i] == "object" && dst[i] && typeof dst[i] == "object")
                extend(dst[i], src[i]);
            else
                node[i]=obj[i];
        }
    }
    extend(node, obj);
    return node;
}

// by http://lowreal.net/blog/2007/11/17/1
// $X(exp);
// $X(exp, context);
// $X(exp, type);
// $X(exp, context, type);
function $X (exp, context, type /* want type */) {
    if (typeof context == "function") {
        type    = context;
        context = null;
    }
    if (!context) context = document;
    var exp = (context.ownerDocument || context).createExpression(exp, function (prefix) {
        var o = document.createNSResolver(context).lookupNamespaceURI(prefix);
        if (o) return o;
        return (document.contentType == "application/xhtml+xml") ? "http://www.w3.org/1999/xhtml" : "";
    });

    switch (type) {
        case String:
            return exp.evaluate(
                context,
                XPathResult.STRING_TYPE,
                null
            ).stringValue;
        case Number:
            return exp.evaluate(
                context,
                XPathResult.NUMBER_TYPE,
                null
            ).numberValue;
        case Boolean:
            return exp.evaluate(
                context,
                XPathResult.BOOLEAN_TYPE,
                null
            ).booleanValue;
        case Array:
            var 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;
        case undefined:
            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: {
                    // not ensure the order.
                    var ret = [];
                    var i = null;
                    while (i = result.iterateNext()) {
                        ret.push(i);
                    }
                    return ret;
                }
            }
            return null;
        default:
            throw(TypeError("$X: specified type is not valid type."));
    }
}

記事への反応(ブックマークコメント)

ログイン ユーザー登録
ようこそ ゲスト さん