mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-01 23:57:49 +00:00
Add explicit chaining support to Lo-Dash. [closes #325]
Former-commit-id: 58d01723ddc40f636af9954e5a9f6370e0c88aac
This commit is contained in:
76
build.js
76
build.js
@@ -653,72 +653,6 @@
|
||||
* @returns {String} Returns the modified source.
|
||||
*/
|
||||
function addUnderscoreChaining(source) {
|
||||
// add `_.chain`
|
||||
source = source.replace(matchFunction(source, 'tap', true), function(match) {
|
||||
var indent = getIndent(match);
|
||||
return match && (indent + [
|
||||
'',
|
||||
'/**',
|
||||
' * Creates a `lodash` object that wraps the given `value`.',
|
||||
' *',
|
||||
' * @static',
|
||||
' * @memberOf _',
|
||||
' * @category Chaining',
|
||||
' * @param {Mixed} value The value to wrap.',
|
||||
' * @returns {Object} Returns the wrapper object.',
|
||||
' * @example',
|
||||
' *',
|
||||
' * var stooges = [',
|
||||
" * { 'name': 'moe', 'age': 40 },",
|
||||
" * { 'name': 'larry', 'age': 50 },",
|
||||
" * { 'name': 'curly', 'age': 60 }",
|
||||
' * ];',
|
||||
' *',
|
||||
' * var youngest = _.chain(stooges)',
|
||||
' * .sortBy(function(stooge) { return stooge.age; })',
|
||||
" * .map(function(stooge) { return stooge.name + ' is ' + stooge.age; })",
|
||||
' * .first();',
|
||||
" * // => 'moe is 40'",
|
||||
' */',
|
||||
'function chain(value) {',
|
||||
' value = new lodashWrapper(value);',
|
||||
' value.__chain__ = true;',
|
||||
' return value;',
|
||||
'}',
|
||||
'',
|
||||
match
|
||||
].join('\n' + indent));
|
||||
});
|
||||
|
||||
// add `wrapperChain`
|
||||
source = source.replace(matchFunction(source, 'wrapperToString', true), function(match) {
|
||||
var indent = getIndent(match);
|
||||
return match && (indent + [
|
||||
'',
|
||||
'/**',
|
||||
' * Enables method chaining on the wrapper object.',
|
||||
' *',
|
||||
' * @name chain',
|
||||
' * @memberOf _',
|
||||
' * @category Chaining',
|
||||
' * @returns {Mixed} Returns the wrapper object.',
|
||||
' * @example',
|
||||
' *',
|
||||
' * var sum = _([1, 2, 3])',
|
||||
' * .chain()',
|
||||
' * .reduce(function(sum, num) { return sum + num; })',
|
||||
' * .value()',
|
||||
' * // => 6`',
|
||||
' */',
|
||||
'function wrapperChain() {',
|
||||
' this.__chain__ = true;',
|
||||
' return this;',
|
||||
'}',
|
||||
'',
|
||||
match
|
||||
].join('\n' + indent));
|
||||
});
|
||||
|
||||
// remove `lodash.prototype.toString` and `lodash.prototype.valueOf` assignments
|
||||
source = source.replace(/^ *lodash\.prototype\.(?:toString|valueOf) *=.+\n/gm, '');
|
||||
|
||||
@@ -783,11 +717,6 @@
|
||||
].join('\n' + indent);
|
||||
});
|
||||
|
||||
// replace `_.chain` assignment
|
||||
source = source.replace(getMethodAssignments(source), function(match) {
|
||||
return match.replace(/^( *lodash\.chain *= *)[\s\S]+?(?=;\n)/m, '$1chain')
|
||||
});
|
||||
|
||||
// move `mixin(lodash)` to after the method assignments
|
||||
source = source.replace(/(?:\s*\/\/.*)*\n( *)mixin\(lodash\).+/, '');
|
||||
source = source.replace(getMethodAssignments(source), function(match) {
|
||||
@@ -800,11 +729,6 @@
|
||||
].join('\n' + indent);
|
||||
});
|
||||
|
||||
// move the `lodash.prototype.chain` assignment to after `mixin(lodash)`
|
||||
source = source
|
||||
.replace(/^ *lodash\.prototype\.chain *=[\s\S]+?;\n/m, '')
|
||||
.replace(/^( *)lodash\.prototype\.value *=/m, '$1lodash.prototype.chain = wrapperChain;\n$&');
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
|
||||
92
lodash.js
92
lodash.js
@@ -585,7 +585,6 @@
|
||||
*
|
||||
* @name _
|
||||
* @constructor
|
||||
* @alias chain
|
||||
* @category Chaining
|
||||
* @param {Mixed} value The value to wrap in a `lodash` instance.
|
||||
* @returns {Object} Returns a `lodash` instance.
|
||||
@@ -622,9 +621,11 @@
|
||||
*
|
||||
* @private
|
||||
* @param {Mixed} value The value to wrap in a `lodash` instance.
|
||||
* @param {Boolean} chainAll A flag to enable chaining for all methods
|
||||
* @returns {Object} Returns a `lodash` instance.
|
||||
*/
|
||||
function lodashWrapper(value) {
|
||||
function lodashWrapper(value, chainAll) {
|
||||
this.__chain__ = !!chainAll;
|
||||
this.__wrapped__ = value;
|
||||
}
|
||||
// ensure `new lodashWrapper` is an instance of `lodash`
|
||||
@@ -5956,6 +5957,34 @@
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Creates a `lodash` object that wraps the given `value`.
|
||||
*
|
||||
* @static
|
||||
* @memberOf _
|
||||
* @category Chaining
|
||||
* @param {Mixed} value The value to wrap.
|
||||
* @returns {Object} Returns the wrapper object.
|
||||
* @example
|
||||
*
|
||||
* var stooges = [
|
||||
* { 'name': 'moe', 'age': 40 },
|
||||
* { 'name': 'larry', 'age': 50 },
|
||||
* { 'name': 'curly', 'age': 60 }
|
||||
* ];
|
||||
*
|
||||
* var youngest = _.chain(stooges)
|
||||
* .sortBy(function(stooge) { return stooge.age; })
|
||||
* .map(function(stooge) { return stooge.name + ' is ' + stooge.age; })
|
||||
* .first();
|
||||
* // => 'moe is 40'
|
||||
*/
|
||||
function chain(value) {
|
||||
value = new lodashWrapper(value);
|
||||
value.__chain__ = true;
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes `interceptor` with the `value` as the first argument, and then
|
||||
* returns `value`. The purpose of this method is to "tap into" a method chain,
|
||||
@@ -5982,6 +6011,26 @@
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables method chaining on the wrapper object.
|
||||
*
|
||||
* @name chain
|
||||
* @memberOf _
|
||||
* @category Chaining
|
||||
* @returns {Mixed} Returns the wrapper object.
|
||||
* @example
|
||||
*
|
||||
* var sum = _([1, 2, 3])
|
||||
* .chain()
|
||||
* .reduce(function(sum, num) { return sum + num; })
|
||||
* .value()
|
||||
* // => 6`
|
||||
*/
|
||||
function wrapperChain() {
|
||||
this.__chain__ = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces the `toString` result of the wrapped value.
|
||||
*
|
||||
@@ -6024,6 +6073,7 @@
|
||||
lodash.bind = bind;
|
||||
lodash.bindAll = bindAll;
|
||||
lodash.bindKey = bindKey;
|
||||
lodash.chain = chain;
|
||||
lodash.compact = compact;
|
||||
lodash.compose = compose;
|
||||
lodash.countBy = countBy;
|
||||
@@ -6095,10 +6145,6 @@
|
||||
// add functions to `lodash.prototype`
|
||||
mixin(lodash);
|
||||
|
||||
// add Underscore compat
|
||||
lodash.chain = lodash;
|
||||
lodash.prototype.chain = function() { return this; };
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
// add functions that return unwrapped values when chaining
|
||||
@@ -6162,9 +6208,14 @@
|
||||
forOwn(lodash, function(func, methodName) {
|
||||
if (!lodash.prototype[methodName]) {
|
||||
lodash.prototype[methodName] = function() {
|
||||
var args = [this.__wrapped__];
|
||||
var args = [this.__wrapped__],
|
||||
chainAll = this.__chain__;
|
||||
|
||||
push.apply(args, arguments);
|
||||
return func.apply(lodash, args);
|
||||
var result = func.apply(lodash, args);
|
||||
return chainAll
|
||||
? new lodashWrapper(result, chainAll)
|
||||
: result;
|
||||
};
|
||||
}
|
||||
});
|
||||
@@ -6182,10 +6233,12 @@
|
||||
forOwn(lodash, function(func, methodName) {
|
||||
if (!lodash.prototype[methodName]) {
|
||||
lodash.prototype[methodName]= function(callback, thisArg) {
|
||||
var result = func(this.__wrapped__, callback, thisArg);
|
||||
return callback == null || (thisArg && typeof callback != 'function')
|
||||
var chainAll = this.__chain__,
|
||||
result = func(this.__wrapped__, callback, thisArg);
|
||||
|
||||
return !chainAll && (callback == null || (thisArg && typeof callback != 'function'))
|
||||
? result
|
||||
: new lodashWrapper(result);
|
||||
: new lodashWrapper(result, chainAll);
|
||||
};
|
||||
}
|
||||
});
|
||||
@@ -6202,6 +6255,7 @@
|
||||
lodash.VERSION = '1.3.1';
|
||||
|
||||
// add "Chaining" functions to the wrapper
|
||||
lodash.prototype.chain = wrapperChain;
|
||||
lodash.prototype.toString = wrapperToString;
|
||||
lodash.prototype.value = wrapperValueOf;
|
||||
lodash.prototype.valueOf = wrapperValueOf;
|
||||
@@ -6210,7 +6264,12 @@
|
||||
baseEach(['join', 'pop', 'shift'], function(methodName) {
|
||||
var func = arrayRef[methodName];
|
||||
lodash.prototype[methodName] = function() {
|
||||
return func.apply(this.__wrapped__, arguments);
|
||||
var chainAll = this.__chain__,
|
||||
result = func.apply(this.__wrapped__, arguments);
|
||||
|
||||
return chainAll
|
||||
? new lodashWrapper(result, chainAll)
|
||||
: result;
|
||||
};
|
||||
});
|
||||
|
||||
@@ -6227,7 +6286,7 @@
|
||||
baseEach(['concat', 'slice', 'splice'], function(methodName) {
|
||||
var func = arrayRef[methodName];
|
||||
lodash.prototype[methodName] = function() {
|
||||
return new lodashWrapper(func.apply(this.__wrapped__, arguments));
|
||||
return new lodashWrapper(func.apply(this.__wrapped__, arguments), this.__chain__);
|
||||
};
|
||||
});
|
||||
|
||||
@@ -6239,13 +6298,16 @@
|
||||
isSplice = methodName == 'splice';
|
||||
|
||||
lodash.prototype[methodName] = function() {
|
||||
var value = this.__wrapped__,
|
||||
var chainAll = this.__chain__,
|
||||
value = this.__wrapped__,
|
||||
result = func.apply(value, arguments);
|
||||
|
||||
if (value.length === 0) {
|
||||
delete value[0];
|
||||
}
|
||||
return isSplice ? new lodashWrapper(result) : result;
|
||||
return (chainAll || isSplice)
|
||||
? new lodashWrapper(result, chainAll)
|
||||
: result;
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1214,8 +1214,9 @@
|
||||
vm.runInContext(data.source, context);
|
||||
var lodash = context._;
|
||||
|
||||
ok(lodash.chain(1) instanceof lodash, '_.chain: ' + basename);
|
||||
ok(lodash(1).chain() instanceof lodash, '_#chain: ' + basename);
|
||||
var array = ['abc'];
|
||||
ok(lodash.chain(array).first().first() instanceof lodash, '_.chain: ' + basename);
|
||||
ok(lodash(array).chain().first().first() instanceof lodash, '_#chain: ' + basename);
|
||||
|
||||
var wrapped = lodash(1);
|
||||
strictEqual(wrapped.identity(), 1, '_(...) wrapped values are not chainable by default: ' + basename);
|
||||
|
||||
13
test/test.js
13
test/test.js
@@ -408,6 +408,19 @@
|
||||
var wrapper = _({ 'a': 0 });
|
||||
equal(wrapper.chain(), wrapper);
|
||||
});
|
||||
|
||||
test('should enable chaining of methods that return unwrapped values by default', function() {
|
||||
var array = ['abc'];
|
||||
|
||||
ok(_.chain(array).first() instanceof _);
|
||||
ok(_(array).chain().first() instanceof _);
|
||||
|
||||
ok(_.chain(array).isArray() instanceof _);
|
||||
ok(_(array).chain().isArray() instanceof _);
|
||||
|
||||
ok(_.chain(array).first().first() instanceof _);
|
||||
ok(_(array).chain().first().first() instanceof _);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
Reference in New Issue
Block a user