X-0003 Mozilla の設定ダイアログに独自のパネルを組み込む

カテゴリツリーへの新しい項目の追加

ダイアログウィンドウ左のツリーは preftree.xul に既にある項目を参考に overlay で組み込みます。パネル本体は<page>をルート要素にしたXULのファイルを使用します。パネルの中身については XPCOM の prefs.js 読み書き用の機能を使って自力で作ってもよいのですが、後述するような他のパネルで使われている機能を流用すれば、色々と手間を省けます。

設定パネルの記述

まず、 XUL でパネルの UI を作ります。Mozilla 1.0 では個々のパネルのルート要素は page にするようになっていますが、Netscape 6 でも使えるようにするなら、 window 要素にしても構いません。設定項目に使う checkbox や textbox 、 menulist などには以下の属性を指定してください。

属性名説明備考
pref true その要素が設定項目であることを示す。 Netscape 7以降では省略可。
preftype bool | string | localizedstring | int 設定のタイプ。真偽値、文字列、整数値のどれかを選びます。 Netscape 7以降では省略可。ただし、整数値専用のtextboxなどの場合には必要。
prefstring 任意 保存する設定の名前。 pref.js にあるような形式で書きます。
prefattribute value | label | checked | ... 設定として保存する、その項目の属性。 checkbox なら checked 、 textbox なら value になります。 Netscape 7以降では省略可。

新規ウィンドウを開かなくする隠し設定「 browser.target_new_blocked 」を例に取ってみると、 <checkbox pref="true" preftype="bool" prefattribute="checked" prefstring="browser.target_new_blocked" id="browser.target_new_blocked" label="新規ウィンドウを開かない"/> という具合です。ちなみに id と prefstring を同じにしておくと管理が楽になると思います。

その XUL ドキュメント内に出てくる設定項目の要素の id 全てを _elementIDswindow._elementIDsというグローバル変数window オブジェクトのプロパティの配列に収めます。 _elementIDs = ['id1', 'id2', ...] と自分で書いても、 onload 時に document.getAttribute('pref', 'true') などの方法で要素を集めて自動処理しても、どちらでも構いません(収集漏れを防ぐなら自動処理する方がいいでしょう)。ここで ID を登録しなかった要素については設定が保存されません。

また、 panelwindow.panelというグローバル変数window オブジェクトのプロパティに、パネルの URL を指定しておきます。これは var panel = location.href; とでも書いておけば OK 。

仕上げに、ルート要素の onload 属性に parent.initPanel(location.href); と書きます(前処理・後処理が必要なら、この前後に書く)。これで、設定の読み込み・保存・キャンセル時の処理など後のことは全て Mozilla がやってくれます。非常に楽チンですね。

パネルのタイトルは、NS6 では <box orient="horizontal" class="box-smallheader" title="タイトル"/> という風に記述していましたが、 Mozilla 1.0 ではルート要素( window あるいは page )に <page headertitle="タイトル"> と書いておくとそれが自動で表示されるようになっています。 NS6 と最新の Mozilla の両方で問題なく使えるようにしたい場合、 window.parent.getElementById('header') があるかないかを調べて自前で処理する必要があります。

補足:スタイルシート

パネルのヘッダでは、以下のスタイルシートを読み込むように指定します。対象の Mozilla のバージョンによってファイルが違いますので、注意してください。

Netscape 6
  • <?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
  • <?xml-stylesheet href="chrome://communicator/skin/dialogOverlay.css" type="text/css"?>
Netscape 7, Mozilla 1.0以降
  • <?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>

xul-stylesheet や xul-overlay などの XML 処理命令で存在しないファイルを指定していると、そのパネルを開いたあと別のパネルを開けなくなるという問題が起こるようです。

僕が引っかかったのは dialogOverlay.css です。このファイルはパネルの見出しなどのスタイル指定なのですが、 Mozilla 0.9.8 以降では仕様の変更でファイルがなくなったため、 NS6 用に作ったパネルを Moz で開こうとすると必ずこの問題にぶち当たります。というわけで、面倒ですが、 NS6 用と Mozilla 0.9.8 以降用とでは嫌でもパッケージを分けなければなりません。

これが面倒な場合、多少イリーガルですが、ラクな回避法法もあります。以下のようなスタイルシートを <?xml-stylesheet href="forNS6.css" type="text/css"?> のような形で指定して下さい。

/* forNS6.css */
@import url("chrome://communicator/skin/dialogOverlay.css");

@import で指定したファイルについては、前述のような問題は起こらないようです。