[greasemonkey] cookpad_tukurepo.user.js更新

http://gist.github.com/raw/147258/79560d9304f09adb55b83f22608bcef797683f1a/cookpad_tukurepo.user.js

cookpad側のマークアップが変わっていたらしく動かなくなっていた所、http://d.hatena.ne.jp/IwamotoTakashi/20091024/p1
で修正していただいた。感謝。
forkされたソースを見ると、aタグをgetEmenentsByTagNameで取得して、それぞれに対してレシピのURLかどうかを正規表現で判断していた。もともとのソースはgetElemetsByClassNameでクラス名で取得していたのだが、なぜこのような変更をしているのか気になって調べてみた。

  • 元々のソース
var recepi_titles = Array.slice(elem.getElementsByClassName("recipe-title"));
         recepi_titles.forEach(function(title) {
             GM_xmlhttpRequest({
…
  • forkされたソース
var anchors = Array.slice(elem.getElementsByTagName('a'));
         anchors.forEach(function(a) {
             if (a.href.match(/^http:\/\/cookpad\.com\/recipe\/\d+$/) && a.getElementsByTagName('img').length == 0) {
                 GM_xmlhttpRequest({
…

取得したい要素は下記のようにマークアップされている。表示されるページによって、font13の部分が変わったりするようだ。例えばトップページのレシピへのリンクはclass="recipe-title"となっている。

<a class="recipe-title font13" href="http://cookpad.com/recipe/953747">大根たっぷりみぞれ鍋(0件)</a>

こういう仕様になっているから、class名で取得するのはよくないと判断されたのだろう。forkされたソースをそのまま取り込んでも良かったが、これxpathで取得出来るよねと思い書いてみた。

$X('.//a[starts-with(@class, "recipe-title")]', elem)

で取得している。xpath便利。
$Xはid:os0xさんのvery simple versionを使わせていただきました。動作的にはどちらでも動くので好きな方を使ったら良いと思います。