Last active
December 21, 2018 16:08
-
-
Save matthewhudson/c2e86912a047880e8293 to your computer and use it in GitHub Desktop.
First pass at a device.js refactor from CoffeeScript to JavaScript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*jslint browser: true, indent: 2 */ | |
'use strict'; | |
// Device.js | |
// (c) 2014 Matthew Hudson | |
// Device.js is freely distributable under the MIT license. | |
// For all details and documentation: | |
// http://matthewhudson.me/projects/device.js/ | |
var lib, | |
device, | |
previousDevice, | |
addClass, | |
documentElement, | |
find, | |
handleOrientation, | |
hasClass, | |
orientationEvent, | |
removeClass, | |
userAgent; | |
// Save the previous value of the device variable. | |
previousDevice = window.device; | |
device = {}; | |
// Add device as a global object. | |
window.device = device; | |
// The <html> element. | |
documentElement = window.document.documentElement; | |
// The client user agent string. | |
// Lowercase, so we can use the more efficient indexOf(), instead of Regex | |
userAgent = window.navigator.userAgent.toLowerCase(); | |
// Main functions | |
// -------------- | |
device.ios = function () { | |
return device.iphone() || device.ipod() || device.ipad(); | |
}; | |
device.iphone = function () { | |
return find('iphone'); | |
}; | |
device.ipod = function () { | |
return find('ipod'); | |
}; | |
device.ipad = function () { | |
return find('ipad'); | |
}; | |
device.android = function () { | |
return find('android'); | |
}; | |
device.androidPhone = function () { | |
return device.android() && find('mobile'); | |
}; | |
device.androidTablet = function () { | |
return device.android() && !find('mobile'); | |
}; | |
device.blackberry = function () { | |
return find('blackberry') || find('bb10') || find('rim'); | |
}; | |
device.blackberryPhone = function () { | |
return device.blackberry() && !find('tablet'); | |
}; | |
device.blackberryTablet = function () { | |
return device.blackberry() && find('tablet'); | |
}; | |
device.windows = function () { | |
return find('windows'); | |
}; | |
device.windowsPhone = function () { | |
return device.windows() && find('phone'); | |
}; | |
device.windowsTablet = function () { | |
return device.windows() && (find('touch') && !device.windowsPhone()); | |
}; | |
device.fxos = function () { | |
return (find('(mobile;') || find('(tablet;')) && find('; rv:'); | |
}; | |
device.fxosPhone = function () { | |
return device.fxos() && find('mobile'); | |
}; | |
device.fxosTablet = function () { | |
return device.fxos() && find('tablet'); | |
}; | |
device.meego = function () { | |
return find('meego'); | |
}; | |
device.cordova = function () { | |
return window.cordova && location.protocol === 'file:'; | |
}; | |
device.nodeWebkit = function () { | |
return typeof window.process === 'object'; | |
}; | |
device.mobile = function () { | |
return device.androidPhone() || device.iphone() || device.ipod() || device.windowsPhone() || device.blackberryPhone() || device.fxosPhone() || device.meego(); | |
}; | |
device.tablet = function () { | |
return device.ipad() || device.androidTablet() || device.blackberryTablet() || device.windowsTablet() || device.fxosTablet(); | |
}; | |
device.desktop = function () { | |
return !device.tablet() && !device.mobile(); | |
}; | |
device.portrait = function () { | |
return (window.innerHeight / window.innerWidth) > 1; | |
}; | |
device.landscape = function () { | |
return (window.innerHeight / window.innerWidth) < 1; | |
}; | |
// Public Utility Functions | |
// ------------------------ | |
// Run device.js in noConflict mode, | |
// returning the device variable to its previous owner. | |
device.noConflict = function () { | |
window.device = previousDevice; | |
return this; | |
}; | |
// Private Utility Functions | |
// ------------------------- | |
// Simple UA string search | |
find = function (needle) { | |
return userAgent.indexOf(needle) !== -1; | |
}; | |
// Check if documentElement already has a given class. | |
hasClass = function (className) { | |
var regex; | |
regex = new RegExp(className, 'i'); | |
return documentElement.className.match(regex); | |
}; | |
// Add one or more CSS classes to the <html> element. | |
addClass = function (className) { | |
if (!hasClass(className)) { | |
documentElement.className += " " + className; | |
} | |
}; | |
// Remove single CSS class from the <html> element. | |
removeClass = function (className) { | |
if (hasClass(className)) { | |
documentElement.className = documentElement.className.replace(" " + className, ""); | |
} | |
}; | |
// HTML Element Handling | |
// --------------------- | |
// Insert the appropriate CSS class based on the _user_agent. | |
if (device.ios()) { | |
if (device.ipad()) { | |
addClass("ios ipad tablet"); | |
} else if (device.iphone()) { | |
addClass("ios iphone mobile"); | |
} else if (device.ipod()) { | |
addClass("ios ipod mobile"); | |
} | |
} else if (device.android()) { | |
if (device.androidTablet()) { | |
addClass("android tablet"); | |
} else { | |
addClass("android mobile"); | |
} | |
} else if (device.blackberry()) { | |
if (device.blackberryTablet()) { | |
addClass("blackberry tablet"); | |
} else { | |
addClass("blackberry mobile"); | |
} | |
} else if (device.windows()) { | |
if (device.windowsTablet()) { | |
addClass("windows tablet"); | |
} else if (device.windowsPhone()) { | |
addClass("windows mobile"); | |
} else { | |
addClass("desktop"); | |
} | |
} else if (device.fxos()) { | |
if (device.fxosTablet()) { | |
addClass("fxos tablet"); | |
} else { | |
addClass("fxos mobile"); | |
} | |
} else if (device.meego()) { | |
addClass("meego mobile"); | |
} else if (device.nodeWebkit()) { | |
addClass("node-webkit"); | |
} else { | |
addClass("desktop"); | |
} | |
if (device.cordova()) { | |
addClass("cordova"); | |
} | |
// Orientation Handling | |
// -------------------- | |
// Handle device orientation changes. | |
handleOrientation = function () { | |
if (device.landscape()) { | |
removeClass("portrait"); | |
addClass("landscape"); | |
} else { | |
removeClass("landscape"); | |
addClass("portrait"); | |
} | |
return; | |
}; | |
// Detect whether device supports orientationchange event, | |
// otherwise fall back to the resize event. | |
if (window.hasOwnProperty("onorientationchange")) { | |
orientationEvent = "orientationchange"; | |
} else { | |
orientationEvent = "resize"; | |
} | |
// Listen for changes in orientation. | |
if (window.addEventListener) { | |
window.addEventListener(orientationEvent, handleOrientation, false); | |
} else if (window.attachEvent) { | |
window.attachEvent(orientationEvent, handleOrientation); | |
} else { | |
window[orientationEvent] = handleOrientation; | |
} | |
handleOrientation(); | |
module.exports = device; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment