Advanced Topics in Jaxer

__noSuchMethod__

By default, an attempt to call a method that doesn't exist on an object results in a TypeError being thrown. This behavior can be avoided by defining a function at that object's __noSuchMethod__ member. The function attached will be invoked with two arguments, the name of the method called and an array of the arguments passed in the method call.

The default Mozilla implementation omits allowing this to happen on the anonymous global (window) object so while a call to the method in the window namespace (e.g., window.foo()) would be trapped by the __noSuchMethod__ handler the same function accessed without the window prefix (e.g., foo()) would not. Since both calls are referring to the same global object this is an unintuitive result.

Jaxer repairs this core JavaScript behavior by making the anonymous global also trigger the __noSuchMethod__ handler if defined. This was used, to give a real world example, to develop the autoloading component of the ActiveJS framework.

To demonstrate the difference between the old and new handling of missing methods, the sample below shows different results when the handler is triggered by server code (new behavior) versus client code (old behavior). The second method call on the client results in an exception, whereas both calls are trapped by the handler on the server side. The try/catch blocks avoid messy browser exceptions.

Note: The following sample will only work in Firefox as it illustrates in the feature between the Jaxer and Mozilla engines.

Using the global __noSuchMethod__ handler

Result of running the __noSuchMethod__ example

Result of running the __noSuchMethod__ example

Jaxer Extensions

Jaxer is built with a simple method for adding your own capabilities to the core Jaxer object, extensions. An extension is written in JavaScript, in a file stored in the local_jaxer/extensions folder, which gets loaded when Jaxer starts up. The functionality can be anything you like but should be structured using the Module pattern developed by Douglas Crockford, which is well explained in a post on the Yahoo! User Interface blog by Eric Miraglia. The pattern basically is a method for keeping all information contained within the module's scope.

The simplest extension would look like this:

(function(){
  Jaxer.MyProp = 'hey I extended Jaxer !!!';
})();

Jaxer ships with a sample extension, jaxer/framework/extensions/sampleExtension.js, which will record the scripts loaded by your applications. As shipped the extension is disabled by having the first line return, so to see it in action you need to comment out that line, restart Jaxer and then run through your application.

Looking at the sample extension's code, in the next block, note that the key work is done in the onLoad and onUnload event handlers. The two functions add and remove, respectively, the actual functions which the extension use to do the heavy lifting by calling CoreEvents.addHandler() and CoreEvents.removeHandler().

Record page and script requests with a Jaxer extension