firefox обнаруживает идентификатор вкладки в api" sdk/system/events"
Добрый день. у меня есть проблема с переносом расширения chromium в firefox. мне нужно определить все исходящие запросы и идентификаторы вкладок, к которым они принадлежат. для обнаружения запросов я используюsystem/events api, но не могу найти способ, как определить id вкладки из входящих событий. Как я понимаю, эти события-объекты xpcom, и я должен использовать QueryInterface, чтобы получить какой-то интерфейс, чтобы получить какой-то другой интерфейс, чтобы получить какой-то другой интерфейс ..... чтобы получить какой-то другой интерфейс чтобы получить id вкладки из него (как и в реализации COM В windows), но я не могу найти, какой интерфейс мне нужен, не могу найти документацию об этих событиях вообще...
Код, который я использую в chromium:
chrome.webRequest.onBeforeRequest.addListener(
function(info) {
if(info.tabId)
//do stuff here
}
Так вот чего я хочу добиться от firefox...
Код, который я сейчас пишу для firefox:
exports.main = function(options)
{
//stuf here ....
........
function listener(event)
{
var channel = event.subject.QueryInterface(Ci.nsIHttpChannel);
console.log(channel);
//TODO: get tab here somehow
}
events.on("http-on-opening-request", listener);
}
Я посмотрел на xpcom docs несколько дней, но все еще не хватает информации, чтобы реализовать эту простую вещь... так что если у кого-то есть успех с этим, пожалуйста помощь.
2 ответа:
Я только что нашел фрагмент кода для получения браузера, который запускает уведомление http-on-modify-request. Код там, кажется, сломан, но я использовал некоторые из них, чтобы создать эту функцию, чтобы получить вкладку из канала.
const getTabFromChannel = (aChannel) => { try { let notificationCallbacks = aChannel.notificationCallbacks || aChannel.loadGroup.notificationCallbacks; if (!notificationCallbacks) return null; let domWin = notificationCallbacks.getInterface(Ci.nsIDOMWindow); let chromeTab = tabsUtils.getTabForContentWindow(domWin); return getSdkTabFromChromeTab(chromeTab); } catch (e) { // some type errors happen here, not sure how to handle them console.log(e); return null; } }
Эта функция преобразует низкоуровневую вкладку в высокоуровневую. В зависимости от того, какой из них вам нужен, вы можете пропустить эту функцию, конечно. Опять же, в последнем SDK вы, вероятно, можете заменить его на
tabs.viewFor(chromeTab)
.const tabs = require("sdk/tabs"); const tabsUtils = require("sdk/tabs/utils"); const getSdkTabFromChromeTab = (chromeTab) => { const tabId = tabsUtils.getTabId(chromeTab); for each (let sdkTab in tabs){ if (sdkTab.id === tabId) { return sdkTab; } } return null; };
Похоже, возникла проблема. что прослушиватель терпит неудачу при переключении между окнами при использовании
system/events
. Вместо этого используйтеServices.obs.addObserver
:Я могу только надеяться, что он работает для всех запросов, которые вам нужно обнаружить. В документации уже упоминаются некоторые случаи, когда это не сработает:const httpRequestObserver = { observe: function (subject, topic, data) { var channel = subject.QueryInterface(Ci.nsIHttpChannel); console.log("channel"); var tab = getTabFromChannel(channel); if(tab) { console.log("request by tab", tab.id); } } } exports.main = function() { Cu.import('resource://gre/modules/Services.jsm'); Services.obs.addObserver(httpRequestObserver, 'http-on-opening-request', false); }
Обратите внимание, что некоторые HTTP-запросы не связаны с вкладкой; например, обновления RSS-каналов, запросы extension manager, запросы XHR от компонентов XPCOM и т. д.
Статья прослушивание событий на всех вкладках описывает, как настроить прослушиватели веб-прогресса для вкладок. С помощью этого прослушивателя вы можете получать запросы и перенаправления.
const tabsUtils = require("sdk/tabs/utils"); const listener = { QueryInterface: XPCOMUtils.generateQI(["nsIWebProgressListener", "nsISupportsWeakReference"]), onLocationChange: (browser, progress, request, uri) => { let tab = tabsUtils.getTabForContentWindow(progress.DOMWindow); // ... }, onStateChange: (browser, progress, request, state) => { let tab = tabsUtils.getTabForContentWindow(progress.DOMWindow); // ... } // ... }; getChromeWindow(sdkWindow).getBrowser().addTabsProgressListener(listener);
В какой - то момент вам может понадобиться конвертировать между низко-и высокоуровневыми вкладками или окнами chrome/dom/sdk, которые реализованы очень плохо и сбивают с толку. Окно sdk в этом случае-это окно, которое вы получаете с
windows.browserWindows
, окно chrome имеет ссылку наgBrowser
. Если вы используете последнюю версию sdk, возможно, это поможет: https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_API/tabs#Converting_to_XUL_tabs и https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/windows#Converting_to_DOM_windows. я использовал эту функцию, чтобы получить окно chrome из окна sdk: https://bugzilla.mozilla.org/show_bug.cgi?id=695143#c15const { BrowserWindow } = require('sdk/windows'); const { windows } = require('sdk/window/utils'); function getChromeWindow(sdkWindow) { // to include private window use the as second argument // { includePrivate: true } for (let window of windows('navigator:browser')) if (BrowserWindow({window: window}) === sdkWindow) return window; return null; }