Shamelessly stolen from http://www.quirksmode.org/js/detect.html