Narzędzia dla programistów Extend

Rozszerzenia Narzędzi deweloperskich dodają funkcje do Narzędzi deweloperskich w Chrome, uzyskując dostęp do interfejsów API rozszerzeń specyficznych dla Narzędzi deweloperskich za pomocą strony Narzędzi deweloperskich dodanej do rozszerzenia.

Schemat architektury pokazujący stronę Narzędzi deweloperskich komunikującą się z kontrolowanym oknem i skryptem service worker. Skrypt service worker komunikuje się ze skryptami treści i ma dostęp do interfejsów API rozszerzeń.
         Strona Narzędzi deweloperskich ma dostęp do interfejsów API Narzędzi deweloperskich, np. do tworzenia paneli.
Architektura rozszerzenia Narzędzi deweloperskich.

Interfejsy API rozszerzeń przeznaczone dla Narzędzi deweloperskich obejmują:

Strona Narzędzi deweloperskich

Gdy otworzy się okno Narzędzi deweloperskich, rozszerzenie Narzędzi deweloperskich utworzy instancję swojej strony Narzędzi deweloperskich, która będzie istniała tak długo, jak długo okno będzie otwarte. Ta strona ma dostęp do interfejsów API Narzędzi deweloperskich i interfejsów API rozszerzeń oraz może wykonywać te czynności:

Strona Narzędzi deweloperskich ma bezpośredni dostęp do interfejsów API rozszerzeń. Obejmuje to możliwość komunikowania się ze skryptem service worker za pomocą przekazywania wiadomości.

Tworzenie rozszerzenia Narzędzi deweloperskich

Aby utworzyć stronę Narzędzi deweloperskich dla rozszerzenia, dodaj pole devtools_page w pliku manifestu rozszerzenia:

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

Pole devtools_page musi wskazywać stronę HTML. Strona Narzędzi deweloperskich musi być lokalna w stosunku do rozszerzenia, dlatego zalecamy określanie jej za pomocą względnego adresu URL.

Elementy interfejsu chrome.devtools API są dostępne tylko na stronach wczytanych w oknie Narzędzi deweloperskich, gdy to okno jest otwarte. Skrypty treści i inne strony rozszerzenia nie mają dostępu do tych interfejsów API.

Przestrzeń nazw przeglądarki i rozszerzenia Narzędzi deweloperskich

browser Przestrzeń nazw wprowadzona w Chrome 148 jest wyłączona w przypadku rozszerzeń, które deklarują devtools_page. Rezygnacja dotyczy całego rozszerzenia, a nie tylko strony Narzędzi deweloperskich, ale każdego kontekstu skryptu, w którym działają interfejsy API rozszerzeń. W tych rozszerzeniach nadal używaj symbolu chrome.*.

Przyczyną jest brak zgodności z webextension-polyfill. Interfejsy API chrome.devtools.* działają tylko w przypadku wywołań zwrotnych – nie zwracają jeszcze natywnie obiektów Promise, więc rozszerzenia Narzędzi deweloperskich często korzystają z polyfillu, aby je opakować. Jeśli zdefiniowano browser, polyfill pomija opakowywanie, zakładając, że host już wykonał to zadanie. Jeśli Chrome włączy browser dla tych rozszerzeń, polyfill nie będzie działać, a wywołania chrome.devtools.* przestaną zwracać obietnice. Wyłączenie browser powoduje, że polyfill nadal opakowuje.

Ta sama rezygnacja wyłącza też inne zmiany w interfejsie Chrome 148 Messaging API w przypadku tych rozszerzeń, w tym odpowiedzi Promise w runtime.onMessage. Ograniczenie zostanie zniesione, gdy interfejsy API Narzędzi deweloperskich będą natywnie obsługiwać obietnice.

Elementy interfejsu Narzędzi deweloperskich: panele i panele boczne

Oprócz zwykłych elementów interfejsu rozszerzenia, takich jak działania przeglądarki, menu kontekstowe i wyskakujące okienka, rozszerzenie Narzędzi deweloperskich może dodawać elementy interfejsu do okna Narzędzi deweloperskich:

  • Panel to karta najwyższego poziomu, np. Elementy, Źródła czy Sieć.
  • Panel paska bocznego zawiera dodatkowy interfejs powiązany z panelem. Panele Style, Style wynikowe i Detektory zdarzeń na panelu Elementy to przykłady paneli bocznych. W zależności od wersji Chrome, której używasz, i miejsca zadokowania okna Narzędzi deweloperskich panele boczne mogą wyglądać jak na tym przykładzie:
Okno Narzędzi deweloperskich z panelem Elementy i panelem bocznym Style.
Okno Narzędzi deweloperskich z panelem Elementy i paskiem bocznym Style.

Każdy panel to osobny plik HTML, który może zawierać inne zasoby (JavaScript, CSS, obrazy itp.). Aby utworzyć podstawowy panel, użyj tego kodu:

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

Kod JavaScript wykonywany w panelu lub w okienku paska bocznego ma dostęp do tych samych interfejsów API co strona Narzędzi deweloperskich.

Aby utworzyć podstawowy panel boczny, użyj tego kodu:

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

Treści w panelu bocznym można wyświetlać na kilka sposobów:

  • Treść HTML: wywołaj funkcję setPage(), aby określić stronę HTML, która ma być wyświetlana w panelu.
  • Dane JSON: przekaż obiekt JSON do funkcji setObject().
  • Wyrażenie JavaScript: przekaż wyrażenie do funkcji setExpression(). Narzędzia deweloperskie obliczają wartość wyrażenia w kontekście sprawdzanej strony, a następnie wyświetlają wartość zwracaną.

W przypadku obu typów setObject()setExpression() w panelu wyświetlana jest wartość, która pojawiłaby się w konsoli Narzędzi deweloperskich. setExpression() umożliwia jednak wyświetlanie elementów DOM i dowolnych obiektów JavaScript, a setObject() obsługuje tylko obiekty JSON.

Komunikacja między komponentami rozszerzenia

W sekcjach poniżej znajdziesz przydatne sposoby umożliwiające komponentom rozszerzenia Narzędzi deweloperskich komunikację ze sobą.

Wstrzykiwanie skryptu dotyczącego zawartości

Aby wstrzyknąć skrypt treści, użyj scripting.executeScript():

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

Identyfikator karty sprawdzanego okna możesz pobrać za pomocą właściwości inspectedWindow.tabId.

Jeśli skrypt treści został już wstrzyknięty, możesz użyć interfejsów API do przesyłania wiadomości, aby się z nim komunikować.

Ocena JavaScriptu w sprawdzanym oknie

Możesz użyć metody inspectedWindow.eval(), aby wykonać kod JavaScript w kontekście sprawdzanej strony. Metodę eval() możesz wywołać ze strony Narzędzi deweloperskich, panelu lub panelu bocznego.

Domyślnie wyrażenie jest oceniane w kontekście ramki głównej strony. inspectedWindow.eval() używa tego samego kontekstu i opcji wykonywania skryptu co kod wpisany w konsoli Narzędzi deweloperskich, co umożliwia dostęp do funkcji interfejsu API narzędzi konsoli Narzędzi deweloperskich podczas korzystania z eval(). Możesz go na przykład użyć do sprawdzenia pierwszego elementu skryptu w sekcji <head> dokumentu HTML:

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

Możesz też ustawić wartość useContentScriptContext na true podczas wywoływania inspectedWindow.eval(), aby ocenić wyrażenie w tym samym kontekście co skrypty treści. Aby użyć tej opcji, przed wywołaniem funkcji eval() użyj deklaracji skryptu treści statycznych, wywołując funkcję executeScript() lub określając skrypt treści w pliku manifest.json. Po wczytaniu kontekstu skryptu dotyczącego zawartości możesz też użyć tej opcji, aby wstrzyknąć dodatkowe skrypty dotyczące zawartości.

Przekazywanie wybranego elementu do skryptu treści

Skrypt treści nie ma bezpośredniego dostępu do obecnie wybranego elementu. Jednak każdy kod, który wykonujesz za pomocą inspectedWindow.eval(), ma dostęp do konsoli Narzędzi deweloperskich i interfejsów API narzędzi konsoli. Na przykład w ocenianym kodzie możesz użyć $0, aby uzyskać dostęp do wybranego elementu.

Aby przekazać wybrany element do skryptu treści:

  1. Utwórz w skrypcie treści metodę, która przyjmuje wybrany element jako argument.

    function setSelectedElement(el) {
        // do something with the selected element
    }
    
  2. Wywołaj metodę ze strony Narzędzi deweloperskich za pomocą inspectedWindow.eval() z opcją useContentScriptContext: true.

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

Opcja useContentScriptContext: true oznacza, że wyrażenie musi być oceniane w tym samym kontekście co skrypty treści, dzięki czemu może uzyskać dostęp do metody setSelectedElement.

Pobieranie window z panelu referencyjnego

Aby wywołać funkcję postMessage() z panelu narzędzi deweloperskich, musisz mieć odniesienie do jej obiektu window. Pobierz okno elementu iframe panelu z modułu obsługi zdarzeń panel.onShown:

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

Wysyłanie wiadomości ze skryptów wstrzykiwanych na stronę Narzędzi deweloperskich

Kod wstrzyknięty bezpośrednio na stronę bez skryptu treści, w tym przez dodanie tagu <script> lub wywołanie inspectedWindow.eval(), nie może wysyłać wiadomości na stronę Narzędzi deweloperskich za pomocą runtime.sendMessage(). Zamiast tego zalecamy połączenie wstrzykniętego skryptu ze skryptem treści, który może pełnić rolę pośrednika, i użycie metody window.postMessage(). W tym przykładzie użyto skryptu w tle z poprzedniej sekcji:

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

Inne alternatywne techniki przekazywania wiadomości znajdziesz na GitHubie.

Wykrywanie otwierania i zamykania Narzędzi deweloperskich

Aby śledzić, czy okno Narzędzi deweloperskich jest otwarte, dodaj do skryptu service worker odbiornik onConnect i wywołaj connect() ze strony Narzędzi deweloperskich. Każda karta może mieć otwarte własne okno Narzędzi deweloperskich, więc możesz otrzymać wiele zdarzeń połączenia. Aby śledzić, czy jest otwarte jakiekolwiek okno Narzędzi deweloperskich, zliczaj zdarzenia połączenia i rozłączenia, jak pokazano w tym przykładzie:

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

Strona Narzędzi deweloperskich tworzy połączenie w ten sposób:

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

Przykłady rozszerzeń Narzędzi deweloperskich

Przykłady na tej stronie pochodzą z tych stron:

  • Rozszerzenie Polymer Devtools – korzysta z wielu pomocników działających na stronie hosta, aby wysyłać zapytania do stanu DOM/JS i przesyłać je z powrotem do panelu niestandardowego.
  • Rozszerzenie React DevTools – używa podmodułu renderera do ponownego wykorzystania komponentów interfejsu Narzędzi deweloperskich.
  • Ember Inspector – wspólny rdzeń rozszerzenia z adapterami dla Chrome i Firefox.
  • Coquette-inspect – czyste rozszerzenie oparte na React z wstrzykniętym agentem debugowania na stronie hosta.
  • Przykładowe rozszerzenia zawierają więcej przydatnych rozszerzeń, które możesz zainstalować, wypróbować i poznać.

Więcej informacji

Informacje o standardowych interfejsach API, z których mogą korzystać rozszerzenia, znajdziesz w artykule chrome.* interfejsy APIinterfejsy API.

Prześlij nam opinię Twoje komentarze i sugestie pomogą nam ulepszyć interfejsy API.

Przykłady

Przykłady korzystania z interfejsów API Narzędzi deweloperskich znajdziesz w sekcji Przykłady.