Estensione di DevTools

Panoramica

Un'estensione DevTools aggiunge funzionalità a Chrome DevTools. Può aggiungere nuovi riquadri dell'interfaccia utente barre laterali, interagire con la pagina ispezionata, ottenere informazioni sulle richieste di rete e altro ancora. Visualizza estensioni DevTools in primo piano. Le estensioni DevTools hanno accesso a un insieme aggiuntivo di API di estensione specifiche per DevTools:

Un'estensione DevTools è strutturata come qualsiasi altra estensione: può avere una pagina in background, contenuti script e altri elementi. Inoltre, ogni estensione DevTools dispone di una pagina DevTools, che può accedere. alle API DevTools.

Diagramma dell'architettura che mostra la pagina DevTools che comunica con il
       finestra ispezionata e pagina di sfondo. Viene mostrata la pagina di sfondo
       comunicare con gli script di contenuti e accedere alle API delle estensioni.
       La pagina DevTools ha accesso alle API DevTools, ad esempio per la creazione di riquadri.

Pagina DevTools

Ogni volta che si apre una finestra DevTools, viene creata un'istanza della pagina DevTools dell'estensione. La La pagina DevTools esiste per tutta la durata della finestra DevTools. La pagina DevTools ha accesso API DevTools e un insieme limitato di API di estensione. In particolare, la pagina DevTools può:

  • Crea e interagisci con i riquadri utilizzando le API devtools.panels.
  • Recupera le informazioni sulla finestra ispezionata e valuta il codice al suo interno utilizzando API di devtools.inspectedWindow.
  • Recuperare informazioni sulle richieste di rete utilizzando le API devtools.network.

La pagina DevTools non può utilizzare direttamente la maggior parte delle API delle estensioni. Ha accesso allo stesso sottoinsieme delle API extension e runtime a cui ha accesso uno script di contenuti. Mettere Mi piace a un contenuto una pagina DevTools può comunicare con la pagina in background utilizzando la funzionalità Trasmissione dei messaggi. Per un consulta l'articolo sull'inserimento di uno script di contenuti.

Creazione di un'estensione DevTools

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

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

Viene creata un'istanza di devtools_page specificata nel manifest dell'estensione per ogni Finestra DevTools aperta. La pagina potrebbe aggiungere altre pagine di estensioni sotto forma di riquadri e barre laterali alla Finestra DevTools utilizzando l'API devtools.panels.

I moduli API chrome.devtools.* sono disponibili solo per le pagine caricate in DevTools finestra. Gli script dei contenuti e altre pagine di estensioni non dispongono di queste API. Di conseguenza, le API vengono e sarà disponibile solo per tutta la durata della finestra DevTools.

Esistono anche alcune API DevTools ancora sperimentali. Fai riferimento a chrome.experimental.* API per consultare l'elenco delle API sperimentali e le linee guida su come utilizzarle.

Elementi UI DevTools: riquadri e riquadri della barra laterale

Oltre ai soliti elementi dell'interfaccia utente delle estensioni, come le azioni del browser, i menu contestuali e i popup, è disponibile L'estensione DevTools può aggiungere elementi UI alla finestra DevTools:

  • Un riquadro è una scheda di primo livello, come i riquadri Elementi, Sorgenti e Rete.
  • Un riquadro della barra laterale presenta una UI supplementare relativa a un riquadro. Stili, stili elaborati e I riquadri Listener di eventi nel riquadro Elementi sono esempi di riquadri della barra laterale. Tieni presente che l'aspetto dei riquadri della barra laterale potrebbe non corrispondere all'immagine, a seconda della versione di Chrome e il punto in cui la finestra DevTools è agganciata.)

Finestra DevTools che mostra il riquadro Elementi e il riquadro della barra laterale Stili.

Ogni riquadro è il proprio file HTML, che può includere altre risorse (JavaScript, CSS, immagini attiva). La creazione di un riquadro di base ha il seguente aspetto:

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 in un riquadro laterale ha accesso alle stesse API della pagina DevTools.

La creazione di un riquadro della barra laterale di base per il riquadro Elementi ha il seguente aspetto:

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. Richiama setPage per specificare una pagina HTML da visualizzare nel riquadro.
  • Dati JSON. Trasmetti un oggetto JSON a setObject.
  • espressione JavaScript. Passa un'espressione a setExpression. DevTools valuta nel contesto della pagina ispezionata, oltre a visualizzare il valore restituito.

Sia per setObject che per setExpression, il riquadro mostra il valore come apparirebbe nel Console DevTools. Tuttavia, setExpression consente di visualizzare elementi DOM e JavaScript arbitrario mentre setObject supporta solo oggetti JSON.

Comunicazione tra i componenti delle estensioni

Le seguenti sezioni descrivono alcuni scenari tipici di comunicazione tra i diversi di un'estensione DevTools.

Inserimento di uno script di contenuti

La pagina DevTools non può chiamare direttamente tabs.executeScript. Per inserire uno script di contenuti da pagina DevTools, devi recuperare l'ID della scheda della finestra ispezionata utilizzando inspectedWindow.tabId e inviare un messaggio alla pagina di sfondo. Da pagina di sfondo, richiama tabs.executeScript per inserire lo script.

I seguenti snippet di codice mostrano come inserire uno script di contenuti utilizzando executeScript.

// DevTools page -- devtools.js
// Create a connection to the background page
var backgroundPageConnection = chrome.runtime.connect({
    name: "devtools-page"
});

backgroundPageConnection.onMessage.addListener(function (message) {
    // Handle responses from the background page, if any
});

// Relay the tab ID to the background page
chrome.runtime.sendMessage({
    tabId: chrome.devtools.inspectedWindow.tabId,
    scriptToInject: "content_script.js"
});

Codice per la pagina di sfondo:

// Background page -- background.js
chrome.runtime.onConnect.addListener(function(devToolsConnection) {
    // assign the listener function to a variable so we can remove it later
    var devToolsListener = function(message, sender, sendResponse) {
        // Inject a content script into the identified tab
        chrome.tabs.executeScript(message.tabId,
            { file: message.scriptToInject });
    }
    // add the listener
    devToolsConnection.onMessage.addListener(devToolsListener);

    devToolsConnection.onDisconnect.addListener(function() {
         devToolsConnection.onMessage.removeListener(devToolsListener);
    });
});

Valutazione di JavaScript nella finestra ispezionata

Puoi utilizzare il metodo inspectedWindow.eval per eseguire il 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. Puoi Avere familiarità con le funzionalità dell'API a riga di comando di DevTools, come l'ispezione degli elementi. (inspect(elem)), l'interruzione delle funzioni (debug(fn)), la copia negli appunti (copy()) e altro ancora. inspectedWindow.eval() utilizza lo stesso contesto e le stesse opzioni di esecuzione dello script del codice digitato nella Console DevTools, che consente di accedere a queste API all'interno della valutazione. Ad esempio, SOAK lo utilizza per ispezionare un elemento:

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

In alternativa, usa l'opzione useContentScriptContext: true per inspectedWindow.eval() per valutano l'espressione nello stesso contesto degli script di contenuti. Chiamata a eval con useContentScriptContext: true non crea un contesto di script di contenuti, quindi devi caricare un script di contesto prima di chiamare eval, chiamando executeScript o specificando un contenuto nel file manifest.json.

Quando il contesto dello script di contesto esiste, puoi utilizzare questa opzione per inserire altri contenuti script.

Il metodo eval è efficace se usato nel contesto giusto e pericoloso se usato in modo inappropriato. Utilizza il metodo tabs.executeScript se non hai bisogno dell'accesso al Contesto JavaScript della pagina ispezionata. Per avvertenze dettagliate e un confronto tra i due metodi, consulta inspectedWindow.

Trasmettere l'elemento selezionato a uno script di contenuti

Lo script dei contenuti non ha accesso diretto all'elemento attualmente selezionato. Tuttavia, qualsiasi codice l'esecuzione con inspectedWindow.eval dispone dell'accesso alla console DevTools e alle API a riga di comando. Ad esempio, nel codice valutato puoi usare $0 per accedere all'elemento selezionato.

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

  • Crea un metodo nello script dei contenuti che utilizzi l'elemento selezionato come argomento.
  • Chiama il metodo dalla pagina DevTools utilizzando inspectedWindow.eval con la Opzione useContentScriptContext: true.

Il codice nello script dei contenuti potrebbe essere simile al seguente:

function setSelectedElement(el) {
    // do something with the selected element
}

Richiama il metodo dalla pagina DevTools nel seguente modo:

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

L'opzione useContentScriptContext: true specifica che l'espressione deve essere valutata nel campo stesso contesto degli script di contenuti, in modo che possa accedere al metodo setSelectedElement.

Recupero di un window del riquadro di riferimento in corso...

Per eseguire il comando postMessage da un riquadro DevTools, devi fare riferimento al relativo oggetto window. Recupera la finestra iframe di un riquadro dal gestore di eventi panel.onShown:

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

Messaggi dagli script di contenuti alla pagina DevTools

La messaggistica tra la pagina DevTools e gli script di contenuti è indiretta, attraverso la pagina in background.

Quando invii un messaggio a uno script di contenuti, la pagina di sfondo può utilizzare lo script tabs.sendMessage, che indirizza un messaggio agli script di contenuti in una scheda specifica. come mostrato in Inserimento di uno script di contenuti.

Quando si invia un messaggio da uno script di contenuti, non esiste un metodo pronto all'uso per recapitare un messaggio all'istanza della pagina DevTools corretta associata alla scheda corrente. Come soluzione alternativa, puoi avere la pagina DevTools stabilisce una connessione di lunga durata con la pagina in background e pagina di sfondo mantiene una mappa degli ID scheda alle connessioni, in modo da poter indirizzare ogni messaggio al messaggio connessione.

// background.js
var connections = {};

chrome.runtime.onConnect.addListener(function (port) {

    var extensionListener = function (message, sender, sendResponse) {

        // The original connection event doesn't include the tab ID of the
        // DevTools page, so we need to send it explicitly.
        if (message.name == "init") {
          connections[message.tabId] = port;
          return;
        }

    // other message handling
    }

    // Listen to messages sent from the DevTools page
    port.onMessage.addListener(extensionListener);

    port.onDisconnect.addListener(function(port) {
        port.onMessage.removeListener(extensionListener);

        var tabs = Object.keys(connections);
        for (var i=0, len=tabs.length; i < len; i++) {
          if (connections[tabs[i]] == port) {
            delete connections[tabs[i]]
            break;
          }
        }
    });
});

// Receive message from content script and relay to the devTools page for the
// current tab
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    // Messages from content scripts should have sender.tab set
    if (sender.tab) {
      var tabId = sender.tab.id;
      if (tabId in connections) {
        connections[tabId].postMessage(request);
      } else {
        console.log("Tab not found in connection list.");
      }
    } else {
      console.log("sender.tab not defined.");
    }
    return true;
});

La pagina DevTools (o il riquadro o il riquadro della barra laterale) stabilisce la connessione nel seguente modo:

// Create a connection to the background page
var backgroundPageConnection = chrome.runtime.connect({
    name: "panel"
});

backgroundPageConnection.postMessage({
    name: 'init',
    tabId: chrome.devtools.inspectedWindow.tabId
});

Messaggi dagli script inseriti alla pagina DevTools

La soluzione descritta sopra funziona per gli script di contenuti, ma il codice viene inserito direttamente nella pagina. (ad es. mediante l'aggiunta di un tag <script> o tramite inspectedWindow.eval) richiede un strategia diversa. In questo contesto, runtime.sendMessage non trasferirà messaggi alla come previsto.

Come soluzione alternativa, puoi combinare lo script inserito con uno script dei contenuti che funga da intermediario. Per trasmettere i messaggi allo script dei contenuti, puoi utilizzare la window.postMessage tramite Google Cloud CLI o tramite l'API Compute Engine. Ecco un esempio, supponendo che 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
  if (typeof message !== 'object' || message === null ||
      !message.source === 'my-devtools-extension') {
    return;
  }

  chrome.runtime.sendMessage(message);
});

Il messaggio passerà dallo script inserito allo script dei contenuti, allo sfondo e infine alla pagina DevTools.

Puoi anche prendere in considerazione due tecniche alternative di trasmissione dei messaggi qui.

Rilevamento dell'apertura e della chiusura di DevTools

Se l'estensione deve monitorare se la finestra DevTools è aperta, puoi aggiungere un'estensione onConnect listener sulla pagina in background e chiama connect dalla pagina DevTools. Poiché ogni scheda può con una finestra DevTools aperta, potresti ricevere più eventi di connessione. Per monitorare l'eventuale presenza di La finestra DevTools è aperta. Devi conteggiare gli eventi di connessione e disconnessione come mostrato di seguito:

// 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 background page
var backgroundPageConnection = chrome.runtime.connect({
    name: "devtools-page"
});

Esempi di estensioni DevTools

Sfoglia l'origine di questi esempi di estensioni DevTools:

Ulteriori informazioni

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

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