このセクションでは、コマンドの状態を、タイムリーに更新する方法について見ていきます。
コマンドの起動
コマンド (
) に command
属性が与えられている場合は、コマンドか、そのコマンドに結びつけられた要素に対して oncommand
メソッドを呼び出すことによりコマンドを起動できますが、 それ以外の場合は、起動するために数行のコードが必要になります。 コントローラとして実装されたコマンドを起動するためには、この追加の手順を踏む必要があります。 具体的には、独自のメニューコマンドを作成する場合、 例えば、実際のアプリケーションを開発するときに、編集メニュー用のコマンドを実装するような場面で、この手順が必要になると思います。doCommand
幸い、この追加コードは非常に簡単です。 必要なことは、使用するコントローラを取得してコマンドを呼び出すだけです。 簡単に記述した例を以下に示します。
var controller = document.commandDispatcher.getControllerForCommand("cmd_paste"); if (controller && controller.isCommandEnabled("cmd_paste")){ controller.doCommand(command); }
上のコードでは、まず、コマンドディスパッチャから「cmd_paste」コマンドに対するコントローラを取得しています。 次に、コマンドが有効かどうかをチェックし、有効な場合は、コントローラの doCommand
メソッドを使って、コマンドを実行します。 このとき、どの要素、あるいは、どのコントローラを利用すべきかについては、コマンドディスパッチャの方で考慮しているため、呼び出し側では意識する必要がないことを補足しておきます。 また、ほとんどの場合でするべきではないことですが、 コマンドが有効かどうかをチェックせずに、単に doCommand
を呼び出しても、かまわないことになっています。
上のコードを、コマンドを引数として渡せば、そのコマンドを実行するように関数化すれば、十分な汎用性を持たせることができます。 関数化しておけば、どんなコマンドを起動する場合にも、そのまま再利用が可能です。 実際、この関数は共通コードとして十分な機能なので、同じものが Mozilla のライブラリにも含まれています。 ライブラリの方の関数を使うためには、XUL ファイルから、スクリプト「chrome://global/content/globalOverlay.js」を読み込んでおき、 実行したいコマンドを引数で渡して、goDoCommand
メソッドを呼び出します。 この関数のコードは、上記のものより若干長いだけなので、何かの理由でライブラリ全体を読み込みたくない場合は、このコードだけを直接、開発中のコードに取り込んでもかまわないと思います。
<script src="chrome://global/content/globalOverlay.js"/> <command id="cmd_paste" oncommand="goDoCommand('cmd_paste');"/> <button label="Paste" command="cmd_paste"/>
上の例では「貼り付け」ボタンを実装しています。 このボタンはコマンド要素に結びつけられています。 このコマンド要素は、ボタンから呼び出されたときに、必要なコントローラを探して、そこに実装されたコマンドを起動することになります。 上記のコードは、アプリケーションに「貼り付け」コマンドを作る場合に、機能面で実装するべきの内容の全てになります。 それ以外に必要なことは、「貼り付け」コマンドつまりボタンについても、有効か無効かを、以下に示すような方法によって、タイムリーに更新されるようにするだけです。
コマンドアップデータ
コマンドアップデータは
要素に追加された機能で、指定されたイベントが発生したときに、1 つ、もしくは複数のコマンドの、有効かどうかの状態を更新します。 この機能を使用する場合、開発者は、コマンドがいつ有効になり、いつ無効になるのかを考えておく必要があります。 つまり、状態が変更されるタイミングと、コマンドを更新するべきタイミングを検討する必要があります。commandset
例えば、貼り付けコマンドは、テキスト入力欄がフォーカスを得ていて、かつ、クリップボード内に、貼り付け可能なものがあるときにのみ有効です。 このため、コマンドは、テキスト入力欄がフォーカスを得ている間に、クリップボードの内容が変化したときに有効 (または無効) になる可能性があります。 コマンドアップデータは、上記の状況が満たされるタイミングを監視しており、 状況が満たされたときに、コマンドの有効状態を更新するために必要なコードを実行させることが可能です。
以下に、単純なコマンドアップデータの例を示します。
<commandset id="updatePasteItem" commandupdater="true" events="focus" oncommandupdate="goUpdateCommand('cmd_paste');"/>
コマンドアップデータは、
属性を使用して指示されます。 このとき、属性値としては commandupdater
true
を設定する必要があります。
属性は、コマンドアップデータが監視するイベントのリストを設定するために使用されます。 イベントが複数の場合、コンマで区切って指定できます。 上の例では、コマンドアップデータは フォーカスイベントを監視しています。 これによって、要素がフォーカスを得たときにコマンドが更新されることになります。events
フォーカスイベントが発生したとき、
属性に指定されたコードが呼び出されます。 この例では、前に述べたスクリプト globalOverlay.js に含まれている oncommandupdate
goUpdateCommand
メソッドが呼び出されます。 このメソッドは、コマンドを更新し、コマンドと結び付けられたボタンやメニュー項目は、それに応じて有効または無効になります。 このメソッドのコードは単純なものです。 必要なコントローラを得て、その isCommandEnabled
メソッドを呼び出し、その結果からコマンドを有効化または無効化します。 複数のコマンドを更新したい場合は、それぞれのコマンドに対して、goUpdateCommand
メソッドを呼び出すようにします。
コマンドアップデータは、すべての要素に対する、すべてのフォーカスイベントについて、他のイベントハンドラが応答した場合でさえも、通知を受けることに注意して下さい。 本質的に、コマンドアップデータは、大域的なイベントハンドラと類似しています。
コマンドアップデータが反応することが可能なイベントを以下に示します。 必要なら、独自に作成することも可能です。
- focus: フォーカスを得ている要素が変更されたとき発生
- select: テキストの選択が変更されたとき発生
- undo: アンドゥ用のバッファが変更されたとき発生
- clipboard: クリップボードの内容が変更されたとき発生
以下の例は、Mozilla ブラウザで利用されている、編集メニューコマンドを更新するための、コマンドアップデータです。 使われている関数は、「chrome://communicator/content/utilityOverlay.js」で定義されています。
<commandset id="globalEditMenuItems" commandupdater="true" events="focus" oncommandupdate="goUpdateGlobalEditMenuItems()"/> <commandset id="selectEditMenuItems" commandupdater="true" events="select" oncommandupdate="goUpdateSelectEditMenuItems()"/> <commandset id="undoEditMenuItems" commandupdater="true" events="undo" oncommandupdate="goUpdateUndoEditMenuItems()"/> <commandset id="clipboardEditMenuItems" commandupdater="true" events="clipboard" oncommandupdate="goUpdatePasteMenuItems()"/>
次のセクションでは、オブザーバについて見ていきます。