From 90ad912e8dd5a6c10e56dc262817a254759c6ddc Mon Sep 17 00:00:00 2001 From: Hannes Diercks Date: Fri, 13 Sep 2013 14:00:17 +0200 Subject: [PATCH 01/11] Add braces for better minification and semicolons to improve readability. --- bowser.js | 82 ++++++++++++++++++++++++++++++--------------------- bowser.min.js | 2 +- src/bowser.js | 82 ++++++++++++++++++++++++++++++--------------------- 3 files changed, 97 insertions(+), 69 deletions(-) diff --git a/bowser.js b/bowser.js index c19137c..851a1a3 100644 --- a/bowser.js +++ b/bowser.js @@ -5,9 +5,13 @@ */ !function (name, definition) { - if (typeof define == 'function') define(definition) - else if (typeof module != 'undefined' && module.exports) module.exports['browser'] = definition() - else this[name] = definition() + if (typeof define === 'function') { + define(definition); + } else if (typeof module !== 'undefined' && module.exports) { + module.exports[name] = definition(); + } else { + this[name] = definition(); + } }('bowser', function () { /** * navigator.userAgent => @@ -40,72 +44,80 @@ , seamonkey = /seamonkey\//i.test(ua) , webkitVersion = /version\/(\d+(\.\d+)?)/i , firefoxVersion = /firefox\/(\d+(\.\d+)?)/i - , o + , o; function detect() { - if (ie) return { + if (ie) { + return { msie: t , version: ua.match(/(msie |rv:)(\d+(\.\d+)?)/i)[2] - } - if (opera) return { + }; + } else if (opera) { + return { opera: t , version: ua.match(webkitVersion) ? ua.match(webkitVersion)[1] : ua.match(/opr\/(\d+(\.\d+)?)/i) - } - if (chrome) return { + }; + } else if (chrome) { + return { webkit: t , chrome: t , version: ua.match(/chrome\/(\d+(\.\d+)?)/i)[1] - } - if (phantom) return { + }; + } else if (phantom) { + return { webkit: t , phantom: t , version: ua.match(/phantomjs\/(\d+(\.\d+)+)/i)[1] - } - if (touchpad) return { + }; + } else if (touchpad) { + return { webkit: t , touchpad: t , version : ua.match(/touchpad\/(\d+(\.\d+)?)/i)[1] - } - if (iphone || ipad) { + }; + } else if (iphone || ipad) { o = { webkit: t , mobile: t , ios: t , iphone: iphone , ipad: ipad - } + }; // WTF: version is not part of user agent in web apps if (webkitVersion.test(ua)) { - o.version = ua.match(webkitVersion)[1] + o.version = ua.match(webkitVersion)[1]; } - return o - } - if (android) return { + return o; + } else if (android) { + return { webkit: t , android: t , mobile: t , version: (ua.match(webkitVersion) || ua.match(firefoxVersion))[1] - } - if (safari) return { + }; + } else if (safari) { + return { webkit: t , safari: t , version: ua.match(webkitVersion)[1] - } - if (gecko) { + }; + } else if (gecko) { o = { gecko: t , mozilla: t , version: ua.match(firefoxVersion)[1] - } - if (firefox) o.firefox = t - return o - } - if (seamonkey) return { + }; + if (firefox) o.firefox = t; + return o; + } else if (seamonkey) { + return { seamonkey: t , version: ua.match(/seamonkey\/(\d+(\.\d+)?)/i)[1] - } - return {} + }; + } else { + return {}; + } } var bowser = detect() @@ -125,8 +137,10 @@ (bowser.firefox && bowser.version < 4.0) || (bowser.safari && bowser.version < 5) || (bowser.opera && bowser.version < 10.0)) { - bowser.c = t - } else bowser.x = t + bowser.c = t; + } else { + bowser.x = t; + } - return bowser + return bowser; }) diff --git a/bowser.min.js b/bowser.min.js index 04f4764..bceae58 100644 --- a/bowser.min.js +++ b/bowser.min.js @@ -3,4 +3,4 @@ * https://github.com/ded/bowser * MIT License | (c) Dustin Diaz 2013 */ -!function(e,t){typeof define=="function"?define(t):typeof module!="undefined"&&module.exports?module.exports.browser=t():this[e]=t()}("bowser",function(){function g(){return n?{msie:t,version:e.match(/(msie |rv:)(\d+(\.\d+)?)/i)[2]}:l?{opera:t,version:e.match(d)?e.match(d)[1]:e.match(/opr\/(\d+(\.\d+)?)/i)}:r?{webkit:t,chrome:t,version:e.match(/chrome\/(\d+(\.\d+)?)/i)[1]}:i?{webkit:t,phantom:t,version:e.match(/phantomjs\/(\d+(\.\d+)+)/i)[1]}:a?{webkit:t,touchpad:t,version:e.match(/touchpad\/(\d+(\.\d+)?)/i)[1]}:o||u?(m={webkit:t,mobile:t,ios:t,iphone:o,ipad:u},d.test(e)&&(m.version=e.match(d)[1]),m):f?{webkit:t,android:t,mobile:t,version:(e.match(d)||e.match(v))[1]}:s?{webkit:t,safari:t,version:e.match(d)[1]}:h?(m={gecko:t,mozilla:t,version:e.match(v)[1]},c&&(m.firefox=t),m):p?{seamonkey:t,version:e.match(/seamonkey\/(\d+(\.\d+)?)/i)[1]}:{}}var e=navigator.userAgent,t=!0,n=/(msie|trident)/i.test(e),r=/chrome/i.test(e),i=/phantom/i.test(e),s=/safari/i.test(e)&&!r&&!i,o=/iphone/i.test(e),u=/ipad/i.test(e),a=/touchpad/i.test(e),f=/android/i.test(e),l=/opera/i.test(e)||/opr/i.test(e),c=/firefox/i.test(e),h=/gecko\//i.test(e),p=/seamonkey\//i.test(e),d=/version\/(\d+(\.\d+)?)/i,v=/firefox\/(\d+(\.\d+)?)/i,m,y=g();return y.msie&&y.version>=8||y.chrome&&y.version>=10||y.firefox&&y.version>=4||y.safari&&y.version>=5||y.opera&&y.version>=10?y.a=t:y.msie&&y.version<8||y.chrome&&y.version<10||y.firefox&&y.version<4||y.safari&&y.version<5||y.opera&&y.version<10?y.c=t:y.x=t,y}) \ No newline at end of file +!function(e,t){typeof define=="function"?define(t):typeof module!="undefined"&&module.exports?module.exports[e]=t():this[e]=t()}("bowser",function(){function g(){return n?{msie:t,version:e.match(/(msie |rv:)(\d+(\.\d+)?)/i)[2]}:l?{opera:t,version:e.match(d)?e.match(d)[1]:e.match(/opr\/(\d+(\.\d+)?)/i)}:r?{webkit:t,chrome:t,version:e.match(/chrome\/(\d+(\.\d+)?)/i)[1]}:i?{webkit:t,phantom:t,version:e.match(/phantomjs\/(\d+(\.\d+)+)/i)[1]}:a?{webkit:t,touchpad:t,version:e.match(/touchpad\/(\d+(\.\d+)?)/i)[1]}:o||u?(m={webkit:t,mobile:t,ios:t,iphone:o,ipad:u},d.test(e)&&(m.version=e.match(d)[1]),m):f?{webkit:t,android:t,mobile:t,version:(e.match(d)||e.match(v))[1]}:s?{webkit:t,safari:t,version:e.match(d)[1]}:h?(m={gecko:t,mozilla:t,version:e.match(v)[1]},c&&(m.firefox=t),m):p?{seamonkey:t,version:e.match(/seamonkey\/(\d+(\.\d+)?)/i)[1]}:{}}var e=navigator.userAgent,t=!0,n=/(msie|trident)/i.test(e),r=/chrome/i.test(e),i=/phantom/i.test(e),s=/safari/i.test(e)&&!r&&!i,o=/iphone/i.test(e),u=/ipad/i.test(e),a=/touchpad/i.test(e),f=/android/i.test(e),l=/opera/i.test(e)||/opr/i.test(e),c=/firefox/i.test(e),h=/gecko\//i.test(e),p=/seamonkey\//i.test(e),d=/version\/(\d+(\.\d+)?)/i,v=/firefox\/(\d+(\.\d+)?)/i,m,y=g();return y.msie&&y.version>=8||y.chrome&&y.version>=10||y.firefox&&y.version>=4||y.safari&&y.version>=5||y.opera&&y.version>=10?y.a=t:y.msie&&y.version<8||y.chrome&&y.version<10||y.firefox&&y.version<4||y.safari&&y.version<5||y.opera&&y.version<10?y.c=t:y.x=t,y}) \ No newline at end of file diff --git a/src/bowser.js b/src/bowser.js index 35c1d5c..889be66 100644 --- a/src/bowser.js +++ b/src/bowser.js @@ -1,7 +1,11 @@ !function (name, definition) { - if (typeof define == 'function') define(definition) - else if (typeof module != 'undefined' && module.exports) module.exports['browser'] = definition() - else this[name] = definition() + if (typeof define === 'function') { + define(definition); + } else if (typeof module !== 'undefined' && module.exports) { + module.exports[name] = definition(); + } else { + this[name] = definition(); + } }('bowser', function () { /** * navigator.userAgent => @@ -34,72 +38,80 @@ , seamonkey = /seamonkey\//i.test(ua) , webkitVersion = /version\/(\d+(\.\d+)?)/i , firefoxVersion = /firefox\/(\d+(\.\d+)?)/i - , o + , o; function detect() { - if (ie) return { + if (ie) { + return { msie: t , version: ua.match(/(msie |rv:)(\d+(\.\d+)?)/i)[2] - } - if (opera) return { + }; + } else if (opera) { + return { opera: t , version: ua.match(webkitVersion) ? ua.match(webkitVersion)[1] : ua.match(/opr\/(\d+(\.\d+)?)/i) - } - if (chrome) return { + }; + } else if (chrome) { + return { webkit: t , chrome: t , version: ua.match(/chrome\/(\d+(\.\d+)?)/i)[1] - } - if (phantom) return { + }; + } else if (phantom) { + return { webkit: t , phantom: t , version: ua.match(/phantomjs\/(\d+(\.\d+)+)/i)[1] - } - if (touchpad) return { + }; + } else if (touchpad) { + return { webkit: t , touchpad: t , version : ua.match(/touchpad\/(\d+(\.\d+)?)/i)[1] - } - if (iphone || ipad) { + }; + } else if (iphone || ipad) { o = { webkit: t , mobile: t , ios: t , iphone: iphone , ipad: ipad - } + }; // WTF: version is not part of user agent in web apps if (webkitVersion.test(ua)) { - o.version = ua.match(webkitVersion)[1] + o.version = ua.match(webkitVersion)[1]; } - return o - } - if (android) return { + return o; + } else if (android) { + return { webkit: t , android: t , mobile: t , version: (ua.match(webkitVersion) || ua.match(firefoxVersion))[1] - } - if (safari) return { + }; + } else if (safari) { + return { webkit: t , safari: t , version: ua.match(webkitVersion)[1] - } - if (gecko) { + }; + } else if (gecko) { o = { gecko: t , mozilla: t , version: ua.match(firefoxVersion)[1] - } - if (firefox) o.firefox = t - return o - } - if (seamonkey) return { + }; + if (firefox) o.firefox = t; + return o; + } else if (seamonkey) { + return { seamonkey: t , version: ua.match(/seamonkey\/(\d+(\.\d+)?)/i)[1] - } - return {} + }; + } else { + return {}; + } } var bowser = detect() @@ -119,8 +131,10 @@ (bowser.firefox && bowser.version < 4.0) || (bowser.safari && bowser.version < 5) || (bowser.opera && bowser.version < 10.0)) { - bowser.c = t - } else bowser.x = t + bowser.c = t; + } else { + bowser.x = t; + } - return bowser + return bowser; }) From 3fe73237e225a1c7d399097f036df96d3a3c121d Mon Sep 17 00:00:00 2001 From: Hannes Diercks Date: Fri, 13 Sep 2013 14:08:52 +0200 Subject: [PATCH 02/11] Make the detect function reusable. --- bowser.js | 108 ++++++++++++++++++++++++++------------------------ bowser.min.js | 2 +- src/bowser.js | 108 ++++++++++++++++++++++++++------------------------ 3 files changed, 115 insertions(+), 103 deletions(-) diff --git a/bowser.js b/bowser.js index 851a1a3..4e4e7b9 100644 --- a/bowser.js +++ b/bowser.js @@ -28,44 +28,42 @@ * PhantomJS: "Mozilla/5.0 (Macintosh; Intel Mac OS X) AppleWebKit/534.34 (KHTML, like Gecko) PhantomJS/1.5.0 Safari/534.34" */ - var ua = navigator.userAgent - , t = true - , ie = /(msie|trident)/i.test(ua) - , chrome = /chrome/i.test(ua) - , phantom = /phantom/i.test(ua) - , safari = /safari/i.test(ua) && !chrome && !phantom - , iphone = /iphone/i.test(ua) - , ipad = /ipad/i.test(ua) - , touchpad = /touchpad/i.test(ua) - , android = /android/i.test(ua) - , opera = /opera/i.test(ua) || /opr/i.test(ua) - , firefox = /firefox/i.test(ua) - , gecko = /gecko\//i.test(ua) - , seamonkey = /seamonkey\//i.test(ua) - , webkitVersion = /version\/(\d+(\.\d+)?)/i - , firefoxVersion = /firefox\/(\d+(\.\d+)?)/i - , o; - - function detect() { + function detect(ua) { + var t = true + , ie = /(msie|trident)/i.test(ua) + , chrome = /chrome/i.test(ua) + , phantom = /phantom/i.test(ua) + , safari = /safari/i.test(ua) && !chrome && !phantom + , iphone = /iphone/i.test(ua) + , ipad = /ipad/i.test(ua) + , touchpad = /touchpad/i.test(ua) + , android = /android/i.test(ua) + , opera = /opera/i.test(ua) || /opr/i.test(ua) + , firefox = /firefox/i.test(ua) + , gecko = /gecko\//i.test(ua) + , seamonkey = /seamonkey\//i.test(ua) + , webkitVersion = /version\/(\d+(\.\d+)?)/i + , firefoxVersion = /firefox\/(\d+(\.\d+)?)/i + , o; if (ie) { - return { + o = { msie: t , version: ua.match(/(msie |rv:)(\d+(\.\d+)?)/i)[2] }; } else if (opera) { - return { + o = { opera: t , version: ua.match(webkitVersion) ? ua.match(webkitVersion)[1] : ua.match(/opr\/(\d+(\.\d+)?)/i) }; } else if (chrome) { - return { + o = { webkit: t , chrome: t , version: ua.match(/chrome\/(\d+(\.\d+)?)/i)[1] }; } else if (phantom) { - return { + o = { webkit: t , phantom: t , version: ua.match(/phantomjs\/(\d+(\.\d+)+)/i)[1] @@ -88,16 +86,15 @@ if (webkitVersion.test(ua)) { o.version = ua.match(webkitVersion)[1]; } - return o; } else if (android) { - return { + o = { webkit: t , android: t , mobile: t , version: (ua.match(webkitVersion) || ua.match(firefoxVersion))[1] }; } else if (safari) { - return { + o = { webkit: t , safari: t , version: ua.match(webkitVersion)[1] @@ -109,38 +106,47 @@ , version: ua.match(firefoxVersion)[1] }; if (firefox) o.firefox = t; - return o; } else if (seamonkey) { - return { + o = { seamonkey: t , version: ua.match(/seamonkey\/(\d+(\.\d+)?)/i)[1] }; } else { - return {}; + o = {}; } + + // Graded Browser Support + // http://developer.yahoo.com/yui/articles/gbs + if ((o.msie && o.version >= 8) || + (o.chrome && o.version >= 10) || + (o.firefox && o.version >= 4.0) || + (o.safari && o.version >= 5) || + (o.opera && o.version >= 10.0)) { + o.a = t; + } + + else if ((o.msie && o.version < 8) || + (o.chrome && o.version < 10) || + (o.firefox && o.version < 4.0) || + (o.safari && o.version < 5) || + (o.opera && o.version < 10.0)) { + o.c = t; + } else { + o.x = t; + } + + return o; } - var bowser = detect() - - // Graded Browser Support - // http://developer.yahoo.com/yui/articles/gbs - if ((bowser.msie && bowser.version >= 8) || - (bowser.chrome && bowser.version >= 10) || - (bowser.firefox && bowser.version >= 4.0) || - (bowser.safari && bowser.version >= 5) || - (bowser.opera && bowser.version >= 10.0)) { - bowser.a = t; - } - - else if ((bowser.msie && bowser.version < 8) || - (bowser.chrome && bowser.version < 10) || - (bowser.firefox && bowser.version < 4.0) || - (bowser.safari && bowser.version < 5) || - (bowser.opera && bowser.version < 10.0)) { - bowser.c = t; - } else { - bowser.x = t; - } + /* Get our main bowser object from navigators user agent if present. */ + var bowser = detect(typeof navigator !== 'undefined' ? navigator.userAgent : ''); + + /* + * Set our detect method to the main bowser object so we can + * reuse it to test other user agents. + * This is needed to implement future tests. + */ + bowser._detect = detect; return bowser; -}) +}); diff --git a/bowser.min.js b/bowser.min.js index bceae58..63ab1c5 100644 --- a/bowser.min.js +++ b/bowser.min.js @@ -3,4 +3,4 @@ * https://github.com/ded/bowser * MIT License | (c) Dustin Diaz 2013 */ -!function(e,t){typeof define=="function"?define(t):typeof module!="undefined"&&module.exports?module.exports[e]=t():this[e]=t()}("bowser",function(){function g(){return n?{msie:t,version:e.match(/(msie |rv:)(\d+(\.\d+)?)/i)[2]}:l?{opera:t,version:e.match(d)?e.match(d)[1]:e.match(/opr\/(\d+(\.\d+)?)/i)}:r?{webkit:t,chrome:t,version:e.match(/chrome\/(\d+(\.\d+)?)/i)[1]}:i?{webkit:t,phantom:t,version:e.match(/phantomjs\/(\d+(\.\d+)+)/i)[1]}:a?{webkit:t,touchpad:t,version:e.match(/touchpad\/(\d+(\.\d+)?)/i)[1]}:o||u?(m={webkit:t,mobile:t,ios:t,iphone:o,ipad:u},d.test(e)&&(m.version=e.match(d)[1]),m):f?{webkit:t,android:t,mobile:t,version:(e.match(d)||e.match(v))[1]}:s?{webkit:t,safari:t,version:e.match(d)[1]}:h?(m={gecko:t,mozilla:t,version:e.match(v)[1]},c&&(m.firefox=t),m):p?{seamonkey:t,version:e.match(/seamonkey\/(\d+(\.\d+)?)/i)[1]}:{}}var e=navigator.userAgent,t=!0,n=/(msie|trident)/i.test(e),r=/chrome/i.test(e),i=/phantom/i.test(e),s=/safari/i.test(e)&&!r&&!i,o=/iphone/i.test(e),u=/ipad/i.test(e),a=/touchpad/i.test(e),f=/android/i.test(e),l=/opera/i.test(e)||/opr/i.test(e),c=/firefox/i.test(e),h=/gecko\//i.test(e),p=/seamonkey\//i.test(e),d=/version\/(\d+(\.\d+)?)/i,v=/firefox\/(\d+(\.\d+)?)/i,m,y=g();return y.msie&&y.version>=8||y.chrome&&y.version>=10||y.firefox&&y.version>=4||y.safari&&y.version>=5||y.opera&&y.version>=10?y.a=t:y.msie&&y.version<8||y.chrome&&y.version<10||y.firefox&&y.version<4||y.safari&&y.version<5||y.opera&&y.version<10?y.c=t:y.x=t,y}) \ No newline at end of file +!function(e,t){typeof define=="function"?define(t):typeof module!="undefined"&&module.exports?module.exports[e]=t():this[e]=t()}("bowser",function(){function e(e){var t=!0,n=/(msie|trident)/i.test(e),r=/chrome/i.test(e),i=/phantom/i.test(e),s=/safari/i.test(e)&&!r&&!i,o=/iphone/i.test(e),u=/ipad/i.test(e),a=/touchpad/i.test(e),f=/android/i.test(e),l=/opera/i.test(e)||/opr/i.test(e),c=/firefox/i.test(e),h=/gecko\//i.test(e),p=/seamonkey\//i.test(e),d=/version\/(\d+(\.\d+)?)/i,v=/firefox\/(\d+(\.\d+)?)/i,m;if(n)m={msie:t,version:e.match(/(msie |rv:)(\d+(\.\d+)?)/i)[2]};else if(l)m={opera:t,version:e.match(d)?e.match(d)[1]:e.match(/opr\/(\d+(\.\d+)?)/i)};else if(r)m={webkit:t,chrome:t,version:e.match(/chrome\/(\d+(\.\d+)?)/i)[1]};else if(i)m={webkit:t,phantom:t,version:e.match(/phantomjs\/(\d+(\.\d+)+)/i)[1]};else{if(a)return{webkit:t,touchpad:t,version:e.match(/touchpad\/(\d+(\.\d+)?)/i)[1]};o||u?(m={webkit:t,mobile:t,ios:t,iphone:o,ipad:u},d.test(e)&&(m.version=e.match(d)[1])):f?m={webkit:t,android:t,mobile:t,version:(e.match(d)||e.match(v))[1]}:s?m={webkit:t,safari:t,version:e.match(d)[1]}:h?(m={gecko:t,mozilla:t,version:e.match(v)[1]},c&&(m.firefox=t)):p?m={seamonkey:t,version:e.match(/seamonkey\/(\d+(\.\d+)?)/i)[1]}:m={}}return m.msie&&m.version>=8||m.chrome&&m.version>=10||m.firefox&&m.version>=4||m.safari&&m.version>=5||m.opera&&m.version>=10?m.a=t:m.msie&&m.version<8||m.chrome&&m.version<10||m.firefox&&m.version<4||m.safari&&m.version<5||m.opera&&m.version<10?m.c=t:m.x=t,m}var t=e(typeof navigator!="undefined"?navigator.userAgent:"");return t._detect=e,t}) \ No newline at end of file diff --git a/src/bowser.js b/src/bowser.js index 889be66..2b6ff82 100644 --- a/src/bowser.js +++ b/src/bowser.js @@ -22,44 +22,42 @@ * PhantomJS: "Mozilla/5.0 (Macintosh; Intel Mac OS X) AppleWebKit/534.34 (KHTML, like Gecko) PhantomJS/1.5.0 Safari/534.34" */ - var ua = navigator.userAgent - , t = true - , ie = /(msie|trident)/i.test(ua) - , chrome = /chrome/i.test(ua) - , phantom = /phantom/i.test(ua) - , safari = /safari/i.test(ua) && !chrome && !phantom - , iphone = /iphone/i.test(ua) - , ipad = /ipad/i.test(ua) - , touchpad = /touchpad/i.test(ua) - , android = /android/i.test(ua) - , opera = /opera/i.test(ua) || /opr/i.test(ua) - , firefox = /firefox/i.test(ua) - , gecko = /gecko\//i.test(ua) - , seamonkey = /seamonkey\//i.test(ua) - , webkitVersion = /version\/(\d+(\.\d+)?)/i - , firefoxVersion = /firefox\/(\d+(\.\d+)?)/i - , o; - - function detect() { + function detect(ua) { + var t = true + , ie = /(msie|trident)/i.test(ua) + , chrome = /chrome/i.test(ua) + , phantom = /phantom/i.test(ua) + , safari = /safari/i.test(ua) && !chrome && !phantom + , iphone = /iphone/i.test(ua) + , ipad = /ipad/i.test(ua) + , touchpad = /touchpad/i.test(ua) + , android = /android/i.test(ua) + , opera = /opera/i.test(ua) || /opr/i.test(ua) + , firefox = /firefox/i.test(ua) + , gecko = /gecko\//i.test(ua) + , seamonkey = /seamonkey\//i.test(ua) + , webkitVersion = /version\/(\d+(\.\d+)?)/i + , firefoxVersion = /firefox\/(\d+(\.\d+)?)/i + , o; if (ie) { - return { + o = { msie: t , version: ua.match(/(msie |rv:)(\d+(\.\d+)?)/i)[2] }; } else if (opera) { - return { + o = { opera: t , version: ua.match(webkitVersion) ? ua.match(webkitVersion)[1] : ua.match(/opr\/(\d+(\.\d+)?)/i) }; } else if (chrome) { - return { + o = { webkit: t , chrome: t , version: ua.match(/chrome\/(\d+(\.\d+)?)/i)[1] }; } else if (phantom) { - return { + o = { webkit: t , phantom: t , version: ua.match(/phantomjs\/(\d+(\.\d+)+)/i)[1] @@ -82,16 +80,15 @@ if (webkitVersion.test(ua)) { o.version = ua.match(webkitVersion)[1]; } - return o; } else if (android) { - return { + o = { webkit: t , android: t , mobile: t , version: (ua.match(webkitVersion) || ua.match(firefoxVersion))[1] }; } else if (safari) { - return { + o = { webkit: t , safari: t , version: ua.match(webkitVersion)[1] @@ -103,38 +100,47 @@ , version: ua.match(firefoxVersion)[1] }; if (firefox) o.firefox = t; - return o; } else if (seamonkey) { - return { + o = { seamonkey: t , version: ua.match(/seamonkey\/(\d+(\.\d+)?)/i)[1] }; } else { - return {}; + o = {}; } + + // Graded Browser Support + // http://developer.yahoo.com/yui/articles/gbs + if ((o.msie && o.version >= 8) || + (o.chrome && o.version >= 10) || + (o.firefox && o.version >= 4.0) || + (o.safari && o.version >= 5) || + (o.opera && o.version >= 10.0)) { + o.a = t; + } + + else if ((o.msie && o.version < 8) || + (o.chrome && o.version < 10) || + (o.firefox && o.version < 4.0) || + (o.safari && o.version < 5) || + (o.opera && o.version < 10.0)) { + o.c = t; + } else { + o.x = t; + } + + return o; } - var bowser = detect() - - // Graded Browser Support - // http://developer.yahoo.com/yui/articles/gbs - if ((bowser.msie && bowser.version >= 8) || - (bowser.chrome && bowser.version >= 10) || - (bowser.firefox && bowser.version >= 4.0) || - (bowser.safari && bowser.version >= 5) || - (bowser.opera && bowser.version >= 10.0)) { - bowser.a = t; - } - - else if ((bowser.msie && bowser.version < 8) || - (bowser.chrome && bowser.version < 10) || - (bowser.firefox && bowser.version < 4.0) || - (bowser.safari && bowser.version < 5) || - (bowser.opera && bowser.version < 10.0)) { - bowser.c = t; - } else { - bowser.x = t; - } + /* Get our main bowser object from navigators user agent if present. */ + var bowser = detect(typeof navigator !== 'undefined' ? navigator.userAgent : ''); + + /* + * Set our detect method to the main bowser object so we can + * reuse it to test other user agents. + * This is needed to implement future tests. + */ + bowser._detect = detect; return bowser; -}) +}); From 73ac715e1ebd98d581e27c21a91ef79926dfe7fe Mon Sep 17 00:00:00 2001 From: Hannes Diercks Date: Fri, 13 Sep 2013 14:25:31 +0200 Subject: [PATCH 03/11] Move user agent tests and version matches in callback to improve minification. --- bowser.js | 71 ++++++++++++++++++++++++++++++++------------------- bowser.min.js | 2 +- src/bowser.js | 71 ++++++++++++++++++++++++++++++++------------------- 3 files changed, 91 insertions(+), 53 deletions(-) diff --git a/bowser.js b/bowser.js index 4e4e7b9..1863071 100644 --- a/bowser.js +++ b/bowser.js @@ -29,19 +29,40 @@ */ function detect(ua) { + /** + * Test a given regex against our user agent + * + * @param {RegExp} regex + * @return {Boolean} + */ + function uaTest(regex) { + return regex.test(ua); + } + + /** + * Get version numbers from our user agent. + * + * @param {RegExp} regex + * @return {Number} + */ + function versionTest(regex, i) { + var match = ua.match(regex); + return match ? match[i || 1] : 0; + } + var t = true - , ie = /(msie|trident)/i.test(ua) - , chrome = /chrome/i.test(ua) - , phantom = /phantom/i.test(ua) - , safari = /safari/i.test(ua) && !chrome && !phantom - , iphone = /iphone/i.test(ua) - , ipad = /ipad/i.test(ua) - , touchpad = /touchpad/i.test(ua) - , android = /android/i.test(ua) - , opera = /opera/i.test(ua) || /opr/i.test(ua) - , firefox = /firefox/i.test(ua) - , gecko = /gecko\//i.test(ua) - , seamonkey = /seamonkey\//i.test(ua) + , ie = uaTest(/(msie|trident)/i) + , chrome = uaTest(/chrome/i) + , phantom = uaTest(/phantom/i) + , safari = uaTest(/safari/i) && !chrome && !phantom + , iphone = uaTest(/iphone/i) + , ipad = uaTest(/ipad/i) + , touchpad = uaTest(/touchpad/i) + , android = uaTest(/android/i) + , opera = uaTest(/opera/i) || uaTest(/opr/i) + , firefox = uaTest(/firefox/i) + , gecko = uaTest(/gecko\//i) + , seamonkey = uaTest(/seamonkey\//i) , webkitVersion = /version\/(\d+(\.\d+)?)/i , firefoxVersion = /firefox\/(\d+(\.\d+)?)/i , o; @@ -49,30 +70,30 @@ if (ie) { o = { msie: t - , version: ua.match(/(msie |rv:)(\d+(\.\d+)?)/i)[2] + , version: versionTest(/(msie |rv:)(\d+(\.\d+)?)/i, 2) }; } else if (opera) { o = { opera: t - , version: ua.match(webkitVersion) ? ua.match(webkitVersion)[1] : ua.match(/opr\/(\d+(\.\d+)?)/i) + , version: versionTest(webkitVersion) || versionTest(/opr\/(\d+(\.\d+)?)/i) }; } else if (chrome) { o = { webkit: t , chrome: t - , version: ua.match(/chrome\/(\d+(\.\d+)?)/i)[1] + , version: versionTest(/chrome\/(\d+(\.\d+)?)/i) }; } else if (phantom) { o = { webkit: t , phantom: t - , version: ua.match(/phantomjs\/(\d+(\.\d+)+)/i)[1] + , version: versionTest(/phantomjs\/(\d+(\.\d+)+)/i) }; } else if (touchpad) { - return { + o = { webkit: t , touchpad: t - , version : ua.match(/touchpad\/(\d+(\.\d+)?)/i)[1] + , version : versionTest(/touchpad\/(\d+(\.\d+)?)/i) }; } else if (iphone || ipad) { o = { @@ -81,35 +102,33 @@ , ios: t , iphone: iphone , ipad: ipad - }; // WTF: version is not part of user agent in web apps - if (webkitVersion.test(ua)) { - o.version = ua.match(webkitVersion)[1]; - } + , version: versionTest(webkitVersion) + }; } else if (android) { o = { webkit: t , android: t , mobile: t - , version: (ua.match(webkitVersion) || ua.match(firefoxVersion))[1] + , version: versionTest(webkitVersion) || versionTest(firefoxVersion) }; } else if (safari) { o = { webkit: t , safari: t - , version: ua.match(webkitVersion)[1] + , version: versionTest(webkitVersion) }; } else if (gecko) { o = { gecko: t , mozilla: t - , version: ua.match(firefoxVersion)[1] + , version: versionTest(firefoxVersion) }; if (firefox) o.firefox = t; } else if (seamonkey) { o = { seamonkey: t - , version: ua.match(/seamonkey\/(\d+(\.\d+)?)/i)[1] + , version: versionTest(/seamonkey\/(\d+(\.\d+)?)/i) }; } else { o = {}; diff --git a/bowser.min.js b/bowser.min.js index 63ab1c5..376f1f8 100644 --- a/bowser.min.js +++ b/bowser.min.js @@ -3,4 +3,4 @@ * https://github.com/ded/bowser * MIT License | (c) Dustin Diaz 2013 */ -!function(e,t){typeof define=="function"?define(t):typeof module!="undefined"&&module.exports?module.exports[e]=t():this[e]=t()}("bowser",function(){function e(e){var t=!0,n=/(msie|trident)/i.test(e),r=/chrome/i.test(e),i=/phantom/i.test(e),s=/safari/i.test(e)&&!r&&!i,o=/iphone/i.test(e),u=/ipad/i.test(e),a=/touchpad/i.test(e),f=/android/i.test(e),l=/opera/i.test(e)||/opr/i.test(e),c=/firefox/i.test(e),h=/gecko\//i.test(e),p=/seamonkey\//i.test(e),d=/version\/(\d+(\.\d+)?)/i,v=/firefox\/(\d+(\.\d+)?)/i,m;if(n)m={msie:t,version:e.match(/(msie |rv:)(\d+(\.\d+)?)/i)[2]};else if(l)m={opera:t,version:e.match(d)?e.match(d)[1]:e.match(/opr\/(\d+(\.\d+)?)/i)};else if(r)m={webkit:t,chrome:t,version:e.match(/chrome\/(\d+(\.\d+)?)/i)[1]};else if(i)m={webkit:t,phantom:t,version:e.match(/phantomjs\/(\d+(\.\d+)+)/i)[1]};else{if(a)return{webkit:t,touchpad:t,version:e.match(/touchpad\/(\d+(\.\d+)?)/i)[1]};o||u?(m={webkit:t,mobile:t,ios:t,iphone:o,ipad:u},d.test(e)&&(m.version=e.match(d)[1])):f?m={webkit:t,android:t,mobile:t,version:(e.match(d)||e.match(v))[1]}:s?m={webkit:t,safari:t,version:e.match(d)[1]}:h?(m={gecko:t,mozilla:t,version:e.match(v)[1]},c&&(m.firefox=t)):p?m={seamonkey:t,version:e.match(/seamonkey\/(\d+(\.\d+)?)/i)[1]}:m={}}return m.msie&&m.version>=8||m.chrome&&m.version>=10||m.firefox&&m.version>=4||m.safari&&m.version>=5||m.opera&&m.version>=10?m.a=t:m.msie&&m.version<8||m.chrome&&m.version<10||m.firefox&&m.version<4||m.safari&&m.version<5||m.opera&&m.version<10?m.c=t:m.x=t,m}var t=e(typeof navigator!="undefined"?navigator.userAgent:"");return t._detect=e,t}) \ No newline at end of file +!function(e,t){typeof define=="function"?define(t):typeof module!="undefined"&&module.exports?module.exports[e]=t():this[e]=t()}("bowser",function(){function e(e){function t(t){return t.test(e)}function n(t,n){var r=e.match(t);return r?r[n||1]:0}var r=!0,i=t(/(msie|trident)/i),s=t(/chrome/i),o=t(/phantom/i),u=t(/safari/i)&&!s&&!o,a=t(/iphone/i),f=t(/ipad/i),l=t(/touchpad/i),c=t(/android/i),h=t(/opera/i)||t(/opr/i),p=t(/firefox/i),d=t(/gecko\//i),v=t(/seamonkey\//i),m=/version\/(\d+(\.\d+)?)/i,g=/firefox\/(\d+(\.\d+)?)/i,y;return i?y={msie:r,version:n(/(msie |rv:)(\d+(\.\d+)?)/i,2)}:h?y={opera:r,version:n(m)||n(/opr\/(\d+(\.\d+)?)/i)}:s?y={webkit:r,chrome:r,version:n(/chrome\/(\d+(\.\d+)?)/i)}:o?y={webkit:r,phantom:r,version:n(/phantomjs\/(\d+(\.\d+)+)/i)}:l?y={webkit:r,touchpad:r,version:n(/touchpad\/(\d+(\.\d+)?)/i)}:a||f?y={webkit:r,mobile:r,ios:r,iphone:a,ipad:f,version:n(m)}:c?y={webkit:r,android:r,mobile:r,version:n(m)||n(g)}:u?y={webkit:r,safari:r,version:n(m)}:d?(y={gecko:r,mozilla:r,version:n(g)},p&&(y.firefox=r)):v?y={seamonkey:r,version:n(/seamonkey\/(\d+(\.\d+)?)/i)}:y={},y.msie&&y.version>=8||y.chrome&&y.version>=10||y.firefox&&y.version>=4||y.safari&&y.version>=5||y.opera&&y.version>=10?y.a=r:y.msie&&y.version<8||y.chrome&&y.version<10||y.firefox&&y.version<4||y.safari&&y.version<5||y.opera&&y.version<10?y.c=r:y.x=r,y}var t=e(typeof navigator!="undefined"?navigator.userAgent:"");return t._detect=e,t}) \ No newline at end of file diff --git a/src/bowser.js b/src/bowser.js index 2b6ff82..8822895 100644 --- a/src/bowser.js +++ b/src/bowser.js @@ -23,19 +23,40 @@ */ function detect(ua) { + /** + * Test a given regex against our user agent + * + * @param {RegExp} regex + * @return {Boolean} + */ + function uaTest(regex) { + return regex.test(ua); + } + + /** + * Get version numbers from our user agent. + * + * @param {RegExp} regex + * @return {Number} + */ + function versionTest(regex, i) { + var match = ua.match(regex); + return match ? match[i || 1] : 0; + } + var t = true - , ie = /(msie|trident)/i.test(ua) - , chrome = /chrome/i.test(ua) - , phantom = /phantom/i.test(ua) - , safari = /safari/i.test(ua) && !chrome && !phantom - , iphone = /iphone/i.test(ua) - , ipad = /ipad/i.test(ua) - , touchpad = /touchpad/i.test(ua) - , android = /android/i.test(ua) - , opera = /opera/i.test(ua) || /opr/i.test(ua) - , firefox = /firefox/i.test(ua) - , gecko = /gecko\//i.test(ua) - , seamonkey = /seamonkey\//i.test(ua) + , ie = uaTest(/(msie|trident)/i) + , chrome = uaTest(/chrome/i) + , phantom = uaTest(/phantom/i) + , safari = uaTest(/safari/i) && !chrome && !phantom + , iphone = uaTest(/iphone/i) + , ipad = uaTest(/ipad/i) + , touchpad = uaTest(/touchpad/i) + , android = uaTest(/android/i) + , opera = uaTest(/opera/i) || uaTest(/opr/i) + , firefox = uaTest(/firefox/i) + , gecko = uaTest(/gecko\//i) + , seamonkey = uaTest(/seamonkey\//i) , webkitVersion = /version\/(\d+(\.\d+)?)/i , firefoxVersion = /firefox\/(\d+(\.\d+)?)/i , o; @@ -43,30 +64,30 @@ if (ie) { o = { msie: t - , version: ua.match(/(msie |rv:)(\d+(\.\d+)?)/i)[2] + , version: versionTest(/(msie |rv:)(\d+(\.\d+)?)/i, 2) }; } else if (opera) { o = { opera: t - , version: ua.match(webkitVersion) ? ua.match(webkitVersion)[1] : ua.match(/opr\/(\d+(\.\d+)?)/i) + , version: versionTest(webkitVersion) || versionTest(/opr\/(\d+(\.\d+)?)/i) }; } else if (chrome) { o = { webkit: t , chrome: t - , version: ua.match(/chrome\/(\d+(\.\d+)?)/i)[1] + , version: versionTest(/chrome\/(\d+(\.\d+)?)/i) }; } else if (phantom) { o = { webkit: t , phantom: t - , version: ua.match(/phantomjs\/(\d+(\.\d+)+)/i)[1] + , version: versionTest(/phantomjs\/(\d+(\.\d+)+)/i) }; } else if (touchpad) { - return { + o = { webkit: t , touchpad: t - , version : ua.match(/touchpad\/(\d+(\.\d+)?)/i)[1] + , version : versionTest(/touchpad\/(\d+(\.\d+)?)/i) }; } else if (iphone || ipad) { o = { @@ -75,35 +96,33 @@ , ios: t , iphone: iphone , ipad: ipad - }; // WTF: version is not part of user agent in web apps - if (webkitVersion.test(ua)) { - o.version = ua.match(webkitVersion)[1]; - } + , version: versionTest(webkitVersion) + }; } else if (android) { o = { webkit: t , android: t , mobile: t - , version: (ua.match(webkitVersion) || ua.match(firefoxVersion))[1] + , version: versionTest(webkitVersion) || versionTest(firefoxVersion) }; } else if (safari) { o = { webkit: t , safari: t - , version: ua.match(webkitVersion)[1] + , version: versionTest(webkitVersion) }; } else if (gecko) { o = { gecko: t , mozilla: t - , version: ua.match(firefoxVersion)[1] + , version: versionTest(firefoxVersion) }; if (firefox) o.firefox = t; } else if (seamonkey) { o = { seamonkey: t - , version: ua.match(/seamonkey\/(\d+(\.\d+)?)/i)[1] + , version: versionTest(/seamonkey\/(\d+(\.\d+)?)/i) }; } else { o = {}; From 38478c576dc99d6399e3bdcbf91d5d0fb486c0c6 Mon Sep 17 00:00:00 2001 From: Hannes Diercks Date: Fri, 13 Sep 2013 14:30:33 +0200 Subject: [PATCH 04/11] Move user agent tests to if clauses for better minification and less function calls. --- bowser.js | 32 ++++++++++++-------------------- bowser.min.js | 2 +- src/bowser.js | 32 ++++++++++++-------------------- 3 files changed, 25 insertions(+), 41 deletions(-) diff --git a/bowser.js b/bowser.js index 1863071..082cd47 100644 --- a/bowser.js +++ b/bowser.js @@ -51,45 +51,35 @@ } var t = true - , ie = uaTest(/(msie|trident)/i) - , chrome = uaTest(/chrome/i) - , phantom = uaTest(/phantom/i) - , safari = uaTest(/safari/i) && !chrome && !phantom , iphone = uaTest(/iphone/i) , ipad = uaTest(/ipad/i) - , touchpad = uaTest(/touchpad/i) - , android = uaTest(/android/i) - , opera = uaTest(/opera/i) || uaTest(/opr/i) - , firefox = uaTest(/firefox/i) - , gecko = uaTest(/gecko\//i) - , seamonkey = uaTest(/seamonkey\//i) , webkitVersion = /version\/(\d+(\.\d+)?)/i , firefoxVersion = /firefox\/(\d+(\.\d+)?)/i , o; - if (ie) { + if (uaTest(/(msie|trident)/i)) { o = { msie: t , version: versionTest(/(msie |rv:)(\d+(\.\d+)?)/i, 2) }; - } else if (opera) { + } else if (uaTest(/opera/i) || uaTest(/opr/i)) { o = { opera: t , version: versionTest(webkitVersion) || versionTest(/opr\/(\d+(\.\d+)?)/i) }; - } else if (chrome) { + } else if (uaTest(/chrome/i)) { o = { webkit: t , chrome: t , version: versionTest(/chrome\/(\d+(\.\d+)?)/i) }; - } else if (phantom) { + } else if (uaTest(/phantom/i)) { o = { webkit: t , phantom: t , version: versionTest(/phantomjs\/(\d+(\.\d+)+)/i) }; - } else if (touchpad) { + } else if (uaTest(/touchpad/i)) { o = { webkit: t , touchpad: t @@ -105,27 +95,29 @@ // WTF: version is not part of user agent in web apps , version: versionTest(webkitVersion) }; - } else if (android) { + } else if (uaTest(/android/i)) { o = { webkit: t , android: t , mobile: t , version: versionTest(webkitVersion) || versionTest(firefoxVersion) }; - } else if (safari) { + } else if (uaTest(/safari/i)) { o = { webkit: t , safari: t , version: versionTest(webkitVersion) }; - } else if (gecko) { + } else if (uaTest(/gecko\//i)) { o = { gecko: t , mozilla: t , version: versionTest(firefoxVersion) }; - if (firefox) o.firefox = t; - } else if (seamonkey) { + if (uaTest(/firefox/i)) { + o.firefox = t; + } + } else if (uaTest(/seamonkey\//i)) { o = { seamonkey: t , version: versionTest(/seamonkey\/(\d+(\.\d+)?)/i) diff --git a/bowser.min.js b/bowser.min.js index 376f1f8..ed48146 100644 --- a/bowser.min.js +++ b/bowser.min.js @@ -3,4 +3,4 @@ * https://github.com/ded/bowser * MIT License | (c) Dustin Diaz 2013 */ -!function(e,t){typeof define=="function"?define(t):typeof module!="undefined"&&module.exports?module.exports[e]=t():this[e]=t()}("bowser",function(){function e(e){function t(t){return t.test(e)}function n(t,n){var r=e.match(t);return r?r[n||1]:0}var r=!0,i=t(/(msie|trident)/i),s=t(/chrome/i),o=t(/phantom/i),u=t(/safari/i)&&!s&&!o,a=t(/iphone/i),f=t(/ipad/i),l=t(/touchpad/i),c=t(/android/i),h=t(/opera/i)||t(/opr/i),p=t(/firefox/i),d=t(/gecko\//i),v=t(/seamonkey\//i),m=/version\/(\d+(\.\d+)?)/i,g=/firefox\/(\d+(\.\d+)?)/i,y;return i?y={msie:r,version:n(/(msie |rv:)(\d+(\.\d+)?)/i,2)}:h?y={opera:r,version:n(m)||n(/opr\/(\d+(\.\d+)?)/i)}:s?y={webkit:r,chrome:r,version:n(/chrome\/(\d+(\.\d+)?)/i)}:o?y={webkit:r,phantom:r,version:n(/phantomjs\/(\d+(\.\d+)+)/i)}:l?y={webkit:r,touchpad:r,version:n(/touchpad\/(\d+(\.\d+)?)/i)}:a||f?y={webkit:r,mobile:r,ios:r,iphone:a,ipad:f,version:n(m)}:c?y={webkit:r,android:r,mobile:r,version:n(m)||n(g)}:u?y={webkit:r,safari:r,version:n(m)}:d?(y={gecko:r,mozilla:r,version:n(g)},p&&(y.firefox=r)):v?y={seamonkey:r,version:n(/seamonkey\/(\d+(\.\d+)?)/i)}:y={},y.msie&&y.version>=8||y.chrome&&y.version>=10||y.firefox&&y.version>=4||y.safari&&y.version>=5||y.opera&&y.version>=10?y.a=r:y.msie&&y.version<8||y.chrome&&y.version<10||y.firefox&&y.version<4||y.safari&&y.version<5||y.opera&&y.version<10?y.c=r:y.x=r,y}var t=e(typeof navigator!="undefined"?navigator.userAgent:"");return t._detect=e,t}) \ No newline at end of file +!function(e,t){typeof define=="function"?define(t):typeof module!="undefined"&&module.exports?module.exports[e]=t():this[e]=t()}("bowser",function(){function e(e){function t(t){return t.test(e)}function n(t,n){var r=e.match(t);return r?r[n||1]:0}var r=!0,i=t(/iphone/i),s=t(/ipad/i),o=/version\/(\d+(\.\d+)?)/i,u=/firefox\/(\d+(\.\d+)?)/i,a;if(t(/(msie|trident)/i))a={msie:r,version:n(/(msie |rv:)(\d+(\.\d+)?)/i,2)};else if(t(/opera/i)||t(/opr/i))a={opera:r,version:n(o)||n(/opr\/(\d+(\.\d+)?)/i)};else if(t(/chrome/i))a={webkit:r,chrome:r,version:n(/chrome\/(\d+(\.\d+)?)/i)};else if(t(/phantom/i))a={webkit:r,phantom:r,version:n(/phantomjs\/(\d+(\.\d+)+)/i)};else{if(t(/touchpad/i))return{webkit:r,touchpad:r,version:n(/touchpad\/(\d+(\.\d+)?)/i)};i||s?a={webkit:r,mobile:r,ios:r,iphone:i,ipad:s,version:n(o)}:t(/android/i)?a={webkit:r,android:r,mobile:r,version:n(o)||n(u)}:t(/safari/i)?a={webkit:r,safari:r,version:n(o)}:t(/gecko\//i)?(a={gecko:r,mozilla:r,version:n(u)},t(/firefox/i)&&(a.firefox=r)):t(/seamonkey\//i)?a={seamonkey:r,version:n(/seamonkey\/(\d+(\.\d+)?)/i)}:a={}}return a.msie&&a.version>=8||a.chrome&&a.version>=10||a.firefox&&a.version>=4||a.safari&&a.version>=5||a.opera&&a.version>=10?a.a=r:a.msie&&a.version<8||a.chrome&&a.version<10||a.firefox&&a.version<4||a.safari&&a.version<5||a.opera&&a.version<10?a.c=r:a.x=r,a}var t=e(typeof navigator!="undefined"?navigator.userAgent:"");return t._detect=e,t}) diff --git a/src/bowser.js b/src/bowser.js index 8822895..fb8bd7f 100644 --- a/src/bowser.js +++ b/src/bowser.js @@ -45,45 +45,35 @@ } var t = true - , ie = uaTest(/(msie|trident)/i) - , chrome = uaTest(/chrome/i) - , phantom = uaTest(/phantom/i) - , safari = uaTest(/safari/i) && !chrome && !phantom , iphone = uaTest(/iphone/i) , ipad = uaTest(/ipad/i) - , touchpad = uaTest(/touchpad/i) - , android = uaTest(/android/i) - , opera = uaTest(/opera/i) || uaTest(/opr/i) - , firefox = uaTest(/firefox/i) - , gecko = uaTest(/gecko\//i) - , seamonkey = uaTest(/seamonkey\//i) , webkitVersion = /version\/(\d+(\.\d+)?)/i , firefoxVersion = /firefox\/(\d+(\.\d+)?)/i , o; - if (ie) { + if (uaTest(/(msie|trident)/i)) { o = { msie: t , version: versionTest(/(msie |rv:)(\d+(\.\d+)?)/i, 2) }; - } else if (opera) { + } else if (uaTest(/opera/i) || uaTest(/opr/i)) { o = { opera: t , version: versionTest(webkitVersion) || versionTest(/opr\/(\d+(\.\d+)?)/i) }; - } else if (chrome) { + } else if (uaTest(/chrome/i)) { o = { webkit: t , chrome: t , version: versionTest(/chrome\/(\d+(\.\d+)?)/i) }; - } else if (phantom) { + } else if (uaTest(/phantom/i)) { o = { webkit: t , phantom: t , version: versionTest(/phantomjs\/(\d+(\.\d+)+)/i) }; - } else if (touchpad) { + } else if (uaTest(/touchpad/i)) { o = { webkit: t , touchpad: t @@ -99,27 +89,29 @@ // WTF: version is not part of user agent in web apps , version: versionTest(webkitVersion) }; - } else if (android) { + } else if (uaTest(/android/i)) { o = { webkit: t , android: t , mobile: t , version: versionTest(webkitVersion) || versionTest(firefoxVersion) }; - } else if (safari) { + } else if (uaTest(/safari/i)) { o = { webkit: t , safari: t , version: versionTest(webkitVersion) }; - } else if (gecko) { + } else if (uaTest(/gecko\//i)) { o = { gecko: t , mozilla: t , version: versionTest(firefoxVersion) }; - if (firefox) o.firefox = t; - } else if (seamonkey) { + if (uaTest(/firefox/i)) { + o.firefox = t; + } + } else if (uaTest(/seamonkey\//i)) { o = { seamonkey: t , version: versionTest(/seamonkey\/(\d+(\.\d+)?)/i) From 7650c935bf5cfec73e8bb7381f8c0c1ae6d805de Mon Sep 17 00:00:00 2001 From: Hannes Diercks Date: Fri, 13 Sep 2013 14:52:14 +0200 Subject: [PATCH 05/11] Add tests. --- Makefile | 16 +++++++- src/bowser.js | 9 +++-- src/useragents.js | 93 +++++++++++++++++++++++++++++++++++++++++++++++ test/test.js | 62 +++++++++++++++++++++++++++++++ 4 files changed, 176 insertions(+), 4 deletions(-) create mode 100644 src/useragents.js create mode 100644 test/test.js diff --git a/Makefile b/Makefile index 09b69fe..d5cd37f 100644 --- a/Makefile +++ b/Makefile @@ -1,2 +1,16 @@ boosh: - node make/build.js \ No newline at end of file + node make/build.js + +REPORTER = dot + +test: + @NODE_ENV=test ./node_modules/.bin/mocha \ + --reporter $(REPORTER) \ + +test-w: + @NODE_ENV=test ./node_modules/.bin/mocha \ + --reporter $(REPORTER) \ + --growl \ + --watch + +.PHONY: test test-w diff --git a/src/bowser.js b/src/bowser.js index fb8bd7f..8c211fd 100644 --- a/src/bowser.js +++ b/src/bowser.js @@ -71,7 +71,7 @@ o = { webkit: t , phantom: t - , version: versionTest(/phantomjs\/(\d+(\.\d+)+)/i) + , version: versionTest(/phantomjs\/(\d+(\.\d+)?)/i) }; } else if (uaTest(/touchpad/i)) { o = { @@ -84,11 +84,14 @@ webkit: t , mobile: t , ios: t - , iphone: iphone - , ipad: ipad // WTF: version is not part of user agent in web apps , version: versionTest(webkitVersion) }; + if (iphone) { + o.iphone = t; + } else if (ipad) { + o.ipad = t; + } } else if (uaTest(/android/i)) { o = { webkit: t diff --git a/src/useragents.js b/src/useragents.js new file mode 100644 index 0000000..574cc16 --- /dev/null +++ b/src/useragents.js @@ -0,0 +1,93 @@ +/** + * Example User Agents and thair expected bowser objects. + * + * @see test/test.js + * @author hannes.diercks@jimdo.com + */ + +module.exports.useragents = { + Chrome: { + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_7) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.57 Safari/534.24': { + chrome: true, + version: '11.0', + webkit: true, + a: true + } + }, + Opera: { + 'Opera/9.80 (Macintosh; Intel Mac OS X 10.6.7; U; en) Presto/2.7.62 Version/11.01': { + opera: true, + version: '11.01', + a: true + } + }, + Safari: { + 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-us) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1': { + safari: true, + version: '5.0', + webkit: true, + a: true + } + }, + 'Internet Explorer': { + 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C)': { + msie: true, + version: '8.0', + a: true + } + }, + Firefox: { + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0) Gecko/20100101 Firefox/4.0': { + mozilla: true, + gecko: true, + firefox: true, + version: '4.0', + a: true + } + }, + iPhone: { + 'Mozilla/5.0 (iPhone Simulator; U; CPU iPhone OS 4_3_2 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8H7 Safari/6533.18.5': { + ios: true, + version: '5.0', + iphone: true, + mobile: true, + webkit: true, + x: true + } + }, + iPad: { + 'Mozilla/5.0 (iPad; U; CPU OS 4_3_2 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8H7 Safari/6533.18.5': { + ios: true, + version: '5.0', + ipad: true, + mobile: true, + webkit: true, + x: true + } + }, + Android: { + 'Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; T-Mobile G2 Build/GRJ22) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1': { + android: true, + webkit: true, + version: 4.0, + mobile: true, + x: true + } + }, + Touchpad: { + 'Mozilla/5.0 (hp-tabled;Linux;hpwOS/3.0.5; U; en-US)) AppleWebKit/534.6 (KHTML, like Gecko) wOSBrowser/234.83 Safari/534.6 TouchPad/1.0': { + touchpad: true, + version: '1.0', + webkit: true, + x: true + } + }, + PhantomJS: { + 'Mozilla/5.0 (Macintosh; Intel Mac OS X) AppleWebKit/534.34 (KHTML, like Gecko) PhantomJS/1.5.0 Safari/534.34': { + phantom: true, + webkit: true, + version: '1.5', + x: true + } + } +}; diff --git a/test/test.js b/test/test.js new file mode 100644 index 0000000..963dfa8 --- /dev/null +++ b/test/test.js @@ -0,0 +1,62 @@ +/** + * Loop through all entries in our user agents object and test everything. + * + * @see src/useragents.js + * @author hannes.diercks@jimdo.com + */ + +var g, ua, p, + assert = require('assert'), + bowser = require('../src/bowser').bowser, + allUserAgents = require('../src/useragents').useragents; + + +/** + * Get the length of an object. + * http://stackoverflow.com/questions/5223/length-of-javascript-object-ie-associative-array + * + * @param {Object} obj + * @return {Number} + */ +function objLength(obj) { + var size = 0, key; + for (key in obj) { + if (obj.hasOwnProperty(key)) { + size++; + } + } + return size; +} + +/* Groups */ +for (g in allUserAgents) { (function(group, userAgents) { + describe(group, function() { + + /* User Agents */ + for (ua in userAgents) { (function(userAgent, expections) { + describe('#' + userAgent, function() { + + /* Get the result from bowser. */ + var result = bowser._detect(userAgent), + expectionLength = objLength(expections); + + /* At first, check if the result has the correct length. */ + it('Should have ' + expectionLength + ' properties', function() { + assert.equal(objLength(result), expectionLength); + }); + + /* Properties */ + for (p in expections) { (function(property, value, resultValue) { + + /* Now ensure correctness of every property. */ + it('\'s Property "' + property + '" should be ' + value, function() { + assert.equal(resultValue, value); + }); + + })(p, expections[p], result[p]); } + + }); + })(ua, userAgents[ua]); } + + }); +})(g, allUserAgents[g]); } From 2d6b83fc2d4b4a6709ab3c0ca397ba58610073a9 Mon Sep 17 00:00:00 2001 From: Hannes Diercks Date: Fri, 13 Sep 2013 15:09:15 +0200 Subject: [PATCH 06/11] Introduce constants to shorten object property names and improve minification. --- bowser.js | 142 ++++++++++++++++++++++++++------------------------ bowser.min.js | 2 +- src/bowser.js | 139 ++++++++++++++++++++++++------------------------ 3 files changed, 144 insertions(+), 139 deletions(-) diff --git a/bowser.js b/bowser.js index 082cd47..980781e 100644 --- a/bowser.js +++ b/bowser.js @@ -28,6 +28,34 @@ * PhantomJS: "Mozilla/5.0 (Macintosh; Intel Mac OS X) AppleWebKit/534.34 (KHTML, like Gecko) PhantomJS/1.5.0 Safari/534.34" */ + /** @const */ + var TRUE = true; + + /** @const */ + var STR_VERSION = 'version'; + + /** @const */ + var STR_MOBILE = 'mobile'; + + /** @const */ + var STR_MSIE = 'msie'; + + /** @const */ + var STR_OPERA = 'opera'; + + /** @const */ + var STR_CHROME = 'chrome'; + + /** @const */ + var STR_WEBKIT = 'webkit'; + + /** @const */ + var STR_SAFARI = 'safari'; + + /** @const */ + var STR_FIREFOX = 'firefox'; + + function detect(ua) { /** * Test a given regex against our user agent @@ -50,100 +78,76 @@ return match ? match[i || 1] : 0; } - var t = true - , iphone = uaTest(/iphone/i) + var iphone = uaTest(/iphone/i) , ipad = uaTest(/ipad/i) , webkitVersion = /version\/(\d+(\.\d+)?)/i , firefoxVersion = /firefox\/(\d+(\.\d+)?)/i - , o; + , o = {} + , version = 0; if (uaTest(/(msie|trident)/i)) { - o = { - msie: t - , version: versionTest(/(msie |rv:)(\d+(\.\d+)?)/i, 2) - }; + o[STR_MSIE] = TRUE; + o[STR_VERSION] = versionTest(/(msie |rv:)(\d+(\.\d+)?)/i, 2); } else if (uaTest(/opera/i) || uaTest(/opr/i)) { - o = { - opera: t - , version: versionTest(webkitVersion) || versionTest(/opr\/(\d+(\.\d+)?)/i) - }; + o[STR_OPERA] = TRUE; + o[STR_VERSION] = versionTest(webkitVersion) || versionTest(/opr\/(\d+(\.\d+)?)/i); } else if (uaTest(/chrome/i)) { - o = { - webkit: t - , chrome: t - , version: versionTest(/chrome\/(\d+(\.\d+)?)/i) - }; + o[STR_CHROME] = o[STR_WEBKIT] = TRUE; + o[STR_VERSION] = versionTest(/chrome\/(\d+(\.\d+)?)/i); } else if (uaTest(/phantom/i)) { - o = { - webkit: t - , phantom: t - , version: versionTest(/phantomjs\/(\d+(\.\d+)+)/i) - }; + o.phantom = o[STR_WEBKIT] = TRUE; + o[STR_VERSION] = versionTest(/phantomjs\/(\d+(\.\d+)?)/i); } else if (uaTest(/touchpad/i)) { - o = { - webkit: t - , touchpad: t - , version : versionTest(/touchpad\/(\d+(\.\d+)?)/i) - }; + o.touchpad = o[STR_WEBKIT] = TRUE; + o[STR_VERSION] = versionTest(/touchpad\/(\d+(\.\d+)?)/i); } else if (iphone || ipad) { - o = { - webkit: t - , mobile: t - , ios: t - , iphone: iphone - , ipad: ipad + o.ios = o[STR_MOBILE] = o[STR_WEBKIT] = TRUE; // WTF: version is not part of user agent in web apps - , version: versionTest(webkitVersion) - }; + o[STR_VERSION] = versionTest(webkitVersion); + if (iphone) { + o.iphone = TRUE; + } else if (ipad) { + o.ipad = TRUE; + } } else if (uaTest(/android/i)) { - o = { - webkit: t - , android: t - , mobile: t - , version: versionTest(webkitVersion) || versionTest(firefoxVersion) - }; + o.android = o[STR_MOBILE] = o[STR_WEBKIT] = TRUE; + o[STR_VERSION] = versionTest(webkitVersion) || versionTest(firefoxVersion); } else if (uaTest(/safari/i)) { - o = { - webkit: t - , safari: t - , version: versionTest(webkitVersion) - }; + o[STR_SAFARI] = o[STR_WEBKIT] = TRUE; + o[STR_VERSION] = versionTest(webkitVersion); } else if (uaTest(/gecko\//i)) { - o = { - gecko: t - , mozilla: t - , version: versionTest(firefoxVersion) - }; + o.gecko = o.mozilla = TRUE; + o[STR_VERSION] = versionTest(firefoxVersion); if (uaTest(/firefox/i)) { - o.firefox = t; + o.firefox = TRUE; } } else if (uaTest(/seamonkey\//i)) { - o = { - seamonkey: t - , version: versionTest(/seamonkey\/(\d+(\.\d+)?)/i) - }; + o.seamonkey = TRUE; + o[STR_VERSION] = versionTest(/seamonkey\/(\d+(\.\d+)?)/i); } else { - o = {}; + o[STR_VERSION] = 0; } + version = o[STR_VERSION]; + // Graded Browser Support // http://developer.yahoo.com/yui/articles/gbs - if ((o.msie && o.version >= 8) || - (o.chrome && o.version >= 10) || - (o.firefox && o.version >= 4.0) || - (o.safari && o.version >= 5) || - (o.opera && o.version >= 10.0)) { - o.a = t; + if ((o[STR_MSIE] && version >= 8) || + (o[STR_CHROME] && version >= 10) || + (o[STR_FIREFOX] && version >= 4.0) || + (o[STR_SAFARI] && version >= 5) || + (o[STR_OPERA] && version >= 10.0)) { + o.a = TRUE; } - else if ((o.msie && o.version < 8) || - (o.chrome && o.version < 10) || - (o.firefox && o.version < 4.0) || - (o.safari && o.version < 5) || - (o.opera && o.version < 10.0)) { - o.c = t; + else if ((o[STR_MSIE] && version < 8) || + (o[STR_CHROME] && version < 10) || + (o[STR_FIREFOX] && version < 4.0) || + (o[STR_SAFARI] && version < 5) || + (o[STR_OPERA] && version < 10.0)) { + o.c = TRUE; } else { - o.x = t; + o.x = TRUE; } return o; diff --git a/bowser.min.js b/bowser.min.js index ed48146..8546b85 100644 --- a/bowser.min.js +++ b/bowser.min.js @@ -3,4 +3,4 @@ * https://github.com/ded/bowser * MIT License | (c) Dustin Diaz 2013 */ -!function(e,t){typeof define=="function"?define(t):typeof module!="undefined"&&module.exports?module.exports[e]=t():this[e]=t()}("bowser",function(){function e(e){function t(t){return t.test(e)}function n(t,n){var r=e.match(t);return r?r[n||1]:0}var r=!0,i=t(/iphone/i),s=t(/ipad/i),o=/version\/(\d+(\.\d+)?)/i,u=/firefox\/(\d+(\.\d+)?)/i,a;if(t(/(msie|trident)/i))a={msie:r,version:n(/(msie |rv:)(\d+(\.\d+)?)/i,2)};else if(t(/opera/i)||t(/opr/i))a={opera:r,version:n(o)||n(/opr\/(\d+(\.\d+)?)/i)};else if(t(/chrome/i))a={webkit:r,chrome:r,version:n(/chrome\/(\d+(\.\d+)?)/i)};else if(t(/phantom/i))a={webkit:r,phantom:r,version:n(/phantomjs\/(\d+(\.\d+)+)/i)};else{if(t(/touchpad/i))return{webkit:r,touchpad:r,version:n(/touchpad\/(\d+(\.\d+)?)/i)};i||s?a={webkit:r,mobile:r,ios:r,iphone:i,ipad:s,version:n(o)}:t(/android/i)?a={webkit:r,android:r,mobile:r,version:n(o)||n(u)}:t(/safari/i)?a={webkit:r,safari:r,version:n(o)}:t(/gecko\//i)?(a={gecko:r,mozilla:r,version:n(u)},t(/firefox/i)&&(a.firefox=r)):t(/seamonkey\//i)?a={seamonkey:r,version:n(/seamonkey\/(\d+(\.\d+)?)/i)}:a={}}return a.msie&&a.version>=8||a.chrome&&a.version>=10||a.firefox&&a.version>=4||a.safari&&a.version>=5||a.opera&&a.version>=10?a.a=r:a.msie&&a.version<8||a.chrome&&a.version<10||a.firefox&&a.version<4||a.safari&&a.version<5||a.opera&&a.version<10?a.c=r:a.x=r,a}var t=e(typeof navigator!="undefined"?navigator.userAgent:"");return t._detect=e,t}) +!function(e,t){typeof define=="function"?define(t):typeof module!="undefined"&&module.exports?module.exports[e]=t():this[e]=t()}("bowser",function(){function f(f){function l(e){return e.test(f)}function c(e,t){var n=f.match(e);return n?n[t||1]:0}var h=l(/iphone/i),p=l(/ipad/i),d=/version\/(\d+(\.\d+)?)/i,v=/firefox\/(\d+(\.\d+)?)/i,m={},g=0;return l(/(msie|trident)/i)?(m[r]=e,m[t]=c(/(msie |rv:)(\d+(\.\d+)?)/i,2)):l(/opera/i)||l(/opr/i)?(m[i]=e,m[t]=c(d)||c(/opr\/(\d+(\.\d+)?)/i)):l(/chrome/i)?(m[s]=m[o]=e,m[t]=c(/chrome\/(\d+(\.\d+)?)/i)):l(/phantom/i)?(m.phantom=m[o]=e,m[t]=c(/phantomjs\/(\d+(\.\d+)?)/i)):l(/touchpad/i)?(m.touchpad=m[o]=e,m[t]=c(/touchpad\/(\d+(\.\d+)?)/i)):h||p?(m.ios=m[n]=m[o]=e,m[t]=c(d),h?m.iphone=e:p&&(m.ipad=e)):l(/android/i)?(m.android=m[n]=m[o]=e,m[t]=c(d)||c(v)):l(/safari/i)?(m[u]=m[o]=e,m[t]=c(d)):l(/gecko\//i)?(m.gecko=m.mozilla=e,m[t]=c(v),l(/firefox/i)&&(m.firefox=e)):l(/seamonkey\//i)?(m.seamonkey=e,m[t]=c(/seamonkey\/(\d+(\.\d+)?)/i)):m[t]=0,g=m[t],m[r]&&g>=8||m[s]&&g>=10||m[a]&&g>=4||m[u]&&g>=5||m[i]&&g>=10?m.a=e:m[r]&&g<8||m[s]&&g<10||m[a]&&g<4||m[u]&&g<5||m[i]&&g<10?m.c=e:m.x=e,m}var e=!0,t="version",n="mobile",r="msie",i="opera",s="chrome",o="webkit",u="safari",a="firefox",l=f(typeof navigator!="undefined"?navigator.userAgent:"");return l._detect=f,l}) \ No newline at end of file diff --git a/src/bowser.js b/src/bowser.js index 8c211fd..8b1506e 100644 --- a/src/bowser.js +++ b/src/bowser.js @@ -22,6 +22,34 @@ * PhantomJS: "Mozilla/5.0 (Macintosh; Intel Mac OS X) AppleWebKit/534.34 (KHTML, like Gecko) PhantomJS/1.5.0 Safari/534.34" */ + /** @const */ + var TRUE = true; + + /** @const */ + var STR_VERSION = 'version'; + + /** @const */ + var STR_MOBILE = 'mobile'; + + /** @const */ + var STR_MSIE = 'msie'; + + /** @const */ + var STR_OPERA = 'opera'; + + /** @const */ + var STR_CHROME = 'chrome'; + + /** @const */ + var STR_WEBKIT = 'webkit'; + + /** @const */ + var STR_SAFARI = 'safari'; + + /** @const */ + var STR_FIREFOX = 'firefox'; + + function detect(ua) { /** * Test a given regex against our user agent @@ -44,103 +72,76 @@ return match ? match[i || 1] : 0; } - var t = true - , iphone = uaTest(/iphone/i) + var iphone = uaTest(/iphone/i) , ipad = uaTest(/ipad/i) , webkitVersion = /version\/(\d+(\.\d+)?)/i , firefoxVersion = /firefox\/(\d+(\.\d+)?)/i - , o; + , o = {} + , version = 0; if (uaTest(/(msie|trident)/i)) { - o = { - msie: t - , version: versionTest(/(msie |rv:)(\d+(\.\d+)?)/i, 2) - }; + o[STR_MSIE] = TRUE; + o[STR_VERSION] = versionTest(/(msie |rv:)(\d+(\.\d+)?)/i, 2); } else if (uaTest(/opera/i) || uaTest(/opr/i)) { - o = { - opera: t - , version: versionTest(webkitVersion) || versionTest(/opr\/(\d+(\.\d+)?)/i) - }; + o[STR_OPERA] = TRUE; + o[STR_VERSION] = versionTest(webkitVersion) || versionTest(/opr\/(\d+(\.\d+)?)/i); } else if (uaTest(/chrome/i)) { - o = { - webkit: t - , chrome: t - , version: versionTest(/chrome\/(\d+(\.\d+)?)/i) - }; + o[STR_CHROME] = o[STR_WEBKIT] = TRUE; + o[STR_VERSION] = versionTest(/chrome\/(\d+(\.\d+)?)/i); } else if (uaTest(/phantom/i)) { - o = { - webkit: t - , phantom: t - , version: versionTest(/phantomjs\/(\d+(\.\d+)?)/i) - }; + o.phantom = o[STR_WEBKIT] = TRUE; + o[STR_VERSION] = versionTest(/phantomjs\/(\d+(\.\d+)?)/i); } else if (uaTest(/touchpad/i)) { - o = { - webkit: t - , touchpad: t - , version : versionTest(/touchpad\/(\d+(\.\d+)?)/i) - }; + o.touchpad = o[STR_WEBKIT] = TRUE; + o[STR_VERSION] = versionTest(/touchpad\/(\d+(\.\d+)?)/i); } else if (iphone || ipad) { - o = { - webkit: t - , mobile: t - , ios: t + o.ios = o[STR_MOBILE] = o[STR_WEBKIT] = TRUE; // WTF: version is not part of user agent in web apps - , version: versionTest(webkitVersion) - }; + o[STR_VERSION] = versionTest(webkitVersion); if (iphone) { - o.iphone = t; + o.iphone = TRUE; } else if (ipad) { - o.ipad = t; + o.ipad = TRUE; } } else if (uaTest(/android/i)) { - o = { - webkit: t - , android: t - , mobile: t - , version: versionTest(webkitVersion) || versionTest(firefoxVersion) - }; + o.android = o[STR_MOBILE] = o[STR_WEBKIT] = TRUE; + o[STR_VERSION] = versionTest(webkitVersion) || versionTest(firefoxVersion); } else if (uaTest(/safari/i)) { - o = { - webkit: t - , safari: t - , version: versionTest(webkitVersion) - }; + o[STR_SAFARI] = o[STR_WEBKIT] = TRUE; + o[STR_VERSION] = versionTest(webkitVersion); } else if (uaTest(/gecko\//i)) { - o = { - gecko: t - , mozilla: t - , version: versionTest(firefoxVersion) - }; + o.gecko = o.mozilla = TRUE; + o[STR_VERSION] = versionTest(firefoxVersion); if (uaTest(/firefox/i)) { - o.firefox = t; + o.firefox = TRUE; } } else if (uaTest(/seamonkey\//i)) { - o = { - seamonkey: t - , version: versionTest(/seamonkey\/(\d+(\.\d+)?)/i) - }; + o.seamonkey = TRUE; + o[STR_VERSION] = versionTest(/seamonkey\/(\d+(\.\d+)?)/i); } else { - o = {}; + o[STR_VERSION] = 0; } + version = o[STR_VERSION]; + // Graded Browser Support // http://developer.yahoo.com/yui/articles/gbs - if ((o.msie && o.version >= 8) || - (o.chrome && o.version >= 10) || - (o.firefox && o.version >= 4.0) || - (o.safari && o.version >= 5) || - (o.opera && o.version >= 10.0)) { - o.a = t; + if ((o[STR_MSIE] && version >= 8) || + (o[STR_CHROME] && version >= 10) || + (o[STR_FIREFOX] && version >= 4.0) || + (o[STR_SAFARI] && version >= 5) || + (o[STR_OPERA] && version >= 10.0)) { + o.a = TRUE; } - else if ((o.msie && o.version < 8) || - (o.chrome && o.version < 10) || - (o.firefox && o.version < 4.0) || - (o.safari && o.version < 5) || - (o.opera && o.version < 10.0)) { - o.c = t; + else if ((o[STR_MSIE] && version < 8) || + (o[STR_CHROME] && version < 10) || + (o[STR_FIREFOX] && version < 4.0) || + (o[STR_SAFARI] && version < 5) || + (o[STR_OPERA] && version < 10.0)) { + o.c = TRUE; } else { - o.x = t; + o.x = TRUE; } return o; From 4d5db699bd1caf386995e5577e69bf99131a3251 Mon Sep 17 00:00:00 2001 From: Hannes Diercks Date: Fri, 13 Sep 2013 15:21:31 +0200 Subject: [PATCH 07/11] Move the versionNumber matcher to the matcher function to improve minification. --- bowser.js | 33 +++++++++++++++++---------------- bowser.min.js | 2 +- src/bowser.js | 33 +++++++++++++++++---------------- 3 files changed, 35 insertions(+), 33 deletions(-) diff --git a/bowser.js b/bowser.js index 980781e..9edefc1 100644 --- a/bowser.js +++ b/bowser.js @@ -68,42 +68,43 @@ } /** - * Get version numbers from our user agent. + * Append version number matcher to our starting string + * and get version number from our user agent. * - * @param {RegExp} regex + * @param {String} start * @return {Number} */ - function versionTest(regex, i) { - var match = ua.match(regex); + function versionTest(start, i) { + var match = ua.match(new RegExp(start + '(\\d+(\\.\\d+)?)', 'i')); return match ? match[i || 1] : 0; } var iphone = uaTest(/iphone/i) , ipad = uaTest(/ipad/i) - , webkitVersion = /version\/(\d+(\.\d+)?)/i - , firefoxVersion = /firefox\/(\d+(\.\d+)?)/i + , webkitVersion = versionTest(STR_VERSION + '\/') + , firefoxVersion = versionTest(STR_FIREFOX + '[\/ ]') , o = {} , version = 0; if (uaTest(/(msie|trident)/i)) { o[STR_MSIE] = TRUE; - o[STR_VERSION] = versionTest(/(msie |rv:)(\d+(\.\d+)?)/i, 2); + o[STR_VERSION] = versionTest('(msie |rv:)', 2); } else if (uaTest(/opera/i) || uaTest(/opr/i)) { o[STR_OPERA] = TRUE; - o[STR_VERSION] = versionTest(webkitVersion) || versionTest(/opr\/(\d+(\.\d+)?)/i); + o[STR_VERSION] = webkitVersion || versionTest('opr\/'); } else if (uaTest(/chrome/i)) { o[STR_CHROME] = o[STR_WEBKIT] = TRUE; - o[STR_VERSION] = versionTest(/chrome\/(\d+(\.\d+)?)/i); + o[STR_VERSION] = versionTest(STR_CHROME + '\/'); } else if (uaTest(/phantom/i)) { o.phantom = o[STR_WEBKIT] = TRUE; - o[STR_VERSION] = versionTest(/phantomjs\/(\d+(\.\d+)?)/i); + o[STR_VERSION] = versionTest('phantomjs\/'); } else if (uaTest(/touchpad/i)) { o.touchpad = o[STR_WEBKIT] = TRUE; - o[STR_VERSION] = versionTest(/touchpad\/(\d+(\.\d+)?)/i); + o[STR_VERSION] = versionTest('touchpad\/'); } else if (iphone || ipad) { o.ios = o[STR_MOBILE] = o[STR_WEBKIT] = TRUE; // WTF: version is not part of user agent in web apps - o[STR_VERSION] = versionTest(webkitVersion); + o[STR_VERSION] = webkitVersion; if (iphone) { o.iphone = TRUE; } else if (ipad) { @@ -111,19 +112,19 @@ } } else if (uaTest(/android/i)) { o.android = o[STR_MOBILE] = o[STR_WEBKIT] = TRUE; - o[STR_VERSION] = versionTest(webkitVersion) || versionTest(firefoxVersion); + o[STR_VERSION] = webkitVersion || firefoxVersion; } else if (uaTest(/safari/i)) { o[STR_SAFARI] = o[STR_WEBKIT] = TRUE; - o[STR_VERSION] = versionTest(webkitVersion); + o[STR_VERSION] = webkitVersion; } else if (uaTest(/gecko\//i)) { o.gecko = o.mozilla = TRUE; - o[STR_VERSION] = versionTest(firefoxVersion); + o[STR_VERSION] = firefoxVersion; if (uaTest(/firefox/i)) { o.firefox = TRUE; } } else if (uaTest(/seamonkey\//i)) { o.seamonkey = TRUE; - o[STR_VERSION] = versionTest(/seamonkey\/(\d+(\.\d+)?)/i); + o[STR_VERSION] = versionTest('seamonkey\/'); } else { o[STR_VERSION] = 0; } diff --git a/bowser.min.js b/bowser.min.js index 8546b85..a7f0b78 100644 --- a/bowser.min.js +++ b/bowser.min.js @@ -3,4 +3,4 @@ * https://github.com/ded/bowser * MIT License | (c) Dustin Diaz 2013 */ -!function(e,t){typeof define=="function"?define(t):typeof module!="undefined"&&module.exports?module.exports[e]=t():this[e]=t()}("bowser",function(){function f(f){function l(e){return e.test(f)}function c(e,t){var n=f.match(e);return n?n[t||1]:0}var h=l(/iphone/i),p=l(/ipad/i),d=/version\/(\d+(\.\d+)?)/i,v=/firefox\/(\d+(\.\d+)?)/i,m={},g=0;return l(/(msie|trident)/i)?(m[r]=e,m[t]=c(/(msie |rv:)(\d+(\.\d+)?)/i,2)):l(/opera/i)||l(/opr/i)?(m[i]=e,m[t]=c(d)||c(/opr\/(\d+(\.\d+)?)/i)):l(/chrome/i)?(m[s]=m[o]=e,m[t]=c(/chrome\/(\d+(\.\d+)?)/i)):l(/phantom/i)?(m.phantom=m[o]=e,m[t]=c(/phantomjs\/(\d+(\.\d+)?)/i)):l(/touchpad/i)?(m.touchpad=m[o]=e,m[t]=c(/touchpad\/(\d+(\.\d+)?)/i)):h||p?(m.ios=m[n]=m[o]=e,m[t]=c(d),h?m.iphone=e:p&&(m.ipad=e)):l(/android/i)?(m.android=m[n]=m[o]=e,m[t]=c(d)||c(v)):l(/safari/i)?(m[u]=m[o]=e,m[t]=c(d)):l(/gecko\//i)?(m.gecko=m.mozilla=e,m[t]=c(v),l(/firefox/i)&&(m.firefox=e)):l(/seamonkey\//i)?(m.seamonkey=e,m[t]=c(/seamonkey\/(\d+(\.\d+)?)/i)):m[t]=0,g=m[t],m[r]&&g>=8||m[s]&&g>=10||m[a]&&g>=4||m[u]&&g>=5||m[i]&&g>=10?m.a=e:m[r]&&g<8||m[s]&&g<10||m[a]&&g<4||m[u]&&g<5||m[i]&&g<10?m.c=e:m.x=e,m}var e=!0,t="version",n="mobile",r="msie",i="opera",s="chrome",o="webkit",u="safari",a="firefox",l=f(typeof navigator!="undefined"?navigator.userAgent:"");return l._detect=f,l}) \ No newline at end of file +!function(e,t){typeof define=="function"?define(t):typeof module!="undefined"&&module.exports?module.exports[e]=t():this[e]=t()}("bowser",function(){function f(f){function l(e){return e.test(f)}function c(e,t){var n=f.match(new RegExp(e+"(\\d+(\\.\\d+)?)","i"));return n?n[t||1]:0}var h=l(/iphone/i),p=l(/ipad/i),d=c(t+"/"),v=c(a+"[/ ]"),m={},g=0;return l(/(msie|trident)/i)?(m[r]=e,m[t]=c("(msie |rv:)",2)):l(/opera/i)||l(/opr/i)?(m[i]=e,m[t]=d||c("opr/")):l(/chrome/i)?(m[s]=m[o]=e,m[t]=c(s+"/")):l(/phantom/i)?(m.phantom=m[o]=e,m[t]=c("phantomjs/")):l(/touchpad/i)?(m.touchpad=m[o]=e,m[t]=c("touchpad/")):h||p?(m.ios=m[n]=m[o]=e,m[t]=d,h?m.iphone=e:p&&(m.ipad=e)):l(/android/i)?(m.android=m[n]=m[o]=e,m[t]=d||v):l(/safari/i)?(m[u]=m[o]=e,m[t]=d):l(/gecko\//i)?(m.gecko=m.mozilla=e,m[t]=v,l(/firefox/i)&&(m.firefox=e)):l(/seamonkey\//i)?(m.seamonkey=e,m[t]=c("seamonkey/")):m[t]=0,g=m[t],m[r]&&g>=8||m[s]&&g>=10||m[a]&&g>=4||m[u]&&g>=5||m[i]&&g>=10?m.a=e:m[r]&&g<8||m[s]&&g<10||m[a]&&g<4||m[u]&&g<5||m[i]&&g<10?m.c=e:m.x=e,m}var e=!0,t="version",n="mobile",r="msie",i="opera",s="chrome",o="webkit",u="safari",a="firefox",l=f(typeof navigator!="undefined"?navigator.userAgent:"");return l._detect=f,l}) \ No newline at end of file diff --git a/src/bowser.js b/src/bowser.js index 8b1506e..721da88 100644 --- a/src/bowser.js +++ b/src/bowser.js @@ -62,42 +62,43 @@ } /** - * Get version numbers from our user agent. + * Append version number matcher to our starting string + * and get version number from our user agent. * - * @param {RegExp} regex + * @param {String} start * @return {Number} */ - function versionTest(regex, i) { - var match = ua.match(regex); + function versionTest(start, i) { + var match = ua.match(new RegExp(start + '(\\d+(\\.\\d+)?)', 'i')); return match ? match[i || 1] : 0; } var iphone = uaTest(/iphone/i) , ipad = uaTest(/ipad/i) - , webkitVersion = /version\/(\d+(\.\d+)?)/i - , firefoxVersion = /firefox\/(\d+(\.\d+)?)/i + , webkitVersion = versionTest(STR_VERSION + '\/') + , firefoxVersion = versionTest(STR_FIREFOX + '[\/ ]') , o = {} , version = 0; if (uaTest(/(msie|trident)/i)) { o[STR_MSIE] = TRUE; - o[STR_VERSION] = versionTest(/(msie |rv:)(\d+(\.\d+)?)/i, 2); + o[STR_VERSION] = versionTest('(msie |rv:)', 2); } else if (uaTest(/opera/i) || uaTest(/opr/i)) { o[STR_OPERA] = TRUE; - o[STR_VERSION] = versionTest(webkitVersion) || versionTest(/opr\/(\d+(\.\d+)?)/i); + o[STR_VERSION] = webkitVersion || versionTest('opr\/'); } else if (uaTest(/chrome/i)) { o[STR_CHROME] = o[STR_WEBKIT] = TRUE; - o[STR_VERSION] = versionTest(/chrome\/(\d+(\.\d+)?)/i); + o[STR_VERSION] = versionTest(STR_CHROME + '\/'); } else if (uaTest(/phantom/i)) { o.phantom = o[STR_WEBKIT] = TRUE; - o[STR_VERSION] = versionTest(/phantomjs\/(\d+(\.\d+)?)/i); + o[STR_VERSION] = versionTest('phantomjs\/'); } else if (uaTest(/touchpad/i)) { o.touchpad = o[STR_WEBKIT] = TRUE; - o[STR_VERSION] = versionTest(/touchpad\/(\d+(\.\d+)?)/i); + o[STR_VERSION] = versionTest('touchpad\/'); } else if (iphone || ipad) { o.ios = o[STR_MOBILE] = o[STR_WEBKIT] = TRUE; // WTF: version is not part of user agent in web apps - o[STR_VERSION] = versionTest(webkitVersion); + o[STR_VERSION] = webkitVersion; if (iphone) { o.iphone = TRUE; } else if (ipad) { @@ -105,19 +106,19 @@ } } else if (uaTest(/android/i)) { o.android = o[STR_MOBILE] = o[STR_WEBKIT] = TRUE; - o[STR_VERSION] = versionTest(webkitVersion) || versionTest(firefoxVersion); + o[STR_VERSION] = webkitVersion || firefoxVersion; } else if (uaTest(/safari/i)) { o[STR_SAFARI] = o[STR_WEBKIT] = TRUE; - o[STR_VERSION] = versionTest(webkitVersion); + o[STR_VERSION] = webkitVersion; } else if (uaTest(/gecko\//i)) { o.gecko = o.mozilla = TRUE; - o[STR_VERSION] = versionTest(firefoxVersion); + o[STR_VERSION] = firefoxVersion; if (uaTest(/firefox/i)) { o.firefox = TRUE; } } else if (uaTest(/seamonkey\//i)) { o.seamonkey = TRUE; - o[STR_VERSION] = versionTest(/seamonkey\/(\d+(\.\d+)?)/i); + o[STR_VERSION] = versionTest('seamonkey\/'); } else { o[STR_VERSION] = 0; } From 749746070c5066f2880540f9a48e2e5c506b3cf7 Mon Sep 17 00:00:00 2001 From: Hannes Diercks Date: Fri, 13 Sep 2013 15:26:55 +0200 Subject: [PATCH 08/11] Add iPod, Blackberry, WebOS and Windows Phone support. --- bowser.js | 25 +++++++++++++++++++++---- bowser.min.js | 2 +- src/bowser.js | 25 +++++++++++++++++++++---- 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/bowser.js b/bowser.js index 9edefc1..252c5b0 100644 --- a/bowser.js +++ b/bowser.js @@ -81,12 +81,16 @@ var iphone = uaTest(/iphone/i) , ipad = uaTest(/ipad/i) + , ipod = uaTest(/ipod/i) , webkitVersion = versionTest(STR_VERSION + '\/') , firefoxVersion = versionTest(STR_FIREFOX + '[\/ ]') , o = {} , version = 0; - if (uaTest(/(msie|trident)/i)) { + if (uaTest(/windows phone/i)) { + o.windowsphone = o[STR_MOBILE] = TRUE; + o[STR_VERSION] = versionTest('iemobile\/'); + } else if (uaTest(/(msie|trident)/i)) { o[STR_MSIE] = TRUE; o[STR_VERSION] = versionTest('(msie |rv:)', 2); } else if (uaTest(/opera/i) || uaTest(/opr/i)) { @@ -101,15 +105,28 @@ } else if (uaTest(/touchpad/i)) { o.touchpad = o[STR_WEBKIT] = TRUE; o[STR_VERSION] = versionTest('touchpad\/'); - } else if (iphone || ipad) { + } else if (iphone || ipad || ipod) { o.ios = o[STR_MOBILE] = o[STR_WEBKIT] = TRUE; - // WTF: version is not part of user agent in web apps + // CAUTION: version is not part of user agent in web apps o[STR_VERSION] = webkitVersion; - if (iphone) { + if (ipod) { + o.ipod = TRUE; + } else if (iphone) { o.iphone = TRUE; } else if (ipad) { o.ipad = TRUE; } + } else if (uaTest(/blackberry/i)) { + o.blackberry = o[STR_MOBILE] = TRUE; + if (webkitVersion) { + o[STR_WEBKIT] = TRUE; + o[STR_VERSION] = webkitVersion; + } else { + o[STR_VERSION] = versionTest('blackberry[\\d]+\/'); + } + } else if (uaTest(/webos/i)) { + o.webos = o[STR_MOBILE] = o[STR_WEBKIT] = TRUE; + o[STR_VERSION] = webkitVersion || versionTest('wosbrowser\/'); } else if (uaTest(/android/i)) { o.android = o[STR_MOBILE] = o[STR_WEBKIT] = TRUE; o[STR_VERSION] = webkitVersion || firefoxVersion; diff --git a/bowser.min.js b/bowser.min.js index a7f0b78..24a6344 100644 --- a/bowser.min.js +++ b/bowser.min.js @@ -3,4 +3,4 @@ * https://github.com/ded/bowser * MIT License | (c) Dustin Diaz 2013 */ -!function(e,t){typeof define=="function"?define(t):typeof module!="undefined"&&module.exports?module.exports[e]=t():this[e]=t()}("bowser",function(){function f(f){function l(e){return e.test(f)}function c(e,t){var n=f.match(new RegExp(e+"(\\d+(\\.\\d+)?)","i"));return n?n[t||1]:0}var h=l(/iphone/i),p=l(/ipad/i),d=c(t+"/"),v=c(a+"[/ ]"),m={},g=0;return l(/(msie|trident)/i)?(m[r]=e,m[t]=c("(msie |rv:)",2)):l(/opera/i)||l(/opr/i)?(m[i]=e,m[t]=d||c("opr/")):l(/chrome/i)?(m[s]=m[o]=e,m[t]=c(s+"/")):l(/phantom/i)?(m.phantom=m[o]=e,m[t]=c("phantomjs/")):l(/touchpad/i)?(m.touchpad=m[o]=e,m[t]=c("touchpad/")):h||p?(m.ios=m[n]=m[o]=e,m[t]=d,h?m.iphone=e:p&&(m.ipad=e)):l(/android/i)?(m.android=m[n]=m[o]=e,m[t]=d||v):l(/safari/i)?(m[u]=m[o]=e,m[t]=d):l(/gecko\//i)?(m.gecko=m.mozilla=e,m[t]=v,l(/firefox/i)&&(m.firefox=e)):l(/seamonkey\//i)?(m.seamonkey=e,m[t]=c("seamonkey/")):m[t]=0,g=m[t],m[r]&&g>=8||m[s]&&g>=10||m[a]&&g>=4||m[u]&&g>=5||m[i]&&g>=10?m.a=e:m[r]&&g<8||m[s]&&g<10||m[a]&&g<4||m[u]&&g<5||m[i]&&g<10?m.c=e:m.x=e,m}var e=!0,t="version",n="mobile",r="msie",i="opera",s="chrome",o="webkit",u="safari",a="firefox",l=f(typeof navigator!="undefined"?navigator.userAgent:"");return l._detect=f,l}) \ No newline at end of file +!function(e,t){typeof define=="function"?define(t):typeof module!="undefined"&&module.exports?module.exports[e]=t():this[e]=t()}("bowser",function(){function f(f){function l(e){return e.test(f)}function c(e,t){var n=f.match(new RegExp(e+"(\\d+(\\.\\d+)?)","i"));return n?n[t||1]:0}var h=l(/iphone/i),p=l(/ipad/i),d=l(/ipod/i),v=c(t+"/"),m=c(a+"[/ ]"),g={},y=0;return l(/windows phone/i)?(g.windowsphone=g[n]=e,g[t]=c("iemobile/")):l(/(msie|trident)/i)?(g[r]=e,g[t]=c("(msie |rv:)",2)):l(/opera/i)||l(/opr/i)?(g[i]=e,g[t]=v||c("opr/")):l(/chrome/i)?(g[s]=g[o]=e,g[t]=c(s+"/")):l(/phantom/i)?(g.phantom=g[o]=e,g[t]=c("phantomjs/")):l(/touchpad/i)?(g.touchpad=g[o]=e,g[t]=c("touchpad/")):h||p||d?(g.ios=g[n]=g[o]=e,g[t]=v,d?g.ipod=e:h?g.iphone=e:p&&(g.ipad=e)):l(/blackberry/i)?(g.blackberry=g[n]=e,v?(g[o]=e,g[t]=v):g[t]=c("blackberry[\\d]+/")):l(/webos/i)?(g.webos=g[n]=g[o]=e,g[t]=v||c("wosbrowser/")):l(/android/i)?(g.android=g[n]=g[o]=e,g[t]=v||m):l(/safari/i)?(g[u]=g[o]=e,g[t]=v):l(/gecko\//i)?(g.gecko=g.mozilla=e,g[t]=m,l(/firefox/i)&&(g.firefox=e)):l(/seamonkey\//i)?(g.seamonkey=e,g[t]=c("seamonkey/")):g[t]=0,y=g[t],g[r]&&y>=8||g[s]&&y>=10||g[a]&&y>=4||g[u]&&y>=5||g[i]&&y>=10?g.a=e:g[r]&&y<8||g[s]&&y<10||g[a]&&y<4||g[u]&&y<5||g[i]&&y<10?g.c=e:g.x=e,g}var e=!0,t="version",n="mobile",r="msie",i="opera",s="chrome",o="webkit",u="safari",a="firefox",l=f(typeof navigator!="undefined"?navigator.userAgent:"");return l._detect=f,l}) \ No newline at end of file diff --git a/src/bowser.js b/src/bowser.js index 721da88..e5d1edc 100644 --- a/src/bowser.js +++ b/src/bowser.js @@ -75,12 +75,16 @@ var iphone = uaTest(/iphone/i) , ipad = uaTest(/ipad/i) + , ipod = uaTest(/ipod/i) , webkitVersion = versionTest(STR_VERSION + '\/') , firefoxVersion = versionTest(STR_FIREFOX + '[\/ ]') , o = {} , version = 0; - if (uaTest(/(msie|trident)/i)) { + if (uaTest(/windows phone/i)) { + o.windowsphone = o[STR_MOBILE] = TRUE; + o[STR_VERSION] = versionTest('iemobile\/'); + } else if (uaTest(/(msie|trident)/i)) { o[STR_MSIE] = TRUE; o[STR_VERSION] = versionTest('(msie |rv:)', 2); } else if (uaTest(/opera/i) || uaTest(/opr/i)) { @@ -95,15 +99,28 @@ } else if (uaTest(/touchpad/i)) { o.touchpad = o[STR_WEBKIT] = TRUE; o[STR_VERSION] = versionTest('touchpad\/'); - } else if (iphone || ipad) { + } else if (iphone || ipad || ipod) { o.ios = o[STR_MOBILE] = o[STR_WEBKIT] = TRUE; - // WTF: version is not part of user agent in web apps + // CAUTION: version is not part of user agent in web apps o[STR_VERSION] = webkitVersion; - if (iphone) { + if (ipod) { + o.ipod = TRUE; + } else if (iphone) { o.iphone = TRUE; } else if (ipad) { o.ipad = TRUE; } + } else if (uaTest(/blackberry/i)) { + o.blackberry = o[STR_MOBILE] = TRUE; + if (webkitVersion) { + o[STR_WEBKIT] = TRUE; + o[STR_VERSION] = webkitVersion; + } else { + o[STR_VERSION] = versionTest('blackberry[\\d]+\/'); + } + } else if (uaTest(/webos/i)) { + o.webos = o[STR_MOBILE] = o[STR_WEBKIT] = TRUE; + o[STR_VERSION] = webkitVersion || versionTest('wosbrowser\/'); } else if (uaTest(/android/i)) { o.android = o[STR_MOBILE] = o[STR_WEBKIT] = TRUE; o[STR_VERSION] = webkitVersion || firefoxVersion; From c9ee5e4efec871080e90b6e6708843c8540b16b5 Mon Sep 17 00:00:00 2001 From: Hannes Diercks Date: Fri, 13 Sep 2013 15:38:28 +0200 Subject: [PATCH 09/11] Add thousand and one tests. --- bowser.js | 6 +- bowser.min.js | 2 +- src/bowser.js | 6 +- src/useragents.js | 364 +++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 370 insertions(+), 8 deletions(-) diff --git a/bowser.js b/bowser.js index 252c5b0..86ac84e 100644 --- a/bowser.js +++ b/bowser.js @@ -90,12 +90,12 @@ if (uaTest(/windows phone/i)) { o.windowsphone = o[STR_MOBILE] = TRUE; o[STR_VERSION] = versionTest('iemobile\/'); + } else if (uaTest(/opera/i) || uaTest(/opr/i)) { + o[STR_OPERA] = TRUE; + o[STR_VERSION] = webkitVersion || versionTest('opr\/') || versionTest('opera[ \/]'); } else if (uaTest(/(msie|trident)/i)) { o[STR_MSIE] = TRUE; o[STR_VERSION] = versionTest('(msie |rv:)', 2); - } else if (uaTest(/opera/i) || uaTest(/opr/i)) { - o[STR_OPERA] = TRUE; - o[STR_VERSION] = webkitVersion || versionTest('opr\/'); } else if (uaTest(/chrome/i)) { o[STR_CHROME] = o[STR_WEBKIT] = TRUE; o[STR_VERSION] = versionTest(STR_CHROME + '\/'); diff --git a/bowser.min.js b/bowser.min.js index 24a6344..ebd2e8a 100644 --- a/bowser.min.js +++ b/bowser.min.js @@ -3,4 +3,4 @@ * https://github.com/ded/bowser * MIT License | (c) Dustin Diaz 2013 */ -!function(e,t){typeof define=="function"?define(t):typeof module!="undefined"&&module.exports?module.exports[e]=t():this[e]=t()}("bowser",function(){function f(f){function l(e){return e.test(f)}function c(e,t){var n=f.match(new RegExp(e+"(\\d+(\\.\\d+)?)","i"));return n?n[t||1]:0}var h=l(/iphone/i),p=l(/ipad/i),d=l(/ipod/i),v=c(t+"/"),m=c(a+"[/ ]"),g={},y=0;return l(/windows phone/i)?(g.windowsphone=g[n]=e,g[t]=c("iemobile/")):l(/(msie|trident)/i)?(g[r]=e,g[t]=c("(msie |rv:)",2)):l(/opera/i)||l(/opr/i)?(g[i]=e,g[t]=v||c("opr/")):l(/chrome/i)?(g[s]=g[o]=e,g[t]=c(s+"/")):l(/phantom/i)?(g.phantom=g[o]=e,g[t]=c("phantomjs/")):l(/touchpad/i)?(g.touchpad=g[o]=e,g[t]=c("touchpad/")):h||p||d?(g.ios=g[n]=g[o]=e,g[t]=v,d?g.ipod=e:h?g.iphone=e:p&&(g.ipad=e)):l(/blackberry/i)?(g.blackberry=g[n]=e,v?(g[o]=e,g[t]=v):g[t]=c("blackberry[\\d]+/")):l(/webos/i)?(g.webos=g[n]=g[o]=e,g[t]=v||c("wosbrowser/")):l(/android/i)?(g.android=g[n]=g[o]=e,g[t]=v||m):l(/safari/i)?(g[u]=g[o]=e,g[t]=v):l(/gecko\//i)?(g.gecko=g.mozilla=e,g[t]=m,l(/firefox/i)&&(g.firefox=e)):l(/seamonkey\//i)?(g.seamonkey=e,g[t]=c("seamonkey/")):g[t]=0,y=g[t],g[r]&&y>=8||g[s]&&y>=10||g[a]&&y>=4||g[u]&&y>=5||g[i]&&y>=10?g.a=e:g[r]&&y<8||g[s]&&y<10||g[a]&&y<4||g[u]&&y<5||g[i]&&y<10?g.c=e:g.x=e,g}var e=!0,t="version",n="mobile",r="msie",i="opera",s="chrome",o="webkit",u="safari",a="firefox",l=f(typeof navigator!="undefined"?navigator.userAgent:"");return l._detect=f,l}) \ No newline at end of file +!function(e,t){typeof define=="function"?define(t):typeof module!="undefined"&&module.exports?module.exports[e]=t():this[e]=t()}("bowser",function(){function f(f){function l(e){return e.test(f)}function c(e,t){var n=f.match(new RegExp(e+"(\\d+(\\.\\d+)?)","i"));return n?n[t||1]:0}var h=l(/iphone/i),p=l(/ipad/i),d=l(/ipod/i),v=c(t+"/"),m=c(a+"[/ ]"),g={},y=0;return l(/windows phone/i)?(g.windowsphone=g[n]=e,g[t]=c("iemobile/")):l(/opera/i)||l(/opr/i)?(g[i]=e,g[t]=v||c("opr/")||c("opera[ /]")):l(/(msie|trident)/i)?(g[r]=e,g[t]=c("(msie |rv:)",2)):l(/chrome/i)?(g[s]=g[o]=e,g[t]=c(s+"/")):l(/phantom/i)?(g.phantom=g[o]=e,g[t]=c("phantomjs/")):l(/touchpad/i)?(g.touchpad=g[o]=e,g[t]=c("touchpad/")):h||p||d?(g.ios=g[n]=g[o]=e,g[t]=v,d?g.ipod=e:h?g.iphone=e:p&&(g.ipad=e)):l(/blackberry/i)?(g.blackberry=g[n]=e,v?(g[o]=e,g[t]=v):g[t]=c("blackberry[\\d]+/")):l(/webos/i)?(g.webos=g[n]=g[o]=e,g[t]=v||c("wosbrowser/")):l(/android/i)?(g.android=g[n]=g[o]=e,g[t]=v||m):l(/safari/i)?(g[u]=g[o]=e,g[t]=v):l(/gecko\//i)?(g.gecko=g.mozilla=e,g[t]=m,l(/firefox/i)&&(g.firefox=e)):l(/seamonkey\//i)?(g.seamonkey=e,g[t]=c("seamonkey/")):g[t]=0,y=g[t],g[r]&&y>=8||g[s]&&y>=10||g[a]&&y>=4||g[u]&&y>=5||g[i]&&y>=10?g.a=e:g[r]&&y<8||g[s]&&y<10||g[a]&&y<4||g[u]&&y<5||g[i]&&y<10?g.c=e:g.x=e,g}var e=!0,t="version",n="mobile",r="msie",i="opera",s="chrome",o="webkit",u="safari",a="firefox",l=f(typeof navigator!="undefined"?navigator.userAgent:"");return l._detect=f,l}) \ No newline at end of file diff --git a/src/bowser.js b/src/bowser.js index e5d1edc..0e787d8 100644 --- a/src/bowser.js +++ b/src/bowser.js @@ -84,12 +84,12 @@ if (uaTest(/windows phone/i)) { o.windowsphone = o[STR_MOBILE] = TRUE; o[STR_VERSION] = versionTest('iemobile\/'); + } else if (uaTest(/opera/i) || uaTest(/opr/i)) { + o[STR_OPERA] = TRUE; + o[STR_VERSION] = webkitVersion || versionTest('opr\/') || versionTest('opera[ \/]'); } else if (uaTest(/(msie|trident)/i)) { o[STR_MSIE] = TRUE; o[STR_VERSION] = versionTest('(msie |rv:)', 2); - } else if (uaTest(/opera/i) || uaTest(/opr/i)) { - o[STR_OPERA] = TRUE; - o[STR_VERSION] = webkitVersion || versionTest('opr\/'); } else if (uaTest(/chrome/i)) { o[STR_CHROME] = o[STR_WEBKIT] = TRUE; o[STR_VERSION] = versionTest(STR_CHROME + '\/'); diff --git a/src/useragents.js b/src/useragents.js index 574cc16..0b8804b 100644 --- a/src/useragents.js +++ b/src/useragents.js @@ -7,42 +7,274 @@ module.exports.useragents = { Chrome: { + 'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.17 Safari/537.36': { + chrome: true, + version: '30.0', + webkit: true, + a: true + }, + 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.62 Safari/537.36': { + chrome: true, + version: '29.0', + webkit: true, + a: true + }, + 'Mozilla/5.0 (X11; CrOS i686 4319.74.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36': { + chrome: true, + version: '29.0', + webkit: true, + a: true + }, + 'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.2 Safari/537.36': { + chrome: true, + version: '29.0', + webkit: true, + a: true + }, + 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36': { + chrome: true, + version: '28.0', + webkit: true, + a: true + }, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_7) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.57 Safari/534.24': { chrome: true, version: '11.0', webkit: true, a: true + }, + 'Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.3 (KHTML, like Gecko) Chrome/6.0.462.0 Safari/534.3': { + chrome: true, + version: '6.0', + webkit: true, + c: true } }, Opera: { + 'Opera/9.80 (Windows NT 6.0) Presto/2.12.388 Version/12.14': { + opera: true, + version: '12.14', + a: true + }, + 'Mozilla/5.0 (Windows NT 6.0; rv:2.0) Gecko/20100101 Firefox/4.0 Opera 12.14': { + opera: true, + version: '12.14', + a: true + }, + 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0) Opera 12.14': { + opera: true, + version: '12.14', + a: true + }, + 'Opera/12.80 (Windows NT 5.1; U; en) Presto/2.10.289 Version/12.02': { + opera: true, + version: '12.02', + a: true + }, + 'Opera/9.80 (X11; Linux i686; U; es-ES) Presto/2.8.131 Version/11.11': { + opera: true, + version: '11.11', + a: true + }, 'Opera/9.80 (Macintosh; Intel Mac OS X 10.6.7; U; en) Presto/2.7.62 Version/11.01': { opera: true, version: '11.01', a: true + }, + 'Opera/9.80 (Windows NT 5.2; U; zh-cn) Presto/2.6.30 Version/10.63': { + opera: true, + version: '10.63', + a: true + }, + 'Opera/9.80 (X11; Linux i686; U; it) Presto/2.5.24 Version/10.54': { + opera: true, + version: '10.54', + a: true + }, + 'Opera/9.70 (Linux ppc64 ; U; en) Presto/2.2.1': { + opera: true, + version: '9.70', + c: true + }, + 'Opera/9.63 (X11; Linux i686)': { + opera: true, + version: '9.63', + c: true + }, + 'Mozilla/5.0 (X11; Linux i686; U; en) Opera 8.52': { + opera: true, + version: '8.52', + c: true } }, Safari: { + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.13+ (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2': { + safari: true, + version: '5.1', + webkit: true, + a: true + }, 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-us) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1': { safari: true, version: '5.0', webkit: true, a: true - } + }, + 'Mozilla/5.0 (Windows; U; Windows NT 5.1; ru-RU) AppleWebKit/533.18.1 (KHTML, like Gecko) Version/5.0.2 Safari/533.18.5': { + safari: true, + version: '5.0', + webkit: true, + a: true + }, + 'Mozilla/5.0 (X11; U; Linux x86_64; en-us) AppleWebKit/531.2+ (KHTML, like Gecko) Version/5.0 Safari/531.2+': { + safari: true, + version: '5.0', + webkit: true, + a: true + }, + 'Mozilla/5.0 (Windows; U; Windows NT 5.0; en-en) AppleWebKit/533.16 (KHTML, like Gecko) Version/4.1 Safari/533.16': { + safari: true, + version: '4.1', + webkit: true, + c: true + }, + 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_6_1; en_GB, en_US) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10': { + safari: true, + version: '4.0', + webkit: true, + c: true + }, + 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_7; de-de) AppleWebKit/525.28.3 (KHTML, like Gecko) Version/3.2.3 Safari/525.28.3': { + safari: true, + version: '3.2', + webkit: true, + c: true + }, }, 'Internet Explorer': { + 'Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; .NET4.0E; .NET4.0C; Media Center PC 6.0; rv:11.0) like Gecko': { + msie: true, + version: '11.0', + a: true + }, + 'Mozilla/5.0 (compatible; MSIE 10.6; Windows NT 6.1; Trident/5.0; InfoPath.2; SLCC1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 2.0.50727) 3gpp-gba UNTRUSTED/1.0': { + msie: true, + version: '10.6', + a: true + }, + 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/4.0; InfoPath.2; SV1; .NET CLR 2.0.50727; WOW64)': { + msie: true, + version: '10.0', + a: true + }, + 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)': { + msie: true, + version: '9.0', + a: true + }, 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C)': { msie: true, version: '8.0', a: true + }, + 'Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.1; .NET CLR 1.1.4322; InfoPath.1; .NET CLR 2.0.50727)': { + msie: true, + version: '7.0', + c: true + }, + 'Mozilla/4.0 (compatible; MSIE 6.1; Windows XP; .NET CLR 1.1.4322; .NET CLR 2.0.50727)': { + msie: true, + version: '6.1', + c: true + }, + 'Mozilla/4.0 (Compatible; Windows NT 5.1; MSIE 6.0) (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)': { + msie: true, + version: '6.0', + c: true + }, + 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT)': { + msie: true, + version: '5.01', + c: true } }, Firefox: { + 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0) Gecko/20100101 Firefox/25.0': { + mozilla: true, + gecko: true, + firefox: true, + version: '25.0', + a: true + }, + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:24.0) Gecko/20100101 Firefox/24.0': { + mozilla: true, + gecko: true, + firefox: true, + version: '24.0', + a: true + }, + 'Mozilla/5.0 (X11; Linux i686; rv:21.0) Gecko/20100101 Firefox/21.0': { + mozilla: true, + gecko: true, + firefox: true, + version: '21.0', + a: true + }, + 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:15.0) Gecko/20120910144328 Firefox/15.0.2': { + mozilla: true, + gecko: true, + firefox: true, + version: '15.0', + a: true + }, + 'Mozilla/5.0 (Windows; U; Windows NT 6.1; WOW64; en-US; rv:2.0.4) Gecko/20120718 AskTbAVR-IDW/3.12.5.17700 Firefox/14.0.1': { + mozilla: true, + gecko: true, + firefox: true, + version: '14.0', + a: true + }, + 'Mozilla/5.0 (Windows NT 5.1; rv:6.0) Gecko/20100101 Firefox/6.0 FirePHP/0.6': { + mozilla: true, + gecko: true, + firefox: true, + version: '6.0', + a: true + }, + 'Mozilla/5.0 (X11; Linux x86_64; rv:2.2a1pre) Gecko/20100101 Firefox/4.2a1pre': { + mozilla: true, + gecko: true, + firefox: true, + version: '4.2', + a: true + }, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0) Gecko/20100101 Firefox/4.0': { mozilla: true, gecko: true, firefox: true, version: '4.0', a: true + }, + 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2b1) Gecko/20091014 Firefox/3.6b1 GTB5': { + mozilla: true, + gecko: true, + firefox: true, + version: '3.6', + c: true + }, + 'Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.15) Gecko/2009101601 Firefox 2.1 (.NET CLR 3.5.30729)': { + mozilla: true, + gecko: true, + firefox: true, + version: '2.1', + c: true + }, + 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.7) Gecko/20061014 Firefox/1.5.0.7': { + mozilla: true, + gecko: true, + firefox: true, + version: '1.5', + c: true } }, iPhone: { @@ -53,9 +285,49 @@ module.exports.useragents = { mobile: true, webkit: true, x: true + }, + 'Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3': { + ios: true, + version: '3.0', + iphone: true, + mobile: true, + webkit: true, + x: true + }, + 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B5097d Safari/6531.22.7': { + ios: true, + version: '4.0', + iphone: true, + mobile: true, + webkit: true, + x: true + }, + 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_5_2; en-gb) AppleWebKit/526+ (KHTML, like Gecko) Version/3.1 iPhone': { + ios: true, + version: '3.1', + iphone: true, + mobile: true, + webkit: true, + x: true } }, iPad: { + 'Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25': { + ios: true, + version: '6.0', + ipad: true, + mobile: true, + webkit: true, + x: true + }, + 'Mozilla/5.0 (iPad; CPU OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko ) Version/5.1 Mobile/9B176 Safari/7534.48.3': { + ios: true, + version: '5.1', + ipad: true, + mobile: true, + webkit: true, + x: true + }, 'Mozilla/5.0 (iPad; U; CPU OS 4_3_2 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8H7 Safari/6533.18.5': { ios: true, version: '5.0', @@ -63,8 +335,91 @@ module.exports.useragents = { mobile: true, webkit: true, x: true + }, + 'Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; es-es) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B360 Safari/531.21.10': { + ios: true, + version: '4.0', + ipad: true, + mobile: true, + webkit: true, + x: true + }, + }, + iPod: { + 'Mozilla/5.0 (iPod; U; CPU iPhone OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5': { + ios: true, + version: '5.0', + ipod: true, + mobile: true, + webkit: true, + x: true + }, + 'Mozilla/5.0 (iPod; U; CPU like Mac OS X; en) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/4A93 Safari/419.3': { + ios: true, + version: '3.0', + ipod: true, + mobile: true, + webkit: true, + x: true } }, + BlackBerry: { + 'Mozilla/5.0 (BlackBerry; U; BlackBerry 9900; en) AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.1.0.346 Mobile Safari/534.11+': { + blackberry: true, + version: '7.1', + webkit: true, + mobile: true, + x: true + }, + 'Mozilla/5.0 (BlackBerry; U; BlackBerry 9800; en-US) AppleWebKit/534.8+ (KHTML, like Gecko) Version/6.0.0.450 Mobile Safari/534.8+': { + blackberry: true, + version: '6.0', + webkit: true, + mobile: true, + x: true + }, + 'BlackBerry9800/5.0.0.862 Profile/MIDP-2.1 Configuration/CLDC-1.1 VendorID/331 UNTRUSTED/1.0 3gpp-gba': { + blackberry: true, + version: '5.0', + mobile: true, + x: true + }, + 'BlackBerry8320/4.5.0.52 Profile/MIDP-2.0 Configuration/CLDC-1.1 VendorID/179': { + blackberry: true, + version: '4.5', + mobile: true, + x: true + } + }, + 'Windows Phone': { + 'Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 920)': { + windowsphone: true, + version: '10.0', + mobile: true, + x: true + }, + 'Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0)': { + windowsphone: true, + version: '9.0', + mobile: true, + x: true + }, + 'Mozilla/4.0 (compatible; MSIE 7.0; Windows Phone OS 7.0; Trident/3.1; IEMobile/7.0; Nokia;N70)': { + windowsphone: true, + version: '7.0', + mobile: true, + x: true + } + }, + WebOS: { + 'Mozilla/5.0 (webOS/1.0; U; en-US) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/1.0 Safari/525.27.1 Pre/1.0': { + webos: true, + webkit: true, + version: '1.0', + mobile: true, + x: true + }, + }, Android: { 'Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; T-Mobile G2 Build/GRJ22) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1': { android: true, @@ -72,6 +427,13 @@ module.exports.useragents = { version: 4.0, mobile: true, x: true + }, + 'Mozilla/5.0 (Linux; U; Android 1.6; ar-us; SonyEricssonX10i Build/R2BA026) AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1': { + android: true, + webkit: true, + version: 3.1, + mobile: true, + x: true } }, Touchpad: { From 5376cc67dc68ff13d215baaa107d8aaa36f67700 Mon Sep 17 00:00:00 2001 From: Hannes Diercks Date: Fri, 13 Sep 2013 15:42:55 +0200 Subject: [PATCH 10/11] Further minifications and bugfixes. --- bowser.js | 103 +++++++++++++++++++++++++++++++--------------- bowser.min.js | 10 ++--- src/bowser.js | 95 +++++++++++++++++++++++++++++------------- src/copyright.js | 8 ++-- src/useragents.js | 1 - 5 files changed, 145 insertions(+), 72 deletions(-) diff --git a/bowser.js b/bowser.js index 86ac84e..5a92171 100644 --- a/bowser.js +++ b/bowser.js @@ -1,8 +1,8 @@ /*! - * Bowser - a browser detector - * https://github.com/ded/bowser - * MIT License | (c) Dustin Diaz 2013 - */ + * Bowser - a browser detector + * https://github.com/ded/bowser + * MIT License | (c) Dustin Diaz 2013 + */ !function (name, definition) { if (typeof define === 'function') { @@ -55,6 +55,30 @@ /** @const */ var STR_FIREFOX = 'firefox'; + /** @const */ + var STR_BLACKBERRY = 'blackberry'; + + /** @const */ + var STR_WEBOS = 'webos'; + + /** @const */ + var STR_GECKO = 'gecko'; + + /** @const */ + var STR_ANDROID = 'android'; + + /** @const */ + var STR_TOUCHPAD = 'touchpad'; + + /** @const */ + var STR_IPHONE = 'iphone'; + + /** @const */ + var STR_IPAD = 'ipad'; + + /** @const */ + var STR_IPOD = 'ipod'; + function detect(ua) { /** @@ -63,8 +87,8 @@ * @param {RegExp} regex * @return {Boolean} */ - function uaTest(regex) { - return regex.test(ua); + function uaTest(test) { + return new RegExp(test, 'i').test(ua); } /** @@ -79,69 +103,82 @@ return match ? match[i || 1] : 0; } - var iphone = uaTest(/iphone/i) - , ipad = uaTest(/ipad/i) - , ipod = uaTest(/ipod/i) + var iphone = uaTest(STR_IPHONE) + , ipad = uaTest(STR_IPAD) + , ipod = uaTest(STR_IPOD) , webkitVersion = versionTest(STR_VERSION + '\/') , firefoxVersion = versionTest(STR_FIREFOX + '[\/ ]') , o = {} , version = 0; - if (uaTest(/windows phone/i)) { + if (uaTest('windows phone')) { o.windowsphone = o[STR_MOBILE] = TRUE; o[STR_VERSION] = versionTest('iemobile\/'); - } else if (uaTest(/opera/i) || uaTest(/opr/i)) { + + } else if (uaTest(STR_OPERA) || uaTest('opr')) { o[STR_OPERA] = TRUE; o[STR_VERSION] = webkitVersion || versionTest('opr\/') || versionTest('opera[ \/]'); - } else if (uaTest(/(msie|trident)/i)) { + + } else if (uaTest('(msie|trident)')) { o[STR_MSIE] = TRUE; o[STR_VERSION] = versionTest('(msie |rv:)', 2); - } else if (uaTest(/chrome/i)) { + + } else if (uaTest(STR_CHROME)) { o[STR_CHROME] = o[STR_WEBKIT] = TRUE; o[STR_VERSION] = versionTest(STR_CHROME + '\/'); - } else if (uaTest(/phantom/i)) { + + } else if (uaTest('phantom')) { o.phantom = o[STR_WEBKIT] = TRUE; o[STR_VERSION] = versionTest('phantomjs\/'); - } else if (uaTest(/touchpad/i)) { - o.touchpad = o[STR_WEBKIT] = TRUE; - o[STR_VERSION] = versionTest('touchpad\/'); + + } else if (uaTest(STR_TOUCHPAD)) { + o[STR_TOUCHPAD] = o[STR_WEBKIT] = TRUE; + o[STR_VERSION] = versionTest(STR_TOUCHPAD + '\/'); + } else if (iphone || ipad || ipod) { o.ios = o[STR_MOBILE] = o[STR_WEBKIT] = TRUE; // CAUTION: version is not part of user agent in web apps o[STR_VERSION] = webkitVersion; if (ipod) { - o.ipod = TRUE; + o[STR_IPOD] = TRUE; } else if (iphone) { - o.iphone = TRUE; + o[STR_IPHONE] = TRUE; } else if (ipad) { - o.ipad = TRUE; + o[STR_IPAD] = TRUE; } - } else if (uaTest(/blackberry/i)) { - o.blackberry = o[STR_MOBILE] = TRUE; + + } else if (uaTest(STR_BLACKBERRY)) { + o[STR_BLACKBERRY] = o[STR_MOBILE] = TRUE; if (webkitVersion) { o[STR_WEBKIT] = TRUE; o[STR_VERSION] = webkitVersion; } else { - o[STR_VERSION] = versionTest('blackberry[\\d]+\/'); + o[STR_VERSION] = versionTest(STR_BLACKBERRY + '[\\d]+\/'); } - } else if (uaTest(/webos/i)) { - o.webos = o[STR_MOBILE] = o[STR_WEBKIT] = TRUE; + + } else if (uaTest(STR_WEBOS)) { + o[STR_WEBOS] = o[STR_MOBILE] = o[STR_WEBKIT] = TRUE; o[STR_VERSION] = webkitVersion || versionTest('wosbrowser\/'); - } else if (uaTest(/android/i)) { - o.android = o[STR_MOBILE] = o[STR_WEBKIT] = TRUE; + + } else if (uaTest(STR_ANDROID)) { + o[STR_ANDROID] = o[STR_MOBILE] = o[STR_WEBKIT] = TRUE; o[STR_VERSION] = webkitVersion || firefoxVersion; - } else if (uaTest(/safari/i)) { + + } else if (uaTest(STR_SAFARI)) { o[STR_SAFARI] = o[STR_WEBKIT] = TRUE; o[STR_VERSION] = webkitVersion; - } else if (uaTest(/gecko\//i)) { - o.gecko = o.mozilla = TRUE; + + } else if (uaTest(STR_GECKO)) { + o[STR_GECKO] = o.mozilla = TRUE; o[STR_VERSION] = firefoxVersion; - if (uaTest(/firefox/i)) { + if (uaTest(STR_FIREFOX)) { o.firefox = TRUE; } - } else if (uaTest(/seamonkey\//i)) { + + } else if (uaTest('seamonkey\/')) { o.seamonkey = TRUE; o[STR_VERSION] = versionTest('seamonkey\/'); + } else { o[STR_VERSION] = 0; } @@ -173,7 +210,7 @@ /* Get our main bowser object from navigators user agent if present. */ var bowser = detect(typeof navigator !== 'undefined' ? navigator.userAgent : ''); - + /* * Set our detect method to the main bowser object so we can * reuse it to test other user agents. diff --git a/bowser.min.js b/bowser.min.js index ebd2e8a..1008179 100644 --- a/bowser.min.js +++ b/bowser.min.js @@ -1,6 +1,6 @@ /*! - * Bowser - a browser detector - * https://github.com/ded/bowser - * MIT License | (c) Dustin Diaz 2013 - */ -!function(e,t){typeof define=="function"?define(t):typeof module!="undefined"&&module.exports?module.exports[e]=t():this[e]=t()}("bowser",function(){function f(f){function l(e){return e.test(f)}function c(e,t){var n=f.match(new RegExp(e+"(\\d+(\\.\\d+)?)","i"));return n?n[t||1]:0}var h=l(/iphone/i),p=l(/ipad/i),d=l(/ipod/i),v=c(t+"/"),m=c(a+"[/ ]"),g={},y=0;return l(/windows phone/i)?(g.windowsphone=g[n]=e,g[t]=c("iemobile/")):l(/opera/i)||l(/opr/i)?(g[i]=e,g[t]=v||c("opr/")||c("opera[ /]")):l(/(msie|trident)/i)?(g[r]=e,g[t]=c("(msie |rv:)",2)):l(/chrome/i)?(g[s]=g[o]=e,g[t]=c(s+"/")):l(/phantom/i)?(g.phantom=g[o]=e,g[t]=c("phantomjs/")):l(/touchpad/i)?(g.touchpad=g[o]=e,g[t]=c("touchpad/")):h||p||d?(g.ios=g[n]=g[o]=e,g[t]=v,d?g.ipod=e:h?g.iphone=e:p&&(g.ipad=e)):l(/blackberry/i)?(g.blackberry=g[n]=e,v?(g[o]=e,g[t]=v):g[t]=c("blackberry[\\d]+/")):l(/webos/i)?(g.webos=g[n]=g[o]=e,g[t]=v||c("wosbrowser/")):l(/android/i)?(g.android=g[n]=g[o]=e,g[t]=v||m):l(/safari/i)?(g[u]=g[o]=e,g[t]=v):l(/gecko\//i)?(g.gecko=g.mozilla=e,g[t]=m,l(/firefox/i)&&(g.firefox=e)):l(/seamonkey\//i)?(g.seamonkey=e,g[t]=c("seamonkey/")):g[t]=0,y=g[t],g[r]&&y>=8||g[s]&&y>=10||g[a]&&y>=4||g[u]&&y>=5||g[i]&&y>=10?g.a=e:g[r]&&y<8||g[s]&&y<10||g[a]&&y<4||g[u]&&y<5||g[i]&&y<10?g.c=e:g.x=e,g}var e=!0,t="version",n="mobile",r="msie",i="opera",s="chrome",o="webkit",u="safari",a="firefox",l=f(typeof navigator!="undefined"?navigator.userAgent:"");return l._detect=f,l}) \ No newline at end of file + * Bowser - a browser detector + * https://github.com/ded/bowser + * MIT License | (c) Dustin Diaz 2013 + */ +!function(e,t){typeof define=="function"?define(t):typeof module!="undefined"&&module.exports?module.exports[e]=t():this[e]=t()}("bowser",function(){function g(g){function y(e){return(new RegExp(e,"i")).test(g)}function b(e,t){var n=g.match(new RegExp(e+"(\\d+(\\.\\d+)?)","i"));return n?n[t||1]:0}var w=y(d),E=y(v),S=y(m),x=b(t+"/"),T=b(a+"[/ ]"),N={},C=0;return y("windows phone")?(N.windowsphone=N[n]=e,N[t]=b("iemobile/")):y(i)||y("opr")?(N[i]=e,N[t]=x||b("opr/")||b("opera[ /]")):y("(msie|trident)")?(N[r]=e,N[t]=b("(msie |rv:)",2)):y(s)?(N[s]=N[o]=e,N[t]=b(s+"/")):y("phantom")?(N.phantom=N[o]=e,N[t]=b("phantomjs/")):y(p)?(N[p]=N[o]=e,N[t]=b(p+"/")):w||E||S?(N.ios=N[n]=N[o]=e,N[t]=x,S?N[m]=e:w?N[d]=e:E&&(N[v]=e)):y(f)?(N[f]=N[n]=e,x?(N[o]=e,N[t]=x):N[t]=b(f+"[\\d]+/")):y(l)?(N[l]=N[n]=N[o]=e,N[t]=x||b("wosbrowser/")):y(h)?(N[h]=N[n]=N[o]=e,N[t]=x||T):y(u)?(N[u]=N[o]=e,N[t]=x):y(c)?(N[c]=N.mozilla=e,N[t]=T,y(a)&&(N.firefox=e)):y("seamonkey/")?(N.seamonkey=e,N[t]=b("seamonkey/")):N[t]=0,C=N[t],N[r]&&C>=8||N[s]&&C>=10||N[a]&&C>=4||N[u]&&C>=5||N[i]&&C>=10?N.a=e:N[r]&&C<8||N[s]&&C<10||N[a]&&C<4||N[u]&&C<5||N[i]&&C<10?N.c=e:N.x=e,N}var e=!0,t="version",n="mobile",r="msie",i="opera",s="chrome",o="webkit",u="safari",a="firefox",f="blackberry",l="webos",c="gecko",h="android",p="touchpad",d="iphone",v="ipad",m="ipod",y=g(typeof navigator!="undefined"?navigator.userAgent:"");return y._detect=g,y}) \ No newline at end of file diff --git a/src/bowser.js b/src/bowser.js index 0e787d8..60770f0 100644 --- a/src/bowser.js +++ b/src/bowser.js @@ -49,6 +49,30 @@ /** @const */ var STR_FIREFOX = 'firefox'; + /** @const */ + var STR_BLACKBERRY = 'blackberry'; + + /** @const */ + var STR_WEBOS = 'webos'; + + /** @const */ + var STR_GECKO = 'gecko'; + + /** @const */ + var STR_ANDROID = 'android'; + + /** @const */ + var STR_TOUCHPAD = 'touchpad'; + + /** @const */ + var STR_IPHONE = 'iphone'; + + /** @const */ + var STR_IPAD = 'ipad'; + + /** @const */ + var STR_IPOD = 'ipod'; + function detect(ua) { /** @@ -57,8 +81,8 @@ * @param {RegExp} regex * @return {Boolean} */ - function uaTest(regex) { - return regex.test(ua); + function uaTest(test) { + return new RegExp(test, 'i').test(ua); } /** @@ -73,69 +97,82 @@ return match ? match[i || 1] : 0; } - var iphone = uaTest(/iphone/i) - , ipad = uaTest(/ipad/i) - , ipod = uaTest(/ipod/i) + var iphone = uaTest(STR_IPHONE) + , ipad = uaTest(STR_IPAD) + , ipod = uaTest(STR_IPOD) , webkitVersion = versionTest(STR_VERSION + '\/') , firefoxVersion = versionTest(STR_FIREFOX + '[\/ ]') , o = {} , version = 0; - if (uaTest(/windows phone/i)) { + if (uaTest('windows phone')) { o.windowsphone = o[STR_MOBILE] = TRUE; o[STR_VERSION] = versionTest('iemobile\/'); - } else if (uaTest(/opera/i) || uaTest(/opr/i)) { + + } else if (uaTest(STR_OPERA) || uaTest('opr')) { o[STR_OPERA] = TRUE; o[STR_VERSION] = webkitVersion || versionTest('opr\/') || versionTest('opera[ \/]'); - } else if (uaTest(/(msie|trident)/i)) { + + } else if (uaTest('(msie|trident)')) { o[STR_MSIE] = TRUE; o[STR_VERSION] = versionTest('(msie |rv:)', 2); - } else if (uaTest(/chrome/i)) { + + } else if (uaTest(STR_CHROME)) { o[STR_CHROME] = o[STR_WEBKIT] = TRUE; o[STR_VERSION] = versionTest(STR_CHROME + '\/'); - } else if (uaTest(/phantom/i)) { + + } else if (uaTest('phantom')) { o.phantom = o[STR_WEBKIT] = TRUE; o[STR_VERSION] = versionTest('phantomjs\/'); - } else if (uaTest(/touchpad/i)) { - o.touchpad = o[STR_WEBKIT] = TRUE; - o[STR_VERSION] = versionTest('touchpad\/'); + + } else if (uaTest(STR_TOUCHPAD)) { + o[STR_TOUCHPAD] = o[STR_WEBKIT] = TRUE; + o[STR_VERSION] = versionTest(STR_TOUCHPAD + '\/'); + } else if (iphone || ipad || ipod) { o.ios = o[STR_MOBILE] = o[STR_WEBKIT] = TRUE; // CAUTION: version is not part of user agent in web apps o[STR_VERSION] = webkitVersion; if (ipod) { - o.ipod = TRUE; + o[STR_IPOD] = TRUE; } else if (iphone) { - o.iphone = TRUE; + o[STR_IPHONE] = TRUE; } else if (ipad) { - o.ipad = TRUE; + o[STR_IPAD] = TRUE; } - } else if (uaTest(/blackberry/i)) { - o.blackberry = o[STR_MOBILE] = TRUE; + + } else if (uaTest(STR_BLACKBERRY)) { + o[STR_BLACKBERRY] = o[STR_MOBILE] = TRUE; if (webkitVersion) { o[STR_WEBKIT] = TRUE; o[STR_VERSION] = webkitVersion; } else { - o[STR_VERSION] = versionTest('blackberry[\\d]+\/'); + o[STR_VERSION] = versionTest(STR_BLACKBERRY + '[\\d]+\/'); } - } else if (uaTest(/webos/i)) { - o.webos = o[STR_MOBILE] = o[STR_WEBKIT] = TRUE; + + } else if (uaTest(STR_WEBOS)) { + o[STR_WEBOS] = o[STR_MOBILE] = o[STR_WEBKIT] = TRUE; o[STR_VERSION] = webkitVersion || versionTest('wosbrowser\/'); - } else if (uaTest(/android/i)) { - o.android = o[STR_MOBILE] = o[STR_WEBKIT] = TRUE; + + } else if (uaTest(STR_ANDROID)) { + o[STR_ANDROID] = o[STR_MOBILE] = o[STR_WEBKIT] = TRUE; o[STR_VERSION] = webkitVersion || firefoxVersion; - } else if (uaTest(/safari/i)) { + + } else if (uaTest(STR_SAFARI)) { o[STR_SAFARI] = o[STR_WEBKIT] = TRUE; o[STR_VERSION] = webkitVersion; - } else if (uaTest(/gecko\//i)) { - o.gecko = o.mozilla = TRUE; + + } else if (uaTest(STR_GECKO)) { + o[STR_GECKO] = o.mozilla = TRUE; o[STR_VERSION] = firefoxVersion; - if (uaTest(/firefox/i)) { + if (uaTest(STR_FIREFOX)) { o.firefox = TRUE; } - } else if (uaTest(/seamonkey\//i)) { + + } else if (uaTest('seamonkey\/')) { o.seamonkey = TRUE; o[STR_VERSION] = versionTest('seamonkey\/'); + } else { o[STR_VERSION] = 0; } @@ -167,7 +204,7 @@ /* Get our main bowser object from navigators user agent if present. */ var bowser = detect(typeof navigator !== 'undefined' ? navigator.userAgent : ''); - + /* * Set our detect method to the main bowser object so we can * reuse it to test other user agents. diff --git a/src/copyright.js b/src/copyright.js index efc64e0..3c0a02a 100644 --- a/src/copyright.js +++ b/src/copyright.js @@ -1,5 +1,5 @@ /*! - * Bowser - a browser detector - * https://github.com/ded/bowser - * MIT License | (c) Dustin Diaz 2013 - */ + * Bowser - a browser detector + * https://github.com/ded/bowser + * MIT License | (c) Dustin Diaz 2013 + */ diff --git a/src/useragents.js b/src/useragents.js index 0b8804b..301502f 100644 --- a/src/useragents.js +++ b/src/useragents.js @@ -4,7 +4,6 @@ * @see test/test.js * @author hannes.diercks@jimdo.com */ - module.exports.useragents = { Chrome: { 'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.17 Safari/537.36': { From 43953fc11fb86b97c87ea5f471e57fa3976f66e1 Mon Sep 17 00:00:00 2001 From: Hannes Diercks Date: Fri, 13 Sep 2013 16:19:03 +0200 Subject: [PATCH 11/11] Let me risk a little more light. --- README.md | 35 +++++++++++++++++++++++++++++++---- src/useragents.js | 1 + 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ba6e427..1776392 100644 --- a/README.md +++ b/README.md @@ -10,14 +10,25 @@ if (bowser.msie && bowser.version <= 6) { } ``` -Detected Browsers +Detected Browsers and Devices ----- - * msie - * safari[webkit] + * android + * blackberry * chrome[webkit] * firefox[gecko] + * ipad + * iphone + * ipod + * msie * opera + * phantomjs + * safari[webkit] + * seamonkey + * touchpad + * webos + * windows phone + Notes ---- @@ -60,4 +71,20 @@ else if (bowser.c) { } else { // unsupported (bowser.x) -} \ No newline at end of file +} +``` + +Building +-------- + +Simply `$ npm install` and `$ make` inside the bowser folder. + + +Testing +------- +We started a list `src/useragents.js` with example user agents and their expected bowser object. + +Whenever you add support for new browsers or notice a bug / mismatch, please update the list and +check if all tests are still passing. + +To run the test call `$ make test` and hope for green light ;) \ No newline at end of file diff --git a/src/useragents.js b/src/useragents.js index 301502f..e11fc2e 100644 --- a/src/useragents.js +++ b/src/useragents.js @@ -1,5 +1,6 @@ /** * Example User Agents and thair expected bowser objects. + * Most of them where found at http://www.useragentstring.com/ * * @see test/test.js * @author hannes.diercks@jimdo.com