Les extensions DevTools ajoutent des fonctionnalités aux outils pour les développeurs Chrome en accédant à des API d'extension spécifiques aux outils pour les développeurs via une page d'outils pour les développeurs ajoutée à l'extension.
Les API d'extension spécifiques aux outils pour les développeurs incluent les éléments suivants :
La page des outils de développement
Lorsqu'une fenêtre d'Outils de développement s'ouvre, une extension d'Outils de développement crée une instance de sa page d'Outils de développement qui existe tant que la fenêtre est ouverte. Cette page a accès aux API des Outils de développement et aux API d'extension, et peut effectuer les opérations suivantes :
- Créer des panneaux et interagir avec eux à l'aide des
devtools.panelsAPI, y compris en ajoutant d'autres pages d'extension en tant que panneaux ou barres latérales à la fenêtre des outils de développement. - Obtenir des informations sur la fenêtre inspectée et évaluer le code dans la fenêtre inspectée à l'aide des
devtools.inspectedWindowAPI. - Obtenir des informations sur les requêtes réseau à l'aide des
devtools.networkAPI. - Étendre le panneau de l'enregistreur à l'aide des
devtools.recorderAPI. - Obtenir des informations sur l'état d'enregistrement du panneau "Performances" à l'aide des
devtools.performanceAPI.
La page des outils de développement peut accéder directement aux API d'extension. Cela inclut la possibilité de communiquer avec le service worker à l'aide de la transmission de messages.
Créer une extension d'outils pour les développeurs
Pour créer une page d'Outils de développement pour votre extension, ajoutez le champ devtools_page dans le fichier manifeste de l'extension :
{
"name": ...
"version": "1.0",
"devtools_page": "devtools.html",
...
}
Le champ devtools_page doit pointer vers une page HTML. Étant donné que la page Outils de développement doit être locale à votre extension, nous vous recommandons de la spécifier à l'aide d'une URL relative.
Les membres de l'API chrome.devtools ne sont disponibles que pour les pages chargées dans la fenêtre d'outils pour les développeurs lorsque cette fenêtre est ouverte. Les scripts de contenu et les autres pages d'extension n'ont pas accès à ces API.
Espace de noms du navigateur et extensions d'outils pour les développeurs
Dans Chrome 152 et versions ultérieures, les extensions avec une page d'outils pour les développeurs peuvent utiliser l'espace de noms browser.
Dans les versions de Chrome antérieures à la version 152, l'browserespace de noms
était désactivé pour les extensions qui déclarent
devtools_page. La désactivation s'appliquait à l'ensemble de l'extension, et pas seulement à la page des outils de développement, mais à tous les contextes de script dans lesquels les API d'extension s'exécutent.
La raison en était un écart de compatibilité avec
webextension-polyfill.
Les API chrome.devtools.* antérieures à Chrome 152 étaient uniquement des rappels. Elles ne renvoyaient pas de promesses de manière native. Les extensions d'outils pour les développeurs s'appuyaient donc généralement sur le polyfill pour les encapsuler. Le polyfill ignore l'encapsulation chaque fois que browser est défini, en supposant que l'hôte a déjà effectué le travail. Si Chrome avait activé browser pour ces extensions, le polyfill n'aurait pas fonctionné et les appels chrome.devtools.* auraient cessé de renvoyer des promesses. Le fait de désactiver browser a permis au polyfill de continuer à encapsuler.
La même désactivation a également désactivé les autres modifications de l'API de messagerie Chrome 148
pour ces extensions, y compris
les réponses de promesse dans runtime.onMessage.
La restriction a été levée une fois que les API des Outils de développement ont pris en charge les promesses de manière native.
Éléments d'interface utilisateur des outils de développement : panneaux et volets de la barre latérale
En plus des éléments d'interface utilisateur d'extension habituels, tels que les actions du navigateur, les menus contextuels et les pop-up, une extension d'outils pour les développeurs peut ajouter des éléments d'interface utilisateur à la fenêtre d'outils pour les développeurs :
- Un panneau est un onglet de premier niveau, comme les panneaux "Éléments", "Sources" et "Réseau".
- Un volet de la barre latérale présente une interface utilisateur supplémentaire liée à un panneau. Les volets "Styles", "Styles calculés" et "Écouteurs d'événements" du panneau "Éléments" sont des exemples de volets de la barre latérale. Selon la version de Chrome que vous utilisez et l'emplacement où la fenêtre des Outils de développement est ancrée, vos volets de la barre latérale peuvent ressembler à l'exemple d'image suivant :
Chaque panneau est son propre fichier HTML, qui peut inclure d'autres ressources (JavaScript, CSS, images, etc.). Pour créer un panneau de base, utilisez le code suivant :
chrome.devtools.panels.create("My Panel",
"MyPanelIcon.png",
"Panel.html",
function(panel) {
// code invoked on panel creation
}
);
Le code JavaScript exécuté dans un panneau ou un volet de la barre latérale a accès aux mêmes API que la page d'outils pour les développeurs.
Pour créer un volet de la barre latérale de base, utilisez le code suivant :
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 la barre latérale :
- Contenu HTML : appelez
setPage()pour 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, puis affichent la valeur renvoyée.
Pour setObject() et setExpression(), le volet affiche la valeur telle qu'elle apparaîtrait dans la console des Outils de développement. Toutefois, setExpression() vous permet d'afficher des éléments DOM et des objets JavaScript arbitraires, tandis que setObject() n'est compatible qu'avec les objets JSON.
Communiquer entre les composants d'extension
Les sections suivantes décrivent certaines méthodes utiles pour permettre aux composants d'extension des Outils de développement de communiquer entre eux.
Injecter un script de contenu
Pour injecter un script de contenu, utilisez scripting.executeScript() :
// DevTools page -- devtools.js
chrome.scripting.executeScript({
target: {
tabId: chrome.devtools.inspectedWindow.tabId
},
files: ["content_script.js"]
});
Vous pouvez récupérer l'ID d'onglet de la fenêtre inspectée à l'aide de la
inspectedWindow.tabId propriété.
Si un script de contenu a déjà été injecté, vous pouvez utiliser des API de messagerie pour communiquer avec lui.
É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() à partir d'une page d'Outils de développement, d'un panneau ou d'un volet de la barre latérale.
Par défaut, l'expression est évaluée dans le contexte du frame principal de la page.
inspectedWindow.eval() utilise le même contexte d'exécution de script et les mêmes options que le code saisi dans la console des Outils de développement, ce qui permet d'accéder aux fonctionnalités de l'API des utilitaires de la console des Outils de développement lors de l'utilisation de eval(). Par exemple, utilisez-la pour inspecter
le premier élément de script dans la section <head> du document HTML :
chrome.devtools.inspectedWindow.eval(
"inspect($$('head script')[0])",
function(result, isException) { }
);
Vous pouvez également définir useContentScriptContext sur true lorsque vous appelez inspectedWindow.eval() pour évaluer l'expression dans le même contexte que les scripts de contenu. Pour utiliser cette option, utilisez une déclaration de script de contenu statique 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 du script de contenu chargé, vous pouvez également utiliser cette option pour injecter des scripts de contenu supplémentaires.
Transmettre l'élément sélectionné à un script de contenu
Le script de contenu n'a pas d'accès direct à l'élément actuellement sélectionné. Toutefois, tout code que vous exécutez à l'aide de inspectedWindow.eval() a accès à la console des Outils de développement et aux API des utilitaires de la console. 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.
function setSelectedElement(el) { // do something with the selected element }Appelez la méthode à partir de la page d'outils pour les développeurs à l'aide de
inspectedWindow.eval()avec l'optionuseContentScriptContext: true.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 un panneau de référence window
Pour appeler postMessage() à partir d'un panneau d'outils pour les développeurs, vous aurez besoin d'une référence à son objet window. Obtenez la fenêtre iframe d'un
panneau à partir du panel.onShown gestionnaire d'événements :
extensionPanel.onShown.addListener(function (extPanelWindow) {
extPanelWindow instanceof Window; // true
extPanelWindow.postMessage( // …
});
Envoyer des messages des scripts injectés à la page d'outils pour les développeurs
Le code injecté directement dans la page sans script de contenu, y compris en ajoutant un <script>
tag ou en appelant inspectedWindow.eval(), ne peut pas envoyer de messages à la
page d'outils pour les développeurs à l'aide de runtime.sendMessage(). Nous vous recommandons plutôt de
combiner votre script injecté avec un script de contenu qui peut servir d'intermédiaire et d'utiliser
la window.postMessage() méthode. L'exemple suivant utilise le script d'arrière-plan de la section précédente :
// 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);
});
D'autres techniques alternatives de transmission de messages sont disponibles sur GitHub.
Détecter l'ouverture et la fermeture des outils de développement
Pour savoir si la fenêtre des Outils de développement est ouverte, ajoutez un onConnect au service worker et appelez connect() à partir de la page des Outils de développement. Étant donné que chaque onglet peut avoir sa propre fenêtre d'outils pour les développeurs ouverte, vous pouvez recevoir plusieurs événements de connexion. Pour savoir si une fenêtre des Outils de développement est ouverte, comptez les événements de connexion et de déconnexion, comme illustré dans l'exemple suivant :
// 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 Outils de développement crée une connexion comme suit :
// 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);
Exemples d'extensions d'outils pour les développeurs
Les exemples de cette page proviennent des pages suivantes :
- Extension Polymer Devtools : utilise de nombreux assistants s'exécutant sur la page hôte pour interroger l'état DOM/JS à renvoyer au panneau personnalisé.
- Extension React DevTools : utilise un sous-module du moteur de rendu pour réutiliser les composants d'interface utilisateur des outils pour les développeurs.
- Ember Inspector : noyau d'extension partagé 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.
- Les exemples d'extensions proposent d'autres extensions intéressantes à installer, à essayer 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.
Faites-nous part de vos commentaires ! Vos commentaires et suggestions nous aident à améliorer les API.
Exemples
Vous trouverez des exemples qui utilisent les API d'outils pour les développeurs dans Exemples.