あなたの質問は本当に漠然としているので、私はたくさんの推測に基づいて答えます。おそらく、アドオン SDKが内部で行うことと同じようなことをしたいでしょう- プラグインをサンドボックスにロードし、API を提供し、必要に応じてそれらのメソッドを呼び出します。また、 null プリンシパルを使用して、サンドボックスに追加の権限がないことを確認したいと思います。このようなことをする必要があります:
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 でのみ機能することに注意してください。拡張機能の一部であるか、ユーザーのディスクにあるプラグインのみが機能します。プラグインのリストが動的になる場合は、おそらくユーザーのプロファイルにそれらのディレクトリを作成し、必要に応じてこのディレクトリにダウンロードすることをお勧めします (これらのプラグインにあまりにも多くの権限を与えないように十分に注意する必要があります。セキュリティ上の問題)。