Firefox addon 从firefox附加内容脚本加载其他javascript代码
我正在写一些我想作为chrome扩展和firefox插件发布的东西 chrome的扩展是。我使用与requirejs使用的模块加载格式类似的模块加载格式将代码分解为几个模块;我这样做是为了将特定于chrome的部分与我希望在firefox插件中重复使用的部分分开 具体来说,我不仅拆分了后端工作,还拆分了内容脚本 在chrome中,当我的内容脚本需要加载另一个模块时,它会向后台页面发送一条消息,说“请加载此模块”;然后,背景页上的脚本执行以下操作:Firefox addon 从firefox附加内容脚本加载其他javascript代码,firefox-addon,Firefox Addon,我正在写一些我想作为chrome扩展和firefox插件发布的东西 chrome的扩展是。我使用与requirejs使用的模块加载格式类似的模块加载格式将代码分解为几个模块;我这样做是为了将特定于chrome的部分与我希望在firefox插件中重复使用的部分分开 具体来说,我不仅拆分了后端工作,还拆分了内容脚本 在chrome中,当我的内容脚本需要加载另一个模块时,它会向后台页面发送一条消息,说“请加载此模块”;然后,背景页上的脚本执行以下操作: function onLoadLibrary
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
方法。这不仅是安全问题的主要来源,而且可能是性能杀手,因为目前IIRCeval
ed代码不会使用JIT。当然,这会让我们AMO的编辑们畏缩,即使使用“正确”
- 不要使用延迟加载,从一开始就指定所有内容脚本。这就是附加组件通常所做的(我几乎倾向于说“总是”)。然而,这与您当前的设计相冲突,并且取决于您的附加组件,可能会对加载最终并不真正需要的内容造成严重的性能损失
- 您可以使用
require
机制将大多数脚本作为SDK模块,而不是内容脚本。当然,这并不总是可行的,例如,在处理通常会修改内容脚本中DOM的代码时,但可能适用于其他内容
- 用您自己的类似Greasemonkey的增强API替换
page mod
等。这意味着大量的工作,它容易出错,对安全性敏感,并且必须进行维护。所以,我认为这不是一个可行的解决方案
Components.utils.import
对您没有帮助。无论如何,它对内容脚本不可用。内容脚本不会公开公共API,以便在内容脚本沙盒初始化后将更多脚本附加到内容脚本沙盒。如果还没有一个已归档的用例(先搜索),您可能应该归档一个,并说明您的用例,甚至您自己
如果您的插件拥有一个DOM(widget
),那么只需附加另一个脚本标记即可
对于