On the Subject of Web Browsers

Tuesday 11th August, 2009

Creative agency mogul and Javascript whizz-kid Phil Hawksworth has posted a defence of IE6, arguing that in fact IE6 isn’t really as awful as we sometimes make out, and that its entrenchment (which is the biggest annoyance) is caused by the web development community’s own pandering to the IE feature set after the first great Browser War (BW 1).

It sounds weird to hear it now, but as someone who wrote DHTML in the bad old days when the big guns were Netscape 4 and IE 4 and backward compatability demanded IE3 and Netscape 3, I can tell you that IE6 is a dream come true, just like IE5 was when that came out. Yes, I complain about it too, and I know there’s non-standard behaviour, but there are ways of ironing out those inconsistencies without resorting to browser-specific hacks, or except in specific circumstances separate codepaths (the prime exceptions being XmlHttpRequest, vector graphics, and events).

The required attributes for a web browser these days are:

  1. Standards compliance (implemented forgivingly)
  2. Performance
  3. A decent debugging tool
  4. Distribution deals

With the advent of Chrome and the Iphone it’s clear that although IE still holds dominance in corporate applications, in the open web the two competing layout engines are Gecko and WebKit, with Trident a distant and somewhat lame third place. Sorry IE, any browser that doesn’t include a decent dev tool is really going to suffer.

JQuery now integrated with TiddlyWiki

Saturday 14th March, 2009

My old mucker Phil Hawksworth announced yesterday that from version 2.5 TiddlyWiki will utilise JQuery under the hood.

Both JQuery and Tiddlywiki represent significant shifts in the way coders percieve Javascript, so as well as being a victory for maintainability there’s a nice idealogical synergy there.

Congratulations to Phil, Jeremy and all the other Osmonauts.

Logging in Javascript

Wednesday 15th October, 2008

Today’s Ajaxian article about the Blackbird Javascript logging library has prompted a stream of comments asking what advantage this gives over console.log() in Firebug.

I think both the commenters and the Blackbird author have missed a very important aspect of logging in Javascript, namely the ability to record errors outside your own session, i.e. server-side.

This is all that’s missing (in roughly JQuery syntax for brevity):

window.onerror = function(e)
    // get the error data
    if (!e) e = window.error;
    // save error and UI activity for context
    $.post( log_url, 
            // do callback if necessary

Automating Javascript Testing

Tuesday 10th June, 2008

If you’re putting together a software application you probably want to think about setting up build environment, and applications that use a lot of Javascript are no different. A little time invested will probably save headaches down the line. Being able to perform single-click builds of your app is really useful, as explained by Joel Spolsky.

Back in 2005 I started putting together an app (Newsdesk) for Moreover that included what turned about to be about 6000 lines of Javascript. The build environment I came up with wasn’t perfect, and could never remove the need for actual human testing, but it saved an awful lot more work than it took to build. In this article I’ll outline a few ways you can achieve something similar.

Setting up a build

If you’re reading this you should know about encapsulation, the process of restricting outside knowledge of the inner workings of a component. In large systems this is a fundamental “Good Idea”. In compiled systems it’s simple to encapsulate classes and then have them compiled into more monolithic chunks to make them easier to distribute (DLLs, JARs, EXEs, whatever). Usually your IDE/compiler will take care of this for you.

In Javascript a self-disciplined coder can do the same thing. Rather than having one or two large files, you can split your code up into encapsulated components and have them concatenated together into your final files at build-time. This build script can also serve as a platform for code hygene, unit testing, and regression testing.

The core build script

I’d recommend using ANT, (or NANT if you’re using Dot Net). ANT is a flexible, modular, and powerful build program that you can configure to do just about whatever you want. It feels a little strange to write procedural instructions in XML, but once you get over that it’s simple. Using a basic ANT script you can get the latest code from source control, compile it, move it around, rename it, run tests, send an email with the build result to your team, FTP it to your server, or pretty much anything else you can think of.

My build script did roughly this to the Javascript:

  • Iterate the build number and add it to the code’s config file
  • Running unit tests
  • Concatenating code and language files into packages
  • Running code compression on packages (removing comments, whitespace, etc)
  • Generating Javascript code reference

…but you could also include

  • Regression testing
  • Code duplication analysis
  • GZip pre-compression
  • Deploying code to specified server

Build script configuration

If you’re writing a build script you probably ought to think about running it in a couple of modes, because you usually have more than one use case for your build.

Firstly you’re going to want a relatively quick dev build that does quick testing and spits out your compiled code to a local development environment. This might also run some analysis depending on your requirements.

Secondly you might want an occasional analysis build that runs code hygene analysis, runs more in-depth tests, that sort of thing.

Lastly, you might want a deployment build, that retrieves only a specific version (latest, codebase version X, or codebase as of date Z) and outputs a zip or tarball of the compiled codebase ready to be archived and/or copied to servers.

Testing your Javascript

This might seem a bit hard to automate until you discover Rhino. Mozilla’s Rhino engine (in Java) and SpiderMonkey (in C) are invaluable for running Javascript either under a shell or embedded in other applications. Putting Rhino’s JAR file into your classpath allows your build to execute Javascript.

If you want to run JSLint over your source, you can do that. If you want to write your own code analysis tool in JS you can do that too.

This is great for unit testing, but with a UI unit testing can only get you so far. If you want to be a bit more thorough you need regression testing. This can be achieved using Selenium. Selenium is a Javascript-based regression testing engine that allows you to trigger DOM events and test assertions against the resulting DOM. Although this engine is browser-based, you can also call it from code, or ANT, using secondary tools like Selenium RC (Remote Control). There’s also a Firefox plugin that allows you (or your QA team) to build up a library of regression tests that can be run automatically on each build.


I’ve tried not to get into too much detail this time. When I get round to it I might write up areas in more detail. Let me know if you’re interested in something particular.

Client-Side Storage in Javascript

Wednesday 14th May, 2008

Thomas Frank published an awesome hack back in January. Somehow I missed it at the time, but the ever-vigilant Simon Willison picked it up yesterday.

The short version is that by serialising a data structure to the window.name property in the browser DOM you can store up to 2MB (much more in some browsers, eg. IE:32MB, Safari:64MB) for the life of that window object, so a single-window session (multiple tabs or windows open on a page at the same time would not have access to the same data).

Besides from begging the question of what browser developers have been smoking, this isn’t a revolution… The HTML 5 working draft features structured client-side storage so this was already on its way via a more formal route. There are also other methods in place to accomplish similar things, for example Dojo uses the Flash plugin where available to achieve client-side storage.

That said, I’d be surprised if this method didn’t sneak its way into a few codebases here and there due to it’s simplicity, broad browser support, and immediacy… and once Javascript developers become more accustomed to the concept of client-side storage we may well see a flurry of new techniques built on client-side storage.

Processing ported to Javascript

Friday 9th May, 2008

One of my favourite chronic overachievers John Resig has ported one of my favourite programs, Processing, to one of my favourite environments, Javascript, using the Canvas tag.

From first appearances it seems like performance is good. Well done John.

Javascript JVM

Wednesday 30th April, 2008

It’s amazing what programming gymnastics can be achieved when someone sets their mind to it. JQuery‘s John Resig reports on Orto, which is a JVM written in Javascript that accomplishes multithreading in a single thread using yields.

Capturing data using RegExp Backreferences

Thursday 27th March, 2008

Quite often you need to capture data from a string. For example when translating a formatted date into a date object. The following example shows one way you can do that in Javascript.

// String to parse
var dateString = "Mar 27 2008 1:46PM";

// Define the pattern, including capturing brackets
// ^ - Start of string
// (\w{3}) - Three letters : "Mar"
// ([0-9]{1,2}) - One or two numbers : "27"
// ([0-9]{4}) - Four numbers : "2008"
// ([0-9]{1,2}) - One or two numbers : "1"
// : - Colon
// ([0-9]{2}) - Two numbers : "46"
// (\w{2}) - Two letters : "PM";
// $ - End of string;
var format =
        /^(\w{3}) ([0-9]{1,2}) ([0-9]{4}) ([0-9]{1,2}):([0-9]{2})(\w{2})$/i;

// Specify which bracket pairs have which meanings
// This is mostly just to make the code readable below
var parts = {
        month : "$1",
        day : "$2",
        year : "$3",
        hour : "$4",
        minute : "$5",
        half : "$6" };

// Define key to translate month names to numbers
var months = {
        Dec:12 };

// Execute the RegExp
format.exec( dateString );

// Pull a few captured values out of global RegExp object
var hour = parseInt( RegExp[parts.hour], 10 );
var half = RegExp[parts.half];
hour = ( half == "AM" && hour == 12 ) ? 0 : hour;
hour += ( half == "PM" && hour != 12 ) ? 12 : 0;

// Create a date object and set the captured values
var d = new Date();
	( months[ RegExp[parts.month] ] - 1 ),
	RegExp[parts.day] );
d.setUTCHours( hour );
d.setUTCMinutes( RegExp[parts.minute] );