Firefox 拡張機能の設定項目の保存時に日本語が化ける

Firefox拡張機能でユーザに設定項目を入力させる場合、その設定内容は nsIPrefBranch を使って保存したり読み込んだりすることが多いと思います。

参考: 4章:XPCOM活用術〜高度な処理を実現する〜 (Firefox 拡張機能開発チュートリアル)

んで文字列を保存するときに、日本語等の非 ascii 文字も問題なく保存、読出しができるものだと思っていたのですが違うみたいですね。 以下のコードでテストしました。

/**
* 設定保存, 読出しで日本語が化けないかどうかのテスト
*/
var test = function() {
// 設定の情報を取得する XPCOM オブジェクトの生成
var prefSvc = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefService);
var prefBranch = prefSvc.getBranch("extensions.applauncher.");
// 保存
prefBranch.setCharPref("test", "日本語テスト!");
// 読み出して、アラートで表示
// 実際はタイプ別に取得する関数を分けた方がいい (と思う) が, ここでは省略
window.alert( prefBranch.getCharPref("test") );
};

"日本語テスト!" と表示されるべきところですが、実際はよくわからん文字 (化けた文字) が表示されました。 そんなわけで日本語はそのままじゃ保存できないみたいです・・・。

日本語もちゃんと保存させるために

以下のように URL エンコード + エスケープすれば良いみたい。 4章:XPCOM活用術〜高度な処理を実現する〜 (Firefox 拡張機能開発チュートリアル) に書いてあるそのまんまですが。

/**
* 設定保存, 読出しで日本語が化けないかどうかのテスト
*/
var test = function() {
// 設定の情報を取得する XPCOM オブジェクトの生成
var prefSvc = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefService);
var prefBranch = prefSvc.getBranch("extensions.applauncher.");
// 保存
prefBranch.setCharPref( "test", unescape(encodeURIComponent("日本語テスト!")) );
// 読み出して、アラートで表示
// 実際はタイプ別に取得する関数を分けた方がいい (と思う) が, ここでは省略
window.alert( decodeURIComponent(escape( prefBranch.getCharPref("test") )) );
};