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

时间:2011-06-26 15:25:44

标签: javascript firefox-addon mozilla

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

捕获代码非常有效,我正在尝试计算重试总次数store this in the tab using Session Store。不幸的是,现在我正在获取对DOM窗口的引用(通过interfaceRequestor.getInterface(Components.interfaces.nsIDOMWindow)),但我需要一个对nsIDOMNode // 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"); } }, 的{​​{1}}的引用。

到目前为止我已经完成了这个例子的实际重试:

setTabValue

当然{{1}}参数无效,这当然失败了。如何获取与DOM窗口关联的选项卡?

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

2 个答案:

答案 0 :(得分:6)

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应该是一个足够独特的名称,以避免与可能还想使用expando属性的其他扩展冲突。

答案 1 :(得分:4)

引用nsIDOMNode aTab的nsISessionStore API要求您获取存储数据的选项卡节点。如果您使用的是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');