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

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

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

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

Страница инструментов разработчика

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

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

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

Создайте расширение DevTools.

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

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

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

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

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

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

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

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

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

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

Чтобы создать базовую боковую панель, используйте следующий код:

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() . DevTools оценивает выражение в контексте проверяемой страницы, а затем отображает возвращаемое значение.

Как для setObject() так и setExpression() на панели отображается значение так, как оно отображается в консоли DevTools. Однако 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() со страницы, панели или боковой панели DevTools.

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

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

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

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

Сценарий содержимого не имеет прямого доступа к текущему выбранному элементу. Однако любой код, который вы выполняете с помощью inspectedWindow.eval() имеет доступ к консоли DevTools и API консольных утилит. Например, в оцененном коде вы можете использовать $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( // …
});

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

Код, внедренный непосредственно на страницу без сценария содержимого, в том числе путем добавления тега <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 открывается и закрывается

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

// 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 создает такое соединение:

// 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 с агентом отладки, внедренным в хост-страницу.
  • Примеры расширений содержат более полезные расширения, которые можно установить, опробовать и изучить.

Дополнительная информация

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

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

Примеры

Вы можете найти примеры, использующие API DevTools, в разделе Samples .