バグ修正・・・。
前回のエントリー しなもんとどこでも遊べるGreasemonkey & Bookmarklet - sawatの日記 のやつについて、
Greasemonkeyで実行した場合にはてなブックマークコメントの取得ができておらず、しなもんがおしゃべりをしないことに2週間たった今頃気付きました…。
バグが発生した経緯は以下の通り。
- はてなブックマークコメントの取得は、はじめJSONPバージョンを使って行っていた。
- しかし、Greasemonkeyのスクリプト内で定義された関数は他からは参照できない(サンドボックス機能)*1。そのため、Greasemonkeyで実行する場合はJSONPのコールバック呼び出しができない。
- なので、Bookmarkletで実行されたときはJSONPを呼び出し、Greasemonkeyの時はGM_xmlhttpRequestを使って、普通のJSONのAPIを呼び出すように修正。
if ( typeof(xmlhttpRequest) == 'function' ) { // Greasemonkeyの場合 xmlhttpRequestでJSON呼び出し } else { // bookmarkletの場合 appendChild(script)でJSONP呼び出し }
- しかし、Trixieの場合、Trixie版のGM_xmlhttpRequestが使えるはずだが、なぜかうまく実行されない。逆にTrixieにはサンドボックスがないらしく*2、JSONP呼び出しならうまくいく。
- Trixie版GM_xmlhttpRequestについて詳しく調べたりしたくなかったので、TrixieではJSONP呼び出しをするように変更。GM_xmlhttpRequestの有無だとGreasemonkeyとTrixieを区別できないため、Trixieには定義されていないGM_logで判別するようする。
if ( typeof(window.GM_log) == 'function' ) { // Greasemonkeyの場合 xmlhttpRequestでJSON呼び出し } else { // bookmarkletとTrixieの場合 appendChild(script)でJSONP呼び出し }
- やったTrixieでもちゃんと動いたぞ。よし。これで完成!
で、どこにバグがあるかというと、window.GM_logの部分。なぜかGM_logにしたときにwindow.をつけてしまった。GM_logはトップレベルの関数だから、windowオブジェクトのプロパティに違いないという思い込み。しかし、実際はそうではなく、typeof(window.GM_log)はつねに"undefined"を返し、Greasemonkeyの場合でもJSONP呼び出しをするというバグが残ってしまったのでした。あべし。
非常にいまさらですが、修正版をおいておきます。
http://sawat.jf.land.to/cinnamon/browsertop_accesory_cinnamon.user.js
Greasemonkeyにインストールして、いまだに使い続けているひとが万が一*3いましたらアップデートをお願いします。
あと、無駄に機能追加。しなもんをダブルクリックすると、なんと2匹目のしなもんを召喚することができるようになりました!(右図)
前から、ブックマークレット版を複数回実行すればできましたけどね。*4