为特定 window 设置浏览器操作上下文菜单标签

Set browser action contextmenu label for specific window

我有一个添加浏览器按钮的 Chrome 扩展。浏览器按钮有 1 个自定义上下文菜单项,“禁用 DOMAIN”或“重新启用 DOMAIN”。这是 2 个变量,具体取决于活动选项卡:enabled/disabled 及其域名。

我使用 chrome.tabs.onUpdated 来跟踪新标签,并使用 chrome.tabs.onActivated 来跟踪标签切换。无论发生哪种情况,我都会根据这两个变量更新标签。例如。 “为 twitter.com 重新启用”或“为 google.com 禁用”。

当您有超过 1 个时会出现问题 window:

  1. 在 window 中打开新标签页 1. 标签现在是“禁用 foo.com
  2. 在新 window 的那个选项卡中打开 link (2)。 Window 2 的标签现在是“禁用 bar.com”。
    • 但是 window 1 的标签也变成了那个!
  3. 切换回 window 1(仍在 foo.com)(这不会触发任何选项卡事件)。标签是“禁用bar.com”<错误

另一种情况是打开devtools,它会将所有windows.

中所有标签中的所有DOMAIN更改为devtools

如何区分 windows? 每个 window 有 1 个浏览器操作,但只有 1 个上下文菜单标签要更改(这会更改它们全部)。没有办法知道我正在单击的 window 是 active/which window 的浏览器操作。没有切换标签事件windows,所以我不能更改标签。

我正在检查 AdBlock 的代码,但它有相同的错误:如果您打开一个新的 window,其中 AdBlock 被禁用,它会删除所有 windows 上的上下文菜单项并且不会放置直到您切换标签页 (onActivated)。

Tabs 事件代码,如果有帮助:

chrome.tabs.onUpdated.addListener(function(tabId, info, tab) {
    console.log('onUpdated', tabId, info, tab);
    if ( info.status && tab.active ) {
        updateLabelStatus(tab);
    }
});

chrome.tabs.onActivated.addListener(function(info) {
    console.log('onActivated', info);
    chrome.tabs.get(info.tabId, function(tab) {
        updateLabelStatus(tab);
    });
});

function updateLabelStatus(tab) {
    var host = rweb.host(tab.url);

    chrome.storage.local.get('disabled', function(items) {
        var disabled = items.disabled || {};
        updateLabel(host in disabled, host, tab.id);
    });
}

function updateLabel(disabled, host, tabId) {
    // Update label
    var newLabel = labels[ Number(disabled) ].replace('DOMAIN', host);

    // >> THIS IS WHERE I MIGHT WANT TO SPECIFY A WINDOW <<
    chrome.contextMenus.update(browserActionMenuItemId, {"title": newLabel});
}

相关的 Chromium 错误:https://code.google.com/p/chromium/issues/detail?id=469417

哦,当然有 API chrome.windows。傻

这位宝贝修好了:

chrome.windows.onFocusChanged.addListener(function(windowId) {
    chrome.windows.get(windowId, {"populate": true}, function(window) {
        var e = chrome.runtime.lastError; // Stut up, Chrome
        if ( !window ) return;
        console.log('onFocusChanged', windowId, window);

        for ( var i=window.tabs.length-1; i>=0; i-- ) {
            var tab = window.tabs[i];
            if ( tab.active ) {
                updateLabelStatus(tab);
                break;
            }
        };
    });
});

也很重要:在 updateLabel() 中我做了一些 chrome.browserAction.setBadgeBackgroundColor 没有指定 tabId,但是没有它,它会改变所有 windows 打开的 bgcolor选项卡。

好吧,调试 3 个小时一点都不有趣。 (其中 2.5 我不知道 chrome.windows,该死!)

一个更简单的解决方案是在调用 browserAction 时传递一个 tabIdsetBadgeTextsetBadgeBackgroundColorsetIcon 等),如建议的那样由 documentation.

example