Descripción general
Una extensión de DevTools agrega funcionalidad a Chrome DevTools. Puede agregar nuevos paneles de IU y las barras laterales, interactuar con la página inspeccionada, obtener información sobre las solicitudes de red y mucho más. Consulta las extensiones de DevTools destacadas. Las extensiones de Herramientas para desarrolladores tienen acceso a un conjunto adicional de APIs de extensión específicas de Herramientas para desarrolladores:
Una extensión de Herramientas para desarrolladores se estructura como cualquier otra extensión: puede tener una página de fondo, contenido secuencias de comandos y otros elementos. Además, cada extensión de DevTools tiene una página de DevTools, que tiene acceso a las APIs de DevTools.
La página de Herramientas para desarrolladores
Cada vez que se abre una ventana de Herramientas para desarrolladores, se crea una instancia de la página de Herramientas para desarrolladores de la extensión. La página de DevTools existe durante el tiempo que se abre la ventana de DevTools. La página de Herramientas para desarrolladores tiene acceso a la APIs de Herramientas para desarrolladores y un conjunto limitado de APIs de extensión. Específicamente, la página de Herramientas para desarrolladores puede hacer lo siguiente:
- Crea paneles e interactúa con ellos mediante las APIs de
devtools.panels
. - Obtén información sobre la ventana inspeccionada y evalúa el código en la ventana inspeccionada con el
APIs de
devtools.inspectedWindow
. - Obtén información sobre las solicitudes de red con las APIs de
devtools.network
.
La página de DevTools no puede usar la mayoría de las APIs de extensiones directamente. Tiene acceso al mismo subconjunto de las APIs de extension
y runtime
al que tiene acceso una secuencia de comandos de contenido. Al igual que una secuencia de comandos de contenido, una página de DevTools puede comunicarse con la página en segundo plano mediante el envío de mensajes. Para un
Por ejemplo, consulta Cómo insertar una secuencia de comandos de contenido.
Cómo crear una extensión de DevTools
Si deseas crear una página de Herramientas para desarrolladores para tu extensión, agrega el campo devtools_page
en la extensión
manifest:
{
"name": ...
"version": "1.0",
"minimum_chrome_version": "10.0",
"devtools_page": "devtools.html",
...
}
Se crea una instancia del devtools_page
especificado en el manifiesto de tu extensión para cada ventana de DevTools que se abre. La página puede agregar otras páginas de extensión como paneles y barras laterales a la ventana de DevTools con la API de devtools.panels
.
Los módulos de la API de chrome.devtools.*
solo están disponibles para las páginas cargadas en las Herramientas para desarrolladores
en la ventana modal. Las secuencias de comandos de contenido y otras páginas de extensiones no tienen estas APIs. Por lo tanto, las APIs son
disponible solo durante el ciclo de vida de la ventana de Herramientas para desarrolladores.
También hay algunas APIs de Herramientas para desarrolladores que aún son experimentales. Consulta chrome.experimental.* las API para obtener la lista de las APIs experimentales y los lineamientos para usarlas.
Elementos de la IU de Herramientas para desarrolladores: paneles y paneles de la barra lateral
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 Elements, Sources y Network.
- Un panel lateral presenta una IU complementaria relacionada con un panel. Los estilos, los estilos calculados y Los paneles de los objetos de escucha de eventos del panel Elements son ejemplos de paneles de la barra lateral. (Ten en cuenta que el que la apariencia de los paneles de la barra lateral no coincida con la imagen, según la versión de Chrome usando y dónde está anclada la ventana de Herramientas para desarrolladores).
Cada panel es su propio archivo HTML, que puede incluir otros recursos (JavaScript, CSS, imágenes, etc.). La creación de un panel básico se ve de la siguiente manera:
chrome.devtools.panels.create("My Panel",
"MyPanelIcon.png",
"Panel.html",
function(panel) {
// code invoked on panel creation
}
);
JavaScript ejecutado 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.
La creación de un panel básico de barra lateral para el panel Elementos se verá de la siguiente manera:
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
. - Es una 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 muestra el valor que se devuelve.
Tanto para setObject
como para setExpression
, el panel muestra el valor tal como aparecería en
Consola de Herramientas para desarrolladores. Sin embargo, setExpression
te permite mostrar elementos DOM y JavaScript arbitrario
objetos, mientras que setObject
solo admite objetos JSON.
Cómo establecer comunicaciones entre los componentes de una extensión
Las siguientes secciones describen algunas situaciones típicas de comunicación entre los diferentes componentes de una extensión de Herramientas para desarrolladores.
Cómo insertar un guion de contenido
La página de Herramientas para desarrolladores no puede llamar a tabs.executeScript
directamente. Para insertar una secuencia de comandos de contenido desde
página de Herramientas para desarrolladores, debes recuperar el ID de la pestaña de la ventana inspeccionada usando el
inspectedWindow.tabId
y envía un mensaje a la página en segundo plano. Desde la página en segundo plano, llama a tabs.executeScript
para insertar la secuencia de comandos.
En los siguientes fragmentos de código, se muestra cómo insertar una secuencia de comandos de contenido con 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"
});
Código de la página en segundo plano:
// 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);
});
});
Cómo evaluar 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 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. Ahora, puedes
Familiarizarte con las funciones de la API de línea de comandos de Herramientas para desarrolladores, como la inspección de elementos
(inspect(elem)
), rompiendo funciones (debug(fn)
), copiar en el portapapeles (copy()
) y mucho más.
inspectedWindow.eval()
usa las mismas opciones y contexto de ejecución de secuencia de comandos que el código escrito en el
La consola de Herramientas para desarrolladores, que permite el acceso a estas APIs dentro de la evaluación. Por ejemplo, SOAK lo usa para inspeccionar un elemento:
chrome.devtools.inspectedWindow.eval(
"inspect($$('head script[data-soak=main]')[0])",
function(result, isException) { }
);
Como alternativa, usa la opción useContentScriptContext: true
para inspectedWindow.eval()
para
evaluar la expresión en el mismo contexto que las secuencias de comandos de contenido. Llamando a eval
con
useContentScriptContext: true
no crea un contexto de secuencia de comandos de contenido, por lo que debes cargar un
secuencia de comandos de contexto antes de llamar a eval
, ya sea llamando a executeScript
o especificando un contenido
en el archivo manifest.json
.
Una vez que exista el contexto de la secuencia de comandos de contexto, puedes usar esta opción para insertar secuencias de comandos de contenido adicionales.
El método eval
es potente cuando se usa en el contexto correcto y peligroso cuando se usa de forma inadecuada. Usa el método tabs.executeScript
si no necesitas acceso a la
Contexto de JavaScript de la página inspeccionada. Para precauciones detalladas y una comparación de los dos métodos,
consulta inspectedWindow
.
Pasar el elemento seleccionado a una secuencia de comandos de contenido
La secuencia de comandos de contenido no tiene acceso directo al elemento seleccionado actualmente. Sin embargo, cualquier código que ejecutes con inspectedWindow.eval
tiene acceso a la consola de DevTools y a las APIs de línea de comandos.
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.
- Llama al método desde la página de Herramientas para desarrolladores usando
inspectedWindow.eval
con el comandouseContentScriptContext: true
opción.
El código de tu secuencia de comandos de contenido podría verse de la siguiente manera:
function setSelectedElement(el) {
// do something with the selected element
}
Invoca el método desde la página de DevTools de la siguiente manera:
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
.
Cómo obtener el window
de un panel de referencia
Para 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
:
onShown.addListener(function callback)
extensionPanel.onShown.addListener(function (extPanelWindow) {
extPanelWindow instanceof Window; // true
extPanelWindow.postMessage( // …
});
Mensajes de las secuencias de comandos de contenido a la página de Herramientas para desarrolladores
La mensajería entre la página de Herramientas para desarrolladores y las secuencias de comandos de contenido es indirecta, a través de la página en segundo plano.
Cuando envías un mensaje a una secuencia de comandos de contenido, la página en segundo plano puede usar el elemento
tabs.sendMessage
, que dirige un mensaje a las secuencias de comandos de contenido de una pestaña específica
como se muestra en Cómo insertar una secuencia de comandos de contenido.
Cuando se envía un mensaje desde una secuencia de comandos de contenido, no hay un método listo para enviar un mensaje a la instancia correcta de la página de DevTools asociada con la pestaña actual. Como solución alternativa, puedes tener la página de Herramientas para desarrolladores establezca una conexión de larga duración con la página en segundo plano y tendrá la la página en segundo plano mantienen un mapa de los IDs de las pestañas a las conexiones, para que se pueda enrutar cada mensaje al conexión.
// 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 página de DevTools (o el panel o panel lateral) establece la conexión de la siguiente manera:
// Create a connection to the background page
var backgroundPageConnection = chrome.runtime.connect({
name: "panel"
});
backgroundPageConnection.postMessage({
name: 'init',
tabId: chrome.devtools.inspectedWindow.tabId
});
Mensajes de secuencias de comandos insertadas a la página de DevTools
Si bien la solución anterior funciona para las secuencias de comandos de contenido, el código que se incorpora directamente en la página
(p.ej., agregando una etiqueta <script>
o inspectedWindow.eval
) requiere un
estrategia diferente. En este contexto, runtime.sendMessage
no pasará mensajes a la secuencia de comandos en segundo plano como se espera.
Como solución alternativa, puede combinar la secuencia de comandos insertada con una secuencia de comandos de contenido que actúe como una
intermediario. Para pasar mensajes a la secuencia de comandos de contenido, puedes usar window.postMessage
.
API de gcloud. Este es un ejemplo, en el que se supone que 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
if (typeof message !== 'object' || message === null ||
!message.source === 'my-devtools-extension') {
return;
}
chrome.runtime.sendMessage(message);
});
Tu mensaje ahora fluirá de la secuencia de comandos insertada a la secuencia de comandos de contenido, a la secuencia de comandos en segundo plano y, por último, a la página de DevTools.
También puedes considerar dos técnicas alternativas de transmisión de mensajes aquí.
Cómo detectar cuándo se abre y se cierra Herramientas para desarrolladores
Si tu extensión necesita hacer un seguimiento de si la ventana de DevTools está abierta, puedes agregar un objeto de escucha onConnect a la página en segundo plano y llamar a connect desde la página de DevTools. Como 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 La ventana de Herramientas para desarrolladores está abierta. Debes contar los eventos de conexión y desconexión, como se muestra a continuación:
// 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 la siguiente:
// devtools.js
// Create a connection to the background page
var backgroundPageConnection = chrome.runtime.connect({
name: "devtools-page"
});
Ejemplos de extensión de Herramientas para desarrolladores
Explora la fuente de estos ejemplos de extensiones de DevTools:
- 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 DevTools de React: Usa un submódulo de Blink 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: una extensión limpia basada en React con un agente de depuración inyectado en página de host.
- En nuestra Galería de extensiones de DevTools y las Extensiones de muestra, encontrarás apps más valiosas para instalar, probar y aprender.
Más información
Para obtener información sobre las APIs estándar que pueden usar las extensiones, consulta chrome.* APIs y la 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 Muestras.