You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
304 lines
7.2 KiB
304 lines
7.2 KiB
7 years ago
|
// 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/
|
||
|
|
||
|
(function() {
|
||
|
|
||
|
var 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 !device.windows() && find('iphone');
|
||
|
};
|
||
|
|
||
|
device.ipod = function () {
|
||
|
return find('ipod');
|
||
|
};
|
||
|
|
||
|
device.ipad = function () {
|
||
|
return find('ipad');
|
||
|
};
|
||
|
|
||
|
device.android = function () {
|
||
|
return !device.windows() && 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.television = function() {
|
||
|
var i, tvString;
|
||
|
|
||
|
television = [
|
||
|
"googletv",
|
||
|
"viera",
|
||
|
"smarttv",
|
||
|
"internet.tv",
|
||
|
"netcast",
|
||
|
"nettv",
|
||
|
"appletv",
|
||
|
"boxee",
|
||
|
"kylo",
|
||
|
"roku",
|
||
|
"dlnadoc",
|
||
|
"roku",
|
||
|
"pov_tv",
|
||
|
"hbbtv",
|
||
|
"ce-html"
|
||
|
];
|
||
|
|
||
|
i = 0;
|
||
|
while (i < television.length) {
|
||
|
if (find(television[i])) {
|
||
|
return true;
|
||
|
}
|
||
|
i++;
|
||
|
}
|
||
|
return false;
|
||
|
};
|
||
|
|
||
|
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) {
|
||
|
var currentClassNames = null;
|
||
|
if (!hasClass(className)) {
|
||
|
currentClassNames = documentElement.className.replace(/^\s+|\s+$/g, '');
|
||
|
documentElement.className = currentClassNames + " " + 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 if (device.television()) {
|
||
|
addClass("television");
|
||
|
} else if (device.desktop()) {
|
||
|
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 (Object.prototype.hasOwnProperty.call(window, "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();
|
||
|
|
||
|
if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {
|
||
|
define(function() {
|
||
|
return device;
|
||
|
});
|
||
|
} else if (typeof module !== 'undefined' && module.exports) {
|
||
|
module.exports = device;
|
||
|
} else {
|
||
|
window.device = device;
|
||
|
}
|
||
|
|
||
|
}).call(this);
|