1

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

chrome 扩展已经在 github 上可用。我使用类似于 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中,我无法弄清楚如何做到这一点。我将通过s 并通过pageMod调用. 这看起来很简单,但是如果该内容脚本需要加载更多代码,我将不知道该怎么做。tab.attachtabs

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

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

定义附加 API的用法traits似乎关闭了对对象的访问,因此我无法进入 aWorker以获取对我的内容脚本正在其中执行的沙箱的引用。此时,我似乎会需要在我的附加组件中包含几乎完整的 sdk 副本,以便在WorkerSandbox.

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

4

1 回答 1

1

内容脚本在初始化后不会公开公共 API 以将更多脚本附加到内容脚本沙箱。您可能应该提交一个增强错误并说明您的用例,如果还没有提交(先搜索),和/或自己提出一些补丁

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

对于page-mods没有 DOM 的情况,您有几个选择,但没有一个是真正令人满意的。正如您自己已经发现的那样,使用特征会禁止您访问“私有”属性/方法。

  • fork page-mod//tab提供content-worker你需要的功能。这将需要创建您自己的模块副本并公开必要的 API 以将脚本注入现有工作人员。

    这是一个陡峭的学习曲线(但鉴于您已经弄清楚了诸如特征之类的细节,应该对您可行),但更重要的是难以维护,因为您需要确保跟上上游的步伐。AMO 编辑不会因此而非常喜欢你 :p

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

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

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

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

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

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

于 2013-10-21T08:30:55.247 回答