はてなスターでrel="canonical"を見るように

Googleの+1はデフォルトでrel="canonical"を見るようになってたりします。Facebookのいいね! ボタンはてなブックマークボタンは対応していませんが、明示的に対象のURLを指定できるようになっているのであまり問題はありません。しかし、はてなスターはa要素かwindow.locationdocument.locationという訪問者側がいくらでも細工ができるものしか指定できないため、宗教上の理由で自身のURLへリンクを張るa要素を書くことができない人は詰みます。そんな理由で外してしまったんですが、対応してくれそうもないので重い腰を上げてHatenaStar.jsに処理を追加しました。

ざっと読んだところHatena.Star.EntryLoader.getElementByConfigSelector()でうまいことrel="canonical"link要素を返すようにすれば良さそうです。gEBCS()はCSSセレクタを渡して要素を選択するものだが、内部でquerySelector()のラッパーになってたりとかそういううまい話はないので、link[rel="canonical"]を渡してもそのままではうまく動きません。なのでwindow.location等と同じように特別視する処理を入れてやる必要があります。

} else if (selector == 'link[rel="canonical"]') {
  var z = document.getElementsByTagName("link"),
    y,
    x = z.length,
    w,
    v = document.createElement("a");

  for (y = 0; y < x; y++) {
    w = z[y];

    if (w.rel === "canonical") {
      v.setAttribute("href", w.href);
      result = v.cloneNode(false);
      break;
    }
  }

getElementsByTagName()link要素を全て取得し、rel属性がcanonicalなものをresultにセットするというだけです。変数がはっちゃけているのは気にしない。cloneNode()を使っているのは相対URLでrel="canonical"が書かれていた場合に某ブラウザもどきで絶対URLにならないことへの対策で、元ネタはグループ日記のタイトルを変えすぎる人のエントリです。パッチもあります。

これでHatena.Star.SiteConfigで特殊なセレクタとしてlink[rel="canonical"]が使えるようになります。


このブログのように、Blosxomで一覧ページとpermalinkで対象とするURLを切り替える場合はinterpolcate_fancyを使って以下のようにすれば良いでしょう。

<script type="text/javascript">
Hatena.Star.SiteConfig = {
  entryNodes: {
    "article": {
<?$path_info like="\.html$">
      uri:       "link[rel=\"canonical\"]",
</?>
<?$path_info unlike="\.html$">
      uri:       "h2 a",
</?>
      title:     "h2",
      container: "footer p"
    }
  }
};
</script>

これでスター通知でニヤニヤする日々が帰ってきますね!