Closed5

React Developer Tools の要素選択機能がどういう実装になっているのか調べる

Atsushi TanakaAtsushi Tanaka

Why

アイコンを押すと id attribute が付いた DOM 要素を選択してコピーなりジャンプなりできるというブラウザ拡張機能 https://github.com/bgpat/anchor-selector を開発している。

現状の選択機能はページ全体のスクロールには対応しているけど overflow 要素のスクロールには対応できていない。
React Developer Tools ではスクロールに対応できていることに気付いたので参考にしたい。

↓こういうスクロールバーが付いている要素

Atsushi TanakaAtsushi Tanaka

anchor-selector の実装

選択対象を視覚化するために body 要素の一番後に overlay container を挿入している。

overlay container が表示されているときはクリックやポインタ移動等のマウス操作は全て overlay container が吸収するので本来の Web ページの処理は実行されないようになっている。
スクロールだけは透過したいけど pointer-events: none だと他のマウス操作も透過してしまうので使うのを諦めた。

Atsushi TanakaAtsushi Tanaka

React Developer Tools の実装

こちらも body 要素の末尾に選択用の div 要素を挿入している。

pointer-events: none が付いている。

これだとクリックが透過されてしまうのでどこかでキャプチャしているはず。
ということでそれっぽいコードを見つけた。
https://github.com/facebook/react/blob/cae635054e17a6f107a39d328649137b83f25972/packages/react-devtools-shared/src/backend/views/Highlighter/index.js#L44-L50

click, mousedown, mouseover, mouseup, pointerdown, pointerover, pointerup に対してそれぞれ event.preventDefault()event.stopPropagation() を実行していた。
window に対して capture = trueaddEventListerner しているので window 以外の DOM 要素はイベントを受け取らないようになる。
mousewheel は含まれていないのでスクロールはできる。

pointerdown で選択時の処理、 click で選択終了の処理をしている。
クリックしながら移動させても最終的に選択されている要素にフォーカスが当たればいいので pointerdown でいいっぽい。

Atsushi TanakaAtsushi Tanaka

anchor-selector で真似するときはクリップボードとか history を汚染しそうなので確定させるのは click のタイミングにするのがよさそう。

このスクラップは2022/02/28にクローズされました