Skip to content

Instantly share code, notes, and snippets.

@matthewhudson
Last active December 21, 2018 16:08
Show Gist options
  • Save matthewhudson/c2e86912a047880e8293 to your computer and use it in GitHub Desktop.
Save matthewhudson/c2e86912a047880e8293 to your computer and use it in GitHub Desktop.
First pass at a device.js refactor from CoffeeScript to JavaScript
/*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