4

我有一个为 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技术的实用函数)

检查是否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);
}

上面的代码不起作用,但如果我throw new Error('')在之前插入 adoc.body.appendChild(myElement)则它确实起作用,这表明在 Firefox 4 中,appendChild调用显然myElement在引发错误之前以某种方式进行了修改。我确信我可以弄清楚如何让这个特定的代码片段工作,但我担心我也会遇到更多这样的问题,所以我想看看其他人是否已经经历过一个类似的过程,并且有任何我应该注意的提示。

很抱歉这个冗长的问题。这就是我真正要问的:

  1. 对于尝试同时与 Firefox 3 和 Firefox 4 兼容的插件,您有什么建议?
  2. 您如何看待对代码进行分支以便我们有一个 3.x 版本和另一个 4.x 版本的想法?然后,我们必须将任何新功能应用于两个版本,并在两个版本中测试它们,等等。
  3. 一般来说,最好测试是否存在您想要的特定功能(就像我使用if (Application.extensions) ...或 try/catch 所做的那样)还是只检查是否Application.version以“3”或“4”开头?
4

2 回答 2

1

Mozilla #addons IRC 频道对我的getVersion()功能的一个建议是:编写一个由 nsIExtensionManager 支持的 AddonManager 模型。或者使用这个。这样,函数本身就不必具有 if/then 模式。

于 2010-12-18T20:39:57.783 回答
1

对于尝试同时与 Firefox 3 和 Firefox 4 兼容的插件,您有什么建议?

我会为最近的两个主要版本推荐一个 XPI。旧版本的人是一个迷失的案例,并且为不同的“活动”版本拥有两个 XPI 令人困惑(我最近没有尝试过 AMO 呈现这个的方式,但这是我的旧印象)。

您如何看待对代码进行分支以便我们有一个 3.x 版本和另一个 4.x 版本的想法?然后,我们必须将任何新功能应用于两个版本,并在两个版本中测试它们,等等。

只有当代码变得过于意大利面时,我才会这样做。作为一个业余爱好者,我会停止更新旧版本,将它留给使用旧​​ Firefox 版本的人使用。您可以在 AMO 上查看扩展的统计信息,以检查新 Firefox 版本的采用率(即使统计页面不是很容易使用)。

一般来说,最好测试是否存在您想要的特定功能(就像我对 if (Application.extensions) ... 或 try/catch 所做的那样)还是只检查 Application.version 是否以 '3' 开头或“4”?

基于能力的分支在这里无关紧要,因为您正在处理一组固定的主机应用程序,这与网页不同。

但请记住可能的副作用:

  • 检查应用程序的版本将使移植到其他应用程序变得更加困难,因此如果您的部分代码仅使用平台功能,而不是特定应用程序的功能,那么测试平台版本会更有意义。
  • try..catch 还可以捕获与您期望的错误无关的其他错误。我会避免它。

附言

1)为了避免关于未知属性的 CSS 警告(如果有很多),您可以通过chrome.manifest 中的 appversion为不同的版本使用不同的样式

2) 我相信 Thread.processNextEvent 技术是危险的,因为它会阻止调用堆栈展开,直到你完成。

于 2011-01-09T19:14:09.613 回答