Estendi DevTools

Le estensioni di DevTools aggiungono funzionalità a Chrome DevTools accedendo alle API di estensioni specifiche di DevTools tramite una pagina di DevTools aggiunta all'estensione.

Diagramma dell'architettura che mostra la pagina di DevTools che comunica con la finestra ispezionata e il servizio worker. Il worker del servizio viene mostrato mentre comunica con gli script di contenuti e accede alle API di estensione.
         La pagina DevTools ha accesso alle API DevTools, ad esempio per la creazione di riquadri.
Architettura delle estensioni di DevTools.

Le API di estensione specifiche di DevTools includono quanto segue:

Pagina DevTools

Quando si apre una finestra di DevTools, un'estensione di DevTools crea un'istanza della propria pagina di DevTools che esiste finché la finestra è aperta. Questa pagina ha accesso alle API DevTools e alle API di estensione e può eseguire le seguenti operazioni:

La pagina DevTools può accedere direttamente alle API delle estensioni. Ciò include la possibilità di comunicare con il service worker utilizzando la trasmissione di messaggi.

Creare un'estensione DevTools

Per creare una pagina di DevTools per l'estensione, aggiungi il campo devtools_page nel manifest dell'estensione:

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

Il campo devtools_page deve puntare a una pagina HTML. Poiché la pagina DevTools deve essere locale per l'estensione, ti consigliamo di specificarla utilizzando un URL relativo.

Gli elementi dell'API chrome.devtools sono disponibili solo per le pagine caricate all'interno della finestra DevTools mentre è aperta. Gli script di contenuto e altre pagine dell'estensione non hanno accesso a queste API.

Elementi dell'interfaccia utente di DevTools: riquadri e riquadri della barra laterale

Oltre ai soliti elementi dell'interfaccia utente delle estensioni, come azioni del browser, menu contestuali e popup, un'estensione di DevTools può aggiungere elementi dell'interfaccia utente alla finestra di DevTools:

  • Un riquadro è una scheda di primo livello, come i riquadri Elementi, Origini e Rete.
  • Un riquadro della barra laterale presenta un'interfaccia utente supplementare relativa a un riquadro. I riquadri Stili, Stili elaborati e Listener eventi nel riquadro Elementi sono esempi di riquadri della barra laterale. A seconda della versione di Chrome in uso e della posizione in cui è agganciata la finestra di DevTools, i riquadri della barra laterale potrebbero avere l'aspetto dell'immagine di esempio seguente:
Finestra di DevTools che mostra il riquadro Elementi e il riquadro della barra laterale Stili.
Finestra di DevTools che mostra il riquadro Elementi e il riquadro della barra laterale Stili.

Ogni riquadro è un file HTML autonomo, che può includere altre risorse (JavaScript, CSS, immagini e così via). Per creare un riquadro di base, utilizza il seguente codice:

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

Il codice JavaScript eseguito in un riquadro o un riquadro della barra laterale ha accesso alle stesse API della pagina DevTools.

Per creare un riquadro della barra laterale di base, utilizza il seguente codice:

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

Esistono diversi modi per visualizzare i contenuti in un riquadro della barra laterale:

  • Contenuti HTML: chiama setPage() per specificare una pagina HTML da visualizzare nel riquadro.
  • Dati JSON: passa un oggetto JSON a setObject().
  • Espressione JavaScript: passa un'espressione a setExpression(). DevTools valuta l'espressione nel contesto della pagina ispezionata, quindi mostra il valore restituito.

Sia per setObject() che per setExpression(), il riquadro mostra il valore visualizzato nella console DevTools. Tuttavia, setExpression() consente di visualizzare elementi DOM e oggetti JavaScript arbitrari, mentre setObject() supporta solo gli oggetti JSON.

Comunicazione tra i componenti dell'estensione

Le sezioni seguenti descrivono alcuni modi utili per consentire ai componenti dell'estensione DevTools di comunicare tra loro.

Inserire uno script di contenuti

Per inserire uno script di contenuti, utilizza scripting.executeScript():

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

Puoi recuperare l'ID scheda della finestra ispezionata utilizzando la proprietà inspectedWindow.tabId.

Se è già stato inserito uno script di contenuti, puoi utilizzare le API di messaggistica per comunicare con esso.

Valutare JavaScript nella finestra ispezionata

Puoi utilizzare il metodo inspectedWindow.eval() per eseguire codice JavaScript nel contesto della pagina ispezionata. Puoi richiamare il metodo eval() da una pagina, un riquadro o un riquadro della barra laterale di DevTools.

Per impostazione predefinita, l'espressione viene valutata nel contesto del frame principale della pagina. inspectedWindow.eval() utilizza lo stesso contesto di esecuzione dello script e le stesse opzioni del codice inserito nella console DevTools, il che consente di accedere alle funzionalità dell'API Console Utilities di DevTools quando si utilizza eval(). Ad esempio, SOAK lo utilizza per ispezionare un elemento:

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

Puoi anche impostare useContentScriptContext su true quando chiami inspectedWindow.eval() per valutare l'espressione nello stesso contesto degli script dei contenuti. Per utilizzare questa opzione, utilizza una dichiarazione di script di contenuti statici prima di chiamare eval() chiamando executeScript() o specificando uno script di contenuti nel file manifest.json. Dopo aver caricato lo script di contesto, puoi utilizzare questa opzione anche per inserire script di contenuti aggiuntivi.

Passare l'elemento selezionato a uno script di contenuti

Lo script dei contenuti non ha accesso diretto all'elemento attualmente selezionato. Tuttavia, qualsiasi codice eseguito utilizzando inspectedWindow.eval() ha accesso alla console DevTools e alle API Console Utilities. Ad esempio, nel codice valutato puoi utilizzare $0 per accedere all'elemento selezionato.

Per passare l'elemento selezionato a uno script di contenuti:

  1. Crea un metodo nello script dei contenuti che prenda l'elemento selezionato come argomento.

    function setSelectedElement(el) {
        // do something with the selected element
    }
    
  2. Chiama il metodo dalla pagina DevTools utilizzando inspectedWindow.eval() con l'opzione useContentScriptContext: true.

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

L'opzione useContentScriptContext: true specifica che l'espressione deve essere valutata nello stesso contesto degli script dei contenuti, in modo da poter accedere al metodo setSelectedElement.

Ottenere il window di un riquadro di riferimento

Per chiamare postMessage() da un riquadro devtools, devi avere un riferimento al relativo oggetto window. Recupera la finestra iframe di un riquadro dal gestore eventi panel.onShown:

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

Inviare messaggi dagli script iniettati alla pagina di DevTools

Il codice iniettato direttamente nella pagina senza uno script di contenuti, ad esempio aggiungendo un tag <script> o chiamando inspectedWindow.eval(), non può inviare messaggi alla pagina DevTools utilizzando runtime.sendMessage(). Ti consigliamo invece di combinare lo script iniettato con uno script di contenuti che possa fungere da intermediario e di utilizzare il metodo window.postMessage(). L'esempio seguente utilizza lo script in background della sezione precedente:

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

Altre tecniche di trasmissione dei messaggi alternative sono disponibili su GitHub.

Rileva l'apertura e la chiusura di DevTools

Per monitorare se la finestra di DevTools è aperta, aggiungi un ascoltatore onConnect al servizio worker e chiama connect() dalla pagina di DevTools. Poiché ogni scheda può avere la propria finestra di DevTools aperta, potresti ricevere più eventi di connessione. Per monitorare se è aperta una finestra di DevTools, conteggia gli eventi di connessione e disconnessione come mostrato nel seguente esempio:

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

La pagina DevTools crea una connessione come questa:

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

Esempi di estensioni di DevTools

Gli esempi in questa pagina provengono dalle seguenti pagine:

  • Estensione DevTools di Polymer: utilizza molti helper in esecuzione nella pagina host per eseguire query sullo stato DOM/JS da inviare al riquadro personalizzato.
  • Estensione React DevTools: utilizza un sottomodulo del renderer per riutilizzare i componenti dell'interfaccia utente di DevTools.
  • Ember Inspector: nucleo dell'estensione condiviso con adattatori per Chrome e Firefox.
  • Coquette-inspect: un'estensione basata su React pulita con un agente di debug iniettato nella pagina dell'host.
  • Sample Extensions contiene più estensioni utili da installare, provare e da cui imparare.

Ulteriori informazioni

Per informazioni sulle API standard che le estensioni possono utilizzare, consulta chrome.* API e API web.

Inviaci il tuo feedback. I tuoi commenti e suggerimenti ci aiutano a migliorare le API.

Esempi

Puoi trovare esempi che utilizzano le API DevTools in Samples.