constructor(parent: HoverParent, targetEl: HTMLElement | null, waitTime?: number);
実は、コンストラクタ内では
this.parent.hoverPopover = this;
という操作は行われていない。この操作は onShow
メソッド内で行われる。つまり、実際に popover が表示されるタイミングで親の hoverPopover
プロパティにセットされるというわけだ。
hoverEl: HTMLElement
targetEl: HTMLElement | null
targetEl
が HTMLElement
の場合、コンストラクタ内で mouseout
イベントハンドラが追加される。これによって、ホバーが外れるとポップアップが消えるようになっている。
一方、targetEl
が null
の場合にはそのようなイベントハンドラはフックされないので、明示的に消そう (`hide`) としないとポップアップが消えないようにできる。
ただし、この場合でも hoverEl
にはイベントハンドラが追加される。Quick Preview においてパッと見これが働いているように見えないのはなぜだろうか?
waitTime: number
特に指定しないと 300
になる。
state
shownPos
初期化時は null
。
`show` メソッド内に
this.shownPos = P_,
this.position(P_),
という箇所がある。
P_
は F_
という関数でセットさせる。引数として渡されたイベントの clientX
, clientY
, doc
を P_
に記録する。F_
は、
onHoverLink
内で呼ばれるか、window
全体に対する mousemove
イベントハンドラとしてセットされる。onLinkHover
を直接読んだ場合は 1. の可能性はない。なるほど、それで Quick Preview でマウスを使って Suggestions > `setSelectedItem` したときにはマウスの位置にポップオーバーが追従していたのか。
mousemove
イベントも発火しない場合は?次は targetEl
があればそれに準じて位置が計算される。しかし今回はそれも null
である。この場合は、
t = {
top: 0,
bottom: 0,
left: 0,
right: 0
};
onShow
ひとつの HoverParent を親としてもつ HoverPopover のうち、実際に開いているものが高々 1 個に抑えられるようにする(これが HoverParent の目的)ための処理をしている。
if (this.parent.hoverPopover) this.parent.hoverPopover.hide();
this.parent.hoverPopover = this;
onHide
if (this.parent.hoverPopover === this) this.parent.hoverPopover = null;
show
this.targetEl
が存在して document.body
の一部である場合、
this.state
を Shown
に更新してthis.onShow
を呼んでthis.load
する。hide
this.state
を Hidden
に更新this.onHide
を呼ぶthis.unload
するposition
たぶん、このメソッドを monkey patch して、this.shownPos
に好きな {x: number, y: number}
をセットしてそれを old
の引数に渡すことでポップオーバーの表示位置をコントロールできると思う。