The importance of being !important

January 18th, 2007

There are plenty of good articles describing how CSS specificity is calculated for normal rule-sets, but the !important modifier is often ignored or overlooked. However, with a little manipulation, !important can simply be treated as one more factor in the specificity calculation.

Read the rest of this entry »

undefined is not a reserved word

January 19th, 2007

With the new release of Prototype (1.5.0) comes a new website for the Prototype JavaScript Library. The home-page of the new website features a snippet of JavaScript:

cells: function(row) {
  if(row == undefined) return this.tab...
  return $(row).getElementsBySelector(...
}

Let’s get this straight: undefined is not a reserved word. It’s safer and more logical to make the comparison to null:

cells: function(row) {
  if(row == null) return this.tab...
  return $(row).getElementsBySelector(...
}

As null is a reserved word (and it’s quicker to type) I’d expect the Prototype community to favour it.

Note: assuming undefined hasn’t been redefined, the two code fragments are functionally identical. i.e. the equals operator (==) treats null and the primitive value undefined exactly the same.

I hate my Macbook Pro

February 16th, 2007

Don’t misunderstand me: I like OS X, I like the build-quality, and I like the look But there are some things I just can’t stand; and they’re ruining the whole experience for me:

  1. anti-social speakers (delayed headphone detection)
  2. poorly-positioned DVD-drive (and it’s region-locked!)
  3. badly laid-out keyboard (particularly the European models)

Read the rest of this entry »

sprintf for JavaScript

March 14th, 2007

Avoid writing formatting functions in JavaScript by grabbing yourself a decent sprintf implementation - handling padding, truncation, floating-point numbers, left/right alignment and re-ordered arguments.

You can download sprintf for JavaScript, available under the Create Commons Attribution License. Now license free (use it where/when/how you like.)

The version I’ve written is based strongly on Perl’s sprintf implementation, allowing argument reordering to help with internationalisation (i18n). Some overly simplistic examples follow, leaving room for obvious improvements like:

  1. letting the user specify their locale as a preference
  2. set default locale based on visitor demographics
  3. use locale-specific message-bundles with a fall-back to the default locale

On with the examples:

var locale = 'es';
var messages = {
    'en': 'I am %d years and %d months old.',
    'es': 'Tengo %2$d meses y %1$d aƱos.'
};
var message = sprintf(messages[locale], 31, 7);

You could also use it for

var date = new Date;
var dateFormats = [
    /* ISO-8601: */ '%04d-%02d-%02d %02d:%02d:%02d',
    /* British:  */ '%3$02d/%2$02d/%1$02d',
    /* U.S.:     */ '%2$02d/%3$02d/%1$02d'
];

// for example only: choose random date format
var dateFormat = dateFormats[3 * Math.random() >>> 0];

var formatted = sprintf(dateFormat,
    date.getFullYear(), date.getMonth() + 1, date.getDate(),
    date.getHours(), date.getMinutes(), date.getSeconds());
alert(formatted);

The Perl documentation has more examples in the “order of arguments section“.
Note: this implementation allows the precision of a number to be set from a specific argument (using e.g. “%.*3$f”), which the perldocs (perldoc -f sprintf) say hasn’t been implemented yet.


I haven’t (re)written any documentation for it, but you should be able to use Firebug (or the javascript: protocol) to try out sprintf on this page, and you can also check out the test page for sprintf for more input/output samples.

As usual, writing test-cases uncovered a couple of browser-dependent issues. Safari has some bizarre behaviour with Maths.abs(0).toFixed(6) resulting in "0.0000-0" instead of "0.000000". Another issue I came across is that 0.5 rounds to 0 or 1 depending on browser (worded differently: numbers are rounded off inconsistently across browsers.)

Dependencies

On modern browsers, there are no dependencies. But to run sprintf on older browsers you’ll need to patch the Number and String objects. Number needs toFixed, toExponential and toPrecision methods, while String needs a replace method capable of using functions in the replacement parameter.

How to skip DVD intros

April 2nd, 2007

No-one enjoys the force-fed FBI, F.A.C.T. and Copyright propaganda on DVDs. Thankfully, there are ways of skipping them. Read the rest of this entry »