d2-ui
Version:
135 lines (120 loc) • 2.79 kB
JavaScript
/*!
* type-detect
* Copyright(c) 2013 jake luer <jake@alogicalparadox.com>
* MIT Licensed
*/
/*!
* Primary Exports
*/
var exports = module.exports = getType;
/**
* ### typeOf (obj)
*
* Use several different techniques to determine
* the type of object being tested.
*
*
* @param {Mixed} object
* @return {String} object type
* @api public
*/
var objectTypeRegexp = /^\[object (.*)\]$/;
function getType(obj) {
var type = Object.prototype.toString.call(obj).match(objectTypeRegexp)[1].toLowerCase();
// Let "new String('')" return 'object'
if (typeof Promise === 'function' && obj instanceof Promise) return 'promise';
// PhantomJS has type "DOMWindow" for null
if (obj === null) return 'null';
// PhantomJS has type "DOMWindow" for undefined
if (obj === undefined) return 'undefined';
return type;
}
exports.Library = Library;
/**
* ### Library
*
* Create a repository for custom type detection.
*
* ```js
* var lib = new type.Library;
* ```
*
*/
function Library() {
if (!(this instanceof Library)) return new Library();
this.tests = {};
}
/**
* #### .of (obj)
*
* Expose replacement `typeof` detection to the library.
*
* ```js
* if ('string' === lib.of('hello world')) {
* // ...
* }
* ```
*
* @param {Mixed} object to test
* @return {String} type
*/
Library.prototype.of = getType;
/**
* #### .define (type, test)
*
* Add a test to for the `.test()` assertion.
*
* Can be defined as a regular expression:
*
* ```js
* lib.define('int', /^[0-9]+$/);
* ```
*
* ... or as a function:
*
* ```js
* lib.define('bln', function (obj) {
* if ('boolean' === lib.of(obj)) return true;
* var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];
* if ('string' === lib.of(obj)) obj = obj.toLowerCase();
* return !! ~blns.indexOf(obj);
* });
* ```
*
* @param {String} type
* @param {RegExp|Function} test
* @api public
*/
Library.prototype.define = function(type, test) {
if (arguments.length === 1) return this.tests[type];
this.tests[type] = test;
return this;
};
/**
* #### .test (obj, test)
*
* Assert that an object is of type. Will first
* check natives, and if that does not pass it will
* use the user defined custom tests.
*
* ```js
* assert(lib.test('1', 'int'));
* assert(lib.test('yes', 'bln'));
* ```
*
* @param {Mixed} object
* @param {String} type
* @return {Boolean} result
* @api public
*/
Library.prototype.test = function(obj, type) {
if (type === getType(obj)) return true;
var test = this.tests[type];
if (test && 'regexp' === getType(test)) {
return test.test(obj);
} else if (test && 'function' === getType(test)) {
return test(obj);
} else {
throw new ReferenceError('Type test "' + type + '" not defined or invalid.');
}
};