1// Device.js 2// (c) 2014 Matthew Hudson 3// Device.js is freely distributable under the MIT license. 4// For all details and documentation: 5// http://matthewhudson.me/projects/device.js/ 6 7(function() { 8 9 var device, 10 previousDevice, 11 addClass, 12 documentElement, 13 find, 14 handleOrientation, 15 hasClass, 16 orientationEvent, 17 removeClass, 18 userAgent; 19 20 // Save the previous value of the device variable. 21 previousDevice = window.device; 22 23 device = {}; 24 25 // Add device as a global object. 26 window.device = device; 27 28 // The <html> element. 29 documentElement = window.document.documentElement; 30 31 // The client user agent string. 32 // Lowercase, so we can use the more efficient indexOf(), instead of Regex 33 userAgent = window.navigator.userAgent.toLowerCase(); 34 35 // Main functions 36 // -------------- 37 38 device.ios = function () { 39 return device.iphone() || device.ipod() || device.ipad(); 40 }; 41 42 device.iphone = function () { 43 return !device.windows() && find('iphone'); 44 }; 45 46 device.ipod = function () { 47 return find('ipod'); 48 }; 49 50 device.ipad = function () { 51 return find('ipad'); 52 }; 53 54 device.android = function () { 55 return !device.windows() && find('android'); 56 }; 57 58 device.androidPhone = function () { 59 return device.android() && find('mobile'); 60 }; 61 62 device.androidTablet = function () { 63 return device.android() && !find('mobile'); 64 }; 65 66 device.blackberry = function () { 67 return find('blackberry') || find('bb10') || find('rim'); 68 }; 69 70 device.blackberryPhone = function () { 71 return device.blackberry() && !find('tablet'); 72 }; 73 74 device.blackberryTablet = function () { 75 return device.blackberry() && find('tablet'); 76 }; 77 78 device.windows = function () { 79 return find('windows'); 80 }; 81 82 device.windowsPhone = function () { 83 return device.windows() && find('phone'); 84 }; 85 86 device.windowsTablet = function () { 87 return device.windows() && (find('touch') && !device.windowsPhone()); 88 }; 89 90 device.fxos = function () { 91 return (find('(mobile;') || find('(tablet;')) && find('; rv:'); 92 }; 93 94 device.fxosPhone = function () { 95 return device.fxos() && find('mobile'); 96 }; 97 98 device.fxosTablet = function () { 99 return device.fxos() && find('tablet'); 100 }; 101 102 device.meego = function () { 103 return find('meego'); 104 }; 105 106 device.cordova = function () { 107 return window.cordova && location.protocol === 'file:'; 108 }; 109 110 device.nodeWebkit = function () { 111 return typeof window.process === 'object'; 112 }; 113 114 device.mobile = function () { 115 return device.androidPhone() || device.iphone() || device.ipod() || device.windowsPhone() || device.blackberryPhone() || device.fxosPhone() || device.meego(); 116 }; 117 118 device.tablet = function () { 119 return device.ipad() || device.androidTablet() || device.blackberryTablet() || device.windowsTablet() || device.fxosTablet(); 120 }; 121 122 device.desktop = function () { 123 return !device.tablet() && !device.mobile(); 124 }; 125 126 device.television = function() { 127 var i, television = [ 128 "googletv", 129 "viera", 130 "smarttv", 131 "internet.tv", 132 "netcast", 133 "nettv", 134 "appletv", 135 "boxee", 136 "kylo", 137 "roku", 138 "dlnadoc", 139 "roku", 140 "pov_tv", 141 "hbbtv", 142 "ce-html" 143 ]; 144 145 i = 0; 146 while (i < television.length) { 147 if (find(television[i])) { 148 return true; 149 } 150 i++; 151 } 152 return false; 153 }; 154 155 device.portrait = function () { 156 return (window.innerHeight / window.innerWidth) > 1; 157 }; 158 159 device.landscape = function () { 160 return (window.innerHeight / window.innerWidth) < 1; 161 }; 162 163 // Public Utility Functions 164 // ------------------------ 165 166 // Run device.js in noConflict mode, 167 // returning the device variable to its previous owner. 168 device.noConflict = function () { 169 window.device = previousDevice; 170 return this; 171 }; 172 173 // Private Utility Functions 174 // ------------------------- 175 176 // Simple UA string search 177 find = function (needle) { 178 return userAgent.indexOf(needle) !== -1; 179 }; 180 181 // Check if documentElement already has a given class. 182 hasClass = function (className) { 183 var regex; 184 regex = new RegExp(className, 'i'); 185 return documentElement.className.match(regex); 186 }; 187 188 // Add one or more CSS classes to the <html> element. 189 addClass = function (className) { 190 var currentClassNames = null; 191 if (!hasClass(className)) { 192 currentClassNames = documentElement.className.replace(/^\s+|\s+$/g, ''); 193 documentElement.className = currentClassNames + " " + className; 194 } 195 }; 196 197 // Remove single CSS class from the <html> element. 198 removeClass = function (className) { 199 if (hasClass(className)) { 200 documentElement.className = documentElement.className.replace(" " + className, ""); 201 } 202 }; 203 204 // HTML Element Handling 205 // --------------------- 206 207 // Insert the appropriate CSS class based on the _user_agent. 208 209 if (device.ios()) { 210 if (device.ipad()) { 211 addClass("ios ipad tablet"); 212 } else if (device.iphone()) { 213 addClass("ios iphone mobile"); 214 } else if (device.ipod()) { 215 addClass("ios ipod mobile"); 216 } 217 } else if (device.android()) { 218 if (device.androidTablet()) { 219 addClass("android tablet"); 220 } else { 221 addClass("android mobile"); 222 } 223 } else if (device.blackberry()) { 224 if (device.blackberryTablet()) { 225 addClass("blackberry tablet"); 226 } else { 227 addClass("blackberry mobile"); 228 } 229 } else if (device.windows()) { 230 if (device.windowsTablet()) { 231 addClass("windows tablet"); 232 } else if (device.windowsPhone()) { 233 addClass("windows mobile"); 234 } else { 235 addClass("desktop"); 236 } 237 } else if (device.fxos()) { 238 if (device.fxosTablet()) { 239 addClass("fxos tablet"); 240 } else { 241 addClass("fxos mobile"); 242 } 243 } else if (device.meego()) { 244 addClass("meego mobile"); 245 }
245 else if (device.nodeWebkit()) { 246 addClass("node-webkit"); 247 } else if (device.television()) { 248 addClass("television"); 249 } else if (device.desktop()) { 250 addClass("desktop"); 251 } 252 253 if (device.cordova()) { 254 addClass("cordova"); 255 } 256 257 // Orientation Handling 258 // -------------------- 259 260 // Handle device orientation changes. 261 handleOrientation = function () { 262 if (device.landscape()) { 263 removeClass("portrait"); 264 addClass("landscape"); 265 } else { 266 removeClass("landscape"); 267 addClass("portrait"); 268 } 269 }; 270 271 // Detect whether device supports orientationchange event, 272 // otherwise fall back to the resize event. 273 if (Object.prototype.hasOwnProperty.call(window, "onorientationchange")) { 274 orientationEvent = "orientationchange"; 275 } else { 276 orientationEvent = "resize"; 277 } 278 279 // Listen for changes in orientation. 280 if (window.addEventListener) { 281 window.addEventListener(orientationEvent, handleOrientation, false); 282 } else if (window.attachEvent) { 283 window.attachEvent(orientationEvent, handleOrientation); 284 } else { 285 window[orientationEvent] = handleOrientation; 286 } 287 288 handleOrientation(); 289 290 if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) { 291 define(function() { 292 return device; 293 }); 294 } else if (typeof module !== 'undefined' && module.exports) { 295 module.exports = device; 296 } else { 297 window.device = device; 298 } 299 300}).call(this);
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.