ひだまりソケットは壊れない

ソフトウェア開発に関する話を書きます。 最近は主に Android アプリ、Windows アプリ (UWP アプリ)、Java 関係です。

まじめなことを書くつもりでやっています。 適当なことは 「一角獣は夜に啼く」 に書いています。

XUL の menulist 要素内の menuitem 要素の画像を表示させる

Firefox (やその他 mozilla 製品) の UI 記述言語である XUL 周辺の話です。 XUL の menuitem 要素の画像がある条件下では表示されないので、それを表示したいなぁという話です。 基本的に Firefox 拡張開発を念頭において書いているので、別のアプリケーションではちょっと違っていたりするかもしれません。

本記事中の XML の各要素の名前空間は明示されていませんが、基本的に "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" の名前空間 URI に属していると思って読んでください。

menulist 要素内の menuitem 要素に画像が表示されない

コンテキストメニューやボタンなどをクリックしたときに出てくるポップアップメニューを表すための要素として、https://developer.mozilla.org/ja/docs/XUL/menupopup:menupopup 要素 があります。 そして、この要素の中の各項目を表すための要素として、menuitem 要素 があります。

menuitem 要素にはアイコン画像を付けることができます。 ドキュメントによれば、menuitem 要素の image 属性にアイコン画像の URI を記述し、クラスとして "menuitem-iconic" を指定すれば、アイコン画像が表示されるようになっています。

例えば、menu 要素内に menupopup 要素を入れた場合、以下のようにアイコン画像が表示されます。

<menu>
  <menupopup>
    <menuitem label="Hello World!" class="menuitem-iconic" image="hw_icon.png" />
  </menupopup>
</menu>

f:id:nobuoka:20130323213222p:plain

しかし、以下のように menulist 要素の中に menupopup 要素を入れた場合、選択された項目として表示されている部分には画像が表示されるものの、項目一覧のポップアップ中には画像が表示されませんでした。

<menulist>
  <menupopup>
    <menuitem label="Hello World!" class="menuitem-iconic" image="hw_icon.png" />
    <menuitem label="これは画像なし" />
  </menupopup>
</menulist>

f:id:nobuoka:20130323215328p:plain

menulist 要素内の menuitem 要素の画像は CSS で非表示にされている

そもそも XUL の構造的にどうなってるのかを DOM Inspector を使って調べてみると、下記画像のような感じになっていました。

f:id:nobuoka:20130323215723p:plain

詳しい仕組みは調べていませんが、mozilla のアプリケーション側が自動的に menu-iconic-left というクラス名の hbox 要素や menu-iconic-icon というクラス名を持つ image 要素を作っているようです。 これらの XUL の構造は、menu 要素の中の menuitem 要素でも menulist 要素の中の menuitem 要素でも違いはないようでした。

XUL の構造は同じなのになぜ見た目が違うのかというと、CSS でのスタイル指定が違っているからのようでした。 Windows 用 Firefox 20 beta のデフォルト CSS だと、menulist 要素内の menu-iconic-left というクラス名の hbox 要素には "display: none" のスタイル指定が適用されていました。 これでは当然アイコン画像は表示されません。

menulist 要素内の menuitem 要素の画像を表示するように CSS を書く

menulist menupopup .menuitem-iconic .menu-iconic-left {
  display: -moz-box;
  visibility: visible;
}

上のような感じで CSS を書いておけば、menu-iconic-left というクラス名の hbox 要素が表示されるはずなので、アイコン画像も表示されるようになるはずです。 Windows 環境だと以下のようになりました。 padding などは特にいじってないので、必要に応じていじるといいかもしれません。

f:id:nobuoka:20130323221839p:plain

また、Linux 環境でもちゃんと表示されました。 (visibility: visible というスタイル指定は、Linux 環境用。)

他にもっとちゃんとした方法があるのかもしれませんが、調べた限りでは他に良い方法はなさそうだったので CSS をいじるのが一番いいのかなーと思います。

関連情報