Detecting browsers javascript hacks

I enjoyed my last experiment to create tiny browser detection hacks, so I thought I’d try and do some more in other browsers. I’ve found these while testing Hackvertor and writing the inspection functions. The rules are simple if you want to post your own:-

1. The variable assignment must be the abbreviation of the browser. E.g. FF, IE, Op, Saf, Chr.
2. The detection shouldn’t be able to be overwritten. E.g. IE=!!top.execScript is incorrect because a web site can redefine execScript as a variable or function.
3. Small and as fast as possible please.

To start off, this one was found by DoctorDan from the slackers forums:-

//Firefox detector 2/3 by DoctorDan
FF=/a/[-1]=='a'
//Firefox 3 by me:-
FF3=(function x(){})[-5]=='x'
//Firefox 2 by me:-
FF2=(function x(){})[-6]=='x'
//IE detector I posted previously
IE='\v'=='v'
//Safari detector by me
Saf=/a/.__proto__=='//'
//Chrome by me
Chr=/source/.test((/a/.toString+''))
//Opera by me
Op=/^function \(/.test([].sort)
//IE6 detector using conditionals 
try {IE6=@cc_on @_jscript_version <= 5.7&&@_jscript_build<10000} catch(e){IE6=false;}

As I come across more developing Hackvertor I shall post them here. Please post your own or verify any of the ones posted.

Update...

One line to rule them all:-

B=(function x(){})[-5]=='x'?'FF3':(function x(){})[-6]=='x'?'FF2':/a/[-1]=='a'?'FF':'\v'=='v'?'IE':/a/.__proto__=='//'?'Saf':/s/.test(/a/.toString)?'Chr':/^function \(/.test([].sort)?'Op':'Unknown'

41 Responses to “Detecting browsers javascript hacks”

  1. est writes:

    Nice!

  2. Dave writes:

    That is pretty epic I wont lie. *Blogs this*

  3. Gareth Heyes writes:

    I can make it smaller if you’re not interested in which version of FF:-

    B=/a/[-1]==’a’?’FF’:’\v’==’v’?’IE’:/a/.__proto__==’//’?’Saf’:/s/.test(/a/.toString)?’Chr’:’Op’

    //94!

  4. Ben writes:

    This is pretty insane, man!

    I sure do hope it gets implemented in jQuery’s and the other libraries’ cores…

  5. Sam writes:

    It gives ‘Op’ in FF3.1 beta2.

  6. Gareth Heyes writes:

    @Sam

    I’ve updated the one rule, please try again. If you can please run this hackvertor code to see what results in FF3.1 beta :-

    http://www.businessinfo.co.uk/labs/hackvertor/hackvertor.php?input=Ly9DbGljayAiaW5zcGVjdCBvdXRwdXQiCmFsZXJ0

  7. Keenora writes:

    Another little change would be a CSS-Selector in 252 Bytes:

    document.getElementsByTagName(‘html’)[0].className+=’ ‘+(function x(){})[-5]==’x’?’FF3′:(function x(){})[-6]==’x’?’FF2′:/a/[-1]==’a’?’FF’:’\v’==’v’?’IE’:/a/.__proto__==’//’?’Saf’:/s/.test(/a/.toString)?’Chr’:/^function \(/.test([].sort)?’Op’:’Unknown’

    You can use:

    .IE .example { color: red; }
    .FF2 . example { color: lime; }
    etc…
    (classNames are case sensitive!)

    Have fun 🙂

  8. Graham writes:

    One obvious point is that browser detection is something that should be avoided wherever possible – feature detection should be used instead otherwise your website won’t work on the next browser released…

  9. kangax writes:

    Opera test doesn’t quite satisfy your rules, as it can be easily overwritten:

    Array.prototype.sort.toString = function(){ return ‘function (){}’ }

    /^function \(/.test([].sort); // true

  10. kangax writes:

    Safari check can be fooled in the very same way, of course:

    RegExp.prototype.toString = function(){ return ‘//’ };
    /a/.__proto__==’//’; // true

  11. Paul Irish writes:

    These are most excellent. I just used a few in a bookmarklet for adding new css rules to the page

    The safari test only catches safari proper and not the webkit-also Chrome… Do you have a clever solution to catch both? (I recognize they’re different js engines, but come on.. you’re clever. 🙂

  12. Gareth Heyes writes:

    @Paul

    I’ve not got Chrome handy at the moment because I’m on a different computer. However this should work:-

    WebKit=typeof document.body.style.WebkitAppearance==’string’;

    This can be overwritten though so technically it breaks the rules but it might be good enough for what you want.

  13. Gareth Heyes writes:

    Just to confirm it does work in Chrome and Safari 😀

  14. Paul Irish writes:

    Gareth, you are a machine. Well done.

  15. Ehsun Amanolahi writes:

    Nice stuff!

  16. asf writes:

    The Opera test does not work in 9.2x

  17. Gyrobo writes:

    IE=@cc_on true ? true : @false;

    Internet Explorer supports <a href=”http://msdn.microsoft.com/en-us/library/ahx1z4fs(VS.80).aspx”>conditional compilation</a> which can be used to accurately detect its version:

    IE8=@cc_on @_jscript_version == 5.8 ? true : @false

    IE7=@cc_on @_jscript_version == 5.7 ? true : @false

    IE6=@cc_on @_jscript_version == 5.6 ? true : @false

    IE55=@cc_on @_jscript_version == 5.5 ? true : @false

  18. Gyrobo writes:

    My asterisks and slashes have vanished.

    There should be a block comment opened right before each @cc_on, and closed after the final @.

  19. Gareth Heyes writes:

    @Gyrobo

    Sorry about that I remove comments from WordPress to avoid SQL injection attacks.

    Conditional comments work well but not when the code is compressed

  20. 布里斯班 writes:

    Quite a great effect.
    Thanks for sharing.

  21. Gyrobo writes:

    Well then, I guess I learned something about both compression and SQL injection. Yay!

  22. Инокентий writes:

    Хорошая статья, больше бы таких!

  23. Димитрий writes:

    А подробнее можно?

  24. Gareth Heyes writes:

    Да, больше невозможно. Попробуйте JavaScript обнаружения CSS свойства как МОЗ или MS-т.д.

  25. d writes:

    hello,

    great stuff! it seems that the one line detector is just returning ‘FF’ for firefox 3.5.1 mac+win. Any chance of a fix?

    best,
    -D

  26. Gareth Heyes writes:

    @d

    This should detect FF3.5 and above:-

    FF3=(/a/[-1]&&Object.getPrototypeOf)?true:false

  27. Kyle Simpson writes:

    Just wanted to share two hacks I’m currently using (in LABjs) for detecting Firefox(Gecko) and for detecting Opera:

    is_opera = window.opera && Object.toString.call(window.opera) == “[object Opera]”

    is_gecko = (function(o) { o[o] = o+””; return o[o] != o+””; })(new String(“__count__”))

  28. d writes:

    @gareth:
    thanks brother!

  29. Mathias Bynens writes:

    The IE check can be shortened to:

    IE=!+'\v1';
  30. Gareth Heyes writes:

    @Mathias

    Yeah someone already pointed that out:-

    http://sla.ckers.org/forum/read.php?2,15812,26331,page=13#msg-26331

  31. Dmitry Binner writes:

    I didn’t know that. thank you

  32. Jordan writes:

    When I run the one-liner in Mac Google Chrome, I get “Unknown”.

    Any chance someone could update the one-liner to work with Mac Google Chrome?

  33. superhei writes:

    /a/[-1]==’a’ isn’t work on firefox3.6

  34. Gareth Heyes writes:

    @superhei

    Yep Mozilla decided this was a security issue when I reported it so these techniques can no longer be expected to work in later versions of Firefox

  35. noob writes:

    i was wondering why are you using ((/a/.toString+”)) instead of (/a/.toString+”) ?

  36. Gareth Heyes writes:

    @noob

    Yeah probably a typo nobody is perfect 🙂

  37. hztny writes:

    Yeah probably a typo nobody is perfect

  38. Damian writes:

    FireFox keeps being detected as Chrome

    function getBrowser()
    {
    if( _browser == undefined )
    {
    _browser = (function x(){})[-5]==’x’
    ?’FF3′:/a/[-1]&&Object.getPrototypeOf
    ?’FF2′:/a/[-1]==’a’
    ?’FF’:’\v’==’v’
    ?’IE’:/a/.__proto__==’//’
    ?’SAF’:(/a/.toString+”)
    ?’CHR’:/^function \(/.test([].sort)
    ?’OP’:’Unknown’;

    /* not sure what’s wrong w/ the above oneliner.. */
    if( /a/[-1]&&Object.getPrototypeOf ) _browser = ‘FF3’;
    if( _browser == ‘IE’ && isIE8() ) _browser = ‘IE8’;
    if( _browser == ‘IE’ && isIE7() ) _browser = ‘IE7’;
    if( _browser == ‘IE’ && isIE6() ) _browser = ‘IE6’;
    }
    return USE_LOWERCASE_BROWSER ? _browser.toLowerCase() : _browser;
    }

  39. abhishek writes:

    Hi,
    Nice trick for detecting browsers. I am adding this to my blog.

  40. 2web writes:

    Nice artcile)
    Translated & posted.

  41. HP Bryce writes:

    This is sweet! I use ie and Fire Fox depending on what I’m doing or where I’m browsing. This will be great to keep peoples noses out of my browser!