Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

platform

Package Overview
Dependencies
Maintainers
3
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

platform - npm Package Compare versions

Comparing version 1.0.0 to 1.1.0

2

LICENSE.txt

@@ -1,2 +0,2 @@

Copyright 2011-2012 John-David Dalton <http://allyoucanleet.com/>
Copyright 2011-2014 John-David Dalton <http://allyoucanleet.com/>

@@ -3,0 +3,0 @@ Permission is hereby granted, free of charge, to any person obtaining

{
"name": "platform",
"version": "1.0.0",
"version": "1.1.0",
"description": "A platform detection library that works on nearly all JavaScript platforms.",
"homepage": "https://github.com/bestiejs/platform.js",
"main": "platform",
"keywords": [
"environment",
"platform",
"ua",
"useragent"
"license": "MIT",
"main": "platform.js",
"keywords": ["environment", "platform", "ua", "useragent"],
"author": "John-David Dalton <john.david.dalton@gmail.com> (http://allyoucanleet.com/)",
"contributors": [
"John-David Dalton <john.david.dalton@gmail.com> (http://allyoucanleet.com/)",
"Benjamin Tan <demoneaux@gmail.com> (http://d10.github.io/)",
"Mathias Bynens <mathias@qiwi.be> (http://mathiasbynens.be/)"
],
"licenses": [
{
"type": "MIT",
"url": "http://mths.be/mit"
}
"bugs": "https://github.com/bestiejs/platform.js/issues",
"repository": "bestiejs/platform.js",
"scripts": { "test": "echo \"See the repository CONTRIBUTING.md for testing instructions.\"" },
"engines": ["node", "rhino"],
"files": [
"LICENSE.txt",
"platform.js"
],
"author": {
"name": "John-David Dalton",
"email": "john@fusejs.com",
"web": "http://allyoucanleet.com/"
},
"maintainers": [
{
"name": "John-David Dalton",
"email": "john.david.dalton@gmail.com",
"web": "http://allyoucanleet.com/"
},
{
"name": "Mathias Bynens",
"email": "mathias@qiwi.be",
"web": "http://mathiasbynens.be/"
}
],
"bugs": {
"url": "https://github.com/bestiejs/platform.js/issues"
},
"repository": {
"type": "git",
"url": "https://github.com/bestiejs/platform.js.git"
},
"engines": [
"node",
"rhino"
],
"directories": {
"doc": "./doc",
"test": "./test"
"jam": {
"main": "platform.js",
"include": [
"LICENSE.txt",
"platform.js"
]
}
}
}
/*!
* Platform.js v1.0.0 <http://mths.be/platform>
* Copyright 2010-2012 John-David Dalton <http://allyoucanleet.com/>
* Platform.js v1.1.0 <http://mths.be/platform>
* Copyright 2010-2014 John-David Dalton <http://allyoucanleet.com/>
* Available under MIT license <http://mths.be/mit>
*/
;(function(window) {
;(function() {
'use strict';
/** Backup possible window/global object */
var oldWin = window;
/** Used to determine if values are of the language type Object */
var objectTypes = {
'function': true,
'object': true
};
/** Detect free variable `exports` */
var freeExports = typeof exports == 'object' && exports;
/** Used as a reference to the global object */
var root = (objectTypes[typeof window] && window) || this;
/** Detect free variable `global` */
var freeGlobal = typeof global == 'object' && global &&
(global == global.global ? (window = global) : global);
/** Backup possible global object */
var oldRoot = root;
/** Opera regexp */
var reOpera = /Opera/;
/** Detect free variable `exports` */
var freeExports = objectTypes[typeof exports] && exports;
/** Used to resolve a value's internal [[Class]] */
var toString = {}.toString;
/** Detect free variable `module` */
var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
/** Detect Java environment */
var java = /Java/.test(getClassOf(window.java)) && window.java;
/** Detect free variable `global` from Node.js or Browserified code and use it as `root` */
var freeGlobal = freeExports && freeModule && typeof global == 'object' && global;
if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) {
root = freeGlobal;
}
/** A character to represent alpha */
var alpha = java ? 'a' : '\u03b1';
/** A character to represent beta */
var beta = java ? 'b' : '\u03b2';
/** Browser document object */
var doc = window.document || {};
/** Used to check for own properties of an object */
var hasOwnProperty = {}.hasOwnProperty;
/** Browser navigator object */
var nav = window.navigator || {};
/**
* Detect Opera browser
* http://www.howtocreate.co.uk/operaStuff/operaObject.html
* http://dev.opera.com/articles/view/opera-mini-web-content-authoring-guidelines/#operamini
* Used as the maximum length of an array-like object.
* See the [ES6 spec](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength)
* for more details.
*/
var opera = window.operamini || window.opera;
var maxSafeInteger = Math.pow(2, 53) - 1;
/** Opera [[Class]] */
var operaClass = reOpera.test(operaClass = getClassOf(opera)) ? operaClass : (opera = null);
/** Opera regexp */
var reOpera = /Opera/;

@@ -56,5 +46,11 @@ /** Possible global object */

/** Browser user agent string */
var userAgent = nav.userAgent || '';
/** Used for native method references */
var objectProto = Object.prototype;
/** Used to check for own properties of an object */
var hasOwnProperty = objectProto.hasOwnProperty;
/** Used to resolve the internal `[[Class]]` of values */
var toString = objectProto.toString;
/*--------------------------------------------------------------------------*/

@@ -66,4 +62,4 @@

* @private
* @param {String} string The string to capitalize.
* @returns {String} The capitalized string.
* @param {string} string The string to capitalize.
* @returns {string} The capitalized string.
*/

@@ -84,5 +80,5 @@ function capitalize(string) {

var index = -1,
length = object.length;
length = object ? object.length : 0;
if (length == length >>> 0) {
if (typeof length == 'number' && length > -1 && length <= maxSafeInteger) {
while (++index < length) {

@@ -100,4 +96,4 @@ callback(object[index], index, object);

* @private
* @param {String} string The string to format.
* @returns {String} The formatted string.
* @param {string} string The string to format.
* @returns {string} The formatted string.
*/

@@ -120,3 +116,5 @@ function format(string) {

for (var key in object) {
hasKey(object, key) && callback(object[key], key, object);
if (hasOwnProperty.call(object, key)) {
callback(object[key], key, object);
}
}

@@ -129,4 +127,4 @@ }

* @private
* @param {Mixed} value The value.
* @returns {String} The [[Class]].
* @param {*} value The value.
* @returns {string} The [[Class]].
*/

@@ -140,44 +138,10 @@ function getClassOf(value) {

/**
* Checks if an object has the specified key as a direct property.
*
* @private
* @param {Object} object The object to check.
* @param {String} key The key to check for.
* @returns {Boolean} Returns `true` if key is a direct property, else `false`.
*/
function hasKey() {
// lazy define for others (not as accurate)
hasKey = function(object, key) {
var parent = object != null && (object.constructor || Object).prototype;
return !!parent && key in Object(object) && !(key in parent && object[key] === parent[key]);
};
// for modern browsers
if (getClassOf(hasOwnProperty) == 'Function') {
hasKey = function(object, key) {
return object != null && hasOwnProperty.call(object, key);
};
}
// for Safari 2
else if ({}.__proto__ == Object.prototype) {
hasKey = function(object, key) {
var result = false;
if (object != null) {
object = Object(object);
object.__proto__ = [object.__proto__, object.__proto__ = null, result = key in object][0];
}
return result;
};
}
return hasKey.apply(this, arguments);
}
/**
* Host objects can return type values that are different from their actual
* data type. The objects we are concerned with usually return non-primitive
* types of object, function, or unknown.
* types of "object", "function", or "unknown".
*
* @private
* @param {Mixed} object The owner of the property.
* @param {String} property The property to check.
* @returns {Boolean} Returns `true` if the property value is a non-primitive, else `false`.
* @param {*} object The owner of the property.
* @param {string} property The property to check.
* @returns {boolean} Returns `true` if the property value is a non-primitive, else `false`.
*/

@@ -191,8 +155,7 @@ function isHostType(object, property) {

/**
* Prepares a string for use in a RegExp constructor by making hyphens and
* spaces optional.
* Prepares a string for use in a `RegExp` by making hyphens and spaces optional.
*
* @private
* @param {String} string The string to qualify.
* @returns {String} The qualified string.
* @param {string} string The string to qualify.
* @returns {string} The qualified string.
*/

@@ -204,3 +167,3 @@ function qualify(string) {

/**
* A bare-bones` Array#reduce` like utility function.
* A bare-bones `Array#reduce` like utility function.
*

@@ -210,4 +173,3 @@ * @private

* @param {Function} callback The function called per iteration.
* @param {Mixed} accumulator Initial value of the accumulator.
* @returns {Mixed} The accumulator.
* @returns {*} The accumulated result.
*/

@@ -226,4 +188,4 @@ function reduce(array, callback) {

* @private
* @param {String} string The string to trim.
* @returns {String} The trimmed string.
* @param {string} string The string to trim.
* @returns {string} The trimmed string.
*/

@@ -240,3 +202,4 @@ function trim(string) {

* @memberOf platform
* @param {String} [ua = navigator.userAgent] The user agent string.
* @param {Object|string} [ua=navigator.userAgent] The user agent string or
* context object.
* @returns {Object} A platform object.

@@ -246,4 +209,66 @@ */

/** The environment context object */
var context = root;
/** Used to flag when a custom context is provided */
var isCustomContext = ua && typeof ua == 'object' && getClassOf(ua) != 'String';
// juggle arguments
if (isCustomContext) {
context = ua;
ua = null;
}
/** Browser navigator object */
var nav = context.navigator || {};
/** Browser user agent string */
var userAgent = nav.userAgent || '';
ua || (ua = userAgent);
/** Used to flag when `thisBinding` is the [ModuleScope] */
var isModuleScope = isCustomContext || thisBinding == oldRoot;
/** Used to detect if browser is like Chrome */
var likeChrome = isCustomContext
? !!nav.likeChrome
: /\bChrome\b/.test(ua) && !/internal|\n/i.test(toString.toString());
/** Internal [[Class]] value shortcuts */
var objectClass = 'Object',
airRuntimeClass = isCustomContext ? objectClass : 'ScriptBridgingProxyObject',
enviroClass = isCustomContext ? objectClass : 'Environment',
javaClass = (isCustomContext && context.java) ? 'JavaPackage' : getClassOf(context.java),
phantomClass = isCustomContext ? objectClass : 'RuntimeObject';
/** Detect Java environment */
var java = /Java/.test(javaClass) && context.java;
/** Detect Rhino */
var rhino = java && getClassOf(context.environment) == enviroClass;
/** A character to represent alpha */
var alpha = java ? 'a' : '\u03b1';
/** A character to represent beta */
var beta = java ? 'b' : '\u03b2';
/** Browser document object */
var doc = context.document || {};
/**
* Detect Opera browser
* http://www.howtocreate.co.uk/operaStuff/operaObject.html
* http://dev.opera.com/articles/view/opera-mini-web-content-authoring-guidelines/#operamini
*/
var opera = context.operamini || context.opera;
/** Opera [[Class]] */
var operaClass = reOpera.test(operaClass = (isCustomContext && opera) ? opera['[[Class]]'] : getClassOf(opera))
? operaClass
: (opera = null);
/*------------------------------------------------------------------------*/
/** Temporary variable used over the script's lifetime */

@@ -292,3 +317,3 @@ var data;

'Iceweasel',
'Iron',
{ 'label': 'SRWare Iron', 'pattern': 'Iron' },
'K-Meleon',

@@ -313,2 +338,3 @@ 'Konqueror',

'Opera',
{ 'label': 'Opera', 'pattern': 'OPR' },
'Chrome',

@@ -323,5 +349,8 @@ { 'label': 'Chrome Mobile', 'pattern': '(?:CriOS|CrMo)' },

var product = getProduct([
{ 'label': 'BlackBerry', 'pattern': 'BB10' },
'BlackBerry',
{ 'label': 'Galaxy S', 'pattern': 'GT-I9000' },
{ 'label': 'Galaxy S2', 'pattern': 'GT-I9100' },
{ 'label': 'Galaxy S3', 'pattern': 'GT-I9300' },
{ 'label': 'Galaxy S4', 'pattern': 'GT-I9500' },
'Google TV',

@@ -335,5 +364,11 @@ 'iPad',

'PlayBook',
'PlayStation 4',
'PlayStation 3',
'PlayStation Vita',
'TouchPad',
'Transformer',
{ 'label': 'Wii U', 'pattern': 'WiiU' },
'Wii',
'Xbox One',
{ 'label': 'Xbox 360', 'pattern': 'Xbox' },
'Xoom'

@@ -351,7 +386,10 @@ ]);

'HP': { 'TouchPad': 1 },
'HTC': { },
'LG': { },
'Microsoft': { 'Xbox': 1, 'Xbox One': 1 },
'Motorola': { 'Xoom': 1 },
'Nintendo': { 'Wii U': 1, 'Wii': 1 },
'Nokia': { },
'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1 },
'Sony': { 'PlayStation Vita': 1 }
'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1, 'Galaxy S3': 1, 'Galaxy S4': 1 },
'Sony': { 'PlayStation 4': 1, 'PlayStation 3': 1, 'PlayStation Vita': 1 }
});

@@ -395,3 +433,3 @@

* @param {Array} guesses An array of guesses.
* @returns {String|Null} The detected layout engine.
* @returns {null|string} The detected layout engine.
*/

@@ -410,4 +448,4 @@ function getLayout(guesses) {

* @private
* @param {Array} guesses An array of guesses.
* @returns {String|Null} The detected manufacturer.
* @param {Object} guesses An object of guesses.
* @returns {null|string} The detected manufacturer.
*/

@@ -420,4 +458,4 @@ function getManufacturer(guesses) {

value[0/*Opera 9.25 fix*/, /^[a-z]+(?: +[a-z]+\b)*/i.exec(product)] ||
RegExp('\\b' + (key.pattern || qualify(key)) + '(?:\\b|\\w*\\d)', 'i').exec(ua)
) && (key.label || key);
RegExp('\\b' + qualify(key) + '(?:\\b|\\w*\\d)', 'i').exec(ua)
) && key;
});

@@ -431,3 +469,3 @@ }

* @param {Array} guesses An array of guesses.
* @returns {String|Null} The detected browser name.
* @returns {null|string} The detected browser name.
*/

@@ -447,3 +485,3 @@ function getName(guesses) {

* @param {Array} guesses An array of guesses.
* @returns {String|Null} The detected OS name.
* @returns {null|string} The detected OS name.
*/

@@ -454,3 +492,4 @@ function getOS(guesses) {

if (!result && (result =
RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua))) {
RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua)
)) {
// platform tokens defined at

@@ -460,2 +499,3 @@ // http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx

data = {
'6.3': '8.1',
'6.2': '8',

@@ -484,2 +524,3 @@ '6.1': 'Server 2008 R2 / 7',

.replace(/(OS X) [^ \d]+/i, '$1')
.replace(/Mac (OS X)/, '$1')
.replace(/\/(\d)/, ' $1')

@@ -500,3 +541,3 @@ .replace(/_/g, '.')

* @param {Array} guesses An array of guesses.
* @returns {String|Null} The detected product name.
* @returns {null|string} The detected product name.
*/

@@ -511,3 +552,3 @@ function getProduct(guesses) {

// split by forward slash and append product version if needed
if ((result = String(guess.label || result).split('/'))[1] && !/[\d.]+/.test(result[0])) {
if ((result = String((guess.label && !RegExp(pattern, 'i').test(guess.label)) ? guess.label : result).split('/'))[1] && !/[\d.]+/.test(result[0])) {
result[0] += ' ' + result[1];

@@ -520,3 +561,3 @@ }

.replace(RegExp('; *(?:' + guess + '[_-])?', 'i'), ' ')
.replace(RegExp('(' + guess + ')(\\w)', 'i'), '$1 $2'));
.replace(RegExp('(' + guess + ')[-_.]?(\\w)', 'i'), '$1 $2'));
}

@@ -532,3 +573,3 @@ return result;

* @param {Array} patterns An array of UA patterns.
* @returns {String|Null} The detected version.
* @returns {null|string} The detected version.
*/

@@ -542,4 +583,2 @@ function getVersion(patterns) {

/*------------------------------------------------------------------------*/
/**

@@ -550,3 +589,3 @@ * Returns `platform.description` when the platform object is coerced to a string.

* @memberOf platform
* @returns {String} Returns `platform.description` if available, else an empty string.
* @returns {string} Returns `platform.description` if available, else an empty string.
*/

@@ -587,3 +626,3 @@ function toStringPlatform() {

else if (manufacturer && manufacturer != 'Google' &&
/Chrome|Vita/.test(name + ';' + product)) {
((/Chrome/.test(name) && !/Mobile Safari/.test(ua)) || /Vita/.test(product))) {
name = 'Android Browser';

@@ -593,3 +632,3 @@ os = /Android/.test(os) ? os : 'Android';

// detect false positives for Firefox/Safari
else if (!name || (data = !/\bMinefield\b/i.test(ua) && /Firefox|Safari/.exec(name))) {
else if (!name || (data = !/\bMinefield\b|\(Android;/i.test(ua) && /Firefox|Safari/.exec(name))) {
// escape the `/` for Firefox 1

@@ -606,6 +645,13 @@ if (name && !product && /[\/,]|^[^(]+?\)/.test(ua.slice(ua.indexOf(data + '/') + 8))) {

}
// detect Firefox OS
if ((data = /\((Mobile|Tablet).*?Firefox/i.exec(ua)) && data[1]) {
os = 'Firefox OS';
if (!product) {
product = data[1];
}
}
// detect non-Opera versions (order is important)
if (!version) {
version = getVersion([
'(?:Cloud9|CriOS|CrMo|Opera ?Mini|Raven|Silk(?!/[\\d.]+$))',
'(?:Cloud9|CriOS|CrMo|Iron|Opera ?Mini|OPR|Raven|Silk(?!/[\\d.]+$))',
'Version',

@@ -619,8 +665,18 @@ qualify(name),

layout = ['WebKit'];
} else if (data =
/Opera/.test(name) && 'Presto' ||
/\b(?:Midori|Nook|Safari)\b/i.test(ua) && 'WebKit' ||
!layout && /\bMSIE\b/i.test(ua) && (/^Mac/.test(os) ? 'Tasman' : 'Trident')) {
} else if ((data =
/Opera/.test(name) && (/OPR/.test(ua) ? 'Blink' : 'Presto') ||
/\b(?:Midori|Nook|Safari)\b/i.test(ua) && 'WebKit' ||
!layout && /\bMSIE\b/i.test(ua) && (os == 'Mac OS' ? 'Tasman' : 'Trident')
)) {
layout = [data];
}
// detect NetFront on PlayStation
else if (/PlayStation(?! Vita)/i.test(name) && layout == 'WebKit') {
layout = ['NetFront'];
}
// detect IE 11 and above
if (!name && layout == 'Trident') {
name = 'IE';
version = (/\brv:([\d.]+)/.exec(ua) || 0)[1];
}
// leverage environment features

@@ -630,3 +686,3 @@ if (useFeatures) {

// Rhino has a global function while others have a global object
if (isHostType(window, 'global')) {
if (isHostType(context, 'global')) {
if (java) {

@@ -637,16 +693,16 @@ data = java.lang.System;

}
if (typeof exports == 'object' && exports) {
// if `thisBinding` is the [ModuleScope]
if (thisBinding == oldWin && typeof system == 'object' && (data = [system])[0]) {
if (isHostType(context, 'exports')) {
if (isModuleScope && isHostType(context, 'system') && (data = [context.system])[0]) {
os || (os = data[0].os || null);
try {
data[1] = require('ringo/engine').version;
data[1] = (data[1] = context.require) && data[1]('ringo/engine').version;
version = data[1].join('.');
name = 'RingoJS';
} catch(e) {
if (data[0].global == freeGlobal) {
if (data[0].global.system == context.system) {
name = 'Narwhal';
}
}
} else if (typeof process == 'object' && (data = process)) {
}
else if (typeof context.process == 'object' && (data = context.process)) {
name = 'Node.js';

@@ -657,3 +713,7 @@ arch = data.arch;

}
} else if (getClassOf(window.environment) == 'Environment') {
else if (rhino) {
name = 'Rhino';
}
}
else if (rhino) {
name = 'Rhino';

@@ -663,3 +723,3 @@ }

// detect Adobe AIR
else if (getClassOf(data = window.runtime) == 'ScriptBridgingProxyObject') {
else if (getClassOf((data = context.runtime)) == airRuntimeClass) {
name = 'Adobe AIR';

@@ -669,3 +729,3 @@ os = data.flash.system.Capabilities.os;

// detect PhantomJS
else if (getClassOf(data = window.phantom) == 'RuntimeObject') {
else if (getClassOf((data = context.phantom)) == phantomClass) {
name = 'PhantomJS';

@@ -681,3 +741,3 @@ version = (data = data.version || null) && (data.major + '.' + data.minor + '.' + data.patch);

description.push('IE ' + version[1] + ' mode');
layout[1] = '';
layout && (layout[1] = '');
version[1] = data;

@@ -691,5 +751,6 @@ }

if (version && (data =
/(?:[ab]|dp|pre|[ab]\d+pre)(?:\d+\+?)?$/i.exec(version) ||
/(?:alpha|beta)(?: ?\d)?/i.exec(ua + ';' + (useFeatures && nav.appMinorVersion)) ||
/\bMinefield\b/i.test(ua) && 'a')) {
/(?:[ab]|dp|pre|[ab]\d+pre)(?:\d+\+?)?$/i.exec(version) ||
/(?:alpha|beta)(?: ?\d)?/i.exec(ua + ';' + (useFeatures && nav.appMinorVersion)) ||
/\bMinefield\b/i.test(ua) && 'a'
)) {
prerelease = /b/i.test(data) ? 'beta' : 'alpha';

@@ -699,4 +760,4 @@ version = version.replace(RegExp(data + '\\+?$'), '') +

}
// rename code name "Fennec"
if (name == 'Fennec') {
// detect Firefox Mobile
if (name == 'Fennec' || name == 'Firefox' && /Android|Firefox OS/.test(os)) {
name = 'Firefox Mobile';

@@ -720,8 +781,15 @@ }

else if (name == 'IE' && (data = (/; *(?:XBLWP|ZuneWP)(\d+)/i.exec(ua) || 0)[1])) {
name += ' Mobile';
os = 'Windows Phone OS ' + data + '.x';
description.unshift('desktop mode');
name += ' Mobile';
os = 'Windows Phone OS ' + data + '.x';
description.unshift('desktop mode');
}
// detect Xbox 360 and Xbox One
else if (/Xbox/i.test(product)) {
os = null;
if (product == 'Xbox 360' && /IEMobile/.test(ua)) {
description.unshift('mobile mode');
}
}
// add mobile postfix
else if ((name == 'IE' || name && !product && !/Browser|Mobi/.test(name)) &&
else if ((name == 'Chrome' || name == 'IE' || name && !product && !/Browser|Mobi/.test(name)) &&
(os == 'Windows CE' || /Mobi/i.test(ua))) {

@@ -731,3 +799,3 @@ name += ' Mobile';

// detect IE platform preview
else if (name == 'IE' && useFeatures && typeof external == 'object' && !external) {
else if (name == 'IE' && useFeatures && context.external === null) {
description.unshift('platform preview');

@@ -737,6 +805,8 @@ }

// http://docs.blackberry.com/en/developers/deliverables/18169/HTTP_headers_sent_by_BB_Browser_1234911_11.jsp
else if (/BlackBerry/.test(product) && (data =
(RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] ||
version)) {
os = 'Device Software ' + data;
else if ((/BlackBerry/.test(product) || /BB10/.test(ua)) && (data =
(RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] ||
version
)) {
data = [data, /BB10/.test(ua)];
os = (data[1] ? (product = null, manufacturer = 'BlackBerry') : 'Device Software') + ' ' + data[0];
version = null;

@@ -747,11 +817,13 @@ }

else if (this != forOwn && (
(useFeatures && opera) ||
(/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) ||
(name == 'Firefox' && /OS X (?:\d+\.){2,}/.test(os)) ||
(name == 'IE' && (
(os && !/^Win/.test(os) && version > 5.5) ||
/Windows XP/.test(os) && version > 8 ||
version == 8 && !/Trident/.test(ua)
))
) && !reOpera.test(data = parse.call(forOwn, ua.replace(reOpera, '') + ';')) && data.name) {
product != 'Wii' && (
(useFeatures && opera) ||
(/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) ||
(name == 'Firefox' && /OS X (?:\d+\.){2,}/.test(os)) ||
(name == 'IE' && (
(os && !/^Win/.test(os) && version > 5.5) ||
/Windows XP/.test(os) && version > 8 ||
version == 8 && !/Trident/.test(ua)
))
)
) && !reOpera.test((data = parse.call(forOwn, ua.replace(reOpera, '') + ';'))) && data.name) {

@@ -797,19 +869,22 @@ // when "indentifying", the UA contains both Opera and the other browser's name

else if (version == data[1] ||
version == (/\bSafari\/([\d.]+\+?)/i.exec(ua) || 0)[1]) {
version == (data[2] = (/\bSafari\/([\d.]+\+?)/i.exec(ua) || 0)[1])) {
version = null;
}
// use the full Chrome version when available
data = [data[0], (/\bChrome\/([\d.]+)/i.exec(ua) || 0)[1]];
data[1] = (/\bChrome\/([\d.]+)/i.exec(ua) || 0)[1];
// detect Blink layout engine
if (data[0] == 537.36 && data[2] == 537.36 && parseFloat(data[1]) >= 28) {
layout = ['Blink'];
}
// detect JavaScriptCore
// http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androi
if (!useFeatures || (/internal|\n/i.test(toString.toString()) && !data[1])) {
layout[1] = 'like Safari';
data = (data = data[0], data < 400 ? 1 : data < 500 ? 2 : data < 526 ? 3 : data < 533 ? 4 : data < 534 ? '4+' : data < 535 ? 5 : '5');
if (!useFeatures || (!likeChrome && !data[1])) {
layout && (layout[1] = 'like Safari');
data = (data = data[0], data < 400 ? 1 : data < 500 ? 2 : data < 526 ? 3 : data < 533 ? 4 : data < 534 ? '4+' : data < 535 ? 5 : data < 537 ? 6 : data < 538 ? 7 : '7');
} else {
layout[1] = 'like Chrome';
data = data[1] || (data = data[0], data < 530 ? 1 : data < 532 ? 2 : data < 532.05 ? 3 : data < 533 ? 4 : data < 534.03 ? 5 : data < 534.07 ? 6 : data < 534.10 ? 7 : data < 534.13 ? 8 : data < 534.16 ? 9 : data < 534.24 ? 10 : data < 534.30 ? 11 : data < 535.01 ? 12 : data < 535.02 ? '13+' : data < 535.07 ? 15 : data < 535.11 ? 16 : data < 535.19 ? 17 : data < 536.05 ? 18 : data < 536.10 ? 19 : data < 537.01 ? 20 : '21');
layout && (layout[1] = 'like Chrome');
data = data[1] || (data = data[0], data < 530 ? 1 : data < 532 ? 2 : data < 532.05 ? 3 : data < 533 ? 4 : data < 534.03 ? 5 : data < 534.07 ? 6 : data < 534.10 ? 7 : data < 534.13 ? 8 : data < 534.16 ? 9 : data < 534.24 ? 10 : data < 534.30 ? 11 : data < 535.01 ? 12 : data < 535.02 ? '13+' : data < 535.07 ? 15 : data < 535.11 ? 16 : data < 535.19 ? 17 : data < 536.05 ? 18 : data < 536.10 ? 19 : data < 537.01 ? 20 : data < 537.11 ? '21+' : data < 537.13 ? 23 : data < 537.18 ? 24 : data < 537.24 ? 25 : data < 537.36 ? 26 : layout != 'Blink' ? '27' : '28');
}
// add the postfix of ".x" or "+" for approximate versions
layout[1] += ' ' + (data += typeof data == 'number' ? '.x' : /[.+]/.test(data) ? '' : '+');
layout && (layout[1] += ' ' + (data += typeof data == 'number' ? '.x' : /[.+]/.test(data) ? '' : '+'));
// obscure version for some Safari 1-2 releases

@@ -832,3 +907,3 @@ if (name == 'Safari' && (!version || parseInt(version) > 45)) {

// detect Chrome desktop mode
else if (name == 'Safari' && /Chrome/.exec(layout[1])) {
else if (name == 'Safari' && /Chrome/.exec(layout && layout[1])) {
description.unshift('desktop mode');

@@ -838,3 +913,3 @@ name = 'Chrome Mobile';

if (/Mac OS X/.test(os)) {
if (/OS X/.test(os)) {
manufacturer = 'Apple';

@@ -847,3 +922,3 @@ os = 'iOS 4.3+';

// strip incorrect OS versions
if (version && version.indexOf(data = /[\d.]+$/.exec(os)) == 0 &&
if (version && version.indexOf((data = /[\d.]+$/.exec(os))) == 0 &&
ua.indexOf('/' + data + '-') > -1) {

@@ -885,6 +960,6 @@ os = trim(os.replace(data, ''));

// add browser/OS architecture
if ((data = / (?:AMD|IA|Win|WOW|x86_|x)64\b/i.exec(arch)) && !/\bi686\b/i.test(arch)) {
if ((data = /\b(?:AMD|IA|Win|WOW|x86_|x)64\b/i.exec(arch)) && !/\bi686\b/i.test(arch)) {
if (os) {
os.architecture = 64;
os.family = os.family.replace(data, '');
os.family = os.family.replace(RegExp(' *' + data), '');
}

@@ -907,119 +982,125 @@ if (name && (/WOW64/i.test(ua) ||

*/
return {
var platform = {};
/**
* The browser/environment version.
*
* @memberOf platform
* @type String|Null
*/
'version': name && version && (description.unshift(version), version),
/**
* The platform description.
*
* @memberOf platform
* @type string|null
*/
platform.description = ua;
/**
* The name of the browser/environment.
*
* @memberOf platform
* @type String|Null
*/
'name': name && (description.unshift(name), name),
/**
* The name of the browser's layout engine.
*
* @memberOf platform
* @type string|null
*/
platform.layout = layout && layout[0];
/**
* The name of the operating system.
*
* @memberOf platform
* @type Object
*/
'os': os
? (name &&
!(os == String(os).split(' ')[0] && (os == name.split(' ')[0] || product)) &&
description.push(product ? '(' + os + ')' : 'on ' + os), os)
: {
/**
* The name of the product's manufacturer.
*
* @memberOf platform
* @type string|null
*/
platform.manufacturer = manufacturer;
/**
* The CPU architecture the OS is built for.
*
* @memberOf platform.os
* @type String|Null
*/
'architecture': null,
/**
* The name of the browser/environment.
*
* @memberOf platform
* @type string|null
*/
platform.name = name;
/**
* The family of the OS.
*
* @memberOf platform.os
* @type String|Null
*/
'family': null,
/**
* The alpha/beta release indicator.
*
* @memberOf platform
* @type string|null
*/
platform.prerelease = prerelease;
/**
* The version of the OS.
*
* @memberOf platform.os
* @type String|Null
*/
'version': null,
/**
* The name of the product hosting the browser.
*
* @memberOf platform
* @type string|null
*/
platform.product = product;
/**
* Returns the OS string.
*
* @memberOf platform.os
* @returns {String} The OS string.
*/
'toString': function() { return 'null'; }
},
/**
* The browser's user agent string.
*
* @memberOf platform
* @type string|null
*/
platform.ua = ua;
/**
* The platform description.
*
* @memberOf platform
* @type String|Null
*/
'description': description.length ? description.join(' ') : ua,
/**
* The browser/environment version.
*
* @memberOf platform
* @type string|null
*/
platform.version = name && version;
/**
* The name of the browser layout engine.
*
* @memberOf platform
* @type String|Null
*/
'layout': layout && layout[0],
/**
* The name of the operating system.
*
* @memberOf platform
* @type Object
*/
platform.os = os || {
/**
* The name of the product's manufacturer.
* The CPU architecture the OS is built for.
*
* @memberOf platform
* @type String|Null
* @memberOf platform.os
* @type number|null
*/
'manufacturer': manufacturer,
'architecture': null,
/**
* The alpha/beta release indicator.
* The family of the OS.
*
* @memberOf platform
* @type String|Null
* @memberOf platform.os
* @type string|null
*/
'prerelease': prerelease,
'family': null,
/**
* The name of the product hosting the browser.
* The version of the OS.
*
* @memberOf platform
* @type String|Null
* @memberOf platform.os
* @type string|null
*/
'product': product,
'version': null,
/**
* The browser's user agent string.
* Returns the OS string.
*
* @memberOf platform
* @type String|Null
* @memberOf platform.os
* @returns {string} The OS string.
*/
'ua': ua,
'toString': function() { return 'null'; }
};
// parses a user agent string into a platform object
'parse': parse,
platform.parse = parse;
platform.toString = toStringPlatform;
// returns the platform description
'toString': toStringPlatform
};
if (platform.version) {
description.unshift(version);
}
if (platform.name) {
description.unshift(name);
}
if (os && name && !(os == String(os).split(' ')[0] && (os == name.split(' ')[0] || product))) {
description.push(product ? '(' + os + ')' : 'on ' + os);
}
if (description.length) {
platform.description = description.join(' ');
}
return platform;
}

@@ -1029,4 +1110,4 @@

// expose platform
// some AMD build optimizers, like r.js, check for specific condition patterns like the following:
// export platform
// some AMD build optimizers, like r.js, check for condition patterns like the following:
if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {

@@ -1039,4 +1120,4 @@ // define as an anonymous module so, through path mapping, it can be aliased

// check for `exports` after `define` in case a build optimizer adds an `exports` object
else if (freeExports) {
// in Narwhal, Node.js, or RingoJS
else if (freeExports && freeModule) {
// in Narwhal, Node.js, Rhino -require, or RingoJS
forOwn(parse(), function(value, key) {

@@ -1048,6 +1129,4 @@ freeExports[key] = value;

else {
// use square bracket notation so Closure Compiler won't munge `platform`
// http://code.google.com/closure/compiler/docs/api-tutorial3.html#export
window['platform'] = parse();
root.platform = parse();
}
}(this));
}.call(this));

@@ -1,2 +0,2 @@

# Platform.js <sup>v1.0.0</sup>
# Platform.js <sup>v1.1.0</sup>

@@ -11,3 +11,3 @@ A platform detection library that works on nearly all JavaScript platforms<sup><a name="fnref1" href="#fn1">1</a></sup>.

Platform.js is part of the BestieJS *"Best in Class"* module collection. This means we promote solid browser/environment support, ES5 precedents, unit testing, and plenty of documentation.
Platform.js is part of the BestieJS *"Best in Class"* module collection. This means we promote solid browser/environment support, ES5+ precedents, unit testing, and plenty of documentation.

@@ -18,2 +18,3 @@ ## Documentation

The full changelog for this release is available on our [wiki](https://github.com/bestiejs/platform.js/wiki/Changelog).<br>
For a list of upcoming features, check out our [roadmap](https://github.com/bestiejs/platform.js/wiki/Roadmap).

@@ -23,33 +24,33 @@

Platform.js has been tested in at least Adobe AIR 3.1, Chrome 5-21, Firefox 1.5-13, IE 6-9, Opera 9.25-12.01, Safari 3-6, Node.js 0.8.6, Narwhal 0.3.2, RingoJS 0.8, and Rhino 1.7RC5.
Tested in Chrome 34-35, Firefox 28-29, IE 6-11, Opera 20-21, Safari 5-7, Node.js 0.6.21~0.10.28, Narwhal 0.3.2, PhantomJS 1.9.2, RingoJS 0.9, & Rhino 1.7RC5.
## Installation and usage
In a browser or Adobe AIR:
In a browser:
~~~ html
```html
<script src="platform.js"></script>
~~~
```
Via [npm](http://npmjs.org/):
~~~ bash
```bash
npm install platform
~~~
```
In [Node.js](http://nodejs.org/) and [RingoJS](http://ringojs.org/):
~~~ js
```js
var platform = require('platform');
~~~
```
In [Rhino](http://www.mozilla.org/rhino/):
~~~ js
```js
load('platform.js');
~~~
```
In an AMD loader like [RequireJS](http://requirejs.org/):
~~~ js
```js
require({

@@ -63,7 +64,7 @@ 'paths': {

});
~~~
```
Usage example:
~~~ js
```js
// on IE10 x86 platform preview running in IE7 compatibility mode on Windows 7 64 bit edition

@@ -92,12 +93,14 @@ platform.name; // 'IE'

info.description; // 'Opera 11.52 (identifying as Firefox 4.0) on Mac OS X 10.7.2'
~~~
```
## Author
* [John-David Dalton](http://allyoucanleet.com/)
[![twitter/jdalton](http://gravatar.com/avatar/299a3d891ff1920b69c364d061007043?s=70)](https://twitter.com/jdalton "Follow @jdalton on Twitter")
| [![twitter/jdalton](http://gravatar.com/avatar/299a3d891ff1920b69c364d061007043?s=70)](https://twitter.com/jdalton "Follow @jdalton on Twitter") |
|---|
| [John-David Dalton](http://allyoucanleet.com/) |
## Contributors
* [Mathias Bynens](http://mathiasbynens.be/)
[![twitter/mathias](http://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](https://twitter.com/mathias "Follow @mathias on Twitter")
| [![twitter/demoneaux](http://gravatar.com/avatar/029b19dba521584d83398ada3ecf6131?s=70)](https://twitter.com/demoneaux "Follow @demoneaux on Twitter") | [![twitter/mathias](http://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](https://twitter.com/mathias "Follow @mathias on Twitter") |
|---|---|
| [Benjamin Tan](http://d10.github.io/) | [Mathias Bynens](http://mathiasbynens.be/) |
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc