Las extensiones de DevTools agregan funciones a las Herramientas para desarrolladores de Chrome a través del acceso a las APIs de extensiones específicas de DevTools mediante una página de DevTools que se agrega a la extensión.
Las APIs de extensión específicas de DevTools incluyen las siguientes:
La página de Herramientas para desarrolladores
Cuando se abre una ventana de DevTools, una extensión de DevTools crea una instancia de su página de DevTools que existe mientras la ventana está abierta. Esta página tiene acceso a las APIs de DevTools y a las APIs de extensiones, y puede hacer lo siguiente:
- Crea paneles y, luego, interactúa con ellos mediante las APIs de
devtools.panels
, lo que incluye agregar otras páginas de extensión como paneles o barras laterales a la ventana de DevTools. - Obtén información sobre la ventana inspeccionada y evalúa el código en ella con las APIs de
devtools.inspectedWindow
. - Obtén información sobre las solicitudes de red con las APIs de
devtools.network
. - Extiende el panel de la grabadora con las APIs de
devtools.recorder
. - Obtén información sobre el estado de grabación del panel de rendimiento con las APIs de
devtools.performance
.
La página de DevTools puede acceder directamente a las APIs de extensiones. Esto incluye poder comunicarse con el trabajador de servicio mediante el pase de mensajes.
Crea una extensión de DevTools
Para crear una página de DevTools para tu extensión, agrega el campo devtools_page
en el manifiesto de la extensión:
{
"name": ...
"version": "1.0",
"devtools_page": "devtools.html",
...
}
El campo devtools_page
debe dirigir a una página HTML. Debido a que la página de DevTools debe ser local para tu extensión, te recomendamos que la especifiques con una URL relativa.
Los miembros de la API de chrome.devtools
solo están disponibles para las páginas cargadas en la ventana de DevTools mientras esta está abierta. Las secuencias de comandos de contenido y otras páginas de extensiones no tienen acceso a estas APIs.
Elementos de la IU de DevTools: paneles y paneles laterales
Además de los elementos habituales de la IU de la extensión, como las acciones del navegador, los menús contextuales y las ventanas emergentes, una extensión de DevTools puede agregar elementos de la IU a la ventana de DevTools:
- Un panel es una pestaña de nivel superior, como los paneles Elementos, Fuentes y Red.
- Un panel lateral presenta una IU complementaria relacionada con un panel. Los paneles Estilos, Estilos calculados y Objetos de escucha de eventos del panel Elementos son ejemplos de paneles de la barra lateral. Según la versión de Chrome que uses y dónde esté anclada la ventana de DevTools, los paneles de la barra lateral pueden verse como en la siguiente imagen de ejemplo:
Cada panel es su propio archivo HTML, que puede incluir otros recursos (JavaScript, CSS, imágenes, etc.). Para crear un panel básico, usa el siguiente código:
chrome.devtools.panels.create("My Panel",
"MyPanelIcon.png",
"Panel.html",
function(panel) {
// code invoked on panel creation
}
);
El código JavaScript que se ejecuta en un panel o panel lateral tiene acceso a las mismas APIs que la página de DevTools.
Para crear un panel lateral básico, usa el siguiente código:
chrome.devtools.panels.elements.createSidebarPane("My Sidebar",
function(sidebar) {
// sidebar initialization code here
sidebar.setObject({ some_data: "Some data to show" });
});
Existen varias formas de mostrar contenido en un panel lateral:
- Contenido HTML: Llama a
setPage()
para especificar una página HTML que se mostrará en el panel. - Datos JSON: Pasa un objeto JSON a
setObject()
. - Expresión de JavaScript: Pasa una expresión a
setExpression()
. DevTools evalúa la expresión en el contexto de la página inspeccionada y, luego, muestra el valor que se muestra.
En el caso de setObject()
y setExpression()
, el panel muestra el valor tal como aparecería en la consola de DevTools. Sin embargo, setExpression()
te permite mostrar elementos DOM y objetos JavaScript arbitrarios, mientras que setObject()
solo admite objetos JSON.
Cómo comunicarse entre los componentes de la extensión
En las siguientes secciones, se describen algunas formas útiles de permitir que los componentes de la extensión de DevTools se comuniquen entre sí.
Cómo insertar una secuencia de comandos de contenido
Para insertar una secuencia de comandos de contenido, usa scripting.executeScript()
:
// DevTools page -- devtools.js
chrome.scripting.executeScript({
target: {
tabId: chrome.devtools.inspectedWindow.tabId
},
files: ["content_script.js"]
});
Puedes recuperar el ID de la pestaña de la ventana inspeccionada con la propiedad inspectedWindow.tabId
.
Si ya se insertó una secuencia de comandos de contenido, puedes usar las APIs de mensajería para comunicarte con ella.
Evalúa JavaScript en la ventana inspeccionada
Puedes usar el método inspectedWindow.eval()
para ejecutar código JavaScript en el contexto de la página inspeccionada. Puedes invocar el método eval()
desde una página, un panel o un panel lateral de DevTools.
De forma predeterminada, la expresión se evalúa en el contexto del marco principal de la página.
inspectedWindow.eval()
usa el mismo contexto y las mismas opciones de ejecución de secuencia de comandos que el código ingresado en la consola de DevTools, lo que permite el acceso a las funciones de la API de Console Utilities de DevTools cuando se usa eval()
. Por ejemplo, úsalo para inspeccionar el primer elemento de secuencia de comandos dentro de la sección <head>
del documento HTML:
chrome.devtools.inspectedWindow.eval(
"inspect($$('head script')[0])",
function(result, isException) { }
);
También puedes establecer useContentScriptContext
en true
cuando llames a inspectedWindow.eval()
para
evaluar la expresión en el mismo contexto que las secuencias de comandos de contenido. Para usar esta opción, usa una declaración de secuencia de comandos de contenido estático antes de llamar a eval()
, ya sea llamando a executeScript()
o especificando una secuencia de comandos de contenido en el archivo manifest.json
. Después de que se cargue el contexto de la secuencia de comandos, también puedes usar esta opción para insertar secuencias de comandos de contenido adicionales.
Pasa el elemento seleccionado a una secuencia de comandos de contenido
La secuencia de comandos de contenido no tiene acceso directo al elemento seleccionado actual. Sin embargo, cualquier código que ejecutes con inspectedWindow.eval()
tiene acceso a la consola de DevTools y a las APIs de Console Utilities. Por ejemplo, en el código evaluado, puedes usar $0
para acceder al elemento seleccionado.
Para pasar el elemento seleccionado a una secuencia de comandos de contenido, haz lo siguiente:
Crea un método en la secuencia de comandos de contenido que tome el elemento seleccionado como argumento.
function setSelectedElement(el) { // do something with the selected element }
Llama al método desde la página de DevTools con
inspectedWindow.eval()
con la opciónuseContentScriptContext: true
.chrome.devtools.inspectedWindow.eval("setSelectedElement($0)", { useContentScriptContext: true });
La opción useContentScriptContext: true
especifica que la expresión se debe evaluar en el mismo contexto que las secuencias de comandos de contenido para que pueda acceder al método setSelectedElement
.
Obtén el window
de un panel de referencia
Para llamar a postMessage()
desde un panel de herramientas para desarrolladores, necesitarás una referencia a su objeto window
. Obtén la ventana de iframe de un panel desde el controlador de eventos panel.onShown
:
extensionPanel.onShown.addListener(function (extPanelWindow) {
extPanelWindow instanceof Window; // true
extPanelWindow.postMessage( // …
});
Envía mensajes de secuencias de comandos insertadas a la página de DevTools
El código que se inserta directamente en la página sin una secuencia de comandos de contenido, incluso si se agrega una etiqueta <script>
o se llama a inspectedWindow.eval()
, no puede enviar mensajes a la página de DevTools con runtime.sendMessage()
. En su lugar, te recomendamos que combines la secuencia de comandos insertada con una secuencia de comandos de contenido que pueda actuar como intermediario y que uses el método window.postMessage()
. En el siguiente ejemplo, se usa la secuencia de comandos en segundo plano de la sección anterior:
// 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);
});
Puedes encontrar otras técnicas alternativas de transmisión de mensajes en GitHub.
Detecta cuándo se abre y se cierra DevTools
Para hacer un seguimiento de si la ventana de DevTools está abierta, agrega un objeto de escucha onConnect al trabajador de servicio y llama a connect() desde la página de DevTools. Debido a que cada pestaña puede tener su propia ventana de DevTools abierta, es posible que recibas varios eventos de conexión. Para hacer un seguimiento de si hay alguna ventana de DevTools abierta, cuenta los eventos de conexión y desconexión como se muestra en el siguiente ejemplo:
// 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 página de Herramientas para desarrolladores crea una conexión de la siguiente manera:
// 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);
Ejemplos de extensiones de DevTools
Los ejemplos de esta página provienen de las siguientes páginas:
- Extensión de Devtools de Polymer: Usa muchos asistentes que se ejecutan en la página host para consultar el estado de DOM/JS y enviarlo al panel personalizado.
- Extensión de React DevTools: Usa un submódulo del renderizador para reutilizar los componentes de la IU de DevTools.
- Ember Inspector: Es un núcleo de extensión compartido con adaptadores para Chrome y Firefox.
- Coquette-inspect: Es una extensión limpia basada en React con un agente de depuración insertado en la página host.
- En Extensiones de muestra, encontrarás extensiones más valiosas para instalar, probar y aprender de ellas.
Más información
Para obtener información sobre las APIs estándar que pueden usar las extensiones, consulta chrome.* APIs y APIs web.
Envíanos tus comentarios. Tus comentarios y sugerencias nos ayudan a mejorar las APIs.
Ejemplos
Puedes encontrar ejemplos que usan las APIs de DevTools en Samples.