Safari 扩展 - 如何仅在特定选项卡上设置徽章编号?

Safari extension - How do I set the badge number on specific tab only?

如何只在特定标签上设置徽章编号?到目前为止,我有一个代码可以在所有选项卡上设置徽章编号。我已经阅读了很多,但似乎没有太多关于此的信息,所以也许我会找到一个解决方案这个在这里。

我想要像 Adblock Plus 这样的东西,它可以为特定的标签设置徽章编号。这在 Chrome 等中非常容易,但在 Safari 中似乎并非如此。

有谁知道像 Adblock plus 这样的扩展程序如何在特定选项卡上显示徽章编号?

到目前为止我只有这段代码,但如前所述,它在所有选项卡上设置了徽章,这不是我想要的结果。

safari.extension.toolbarItems[0].badge = 2;

编辑:

我一直在看Adblock plus 的源代码,以及其他一些具有此功能的扩展。而且它似乎正在使用一些原型。

Adblock 加上背景片段:

BrowserAction.prototype = {
_set: function(name, value)
{
  var toolbarItem = getToolbarItemForWindow(this._page._tab.browserWindow);
  if (!toolbarItem)
  {
    return;
  }
  var property = toolbarItemProperties[name];
  if (!property)
  {
    property = toolbarItemProperties[name] = {
      pages: new ext.PageMap(),
      global: toolbarItem[name]
    };
  }
  property.pages.set(this._page, value);
  if (isPageActive(this._page))
  {
    toolbarItem[name] = value;
  }
},
setIcon: function(path)
{
  this._set("image", safari.extension.baseURI + path.replace("$size", "16"));
},
setBadge: function(badge)
{
  if (!badge)
  {
    this._set("badge", 0);
  }
  else if ("number" in badge)
  {
    this._set("badge", badge.number);
  }
}
};

内容脚本(adblockplus.js)

FilterNotifier.on("filter.hitCount", function(filter, newValue, oldValue, page)
{
if (!(filter instanceof BlockingFilter) || !page)
{
  return;
}
Prefs.blocked_total++;
var blocked = blockedPerPage.get(page) || 0;
blockedPerPage.set(page, ++blocked);
if (Prefs.show_statsinicon)
{
  page.browserAction.setBadge(
  {
    color: badgeColor,
    number: blocked
  });
}
});

Adblock plus 似乎就是这样做的,但到目前为止我还没有能够复制它。虽然还在努力..

好的,所以我终于找到了解决方案,我想我会分享我所做的,以防其他人遇到同样的情况。

今天早上我想到了将数据存储在数组中的想法,当用户访问我想显示徽章编号的网站之一时(不存储用户访问的所有网站),只有当它匹配我想要定位的网站之一。我将以下数据存储在数组中:根域 (example.com) 和 badgeNumber.

为此,您需要将要定位的网站的根域组成一个数组,然后只有在匹配时才执行以下操作,否则数组会很快填满,我们不不想里面有太多数据。

在全局页面中,首先创建一个空数组来存储数据

var badgeUpdateArray = [];

然后您还需要在全局页面中设置消息处理。

safari.application.addEventListener('message', handleMessage, false);

function handleMessage(event) {
if(event.name === "setBadgeText"){

    var id = badgeUpdateArray.length + 1;
    var isFound = 0;
    var found = badgeUpdateArray.some(function (el) {
        if(el.identifier === event.message.identifier){
            // Was found
            isFound = 1;
        }
    });
    if (isFound == 0) {
        // Not found, add to the array
        badgeUpdateArray.push({identifier:event.message.identifier,badgeNumber:event.message.badgeNumber});
    }

    // Set the badge number
    safari.extension.toolbarItems[0].badge = event.message.badgeNumber;
}
}

现在我们需要将消息从内容脚本发送到全局页面。您需要获取根域 (example.com),我不会在这里深入讨论,因为这很容易。您还需要 badgeNumber 值,这可以从任何地方收集(GET 请求,或其他地方..)

请记住,仅当网站与您的目标域匹配时才执行此代码。

var message = {
        identifier: domain,
        badgeNumber: rows.length
    }
    safari.self.tab.dispatchMessage("setBadgeText", message);

这将发送消息,并将数据存储在数组中,它还会设置徽章编号。

现在,要使其在不同的选项卡上运行,您需要在全局页面上为 "activate" 创建一个事件处理程序,只要选项卡处于活动状态,这就会 运行。

safari.application.addEventListener("activate", updateBadge, true);

function updateBadge(){

var cDomain = safari.application.activeBrowserWindow.activeTab.url;
cDomain = cDomain.replace("www3.","");
cDomain = cDomain.replace("www2.","");
cDomain = cDomain.replace("www1.","");
cDomain = cDomain.replace("www.","");
cDomain = new URL(cDomain);
cDomain = cDomain.hostname;

var id = badgeUpdateArray.length + 1;
var isFound = 0;
var badgeNumber = 0;
var found = badgeUpdateArray.some(function (el) {
    badgeNumber = el.badgeNumber;
    if(el.identifier === cDomain){
        // Was found, set the badge number
        isFound = 1;
        safari.extension.toolbarItems[0].badge = el.badgeNumber;
    }
});
if (isFound == 0) {
    // Was not found
    safari.extension.toolbarItems[0].badge = 0;
}

}

希望我已经把所有的东西都放在这里了,至少还有一些有用的东西,尽管我不得不说我更喜欢一种更简单的存储方式..就像 Chrome 等那样,用选项卡 API.