Brain Flush

February 29, 2008

Firefox 3 Claims Huge Performance Boost in JavaScript Runtime

As posted recently on Cybernet News, a profile-guided optimization build of the upcoming version 3 of the Firefox Web browser has appeared which performs the SunSpider JavaScript Benchmark in only one third of the time required by Firefox 2.0.0.12.

This sounds great at first, but if you take a closer look, you see that this benchmark for example does not take DOM operations into account. AJAX heavy websites however basically evolve around modifying a page’s DOM tree at runtime, which can quickly become the major bottle neck when requesting and re-rendering large amounts of data.

Instead of focusing on DOM operations, the benchmark runs exotic tests like 3D raytracing and cryptographic calculations which do not seem to be typical use cases for Web 2.0 content.

For my part, I remain skeptical, although I would of course welcome performance improvements in any part of Firefox in upcoming releases.

January 18, 2008

Integrating Direct Web Remoting (DWR) in Mozilla Thunderbird

Direct Web Remoting, or DWR for short, is a Web technology for exposing server-side Java interfaces via a dynamically generated JavaScript API. A specific Servlet will translate incoming JavaScript calls to their Java equivalents which makes integration of applications programmed in client-side JavaScript with Web applications written in server-side Java a no-brainer.

DWR calls are typically dispatched from a JavaScript/JScript program running in a Web browser such as Mozilla Firefox or Microsoft’s Internet Explorer, but since all Mozilla products are built upon the Gecko layout engine and XUL (which are programmed using JavaScript modules), you can leverage DWR to dispatch remote calls from e.g. a Mozilla Thunderbird extension just as easily. Integrating DWR into a XUL based extension is actually pretty straight forward, but there are couple of subtleties to be aware of.

I will hereafter assume that a Web application called ‘MyWebApp’ has been deployed on localhost port 8080, that it’s up and running, that it exposes an interface called ‘MyService’ via DWR. Refer to the DWR documentation if you are unsure how to do that. It is further assumed that the DWR servlet is reached at dwr/ relative to the base URL. All following code examples refer to DWR version 1.1, which unfortunately has already been superseded by version 2.x at the time of this writing. If required at all, changing the code to run with newer versions of DWR should be easy enough however.

In order for your XUL component to be able to access `MyService’, add the following lines to your XUL file (e.g. myOverlay.xul):

<script type="application/x-javascript"
    src="http://localhost:8080/MyWebApp/dwr/engine.js"/>

<script type="application/x-javascript"
    src="http://localhost:8080/MyWebApp/dwr/util.js"/>

<script type="application/x-javascript"
    src="http://localhost:8080/MyWebApp/dwr/interface/MyService.js"/>

Don’t go looking for MyService.js in your file system, it’s not there. DWR will take care of dynamically creating it once your client requests it from the server. You can find both engine.js and util.js in the dwr.jar file which should reside at WEB-INF/lib of your deployed Web application.

Now you’re already prepared to invoke your service. However, when run outside a Web browser, as is the case with e.g. a Thunderbird extension, there is a catch: DWR won’t correctly resolve the target URL for your server, because it operates on relative URLs by default. You can fix that problem by modifying the MyService._path variable, which was auto-generated by DWR. Ponder the example program below, which invokes MyService.service() from a JavaScript program running in a Thunderbird extension:

function callService() {

    MyService._path = "http://localhost:8080/MyWebApp/dwr";

    MyService.service({
        callback: function(returnData) {
            // perform logic
        },

        errorHandler: function(error) {
            // handle error
        }
    });
}

That’s it basically; of course you may want to add additional call variables or use another invocation style altogether, but you get the idea.

January 17, 2008

Mozilla Thunderbird Extension Development – Environment Setup

It took me a while to setup my Thunderbird installation in order to make it ready for convenient extension development, by which I mean having all the tools and configuration in place. So I thought I’d share the most useful steps you want to perform in order to make your life easier.

You should basically do two things: One, reconfigure Thunderbird to be more developer-friendly, and two, install some cool extensions.

First, I recommend installing the following plugins:

  1. ChromEdit Plus – allows for easy access to your configuration files. Works in Firefox, too.
  2. Venkman – A JavaScript debugger. Must have. For Firefox, I recommend Firebug instead.
  3. Console² – An advanced error console. Can interpret JavaScript commands on-the-fly.
  4. Chrome List – Lets you inspect chrome packages of all installed components. It’s somewhat buggy for me though, sometimes the contents of XUL files are not displayed in the viewer.

With these plugins installed, you already have a solid basis to built your hacking on.

Now to the configuration. You can do this with ChromEdit now, or if you haven’t installed it, fall back to your favorite text editor. Open the ChromEdit Plus menu, select ChromEdit and navigate to the ‘user.js’ tab. From here you can edit your ‘user.js’ file located in your profile folder (on Linux, it’s in your home directory, on Windows, it’s in ‘Documents and Settings/<username>/Application Data/Thunderbird/Profiles/<long_UUID>’ ). If it does not yet exist, and it doesn’t by default, go ahead and create it). Add the following lines (it’s a JavaScript file, so it’s simply JavaScript syntax):

user_pref(“javascript.options.showInConsole”, true);
user_pref(“nglayout.debug.disable_xul_cache”, true);
user_pref(“browser.dom.window.dump.enabled”, true);
user_pref(“javascript.options.strict”, true);

The following explanations are taken from the MDC:

  • javascript.options.showInConsole = true. Logs errors in chrome files to the Error Console.
  • nglayout.debug.disable_xul_cache = true. Disables the XUL cache so that changes to windows and dialogs do not require a restart. This assumes you’re using directories rather than JARs. Changes to XUL overlays will still require reloading of the document overlaid.
  • browser.dom.window.dump.enabled = true. Enables the use of the dump() statement to print to the standard console. See window.dump for more info. You can also use nsIConsoleService from privileged script.
  • javascript.options.strict = true. Enables strict JavaScript warnings in the Error Console. Note that since many people have this setting turned off when developing, you will see lots of warnings for problems with their code in addition to warnings for your own extension. You can filter those with Console2.

In order for the Thunderbird standard console to appear, run Thunderbird with the ‘-console’ command line argument. The dumped statements won’t appear in Console² though.

You may also want to refer to Setting up extension development environment on MDC as a primer, I particularly recommend the steps outlined for externalizing your development files into a separate folder, so you won`t have to reinstall the plugin each time you change a line of code.

December 8, 2007

Defining default buttons in HTML forms using JavaScript

Filed under: Software Development & Programming — Tags: , , , — Matthias @ 1:23 pm

Being a keyboard junky myself, I recently stumbled over the somewhat annoying fact that it seems to be impossible to explicitly tell a web browser what the default button in an HTML form is, i.e. which button will be activated when the user hits the ENTER key. I suspected some kind of “default” attribute to be set on a button, but nada, there simply is no such thing. The default button of an HTML form is always the “submit” button.

This is pretty useless for AJAX applications, where you typically do not want to submit the form by evaluating the action parameter of the form, but instead want to trigger an asynchronous request that carries the data of the form. The obvious solution is to exploit the action parameter of the surrounding form: Instead of providing a server URL, you simply execute the click-handler of the button you want to be the default button:

<script type="text/javascript">
    function sendForm() {
        alert ("sending data");
    }
</script>
<form id="MyForm" action="javascript:sendForm()">
   <input type="text" size="50" name="myParam"/>
   <input type="button" name="myButton" value="Send"
        onclick="sendForm()"/>
</form>

Whenever the user hits the ENTER key, the button’s click-handler is invoked. Technically, no actual click event is fired of course. But it does the job.

Blog at WordPress.com.