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, tvString; 128 129 television = [ 130 "googletv", 131 "viera", 132 "smarttv", 133 "internet.tv", 134 "netcast", 135 "nettv", 136 "appletv", 137 "boxee", 138 "kylo", 139 "roku", 140 "dlnadoc", 141 "roku", 142 "pov_tv", 143 "hbbtv", 144 "ce-html" 145 ]; 146 147 i = 0; 148 while (i < television.length) { 149 if (find(television[i])) { 150 return true; 151 } 152 i++; 153 } 154 return false; 155 }; 156 157 device.portrait = function () { 158 return (window.innerHeight / window.innerWidth) > 1; 159 }; 160 161 device.landscape = function () { 162 return (window.innerHeight / window.innerWidth) < 1; 163 }; 164 165 // Public Utility Functions 166 // ------------------------ 167 168 // Run device.js in noConflict mode, 169 // returning the device variable to its previous owner. 170 device.noConflict = function () { 171 window.device = previousDevice; 172 return this; 173 }; 174 175 // Private Utility Functions 176 // ------------------------- 177 178 // Simple UA string search 179 find = function (needle) { 180 return userAgent.indexOf(needle) !== -1; 181 }; 182 183 // Check if documentElement already has a given class. 184 hasClass = function (className) { 185 var regex; 186 regex = new RegExp(className, 'i'); 187 return documentElement.className.match(regex); 188 }; 189 190 // Add one or more CSS classes to the <html> element. 191 addClass = function (className) { 192 var currentClassNames = null; 193 if (!hasClass(className)) { 194 currentClassNames = documentElement.className.replace(/^\s+|\s+$/g, ''); 195 documentElement.className = currentClassNames + " " + className; 196 } 197 }; 198 199 // Remove single CSS class from the <html> element. 200 removeClass = function (className) { 201 if (hasClass(className)) { 202 documentElement.className = documentElement.className.replace(" " + className, ""); 203 } 204 }; 205 206 // HTML Element Handling 207 // --------------------- 208 209 // Insert the appropriate CSS class based on the _user_agent. 210 211 if (device.ios()) { 212 if (device.ipad()) { 213 addClass("ios ipad tablet"); 214 } else if (device.iphone()) { 215 addClass("ios iphone mobile"); 216 } else if (device.ipod()) { 217 addClass("ios ipod mobile"); 218 } 219 } else if (device.android()) { 220 if (device.androidTablet()) { 221 addClass("android tablet"); 222 } else { 223 addClass("android mobile"); 224 } 225 } else if (device.blackberry()) { 226 if (device.blackberryTablet()) { 227 addClass("blackberry tablet"); 228 } else { 229 addClass("blackberry mobile"); 230 } 231 } else if (device.windows()) { 232 if (device.windowsTablet()) { 233 addClass("windows tablet"); 234 } else if (device.windowsPhone()) { 235 addClass("windows mobile"); 236 } else { 237 addClass("desktop"); 238 } 239 } else if (device.fxos()) { 240 if (device.fxosTablet()) { 241 addClass("fxos tablet"); 242 } else { 243 addClass("fxos mobile"); 244 } 245 } else if (device.meego()) { 246 addClass("meego mobile"); 247 }
247 else if (device.nodeWebkit()) { 248 addClass("node-webkit"); 249 } else if (device.television()) { 250 addClass("television"); 251 } else if (device.desktop()) { 252 addClass("desktop"); 253 } 254 255 if (device.cordova()) { 256 addClass("cordova"); 257 } 258 259 // Orientation Handling 260 // -------------------- 261 262 // Handle device orientation changes. 263 handleOrientation = function () { 264 if (device.landscape()) { 265 removeClass("portrait"); 266 addClass("landscape"); 267 } else { 268 removeClass("landscape"); 269 addClass("portrait"); 270 } 271 return; 272 }; 273 274 // Detect whether device supports orientationchange event, 275 // otherwise fall back to the resize event. 276 if (Object.prototype.hasOwnProperty.call(window, "onorientationchange")) { 277 orientationEvent = "orientationchange"; 278 } else { 279 orientationEvent = "resize"; 280 } 281 282 // Listen for changes in orientation. 283 if (window.addEventListener) { 284 window.addEventListener(orientationEvent, handleOrientation, false); 285 } else if (window.attachEvent) { 286 window.attachEvent(orientationEvent, handleOrientation); 287 } else { 288 window[orientationEvent] = handleOrientation; 289 } 290 291 handleOrientation(); 292 293 if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) { 294 define(function() { 295 return device; 296 }); 297 } else if (typeof module !== 'undefined' && module.exports) { 298 module.exports = device; 299 } else { 300 window.device = device; 301 } 302 303}).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.