3

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

  1. 全球的
  2. 窗户
  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>)。但是按需加载它似乎重复了一些事情。

我在这里还缺少其他策略吗?

4

1 回答 1

4

甚至负载保护逻辑(即仅在框架脚本函数不存在时创建它们)

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

相反,您可能想要跟踪已经将框架脚本附加到WeakMap的浏览器对象。虽然我认为也有一些属性可以枚举加载的帧脚本。

在加载项初始化时加载一次似乎效果不佳

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

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

如果您在特定浏览器上运行延迟标志,您实际上并不需要将其设置为 true,这只对广播消息管理器有意义,这可能会在未来获得更多的孩子。

于 2015-01-24T21:46:18.170 回答