mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-01-29 14:37:49 +00:00
Compare commits
111 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6ce9df8504 | ||
|
|
2a0b223896 | ||
|
|
c2db180829 | ||
|
|
3223e4ffa5 | ||
|
|
24c9b6e211 | ||
|
|
e5555dd26a | ||
|
|
ee2d0ddf8a | ||
|
|
aef130b396 | ||
|
|
fbdadec5e5 | ||
|
|
a068339079 | ||
|
|
3f07d3ec55 | ||
|
|
62e7da9d8a | ||
|
|
b60d43e5f6 | ||
|
|
a5873a3158 | ||
|
|
3a698eb0ed | ||
|
|
1e2ef542e4 | ||
|
|
94e8af4d93 | ||
|
|
250a0ab5eb | ||
|
|
2da05d88a0 | ||
|
|
7faa849a89 | ||
|
|
c5bceb8fc8 | ||
|
|
1e94b93ce6 | ||
|
|
3f7bccf2e6 | ||
|
|
181b869109 | ||
|
|
2332245be1 | ||
|
|
3c6999f3a4 | ||
|
|
5f2f15b976 | ||
|
|
47dfb5b6b7 | ||
|
|
c410c1293e | ||
|
|
ca1c732f31 | ||
|
|
5e8c373bf4 | ||
|
|
51a459fe48 | ||
|
|
03c07abbc3 | ||
|
|
5eabe1a172 | ||
|
|
5b6ea7afb2 | ||
|
|
7c1c5e70ca | ||
|
|
d475f8f965 | ||
|
|
fd239076dd | ||
|
|
5f786bbe47 | ||
|
|
f66dc6bed8 | ||
|
|
52c36ac445 | ||
|
|
8f6a78cba5 | ||
|
|
7053e9113f | ||
|
|
89f9ab9940 | ||
|
|
240bc40b39 | ||
|
|
74649b5f28 | ||
|
|
b484d4b2dc | ||
|
|
da1124dd37 | ||
|
|
210485d0be | ||
|
|
d9aee5ae60 | ||
|
|
9ac64623fc | ||
|
|
6ea4226680 | ||
|
|
c1416bba39 | ||
|
|
ddb3ab3238 | ||
|
|
5e7c9698c7 | ||
|
|
4c66b95516 | ||
|
|
2d03060a0d | ||
|
|
3313b0aa42 | ||
|
|
5d2928d2b3 | ||
|
|
f6e2ae41d6 | ||
|
|
7ccb038b6d | ||
|
|
7d62bbf74f | ||
|
|
3d8cc32302 | ||
|
|
861eea5148 | ||
|
|
b432721fe5 | ||
|
|
f13a0cc7e0 | ||
|
|
1f7e37a1a3 | ||
|
|
548e9cac26 | ||
|
|
0d2a1641c9 | ||
|
|
a67281f8e7 | ||
|
|
281475e6ef | ||
|
|
a5712fc873 | ||
|
|
205ded45e2 | ||
|
|
8ef039b9db | ||
|
|
3d2428b278 | ||
|
|
35d5704e3f | ||
|
|
c1860d30d6 | ||
|
|
e0fba5cb51 | ||
|
|
570ba189ed | ||
|
|
e335e0fd72 | ||
|
|
74a2d8dcb1 | ||
|
|
43ea0c9072 | ||
|
|
dde3eb2e36 | ||
|
|
2008bf90af | ||
|
|
06ffa93bd0 | ||
|
|
5da03cac79 | ||
|
|
8a5eb89aa8 | ||
|
|
f81ede2fd6 | ||
|
|
6f7df67ded | ||
|
|
bb9ad69219 | ||
|
|
8f7667a524 | ||
|
|
86e125a6f3 | ||
|
|
8b3ba13ff0 | ||
|
|
82f062caf2 | ||
|
|
67303eb9fb | ||
|
|
af3ded68c4 | ||
|
|
b94eb44e18 | ||
|
|
c62b24b024 | ||
|
|
baa37450cc | ||
|
|
231fd46cd2 | ||
|
|
b2728d9902 | ||
|
|
451a33f526 | ||
|
|
3670bce918 | ||
|
|
afb041b23c | ||
|
|
5315058e2d | ||
|
|
26d9cc972e | ||
|
|
52ae87812e | ||
|
|
f8af24b383 | ||
|
|
b38947146e | ||
|
|
5c48abff4b | ||
|
|
3994c7fc2b |
132
README.md
132
README.md
@@ -1,12 +1,18 @@
|
||||
# Lo-Dash <sup>v0.2.0</sup>
|
||||
# Lo-Dash <sup>v0.3.2</sup>
|
||||
|
||||
A drop-in replacement for Underscore.js, from the devs behind [jsPerf.com](http://jsperf.com), that delivers [performance improvements](http://jsperf.com/lodash-underscore#filterby=family), bug fixes, and additional features.
|
||||
A drop-in replacement for Underscore.js, from the devs behind [jsPerf.com](http://jsperf.com), that delivers [performance improvements](http://lodash.com/benchmarks), [bug fixes](https://github.com/bestiejs/lodash#closed-underscorejs-issues), and [additional features](https://github.com/bestiejs/lodash#features).
|
||||
|
||||
Lo-Dash’s performance is gained by avoiding slower native methods, instead opting for simplified non-ES5 compliant methods optimized for common usage, and by leveraging function compilation to reduce the number of overall function calls.
|
||||
|
||||
## Download
|
||||
|
||||
* [Development source](https://raw.github.com/bestiejs/lodash/v0.3.2/lodash.js)
|
||||
* [Production source](https://raw.github.com/bestiejs/lodash/v0.3.2/lodash.min.js)
|
||||
* For optimal performance, [create a custom build](https://github.com/bestiejs/lodash#custom-builds) with only the features you need
|
||||
|
||||
## Dive in
|
||||
|
||||
We’ve got [API docs](http://lodash.com/docs) and [unit tests](http://lodash.com/tests).
|
||||
We’ve got [API docs](http://lodash.com/docs), [benchmarks](http://lodash.com/benchmarks), and [unit tests](http://lodash.com/tests).
|
||||
|
||||
For a list of upcoming features, check out our [roadmap](https://github.com/bestiejs/lodash/wiki/Roadmap).
|
||||
|
||||
@@ -19,35 +25,63 @@ For more information check out these screencasts over Lo-Dash:
|
||||
|
||||
## Features
|
||||
|
||||
* AMD loader support
|
||||
* [_.bind](http://lodash.com/docs#_bindfunc--arg1-arg2-) supports *"lazy"* binding
|
||||
* [_.debounce](http://lodash.com/docs#_debouncefunc-wait-immediate)’ed functions match [_.throttle](http://lodash.com/docs#_throttlefunc-wait)’ed functions’ return value behavior
|
||||
* [_.forEach](http://lodash.com/docs#_foreachcollection-callback--thisarg) is chainable
|
||||
* [_.groupBy](http://lodash.com/docs#_groupbycollection-callback--thisarg) accepts a third `thisArg` argument
|
||||
* [_.partial](http://lodash.com/docs#_partialfunc--arg1-arg2-) for more functional fun
|
||||
* [_.size](http://lodash.com/docs#_sizecollection) returns the `length` of string values
|
||||
* AMD loader support ([RequireJS](http://requirejs.org/), [curl.js](https://github.com/cujojs/curl), etc.)
|
||||
* [_.bind](http://lodash.com/docs#bind) supports *"lazy"* binding
|
||||
* [_.debounce](http://lodash.com/docs#debounce)’ed functions match [_.throttle](http://lodash.com/docs#throttle)’ed functions’ return value behavior
|
||||
* [_.forEach](http://lodash.com/docs#forEach) is chainable
|
||||
* [_.forIn](http://lodash.com/docs#forIn) for iterating over an object’s own and inherited properties
|
||||
* [_.forOwn](http://lodash.com/docs#forOwn) for iterating over an object’s own properties
|
||||
* [_.groupBy](http://lodash.com/docs#groupBy), [_.sortedIndex](http://lodash.com/docs#sortedIndex), and [_.uniq](http://lodash.com/docs#uniq) accept a `thisArg` argument
|
||||
* [_.indexOf](http://lodash.com/docs#indexOf) and [_.lastIndexOf](http://lodash.com/docs#lastIndexOf) accept a `fromIndex` argument
|
||||
* [_.partial](http://lodash.com/docs#partial) for more functional fun
|
||||
* [_.size](http://lodash.com/docs#size) supports returning the `length` of string values
|
||||
* [_.template](http://lodash.com/docs#template) utilizes [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) for easier debugging
|
||||
|
||||
## Support
|
||||
|
||||
Lo-Dash has been tested in at least Chrome 5-19, Firefox 1.5-12, IE 6-9, Opera 9.25-11.64, Safari 3.0.4-5.1.3, Node.js 0.4.8-0.6.18, Narwhal 0.3.2, RingoJS 0.8, and Rhino 1.7RC3.
|
||||
Lo-Dash has been tested in at least Chrome 5-19, Firefox 1.5-13, IE 6-9, Opera 9.25-12, Safari 3.0.4-5.1.3, Node.js 0.4.8-0.6.18, Narwhal 0.3.2, RingoJS 0.8, and Rhino 1.7RC3.
|
||||
|
||||
## Custom builds
|
||||
|
||||
Custom builds make it easy to create lightweight versions of Lo-Dash containing only the methods you need.
|
||||
We handle all the method dependency and alias mapping for you.
|
||||
|
||||
Custom builds may be created in two ways:
|
||||
|
||||
1. Use the`include` argument to pass the names of the methods to include in the build.
|
||||
* Backbone builds, containing all methods required by Backbone, may be created using the `backbone` modifier argument.
|
||||
~~~ bash
|
||||
node build include=each,filter,map,noConflict
|
||||
node build include="each, filter, map, noConflict"
|
||||
node build backbone
|
||||
~~~
|
||||
|
||||
2. Use the `exclude` argument to pass the names of the methods to exclude from the build.
|
||||
* Mobile builds, with IE bug fixes and method compilation removed, may be created using the `mobile` modifier argument.
|
||||
~~~ bash
|
||||
node build exclude=isNaN,isUndefined,union,zip
|
||||
node build exclude="isNaN, isUndefined, union, zip"
|
||||
node build mobile
|
||||
~~~
|
||||
|
||||
Custom builds may be created in three ways:
|
||||
|
||||
1. Use the `category` argument to pass the categories of methods to include in the build.<br>
|
||||
Valid categories are *"arrays"*, *"chaining"*, *"collections"*, *"functions"*, *"objects"*, and *"utilities"*.
|
||||
~~~ bash
|
||||
node build category=collections,functions
|
||||
node build category="collections, functions"
|
||||
~~~
|
||||
|
||||
2. Use the `include` argument to pass the names of methods to include in the build.
|
||||
~~~ bash
|
||||
node build include=each,filter,map
|
||||
node build include="each, filter, map"
|
||||
~~~
|
||||
|
||||
3. Use the `exclude` argument to pass the names of methods to exclude from the build.
|
||||
~~~ bash
|
||||
node build exclude=union,uniq,zip
|
||||
node build exclude="union, uniq, zip"
|
||||
~~~
|
||||
|
||||
All arguments, except `include` and `exlcude`, may be combined.
|
||||
|
||||
~~~ bash
|
||||
node build backbone mobile category=functions include=pick,uniq
|
||||
node build backbone mobile category=utilities exclude=first,last
|
||||
~~~
|
||||
|
||||
Custom builds are saved to `lodash.custom.js` and `lodash.custom.min.js`.
|
||||
@@ -116,14 +150,22 @@ git submodule update --init
|
||||
|
||||
## Closed Underscore.js issues
|
||||
|
||||
* Fix Firefox, IE, Opera, and Safari object iteration bugs [#376](https://github.com/documentcloud/underscore/issues/376)
|
||||
* Handle arrays with `undefined` values correctly in IE < 9 [#601](https://github.com/documentcloud/underscore/issues/601)
|
||||
* Methods should work on pages with incorrectly shimmed native methods [#7](https://github.com/documentcloud/underscore/issues/7)
|
||||
* Register as AMD module, but still export to global [#431](https://github.com/documentcloud/underscore/pull/431)
|
||||
* `_.forEach` should be chainable [#142](https://github.com/documentcloud/underscore/issues/142)
|
||||
* `_isNaN(new Number(NaN))` should return `true`
|
||||
* `_.reduceRight` should pass correct callback arguments when iterating objects
|
||||
* `_.size` should return the `length` of string values
|
||||
* Allow iteration of objects with a `length` property [[#148](https://github.com/documentcloud/underscore/issues/148), [#154](https://github.com/documentcloud/underscore/issues/154), [#252](https://github.com/documentcloud/underscore/issues/252), [#448](https://github.com/documentcloud/underscore/issues/448), [test](https://github.com/bestiejs/lodash/blob/1ba47a7c2a35552796f0c75dc2b46660e230f842/test/test.js#L271-276)]
|
||||
* Ensure "Arrays" category methods allow falsey `array` arguments [[test](https://github.com/bestiejs/lodash/blob/1ba47a7c2a35552796f0c75dc2b46660e230f842/test/test.js#L758-790)]
|
||||
* Ensure array-like objects with invalid `length` properties are treated like regular objects [[test](https://github.com/bestiejs/lodash/blob/1ba47a7c2a35552796f0c75dc2b46660e230f842/test/test.js#L242-248), [test](https://github.com/bestiejs/lodash/blob/1ba47a7c2a35552796f0c75dc2b46660e230f842/test/test.js#L560-569), [test](https://github.com/bestiejs/lodash/blob/1ba47a7c2a35552796f0c75dc2b46660e230f842/test/test.js#L705-708)]
|
||||
* Ensure `_(…)` returns passed wrapper instances [[test](https://github.com/bestiejs/lodash/blob/801e8a5b3a963157fceaad15075690f59c22de9c/test/test.js#L106-109)]
|
||||
* Ensure `_.escape` returns an empty string when passed `null` or `undefined` [[#407](https://github.com/documentcloud/underscore/issues/427), [test](https://github.com/bestiejs/lodash/blob/1ba47a7c2a35552796f0c75dc2b46660e230f842/test/test.js#L161-164)]
|
||||
* Ensure `_.groupBy` adds values to own, not inherited, properties [[test](https://github.com/bestiejs/lodash/blob/1ba47a7c2a35552796f0c75dc2b46660e230f842/test/test.js#L322-329)]
|
||||
* Ensure `_.sortedIndex` supports arrays with high `length` values [[test](https://github.com/bestiejs/lodash/blob/1ba47a7c2a35552796f0c75dc2b46660e230f842/test/test.js#L613-622)]
|
||||
* Ensure `_.throttle` works when called in tight loops [[#502](https://github.com/documentcloud/underscore/issues/502), [test](https://github.com/bestiejs/lodash/blob/1ba47a7c2a35552796f0c75dc2b46660e230f842/test/test.js#L656-666)]
|
||||
* Fix Firefox, IE, Opera, and Safari object iteration bugs [[#376](https://github.com/documentcloud/underscore/issues/376), [test](https://github.com/bestiejs/lodash/blob/1ba47a7c2a35552796f0c75dc2b46660e230f842/test/test.js#L180-192), [test](https://github.com/bestiejs/lodash/blob/1ba47a7c2a35552796f0c75dc2b46660e230f842/test/test.js#L282-307), [test](https://github.com/bestiejs/lodash/blob/1ba47a7c2a35552796f0c75dc2b46660e230f842/test/test.js#L395-406), [test](https://github.com/bestiejs/lodash/blob/1ba47a7c2a35552796f0c75dc2b46660e230f842/test/test.js#L414-416), [test](https://github.com/bestiejs/lodash/blob/1ba47a7c2a35552796f0c75dc2b46660e230f842/test/test.js#L434-454), [test](https://github.com/bestiejs/lodash/blob/1ba47a7c2a35552796f0c75dc2b46660e230f842/test/test.js#L581-583)]
|
||||
* Handle arrays with `undefined` values correctly in IE < 9 [[#601](https://github.com/documentcloud/underscore/issues/601)]
|
||||
* Methods should work on pages with incorrectly shimmed native methods [[#7](https://github.com/documentcloud/underscore/issues/7), [test](https://github.com/bestiejs/lodash/blob/1ba47a7c2a35552796f0c75dc2b46660e230f842/test/test.js#L88-94)]
|
||||
* Register as AMD module, but still export to global [[#431](https://github.com/documentcloud/underscore/pull/431), [test](https://github.com/bestiejs/lodash/blob/1ba47a7c2a35552796f0c75dc2b46660e230f842/test/test.js#L72-86)]
|
||||
* `_.forEach` should be chainable [[#142](https://github.com/documentcloud/underscore/issues/142), [test](https://github.com/bestiejs/lodash/blob/1ba47a7c2a35552796f0c75dc2b46660e230f842/test/test.js#L237-240)]
|
||||
* `_isNaN(new Number(NaN))` should return `true` [[test](https://github.com/bestiejs/lodash/blob/1ba47a7c2a35552796f0c75dc2b46660e230f842/test/test.js#L424-426)]
|
||||
* `_.reduceRight` should pass correct callback arguments when iterating objects [[test](https://github.com/bestiejs/lodash/blob/1ba47a7c2a35552796f0c75dc2b46660e230f842/test/test.js#L548-558)]
|
||||
* `_.size` should return the `length` of string values [[test](https://github.com/bestiejs/lodash/blob/1ba47a7c2a35552796f0c75dc2b46660e230f842/test/test.js#L577-579)]
|
||||
|
||||
## Optimized methods <sup>(50+)</sup>
|
||||
|
||||
@@ -146,7 +188,7 @@ git submodule update --init
|
||||
* `_.functions`, `_.methods`
|
||||
* `_.groupBy`
|
||||
* `_.indexOf`
|
||||
* `_.intersection`, `_.intersect`
|
||||
* `_.intersection`
|
||||
* `_.invoke`
|
||||
* `_.isEmpty`
|
||||
* `_.isEqual`
|
||||
@@ -171,6 +213,7 @@ git submodule update --init
|
||||
* `_.sortedIndex`
|
||||
* `_.template`
|
||||
* `_.throttle`
|
||||
* `_.times`
|
||||
* `_.toArray`
|
||||
* `_.union`
|
||||
* `_.uniq`, `_.unique`
|
||||
@@ -178,33 +221,20 @@ git submodule update --init
|
||||
* `_.without`
|
||||
* `_.wrap`
|
||||
* `_.zip`
|
||||
* plus all `_(...)` method wrappers
|
||||
* plus all `_(…)` method wrappers
|
||||
|
||||
## Changelog
|
||||
## Release Notes
|
||||
|
||||
### <sup>v0.2.0</sup>
|
||||
### <sup>v0.3.2</sup>
|
||||
|
||||
* Added custom build options
|
||||
* Added default `_.templateSettings.variable` value
|
||||
* Added *"lazy bind"* support to `_.bind`
|
||||
* Added native method overwrite detection to avoid bad native shims
|
||||
* Added support for more AMD build optimizers and aliasing as the *"underscore"* module
|
||||
* Added `thisArg` to `_.groupBy`
|
||||
* Added whitespace to compiled strings
|
||||
* Added `_.partial`
|
||||
* Commented the `iterationFactory` options object
|
||||
* Ensured `_.max` and `_.min` support extremely large arrays
|
||||
* Fixed IE < 9 `[DontEnum]` bug and Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1’s prototype property iteration bug
|
||||
* Inlined `_.isFunction` calls.
|
||||
* Made `_.debounce`’ed functions match `_.throttle`’ed functions’ return value behavior
|
||||
* Made `_.escape` no longer translate the *">"* character
|
||||
* Fixed `clearTimeout` typo
|
||||
* Simplified all methods in the *"Arrays"* category
|
||||
* Optimized `_.debounce`, `_.escape`, `_.flatten`, `_.forEach`, `_.groupBy`, `_.intersection`, `_.invoke`, `_.isObject`, `_.max`, `_.min`, `_.pick`, `_.shuffle`, `_.sortedIndex`, `_.template`, `_.throttle`, `_.union`, `_.uniq`
|
||||
* Deprecated `_(…).chain`, `_.isFinite`, `_.isNaN`, `_.isNull`, `_.isUndefined`, `_.result`, and `_.size`
|
||||
* Ensured `_.escape` returns an empty string when passed `null` or `undefined`
|
||||
* Ensured `sourceURL` support doesn't cause errors in Adobe's JS engine.
|
||||
* Fixed regression in generating custom builds
|
||||
* Moved `_.invoke` and `_.pluck` back to the *"Collections"* category
|
||||
* Moved `_.tap` to the *"Chaining"* category
|
||||
|
||||
### <sup>v0.1.0</sup>
|
||||
|
||||
* Initial release
|
||||
The full changelog is available [here](https://github.com/bestiejs/lodash/wiki/Changelog).
|
||||
|
||||
## BestieJS
|
||||
|
||||
|
||||
378
build.js
378
build.js
@@ -10,9 +10,6 @@
|
||||
var lodash = require(path.join(__dirname, 'lodash')),
|
||||
minify = require(path.join(__dirname, 'build', 'minify'));
|
||||
|
||||
/** Flag used to specify a custom build */
|
||||
var isCustom = false;
|
||||
|
||||
/** Shortcut used to convert array-like objects to arrays */
|
||||
var slice = [].slice;
|
||||
|
||||
@@ -31,7 +28,6 @@
|
||||
'head': 'first',
|
||||
'include': 'contains',
|
||||
'inject': 'reduce',
|
||||
'intersect': 'intersection',
|
||||
'methods': 'functions',
|
||||
'select': 'filter',
|
||||
'tail': 'rest',
|
||||
@@ -48,7 +44,6 @@
|
||||
'first': ['head', 'take'],
|
||||
'forEach': ['each'],
|
||||
'functions': ['methods'],
|
||||
'intersection': ['intersect'],
|
||||
'map': ['collect'],
|
||||
'reduce': ['foldl', 'inject'],
|
||||
'reduceRight': ['foldr'],
|
||||
@@ -57,32 +52,78 @@
|
||||
'uniq': ['unique']
|
||||
};
|
||||
|
||||
/** Used to track Backbone's Lo-Dash dependencies */
|
||||
var backboneDependencies = [
|
||||
'bind',
|
||||
'bindAll',
|
||||
'clone',
|
||||
'contains',
|
||||
'escape',
|
||||
'every',
|
||||
'extend',
|
||||
'filter',
|
||||
'find',
|
||||
'first',
|
||||
'forEach',
|
||||
'groupBy',
|
||||
'has',
|
||||
'indexOf',
|
||||
'initial',
|
||||
'invoke',
|
||||
'isArray',
|
||||
'isEmpty',
|
||||
'isEqual',
|
||||
'isFunction',
|
||||
'isObject',
|
||||
'isRegExp',
|
||||
'keys',
|
||||
'last',
|
||||
'lastIndexOf',
|
||||
'map',
|
||||
'max',
|
||||
'min',
|
||||
'mixin',
|
||||
'reduce',
|
||||
'reduceRight',
|
||||
'reject',
|
||||
'rest',
|
||||
'shuffle',
|
||||
'size',
|
||||
'some',
|
||||
'sortBy',
|
||||
'sortedIndex',
|
||||
'toArray',
|
||||
'uniqueId',
|
||||
'without'
|
||||
];
|
||||
|
||||
/** Used to track function dependencies */
|
||||
var dependencyMap = {
|
||||
'after': [],
|
||||
'bind': [],
|
||||
'bindAll': ['bind'],
|
||||
'chain': [],
|
||||
'bindAll': ['bind', 'functions'],
|
||||
'chain': ['mixin'],
|
||||
'clone': ['extend', 'isArray'],
|
||||
'compact': [],
|
||||
'compose': [],
|
||||
'contains': ['createIterator'],
|
||||
'createIterator': [],
|
||||
'contains': [],
|
||||
'debounce': [],
|
||||
'defaults': ['createIterator'],
|
||||
'defaults': [],
|
||||
'defer': [],
|
||||
'delay': [],
|
||||
'difference': ['indexOf'],
|
||||
'escape': [],
|
||||
'every': ['bind', 'createIterator', 'identity'],
|
||||
'extend': ['createIterator'],
|
||||
'filter': ['bind', 'createIterator', 'identity'],
|
||||
'find': ['createIterator'],
|
||||
'every': ['identity'],
|
||||
'extend': [],
|
||||
'filter': ['identity'],
|
||||
'find': [],
|
||||
'first': [],
|
||||
'flatten': ['isArray'],
|
||||
'forEach': ['bind', 'createIterator'],
|
||||
'functions': ['createIterator'],
|
||||
'groupBy': ['bind', 'createIterator'],
|
||||
'forEach': [],
|
||||
'forIn': [],
|
||||
'forOwn': [],
|
||||
'functions': [],
|
||||
'groupBy': [],
|
||||
'has': [],
|
||||
'identity': [],
|
||||
'indexOf': ['sortedIndex'],
|
||||
@@ -94,7 +135,7 @@
|
||||
'isBoolean': [],
|
||||
'isDate': [],
|
||||
'isElement': [],
|
||||
'isEmpty': ['createIterator'],
|
||||
'isEmpty': [],
|
||||
'isEqual': [],
|
||||
'isFinite': [],
|
||||
'isFunction': [],
|
||||
@@ -105,44 +146,76 @@
|
||||
'isRegExp': [],
|
||||
'isString': [],
|
||||
'isUndefined': [],
|
||||
'keys': ['createIterator'],
|
||||
'keys': [],
|
||||
'last': [],
|
||||
'lastIndexOf': [],
|
||||
'map': ['bind', 'createIterator', 'identity'],
|
||||
'max': ['bind'],
|
||||
'map': ['identity'],
|
||||
'max': [],
|
||||
'memoize': [],
|
||||
'min': ['bind'],
|
||||
'mixin': ['forEach'],
|
||||
'min': [],
|
||||
'mixin': ['forEach', 'functions'],
|
||||
'noConflict': [],
|
||||
'once': [],
|
||||
'partial': [],
|
||||
'pick': [],
|
||||
'pluck': ['createIterator'],
|
||||
'pluck': [],
|
||||
'range': [],
|
||||
'reduce': ['bind', 'createIterator'],
|
||||
'reduceRight': ['bind', 'keys'],
|
||||
'reject': ['bind', 'createIterator', 'identity'],
|
||||
'reduce': [],
|
||||
'reduceRight': ['keys'],
|
||||
'reject': ['identity'],
|
||||
'rest': [],
|
||||
'result': [],
|
||||
'shuffle': [],
|
||||
'size': ['keys'],
|
||||
'some': ['bind', 'createIterator', 'identity'],
|
||||
'sortBy': ['bind', 'map', 'pluck'],
|
||||
'sortedIndex': [],
|
||||
'some': ['identity'],
|
||||
'sortBy': [],
|
||||
'sortedIndex': ['bind'],
|
||||
'tap': [],
|
||||
'template': ['escape'],
|
||||
'throttle': [],
|
||||
'times': ['bind'],
|
||||
'times': [],
|
||||
'toArray': ['values'],
|
||||
'union': ['indexOf'],
|
||||
'uniq': ['indexOf'],
|
||||
'uniq': ['identity', 'indexOf'],
|
||||
'uniqueId': [],
|
||||
'values': ['createIterator'],
|
||||
'values': [],
|
||||
'without': ['indexOf'],
|
||||
'wrap': [],
|
||||
'zip': ['max', 'pluck']
|
||||
};
|
||||
|
||||
/** Collections of method names */
|
||||
var excludeMethods,
|
||||
includeMethods,
|
||||
allMethods = Object.keys(dependencyMap);
|
||||
|
||||
/** Used to specify whether filtering is for exclusion or inclusion */
|
||||
var filterType = process.argv.reduce(function(result, value) {
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
var pair = value.match(/^(exclude|include)=(.*)$/);
|
||||
if (!pair) {
|
||||
return result;
|
||||
}
|
||||
// remove nonexistent method names
|
||||
var methodNames = lodash.intersection(allMethods, pair[2].split(/, */).map(getRealName));
|
||||
|
||||
if (pair[1] == 'exclude') {
|
||||
excludeMethods = methodNames;
|
||||
} else {
|
||||
includeMethods = methodNames;
|
||||
}
|
||||
// return `filterType`
|
||||
return pair[1];
|
||||
}, '');
|
||||
|
||||
/** Flag used to specify a backbone build */
|
||||
var isBackbone = process.argv.indexOf('backbone') > -1;
|
||||
|
||||
/** Flag used to specify a mobile build */
|
||||
var isMobile = process.argv.indexOf('mobile') > -1;
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
@@ -167,7 +240,7 @@
|
||||
// iterate over `dependencyMap`, adding the names of functions that
|
||||
// have `funcName` as a dependency
|
||||
return lodash.reduce(dependencyMap, function(result, dependencies, otherName) {
|
||||
if (dependencies.indexOf(funcName) > -1) {
|
||||
if (lodash.contains(dependencies, funcName)) {
|
||||
result.push(otherName);
|
||||
}
|
||||
return result;
|
||||
@@ -175,25 +248,26 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of dependencies for a function of the given `funcName`.
|
||||
* Gets an array of dependencies for a given function name. If passed an array
|
||||
* of dependencies it will return an array containing the given dependencies
|
||||
* plus any additional detected sub-dependencies.
|
||||
*
|
||||
* @private
|
||||
* @param {String} funcName The name of the function to query.
|
||||
* @param {Array|String} funcName A single function name or array of
|
||||
* dependencies to query.
|
||||
* @returns {Array} Returns an array of function dependencies.
|
||||
*/
|
||||
function getDependencies(funcName) {
|
||||
var dependencies = dependencyMap[funcName],
|
||||
result = [];
|
||||
|
||||
var dependencies = Array.isArray(funcName) ? funcName : dependencyMap[funcName];
|
||||
if (!dependencies) {
|
||||
return result;
|
||||
return [];
|
||||
}
|
||||
// recursively accumulate the dependencies of the `funcName` function, and
|
||||
// the dependencies of its dependencies, and so on.
|
||||
return dependencies.reduce(function(result, otherName) {
|
||||
return lodash.uniq(dependencies.reduce(function(result, otherName) {
|
||||
result.push.apply(result, getDependencies(otherName).concat(otherName));
|
||||
return result;
|
||||
}, result);
|
||||
}, []));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -208,7 +282,7 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if all functions of the given names have been removed from the `source`.
|
||||
* Determines if all functions of the given names have been removed from `source`.
|
||||
*
|
||||
* @private
|
||||
* @param {String} source The source to inspect.
|
||||
@@ -222,7 +296,7 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches the `source` for a `funcName` function declaration, expression, or
|
||||
* Searches `source` for a `funcName` function declaration, expression, or
|
||||
* assignment and returns the matched snippet.
|
||||
*
|
||||
* @private
|
||||
@@ -239,9 +313,9 @@
|
||||
// match a function declaration
|
||||
'( +)function ' + funcName + '\\b[\\s\\S]+?\\n\\1}|' +
|
||||
// match a variable declaration with `createIterator`
|
||||
' +var ' + funcName + ' *= *(?:[a-zA-Z]+ *\\|\\| *)?createIterator\\((?:{|[a-zA-Z])[\\s\\S]+?\\);|' +
|
||||
' +var ' + funcName + ' *=.*?createIterator\\((?:{|[a-zA-Z])[\\s\\S]+?\\);|' +
|
||||
// match a variable declaration with function expression
|
||||
'( +)var ' + funcName + ' *= *(?:[a-zA-Z]+ *\\|\\| *)?function[\\s\\S]+?\\n\\2};' +
|
||||
'( +)var ' + funcName + ' *=.*?function[\\s\\S]+?\\n\\2};' +
|
||||
// end non-capturing group
|
||||
')\\n'
|
||||
));
|
||||
@@ -258,7 +332,7 @@
|
||||
* @returns {String} Returns the modified source.
|
||||
*/
|
||||
function removeFromCreateIterator(source, refName) {
|
||||
var snippet = matchFunction(source, 'createIterator'),
|
||||
var snippet = matchFunction(source, 'createIterator').match(/Function\([\s\S]+$/)[0],
|
||||
modified = snippet.replace(RegExp('\\b' + refName + '\\b,? *', 'g'), '');
|
||||
|
||||
return source.replace(snippet, modified);
|
||||
@@ -266,7 +340,7 @@
|
||||
|
||||
/**
|
||||
* Removes the `funcName` function declaration, expression, or assignment and
|
||||
* associated code from the `source`.
|
||||
* associated code from `source`.
|
||||
*
|
||||
* @private
|
||||
* @param {String} source The source to process.
|
||||
@@ -281,7 +355,6 @@
|
||||
if (!snippet) {
|
||||
return source;
|
||||
}
|
||||
|
||||
// remove function
|
||||
source = source.replace(matchFunction(source, funcName), '');
|
||||
|
||||
@@ -300,7 +373,18 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a given variable from the `source`.
|
||||
* Removes the `_.isArguments` fallback from `source`.
|
||||
*
|
||||
* @private
|
||||
* @param {String} source The source to process.
|
||||
* @returns {String} Returns the source with the `isArguments` fallback removed.
|
||||
*/
|
||||
function removeIsArgumentsFallback(source) {
|
||||
return source.replace(/(?: *\/\/.*)*\s*if *\(!isArguments[^)]+\)[\s\S]+?};?\s*}\n/, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a given variable from `source`.
|
||||
*
|
||||
* @private
|
||||
* @param {String} source The source to process.
|
||||
@@ -330,70 +414,96 @@
|
||||
return removeFromCreateIterator(source, varName);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
// inline `iteratorTemplate`
|
||||
(function() {
|
||||
var iteratorTemplate = lodash._iteratorTemplate,
|
||||
code = /^function[^{]+{([\s\S]+?)}$/.exec(iteratorTemplate)[1];
|
||||
|
||||
// remove whitespace from template
|
||||
code = code.replace(/\[object |else if|function | in |return\s+[\w']|throw |typeof |var |\\\\n|\\n|\s+/g, function(match) {
|
||||
/**
|
||||
* Removes non-syntax critical whitespace from a string.
|
||||
*
|
||||
* @private
|
||||
* @param {String} source The source to process.
|
||||
* @returns {String} Returns the source with whitespace removed.
|
||||
*/
|
||||
function removeWhitespace(source) {
|
||||
return source.replace(/\[object |else if|function | in |return\s+[\w']|throw |typeof |var |@ |\\\\n|\\n|\s+/g, function(match) {
|
||||
return match == false || match == '\\n' ? '' : match;
|
||||
});
|
||||
}
|
||||
|
||||
// remove unnecessary code
|
||||
code = code
|
||||
.replace(/\|\|\{\}|,__t,__j=Array.prototype.join|function print[^}]+}|\+''/g, '')
|
||||
.replace(/(\{);|;(\})/g, '$1$2')
|
||||
.replace(/\(\(__t=\(([^)]+)\)\)==null\?'':__t\)/g, '$1');
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
// ensure escaped characters are interpreted correctly inside the `Function()` string
|
||||
code = code.replace(/\\/g, '\\\\');
|
||||
// Backbone build
|
||||
if (isBackbone) {
|
||||
// add any additional dependencies
|
||||
backboneDependencies = getDependencies(backboneDependencies);
|
||||
|
||||
// add `code` to `Function()`
|
||||
code = '$1Function(\'object\',\n$2 "' + code + '"\n$2);\n';
|
||||
if (filterType == 'exclude') {
|
||||
// remove excluded methods from `backboneDependencies`
|
||||
includeMethods = lodash.without.apply(lodash, [backboneDependencies].concat(excludeMethods));
|
||||
}
|
||||
else if (filterType) {
|
||||
// merge backbone dependencies into `includeMethods`
|
||||
includeMethods = lodash.union(includeMethods, backboneDependencies);
|
||||
}
|
||||
else {
|
||||
// include only the Backbone dependencies
|
||||
includeMethods = backboneDependencies;
|
||||
}
|
||||
filterType = 'include';
|
||||
}
|
||||
|
||||
// replace `template()` with `Function()`
|
||||
source = source.replace(/(( +)var iteratorTemplate *= *)([\s\S]+?\n\2.+?);\n/, code);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
// remove pseudo private property `_iteratorTemplate`
|
||||
source = source.replace(/(?:\s*\/\/.*)*\s*lodash\._iteratorTemplate\b.+\n/, '\n');
|
||||
}());
|
||||
// add category methods
|
||||
process.argv.some(function(value) {
|
||||
var categories = value.match(/^category=(.*)$/);
|
||||
if (!categories) {
|
||||
return false;
|
||||
}
|
||||
// resolve method names belonging to each category
|
||||
var categoryMethods = categories.reduce(function(result, category) {
|
||||
return result.concat(allMethods.filter(function(funcName) {
|
||||
return RegExp('@category ' + category + '\\b', 'i').test(matchFunction(source, funcName));
|
||||
}));
|
||||
}, []);
|
||||
|
||||
if (filterType == 'exclude') {
|
||||
// remove excluded methods from `categoryMethods`
|
||||
includeMethods = lodash.without.apply(lodash, [categoryMethods].concat(excludeMethods));
|
||||
}
|
||||
else if (filterType) {
|
||||
// merge backbone dependencies into `includeMethods`
|
||||
includeMethods = lodash.union(includeMethods, categoryMethods);
|
||||
}
|
||||
else {
|
||||
// include only the Backbone dependencies
|
||||
includeMethods = categoryMethods;
|
||||
}
|
||||
|
||||
filterType = 'include';
|
||||
return true;
|
||||
});
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
// custom build
|
||||
process.argv.some(function(arg) {
|
||||
// exit early if not the "exclude" or "include" command option
|
||||
var pair = arg.match(/^(exclude|include)=(.*)$/);
|
||||
if (!pair) {
|
||||
return false;
|
||||
(function() {
|
||||
// exit early if "exclude" or "include" options aren't specified
|
||||
if (!filterType) {
|
||||
return;
|
||||
}
|
||||
|
||||
var filterType = pair[1],
|
||||
filterNames = lodash.intersection(Object.keys(dependencyMap), pair[2].split(/, */).map(getRealName));
|
||||
|
||||
// set custom build flag
|
||||
isCustom = true;
|
||||
|
||||
// remove the specified functions and their dependants
|
||||
if (filterType == 'exclude') {
|
||||
filterNames.forEach(function(funcName) {
|
||||
// remove methods that are named in `excludeMethods` and their dependants
|
||||
excludeMethods.forEach(function(funcName) {
|
||||
getDependants(funcName).concat(funcName).forEach(function(otherName) {
|
||||
source = removeFunction(source, otherName);
|
||||
});
|
||||
});
|
||||
}
|
||||
// else remove all but the specified functions and their dependencies
|
||||
else {
|
||||
filterNames = lodash.uniq(filterNames.reduce(function(result, funcName) {
|
||||
result.push.apply(result, getDependencies(funcName).concat(funcName));
|
||||
return result;
|
||||
}, []));
|
||||
// add dependencies to `includeMethods`
|
||||
includeMethods = getDependencies(includeMethods);
|
||||
|
||||
lodash.each(dependencyMap, function(dependencies, otherName) {
|
||||
if (filterNames.indexOf(otherName) < 0) {
|
||||
// remove methods that aren't named in `includeMethods`
|
||||
lodash.each(allMethods, function(otherName) {
|
||||
if (!lodash.contains(includeMethods, otherName)) {
|
||||
source = removeFunction(source, otherName);
|
||||
}
|
||||
});
|
||||
@@ -401,8 +511,7 @@
|
||||
|
||||
// remove associated functions, variables and code snippets
|
||||
if (isRemoved(source, 'isArguments')) {
|
||||
// remove `isArguments` if-statement
|
||||
source = source.replace(/(?:\s*\/\/.*)*\s*if *\(!isArguments[^)]+\)[\s\S]+?};?\s*}\n/, '');
|
||||
source = removeIsArgumentsFallback(source);
|
||||
}
|
||||
if (isRemoved(source, 'mixin')) {
|
||||
// remove `LoDash` constructor
|
||||
@@ -416,21 +525,28 @@
|
||||
// remove `templateSettings` assignment
|
||||
source = source.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *lodash\.templateSettings[\s\S]+?};\n/, '');
|
||||
}
|
||||
if (isRemoved(source, 'max', 'min')) {
|
||||
source = removeVar(source, 'argsLimit');
|
||||
// remove `argsLimit` try-catch
|
||||
source = source.replace(/\n *try\s*\{[\s\S]+?argsLimit *=[\s\S]+?catch[^}]+}\n/, '');
|
||||
}
|
||||
if (isRemoved(source, 'isArray', 'isEmpty', 'isEqual', 'size')) {
|
||||
source = removeVar(source, 'arrayClass');
|
||||
}
|
||||
if (isRemoved(source, 'bind', 'functions', 'groupBy', 'invoke', 'isEqual', 'isFunction', 'result', 'sortBy', 'toArray')) {
|
||||
source = removeVar(source, 'funcClass');
|
||||
}
|
||||
if (isRemoved(source, 'bind')) {
|
||||
source = removeVar(source, 'nativeBind');
|
||||
}
|
||||
if (isRemoved(source, 'isArray')) {
|
||||
source = removeVar(source, 'nativeIsArray');
|
||||
}
|
||||
if (isRemoved(source, 'keys')) {
|
||||
source = removeVar(source, 'nativeKeys');
|
||||
}
|
||||
if (isRemoved(source, 'clone', 'isObject', 'keys')) {
|
||||
source = removeVar(source, 'objectTypes');
|
||||
source = removeFromCreateIterator(source, 'objectTypes');
|
||||
}
|
||||
if (isRemoved(source, 'bind', 'isArray', 'keys')) {
|
||||
source = removeVar(source, 'reNative');
|
||||
}
|
||||
if (isRemoved(source, 'isEmpty', 'isEqual', 'isString', 'size')) {
|
||||
source = removeVar(source, 'stringClass');
|
||||
}
|
||||
@@ -439,12 +555,66 @@
|
||||
source = source.replace(/(?:\s*\/\*-+\*\/\s*){2,}/g, function(separators) {
|
||||
return separators.match(/^\s*/)[0] + separators.slice(separators.lastIndexOf('/*'));
|
||||
});
|
||||
}());
|
||||
|
||||
return true;
|
||||
});
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
if (isMobile) {
|
||||
// inline functions defined with `createIterator`
|
||||
lodash.functions(lodash).forEach(function(funcName) {
|
||||
// match `funcName` with pseudo private `_` prefixes removed to allow matching `shimKeys`
|
||||
var reFunc = RegExp('(\\bvar ' + funcName.replace(/^_/, '') + ' *= *)createIterator\\(((?:{|[a-zA-Z])[\\s\\S]+?)\\);\\n');
|
||||
|
||||
// skip if not defined with `createIterator`
|
||||
if (!reFunc.test(source)) {
|
||||
return;
|
||||
}
|
||||
// extract and format the function's code
|
||||
var code = (lodash[funcName] + '').replace(/\n(?:.*)/g, function(match) {
|
||||
match = match.slice(1);
|
||||
return (match == '}' ? '\n ' : '\n ') + match;
|
||||
});
|
||||
|
||||
source = source.replace(reFunc, '$1' + code + ';\n');
|
||||
});
|
||||
|
||||
source = removeIsArgumentsFallback(source);
|
||||
|
||||
source = removeVar(source, 'iteratorTemplate');
|
||||
|
||||
// remove JScript [[DontEnum]] fix from `isEqual`
|
||||
source = source.replace(/(?:\s*\/\/.*\n)*( +)if *\(result *&& *hasDontEnumBug[\s\S]+?\n\1}/, '');
|
||||
|
||||
// remove IE `shift` and `splice` fix
|
||||
source = source.replace(/(?:\s*\/\/.*\n)*( +)if *\(value.length *=== *0[\s\S]+?\n\1}/, '');
|
||||
}
|
||||
else {
|
||||
// inline `iteratorTemplate` template
|
||||
source = source.replace(/(( +)var iteratorTemplate *= *)([\s\S]+?\n\2.+?);\n/, (function() {
|
||||
// extract `iteratorTemplate` code
|
||||
var code = /^function[^{]+{([\s\S]+?)}$/.exec(lodash._iteratorTemplate)[1];
|
||||
|
||||
code = removeWhitespace(code)
|
||||
// remove unnecessary code
|
||||
.replace(/\|\|\{\}|,__t,__j=Array.prototype.join|function print[^}]+}|\+''/g, '')
|
||||
.replace(/(\{);|;(\})/g, '$1$2')
|
||||
.replace(/\(\(__t=\(([^)]+)\)\)==null\?'':__t\)/g, '$1')
|
||||
// ensure escaped characters are interpreted correctly in the string literal
|
||||
.replace(/\\/g, '\\\\');
|
||||
|
||||
// add `code` to `Function()` as a string literal to avoid strict mode
|
||||
// errors caused by the required with-statement
|
||||
return '$1Function(\'obj\',\n$2 "' + code + '"\n$2);\n';
|
||||
}()));
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
// remove pseudo private properties
|
||||
source = source.replace(/(?:(?:\s*\/\/.*)*\s*lodash\._[^=]+=.+\n)+/g, '\n');
|
||||
|
||||
// begin the minification process
|
||||
if (isCustom) {
|
||||
if (filterType || isBackbone || isMobile) {
|
||||
fs.writeFileSync(path.join(__dirname, 'lodash.custom.js'), source);
|
||||
minify(source, 'lodash.custom.min', function(result) {
|
||||
fs.writeFileSync(path.join(__dirname, 'lodash.custom.min.js'), result);
|
||||
|
||||
@@ -9,28 +9,23 @@
|
||||
var compiledVars = [
|
||||
'accumulator',
|
||||
'args',
|
||||
'array',
|
||||
'arrayClass',
|
||||
'bind',
|
||||
'callback',
|
||||
'className',
|
||||
'collection',
|
||||
'concat',
|
||||
'ctor',
|
||||
'false',
|
||||
'funcClass',
|
||||
'hasOwnProperty',
|
||||
'identity',
|
||||
'index',
|
||||
'indexOf',
|
||||
'isArray',
|
||||
'isEmpty',
|
||||
'isFunc',
|
||||
'iteratorBind',
|
||||
'length',
|
||||
'methodName',
|
||||
'noaccum',
|
||||
'object',
|
||||
'objectTypes',
|
||||
'noaccum',
|
||||
'prop',
|
||||
'property',
|
||||
'result',
|
||||
'skipProto',
|
||||
@@ -71,9 +66,10 @@
|
||||
/** Used to minify variables and string values to a single character */
|
||||
var minNames = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
|
||||
|
||||
/** Used protect the specified properties from getting minified */
|
||||
/** Used to protect the specified properties from getting minified */
|
||||
var propWhitelist = [
|
||||
'_',
|
||||
'_chain',
|
||||
'_wrapped',
|
||||
'after',
|
||||
'all',
|
||||
@@ -109,6 +105,8 @@
|
||||
'foldl',
|
||||
'foldr',
|
||||
'forEach',
|
||||
'forIn',
|
||||
'forOwn',
|
||||
'functions',
|
||||
'groupBy',
|
||||
'has',
|
||||
@@ -119,7 +117,6 @@
|
||||
'initial',
|
||||
'inject',
|
||||
'interpolate',
|
||||
'intersect',
|
||||
'intersection',
|
||||
'invoke',
|
||||
'isArguments',
|
||||
@@ -177,7 +174,6 @@
|
||||
'throttle',
|
||||
'times',
|
||||
'toArray',
|
||||
'toArray',
|
||||
'union',
|
||||
'uniq',
|
||||
'unique',
|
||||
@@ -203,21 +199,33 @@
|
||||
// remove copyright to add later in post-compile.js
|
||||
source = source.replace(/\/\*![\s\S]+?\*\//, '');
|
||||
|
||||
// correct JSDoc tags for Closure Compiler
|
||||
// remove unrecognized JSDoc tags so Closure Compiler won't complain
|
||||
source = source.replace(/@(?:alias|category)\b.*/g, '');
|
||||
|
||||
// add brackets to whitelisted properties so Closure Compiler won't mung them
|
||||
// http://code.google.com/closure/compiler/docs/api-tutorial3.html#export
|
||||
source = source.replace(RegExp('\\.(' + propWhitelist.join('|') + ')\\b', 'g'), "['$1']");
|
||||
|
||||
// remove brackets from `_.escape()` in `tokenizeEscape`
|
||||
source = source.replace("_['escape'](\"", '_.escape("');
|
||||
|
||||
// remove whitespace from string literals
|
||||
source = source.replace(/'(?:(?=(\\?))\1.)*?'/g, function(string) {
|
||||
// avoids removing the '\n' of the `escapes` object
|
||||
return string.replace(/\[object |else if|function | in |return\s+[\w']|throw |typeof |use strict|var |'\\n'|\\\\n|\\n|\s+/g, function(match) {
|
||||
// avoids removing the '\n' of the `stringEscapes` object
|
||||
return string.replace(/\[object |else if|function | in |return\s+[\w']|throw |typeof |use strict|var |@ |'\\n'|\\\\n|\\n|\s+/g, function(match) {
|
||||
return match == false || match == '\\n' ? '' : match;
|
||||
});
|
||||
});
|
||||
|
||||
// remove newline from double-quoted string in `_.template`
|
||||
source = source.replace('"\';\\n"', '"\';"');
|
||||
|
||||
// remove `useSourceURL` variable
|
||||
source = source.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *try *\{(?:\s*\/\/.*\n)* *var useSourceURL[\s\S]+?catch[^}]+}\n/, '');
|
||||
|
||||
// remove debug sourceURL use in `_.template`
|
||||
source = source.replace(/(?:\s*\/\/.*\n)* *if *\(useSourceURL[^}]+}/, '');
|
||||
|
||||
// minify `_.sortBy` internal properties
|
||||
(function() {
|
||||
var properties = ['criteria', 'value'],
|
||||
@@ -225,9 +233,9 @@
|
||||
result = snippet;
|
||||
|
||||
if (snippet) {
|
||||
// minify property strings
|
||||
// minify properties
|
||||
properties.forEach(function(property, index) {
|
||||
result = result.replace(RegExp("'" + property + "'", 'g'), "'" + minNames[index] + "'");
|
||||
result = result.replace(RegExp('\\b' + property + '\\b', 'g'), minNames[index]);
|
||||
});
|
||||
// replace with modified snippet
|
||||
source = source.replace(snippet, result);
|
||||
@@ -286,7 +294,7 @@
|
||||
// correct external boolean literals
|
||||
else if (variable == 'true' || variable == 'false') {
|
||||
result = result
|
||||
.replace(RegExp(': *' + minNames[index] + ',', 'g'), ':' + variable + ',')
|
||||
.replace(RegExp(': *' + minNames[index] + '([,\\n])', 'g'), ':' + variable + '$1')
|
||||
.replace(RegExp('\\b' + minNames[index] + ';', 'g'), variable + ';');
|
||||
}
|
||||
});
|
||||
|
||||
834
doc/README.md
834
doc/README.md
File diff suppressed because it is too large
Load Diff
@@ -21,8 +21,8 @@
|
||||
// generate Markdown
|
||||
$markdown = docdown(array(
|
||||
'path' => '../' . $file,
|
||||
'title' => 'Lo-Dash <sup>v0.2.0</sup>',
|
||||
'url' => 'https://github.com/bestiejs/lodash/blob/master/lodash.js'
|
||||
'title' => 'Lo-Dash <sup>v0.3.2</sup>',
|
||||
'url' => 'https://github.com/bestiejs/lodash/blob/v0.3.2/lodash.js'
|
||||
));
|
||||
|
||||
// save to a .md file
|
||||
|
||||
56
lodash.min.js
vendored
56
lodash.min.js
vendored
@@ -1,30 +1,32 @@
|
||||
/*!
|
||||
Lo-Dash 0.2.0 lodash.com/license
|
||||
Lo-Dash 0.3.2 lodash.com/license
|
||||
Underscore.js 1.3.3 github.com/documentcloud/underscore/blob/master/LICENSE
|
||||
*/
|
||||
;(function(u,m){"use strict";function R(a){return"[object Arguments]"==h.call(a)}function c(a){return new p(a)}function p(a){if(a&&a._wrapped)return a;this._wrapped=a}function j(){for(var a,b,d,k=-1,c=arguments.length,f={e:"",f:"",k:"",q:"",c:{m:"++o<t"},o:{}};++k<c;)for(b in a=arguments[k],a)d=(d=a[b])==o?"":d,/d|m|j/.test(b)?("string"==typeof d&&(d={b:d,n:d}),f.c[b]=d.b,f.o[b]=d.n):f[b]=d;a=f.a,b=f.c,d=f.o;var k=/^[^,]+/.exec(a)[0],c=d.m,g=/\S+$/.exec(c||k)[0];f.g=k,f.i=H,f.h="m.call("+g+",o)",f
|
||||
.l=g,f.p=ba,f.r=f.r!==r,f.f||(f.f="if("+k+"==null)return z");if("u"==k||!b.j)f.c=o;return c||(d.m="o in "+g),Function("d,e,i,l,m,n,p,q,r,v,B,E,H,I,k,J",'"use strict";return function('+a+"){"+ta(f)+"}")(I,v,D,s,t,ca,w,J,da,S,l,K,h,n,r)}function ua(a,b){return x[b]}function va(a){return"\\"+wa[a]}function xa(a,b){var d=x.length;return x[d]="'+((__t=("+b+"))==null?'':_['escape'](__t))+'",T+d}function ya(a,b){var d=x.length;return x[d]="'+((__t=("+b+"))==null?'':__t)+'",T+d}function za(a,b){var d=x.length
|
||||
;return x[d]="';"+b+";__p+='",T+d}function ea(a,b,d,c){if(!a)return d;var e=a.length,f=3>arguments.length;c&&(b=v(b,c));if(e===+e){for(e&&f&&(d=a[--e]);e--;)d=b(d,a[e],e,a);return d}var g=U(a);for((e=g.length)&&f&&(d=a[g[--e]]);e--;)f=g[e],d=b(d,a[f],f,a);return d}function V(a,b,d){return b==m||d?a[0]:l.call(a,0,b)}function fa(a,b){if(b)return D.apply(z,a);for(var d,c=-1,e=a.length,f=[];++c<e;)d=a[c],J(d)?E.apply(f,fa(d)):f.push(d);return f}function w(a,b,d){var c;if(!a)return-1;if(d)return d=ga(
|
||||
a,b),a[d]===b?d:-1;d=0;for(c=a.length;d<c;d++)if(a[d]===b)return d;return-1}function ha(a){for(var b,d=-1,c=a.length,e=l.call(arguments,1),f=[];++d<c;)b=a[d],0>w(f,b)&&W(e,function(a){return-1<w(a,b)})&&f.push(b);return f}function ia(a,b,d){var c=-Infinity,e=-1,f=a.length,g=c;if(b)d&&(b=v(b,d));else{if(a[0]===+a[0]&&f<=L)try{return Math.max.apply(Math,a)}catch(i){}if(!a.length)return g}for(;++e<f;)d=b?b(a[e],e,a):a[e],d>c&&(c=d,g=a[e]);return g}function ja(a,b,d){return l.call(a,b==m||d?1:b)}function ga
|
||||
(a,b,d){var c,e=0,f=a.length;for(d&&(b=d(b));e<f;)c=e+f>>1,(d?d(a[c]):a[c])<b?e=c+1:f=c;return e}function ka(a,b,d){var c,e=-1,f=a.length,g=[],i=[];for(3>f&&(b=n);++e<f;)if(c=d?d(a[e]):a[e],b?!e||i[i.length-1]!==c:0>w(i,c))i.push(c),g.push(a[e]);return g}function v(a,b){var d,c=h.call(a)==s;if(c){if(B)return a=B.call.apply(B,arguments),function(){return arguments.length?a.apply(m,arguments):a()}}else d=b,b=a;var e=l.call(arguments,2),f=e.length;return function(){var g;return g=arguments,c||(a=b[d
|
||||
]),f&&(g.length&&(e.length=f,E.apply(e,g)),g=e),g=g.length?a.apply(b,g):a.call(b),e.length=f,g}}function M(a,b,d){d||(d=[]);if(a===b)return 0!==a||1/a==1/b;if(a==m||b==m)return a===b;a.s&&(a=a._wrapped),b.s&&(b=b._wrapped);if(a.isEqual&&h.call(a.isEqual)==s)return a.isEqual(b);if(b.isEqual&&h.call(b.isEqual)==s)return b.isEqual(a);var c=h.call(a);if(c!=h.call(b))return r;switch(c){case K:return a==""+b;case N:return a!=+a?b!=+b:0==a?1/a==1/b:a==+b;case la:case ma:return+a==+b;case na:return a.source==
|
||||
b.source&&a.global==b.global&&a.multiline==b.multiline&&a.ignoreCase==b.ignoreCase}if("object"!=typeof a||"object"!=typeof b)return r;for(var e=d.length;e--;)if(d[e]==a)return n;var e=-1,f=n,g=0;d.push(a);if(c==I){if(g=a.length,f=g==b.length)for(;g--&&(f=M(a[g],b[g],d)););}else{if("constructor"in a!="constructor"in b||a.constructor!=b.constructor)return r;for(var i in a)if(t.call(a,i)&&(g++,!(f=t.call(b,i)&&M(a[i],b[i],d))))break;if(f){for(i in b)if(t.call(b,i)&&!(g--))break;f=!g}if(f&&H)for(;7>++
|
||||
e&&(i=ba[e],!t.call(a,i)||!!(f=t.call(b,i)&&M(a[i],b[i],d))););}return d.pop(),f}function ca(a){return a}function oa(a){F(O(a),function(b){var d=c[b]=a[b];p.prototype[b]=function(){var a=[this._wrapped];return arguments.length&&E.apply(a,arguments),a=1==a.length?d.call(c,a[0]):d.apply(c,a),this.s&&(a=new p(a),a.s=n),a}})}var n=!0,o=null,r=!1,X="object"==typeof exports&&exports&&("object"==typeof global&&global&&global==global.global&&(u=global),exports),L=5e4;try{(function(){L=arguments.length}).
|
||||
apply(o,Array(L))}catch(Ha){}var wa={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"},H=!{valueOf:0}.propertyIsEnumerable("valueOf"),Aa=0,S={"boolean":r,"function":n,object:n,number:r,string:r,"undefined":r},Ba=u._,A=RegExp("^"+({}.valueOf+"").replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),Ca=/__token__(\d+)/g,Da=/['\n\r\t\u2028\u2029\\]/g,ba="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf"
|
||||
.split(" "),T="__token__",x=[],I="[object Array]",la="[object Boolean]",ma="[object Date]",s="[object Function]",N="[object Number]",na="[object RegExp]",K="[object String]",z=Array.prototype,y=Object.prototype,D=z.concat,t=y.hasOwnProperty,E=z.push,l=z.slice,h=y.toString,B=A.test(B=l.bind)&&/\n|Opera/.test(B+h.call(u.opera))&&B,C=A.test(C=Array.isArray)&&C,Ea=u.isFinite,Y=A.test(Y=Object.keys)&&Y,Fa=u.clearTimeout,P=u.setTimeout,ta=Function("u","var __p;with(u){__p='var o,z';if(k){__p+='='+k};__p+=';'+f+';'+q+';';if(c){__p+='var t='+g+'.length;o=-1;';if(o){__p+='if(t===+t){'};__p+=''+c['d']+';while('+c['m']+'){'+c['j']+'}';if(o){__p+='}'}}if(o){if(c){__p+='else{'}if(!i){__p+='var A=typeof '+l+'==\\'function\\';'};__p+=''+o['d']+';for('+o['m']+'){';if(i){if(r){__p+='if('+h+'){'};__p+=''+o['j']+';';if(r){__p+='}'}}else{__p+='if(!(A&&o==\\'prototype\\')';if(r){__p+='&&'+h};__p+='){'+o['j']+'}'};__p+='}';if(i){__p+='var j='+l+'.constructor;';for(var k=0;k<7;k++){__p+='o=\\''+p[k]+'\\';if(';if(p[k]=='constructor'){__p+='!(j&&j.prototype==='+l+')&&'};__p+=''+h+'){'+o['j']+'}'}}if(c){__p+='}'}};__p+=''+e+';return z'}return __p"
|
||||
),q={a:"h,f,G",k:"h",q:"if(!f){f=n}else if(G){f=e(f,G)}",j:"f(h[o],o,h)"},Z={k:"I",j:"if(!f(h[o],o,h))return!z"},A={a:"u",k:"u",q:"for(var C,D=1,t=arguments.length;D<t;D++){C=arguments[D];"+(H?"if(C){":""),m:"o in C",r:r,j:"u[o]=C[o]",e:(H?"}":"")+"}"},G={k:"[]",j:"f(h[o],o,h)&&z.push(h[o])"},y={k:"",f:"if(!h)return[]",d:{b:"z=Array(t)",n:"z=[]"},j:{b:"z[o]=f(h[o],o,h)",n:"z.push(f(h[o],o,h))"}},J=C||function(a){return h.call(a)==I},da=j({a:"K",k:"I",q:"var g=H.call(K);if(g==d||g==E)return!K.length"
|
||||
,j:{n:"return k"}}),C=j({a:"h,F",k:"k",j:"if(h[o]===F)return I"}),W=j(q,Z),pa=j(q,G),qa=j(q,{j:"if(f(h[o],o,h))return h[o]"}),F=j(q,{q:"if(G)f=e(f,G)"}),Ga=j(q,{k:"{}",q:"var x,s=H.call(f)==l;if(s&&G)f=e(f,G)",j:"x=s?f(h[o],o,h):h[o][f];(z[x]||(z[x]=[])).push(h[o])"}),$=j(q,y),Q=j(y,{a:"h,y",j:{b:"z[o]=h[o][y]",n:"z.push(h[o][y])"}}),aa=j({a:"h,f,a,G",k:"a",q:"var w=arguments.length<3;if(G)f=e(f,G)",d:{b:"if(w)z=h[++o]"},j:{b:"z=f(z,h[o],o,h)",n:"z=w?(w=k,h[o]):f(z,h[o],o,h)"}}),G=j(q,G,{j:"!"+G.
|
||||
j}),q=j(q,Z,{k:"k",j:Z.j.replace("!","")}),ra=j(y,{a:"h",j:{b:"z[o]=h[o]",n:"z.push(h[o])"}}),y=j(A,{j:"if(u[o]==J)"+A.j}),sa=j(A),O=j({a:"u",k:"[]",r:r,j:"if(H.call(u[o])==l)z.push(o)",e:"z.sort()"});R(arguments)||(R=function(a){return!!a&&!!t.call(a,"callee")});var U=Y||j({a:"u",f:"if(!v[typeof u]||u===null)throw TypeError()",k:"[]",j:"z.push(o)"});c.VERSION="0.2.0",c.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:"object"},c.after=
|
||||
function(a,b){return 1>a?b():function(){if(1>--a)return b.apply(this,arguments)}},c.bind=v,c.bindAll=function(a){var b=arguments,d=1;1==b.length&&(d=0,b=O(a));for(var c=b.length;d<c;d++)a[b[d]]=v(a[b[d]],a);return a},c.chain=function(a){return a=new p(a),a.s=n,a},c.clone=function(a){return S[typeof a]&&a!==o?J(a)?a.slice():sa({},a):a},c.compact=function(a){for(var b=-1,d=a.length,c=[];++b<d;)a[b]&&c.push(a[b]);return c},c.compose=function(){var a=arguments;return function(){for(var b=arguments,d=
|
||||
a.length;d--;)b=[a[d].apply(this,b)];return b[0]}},c.contains=C,c.debounce=function(a,b,d){function c(){i=m,d||a.apply(g,e)}var e,f,g,i;return function(){var h=d&&!i;return e=arguments,g=this,Fa(i),i=P(c,b),h&&(f=a.apply(g,e)),f}},c.defaults=y,c.defer=function(a){var b=l.call(arguments,1);return P(function(){return a.apply(m,b)},1)},c.delay=function(a,b){var d=l.call(arguments,2);return P(function(){return a.apply(m,d)},b)},c.difference=function(a){for(var b=-1,d=a.length,c=[],e=D.apply(c,l.call(
|
||||
arguments,1));++b<d;)0>w(e,a[b])&&c.push(a[b]);return c},c.escape=function(a){return(a+"").replace(/&/g,"&").replace(/</g,"<").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")},c.every=W,c.extend=sa,c.filter=pa,c.find=qa,c.first=V,c.flatten=fa,c.forEach=F,c.functions=O,c.groupBy=Ga,c.has=function(a,b){return t.call(a,b)},c.identity=ca,c.indexOf=w,c.initial=function(a,b,d){return l.call(a,0,-(b==m||d?1:b))},c.intersection=ha,c.invoke=function(a,b){for(var d=l.call(arguments
|
||||
,2),c=-1,e=a.length,f=h.call(b)==s,g=[];++c<e;)g[c]=(f?b:a[c][b]).apply(a[c],d);return g},c.isArguments=R,c.isArray=J,c.isBoolean=function(a){return a===n||a===r||h.call(a)==la},c.isDate=function(a){return h.call(a)==ma},c.isElement=function(a){return!!a&&1==a.nodeType},c.isEmpty=da,c.isEqual=M,c.isFinite=function(a){return Ea(a)&&h.call(a)==N},c.isFunction=function(a){return h.call(a)==s},c.isNaN=function(a){return h.call(a)==N&&a!=+a},c.isNull=function(a){return a===o},c.isNumber=function(a){return h
|
||||
.call(a)==N},c.isObject=function(a){return S[typeof a]&&a!==o},c.isRegExp=function(a){return h.call(a)==na},c.isString=function(a){return h.call(a)==K},c.isUndefined=function(a){return a===m},c.keys=U,c.last=function(a,b,d){var c=a.length;return b==m||d?a[c-1]:l.call(a,-b||c)},c.lastIndexOf=function(a,b){if(!a)return-1;for(var d=a.length;d--;)if(a[d]===b)return d;return-1},c.map=$,c.max=ia,c.memoize=function(a,b){var d={};return function(){var c=b?b.apply(this,arguments):arguments[0];return t.call
|
||||
(d,c)?d[c]:d[c]=a.apply(this,arguments)}},c.min=function(a,b,d){var c=Infinity,e=-1,f=a.length,g=c;if(b)d&&(b=v(b,d));else{if(a[0]===+a[0]&&f<=L)try{return Math.min.apply(Math,a)}catch(i){}if(!a.length)return g}for(;++e<f;)d=b?b(a[e],e,a):a[e],d<c&&(c=d,g=a[e]);return g},c.mixin=oa,c.noConflict=function(){return u._=Ba,this},c.once=function(a){var b,d=r;return function(){return d?b:(d=n,b=a.apply(this,arguments))}},c.partial=function(a){var b=l.call(arguments,1),d=b.length;return function(){var c
|
||||
;return c=arguments,c.length&&(b.length=d,E.apply(b,c)),c=1==b.length?a.call(this,b[0]):a.apply(this,b),b.length=d,c}},c.pick=function(a){for(var b,d=0,c=D.apply(z,arguments),e=c.length,f={};++d<e;)b=c[d],b in a&&(f[b]=a[b]);return f},c.pluck=Q,c.range=function(a,b,d){d||(d=1),2>arguments.length&&(b=a||0,a=0);for(var c=-1,e=Math.max(Math.ceil((b-a)/d),0),f=Array(e);++c<e;)f[c]=a,a+=d;return f},c.reduce=aa,c.reduceRight=ea,c.reject=G,c.rest=ja,c.result=function(a,b){if(!a)return o;var d=a[b];return h
|
||||
.call(d)==s?a[b]():d},c.shuffle=function(a){for(var b,d=-1,c=a.length,e=Array(c);++d<c;)b=Math.floor(Math.random()*(d+1)),e[d]=e[b],e[b]=a[d];return e},c.size=function(a){var b=h.call(a);return b==I||b==K?a.length:U(a).length},c.some=q,c.sortBy=function(a,b,d){if(h.call(b)!=s)var c=b,b=function(a){return a[c]};else d&&(b=v(b,d));return Q($(a,function(d,c){return{a:b(d,c,a),b:d}}).sort(function(a,b){var d=a.a,c=b.a;return d===m?1:c===m?-1:d<c?-1:d>c?1:0}),"b")},c.sortedIndex=ga,c.tap=function(a,b)
|
||||
{return b(a),a},c.template=function(a,b,d){d||(d={});var k;k=c.templateSettings||{};var e=d.escape,f=d.evaluate,g=d.interpolate,d=d.variable;return e==o&&(e=k.escape),f==o&&(f=k.evaluate),g==o&&(g=k.interpolate),e&&(a=a.replace(e,xa)),g&&(a=a.replace(g,ya)),f&&(a=a.replace(f,za)),a="__p='"+a.replace(Da,va).replace(Ca,ua)+"';\n",x.length=0,d||(d=k.variable||"object",a="with("+d+"||{}){"+a+"}"),a="function("+d+"){var __p,__t,__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}"+a+"return __p}"
|
||||
,k=Function("_","return "+a)(c),b?k(b):(k.source=a,k)},c.throttle=function(a,b){function d(){i=new Date,g=m,a.apply(f,c)}var c,e,f,g,i=0;return function(){var h=new Date,j=b-(h-i);return c=arguments,f=this,0>=j?(i=h,e=a.apply(f,c)):g||(g=P(d,j)),e}},c.times=function(a,b,d){d&&(b=v(b,d));for(d=0;d<a;d++)b(d)},c.toArray=function(a){if(!a)return[];if(h.call(a.toArray)==s)return a.toArray();var b=a.length;return b===+b?l.call(a):ra(a)},c.union=function(){for(var a=-1,b=[],d=D.apply(b,arguments),c=d.length
|
||||
;++a<c;)0>w(b,d[a])&&b.push(d[a]);return b},c.uniq=ka,c.uniqueId=function(a){var b=Aa++;return a?a+b:b},c.values=ra,c.without=function(a){for(var b=l.call(arguments,1),d=-1,c=a.length,e=[];++d<c;)0>w(b,a[d])&&e.push(a[d]);return e},c.wrap=function(a,b){return function(){var c=[a];return arguments.length&&E.apply(c,arguments),b.apply(this,c)}},c.zip=function(){for(var a=-1,b=ia(Q(arguments,"length")),c=Array(b);++a<b;)c[a]=Q(arguments,a);return c},c.all=W,c.any=q,c.collect=$,c.detect=qa,c.each=F,c
|
||||
.foldl=aa,c.foldr=ea,c.head=V,c.include=C,c.inject=aa,c.intersect=ha,c.methods=O,c.select=pa,c.tail=ja,c.take=V,c.unique=ka,p.prototype=c.prototype,oa(c),p.prototype.chain=function(){return this.s=n,this},p.prototype.value=function(){return this._wrapped},F("pop push reverse shift sort splice unshift".split(" "),function(a){var b=z[a];p.prototype[a]=function(){var a=this._wrapped;return arguments.length?b.apply(a,arguments):b.call(a),a.length===0&&delete a[0],this.s&&(a=new p(a),a.s=n),a}}),F(["concat"
|
||||
,"join","slice"],function(a){var b=z[a];p.prototype[a]=function(){var a=this._wrapped,a=arguments.length?b.apply(a,arguments):b.call(a);return this.s&&(a=new p(a),a.s=n),a}}),X?"object"==typeof module&&module&&module.t==X?(module.t=c)._=c:X._=c:(u._=c,typeof define=="function"&&typeof define.amd=="object"&&define.amd&&define(function(){return c}))})(this);
|
||||
;(function(e,t){"use strict";function s(e){return"[object Arguments]"==nt.call(e)}function o(e){return new u(e)}function u(e){if(e&&e._wrapped)return e;this._wrapped=e}function a(){for(var e,t,s,o=-1,u=arguments.length,a={e:"",f:"",k:"",q:"",c:{d:"",m:"++l<o"},o:{d:""}};++o<u;)for(t in e=arguments[o],e)s=(s=e[t])==r?"":s,/d|m|j/.test(t)?("string"==typeof s&&(s={b:s,n:s}),a.c[t]=s.b,a.o[t]=s.n):a[t]=s;e=a.a,t=a.c,s=a.o;var o=/^[^,]+/.exec(e)[0],u=s.m,f=/\S+$/.exec(u||o)[0];a.g=o,a.i=O,a.h="j.call("+
|
||||
f+",l)",a.l=f,a.p=j,a.r=a.r!==i,a.f||(a.f="if(!"+o+")return u");if("r"==o||!t.j)a.c=r;return u||(s.m="l in "+f),Function("c,i,j,k,n,s,w,z,C,D,h,E",'"use strict";return function('+e+"){"+ft(a)+"}")(z,V,Z,k,h,R,tt,K,nt,n,i)}function f(e,t){return I[t]}function l(e){return"\\"+U[e]}function c(e){return q[e]}function h(e,t){return function(n,r,i){return e.call(t,n,r,i)}}function p(){}function d(e,t){var n=I.length;return I[n]="'+_.escape("+t+")+'",F+n}function v(e,t){var n=I.length;return I[n]="'+((__t=("+
|
||||
t+"))==null?'':__t)+'",F+n}function m(e,t){var n=I.length;return I[n]="';"+t+";__p+='",F+n}function g(e,t,n,r){if(!e)return n;var i=e.length,s=3>arguments.length;r&&(t=h(t,r));if(i===i>>>0){for(i&&s&&(n=e[--i]);i--;)n=t(n,e[i],i,e);return n}var o=Lt(e);for((i=o.length)&&s&&(n=e[o[--i]]);i--;)s=o[i],n=t(n,e[s],s,e);return n}function y(e,n,r){if(e)return n==t||r?e[0]:tt.call(e,0,n)}function b(e,t){var n=[];if(!e)return n;for(var r,i=-1,s=e.length;++i<s;)r=e[i],kt(r)?et.apply(n,t?r:b(r)):n.push(r);return n
|
||||
}function w(e,t,n){if(!e)return-1;var r=-1,i=e.length;if(n){if("number"!=typeof n)return r=x(e,t),e[r]===t?r:-1;r=(0>n?Math.max(0,i+n):n)-1}for(;++r<i;)if(e[r]===t)return r;return-1}function E(e,t,n){var r=-Infinity,i=r;if(!e)return i;var s=-1,o=e.length;if(!t){for(;++s<o;)e[s]>i&&(i=e[s]);return i}for(n&&(t=h(t,n));++s<o;)n=t(e[s],s,e),n>r&&(r=n,i=e[s]);return i}function S(e,n,r){return e?tt.call(e,n==t||r?1:n):[]}function x(e,t,n,r){if(!e)return 0;var i=0,s=e.length;if(n){r&&(n=N(n,r));for(t=n(
|
||||
t);i<s;)r=i+s>>>1,n(e[r])<t?i=r+1:s=r}else for(;i<s;)r=i+s>>>1,e[r]<t?i=r+1:s=r;return i}function T(e,t,n,r){var s=[];if(!e)return s;var o=-1,u=e.length,a=[];"function"==typeof t&&(r=n,n=t,t=i);for(n?r&&(n=h(n,r)):n=k;++o<u;)if(r=n(e[o],o,e),t?!o||a[a.length-1]!==r:0>w(a,r))a.push(r),s.push(e[o]);return s}function N(e,t){function n(){var u=arguments,a=t;return s||(e=t[i]),o.length&&(u=u.length?Y.apply(o,u):o),this instanceof n?(p.prototype=e.prototype,a=new p,u=e.apply(a,u),R[typeof u]&&u!==r?u:a
|
||||
):e.apply(a,u)}var i,s=nt.call(e)==V;if(s){if(rt)return rt.call.apply(rt,arguments)}else i=t,t=e;var o=tt.call(arguments,2);return n}function C(e,r,s){s||(s=[]);if(e===r)return 0!==e||1/e==1/r;if(e==t||r==t)return e===r;e._chain&&(e=e._wrapped),r._chain&&(r=r._wrapped);if(e.isEqual&&nt.call(e.isEqual)==V)return e.isEqual(r);if(r.isEqual&&nt.call(r.isEqual)==V)return r.isEqual(e);var o=nt.call(e);if(o!=nt.call(r))return i;switch(o){case K:return e==""+r;case $:return e!=+e?r!=+r:0==e?1/e==1/r:e==+
|
||||
r;case W:case X:return+e==+r;case J:return e.source==r.source&&e.global==r.global&&e.multiline==r.multiline&&e.ignoreCase==r.ignoreCase}if("object"!=typeof e||"object"!=typeof r)return i;for(var u=s.length;u--;)if(s[u]==e)return n;var u=-1,a=n,f=0;s.push(e);if(o==z){if(f=e.length,a=f==r.length)for(;f--&&(a=C(e[f],r[f],s)););}else{if("constructor"in e!="constructor"in r||e.constructor!=r.constructor)return i;for(var l in e)if(Z.call(e,l)&&(f++,!(a=Z.call(r,l)&&C(e[l],r[l],s))))break;if(a){for(l in
|
||||
r)if(Z.call(r,l)&&!(f--))break;a=!f}if(a&&O)for(;7>++u&&(l=j[u],!Z.call(e,l)||!!(a=Z.call(r,l)&&C(e[l],r[l],s))););}return s.pop(),a}function k(e){return e}function L(e){wt(Ct(e),function(t){var r=o[t]=e[t];u.prototype[t]=function(){var e=[this._wrapped];return arguments.length&&et.apply(e,arguments),e=r.apply(o,e),this._chain&&(e=new u(e),e._chain=n),e}})}var n=!0,r=null,i=!1,A="object"==typeof exports&&exports&&("object"==typeof global&&global&&global==global.global&&(e=global),exports),O=!{valueOf
|
||||
:0}.propertyIsEnumerable("valueOf"),M=0,_=e._,D=RegExp("^"+({}.valueOf+"").replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),P=/__token__(\d+)/g,H=/[&<"']/g,B=/['\n\r\t\u2028\u2029\\]/g,j="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),F="__token__",I=[],q={"&":"&","<":"<",'"':""","'":"'"},R={"boolean":i,"function":n,object:n,number:i,string:i,"undefined":i},U={"\\":"\\","'":"'","\n":"n"
|
||||
,"\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"},z="[object Array]",W="[object Boolean]",X="[object Date]",V="[object Function]",$="[object Number]",J="[object RegExp]",K="[object String]",Q=Array.prototype,G=Object.prototype,Y=Q.concat,Z=G.hasOwnProperty,et=Q.push,tt=Q.slice,nt=G.toString,rt=D.test(rt=tt.bind)&&/\n|Opera/.test(rt+nt.call(e.opera))&&rt,it=D.test(it=Array.isArray)&&it,st=e.isFinite,ot=D.test(ot=Object.keys)&&ot,ut=e.clearTimeout,at=e.setTimeout;o.templateSettings={escape:/<%-([\s\S]+?)%>/g
|
||||
,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:"obj"};var ft=Function("obj","var __p;with(obj){__p='var l,u';if(k){__p+='='+k};__p+=';'+f+';'+q+';';if(c){__p+='var o='+g+'.length;l=-1;';if(o){__p+='if(o===o>>>0){'};__p+=''+c['d']+';while('+c['m']+'){'+c['j']+'}';if(o){__p+='}'}}if(o){if(c){__p+='else{'}if(!i){__p+='var v=typeof '+l+'==\\'function\\';'};__p+=''+o['d']+';for('+o['m']+'){';if(i){if(r){__p+='if('+h+'){'};__p+=''+o['j']+';';if(r){__p+='}'}}else{__p+='if(!(v&&l==\\'prototype\\')';if(r){__p+='&&'+h};__p+='){'+o['j']+'}'};__p+='}';if(i){__p+='var g='+l+'.constructor;';for(var k=0;k<7;k++){__p+='l=\\''+p[k]+'\\';if(';if(p[k]=='constructor'){__p+='!(g&&g.prototype==='+l+')&&'};__p+=''+h+'){'+o['j']+'}'}}if(c){__p+='}'}};__p+=''+e+';return u'}return __p"
|
||||
),lt={a:"f,d,B",k:"f",q:"if(!d){d=k}else if(B){d=n(d,B)}",j:"d(f[l],l,f)"},ct={k:"D",j:"if(!d(f[l],l,f))return!u"},ht={a:"r",k:"r",q:"for(var x,y=1,o=arguments.length;y<o;y++){x=arguments[y];"+(O?"if(x){":""),m:"l in x",r:i,j:"r[l]=x[l]",e:(O?"}":"")+"}"},pt={k:"[]",j:"d(f[l],l,f)&&u.push(f[l])"},dt={q:"if(B)d=n(d,B)"},vt={j:{n:lt.j}},mt={k:"",f:"if(!f)return[]",d:{b:"u=Array(o)",n:"u=[]"},j:{b:"u[l]=d(f[l],l,f)",n:"u.push(d(f[l],l,f))"}},gt=a({a:"r",f:"if(!s[typeof r]||r===null)throw TypeError()"
|
||||
,k:"[]",j:"u.push(l)"}),D=a({a:"f,A",k:"h",j:"if(f[l]===A)return D"}),yt=a(lt,ct),G=a(lt,pt),bt=a(lt,dt,{k:"",j:"if(d(f[l],l,f))return f[l]"}),wt=a(lt,dt),Et=a(mt,{a:"f,p",q:"var b=w.call(arguments,2),m=typeof p=='function'",j:{b:"u[l]=(m?p:f[l][p]).apply(f[l],b)",n:"u.push((m?p:f[l][p]).apply(f[l],b))"}}),St=a(lt,mt),xt=a(mt,{a:"f,t",j:{b:"u[l]=f[l][t]",n:"u.push(f[l][t])"}}),mt=a({a:"f,d,a,B",k:"a",q:"var q=arguments.length<3;if(B)d=n(d,B)",d:{b:"if(q)u=f[++l]"},j:{b:"u=d(u,f[l],l,f)",n:"u=q?(q=h,f[l]):d(u,f[l],l,f)"
|
||||
}}),pt=a(lt,pt,{j:"!"+pt.j}),ct=a(lt,ct,{k:"h",j:ct.j.replace("!","")}),Tt=a(ht,{j:"if(r[l]==E)"+ht.j}),Nt=a(ht),ht=a(lt,dt,vt,{r:i}),lt=a(lt,dt,vt),Ct=a({a:"r",k:"[]",r:i,j:"if(C.call(r[l])==i)u.push(l)",e:"u.sort()"});s(arguments)||(s=function(e){return!!e&&!!Z.call(e,"callee")});var kt=it||function(e){return nt.call(e)==z},it=a({a:"F",k:"D",q:"var e=C.call(F);if(e==c||e==z)return!F.length",j:{n:"return h"}}),Lt=ot?function(e){return"function"==typeof e?gt(e):ot(e)}:gt,At=a({a:"r",k:"[]",j:"u.push(r[l])"
|
||||
});o.VERSION="0.3.2",o.after=function(e,t){return 1>e?t():function(){if(1>--e)return t.apply(this,arguments)}},o.bind=N,o.bindAll=function(e){var t=arguments,n=1;1==t.length&&(n=0,t=Ct(e));for(var r=t.length;n<r;n++)e[t[n]]=N(e[t[n]],e);return e},o.chain=function(e){return e=new u(e),e._chain=n,e},o.clone=function(e){return R[typeof e]&&e!==r?kt(e)?e.slice():Nt({},e):e},o.compact=function(e){var t=[];if(!e)return t;for(var n=-1,r=e.length;++n<r;)e[n]&&t.push(e[n]);return t},o.compose=function(){var e=
|
||||
arguments;return function(){for(var t=arguments,n=e.length;n--;)t=[e[n].apply(this,t)];return t[0]}},o.contains=D,o.debounce=function(e,n,r){function i(){a=t,r||e.apply(u,s)}var s,o,u,a;return function(){var t=r&&!a;return s=arguments,u=this,ut(a),a=at(i,n),t&&(o=e.apply(u,s)),o}},o.defaults=Tt,o.defer=function(e){var n=tt.call(arguments,1);return at(function(){return e.apply(t,n)},1)},o.delay=function(e,n){var r=tt.call(arguments,2);return at(function(){return e.apply(t,r)},n)},o.difference=function(
|
||||
e){var t=[];if(!e)return t;for(var n=-1,r=e.length,i=Y.apply(t,tt.call(arguments,1));++n<r;)0>w(i,e[n])&&t.push(e[n]);return t},o.escape=function(e){return e==r?"":(e+"").replace(H,c)},o.every=yt,o.extend=Nt,o.filter=G,o.find=bt,o.first=y,o.flatten=b,o.forEach=wt,o.forIn=ht,o.forOwn=lt,o.functions=Ct,o.groupBy=function(e,t,n){var r={};if(!e)return r;var i,s=-1,o="function"==typeof t,u=e.length;for(o&&n&&(t=h(t,n));++s<u;)i=e[s],n=o?t(i,s,e):i[t],(Z.call(r,n)?r[n]:r[n]=[]).push(i);return r},o.has=
|
||||
function(e,t){return Z.call(e,t)},o.identity=k,o.indexOf=w,o.initial=function(e,n,r){return e?tt.call(e,0,-(n==t||r?1:n)):[]},o.intersection=function(e){var t=[];if(!e)return t;for(var n,r=-1,i=e.length,s=tt.call(arguments,1);++r<i;)n=e[r],0>w(t,n)&&yt(s,function(e){return-1<w(e,n)})&&t.push(n);return t},o.invoke=Et,o.isArguments=s,o.isArray=kt,o.isBoolean=function(e){return e===n||e===i||nt.call(e)==W},o.isDate=function(e){return nt.call(e)==X},o.isElement=function(e){return!!e&&1==e.nodeType},o
|
||||
.isEmpty=it,o.isEqual=C,o.isFinite=function(e){return st(e)&&nt.call(e)==$},o.isFunction=function(e){return nt.call(e)==V},o.isNaN=function(e){return nt.call(e)==$&&e!=+e},o.isNull=function(e){return e===r},o.isNumber=function(e){return nt.call(e)==$},o.isObject=function(e){return R[typeof e]&&e!==r},o.isRegExp=function(e){return nt.call(e)==J},o.isString=function(e){return nt.call(e)==K},o.isUndefined=function(e){return e===t},o.keys=Lt,o.last=function(e,n,r){if(e){var i=e.length;return n==t||r?
|
||||
e[i-1]:tt.call(e,-n||i)}},o.lastIndexOf=function(e,t,n){if(!e)return-1;var r=e.length;for(n&&"number"==typeof n&&(r=(0>n?Math.max(0,r+n):Math.min(n,r-1))+1);r--;)if(e[r]===t)return r;return-1},o.map=St,o.max=E,o.memoize=function(e,t){var n={};return function(){var r=t?t.apply(this,arguments):arguments[0];return Z.call(n,r)?n[r]:n[r]=e.apply(this,arguments)}},o.min=function(e,t,n){var r=Infinity,i=r;if(!e)return i;var s=-1,o=e.length;if(!t){for(;++s<o;)e[s]<i&&(i=e[s]);return i}for(n&&(t=h(t,n));++
|
||||
s<o;)n=t(e[s],s,e),n<r&&(r=n,i=e[s]);return i},o.mixin=L,o.noConflict=function(){return e._=_,this},o.once=function(e){var t,r=i;return function(){return r?t:(r=n,t=e.apply(this,arguments))}},o.partial=function(e){var t=tt.call(arguments,1),n=t.length;return function(){var r;return r=arguments,r.length&&(t.length=n,et.apply(t,r)),r=1==t.length?e.call(this,t[0]):e.apply(this,t),t.length=n,r}},o.pick=function(e){for(var t,n=0,r=Y.apply(Q,arguments),i=r.length,s={};++n<i;)t=r[n],t in e&&(s[t]=e[t]);
|
||||
return s},o.pluck=xt,o.range=function(e,t,n){n||(n=1),2>arguments.length&&(t=e||0,e=0);for(var r=-1,i=Math.max(Math.ceil((t-e)/n),0),s=Array(i);++r<i;)s[r]=e,e+=n;return s},o.reduce=mt,o.reduceRight=g,o.reject=pt,o.rest=S,o.result=function(e,t){if(!e)return r;var n=e[t];return nt.call(n)==V?e[t]():n},o.shuffle=function(e){if(!e)return[];for(var t,n=-1,r=e.length,i=Array(r);++n<r;)t=Math.floor(Math.random()*(n+1)),i[n]=i[t],i[t]=e[n];return i},o.size=function(e){var t=nt.call(e);return t==z||t==K?
|
||||
e.length:Lt(e).length},o.some=ct,o.sortBy=function(e,n,r){if(!e)return[];if("string"==typeof n)var i=n,n=function(e){return e[i]};else r&&(n=h(n,r));for(var r=-1,s=e.length,o=Array(s);++r<s;)o[r]={a:n(e[r],r,e),b:e[r]};for(o.sort(function(e,n){var r=e.a,i=n.a;return r===t?1:i===t?-1:r<i?-1:r>i?1:0});s--;)o[s]=o[s].b;return o},o.sortedIndex=x,o.tap=function(e,t){return t(e),e},o.template=function(e,t,n){n||(n={});var i;i=o.templateSettings;var s=n.escape,u=n.evaluate,a=n.interpolate,n=n.variable;return s==
|
||||
r&&(s=i.escape),u==r&&(u=i.evaluate),a==r&&(a=i.interpolate),s&&(e=e.replace(s,d)),a&&(e=e.replace(a,v)),u&&(e=e.replace(u,m)),e="__p='"+e.replace(B,l).replace(P,f)+"';",I.length=0,n||(n=i.variable,e="with("+n+"||{}){"+e+"}"),e="function("+n+"){var __p,__t,__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}"+e+"return __p}",i=Function("_","return "+e)(o),t?i(t):(i.source=e,i)},o.throttle=function(e,n){function r(){a=new Date,u=t,e.apply(o,i)}var i,s,o,u,a=0;return function(){var t=new
|
||||
Date,f=n-(t-a);return i=arguments,o=this,0>=f?(a=t,s=e.apply(o,i)):u||(u=at(r,f)),s}},o.times=function(e,t,n){var r=-1;if(n)for(;++r<e;)t.call(n,r);else for(;++r<e;)t(r)},o.toArray=function(e){if(!e)return[];if(nt.call(e.toArray)==V)return e.toArray();var t=e.length;return t===t>>>0?tt.call(e):At(e)},o.union=function(){for(var e=-1,t=[],n=Y.apply(t,arguments),r=n.length;++e<r;)0>w(t,n[e])&&t.push(n[e]);return t},o.uniq=T,o.uniqueId=function(e){var t=M++;return e?e+t:t},o.values=At,o.without=function(
|
||||
e){var t=[];if(!e)return t;for(var n=tt.call(arguments,1),r=-1,i=e.length;++r<i;)0>w(n,e[r])&&t.push(e[r]);return t},o.wrap=function(e,t){return function(){var n=[e];return arguments.length&&et.apply(n,arguments),t.apply(this,n)}},o.zip=function(e){if(!e)return[];for(var t=-1,n=E(xt(arguments,"length")),r=Array(n);++t<n;)r[t]=xt(arguments,t);return r},o.all=yt,o.any=ct,o.collect=St,o.detect=bt,o.each=wt,o.foldl=mt,o.foldr=g,o.head=y,o.include=D,o.inject=mt,o.methods=Ct,o.select=G,o.tail=S,o.take=
|
||||
y,o.unique=T,u.prototype=o.prototype,L(o),u.prototype.chain=function(){return this._chain=n,this},u.prototype.value=function(){return this._wrapped},wt("pop push reverse shift sort splice unshift".split(" "),function(e){var t=Q[e];u.prototype[e]=function(){var e=this._wrapped;return t.apply(e,arguments),e.length===0&&delete e[0],this._chain&&(e=new u(e),e._chain=n),e}}),wt(["concat","join","slice"],function(e){var t=Q[e];u.prototype[e]=function(){var e=t.apply(this._wrapped,arguments);return this
|
||||
._chain&&(e=new u(e),e._chain=n),e}}),typeof define=="function"&&typeof define.amd=="object"&&define.amd?(e._=o,define(function(){return o})):A?"object"==typeof module&&module&&module.s==A?(module.s=o)._=o:A._=o:e._=o})(this);
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "lodash",
|
||||
"version": "0.2.0",
|
||||
"version": "0.3.2",
|
||||
"description": "A drop-in replacement for Underscore.js that delivers performance improvements, bug fixes, and additional features.",
|
||||
"homepage": "http://lodash.com",
|
||||
"main": "lodash",
|
||||
|
||||
@@ -9,14 +9,18 @@
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
}
|
||||
applet {
|
||||
position: absolute;
|
||||
left: -9999em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script src="../lodash.min.js"></script>
|
||||
<script src="../lodash.js"></script>
|
||||
<script>
|
||||
var lodash = _.noConflict();
|
||||
</script>
|
||||
<script src="../vendor/underscore/underscore-min.js"></script>
|
||||
<script src="../vendor/underscore/underscore.js"></script>
|
||||
<script src="../vendor/benchmark.js/benchmark.js"></script>
|
||||
<script src="../vendor/firebug-lite/src/firebug-lite-debug.js"></script>
|
||||
<script>
|
||||
@@ -30,11 +34,13 @@
|
||||
}());
|
||||
|
||||
window.onload = function() {
|
||||
var sibling = document.getElementsByTagName('script')[0],
|
||||
var fbUI = document.getElementById('FirebugUI'),
|
||||
fbDoc = (fbDoc = fbUI.contentWindow || fbUI.contentDocument).document || fbDoc,
|
||||
sibling = document.getElementsByTagName('script')[0],
|
||||
script = document.createElement('script');
|
||||
|
||||
document.getElementById('FirebugUI').style.height = '100%';
|
||||
script.src = 'perf.js';
|
||||
fbUI.style.height = fbDoc.body.style.height = fbDoc.documentElement.style.height = '100%';
|
||||
script.src = 'perf.js?t=' + (+new Date);
|
||||
sibling.parentNode.insertBefore(script, sibling);
|
||||
};
|
||||
</script>
|
||||
|
||||
509
perf/perf.js
509
perf/perf.js
@@ -13,7 +13,7 @@
|
||||
/** Load Lo-Dash */
|
||||
var lodash =
|
||||
window.lodash || (
|
||||
lodash = load('../lodash.min.js') || window._,
|
||||
lodash = load('../lodash.js') || window._,
|
||||
lodash = lodash._ || lodash,
|
||||
lodash.noConflict()
|
||||
);
|
||||
@@ -21,10 +21,15 @@
|
||||
/** Load Underscore */
|
||||
var _ =
|
||||
window._ || (
|
||||
_ = load('../vendor/underscore/underscore-min.js') || window._,
|
||||
_ = load('../vendor/underscore/underscore.js') || window._,
|
||||
_._ || _
|
||||
);
|
||||
|
||||
/** Used to access the Firebug Lite panel */
|
||||
var fbPanel = (fbPanel = window.document && document.getElementById('FirebugUI')) &&
|
||||
(fbPanel = (fbPanel = fbPanel.contentWindow || fbPanel.contentDocument).document || fbPanel) &&
|
||||
fbPanel.getElementById('fbPanel1');
|
||||
|
||||
/** Used to score Lo-Dash and Underscore performance */
|
||||
var score = { 'lodash': 0, 'underscore': 0 };
|
||||
|
||||
@@ -41,43 +46,112 @@
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Logs text to the console.
|
||||
*
|
||||
* @private
|
||||
* @param {String} text The text to log.
|
||||
*/
|
||||
function log(text) {
|
||||
console.log(text);
|
||||
if (fbPanel) {
|
||||
// scroll the Firebug Lite panel down
|
||||
fbPanel.scrollTop = fbPanel.scrollHeight;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
lodash.extend(Benchmark.options, {
|
||||
'async': true,
|
||||
'setup': function() {
|
||||
var window = Function('return this || global')(),
|
||||
_ = window._,
|
||||
lodash = window.lodash,
|
||||
numbers = [],
|
||||
object = {};
|
||||
lodash = window.lodash;
|
||||
|
||||
for (var index = 0; index < 20; index++) {
|
||||
var length = 20,
|
||||
numbers = [],
|
||||
object = {},
|
||||
fourNumbers = [5, 25, 10, 30],
|
||||
nestedNumbers = [1, [2], [3, [[4]]]],
|
||||
twoNumbers = [12, 21];
|
||||
|
||||
var ctor = function() { },
|
||||
func = function(greeting) { return greeting + ': ' + this.name; };
|
||||
|
||||
var lodashBoundNormal = lodash.bind(func, { 'name': 'moe' }),
|
||||
lodashBoundCtor = lodash.bind(ctor, { 'name': 'moe' }),
|
||||
lodashBoundPartial = lodash.bind(func, { 'name': 'moe' }, 'hi');
|
||||
|
||||
var _boundNormal = _.bind(func, { 'name': 'moe' }),
|
||||
_boundCtor = _.bind(ctor, { 'name': 'moe' }),
|
||||
_boundPartial = _.bind(func, { 'name': 'moe' }, 'hi');
|
||||
|
||||
var wordToNumber = {
|
||||
'one': 1,
|
||||
'two': 2,
|
||||
'three': 3,
|
||||
'four': 4,
|
||||
'five': 5,
|
||||
'six': 6,
|
||||
'seven': 7,
|
||||
'eight': 8,
|
||||
'nine': 9,
|
||||
'ten': 10,
|
||||
'eleven': 11,
|
||||
'twelve': 12,
|
||||
'thirteen': 13,
|
||||
'fourteen': 14,
|
||||
'fifteen': 15,
|
||||
'sixteen': 16,
|
||||
'seventeen': 17,
|
||||
'eighteen': 18,
|
||||
'nineteen': 19,
|
||||
'twenty': 20,
|
||||
'twenty-one': 21,
|
||||
'twenty-two': 22,
|
||||
'twenty-three': 23,
|
||||
'twenty-four': 24,
|
||||
'twenty-five': 25
|
||||
};
|
||||
|
||||
var words = _.keys(wordToNumber).slice(0, length);
|
||||
|
||||
for (var index = 0; index < length; index++) {
|
||||
numbers[index] = index;
|
||||
object['key' + index] = index;
|
||||
}
|
||||
|
||||
var objects = lodash.map(numbers, function(n) {
|
||||
return { 'num': n };
|
||||
var objects = lodash.map(numbers, function(num) {
|
||||
return { 'num': num };
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
lodash.extend(Benchmark.Suite.options, {
|
||||
'onStart': function() {
|
||||
console.log('\n' + this.name + ':');
|
||||
log('\n' + this.name + ':');
|
||||
},
|
||||
'onCycle': function(event) {
|
||||
console.log(event.target + '');
|
||||
log(event.target + '');
|
||||
},
|
||||
'onComplete': function() {
|
||||
var fastest = this.filter('fastest').pluck('name'),
|
||||
var formatNumber = Benchmark.formatNumber,
|
||||
fastest = this.filter('fastest'),
|
||||
slowest = this.filter('slowest'),
|
||||
lodashHz = 1 / (this[0].stats.mean + this[0].stats.moe),
|
||||
underscoreHz = 1 / (this[1].stats.mean + this[1].stats.moe);
|
||||
|
||||
if (fastest.length > 1) {
|
||||
console.log('It\'s too close to call.');
|
||||
log('It\'s too close to call.');
|
||||
lodashHz = underscoreHz = Math.min(lodashHz, underscoreHz);
|
||||
} else {
|
||||
console.log(fastest + ' is the fastest.');
|
||||
}
|
||||
else {
|
||||
var fastestHz = fastest[0] == this[0] ? lodashHz : underscoreHz,
|
||||
slowestHz = slowest[0] == this[0] ? lodashHz : underscoreHz,
|
||||
percent = ((fastestHz / slowestHz) - 1) * 100;
|
||||
|
||||
log(fastest[0].name + ' is ' + formatNumber(percent < 1 ? percent.toFixed(2) : Math.round(percent)) + '% faster.');
|
||||
}
|
||||
// add score adjusted for margin of error
|
||||
score.lodash += lodashHz;
|
||||
@@ -91,11 +165,17 @@
|
||||
suites[0].run();
|
||||
}
|
||||
else {
|
||||
var fastestTotalHz = Math.max(score.lodash, score.underscore),
|
||||
slowestTotalHz = Math.min(score.lodash, score.underscore),
|
||||
totalPercent = formatNumber(Math.round(((fastestTotalHz / slowestTotalHz) - 1) * 100)),
|
||||
totalX = fastestTotalHz / slowestTotalHz,
|
||||
message = ' is ' + totalPercent + '% ' + (totalX == 1 ? '' : '(' + formatNumber(totalX.toFixed(2)) + 'x) ') + 'faster than ';
|
||||
|
||||
// report results
|
||||
if (score.lodash >= score.underscore) {
|
||||
console.log('\nLo-Dash is ' + (score.lodash / score.underscore).toFixed(2) + 'x faster than Underscore.');
|
||||
log('\nLo-Dash' + message + 'Underscore.');
|
||||
} else {
|
||||
console.log('\nUnderscore is ' + (score.underscore / score.lodash).toFixed(2) + 'x faster than Lo-Dash.');
|
||||
log('\nUnderscore' + message + 'Lo-Dash.');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -103,18 +183,88 @@
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('bind call')
|
||||
.add('Lo-Dash', function() {
|
||||
lodash.bind(func, { 'name': 'moe' }, 'hi');
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
_.bind(func, { 'name': 'moe' }, 'hi');
|
||||
})
|
||||
);
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('bound')
|
||||
.add('Lo-Dash', function() {
|
||||
lodashBoundNormal();
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
_boundNormal();
|
||||
})
|
||||
);
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('bound partial')
|
||||
.add('Lo-Dash', function() {
|
||||
lodashBoundPartial();
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
_boundPartial();
|
||||
})
|
||||
);
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('bound constructor')
|
||||
.add('Lo-Dash', function() {
|
||||
new lodashBoundCtor();
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
new _boundCtor();
|
||||
})
|
||||
);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('each array')
|
||||
.add('Lo-Dash', function() {
|
||||
var timesTwo = [];
|
||||
lodash.each(numbers, function(num) {
|
||||
timesTwo.push(num * 2);
|
||||
var result = [];
|
||||
lodash.each(numbers, function(num) { result.push(num * 2); });
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
var result = [];
|
||||
_.each(numbers, function(num) { result.push(num * 2); });
|
||||
})
|
||||
);
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('each array thisArg (slow path)')
|
||||
.add('Lo-Dash', function() {
|
||||
var result = [];
|
||||
lodash.each(numbers, function(num, index) {
|
||||
result.push(num + this['key' + index]);
|
||||
}, object);
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
var result = [];
|
||||
_.each(numbers, function(num, index) {
|
||||
result.push(num + this['key' + index]);
|
||||
}, object);
|
||||
})
|
||||
);
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('each object')
|
||||
.add('Lo-Dash', function() {
|
||||
var result = [];
|
||||
lodash.each(object, function(num) {
|
||||
result.push(num * 2);
|
||||
});
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
var timesTwo = [];
|
||||
_.each(numbers, function(num) {
|
||||
timesTwo.push(num * 2);
|
||||
var result = [];
|
||||
_.each(object, function(num) {
|
||||
result.push(num * 2);
|
||||
});
|
||||
})
|
||||
);
|
||||
@@ -122,23 +272,111 @@
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('each object')
|
||||
Benchmark.Suite('find')
|
||||
.add('Lo-Dash', function() {
|
||||
var timesTwo = [];
|
||||
lodash.each(object, function(num) {
|
||||
timesTwo.push(num * 2);
|
||||
lodash.find(numbers, function(num) {
|
||||
return num === 19;
|
||||
});
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
var timesTwo = [];
|
||||
_.each(object, function(num) {
|
||||
timesTwo.push(num * 2);
|
||||
_.find(numbers, function(num) {
|
||||
return num === 19;
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('flatten deep')
|
||||
.add('Lo-Dash', function() {
|
||||
lodash.flatten(nestedNumbers);
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
_.flatten(nestedNumbers);
|
||||
})
|
||||
);
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('flatten shallow')
|
||||
.add('Lo-Dash', function() {
|
||||
lodash.flatten(nestedNumbers, true);
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
_.flatten(nestedNumbers, true);
|
||||
})
|
||||
);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('difference')
|
||||
.add('Lo-Dash', function() {
|
||||
lodash.difference(numbers, fourNumbers);
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
_.difference(numbers, fourNumbers);
|
||||
})
|
||||
);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('groupBy callback')
|
||||
.add('Lo-Dash', function() {
|
||||
lodash.groupBy(numbers, function(num) { return num >> 1; });
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
_.groupBy(numbers, function(num) { return num >> 1; });
|
||||
})
|
||||
);
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('groupBy property name')
|
||||
.add('Lo-Dash', function() {
|
||||
lodash.groupBy(words, 'length');
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
_.groupBy(words, 'length');
|
||||
})
|
||||
);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('indexOf')
|
||||
.add('Lo-Dash', function() {
|
||||
lodash.indexOf(numbers, 9);
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
_.indexOf(numbers, 9);
|
||||
})
|
||||
);
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('indexOf isSorted')
|
||||
.add('Lo-Dash', function() {
|
||||
lodash.indexOf(numbers, 19, true);
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
_.indexOf(numbers, 19, true);
|
||||
})
|
||||
);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('intersection')
|
||||
.add('Lo-Dash', function() {
|
||||
lodash.intersection(numbers, fourNumbers, twoNumbers);
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
_.intersection(numbers, fourNumbers, twoNumbers);
|
||||
})
|
||||
);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('keys')
|
||||
.add('Lo-Dash', function() {
|
||||
@@ -151,20 +389,82 @@
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('lastIndexOf')
|
||||
.add('Lo-Dash', function() {
|
||||
lodash.lastIndexOf(numbers, 9);
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
_.lastIndexOf(numbers, 9);
|
||||
})
|
||||
);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('map')
|
||||
.add('Lo-Dash', function() {
|
||||
lodash.map(objects, function(obj) {
|
||||
return obj.num;
|
||||
lodash.map(objects, function(value) {
|
||||
return value.num;
|
||||
});
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
_.map(objects, function(obj) {
|
||||
return obj.num;
|
||||
_.map(objects, function(value) {
|
||||
return value.num;
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('map thisArg (slow path)')
|
||||
.add('Lo-Dash', function() {
|
||||
lodash.map(objects, function(value, index) {
|
||||
return this['key' + index] + value.num;
|
||||
}, object);
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
_.map(objects, function(value, index) {
|
||||
return this['key' + index] + value.num;
|
||||
}, object);
|
||||
})
|
||||
);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('max')
|
||||
.add('Lo-Dash', function() {
|
||||
lodash.max(numbers);
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
_.max(numbers);
|
||||
})
|
||||
);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('min')
|
||||
.add('Lo-Dash', function() {
|
||||
lodash.min(numbers);
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
_.min(numbers);
|
||||
})
|
||||
);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('pick')
|
||||
.add('Lo-Dash', function() {
|
||||
lodash.pick(object, 'key6', 'key13');
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
_.pick(object, 'key6', 'key13');
|
||||
})
|
||||
);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
suites.push(
|
||||
@@ -180,21 +480,156 @@
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('values')
|
||||
Benchmark.Suite('shuffle')
|
||||
.add('Lo-Dash', function() {
|
||||
lodash.values(objects);
|
||||
lodash.shuffle(numbers);
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
_.values(objects);
|
||||
_.shuffle(numbers);
|
||||
})
|
||||
);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('sortBy callback')
|
||||
.add('Lo-Dash', function() {
|
||||
lodash.sortBy(numbers, function(num) { return Math.sin(num); });
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
_.sortBy(numbers, function(num) { return Math.sin(num); });
|
||||
})
|
||||
);
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('sortBy callback thisArg (slow path)')
|
||||
.add('Lo-Dash', function() {
|
||||
lodash.sortBy(numbers, function(num) { return this.sin(num); }, Math);
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
_.sortBy(numbers, function(num) { return this.sin(num); }, Math);
|
||||
})
|
||||
);
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('sortBy property name')
|
||||
.add('Lo-Dash', function() {
|
||||
lodash.sortBy(words, 'length');
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
_.sortBy(words, 'length');
|
||||
})
|
||||
);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('sortedIndex')
|
||||
.add('Lo-Dash', function() {
|
||||
lodash.sortedIndex(numbers, 25);
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
_.sortedIndex(numbers, 25);
|
||||
})
|
||||
);
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('sortedIndex callback')
|
||||
.add('Lo-Dash', function() {
|
||||
lodash.sortedIndex(words, 'twenty-five', function(value) {
|
||||
return wordToNumber[value];
|
||||
});
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
_.sortedIndex(words, 'twenty-five', function(value) {
|
||||
return wordToNumber[value];
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('times')
|
||||
.add('Lo-Dash', function() {
|
||||
var result = [];
|
||||
lodash.times(length, function(n) { result.push(n); });
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
var result = [];
|
||||
_.times(length, function(n) { result.push(n); });
|
||||
})
|
||||
);
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('times thisArg')
|
||||
.add('Lo-Dash', function() {
|
||||
var result = [];
|
||||
lodash.times(length, function(n) { result.push(this.sin(n)); }, Math);
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
var result = [];
|
||||
_.times(length, function(n) { result.push(this.sin(n)); }, Math);
|
||||
})
|
||||
);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('union')
|
||||
.add('Lo-Dash', function() {
|
||||
lodash.union(numbers, fourNumbers, twoNumbers);
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
_.union(numbers, fourNumbers, twoNumbers);
|
||||
})
|
||||
);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('uniq')
|
||||
.add('Lo-Dash', function() {
|
||||
lodash.uniq(numbers.concat(fourNumbers, twoNumbers));
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
_.uniq(numbers.concat(fourNumbers, twoNumbers));
|
||||
})
|
||||
);
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('uniq callback')
|
||||
.add('Lo-Dash', function() {
|
||||
lodash.uniq(numbers.concat(fourNumbers, twoNumbers), function(num) {
|
||||
return num % 2;
|
||||
});
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
_.uniq(numbers.concat(fourNumbers, twoNumbers), function(num) {
|
||||
return num % 2;
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
suites.push(
|
||||
Benchmark.Suite('values')
|
||||
.add('Lo-Dash', function() {
|
||||
lodash.values(object);
|
||||
})
|
||||
.add('Underscore', function() {
|
||||
_.values(object);
|
||||
})
|
||||
);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
if (Benchmark.platform + '') {
|
||||
console.log(Benchmark.platform + '');
|
||||
log(Benchmark.platform + '');
|
||||
}
|
||||
// start suites
|
||||
log('\nSit back and relax, this may take a while.');
|
||||
suites[0].run();
|
||||
|
||||
}(typeof global == 'object' && global || this));
|
||||
|
||||
@@ -34,6 +34,5 @@
|
||||
<script src="../vendor/backbone/test/router.js"></script>
|
||||
<script src="../vendor/backbone/test/view.js"></script>
|
||||
<script src="../vendor/backbone/test/sync.js"></script>
|
||||
<script src="../vendor/backbone/test/setdomlibrary.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
425
test/test.js
425
test/test.js
@@ -37,6 +37,17 @@
|
||||
'valueOf': 7
|
||||
};
|
||||
|
||||
/** Used to check problem JScript properties too */
|
||||
var shadowedKeys = [
|
||||
'constructor',
|
||||
'hasOwnProperty',
|
||||
'isPrototypeOf',
|
||||
'propertyIsEnumerable',
|
||||
'toLocaleString',
|
||||
'toString',
|
||||
'valueOf'
|
||||
];
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
@@ -92,7 +103,7 @@
|
||||
ok(_() instanceof _);
|
||||
});
|
||||
|
||||
test('should pass through LoDash instances', function() {
|
||||
test('should return passed LoDash instances', function() {
|
||||
var wrapped = _([]);
|
||||
equal(_(wrapped), wrapped);
|
||||
});
|
||||
@@ -142,6 +153,15 @@
|
||||
test('should not escape the ">" character', function() {
|
||||
equal(_.escape('>'), '>');
|
||||
});
|
||||
|
||||
test('should not escape the "/" character', function() {
|
||||
equal(_.escape('/'), '/');
|
||||
});
|
||||
|
||||
test('should return empty string when passed `null` or `undefined`', function() {
|
||||
equal(_.escape(null), '');
|
||||
equal(_.escape(undefined), '');
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -174,26 +194,120 @@
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.find');
|
||||
|
||||
(function() {
|
||||
var array = [1, 2, 3];
|
||||
|
||||
test('should return found `value`', function() {
|
||||
equal(_.find(array, function(n) { return n > 2; }), 3);
|
||||
});
|
||||
|
||||
test('should return `undefined` if `value` is not found', function() {
|
||||
equal(_.find(array, function(n) { return n == 4; }), undefined);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.flatten');
|
||||
|
||||
(function() {
|
||||
test('should treat sparse arrays as dense', function() {
|
||||
var array = [[1, 2, 3], Array(3)],
|
||||
expected = [1, 2, 3],
|
||||
actual1 = _.flatten(array),
|
||||
actual2 = _.flatten(array, true);
|
||||
|
||||
expected.push(undefined, undefined, undefined);
|
||||
|
||||
deepEqual(actual1, expected);
|
||||
ok('4' in actual1);
|
||||
|
||||
deepEqual(actual2, expected);
|
||||
ok('4' in actual2);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.forEach');
|
||||
|
||||
(function() {
|
||||
test('returns the collection', function() {
|
||||
var collection = [1, 2, 3, 4];
|
||||
var collection = [1, 2, 3];
|
||||
equal(_.forEach(collection, Boolean), collection);
|
||||
});
|
||||
|
||||
test('fixes the JScript [[DontEnum]] bug (test in IE < 9)', function() {
|
||||
var object = {};
|
||||
_.forEach(shadowed, function(value, key) {
|
||||
object[key] = value;
|
||||
});
|
||||
test('should treat array-like object with invalid `length` as a regular object', function() {
|
||||
var keys = [],
|
||||
object = { 'length': -1 };
|
||||
|
||||
deepEqual(object, shadowed);
|
||||
_.forEach(object, function(value, key) { keys.push(key); });
|
||||
deepEqual(keys, ['length']);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.forIn');
|
||||
|
||||
(function() {
|
||||
test('iterates over inherited properties', function() {
|
||||
function Dog(name) { this.name = name; }
|
||||
Dog.prototype.bark = function() { /* Woof, woof! */ };
|
||||
|
||||
var keys = [];
|
||||
_.forIn(new Dog('Dagny'), function(value, key) { keys.push(key); });
|
||||
deepEqual(keys.sort(), ['bark', 'name']);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.forOwn');
|
||||
|
||||
(function() {
|
||||
test('iterates over the `length` property', function() {
|
||||
var keys = [],
|
||||
object = { '0': 'zero', '1': 'one', 'length': 2 };
|
||||
|
||||
_.forOwn(object, function(value, key) { keys.push(key); });
|
||||
deepEqual(keys.sort(), ['0', '1', 'length']);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
_.each(['forEach', 'forIn', 'forOwn'], function(methodName) {
|
||||
var func = _[methodName];
|
||||
QUnit.module('lodash.' + methodName + ' iteration bugs');
|
||||
|
||||
test('fixes the JScript [[DontEnum]] bug (test in IE < 9)', function() {
|
||||
var keys = [];
|
||||
func(shadowed, function(value, key) { keys.push(key); });
|
||||
deepEqual(keys.sort(), shadowedKeys);
|
||||
});
|
||||
|
||||
test('skips the prototype property of functions (test in Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1)', function() {
|
||||
function Foo() {}
|
||||
Foo.prototype.a = 1;
|
||||
|
||||
var keys = [];
|
||||
function callback(value, key) { keys.push(key); }
|
||||
|
||||
func(Foo, callback);
|
||||
deepEqual(keys, []);
|
||||
keys.length = 0;
|
||||
|
||||
Foo.prototype = { 'a': 1 };
|
||||
func(Foo, callback);
|
||||
deepEqual(keys, []);
|
||||
});
|
||||
});
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.groupBy');
|
||||
|
||||
(function() {
|
||||
@@ -204,6 +318,51 @@
|
||||
|
||||
deepEqual(actual, { '1': [1.3], '2': [2.1, 2.4] });
|
||||
});
|
||||
|
||||
test('should only add elements to own, not inherited, properties', function() {
|
||||
var actual = _.groupBy([1.3, 2.1, 2.4], function(num) {
|
||||
return Math.floor(num) > 1 ? 'hasOwnProperty' : 'constructor';
|
||||
});
|
||||
|
||||
deepEqual(actual.constructor, [1.3]);
|
||||
deepEqual(actual.hasOwnProperty, [2.1, 2.4]);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.indexOf');
|
||||
|
||||
(function() {
|
||||
var array = [1, 2, 3, 1, 2, 3];
|
||||
|
||||
test('should work with a positive `fromIndex`', function() {
|
||||
equal(_.indexOf(array, 1, 2), 3);
|
||||
});
|
||||
|
||||
test('should work with `fromIndex` >= `array.length`', function() {
|
||||
equal(_.indexOf(array, 1, 6), -1);
|
||||
equal(_.indexOf(array, undefined, 6), -1);
|
||||
equal(_.indexOf(array, 1, 8), -1);
|
||||
equal(_.indexOf(array, undefined, 8), -1);
|
||||
});
|
||||
|
||||
test('should work with a negative `fromIndex`', function() {
|
||||
equal(_.indexOf(array, 2, -3), 4);
|
||||
});
|
||||
|
||||
test('should work with a negative `fromIndex` <= `-array.length`', function() {
|
||||
equal(_.indexOf(array, 1, -6), 0);
|
||||
equal(_.indexOf(array, 2, -8), 1);
|
||||
});
|
||||
|
||||
test('should ignore non-number `fromIndex` values', function() {
|
||||
equal(_.indexOf([1, 2, 3], 1, '1'), 0);
|
||||
});
|
||||
|
||||
test('should work with `isSorted`', function() {
|
||||
equal(_.indexOf([1, 2, 3], 1, true), 0);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -212,19 +371,39 @@
|
||||
|
||||
(function() {
|
||||
test('returns an empty collection for `n` of `0`', function() {
|
||||
var array = [1, 2, 3, 4];
|
||||
var array = [1, 2, 3];
|
||||
deepEqual(_.initial(array, 0), []);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.invoke');
|
||||
|
||||
(function() {
|
||||
test('should work with an object for `collection`', function() {
|
||||
var object = { 'a': 1, 'b': 2, 'c': 3 };
|
||||
deepEqual(_.invoke(object, 'toFixed', 1), ['1.0', '2.0', '3.0']);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.isEmpty');
|
||||
|
||||
(function() {
|
||||
test('fixes the JScript [[DontEnum]] bug (test in IE < 9)', function() {
|
||||
equal(_.isEmpty(shadowed), false);
|
||||
});
|
||||
|
||||
test('skips the prototype property of functions (test in Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1)', function() {
|
||||
function Foo() {}
|
||||
Foo.prototype.a = 1;
|
||||
equal(_.isEmpty(Foo), true);
|
||||
|
||||
Foo.prototype = { 'a': 1 };
|
||||
equal(_.isEmpty(Foo), true);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -257,30 +436,54 @@
|
||||
Foo.prototype.a = 1;
|
||||
|
||||
deepEqual(_.keys(Foo.prototype), ['a']);
|
||||
deepEqual(_.keys(shadowed).sort(),
|
||||
'constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf'.split(' '));
|
||||
deepEqual(_.keys(shadowed).sort(), shadowedKeys);
|
||||
});
|
||||
|
||||
test('skips the prototype property of functions (test in Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1)', function() {
|
||||
function Foo() {}
|
||||
Foo.prototype.c = 3;
|
||||
|
||||
Foo.a = 1;
|
||||
Foo.b = 2;
|
||||
|
||||
var expected = ['a', 'b'];
|
||||
deepEqual(_.keys(Foo), expected);
|
||||
|
||||
Foo.prototype = { 'c': 3 };
|
||||
deepEqual(_.keys(Foo), expected);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.lastIndexOf');
|
||||
|
||||
(function() {
|
||||
var i = -1,
|
||||
largeArray = [];
|
||||
var array = [1, 2, 3, 1, 2, 3];
|
||||
|
||||
while (++i <= 1e6) {
|
||||
largeArray[i] = i;
|
||||
}
|
||||
_.each(['max', 'min'], function(methodName) {
|
||||
QUnit.module('lodash.' + methodName);
|
||||
test('should work with a positive `fromIndex`', function() {
|
||||
equal(_.lastIndexOf(array, 1, 2), 0);
|
||||
});
|
||||
|
||||
test('does not error when computing the ' + methodName + ' value of massive arrays', function() {
|
||||
try {
|
||||
var actual = _[methodName](largeArray);
|
||||
} catch(e) { }
|
||||
test('should work with `fromIndex` >= `array.length`', function() {
|
||||
equal(_.lastIndexOf(array, undefined, 6), -1);
|
||||
equal(_.lastIndexOf(array, 1, 6), 3);
|
||||
equal(_.lastIndexOf(array, undefined, 8), -1);
|
||||
equal(_.lastIndexOf(array, 1, 8), 3);
|
||||
});
|
||||
|
||||
equal(actual, methodName == 'max' ? 1e6 : 0);
|
||||
});
|
||||
test('should work with a negative `fromIndex`', function() {
|
||||
equal(_.lastIndexOf(array, 2, -3), 1);
|
||||
});
|
||||
|
||||
test('should work with a negative `fromIndex` <= `-array.length`', function() {
|
||||
equal(_.lastIndexOf(array, 1, -6), 0);
|
||||
equal(_.lastIndexOf(array, 2, -8), -1);
|
||||
});
|
||||
|
||||
test('should ignore non-number `fromIndex` values', function() {
|
||||
equal(_.lastIndexOf([1, 2, 3], 3, '1'), 2);
|
||||
equal(_.lastIndexOf([1, 2, 3], 3, true), 2);
|
||||
});
|
||||
}());
|
||||
|
||||
@@ -328,6 +531,17 @@
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.pluck');
|
||||
|
||||
(function() {
|
||||
test('should work with an object for `collection`', function() {
|
||||
var object = { 'a': [1], 'b': [1, 2], 'c': [1, 2, 3] };
|
||||
deepEqual(_.pluck(object, 'length'), [1, 2, 3]);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.reduceRight');
|
||||
|
||||
(function() {
|
||||
@@ -342,6 +556,17 @@
|
||||
|
||||
deepEqual(args, ['C', 'B', 'b', object]);
|
||||
});
|
||||
|
||||
test('should treat array-like object with invalid `length` as a regular object', function() {
|
||||
var args,
|
||||
object = { 'a': 'A', 'length': -1 };
|
||||
|
||||
_.reduceRight(object, function() {
|
||||
args || (args = slice.call(arguments));
|
||||
});
|
||||
|
||||
deepEqual(args, [-1, 'A', 'a', object]);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -364,11 +589,36 @@
|
||||
|
||||
(function() {
|
||||
test('supports the `thisArg` argument', function() {
|
||||
var actual = _.sortBy([1, 2, 3, 4], function(num) {
|
||||
var actual = _.sortBy([1, 2, 3], function(num) {
|
||||
return this.sin(num);
|
||||
}, Math);
|
||||
|
||||
deepEqual(actual, [4, 3, 1, 2]);
|
||||
deepEqual(actual, [3, 1, 2]);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.sortedIndex');
|
||||
|
||||
(function() {
|
||||
test('supports the `thisArg` argument', function() {
|
||||
var actual = _.sortedIndex([1, 2, 3], 4, function(num) {
|
||||
return this.sin(num);
|
||||
}, Math);
|
||||
|
||||
equal(actual, 0);
|
||||
});
|
||||
|
||||
test('supports arrays with lengths larger than `Math.pow(2, 31) - 1`', function() {
|
||||
var length = Math.pow(2, 32) - 1,
|
||||
index = length - 1,
|
||||
array = Array(length),
|
||||
steps = 0;
|
||||
|
||||
array[index] = index;
|
||||
_.sortedIndex(array, index, function() { steps++; });
|
||||
equal(steps, 33);
|
||||
});
|
||||
}());
|
||||
|
||||
@@ -378,7 +628,7 @@
|
||||
|
||||
(function() {
|
||||
test('supports recursive calls', function() {
|
||||
var compiled = _.template('<%= a %><% a = _.template(c, object) %><%= a %>'),
|
||||
var compiled = _.template('<%= a %><% a = _.template(c, obj) %><%= a %>'),
|
||||
data = { 'a': 'A', 'b': 'B', 'c': '<%= b %>' };
|
||||
|
||||
equal(compiled(data), 'AB');
|
||||
@@ -412,7 +662,24 @@
|
||||
while ((new Date - start) < limit) {
|
||||
throttled();
|
||||
}
|
||||
equal(counter, 3);
|
||||
ok(counter > 1);
|
||||
});
|
||||
|
||||
asyncTest('supports recursive calls', function() {
|
||||
var counter = 0;
|
||||
var throttled = _.throttle(function() {
|
||||
counter++;
|
||||
if (counter < 4) {
|
||||
throttled();
|
||||
}
|
||||
}, 100);
|
||||
|
||||
setTimeout(function() {
|
||||
ok(counter > 1);
|
||||
QUnit.start();
|
||||
}, 220);
|
||||
|
||||
throttled();
|
||||
});
|
||||
}());
|
||||
|
||||
@@ -429,15 +696,34 @@
|
||||
deepEqual(_.toArray(array), [3, 2, 1]);
|
||||
});
|
||||
|
||||
test('should treat array-like-objects like arrays', function() {
|
||||
test('should treat array-like objects like arrays', function() {
|
||||
var object = { '0': 'a', '1': 'b', '2': 'c', 'length': 3 };
|
||||
deepEqual(_.toArray(object), ['a', 'b', 'c']);
|
||||
deepEqual(_.toArray(args), [1, 2, 3]);
|
||||
});
|
||||
|
||||
test('should treat array-like object with invalid `length` as a regular object', function() {
|
||||
var object = { 'length': -1 };
|
||||
deepEqual(_.toArray(object), [-1]);
|
||||
});
|
||||
}(1, 2, 3));
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash.uniq');
|
||||
|
||||
(function() {
|
||||
test('supports the `thisArg` argument', function() {
|
||||
var actual = _.uniq([1, 2, 1.5, 3, 2.5], function(num) {
|
||||
return this.floor(num);
|
||||
}, Math);
|
||||
|
||||
deepEqual(actual, [1, 2, 3]);
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash(...).shift');
|
||||
|
||||
(function() {
|
||||
@@ -466,7 +752,84 @@
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
// explicitly call `QUnit.start()` for Narwhal, Rhino, and RingoJS
|
||||
QUnit.start();
|
||||
QUnit.module('lodash "Arrays" methods');
|
||||
|
||||
(function() {
|
||||
test('should allow a falsey `array` argument', function() {
|
||||
_.each([
|
||||
'compact',
|
||||
'difference',
|
||||
'first',
|
||||
'flatten',
|
||||
'groupBy',
|
||||
'indexOf',
|
||||
'initial',
|
||||
'intersection',
|
||||
'last',
|
||||
'lastIndexOf',
|
||||
'max',
|
||||
'min',
|
||||
'range',
|
||||
'rest',
|
||||
'shuffle',
|
||||
'sortBy',
|
||||
'sortedIndex',
|
||||
'union',
|
||||
'uniq',
|
||||
'without',
|
||||
'zip'
|
||||
], function(methodName) {
|
||||
var pass = true;
|
||||
try {
|
||||
_[methodName]();
|
||||
} catch(e) {
|
||||
pass = false;
|
||||
}
|
||||
ok(pass, methodName + ' allows a falsey `array` argument');
|
||||
});
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
QUnit.module('lodash "Collections" methods');
|
||||
|
||||
(function() {
|
||||
test('should allow a falsey `collection` argument', function() {
|
||||
_.each([
|
||||
'contains',
|
||||
'every',
|
||||
'filter',
|
||||
'find',
|
||||
'forEach',
|
||||
'invoke',
|
||||
'map',
|
||||
'pluck',
|
||||
'reduce',
|
||||
'reduceRight',
|
||||
'reject',
|
||||
'some',
|
||||
'toArray'
|
||||
], function(methodName) {
|
||||
var pass = true;
|
||||
try {
|
||||
if (/^(?:contains|toArray)$/.test(methodName)) {
|
||||
_[methodName](null);
|
||||
} else {
|
||||
_[methodName](null, _.identity);
|
||||
}
|
||||
} catch(e) {
|
||||
pass = false;
|
||||
}
|
||||
ok(pass, methodName + ' allows a falsey `collection` argument');
|
||||
});
|
||||
});
|
||||
}());
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
// explicitly call `QUnit.start()` for Narwhal, Rhino, and RingoJS
|
||||
if (!window.document) {
|
||||
QUnit.start();
|
||||
}
|
||||
}(typeof global == 'object' && global || this));
|
||||
|
||||
2
vendor/backbone
vendored
2
vendor/backbone
vendored
Submodule vendor/backbone updated: e34e14c466...d4d7fb97a5
2
vendor/benchmark.js
vendored
2
vendor/benchmark.js
vendored
Submodule vendor/benchmark.js updated: 5ff44811ef...ccf5dba9d1
2
vendor/docdown
vendored
2
vendor/docdown
vendored
Submodule vendor/docdown updated: 5448a5837d...87466c279a
2
vendor/qunit
vendored
2
vendor/qunit
vendored
Submodule vendor/qunit updated: 3f5e8b2123...0d596a809d
2
vendor/qunit-clib
vendored
2
vendor/qunit-clib
vendored
Submodule vendor/qunit-clib updated: 2ed9f21633...8b294472e6
2
vendor/requirejs
vendored
2
vendor/requirejs
vendored
Submodule vendor/requirejs updated: 07de481552...42dba3d981
2
vendor/uglifyjs
vendored
2
vendor/uglifyjs
vendored
Submodule vendor/uglifyjs updated: ef4d776aed...a3fcb0d2aa
2
vendor/underscore
vendored
2
vendor/underscore
vendored
Submodule vendor/underscore updated: a4414cede6...91a841a0a9
Reference in New Issue
Block a user