Skip to content

Instantly share code, notes, and snippets.

@blackmjck
Last active April 3, 2017 17:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save blackmjck/36081e0964b4560c73ae733187569a67 to your computer and use it in GitHub Desktop.
Save blackmjck/36081e0964b4560c73ae733187569a67 to your computer and use it in GitHub Desktop.
Simple browser detection via user agent string for Chrome/IE/Firefox/Opera/Safari. For if you absolutely _have_ to browser detect rather than feature detect...
/**
* @name browserDetect
* @description
* Parses the User Agent string to determine browser and version information, as applicable. Reliably detects major
* versions of the following:
* * Chrome
* * Internet Explorer
* * Edge
* * Safari
* * Firefox
* * Opera
*
* @returns {{major: number, minor: number, patch: number, build: number, browser: string}}
*/
function browserDetect() {
'use strict';
var UA = ( navigator || window.navigator ).userAgent.toLowerCase(),
tests = {
// no minor or patch, but at least we get a build?
edge: /edge\/(\d+)\.(\d+)/,
// mostly only reports major version with unnecessary ".0" suffix
firefox: /firefox\/(\d+(?:\.\d+)*)/,
// sure, there are other tests, but they're complicated and unreliable
ie: /trident\/(\d+)/,
// ie <=7, unsupported by any sane creature
oldIE: /msie\/(\d+)/,
// has to be checked for, lest it be mistaken for Safari or Chrome
opera: /opr\/(\d+(?:\.\d+)*)/,
// both of these have to be present; other browsers like to pretend to be Safari
safari: [
/safari\/(\d+(?:\.\d+)*)/, // build
/version\/(\d+(?:\.\d+)*)/ // major/minor/patch
],
// Note: chrome test is only true if all other tests are false; practically everyone pretends to be Chrome
chrome: /chrome\/(\d+(?:\.\d+)*)/
},
// what we'll be exposing
details = {
major: 0,
minor: 0,
patch: 0,
build: 0,
browser: ''
};
/**
* @name splitFour
* @description
* Takes the result of a `String.match` call, splits the returned inner match on decimals, and assigns the resulting
* version number parts to the details object
* @private
*
* @param {Array} match Result of a `String.match` call. Should have an inner match at index 1
*/
function splitFour( match ) {
var versions = match[1].split( '.' );
details.major = versions[0];
if( versions[1] ) details.minor = versions[1];
if( versions[2] ) details.patch = versions[2];
if( versions[3] ) details.build = versions[3];
}
// Edge
if( tests.edge.test( UA ) ) {
details.browser = 'Edge';
// Edge exposes a major version number, but sadly the only _other_ thing it exposes is the Windows Build number.
details.major = UA.match( tests.edge )[1];
details.build = UA.match( tests.edge )[2];
// IE 8-11
} else if( tests.ie.test( UA ) ) {
details.browser = 'IE';
// IE doesn't tell you _squat_ about versioning beyond the major number, which it doesn't necessarily tell you straight, either
switch( UA.match( tests.ie )[1] ) {
case '7':
details.major = 11;
break;
case '6':
details.major = 10;
break;
case '5':
details.major = 9;
break;
case '4':
details.major = 8;
break;
}
// IE <8
} else if( tests.oldIE.test( UA ) ) {
// we're dealing with ancient artifacts here, Indy
details.browser = 'IE';
details.major = UA.match( tests.oldIE )[1];
// Firefox
} else if( tests.firefox.test( UA ) ) {
details.browser = 'Firefox';
splitFour( UA.match( tests.firefox ) );
// Opera
} else if( tests.opera.test( UA ) ) {
details.browser = 'Opera';
splitFour( UA.match( tests.opera ) );
// Safari
} else if( tests.safari[0].test( UA ) && tests.safari[1].test( UA ) ) {
details.browser = 'Safari';
// safari reports its major/minor/patch versions directly under Version/a.b.c
splitFour( UA.match( tests.safari[1] ) );
// build is reported separately, under the Safari/x.y.z format
details.build = UA.match( tests.safari[0] )[1];
// Chrome
} else if( tests.chrome.test( UA ) ) {
details.browser = 'Chrome';
splitFour( UA.match( tests.chrome ) );
// Browser Incognita
} else {
// do we care at this point?
details.browser = '?';
}
return details;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment