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ń związanych z tymi narzędziami za pomocą dodanej do rozszerzenia strony Narzędzia deweloperskie.

Schemat architektury przedstawiający stronę narzędzi deweloperskich komunikujących się ze sprawdzanym oknem i mechanizmem Service Worker. Skrypt service worker komunikuje się ze skryptami treści i uzyskuje dostęp do interfejsów API rozszerzeń.
         Strona Narzędzia deweloperskie ma dostęp do interfejsów API Narzędzi deweloperskich, na przykład do tworzenia paneli.
Architektura rozszerzenia DevTools.

Interfejsy API rozszerzeń związane z Narzędziami deweloperskimi to między innymi:

Strona DevTools

Gdy otworzy się okno Narzędzi deweloperskich, rozszerzenie z tych narzędzi utworzy instancję strony Narzędzi deweloperskich, która będzie istnieć, dopóki to okno jest otwarte. Ta strona ma dostęp do interfejsów DevTools API i interfejsów API rozszerzeń oraz może wykonywać te czynności:

  • Twórz panele i wchodź z nimi w interakcję za pomocą interfejsów API devtools.panels, m.in. dodawaj inne strony rozszerzeń jako panele lub paski boczne do okna Narzędzi dla programistów.
  • Pobierz informacje o kontrolowanym oknie i oceniaj kod w sprawdzanym oknie za pomocą interfejsów API devtools.inspectedWindow.
  • Uzyskiwanie informacji o żądaniach sieciowych za pomocą interfejsów API devtools.network.
  • Rozszerz panel Dyktafonu za pomocą interfejsów API devtools.recorder.

Strona Narzędzia deweloperskie ma bezpośredni dostęp do interfejsów API rozszerzeń. Obejmuje to też komunikację z mechanizmem Service Worker za pomocą przekazywania wiadomości.

Tworzenie rozszerzenia Narzędzia deweloperskie

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 mieć lokalizację lokalną, więc zalecamy podanie jej za pomocą względnego adresu URL.

Użytkownicy interfejsu chrome.devtools API są dostępni tylko na stronach wczytywanych w oknie Narzędzi deweloperskich, gdy to okno jest otwarte. Skrypty treści i inne strony rozszerzeń nie mają dostępu do tych interfejsów API.

Elementy interfejsu Narzędzi deweloperskich: panele i panele na pasku bocznym

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

  • Panel to karta najwyższego poziomu, tak jak panele Elementy, Źródła i Sieć.
  • Panel boczny to dodatkowy interfejs powiązany z panelem. Panele Style, Style obliczone i Detektory zdarzeń w panelu Elementy to przykłady paneli paska bocznego. W zależności od używanej wersji Chrome i miejsca zadokowania okna Narzędzi deweloperskich panele paska bocznego mogą wyglądać tak jak na tym przykładowym obrazie:
Okno narzędzi deweloperskich z widocznym panelem Elementy i panelem Style na pasku bocznym.
Okno Narzędzia deweloperskie z widocznym panelem Elementy i panelem Style na pasku bocznym.

Każdy panel to własny plik HTML, który może zawierać inne zasoby (JavaScript, CSS, obrazy itd.). 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 panelu paska bocznego ma dostęp do tych samych interfejsów API co strona Narzędzia dla deweloperów.

Aby utworzyć podstawowy panel paska bocznego, 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" });
});

Zawartość panelu paska bocznego można wyświetlać na kilka sposobów:

  • Treść HTML: wywołaj setPage(), aby wskazać stronę HTML wyświetlaną w panelu.
  • Dane JSON: przekaż obiekt JSON do setObject().
  • Wyrażenie JavaScript: przekaż wyrażenie do funkcji setExpression(). Narzędzia deweloperskie oceniają wyrażenie w kontekście sprawdzanej strony, a potem wyświetlają zwracaną wartość.

Zarówno w przypadku setObject(), jak i setExpression() panel wyświetla wartość, która będzie widoczna 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 rozszerzeń

W sekcjach poniżej znajdziesz przydatne sposoby umożliwiania komunikacji między komponentami rozszerzeń Narzędzi deweloperskich.

Wstaw skrypt treści

Aby wstawić 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 badanego okna możesz pobrać za pomocą właściwości inspectedWindow.tabId.

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

Ocena JavaScriptu w sprawdzanym oknie

Możesz użyć metody inspectedWindow.eval() do wykonywania kodu JavaScript w kontekście sprawdzanej strony. Metodę eval() możesz wywołać na stronie, panelu lub panelu paska bocznego Narzędzia deweloperskie.

Domyślnie wyrażenie jest sprawdzane w kontekście głównej ramki strony. inspectedWindow.eval() korzysta z tego samego kontekstu wykonywania skryptu i opcji co kod wpisany w konsoli Narzędzi deweloperskich, co umożliwia dostęp do funkcji interfejsu API konsoli narzędzi DevTools, gdy używasz eval(). Na przykład funkcja SOAK używa go do badania elementu:

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

Możesz też ustawić useContentScriptContext na true podczas wywoływania metody inspectedWindow.eval(), aby ocenić wyrażenie w tym samym kontekście co skrypty treści. Aby skorzystać z tej opcji, przed wywołaniem metody eval() użyj deklaracji skryptu treści statycznych. W tym celu wywołaj metodę executeScript() lub wskaż skrypt treści w pliku manifest.json. Po wczytaniu kontekstu skryptu kontekstowego możesz też użyć tej opcji, aby wstrzyknąć dodatkowe skrypty treści.

Przekaż wybrany element do skryptu dotyczącego treści

Skrypt treści nie ma bezpośredniego dostępu do aktualnie wybranego elementu. Jednak każdy kod wykonywany za pomocą inspectedWindow.eval() ma dostęp do konsoli DevTools i interfejsów Console Utilities API. Na przykład w ocenionym kodzie możesz użyć polecenia $0, aby uzyskać dostęp do wybranego elementu.

Aby przekazać wybrany element do skryptu dotyczącego 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ę na stronie Narzędzia deweloperskie za pomocą inspectedWindow.eval() z opcją useContentScriptContext: true.

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

Opcja useContentScriptContext: true określa, że wyrażenie musi być oceniane w tym samym kontekście co skrypty treści, aby miało dostęp do metody setSelectedElement.

Pobierz window panelu referencyjnego

Aby wywołać postMessage() z panelu narzędzi deweloperskich, potrzebujesz odwołania do jego obiektu window. Pobierz okno iframe panelu z modułu obsługi zdarzeń panel.onShown:

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

Wysyłanie komunikatów z wstrzykniętych skryptów na stronę Narzędzi deweloperskich

Kod wstrzyknięty bezpośrednio na stronie bez skryptu dotyczącego treści, na przykład przez dołączenie 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, za pomocą metody window.postMessage(). W tym przykładzie używamy skryptu działającego 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 metody przekazywania wiadomości znajdziesz na GitHubie.

Wykrywanie otwarcia i zamykania Narzędzi deweloperskich

Aby sprawdzić, czy okno Narzędzi deweloperskich jest otwarte, dodaj detektor onConnect do skryptu service worker i wywołaj connect() na stronie Narzędzia dla programistów. Każda karta może mieć własne okno Narzędzi deweloperskich, więc możesz otrzymywać wiele zdarzeń połączenia. Aby sprawdzić, czy jest otwarte jakieś okno Narzędzi deweloperskich, policz zdarzenia łączenia i rozłączania w ten sposób:

// 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 DevTools tworzy takie połączenie:

// 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 elementów pomocniczych działających na stronie hosta w celu wysyłania zapytań dotyczących stanu DOM/JS w celu przekierowania do panelu niestandardowego.
  • Rozszerzenie React DevTools – używa modułu podrzędnego mechanizmu renderowania, aby ponownie używać komponentów interfejsu Narzędzi deweloperskich.
  • Ember Inspector – współużytkowany rdzeń rozszerzenia z adapterami do Chrome i Firefoksa.
  • Coquette-inspect – czyste rozszerzenie oparte na React, w którym na stronie hosta jest wstrzyknięty agent debugowania.
  • Przykładowe rozszerzenia zawierają przydatne rozszerzenia, które warto zainstalować, wypróbować i wyciągnąć.

Więcej informacji

Informacje o standardowych interfejsach API, z których mogą korzystać rozszerzenia, znajdziesz na stronie chrome.* interfejsów API i internetowych interfejsów API.

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

Przykłady

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