1

ブラウザーのタブ コンテキスト メニューにメニュー項目を追加して、タブの 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
}
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 に答える