util: store chainable behavior in a __methods object on ctx

This commit is contained in:
Max Edmands 2013-12-01 09:55:01 -08:00
parent 76ac685d5a
commit 270f9d92d9
2 changed files with 13 additions and 27 deletions

View file

@ -54,21 +54,21 @@ var call = Function.prototype.call,
* @api public
*/
module.exports = addChainableMethod = function (ctx, name, method, chainingBehavior) {
if (typeof chainingBehavior !== 'function')
module.exports = function (ctx, name, method, chainingBehavior) {
if (typeof chainingBehavior !== 'function') {
chainingBehavior = function () { };
}
var chainableBehavior = {
ctx: ctx
, method: method
method: method
, chainingBehavior: chainingBehavior
};
// save the methods so we can overwrite them later, if we need to.
if (!addChainableMethod.methods[name])
addChainableMethod.methods[name] = [];
addChainableMethod.methods[name].push(chainableBehavior);
if (!ctx.__methods) {
ctx.__methods = {};
}
ctx.__methods[name] = chainableBehavior;
Object.defineProperty(ctx, name,
{ get: function () {
@ -104,5 +104,3 @@ module.exports = addChainableMethod = function (ctx, name, method, chainingBehav
, configurable: true
});
};
addChainableMethod.methods = {};

View file

@ -4,8 +4,6 @@
* MIT Licensed
*/
var addChainableMethod = require('./addChainableMethod');
/**
* ### overwriteChainableMethod (ctx, name, fn)
*
@ -39,26 +37,16 @@ var addChainableMethod = require('./addChainableMethod');
*/
module.exports = function (ctx, name, method, chainingBehavior) {
var index = 0;
var chainableMethods = addChainableMethod.methods[name];
var chainableBehavior = ctx.__methods[name];
// doing a brute-force sequential search for the reference to the object in
// question, so we can get its original method and chaining behavior. yep.
// there is a danger of this running very slowly (O of n), but it's difficult
// for me to imagine n ever getting longer than, well, 1.
while(index < chainableMethods.length) {
if (chainableMethods[index].ctx === ctx) break;
++index;
}
var _chainingBehavior = chainableMethods[index].chainingBehavior;
chainableMethods[index].chainingBehavior = function () {
var _chainingBehavior = chainableBehavior.chainingBehavior;
chainableBehavior.chainingBehavior = function () {
var result = chainingBehavior(_chainingBehavior).call(this);
return result === undefined ? this : result;
};
var _method = chainableMethods[index].method;
chainableMethods[index].method = function () {
var _method = chainableBehavior.method;
chainableBehavior.method = function () {
var result = method(_method).apply(this, arguments);
return result === undefined ? this : result;
};