prefs.js の設定項目や RDF ファイルの内容が変更された場合に、それを自動で感知して処理を行わせる仕組みが、 XPCOM には用意されています。
Preferences Listener (というのは正式な名前ではありませんが、 Navigator のソースコード内ではそういう名前で書かれていました)は、指定した名前を含む設定項目が変更された場合に、指定した関数を自動で実行するためのものです。とりあえず、以下のような二つの関数を定義しておいて下さい。
// 監視を開始する
function addPrefListener(aObserver) {
try {
var pbi = Components.classes['@mozilla.org/preferences;1'].getService(Components.interfaces.nsIPrefBranchInternal);
pbi.addObserver(aObserver.domain, aObserver, false);
} catch(e) {}
}
// 監視を終了する
function removePrefListener(aObserver) {
try {
var pbi = Components.classes['@mozilla.org/preferences;1'].getService(Components.interfaces.nsIPrefBranchInternal);
pbi.removeObserver(aObserver.domain, aObserver);
} catch(e) {}
}
例えば、ツールバーのボタンの表示・非表示を app.showbutton.button1
, app.showbutton.button2
などの設定名で保存しておき、アプリ起動時に設定を見てボタンの表示・非表示を切り替えるようにしていたとしましょう。設定を反映させるのは起動時の一回だけですから、起動中に設定が変更された場合、ボタンの表示は再起動するまで変わりません。これはちょっとマヌケですよね。
こんな時は、以下のような Listener を定義して addPrefListener で登録しておけば OK です。
var buttonPrefListener = {
domain : 'app.showbutton',
//"app.showbutton.XXX"という名前の設定が変更された場合全てで処理を行う
observe : function(aSubject, aTopic, aPrefstring) {
if (aTopic == 'nsPref:changed') {
...
// 設定が変更された時の処理
}
}
};
addPrefListener(buttonPrefListener); // 登録処理
全てのウィンドウで起動時に Preferences Listener を登録しておけば、他のウィンドウでも自動的に処理が行われます。 Navigator でも実際に、ツールバーのボタンの表示設定を反映する処理に使われています。
prefs.js ではなく RDF ファイルに設定を保存している場合は、 RDF DataSource Observer を使います。 Observer はデータソースごとに登録します。
var RDFObserver = {
onAssert: function (aDataSource, aSource, aProperty, aTarget) {
// 何らかのデータがデータソースに追加された時
},
onUnassert: function (aDataSource, aSource, aProperty, aTarget) {
// 何らかのデータがデータソースに追加された時
},
onChange: function (aDataSource, aSource, aProperty, aOldTarget, aNewTarget) {
// リソースが変更された時
},
onMove: function (aDataSource, aOldSource, aNewSource, aProperty, aTarget) {
// リソースが移動された時
},
beginUpdateBatch: function (aDataSource) {
// 上記それぞれの処理が始まった時
},
endUpdateBatch: function (aDataSource) {
// 上記それぞれの処理が全て終わった時
}
};
const RDF = Components.classes['@mozilla.org/rdf/rdf-service;1']
.getService(Components.interfaces.nsIRDFService);
var dsource = RDF.GetDataSource('file:///c:/ ... /data.rdf');
dsource.AddObserver(RDFObserver); //監視を開始
// dsource.RemoveObserver(RDFObserver); //監視を終了
これは、 Navigator でも実際に、ブックマークの内容が変更された場合の処理に使われています。