Skip to content

Instantly share code, notes, and snippets.

@ruslanchek
Created June 24, 2016 12:46
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 ruslanchek/3fae84e39c66d6215472b63204bf2264 to your computer and use it in GitHub Desktop.
Save ruslanchek/3fae84e39c66d6215472b63204bf2264 to your computer and use it in GitHub Desktop.
export interface Browser {
name:string,
version:any,
osversion:string,
tablet:boolean,
mobile:boolean,
opera:boolean,
chromeBook:boolean,
chrome:boolean,
yandexbrowser:boolean,
windowsphone:boolean,
msedge:boolean,
msie:boolean,
sailfish:boolean,
seamonkey:boolean,
firefox:boolean,
firefoxos:boolean,
silk:boolean,
phantom:boolean,
blackberry:boolean,
webos:boolean,
bada:boolean,
tizen:boolean,
safari:boolean,
webkit:boolean,
gecko:boolean,
ios:boolean,
android:boolean,
touchpad:boolean,
a:boolean,
c:boolean,
x:boolean
}
export class BrowserDetect {
static detect():Browser {
let ua:any = typeof navigator !== 'undefined' ? navigator.userAgent : '';
function getFirstMatch(regex):any {
var match = ua.match(regex);
return (match && match.length > 1 && match[1]) || '';
}
function getSecondMatch(regex):any {
var match = ua.match(regex);
return (match && match.length > 1 && match[2]) || '';
}
let iosdevice:any = getFirstMatch(/(ipod|iphone|ipad)/i).toLowerCase();
let likeAndroid:boolean = /like android/i.test(ua);
let android:boolean = !likeAndroid && /android/i.test(ua);
let chromeBook:boolean = /CrOS/.test(ua);
let edgeVersion:any = getFirstMatch(/edge\/(\d+(\.\d+)?)/i);
let versionIdentifier:any = getFirstMatch(/version\/(\d+(\.\d+)?)/i);
let tablet:boolean = /tablet/i.test(ua);
let mobile:boolean = !tablet && /[^-]mobi/i.test(ua);
let result:Browser = {
name: '',
version: '',
osversion: '',
tablet: false,
mobile: false,
opera: false,
chromeBook: false,
chrome: false,
yandexbrowser: false,
windowsphone: false,
msedge: false,
msie: false,
sailfish: false,
seamonkey: false,
firefox: false,
firefoxos: false,
silk: false,
phantom: false,
blackberry: false,
webos: false,
bada: false,
tizen: false,
safari: false,
webkit: false,
gecko: false,
ios: false,
android: false,
touchpad: false,
a: false,
c: false,
x: false
};
if (/opera|opr/i.test(ua)) {
result.name = 'Opera';
result.opera = true;
result.version = versionIdentifier || getFirstMatch(/(?:opera|opr)[\s\/](\d+(\.\d+)?)/i);
} else if (/yabrowser/i.test(ua)) {
result.name = 'Yandex Browser';
result.yandexbrowser = true;
result.version = versionIdentifier || getFirstMatch(/(?:yabrowser)[\s\/](\d+(\.\d+)?)/i);
} else if (/windows phone/i.test(ua)) {
result.name = 'Windows Phone',
result.windowsphone = true;
if (edgeVersion) {
result.msedge = true;
result.version = edgeVersion
} else {
result.msie = true;
result.version = getFirstMatch(/iemobile\/(\d+(\.\d+)?)/i)
}
} else if (/msie|trident/i.test(ua)) {
result.name = 'Internet Explorer';
result.msie = true;
result.version = getFirstMatch(/(?:msie |rv:)(\d+(\.\d+)?)/i);
} else if (chromeBook) {
result.name = 'Chrome';
result.chromeBook = true;
result.chrome = true;
result.version = getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i);
} else if (/chrome.+? edge/i.test(ua)) {
result.name = 'Microsoft Edge';
result.msedge = true;
result.version = edgeVersion;
} else if (/chrome|crios|crmo/i.test(ua)) {
result.name = 'Chrome';
result.chrome = true;
result.version = getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i);
} else if (iosdevice) {
result.name = iosdevice == 'iphone' ? 'iPhone' : iosdevice == 'ipad' ? 'iPad' : 'iPod';
// WTF: version is not part of user agent in web apps
if (versionIdentifier) {
result.version = versionIdentifier
}
} else if (/sailfish/i.test(ua)) {
result.name = 'Sailfish';
result.sailfish = true;
result.version = getFirstMatch(/sailfish\s?browser\/(\d+(\.\d+)?)/i);
} else if (/seamonkey\//i.test(ua)) {
result.name = 'SeaMonkey';
result.seamonkey = true;
result.version = getFirstMatch(/seamonkey\/(\d+(\.\d+)?)/i);
} else if (/firefox|iceweasel/i.test(ua)) {
result.name = 'Firefox';
result.firefox = true;
result.version = getFirstMatch(/(?:firefox|iceweasel)[ \/](\d+(\.\d+)?)/i);
if (/\((mobile|tablet);[^\)]*rv:[\d\.]+\)/i.test(ua)) {
result.firefoxos = true;
}
} else if (/silk/i.test(ua)) {
result.name = 'Amazon Silk';
result.silk = true;
result.version = getFirstMatch(/silk\/(\d+(\.\d+)?)/i);
} else if (android) {
result.name = 'Android';
result.version = versionIdentifier;
} else if (/phantom/i.test(ua)) {
result.name = 'PhantomJS';
result.phantom = true;
result.version = getFirstMatch(/phantomjs\/(\d+(\.\d+)?)/i);
} else if (/blackberry|\bbb\d+/i.test(ua) || /rim\stablet/i.test(ua)) {
result.name = 'BlackBerry';
result.blackberry = true;
result.version = versionIdentifier || getFirstMatch(/blackberry[\d]+\/(\d+(\.\d+)?)/i);
} else if (/(web|hpw)os/i.test(ua)) {
result.name = 'WebOS';
result.webos = true;
result.version = versionIdentifier || getFirstMatch(/w(?:eb)?osbrowser\/(\d+(\.\d+)?)/i);
/touchpad\//i.test(ua) && (result.touchpad = true);
} else if (/bada/i.test(ua)) {
result.name = 'Bada';
result.bada = true;
result.version = getFirstMatch(/dolfin\/(\d+(\.\d+)?)/i);
} else if (/tizen/i.test(ua)) {
result.name = 'Tizen';
result.tizen = true;
result.version = getFirstMatch(/(?:tizen\s?)?browser\/(\d+(\.\d+)?)/i) || versionIdentifier;
} else if (/safari/i.test(ua)) {
result.name = 'Safari';
result.safari = true;
result.version = versionIdentifier;
} else {
result.name = getFirstMatch(/^(.*)\/(.*) /);
result.version = getSecondMatch(/^(.*)\/(.*) /);
}
// set webkit or gecko flag for browsers based on these engines
if (!result.msedge && /(apple)?webkit/i.test(ua)) {
result.name = result.name || "Webkit"
result.webkit = true;
if (!result.version && versionIdentifier) {
result.version = versionIdentifier
}
} else if (!result.opera && /gecko\//i.test(ua)) {
result.name = result.name || "Gecko"
result.gecko = true;
result.version = result.version || getFirstMatch(/gecko\/(\d+(\.\d+)?)/i)
}
// set OS flags for platforms that have multiple browsers
if (!result.msedge && (android || result.silk)) {
result.android = true;
} else if (iosdevice) {
result[iosdevice] = true;
result.ios = true;
}
// OS version extraction
var osVersion = '';
if (result.windowsphone) {
osVersion = getFirstMatch(/windows phone (?:os)?\s?(\d+(\.\d+)*)/i);
} else if (iosdevice) {
osVersion = getFirstMatch(/os (\d+([_\s]\d+)*) like mac os x/i);
osVersion = osVersion.replace(/[_\s]/g, '.');
} else if (android) {
osVersion = getFirstMatch(/android[ \/-](\d+(\.\d+)*)/i);
} else if (result.webos) {
osVersion = getFirstMatch(/(?:web|hpw)os\/(\d+(\.\d+)*)/i);
} else if (result.blackberry) {
osVersion = getFirstMatch(/rim\stablet\sos\s(\d+(\.\d+)*)/i);
} else if (result.bada) {
osVersion = getFirstMatch(/bada\/(\d+(\.\d+)*)/i);
} else if (result.tizen) {
osVersion = getFirstMatch(/tizen[\/\s](\d+(\.\d+)*)/i);
}
if (osVersion) {
result.osversion = osVersion;
}
// device type extraction
var osMajorVersion:any = osVersion.split('.')[0];
if (tablet || iosdevice == 'ipad' || (android && (osMajorVersion == 3 || (osMajorVersion == 4 && !mobile))) || result.silk) {
result.tablet = true
} else if (mobile || iosdevice == 'iphone' || iosdevice == 'ipod' || android || result.blackberry || result.webos || result.bada) {
result.mobile = true
}
// Graded Browser Support
// http://developer.yahoo.com/yui/articles/gbs
if (result.msedge ||
(result.msie && result.version >= 10) ||
(result.yandexbrowser && result.version >= 15) ||
(result.chrome && result.version >= 20) ||
(result.firefox && result.version >= 20.0) ||
(result.safari && result.version >= 6) ||
(result.opera && result.version >= 10.0) ||
(result.ios && result.osversion && result.osversion.split('.')[0] as any >= 6) ||
(result.blackberry && result.version >= 10.1)
) {
result.a = true;
} else if ((result.msie && result.version < 10) ||
(result.chrome && result.version < 20) ||
(result.firefox && result.version < 20.0) ||
(result.safari && result.version < 6) ||
(result.opera && result.version < 10.0) ||
(result.ios && result.osversion && result.osversion.split('.')[0] as any < 6)
) {
result.c = true;
} else result.x = true;
return result
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment