このセクションでは、共通の内容を区別するのに使えるオーバーレイの説明をします。
ウィンドウを一つしか使わない単純なアプリケーションでは、普通、XUL ファイルが一つに、スクリプトファイル、スタイルシート、DTD ファイル、そしておそらくイメージが幾つかあるだけでしょう。アプリケーションによっては、関連付けられた多数のダイアログもあるでしょう。これらは、別々のファイルに保存されることになるでしょう。もっと込み入ったアプリケーションには多くのウィンドウとダイアログがあることでしょう。
ウィンドウを幾つかもつアプリケーションには、個々のウィンドウ間で共通する要素やユーザーインターフェースの部分が数多くあることでしょう。例えば、Mozilla の個々のコンポーネントは、共通する要素を共有しています。タスクやヘルプメニューなど、メニューの幾つかは類似しています。サイドバーは類似しています。個々のウィンドウは、共通のグローバルなキーボードショートカットを共有しています。
これは、必要な個々のファイルで、類似した要素や機能を再実装することによって処理できるかもしれません。しかし、そうするとメンテナンスが困難になります。あるものを変えようと決めた場合、それを色々な場所で変えなければなりません。むしろ、共通する要素を区別し、それらをウィンドウ間で共有できるメカニズムを使う方がよいでしょう。これはオーバーレイを使えば可能です。
オーバーレイファイルは、ウィンドウではなくオーバーレイを記述する XUL ファイルです。オーバーレイの内部には、オーバーレイを使うウィンドウすべてで共有される要素を置きます。こうした要素は、id によって決められたウィンドウ内の場所に追加されます。
例えば、幾つかのウィンドウ間で共有されるヘルプメニューを作りたいとしましょう。ヘルプメニューは、通常使用するのと同じ XUL を使って、オーバーレイに置きます。メニューは、それを識別するため、id 属性を与えられます。個々のウィンドウは、すぐに説明するディレクティブ (directive) を使ってオーバーレイをインポートします。オーバーレイで定義されたヘルプメニューを使うには、id 属性にオーバーレイで使ったのと同じ値をもつメニュー要素を一つ追加するだけです。このメニューは、オーバーレイ内に置かれた子供をもつ必要はありません。
オーバーレイをもつウィンドウを開くと、ウィンドウと、ウィンドウと同じ id をもつオーバーレイにある要素は、結び付けられます。マッチした要素の子供は、ウィンドウの要素内の子供セットの後ろに追加されます。オーバーレイの要素にある属性は、ウィンドウの要素に適用されます。この詳細は後でもっと詳しく説明します。
オーバーレイをウィンドウにインポートするには、以下で説明するシンタックスを使います。「ファイル検索」ダイアログの XUL ファイルの先頭近くに次のコードを追加しましょう。
<?xul-overlay href="chrome://findfile/content/helpoverlay.xul"?> |
この行はファイルの先頭近くのどこか、通常は DTD を宣言するすぐ前に追加します。上の例では、ウィンドウはファイル helpoverlay.xul に保存されたオーバーレイをインポートします。
オーバーレイ自身は、ウィンドウ要素の代わりにオーバーレイ要素をもつ XUL ファイルです。それ以外は、ほとんど同じです。他のオーバーレイの内部からオーバーレイをインポートすることもできます。オーバーレイは、それ自身のスタイルシートや DTD、スクリプトをもつこともできます。下の例は、オーバーレイに保存された簡単なヘルプメニューを示しています。
例 12.6.1
<?xml version="1.0"?>
<overlay id="toverlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<menu id="help-menu">
<menupopup id="help-popup">
<menuitem id="help-contents" label="Contents"/>
<menuitem id="help-index" label="Index"/>
<menuitem id="help-about" label="About..."/>
</menupopup>
</menu>
</overlay>
|
overlay がオーバーレイの内容を囲んでいます。これは、XUL ウィンドウファイルと同じネームスペースを使います。オーバーレイの内部には、3 つの項目からなるメニューが一つ定義されています。このメニューの id は、help-menu です。これは、その内容がウィンドウ中の同じ id 値をもつ類似した要素がある場所に追加されるということです。このような要素がない場合、オーバーレイのその部分無視されます。オーバーレイは、必要に応じて要素を幾つでももつことができます。
次に、ヘルプメニューを「ファイル検索」ダイアログウィンドウに追加する必要があります。このためには、同じ id をもつメニューを適切な場所に加えるだけです。最も適切な場所は edit メニューのすぐ後でしょう。
<menu id="edit-menu" label="Edit" accesskey="e">
<menupopup id="edit-popup">
<menuitem label="Cut" accesskey="t" key="cut_cmd" oncommand="doCut()"/>
<menuitem label="Copy" accesskey="c" key="copy_cmd" oncommand="doCopy()"/>
<menuitem label="Paste" accesskey="p" key="paste_cmd" oncommand="doPaste()"/>
</menupopup>
</menu>
<menu id="help-menu" label="Help" accesskey="h"/>
</menubar>
|
ここでは、ヘルプメニュー要素には内容が何もありません。メニューの項目は、id がマッチするのでオーバーレイから取られます。次に、オーバーレイを別のウィンドウでインポートできます。そのため、一個所で定義したヘルプメニューの内容だけがあれば十分です。
ヘルプメニューの属性 (この例では label と accesskey) をオーバーレイに置くことによって、ウィンドウ内のコードの両をもっと減らすことができます。これらの属性は、要素が継承します。要素とウィンドウの両方に同じ属性を指定すると、オーバーレイ内の値が要素の値を上書きします。
ヘルプメニューをこのやり方で変更しましょう。
findfile.xul:
<menu id="edit-menu" label="Edit" accesskey="e">
<menupopup id="edit-popup">
<menuitem label="Cut" accesskey="t" key="cut_cmd" oncommand="doCut()"/>
<menuitem label"Copy" accesskey="c" key="copy_cmd" oncommand="doCopy()"/>
<menuitem label="Paste" accesskey="p" key="paste_cmd" oncommand="doPaste()"/>
</menupopup>
</menu>
<menu id="help-menu"/>
</menubar>
helpoverlay.xul:
<?xml version="1.0"?>
<overlay id="toverlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<menu id="help-menu" label="Help" accesskey="h">
<menupopup id="help-popup">
.
.
.
|
オーバーレイとウィンドウの要素の両方に内容があると何が起こるのでしょうか。この場合、ウィンドウの内容がそのまま使われ、オーバーレイの内容はその末尾に追加されます。以下の例は、このことを示しています。
stopandgo.xul:
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
<window title="Stop and Go" id="test-window"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<?xul-overlay href="chrome://findfile/content/toverlay.xul"?>
<box id="singlebox">
<button id="gobutton" label="Go"/>
<button id="stopbutton" label="Stop"/>
</box>
</window>
toverlay.xul:
<?xml version="1.0"?>
<overlay id="toverlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<box id="singlebox">
<button id="backbutton" label="Back"/>
<button id="forwardbutton" label="Forward"/>
</box>
</overlay>
|
この例では、識別子 singlebox をもつボックスにはそれ自身の内容があります。要素は結び付けられ、オーバーレイの 2 つのボタンがボックスの末尾に追加されます。それらを先頭に追加したい場合、もう一つ内部ボックスを追加し、その中に要素をインポートすればよいでしょう。外側のボックスに id を置く代わりに、ボタンを置きたい内側のボックスにそれを置きます。もっとよい方法は、すぐあとで説明します。
メニューを使うと、余分な menupopup 要素が必要となるため、少々トリッキーになります。ウィンドウとオーバーレイにポップアップを置くと、その一方だけが使われます。メニューはポップアップを一つしか使えないからです。ポップアップの id を使うことによって、これは簡単に回避できます。
findfile.xul:
<menu id="help-menu">
<menupopup id="help-popup">
<menuitem id="help-findfiles" label="Find files help"/>
</menupopup>
</menu>
</menubar>
helpoverlay.xul:
<menu id="help-menu" label="Help" accesskey="h" />
<menupopup id="help-popup">;
<menuitem id="help-contents" label="Contents"/>
<menuitem id="help-index" label="Index"/>
<menuitem id="help-about" label="About..."/>
</menupopup>
|
今度は、属性を取得するための menu 要素とメニュー内容を取得するための menupopup 要素の両方をオーバーレイすることにします。こうすることにより、項目 4 つからなるメニューが得られます。
しかし、前の例では、オーバーレイ内のメニュー項目を末尾にではなくメニューの先頭に置きたかったのでした。XUL は、それらを先頭だけでなく、項目の幾つかを先頭に置き残りを下部 (あるいは、その間のどこにでも) 置くメカニズムを提供しています。これによって、メニュー、ツールバー、その他のウィジェットを必要な正確な場所にオーバーレイすることができます。
このためには、メニュー項目に insertbefore 属性を使います。その値は、項目を挿入したい位置のすぐ後の要素の id にします。それ以外に、どの要素の後ろに項目を挿入したいのかを指示するため、insertafter 属性が使えます。これらの属性は、それが指定されている要素だけに影響します。ある要素が '前に挿入された' としても、残りの要素は末尾に追加されます。要素すべてを前に表示させたい場合、要素すべてに insertbefore を置かなければなりません。
更に、特定のインデックスの位置を指定したい場合は、position 属性が使えます。最初の位置は 1 です。
オーバーレイの Contents と Index 項目を「ファイル検索」ヘルプメニューの前に表示し、 About 項目を後ろに表示したいとしましょう。このためには、Contents と Index メニュー項目の両方に insertbefore 属性を追加します。完璧を期すため、About メニューにも insertafter を追加しても構いませんが、これは必要ありません。それはデフォルトで末尾に表示されるからです。
上のヘルプメニューの例では、メニュー項目の id は help-findfiles です。このため、insertbefore をこの id に設定する必要があります。下の例はこの変更を示しています。
<menupopup id="help-popup"> <menuitem id="help-contents" label="Contents" insertbefore="help-findfiles"/> <menuitem id="help-index" label="Index" insertbefore="help-findfiles"/> <menuitem id="help-about" label="About..."/> </menupopup> |
これで、(「ファイル検索」ダイアログなどの) ヘルプオーバーレイを使ったウィンドウ が開かれると、次のことが起こります。
実際には、insertbefore と insertafter の値は、カンマで区切ったリストでも構いません。この場合は、ウィンドウで見付かったリスト内の最初の id が、その位置を決めるのに使われます。
(進む) 次は、オーバーレイを異なったパッケージ内のウィンドウに適用する場合を見ることにしましょう。
例: 12.2.1