Popup ALT Attributes ALT属性のポップアップ表示の紹介

Mozilla.Party.jp 5.0のXULコンテスト用に作成した、ALT属性のポップアップ表示の資料です。

コンセプト

ツールチップ型のポップアップをささやかに改善する。

概要

Mozillaは初期状態では画像の代替文字列(alt属性の値)をポップアップ表示しません。これはHTMLの仕様としては問題ない動作ですが、実際にWeb上にある既存のWebサイトを閲覧する場合、Mozilla ClassicやInternet Explorerのように代替文字列がポップアップ表示されることを前提に(alt属性を説明文表示のためのものと勘違いして)作られたページに出くわすことも少なくないです。そのような場合に残念な思いをしなくて済むようにしたいというのが、当初の開発意図です。

今回アピールさせて頂きたいのは、名称からは外れた機能になってしまっていますが、長い内容を折り返して表示する機能についてです。これは画像の代替文字列だけでなく、その他の場面で表示されるポップアップについても効果があります。

Mozillaではポップアップの内容テキストが長くなった場合でもそのまま1行で表示してしまいますが、Internet Explorerでは適当なところで自動で折り返して表示してくれます。どうすればこれをXULで容易に再現できるだろうか、という実験的な意図がこの機能には込められています。

実装の方法

代替文字列のポップアップ表示

まずは名称にもなっている方の機能からご説明します。

MozillaのXULでは、<tooltip id="foobar"/>という要領で記述したtooltip要素のid属性を他の要素のtooltip属性に記述することで、その中の要素などをポイントしてしばらく待つとツールチップ型のポップアップが表示される、という機能があります。この時、popupshowingイベントをトリガーにして「どの要素の上でポップアップが表示されたか」を知ることができ、Mozillaではこの時に要素のtitle属性に記述されたテキストなどを取得して、場合に応じたポップアップを表示するようになっています。

この拡張機能はpopupshowingイベント発生時の処理に割り込んで、ポップアップが表示されたのがHTMLの中に埋め込まれた画像であればその代替文字列を取得して表示します。この処理自体はごくごく単純なもので、特筆するようなことは特にないです。

なお、画像でなかった場合や代替文字列がない場合などは、割り込みを終了してMozillaの元々の処理を続けます。

長いテキストの自動折り返し

名称になっている機能の処理が単純なのに比べて、ポップアップの自動折り返しについては少々ややこしいことをしています。

tooltip要素は、label属性に設定したテキストが内部のlabel要素(HTMLのlabelとは別物です)のvalue属性の値に代入されて、そのままポップアップの内容として表示されます。つまり、tooltip要素のlabel属性に書かれたテキストがポップアップ表示されるということです。

label要素は使い方が二つあります。一つはvalue属性に文字列を設定するもので、文字列が長くなっても折り返しはされません。Mozillaのポップアップが折り返されないのはこの制約によるものです。

もう一つの使い方は、HTMLの要素のように開始タグと終了タグの間に文字列を書く、つまり、label要素にテキストノードの子を持たせるというもので、この場合は文字列が長くなるとウィンドウの右端で折り返されます。この拡張機能は、value属性の値として書かれたテキストを自動的に要素の内容に置き換えることで、ポップアップの自動折り返しを実現しています。

この拡張機能はtooltip要素の属性が変更されたことをDOMAttrModifiedイベントで検知して、変更されたのがlabel属性であった場合(つまり、ポップアップするテキストが設定された時)、その値を取得して新しいテキストノードを作り、tooltip要素内部のlabel要素の子要素として挿入します。後は、ポップアップが表示されれば全体の幅が適当に計算されて、それに合わせてテキストも折り返し表示されるという寸法です。

ただ、開発環境では残念ながら、これだけでは正常に機能しませんでした。何故か表示されるポップアップの高さが1行分にしかならず、2行目以降が隠れてしまうのです。 試しにgetComputedStyle()メソッドで表示中のポップアップの「高さ」の値を調べてみたところ、内部的には正しい高さが取得できたので、レンダリング時の問題でそれが反映されていないらしいということが分かりました。そこでこの拡張機能では、ポップアップが表示されて「適切な高さ」が計算されたタイミングで(タイマーで0ミリ秒後に処理を送らせるだけでよいです)、その値を取得し改めて「ポップアップの高さ」として設定し直すことにより、ポップアップを強制的に正しいサイズで表示させるようにしています。

おわりに――今後の展望

ツールチップ型のポップアップをより高機能なものにするという試みには、Safari風のポップアップを表示するようにする「Nice Titles」や、XULアプリケーションではないですが、Webページに埋め込んだスクリプトによってIEやMozilla向けにサムネイルなども含めたポップアップを提供する「あれこれポップアップ」(ありみかさとみ氏)などがあります。

この拡張機能における実験は、これらの例と組み合わせてより高機能なポップアップを実装する上での手がかりになると思います。余力があれば自分でも取り組んでみたいテーマではあるのですが、現在の所は他の拡張機能(特にタブブラウザ拡張)の開発で手一杯という感があり、手を付けられずにいます。私の制作しているXULアプリケーションは全てオープンソースライセンスのGPL/MPLで公開しており、ソースコードの閲覧も流用も自由にして頂いて構いませんので、「それではいっちょ」とやって下さる方が現れてくださることを切に願う次第です。