使用 Bookmarks API

书签使用户能够收集和组织网页列表,以便他们轻松地回到他们喜欢的页面。使用书签 API,您的扩展程序可以以与用户相同的方式操作书签。

Permissions

要使用书签 API,您需要在扩展程序的 manifest.json 文件中请求 "bookmarks" 权限。

json
"permissions": [
  "bookmarks"
],

功能

书签 API 允许您的扩展程序执行用户可以使用书签执行的操作,并包含用于以下功能的函数:

示例详解

为了更好地理解如何使用书签 API,让我们来看一个名为 bookmark-it 的示例。该示例添加了一个工具栏图标(browserAction),当单击该图标时,会将当前页面添加到书签或从书签中删除。如果页面以其他方式被收藏(或从收藏中删除),图标将更新以显示页面的收藏状态。

此视频展示了扩展程序的工作情况。

manifest.json

manifest.json 描述了此扩展程序。

json
{
  "manifest_version": 2,
  "name": "Bookmark it!",
  "version": "1.1",
  "description": "A simple bookmark button",
  "homepage_url": "https://github.com/mdn/webextensions-examples/tree/main/bookmark-it",

定义了将用于表示扩展程序的图标,例如在附加组件管理器等位置。

json
  "icons": {
    "48": "icons/bookmark-it.png",
    "96": "icons/bookmark-it@2x.png"
  },

请求权限。请求 "bookmarks" 以启用书签 API 的使用。请求 "tabs" 以便读取活动标签页的 URL 和标题,并用于创建或查找页面的书签。访问这些详细信息需要 Tabs API,这意味着您不太可能在不使用 Tabs API 的情况下使用 Bookmark API。

json
  "permissions": [
    "bookmarks",
    "tabs"
  ],

设置了基本工具栏按钮的详细信息。在得知页面的书签状态后,按钮的大部分功能将在代码中设置。

json
  "browser_action": {
    "default_icon": "icons/star-empty-38.png",
    "default_title": "Bookmark it!"
  },

定义了将添加和删除页面书签以及设置工具栏按钮特性的后台脚本。

json
  "background": {
    "scripts": ["background.js"]
  }

}

background.js

与任何后台脚本一样,background.js 在扩展程序启动时立即运行。最初,脚本调用 updateActiveTab(),该函数首先使用 tabs.query 获取当前标签页的 Tabs 对象,然后使用以下代码将该对象传递给 updateTab()

js
let gettingActiveTab = browser.tabs.query({
  active: true,
  currentWindow: true,
});
gettingActiveTab.then(updateTab);

updateTab() 首先将活动标签页的 URL 传递给 isSupportedProtocol()。如果协议受书签支持,则扩展程序会确定标签页的 URL 是否已被收藏,如果已收藏,则调用 updateIcon()

js
function updateTab(tabs) {
  if (tabs[0]) {
    currentTab = tabs[0];
    if (isSupportedProtocol(currentTab.url)) {
      let searching = browser.bookmarks.search({ url: currentTab.url });
      searching.then((bookmarks) => {
        currentBookmark = bookmarks[0];
        updateIcon();
      });
    } else {
      console.log(`Bookmark it! does not support the '${currentTab.url}' URL.`);
    }
  }
}

isSupportedProtocol() 确定活动标签页中显示的 URL 是否可以被收藏。为了从标签页的 URL 中提取协议,扩展程序利用了 HTMLAnchorElement,通过将标签页的 URL 添加到一个 <a> 元素中,然后使用 protocol 属性获取协议。

js
function isSupportedProtocol(urlString) {
  let supportedProtocols = ["https:", "http:", "file:"];
  let url = document.createElement("a");
  url.href = urlString;
  return supportedProtocols.includes(url.protocol);
}

updateIcon() 根据 URL 是否被收藏来设置工具栏按钮的图标和标题。

js
function updateIcon() {
  browser.browserAction.setIcon({
    path: currentBookmark
      ? {
          19: "icons/star-filled-19.png",
          38: "icons/star-filled-38.png",
        }
      : {
          19: "icons/star-empty-19.png",
          38: "icons/star-empty-38.png",
        },
    tabId: currentTab.id,
  });
  browser.browserAction.setTitle({
    // Screen readers can see the title
    title: currentBookmark ? "Unbookmark it!" : "Bookmark it!",
    tabId: currentTab.id,
  });
}

初始化工具栏按钮后,扩展程序开始监听工具栏按钮的单击事件,并在事件发生时调用 toggleBookmark()

js
browser.browserAction.onClicked.addListener(toggleBookmark);

toggleBookmark() 使用 updateTabs() 进行的搜索结果(该搜索查找 URL 是否存在于书签中)来确定是删除还是添加当前 URL 的书签。

js
function toggleBookmark() {
  if (currentBookmark) {
    browser.bookmarks.remove(currentBookmark.id);
  } else {
    browser.bookmarks.create({ title: currentTab.title, url: currentTab.url });
  }
}

为了更新工具栏图标,扩展程序会监听书签的创建或删除。这种方法的好处在于可以捕获扩展程序所做的书签更新以及用户在扩展程序外部所做的任何更新。

js
// listen for bookmarks being created
browser.bookmarks.onCreated.addListener(updateActiveTab);

// listen for bookmarks being removed
browser.bookmarks.onRemoved.addListener(updateActiveTab);

最后,扩展程序会监听活动标签页 URL 的更改,或者用户切换到其他标签页或窗口。这些操作可能会更改 URL,从而改变扩展程序工具栏图标的状态。

js
// listen to tab URL changes
browser.tabs.onUpdated.addListener(updateActiveTab);

// listen to tab switching
browser.tabs.onActivated.addListener(updateActiveTab);

// listen for window switching
browser.windows.onFocusChanged.addListener(updateActiveTab);

了解更多

如果您想了解更多信息,请查阅 书签 API 参考