用于切换侧边栏的 Firefox WebExtension 工具栏按钮

Firefox WebExtension toolbar buttons to toggle sidebars

自 Firefox Australis 界面以来,不再有工具栏按钮可以通过单击切换书签和历史侧边栏。有 "show sidebars" 工具栏按钮,但它会显示动画弹出窗口并需要单击 2 次。

所以我正在尝试创建一个 WebExtension 来实现这些按钮。

我尝试了很多东西,但都没有成功,例如:

使用 browserAction 按钮打开您自己的边栏

您可以有一个 browserAction 工具栏按钮,它可以打开 您自己的 边栏。您可以通过在 manifest.json.

中同时定义 sidebar_actionbrowser_action 来做到这一点

在提出这个问题时,无法将 sidebar_actionbrowser_action 组合成 manifest.json。我不确定什么时候真正改变了,但截至目前(在 FF71 上测试),你可以同时拥有两者。

以下是执行此操作的示例代码:

manifest.json:

{
    "manifest_version": 2,
    "name": "Button opens sidebar",
    "description": "Open the sidebar with a toolbar button.",
    "version": "1.0",

    "browser_action": {
        "default_icon": "icon.png",
        "default_title": "Open Sidebar"
    },
    "background": {
        "scripts":[
            "background.js"
        ]
    },
    "sidebar_action": {
        "default_icon": "icon.png",
        "default_title": "Example Sidebar",
        "default_panel": "sidebar.html",
        "open_at_install": false
    }
}

background.js:

//The manifest.json entry must be a file in your extension, but you can change it to
//  an external site in your background.js:
browser.sidebarAction.setPanel({panel: 'https://example.org/'});
//Open the sidebar when the browserAction button is clicked.
browser.browserAction.onClicked.addListener(() => {
  browser.sidebarAction.open();
});

sidebar.html

<html>
  <body>
    <div>Example text</div>
  </body>
</html>

切换边栏open/closed

我尝试实现一个实际切换侧边栏的按钮的简单实现:

background.js

browser.browserAction.onClicked.addListener(() => {
    browser.sidebarAction.isOpen({}).then((isOpen) =>  {
        if (isOpen) {
            browser.sidebarAction.close();
        } else {
            browser.sidebarAction.open();
        }
    });
});

不幸的是,这失败并出现错误:

Error: sidebarAction.open may only be called from a user input handler

使用第二个 browserAction onClicked

您可以利用这样一个事实,即在您的扩展程序中显示 HTML 的侧边栏在后台上下文中 运行ning,只需添加一个额外的 browserAction.onClicked 侦听器关闭侧边栏的侧边栏。

background.js

browser.browserAction.onClicked.addListener(() => {
    browser.sidebarAction.open();
});

sidebar.js

browser.browserAction.onClicked.addListener(() => {
    browser.sidebarAction.close();
});

sidebar.html

<html>
  <head>
    <script src="sidebar.js"></script>
  </head>
  <body>
    <div>Example text</div>
  </body>
</html>

事件侦听器按添加的顺序执行,因此关闭侧边栏的 sidebar.js 添加的是 运行 在 background.js 中的那个之后打开侧边栏。因此,当边栏打开时,它会在单击 browserAction 按钮时关闭。

无法打开实际的书签或历史边栏

您特别希望打开实际的书签或历史边栏,而 WebExtensions 无法实现。你可以做的是自己实现类似的侧边栏。

我确实尝试将边栏 URL 更改为 chrome:// URL:

browser.sidebarAction.setPanel({panel: 'chrome://browser/content/aboutDialog.xul'});

不幸的是,这会导致错误:

Error: Access denied for URL chrome://browser/content/aboutDialog.xul

如果您希望以某种方式以编程方式打开实际的书签或历史边栏,那么您将需要 file a bug requesting the functionality. Alternately, you can also create a WebExtension Experiment 在安装 WebExtension Experiment 时将功能添加到 WebExtensions API。 WebExtension Experiments 不会自动集成到 Firefox 中,但有可能集成。

Firefox ⩾ 73

从 Firefox 73 开始,您可以简单地使用:

browser.browserAction.onClicked.addListener(() => {
    browser.sidebarAction.toggle();
});

Documentation on MDN

Firefox < 73

如果您需要支持旧版本的 Firefox,尤其是 ESR,您可以跟踪打开了哪些边栏。这是我为我的一个插件开发的方法,也是我知道的唯一一个可以与多个 windows.

一起正常工作的方法

在您的后台脚本中:

let openedSidebarWindows = {};
browser.runtime.onConnect.addListener(port => onConnect(port));
browser.browserAction.onClicked.addListener(tab => this.onClick(tab));

function onConnect(port) {
  const windowId = parseInt(port.name);
  openedSidebarWindows[windowId] = port;
  port.onDisconnect.addListener(port => {
    delete openedSidebarWindows[parseInt(port.name)];
  });
}

function onClick({ windowId }) {
  if (openedSidebarWindows[windowId] !== undefined) {
    browser.sidebarAction.close();
  } else {
    browser.sidebarAction.open();
  }
}

在您的边栏脚本中:

browser.runtime.connect({ name: windowId.toString() });