我在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窗口关联的变量,以便我不必自己清理内存?
答案 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');