我正在尝试增强现有的Firefox扩展,该扩展依赖于nsIContentPolicy
来检测并中止某些网络加载(为了阻止生成的UI操作,即标签导航)。然后处理内部加载该资源。在极少数情况下,只有在处理完负载之后,我们才能完全中断负载,因此我们将其标记为忽略并重新启动它。
在e10s / multi-process下,这意味着父级(内容策略正在运行的位置)必须向子级发送消息(处理内容的UI)以重新启动加载。今天,这完成了:
function findMessageManager(aContext) {
// With e10s off, context is a <browser> with a direct reference to
// the docshell loaded therein.
var docShell = aContext && aContext.docShell;
if (!docShell) {
// But with e10s on, context is a content window and we have to work hard
// to find the docshell, from which we can find the message manager.
docShell = aContext
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem).rootTreeItem;
}
try {
return docShell
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIContentFrameMessageManager);
} catch (e) {
return null;
}
};
哪个是疯狂的复杂,因为e10s是疯狂的复杂。但它有效;它在父级中生成一些对象,我可以在其上调用.sendAsyncMessage()
,然后我的frame / child脚本中的addMessageListener()
处理程序接收它,并完成它需要做的事情。
我希望从nsIContentPolicy
切换到http-on-modify-request
,因为它提供了更多信息,可以更早地做出更好的决定(阻止和处理此负载?)。在那个观察者里面我能做到:
var browser = httpChannel
.notificationCallbacks.getInterface(Ci.nsILoadContext)
.topFrameElement;
这给了我一个对象,其中.messageManager
是某种的消息管理器,并且有一个.sendAsyncMessage()
方法。但是,当我使用.sendAsyncMessage()
时,消息消失,孩子永远不会被观察到。
答案 0 :(得分:2)
这应该原则上有效,尽管docshell树遍历可能在e10s和非e10s中做不同的事情,所以你必须要小心。在e10s rootTreeItem
- &gt; nsIContentFrameMessageManager
应该为您提供相当于框架脚本的MM,而topFrameElement.frameLoader.messageManager
应该为您提供<browser>
的MM,这几乎是与其对应的父级对象。
潜在的混淆来源:
答案 1 :(得分:-1)
这是我用来查找内容消息管理器的功能:
function contentMMFromContentWindow_Method2(aContentWindow) {
if (!gCFMM) {
gCFMM = aContentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDocShell)
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIContentFrameMessageManager);
}
return gCFMM;
}
因此,可能会获取触发该请求的内容窗口,然后使用此功能。