Skip navigation

Monthly Archives: September 2009

We’ve recently added two new API’s on XPCOMUtils that make a common coding pattern simpler to do. It is quite common to have “smart getters” to store a reference to a service that you use in JavaScript. Normally, folks write code that looks something like this:

this.__defineGetter__("_ioService", function() {
  delete this._ioService;
  return this._ioService = Components.classes[";1"].

That gets long and verbose if you have any more than a few of these getters. The new approach looks like this:

XPCOMUtils.defineLazyServiceGetter(this, "_ioService",

The net result is a lot less boilerplate code, which, in my opinion, is a lot nicer to read. I’ve already converted the toolkit code in the Places module over, and the resulting code is much nicer.

Sometimes, however, you want to have a getter for something that is not a service. That’s where the second API comes in. You can pass in a lambda function that will be called when the value is needed for the first time. From then on, the value is cached. Some old code may look something like this:

this.__defineGetter__("_db", function() {
  delete this._db;
  return this._db = Components.classes[";1"].

With the new API, that code turns into this:

XPCOMUtils.defineLazyGetter(this, "_db", function() {
  return Components.classes[";1"].

Again, much nicer looking! If you are interested, the implementation of these methods can be found here.

Did you know about the handy NetUtil object available when you import NetUtil.jsm? I bet you didn’t since it’s fairly new! There’s no MDC page yet, but the API is getting even better. Bug 508902 added a new method on NetUtil to create nsIURI objects. NetUtil will cache the IO Service so the calling site doesn’t have to. As more code starts to use this, fewer objects will have to cache the IO Service themselves.

The API mirrors nsIOService‘s newURI method with one minor improvement; the last two arguments are optional. Most callers in JavaScript tend to pass null for those last two arguments anyway, but when using NetUtil.newURI, they just have to pass the spec which should be easier.

New JavaScript code that needs to create nsIURI objects should start using this method.

When we landed the asynchronous location bar, some people started to see substantially slower results. This was alarming since it was supposed to end up speeding or staying the same for everyone. After some investigation, we realized that the AutoComplete code was doing something very dumb with asynchronous searches. The problem was that the code would not actually handle the user pressing the enter key until the next set of results came in. Not only did this result in slower processing of the user’s selection, it also meant that weird race conditions would come up such as up opening a new tab, pasting a url in, press enter, and then switch tabs resulting in the reloading of the page that was just switched to. In other words, epic fail all around.

Luckily, the fix was trivial. Now we handle the enter keypress immediately when the user hits it, and not later. Problem solved :)