menu 要素

4.11.4 menu 要素

カテゴリー:
フロー・コンテンツ
この要素の type 属性が toolbar 状態にある場合: インタラクティブ・コンテンツ
この要素の type 属性が toolbar 状態、または、list 状態にある場合: パルパブル・コンテンツ
この要素を使うことができるコンテキスト:
フロー・コンテンツが期待される場所
コンテンツ・モデル:
0 個以上の li 要素、または、
フロー・コンテンツ、のいずれか
コンテンツ属性:
グローバル属性
type
label
DOM インタフェース:
interface HTMLMenuElement : HTMLElement {
           attribute DOMString type;
           attribute DOMString label;
};

menu 要素は、コマンドのリストを表します。

type 属性は列挙属性で、宣言されているメニューの種類を示します。この属性は 3 つの状態を持ちます。context キーワードは、context menu 状態に相当し、この要素はコンテキスト・メニューであると宣言するものです。toolbar キーワードは、toolbar 状態に相当し、この要素はツールバーであると宣言するものです。この属性は省略することもできます。省略された場合のデフォルトlist 状態となり、この要素はただ単にコマンドのリストに過ぎず、コンテキスト・メニューを宣言するものでも、ツールバーを定義するものでもありません。

menu 要素の type 属性が context menu 状態にあるなら、この要素はコンテキスト・メニューのコマンドを表します。ユーザーは、そのコンテキスト・メニューが有効となっているなら、そのコマンドを実行することができます。

menu 要素の type 属性が toolbar 状態にあるなら、この要素は、ユーザーがすぐに実行することができる有効なコマンドのリストを表します。

menu 要素の type 属性が list 状態にあるなら、この要素は非順序の項目リストを表します(それぞれの項目は li 要素で表されます)。それぞれの項目は、ユーザーが実行したり、有効化することができるコマンドを表します。この要素の子要素に li 要素がなければ、利用可能なコマンドを説明するフロー・コンテンツを表します。

label 属性は、メニューのラベルを与えます。これは、ユーザーエージェントが UI でネストされたメニューを表示するために使われます。例えば、コンテキスト・メニューに、もう一つメニューを含んでいる場合、ネストされたメニューの label 属性を、サブメニューのラベルに使うでしょう。

typelabel IDL 属性は、それぞれ、同じ名前の対応するコンテンツ属性を反映しなければいけません。

このセクションは非規定です。

menu 要素は、コンテキスト・メニューやツールバーを定義するために使われます。

例えば、次は 3 つのメニューボタンを伴ったツールバーを表します。それぞれのボタンには、一連の選択肢を伴ったドロップダウン・メニューがあります:

<menu type="toolbar">
 <li>
  <menu label="File">
   <button type="button" onclick="fnew()">New...</button>
   <button type="button" onclick="fopen()">Open...</button>
   <button type="button" onclick="fsave()">Save</button>
   <button type="button" onclick="fsaveas()">Save as...</button>
  </menu>
 </li>
 <li>
  <menu label="Edit">
   <button type="button" onclick="ecopy()">Copy</button>
   <button type="button" onclick="ecut()">Cut</button>
   <button type="button" onclick="epaste()">Paste</button>
  </menu>
 </li>
 <li>
  <menu label="Help">
   <li><a href="help.html">Help</a></li>
   <li><a href="about.html">About</a></li>
  </menu>
 </li>
</menu>

対応ブラウザでは、次のように表示されるでしょう:

A toolbar with three buttons, labeled 'File', 'Edit', and 'Help'; where if you select the 'Edit' button you get a drop-down menu with three more options, 'Copy', 'Cut', and 'Paste'.

古いブラウザでは、3 つの項目を伴った黒丸付きのリストのように見えるでしょう。最初の項目には 4 つのボタンが、2 つ目の項目には 3 つのボタンが、3 つ目の項目には、リンクから構成される項目を伴った黒丸が 2 つネストされるでしょう。


次では類似のルールバーを実装しています。選択した値に応じてウェブ・サイトにユーザーをリダイレクトするボタンが一つあります。

<form action="redirect.cgi">
 <menu type="toolbar">
  <label for="goto">Go to...</label>
  <menu label="Go">
   <select id="goto">
    <option value="" selected="selected"> Select site: </option>
    <option value="http://www.apple.com/"> Apple </option>
    <option value="http://www.mozilla.org/"> Mozilla </option>
    <option value="http://www.opera.com/"> Opera </option>
   </select>
   <span><input type="submit" value="Go"></span>
  </menu>
 </menu>
</form>

対応ブラウザにおけるビヘイビアは、前述の例に似ていますが、ここでは、古いブラウザのビヘイビアは、サブミット・ボタンを伴った select 要素ひとつから構成されます。このサブミット・ボタンは、ツールバーには現れません。なぜなら、そのボタンは、menu 要素、または、その子である li 要素の直下の子ではないからです。

4.11.4.2 メニューとツールバーの生成

メニュー(またはツールバー)は、0 個以上の次のコンポーネントのリストで構成されます:

  • コマンド, デフォルトのコマンドとしてマークすることができます。
  • セパレータ
  • 他のメニュー(ネストしたリストが可能です)

特定の menu 要素に相当するリストは、その子ノード上を反復することによって生成されます。ツリー順に取り出されたそれぞれの子ノードに対する必須の挙動は、そのノードが何かに依存します。それは次の通りです:

コマンドを定義する要素
メニューにコマンドを追加しますが、そのファセット(これは http に由来したプライバシーに関するものでしょう)に合わせます。そして、そのイメージをコマンドに関連付けるべきです。そのようなコマンドそれぞれに対して、そのイメージを一度だけフェッチします。これは、そのイメージが一度フェッチされた後、ベース URL が変更されても影響を受けないようにするためです。(Icon ファセットを解決する必要はありません。それは絶対 URL です。)-->.
hr 要素
value 属性に空文字列がセットされ、disabled 属性を持ち、その textContent が一つ以上のハイフン (U+002D HYPHEN-MINUS) から成る option 要素
メニューにセパレータを追加します。
li 要素
label 要素
この要素の子要素上を反復します。
label 属性を持たない menu 要素
select 要素
メニューにセパレータを加え、子要素のうち menu 要素または select 要素上を反復します。それから、もう一つセパレータを加えます。
label 属性を持つ menu 要素
label 属性を持つ optgroup 要素
メニューにサブメニューを加えます。この要素の label 属性をメニューのラベルとして使います。サブメニューは、その要素を使って新しいメニューを生成することで構築されなければいけません。この完全な手順はこのセクションで説明します。
その他のノード
そのノードを無視します。

前述の処理が全てのノードに対して終了したら、ユーザーエージェントは、下記の通り、該当のメニューに後処理を施さなければいけません:

  1. セパレータを除いて、ラベルがない、または、ラベルが空文字列のメニュー項目を削除しなければいけません。
  2. 1 行に 2 つ以上連続したセパレータがあれば、それを一つにまとめなければいけません。
  3. メニューの最初と最後のセパレータを削除しなければいけません。
4.11.4.3 コンテキスト・メニュー

contextmenu 属性は、その要素のコンテキスト・メニューを与えます。この値は DOM における menu 要素の ID でなければいけません。この属性値を引数にして getElementById() メソッドを呼び出して得られたノードが null または menu 要素でないなら、その要素には、割り当てコンテキスト・メニューを持ちません。そうでなければ、この要素の割り当てコンテキスト・メニューは、そう認識された要素となります。

要素のコンテキスト・メニューがリクエストされたとき(例えば、ユーザーが要素を右クリックしたり、コンテキスト・メニュー・キーを押したとき)、ユーザーエージェントは、次のリストから適切な規則を適用しなければいけません:

ユーザーがポインティング・デバイスを使ってコンテキスト・メニューをリクエストした場合

ユーザーエージェントは、メニューがリクエストされた要素で contextmenu という名前のイベントを発出しなければいけません。これはバブリングしキャンセル可能です。そして、MouseEvent インタフェースを使います。このイベントのコンテキスト情報は、コンテキスト・メニューのリクエストとして解釈されたジェスチャーの一部として発出された最後の MouseEvent ユーザー・インタラクション・イベントと同じ値にセットされなければいけません。

そうでなければ

ユーザーエージェントは、メニューがリクエストされた要素で contextmenu という名前の疑似マウス・イベントを発出しなければいけません。これはバブリングし、キャンセル可能です。

ゆえに、通常は、contextmenu イベントの発出は、mouseupkeyup イベントのデフォルト・アクションとなるでしょう。イベントの正確なシーケンスはユーザーエージェントに依存しますが、プラットフォームの慣例に基づいて異なってくるでしょう。

contextmenu イベントのデフォルト・アクションは、この要素、または、その祖先にコンテキスト・メニューが(contextmenu 属性を使って)割り当てられているのかそうでないのかに依存します。もしコンテキスト・メニューが割り当てられていなければ、そのデフォルト・アクションは、デフォルトのコンテキスト・メニューがあるのであれば、それを見せることです。

この要素、または、その祖先の一つにコンテキスト・メニューが割り当てられているなら、ユーザーエージェントは、コンテキスト・メニューが割り当てられている祖先のうち直近のコンテキスト・メニューの menu 要素(自分自身の要素も含む)で、show という名前のシンプルなイベントを発出しなければいけません。

このイベントのデフォルト・アクションは、menu 要素から構築したコンテキスト・メニューをユーザーエージェントが表示することです。

ユーザーエージェントは、デフォルトのコンテキスト・メニューがあれば、それへのアクセス手段を、すでに表示済みのコンテキスト・メニューとともに提供することも可能です。例えば、二つのメニューのメニュー項目をマージしたり、ページのコンテキスト・メニューをデフォルトのメニューのサブメニューとして提供することができます。

ユーザーが何も選択せずにメニューを閉じたら、特に何も起こりません。

ユーザーがコマンドを表すメニュー項目を選択したら、ユーザーエージェントは、そのコマンドのアクションを呼び出さなければいけません。

コンテキスト・メニューは、表示されている間は、DOM の変更を反映してはいません。それらは、show イベントのデフォルト・アクションとして構築され、閉じられるまでそのままにしておかなければいけません。

ユーザーエージェントは、コンテキスト・メニューの処理モデルをバイパスする手段を提供することができます。こうすることで、ユーザーはいつでも確実にユーザーエージェントのデフォルトのコンテキスト・メニューにアクセスすることができるようになります。例えば、Shift キーを押しながらの右クリックしたら、contextmenu イベントが発出されず、その代わりに、常にデフォルトのコンテキスト・メニューを表示する、といったことをユーザーエージェントはハンドリングすることができます。

contextMenu IDL 属性は、contextmenu コンテンツ属性を反映しなければいけません。

これは、入力コントロール用のコンテキスト・メニューの例です:

<form name="npc">
 <label>Character name: <input name=char type=text contextmenu=namemenu required></label>
 <menu type=context id=namemenu>
  <command label="Pick random name" onclick="document.forms.npc.elements.char.value = getRandomName()">
  <command label="Prefill other fields based on name" onclick="prefillFields(document.forms.npc.elements.char.value)">
 </menu>
</form>

これは、コントロールのコンテキスト・メニューに、"Pick random name"、"Prefill other fields based on name" という 2 つの項目を追加しています。これらは、上記の例には表示されてはいませんが、スクリプトを呼び出します。

4.11.4.4 ツールバー

menu 要素が toolbar 状態にある type 属性を持つとき、ユーザーエージェントは、その menu 要素に対してメニューを構築しなければいけません。そして、その結果をレンダリングに使わなければいけません。

ユーザーエージェントは、 menu の DOM に変更があったら、すぐに該当のメニューを再構築して、その変更を反映しなければいけません。


※ 原文:http://www.w3.org/TR/2012/CR-html5-20121217/interactive-elements.html#the-menu-element