As extensões do DevTools adicionam recursos ao Chrome DevTools acessando APIs de extensão específicas do DevTools por uma página do DevTools adicionada à extensão.
As APIs de extensão específicas do DevTools incluem o seguinte:
A página do DevTools
Quando uma janela do DevTools é aberta, uma extensão do DevTools cria uma instância da página do DevTools que existe enquanto a janela está aberta. Essa página tem acesso às APIs do DevTools e às APIs de extensão e pode fazer o seguinte:
- Criar e interagir com painéis usando as
devtools.panelsAPIs, incluindo a adição de outras páginas de extensão como painéis ou barras laterais à janela do DevTools. - Receber informações sobre a janela inspecionada e avaliar o código nela usando as
devtools.inspectedWindowAPIs. - Receber informações sobre solicitações de rede usando as
devtools.networkAPIs. - Estender o painel do gravador usando as APIs
devtools.recorder. - Receber informações sobre o status do registro do painel de desempenho usando as APIs
devtools.performance.
A página do DevTools pode acessar diretamente as APIs de extensões. Isso inclui a capacidade de se comunicar com o service worker usando a passagem de mensagens.
Criar uma extensão do DevTools
Para criar uma página do DevTools para sua extensão, adicione o campo devtools_page no manifesto da extensão:
{
"name": ...
"version": "1.0",
"devtools_page": "devtools.html",
...
}
O campo devtools_page precisa apontar para uma página HTML. Como a página do DevTools precisa ser local para sua extensão, recomendamos especificá-la usando um URL relativo.
Os membros da API chrome.devtools estão disponíveis apenas para as páginas carregadas na janela do DevTools enquanto essa janela estiver aberta. Scripts de conteúdo e outras páginas de extensão não têm acesso a essas APIs.
O namespace do navegador e as extensões do DevTools
O browser namespace
introduzido no Chrome 148 está desativado para extensões que declaram
devtools_page. A desativação se aplica a toda a extensão, não apenas à página do DevTools, mas a todos os contextos de script em que as APIs de extensão são executadas. Continue usando chrome.* nessas extensões.
O motivo é uma lacuna de compatibilidade com
o webextension-polyfill.
As APIs chrome.devtools.* são apenas de callback. Elas ainda não retornam Promises de forma nativa. Portanto, as extensões do DevTools geralmente dependem do polyfill para envolvê-las. O polyfill ignora o encapsulamento sempre que browser é definido, presumindo que o host já fez o trabalho. Se o Chrome ativasse browser para essas extensões, o polyfill não funcionaria e as chamadas chrome.devtools.* parariam de retornar Promises. Manter browser desativado permite que o polyfill continue encapsulando.
A mesma desativação também desativa as outras mudanças na API de mensagens do Chrome 148
para essas extensões, incluindo
respostas de Promises em runtime.onMessage.
A restrição será removida quando as APIs do DevTools oferecerem suporte a Promises de forma nativa.
Elementos da interface do DevTools: painéis e barras laterais
Além dos elementos de interface de extensão comuns, como ações do navegador, menus de contexto e pop-ups, uma extensão do DevTools pode adicionar elementos de interface à janela do DevTools:
- Um painel é uma guia de nível superior, como os painéis "Elementos", "Fontes" e "Rede".
- Um painel da barra lateral apresenta uma interface complementar relacionada a um painel. Os painéis "Estilos", "Estilos computados" e "Listeners de eventos" no painel "Elementos" são exemplos de painéis da barra lateral. Dependendo da versão do Chrome que você está usando e de onde a janela do DevTools está ancorada, os painéis da barra lateral podem ser parecidos com a imagem de exemplo a seguir:
Cada painel é um arquivo HTML próprio, que pode incluir outros recursos (JavaScript, CSS, imagens etc.). Para criar um painel básico, use o código a seguir:
chrome.devtools.panels.create("My Panel",
"MyPanelIcon.png",
"Panel.html",
function(panel) {
// code invoked on panel creation
}
);
O JavaScript executado em um painel ou painel da barra lateral tem acesso às mesmas APIs que a página do DevTools.
Para criar um painel da barra lateral básico, use o código a seguir:
chrome.devtools.panels.elements.createSidebarPane("My Sidebar",
function(sidebar) {
// sidebar initialization code here
sidebar.setObject({ some_data: "Some data to show" });
});
Há várias maneiras de mostrar conteúdo em um painel da barra lateral:
- Conteúdo HTML: chame
setPage()para especificar uma página HTML a ser mostrada no painel. - Dados JSON: transmita um objeto JSON para
setObject(). - Expressão JavaScript: transmita uma expressão para
setExpression(). O DevTools avalia a expressão no contexto da página inspecionada e mostra o valor de retorno.
Para setObject() e setExpression(), o painel mostra o valor da mesma forma que ele aparece no console do DevTools. No entanto, setExpression() permite mostrar elementos DOM e objetos JavaScript arbitrários, enquanto setObject() oferece suporte apenas a objetos JSON.
Comunicar entre componentes de extensão
As seções a seguir descrevem algumas maneiras úteis de permitir que os componentes de extensão do DevTools se comuniquem entre si.
Injetar um script de conteúdo
Para injetar um script de conteúdo, use scripting.executeScript():
// DevTools page -- devtools.js
chrome.scripting.executeScript({
target: {
tabId: chrome.devtools.inspectedWindow.tabId
},
files: ["content_script.js"]
});
É possível recuperar o ID da guia da janela inspecionada usando a
inspectedWindow.tabId propriedade.
Se um script de conteúdo já tiver sido injetado, você poderá usar APIs de mensagens para se comunicar com ele.
Avaliar JavaScript na janela inspecionada
É possível usar o método inspectedWindow.eval() para executar o código JavaScript
no contexto da página inspecionada. Você pode invocar o método eval() em uma página, painel ou barra lateral do DevTools.
Por padrão, a expressão é avaliada no contexto do frame principal da página.
inspectedWindow.eval() usa o mesmo contexto e opções de execução de script que o código
inserido no console do DevTools, o que permite o acesso aos recursos da API de utilitários do console
do DevTools ao usar eval(). Por exemplo, use-o para inspecionar
o primeiro elemento de script na seção <head> do documento HTML:
chrome.devtools.inspectedWindow.eval(
"inspect($$('head script')[0])",
function(result, isException) { }
);
Você também pode definir useContentScriptContext como true ao chamar inspectedWindow.eval() para avaliar a expressão no mesmo contexto que os scripts de conteúdo. Para usar essa opção, use uma declaração de script de conteúdo estático antes de chamar eval(), chamando executeScript() ou especificando um script de conteúdo
no arquivo manifest.json. Depois que o contexto do script de conteúdo for carregado, você também poderá usar essa opção para injetar outros scripts de conteúdo.
Transmitir o elemento selecionado para um script de conteúdo
O script de conteúdo não tem acesso direto ao elemento selecionado no momento. No entanto, qualquer código que você
executar usando inspectedWindow.eval() tem acesso ao console do DevTools
e às APIs de utilitários do console. Por exemplo, no código avaliado, você pode usar $0 para acessar o elemento selecionado.
Para transmitir o elemento selecionado para um script de conteúdo:
Crie um método no script de conteúdo que receba o elemento selecionado como argumento.
function setSelectedElement(el) { // do something with the selected element }Chame o método na página do DevTools usando
inspectedWindow.eval()com a opçãouseContentScriptContext: true.chrome.devtools.inspectedWindow.eval("setSelectedElement($0)", { useContentScriptContext: true });
A opção useContentScriptContext: true especifica que a expressão precisa ser avaliada no mesmo contexto que os scripts de conteúdo, para que ela possa acessar o método setSelectedElement.
Receber o window de um painel de referência
Para chamar postMessage() em um painel do DevTools, você precisa de uma referência ao objeto window. Receba a
janela do iframe de um painel do panel.onShown manipulador de eventos:
extensionPanel.onShown.addListener(function (extPanelWindow) {
extPanelWindow instanceof Window; // true
extPanelWindow.postMessage( // …
});
Enviar mensagens de scripts injetados para a página do DevTools
O código injetado diretamente na página sem um script de conteúdo, incluindo a anexação de uma <script>
tag ou a chamada de inspectedWindow.eval(), não pode enviar mensagens para a
página do DevTools usando runtime.sendMessage(). Em vez disso, recomendamos
combinar o script injetado com um script de conteúdo que possa atuar como intermediário e usar
o window.postMessage() método. O exemplo a seguir usa o script de segundo plano da seção 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);
});
Outras técnicas alternativas de passagem de mensagens podem ser encontradas no GitHub.
Detectar quando o DevTools é aberto e fechado
Para acompanhar se a janela do DevTools está aberta, adicione um onConnect listener ao service worker e chame connect() na página do DevTools. Como cada guia pode ter a própria janela do DevTools aberta, você pode receber vários eventos de conexão. Para acompanhar se alguma janela do DevTools está aberta, conte os eventos de conexão e desconexão, conforme mostrado no exemplo a seguir:
// 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.");
}
});
}
});
A página do DevTools cria uma conexão 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);
Exemplos de extensão do DevTools
Os exemplos nesta página são das seguintes páginas:
- Extensão do Polymer Devtools (link em inglês) – usa muitos auxiliares em execução na página do host para consultar o estado do DOM/JS e enviar de volta ao painel personalizado.
- Extensão do React DevTools (link em inglês) – usa um submódulo do renderizador para reutilizar componentes da interface do DevTools.
- Ember Inspector (link em inglês) – núcleo de extensão compartilhado com adaptadores para Chrome e Firefox.
- Coquette-inspect (link em inglês) – uma extensão limpa baseada em React com um agente de depuração injetado na página do host.
- As extensões de amostra têm mais extensões úteis para instalar, testar e aprender com.
Mais informações
Para informações sobre as APIs padrão que as extensões podem usar, consulte chrome.* APIs e APIs da Web.
Envie seu feedback. Seus comentários e sugestões nos ajudam a melhorar as APIs.
Exemplos
Você pode encontrar exemplos que usam APIs do DevTools em Amostras.