2007-06-25

Users drift, time zones vary

In a time of user centricity on the web, I have still not seen any web site or service that groks that time zone is not a per-author (or sometimes even per-visitor) configuration setting, but a function of present location, which in turn is a variable entity over time. (Hint: per-item, with a preference towards suggesting last used time zone, works a lot better. Do it in style, presenting it by the widget you have that shows creation time or similar, so it reads something like "June 25, 11:36, Europe/Stockholm time", relevant fields appropriately editable.)

I entered my flight details (I'm visiting San Francisco most of the later half of July) in Google Calendar the other day, but couldn't tie down start and end points in geography, so it shows my westward flights as ridiculously short, and my first-hop home flight in later July as a huge 24-hour stretch from San Francisco to Amsterdam. There are not always 24 hours in a day when in transit, but it's a very common assumption when crafting user interfaces. Of course it's a can of worms coming up with a good visualization of what time it is throughout the day, if you're in Sweden the first few hours of the day, in London by lunch and Vancouver at the end of the day, adding hours to the day every hop on the way.

Maybe FireEagle and cool hacks like this might pave the way towards betterization on this front, for the "here and now" kind of tools, like blogs, instant messengers and other social applications.

Good OpenID integration for the presence awareness broker would of course be another huge hit. That probably needs integration work from both sides, as the time for breaking some of the assumptions ranted about above comes upon us. I personally have a feeling this forthcoming user centric wave will hit the web from the client rather than server side, though.

These days, neither clients nor users are as dumb as they used to be treated as. But most server side code still is.

2007-06-13

Javascript MD5 singleton

I really love how Yahoo! are spreading the gospel on sound javascript code practices and design patterns, popularizing good ideas among the masses, the most recent example being the module pattern.

In some ways it's the pop version of Douglas Crockford's writings on javascript, in this case private members in javascript, which tells the story of how almost any higher aspect of programming in javascript is accomplished through exploiting the few properties of the function keyword and closures. You can do most kinds of programming in javascript, there is just very rarely any syntactic aid for it.

By contrast, posts like this one would be the boring narrative recount telling you to read the gospel. I'm actually going to add a tiny bit more than that, though, and give an example of how to (re)structure code (not even necessarily your own) to use the module pattern, where it did not use to. It greatly helps keeping mess out of your way.

For a one-off hack (a user script that shows bookmark permalinks at del.icio.us, so you can share them with others, even before more people than yourself have bookmarked the url), I needed a javascript MD5 implementation. Paul Johnston's one (linked) is BSD licensed and works well, but exposes lots of namespace clutter, so I wrapped it up in an MD5 object, exposing only the bits I wanted from it.

Basically, I ended up framing the code inside a var MD5 = (function(){ /* original function definitions here */ return {hash:hex_md5}; })(); block, which exposes the only method I wanted as MD5.hash( data ). No namespace pollution, readable code.

Since an MD5 component is something I often want to use to interface with the world (here it was just to interface with Del.icio.us, which uses hex encoded MD5 hashes of urls for permalinks), I decided to go on and wrap up a version exposing the full (MD5 related) feature set of the lib, though, into a tidy MD5 module.

The API is very lightly wrapped, into methods MD5.string(data), which does a raw MD5 hash on its input string, MD5.hex(data), returning the same, but hexified, MD5.base64(data), ditto but base64 encoded instead, and the same method names with an "MD5.hmac." prefix for the hmac variants. (There is an MD5.test() method for good measure too.) The same config options as the original are supported too, and with the same default values, so set MD5.b64pad = "=" for real base64.

I thought I'd mention this too, here: if you want a similar javascript AES/Rijndael singleton, you should peek at Josh Davis's project on javascript cryptography, which has embarked on a similar path to the above since its conception. It might still be applying an UTF-8 codec on all data that passes through it, but if you need raw AES, just drop the few utf8 related lines, and you've got one.