DevTools の拡張

概要

DevTools 拡張機能は、Chrome DevTools に機能を追加します。新しい UI パネルやサイドバーを追加したり、検査対象のページを操作したり、ネットワーク リクエストに関する情報を取得したりできます。注目の DevTools 拡張機能を表示します。DevTools 拡張機能は、DevTools 固有の拡張機能 API の追加セットにアクセスできます。

DevTools 拡張機能は他の拡張機能と同様に構成されており、バックグラウンド ページ、コンテンツ スクリプトなどのアイテムです。また、各 DevTools 拡張機能には、DevTools API にアクセスできる DevTools ページがあります。

検査対象のウィンドウとバックグラウンド ページと通信する DevTools ページを示すアーキテクチャ図。バックグラウンド ページがコンテンツ スクリプトと通信し、拡張機能 API にアクセスしています。DevTools ページでは、パネルの作成など、DevTools API にアクセスできます。

DevTools ページ

DevTools ウィンドウを開くたびに、拡張機能の DevTools ページのインスタンスが作成されます。DevTools ページは、DevTools ウィンドウの存続期間中存在します。DevTools ページでは、DevTools API と限定された一連の拡張機能 API にアクセスできます。具体的には、DevTools ページでは次のことができます。

  • devtools.panels API を使用してパネルを作成して操作します。
  • devtools.inspectedWindow API を使用して、検査対象のウィンドウに関する情報を取得し、検査対象のウィンドウ内のコードを評価します。
  • devtools.network API を使用して、ネットワーク リクエストに関する情報を取得します。

DevTools ページでは、ほとんどの拡張機能 API を直接使用することはできません。コンテンツ スクリプトがアクセスできる extension API と runtime API のサブセットにアクセスできます。コンテンツに高評価を付ける DevTools のページがメッセージの受け渡しを使用してバックグラウンド ページと通信できます。例については、コンテンツ スクリプトの挿入をご覧ください。

DevTools 拡張機能の作成

拡張機能の DevTools ページを作成するには、拡張機能マニフェストに devtools_page フィールドを追加します。

{
  "name": ...
  "version": "1.0",
  "minimum_chrome_version": "10.0",
  "devtools_page": "devtools.html",
  ...
}

拡張機能のマニフェストで指定された devtools_page のインスタンスは、 DevTools ウィンドウを開きました。このページには、他の拡張機能ページをパネルやサイドバーとして devtools.panels API を使用する [DevTools] ウィンドウ。

chrome.devtools.* API モジュールは、DevTools ウィンドウ内で読み込まれたページでのみ使用できます。コンテンツ スクリプトやその他の拡張機能ページには、これらの API がありません。したがって、API は DevTools ウィンドウの存続期間中のみ使用できます。

まだ試験運用版の DevTools API もあります。詳しくは、chrome.experimental.* をご覧ください。 API をご覧ください。

DevTools UI 要素: パネルとサイドバー ペイン

ブラウザのアクション、コンテキスト メニュー、ポップアップといった通常の拡張機能 UI 要素に加え、 DevTools 拡張機能を使用すると、DevTools ウィンドウに UI 要素を追加できます。

  • パネルは、[要素]、[ソース]、[ネットワーク] パネルなどの最上位タブです。
  • サイドバー ペインは、パネルに関連する補足の UI です。スタイル、計算されたスタイル、 [要素] パネルの [イベント リスナー] ペインは、サイドバー ペインの例です。(使用している Chrome のバージョンや、DevTools ウィンドウのドッキング場所によっては、サイドバー ペインの外観が画像と異なる場合があります)。

[Elements] パネルと [Styles] サイドバー ペインが表示された [DevTools] ウィンドウ。

各パネルは独自の HTML ファイルであり、他のリソース(JavaScript、CSS、画像など)を含めることができます。 オン)。基本的なパネルの作成は次のようになります。

chrome.devtools.panels.create("My Panel",
    "MyPanelIcon.png",
    "Panel.html",
    function(panel) {
      // code invoked on panel creation
    }
);

パネルまたはサイドバー ペインで実行される JavaScript は、DevTools ページと同じ API にアクセスできます。

要素パネルの基本的なサイドバー ペインを作成するコードは次のようになります。

chrome.devtools.panels.elements.createSidebarPane("My Sidebar",
    function(sidebar) {
        // sidebar initialization code here
        sidebar.setObject({ some_data: "Some data to show" });
});

サイドバー ペインにコンテンツを表示する方法はいくつかあります。

  • HTML コンテンツ。setPage を呼び出して、ペインに表示する HTML ページを指定します。
  • JSON データ。JSON オブジェクトを setObject に渡します。
  • JavaScript 式。式を setExpression に渡します。DevTools は、検査対象のページのコンテキストで式を評価し、戻り値を表示します。

setObjectsetExpression の両方で、ペインには、 DevTools コンソール。ただし、setExpression では DOM 要素と任意の JavaScript オブジェクトを表示できますが、setObject は JSON オブジェクトのみをサポートします。

拡張機能コンポーネント間の通信

以降のセクションでは、DevTools 拡張機能のさまざまなコンポーネント間で通信する一般的なシナリオについて説明します。

コンテンツ スクリプトの挿入

DevTools ページから tabs.executeScript を直接呼び出すことはできません。DevTools ページからコンテンツ スクリプトを挿入するには、inspectedWindow.tabId プロパティを使用して検査対象のウィンドウのタブの ID を取得し、バックグラウンド ページにメッセージを送信する必要があります。バックグラウンド ページから tabs.executeScript を呼び出してスクリプトを挿入します。

次のコード スニペットは、executeScript を使用してコンテンツ スクリプトを挿入する方法を示しています。

// DevTools page -- devtools.js
// Create a connection to the background page
var backgroundPageConnection = chrome.runtime.connect({
    name: "devtools-page"
});

backgroundPageConnection.onMessage.addListener(function (message) {
    // Handle responses from the background page, if any
});

// Relay the tab ID to the background page
chrome.runtime.sendMessage({
    tabId: chrome.devtools.inspectedWindow.tabId,
    scriptToInject: "content_script.js"
});

バックグラウンド ページのコード:

// Background page -- background.js
chrome.runtime.onConnect.addListener(function(devToolsConnection) {
    // assign the listener function to a variable so we can remove it later
    var devToolsListener = function(message, sender, sendResponse) {
        // Inject a content script into the identified tab
        chrome.tabs.executeScript(message.tabId,
            { file: message.scriptToInject });
    }
    // add the listener
    devToolsConnection.onMessage.addListener(devToolsListener);

    devToolsConnection.onDisconnect.addListener(function() {
         devToolsConnection.onMessage.removeListener(devToolsListener);
    });
});

検査対象のウィンドウで JavaScript を評価する

inspectedWindow.eval メソッドを使用すると、検査対象のページのコンテキストで JavaScript コードを実行できます。eval メソッドは、DevTools のページ、パネル、サイドバー ペインから呼び出すことができます。

デフォルトでは、式はページのメインフレームのコンテキストで評価されます。これで、要素の検査(inspect(elem))、関数でのブレークポイント(debug(fn))、クリップボードへのコピー(copy())など、DevTools の コマンドライン API の機能に慣れ親しんだことでしょう。inspectedWindow.eval() は、 DevTools コンソール。評価内でこれらの API にアクセスできます。たとえば、SOAK ではこれを使用します。 を使用して確認できます。

chrome.devtools.inspectedWindow.eval(
  "inspect($$('head script[data-soak=main]')[0])",
  function(result, isException) { }
);

または、inspectedWindow.eval()useContentScriptContext: true オプションを使用して、 コンテンツ スクリプトと同じコンテキストで式を評価します。eval に発信中: useContentScriptContext: true はコンテンツ スクリプトのコンテキストを作成しないため、 コンテキスト スクリプト。eval を呼び出す前に、executeScript を呼び出すか、コンテンツを指定します。 スクリプトを manifest.json ファイルに記述します。

コンテキスト スクリプトのコンテキストが存在する場合は、このオプションを使用して追加のコンテンツを挿入できます。 使用できます。

eval メソッドは、適切なコンテキストで使用すると効果的ですが、使用すると危険です 除外します検査対象ページの JavaScript コンテキストにアクセスする必要がない場合は、tabs.executeScript メソッドを使用します。詳細な注意事項と 2 つの方法の比較については、 inspectedWindow をご覧ください。

選択した要素をコンテンツ スクリプトに渡す

コンテンツ スクリプトは、現在選択されている要素に直接アクセスできません。ただし、inspectedWindow.eval を使用して実行するコードは、DevTools コンソールとコマンドライン API にアクセスできます。たとえば、評価されたコードでは、$0 を使用して選択した要素にアクセスできます。

選択した要素をコンテンツ スクリプトに渡すには:

  • 選択した要素を引数として受け取るメソッドをコンテンツ スクリプトに作成します。
  • useContentScriptContext: true オプションを指定して inspectedWindow.eval を使用して、DevTools ページからメソッドを呼び出します。

コンテンツ スクリプトのコードは次のようになります。

function setSelectedElement(el) {
    // do something with the selected element
}

次のように、DevTools ページからメソッドを呼び出します。

chrome.devtools.inspectedWindow.eval("setSelectedElement($0)",
    { useContentScriptContext: true });

useContentScriptContext: true オプションは、式を評価する必要があることを指定します。 コンテンツ スクリプトと同じコンテキストなので、setSelectedElement メソッドにアクセスできます。

参照パネルの window を取得する

デベロッパー ツールパネルから postMessage するには、その window オブジェクトへの参照が必要です。panel.onShown イベント ハンドラからパネルの iframe ウィンドウを取得します。

onShown.addListener(function callback)
extensionPanel.onShown.addListener(function (extPanelWindow) {
    extPanelWindow instanceof Window; // true
    extPanelWindow.postMessage( // …
});

コンテンツ スクリプトから DevTools ページへのメッセージ送信

DevTools ページとコンテンツ スクリプト間のメッセージは、バックグラウンド ページを介して間接的に送信されます。

コンテンツ スクリプトメッセージを送信する場合、バックグラウンド ページは tabs.sendMessage メソッドを使用できます。このメソッドは、コンテンツ スクリプトの挿入に示すように、特定のタブのコンテンツ スクリプトにメッセージを転送します。

コンテンツ スクリプトからメッセージを送信する場合、現在のタブに関連付けられた正しい DevTools ページ インスタンスにメッセージを配信する既成の方法はありません。回避策として、DevTools ページがバックグラウンド ページとの長時間接続を確立し、バックグラウンド ページが接続へのタブ ID のマップを保持して、各メッセージを正しい接続に転送できるようにします。

// background.js
var connections = {};

chrome.runtime.onConnect.addListener(function (port) {

    var extensionListener = function (message, sender, sendResponse) {

        // The original connection event doesn't include the tab ID of the
        // DevTools page, so we need to send it explicitly.
        if (message.name == "init") {
          connections[message.tabId] = port;
          return;
        }

    // other message handling
    }

    // Listen to messages sent from the DevTools page
    port.onMessage.addListener(extensionListener);

    port.onDisconnect.addListener(function(port) {
        port.onMessage.removeListener(extensionListener);

        var tabs = Object.keys(connections);
        for (var i=0, len=tabs.length; i < len; i++) {
          if (connections[tabs[i]] == port) {
            delete connections[tabs[i]]
            break;
          }
        }
    });
});

// Receive message from content script and relay to the devTools page for the
// current tab
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    // Messages from content scripts should have sender.tab set
    if (sender.tab) {
      var tabId = sender.tab.id;
      if (tabId in connections) {
        connections[tabId].postMessage(request);
      } else {
        console.log("Tab not found in connection list.");
      }
    } else {
      console.log("sender.tab not defined.");
    }
    return true;
});

DevTools ページ(またはパネルまたはサイドバー ペイン)は、次のように接続を確立します。

// Create a connection to the background page
var backgroundPageConnection = chrome.runtime.connect({
    name: "panel"
});

backgroundPageConnection.postMessage({
    name: 'init',
    tabId: chrome.devtools.inspectedWindow.tabId
});

挿入されたスクリプトから DevTools ページへのメッセージ送信

上記のソリューションはコンテンツ スクリプトには有効ですが、ページに直接挿入されるコード(<script> タグの追加や inspectedWindow.eval による挿入など)には別の戦略が必要です。このコンテキストでは、runtime.sendMessage は想定どおりにバックグラウンド スクリプトにメッセージを渡しません。

回避策として、挿入されたスクリプトを、仲介役として機能するコンテンツ スクリプトと組み合わせることができます。コンテンツ スクリプトにメッセージを渡すには、window.postMessage を使用します。 API前のセクションのバックグラウンド スクリプトを想定した例を次に示します。

// injected-script.js

window.postMessage({
  greeting: 'hello there!',
  source: 'my-devtools-extension'
}, '*');
// content-script.js

window.addEventListener('message', function(event) {
  // Only accept messages from the same frame
  if (event.source !== window) {
    return;
  }

  var message = event.data;

  // Only accept messages that we know are ours
  if (typeof message !== 'object' || message === null ||
      !message.source === 'my-devtools-extension') {
    return;
  }

  chrome.runtime.sendMessage(message);
});

メッセージが挿入されたスクリプトからコンテンツ スクリプト、バックグラウンドへと流れるようになりました 最後に [DevTools] ページに移動します。

こちらで、2 つの代替メッセージ パススルー手法も検討してください。

DevTools の開閉のタイミングを検出する

拡張機能が DevTools ウィンドウが開いているかどうかをトラッキングする必要がある場合は、onConnect リスナーをバックグラウンド ページに追加し、DevTools ページから connect を呼び出します。各タブには 固有の DevTools ウィンドウが開いていると、複数の接続イベントが表示されることがあります。DevTools ウィンドウが開いているかどうかを追跡するには、次のように接続イベントと切断イベントをカウントする必要があります。

// background.js
var openCount = 0;
chrome.runtime.onConnect.addListener(function (port) {
    if (port.name == "devtools-page") {
      if (openCount == 0) {
        alert("DevTools window opening.");
      }
      openCount++;

      port.onDisconnect.addListener(function(port) {
          openCount--;
          if (openCount == 0) {
            alert("Last DevTools window closing.");
          }
      });
    }
});

DevTools のページでは、次のような接続が作成されます。

// devtools.js

// Create a connection to the background page
var backgroundPageConnection = chrome.runtime.connect({
    name: "devtools-page"
});

DevTools 拡張機能の例

以下の DevTools 拡張機能の例のソースをご覧ください。

  • Polymer Devtools 拡張機能 - ホストページで実行されている多くのヘルパーを使用して DOM/JS をクエリします。 カスタムパネルに返送します
  • React DevTools 拡張機能 - Blink のサブモジュールを使用して、DevTools UI コンポーネントを再利用します。
  • Ember Inspector - Chrome と Firefox の両方に対応したアダプターを備えた共有拡張機能コアです。
  • Coquette-inspect - デバッグ エージェントが挿入された、React ベースのクリーンな拡張機能。 表示されます。
  • DevTools 拡張機能ギャラリーサンプル拡張機能には、インストール、試用、学習に役立つアプリが他にもたくさんあります。

詳細

拡張機能で使用できる標準 API については、chrome.*APIウェブ API

フィードバックをお寄せください皆様からのコメントやご提案は、API の改善に役立てさせていただきます。

DevTools API を使用する例については、サンプルをご覧ください。