Cómo extender Herramientas para desarrolladores

Descripción general

Una extensión de Herramientas para desarrolladores agrega funcionalidad a las Herramientas para desarrolladores de Chrome. 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. Ver extensiones destacadas de Herramientas para desarrolladores. 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 Herramientas para desarrolladores tiene una página de Herramientas para desarrolladores, que tiene acceso a a las APIs de Herramientas para desarrolladores.

Diagrama de la arquitectura en el que se muestra la página de Herramientas para desarrolladores que se comunica con el
       la ventana inspeccionada y la página en segundo plano. Se muestra la página en segundo plano
       la comunicación con las secuencias de comandos de contenido y el acceso a las APIs de extensiones.
       La página de Herramientas para desarrolladores tiene acceso a las APIs de Herramientas para desarrolladores, por ejemplo, para crear paneles.

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. El La página de Herramientas para desarrolladores existe desde que se creó la ventana de Herramientas para desarrolladores. 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 Herramientas para desarrolladores no puede usar la mayoría de las APIs de extensiones directamente. Tiene acceso al mismo subconjunto de las APIs de extension y runtime a las que tiene acceso una secuencia de comandos de contenido. Indicar que me gusta un contenido de comandos, una página de Herramientas para desarrolladores puede comunicarse con la página en segundo plano mediante la opción de 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 Herramientas para desarrolladores

Si deseas crear una página de Herramientas para desarrolladores para tu extensión, agrega el campo devtools_page en la extensión manifiesto:

{
  "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 por cada Se abrió la ventana de Herramientas para desarrolladores. La página puede agregar otras páginas de extensiones, como paneles y barras laterales, a la Ventana de Herramientas para desarrolladores 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 extensión, como las acciones del navegador, los menús contextuales y las ventanas emergentes, una La 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 Elements, Sources y Network.
  • Un panel de la barra 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).

Ventana de Herramientas para desarrolladores que muestra el panel Elementos y el panel Estilos de la barra lateral.

Cada panel tiene su propio archivo HTML, que puede incluir otros recursos (JavaScript, CSS, imágenes, etcétera) activada). 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.
  • Expresión de JavaScript. Pasa una expresión a setExpression. Herramientas para desarrolladores evalúa en el contexto de la página inspeccionada y muestra el valor que se muestra.

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 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 para 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);
    });
});

Evaluar JavaScript en la ventana inspeccionada

Puedes usar el método inspectedWindow.eval para ejecutar el 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) { }
);

También puedes usar la opción useContentScriptContext: true para que inspectedWindow.eval() realice lo siguiente: 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 contenido adicional secuencias de comandos.

El método eval es potente cuando se usa en el contexto adecuado y peligroso cuando se usa. de forma inapropiada. 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.

Pasa 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 ejecutar con inspectedWindow.eval tiene acceso a la consola de Herramientas para desarrolladores 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 comando useContentScriptContext: true opción.

El código de tu secuencia de comandos de contenido podría ser similar al siguiente:

function setSelectedElement(el) {
    // do something with the selected element
}

Invoca el método desde la página de Herramientas para desarrolladores de la siguiente manera:

chrome.devtools.inspectedWindow.eval("setSelectedElement($0)",
    { useContentScriptContext: true });

La opción useContentScriptContext: true especifica que la expresión debe evaluarse en el el mismo contexto que las secuencias de comandos de contenido, por lo que puede acceder al método setSelectedElement.

Obtén 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 envías un mensaje desde una secuencia de comandos de contenido, no hay un método preestablecido para entregarlo. a la instancia de la página de Herramientas para desarrolladores correcta 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 Herramientas para desarrolladores (o el panel o el panel de la barra 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
});

Mensajería de las secuencias de comandos insertadas en la página de Herramientas para desarrolladores

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 al secuencia de comandos en segundo plano como se esperaba.

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. en la API de Cloud. Aquí hay un ejemplo, suponiendo 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á desde la secuencia de comandos insertada hasta la secuencia de comandos del contenido y pasará al segundo plano. y, por último, a la página de Herramientas para desarrolladores.

También puedes considerar dos técnicas alternativas de envío de mensajes aquí.

Cómo detectar cuándo se abre y se cierra Herramientas para desarrolladores

Si tu extensión necesita realizar un seguimiento de si la ventana de Herramientas para desarrolladores está abierta, puedes agregar onConnect de objetos a la página en segundo plano y llama a connect desde la página de Herramientas para desarrolladores. Como cada pestaña puede tienes su propia ventana de Herramientas para desarrolladores 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 el código fuente de estos ejemplos de extensión de Herramientas para desarrolladores:

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.