Opening a Link in the Default Browser

XULRunner applications may have situation where they wish to open a URI in the default browser. This will often be an HTTP or HTTPS URI, but can use any scheme for which an external handler exists. This can be done using the nsIExternalProtocolService interface:

// first construct an nsIURI object using the ioservice
var ioservice = Components.classes["@mozilla.org/network/io-service;1"]
                          .getService(Components.interfaces.nsIIOService);

var uriToOpen = ioservice.newURI("http://www.example.com/", null, null);

var extps = Components.classes["@mozilla.org/uriloader/external-protocol-service;1"]
                      .getService(Components.interfaces.nsIExternalProtocolService);

// now, open it!
extps.loadURI(uriToOpen, null);

By default, the external protocol service will warn the user about opening the link in another application. To suppress this warning for particular protocols that are safe to open in the default application, you must set default prefs (Thunderbird sets the following prefs):

// suppress external-load warning for standard browser schemes
pref("network.protocol-handler.warn-external.http", false);
pref("network.protocol-handler.warn-external.https", false);
pref("network.protocol-handler.warn-external.ftp", false);

You can also check whether an external handler for a scheme exists. This is how you do it:

var extps = Components.classes["@mozilla.org/uriloader/external-protocol-service;1"]
                      .getService(Components.interfaces.nsIExternalProtocolService);
if (extps.externalProtocolHandlerExists("http")) {
  // Handler for http:// URLs exists
}

To enable a link inside an html document that is the "src" of an iframe to be opened in the default browser, setting the preference:

pref("network.protocol-handler.expose-all", false);

seems to work.