1

我正在编写一个 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
}
4

1 回答 1

2

当显示上下文菜单时,您可以通过执行以下操作找出触发弹出窗口的元素:

e.target.ownerDocument.popupNode

这可能很有用,但实际上您只需要ownerDocument.defaultView

我认为甚至有一个e.view属性可以保存浏览器窗口。

例如:

function contextMenuShowing(e) {
    console.log('context menu showing', 'popupNode:', e.target.ownerDocument.popupNode);
    var currentWindow = e.target.ownerDocument.defaultView; // can try var currentWindow = e.view;
    if (currentWindow.gBrowser) {
          var tabURL  = gBrowser.selectedBrowser.currentURI;
    }
}

cToolbarContextMenu.addEventListener('popupshowing', contextMenuShowing, false);

另一种方法是因为在右键单击时,这显然意味着窗口已聚焦。所以你可以这样做:

const { getMostRecentBrowserWindow } = require('sdk/window/utils');

cToolbarContextMenu.addEventListener('popupshowing', function() {
    var currentWindow = getMostRecentBrowserWindow();
    if (currentWindow.gBrowser) {
         var tabURL = currentWindow.gBrowser.selectedBrowser.currentURI.spec;
    }
}, false);
于 2016-05-09T19:24:10.377 回答