DevTools extensions add features to Chrome DevTools by accessing DevTools-specific extension APIs through a DevTools page added to the extension.
DevTools extension architecture.The DevTools-specific extension APIs include the following:
The DevTools pageWhen a DevTools window opens, a DevTools extension creates an instance of its DevTools page that exists as long as the window is open. This page has access to the DevTools APIs and extension APIs, and can do the following:
devtools.panels
APIs, including adding other extension pages as panels or sidebars to the DevTools window.devtools.inspectedWindow
APIs.devtools.network
APIs.devtools.recorder
APIs.devtools.performance
APIs.The DevTools page can directly access extensions APIs. This includes being able to communicate with the service worker using message passing.
Create a DevTools extensionTo create a DevTools page for your extension, add the devtools_page
field in the extension manifest:
{
"name": ...
"version": "1.0",
"devtools_page": "devtools.html",
...
}
The devtools_page
field must point to an HTML page. Because the DevTools page must be local to your extension, we recommend specifying it using a relative URL.
The members of the chrome.devtools
API are available only to the pages loaded within the DevTools window while that window is open. Content scripts and other extension pages don't have access to these APIs.
In addition to the usual extension UI elements, such as browser actions, context menus and popups, a DevTools extension can add UI elements to the DevTools window:
Each panel is its own HTML file, which can include other resources (JavaScript, CSS, images, and so on). To create a basic panel, use the following code:
chrome.devtools.panels.create("My Panel",
"MyPanelIcon.png",
"Panel.html",
function(panel) {
// code invoked on panel creation
}
);
JavaScript executed in a panel or sidebar pane has access to the same APIs as the DevTools page.
To create a basic sidebar pane, use the following code:
chrome.devtools.panels.elements.createSidebarPane("My Sidebar",
function(sidebar) {
// sidebar initialization code here
sidebar.setObject({ some_data: "Some data to show" });
});
There are several ways to display content in a sidebar pane:
setPage()
to specify an HTML page to display in the pane.setObject()
.setExpression()
. DevTools evaluates the expression in the context of the inspected page, then displays the return value.For both setObject()
and setExpression()
, the pane displays the value as it would appear in the DevTools console. However, setExpression()
lets you display DOM elements and arbitrary JavaScript objects, while setObject()
only supports JSON objects.
The following sections describe some helpful ways to allow DevTools extension components to communicate with each other.
Inject a content scriptTo inject a content script, use scripting.executeScript()
:
// DevTools page -- devtools.js
chrome.scripting.executeScript({
target: {
tabId: chrome.devtools.inspectedWindow.tabId
},
files: ["content_script.js"]
});
You can retrieve the tab ID of the inspected window using the inspectedWindow.tabId
property.
If a content script has already been injected, you can use messaging APIs to communicate with it.
Evaluate JavaScript in the inspected windowYou can use the inspectedWindow.eval()
method to execute JavaScript code in the context of the inspected page. You can invoke the eval()
method from a DevTools page, panel, or sidebar pane.
eval()
only if you need access to the JavaScript content of an inspected page. Otherwise, we recommend using the scripting.executeScript()
method to run scripts. For more information, see inspectedWindow
.
By default, the expression is evaluated in the context of the main frame of the page. inspectedWindow.eval()
uses the same script execution context and options as code entered in the DevTools console, which allows access to DevTools Console Utilities API features when using eval()
. For example, use it to inspect the first script element within the <head>
section of the HTML document:
chrome.devtools.inspectedWindow.eval(
"inspect($$('head script')[0])",
function(result, isException) { }
);
You can also set the useContentScriptContext
to true
when calling inspectedWindow.eval()
to evaluate the expression in the same context as the content scripts. To use this option, use a static content script declaration before calling eval()
, either by calling executeScript()
or by specifying a content script in the manifest.json
file. After the context script context loads, you can also use this option to inject additional content scripts.
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.
To pass the selected element to a content script:
Create a method in the content script that takes the selected element as an argument.
function setSelectedElement(el) {
// do something with the selected element
}
Call the method from the DevTools page using inspectedWindow.eval()
with the useContentScriptContext: true
option.
chrome.devtools.inspectedWindow.eval("setSelectedElement($0)",
{ useContentScriptContext: true });
The useContentScriptContext: true
option specifies that the expression must be evaluated in the same context as the content scripts, so it can access the setSelectedElement
method.
window
To call postMessage()
from a devtools panel, you'll need a reference to its window
object. Get a panel's iframe window from the panel.onShown
event handler:
extensionPanel.onShown.addListener(function (extPanelWindow) {
extPanelWindow instanceof Window; // true
extPanelWindow.postMessage( // …
});
Send messages from injected scripts to the DevTools page
Code injected directly into the page without a content script, including by appending a <script>
tag or calling inspectedWindow.eval()
, can't send messages to the DevTools page using runtime.sendMessage()
. Instead, we recommend combining your injected script with a content script that can act as an intermediary, and using the window.postMessage()
method. The following example uses the background script from the previous section:
// 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);
});
Other alternative message-passing techniques can be found on GitHub.
Detect when DevTools opens and closesTo track whether the DevTools window is open, add an onConnect listener to the service worker and call connect() from the DevTools page. Because each tab can have its own DevTools window open, you might receive multiple connect events. To track whether any DevTools window is open, count the connect and disconnect events as shown in the following example:
// 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.");
}
});
}
});
The DevTools page creates a connection like this:
// 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);
The examples on this page come from the following pages:
For information on the standard APIs that extensions can use, see chrome.* APIs and web APIs.
Give us feedback! Your comments and suggestions help us improve the APIs.
ExamplesYou can find examples that use DevTools APIs in Samples.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4