twitterの画面に被はてブ数を表示するグリモン
twitterの画面に被はてブ数を表示するグリモン(greasemonkey)を書いてみた。
とか、
とかを表示すると、
各エントリーの最後に(12users)みたいに、そのエントリーをブクマしてる人数がわかる。
2番煎じかもしれないけど、グリモン初心者なので、
車輪の再実装。
autopagerize 対応どうやるんだろう。対応した。
// ==UserScript== // @name twitterHatebuCount // @namespace twitterHatebuCount // @include http://twitter.com/* // ==/UserScript== function() { //どうもリクエストした順に、はてブのAPIがカウントすう返してくれるわけじゃないので、UPLとHTML要素をマップする //という意図と、AutoPagerize に対応したので、一度調べたエントリーは調べないようにする var urlToStatusMap = {}; var hatebuFunc = function() { function log() {if(console) console.log.apply(console, Array.slice(arguments));} //指定されたノードから指定された XPath から最初の要素を取得する function findNode(root, xpath) { var result = document.evaluate(xpath, root, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); if (! result.snapshotLength) return null; return result.snapshotItem(0); } //「user」って指定されたノードに入れる関数 function insertBookmarkCount(targetNode, url, count) { var a = document.createElement('a'); a.setAttribute('href', "http://b.hatena.ne.jp/entry/" + url); var str = (count > 0 ? "" + count : "no") + " user" + (count != 1 ? "s" : ""); 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"; } } targetNode.appendChild(document.createTextNode(" (")); targetNode.appendChild(a); targetNode.appendChild(document.createTextNode(") ")); } //status のノードから url を取得する function getStatusUrl(status) { var permanentLink = findNode(status, ".//a[@class='entry-date']"); return permanentLink.href; } var statusList = document.evaluate( "//*[@class='status-body']", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); if (statusList.snapshotLength == 0) { //status が一個もないってのは、タイムライン表示してない場合・・・に違いない return; } var request = '<?xml version="1.0"?>\n<methodCall>\n<methodName>bookmark.getCount</methodName>\n<params>\n'; var status; var url; for (var i = 0 ; i < statusList.snapshotLength; i++) { status = statusList.snapshotItem(i); url = getStatusUrl(status); if(!urlToStatusMap[url]) { //まだはてブ数調べてなかったら request += "<param><value><string>" + url + "</string></value></param>\n"; urlToStatusMap[url] = status; } } request += "</params>\n</methodCall>\n"; const endpoint = "http://b.hatena.ne.jp/xmlrpc"; GM_xmlhttpRequest( { method: "POST", url: endpoint, data: request, onload: function(response) { console.info("hoge"); if (response.responseText.match(/<fault>/)) { //エラーがあった。とりあえずスルー alert("xmlrpc call failed: " + response.responseText + "\n" + "request: " + request); } else { var pattern = /<name>([^<]+)<\/name>\s*<value><int>(\d+)/g; var match; var i = 0; var status; while (match = pattern.exec(response.responseText)) { status = urlToStatusMap[match[1]]; i++; insertBookmarkCount(status, getStatusUrl(status), match[2]); } } } }); } if (window.AutoPagerize && window.AutoPagerize.addFilter){ window.AutoPagerize.addFilter(hatebuFunc); } hatebuFunc(); }();
追記:
なんかtwitterのhtmlが変わってたので修正した。具体的にはxpathを
//div
ってなってたのを
//*
にした。