mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-08 18:17:48 +00:00
Add support for strings in "Collections" methods.
Former-commit-id: 1abb252101d20c9a01291f4cef19db8a7eeda743
This commit is contained in:
85
build.js
85
build.js
@@ -217,15 +217,14 @@
|
|||||||
'bottom',
|
'bottom',
|
||||||
'exit',
|
'exit',
|
||||||
'firstArg',
|
'firstArg',
|
||||||
'hasExp',
|
|
||||||
'hasDontEnumBug',
|
'hasDontEnumBug',
|
||||||
'inLoop',
|
'inLoop',
|
||||||
'init',
|
'init',
|
||||||
'isKeysFast',
|
'isKeysFast',
|
||||||
'iteratedObject',
|
'iteratee',
|
||||||
'loopExp',
|
|
||||||
'object',
|
'object',
|
||||||
'objectBranch',
|
'objectBranch',
|
||||||
|
'noCharByIndex',
|
||||||
'shadowed',
|
'shadowed',
|
||||||
'top',
|
'top',
|
||||||
'useHas'
|
'useHas'
|
||||||
@@ -260,7 +259,7 @@
|
|||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the aliases associated with a given `funcName`.
|
* Gets the aliases associated with a given function name.
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
* @param {String} funcName The name of the function to get aliases for.
|
* @param {String} funcName The name of the function to get aliases for.
|
||||||
@@ -271,7 +270,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets an array of depenants for a function by the given `funcName`.
|
* Gets an array of depenants for a function by a given name.
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
* @param {String} funcName The name of the function to query.
|
* @param {String} funcName The name of the function to query.
|
||||||
@@ -320,6 +319,8 @@
|
|||||||
*/
|
*/
|
||||||
function getFunctionSource(func) {
|
function getFunctionSource(func) {
|
||||||
var source = func.source || (func + '');
|
var source = func.source || (func + '');
|
||||||
|
|
||||||
|
// all leading whitespace
|
||||||
return source.replace(/\n(?:.*)/g, function(match, index) {
|
return source.replace(/\n(?:.*)/g, function(match, index) {
|
||||||
match = match.slice(1);
|
match = match.slice(1);
|
||||||
return (
|
return (
|
||||||
@@ -340,7 +341,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the real name, not alias, of a given `funcName`.
|
* Gets the real name, not alias, of a given function name.
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
* @param {String} funcName The name of the function to resolve.
|
* @param {String} funcName The name of the function to resolve.
|
||||||
@@ -393,7 +394,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the all references to `refName` from the `createIterator` source.
|
* Removes the all references to `refName` from `createIterator` in `source`.
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
* @param {String} source The source to process.
|
* @param {String} source The source to process.
|
||||||
@@ -461,10 +462,10 @@
|
|||||||
*/
|
*/
|
||||||
function removeKeysOptimization(source) {
|
function removeKeysOptimization(source) {
|
||||||
return removeVar(source, 'isKeysFast')
|
return removeVar(source, 'isKeysFast')
|
||||||
// remove conditional concat in `mapIteratorOptions`
|
// remove `isKeysFast` from `beforeLoop.object` of `mapIteratorOptions`
|
||||||
.replace(/= *' *\+ *\(isKeysFast.+/, "= []'")
|
.replace(/=\s*'\s*\+\s*\(isKeysFast.+/, "= []'")
|
||||||
// remove conditional concat in `mapIteratorOptions`, `invoke`, `pluck`, and `sortBy`
|
// remove `isKeysFast` from `inLoop.object` of `mapIteratorOptions`, `invoke`, `pluck`, and `sortBy`
|
||||||
.replace(/' *\+ *\(isKeysFast.+?\) *\+ *'/g, '.push')
|
.replace(/'\s*\+\s*\(isKeysFast[^)]+?\)\s*\+\s*'/g, '.push')
|
||||||
// remove data object property assignment in `createIterator`
|
// remove data object property assignment in `createIterator`
|
||||||
.replace(/\s*.+?\.isKeysFast *=.+/, '')
|
.replace(/\s*.+?\.isKeysFast *=.+/, '')
|
||||||
// remove optimized branch in `iteratorTemplate`
|
// remove optimized branch in `iteratorTemplate`
|
||||||
@@ -518,7 +519,7 @@
|
|||||||
'(?:.+?;|(?:Function\\(.+?|.*?[^,])\\n[\\s\\S]+?\\n\\2.+?;)\\n'
|
'(?:.+?;|(?:Function\\(.+?|.*?[^,])\\n[\\s\\S]+?\\n\\2.+?;)\\n'
|
||||||
), '$1' + varValue + ';\n');
|
), '$1' + varValue + ';\n');
|
||||||
|
|
||||||
// replace a varaible at the start of middle of a declaration list
|
// replace a varaible at the start or middle of a declaration list
|
||||||
source = source.replace(RegExp('((?:var|\\n) +' + varName + ' *=).+?,'), '$1 ' + varValue + ',');
|
source = source.replace(RegExp('((?:var|\\n) +' + varName + ' *=).+?,'), '$1 ' + varValue + ',');
|
||||||
|
|
||||||
// replace a variable at the end of a variable declaration list
|
// replace a variable at the end of a variable declaration list
|
||||||
@@ -531,7 +532,7 @@
|
|||||||
|
|
||||||
// Backbone build
|
// Backbone build
|
||||||
if (isBackbone) {
|
if (isBackbone) {
|
||||||
// add any additional dependencies
|
// add any additional sub-dependencies
|
||||||
backboneDependencies = getDependencies(backboneDependencies);
|
backboneDependencies = getDependencies(backboneDependencies);
|
||||||
|
|
||||||
if (filterType == 'exclude') {
|
if (filterType == 'exclude') {
|
||||||
@@ -569,14 +570,13 @@
|
|||||||
includeMethods = lodash.without.apply(lodash, [categoryMethods].concat(excludeMethods));
|
includeMethods = lodash.without.apply(lodash, [categoryMethods].concat(excludeMethods));
|
||||||
}
|
}
|
||||||
else if (filterType) {
|
else if (filterType) {
|
||||||
// merge backbone dependencies into `includeMethods`
|
// merge `categoryMethods` into `includeMethods`
|
||||||
includeMethods = lodash.union(includeMethods, categoryMethods);
|
includeMethods = lodash.union(includeMethods, categoryMethods);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// include only the Backbone dependencies
|
// include only the `categoryMethods`
|
||||||
includeMethods = categoryMethods;
|
includeMethods = categoryMethods;
|
||||||
}
|
}
|
||||||
|
|
||||||
filterType = 'include';
|
filterType = 'include';
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
@@ -609,7 +609,7 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove associated functions, variables and code snippets
|
// remove associated functions, variables, and code snippets
|
||||||
if (isRemoved(source, 'isArguments')) {
|
if (isRemoved(source, 'isArguments')) {
|
||||||
source = removeIsArgumentsFallback(source);
|
source = removeIsArgumentsFallback(source);
|
||||||
}
|
}
|
||||||
@@ -674,7 +674,7 @@
|
|||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
// DRY out isType methods
|
// DRY out isType functions
|
||||||
(function() {
|
(function() {
|
||||||
var iteratorName = lodash.find(['forEach', 'forOwn'], function(funcName) {
|
var iteratorName = lodash.find(['forEach', 'forOwn'], function(funcName) {
|
||||||
return !isRemoved(source, funcName);
|
return !isRemoved(source, funcName);
|
||||||
@@ -686,7 +686,7 @@
|
|||||||
}
|
}
|
||||||
var snippet,
|
var snippet,
|
||||||
funcNames = [],
|
funcNames = [],
|
||||||
result = [],
|
objectSnippets = [],
|
||||||
token = '__isTypeToken__';
|
token = '__isTypeToken__';
|
||||||
|
|
||||||
// build replacement code
|
// build replacement code
|
||||||
@@ -698,7 +698,7 @@
|
|||||||
'RegExp': 'regexpClass',
|
'RegExp': 'regexpClass',
|
||||||
'String': 'stringClass'
|
'String': 'stringClass'
|
||||||
}, function(value, key) {
|
}, function(value, key) {
|
||||||
// skip `isArguments` if legacy build
|
// skip `isArguments` if a legacy build
|
||||||
if (isLegacy && key == 'Arguments') {
|
if (isLegacy && key == 'Arguments') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -711,12 +711,12 @@
|
|||||||
snippet = funcCode;
|
snippet = funcCode;
|
||||||
}
|
}
|
||||||
funcNames.push(funcName);
|
funcNames.push(funcName);
|
||||||
result.push("'" + key + "': " + value);
|
objectSnippets.push("'" + key + "': " + value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// skip this optimization if there are less than 2 functions
|
// skip this optimization if there are less than 2 isType functions
|
||||||
if (result.length < 2) {
|
if (funcNames.length < 2) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// add a token to mark the position to insert new code
|
// add a token to mark the position to insert new code
|
||||||
@@ -730,7 +730,7 @@
|
|||||||
// replace token with new DRY code
|
// replace token with new DRY code
|
||||||
source = source.replace(token,
|
source = source.replace(token,
|
||||||
' // add `_.' + funcNames.join('`, `_.') + '`\n' +
|
' // add `_.' + funcNames.join('`, `_.') + '`\n' +
|
||||||
' ' + iteratorName + '({\n ' + result.join(',\n ') + '\n }, function(className, key) {\n' +
|
' ' + iteratorName + '({\n ' + objectSnippets.join(',\n ') + '\n }, function(className, key) {\n' +
|
||||||
" lodash['is' + key] = function(value) {\n" +
|
" lodash['is' + key] = function(value) {\n" +
|
||||||
' return toString.call(value) == className;\n' +
|
' return toString.call(value) == className;\n' +
|
||||||
' };\n' +
|
' };\n' +
|
||||||
@@ -740,8 +740,8 @@
|
|||||||
// tweak `isArguments` fallback
|
// tweak `isArguments` fallback
|
||||||
snippet = !isLegacy && getIsArgumentsFallback(source);
|
snippet = !isLegacy && getIsArgumentsFallback(source);
|
||||||
if (snippet) {
|
if (snippet) {
|
||||||
result = '\n' + snippet.replace(/isArguments/g, 'lodash.$&');
|
var modified = '\n' + snippet.replace(/isArguments/g, 'lodash.$&');
|
||||||
source = source.replace(snippet, result);
|
source = source.replace(snippet, modified);
|
||||||
}
|
}
|
||||||
}());
|
}());
|
||||||
|
|
||||||
@@ -754,17 +754,17 @@
|
|||||||
|
|
||||||
['bind', 'isArray'].forEach(function(funcName) {
|
['bind', 'isArray'].forEach(function(funcName) {
|
||||||
var snippet = matchFunction(source, funcName),
|
var snippet = matchFunction(source, funcName),
|
||||||
result = snippet;
|
modified = snippet;
|
||||||
|
|
||||||
// remove native `Function#bind` branch
|
// remove native `Function#bind` branch in `_.bind`
|
||||||
if (funcName == 'bind' ) {
|
if (funcName == 'bind' ) {
|
||||||
result = result.replace(/(?:\s*\/\/.*)*\s*else if *\(isBindFast[^}]+}/, '');
|
modified = modified.replace(/(?:\s*\/\/.*)*\s*else if *\(isBindFast[^}]+}/, '');
|
||||||
}
|
}
|
||||||
// remove native `Array.isArray` branch
|
// remove native `Array.isArray` branch in `_.isArray`
|
||||||
else if (funcName == 'isArray') {
|
else if (funcName == 'isArray') {
|
||||||
result = result.replace(/nativeIsArray * \|\|/, '');
|
modified = modified.replace(/nativeIsArray * \|\|/, '');
|
||||||
}
|
}
|
||||||
source = source.replace(snippet, result);
|
source = source.replace(snippet, modified);
|
||||||
});
|
});
|
||||||
|
|
||||||
// replace `_.keys` with `shimKeys`
|
// replace `_.keys` with `shimKeys`
|
||||||
@@ -786,12 +786,13 @@
|
|||||||
source = removeIsArgumentsFallback(source);
|
source = removeIsArgumentsFallback(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
source = removeVar(source, 'reNative');
|
||||||
source = removeFromCreateIterator(source, 'nativeKeys');
|
source = removeFromCreateIterator(source, 'nativeKeys');
|
||||||
source = removeKeysOptimization(source);
|
source = removeKeysOptimization(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isMobile) {
|
if (isMobile) {
|
||||||
// inline functions defined with `createIterator`
|
// inline all functions defined with `createIterator`
|
||||||
lodash.functions(lodash).forEach(function(funcName) {
|
lodash.functions(lodash).forEach(function(funcName) {
|
||||||
// match `funcName` with pseudo private `_` prefixes removed to allow matching `shimKeys`
|
// match `funcName` with pseudo private `_` prefixes removed to allow matching `shimKeys`
|
||||||
var reFunc = RegExp('(\\bvar ' + funcName.replace(/^_/, '') + ' *= *)createIterator\\(((?:{|[a-zA-Z])[\\s\\S]+?)\\);\\n');
|
var reFunc = RegExp('(\\bvar ' + funcName.replace(/^_/, '') + ' *= *)createIterator\\(((?:{|[a-zA-Z])[\\s\\S]+?)\\);\\n');
|
||||||
@@ -804,12 +805,15 @@
|
|||||||
source = source.replace(reFunc, '$1' + getFunctionSource(lodash[funcName]) + ';\n');
|
source = source.replace(reFunc, '$1' + getFunctionSource(lodash[funcName]) + ';\n');
|
||||||
});
|
});
|
||||||
|
|
||||||
// remove JScript [[DontEnum]] fix from `isEqual`
|
// remove JScript [[DontEnum]] fix from `_.isEqual`
|
||||||
source = source.replace(/(?:\s*\/\/.*)*\n( +)if *\(result *&& *hasDontEnumBug[\s\S]+?\n\1}/, '');
|
source = source.replace(/(?:\s*\/\/.*)*\n( +)if *\(result *&& *hasDontEnumBug[\s\S]+?\n\1}/, '');
|
||||||
|
|
||||||
// remove IE `shift` and `splice` fix
|
// remove IE `shift` and `splice` fix from mutator Array functions mixin
|
||||||
source = source.replace(/(?:\s*\/\/.*)*\n( +)if *\(value.length *=== *0[\s\S]+?\n\1}/, '');
|
source = source.replace(/(?:\s*\/\/.*)*\n( +)if *\(value.length *=== *0[\s\S]+?\n\1}/, '');
|
||||||
|
|
||||||
|
// remove `noCharByIndex` from `_.reduceRight` and `_.toArray`
|
||||||
|
source = source.replace(/noCharByIndex *&&[^:]+: *([^;]+)/g, '$1');
|
||||||
|
|
||||||
source = removeVar(source, 'extendIteratorOptions');
|
source = removeVar(source, 'extendIteratorOptions');
|
||||||
source = removeVar(source, 'hasDontEnumBug');
|
source = removeVar(source, 'hasDontEnumBug');
|
||||||
source = removeVar(source, 'iteratorTemplate');
|
source = removeVar(source, 'iteratorTemplate');
|
||||||
@@ -821,9 +825,16 @@
|
|||||||
source = source.replace(/(( +)var iteratorTemplate *= *)[\s\S]+?\n\2.+?;\n/, (function() {
|
source = source.replace(/(( +)var iteratorTemplate *= *)[\s\S]+?\n\2.+?;\n/, (function() {
|
||||||
var snippet = getFunctionSource(lodash._iteratorTemplate);
|
var snippet = getFunctionSource(lodash._iteratorTemplate);
|
||||||
|
|
||||||
// expand properties to avoid having to use a with-statement
|
// prepend data object references to property names to avoid having to
|
||||||
|
// use a with-statement
|
||||||
iteratorOptions.forEach(function(property) {
|
iteratorOptions.forEach(function(property) {
|
||||||
snippet = snippet.replace(RegExp('([^\\w.])\\b' + property + '\\b', 'g'), '$1obj.' + property);
|
if (property == 'iteratee') {
|
||||||
|
// use a more fine-grained regexp for the `iteratee` property because
|
||||||
|
// it's a compiled variable as well as a data property
|
||||||
|
snippet = snippet.replace(/(__t *= *\( *)(iteratee)/, '$1obj.$2');
|
||||||
|
} else {
|
||||||
|
snippet = snippet.replace(RegExp('([^\\w.])\\b' + property + '\\b', 'g'), '$1obj.' + property);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// remove unnecessary code
|
// remove unnecessary code
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
'identity',
|
'identity',
|
||||||
'index',
|
'index',
|
||||||
'isFunc',
|
'isFunc',
|
||||||
|
'iteratee',
|
||||||
'iteratorBind',
|
'iteratorBind',
|
||||||
'length',
|
'length',
|
||||||
'methodName',
|
'methodName',
|
||||||
@@ -53,15 +54,14 @@
|
|||||||
'bottom',
|
'bottom',
|
||||||
'exit',
|
'exit',
|
||||||
'firstArg',
|
'firstArg',
|
||||||
'hasExp',
|
|
||||||
'hasDontEnumBug',
|
'hasDontEnumBug',
|
||||||
'inLoop',
|
'inLoop',
|
||||||
'init',
|
'init',
|
||||||
'isKeysFast',
|
'isKeysFast',
|
||||||
'iteratedObject',
|
'iteratee',
|
||||||
'loopExp',
|
|
||||||
'object',
|
'object',
|
||||||
'objectBranch',
|
'objectBranch',
|
||||||
|
'noCharByIndex',
|
||||||
'shadowed',
|
'shadowed',
|
||||||
'top',
|
'top',
|
||||||
'useHas'
|
'useHas'
|
||||||
@@ -196,9 +196,9 @@
|
|||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pre-process a given JavaScript `source`, preparing it for minification.
|
* Pre-process a given Lo-Dash source, preparing it for minification.
|
||||||
*
|
*
|
||||||
* @param {String} source The source to process.
|
* @param {String} source The Lo-Dash source to process.
|
||||||
* @returns {String} Returns the processed source.
|
* @returns {String} Returns the processed source.
|
||||||
*/
|
*/
|
||||||
function preprocess(source) {
|
function preprocess(source) {
|
||||||
@@ -257,23 +257,23 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
snippets.forEach(function(snippet) {
|
snippets.forEach(function(snippet) {
|
||||||
var result = snippet,
|
var modified = snippet,
|
||||||
isSortBy = /var sortBy\b/.test(result),
|
isSortBy = /var sortBy\b/.test(modified),
|
||||||
isInlined = !/\bcreateIterator\b/.test(result);
|
isInlined = !/\bcreateIterator\b/.test(modified);
|
||||||
|
|
||||||
// minify properties
|
// minify properties
|
||||||
properties.forEach(function(property, index) {
|
properties.forEach(function(property, index) {
|
||||||
// add quotes around properties in the inlined `sortBy` of the mobile
|
// add quotes around properties in the inlined `_.sortBy` of the mobile
|
||||||
// build so Closure Compiler won't mung them
|
// build so Closure Compiler won't mung them
|
||||||
if (isSortBy && isInlined) {
|
if (isSortBy && isInlined) {
|
||||||
result = result
|
modified = modified
|
||||||
.replace(RegExp('\\.' + property + '\\b', 'g'), "['" + minNames[index] + "']")
|
.replace(RegExp('\\.' + property + '\\b', 'g'), "['" + minNames[index] + "']")
|
||||||
.replace(RegExp('\\b' + property + ' *:', 'g'), "'" + minNames[index] + "':");
|
.replace(RegExp('\\b' + property + ' *:', 'g'), "'" + minNames[index] + "':");
|
||||||
}
|
}
|
||||||
result = result.replace(RegExp('\\b' + property + '\\b', 'g'), minNames[index]);
|
modified = modified.replace(RegExp('\\b' + property + '\\b', 'g'), minNames[index]);
|
||||||
});
|
});
|
||||||
// replace with modified snippet
|
// replace with modified snippet
|
||||||
source = source.replace(snippet, result);
|
source = source.replace(snippet, modified);
|
||||||
});
|
});
|
||||||
}());
|
}());
|
||||||
|
|
||||||
@@ -299,26 +299,26 @@
|
|||||||
snippets.forEach(function(snippet, index) {
|
snippets.forEach(function(snippet, index) {
|
||||||
var isCreateIterator = /function createIterator\b/.test(snippet),
|
var isCreateIterator = /function createIterator\b/.test(snippet),
|
||||||
isIteratorTemplate = /var iteratorTemplate\b/.test(snippet),
|
isIteratorTemplate = /var iteratorTemplate\b/.test(snippet),
|
||||||
result = snippet;
|
modified = snippet;
|
||||||
|
|
||||||
// add brackets to whitelisted properties so Closure Compiler won't mung them
|
// add brackets to whitelisted properties so Closure Compiler won't mung them
|
||||||
result = result.replace(RegExp('\\.(' + iteratorOptions.join('|') + ')\\b', 'g'), "['$1']");
|
modified = modified.replace(RegExp('\\.(' + iteratorOptions.join('|') + ')\\b', 'g'), "['$1']");
|
||||||
|
|
||||||
if (isCreateIterator) {
|
if (isCreateIterator) {
|
||||||
// replace with modified snippet early and clip snippet so other arguments
|
// replace with modified snippet early and clip snippet so other arguments
|
||||||
// aren't minified
|
// aren't minified
|
||||||
source = source.replace(snippet, result);
|
source = source.replace(snippet, modified);
|
||||||
snippet = result = result.replace(/factory\([\s\S]+$/, '');
|
snippet = modified = modified.replace(/factory\([\s\S]+$/, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
// minify snippet variables / arguments
|
// minify snippet variables / arguments
|
||||||
compiledVars.forEach(function(variable, index) {
|
compiledVars.forEach(function(variable, index) {
|
||||||
// ensure properties in compiled strings aren't minified
|
// ensure properties in compiled strings aren't minified
|
||||||
result = result.replace(RegExp('([^.]\\b)' + variable + '\\b(?!\' *[\\]:])', 'g'), '$1' + minNames[index]);
|
modified = modified.replace(RegExp('([^.]\\b)' + variable + '\\b(?!\' *[\\]:])', 'g'), '$1' + minNames[index]);
|
||||||
|
|
||||||
// correct `typeof x == 'object'`
|
// correct `typeof x == 'object'`
|
||||||
if (variable == 'object') {
|
if (variable == 'object') {
|
||||||
result = result.replace(RegExp("(typeof [^']+')" + minNames[index] + "'", 'g'), "$1object'");
|
modified = modified.replace(RegExp("(typeof [^']+')" + minNames[index] + "'", 'g'), "$1object'");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -326,26 +326,26 @@
|
|||||||
iteratorOptions.forEach(function(property, index) {
|
iteratorOptions.forEach(function(property, index) {
|
||||||
if (isIteratorTemplate) {
|
if (isIteratorTemplate) {
|
||||||
// minify property names as interpolated template variables
|
// minify property names as interpolated template variables
|
||||||
result = result.replace(RegExp('\\b' + property + '\\b', 'g'), minNames[index]);
|
modified = modified.replace(RegExp('\\b' + property + '\\b', 'g'), minNames[index]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (property == 'array' || property == 'object') {
|
if (property == 'array' || property == 'object') {
|
||||||
// minify "array" and "object" sub property names
|
// minify "array" and "object" sub property names
|
||||||
result = result.replace(RegExp("'" + property + "'( *[\\]:])", 'g'), "'" + minNames[index] + "'$1");
|
modified = modified.replace(RegExp("'" + property + "'( *[\\]:])", 'g'), "'" + minNames[index] + "'$1");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// minify property name strings
|
// minify property name strings
|
||||||
result = result.replace(RegExp("'" + property + "'", 'g'), "'" + minNames[index] + "'");
|
modified = modified.replace(RegExp("'" + property + "'", 'g'), "'" + minNames[index] + "'");
|
||||||
// minify property names in regexps and accessors
|
// minify property names in regexps and accessors
|
||||||
if (isCreateIterator) {
|
if (isCreateIterator) {
|
||||||
result = result.replace(RegExp('([\\.|/])' + property + '\\b' , 'g'), '$1' + minNames[index]);
|
modified = modified.replace(RegExp('([\\.|/])' + property + '\\b' , 'g'), '$1' + minNames[index]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// replace with modified snippet
|
// replace with modified snippet
|
||||||
source = source.replace(snippet, result);
|
source = source.replace(snippet, modified);
|
||||||
});
|
});
|
||||||
|
|
||||||
return source;
|
return source;
|
||||||
|
|||||||
186
lodash.js
186
lodash.js
@@ -128,6 +128,13 @@
|
|||||||
*/
|
*/
|
||||||
var hasDontEnumBug = !propertyIsEnumerable.call({ 'valueOf': 0 }, 'valueOf');
|
var hasDontEnumBug = !propertyIsEnumerable.call({ 'valueOf': 0 }, 'valueOf');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detect support for accessing string characters by index:
|
||||||
|
* IE < 8 can't access characters by index and IE 8 can only access
|
||||||
|
* characters by index on string literals.
|
||||||
|
*/
|
||||||
|
var noCharByIndex = ('x'[0] + Object('x')[0]) != 'xx';
|
||||||
|
|
||||||
/* Detect if `Function#bind` exists and is inferred to be fast (i.e. all but V8) */
|
/* Detect if `Function#bind` exists and is inferred to be fast (i.e. all but V8) */
|
||||||
var isBindFast = nativeBind && /\n|Opera/.test(nativeBind + toString.call(window.opera));
|
var isBindFast = nativeBind && /\n|Opera/.test(nativeBind + toString.call(window.opera));
|
||||||
|
|
||||||
@@ -262,18 +269,27 @@
|
|||||||
*/
|
*/
|
||||||
var iteratorTemplate = template(
|
var iteratorTemplate = template(
|
||||||
// assign the `result` variable an initial value
|
// assign the `result` variable an initial value
|
||||||
'var index, result<% if (init) { %> = <%= init %><% } %>;\n' +
|
'var result<% if (init) { %> = <%= init %><% } %>;\n' +
|
||||||
// add code to exit early or do so if the first argument is falsey
|
// add code to exit early or do so if the first argument is falsey
|
||||||
'<%= exit %>;\n' +
|
'<%= exit %>;\n' +
|
||||||
// add code after the exit snippet but before the iteration branches
|
// add code after the exit snippet but before the iteration branches
|
||||||
'<%= top %>;\n' +
|
'<%= top %>;\n' +
|
||||||
|
'var index, iteratee = <%= iteratee %>;\n' +
|
||||||
|
|
||||||
// the following branch is for iterating arrays and array-like objects
|
// the following branch is for iterating arrays and array-like objects
|
||||||
'<% if (arrayBranch) { %>' +
|
'<% if (arrayBranch) { %>' +
|
||||||
'var length = <%= firstArg %>.length; index = -1;' +
|
'var length = iteratee.length; index = -1;' +
|
||||||
' <% if (objectBranch) { %>\nif (length === length >>> 0) {<% } %>\n' +
|
' <% if (objectBranch) { %>\nif (length === length >>> 0) {<% } %>' +
|
||||||
|
|
||||||
|
// add support for accessing string characters by index if needed
|
||||||
|
' <% if (noCharByIndex) { %>\n' +
|
||||||
|
' if (toString.call(iteratee) == stringClass) {\n' +
|
||||||
|
' iteratee = iteratee.split(\'\')\n' +
|
||||||
|
' }' +
|
||||||
|
' <% } %>\n' +
|
||||||
|
|
||||||
' <%= arrayBranch.beforeLoop %>;\n' +
|
' <%= arrayBranch.beforeLoop %>;\n' +
|
||||||
' while (<%= arrayBranch.loopExp %>) {\n' +
|
' while (++index < length) {\n' +
|
||||||
' <%= arrayBranch.inLoop %>\n' +
|
' <%= arrayBranch.inLoop %>\n' +
|
||||||
' }' +
|
' }' +
|
||||||
' <% if (objectBranch) { %>\n}<% } %>' +
|
' <% if (objectBranch) { %>\n}<% } %>' +
|
||||||
@@ -283,13 +299,13 @@
|
|||||||
'<% if (objectBranch) { %>' +
|
'<% if (objectBranch) { %>' +
|
||||||
' <% if (arrayBranch) { %>\nelse {<% } %>' +
|
' <% if (arrayBranch) { %>\nelse {<% } %>' +
|
||||||
' <% if (!hasDontEnumBug) { %>\n' +
|
' <% if (!hasDontEnumBug) { %>\n' +
|
||||||
' var skipProto = typeof <%= iteratedObject %> == \'function\' && \n' +
|
' var skipProto = typeof iteratee == \'function\' && \n' +
|
||||||
' propertyIsEnumerable.call(<%= iteratedObject %>, \'prototype\');\n' +
|
' propertyIsEnumerable.call(iteratee, \'prototype\');\n' +
|
||||||
' <% } %>' +
|
' <% } %>' +
|
||||||
|
|
||||||
// iterate own properties using `Object.keys` if it's fast
|
// iterate own properties using `Object.keys` if it's fast
|
||||||
' <% if (isKeysFast && useHas) { %>\n' +
|
' <% if (isKeysFast && useHas) { %>\n' +
|
||||||
' var props = nativeKeys(<%= iteratedObject %>),\n' +
|
' var props = nativeKeys(iteratee),\n' +
|
||||||
' propIndex = -1,\n' +
|
' propIndex = -1,\n' +
|
||||||
' length = props.length;\n\n' +
|
' length = props.length;\n\n' +
|
||||||
' <%= objectBranch.beforeLoop %>;\n' +
|
' <%= objectBranch.beforeLoop %>;\n' +
|
||||||
@@ -303,11 +319,11 @@
|
|||||||
// else using a for-in loop
|
// else using a for-in loop
|
||||||
' <% } else { %>\n' +
|
' <% } else { %>\n' +
|
||||||
' <%= objectBranch.beforeLoop %>;\n' +
|
' <%= objectBranch.beforeLoop %>;\n' +
|
||||||
' for (<%= objectBranch.loopExp %>) {' +
|
' for (index in iteratee) {' +
|
||||||
' <% if (hasDontEnumBug) { %>\n' +
|
' <% if (hasDontEnumBug) { %>\n' +
|
||||||
' <% if (useHas) { %>if (<%= hasExp %>) {\n <% } %>' +
|
' <% if (useHas) { %>if (hasOwnProperty.call(iteratee, index)) {\n <% } %>' +
|
||||||
' <%= objectBranch.inLoop %>;\n' +
|
' <%= objectBranch.inLoop %>;\n' +
|
||||||
' <% if (useHas) { %>}<% } %>' +
|
' <% if (useHas) { %>}<% } %>' +
|
||||||
' <% } else { %>\n' +
|
' <% } else { %>\n' +
|
||||||
|
|
||||||
// Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1
|
// Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1
|
||||||
@@ -316,7 +332,8 @@
|
|||||||
// value to `true`. Because of this Lo-Dash standardizes on skipping
|
// value to `true`. Because of this Lo-Dash standardizes on skipping
|
||||||
// the the `prototype` property of functions regardless of its
|
// the the `prototype` property of functions regardless of its
|
||||||
// [[Enumerable]] value.
|
// [[Enumerable]] value.
|
||||||
' if (!(skipProto && index == \'prototype\')<% if (useHas) { %> && <%= hasExp %><% } %>) {\n' +
|
' if (!(skipProto && index == \'prototype\')<% if (useHas) { %> &&\n' +
|
||||||
|
' hasOwnProperty.call(iteratee, index)<% } %>) {\n' +
|
||||||
' <%= objectBranch.inLoop %>\n' +
|
' <%= objectBranch.inLoop %>\n' +
|
||||||
' }' +
|
' }' +
|
||||||
' <% } %>\n' +
|
' <% } %>\n' +
|
||||||
@@ -328,13 +345,13 @@
|
|||||||
// defaults to non-enumerable, Lo-Dash skips the `constructor`
|
// defaults to non-enumerable, Lo-Dash skips the `constructor`
|
||||||
// property when it infers it's iterating over a `prototype` object.
|
// property when it infers it's iterating over a `prototype` object.
|
||||||
' <% if (hasDontEnumBug) { %>\n\n' +
|
' <% if (hasDontEnumBug) { %>\n\n' +
|
||||||
' var ctor = <%= iteratedObject %>.constructor;\n' +
|
' var ctor = iteratee.constructor;\n' +
|
||||||
' <% for (var k = 0; k < 7; k++) { %>\n' +
|
' <% for (var k = 0; k < 7; k++) { %>\n' +
|
||||||
' index = \'<%= shadowed[k] %>\';\n' +
|
' index = \'<%= shadowed[k] %>\';\n' +
|
||||||
' if (<%' +
|
' if (<%' +
|
||||||
' if (shadowed[k] == \'constructor\') {' +
|
' if (shadowed[k] == \'constructor\') {' +
|
||||||
' %>!(ctor && ctor.prototype === <%= iteratedObject %>) && <%' +
|
' %>!(ctor && ctor.prototype === iteratee) && <%' +
|
||||||
' } %><%= hasExp %>) {\n' +
|
' } %>hasOwnProperty.call(iteratee, index)) {\n' +
|
||||||
' <%= objectBranch.inLoop %>\n' +
|
' <%= objectBranch.inLoop %>\n' +
|
||||||
' }' +
|
' }' +
|
||||||
' <% } %>' +
|
' <% } %>' +
|
||||||
@@ -363,13 +380,13 @@
|
|||||||
'else if (thisArg) {\n' +
|
'else if (thisArg) {\n' +
|
||||||
' callback = iteratorBind(callback, thisArg)\n' +
|
' callback = iteratorBind(callback, thisArg)\n' +
|
||||||
'}',
|
'}',
|
||||||
'inLoop': 'callback(collection[index], index, collection)'
|
'inLoop': 'callback(iteratee[index], index, collection)'
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Reusable iterator options for `every` and `some` */
|
/** Reusable iterator options for `every` and `some` */
|
||||||
var everyIteratorOptions = {
|
var everyIteratorOptions = {
|
||||||
'init': 'true',
|
'init': 'true',
|
||||||
'inLoop': 'if (!callback(collection[index], index, collection)) return !result'
|
'inLoop': 'if (!callback(iteratee[index], index, collection)) return !result'
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Reusable iterator options for `defaults` and `extend` */
|
/** Reusable iterator options for `defaults` and `extend` */
|
||||||
@@ -380,16 +397,16 @@
|
|||||||
'for (var source, sourceIndex = 1, length = arguments.length; sourceIndex < length; sourceIndex++) {\n' +
|
'for (var source, sourceIndex = 1, length = arguments.length; sourceIndex < length; sourceIndex++) {\n' +
|
||||||
' source = arguments[sourceIndex];\n' +
|
' source = arguments[sourceIndex];\n' +
|
||||||
(hasDontEnumBug ? ' if (source) {' : ''),
|
(hasDontEnumBug ? ' if (source) {' : ''),
|
||||||
'loopExp': 'index in source',
|
'iteratee': 'source',
|
||||||
'useHas': false,
|
'useHas': false,
|
||||||
'inLoop': 'object[index] = source[index]',
|
'inLoop': 'result[index] = iteratee[index]',
|
||||||
'bottom': (hasDontEnumBug ? ' }\n' : '') + '}'
|
'bottom': (hasDontEnumBug ? ' }\n' : '') + '}'
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Reusable iterator options for `filter` and `reject` */
|
/** Reusable iterator options for `filter` and `reject` */
|
||||||
var filterIteratorOptions = {
|
var filterIteratorOptions = {
|
||||||
'init': '[]',
|
'init': '[]',
|
||||||
'inLoop': 'callback(collection[index], index, collection) && result.push(collection[index])'
|
'inLoop': 'callback(iteratee[index], index, collection) && result.push(iteratee[index])'
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Reusable iterator options for `find`, `forEach`, `forIn`, and `forOwn` */
|
/** Reusable iterator options for `find`, `forEach`, `forIn`, and `forOwn` */
|
||||||
@@ -413,8 +430,8 @@
|
|||||||
'object': 'result = ' + (isKeysFast ? 'Array(length)' : '[]')
|
'object': 'result = ' + (isKeysFast ? 'Array(length)' : '[]')
|
||||||
},
|
},
|
||||||
'inLoop': {
|
'inLoop': {
|
||||||
'array': 'result[index] = callback(collection[index], index, collection)',
|
'array': 'result[index] = callback(iteratee[index], index, collection)',
|
||||||
'object': 'result' + (isKeysFast ? '[propIndex] = ' : '.push') + '(callback(collection[index], index, collection))'
|
'object': 'result' + (isKeysFast ? '[propIndex] = ' : '.push') + '(callback(iteratee[index], index, collection))'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -442,8 +459,8 @@
|
|||||||
* beforeLoop - A string or object containing an "array" or "object" property
|
* beforeLoop - A string or object containing an "array" or "object" property
|
||||||
* of code to execute before the array or object loops.
|
* of code to execute before the array or object loops.
|
||||||
*
|
*
|
||||||
* loopExp - A string or object containing an "array" or "object" property
|
* iteratee - A string or object containing an "array" or "object" property
|
||||||
* of code to execute as the array or object loop expression.
|
* of the variable to be iterated in the loop expression.
|
||||||
*
|
*
|
||||||
* useHas - A boolean to specify whether or not to use `hasOwnProperty` checks
|
* useHas - A boolean to specify whether or not to use `hasOwnProperty` checks
|
||||||
* in the object loop.
|
* in the object loop.
|
||||||
@@ -469,7 +486,7 @@
|
|||||||
'exit': '',
|
'exit': '',
|
||||||
'init': '',
|
'init': '',
|
||||||
'top': '',
|
'top': '',
|
||||||
'arrayBranch': { 'beforeLoop': '', 'loopExp': '++index < length' },
|
'arrayBranch': { 'beforeLoop': '' },
|
||||||
'objectBranch': { 'beforeLoop': '' }
|
'objectBranch': { 'beforeLoop': '' }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -478,7 +495,7 @@
|
|||||||
for (prop in object) {
|
for (prop in object) {
|
||||||
value = (value = object[prop]) == null ? '' : value;
|
value = (value = object[prop]) == null ? '' : value;
|
||||||
// keep this regexp explicit for the build pre-process
|
// keep this regexp explicit for the build pre-process
|
||||||
if (/beforeLoop|loopExp|inLoop/.test(prop)) {
|
if (/beforeLoop|inLoop/.test(prop)) {
|
||||||
if (typeof value == 'string') {
|
if (typeof value == 'string') {
|
||||||
value = { 'array': value, 'object': value };
|
value = { 'array': value, 'object': value };
|
||||||
}
|
}
|
||||||
@@ -491,29 +508,22 @@
|
|||||||
}
|
}
|
||||||
// set additional template `data` values
|
// set additional template `data` values
|
||||||
var args = data.args,
|
var args = data.args,
|
||||||
arrayBranch = data.arrayBranch,
|
|
||||||
objectBranch = data.objectBranch,
|
|
||||||
firstArg = /^[^,]+/.exec(args)[0],
|
firstArg = /^[^,]+/.exec(args)[0],
|
||||||
loopExp = objectBranch.loopExp,
|
iteratee = (data.iteratee = data.iteratee || firstArg);
|
||||||
iteratedObject = /\S+$/.exec(loopExp || firstArg)[0];
|
|
||||||
|
|
||||||
data.firstArg = firstArg;
|
data.firstArg = firstArg;
|
||||||
data.hasDontEnumBug = hasDontEnumBug;
|
data.hasDontEnumBug = hasDontEnumBug;
|
||||||
data.hasExp = 'hasOwnProperty.call(' + iteratedObject + ', index)';
|
|
||||||
data.isKeysFast = isKeysFast;
|
data.isKeysFast = isKeysFast;
|
||||||
data.iteratedObject = iteratedObject;
|
data.noCharByIndex = noCharByIndex;
|
||||||
data.shadowed = shadowed;
|
data.shadowed = shadowed;
|
||||||
data.useHas = data.useHas !== false;
|
data.useHas = data.useHas !== false;
|
||||||
|
|
||||||
if (!data.exit) {
|
if (!data.exit) {
|
||||||
data.exit = 'if (!' + firstArg + ') return result';
|
data.exit = 'if (!' + firstArg + ') return result';
|
||||||
}
|
}
|
||||||
if (firstArg == 'object' || !arrayBranch.inLoop) {
|
if (firstArg != 'collection' || !data.arrayBranch.inLoop) {
|
||||||
data.arrayBranch = null;
|
data.arrayBranch = null;
|
||||||
}
|
}
|
||||||
if (!loopExp) {
|
|
||||||
objectBranch.loopExp = 'index in ' + iteratedObject;
|
|
||||||
}
|
|
||||||
// create the function factory
|
// create the function factory
|
||||||
var factory = Function(
|
var factory = Function(
|
||||||
'arrayClass, compareAscending, funcClass, hasOwnProperty, identity, ' +
|
'arrayClass, compareAscending, funcClass, hasOwnProperty, identity, ' +
|
||||||
@@ -620,7 +630,7 @@
|
|||||||
*/
|
*/
|
||||||
var shimKeys = createIterator({
|
var shimKeys = createIterator({
|
||||||
'args': 'object',
|
'args': 'object',
|
||||||
'exit': 'if (!objectTypes[typeof object] || object === null) throw TypeError()',
|
'exit': 'if (!(object && objectTypes[typeof object])) throw TypeError()',
|
||||||
'init': '[]',
|
'init': '[]',
|
||||||
'inLoop': 'result.push(index)'
|
'inLoop': 'result.push(index)'
|
||||||
});
|
});
|
||||||
@@ -694,7 +704,7 @@
|
|||||||
* @memberOf _
|
* @memberOf _
|
||||||
* @alias include
|
* @alias include
|
||||||
* @category Collections
|
* @category Collections
|
||||||
* @param {Array|Object} collection The collection to iterate over.
|
* @param {Array|Object|String} collection The collection to iterate over.
|
||||||
* @param {Mixed} target The value to check for.
|
* @param {Mixed} target The value to check for.
|
||||||
* @returns {Boolean} Returns `true` if `target` value is found, else `false`.
|
* @returns {Boolean} Returns `true` if `target` value is found, else `false`.
|
||||||
* @example
|
* @example
|
||||||
@@ -705,7 +715,7 @@
|
|||||||
var contains = createIterator({
|
var contains = createIterator({
|
||||||
'args': 'collection, target',
|
'args': 'collection, target',
|
||||||
'init': 'false',
|
'init': 'false',
|
||||||
'inLoop': 'if (collection[index] === target) return true'
|
'inLoop': 'if (iteratee[index] === target) return true'
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -718,7 +728,7 @@
|
|||||||
* @memberOf _
|
* @memberOf _
|
||||||
* @alias all
|
* @alias all
|
||||||
* @category Collections
|
* @category Collections
|
||||||
* @param {Array|Object} collection The collection to iterate over.
|
* @param {Array|Object|String} collection The collection to iterate over.
|
||||||
* @param {Function} [callback=identity] The function called per iteration.
|
* @param {Function} [callback=identity] The function called per iteration.
|
||||||
* @param {Mixed} [thisArg] The `this` binding for the callback.
|
* @param {Mixed} [thisArg] The `this` binding for the callback.
|
||||||
* @returns {Boolean} Returns `true` if all values pass the callback check, else `false`.
|
* @returns {Boolean} Returns `true` if all values pass the callback check, else `false`.
|
||||||
@@ -739,7 +749,7 @@
|
|||||||
* @memberOf _
|
* @memberOf _
|
||||||
* @alias select
|
* @alias select
|
||||||
* @category Collections
|
* @category Collections
|
||||||
* @param {Array|Object} collection The collection to iterate over.
|
* @param {Array|Object|String} collection The collection to iterate over.
|
||||||
* @param {Function} [callback=identity] The function called per iteration.
|
* @param {Function} [callback=identity] The function called per iteration.
|
||||||
* @param {Mixed} [thisArg] The `this` binding for the callback.
|
* @param {Mixed} [thisArg] The `this` binding for the callback.
|
||||||
* @returns {Array} Returns a new array of values that passed callback check.
|
* @returns {Array} Returns a new array of values that passed callback check.
|
||||||
@@ -761,7 +771,7 @@
|
|||||||
* @memberOf _
|
* @memberOf _
|
||||||
* @alias detect
|
* @alias detect
|
||||||
* @category Collections
|
* @category Collections
|
||||||
* @param {Array|Object} collection The collection to iterate over.
|
* @param {Array|Object|String} collection The collection to iterate over.
|
||||||
* @param {Function} callback The function called per iteration.
|
* @param {Function} callback The function called per iteration.
|
||||||
* @param {Mixed} [thisArg] The `this` binding for the callback.
|
* @param {Mixed} [thisArg] The `this` binding for the callback.
|
||||||
* @returns {Mixed} Returns the value that passed the callback check, else `undefined`.
|
* @returns {Mixed} Returns the value that passed the callback check, else `undefined`.
|
||||||
@@ -772,7 +782,7 @@
|
|||||||
*/
|
*/
|
||||||
var find = createIterator(baseIteratorOptions, forEachIteratorOptions, {
|
var find = createIterator(baseIteratorOptions, forEachIteratorOptions, {
|
||||||
'init': '',
|
'init': '',
|
||||||
'inLoop': 'if (callback(collection[index], index, collection)) return collection[index]'
|
'inLoop': 'if (callback(iteratee[index], index, collection)) return iteratee[index]'
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -785,7 +795,7 @@
|
|||||||
* @memberOf _
|
* @memberOf _
|
||||||
* @alias each
|
* @alias each
|
||||||
* @category Collections
|
* @category Collections
|
||||||
* @param {Array|Object} collection The collection to iterate over.
|
* @param {Array|Object|String} collection The collection to iterate over.
|
||||||
* @param {Function} callback The function called per iteration.
|
* @param {Function} callback The function called per iteration.
|
||||||
* @param {Mixed} [thisArg] The `this` binding for the callback.
|
* @param {Mixed} [thisArg] The `this` binding for the callback.
|
||||||
* @returns {Array|Object} Returns the `collection`.
|
* @returns {Array|Object} Returns the `collection`.
|
||||||
@@ -809,7 +819,7 @@
|
|||||||
* @static
|
* @static
|
||||||
* @memberOf _
|
* @memberOf _
|
||||||
* @category Collections
|
* @category Collections
|
||||||
* @param {Array|Object} collection The collection to iterate over.
|
* @param {Array|Object|String} collection The collection to iterate over.
|
||||||
* @param {Function|String} callback The function called per iteration or
|
* @param {Function|String} callback The function called per iteration or
|
||||||
* property name to group by.
|
* property name to group by.
|
||||||
* @param {Mixed} [thisArg] The `this` binding for the callback.
|
* @param {Mixed} [thisArg] The `this` binding for the callback.
|
||||||
@@ -832,9 +842,9 @@
|
|||||||
'if (isFunc && thisArg) callback = iteratorBind(callback, thisArg)',
|
'if (isFunc && thisArg) callback = iteratorBind(callback, thisArg)',
|
||||||
'inLoop':
|
'inLoop':
|
||||||
'prop = isFunc\n' +
|
'prop = isFunc\n' +
|
||||||
' ? callback(collection[index], index, collection)\n' +
|
' ? callback(iteratee[index], index, collection)\n' +
|
||||||
' : collection[index][callback];\n' +
|
' : iteratee[index][callback];\n' +
|
||||||
'(hasOwnProperty.call(result, prop) ? result[prop] : result[prop] = []).push(collection[index])'
|
'(hasOwnProperty.call(result, prop) ? result[prop] : result[prop] = []).push(iteratee[index])'
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -846,7 +856,7 @@
|
|||||||
* @static
|
* @static
|
||||||
* @memberOf _
|
* @memberOf _
|
||||||
* @category Collections
|
* @category Collections
|
||||||
* @param {Array|Object} collection The collection to iterate over.
|
* @param {Array|Object|String} collection The collection to iterate over.
|
||||||
* @param {Function|String} methodName The name of the method to invoke or
|
* @param {Function|String} methodName The name of the method to invoke or
|
||||||
* the function invoked per iteration.
|
* the function invoked per iteration.
|
||||||
* @param {Mixed} [arg1, arg2, ...] Arguments to invoke the method with.
|
* @param {Mixed} [arg1, arg2, ...] Arguments to invoke the method with.
|
||||||
@@ -865,8 +875,12 @@
|
|||||||
'var args = slice.call(arguments, 2),\n' +
|
'var args = slice.call(arguments, 2),\n' +
|
||||||
' isFunc = typeof methodName == \'function\'',
|
' isFunc = typeof methodName == \'function\'',
|
||||||
'inLoop': {
|
'inLoop': {
|
||||||
'array': 'result[index] = (isFunc ? methodName : collection[index][methodName]).apply(collection[index], args)',
|
'array':
|
||||||
'object': 'result' + (isKeysFast ? '[propIndex] = ' : '.push') + '((isFunc ? methodName : collection[index][methodName]).apply(collection[index], args))'
|
'result[index] = (isFunc ? methodName : iteratee[index][methodName])' +
|
||||||
|
'.apply(iteratee[index], args)',
|
||||||
|
'object':
|
||||||
|
'result' + (isKeysFast ? '[propIndex] = ' : '.push') +
|
||||||
|
'((isFunc ? methodName : iteratee[index][methodName]).apply(iteratee[index], args))'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -880,7 +894,7 @@
|
|||||||
* @memberOf _
|
* @memberOf _
|
||||||
* @alias collect
|
* @alias collect
|
||||||
* @category Collections
|
* @category Collections
|
||||||
* @param {Array|Object} collection The collection to iterate over.
|
* @param {Array|Object|String} collection The collection to iterate over.
|
||||||
* @param {Function} [callback=identity] The function called per iteration.
|
* @param {Function} [callback=identity] The function called per iteration.
|
||||||
* @param {Mixed} [thisArg] The `this` binding for the callback.
|
* @param {Mixed} [thisArg] The `this` binding for the callback.
|
||||||
* @returns {Array} Returns a new array of values returned by the callback.
|
* @returns {Array} Returns a new array of values returned by the callback.
|
||||||
@@ -901,7 +915,7 @@
|
|||||||
* @static
|
* @static
|
||||||
* @memberOf _
|
* @memberOf _
|
||||||
* @category Collections
|
* @category Collections
|
||||||
* @param {Array|Object} collection The collection to iterate over.
|
* @param {Array|Object|String} collection The collection to iterate over.
|
||||||
* @param {String} property The property to pluck.
|
* @param {String} property The property to pluck.
|
||||||
* @returns {Array} Returns a new array of property values.
|
* @returns {Array} Returns a new array of property values.
|
||||||
* @example
|
* @example
|
||||||
@@ -918,8 +932,8 @@
|
|||||||
var pluck = createIterator(mapIteratorOptions, {
|
var pluck = createIterator(mapIteratorOptions, {
|
||||||
'args': 'collection, property',
|
'args': 'collection, property',
|
||||||
'inLoop': {
|
'inLoop': {
|
||||||
'array': 'result[index] = collection[index][property]',
|
'array': 'result[index] = iteratee[index][property]',
|
||||||
'object': 'result' + (isKeysFast ? '[propIndex] = ' : '.push') + '(collection[index][property])'
|
'object': 'result' + (isKeysFast ? '[propIndex] = ' : '.push') + '(iteratee[index][property])'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -934,7 +948,7 @@
|
|||||||
* @memberOf _
|
* @memberOf _
|
||||||
* @alias foldl, inject
|
* @alias foldl, inject
|
||||||
* @category Collections
|
* @category Collections
|
||||||
* @param {Array|Object} collection The collection to iterate over.
|
* @param {Array|Object|String} collection The collection to iterate over.
|
||||||
* @param {Function} callback The function called per iteration.
|
* @param {Function} callback The function called per iteration.
|
||||||
* @param {Mixed} [accumulator] Initial value of the accumulator.
|
* @param {Mixed} [accumulator] Initial value of the accumulator.
|
||||||
* @param {Mixed} [thisArg] The `this` binding for the callback.
|
* @param {Mixed} [thisArg] The `this` binding for the callback.
|
||||||
@@ -955,11 +969,11 @@
|
|||||||
},
|
},
|
||||||
'inLoop': {
|
'inLoop': {
|
||||||
'array':
|
'array':
|
||||||
'result = callback(result, collection[index], index, collection)',
|
'result = callback(result, iteratee[index], index, collection)',
|
||||||
'object':
|
'object':
|
||||||
'result = noaccum\n' +
|
'result = noaccum\n' +
|
||||||
' ? (noaccum = false, collection[index])\n' +
|
' ? (noaccum = false, iteratee[index])\n' +
|
||||||
' : callback(result, collection[index], index, collection)'
|
' : callback(result, iteratee[index], index, collection)'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -970,7 +984,7 @@
|
|||||||
* @memberOf _
|
* @memberOf _
|
||||||
* @alias foldr
|
* @alias foldr
|
||||||
* @category Collections
|
* @category Collections
|
||||||
* @param {Array|Object} collection The collection to iterate over.
|
* @param {Array|Object|String} collection The collection to iterate over.
|
||||||
* @param {Function} callback The function called per iteration.
|
* @param {Function} callback The function called per iteration.
|
||||||
* @param {Mixed} [accumulator] Initial value of the accumulator.
|
* @param {Mixed} [accumulator] Initial value of the accumulator.
|
||||||
* @param {Mixed} [thisArg] The `this` binding for the callback.
|
* @param {Mixed} [thisArg] The `this` binding for the callback.
|
||||||
@@ -993,11 +1007,15 @@
|
|||||||
callback = iteratorBind(callback, thisArg);
|
callback = iteratorBind(callback, thisArg);
|
||||||
}
|
}
|
||||||
if (length === length >>> 0) {
|
if (length === length >>> 0) {
|
||||||
|
var iteratee = noCharByIndex && toString.call(collection) == stringClass
|
||||||
|
? collection.split('')
|
||||||
|
: collection;
|
||||||
|
|
||||||
if (length && noaccum) {
|
if (length && noaccum) {
|
||||||
accumulator = collection[--length];
|
accumulator = iteratee[--length];
|
||||||
}
|
}
|
||||||
while (length--) {
|
while (length--) {
|
||||||
accumulator = callback(accumulator, collection[length], length, collection);
|
accumulator = callback(accumulator, iteratee[length], length, collection);
|
||||||
}
|
}
|
||||||
return accumulator;
|
return accumulator;
|
||||||
}
|
}
|
||||||
@@ -1023,7 +1041,7 @@
|
|||||||
* @static
|
* @static
|
||||||
* @memberOf _
|
* @memberOf _
|
||||||
* @category Collections
|
* @category Collections
|
||||||
* @param {Array|Object} collection The collection to iterate over.
|
* @param {Array|Object|String} collection The collection to iterate over.
|
||||||
* @param {Function} [callback=identity] The function called per iteration.
|
* @param {Function} [callback=identity] The function called per iteration.
|
||||||
* @param {Mixed} [thisArg] The `this` binding for the callback.
|
* @param {Mixed} [thisArg] The `this` binding for the callback.
|
||||||
* @returns {Array} Returns a new array of values that did **not** pass the callback check.
|
* @returns {Array} Returns a new array of values that did **not** pass the callback check.
|
||||||
@@ -1047,7 +1065,7 @@
|
|||||||
* @memberOf _
|
* @memberOf _
|
||||||
* @alias any
|
* @alias any
|
||||||
* @category Collections
|
* @category Collections
|
||||||
* @param {Array|Object} collection The collection to iterate over.
|
* @param {Array|Object|String} collection The collection to iterate over.
|
||||||
* @param {Function} [callback=identity] The function called per iteration.
|
* @param {Function} [callback=identity] The function called per iteration.
|
||||||
* @param {Mixed} [thisArg] The `this` binding for the callback.
|
* @param {Mixed} [thisArg] The `this` binding for the callback.
|
||||||
* @returns {Boolean} Returns `true` if any value passes the callback check, else `false`.
|
* @returns {Boolean} Returns `true` if any value passes the callback check, else `false`.
|
||||||
@@ -1073,7 +1091,7 @@
|
|||||||
* @static
|
* @static
|
||||||
* @memberOf _
|
* @memberOf _
|
||||||
* @category Collections
|
* @category Collections
|
||||||
* @param {Array|Object} collection The collection to iterate over.
|
* @param {Array|Object|String} collection The collection to iterate over.
|
||||||
* @param {Function|String} callback The function called per iteration or
|
* @param {Function|String} callback The function called per iteration or
|
||||||
* property name to sort by.
|
* property name to sort by.
|
||||||
* @param {Mixed} [thisArg] The `this` binding for the callback.
|
* @param {Mixed} [thisArg] The `this` binding for the callback.
|
||||||
@@ -1101,13 +1119,13 @@
|
|||||||
'inLoop': {
|
'inLoop': {
|
||||||
'array':
|
'array':
|
||||||
'result[index] = {\n' +
|
'result[index] = {\n' +
|
||||||
' criteria: callback(collection[index], index, collection),\n' +
|
' criteria: callback(iteratee[index], index, collection),\n' +
|
||||||
' value: collection[index]\n' +
|
' value: iteratee[index]\n' +
|
||||||
'}',
|
'}',
|
||||||
'object':
|
'object':
|
||||||
'result' + (isKeysFast ? '[propIndex] = ' : '.push') + '({\n' +
|
'result' + (isKeysFast ? '[propIndex] = ' : '.push') + '({\n' +
|
||||||
' criteria: callback(collection[index], index, collection),\n' +
|
' criteria: callback(iteratee[index], index, collection),\n' +
|
||||||
' value: collection[index]\n' +
|
' value: iteratee[index]\n' +
|
||||||
'})'
|
'})'
|
||||||
},
|
},
|
||||||
'bottom':
|
'bottom':
|
||||||
@@ -1125,7 +1143,7 @@
|
|||||||
* @static
|
* @static
|
||||||
* @memberOf _
|
* @memberOf _
|
||||||
* @category Collections
|
* @category Collections
|
||||||
* @param {Array|Object} collection The collection to convert.
|
* @param {Array|Object|String} collection The collection to convert.
|
||||||
* @returns {Array} Returns the new converted array.
|
* @returns {Array} Returns the new converted array.
|
||||||
* @example
|
* @example
|
||||||
*
|
*
|
||||||
@@ -1141,7 +1159,9 @@
|
|||||||
}
|
}
|
||||||
var length = collection.length;
|
var length = collection.length;
|
||||||
if (length === length >>> 0) {
|
if (length === length >>> 0) {
|
||||||
return slice.call(collection);
|
return noCharByIndex && toString.call(collection) == stringClass
|
||||||
|
? collection.split('')
|
||||||
|
: slice.call(collection);
|
||||||
}
|
}
|
||||||
return values(collection);
|
return values(collection);
|
||||||
}
|
}
|
||||||
@@ -2008,7 +2028,7 @@
|
|||||||
// mimic the constructor's `return` behavior
|
// mimic the constructor's `return` behavior
|
||||||
// http://es5.github.com/#x13.2.2
|
// http://es5.github.com/#x13.2.2
|
||||||
var result = func.apply(thisBinding, args);
|
var result = func.apply(thisBinding, args);
|
||||||
return objectTypes[typeof result] && result !== null
|
return result && objectTypes[typeof result]
|
||||||
? result
|
? result
|
||||||
: thisBinding
|
: thisBinding
|
||||||
}
|
}
|
||||||
@@ -2366,7 +2386,7 @@
|
|||||||
* // => { 'name': 'moe' };
|
* // => { 'name': 'moe' };
|
||||||
*/
|
*/
|
||||||
function clone(value) {
|
function clone(value) {
|
||||||
return objectTypes[typeof value] && value !== null
|
return value && objectTypes[typeof value]
|
||||||
? (isArray(value) ? value.slice() : extend({}, value))
|
? (isArray(value) ? value.slice() : extend({}, value))
|
||||||
: value;
|
: value;
|
||||||
}
|
}
|
||||||
@@ -2389,7 +2409,7 @@
|
|||||||
* // => { 'flavor': 'chocolate', 'sprinkles': 'rainbow' }
|
* // => { 'flavor': 'chocolate', 'sprinkles': 'rainbow' }
|
||||||
*/
|
*/
|
||||||
var defaults = createIterator(extendIteratorOptions, {
|
var defaults = createIterator(extendIteratorOptions, {
|
||||||
'inLoop': 'if (object[index] == null)' + extendIteratorOptions.inLoop
|
'inLoop': 'if (result[index] == null) ' + extendIteratorOptions.inLoop
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2480,7 +2500,7 @@
|
|||||||
'args': 'object',
|
'args': 'object',
|
||||||
'init': '[]',
|
'init': '[]',
|
||||||
'useHas': false,
|
'useHas': false,
|
||||||
'inLoop': 'if (toString.call(object[index]) == funcClass) result.push(index)',
|
'inLoop': 'if (toString.call(iteratee[index]) == funcClass) result.push(index)',
|
||||||
'bottom': 'result.sort()'
|
'bottom': 'result.sort()'
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -2853,7 +2873,7 @@
|
|||||||
function isObject(value) {
|
function isObject(value) {
|
||||||
// check if the value is the ECMAScript language type of Object
|
// check if the value is the ECMAScript language type of Object
|
||||||
// http://es5.github.com/#x8
|
// http://es5.github.com/#x8
|
||||||
return objectTypes[typeof value] && value !== null;
|
return value && objectTypes[typeof value];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -3075,7 +3095,7 @@
|
|||||||
var values = createIterator({
|
var values = createIterator({
|
||||||
'args': 'object',
|
'args': 'object',
|
||||||
'init': '[]',
|
'init': '[]',
|
||||||
'inLoop': 'result.push(object[index])'
|
'inLoop': 'result.push(iteratee[index])'
|
||||||
});
|
});
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
@@ -3274,21 +3294,21 @@
|
|||||||
startIndex,
|
startIndex,
|
||||||
result,
|
result,
|
||||||
useWith,
|
useWith,
|
||||||
defaults = lodash.templateSettings,
|
|
||||||
escapeDelimiter = options.escape,
|
escapeDelimiter = options.escape,
|
||||||
evaluateDelimiter = options.evaluate,
|
evaluateDelimiter = options.evaluate,
|
||||||
interpolateDelimiter = options.interpolate,
|
interpolateDelimiter = options.interpolate,
|
||||||
|
settings = lodash.templateSettings,
|
||||||
variable = options.variable;
|
variable = options.variable;
|
||||||
|
|
||||||
// use template defaults if no option is provided
|
// use default settings if no options object is provided
|
||||||
if (escapeDelimiter == null) {
|
if (escapeDelimiter == null) {
|
||||||
escapeDelimiter = defaults.escape;
|
escapeDelimiter = settings.escape;
|
||||||
}
|
}
|
||||||
if (evaluateDelimiter == null) {
|
if (evaluateDelimiter == null) {
|
||||||
evaluateDelimiter = defaults.evaluate;
|
evaluateDelimiter = settings.evaluate;
|
||||||
}
|
}
|
||||||
if (interpolateDelimiter == null) {
|
if (interpolateDelimiter == null) {
|
||||||
interpolateDelimiter = defaults.interpolate;
|
interpolateDelimiter = settings.interpolate;
|
||||||
}
|
}
|
||||||
|
|
||||||
// tokenize delimiters to avoid escaping them
|
// tokenize delimiters to avoid escaping them
|
||||||
@@ -3314,7 +3334,7 @@
|
|||||||
// delimiters, inject a with-statement around all "evaluate" delimiters to
|
// delimiters, inject a with-statement around all "evaluate" delimiters to
|
||||||
// add the data object to the top of the scope chain
|
// add the data object to the top of the scope chain
|
||||||
if (!variable) {
|
if (!variable) {
|
||||||
variable = defaults.variable || lastVariable || 'obj';
|
variable = settings.variable || lastVariable || 'obj';
|
||||||
useWith = isEvaluating;
|
useWith = isEvaluating;
|
||||||
|
|
||||||
if (useWith) {
|
if (useWith) {
|
||||||
@@ -3349,7 +3369,7 @@
|
|||||||
lastVariable = variable;
|
lastVariable = variable;
|
||||||
reDoubleVariable = RegExp('([(\\s])' + variable + '\\.' + variable + '\\b', 'g');
|
reDoubleVariable = RegExp('([(\\s])' + variable + '\\.' + variable + '\\b', 'g');
|
||||||
}
|
}
|
||||||
// inject data object references outside of the with-statement
|
// prepend data object references to property names outside of the with-statement
|
||||||
text = (useWith ? text.slice(0, startIndex) : text)
|
text = (useWith ? text.slice(0, startIndex) : text)
|
||||||
.replace(reInsertVariable, strInsertVariable)
|
.replace(reInsertVariable, strInsertVariable)
|
||||||
.replace(reDoubleVariable, strDoubleVariable) +
|
.replace(reDoubleVariable, strDoubleVariable) +
|
||||||
|
|||||||
Reference in New Issue
Block a user