Firefox扩展:通过向负责加载的子框架发送消息来响应父框架中观察到的http on modify请求

Firefox扩展:通过向负责加载的子框架发送消息来响应父框架中观察到的http on modify请求,firefox,firefox-addon,e10s,Firefox,Firefox Addon,E10s,我正在尝试增强一个现有的Firefox扩展,该扩展依赖于nsIContentPolicy来检测和中止某些网络负载(以阻止产生的UI操作,即选项卡导航)。然后在内部处理该资源的加载。在极少数情况下,只有在处理负载之后,我们才发现根本不应该中断负载,因此我们将其标记为忽略并重新启动 在e10s/multi-process下,这意味着父级(运行内容策略的地方)必须向子级(处理内容的UI)发送消息以重新启动加载。今天,这是由以下人员完成的: function findMessageManager(aCo

我正在尝试增强一个现有的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;
  }
};
这给了我一个对象,它有一个
.messageManager
,这是一种消息管理器,它有一个
.sendAsyncMessage()
方法。但是,当我使用该
.sendAsyncMessage()
时,该消息将消失,孩子永远不会看到



上下文:

虽然docshell树遍历在E10和非E10中可能会做不同的事情,但原则上这应该是可行的,因此您必须小心。在e10s中,
rootTreeItem
->
nsIContentFrameMessageManager
应该为您提供与框架脚本相当的MM,而
topFrameElement.frameLoader.messageManager
应该为您提供
的MM,它几乎是它的父端对应项

潜在的混淆源:

  • e10s打开与关闭
  • 过程MM与框架MM层次结构
  • 在错误的帧中侦听消息(在所有帧中注册可能有助于调试)

这是我用来查找内容消息管理器的函数:

function contentMMFromContentWindow_Method2(aContentWindow) {
    if (!gCFMM) {
        gCFMM = aContentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                              .getInterface(Ci.nsIDocShell)
                              .QueryInterface(Ci.nsIInterfaceRequestor)
                              .getInterface(Ci.nsIContentFrameMessageManager);
    }
    return gCFMM;

}

因此,也许可以获取触发该请求的内容窗口,然后使用该函数。

我已经获得了
topframelement.frameLoader.messageManager
。我已将消息侦听器添加到全局、父级和浏览器框架中。当我
.sendAsyncMessage()
时,没有人听到它。是否还有另一个框架可供监听?我不确定这是否措词不当,但将侦听器附加到全局/父/浏览器MM将无法从父/母向您发送消息。他们将只接受儿童一方。另外一个可以吞下消息的方法是标签卸载和标签交换。只是整个e10s型号不适合我的头脑。多年来我所知道的所有事情,现在有些只在父母身上起作用,有些只在孩子身上起作用,而且有很多种消息管理器和消息传递的方向。事实上,在正确的位置(框架)进行监听可以实现这一点。特别是在E10打开的情况下,即使我可以强制使用E10,它也不会存在(它将在子进程中)。您无法从观察者处获取相关的contentWindow吗?我以前做过
function contentMMFromContentWindow_Method2(aContentWindow) {
    if (!gCFMM) {
        gCFMM = aContentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                              .getInterface(Ci.nsIDocShell)
                              .QueryInterface(Ci.nsIInterfaceRequestor)
                              .getInterface(Ci.nsIContentFrameMessageManager);
    }
    return gCFMM;

}