「あわせて読みたい」にはてブとlivedoor Readerのカウンターをつけるuser.js

あわせて読みたい」が更新されたから、前回エントリーのuser.jsも直さなきゃいけないかなと思ったのですが、全然そのままで問題ないみたいなので、代わりに(?) id:onkさんのアイデアを実装してみました。
livedoor Reader購読者数の取得にはFeed Discover APIを使っています。

スクリーンショット



あわせて読みたい」に「livedoor Reader購読者数」もあわせてみた。

これをインストール

awasetewithhbmldr.user.js
スクリプト名を別にしてあるので、前作がインストールされている場合はアンインストールしてください。

動作環境

とりあえず、Firefox+GreasemonkeySleipnir+SeaHorseOperaのuser.js、IE7Trixieで動作確認しました。

ソース

// ==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用の処理もつけた。
  • scriptのcharsetはsrcより先に設定しなきゃダメ。
  • 若干上にずれて表示されているのが何でかわからない。
  • 画像API(HBM)はJSONAPIにくらべて用途が限られるが使うのは簡単だ。

まとめ

ごちゃごちゃと追加しすぎると元々のシンプルデザインが台無しという気がしないでもないですが、
どうぞご利用ください。

*1:理由は使ってみたかったから