Comparing version 0.0.1 to 0.0.2
@@ -14,3 +14,9 @@ (function () { | ||
* | ||
* ##Why Is Extender Different? | ||
* | ||
* Extender is different than normal chaining because is does more than return `this`. It decorates your values in a type safe manner. | ||
* | ||
* For example if you return an array from a string based method then the returned value will be decorated with array methods and not the string methods. This allow you as the developer to focus on your API and not worrying about how to properly build and connect your API. | ||
* | ||
* | ||
* ##Installation | ||
@@ -52,4 +58,3 @@ * | ||
* | ||
* var myExtender = | ||
* .define(isString, { | ||
* var myExtender = extender.define(isString, { | ||
* multiply: function (str, times) { | ||
@@ -72,3 +77,3 @@ * var ret = str; | ||
* | ||
* If do not specify a tester function and just pass in an object of `functions` then all values passed in will be decorated with methods. | ||
* If you do not specify a tester function and just pass in an object of `functions` then all values passed in will be decorated with methods. | ||
* | ||
@@ -170,2 +175,27 @@ * ```javascript | ||
* | ||
* **`noWrap`** | ||
* | ||
* `extender` also allows you to specify methods that should not have the value wrapped providing a cleaner exit function other than `value()`. | ||
* | ||
* For example suppose you have an API that allows you to build a validator, rather than forcing the user to invoke the `value` method you could add a method called `validator` which makes more syntactic sense. | ||
* | ||
* ``` | ||
* | ||
* var myValidator = extender.define({ | ||
* //chainable validation methods | ||
* //... | ||
* //end chainable validation methods | ||
* | ||
* noWrap : { | ||
* validator : function(){ | ||
* //return your validator | ||
* } | ||
* } | ||
* }); | ||
* | ||
* myValidator().isNotNull().isEmailAddress().validator(); //now you dont need to call .value() | ||
* | ||
* | ||
* ``` | ||
* | ||
* **Using `instanceof`** | ||
@@ -261,2 +291,41 @@ * | ||
function addNoWrapMethod(proto, name, func) { | ||
if ("function" !== typeof func) { | ||
throw new TypeError("when extending type you must provide a function"); | ||
} | ||
var extendedMethod; | ||
if (name === "constructor") { | ||
extendedMethod = function () { | ||
var args = slice.call(arguments); | ||
this._super(arguments); | ||
func.apply(this, arguments); | ||
} | ||
} else { | ||
extendedMethod = function extendedMethod() { | ||
var args = slice.call(arguments); | ||
args.unshift(this._value) | ||
return func.apply(this, args); | ||
} | ||
} | ||
proto[name] = extendedMethod | ||
} | ||
function decorateProto(proto, decoration, nowrap) { | ||
for (var i in decoration) { | ||
if (decoration.hasOwnProperty(i)) { | ||
if (i !== "getters" && i !== "setters") { | ||
if (i === "noWrap") { | ||
decorateProto(proto, decoration[i], true); | ||
} else if (nowrap) { | ||
addNoWrapMethod(proto, i, decoration[i]) | ||
} else { | ||
addMethod(proto, i, decoration[i]); | ||
} | ||
} else { | ||
proto[i] = decoration[i]; | ||
} | ||
} | ||
} | ||
} | ||
function _extender(obj) { | ||
@@ -287,7 +356,3 @@ var ret = obj; | ||
var proto = {}; | ||
for (var i in decorate) { | ||
if (decorate.hasOwnProperty(i)) { | ||
addMethod(proto, i, decorate[i]); | ||
} | ||
} | ||
decorateProto(proto, decorate); | ||
defined.push([tester, proto]); | ||
@@ -294,0 +359,0 @@ return _extender; |
{ | ||
"name": "extender", | ||
"version": "0.0.1", | ||
"version": "0.0.2", | ||
"description": "Easily create object decorators!", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -9,3 +9,9 @@ <a name="top"></a> | ||
##Why Is Extender Different? | ||
Extender is different than normal chaining because is does more than return `this`. It decorates your values in a type safe manner. | ||
For example if you return an array from a string based method then the returned value will be decorated with array methods and not the string methods. This allow you as the developer to focus on your API and not worrying about how to properly build and connect your API. | ||
##Installation | ||
@@ -47,4 +53,3 @@ | ||
var myExtender = | ||
.define(isString, { | ||
var myExtender = extender.define(isString, { | ||
multiply: function (str, times) { | ||
@@ -67,3 +72,3 @@ var ret = str; | ||
If do not specify a tester function and just pass in an object of `functions` then all values passed in will be decorated with methods. | ||
If you do not specify a tester function and just pass in an object of `functions` then all values passed in will be decorated with methods. | ||
@@ -165,2 +170,27 @@ ```javascript | ||
**`noWrap`** | ||
`extender` also allows you to specify methods that should not have the value wrapped providing a cleaner exit function other than `value()`. | ||
For example suppose you have an API that allows you to build a validator, rather than forcing the user to invoke the `value` method you could add a method called `validator` which makes more syntactic sense. | ||
``` | ||
var myValidator = extender.define({ | ||
//chainable validation methods | ||
//... | ||
//end chainable validation methods | ||
noWrap : { | ||
validator : function(){ | ||
//return your validator | ||
} | ||
} | ||
}); | ||
myValidator().isNotNull().isEmailAddress().validator(); //now you dont need to call .value() | ||
``` | ||
**Using `instanceof`** | ||
@@ -179,1 +209,10 @@ | ||
To see more examples click [here](https://github.com/doug-martin/extender/tree/master/examples) | ||
@@ -38,2 +38,17 @@ "use strict"; | ||
return str.split(delim); | ||
}, | ||
noWrap: { | ||
multiplyPlain: function (str, times) { | ||
var ret = str; | ||
for (var i = 1; i < times; i++) { | ||
ret += str; | ||
} | ||
return ret; | ||
}, | ||
toArrayPlain: function (str, delim) { | ||
delim = delim || ""; | ||
return str.split(delim); | ||
} | ||
} | ||
@@ -48,2 +63,12 @@ }) | ||
return ret; | ||
}, | ||
noWrap: { | ||
pluckPlain: function (arr, m) { | ||
var ret = []; | ||
for (var i = 0, l = arr.length; i < l; i++) { | ||
ret.push(arr[i][m]); | ||
} | ||
return ret; | ||
} | ||
} | ||
@@ -55,2 +80,8 @@ }) | ||
return !val; | ||
}, | ||
noWrap: { | ||
invertPlain: function (val) { | ||
return !val; | ||
} | ||
} | ||
@@ -90,2 +121,12 @@ | ||
it.should("not wrap methods in noWrap", function () { | ||
assert.equal(myExtender("hello").multiplyPlain(5), "hellohellohellohellohello"); | ||
assert.isFalse(myExtender(true).invertPlain()); | ||
assert.deepEqual(myExtender([ | ||
{a: "a"}, | ||
{a: "b"}, | ||
{a: "c"} | ||
]).pluckPlain("a"), ["a", "b", "c"]); | ||
}); | ||
it.should("keep extenders in their own scope", function () { | ||
@@ -92,0 +133,0 @@ var myExtender = extender |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
584
214
27948
10