「あわせて読みたい」にはてブとlivedoor Readerのカウンターをつけるuser.js
「あわせて読みたい」が更新されたから、前回エントリーのuser.jsも直さなきゃいけないかなと思ったのですが、全然そのままで問題ないみたいなので、代わりに(?) id:onkさんのアイデアを実装してみました。
livedoor Reader購読者数の取得にはFeed Discover APIを使っています。
これをインストール
awasetewithhbmldr.user.js
スクリプト名を別にしてあるので、前作がインストールされている場合はアンインストールしてください。
ソース
// ==UserScript== // @name Awasete with HBM & LDR // @namespace http://d.hatena.ne.jp/sawat/ // @description Awasete.com with Hatena bookmark counter // @include http://awasete.com/show.phtml?* // ==/UserScript== // LDR Icon var data = 'data:image/png;base64,'+ 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAARVBMVEUFFUAGGEAGFkAHGkAHGUAI'+ 'HUATR/8USv8VUv8VTf8XVv8YWv8ZXv8aYv8bZv8cav8dbv8fd/8fcv8gev8hff8igP/////sqzRG'+ 'AAAAYElEQVR42l3MSRLCQBADQbGYZbABG6j/PxWp5+TJiOrQqcVvB30H+gy0GmUt2myCyWVuegf0'+ 'TK+AnukZ9eNUU0vAGWotmgPmgws9AnqmZvnQjjmt6Wayutn3ga4DcdnhDwXhDnMwffCnAAAAAElF'+ 'TkSuQmCC'; function appendHBMCounter(href, li) { var hateb = document.createElement("a"); hateb.href = "http://b.hatena.ne.jp/entrylist?url=" + href; hateb.style.marginLeft = "10px"; var img = document.createElement("img"); img.style.width = "75px"; img.style.height= "14px"; img.src = "http://b.hatena.ne.jp/bc/lg/" + href; hateb.appendChild(img); li.insertBefore(hateb, li.getElementsByTagName("br")[0]); } function appendLDRCounter(href, li, count) { var ldr = document.createElement("a"); ldr.href= "http://reader.livedoor.com/about/"+href; ldr.style.marginLeft = "10px"; ldr.style.whiteSpace = "nowrap"; var img = document.createElement("img"); img.style.width = img.style.height = "16px"; try { img.onerror = function() { this.src = "http://sawat.jf.land.to/gm/ldr_icon.png"; }; } catch(e) {} img.src = data; ldr.appendChild(img); ldr.appendChild(document.createElement("span")).innerHTML = " " + count + (count > 1 ? " users" : "user"); li.insertBefore(ldr, li.getElementsByTagName("br")[0]); } var list = document.getElementsByTagName("li"); var links = []; var map = {}; for(var i=0, n=list.length; i<n; i++) { var as = list[i].getElementsByTagName("a"); var href; for(var j=0; j<as.length; j++) { if(as[j].href.indexOf("awasete.com") == -1) { href = as[j].href; } } if(href) { appendHBMCounter(href, list[i]); links.push(href); map[href] = list[i]; } } var win = (typeof unsafeWindow == 'undefined') ? window : unsafeWindow; var func = function(feedInfo) { for(var i=0; i<feedInfo.length; i++) { var li = map[feedInfo[i].source]; appendLDRCounter(feedInfo[i].source, li, feedInfo[i].subscribers_count); } win.awhl_callback = undefined; } win.awhl_callback = func; // for SeaHorse(Slepnir) win.eval("window.awhl_callback=" + func); var script = document.createElement("script"); script.type = "text/javascript"; script.charset = "UTF-8"; script.src = "http://rpc.reader.livedoor.com/feed/discover?" + "format=json&callback=awhl_callback&links=" + encodeURIComponent(links.join("\n")); document.body.appendChild(script);
今回の修正の(個人的な)ポイント
- ソースが長くなって、汚くなった。
- Feed Discover APIは複数のURLの情報をいっぺんに取得できる。
- が、あまり長すぎるリクエストをGETで投げつけるのはいかがなものかもしれない。
- JSONPのコールバックはGreasemonkeyならunsafeWindowに登録すればよいが、SeaHorseだとevalで登録しないといけない。
- LDRアイコン表示にdataスキームを使ってみた*1が、onerrorでIE用の処理もつけた。
- Greasemonkeyでimgにonerrorを設定したらエラーになった。⇒ try-catchで対処。
- dataスキームのURI生成は[JavaScript] dataスキームURI生成(画像データのBase64変換)を使った。
- scriptのcharsetはsrcより先に設定しなきゃダメ。
- 若干上にずれて表示されているのが何でかわからない。
- 画像API(HBM)はJSON型APIにくらべて用途が限られるが使うのは簡単だ。
まとめ
ごちゃごちゃと追加しすぎると元々のシンプルデザインが台無しという気がしないでもないですが、
どうぞご利用ください。
*1:理由は使ってみたかったから