Services.jsm
I just landed the patch for bug 512784 on mozilla-central. It adds a new module to the toolkit whose sole purpose is to expose memoized getters for common XPCOM services on a simple “Services” JS object. The first pass involved adding getters for the prefs service, observer service, window mediator, permission manager, IO Service, prompt service, and search service. This patch also updates Firefox’s browser.js to make use of the module, which means that trunk-based extensions that run code in Firefox chrome windows can start making use of it if they’d like.
Here’s an example of one of the changes:
+// Services = object with smart getters for common XPCOM services
+Components.utils.import("resource://gre/modules/Services.jsm");
function getTopWin()
{
- var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1']
- .getService(Components.interfaces.nsIWindowMediator);
- return windowManager.getMostRecentWindow("navigator:browser");
+ return Services.wm.getMostRecentWindow("navigator:browser");
}
I expect to add some other services to it as I look at expanding use of the module (Mossop has some suggestions in the bug). We might also add an equivalent in Firefox for browser-specific services, if that proves to be useful. The end goal is to remove a lot of the XPCOM boilerplate junk we see spread around our front-end JS code, and a side benefit is the reduction of unnecessary getService() calls for services that are already guaranteed to be otherwise instantiated and kept around for the app’s lifetime. This necessarily implies that JS scopes where the module was imported will now have permanent references to services after their first use, which is worth keeping in mind, both when making use of of the module and when adding additional getters to it.
glandium said,
February 25, 2010 @ 4:23 pm
Finally !
Robert Kaiser said,
February 26, 2010 @ 8:28 am
Gavin already knows, but for any other readers I’d like to point out that 1) this is in toolkit so any Mozilla application can use it and 2) https://bugzilla.mozilla.org/show_bug.cgi?id=548715 is working on starting to use it in SeaMonkey.
AndersH said,
February 27, 2010 @ 2:37 am
Would it be silly to use something like __noSuchMethod__ to add the shorthand for all (or most) classes at once. Also this way the new names are guessable and documented since they are the same as the old. Pseudo-code (I hope it doesn’t turn up to garbled):
var Services = {
__noSuchMethod__: function(id, args) {
var cName = id.replace(/([A-Z])/, “-$1″).toLowerCase();
var iName = “nsI” + id.substring(0, 1).toUpperCase() + id.substring(1);
var c = Components.classes['@mozilla.org/appshell/" + cName + ";1'];
var i = Components.interfaces[iName];
return c.getService(i);
}
}
function getTopWin() {
return Services.windowMediator().getMostRecentWindow(“navigator:browser”);
}
AndersH said,
February 27, 2010 @ 2:23 pm
Sorry, I overlooked the “appshell” part. And doing something like …appshell$windowMediator() will probably be to long.
Home of KaiRo: Weekly Status Report, W08/2010 said,
March 1, 2010 @ 11:37 am
[...] pass of that but needs some answers from places developers as well to get in.Services.jsm: Gavin introduced Services.jsm to toolkit this week, and as I think this is a very welcome improvement for reducing code [...]
Gavin’s blog » browser.js cleanup ideas said,
March 30, 2010 @ 9:01 am
[...] it up has been brought up several times in the past. We have made some changes that help – Services.jsm landed recently and helps reduce some of the XPCOM boilerplate overhead (though there’s a [...]
Taras’ Blog » Blog Archive » mozilla::services said,
April 20, 2010 @ 2:20 pm
[...] landed the mozilla::services bug around the same time as Gavin announced the Services.jsm equivalent. Services.jsm came a pleasant surprise to me, it’s nice to have [...]