Firefox 3 – Web Protocol Handlers

Web protocol handlers are a new Firefox 3 feature that gives more power to RIA web applications. Basically, when a user clicks on a link with specific protocol, Firefox can send an HTTP(S) request with the link data to a web application. An easy example is a mailto: link:


Web Master

Normally, if a user clicks this link, Firefox (or other browser) will open the default mail application on the user’s machine and start composing an email message. With so many web-based email applications in use today, it only seems natural that some people would want to use a web-based email application to compose the message.

With web protocol handlers, the web application can register the specific protocol it wants to handle. Firefox will then prompt the user to choose which of the registered applications (web or desktop) it should use to handle the action. Any protocol, real or imaginary, can be used – mailto: is only one example, webcal:, tel: and fax: are others. In the case of the mailto: example, the web-based email application could parse the data passed to it from Firefox to get the parameters of the protocol, perform a sign-on (if needed) and display its “compose” UI.

Firefox 3 will ship with some packaged web protocol handlers. For those developers interested in adding protocol support to their web applications, we have an MDC article explaining the details of setting up and using web protocol handlers. Also checkout the compliance test page we use to test the feature. During the process of getting the packaged handlers into Firefox 3, we ran into some common implementation misconceptions:

  • Web protocol handlers are not just for mailto:! The system is designed for any protocol.
  • Web protocol handlers have no idea about the protocol details. For example, the system does not know that mailto: support to or subject parameters. The system just sends the entire HREF of the link to the registered handler. Be prepared to do the parsing yourself.

Go forth and make web applications rock!

JS-CTYPES Status

Unfortunately, the js-ctypes project got back-burnered for a while. Fortunately, some great contributors swooped in and landed some really nice bits. Fredrik Larsson helped out on some Linux problems (bug 416119), filled in ANSI string support (bug 416229) and setup an xpcshell test framework (bug 427286).

The Atul Varma came to my rescue by adding support for OS X and fixing a small bug (bug 429063). Atul also added build instructions to the wiki. Brahmana found a bug too and posted a patch (bug 413783).

We are getting pretty close to a usable library. The next step is struct support. The current plan is to do something like this:


// define the struct
var POINT = [{"x": INT32}, {"y": INT32}];

// use the struct when declaring the function call
var pointsEqual = library.declare("PointsEqual", STDCALL, BOOLEAN, POINT, POINT);

// initialize objects that looks like POINT
var pt1 = {"x": 10, "y": 20};
var pt2 = {"x": 20, "y": 20};
var result = pointsEqual(pt1, pt2);

// "result" should be false :)

The wiki page has bugzilla and SVN information too. Feedback welcome. Patches welcome!

Extension Developers – Breaking News, Part 2

If you have an extension that uses mozIJSSubScriptLoader (a mouthful, I know) then you should be aware of a recent change (bug 418356). The mozIJSSubScriptLoader interface can be used from JS to load and run JavaScript code from the given URL at run-time. Previously, the URL could be chrome:, file:, data: or resource:, but due to a security fix, the URL is now limited to chrome: only.

Therefore, this will no longer work:

var obj = {};
var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
                       .getService(Components.interfaces.mozIJSSubScriptLoader);
loader.loadSubScript("file:///blah.js", obj)

Instead, try moving the JS file into a chrome area and use chrome: or you can try to refactor your code to use Components.utils.import and a resource: URL. Firefox 3 has new ways for extensions to define resource: aliases in chrome manifests, which will make the refactor easier.

Components.utils.import("resource://myext/modules/blah.jsm");

Let me know if there is a reason this change or workaround is completely unacceptable to you.

Mozilla 2 – The Future of the Mozilla Platform

Firefox 3 is not even out the door, but work has started on the next refactoring of the Mozilla platform. Dubbed Mozilla 2 (FF3 is built on Mozilla 1.9), it is a chance to make lots of interesting, even scary, changes to the platform. For some background on Mozilla 2 go back and read Brendan’s post. Also, read the Mozilla 2 wiki pages.

Actually, lots of work has already been completed and lots more work is underway. Checkout the notes from the status meetings. You can call in every Wednesday to hear what’s happening. The work on ActionMonkey and XPCOMGC is pretty exciting stuff (for geeks, I know).

Another of the more exciting goals of Mozilla 2 is the move to use more JavaScript and less C++. Yes, C++ is great for those times you really need it (performance & native APIs), but JavaScript can handle many things better, easier and without a compiler. Mozilla 2 is adding a lot of improvements to JavaScript as well, making it faster too.

Less C++ is really part of the “Less Binary Code” theme of Mozilla 2. Another part of that theme is reducing our XPCOM footprint. Benjamin Smedberg recently posted some information about goals for XPCOM in Mozilla 2 to the Wiki and Newsgroup. See Benjamin’s older post on XPCOM changes too. I encourage any extension, embedders and XUL application developers who use binary code to go and read the information.

Extension Developers – Native JSON Parsing

Firefox 3 is using JSON to store data in several places – such as bookmark backups, session restore, and offline manifests. Originally, JSON parsing was scattered through the code. Then it was consolidated to JSON.jsm, a JavaScript code module. Eventually, it was converted into nsIJSON.idl, a C++ XPCOM Component. What does this mean to extension and application developers? Well, you now have access to JSON encoding and decoding routines that can be a lot faster (more in a bit) than the JavaScript counterparts.

var testObj - { name: "Jimmy", age: 25, loves: ["XULRunner", "sunrises", "Mt Dew"] };

// encode to string using javascript implementation
Components.utils.import("resource://gre/modules/json.jsm");
var testJS = JSON.toString(testObj);

// encode to string using native implementation
var Ci = Components.interfaces;
var Cc = Components.classes;

var nativeJSON = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
var testNative = nativeJSON.encode(testObj);

Of course, you can also encode to a string using the json2.js code at json.org

I put together a little benchmark (on bug 410890) to get a feel for the speed improvements that could be obtained using native JSON parsing. The code iterates over a fixed chunk of JSON (taken from Robert Sayre’s unit tests) multiple times. The number of iterations are on the x-axis while the milliseconds required are on the y-axis:

Encoding
json-object-encode.png

Decoding
json-object-decode.png

I found that John Resig did some JSON benchmarking last year, so I made a second benchmark script (same bug) that used his 1600 item array as the JSON source. This code takes the 1600 item array and breaks it into variable sized chunks, then sends those different sized chunks into the JSON parsers. The chunk size is on the x-axis while the milliseconds required are on the y-axis:

Encoding
json-array-encode.png

Decoding
json-array-decode.png

The tests show a very nice performance improvement for encoding JavaScript objects to JSON data. The performance improvements for decoding JSON data into JavaScript objects is smaller, but still very worthwhile. For the curious, the original native JSON code was further optimized to increase the improvements.

Note: Currently, native JSON is only available to privileged code with access to XPCOM. This means that web content JavaScript is not yet able to access the feature. Working is moving ahead in this bug to get these APIs exposed to web content as well. Exposing APIs to web content is something that needs to be thought out and perhaps standardized. There was a proposal to add JSON encoding/decoding to ES4, which seems to have been dropped. Maybe the WHAT WG will draft something.

Check out John Resig’s post on the State of JSON for lots more information on JSON, web content and standards.

Extension Developers – More On Updating

We have been putting out the call for extension developers to start the process of updating their extension to workin Firefox 3. It’s never fun when your extension breaks because of changes in Firefox, but everyone wants to make the platform better. In doing so, we had to break some eggs.

On the bright side, extension developers seem to be really charging ahead full steam. In addition to finding signs of extension update work being done on developer websites, #extdev on Mozilla IRC has been pretty active. I have also noticed posts on Mozillazine forums too.

I thought I’d list a few issues I have seen come up during update discussions:

  • event.preventBubble() has been removed in Firefox 3. It was deprecated in Firefox 2 and code should be using event.stopPropagation(), which also works in Firefox 2.
  • Using window.addEventListener("load", myFunc, true) to listen for web content page loads does not work anymore. Changes were made to improve security and this was fallout from those changes. You should be using gBrowser.addEventListener("load", myFunc, true) anyway. Listening for “load” events on the Firefox main window is a bit overkill. Listening for the event on the tabbed browser makes more sense and works (in Firefox 2 as well).
  • The XUL popup system (popup, menupopup & tooltip) has been significantly overhauled in Firefox 3. Some methods were deprecated (showPopup), some were added (openPopup & openPopupAtScreen) and a whole new type of popup was added (panel). See the new Popup Guide for more information.

There is a wiki page listing a bunch of stuff extension developers should consider or to watch when updating. If you find something, add it to the list.

One of the other benefits of updating early is the potential for helping us find Firefox bugs. We recently had an extension fail to update to Firefox 3 for no apparent reason. It was doing nothing different than when running in Firefox 2 and didn’t seem to hit any of the other know update issues.

Turns out, the extension adds a utility method to the Array prototype which worked fine in Firefox 2, but caused weird exceptions in Firefox 3. The exception ocurred in places where Firefox 3 added uses of for each on Arrays, which is a no-no. The problem didn’t show up in any tests because Firefox 3 doesn’t add anything to the Array prototype. We are fixing this in Firefox, but it could happen to other extensions if they use for each on Arrays. Perhaps the best advice is to always be defensive when dealing with things that could pollute the global namespace – shared by Firefox and all of its extensions.

JavaScript Code Modules

XPCOM – It’s a place most XUL application and extension developers would rather avoid. There are times when XPCOM components are needed and developers have to bite-the-bullet. A few examples are commandline handlers, autocomplete implementations and the new custom query processors for XUL templates. If you’re lucky, you can use JavaScript to implement the XPCOM component.

Another very common use case in extensions is sharing data across browser windows. Technically, a JavaScript XPCOM component is the right way to go. But yeah, it’s XPCOM.

Well, Firefox 3 (Gecko 1.9) offers a new, simple, non-XPCOM method of sharing data: JavaScript Code Modules. Of course, you can use JS modules for lots of other purposes too. Check it out using a Firefox 3 beta or a nightly XUL Runner.

New Datasources for XUL Templating [Part 3]

I have talked a bit about the new built-in datasources (XML and SQL) developers can use with XUL templating (guide and tutorial). I wanted to wrapup my little foray into XUL template datasources by also talking about custom datasources.

A generic framework for adding any kind of datasource (bug 321170) was created as part of the work to make the new XML and SQL datasources. Creating a custom datasource involves implementing 2 new XPCOM interfaces: nsIXULTemplateQueryProcessor and nsIXULTemplateResult.

With the help of Peter van Hardenberg (of Songbird), I got a simple JavaScript implementation working and available on MDC. The sample is fairly basic, but you could extend it to expose any kind of backend datasource.

I Call Shenanigans!

Zoho’s recent blog post about why they used JavaScript and not Flash when building their offline version of Zoho Writer has led to some interesting but somewhat predictable responses [1] & [2]. I could have fallen into a predictable (but not necessarily interesting) response myself, but didn’t. Until I saw Ryan Stewart post the following:

I don’t think it’s an accident that Zoho and Buzzword have such different design goals or that Flex applications generally tend to look more sophisticated than Ajax applications.

That quote (and the post) seem to suggest that AJAX webapps are less usable, less sophisticated and, generally, not as pretty as their Flex counterparts. Likely not Ryan’s intent and I did say “seem to suggest” right? I usually don’t define usability based on how an application looks, but on how productive I am using the application or how easy I can learn the application. Unfortunately, some applications try to get by on looks alone. I try to see the inner beauty.

Animating with Canvas

has been supported on most browsers (and emulated on others) for a while now. Web developers have done some pretty cool stuff with – from niffty reflections to very cool charting [1] & [2] to UIs. Recently, I have noticed a few examples of using to create animations. The results are pretty amazing and don’t seem to kill my CPU in the process:

  • John Resig’s processing demos [1] & [2] (I hope these get published soon)
  • Canvas Animation Kit Experiment [blog] & [demo]

And now we are getting 3D canvas too (Firefox and Opera). Sweet.

What’s it going to take to get this simple bitmap buffer into Internet Explorer?