我有一个为Firefox 3.6编写的附加组件,现在我正在为Firefox 4.0升级它,同时试图使它与3.6兼容 . 有没有人有尝试这样做的经验,或者如何在没有代码太过意大利面的情况下如何做到的提示?
有几个地方保持它兼容两个版本意味着做这样的事情:
.myAddonClass {
-moz-background-size: 100% 100%; /* Fx 3.x */
background-size: 100% 100%; /* Fx 4.x */
}
这会在两个版本中产生CSS警告 . 我可以忍受这一点 . 还有其他地方我在做这样的事情:
/** get the current version of this addon */
function getVersion() {
var version;
if (Application.extensions) { // Fx 3.x
version = Application.extensions.get('myaddon@example.com').version;
}
else { // Fx 4.x
Components.utils.import('resource://gre/modules/AddonManager.jsm');
AddonManager.getAddonByID('myaddon@example.com', function(addon) {
version = addon.version;
});
sleepUntil(function() {
return version;
}
}
return version;
}
(其中sleepUntil是一个使用Thread.processNextEvent technique的实用函数)
检查 Application.extensions
是否定义似乎比直接检查 Application.version
字符串更清晰,但是可能有's some flaw with that approach that I don'知道?
我也遇到了试图将内容插入网页的问题 . 在一个案例中, doc.body.appendChild
在3.x中工作但在4.x中没有,所以我尝试这样做:
try { // Fx 3.x
doc.body.appendChild(myElement);
}
catch (e) { // Fx 4.x
let span = doc.createElement('span');
doc.body.appendChild(span);
span.innerHTML = outerHTML(myElement);
}
上面的代码不起作用,但是如果我在 doc.body.appendChild(myElement)
之前插入一个 throw new Error('')
那么它确实有效,表明在Firefox 4中, appendChild
调用显然会在它抛出错误之前以某种方式修改 myElement
. 我担心我会遇到更多像这样的问题,所以我想看看是否有其他人已经经历过类似的过程,并且有任何我应该注意的提示 .
对不起,这是一个长期存在的问题 . Here's what I'm really asking:
-
你有什么建议可以让插件同时兼容Firefox 3和Firefox 4?
-
您如何看待分支代码的想法,以便我们有一个版本用于3.x而另一个版本用于4.x?然后我们必须对这两个版本应用任何新功能,并在两个版本中测试它们等 .
-
一般情况下,测试是否存在您想要的特定功能(比如我使用
if (Application.extensions) ...
或try / catch)或只检查Application.version
是否以'3'或'4'开头是否更好?
2 回答
我建议为最近的两个主要版本使用一个XPI . 旧版本的人是一个丢失的案例,并且有两个XPI用于不同的“活动”版本是令人困惑的(我最近没有尝试AMO呈现这种方式,但这是我的旧印象) .
只有当代码变得过于意大利面时,我才会这样做 . 作为一个业余爱好者,我会停止更新旧版本,然后将它留给旧版Firefox版本的用户使用 . 您可以在AMO上查看扩展的统计信息,以检查新Firefox版本的采用率(即使统计页面不是很容易使用 . )
基于功能的分支在这里并不重要,因为与网页不同,您正在处理一组固定的主机应用程序 .
但请记住可能的副作用:
检查应用程序的版本将使其更难移植到其他应用程序,因此如果您的部分代码仅使用平台功能,而不是特定应用程序的功能,那么测试平台版本会更有意义 .
try..catch还可以捕获其他错误,与您避免的错误无关 .
附:
1)为了避免有关未知属性的CSS警告(如果有很多),您可以通过appversion in chrome.manifest为不同的版本使用不同的样式
2)我认为Thread.processNextEvent技术是危险的,因为它会阻止调用堆栈在你完成之前展开 .
来自Mozilla #addons IRC Channels 的一个建议,我的
getVersion()
函数:编写一个由nsIExtensionManager支持的AddonManager模型 . Or use this one . 这样,函数本身不必具有if / then模式 .