新規メニューの追加
Firefox のメインメニューバーは 'main-menubar' という id を持っています。アプリケーションのメインメニューバーに新しいメニューを追加するには、このメニューバーに対してオーバーレイする必要があります。たとえば、
<menubar id="main-menubar"> <menu label="Search" insertbefore="tools-menu"> <menupopup> <menuitem label="Web"/> <menuitem label="Mail"/> </menupopup> </menu> </menubar>
このメニューはメインメニューバーのツールメニューの前に追加されます。新しいメニューが正しい位置に追加されるように、insertbefore
属性を 'tools-menu' に設定しています。メニューが <menupopup>
を持たない限りメニューは表示されないので注意してください。
新規メニューアイテムの追加
メニューのどれかに新しいアイテムを追加したい事があるかもしれません。これはアイテムを追加する要素にオーバーレイすることで可能になります。Firefox のメニューの id の一覧は、Firefox Menus を参照して下さい。たとえば、ツールメニューの最後にアイテムを追加するには次のようにします。
<menupopup id="menu_ToolsPopup"> <menuitem label="Thesaurus"/> </menupopup>
他の拡張機能が同じメニューの中に独自のアイテムを追加することがあるという事に注意してください。これが原因で、オーバーレイが適用される順番によっては、新しいアイテムがメニューの最後ではなく他の拡張機能が追加したメニューアイテムの前に追加される事があります。オーバーレイが適用される順番を予測する事はできないので、他の拡張機能が存在する場合にはメニューアイテムが特定の位置にあることを当てにするべきではありません。
コンテキストメニューの改変
拡張機能はブラウザ領域に関連付けられたコンテキストメニューを改変することがよくあります。通常は、このメニューは何がコンテキストクリックされたかや、何にフォーカスがあるかによって特定のメニューを表示します。たとえば、リンクに対してコンテキストメニューを開くと、リンクを新しいウィンドウやタブで開くアイテムや、リンクを保存したりブックマークするアイテムが表示されます。拡張機能はコンテキストメニューを改変することで、追加したメニューを常に表示させることも、特定のコンテンツが選択された時にのみ表示させることもできます。
Firefox では、Web ページを表示するブラウザ領域はコンテキストメニューを 1 つだけ持っています。コンテキストメニューのターゲットの種類によって別々のコンテキストメニューを使用するのではなく、ただ 1 つのコンテキストメニューを使って、ターゲットに対して適用できないアイテムは必要に応じて隠されるようになっています。したがって、この単一のメニューにオーバーレイすることで Firefox のコンテキストメニューにアイテムを追加できます。このコンテキストメニューの id は 'contentAreaContextMenu' です。この例では、Firefox のコンテキストメニューの最後に 1 つのアイテムを追加します。
<popup id="contentAreaContextMenu"> <menuitem id="thumbnail-show" label="View Thumbnail" oncommand="Thumbnails.view();"/> </popup>
menupopup 要素ではなく popup 要素を使用していることに注意してください。これは Firefox でこの要素が使用されているためです。
上のコードはコンテキストメニューの最後に新しいアイテムを追加します。コンテキストメニューの最後ではなく特定の位置にアイテムを設置したければ、insertbefore
もしくは insertafter
属性を使って id で指定された他のアイテムの前か後に挿入することができます。たとえば、次のコードは「すべて選択」コマンドのすぐ後にコマンドを挿入します。
<popup id="contentAreaContextMenu"> <menuitem label="Select Links" oncommand="Thumbnails.selectAllLinks();" insertafter="context-selectall"/> </popup>
Firefox Context Menu で Firefox のコンテキストメニューにあるアイテムの id の一覧を参照して下さい。
コンテキストメニューアイテムの表示非表示
追加したメニューアイテムをコンテキストによって表示したり隠したりするには、popupshowing イベントをリッスンするイベントハンドラを使用します。たとえば、画像がコンテキストクリックされた場合、追加したメニューアイテムが実行する操作が画像に対して適用できないものならば、それを非表示にしたいと思うかもしれません。
function init() { var contextMenu = document.getElementById("contentAreaContextMenu"); if (contextMenu) contextMenu.addEventListener("popupshowing", ThumbnailsShowHideItems, false); } function ThumbnailsShowHideItems(event) { var show = document.getElementById("thumbnail-show"); show.hidden = (document.popupNode.localName != "IMG"); }
ユーザがポップアップを開く前に popupshowing イベントハンドラを取り付けるため、関数 init は load イベントハンドラで呼び出すようにします。この例では、ポップアップが表示されようとする時に関数 ThumbnailsShowHideItems が呼ばれます。この関数は 'thumbnail-show' という id を持つ拡張機能が追加したメニューアイテムを取得し、コンテキストメニューのターゲットが画像でなければそれを隠します。document の popupNode プロパティはコンテキストメニューのターゲットを保持します。
コンテキストメニュー上のアイテムの表示非表示に関する詳細は、コンテキストによるメニューアイテムの表示非表示を参照して下さい。
どの要素がコンテキストクリックされたか判別する
どの要素がコンテキストメニューのターゲットか、つまりコンテキストクリックされた要素を判別する方法に関する一般的な情報はコンテキストとして何がクリックされたか判定するを参照して下さい。
Firefox は独自の popupshowing イベントリスナを使ってコンテキストメニューのアイテムを調整しています。これによりメニューは異なる種類のターゲットに対して異なるコマンドを持つことができます。ポップアップが開かれている間、グローバル変数 gContextMenu に Firefox のコンテキストメニュー固有の機能をすべて扱うオブジェクトが格納されます。具体的に言うと、このオブジェクトはコンテキストメニューのターゲットの種類を示すプロパティの集合によって初期化されます。たとえば、リンクがコンテキストクリックされると 'onLink' プロパティが true に設定されます。
手動で処理しようとすると大量のコードが必要となるような様々な特殊で複雑なケースを Firefox のコードがあらかじめ処理しているので、自分でターゲットの種類を判別するよりもこれらのプロパティを使用したほうがいいでしょう。次の表は最もよく使われるチェック可能なプロパティの一覧です。
target | コンテキストクリックされた要素。キーボードでコンテキストメニューを開いた場合は、フォーカスのある要素。 |
onTextInput | ターゲットがプレーンまたはパスワードタイプの input、textarea、または編集可能な領域ならば true。テキストの編集に関するコマンドを有効または無効にするのに使用できる。 |
onImage | ターゲットが画像なら true。 |
hasBGImage | 祖先要素が背景画像を持っていれば true。 |
onMathML | ターゲットが MathML 要素なら true。 |
onLink | ターゲットがリンクなら true。 |
onMailtoLink | ターゲットが E メールアドレスのリンク (mailto:) なら true。 |
linkURL | コンテキストクリックされたリンクの URL。 |
inFrame | フレーム内でコンテキストクリックされたなら true。 |
isTextSelected | テキストが選択されていれば true。 |
isContentSelected | テキストを含む何らかのものが選択されていれば true。 |
次の例では、ターゲットが画像かリンクでなければメニューアイテムは非表示になります。
function ThumbnailsShowHideItems(event) { var show = document.getElementById("thumbnail-show"); show.hidden = !(gContextMenu.onImage || gContextMenu.onLink); }