読者です 読者をやめる 読者になる 読者になる

Chromeデベロッパーツール拡張の話

艦これ向けChrome Extension 「艦これインスペクタ」を作りました - logiqboard の続き

艦これインスペクタを作る際に、devtools拡張の日本語情報がなくて結構苦労したので、調べたことをまとめておきます。元ドキュメントを読む際の理解の助けになれば幸いです。

実装例として feiz / kancolle_inspector / source / — Bitbucket も参照するとよいと思います。

基本的なこと

Chrome extensionにはデベロッパーツールを拡張するためのAPI chrome.devtools.* が用意されています。

Extending DevTools - Google Chrome

デベロッパーツールにパネル(タブ?)を追加したり、インスペクト対象のウィンドウにcontent scriptを送り込んだり、webRequestでは取れないHTTPレスポンス内容を取得したりできます。

デベロッパーツールを真面目に拡張する人は中々いないと思いますが、艦これインスペクタのようにchrome extensionでHTTPレスポンスの内容を覗き見したい場合は実質devtools拡張しか無いと思います。*1

devtools_page

devtools APIは通常のbackground_pageやcontent script上では参照できず、devtools_pageという"デベロッパーツールのバックグラウンドページ"みたいなものの中でのみ参照できます。

逆にこのコンテキスト内ではchrome.devtools.*とchrome.runtime以外のAPIが参照できません。

それらのAPIを使うときは、background側にchrome.runtime.postMessageでデータを投げ*2、向こう側で処理してもらう必要があります。

また必然的に、動作させるためにはデベロッパーツールが起動している必要があります。なので、違和感なく使えるツールにするのはなかなか難しいです。

特定のwebサイト用のdevtools拡張

manifestのドキュメントを見た限りではcontent_scriptのような「特定のサイト上でdevtoolsを起動した時だけ読ませる」設定はないようです。したがって、どんなページでデベロッパーツールを起動してもdevtools_pageは読み込まれてしまいます。

インスペクトしているページのURLは以下のようなコードで判別できるので、艦これインスペクタでは以下のようにしてパネルの追加を制御しています。

chrome.devtools.inspectedWindow.eval('document.baseURI', function(page_url) {
  if (!is_kancolle_page(page_url)){
    return;
  }
  chrome.devtools.panels.create("艦隊情報", 'icon/icon.png', 'html/panel.html');
});

デバッグ

以下のとおり。MacではCmd+Shift+Iです。


番外: extension内でevalする

(devtoolsだけでなく)chrome.*が使える場所ではevalやFunctionが使えません。テンプレートエンジンとかを組み込むときは面倒ですが

  1. manifestでsandbox化するhtmlのパスを指定
  2. 指定したhtmlをsandboxを使いたいページにiframeで読み込む
  3. evalを使うコードはsandboxページの中で処理するようにし、外部とのやりとりはwindow.postMessageで行う

という手順が必要です。

Using eval in Chrome Extensions. Safely. - Google Chrome

まとめ

  • レスポンスを読みたいならFirefoxを使えdevtools拡張をつかう
  • なにをするにもpostMessage地獄なので覚悟する

*1:webRequestで取れるようにしてくれという要望もあるみたいですが、パフォーマンス的に厳しいようです。

*2:実際はちゃんとchannel作ったほうがいいです