Firefox addon 从firefox附加内容脚本加载其他javascript代码

Firefox addon 从firefox附加内容脚本加载其他javascript代码,firefox-addon,Firefox Addon,我正在写一些我想作为chrome扩展和firefox插件发布的东西 chrome的扩展是。我使用与requirejs使用的模块加载格式类似的模块加载格式将代码分解为几个模块;我这样做是为了将特定于chrome的部分与我希望在firefox插件中重复使用的部分分开 具体来说,我不仅拆分了后端工作,还拆分了内容脚本 在chrome中,当我的内容脚本需要加载另一个模块时,它会向后台页面发送一条消息,说“请加载此模块”;然后,背景页上的脚本执行以下操作: function onLoadLibrary

我正在写一些我想作为chrome扩展和firefox插件发布的东西

chrome的扩展是。我使用与requirejs使用的模块加载格式类似的模块加载格式将代码分解为几个模块;我这样做是为了将特定于chrome的部分与我希望在firefox插件中重复使用的部分分开

具体来说,我不仅拆分了后端工作,还拆分了内容脚本

在chrome中,当我的内容脚本需要加载另一个模块时,它会向后台页面发送一条消息,说“请加载此模块”;然后,背景页上的脚本执行以下操作:

  function onLoadLibrary(request, sender, sendResponse) { 
    var allFrames = request.allFrames || false;
    chrome.tabs.executeScript(
      sender.tab.id, {file: request.library.toLowerCase()  + '.js',
                      allFrames: allFrames},
      function () {
        sendResponse({});
      });
    return true;
  }
也就是说,我能够将额外的javascript加载到与请求该代码的内容脚本相同的沙箱中。这是使模块依赖项正常工作所必需的

在firefox中,我不知道如何做到这一点。我将通过
pageMod
s和调用
tab来附加我的初始内容脚本。从
tabs
的“就绪”事件附加
。这看起来很简单,但是如果内容脚本需要加载更多的代码,我就不知道怎么做了

似乎没有办法从
main.js
文件访问我的内容脚本正在运行的沙箱,以便向其中注入更多代码。即使我以某种方式保留了对相关
选项卡
实例的引用(这在任何情况下都只允许我注入顶部框架),似乎对
选项卡.attach的每次新调用都会将注入的代码放入一个新的沙盒中。传递给我的就绪事件句柄的对象
选项卡
不是我可以传递给
require(“tabs/util”)的真正的XUL选项卡;如果是的话,那么我想我可以完成足够多的sdk代码来创建我自己的沙盒,尽管我担心会留下意外的内存泄漏

我考虑过通过“eval this code”消息将代码传递回内容脚本,但出于安全考虑,我真的不想在扩展中使用
eval
;我还担心使用
eval
会使我的firefox插件很难获得批准。(另外,当我的加载项在具有内容安全策略的站点上运行时,它将如何交互?)

使用
traits
来定义附加API似乎关闭了对对象的访问,因此我无法进入
工作者的内部
以获取对我的内容脚本正在执行的沙箱的引用。此时,我似乎需要在我的插件中包含sdk的几乎完整副本,以便在
WorkerSandbox
上公开一个方法


注意:我正在使用附加sdk(该项目以前称为JetPack)。如果有人能告诉我如何在附加SDK管理的内容脚本中使用,我愿意使用
组件.utils.import

内容脚本不会公开公共API,以便在初始化后将更多脚本附加到内容脚本沙盒。如果还没有一个已归档的用例(先搜索),您可能应该归档一个,并说明您的用例,甚至您自己

如果您的插件拥有一个DOM(
widget
),那么只需附加另一个脚本标记即可

对于像
pagemods
这样没有自己的DOM的东西,您只剩下几个选项,没有一个是真正令人满意的。正如您自己已经发现的,traits的使用禁止您访问“私有”属性/方法

  • Fork
    page mod
    /
    选项卡
    /
    内容工作者
    提供您需要的功能。这将需要创建您自己的模块副本,并公开必要的API,以便将脚本注入现有工作人员

    这是一个陡峭的学习曲线(但考虑到你已经了解了诸如特征等细节,这对你来说应该是可行的),但更重要的是很难保持,因为你需要确保跟上上游。AMO的编辑们也不会因此而喜欢你:p

    从好的方面来说,您可以尝试将您的内容提交到上游,为每个人解决这个问题,并成为许多使用附加SDK的作者的英雄

  • 您建议的
    eval
    方法。这不仅是安全问题的主要来源,而且可能是性能杀手,因为目前IIRC
    eval
    ed代码不会使用JIT。当然,这会让我们AMO的编辑们畏缩,即使使用“正确”

  • 不要使用延迟加载,从一开始就指定所有内容脚本。这就是附加组件通常所做的(我几乎倾向于说“总是”)。然而,这与您当前的设计相冲突,并且取决于您的附加组件,可能会对加载最终并不真正需要的内容造成严重的性能损失

  • 您可以使用
    require
    机制将大多数脚本作为SDK模块,而不是内容脚本。当然,这并不总是可行的,例如,在处理通常会修改内容脚本中DOM的代码时,但可能适用于其他内容

  • 用您自己的类似Greasemonkey的增强API替换
    page mod
    等。这意味着大量的工作,它容易出错,对安全性敏感,并且必须进行维护。所以,我认为这不是一个可行的解决方案


Components.utils.import
对您没有帮助。无论如何,它对内容脚本不可用。

内容脚本不会公开公共API,以便在内容脚本沙盒初始化后将更多脚本附加到内容脚本沙盒。如果还没有一个已归档的用例(先搜索),您可能应该归档一个,并说明您的用例,甚至您自己

如果您的插件拥有一个DOM(
widget
),那么只需附加另一个脚本标记即可

对于