dropbox から返答があり、無事承認された。
* * *
で。
自動的に起動した wasavi が、これまた自動的に終了するには 2 つの方法がある。まず、ユーザが明示的に wasavi から他の要素にフォーカスを移した場合。これはフォーカス可能な要素に限らず、単に body をクリックした場合も含まれる。いずれにしても、wasavi がフォーカスを失う時点での編集内容が textarea に反映され、wasavi は終了する。フォーカスはユーザが指定した要素にある。
次に、wasavi の起動中にコマンドモードで tab を押下した場合。この場合も wasavi のその時点の編集内容が textarea に反映され、wasavi は終了するのだが、前者との違いは、wasavi が拡張する対象となる textarea の次の tabindex を持つ要素にフォーカスされることだ。
つまり両者の違いは、wasavi の終了後にどの要素にフォーカスが移るかだ。前者は移行先要素をユーザが明示し、後者は暗黙的なので explicit deactivation と implicit deactivation と区別することができると思う。
で。
問題は、後者の implicit deactivation において、ある要素の、sequential focus navigation に沿った上での次の要素を求める手段が、標準的な API では提供されていないということだ。HTMLElement#nextFocusingElement みたいなのがあれば一発なんだけど。
sequential focus navigation というのは、PC 上のブラウザにおいては、tab キーを押すことで順繰りに、適当な要素にフォーカスが移っていく操作のことだ。適当な要素というのは、既定では
- href 属性を備えた a 要素
- href 属性を備えた link 要素
- disabled ではない button 要素
- disalbed ではなく、かつ type が hidden ではない input 要素
- disabled ではない select 要素
- disabled ではない textarea 要素
- disalbed ではない command 要素
- draggable 属性を備えた要素。ただし、ユーザーエージェントがポインティングデバイスを使うことなくドラッグ開始することを許可している場合
- エディティング・ホスト
- ブラウジング・コンテキスト・コンテナ
これに加えて、tabindex でインデックスが 0 と明示してある要素、および 0 以上の値が明示してある要素が sequential focus navigation の対象となる。前者は前後関係は文書順に従って自動的に決められるが、後者は順番は指定された tabindex に従う。
フォーカスを受け取れる要素は、以下の順になる:
- tabindex が 0 より大きい要素群(同一の tabindex では文書順)
- tabindex が無効な(指定されていないか、パース結果がエラーとなる)要素群
- tabindex が 0 以下と明示してある要素群
このうち sequential focus navigation は 1. と 2. の要素群が対象になる。
結局のところ、それらの要素群を抜き出し、wasavi の拡張対象となる要素を探し出し、その次の要素にフォーカスを移せばいい。
……すごく面倒くさいです! ブラウザ自身が持っている情報なのに、わざわざ javascript で算出するのはとても無駄です。