升级插件以与 Firefox 4.0 兼容,但也尝试使其与 3.x 兼容。建议?
我有一个为 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('[email protected]').version;
}
else { // Fx 4.x
Components.utils.import('resource://gre/modules/AddonManager.jsm');
AddonManager.getAddonByID('[email protected]', function(addon) {
version = addon.version;
});
sleepUntil(function() {
return version;
}
}
return version;
}
其中 sleepUntil 是一个实用程序函数,使用 Thread.processNextEvent
技术)
检查是否定义了 Application.extensions
似乎比直接检查 Application.version
字符串更清晰,但也许这种方法存在一些我不知道的缺陷?
我在尝试将内容插入网页时也遇到了问题。在一种情况下, 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);
}
上面的代码不起作用,但是如果我插入 在
然后它确实起作用,表明在 Firefox 4 中,doc.body.appendChild(myElement)
之前抛出 new Error('')appendChild
调用显然在抛出错误之前以某种方式修改了 myElement
。我确信我可以弄清楚如何让这个特定的代码片段工作,但我担心我还会遇到更多这样的问题,所以我想看看其他人是否已经经历过类似的过程,并且有我应该注意的任何提示。
抱歉问了这么长的问题。 这就是我真正要问的:
- 对于尝试让插件同时兼容 Firefox 3 和 Firefox 4,您有什么建议?
- 您如何看待对代码进行分支以便我们有一个 3.x 版本和另一个 4.x 版本的想法?然后,我们必须将任何新功能应用到两个版本,并在两个版本中测试它们,等等。
- 一般来说,最好测试您想要的特定功能是否存在(就像我对
if (Application .extensions) ...
或 try/catch) 或者只是检查Application.version
是否以“3”或“4”开头?
I have an add-on which was written for Firefox 3.6 and now I'm upgrading it for Firefox 4.0, while trying to also keep it compatible with 3.6. Does anyone have any experience with trying to do this, or tips on how to do it without the code getting too spaghetti-ish?
There are a few places where keeping it compatible with both versions means doing something like this:
.myAddonClass {
-moz-background-size: 100% 100%; /* Fx 3.x */
background-size: 100% 100%; /* Fx 4.x */
}
which produces a CSS warning in both versions. I can live with that. There are other places where I'm doing things like this:
/** get the current version of this addon */
function getVersion() {
var version;
if (Application.extensions) { // Fx 3.x
version = Application.extensions.get('[email protected]').version;
}
else { // Fx 4.x
Components.utils.import('resource://gre/modules/AddonManager.jsm');
AddonManager.getAddonByID('[email protected]', function(addon) {
version = addon.version;
});
sleepUntil(function() {
return version;
}
}
return version;
}
(where sleepUntil is a utility function that uses the Thread.processNextEvent
technique)
Checking whether Application.extensions
is defined seems cleaner than just checking the Application.version
string directly, but maybe there's some flaw with that approach that I don't know about?
I'm also running into issues trying to insert content into webpages. In one case, doc.body.appendChild
was working in 3.x but not in 4.x, so I tried doing this:
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);
}
The code above doesn't work, but if I insert a throw new Error('')
just before doc.body.appendChild(myElement)
then it does work, indicating that in Firefox 4, the appendChild
call apparently modifies myElement
in some way before it throws an error. I'm sure I can figure out how to get this particular code snippet to work, but I'm worried that I'll run into a lot more problems like this as well, so I want to see if anyone else has already gone through a similar process, and has any tips that I should be aware of.
Sorry for the long-ish question. Here's what I'm really asking:
- What advice do you have for trying to keep an addon compatible with both Firefox 3 and Firefox 4 at the same time?
- What do you think about the idea of branching the code so that we have one version for 3.x and another for 4.x? We would then have to apply any new features to both versions, and test them in both versions, etc.
- In general, is it better to test for the presence of the specific feature you want (like I did with
if (Application.extensions) ...
or try/catch) or to just check whetherApplication.version
starts with '3' or '4'?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我建议为两个最新的主要版本使用单个 XPI。使用旧版本的人是一个迷失的案例,并且为不同的“活动”版本提供两个 XPI 令人困惑(我最近没有尝试过 AMO 呈现此方式的方式,但这是我的旧印象)。
只有当代码变得太意大利面条时我才会这样做。作为一名爱好者,我会停止更新旧版本,将其留给使用旧 Firefox 版本的人使用。您可以在 AMO 上查看扩展程序的统计信息,以检查新版 Firefox 的采用率(即使统计信息页面不太好用。)
基于功能的分支在这里并不重要,因为您处理的是一组固定的主机应用程序,与网页不同。
但请记住可能的副作用:
PS
1) 为了避免有关未知属性的 CSS 警告(如果有很多),您可以通过 appversion in chrome.manifest
2) 我认为 Thread.processNextEvent 技术是危险的,因为它会阻止调用堆栈在完成之前展开。
I'd recommend a single XPI for the two most recent major versions. The people on older versions are a lost case, and having two XPIs for different "active" versions is confusing (I haven't experimented recently with the way AMO presents this, but that's my old impression).
I'd do that only if the code had become too spaghetti. As a hobbyist, I'd stop updating the older version then, leaving it around for people on older Firefox versions to use. You can see statistics for your extension on AMO to check the adoption rate of new Firefox versions (even if the stats page is not very easy to use.)
Capability-based branching doesn't matter here, since you're dealing with a fixed set of host applications, unlike the web pages.
Keep in mind the possible side-effects, though:
P.S.
1) To avoid CSS warnings about unknown properties (if there are lots of them), you can use different styles for different versions via appversion in chrome.manifest
2) I believe the Thread.processNextEvent technique to be dangerous, since it prevents the call stack from unwinding until you're done.
Mozilla #addons IRC 频道对我的
getVersion()
函数提出了一项建议:编写一个由 nsIExtensionManager 支持的 AddonManager 模型。 或者使用这个。这样函数本身就不必具有 if/then 模式。One suggestion from the Mozilla #addons IRC channel, for my
getVersion()
function: Write a mock-up of AddonManager that's backed by nsIExtensionManager. Or use this one. That way the function itself won't have to have that if/then pattern.