查找与DOM窗口关联的选项卡

Pau*_*sma 7 javascript mozilla firefox-addon

我在Firefox扩展程序TryAgain中添加了一些新功能,用于捕获HTTP错误代码(例如500)并在一段时间后自动重试加载页面.

捕获代码非常有效,我正在尝试计算重试总次数,并使用Session Store将其存储在选项卡中.不幸的是,现在我正在获取对DOM窗口的引用(通过interfaceRequestor.getInterface(Components.interfaces.nsIDOMWindow)),但是我需要一个对tab的引用,这是一个nsIDOMNode根据setTabValue()上的nsISessionStore文档.

我到目前为止(我已经剪断了这个例子中的实际重试):

// 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");
    }
},
Run Code Online (Sandbox Code Playgroud)

这当然会因setTabValue参数无效而失败.如何获取与DOM窗口关联的选项卡?

作为替代解决方案,我可以以某种方式存储与DOM窗口关联的变量,这样我自己就不必清理内存吗?

Wla*_*ant 6

domWindow是一个内容窗口,首先你需要获得包含它的chrome窗口.这是由相当丑陋的代码完成的:

var chromeWindow = window.QueryInterface(Ci.nsIInterfaceRequestor)
                         .getInterface(Ci.nsIWebNavigation)
                         .QueryInterface(Ci.nsIDocShellTreeItem)
                         .rootTreeItem
                         .QueryInterface(Ci.nsIInterfaceRequestor)
                         .getInterface(Ci.nsIDOMWindow);
Run Code Online (Sandbox Code Playgroud)

然后你想问<tabbrowser>关于标签的元素(注意你应该传入,domWindow.top因为domWindow可能不是顶部框架):

var browser = chromeWindow.gBrowser.getBrowserForDocument(domWindow.top.document);
Run Code Online (Sandbox Code Playgroud)

请注意,这是<browser>元素,而不是关联的元素<tab>(对于后者,您需要getBrowserIndexForDocument然后再看gBrowser.tabs[index]).但我认为您只想存储此选项卡的属性,而不是在会话中保持此属性?然后你可以使用expando属性:

if (!("_myExtensionErrorCount" in browser))
  browser._myExtensionErrorCount = 0;
browser._myExtensionErrorCount++;
Run Code Online (Sandbox Code Playgroud)

这里_myExtensionErrorCount应该是一个足够独特的名称,以避免与可能想要使用expando属性的其他扩展冲突.