Breid DevTools uit

DevTools-extensies voegen functionaliteit toe aan Chrome DevTools door toegang te krijgen tot DevTools-specifieke extensie-API's via een DevTools-pagina die aan de extensie is toegevoegd.

Architectuurdiagram dat laat zien hoe de DevTools-pagina communiceert met het geïnspecteerde venster en de service worker. De service worker communiceert met de content scripts en heeft toegang tot de extensie-API's.  De DevTools-pagina heeft toegang tot de DevTools-API's, bijvoorbeeld voor het maken van panelen.
Architectuur van de DevTools-extensie.

De DevTools-specifieke extensie-API's omvatten de volgende:

De DevTools-pagina

Wanneer een DevTools-venster wordt geopend, maakt een DevTools-extensie een instantie van de bijbehorende DevTools-pagina aan. Deze instantie blijft bestaan ​​zolang het venster open is. De pagina heeft toegang tot de DevTools-API's en extensie-API's en kan het volgende doen:

Via de DevTools-pagina heb je direct toegang tot de API's van extensies. Dit houdt onder andere in dat je via berichtoverdracht met de service worker kunt communiceren.

Een DevTools-extensie maken

Om een ​​DevTools-pagina voor uw extensie te maken, voegt u het veld devtools_page toe aan het extensiemanifest:

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

Het veld devtools_page moet verwijzen naar een HTML-pagina. Omdat de DevTools-pagina lokaal moet zijn voor uw extensie, raden we aan een relatieve URL te gebruiken.

De API-leden van chrome.devtools zijn alleen beschikbaar voor pagina's die geladen zijn binnen het DevTools-venster zolang dat venster geopend is. Inhoudsscripts en andere extensiepagina's hebben geen toegang tot deze API's.

UI-elementen van DevTools: panelen en zijbalken

Naast de gebruikelijke UI-elementen van extensies, zoals browseracties, contextmenu's en pop-ups, kan een DevTools-extensie ook UI-elementen aan het DevTools-venster toevoegen:

  • Een paneel is een tabblad op het hoogste niveau, zoals de panelen Elementen, Bronnen en Netwerk.
  • Een zijpaneel toont aanvullende gebruikersinterface-elementen die bij een paneel horen. De panelen Stijlen, Berekende stijlen en Gebeurtenislisteners in het paneel Elementen zijn voorbeelden van zijpanelen. Afhankelijk van de versie van Chrome die u gebruikt en waar het DevTools-venster is gedockt, kunnen uw zijpanelen eruitzien zoals in de volgende voorbeeldafbeelding:
Het DevTools-venster toont het Elementen-paneel en het Stijlen-zijpaneel.
Het DevTools-venster toont het Elementen-paneel en het Stijlen-zijpaneel.

Elk paneel is een eigen HTML-bestand, dat andere elementen kan bevatten (JavaScript, CSS, afbeeldingen, enzovoort). Gebruik de volgende code om een ​​basispaneel te maken:

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

JavaScript dat wordt uitgevoerd in een paneel of zijbalk heeft toegang tot dezelfde API's als de DevTools-pagina.

Om een ​​eenvoudig zijpaneel te maken, gebruikt u de volgende code:

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

Er zijn verschillende manieren om inhoud in een zijbalk weer te geven:

  • HTML-inhoud: Roep setPage() aan om een ​​HTML-pagina op te geven die in het paneel moet worden weergegeven.
  • JSON-gegevens: Geef een JSON-object door aan setObject() .
  • JavaScript-expressie: Geef een expressie door aan setExpression() . DevTools evalueert de expressie in de context van de geïnspecteerde pagina en geeft vervolgens de retourwaarde weer.

Bij zowel setObject() als setExpression() wordt de waarde in het venster weergegeven zoals deze in de DevTools-console zou verschijnen. Met setExpression() kunt u echter DOM-elementen en willekeurige JavaScript-objecten weergeven, terwijl setObject() alleen JSON-objecten ondersteunt.

Communicatie tussen uitbreidingscomponenten

In de volgende paragrafen worden enkele handige manieren beschreven om DevTools-extensiecomponenten met elkaar te laten communiceren.

Een inhoudsscript invoegen

Om een ​​script met inhoud te injecteren, gebruikt u scripting.executeScript() :

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

Je kunt de tab-ID van het geïnspecteerde venster ophalen met behulp van de eigenschap inspectedWindow.tabId .

Als er al een contentscript is geïnjecteerd, kunt u berichten-API's gebruiken om ermee te communiceren.

Evalueer JavaScript in het geïnspecteerde venster.

Je kunt de methode inspectedWindow.eval() gebruiken om JavaScript-code uit te voeren in de context van de geïnspecteerde pagina. Je kunt de eval() -methode aanroepen vanuit een pagina, paneel of zijbalk van de ontwikkelaarstools.

Standaard wordt de expressie geëvalueerd in de context van het hoofdframe van de pagina. inspectedWindow.eval() gebruikt dezelfde scriptuitvoeringscontext en opties als code die in de DevTools-console wordt ingevoerd, waardoor toegang mogelijk is tot de API-functies van DevTools Console Utilities bij gebruik eval() . Gebruik het bijvoorbeeld om het eerste scriptelement binnen de <head> -sectie van het HTML-document te inspecteren:

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

Je kunt useContentScriptContext ook op true zetten bij het aanroepen van inspectedWindow.eval() om de expressie in dezelfde context als de contentscripts te evalueren. Om deze optie te gebruiken, moet je een statische contentscriptdeclaratie gebruiken vóór het aanroepen eval() , door executeScript() aan te roepen of door een contentscript in het manifest.json bestand op te geven. Nadat de contentscriptcontext is geladen, kun je deze optie ook gebruiken om extra contentscripts te injecteren.

Geef het geselecteerde element door aan een inhoudsscript.

Het script dat de inhoud weergeeft, heeft geen directe toegang tot het momenteel geselecteerde element. Code die je uitvoert met inspectedWindow.eval() heeft echter wel toegang tot de DevTools-console en de Console Utilities API's. In geëvalueerde code kun je bijvoorbeeld $0 gebruiken om toegang te krijgen tot het geselecteerde element.

Om het geselecteerde element door te geven aan een contentscript:

  1. Maak in het contentscript een methode aan die het geselecteerde element als argument accepteert.

    function setSelectedElement(el) {
        // do something with the selected element
    }
    
  2. Roep de methode aan vanuit de DevTools-pagina met behulp van inspectedWindow.eval() met de optie useContentScriptContext: true .

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

De optie useContentScriptContext: true geeft aan dat de expressie in dezelfde context als de content scripts moet worden geëvalueerd, zodat de setSelectedElement -methode kan worden aangeroepen.

window van een referentiepaneel openen

Om postMessage() vanuit een ontwikkelaarstools-paneel aan te roepen, hebt u een verwijzing naar het window nodig. U kunt het iframe-venster van een paneel verkrijgen via de eventhandler panel.onShown :

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

Verzend berichten vanuit geïnjecteerde scripts naar de DevTools-pagina.

Code die rechtstreeks in de pagina wordt geïnjecteerd zonder een contentscript, bijvoorbeeld door een <script> -tag toe te voegen of inspectedWindow.eval() aan te roepen, kan geen berichten naar de DevTools-pagina verzenden met runtime.sendMessage() . In plaats daarvan raden we aan om uw geïnjecteerde script te combineren met een contentscript dat als tussenpersoon kan fungeren en de window.postMessage() methode te gebruiken. Het volgende voorbeeld gebruikt het achtergrondscript uit de vorige sectie:

// 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 alternatieve berichtuitwisselingstechnieken zijn te vinden op GitHub .

Detecteer wanneer DevTools wordt geopend en gesloten.

Om bij te houden of het DevTools-venster geopend is, voegt u een onConnect- listener toe aan de service worker en roept u de methode connect() aan vanuit de DevTools-pagina. Omdat elk tabblad een eigen DevTools-venster kan hebben geopend, kunt u meerdere verbindingsgebeurtenissen ontvangen. Om bij te houden of er een DevTools-venster geopend is, telt u de verbindings- en ontkoppelingsgebeurtenissen zoals in het volgende voorbeeld:

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

De DevTools-pagina maakt een verbinding zoals deze:

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

Voorbeelden van DevTools-extensies

De voorbeelden op deze pagina zijn afkomstig van de volgende pagina's:

  • Polymer Devtools-extensie - Maakt gebruik van diverse hulpprogramma's die op de hostpagina draaien om de DOM/JS-status op te vragen en terug te sturen naar het aangepaste paneel.
  • React DevTools-extensie - Gebruikt een submodule van de renderer om DevTools UI-componenten te hergebruiken.
  • Ember Inspector - Gedeelde extensiekern met adapters voor zowel Chrome als Firefox.
  • Coquette-inspect - Een strakke, op React gebaseerde extensie met een debug-agent die in de hostpagina is geïnjecteerd.
  • Sample Extensions bevat meer nuttige extensies om te installeren, uit te proberen en van te leren.

Meer informatie

Voor informatie over de standaard-API's die extensies kunnen gebruiken, zie chrome.* API's en web-API's .

Geef ons feedback! Uw opmerkingen en suggesties helpen ons de API's te verbeteren.

Voorbeelden

Voorbeelden van het gebruik van DevTools API's vindt u in de sectie Voorbeelden .