开发者

Upgrading an addon to be compatible with Firefox 4.0, but trying to keep it compatible with 3.x also. Advice?

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('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;
}

(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:

  1. What advice do you have for trying to keep an addon compatible with both Firefox 3 and Firefox 4开发者_JS百科 at the same time?
  2. 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.
  3. 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 whether Application.version starts with '3' or '4'?


What advice do you have for trying to keep an addon compatible with both Firefox 3 and Firefox 4 at the same time?

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).

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.

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.)

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 whether Application.version starts with '3' or '4'?

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:

  • Checking application's version will make it harder to port to other applications, so if parts of your code are only using the platform features, not features of a specific application, it would make more sense to test the platform version.
  • try..catch can also catch other errors, not related to the one you're expecting. I'd avoid it.

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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜