m8
Version:
m8 is a small utility library you might find useful or just plain annoying.
384 lines (301 loc) • 11.1 kB
JavaScript
function __lib__( val ) { return val; }
function bless( ns, ctx ) {
if ( !Array.isArray( ns ) ) {
if ( typeof ns == 'string' )
ns = ns.split( '.' );
else
return bless_ctx( ctx );
}
if ( re_lib.test( ns[0] ) ) { ctx = __lib__; ns.shift(); }
if ( !ns.length ) return bless_ctx( ctx );
ns[0].indexOf( '^' ) || ( ctx || ns[0] == '^' ? ns.shift() : ns[0] = ns[0].substring( 1 ) );
ctx = bless_ctx( ctx );
var o; while ( o = ns.shift() ) ctx = ctx[o] || ( ctx[o] = obj() );
return ctx;
}
function bless_ctx( ctx ) {
return ENV == 'commonjs'
? ( ctx ? is_mod( ctx ) ? ctx.exports : ctx : module.exports )
: ctx || root;
}
function coerce( item ) {
var num = Number( item ), str;
return !isNaN( num ) ? num : ( str = String( item ) ) in force ? force[str] : item;
}
function copy( target, source, no_overwrite ) {
no_overwrite = no_overwrite === true;
if ( !source ) {
source = target;
target = {};
}
source = Object( source );
for ( var key in source )
if ( OP.hasOwnProperty.call( source, key ) && ( no_overwrite !== true || !OP.hasOwnProperty.call( target, key ) ) )
target[key] = source[key];
return target;
}
function cpdef( target, source, no_overwrite ) {
no_overwrite = no_overwrite === true; source || ( source = target, target = obj() );
return Object.getOwnPropertyNames( source ).reduce( function( o, key ) {
( no_overwrite && has( o, key ) ) || def( o, key, description( source, key ) );
return o;
}, target );
}
function def( item, name, desc ) {
var args = slice.call( arguments, 3 ),
defined = name in Object( item ), debug, mode, ntype, overwrite;
switch ( typeof args[0] ) {
case 'string' : mode = modes[args.shift()]; break;
case 'object' : mode = args.shift();
if ( desc === null )
desc = { value : null };
break;
default :
ntype = nativeType( desc );
mode = ntype != 'object' && defined
? description( item, name )
: null;
if ( !mode )
mode = ntype == 'function'
? modes.cw
: modes.cew;
}
overwrite = args.shift() === true;
debug = args.shift() === true;
if ( defined && !overwrite ) {
if ( debug ) new Error( Name + '.def cannot overwrite existing property: ' + name + ', in item type: ' + type( item ) + '.' );
}
else {
if ( ntype != 'object' && mode )
desc = describe( desc, mode );
if ( desc.get || desc.set )
delete desc.writable; // <- ARGH!!! see: https://plus.google.com/117400647045355298632/posts/YTX1wMry8M2
Object.defineProperty( item, name, desc )
}
return __lib__;
}
function define_amd( path, deps, mod ) {
if ( !AMD ) return;
if ( Array.isArray( deps ) ) {
mod = deps;
deps = [];
}
define( path, deps, function() { return mod; } );
return __lib__;
}
function defs( item, props, mode, overwrite, debug ) {
mode || ( mode = 'cw' );
for ( var key in props )
!has( props, key ) || def( item, key, props[key], mode, overwrite, debug );
return __lib__;
}
function describe( desc, mode ) {
return copy( ( nativeType( desc ) == 'object' ? desc : { value : desc } ), ( nativeType( mode ) == 'object' ? mode : modes[String( mode ).toLowerCase()] || modes.cew ), true );
}
function description( item, property ) {
return Object.getOwnPropertyDescriptor( item, property );
}
function empty( item ) { return !exists( item ) || ( !len( item ) && iter( item ) ) || false; }
function exists( item ) { return !( item === null || item === UNDEF || ( typeof item == 'number' && isNaN( item ) ) ); }
function expose( lib, name, mod ) {
if ( typeof name != 'string' && lib[__name__] ) {
mod = name;
name = lib[__name__];
}
var conflict, defaults = obj(); // make sure the exposed library has a type
defaults[__name__] = name; defaults[__type__] = 'library'; // of "library" and its name attached to it.
if ( ENV == 'commonjs' && is_mod( mod ) )
mod.exports = lib;
else {
mod || ( mod = root );
if ( ( conflict = mod[name] ) && iter( conflict ) ) {
conflict[name] = lib;
lib = cpdef( conflict, lib );
}
else
def( mod, name, describe( { value : lib }, 'ew' ) );
// don't expose as amd if lib is being added to a module that will be exposed
!AMD || mod !== root || define_amd( name, lib );
}
defs( lib, defaults, 'w', true );
return lib; // return the exposed library, if it already exists this will allow us to re-assign our internal copy
}
function fname( fn ) { return fn.name || fn.displayName || ( String( fn ).match( re_name ) || ['', ''] )[1].trim(); }
function format( str ) { return gsub( str, Array.coerce( arguments, 1 ) ); }
function got( item, property ) {
return String( property ) in Object( item );
}
function gsub( str, o, pattern ) {
return String( str ).replace( ( pattern || re_gsub ), function( m, p ) { return o[p] || ''; } );
}
// credit for guid goes here: gist.github.com/2295777
function guid() { return tpl_guid.replace( re_guid, guid_replace ); }
function guid_replace( match ) {
var num = ( randy() * 16 ) | 0;
return ( match == 'x' ? num : ( num & 0x3 | 0x8 ) ).toString( 16 );
}
function has( item, property ) {
return OP.hasOwnProperty.call( Object( item ), String( property ) );
}
function id( item, prefix ) { return item ? 'id' in Object( item ) && !empty( item.id ) ? item.id : ( item.id = id_create( prefix ) ) : id_create( prefix ); }
function id_create( prefix ) { return ( prefix || id_prefix ) + '-' + ( ++id_count ); }
function is_mod( mod ) {
if ( Module === null ) return false;
try { return mod instanceof Module; }
catch ( e ) { return false; }
}
function is_plain_object( item ) {
if ( item === UNDEF || item === null || typeof item !== 'object' )
return false;
var proto = Object.getPrototypeOf( item );
return !!( proto === null || proto.constructor === Object );
}
function iter( item ) { return exists( item ) && ( ( 'length' in Object( item ) ) || typeof item == 'object' ); }
function len( item ) { return ( 'length' in ( item = Object( item ) ) ? item : Object.keys( item ) ).length; }
function merge( target, source ) {
if ( source === UNDEF ) {
if ( target === UNDEF ) // todo: test
return target;
if ( Array.isArray( target ) )
return target.reduce( merge_array, [] );
else if ( is_plain_object( target ) )
return Object.keys( target ).reduce( merge_object, {
source : target,
target : {}
} ).target;
return target;
}
if ( Array.isArray( source ) ) {
if ( !Array.isArray( target ) )
target = [];
else
target.length = source.length; // remove any extra items on the merged Array
return source.reduce( merge_array, target );
}
else if ( is_plain_object( source ) )
return Object.keys( source ).reduce( merge_object, {
source : source,
target : is_plain_object( target ) ? target : {}
} ).target;
return source;
}
function merge_array( target, source, i ) {
target[i] = merge( target[i], source );
return target;
}
function merge_object( o, key ) {
o.target[key] = merge( o.target[key], o.source[key] );
return o;
}
function noop() {}
function obj( props ) {
var nobj = Object.create( null );
return typeof props == 'object' ? copy( nobj, props ) : nobj;
}
function prop_exists( test, item, property ) {
var key; property = String( property );
if ( arguments.length > 3 ) {
property = slice.call( arguments, 2 );
while ( key = property.shift() )
if ( prop_exists( test, item, key ) )
return true;
return false;
}
if ( test( item, property ) )
return true;
if ( typeof item != 'string' && !!~property.indexOf( '.' ) ) {
property = property.split( '.' );
while ( key = property.shift() ) {
if ( !prop_exists( test, item, key ) )
return false;
item = item[key];
}
return true;
}
return false;
}
function range( i, j ) {
return isNaN( i ) ? range_str( i, j ) : range_num( i, j );
}
function range_num( i, j ) {
var a = [i];
while ( ++i <= j ) a.push( i );
return a;
}
function range_str( i, j ) {
i = String( i ).charCodeAt( 0 );
j = String( j ).charCodeAt( 0 );
var a = [], m = -1, n = Math.abs( i - j ); --i;
while ( ++m <= n ) a.push( String.fromCharCode( ++i ) );
return a;
}
function remove( item, keys ) {
keys = Array.isArray( keys ) ? keys : slice.call( arguments, 1 );
var remove_ = Array.isArray( item ) ? remove_array : remove_object;
keys.forEach( remove_, item );
return item;
}
function remove_array( val ) {
var i = this.indexOf( val );
i = !!~i ? i : !isNaN( val ) && val in this ? val : i;
i < 0 || this.splice( i, 1 );
}
function remove_object( key ) { delete this[key]; }
function proto( item ) { return Object.getPrototypeOf( item ); }
function tostr( item ) { return OP.toString.call( item ); }
function valof( item ) { return OP.valueOf.call( item ); }
// type methods
function dom_type( dtype, item ) {
return dtype == htmdoc
? htmdoc : ( dtype == htmcol || dtype == 'nodelist' )
? htmcol : ( !dtype.indexOf( 'htm' ) && ( dtype.lastIndexOf( 'element' ) + 7 === dtype.length ) )
? 'htmlelement' : item === root ? 'global' : false;
}
// function get_type( str_type ) { return str_type.split( ' ' )[1].split( ']' )[0].replace( re_vendor, '$1' ).toLowerCase(); }
function get_type( str_type ) { return str_type.replace( re_tostr, '$1' ).toLowerCase(); }
function nativeType( item ) {
var native_type = OP.toString.call( item );
return native_type in ntype_cache // check the ntype_cache first
? ntype_cache[native_type]
: ntype_cache[native_type] = get_type( native_type );
}
function ptype( item ) { return nativeType( proto( Object( item ) ) ); }
function type( item ) {
if ( item === null || item === UNDEF )
return false;
if ( item === root ) return 'global'; // quick fix for android
var t = __type__ in Object( item )
? item[__type__] : proto( item ) === null
? 'nullobject' : UNDEF;
return t;
// return t !== 'object'
// ? t
// : ( prop_exists( has, item, 'configurable', 'enumerable', 'writable' ) && has( item, 'value' )
// || prop_exists( has, item, 'get', 'set' ) )
// ? 'descriptor'
// : t;
}
function update( target, source ) {
if ( source === UNDEF ) return merge( target );
if ( target === UNDEF || target === null )
return merge( source );
if ( Array.isArray( source ) ) {
if ( !Array.isArray( target ) )
return target;
return source.reduce( update_array, target )
}
else if ( is_plain_object( source ) ) {
if ( !is_plain_object( target ) )
return target;
return Object.keys( source ).reduce( update_object, { source : source, target : target } ).target;
}
return target;
}
function update_array( target, source, i ) {
target[i] = update( target[i], source );
return target;
}
function update_object( o, key ) {
o.target[key] = update( o.target[key], o.source[key] );
return o;
}