Mar 19, 2008
外部のスクリプトを読み込む
各地既報ですが、セキュリティ上の仕様変更によってmozIJSSubScriptLoaderで読み込めるスクリプトの置き場所がChrome内に限定されるようになった(File URLなどの読み込みは拒否されるようになった)そうで。まあ自分が作ってる拡張機能には外部のスクリプトを動的に読み込んでどうこうするものがあんまり無いのでそれほど影響は無いんですが、せっかくなので手持ちの情報を晒しときます。
実は僕、割と最近まで、mozIJSSuScriptLoaderで実行コンテキストを指定できるってことに気付いてなかったんですよね。だから、外部スクリプトは実行できてもその実行結果を取り出すとかはできないと思い込んでまして。Firefox 1.5以前から作ってたやつでデフォルト設定をdefault.jsとしてcontent内に置いてた物で、default.jsの内容を読み込ませるために、わざわざmozIJSSubScriptLoaderと同じ働きをするコードを書いてたんです。ああ車輪の再発明。そんなわけで以下の情報がもしかしたら参考になるかもしれません。
- テキストファイルの入出力:任意のURIで示されたファイルの内容をテキストとして読み込む方法。httpとかftpとかだと、うまくやらないとファイルの頭の方だけしか取れてないのに処理が先に進んでしまうとかそんなことになりかねないので、要注意。面倒な事を考えたくなければnsIXMLHttpRequestでやった方が早いかも。
- nsIXMLHttpRequestの利用例(Rewind/Fastforward Buttons)
- 実行コンテキストを指定して任意のスクリプトを実行する方法:Firefox 3の仕様変更を乗り越えるための試行錯誤の痕跡。実際のコード
……あ。今気付いたけど(ぉぃ)、Chrome URL限定ってことはdata: URLもダメになったってことか。んじゃUXUもやっぱ影響受けるなぁ。さてどうしたものか。
とりあえずスクリプトを実行するだけだったら上記の方法で読み込んだファイルの内容をeval()
するだけでいいので、その点では話は簡単なんですけどね。
20日追記。最終的に、格好悪いやっつけの方法ではあるんだけど、こういう風な所に落ち着いた。UxU 0.2.6で採用した方法は以下の通り。
- 上記の方法でJavaScriptファイルの内容を文字列として取得。
- それをmozIJSSubScriptLoaderに渡すコンテキストオブジェクトのプロパティとして格納。
- そのコンテキストのプロパティとして格納されているスクリプトを
eval()
するだけのスクリプトをパッケージに含めておき、mozIJSSubScriptLoaderで読み込んで実行。
実際のコードはこんな感じ。
var loader = Components
.classes['@mozilla.org/moz/jssubscript-loader;1']
.getService(Components.interfaces.mozIJSSubScriptLoader);
this.include = function(aSource, aEnvironment, aEncoding) {
var encoding = aEncoding || this.getPref('extensions.uxu.defaultEncoding')
var script = this.readFrom(aSource, encoding) || '';
var env = aEnvironment || this.environment;
env._subScript = script;
loader.loadSubScript(
'chrome://uxu/content/test/helper/subScriptRunner.js?includeSource='+
encodeURIComponent(aSource)+
';encoding='+encoding,
env
);
};
subScriptRunner.jsというファイルの内容は、たったこれだけ。
if (_subScript) eval(_subScript);
これで、mozIJSSubScriptLoaderで普通にスクリプトを読み込ませるのと同じような結果になる。
さらに追記。仕様が変更されて、file:とresource:は使えるようになったそうだ。でもdata:は相変わらずダメなので、今までdata:でやってたものはここに書いたような何らかの方法で代替するしかないと思う。
さらにさらに追記。evalInSandboxを使う方法もあるそうだ。
さらにさらにさらに追記。evalの機能についてFirefox 3.1でまた変更があったようだ。
wikieditish message: Ready to edit this entry.