次に、XBL で定義された要素にカスタムメソッドを追加する方法を見ることにしましょう。
XBL で定義された要素は、スクリプトプロパティーを追加する以外に、メソッドを追加することもできます。これらのメソッドは、スクリプトから呼び出すことができます。メソッドとは、'window.open()' など、オブジェクトの関数です。method 要素を使えば、自分の要素のためのカスタムメソッドの定義ができます。メソッドの一般的なシンタックスは次の通りです。
<implementation>
<method name="method-name">
<parameter name="parameter-name1"/>
<parameter name="parameter-name2"/>
.
.
.
<body>
-- メソッドのスクリプトがここに来る --
</body>
</method>
</implementation>
|
メソッドの宣言は、プロパティーの場合と同様に、implementation 要素の中で行ないます。method 要素には 2 種類の子供要素があります。メソッドへのパラメータを記述する parameter 要素と、メソッドのスクリプトからなる body 要素です。
name 属性の値がメソッドの名前になります。同様に、parameter 要素の name 属性が個々のパラメータの名前になります。個々の parameter 要素を使って、メソッドへのパラメータのそれぞれを宣言します。例えば、メソッドにパラメータが 3 つある場合、parameter 要素が 3 つ必要です。パラメータが必要ない場合、parameter 要素は使いません。
body 要素には、メソッドが呼ばれたときに実行されるスクリプトを置きます。パラメータの名前は、あたかもパラメータとして渡されたかのように、スクリプト内の変数として定義します。例えば、以下の JavaScript 関数は、XBL メソッドとして書くことができます。
function getMaximum(num1,num2)
{
if (num1<=num2) return num2;
else return num1;
}
XBL:
<method name="getMaximum">
<parameter name="num1"/>
<parameter name="num2"/>
<body>
if (num1<=num2) return num2;
else return num1;
</body>
<method>
|
getMaximum というこの関数は、メソッドにパラメータとして渡された値のうち最大のものを返します。小なり記号をエスケープしなければならない点に注意して下さい。そうしないと、タグの始まりと見られてしまいます。メソッドは、'element.getMaximum(5,10)' のようなコードを使って呼び出すことができます。ここで、element とは、XBL で定義された getMaximum メソッドをもつ要素 (XBL に結び付けられた要素) の参照です。
parameter タグを使って、メソッドへのパラメータの定義ができます。Mozilla はスクリプト言語として JavaScript を使うので、また JavaScript は型のない言語なので、パラメータの型を指定する必要はありません。しかし、将来、XBL で別の言語が使われるかもしれません。このため、追加属性が幾つか定義されています。JavaScript を使っている場合、実際には、これを知っておく必要はありません。
例えば、Java メソッドには、次のコードが使われるかもしれません。
<method name="substring" returns="java.lang.String">
<parameter name="length" type="int"/>
<body type="application/java">
return myStringProperty.substring(length);
</body>
<method>
|
メソッド本体やその他の場所で、content 要素内で定義された幾つかの部分を変更したい場合があるかもしれません。これらの要素は無名のまま作られているので、通常の DOM 関数からアクセスすることはできません。これは隠されており、開発者は、これを使う上で、要素がどのように実装されているのか知る必要はありません。しかし、この無名内容を取得する特別な方法があります。
| 比較的新しい Mozilla のビルドではシンタックスが変更され、無名内容ノードにアクセスできるようになっています。古いビルドでは、要素の anonymousContent と呼ばれるプロパティーにアクセルするメソッドが必要でした。以下では、新しいメソッドの説明をします。 |
XBL の振る舞いを貼り付けられた要素には、内部に無名子供要素の配列をもつ特殊なプロパティーがあります。配列の個々の要素には、XBL で定義された要素の直接の無名子供要素それぞれからなる配列が保存されています。この特殊プロパティーに直接アクセスすることはできません。その代わりに、document の getAnonymousNodes メソッドを呼び出す必要があります。
var value=document.getAnonymousNodes(element); |
ここで、'element' には、無名内容を取得したい要素への参照を設定します。関数は、要素の配列を返します。これは、無名内容です。その下の要素を取得するには、通常の DOM 関数が使えます。それらの要素は隠されていないからです。XBL に結び付けられた要素を別の要素の中に置くことができる点に注意して下さい。その場合、getAnonymousNodes 関数を再度使用する必要があります。
下の例は、ボタンの行を作ります。
<binding id="buttonrow">
<content>
<button label="Yes"/>
<button label="No"/>
<button label="Sort Of"/>
</content>
</binding>
|
個々のボタンを参照するには、getAnonymousNodes 関数が使えます。そのためには、パラメータとして、バインディングが結び付けられている要素への参照を渡します。返される配列には、最初のボタンが最初の配列 ('getAnonymousNodes(element)[0]') に保存され、2 つ目のボタンが 2 番目の配列要素に、3 つ目のボタンが 3 番目の配列要素に保存されます。バインディングメソッド内のコードでは、'this' を getAnonymousNodes へのパラメータとして渡すことができます。
次の例を使えば、ラベル付きのテキストを作ることができます。メソッド 'showTitle' を使って、ラベルを表示したり隠したりできます。これは、無名配列を使ってタイトル要素への参照を取得し、その可視性 (visibility) を変更することによって機能します。
XUL:
<box id="num" class="labeledbutton" title="Number of Things:" value="52"/>
<button label="Show" onclick="document.getElementById('num').showTitle(true)"/>
<button label="Hide" onclick="document.getElementById('num').showTitle(false)"/>
XBL:
<binding id="labeledbutton">
<content>
<xul:text inherits="value=title"/>
<xul:text inherits="value"/>
</content>
<implementation>
<method name="showTitle">
<parameter name="state"/>
<body>
if (state) document.getAnonymousNodes(this)[0].setAttribute("style","visibility: visible");
else document.getAnonymousNodes(this)[0].setAttribute("style","visibility: collapse");
</body>
</method>
</implementation>
</binding>
|
XUL に追加された 2 つのボタンには、ラベルの可視性を変更するのに使われる onclick ハンドラーがあります。それぞれのボタンは、'showTitle' メソッドを呼び出します。このメソッドは、渡された 'state' パラメータをチェックして、ラベル要素を表示するか隠すかを判断します。どの場合も、無名配列の最初の要素を捉えます。これは、content 要素の最初の子供を参照しています。ここでは、これは最初のテキストウィジェットです。可視性は、要素のスタイルを変更することによって変更されています。
別のことをする準備として、無名内容の中から XBL に結び付けられた要素を取得するため、DOM の 'parentNode' プロパティーを使います。これは、要素の親を取得します。例えば、Show ボタンと Hide ボタンを XBL に移すには次のようにします。
例 11.5.1
<binding id="labeledbutton">
<content>
<xul:text inherits="title=value"/>
<xul:text inherits="value"/>
<xul:button label="Show" onclick="parentNode.showTitle(true);"/>
<xul:button label="Hide" onclick="parentNode.showTitle(false);"/>
</content>
<implementation>
<method name="showTitle">
<parameter name="state"/>
<body>
if (state) document.getAnonymousNodes(this)[0].setAttribute("style","visibility: visible");
else document.getAnonymousNodes(this)[0].setAttribute("style","visibility: collapse");
</body>
</method>
</implementation>
</binding>
|
ここでは、onclick ハンドラーは、まず、その親要素への参照を取得します。これは、content ではなく、XBL が結び付けられている XUL 要素です。(この例では、labeledbutton クラスをもつボックスです。) 次に、'showTitle' メソッドが呼び出されます。その機能は前の場合と同じです。
カスタムプロパティーとメソッドは、XBL が結び付けられている外側の XUL 要素だけに追加できます。content タグ内で宣言された要素は、これらのプロパティーやメソッドをもつことはできません。このため、まず、親を取得しなければならなかったのです。
XUL ファイルに置かれた要素の子供は、通常の方法で検索できます。children タグを使う場合でも、それは変わりません。次のコードはその例です。
XUL:
<box id="outer" class="container">
<button label="One"/>
<button label="Two"/>
<button label="Three"/>
<button label="Four"/>
</box>
XBL:
<binding id="labeledbutton">
<content>
<description value="A stack:"/>
<stack>
<children/>
</stack>
</content>
</binding>
|
要素の子供を取得するために、'childNodes' などの DOM 関数を使うと、outer という id をもつ XUL ボックスには、子供が 4 つあることが分かります。これらは、4 つのボタンに対応します。これらのボタンがスタック内に描画されている場合であっても、それは変わりません。スタックには、子供が一つだけあります。children 要素自身です。外側のボックスの無名配列の長さは 2 で、最初の要素はテキストラベル、2 番目の要素はスタックです。
(進む) 次のセクションでは、XBL で定義された要素にイベントハンドラーを追加する方法を示します。
例: 11.5.1