Last active
April 3, 2017 17:21
-
-
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...
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @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