Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Revamp NTT's force-compatiblity feature. Fixes #52. #82

Closed
wants to merge 14 commits into from

3 participants

@xabolcs
Owner

Please note the following:

  • it's a draft!
  • it is based on that addon in #52.
  • it introduces a new feature: restart on demand - inspired by that addon. :)
extension/chrome/content/nightly.js
@@ -493,14 +493,22 @@ openPushlog: function() {
toggleCompatibility: function() {
var forceCompat = nightly.preferences.getBoolPref("disableCheckCompatibility");
- nightly.preferences.setBoolPref("disableCheckCompatibility", !forceCompat);
+ var os = Components.classes["@mozilla.org/observer-service;1"].
@whimboo Owner
whimboo added a note

It has been named obs across the Firefox codebase. I would propose we do the same here, which makes it easier for us later to replace the instances with Services.obs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
extension/chrome/content/nightly.js
((17 lines not shown))
if (nightlyApp.openNotification) {
- nightlyApp.openNotification("nightly-compatibility-restart",
- nightly.getString("nightly.restart.message"),
- nightly.getString("nightly.restart.label"),
- nightly.getString("nightly.restart.accesskey"),
- function() { Application.restart(); });
+ os.addObserver({observe: restartObserver}, "nttACS", false);
@whimboo Owner
whimboo added a note

I would propose we better define an object with the observe method contained.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
extension/components/nttAddonCompatibilityService.js
((9 lines not shown))
function nttAddonCompatibilityService() {
this.prefService = Components.classes['@mozilla.org/preferences-service;1']
.getService(Components.interfaces.nsIPrefBranch2);
- this.prefService.addObserver("", this, false);
+ this.prefService.addObserver(PREF, this, false);
+
+ this.appinfo = Components.classes["@mozilla.org/xre/app-info;1"]
+ .getService(Components.interfaces.nsIXULAppInfo);
@whimboo Owner
whimboo added a note

Please shorten to Cc and Ci and align the second row with C from Cc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
extension/components/nttAddonCompatibilityService.js
@@ -37,17 +37,30 @@
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+const PREF = "nightly.disableCheckCompatibility";
+const PREFIX = "extensions.checkCompatibility.";
+const PREF_NIGHTLY = "nightly";
@whimboo Owner
whimboo added a note

Please use better names for those constants so it's easier later in the code what we are referring to.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
extension/components/nttAddonCompatibilityService.js
((24 lines not shown))
this.setCompatPrefs();
}
nttAddonCompatibilityService.prototype = {
+ get version() this.appinfo.version.replace(/^([^\.]+\.[0-9]+[a-z]*).*/i, "$1"),
@whimboo Owner
whimboo added a note

Please move this down below all the components registration code and also put brackets around the function body.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
extension/components/nttAddonCompatibilityService.js
((112 lines not shown))
+ function count() addons.reduce(function (acc, a) acc + (
+ (a.pendingOperations & AddonManager.PENDING_ENABLE) != 0 ||
+ (a.pendingOperations & AddonManager.PENDING_DISABLE) != 0
+ ), 0);
+
+ let startCount = count();
+ self.setCompatPrefs();
+ if (startCount != count()) {
+ Components.utils.reportError("restart needed! "
+ + ", counts: " + startCount + " and " + count()
+ );
+ self.obs.notifyObservers(null, "nttACS", "restartNeeded");
+ } else {
+ self.obs.notifyObservers(null, "nttACS", null);
+ }
+ });
@whimboo Owner
whimboo added a note

This looks like a 1:1 copy from the source. Please make sure to format the code accordingly to our styles. Also please separate out getAddonsByTypes so it can be read and understood easier.

@xabolcs Owner
xabolcs added a note

whimboo commented on commit

...
Also please separate out getAddonsByTypes so it can be read and understood easier.

I had no idea how to do this nicely without #90. :(
After checking 392a9b8 please advice me how to separate out getAddonByTypes more!
I gave it a try in the commit above, but any comments are welcome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
extension/components/nttAddonCompatibilityService.js
((110 lines not shown))
+ let self = this;
+ AddonManager.getAddonsByTypes(null, function (addons) {
+ function count() addons.reduce(function (acc, a) acc + (
+ (a.pendingOperations & AddonManager.PENDING_ENABLE) != 0 ||
+ (a.pendingOperations & AddonManager.PENDING_DISABLE) != 0
+ ), 0);
+
+ let startCount = count();
+ self.setCompatPrefs();
+ if (startCount != count()) {
+ Components.utils.reportError("restart needed! "
+ + ", counts: " + startCount + " and " + count()
+ );
+ self.obs.notifyObservers(null, "nttACS", "restartNeeded");
+ } else {
+ self.obs.notifyObservers(null, "nttACS", null);
@whimboo Owner
whimboo added a note

why do we have to notify with null?

@xabolcs Owner
xabolcs added a note

You should read the code more carefully! :)

Definitely notifying with "pleaseDeRegisterYourself" message would be more understandable:
in nightly.toggleCompatibility an observer is registered in every menuItem click ... that should be unregistered! Always.

Of course there are other ways of implementing "Restart on demand". :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
extension/components/nttAddonCompatibilityService.js
((132 lines not shown))
}
- else if (appInfo.name == "Songbird") {
- prefs = ["extensions.checkCompatibility",
- "extensions.checkCompatibility.1.8",
- "extensions.checkCompatibility.1.9",
- "extensions.checkCompatibility.1.10",
- "extensions.checkCompatibility.1.11",
- "extensions.checkCompatibility.1.12"];
+ },
+
+
+ setCompatPrefs : function() {
@whimboo Owner
whimboo added a note

Why a separate function? Move this code directly into the else case of manageCompatPrefsSetting.

@xabolcs Owner
xabolcs added a note

Again, You should read the code more carefully! :)
Or I missed something.

manageCompatPrefsSetting setCompatPrefsHelper does the following:
IF there is AddonsManager then:
1. do something
2. call setCompatPrefs
3. do other stuffs
ELSE
1. call setCompatPrefs
2. other stuff

Please clarify Your question!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@xabolcs xabolcs #Issue 52 - addressing comments, round 1
- renamed 'os' to 'obs'
- moved observer code to an object
- shortened Components.*
- formatted foreign code
- renamed preference constants
- moved version()
392a9b8
@xabolcs
Owner

Added commit 392a9b8 - Addressing comments, round 1.

extension/components/nttAddonCompatibilityService.js
((118 lines not shown))
+ return aAccumulator + (
+ (aAddon.pendingOperations & AddonManager.PENDING_ENABLE) != 0 ||
+ (aAddon.pendingOperations & AddonManager.PENDING_DISABLE) != 0
+ );
+ }, 0);
+ }
+
+ let startCount = count();
+ self.setCompatPrefs();
+ if (startCount != count()) {
+ self.obs.notifyObservers(null, "nttACS", "restartNeeded");
+ } else {
+ self.obs.notifyObservers(null, "nttACS", null);
+ }
+ }
+ AddonManager.getAddonsByTypes(null, countPendingAddonsAndNotifyToRestartCallback);
@xabolcs Owner
xabolcs added a note

The number of characters in function name countPendingAddonsAndNotifyToRestartCallback is too damn high.

@whimboo Owner
whimboo added a note

I would suggest we move the callback inline. There is no reason to have it separate given that it is only used once.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@whimboo
Owner

Would you mind to update the pull for the latest version of the NTT code? We really missed that in the 3.4 release. :/

@xabolcs
Owner

whimboo wrote:

Would you mind to update the pull for the latest version of the NTT code? We really missed that in the 3.4 release. :/

Sure! :)
Thank you for picking up.

@xabolcs
Owner

This pull request can be automatically merged. Again. :)

extension/components/nttAddonCompatibilityService.js
((155 lines not shown))
+ Cu.import("resource://gre/modules/AddonManager.jsm");
+ let self = this;
+ function countPendingAddonsAndNotifyToRestartCallback(aAddons) {
+ function count() {
+ return aAddons.reduce(function (aAccumulator, aAddon) {
+ return aAccumulator + (
+ (aAddon.pendingOperations & AddonManager.PENDING_ENABLE) != 0 ||
+ (aAddon.pendingOperations & AddonManager.PENDING_DISABLE) != 0
+ );
+ }, 0);
+ }
+
+ let startCount = count();
+ self.setCompatPrefs();
+ if (startCount != count()) {
+ self.obs.notifyObservers(null, "nttACS", "restartNeeded");
@whimboo Owner
whimboo added a note

I would suggest we send an object like { restart: true } which will make it easier to extend the observer data later if needed.

@xabolcs Owner
xabolcs added a note

I would suggest we send an object ...

Are you sure? Please check notifyObservers() documentation again! ;)

void notifyObservers(
  in nsISupports aSubject,
  in string aTopic,
  in wstring someData 
);

I could use JSON.parse() here on the other side, if you really want to pass an object.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
extension/components/nttAddonCompatibilityService.js
((144 lines not shown))
- "extensions.checkCompatibility.2.17a",
- "extensions.checkCompatibility.2.18",
- "extensions.checkCompatibility.2.18a",
- "extensions.checkCompatibility.nightly"];
+
+ get version() {
+ return this.appinfo.version.replace(/^([^\.]+\.[0-9]+[a-z]*).*/i, "$1");
+ },
+
+ setCompatPrefsHelper : function() {
+ try{
+ Cu.import("resource://gre/modules/AddonManager.jsm");
+ let self = this;
+ function countPendingAddonsAndNotifyToRestartCallback(aAddons) {
+ function count() {
+ return aAddons.reduce(function (aAccumulator, aAddon) {
@whimboo Owner
whimboo added a note

Instead of reduce I would run a filter for the addon state and take the count from the final array length.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
extension/components/nttAddonCompatibilityService.js
((183 lines not shown))
- "extensions.checkCompatibility.1.6",
- "extensions.checkCompatibility.1.7",
- "extensions.checkCompatibility.1.8",
- "extensions.checkCompatibility.1.9",
- "extensions.checkCompatibility.1.10",
- "extensions.checkCompatibility.1.11",
- "extensions.checkCompatibility.1.12",
- "extensions.checkCompatibility.2.0",
- "extensions.checkCompatibility.2.1",
- "extensions.checkCompatibility.2.2",
- "extensions.checkCompatibility.2.3",
- "extensions.checkCompatibility.2.4"];
+ },
+
+
+ setCompatPrefs : function() {
@whimboo Owner
whimboo added a note

nit: space before the rounded opening bracket

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
extension/components/nttAddonCompatibilityService.js
((186 lines not shown))
- "extensions.checkCompatibility.1.9",
- "extensions.checkCompatibility.1.10",
- "extensions.checkCompatibility.1.11",
- "extensions.checkCompatibility.1.12",
- "extensions.checkCompatibility.2.0",
- "extensions.checkCompatibility.2.1",
- "extensions.checkCompatibility.2.2",
- "extensions.checkCompatibility.2.3",
- "extensions.checkCompatibility.2.4"];
+ },
+
+
+ setCompatPrefs : function() {
+ var prefs = [];
+
+ switch(this.appinfo.name) {
@whimboo Owner
whimboo added a note

nit: same here

@whimboo Owner
whimboo added a note

Also please add a comment why we are excluding Songbird here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
extension/components/nttAddonCompatibilityService.js
((135 lines not shown))
- "extensions.checkCompatibility.2.13",
- "extensions.checkCompatibility.2.13a",
- "extensions.checkCompatibility.2.14",
- "extensions.checkCompatibility.2.14a",
- "extensions.checkCompatibility.2.15",
- "extensions.checkCompatibility.2.15a",
- "extensions.checkCompatibility.2.16",
- "extensions.checkCompatibility.2.16a",
- "extensions.checkCompatibility.2.17",
- "extensions.checkCompatibility.2.17a",
- "extensions.checkCompatibility.2.18",
- "extensions.checkCompatibility.2.18a",
- "extensions.checkCompatibility.nightly"];
+
+ get version() {
+ return this.appinfo.version.replace(/^([^\.]+\.[0-9]+[a-z]*).*/i, "$1");
@whimboo Owner
whimboo added a note

We don't need a getter here. Call this once in the constructor and store it. The version will never change during a Firefox session.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
xabolcs added some commits
@xabolcs xabolcs #Issue 52 - addressing comments, round 2, part 1
- JSONed observer data
- version is now a property
- space nits
- Songbird exclusion note
- filtering addons
- not inlining long name function yet
f6fef70
@xabolcs xabolcs #Issue 52 - addressing comments, round 2, part 2
- rework setCompatPrefsHelper
d24465f
@xabolcs
Owner

@whimboo
All your comments addressed.
While in-lining the long named function I restructured a little bit.

@xabolcs
Owner

@whimboo
You could review now, but please don't land it for a while.
Let me consult Gerv about crediting Kris for his original work before landing.

extension/chrome/content/nightly.js
@@ -473,14 +473,25 @@ openPushlogSinceCurrentBuild: function() {
toggleCompatibility: function() {
var forceCompat = nightly.preferences.getBoolPref("disableCheckCompatibility");
- nightly.preferences.setBoolPref("disableCheckCompatibility", !forceCompat);
+ var obs = Components.classes["@mozilla.org/observer-service;1"].
+ getService(Components.interfaces.nsIObserverService);
+ var restartObserver = {
+ observe: function (subject, topic, data) {
+ obs.removeObserver(restartObserver, "nttACS");
+ var parsedData = JSON.parse(data);
+ if (parsedData && parsedData.restart) {
+ nightlyApp.openNotification("nightly-compatibility-restart",
@whimboo Owner
whimboo added a note

Before we had if (nightlyApp.openNotification). Isn't that necessary anymore?

@xabolcs Owner
xabolcs added a note

Before we had if (nightlyApp.openNotification). Isn't that necessary anymore?
It's still around here! :)

The restartObserver above is activated only if nightlyApp.openNotification exists. See L491!

@whimboo Owner
whimboo added a note

I would move this if in here, so that we always send an observer notification. Other extensions may want to rely on the notification and then could benefit from.

@xabolcs Owner
xabolcs added a note

I would move this if in here, so that we always send an observer notification. ...

?!
The nttAddonCompatibilityService sends the notification in all case. See the other, sendNotification(), notifyObject related threads near at line L54 and L73/L83!

The restartObserver here isn't always activated.
For example Songbird doesn't have nightlyApp.openNotification implemented yet,
therefore nightly.toggleCompatibility doesn't register for the restart notification.
It simply discards. :)
But in Firefox case it will register the observer, and the PopupNotification/NotificationBox could open if restart would be needed after pref change.

@whimboo Owner
whimboo added a note

It doesn't matter which application has openNotification available or not. If a restart is necessary we should fire the observer anyway. If the notification cannot be handled in observe because the above method is not available, we can always skip it. But we should not stop sending the observer notification due to that reason. As I have mentioned above others may be very well interested in our notification too.

@xabolcs Owner
xabolcs added a note

I don't undestand you.
I repeat, the notification from the component is always sent.
The sent (here: the received) notification data contains the { restart: true/false } object stringified.

Why do we need register for notifications if we going to discard all of them?
What other action should done by NTT when a restart is needed?
I think notifying the user about the restart is the only action here.

Of course I could move that if there, but I think that won't be the optimal fix in this case.

@whimboo Owner
whimboo added a note

So this observer notification is only to trigger our restart prompt? If that's the case please make sure to give it a better topic. Most likely we should make it internal then, so no other add-ons could hook-up on it.

@xabolcs Owner
xabolcs added a note

You are right! The topic name is "nttACS" could be improved, and it is used for triggering the restat prompt.
I decided to use observer notifications because that was the easiest way.
Please note, there are no elegant way to prevent other addons to hook-up on this restart trigger while nttAddonCompatibilityService is an independent module IMHO.
If you really want this then we should:

  • drop the whole restart-on-demand proposal
  • move the count-pending-addons stuff back to nightly. In this case syncing between component and window object should be done
  • convert NTT into one big bootstrap.js
  • try to find other resolution

Instead trying hide this trigger from other extensions I vote for correct topic naming.
BTW it's OK to me to convert this interface to a callback interface (like AddonManager's ....listener methods).

@whimboo Owner
whimboo added a note

I don't think we should over-engineer it at this point. When we really only want to have it available internally, why can't we call it directly through it's object/instance? If the prompt has to happen async we can use setTimeout(fun, 0) to trigger it, right?

@xabolcs Owner
xabolcs added a note

In this case the component should find the most recent Tb, SM, Fx, ... window - if any - then it could call nightly.openNotification.

But I'm still voting for drop this demand stuff from this pull, and let it born as a follow-up issue. Or simply leave it as is - a public interface.
And I still can't imagine what do you think how should I implement this interface privately. :(

@whimboo Owner
whimboo added a note

Ok, so lets rename the observer topic to _nttACS which should make it clear it's somewhat private. Please file a follow-up where we can discuss another (better) solution. Thanks.

@xabolcs Owner
xabolcs added a note

Ok, so lets rename the observer topic to _nttACS ...

Renamed, but not tested.

@xabolcs Owner
xabolcs added a note

Until this private interface doesn't get implemented (should file a follow-up issue) I move this obs and restartObserver into if (nightlyApp.openNotification) section:

  • to avoid confusion, because they belongs there
  • due to performance :)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
extension/components/nttAddonCompatibilityService.js
((28 lines not shown))
- if(this.prefService.getBoolPref("nightly.disableCheckCompatibility"))
+ this.version = this.appinfo.version.replace(/^([^\.]+\.[0-9]+[a-z]*).*/i, "$1");
+
+ if(this.prefService.getBoolPref(PREF_FORCE_COMPAT)) {
@whimboo Owner
whimboo added a note

nit: a blank between if and the opening bracket.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
extension/components/nttAddonCompatibilityService.js
((43 lines not shown))
// nsIObserver
- observe : function(subject, topic, data) {
+ observe : function (subject, topic, data) {
if (topic == "nsPref:changed") {
switch(data) {
@whimboo Owner
whimboo added a note

nit: blank after switch please.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
extension/components/nttAddonCompatibilityService.js
((145 lines not shown))
- "extensions.checkCompatibility.2.13a",
- "extensions.checkCompatibility.2.14",
- "extensions.checkCompatibility.2.14a",
- "extensions.checkCompatibility.2.15",
- "extensions.checkCompatibility.2.15a",
- "extensions.checkCompatibility.2.16",
- "extensions.checkCompatibility.2.16a",
- "extensions.checkCompatibility.2.17",
- "extensions.checkCompatibility.2.17a",
- "extensions.checkCompatibility.2.18",
- "extensions.checkCompatibility.2.18a",
- "extensions.checkCompatibility.nightly"];
+ try{
+ Cu.import("resource://gre/modules/AddonManager.jsm");
+ AddonManager.getAddonsByTypes(null, function (aAddons) {
+ function isPendingAddon(aAddon) {
@whimboo Owner
whimboo added a note

I still don't see the reason why it has to be a separate function. Make it an inline function for filter() please which let us better follow the flow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@whimboo whimboo commented on the diff
extension/components/nttAddonCompatibilityService.js
((163 lines not shown))
+ ;
+ }
+ function count() {
+ return aAddons.filter(isPendingAddon).length;
+ }
+ sendNotification({count: count});
+ });
+ } catch(e) {
+ // old extension manager API
+ let counter = 0;
+ function count() {
+ // Feel free to write the real count() for the old EM API,
+ // but now it's always returning a different number
+ return counter++;
+ }
+ sendNotification({count: count});
@whimboo Owner
whimboo added a note

So we always send a notification, right? We may want to condense both calls into a single one and put it after the try/catch.

@xabolcs Owner
xabolcs added a note

So we always send a notification, right?

Nope.
The first sendNotification is called async, the second is called in sync.
The common stuff - sendNotification - is already put before the try/catch.

@whimboo Owner
whimboo added a note

Ah, you are right. So that's fine then. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@whimboo whimboo commented on the diff
extension/components/nttAddonCompatibilityService.js
((189 lines not shown))
- "extensions.checkCompatibility.2.0",
- "extensions.checkCompatibility.2.1",
- "extensions.checkCompatibility.2.2",
- "extensions.checkCompatibility.2.3",
- "extensions.checkCompatibility.2.4"];
+ },
+
+ setCompatPrefs : function () {
+ var prefs = [];
+
+ switch (this.appinfo.name) {
+ case "Songbird":
+ /**
+ * Excluding Songbird because it is based on Gecko 1.9.2
+ * and "extensions.checkCompatibility.nightly" preference
+ * introduced in Gecko 7.
@whimboo Owner
whimboo added a note

What about Firefox 3.6 you still want to support? It would have the same issue. Shouldn't we set the compatibility for 1.9.2 instead? There may be extensions which are disabled and the user still can't force to be enabled.

@whimboo Owner
whimboo added a note

Oh wait. The line is below. Forget about it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@xabolcs
Owner

Pull updated for the nits.
The nightlynttAddonCompatibilityService private communication is still unclear to me.

@whimboo
Owner

Looks fine to me. @xabolcs can we get this tested? Do you have the time for? If not could you, @tonymec do it? I would kinda appreciate that given the lack of time on my side this week. :/

@xabolcs
Owner

Looks fine to me. @xabolcs can we get this tested?

Grrr!
Testing with an old Nighlty (Mozilla/5.0 (Windows NT 6.1; WOW64; rv:20.0) Gecko/20121229 Firefox/20.0 ID:20121229030919 CSet: 0bb4773db082) showed me that commit 593d77f introduced a regression in the restart-notification. :(

Seems like the inline transformation of isPendingAddon() wasn't succesful.

@tonymec
Owner

I'll have extremely little free time until at least Easter Monday. The two weeks after that I might have a little more slack.

xabolcs added some commits
@xabolcs xabolcs Issue #52 - addressing comments, round 4, part 1
- not starting a boolean in isPendingAddon()
- space nits
c4eb549
@xabolcs xabolcs Issue #52 - addressing comments, round 4, part 2
- not starting a boolean in isPendingAddon(), really
0605f66
@xabolcs
Owner

Seems like the inline transformation of isPendingAddon() wasn't succesful.

Bug hunted down.
Tested with

  • Mozilla/5.0 (Windows NT 6.1; WOW64; rv:22.0) Gecko/20130327 Firefox/22.0 ID:20130327031035 CSet: 178a4a770bb1
  • Mozilla/5.0 (Windows NT 6.1; WOW64; rv:20.0) Gecko/20121229 Firefox/20.0 ID:20121229030919 CSet: 0bb4773db082
  • Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0 ID:20130116073211 CSet: eecd28b7ba09
@xabolcs

This returns undefined instead the given result.

@xabolcs
Owner

@whimboo
Addressing comments is done for now, feel free to review again!

@whimboo

So what was the problem with those lines? You didn't gave an answer on the changes. And I also don't see anything here. So I'm interested in what fixed it.

nit: Can you please correct the indentation of the second line, so that both brackets start in the same column?

@xabolcs
Owner

So what was the problem with those lines? You didn't gave an answer on the changes. And I also don't see anything here. So I'm interested in what fixed it.

Try this gist!
The problem is that if return finds nothing but whitespace to EOL then it thinks there is nothing there, and returns undefined.
I had to start the expression in the same line where the return is.

nit: Can you please correct the indentation of the second line, so that both brackets start in the same column?

Sure!

Owner

Hah, I have never seen that and expected such a smart thing from the JS interpreter. Good to know! Thanks

@xabolcs
Owner

@whimboo
Commit 94e0e83 is added, now it's your turn.

extension/chrome/content/nightly.js
@@ -473,14 +473,25 @@ openPushlogSinceCurrentBuild: function() {
toggleCompatibility: function() {
var forceCompat = nightly.preferences.getBoolPref("disableCheckCompatibility");
- nightly.preferences.setBoolPref("disableCheckCompatibility", !forceCompat);
+ var obs = Components.classes["@mozilla.org/observer-service;1"].
+ getService(Components.interfaces.nsIObserverService);
@whimboo Owner
whimboo added a note

We have an inconsistency here how we use Cc and Ci regarding their short and long names. If you feel fine please make it shorter here.

@xabolcs Owner
xabolcs added a note

I see no inconsistency here reagrding to Cx shortcuts.
Please note that nightly.js doesn't have those shortcuts!

@whimboo Owner
whimboo added a note

So please file a new issue which we can use to sync up all the files.

@xabolcs Owner
xabolcs added a note

We have #87 already for styling. Should I file a new for code consistency?

@whimboo Owner
whimboo added a note

Whatever works best for you. Is something else remaining now or can we can get this pull merged?

@xabolcs Owner
xabolcs added a note

I have to fix the two nits, so the pull request is not ready yet.

@xabolcs Owner
xabolcs added a note

So please file a new issue which we can use to sync up all the files.

Filed #128.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
extension/components/nttAddonCompatibilityService.js
((98 lines not shown))
- "extensions.checkCompatibility.19.0a",
- "extensions.checkCompatibility.20.0",
- "extensions.checkCompatibility.20.0a",
- "extensions.checkCompatibility.21.0",
- "extensions.checkCompatibility.21.0a",
- "extensions.checkCompatibility.22.0",
- "extensions.checkCompatibility.22.0a",
- "extensions.checkCompatibility.nightly"];
+ setCompatPrefsHelper : function () {
+ let self = this;
+ let notifyObject = { restart: true };
+ function sendNotification(options) {
+ let { count } = options;
+ let startCount = count();
+ self.setCompatPrefs();
+ notifyObject.restart = startCount != count();
@whimboo Owner
whimboo added a note

I believe you want to have a triple operator here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
extension/components/nttAddonCompatibilityService.js
((154 lines not shown))
- "extensions.checkCompatibility.2.18",
- "extensions.checkCompatibility.2.18a",
- "extensions.checkCompatibility.nightly"];
+ try {
+ Cu.import("resource://gre/modules/AddonManager.jsm");
+ AddonManager.getAddonsByTypes(null, function (aAddons) {
+ function count() {
+ return aAddons.filter(function isPendingAddon(aAddon) {
+ return (aAddon.pendingOperations & AddonManager.PENDING_ENABLE) != 0 ||
+ (aAddon.pendingOperations & AddonManager.PENDING_DISABLE) != 0
+ ;
+ }).length;
+ }
+ sendNotification({count: count});
+ });
+ } catch(e) {
@whimboo Owner
whimboo added a note

nit: space before the rounded brackets

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@whimboo
Owner

Except the two nits we are very close to get this landed!

@xabolcs xabolcs Issue #52 - addressing comments, round 6
- obs + restartObserver is relevant only in nightlyApp.openNotification case
- nttAddonCompatibilityService space nits
4bf06c6
@xabolcs
Owner

Added commit 4bf06c6:

  • move obs, restartObserver where they belong
  • space nits

I hope you agree with that move in

@xabolcs
Owner

... nightly.js and we are still very close to get this landed! :)

@whimboo
Owner

Looks fine to me. Lets get it landed.

@xabolcs
Owner

Landed as ae9184f.

@xabolcs xabolcs closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jun 6, 2012
  1. @xabolcs
  2. @xabolcs
  3. @xabolcs
Commits on Aug 13, 2012
  1. @xabolcs

    #Issue 52 - addressing comments, round 1

    xabolcs authored
    - renamed 'os' to 'obs'
    - moved observer code to an object
    - shortened Components.*
    - formatted foreign code
    - renamed preference constants
    - moved version()
Commits on Mar 8, 2013
  1. @xabolcs

    Merge in v3.4 changes

    xabolcs authored
Commits on Mar 14, 2013
  1. @xabolcs

    #Issue 52 - addressing comments, round 2, part 1

    xabolcs authored
    - JSONed observer data
    - version is now a property
    - space nits
    - Songbird exclusion note
    - filtering addons
    - not inlining long name function yet
  2. @xabolcs

    #Issue 52 - addressing comments, round 2, part 2

    xabolcs authored
    - rework setCompatPrefsHelper
Commits on Mar 21, 2013
  1. @xabolcs

    #Issue 52 - addressing comments, round 3, part 1

    xabolcs authored
    - space nits
    - inline pending filter
Commits on Mar 25, 2013
  1. @xabolcs

    Issue #52 - addressing comments, round 3, part 2

    xabolcs authored
    - "nttACS" -> "_nttACS"
Commits on Mar 27, 2013
  1. @xabolcs

    Issue #52 - addressing comments, round 4, part 1

    xabolcs authored
    - not starting a boolean in isPendingAddon()
    - space nits
  2. @xabolcs

    Issue #52 - addressing comments, round 4, part 2

    xabolcs authored
    - not starting a boolean in isPendingAddon(), really
  3. @xabolcs

    Issue #52 - addressing comments, round 4, part 3

    xabolcs authored
    - space nit
Commits on Apr 9, 2013
  1. @xabolcs

    Issue #52 - addressing comments, round 5

    xabolcs authored
    - indentation
Commits on Apr 13, 2013
  1. @xabolcs

    Issue #52 - addressing comments, round 6

    xabolcs authored
    - obs + restartObserver is relevant only in nightlyApp.openNotification case
    - nttAddonCompatibilityService space nits
This page is out of date. Refresh to see the latest.
View
1  extension/chrome.manifest
@@ -12,7 +12,6 @@ contract @mozilla.org/network/protocol/about;1?what=nightly {4cec494a-d33a-4ee7-
# addon compatiblity component
component {126c18c5-386c-4c13-b59f-dc909e78aea0} components/nttAddonCompatibilityService.js
contract @mozilla.com/nightly/addoncompatibility;1 {126c18c5-386c-4c13-b59f-dc909e78aea0}
-category profile-after-change nttAddonCompatibilityService @mozilla.com/nightly/addoncompatibility;1
# Shared chrome
override chrome://nightly/content/platform.js chrome://nightly/content/winPlatform.js os=winnt
View
23 extension/chrome/content/nightly.js
@@ -473,14 +473,25 @@ openPushlogSinceCurrentBuild: function() {
toggleCompatibility: function() {
var forceCompat = nightly.preferences.getBoolPref("disableCheckCompatibility");
- nightly.preferences.setBoolPref("disableCheckCompatibility", !forceCompat);
if (nightlyApp.openNotification) {
- nightlyApp.openNotification("nightly-compatibility-restart",
- nightly.getString("nightly.restart.message"),
- nightly.getString("nightly.restart.label"),
- nightly.getString("nightly.restart.accesskey"),
- function() { Application.restart(); });
+ var obs = Components.classes["@mozilla.org/observer-service;1"]
+ .getService(Components.interfaces.nsIObserverService);
+ var restartObserver = {
+ observe: function (subject, topic, data) {
+ obs.removeObserver(restartObserver, "_nttACS");
+ var parsedData = JSON.parse(data);
+ if (parsedData && parsedData.restart) {
+ nightlyApp.openNotification("nightly-compatibility-restart",
+ nightly.getString("nightly.restart.message"),
+ nightly.getString("nightly.restart.label"),
+ nightly.getString("nightly.restart.accesskey"),
+ function() { Application.restart(); });
+ }
+ }
+ };
+ obs.addObserver(restartObserver, "_nttACS", false);
}
+ nightly.preferences.setBoolPref("disableCheckCompatibility", !forceCompat);
},
}
View
250 extension/components/nttAddonCompatibilityService.js
@@ -2,30 +2,46 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+const PREF_FORCE_COMPAT = "nightly.disableCheckCompatibility";
+const PREF_CHECK_COMPAT_PREFIX = "extensions.checkCompatibility.";
+const PREF_CHECK_COMPAT_NIGHTLY = "extensions.checkCompatibility.nightly";
+
function nttAddonCompatibilityService() {
- this.prefService = Components.classes['@mozilla.org/preferences-service;1']
- .getService(Components.interfaces.nsIPrefBranch2);
-
- this.prefService.addObserver("", this, false);
+ this.prefService = Cc['@mozilla.org/preferences-service;1']
+ .getService(Ci.nsIPrefBranch2);
+
+ this.prefService.addObserver(PREF_FORCE_COMPAT, this, false);
+
+ this.appinfo = Cc["@mozilla.org/xre/app-info;1"]
+ .getService(Ci.nsIXULAppInfo);
+
+ this.obs = Cc["@mozilla.org/observer-service;1"]
+ .getService(Ci.nsIObserverService);
+
+ this.version = this.appinfo.version.replace(/^([^\.]+\.[0-9]+[a-z]*).*/i, "$1");
- if(this.prefService.getBoolPref("nightly.disableCheckCompatibility"))
+ if (this.prefService.getBoolPref(PREF_FORCE_COMPAT)) {
this.setCompatPrefs();
+ }
}
nttAddonCompatibilityService.prototype = {
classDescription: "Nightly Tester Tools Addon Compatibility",
classID: Components.ID("{126c18c5-386c-4c13-b59f-dc909e78aea0}"),
contractID: "@mozilla.com/nightly/addoncompatibility;1",
- QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsIObserver]),
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
// nsIObserver
- observe : function(subject, topic, data) {
+ observe : function (subject, topic, data) {
if (topic == "nsPref:changed") {
- switch(data) {
- case "nightly.disableCheckCompatibility":
- this.setCompatPrefs();
+ switch (data) {
+ case PREF_FORCE_COMPAT:
+ this.setCompatPrefsHelper();
break;
default:
break;
@@ -33,170 +49,64 @@ nttAddonCompatibilityService.prototype = {
}
},
- setCompatPrefs : function() {
- var prefs = ["extensions.checkCompatibility",
- "extensions.checkCompatibility.3.6b",
- "extensions.checkCompatibility.3.6",
- "extensions.checkCompatibility.3.6p",
- "extensions.checkCompatibility.3.6pre",
- "extensions.checkCompatibility.3.7a",
- "extensions.checkCompatibility.4.0",
- "extensions.checkCompatibility.4.0b",
- "extensions.checkCompatibility.4.0pre",
- "extensions.checkCompatibility.4.0p",
- "extensions.checkCompatibility.4.2a",
- "extensions.checkCompatibility.4.2a1",
- "extensions.checkCompatibility.4.2a1pre",
- "extensions.checkCompatibility.4.2",
- "extensions.checkCompatibility.4.2b",
- "extensions.checkCompatibility.5.0",
- "extensions.checkCompatibility.5.0a",
- "extensions.checkCompatibility.5.0b",
- "extensions.checkCompatibility.6.0",
- "extensions.checkCompatibility.6.0a",
- "extensions.checkCompatibility.6.0b",
- "extensions.checkCompatibility.7.0",
- "extensions.checkCompatibility.7.0a",
- "extensions.checkCompatibility.7.0b",
- "extensions.checkCompatibility.8.0",
- "extensions.checkCompatibility.8.0a",
- "extensions.checkCompatibility.9.0",
- "extensions.checkCompatibility.9.0a",
- "extensions.checkCompatibility.10.0",
- "extensions.checkCompatibility.10.0a",
- "extensions.checkCompatibility.11.0",
- "extensions.checkCompatibility.11.0a",
- "extensions.checkCompatibility.12.0",
- "extensions.checkCompatibility.12.0a",
- "extensions.checkCompatibility.13.0",
- "extensions.checkCompatibility.13.0a",
- "extensions.checkCompatibility.14.0",
- "extensions.checkCompatibility.14.0a",
- "extensions.checkCompatibility.15.0",
- "extensions.checkCompatibility.15.0a",
- "extensions.checkCompatibility.16.0",
- "extensions.checkCompatibility.16.0a",
- "extensions.checkCompatibility.17.0",
- "extensions.checkCompatibility.17.0a",
- "extensions.checkCompatibility.18.0",
- "extensions.checkCompatibility.18.0a",
- "extensions.checkCompatibility.19.0",
- "extensions.checkCompatibility.19.0a",
- "extensions.checkCompatibility.20.0",
- "extensions.checkCompatibility.20.0a",
- "extensions.checkCompatibility.21.0",
- "extensions.checkCompatibility.21.0a",
- "extensions.checkCompatibility.22.0",
- "extensions.checkCompatibility.22.0a",
- "extensions.checkCompatibility.nightly"];
-
- var appInfo = Components.classes["@mozilla.org/xre/app-info;1"]
- .getService(Components.interfaces.nsIXULAppInfo);
- if (appInfo.name == "Thunderbird") {
- prefs = ["extensions.checkCompatibility",
- "extensions.checkCompatibility.3.0",
- "extensions.checkCompatibility.3.1p",
- "extensions.checkCompatibility.3.1pre",
- "extensions.checkCompatibility.3.1a",
- "extensions.checkCompatibility.3.1b",
- "extensions.checkCompatibility.3.1",
- "extensions.checkCompatibility.3.2a",
- "extensions.checkCompatibility.3.3a",
- "extensions.checkCompatibility.7.0a",
- "extensions.checkCompatibility.7.0b",
- "extensions.checkCompatibility.8.0",
- "extensions.checkCompatibility.8.0a",
- "extensions.checkCompatibility.9.0",
- "extensions.checkCompatibility.9.0a",
- "extensions.checkCompatibility.10.0",
- "extensions.checkCompatibility.10.0a",
- "extensions.checkCompatibility.11.0",
- "extensions.checkCompatibility.11.0a",
- "extensions.checkCompatibility.12.0",
- "extensions.checkCompatibility.12.0a",
- "extensions.checkCompatibility.13.0",
- "extensions.checkCompatibility.13.0a",
- "extensions.checkCompatibility.14.0",
- "extensions.checkCompatibility.14.0a",
- "extensions.checkCompatibility.15.0",
- "extensions.checkCompatibility.15.0a",
- "extensions.checkCompatibility.16.0",
- "extensions.checkCompatibility.16.0a",
- "extensions.checkCompatibility.17.0",
- "extensions.checkCompatibility.17.0a",
- "extensions.checkCompatibility.18.0",
- "extensions.checkCompatibility.18.0a",
- "extensions.checkCompatibility.19.0",
- "extensions.checkCompatibility.19.0a",
- "extensions.checkCompatibility.20.0",
- "extensions.checkCompatibility.20.0a",
- "extensions.checkCompatibility.21.0",
- "extensions.checkCompatibility.21.0a",
- "extensions.checkCompatibility.22.0",
- "extensions.checkCompatibility.22.0a",
- "extensions.checkCompatibility.nightly"];
+ setCompatPrefsHelper : function () {
+ let self = this;
+ let notifyObject = { restart: true };
+ function sendNotification(options) {
+ let { count } = options;
+ let startCount = count();
+ self.setCompatPrefs();
+ notifyObject.restart = startCount !== count();
+ self.obs.notifyObservers(null, "_nttACS", JSON.stringify(notifyObject));
}
- else if (appInfo.name == "SeaMonkey") {
- prefs = ["extensions.checkCompatibility",
- "extensions.checkCompatibility.2.0",
- "extensions.checkCompatibility.2.1p",
- "extensions.checkCompatibility.2.1pre",
- "extensions.checkCompatibility.2.1a",
- "extensions.checkCompatibility.2.1b",
- "extensions.checkCompatibility.2.1",
- "extensions.checkCompatibility.2.2a",
- "extensions.checkCompatibility.2.2b",
- "extensions.checkCompatibility.2.4a",
- "extensions.checkCompatibility.2.4b",
- "extensions.checkCompatibility.2.5",
- "extensions.checkCompatibility.2.5a",
- "extensions.checkCompatibility.2.6",
- "extensions.checkCompatibility.2.6a",
- "extensions.checkCompatibility.2.7",
- "extensions.checkCompatibility.2.7a",
- "extensions.checkCompatibility.2.8",
- "extensions.checkCompatibility.2.8a",
- "extensions.checkCompatibility.2.9",
- "extensions.checkCompatibility.2.9a",
- "extensions.checkCompatibility.2.10",
- "extensions.checkCompatibility.2.10a",
- "extensions.checkCompatibility.2.11",
- "extensions.checkCompatibility.2.11a",
- "extensions.checkCompatibility.2.12",
- "extensions.checkCompatibility.2.12a",
- "extensions.checkCompatibility.2.13",
- "extensions.checkCompatibility.2.13a",
- "extensions.checkCompatibility.2.14",
- "extensions.checkCompatibility.2.14a",
- "extensions.checkCompatibility.2.15",
- "extensions.checkCompatibility.2.15a",
- "extensions.checkCompatibility.2.16",
- "extensions.checkCompatibility.2.16a",
- "extensions.checkCompatibility.2.17",
- "extensions.checkCompatibility.2.17a",
- "extensions.checkCompatibility.2.18",
- "extensions.checkCompatibility.2.18a",
- "extensions.checkCompatibility.nightly"];
+ try {
+ Cu.import("resource://gre/modules/AddonManager.jsm");
+ AddonManager.getAddonsByTypes(null, function (aAddons) {
+ function count() {
+ return aAddons.filter(function isPendingAddon(aAddon) {
+ return (aAddon.pendingOperations & AddonManager.PENDING_ENABLE) != 0 ||
+ (aAddon.pendingOperations & AddonManager.PENDING_DISABLE) != 0
+ ;
+ }).length;
+ }
+ sendNotification({count: count});
+ });
+ } catch (e) {
+ // old extension manager API
+ let counter = 0;
+ function count() {
+ // Feel free to write the real count() for the old EM API,
+ // but now it's always returning a different number
+ return counter++;
+ }
+ sendNotification({count: count});
@whimboo Owner
whimboo added a note

So we always send a notification, right? We may want to condense both calls into a single one and put it after the try/catch.

@xabolcs Owner
xabolcs added a note

So we always send a notification, right?

Nope.
The first sendNotification is called async, the second is called in sync.
The common stuff - sendNotification - is already put before the try/catch.

@whimboo Owner
whimboo added a note

Ah, you are right. So that's fine then. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
}
- else if (appInfo.name == "Songbird") {
- prefs = ["extensions.checkCompatibility",
- "extensions.checkCompatibility.1.6",
- "extensions.checkCompatibility.1.7",
- "extensions.checkCompatibility.1.8",
- "extensions.checkCompatibility.1.9",
- "extensions.checkCompatibility.1.10",
- "extensions.checkCompatibility.1.11",
- "extensions.checkCompatibility.1.12",
- "extensions.checkCompatibility.2.0",
- "extensions.checkCompatibility.2.1",
- "extensions.checkCompatibility.2.2",
- "extensions.checkCompatibility.2.3",
- "extensions.checkCompatibility.2.4"];
+ },
+
+ setCompatPrefs : function () {
+ var prefs = [];
+
+ switch (this.appinfo.name) {
+ case "Songbird":
+ /**
+ * Excluding Songbird because it is based on Gecko 1.9.2
+ * and "extensions.checkCompatibility.nightly" preference
+ * introduced in Gecko 7.
@whimboo Owner
whimboo added a note

What about Firefox 3.6 you still want to support? It would have the same issue. Shouldn't we set the compatibility for 1.9.2 instead? There may be extensions which are disabled and the user still can't force to be enabled.

@whimboo Owner
whimboo added a note

Oh wait. The line is below. Forget about it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ *
+ * @see http://kb.mozillazine.org/Extensions.checkCompatibility
+ * @see http://www.oxymoronical.com/blog/2011/05/How-to-disable-extension-compatibility-checking-on-Nightly-builds-of-Firefox
+ */
+ break;
+ default:
+ prefs.push(PREF_CHECK_COMPAT_NIGHTLY);
+ break;
}
+ prefs.push(PREF_CHECK_COMPAT_PREFIX + this.version);
- var enable = !this.prefService.getBoolPref("nightly.disableCheckCompatibility");
- for(var i = 0; i < prefs.length; i++)
+ var enable = !this.prefService.getBoolPref(PREF_FORCE_COMPAT);
+ for (var i = 0; i < prefs.length; i++) {
this.prefService.setBoolPref(prefs[i], enable);
+ }
}
};
Something went wrong with that request. Please try again.