-
Notifications
You must be signed in to change notification settings - Fork 0
/
package.json
49 lines (49 loc) · 42.8 KB
/
package.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
{
"author": {
"name": "constantology",
"email": "christos@muigui.com",
"url": "http://muigui.com"
},
"description": "m8 is a small utility library you might find useful or just plain annoying.",
"devDependencies": {
"catn8": ">= 0.0.4",
"chai": ">= 1.2.0",
"mocha": ">= 1.4.2"
},
"engines": {
"node": ">= 0.8.x"
},
"keywords": [
"api",
"framework",
"functional",
"javascript",
"library",
"programming",
"utility"
],
"licenses": [
{
"type": "MIT",
"url": "https://raw.github.com/constantology/m8/master/LICENSE"
}
],
"main": "./m8",
"name": "m8",
"repository": {
"type": "git",
"url": "git@github.com:constantology/m8.git"
},
"scripts": {
"test": "mocha -c --ignore-leaks -R spec -u tdd ./test/*.test.js"
},
"version": "0.4.4",
"readme": "# m8.js [![build status](https://secure.travis-ci.org/constantology/m8.png)](http://travis-ci.org/constantology/m8)\n\nm8 (mate) is a small utility library – for modern JavaScript engines – you might find useful or just plain annoying.\n\nm8 provides a set of basic functionality I tend to write over and over in each of my projects, so I just abstracted it out into its own library!\n\n## A note on the archticture\nThe bulk of the `m8` API, lives under the `m8` namespace. There are a few extensions to JavaScript Natives.\n\nThe reason being: some methods/ properties make more sense being assigned to a specific Type. These are extended correctly, using `Object.defineProperty` and are non-enumerable.\n\nThey will not break any standard functionality – e.g. `for ... in` loops – and they will not overwrite any existing functionality with the same name – though it is possible if you want to.\n\n### Extending into the future\n[Common JS Modules 1.1.1](http://wiki.commonjs.org/wiki/Modules/1.1.1) [notes on extending native prototypes from a module](http://wiki.commonjs.org/wiki/Modules/Natives) contains a [proposal for explicit native use in modules](http://wiki.commonjs.org/wiki/Modules/ProposalForNativeExtension).\n\nIn essence: future commonjs modules could potentially be sandboxed from the rest of the environment they're running in. So the behaviour of extending native Types could become unpredictable.\n\nm8 **attempts** to future proof itself by implementing functionality similar to that defined in the [example of how to extend prototypes using a commonjs module](https://gist.github.com/268543) included in the proposal.\n\n#### m8.x( [Type1:Mixed, Type2:Mixed, ..., TypeN:Mixed] ):m8 and m8.x.cache( Type:String, extensisons:Function ):m8\nThese two methods work in tandem to allow you to store any extensions for a particular Type – Native or otherwise, using `m8.x.cache` – and then extend Types as and when needed – using `m8.x`.\n\n##### Example:\nSuppose we have a module called `foo` with the following code:\n\n```javascript\n\n// require m8\n var m8 = require( 'm8' );\n\n// extend foo module's natives if sandboxed.\n// IMPORTANT: if the module IS NOT sandboxed, the natives in foo will have already been extended when m8 was required\n// m8 keeps track of this and will only attempt to apply any newly added extensions.\n m8.x( Object, Array, Boolean, Function );\n\n// caching new extensions for Array. won't actually extend anything at this point.\n m8.x.cache( 'Array', function( Type ) { // <= notice 'Array' is a String, NOT the actual Array Function\n m8.def( Type, m8.describe( function() {\n /** some static method **/\n }, 'w' ) );\n\n m8.defs( Type.prototype, {\n doSomething : function() { /** do something **/ },\n doSomethingElse : function() { /** do something else **/ }\n }, 'w' );\n } );\n\n// only extends foo module's Array! since it is the only Type to have more extensions added.\n m8.x( Object, Array, Boolean, Function ); // no danger and no pointless iterations either.\n\n module.exports = {\n extend : function() {\n m8.x.apply( m8, arguments );\n }\n };\n\n```\n\nWe can then require `foo` from another module and pass it any Types we want to extend:\n\n```javascript\n\n// extend this module's natives if sandboxed.\n require( 'foo' ).extend( Object, Array, Boolean, Function );\n\n// do all the stuff \"JavaScript: The Good Parts\" tells you not to do here, coz you're an animal!\n\n```\n\n## Support\n\nTested to work with nodejs, FF4+, Safari 5+, Chrome 7+, IE9+. Should technically work in any browser that supports [ecma 5]( http://kangax.github.com/es5-compat-table/) without throwing any JavaScript errors.\n\n## API\n\n### m8( item:Mixed ):Mixed\nm8 itself is a Function which returns the the first parameter passed to it.\n\n#### Example\n\n```javascript\n\n m8( true ); // returns => true\n\n m8( 'foo' ); // returns => \"foo\"\n\n m8( { foo : 'bar' } ); // returns => { \"foo\" : \"bar\" }\n\n```\n\n### m8.bless( namespace:String[, context:Object] ):Object\nCreates an Object representation of the passed `namespace` String and returns it.\n\nIf a `context` Object is given, the Object tree created will be added to the `context` Object, otherwise it will be added to the global namespace.\n\n**NOTE:** If any existing Objects with the same name already exist, they will **NOT** be replaced and any child Objects will be appended to them.\n\n#### Example:\n\n```javascript\n\n// m8.ENV == 'browser'\n m8.bless( 'foo.bar' ); // creates => global.foo.bar\n\n// you can now do:\n foo.bar.Something = function() {};\n\n m8.bless( 'foo.bar', m8 ); // creates => m8.foo.bar\n\n var bar = m8.bless( 'foo.bar' );\n\n bar === foo.bar // returns => true\n\n```\n\n**IMPORTANT:** When using `m8.bless` within a commonjs module: if you want your namespace Object to be assigned to the correct `module.exports`, then you should always pass the `module` instance as the context (`ctx`) of your namespace.\n\n#### Example:\n\n```javascript\n\n// m8.ENV == 'commonjs'\n\n// inside my_commonjs_module.js\n m8.bless( 'foo.bar', module ); // creates => module.exports.foo.bar\n\n// you can now do:\n module.exports.foo.bar.Something = function() {};\n\n// if you want to include \"exports\" in your namespace, you can do so by placing a carat (^) at the start of the String\n m8.bless( '^exports.foo.bar', module ); // creates => module.exports.foo.bar\n\n// otherwise, you will end up creating an extra exports Object, e.g:\n m8.bless( 'exports.foo.bar', module ); // creates => module.exports.exports.foo.bar\n\n// alternatively, you can also do:\n m8.bless( 'foo.bar', module.exports ); // creates => module.exports.foo.bar\n\n```\n\n### m8.coerce( item:Mixed ):Mixed\nAttempts to coerce primitive values \"trapped\" in Strings, into their real types.\n\n#### Example:\n\n```javascript\n\n m8.coerce( 'false' ); // returns false\n\n m8.coerce( 'null' ); // returns null\n\n m8.coerce( 'true' ); // returns true\n\n m8.coerce( 'undefined' ); // returns undefined\n\n m8.coerce( 'NaN' ); // returns NaN\n\n m8.coerce( '0001' ); // returns 1\n\n m8.coerce( '0012' ); // returns 12\n\n m8.coerce( '0123' ); // returns 123\n\n m8.coerce( '123.4' ); // returns 123.4\n\n m8.coerce( '123.45' ); // returns 123.45\n\n m8.coerce( '123.456' ); // returns 123.456\n\n m8.coerce( '123.456.789' ); // returns \"123.456.789\"\n\n```\n\n### m8.copy( target:Object, source:Object[, no_overwrite:Boolean] ):Object\nCopies the properties – accessible via `Object.keys` – from the `source` Object to the `target` Object and returns the `target` Object.\n\n#### Example:\n\n```javascript\n\n var foo = { one : 1, two : 2, three : 3 },\n bar = m8.copy( {}, foo );\n\n bar // returns => { \"one\" : 1, \"two\" : 2, \"three\" : 3 }\n\n foo === bar // returns => false\n\n m8.copy( foo, { three : 3.3, four : 4 }, true ); // returns => { \"one\" : 1, \"two\" : 2, \"three\" : 3, \"four\" : 4 }\n\n```\n\n### m8.def( item:Mixed, name:String, descriptor:Object[, overwrite:Boolean, debug:Boolean]] ):m8\nShortened version of [Object.defineProperty](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/defineProperty) with some extra options.\n\n<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n\t<tr><td>item</td><td>The item to define a property on.</td></tr>\n\t<tr><td>name</td><td>The name of the property you are defining.</td></tr>\n\t<tr><td>descriptor</td><td>The property descriptor for the new/ modified property.</td></tr>\n\t<tr><td>overwrite</td><td>Whether or not to attempt overwriting the new property if it exists.</td></tr>\n\t<tr><td>debug</td><td>Whether or not to throw an error if the property already exists.</td></tr>\n</table>\n\nThe last two – optional – parameters are handy for extending JavaScript Natives without risking collisions with native/ other implementations.\n\n#### Example:\n\n```javascript\n\n m8.def( Object, 'greet', m8.describe( function( name ) { return 'Hello ' + name + '!'; }, 'w' ) );\n\n Object.greet( 'world' ); // returns => \"Hello world!\"\n\n delete Object.greet; // returns => false; Object.greet is not configurable\n\n```\n\n### m8.defs( item:Mixed, descriptors:Object, mode:String|Object[, overwrite:Boolean, debug:Boolean]] ):m8\nSimilar to `m8.def` except `m8.defs` allows you to define multiple properties at once.\n\n**NOTE:** Calls `m8.def` internally.\n\n<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n\t<tr><td>item</td><td>The item to define the properties on.</td></tr>\n\t<tr><td>descriptors</td><td>An Object of properties apply to the item. Each of the <code>descriptors</code> key/ value pairs become the property name and value on the item. This can be a property descriptor, partial descriptor or just the value you want to assign.</td></tr>\n\t<tr><td>mode</td><td>The permissions to apply to each property descriptor in the <code>descriptors</code> Object. See <code>m8.describe</code> directly below and <code>m8.modes</code> to find out more about this.</td></tr>\n\t<tr><td>overwrite</td><td>Whether or not to attempt overwriting the new property if it exists.</td></tr>\n\t<tr><td>debug</td><td>Whether or not to throw an error if the property already exists.</td></tr>\n</table>\n\nThe last two – optional – parameters are handy for extending JavaScript Natives without risking collisions with native/ other implementations.\n\n#### Example:\n\n```javascript\n\n m8.defs( Object, {\n accessor : { get : function() { return this.__accessor; }, set : function( a ) { this.__accessor = a; } },\n global : { value : window },\n greeting : function( name ) { return 'Hello ' + name + '!'; }\n }, 'w' ) );\n/**\n IMPORTANT TO NOTE: Accessors do not alllow the \"writable\" attribute to even be present in their descriptor Object.\n see: https://plus.google.com/117400647045355298632/posts/YTX1wMry8M2\n m8.def handles this internally, so if a \"get\" or \"set\" accessor Function is in the descriptor, the\n \"writable\" attribute will be removed from the descriptor, if it exists.\n**/\n\n Object.accessor = 'foo'; // returns => 'foo'\n Object.accessor; // returns => 'foo'\n\n Object.global === window // returns => true\n Object.greet( 'world' ); // returns => \"Hello world!\"\n\n delete Object.greet; // returns => false; Object.greet is not configurable\n\n```\n\n### m8.describe( value:Mixed[, mode:Object|String] ):Object\nWhen using [Object.defineProperty](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/defineProperty) en masse, your property descriptors can really start to bulk out your codebase.\n\nUsing `m8.describe` in combination with `m8.modes` can significantly reduce the amount of superfluous code you need to write. Especially when working with verbose property names like: `configurable`, `enumerable` & `writeable`.\n\nWhen `value` is an Object `m8.describe` assumes you are passing it a property descriptor you want to assign modes to.\n\n#### Example:\n\n```javascript\n\n m8.describe( {\n get : function() { ... },\n set : function() { ... }\n }, 'cw' );\n\n /* returns => {\n configurable : true,\n enumerable : false,\n get : function() { ... },\n set : function() { ... },\n writable : true // NOTE: this property is illegal in an accessor descriptor. however, m8.def will handle this internally saving you tears\n } */\n\n```\n\nWhen `value` is anything but an Object, it is assigned to the `value` property of the property descriptor.\n\n#### Example:\n\n```javascript\n\n m8.describe( function() { ... }, m8.modes.c );\n\n /* returns => {\n configurable : true,\n enumerable : false,\n value : function() { ... },\n writeable : false\n } */\n\n```\n\nSee `m8.modes` below for a list of available property descriptors.\n\n### m8.description( item:Object, property:String ):Object\nShortened version for [Object.getOwnPropertyDescriptor](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor).\n\n### m8.empty( value:Mixed ):Boolean\nReturns `true` if the passed `value` does not exist (see `exist` below), is an empty Array, Object, String or any other enumerable type.\n\n#### Example:\n\n```javascript\n\n m8.empty( undefined ); // returns => true\n\n m8.empty( null ); // returns => true\n\n m8.empty( '' ); // returns => true\n\n m8.empty( [] ); // returns => true\n\n m8.empty( {} ); // returns => true\n\n m8.empty( ' ' ); // returns => false\n\n m8.empty( [1] ); // returns => false\n\n m8.empty( { 0 : null } ); // returns => false\n\n```\n\n### m8.exists( value:Mixed ):Boolean\nReturns `false` if the passed `value` is `undefined` , `NaN` or `null`, returns `true` otherwise.\n\n#### Example:\n\n```javascript\n\n m8.exists( undefined ); // returns => false\n\n m8.exists( NaN ); // returns => false\n\n m8.exists( null ); // returns => false\n\n m8.exists( 0 ); // returns => true\n\n m8.exists( false ); // returns => true\n\n m8.exists( {} ); // returns => true\n\n```\n\n### m8.expose( library:Object[, name:String, module:Module] ):library\nGeneric method to standardise exposing your library package to either the global namespace or a commonjs module.\n\nInternally resolves any conflict between the `library` to be exposed and an existing Object with the same `name`.\n\nIf the `library` already has a `__name__` property then the `name` parameter may be omitted.\n\nIf the `library` is not going to be used as a commonjs module then the `module` parameter may be omitted.\n\n#### Example:\n\n```javascript\n\n // browser based version\n ;!function() {\n\n var my_library = { /* you awesome library api here */ };\n\n m8.expose( my_library, 'foo' );\n\n }();\n\n m8.type( foo ) // returns => \"library\"\n\n foo.__name__ // returns => \"foo\"\n\n m8.expose( m8, foo );\n\n foo.m8 === m8 // returns => true\n\n m8.expose( m8, 'bar', foo );\n \n foo.bar === m8 // returns => true\n\n foo.bar.__name__ // returns => \"m8\"\n\n```\n\n```javascript\n\n // commonjs based version\n var m8 = require( 'm8' ),\n my_library = { /* you awesome library api here */ };\n\n m8.expose( my_library, 'foo', module );\n\n m8.type( foo ); // returns => 'library'\n\n foo.__name__; // returns => 'foo'\n\n```\n\n### m8.format( tpl:String, arg1:String[, arg2:String, ..., argN:String] ):String\nReplaces the – zero indexed – numeric tokens in the String with the passed parameters.\n\nIf a token does not have a value, an empty String is used in its place.\n\n**NOTE:** `format` calls `gsub` internally.\n\n#### Example:\n\n```javascript\n\n m8.format( '{0} {1} {2} {3}', 'lorem', 'ipsum', 'dolor' ) // returns => \"lorem ipsum dolor \"\n\n```\n\n### m8.got( object:Object, key:String ):Boolean\nReturns `true` if `object` contains `key` based on the `in` operator.\n\nAny type passed to `m8.got` is cast as an Object before checking it contains a specific key. So using `m8.got` instead of simply using the `in` operator can help reduce the chance of error in your code.\n\n```javascript\n\n var foo = { one : 1, two : 2, three : 3 };\n\n m8.got( foo, 'one' ); // returns => true\n\n m8.got( foo, 'four' ); // returns => false\n\n m8.got( foo, '__type__' ); // returns => true\n\n```\n\n### m8.gsub( tpl:String, dictionary:String[]|String{}[, pattern:RegExp] ):String\nReplaces the tokens in the String with the values of the corresponding properties from the passed `dictionary` Object.\n\nAlso accepts an optional second parameter allowing you to define your own token matching `pattern`.\n\nIf a token does not have a value, an empty String is used in its place.\n\n#### Example:\n\n```javascript\n\n m8.gsub( '{one} {two} {three} {four}', { one : 'lorem', two : 'ipsum', three : 'dolor' } ) // returns => \"lorem ipsum dolor \"\n\n```\n\n### m8.guid():String\nGenerates a guid/uuid, the code for this was adapted from [this gist](https://gist.github.com/2295777).\n\n```javascript\n\n\tm8.guid(); // returns something like => \"286cb768-df10-4466-aabf-f5cb4ba406a2\"\n\n```\n\n### m8.has( object:Object, key:String ):Boolean\nShortened version of `Object.prototype.hasOwnProperty.call`.\n\n#### Example:\n\n```javascript\n\n var foo = { one : 1, two : 2, three : 3 };\n\n m8.has( foo, 'one' ); // returns => true\n\n m8.has( foo, 'four' ); // returns => false\n\n m8.has( foo, '__type__' ); // returns => false\n\n```\n\n### m8.id( item:Mixed[, prefix:String] ):String\nReturns the `id` property of the passed item – item can be an Object, HTMLElement, \"JavaScript Class\" instance, etc...\n\nIf an `id` does not exist on the passed `item`, the item is assigned an auto-generated `id` and the value is returned.\n\nIf a `prefix` is supplied then it is used as the prefix for the `id` – if not `anon` is used as the `prefix`.\n\nAn internal counter that is automatically incremented is appended to the end of the `prefix` and is separated from the prefix by a hyphen.\n\n#### Example:\n\n```javascript\n\n var foo = { id : 'foo' },\n bar = { name : 'bar' },\n yum = { nam : 'yum' };\n\n m8.id( foo ); // returns => \"foo\"\n\n m8.id( bar ); // returns => \"anon-1000\"\n\n m8.id( yum, 'yum' ); // returns => \"yum-1001\"\n\n```\n\n### m8.iter( item:Mixed ):Boolean\nReturns `true` if the passed item can be iterated over.\n\n### m8.len( item:Mixed ):Number\nTries the returns the `length` property of the passed `item`.\n\n#### Example:\n\n```javascript\n\n m8.len( { one : 1, two : 2, three : 3 } ); // returns => 3\n\n m8.len( [1, 2, 3] ); // returns => 3\n\n m8.len( 'foobar' ); // returns => 6\n\n m8.len( { one : 1, two : 2, three : 3 } ) === Object.keys( { one : 1, two : 2, three : 3 } ).length\n // returns => true\n\n```\n\n### m8.merge( target:Array|Object, source:Array|Object ):Boolean\nPerforms a \"deep copy\" of all the properties in `source` to `target`, so that `target` does not reference any child Arrays and/ or Objects that belong to `source`.\n\n### m8.nativeType( item:Mixed ):String (alias: m8.ntype)\nReturns the native `type` of the passed item. For normalised types use `m8.type`.\n\n**Note:** All types are **always** in lowercase.\n\n#### Example:\n\n```javascript\n\n m8.nativeType( null ); // returns => \"null\"\n\n m8.nativeType( undefined ); // returns => \"undefined\"\n\n m8.nativeType( [] ); // returns => \"array\"\n\n m8.nativeType( true ); // returns => \"boolean\"\n\n m8.nativeType( new Date() ); // returns => \"date\"\n\n m8.nativeType( function() {} ); // returns => \"function\"\n\n m8.nativeType( 0 ); // returns => \"number\"\n\n m8.type( { enumerable : true, get : function() {} } ); // returns => \"object\"\n\n m8.type( m8.description( window, 'document' ) ); // returns => \"object\"\n\n m8.nativeType( {} ); // returns => \"object\"\n\n m8.nativeType( Object.create( null ) ); // returns => \"object\"\n\n m8.nativeType( /.*/ ); // returns => \"regexp\"\n\n m8.nativeType( '' ); // returns => \"string\"\n\n m8.nativeType( document.createElement( 'div' ) ); // returns => \"htmldivelement\"\n\n m8.nativeType( document.querySelectorAll( 'div' ) ); // returns => \"htmlcollection\" | \"nodelist\"\n\n m8.nativeType( document.getElementsByTagName( 'div' ) ); // returns => \"htmlcollection\" | \"nodelist\"\n\n m8.nativeType( global ); // returns => \"global\"\n\n m8.nativeType( window ); // returns => \"global\" | \"window\"\n\n```\n\n### m8.noop():void\nAn empty Function that returns nothing.\n\n### m8.nativeType( item:Mixed ):String (alias: m8.ntype)\nReturns the native `type` of the passed item. For normalised types use `m8.type`.\n\n**Note:** All types are **always** in lowercase.\n\n#### Example:\n\n```javascript\n\n m8.nativeType( null ); // returns => \"null\"\n\n m8.nativeType( undefined ); // returns => \"undefined\"\n\n m8.nativeType( [] ); // returns => \"array\"\n\n m8.nativeType( true ); // returns => \"boolean\"\n\n m8.nativeType( new Date() ); // returns => \"date\"\n\n m8.nativeType( function() {} ); // returns => \"function\"\n\n m8.nativeType( 0 ); // returns => \"number\"\n\n m8.nativeType( { enumerable : true, get : function() {} } ); // returns => \"object\"\n\n m8.nativeType( m8.description( window, 'document' ) ); // returns => \"object\"\n\n m8.nativeType( {} ); // returns => \"object\"\n\n m8.nativeType( Object.create( null ) ); // returns => \"object\"\n\n m8.nativeType( /.*/ ); // returns => \"regexp\"\n\n m8.nativeType( '' ); // returns => \"string\"\n\n m8.nativeType( document.createElement( 'div' ) ); // returns => \"htmldivelement\"\n\n m8.nativeType( document.querySelectorAll( 'div' ) ); // returns => \"htmlcollection\" | \"nodelist\"\n\n m8.nativeType( document.getElementsByTagName( 'div' ) ); // returns => \"htmlcollection\" | \"nodelist\"\n\n m8.nativeType( global ); // returns => \"global\"\n\n m8.nativeType( window ); // returns => \"global\" | \"window\"\n\n```\n\n### m8.obj( [props:Obejct] ):Object\nCreates 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`.\n\nOptionally pass an Object whose properties you want copied to the empty Object instance.\n\n### m8.ptype( item:Mixed ):String\nReturns the native `type` of the passed item's `__proto__`.\n\n**Note:** All types are **always** in lowercase.\n\n#### Example:\n\n```javascript\n\n m8.ptype( null ); // returns => \"object\"\n\n m8.ptype( undefined ); // returns => \"object\"\n\n m8.ptype( [] ); // returns => \"array\"\n\n m8.ptype( true ); // returns => \"boolean\"\n\n m8.ptype( new Date() ); // returns => \"date\"\n\n m8.ptype( function() {} ); // returns => \"function\"\n\n m8.ptype( 0 ); // returns => \"number\"\n\n m8.ptype( {} ); // returns => \"object\"\n\n m8.ptype( Object.create( null ) ); // returns => \"null\"\n\n m8.ptype( /.*/ ); // returns => \"regexp\"\n\n m8.ptype( '' ); // returns => \"string\"\n\n m8.ptype( document.createElement( 'div' ) ); // returns => \"object\" <- WebKit\n // | \"xpc_..._jsclass\" <- FireFox\n // | \"htmldivelementprototype\" <- MSIE >= 9\n\n m8.ptype( document.querySelectorAll( 'div' ) ); // returns => \"object\" <- WebKit\n // | \"xpc_..._jsclass\" <- FireFox\n // | \"htmlcollectionprototype\" <- MSIE >= 9\n\n m8.ptype( document.getElementsByTagName( 'div' ) ); // returns => \"object\" <- WebKit\n // | \"xpc_..._jsclass\" <- FireFox\n // | \"nodelistprototype\" <- MSIE >= 9\n\n m8.ptype( global ); // returns => \"object\" <- WebKit\n // | \"xpc_..._jsclass\" <- FireFox\n // | \"windowprototype\" <- MSIE >= 9\n\n m8.ptype( window ); // returns => \"object\" <- WebKit\n // | \"xpc_..._jsclass\" <- FireFox\n // | \"windowprototype\" <- MSIE >= 9 (I like the MSIE ones the best!)\n\n```\n\n### m8.range( begin:Number|String, end:Number|String ):Array\nReturns an Array starting at `begin` where each value is incremented by `1` until `end` is reached.\n\n#### Example:\n\n```javascript\n\n m8.range( 1, 10 ); // returns => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n m8.range( 20, 1000 ); // returns => [20, 21, 22, ..., 1000]\n\n m8.range( 'A', 'z' ); // returns => ['A', 'B', 'C', ..., 'x', 'y', 'z']\n m8.range( 'α', 'ω' ); // returns => ['α', 'β', 'γ', ..., 'χ', 'ψ', 'ω']\n\n```\n\n**NOTE:** Only the first character will be incremented in a `String` range.\n\n## m8.remove( item:Array, value_or_index1:Number|Mixed|Number[]|Mixed[][, value_or_index2:Number|Mixed, ..., value_or_indexN:Number|Mixed] ):item\n## m8.remove( item:Object, property1:String|String[][, property2:String, ..., propertyN:String] ):item\nRemoves items from the passed Array or Object and returns the passed Array or Object.\n\nIf removing items from an Array, you can either pass the index of the item you want to remove or the item itself.\nIf removing items from an Object, you simply pass the key of the item you want to remove.\n\n#### Example:\n\n```javascript\n\n var foo_arr = ['one', 'two', 'three'],\n foo_obj = { one : 1, two : 2, three : 3 };\n\n m8.remove( foo_arr, 'one', 'three' ); // returns => ['two']\n\n m8.remove( foo_arr, ['one', 'three'] ); // same as above\n\n m8.remove( foo_arr, 0, 2 ); // same as above\n\n m8.remove( foo_arr, [0, 2] ); // same as above\n\n m8.remove( foo_obj, 'one', 'three' ); // returns => { two : 2 }\n\n m8.remove( foo_obj, ['one', 'three'] ); // same as above\n\n```\n\n### m8.tostr( item:Mixed ):String\nShortened version of `Object.prototype.toString.call`.\n\n### m8.type( item:Mixed ):String\nReturns the normalised `type` of the passed item.\n\n**Note:** All types are **always** in lowercase.\n\n#### Example:\n\n```javascript\n\n m8.type( null ); // returns => false\n\n m8.type( undefined ); // returns => false\n\n m8.type( [] ); // returns => \"array\"\n\n m8.type( true ); // returns => \"boolean\"\n\n m8.type( new Date() ); // returns => \"date\"\n\n m8.type( { enumerable : true, get : function() {} } ); // returns => \"descriptor\"\n\n m8.type( m8.description( window, 'document' ) ); // returns => \"descriptor\"\n\n m8.type( function() {} ); // returns => \"function\"\n\n m8.type( 0 ); // returns => \"number\"\n\n m8.type( NaN ); // returns => \"nan\"\n\n m8.type( Object.create( null ) ); // returns => \"nullobject\"\n\n m8.type( {} ); // returns => \"object\"\n\n m8.type( /.*/ ); // returns => \"regexp\"\n\n m8.type( '' ); // returns => \"string\"\n\n m8.type( document.createElement( 'div' ) ); // returns => \"htmlelement\"\n\n m8.type( document.querySelectorAll( 'div' ) ); // returns => \"htmlcollection\"\n\n m8.type( document.getElementsByTagName( 'div' ) ); // returns => \"htmlcollection\"\n\n m8.type( global ); // returns => \"global\"\n\n m8.type( window ); // returns => \"global\"\n\n```\n\n### m8.update( target:Array|Object, source:Array|Object ):Boolean\nPerforms a \"deep copy\" of all the properties in `source` **that are not already contained in** `target`, so that `target` does not reference any child Arrays and/ or Objects that belong to `source`.\n\nThis works similarly to `m8.merge` except that existing properties are not overwritten.\n\n## static properties\n\n### m8.ENV:String\nInternally `m8` tries to figure out what environment it is currrently being run in.\n\n`m8.ENV` is a String representation of what environment `m8` is assuming it is running in.\n\n#### Environments:\n<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t<thead><tr><th>env</th><th>description</th></tr></thead>\n\t<tbody>\n\t\t<tr><td><strong>browser</strong></td><td>m8 is being used within a web browser.</td></tr>\n\t\t<tr><td><strong>commonjs</strong></td><td>m8 is being used within a commonjs style architecture (e.g. nodejs).</td></tr>\n\t\t<tr><td><strong>other</strong></td><td>m8 has no idea where the fudge it is.</td></tr>\n\t<tbody>\n</table>\n\n### m8.global:Global\nA reference to the global Object, this will be `window` in a web browser and `global` in nodejs.\n\nm8 uses the `\"use strict\";` directive, so having a reference to the global Object is handy.\n\n### m8.modes:Object\n`m8.modes` is an Object containing all the variations on different permissions a property may have when assigned using `Object.defineProperty`.\n\nSee `m8.describe` above for more information on how to use `m8.modes` to create property descriptors compatible with `Object.defineProperty`.\n\n#### Available modes are:\n<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n\t<thead><tr><th>mode</th><th>configurable</th><th>enumerable</th><th>writeable</th></tr></thead>\n\t<tbody>\n\t\t<tr><td><strong>r</strong></td><td>false</td><td>false</td><td>false</td></tr>\n\t\t<tr><td><strong>ce</strong></td><td>true</td><td>true</td><td>false</td></tr>\n\t\t<tr><td><strong>cw</strong></td><td>true</td><td>false</td><td>true</td></tr>\n\t\t<tr><td><strong>ew</strong></td><td>false</td><td>true</td><td>true</td></tr>\n\t\t<tr><td><strong>cew</strong></td><td>true</td><td>true</td><td>true</td></tr>\n\t<tbody>\n</table>\n\n**NOTE:** You can supply the characters for a specific mode in any order.\n\n## Extensions to JavaScript Natives\n\n### Array.coerce( value:Mixed[, index_from:Number[, index_to:Number]] ):Array\nAttempts to coerce the passed value into and Array.\n\nIf the value cannot be coerced, an Array is returned with the value as the first and only item in the Array.\n\nThe most common Types which can be coerced into Arrays are: `HtmlCollection`/ `NodeList` and Function `Arguments`.\n\nIf a `index_from` is a valid Number, then `Array.coerce` will attempt to return a slice of the returned Array starting from the Number provided.\n\nIf a `index_to` is a valid Number, then `Array.coerce` will attempt to return a slice of the returned Array starting from the Number provided by `index_from` and ending at `index_to` provided.\n\n#### Example:\n\n```html\n\n <body>\n <div id=\"one\"></div>\n <div id=\"two\"></div>\n <div id=\"three\"></div>\n </body>\n\n```\n\n```javascript\n\n Array.coerce( document.body.children ); // returns => [div#one, div#two, div#three]\n\n Array.coerce( document.body.querySelectorAll( '*' ) ); // returns => [div#one, div#two, div#three]\n\n Array.coerce( function( a, b, c ) { return arguments; }( 1, 2, 3 ) ); // returns => [1, 2, 3]\n\n Array.coerce( { one : 1, two : 2, three : 3 } ); // returns => [{ one : 1, two : 2, three : 3 }]\n\n Array.coerce( [1, 2, 3, 4, 5, 6, 7], 3 ); // returns => [4, 5, 6, 7]\n\n Array.coerce( [1, 2, 3, 4, 5, 6, 7], 3, 0 ); // returns => [4, 5, 6, 7]\n\n Array.coerce( [1, 2, 3, 4, 5, 6, 7], 1, 3 ); // returns => [2, 3]\n\n Array.coerce( [1, 2, 3, 4, 5, 6, 7], 3, 2 ); // returns => [4, 5]\n\n Array.coerce( [1, 2, 3, 4, 5, 6, 7], 3, -1 ); // returns => [4, 5, 6]\n\n```\n\n### Array.prototype.find( iterator:Function[, context:Object] ):Mixed\nReturns the first item in the Array that returns a \"truthy\" value when executing the passed `iterator` function over the Array, or `null` if none is found.\n\n#### Example:\n\n```javascript\n\n [1, 2, 3, 4].find( function( value ) { return value > 2; } ); // returns => 3\n\n [1, 2, 3, 4].find( function( value, index ) { return value > 2 && index > 2; } ); // returns => 4\n\n [1, 2, 3, 4].find( function( value ) { return value > 4; } ); // returns => null\n\n```\n\n**REMEMBER:** The ACTUAL item in the Array is returned, **NOT** the `iterator`'s return value.\n\n### Array.prototype.invoke( method:String[, arg1:Mixed, arg2:Mixed, ..., argN:Mixed] ):Array\nExecutes the passed `method` — **NOTE:** `method` is a String, and should be the name of `method` that exists on each item in the Array — passing any extra arguments to each method call.\n\n#### Example:\n\n```javascript\n\n ['lorem', 'ipsum', 'dolor', 'sit', 'amet'].invoke( 'toUpperCase' ); // returns => [\"LOREM\", \"IPSUM\", \"DOLOR\", \"SIT\", \"AMET\"]\n\n [1, 2, 3, 4, 5, 6, 7, 8].invoke( 'toString', 2 ); // returns => ['1', '10', '11', '100', '101', '110', '111', '1000']\n\n```\n\n### Array.prototype.pluck( key:String[, compact:Boolean] ):Array\nReturns a new Array where all the items are the values of the passed property `key`.\n\nIf `compact` is set to `true` then all `NaN`, `null` and `undefined` values will be omitted from the returned Array.\n\n**NOTE:** Unlike other `pluck` implementations, this implementation has a \"smarter\" way to get property values, allows you to `pluck` nested Object values, as well as HTML attributes.\n\n#### Example:\n\n```javascript\n\n var data = [{ data : { value : 'foo' } }, { data : { value : 'bar' } }, {}, { value : 'blim' }, { data : { value : 'blam' } }];\n\n// slower, has to iterate twice\n data.pluck( 'data' ).pluck( 'value' ); // returns => [\"foo\", \"bar\", undefined, undefined, \"blam\"]\n\n// optimised version of the above\n data.pluck( 'data.value' ); // returns => [\"foo\", \"bar\", undefined, undefined, \"blam\"]\n\n data.pluck( 'data.value', true ); // returns => [\"foo\", \"bar\", \"blam\"]\n\n```\n\n### Boolean.coerce( value:Mixed ):Boolean\nHandy for working with Booleans trapped in Strings.\n\nReturns a normalised Boolean value for a String, Number, null or undefined.\n\nEverything will return `true`, except for the following which all return `false`:\n\n```javascript\n\n Boolean.coerce( 'false' ); Boolean.coerce( false );\n\n Boolean.coerce( '0' ); Boolean.coerce( 0 );\n\n Boolean.coerce( 'NaN' ); Boolean.coerce( NaN );\n\n Boolean.coerce( 'null' ); Boolean.coerce( null );\n\n Boolean.coerce( 'undefined' ); Boolean.coerce( undefined );\n\n Boolean.coerce(); Boolean.coerce( '' );\n\n```\n\n### GET: Function.prototype.\\_\\_name\\_\\_:String\n### GET: Function.prototype.\\_\\_name\\_\\_:String\nTries to return the name of a Function instance. If a function is mimicking another function, then that function's name is returned.\n\nIf no name can be resolved, then `anonymous` is returned.\n\n### Function.prototype.mimic( fn:Function[, name:String] ):Function\nHandy for working with wrapper methods, allows a function to mimics another, by over-writing its `toString` and `valueOf` methods.\n\nThe `displayName` property used by web inspector to allow assigning names to anonymous functions is also set.\n\nIf a `name` param is passed, then it is used as the `displayName`, otherwise the passes function's name is used.\n\n#### Example:\n\n```javascript\n\n function foo( a, b, c ) { ... }\n\n foo.__name__; // returns => \"foo\"\n\n ( function( a, b, c ) { ... } ).__name__; // returns => \"anonymous\"\n\n function bar( a, b, c ) { ... }.mimic( foo ).__name__; // returns => \"foo\"\n\n```\n\n## Object.key( object:Object, value:Mixed ):String\nReturns the `object`'s property `key` for the passed `value` if `value` is a property of `object`. If not `null` is returned.\n\n**NOTE:** `value` is determined based on the `===` operator.\n\n#### Example:\n\n```javascript\n\n var foo = { one : 1, two : 2, three : 3 };\n\n Object.key( foo, 2 ); // returns => \"two\"\n\n Object.key( foo, 4 ); // returns => null\n\n```\n\n### Object.reduce( object:Object, iterator:Function, value:Mixed ):Mixed\nThis is similar to [Array.reduce](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/reduce) except that it is used on Objects instead of Arrays.\n\nThe `iterator` Function will receive 5 arguments:\n\n<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n\t<tr><td>previous_value</td><td>When the <code>iterator</code> Function is first called, this will be the initially supplied <code>value</code>, after which it will be previous value returned by the <code>iterator</code> Function.</td></tr>\n\t<tr><td>value</td><td>The value of the item currently being iterated over.</td></tr>\n\t<tr><td>key</td><td>The key of the item currently being iterated over.</td></tr>\n\t<tr><td>object</td><td>The Object being iterated over.</td></tr>\n\t<tr><td>index</td><td>The zero based index of the item currently being iterated over.</td></tr>\n</table>\n\n#### Example:\n\n```javascript\n\n// the sum of all values of the passed object\n Object.reduce( { one : 1, two : 2, three : 3 }, function( previous_value, value, key, index, object ) {\n console.log( 'previous_value : ', previous_value, ', value : ', value, ', key : ', key, ', index : ', index );\n\t\treturn previous_value += value;\n }, 0 );\n// logs => previous_value : 0, value : 1, key : one, index : 0\n// logs => previous_value : 1, value : 2, key : two, index : 1\n// logs => previous_value : 3, value : 3, key : three, index : 2\n// returns => 6\n\n```\n\n**NOTE:** `Object.reduce` is the only Object iterator included in `m8` because it is the most powerful.\nApart from `every` & `some` you can use `reduce` to implement the same functionality available in all other ES5 Array iterators.\n\nThis will help keep the file size down.\n\n### Object.value( object:Object, path:String ):Mixed\nReturns the property value at the specified path in an Object.\n\n#### Example:\n\n```javascript\n\n var data = { one : { two : { three : true, four : [1, 2, 3, 4] } } };\n\n Object.value( data, 'one' ); // returns => { two : { three : true, four : [1, 2, 3, 4] } }\n\n Object.value( data, 'one.two' ); // returns => { three : true, four : [1, 2, 3, 4] }\n\n Object.value( data, 'one.two.three' ); // returns => { three : true }\n\n Object.value( data, 'one.two.four' ); // returns => [1, 2, 3, 4]\n\n Object.value( data, 'one.two.four.2' ); // returns => 3\n\n```\n\n### Object.values( object:Object ):Array\nReturns the `values` of the passed Object based on it's enumerable keys.\n\n#### Example:\n\n```javascript\n\n Object.values( { one : 1, two : 2, three : 3 } ); // returns => [1,2,3]\n\n```\n\n### GET: Object.prototype.\\_\\_proto\\_\\_:String\nSome browsers — like MSIE 9 & 10 which `m8` supports — do not support the non-standard property `__proto__`.\n\nLuckily however, they do support `Object.getPrototypeOf`, which will return the same value as `__proto__`.\n\n`m8` conveniently wraps this call up inside the `__proto__` getter for those browsers, so you can (more) easily work with `Object` prototypes.\n\n### GET: Object.prototype.\\_\\_type\\_\\_:String\nAttempts to resolve a normalised type for any type that inherits from JavaScript's `Object.prototype`. See `m8.type` for more information.\n\n**NOTE:** All types are **always** in lowercase\n\n## File size\n\n- m8.js ≅ 6.9kb (gzipped)\n- m8.min.js ≅ 3.7kb (minzipped)\n\n## License\n\n(The MIT License)\n\nCopyright © 2012 christos \"constantology\" constandinou http://muigui.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n",
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/constantology/m8/issues"
},
"homepage": "https://github.com/constantology/m8",
"_id": "m8@0.4.4",
"_from": "m8@>= 0.4.3"
}