thumbnail

chrome拡張からkeyboard操作をする方法

2022/05/02

とあるprojectにてchrome拡張でデバイスとBluetooth接続をして、そのデバイスから特定のサイトを操作する(物理キーボードの代わりにする)ことを行いました。

当初思っていたよりも実装が特殊だったのでその方法を共有します。

試した方法

keyEventの発火(ダメだった)

window.addEventListenerでKeyboardEventを監視してみると、キーを押したときのevent詳細が確認できます。

console
window.addEventListener('keyup', (e) => {
    console.log(e)
})

例) qを押したとき

console
KeyboardEvent {isTrusted: true, key: 'q', code: 'KeyQ', location: 0, ctrlKey: false, …}

とりあえずこれと同じeventをchrome拡張上から再現すれば拡張上からもキーボード操作ができるかと考えましたが、実際に操作はできませんでした。

console
window.dispatchEvent(new KeyboardEvent('keyup',{'key':'a'}));

例えばArrowDowndispatchEventしてもカーソル↓を押したときのようにページがスクロールされることはなく、 サイト側でaddEventListenerなどで各KeyboardEventごとの挙動を設定していないかぎり、KeyboardEventdispatchEventしても意味がないようです。

これでは物理キーボードの代わりにはなりえません。

debuggerモードの活用(上手くいった)

別の方法をいろいろ調べた結果、chromeブラウザ上で物理keyboardと完全に同じeventを発火させるにはdebuggerモードを活用する必要があることがわかりました。

chrome拡張上で以下のコードを実行するとdebuggerモードへ移行します。

background.js
chrome.debugger.attach({ tabId }, '1.3');

debuggerモードになると、chrome上でDevTools Protocolを使用することができるようになります。

DevTools Protocolはchromeなどのブラウザの計測、検査、デバッグ、プロファイルを行うためのツールを提供するものです。 ブラウザをプログラム側から操作することもできるため、ブラウザオートメーションなどにも使用されます。

最終的にはdebuggerモードの状態でchrome.debugger.sendCommandを実行することで物理キーボードと同じ挙動を再現することができました。

background.js
chrome.debugger.sendCommand({ tabId }, 'Input.dispatchKeyEvent', { type: 'keyDown', key: 'ArrowDown', code: 'ArrowDown', windowsVirtualKeyCode: 40, nativeVirtualKeyCode: 40, macCharCode: 40 });

参考になれば幸いです。

おわり

debugモードにすると余分なバーが表示されちゃうけど、これはセキュリティ上しょうがないのかな... 🥺

author picture

Mitsuru Takahashi

京都市内にてフリーランスエンジニアとして活動しています。

detail

Profile

author picture

Mitsuru Takahashi

京都市内にてフリーランスエンジニアとして活動しています。

detail

© 2022 mitsuru takahashi