From 1608d89174030619b257346853f3ad15c38875e0 Mon Sep 17 00:00:00 2001 From: jdalton Date: Sun, 1 Feb 2015 22:03:53 -0800 Subject: [PATCH] Bump to v3.1.0. --- README.md | 2 +- chain/lodash.js | 6 +-- collection/findWhere.js | 4 +- collection/pluck.js | 4 +- collection/where.js | 4 +- internal/baseCallback.js | 2 +- internal/baseMatches.js | 8 +--- internal/isIndex.js | 2 +- internal/isIterateeCall.js | 2 +- internal/isLength.js | 6 ++- main.js | 80 +++++++++++++++++++++++++------------- package.json | 2 +- string.js | 3 +- string/camelCase.js | 2 +- string/snakeCase.js | 4 +- string/startCase.js | 29 ++++++++++++++ string/trim.js | 2 +- string/trimLeft.js | 2 +- string/trimRight.js | 2 +- utility/callback.js | 6 ++- utility/matches.js | 4 +- 21 files changed, 118 insertions(+), 58 deletions(-) create mode 100644 string/startCase.js diff --git a/README.md b/README.md index 04922e847..2d65901b4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# lodash v3.0.1 +# lodash v3.1.0 The [modern build](https://github.com/lodash/lodash/wiki/Build-Differences) of [lodash](https://lodash.com/) exported as [AMD](https://github.com/amdjs/amdjs-api/wiki/AMD) modules. diff --git a/chain/lodash.js b/chain/lodash.js index c30b59c2c..603126a15 100644 --- a/chain/lodash.js +++ b/chain/lodash.js @@ -54,14 +54,14 @@ define(['../internal/LodashWrapper', '../internal/arrayCopy', '../lang/isArray', * `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, `has`, * `identity`, `includes`, `indexOf`, `isArguments`, `isArray`, `isBoolean`, * `isDate`, `isElement`, `isEmpty`, `isEqual`, `isError`, `isFinite`, - * `isFunction`, `isMatch` , `isNative`, `isNaN`, `isNull`, `isNumber`, + * `isFunction`, `isMatch`, `isNative`, `isNaN`, `isNull`, `isNumber`, * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, * `isTypedArray`, `join`, `kebabCase`, `last`, `lastIndexOf`, `max`, `min`, * `noConflict`, `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, * `random`, `reduce`, `reduceRight`, `repeat`, `result`, `runInContext`, * `shift`, `size`, `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, - * `startsWith`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`, - * `unescape`, `uniqueId`, `value`, and `words` + * `startCase`, `startsWith`, `template`, `trim`, `trimLeft`, `trimRight`, + * `trunc`, `unescape`, `uniqueId`, `value`, and `words` * * The wrapper function `sample` will return a wrapped value when `n` is provided, * otherwise an unwrapped value is returned. diff --git a/collection/findWhere.js b/collection/findWhere.js index c949868fd..bf7098a6d 100644 --- a/collection/findWhere.js +++ b/collection/findWhere.js @@ -1,4 +1,4 @@ -define(['./find', '../utility/matches'], function(find, matches) { +define(['../internal/baseMatches', './find'], function(baseMatches, find) { /** * Performs a deep comparison between each element in `collection` and the @@ -25,7 +25,7 @@ define(['./find', '../utility/matches'], function(find, matches) { * // => 'fred' */ function findWhere(collection, source) { - return find(collection, matches(source)); + return find(collection, baseMatches(source)); } return findWhere; diff --git a/collection/pluck.js b/collection/pluck.js index f3052bc26..7d8505a4c 100644 --- a/collection/pluck.js +++ b/collection/pluck.js @@ -1,4 +1,4 @@ -define(['./map', '../utility/property'], function(map, property) { +define(['../internal/baseProperty', './map'], function(baseProperty, map) { /** * Gets the value of `key` from all elements in `collection`. @@ -24,7 +24,7 @@ define(['./map', '../utility/property'], function(map, property) { * // => [36, 40] (iteration order is not guaranteed) */ function pluck(collection, key) { - return map(collection, property(key)); + return map(collection, baseProperty(key + '')); } return pluck; diff --git a/collection/where.js b/collection/where.js index 433abb8f6..d7d6613cb 100644 --- a/collection/where.js +++ b/collection/where.js @@ -1,4 +1,4 @@ -define(['./filter', '../utility/matches'], function(filter, matches) { +define(['../internal/baseMatches', './filter'], function(baseMatches, filter) { /** * Performs a deep comparison between each element in `collection` and the @@ -28,7 +28,7 @@ define(['./filter', '../utility/matches'], function(filter, matches) { * // => ['barney', 'fred'] */ function where(collection, source) { - return filter(collection, matches(source)); + return filter(collection, baseMatches(source)); } return where; diff --git a/internal/baseCallback.js b/internal/baseCallback.js index de8dace0c..9f1a1a9a6 100644 --- a/internal/baseCallback.js +++ b/internal/baseCallback.js @@ -22,7 +22,7 @@ define(['./baseMatches', './baseProperty', './bindCallback', '../utility/identit } // Handle "_.property" and "_.matches" style callback shorthands. return type == 'object' - ? baseMatches(func, !argCount) + ? baseMatches(func) : baseProperty(func + ''); } diff --git a/internal/baseMatches.js b/internal/baseMatches.js index 2b8fac751..f980830ac 100644 --- a/internal/baseMatches.js +++ b/internal/baseMatches.js @@ -1,4 +1,4 @@ -define(['./baseClone', './baseIsMatch', './isStrictComparable', '../object/keys'], function(baseClone, baseIsMatch, isStrictComparable, keys) { +define(['./baseIsMatch', './isStrictComparable', '../object/keys'], function(baseIsMatch, isStrictComparable, keys) { /** Used for native method references. */ var objectProto = Object.prototype; @@ -12,10 +12,9 @@ define(['./baseClone', './baseIsMatch', './isStrictComparable', '../object/keys' * * @private * @param {Object} source The object of property values to match. - * @param {boolean} [isCloned] Specify cloning the source object. * @returns {Function} Returns the new function. */ - function baseMatches(source, isCloned) { + function baseMatches(source) { var props = keys(source), length = props.length; @@ -29,9 +28,6 @@ define(['./baseClone', './baseIsMatch', './isStrictComparable', '../object/keys' }; } } - if (isCloned) { - source = baseClone(source, true); - } var values = Array(length), strictCompareFlags = Array(length); diff --git a/internal/isIndex.js b/internal/isIndex.js index 8566b1ba3..28f79eef4 100644 --- a/internal/isIndex.js +++ b/internal/isIndex.js @@ -2,7 +2,7 @@ define([], function() { /** * Used as the maximum length of an array-like value. - * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength) + * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer) * for more details. */ var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1; diff --git a/internal/isIterateeCall.js b/internal/isIterateeCall.js index 7174a8dd6..99e93d5bf 100644 --- a/internal/isIterateeCall.js +++ b/internal/isIterateeCall.js @@ -18,7 +18,7 @@ define(['./isIndex', './isLength', '../lang/isObject'], function(isIndex, isLeng var length = object.length, prereq = isLength(length) && isIndex(index, length); } else { - prereq = type == 'string' && index in value; + prereq = type == 'string' && index in object; } return prereq && object[index] === value; } diff --git a/internal/isLength.js b/internal/isLength.js index 3069b5435..165e7a0b7 100644 --- a/internal/isLength.js +++ b/internal/isLength.js @@ -2,7 +2,7 @@ define([], function() { /** * Used as the maximum length of an array-like value. - * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength) + * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer) * for more details. */ var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1; @@ -10,6 +10,10 @@ define([], function() { /** * Checks if `value` is a valid array-like length. * + * **Note:** This function is based on ES `ToLength`. See the + * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength) + * for more details. + * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. diff --git a/main.js b/main.js index fa8a8d40a..09056091a 100644 --- a/main.js +++ b/main.js @@ -1,6 +1,6 @@ /** * @license - * lodash 3.0.1 (Custom Build) + * lodash 3.1.0 (Custom Build) * Build: `lodash modern exports="amd" -d -o ./main.js` * Copyright 2012-2015 The Dojo Foundation * Based on Underscore.js 1.7.0 @@ -13,7 +13,7 @@ var undefined; /** Used as the semantic version number. */ - var VERSION = '3.0.1'; + var VERSION = '3.1.0'; /** Used to compose bitmasks for wrapper metadata. */ var BIND_FLAG = 1, @@ -766,7 +766,7 @@ /** * Used as the maximum length of an array-like value. - * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength) + * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer) * for more details. */ var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1; @@ -824,14 +824,14 @@ * `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, `has`, * `identity`, `includes`, `indexOf`, `isArguments`, `isArray`, `isBoolean`, * `isDate`, `isElement`, `isEmpty`, `isEqual`, `isError`, `isFinite`, - * `isFunction`, `isMatch` , `isNative`, `isNaN`, `isNull`, `isNumber`, + * `isFunction`, `isMatch`, `isNative`, `isNaN`, `isNull`, `isNumber`, * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, * `isTypedArray`, `join`, `kebabCase`, `last`, `lastIndexOf`, `max`, `min`, * `noConflict`, `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, * `random`, `reduce`, `reduceRight`, `repeat`, `result`, `runInContext`, * `shift`, `size`, `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, - * `startsWith`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`, - * `unescape`, `uniqueId`, `value`, and `words` + * `startCase`, `startsWith`, `template`, `trim`, `trimLeft`, `trimRight`, + * `trunc`, `unescape`, `uniqueId`, `value`, and `words` * * The wrapper function `sample` will return a wrapped value when `n` is provided, * otherwise an unwrapped value is returned. @@ -1644,7 +1644,7 @@ } // Handle "_.property" and "_.matches" style callback shorthands. return type == 'object' - ? baseMatches(func, !argCount) + ? baseMatches(func) : baseProperty(func + ''); } @@ -2265,10 +2265,9 @@ * * @private * @param {Object} source The object of property values to match. - * @param {boolean} [isCloned] Specify cloning the source object. * @returns {Function} Returns the new function. */ - function baseMatches(source, isCloned) { + function baseMatches(source) { var props = keys(source), length = props.length; @@ -2282,9 +2281,6 @@ }; } } - if (isCloned) { - source = baseClone(source, true); - } var values = Array(length), strictCompareFlags = Array(length); @@ -3595,7 +3591,7 @@ var length = object.length, prereq = isLength(length) && isIndex(index, length); } else { - prereq = type == 'string' && index in value; + prereq = type == 'string' && index in object; } return prereq && object[index] === value; } @@ -3603,6 +3599,10 @@ /** * Checks if `value` is a valid array-like length. * + * **Note:** This function is based on ES `ToLength`. See the + * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength) + * for more details. + * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. @@ -5673,7 +5673,7 @@ * // => 'fred' */ function findWhere(collection, source) { - return find(collection, matches(source)); + return find(collection, baseMatches(source)); } /** @@ -6050,7 +6050,7 @@ * // => [36, 40] (iteration order is not guaranteed) */ function pluck(collection, key) { - return map(collection, property(key)); + return map(collection, baseProperty(key + '')); } /** @@ -6421,7 +6421,7 @@ * // => ['barney', 'fred'] */ function where(collection, source) { - return filter(collection, matches(source)); + return filter(collection, baseMatches(source)); } /*------------------------------------------------------------------------*/ @@ -9066,7 +9066,7 @@ */ var camelCase = createCompounder(function(result, word, index) { word = word.toLowerCase(); - return index ? (result + word.charAt(0).toUpperCase() + word.slice(1)) : word; + return result + (index ? (word.charAt(0).toUpperCase() + word.slice(1)) : word); }); /** @@ -9417,16 +9417,41 @@ * _.snakeCase('Foo Bar'); * // => 'foo_bar' * - * _.snakeCase('--foo-bar'); + * _.snakeCase('fooBar'); * // => 'foo_bar' * - * _.snakeCase('fooBar'); + * _.snakeCase('--foo-bar'); * // => 'foo_bar' */ var snakeCase = createCompounder(function(result, word, index) { return result + (index ? '_' : '') + word.toLowerCase(); }); + /** + * Converts `string` to start case. + * See [Wikipedia](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage) + * for more details. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the start cased string. + * @example + * + * _.startCase('--foo-bar'); + * // => 'Foo Bar' + * + * _.startCase('fooBar'); + * // => 'Foo Bar' + * + * _.startCase('__foo_bar__'); + * // => 'Foo Bar' + */ + var startCase = createCompounder(function(result, word, index) { + return result + (index ? ' ' : '') + (word.charAt(0).toUpperCase() + word.slice(1)); + }); + /** * Checks if `string` starts with the given target string. * @@ -9686,7 +9711,7 @@ if (guard ? isIterateeCall(value, chars, guard) : chars == null) { return string.slice(trimmedLeftIndex(string), trimmedRightIndex(string) + 1); } - chars = baseToString(chars); + chars = (chars + ''); return string.slice(charsLeftIndex(string, chars), charsRightIndex(string, chars) + 1); } @@ -9717,7 +9742,7 @@ if (guard ? isIterateeCall(value, chars, guard) : chars == null) { return string.slice(trimmedLeftIndex(string)) } - return string.slice(charsLeftIndex(string, baseToString(chars))); + return string.slice(charsLeftIndex(string, (chars + ''))); } /** @@ -9747,7 +9772,7 @@ if (guard ? isIterateeCall(value, chars, guard) : chars == null) { return string.slice(0, trimmedRightIndex(string) + 1) } - return string.slice(0, charsRightIndex(string, baseToString(chars)) + 1); + return string.slice(0, charsRightIndex(string, (chars + '')) + 1); } /** @@ -9954,7 +9979,9 @@ if (guard && isIterateeCall(func, thisArg, guard)) { thisArg = null; } - return baseCallback(func, thisArg); + return isObjectLike(func) + ? matches(func) + : baseCallback(func, thisArg); } /** @@ -10022,7 +10049,7 @@ * // => { 'user': 'barney', 'age': 36 } */ function matches(source) { - return baseMatches(source, true); + return baseMatches(baseClone(source, true)); } /** @@ -10519,6 +10546,7 @@ lodash.some = some; lodash.sortedIndex = sortedIndex; lodash.sortedLastIndex = sortedLastIndex; + lodash.startCase = startCase; lodash.startsWith = startsWith; lodash.template = template; lodash.trim = trim; @@ -10644,10 +10672,10 @@ // Add `LazyWrapper` methods for `_.pluck` and `_.where`. arrayEach(['pluck', 'where'], function(methodName, index) { var operationName = index ? 'filter' : 'map', - createCallback = index ? matches : property; + createCallback = index ? baseMatches : baseProperty; LazyWrapper.prototype[methodName] = function(value) { - return this[operationName](createCallback(value)); + return this[operationName](createCallback(index ? value : (value + ''))); }; }); diff --git a/package.json b/package.json index 5d26c56b0..5fcad7450 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lodash", - "version": "3.0.1", + "version": "3.1.0", "main": "main.js", "private": true, "volo": { diff --git a/string.js b/string.js index 87406d0d5..b1e317936 100644 --- a/string.js +++ b/string.js @@ -1,4 +1,4 @@ -define(['./string/camelCase', './string/capitalize', './string/deburr', './string/endsWith', './string/escape', './string/escapeRegExp', './string/kebabCase', './string/pad', './string/padLeft', './string/padRight', './string/parseInt', './string/repeat', './string/snakeCase', './string/startsWith', './string/template', './string/templateSettings', './string/trim', './string/trimLeft', './string/trimRight', './string/trunc', './string/unescape', './string/words'], function(camelCase, capitalize, deburr, endsWith, escape, escapeRegExp, kebabCase, pad, padLeft, padRight, parseInt, repeat, snakeCase, startsWith, template, templateSettings, trim, trimLeft, trimRight, trunc, unescape, words) { +define(['./string/camelCase', './string/capitalize', './string/deburr', './string/endsWith', './string/escape', './string/escapeRegExp', './string/kebabCase', './string/pad', './string/padLeft', './string/padRight', './string/parseInt', './string/repeat', './string/snakeCase', './string/startCase', './string/startsWith', './string/template', './string/templateSettings', './string/trim', './string/trimLeft', './string/trimRight', './string/trunc', './string/unescape', './string/words'], function(camelCase, capitalize, deburr, endsWith, escape, escapeRegExp, kebabCase, pad, padLeft, padRight, parseInt, repeat, snakeCase, startCase, startsWith, template, templateSettings, trim, trimLeft, trimRight, trunc, unescape, words) { return { 'camelCase': camelCase, 'capitalize': capitalize, @@ -13,6 +13,7 @@ define(['./string/camelCase', './string/capitalize', './string/deburr', './strin 'parseInt': parseInt, 'repeat': repeat, 'snakeCase': snakeCase, + 'startCase': startCase, 'startsWith': startsWith, 'template': template, 'templateSettings': templateSettings, diff --git a/string/camelCase.js b/string/camelCase.js index 63e41b387..88f374b53 100644 --- a/string/camelCase.js +++ b/string/camelCase.js @@ -22,7 +22,7 @@ define(['../internal/createCompounder'], function(createCompounder) { */ var camelCase = createCompounder(function(result, word, index) { word = word.toLowerCase(); - return index ? (result + word.charAt(0).toUpperCase() + word.slice(1)) : word; + return result + (index ? (word.charAt(0).toUpperCase() + word.slice(1)) : word); }); return camelCase; diff --git a/string/snakeCase.js b/string/snakeCase.js index 3f338b296..607f6b852 100644 --- a/string/snakeCase.js +++ b/string/snakeCase.js @@ -14,10 +14,10 @@ define(['../internal/createCompounder'], function(createCompounder) { * _.snakeCase('Foo Bar'); * // => 'foo_bar' * - * _.snakeCase('--foo-bar'); + * _.snakeCase('fooBar'); * // => 'foo_bar' * - * _.snakeCase('fooBar'); + * _.snakeCase('--foo-bar'); * // => 'foo_bar' */ var snakeCase = createCompounder(function(result, word, index) { diff --git a/string/startCase.js b/string/startCase.js new file mode 100644 index 000000000..6a0d4b156 --- /dev/null +++ b/string/startCase.js @@ -0,0 +1,29 @@ +define(['../internal/createCompounder'], function(createCompounder) { + + /** + * Converts `string` to start case. + * See [Wikipedia](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage) + * for more details. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the start cased string. + * @example + * + * _.startCase('--foo-bar'); + * // => 'Foo Bar' + * + * _.startCase('fooBar'); + * // => 'Foo Bar' + * + * _.startCase('__foo_bar__'); + * // => 'Foo Bar' + */ + var startCase = createCompounder(function(result, word, index) { + return result + (index ? ' ' : '') + (word.charAt(0).toUpperCase() + word.slice(1)); + }); + + return startCase; +}); diff --git a/string/trim.js b/string/trim.js index 68aa6c84f..ea2b6f6ee 100644 --- a/string/trim.js +++ b/string/trim.js @@ -30,7 +30,7 @@ define(['../internal/baseToString', '../internal/charsLeftIndex', '../internal/c if (guard ? isIterateeCall(value, chars, guard) : chars == null) { return string.slice(trimmedLeftIndex(string), trimmedRightIndex(string) + 1); } - chars = baseToString(chars); + chars = (chars + ''); return string.slice(charsLeftIndex(string, chars), charsRightIndex(string, chars) + 1); } diff --git a/string/trimLeft.js b/string/trimLeft.js index 310e75ff6..b11eff02d 100644 --- a/string/trimLeft.js +++ b/string/trimLeft.js @@ -27,7 +27,7 @@ define(['../internal/baseToString', '../internal/charsLeftIndex', '../internal/i if (guard ? isIterateeCall(value, chars, guard) : chars == null) { return string.slice(trimmedLeftIndex(string)) } - return string.slice(charsLeftIndex(string, baseToString(chars))); + return string.slice(charsLeftIndex(string, (chars + ''))); } return trimLeft; diff --git a/string/trimRight.js b/string/trimRight.js index 2ed4123e3..f9627443d 100644 --- a/string/trimRight.js +++ b/string/trimRight.js @@ -27,7 +27,7 @@ define(['../internal/baseToString', '../internal/charsRightIndex', '../internal/ if (guard ? isIterateeCall(value, chars, guard) : chars == null) { return string.slice(0, trimmedRightIndex(string) + 1) } - return string.slice(0, charsRightIndex(string, baseToString(chars)) + 1); + return string.slice(0, charsRightIndex(string, (chars + '')) + 1); } return trimRight; diff --git a/utility/callback.js b/utility/callback.js index bed0d9a60..4523e9f37 100644 --- a/utility/callback.js +++ b/utility/callback.js @@ -1,4 +1,4 @@ -define(['../internal/baseCallback', '../internal/isIterateeCall'], function(baseCallback, isIterateeCall) { +define(['../internal/baseCallback', '../internal/isIterateeCall', '../internal/isObjectLike', './matches'], function(baseCallback, isIterateeCall, isObjectLike, matches) { /** * Creates a function bound to an optional `thisArg`. If `func` is a property @@ -39,7 +39,9 @@ define(['../internal/baseCallback', '../internal/isIterateeCall'], function(base if (guard && isIterateeCall(func, thisArg, guard)) { thisArg = null; } - return baseCallback(func, thisArg); + return isObjectLike(func) + ? matches(func) + : baseCallback(func, thisArg); } return callback; diff --git a/utility/matches.js b/utility/matches.js index 554274588..4a73a2a3b 100644 --- a/utility/matches.js +++ b/utility/matches.js @@ -1,4 +1,4 @@ -define(['../internal/baseMatches'], function(baseMatches) { +define(['../internal/baseClone', '../internal/baseMatches'], function(baseClone, baseMatches) { /** * Creates a function which performs a deep comparison between a given object @@ -26,7 +26,7 @@ define(['../internal/baseMatches'], function(baseMatches) { * // => { 'user': 'barney', 'age': 36 } */ function matches(source) { - return baseMatches(source, true); + return baseMatches(baseClone(source, true)); } return matches;