custom-ability
Advanced tools
Comparing version 1.2.3 to 1.3.0
@@ -21,3 +21,3 @@ (function() { | ||
module.exports = function(abilityClass, aCoreMethod, isGetClassFunc) { | ||
var abilityFn; | ||
var abilityFn, filter, getAdditionalAbility; | ||
if (isBoolean(aCoreMethod)) { | ||
@@ -28,3 +28,3 @@ isGetClassFunc = aCoreMethod; | ||
abilityFn = function(aClass, aOptions) { | ||
var AbilityClass, filter, filterMethods, vAbility, vCoreMethod, vExcludes, vIncludes, vName; | ||
var $abilities, AbilityClass, filterMethods, i, vAbilities, vExcludes, vFilter, vHasAddtionalAbility, vIncludes, vName, vOptions, vhasCoreMethod; | ||
AbilityClass = abilityClass; | ||
@@ -38,21 +38,15 @@ if (isGetClassFunc === true) { | ||
vName = AbilityClass.name; | ||
vCoreMethod = isArray(aCoreMethod) ? aCoreMethod[0] : aCoreMethod; | ||
vhasCoreMethod = aClass.prototype[(isArray(aCoreMethod) ? aCoreMethod[0] : aCoreMethod)]; | ||
if (vName && aClass.prototype.$abilities) { | ||
$abilities = aClass.prototype.$abilities; | ||
} | ||
vHasAddtionalAbility = vName && $abilities && $abilities[vName]; | ||
if (aClass == null) { | ||
aClass = AbilityClass; | ||
} else if (!((vCoreMethod && aClass.prototype[vCoreMethod]) || (vName && aClass.prototype.$abilities && aClass.prototype.$abilities['$' + vName]))) { | ||
if (!(aOptions && aOptions.inited) && vName && aClass.prototype.$abilities && (vAbility = aClass.prototype.$abilities[vName])) { | ||
if (aOptions) { | ||
aOptions.inited = true; | ||
} else { | ||
aOptions = { | ||
inited: true | ||
}; | ||
} | ||
return vAbility(aClass, aOptions); | ||
} | ||
} else if (!(vhasCoreMethod || ($abilities && $abilities['$' + vName]))) { | ||
if (vName) { | ||
if (!aClass.prototype.$abilities) { | ||
defineProperty(aClass.prototype, '$abilities', {}); | ||
if (!$abilities) { | ||
defineProperty(aClass.prototype, '$abilities', $abilities = {}); | ||
} | ||
aClass.prototype.$abilities['$' + vName] = abilityFn; | ||
$abilities['$' + vName] = abilityFn; | ||
} | ||
@@ -86,16 +80,4 @@ if ((aOptions == null) || !(aOptions.include || aOptions.exclude)) { | ||
} | ||
filter = function(k) { | ||
var result; | ||
result = vIncludes.length; | ||
if (result) { | ||
result = __indexOf.call(vIncludes, k) >= 0; | ||
if (!result && vExcludes.length) { | ||
result = !(__indexOf.call(vExcludes, k) >= 0); | ||
} | ||
} else if (vExcludes.length) { | ||
result = !(__indexOf.call(vExcludes, k) >= 0); | ||
} else { | ||
result = true; | ||
} | ||
return result; | ||
vFilter = function(k) { | ||
return filter(k, vIncludes, vExcludes); | ||
}; | ||
@@ -106,3 +88,3 @@ filterMethods = function(methods) { | ||
for (k in methods) { | ||
if (!filter(k)) { | ||
if (!vFilter(k)) { | ||
delete methods[k]; | ||
@@ -113,13 +95,45 @@ } | ||
}; | ||
extendFilter(aClass, AbilityClass, filter); | ||
extendFilter(aClass.prototype, AbilityClass.prototype, filter); | ||
if (vHasAddtionalAbility) { | ||
vAbilities = getAdditionalAbility(aClass, vName); | ||
i = vAbilities.length; | ||
while (--i >= 0) { | ||
vOptions = vAbilities[i](); | ||
if (vOptions != null) { | ||
filterMethods(vOptions.methods); | ||
filterMethods(vOptions.classMethods); | ||
if (vOptions.methods instanceof Object) { | ||
injectMethods(aClass.prototype, vOptions.methods, vOptions); | ||
} | ||
if (vOptions.classMethods instanceof Object) { | ||
injectMethods(aClass, vOptions.classMethods, vOptions); | ||
} | ||
} | ||
} | ||
} | ||
extendFilter(aClass, AbilityClass, vFilter); | ||
extendFilter(aClass.prototype, AbilityClass.prototype, vFilter); | ||
filterMethods(aOptions.methods); | ||
filterMethods(aOptions.classMethods); | ||
} | ||
if (vHasAddtionalAbility && !vAbilities) { | ||
vAbilities = getAdditionalAbility(aClass, vName); | ||
i = vAbilities.length; | ||
while (--i >= 0) { | ||
vOptions = vAbilities[i](); | ||
if (vOptions != null) { | ||
if (vOptions.methods instanceof Object) { | ||
injectMethods(aClass.prototype, vOptions.methods, vOptions); | ||
} | ||
if (vOptions.classMethods instanceof Object) { | ||
injectMethods(aClass, vOptions.classMethods, vOptions); | ||
} | ||
} | ||
} | ||
} | ||
if (aOptions != null) { | ||
if (aOptions.methods instanceof Object) { | ||
injectMethods(aClass.prototype, aOptions.methods); | ||
injectMethods(aClass.prototype, aOptions.methods, aOptions); | ||
} | ||
if (aOptions.classMethods instanceof Object) { | ||
injectMethods(aClass, aOptions.classMethods); | ||
injectMethods(aClass, aOptions.classMethods, aOptions); | ||
} | ||
@@ -130,2 +144,30 @@ } | ||
}; | ||
abilityFn.filter = filter = function(k, aIncludes, aExcludes) { | ||
var result; | ||
result = aIncludes.length; | ||
if (result) { | ||
result = __indexOf.call(aIncludes, k) >= 0; | ||
if (!result && aExcludes.length) { | ||
result = !(__indexOf.call(aExcludes, k) >= 0); | ||
} | ||
} else if (aExcludes.length) { | ||
result = !(__indexOf.call(aExcludes, k) >= 0); | ||
} else { | ||
result = true; | ||
} | ||
return result; | ||
}; | ||
getAdditionalAbility = function(aClass, aName) { | ||
var result, vAbility; | ||
result = []; | ||
while (aClass && aClass.prototype) { | ||
if (aClass.prototype.hasOwnProperty('$abilities')) { | ||
if (vAbility = aClass.prototype.$abilities[aName]) { | ||
result.push(vAbility); | ||
} | ||
} | ||
aClass = aClass.super_; | ||
} | ||
return result; | ||
}; | ||
return abilityFn; | ||
@@ -132,0 +174,0 @@ }; |
{ | ||
"name": "custom-ability", | ||
"version": "1.2.3", | ||
"version": "1.3.0", | ||
"description": "make custom ability more easy. generate the ability which can be added to any class directly.", | ||
@@ -20,3 +20,3 @@ "homepage": "https://github.com/snowyu/custom-ability.js", | ||
"inherits-ex": "~1.0.6", | ||
"util-ex": "~0.2.8" | ||
"util-ex": "~0.2.9" | ||
}, | ||
@@ -23,0 +23,0 @@ "devDependencies": { |
@@ -41,11 +41,66 @@ ### custom-ability [![Build Status](https://img.shields.io/travis/snowyu/custom-ability.js/master.png)](http://travis-ci.org/snowyu/custom-ability.js) [![npm](https://img.shields.io/npm/v/custom-ability.svg)](https://npmjs.org/package/custom-ability) [![downloads](https://img.shields.io/npm/dm/custom-ability.svg)](https://npmjs.org/package/custom-ability) [![license](https://img.shields.io/npm/l/custom-ability.svg)](https://npmjs.org/package/custom-ability) | ||
* key: the method name to hook. | ||
* value: the new method function | ||
* value: the new method function, if original method is exists or not in replacedMethods: | ||
* use `this.super()` to call the original method. | ||
* `this.self` is the original `this` object. | ||
* `classMethods` *(object)*: hooked class methods to the class | ||
* `replacedMethods` *(array)*: the method name in the array will be replaced the original | ||
method directly. | ||
# Specification | ||
## V1.2.x | ||
## V1.3.x | ||
+ add the replaceMethods option to custom ability function. | ||
* **<broken change>**: additional abilities usage changed | ||
* separate ability options object. | ||
* Put the '$abilities'*(object)* property on your prototype of class if need to modify | ||
the class before apply ability. | ||
* the `$abilities` object key is the AbilityClass Name | ||
* the value is the function to return the **ability options object**. | ||
```coffee | ||
AbstractObject = require('./lib/abstract-object') | ||
AbstractObject.$abilities = { | ||
# "Eventable" is the AbilityClass name | ||
# the value is modified ability function. | ||
Eventable: require('./lib/eventable-options') | ||
} | ||
module.exports = AbstractObject | ||
``` | ||
the [eventable-options.coffee](https://github.com/snowyu/abstract-object/blob/master/src/eventable-options.coffee) file: | ||
```coffee | ||
# eventable-options.coffee | ||
module.exports = (aOptions)-> | ||
aOptions = {} unless aOptions | ||
aOptions.methods = {} unless aOptions.methods | ||
extend aOptions.methods, | ||
# override methods: | ||
setObjectState: (value, emitted = true)-> | ||
self= @self | ||
@super.call(self, value) | ||
self.emit value, self if emitted | ||
return | ||
... | ||
return aOptions | ||
# more detail on [AbstractObject/src/eventable-options.coffee](https://github.com/snowyu/abstract-object) | ||
``` | ||
the AbstractObject's 'eventable' function: | ||
```coffee | ||
eventable = require 'events-ex/eventable' | ||
eventableOptions = require './eventable-options' | ||
module.exports = (aClass, aOptions)-> | ||
eventable aClass, eventableOptions(aOptions) | ||
``` | ||
## V1.2.x *(deprecated)* | ||
* Put the 'ability.js' file in your NPM Package folder which means this can be | ||
@@ -183,5 +238,14 @@ as ability. So you can use this way to get the ability: | ||
eventable = require 'events-ex/eventable' | ||
eventableOptions = require './eventable-options' | ||
module.exports = (aClass)-> | ||
eventable aClass, methods: | ||
module.exports = (aClass, aOptions)-> | ||
eventable aClass, eventableOptions(aOptions) | ||
``` | ||
```coffee | ||
# eventable-options.coffee | ||
module.exports = (aOptions)-> | ||
aOptions = {} unless aOptions | ||
aOptions.methods = {} unless aOptions.methods | ||
extend aOptions.methods, | ||
# override methods: | ||
@@ -193,3 +257,5 @@ setObjectState: (value, emitted = true)-> | ||
return | ||
# more detail on [AbstractObject/src/eventable](https://github.com/snowyu/abstract-object) | ||
... | ||
return aOptions | ||
# more detail on [AbstractObject/src/eventable-options.coffee](https://github.com/snowyu/abstract-object) | ||
``` | ||
@@ -217,5 +283,5 @@ | ||
# "Eventable" is the AbilityClass name | ||
Eventable: require('./eventable') | ||
Eventable: require('./lib/eventable-options') | ||
module.exports = AbstractObject | ||
``` |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
35897
177
284
Updatedutil-ex@~0.2.9