Présentation
Une extension d'outils de développement ajoute des fonctionnalités aux outils pour les développeurs Chrome. Il peut ajouter de nouveaux panneaux et barres latérales d'UI, interagir avec la page inspectée, obtenir des informations sur les requêtes réseau, et plus encore. Afficher les extensions d'outils de développement recommandées Les extensions DevTools ont accès à un ensemble supplémentaire d'API d'extension spécifiques à DevTools :
Une extension DevTools est structurée comme n'importe quelle autre extension : elle peut comporter une page d'arrière-plan, des scripts de contenu et d'autres éléments. De plus, chaque extension d'outils de développement dispose d'une page d'outils de développement qui a accès aux API d'outils de développement.

Page "Outils de développement"
Une instance de la page d'outils pour les développeurs de l'extension est créée chaque fois qu'une fenêtre d'outils pour les développeurs s'ouvre. La page "Outils de développement" existe pendant toute la durée de vie de la fenêtre "Outils de développement". La page des outils de développement a accès aux API DevTools et à un ensemble limité d'API d'extension. Plus précisément, la page des outils de développement peut :
- Créez des panneaux et interagissez avec eux à l'aide des API
devtools.panels. - Obtenez des informations sur la fenêtre inspectée et évaluez le code dans la fenêtre inspectée à l'aide des API
devtools.inspectedWindow. - Obtenez des informations sur les requêtes réseau à l'aide des API
devtools.network.
La page des outils de développement ne peut pas utiliser directement la plupart des API d'extensions. Il a accès au même sous-ensemble des API extension et runtime qu'un script de contenu. Comme un script de contenu, une page DevTools peut communiquer avec la page d'arrière-plan à l'aide de la transmission de messages. Pour obtenir un exemple, consultez Injecter un script de contenu.
Créer une extension DevTools
Pour créer une page DevTools pour votre extension, ajoutez le champ devtools_page dans le fichier manifeste de l'extension :
{
"name": ...
"version": "1.0",
"minimum_chrome_version": "10.0",
"devtools_page": "devtools.html",
...
}
Une instance de devtools_page spécifiée dans le fichier manifeste de votre extension est créée pour chaque fenêtre d'outils de développement ouverte. La page peut ajouter d'autres pages d'extension sous forme de panneaux et de barres latérales à la fenêtre des outils de développement à l'aide de l'API devtools.panels.
Les modules de l'API chrome.devtools.* ne sont disponibles que pour les pages chargées dans la fenêtre des outils de développement. Les scripts de contenu et les autres pages d'extension ne disposent pas de ces API. Les API ne sont donc disponibles que pendant la durée de vie de la fenêtre des outils de développement.
Certaines API DevTools sont encore expérimentales. Consultez chrome.experimental.* API pour obtenir la liste des API expérimentales et des consignes sur leur utilisation.
Éléments de l'UI des outils de développement : panneaux et volets de la barre latérale
En plus des éléments d'UI d'extension habituels, tels que les actions de navigateur, les menus contextuels et les pop-ups, une extension DevTools peut ajouter des éléments d'UI à la fenêtre DevTools :
- Un panneau est un onglet de premier niveau, comme les panneaux "Éléments", "Sources" et "Réseau".
- Un volet latéral présente une UI supplémentaire liée à un panneau. Les volets "Styles", "Styles calculés" et "Écouteurs d'événements" du volet "Éléments" sont des exemples de volets de barre latérale. (Notez que l'apparence des volets de la barre latérale peut ne pas correspondre à l'image, selon la version de Chrome que vous utilisez et l'emplacement où la fenêtre des outils de développement est ancrée.)

Chaque panneau est son propre fichier HTML, qui peut inclure d'autres ressources (JavaScript, CSS, images, etc.). Voici à quoi ressemble la création d'un panneau de base :
chrome.devtools.panels.create("My Panel",
"MyPanelIcon.png",
"Panel.html",
function(panel) {
// code invoked on panel creation
}
);
Le code JavaScript exécuté dans un volet de panneau ou de barre latérale a accès aux mêmes API que la page des outils de développement.
Voici comment créer un volet de barre latérale de base pour le panneau "Éléments" :
chrome.devtools.panels.elements.createSidebarPane("My Sidebar",
function(sidebar) {
// sidebar initialization code here
sidebar.setObject({ some_data: "Some data to show" });
});
Il existe plusieurs façons d'afficher du contenu dans un volet de barre latérale :
- Contenu HTML. Appelez
setPagepour spécifier une page HTML à afficher dans le volet. - Données JSON. Transmettez un objet JSON à
setObject. - Expression JavaScript. Transmettez une expression à
setExpression. Les outils de développement évaluent l'expression dans le contexte de la page inspectée et affichent la valeur renvoyée.
Pour setObject et setExpression, le volet affiche la valeur telle qu'elle apparaîtrait dans la console DevTools. Toutefois, setExpression vous permet d'afficher des éléments DOM et des objets JavaScript arbitraires, tandis que setObject n'accepte que les objets JSON.
Communiquer entre les composants d'extension
Les sections suivantes décrivent certains scénarios typiques de communication entre les différents composants d'une extension DevTools.
Injecter un script de contenu
La page des outils de développement ne peut pas appeler tabs.executeScript directement. Pour injecter un script de contenu à partir de la page des outils de développement, vous devez récupérer l'ID de l'onglet de la fenêtre inspectée à l'aide de la propriété inspectedWindow.tabId et envoyer un message à la page d'arrière-plan. À partir de la page d'arrière-plan, appelez tabs.executeScript pour injecter le script.
Les extraits de code suivants montrent comment injecter un script de contenu à l'aide de 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"
});
Code de la page d'arrière-plan :
// 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);
});
});
Évaluer JavaScript dans la fenêtre inspectée
Vous pouvez utiliser la méthode inspectedWindow.eval pour exécuter du code JavaScript dans le contexte de la page inspectée. Vous pouvez appeler la méthode eval depuis une page, un panneau ou un volet de barre latérale des outils de développement.
Par défaut, l'expression est évaluée dans le contexte du frame principal de la page. Vous connaissez peut-être déjà les fonctionnalités de l'API de ligne de commande des outils de développement, comme l'inspection des éléments (inspect(elem)), l'ajout de points d'arrêt dans les fonctions (debug(fn)), la copie dans le presse-papiers (copy()), etc.
inspectedWindow.eval() utilise le même contexte et les mêmes options d'exécution de script que le code saisi dans la console DevTools, ce qui permet d'accéder à ces API dans l'évaluation. Par exemple, SOAK l'utilise pour inspecter un élément :
chrome.devtools.inspectedWindow.eval(
"inspect($$('head script[data-soak=main]')[0])",
function(result, isException) { }
);
Vous pouvez également utiliser l'option useContentScriptContext: true pour inspectedWindow.eval() afin d'évaluer l'expression dans le même contexte que les scripts de contenu. L'appel de eval avec useContentScriptContext: true ne crée pas de contexte de script de contenu. Vous devez donc charger un script de contexte avant d'appeler eval, soit en appelant executeScript, soit en spécifiant un script de contenu dans le fichier manifest.json.
Une fois le contexte de script de contexte existant, vous pouvez utiliser cette option pour injecter des scripts de contenu supplémentaires.
La méthode eval est puissante lorsqu'elle est utilisée dans le bon contexte et dangereuse lorsqu'elle est utilisée de manière inappropriée. Utilisez la méthode tabs.executeScript si vous n'avez pas besoin d'accéder au contexte JavaScript de la page inspectée. Pour obtenir des avertissements détaillés et une comparaison des deux méthodes, consultez inspectedWindow.
Transmettre l'élément sélectionné à un script de contenu
Le script de contenu n'a pas accès directement à l'élément sélectionné. Toutefois, tout code que vous exécutez à l'aide de inspectedWindow.eval a accès à la console DevTools et aux API de ligne de commande.
Par exemple, dans le code évalué, vous pouvez utiliser $0 pour accéder à l'élément sélectionné.
Pour transmettre l'élément sélectionné à un script de contenu :
- Créez une méthode dans le script de contenu qui prend l'élément sélectionné comme argument.
- Appelez la méthode à partir de la page Outils de développement à l'aide de
inspectedWindow.evalavec l'optionuseContentScriptContext: true.
Le code de votre script de contenu peut se présenter comme suit :
function setSelectedElement(el) {
// do something with the selected element
}
Appelez la méthode depuis la page Outils de développement comme suit :
chrome.devtools.inspectedWindow.eval("setSelectedElement($0)",
{ useContentScriptContext: true });
L'option useContentScriptContext: true spécifie que l'expression doit être évaluée dans le même contexte que les scripts de contenu, afin qu'elle puisse accéder à la méthode setSelectedElement.
Obtenir les window d'un panneau de référence
Pour postMessage à partir d'un panneau DevTools, vous aurez besoin d'une référence à son objet window.
Obtenez la fenêtre iframe d'un panneau à partir du gestionnaire d'événements panel.onShown :
onShown.addListener(function callback)
extensionPanel.onShown.addListener(function (extPanelWindow) {
extPanelWindow instanceof Window; // true
extPanelWindow.postMessage( // …
});
Messagerie des scripts de contenu vers la page Outils de développement
La messagerie entre la page des outils de développement et les scripts de contenu est indirecte, via la page d'arrière-plan.
Lors de l'envoi d'un message à un script de contenu, la page d'arrière-plan peut utiliser la méthode tabs.sendMessage, qui dirige un message vers les scripts de contenu d'un onglet spécifique, comme indiqué dans Injection d'un script de contenu.
Lorsque vous envoyez un message à partir d'un script de contenu, il n'existe aucune méthode prédéfinie pour envoyer un message à la bonne instance de page des outils de développement associée à l'onglet actuel. Pour contourner ce problème, vous pouvez faire en sorte que la page des outils de développement établisse une connexion de longue durée avec la page d'arrière-plan, et que la page d'arrière-plan conserve une carte des ID d'onglet vers les connexions, afin qu'elle puisse acheminer chaque message vers la connexion appropriée.
// 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 page (ou le panneau ou le volet latéral) des outils de développement établit la connexion comme suit :
// Create a connection to the background page
var backgroundPageConnection = chrome.runtime.connect({
name: "panel"
});
backgroundPageConnection.postMessage({
name: 'init',
tabId: chrome.devtools.inspectedWindow.tabId
});
Envoi de messages depuis des scripts injectés vers la page des outils de développement
Bien que la solution ci-dessus fonctionne pour les scripts de contenu, le code injecté directement dans la page (par exemple, en ajoutant une balise <script> ou via inspectedWindow.eval) nécessite une stratégie différente. Dans ce contexte, runtime.sendMessage ne transmettra pas les messages au script d'arrière-plan comme prévu.
Pour contourner ce problème, vous pouvez combiner votre script injecté avec un script de contenu qui sert d'intermédiaire. Pour transmettre des messages au script de contenu, vous pouvez utiliser l'API window.postMessage. Voici un exemple, en supposant que le script d'arrière-plan de la section précédente soit utilisé :
// 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);
});
Votre message passera désormais du script injecté au script de contenu, puis au script d'arrière-plan et enfin à la page des outils de développement.
Vous pouvez également envisager deux autres techniques de transmission de messages ici.
Détecter l'ouverture et la fermeture des outils de développement
Si votre extension doit suivre si la fenêtre Outils de développement est ouverte, vous pouvez ajouter un écouteur onConnect à la page d'arrière-plan et appeler connect depuis la page Outils de développement. Étant donné que chaque onglet peut avoir sa propre fenêtre d'outils de développement ouverte, vous pouvez recevoir plusieurs événements de connexion. Pour savoir si une fenêtre d'outils de développement est ouverte, vous devez comptabiliser les événements de connexion et de déconnexion, comme indiqué ci-dessous :
// 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 page des Outils de développement crée une connexion comme suit :
// devtools.js
// Create a connection to the background page
var backgroundPageConnection = chrome.runtime.connect({
name: "devtools-page"
});
Exemples d'extensions DevTools
Parcourez la source de ces exemples d'extensions DevTools :
- L'extension Polymer Devtools utilise de nombreux assistants s'exécutant sur la page hôte pour interroger l'état DOM/JS et le renvoyer au panneau personnalisé.
- L'extension React DevTools utilise un sous-module de Blink pour réutiliser les composants de l'UI DevTools.
- Ember Inspector : extension de base partagée avec des adaptateurs pour Chrome et Firefox.
- Coquette-inspect : extension propre basée sur React avec un agent de débogage injecté dans la page hôte.
- Notre galerie d'extensions DevTools et nos exemples d'extensions contiennent d'autres applications intéressantes à installer, à tester et à partir desquelles vous pouvez apprendre.
En savoir plus
Pour en savoir plus sur les API standards que les extensions peuvent utiliser, consultez chrome.* API et API Web.
Donnez-nous votre avis ! Vos commentaires et suggestions nous aident à améliorer les API.
Exemples
Vous trouverez des exemples d'utilisation des API DevTools dans Exemples.