Breid DevTools uit

DevTools-extensies voegen functies 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 waarop de DevTools-pagina wordt weergegeven die communiceert met het geïnspecteerde venster en de servicemedewerker. Er wordt getoond dat de servicemedewerker communiceert met de inhoudsscripts en toegang heeft tot extensie-API's. De DevTools-pagina heeft toegang tot de DevTools API's, waarmee u bijvoorbeeld panelen kunt maken.
DevTools-extensiearchitectuur.

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

De DevTools-pagina

Wanneer een DevTools-venster wordt geopend, maakt een DevTools-extensie een exemplaar van de DevTools-pagina die bestaat zolang het venster open is. Deze pagina heeft toegang tot de DevTools API's en extensie-API's en kan het volgende doen:

  • Creëer en communiceer met panelen met behulp van de devtools.panels API's, inclusief het toevoegen van andere extensiepagina's als panelen of zijbalken aan het DevTools-venster.
  • Krijg informatie over het geïnspecteerde venster en evalueer code in het geïnspecteerde venster met behulp van de devtools.inspectedWindow API's.
  • Krijg informatie over netwerkverzoeken met behulp van de devtools.network API's.
  • Breid het Recorder-paneel uit met de devtools.recorder API's.

De DevTools-pagina heeft rechtstreeks toegang tot extensie-API's. Dit omvat ook de mogelijkheid om met de servicemedewerker te communiceren via het doorgeven van berichten .

Maak een DevTools-extensie

Als u een DevTools-pagina voor uw extensie wilt maken, voegt u het veld devtools_page toe aan het extensiemanifest:

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

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

De leden van de chrome.devtools API zijn alleen beschikbaar voor de pagina's die in het DevTools-venster worden geladen terwijl dat venster open is. Inhoudsscripts en andere extensiepagina's hebben geen toegang tot deze API's.

DevTools UI-elementen: panelen en zijbalkvensters

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

  • Een paneel is een tabblad op het hoogste niveau, net als de panelen Elementen, Bronnen en Netwerk.
  • Een zijbalkvenster presenteert een aanvullende gebruikersinterface met betrekking tot een paneel. De deelvensters Stijlen, Berekende stijlen en Gebeurtenislisteners in het paneel Elementen zijn voorbeelden van zijbalkvensters. Afhankelijk van de versie van Chrome die u gebruikt en waar het DevTools-venster is gekoppeld, kunnen uw zijbalkvensters er uitzien als in de volgende voorbeeldafbeelding:
DevTools-venster met het paneel Elementen en het zijbalkpaneel Stijlen.
DevTools-venster met het paneel Elementen en het zijbalkpaneel Stijlen.

Elk paneel is een eigen HTML-bestand, dat andere bronnen 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 zijbalkvenster heeft toegang tot dezelfde API's als de DevTools-pagina.

Gebruik de volgende code om een ​​eenvoudig zijbalkvenster te maken:

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 zijbalkvenster weer te geven:

  • HTML-inhoud: Roep setPage() om een ​​HTML-pagina op te geven die in het deelvenster 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 geretourneerde waarde weer.

Voor zowel setObject() als setExpression() geeft het deelvenster de waarde weer zoals deze zou verschijnen in de DevTools-console. setExpression() kunt u echter DOM-elementen en willekeurige JavaScript-objecten weergeven, terwijl setObject() alleen JSON-objecten ondersteunt.

Communiceer tussen uitbreidingscomponenten

In de volgende secties worden enkele handige manieren beschreven waarmee DevTools-extensiecomponenten met elkaar kunnen communiceren.

Een inhoudsscript injecteren

Gebruik scripting.executeScript() om een ​​inhoudsscript te injecteren:

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

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

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

Evalueer JavaScript in het geïnspecteerde venster

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

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 is ingevoerd in de DevTools-console, waardoor toegang wordt verleend tot de API-functies van DevTools Console Utilities bij gebruik van eval() . SOAK gebruikt het bijvoorbeeld voor het inspecteren van een element:

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

U kunt ook de useContentScriptContext instellen op true wanneer u inspectedWindow.eval() aanroept om de expressie in dezelfde context te evalueren als de inhoudsscripts. Als u deze optie wilt gebruiken, gebruikt u een statische inhoudsscriptdeclaratie voordat u eval() aanroept, door executeScript() aan te roepen of door een inhoudsscript op te geven in het bestand manifest.json . Nadat de contextscriptcontext is geladen, kunt u deze optie ook gebruiken om aanvullende inhoudscripts te injecteren.

Geef het geselecteerde element door aan een inhoudsscript

Het inhoudsscript heeft geen directe toegang tot het huidige geselecteerde element. Elke code die u uitvoert met inspectedWindow.eval() heeft echter toegang tot de DevTools-console en de Console Utilities-API's. In geëvalueerde code kunt u bijvoorbeeld $0 gebruiken om toegang te krijgen tot het geselecteerde element.

Het geselecteerde element doorgeven aan een inhoudsscript:

  1. Maak een methode in het inhoudsscript die het geselecteerde element als argument gebruikt.

    function setSelectedElement(el) {
        // do something with the selected element
    }
    
  2. Roep de methode aan vanaf 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 moet worden geëvalueerd in dezelfde context als de inhoudsscripts, zodat deze toegang krijgt tot de methode setSelectedElement .

Verkrijg het window van een referentiepaneel

Om postMessage() vanuit een devtools-paneel aan te roepen, hebt u een verwijzing naar het window object nodig. Haal het iframe-venster van een paneel op via de gebeurtenishandler panel.onShown :

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

Stuur berichten van geïnjecteerde scripts naar de DevTools-pagina

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

// 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 technieken voor het doorgeven van berichten 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 servicemedewerker en roept u connect() aan vanaf de DevTools-pagina. Omdat op elk tabblad een eigen DevTools-venster geopend kan zijn, ontvangt u mogelijk meerdere connect-gebeurtenissen. Om bij te houden of er een DevTools-venster geopend is, telt u de gebeurtenissen voor verbinden en verbreken, zoals weergegeven 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 als 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 komen van de volgende pagina's:

  • Polymer Devtools-extensie - Gebruikt veel helpers 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 opnieuw te gebruiken.
  • Ember Inspector - Gedeelde extensiekern met adapters voor zowel Chrome als Firefox.
  • Coquette-inspect - Een schone, op React gebaseerde extensie met een foutopsporingsagent die in de hostpagina is geïnjecteerd.
  • Voorbeeldextensies hebben waardevollere extensies om te installeren, uit te proberen en van te leren.

Meer informatie

Zie chrome.* API's en web-API's voor informatie over de standaard API's die extensies kunnen gebruiken.

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 Samples .