Entwicklertools erweitern

Übersicht

Mit einer DevTools-Erweiterung werden den Chrome-Entwicklertools neue Funktionen hinzugefügt. Sie kann neue UI-Felder und Seitenleisten hinzufügen, mit der untersuchten Seite interagieren, Informationen zu Netzwerkanfragen erhalten und vieles mehr. Ansicht ausgewählten Entwicklertools-Erweiterungen. Die Entwicklertools-Erweiterungen haben Zugriff auf zusätzliche Entwicklertools-spezifische Erweiterungs-APIs:

Eine DevTools-Erweiterung ist wie jede andere Erweiterung strukturiert: Sie kann eine Hintergrundseite, Inhalte Skripte und andere Elemente. Darüber hinaus verfügt jede Entwicklertools-Erweiterung über eine Entwicklertools-Seite, auf der du Entwicklertools-APIs.

Architekturdiagramm, das die Kommunikation der Entwicklertools-Seite mit dem
       das untersuchte Fenster und die Hintergrundseite. Die Hintergrundseite wird angezeigt.
       mit Inhaltsskripts kommunizieren und auf Erweiterungs-APIs zugreifen.
       Die Seite „Entwicklertools“ hat Zugriff auf die Entwicklertools-APIs, z. B. zum Erstellen von Bereichen.

Seite „Entwicklertools“

Jedes Mal, wenn ein Entwicklertools-Fenster geöffnet wird, wird eine Instanz der Entwicklertools-Seite der Erweiterung erstellt. Die Die Seite „Entwicklertools“ existiert für die gesamte Lebensdauer des Entwicklertools-Fensters. Die Seite „Entwicklertools“ hat Zugriff auf DevTools APIs und eine begrenzte Anzahl von Erweiterungs-APIs Die Seite „Entwicklertools“ bietet folgende Möglichkeiten:

  • Über die devtools.panels APIs Bereiche erstellen und mit ihnen interagieren
  • Rufen Sie Informationen über das untersuchte Fenster ab und bewerten Sie den Code im untersuchten Fenster mithilfe der Funktion devtools.inspectedWindow APIs
  • Rufen Sie mit den devtools.network APIs Informationen zu Netzwerkanfragen ab.

Die meisten der Erweiterungs-APIs können auf der Seite „Entwicklertools“ nicht direkt verwendet werden. Sie hat Zugriff auf dieselbe Teilmenge, der extension und runtime APIs, auf die ein Content-Script Zugriff hat. Inhalte mit „Mag ich“ bewerten -Script kann eine Entwicklertools-Seite über die Nachrichtenübergabe mit der Hintergrundseite kommunizieren. Für eine erhalten Sie unter Content-Skript einfügen.

Entwicklertools-Erweiterung erstellen

Um eine Entwicklertools-Seite für deine Erweiterung zu erstellen, füge das Feld devtools_page in die Erweiterung ein Manifest:

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

Eine Instanz von devtools_page, die im Manifest Ihrer Erweiterung angegeben ist, wird für jede Das Fenster mit den Entwicklertools wurde geöffnet. Eventuell werden der Seite weitere Erweiterungsseiten als Steuerfelder und Seitenleisten hinzugefügt. Entwicklertools-Fenster mit der devtools.panels API.

Die chrome.devtools.* API-Module sind nur für die Seiten verfügbar, die in den Entwicklertools geladen werden . Inhaltsskripte und andere Erweiterungsseiten verfügen über diese APIs nicht. Daher sind die APIs ist nur während der gesamten Lebensdauer des Entwicklertools-Fensters verfügbar.

Es gibt auch einige DevTools APIs, die sich noch in der Testphase befinden. Weitere Informationen finden Sie unter chrome.experimental.* APIs: Liste der experimentellen APIs und Richtlinien zu ihrer Verwendung

UI-Elemente der Entwicklertools: Steuerfelder und Seitenleistenbereiche

Zusätzlich zu den üblichen Benutzeroberflächenelementen der Erweiterung, wie Browseraktionen, Kontextmenüs und Pop-ups, gibt es ein Mit der Entwicklertools-Erweiterung können UI-Elemente zum Entwicklertools-Fenster hinzugefügt werden:

  • Ein Steuerfeld ist ein Tab auf oberster Ebene, z. B. die Bereiche „Elemente“, „Quellen“ und „Netzwerk“.
  • Ein Seitenleistenbereich enthält eine ergänzende UI für einen Bereich. Mit den Stilen, berechneten Stilen und Die Bereiche Ereignis-Listener im Steuerfeld „Elemente“ sind Beispiele für Bereiche in der Seitenleiste. (Beachten Sie, dass die Je nachdem, welche Chrome-Version Sie verwenden, kann es sein, dass die Fenster der Seitenleiste nicht zum Bild passen. und wo das Entwicklertools-Fenster angedockt ist.)

Das Entwicklertools-Fenster mit dem Bereich „Elemente“ und dem Seitenleistenbereich „Stile“.

Jedes Steuerfeld verfügt über eine eigene HTML-Datei, die weitere Ressourcen enthalten kann (JavaScript, CSS, Bilder usw.). aktiviert). So erstellen Sie ein Basissteuerfeld:

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

JavaScript, das in einem Steuerfeld oder Seitenleistenbereich ausgeführt wird, hat Zugriff auf dieselben APIs wie die Entwicklertools-Seite.

So erstellen Sie ein einfaches Seitenleistenfenster für das Steuerfeld „Elemente“:

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 Fenster angezeigt werden soll.
  • JSON-Daten. Übergeben Sie ein JSON-Objekt an setObject.
  • JavaScript-Ausdruck. Übergeben Sie einen Ausdruck an setExpression. Entwicklertools evaluieren im Kontext der untersuchten Seite und zeigt den Rückgabewert an.

Für setObject und setExpression wird der Wert im Bereich so angezeigt, wie er im Feld Entwicklertools-Konsole. Mit setExpression können Sie jedoch DOM-Elemente und beliebiges JavaScript anzeigen. -Objekte, während setObject nur JSON-Objekte unterstützt.

Kommunikation zwischen Erweiterungskomponenten

In den folgenden Abschnitten werden einige typische Szenarien für die Kommunikation zwischen den verschiedenen Komponenten einer DevTools-Erweiterung.

Content-Script einfügen

Die Seite „Entwicklertools“ kann tabs.executeScript nicht direkt aufrufen. So fügen Sie ein Inhaltsskript aus der Entwicklertools-Seite ist, müssen Sie die ID des Tabs des untersuchten Fensters mithilfe der Funktion inspectedWindow.tabId-Property und schickt eine Nachricht an die Hintergrundseite. Wählen Sie im Hintergrundseite aufzurufen, rufen Sie tabs.executeScript auf, um das Skript einzufügen.

Die folgenden Code-Snippets zeigen, wie ein Inhaltsskript mithilfe von executeScript eingeschleust wird.

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

Code für die Hintergrundseite:

// 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 im geprüften Fenster auswerten

Mit der Methode inspectedWindow.eval kannst du JavaScript-Code im Kontext des der untersuchten Seite. Du kannst die eval-Methode über eine Entwicklertools-Seite, einen Bereich oder einen Seitenleistenbereich aufrufen.

Standardmäßig wird der Ausdruck im Kontext des Hauptframes der Seite ausgewertet. Jetzt können Sie Du solltest dich mit den Funktionen der Befehlszeilen-API von Entwicklertools wie der Elementprüfung vertraut machen. (inspect(elem)) und Funktionen (debug(fn)), Kopieren in die Zwischenablage (copy()) und mehr funktionieren nicht mehr. inspectedWindow.eval() verwendet denselben Kontext und dieselben Optionen für die Skriptausführung wie der Code, der bei der Entwicklertools-Konsole, die den Zugriff auf diese APIs innerhalb des Evaluierungsprogramms ermöglicht. Beispielsweise wird sie von SOAK verwendet. zum Untersuchen eines Elements:

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

Alternativ können Sie die Option useContentScriptContext: true für inspectedWindow.eval() verwenden, um den Ausdruck im selben Kontext wie die Inhaltsskripte auswerten. eval wird angerufen mit useContentScriptContext: true erstellt keinen Content-Script-Kontext, daher müssen Sie ein Kontextskripts vor eval aufrufen, entweder durch Aufrufen von executeScript oder durch Angeben eines Inhalts Skript in der Datei manifest.json.

Sobald der Kontext des Kontextskripts vorhanden ist, können Sie mit dieser Option zusätzliche Inhalte einfügen Skripts erstellt.

Die Methode eval ist leistungsstark, wenn sie im richtigen Kontext verwendet wird, und gefährlich, wenn sie verwendet wird die nicht unangemessen sind. Verwenden Sie die Methode tabs.executeScript, wenn Sie keinen Zugriff auf den JavaScript-Kontext der geprüften Seite Ausführliche Vorsichtsmaßnahmen und einen Vergleich der beiden Methoden finden Sie Weitere Informationen finden Sie unter inspectedWindow.

Ausgewähltes Element an ein Content-Skript übergeben

Das Content-Skript hat keinen direkten Zugriff auf das aktuell ausgewählte Element. Jeglicher Code, den Sie Mit inspectedWindow.eval ausführen hat Zugriff auf die Entwicklertools-Konsole und die Befehlszeilen-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 Content-Skript:

  • Erstellen Sie im Content-Skript eine Methode, die das ausgewählte Element als Argument verwendet.
  • Rufen Sie die Methode über die Entwicklertools-Seite auf. Verwenden Sie dazu inspectedWindow.eval mit dem Option useContentScriptContext: true.

Der Code in Ihrem Content-Skript könnte etwa so aussehen:

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

Rufen Sie die Methode auf der Seite der Entwicklertools so auf:

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

Die Option useContentScriptContext: true gibt an, dass der Ausdruck im denselben Kontext wie die Inhaltsskripte, damit sie auf die Methode setSelectedElement zugreifen kann.

window eines Referenzbereichs abrufen

Für die postMessage aus einem Entwicklertools-Bereich benötigen Sie einen Verweis auf das zugehörige window-Objekt. Rufen Sie das iFrame-Fenster eines Bereichs über den Event-Handler panel.onShown ab:

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

Mitteilungen von Content-Scripts an die Seite „Entwicklertools“

Die Kommunikation zwischen der Entwicklertools-Seite und den Content-Skripts erfolgt indirekt über die Hintergrundseite.

Beim Senden einer Nachricht an ein Content-Skript kann die Hintergrundseite die Methode tabs.sendMessage-Methode, bei der eine Nachricht an die Inhaltsskripte auf einem bestimmten Tab weitergeleitet wird, wie unter Content-Skript einfügen beschrieben.

Wenn eine Nachricht von einem Inhaltsskript gesendet wird, gibt es keine vordefinierte Methode zum Senden einer Nachricht. an die korrekte Entwicklertools-Seiteninstanz, die dem aktuellen Tab zugeordnet ist. Als Behelfslösung können Sie über die Entwicklertools-Seite eine langlebige Verbindung zur Hintergrundseite herstellen und Im Hintergrund wird eine Zuordnung der Tab-IDs zu Verbindungen erstellt, damit jede Nachricht an die richtige

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

Über die Seite mit den Entwicklertools (oder das Steuerfeld oder Seitenleistenbereich) wird die Verbindung wie folgt hergestellt:

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

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

Nachrichten von eingefügten Skripts an die Entwicklertools-Seite

Die obige Lösung funktioniert zwar für Inhaltsskripte, aber Code, der direkt in die Seite eingeschleust wird (z.B. durch Anhängen eines <script>-Tags oder über inspectedWindow.eval) erfordert ein eine andere Strategie entwickeln. In diesem Kontext gibt runtime.sendMessage keine Nachrichten an den wie erwartet aus.

Als Behelfslösung können Sie Ihr eingefügtes Skript mit einem Inhaltsskript kombinieren, das als Vermittler. Um Nachrichten an das Inhaltsskript zu übergeben, können Sie den window.postMessage verwenden. der API erstellen. Hier ist ein Beispiel, bei dem das Hintergrundskript aus dem vorherigen Abschnitt angenommen wird:

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

Ihre Nachricht wird jetzt vom eingefügten Skript zum Inhaltsskript zum Hintergrund geleitet. und schließlich zur Entwicklertools-Seite.

Sie können hier auch zwei alternative Verfahren zur Nachrichtenweitergabe in Betracht ziehen.

Erkennen, wann die Entwicklertools geöffnet und geschlossen werden

Wenn deine Erweiterung erfassen muss, ob das Entwicklertools-Fenster geöffnet ist, kannst du ein onConnect-Element hinzufügen. Listener für die Hintergrundseite und rufe connect über die Entwicklertools-Seite auf. Da jeder Tab eigenes Entwicklertools-Fenster geöffnet ist, erhalten Sie möglicherweise mehrere Verbindungsereignisse. Um zu erfassen, ob Das Entwicklertools-Fenster ist geöffnet. Sie müssen die Ereignisse zum Herstellen und Trennen der Verbindung wie unten gezeigt zählen:

// 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 background page
var backgroundPageConnection = chrome.runtime.connect({
    name: "devtools-page"
});

Beispiele für Entwicklertools-Erweiterungen

Sieh dir die Quelle dieser Beispiele für Entwicklertools-Erweiterungen an:

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 für die Verwendung von DevTools APIs finden Sie unter Beispiele.