Permalink
Browse files

- added static method `m8.proto` as alias for `Object.getPrototypeOf()`

- added static method `m8.ptype` to return the native type of an item's `__proto__`
- minor tweaks for `Object.value` and `m8.nativeType`
- minor code tidy ups...
  • Loading branch information...
1 parent 71ca5f1 commit dc515585a8bcdb70ec6a1d4e19153f58ed350fd8 @constantology committed Dec 20, 2012
Showing with 250 additions and 49 deletions.
  1. +92 −2 README.md
  2. +42 −23 m8.js
  3. +1 −1 m8.min.js
  4. +1 −0 src/expose.js
  5. +15 −6 src/lib.js
  6. +10 −7 src/nativex.js
  7. +16 −10 src/vars.js
  8. +73 −0 test/m8.test.js
View
@@ -574,11 +574,101 @@ Returns the native `type` of the passed item. For normalised types use `m8.type`
### m8.noop():void
An empty Function that returns nothing.
+### m8.nativeType( item:Mixed ):String (alias: m8.ntype)
+Returns the native `type` of the passed item. For normalised types use `m8.type`.
+
+**Note:** All types are **always** in lowercase.
+
+#### Example:
+
+```javascript
+
+ m8.nativeType( null ); // returns => "null"
+
+ m8.nativeType( undefined ); // returns => "undefined"
+
+ m8.nativeType( [] ); // returns => "array"
+
+ m8.nativeType( true ); // returns => "boolean"
+
+ m8.nativeType( new Date() ); // returns => "date"
+
+ m8.nativeType( function() {} ); // returns => "function"
+
+ m8.nativeType( 0 ); // returns => "number"
+
+ m8.nativeType( { enumerable : true, get : function() {} } ); // returns => "object"
+
+ m8.nativeType( m8.description( window, 'document' ) ); // returns => "object"
+
+ m8.nativeType( {} ); // returns => "object"
+
+ m8.nativeType( Object.create( null ) ); // returns => "object"
+
+ m8.nativeType( /.*/ ); // returns => "regexp"
+
+ m8.nativeType( '' ); // returns => "string"
+
+ m8.nativeType( document.createElement( 'div' ) ); // returns => "htmldivelement"
+
+ m8.nativeType( document.querySelectorAll( 'div' ) ); // returns => "htmlcollection" | "nodelist"
+
+ m8.nativeType( document.getElementsByTagName( 'div' ) ); // returns => "htmlcollection" | "nodelist"
+
+ m8.nativeType( global ); // returns => "global"
+
+ m8.nativeType( window ); // returns => "global" | "window"
+
+```
+
### m8.obj( [props:Obejct] ):Object
Creates an empty Object using `Object.create( null )`, the Object has no constructor and executing `Object.getPrototypeOf` on the empty Object instance will return `null` rather than `Object.prototype`.
Optionally pass an Object whose properties you want copied to the empty Object instance.
+### m8.ptype( item:Mixed ):String
+Returns the native `type` of the passed item's `__proto__`.
+
+**Note:** All types are **always** in lowercase.
+
+#### Example:
+
+```javascript
+
+ m8.ptype( null ); // returns => "object"
+
+ m8.ptype( undefined ); // returns => "object"
+
+ m8.ptype( [] ); // returns => "array"
+
+ m8.ptype( true ); // returns => "boolean"
+
+ m8.ptype( new Date() ); // returns => "date"
+
+ m8.ptype( function() {} ); // returns => "function"
+
+ m8.ptype( 0 ); // returns => "number"
+
+ m8.ptype( {} ); // returns => "object"
+
+ m8.ptype( Object.create( null ) ); // returns => "null"
+
+ m8.ptype( /.*/ ); // returns => "regexp"
+
+ m8.ptype( '' ); // returns => "string"
+
+ m8.ptype( document.createElement( 'div' ) ); // returns => "object" | "xpc_..._jsclass" <- FireFox :P
+
+ m8.ptype( document.querySelectorAll( 'div' ) ); // returns => "object" | "xpc_..._jsclass"
+
+ m8.ptype( document.getElementsByTagName( 'div' ) ); // returns => "object" | "xpc_..._jsclass"
+
+ m8.ptype( global ); // returns => "object" | "xpc_..._jsclass"
+
+ m8.ptype( window ); // returns => "object" | "xpc_..._jsclass"
+
+```
+
### m8.range( begin:Number|String, end:Number|String ):Array
Returns an Array starting at `begin` where each value is incremented by `1` until `end` is reached.
@@ -969,8 +1059,8 @@ Attempts to resolve a normalised type for any type that inherits from JavaScript
## File size
-- m8.js ≅ 6.4kb (gzipped)
-- m8.min.js ≅ 3.6kb (minzipped)
+- m8.js ≅ 6.9kb (gzipped)
+- m8.min.js ≅ 3.7kb (minzipped)
## License
View
65 m8.js
@@ -48,19 +48,25 @@
delete modes[UNDEF];
return modes;
}(), // pre-caching common types for faster checks
- ntype_cache = 'Array Boolean Date Function Null Number Object RegExp String Undefined'
- .split( ' ' ).reduce( function( cache, type ) {
+ ntypes_common = 'Array Boolean Date Function Number Object RegExp String Null Undefined'.split( ' ' ),
+ ntype_cache = ntypes_common.reduce( function( cache, type ) {
cache['[object ' + type + ']'] = type.toLowerCase();
return cache;
}, obj() ),
- randy = Math.random, re_global = /global|window/i,
- re_gsub = /\$?\{([^\}'"]+)\}/g, re_guid = /[xy]/g, re_lib = new RegExp( '^\\u005E?' + Name ),
- re_name = /[\s\(]*function([^\(]+).*/, re_vendor = /^[Ww]ebkit|[Mm]oz|O|[Mm]s|[Kk]html(.*)$/,
- slice = Array.prototype.slice, tpl_guid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx',
- xcache = {
- 'Array' : [], 'Boolean' : [], 'Date' : [], 'Function' : [],
- 'Number' : [], 'Object' : [], 'RegExp' : [], 'String' : []
- };
+ randy = Math.random, re_global = /global|window/i,
+ re_gsub = /\$?\{([^\}'"]+)\}/g, re_guid = /[xy]/g, re_lib = new RegExp( '^\\u005E?' + Name ),
+ re_name = /[\s\(]*function([^\(]+).*/, //re_vendor = /^[Ww]ebkit|[Mm]oz|O|[Mm]s|[Kk]html(.*)$/,
+/** opera has been purposefully left out for the following reasons:
+ * whose stupid decision was it to make dragonfly not work unless you have an internet connection!?
+ * the previous point is so seriously retarded it needs to be mentioned again, here.
+ * the opera prefix `O` screws with [object Object] I don't like it, so it's gonski...
+**/
+ re_tostr = /^\[object (?:[Ww]eb[Kk]it|[Mm]oz|[Mm]s|[Kk]html){0,1}([^\]]+)\]$/,
+ slice = Array.prototype.slice, tpl_guid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx',
+ xcache = ntypes_common.slice( 0, -2 ).reduce( function( cache, type ) {
+ cache[type] = [];
+ return cache;
+ }, obj() );
@@ -337,24 +343,33 @@
}
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 domType( dtype ) {
- return dtype == htmdoc ? htmdoc : ( dtype == htmcol || dtype == 'nodelist' ) ? htmcol : ( !dtype.indexOf( 'htm' ) && ( dtype.lastIndexOf( 'element' ) + 7 === dtype.length ) ) ? 'htmlelement' : false;
- }
+ function dom_type( dtype ) {
+ return dtype == htmdoc
+ ? htmdoc : ( dtype == htmcol || dtype == 'nodelist' )
+ ? htmcol : ( !dtype.indexOf( 'htm' ) && ( dtype.lastIndexOf( 'element' ) + 7 === dtype.length ) )
+ ? 'htmlelement' : 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 = tostr( item );
- if ( native_type in ntype_cache ) return ntype_cache[native_type]; // check the ntype_cache first
- return ( ntype_cache[native_type] = native_type.split( ' ' )[1].split( ']' )[0].replace( re_vendor, '$1' ).toLowerCase() );
+
+ 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;
var t = got( item, __type__ )
- ? item[__type__] : Object.getPrototypeOf( item ) === null
+ ? item[__type__] : proto( item ) === null
? 'nullobject' : UNDEF;
return t !== 'object'
@@ -513,7 +528,7 @@
// since it internally uses __type__ which is about to be set up here.
def( Type.prototype, __type__, copy( { get : function() {
var _type_, item = this, ctor = item.constructor, ntype = nativeType( item ),
- dtype = domType( ntype ) || ( re_global.test( ntype ) ? 'global' : false );
+ dtype = dom_type( ntype ) || ( re_global.test( ntype ) ? 'global' : false );
if ( dtype ) return dtype;
if ( ntype == 'number' ) return isNaN( item ) ? 'nan' : 'number';
@@ -530,8 +545,8 @@
def( Type.prototype, '__proto__', {
get : function() {
- return Type.getPrototypeOf( this );
- } // todo: set???
+ return proto( this );
+ } // todo: set, or would it be anti-spec/overkill???
}, 'c' );
defs( Type, {
@@ -547,8 +562,11 @@
}, val );
},
value : function( item, key ) {
- if ( isNaN( key ) ) {
- if ( got( item, key ) ) return item[key];
+ if ( !exists( item ) ) return UNDEF;
+
+ if ( key in item ) return item[key];
+
+ if ( isNaN( +key ) ) {
if ( !!~key.indexOf( '.' ) ) {
var val; key = key.split( '.' );
while ( val = key.shift() )
@@ -557,8 +575,8 @@
return item;
}
}
- return empty( item )
- ? UNDEF : exists( item[key] )
+
+ return item[key] !== UNDEF
? item[key] : typeof item.get == 'function'
? item.get( key ) : typeof item.getAttribute == 'function'
? item.getAttribute( key ) : UNDEF;
@@ -589,6 +607,7 @@
len : len, merge : merge,
nativeType : nativeType, noop : noop,
ntype : nativeType, obj : obj,
+ proto : proto, ptype : ptype,
range : range, remove : remove,
tostr : tostr, type : type,
update : update, valof : valof,
View

Large diffs are not rendered by default.

Oops, something went wrong.
View
@@ -16,6 +16,7 @@
len : len, merge : merge,
nativeType : nativeType, noop : noop,
ntype : nativeType, obj : obj,
+ proto : proto, ptype : ptype,
range : range, remove : remove,
tostr : tostr, type : type,
update : update, valof : valof,
View
@@ -269,24 +269,33 @@
}
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 domType( dtype ) {
- return dtype == htmdoc ? htmdoc : ( dtype == htmcol || dtype == 'nodelist' ) ? htmcol : ( !dtype.indexOf( 'htm' ) && ( dtype.lastIndexOf( 'element' ) + 7 === dtype.length ) ) ? 'htmlelement' : false;
- }
+ function dom_type( dtype ) {
+ return dtype == htmdoc
+ ? htmdoc : ( dtype == htmcol || dtype == 'nodelist' )
+ ? htmcol : ( !dtype.indexOf( 'htm' ) && ( dtype.lastIndexOf( 'element' ) + 7 === dtype.length ) )
+ ? 'htmlelement' : 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 = tostr( item );
- if ( native_type in ntype_cache ) return ntype_cache[native_type]; // check the ntype_cache first
- return ( ntype_cache[native_type] = native_type.split( ' ' )[1].split( ']' )[0].replace( re_vendor, '$1' ).toLowerCase() );
+
+ 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;
var t = got( item, __type__ )
- ? item[__type__] : Object.getPrototypeOf( item ) === null
+ ? item[__type__] : proto( item ) === null
? 'nullobject' : UNDEF;
return t !== 'object'
View
@@ -84,7 +84,7 @@
// since it internally uses __type__ which is about to be set up here.
def( Type.prototype, __type__, copy( { get : function() {
var _type_, item = this, ctor = item.constructor, ntype = nativeType( item ),
- dtype = domType( ntype ) || ( re_global.test( ntype ) ? 'global' : false );
+ dtype = dom_type( ntype ) || ( re_global.test( ntype ) ? 'global' : false );
if ( dtype ) return dtype;
if ( ntype == 'number' ) return isNaN( item ) ? 'nan' : 'number';
@@ -101,8 +101,8 @@
def( Type.prototype, '__proto__', {
get : function() {
- return Type.getPrototypeOf( this );
- } // todo: set???
+ return proto( this );
+ } // todo: set, or would it be anti-spec/overkill???
}, 'c' );
defs( Type, {
@@ -118,8 +118,11 @@
}, val );
},
value : function( item, key ) {
- if ( isNaN( key ) ) {
- if ( got( item, key ) ) return item[key];
+ if ( !exists( item ) ) return UNDEF;
+
+ if ( key in item ) return item[key];
+
+ if ( isNaN( +key ) ) {
if ( !!~key.indexOf( '.' ) ) {
var val; key = key.split( '.' );
while ( val = key.shift() )
@@ -128,8 +131,8 @@
return item;
}
}
- return empty( item )
- ? UNDEF : exists( item[key] )
+
+ return item[key] !== UNDEF
? item[key] : typeof item.get == 'function'
? item.get( key ) : typeof item.getAttribute == 'function'
? item.getAttribute( key ) : UNDEF;
View
@@ -41,16 +41,22 @@
delete modes[UNDEF];
return modes;
}(), // pre-caching common types for faster checks
- ntype_cache = 'Array Boolean Date Function Null Number Object RegExp String Undefined'
- .split( ' ' ).reduce( function( cache, type ) {
+ ntypes_common = 'Array Boolean Date Function Number Object RegExp String Null Undefined'.split( ' ' ),
+ ntype_cache = ntypes_common.reduce( function( cache, type ) {
cache['[object ' + type + ']'] = type.toLowerCase();
return cache;
}, obj() ),
- randy = Math.random, re_global = /global|window/i,
- re_gsub = /\$?\{([^\}'"]+)\}/g, re_guid = /[xy]/g, re_lib = new RegExp( '^\\u005E?' + Name ),
- re_name = /[\s\(]*function([^\(]+).*/, re_vendor = /^[Ww]ebkit|[Mm]oz|O|[Mm]s|[Kk]html(.*)$/,
- slice = Array.prototype.slice, tpl_guid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx',
- xcache = {
- 'Array' : [], 'Boolean' : [], 'Date' : [], 'Function' : [],
- 'Number' : [], 'Object' : [], 'RegExp' : [], 'String' : []
- };
+ randy = Math.random, re_global = /global|window/i,
+ re_gsub = /\$?\{([^\}'"]+)\}/g, re_guid = /[xy]/g, re_lib = new RegExp( '^\\u005E?' + Name ),
+ re_name = /[\s\(]*function([^\(]+).*/, //re_vendor = /^[Ww]ebkit|[Mm]oz|O|[Mm]s|[Kk]html(.*)$/,
+/** opera has been purposefully left out for the following reasons:
+ * whose stupid decision was it to make dragonfly not work unless you have an internet connection!?
+ * the previous point is so seriously retarded it needs to be mentioned again, here.
+ * the opera prefix `O` screws with [object Object] I don't like it, so it's gonski...
+**/
+ re_tostr = /^\[object (?:[Ww]eb[Kk]it|[Mm]oz|[Mm]s|[Kk]html){0,1}([^\]]+)\]$/,
+ slice = Array.prototype.slice, tpl_guid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx',
+ xcache = ntypes_common.slice( 0, -2 ).reduce( function( cache, type ) {
+ cache[type] = [];
+ return cache;
+ }, obj() );
Oops, something went wrong.

0 comments on commit dc51558

Please sign in to comment.