Расширение инструментов разработчика

Расширения DevTools добавляют функции в Chrome DevTools, получая доступ к API расширений, специфичных для DevTools, через страницу DevTools, добавленную в расширение.

Архитектурная схема, показывающая взаимодействие страницы DevTools с проверяемым окном и сервис-воркером. Сервис-воркер показан взаимодействующим со скриптами контента и получающим доступ к API расширений. Страница DevTools имеет доступ к API DevTools, например, для создания панелей.
Архитектура расширений DevTools.

К числу API-интерфейсов расширений, специфичных для DevTools, относятся следующие:

Страница DevTools

Когда открывается окно DevTools, расширение DevTools создает экземпляр своей страницы DevTools, который существует до тех пор, пока окно открыто. Эта страница имеет доступ к API DevTools и API расширений и может выполнять следующие действия:

  • Создавайте панели и взаимодействуйте с ними, используя API devtools.panels , включая добавление страниц других расширений в качестве панелей или боковых панелей в окно DevTools.
  • Получите информацию об проверяемом окне и выполните код в проверяемом окне, используя API devtools.inspectedWindow .
  • Получайте информацию о сетевых запросах с помощью API devtools.network .
  • Расширьте функциональность панели записи, используя API-интерфейс devtools.recorder .
  • Получите информацию о состоянии записи на панели «Производительность» с помощью API devtools.performance .

На странице DevTools можно напрямую получить доступ к API расширений. Это включает в себя возможность взаимодействия с сервис-воркером с использованием передачи сообщений .

Создайте расширение для инструментов разработчика.

Чтобы создать страницу инструментов разработчика для вашего расширения, добавьте поле devtools_page в манифест расширения:

{
  "name": ...
  "version": "1.0",
  "devtools_page": "devtools.html",
  ...
}

Поле devtools_page должно указывать на HTML-страницу. Поскольку страница DevTools должна находиться локально в вашем расширении, мы рекомендуем указывать её с помощью относительного URL-адреса.

Доступ к API chrome.devtools имеют только страницы, загруженные в окне DevTools, пока это окно открыто. Скрипты контента и другие страницы расширений не имеют доступа к этим API.

Элементы пользовательского интерфейса DevTools: панели и боковые панели.

Помимо обычных элементов пользовательского интерфейса расширений, таких как действия браузера, контекстные меню и всплывающие окна, расширение DevTools может добавлять элементы пользовательского интерфейса в окно DevTools:

  • Панель — это вкладка верхнего уровня, подобная панелям «Элементы», «Источники» и «Сеть».
  • Боковая панель отображает дополнительный пользовательский интерфейс, связанный с основной панелью. Примерами боковых панелей являются панели «Стили», «Вычисляемые стили» и «Обработчики событий» на панели «Элементы». В зависимости от используемой версии Chrome и положения окна «Инструменты разработчика» ваши боковые панели могут выглядеть как на следующем примере:
Окно инструментов разработчика, отображающее панель «Элементы» и боковую панель «Стили».
Окно инструментов разработчика, отображающее панель «Элементы» и боковую панель «Стили».

Каждая панель представляет собой отдельный HTML-файл, который может содержать другие ресурсы (JavaScript, CSS, изображения и т. д.). Для создания простой панели используйте следующий код:

chrome.devtools.panels.create("My Panel",
    "MyPanelIcon.png",
    "Panel.html",
    function(panel) {
      // code invoked on panel creation
    }
);

JavaScript, выполняемый в панели или боковой панели, имеет доступ к тем же API, что и страница инструментов разработчика.

Для создания простой боковой панели используйте следующий код:

chrome.devtools.panels.elements.createSidebarPane("My Sidebar",
    function(sidebar) {
        // sidebar initialization code here
        sidebar.setObject({ some_data: "Some data to show" });
});

Существует несколько способов отображения контента в боковой панели:

  • HTML-содержимое: вызовите setPage() , чтобы указать HTML-страницу для отображения в панели.
  • Данные в формате JSON: передайте объект JSON в setObject() .
  • Выражение JavaScript: Передайте выражение в setExpression() . Инструменты разработчика вычислят выражение в контексте проверяемой страницы, а затем отобразят возвращаемое значение.

Для функций setObject() и setExpression() панель отображает значение так, как оно выглядело бы в консоли инструментов разработчика. Однако setExpression() позволяет отображать элементы DOM и произвольные объекты JavaScript, в то время как setObject() поддерживает только объекты JSON.

Взаимодействие между компонентами расширения

В следующих разделах описаны некоторые полезные способы обеспечения взаимодействия компонентов расширений DevTools друг с другом.

Внедрить скрипт контента

Для внедрения скрипта содержимого используйте scripting.executeScript() :

// DevTools page -- devtools.js
chrome.scripting.executeScript({
  target: {
    tabId: chrome.devtools.inspectedWindow.tabId
  },
  files: ["content_script.js"]
});

Идентификатор вкладки проверяемого окна можно получить с помощью свойства inspectedWindow.tabId .

Если скрипт контента уже внедрен, вы можете использовать API обмена сообщениями для взаимодействия с ним.

Выполните JavaScript в проверяемом окне.

Метод inspectedWindow.eval() позволяет выполнять код JavaScript в контексте проверяемой страницы. Вызов метода eval() можно осуществить на странице, панели или боковой панели инструментов разработчика.

По умолчанию выражение вычисляется в контексте основного фрейма страницы. inspectedWindow.eval() использует тот же контекст выполнения скрипта и параметры, что и код, введенный в консоли DevTools, что позволяет получить доступ к функциям API утилит консоли DevTools при использовании eval() . Например, используйте его для проверки первого элемента скрипта в разделе <head> HTML-документа:

chrome.devtools.inspectedWindow.eval(
  "inspect($$('head script')[0])",
  function(result, isException) { }
);

Вы также можете установить useContentScriptContext в true при вызове inspectedWindow.eval() , чтобы оценить выражение в том же контексте, что и скрипты содержимого. Для использования этой опции используйте статическое объявление скрипта содержимого перед вызовом eval() , либо вызвав executeScript() , либо указав скрипт содержимого в файле manifest.json . После загрузки контекста скрипта содержимого вы также можете использовать эту опцию для внедрения дополнительных скриптов содержимого.

Передайте выбранный элемент в скрипт содержимого.

Скрипт содержимого не имеет прямого доступа к текущему выбранному элементу. Однако любой код, выполняемый с помощью inspectedWindow.eval() имеет доступ к консоли DevTools и API Console Utilities. Например, в выполняемом коде вы можете использовать $0 для доступа к выбранному элементу.

Чтобы передать выбранный элемент в скрипт содержимого:

  1. Создайте в скрипте содержимого метод, который принимает выбранный элемент в качестве аргумента.

    function setSelectedElement(el) {
        // do something with the selected element
    }
    
  2. Вызовите метод со страницы DevTools, используя inspectedWindow.eval() с параметром useContentScriptContext: true .

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

Параметр useContentScriptContext: true указывает, что выражение должно вычисляться в том же контексте, что и скрипты содержимого, чтобы иметь доступ к методу setSelectedElement .

Получить window справочной панели

Для вызова postMessage() из панели инструментов разработчика вам потребуется ссылка на её объект window . Получить iframe-окно панели можно из обработчика события panel.onShown :

extensionPanel.onShown.addListener(function (extPanelWindow) {
    extPanelWindow instanceof Window; // true
    extPanelWindow.postMessage( // …
});

Отправляйте сообщения из внедренных скриптов на страницу инструментов разработчика.

Код, внедренный непосредственно на страницу без скрипта содержимого, включая добавление тега <script> или вызов inspectedWindow.eval() , не может отправлять сообщения на страницу DevTools с помощью runtime.sendMessage() . Вместо этого мы рекомендуем объединить внедренный скрипт со скриптом содержимого, который может выступать в качестве посредника, и использовать метод window.postMessage() . В следующем примере используется фоновый скрипт из предыдущего раздела:

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

Другие альтернативные методы передачи сообщений можно найти на GitHub .

Определять, когда открываются и закрываются инструменты разработчика.

Чтобы отслеживать, открыто ли окно DevTools, добавьте слушатель onConnect к сервис-воркеру и вызовите метод connect() со страницы DevTools. Поскольку каждая вкладка может иметь открытое собственное окно DevTools, вы можете получать несколько событий connect. Чтобы отслеживать, открыто ли какое-либо окно DevTools, подсчитайте события connect и disconnect, как показано в следующем примере:

// 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.");
          }
      });
    }
});

На странице «Инструменты разработчика» устанавливается соединение следующим образом:

// 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);

Примеры расширений DevTools

Примеры на этой странице взяты со следующих страниц:

  • Расширение Polymer Devtools — использует множество вспомогательных функций, работающих на главной странице, для запроса состояния DOM/JS и отправки его обратно в пользовательскую панель.
  • Расширение React DevTools — использует подмодуль рендерера для повторного использования компонентов пользовательского интерфейса DevTools.
  • Ember Inspector — общее ядро ​​расширений с адаптерами для Chrome и Firefox.
  • Coquette-inspect — это простое расширение на основе React с агентом отладки, внедряемым в главную страницу.
  • В разделе Sample Extensions вы найдете множество полезных расширений, которые стоит установить, попробовать и изучить.

Более подробная информация

Для получения информации о стандартных API, которые могут использовать расширения, см. API chrome.* и веб-API .

Оставляйте отзывы! Ваши комментарии и предложения помогают нам улучшать API.

Примеры

Примеры использования API DevTools можно найти в разделе «Примеры» .