Firefox3 で動かすグリモンスクリプトで unsafeWindow 以下の prototype にアクセスしたいときは

こういう書き方をする。

location.href = 'javascript:(' + function() {
  (function (w) {
  // ...
  // unsafeWindow.hogehoge.prototype とかはここに書く
  // ...
  }) (this.unsafeWindow || window);
}.toString() + ')()';

結論からはじめるメソッド使ってみた。以下は理由。


はてなハイクのパレットを変更するグリモン - gan2 の Ruby 勉強日記にあるスクリプトを書いてたときに
以下の2つは同じ動作をするものだと思っていたのだけど、実際は違っていてけっこうハマった。

(function () { ... } )();
location.href = 'javascript:(' + function () { ... }.toString() + ')()';


「...」で省略しているところには「unsafeWindow.deconcept.SWFObject.prototype」が入っている。
これは「SWFObject」っていう HTML に SWF を埋め込むための
便利なライブラリが生成するオブジェクトなのだけど、
1つ目のやり方だとどうしてもこのオブジェクトにアクセスできない
(もっとちゃんといえば deconcept が undefined になっちゃう)のに
2つ目のやり方だとすんなりアクセスできる。
で、僕は1つ目と2つ目の違いが全然分からなくて*1
しばらくなんでなんでーって状態になっていた。


でもGreasemonkeyをBookmarklet的に実行してみる - 0x集積蔵を見てちょっとスッキリした。
グリモンのスクリプトを書くときは1つ目の書き方で囲ってあげるのが定石だと思っていたんだけど
この書き方をしたスクリプトを Firefox3 で動かすと
unsafeWindow 以下の prototype にアクセスできないらしい。


そして、どういう原理なのか今一よく分かっていないけど
2つ目の書き方のように Bookmarklet っぽい囲み方をするとそっちはうまくいくようだ。
でもこの方法を使うと GM 系の関数は使えなくなるみたい。
えーじゃあ prototype といっしょに GM_xmlhttpRequest を使いたくなったらどうすんだろー。


まあ今はとりあえずこういうものだと覚えておいて
その内うまい解決策が見つかることを祈ろう。

*1:今でもよく分かってない