我正在尝试增强现有的 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()
,然后addMessageListener()
我的框架/子脚本中的处理程序接收它,并执行它需要做的事情。
我想从 切换nsIContentPolicy
到 ,http-on-modify-request
因为它提供了更多信息,以便更早地做出更好的决定(阻止并处理此负载?)。在那个观察者里面我可以做:
var browser = httpChannel
.notificationCallbacks.getInterface(Ci.nsILoadContext)
.topFrameElement;
这给了我一个对象,该对象具有.messageManager
某种消息管理器,并且具有.sendAsyncMessage()
方法。但是当我使用它时.sendAsyncMessage()
,消息消失了,孩子永远不会观察到。
上下文:https ://github.com/greasemonkey/greasemonkey/issues/2280