Estendi DevTools

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

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

Le API di estensione specifiche di DevTools includono quanto segue:

Pagina DevTools

Quando si apre una finestra DevTools, un'estensione DevTools crea un'istanza della relativa pagina DevTools che esiste finché la finestra è aperta. Questa pagina ha accesso alle API DevTools e alle API delle estensioni e può:

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

Creare un'estensione DevTools

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

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

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

I membri dell'API chrome.devtools sono disponibili solo per le pagine caricate all'interno della finestra DevTools mentre questa è aperta. Gli script dei contenuti e le altre pagine dell'estensione non hanno accesso a queste API.

Lo spazio dei nomi del browser e le estensioni DevTools

Lo spazio dei nomi browser introdotto in Chrome 148 è disattivato per le estensioni che dichiarano devtools_page. Il ritiro si applica all'intera estensione, non solo alla pagina DevTools, ma a ogni contesto di script in cui vengono eseguite le API delle estensioni. Continua a utilizzare chrome.* in queste estensioni.

Il motivo è una lacuna di compatibilità con webextension-polyfill. Le API chrome.devtools.* sono solo di callback, non restituiscono ancora le promesse in modo nativo, quindi le estensioni DevTools si basano comunemente sul polyfill per eseguirle. Il polyfill salta il wrapping ogni volta che è definito browser, supponendo che l'host abbia già svolto il lavoro. Se Chrome ha attivato browser per queste estensioni, il polyfill non funzionerà e le chiamate chrome.devtools.* smetteranno di restituire promesse. Se browser è disattivato, il polyfill continua a eseguire il wrapping.

La stessa disattivazione disabilita anche le altre modifiche all'API Messaging di Chrome 148 per queste estensioni, tra cui le risposte Promise in runtime.onMessage. La limitazione verrà rimossa una volta che le API DevTools supporteranno le promesse in modo nativo.

Elementi della UI di DevTools: pannelli e riquadri della barra laterale

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

  • Un pannello è una scheda di primo livello, come i pannelli Elementi, Origini e Rete.
  • Un riquadro della barra laterale presenta un'interfaccia utente supplementare correlata a un pannello. I riquadri Stili, Stili calcolati e Listener di eventi nel riquadro Elementi sono esempi di riquadri della barra laterale. A seconda della versione di Chrome che utilizzi e della posizione in cui è ancorata la finestra DevTools, i riquadri della barra laterale potrebbero essere simili all'immagine di esempio seguente:
Finestra 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 separato, che può includere altre risorse (JavaScript, CSS, immagini e così via). Per creare un pannello 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 del pannello o 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 esaminata, quindi visualizza il valore restituito.

Per setObject() e setExpression(), il riquadro mostra il valore così come apparirebbe nella console DevTools. Tuttavia, setExpression() consente di visualizzare elementi DOM e oggetti JavaScript arbitrari, mentre setObject() supporta solo oggetti JSON.

Comunicare 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 un content script, 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 uno script dei contenuti è già stato inserito, puoi utilizzare le API di messaggistica per comunicare con esso.

Valuta JavaScript nella finestra ispezionata

Puoi utilizzare il metodo inspectedWindow.eval() per eseguire codice JavaScript nel contesto della pagina esaminata. 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 e le stesse opzioni dello script del codice inserito nella console DevTools, il che consente l'accesso alle funzionalità dell'API Console Utilities quando si utilizza eval(). Ad esempio, utilizzalo per ispezionare il primo elemento script all'interno della sezione <head> del documento HTML:

chrome.devtools.inspectedWindow.eval(
  "inspect($$('head script')[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, usa una dichiarazione di script dei contenuti statici prima di chiamare eval(), chiamando executeScript() o specificando uno script dei contenuti nel file manifest.json. Dopo il caricamento del contesto dello script di contenuti, puoi utilizzare questa opzione anche per inserire script di contenuti aggiuntivi.

Passare l'elemento selezionato a uno script dei contenuti

Lo script dei contenuti non ha accesso diretto all'elemento 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 dei contenuti:

  1. Crea un metodo nello script dei contenuti che accetta 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 degli strumenti di sviluppo, devi avere un riferimento al relativo oggetto window. Recupera la finestra iframe di un pannello dal gestore di eventi panel.onShown:

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

Inviare messaggi dagli script inseriti alla pagina DevTools

Il codice inserito direttamente nella pagina senza uno script dei 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 inserito con uno script dei contenuti che può fungere da intermediario e di utilizzare il metodo window.postMessage(). L'esempio seguente utilizza lo script di sfondo 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 alternative di passaggio dei messaggi sono disponibili su GitHub.

Rilevare quando DevTools si apre e si chiude

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

// 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 DevTools

Gli esempi riportati in questa pagina provengono dalle seguenti pagine:

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

Ulteriori informazioni

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

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

Esempi

Puoi trovare esempi che utilizzano le API DevTools in Samples.