ブラウザーのタブ コンテキスト メニューにメニュー項目を追加して、タブの URL を Web サービスに送信する Firefox 拡張機能を作成しています。command
メニュー項目が選択されたときに起動し、正常に動作するメニュー項目のイベント リスナーがあります。
私が抱えている問題は、受け取ったイベントに基づいて右クリックされたタブを特定することです。command
タブ コンテキスト メニューは XUL ランドのタブの子ではないため、メニュー項目自体 (イベントのターゲット) からタブへの簡単なパスはないようです。もちろん、ユーザーが非アクティブなタブを右クリックした可能性があるため、現在のタブを取得することはできません。
私が現在使用している解決策はcontextmenu
、タブの URL をグローバル変数に格納するイベント ハンドラーを各タブに配置し、このグローバル変数をcommand
イベント ハンドラーで使用することです。これは問題なく動作し、複数のコンテキスト メニューを同時に表示することは物理的に不可能であるため、グローバル変数についてはある程度満足しています。
しかし、より良い方法はありますか?URL を保持するクロージャーでイベント ハンドラーを更新することを考えcommand
ましたが、新しいイベント ハンドラーを追加する前に古いイベント ハンドラーを削除する必要があるという欠点があり、事態がさらに複雑になります。
私の現在のコードは次のようになります。
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
}