Entwicklertools erweitern

Mithilfe von DevTools-Erweiterungen können Sie den Chrome-Entwicklertools Funktionen hinzufügen, indem Sie über eine DevTools-Seite, die der Erweiterung hinzugefügt wird, auf DevTools-spezifische Erweiterungs-APIs zugreifen.

Architekturdiagramm, das die DevTools-Seite zeigt, die mit dem geprüften Fenster und dem Dienst-Worker kommuniziert Der Dienst-Worker kommuniziert mit den Inhalts-Scripts und greift auf Erweiterungs-APIs zu.
         Die Seite „DevTools“ bietet Zugriff auf die DevTools APIs, z. B. zum Erstellen von Steuerfeldern.
Architektur der DevTools-Erweiterung.

Zu den DevTools-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 so lange vorhanden ist, wie das Fenster geöffnet ist. Auf dieser Seite haben Sie Zugriff auf die DevTools-APIs und Erweiterungs-APIs. Sie können Folgendes tun:

Über die Seite „DevTools“ kann direkt auf Erweiterungs-APIs zugegriffen werden. Dazu gehört auch die Möglichkeit, über Nachrichtenübertragung mit dem Dienstarbeiter zu kommunizieren.

DevTools-Erweiterung erstellen

Wenn Sie eine DevTools-Seite für Ihre Erweiterung erstellen möchten, fügen Sie das Feld devtools_page in das Manifest der Erweiterung ein:

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

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

Die Mitglieder der chrome.devtools API sind nur für die Seiten verfügbar, die im DevTools-Fenster geladen werden, solange dieses Fenster geöffnet ist. Content-Scripts und andere Erweiterungsseiten haben keinen Zugriff auf diese APIs.

UI-Elemente der DevTools: Bereiche und Seitenleisten

Zusätzlich zu den üblichen UI-Elementen einer Erweiterung, z. B. Browseraktionen, Kontextmenüs und Pop-ups, kann eine DevTools-Erweiterung dem DevTools-Fenster UI-Elemente hinzufügen:

  • Ein Steuerfeld ist ein Tab der obersten Ebene, z. B. die Steuerfelder „Elemente“, „Quellen“ und „Netzwerk“.
  • Eine Seitenleiste enthält zusätzliche Steuerelemente für einen Bereich. Die Bereiche „Stile“, „Berechnete Stile“ und „Ereignis-Listener“ im Bereich „Elemente“ sind Beispiele für Seitenleisten. Je nach verwendeter Chrome-Version und Position des DevTools-Fensters sehen die Seitenleisten möglicherweise so aus wie im folgenden Beispielbild:
DevTools-Fenster mit dem Bereich „Elemente“ und der Seitenleiste „Stile“
DevTools-Fenster mit dem Bereich „Elemente“ und der Seitenleiste „Stile“

Jedes Steuerfeld ist eine eigene HTML-Datei, die andere Ressourcen (JavaScript, CSS, Bilder usw.) enthalten kann. Verwenden Sie den folgenden Code, um ein einfaches Steuerfeld 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 in der Seitenleiste ausgeführt wird, hat Zugriff auf dieselben APIs wie die Seite „DevTools“.

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 einem Seitenleistenbereich 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(). In den DevTools wird der Ausdruck im Kontext der geprüften Seite ausgewertet und der Rückgabewert angezeigt.

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

Zwischen Erweiterungskomponenten kommunizieren

In den folgenden Abschnitten werden einige hilfreiche Möglichkeiten beschrieben, wie Komponenten von DevTools-Erweiterungen miteinander kommunizieren können.

Inhaltsskript einfügen

Um ein Inhaltsskript einzufügen, verwende scripting.executeScript():

// 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 mithilfe der Property inspectedWindow.tabId abrufen.

Wenn ein Inhaltsskript bereits eingefügt wurde, können Sie über Messaging APIs mit ihm 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 eval()-Methode auf einer Seite, in einem Steuerfeld oder in der Seitenleiste der Entwicklertools aufrufen.

Standardmäßig wird der Ausdruck im Kontext des Hauptframes der Seite ausgewertet. inspectedWindow.eval() verwendet denselben Script-Ausführungskontext und dieselben Optionen wie Code, der in der DevTools-Konsole eingegeben wird. Dadurch ist bei Verwendung von eval() der Zugriff auf die Funktionen der Console Utilities API von DevTools möglich. In SOAK wird es beispielsweise zum Prüfen eines Elements verwendet:

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

Sie können useContentScriptContext auch auf true festlegen, wenn Sie inspectedWindow.eval() aufrufen, um den Ausdruck im selben Kontext wie die Inhaltsscripts zu bewerten. Wenn du diese Option verwenden möchtest, musst du vor dem Aufruf von eval() eine Deklaration für ein statisches Inhaltsskript verwenden. Dazu kannst du entweder executeScript() aufrufen oder ein Inhaltsskript in der manifest.json-Datei angeben. Nachdem das Kontextskript geladen wurde, können Sie mit dieser Option auch zusätzliche Inhaltsscripts einfügen.

Ausgewähltes Element an ein Inhaltsskript ü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 DevTools-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 annimmt.

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

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

Mit der Option useContentScriptContext: true wird angegeben, dass der Ausdruck im selben Kontext wie die Inhaltsscripts ausgewertet werden muss, damit er auf die Methode setSelectedElement zugreifen kann.

window eines Referenzpanels abrufen

Wenn Sie postMessage() über ein devtools-Steuerfeld aufrufen möchten, benötigen Sie einen Verweis auf das zugehörige window-Objekt. iframe-Fenster eines Steuerfelds über den Ereignis-Handler panel.onShown abrufen:

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

Nachrichten von eingeschleusten Scripts an die DevTools-Seite senden

Code, der ohne Inhaltsskript direkt in die Seite eingefügt wird, z. B. durch Anhängen eines <script>-Tags oder Aufrufen von inspectedWindow.eval(), kann keine Nachrichten über runtime.sendMessage() an die DevTools-Seite senden. Stattdessen empfehlen wir, das eingeschleuste Script mit einem Inhalts-Script zu kombinieren, das als Vermittler 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);
});

Weitere alternative Techniken zur Nachrichtenweitergabe finden Sie auf GitHub.

Erkennen, wenn die Entwicklertools geöffnet und geschlossen werden

Wenn Sie verfolgen möchten, ob das DevTools-Fenster geöffnet ist, fügen Sie dem Dienst-Worker einen onConnect-Listener hinzu und rufen Sie connect() auf der DevTools-Seite auf. Da auf jedem Tab ein eigenes DevTools-Fenster geöffnet werden kann, erhalten Sie möglicherweise mehrere Connect-Ereignisse. Wenn Sie nachverfolgen möchten, ob ein DevTools-Fenster geöffnet ist, zählen Sie die Verbindungs- und Trennungsereignisse 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.");
          }
      });
    }
});

Auf der Seite „DevTools“ wird eine Verbindung so erstellt:

// 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 DevTools-Erweiterungen

Die Beispiele auf dieser Seite stammen von den folgenden Seiten:

  • Polymer Devtools-Erweiterung: Verwendet viele Helfer, die auf der Hostseite ausgeführt werden, um den DOM/JS-Status abzufragen und an das benutzerdefinierte Steuerfeld zurückzugeben.
  • React DevTools-Erweiterung: Verwendet ein Submodul des Renderers, um DevTools-UI-Komponenten wiederzuverwenden.
  • Ember Inspector: Gemeinsamer Erweiterungskern mit Adaptern für Chrome und Firefox.
  • Coquette-inspect: Eine einfache React-basierte Erweiterung mit einem Debug-Agent, der in die Hostseite eingefügt wird.
  • Unter Beispiele für Erweiterungen finden Sie weitere interessante Erweiterungen, die Sie installieren, ausprobieren und aus denen Sie lernen können.

Weitere Informationen

Informationen zu den Standard-APIs, die von Erweiterungen verwendet werden 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 für die Verwendung von DevTools APIs finden Sie unter Beispiele.