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

Расширения 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

Пространство имен browser , введенное в Chrome 148, отключено для расширений, объявляющих devtools_page . Отключение распространяется на все расширение — не только на страницу DevTools, но и на каждый контекст скрипта, где выполняются API расширений. Продолжайте использовать chrome.* во всех этих расширениях.

The reason is a compatibility gap with webextension-polyfill . The chrome.devtools.* APIs are callback-only—they don't yet return Promises natively—so DevTools extensions commonly rely on the polyfill to wrap them. The polyfill skips wrapping whenever browser is defined, assuming the host has already done the work. If Chrome enabled browser for these extensions, the polyfill would no-op and chrome.devtools.* calls would stop returning Promises. Keeping browser off lets the polyfill keep wrapping.

Аналогичная опция также отключает другие изменения API обмена сообщениями Chrome 148 для этих расширений, включая ответы Promise в runtime.onMessage . Ограничение будет снято, как только API инструментов разработчика начнут поддерживать Promise нативно.

Элементы пользовательского интерфейса 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 друг с другом.

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

To inject a content script, use 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 . После загрузки контекста скрипта содержимого вы также можете использовать эту опцию для внедрения дополнительных скриптов содержимого.

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

The content script doesn't have direct access to the current selected element. However, any code you execute using inspectedWindow.eval() has access to the DevTools console and Console Utilities APIs. For example, in evaluated code you can use $0 to access the selected element.

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

  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 have more worthwhile extensions to install, try out, and learn from.

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

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

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

Примеры

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