Talk about add-ons and extension development.
irshad
Posts: 6Joined: September 8th, 2005, 5:53 am
March 8th, 2006, 7:44 am
Posted March 8th, 2006, 7:44 am
How can i get notified if a user changes some preferences for my extension throught the about:config page ???
TIA
old Captain Caveman
Posts: 0Joined: December 31st, 1969, 5:00 pm
March 8th, 2006, 8:11 am
Posted March 8th, 2006, 8:11 am
By using a pref observer in your pref service, quick sample:
- Code: Select all
const MyPrefObserver = { observe: function(subject, topic, prefName) { if (topic == "nsPref:changed" && prefName == "extensions.somepref") { //Do your thing... } } }; var oPrefService = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranchInternal); oPrefService.addObserver("extensions.somepref", MyPrefObserver, false);
Enjoy!
irshad
Posts: 6Joined: September 8th, 2005, 5:53 am
March 8th, 2006, 8:41 am
Posted March 8th, 2006, 8:41 am
Thanks Captain Caveman for your fast reply.
I understand that nsIPrefBranchInternal has been renamed to nsIPrefBranch2 in Gecko 1.8. So should i be using it in extension for newer versions of firefox ???
I found this code through google at http://kb.mozillazine.org/Dev_:_Using_preferences
- Code: Select all
var myPrefObserver = { register: function() { var prefService = Components.classes["@mozilla.org/preferences-service;1"] .getService(Components.interfaces.nsIPrefService); this._branch = prefService.getBranch("extensions.myextension."); this._branch.QueryInterface(Components.interfaces.nsIPrefBranch2); this._branch.addObserver("", this, false); },
unregister: function() { if(!this._branch) return; this._branch.removeObserver("", this); },
observe: function(aSubject, aTopic, aData) { if(aTopic != "nsPref:changed") return; // aSubject is the nsIPrefBranch we're observing (after appropriate QI) // aData is the name of the pref that's been changed (relative to aSubject) switch (aData) { case "pref1": // extensions.myextension.pref1 was changed break; case "pref2": // extensions.myextension.pref2 was changed break; } } } myPrefListener.register();
Its pretty much similar to your code. Can you explain the significance of the third argument(the boolean one) to the call addObserver(). Why is there a call like - Code: Select all
this._branch.QueryInterface(Components.interfaces.nsIPrefBranch2);
What exactly does QueryInterface() do ???
old Captain Caveman
Posts: 0Joined: December 31st, 1969, 5:00 pm
March 8th, 2006, 9:14 am
Posted March 8th, 2006, 9:14 am
That's a lot of questions! I'll try to answer them, but I'm not sure if I have already learned enough to realy know/understand this all correctly.
1. Sorry, you should indeed start using nsIPrefBranch2
nsIPrefBranchInternal IID: d1d412d9-15d6-4a6a-9533-b949dc175ff5 Inherits From: nsIPrefBranch2 Status: NON-FROZEN interface WHICH WILL PROBABLY GO AWAY.
An empty interface to provide backwards compatibility for existing code that bsmedberg didn't want to break all at once. Don't use me!
2. AFAIK a weak-reference means that the reference does not prevent a garbage collector (internal memory cleanup) to destroy the referenced object. a strong one does prevent that. But I do not know what the consequences of these are in a Firefox extension. I always hold a strong reference, cause that would be "safer"
3. nsIPrefService.getBranch() returns a nsIPrefBranch, with QueryInterface you can cast it to another interface that inherits from it.
Hope this helps/informs you a bit, and also that I did not say too many stupid/n00blike things for all the real developers over here.
irshad
Posts: 6Joined: September 8th, 2005, 5:53 am
March 8th, 2006, 11:13 am
Posted March 8th, 2006, 11:13 am
Thank you once again... Its working well n fine...
Philip Chee

Posts: 4294Joined: March 1st, 2005, 3:03 pm
March 9th, 2006, 10:15 am
Posted March 9th, 2006, 10:15 am
- Code: Select all
register: function() { var prefService = Components.classes["@mozilla.org/preferences-service;1"] .getService(Components.interfaces.nsIPrefService); this._branch = prefService.getBranch("extensions.myextension."); this._branch.QueryInterface(Components.interfaces.nsIPrefBranch2); this._branch.addObserver("", this, false); },
In the call to getBranch() if I use anything except an empty string (i.e. ""), my pref observer is never called.
Anybody know why? No errors in the JS/Error consoles.
Phil
old Captain Caveman
Posts: 0Joined: December 31st, 1969, 5:00 pm
March 9th, 2006, 1:06 pm
Posted March 9th, 2006, 1:06 pm
Not sure if I understand your problem Philip, but shouldn't you pass the domain you want to observe in the call to addObserver?
So this one listens to a change in somepref of your extension:
- Code: Select all
register: function() { var prefService = Components.classes["@mozilla.org/preferences-service;1"] .getService(Components.interfaces.nsIPrefService); this._branch = prefService.getBranch("extensions.myextension."); this._branch.QueryInterface(Components.interfaces.nsIPrefBranch2); this._branch.addObserver("extensions.myextension.somepref", this, false); },
Philip Chee

Posts: 4294Joined: March 1st, 2005, 3:03 pm
March 9th, 2006, 8:15 pm
Posted March 9th, 2006, 8:15 pm
I want to listen for changes to several perferences e.g. "extensions.xsidebar.webpanel.*" so following the example given I used: - Code: Select all
register: function() { var prefService = Components.classes["@mozilla.org/preferences-service;1"] .getService(Components.interfaces.nsIPrefService); this._branch = prefService.getBranch("extensions.myextension."); this._branch.QueryInterface(Components.interfaces.nsIPrefBranch2); this._branch.addObserver("", this, false); },
but my observer is never called despite listening to "" which should return all pref changes. So now I'm using - Code: Select all
prefBranch : Components.classes["@mozilla.org/preferences-service;1"] .getService(Components.interfaces.nsIPrefService) .QueryInterface(Components.interfaces.nsIPrefBranchInternal),
prefObserver : { observe: function(subject, topic, data) { // subject is the nsIPrefBranch we're observing (after appropriate QI) // data is the name of the pref that's been changed (relative to subject) dump("\nxsbPrefObserver-topic:"+topic); dump("\nxsbPrefObserver-subject:"+subject); dump("\nxsbPrefObserver-data:"+data); if(topic == "nsPref:changed") xsbWebPanel.initSettings(); } },
addPrefObserver : function () { dump("\nxsbPrefObserver: adding\n"); xsbWebPanel.prefBranch.addObserver("extensions.xsidebar.webpanel.", xsbWebPanel.prefObserver, false); },
Now this works but the data parameter returned by the observer is the full pref string and not
the part to the right of "extensions.xsidebar.webpanel."
Phil
old Captain Caveman
Posts: 0Joined: December 31st, 1969, 5:00 pm
March 10th, 2006, 3:49 am
Posted March 10th, 2006, 3:49 am
That is all "by design" I believe. You can't listen to all pref changes, and the observer's data param will hold the complete pref that has changed.
void addObserver ( char* domain , nsIObserver observer , PRBool holdWeak )
Add a preference change observer. On preference changes, the following arguments will be passed to the nsIObserver.observe() method: subject - The nsIPrefBranch object (this) topic - The string defined by NS_PREFBRANCH_PREFCHANGE_TOPIC_ID data - The preference which has changed
Arguments: domain: The preference on which to listen for changes. This can be the name of an entire branch to observe. e.g. Holding the "root" prefbranch and calling addObserver("foo.bar.", ...) will observe changes to foo.bar.baz and foo.bar.bzip observer: The object to be notified if the preference changes. holdWeak: true Hold a weak reference to |observer|. The object must implement the nsISupportsWeakReference interface or this will fail. false Hold a strong reference to |observer|.
Why is that a problem? Though it might be a bit slower, you could just do a data.replace('extensions.xsidebar.webpanel.', '') to get just the pref.
Philip Chee

Posts: 4294Joined: March 1st, 2005, 3:03 pm
March 10th, 2006, 4:17 am
Posted March 10th, 2006, 4:17 am
Captain Caveman wrote:Why is that a problem? Though it might be a bit slower, you could just do a data.replace('extensions.xsidebar.webpanel.', '') to get just the pref.
It's not a problem. It's just that the code in the KB article implies that it should work otherwise.
Phil
old Captain Caveman
Posts: 0Joined: December 31st, 1969, 5:00 pm
March 10th, 2006, 5:45 am
Posted March 10th, 2006, 5:45 am
Than that's probably the reason why the author of it added this line
Here's an example (note, this code hasn't actually been tested, so it may contain typos and other errors):
asqueella
Posts: 3996Joined: November 16th, 2003, 3:05 amLocation: Russia, Moscow
March 12th, 2006, 7:30 pm
Posted March 12th, 2006, 7:30 pm
That code works fine for me. aData is relative to the aSubject. You can remove the "untested" warning.
Re: weak references, if you use a strong reference, you must remember to unregister the observer on window unload, otherwise the window will leak. I think weak reference would work fine, since the observer is referenced by the window, and therefore will not be destroyed until the window is closed.
Philip Chee

Posts: 4294Joined: March 1st, 2005, 3:03 pm
March 12th, 2006, 8:07 pm
Posted March 12th, 2006, 8:07 pm
My observer isn't called at all (as far as my dump statements indicate) if I use .getBranch()
with anything other than an empty string (""). Why is this?
Phil
asqueella
Posts: 3996Joined: November 16th, 2003, 3:05 amLocation: Russia, Moscow
March 13th, 2006, 12:20 pm
Posted March 13th, 2006, 12:20 pm
Post the testcase.
Philip Chee

Posts: 4294Joined: March 1st, 2005, 3:03 pm
March 14th, 2006, 3:28 am
Posted March 14th, 2006, 3:28 am
Sorry, as I said I rewrote my code since. I might try to recreate the problem when I have time.
Phil
Return to Extension Development
Who is online
Users browsing this forum: No registered users and 1 guest
|