我正在编写一个 Firefox 扩展,它将菜单项添加到浏览器的选项卡上下文菜单中,以将选项卡的 URL 发送到 Web 服务。我的菜单项有一个command
事件侦听器,它在选择菜单项时触发并且工作正常。
我遇到的麻烦是根据我收到的事件确定右键单击了哪个选项卡。从菜单项本身(这是事件的目标)到选项卡似乎没有一条简单的路径command
,因为选项卡上下文菜单不是 XUL-land 中选项卡的子项。当然,我不能只获取当前选项卡,因为用户可能右键单击了非活动选项卡。
我目前使用的解决方案是contextmenu
在每个选项卡上放置一个事件处理程序,将选项卡的 URL 存储在全局变量中,并在我的command
事件处理程序中使用这个全局变量。这很好用,而且我对全局变量有点放心,因为在物理上不可能同时调出多个上下文菜单。
但是有更好的方法吗?我想command
用一个包含 URL 的闭包来更新我的事件处理程序,但这样做的缺点是需要在添加新的事件处理程序之前删除旧的事件处理程序,这只会使事情变得更加复杂。
我当前的代码看起来像这样:
var tabs = require("sdk/tabs");
var xultabs = require("sdk/tabs/utils");
var viewFor = require("sdk/view/core").viewFor;
var itemid = "my-extension-name";
var xulns = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
// global variable to hold tab URL and function to set it on right-click of tab
taburl = "";
function getTabURL(e) { taburl = xultabs.getTabURL(e.target); }
tabs.on('ready', function(tab) {
// set up event listener to get tab URL when tab is right-clicked
let vtab = viewFor(tab);
vtab.addEventListener("contextmenu", getTabURL);
// add our context menu item if it's not already there
let doc = viewFor(tab.window).document;
if (!doc.getElementById(itemid)) {
let menu = doc.getElementById("tabContextMenu");
let item = doc.createElementNS(xulns, "menuseparator");
menu.appendChild(item);
item = doc.createElementNS(xulns, "menuitem");
item.setAttribute("label", "My Menu Item");
item.setAttribute("id", itemid);
item.addEventListener("command", function() { pushURL(taburl) });
menu.appendChild(item);
}
});
function pushURL(url) {
// pushes the URL to the service
}