你的问题实在是模糊的,所以我会根据一堆猜测来回答吧。您可能想要执行类似Add-on SDK内部的操作 - 将您的插件加载到sandboxes中,为它们提供一些API并根据需要调用它们的方法。另外,我想你想使用null principal来确保沙盒没有额外的权限。像这样的东西应该做的:
Components.utils.import("resource://gre/modules/Services.jsm");
var sandboxProto = {
rank: -1,
foo: function()
{
throw new Error("Please implement");
},
myAPIMethod: function()
{
return 5;
}
};
var sandboxPrincipal = Components.classes["@mozilla.org/nullprincipal;1"]
.getService(Components.interfaces.nsIPrincipal);
var plugins = [];
function loadPlugin(url)
{
try
{
var sandbox = Components.utils.Sandbox(sandboxPrincipal, {
sandboxName: url,
sandboxPrototype: sandboxProto
});
Services.scriptloader.loadSubScript(url, sandbox);
plugins.push(sandbox);
}
catch (e)
{
Components.utils.reportError(e);
}
}
function callPluginMethod(methodName)
{
var args = Array.prototype.slice.call(arguments, 1);
// Always resort plugins in case their rank changes
plugins.sort(function(a, b)
{
// Make sure that we work with numbers
var r1 = parseInt(a.rank, 10) || -1;
var r2 = parseInt(a.rank, 10) || -1;
return r2 - r1;
});
var results = [];
for (var i = 0; i < plugins.length; i++)
{
if (methodName in plugins[i])
{
try
{
results.push(plugins[i][methodName].apply(plugins[i], args));
}
catch (e)
{
Components.utils.reportError(e);
}
}
}
return results;
}
而且一个插件是这样的:
var rank = 1000;
function foo()
{
return 2 * myAPIMethod();
}
所以下面的代码,你应该表现出[10]
:
loadPlugin("chrome://.../content/plugin.js");
var results = callPluginMethod("foo");
alert(results.toSource());
至于你的扩展会怎样知道在哪里可以找到它的插件 - 这是一个完全不同的问题,很大程度上取决于需求(这个问题缺少的东西)。但请注意,下标加载器只能与本地URL一起工作 - 只有插件可以作为您的扩展的一部分或位于用户磁盘上。如果插件列表将是动态的,那么您可能需要在用户配置文件中为它们创建一个目录,并根据需要将它们下载到此目录中(您应该非常小心,因为不要为这些插件提供太多权限,安全问题)。
我想你想要你的插件被沙盒,而不是有全部的特权? –
@WladimirPalant在这个阶段,我并不在意沙盒,因为在初始阶段,我将是唯一的开发人员,但是我需要创意。正如我看到你是这方面的专家。你能分享一些答案吗? – Pentium10