Firefox 3 でのポップアップ仕様変更

Firefox 3 (Gecko 1.9) では XUL ポップアップの仕様が大幅に変更される。
Neil’s Place » Blog Archive » XUL Popup Improvements

特に注意すべき点

  1. popup 要素は非推奨となり、その代わりにまったく等価な menupopup 要素を使用することが推奨されている。
  2. panel という汎用のポップアップ型要素が新たに追加される。子に menuitem を配置するなら menupopup 、それ以外の色々なUI部品を配置したければ panel 、というふうに使い分ける。
  3. showPopup メソッドが非推奨となり、代わりに openPopup と openPopupAtScreen メソッドが追加される。
  4. state プロパティが追加され、ポップアップが現在開いているか、閉じているかなどが判別可能になる。
  5. ポップアップを開く動作が非同期的なイベントになる。したがってポップアップが開いた直後に何らかの処理をしたければ、 popupshown イベントハンドラを使用する必要がある。
  6. popup / menupopup 要素の見た目がOSネイティブな見た目になる。

openPopup / openPopupAtScreen メソッド

showPopup メソッドは引数の指定方法がわかりにくく混乱を招いていたが、 Firefox 3 で新たに追加される2つのメソッドは、スクリーンに対する絶対位置へポップアップを開くための openPopupAtScreen と、ある要素に対する相対位置へポップアップを開くための openPopup というように明瞭化されている。
例1) スクリーン上の位置 (100, 200) にポップアップ popupElt を開く

Firefox 2
document.popupNode = null;  // 位置ズレ防止
popupElt.showPopup(document.documentElement, 100, 200, "popup", null, null);
Firefox 3
popupElt.openPopupAtScreen(100, 200, false);

例2) 要素 aAnchorElt の左下にポップアップ popupElt を開く

Firefox 2
popupElt.showPopup(aAnchorElt, -1, -1, "popup", "bottomleft", "topleft");
Firefox 3
popupElt.openPopup(aAnchorElt, "after_start", 0, 0, false, true);

openPopup メソッドの第5引数 isContextMenu はコンテキストメニューかどうかを示す。しかし、コンテキストメニューにした場合、実際にどのような変化が現れるのかは不明。 openPopup メソッドの第6引数 attributesOverride は position 属性をメソッドの第2引数で上書きするかどうかを示す。

state プロパティ

nsIPopupBoxObject#popupState プロパティへのエイリアス。
Firefox 2 では特定のポップアップが開いているか否かという状態を調べるためには popupshowing や popuphidden などのイベントを監視して自前のフラグを管理したりする必要があったが、そういった苦労は state プロパティで一気に解消される。

state プロパティの値 意味
showing ポップアップは開く途中である。 popupshowing イベント発生時はこの状態。
open ポップアップは開いている。 popupshown イベント発生後はこの状態。
hiding ポップアップは閉じる途中である。 popuphiding イベント発生時はこの状態。
closed ポップアップは閉じている。 popuphidden イベント発生後はこの状態。

ポップアップの非同期的な動作

例えば以下のようなコードを実行すると Firefox 2 では「123」の順番で出力されるが、 Firefox 3 では「132」の順番になる。

XUL
<menupopup id="testPopup" onpopupshowing="dump('1');" onpopupshown="dump('2');"> ...
JavaScript
document.getElementById("testPopup").showPopup( ... ); dump('3');

他には?

nsIPopupBoxObject#enableKeyboardNavigator について、現段階 (Minefield 3.0a8pre) では実行すべきタイミングや得られる効果が Firefox 2 と異なる。効果が逆なのは明らかにバグなのでBug 279703のコメントに書いたところ、Bug 396517としてパッチも提供されてチェックイン間近となっている。なお、代替として ignorekeys 属性を使用することが推奨されており、こちらの動作は問題ない。

nsIPopupBoxObject#enableRollup について、現段階 (Minefield 3.0a8pre) では何もしない
代わりに、新しく追加された setConsumeRollupEvent を使うことで Windows + Minefield 3.0a8pre では期待通りの動作結果が得られた。しかし Linux + Minefield 3.0a8pre では効果がない模様?これも詳細を調べ中。

また、C++レベルでの内部的な実装が一新されたことに伴い、ポップアップの位置ズレやサイズ不正、クラッシュバグ、複数のポップアップを開いたときに閉じられなくなることがあるバグなど、多くのバグが解消されているようだ。

関連リンク

mozilla mozilla/toolkit/content/widgets/popup.xml
mozilla mozilla/layout/xul/base/public/nsIPopupBoxObject.idl
XUL:PopupGuide – MDC

TOP

TOP