Поиск вкладки, связанной с окном DOM - PullRequest
7 голосов
/ 26 июня 2011

Я добавляю некоторые новые функции в расширение Firefox, TryAgain , которое перехватывает коды ошибок HTTP (например, 500) и автоматически повторяет загрузку страницы через некоторый интервал.

Захват кодов работает превосходно, и я пытаюсь подсчитать общее количество повторов и сохранить это на вкладке, используя Session Store . К сожалению, сейчас я получаю ссылку на окно DOM (через interfaceRequestor.getInterface(Components.interfaces.nsIDOMWindow)), но мне нужна ссылка на вкладку, которая является nsIDOMNode согласно nsISessionStore docs для setTabValue () .

То, что у меня есть до сих пор (я попытался повторить попытку в этом примере):

// This function implements the nsIObserverService interface and observes
// the status of all HTTP channels
observe : function(aSubject, aTopic, aData) {
    var httpChannel = aSubject
            .QueryInterface(Components.interfaces.nsIHttpChannel);
    if (httpChannel.responseStatus == 500) {
        var domWindow;
        try {
            var notificationCallbacks;
            if (httpChannel.notificationCallbacks) {
                notificationCallbacks = httpChannel.notificationCallbacks;
            } else {
                notificationCallbacks = aSubject.loadGroup
                        .notificationCallbacks;
            }
            var interfaceRequestor = notificationCallbacks
                    .QueryInterface(Components.interfaces
                        .nsIInterfaceRequestor);
            domWindow = interfaceRequestor
                    .getInterface(Components.interfaces.nsIDOMWindow);
        } catch (e) {
            // No window associated with this channel
            return;
        }
        var ss = Components.classes["@mozilla.org/browser/sessionstore;1"]
                .getService(Components.interfaces.nsISessionStore);
        ss.setTabValue(domWindow, "foo", "bar");
    }
},

Это, конечно, не работает на setTabValue с недопустимым параметром. Как я могу получить вкладку, связанную с окном DOM?

Как альтернативное решение, могу ли я каким-либо образом хранить переменные, связанные с окном DOM, чтобы мне не приходилось очищать память самостоятельно?

Ответы [ 2 ]

6 голосов
/ 27 июня 2011

domWindow - это окно содержимого, сначала вам нужно получить окно chrome, содержащее его. Это сделано с помощью этого довольно уродливого кода:

var chromeWindow = window.QueryInterface(Ci.nsIInterfaceRequestor)
                         .getInterface(Ci.nsIWebNavigation)
                         .QueryInterface(Ci.nsIDocShellTreeItem)
                         .rootTreeItem
                         .QueryInterface(Ci.nsIInterfaceRequestor)
                         .getInterface(Ci.nsIDOMWindow);

Затем вы хотите спросить элемент <tabbrowser> о вкладке (обратите внимание, что вы должны передать domWindow.top, поскольку domWindow может не быть верхним фреймом):

var browser = chromeWindow.gBrowser.getBrowserForDocument(domWindow.top.document);

Обратите внимание, что это элемент <browser>, а не связанный <tab> (для последнего вам потребуется getBrowserIndexForDocument, а затем посмотрите на gBrowser.tabs[index]). Но я думаю, что вы просто хотите сохранить свойство для этой вкладки, чтобы это свойство не сохранялось между сеансами? Тогда вы можете использовать свойство expando:

if (!("_myExtensionErrorCount" in browser))
  browser._myExtensionErrorCount = 0;
browser._myExtensionErrorCount++;

Здесь _myExtensionErrorCount должно быть достаточно уникальным именем, чтобы избежать конфликтов с другими расширениями, которые также могут захотеть использовать свойства расширения.

4 голосов
/ 27 июня 2011

API-интерфейсы nsISessionStore, ссылающиеся на nsIDOMNode aTab, требуют, чтобы вы взялись за узел вкладки, хранящий данные.Если вы работаете в оверлее browser.xul и хотите выбрать текущую выбранную вкладку, это так же просто, как gBrowser.selectedTab.Если вы просто удерживаете ссылку на некоторый документ содержимого в окне Chrome оверлея, вот как вы найдете соответствующую вкладку:

function tabFromDoc(doc) {
    var no = gBrowser.getBrowserIndexForDocument(doc);
    return gBrowser.tabContainer.childNodes[no];
}

// example use:
Cc['@mozilla.org/browser/sessionstore;1']
    .getService(Ci.nsISessionStore)
    .setTabValue(tabFromDoc(myContentDoc), 'myKey', 'myValue');
...