ウィンドウとダイアログを開く
新しいウィンドウを開くには、HTML と同じように JavaScript の window.open 関数を使用します。
window.open( "chrome://xulschoolhello/content/someWindow.xul", "xulschoolhello-some-window", "chrome,centerscreen");
最初の引数は開く URL です。2 番目の引数は window を識別する id です。残りは、window の振る舞いや外観についての特性を任意で指定するカンマ区切りのリストです。この値が null または空の場合、新しいウィンドウにメインウィンドウのデフォルトのツールバーが追加されますが、このようなことはあまりしないでしょう。window.open のページに、その特性を指定するための値についての詳しい説明があります。以下の特性は特に重要なので覚えておいてください:
- "chrome"。これは、chrome からのみ使用され、通常の HTML の JavaScript からは使用できません。これは、ウェブページではなく、chrome ドキュメントが開かれることを示します。つまり、開くドキュメントはウィンドウ全体を定義し、内部のコンテンツ領域だけではないことを意味します。XUL ウィンドウやダイアログを開く場合は、常に指定しなければなりません。
- "modal"。モーダルウィンドウは、閉じられるまで、その親ウィンドウの操作をブロックします。警告ウィンドウが例として挙げられます。モーダルウィンドウは、ユーザのブラウジングに割り込み、表示されただけで煩わしくなるため、できるだけ利用を避けるべきです。この特性は、ユーザが何かをしなければ続ける方法が無い場合にのみ使用してください。アプリケーションの起動時にモーダルウィンドウを開いてはいけません。
- "resizable"。 ユーザがウィンドウのサイズを変更可能にするかどうかを示します。一般的に、データソースから動的に生成されるコンテンツを表示するのでない限り、ウィンドウのサイズを変更可能にすべきではありません。リストやツリーなどのコンテンツは、それらが正しく表示されるように、ウィンドウのサイズを変更可能にする必要があるでしょう。
新しいダイアログを開くには、open の拡張版である window.openDialog 関数を使用します。この関数は、ダイアログに任意のパラメータのセットを渡すことができます。
let someValue = 2; let returnValue = { accepted : false , result : "" }; window.openDialog( "chrome://xulschoolhello/content/someDialog.xul", "xulschoolhello-some-dialog", "chrome,centerscreen", someValue, returnValue); // ダイアログに必要なだけ追加のパラメータを渡せます。 // if (returnValue.accepted) { do stuff }
渡したパラメータは、ダイアログのコード内で window.arguments プロパティを通して利用できます:
let someValue = window.arguments[0]; let returnValue = window.arguments[1]; // returnValue.accepted = true; // returnValue.result = "something";
上記の例の returnValue という名前のパラメータは、ダイアログでユーザが行った変更を反映するためのオブジェクトです。これは、ダイアログからオープナーへ値を返す最も簡単な方法です。ただし、オープナーはダイアログが閉じられるまで待機しているので注意してください。openDialog 関数を呼び出すと、ユーザがダイアログを閉じるまで何も返しません。
共通のダイアログとプロンプトサービス
共通のダイアログにはいくつかの種類があります。ここでは、それらの XUL コードや JavaScript コードを一から書くような車輪の再発明をせずに、簡単に作成する方法を説明します。新しいダイアログが必要になった場合、本当にこれらの共通のダイアログで実装できるか確認し、可能であれば使用してください。これらは、OS との統合、アクセシビリティ、ローカライズがすべてテストされているため、手軽に使用できます。
拡張機能で共通のダイアログを作成するときは、プロンプトサービスの使用をお勧めします。プロンプトサービスのページの説明と例を注意深く読んでください。プロンプトサービスでは、多くの役立つ関数が使用できます。window オブジェクトにも同等の単純な関数がありますが、これらは特権のない HTML の JavaScript コードで使用するためのものです。
警告ダイアログ
alert は、最も単純な形のダイアログです。ユーザに読ませるテキストメッセージを表示し、OK ボタンをクリックすると閉じます。私たちの例では、window.alert 関数を使用して警告メッセージのダイアログを開いていますが、これは正しい方法ではありません。この関数を何らかの問題をデバッグし、プログラムがコードの特定の行に達したことを知ったり変数の値を調べたりするために使用するだけなら良いでしょう。しかし、最終的に公開する拡張機能では alert の呼び出しをしてはいけません。
window.alert を使用すると、[JavaScript Application] というタイトルの警告ウィンドウになり、メッセージのソースが正しく定義されていないことを示します。プロンプトサービスを使用すると、さらによい警告表示ができます。次の例では、警告の表示に プロンプトサービスを使用しています:
let prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"]. getService(Ci.nsIPromptService); prompts.alert(window, "Alert Title", "Hello!");
ここでも、メッセージの文字列を直接書かずに、ローカライズされた文字列を使用するべきです。
プロンプトサービスを使用すると、ダイアログのタイトルを設定できます。また、警告の親ウィンドウを設定できますが、通常は現在のウィンドウに設定してください。値に null を渡すと、現在のアクティブなウィンドウが設定されます。
確認ダイアログ
確認ダイアログは、テキストと [はい]/[いいえ] のボタンを表示し、ユーザに答えを選択させます。HTML では、window.confirm 関数を使用してください。プロンプトサービスには、これと似た振る舞いをする confirm メソッドがあります:
let prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"]. getService(Ci.nsIPromptService); if (prompts.confirm(window, "Confirm Title", "Would you like to continue?")) { // do something. } else { // do something else }
このメソッドは、ユーザの反応を示す真偽値を返します。
その他
特権のない JavaScript は、ユーザが入力したテキストを受け取るために window.prompt 関数を使用することもできます。プロンプトサービスは、テキストやパスワード、ユーザ名とパスワード、"今後同様に処理する" のチェックボックスを含むダイアログなど、様々な形式の入力ができるとても高度な関数のセットです。confirmEx および prompt は、最もカスタマイズ可能なメソッドです。これらには、多くの一般的な形式のダイアログのオプションがあります。
プロンプトサービスを使用すれば、XUL コードを短くし、Mozilla が試験済みのコードを安心して使用することができます。
ダイアログ要素
プロンプトサービスで不十分な場合は、独自の XUL ダイアログを作成しなければなりません。幸運にも、dialog 要素を一般的な window 要素の代わりにドキュメントのルートとして使用すれば、プラットフォームから多くの助けを得ることができます。
OK ボタンやキャンセルボタンを持つ簡単な XUL ウィンドウを定義することとの大きな違いがどこにあるのか、疑問に思うかもしれません。このセクションで扱うダイアログは、とても簡単で、XUL を使用して実装することほど難しくありません。また、複雑な事情もあります。ダイアログの位置やボタンがオペレーティングシステムごとに異なります。細かいことですが、ウィンドウサイズやマージン、パディングがすべてのシステムで異なるため、ダイアログをスクラッチから書いたりダイアログのデフォルトの CSS スタイルを書き換えたりすることは避けてください。
dialog 要素は、これらをすべて透過的に扱います。必要なことは、ダイアログに必要なボタンと関連付けられた動作を定義することだけです。
<dialog id="xulschoolhello-hello-dialog" title="&xulschoolhello.helloDialog.title;" buttons="accept,cancel" ondialogaccept="return XULSchoolChrome.HelloDialog.accept();" ondialogcancel="return XULSchoolChrome.HelloDialog.cancel();" xmlns="https://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
dialog 要素の仕様を注意深く読んでください。幅広い様々なボタンを選ぶことができ、それらに必要な動作を関連付け、ラベルの書き換えや完全にカスタマイズされたボタンを追加できることが分かるでしょう。これらはすべて、オペレーティングシステムごとの外観の違いを気にせずに行えます。どのようなダイアログでも不変の規則が一つあります。OK ボタンやキャンセルボタンをクリックすると、関連付けられた関数が false を返さなくてもダイアログが閉じられます。特に、キャンセルボタンがクリックされた時に false を返してはいけません。一般に、ダイアログは簡単に閉じられなければなりません。
ダイアログを固定サイズにしてはいけません。潜在的なローカライズの問題を引き起こします。ダイアログのサイズは、その内容によって最適なサイズに合わせられます。しかしながら、ダイアログの内容があなたのコードによって動的に生成されたり引き伸ばされたりする場合は、ダイアログを適切なサイズに変更する必要があるでしょう。この場合は、window.sizeToContent 関数を使用してください。
入力コントロール
拡張機能で追加されるほとんどの XUL ウィンドウやダイアログには、ちょっとした入力フォームがあります。よく使用されるフォーム要素とその XUL ウィンドウでの使用方法を見ていきましょう。XUL チュートリアルに補足する必要のあるフォームの説明はそれほど多くありません。まずは、以下のリンク先のセクションを読んでください:
以下のセクションでは、入力コントロールを扱うときに考慮すべきその他の点を扱います。
グループボックス
groupbox 要素は、簡単に理解できるでしょう。これは、XUL コントロールをまとめてグループ化し、コンテンツの周りを視覚的な境界線でスタイル付けする box コンテナです。グループ化されているものが一目でわかるでしょう。また、グループ化された要素にタイトルを付ける caption 要素がこの要素と共によく使用されます。
groupbox は、見た目を整えるための要素ではなく、論理的なものです。境界線だけが必要な場合は、CSS を使用してください。groupbox 要素は、囲まれた要素が同じ機能を共有していることを示し、同じウィンドウ内の他の要素やグループから分けるために使用されます。またアクセシビリティ機能にも役立ちます。スクリーンリーダは、コンテンツ内のテキストを読み上げる前にキャプションを読み上げるでしょう。境界線を描画したくないときは、CSS を使用してスタイルを変更してください。Firefox の設定ウィンドウに、この例があります。セクションが groupbox を使用して定義されていますが、デフォルトのスタイルとは多少異なります。
属性値の永続性
リストボックスからのオプションの選択やテキストボックスへのテキストの入力など、ユーザの操作によってウィンドウの状態が変更されます。ユーザがそのウィンドウを閉じて再び開いた場合、すべてのコントロールはデフォルトにリセットされます。これは、望まれた動作ではないでしょう。何らかの方法でユーザが変更した属性の値を記憶させておき、ウィンドウを開き直しても前回の状態が読み込まれるようにする必要があります。
ほとんどの XUL 要素は、この場合に相応しい persist 属性をサポートしています。persist 属性にスペースで区切られた属性名のリストを設定すると、ウィンドウの "セッション" を超えて、その属性値が維持されます。
<checkbox id="xulschoolhello-some-checkbox" label="&xulschoolhello.someText.label;" checked="false" persist="checked" />
persist 属性を動作させたいときは、必ず、その要素に id 属性を設定しなければなりません。document.persist 関数を使用して永続性をプログラム内で設定することもできます:
document.persist("xulschoolhello-some-checkbox", "checked");
永続化されたデータは、ユーザプロファイルの localstore.rdf ファイル内に格納されます。あなたの拡張機能で永続性をテストする時は、このファイルを変更するか削除する必要があるでしょう。
フォーカスとタブ
キーボードだけでウィンドウ内のすべての入力コントロールへ移動できるようにすることが、アクセシビリティを確保するために必要です。ほとんどの Firefox ウィンドウでは、Tab キーを押すことで移動できます。Tab キーを押すごとにウィンドウ内の次のコントロールへフォーカスが移動します。
一般的には、キーボードによるフォーカスのためにする必要なことは何もありません。Firefox は、自動的にウィンドウ内の最初の入力コントロールへフォーカスを移動し、Tab キーが押されると、XUL ドキュメント内で見つかった次のアイテムにフォーカスを移動します。とても複雑なレイアウトにしたい場合やカスタマイズされた Tab キーの振る舞いが必要な場合は、コントロールに tabindex 属性を設定してください。また、ウィンドウの読み込みなどのイベントに応じて要素にフォーカスを移動するために focus 関数を使用することもできます。フォーカスの移動を変更するときは、アクセスできないコントロールが無いように注意してください。
通常はフォーカスを受け取らない要素へのフォーカスを有効にするために、CSS プロパティの -moz-user-focus が使用できます。ただし、このような変更は控え目にしてください。
This tutorial was kindly donated to Mozilla by Appcoast.