Update vendor.

This commit is contained in:
John-David Dalton
2014-05-25 23:55:59 -07:00
parent 2e5052a7fa
commit c5237a926d
3 changed files with 311 additions and 243 deletions

View File

@@ -1583,7 +1583,7 @@
var bench = clone._original, var bench = clone._original,
stringable = isStringable(bench.fn), stringable = isStringable(bench.fn),
count = bench.count = clone.count, count = bench.count = clone.count,
decompilable = stringable || (support.decompilation && (_.has(clone, 'setup') || _.has(clone, 'teardown'))), decompilable = stringable || (support.decompilation && (clone.setup !== _.noop || clone.teardown !== _.noop)),
id = bench.id, id = bench.id,
name = bench.name || (typeof id == 'number' ? '<Test #' + id + '>' : id), name = bench.name || (typeof id == 'number' ? '<Test #' + id + '>' : id),
result = 0; result = 0;

View File

@@ -1,63 +1,56 @@
/*! /*!
* Platform.js v1.0.0 <http://mths.be/platform> * Platform.js v1.1.0 <http://mths.be/platform>
* Copyright 2010-2014 John-David Dalton <http://allyoucanleet.com/> * Copyright 2010-2014 John-David Dalton <http://allyoucanleet.com/>
* Available under MIT license <http://mths.be/mit> * Available under MIT license <http://mths.be/mit>
*/ */
;(function(root) { ;(function() {
'use strict'; 'use strict';
/** Used to determine if values are of the language type Object */
var objectTypes = {
'function': true,
'object': true
};
/** Used as a reference to the global object */
var root = (objectTypes[typeof window] && window) || this;
/** Backup possible global object */ /** Backup possible global object */
var oldRoot = root; var oldRoot = root;
/** Detect free variable `exports` */ /** Detect free variable `exports` */
var freeExports = typeof exports == 'object' && exports; var freeExports = objectTypes[typeof exports] && exports;
/** Detect free variable `global` */ /** Detect free variable `module` */
var freeGlobal = typeof global == 'object' && global && var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
(global == global.global ? (root = global) : global);
/** 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;
}
/**
* 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 maxSafeInteger = Math.pow(2, 53) - 1;
/** Opera regexp */ /** Opera regexp */
var reOpera = /Opera/; var reOpera = /Opera/;
/** Used to resolve a value's internal [[Class]] */
var toString = Object.prototype.toString;
/** Detect Java environment */
var java = /Java/.test(getClassOf(root.java)) && root.java;
/** Detect Rhino */
var rhino = java && getClassOf(root.environment) == 'Environment';
/** 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 = root.document || {};
/** Used to check for own properties of an object */
var hasOwnProperty = {}.hasOwnProperty;
/** Browser navigator object */
var nav = root.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
*/
var opera = root.operamini || root.opera;
/** Opera [[Class]] */
var operaClass = reOpera.test(operaClass = getClassOf(opera)) ? operaClass : (opera = null);
/** Possible global object */ /** Possible global object */
var thisBinding = this; var thisBinding = this;
/** Browser user agent string */ /** Used for native method references */
var userAgent = nav.userAgent || ''; 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;
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
@@ -82,9 +75,9 @@
*/ */
function each(object, callback) { function each(object, callback) {
var index = -1, 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) { while (++index < length) {
callback(object[index], index, object); callback(object[index], index, object);
} }
@@ -116,7 +109,9 @@
*/ */
function forOwn(object, callback) { function forOwn(object, callback) {
for (var key in object) { for (var key in object) {
hasKey(object, key) && callback(object[key], key, object); if (hasOwnProperty.call(object, key)) {
callback(object[key], key, object);
}
} }
} }
@@ -133,44 +128,10 @@
: toString.call(value).slice(8, -1); : toString.call(value).slice(8, -1);
} }
/**
* 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 * Host objects can return type values that are different from their actual
* data type. The objects we are concerned with usually return non-primitive * 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 * @private
* @param {*} object The owner of the property. * @param {*} object The owner of the property.
@@ -184,8 +145,7 @@
} }
/** /**
* Prepares a string for use in a RegExp constructor by making hyphens and * Prepares a string for use in a `RegExp` by making hyphens and spaces optional.
* spaces optional.
* *
* @private * @private
* @param {string} string The string to qualify. * @param {string} string The string to qualify.
@@ -196,13 +156,12 @@
} }
/** /**
* A bare-bones` Array#reduce` like utility function. * A bare-bones `Array#reduce` like utility function.
* *
* @private * @private
* @param {Array} array The array to iterate over. * @param {Array} array The array to iterate over.
* @param {Function} callback The function called per iteration. * @param {Function} callback The function called per iteration.
* @param {*} accumulator Initial value of the accumulator. * @returns {*} The accumulated result.
* @returns {*} The accumulator.
*/ */
function reduce(array, callback) { function reduce(array, callback) {
var accumulator = null; var accumulator = null;
@@ -229,13 +188,76 @@
* Creates a new platform object. * Creates a new platform object.
* *
* @memberOf platform * @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. * @returns {Object} A platform object.
*/ */
function parse(ua) { function parse(ua) {
/** 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); 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 */ /** Temporary variable used over the script's lifetime */
var data; var data;
@@ -279,7 +301,7 @@
'GreenBrowser', 'GreenBrowser',
'iCab', 'iCab',
'Iceweasel', 'Iceweasel',
'Iron', { 'label': 'SRWare Iron', 'pattern': 'Iron' },
'K-Meleon', 'K-Meleon',
'Konqueror', 'Konqueror',
'Lunascape', 'Lunascape',
@@ -309,9 +331,12 @@
/* Detectable products (order is important) */ /* Detectable products (order is important) */
var product = getProduct([ var product = getProduct([
{ 'label': 'BlackBerry', 'pattern': 'BB10' },
'BlackBerry', 'BlackBerry',
{ 'label': 'Galaxy S', 'pattern': 'GT-I9000' }, { 'label': 'Galaxy S', 'pattern': 'GT-I9000' },
{ 'label': 'Galaxy S2', 'pattern': 'GT-I9100' }, { 'label': 'Galaxy S2', 'pattern': 'GT-I9100' },
{ 'label': 'Galaxy S3', 'pattern': 'GT-I9300' },
{ 'label': 'Galaxy S4', 'pattern': 'GT-I9500' },
'Google TV', 'Google TV',
'iPad', 'iPad',
'iPod', 'iPod',
@@ -320,9 +345,15 @@
{ 'label': 'Kindle Fire', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, { 'label': 'Kindle Fire', 'pattern': '(?:Cloud9|Silk-Accelerated)' },
'Nook', 'Nook',
'PlayBook', 'PlayBook',
'PlayStation 4',
'PlayStation 3',
'PlayStation Vita', 'PlayStation Vita',
'TouchPad', 'TouchPad',
'Transformer', 'Transformer',
{ 'label': 'Wii U', 'pattern': 'WiiU' },
'Wii',
'Xbox One',
{ 'label': 'Xbox 360', 'pattern': 'Xbox' },
'Xoom' 'Xoom'
]); ]);
@@ -335,11 +366,14 @@
'BlackBerry': { 'PlayBook': 1 }, 'BlackBerry': { 'PlayBook': 1 },
'Google': { 'Google TV': 1 }, 'Google': { 'Google TV': 1 },
'HP': { 'TouchPad': 1 }, 'HP': { 'TouchPad': 1 },
'HTC': { },
'LG': { }, 'LG': { },
'Microsoft': { 'Xbox': 1, 'Xbox One': 1 },
'Motorola': { 'Xoom': 1 }, 'Motorola': { 'Xoom': 1 },
'Nintendo': { 'Wii U': 1, 'Wii': 1 },
'Nokia': { }, 'Nokia': { },
'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1 }, 'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1, 'Galaxy S3': 1, 'Galaxy S4': 1 },
'Sony': { 'PlayStation Vita': 1 } 'Sony': { 'PlayStation 4': 1, 'PlayStation 3': 1, 'PlayStation Vita': 1 }
}); });
/* Detectable OSes (order is important) */ /* Detectable OSes (order is important) */
@@ -392,7 +426,7 @@
* Picks the manufacturer from an array of guesses. * Picks the manufacturer from an array of guesses.
* *
* @private * @private
* @param {Array} guesses An array of guesses. * @param {Object} guesses An object of guesses.
* @returns {null|string} The detected manufacturer. * @returns {null|string} The detected manufacturer.
*/ */
function getManufacturer(guesses) { function getManufacturer(guesses) {
@@ -401,8 +435,8 @@
return result || ( return result || (
value[product] || value[product] ||
value[0/*Opera 9.25 fix*/, /^[a-z]+(?: +[a-z]+\b)*/i.exec(product)] || 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) RegExp('\\b' + qualify(key) + '(?:\\b|\\w*\\d)', 'i').exec(ua)
) && (key.label || key); ) && key;
}); });
} }
@@ -432,11 +466,13 @@
return reduce(guesses, function(result, guess) { return reduce(guesses, function(result, guess) {
var pattern = guess.pattern || qualify(guess); var pattern = guess.pattern || qualify(guess);
if (!result && (result = if (!result && (result =
RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua))) { RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua)
)) {
// platform tokens defined at // platform tokens defined at
// http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx // http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx
// http://web.archive.org/web/20081122053950/http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx // http://web.archive.org/web/20081122053950/http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx
data = { data = {
'6.3': '8.1',
'6.2': '8', '6.2': '8',
'6.1': 'Server 2008 R2 / 7', '6.1': 'Server 2008 R2 / 7',
'6.0': 'Server 2008 / Vista', '6.0': 'Server 2008 / Vista',
@@ -486,7 +522,7 @@
RegExp('\\b' + pattern + '(?:; *(?:[a-z]+[_-])?[a-z]+\\d+|[^ ();-]*)', 'i').exec(ua) RegExp('\\b' + pattern + '(?:; *(?:[a-z]+[_-])?[a-z]+\\d+|[^ ();-]*)', 'i').exec(ua)
)) { )) {
// split by forward slash and append product version if needed // 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]; result[0] += ' ' + result[1];
} }
// correct character case and cleanup // correct character case and cleanup
@@ -494,7 +530,7 @@
result = format(result[0] result = format(result[0]
.replace(RegExp(pattern, 'i'), guess) .replace(RegExp(pattern, 'i'), guess)
.replace(RegExp('; *(?:' + guess + '[_-])?', 'i'), ' ') .replace(RegExp('; *(?:' + guess + '[_-])?', 'i'), ' ')
.replace(RegExp('(' + guess + ')(\\w)', 'i'), '$1 $2')); .replace(RegExp('(' + guess + ')[-_.]?(\\w)', 'i'), '$1 $2'));
} }
return result; return result;
}); });
@@ -514,8 +550,6 @@
}); });
} }
/*------------------------------------------------------------------------*/
/** /**
* Returns `platform.description` when the platform object is coerced to a string. * Returns `platform.description` when the platform object is coerced to a string.
* *
@@ -562,7 +596,7 @@
os = /Android/.test(os) ? os : 'Android'; os = /Android/.test(os) ? os : 'Android';
} }
// detect false positives for Firefox/Safari // 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 // escape the `/` for Firefox 1
if (name && !product && /[\/,]|^[^(]+?\)/.test(ua.slice(ua.indexOf(data + '/') + 8))) { if (name && !product && /[\/,]|^[^(]+?\)/.test(ua.slice(ua.indexOf(data + '/') + 8))) {
// clear name of false positives // clear name of false positives
@@ -574,10 +608,17 @@
name = /[a-z]+(?: Hat)?/i.exec(/Android/.test(os) ? os : data) + ' Browser'; name = /[a-z]+(?: Hat)?/i.exec(/Android/.test(os) ? os : data) + ' Browser';
} }
} }
// 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) // detect non-Opera versions (order is important)
if (!version) { if (!version) {
version = getVersion([ version = getVersion([
'(?:Cloud9|CriOS|CrMo|Opera ?Mini|OPR|Raven|Silk(?!/[\\d.]+$))', '(?:Cloud9|CriOS|CrMo|Iron|Opera ?Mini|OPR|Raven|Silk(?!/[\\d.]+$))',
'Version', 'Version',
qualify(name), qualify(name),
'(?:Firefox|Minefield|NetFront)' '(?:Firefox|Minefield|NetFront)'
@@ -593,31 +634,39 @@
)) { )) {
layout = [data]; 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 // leverage environment features
if (useFeatures) { if (useFeatures) {
// detect server-side environments // detect server-side environments
// Rhino has a global function while others have a global object // Rhino has a global function while others have a global object
if (isHostType(root, 'global')) { if (isHostType(context, 'global')) {
if (java) { if (java) {
data = java.lang.System; data = java.lang.System;
arch = data.getProperty('os.arch'); arch = data.getProperty('os.arch');
os = os || data.getProperty('os.name') + ' ' + data.getProperty('os.version'); os = os || data.getProperty('os.name') + ' ' + data.getProperty('os.version');
} }
if (freeExports) { if (isHostType(context, 'exports')) {
// if `thisBinding` is the [ModuleScope] if (isModuleScope && isHostType(context, 'system') && (data = [context.system])[0]) {
if (thisBinding == oldRoot && typeof system == 'object' && (data = [system])[0]) {
os || (os = data[0].os || null); os || (os = data[0].os || null);
try { try {
data[1] = require('ringo/engine').version; data[1] = (data[1] = context.require) && data[1]('ringo/engine').version;
version = data[1].join('.'); version = data[1].join('.');
name = 'RingoJS'; name = 'RingoJS';
} catch(e) { } catch(e) {
if (data[0].global == freeGlobal) { if (data[0].global.system == context.system) {
name = 'Narwhal'; name = 'Narwhal';
} }
} }
} }
else if (typeof process == 'object' && (data = process)) { else if (typeof context.process == 'object' && (data = context.process)) {
name = 'Node.js'; name = 'Node.js';
arch = data.arch; arch = data.arch;
os = data.platform; os = data.platform;
@@ -632,12 +681,12 @@
} }
} }
// detect Adobe AIR // detect Adobe AIR
else if (getClassOf((data = root.runtime)) == 'ScriptBridgingProxyObject') { else if (getClassOf((data = context.runtime)) == airRuntimeClass) {
name = 'Adobe AIR'; name = 'Adobe AIR';
os = data.flash.system.Capabilities.os; os = data.flash.system.Capabilities.os;
} }
// detect PhantomJS // detect PhantomJS
else if (getClassOf((data = root.phantom)) == 'RuntimeObject') { else if (getClassOf((data = context.phantom)) == phantomClass) {
name = 'PhantomJS'; name = 'PhantomJS';
version = (data = data.version || null) && (data.major + '.' + data.minor + '.' + data.patch); version = (data = data.version || null) && (data.major + '.' + data.minor + '.' + data.patch);
} }
@@ -648,7 +697,7 @@
version = [version, doc.documentMode]; version = [version, doc.documentMode];
if ((data = +data[1] + 4) != version[1]) { if ((data = +data[1] + 4) != version[1]) {
description.push('IE ' + version[1] + ' mode'); description.push('IE ' + version[1] + ' mode');
layout[1] = ''; layout && (layout[1] = '');
version[1] = data; version[1] = data;
} }
version = name == 'IE' ? String(version[1].toFixed(1)) : version[0]; version = name == 'IE' ? String(version[1].toFixed(1)) : version[0];
@@ -665,8 +714,8 @@
version = version.replace(RegExp(data + '\\+?$'), '') + version = version.replace(RegExp(data + '\\+?$'), '') +
(prerelease == 'beta' ? beta : alpha) + (/\d+\+?/.exec(data) || ''); (prerelease == 'beta' ? beta : alpha) + (/\d+\+?/.exec(data) || '');
} }
// rename code name "Fennec" // detect Firefox Mobile
if (name == 'Fennec') { if (name == 'Fennec' || name == 'Firefox' && /Android|Firefox OS/.test(os)) {
name = 'Firefox Mobile'; name = 'Firefox Mobile';
} }
// obscure Maxthon's unreliable version // obscure Maxthon's unreliable version
@@ -685,9 +734,16 @@
} }
// detect Windows Phone desktop mode // detect Windows Phone desktop mode
else if (name == 'IE' && (data = (/; *(?:XBLWP|ZuneWP)(\d+)/i.exec(ua) || 0)[1])) { else if (name == 'IE' && (data = (/; *(?:XBLWP|ZuneWP)(\d+)/i.exec(ua) || 0)[1])) {
name += ' Mobile'; name += ' Mobile';
os = 'Windows Phone OS ' + data + '.x'; os = 'Windows Phone OS ' + data + '.x';
description.unshift('desktop mode'); 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 // add mobile postfix
else if ((name == 'Chrome' || name == 'IE' || name && !product && !/Browser|Mobi/.test(name)) && else if ((name == 'Chrome' || name == 'IE' || name && !product && !/Browser|Mobi/.test(name)) &&
@@ -695,29 +751,32 @@
name += ' Mobile'; name += ' Mobile';
} }
// detect IE platform preview // 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'); description.unshift('platform preview');
} }
// detect BlackBerry OS version // detect BlackBerry OS version
// http://docs.blackberry.com/en/developers/deliverables/18169/HTTP_headers_sent_by_BB_Browser_1234911_11.jsp // http://docs.blackberry.com/en/developers/deliverables/18169/HTTP_headers_sent_by_BB_Browser_1234911_11.jsp
else if (/BlackBerry/.test(product) && (data = else if ((/BlackBerry/.test(product) || /BB10/.test(ua)) && (data =
(RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] || (RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] ||
version version
)) { )) {
os = 'Device Software ' + data; data = [data, /BB10/.test(ua)];
os = (data[1] ? (product = null, manufacturer = 'BlackBerry') : 'Device Software') + ' ' + data[0];
version = null; version = null;
} }
// detect Opera identifying/masking itself as another browser // detect Opera identifying/masking itself as another browser
// http://www.opera.com/support/kb/view/843/ // http://www.opera.com/support/kb/view/843/
else if (this != forOwn && ( else if (this != forOwn && (
(useFeatures && opera) || product != 'Wii' && (
(/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) || (useFeatures && opera) ||
(name == 'Firefox' && /OS X (?:\d+\.){2,}/.test(os)) || (/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) ||
(name == 'IE' && ( (name == 'Firefox' && /OS X (?:\d+\.){2,}/.test(os)) ||
(os && !/^Win/.test(os) && version > 5.5) || (name == 'IE' && (
/Windows XP/.test(os) && version > 8 || (os && !/^Win/.test(os) && version > 5.5) ||
version == 8 && !/Trident/.test(ua) /Windows XP/.test(os) && version > 8 ||
)) version == 8 && !/Trident/.test(ua)
))
)
) && !reOpera.test((data = parse.call(forOwn, ua.replace(reOpera, '') + ';'))) && data.name) { ) && !reOpera.test((data = parse.call(forOwn, ua.replace(reOpera, '') + ';'))) && data.name) {
// when "indentifying", the UA contains both Opera and the other browser's name // when "indentifying", the UA contains both Opera and the other browser's name
@@ -759,23 +818,26 @@
} }
// clear incorrect browser versions // clear incorrect browser versions
else if (version == data[1] || 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; version = null;
} }
// use the full Chrome version when available // 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 // detect JavaScriptCore
// http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androi // 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])) { if (!useFeatures || (!likeChrome && !data[1])) {
layout[1] = 'like Safari'; 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 : '5'); 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 { } else {
layout[1] = 'like Chrome'; 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 : '21'); 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 // 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 // obscure version for some Safari 1-2 releases
if (name == 'Safari' && (!version || parseInt(version) > 45)) { if (name == 'Safari' && (!version || parseInt(version) > 45)) {
version = data; version = data;
@@ -793,7 +855,7 @@
} }
} }
// detect Chrome desktop mode // 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'); description.unshift('desktop mode');
name = 'Chrome Mobile'; name = 'Chrome Mobile';
version = null; version = null;
@@ -864,128 +926,134 @@
* @name platform * @name platform
* @type Object * @type Object
*/ */
return { var platform = {};
/**
* The platform description.
*
* @memberOf platform
* @type string|null
*/
platform.description = ua;
/**
* The name of the browser's layout engine.
*
* @memberOf platform
* @type string|null
*/
platform.layout = layout && layout[0];
/**
* The name of the product's manufacturer.
*
* @memberOf platform
* @type string|null
*/
platform.manufacturer = manufacturer;
/**
* The name of the browser/environment.
*
* @memberOf platform
* @type string|null
*/
platform.name = name;
/**
* The alpha/beta release indicator.
*
* @memberOf platform
* @type string|null
*/
platform.prerelease = prerelease;
/**
* The name of the product hosting the browser.
*
* @memberOf platform
* @type string|null
*/
platform.product = product;
/**
* The browser's user agent string.
*
* @memberOf platform
* @type string|null
*/
platform.ua = ua;
/**
* The browser/environment version.
*
* @memberOf platform
* @type string|null
*/
platform.version = name && version;
/**
* The name of the operating system.
*
* @memberOf platform
* @type Object
*/
platform.os = os || {
/** /**
* The browser/environment version. * The CPU architecture the OS is built for.
* *
* @memberOf platform * @memberOf platform.os
* @type number|null
*/
'architecture': null,
/**
* The family of the OS.
*
* @memberOf platform.os
* @type string|null * @type string|null
*/ */
'version': name && version && (description.unshift(version), version), 'family': null,
/** /**
* The name of the browser/environment. * The version of the OS.
* *
* @memberOf platform * @memberOf platform.os
* @type string|null * @type string|null
*/ */
'name': name && (description.unshift(name), name), 'version': null,
/** /**
* The name of the operating system. * Returns the OS string.
* *
* @memberOf platform * @memberOf platform.os
* @type Object * @returns {string} The OS string.
*/ */
'os': os 'toString': function() { return 'null'; }
? (name &&
!(os == String(os).split(' ')[0] && (os == name.split(' ')[0] || product)) &&
description.push(product ? '(' + os + ')' : 'on ' + os), os)
: {
/**
* The CPU architecture the OS is built for.
*
* @memberOf platform.os
* @type number|null
*/
'architecture': null,
/**
* The family of the OS.
*
* @memberOf platform.os
* @type string|null
*/
'family': null,
/**
* The version of the OS.
*
* @memberOf platform.os
* @type string|null
*/
'version': null,
/**
* Returns the OS string.
*
* @memberOf platform.os
* @returns {string} The OS string.
*/
'toString': function() { return 'null'; }
},
/**
* The platform description.
*
* @memberOf platform
* @type string|null
*/
'description': description.length ? description.join(' ') : ua,
/**
* The name of the browser layout engine.
*
* @memberOf platform
* @type string|null
*/
'layout': layout && layout[0],
/**
* The name of the product's manufacturer.
*
* @memberOf platform
* @type string|null
*/
'manufacturer': manufacturer,
/**
* The alpha/beta release indicator.
*
* @memberOf platform
* @type string|null
*/
'prerelease': prerelease,
/**
* The name of the product hosting the browser.
*
* @memberOf platform
* @type string|null
*/
'product': product,
/**
* The browser's user agent string.
*
* @memberOf platform
* @type string|null
*/
'ua': ua,
// parses a user agent string into a platform object
'parse': parse,
// returns the platform description
'toString': toStringPlatform
}; };
platform.parse = parse;
platform.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;
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
// expose platform // export platform
// some AMD build optimizers, like r.js, check for condition patterns like the following: // some AMD build optimizers, like r.js, check for condition patterns like the following:
if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
// define as an anonymous module so, through path mapping, it can be aliased // define as an anonymous module so, through path mapping, it can be aliased
@@ -994,8 +1062,8 @@
}); });
} }
// check for `exports` after `define` in case a build optimizer adds an `exports` object // check for `exports` after `define` in case a build optimizer adds an `exports` object
else if (freeExports && !freeExports.nodeType) { else if (freeExports && freeModule) {
// in Narwhal, Node.js, or RingoJS // in Narwhal, Node.js, Rhino -require, or RingoJS
forOwn(parse(), function(value, key) { forOwn(parse(), function(value, key) {
freeExports[key] = value; freeExports[key] = value;
}); });
@@ -1004,4 +1072,4 @@
else { else {
root.platform = parse(); root.platform = parse();
} }
}(this)); }.call(this));

View File

@@ -1,5 +1,5 @@
/*! /*!
* QUnit Extras v1.1.0 * QUnit Extras v1.2.0
* Copyright 2011-2014 John-David Dalton <http://allyoucanleet.com/> * Copyright 2011-2014 John-David Dalton <http://allyoucanleet.com/>
* Based on a gist by Jörn Zaefferer <https://gist.github.com/722381> * Based on a gist by Jörn Zaefferer <https://gist.github.com/722381>
* Available under MIT license <http://mths.be/mit> * Available under MIT license <http://mths.be/mit>