このセクションでは、XPCOM の利用例を、いくつかの新しいインターフェイスを用いて紹介します。
ウィンドウの管理
Window メニューの生成
Mozilla では、そのときに開いているウィンドウのリストを RDF データソースとして利用できます。
これによって、アプリケーションで開いているウィンドウのリストを表示する Window メニューを作成することが可能です。
このためのデータソースは、rdf:window-mediator
になります。
【訳注: Mediator は、GoF による 23 のデザインパターンの 1 つで「仲介者」といった意味】
以下に使用例を示します。
<toolbox> <menubar id="windowlist-menubar"> <menu label="Window"> <menupopup id="window-menu" datasources="rdf:window-mediator" ref="NC:WindowMediatorRoot"> <template> <rule> <menuitem uri="rdf:*" label="rdf:https://home.netscape.com/NC-rdf#Name"/> </rule> </template> </menupopup> </menu> </menubar> </toolbox>
これによって、Window メニューが作成され、開いている全てのウィンドウの一覧を表示することが可能になります。 たくさんのブラウザウィンドウを開いてからこの例を試して、それらのウィンドウがメニューに現れることを確かめてみてください。
ウィンドウメディエータ コンポーネント
これでウィンドウの一覧表示は十分なので、
次にメニュー項目をクリックすることでウィンドウを切り替えられるように拡張することを考えます。
これは、ウィンドウメディエータ コンポーネントを利用することで実現できます。
このコンポーネントは、nsIWindowDataSource
インターフェイスを実装しています。
以下に、コンポーネントを取得する例を示します。
var wmdata = Components.classes["@mozilla.org/rdf/datasource;1?name=window-mediator"].getService(); wmdata.QueryInterface(Components.interfaces.nsIWindowDataSource);
このコードは、ウィンドウメディエータのデータソースのコンポーネントを取得します。 ここで利用するコンポーネントは、最初の例で (内部的に) window-mediator RDF データソースを処理しているものと同じです。 なお、このコンポーネントは、RDF サービス (RDF データソースを管理する別のサービス) から取得することも可能です。
nsIWindowDataSource インターフェイスには、getWindowForResource
関数があり、これを利用してリソースに対応するウィンドウオブジェクトを取得することができます。
最初の例で、ウィンドウのリストを生成し、テンプレート経由でメニューに加えています。
このときテンプレートは、各
要素に対して、それぞれ menuitem
属性を生成します。
この id 属性に設定される値がリソースとして利用できます。
まとめると、ウィンドウのフォーカスを切り替えるためには、以下のことを行う必要があります。
id
- ユーザがクリックした要素を特定する。
- その要素から
属性の値を取得する。id
- その値を
getWindowFromResource()
に渡して、ウィンドウオブジェクトを取得する。 - 取得したウィンドウにフォーカスを切り替える。
以下に、これを行った例を示します。
<toolbox> <menubar id="windowlist-menubar"> <menu label="Window" oncommand="switchFocus(event.target);"> <menupopup id="window-menu" datasources="rdf:window-mediator" ref="NC:WindowMediatorRoot"> <template> <rule> <menuitem uri="rdf:*" label="rdf:https://home.netscape.com/NC-rdf#Name"/> </rule> </template> </menupopup> </menu> </menubar> </toolbox> <script> function switchFocus(elem) { var mediator = Components.classes["@mozilla.org/rdf/datasource;1?name=window-mediator"].getService(); mediator.QueryInterface(Components.interfaces.nsIWindowDataSource); var resource = elem.getAttribute('id'); switchwindow = mediator.getWindowForResource(resource); if (switchwindow){ switchwindow.focus(); } } </script>
この例では、メニュー要素に対してコマンドハンドラが設定され、メニュー項目が選択されたときに選択された要素を引数として関数 switchFocus()
を呼び出すようになっています。
関数 switchFocus()
は、以下の動作を行います。
- 最初に、ウィンドウメディエータのデータソースのインターフェイスを実装するコンポーネントを取得します。
- 次に、要素の
属性を取得します。ここには、リソースとして利用可能な値が設定されています。id
- 関数
getWindowForResource()
は、渡されたリソースに対応するウィンドウを返します。これによって取得されswitchwindow
変数に格納されたウィンドウは、JavaScript のウィンドウオブジェクトと同様に扱うことができます。 - ここでは
関数を呼び出していますが、そのオブジェクトが提供する関数であれば任意のものを呼び出すことが可能です。focus()
クッキー
次の例として、ブラウザに保存されているクッキーのリストを取得してみます。
これは、クッキーサービスを利用することで実現できます。
クッキーサービスは、nsICookieManager
インターフェイス実装しており、これを利用してすべてのクッキーを列挙することが可能です。
ここでは、例として MozillaZine から設定されたすべてのクッキーの名前を表示するメニューリストを構築してみます。
<script> function getCookies() { var menu = document.getElementById("cookieMenu"); menu.removeAllItems(); var cookieManager = Components.classes["@mozilla.org/cookiemanager;1"] .getService(Components.interfaces.nsICookieManager); var iter = cookieManager.enumerator; while (iter.hasMoreElements()){ var cookie = iter.getNext(); if (cookie instanceof Components.interfaces.nsICookie){ if (cookie.host == "www.mozillazine.org") menu.appendItem(cookie.name,cookie.value); } } } </script> <hbox> <menulist id="cookieMenu" onpopupshowing="getCookies();"/> </hbox>
要素に menulist
属性を設定することで、
onpopupshowing
getCookies()
関数がメニューが開かれるたびごとに呼び出されるようにしています。
getCookies()
の最初の 2 行は、
要素を取得して、すべての項目をメニューから削除しています。
menulist
getCookies()
は、メニューが開かれるたびに繰り返し呼び出されることになるので、
以前の項目が残ったままにならないように最初に削除する必要があるわけです。
次に、クッキーマネージャを取得します。
このクッキーマネージャには enumerator
メソッドがあり、
このメソッドは nsISimpleEnumerator
を実装した列挙オブジェクトを返します。
このオブジェクトを使用することで、全てのクッキーに対して反復処理が行えます。
列挙オブジェクトには hasMoreElements()
メソッドがあり、これは最後のクッキーが得られるまで true を返し続けます。
また、getNext()
メソッドは、クッキーを取得して、列挙オブジェクトのインデックスを次のクッキーに進めます。
このメソッドは、単に汎用オブジェクトを返すため、
使用する前に QueryInterface()
を使って nsICookie
にする必要がありますが、
ここでは instanceof
演算子を使っているため、このとき同様の効果が得られています。
最後に、クッキーのメニューに項目を追加します。
このためにクッキーの host
、name
、value
プロパティを利用します。
メニューには、項目を追加する
関数があるので、これにラベルと値を与えて項目を追加します。
appendItem()
それ以外の例
以下のページでは、さらにたくさんの例が紹介されています。
次のセクションでは、ツリーの作成について見ていきます。