Files
socket.io/lib/util.js
2014-03-07 01:44:16 +02:00

219 lines
4.0 KiB
JavaScript

/**
* Status of page load.
*/
var pageLoaded = false;
/**
* Inheritance.
*
* @param {Function} ctor a
* @param {Function} ctor b
* @api private
*/
exports.inherits = function inherits (a, b) {
function c () { }
c.prototype = b.prototype;
a.prototype = new c;
};
/**
* Object.keys
*/
exports.keys = Object.keys || function (obj) {
var ret = [];
var has = Object.prototype.hasOwnProperty;
for (var i in obj) {
if (has.call(obj, i)) {
ret.push(i);
}
}
return ret;
};
/**
* Adds an event.
*
* @api private
*/
exports.on = function (element, event, fn, capture) {
if (element.attachEvent) {
element.attachEvent('on' + event, fn);
} else if (element.addEventListener) {
element.addEventListener(event, fn, capture);
}
};
/**
* Load utility.
*
* @api private
*/
exports.load = function (fn) {
if (global.document && document.readyState === 'complete' || pageLoaded) {
return fn();
}
exports.on(global, 'load', fn, false);
};
/**
* Change the internal pageLoaded value.
*/
if ('undefined' != typeof window) {
exports.load(function () {
pageLoaded = true;
});
}
/**
* JSON parse.
*
* @see Based on jQuery#parseJSON (MIT) and JSON2
* @api private
*/
var rvalidchars = /^[\],:{}\s]*$/;
var rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
var rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
var rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g;
var rtrimLeft = /^\s+/;
var rtrimRight = /\s+$/;
exports.parseJSON = function (data) {
if ('string' != typeof data || !data) {
return null;
}
data = data.replace(rtrimLeft, '').replace(rtrimRight, '');
// Attempt to parse using the native JSON parser first
if (global.JSON && JSON.parse) {
return JSON.parse(data);
}
if (rvalidchars.test(data.replace(rvalidescape, '@')
.replace(rvalidtokens, ']')
.replace(rvalidbraces, ''))) {
return (new Function('return ' + data))();
}
};
/**
* UA / engines detection namespace.
*
* @namespace
*/
exports.ua = {};
/**
* Detect webkit.
*
* @api private
*/
exports.ua.webkit = 'undefined' != typeof navigator &&
/webkit/i.test(navigator.userAgent);
/**
* Detect gecko.
*
* @api private
*/
exports.ua.gecko = 'undefined' != typeof navigator &&
/gecko/i.test(navigator.userAgent);
/**
* Detect android;
*/
exports.ua.android = 'undefined' != typeof navigator &&
/android/i.test(navigator.userAgent);
/**
* Detect iOS.
*/
exports.ua.ios = 'undefined' != typeof navigator &&
/^(iPad|iPhone|iPod)$/.test(navigator.platform);
exports.ua.ios6 = exports.ua.ios && /OS 6_/.test(navigator.userAgent);
/**
* Detect Chrome Frame.
*/
exports.ua.chromeframe = Boolean(global.externalHost);
/**
* Parses an URI
*
* @author Steven Levithan <stevenlevithan.com> (MIT license)
* @api private
*/
var re = /^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;
var parts = [
'source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host'
, 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor'
];
exports.parseUri = function (str) {
var m = re.exec(str || '')
, uri = {}
, i = 14;
while (i--) {
uri[parts[i]] = m[i] || '';
}
return uri;
};
/**
* Compiles a querystring
*
* @param {Object}
* @api private
*/
exports.qs = function (obj) {
var str = '';
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
if (str.length) str += '&';
str += encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]);
}
}
return str;
};
/**
* Parses a simple querystring.
*
* @param {String} qs
* @api private
*/
exports.qsParse = function(qs){
var qry = {};
var pairs = qs.split('&');
for (var i = 0, l = pairs.length; i < l; i++) {
var pair = pairs[i].split('=');
qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
}
return qry;
};