何时加载浏览器框架脚本 (e10s)?

When do I load a browser frame script (e10s)?

我正在尝试移植我的 Firefox 扩展之一以支持电解 (e10s)。我的扩展程序获取一些页面数据并通过用户可以单击的上下文菜单项将其放在剪贴板上。基于 message manager documentation,有 3 种类型的消息管理器可用:

  1. 全球
  2. Window
  3. 浏览器

由于我的附加组件是特定于上下文的,所以最后一个似乎是我想要使用的。问题是我不完全知道何时加载框架脚本。我的上下文菜单项的操作处理代码的简化版本如下所示:

onContext: function() {
  let browserMM = gBrowser.selectedBrowser.messageManager;
  browserMM.loadFrameScript("chrome://myaddon/content/frame-script.js", true);
  browserMM.sendAsyncMessage("myaddon@myaddon.com:get-page-info", json);
}

在此处加载框架脚本对我来说似乎是最好的主意,因为 (a) 不能保证在每个页面上都使用框架脚本,并且 (b) 我认为框架脚本每次加载一次且仅加载一次<browser>。第二种理论似乎不正确;每次我调用 loadFrameScript 时,都会加载一个新副本。甚至加载保护逻辑(即仅创建框架脚本函数,如果它们尚不存在)似乎也无法解决问题。

所以,我的问题是每次访问上下文菜单项时,都会加载框架脚本的新副本。由于我的框架脚本添加了一个消息侦听器,因此我在上下文菜单项的后续调用中收到重复的消息。

我应该什么时候加载浏览器框架脚本?在加载项初始化时加载一次似乎效果不佳,因为它仅在第一个 <browser> 上加载(我希望此代码在任何后续 <browser> 请求时执行)。但是按需加载它似乎重复了一些东西。

这里还有我遗漏的其他策略吗?

Even load-protection logic (i.e. only creating the frame script functions if they don't already exist)

框架脚本有点棘手,每个选项卡的脚本共享一个全局 object 但有一个单独的范围,类似于在它们自己的功能块中进行评估。因此,如果您将它多次添加到一个选项卡中,那么每次都会在一个单独的范围内进行评估。

相反,您可能想要跟踪浏览器 object,这些浏览器已经使用 WeakMap 附加了您的框架脚本。虽然我认为还有一些属性可以枚举加载的框架脚本。

Loading it once on add-on initialization doesn't seem to work well

如果需要,请使用全局消息管理器并附加延迟帧脚本,该脚本将附加到所有当前和未来的选项卡。当然,这比将它附加到真正需要它的选项卡会消耗更多的内存。

browserMM.loadFrameScript("chrome://myaddon/content/frame-script.js", true);

如果你在特定的浏览器上 运行 延迟标志,你真的不需要将它设置为真,这只对广播消息管理器有意义,它可能会在 children未来。