DevTools-Erweiterungen fügen Chrome-Entwicklertools Funktionen hinzu, indem sie über eine DevTools-Seite, die der Erweiterung hinzugefügt wird, auf DevTools-spezifische Erweiterungs-APIs zugreifen.
Die DevTools-spezifischen Erweiterungs-APIs umfassen Folgendes:
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. Diese Seite hat Zugriff auf die Entwicklertools-APIs und Erweiterungs-APIs und kann Folgendes tun:
- Mit den
devtools.panels-APIs können Sie Bereiche erstellen und mit ihnen interagieren. Dazu gehört auch, andere Erweiterungsseiten als Bereiche oder Seitenleisten zum Entwicklertools-Fenster hinzuzufügen. - Informationen zum untersuchten Fenster abrufen und Code im untersuchten Fenster mit den
devtools.inspectedWindow-APIs auswerten. - Mit den
devtools.network-APIs können Sie Informationen zu Netzwerkanfragen abrufen. - Erweitern Sie den Rekorderbereich mit den
devtools.recorder-APIs. - Mit den
devtools.performance-APIs können Sie Informationen zum Aufzeichnungsstatus des Leistungssteuerfelds abrufen.
Die Entwicklertools-Seite kann direkt auf Erweiterungs-APIs zugreifen. Dazu gehört auch die Möglichkeit, über message passing mit dem Service Worker zu kommunizieren.
Entwicklertools-Erweiterung erstellen
Wenn Sie eine DevTools-Seite für Ihre Erweiterung erstellen möchten, fügen Sie das Feld devtools_page in das Erweiterungsmanifest ein:
{
"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 Elemente der browser.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.
Der Browser-Namespace und DevTools-Erweiterungen
In Chrome-Version 152 und höher können Erweiterungen mit einer Entwicklertools-Seite den browser-Namespace verwenden.
In Chrome-Versionen vor Version 152 war der browser-Namespace für Erweiterungen deaktiviert, die devtools_page deklarieren. Das Deaktivieren galt für die gesamte Erweiterung, nicht nur für die Entwicklertools-Seite, sondern für jeden Skript-Kontext, in dem Erweiterungs-APIs ausgeführt werden.
Der Grund war eine Kompatibilitätslücke mit webextension-polyfill.
Die browser.devtools.*-APIs vor Chrome 152 waren reine Callback-APIs. Sie gaben keine nativen Promises zurück. Daher wurde in DevTools-Erweiterungen häufig das Polyfill verwendet, um sie zu umschließen. Das Polyfill überspringt das Wrapping, wenn browser definiert ist, da davon ausgegangen wird, dass der Host die Arbeit bereits erledigt hat. Wenn browser für diese Erweiterungen in Chrome aktiviert gewesen wäre, hätte das Polyfill keine Auswirkungen gehabt und browser.devtools.*-Aufrufe hätten keine Promises mehr zurückgegeben. Wenn browser deaktiviert war, wurde der Polyfill immer wieder umschlossen.
Durch dieselbe Deaktivierung wurden auch die anderen Änderungen an der Messaging API in Chrome 148 für diese Erweiterungen deaktiviert, einschließlich Promise-Antworten in runtime.onMessage.
Die Einschränkung wurde aufgehoben, sobald die Entwicklertools-APIs Promises nativ unterstützten.
UI-Elemente in den Entwicklertools: Bereiche und Seitenleistenbereiche
Zusätzlich zu den üblichen UI-Elementen von Erweiterungen wie Browseraktionen, Kontextmenüs und Pop-ups kann eine Entwicklertools-Erweiterung UI-Elemente zum Entwicklertools-Fenster hinzufügen:
- Ein Bereich ist ein Tab der obersten Ebene, z. B. die Bereiche „Elemente“, „Quellen“ und „Netzwerk“.
- In einem Seitenleistenbereich wird eine zusätzliche Benutzeroberfläche für ein bestimmtes Feld angezeigt. Die Bereiche „Stile“, „Berechnete Stile“ und „Event-Listener“ im Bereich „Elemente“ sind Beispiele für Seitenleistenbereiche. Je nach verwendeter Chrome-Version und Andockposition des Entwicklertools-Fensters sehen die Seitenleistenbereiche möglicherweise so aus wie im folgenden Beispielbild:
Jedes Feld ist eine eigene HTML-Datei, die andere Ressourcen (JavaScript, CSS, Bilder usw.) enthalten kann. Verwenden Sie den folgenden Code, um ein einfaches Feld zu erstellen:
browser.devtools.panels.create("My Panel",
"MyPanelIcon.png",
"Panel.html",
function(panel) {
// code invoked on panel creation
}
);
JavaScript, das in einem Bereich oder Seitenleistenbereich ausgeführt wird, hat Zugriff auf dieselben APIs wie die DevTools-Seite.
Verwenden Sie den folgenden Code, um einen einfachen Seitenleistenbereich zu erstellen:
browser.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-Inhalte: 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(). DevTools wertet den Ausdruck im Kontext der untersuchten Seite aus und zeigt dann den Rückgabewert an.
Für setObject() und setExpression() wird im Bereich der Wert so angezeigt, wie er in der Entwicklertools-Konsole zu sehen wäre. 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 Entwicklertools-Erweiterungskomponenten miteinander kommunizieren können.
Content-Script einfügen
So fügen Sie ein Content-Script ein: scripting.executeScript()
// DevTools page -- devtools.js
browser.scripting.executeScript({
target: {
tabId: browser.devtools.inspectedWindow.tabId
},
files: ["content_script.js"]
});
Sie können die Tab-ID des untersuchten Fensters mit der Eigenschaft inspectedWindow.tabId abrufen.
Wenn ein Content-Script bereits eingefügt wurde, können Sie Messaging-APIs verwenden, um damit zu kommunizieren.
JavaScript im untersuchten Fenster auswerten
Mit der Methode inspectedWindow.eval() können Sie JavaScript-Code im Kontext der untersuchten Seite ausführen. Sie können die Methode eval() über eine Entwicklertools-Seite, ein Entwicklertools-Fenster oder einen Entwicklertools-Seitenleistenbereich aufrufen.
Standardmäßig wird der Ausdruck im Kontext des Hauptframes der Seite ausgewertet.
inspectedWindow.eval() verwendet denselben Skriptausführungskontext und dieselben Optionen wie Code, der in die DevTools-Konsole eingegeben wird. Dadurch kann bei der Verwendung von eval() auf die Console Utilities API von DevTools zugegriffen werden. Sie können es beispielsweise verwenden, um das erste Script-Element im <head>-Abschnitt des HTML-Dokuments zu untersuchen:
browser.devtools.inspectedWindow.eval(
"inspect($$('head script')[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 vor dem Aufrufen von eval() eine statische Inhaltsdeklaration verwenden. Das kann entweder durch Aufrufen von executeScript() oder durch Angabe eines Inhaltsskripts in der manifest.json-Datei erfolgen. Nachdem der Kontext des Inhaltsskripts geladen wurde, können Sie diese Option auch verwenden, um zusätzliche Inhaltsskripte einzufügen.
Ausgewähltes Element an ein Inhaltsscript übergeben
Das Content-Script hat keinen direkten Zugriff auf das aktuell ausgewählte Element. Code, den Sie mit inspectedWindow.eval() ausführen, hat jedoch Zugriff auf die Entwicklertools-Konsole und die Console Utilities APIs. Im ausgewerteten Code können Sie beispielsweise mit $0 auf das ausgewählte Element zugreifen.
So übergeben Sie das ausgewählte Element an ein Inhaltsskript:
Erstellen Sie eine Methode im Content-Script, die das ausgewählte Element als Argument verwendet.
function setSelectedElement(el) { // do something with the selected element }Rufen Sie die Methode über die Entwicklertools-Seite mit
inspectedWindow.eval()und der OptionuseContentScriptContext: trueauf.browser.devtools.inspectedWindow.eval("setSelectedElement($0)", { useContentScriptContext: true });
Mit der Option useContentScriptContext: true wird angegeben, dass der Ausdruck im selben Kontext wie die Content-Scripts ausgewertet werden muss, damit auf die Methode setSelectedElement zugegriffen werden kann.
window eines Referenzbereichs abrufen
Wenn Sie postMessage() über ein Entwicklertools-Panel aufrufen möchten, benötigen Sie einen Verweis auf das zugehörige window-Objekt. So rufen Sie das Iframe-Fenster eines Bereichs über den Ereignis-Handler panel.onShown ab:
extensionPanel.onShown.addListener(function (extPanelWindow) {
extPanelWindow instanceof Window; // true
extPanelWindow.postMessage( // …
});
Nachrichten von eingefügten Skripts an die Entwicklertools-Seite senden
Code, der ohne Content-Script direkt in die Seite eingeschleust wird, z. B. durch Anhängen eines <script>-Tags oder Aufrufen von inspectedWindow.eval(), kann keine Nachrichten an die Entwicklertools-Seite senden, wenn runtime.sendMessage() verwendet wird. Stattdessen empfehlen wir, das eingefügte Skript mit einem Inhaltsskript 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;
}
browser.runtime.sendMessage(message);
});
Weitere alternative Techniken zur Nachrichtenübermittlung finden Sie auf GitHub.
Erkennen, wenn die Entwicklertools geöffnet und geschlossen werden
Um zu erfassen, ob das Entwicklertools-Fenster geöffnet ist, fügen Sie dem Service Worker einen onConnect-Listener hinzu und rufen Sie connect() über die Entwicklertools-Seite auf. Da für jeden Tab ein eigenes Entwicklertools-Fenster geöffnet sein kann, erhalten Sie möglicherweise mehrere Verbindungsereignisse. Um zu verfolgen, ob ein Entwicklertools-Fenster geöffnet ist, zählen Sie die Verbindungs- und Trennungsereignisse, wie im folgenden Beispiel gezeigt:
// background.js
var openCount = 0;
browser.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 DevTools-Seite wird eine Verbindung so hergestellt:
// devtools.js
// Create a connection to the service worker
const serviceWorkerConnection = browser.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 Devtools Extension: Hier werden viele Helfer auf der Hostseite ausgeführt, um den DOM-/JS-Status abzufragen und an das benutzerdefinierte Feld zurückzusenden.
- React DevTools-Erweiterung: Hier wird ein Untermodul des Renderers verwendet, um UI-Komponenten der Entwicklertools wiederzuverwenden.
- Ember Inspector: Gemeinsamer Erweiterungskern mit Adaptern für Chrome und Firefox.
- Coquette-inspect: Eine saubere React-basierte Erweiterung mit einem Debugging-Agent, der in die Hostseite eingefügt wird.
- Beispielerweiterungen bieten mehr lohnende Erweiterungen, die Sie installieren, ausprobieren und von denen Sie lernen können.
Weitere Informationen
Informationen zu den Standard-APIs, die Erweiterungen verwenden können, finden Sie unter browser.* APIs und Web-APIs.
Geben Sie uns Feedback. Ihr Feedback hilft uns, die APIs zu verbessern.
Beispiele
Beispiele für die Verwendung von Entwicklertools-APIs finden Sie unter Samples.