扩展开发者工具

开发者工具扩展程序通过访问开发者工具专用项,向 Chrome 开发者工具添加功能 通过向扩展程序添加的开发者工具页面进行操作。

<ph type="x-smartling-placeholder">
</ph> 显示开发者工具页面与
         检查窗口和 Service Worker。显示了 Service Worker
         与内容脚本通信以及访问扩展程序 API。
         “开发者工具”页面可以访问 DevTools API,例如创建面板。
DevTools 扩展程序架构。

开发者工具特定的扩展程序 API 包括:

开发者工具页面

打开开发者工具窗口时,DevTools 扩展程序会创建其开发者工具页面的实例, 但前提是窗口处于打开状态此页面有权访问开发者工具 API 和扩展程序 API,并可以执行以下操作:

“开发者工具”页面可以直接访问扩展程序 API。这包括 与 Service Worker 通信 消息传递

创建开发者工具扩展程序

如需为您的扩展程序创建开发者工具页面,请在扩展程序中添加 devtools_page 字段 清单:

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

devtools_page 字段必须指向 HTML 网页。因为开发者工具 网页必须是您的扩展程序的本地网页,我们建议您使用相对网址指定该网页。

chrome.devtools API 的成员仅适用于在开发者工具中加载的页面 同时该窗口处于打开状态内容脚本和其他扩展程序页面没有访问权限 这些 API。

开发者工具界面元素:面板和边栏窗格

除了常见的扩展程序界面元素(如浏览器操作、上下文菜单和弹出式窗口)外, DevTools 扩展程序可以将界面元素添加到开发者工具窗口:

  • 面板是顶级标签页,例如“元素”面板、“来源”面板和“网络”面板。
  • 边栏窗格提供与面板相关的补充界面。样式、计算样式和 “元素”面板上的“事件监听器”窗格就是边栏窗格的示例。根据 以及开发者工具窗口停靠的位置,则您的边栏窗格可能 如以下示例所示:
显示“Elements”面板和“Styles”边栏窗格的开发者工具窗口。
显示“元素”面板和“样式”边栏窗格的“开发者工具”窗口。

每个面板都是其自己的 HTML 文件,其中可包含其他资源(JavaScript、CSS、图片等) on)。如需创建基本面板,请使用以下代码:

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()。DevTools 在被检查网页的上下文中对表达式求值,然后显示返回值。

对于 setObject()setExpression(),窗格会显示其值,就像在 开发者工具控制台。不过,setExpression() 可让您显示 DOM 元素和任意 JavaScript 对象,而 setObject() 仅支持 JSON 对象。

在扩展程序组件之间通信

下面几部分介绍了允许开发者工具扩展程序组件执行下列操作的一些实用方法: 相互通信

注入内容脚本

如需注入内容脚本,请使用 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() 使用与代码相同的脚本执行上下文和选项 在开发者工具控制台中输入,从而允许访问开发者工具控制台实用程序 API 功能。eval()例如,SOAK 将其用于检查元素:

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

您也可以在调用 inspectedWindow.eval() 时将 useContentScriptContext 设置为 true。 在与内容脚本相同的上下文中对表达式求值。如需使用此选项,请在调用 eval() 之前使用静态内容脚本声明,方法是调用 executeScript() 或指定内容 脚本(位于 manifest.json 文件中)。加载上下文脚本上下文后,您还可以使用此选项 注入其他内容脚本。

将所选元素传递给内容脚本

内容脚本无法直接访问当前所选的元素。然而,您创建的任何代码 使用 inspectedWindow.eval() 执行,并且有权访问开发者工具 控制台和 Console 实用程序 API。例如,在经过评估的代码中,您可以使用 $0 访问 所选元素。

如需将所选元素传递给内容脚本,请执行以下操作:

  1. 在内容脚本中创建一个将所选元素作为参数的方法。

    function setSelectedElement(el) {
        // do something with the selected element
    }
    
  2. 使用 inspectedWindow.eval() 从开发者工具页面调用该方法 使用 useContentScriptContext: true 选项。

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

useContentScriptContext: true 选项指定必须在 与内容脚本相同的上下文,以便它可以访问 setSelectedElement 方法。

获取参考面板的 window

如需从开发者工具面板调用 postMessage(),您需要引用其 window 对象。获取 从 panel.onShown 事件处理脚本中移除面板的 iframe 窗口:

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

从注入的脚本向开发者工具页面发送消息

无需内容脚本即可直接注入到页面中的代码,包括通过附加 <script> 的方式注入 代码或调用 inspectedWindow.eval() 时,无法将消息发送到 使用 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 上找到其他替代消息传递技术。

检测开发者工具何时打开和关闭

如需跟踪开发者工具窗口是否已打开,请添加 onConnect 监听器 并从 DevTools 页面调用 connect()。因为 每个标签页都可以打开自己的开发者工具窗口,您可能会收到多个连接事件。 要跟踪是否打开了任何开发者工具窗口,请计算连接和断开连接事件数,如下所示 如下例中所示:

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

开发者工具扩展程序示例

本页面上的示例来自以下页面:

  • Polymer Devtools 扩展程序 - 使用在主机页面中运行的多个帮助程序来查询 要发送回自定义面板的 DOM/JS 状态。
  • React DevTools 扩展程序 - 使用渲染程序的子模块来重复使用开发者工具界面 组件。
  • Ember Inspector - 具有适用于 Chrome 和 Firefox 的适配器的共享扩展程序核心。
  • Coquette-Inspect - 注入了调试代理的干净基于 React 的扩展程序 复制到托管网页中
  • 扩展程序示例提供了更值得安装、试用和学习的扩展程序 。

更多信息

要了解扩展程序可以使用的标准 API,请参阅 chrome.*API网站 API

向我们提供反馈!您的意见和建议有助于我们改进 API。

示例

您可以在示例中找到使用开发者工具 API 的示例。