16

Click here to load reader

TabScope 苦労話

  • Upload
    gomita

  • View
    168

  • Download
    3

Embed Size (px)

DESCRIPTION

Tab Scope苦労話苦労話1ポップアップを閉じるタイミング閉じない閉じる閉じる閉じる当初の実装 browserポップアップに対する mouseoutイベントを監視 通常mouseout時の event.relatedTargetから マウスがどの要素へ逃げ たかを調べることが可能 relatedTargetがbrowser 要素だったらポップアップ を閉じればよいだろうif (event.relatedTarget && event.relatedTarget.localName == "browser") this.hidePopup();こんな場合はうまくいかない①mouseoutした先がプラグインこんな場合はうまくいかない②mouseoutした先がFirefoxのウィンドウの外こんな場合はうまくいかない③ そもそもLinuxではrelatedTargetがnull  WindowsでもFirefox3ではnullそこで… event.relatedTargetに加えて

Citation preview

Page 1: TabScope 苦労話

Tab Scope苦労話

Page 2: TabScope 苦労話

苦労話1

Page 3: TabScope 苦労話

ポップアップを閉じるタイミング

閉じる 閉じる

閉じる

閉じない

Page 4: TabScope 苦労話

当初の実装

browser

ポップアップに対するmouseoutイベントを監視

通常mouseout時のevent.relatedTargetからマウスがどの要素へ逃げたかを調べることが可能

relatedTargetがbrowser要素だったらポップアップを閉じればよいだろう

if (event.relatedTarget && event.relatedTarget.localName == "browser")this.hidePopup();

Page 5: TabScope 苦労話

こんな場合はうまくいかない①

mouseoutした先がプラグイン

Page 6: TabScope 苦労話

こんな場合はうまくいかない②

mouseoutした先がFirefoxのウィンドウの外

Page 7: TabScope 苦労話

こんな場合はうまくいかない③

そもそもLinuxではrelatedTargetがnull

WindowsでもFirefox 3ではnull

Page 8: TabScope 苦労話

そこで…

event.relatedTargetに加えて

マウスの座標によるダブルチェック

Page 9: TabScope 苦労話

event.relatedTargetがnullでない場合

event.relatedTargetと(その祖先)を調べる

var rel = aEvent.relatedTarget;while (rel) {

// タブまたはポップアップなら何もしないif (rel == this._tab || rel == this)

return;rel = rel.parentNode;

}// それ以外ならポップアップを閉じるthis.abort();return;

}

Page 10: TabScope 苦労話

event.relatedTargetがnullだった場合

マウスの座標(event.screenX, event.screenY)を調べる

マウスの座標が要素aElement内かどうかを調べる関数<method name="_isEntering">

<parameter name="aEvent" /><parameter name="aElement" /><body><![CDATA[var x = aElement.boxObject.screenX;var y = aElement.boxObject.screenY;if (x < aEvent.screenX && y <= aEvent.screenY &&

aEvent.screenX < x + aElement.boxObject.width && aEvent.screenY <= y + aElement.boxObject.height) {return true;

}return false;]]></body>

</method>

if (this._isEntering(aEvent, this) || (this._tab && this._isEntering(aEvent, this._tab)))return;

this.abort();

Page 11: TabScope 苦労話

苦労話2

Page 12: TabScope 苦労話

ポップアップとツールチップOSによって動作が異なる

ポップアップ popup.showPopup(tab, -1, -1, "popup", "topleft", "bottomleft");

ツールチップ popup.showPopup(tab, -1, -1, “tooltip", "topleft", "bottomleft");

Page 13: TabScope 苦労話

Linuxにおけるポップアップ問題点

ポップアップ外のクリックイベントが奪取される

一回目のクリックではポップアップを閉じるだけ

その対策

ポップアップの代わりにツールチップにしたら、クリックイベントが奪取されなくなった

Page 14: TabScope 苦労話

Windowsでのツールチップ問題点

ツールチップ内のbutton, toolbarbutton要素など

透明な壁にさえぎられてクリック不可

ツールチップ内のmenuitem要素

透明な壁をすり抜けてクリック可能

「透明な壁」はDOMのレイヤーよりも上?

ツールチップには外側へマウスが移動したときに自動で閉じる仕組みがXBLで実装されている

Tab Scopeでは閉じるタイミングが特殊であり、自前で実装すべき

Page 15: TabScope 苦労話

試行錯誤

Windowsにおけるツールチップ問題点は解

決不能

Linuxにおけるポップアップ問題点は以下で

解決されたpopup.popupBoxObject.enableRollup(false)

しかし再びWindowsでポップアップ内のボタ

ン要素などがクリックできない問題点が再発

Page 16: TabScope 苦労話

結論

ツールチップではなくポップアップ popup.showPopup(tab, -1, -1, "popup", "topleft", "bottomleft");

LinuxのみenableRollup(false) if (navigator.platform.indexOf("Linux") == 0)

popup.popupBoxObject.enableRollup(false);

しかし、今度はMacで正常動作しない?