Entwicklertools erweitern

Mit Entwicklertools-Erweiterungen werden Funktionen zu den Chrome-Entwicklertools hinzugefügt. Dabei greifen sie über eine Entwicklertools-Seite auf die Entwicklertools-spezifischen Erweiterungs-APIs zu.

Architekturdiagramm, das die Kommunikation der Seite „Entwicklertools“ mit dem geprüften Fenster und dem Service Worker zeigt. Es wird gezeigt, wie der Service Worker mit den Inhaltsskripts kommuniziert und auf Erweiterungs-APIs zugreift.
         Über die Seite „Entwicklertools“ kann auf die Entwicklertools-APIs zugegriffen werden, um z. B. Bereiche zu erstellen.
Architektur der Entwicklertools-Erweiterung.

Zu den für die Entwicklertools spezifischen Erweiterungs-APIs gehören:

Die Seite „Entwicklertools“

Wenn ein Entwicklertools-Fenster geöffnet wird, erstellt eine Entwicklertools-Erweiterung eine Instanz ihrer Entwicklertools-Seite, die vorhanden ist, solange das Fenster geöffnet ist. Diese Seite hat Zugriff auf die Entwicklertools APIs und Erweiterungs-APIs und kann Folgendes tun:

  • Über die devtools.panels APIs können Sie Bereiche erstellen und mit ihnen interagieren. Außerdem können Sie im Fenster „Entwicklertools“ andere Erweiterungsseiten als Bereiche oder Seitenleisten hinzufügen.
  • Mit den devtools.inspectedWindow APIs können Sie Informationen zum geprüften Fenster abrufen und den Code im geprüften Fenster auswerten.
  • Informationen zu Netzwerkanfragen mit den devtools.network APIs abrufen
  • Erweitern Sie das Rekorder-Steuerfeld mithilfe der devtools.recorder APIs.

Über die Seite „Entwicklertools“ kann direkt auf Erweiterungs-APIs zugegriffen werden. Dazu gehört auch, dass Sie über die Nachrichtenübergabe mit dem Service Worker kommunizieren können.

Entwicklertools-Erweiterung erstellen

Um eine Entwicklertools-Seite für Ihre Erweiterung zu erstellen, fügen Sie im Erweiterungsmanifest das Feld devtools_page hinzu:

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

Das Feld devtools_page muss auf eine HTML-Seite verweisen. Da die Entwicklertools-Seite lokal für Ihre Erweiterung sein muss, empfehlen wir, sie mit einer relativen URL anzugeben.

Die chrome.devtools API ist nur für die Seiten verfügbar, die im Fenster der Entwicklertools geladen werden, während das Fenster geöffnet ist. Inhaltsskripts und andere Erweiterungsseiten haben keinen Zugriff auf diese APIs.

UI-Elemente der Entwicklertools: Steuerfelder und Seitenleisten

Zusätzlich zu den üblichen UI-Elementen der Erweiterung wie Browseraktionen, Kontextmenüs und Pop-ups kann eine Entwicklertools-Erweiterung UI-Elemente zum Entwicklertools-Fenster hinzufügen:

  • Ein Bereich ist ein Tab auf oberster Ebene, wie die Steuerfelder „Elemente“, „Quellen“ und „Netzwerk“.
  • Ein Seitenleistenbereich enthält eine zusätzliche UI für einen Bereich. Die Bereiche „Stile“, „Berechnete Stile“ und „Ereignis-Listener“ im Steuerfeld „Elemente“ sind Beispiele für Seitenleistenbereiche. Abhängig von der verwendeten Chrome-Version und davon, wo das Fenster der Entwicklertools angedockt ist, können Ihre Seitenleistenbereiche wie die folgende Beispielabbildung aussehen:
Entwicklertools-Fenster mit dem Bereich „Elemente“ und dem Seitenleistenbereich „Stile“.
Das Entwicklertools-Fenster mit dem Bereich „Elemente“ und der Seitenleiste „Stile“.

Jeder Bereich ist eine eigene HTML-Datei, die andere Ressourcen (JavaScript, CSS, Bilder usw.) enthalten kann. Verwenden Sie den folgenden Code, um ein Basissteuerfeld zu erstellen:

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

JavaScript, das in einem Steuerfeld oder einer Seitenleiste ausgeführt wird, hat Zugriff auf dieselben APIs wie die Seite „Entwicklertools“.

Verwenden Sie den folgenden Code, um einen einfachen Seitenleistenbereich zu erstellen:

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

Es gibt mehrere Möglichkeiten, Inhalte in einer Seitenleiste anzuzeigen:

  • HTML-Inhalt: Rufen Sie setPage() auf, um eine HTML-Seite anzugeben, die im Bereich angezeigt werden soll.
  • JSON-Daten: Übergeben Sie ein JSON-Objekt an setObject().
  • JavaScript-Ausdruck: Übergeben Sie einen Ausdruck an setExpression(). Die Entwicklertools werten den Ausdruck im Kontext der geprüften Seite aus und zeigen dann den Rückgabewert an.

Sowohl für setObject() als auch für setExpression() wird im Bereich der Wert so angezeigt, wie er in der Entwicklertools-Konsole erscheinen würde. Mit setExpression() können Sie jedoch DOM-Elemente und beliebige JavaScript-Objekte anzeigen lassen, während setObject() nur JSON-Objekte unterstützt.

Kommunikation zwischen Erweiterungskomponenten

In den folgenden Abschnitten werden einige hilfreiche Möglichkeiten beschrieben, wie die Erweiterungskomponenten der Entwicklertools miteinander kommunizieren können.

Inhaltsskript einfügen

Verwenden Sie scripting.executeScript(), um ein Inhaltsskript einzufügen:

// DevTools page -- devtools.js
chrome.scripting.executeScript({
  target: {
    tabId: chrome.devtools.inspectedWindow.tabId
  },
  files: ["content_script.js"]
});

Sie können die Tab-ID des geprüften Fensters mit der Eigenschaft inspectedWindow.tabId abrufen.

Wenn bereits ein Inhaltsskript eingeschleust wurde, können Sie Messaging-APIs verwenden, um damit zu kommunizieren.

JavaScript im geprüften Fenster auswerten

Mit der Methode inspectedWindow.eval() können Sie JavaScript-Code im Kontext der geprüften Seite ausführen. Sie können die Methode eval() über eine Seite, einen Bereich oder einen Seitenleistenbereich der Entwicklertools aufrufen.

Standardmäßig wird der Ausdruck im Kontext des Hauptframes der Seite ausgewertet. inspectedWindow.eval() verwendet denselben Kontext und dieselben Optionen für die Skriptausführung wie der Code, der in der Entwicklertools-Konsole eingegeben wird. Dadurch wird bei Verwendung von eval() der Zugriff auf die Console Utilities API-Funktionen der Entwicklertools ermöglicht. Beispielsweise wird es in SOAK zur Prüfung eines Elements verwendet:

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

Sie können useContentScriptContext auch auf true setzen, wenn Sie inspectedWindow.eval() aufrufen, um den Ausdruck im selben Kontext wie die Inhaltsskripts auszuwerten. Wenn Sie diese Option verwenden möchten, müssen Sie eine Script-Deklaration für statische Inhalte verwenden, bevor Sie eval() aufrufen. Dazu rufen Sie entweder executeScript() auf oder geben ein Inhaltsskript in der Datei manifest.json an. Nachdem der Kontextskriptkontext geladen wurde, können Sie diese Option auch verwenden, um zusätzliche Inhaltsskripte einzufügen.

Ausgewähltes Element an ein Content-Script übergeben

Das Inhaltsskript hat keinen direkten Zugriff auf das aktuell ausgewählte Element. Jeder Code, den Sie mit inspectedWindow.eval() ausführen, hat jedoch Zugriff auf die Entwicklertools-Konsole und die Console Utilities APIs. In ausgewertetem Code können Sie beispielsweise $0 verwenden, um auf das ausgewählte Element zuzugreifen.

So übergeben Sie das ausgewählte Element an ein Inhaltsskript:

  1. Erstellen Sie im Inhaltsskript eine Methode, die das ausgewählte Element als Argument verwendet.

    function setSelectedElement(el) {
        // do something with the selected element
    }
    
  2. Rufen Sie die Methode auf der Seite „Entwicklertools“ mit inspectedWindow.eval() und der Option useContentScriptContext: true auf.

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

Die Option useContentScriptContext: true gibt an, dass der Ausdruck im selben Kontext wie die Inhaltsskripte ausgewertet werden muss, damit er auf die Methode setSelectedElement zugreifen kann.

window eines Referenzbereichs abrufen

Um postMessage() aus einem Entwicklertools-Bereich aufzurufen, benötigst du einen Verweis auf das zugehörige window-Objekt. Rufen Sie das iFrame-Fenster eines Bereichs vom panel.onShown-Event-Handler ab:

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

Nachrichten über eingefügte Skripts an die Seite für die Entwicklertools senden

Code, der ohne Inhaltsskript direkt in die Seite eingeschleust wird (z. B. durch Anfügen eines <script>-Tags oder Aufrufen von inspectedWindow.eval()), kann keine Nachrichten mit runtime.sendMessage() an die Entwicklertools-Seite senden. Stattdessen empfehlen wir, das eingeschleuste Skript mit einem Inhaltsskript zu kombinieren, das als Mittler fungieren kann, und die Methode window.postMessage() zu verwenden. Im folgenden Beispiel wird das Hintergrundskript aus dem vorherigen Abschnitt verwendet:

// 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. Note that this is not foolproof
  // and the page can easily spoof messages if it wants to.
  if (typeof message !== 'object' || message === null ||
      message.source !== 'my-devtools-extension') {
    return;
  }

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

Andere alternative Techniken zur Nachrichtenweitergabe finden Sie auf GitHub.

Erkennen, wenn die Entwicklertools geöffnet und geschlossen werden

Wenn Sie verfolgen möchten, ob das Entwicklertools-Fenster geöffnet ist, fügen Sie dem Service Worker einen onConnect-Listener hinzu und rufen Sie connect() über die Seite der Entwicklertools auf. Da auf jedem Tab ein eigenes Entwicklertools-Fenster geöffnet sein kann, erhalten Sie möglicherweise mehrere Verbindungsereignisse. Um zu prüfen, ob ein Entwicklertools-Fenster geöffnet ist, zählen Sie die Verbindungs- und Trennereignisse wie im folgenden Beispiel gezeigt:

// 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.");
          }
      });
    }
});

Die Seite „Entwicklertools“ erstellt eine Verbindung wie diese:

// devtools.js

// Create a connection to the service worker
const serviceWorkerConnection = chrome.runtime.connect({
    name: "devtools-page"
});

// Send a periodic heartbeat to keep the port open.
setInterval(() => {
  port.postMessage("heartbeat");
}, 15000);

Beispiele für Entwicklertools-Erweiterungen

Die Beispiele auf dieser Seite stammen von den folgenden Seiten:

  • Polymer-Entwicklertools-Erweiterung: Verwendet viele Helper, die auf der Hostseite ausgeführt werden, um den DOM-/JS-Status abzufragen und an das benutzerdefinierte Steuerfeld zurückzusenden.
  • Erweiterung für React-Entwicklertools: Hier wird ein Untermodul des Renderers zur Wiederverwendung von UI-Komponenten der Entwicklertools verwendet.
  • Ember Inspector: Gemeinsamer Erweiterungskern mit Adaptern für Chrome und Firefox.
  • Coquette-Inspect: Eine saubere, auf React basierende Erweiterung, bei der ein Debugging-Agent in die Hostseite eingefügt wurde.
  • Beispielerweiterungen bieten weitere lohnenswerte Erweiterungen, die Sie installieren, ausprobieren und lernen können.

Weitere Informationen

Informationen zu den Standard-APIs, die Erweiterungen verwenden können, finden Sie unter chrome.* APIs und Web-APIs.

Geben Sie uns Feedback. Ihre Kommentare und Vorschläge helfen uns, die APIs zu verbessern.

Beispiele

Beispiele, bei denen DevTools APIs verwendet werden, finden Sie unter Beispiele.