Panoramica
Un'estensione di DevTools aggiunge funzionalità a Chrome DevTools. Può aggiungere nuovi riquadri e riquadri laterali dell'interfaccia utente, interagire con la pagina ispezionata, ottenere informazioni sulle richieste di rete e altro ancora. Visualizza le estensioni DevTools in primo piano. Le estensioni di DevTools hanno accesso a un ulteriore insieme di API di estensioni specifiche di DevTools:
Un'estensione di DevTools è strutturata come qualsiasi altra estensione: può avere una pagina di sfondo, script di contenuti e altri elementi. Inoltre, ogni estensione DevTools ha una pagina DevTools con accesso alle API DevTools.
Pagina DevTools
Ogni volta che si apre una finestra di DevTools, viene creata un'istanza della pagina DevTools dell'estensione. La pagina DevTools esiste per tutta la durata della finestra DevTools. La pagina DevTools ha accesso alle API DevTools e a un insieme limitato di API di estensioni. Nello specifico, la pagina DevTools può:
- Crea e interagisci con i riquadri utilizzando le API
devtools.panels
. - Visualizza informazioni sulla finestra ispezionata e valuta il codice al suo interno utilizzando le API
devtools.inspectedWindow
. - Visualizza informazioni sulle richieste di rete utilizzando le API
devtools.network
.
La pagina DevTools non può utilizzare direttamente la maggior parte delle API di estensioni. Ha accesso allo stesso sottoinsieme
delle API extension
e runtime
a cui ha accesso uno script di contenuti. Come uno script di contenuti, una pagina di DevTools può comunicare con la pagina in background utilizzando il passaggio di messaggi. Per un
esempio, vedi Eseguire l'iniezione di uno script di contenuti.
Creazione di 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",
"minimum_chrome_version": "10.0",
"devtools_page": "devtools.html",
...
}
Per ogni finestra di DevTools aperta viene creata un'istanza di devtools_page
specificata nel manifest dell'estensione. La pagina può aggiungere altre pagine di estensioni come riquadri e barre laterali alla finestra di DevTools utilizzando l'API devtools.panels
.
I moduli dell'API chrome.devtools.*
sono disponibili solo per le pagine caricate all'interno della finestra DevTools. Gli script di contenuto e altre pagine di estensione non dispongono di queste API. Pertanto, le API sono disponibili solo per tutta la durata della finestra di DevTools.
Esistono anche alcune API DevTools ancora sperimentali. Fai riferimento a chrome.experimental.* API per l'elenco delle API sperimentali e le linee guida su come utilizzarle.
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. Tieni presente che l'aspetto dei riquadri della barra laterale potrebbe non corrispondere all'immagine, a seconda della versione di Chrome in uso e della posizione in cui è agganciata la finestra di DevTools.
Ogni riquadro è un file HTML autonomo, che può includere altre risorse (JavaScript, CSS, immagini e così via). La creazione di un riquadro di base è la seguente:
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 nel riquadro della barra 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. 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 e 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 scenari tipici per la comunicazione tra i diversi componenti di un'estensione di DevTools.
Inserire uno script di contenuti
La pagina DevTools non può chiamare direttamente tabs.executeScript
. Per iniettare uno script di contenuti dalla pagina DevTools, devi recuperare l'ID della scheda della finestra ispezionata utilizzando la proprietà inspectedWindow.tabId
e inviare un messaggio alla pagina di sfondo. Dalla pagina
di sfondo, chiama tabs.executeScript
per iniettare lo script.
I seguenti snippet di codice mostrano come iniettare 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 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. Ora potresti essere familiare con le funzionalità dell'API a riga di comando di DevTools, come l'ispezione degli elementi (inspect(elem)
), l'interruzione nelle funzioni (debug(fn)
), la copia negli appunti (copy()
) e altro ancora.
inspectedWindow.eval()
utilizza lo stesso contesto di esecuzione dello script e le stesse opzioni del codice digitato nella console di DevTools, che consente l'accesso a queste API all'interno di eval. 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, utilizza l'opzione useContentScriptContext: true
per inspectedWindow.eval()
per valutare l'espressione nello stesso contesto degli script dei contenuti. L'utilizzo di eval
con
useContentScriptContext: true
non create un contesto dello script di contenuti, quindi devi caricare un
script di contesto prima di chiamare eval
, chiamando executeScript
o specificando uno script di contenuti
nel file manifest.json
.
Una volta che lo script contestuale è stato creato, puoi utilizzare questa opzione per inserire script di contenuti aggiuntivi.
Il metodo eval
è efficace se utilizzato nel contesto giusto e pericoloso se usato in modo improprio. Utilizza il metodo tabs.executeScript
se non hai bisogno di accedere al
contesto JavaScript della pagina ispezionata. Per avvertenze dettagliate e un confronto tra i due metodi, consulta inspectedWindow
.
Trasmissione dell'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 di DevTools e alle API a riga di comando.
Ad esempio, nel codice valutato puoi utilizzare $0
per accedere all'elemento selezionato.
Per passare l'elemento selezionato a uno script di contenuti:
- Crea un metodo nello script dei contenuti che prenda l'elemento selezionato come argomento.
- Chiama il metodo dalla pagina DevTools utilizzando
inspectedWindow.eval
con l'opzioneuseContentScriptContext: true
.
Il codice nello script dei contenuti potrebbe avere il seguente aspetto:
function setSelectedElement(el) {
// do something with the selected element
}
Richiama il metodo dalla pagina DevTools come segue:
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 valore window
di un pannello di riferimento
Per postMessage
da un riquadro devtools, devi avere un 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( // …
});
Messaggistica dagli script di contenuti alla pagina DevTools
La messaggistica tra la pagina di DevTools e gli script dei contenuti è indiretta, tramite la pagina di sfondo.
Quando invia un messaggio a uno script di contenuti, la pagina di sfondo può utilizzare il metodo tabs.sendMessage
, che indirizza un messaggio agli script di contenuti in una scheda specifica, come mostrato in Inserimento di uno script di contenuti.
Quando invii un messaggio da uno script di contenuti, non esiste un metodo pronto all'uso per inviare un messaggio all'istanza della pagina DevTools corretta associata alla scheda corrente. Come soluzione alternativa, puoi fare in modo che la pagina DevTools stabilisca una connessione permanente con la pagina di sfondo e che quest'ultima mantenga una mappa degli ID scheda per le connessioni, in modo da poter indirizzare ogni messaggio alla connessione corretta.
// 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 del riquadro laterale o del riquadro 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
});
Messaggistica dagli script iniettati alla pagina DevTools
Sebbene la soluzione sopra riportata funzioni per gli script dei contenuti, il codice inserito direttamente nella pagina
(ad es. aggiungendo un tag <script>
o tramite inspectedWindow.eval
) richiede una
strategia diversa. In questo contesto, runtime.sendMessage
non passerà i messaggi allo script in background come previsto.
Come soluzione alternativa, puoi combinare lo script iniettato con uno script di contenuti che funge da intermediario. Per passare i messaggi allo script dei contenuti, puoi utilizzare l'API window.postMessage
. Ecco un esempio, supponendo 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 iniettato allo script dei contenuti, allo script di sfondo e infine alla pagina di DevTools.
Puoi anche prendere in considerazione due tecniche alternative di trasmissione dei messaggi qui.
Rilevare l'apertura e la chiusura di DevTools
Se l'estensione deve monitorare se la finestra di DevTools è aperta, puoi aggiungere un ascoltatore onConnect alla pagina in background e chiamare 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, 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 di DevTools
Sfoglia il codice sorgente di questi esempi di estensioni DevTools:
- 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 di Blink 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 inserito nella pagina dell'host.
- La nostra Galleria di estensioni di DevTools e le Estensioni di esempio contengono altre app 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.