Las extensiones de Herramientas para desarrolladores agregan funciones a las Herramientas para desarrolladores de Chrome mediante el acceso a las APIs de extensión específicas de Herramientas para desarrolladores a través de una página de Herramientas para desarrolladores agregada a la extensión.
Las APIs de extensión específicas de Herramientas para desarrolladores incluyen lo siguiente:
La página de Herramientas para desarrolladores
Cuando se abre una ventana de Herramientas para desarrolladores, una extensión de Herramientas para desarrolladores crea una instancia de su página de Herramientas para desarrolladores que existe mientras la ventana está abierta. Esta página tiene acceso a las APIs de Herramientas para desarrolladores y a las APIs de extensión, y puede hacer lo siguiente:
- Crear paneles e interactuar 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 Herramientas para desarrolladores - Obtener información sobre la ventana inspeccionada y evaluar el código en la ventana inspeccionada con las
devtools.inspectedWindowAPIs. - Obtener información sobre las solicitudes de red con las
devtools.networkAPIs. - Extender el panel de Recorder con las APIs de
devtools.recorder - Obtener información sobre el estado de grabación del panel de rendimiento con las APIs de
devtools.performance
La página de Herramientas para desarrolladores puede acceder directamente a las APIs de extensiones. Esto incluye la capacidad de comunicarse con el service worker mediante el paso de mensajes.
Cómo crear una extensión de Herramientas para desarrolladores
Para crear una página de Herramientas para desarrolladores 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 apuntar a una página HTML. Debido a que la página de Herramientas para desarrolladores 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 Herramientas para desarrolladores mientras esa ventana está abierta. Las secuencias de comandos de contenido y otras páginas de extensión no tienen acceso a estas APIs.
El espacio de nombres del navegador y las extensiones de Herramientas para desarrolladores
En Chrome 152 y versiones posteriores, las extensiones con una página de Herramientas para desarrolladores pueden usar el espacio de nombres browser.
En las versiones de Chrome anteriores a la 152, el browser espacio de nombres
se desactivó para las extensiones que declaran
devtools_page. La inhabilitación se aplicó a toda la extensión, no solo a la página de Herramientas para desarrolladores, sino a cada contexto de secuencia de comandos en el que se ejecutan las APIs de extensión.
El motivo fue una brecha de compatibilidad con
webextension-polyfill.
Las APIs de chrome.devtools.* anteriores a Chrome 152 eran solo de devolución de llamada (no mostraban Promises de forma nativa), por lo que las extensiones de Herramientas para desarrolladores solían depender del polyfill para ajustarlas. El polyfill omite el ajuste cada vez que se define browser, suponiendo que el host ya hizo el trabajo. Si Chrome hubiera habilitado browser para estas extensiones, el polyfill no funcionaría y las llamadas a chrome.devtools.* habrían dejado de mostrar Promises. Mantener browser desactivado mantuvo el polyfill en ajuste.
La misma inhabilitación también inhabilitó los otros cambios en la API de mensajería de Chrome 148
para estas extensiones, incluidas
las respuestas de Promise en runtime.onMessage.
La restricción se levantó una vez que las APIs de Herramientas para desarrolladores admitieron Promises de forma nativa.
Elementos de la IU de Herramientas para desarrolladores: paneles y paneles de la barra lateral
Además de los elementos de la IU de extensión habituales, como las acciones del navegador, los menús contextuales y las ventanas emergentes, una extensión de Herramientas para desarrolladores puede agregar elementos de la IU a la ventana de Herramientas para desarrolladores:
- Un panel es una pestaña de nivel superior, como los paneles Elementos, Fuentes y Red.
- Un panel de la barra lateral presenta una IU complementaria relacionada con un panel. Los paneles Estilos, Estilos calculados y Detectores 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 Herramientas para desarrolladores, los paneles de la barra lateral podrían verse como la siguiente imagen de ejemplo:
Cada panel es su propio archivo HTML, que puede incluir otros recursos (JavaScript, CSS, imágenes, etcétera). 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 en un panel de la barra lateral tiene acceso a las mismas APIs que la página de Herramientas para desarrolladores.
Para crear un panel de la barra 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" });
});
Hay varias formas de mostrar contenido en un panel de la barra 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(). Herramientas para desarrolladores evalúa la expresión en el contexto de la página inspeccionada y, luego, muestra el valor devuelto.
Para setObject() y setExpression(), el panel muestra el valor tal como aparecería en la consola de Herramientas para desarrolladores. Sin embargo, setExpression() te permite mostrar elementos DOM y objetos JavaScript arbitrarios, mientras que setObject() solo admite objetos JSON.
Comunicación entre componentes de extensión
En las siguientes secciones, se describen algunas formas útiles de permitir que los componentes de extensión de Herramientas para desarrolladores 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
inspectedWindow.tabId propiedad.
Si ya se insertó una secuencia de comandos de contenido, puedes usar las APIs de mensajería para comunicarte con ella.
Cómo evaluar JavaScript en la ventana inspeccionada
Puedes usar el inspectedWindow.eval() método 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 de la barra lateral de Herramientas para desarrolladores.
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 de ejecución de secuencia de comandos y las mismas opciones que el código
ingresado en la consola de Herramientas para desarrolladores, lo que permite el acceso a las funciones de la API de Console Utilities
Herramientas para desarrolladores 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 configurar useContentScriptContext como 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ática 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 de contenido, también puedes usar esta opción para insertar secuencias de comandos de contenido adicionales.
Cómo pasar 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 Herramientas para desarrolladores
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 Herramientas para desarrolladores 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, por lo que puede acceder al método setSelectedElement.
Cómo obtener 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 una
ventana iframe del panel desde el panel.onShown controlador de eventos:
extensionPanel.onShown.addListener(function (extPanelWindow) {
extPanelWindow instanceof Window; // true
extPanelWindow.postMessage( // …
});
Cómo enviar mensajes desde secuencias de comandos insertadas a la página de Herramientas para desarrolladores
El código insertado directamente en la página sin una secuencia de comandos de contenido, incluso agregando una <script>
etiqueta o llamando a inspectedWindow.eval(), no puede enviar mensajes a la
página de Herramientas para desarrolladores con runtime.sendMessage(). En cambio, te recomendamos que combines tu 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 paso de mensajes en GitHub.
Cómo detectar cuándo se abren y cierran las Herramientas para desarrolladores
Para hacer un seguimiento de si la ventana de Herramientas para desarrolladores está abierta, agrega un objeto de escucha onConnect al service worker y llama a connect() desde la página de Herramientas para desarrolladores. Debido a que cada pestaña puede tener su propia ventana de Herramientas para desarrolladores abierta, es posible que recibas varios eventos de conexión. Para hacer un seguimiento de si alguna ventana de Herramientas para desarrolladores está 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 como esta:
// 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 Herramientas para desarrolladores
Los ejemplos de esta página provienen de las siguientes páginas:
- Extensión de Herramientas para desarrolladores de Polymer: Usa muchos asistentes que se ejecutan en la página host para consultar el estado de DOM/JS y enviarlo de vuelta al panel personalizado.
- Extensión de Herramientas para desarrolladores de React: Usa un submódulo del renderizador para reutilizar los componentes de la IU de Herramientas para desarrolladores.
- Ember Inspector: Núcleo de extensión compartido con adaptadores para Chrome y Firefox.
- Coquette-inspect: Una extensión limpia basada en React con un agente de depuración insertado en la página host.
- Las extensiones de muestra tienen extensiones más valiosas para instalar, probar y aprender de.
Más información
Para obtener información sobre las APIs estándar que pueden usar las extensiones, consulta chrome.* APIs y web APIs.
Envíanos tus comentarios. Tus comentarios y sugerencias nos ayudan a mejorar las APIs.
Ejemplos
Puedes encontrar ejemplos que usan las APIs de Herramientas para desarrolladores en Samples.