我在将我们的扩展程序从XUL迁移到Firefox SDK的过程中遇到了(希望)最后的障碍,但我还有一个最后的问题:
偏好设置。
当插件的SDK版本安装在XUL插件的顶部时,有许多首选项必须简单地迁移。出于各种原因,这些首选项不会向最终用户公开。两种体系结构之间的首选项命名空间完全不同。例如 -
A" version_number" XUL中的首选项由开发人员任意命名,并在about:config:
中显示my.preference.name
但是,在SDK中,它们的范围限定为相关扩展名:
extensions.[extension ID].my.preference.name
是否可以迁移XUL插件的首选项以便在SDK插件中重复使用?如果是这样,怎么样?
答案 0 :(得分:0)
虽然看起来无法从SDK插件的命名空间之外的首选项中读取,但它可以写入旧XUL扩展中的EXPECTED命名空间。我们提出的解决方案是在我们将新的SDK版本发布到AMO之前,发布一个旧的XUL插件的小型最终版本,其中包含一些额外的逻辑,负责执行此迁移。
这是我们方法的伪代码表示:
ContentScript.js
function initNewFFInstallation() {
...
if (checkIsUpgrade()) {
var keys = getPrefKeys()
migratePrefs(keys);
}
}
Utils.js - 充当将Overlay功能暴露给内容脚本的桥梁
Util.prototype.getPrefsBranch = function() {
return Components.classes["@mozilla.org/preferences-service;1"].
getService(Components.interfaces.nsIPrefService).
getBranch("my.prefs.ns.");
}
Util.prototype.getV2PrefsBranch = function() {
return Components.classes["@mozilla.org/preferences-service;1"].
getService(Components.interfaces.nsIPrefService).
getBranch("extensions.[SDK_ADDON_ID].");
}
Util.prototype.setBoolPref = function(key, val) {
this.getPrefsBranch().setBoolPref(key, val);
this.getPrefsBranch().setBoolPref(key, val);
}
Util.prototype.setCharPref = function(key, val) {
this.getPrefsBranch().setCharPref (key, val);
this.getV2PrefsBranch().setCharPref (key, val);
}
//copies all the preferences over
Util.prototype.migratePrefs = function(boolPrefKeys, charPrefKeys) {
boolPrefKeys.each(function (key) {
this.getV2PrefsBranch().setBoolPref(key, this.getPrefsBranch().getBoolPref(key));
});
charPrefKeys.forEach(function (key) {
this.getV2PrefsBranch().setCharPref(key, this.getPrefsBranch().getCharPref(key));
});
}
然后在我们的scriptcompiler.js中,实际上将脚本注入到页面中,util方法被挂钩到SafeWindow对象上。
injectScript: function(script, unsafeContentWin) {
var safeWin=new XPCNativeWrapper(unsafeContentWin);
var sandbox=new Components.utils.Sandbox(safeWin, {"sandboxPrototype":safeWin});
sandbox.window=safeWin;
sandbox.document=sandbox.window.document;
sandbox.unsafeWindow=unsafeContentWin;
var util = new Util();
//...other APIs
sandbox.migratePreferences=app_gmCompiler.hitch(util , "migratePreferences");
try {
Components.utils.evalInSandbox("(function(){"+script+"})()", sandbox);
} catch (e) {
}
}