1/** 2 * Detectr.js 3 * @author Rogerio Taques ([email protected]) 4 * @see http://github.com/rogeriotaques/detectrjs 5 * @version 1.7 6 * 7 * This project is based on the Rafael Lima's work 8 * which is called css_browser_selector and seems 9 * to be discontinued. (http://rafael.adm.br/css_browser_selector/). 10 */ 11 12/* 13 * Release notes 14 * v1.7 - Fixed a small bug regarding global variable 15 * v1.6 - Add a listener to reanalyse page on resize event 16 * v1.4 ~ v1.5 - Bug fixes for detecting Android Stock Browser and some improvements 17 * v1.3 - Start detecting Android Stock Browser 18 * v1.2 - Start detecting when device runs iOS 19 * v1.1 - Added support for Microsoft Edge 20 * v1.0 - First release. Totally rewritten and new detectings added. 21 */ 22 23/* 24 The MIT License (MIT) 25 26 Copyright (c) 2015 Rogério Taques 27 28 Permission is hereby granted, free of charge, to any person obtaining a copy 29 of this software and associated documentation files (the "Software"), to deal 30 in the Software without restriction, including without limitation the rights 31 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 32 copies of the Software, and to permit persons to whom the Software is 33 furnished to do so, subject to the following conditions: 34 35 The above copyright notice and this permission notice shall be included in all 36 copies or substantial portions of the Software. 37 38 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 39 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 40 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 41 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 42 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 43 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 44 SOFTWARE. 45 */ 46 47(function ($) { 48 "use strict"; 49 50 var version = '1.7'; 51 52 /** 53 * Whenever .trim() isn't supported, makes it be. 54 */ 55 if(typeof String.prototype.trim !== 'function') { 56 57 String.prototype.trim = function() { 58 return this.replace(/^\s+|\s+$/g, ''); 59 }; 60 61 } 62 63 var 64 doc = $.document, 65 element = doc.documentElement, 66 detectr, 67 originalClassNames, 68 resizing; 69 70 detectr = function (userAgent) { 71 72 var 73 ua = userAgent.toLowerCase(), 74 winWidth = $.outerWidth || element.clientWidth, 75 winHeight = $.outerHeight || element.clientHeight, 76 gecko = 'gecko', 77 webkit = 'webkit', 78 safari = 'safari', 79 opera = 'opera', 80 mobile = 'mobile', 81 is, detect; 82 83 /** 84 * Checks if given string is present on the userAgent. 85 * @param string str 86 * @return {Boolean} 87 */ 88 is = function (str) { 89 return ua.indexOf(str) > -1; 90 }; 91 92 /** 93 * The core feature ... 94 */ 95 detect = function () { 96 var 97 rendered = [], 98 version = '', 99 implementation = doc.implementation, 100 webkitVersion = (/applewebkit\/(\d{1,})/.test(ua) ? RegExp.$1 : false); 101 102 // *** Detecting browsers *** 103 switch ( true ) { 104 105 // internet explorer 106 case (is('msie') && !is('opera') && !is('webtv') || is('trident') || is('edge')): 107 108 if (is('edge')) { 109 version = (/edge\/(\w+)/.test(ua) ? ' edge ie' + RegExp.$1 : ' ie11'); 110 } else if (is('msie 8.0') || is('trident/7.0')) { 111 version = ' ie11'; 112 } else { 113 version = (/msie\s(\d+)/.test(ua) ? ' ie' + RegExp.$1 : ''); 114 } 115 116 rendered.push('ie' + version); 117 break; 118 119 // iron 120 case (is('iron/') || is('iron')): 121 version = (/iron\/(\d+)/.test(ua) ? ' iron' + RegExp.$1 : ''); 122 rendered.push(webkit + ' iron' + version); 123 break; 124 125 // android 126 case (is('android') && is('u;') && (!is('chrome') || is('chrome') && webkitVersion && webkitVersion <= 534)): 127 128 // according to some researches (http://stackoverflow.com/questions/14403766/how-to-detect-the-stock-android-browser) 129 // android stock (native) browsers never went above applewebkit/534.x, then, we can suppose user is using a 130 // native browser in android when the UA contains "android", "mobile" and "U;" strings 131 132 rendered.push('android-browser'); 133 break; 134 135 // google chrome 136 case (is('chrome/') || is('chrome')): 137 version = (/chrome\/(\d+)/.test(ua) ? ' chrome' + RegExp.$1 : ''); 138 rendered.push(webkit + ' chrome' + version); 139 break; 140 141 // firefox 142 case (is('firefox/') || is('firefox')): 143 version = (/firefox\/(\d+)/.test(ua) ? ' firefox' + RegExp.$1 : ''); 144 rendered.push(gecko + ' firefox' + version); 145 break; 146 147 // opera 148 case (is('opera/') || is('opera')): 149 version = (/version(\s|\/)(\d+)/.test(ua) || /opera(\s|\/)(\d+)/.test(ua) ? ' ' + opera + RegExp.$2 : ''); 150 rendered.push(opera + version); 151 break; 152 153 // konqueror 154 case (is('konqueror')): 155 rendered.push(mobile + ' konqueror'); 156 break; 157 158 // blackberry 159 case (is('blackberry') || is('bb')): 160 rendered.push(mobile + ' blackberry'); 161 162 if (is('bb')) { 163 version = (/bb(\d{1,2})(\;{0,1})/.test(ua) ? 'bb' + RegExp.$1 : ''); 164 rendered.push(version); 165 } 166 167 break; 168 169 // safari 170 case (is('safari/') || is('safari')): 171 172 version = (/version\/(\d+)/.test(ua) || /safari\/(\d+)/.test(ua) ? ' ' + s
172afari + RegExp.$1 : ''); 173 rendered.push(webkit + ' ' + safari + version); 174 break; 175 176 // applewebkit 177 case (is('applewebkit/') || is('applewebkit')): 178 version = (/applewebkit\/(\d+)/.test(ua) ? ' ' + webkit + RegExp.$1 : ''); 179 rendered.push(webkit); 180 break; 181 182 // gecko || mozilla 183 case (is('gecko') || is('mozilla/')): 184 rendered.push(gecko); 185 break; 186 } 187 188 // *** Detecting O.S *** 189 switch ( true ) { 190 191 // ios 192 case (is('iphone') || is('ios')): 193 version = (/iphone\sos\s(\d{1,2})/.test(ua) ? ' ios' + RegExp.$1 : ''); 194 195 // For some reason when it's iOS8, userAgent comes like OS 10_10 196 // what returns a wrong version, then we need to match it against 197 // another value 198 if (version === ' ios10') { 199 var vv = (/(\d{1,2})/.test(version) ? RegExp.$1 : 0); 200 var vd = (/\sversion\/(\d{1,2})/.test(ua) ? RegExp.$1 : ''); 201 202 if (parseInt(vv) > parseInt(vd)) { 203 version = ' ios' + vd; 204 } 205 } 206 207 rendered.push('ios' + version); 208 break; 209 210 // macintosh 211 case (is('mac') || is('macintosh') || is('darwin')): 212 version = (/mac\sos\sx\s(\d{1,2}\_\d{1,2})/.test(ua) ? ' osx' + RegExp.$1 : ''); 213 rendered.push('mac' + version); 214 break; 215 216 // windows 217 case (is('windows') || is('win')): 218 version = (/windows\s(nt\s{0,1})(\d{1,2}\.\d)/.test(ua) ? '' + RegExp.$2 : ''); 219 220 // defining windows version 221 switch ( version ) { 222 case '5.0': 223 version = ' win2k'; 224 break; 225 case '5.01': 226 version = ' win2k sp1'; 227 break; 228 case '5.1': 229 case '5.2': 230 version = ' xp'; 231 break; 232 case '6.0': 233 version = ' vista'; 234 break; 235 case '6.1': 236 version = ' win7'; 237 break; 238 case '6.2': 239 version = ' win8'; 240 break; 241 case '6.3': 242 version = ' win8_1'; 243 break; 244 case '6.4': 245 version = ' win10'; 246 break; 247 default: 248 version = ' nt nt' + version; 249 } 250 251 rendered.push('windows' + version); 252 break; 253 254 // webtv 255 case (is('webtv')): 256 rendered.push('webtv'); 257 break; 258 259 // freebsd 260 case (is('freebsd')): 261 rendered.push('freebsd'); 262 break; 263 264 // android 265 case (is('android') || (is('linux') && is('mobile'))): 266 rendered.push('android'); 267 break; 268 269 // linux 270 case (is('linux') || is('x11')): 271 rendered.push('linux'); 272 break; 273 } 274 275 // *** Detecting platform *** 276 switch ( true ) { 277 // 64 bits 278 case (is('wow64') || is('x64')): 279 rendered.push('x64'); 280 break; 281 282 // arm 283 case (is('arm')): 284 rendered.push('arm'); 285 break; 286 287 // 32 bits 288 default: 289 rendered.push('x32'); 290 } 291 292 // *** Detecting devices *** 293 switch (true) { 294 295 case (is('j2me')): 296 rendered.push(mobile + ' j2me'); 297 break; 298 299 case ( /(iphone|ipad|ipod)/.test(ua) ): 300 rendered.push(mobile + ' ' + RegExp.$1); 301 break; 302 303 case (is('mobile')): 304 rendered.push(mobile); 305 break; 306 } 307 308 // *** Detecting touchable devices *** 309 if (/touch/.test(ua)) { 310 rendered.push('touch'); 311 } 312 313 // *** Assume that it supports javascript by default *** 314 rendered.push('js'); 315 316 // *** Detect if SVG images are supported *** 317 rendered.push( 318 implementation !== undefined && 319 typeof implementation.hasFeature === 'function' && 320 implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Image", "1.1") ? 321 'svg' : 322 'no-svg' 323 ); 324 325 // *** Detect retina display *** 326 rendered.push($.devicePixelRatio !== undefined && $.devicePixelRatio > 1 ? 'retina' : 'no-retina'); 327 328 // *** Detecting orientation *** 329 rendered.push(winWidth < winHeight ? 'portrait' : 'landscape'); 330 331 return rendered; 332 }; 333 334 // convert 'detect' from function to array 335 // and avoid unnecessary processing 336 detect = detect(); 337 338 // inject the information in the HTML tag 339 element.className = element.className.split(' ').concat(detect).join(' ').trim(); 340 341 // return what was detected 342 return { 343 'detected': detect.join(' ').trim(), 344 'version': version 345 }; 346 }; 347 348 // make detectr return available on global scope of console. 349 originalClassNames = element.className; 350 $.detectr = detectr($.navigator.userAgent); 351 352 /** 353 * The listener engine for resize event ... 354 */ 355 resizing = function (event) { 356 element.className = originalClassNames; 357 $.detectr = detectr($.navigator.userAgent); 358 }; 359 360 //this chrashes our async logininfo 361 /*if ($.attachEvent) { 362 $.attachEvent('onresize', resizing); 363 } else if ($.addEventListener) { 364 $.addEventListener('resize', resizing, true); 365 }*/ 366}(window));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.