Google Readerにはてなブックマーク件数を表示する
Google x はてブ(Greasemonkey版)を参考に作ってみた。
// ==UserScript== // @name GR+?B // @namespace http://d.hatena.ne.jp/nozom/ // @description show ?B count in Google Reader // @include http://www.google.com/reader/view/* // ==/UserScript== // original author is id:kusigahama // see http://d.hatena.ne.jp/kusigahama/20051207#p1 (function() { var timerID; var busy = false; var url2count = new Object(); String.prototype.htmlescape = function() { return this.replace(/&/, "&").replace(/</g, "<"); } function setBookmarkCount(targetNode, href, count) { var str = (count > 0 ? "" + count : "no") + " user" + (count > 1 ? "s" : ""); var a = document.createElement("a"); a.setAttribute('href', "http://b.hatena.ne.jp/entry/" + href); a.setAttribute('target', '_blank'); a.appendChild(document.createTextNode(str)); with (a.style) { fontSize = "0.9em"; textDecoration = "none"; if (count >= 5) { fontWeight = "bold"; backgroundColor = "#fff0f0"; color = "#f66"; } if (count >= 10) { backgroundColor = "#ffcccc"; color = "red"; } } with (targetNode) { appendChild(document.createTextNode(" (")); appendChild(a); appendChild(document.createTextNode(") ")); } } function setBookmarkCounts(titleArray) { for (var i = 0; i < titleArray.length; i++) { var href = titleArray[i].href; var title = titleArray[i].node; var count = url2count[href]; if (count != null) { var node = document.createElement('span'); node.className = 'hatena-bookmark-count'; if (count > 0) setBookmarkCount(node, href, count); title.insertBefore(node, title.childNodes[1]); } } } function callXmlrpc(requestbody, titleArray) { const endpoint = "http://b.hatena.ne.jp/xmlrpc"; function onload(response) { if (response.responseText.match(/<fault>/)) { clearInterval(timerID); alert("xmlrpc call failed: " + response.responseText + "\n" + "request: " + requestbody); } else { var pattern = /<name>([^<]+)<\/name>\s*<value><int>(\d+)/g; var m; while (m = pattern.exec(response.responseText)) { url2count[m[1]] = m[2]; } setBookmarkCounts(titleArray); } busy = false; } // alert('xmlrpc call'); GM_xmlhttpRequest({ method: "POST", url: endpoint, data: requestbody, onload: onload }); } function greader_add_bookmark_count() { if (busy) return; var titles = document.evaluate('//h2[@class="entry-title"]', document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); if (! titles.snapshotLength) return; busy = true; var titleArray = new Array(); var reqUrlArray = new Array(); var reqUrlHash = new Object(); for (var i = 0; i < titles.snapshotLength; i++) { var title = titles.snapshotItem(i); var nodes = title.childNodes; if ((nodes == null) || (nodes[1] == null) || (nodes[1].tagName != 'SPAN') || (nodes[1].className != 'hatena-bookmark-count')) { var link = null; if (title.firstChild.tagName == 'A') { // entry-container (Expanded view or Collapsed item) link = title.firstChild; } else { // entry (List view) link = title.parentNode.parentNode.firstChild; if (link.tagName != 'A') link = null; } if (link != null) { titleArray.push({ node: title, href: link.href }); if ((url2count[link.href] == null) && (! reqUrlHash[link.href])) { reqUrlHash[link.href] = true; reqUrlArray.push(link.href); } } } } if (titleArray.length == 0) { busy = false; return; } if (reqUrlArray.length == 0) { // all items are found in the cache setBookmarkCounts(titleArray); busy = false; } else { var request = '<?xml version="1.0"?>\n<methodCall>\n<methodName>bookmark.getCount</methodName>\n<params>\n'; for (var i = 0; i < reqUrlArray.length; i++) { // avoid xmlrpc call failure in 'too many params' error if (i > 20) break; var href = reqUrlArray[i]; request += "<param><value><string>" + href.htmlescape() + "</string></value></param>\n"; } request += "</params>\n</methodCall>\n"; callXmlrpc(request, titleArray); } } // be careful not to be too busy timerID = setInterval(greader_add_bookmark_count, 3000); })();
Google Readerがバージョンアップして使いやすくなったので、これまでメインで使っていたはてなRSSから移行することにした。それで一つ困ったのが、はてなRSSにあったはてなブックマーク件数を表示する機能が使えなくなること。そのためいくつかのフィードについては移行できないでいたのだが、これで完全に移行できる。
ちなみに、Google Readerの使い方を色々試してみて、今はShow all + List View + Sort by newestに落ち着いた。j,kで読み進めていって、気になったエントリはvで元ページを表示するといった感じ。これが一番Gmailっぽい使い方ができる。