在Firefox Add-on SDK中收听pin / unpin标签事件

时间:2016-10-16 10:18:02

标签: javascript firefox firefox-addon firefox-addon-sdk

我正在编写Firefox Add-on SDK扩展。我希望在固定或取消固定任何标签时收到通知。不幸的是,sdk/tabs模块并未提供此类事件。是否有一些低级API提供用于固定/取消固定标签的事件?

1 个答案:

答案 0 :(得分:2)

没有Firefox附加SDK Low-Level API,它提供了一种方法来监听被固定或取消固定的标签。 "附加SDK低级API"是一个非常具体的API列表,仅在Add-on SDK中定义。您没有将请求仅限于Add-on SDK特定API,而是限制在Add-on SDK中运行的所有Firefox API,除了WebExtensions之外,它几乎都是Firefox API。

您可以通过在您感兴趣的<tabs>的XUL window元素上收听TabPinnedTabUnpinned事件来获取此类事件。您可以使用<tabs>获取XUL getTabContainer(window)元素。如果要在所有浏览器窗口中获取所有此类事件,则需要将事件添加到每个浏览器窗口的tabContainer,即XUL <tabs>元素。您可以看到tab specific events in the MDN Event Reference page的列表。

以下是基于Firefox Add-on SDK的扩展程序,它将在所有窗口中监听TabPinnedTabUnpinned个事件。

index.js

var sdkWinUtils = require('sdk/window/utils');
var sdkTabsUtils = require('sdk/tabs/utils');
var sdkWindows = require("sdk/windows");

//For testing, open the Browser Console
sdkWinUtils.getMostRecentBrowserWindow()
           .document.getElementById('menu_browserConsole').doCommand();

function tabPinned(event) {
  let tabId = sdkTabsUtils.getTabId(event.target);
  console.log('Pinned Tab ID:',tabId);
}

function tabUnpinned(event) {
  let tabId = sdkTabsUtils.getTabId(event.target);
  console.log('Unpinned Tab ID:',tabId);
}

function addTabPinUnpinListenersInWindow(win){
    //win can be either a browserWindow provided by the 
    //    sdkWindows.browserWindows.on('open',);
    //  event, or nsIDOMWindow instances provided in the array from
    //    sdkWinUtils.windows()
    //  We can distinguish between the two by using 
    //    sdkWinUtils.isBrowser(win)
    let container;
    if(sdkWinUtils.isBrowser(win)){
        container = sdkTabsUtils.getTabContainer(win);
    }else{
        let { viewFor } = require("sdk/view/core");
        container = sdkTabsUtils.getTabContainer(viewFor(win));
    }
    container.addEventListener("TabPinned", tabPinned, false);
    container.addEventListener("TabUnpinned", tabUnpinned, false);
}

function removeTabPinUnpinListenersInWindow(win){
    let container = sdkTabsUtils.getTabContainer(win);
    container.removeEventListener("TabPinned", tabPinned, false);
    container.removeEventListener("TabUnpinned", tabUnpinned, false);
}

function forEachOpenWindow(func){
    let allWindows = sdkWinUtils.windows('navigator:browser', {includePrivate:true});
    for(let win of allWindows){
        func(win);
    }
}

function forEachOpenWindowAndAllNewWindows(func){
    forEachOpenWindow(func);
    //Listen for new windows opening and add tab pin/unpin listeners:
    sdkWindows.browserWindows.on('open',func);
}

function removeAllListeners(){
    //To be called upon shutdown for add-on upgrade/disable/removal
    //Remove new window open listener
    sdkWindows.browserWindows.off('open',addTabPinUnpinListenersInWindow);
    //Remove tab pin/unpin listeners
    forEachOpenWindow(removeTabPinUnpinListenersInWindow);
}

//Add listeners to all open windows and all which open
forEachOpenWindowAndAllNewWindows(addTabPinUnpinListenersInWindow);

//Clean up if Firefox is not shutting down (e.g. the add-on is disabled by user).
exports.onUnload = reason => {
    if(reason !== 'shutdown'){
        //The add-on is being unloaded and it is not because Firefox is sutting down.
        removeAllListeners();
    }
};

的package.json

{
    "title": "Listen to tab pin/unpin",
    "name": "listen-to-tab-pin-unpin",
    "version": "0.0.1",
    "description": "Output to console when a tab is pinned or unpinned.",
    "main": "index.js",
    "author": "Makyen",
    "permissions": {"private-browsing": true},
    "engines": {
        "firefox": ">=38.0a1",
        "fennec": ">=38.0a1"
    },
    "license": "MIT",
    "keywords": [
        "jetpack"
    ]
}