UNPKG

chicago

Version:

A front-end JavaScript library for user-interface developers.

586 lines (541 loc) 16.7 kB
/*! * Chicago - Browser * A collection of browser capability methods * * Copyright (c) 2015 Erik Nielsen * * Licensed under the MIT license: * http://www.opensource.org/licenses/mit-license.php * * Project home: * https://nielse63.github.io/Chicago/ * * Version: @VERSION * */ (function( global, factory ) { var module; var Chicago = global.Chicago || null; if(Chicago) { module = factory( Chicago, global, global.document ); } if( typeof define === 'function' && define.amd ) { define('chicago-browser', ['chicago'], function() { return module || factory( Chicago, global, global.document ); }); } })(typeof window !== "undefined" ? window : (typeof this.window !== "undefined" ? this.window : this), function( _c, win, doc ) { var test = function( rgx ) { var ua = win.navigator.userAgent; return rgx.test( ua ) || rgx.test( ua.toLowerCase() ); }; var exec = function( rgx ) { var ua = win.navigator.userAgent; return rgx.exec( ua ) || rgx.exec( ua.toLowerCase() ); }; var uamatches = function( key ) { var ua = win.navigator.userAgent; return ua.indexOf( key ) > -1 || ua.toLowerCase().indexOf( key ) > -1; }; var match = function( key ) { var matches = win.navigator.userAgent.match(key); return !! matches ? matches[0] : null; }; var version = function(obj, string) { var returnObj = { version : { full : string } }; var versionArray = string.split('.'); if(versionArray.length > 0) { versionArray = versionArray.reverse(); returnObj.version.major = parseFloat( versionArray.pop() ); if(versionArray.length > 0) { returnObj.version.minor = parseFloat( versionArray.pop() ); if(versionArray.length > 0) { versionArray = versionArray.reverse(); returnObj.version.patch = parseFloat( versionArray.join('.') ); } else { returnObj.version.patch = 0; } } else { returnObj.version.minor = 0; } } else { returnObj.version.major = 0; } return _c.$.extend( obj, returnObj ); }; var objectHasKey = function( search, obj ) { if( ! _c.utils.is.object( obj ) ) { return false; } if( _c.utils.is.string( search ) ) { search = search.toLowerCase(); } for( var k in obj ) { var val = obj[k]; if( _c.utils.is.string( val ) ) { val = val.toLowerCase(); } if( _c.utils.is.object( val ) ) { var contains = objectHasKey( search, val ); if( contains ) { return true; } } if( val === search ) { return true; } } return false; }; var defs = { device : { types : ['TV', 'Tablet', 'Mobile', 'Desktop'], }, screens : { mini : 0, small : 480, medium : 768, large : 960, xlarge : 1220 }, }; _c.browser = { is : function( string ) { return objectHasKey( string, this ); }, can : function( style ) { var supports = (function() { var div = doc.createElement('div'); var vendors = 'Khtml Ms ms O Moz Webkit'.split(' '); return function(prop) { if( ! _c.utils.is.undefined( div.style[prop] ) ) { return true; } prop = prop.replace(/^[a-z]/, function(val) { return val.toUpperCase(); }); for(var i = 0; i < vendors.length; i++) { var vendor = vendors[i]; if( ! _c.utils.is.undefined( div.style[vendor + prop] ) ) { return true; } } return false; }; })(); return supports( style ); }, getPrefix : function( prop ) { var div = doc.createElement( 'div' ), vendors = 'Khtml Ms ms O Moz Webkit'.split(' '); prop = _c.utils.toCamelCase( prop ); if( ! _c.utils.is.undefined( div.style[prop] ) ) { return ''; } for( var i = 0; i < vendors.length; i++ ) { var vendor = vendors[i]; if( ! _c.utils.is.undefined( div.style[vendor + prop] ) ) { return '-' + vendor.toLowerCase() + '-'; } } return ''; }, }; return _c.module('browserProxy', { defaults : { check : { borwser : true, device : true, language : true, os : true, plugins : true, screen : true, touch : true, }, addHTMLClasses : true, }, classes : [], boot : function() { return _c.ready(function() { var ele = _c.$doc; if( ! ele.data( 'chicago.data.browserProxy' ) ) { _c.browserProxy( ele ); } }); }, init : function() { _c.$doc.on('ready.chicago.dom reloaded.chicago.dom', function(_this) { return function(e) { _this.setBrowserData(); }; }(this)); }, // setters setBrowserData : function() { if( this.options.check.touch ) { _c.browser.touch = this.getTouch(); } if( this.options.check.device ) { _c.browser.device = this.getDevice(); } if( this.options.check.screen ) { _c.browser.screen = this.getScreen(); } if( this.options.check.os ) { _c.browser.os = this.getOS(); } if( this.options.check.borwser ) { _c.browser.browser = this.getBrowser(); } if( this.options.check.language ) { _c.browser.language = this.getLanguage(); } if( this.options.check.plugins ) { _c.browser.plugins = this.getPlugins(); } if( this.options.addHTMLClasses ) { this.addHTMLClasses(); } win.setTimeout(function() { _c.$doc.trigger('updated.chicago.browser'); }); }, // getters getTouch : function() { var touch = 'ontouchstart' in win && win.navigator.userAgent.toLowerCase().match(/mobile|tablet/) || win.DocumentTouch && doc instanceof win.DocumentTouch || win.navigator.msPointerEnabled && win.navigator.msMaxTouchPoints > 0 || win.navigator.pointerEnabled && win.navigator.maxTouchPoints > 0 || false; return !! touch; }, getDevice : function() { var device = { type : null, model : null }; if( test(/GoogleTV|SmartTV|SMART-TV|Internet.TV|NetCast|NetTV|AppleTV|Boxee|Kylo|Roku|dlnadoc|Roku|POV_TV|HbbTV|ce\-html/) ) { device.type = defs.device.types[0]; device.model = 'SmartTV'; } else if( test(/Xbox|PLAYSTATION 3|Wii/) ) { device.type = defs.device.types[0]; device.model = 'Game Console'; } else if( test(/ip(a|ro)d/)) { device.type = defs.device.types[1]; device.model = 'iPad'; } else if( ( test(/tablet/) && ! test(/rx-34/) ) || test(/folio/) ) { device.type = defs.device.types[1]; device.model = String( exec(/PlayBook/) || '' ); } else if( test(/linux/) && test(/Android/) && ! test(/Fennec|mobi|htc.magic|htcX06ht|nexus.one|sc-02b|fone.945/) ) { device.type = defs.device.types[1]; device.model = 'Android'; } else if( test(/Kindle/) || ( test(/mac.os/) && test(/silk/)) ) { device.type = defs.device.types[1]; device.model = 'Kindle'; } else if( test(/gt-p10|sc-01c|shw-m180s|sgh-t849|sch-i800|shw-m180l|sph-p100|sgh-i987|zt180|htc(.flyer|\_flyer)|sprint.atp51|viewpad7|pandigital(sprnova|nova)|ideos.s7|dell.streak.7|advent.vega|a101it|a70bht|mid7015|next2|nook/) || ( test(/mb511/) && test(/rutem/))) { device.type = defs.device.types[1]; device.model = 'Android'; } else if( test(/bb10/)) { device.type = defs.device.types[1]; device.model = 'BlackBerry'; } else { device.model = exec(/iPhone|iPod|Android|BlackBerry|Opera Mini|Opera Mobi|Skyfire|Maemo|Windows Phone|Palm|IEMobile|Symbian|SymbianOS|Fennec|J2ME/); if(device.model !== null) { device.type = defs.device.types[2]; device.model = match( String( device.model ) ); } else { device.model = ''; if( test(/Bolt|Fennec|Iris|Maemo|minimo|mobi|mowser|netfront|novarra|prism|rx-34|Skyfire|tear|xv6875|xv6975|google.wireless.transcoder/)) { device.type = defs.device.types[2]; } else if( test(/opera/) && test(/windows.nt.5/) && test(/htc|xda|mini|vario|samsung\-gt\-i8000|samsung\-sgh\-i9/)) { device.type = defs.device.types[2]; } else if(( test(/windows.(nt|xp|me|9)/) && ! test(/phone/)) || test(/win(9|.9|nt)/) || test(/\(windows 8\)/)) { device.type = defs.device.types[3]; } else if( test(/macintosh|powerpc/) && ! test(/silk/)) { device.type = defs.device.types[3]; device.model = 'Mac'; } else if( test(/linux/) && test(/x11/)) { device.type = defs.device.types[3]; } else if( test(/solaris|sunos|bsd/)) { device.type = defs.device.types[3]; } else if( test(/cros/)) { device.type = defs.device.types[3]; } else if( test(/bot|crawler|spider|yahoo|ia_archiver|covario-ids|findlinks|dataparksearch|larbin|mediapartners-google|ng-search|snappy|teoma|jeeves|tineye/) && ! test(/mobile/)) { device.type = defs.device.types[3]; device.model = 'Crawler'; } else { device.type = defs.device.types[3]; } } } if( device.type !== 'Desktop' && device.type !== 'TV' ) { device.orientation = 'landscape'; if( win.innerHeight > win.innerWidth ) { device.orientation = 'portrait'; } } return device; }, getScreen : function() { var keys = Object.keys( defs.screens ).reverse(); for(var i = 0; i < keys.length; i++) { var size = keys[i]; var width = defs.screens[size]; if( win.innerWidth > ( width - 1 ) ) { return size; } } }, getOS: function() { var os = { name : null, addressRegisterSize : null, }; if(_c.browser.device.model !== '') { if(_c.browser.device.model === 'iPad' || _c.browser.device.model === 'iPhone' || _c.browser.device.model === 'iPod') { os.name = 'iOS'; os = version(os, (test(/os\s([\d_]+)/) ? RegExp.$1 : '').replace(/_/g, '.')); } else if(_c.browser.device.model === 'Android') { os.name = 'Android'; os = version(os, (test(/Android\s([\d\.]+)/) ? RegExp.$1 : '')); } else if(_c.browser.device.model === 'BlackBerry') { os.name = 'BlackBerry'; os = version(os, (test(/version\/([^\s]+)/) ? RegExp.$1 : '')); } else if(_c.browser.device.model === 'PlayBook') { os.name = 'BlackBerry'; os = version(os, (test(/os ([^\s]+)/) ? RegExp.$1.replace(';', '') : '')); } } if( ! os.name ) { var options = [ 'iOS', 'Android', 'BlackBerry', 'Opera Mini', 'Windows', 'Mac OS', 'OS X', 'AIX', 'Amiga', 'AROS', 'Bada', 'BeOS', 'Brew', 'Chrome OS', 'COS', 'Danger Hiptop', 'DragonFly BSD', 'Fire OS', 'Firefox OS', 'FreeBSD', 'GNU OS', 'Haiku OS', 'HP-UX', 'Inferno OS', 'IRIX', 'Joli OS', 'JVM (Java)', 'JVM', 'KIN OS', 'Linux', 'LiveArea', 'Maemo', 'MeeGo', 'MINIX 3', 'MorphOS', 'MSN TV (WebTV)', 'NetBSD', 'Nintendo 3DS', 'Nintendo DS', 'OpenBSD', 'OpenVM', 'Orbis OS', 'OS/2', 'OS/2 Warp', 'Palm OS', 'PClinuxOS', 'Plan 9', 'QNX x86pc', 'RISK OS', 'Sailfish', 'SCO OpenServer', 'SkyOS', 'Solaris', 'Syllable', 'Symbian OS', 'Tizen', 'Ubuntu Touch', 'webOS', 'Wii OS', 'Wii U OS', 'Xbox', 'XrossMediaBar (XMB)', 'Yun OS', 'unknown', ]; for( var i = 0; i < options.length; i++ ) { var option = options[i]; if( uamatches( option ) ) { os.name = option; break; } } } if( ! os.name ) { if(_c.browser.device.model !== '') { if(_c.browser.device.model === 'ipad' || _c.browser.device.model === 'iphone' || _c.browser.device.model === 'ipod') { os.name = 'ios'; version(os, (test(/os\s([\d_]+)/) ? RegExp.$1 : '').replace(/_/g, '.')); } else if(_c.browser.device.model === 'Android') { os.name = 'Android'; version(os, (test(/Android\s([\d\.]+)/) ? RegExp.$1 : '')); } else if(_c.browser.device.model === 'BlackBerry') { os.name = 'BlackBerry'; version(os, (test(/version\/([^\s]+)/) ? RegExp.$1 : '')); } else if(_c.browser.device.model === 'PlayBook') { os.name = 'BlackBerry'; version(os, (test(/os ([^\s]+)/) ? RegExp.$1.replace(';', '') : '')); } } } if( ! os.name ) { if(uamatches('win') || uamatches('16bit')) { os.name = 'windows'; if(uamatches('windows nt 6.3')) { os = version(os, '8.1'); } else if(uamatches('windows nt 6.2') || test(/\(windows 8\)/)) { os = version(os, '8'); } else if(uamatches('windows nt 6.1')) { os = version(os, '7'); } else if(uamatches('windows nt 6.0')) { os = version(os, 'vista'); } else if(uamatches('windows nt 5.2') || uamatches('windows nt 5.1') || uamatches('windows xp')) { os = version(os, 'xp'); } else if(uamatches('windows nt 5.0') || uamatches('windows 2000')) { os = version(os, '2k'); } else if(uamatches('winnt') || uamatches('windows nt')) { os = version(os, 'nt'); } else if(uamatches('win98') || uamatches('windows 98')) { os = version(os, '98'); } else { if(uamatches('win95') || uamatches('windows 95')) { os = version(os, '95'); } } } else if(uamatches('mac') || uamatches('darwin')) { os.name = 'mac'; if(uamatches('68k') || uamatches('68000')) { os = version(os, '68k'); } else if(uamatches('ppc') || uamatches('powerpc')) { os = version(os, 'ppc'); } else { if(uamatches('os x')) { os = version(os, (test(/os\sx\s([\d_]+)/) ? RegExp.$1 : 'os x').replace(/_/g, '.')); } } } else if(uamatches('webtv')) { os.name = 'webtv'; } else if(uamatches('x11') || uamatches('inux')) { os.name = 'linux'; } else if(uamatches('sunos')) { os.name = 'sun'; } else if(uamatches('irix')) { os.name = 'irix'; } else if(uamatches('freebsd')) { os.name = 'freebsd'; } else { if(uamatches('bsd')) { os.name = 'bsd'; } } } if(test(/\sx64|\sx86|\swin64|\swow64|\samd64/)) { os.addressRegisterSize = '64bit'; } else { os.addressRegisterSize = '32bit'; } return os; }, getBrowser: function() { var browser = { name : null, engine : null, }; if( ! test(/opera|webtv/) && ( test(/msie\s([\d\w\.]+)/) || uamatches('trident') ) ) { browser.engine = 'trident'; browser.name = 'ie'; if( ! win.addEventListener && doc.documentMode && doc.documentMode === 7) { browser = version(browser, '8.compat'); } else if(test(/trident.*rv[ :](\d+)\./)) { browser = version(browser, RegExp.$1); } else { browser = version(browser, (test(/trident\/4\.0/) ? '8' : RegExp.$1)); } } else if(uamatches('firefox')) { browser.engine = 'gecko'; browser.name = 'firefox'; browser = version(browser, (test(/firefox\/([\d\w\.]+)/) ? RegExp.$1 : '')); } else if(uamatches('gecko/')) { browser.engine = 'gecko'; } else if(uamatches('opera') || uamatches('opr')) { browser.name = 'opera'; browser.engine = 'presto'; browser = version(browser, (test(/version\/([\d\.]+)/) ? RegExp.$1 : (test(/opera(\s|\/)([\d\.]+)/) ? RegExp.$2 : ''))); } else if(uamatches('konqueror')) { browser.name = 'konqueror'; } else if(uamatches('chrome')) { browser.engine = 'webkit'; browser.name = 'chrome'; browser = version(browser, (test(/chrome\/([\d\.]+)/) ? RegExp.$1 : '')); } else if(uamatches('iron')) { browser.engine = 'webkit'; browser.name = 'iron'; } else if(uamatches('crios')) { browser.name = 'chrome'; browser.engine = 'webkit'; browser = version(browser, (test(/crios\/([\d\.]+)/) ? RegExp.$1 : '')); } else if(uamatches('applewebkit/')) { browser.name = 'safari'; browser.engine = 'webkit'; browser = version(browser, (test(/version\/([\d\.]+)/) ? RegExp.$1 : '')); } else if(uamatches('mozilla/')) { browser.engine = 'gecko'; } return browser; }, getLanguage: function() { return { direction : _c.$html.attr('dir') || win.getComputedStyle(doc.body || doc.documentElement).direction || 'ltr', code : win.navigator.userLanguage || win.navigator.language, }; }, getPlugins: function() { var output = []; if( ! _c.utils.is.undefined( win.navigator.plugins ) ) { for( var i = 0; i < win.navigator.plugins.length; i++ ) { output.push( win.navigator.plugins[i] ); } } return output; }, // add html tables addHTMLClasses : function() { var classes = []; if( _c.browser.screen ) { classes.push( 'screen-' + _c.browser.screen ); } if( ! _c.utils.is.undefined( _c.browser.touch ) ) { classes.push( _c.browser.touch ? 'touch' : 'notouch' ); } if( classes.diff( this.classes ).length ) { _c.$html.removeClass( this.classes.join(' ') ); _c.$html.addClass( classes.join(' ') ); this.classes = classes; } } }); });