Compare commits

..

725 Commits

Author SHA1 Message Date
John-David Dalton
54b862bd79 Bump to v1.0.0-rc.2.
Former-commit-id: 55bca6a70e127152329deeff509a72a73436f40e
2012-12-05 02:24:46 -08:00
John-David Dalton
e37e1c109a Tweak method's chaining behavior.
Former-commit-id: 3bfdd8d004fbdcb839843748b907cad5a5003446
2012-12-05 01:37:28 -08:00
John-David Dalton
939123785b Specify more method's chaining behavior.
Former-commit-id: 7b8c18f6058bb279ab25f7e8b94e7418951e3ded
2012-12-05 01:36:18 -08:00
John-David Dalton
221b347bd9 Update vendor/underscore to v1.4.3 and update the Underscore build compatibility.
Former-commit-id: ebcaad4a92848bef3bbf65bb8eb3a0c1553e005c
2012-12-05 01:03:10 -08:00
John-David Dalton
af9bf3e852 Cleanup comments/docs/descriptions. [ci skip]
Former-commit-id: 4d6a0a54abbaa6607cc5897a09e5a7c0fc884a1a
2012-12-04 09:14:59 -08:00
John-David Dalton
ed8746df77 Rebuild update vendors, minified files, and adjust README.md changelog.
Former-commit-id: a01567b3d8e88da0cb20e12c864703e633b86fc6
2012-12-04 01:29:24 -08:00
John-David Dalton
bb187db49d Tweak _.throttle unit test and add _.bind test.
Former-commit-id: b863194c661d97177bbcda9676699e9753f0db22
2012-12-03 22:37:09 -08:00
John-David Dalton
081e72b3ea Fix typo in _.clone documentation. [closes #130]
Former-commit-id: 81e17c992848c5d0ac9d30fb64eef3163bac6598
2012-12-03 22:10:08 -08:00
John-David Dalton
6188c38053 Move bound inheritance hookup inside bound.
Former-commit-id: 7f95fffa14ef42f8f065aad124ac883740baac64
2012-12-03 22:07:45 -08:00
John-David Dalton
12b0186f5a Make _.isEqual work with arguments objects in older versions of Opera.
Former-commit-id: 860a27e7f81e14781eb371cadf24bb812eb31718
2012-12-03 01:54:46 -08:00
John-David Dalton
9bccc9c53c Ensured _.throttle nulls the timeoutId. [closes #129]
Former-commit-id: 24242f513e01adb2827cc3a5af6c8904098a9280
2012-12-03 01:04:54 -08:00
John-David Dalton
351b2b320e Bump to version 1.0.0-rc.1.
Former-commit-id: 8867f4ddfab62435d0c2c685d67e68555d146545
2012-12-02 22:09:56 -08:00
John-David Dalton
94258feb09 Make _#bind return non-wrapped values and cleanup a _.template unit test.
Former-commit-id: 351e4ae8b346a69a795c6d2bfe6a55b306515af6
2012-12-02 21:19:34 -08:00
John-David Dalton
8b0f033a78 Update vendor/underscore.
Former-commit-id: 8bb0b59d367ab2600a85a4442789eb41d9d97cb6
2012-12-02 21:18:46 -08:00
John-David Dalton
f58f255fc8 Make the custom build message work with -rc.1 and fix build.
Former-commit-id: 96f31fff906fa978a0d10fad90d9322c761e1d26
2012-12-02 02:21:55 -08:00
John-David Dalton
e3eabcf648 Fix isBindFast and isKeysFast.
Former-commit-id: 59e6cfa0669f28139a7036a172995d7f7f8a64ef
2012-12-02 00:01:29 -08:00
John-David Dalton
9aa506cbd7 Cleanup build.js.
Former-commit-id: 91bb957cef2efd3aefd3c196374841efbd3ffd1d
2012-12-01 23:32:26 -08:00
John-David Dalton
d8cff7b90f Remove script injection and simplify createFunction.
Former-commit-id: cc466c8ea05210b2238ee72a624628c7454eb1ee
2012-12-01 23:32:02 -08:00
John-David Dalton
07e7bca9eb Merge branch 'master' of github.com:bestiejs/lodash
Former-commit-id: a1f2773afba4c885385e601e656c6ee461a6fb24
2012-12-01 18:49:46 -08:00
John-David Dalton
e1f442be90 Ensure Lo-Dash works in the JS engine embedded in Adobe products.
Former-commit-id: 860665d3735aef1dff75149b49b78c1615f38fa0
2012-12-01 18:47:38 -08:00
John-David Dalton
c5d579e0e3 Update vendors, minified files, and docs.
Former-commit-id: b29e9f8a497153408ba6266bf44412004e63c1af
2012-12-01 17:16:50 -08:00
John-David Dalton
5271c2e08f Update vendors, minified files, and docs.
Former-commit-id: 018dfcade1386aa84492f60c8404ea00c01cbe11
2012-12-01 13:24:40 -08:00
John-David Dalton
9010a7ddbc Fix typo in _.toArray and tweak _.forEach documentation.
Former-commit-id: 6417e50be9381a4ecede54868a9c2c41dabca4f2
2012-12-01 13:23:15 -08:00
John-David Dalton
bb95fb7d07 Reduce _.pluck.
Former-commit-id: 91db56f95d258070a0d25e4e4b74917e52b8cefe
2012-12-01 10:47:00 -08:00
John-David Dalton
2edb11376d Avoid script injection unless the JS engine is inferred to be Firefox's.
Former-commit-id: 1e267374fe85a858197609b35b85670394c0b66d
2012-12-01 01:08:38 -08:00
John-David Dalton
e7f5ebf912 Rebuild minified files and docs.
Former-commit-id: 18a7f085459a08c6440be3e14d3f663fa181032d
2012-11-30 23:17:00 -08:00
John-David Dalton
da9758c2f3 Ensure bound result of _.bind(func, …) is an instance of bound and func.
Former-commit-id: d8176ad5eb45a3d675617676fc1eee4d9cbd6ebc
2012-11-30 23:16:39 -08:00
John-David Dalton
3e11d58d73 Ensure _.toArray returns a dence array.
Former-commit-id: 534091d4d200208b8aa831d86801d5e9d73410fe
2012-11-30 22:51:15 -08:00
John-David Dalton
6b35c097d6 Make deep _.clone copy array properties assigned by RegExp#exec.
Former-commit-id: b465457babfc04e8204048dfaeff6e5d37e5e43c
2012-11-30 00:40:32 -08:00
John-David Dalton
619ba13265 Make _.uniqueId consistently return a string value.
Former-commit-id: 5a5c626df83b0fc78e9bae37510680383f112c0b
2012-11-29 22:38:15 -08:00
John-David Dalton
529c5b8abf Use forIn in _.isEqual instead of forOwn.
Former-commit-id: dd057e421be029d67cd293b733ee1cfee2b7715f
2012-11-29 20:57:13 -08:00
John-David Dalton
3a5ed6e800 Ensure revised _.isEqual works correctly in Underscore build.
Former-commit-id: 24c01405f08f8925bfe473d5d7e9ad0a270382b6
2012-11-29 08:54:33 -08:00
John-David Dalton
52cddc015b Make _.clone follow the structured cloning algorithm's behavior for cloning objects created by constructors other than Object and make _.isEqual equate objects to arguments objects.
Former-commit-id: a387c6444694d8d550ab463ea5290088d3356d8b
2012-11-29 02:04:16 -08:00
John-David Dalton
4a01f4f65f Update vendor/underscore.js
Former-commit-id: d74b9331b5547cfde6c04bd1b915e983187b2ec0
2012-11-27 19:25:55 -08:00
John-David Dalton
f9768cb5a3 Use typeof x == 'undefined' checks instead of x === undefined for consistency with other typeof checks.
Former-commit-id: 8ab7d3efe54aa7017b52295b0598b75c297a6277
2012-11-26 09:24:51 -06:00
John-David Dalton
221e0e550c Optimize _.forEach, _.forIn, and _.forOwn.
Former-commit-id: 5d3b83ec0d5240ee14a86421994de86f311089fd
2012-11-24 23:21:30 -06:00
John-David Dalton
d2d1d42d0f Optimize _.isNumber and _.isString. [closes #126]
Former-commit-id: 633dfe2e9c2c0ff7e54d5bbb4bf95f9adcca83c4
2012-11-24 09:46:20 -06:00
John-David Dalton
faf018a097 Rebuild minified files and docs.
Former-commit-id: b3e87e12dfa55dcaa813d31b2ef0749a83b652aa
2012-11-24 01:49:56 -06:00
John-David Dalton
a2a71a107e Fix onerror typo.
Former-commit-id: 61ba70537963824f396496cc59e7cfac1e9f8c8a
2012-11-24 01:36:18 -06:00
John-David Dalton
fc9c937e67 Simplify iteratorTemplate and support for minifying double quoted strings in source.
Former-commit-id: d18cbd6dc380001fe3617f6891c84a794a13c8d1
2012-11-24 01:34:00 -06:00
John-David Dalton
b4f2e9b442 Fix build.
Former-commit-id: dba1a3fa7526001d0062dc6e0b44f3c6e3d3d8db
2012-11-23 13:26:12 -06:00
John-David Dalton
1672645e73 Avoid engine slow path for primitives in _(…). [closes #123]
Former-commit-id: 32e33b0c0d192915e6d5a83001b85645829ca0ab
2012-11-23 10:19:10 -06:00
John-David Dalton
4a42c44101 Use createFunction in _.template.
Former-commit-id: c996d94c7002bf4a89092b9cf7f4e5e80f70d9fd
2012-11-23 10:05:15 -06:00
John-David Dalton
383b1a5769 Avoid Firefox's unoptimized Function constructor.
Former-commit-id: 7cc5fc63c0cebd1410edde47c88e580c64fa2b98
2012-11-23 01:14:44 -06:00
John-David Dalton
77bac4cf9e Narrow the scope of regexes used in build.js to the functions they relate to.
Former-commit-id: 6d838b24778d5e2107f4f5b25613ae40f363e969
2012-11-20 16:20:06 -06:00
John-David Dalton
e2b8e530c9 Merge pull request #119 from bestiejs/no-chain
Make `_(...)` wrapped values chainable without the need to call `chain`

Former-commit-id: 2e133540c0bedb41440bab592f1bacb75d426687
2012-11-20 07:52:11 -08:00
John-David Dalton
e9f752bd67 Merge /master into /no-chain
Former-commit-id: 59e5a4b13eb8bddd39bd37d917344715d62bf385
2012-11-20 07:47:48 -08:00
John-David Dalton
4b31921eb4 Rebuild minified files and docs.
Former-commit-id: 9565bb8c27577b72cf42d79cc7a1569a496d8bdc
2012-11-20 07:44:25 -08:00
John-David Dalton
3df9fc6225 Ensure _.reduce and _.reduceRight pass the correct number of callback arguments.
Former-commit-id: fec2d28b5a69ceb590e0ef1d8a0792b25b53c7e9
2012-11-20 07:43:09 -08:00
John-David Dalton
b57fe466ce Make _(…) wrapper versions of _.first and _.last capable of returning wrapped and unwrapped values.
Former-commit-id: b30704c1ce359213aa09069b290ee55edfb3e33e
2012-11-20 07:32:51 -08:00
John-David Dalton
bd4bff3b6b Add lodash.prototype methods that return non-wrapped values.
Former-commit-id: b7ecb8c91ec9647827a80a297b966639c6580ef0
2012-11-19 23:02:35 -08:00
John-David Dalton
9d4618a223 Merge /master into /no-chain
Former-commit-id: fcef4ca54be1907762e92ee528b650bea9759c1d
2012-11-19 21:52:25 -08:00
John-David Dalton
93636180df Fallback to the local npm install if there are problems resolving the npm -g root path. [closes #122]
Former-commit-id: 1cbf807877e51198853950e5ebd1b49a6e20d123
2012-11-19 21:42:54 -08:00
John-David Dalton
fcceaa168f Update v0.10.0 changelog in README.md.
Former-commit-id: daf4501ee97420d93bb02d7c1dfd5498d6618bb9
2012-11-19 21:12:57 -08:00
John-David Dalton
2639cc6138 Update vendors.
Former-commit-id: e109c9ffd436610d066493b07bd38293e1ec01a7
2012-11-19 20:54:23 -08:00
John-David Dalton
4a99c2e928 Add support for NodeLists in _.toArray for IE < 9.
Former-commit-id: 67b26fe6fe60d77c0b38c48865bfd2ca56f7b470
2012-11-19 20:47:16 -08:00
John-David Dalton
7d5af3df05 Remove deprecated indicators from _.isFinite, _.isNaN, _.isNull, _.isUndefined, and _.result docs. [ci skip]
Former-commit-id: 39a6e1a4a948469993afb90c6303f1f6faa661fd
2012-11-18 22:37:47 -08:00
John-David Dalton
c88b80d2a0 Add documentation note to _#chain. [ci skip]
Former-commit-id: 90b50a50b6b104cd9e2bbccc4412346dfd6a6bba
2012-11-18 22:35:23 -08:00
John-David Dalton
819d4abaa2 Add _#toString and _#valueOf.
Former-commit-id: adb194b6270fc72f794c69343891a2e891b90051
2012-11-18 21:50:41 -08:00
John-David Dalton
20630aeb47 Remove the need to call chain on _(…) wrapped values.
Former-commit-id: 21861c88e3ec9af955d844c025b50cb32c322809
2012-11-18 21:06:24 -08:00
John-David Dalton
0c0db3babb Remove deprecated indicators from _.isFinite, _.isNaN, _.isNull, _.isUndefined, and _.result docs. [ci skip]
Former-commit-id: 597001cfe5ef71d40b3254344eb5dbbe9905430a
2012-11-18 15:41:07 -08:00
John-David Dalton
e7761f7e57 Minor cleanup to README.md.
Former-commit-id: a4ded5a5b2f41016fad5e4c7491dd96704e9d69a
2012-11-18 14:38:04 -08:00
John-David Dalton
064fd497ae Bump version to v0.10.0 in package.json.
Former-commit-id: 0be4f584b19bc6d53bd6bce61e8ac3cc249f2003
2012-11-18 13:39:43 -08:00
John-David Dalton
49c60b6b75 Add link to ES6 draft spec for Object.assign and add more notes to the v0.10.0 changelog to README.md.
Former-commit-id: c0f5d00e506f6b4a03d0844e7cc8379d462f9fff
2012-11-18 13:31:50 -08:00
John-David Dalton
ca7f36506c Update vendors.
Former-commit-id: cdd10877e964b62eb73747fbaec5f7eda6ace599
2012-11-18 00:00:51 -08:00
John-David Dalton
155f0a9736 Bump to v0.10.0.
Former-commit-id: fd251fd13dfda3120569d3d284aa55ded0b806af
2012-11-17 23:48:57 -08:00
John-David Dalton
25e1eb3ce9 Rename _.lateBind to _.bindKey. [closes #114]
Former-commit-id: 971e56cb86b5298ba2a9f92365f0463665d27230
2012-11-17 00:06:55 -08:00
John-David Dalton
f2f980928b Update vendors to replace CRLF with LF.
Former-commit-id: 65f8982b6cfe965808ef97acba49c4d1cef6cd18
2012-11-16 22:09:41 -08:00
John-David Dalton
1d121a97a7 Convert resolve real paths of npm -g root. [closes #116]
Former-commit-id: 0379fdf33da465fbb9ac78ddaa9e820b9b3e9987
2012-11-16 21:59:36 -08:00
John-David Dalton
211d13da09 Cleanup build/post-install.js.
Former-commit-id: efb35fab14fa62b79caec2ba806173415b217207
2012-11-16 21:06:48 -08:00
John-David Dalton
11343d469e Merge branch 'master' of github.com:bestiejs/lodash
Former-commit-id: 08347b0f4b7c5853e28557d482424b63028505b6
2012-11-15 23:58:35 -08:00
John-David Dalton
d7c8041aa1 Update Backbone build method dependencies.
Former-commit-id: 808b991f6cebc72c182ce8d0def370778cce0b05
2012-11-15 23:51:49 -08:00
Kit Cambridge
9587e30af8 post-install: Show instructions for manually downloading the minifiers. [#113]
Former-commit-id: d9b794bc51057216f922f43c5bb6d8c9dc38f570
2012-11-15 22:21:34 -08:00
John-David Dalton
76fa7affaf Add @cascadiajs video link to README.md. [ci skip]
Former-commit-id: 72fbf780e0727ce751090b09cf783e5a88752614
2012-11-14 23:55:52 -08:00
John-David Dalton
2971dd8672 Cleanup npm note in README.md.
Former-commit-id: d1cd290edb316116c69cf9b7b79a10498fd6df3c
2012-11-14 22:13:22 -08:00
John-David Dalton
2a33fe3564 Add .gitattributes.
Former-commit-id: 4a4ecefda83fb408200dfb106ea5b0a837af43c0
2012-11-14 21:59:18 -08:00
Kit Cambridge
46cdf5da70 Encourage users to update to the latest npm version.
Former-commit-id: bbcab6e7338039fb3343cfaca09c17ae0ea293a1
2012-11-14 20:03:40 -08:00
John-David Dalton
28c801bfd4 Add more info about the csp build to README.md. [skip ci]
Former-commit-id: ceb0cb3588bff9cadd791b091390799b506874ca
2012-11-14 08:17:43 -08:00
John-David Dalton
c22cd40293 Move Underscore build _.template replacement within build.js.
Former-commit-id: 3c2971a67986e69a9ea0952056e2cdf95f73435f
2012-11-14 00:31:48 -08:00
John-David Dalton
56bd430983 Cleanup and comment _.merge's _.reduce support.
Former-commit-id: 2cfc41f1c00a7a3981c51be7e8005f0cc95ac692
2012-11-12 07:41:31 -08:00
John-David Dalton
d873890e46 Remove alternative _.where for Underscore build.
Former-commit-id: 4e42a26d4c16157957fa43dbb31ae9706e2641b8
2012-11-12 07:35:33 -08:00
John-David Dalton
d29b8eca3c Ensure _.merge works with _.reduce.
Former-commit-id: de53bfd024c7a088c98ee94c95d0c57fb00ed032
2012-11-12 07:35:05 -08:00
John-David Dalton
6f258000fe Add the build commands used to the custom build's copyright/license header. [via @phated]
Former-commit-id: 2e1ff0c6a83e3c4c404ad4bac968f12d34afaa6e
2012-11-11 21:42:52 -08:00
John-David Dalton
255211cd07 Update vendor/underscore.
Former-commit-id: 3e8a169e8cb81fd852e41420ad317ee12ae486f9
2012-11-11 20:00:48 -08:00
John-David Dalton
f6d28a90e3 Make _.where iterate over only own properties.
Former-commit-id: 29b4cafe5271cad70c711c2d401cea627fa97e33
2012-11-11 20:00:20 -08:00
John-David Dalton
ed66ff88a1 Update minified and doc builds.
Former-commit-id: 5d6d8ee0538a2502eef6c38d77e58d31e8026e53
2012-11-11 16:20:16 -08:00
John-David Dalton
82e58f2bf9 Make _.defaults follow _.assign and only assign own properties of source.
Former-commit-id: 114dc47bbfa6db6a53a2fa03dd477fe86c3395cb
2012-11-11 16:16:11 -08:00
John-David Dalton
797a87ca26 Make _.extend and alias of _.assign and make _.assign iterate only own enumerable source props to align with ES6.
Former-commit-id: 37ba7c3066c1ea70210346a9bf598e8587e907db
2012-11-11 15:52:43 -08:00
John-David Dalton
ec6a709393 Add ES6 _.assign alias of _.extend.
Former-commit-id: 20a0e0d295cb90a1756a5831b0b6684b97477170
2012-11-11 14:03:10 -08:00
John-David Dalton
07cbfdb424 Optimize _.contains.
Former-commit-id: b50628adedd21fe2c099f4dcab1aa9f0036a22ed
2012-11-10 23:09:23 -08:00
John-David Dalton
3b9bd944fb Ensure _.find works correctly in the Underscore build.
Former-commit-id: c22b91ffcab34b75415f126582c48c168a7cc759
2012-11-10 22:42:13 -08:00
John-David Dalton
934e585cb3 Optimize _.filter.
Former-commit-id: 565c1b0159207e9d9413d82b5827ed685564efff
2012-11-10 21:15:25 -08:00
John-David Dalton
3a68f4cf54 Cleanup build/post-install.js.
Former-commit-id: 5e289381b90e764b38bf5a3ba1866b6658766f52
2012-11-10 21:09:50 -08:00
Kit Cambridge
bd00fcb875 Improve zlib error handling. [#109]
Former-commit-id: f6d7dd9afb630125d55188401da037ed97d6e5c5
2012-11-09 14:24:57 -08:00
John-David Dalton
905dd5a70f Add template precompiler unit test for ES6 delimiters.
Former-commit-id: dc4561afa74844294bf38ecff7dadd43c0b0b99f
2012-11-09 11:13:46 -08:00
John-David Dalton
c65250ec39 Document the this binding of the returned functions of _.after, _.compose, _.memoize, _.once, and _.wrap. [closes #107]
Former-commit-id: 223c27fca0a07b5ee8ccd70ac78247a6af50cecf
2012-11-09 05:40:59 -08:00
John-David Dalton
607eec6ff0 Bump to v0.9.2.
Former-commit-id: cd4b7bd3db92f07e0ac1af74ee70bd6525f36c55
2012-11-09 04:58:41 -08:00
John-David Dalton
14fb3bde60 Cleanup build/minify.js.
Former-commit-id: 08896dd9407afdbaa98a7d6011121e785e62ede9
2012-11-09 04:46:01 -08:00
Kit Cambridge
6782bc8ca2 Skip {hybrid} advanced compilation for templates.
Former-commit-id: d76ed99ba7d906812b24a751b56d3a8a6b955203
2012-11-08 17:07:01 -08:00
Kit Cambridge
3db6841305 Preliminary Closure Compiler simple optimizations support.
Former-commit-id: 515b8e47b6fa08e1f36d0e735f8a2bf188286d12
2012-11-08 16:32:17 -08:00
John-David Dalton
f478fa8029 Add lodash moduleId=… build option.
Former-commit-id: a68a2085028a3832181aaf02081311d84e93fab5
2012-11-08 16:08:03 -08:00
John-David Dalton
d255f8400f Work around a Closure Compiler bug without a pre/post process. [via @phated]
Former-commit-id: 2b9ead74c8c29357a7d8af965b6e0702e77872a5
2012-11-08 09:40:21 -08:00
John-David Dalton
a1545c60d6 Optimize _.every, _.find, and _.some.
Former-commit-id: 37ace9b92bb2b9875093b73e460f01df9d9c211a
2012-11-08 01:05:34 -08:00
John-David Dalton
ed48603ab5 Update vendor/underscore.
Former-commit-id: 3d39397aaee8408778b738c3aa105eda67abd6bc
2012-11-06 22:00:01 -08:00
John-David Dalton
23a0507439 Simplify iteratorTemplate, createIterator, and _.keys.
Former-commit-id: 89c6d5a0311944e86fa4fca330328e903ce18958
2012-11-06 21:59:42 -08:00
John-David Dalton
482e013887 Cleanup _.max and _.min.
Former-commit-id: 9688a11db3d90f6b0f4a7d6d13b4e1c6c0709870
2012-11-06 20:22:58 -08:00
John-David Dalton
265727c30f Remove "resolved issues" that are covered under "features" in README.md.
Former-commit-id: 2239f4c78c7164e85c8fbae2e9d6fb4dfac42f1a
2012-11-06 08:01:37 -08:00
John-David Dalton
4d3f4e096b Remove tar module dependency from package.json and cleanup /vendors.
Former-commit-id: 6d32d4a3b5ef1c79e07ae3328080cb1d02f6f794
2012-11-06 07:47:57 -08:00
John-David Dalton
7629bca62d Remove stderr from the exec error check in post-install.js. [closes #101]
Former-commit-id: eecd66ffe3bce1bd6ef0261140bd634567ec60ae
2012-11-06 03:23:14 -08:00
John-David Dalton
2712f17262 Tweak capturing spaces in build.js regexes and update lodash.min.js.
Former-commit-id: a5d30941945150251a6fc4342840d906a3af1ad9
2012-11-06 03:05:09 -08:00
John-David Dalton
86a37559ba Update build dependencies.
Former-commit-id: 6a9680a118115e059636a5fc0125c4efa5161765
2012-11-06 02:56:34 -08:00
John-David Dalton
b504a557f4 Add unit tests for _.max and _.min accepting strings and adjust the build/test-build.js.
Former-commit-id: b567c019146e96ad257dab8fe1b4138d07f470c0
2012-11-06 02:56:14 -08:00
John-David Dalton
e849b46f6b Rebuild docs and minified files.
Former-commit-id: caae765d9b2e7f4de803e6057e8a2c20668c742f
2012-11-06 01:56:14 -08:00
John-David Dalton
738dc50a6f Correct _.initial and _.rest documentation. [closes #104]
Former-commit-id: d9ace8a8198b22def34c1ae3adc9421ab97790fa
2012-11-06 01:55:23 -08:00
John-David Dalton
3138523b5b Optimize _.max and _.min.
Former-commit-id: 8c5dc8606d00e68dee63f06438e83c3bd65f3b29
2012-11-06 01:46:36 -08:00
John-David Dalton
537643a4c3 Use Underscore v1.4.2 _.isFinite equivalent for lodash underscore build.
Former-commit-id: 5c6f0efb0159d8044d6f4670fb42fabc6383dda2
2012-11-04 19:20:52 -08:00
John-David Dalton
04bfe098ed Tweak _.max and _.min documentation. [ci skip]
Former-commit-id: c8506aa1b15143bc8ee1eea59027eed188a745ba
2012-11-04 18:36:05 -08:00
John-David Dalton
c507887bdd Support ES6 template delimiters only when _.templateSettings.interpolate is unmodified.
Former-commit-id: 4c4f9163af0ef2f9a8218a167092584a1d288d9e
2012-11-04 18:16:14 -08:00
John-David Dalton
ee261313ac Rebuild docs.
Former-commit-id: 7ae9d217bdbb78e9ec95d0a289a56cfc6489bb47
2012-11-04 15:36:08 -08:00
John-David Dalton
c9c152bc8a Add support for ES6 template delimiters to _.template.
Former-commit-id: d84ef4fd89d9a51237b22a09affab366974b93ff
2012-11-04 15:27:52 -08:00
John-David Dalton
6c8e19a321 Update vendor/backbone.
Former-commit-id: dc1a37f3c44eecc1fcd1cba2018d70e8c337d6f3
2012-11-04 14:40:23 -08:00
John-David Dalton
218e3b66f2 Add fromIndex to _.contains.
Former-commit-id: 9f61db3ceda2d87ddfbfd4cffb2bd1f9732cc79a
2012-11-04 11:24:29 -08:00
John-David Dalton
1d3488fa8e Update .jamignore file. [ci skip]
Former-commit-id: f34029dbc566eec92b8648d232f868a9e431c085
2012-11-04 08:26:54 -08:00
John-David Dalton
f4c1682592 Merge pull request #102 from ryanramage/patch-1
Fix for jam dependencies.

Former-commit-id: 873396512a836cdf1ea6f8d70e5a97343b696ba1
2012-11-03 15:27:24 -07:00
Ryan Ramage
28ac6623c7 Fix for jam dependencies
jam install lodash is not working as it is thinking that tar is a dependency.
Just adding a empty dependencies object to the jam section fixes this.

After pulling this, could you republish to the jam repo? No need to bump the package version, just

    jam publish -f


cheers

Former-commit-id: 1364abac5c9005053f0c604ac580f753426b4f8d
2012-11-03 16:24:28 -06:00
John-David Dalton
16ab179e1d Add _.uniq unit test.
Former-commit-id: 29a09711863011681a45ae800502eca9a7022799
2012-11-02 23:00:57 -07:00
John-David Dalton
a8ff5385dc Cleanup cachedContains.
Former-commit-id: a2b396e910eacc0e204d5bdb3f4ed834b8d6e148
2012-11-02 22:50:45 -07:00
John-David Dalton
9dc33c6086 Remove the large array optimization for _.uniq from the underscore build.
Former-commit-id: 4cafbf2568c786834e40f0e4ea9b64ff670f60b7
2012-11-02 22:31:04 -07:00
John-David Dalton
b17c576705 Optimize _.uniq for large arrays.
Former-commit-id: 6c739aab6bcb8c31f9db9821d6eaf50c9a4fb80b
2012-11-02 12:16:39 -07:00
John-David Dalton
96f8f2891b Fix typo in _.times test.
Former-commit-id: 0c32ded25b80debf4ae2ea9a9e60ee74b98c15a1
2012-11-02 11:54:37 -07:00
John-David Dalton
581d73afe0 Update vendors.
Former-commit-id: 76887b14d32e661f4c415393637478d93174329d
2012-10-31 00:38:38 -07:00
John-David Dalton
1baefebe8f Bump to v0.9.1.
Former-commit-id: d7cece2893c97c38a9379877f987ec2cfe60cb47
2012-10-31 00:18:40 -07:00
John-David Dalton
39fb05033f Tweak times of async unit tests.
Former-commit-id: 064813c739edde5f6236f33a3c75a6cb39ba774e
2012-10-30 23:49:23 -07:00
John-David Dalton
c6093c084c Ensure _.isFinite returns false for non-numeric strings. [closes #98]
Former-commit-id: 2505c8d7d9a0ab1e5f669730c318efdc9232799b
2012-10-30 21:36:53 -07:00
John-David Dalton
dfec6d9a6d Adjust _.throttle unit test.
Former-commit-id: 1cc461b62fb5ca20f2e623ab145f157a92d18fcf
2012-10-30 08:10:40 -07:00
John-David Dalton
08b1261c75 Update @category docs.
Former-commit-id: edf8964b2061c80d8c868ea71b8c05a29cee4e28
2012-10-29 22:01:34 -07:00
John-David Dalton
2ad6faae3a Ensure _.every returns false as soon as the callback result is falsey.
Former-commit-id: d5488688c4a30376999b04ba80f1551af403b516
2012-10-28 00:28:40 -07:00
John-David Dalton
4eff301db3 Reduce the size of _.union.
Former-commit-id: c8f4d18817e6a294ece014b65fb3c690d4ddf7b9
2012-10-26 08:51:28 -07:00
John-David Dalton
447e43e8f4 Remove chainability from _.forEach in the lodash underscore build.
Former-commit-id: 1db7daafacddcf78492643d6c6301af706b92150
2012-10-24 20:05:50 -07:00
John-David Dalton
7457001275 Add CDN links to the Underscore and development builds and cleanup changelog.
Former-commit-id: 1414f0509900e858c441ad642e27b369fbf875c8
2012-10-24 08:11:59 -07:00
John-David Dalton
fcabd5e79e Update .npmignore.
Former-commit-id: 7073069a2002a707bdf2becf80c653767e93d7a6
2012-10-24 01:09:42 -07:00
John-David Dalton
594002316c Bump to v0.9.0.
Former-commit-id: adbe6963da3dd52bed5e8adcf7875871b561584c
2012-10-24 00:02:06 -07:00
John-David Dalton
eccf92ebaf Cleanup build script comments and fix Closure Compiler bugs.
Former-commit-id: 84771ac79d6cfd7ec3b0d29586edf58d617d5577
2012-10-23 23:54:53 -07:00
John-David Dalton
ad9ddc5621 Remove optimized methods list from README.md.
Former-commit-id: 91f5fd06073dd4b0e4ef450392550e6eb7245c12
2012-10-23 22:20:19 -07:00
John-David Dalton
1825dd916e Fix unit tests and reduce object/array references.
Former-commit-id: 25aaabd506cb4515cf833ebb104ba0146e4354dd
2012-10-23 22:16:53 -07:00
John-David Dalton
dfcde8171e Reduce _.toArray and _.difference.
Former-commit-id: a0253006b0f38744314c449dbcffa15b67390910
2012-10-23 18:08:09 -07:00
John-David Dalton
b0361183df Add _.compact, _.defaults, and _.extend benchmarks.
Former-commit-id: adebc01aeda08323174af63166c2b6e0e798c313
2012-10-23 09:09:14 -07:00
John-David Dalton
71fe13b249 Simplify _.mixin and _.wrap.
Former-commit-id: 89b802a1b887fcd61af8938e84f3ff06e3a7938c
2012-10-23 09:03:56 -07:00
John-David Dalton
442f51224d Update vendors.
Former-commit-id: 1e711564671134b82eed980bccb628af612ae195
2012-10-23 01:21:45 -07:00
John-David Dalton
974678f500 Remove unused iterator options references from build scripts.
Former-commit-id: 9610a20d8fea6778523d1d0a8b3e16b930534f20
2012-10-23 00:30:59 -07:00
John-David Dalton
8329409c03 Reorganize method order.
Former-commit-id: a24a02725595ac28633a24a1f33c152db87dda77
2012-10-22 23:57:03 -07:00
John-David Dalton
06c2ac2724 Reduce iteratorTemplate.
Former-commit-id: 586e08c796462e1e0ff59a14a9cde07723abd771
2012-10-22 23:41:19 -07:00
John-David Dalton
04e9e8f9d8 Remove pseudo private _shimKeys.
Former-commit-id: e8289094ceb14e62ce5d9fb74e7b9021f30f5aab
2012-10-22 22:42:42 -07:00
John-David Dalton
7a3330cb8c Simplify createIterator.
Former-commit-id: 7187930670d888550ea741967da916a13eef091d
2012-10-22 22:29:46 -07:00
John-David Dalton
cae29941ea Merge branch 'master' of github.com:bestiejs/lodash
Former-commit-id: 60eee2c007a673cfe706c71a0ada05582a72e790
2012-10-22 21:37:32 -07:00
John-David Dalton
15cf2ad076 Rework "strict" build option and fix typo in test-ui.js.
Former-commit-id: e06045546bea43bbe1fff78d6c948036ad98a88c
2012-10-22 21:28:12 -07:00
John-David Dalton
2f16f6dc23 Remove extraneous skipTest call from test.js.
Former-commit-id: 58f747ff8f8beee621038f7e06bfe3aa408f0b14
2012-10-22 20:27:45 -07:00
John-David Dalton
528aebffe4 Reduce _.where and remove compiling from _.bindAll.
Former-commit-id: 78f4db8c112ad9687f7a7e4322460f7b5edf5af9
2012-10-22 20:27:04 -07:00
Kit Cambridge
e82b2f0cbe Merge pull request #96 from terinjokes/master
Fix a typo in the `_.groupBy` docs.

Former-commit-id: a5fb6f9769bb80d8bb6a0e2a176385a2f0d7fd83
2012-10-22 12:14:37 -07:00
Terin Stock
73e64f3e4a Tweaked and rebuilt docs for _.groupBy.
Former-commit-id: a541ec305742ab6f330aeceae4804577f64905ab
2012-10-22 11:59:31 -07:00
John-David Dalton
15f5b1f830 Ensure _.map rewrite handles objects with non-numeric length properties correctly.
Former-commit-id: 60a4f322dcd284db5bb8ad4d8d5138e52e14cce3
2012-10-22 01:56:50 -07:00
John-David Dalton
1b0a77f9a8 Add more and rebuild documentation as well as update minified builds.
Former-commit-id: fab04394692ecbfb0d55e212928f0ff53902d921
2012-10-22 01:21:53 -07:00
John-David Dalton
0f82ae3644 Cleanup build/post-install.js.
Former-commit-id: e92e1c1e1c1cd821721085a3e1520756c158dfb5
2012-10-21 23:24:42 -07:00
John-David Dalton
de3b01b54b Remove unnecessary return statements from _.delay and _.defer.
Former-commit-id: fb912605e8414b1a4d9d2d8ae96f21dfe95609c2
2012-10-21 17:29:41 -07:00
John-David Dalton
c17e3646d5 Rebuild docs.
Former-commit-id: 7c2d47728fdb8a61e739f8bbec4fad619342f2c5
2012-10-21 11:44:06 -07:00
John-David Dalton
26aed3e89e Reduce _.isFinite, _.sortedIndex, and _.map, tweak docs for _.unescape, and ensure rewritten _.map works for objects correctly.
Former-commit-id: 43c810538b500b55018d4cfb9812618671fae2c7
2012-10-21 11:37:10 -07:00
John-David Dalton
74caea8f8f Inflate dev test dependencies for easier inspection and swap firebug-lite with its debug build for Opera support.
Former-commit-id: 2f9ee3e33384b5ef5ed3da9c9ad5bbe7b561d265
2012-10-21 09:23:30 -07:00
John-David Dalton
2cf07fa072 Make variable naming more consistent and add indicatorObject for more clarity.
Former-commit-id: 27b5730a33222409c69d174962db7a25e06bd373
2012-10-21 01:48:38 -07:00
John-David Dalton
1181cd2fd7 Reduce _.uniq in the lodash underscore build.
Former-commit-id: 12c8ee7a269dbaebbe4d05d902bfcc4bed193cec
2012-10-20 20:16:39 -07:00
John-David Dalton
850d55ab45 Rework _.intersection.
Former-commit-id: b05442888b15b448f6594b46b5cf1a2a06611da2
2012-10-20 19:40:38 -07:00
John-David Dalton
a0c91b8754 Remove clearTimeout and setTimeout from the list of properties to escape in pre-compile.js.
Former-commit-id: 7d2c5fb866bd53df079fff3dab533866ab1f79f4
2012-10-20 18:55:28 -07:00
John-David Dalton
937bdc05c8 Reduce _.intersection and _.where.
Former-commit-id: b8d87f72c72c0f42e693eff67296135f0a5c548b
2012-10-20 18:54:34 -07:00
John-David Dalton
453755bfa1 Fix _.isFinite unit test in Node and remove isStrictFast use.
Former-commit-id: e2e04f4cee0a52f4461c8ee84c157c1ea0e4c132
2012-10-20 16:37:07 -07:00
John-David Dalton
400b6fbb61 Sync _.isFinite changes with Underscore and update vendor/underscore and vendor/backbone.
Former-commit-id: 9acb93a276a11da8186da76bd82f1fd6f89c27dd
2012-10-20 13:02:39 -07:00
John-David Dalton
8c4e882fa3 Reduce file size further.
Former-commit-id: e66751a6a76331dedcfc68e9eaf81eddf5afe8b2
2012-10-20 12:59:37 -07:00
John-David Dalton
84eec23793 Ensure _.every and _.some work in Underscore builds without the "exit early" feature of _.forEach and reduce unexposed forIn and forOwn.
Former-commit-id: 35488c1c0f70cb5446c875bd4647b0ce47077d9e
2012-10-20 02:45:59 -07:00
John-David Dalton
7dfe69f6a5 Reduce iterator template and _.bindAll.
Former-commit-id: 2655b7ca336baf9e04c87ff546c4bfc614873b50
2012-10-20 01:14:28 -07:00
John-David Dalton
ada6115073 Simplify _.bindAll.
Former-commit-id: 02de2a2a6020461d42e222a476c2fb7e66f6895e
2012-10-19 08:23:52 -07:00
John-David Dalton
e1643566f9 Capitalize comment in post-install.js.
Former-commit-id: ea8604f6d044b60378548afea2ca672ac5795244
2012-10-19 01:33:06 -07:00
John-David Dalton
053a9a6317 Remove compiling from _.map.
Former-commit-id: 5274c0972cd7ab848739c39cfe46586d88c93327
2012-10-19 01:25:07 -07:00
John-David Dalton
425b976cc0 Remove compiling from _.every, _.filter, and _.some and add related benchmarks.
Former-commit-id: 545195dc7085c1294ad8709f44fddb0c3c6a0545
2012-10-19 00:59:14 -07:00
Kit Cambridge
5f5f1b1e09 Add download progress messages and a comment explaining the Accept header to the post-install script.
Former-commit-id: 10ed30f49f3028169610f7e4a10427e55a4c25eb
2012-10-18 23:30:38 -07:00
John-David Dalton
e6f4935c7b Cleanup package install related files.
Former-commit-id: ac905fe660af05077a52b001b295ee557aaacfa8
2012-10-18 23:13:55 -07:00
John-David Dalton
6452e5976b Merge branch 'master' of github.com:bestiejs/lodash
Conflicts:
	build/post-install.js

Former-commit-id: 793ebf1f983d4077c7b333c9305958a409e18d95
2012-10-18 22:36:33 -07:00
Kit Cambridge
2383dff317 Avoid including npm as a dependency; parse the npm -g root output directly.
Former-commit-id: a6b432de64292ce2af280d0a861f610ceeabce6c
2012-10-18 09:43:53 -07:00
John-David Dalton
de3e5042fb Merge branch 'master' of github.com:bestiejs/lodash
Former-commit-id: 24cd5b5b280e405b4261511222ba6bf7dfacc783
2012-10-18 08:21:01 -07:00
John-David Dalton
0dcc35152c Simplify lodash underscore build's _.template.
Former-commit-id: d3f98bf310f5ef7c06cacb7716fc0999440d411b
2012-10-18 00:51:26 -07:00
Kit Cambridge
8eecfcbfaf Manually download Closure Compiler and UglifyJS for Travis.
Former-commit-id: 8aa022e2816917ec4bb42c77cdf5d26ed53e1e3a
2012-10-18 00:39:58 -07:00
Kit Cambridge
efa3e60f89 Add npm as a dev dependency.
Former-commit-id: 7f7a80492f05afa66925cb6fba1b0000b376807e
2012-10-18 00:32:42 -07:00
John-David Dalton
782df659bc Fix typo in _.where.
Former-commit-id: e4da5a993a26eb3e408c9a2ddd408ee785671088
2012-10-17 23:26:16 -07:00
Kit Cambridge
0aa158824f Add npm as a dev dependency.
Former-commit-id: c72a6e13774bce378dd2ab5982f51ba37c6a7bc0
2012-10-17 22:46:07 -07:00
Kit Cambridge
da7fb44e5d Add the post-install script.
Former-commit-id: cab08838401ab9ccf4f2333a3d353c852f59a91b
2012-10-17 22:11:02 -07:00
Kit Cambridge
4b59ef802e Move dependency downloading into a post-install script.
Former-commit-id: c85d930fe4be787d6583015aa79d922d8909367e
2012-10-17 22:08:14 -07:00
Kit Cambridge
be5789cd56 Automatically download Closure Compiler and UglifyJS if they are not available. Add tar as a dependency.
Former-commit-id: baff21528a09bad5beff5eab65d1b7ffe4fc8a40
2012-10-17 21:22:02 -07:00
John-David Dalton
9adf0e5d59 Update .gitignore, .jamignore, .npmignore.
Former-commit-id: a01be2b79a51188e3bbd91926c68afcb17476808
2012-10-17 08:48:47 -07:00
John-David Dalton
e2de22470e Cleanup vendors.
Former-commit-id: 9e4f91aa0d498c1b160907f365b82b902e516880
2012-10-17 07:19:57 -07:00
John-David Dalton
3b7ab2e553 Make lib references more generic in perf.js.
Former-commit-id: 9984b8ac9f552d5a1051d738b57ff0b69b8d764a
2012-10-15 08:15:29 -07:00
John-David Dalton
8617dedc46 Use the buildPath and otherPath in the logged perf status updates.
Former-commit-id: 0f1301e68dca84c0f72459bcfed11b3cc55cb577
2012-10-14 23:32:24 -07:00
John-David Dalton
0b8f1a9a58 Add build dropdown to perf/index.html. [ci skip]
Former-commit-id: 669acae55ee53819fe4155aa0020cd40db7d6843
2012-10-14 22:18:53 -07:00
John-David Dalton
16748c0920 Cleanup lodash.js and ensure _.where returns an empty array when passed an empty properties object.
Former-commit-id: 34d1f8d967806d3c59895eff3a7d4d32262a46ea
2012-10-14 18:56:39 -07:00
John-David Dalton
01ec585a44 Cleanup _.merge.
Former-commit-id: 49c646ff8f199b001cfd8145d7e2076d8d1ceaf0
2012-10-14 15:37:49 -07:00
John-David Dalton
b5f2295f37 Simplify _.bindAll iterator options.
Former-commit-id: e9abbcc940f333e053d1ab5c35c7f4ae2d96d381
2012-10-14 14:55:51 -07:00
John-David Dalton
d6ca0199b7 Remove compiling from _.reject and consolidate iterator option objects.
Former-commit-id: 10eb78c0c4cdfc35317b9ad263768df60f70db40
2012-10-14 14:04:42 -07:00
John-David Dalton
2257c5e547 Remove arrayLikeClasses variable.
Former-commit-id: 6615f8b94da319bf25fffe7275c959293e5075e3
2012-10-14 04:17:23 -07:00
John-David Dalton
b5a3d39799 Improve _.isEqual performance.
Former-commit-id: d705b29825eff419ac14806f0a5fcf7c7458c6de
2012-10-14 03:06:25 -07:00
John-David Dalton
a26c3e9d3c Fix build after shimKeys change.
Former-commit-id: 7ca25a08f3ac20e3b8410fbc975c96da2570e0a7
2012-10-14 02:19:57 -07:00
John-David Dalton
98a09532eb Avoid argument issues in _.merge.
Former-commit-id: 2f8a798654e903454050211886b19b3b581a3c88
2012-10-14 01:52:48 -07:00
John-David Dalton
d736789bbc Remove compiling from _.invert and shimKeys.
Former-commit-id: 9fc384680960cf45f49f16e4cd84e3dca2b4cf19
2012-10-14 01:42:44 -07:00
John-David Dalton
82a6cfc03a Add _.reject benchmark.
Former-commit-id: 936a8b8915522abd5a64bbb2c7756a36a4af7c30
2012-10-14 01:40:50 -07:00
John-David Dalton
62e9c7c75a Add comments to test/test-build.js.
Former-commit-id: ae663d4570c3a464fffbf3090494b070279a24a7
2012-10-13 23:39:01 -07:00
John-David Dalton
eb32bd45e7 Rebuild docs and minified builds.
Former-commit-id: 556d91b9c58c9f6be2994ec17de3823f49416911
2012-10-13 23:33:16 -07:00
John-David Dalton
4b95f07923 Simplify _.omit and _.pick for the lodash underscore build.
Former-commit-id: 9a42c964ce4003bde1b4ce55f0f851141dbc9bb6
2012-10-13 23:32:17 -07:00
John-David Dalton
dea8ad4c49 Optimize _.contains and _.omit.
Former-commit-id: f1d7b5699bae6de90d880fe593531f7d3772924e
2012-10-13 23:30:25 -07:00
John-David Dalton
96553b217c Reduce _.merge.
Former-commit-id: 5797e14e589d39e553d7af109d282109e633cd80
2012-10-13 20:58:39 -07:00
John-David Dalton
3f79ed5d91 Reduce _.isEmpty and ensure dependencies are modified correctly for the lodash underscore build.
Former-commit-id: 23ff37da17578dfeafbabee4bcae100f4df68ed6
2012-10-13 20:58:08 -07:00
John-David Dalton
1e4283aad3 Remove compiling from _.functions, _.isEmpty, _.pairs, _.values, _.contains, _.find, _.invoke, _.pluck, _.reduce, and _.where.
Former-commit-id: 207f20330ede82cb58d4f008fe5164771e97a8b0
2012-10-13 15:12:21 -07:00
John-David Dalton
1dda31a28c Make remove compiling from _.merge, _.countBy, _.groupBy, _.pick, _.omit, and _.sortBy.
Former-commit-id: 52b245e69629e7a9fbe5f0dcbdfafabcd75d9dfc
2012-10-13 00:03:40 -07:00
John-David Dalton
10c87012be Update vendor/underscore.
Former-commit-id: 5ede87579d9b7a8e505da23fc3a4531be40a151b
2012-10-13 00:01:29 -07:00
John-David Dalton
bda00bf512 Add json3.js, remove json2 and jslitmus from vendors.
Former-commit-id: d801c48ec81ea2f5c5638910190da461facf98cf
2012-10-12 01:11:58 -07:00
John-David Dalton
c8f871ff2a Escape template properties for minified precompiled templates and add a lodash template="…" exports="…" build test.
Former-commit-id: 866252235232ab52cf21842554c37573de4cf402
2012-10-12 00:25:32 -07:00
John-David Dalton
58dc0b1aef Remove unnecessary template unit test.
Former-commit-id: 42ea5be4168d4db818ec93a8f6c61c51905127c7
2012-10-11 22:14:05 -07:00
John-David Dalton
4cd4d8f31a Add sourceURL template option. [closes #90]
Former-commit-id: 5db79c6b08aa7c8b2925db70d86dde75298da4c4
2012-10-11 22:13:42 -07:00
John-David Dalton
b751fd738d Tweak _.isPlainObject doc example. [ci skip]
Former-commit-id: 5d4916d5c1a2909062cc9f2646a580b630fb4e35
2012-10-10 00:46:52 -07:00
John-David Dalton
f97c6fb94c Tweak npm global install note in README.md. [ci skip]
Former-commit-id: 1105c1cf4c5889278eeb5be4bff9534091904821
2012-10-10 00:28:07 -07:00
John-David Dalton
219138ade6 Bump to v0.8.2.
Former-commit-id: edbb9d995a63ec8fd5a3b1a47ccda7b30c353b35
2012-10-10 00:03:39 -07:00
John-David Dalton
9086d189b9 Update vendors.
Former-commit-id: e88301bddf23f177a2d14f2c729877eaede022e5
2012-10-09 20:11:57 -07:00
Kit Cambridge
d1178defe0 Add a note about npm link. See #88.
Former-commit-id: 11c4a9bce02e5f143b09d0edff80362e2e824b10
2012-10-09 15:22:26 -07:00
John-David Dalton
691a561a95 Merge pull request #87 from danheberden/typo_fix
Fix typo in `_.indexOf` docs.

Former-commit-id: 25305344f272cb875a612e37a93ae252a53e1b4b
2012-10-09 13:56:59 -07:00
Dan Heberden
aaaac93bd0 fix tiny baby super small almost didn't need to worry about fixing typo from isSorted to fromIndex for indexOf method
Former-commit-id: 6f2a7b3e11c4830ec47c174f24badca3ef2e6530
2012-10-09 16:53:56 -04:00
John-David Dalton
fd790566b2 Ensure _.throttle clears the timeout when func is called. [closes #86]
Former-commit-id: 6f3b777aa247f059d97f965c02323d4ee6ab8464
2012-10-09 02:15:06 -07:00
John-David Dalton
db3b429784 Update _.min, _.max, _.shuffle build dependencies.
Former-commit-id: 21c4c99f8ead92b90b46c299fee59098131758b1
2012-10-09 01:43:24 -07:00
John-David Dalton
40ed3278d4 Rebuild minified files and docs.
Former-commit-id: b14af8d9fcb9046c2faf4374fe2e6e83c4f4f835
2012-10-09 01:02:14 -07:00
John-David Dalton
d174b13111 Add object iteration unit tests for _.max, _.min, _.shuffle.
Former-commit-id: 45129100fbbfa14610cacb055c1fa393ae6ce153
2012-10-09 00:59:55 -07:00
John-David Dalton
1708663b32 Move _.max, _.min, _.shuffle back to "Collections" methods for compat but still optimized for arrays.
Former-commit-id: 28cd9298915ad123445400a5d061ac8e9432eb6b
2012-10-09 00:48:02 -07:00
John-David Dalton
6fdce4ad0d Re-optimize _.max, _.min, and _.sortedIndex.
Former-commit-id: 7f449a4fde6777f14a1def0d767f2926bdea07c9
2012-10-09 00:17:10 -07:00
John-David Dalton
fff8d5f07d Cleanup var names in lodash.js and continue to optimize for gzip.
Former-commit-id: 00d76bd7ab8b35d2b45237224662849e42d00bac
2012-10-07 22:26:23 -07:00
John-David Dalton
9c8e1f4706 Reduce _.compact and revert _.random use in _.shuffle.
Former-commit-id: 17d153cb09c262830f1497f93c0f3d9b279c8f8a
2012-10-07 19:32:56 -07:00
John-David Dalton
0a1036c78f Add unit tests to check "Collections" methods return values.
Former-commit-id: 6ac6cd97414035f74a102a51e913099e744d9a93
2012-10-07 18:18:20 -07:00
John-David Dalton
0e881a7972 Simplify _.shuffle and iterator options.
Former-commit-id: 341fd577d65725d47b26172d25b46dec2ac8e67f
2012-10-07 17:43:38 -07:00
John-David Dalton
839e52ba30 Organize docs by category. [closes #84]
Former-commit-id: f4ebda7c32a0ce9c5a86cdb0fd1e689f76557e42
2012-10-07 12:21:01 -07:00
John-David Dalton
8f7d5dcb4d Reduce lodash file size.
Former-commit-id: c6c309cbbc5f93bffb852726e831ba9f90c332a0
2012-10-06 23:39:41 -07:00
John-David Dalton
1104b28bc1 Update README.md to remove fixed Underscore issue.
Former-commit-id: 16fc177c33c2f2522fd9080c0974091ef8e97850
2012-10-06 23:38:25 -07:00
John-David Dalton
48521cb1e4 Update DocDown and Underscore.
Former-commit-id: 7744ef274a9d8b47975dc9f3e3283bd778bc5403
2012-10-06 22:31:08 -07:00
John-David Dalton
17e113dafb Update _.map to return an empty array when falsey values are passed.
Former-commit-id: 2f091fbeb140cbc0b8f3bd2df7a449a06239be0b
2012-10-06 21:17:50 -07:00
John-David Dalton
c33825a904 Reduce Underscore build and update Underscore version number.
Former-commit-id: fd631cd5525fa287c2af493bfe4a93668678977d
2012-10-06 20:58:21 -07:00
John-David Dalton
b07ef98c8f Update Backbone/Underscore vendor folders.
Former-commit-id: 3317d501fe535d91eefab8a5dcb3a88a791e20ac
2012-10-06 20:56:42 -07:00
John-David Dalton
b3d68893df Reduce deep _.clone array iteration and add _.each dependency.
Former-commit-id: 3cb599d294a693974483b892748e6f60186d0c50
2012-10-06 18:15:30 -07:00
John-David Dalton
1329599987 Simplify how deep _.clone handles booleans.
Former-commit-id: adf1d03677336131da2f62bd2fb6e2900c9889a4
2012-10-06 17:32:18 -07:00
John-David Dalton
2adf3f364c Add _.isPlainObject to the list of features in README.md. [ci skip]
Former-commit-id: ec81cdc9e7fef775871cc1c4a497e4d17e7716aa
2012-10-06 15:45:48 -07:00
John-David Dalton
436ee34a02 Simplify createIterator.
Former-commit-id: 0530a9db49488900843c6312cc0d30b1dc641120
2012-10-06 14:43:34 -07:00
John-David Dalton
4a6e17b214 Reduce lodash builds and cleanup README.md.
Former-commit-id: 3c6bbc236a35687c843a8cb27c29f71ed89d0ab0
2012-10-04 23:35:36 -07:00
John-David Dalton
6e9cbccde6 Bump to v0.8.1.
Former-commit-id: 1b63f03d4a7ca0cdc66e44cd987fddecaf88f9ce
2012-10-04 01:40:17 -07:00
John-David Dalton
a0cb8ec124 Cleanup lodash.js.
Former-commit-id: 7a2443719a96b36ae53b2f7d0fe2a1867d650f02
2012-10-04 00:28:45 -07:00
John-David Dalton
21217dfda3 Reduce createIterator.
Former-commit-id: 8c27ca8e4d1f71b2727dd988bc62194510a850dc
2012-10-04 00:02:43 -07:00
John-David Dalton
25ba18e570 Update vendors.
Former-commit-id: 94bb6b8541c223d3ef6eb8aad5fb5925f2d3be48
2012-10-03 23:21:51 -07:00
John-David Dalton
a210377f35 Add unit tests for passing falsey values to _.initial and _.rest.
Former-commit-id: 9d5d4960c175a3dd90af977b605ce309bc6446d3
2012-10-03 20:12:03 -07:00
John-David Dalton
07b9ca457f Cleanup build.js regexes.
Former-commit-id: 0d23053cd8ae20fa2268ba24b15db72c6cd7a85e
2012-10-03 09:09:40 -07:00
John-David Dalton
5f1372d39c Rebuild minified files and docs.
Former-commit-id: d8d8453fa79ab026be0acd44a1af967bdb0bc4cc
2012-10-03 09:09:20 -07:00
John-David Dalton
01b84c79f0 Revert removing falsey guards.
Former-commit-id: b5eeb5d4a0896eb030f20e7e91e54bf101535abc
2012-10-03 09:08:51 -07:00
John-David Dalton
4017443b1e Allow deep clone if requested via include or plus with the underscore build.
Former-commit-id: e86dba41f7265700330e57346a112b578873b390
2012-10-02 21:39:18 -07:00
John-David Dalton
fd2a17d244 Reduce lodash.underscore.min.js.
Former-commit-id: a5032bc542e1166fab6acfd7313c305dd8236d36
2012-10-02 01:43:49 -07:00
John-David Dalton
126804f7c3 Cleanup _.difference, _.intersecton, _.without.
Former-commit-id: 1ca8edb52a1c403fc2d8a8e1b3fd113ced9ff39e
2012-10-02 01:43:30 -07:00
John-David Dalton
5167bbf59e Fix _.lateBind doc typo.
Former-commit-id: 3284bee699837ab380a3e8fd2853f8bdcf0684b6
2012-10-01 23:33:35 -07:00
John-David Dalton
8bcdfa2793 Add identitydependencies to build dependency map.
Former-commit-id: e466c8547888755b9e3d645d555298b21b5a6849
2012-10-01 08:31:23 -07:00
John-David Dalton
2f9cb6a91e Add more to .jamignore.
Former-commit-id: aaa51092bb28995478e4cf8cf1b5ff249880a99c
2012-09-30 23:29:43 -07:00
John-David Dalton
662be14535 Tweak whitespace in README.md and update QUnit-CLIB.
Former-commit-id: b8fed819580bf7db926b8a4cfb794aa7666c5f58
2012-09-30 23:06:40 -07:00
John-David Dalton
d6d065cd61 Cleanup settings=.. build option usage.
Former-commit-id: 33506d9cfc2101cba8d160169c5d27861f8c7064
2012-09-30 22:52:34 -07:00
John-David Dalton
ac7f045708 Correct bullets in README.md.
Former-commit-id: fb75befff853071b7ad5dde3f3a575c707930cc4
2012-09-30 22:47:29 -07:00
John-David Dalton
ffe02ad7bf Reduce the size of lodash.underscore.min.js.
Former-commit-id: fd7d512e104c6325a38a7d0e09015235ca69b1da
2012-09-30 22:36:57 -07:00
John-David Dalton
db1a87d10c Bump to v0.8.0.
Former-commit-id: b5bed986eed052cab3f927a928d92d58044a4798
2012-09-30 21:49:12 -07:00
John-David Dalton
4bae41ffd8 Use a better strict mode detect for tests.js so older versions of Node.js pass.
Former-commit-id: fd9f6ea35c71a8183ce0dcf4a6ec6e6afe13c39e
2012-09-30 21:45:50 -07:00
John-David Dalton
be36fb979f Make .jamignore ignore test-build.js and test/template/.
Former-commit-id: cc6e5e744e81cfb92ae46a4991a39b5c925a0727
2012-09-30 21:39:00 -07:00
John-David Dalton
0f66d763e0 No longer create/use the dist/ folder during the build process.
Former-commit-id: d8d298d5ce21032542d21c4d4fbc7e0112f6ad65
2012-09-30 15:05:17 -07:00
John-David Dalton
06f4743f51 Add lodash.underscore.min.js.
Former-commit-id: 15592a33a6f6979a1d60632a6ade3c341f13d0e7
2012-09-30 02:49:48 -07:00
John-David Dalton
9cc11b8774 Cleanup build files.
Former-commit-id: d19939a34688a8a63979f84eb1a5c5f9c926897b
2012-09-30 01:55:26 -07:00
John-David Dalton
de821e55ae Add template and settings build options unit tests and tweak _.template docs.
Former-commit-id: c814799c82e5a1dde60e5eda4dda5cb192d437f9
2012-09-30 01:03:43 -07:00
John-David Dalton
463b5c6e49 Tweak build option internals and add test template files.
Former-commit-id: ed5ec6ed7886a066c8c727de19dc0fe6548a276d
2012-09-30 00:57:09 -07:00
John-David Dalton
65ab5fdb34 Ensured failed tests trigger travis fails.
Former-commit-id: d513b5b1bae77ab1f4aa9e98ec3622e143048def
2012-09-29 19:54:39 -07:00
John-David Dalton
d2f7a035b3 Add test-build.js to npm test.
Former-commit-id: c915ba8401c1c1b11aa69d155cebe2a0a81eb2d1
2012-09-29 17:20:51 -07:00
John-David Dalton
bc0b924283 Reorganize tests.
Former-commit-id: 5293cdc1206af20824e8aec86b892afd4badf639
2012-09-29 16:42:13 -07:00
John-David Dalton
56ad6af5b2 Add travis integration.
Former-commit-id: 293478e5175ff94dab92bc340034d8d83e3e4773
2012-09-29 16:05:17 -07:00
John-David Dalton
c50bb3a5a9 Remove component.json and add index.js.
Former-commit-id: 16718a8ee6c4b6c834fe96feb58404311b82e3a0
2012-09-29 15:31:47 -07:00
John-David Dalton
d993a62263 Use invert to assign htmlUnescapes.
Former-commit-id: 20f9f29d622643e2f59bbc4a57fd2456c09ef49e
2012-09-29 14:36:23 -07:00
John-David Dalton
82bc52b909 Reduce underscore build size.
Former-commit-id: 207d4ab49063483245dc951d4646413d6d4a1903
2012-09-29 12:21:34 -07:00
John-David Dalton
f31598f916 Update README.md and rebuild minified file.
Former-commit-id: 0b37eebda0d1a82d0bb62cf2ba6e5b190e176547
2012-09-29 03:48:15 -07:00
John-David Dalton
6a9efd8ac6 Ensure build tests pass.
Former-commit-id: 9b91f0d884fe96dce1df34a6c0b659619276b83e
2012-09-29 03:41:00 -07:00
John-David Dalton
a9dddb6066 Update vendors.
Former-commit-id: 31e8de8842ed9ea020f54ca06cdb87b1478e3b08
2012-09-29 03:14:03 -07:00
John-David Dalton
40cf5c99ef Update reduce repeated code.
Former-commit-id: 3412cde47a136dab5c241c67d1c29f2e676c38d1
2012-09-29 03:13:45 -07:00
John-David Dalton
42f58cbbb3 Fix perf.js.
Former-commit-id: 4eef40ddbcb851aca3a87813a17dc329f9ecb071
2012-09-29 00:17:27 -07:00
John-David Dalton
fd9c780015 Reduce file size further.
Former-commit-id: 009540db12d86f0fb79ccd493b61c4fa2cdd9b1f
2012-09-28 07:58:16 -07:00
John-David Dalton
383b92b207 Update build.js, test-build.js and rebuild docs.
Former-commit-id: 385c6b4cb127ad8089622416758021556e413a0a
2012-09-28 02:14:59 -07:00
John-David Dalton
7036ed5e2f Remove falsey checks and reduce file size.
Former-commit-id: 5263a0beaffe2a987eb65fd3631ea4aff8d9f000
2012-09-28 00:46:57 -07:00
John-David Dalton
30666aa111 Update vendor.
Former-commit-id: 9f433cc31e3c70dddba332346c7d053539f54ab5
2012-09-27 20:53:49 -07:00
John-David Dalton
9614d68baa Cleanup test-build.js.
Former-commit-id: d6588b8cc7cebe0ce44392269cdda1ebd851f1ae
2012-09-26 23:08:19 -07:00
John-David Dalton
c25fb4c743 Merge branch 'master' of github.com:bestiejs/lodash
Former-commit-id: a8dbad27cb89e403dbdafcc7cc69a397ae1e5bbd
2012-09-26 22:31:18 -07:00
John-David Dalton
09d5222b1f Allow _.sortedIndex to accept a string value.
Former-commit-id: 7ac17a6bb620ad16ecce17718a8110d422d49118
2012-09-26 22:30:15 -07:00
John-David Dalton
426ca78bf7 Update vendors.
Former-commit-id: 48e14b4b41c9b26382b09294127e552a794e49be
2012-09-26 20:42:52 -07:00
Kit Cambridge
a77a0945fe Add tests for the -d and -m options.
Former-commit-id: def5bcf323aaed96c037fea3e15c4a5c8c72a977
2012-09-26 09:26:40 -06:00
Kit Cambridge
5311a0f903 Allow the -d option to be used independently.
Former-commit-id: cb838b158edb8360d6d7c98ee18f2a7fbb4e9bb4
2012-09-26 08:59:33 -06:00
John-David Dalton
d421656be8 Cleanup build exports options.
Former-commit-id: 75a5f57c0c9f71067cf6d55006f59fa0296a82e2
2012-09-25 23:06:30 -07:00
John-David Dalton
04459eaa50 Remove internal skipArgsCheck from _.isPlainObject and add unit tests.
Former-commit-id: 213c1e95f61368eb8912850248a97f44664384d8
2012-09-25 09:05:09 -07:00
John-David Dalton
3beda8eea0 Add _ references to precompiled templates.
Former-commit-id: 4a6f38ec03790d647de4923262bba8d73378ce14
2012-09-25 02:10:35 -07:00
Mathias Bynens
5e894be06b Fix typo
Former-commit-id: b9fa32da8453a1a928b16bc712a9f2ec53722341
2012-09-24 15:22:55 +03:00
John-David Dalton
bc8f93b596 Remove internal params from built docs.
Former-commit-id: 8b0be9d888ef88dae74554101463f4fa8d268dbc
2012-09-24 01:15:46 -07:00
John-David Dalton
2fb93bac99 Use a different private indicator for _.merge now that isPlainObject is exposed.
Former-commit-id: 5c75de935eb3e5e9e035bd6520398c7fbd811ea6
2012-09-24 01:06:58 -07:00
John-David Dalton
d0c94c1aef Cleanup template build option.
Former-commit-id: 38b94dad822dd9030a6a71f66e65ff7aec0726cc
2012-09-24 00:03:41 -07:00
John-David Dalton
77242bfb95 Expose _.isPlainObject.
Former-commit-id: 884bc87df7773ef3cb5e52725d5a37f07812385a
2012-09-23 21:30:14 -07:00
John-David Dalton
5d2d86bffc Initial lodash template=… build support.
Former-commit-id: 9d13021463380556a997cb53f5ae89eb22a7b98b
2012-09-23 21:29:20 -07:00
John-David Dalton
8492c13e72 Remove DRY modifications for smaller gzip size.
Former-commit-id: 69391d792d76c6592e7d48aec44165a8db388f81
2012-09-22 20:50:59 -07:00
John-David Dalton
e4eb5dadda Modify "underscore" build methods in prep for Underscore.next.
Former-commit-id: 22503a046256915aa6667e32f6efb992c6ddbce9
2012-09-22 20:03:43 -07:00
John-David Dalton
8532dc4b75 Refactor reduceRight and modify a _.difference benchmark.
Former-commit-id: b70272ac5316fe1bee52b9611a1a5ea4d761dd3c
2012-09-22 16:11:23 -07:00
John-David Dalton
1ca26ce676 Ensure methods accepting a thisArg argument allow null values.
Former-commit-id: 368b943687291f0d7ed02304284ac076ef86e02b
2012-09-22 15:39:37 -07:00
John-David Dalton
d8e3e823a7 Removed Underscore's fixed issues from README.md and rebuild docs.
Former-commit-id: 08db54926a791ab32b7e003143ae0f70a251068e
2012-09-20 21:13:36 -07:00
John-David Dalton
473dd7660b Reduce _.reduceRight and update vendors.
Former-commit-id: f7250ccb4b8f15052c1f1420947c2ac68963a92c
2012-09-20 21:06:32 -07:00
John-David Dalton
5afeed56ef Cleanup _.difference and _.union.
Former-commit-id: 1fcaab3989caaaacd9fe73de071d8f360f52b715
2012-09-19 22:15:15 -07:00
John-David Dalton
b91b04f652 Update vendors and add _.reduce, _.reduceRight, and _.where benchmarks.
Former-commit-id: c1b4bc7f8aaf08c429ae918f5d528401f1a66255
2012-09-19 21:40:39 -07:00
John-David Dalton
25de44a23d Cleanup _.template.
Former-commit-id: dc3fa2d02a9a4a2d4034136d2ce7f03d0b67224a
2012-09-19 01:06:45 -07:00
John-David Dalton
00cfb95971 Update vendors.
Former-commit-id: fddaef2be532e30f197f8bdff70dc6ec9bfa3cfc
2012-09-18 23:42:52 -07:00
John-David Dalton
f4ba0e1191 Simplify _.template and remove superfluous caching.
Former-commit-id: f9f18a63a77376471e69c95d5046dfe0146b9887
2012-09-18 23:42:26 -07:00
John-David Dalton
6499643769 Make _.random return 0 or 1 when no arguments are passed.
Former-commit-id: 7d20f5240d534f0091757f613c664b08e0d45759
2012-09-18 20:29:36 -07:00
John-David Dalton
f85287a444 Add "category" options unit tests to test-build.js.
Former-commit-id: 0499317babeb422e88700edd0f1e46c1fa6196fd
2012-09-18 01:22:10 -07:00
John-David Dalton
483bc9ad87 Add unit test to confirm correctly parsing delimiters.
Former-commit-id: 71aa7a240d2becb8082e36f9aa4874eb0aed09d3
2012-09-17 23:49:03 -07:00
John-David Dalton
93b89a93c1 Make _.times return an array of the results of each callback execution. [Closes #73]
Former-commit-id: 808af6b9eb07bf1fada8221ca659558d82e6eb57
2012-09-17 21:48:26 -07:00
John-David Dalton
10064c046c Allow build "plus", "minus", and "include" to accept case-sensitive category names.
Former-commit-id: f74d4cda73195854b3471ddce0afaab099dcfe77
2012-09-16 18:11:53 -07:00
John-David Dalton
a5aecb9d0e Add minus and plus commands to build.js.
Former-commit-id: fcdd2e829de5a6a29ebc342e694b7986d9a5eade
2012-09-16 13:22:26 -07:00
John-David Dalton
de1e889f1d Make lodash underscore build smaller and rebuild docs.
Former-commit-id: 19405bc4e490588d7a55379974d2d7d81d1cf5f7
2012-09-15 19:24:26 -07:00
John-David Dalton
16f89b40c3 Remove issues resolved by Underscore from README.md.
Former-commit-id: 27510827a1e60dd4cf81f5306991e3f63e8cedb5
2012-09-15 08:47:22 -07:00
John-David Dalton
0e387d2cda Remove custom toArray checks in _.toArray and simplify array-like object checks in "Collections" methods.
Former-commit-id: 6b7678de16907f44c1b079a22a6a2e091a638d4b
2012-09-15 08:46:49 -07:00
John-David Dalton
837c15e4f9 Update vendors.
Former-commit-id: 1e93a793891e5f4e2c0d3927f3f38b25bd182263
2012-09-15 08:21:44 -07:00
John-David Dalton
ae7e353169 DRY more code in the "underscore" build.
Former-commit-id: c1dbc3daccb1efba371c38f20b9a4ff96a7171a4
2012-09-14 01:09:02 -07:00
John-David Dalton
6c1bbd2344 Tweak iteratorTemplate formatting and remove more code from "underscore" builds.
Former-commit-id: cbaa8e41a9a60b5828d2c0da7188d483702c55e1
2012-09-13 23:51:52 -07:00
John-David Dalton
27247e8e56 Remove freeExports var when not used via exports build option.
Former-commit-id: 66950af3a18b35412fbe1092e19c5d7ef0c9a029
2012-09-13 19:28:56 -07:00
John-David Dalton
08249d78ea Add RequireJS "shim" test and a build test to ensure the AMD snippet is maintained for r.js.
Former-commit-id: 708c07877cfca0022d6d56c16c36d8bae79e4796
2012-09-13 19:11:48 -07:00
John-David Dalton
827091e522 Remove "lazy" bind from README.md until next version bump.
Former-commit-id: f132182f32670aa7df7ac418f58db0a1fb0f8547
2012-09-13 02:10:23 -07:00
John-David Dalton
13d901bf8d Make the IIFE Closure Compiler regexp in post process more restrictive to work better with the "iife" build option.
Former-commit-id: 999602451e50850eb82680b9c377d97605be8af4
2012-09-13 01:40:28 -07:00
John-David Dalton
e69bdabc99 Rename makeBound to createBound for naming consistency.
Former-commit-id: ec6845badba06231af0b1341b1f1efedb8adbc88
2012-09-13 00:46:47 -07:00
John-David Dalton
e8d19265e4 Cleanup component.json.
Former-commit-id: 0761bb592e5c643223848e2cd7fca0efc5b9c725
2012-09-13 00:10:16 -07:00
John-David Dalton
49e3a49dc5 Update docs, minified, build, and vendors.
Former-commit-id: 8b1425b8c4a5238a42185dfa974bb3b2468eebea
2012-09-13 00:08:52 -07:00
John-David Dalton
82a7c01898 Simplify "underscore" build of _.clone.
Former-commit-id: 32975bb5966f1ded4f007eb76dcf2d4677478e7d
2012-09-13 00:04:53 -07:00
John-David Dalton
c0d7dbf639 Reduce code around _.bind and _.partial, and add _.lateBind.
Former-commit-id: 4c962d066ecfa54882cee2216a7310ab34b3b5a3
2012-09-13 00:04:00 -07:00
John-David Dalton
569caa0bf2 Remove custom isEqual checks from _.isEqual and custom clone checks from _.clone and simply _.clone, _.isEqual, and _.merge.
Former-commit-id: 45e90ab1494e46e281265f660c87e27f59581308
2012-09-12 22:00:23 -07:00
John-David Dalton
f88ea1ee7d Re-order test-build unit tests and make the iife test a bit more thorough.
Former-commit-id: f798639cfa58241b052d16b9ca6fbf4537482349
2012-09-12 08:40:01 -07:00
John-David Dalton
d5a8fa0b97 Update underscore unit tests.
Former-commit-id: ae00a864c7cb3bff9970289917df681ad5e295d9
2012-09-12 08:39:18 -07:00
John-David Dalton
3f8f96edea Add "mobile" build unit test.
Former-commit-id: f067b42618abe6a9f747fea000522de6a9117b3c
2012-09-11 22:30:23 -07:00
John-David Dalton
04fb4aff28 Update underscore.
Former-commit-id: 7041883ef258e3dc80d3c3751a5e4beecf0b4767
2012-09-11 20:15:13 -07:00
John-David Dalton
83c6fb089e Ensure mobile build has properties correctly minified.
Former-commit-id: 61da738afbcefc7ecd277190147041d884002af1
2012-09-11 09:15:32 -07:00
John-David Dalton
9d8d17b964 Update cdn link in README.md.
Former-commit-id: 5da17daf1a6d1d5c9f6e9ba7875f45bd2d763cda
2012-09-11 07:41:47 -07:00
John-David Dalton
39d4842ff5 Bump to v0.7.0.
Former-commit-id: 7c51a310c7c62bfe0ba9a2cdea4e074e633cee70
2012-09-11 02:53:12 -07:00
John-David Dalton
cad8473986 Re-add overwritten _.isEqual unit test.
Former-commit-id: 52d4e3bc02a6fd0ac30177c9da82dec60ee6eb81
2012-09-10 23:41:20 -07:00
John-David Dalton
5f085ccb52 Fix typo in _.isEqual.
Former-commit-id: 9d5065953c51d12f1308dd8c0c142b6505efe765
2012-09-10 23:04:42 -07:00
John-David Dalton
b406246689 Add "iife=.." command to build.js.
Former-commit-id: 85d8c7ea550403663a878f2713ce93ae8c2dbc6a
2012-09-10 22:52:28 -07:00
John-David Dalton
cbe46afdff Minor lodash.js cleanup.
Former-commit-id: 544f2a2690b48b52870b3ab62509221a82ed4173
2012-09-10 21:04:04 -07:00
John-David Dalton
a59d6dc3c7 Add minify.js Underscore unit test.
Former-commit-id: 1db7b19709ef953dd1996a082e73a2ba542f29f7
2012-09-10 20:35:27 -07:00
John-David Dalton
2afb2dd5fd Reduce temporary objects created in _.merge, _.clone, and _.isEqual.
Former-commit-id: e6696642505f39eefdf59075ff8a993ab033465a
2012-09-10 20:12:42 -07:00
John-David Dalton
4fc3c969d3 Add component.json for Bower.
Former-commit-id: d681c2300b4e79fb168793aed34b82c3021647d1
2012-09-10 00:48:12 -07:00
John-David Dalton
1796ce324b Cleanup build.js
Former-commit-id: 6a4502883d7431f5dcedbf7f7d3bfb871ce1c0f4
2012-09-09 23:30:38 -07:00
John-David Dalton
5e04c7f827 Add "output" and "stdout" build option unit tests.
Former-commit-id: 2adcdbff4cd1ef6319e33c69fd5ed3b07b205cfe
2012-09-09 20:33:08 -07:00
John-David Dalton
20fcede440 Add "-o" and "--output" build options.
Former-commit-id: 154c0a6b749ff2439c024602fb9ec781e293f511
2012-09-09 17:26:30 -07:00
John-David Dalton
012c1833f2 Added "-c" and "--stdout" options to build.js.
Former-commit-id: 388c529ca1836ee7cd65517d2e9f8533e480b8cd
2012-09-09 16:33:57 -07:00
John-David Dalton
32e8e03256 Add build "exports" unit tests.
Former-commit-id: afe0fe59933d272bfa597be835011b3c81b28dda
2012-09-09 16:00:11 -07:00
John-David Dalton
dca653cb92 Update minified build and docs.
Former-commit-id: a7719898e67aab04d37e775f4794b0be7a4a2e24
2012-09-09 14:13:18 -07:00
John-David Dalton
0805eca979 Remove Object.keys optimization from the "legacy" build iteratorTemplate.
Former-commit-id: 5a63b627c4982ca43a46a830722513cab2c7b633
2012-09-09 14:11:46 -07:00
John-David Dalton
17935a78ff Make previous _.isEqual fix pass Underscore unit tests.
Former-commit-id: 2b3563bb628b307ad2e4a2ef00ed5afec2f59506
2012-09-09 14:11:07 -07:00
John-David Dalton
e16918ee32 Add "exports" option to build.js.
Former-commit-id: cc1572dbe9d1367f806a44597cbcec8508f51ad6
2012-09-09 13:12:44 -07:00
John-David Dalton
78471b4595 Cleanup test files.
Former-commit-id: 3b138bc74c2f4c2c6d374893c0f90a8422a7248b
2012-09-09 11:55:24 -07:00
John-David Dalton
c30bcdd515 Ensure _.isEqual matches values with circular references correctly.
Former-commit-id: 07968aeb430f56c32aab22dfda919706da840680
2012-09-09 11:54:32 -07:00
John-David Dalton
ac78c5f4e5 Make minify.js support passing minify an array of command-line arguments.
Former-commit-id: fd67d3d6dd8b19c88c74529a33fd50b2fbd0db01
2012-09-08 23:43:36 -07:00
John-David Dalton
57a990ce25 Add "underscore" build test.
Former-commit-id: 8050e285fae94c96e7db1c8847ace45ae5cade33
2012-09-08 19:30:58 -07:00
John-David Dalton
24825b42a2 Cleanup and add test-build to run-test.sh.
Former-commit-id: 29d198ca03dbd23b864a96ea48348fb22728056a
2012-09-08 14:20:46 -07:00
John-David Dalton
4f7323f7fc Add test/test-build.js.
Former-commit-id: b0c28b814dec71095a927469cbbda766fd9fc701
2012-09-08 14:03:21 -07:00
John-David Dalton
a228be85e2 Cleanup compareAscending.
Former-commit-id: c11be9f8211242a8d25a2cd06e20efefa685c3ee
2012-09-07 23:56:28 -07:00
John-David Dalton
fa565bdbdf Hold off on the version bump until test-build.js is finished.
Former-commit-id: a627062b1133cdb5a06a3fd960bbeaddfd0f9a54
2012-09-07 22:00:27 -07:00
John-David Dalton
2dc53223e5 Ensure _.template works with "interpolate" delimiters containing ternary operators. [closes #68]
Former-commit-id: 287df2ef5802ea6db743da5f211e480d6b0f85c9
2012-09-07 21:17:00 -07:00
John-David Dalton
958ac72805 Ensure the internal stack argument of _.merge doesn't pave the 4th argument passed to it. [closes #69]
Former-commit-id: b33e1cb7795294b9481e2c9c6888d0f37419208d
2012-09-07 21:09:21 -07:00
John-David Dalton
f7297b84e7 Tweak text of build.js help message.
Former-commit-id: 755872c9ae5670cc3a33aa158be4478eafacc574
2012-09-06 23:27:00 -07:00
John-David Dalton
9a7d9e7bb8 Ensure _.sortBy is stable for undefined values.
Former-commit-id: bf250150d27de050ea7a6fa376aacdc8d1ba7716
2012-09-06 22:35:20 -07:00
John-David Dalton
fa9df75cf7 Rework build.js to work as a module and add a "silent" mode to minify.js.
Former-commit-id: cf62532b957d37da77a2d64aa64d2d388e6382ae
2012-09-06 22:19:43 -07:00
John-David Dalton
e3ec76418b Update Underscore/Backbone vendors.
Former-commit-id: beb38126acaebf1045c2676aeda037e35f0b99c8
2012-09-06 20:56:02 -07:00
John-David Dalton
102d6d8c84 Capture the result of the last func call in _.throttle and _.debounce.
Former-commit-id: 2e783fad2e86824bf098bdb24ca6911317576f32
2012-09-06 20:49:06 -07:00
John-David Dalton
a742b5f3e2 Rewrite build.js to be used as a module.
Former-commit-id: bf6425925e511a327b5297f9b17620a97ff53b67
2012-09-06 20:36:24 -07:00
John-David Dalton
a2a3bb291f Let build.js handle the "use strict" directive and not minify.js.
Former-commit-id: 741eb692b158e22aa688d6dac1b63fc2787cc426
2012-09-06 00:41:18 -07:00
John-David Dalton
b7c0ac7d67 Tweak test/test-ui.js for QUnit v1.10.0.
Former-commit-id: 6481cce305fb4d69bba22ba2186a30ee13bb2282
2012-09-06 00:40:26 -07:00
John-David Dalton
13b1fc6b44 Remove an unneeded _.object unit test.
Former-commit-id: 2334bda13fbd9bd683b3f650ff47f1a676139319
2012-09-06 00:38:22 -07:00
John-David Dalton
3939fcf6e7 Allow unit tests to run when testing custom builds without noConflict.
Former-commit-id: 2aee7eb872144583df1f22743f5d3f7102d14eae
2012-09-05 07:12:35 -07:00
John-David Dalton
13abbb81af Bump to v0.7.0.
Former-commit-id: 4ab5bfe3bba14182ffe24c05792b3b8f194afa0c
2012-09-05 01:12:57 -07:00
John-David Dalton
019f0153c8 Update alias style in docs.
Former-commit-id: d7b1eb9999f535c365ce3ea6251a359c7d901769
2012-09-04 23:47:27 -07:00
John-David Dalton
8abc2925e0 Fix invalid doc entry in doc/README.md.
Former-commit-id: 64721e5c3417a25b2f34f1f380b0cecc6561fa35
2012-09-04 22:29:06 -07:00
John-David Dalton
996c9a032a Update docs to include method aliases.
Former-commit-id: b93b13a42381ba28b84a3e279d5157673b20fdce
2012-09-04 21:40:29 -07:00
John-David Dalton
22d3794d22 Update vendors.
Former-commit-id: ad3284b1e77cfb0b17af99e0ddaf00618e4485b7
2012-09-04 21:37:01 -07:00
John-David Dalton
ba948a38e9 Ensure to escape exports property for Closure Compiler.
Former-commit-id: 9b6bd1201e74d9e85fbc340bcabce40039239a59
2012-09-04 15:25:47 -07:00
John-David Dalton
e8a522c4df Update README to reflect Underscore patches.
Former-commit-id: b0222d92b90e190c7c322e409ec877ca473f3594
2012-09-04 11:27:23 -07:00
John-David Dalton
c60f3da32e Reduce size of "mobile" and "underscore" builds.
Former-commit-id: 062dc03e3d3dd7a8e1ceb6a8b4ea155394a9b899
2012-09-03 23:20:18 -07:00
John-David Dalton
0c92d3cbb2 Fix how post-compile.js unescapes properties to avoid extra work in pre-compile.js.
Former-commit-id: f604f706af358288877763681243f4816d5cbe9e
2012-09-03 21:40:23 -07:00
John-David Dalton
e4fc8dd6fe Remove older Opera fixes from the "underscore" build.
Former-commit-id: a012ed6957b4d964b5f2dc1a636d7f5f19fbf307
2012-09-03 16:30:55 -07:00
John-David Dalton
1a849e2de0 Update docs and minified build.
Former-commit-id: 62f3293c13d5fa08f857ca455506b4762aa65416
2012-09-03 16:07:46 -07:00
John-David Dalton
ffdd79f86b Adjust how _.template handles compiled syntax errors for compatibility with Underscore.
Former-commit-id: ba84c5b468938a1be1a1fd0afd31cb83f563e1ca
2012-09-03 16:05:47 -07:00
John-David Dalton
e87e46b1b6 Remove deep clone from "underscore" build and fix how invalidArgs are detected in build.js.
Former-commit-id: 5038d1541fa7d0c062e5a48004a60fb9140778d7
2012-09-03 15:42:02 -07:00
John-David Dalton
3ca81a4ff7 Fix Underscore detection in post-compile.js.
Former-commit-id: ad3c5cd28bc9ac0f6c9e5801c3849acd4305c528
2012-09-03 15:40:47 -07:00
John-David Dalton
5477d3c292 Cleanup iteratorTemplate and isPlainObject.
Former-commit-id: a96b8716cfd0efbc46daf2307fae8f1ee5969862
2012-09-03 15:36:18 -07:00
John-David Dalton
08300183b3 Cleanup build.js help message.
Former-commit-id: 36edcf06e78580835f33872f0c72a233604a4adc
2012-09-03 12:58:46 -07:00
John-David Dalton
095c77f22c Inform users of invalid arguments passed to build.js.
Former-commit-id: 1b15dd2242387c7037678a3348931f5430612a8b
2012-09-03 10:50:25 -07:00
John-David Dalton
09926e63a3 Add 4th screencast link to README.md.
Former-commit-id: 07d890b65e7e4ed600173634f04a9783d18bc701
2012-09-02 16:15:56 -07:00
John-David Dalton
87d70f29a1 Make pre-compile.js and post-compile.js support underscore.js.
Former-commit-id: 76d040f630faf03bd5a8eb168259814f5662ba50
2012-09-02 16:11:29 -07:00
John-David Dalton
3a7661b111 Make _chain and _wrapped double underscored to further avoid conflicts.
Former-commit-id: 27f545d99cc383be05509ac7382e42fc727e0215
2012-09-02 12:57:53 -07:00
John-David Dalton
ec976953cd Simplify wrapper inference in _.isEqual.
Former-commit-id: b4fda683ebee4c3f7dddd0cb87201306c08fa7d5
2012-09-02 12:04:35 -07:00
John-David Dalton
1837562b50 Cleanup README.md, update Backbone, rebuild docs and minified build.
Former-commit-id: 8f54e0a4b76cf1a42c11ca37f3e8672a75178d30
2012-09-02 02:44:26 -07:00
John-David Dalton
f3bec4fc37 Ensure optimized isPlainObject works with objects from other documents.
Former-commit-id: 2f782b3dfc19e7ea3274132c31cd408ee2387021
2012-09-02 02:35:02 -07:00
John-David Dalton
c2117ef4fd Add _.result to "backbone" build.
Former-commit-id: c04ddcdbfb229440b19b268d51887bf31ae11296
2012-09-01 14:58:35 -07:00
John-David Dalton
910804ecd1 Avoid arguments object in _.random.
Former-commit-id: 24e54869ae03c0251f419c922f59f53f01b8fa35
2012-08-31 18:03:10 -07:00
John-David Dalton
ce5ae1dfdd Simplify _.size.
Former-commit-id: a7d3338cbd5784ec6b9b6a25e18acd9507f4b21c
2012-08-31 17:58:34 -07:00
John-David Dalton
2c31411ffb Optimize _.pairs.
Former-commit-id: 1de87609a8635fb8d48bc558fbdabc545da53b4b
2012-08-31 15:45:27 -07:00
John-David Dalton
84d69fa2a1 Update resolved issue count in README.md.
Former-commit-id: 41a22ec12d02a1cff5b172022c8260b80c63fe9b
2012-08-31 13:57:23 -07:00
John-David Dalton
2aea296d19 Update minified build and docs.
Former-commit-id: aed499a9ffee5fd7c1f29dad13a8c4e756b431d8
2012-08-31 13:53:04 -07:00
John-David Dalton
2b0bffc362 Ensure template delimiters are tokenized correctly. [closes #64]
Former-commit-id: 814f3f8a840a70a9b455e5f91da0e21174f08787
2012-08-31 13:50:10 -07:00
John-David Dalton
83356142c1 Update README.md with API changes.
Former-commit-id: 4571a2331d433af28ae33813780f8abc9477437e
2012-08-31 13:36:16 -07:00
John-David Dalton
24dcc6947c Update build.js and pre-compile.js for _.invert, _.pairs, and _.random.
Former-commit-id: 0dc281f6e1a07f0a4121f71c37e15a7ca0e18960
2012-08-31 13:35:40 -07:00
John-David Dalton
a7e3136a0b Add _.random.
Former-commit-id: cf720b9187b0b54b43773a9f5f02fb475d786bfa
2012-08-31 13:33:44 -07:00
John-David Dalton
71639cfea7 Cleanup _.times documentation.
Former-commit-id: 59ce4b689bb280650d28944664abd6a38f1c43a0
2012-08-31 13:05:12 -07:00
John-David Dalton
8c2d39fb82 Add _.invert and _.pairs.
Former-commit-id: b265ed3f148e5e951b8d061107bb376e0b2e651e
2012-08-31 13:02:55 -07:00
John-David Dalton
e060d29337 Rename _.drop and _.zipObject unit tests.
Former-commit-id: d68abda2400244b7801eac9ad90de88b2f99a1f4
2012-08-31 12:59:18 -07:00
John-David Dalton
79e9156d2f Make _.drop an alias of _.rest and rename _.zipObject to _.object.
Former-commit-id: 08cb9ec2d5009b9a9f959b2341f8b78f6bbd37a0
2012-08-31 12:57:52 -07:00
John-David Dalton
9100db55b0 Update vendors.
Former-commit-id: 88e9746e94e8ec899227b1a925bea4ab4d373fb0
2012-08-31 12:47:55 -07:00
John-David Dalton
141c10f6fe Ensure noArgsClass references aren't removed for "underscore" builds.
Former-commit-id: 697e2d29d5fef32b0b10d775eee7a12d193ff1a9
2012-08-30 00:58:54 -07:00
John-David Dalton
4613ab9dc3 Update cdn links and tested browsers in README.md.
Former-commit-id: db952c5d72fa9e4d6ce3280574b9e4e26da8c928
2012-08-29 18:03:03 -07:00
John-David Dalton
061ad41b51 Cleanup link hashes in generated docs and update vendors.
Former-commit-id: 278366a7dacea91d965835b24ae7ec046f455110
2012-08-29 08:28:37 -07:00
John-David Dalton
3a0007cd18 Remove pseudo private properties from debug builds.
Former-commit-id: 839c2e47e19ba163f0c69d3c115ec9ee262d5d6b
2012-08-29 01:17:28 -07:00
John-David Dalton
0044917943 Ensure Closure Compiler removes isPlainObject when it's no longer needed in build.js.
Former-commit-id: 748de0f28f4e0733ef83a77fe2b1f6e40e4f8ce2
2012-08-29 00:34:58 -07:00
John-David Dalton
0337c04278 Bump to v0.6.1.
Former-commit-id: 68b59ea3e76d06d60acc81e30770b5899b8ea761
2012-08-29 00:14:40 -07:00
John-David Dalton
4585acf70b Optimize isPlainObject.
Former-commit-id: 37754e27d03929927d8b8653bd7e44ad3ce2b23c
2012-08-29 00:05:02 -07:00
John-David Dalton
2ad9bbae25 Avoid issues in IE with other code containing comments like //@todo xyz.
Former-commit-id: 92ec6258539bf48144e9af05d0e326651a5fedda
2012-08-28 23:58:07 -07:00
John-David Dalton
cf075df7d1 Update cdnjs link in README.md.
Former-commit-id: 50a52807a505d0d559f9977e3b5c9532fa3f131e
2012-08-28 08:58:47 -07:00
John-David Dalton
11cd9905c4 Bump to v0.6.0.
Former-commit-id: 7339c27ba63208f23d94ae4a29dec53a43220bad
2012-08-28 01:47:22 -07:00
John-David Dalton
cf462542e9 Cleanup iteratorTemplate and remove more code from the "underscore" build.
Former-commit-id: 3f4c283f0aa205dbcce1940f7222b594284263c4
2012-08-28 00:30:52 -07:00
John-David Dalton
b63f25a1ae Simplify _.unescape to match the behavior of _.escape.
Former-commit-id: ec7f4cf9a6f44b1ba99f467c47d7e04d5596d76e
2012-08-27 07:54:03 -07:00
John-David Dalton
7de69a21c5 Cleanup unescape comments.
Former-commit-id: 4c0a66d28ed8b04748e4d97755983ec328e53ca4
2012-08-27 02:54:55 -07:00
John-David Dalton
21783e4ea0 Add unescape to the dependency map and exclude unescape from the "underscore" build.
Former-commit-id: 20656e5226207e55713a286c7d7069b73170272f
2012-08-27 02:33:38 -07:00
John-David Dalton
53e5a756d7 Update minified build, docdown, and rebuild docs.
Former-commit-id: f198b30ba8963d8b69838ba31d2e3d8085537629
2012-08-27 02:09:04 -07:00
John-David Dalton
8c911a2fd0 Add _.unescape method. [closes #63]
Former-commit-id: 10eada385fd0e1157271a2da6fb32de047d6d88a
2012-08-27 02:05:37 -07:00
John-David Dalton
ce440e9f43 Add hasObjectSpliceBug to avoid unnecessary use of the delete operator from the mutator Array function mixin.
Former-commit-id: 8e92914f451454323a1ff6ef8ec1886b41e54ced
2012-08-26 12:54:03 -07:00
John-David Dalton
6465f8d8e6 Cleanup docs for _.drop, _.pick, _.countBy, _.groupBy, and _.sortBy.
Former-commit-id: 0dc89937d067c996fd28b585f42c1e01e928441b
2012-08-26 11:41:17 -07:00
John-David Dalton
4bdf28059a Cleanup unit tests, update minified build, and docs.
Former-commit-id: 5bca51894bf2fb01732a1ecc5873711d8abf3f9c
2012-08-26 03:09:19 -07:00
John-David Dalton
21010c6540 Add callback and thisArg arguments to _.drop and _.pick. [closes #62]
Former-commit-id: 990655e9e849348c287b3d994d2e2dc741f78fbf
2012-08-26 03:06:43 -07:00
John-David Dalton
a5a6cabac6 Cleanup createIterator and _.contains.
Former-commit-id: 39d4c33e5af0d9338a1725b5c07332a14f453374
2012-08-26 01:07:36 -07:00
John-David Dalton
f460c77f2c Ensure _.reduce works with string Objects in IE < 9.
Former-commit-id: 0ee3496e52f4c393900f37f03e451b8e4abba206
2012-08-26 01:04:09 -07:00
John-David Dalton
1c69d9213e Update minified build and rebuild docs.
Former-commit-id: e9da1d37b6741caf19c47e8dd81b89df60e8410f
2012-08-25 21:50:52 -07:00
John-David Dalton
c02c2d3b2c Optimize _.intersection, move largeSize default to largeArraySize, and cleanup _.where.
Former-commit-id: 9eaea7922623f1bd69f2b18578468a6fc9ba13fc
2012-08-25 21:50:08 -07:00
John-David Dalton
7adf5e763b Cleanup benchmarks in perf.js.
Former-commit-id: f845855383e01c63d513cea53cec86abb4f4fb65
2012-08-25 20:13:24 -07:00
John-David Dalton
0e4afefc7f Add more _.omit benchmarks and update Underscore.
Former-commit-id: b8de29706b381ebc000a7cbaa19aa0a2a628d6a8
2012-08-25 01:04:33 -07:00
John-David Dalton
c7f290f42e Cleanup unit tests and update ticket reference in README.md.
Former-commit-id: c2433e841c20eb17334d375deabcf0605ed49a3b
2012-08-25 01:00:19 -07:00
John-David Dalton
bb553b8a6a Update whitespace removal for delete operators in pre-compile.js.
Former-commit-id: 8dddeed54f8f13268f777d829ba52363706b9f4a
2012-08-25 00:56:00 -07:00
John-David Dalton
21eda2a1a3 Add _.omit as an alias of _.drop.
Former-commit-id: 630b0897bb49161fbc3b51a38c816b4bce548fba
2012-08-24 09:46:44 -07:00
John-David Dalton
48c13c990f Update vendors.
Former-commit-id: f2a09b6501a34b2ae2d8e996b13c9da4fb048535
2012-08-24 08:26:34 -07:00
John-David Dalton
a2665529f6 Optimize method compilation with/without strict mode.
Former-commit-id: 05e4d9282116987b53a817b406c82c140a25c761
2012-08-23 01:49:44 -07:00
John-David Dalton
8d35d78eff Ensure debug builds work against more build options.
Former-commit-id: 121b3605026d8f936e2ca0e3a03142cb08e75e66
2012-08-22 09:13:50 -07:00
John-David Dalton
a82a364c22 Update dependencies in build.js.
Former-commit-id: 020a52bdd604b55b078637aeb59e2e53483c950d
2012-08-21 21:21:24 -07:00
John-David Dalton
cc150ff9d2 Cleanup test.js and README.md.
Former-commit-id: af3372f58ecf8d979d22c88193589857c06ff7c1
2012-08-21 02:31:40 -07:00
John-David Dalton
feeb38293d Update cdnjs link to v0.5.2 in README.md.
Former-commit-id: e519a03ad9016f8aebd2c703f29bb350bcd442f1
2012-08-21 02:13:53 -07:00
John-David Dalton
5b9271ccfe Add isType benchmarks.
Former-commit-id: 875af51200d60eb6105eb36ab090e9f307a15340
2012-08-21 01:59:56 -07:00
John-David Dalton
e60bbc2fb7 Bump to v0.5.2.
Former-commit-id: 43998ef8cf3cbdb9205d702d950f9f59febc420b
2012-08-21 01:32:41 -07:00
John-David Dalton
387cc184e6 Keep test count consistent for Node.js.
Former-commit-id: ca0452ff4511c946946a2208b44471b1e2c6fc43
2012-08-21 01:31:54 -07:00
John-David Dalton
a830ddcb43 Cleanup perf/index.html.
Former-commit-id: 7592ee8ec0c6b2bb85d93d7dc599d814ef5a1eef
2012-08-20 22:46:35 -07:00
John-David Dalton
35fea30191 Cleanup string tests and add string test to _.toArray.
Former-commit-id: 3565f7233f1f7662604e3b8e1f07eead62349454
2012-08-20 22:45:57 -07:00
John-David Dalton
24b672b968 Update vendors.
Former-commit-id: 4ccda4fafe86514cdb45d191cb743baca9b1baa4
2012-08-20 22:43:43 -07:00
John-David Dalton
de6a3c5ab1 Switch order of performance.now check in perf/index.html and convert benchmarks to strings in perf.js for better compatibility with older browsers.
Former-commit-id: d766316c9c162e31dd0471d80b50ecfd1da2c9a8
2012-08-19 23:45:16 -07:00
John-David Dalton
260ff6de3e Avoid using the nano applet in perf/index.html if it isn't needed.
Former-commit-id: 342983337140dd5608848b7f09d24038ea61d1a1
2012-08-19 15:35:38 -07:00
John-David Dalton
7cb37411c9 Ensure _.template won't error when passed falsey values, add _.template documentation, and DRY out tokenizeEvaluate.
Former-commit-id: b575de8bf968c2fc2655eadff0a09bcbff1e1753
2012-08-19 13:34:58 -07:00
John-David Dalton
e4e41e5ef8 Cleanup _.template docs and generate less unused code in compiled templates.
Former-commit-id: e6703414b83e9286d9ce5e14214375bbbaf9285f
2012-08-19 02:13:43 -07:00
John-David Dalton
985f4aafca Update minified build and rebuild docs.
Former-commit-id: 0c2c5769a94c0591359fcc7d0ae55ccfe975c38b
2012-08-18 21:44:35 -07:00
John-David Dalton
0c25dd44b3 Ensure _.isElement uses strict equality in its duck type check.
Former-commit-id: 6348026ebdc219ef1df9926aca1d8df66e472de9
2012-08-18 21:41:29 -07:00
John-David Dalton
285f0bc6dd Ensure isXYZ methods return boolean values and almost all methods allow falsey arguments.
Former-commit-id: a842eaf2fd262bed03df4a71b560b91801b7a75f
2012-08-18 20:52:31 -07:00
John-David Dalton
07a370fd24 Update cdnjs link to v0.5.1 in README.md.
Former-commit-id: 3c00694a949b4f30be48a898f1f2a9046b2573d1
2012-08-18 10:02:38 -07:00
John-David Dalton
95f07ea38a Add stable-sort note to _.sortBy documentation.
Former-commit-id: 17b9818baa6ff72ce5762ec8b3cc01bbac8725bb
2012-08-18 03:40:42 -07:00
John-David Dalton
2890b92b21 Tweak to _.bind unit test for Narwhal.
Former-commit-id: 5df60a9d1e46b09253151ab39281c5af0c48544f
2012-08-18 03:37:43 -07:00
John-David Dalton
8b80c5d0b5 Bump v0.5.1.
Former-commit-id: 09922fa2e936e0b112100690a04d6437131904a8
2012-08-18 02:20:30 -07:00
John-David Dalton
04425786a1 Ensure _.bind correctly appends array arguments to partially applied arguments.
Former-commit-id: 4fdb100f83ff9a0eafcba3f5bf91872748205595
2012-08-18 02:11:40 -07:00
John-David Dalton
15b14e12e2 Change to triple-backtick code fences.
Former-commit-id: 81d38ed0155734a72d98b2e16425635da907aa01
2012-08-18 00:04:17 -07:00
Mathias Bynens
b328972c4d README: Switch to the triple backtick syntax for highlighted code blocks
Former-commit-id: c4fba0c9cf7e8b0fdfc846260b148ecd327c0a1f
2012-08-17 19:31:03 +02:00
John-David Dalton
da3156047f Update minified build and rebuild documentation.
Former-commit-id: ab353b4c73c47b51144f5a917aeb53682b40552e
2012-08-17 08:17:14 -07:00
John-David Dalton
f9f08ba54f Optimize isPlainObject use in _.clone.
Former-commit-id: 7bb48bc5f9276c730f947b6e75b6fba4588f17c1
2012-08-17 08:16:31 -07:00
John-David Dalton
b43684262f Cleanup _.template documentation.
Former-commit-id: 7b45705bd8a4661dbf824912798ccba15e5ed989
2012-08-17 04:05:50 -07:00
John-David Dalton
2120f78bd7 Fix typos in README.md.
Former-commit-id: fb31a291a3afe799d2e9809f17420eda10888250
2012-08-17 02:54:19 -07:00
John-David Dalton
2d896f22d6 Bump to v0.5.0.
Former-commit-id: f30f4b99104c94fb52df4c90dcda24b8ac51432c
2012-08-17 02:28:42 -07:00
John-David Dalton
9fa0aebfe9 Add check for V8 bug #2291.
Former-commit-id: 245f156a2ce1ee92c8f8f8f34b9891ba4eff0d23
2012-08-17 02:12:17 -07:00
John-David Dalton
2ddc3af5ff Fix jQuery/MooTools DOM collection unit tests in IE6.
Former-commit-id: b9c3dbcffb28b0088018614e21fbe313b0d53713
2012-08-17 00:25:52 -07:00
John-David Dalton
fd80e096ea Remove noArgsClass check from isPlainObject.
Former-commit-id: bab7a68e8eaa21679b33b2ab70a9f8e47758ebc1
2012-08-17 00:10:03 -07:00
John-David Dalton
fab2d69fce Ensure _.sortBy performs a stable sort. [closes #59]
Former-commit-id: 09c5ff85ef0f1d054579ec4260a7f76d9c0da281
2012-08-16 23:24:59 -07:00
John-David Dalton
83d08e3aba Avoid false positives for arguments objects in IE < 9 when using isPlainObject.
Former-commit-id: 19e5a6efed32f26d0c908771eec40e7fb2ecf265
2012-08-16 22:22:08 -07:00
John-David Dalton
bfea6bcacf Maintain up-to-date minified underscore-min.js and use in perf tests.
Former-commit-id: 6317df872bd6136d81763d27a62a444f6e392537
2012-08-16 21:21:48 -07:00
John-David Dalton
feff34b021 Update vendors.
Former-commit-id: 44c2fe9fbfbf50aa64663d46b45d6fd2c778f2b7
2012-08-16 21:20:54 -07:00
John-David Dalton
79fbade92a Minor unit test cleanup.
Former-commit-id: 3243247d9da53f3a12cd19bec822bb43eb7f315e
2012-08-16 21:20:05 -07:00
John-David Dalton
bf508e453e Remove unused funcClass variable from compiled functions.
Former-commit-id: f47b8e412b5151e69a3ab78f03243c461b5ab072
2012-08-16 21:19:47 -07:00
John-David Dalton
47b51c22fa Ensure build tweaks are applied when new lines break up specific patterns.
Former-commit-id: 085a837521750457db9f20f3701984cba24a4f4f
2012-08-14 23:15:04 -07:00
John-David Dalton
ebd16105f2 Detect and remove additional unnecessary brackets from template strings during the build process.
Former-commit-id: 0b9786e7d41497fd1627e31401a5e7e0926eea9c
2012-08-14 00:12:27 -07:00
John-David Dalton
01fb1a5775 Optimize _.isFunction.
Former-commit-id: 0aaaa6d166c7eea94237388d61a11c6d183cbe1f
2012-08-13 23:11:01 -07:00
John-David Dalton
b8c2a05db9 Add strict comparison note to _.intersection and _.union documentation.
Former-commit-id: 47792d96e77fdeb6f00db1e4d30b41a6f1a59dbb
2012-08-13 07:37:26 -07:00
John-David Dalton
4087dc5fe4 Reword unit jQuery/MooTools DOM query collection unit test.
Former-commit-id: c80673f799ce6f1449d043eabf76fd6970a70b77
2012-08-13 00:45:38 -07:00
John-David Dalton
408029e6e0 Don't expose _.forIn or _.forOwn if underscore build modifier is present and include doesn't contain forIn or forOwn.
Former-commit-id: 6ebd0bc61d3ae6e2d0506fe72dd22ed59c601c70
2012-08-13 00:44:37 -07:00
John-David Dalton
23ff403529 Update vendors.
Former-commit-id: b239f365c9d8e012bf20525167e6d1a412ce828e
2012-08-12 22:33:27 -07:00
John-David Dalton
be4f81f584 Remove more unnecessary brackets from template strings during the build process.
Former-commit-id: c8e3dfe7d34f9c61fff75512fb4587a987bdf49f
2012-08-12 21:41:41 -07:00
John-David Dalton
361c91e610 Add support in _.isEmpty and _.size for jQuery/MooTools DOM query collections.
Former-commit-id: dc834256d09d7a3f2797ba65690961aad00717bf
2012-08-12 21:40:46 -07:00
John-David Dalton
2aa2ea9675 Fix edge issue with Opera 10.53-10.60.
Former-commit-id: 60014a8e3855bcbf0e4c6f47461123cacafcf668
2012-08-11 21:47:04 -07:00
John-David Dalton
e084225edf Cleanup .npmignore and ensure perf.js will work in the package.
Former-commit-id: e03213fba34c38af2be9003f5be4837d293198e1
2012-08-11 21:36:14 -07:00
John-David Dalton
9ce342205b Add Jam package support.
Former-commit-id: 399caeea73fc79dd340baa7e34b46179ff2beb86
2012-08-11 21:35:06 -07:00
John-David Dalton
0edf50e00e Update edge links in README.md to v0.5.0-rc.1 tagged links.
Former-commit-id: 1f9fea70c6608d980cc8c8fd7d0a39764cf14fa2
2012-08-09 00:24:53 -07:00
John-David Dalton
1ea19daad9 Clear the func variable in _.once so the function may be garbage collected.
Former-commit-id: 521a9d997cb206a5c468b30e5dfa8e096e1a13d5
2012-08-09 00:16:35 -07:00
John-David Dalton
32b302314e Add doc links to the change log entry in README.md.
Former-commit-id: 3c6c79de33331f14af2d5d2c64d1286c67bfb774
2012-08-07 08:20:00 -07:00
John-David Dalton
ee197e02a2 Updated tested environments and resolved issues in README.md.
Former-commit-id: 7d8cc17bad215d87c8c11210d58e1927c5766145
2012-08-07 08:04:46 -07:00
John-David Dalton
7cd6ffec2a Bump to v0.5.0-rc.1.
Former-commit-id: f5a29fd34de5aced3287413f40a0a36226465c84
2012-08-07 00:47:15 -07:00
John-David Dalton
0077580838 Fix failing unit tests in various browsers.
Former-commit-id: 9b5c6e82e0dfed79c505f41b66030ede81ca9a1c
2012-08-07 00:17:04 -07:00
John-David Dalton
4d85a79fd1 Add note about Chrome extensions to _.template.
Former-commit-id: 97b5220ebc3dbbd30b0e52f6c804b449b8d451ca
2012-08-06 08:03:54 -07:00
John-David Dalton
a35139bb61 Fix typo in test-ui.js.
Former-commit-id: 95057e80cfac9d7d776170d66f2c2bfdd364944f
2012-08-06 02:02:23 -07:00
John-David Dalton
f72b833724 Ensure _.keys works with arguments objets cross-browser.
Former-commit-id: 1238c9efcfc13a420804c26c5edee1e4aa5a4238
2012-08-06 01:51:47 -07:00
John-David Dalton
0e16bac6e2 Rebuild documentation.
Former-commit-id: d24c2fb65a54b018da9ad08aa3a67363a31c1122
2012-08-05 23:38:23 -07:00
John-David Dalton
e17564b362 Add unit tests for exiting early from _.forEach, _.forIn, _.forOwn.
Former-commit-id: 18d55054989d3b55afce1f4d604cd274eb9289c8
2012-08-05 23:09:05 -07:00
John-David Dalton
90b66eddf5 Add _.keys unit test for arguments objects.
Former-commit-id: dd90a9d3dc973a6ea8dce0c10ad511cce82097dd
2012-08-05 22:37:43 -07:00
John-David Dalton
2862a5849f Document how _.each, _.forIn, and _.forOwn may terminate iteration early by explicitly returning false in the callback.
Former-commit-id: e218eae83de880deecf1e45d32ca019efd25b548
2012-08-05 00:29:18 -07:00
John-David Dalton
7e839231ed Add iteratesOwnLast bug check.
Former-commit-id: fcc42a42f08e60acc1252ec06b045cfee17bd020
2012-08-05 00:09:00 -07:00
John-David Dalton
fa56a4bb73 Cleanup build.js and update dependencies for _.clone, _.isEmpty, _.isEqual, _.merge, and _.size.
Former-commit-id: df19990609a3dd8432694798149a5eb5bda142c4
2012-08-05 00:02:33 -07:00
John-David Dalton
dff950748c Fix the build to work with _.merge.
Former-commit-id: cb1d9897b97b357197bb6933c65f4afbecea1aea
2012-08-04 17:13:09 -07:00
John-David Dalton
b7374e3f8e Ensure merge works with sources containing circular references.
Former-commit-id: cb3301868299c4e4d32a3d3608199e4269d951ec
2012-08-04 17:12:25 -07:00
John-David Dalton
4244b92b08 Update minified build and rebuild docs.
Former-commit-id: f80bacba89ab171aae61d5ce7269e8507117bffa
2012-08-02 00:33:39 -07:00
John-David Dalton
4f688028ad Update vendors.
Former-commit-id: d1dd2ecf337cf8cda71e0da2af0647813b8de24a
2012-08-02 00:32:15 -07:00
John-David Dalton
5a9a18501d Add _.merge.
Former-commit-id: e393655b1fa41c8eb6ae1b925f456aa05231078a
2012-08-02 00:28:19 -07:00
John-David Dalton
896b8f7cf1 Remove noNodeClass from "mobile" and "csp" builds.
Former-commit-id: 0773f7b1c1ea637d0d519a3015d1534863a9be11
2012-07-29 23:54:52 -07:00
John-David Dalton
95bd1b014f Rework the noNodeClass inference to detect the JScript quirk too.
Former-commit-id: 3a6b73509490d7e87d2322fe1c09890f5f6b57ea
2012-07-29 23:48:07 -07:00
John-David Dalton
dbdf8642bb Rebuild documentation and update the minified build.
Former-commit-id: c4d4281f16250f50ea4d5337a53acceedd2ce660
2012-07-29 14:18:05 -07:00
John-David Dalton
c3cd9007d2 Add unit tests for _.where.
Former-commit-id: 5247bba20d7aa772867e29def99221faea376db1
2012-07-29 14:17:34 -07:00
John-David Dalton
8079fb5bc5 Reorganize and cleanup code for _.where.
Former-commit-id: 769dfafc1701c5ebc2d351abeb729ca6fcfa12e9
2012-07-29 13:49:23 -07:00
John-David Dalton
80d0b5d4ed Add _.where. [closes #22].
Former-commit-id: dec7a9d0df4158a395ec84fb9e774ed20205d421
2012-07-29 13:48:21 -07:00
John-David Dalton
86bd847bf9 Ensure _.isEqual works correctly for objects from another document and add _.clone benchmark.
Former-commit-id: b1ef745ec6c24e8ea0c8fae304ead80c60dfd5aa
2012-07-29 00:58:23 -07:00
John-David Dalton
943004844a Ensure the callback of _.filter can't modify the resulting value.
Former-commit-id: 6652dc5926390e8418b524c7ffd2347c2fa65c82
2012-07-26 23:24:17 -07:00
John-David Dalton
4ff12e0426 Fix recent typo in isEqual.
Former-commit-id: 84cdf90de59c8184a0ac1f78704f61dcc88c91f1
2012-07-25 01:35:56 -07:00
John-David Dalton
0d7bdb6fa8 Make _.range coerce arguments to numbers.
Former-commit-id: 5408800fef0bc8a418c298a112049232b6d85e78
2012-07-25 01:32:28 -07:00
John-David Dalton
6d488b6a81 Update minified build and rebuild documentation.
Former-commit-id: 5f0ea311b51723c225774d735f67fc58f55a4d6e
2012-07-24 02:15:20 -07:00
John-David Dalton
f1d0263ffa Add csp Content Security Policy build.
Former-commit-id: f922046de5150c098eb7f6d3b6901552117631e7
2012-07-24 02:13:31 -07:00
John-David Dalton
24035caadb Keep objects in the stack array of _.isEqual in case a cyclical object is used in a sibling property.
Former-commit-id: 33ffcec837322f4d479f64f9ec6b14184bf5f7a2
2012-07-24 02:13:07 -07:00
John-David Dalton
ed89a3e0f8 Check for custom isEqual methods in _.isEqual before other comparisons and add cross-browser support for arguments objects.
Former-commit-id: 56e40f670309aeb0dcda7868c8aa84b5909db1f1
2012-07-24 01:45:34 -07:00
John-David Dalton
7088ab89f1 Add deep clone support via the deep argument to _.clone.
Former-commit-id: d4fad45364489efb957d29e201846e8c1875b9ed
2012-07-24 01:41:38 -07:00
John-David Dalton
d4688bd76b Adjust _.wrap docs and rebuild/update the minified build/docs.
Former-commit-id: b33c4489bde49c98e7e161d0f831e07388a9da22
2012-07-20 03:22:13 -04:00
John-David Dalton
befe0fccaf Cleanup _.isEqual comments and ensure _.isEmpty/_.size detect arguments objects correctly.
Former-commit-id: 75b044d27b990d55393bf27234aad6ce369f6abe
2012-07-20 02:06:13 -04:00
John-David Dalton
a192410498 Remove Narwhal link from README.md.
Former-commit-id: b8bd53c9a19ef18480db14cfa82545aa872416b1
2012-07-19 09:15:04 -04:00
John-David Dalton
d43ede3a11 Update vendor/underscore and backbone.
Former-commit-id: 614926653b0b1669f8a5533666adb0aecbd46c03
2012-07-19 01:32:47 -04:00
John-David Dalton
9848ffb77f Add _.countBy and related unit tests, benchmarks, and documentation.
Former-commit-id: 915eaf414883a1dc344a558b08c7a1337ab5a225
2012-07-19 01:29:51 -04:00
John-David Dalton
7487497d1f Update minified build and rebuild documentation.
Former-commit-id: e674d7a30c1e5745b0acf90e38aa5757b15a3423
2012-07-18 04:52:13 -04:00
John-David Dalton
be11c848f4 Add "underscore" build.
Former-commit-id: 44e9f4543631cbf342ae7571cf540214623352db
2012-07-18 04:51:08 -04:00
John-David Dalton
9836b274b9 Add _.drop, unit tests, and cleanup documentation for _.extend, _.defaults, and _.pick.
Former-commit-id: a45b0c45d52fdbe5f71984412d631f3dfe87965b
2012-07-18 03:55:16 -04:00
John-David Dalton
a96d14566f Add Underscore ticket reference to Fix cross-browser object iteration bugs bullet in README.md.
Former-commit-id: 9814daf6b81f1c60b3c6681c10c1fc7b94ac61b8
2012-07-18 02:15:16 -04:00
John-David Dalton
1c8cd8c168 Ensure reEvaluateDelimiter is assigned an initial value if evaluateDelimiter is undefined by default. [closes #52]
Former-commit-id: 6cefeeca164901e611009ce1413e5080027592c9
2012-07-18 01:53:15 -04:00
John-David Dalton
5f5806a98e Update CDN link and rebuild documentation.
Former-commit-id: 32210baffaed31b7fb4daed58a0c0a4f22daf4f0
2012-07-17 01:41:21 -04:00
John-David Dalton
624b045ac0 Add unit tests and code comments for the conditional compilation patch.
Former-commit-id: 557aa43dc7c8db738452a9f3afb8ff2aadf8061a
2012-07-17 01:39:51 -04:00
Jay Phelps
0f8bae950e Ensure running in IE if concated with other files that enable conditional compilation /*@cc_on @/`.
Former-commit-id: cf2d9c01ce92b8b85149116d48145bc4342471a4
2012-07-16 20:07:55 -04:00
John-David Dalton
fcede42903 Add Unit testing video link to README and minor cleanup to build.js help text.
Former-commit-id: 504b69acede1bb4759ba942d01dfd0b899715f00
2012-07-16 18:28:34 -04:00
John-David Dalton
5defe7d975 Bump to v0.4.2.
Former-commit-id: 48638d63970b9d4300661620b881ea34854d24d2
2012-07-16 14:34:48 -04:00
John-David Dalton
7e79903fe8 Update tests to work around QUnit 1.9.0 bug in Narwhal/older-Firefox and add platform.js to test/index.html.
Former-commit-id: eed8246c795735558ba9f499b86f08ed3970ccaf
2012-07-16 13:58:36 -04:00
John-David Dalton
a2fa52504c Ensure stringClass isn't stripped out when needed for certain builds and update dependencies for arrayClass, funcClass, objectTypes, and reNative.
Former-commit-id: 334973dcab4660733e1d081efe3602a167c452d9
2012-07-15 07:01:44 -04:00
John-David Dalton
2629f85e73 Update minified build and rebuild documentation.
Former-commit-id: 5b434ca8c22a44d1603dcc1e92bf4caea6fe00a1
2012-07-15 03:52:22 -04:00
John-David Dalton
8577816234 Add optimizations for large arrays to _.difference, _.intersection, and _.without.
Former-commit-id: 26d55a6a3340e77b5269b2003d20def3fe77bca9
2012-07-15 03:51:28 -04:00
John-David Dalton
e58d47a3b2 Add "strict" build.
Former-commit-id: fcdd8d36c9e0c6d698059541b97915ae1b28650e
2012-07-14 08:59:50 -04:00
John-David Dalton
c9c83ee7e6 Add _.invoke benchmark to perf.js and a link to the compatibility changes wiki entry in README.md.
Former-commit-id: 51296709ea8d9dd6e951530b9874b90af3c764a2
2012-07-14 06:21:59 -04:00
John-David Dalton
139693dce6 Optimize benchmark setups, cleanup perf/index.html, and add platform.js.
Former-commit-id: 228b7b6fd230638f9ec8c79eafa56506fc84b79a
2012-07-14 04:51:50 -04:00
John-David Dalton
f98193d822 Poll until Firebug-lite is loaded.
Former-commit-id: c568ed963fc5716c2c84d63aba45a8ef258c1e7b
2012-07-13 14:41:21 -04:00
John-David Dalton
8052f1ac9d Revert unstable Closure Compiler.
Former-commit-id: 81716f0c269ac8a5befbf584c0dc964777cc1e1a
2012-07-13 04:33:50 -04:00
John-David Dalton
4f78a06993 Add _.isEqual benchmarks.
Former-commit-id: 5b3ee06ea3f31f10e8fac96da8766cc1c4c2d3bb
2012-07-13 04:17:38 -04:00
John-David Dalton
6c4b4b392b Avoid expensive test setup in perf.js.
Former-commit-id: f1c1ed41cb86c83aba2c3f7da1dedf6a280221ad
2012-07-12 18:19:23 -04:00
John-David Dalton
268fe34238 Update Closure Compiler.
Former-commit-id: bfdbe43546f3861cbeaaa99644af68e95f2175d5
2012-07-12 16:54:17 -04:00
John-David Dalton
cc620205d6 Control "use strict" directive use in builds.
Former-commit-id: 66a9bdee5cc61710d7d42d685feba616ec855322
2012-07-12 16:25:30 -04:00
John-David Dalton
f0d7c97b7b Update test-ui.js to better integrate with QUnit 1.9.0.
Former-commit-id: 7e6083ebb54fde0ebaa9f4f4551bb190e602a370
2012-07-12 15:48:52 -04:00
John-David Dalton
660a6e9e4c Update minified build and rebuild documentation.
Former-commit-id: 6e747961d3d756d016a27b530bf961841a93bd00
2012-07-12 15:27:25 -04:00
John-David Dalton
3386c2a7a5 Avoid enforcing strict mode in _.defaults, _.extend, and _.bindAll and add benchmarks for _.bindAll and _.functions. [closes #45]
Former-commit-id: 1bb0b5155d3ae46052b4a06cb538dff307e8ec5e
2012-07-12 15:25:18 -04:00
John-David Dalton
9530efb4d4 Update vendor folder.
Former-commit-id: 363508c8d79afa1ec8c1aba48b5be58a8a572367
2012-07-12 13:32:48 -04:00
John-David Dalton
4293515b3d Add help and version options to build.js.
Former-commit-id: 95a9fdaa7a00550922e71ce01a3f742b845d082c
2012-07-12 13:31:42 -04:00
John-David Dalton
61105e0679 Cleanup inline documentation.
Former-commit-id: 1fa95d45c2c3d1fe50f5827f4743aad3c8b75f95
2012-07-12 03:27:15 -04:00
John-David Dalton
79a289c7e2 Update CDN copy link.
Former-commit-id: 4d0d26292eef227f343f6b482856482f8f554a43
2012-07-12 02:06:55 -04:00
John-David Dalton
46781e7614 Bump to v0.4.1.
Former-commit-id: ef73c95edc22d59412affba898d9820251c06b5b
2012-07-12 00:47:24 -04:00
John-David Dalton
1f3546a9f6 Cleanup pre-compile.js and build.js removing more unused vars missed by minifiers.
Former-commit-id: 198715b39ced1a33bd55109099af462ae96a7188
2012-07-11 23:37:12 -04:00
John-David Dalton
0dc88bb412 Fix template regressions. [Closes #44]
Former-commit-id: 15e98d86c290fea74780822b49b5d71e54064e01
2012-07-11 22:46:16 -04:00
John-David Dalton
971a26c123 Remove noArraySliceOnStrings from the mobile build.
Former-commit-id: 943f907672f211be4f3d1c2e8fe8d5769a0a569e
2012-07-11 12:48:37 -04:00
John-David Dalton
0976a3b721 Bump version to 0.4.0.
Former-commit-id: e3606a629e44711ad9174ac7c6690f2a53f088b9
2012-07-11 11:59:04 -04:00
John-David Dalton
d496361555 Fix failing unit test in Opera < 10.52 and add _.toArray benchmarks.
Former-commit-id: 0ed6d5c52b2486be4ccc212da7bbc7cb6d67cf7f
2012-07-11 11:29:44 -04:00
John-David Dalton
60ed65a73a Add utf8 encoding to the generated minified file in minify.js.
Former-commit-id: 2765e28a177ae2703d3b1a6328a35cf5c92fa6ef
2012-07-11 05:54:19 -04:00
John-David Dalton
d1407b3bd0 Add unneeded vendor folders to .npmignore.
Former-commit-id: 7be56b8081be64d41cc66914dce577695d9d0747
2012-07-11 05:40:25 -04:00
John-David Dalton
5ca2da76df Make build.js work as a npm executable.
Former-commit-id: fff327957854aa85a5abfe80994b59f3d0d24370
2012-07-11 05:39:30 -04:00
John-David Dalton
2ac887ff74 Make compiled templates more debuggable.
Former-commit-id: aba1aa3efcea6695632aae0eb61148aa3174debd
2012-07-11 01:52:50 -04:00
John-David Dalton
cbdc9c0be1 Make _.contains work with strings similar ES6 draft String#contains.
Former-commit-id: 3cfffdcddec3e1e8175da95043ec86ac3c6a85fe
2012-07-11 01:11:25 -04:00
John-David Dalton
b9bade8d5a Remove unused UglifyJS file.
Former-commit-id: cfefdb6796583cc55a16ce02533541e6395e4356
2012-07-10 23:22:01 -04:00
John-David Dalton
eb43786641 Cleanup unit tests.
Former-commit-id: 460ffc3bd38c98dd86fc8c74d4720eed5d50433d
2012-07-10 22:04:40 -04:00
John-David Dalton
0515db3d7c Add more false values unit tests for _.size and "Arrays"/"Collections" methods.
Former-commit-id: 475941321404ceec4eabb56fb9ee10855a653e12
2012-07-10 21:41:38 -04:00
John-David Dalton
db257778c0 Update vendor folder.
Former-commit-id: dde7c53eee254e2f50608e65540893764ab8d9cb
2012-07-10 18:14:15 -04:00
John-David Dalton
3b37d7489f Add legacy build info to README.md and rebuild minified file and documentation.
Former-commit-id: 83560976f173a3c797128b08fb184cc7c1e77319
2012-07-10 01:27:07 -04:00
John-David Dalton
329c7e8e05 Add custom-debug build to unit test runners and add unit tests for passing strings to "Collections" methods.
Former-commit-id: cb6c66d01a9f30908a27e689f8ffba5fa9f04299
2012-07-10 01:06:06 -04:00
John-David Dalton
fad9b4fa72 Add support for strings in "Collections" methods.
Former-commit-id: 1abb252101d20c9a01291f4cef19db8a7eeda743
2012-07-10 01:05:22 -04:00
John-David Dalton
c1a81279ed Rename test/ui.js to test/test-ui.js and add to .npmignore. [closes #40]
Former-commit-id: 80165ec342e8b833a28bbe66f59e074c8f4f5185
2012-07-09 07:54:35 -04:00
John-David Dalton
8bb35a17d2 Allow different builds to be tested more easily with a dropdown menu.
Former-commit-id: a692bda9708523aa0443acb35dd8fcc5a342ef3f
2012-07-09 03:56:43 -04:00
John-David Dalton
36415054ea Update minified build and documentation.
Former-commit-id: fc680301b9ae378139e5174e48eb8e4708fddba0
2012-07-08 18:10:10 -04:00
John-David Dalton
3e84cbae69 Add removeKeysOptimization function to build.js.
Former-commit-id: ce13e7b7a1f12199cdddcccbf0b7e0d98d6438ec
2012-07-08 18:08:41 -04:00
John-David Dalton
f5f2bf7f46 Cleanup iteratorTemplate and optimize methods that use mapIteratorOptions.
Former-commit-id: a0f876250a1c7875745e9080bf75546e16fbf6e7
2012-07-08 10:05:04 -04:00
John-David Dalton
acb6656958 Update minified build and documentation.
Former-commit-id: 19462dc946eca093f4265620b8e063b8c162c27d
2012-07-08 03:40:51 -04:00
John-David Dalton
9d70d7c27e Fix _.sortBy in the mobile build attempt two.
Former-commit-id: 8f54b16a901acc4ce91f071c5b36c632334f7dde
2012-07-08 03:39:38 -04:00
John-David Dalton
648a6afb25 Add object iteration benchmarks for _.filter, _.find, _.groupBy, and _.map to perf.js.
Former-commit-id: dc30e2c0e4f88b2a0164f02bf3bf92fd40a87012
2012-07-08 03:31:40 -04:00
John-David Dalton
57ae1925b1 Fix _.sortBy in the mobile build.
Former-commit-id: 0af3778e89e61effbe60347d6f0bcb33d8c37a2e
2012-07-08 03:30:16 -04:00
John-David Dalton
d49318582f Adjust how "mobile" build is created and add first pass at "legacy" build.
Former-commit-id: 740cc40c21d33353f34796ae6da3bc8ce015ab6c
2012-07-08 03:28:18 -04:00
John-David Dalton
83e3f830e6 Rename useNativeBind and useNativeKeys to isBindFast and isKeysFast.
Former-commit-id: 9f001b030dc49146b177678443406720c436ac0b
2012-07-08 02:47:01 -04:00
John-David Dalton
04d4353c0f Optimize object iteration using Object.keys where faster than for-in loops.
Former-commit-id: 8826f75cf6eaf4233758684e3aae2ccdc3c9f262
2012-07-08 02:04:57 -04:00
John-David Dalton
6d217fc097 Add propertyIsEnumerable check to _.keys.
Former-commit-id: 1dcd532d29b3e99ce54a18f4489c766652d56d83
2012-07-06 14:14:44 -04:00
John-David Dalton
9d7136c63c Add more checks to the reComplexDelimiter regexp.
Former-commit-id: 87fba2813619882d388261a1226e75503ec9b8d0
2012-07-05 15:04:09 -04:00
John-David Dalton
51a679d60a Add _.template unit test to ensure complex "interpolate" delimiters work.
Former-commit-id: bdfdbf00b1a1838e104919214012a9cfb39dda19
2012-07-05 13:19:45 -04:00
John-David Dalton
7d4d28614a Remove more unnecessary code from custom builds.
Former-commit-id: 7df2ebc805072456b9f0565a0a33fc1bcf2a4049
2012-07-05 11:51:40 -04:00
John-David Dalton
c75cfaf692 Update minified build and documentation.
Former-commit-id: 401c87b9755301440d2c86f7bfe618cc68db7e1e
2012-07-05 11:29:28 -04:00
John-David Dalton
fe6aa8a6fc Further optimize _.template by controlling how the with-statement is inserted.
Former-commit-id: a62331e771302f9390d5aca04f878b839fe11b69
2012-07-05 11:28:41 -04:00
John-David Dalton
a5fe1eb5fb Optimize how with-statements are inserted into compiled templates.
Former-commit-id: aabb0b1f8c6e910532464b7a007767801c00a640
2012-07-04 20:07:25 -04:00
John-David Dalton
5afd37c92c Update package.json and .npmignore to allow build.js.
Former-commit-id: 782a448163baa27275ca87da209db53441bdcb08
2012-07-04 20:06:35 -04:00
John-David Dalton
293d0409c6 Remove Cloning this repo from the README.md.
Former-commit-id: 4f95f8b9a6781b5b6207a95082415f97e4d4236b
2012-07-03 12:06:14 -04:00
John-David Dalton
4352f18dd3 Cleanup perf.js.
Former-commit-id: 53285a24dcb27857a05b07aa7a6a8840026f8c42
2012-07-02 17:59:09 -04:00
John-David Dalton
0ae7fe9df5 Add non-submodule vendor directory.
Former-commit-id: 392cdade55487e774e959013d8d25ae0b1dfe93b
2012-07-02 15:35:36 -04:00
John-David Dalton
5048f0422d Delete vendor directory.
Former-commit-id: 3d866435290966ec2f0d00561dcd99d0dfad29e0
2012-07-02 15:31:27 -04:00
John-David Dalton
c46a36f8ed Remove submodules and cleanup repo.
Former-commit-id: f3950601f2001ceb4f36db2a7f2efa28acc8472d
2012-07-02 15:22:48 -04:00
John-David Dalton
90e2bd0372 Correct variable declaration order.
Former-commit-id: 5f5a36057b065799dcc05b0054a2c88f00fad8c0
2012-07-02 03:43:01 -04:00
John-David Dalton
10fbc8a04b Update minified build and documentation.
Former-commit-id: 03b6f5fdf71ab1dab48f3fb06d60b6ec8a8e494c
2012-07-02 03:01:03 -04:00
John-David Dalton
fb818f3775 Cleanup lodash.js.
Former-commit-id: a1b7dc187dbd562b62d3446ce731674e0bb539d9
2012-07-02 03:00:01 -04:00
John-David Dalton
434e23c209 Add _.template benchmarks.
Former-commit-id: 97c5a90825d6a9a0b876d8c9f90e621f00389766
2012-07-02 02:59:33 -04:00
John-David Dalton
fe53bd6475 Fix build for _.bind.
Former-commit-id: 59ef841bca271bed05555c4b40e32b85ee1a4d37
2012-07-02 00:26:16 -04:00
John-David Dalton
268ce91c65 Add _.bind and _.size benchmarks.
Former-commit-id: bb3517e9517db81de56e3794abc256cd2dac59b5
2012-07-02 00:07:55 -04:00
John-David Dalton
3b4074bfc7 Optimize _.template when no evaluate delimiters are used and optimize _.bind when partially applied in V8.
Former-commit-id: 25489d41ba3cac7ac3f1414e09f1971a11a779be
2012-07-02 00:07:22 -04:00
John-David Dalton
6af4652161 Optimize inlining the iteratorTemplate for builds.
Former-commit-id: 8b7ac4622e51dbe5c0364f3c6781aa474dcfa96e
2012-06-30 03:06:21 -04:00
John-David Dalton
3717d30188 Update Backbone and Underscore submodules.
Former-commit-id: 0cdf988c89269ff95eb0d7fbd0bc51cbe95d3524
2012-06-29 20:41:51 -04:00
John-David Dalton
4cf2e83418 Add _.zipObject.
Former-commit-id: 0fe17adc359fbc608025dced32f6dd509d019413
2012-06-29 20:41:12 -04:00
John-David Dalton
1228639103 Cleanup build.js.
Former-commit-id: 01f5488ddba9f51344561c8df493d4f1bc6b0ef9
2012-06-29 19:33:36 -04:00
John-David Dalton
e12d67de94 Update minified build and documentation.
Former-commit-id: f4c5987a37d5c22f9705495e3a49a497f009d01c
2012-06-29 19:09:13 -04:00
John-David Dalton
10bcb37ca5 Inline more functionality into _.sortBy.
Former-commit-id: 6549e86881b7a93d96854a9ac1b04f0f5a5db0f1
2012-06-29 19:07:05 -04:00
John-David Dalton
e973598bff DRY out isType methods and simplify templates during the build process.
Former-commit-id: cd982282a5de63fddc36d1dc4759c8982e1c5ad4
2012-06-29 19:05:30 -04:00
John-David Dalton
3a5129694d Update documentation and minified build.
Former-commit-id: 193568c6f99736971ef93f9c4d63bc72195b8b2b
2012-06-29 04:03:02 -04:00
John-David Dalton
a1e0fbea8b Add issue reference to README.md.
Former-commit-id: 09ed4e386b55f657d8710f40c14fb3b283d66b7c
2012-06-29 04:01:58 -04:00
John-David Dalton
0bf374454e Add scripts entry to package.json.
Former-commit-id: 9ab2b915ea8aa6c3b8c28b5d14eaa32613db7ed0
2012-06-29 04:00:35 -04:00
John-David Dalton
5e592fbf29 Merge branch 'master' of github.com:bestiejs/lodash
Former-commit-id: a4de2b320b871d2bfd689890fc526605215091bf
2012-06-29 03:58:54 -04:00
John-David Dalton
ad4101bc99 Optimize _.sortBy and remove the _.map dependency from _.sortBy.
Former-commit-id: f6a133f0d27e7a00cb54e2e8478066dcfbe05659
2012-06-29 03:11:31 -04:00
John-David Dalton
2d057d92cf Merge pull request #38 from davidmurdoch/00d1cc9bf84355f35268d24201e02feaec6a00b1 [formerly d387147685f95cf88a437e678c873181cbcb907f]
Use `null` when comparing `null`/`undefined`.

Former-commit-id: 16c513648279e37a72eb433bd9b5fbe840854376
2012-06-28 22:21:18 -07:00
David Murdoch
00d1cc9bf8 Use null when comparing null/undefined
for non-strict equals. Saves 2 gzipped bytes.


Former-commit-id: d387147685f95cf88a437e678c873181cbcb907f
2012-06-28 09:56:10 -04:00
David Murdoch
2c1ec5fe75 Save 2 gzipped bytes by flipping args in math.max
Also, remove some stray whitespace.


Former-commit-id: 98b4711bc7d978ef66a693593d6be108f6bcfd8d
2012-06-28 09:45:14 -04:00
John-David Dalton
81b28d005d Remove arguments object from _.range.
Former-commit-id: d3da531e33bcd00a00ff80986f56196ac1b6f2c5
2012-06-27 13:51:46 -04:00
John-David Dalton
6a90616b99 Cleanup README.md.
Former-commit-id: 1a07361430f1d20382beb277db17e94967fd791d
2012-06-26 04:08:11 -04:00
John-David Dalton
d5be43695a Merge pull request #35 from tomByrer/master
Add CDN and jsPerf links to README.md.

Former-commit-id: b2ba93fb493536060c9abb13f406db9fd84d0ea4
2012-06-26 00:31:43 -07:00
John-David Dalton
0a93b81ae7 Update minified build and documentation.
Former-commit-id: 3b2d6cbd0c91933043c64b6f15a4c990a5c400c5
2012-06-26 03:28:08 -04:00
John-David Dalton
65f8da1654 Make _.size work consistently cross-browser with arguments objects and avoid erroring when falsey values are passed.
Former-commit-id: 76dc852a4e1fd84218f9c57f44c93e483a3680d9
2012-06-26 03:23:53 -04:00
John-David Dalton
911014db95 Avoid compiling unnecessary _.template code.
Former-commit-id: 74006fd2df2b5d2ba8a222baf21574f729f34bcb
2012-06-26 02:32:43 -04:00
John-David Dalton
313ee13f18 Move _.groupBy and _.sortBy back to the "Collections" category. [closes #34]
Former-commit-id: ce0f7f906758ce13cc2ea927520ac401e6bba9f6
2012-06-26 02:18:44 -04:00
tomByrer
addad04c44 Update master
Former-commit-id: c61735bdbf4dbad6dfd15a03660901fca9043327
2012-06-19 20:34:28 -06:00
tomByrer
e3789e5b64 merged tests with Dive in section
Former-commit-id: 1b32a93390d9b806bd66a298d558e68588ba7574
2012-06-19 20:32:49 -06:00
tomByrer
410315ce35 + CDN usage link
+ testing links

Former-commit-id: 79740ec7b2ac8c088545ca585ab5d3d94c804e2a
2012-06-19 20:23:58 -06:00
tomByrer
90998da308 + cdn js' hosting
Former-commit-id: 4276796f0fa31602060860da9c45c43dce34e8c4
2012-06-19 19:53:50 -06:00
John-David Dalton
6fa5b13e10 Add comment explaining a V8 optimization.
Former-commit-id: 733f0985509467291287e1e0a95fcd22114cdbcf
2012-06-19 11:42:27 +02:00
John-David Dalton
93067c2d52 Update documentation and minified build.
Former-commit-id: 156cdcff42eb4fef4a982e5b3016030246ba9f63
2012-06-19 10:56:05 +02:00
John-David Dalton
b2079b7007 Leverage _.indexOf's fromIndex in _.difference and _.without.
Former-commit-id: 0fd092d2ee109b99a50791899e7f2d690b3852af
2012-06-19 10:54:23 +02:00
John-David Dalton
b643dd074c Clarify benchmark descriptions.
Former-commit-id: 79c71d7d2c034ebe31f20f5d10251a8ba175cfd8
2012-06-16 20:35:55 -04:00
John-David Dalton
a3932c75e1 Move screencast links to Vimeo.
Former-commit-id: d9f48294d88ff50889c0859b3c1956d0e49a3bd4
2012-06-16 09:34:36 -04:00
John-David Dalton
1cd3b9ec47 Add 3rd screencast link to README.md.
Former-commit-id: c714180beab13c911f9d1676cb65117186a9524a
2012-06-15 17:21:45 -04:00
John-David Dalton
0c77f42080 Fix documentation typo, s/uiq/uniq. [closes #32] [cheeaun]
Former-commit-id: 343ff0d9a7238ab7eec6d5cc75b5c7dff3de1925
2012-06-15 09:12:03 -04:00
John-David Dalton
cea122db38 Update submodules.
Former-commit-id: 53394993a20cacf965de52e382ff72399d2b89ad
2012-06-15 00:12:06 -04:00
John-David Dalton
966f9fcd07 Update unit test link in README.md.
Former-commit-id: 0c11e69795cd0a28f0b370c40b7a6197fe712d0a
2012-06-14 15:30:37 -04:00
John-David Dalton
6ce9df8504 Bump to v0.3.2.
Former-commit-id: ff3cac0ce890b46a45c8738d559f68ac63b80caf
2012-06-14 15:19:09 -04:00
John-David Dalton
2a0b223896 Simplify dependencies in build.js.
Former-commit-id: 2d154d1dfb4d639aa32c5e9aeaeea6942965aee7
2012-06-14 02:17:09 -04:00
John-David Dalton
c2db180829 Tweak _.sortedIndex for Chrome optimizations.
Former-commit-id: d1d9f1bd1ecfd3bcde98aa51423e05e128f6ffd4
2012-06-14 01:06:08 -04:00
John-David Dalton
3223e4ffa5 Update documentation and minified build.
Former-commit-id: 5472dccceb33c3575c538190472dde0e82bcfcde
2012-06-14 00:29:14 -04:00
John-David Dalton
24c9b6e211 Move _.pluck and _.invoke back to the "Collections" category and optimize _.sortedIndex when a callback is passed.
Former-commit-id: d16763e7d35660d8ba9ea976c8b2a4dc20f1211f
2012-06-14 00:28:36 -04:00
John-David Dalton
e5555dd26a Move _.tap to the "Chaining" category, and deprecate _(…).chain, _.isNull, _.isUndefined, _.result, and _.size.
Former-commit-id: 64ee67758b8730fd70cbb28af4230bb336b91214
2012-06-13 15:26:46 -04:00
John-David Dalton
ee2d0ddf8a Ensure custom builds generate lodash.custom files.
Former-commit-id: c89ee640688f6f598bb2d3834f714f0edc4ce7a4
2012-06-13 15:15:20 -04:00
John-David Dalton
aef130b396 Update submodules.
Former-commit-id: 801d3c7413cb5906b4a517639098a6a32d015cba
2012-06-13 00:21:03 -04:00
John-David Dalton
fbdadec5e5 Add _.throttle unit test for recursive calls.
Former-commit-id: 7208516b56905c83df73aef6b02cee0101602349
2012-06-12 23:53:03 -04:00
John-David Dalton
a068339079 Indicate slow paths in perf.js.
Former-commit-id: 561e4f0957934b25422f7f515678705be4af726f
2012-06-12 23:44:21 -04:00
John-David Dalton
3f07d3ec55 Remove the useSourceURL variable from the minified build.
Former-commit-id: c0f02e7e87c533220a99ebe99c9ee08516fb9deb
2012-06-12 20:15:52 -04:00
John-David Dalton
62e7da9d8a Update docs and minified build.
Former-commit-id: d0673323dc850f4e7936f00374905cd29c5d6e24
2012-06-12 19:29:01 -04:00
John-David Dalton
b60d43e5f6 Ensure sourceURL support doesn't cause errors in Adobe's JS engine.
Former-commit-id: 2ad1214e6a58832c732499b272ebfc434953213b
2012-06-12 19:28:47 -04:00
John-David Dalton
a5873a3158 Add comments, documentation, and update the minified build.
Former-commit-id: c65665063f254b1ba9dab9c6948fedf29f1e795f
2012-06-11 22:49:24 -04:00
John-David Dalton
3a698eb0ed Make _.escape match _.template's escape delimiter results for null and undefined values.
Former-commit-id: b6717c6debf3bc308cf12b778916f5a46dbb954d
2012-06-11 22:37:54 -04:00
John-David Dalton
1e2ef542e4 Bump to v0.3.1.
Former-commit-id: 2e1e3b7e47b1f98d2ca20a89a4570a0b958d4323
2012-06-11 00:09:29 -04:00
John-David Dalton
94e8af4d93 Update submodules.
Former-commit-id: 0658ae9b9e49c468f839738f34c9f6361b90897e
2012-06-10 23:58:43 -04:00
John-David Dalton
250a0ab5eb Add _.shuffle benchmark.
Former-commit-id: 13a0a7392108571d4ebced5e6e6ff66048091983
2012-06-10 13:46:45 -04:00
John-David Dalton
2da05d88a0 Add another code example to _.invoke documentation.
Former-commit-id: 0bea74a470771ebc5cf2110243b38db3698cde52
2012-06-10 12:59:42 -04:00
John-David Dalton
7faa849a89 Cleanup README.md.
Former-commit-id: 1cc58476c5737624b97801aabc0dc7368c43c0d3
2012-06-09 03:23:39 -04:00
John-David Dalton
c5bceb8fc8 Update documentation and minified build.
Former-commit-id: edc6264f5721cbdb080c4f7772263848c125b3e2
2012-06-09 03:11:36 -04:00
John-David Dalton
1e94b93ce6 Add Backbone build and correct dependencies for _.bindAll, _.mixin, and _.sortBy.
Former-commit-id: 3d4413d6ab3b41471be6336d138a4b4bfa97fde7
2012-06-09 03:10:57 -04:00
John-David Dalton
3f7bccf2e6 Update Backbone and Underscore submodules.
Former-commit-id: 6f938216d0bb26347ce7fd42169f926e2ae04e0e
2012-06-09 00:31:03 -04:00
John-David Dalton
181b869109 Remove _.map and _.pluck dependency from _.sortBy and simplify method wrappers.
Former-commit-id: 915af96abd41e8da7bba88cd57eb703f8129107f
2012-06-09 00:29:51 -04:00
John-David Dalton
2332245be1 Update minified build and documentation.
Former-commit-id: 6790d25b2164f0df2dcce63d5a5780343f3b5e63
2012-06-07 12:44:53 -04:00
John-David Dalton
3c6999f3a4 Ensure all "Arrays" category methods allow a falsey array argument. [closes #23, #24]
Former-commit-id: 66d09d3c8f3c045daf310c46581afa085daa57de
2012-06-07 12:42:33 -04:00
John-David Dalton
5f2f15b976 Remove _.isArguments fallback from mobile build.
Former-commit-id: d98ac9953e9b403e17bdcef099caafe09873980f
2012-06-07 03:27:01 -04:00
John-David Dalton
47dfb5b6b7 Fix typo in _.values benchmark and tweak how percents are displayed in perf.js.
Former-commit-id: 49be4600561e55e134d3152b00c765e305af98b5
2012-06-07 00:07:33 -04:00
John-David Dalton
c410c1293e Update minified build and documentation.
Former-commit-id: e489b826c65d908b934e13d032ed866d68edd576
2012-06-06 23:48:41 -04:00
John-David Dalton
ca1c732f31 Move _.values to Objects category.
Former-commit-id: e85229b53a7697c11f76eae02aef8a4fce3aec3a
2012-06-06 23:45:30 -04:00
John-David Dalton
5e8c373bf4 Move _.pluck to the Arrays category.
Former-commit-id: a3ba36c1c320c8685c25fcb0bbe16ba2baeb6731
2012-06-06 23:11:25 -04:00
John-David Dalton
51a459fe48 Simplify function checks and cleanup documentation.
Former-commit-id: 460f34725e212ced27831b9aad1e9e7e2fc02cf1
2012-06-06 15:56:40 -04:00
John-David Dalton
03c07abbc3 Update README.md.
Former-commit-id: 64ce8f122be084fd93fd711a6ca207fc4ae6b870
2012-06-06 15:05:52 -04:00
John-David Dalton
5eabe1a172 Add sourceURL support to _.template.
Former-commit-id: 31d40d57f903098fe1678777aa7921e72d1dca9e
2012-06-06 15:05:41 -04:00
John-David Dalton
5b6ea7afb2 Bump to v0.3.0.
Former-commit-id: 2b713b3d926e3dbba80eab6e1e14d080f169bf39
2012-06-06 00:52:57 -04:00
John-David Dalton
7c1c5e70ca Update Backbone and RequireJS submodules.
Former-commit-id: 145455767d22eb1b03a751024e69826e2387fd04
2012-06-06 00:50:31 -04:00
John-David Dalton
d475f8f965 Fix documentation typo.
Former-commit-id: 85e89c893d358d196a3f0f04b95acb10bbca2771
2012-06-05 01:44:50 -04:00
John-David Dalton
fd239076dd Fix minified build for _.forIn.
Former-commit-id: 1d5d41fe63a10ccae8fcf4a91e7e77526a7c0d9c
2012-06-05 01:07:46 -04:00
John-David Dalton
5f786bbe47 Add category build option.
Former-commit-id: 4adea9367949985a1218cff58ff856184fd11db7
2012-06-05 00:41:20 -04:00
John-David Dalton
f66dc6bed8 Fix typo in iteratorTemplate.
Former-commit-id: b787391db088e672c55ca56ca246147557b3694f
2012-06-04 22:49:33 -04:00
John-David Dalton
52c36ac445 Fix documentation typo.
Former-commit-id: defc89d6a8267a4a6626ca6ac7345db1d55cb9b6
2012-06-04 16:54:47 -04:00
John-David Dalton
8f6a78cba5 Update documentation and package.json.
Former-commit-id: 4ab7d954b7abc5f73269eb7c74a39b02fa04970d
2012-06-04 16:38:37 -04:00
John-David Dalton
7053e9113f Add unit test for _.sortedIndex to ensure it supports arrays with high length values.
Former-commit-id: 8956495dfa40c75dcb3c0585e78913607bf92e99
2012-06-04 16:18:23 -04:00
John-David Dalton
89f9ab9940 Bump to v0.3.0-pre.
Former-commit-id: 1e7958b4b1cdffd962a51edf3e3695cea960d8c9
2012-06-04 15:44:54 -04:00
John-David Dalton
240bc40b39 Ensure collection methods treat array-like objects with invalid length properties as regular objects.
Former-commit-id: dd8b382635bc30dc6e417cd9b47c36abfdf5ddcb
2012-06-04 15:36:27 -04:00
John-David Dalton
74649b5f28 Add _.forOwn and _.forIn.
Former-commit-id: f4e94a0fd15318063eec16c464435b07f419fa6a
2012-06-04 14:45:06 -04:00
John-David Dalton
b484d4b2dc Update minified build and documentation.
Former-commit-id: 592319b69487858794529d789383af1b38d55632
2012-06-04 02:23:16 -04:00
John-David Dalton
da1124dd37 Switch to an htmlEscapes object for use in _.escape.
Former-commit-id: bc449b5d6868c846d599840e5c0d90d0314fe4b8
2012-06-04 02:12:41 -04:00
John-David Dalton
210485d0be Update Benchmark.js and UglifyJS submodules.
Former-commit-id: 78611de2f992dc4d6cc4d336bfb761b98b22ce79
2012-06-04 00:08:26 -04:00
John-David Dalton
d9aee5ae60 Update minified build, documentation, and Backbone submodule.
Former-commit-id: cca2cf2f55e2750486d1d32b8da26fbc5576a65b
2012-06-03 21:58:35 -04:00
John-David Dalton
9ac64623fc Added thisArg argument to _.sortedIndex and _.uniq, benchmarks, unit tests, and adjusted related dependencies in build.js.
Former-commit-id: a97aa769d760c7cc4d0df6307cebc860345a0da0
2012-06-03 21:56:36 -04:00
John-David Dalton
6ea4226680 Remove unneeded Closure Compiler export around the template string _.escape(__t) in pre-compile.js.
Former-commit-id: 812bd220cd3baca30a100f07e1d47cd6745a3602
2012-06-03 20:36:31 -04:00
John-David Dalton
c1416bba39 Cleanup console messages in perf.js.
Former-commit-id: b3e669d46f21d39f96873167557b4ede80458beb
2012-06-03 20:35:22 -04:00
John-David Dalton
ddb3ab3238 Tweak indexOf isSorted benchmark.
Former-commit-id: 0183b35929a2c1f7113747a67f55abbc797fab8c
2012-06-03 01:06:12 -04:00
John-David Dalton
5e7c9698c7 Use typeof == 'number' more, and default callback values to docs.
Former-commit-id: 02786903a510d0cc837eeeb7e9f42db2ecd634a4
2012-06-03 01:05:40 -04:00
John-David Dalton
4c66b95516 Make Firebug Lite console fullscreen in more browsers.
Former-commit-id: a42e7d187a582a1caea721860cf3ed4bd0f94368
2012-06-01 07:41:29 -06:00
John-David Dalton
2d03060a0d Make previous build.js regexp simplification non-greedy.
Former-commit-id: e58cfb5e5143e12721bb08445dfd4a6fec119cd1
2012-05-31 23:18:44 -06:00
John-David Dalton
3313b0aa42 Update minified build and docs.
Former-commit-id: 3c0463d77c9091c1e66c7d68240de8b7ab2e499f
2012-05-31 22:54:50 -06:00
John-David Dalton
5d2928d2b3 Simplify regexps in build.js.
Former-commit-id: 7640f90b6aeca0438579c15c9eef270904c2c523
2012-05-31 22:54:37 -06:00
John-David Dalton
f6e2ae41d6 Add more benchmarks.
Former-commit-id: bddb4a26073ecd5aaf622f9726be940b6340cc07
2012-05-31 22:11:07 -06:00
John-David Dalton
7ccb038b6d Add _.isEmpty unit test.
Former-commit-id: 066961a929da280421083d3f9d66b838d3d29dfd
2012-05-31 17:40:47 -06:00
John-David Dalton
7d62bbf74f Optimize _.times.
Former-commit-id: beae48853d0e9be1c3016c11bee86a272964dfa2
2012-05-31 17:37:01 -06:00
John-David Dalton
3d8cc32302 Add fromIndex to _.indexOf and _.lastIndexOf. [closes #20]
Former-commit-id: 3ab67c318a5a7fc2e521a9a2573b694e6920b14d
2012-05-31 17:26:45 -06:00
John-David Dalton
861eea5148 Fix "prototype" iteration bug with _.keys.
Former-commit-id: 1e072b2639e21a5c0a920db0ac27693ade34b009
2012-05-31 10:29:33 -05:00
John-David Dalton
b432721fe5 Optimize this binding in iterator methods and remove _.bind as a dependency for several methods.
Former-commit-id: 60af002cd80758fea81fbff9c2b20b1ccf3ccffd
2012-05-31 10:21:38 -05:00
John-David Dalton
f13a0cc7e0 Format numbers and scroll down results panel in perf.js.
Former-commit-id: 9f80b5534e3b46be7ad9c84ebb7e9ed5afdc35b8
2012-05-30 09:19:58 -04:00
John-David Dalton
1f7e37a1a3 Change performance link in README.md to lodash.com benchmarks.
Former-commit-id: 5c851961fd1b8e46599c28967d782551722a03d4
2012-05-30 04:03:14 -04:00
100 changed files with 53444 additions and 10955 deletions

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
* text=auto

7
.gitignore vendored
View File

@@ -1,4 +1,5 @@
*.custom.*
.DS_Store
dist/
node_modules/
*.custom.*
node_modules/
vendor/closure-compiler/
vendor/uglifyjs/

24
.gitmodules vendored
View File

@@ -1,24 +0,0 @@
[submodule "vendor/benchmark.js"]
path = vendor/benchmark.js
url = git://github.com/bestiejs/benchmark.js.git
[submodule "vendor/docdown"]
path = vendor/docdown
url = git://github.com/jdalton/docdown.git
[submodule "vendor/qunit"]
path = vendor/qunit
url = git://github.com/jquery/qunit.git
[submodule "vendor/qunit-clib"]
path = vendor/qunit-clib
url = git://github.com/jdalton/qunit-clib.git
[submodule "vendor/requirejs"]
path = vendor/requirejs
url = git://github.com/jrburke/requirejs.git
[submodule "vendor/uglifyjs"]
path = vendor/uglifyjs
url = git://github.com/mishoo/UglifyJS.git
[submodule "vendor/underscore"]
path = vendor/underscore
url = git://github.com/documentcloud/underscore.git
[submodule "vendor/backbone"]
path = vendor/backbone
url = git://github.com/documentcloud/backbone.git

12
.jamignore Normal file
View File

@@ -0,0 +1,12 @@
.*
*.custom.*
*.md
*.txt
build.js
index.js
build/
doc/
node_modules/
perf/
test/
vendor/

View File

@@ -1,19 +1,25 @@
*.custom.*
*.min.*
.*
build.*
build/
dist/
*.custom.*
*.d.ts
doc/*.php
node_modules/
perf/*.html
perf/*-ui.js
perf/*.sh
test/*.html
test/*-ui.js
test/*.sh
vendor/*.gz
vendor/backbone/
vendor/closure-compiler/
vendor/docdown/
vendor/benchmark.js/*.jar
vendor/closure-compiler
vendor/docdown
vendor/firebug-lite/
vendor/json3/
vendor/jquery/
vendor/qunit/qunit/*.css
vendor/qunit/qunit/*-1.8.0.js
vendor/requirejs/
vendor/uglifyjs/
vendor/underscore/
vendor/underscore/*-min.js
vendor/uglifyjs
vendor/underscore/test/

7
.travis.yml Normal file
View File

@@ -0,0 +1,7 @@
language: node_js
node_js:
- 0.6
- 0.8
before_script:
- "curl -H 'Accept: application/vnd.github.v3.raw' https://api.github.com/repos/bestiejs/lodash/git/blobs/a2787b470c577cee2404d186c562dd9835f779f5 | tar xvz -C vendor"
- "curl -H 'Accept: application/vnd.github.v3.raw' https://api.github.com/repos/bestiejs/lodash/git/blobs/3390b259e04829538e4d3635d12b317dd6103eca | tar xvz -C vendor"

361
README.md
View File

@@ -1,100 +1,221 @@
# Lo-Dash <sup>v0.2.2</sup>
# Lo-Dash <sup>v1.0.0-rc.2</sup>
[![build status](https://secure.travis-ci.org/bestiejs/lodash.png)](http://travis-ci.org/bestiejs/lodash)
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](https://github.com/bestiejs/lodash#closed-underscorejs-issues), and [additional features](https://github.com/bestiejs/lodash#features).
A utility library, usable as a drop-in replacement for Underscore, delivering [performance](http://lodash.com/benchmarks), [bug fixes](https://github.com/bestiejs/lodash#resolved-underscorejs-issues), and [additional features](http://lodash.com/#features).
Lo-Dashs 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
* Lo-Dash builds:<br>
[Development](https://raw.github.com/bestiejs/lodash/v1.0.0-rc.2/lodash.js) and
[Production](https://raw.github.com/bestiejs/lodash/v1.0.0-rc.2/lodash.min.js)
* Underscore builds:<br>
[Development](https://raw.github.com/bestiejs/lodash/v1.0.0-rc.2/lodash.underscore.js) and
[Production](https://raw.github.com/bestiejs/lodash/v1.0.0-rc.2/lodash.underscore.min.js)
* CDN copies of ≤ v1.0.0-rc.2s builds are available on [cdnjs](http://cdnjs.com/) thanks to [CloudFlare](http://www.cloudflare.com/):<br>
[Lo-Dash development](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.0.0-rc.2/lodash.js),
[Lo-Dash production](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.0.0-rc.2/lodash.min.js),
[Underscore development](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.0.0-rc.2/lodash.underscore.js), and
[Underscore production](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.0.0-rc.2/lodash.underscore.min.js)
* For optimal file size, [create a custom build](https://github.com/bestiejs/lodash#custom-builds) with only the features you need
## Dive in
Weve got [API docs](http://lodash.com/docs), [benchmarks](http://lodash.com/benchmarks), and [unit tests](http://lodash.com/tests).
Create your own benchmarks at [jsPerf](http://jsperf.com), or [search](http://jsperf.com/search?q=lodash) for existing ones.
For a list of upcoming features, check out our [roadmap](https://github.com/bestiejs/lodash/wiki/Roadmap).
## Screencasts
For more information check out these screencasts over Lo-Dash:
* [Introducing Lo-Dash](http://dl.dropbox.com/u/513327/allyoucanleet/post/20/file/screencast.mp4)
* [Optimizations and custom builds](http://dl.dropbox.com/u/513327/allyoucanleet/post/21/file/screencast.mp4)
* [Introducing Lo-Dash](https://vimeo.com/44154599)
* [Lo-Dash optimizations and custom builds](https://vimeo.com/44154601)
* [Lo-Dashs origin and why its a better utility belt](https://vimeo.com/44154600)
* [Unit testing in Lo-Dash](https://vimeo.com/45865290)
* [Lo-Dashs approach to native method use](https://vimeo.com/48576012)
* [CascadiaJS: Lo-Dash for a better utility belt](http://www.youtube.com/watch?v=dpPy4f_SeEk)
## Features
* AMD loader support
* [_.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
* [_.groupBy](http://lodash.com/docs#groupBy) accepts a third, `thisArg`, argument
* [_.partial](http://lodash.com/docs#partial) for more functional fun
* [_.size](http://lodash.com/docs#size) supports returning the `length` of string values
* AMD loader support ([RequireJS](http://requirejs.org/), [curl.js](https://github.com/cujojs/curl), etc.)
* [_(…)](http://lodash.com/docs#_) supports intuitive chaining without calling [_(…).chain](http://lodash.com/docs#prototype_chain)
* [_.bindKey](http://lodash.com/docs#bindKey) for binding [*“lazy”* defined](http://michaux.ca/articles/lazy-function-definition-pattern) methods
* [_.clone](http://lodash.com/docs#clone) supports *“deep”* cloning
* [_.contains](http://lodash.com/docs#contains) accepts a `fromIndex` argument
* [_.forEach](http://lodash.com/docs#forEach) is chainable and supports exiting iteration early
* [_.forIn](http://lodash.com/docs#forIn) for iterating over an objects own and inherited properties
* [_.forOwn](http://lodash.com/docs#forOwn) for iterating over an objects own properties
* [_.isPlainObject](http://lodash.com/docs#isPlainObject) checks if values are created by the `Object` constructor
* [_.merge](http://lodash.com/docs#merge) for a *“deep”* [_.extend](http://lodash.com/docs#extend)
* [_.partial](http://lodash.com/docs#partial) for partial application without `this` binding
* [_.pick](http://lodash.com/docs#pick) and [_.omit](http://lodash.com/docs#omit) accepts `callback` and `thisArg` arguments
* [_.template](http://lodash.com/docs#template) supports [ES6 template delimiters](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-7.8.6) and utilizes [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) for easier debugging
* [_.contains](http://lodash.com/docs#contains), [_.size](http://lodash.com/docs#size), [_.toArray](http://lodash.com/docs#toArray),
[and more…](http://lodash.com/docs "_.countBy, _.every, _.filter, _.find, _.forEach, _.groupBy, _.invoke, _.map, _.max, _.min, _.pluck, _.reduce, _.reduceRight, _.reject, _.shuffle, _.some, _.sortBy, _.where") accept strings
## 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~23, Firefox 1~16, IE 6-10, Opera 9.25-12, Safari 3-6, Node.js 0.4.8-0.8.15, Narwhal 0.3.2, RingoJS 0.8, and Rhino 1.7RC5.
## 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.
To top it off, we handle all method dependency and alias mapping for you.
Mobile builds, with IE bug fixes and method compilation removed, may be created by using the `mobile` argument.
* Backbone builds, with only methods required by Backbone, may be created using the `backbone` modifier argument.
```bash
lodash backbone
```
~~~ bash
node build mobile
~~~
* CSP builds, supporting default [Content Security Policy](http://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html) restrictions, may be created using the `csp` modifier argument.
The `csp` modifier is an alais of the `mobile` modifier. Chrome extensions will require [sandboxing](http://developer.chrome.com/trunk/extensions/sandboxingEval.html) or the use of either the `csp`, `mobile`, or `underscore` build.
```bash
lodash csp
```
Custom builds may be created in two ways:
* Legacy builds, tailored for older browsers without [ES5 support](http://es5.github.com/), may be created using the `legacy` modifier argument.
```bash
lodash legacy
```
1. Use the`include` argument to pass the names of the methods to include in the build.
~~~ bash
node build include=each,filter,map,noConflict
node build include="each, filter, map, noConflict"
node build mobile include=each,filter,map,noConflict
~~~
* Mobile builds, with IE < 9 bug fixes and method compilation removed, may be created using the `mobile` modifier argument.
```bash
lodash mobile
```
2. Use the `exclude` argument to pass the names of the methods to exclude from the build.
~~~ bash
node build exclude=isNaN,isUndefined,union,zip
node build exclude="isNaN, isUndefined, union, zip"
node build mobile exclude=isNaN,isUndefined,union,zip
~~~
* Strict builds, with `_.bindAll`, `_.defaults`, and `_.extend` in [strict mode](http://es5.github.com/#C), may be created using the `strict` modifier argument.
```bash
lodash strict
```
Custom builds are saved to `lodash.custom.js` and `lodash.custom.min.js`.
* Underscore builds, tailored for projects already using Underscore, may be created using the `underscore` modifier argument.
```bash
lodash underscore
```
Custom builds may be created using the following commands:
* Use the `category` argument to pass comma separated categories of methods to include in the build.<br>
Valid categories (case-insensitive) are *“arrays”*, *“chaining”*, *“collections”*, *“functions”*, *“objects”*, and *“utilities”*.
```bash
lodash category=collections,functions
lodash category="collections, functions"
```
* Use the `exports` argument to pass comma separated names of ways to export the `LoDash` function.<br>
Valid exports are *“amd”*, *“commonjs”*, *“global”*, *“node”*, and *“none”*.
```bash
lodash exports=amd,commonjs,node
lodash exports="amd, commonjs, node"
```
* Use the `iife` argument to specify code to replace the immediately-invoked function expression that wraps Lo-Dash.
```bash
lodash iife="!function(window,undefined){%output%}(this)"
```
* Use the `include` argument to pass comma separated method/category names to include in the build.
```bash
lodash include=each,filter,map
lodash include="each, filter, map"
```
* Use the `minus` argument to pass comma separated method/category names to remove from those included in the build.
```bash
lodash underscore minus=result,shuffle
lodash underscore minus="result, shuffle"
```
* Use the `plus` argument to pass comma separated method/category names to add to those included in the build.
```bash
lodash backbone plus=random,template
lodash backbone plus="random, template"
```
* Use the `template` argument to pass the file path pattern used to match template files to precompile.
```bash
lodash template="./*.jst"
```
* Use the `settings` argument to pass the template settings used when precompiling templates.
```bash
lodash settings="{interpolate:/\\{\\{([\\s\\S]+?)\\}\\}/g}"
```
* Use the `moduleId` argument to specify the AMD module ID of Lo-Dash, which defaults to “lodash”, used by precompiled templates.
```bash
lodash moduleId="underscore"
```
All arguments, except `legacy` with `csp` or `mobile`, may be combined.<br>
Unless specified by `-o` or `--output`, all files created are saved to the current working directory.
The following options are also supported:
* `-c`, `--stdout`&nbsp;&nbsp;&nbsp;&nbsp; Write output to standard output
* `-d`, `--debug`&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Write only the debug output
* `-h`, `--help`&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Display help information
* `-m`, `--minify`&nbsp;&nbsp;&nbsp;&nbsp; Write only the minified output
* `-o`, `--output`&nbsp;&nbsp;&nbsp;&nbsp; Write output to a given path/filename
* `-s`, `--silent`&nbsp;&nbsp;&nbsp;&nbsp; Skip status updates normally logged to the console
* `-V`, `--version`&nbsp;&nbsp; Output current version of Lo-Dash
The `lodash` command-line utility is available when Lo-Dash is installed as a global package (i.e. `npm install -g lodash`).
## Installation and usage
In browsers:
~~~ html
```html
<script src="lodash.js"></script>
~~~
```
Using [npm](http://npmjs.org/):
Using [`npm`](http://npmjs.org/):
~~~ bash
```bash
npm install lodash
~~~
npm install -g lodash
npm link lodash
```
To avoid potential issues, update `npm` before installing Lo-Dash:
```bash
npm install npm -g
```
In [Node.js](http://nodejs.org/) and [RingoJS v0.8.0+](http://ringojs.org/):
~~~ js
```js
var _ = require('lodash');
~~~
In [Narwhal](http://narwhaljs.org/) and [RingoJS v0.7.0-](http://ringojs.org/):
// or as a drop-in replacement for Underscore
var _ = require('lodash/lodash.underscore');
```
~~~ js
**Note:** If Lo-Dash is installed globally, run [`npm link lodash`](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/) in your projects root directory before requiring it.
In [RingoJS v0.7.0-](http://ringojs.org/):
```js
var _ = require('lodash')._;
~~~
```
In [Rhino](http://www.mozilla.org/rhino/):
~~~ js
```js
load('lodash.js');
~~~
```
In an AMD loader like [RequireJS](http://requirejs.org/):
~~~ js
```js
require({
'paths': {
'underscore': 'path/to/lodash'
@@ -103,141 +224,49 @@ require({
['underscore'], function(_) {
console.log(_.VERSION);
});
~~~
```
## Cloning this repo
## Resolved Underscore.js issues
To clone this repository including all submodules, using Git 1.6.5 or later:
* Allow iteration of objects with a `length` property [[#799](https://github.com/documentcloud/underscore/pull/799), [test](https://github.com/bestiejs/lodash/blob/v1.0.0-rc.2/test/test.js#L605-L611)]
* Fix cross-browser object iteration bugs [[#60](https://github.com/documentcloud/underscore/issues/60), [#376](https://github.com/documentcloud/underscore/issues/376), [test](https://github.com/bestiejs/lodash/blob/v1.0.0-rc.2/test/test.js#L618-L642)]
* Methods should work on pages with incorrectly shimmed native methods [[#7](https://github.com/documentcloud/underscore/issues/7), [#742](https://github.com/documentcloud/underscore/issues/742), [test](https://github.com/bestiejs/lodash/blob/v1.0.0-rc.2/test/test.js#L140-L146)]
* `_.isEmpty` should support jQuery/MooTools DOM query collections [[#690](https://github.com/documentcloud/underscore/pull/690), [test](https://github.com/bestiejs/lodash/blob/v1.0.0-rc.2/test/test.js#L807-L812)]
* `_.isObject` should avoid V8 bug [#2291](http://code.google.com/p/v8/issues/detail?id=2291) [[#605](https://github.com/documentcloud/underscore/issues/605), [test](https://github.com/bestiejs/lodash/blob/v1.0.0-rc.2/test/test.js#L888-L900)]
* `_.keys` should work with `arguments` objects cross-browser [[#396](https://github.com/documentcloud/underscore/issues/396), [test](https://github.com/bestiejs/lodash/blob/v1.0.0-rc.2/test/test.js#L981-L983)]
* `_.range` should coerce arguments to numbers [[#634](https://github.com/documentcloud/underscore/issues/634), [#683](https://github.com/documentcloud/underscore/issues/683), [test](https://github.com/bestiejs/lodash/blob/v1.0.0-rc.2/test/test.js#L1382-L1385)]
~~~ bash
git clone --recursive https://github.com/bestiejs/lodash.git
cd lodash.js
~~~
## Release Notes
For older Git versions, just use:
### <sup>v1.0.0-rc.2</sup> ###
~~~ bash
git clone https://github.com/bestiejs/lodash.git
cd lodash
git submodule update --init
~~~
* Specified more method chaining behaviors
* Updated `underscore` build compatibility to v1.4.3
## Closed Underscore.js issues
### <sup>v1.0.0-rc.1</sup> ###
* Ensure `_(...)` returns passed wrapper instances [[test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L95-98)]
* Ensure `_.groupBy` adds values to own, not inherited, properties [[test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L229-236)]
* Ensure `_.throttle` works when called in tight loops [[#502](https://github.com/documentcloud/underscore/issues/502), [test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L436-446)]
* Fix Firefox, IE, Opera, and Safari object iteration bugs [[#376](https://github.com/documentcloud/underscore/issues/376), [test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L152-172), [test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L206-213), [test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L255-257), [test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L265-267), [test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L285-292), [test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L386-388)]
* 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/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L77-83)]
* Register as AMD module, but still export to global [[#431](https://github.com/documentcloud/underscore/pull/431), [test](https://github.com/bestiejs/lodash/blob/32627f45072952df18a64cf5e9f2433d2d32730f/test/test.js#L61-75)]
* `_.forEach` should be chainable [[#142](https://github.com/documentcloud/underscore/issues/142), [test](https://github.com/bestiejs/lodash/blob/5bcd444084c92b1753feeaf66c20323e57a2dac3/test/test.js#L74-77)]
* `_isNaN(new Number(NaN))` should return `true` [[test](https://github.com/bestiejs/lodash/blob/5bcd444084c92b1753feeaf66c20323e57a2dac3/test/test.js#L95-99)]
* `_.reduceRight` should pass correct callback arguments when iterating objects [[test](https://github.com/bestiejs/lodash/blob/5bcd444084c92b1753feeaf66c20323e57a2dac3/test/test.js#L106-116)]
* `_.size` should return the `length` of string values [[test](https://github.com/bestiejs/lodash/blob/5bcd444084c92b1753feeaf66c20323e57a2dac3/test/test.js#L121-127)]
#### Compatibility Warnings ####
## Optimized methods <sup>(50+)</sup>
* Made `_(…)` chain automatically without needing to call `_#chain`
* Made `_.isEqual` equate `arguments` objects to similar `Object` objects
* Made `_.clone` copy the enumerable properties of `arguments` objects and objects<br>
created by constructors other than `Object` are cloned to plain `Object` objects
* `_.bind`
* `_.bindAll`
* `_.clone`
* `_.compact`
* `_.contains`, `_.include`
* `_.defaults`
* `_.defer`
* `_.difference`
* `_.each`
* `_.escape`
* `_.every`, `_.all`
* `_.extend`
* `_.filter`, `_.select`
* `_.find`, `_.detect`
* `_.flatten`
* `_.forEach`, `_.each`
* `_.functions`, `_.methods`
* `_.groupBy`
* `_.indexOf`
* `_.intersection`
* `_.invoke`
* `_.isEmpty`
* `_.isEqual`
* `_.isFinite`
* `_.isObject`
* `_.isString`
* `_.keys`
* `_.lastIndexOf`
* `_.map`, `_.collect`
* `_.max`
* `_.memoize`
* `_.min`
* `_.mixin`
* `_.pick`
* `_.pluck`
* `_.reduce`, `_.foldl`, `_.inject`
* `_.reject`
* `_.result`
* `_.shuffle`
* `_.some`, `_.any`
* `_.sortBy`
* `_.sortedIndex`
* `_.template`
* `_.throttle`
* `_.toArray`
* `_.union`
* `_.uniq`, `_.unique`
* `_.values`
* `_.without`
* `_.wrap`
* `_.zip`
* plus all `_(...)` method wrappers
#### Changes ####
## Changelog
* Ensure Lo-Dash runs in the JS engine embedded in Adobe products
* Ensured `_.reduce` and `_.reduceRight` pass the correct number of `callback` arguments
* Ensured `_.throttle` nulls the `timeoutId`
* Made deep `_.clone` more closely follow the structured clone algorithm and copy array properties assigned by `RegExp#exec`
* Optimized compiled templates in Firefox
* Optimized `_.forEach`, `_.forOwn`, `_.isNumber`, and `_.isString`
* Simplified `iteratorTemplate`
### <sup>v0.2.2</sup>
* Added mobile build option
* Ensured `_.find` returns `undefined` for unmatched values
* Ensured `_.templateSettings.variable` is compatible with Underscore.js
* Optimized `_.escape`
* Reduced dependencies in `_.find`
### <sup>v0.2.1</sup>
* Adjusted the Lo-Dash export order for r.js
* Ensured `_.groupBy` values are added to own, not inherited, properties
* Made `_.bind` follow ES5 spec to support a popular Backbone.js pattern
* Removed the alias `intersect`
* Simplified `_.bind`, `_.flatten`, `_.groupBy`, `_.max`, and `_.min`
### <sup>v0.2.0</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` argument to `_.groupBy`
* Added whitespace to compiled strings
* Added `_.partial` method
* Commented the `iterationFactory` options object
* Ensured `_(...)` returns passed wrapper instances
* Ensured `_.max` and `_.min` support extremely large arrays
* Ensured `_.throttle` works in tight loops
* Fixed IE < 9 `[DontEnum]` bug and Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1s 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`
### <sup>v0.1.0</sup>
* Initial release
The full changelog is available [here](https://github.com/bestiejs/lodash/wiki/Changelog).
## BestieJS
Lo-Dash is part of the BestieJS *"Best in Class"* module collection. This means we promote solid browser/environment support, ES5 precedents, unit testing, and plenty of documentation.
Lo-Dash is part of the BestieJS *Best in Class* module collection. This means we promote solid browser/environment support, ES5 precedents, unit testing, and plenty of documentation.
## Author

1991
build.js

File diff suppressed because it is too large Load Diff

View File

@@ -8,26 +8,25 @@
path = require('path'),
spawn = require('child_process').spawn;
/** The directory that is the base of the repository */
var basePath = path.join(__dirname, '../');
/** The path of the directory that is the base of the repository */
var basePath = fs.realpathSync(path.join(__dirname, '..'));
/** The directory where the Closure Compiler is located */
/** The path of the directory where the Closure Compiler is located */
var closurePath = path.join(basePath, 'vendor', 'closure-compiler', 'compiler.jar');
/** The distribution directory */
var distPath = path.join(basePath, 'dist');
/** Load other modules */
var preprocess = require(path.join(__dirname, 'pre-compile')),
postprocess = require(path.join(__dirname, 'post-compile')),
uglifyJS = require(path.join(basePath, 'vendor', 'uglifyjs', 'uglify-js'));
var preprocess = require('./pre-compile.js'),
postprocess = require('./post-compile.js'),
uglifyJS = require('../vendor/uglifyjs/uglify-js.js');
/** Closure Compiler command-line options */
var closureOptions = [
'--compilation_level=ADVANCED_OPTIMIZATIONS',
'--language_in=ECMASCRIPT5_STRICT',
'--warning_level=QUIET'
];
/** The Closure Compiler command-line options */
var closureOptions = ['--warning_level=QUIET'];
/** The Closure Compiler optimization modes */
var optimizationModes = {
'simple': 'SIMPLE_OPTIMIZATIONS',
'advanced': 'ADVANCED_OPTIMIZATIONS'
};
/** Reassign `existsSync` for older versions of Node */
fs.existsSync || (fs.existsSync = path.existsSync);
@@ -35,15 +34,52 @@
/*--------------------------------------------------------------------------*/
/**
* The exposed `minify` function minifies a given `source` and invokes the
* `onComplete` callback when finished.
* Minifies a given Lo-Dash `source` and invokes the `options.onComplete`
* callback when finished. The `onComplete` callback is invoked with one
* argument; (outputSource).
*
* @param {String} source The source to minify.
* @param {String} workingName The name to give temporary files creates during the minification process.
* @param {Function} onComplete A function called when minification has completed.
* @param {Array|String} [source=''] The source to minify or array of commands.
* -o, --output - Write output to a given path/filename.
* -s, --silent - Skip status updates normally logged to the console.
* -t, --template - Applies template specific minifier options.
*
* @param {Object} [options={}] The options object.
* outputPath - Write output to a given path/filename.
* isSilent - Skip status updates normally logged to the console.
* isTemplate - Applies template specific minifier options.
* onComplete - The function called once minification has finished.
*/
function minify(source, workingName, onComplete) {
new Minify(source, workingName, onComplete);
function minify(source, options) {
source || (source = '');
options || (options = {});
// juggle arguments
if (Array.isArray(source)) {
// convert commands to an options object
options = source;
var filePath = options[options.length - 1],
isSilent = options.indexOf('-s') > -1 || options.indexOf('--silent') > -1,
isTemplate = options.indexOf('-t') > -1 || options.indexOf('--template') > -1,
outputPath = path.join(path.dirname(filePath), path.basename(filePath, '.js') + '.min.js');
outputPath = options.reduce(function(result, value, index) {
if (/-o|--output/.test(value)) {
result = options[index + 1];
result = path.join(fs.realpathSync(path.dirname(result)), path.basename(result));
}
return result;
}, outputPath);
options = {
'isSilent': isSilent,
'isTemplate': isTemplate,
'outputPath': outputPath
};
source = fs.readFileSync(filePath, 'utf8');
}
new Minify(source, options);
}
/**
@@ -52,24 +88,35 @@
* @private
* @constructor
* @param {String} source The source to minify.
* @param {String} workingName The name to give temporary files creates during the minification process.
* @param {Function} onComplete A function called when minification has completed.
* @param {Object} options The options object.
* outputPath - Write output to a given path/filename.
* isSilent - Skip status updates normally logged to the console.
* isTemplate - Applies template specific minifier options.
* onComplete - The function called once minification has finished.
*/
function Minify(source, workingName, onComplete) {
// create the destination directory if it doesn't exist
if (!fs.existsSync(distPath)) {
fs.mkdirSync(distPath);
function Minify(source, options) {
// juggle arguments
if (typeof source == 'object' && source) {
options = source || options;
source = options.source || '';
}
this.compiled = {};
this.hybrid = {};
this.compiled = { 'simple': {}, 'advanced': {} };
this.hybrid = { 'simple': {}, 'advanced': {} };
this.uglified = {};
this.onComplete = onComplete;
this.source = source = preprocess(source);
this.workingName = workingName;
this.isSilent = !!options.isSilent;
this.isTemplate = !!options.isTemplate;
this.outputPath = options.outputPath;
source = preprocess(source, options);
this.source = source;
this.onComplete = options.onComplete || function(source) {
fs.writeFileSync(this.outputPath, source, 'utf8');
};
// begin the minification process
closureCompile.call(this, source, onClosureCompile.bind(this));
closureCompile.call(this, source, 'simple', onClosureSimpleCompile.bind(this));
}
/*--------------------------------------------------------------------------*/
@@ -80,26 +127,22 @@
*
* @private
* @param {String} source The JavaScript source to minify.
* @param {String} [message] The message to log.
* @param {Function} callback The function to call once the process completes.
* @param {String} mode The optimization mode.
* @param {Function} callback The function called once the process has completed.
*/
function closureCompile(source, message, callback) {
// the standard error stream, standard output stream, and Closure Compiler process
function closureCompile(source, mode, callback) {
// use simple optimizations when minifying template files
var options = closureOptions.slice();
options.push('--compilation_level=' + optimizationModes[this.isTemplate ? 'simple' : mode]);
// the standard error stream, standard output stream, and the Closure Compiler process
var error = '',
output = '',
compiler = spawn('java', ['-jar', closurePath].concat(closureOptions));
compiler = spawn('java', ['-jar', closurePath].concat(options));
// juggle arguments
if (typeof message == 'function') {
callback = message;
message = null;
if (!this.isSilent) {
console.log('Compressing ' + path.basename(this.outputPath, '.js') + ' using the Closure Compiler (' + mode + ')...');
}
console.log(message == null
? 'Compressing ' + this.workingName + ' using the Closure Compiler...'
: message
);
compiler.stdout.on('data', function(data) {
// append the data to the output stream
output += data;
@@ -111,9 +154,8 @@
});
compiler.on('exit', function(status) {
var exception = null;
// `status` contains the process exit code
var exception = null;
if (status) {
exception = new Error(error);
exception.status = status;
@@ -132,25 +174,17 @@
*
* @private
* @param {String} source The JavaScript source to minify.
* @param {String} [message] The message to log.
* @param {Function} callback The function to call once the process completes.
* @param {String} label The label to log.
* @param {Function} callback The function called once the process has completed.
*/
function uglify(source, message, callback) {
function uglify(source, label, callback) {
var exception,
result,
ugly = uglifyJS.uglify;
// juggle arguments
if (typeof message == 'function') {
callback = message;
message = null;
if (!this.isSilent) {
console.log('Compressing ' + path.basename(this.outputPath, '.js') + ' using ' + label + '...');
}
console.log(message == null
? 'Compressing ' + this.workingName + ' using UglifyJS...'
: message
);
try {
result = ugly.gen_code(
// enable unsafe transformations
@@ -174,42 +208,79 @@
/*--------------------------------------------------------------------------*/
/**
* The `closureCompile()` callback.
* The Closure Compiler callback for simple optimizations.
*
* @private
* @param {Object|Undefined} exception The error object.
* @param {String} result The resulting minified source.
*/
function onClosureCompile(exception, result) {
function onClosureSimpleCompile(exception, result) {
if (exception) {
throw exception;
}
// store the post-processed Closure Compiler result and gzip it
this.compiled.source = result = postprocess(result);
gzip(result, onClosureGzip.bind(this));
result = postprocess(result);
this.compiled.simple.source = result;
gzip(result, onClosureSimpleGzip.bind(this));
}
/**
* The Closure Compiler `gzip` callback.
* The Closure Compiler `gzip` callback for simple optimizations.
*
* @private
* @param {Object|Undefined} exception The error object.
* @param {Buffer} result The resulting gzipped source.
*/
function onClosureGzip(exception, result) {
function onClosureSimpleGzip(exception, result) {
if (exception) {
throw exception;
}
// store the gzipped result and report the size
this.compiled.gzip = result;
console.log('Done. Size: %d bytes.', result.length);
if (!this.isSilent) {
console.log('Done. Size: %d bytes.', result.length);
}
this.compiled.simple.gzip = result;
// next, minify the source using only UglifyJS
uglify.call(this, this.source, onUglify.bind(this));
// next, compile the source using advanced optimizations
closureCompile.call(this, this.source, 'advanced', onClosureAdvancedCompile.bind(this));
}
/**
* The `uglify()` callback.
* The Closure Compiler callback for advanced optimizations.
*
* @private
* @param {Object|Undefined} exception The error object.
* @param {String} result The resulting minified source.
*/
function onClosureAdvancedCompile(exception, result) {
if (exception) {
throw exception;
}
result = postprocess(result);
this.compiled.advanced.source = result;
gzip(result, onClosureAdvancedGzip.bind(this));
}
/**
* The Closure Compiler `gzip` callback for advanced optimizations.
*
* @private
* @param {Object|Undefined} exception The error object.
* @param {Buffer} result The resulting gzipped source.
*/
function onClosureAdvancedGzip(exception, result) {
if (exception) {
throw exception;
}
if (!this.isSilent) {
console.log('Done. Size: %d bytes.', result.length);
}
this.compiled.advanced.gzip = result;
// next, minify the source using only UglifyJS
uglify.call(this, this.source, 'UglifyJS', onUglify.bind(this));
}
/**
* The UglifyJS callback.
*
* @private
* @param {Object|Undefined} exception The error object.
@@ -219,8 +290,8 @@
if (exception) {
throw exception;
}
// store the post-processed Uglified result and gzip it
this.uglified.source = result = postprocess(result);
result = postprocess(result);
this.uglified.source = result;
gzip(result, onUglifyGzip.bind(this));
}
@@ -235,86 +306,115 @@
if (exception) {
throw exception;
}
var message = 'Compressing ' + this.workingName + ' using hybrid minification...';
// store the gzipped result and report the size
if (!this.isSilent) {
console.log('Done. Size: %d bytes.', result.length);
}
this.uglified.gzip = result;
console.log('Done. Size: %d bytes.', result.length);
// next, minify the Closure Compiler minified source using UglifyJS
uglify.call(this, this.compiled.source, message, onHybrid.bind(this));
// next, minify the already Closure Compiler simple optimized source using UglifyJS
uglify.call(this, this.compiled.simple.source, 'hybrid (simple)', onSimpleHybrid.bind(this));
}
/**
* The hybrid `uglify()` callback.
* The hybrid callback for simple optimizations.
*
* @private
* @param {Object|Undefined} exception The error object.
* @param {String} result The resulting minified source.
*/
function onHybrid(exception, result) {
function onSimpleHybrid(exception, result) {
if (exception) {
throw exception;
}
// store the post-processed Uglified result and gzip it
this.hybrid.source = result = postprocess(result);
gzip(result, onHybridGzip.bind(this));
result = postprocess(result);
this.hybrid.simple.source = result;
gzip(result, onSimpleHybridGzip.bind(this));
}
/**
* The hybrid `gzip` callback.
* The hybrid `gzip` callback for simple optimizations.
*
* @private
* @param {Object|Undefined} exception The error object.
* @param {Buffer} result The resulting gzipped source.
*/
function onHybridGzip(exception, result) {
function onSimpleHybridGzip(exception, result) {
if (exception) {
throw exception;
}
// store the gzipped result and report the size
this.hybrid.gzip = result;
console.log('Done. Size: %d bytes.', result.length);
if (!this.isSilent) {
console.log('Done. Size: %d bytes.', result.length);
}
this.hybrid.simple.gzip = result;
// next, minify the already Closure Compiler advance optimized source using UglifyJS
uglify.call(this, this.compiled.advanced.source, 'hybrid (advanced)', onAdvancedHybrid.bind(this));
}
/**
* The hybrid callback for advanced optimizations.
*
* @private
* @param {Object|Undefined} exception The error object.
* @param {String} result The resulting minified source.
*/
function onAdvancedHybrid(exception, result) {
if (exception) {
throw exception;
}
result = postprocess(result);
this.hybrid.advanced.source = result;
gzip(result, onAdvancedHybridGzip.bind(this));
}
/**
* The hybrid `gzip` callback for advanced optimizations.
*
* @private
* @param {Object|Undefined} exception The error object.
* @param {Buffer} result The resulting gzipped source.
*/
function onAdvancedHybridGzip(exception, result) {
if (exception) {
throw exception;
}
if (!this.isSilent) {
console.log('Done. Size: %d bytes.', result.length);
}
this.hybrid.advanced.gzip = result;
// finish by choosing the smallest compressed file
onComplete.call(this);
}
/**
* The callback executed after JavaScript source is minified and gzipped.
* The callback executed after the source is minified and gzipped.
*
* @private
*/
function onComplete() {
var compiled = this.compiled,
hybrid = this.hybrid,
name = this.workingName,
uglified = this.uglified;
// save the Closure Compiled version to disk
fs.writeFileSync(path.join(distPath, name + '.compiler.js'), compiled.source);
fs.writeFileSync(path.join(distPath, name + '.compiler.js.gz'), compiled.gzip);
// save the Uglified version to disk
fs.writeFileSync(path.join(distPath, name + '.uglify.js'), uglified.source);
fs.writeFileSync(path.join(distPath, name + '.uglify.js.gz'), uglified.gzip);
// save the hybrid minified version to disk
fs.writeFileSync(path.join(distPath, name + '.hybrid.js'), hybrid.source);
fs.writeFileSync(path.join(distPath, name + '.hybrid.js.gz'), hybrid.gzip);
var compiledSimple = this.compiled.simple,
compiledAdvanced = this.compiled.advanced,
uglified = this.uglified,
hybridSimple = this.hybrid.simple,
hybridAdvanced = this.hybrid.advanced;
// select the smallest gzipped file and use its minified counterpart as the
// official minified release (ties go to Closure Compiler)
var min = Math.min(compiled.gzip.length, hybrid.gzip.length, uglified.gzip.length);
// pass the minified source to the minify instances "onComplete" callback
this.onComplete(
compiled.gzip.length == min
? compiled.source
: uglified.gzip.length == min
? uglified.source
: hybrid.source
// official minified release (ties go to the Closure Compiler)
var min = Math.min(
compiledSimple.gzip.length,
compiledAdvanced.gzip.length,
uglified.gzip.length,
hybridSimple.gzip.length,
hybridAdvanced.gzip.length
);
// pass the minified source to the "onComplete" callback
[compiledSimple, compiledAdvanced, uglified, hybridSimple, hybridAdvanced].some(function(data) {
if (data.gzip.length == min) {
this.onComplete(data.source);
}
}, this);
}
/*--------------------------------------------------------------------------*/
@@ -324,18 +424,15 @@
module.exports = minify;
}
else {
// read the JavaScript source file from the first argument if the script
// read the Lo-Dash source file from the first argument if the script
// was invoked directly (e.g. `node minify.js source.js`) and write to
// the same file
// `<filename>.min.js`
(function() {
var filePath = process.argv[2],
dirPath = path.dirname(filePath),
source = fs.readFileSync(filePath, 'utf8'),
workingName = path.basename(filePath, '.js') + '.min';
minify(source, workingName, function(result) {
fs.writeFileSync(path.join(dirPath, workingName + '.js'), result);
});
var options = process.argv;
if (options.length < 3) {
return;
}
minify(options);
}());
}
}());

View File

@@ -6,48 +6,52 @@
var fs = require('fs');
/** The minimal license/copyright template */
var licenseTemplate =
'/*!\n' +
' Lo-Dash @VERSION lodash.com/license\n' +
' Underscore.js 1.3.3 github.com/documentcloud/underscore/blob/master/LICENSE\n' +
'*/';
var licenseTemplate = {
'lodash':
'/*!\n' +
' Lo-Dash @VERSION lodash.com/license\n' +
' Underscore.js 1.4.3 underscorejs.org/LICENSE\n' +
'*/',
'underscore':
'/*! Underscore.js @VERSION underscorejs.org/LICENSE */'
};
/*--------------------------------------------------------------------------*/
/**
* Post-process a given minified JavaScript `source`, preparing it for
* Post-process a given minified Lo-Dash `source`, preparing it for
* deployment.
*
* @param {String} source The source to process.
* @returns {String} Returns the processed source.
*/
function postprocess(source) {
// exit early if snippet isn't found
// move vars exposed by the Closure Compiler into the IIFE
source = source.replace(/^((?:(['"])use strict\2;)?(?:var (?:[a-z]+=(?:!0|!1|null)[,;])+)?)([\s\S]*?function[^)]+\){)/, '$3$1');
// correct overly aggressive Closure Compiler advanced optimizations
source = source.replace(/prototype\s*=\s*{\s*valueOf\s*:\s*1\s*}/, 'prototype={valueOf:1,y:1}');
// unescape properties (i.e. foo["bar"] => foo.bar)
source = source.replace(/(\w)\["([^."]+)"\]/g, function(match, left, right) {
return /\W/.test(right) ? match : (left + '.' + right);
});
// correct AMD module definition for AMD build optimizers
source = source.replace(/("function")\s*==\s*(typeof define)\s*&&\s*\(?\s*("object")\s*==\s*(typeof define\.amd)\s*&&\s*(define\.amd)\s*\)?/, '$2==$1&&$4==$3&&$5');
// add trailing semicolon
if (source) {
source = source.replace(/[\s;]*$/, ';');
}
// exit early if version snippet isn't found
var snippet = /VERSION\s*[=:]\s*([\'"])(.*?)\1/.exec(source);
if (!snippet) {
return source;
}
// set the version
var license = licenseTemplate.replace('@VERSION', snippet[2]);
// move vars exposed by Closure Compiler into the IIFE
source = source.replace(/^([^(\n]+)\s*(\(function[^)]+\){)/, '$2$1');
// use double quotes consistently
source = source.replace(/'use strict'/, '"use strict"');
// unescape properties (i.e. foo["bar"] => foo.bar)
source = source.replace(/(\w)\["([^."]+)"\]/g, '$1.$2');
// correct AMD module definition for AMD build optimizers
source = source.replace(/("function")==(typeof define)&&\(?("object")==(typeof define\.amd)(&&define\.amd)\)?/, '$2==$1&&$4==$3$5');
// add license
source = license + '\n;' + source;
// add trailing semicolon
return source.replace(/[\s;]*$/, ';');
// add copyright/license header
return licenseTemplate[/call\(this\);?$/.test(source) ? 'underscore' : 'lodash']
.replace('@VERSION', snippet[2]) + '\n;' + source;
}
/*--------------------------------------------------------------------------*/
@@ -55,13 +59,20 @@
// expose `postprocess`
if (module != require.main) {
module.exports = postprocess;
} else {
// read the JavaScript source file from the first argument if the script
}
else {
// read the Lo-Dash source file from the first argument if the script
// was invoked directly (e.g. `node post-compile.js source.js`) and write to
// the same file
(function() {
var source = fs.readFileSync(process.argv[2], 'utf8');
fs.writeFileSync(process.argv[2], postprocess(source), 'utf8');
var options = process.argv;
if (options.length < 3) {
return;
}
var filePath = options[options.length - 1],
source = fs.readFileSync(filePath, 'utf8');
fs.writeFileSync(filePath, postprocess(source), 'utf8');
}());
}
}());

144
build/post-install.js Normal file
View File

@@ -0,0 +1,144 @@
#!/usr/bin/env node
;(function() {
'use strict';
/** Load Node modules */
var exec = require('child_process').exec,
fs = require('fs'),
https = require('https'),
path = require('path'),
tar = require('../vendor/tar/tar.js'),
zlib = require('zlib');
/** The path of the directory that is the base of the repository */
var basePath = fs.realpathSync(path.join(__dirname, '..'));
/** The path of the `vendor` directory */
var vendorPath = path.join(basePath, 'vendor');
/** The Git object ID of `closure-compiler.tar.gz` */
var closureId = 'a2787b470c577cee2404d186c562dd9835f779f5';
/** The Git object ID of `uglifyjs.tar.gz` */
var uglifyId = '3390b259e04829538e4d3635d12b317dd6103eca';
/** The media type for raw blob data */
var mediaType = 'application/vnd.github.v3.raw';
/** Used to reference parts of the blob href */
var location = (function() {
var host = 'api.github.com',
origin = 'https://api.github.com',
pathname = '/repos/bestiejs/lodash/git/blobs';
return {
'host': host,
'href': host + origin + pathname,
'origin': origin,
'pathname': pathname
};
}());
/*--------------------------------------------------------------------------*/
/**
* Fetches a required `.tar.gz` dependency with the given Git object ID from
* the Lo-Dash repo on GitHub. The object ID may be obtained by running
* `git hash-object path/to/dependency.tar.gz`.
*
* @private
* @param {Object} options The options object.
* id - The Git object ID of the `.tar.gz` file.
* onComplete - The function, invoked with one argument (exception),
* called once the extraction has finished.
* path - The path of the extraction directory.
* title - The dependency's title used in status updates logged to the console.
*/
function getDependency(options) {
options || (options = {});
var id = options.id,
onComplete = options.onComplete,
path = options.path,
title = options.title;
function callback(exception) {
if (exception) {
console.error([
'There was a problem installing ' + title + '. To manually install, run:',
'',
"curl -H 'Accept: " + mediaType + "' " + location.href + '/' + id + " | tar xvz -C '" + path + "'"
].join('\n'));
}
onComplete(exception);
}
console.log('Downloading ' + title + '...');
https.get({
'host': location.host,
'path': location.pathname + '/' + id,
'headers': {
// By default, all GitHub blob API endpoints return a JSON document
// containing Base64-encoded blob data. Overriding the `Accept` header
// with the GitHub raw media type returns the blob data directly.
// See http://developer.github.com/v3/media/.
'Accept': mediaType
}
}, function(response) {
var decompressor = zlib.createUnzip(),
parser = new tar.Extract({ 'path': path });
decompressor.on('error', callback)
parser.on('end', callback).on('error', callback);
response.pipe(decompressor).pipe(parser);
})
.on('error', callback);
}
/*--------------------------------------------------------------------------*/
exec('npm -g root', function(exception, stdout) {
if (!exception) {
try {
var isGlobal = path.resolve(basePath, '..') == fs.realpathSync(stdout.trim());
} catch(e) {
exception = e;
}
}
if (exception) {
console.error([
'Oops! There was a problem detecting the install mode. If youre installing the',
'Lo-Dash command-line executable (via `npm install -g lodash`), youll need to',
'manually install UglifyJS and the Closure Compiler by running:',
'',
"curl -H 'Accept: " + mediaType + "' " + location.href + '/' + closureId + " | tar xvz -C '" + vendorPath + "'",
"curl -H 'Accept: " + mediaType + "' " + location.href + '/' + uglifyId + " | tar xvz -C '" + vendorPath + "'",
'',
'Please submit an issue on the GitHub issue tracker: ' + process.env.npm_package_bugs_url
].join('\n'));
console.error(exception);
}
if (!isGlobal) {
return;
}
// download the Closure Compiler
getDependency({
'title': 'the Closure Compiler',
'id': closureId,
'path': vendorPath,
'onComplete': function() {
// download UglifyJS
getDependency({
'title': 'UglifyJS',
'id': uglifyId,
'path': vendorPath,
'onComplete': function() {
process.exit();
}
});
}
});
});
}());

View File

@@ -7,79 +7,74 @@
/** Used to minify variables embedded in compiled strings */
var compiledVars = [
'accumulator',
'arrayClass',
'bind',
'argsIndex',
'argsLength',
'callback',
'className',
'collection',
'createCallback',
'ctor',
'false',
'funcClass',
'guard',
'hasOwnProperty',
'identity',
'index',
'isArguments',
'isString',
'iteratee',
'length',
'nativeKeys',
'object',
'objectTypes',
'noaccum',
'property',
'ownIndex',
'ownProps',
'propertyIsEnumerable',
'result',
'skipProto',
'source',
'sourceIndex',
'stringClass',
'target',
'thisArg',
'toString',
'true',
'undefined',
'value'
'thisArg'
];
/** Used to minify `compileIterator` option properties */
var iteratorOptions = [
'args',
'array',
'arrayBranch',
'beforeLoop',
'arrayLoop',
'bottom',
'exit',
'firstArg',
'hasExp',
'hasDontEnumBug',
'inLoop',
'init',
'iteratedObject',
'loopExp',
'object',
'objectBranch',
'isKeysFast',
'objectLoop',
'noArgsEnum',
'noCharByIndex',
'shadowed',
'top',
'useHas'
'useHas',
'useStrict'
];
/** Used to minify variables and string values to a single character */
var minNames = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
minNames.push.apply(minNames, minNames.map(function(value) {
return value + value;
}));
/** Used to protect the specified properties from getting minified */
var propWhitelist = [
'_',
'_chain',
'_wrapped',
'__wrapped__',
'after',
'all',
'amd',
'any',
'assign',
'attachEvent',
'bind',
'bindAll',
'bindKey',
'chain',
'clearTimeout',
'clone',
'collect',
'compact',
'compose',
'contains',
'countBy',
'criteria',
'debounce',
'defaults',
@@ -87,12 +82,13 @@
'delay',
'detect',
'difference',
'drop',
'each',
'environment',
'escape',
'escape',
'evaluate',
'every',
'exports',
'extend',
'filter',
'find',
@@ -101,17 +97,22 @@
'foldl',
'foldr',
'forEach',
'forIn',
'forOwn',
'functions',
'global',
'groupBy',
'has',
'head',
'identity',
'include',
'index',
'indexOf',
'initial',
'inject',
'interpolate',
'intersection',
'invert',
'invoke',
'isArguments',
'isArray',
@@ -128,6 +129,7 @@
'isNull',
'isNumber',
'isObject',
'isPlainObject',
'isRegExp',
'isString',
'isUndefined',
@@ -137,15 +139,20 @@
'map',
'max',
'memoize',
'merge',
'methods',
'min',
'mixin',
'noConflict',
'object',
'omit',
'once',
'opera',
'pairs',
'partial',
'pick',
'pluck',
'random',
'range',
'reduce',
'reduceRight',
@@ -153,7 +160,6 @@
'rest',
'result',
'select',
'setTimeout',
'shuffle',
'size',
'some',
@@ -168,6 +174,7 @@
'throttle',
'times',
'toArray',
'unescape',
'union',
'uniq',
'unique',
@@ -176,65 +183,134 @@
'values',
'variable',
'VERSION',
'where',
'without',
'wrap',
'zip'
'zip',
// property used by the `lodash underscore` build
'__chain__',
// properties used by underscore.js
'_chain',
'_wrapped'
];
/*--------------------------------------------------------------------------*/
/**
* Pre-process a given JavaScript `source`, preparing it for minification.
* Pre-process a given Lo-Dash `source`, preparing it for minification.
*
* @param {String} source The source to process.
* @param {String} [source=''] The source to process.
* @param {Object} [options={}] The options object.
* @returns {String} Returns the processed source.
*/
function preprocess(source) {
// remove copyright to add later in post-compile.js
source = source.replace(/\/\*![\s\S]+?\*\//, '');
function preprocess(source, options) {
source || (source = '');
options || (options = {});
// correct JSDoc tags for Closure Compiler
// remove unrecognized JSDoc tags so the 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']");
if (options.isTemplate) {
return source;
}
// remove copyright/license header to add later in post-compile.js
source = source.replace(/\/\*![\s\S]+?\*\//, '');
// 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) {
return match == false || match == '\\n' ? '' : match;
});
// add brackets to whitelisted properties so the 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'), function(match, prop) {
return "['" + prop.replace(/['\n\r\t]/g, '\\$&') + "']";
});
// minify `_.sortBy` internal properties
(function() {
var properties = ['criteria', 'value'],
snippet = (source.match(/( +)function sortBy\b[\s\S]+?\n\1}/) || 0)[0],
result = snippet;
// remove brackets from `_.escape()` in `_.template`
source = source.replace(/__e *= *_\['escape']/g, '__e=_.escape');
if (snippet) {
// minify property strings
properties.forEach(function(property, index) {
result = result.replace(RegExp("'" + property + "'", 'g'), "'" + minNames[index] + "'");
});
// replace with modified snippet
source = source.replace(snippet, result);
// remove brackets from `_.escape()` in underscore.js `_.template`
source = source.replace(/_\['escape'\]\(__t'/g, '_.escape(__t');
// remove brackets from `collection.indexOf` in `_.contains`
source = source.replace("collection['indexOf'](target)", 'collection.indexOf(target)');
// remove brackets from `result[length].value` in `_.sortBy`
source = source.replace("result[length]['value']", 'result[length].value');
// remove whitespace from string literals
source = source.replace(/^([ "'\w]+:)? *"(?:(?=(\\?))\2.)*?"|'(?:(?=(\\?))\3.)*?'/gm, function(string, captured) {
// remove object literal property name
if (/:$/.test(captured)) {
string = string.slice(captured.length);
}
// avoids removing the '\n' of the `stringEscapes` object
string = string.replace(/\[object |delete |else |function | in |return\s+[\w"']|throw |typeof |use strict|var |@ |(["'])\\n\1|\\\\n|\\n|\s+/g, function(match) {
return match == false || match == '\\n' ? '' : match;
});
// prepend object literal property name
return (captured || '') + string;
});
// add newline to `+"__p+='"` in underscore.js `_.template`
source = source.replace(/\+"__p\+='"/g, '+"\\n__p+=\'"');
// add newline to `body + '}'` in `createFunction`
source = source.replace(/body *\+ *'}'/, 'body+"\\n}"');
// remove whitespace from `_.template` related regexes
source = source.replace(/(?:reEmptyString\w+|reInsertVariable) *=.+/g, function(match) {
return match.replace(/ |\\n/g, '');
});
// remove newline from double-quoted strings in `_.template`
source = source
.replace('"__p += \'"', '"__p+=\'"')
.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)* *var sourceURL[^;]+;|\+ *sourceURL/g, '');
// minify internal properties used by 'compareAscending' and `_.sortBy`
(function() {
var properties = ['criteria', 'index', 'value'],
snippets = source.match(/( +)function (?:compareAscending|sortBy)\b[\s\S]+?\n\1}/g);
if (!snippets) {
return;
}
snippets.forEach(function(snippet) {
var modified = snippet;
// minify properties
properties.forEach(function(property, index) {
var reBracketProp = RegExp("\\['(" + property + ")'\\]", 'g'),
reDotProp = RegExp('\\.' + property + '\\b', 'g'),
rePropColon = RegExp("([^?\\s])\\s*([\"'])?\\b" + property + "\\2 *:", 'g');
modified = modified
.replace(reBracketProp, "['" + minNames[index] + "']")
.replace(reDotProp, "['" + minNames[index] + "']")
.replace(rePropColon, "$1'" + minNames[index] + "':");
});
// replace with modified snippet
source = source.replace(snippet, modified);
});
}());
// minify all compilable snippets
var snippets = source.match(
RegExp([
// match the `iteratorTemplate`
'var iteratorTemplate\\b[\\s\\S]+?\\);\\n',
'( +)var iteratorTemplate\\b[\\s\\S]+?\\n\\1}',
// match methods created by `createIterator` calls
'createIterator\\((?:{|[a-zA-Z]+)[\\s\\S]+?\\);\\n',
// match variables storing `createIterator` options
'( +)var [a-zA-Z]+IteratorOptions\\b[\\s\\S]+?\\n\\1}',
'( +)var [a-zA-Z]+IteratorOptions\\b[\\s\\S]+?\\n\\2}',
// match the the `createIterator` function
'( +)function createIterator\\b[\\s\\S]+?\\n\\2}'
'( +)function createIterator\\b[\\s\\S]+?\\n\\3}'
].join('|'), 'g')
);
@@ -246,38 +322,28 @@
snippets.forEach(function(snippet, index) {
var isCreateIterator = /function createIterator\b/.test(snippet),
isIteratorTemplate = /var iteratorTemplate\b/.test(snippet),
result = snippet;
modified = snippet;
// add brackets to whitelisted properties so Closure Compiler won't mung them
result = result.replace(RegExp('\\.(' + iteratorOptions.join('|') + ')\\b', 'g'), "['$1']");
// add brackets to iterator option properties so the Closure Compiler won't mung them
modified = modified.replace(RegExp('\\.(' + iteratorOptions.join('|') + ')\\b', 'g'), function(match, prop) {
return "['" + prop.replace(/['\n\r\t]/g, '\\$&') + "']";
});
if (isCreateIterator) {
// add `true` and `false` arguments to be minified
result = result
.replace(/(Function\(\s*'[\s\S]+?)undefined/, '$1true,false,undefined')
.replace(/factory\([^)]+/, '$&,true,false');
// replace with modified snippet early and clip snippet so other arguments
// aren't minified
source = source.replace(snippet, result);
snippet = result = result.replace(/factory\([\s\S]+$/, '');
// replace with modified snippet early and clip snippet to the `factory`
// call so other arguments aren't minified
source = source.replace(snippet, modified);
snippet = modified = modified.replace(/factory\([\s\S]+$/, '');
}
// minify snippet variables / arguments
compiledVars.forEach(function(variable, index) {
// ensure properties in compiled strings aren't minified
result = result.replace(RegExp('([^.]\\b)' + variable + '\\b(?!\' *[\\]:])', 'g'), '$1' + minNames[index]);
modified = modified.replace(RegExp('([^.]\\b)' + variable + '\\b(?!\' *[\\]:])', 'g'), '$1' + minNames[index]);
// correct `typeof x == 'object'`
if (variable == 'object') {
result = result.replace(RegExp("(typeof [^']+')" + minNames[index] + "'", 'g'), "$1object'");
}
// correct external boolean literals
else if (variable == 'true' || variable == 'false') {
result = result
.replace(RegExp(': *' + minNames[index] + ',', 'g'), ':' + variable + ',')
.replace(RegExp('\\b' + minNames[index] + ';', 'g'), variable + ';');
// correct `typeof` values
if (/^(?:boolean|function|object|number|string|undefined)$/.test(variable)) {
modified = modified.replace(RegExp("(typeof [^']+')" + minNames[index] + "'", 'g'), '$1' + variable + "'");
}
});
@@ -285,26 +351,20 @@
iteratorOptions.forEach(function(property, index) {
if (isIteratorTemplate) {
// minify property names as interpolated template variables
result = result.replace(RegExp('\\b' + property + '\\b', 'g'), minNames[index]);
modified = modified.replace(RegExp('\\b' + property + '\\b', 'g'), minNames[index]);
}
else {
if (property == 'array' || property == 'object') {
// minify "array" and "object" sub property names
result = result.replace(RegExp("'" + property + "'( *[\\]:])", 'g'), "'" + minNames[index] + "'$1");
}
else {
// minify property name strings
result = result.replace(RegExp("'" + property + "'", 'g'), "'" + minNames[index] + "'");
// minify property names in regexps and accessors
if (isCreateIterator) {
result = result.replace(RegExp('([\\.|/])' + property + '\\b' , 'g'), '$1' + minNames[index]);
}
// minify property name strings
modified = modified.replace(RegExp("'" + property + "'", 'g'), "'" + minNames[index] + "'");
// minify property names in accessors
if (isCreateIterator) {
modified = modified.replace(RegExp('\\.' + property + '\\b' , 'g'), '.' + minNames[index]);
}
}
});
// replace with modified snippet
source = source.replace(snippet, result);
source = source.replace(snippet, modified);
});
return source;
@@ -317,12 +377,21 @@
module.exports = preprocess;
}
else {
// read the JavaScript source file from the first argument if the script
// read the Lo-Dash source file from the first argument if the script
// was invoked directly (e.g. `node pre-compile.js source.js`) and write to
// the same file
(function() {
var source = fs.readFileSync(process.argv[2], 'utf8');
fs.writeFileSync(process.argv[2], preprocess(source), 'utf8');
var options = process.argv;
if (options.length < 3) {
return;
}
var filePath = options[options.length - 1],
isTemplate = options.indexOf('-t') > -1 || options.indexOf('--template') > -1,
source = fs.readFileSync(filePath, 'utf8');
fs.writeFileSync(filePath, preprocess(source, {
'isTemplate': isTemplate
}), 'utf8');
}());
}
}());

File diff suppressed because it is too large Load Diff

View File

@@ -20,9 +20,10 @@
// generate Markdown
$markdown = docdown(array(
'path' => '../' . $file,
'title' => 'Lo-Dash <sup>v0.2.2</sup>',
'url' => 'https://github.com/bestiejs/lodash/blob/master/lodash.js'
'path' => '../' . $file,
'title' => 'Lo-Dash <sup>v1.0.0-rc.2</sup>',
'toc' => 'categories',
'url' => 'https://github.com/bestiejs/lodash/blob/master/lodash.js'
));
// save to a .md file

1
index.js Executable file
View File

@@ -0,0 +1 @@
module.exports = require('./lodash');

4971
lodash.js

File diff suppressed because it is too large Load Diff

67
lodash.min.js vendored
View File

@@ -1,30 +1,41 @@
/*!
Lo-Dash 0.2.2 lodash.com/license
Underscore.js 1.3.3 github.com/documentcloud/underscore/blob/master/LICENSE
Lo-Dash 1.0.0-rc.2 lodash.com/license
Underscore.js 1.4.3 underscorejs.org/LICENSE
*/
;(function(u,n){"use strict";function S(a){return"[object Arguments]"==i.call(a)}function b(a){return new p(a)}function p(a){if(a&&a._wrapped)return a;this._wrapped=a}function k(){for(var a,c,d,j=-1,b=arguments.length,e={e:"",f:"",k:"",q:"",c:{d:"",m:"++l<m"},o:{d:""}};++j<b;)for(c in a=arguments[j],a)d=(d=a[c])==o?"":d,/d|m|j/.test(c)?("string"==typeof d&&(d={b:d,n:d}),e.c[c]=d.b,e.o[c]=d.n):e[c]=d;a=e.a,c=e.c,d=e.o;var j=/^[^,]+/.exec(a)[0],b=d.m,g=/\S+$/.exec(b||j)[0];e.g=j,e.i=H,e.h="j.call("+
g+",l)",e.l=g,e.p=ca,e.r=e.r!==q,e.f||(e.f="if(!"+j+")return r");if("n"==j||!c.j)e.c=o;return b||(d.m="l in "+g),Function("b,c,i,j,k,o,v,y,z,h,A",'"use strict";return function('+a+"){"+sa(e)+"}")(I,v,r,s,da,J,K,i,m,q)}function ta(a,c){return w[c]}function ua(a){return"\\"+va[a]}function ea(){}function wa(a,c){var d=w.length;return w[d]="'+((__t=("+c+"))==null?'':_['escape'](__t))+'",T+d}function xa(a,c){var d=w.length;return w[d]="'+((__t=("+c+"))==null?'':__t)+'",T+d}function ya(a,c){var d=w.length
;return w[d]="';"+c+";__p+='",T+d}function fa(a,c,d,j){if(!a)return d;var b=a.length,e=3>arguments.length;j&&(c=v(c,j));if(b===+b){for(b&&e&&(d=a[--b]);b--;)d=c(d,a[b],b,a);return d}var g=U(a);for((b=g.length)&&e&&(d=a[g[--b]]);b--;)e=g[b],d=c(d,a[e],e,a);return d}function V(a,c,d){return c==n||d?a[0]:l.call(a,0,c)}function ga(a,c){for(var d,b=-1,f=a.length,e=[];++b<f;)d=a[b],W(d)?L.apply(e,c?d:ga(d)):e.push(d);return e}function x(a,c,d){var b;if(!a)return-1;if(d)return d=ha(a,c),a[d]===c?d:-1;d=0
;for(b=a.length;d<b;d++)if(a[d]===c)return d;return-1}function ia(a,c,d){var b=-Infinity,f=-1,e=a.length,g=b;if(!c){for(;++f<e;)a[f]>g&&(g=a[f]);return g}for(d&&(c=v(c,d));++f<e;)d=c(a[f],f,a),d>b&&(b=d,g=a[f]);return g}function ja(a,c,d){return l.call(a,c==n||d?1:c)}function ha(a,c,d){var b,f=0,e=a.length;for(d&&(c=d(c));f<e;)b=f+e>>1,(d?d(a[b]):a[b])<c?f=b+1:e=b;return f}function ka(a,c,d){for(var b,f=-1,e=a.length,g=[],h=[];++f<e;)if(b=d?d(a[f]):a[f],c?!f||h[h.length-1]!==b:0>x(h,b))h.push(b),
g.push(a[f]);return g}function v(a,c){function d(){var g=arguments,h=c;return f||(a=c[b]),e.length&&(g=g.length?M.apply(e,g):e),this instanceof d?(ea.prototype=a.prototype,h=new ea,g=a.apply(h,g),J[typeof g]&&g!==o?g:h):a.apply(h,g)}var b,f=i.call(a)==r;if(f){if(y)return y.call.apply(y,arguments)}else b=c,c=a;var e=l.call(arguments,2);return d}function N(a,c,d){d||(d=[]);if(a===c)return 0!==a||1/a==1/c;if(a==n||c==n)return a===c;a._chain&&(a=a._wrapped),c._chain&&(c=c._wrapped);if(a.isEqual&&i.call
(a.isEqual)==r)return a.isEqual(c);if(c.isEqual&&i.call(c.isEqual)==r)return c.isEqual(a);var b=i.call(a);if(b!=i.call(c))return q;switch(b){case K:return a==""+c;case O:return a!=+a?c!=+c:0==a?1/a==1/c:a==+c;case la:case ma:return+a==+c;case na:return a.source==c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if("object"!=typeof a||"object"!=typeof c)return q;for(var f=d.length;f--;)if(d[f]==a)return m;var f=-1,e=m,g=0;d.push(a);if(b==I){if(g=a.length,e=g==c.length
)for(;g--&&(e=N(a[g],c[g],d)););}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return q;for(var h in a)if(s.call(a,h)&&(g++,!(e=s.call(c,h)&&N(a[h],c[h],d))))break;if(e){for(h in c)if(s.call(c,h)&&!(g--))break;e=!g}if(e&&H)for(;7>++f&&(h=ca[f],!s.call(a,h)||!!(e=s.call(c,h)&&N(a[h],c[h],d))););}return d.pop(),e}function da(a){return a}function oa(a){C(P(a),function(c){var d=b[c]=a[c];p.prototype[c]=function(){var a=[this._wrapped];return arguments.length&&L.apply(a,arguments
),a=1==a.length?d.call(b,a[0]):d.apply(b,a),this._chain&&(a=new p(a),a._chain=m),a}})}var m=!0,o=null,q=!1,X="object"==typeof exports&&exports&&("object"==typeof global&&global&&global==global.global&&(u=global),exports),va={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"},H=!{valueOf:0}.propertyIsEnumerable("valueOf"),za=0,J={"boolean":q,"function":m,object:m,number:q,string:q,"undefined":q},Aa=u._,z=RegExp("^"+({}.valueOf+"").replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&"
).replace(/valueOf|for [^\]]+/g,".+?")+"$"),Ba=/__token__(\d+)/g,Ca=/['\n\r\t\u2028\u2029\\]/g,ca="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),T="__token__",w=[],I="[object Array]",la="[object Boolean]",ma="[object Date]",r="[object Function]",O="[object Number]",na="[object RegExp]",K="[object String]",A=Array.prototype,D=Object.prototype,M=A.concat,s=D.hasOwnProperty,L=A.push,l=A.slice,i=D.toString,y=z.test(y=l.bind)&&/\n|Opera/.test
(y+i.call(u.opera))&&y,E=z.test(E=Array.isArray)&&E,Da=u.isFinite,Y=z.test(Y=Object.keys)&&Y,Ea=u.clearTimeout,Q=u.setTimeout;b.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:"obj"};var sa=Function("obj","var __p;with(obj){__p='var l,r';if(k){__p+='='+k};__p+=';'+f+';'+q+';';if(c){__p+='var m='+g+'.length;l=-1;';if(o){__p+='if(m===+m){'};__p+=''+c['d']+';while('+c['m']+'){'+c['j']+'}';if(o){__p+='}'}}if(o){if(c){__p+='else{'}if(!i){__p+='var s=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(!(s&&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 r'}return __p"
),t={a:"f,d,x",k:"f",q:"if(!d){d=k}else if(x){d=c(d,x)}",j:"d(f[l],l,f)"},Z={k:"z",j:"if(!d(f[l],l,f))return!r"},$={a:"n",k:"n",q:"for(var t,u=1,m=arguments.length;u<m;u++){t=arguments[u];"+(H?"if(t){":""),m:"l in t",r:q,j:"n[l]=t[l]",e:(H?"}":"")+"}"},F={k:"[]",j:"d(f[l],l,f)&&r.push(f[l])"},B={q:"if(x)d=c(d,x)"},G={k:"",f:"if(!f)return[]",d:{b:"r=Array(m)",n:"r=[]"},j:{b:"r[l]=d(f[l],l,f)",n:"r.push(d(f[l],l,f))"}},z=k({a:"f,w",k:"h",j:"if(f[l]===w)return z"}),aa=k(t,Z),D=k(t,F),pa=k(t,B,{k:"",
j:"if(d(f[l],l,f))return f[l]"}),C=k(t,B),ba=k(t,G),R=k(G,{a:"f,q",j:{b:"r[l]=f[l][q]",n:"r.push(f[l][q])"}}),B=k({a:"f,d,a,x",k:"a",q:"var p=arguments.length<3;if(x)d=c(d,x)",d:{b:"if(p)r=f[++l]"},j:{b:"r=d(r,f[l],l,f)",n:"r=p?(p=h,f[l]):d(r,f[l],l,f)"}}),F=k(t,F,{j:"!"+F.j}),t=k(t,Z,{k:"h",j:Z.j.replace("!","")}),qa=k(G,{a:"f",j:{b:"r[l]=f[l]",n:"r.push(f[l])"}}),G=k($,{j:"if(n[l]==A)"+$.j}),ra=k($),P=k({a:"n",k:"[]",r:q,j:"if(y.call(n[l])==i)r.push(l)",e:"r.sort()"});S(arguments)||(S=function(
a){return!!a&&!!s.call(a,"callee")});var W=E||function(a){return i.call(a)==I},E=k({a:"B",k:"z",q:"var e=y.call(B);if(e==b||e==v)return!B.length",j:{n:"return h"}}),U=Y||k({a:"n",f:"if(!o[typeof n]||n===null)throw TypeError()",k:"[]",j:"r.push(l)"});b.VERSION="0.2.2",b.after=function(a,c){return 1>a?c():function(){if(1>--a)return c.apply(this,arguments)}},b.bind=v,b.bindAll=function(a){var c=arguments,d=1;1==c.length&&(d=0,c=P(a));for(var b=c.length;d<b;d++)a[c[d]]=v(a[c[d]],a);return a},b.chain=
function(a){return a=new p(a),a._chain=m,a},b.clone=function(a){return J[typeof a]&&a!==o?W(a)?a.slice():ra({},a):a},b.compact=function(a){for(var c=-1,d=a.length,b=[];++c<d;)a[c]&&b.push(a[c]);return b},b.compose=function(){var a=arguments;return function(){for(var c=arguments,d=a.length;d--;)c=[a[d].apply(this,c)];return c[0]}},b.contains=z,b.debounce=function(a,c,d){function b(){h=n,d||a.apply(g,f)}var f,e,g,h;return function(){var i=d&&!h;return f=arguments,g=this,Ea(h),h=Q(b,c),i&&(e=a.apply
(g,f)),e}},b.defaults=G,b.defer=function(a){var c=l.call(arguments,1);return Q(function(){return a.apply(n,c)},1)},b.delay=function(a,c){var d=l.call(arguments,2);return Q(function(){return a.apply(n,d)},c)},b.difference=function(a){for(var c=-1,d=a.length,b=[],f=M.apply(b,l.call(arguments,1));++c<d;)0>x(f,a[c])&&b.push(a[c]);return b},b.escape=function(a){return(a+"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;")},b.every=aa,b.extend=ra,b.filter=D,b.find=
pa,b.first=V,b.flatten=ga,b.forEach=C,b.functions=P,b.groupBy=function(a,c,d){var b,f=-1,e=i.call(c)==r,g=a.length,h={};for(e&&d&&(c=v(c,d));++f<g;)b=a[f],d=e?c(b,f,a):b[c],(s.call(h,d)?h[d]:h[d]=[]).push(b);return h},b.has=function(a,c){return s.call(a,c)},b.identity=da,b.indexOf=x,b.initial=function(a,c,d){return l.call(a,0,-(c==n||d?1:c))},b.intersection=function(a){for(var c,d=-1,b=a.length,f=l.call(arguments,1),e=[];++d<b;)c=a[d],0>x(e,c)&&aa(f,function(a){return-1<x(a,c)})&&e.push(c);return e
},b.invoke=function(a,c){for(var d=l.call(arguments,2),b=-1,f=a.length,e=i.call(c)==r,g=[];++b<f;)g[b]=(e?c:a[b][c]).apply(a[b],d);return g},b.isArguments=S,b.isArray=W,b.isBoolean=function(a){return a===m||a===q||i.call(a)==la},b.isDate=function(a){return i.call(a)==ma},b.isElement=function(a){return!!a&&1==a.nodeType},b.isEmpty=E,b.isEqual=N,b.isFinite=function(a){return Da(a)&&i.call(a)==O},b.isFunction=function(a){return i.call(a)==r},b.isNaN=function(a){return i.call(a)==O&&a!=+a},b.isNull=function(
a){return a===o},b.isNumber=function(a){return i.call(a)==O},b.isObject=function(a){return J[typeof a]&&a!==o},b.isRegExp=function(a){return i.call(a)==na},b.isString=function(a){return i.call(a)==K},b.isUndefined=function(a){return a===n},b.keys=U,b.last=function(a,c,d){var b=a.length;return c==n||d?a[b-1]:l.call(a,-c||b)},b.lastIndexOf=function(a,c){if(!a)return-1;for(var d=a.length;d--;)if(a[d]===c)return d;return-1},b.map=ba,b.max=ia,b.memoize=function(a,c){var d={};return function(){var b=c?
c.apply(this,arguments):arguments[0];return s.call(d,b)?d[b]:d[b]=a.apply(this,arguments)}},b.min=function(a,c,d){var b=Infinity,f=-1,e=a.length,g=b;if(!c){for(;++f<e;)a[f]<g&&(g=a[f]);return g}for(d&&(c=v(c,d));++f<e;)d=c(a[f],f,a),d<b&&(b=d,g=a[f]);return g},b.mixin=oa,b.noConflict=function(){return u._=Aa,this},b.once=function(a){var c,d=q;return function(){return d?c:(d=m,c=a.apply(this,arguments))}},b.partial=function(a){var c=l.call(arguments,1),d=c.length;return function(){var b;return b=arguments
,b.length&&(c.length=d,L.apply(c,b)),b=1==c.length?a.call(this,c[0]):a.apply(this,c),c.length=d,b}},b.pick=function(a){for(var c,d=0,b=M.apply(A,arguments),f=b.length,e={};++d<f;)c=b[d],c in a&&(e[c]=a[c]);return e},b.pluck=R,b.range=function(a,c,d){d||(d=1),2>arguments.length&&(c=a||0,a=0);for(var b=-1,f=Math.max(Math.ceil((c-a)/d),0),e=Array(f);++b<f;)e[b]=a,a+=d;return e},b.reduce=B,b.reduceRight=fa,b.reject=F,b.rest=ja,b.result=function(a,c){if(!a)return o;var d=a[c];return i.call(d)==r?a[c](
):d},b.shuffle=function(a){for(var c,d=-1,b=a.length,f=Array(b);++d<b;)c=Math.floor(Math.random()*(d+1)),f[d]=f[c],f[c]=a[d];return f},b.size=function(a){var c=i.call(a);return c==I||c==K?a.length:U(a).length},b.some=t,b.sortBy=function(a,c,d){if(i.call(c)!=r)var b=c,c=function(a){return a[b]};else d&&(c=v(c,d));return R(ba(a,function(b,d){return{a:c(b,d,a),b:b}}).sort(function(a,c){var b=a.a,d=c.a;return b===n?1:d===n?-1:b<d?-1:b>d?1:0}),"b")},b.sortedIndex=ha,b.tap=function(a,c){return c(a),a},
b.template=function(a,c,d){d||(d={});var j;j=b.templateSettings;var f=d.escape,e=d.evaluate,g=d.interpolate,d=d.variable;return f==o&&(f=j.escape),e==o&&(e=j.evaluate),g==o&&(g=j.interpolate),f&&(a=a.replace(f,wa)),g&&(a=a.replace(g,xa)),e&&(a=a.replace(e,ya)),a="__p='"+a.replace(Ca,ua).replace(Ba,ta)+"';\n",w.length=0,d||(d=j.variable,a="with("+d+"||{}){"+a+"}"),a="function("+d+"){var __p,__t,__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}"+a+"return __p}",j=Function("_","return "+
a)(b),c?j(c):(j.source=a,j)},b.throttle=function(a,c){function b(){h=new Date,g=n,a.apply(e,j)}var j,f,e,g,h=0;return function(){var i=new Date,k=c-(i-h);return j=arguments,e=this,0>=k?(h=i,f=a.apply(e,j)):g||(g=Q(b,k)),f}},b.times=function(a,c,b){b&&(c=v(c,b));for(b=0;b<a;b++)c(b)},b.toArray=function(a){if(!a)return[];if(i.call(a.toArray)==r)return a.toArray();var b=a.length;return b===+b?l.call(a):qa(a)},b.union=function(){for(var a=-1,b=[],d=M.apply(b,arguments),i=d.length;++a<i;)0>x(b,d[a])&&
b.push(d[a]);return b},b.uniq=ka,b.uniqueId=function(a){var b=za++;return a?a+b:b},b.values=qa,b.without=function(a){for(var b=l.call(arguments,1),d=-1,i=a.length,f=[];++d<i;)0>x(b,a[d])&&f.push(a[d]);return f},b.wrap=function(a,b){return function(){var d=[a];return arguments.length&&L.apply(d,arguments),b.apply(this,d)}},b.zip=function(){for(var a=-1,b=ia(R(arguments,"length")),d=Array(b);++a<b;)d[a]=R(arguments,a);return d},b.all=aa,b.any=t,b.collect=ba,b.detect=pa,b.each=C,b.foldl=B,b.foldr=fa
,b.head=V,b.include=z,b.inject=B,b.methods=P,b.select=D,b.tail=ja,b.take=V,b.unique=ka,p.prototype=b.prototype,oa(b),p.prototype.chain=function(){return this._chain=m,this},p.prototype.value=function(){return this._wrapped},C("pop push reverse shift sort splice unshift".split(" "),function(a){var b=A[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._chain&&(a=new p(a),a._chain=m),a}}),C(["concat","join","slice"]
,function(a){var b=A[a];p.prototype[a]=function(){var a=this._wrapped,a=arguments.length?b.apply(a,arguments):b.call(a);return this._chain&&(a=new p(a),a._chain=m),a}}),typeof define=="function"&&typeof define.amd=="object"&&define.amd?(u._=b,define(function(){return b})):X?"object"==typeof module&&module&&module.s==X?(module.s=b)._=b:X._=b:u._=b})(this);
;(function(e,t){function s(e){if(e&&"object"==typeof e&&e.__wrapped__)return e;if(!(this instanceof s))return new s(e);this.__wrapped__=e}function o(t,n){return e.eval("(function("+t+"){"+n+"})")}function u(e,t,n){t||(t=0);var r=e.length,i=r-t>=(n||it);if(i)for(var s={},n=t-1;++n<r;){var o=e[n]+"";(Tt.call(s,o)?s[o]:s[o]=[]).push(e[n])}return function(n){if(i){var r=n+"";return Tt.call(s,r)&&-1<W(s[r],n)}return-1<W(e,n,t)}}function a(e){return e.charCodeAt(0)}function f(e,t){var n=e.b,r=t.b,e=e.a,
t=t.a;if(e!==t){if(e>t||"undefined"==typeof e)return 1;if(e<t||"undefined"==typeof t)return-1}return n<r?-1:1}function l(e,t,n){function i(){var a=arguments,f=o?this:t;return s||(e=t[u]),n.length&&(a=a.length?n.concat(g(a)):n),this instanceof i?(m.prototype=e.prototype,f=new m,m.prototype=r,a=e.apply(f,a),k(a)?a:f):e.apply(f,a)}var s=C(e),o=!n,u=t;return o&&(n=t),s||(t=e),i}function c(e,t){return e?"function"!=typeof e?function(t){return t[e]}:"undefined"!=typeof t?function(n,r,i){return e.call(t
,n,r,i)}:e:K}function h(){for(var e={b:"",c:"",e:Kt,f:Jt,g:"",h:Yt,i:en,j:bt,k:"",l:n},t,r=0;t=arguments[r];r++)for(var i in t)e[i]=t[i];t=e.a,e.d=/^[^,]+/.exec(t)[0],r="var i,l="+e.d+",t="+e.d+";if(!"+e.d+")return t;"+e.k+";",e.b?(r+="var m=l.length;i=-1;if(typeof m=='number'){",e.i&&(r+="if(k(l)){l=l.split('')}"),r+="while(++i<m){"+e.b+"}}else {"):e.h&&(r+="var m=l.length;i=-1;if(m&&j(l)){while(++i<m){i+='';"+e.g+"}}else {"),e.e||(r+="var u=typeof l=='function'&&s.call(l,'prototype');");if(e.f&&
e.l)r+="var q=-1,r=p[typeof l]?n(l):[],m=r.length;while(++q<m){i=r[q];",e.e||(r+="if(!(u&&i=='prototype')){"),r+=e.g+"",e.e||(r+="}");else{r+="for(i in l){";if(!e.e||e.l)r+="if(",e.e||(r+="!(u&&i=='prototype')"),!e.e&&e.l&&(r+="&&"),e.l&&(r+="h.call(l,i)"),r+="){";r+=e.g+";";if(!e.e||e.l)r+="}"}r+="}";if(e.e){r+="var f=l.constructor;";for(i=0;7>i;i++)r+="i='"+e.j[i]+"';if(","constructor"==e.j[i]&&(r+="!(f&&f.prototype===l)&&"),r+="h.call(l,i)){"+e.g+"}"}if(e.b||e.h)r+="}";return r+=e.c+";return t"
,o("e,h,j,k,p,n,s","return function("+t+"){"+r+"}")(c,Tt,b,A,on,_t,Ct)}function p(e){return"\\"+un[e]}function d(e){return dn[e]}function v(e){return"function"!=typeof e.toString&&"string"==typeof (e+"")}function m(){}function g(e,t,n){t||(t=0),"undefined"==typeof n&&(n=e?e.length:0);for(var r=-1,n=n-t||0,i=Array(0>n?0:n);++r<n;)i[r]=e[t+r];return i}function y(e){return vn[e]}function b(e){return kt.call(e)==Bt}function w(e){var t=i;if(!e||"object"!=typeof e||b(e))return t;var n=e.constructor;return!
C(n)&&(!tn||!v(e))||n instanceof n?Qt?(hn(e,function(e,n,r){return t=!Tt.call(r,n),i}),t===i):(hn(e,function(e,n){t=n}),t===i||Tt.call(e,t)):t}function E(e){var t=[];return pn(e,function(e,n){t.push(n)}),t}function S(e,t,n,s,o){if(e==r)return e;n&&(t=i);if(n=k(e)){var u=kt.call(e);if(!rn[u]||tn&&v(e))return e;var a=gn(e)}if(!n||!t)return n?a?g(e):cn({},e):e;n=sn[u];switch(u){case Ft:case It:return new n(+e);case qt:case zt:return new n(e);case Ut:return n(e.source,ct.exec(e))}s||(s=[]),o||(o=[]);
for(u=s.length;u--;)if(s[u]==e)return o[u];var f=a?n(e.length):{};return s.push(e),o.push(f),(a?wn:pn)(e,function(e,n){f[n]=S(e,t,r,s,o)}),a&&(Tt.call(e,"index")&&(f.index=e.index),Tt.call(e,"input")&&(f.input=e.input)),f}function x(e){var t=[];return hn(e,function(e,n){C(e)&&t.push(n)}),t.sort()}function T(e){var t={};return pn(e,function(e,n){t[e]=n}),t}function N(e,t,s,o){if(e===t)return 0!==e||1/e==1/t;if(e==r||t==r)return e===t;var u=kt.call(e),a=kt.call(t);u==Bt&&(u=Rt),a==Bt&&(a=Rt);if(u!=
a)return i;switch(u){case Ft:case It:return+e==+t;case qt:return e!=+e?t!=+t:0==e?1/e==1/t:e==+t;case Ut:case zt:return e==t+""}a=u==jt;if(!a){if(e.__wrapped__||t.__wrapped__)return N(e.__wrapped__||e,t.__wrapped__||t);if(u!=Rt||tn&&(v(e)||v(t)))return i;var u=Zt&&b(e)?Object:e.constructor,f=Zt&&b(t)?Object:t.constructor;if(u!=f&&(!C(u)||!(u instanceof u&&C(f)&&f instanceof f)))return i}s||(s=[]),o||(o=[]);for(u=s.length;u--;)if(s[u]==e)return o[u]==t;var l=n,c=0;s.push(e),o.push(t);if(a){c=e.length
;if(l=c==t.length)for(;c--&&(l=N(e[c],t[c],s,o)););return l}return hn(e,function(e,n,r){if(Tt.call(r,n))return c++,l=Tt.call(t,n)&&N(e,t[n],s,o)}),l&&hn(t,function(e,t,n){if(Tt.call(n,t))return l=-1<--c}),l}function C(e){return"function"==typeof e}function k(e){return e?on[typeof e]:i}function L(e){return"number"==typeof e||kt.call(e)==qt}function A(e){return"string"==typeof e||kt.call(e)==zt}function O(e,t,n){var i=arguments,s=0,o=2,u=i[3],a=i[4];n!==rt&&(u=[],a=[],"number"!=typeof n&&(o=i.length
));for(;++s<o;)pn(i[s],function(t,n){var i,s,o;if(t&&((s=gn(t))||yn(t))){for(var f=u.length;f--;)if(i=u[f]==t)break;i?e[n]=a[f]:(u.push(t),a.push(o=(o=e[n],s)?gn(o)?o:[]:yn(o)?o:{}),e[n]=O(o,t,rt,u,a))}else t!=r&&(e[n]=t)});return e}function M(e){var t=[];return pn(e,function(e){t.push(e)}),t}function _(e,t,n){var r=-1,s=e?e.length:0,o=i,n=(0>n?Dt(0,s+n):n)||0;return"number"==typeof s?o=-1<(A(e)?e.indexOf(t,n):W(e,t,n)):wn(e,function(e){if(++r>=n)return!(o=e===t)}),o}function D(e,t,r){var i=n,t=c
(t,r);if(gn(e))for(var r=-1,s=e.length;++r<s&&(i=!!t(e[r],r,e)););else wn(e,function(e,n,r){return i=!!t(e,n,r)});return i}function P(e,t,n){var r=[],t=c(t,n);if(gn(e))for(var n=-1,i=e.length;++n<i;){var s=e[n];t(s,n,e)&&r.push(s)}else wn(e,function(e,n,i){t(e,n,i)&&r.push(e)});return r}function H(e,t,n){var r,t=c(t,n);return wn(e,function(e,n,s){if(t(e,n,s))return r=e,i}),r}function B(e,t,n){var r=-1,i=e?e.length:0,s=Array("number"==typeof i?i:0),t=c(t,n);if(gn(e))for(;++r<i;)s[r]=t(e[r],r,e);else wn
(e,function(e,n,i){s[++r]=t(e,n,i)});return s}function j(e,t,n){var r=-Infinity,i=-1,s=e?e.length:0,o=r;if(t||!gn(e))t=!t&&A(e)?a:c(t,n),wn(e,function(e,n,i){n=t(e,n,i),n>r&&(r=n,o=e)});else for(;++i<s;)e[i]>o&&(o=e[i]);return o}function F(e,t){return B(e,t+"")}function I(e,t,n,r){var s=3>arguments.length;return t||(t=K),wn(e,function(e,o,u){n=s?(s=i,e):t.call(r,n,e,o,u)}),n}function q(e,t,n,r){var s=e,o=e?e.length:0,u=3>arguments.length;if("number"!=typeof o)var a=bn(e),o=a.length;else en&&A(e)&&
(s=e.split(""));return t||(t=K),wn(e,function(e,f,l){f=a?a[--o]:--o,n=u?(u=i,s[f]):t.call(r,n,s[f],f,l)}),n}function R(e,t,n){var r,t=c(t,n);if(gn(e))for(var n=-1,i=e.length;++n<i&&!(r=t(e[n],n,e)););else wn(e,function(e,n,i){return!(r=t(e,n,i))});return!!r}function U(e,t,n){if(e){var i=e.length;return t==r||n?e[0]:g(e,0,Pt(Dt(0,t),i))}}function z(e,t){for(var n=-1,r=e?e.length:0,i=[];++n<r;){var s=e[n];gn(s)?Nt.apply(i,t?s:z(s)):i.push(s)}return i}function W(e,t,n){var r=-1,i=e?e.length:0;if("number"==typeof
n)r=(0>n?Dt(0,i+n):n||0)-1;else if(n)return r=V(e,t),e[r]===t?r:-1;for(;++r<i;)if(e[r]===t)return r;return-1}function X(e,t,n){return g(e,t==r||n?1:Dt(0,t))}function V(e,t,n,r){for(var i=0,s=e?e.length:i,n=n?c(n,r):K,t=n(t);i<s;)r=i+s>>>1,n(e[r])<t?i=r+1:s=r;return i}function $(e,t,n,r){var s=-1,o=e?e.length:0,u=[],a=u;"function"==typeof t&&(r=n,n=t,t=i);var f=!t&&74<o;if(f)var l={};n&&(a=[],n=c(n,r));for(;++s<o;){var r=e[s],h=n?n(r,s,e):r;f&&(a=Tt.call(l,h+"")?l[h]:l[h]=[]);if(t?!s||a[a.length-1
]!==h:0>W(a,h))(n||f)&&a.push(h),u.push(r)}return u}function J(e,t){return $t||Lt&&2<arguments.length?Lt.call.apply(Lt,arguments):l(e,t,g(arguments,2))}function K(e){return e}function Q(e){wn(x(e),function(t){var n=s[t]=e[t];s.prototype[t]=function(){var e=[this.__wrapped__];return Nt.apply(e,arguments),e=n.apply(s,e),new s(e)}})}function G(){return this.__wrapped__}var n=!0,r=null,i=!1,Y="object"==typeof exports&&exports,Z="object"==typeof global&&global;Z.global===Z&&(e=Z);var et=[],tt=new function(
){},nt=0,rt=tt,it=30,st=e._,ot=/[-?+=!~*%&^<>|{(\/]|\[\D|\b(?:delete|in|instanceof|new|typeof|void)\b/,ut=/&(?:amp|lt|gt|quot|#x27);/g,at=/\b__p\+='';/g,ft=/\b(__p\+=)''\+/g,lt=/(__e\(.*?\)|\b__t\))\+'';/g,ct=/\w*$/,ht=/(?:__e|__t=)\(\s*(?![\d\s"']|this\.)/g,pt=RegExp("^"+(tt.valueOf+"").replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),dt=/\$\{((?:(?=\\?)\\?[\s\S])*?)}/g,vt=/<%=([\s\S]+?)%>/g,mt=/($^)/,gt=/[&<>"']/g,yt=/['\n\r\t\u2028\u2029\\]/g,bt="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf"
.split(" "),wt=Math.ceil,Et=et.concat,St=Math.floor,xt=pt.test(xt=Object.getPrototypeOf)&&xt,Tt=tt.hasOwnProperty,Nt=et.push,Ct=tt.propertyIsEnumerable,kt=tt.toString,Lt=pt.test(Lt=g.bind)&&Lt,At=pt.test(At=Array.isArray)&&At,Ot=e.isFinite,Mt=e.isNaN,_t=pt.test(_t=Object.keys)&&_t,Dt=Math.max,Pt=Math.min,Ht=Math.random,Bt="[object Arguments]",jt="[object Array]",Ft="[object Boolean]",It="[object Date]",qt="[object Number]",Rt="[object Object]",Ut="[object RegExp]",zt="[object String]",Wt=!/1/.test
(Function("1")),Xt=!!e.attachEvent,Vt=Lt&&!/\n|true/.test(Lt+Xt),$t=Lt&&!Vt,Jt=_t&&(Xt||Vt),Kt,Qt,Gt=(Gt={0:1,length:1},et.splice.call(Gt,0,1),Gt[0]),Yt=n;(function(){function e(){this.x=1}var t=[];e.prototype={valueOf:1,y:1};for(var n in new e)t.push(n);for(n in arguments)Yt=!n;Kt=!/valueOf/.test(t),Qt="x"!=t[0]})(1);var Zt=!b(arguments),en="xx"!="x"[0]+Object("x")[0];try{var tn=("[object Object]",kt.call(document)==Rt)}catch(nn){}var rn={"[object Function]":i};rn[Bt]=rn[jt]=rn[Ft]=rn[It]=rn[qt]=
rn[Rt]=rn[Ut]=rn[zt]=n;var sn={};sn[jt]=Array,sn[Ft]=Boolean,sn[It]=Date,sn[Rt]=Object,sn[qt]=Number,sn[Ut]=RegExp,sn[zt]=String;var on={"boolean":i,"function":n,object:n,number:i,string:i,"undefined":i},un={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"};s.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:vt,variable:""};if(Xt||Vt||!Wt)o=Function;var an={a:"o,v,g",k:"for(var a=1,b=typeof g=='number'?2:arguments.length;a<b;a++){if((l=arguments[a])){"
,g:"t[i]=l[i]",c:"}}"},fn={a:"d,c,w",k:"c=c&&typeof w=='undefined'?c:e(c,w)",b:"if(c(l[i],i,d)===false)return t",g:"if(c(l[i],i,d)===false)return t"},ln={b:r},cn=h(an);Zt&&(b=function(e){return e?Tt.call(e,"callee"):i});var hn=h(fn,ln,{l:i}),pn=h(fn,ln),dn={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;"},vn=T(dn),mn=h(an,{g:"if(t[i]==null)"+an.g}),gn=At||function(e){return kt.call(e)==jt};C(/x/)&&(C=function(e){return"[object Function]"==kt.call(e)});var yn=xt?function(e){if(!e||"object"!=typeof
e)return i;var t=e.valueOf,n="function"==typeof t&&(n=xt(t))&&xt(n);return n?e==n||xt(e)==n&&!b(e):w(e)}:w,bn=_t?function(e){return"function"==typeof e&&Ct.call(e,"prototype")?E(e):k(e)?_t(e):[]}:E,wn=h(fn);s.assign=cn,s.bindAll=function(e){for(var t=arguments,n=1<t.length?0:(t=x(e),-1),r=t.length;++n<r;){var i=t[n];e[i]=J(e[i],e)}return e},s.chain=function(e){return new s(e)},s.compact=function(e){for(var t=-1,n=e?e.length:0,r=[];++t<n;){var i=e[t];i&&r.push(i)}return r},s.countBy=function(e,t,n
){var r={},t=c(t,n);return wn(e,function(e,n,i){n=t(e,n,i),Tt.call(r,n)?r[n]++:r[n]=1}),r},s.defaults=mn,s.difference=function(e){for(var t=-1,n=e?e.length:0,r=Et.apply(et,arguments),r=u(r,n),i=[];++t<n;){var s=e[t];r(s)||i.push(s)}return i},s.filter=P,s.flatten=z,s.forEach=wn,s.forIn=hn,s.forOwn=pn,s.functions=x,s.groupBy=function(e,t,n){var r={},t=c(t,n);return wn(e,function(e,n,i){n=t(e,n,i),(Tt.call(r,n)?r[n]:r[n]=[]).push(e)}),r},s.initial=function(e,t,n){if(!e)return[];var i=e.length;return g
(e,0,Pt(Dt(0,i-(t==r||n?1:t||0)),i))},s.intersection=function(e){var t=arguments,n=t.length,r={},i=[];return wn(e,function(e){if(0>W(i,e)){for(var s=n;--s;)if(!(r[s]||(r[s]=u(t[s])))(e))return;i.push(e)}}),i},s.invert=T,s.invoke=function(e,t){var n=g(arguments,2),r="function"==typeof t,i=[];return wn(e,function(e){i.push((r?t:e[t]).apply(e,n))}),i},s.keys=bn,s.map=B,s.max=j,s.merge=O,s.min=function(e,t,n){var r=Infinity,i=-1,s=e?e.length:0,o=r;if(t||!gn(e))t=!t&&A(e)?a:c(t,n),wn(e,function(e,n,i)
{n=t(e,n,i),n<r&&(r=n,o=e)});else for(;++i<s;)e[i]<o&&(o=e[i]);return o},s.object=function(e,t){for(var n=-1,r=e?e.length:0,i={};++n<r;){var s=e[n];t?i[s]=t[n]:i[s[0]]=s[1]}return i},s.omit=function(e,t,n){var r="function"==typeof t,i={};if(r)t=c(t,n);else var s=Et.apply(et,arguments);return hn(e,function(e,n,o){if(r?!t(e,n,o):0>W(s,n,1))i[n]=e}),i},s.pairs=function(e){var t=[];return pn(e,function(e,n){t.push([n,e])}),t},s.pick=function(e,t,n){var r={};if("function"!=typeof t)for(var i=0,s=Et.apply
(et,arguments),o=s.length;++i<o;){var u=s[i];u in e&&(r[u]=e[u])}else t=c(t,n),hn(e,function(e,n,i){t(e,n,i)&&(r[n]=e)});return r},s.pluck=F,s.range=function(e,t,n){e=+e||0,n=+n||1,t==r&&(t=e,e=0);for(var i=-1,t=Dt(0,wt((t-e)/n)),s=Array(t);++i<t;)s[i]=e,e+=n;return s},s.reject=function(e,t,n){return t=c(t,n),P(e,function(e,n,r){return!t(e,n,r)})},s.rest=X,s.shuffle=function(e){var t=-1,n=Array(e?e.length:0);return wn(e,function(e){var r=St(Ht()*(++t+1));n[t]=n[r],n[r]=e}),n},s.sortBy=function(e,
t,n){var r=[],t=c(t,n);wn(e,function(e,n,i){r.push({a:t(e,n,i),b:n,c:e})}),e=r.length;for(r.sort(f);e--;)r[e]=r[e].c;return r},s.tap=function(e,t){return t(e),e},s.times=function(e,t,n){for(var e=+e||0,r=-1,i=Array(e);++r<e;)i[r]=t.call(n,r);return i},s.toArray=function(e){return"number"==typeof (e?e.length:0)?en&&A(e)?e.split(""):g(e):M(e)},s.union=function(){return $(Et.apply(et,arguments))},s.uniq=$,s.values=M,s.where=function(e,t){var n=bn(t);return P(e,function(e){for(var r=n.length;r--;){var i=
e[n[r]]===t[n[r]];if(!i)break}return!!i})},s.without=function(e){for(var t=-1,n=e?e.length:0,r=u(arguments,1,20),i=[];++t<n;){var s=e[t];r(s)||i.push(s)}return i},s.zip=function(e){for(var t=-1,n=e?j(F(arguments,"length")):0,r=Array(n);++t<n;)r[t]=F(arguments,t);return r},s.collect=B,s.drop=X,s.each=wn,s.extend=cn,s.methods=x,s.select=P,s.tail=X,s.unique=$,Q(s),s.after=function(e,t){return 1>e?t():function(){if(1>--e)return t.apply(this,arguments)}},s.bind=J,s.bindKey=function(e,t){return l(e,t,g
(arguments,2))},s.clone=S,s.compose=function(){var e=arguments;return function(){for(var t=arguments,n=e.length;n--;)t=[e[n].apply(this,t)];return t[0]}},s.contains=_,s.debounce=function(e,t,n){function i(){a=r,n||(o=e.apply(u,s))}var s,o,u,a;return function(){var r=n&&!a;return s=arguments,u=this,clearTimeout(a),a=setTimeout(i,t),r&&(o=e.apply(u,s)),o}},s.defer=function(e){var n=g(arguments,1);return setTimeout(function(){e.apply(t,n)},1)},s.delay=function(e,n){var r=g(arguments,2);return setTimeout
(function(){e.apply(t,r)},n)},s.escape=function(e){return e==r?"":(e+"").replace(gt,d)},s.every=D,s.find=H,s.has=function(e,t){return e?Tt.call(e,t):i},s.identity=K,s.indexOf=W,s.isArguments=b,s.isArray=gn,s.isBoolean=function(e){return e===n||e===i||kt.call(e)==Ft},s.isDate=function(e){return kt.call(e)==It},s.isElement=function(e){return e?1===e.nodeType:i},s.isEmpty=function(e){var t=n;if(!e)return t;var r=kt.call(e),s=e.length;return r==jt||r==zt||r==Bt||Zt&&b(e)||r==Rt&&"number"==typeof s&&C
(e.splice)?!s:(pn(e,function(){return t=i}),t)},s.isEqual=N,s.isFinite=function(e){return Ot(e)&&!Mt(parseFloat(e))},s.isFunction=C,s.isNaN=function(e){return L(e)&&e!=+e},s.isNull=function(e){return e===r},s.isNumber=L,s.isObject=k,s.isPlainObject=yn,s.isRegExp=function(e){return kt.call(e)==Ut},s.isString=A,s.isUndefined=function(e){return"undefined"==typeof e},s.lastIndexOf=function(e,t,n){var r=e?e.length:0;for("number"==typeof n&&(r=(0>n?Dt(0,r+n):Pt(n,r-1))+1);r--;)if(e[r]===t)return r;return-1
},s.memoize=function(e,t){var n={};return function(){var r=t?t.apply(this,arguments):arguments[0];return Tt.call(n,r)?n[r]:n[r]=e.apply(this,arguments)}},s.mixin=Q,s.noConflict=function(){return e._=st,this},s.once=function(e){var t,s=i;return function(){return s?t:(s=n,t=e.apply(this,arguments),e=r,t)}},s.partial=function(e){return l(e,g(arguments,1))},s.random=function(e,t){return e==r&&t==r&&(t=1),e=+e||0,t==r&&(t=e,e=0),e+St(Ht()*((+t||0)-e+1))},s.reduce=I,s.reduceRight=q,s.result=function(e,
t){var n=e?e[t]:r;return C(n)?e[t]():n},s.size=function(e){var t=e?e.length:0;return"number"==typeof t?t:bn(e).length},s.some=R,s.sortedIndex=V,s.template=function(e,t,n){e||(e=""),n||(n={});var r,i,u=s.templateSettings,a=0,f=n.interpolate||u.interpolate||mt,l="__p+='",c=n.variable||u.variable,h=c;e.replace(RegExp((n.escape||u.escape||mt).source+"|"+f.source+"|"+(f===vt?dt:mt).source+"|"+(n.evaluate||u.evaluate||mt).source+"|$","g"),function(t,n,i,s,o,u){return i||(i=s),l+=e.slice(a,u).replace(yt
,p),n&&(l+="'+__e("+n+")+'"),o&&(l+="';"+o+";__p+='"),i&&(l+="'+((__t=("+i+"))==null?'':__t)+'"),r||(r=o||ot.test(n||i)),a=u+t.length,t}),l+="';\n",h||(c="obj",r?l="with("+c+"){"+l+"}":(n=RegExp("(\\(\\s*)"+c+"\\."+c+"\\b","g"),l=l.replace(ht,"$&"+c+".").replace(n,"$1__d"))),l=(r?l.replace(at,""):l).replace(ft,"$1").replace(lt,"$1;"),l="function("+c+"){"+(h?"":c+"||("+c+"={});")+"var __t,__p='',__e=_.escape"+(r?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":(h?"":",__d="+
c+"."+c+"||"+c)+";")+l+"return __p}";try{i=o("_","return "+l)(s)}catch(d){throw d.source=l,d}return t?i(t):(i.source=l,i)},s.throttle=function(e,t){function n(){a=new Date,u=r,s=e.apply(o,i)}var i,s,o,u,a=0;return function(){var f=new Date,l=t-(f-a);return i=arguments,o=this,0>=l?(clearTimeout(u),u=r,a=f,s=e.apply(o,i)):u||(u=setTimeout(n,l)),s}},s.unescape=function(e){return e==r?"":(e+"").replace(ut,y)},s.uniqueId=function(e){return(e==r?"":e+"")+ ++nt},s.wrap=function(e,t){return function(){var n=
[e];return Nt.apply(n,arguments),t.apply(this,n)}},s.all=D,s.any=R,s.detect=H,s.foldl=I,s.foldr=q,s.include=_,s.inject=I,pn(s,function(e,t){s.prototype[t]||(s.prototype[t]=function(){var t=[this.__wrapped__];return Nt.apply(t,arguments),e.apply(s,t)})}),s.first=U,s.last=function(e,t,n){if(e){var i=e.length;return t==r||n?e[i-1]:g(e,Dt(0,i-t))}},s.take=U,s.head=U,pn(s,function(e,t){s.prototype[t]||(s.prototype[t]=function(t,n){var i=e(this.__wrapped__,t,n);return t==r||n?i:new s(i)})}),s.VERSION="1.0.0-rc.2"
,s.prototype.chain=function(){return this},s.prototype.toString=function(){return""+this.__wrapped__},s.prototype.value=G,s.prototype.valueOf=G,wn("pop push reverse shift sort splice unshift".split(" "),function(e){var t=et[e];s.prototype[e]=function(){var e=this.__wrapped__;return t.apply(e,arguments),Gt&&e.length===0&&delete e[0],this}}),wn(["concat","join","slice"],function(e){var t=et[e];s.prototype[e]=function(){var e=t.apply(this.__wrapped__,arguments);return new s(e)}}),typeof define=="function"&&typeof
define.amd=="object"&&define.amd?(e._=s,define(function(){return s})):Y?"object"==typeof module&&module&&module.exports==Y?(module.exports=s)._=s:Y._=s:e._=s})(this);

3798
lodash.underscore.js Normal file

File diff suppressed because it is too large Load Diff

33
lodash.underscore.min.js vendored Normal file
View File

@@ -0,0 +1,33 @@
/*!
Lo-Dash 1.0.0-rc.2 (Custom Build) lodash.com/license
Build: `lodash underscore -m -o ./lodash.underscore.min.js`
Underscore.js 1.4.3 underscorejs.org/LICENSE
*/
;(function(e,t){function n(e){if(e&&"object"==typeof e&&e.__wrapped__)return e;if(!(this instanceof n))return new n(e);this.__wrapped__=e}function r(e,t){var n=e.b,r=t.b,e=e.a,t=t.a;if(e!==t){if(e>t||"undefined"==typeof e)return 1;if(e<t||"undefined"==typeof t)return-1}return n<r?-1:1}function i(e,t,n){function r(){var i=arguments,s=t;return n.length&&(i=i.length?n.concat(f(i)):n),this instanceof r?(a.prototype=e.prototype,s=new a,a.prototype=null,i=e.apply(s,i),y(i)?i:s):e.apply(s,i)}return r}function s
(e,t){return e?"function"!=typeof e?function(t){return t[e]}:"undefined"!=typeof t?function(n,r,i){return e.call(t,n,r,i)}:e:I}function o(e){return"\\"+St[e]}function u(e){return Nt[e]}function a(){}function f(e,t,n){t||(t=0),"undefined"==typeof n&&(n=e?e.length:0);for(var r=-1,n=n-t||0,i=Array(0>n?0:n);++r<n;)i[r]=e[t+r];return i}function l(e){return Ct[e]}function c(e){if(!e)return e;for(var t=1,n=arguments.length;t<n;t++){var r=arguments[t];if(r)for(var i in r)e[i]=r[i]}return e}function h(e){
var t=[];return Tt(e,function(e,n){t.push(n)}),t}function p(e){if(!e)return e;for(var t=1,n=arguments.length;t<n;t++){var r=arguments[t];if(r)for(var i in r)null==e[i]&&(e[i]=r[i])}return e}function d(e){var t=[];return xt(e,function(e,n){g(e)&&t.push(n)}),t.sort()}function v(e){var t={};return Tt(e,function(e,n){t[e]=n}),t}function m(e,t,n,r){if(e===t)return 0!==e||1/e==1/t;if(null==e||null==t)return e===t;var i=rt.call(e),s=rt.call(t);if(i!=s)return!1;switch(i){case pt:case dt:return+e==+t;case vt
:return e!=+e?t!=+t:0==e?1/e==1/t:e==+t;case gt:case yt:return e==t+""}s=i==ht;if(!s){if(e.__wrapped__||t.__wrapped__)return m(e.__wrapped__||e,t.__wrapped__||t);if(i!=mt)return!1;var i=e.constructor,o=t.constructor;if(i!=o&&(!g(i)||!(i instanceof i&&g(o)&&o instanceof o)))return!1}n||(n=[]),r||(r=[]);for(i=n.length;i--;)if(n[i]==e)return r[i]==t;var u=!0,a=0;n.push(e),r.push(t);if(s){a=e.length;if(u=a==t.length)for(;a--&&(u=m(e[a],t[a],n,r)););return u}return xt(e,function(e,i,s){if(tt.call(s,i)
)return a++,!(u=tt.call(t,i)&&m(e,t[i],n,r))&&X}),u&&xt(t,function(e,t,n){if(tt.call(n,t))return!(u=-1<--a)&&X}),u}function g(e){return"function"==typeof e}function y(e){return e?Et[typeof e]:!1}function b(e){return"number"==typeof e||rt.call(e)==vt}function w(e){return"string"==typeof e||rt.call(e)==yt}function E(e){var t=[];return Tt(e,function(e){t.push(e)}),t}function S(e,t){var n=!1;return"number"==typeof (e?e.length:0)?n=-1<P(e,t):At(e,function(e){return(n=e===t)&&X}),n}function x(e,t,n){var r=!0
,t=s(t,n);if(kt(e))for(var n=-1,i=e.length;++n<i&&(r=!!t(e[n],n,e)););else At(e,function(e,n,i){return!(r=!!t(e,n,i))&&X});return r}function T(e,t,n){var r=[],t=s(t,n);if(kt(e))for(var n=-1,i=e.length;++n<i;){var o=e[n];t(o,n,e)&&r.push(o)}else At(e,function(e,n,i){t(e,n,i)&&r.push(e)});return r}function N(e,t,n){var r,t=s(t,n);return At(e,function(e,n,i){if(t(e,n,i))return r=e,X}),r}function C(e,t,n){var r=-1,i=e?e.length:0,o=Array("number"==typeof i?i:0),t=s(t,n);if(kt(e))for(;++r<i;)o[r]=t(e[r
],r,e);else At(e,function(e,n,i){o[++r]=t(e,n,i)});return o}function k(e,t,n){var r=-Infinity,i=-1,o=e?e.length:0,u=r;if(t||!kt(e))t=s(t,n),At(e,function(e,n,i){n=t(e,n,i),n>r&&(r=n,u=e)});else for(;++i<o;)e[i]>u&&(u=e[i]);return u}function L(e,t){return C(e,t+"")}function A(e,t,n,r){var i=3>arguments.length;return t||(t=I),At(e,function(e,s,o){n=i?(i=!1,e):t.call(r,n,e,s,o)}),n}function O(e,t,n,r){var i=e?e.length:0,s=3>arguments.length;if("number"!=typeof i)var o=Lt(e),i=o.length;return t||(t=I
),At(e,function(u,a,f){a=o?o[--i]:--i,n=s?(s=!1,e[a]):t.call(r,n,e[a],a,f)}),n}function M(e,t,n){var r,t=s(t,n);if(kt(e))for(var n=-1,i=e.length;++n<i&&!(r=t(e[n],n,e)););else At(e,function(e,n,i){return(r=t(e,n,i))&&X});return!!r}function _(e,t,n){if(e){var r=e.length;return null==t||n?e[0]:f(e,0,lt(ft(0,t),r))}}function D(e,t){for(var n=-1,r=e?e.length:0,i=[];++n<r;){var s=e[n];kt(s)?nt.apply(i,t?s:D(s)):i.push(s)}return i}function P(e,t,n){var r=-1,i=e?e.length:0;if("number"==typeof n)r=(0>n?ft
(0,i+n):n||0)-1;else if(n)return r=B(e,t),e[r]===t?r:-1;for(;++r<i;)if(e[r]===t)return r;return-1}function H(e,t,n){return f(e,null==t||n?1:ft(0,t))}function B(e,t,n,r){for(var i=0,o=e?e.length:i,n=n?s(n,r):I,t=n(t);i<o;)r=i+o>>>1,n(e[r])<t?i=r+1:o=r;return i}function j(e,t,n,r){var i=-1,o=e?e.length:0,u=[],a=u;"function"==typeof t&&(r=n,n=t,t=!1),n&&(a=[],n=s(n,r));for(;++i<o;){var r=e[i],f=n?n(r,i,e):r;if(t?!i||a[a.length-1]!==f:0>P(a,f))n&&a.push(f),u.push(r)}return u}function F(e,t){return bt||
it&&2<arguments.length?it.call.apply(it,arguments):i(e,t,f(arguments,2))}function I(e){return e}function q(e){At(d(e),function(t){var r=n[t]=e[t];n.prototype[t]=function(){var e=[this.__wrapped__];return nt.apply(e,arguments),e=r.apply(n,e),this.__chain__&&(e=new n(e),e.__chain__=!0),e}})}var R="object"==typeof exports&&exports,U="object"==typeof global&&global;U.global===U&&(e=U);var z=[],U=new function(){},W=0,X=U,V=e._,$=/&(?:amp|lt|gt|quot|#x27);/g,J=RegExp("^"+(U.valueOf+"").replace(/[.*+?^=!:${}()|[\]\/\\]/g
,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),K=/($^)/,Q=/[&<>"']/g,G=/['\n\r\t\u2028\u2029\\]/g,Y=Math.ceil,Z=z.concat,et=Math.floor,tt=U.hasOwnProperty,nt=z.push,rt=U.toString,it=J.test(it=f.bind)&&it,st=J.test(st=Array.isArray)&&st,ot=e.isFinite,ut=e.isNaN,at=J.test(at=Object.keys)&&at,ft=Math.max,lt=Math.min,ct=Math.random,ht="[object Array]",pt="[object Boolean]",dt="[object Date]",vt="[object Number]",mt="[object Object]",gt="[object RegExp]",yt="[object String]",U=!!e.attachEvent,U=it&&!/\n|true/
.test(it+U),bt=it&&!U,wt=(wt={0:1,length:1},z.splice.call(wt,0,1),wt[0]),Et={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,"undefined":!1},St={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"};n.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:""},n.isArguments=function(e){return"[object Arguments]"==rt.call(e)},n.isArguments(arguments)||(n.isArguments=function(e){return e?tt.call(e,"callee"):!1}
);var xt=function(e,t){var n;if(!e)return e;t||(t=I);for(n in e)if(t(e[n],n,e)===X)break;return e},Tt=function(e,t){var n;if(!e)return e;t||(t=I);for(n in e)if(tt.call(e,n)&&t(e[n],n,e)===X)break;return e},Nt={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;"},Ct=v(Nt),kt=st||function(e){return rt.call(e)==ht};g(/x/)&&(g=function(e){return"[object Function]"==rt.call(e)});var Lt=at?function(e){return y(e)?at(e):[]}:h,At=function(e,t,n){if(!e)return e;var t=t&&"undefined"==typeof n?t:s(t
,n),r=e.length,n=-1;if("number"==typeof r){for(;++n<r;)if(t(e[n],n,e)===X)return e}else for(n in e)if(tt.call(e,n)&&t(e[n],n,e)===X)return e};n.bindAll=function(e){for(var t=arguments,n=1<t.length?0:(t=d(e),-1),r=t.length;++n<r;){var i=t[n];e[i]=F(e[i],e)}return e},n.chain=function(e){return e=new n(e),e.__chain__=!0,e},n.compact=function(e){for(var t=-1,n=e?e.length:0,r=[];++t<n;){var i=e[t];i&&r.push(i)}return r},n.countBy=function(e,t,n){var r={},t=s(t,n);return At(e,function(e,n,i){n=t(e,n,i)
,tt.call(r,n)?r[n]++:r[n]=1}),r},n.defaults=p,n.difference=function(e){for(var t=-1,n=e.length,r=Z.apply(z,arguments),i=[];++t<n;){var s=e[t];0>P(r,s,n)&&i.push(s)}return i},n.filter=T,n.flatten=D,n.forEach=At,n.functions=d,n.groupBy=function(e,t,n){var r={},t=s(t,n);return At(e,function(e,n,i){n=t(e,n,i),(tt.call(r,n)?r[n]:r[n]=[]).push(e)}),r},n.initial=function(e,t,n){if(!e)return[];var r=e.length;return f(e,0,lt(ft(0,r-(null==t||n?1:t||0)),r))},n.intersection=function(e){var t=arguments,n=t.length
,r=[];return At(e,function(e){if(0>P(r,e)){for(var i=n;--i;)if(0>P(t[i],e))return;r.push(e)}}),r},n.invert=v,n.invoke=function(e,t){var n=f(arguments,2),r="function"==typeof t,i=[];return At(e,function(e){i.push((r?t:e[t]).apply(e,n))}),i},n.keys=Lt,n.map=C,n.max=k,n.min=function(e,t,n){var r=Infinity,i=-1,o=e?e.length:0,u=r;if(t||!kt(e))t=s(t,n),At(e,function(e,n,i){n=t(e,n,i),n<r&&(r=n,u=e)});else for(;++i<o;)e[i]<u&&(u=e[i]);return u},n.object=function(e,t){for(var n=-1,r=e?e.length:0,i={};++n<
r;){var s=e[n];t?i[s]=t[n]:i[s[0]]=s[1]}return i},n.omit=function(e){var t=Z.apply(z,arguments),n={};return xt(e,function(e,r){0>P(t,r,1)&&(n[r]=e)}),n},n.pairs=function(e){var t=[];return Tt(e,function(e,n){t.push([n,e])}),t},n.pick=function(e){for(var t=0,n=Z.apply(z,arguments),r=n.length,i={};++t<r;){var s=n[t];s in e&&(i[s]=e[s])}return i},n.pluck=L,n.range=function(e,t,n){e=+e||0,n=+n||1,null==t&&(t=e,e=0);for(var r=-1,t=ft(0,Y((t-e)/n)),i=Array(t);++r<t;)i[r]=e,e+=n;return i},n.reject=function(
e,t,n){return t=s(t,n),T(e,function(e,n,r){return!t(e,n,r)})},n.rest=H,n.shuffle=function(e){var t=-1,n=Array(e?e.length:0);return At(e,function(e){var r=et(ct()*(++t+1));n[t]=n[r],n[r]=e}),n},n.sortBy=function(e,t,n){var i=[],t=s(t,n);At(e,function(e,n,r){i.push({a:t(e,n,r),b:n,c:e})}),e=i.length;for(i.sort(r);e--;)i[e]=i[e].c;return i},n.tap=function(e,t){return t(e),e},n.times=function(e,t,n){for(var e=+e||0,r=-1,i=Array(e);++r<e;)i[r]=t.call(n,r);return i},n.toArray=function(e){return"number"==typeof
(e?e.length:0)?f(e):E(e)},n.union=function(){return j(Z.apply(z,arguments))},n.uniq=j,n.values=E,n.where=function(e,t){var n=Lt(t);return T(e,function(e){for(var r=n.length;r--;){var i=e[n[r]]===t[n[r]];if(!i)break}return!!i})},n.without=function(e){for(var t=-1,n=e.length,r=[];++t<n;){var i=e[t];0>P(arguments,i,1)&&r.push(i)}return r},n.zip=function(e){for(var t=-1,n=e?k(L(arguments,"length")):0,r=Array(n);++t<n;)r[t]=L(arguments,t);return r},n.collect=C,n.drop=H,n.each=At,n.extend=c,n.methods=d
,n.select=T,n.tail=H,n.unique=j,n.after=function(e,t){return 1>e?t():function(){if(1>--e)return t.apply(this,arguments)}},n.bind=F,n.clone=function(e){return e&&Et[typeof e]?kt(e)?f(e):c({},e):e},n.compose=function(){var e=arguments;return function(){for(var t=arguments,n=e.length;n--;)t=[e[n].apply(this,t)];return t[0]}},n.contains=S,n.debounce=function(e,t,n){function r(){u=null,n||(s=e.apply(o,i))}var i,s,o,u;return function(){var a=n&&!u;return i=arguments,o=this,clearTimeout(u),u=setTimeout(
r,t),a&&(s=e.apply(o,i)),s}},n.defer=function(e){var n=f(arguments,1);return setTimeout(function(){e.apply(t,n)},1)},n.delay=function(e,n){var r=f(arguments,2);return setTimeout(function(){e.apply(t,r)},n)},n.escape=function(e){return null==e?"":(e+"").replace(Q,u)},n.every=x,n.find=N,n.has=function(e,t){return e?tt.call(e,t):!1},n.identity=I,n.indexOf=P,n.isArray=kt,n.isBoolean=function(e){return!0===e||!1===e||rt.call(e)==pt},n.isDate=function(e){return rt.call(e)==dt},n.isElement=function(e){return e?1===
e.nodeType:!1},n.isEmpty=function(e){if(!e)return!0;if(kt(e)||w(e))return!e.length;for(var t in e)if(tt.call(e,t))return!1;return!0},n.isEqual=m,n.isFinite=function(e){return ot(e)&&!ut(parseFloat(e))},n.isFunction=g,n.isNaN=function(e){return b(e)&&e!=+e},n.isNull=function(e){return null===e},n.isNumber=b,n.isObject=y,n.isRegExp=function(e){return rt.call(e)==gt},n.isString=w,n.isUndefined=function(e){return"undefined"==typeof e},n.lastIndexOf=function(e,t,n){var r=e?e.length:0;for("number"==typeof
n&&(r=(0>n?ft(0,r+n):lt(n,r-1))+1);r--;)if(e[r]===t)return r;return-1},n.memoize=function(e,t){var n={};return function(){var r=t?t.apply(this,arguments):arguments[0];return tt.call(n,r)?n[r]:n[r]=e.apply(this,arguments)}},n.mixin=q,n.noConflict=function(){return e._=V,this},n.once=function(e){var t,n=!1;return function(){return n?t:(n=!0,t=e.apply(this,arguments),e=null,t)}},n.random=function(e,t){return null==e&&null==t&&(t=1),e=+e||0,null==t&&(t=e,e=0),e+et(ct()*((+t||0)-e+1))},n.reduce=A,n.reduceRight=
O,n.result=function(e,t){var n=e?e[t]:null;return g(n)?e[t]():n},n.size=function(e){var t=e?e.length:0;return"number"==typeof t?t:Lt(e).length},n.some=M,n.sortedIndex=B,n.template=function(e,t,r){e||(e="");var r=p({},r,n.templateSettings),i=0,s="__p+='",u=r.variable;e.replace(RegExp((r.escape||K).source+"|"+(r.interpolate||K).source+"|"+(r.evaluate||K).source+"|$","g"),function(t,n,r,u,a){s+=e.slice(i,a).replace(G,o),s+=n?"'+_['escape']("+n+")+'":u?"';"+u+";__p+='":r?"'+((__t=("+r+"))==null?'':__t)+'"
:"",i=a+t.length}),s+="';\n",u||(u="obj",s="with("+u+"||{}){"+s+"}"),s="function("+u+"){var __t,__p='',__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}"+s+"return __p}";try{var a=Function("_","return "+s)(n)}catch(f){throw f.source=s,f}return t?a(t):(a.source=s,a)},n.throttle=function(e,t){function n(){u=new Date,o=null,i=e.apply(s,r)}var r,i,s,o,u=0;return function(){var a=new Date,f=t-(a-u);return r=arguments,s=this,0>=f?(clearTimeout(o),o=null,u=a,i=e.apply(s,r)):o||(o=setTimeout
(n,f)),i}},n.unescape=function(e){return null==e?"":(e+"").replace($,l)},n.uniqueId=function(e){var t=++W+"";return e?e+t:t},n.wrap=function(e,t){return function(){var n=[e];return nt.apply(n,arguments),t.apply(this,n)}},n.all=x,n.any=M,n.detect=N,n.foldl=A,n.foldr=O,n.include=S,n.inject=A,n.first=_,n.last=function(e,t,n){if(e){var r=e.length;return null==t||n?e[r-1]:f(e,ft(0,r-t))}},n.take=_,n.head=_,n.VERSION="1.0.0-rc.2",q(n),n.prototype.chain=function(){return this.__chain__=!0,this},n.prototype
.value=function(){return this.__wrapped__},At("pop push reverse shift sort splice unshift".split(" "),function(e){var t=z[e];n.prototype[e]=function(){var e=this.__wrapped__;return t.apply(e,arguments),wt&&e.length===0&&delete e[0],this}}),At(["concat","join","slice"],function(e){var t=z[e];n.prototype[e]=function(){var e=t.apply(this.__wrapped__,arguments);return this.__chain__&&(e=new n(e),e.__chain__=!0),e}}),R?"object"==typeof module&&module&&module.exports==R?(module.exports=n)._=n:R._=n:e._=
n})(this);

View File

@@ -1,9 +1,9 @@
{
"name": "lodash",
"version": "0.2.2",
"description": "A drop-in replacement for Underscore.js that delivers performance improvements, bug fixes, and additional features.",
"version": "1.0.0-rc.2",
"description": "A utility library, usable as a drop-in replacement for Underscore, delivering performance, bug fixes, and additional features.",
"homepage": "http://lodash.com",
"main": "lodash",
"main": "./lodash",
"keywords": [
"browser",
"client",
@@ -21,7 +21,7 @@
],
"author": {
"name": "John-David Dalton",
"email": "john@fusejs.com",
"email": "john.david.dalton@gmail.com",
"web": "http://allyoucanleet.com/"
},
"bugs": {
@@ -31,12 +31,23 @@
"type": "git",
"url": "https://github.com/bestiejs/lodash.git"
},
"bin": {
"lodash": "./build.js"
},
"directories": {
"doc": "./doc",
"test": "./test"
},
"engines": [
"node",
"rhino"
],
"directories": {
"doc": "./doc",
"test": "./test"
"jam": {
"main": "./lodash.js"
},
"scripts": {
"build": "node build",
"test": "node test/test && node test/test-build",
"install": "node build/post-install"
}
}
}

View File

@@ -13,34 +13,69 @@
position: absolute;
left: -9999em;
}
#FirebugUI {
top: 2em;
}
#perf-toolbar {
background-color: #EEE;
color: #5E740B;
font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
font-size: small;
padding: 0.5em 0 0.5em 2em;
overflow: hidden;
}
</style>
</head>
<body>
<script src="../lodash.js"></script>
<div id="perf-toolbar"></div>
<script src="../vendor/platform.js/platform.js"></script>
<script src="../vendor/benchmark.js/benchmark.js"></script>
<script src="../vendor/firebug-lite/src/firebug-lite-debug.js"></script>
<script src="perf-ui.js"></script>
<script>
document.write('<script src="../' + ui.buildPath + '"><\/script>');
</script>
<script>
var lodash = _.noConflict();
</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>
document.write('<script src="../' + ui.otherPath + '"><\/script>');
</script>
<script src="perf.js"></script>
<script>
(function() {
if (!/[?&]nojava=true(?:&|$)/.test(location.search)) {
// using innerHTML avoids an alert in some versions of IE6
var div = document.createElement('div');
div.innerHTML = '<applet code=nano archive="../vendor/benchmark.js/nano.jar">';
document.body.insertBefore(div.lastChild, document.body.firstChild);
var measured,
perfNow,
begin = new Date;
function init() {
var fbUI = document.getElementById('FirebugUI'),
fbDoc = fbUI && (fbDoc = fbUI.contentWindow || fbUI.contentDocument).document || fbDoc,
fbCommandLine = fbDoc && fbDoc.getElementById('fbCommandLine');
if (!fbCommandLine) {
return setTimeout(init, 15);
}
fbUI.style.height = (
Math.max(document.documentElement.clientHeight, document.body.clientHeight) -
document.getElementById('perf-toolbar').clientHeight
) + 'px';
fbDoc.body.style.height = fbDoc.documentElement.style.height = '100%';
setTimeout(run, 15);
}
// is the applet permitted?
if (!/[?&]nojava=true(?:&|$)/.test(location.search)) {
// is the applet really needed?
while (!(measured = new Date - begin)) { }
if (measured != 1 && !((perfNow = window.performance) && typeof (perfNow.now || perfNow.webkitNow) == 'function')) {
// load applet
document.write('<applet code="nano" archive="../vendor/benchmark.js/nano.jar"></applet>');
}
}
window.onload = init;
}());
window.onload = function() {
var sibling = document.getElementsByTagName('script')[0],
script = document.createElement('script');
document.getElementById('FirebugUI').style.height = '100%';
script.src = 'perf.js';
sibling.parentNode.insertBefore(script, sibling);
};
</script>
</body>
</html>
</html>

130
perf/perf-ui.js Normal file
View File

@@ -0,0 +1,130 @@
;(function(window) {
'use strict';
/** The Lo-Dash build to load */
var build = (/build=([^&]+)/.exec(location.search) || [])[1];
/** The other library to load */
var other = (/other=([^&]+)/.exec(location.search) || [])[1];
/** The `ui` object */
var ui = {};
/*--------------------------------------------------------------------------*/
/**
* Registers an event listener on an element.
*
* @private
* @param {Element} element The element.
* @param {String} eventName The name of the event.
* @param {Function} handler The event handler.
* @returns {Element} The element.
*/
function addListener(element, eventName, handler) {
if (typeof element.addEventListener != 'undefined') {
element.addEventListener(eventName, handler, false);
} else if (typeof element.attachEvent != 'undefined') {
element.attachEvent('on' + eventName, handler);
}
}
/*--------------------------------------------------------------------------*/
// expose Lo-Dash build file path
ui.buildPath = (function() {
switch (build) {
case 'lodash-dev': return 'lodash.js';
case 'lodash-underscore': return 'lodash.underscore.min.js';
case 'lodash-custom': return 'lodash.custom.min.js';
}
return 'lodash.min.js';
}());
// expose other library file path
ui.otherPath = (function() {
switch (other) {
case 'lodash-dev': return 'lodash.js';
case 'lodash-prod': return 'lodash.min.js';
case 'lodash-underscore': return 'lodash.underscore.min.js';
case 'lodash-custom': return 'lodash.custom.min.js';
case 'underscore-dev': return 'vendor/underscore/underscore.js';
}
return 'vendor/underscore/underscore-min.js';
}());
// initialize controls
addListener(window, 'load', function() {
function eventHandler(event) {
var search = location.search.replace(/^\?|&?(?:build|other)=[^&]*&?/g, '');
if (event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubble = true;
}
location.href =
location.href.split('?')[0] + '?' +
(search ? search + '&' : '') +
'build=' + buildList[buildList.selectedIndex].value + '&' +
'other=' + otherList[otherList.selectedIndex].value;
}
var span1 = document.createElement('span');
span1.style.cssText = 'float:right';
span1.innerHTML =
'<label for="perf-build">Build: </label>' +
'<select id="perf-build">' +
'<option value="lodash-dev">Lo-Dash</option>' +
'<option value="lodash-prod">Lo-Dash (minified)</option>' +
'<option value="lodash-underscore">Lo-Dash (underscore)</option>' +
'<option value="lodash-custom">Lo-Dash (custom)</option>' +
'</select>';
var span2 = document.createElement('span');
span2.style.cssText = 'float:right';
span2.innerHTML =
'<label for="perf-other">Other Library: </label>' +
'<select id="perf-other">' +
'<option value="underscore-dev">Underscore</option>' +
'<option value="underscore-prod">Underscore (minified)</option>' +
'<option value="lodash-dev">Lo-Dash</option>' +
'<option value="lodash-prod">Lo-Dash (minified)</option>' +
'<option value="lodash-underscore">Lo-Dash (underscore)</option>' +
'<option value="lodash-custom">Lo-Dash (custom)</option>' +
'</select>';
var buildList = span1.lastChild,
otherList = span2.lastChild,
toolbar = document.getElementById('perf-toolbar');
toolbar.appendChild(span2);
toolbar.appendChild(span1);
buildList.selectedIndex = (function() {
switch (build) {
case 'lodash-dev': return 0;
case 'lodash-underscore': return 2;
case 'lodash-custom': return 3;
}
return 1;
}());
otherList.selectedIndex = (function() {
switch (other) {
case 'underscore-dev': return 0;
case 'lodash-dev': return 2;
case 'lodash-prod': return 3;
case 'lodash-underscore': return 4;
case 'lodash-custom': return 5;
}
return 1;
}());
addListener(buildList, 'change', eventHandler);
addListener(otherList, 'change', eventHandler);
});
// expose `ui`
window.ui = ui;
}(this));

File diff suppressed because it is too large Load Diff

View File

@@ -3,14 +3,11 @@
<head>
<meta charset="utf-8">
<title>Backbone Test Suite</title>
<link rel="stylesheet" href="../vendor/backbone/test/vendor/qunit.css">
<link rel="stylesheet" href="../vendor/qunit/qunit/qunit.css">
<style>
body > #qunit-header {
display: none;
}
#jslitmus {
display: none;
}
</style>
</head>
<body>
@@ -21,12 +18,22 @@
<h1>Test</h1>
</div>
</div>
<script src="../vendor/backbone/test/vendor/json2.js"></script>
<script src="../vendor/backbone/test/vendor/jquery-1.7.1.js"></script>
<script src="../vendor/backbone/test/vendor/qunit.js"></script>
<script src="../vendor/backbone/test/vendor/jslitmus.js"></script>
<script src="../lodash.js"></script>
<script src="../vendor/json3/lib/json3.js"></script>
<script src="../vendor/jquery/jquery.js"></script>
<script src="../vendor/platform.js/platform.js"></script>
<script>
// avoid syntax errors for `QUnit.throws` in older Firefoxes
document.write(platform.name == 'Firefox' && /^1\b/.test(platform.version)
? '<script src="../vendor/qunit/qunit/qunit-1.8.0.js"><\/script>'
: '<script src="../vendor/qunit/qunit/qunit.js"><\/script>'
);
</script>
<script src="test-ui.js"></script>
<script>
document.write('<script src="../' + ui.buildPath + '"><\/script>');
</script>
<script src="../vendor/backbone/backbone.js"></script>
<script src="../vendor/backbone/test/environment.js"></script>
<script src="../vendor/backbone/test/noconflict.js"></script>
<script src="../vendor/backbone/test/events.js"></script>
<script src="../vendor/backbone/test/model.js"></script>
@@ -34,6 +41,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>
</html>

View File

@@ -7,47 +7,90 @@
</head>
<body>
<div id="qunit"></div>
<script src="../vendor/qunit/qunit/qunit.js"></script>
<script src="../vendor/platform.js/platform.js"></script>
<script>
var _2,
_3 = Object.keys;
// avoid syntax errors for `QUnit.throws` in older Firefoxes
document.write(platform.name == 'Firefox' && /^1\b/.test(platform.version)
? '<script src="../vendor/qunit/qunit/qunit-1.8.0.js"><\/script>'
: '<script src="../vendor/qunit/qunit/qunit.js"><\/script>'
);
</script>
<script src="test-ui.js"></script>
<script>
// set a bad shim
Object._keys = Object.keys;
Object.keys = function() { return []; };
</script>
<script src="../lodash.js"></script>
<script>
var lodashBadKeys = _,
_ = 1;
Object.keys = _3;
_3 = void 0;
// load Lo-Dash and expose it to the bad `Object.keys` shim
document.write('<script src="../' + ui.buildPath + '"><\/script>');
</script>
<script src="../lodash.js"></script>
<script src="../vendor/requirejs/require.js"></script>
<script>
if (/[?&]norequire=true(?:&|$)/.test(location.search)) {
require = define = null;
document.write('<script src="test.js"><\/script>');
}
else {
require({
// store Lo-Dash to test for bad shim detection
var lodashBadShim = _;
// restore nativeKeys
Object.keys = Object._keys;
delete Object._keys;
// load Lo-Dash again to overwrite the existing `_` value
document.write('<script src="../' + ui.buildPath + '"><\/script>');
// load test.js if not using require.js
document.write(QUnit.urlParams.norequire
? '<script src="test.js"><\/script>'
: '<script src="../vendor/requirejs/require.js"><\/script>'
);
</script>
<script>
// load Lo-Dash as a module
var lodashModule,
shimmedModule,
underscoreModule;
window.require && require(
(function() {
var modulePath = ui.buildPath.replace(/\.js$/, '');
return {
'baseUrl': '../vendor/requirejs/',
'urlArgs': 't=' + (+new Date),
'paths': {
'lodash': '../../lodash',
'underscore': './../../lodash'
'lodash': '../../' + modulePath,
'shimmed': './../../' + modulePath,
'underscore': '../underscore/../../' + modulePath
},
'shim': {
'shimmed': {
'exports': '_'
}
}
},
['lodash', 'underscore'], function(lodash, lodashAsUnderscore) {
_2 = lodash.noConflict();
_2.moduleName = 'lodash';
};
}()),
['lodash', 'shimmed', 'underscore'], function(lodash, shimmed, underscore) {
if (lodash && lodash.noConflict) {
lodashModule = lodash.noConflict();
lodashModule.moduleName = 'lodash';
}
if (shimmed.noConflict) {
shimmedModule = shimmed.noConflict();
shimmedModule.moduleName = 'shimmed';
}
if (underscore && underscore.noConflict) {
underscoreModule = underscore.noConflict();
underscoreModule.moduleName = 'underscore';
}
require(['test.js']);
});
_3 = lodashAsUnderscore.noConflict();
_3.moduleName = 'underscore';
require(['test.js']);
});
}
// set a more readable browser name
window.onload = function() {
var timeoutId = setInterval(function() {
var ua = document.getElementById('qunit-userAgent');
if (ua) {
ua.innerHTML = platform;
clearInterval(timeoutId);
}
}, 15);
};
</script>
</body>
</html>
</html>

View File

@@ -1,9 +1,14 @@
cd "$(dirname "$0")"
for cmd in rhino ringo narwhal node; do
echo ""
echo "Testing in $cmd..."
$cmd test.js
echo ""
echo "Testing in $cmd..."
$cmd test.js
done
echo ""
echo "Testing build..."
node test-build.js
echo ""
echo "Testing in a browser..."
open index.html
open index.html

3
test/template/a.jst Normal file
View File

@@ -0,0 +1,3 @@
<ul>
<% _.forEach(people, function(name) { %><li><%= name %></li><% }); %>
</ul>

1
test/template/b.jst Normal file
View File

@@ -0,0 +1 @@
<% print("Hello " + epithet); %>.

1
test/template/c.jst Normal file
View File

@@ -0,0 +1 @@
Hello ${ name }!

1
test/template/d.tpl Normal file
View File

@@ -0,0 +1 @@
Hello {{ name }}!

1094
test/test-build.js Normal file

File diff suppressed because it is too large Load Diff

102
test/test-ui.js Normal file
View File

@@ -0,0 +1,102 @@
;(function(window) {
'use strict';
/** `QUnit.addEvent` shortcut */
var addEvent = QUnit.addEvent;
/** The Lo-Dash build to load */
var build = (/build=([^&]+)/.exec(location.search) || [])[1];
/** A flag to determine if RequireJS should be loaded */
var norequire = /[?&]norequire=true(?:&|$)/.test(location.search);
/** The `ui` object */
var ui = {};
/*--------------------------------------------------------------------------*/
// expose Lo-Dash build file path
ui.buildPath = (function() {
switch (build) {
case 'lodash-prod': return 'lodash.min.js';
case 'lodash-underscore': return 'lodash.underscore.min.js';
case 'lodash-custom': return 'lodash.custom.min.js';
case 'lodash-custom-debug': return 'lodash.custom.js';
}
return 'lodash.js';
}());
// assign `QUnit.urlParams` properties
QUnit.extend(QUnit.urlParams, {
'build': build,
'norequire': norequire
});
// initialize controls
addEvent(window, 'load', function() {
function eventHandler(event) {
var search = location.search.replace(/^\?|&?(?:build|norequire)=[^&]*&?/g, '');
if (event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubble = true;
}
location.href =
location.href.split('?')[0] + '?' +
(search ? search + '&' : '') +
'build=' + buildList[buildList.selectedIndex].value +
(checkbox.checked ? '&norequire=true' : '');
}
function init() {
var toolbar = document.getElementById('qunit-testrunner-toolbar');
if (toolbar) {
toolbar.appendChild(span1);
toolbar.appendChild(span2);
buildList.selectedIndex = (function() {
switch (build) {
case 'lodash-prod': return 1;
case 'lodash-underscore': return 2;
case 'lodash-custom': return 3;
case 'lodash-custom-debug': return 4;
}
return 0;
}());
checkbox.checked = norequire;
addEvent(checkbox, 'click', eventHandler);
addEvent(buildList, 'change', eventHandler);
}
else {
setTimeout(init, 15);
}
}
var span1 = document.createElement('span');
span1.innerHTML =
'<input id="qunit-norequire" type="checkbox">' +
'<label for="qunit-norequire">No RequireJS</label>';
var span2 = document.createElement('span');
span2.style.cssText = 'float:right';
span2.innerHTML =
'<label for="qunit-build">Build: </label>' +
'<select id="qunit-build">' +
'<option value="lodash-dev">Developement</option>' +
'<option value="lodash-prod">Production</option>' +
'<option value="lodash-underscore">Underscore</option>' +
'<option value="lodash-custom">Custom</option>' +
'<option value="lodash-custom-debug">Custom (debug)</option>' +
'</select>';
var checkbox = span1.firstChild,
buildList = span2.lastChild;
init();
});
// expose `ui`
window.ui = ui;
}(this));

File diff suppressed because it is too large Load Diff

View File

@@ -3,9 +3,9 @@
<head>
<meta charset="utf-8">
<title>Underscore Test Suite</title>
<link rel="stylesheet" href="../vendor/underscore/test/vendor/qunit.css">
<link rel="stylesheet" href="../vendor/qunit/qunit/qunit.css">
<style>
#jslitmus, iframe {
iframe, img {
display: none;
}
</style>
@@ -17,12 +17,21 @@
<div id="id1"></div>
<div id="id2"></div>
</div>
<img id="chart_image" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==">
</div>
<script src="../vendor/backbone/test/vendor/json2.js"></script>
<script src="../vendor/underscore/test/vendor/jquery.js"></script>
<script src="../vendor/underscore/test/vendor/qunit.js"></script>
<script src="../vendor/underscore/test/vendor/jslitmus.js"></script>
<script src="../lodash.js"></script>
<script src="../vendor/jquery/jquery.js"></script>
<script src="../vendor/platform.js/platform.js"></script>
<script>
// avoid syntax errors for `QUnit.throws` in older Firefoxes
document.write(platform.name == 'Firefox' && /^1\b/.test(platform.version)
? '<script src="../vendor/qunit/qunit/qunit-1.8.0.js"><\/script>'
: '<script src="../vendor/qunit/qunit/qunit.js"><\/script>'
);
</script>
<script src="test-ui.js"></script>
<script>
document.write('<script src="../' + ui.buildPath + '"><\/script>');
</script>
<script src="../vendor/underscore/test/collections.js"></script>
<script src="../vendor/underscore/test/arrays.js"></script>
<script src="../vendor/underscore/test/functions.js"></script>
@@ -36,4 +45,4 @@
<li><%= data %></li>
</script>
</body>
</html>
</html>

1
vendor/backbone vendored

Submodule vendor/backbone deleted from 5509e13842

22
vendor/backbone/LICENSE vendored Normal file
View File

@@ -0,0 +1,22 @@
Copyright (c) 2010-2012 Jeremy Ashkenas, DocumentCloud
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

26
vendor/backbone/README.md vendored Normal file
View File

@@ -0,0 +1,26 @@
____ __ __
/\ _`\ /\ \ /\ \ __
\ \ \ \ \ __ ___\ \ \/'\\ \ \____ ___ ___ __ /\_\ ____
\ \ _ <' /'__`\ /'___\ \ , < \ \ '__`\ / __`\ /' _ `\ /'__`\ \/\ \ /',__\
\ \ \ \ \/\ \ \.\_/\ \__/\ \ \\`\\ \ \ \ \/\ \ \ \/\ \/\ \/\ __/ __ \ \ \/\__, `\
\ \____/\ \__/.\_\ \____\\ \_\ \_\ \_,__/\ \____/\ \_\ \_\ \____\/\_\_\ \ \/\____/
\/___/ \/__/\/_/\/____/ \/_/\/_/\/___/ \/___/ \/_/\/_/\/____/\/_/\ \_\ \/___/
\ \____/
\/___/
(_'_______________________________________________________________________________'_)
(_.———————————————————————————————————————————————————————————————————————————————._)
Backbone supplies structure to JavaScript-heavy applications by providing models key-value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing application over a RESTful JSON interface.
For Docs, License, Tests, pre-packed downloads, and everything else, really, see:
http://backbonejs.org
To suggest a feature, report a bug, or general discussion:
http://github.com/documentcloud/backbone/issues/
All contributors are listed here:
http://github.com/documentcloud/backbone/contributors
Special thanks to Robert Kieffer for the original philosophy behind Backbone.
http://github.com/broofa

1500
vendor/backbone/backbone.js vendored Normal file

File diff suppressed because it is too large Load Diff

729
vendor/backbone/test/collection.js vendored Normal file
View File

@@ -0,0 +1,729 @@
$(document).ready(function() {
var a, b, c, d, e, col, otherCol;
module("Backbone.Collection", _.extend(new Environment, {
setup: function() {
Environment.prototype.setup.apply(this, arguments);
a = new Backbone.Model({id: 3, label: 'a'});
b = new Backbone.Model({id: 2, label: 'b'});
c = new Backbone.Model({id: 1, label: 'c'});
d = new Backbone.Model({id: 0, label: 'd'});
e = null;
col = new Backbone.Collection([a,b,c,d]);
otherCol = new Backbone.Collection();
}
}));
test("new and sort", 7, function() {
equal(col.first(), a, "a should be first");
equal(col.last(), d, "d should be last");
col.comparator = function(a, b) {
return a.id > b.id ? -1 : 1;
};
col.sort();
equal(col.first(), a, "a should be first");
equal(col.last(), d, "d should be last");
col.comparator = function(model) { return model.id; };
col.sort();
equal(col.first(), d, "d should be first");
equal(col.last(), a, "a should be last");
equal(col.length, 4);
});
test("String comparator.", 1, function() {
var collection = new Backbone.Collection([
{id: 3},
{id: 1},
{id: 2}
], {comparator: 'id'});
deepEqual(collection.pluck('id'), [1, 2, 3]);
});
test("new and parse", 3, function() {
var Collection = Backbone.Collection.extend({
parse : function(data) {
return _.filter(data, function(datum) {
return datum.a % 2 === 0;
});
}
});
var models = [{a: 1}, {a: 2}, {a: 3}, {a: 4}];
var collection = new Collection(models, {parse: true});
strictEqual(collection.length, 2);
strictEqual(collection.first().get('a'), 2);
strictEqual(collection.last().get('a'), 4);
});
test("get, getByCid", 3, function() {
equal(col.get(0), d);
equal(col.get(2), b);
equal(col.getByCid(col.first().cid), col.first());
});
test("get with non-default ids", 2, function() {
var col = new Backbone.Collection();
var MongoModel = Backbone.Model.extend({
idAttribute: '_id'
});
var model = new MongoModel({_id: 100});
col.push(model);
equal(col.get(100), model);
model.set({_id: 101});
equal(col.get(101), model);
});
test("update index when id changes", 3, function() {
var col = new Backbone.Collection();
col.add([
{id : 0, name : 'one'},
{id : 1, name : 'two'}
]);
var one = col.get(0);
equal(one.get('name'), 'one');
one.set({id : 101});
equal(col.get(0), null);
equal(col.get(101).get('name'), 'one');
});
test("at", 1, function() {
equal(col.at(2), c);
});
test("pluck", 1, function() {
equal(col.pluck('label').join(' '), 'a b c d');
});
test("add", 10, function() {
var added, opts, secondAdded;
added = opts = secondAdded = null;
e = new Backbone.Model({id: 10, label : 'e'});
otherCol.add(e);
otherCol.on('add', function() {
secondAdded = true;
});
col.on('add', function(model, collection, options){
added = model.get('label');
opts = options;
});
col.add(e, {amazing: true});
equal(added, 'e');
equal(col.length, 5);
equal(col.last(), e);
equal(otherCol.length, 1);
equal(secondAdded, null);
ok(opts.amazing);
var f = new Backbone.Model({id: 20, label : 'f'});
var g = new Backbone.Model({id: 21, label : 'g'});
var h = new Backbone.Model({id: 22, label : 'h'});
var atCol = new Backbone.Collection([f, g, h]);
equal(atCol.length, 3);
atCol.add(e, {at: 1});
equal(atCol.length, 4);
equal(atCol.at(1), e);
equal(atCol.last(), h);
});
test("add multiple models", 6, function() {
var col = new Backbone.Collection([{at: 0}, {at: 1}, {at: 9}]);
col.add([{at: 2}, {at: 3}, {at: 4}, {at: 5}, {at: 6}, {at: 7}, {at: 8}], {at: 2});
for (var i = 0; i <= 5; i++) {
equal(col.at(i).get('at'), i);
}
});
test("add; at should have preference over comparator", 1, function() {
var Col = Backbone.Collection.extend({
comparator: function(a,b) {
return a.id > b.id ? -1 : 1;
}
});
var col = new Col([{id: 2}, {id: 3}]);
col.add(new Backbone.Model({id: 1}), {at: 1});
equal(col.pluck('id').join(' '), '3 1 2');
});
test("can't add model to collection twice", function() {
var col = new Backbone.Collection([{id: 1}, {id: 2}, {id: 1}, {id: 2}, {id: 3}]);
equal(col.pluck('id').join(' '), '1 2 3');
});
test("can't add different model with same id to collection twice", 1, function() {
var col = new Backbone.Collection;
col.unshift({id: 101});
col.add({id: 101});
equal(col.length, 1);
});
test("merge in duplicate models with {merge: true}", 3, function() {
var col = new Backbone.Collection;
col.add([{id: 1, name: 'Moe'}, {id: 2, name: 'Curly'}, {id: 3, name: 'Larry'}]);
col.add({id: 1, name: 'Moses'});
equal(col.first().get('name'), 'Moe');
col.add({id: 1, name: 'Moses'}, {merge: true});
equal(col.first().get('name'), 'Moses');
col.add({id: 1, name: 'Tim'}, {merge: true, silent: true});
equal(col.first().get('name'), 'Tim');
});
test("add model to multiple collections", 10, function() {
var counter = 0;
var e = new Backbone.Model({id: 10, label : 'e'});
e.on('add', function(model, collection) {
counter++;
equal(e, model);
if (counter > 1) {
equal(collection, colF);
} else {
equal(collection, colE);
}
});
var colE = new Backbone.Collection([]);
colE.on('add', function(model, collection) {
equal(e, model);
equal(colE, collection);
});
var colF = new Backbone.Collection([]);
colF.on('add', function(model, collection) {
equal(e, model);
equal(colF, collection);
});
colE.add(e);
equal(e.collection, colE);
colF.add(e);
equal(e.collection, colE);
});
test("add model with parse", 1, function() {
var Model = Backbone.Model.extend({
parse: function(obj) {
obj.value += 1;
return obj;
}
});
var Col = Backbone.Collection.extend({model: Model});
var col = new Col;
col.add({value: 1}, {parse: true});
equal(col.at(0).get('value'), 2);
});
test("add model to collection with sort()-style comparator", 3, function() {
var col = new Backbone.Collection;
col.comparator = function(a, b) {
return a.get('name') < b.get('name') ? -1 : 1;
};
var tom = new Backbone.Model({name: 'Tom'});
var rob = new Backbone.Model({name: 'Rob'});
var tim = new Backbone.Model({name: 'Tim'});
col.add(tom);
col.add(rob);
col.add(tim);
equal(col.indexOf(rob), 0);
equal(col.indexOf(tim), 1);
equal(col.indexOf(tom), 2);
});
test("comparator that depends on `this`", 2, function() {
var col = new Backbone.Collection;
col.negative = function(num) {
return -num;
};
col.comparator = function(a) {
return this.negative(a.id);
};
col.add([{id: 1}, {id: 2}, {id: 3}]);
deepEqual(col.pluck('id'), [3, 2, 1]);
col.comparator = function(a, b) {
return this.negative(b.id) - this.negative(a.id);
};
col.sort();
deepEqual(col.pluck('id'), [1, 2, 3]);
});
test("remove", 5, function() {
var removed = null;
var otherRemoved = null;
col.on('remove', function(model, col, options) {
removed = model.get('label');
equal(options.index, 3);
});
otherCol.on('remove', function(model, col, options) {
otherRemoved = true;
});
col.remove(d);
equal(removed, 'd');
equal(col.length, 3);
equal(col.first(), a);
equal(otherRemoved, null);
});
test("shift and pop", 2, function() {
var col = new Backbone.Collection([{a: 'a'}, {b: 'b'}, {c: 'c'}]);
equal(col.shift().get('a'), 'a');
equal(col.pop().get('c'), 'c');
});
test("slice", 2, function() {
var col = new Backbone.Collection([{a: 'a'}, {b: 'b'}, {c: 'c'}]);
var array = col.slice(1, 3);
equal(array.length, 2);
equal(array[0].get('b'), 'b');
});
test("events are unbound on remove", 3, function() {
var counter = 0;
var dj = new Backbone.Model();
var emcees = new Backbone.Collection([dj]);
emcees.on('change', function(){ counter++; });
dj.set({name : 'Kool'});
equal(counter, 1);
emcees.reset([]);
equal(dj.collection, undefined);
dj.set({name : 'Shadow'});
equal(counter, 1);
});
test("remove in multiple collections", 7, function() {
var modelData = {
id : 5,
title : 'Othello'
};
var passed = false;
var e = new Backbone.Model(modelData);
var f = new Backbone.Model(modelData);
f.on('remove', function() {
passed = true;
});
var colE = new Backbone.Collection([e]);
var colF = new Backbone.Collection([f]);
ok(e != f);
ok(colE.length == 1);
ok(colF.length == 1);
colE.remove(e);
equal(passed, false);
ok(colE.length == 0);
colF.remove(e);
ok(colF.length == 0);
equal(passed, true);
});
test("remove same model in multiple collection", 16, function() {
var counter = 0;
var e = new Backbone.Model({id: 5, title: 'Othello'});
e.on('remove', function(model, collection) {
counter++;
equal(e, model);
if (counter > 1) {
equal(collection, colE);
} else {
equal(collection, colF);
}
});
var colE = new Backbone.Collection([e]);
colE.on('remove', function(model, collection) {
equal(e, model);
equal(colE, collection);
});
var colF = new Backbone.Collection([e]);
colF.on('remove', function(model, collection) {
equal(e, model);
equal(colF, collection);
});
equal(colE, e.collection);
colF.remove(e);
ok(colF.length == 0);
ok(colE.length == 1);
equal(counter, 1);
equal(colE, e.collection);
colE.remove(e);
equal(null, e.collection);
ok(colE.length == 0);
equal(counter, 2);
});
test("model destroy removes from all collections", 3, function() {
var e = new Backbone.Model({id: 5, title: 'Othello'});
e.sync = function(method, model, options) { options.success({}); };
var colE = new Backbone.Collection([e]);
var colF = new Backbone.Collection([e]);
e.destroy();
ok(colE.length == 0);
ok(colF.length == 0);
equal(undefined, e.collection);
});
test("Colllection: non-persisted model destroy removes from all collections", 3, function() {
var e = new Backbone.Model({title: 'Othello'});
e.sync = function(method, model, options) { throw "should not be called"; };
var colE = new Backbone.Collection([e]);
var colF = new Backbone.Collection([e]);
e.destroy();
ok(colE.length == 0);
ok(colF.length == 0);
equal(undefined, e.collection);
});
test("fetch", 4, function() {
var collection = new Backbone.Collection;
collection.url = '/test';
collection.fetch();
equal(this.syncArgs.method, 'read');
equal(this.syncArgs.model, collection);
equal(this.syncArgs.options.parse, true);
collection.fetch({parse: false});
equal(this.syncArgs.options.parse, false);
});
test("create", 4, function() {
var collection = new Backbone.Collection;
collection.url = '/test';
var model = collection.create({label: 'f'}, {wait: true});
equal(this.syncArgs.method, 'create');
equal(this.syncArgs.model, model);
equal(model.get('label'), 'f');
equal(model.collection, collection);
});
test("create enforces validation", 1, function() {
var ValidatingModel = Backbone.Model.extend({
validate: function(attrs) {
return "fail";
}
});
var ValidatingCollection = Backbone.Collection.extend({
model: ValidatingModel
});
var col = new ValidatingCollection();
equal(col.create({"foo":"bar"}), false);
});
test("a failing create runs the error callback", 1, function() {
var ValidatingModel = Backbone.Model.extend({
validate: function(attrs) {
return "fail";
}
});
var ValidatingCollection = Backbone.Collection.extend({
model: ValidatingModel
});
var flag = false;
var callback = function(model, error) { flag = true; };
var col = new ValidatingCollection();
col.create({"foo":"bar"}, { error: callback });
equal(flag, true);
});
test("initialize", 1, function() {
var Collection = Backbone.Collection.extend({
initialize: function() {
this.one = 1;
}
});
var coll = new Collection;
equal(coll.one, 1);
});
test("toJSON", 1, function() {
equal(JSON.stringify(col), '[{"id":3,"label":"a"},{"id":2,"label":"b"},{"id":1,"label":"c"},{"id":0,"label":"d"}]');
});
test("where", 6, function() {
var coll = new Backbone.Collection([
{a: 1},
{a: 1},
{a: 1, b: 2},
{a: 2, b: 2},
{a: 3}
]);
equal(coll.where({a: 1}).length, 3);
equal(coll.where({a: 2}).length, 1);
equal(coll.where({a: 3}).length, 1);
equal(coll.where({b: 1}).length, 0);
equal(coll.where({b: 2}).length, 2);
equal(coll.where({a: 1, b: 2}).length, 1);
});
test("Underscore methods", 13, function() {
equal(col.map(function(model){ return model.get('label'); }).join(' '), 'a b c d');
equal(col.any(function(model){ return model.id === 100; }), false);
equal(col.any(function(model){ return model.id === 0; }), true);
equal(col.indexOf(b), 1);
equal(col.size(), 4);
equal(col.rest().length, 3);
ok(!_.include(col.rest()), a);
ok(!_.include(col.rest()), d);
ok(!col.isEmpty());
ok(!_.include(col.without(d)), d);
equal(col.max(function(model){ return model.id; }).id, 3);
equal(col.min(function(model){ return model.id; }).id, 0);
deepEqual(col.chain()
.filter(function(o){ return o.id % 2 === 0; })
.map(function(o){ return o.id * 2; })
.value(),
[4, 0]);
});
test("reset", 10, function() {
var resetCount = 0;
var models = col.models;
col.on('reset', function() { resetCount += 1; });
col.reset([]);
equal(resetCount, 1);
equal(col.length, 0);
equal(col.last(), null);
col.reset(models);
equal(resetCount, 2);
equal(col.length, 4);
equal(col.last(), d);
col.reset(_.map(models, function(m){ return m.attributes; }));
equal(resetCount, 3);
equal(col.length, 4);
ok(col.last() !== d);
ok(_.isEqual(col.last().attributes, d.attributes));
});
test("reset passes caller options", 3, function() {
var Model = Backbone.Model.extend({
initialize: function(attrs, options) {
this.model_parameter = options.model_parameter;
}
});
var col = new (Backbone.Collection.extend({ model: Model }))();
col.reset([{ astring: "green", anumber: 1 }, { astring: "blue", anumber: 2 }], { model_parameter: 'model parameter' });
equal(col.length, 2);
col.each(function(model) {
equal(model.model_parameter, 'model parameter');
});
});
test("trigger custom events on models", 1, function() {
var fired = null;
a.on("custom", function() { fired = true; });
a.trigger("custom");
equal(fired, true);
});
test("add does not alter arguments", 2, function(){
var attrs = {};
var models = [attrs];
new Backbone.Collection().add(models);
equal(models.length, 1);
ok(attrs === models[0]);
});
test("#714: access `model.collection` in a brand new model.", 2, function() {
var collection = new Backbone.Collection;
collection.url = '/test';
var Model = Backbone.Model.extend({
set: function(attrs) {
equal(attrs.prop, 'value');
equal(this.collection, collection);
return this;
}
});
collection.model = Model;
collection.create({prop: 'value'});
});
test("#574, remove its own reference to the .models array.", 2, function() {
var col = new Backbone.Collection([
{id: 1}, {id: 2}, {id: 3}, {id: 4}, {id: 5}, {id: 6}
]);
equal(col.length, 6);
col.remove(col.models);
equal(col.length, 0);
});
test("#861, adding models to a collection which do not pass validation", 2, function() {
var Model = Backbone.Model.extend({
validate: function(attrs) {
if (attrs.id == 3) return "id can't be 3";
}
});
var Collection = Backbone.Collection.extend({
model: Model
});
var collection = new Collection;
collection.on("error", function() { ok(true); });
collection.add([{id: 1}, {id: 2}, {id: 3}, {id: 4}, {id: 5}, {id: 6}]);
deepEqual(collection.pluck('id'), [1, 2, 4, 5, 6]);
});
test("Invalid models are discarded.", 5, function() {
var collection = new Backbone.Collection;
collection.on('test', function() { ok(true); });
collection.model = Backbone.Model.extend({
validate: function(attrs){ if (!attrs.valid) return 'invalid'; }
});
var model = new collection.model({id: 1, valid: true});
collection.add([model, {id: 2}]);;
model.trigger('test');
ok(collection.getByCid(model.cid));
ok(collection.get(1));
ok(!collection.get(2));
equal(collection.length, 1);
});
test("multiple copies of the same model", 3, function() {
var col = new Backbone.Collection();
var model = new Backbone.Model();
col.add([model, model]);
equal(col.length, 1);
col.add([{id: 1}, {id: 1}]);
equal(col.length, 2);
equal(col.last().id, 1);
});
test("#964 - collection.get return inconsistent", 2, function() {
var c = new Backbone.Collection();
ok(c.get(null) === undefined);
ok(c.get() === undefined);
});
test("#1112 - passing options.model sets collection.model", 2, function() {
var Model = Backbone.Model.extend({});
var c = new Backbone.Collection([{id: 1}], {model: Model});
ok(c.model === Model);
ok(c.at(0) instanceof Model);
});
test("null and undefined are invalid ids.", 2, function() {
var model = new Backbone.Model({id: 1});
var collection = new Backbone.Collection([model]);
model.set({id: null});
ok(!collection.get('null'));
model.set({id: 1});
model.set({id: undefined});
ok(!collection.get('undefined'));
});
test("falsy comparator", 4, function(){
var Col = Backbone.Collection.extend({
comparator: function(model){ return model.id; }
});
var col = new Col();
var colFalse = new Col(null, {comparator: false});
var colNull = new Col(null, {comparator: null});
var colUndefined = new Col(null, {comparator: undefined});
ok(col.comparator);
ok(!colFalse.comparator);
ok(!colNull.comparator);
ok(colUndefined.comparator);
});
test("#1355 - `options` is passed to success callbacks", 2, function(){
var m = new Backbone.Model({x:1});
var col = new Backbone.Collection();
var opts = {
success: function(collection, resp, options){
ok(options);
}
};
col.sync = m.sync = function( method, collection, options ){
options.success();
};
col.fetch(opts);
col.create(m, opts);
});
test("#1412 - Trigger 'sync' event.", 2, function() {
var collection = new Backbone.Collection;
collection.url = '/test';
collection.on('sync', function() { ok(true); });
Backbone.ajax = function(settings){ settings.success(); };
collection.fetch();
collection.create({id: 1});
});
test("#1447 - create with wait adds model.", 1, function() {
var collection = new Backbone.Collection;
var model = new Backbone.Model;
model.sync = function(method, model, options){ options.success(); };
collection.on('add', function(){ ok(true); });
collection.create(model, {wait: true});
});
test("#1448 - add sorts collection after merge.", 1, function() {
var collection = new Backbone.Collection([
{id: 1, x: 1},
{id: 2, x: 2}
]);
collection.comparator = function(model){ return model.get('x'); };
collection.add({id: 1, x: 3}, {merge: true});
deepEqual(collection.pluck('id'), [2, 1]);
});
test("#1655 - groupBy can be used with a string argument.", 3, function() {
var collection = new Backbone.Collection([{x: 1}, {x: 2}]);
var grouped = collection.groupBy('x');
strictEqual(_.keys(grouped).length, 2);
strictEqual(grouped[1][0].get('x'), 1);
strictEqual(grouped[2][0].get('x'), 2);
});
test("#1655 - sortBy can be used with a string argument.", 1, function() {
var collection = new Backbone.Collection([{x: 3}, {x: 1}, {x: 2}]);
var values = _.map(collection.sortBy('x'), function(model) {
return model.get('x');
});
deepEqual(values, [1, 2, 3]);
});
test("#1604 - Removal during iteration.", 0, function() {
var collection = new Backbone.Collection([{}, {}]);
collection.on('add', function() {
collection.at(0).destroy();
});
collection.add({}, {at: 0});
});
test("#1638 - `sort` during `add` triggers correctly.", function() {
var collection = new Backbone.Collection;
collection.comparator = function(model) { return model.get('x'); };
var added = [];
collection.on('add', function(model) {
model.set({x: 3});
collection.sort();
added.push(model.id);
});
collection.add([{id: 1, x: 1}, {id: 2, x: 2}]);
deepEqual(added, [1, 2]);
});
test("fetch parses models by default", 1, function() {
var model = {};
var Collection = Backbone.Collection.extend({
url: 'test',
model: Backbone.Model.extend({
parse: function(resp) {
strictEqual(resp, model);
}
})
});
new Collection().fetch();
this.ajaxSettings.success([model]);
});
test("`sort` shouldn't always fire on `add`", 1, function() {
var c = new Backbone.Collection([{id: 1}, {id: 2}, {id: 3}], {
comparator: 'id'
});
c.sort = function(){ ok(true); };
c.add([]);
c.add({id: 1});
c.add([{id: 2}, {id: 3}]);
c.add({id: 4});
});
});

45
vendor/backbone/test/environment.js vendored Normal file
View File

@@ -0,0 +1,45 @@
(function() {
var Environment = this.Environment = function(){};
_.extend(Environment.prototype, {
ajax: Backbone.ajax,
sync: Backbone.sync,
emulateHTTP: Backbone.emulateHTTP,
emulateJSON: Backbone.emulateJSON,
setup: function() {
var env = this;
// Capture ajax settings for comparison.
Backbone.ajax = function(settings) {
env.ajaxSettings = settings;
};
// Capture the arguments to Backbone.sync for comparison.
Backbone.sync = function(method, model, options) {
env.syncArgs = {
method: method,
model: model,
options: options
};
env.sync.apply(this, arguments);
};
},
teardown: function() {
this.syncArgs = null;
this.ajaxSettings = null;
Backbone.sync = this.sync;
Backbone.ajax = this.ajax;
Backbone.emulateHTTP = this.emulateHTTP;
Backbone.emulateJSON = this.emulateJSON;
}
});
})();

195
vendor/backbone/test/events.js vendored Normal file
View File

@@ -0,0 +1,195 @@
$(document).ready(function() {
module("Backbone.Events");
test("on and trigger", 2, function() {
var obj = { counter: 0 };
_.extend(obj,Backbone.Events);
obj.on('event', function() { obj.counter += 1; });
obj.trigger('event');
equal(obj.counter,1,'counter should be incremented.');
obj.trigger('event');
obj.trigger('event');
obj.trigger('event');
obj.trigger('event');
equal(obj.counter, 5, 'counter should be incremented five times.');
});
test("binding and triggering multiple events", 4, function() {
var obj = { counter: 0 };
_.extend(obj,Backbone.Events);
obj.on('a b c', function() { obj.counter += 1; });
obj.trigger('a');
equal(obj.counter, 1);
obj.trigger('a b');
equal(obj.counter, 3);
obj.trigger('c');
equal(obj.counter, 4);
obj.off('a c');
obj.trigger('a b c');
equal(obj.counter, 5);
});
test("trigger all for each event", 3, function() {
var a, b, obj = { counter: 0 };
_.extend(obj, Backbone.Events);
obj.on('all', function(event) {
obj.counter++;
if (event == 'a') a = true;
if (event == 'b') b = true;
})
.trigger('a b');
ok(a);
ok(b);
equal(obj.counter, 2);
});
test("on, then unbind all functions", 1, function() {
var obj = { counter: 0 };
_.extend(obj,Backbone.Events);
var callback = function() { obj.counter += 1; };
obj.on('event', callback);
obj.trigger('event');
obj.off('event');
obj.trigger('event');
equal(obj.counter, 1, 'counter should have only been incremented once.');
});
test("bind two callbacks, unbind only one", 2, function() {
var obj = { counterA: 0, counterB: 0 };
_.extend(obj,Backbone.Events);
var callback = function() { obj.counterA += 1; };
obj.on('event', callback);
obj.on('event', function() { obj.counterB += 1; });
obj.trigger('event');
obj.off('event', callback);
obj.trigger('event');
equal(obj.counterA, 1, 'counterA should have only been incremented once.');
equal(obj.counterB, 2, 'counterB should have been incremented twice.');
});
test("unbind a callback in the midst of it firing", 1, function() {
var obj = {counter: 0};
_.extend(obj, Backbone.Events);
var callback = function() {
obj.counter += 1;
obj.off('event', callback);
};
obj.on('event', callback);
obj.trigger('event');
obj.trigger('event');
obj.trigger('event');
equal(obj.counter, 1, 'the callback should have been unbound.');
});
test("two binds that unbind themeselves", 2, function() {
var obj = { counterA: 0, counterB: 0 };
_.extend(obj,Backbone.Events);
var incrA = function(){ obj.counterA += 1; obj.off('event', incrA); };
var incrB = function(){ obj.counterB += 1; obj.off('event', incrB); };
obj.on('event', incrA);
obj.on('event', incrB);
obj.trigger('event');
obj.trigger('event');
obj.trigger('event');
equal(obj.counterA, 1, 'counterA should have only been incremented once.');
equal(obj.counterB, 1, 'counterB should have only been incremented once.');
});
test("bind a callback with a supplied context", 1, function () {
var TestClass = function () {
return this;
};
TestClass.prototype.assertTrue = function () {
ok(true, '`this` was bound to the callback');
};
var obj = _.extend({},Backbone.Events);
obj.on('event', function () { this.assertTrue(); }, (new TestClass));
obj.trigger('event');
});
test("nested trigger with unbind", 1, function () {
var obj = { counter: 0 };
_.extend(obj, Backbone.Events);
var incr1 = function(){ obj.counter += 1; obj.off('event', incr1); obj.trigger('event'); };
var incr2 = function(){ obj.counter += 1; };
obj.on('event', incr1);
obj.on('event', incr2);
obj.trigger('event');
equal(obj.counter, 3, 'counter should have been incremented three times');
});
test("callback list is not altered during trigger", 2, function () {
var counter = 0, obj = _.extend({}, Backbone.Events);
var incr = function(){ counter++; };
obj.on('event', function(){ obj.on('event', incr).on('all', incr); })
.trigger('event');
equal(counter, 0, 'bind does not alter callback list');
obj.off()
.on('event', function(){ obj.off('event', incr).off('all', incr); })
.on('event', incr)
.on('all', incr)
.trigger('event');
equal(counter, 2, 'unbind does not alter callback list');
});
test("#1282 - 'all' callback list is retrieved after each event.", 1, function() {
var counter = 0;
var obj = _.extend({}, Backbone.Events);
var incr = function(){ counter++; };
obj.on('x', function() {
obj.on('y', incr).on('all', incr);
})
.trigger('x y');
strictEqual(counter, 2);
});
test("if no callback is provided, `on` is a noop", 0, function() {
_.extend({}, Backbone.Events).on('test').trigger('test');
});
test("remove all events for a specific context", 4, function() {
var obj = _.extend({}, Backbone.Events);
obj.on('x y all', function() { ok(true); });
obj.on('x y all', function() { ok(false); }, obj);
obj.off(null, null, obj);
obj.trigger('x y');
});
test("remove all events for a specific callback", 4, function() {
var obj = _.extend({}, Backbone.Events);
var success = function() { ok(true); };
var fail = function() { ok(false); };
obj.on('x y all', success);
obj.on('x y all', fail);
obj.off(null, fail);
obj.trigger('x y');
});
test("off is chainable", 3, function() {
var obj = _.extend({}, Backbone.Events);
// With no events
ok(obj.off() === obj);
// When removing all events
obj.on('event', function(){}, obj);
ok(obj.off() === obj);
// When removing some events
obj.on('event', function(){}, obj);
ok(obj.off('event') === obj);
});
test("#1310 - off does not skip consecutive events", 0, function() {
var obj = _.extend({}, Backbone.Events);
obj.on('event', function() { ok(false); }, obj);
obj.on('event', function() { ok(false); }, obj);
obj.off(null, null, obj);
obj.trigger('event');
});
});

920
vendor/backbone/test/model.js vendored Normal file
View File

@@ -0,0 +1,920 @@
$(document).ready(function() {
var proxy = Backbone.Model.extend();
var klass = Backbone.Collection.extend({
url : function() { return '/collection'; }
});
var doc, collection;
module("Backbone.Model", _.extend(new Environment, {
setup: function() {
Environment.prototype.setup.apply(this, arguments);
doc = new proxy({
id : '1-the-tempest',
title : "The Tempest",
author : "Bill Shakespeare",
length : 123
});
collection = new klass();
collection.add(doc);
}
}));
test("initialize", 3, function() {
var Model = Backbone.Model.extend({
initialize: function() {
this.one = 1;
equal(this.collection, collection);
}
});
var model = new Model({}, {collection: collection});
equal(model.one, 1);
equal(model.collection, collection);
});
test("initialize with attributes and options", 1, function() {
var Model = Backbone.Model.extend({
initialize: function(attributes, options) {
this.one = options.one;
}
});
var model = new Model({}, {one: 1});
equal(model.one, 1);
});
test("initialize with parsed attributes", 1, function() {
var Model = Backbone.Model.extend({
parse: function(obj) {
obj.value += 1;
return obj;
}
});
var model = new Model({value: 1}, {parse: true});
equal(model.get('value'), 2);
});
test("parse can return null", 1, function() {
var Model = Backbone.Model.extend({
parse: function(obj) {
obj.value += 1;
return null;
}
});
var model = new Model({value: 1}, {parse: true});
equal(JSON.stringify(model.toJSON()), "{}");
});
test("url", 3, function() {
doc.urlRoot = null;
equal(doc.url(), '/collection/1-the-tempest');
doc.collection.url = '/collection/';
equal(doc.url(), '/collection/1-the-tempest');
doc.collection = null;
raises(function() { doc.url(); });
doc.collection = collection;
});
test("url when using urlRoot, and uri encoding", 2, function() {
var Model = Backbone.Model.extend({
urlRoot: '/collection'
});
var model = new Model();
equal(model.url(), '/collection');
model.set({id: '+1+'});
equal(model.url(), '/collection/%2B1%2B');
});
test("url when using urlRoot as a function to determine urlRoot at runtime", 2, function() {
var Model = Backbone.Model.extend({
urlRoot: function() {
return '/nested/' + this.get('parent_id') + '/collection';
}
});
var model = new Model({parent_id: 1});
equal(model.url(), '/nested/1/collection');
model.set({id: 2});
equal(model.url(), '/nested/1/collection/2');
});
test("clone", 10, function() {
var a = new Backbone.Model({ 'foo': 1, 'bar': 2, 'baz': 3});
var b = a.clone();
equal(a.get('foo'), 1);
equal(a.get('bar'), 2);
equal(a.get('baz'), 3);
equal(b.get('foo'), a.get('foo'), "Foo should be the same on the clone.");
equal(b.get('bar'), a.get('bar'), "Bar should be the same on the clone.");
equal(b.get('baz'), a.get('baz'), "Baz should be the same on the clone.");
a.set({foo : 100});
equal(a.get('foo'), 100);
equal(b.get('foo'), 1, "Changing a parent attribute does not change the clone.");
var foo = new Backbone.Model({p: 1});
var bar = new Backbone.Model({p: 2});
bar.set(foo.clone(), {unset: true});
equal(foo.get('p'), 1);
equal(bar.get('p'), undefined);
});
test("isNew", 6, function() {
var a = new Backbone.Model({ 'foo': 1, 'bar': 2, 'baz': 3});
ok(a.isNew(), "it should be new");
a = new Backbone.Model({ 'foo': 1, 'bar': 2, 'baz': 3, 'id': -5 });
ok(!a.isNew(), "any defined ID is legal, negative or positive");
a = new Backbone.Model({ 'foo': 1, 'bar': 2, 'baz': 3, 'id': 0 });
ok(!a.isNew(), "any defined ID is legal, including zero");
ok( new Backbone.Model({ }).isNew(), "is true when there is no id");
ok(!new Backbone.Model({ 'id': 2 }).isNew(), "is false for a positive integer");
ok(!new Backbone.Model({ 'id': -5 }).isNew(), "is false for a negative integer");
});
test("get", 2, function() {
equal(doc.get('title'), 'The Tempest');
equal(doc.get('author'), 'Bill Shakespeare');
});
test("escape", 5, function() {
equal(doc.escape('title'), 'The Tempest');
doc.set({audience: 'Bill & Bob'});
equal(doc.escape('audience'), 'Bill &amp; Bob');
doc.set({audience: 'Tim > Joan'});
equal(doc.escape('audience'), 'Tim &gt; Joan');
doc.set({audience: 10101});
equal(doc.escape('audience'), '10101');
doc.unset('audience');
equal(doc.escape('audience'), '');
});
test("has", 10, function() {
var model = new Backbone.Model();
strictEqual(model.has('name'), false);
model.set({
'0': 0,
'1': 1,
'true': true,
'false': false,
'empty': '',
'name': 'name',
'null': null,
'undefined': undefined
});
strictEqual(model.has('0'), true);
strictEqual(model.has('1'), true);
strictEqual(model.has('true'), true);
strictEqual(model.has('false'), true);
strictEqual(model.has('empty'), true);
strictEqual(model.has('name'), true);
model.unset('name');
strictEqual(model.has('name'), false);
strictEqual(model.has('null'), false);
strictEqual(model.has('undefined'), false);
});
test("set and unset", 8, function() {
var a = new Backbone.Model({id: 'id', foo: 1, bar: 2, baz: 3});
var changeCount = 0;
a.on("change:foo", function() { changeCount += 1; });
a.set({'foo': 2});
ok(a.get('foo') == 2, "Foo should have changed.");
ok(changeCount == 1, "Change count should have incremented.");
a.set({'foo': 2}); // set with value that is not new shouldn't fire change event
ok(a.get('foo') == 2, "Foo should NOT have changed, still 2");
ok(changeCount == 1, "Change count should NOT have incremented.");
a.validate = function(attrs) {
equal(attrs.foo, void 0, "don't ignore values when unsetting");
};
a.unset('foo');
equal(a.get('foo'), void 0, "Foo should have changed");
delete a.validate;
ok(changeCount == 2, "Change count should have incremented for unset.");
a.unset('id');
equal(a.id, undefined, "Unsetting the id should remove the id property.");
});
test("multiple unsets", 1, function() {
var i = 0;
var counter = function(){ i++; };
var model = new Backbone.Model({a: 1});
model.on("change:a", counter);
model.set({a: 2});
model.unset('a');
model.unset('a');
equal(i, 2, 'Unset does not fire an event for missing attributes.');
});
test("unset and changedAttributes", 2, function() {
var model = new Backbone.Model({a: 1});
model.unset('a', {silent: true});
var changedAttributes = model.changedAttributes();
ok('a' in changedAttributes, 'changedAttributes should contain unset properties');
changedAttributes = model.changedAttributes();
ok('a' in changedAttributes, 'changedAttributes should contain unset properties when running changedAttributes again after an unset.');
});
test("using a non-default id attribute.", 5, function() {
var MongoModel = Backbone.Model.extend({idAttribute : '_id'});
var model = new MongoModel({id: 'eye-dee', _id: 25, title: 'Model'});
equal(model.get('id'), 'eye-dee');
equal(model.id, 25);
equal(model.isNew(), false);
model.unset('_id');
equal(model.id, undefined);
equal(model.isNew(), true);
});
test("set an empty string", 1, function() {
var model = new Backbone.Model({name : "Model"});
model.set({name : ''});
equal(model.get('name'), '');
});
test("clear", 3, function() {
var changed;
var model = new Backbone.Model({id: 1, name : "Model"});
model.on("change:name", function(){ changed = true; });
model.on("change", function() {
var changedAttrs = model.changedAttributes();
ok('name' in changedAttrs);
});
model.clear();
equal(changed, true);
equal(model.get('name'), undefined);
});
test("defaults", 4, function() {
var Defaulted = Backbone.Model.extend({
defaults: {
"one": 1,
"two": 2
}
});
var model = new Defaulted({two: null});
equal(model.get('one'), 1);
equal(model.get('two'), null);
Defaulted = Backbone.Model.extend({
defaults: function() {
return {
"one": 3,
"two": 4
};
}
});
var model = new Defaulted({two: null});
equal(model.get('one'), 3);
equal(model.get('two'), null);
});
test("change, hasChanged, changedAttributes, previous, previousAttributes", 12, function() {
var model = new Backbone.Model({name : "Tim", age : 10});
equal(model.changedAttributes(), false);
model.on('change', function() {
ok(model.hasChanged('name'), 'name changed');
ok(!model.hasChanged('age'), 'age did not');
ok(_.isEqual(model.changedAttributes(), {name : 'Rob'}), 'changedAttributes returns the changed attrs');
equal(model.previous('name'), 'Tim');
ok(_.isEqual(model.previousAttributes(), {name : "Tim", age : 10}), 'previousAttributes is correct');
});
equal(model.hasChanged(), false);
equal(model.hasChanged(undefined), false);
model.set({name : 'Rob'}, {silent : true});
equal(model.hasChanged(), true);
equal(model.hasChanged(undefined), true);
equal(model.hasChanged('name'), true);
model.change();
equal(model.get('name'), 'Rob');
});
test("changedAttributes", 3, function() {
var model = new Backbone.Model({a: 'a', b: 'b'});
equal(model.changedAttributes(), false);
equal(model.changedAttributes({a: 'a'}), false);
equal(model.changedAttributes({a: 'b'}).a, 'b');
});
test("change with options", 2, function() {
var value;
var model = new Backbone.Model({name: 'Rob'});
model.on('change', function(model, options) {
value = options.prefix + model.get('name');
});
model.set({name: 'Bob'}, {silent: true});
model.change({prefix: 'Mr. '});
equal(value, 'Mr. Bob');
model.set({name: 'Sue'}, {prefix: 'Ms. '});
equal(value, 'Ms. Sue');
});
test("change after initialize", 1, function () {
var changed = 0;
var attrs = {id: 1, label: 'c'};
var obj = new Backbone.Model(attrs);
obj.on('change', function() { changed += 1; });
obj.set(attrs);
equal(changed, 0);
});
test("save within change event", 1, function () {
var env = this;
var model = new Backbone.Model({firstName : "Taylor", lastName: "Swift"});
model.url = '/test';
model.on('change', function () {
model.save();
ok(_.isEqual(env.syncArgs.model, model));
});
model.set({lastName: 'Hicks'});
});
test("validate after save", 1, function() {
var lastError, model = new Backbone.Model();
model.validate = function(attrs) {
if (attrs.admin) return "Can't change admin status.";
};
model.sync = function(method, model, options) {
options.success.call(this, {admin: true});
};
model.save(null, {error: function(model, error) {
lastError = error;
}});
equal(lastError, "Can't change admin status.");
});
test("isValid", 5, function() {
var model = new Backbone.Model({valid: true});
model.validate = function(attrs) {
if (!attrs.valid) return "invalid";
};
equal(model.isValid(), true);
equal(model.set({valid: false}), false);
equal(model.isValid(), true);
ok(model.set('valid', false, {silent: true}));
equal(model.isValid(), false);
});
test("save", 2, function() {
doc.save({title : "Henry V"});
equal(this.syncArgs.method, 'update');
ok(_.isEqual(this.syncArgs.model, doc));
});
test("save in positional style", 1, function() {
var model = new Backbone.Model();
model.sync = function(method, model, options) {
options.success();
};
model.save('title', 'Twelfth Night');
equal(model.get('title'), 'Twelfth Night');
});
test("fetch", 2, function() {
doc.fetch();
equal(this.syncArgs.method, 'read');
ok(_.isEqual(this.syncArgs.model, doc));
});
test("destroy", 3, function() {
doc.destroy();
equal(this.syncArgs.method, 'delete');
ok(_.isEqual(this.syncArgs.model, doc));
var newModel = new Backbone.Model;
equal(newModel.destroy(), false);
});
test("non-persisted destroy", 1, function() {
var a = new Backbone.Model({ 'foo': 1, 'bar': 2, 'baz': 3});
a.sync = function() { throw "should not be called"; };
a.destroy();
ok(true, "non-persisted model should not call sync");
});
test("validate", 7, function() {
var lastError;
var model = new Backbone.Model();
model.validate = function(attrs) {
if (attrs.admin != this.get('admin')) return "Can't change admin status.";
};
model.on('error', function(model, error) {
lastError = error;
});
var result = model.set({a: 100});
equal(result, model);
equal(model.get('a'), 100);
equal(lastError, undefined);
result = model.set({admin: true}, {silent: true});
equal(model.get('admin'), true);
result = model.set({a: 200, admin: false});
equal(lastError, "Can't change admin status.");
equal(result, false);
equal(model.get('a'), 100);
});
test("validate on unset and clear", 6, function() {
var error;
var model = new Backbone.Model({name: "One"});
model.validate = function(attrs) {
if (!attrs.name) {
error = true;
return "No thanks.";
}
};
model.set({name: "Two"});
equal(model.get('name'), 'Two');
equal(error, undefined);
model.unset('name');
equal(error, true);
equal(model.get('name'), 'Two');
model.clear();
equal(model.get('name'), 'Two');
delete model.validate;
model.clear();
equal(model.get('name'), undefined);
});
test("validate with error callback", 8, function() {
var lastError, boundError;
var model = new Backbone.Model();
model.validate = function(attrs) {
if (attrs.admin) return "Can't change admin status.";
};
var callback = function(model, error) {
lastError = error;
};
model.on('error', function(model, error) {
boundError = true;
});
var result = model.set({a: 100}, {error: callback});
equal(result, model);
equal(model.get('a'), 100);
equal(lastError, undefined);
equal(boundError, undefined);
result = model.set({a: 200, admin: true}, {error: callback});
equal(result, false);
equal(model.get('a'), 100);
equal(lastError, "Can't change admin status.");
equal(boundError, true);
});
test("defaults always extend attrs (#459)", 2, function() {
var Defaulted = Backbone.Model.extend({
defaults: {one: 1},
initialize : function(attrs, opts) {
equal(this.attributes.one, 1);
}
});
var providedattrs = new Defaulted({});
var emptyattrs = new Defaulted();
});
test("Inherit class properties", 6, function() {
var Parent = Backbone.Model.extend({
instancePropSame: function() {},
instancePropDiff: function() {}
}, {
classProp: function() {}
});
var Child = Parent.extend({
instancePropDiff: function() {}
});
var adult = new Parent;
var kid = new Child;
equal(Child.classProp, Parent.classProp);
notEqual(Child.classProp, undefined);
equal(kid.instancePropSame, adult.instancePropSame);
notEqual(kid.instancePropSame, undefined);
notEqual(Child.prototype.instancePropDiff, Parent.prototype.instancePropDiff);
notEqual(Child.prototype.instancePropDiff, undefined);
});
test("Nested change events don't clobber previous attributes", 4, function() {
new Backbone.Model()
.on('change:state', function(model, newState) {
equal(model.previous('state'), undefined);
equal(newState, 'hello');
// Fire a nested change event.
model.set({other: 'whatever'});
})
.on('change:state', function(model, newState) {
equal(model.previous('state'), undefined);
equal(newState, 'hello');
})
.set({state: 'hello'});
});
test("hasChanged/set should use same comparison", 2, function() {
var changed = 0, model = new Backbone.Model({a: null});
model.on('change', function() {
ok(this.hasChanged('a'));
})
.on('change:a', function() {
changed++;
})
.set({a: undefined});
equal(changed, 1);
});
test("#582, #425, change:attribute callbacks should fire after all changes have occurred", 9, function() {
var model = new Backbone.Model;
var assertion = function() {
equal(model.get('a'), 'a');
equal(model.get('b'), 'b');
equal(model.get('c'), 'c');
};
model.on('change:a', assertion);
model.on('change:b', assertion);
model.on('change:c', assertion);
model.set({a: 'a', b: 'b', c: 'c'});
});
test("#871, set with attributes property", 1, function() {
var model = new Backbone.Model();
model.set({attributes: true});
ok(model.has('attributes'));
});
test("set value regardless of equality/change", 1, function() {
var model = new Backbone.Model({x: []});
var a = [];
model.set({x: a});
ok(model.get('x') === a);
});
test("unset fires change for undefined attributes", 1, function() {
var model = new Backbone.Model({x: undefined});
model.on('change:x', function(){ ok(true); });
model.unset('x');
});
test("set: undefined values", 1, function() {
var model = new Backbone.Model({x: undefined});
ok('x' in model.attributes);
});
test("change fires change:attr", 1, function() {
var model = new Backbone.Model({x: 1});
model.set({x: 2}, {silent: true});
model.on('change:x', function(){ ok(true); });
model.change();
});
test("hasChanged is false after original values are set", 2, function() {
var model = new Backbone.Model({x: 1});
model.on('change:x', function(){ ok(false); });
model.set({x: 2}, {silent: true});
ok(model.hasChanged());
model.set({x: 1}, {silent: true});
ok(!model.hasChanged());
});
test("save with `wait` succeeds without `validate`", 1, function() {
var model = new Backbone.Model();
model.url = '/test';
model.save({x: 1}, {wait: true});
ok(this.syncArgs.model === model);
});
test("`hasChanged` for falsey keys", 2, function() {
var model = new Backbone.Model();
model.set({x: true}, {silent: true});
ok(!model.hasChanged(0));
ok(!model.hasChanged(''));
});
test("`previous` for falsey keys", 2, function() {
var model = new Backbone.Model({0: true, '': true});
model.set({0: false, '': false}, {silent: true});
equal(model.previous(0), true);
equal(model.previous(''), true);
});
test("`save` with `wait` sends correct attributes", 5, function() {
var changed = 0;
var model = new Backbone.Model({x: 1, y: 2});
model.url = '/test';
model.on('change:x', function() { changed++; });
model.save({x: 3}, {wait: true});
deepEqual(JSON.parse(this.ajaxSettings.data), {x: 3, y: 2});
equal(model.get('x'), 1);
equal(changed, 0);
this.syncArgs.options.success({});
equal(model.get('x'), 3);
equal(changed, 1);
});
test("a failed `save` with `wait` doesn't leave attributes behind", 1, function() {
var model = new Backbone.Model;
model.url = '/test';
model.save({x: 1}, {wait: true});
equal(model.get('x'), void 0);
});
test("#1030 - `save` with `wait` results in correct attributes if success is called during sync", 2, function() {
var model = new Backbone.Model({x: 1, y: 2});
model.sync = function(method, model, options) {
options.success();
};
model.on("change:x", function() { ok(true); });
model.save({x: 3}, {wait: true});
equal(model.get('x'), 3);
});
test("save with wait validates attributes", 1, function() {
var model = new Backbone.Model();
model.url = '/test';
model.validate = function() { ok(true); };
model.save({x: 1}, {wait: true});
});
test("nested `set` during `'change:attr'`", 2, function() {
var events = [];
var model = new Backbone.Model();
model.on('all', function(event) { events.push(event); });
model.on('change', function() {
model.set({z: true}, {silent:true});
});
model.on('change:x', function() {
model.set({y: true});
});
model.set({x: true});
deepEqual(events, ['change:y', 'change:x', 'change']);
events = [];
model.change();
deepEqual(events, ['change:z', 'change']);
});
test("nested `change` only fires once", 1, function() {
var model = new Backbone.Model();
model.on('change', function() {
ok(true);
model.change();
});
model.set({x: true});
});
test("no `'change'` event if no changes", 0, function() {
var model = new Backbone.Model();
model.on('change', function() { ok(false); });
model.change();
});
test("nested `set` during `'change'`", 6, function() {
var count = 0;
var model = new Backbone.Model();
model.on('change', function() {
switch(count++) {
case 0:
deepEqual(this.changedAttributes(), {x: true});
equal(model.previous('x'), undefined);
model.set({y: true});
break;
case 1:
deepEqual(this.changedAttributes(), {y: true});
equal(model.previous('x'), true);
model.set({z: true});
break;
case 2:
deepEqual(this.changedAttributes(), {z: true});
equal(model.previous('y'), true);
break;
default:
ok(false);
}
});
model.set({x: true});
});
test("nested `'change'` with silent", 3, function() {
var count = 0;
var model = new Backbone.Model();
model.on('change:y', function() { ok(true); });
model.on('change', function() {
switch(count++) {
case 0:
deepEqual(this.changedAttributes(), {x: true});
model.set({y: true}, {silent: true});
break;
case 1:
deepEqual(this.changedAttributes(), {y: true, z: true});
break;
default:
ok(false);
}
});
model.set({x: true});
model.set({z: true});
});
test("nested `'change:attr'` with silent", 1, function() {
var model = new Backbone.Model();
model.on('change:y', function(){ ok(true); });
model.on('change', function() {
model.set({y: true}, {silent: true});
model.set({z: true});
});
model.set({x: true});
});
test("multiple nested changes with silent", 1, function() {
var model = new Backbone.Model();
model.on('change:x', function() {
model.set({y: 1}, {silent: true});
model.set({y: 2});
});
model.on('change:y', function(model, val) {
equal(val, 2);
});
model.set({x: true});
model.change();
});
test("multiple nested changes with silent", 2, function() {
var changes = [];
var model = new Backbone.Model();
model.on('change:b', function(model, val) { changes.push(val); });
model.on('change', function() {
model.set({b: 1});
model.set({b: 2}, {silent: true});
});
model.set({b: 0});
deepEqual(changes, [0, 1]);
model.change();
deepEqual(changes, [0, 1, 2, 1]);
});
test("nested set multiple times", 1, function() {
var model = new Backbone.Model();
model.on('change:b', function() {
ok(true);
});
model.on('change:a', function() {
model.set({b: true});
model.set({b: true});
});
model.set({a: true});
});
test("#1179 - isValid returns true in the absence of validate.", 1, function() {
var model = new Backbone.Model();
model.validate = null;
ok(model.isValid());
});
test("#1122 - clear does not alter options.", 1, function() {
var model = new Backbone.Model();
var options = {};
model.clear(options);
ok(!options.unset);
});
test("#1122 - unset does not alter options.", 1, function() {
var model = new Backbone.Model();
var options = {};
model.unset('x', options);
ok(!options.unset);
});
test("#1355 - `options` is passed to success callbacks", 3, function() {
var model = new Backbone.Model();
var opts = {
success: function( model, resp, options ) {
ok(options);
}
};
model.sync = function(method, model, options) {
options.success();
};
model.save({id: 1}, opts);
model.fetch(opts);
model.destroy(opts);
});
test("#1412 - Trigger 'sync' event.", 3, function() {
var model = new Backbone.Model({id: 1});
model.url = '/test';
model.on('sync', function(){ ok(true); });
Backbone.ajax = function(settings){ settings.success(); };
model.fetch();
model.save();
model.destroy();
});
test("#1365 - Destroy: New models execute success callback.", 2, function() {
new Backbone.Model()
.on('sync', function() { ok(false); })
.on('destroy', function(){ ok(true); })
.destroy({ success: function(){ ok(true); }});
});
test("#1433 - Save: An invalid model cannot be persisted.", 1, function() {
var model = new Backbone.Model;
model.validate = function(){ return 'invalid'; };
model.sync = function(){ ok(false); };
strictEqual(model.save(), false);
});
test("#1377 - Save without attrs triggers 'error'.", 1, function() {
var Model = Backbone.Model.extend({
url: '/test/',
sync: function(method, model, options){ options.success(); },
validate: function(){ return 'invalid'; }
});
var model = new Model({id: 1});
model.on('error', function(){ ok(true); });
model.save();
});
test("#1545 - `undefined` can be passed to a model constructor without coersion", function() {
var Model = Backbone.Model.extend({
defaults: { one: 1 },
initialize : function(attrs, opts) {
equal(attrs, undefined);
}
});
var emptyattrs = new Model();
var undefinedattrs = new Model(undefined);
});
asyncTest("#1478 - Model `save` does not trigger change on unchanged attributes", 0, function() {
var Model = Backbone.Model.extend({
sync: function(method, model, options) {
setTimeout(function(){
options.success();
start();
}, 0);
}
});
new Model({x: true})
.on('change:x', function(){ ok(false); })
.save(null, {wait: true});
});
test("#1664 - Changing from one value, silently to another, back to original does not trigger change.", 0, function() {
var model = new Backbone.Model({x:1});
model.on('change:x', function() { ok(false); });
model.set({x:2},{silent:true});
model.set({x:3},{silent:true});
model.set({x:1});
});
test("#1664 - multiple silent changes nested inside a change event", 2, function() {
var changes = [];
var model = new Backbone.Model();
model.on('change', function() {
model.set({a:'c'}, {silent:true});
model.set({b:2}, {silent:true});
model.unset('c', {silent:true});
model.set({a:'a'}, {silent:true});
model.set({b:1}, {silent:true});
model.set({c:'item'}, {silent:true});
});
model.on('change:a change:b change:c', function(model, val) { changes.push(val); });
model.set({a:'a', b:1, c:'item'});
deepEqual(changes, ['a',1,'item']);
model.change();
deepEqual(changes, ['a',1,'item']);
});
test("#1791 - `attributes` is available for `parse`", function() {
var Model = Backbone.Model.extend({
parse: function() { this.has('a'); } // shouldn't throw an error
});
var model = new Model(null, {parse: true});
expect(0);
});
test("silent changes in last `change` event back to original does not trigger change", 2, function() {
var changes = [];
var model = new Backbone.Model();
model.on('change:a change:b change:c', function(model, val) { changes.push(val); });
model.on('change', function() {
model.set({a:'c'}, {silent:true});
});
model.set({a:'a'});
deepEqual(changes, ['a']);
model.set({a:'a'}, {silent:true});
model.change();
deepEqual(changes, ['a']);
});
});

12
vendor/backbone/test/noconflict.js vendored Normal file
View File

@@ -0,0 +1,12 @@
$(document).ready(function() {
module("Backbone.noConflict");
test('noConflict', 2, function() {
var noconflictBackbone = Backbone.noConflict();
equal(window.Backbone, undefined, 'Returned window.Backbone');
window.Backbone = noconflictBackbone;
equal(window.Backbone, noconflictBackbone, 'Backbone is still pointing to the original Backbone');
});
});

505
vendor/backbone/test/router.js vendored Normal file
View File

@@ -0,0 +1,505 @@
$(document).ready(function() {
var router = null;
var location = null;
var lastRoute = null;
var lastArgs = [];
function onRoute(router, route, args) {
lastRoute = route;
lastArgs = args;
}
var Location = function(href) {
this.replace(href);
};
_.extend(Location.prototype, {
replace: function(href) {
_.extend(this, _.pick($('<a></a>', {href: href})[0],
'href',
'hash',
'host',
'search',
'fragment',
'pathname',
'protocol'
));
// In IE, anchor.pathname does not contain a leading slash though
// window.location.pathname does.
if (!/^\//.test(this.pathname)) this.pathname = '/' + this.pathname;
},
toString: function() {
return this.href;
}
});
module("Backbone.Router", {
setup: function() {
location = new Location('http://example.com');
Backbone.history = _.extend(new Backbone.History, {location: location});
router = new Router({testing: 101});
Backbone.history.interval = 9;
Backbone.history.start({pushState: false});
lastRoute = null;
lastArgs = [];
Backbone.history.on('route', onRoute);
},
teardown: function() {
Backbone.history.stop();
Backbone.history.off('route', onRoute);
}
});
var Router = Backbone.Router.extend({
count: 0,
routes: {
"noCallback": "noCallback",
"counter": "counter",
"search/:query": "search",
"search/:query/p:page": "search",
"contacts": "contacts",
"contacts/new": "newContact",
"contacts/:id": "loadContact",
"optional(/:item)": "optionalItem",
"splat/*args/end": "splat",
"*first/complex-:part/*rest": "complex",
":entity?*args": "query",
"*anything": "anything"
},
initialize : function(options) {
this.testing = options.testing;
this.route('implicit', 'implicit');
},
counter: function() {
this.count++;
},
implicit: function() {
this.count++;
},
search : function(query, page) {
this.query = query;
this.page = page;
},
contacts: function(){
this.contact = 'index';
},
newContact: function(){
this.contact = 'new';
},
loadContact: function(){
this.contact = 'load';
},
optionalItem: function(arg){
this.arg = arg !== undefined ? arg : null;
},
splat : function(args) {
this.args = args;
},
complex : function(first, part, rest) {
this.first = first;
this.part = part;
this.rest = rest;
},
query : function(entity, args) {
this.entity = entity;
this.queryArgs = args;
},
anything : function(whatever) {
this.anything = whatever;
}
});
test("initialize", 1, function() {
equal(router.testing, 101);
});
test("routes (simple)", 4, function() {
location.replace('http://example.com#search/news');
Backbone.history.checkUrl();
equal(router.query, 'news');
equal(router.page, undefined);
equal(lastRoute, 'search');
equal(lastArgs[0], 'news');
});
test("routes (two part)", 2, function() {
location.replace('http://example.com#search/nyc/p10');
Backbone.history.checkUrl();
equal(router.query, 'nyc');
equal(router.page, '10');
});
test("routes via navigate", 2, function() {
Backbone.history.navigate('search/manhattan/p20', {trigger: true});
equal(router.query, 'manhattan');
equal(router.page, '20');
});
test("routes via navigate for backwards-compatibility", 2, function() {
Backbone.history.navigate('search/manhattan/p20', true);
equal(router.query, 'manhattan');
equal(router.page, '20');
});
test("route precedence via navigate", 6, function(){
// check both 0.9.x and backwards-compatibility options
_.each([ { trigger: true }, true ], function( options ){
Backbone.history.navigate('contacts', options);
equal(router.contact, 'index');
Backbone.history.navigate('contacts/new', options);
equal(router.contact, 'new');
Backbone.history.navigate('contacts/foo', options);
equal(router.contact, 'load');
});
});
test("loadUrl is not called for identical routes.", 0, function() {
Backbone.history.loadUrl = function(){ ok(false); };
location.replace('http://example.com#route');
Backbone.history.navigate('route');
Backbone.history.navigate('/route');
Backbone.history.navigate('/route');
});
test("use implicit callback if none provided", 1, function() {
router.count = 0;
router.navigate('implicit', {trigger: true});
equal(router.count, 1);
});
test("routes via navigate with {replace: true}", 1, function() {
location.replace('http://example.com#start_here');
Backbone.history.checkUrl();
location.replace = function(href) {
strictEqual(href, new Location('http://example.com#end_here').href);
};
Backbone.history.navigate('end_here', {replace: true});
});
test("routes (splats)", 1, function() {
location.replace('http://example.com#splat/long-list/of/splatted_99args/end');
Backbone.history.checkUrl();
equal(router.args, 'long-list/of/splatted_99args');
});
test("routes (optional)", 2, function() {
location.replace('http://example.com#optional');
Backbone.history.checkUrl();
equal(router.arg, null);
location.replace('http://example.com#optional/thing');
Backbone.history.checkUrl();
equal(router.arg, 'thing');
});
test("routes (complex)", 3, function() {
location.replace('http://example.com#one/two/three/complex-part/four/five/six/seven');
Backbone.history.checkUrl();
equal(router.first, 'one/two/three');
equal(router.part, 'part');
equal(router.rest, 'four/five/six/seven');
});
test("routes (query)", 5, function() {
location.replace('http://example.com#mandel?a=b&c=d');
Backbone.history.checkUrl();
equal(router.entity, 'mandel');
equal(router.queryArgs, 'a=b&c=d');
equal(lastRoute, 'query');
equal(lastArgs[0], 'mandel');
equal(lastArgs[1], 'a=b&c=d');
});
test("routes (anything)", 1, function() {
location.replace('http://example.com#doesnt-match-a-route');
Backbone.history.checkUrl();
equal(router.anything, 'doesnt-match-a-route');
});
test("fires event when router doesn't have callback on it", 1, function() {
router.on("route:noCallback", function(){ ok(true); });
location.replace('http://example.com#noCallback');
Backbone.history.checkUrl();
});
test("#933, #908 - leading slash", 2, function() {
location.replace('http://example.com/root/foo');
Backbone.history.stop();
Backbone.history = _.extend(new Backbone.History, {location: location});
Backbone.history.start({root: '/root', hashChange: false, silent: true});
strictEqual(Backbone.history.getFragment(), 'foo');
Backbone.history.stop();
Backbone.history = _.extend(new Backbone.History, {location: location});
Backbone.history.start({root: '/root/', hashChange: false, silent: true});
strictEqual(Backbone.history.getFragment(), 'foo');
});
test("#1003 - History is started before navigate is called", 1, function() {
Backbone.history.stop();
Backbone.history.navigate = function(){ ok(Backbone.History.started); };
Backbone.history.start();
// If this is not an old IE navigate will not be called.
if (!Backbone.history.iframe) ok(true);
});
test("route callback gets passed decoded values", 3, function() {
var route = 'has%2Fslash/complex-has%23hash/has%20space';
Backbone.history.navigate(route, {trigger: true});
equal(router.first, 'has/slash');
equal(router.part, 'has#hash');
equal(router.rest, 'has space');
});
test("correctly handles URLs with % (#868)", 3, function() {
location.replace('http://example.com#search/fat%3A1.5%25');
Backbone.history.checkUrl();
location.replace('http://example.com#search/fat');
Backbone.history.checkUrl();
equal(router.query, 'fat');
equal(router.page, undefined);
equal(lastRoute, 'search');
});
test("#1185 - Use pathname when hashChange is not wanted.", 1, function() {
Backbone.history.stop();
location.replace('http://example.com/path/name#hash');
Backbone.history = _.extend(new Backbone.History, {location: location});
Backbone.history.start({hashChange: false});
var fragment = Backbone.history.getFragment();
strictEqual(fragment, location.pathname.replace(/^\//, ''));
});
test("#1206 - Strip leading slash before location.assign.", 1, function() {
Backbone.history.stop();
location.replace('http://example.com/root/');
Backbone.history = _.extend(new Backbone.History, {location: location});
Backbone.history.start({hashChange: false, root: '/root/'});
location.assign = function(pathname) {
strictEqual(pathname, '/root/fragment');
};
Backbone.history.navigate('/fragment');
});
test("#1387 - Root fragment without trailing slash.", 1, function() {
Backbone.history.stop();
location.replace('http://example.com/root');
Backbone.history = _.extend(new Backbone.History, {location: location});
Backbone.history.start({hashChange: false, root: '/root/', silent: true});
strictEqual(Backbone.history.getFragment(), '');
});
test("#1366 - History does not prepend root to fragment.", 2, function() {
Backbone.history.stop();
location.replace('http://example.com/root/');
Backbone.history = _.extend(new Backbone.History, {
location: location,
history: {
pushState: function(state, title, url) {
strictEqual(url, '/root/x');
}
}
});
Backbone.history.start({
root: '/root/',
pushState: true,
hashChange: false
});
Backbone.history.navigate('x');
strictEqual(Backbone.history.fragment, 'x');
});
test("Normalize root.", 1, function() {
Backbone.history.stop();
location.replace('http://example.com/root');
Backbone.history = _.extend(new Backbone.History, {
location: location,
history: {
pushState: function(state, title, url) {
strictEqual(url, '/root/fragment');
}
}
});
Backbone.history.start({
pushState: true,
root: '/root',
hashChange: false
});
Backbone.history.navigate('fragment');
});
test("Normalize root.", 1, function() {
Backbone.history.stop();
location.replace('http://example.com/root#fragment');
Backbone.history = _.extend(new Backbone.History, {
location: location,
history: {
pushState: function(state, title, url) {},
replaceState: function(state, title, url) {
strictEqual(url, '/root/fragment');
}
}
});
Backbone.history.start({
pushState: true,
root: '/root'
});
});
test("Normalize root.", 1, function() {
Backbone.history.stop();
location.replace('http://example.com/root');
Backbone.history = _.extend(new Backbone.History, {location: location});
Backbone.history.loadUrl = function() { ok(true); };
Backbone.history.start({
pushState: true,
root: '/root'
});
});
test("Normalize root - leading slash.", 1, function() {
Backbone.history.stop();
location.replace('http://example.com/root');
Backbone.history = _.extend(new Backbone.History, {
location: location,
history: {
pushState: function(){},
replaceState: function(){}
}
});
Backbone.history.start({root: 'root'});
strictEqual(Backbone.history.root, '/root/');
});
test("Transition from hashChange to pushState.", 1, function() {
Backbone.history.stop();
location.replace('http://example.com/root#x/y');
Backbone.history = _.extend(new Backbone.History, {
location: location,
history: {
pushState: function(){},
replaceState: function(state, title, url){
strictEqual(url, '/root/x/y');
}
}
});
Backbone.history.start({
root: 'root',
pushState: true
});
});
test("#1619: Router: Normalize empty root", 1, function() {
Backbone.history.stop();
location.replace('http://example.com/');
Backbone.history = _.extend(new Backbone.History, {
location: location,
history: {
pushState: function(){},
replaceState: function(){}
}
});
Backbone.history.start({root: ''});
strictEqual(Backbone.history.root, '/');
});
test("#1619: Router: nagivate with empty root", 1, function() {
Backbone.history.stop();
location.replace('http://example.com/');
Backbone.history = _.extend(new Backbone.History, {
location: location,
history: {
pushState: function(state, title, url) {
strictEqual(url, '/fragment');
}
}
});
Backbone.history.start({
pushState: true,
root: '',
hashChange: false
});
Backbone.history.navigate('fragment');
});
test("Transition from pushState to hashChange.", 1, function() {
Backbone.history.stop();
location.replace('http://example.com/root/x/y?a=b');
location.replace = function(url) {
strictEqual(url, '/root/?a=b#x/y');
};
Backbone.history = _.extend(new Backbone.History, {
location: location,
history: {
pushState: null,
replaceState: null
}
});
Backbone.history.start({
root: 'root',
pushState: true
});
});
test("#1695 - hashChange to pushState with search.", 1, function() {
Backbone.history.stop();
location.replace('http://example.com/root?a=b#x/y');
Backbone.history = _.extend(new Backbone.History, {
location: location,
history: {
pushState: function(){},
replaceState: function(state, title, url){
strictEqual(url, '/root/x/y?a=b');
}
}
});
Backbone.history.start({
root: 'root',
pushState: true
});
});
test("#1746 - Router allows empty route.", 1, function() {
var Router = Backbone.Router.extend({
routes: {'': 'empty'},
empty: function(){},
route: function(route){
strictEqual(route, '');
}
});
new Router;
});
test("#1794 - Trailing space in fragments.", 1, function() {
var history = new Backbone.History;
strictEqual(history.getFragment('fragment '), 'fragment');
});
test("#1820 - Leading slash and trailing space.", 1, function() {
var history = new Backbone.History;
strictEqual(history.getFragment('/fragment '), 'fragment');
});
});

212
vendor/backbone/test/sync.js vendored Normal file
View File

@@ -0,0 +1,212 @@
$(document).ready(function() {
var Library = Backbone.Collection.extend({
url : function() { return '/library'; }
});
var library;
var attrs = {
title : "The Tempest",
author : "Bill Shakespeare",
length : 123
};
module("Backbone.sync", _.extend(new Environment, {
setup : function() {
Environment.prototype.setup.apply(this, arguments);
library = new Library;
library.create(attrs, {wait: false});
},
teardown: function() {
Environment.prototype.teardown.apply(this, arguments);
Backbone.emulateHTTP = false;
}
}));
test("read", 4, function() {
library.fetch();
equal(this.ajaxSettings.url, '/library');
equal(this.ajaxSettings.type, 'GET');
equal(this.ajaxSettings.dataType, 'json');
ok(_.isEmpty(this.ajaxSettings.data));
});
test("passing data", 3, function() {
library.fetch({data: {a: 'a', one: 1}});
equal(this.ajaxSettings.url, '/library');
equal(this.ajaxSettings.data.a, 'a');
equal(this.ajaxSettings.data.one, 1);
});
test("create", 6, function() {
equal(this.ajaxSettings.url, '/library');
equal(this.ajaxSettings.type, 'POST');
equal(this.ajaxSettings.dataType, 'json');
var data = JSON.parse(this.ajaxSettings.data);
equal(data.title, 'The Tempest');
equal(data.author, 'Bill Shakespeare');
equal(data.length, 123);
});
test("update", 7, function() {
library.first().save({id: '1-the-tempest', author: 'William Shakespeare'});
equal(this.ajaxSettings.url, '/library/1-the-tempest');
equal(this.ajaxSettings.type, 'PUT');
equal(this.ajaxSettings.dataType, 'json');
var data = JSON.parse(this.ajaxSettings.data);
equal(data.id, '1-the-tempest');
equal(data.title, 'The Tempest');
equal(data.author, 'William Shakespeare');
equal(data.length, 123);
});
test("update with emulateHTTP and emulateJSON", 7, function() {
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'}, {
emulateHTTP: true,
emulateJSON: true
});
equal(this.ajaxSettings.url, '/library/2-the-tempest');
equal(this.ajaxSettings.type, 'POST');
equal(this.ajaxSettings.dataType, 'json');
equal(this.ajaxSettings.data._method, 'PUT');
var data = JSON.parse(this.ajaxSettings.data.model);
equal(data.id, '2-the-tempest');
equal(data.author, 'Tim Shakespeare');
equal(data.length, 123);
});
test("update with just emulateHTTP", 6, function() {
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'}, {
emulateHTTP: true
});
equal(this.ajaxSettings.url, '/library/2-the-tempest');
equal(this.ajaxSettings.type, 'POST');
equal(this.ajaxSettings.contentType, 'application/json');
var data = JSON.parse(this.ajaxSettings.data);
equal(data.id, '2-the-tempest');
equal(data.author, 'Tim Shakespeare');
equal(data.length, 123);
});
test("update with just emulateJSON", 6, function() {
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'}, {
emulateJSON: true
});
equal(this.ajaxSettings.url, '/library/2-the-tempest');
equal(this.ajaxSettings.type, 'PUT');
equal(this.ajaxSettings.contentType, 'application/x-www-form-urlencoded');
var data = JSON.parse(this.ajaxSettings.data.model);
equal(data.id, '2-the-tempest');
equal(data.author, 'Tim Shakespeare');
equal(data.length, 123);
});
test("read model", 3, function() {
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
library.first().fetch();
equal(this.ajaxSettings.url, '/library/2-the-tempest');
equal(this.ajaxSettings.type, 'GET');
ok(_.isEmpty(this.ajaxSettings.data));
});
test("destroy", 3, function() {
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
library.first().destroy({wait: true});
equal(this.ajaxSettings.url, '/library/2-the-tempest');
equal(this.ajaxSettings.type, 'DELETE');
equal(this.ajaxSettings.data, null);
});
test("destroy with emulateHTTP", 3, function() {
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
library.first().destroy({
emulateHTTP: true,
emulateJSON: true
});
equal(this.ajaxSettings.url, '/library/2-the-tempest');
equal(this.ajaxSettings.type, 'POST');
equal(JSON.stringify(this.ajaxSettings.data), '{"_method":"DELETE"}');
});
test("urlError", 2, function() {
var model = new Backbone.Model();
raises(function() {
model.fetch();
});
model.fetch({url: '/one/two'});
equal(this.ajaxSettings.url, '/one/two');
});
test("#1052 - `options` is optional.", 0, function() {
var model = new Backbone.Model();
model.url = '/test';
Backbone.sync('create', model);
});
test("Backbone.ajax", 1, function() {
Backbone.ajax = function(settings){
strictEqual(settings.url, '/test');
};
var model = new Backbone.Model();
model.url = '/test';
Backbone.sync('create', model);
});
test("Call provided error callback on error.", 1, function() {
var model = new Backbone.Model;
model.url = '/test';
Backbone.sync('read', model, {
error: function() { ok(true); }
});
this.ajaxSettings.error();
});
test('Use Backbone.emulateHTTP as default.', 2, function() {
var model = new Backbone.Model;
model.url = '/test';
Backbone.emulateHTTP = true;
model.sync('create', model);
strictEqual(this.ajaxSettings.emulateHTTP, true);
Backbone.emulateHTTP = false;
model.sync('create', model);
strictEqual(this.ajaxSettings.emulateHTTP, false);
});
test('Use Backbone.emulateJSON as default.', 2, function() {
var model = new Backbone.Model;
model.url = '/test';
Backbone.emulateJSON = true;
model.sync('create', model);
strictEqual(this.ajaxSettings.emulateJSON, true);
Backbone.emulateJSON = false;
model.sync('create', model);
strictEqual(this.ajaxSettings.emulateJSON, false);
});
test("#1756 - Call user provided beforeSend function.", 4, function() {
Backbone.emulateHTTP = true;
var model = new Backbone.Model;
model.url = '/test';
var xhr = {
setRequestHeader: function(header, value) {
strictEqual(header, 'X-HTTP-Method-Override');
strictEqual(value, 'DELETE');
}
};
model.sync('delete', model, {
beforeSend: function(_xhr) {
ok(_xhr === xhr);
return false;
}
});
strictEqual(this.ajaxSettings.beforeSend(xhr), false);
});
});

382
vendor/backbone/test/view.js vendored Normal file
View File

@@ -0,0 +1,382 @@
$(document).ready(function() {
var view;
module("Backbone.View", {
setup: function() {
view = new Backbone.View({
id : 'test-view',
className : 'test-view',
other : 'non-special-option'
});
}
});
test("constructor", 6, function() {
equal(view.el.id, 'test-view');
equal(view.el.className, 'test-view');
equal(view.el.other, void 0);
equal(view.options.id, 'test-view');
equal(view.options.className, 'test-view');
equal(view.options.other, 'non-special-option');
});
test("jQuery", 1, function() {
var view = new Backbone.View;
view.setElement('<p><a><b>test</b></a></p>');
strictEqual(view.$('a b').html(), 'test');
});
test("make", 3, function() {
var div = view.make('div', {id: 'test-div'}, "one two three");
equal(div.tagName.toLowerCase(), 'div');
equal(div.id, 'test-div');
equal($(div).text(), 'one two three');
});
test("make can take falsy values for content", 2, function() {
var div = view.make('div', {id: 'test-div'}, 0);
equal($(div).text(), '0');
var div = view.make('div', {id: 'test-div'}, '');
equal($(div).text(), '');
});
test("initialize", 1, function() {
var View = Backbone.View.extend({
initialize: function() {
this.one = 1;
}
});
strictEqual(new View().one, 1);
});
test("delegateEvents", 6, function() {
var counter1 = 0, counter2 = 0;
var view = new Backbone.View({el: '<p><a id="test"></a></p>'});
view.increment = function(){ counter1++; };
view.$el.on('click', function(){ counter2++; });
var events = {'click #test': 'increment'};
view.delegateEvents(events);
view.$('#test').trigger('click');
equal(counter1, 1);
equal(counter2, 1);
view.$('#test').trigger('click');
equal(counter1, 2);
equal(counter2, 2);
view.delegateEvents(events);
view.$('#test').trigger('click');
equal(counter1, 3);
equal(counter2, 3);
});
test("delegateEvents allows functions for callbacks", 3, function() {
var view = new Backbone.View({el: '<p></p>'});
view.counter = 0;
var events = {
click: function() {
this.counter++;
}
};
view.delegateEvents(events);
view.$el.trigger('click');
equal(view.counter, 1);
view.$el.trigger('click');
equal(view.counter, 2);
view.delegateEvents(events);
view.$el.trigger('click');
equal(view.counter, 3);
});
test("undelegateEvents", 6, function() {
var counter1 = 0, counter2 = 0;
var view = new Backbone.View({el: '<p><a id="test"></a></p>'});
view.increment = function(){ counter1++; };
view.$el.on('click', function(){ counter2++; });
var events = {'click #test': 'increment'};
view.delegateEvents(events);
view.$('#test').trigger('click');
equal(counter1, 1);
equal(counter2, 1);
view.undelegateEvents();
view.$('#test').trigger('click');
equal(counter1, 1);
equal(counter2, 2);
view.delegateEvents(events);
view.$('#test').trigger('click');
equal(counter1, 2);
equal(counter2, 3);
});
test("_ensureElement with DOM node el", 1, function() {
var View = Backbone.View.extend({
el: document.body
});
equal(new View().el, document.body);
});
test("_ensureElement with string el", 3, function() {
var View = Backbone.View.extend({
el: "body"
});
strictEqual(new View().el, document.body);
View = Backbone.View.extend({
el: "#testElement > h1"
});
strictEqual(new View().el, $("#testElement > h1").get(0));
View = Backbone.View.extend({
el: "#nonexistent"
});
ok(!new View().el);
});
test("with className and id functions", 2, function() {
var View = Backbone.View.extend({
className: function() {
return 'className';
},
id: function() {
return 'id';
}
});
strictEqual(new View().el.className, 'className');
strictEqual(new View().el.id, 'id');
});
test("with options function", 3, function() {
var View1 = Backbone.View.extend({
options: function() {
return {
title: 'title1',
acceptText: 'confirm'
}
}
});
var View2 = View1.extend({
options: function() {
return _.extend(View1.prototype.options.call(this), {
title: 'title2',
fixed: true
});
}
});
strictEqual(new View2().options.title, 'title2');
strictEqual(new View2().options.acceptText, 'confirm');
strictEqual(new View2().options.fixed, true);
});
test("with attributes", 2, function() {
var View = Backbone.View.extend({
attributes: {
id: 'id',
'class': 'class'
}
});
strictEqual(new View().el.className, 'class');
strictEqual(new View().el.id, 'id');
});
test("with attributes as a function", 1, function() {
var View = Backbone.View.extend({
attributes: function() {
return {'class': 'dynamic'};
}
});
strictEqual(new View().el.className, 'dynamic');
});
test("multiple views per element", 3, function() {
var count = 0;
var $el = $('<p></p>');
var View = Backbone.View.extend({
el: $el,
events: {
click: function() {
count++;
}
}
});
var view1 = new View;
$el.trigger("click");
equal(1, count);
var view2 = new View;
$el.trigger("click");
equal(3, count);
view1.delegateEvents();
$el.trigger("click");
equal(5, count);
});
test("custom events, with namespaces", 2, function() {
var count = 0;
var View = Backbone.View.extend({
el: $('body'),
events: function() {
return {"fake$event.namespaced": "run"};
},
run: function() {
count++;
}
});
var view = new View;
$('body').trigger('fake$event').trigger('fake$event');
equal(count, 2);
$('body').unbind('.namespaced');
$('body').trigger('fake$event');
equal(count, 2);
});
test("#1048 - setElement uses provided object.", 2, function() {
var $el = $('body');
var view = new Backbone.View({el: $el});
ok(view.$el === $el);
view.setElement($el = $($el));
ok(view.$el === $el);
});
test("#986 - Undelegate before changing element.", 1, function() {
var button1 = $('<button></button>');
var button2 = $('<button></button>');
var View = Backbone.View.extend({
events: {
click: function(e) {
ok(view.el === e.target);
}
}
});
var view = new View({el: button1});
view.setElement(button2);
button1.trigger('click');
button2.trigger('click');
});
test("#1172 - Clone attributes object", 2, function() {
var View = Backbone.View.extend({
attributes: {foo: 'bar'}
});
var view1 = new View({id: 'foo'});
strictEqual(view1.el.id, 'foo');
var view2 = new View();
ok(!view2.el.id);
});
test("#1228 - tagName can be provided as a function", 1, function() {
var View = Backbone.View.extend({
tagName: function() {
return 'p';
}
});
ok(new View().$el.is('p'));
});
test("dispose", 0, function() {
var View = Backbone.View.extend({
events: {
click: function() { ok(false); }
},
initialize: function() {
this.model.on('all x', function(){ ok(false); }, this);
this.collection.on('all x', function(){ ok(false); }, this);
}
});
var view = new View({
model: new Backbone.Model,
collection: new Backbone.Collection
});
view.dispose();
view.model.trigger('x');
view.collection.trigger('x');
view.$el.click();
});
test("dispose with non Backbone objects", 0, function() {
var view = new Backbone.View({model: {}, collection: {}});
view.dispose();
});
test("view#remove calls dispose.", 1, function() {
var view = new Backbone.View();
view.dispose = function() { ok(true); };
view.remove();
});
test("Provide function for el.", 1, function() {
var View = Backbone.View.extend({
el: function() {
return "<p><a></a></p>";
}
});
var view = new View;
ok(view.$el.is('p:has(a)'));
});
test("events passed in options", 2, function() {
var counter = 0;
var View = Backbone.View.extend({
el: '<p><a id="test"></a></p>',
increment: function() {
counter++;
}
});
var view = new View({events:{'click #test':'increment'}});
var view2 = new View({events:function(){
return {'click #test':'increment'};
}});
view.$('#test').trigger('click');
view2.$('#test').trigger('click');
equal(counter, 2);
view.$('#test').trigger('click');
view2.$('#test').trigger('click');
equal(counter, 4);
});
});

1
vendor/benchmark.js vendored

Submodule vendor/benchmark.js deleted from f0306c0345

22
vendor/benchmark.js/LICENSE.txt vendored Normal file
View File

@@ -0,0 +1,22 @@
Copyright 2010-2012 Mathias Bynens <http://mathiasbynens.be/>
Based on JSLitmus.js, copyright Robert Kieffer <http://broofa.com/>
Modified by John-David Dalton <http://allyoucanleet.com/>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

136
vendor/benchmark.js/README.md vendored Normal file
View File

@@ -0,0 +1,136 @@
# Benchmark.js <sup>v1.0.0</sup>
[![build status](https://secure.travis-ci.org/bestiejs/benchmark.js.png)](http://travis-ci.org/bestiejs/benchmark.js)
A [robust](http://calendar.perfplanet.com/2010/bulletproof-javascript-benchmarks/ "Bulletproof JavaScript benchmarks") benchmarking library that works on nearly all JavaScript platforms<sup><a name="fnref1" href="#fn1">1</a></sup>, supports high-resolution timers, and returns statistically significant results. As seen on [jsPerf](http://jsperf.com/).
## Download
* [Development source](https://raw.github.com/bestiejs/benchmark.js/v1.0.0/benchmark.js)
## Dive in
Weve got [API docs](http://benchmarkjs.com/docs) and [unit tests](http://benchmarkjs.com/tests).
For a list of upcoming features, check out our [roadmap](https://github.com/bestiejs/benchmark.js/wiki/Roadmap).
## Support
Benchmark.js has been tested in at least Adobe AIR 3.1, Chrome 5-21, Firefox 1-15, IE 6-9, Opera 9.25-12, Safari 3-6, Node.js 0.8.8, Narwhal 0.3.2, RingoJS 0.8, and Rhino 1.7RC5.
## Installation and usage
In a browser or Adobe AIR:
```html
<script src="benchmark.js"></script>
```
Optionally, expose Javas nanosecond timer by adding the `nano` applet to the `<body>`:
```html
<applet code="nano" archive="nano.jar"></applet>
```
Or enable Chromes microsecond timer by using the [command line switch](http://peter.sh/experiments/chromium-command-line-switches/#enable-benchmarking):
--enable-benchmarking
Via [npm](http://npmjs.org/):
```bash
npm install benchmark
```
In [Node.js](http://nodejs.org/) and [RingoJS v0.8.0+](http://ringojs.org/):
```js
var Benchmark = require('benchmark');
```
Optionally, use the [microtime module](https://github.com/wadey/node-microtime) by Wade Simmons:
```bash
npm install microtime
```
In [RingoJS v0.7.0-](http://ringojs.org/):
```js
var Benchmark = require('benchmark').Benchmark;
```
In [Rhino](http://www.mozilla.org/rhino/):
```js
load('benchmark.js');
```
In an AMD loader like [RequireJS](http://requirejs.org/):
```js
require({
'paths': {
'benchmark': 'path/to/benchmark'
}
},
['benchmark'], function(Benchmark) {
console.log(Benchmark.version);
});
// or with platform.js
// https://github.com/bestiejs/platform.js
require({
'paths': {
'benchmark': 'path/to/benchmark',
'platform': 'path/to/platform'
}
},
['benchmark', 'platform'], function(Benchmark, platform) {
Benchmark.platform = platform;
console.log(Benchmark.platform.name);
});
```
Usage example:
```js
var suite = new Benchmark.Suite;
// add tests
suite.add('RegExp#test', function() {
/o/.test('Hello World!');
})
.add('String#indexOf', function() {
'Hello World!'.indexOf('o') > -1;
})
// add listeners
.on('cycle', function(event) {
console.log(String(event.target));
})
.on('complete', function() {
console.log('Fastest is ' + this.filter('fastest').pluck('name'));
})
// run async
.run({ 'async': true });
// logs:
// > RegExp#test x 4,161,532 +-0.99% (59 cycles)
// > String#indexOf x 6,139,623 +-1.00% (131 cycles)
// > Fastest is String#indexOf
```
## BestieJS
Benchmark.js is part of the BestieJS *"Best in Class"* module collection. This means we promote solid browser/environment support, ES5 precedents, unit testing, and plenty of documentation.
## Authors
* [Mathias Bynens](http://mathiasbynens.be/)
[![twitter/mathias](http://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](https://twitter.com/mathias "Follow @mathias on Twitter")
* [John-David Dalton](http://allyoucanleet.com/)
[![twitter/jdalton](http://gravatar.com/avatar/299a3d891ff1920b69c364d061007043?s=70)](https://twitter.com/jdalton "Follow @jdalton on Twitter")
## Contributors
* [Kit Cambridge](http://kitcambridge.github.com/)
[![twitter/kitcambridge](http://gravatar.com/avatar/6662a1d02f351b5ef2f8b4d815804661?s=70)](https://twitter.com/kitcambridge "Follow @kitcambridge on Twitter")

3954
vendor/benchmark.js/benchmark.js vendored Normal file

File diff suppressed because it is too large Load Diff

BIN
vendor/benchmark.js/nano.jar vendored Normal file

Binary file not shown.

1
vendor/docdown vendored

Submodule vendor/docdown deleted from 87466c279a

20
vendor/docdown/LICENSE.txt vendored Normal file
View File

@@ -0,0 +1,20 @@
Copyright 2011-2012 John-David Dalton <http://allyoucanleet.com/>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

33
vendor/docdown/README.md vendored Normal file
View File

@@ -0,0 +1,33 @@
# Docdown <sup>v1.0.0</sup>
A simple JSDoc to Markdown documentation generator.
## Documentation
The documentation for Docdown can be viewed here: [/doc/README.md](https://github.com/jdalton/docdown/blob/master/doc/README.md#readme)
For a list of upcoming features, check out our [roadmap](https://github.com/jdalton/docdown/wiki/Roadmap).
## Installation and usage
Usage example:
```php
require("docdown.php");
// generate Markdown
$markdown = docdown(array(
"path" => $filepath,
"url" => "https://github.com/username/project/blob/master/my.js"
));
```
## Author
* [John-David Dalton](http://allyoucanleet.com/)
[![twitter/jdalton](http://gravatar.com/avatar/299a3d891ff1920b69c364d061007043?s=70)](https://twitter.com/jdalton "Follow @jdalton on Twitter")
## Contributors
* [Mathias Bynens](http://mathiasbynens.be/)
[![twitter/mathias](http://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](https://twitter.com/mathias "Follow @mathias on Twitter")

38
vendor/docdown/docdown.php vendored Normal file
View File

@@ -0,0 +1,38 @@
<?php
/*!
* Docdown v1.0.0-pre
* Copyright 2011-2012 John-David Dalton <http://allyoucanleet.com/>
* Available under MIT license <http://mths.be/mit>
*/
require(dirname(__FILE__) . '/src/DocDown/Generator.php');
/**
* Generates Markdown from JSDoc entries in a given file.
*
* @param {Array} [$options=array()] The options array.
* @returns {String} The generated Markdown.
* @example
*
* // specify a file path
* $markdown = docdown(array(
* // path to js file
* 'path' => $filepath,
* // url used to reference line numbers in code
* 'url' => 'https://github.com/username/project/blob/master/my.js'
* ));
*
* // or pass raw js
* $markdown = docdown(array(
* // raw JavaScript source
* 'source' => $rawJS,
* // documentation title
* 'title' => 'My API Documentation',
* // url used to reference line numbers in code
* 'url' => 'https://github.com/username/project/blob/master/my.js'
* ));
*/
function docdown( $options = array() ) {
$gen = new Generator($options);
return $gen->generate();
}
?>

215
vendor/docdown/src/DocDown/Alias.php vendored Normal file
View File

@@ -0,0 +1,215 @@
<?php
/**
* A class to represent a JSDoc entry alias.
*/
class Alias {
/**
* The alias owner.
*
* @memberOf Alias
* @type Object
*/
public $owner;
/*--------------------------------------------------------------------------*/
/**
* The Alias constructor.
*
* @constructor
* @param {String} $name The alias name.
* @param {Object} $owner The alias owner.
*/
public function __construct( $name, $owner ) {
$this->owner = $owner;
$this->_name = $name;
$this->_call = $owner->getCall();
$this->_category = $owner->getCategory();
$this->_desc = $owner->getDesc();
$this->_example = $owner->getExample();
$this->_lineNumber = $owner->getLineNumber();
$this->_members = $owner->getMembers();
$this->_params = $owner->getParams();
$this->_returns = $owner->getReturns();
$this->_type = $owner->getType();
$this->_isCtor = $owner->isCtor();
$this->_isPlugin = $owner->isPlugin();
$this->_isPrivate = $owner->isPrivate();
$this->_isStatic = $owner->isStatic();
}
/*--------------------------------------------------------------------------*/
/**
* Extracts the entry's `alias` objects.
*
* @memberOf Alias
* @param {Number} $index The index of the array value to return.
* @returns {Array|String} The entry's `alias` objects.
*/
public function getAliases( $index = null ) {
$result = array();
return $index !== null
? @$result[$index]
: $result;
}
/**
* Extracts the function call from the owner entry.
*
* @memberOf Alias
* @returns {String} The function call.
*/
public function getCall() {
return $this->_call;
}
/**
* Extracts the owner entry's `category` data.
*
* @memberOf Alias
* @returns {String} The owner entry's `category` data.
*/
public function getCategory() {
return $this->_category;
}
/**
* Extracts the owner entry's description.
*
* @memberOf Alias
* @returns {String} The owner entry's description.
*/
public function getDesc() {
return $this->_desc;
}
/**
* Extracts the owner entry's `example` data.
*
* @memberOf Alias
* @returns {String} The owner entry's `example` data.
*/
public function getExample() {
return $this->_example;
}
/**
* Resolves the owner entry's line number.
*
* @memberOf Alias
* @returns {Number} The owner entry's line number.
*/
public function getLineNumber() {
return $this->_lineNumber;
}
/**
* Extracts the owner entry's `member` data.
*
* @memberOf Alias
* @param {Number} $index The index of the array value to return.
* @returns {Array|String} The owner entry's `member` data.
*/
public function getMembers( $index = null ) {
return $index !== null
? @$this->_members[$index]
: $this->_members;
}
/**
* Extracts the owner entry's `name` data.
*
* @memberOf Alias
* @returns {String} The owner entry's `name` data.
*/
public function getName() {
return $this->_name;
}
/**
* Extracts the owner entry's `param` data.
*
* @memberOf Alias
* @param {Number} $index The index of the array value to return.
* @returns {Array} The owner entry's `param` data.
*/
public function getParams( $index = null ) {
return $index !== null
? @$this->_params[$index]
: $this->_params;
}
/**
* Extracts the owner entry's `returns` data.
*
* @memberOf Alias
* @returns {String} The owner entry's `returns` data.
*/
public function getReturns() {
return $this->_returns;
}
/**
* Extracts the owner entry's `type` data.
*
* @memberOf Alias
* @returns {String} The owner entry's `type` data.
*/
public function getType() {
return $this->_type;
}
/**
* Checks if the entry is an alias.
*
* @memberOf Alias
* @returns {Boolean} Returns `true`.
*/
public function isAlias() {
return true;
}
/**
* Checks if the owner entry is a constructor.
*
* @memberOf Alias
* @returns {Boolean} Returns `true` if a constructor, else `false`.
*/
public function isCtor() {
return $this->_isCtor;
}
/**
* Checks if the owner entry *is* assigned to a prototype.
*
* @memberOf Alias
* @returns {Boolean} Returns `true` if assigned to a prototype, else `false`.
*/
public function isPlugin() {
return $this->_isPlugin;
}
/**
* Checks if the owner entry is private.
*
* @memberOf Alias
* @returns {Boolean} Returns `true` if private, else `false`.
*/
public function isPrivate() {
return $this->_isPrivate;
}
/**
* Checks if the owner entry is *not* assigned to a prototype.
*
* @memberOf Alias
* @returns {Boolean} Returns `true` if not assigned to a prototype, else `false`.
*/
public function isStatic() {
return $this->_isStatic;
}
}
?>

426
vendor/docdown/src/DocDown/Entry.php vendored Normal file
View File

@@ -0,0 +1,426 @@
<?php
require(dirname(__FILE__) . "/Alias.php");
/**
* A class to simplify parsing a single JSDoc entry.
*/
class Entry {
/**
* The documentation entry.
*
* @memberOf Entry
* @type String
*/
public $entry = '';
/**
* The language highlighter used for code examples.
*
* @memberOf Entry
* @type String
*/
public $lang = '';
/**
* The source code.
*
* @memberOf Entry
* @type String
*/
public $source = '';
/*--------------------------------------------------------------------------*/
/**
* The Entry constructor.
*
* @constructor
* @param {String} $entry The documentation entry to analyse.
* @param {String} $source The source code.
* @param {String} [$lang ='js'] The language highlighter used for code examples.
*/
public function __construct( $entry, $source, $lang = 'js' ) {
$this->entry = $entry;
$this->lang = $lang;
$this->source = str_replace(PHP_EOL, "\n", $source);
}
/*--------------------------------------------------------------------------*/
/**
* Extracts the documentation entries from source code.
*
* @static
* @memberOf Entry
* @param {String} $source The source code.
* @returns {Array} The array of entries.
*/
public static function getEntries( $source ) {
preg_match_all('#/\*\*(?![-!])[\s\S]*?\*/\s*[^\n]+#', $source, $result);
return array_pop($result);
}
/*--------------------------------------------------------------------------*/
/**
* Checks if the entry is a function reference.
*
* @private
* @memberOf Entry
* @returns {Boolean} Returns `true` if the entry is a function reference, else `false`.
*/
private function isFunction() {
if (!isset($this->_isFunction)) {
$this->_isFunction = !!(
$this->isCtor() ||
count($this->getParams()) ||
count($this->getReturns()) ||
preg_match('/\* *@function\b/', $this->entry)
);
}
return $this->_isFunction;
}
/*--------------------------------------------------------------------------*/
/**
* Extracts the entry's `alias` objects.
*
* @memberOf Entry
* @param {Number} $index The index of the array value to return.
* @returns {Array|String} The entry's `alias` objects.
*/
public function getAliases( $index = null ) {
if (!isset($this->_aliases)) {
preg_match('#\* *@alias\s+([^\n]+)#', $this->entry, $result);
if (count($result)) {
$result = trim(preg_replace('/(?:^|\n)\s*\* ?/', ' ', $result[1]));
$result = preg_split('/,\s*/', $result);
natsort($result);
foreach ($result as $resultIndex => $value) {
$result[$resultIndex] = new Alias($value, $this);
}
}
$this->_aliases = $result;
}
return $index !== null
? @$this->_aliases[$index]
: $this->_aliases;
}
/**
* Extracts the function call from the entry.
*
* @memberOf Entry
* @returns {String} The function call.
*/
public function getCall() {
if (isset($this->_call)) {
return $this->_call;
}
preg_match('#\*/\s*(?:function ([^(]*)|(.*?)(?=[:=,]|return\b))#', $this->entry, $result);
if ($result = array_pop($result)) {
$result = array_pop(explode('var ', trim(trim(array_pop(explode('.', $result))), "'")));
}
// resolve name
// avoid $this->getName() because it calls $this->getCall()
preg_match('#\* *@name\s+([^\n]+)#', $this->entry, $name);
if (count($name)) {
$name = trim($name[1]);
} else {
$name = $result;
}
// compile function call syntax
if ($this->isFunction()) {
// compose parts
$result = array($result);
$params = $this->getParams();
foreach ($params as $param) {
$result[] = $param[1];
}
// format
$result = $name .'('. implode(array_slice($result, 1), ', ') .')';
$result = str_replace(', [', ' [, ', str_replace('], [', ', ', $result));
}
$this->_call = $result ? $result : $name;
return $this->_call;
}
/**
* Extracts the entry's `category` data.
*
* @memberOf Entry
* @returns {String} The entry's `category` data.
*/
public function getCategory() {
if (isset($this->_category)) {
return $this->_category;
}
preg_match('#\* *@category\s+([^\n]+)#', $this->entry, $result);
if (count($result)) {
$result = trim(preg_replace('/(?:^|\n)\s*\* ?/', ' ', $result[1]));
} else {
$result = $this->getType() == 'Function' ? 'Methods' : 'Properties';
}
$this->_category = $result;
return $result;
}
/**
* Extracts the entry's description.
*
* @memberOf Entry
* @returns {String} The entry's description.
*/
public function getDesc() {
if (isset($this->_desc)) {
return $this->_desc;
}
preg_match('#/\*\*(?:\s*\*)?([\s\S]*?)(?=\*\s\@[a-z]|\*/)#', $this->entry, $result);
if (count($result)) {
$type = $this->getType();
$result = trim(preg_replace('/(?:^|\n)\s*\* ?/', ' ', $result[1]));
$result = ($type == 'Function' ? '' : '(' . str_replace('|', ', ', trim($type, '{}')) . '): ') . $result;
}
$this->_desc = $result;
return $result;
}
/**
* Extracts the entry's `example` data.
*
* @memberOf Entry
* @returns {String} The entry's `example` data.
*/
public function getExample() {
if (isset($this->_example)) {
return $this->_example;
}
preg_match('#\* *@example\s+([\s\S]*?)(?=\*\s\@[a-z]|\*/)#', $this->entry, $result);
if (count($result)) {
$result = trim(preg_replace('/(?:^|\n)\s*\* ?/', "\n", $result[1]));
$result = '```' . $this->lang . "\n" . $result . "\n```";
}
$this->_example = $result;
return $result;
}
/**
* Resolves the entry's line number.
*
* @memberOf Entry
* @returns {Number} The entry's line number.
*/
public function getLineNumber() {
if (!isset($this->_lineNumber)) {
preg_match_all('/\n/', substr($this->source, 0, strrpos($this->source, $this->entry) + strlen($this->entry)), $lines);
$this->_lineNumber = count(array_pop($lines)) + 1;
}
return $this->_lineNumber;
}
/**
* Extracts the entry's `member` data.
*
* @memberOf Entry
* @param {Number} $index The index of the array value to return.
* @returns {Array|String} The entry's `member` data.
*/
public function getMembers( $index = null ) {
if (!isset($this->_members)) {
preg_match('#\* *@member(?:Of)?\s+([^\n]+)#', $this->entry, $result);
if (count($result)) {
$result = trim(preg_replace('/(?:^|\n)\s*\* ?/', ' ', $result[1]));
$result = preg_split('/,\s*/', $result);
natsort($result);
}
$this->_members = $result;
}
return $index !== null
? @$this->_members[$index]
: $this->_members;
}
/**
* Extracts the entry's `name` data.
*
* @memberOf Entry
* @returns {String} The entry's `name` data.
*/
public function getName() {
if (isset($this->_name)) {
return $this->_name;
}
preg_match('#\* *@name\s+([^\n]+)#', $this->entry, $result);
if (count($result)) {
$result = trim(preg_replace('/(?:^|\n)\s*\* ?/', ' ', $result[1]));
} else {
$result = array_shift(explode('(', $this->getCall()));
}
$this->_name = $result;
return $result;
}
/**
* Extracts the entry's `param` data.
*
* @memberOf Entry
* @param {Number} $index The index of the array value to return.
* @returns {Array} The entry's `param` data.
*/
public function getParams( $index = null ) {
if (!isset($this->_params)) {
preg_match_all('#\* *@param\s+\{([^}]+)\}\s+(\[.+\]|[$\w|]+(?:\[.+\])?)\s+([\s\S]*?)(?=\*\s\@[a-z]|\*/)#i', $this->entry, $result);
if (count($result = array_filter(array_slice($result, 1)))) {
// repurpose array
foreach ($result as $param) {
foreach ($param as $key => $value) {
if (!is_array($result[0][$key])) {
$result[0][$key] = array();
}
$result[0][$key][] = trim(preg_replace('/(?:^|\n)\s*\* */', ' ', $value));
}
}
$result = $result[0];
}
$this->_params = $result;
}
return $index !== null
? @$this->_params[$index]
: $this->_params;
}
/**
* Extracts the entry's `returns` data.
*
* @memberOf Entry
* @returns {String} The entry's `returns` data.
*/
public function getReturns() {
if (isset($this->_returns)) {
return $this->_returns;
}
preg_match('#\* *@returns\s+\{([^}]+)\}\s+([\s\S]*?)(?=\*\s\@[a-z]|\*/)#', $this->entry, $result);
if (count($result)) {
$result = array_map('trim', array_slice($result, 1));
$result[0] = str_replace('|', ', ', $result[0]);
$result[1] = preg_replace('/(?:^|\n)\s*\* ?/', ' ', $result[1]);
}
$this->_returns = $result;
return $result;
}
/**
* Extracts the entry's `type` data.
*
* @memberOf Entry
* @returns {String} The entry's `type` data.
*/
public function getType() {
if (isset($this->_type)) {
return $this->_type;
}
preg_match('#\* *@type\s+([^\n]+)#', $this->entry, $result);
if (count($result)) {
$result = trim(preg_replace('/(?:^|\n)\s*\* ?/', ' ', $result[1]));
} else {
$result = $this->isFunction() ? 'Function' : 'Unknown';
}
$this->_type = $result;
return $result;
}
/**
* Checks if the entry is an alias.
*
* @memberOf Entry
* @returns {Boolean} Returns `false`.
*/
public function isAlias() {
return false;
}
/**
* Checks if the entry is a constructor.
*
* @memberOf Entry
* @returns {Boolean} Returns `true` if a constructor, else `false`.
*/
public function isCtor() {
if (!isset($this->_isCtor)) {
$this->_isCtor = !!preg_match('/\* *@constructor\b/', $this->entry);
}
return $this->_isCtor;
}
/**
* Checks if the entry *is* assigned to a prototype.
*
* @memberOf Entry
* @returns {Boolean} Returns `true` if assigned to a prototype, else `false`.
*/
public function isPlugin() {
if (!isset($this->_isPlugin)) {
$this->_isPlugin = !$this->isCtor() && !$this->isPrivate() && !$this->isStatic();
}
return $this->_isPlugin;
}
/**
* Checks if the entry is private.
*
* @memberOf Entry
* @returns {Boolean} Returns `true` if private, else `false`.
*/
public function isPrivate() {
if (!isset($this->_isPrivate)) {
$this->_isPrivate = !!preg_match('/\* *@private\b/', $this->entry) || !preg_match('/\* *@[a-z]+\b/', $this->entry);
}
return $this->_isPrivate;
}
/**
* Checks if the entry is *not* assigned to a prototype.
*
* @memberOf Entry
* @returns {Boolean} Returns `true` if not assigned to a prototype, else `false`.
*/
public function isStatic() {
if (isset($this->_isStatic)) {
return $this->_isStatic;
}
$public = !$this->isPrivate();
$result = $public && !!preg_match('/\* *@static\b/', $this->entry);
// set in cases where it isn't explicitly stated
if ($public && !$result) {
if ($parent = array_pop(preg_split('/[#.]/', $this->getMembers(0)))) {
foreach (Entry::getEntries($this->source) as $entry) {
$entry = new Entry($entry, $this->source);
if ($entry->getName() == $parent) {
$result = !$entry->isCtor();
break;
}
}
} else {
$result = true;
}
}
$this->_isStatic = $result;
return $result;
}
}
?>

565
vendor/docdown/src/DocDown/Generator.php vendored Normal file
View File

@@ -0,0 +1,565 @@
<?php
require(dirname(__FILE__) . "/Entry.php");
/**
* Generates Markdown from JSDoc entries.
*/
class Generator {
/**
* The HTML for the close tag.
*
* @static
* @memberOf Generator
* @type String
*/
public $closeTag = "\n<!-- /div -->\n";
/**
* An array of JSDoc entries.
*
* @memberOf Generator
* @type Array
*/
public $entries = array();
/**
* The HTML for the open tag.
*
* @static
* @memberOf Generator
* @type String
*/
public $openTag = "\n<!-- div -->\n";
/**
* An options array used to configure the generator.
*
* @memberOf Generator
* @type Array
*/
public $options = array();
/**
* The file's source code.
*
* @memberOf Generator
* @type String
*/
public $source = '';
/*--------------------------------------------------------------------------*/
/**
* The Generator constructor.
*
* @constructor
* @param {String} $source The source code to parse.
* @param {Array} $options The options array.
*/
public function __construct( $source, $options = array() ) {
// juggle arguments
if (is_array($source)) {
$options = $source;
} else {
$options['source'] = $source;
}
if (isset($options['source']) && realpath($options['source'])) {
$options['path'] = $options['source'];
}
if (isset($options['path'])) {
preg_match('/(?<=\.)[a-z]+$/', $options['path'], $ext);
$options['source'] = file_get_contents($options['path']);
$ext = array_pop($ext);
if (!isset($options['lang']) && $ext) {
$options['lang'] = $ext;
}
if (!isset($options['title'])) {
$options['title'] = ucfirst(basename($options['path'])) . ' API documentation';
}
}
if (!isset($options['lang'])) {
$options['lang'] = 'js';
}
if (!isset($options['toc'])) {
$options['toc'] = 'properties';
}
$this->options = $options;
$this->source = str_replace(PHP_EOL, "\n", $options['source']);
$this->entries = Entry::getEntries($this->source);
foreach ($this->entries as $index => $value) {
$this->entries[$index] = new Entry($value, $this->source, $options['lang']);
}
}
/*--------------------------------------------------------------------------*/
/**
* Performs common string formatting operations.
*
* @private
* @static
* @memberOf Generator
* @param {String} $string The string to format.
* @returns {String} The formatted string.
*/
private static function format( $string ) {
$counter = 0;
// tokenize inline code snippets
preg_match_all('/`[^`]+`/', $string, $tokenized);
$tokenized = $tokenized[0];
foreach ($tokenized as $snippet) {
$string = str_replace($snippet, '__token' . ($counter++) .'__', $string);
}
// italicize parentheses
$string = preg_replace('/(^|\s)(\([^)]+\))/', '$1*$2*', $string);
// mark numbers as inline code
$string = preg_replace('/ (-?\d+(?:.\d+)?)(?!\.[^\n])/', ' `$1`', $string);
// detokenize inline code snippets
$counter = 0;
foreach ($tokenized as $snippet) {
$string = str_replace('__token' . ($counter++) . '__', $snippet, $string);
}
return trim($string);
}
/**
* Modify a string by replacing named tokens with matching assoc. array values.
*
* @private
* @static
* @memberOf Generator
* @param {String} $string The string to modify.
* @param {Array|Object} $object The template object.
* @returns {String} The modified string.
*/
private static function interpolate( $string, $object ) {
preg_match_all('/#\{([^}]+)\}/', $string, $tokens);
$tokens = array_unique(array_pop($tokens));
foreach ($tokens as $token) {
$pattern = '/#\{' . $token . '\}/';
$replacement = '';
if (is_object($object)) {
preg_match('/\(([^)]+?)\)$/', $token, $args);
$args = preg_split('/,\s*/', array_pop($args));
$method = 'get' . ucfirst(str_replace('/\([^)]+?\)$/', '', $token));
if (method_exists($object, $method)) {
$replacement = (string) call_user_func_array(array($object, $method), $args);
} else if (isset($object->{$token})) {
$replacement = (string) $object->{$token};
}
} else if (isset($object[$token])) {
$replacement = (string) $object[$token];
}
$string = preg_replace($pattern, trim($replacement), $string);
}
return Generator::format($string);
}
/*--------------------------------------------------------------------------*/
/**
* Adds the given `$entries` to the `$result` array.
*
* @private
* @memberOf Generator
* @param {Array} $result The result array to modify.
* @param {Array} $entries The entries to add to the `$result`.
*/
private function addEntries( &$result, $entries ) {
foreach ($entries as $entry) {
// skip aliases
if ($entry->isAlias()) {
continue;
}
// name and description
array_push(
$result,
$this->openTag,
Generator::interpolate("### <a id=\"#{hash}\"></a>`#{member}#{separator}#{call}`\n<a href=\"##{hash}\">#</a> [&#x24C8;](#{href} \"View in source\") [&#x24C9;][1]\n\n#{desc}", $entry)
);
// @alias
if (count($aliases = $entry->getAliases())) {
array_push($result, '', '#### Aliases');
foreach ($aliases as $index => $alias) {
$aliases[$index] = $alias->getName();
}
$result[] = '*' . implode(', ', $aliases) . '*';
}
// @param
if (count($params = $entry->getParams())) {
array_push($result, '', '#### Arguments');
foreach ($params as $index => $param) {
$result[] = Generator::interpolate('#{num}. `#{name}` (#{type}): #{desc}', array(
'desc' => $param[2],
'name' => $param[1],
'num' => $index + 1,
'type' => $param[0]
));
}
}
// @returns
if (count($returns = $entry->getReturns())) {
array_push(
$result, '',
'#### Returns',
Generator::interpolate('(#{type}): #{desc}', array('desc' => $returns[1], 'type' => $returns[0]))
);
}
// @example
if ($example = $entry->getExample()) {
array_push($result, '', '#### Example', $example);
}
array_push($result, "\n* * *", $this->closeTag);
}
}
/**
* Resolves the entry's hash used to navigate the documentation.
*
* @private
* @memberOf Generator
* @param {Number|Object} $entry The entry object.
* @param {String} $member The name of the member.
* @returns {String} The url hash.
*/
private function getHash( $entry, $member = '' ) {
$entry = is_numeric($entry) ? $this->entries[$entry] : $entry;
$member = !$member ? $entry->getMembers(0) : $member;
$result = ($member ? $member . ($entry->isPlugin() ? 'prototype' : '') : '') . $entry->getCall();
$result = preg_replace('/\(\[|\[\]/', '', $result);
$result = preg_replace('/[ =|\'"{}.()\]]/', '', $result);
$result = preg_replace('/[[#,]/', '-', $result);
return strtolower($result);
}
/**
* Resolves the entry's url for the specific line number.
*
* @private
* @memberOf Generator
* @param {Number|Object} $entry The entry object.
* @returns {String} The url.
*/
private function getLineUrl( $entry ) {
$entry = is_numeric($entry) ? $this->entries($entry) : $entry;
return $this->options['url'] . '#L' . $entry->getLineNumber();
}
/**
* Extracts the character used to separate the entry's name from its member.
*
* @private
* @memberOf Generator
* @param {Number|Object} $entry The entry object.
* @returns {String} The separator.
*/
private function getSeparator( $entry ) {
$entry = is_numeric($entry) ? $this->entries($entry) : $entry;
return $entry->isPlugin() ? '.prototype.' : '.';
}
/*--------------------------------------------------------------------------*/
/**
* Generates Markdown from JSDoc entries.
*
* @memberOf Generator
* @returns {String} The rendered Markdown.
*/
public function generate() {
$api = array();
$byCategory = $this->options['toc'] == 'categories';
$categories = array();
$closeTag = $this->closeTag;
$compiling = false;
$openTag = $this->openTag;
$result = array('# ' . $this->options['title']);
$toc = 'toc';
// initialize $api array
foreach ($this->entries as $entry) {
// skip invalid or private entries
$name = $entry->getName();
if (!$name || $entry->isPrivate()) {
continue;
}
$members = $entry->getMembers();
$members = count($members) ? $members : array('');
foreach ($members as $member) {
// create api category arrays
if ($member && !isset($api[$member])) {
// create temporary entry to be replaced later
$api[$member] = new stdClass;
$api[$member]->static = array();
$api[$member]->plugin = array();
}
// append entry to api member
if (!$member || $entry->isCtor() || ($entry->getType() == 'Object' &&
!preg_match('/[=:]\s*(?:null|undefined)\s*[,;]?$/', $entry->entry))) {
// assign the real entry, replacing the temporary entry if it exist
$member = ($member ? $member . ($entry->isPlugin() ? '#' : '.') : '') . $name;
$entry->static = @$api[$member] ? $api[$member]->static : array();
$entry->plugin = @$api[$member] ? $api[$member]->plugin : array();
$api[$member] = $entry;
foreach ($entry->getAliases() as $alias) {
$api[$member] = $alias;
$alias->static = array();
$alias->plugin = array();
}
}
else if ($entry->isStatic()) {
$api[$member]->static[] = $entry;
foreach ($entry->getAliases() as $alias) {
$api[$member]->static[] = $alias;
}
}
else if (!$entry->isCtor()) {
$api[$member]->plugin[] = $entry;
foreach ($entry->getAliases() as $alias) {
$api[$member]->plugin[] = $alias;
}
}
}
}
// add properties to each entry
foreach ($api as $entry) {
$entry->hash = $this->getHash($entry);
$entry->href = $this->getLineUrl($entry);
$member = $entry->getMembers(0);
$member = ($member ? $member . ($entry->isPlugin() ? '.prototype.' : '.') : '') . $entry->getName();
$entry->member = preg_replace('/' . $entry->getName() . '$/', '', $member);
// add properties to static and plugin sub-entries
foreach (array('static', 'plugin') as $kind) {
foreach ($entry->{$kind} as $subentry) {
$subentry->hash = $this->getHash($subentry);
$subentry->href = $this->getLineUrl($subentry);
$subentry->member = $member;
$subentry->separator = $this->getSeparator($subentry);
}
}
}
/*------------------------------------------------------------------------*/
// custom sort for root level entries
// TODO: see how well it handles deeper namespace traversal
function sortCompare($a, $b) {
$score = array( 'a' => 0, 'b' => 0);
foreach (array( 'a' => $a, 'b' => $b) as $key => $value) {
// capitalized properties are last
if (preg_match('/[#.][A-Z]/', $value)) {
$score[$key] = 0;
}
// lowercase prototype properties are next to last
else if (preg_match('/#[a-z]/', $value)) {
$score[$key] = 1;
}
// lowercase static properties next to first
else if (preg_match('/\.[a-z]/', $value)) {
$score[$key] = 2;
}
// root properties are first
else if (preg_match('/^[^#.]+$/', $value)) {
$score[$key] = 3;
}
}
$score = $score['b'] - $score['a'];
return $score ? $score : strcasecmp($a, $b);
}
uksort($api, 'sortCompare');
// sort static and plugin sub-entries
foreach ($api as $entry) {
foreach (array('static', 'plugin') as $kind) {
$sortBy = array( 'a' => array(), 'b' => array(), 'c' => array() );
foreach ($entry->{$kind} as $subentry) {
$name = $subentry->getName();
// functions w/o ALL-CAPs names are last
$sortBy['a'][] = $subentry->getType() == 'Function' && !preg_match('/^[A-Z_]+$/', $name);
// ALL-CAPs properties first
$sortBy['b'][] = preg_match('/^[A-Z_]+$/', $name);
// lowercase alphanumeric sort
$sortBy['c'][] = strtolower($name);
}
array_multisort($sortBy['a'], SORT_ASC, $sortBy['b'], SORT_DESC, $sortBy['c'], SORT_ASC, $entry->{$kind});
}
}
/*------------------------------------------------------------------------*/
// add categories
foreach ($api as $entry) {
$categories[$entry->getCategory()][] = $entry;
foreach (array('static', 'plugin') as $kind) {
foreach ($entry->{$kind} as $subentry) {
$categories[$subentry->getCategory()][] = $subentry;
}
}
}
// sort categories
ksort($categories);
foreach(array('Methods', 'Properties') as $category) {
if (isset($categories[$category])) {
$entries = $categories[$category];
unset($categories[$category]);
$categories[$category] = $entries;
}
}
/*------------------------------------------------------------------------*/
// compile TOC
$result[] = $openTag;
// compile TOC by categories
if ($byCategory) {
foreach ($categories as $category => $entries) {
if ($compiling) {
$result[] = $closeTag;
} else {
$compiling = true;
}
// assign TOC hash
if (count($result) == 2) {
$toc = $category;
}
// add category
array_push(
$result,
$openTag, '## ' . (count($result) == 2 ? '<a id="' . $toc . '"></a>' : '') . '`' . $category . '`'
);
// add entries
foreach ($entries as $entry) {
$result[] = Generator::interpolate('* [`#{member}#{separator}#{name}`](##{hash})', $entry);
}
}
}
// compile TOC by namespace
else {
foreach ($api as $entry) {
if ($compiling) {
$result[] = $closeTag;
} else {
$compiling = true;
}
$member = $entry->member . $entry->getName();
// assign TOC hash
if (count($result) == 2) {
$toc = $member;
}
// add root entry
array_push(
$result,
$openTag, '## ' . (count($result) == 2 ? '<a id="' . $toc . '"></a>' : '') . '`' . $member . '`',
Generator::interpolate('* [`' . $member . '`](##{hash})', $entry)
);
// add static and plugin sub-entries
foreach (array('static', 'plugin') as $kind) {
if ($kind == 'plugin' && count($entry->plugin)) {
array_push(
$result,
$closeTag,
$openTag,
'## `' . $member . ($entry->isCtor() ? '.prototype`' : '`')
);
}
foreach ($entry->{$kind} as $subentry) {
$subentry->member = $member;
$result[] = Generator::interpolate('* [`#{member}#{separator}#{name}`](##{hash})', $subentry);
}
}
}
}
array_push($result, $closeTag, $closeTag);
/*------------------------------------------------------------------------*/
// compile content
$compiling = false;
$result[] = $openTag;
if ($byCategory) {
foreach ($categories as $category => $entries) {
if ($compiling) {
$result[] = $closeTag;
} else {
$compiling = true;
}
if ($category != 'Methods' && $category != 'Properties') {
$category = '“' . $category . '” Methods';
}
array_push($result, $openTag, '## `' . $category . '`');
$this->addEntries($result, $entries);
}
}
else {
foreach ($api as $entry) {
// skip aliases
if ($entry->isAlias()) {
continue;
}
if ($compiling) {
$result[] = $closeTag;
} else {
$compiling = true;
}
// add root entry name
$member = $entry->member . $entry->getName();
array_push($result, $openTag, '## `' . $member . '`');
foreach (array($entry, 'static', 'plugin') as $kind) {
$subentries = is_string($kind) ? $entry->{$kind} : array($kind);
// add sub-entry name
if ($kind != 'static' && $entry->getType() != 'Object' &&
count($subentries) && $subentries[0] != $kind) {
if ($kind == 'plugin') {
$result[] = $closeTag;
}
array_push(
$result,
$openTag,
'## `' . $member . ($kind == 'plugin' ? '.prototype`' : '`')
);
}
$this->addEntries($result, $subentries);
}
}
}
// close tags add TOC link reference
array_push($result, $closeTag, $closeTag, '', ' [1]: #' . $toc . ' "Jump back to the TOC."');
// cleanup whitespace
return trim(preg_replace('/ +\n/', "\n", join($result, "\n")));
}
}
?>

File diff suppressed because it is too large Load Diff

View File

@@ -1,331 +1,331 @@
/* See license.txt for terms of usage */
.panelNode-script {
overflow: hidden;
font-family: monospace;
}
/************************************************************************************************/
.scriptTooltip {
position: fixed;
z-index: 2147483647;
padding: 2px 3px;
border: 1px solid #CBE087;
background: LightYellow;
font-family: monospace;
color: #000000;
}
/************************************************************************************************/
.sourceBox {
/* TODO: xxxpedro problem with sourceBox and scrolling elements */
/*overflow: scroll; /* see issue 1479 */
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
.sourceRow {
white-space: nowrap;
-moz-user-select: text;
}
.sourceRow.hovered {
background-color: #EEEEEE;
}
/************************************************************************************************/
.sourceLine {
-moz-user-select: none;
margin-right: 10px;
border-right: 1px solid #CCCCCC;
padding: 0px 4px 0 20px;
background: #EEEEEE no-repeat 2px 0px;
color: #888888;
white-space: pre;
font-family: monospace; /* see issue 2953 */
}
.noteInToolTip { /* below sourceLine, so it overrides it */
background-color: #FFD472;
}
.useA11y .sourceBox .sourceViewport:focus .sourceLine {
background-color: #FFFFC0;
color: navy;
border-right: 1px solid black;
}
.useA11y .sourceBox .sourceViewport:focus {
outline: none;
}
.a11y1emSize {
width: 1em;
height: 1em;
position: absolute;
}
.useA11y .panelStatusLabel:focus {
outline-offset: -2px !important;
}
.sourceBox > .sourceRow > .sourceLine {
cursor: pointer;
}
.sourceLine:hover {
text-decoration: none;
}
.sourceRowText {
white-space: pre;
}
.sourceRow[exe_line="true"] {
outline: 1px solid #D9D9B6;
margin-right: 1px;
background-color: lightgoldenrodyellow;
}
.sourceRow[executable="true"] > .sourceLine {
content: "-";
color: #4AA02C; /* Spring Green */
font-weight: bold;
}
.sourceRow[exe_line="true"] > .sourceLine {
background-image: url(chrome://firebug/skin/exe.png);
color: #000000;
}
.sourceRow[breakpoint="true"] > .sourceLine {
background-image: url(chrome://firebug/skin/breakpoint.png);
}
.sourceRow[breakpoint="true"][condition="true"] > .sourceLine {
background-image: url(chrome://firebug/skin/breakpointCondition.png);
}
.sourceRow[breakpoint="true"][disabledBreakpoint="true"] > .sourceLine {
background-image: url(chrome://firebug/skin/breakpointDisabled.png);
}
.sourceRow[breakpoint="true"][exe_line="true"] > .sourceLine {
background-image: url(chrome://firebug/skin/breakpointExe.png);
}
.sourceRow[breakpoint="true"][exe_line="true"][disabledBreakpoint="true"] > .sourceLine {
background-image: url(chrome://firebug/skin/breakpointDisabledExe.png);
}
.sourceLine.editing {
background-image: url(chrome://firebug/skin/breakpoint.png);
}
/************************************************************************************************/
.conditionEditor {
z-index: 2147483647;
position: absolute;
margin-top: 0;
left: 2px;
width: 90%;
}
.conditionEditorInner {
position: relative;
top: -26px;
height: 0;
}
.conditionCaption {
margin-bottom: 2px;
font-family: Lucida Grande, sans-serif;
font-weight: bold;
font-size: 11px;
color: #226679;
}
.conditionInput {
width: 100%;
border: 1px solid #0096C0;
font-family: monospace;
font-size: inherit;
}
.conditionEditorInner1 {
padding-left: 37px;
background: url(condBorders.png) repeat-y;
}
.conditionEditorInner2 {
padding-right: 25px;
background: url(condBorders.png) repeat-y 100% 0;
}
.conditionEditorTop1 {
background: url(condCorners.png) no-repeat 100% 0;
margin-left: 37px;
height: 35px;
}
.conditionEditorTop2 {
position: relative;
left: -37px;
width: 37px;
height: 35px;
background: url(condCorners.png) no-repeat;
}
.conditionEditorBottom1 {
background: url(condCorners.png) no-repeat 100% 100%;
margin-left: 37px;
height: 33px;
}
.conditionEditorBottom2 {
position: relative; left: -37px;
width: 37px;
height: 33px;
background: url(condCorners.png) no-repeat 0 100%;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
.upsideDown {
margin-top: 2px;
}
.upsideDown .conditionEditorInner {
top: -8px;
}
.upsideDown .conditionEditorInner1 {
padding-left: 33px;
background: url(condBordersUps.png) repeat-y;
}
.upsideDown .conditionEditorInner2 {
padding-right: 25px;
background: url(condBordersUps.png) repeat-y 100% 0;
}
.upsideDown .conditionEditorTop1 {
background: url(condCornersUps.png) no-repeat 100% 0;
margin-left: 33px;
height: 25px;
}
.upsideDown .conditionEditorTop2 {
position: relative;
left: -33px;
width: 33px;
height: 25px;
background: url(condCornersUps.png) no-repeat;
}
.upsideDown .conditionEditorBottom1 {
background: url(condCornersUps.png) no-repeat 100% 100%;
margin-left: 33px;
height: 43px;
}
.upsideDown .conditionEditorBottom2 {
position: relative;
left: -33px;
width: 33px;
height: 43px;
background: url(condCornersUps.png) no-repeat 0 100%;
}
/************************************************************************************************/
.breakpointsGroupListBox {
overflow: hidden;
}
.breakpointBlockHead {
position: relative;
padding-top: 4px;
}
.breakpointBlockHead > .checkbox {
margin-right: 4px;
}
.breakpointBlockHead > .objectLink-sourceLink {
top: 4px;
right: 20px;
background-color: #FFFFFF; /* issue 3308 */
}
.breakpointBlockHead > .closeButton {
position: absolute;
top: 2px;
right: 2px;
}
.breakpointCheckbox {
margin-top: 0;
vertical-align: top;
}
.breakpointName {
margin-left: 4px;
font-weight: bold;
}
.breakpointRow[aria-checked="false"] > .breakpointBlockHead > *,
.breakpointRow[aria-checked="false"] > .breakpointCode {
opacity: 0.5;
}
.breakpointRow[aria-checked="false"] .breakpointCheckbox,
.breakpointRow[aria-checked="false"] .objectLink-sourceLink,
.breakpointRow[aria-checked="false"] .closeButton,
.breakpointRow[aria-checked="false"] .breakpointMutationType {
opacity: 1.0 !important;
}
.breakpointCode {
overflow: hidden;
white-space: nowrap;
padding-left: 24px;
padding-bottom: 2px;
border-bottom: 1px solid #D7D7D7;
font-family: monospace;
color: DarkGreen;
}
.breakpointCondition {
white-space: nowrap;
padding-left: 24px;
padding-bottom: 2px;
border-bottom: 1px solid #D7D7D7;
font-family: monospace;
color: Gray;
}
.breakpointBlock-breakpoints > .groupHeader {
display: none;
}
.breakpointBlock-monitors > .breakpointCode {
padding: 0;
}
.breakpointBlock-errorBreakpoints .breakpointCheckbox,
.breakpointBlock-monitors .breakpointCheckbox {
display: none;
}
.breakpointHeader {
margin: 0 !important;
border-top: none !important;
}
/* See license.txt for terms of usage */
.panelNode-script {
overflow: hidden;
font-family: monospace;
}
/************************************************************************************************/
.scriptTooltip {
position: fixed;
z-index: 2147483647;
padding: 2px 3px;
border: 1px solid #CBE087;
background: LightYellow;
font-family: monospace;
color: #000000;
}
/************************************************************************************************/
.sourceBox {
/* TODO: xxxpedro problem with sourceBox and scrolling elements */
/*overflow: scroll; /* see issue 1479 */
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
.sourceRow {
white-space: nowrap;
-moz-user-select: text;
}
.sourceRow.hovered {
background-color: #EEEEEE;
}
/************************************************************************************************/
.sourceLine {
-moz-user-select: none;
margin-right: 10px;
border-right: 1px solid #CCCCCC;
padding: 0px 4px 0 20px;
background: #EEEEEE no-repeat 2px 0px;
color: #888888;
white-space: pre;
font-family: monospace; /* see issue 2953 */
}
.noteInToolTip { /* below sourceLine, so it overrides it */
background-color: #FFD472;
}
.useA11y .sourceBox .sourceViewport:focus .sourceLine {
background-color: #FFFFC0;
color: navy;
border-right: 1px solid black;
}
.useA11y .sourceBox .sourceViewport:focus {
outline: none;
}
.a11y1emSize {
width: 1em;
height: 1em;
position: absolute;
}
.useA11y .panelStatusLabel:focus {
outline-offset: -2px !important;
}
.sourceBox > .sourceRow > .sourceLine {
cursor: pointer;
}
.sourceLine:hover {
text-decoration: none;
}
.sourceRowText {
white-space: pre;
}
.sourceRow[exe_line="true"] {
outline: 1px solid #D9D9B6;
margin-right: 1px;
background-color: lightgoldenrodyellow;
}
.sourceRow[executable="true"] > .sourceLine {
content: "-";
color: #4AA02C; /* Spring Green */
font-weight: bold;
}
.sourceRow[exe_line="true"] > .sourceLine {
background-image: url(chrome://firebug/skin/exe.png);
color: #000000;
}
.sourceRow[breakpoint="true"] > .sourceLine {
background-image: url(chrome://firebug/skin/breakpoint.png);
}
.sourceRow[breakpoint="true"][condition="true"] > .sourceLine {
background-image: url(chrome://firebug/skin/breakpointCondition.png);
}
.sourceRow[breakpoint="true"][disabledBreakpoint="true"] > .sourceLine {
background-image: url(chrome://firebug/skin/breakpointDisabled.png);
}
.sourceRow[breakpoint="true"][exe_line="true"] > .sourceLine {
background-image: url(chrome://firebug/skin/breakpointExe.png);
}
.sourceRow[breakpoint="true"][exe_line="true"][disabledBreakpoint="true"] > .sourceLine {
background-image: url(chrome://firebug/skin/breakpointDisabledExe.png);
}
.sourceLine.editing {
background-image: url(chrome://firebug/skin/breakpoint.png);
}
/************************************************************************************************/
.conditionEditor {
z-index: 2147483647;
position: absolute;
margin-top: 0;
left: 2px;
width: 90%;
}
.conditionEditorInner {
position: relative;
top: -26px;
height: 0;
}
.conditionCaption {
margin-bottom: 2px;
font-family: Lucida Grande, sans-serif;
font-weight: bold;
font-size: 11px;
color: #226679;
}
.conditionInput {
width: 100%;
border: 1px solid #0096C0;
font-family: monospace;
font-size: inherit;
}
.conditionEditorInner1 {
padding-left: 37px;
background: url(condBorders.png) repeat-y;
}
.conditionEditorInner2 {
padding-right: 25px;
background: url(condBorders.png) repeat-y 100% 0;
}
.conditionEditorTop1 {
background: url(condCorners.png) no-repeat 100% 0;
margin-left: 37px;
height: 35px;
}
.conditionEditorTop2 {
position: relative;
left: -37px;
width: 37px;
height: 35px;
background: url(condCorners.png) no-repeat;
}
.conditionEditorBottom1 {
background: url(condCorners.png) no-repeat 100% 100%;
margin-left: 37px;
height: 33px;
}
.conditionEditorBottom2 {
position: relative; left: -37px;
width: 37px;
height: 33px;
background: url(condCorners.png) no-repeat 0 100%;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
.upsideDown {
margin-top: 2px;
}
.upsideDown .conditionEditorInner {
top: -8px;
}
.upsideDown .conditionEditorInner1 {
padding-left: 33px;
background: url(condBordersUps.png) repeat-y;
}
.upsideDown .conditionEditorInner2 {
padding-right: 25px;
background: url(condBordersUps.png) repeat-y 100% 0;
}
.upsideDown .conditionEditorTop1 {
background: url(condCornersUps.png) no-repeat 100% 0;
margin-left: 33px;
height: 25px;
}
.upsideDown .conditionEditorTop2 {
position: relative;
left: -33px;
width: 33px;
height: 25px;
background: url(condCornersUps.png) no-repeat;
}
.upsideDown .conditionEditorBottom1 {
background: url(condCornersUps.png) no-repeat 100% 100%;
margin-left: 33px;
height: 43px;
}
.upsideDown .conditionEditorBottom2 {
position: relative;
left: -33px;
width: 33px;
height: 43px;
background: url(condCornersUps.png) no-repeat 0 100%;
}
/************************************************************************************************/
.breakpointsGroupListBox {
overflow: hidden;
}
.breakpointBlockHead {
position: relative;
padding-top: 4px;
}
.breakpointBlockHead > .checkbox {
margin-right: 4px;
}
.breakpointBlockHead > .objectLink-sourceLink {
top: 4px;
right: 20px;
background-color: #FFFFFF; /* issue 3308 */
}
.breakpointBlockHead > .closeButton {
position: absolute;
top: 2px;
right: 2px;
}
.breakpointCheckbox {
margin-top: 0;
vertical-align: top;
}
.breakpointName {
margin-left: 4px;
font-weight: bold;
}
.breakpointRow[aria-checked="false"] > .breakpointBlockHead > *,
.breakpointRow[aria-checked="false"] > .breakpointCode {
opacity: 0.5;
}
.breakpointRow[aria-checked="false"] .breakpointCheckbox,
.breakpointRow[aria-checked="false"] .objectLink-sourceLink,
.breakpointRow[aria-checked="false"] .closeButton,
.breakpointRow[aria-checked="false"] .breakpointMutationType {
opacity: 1.0 !important;
}
.breakpointCode {
overflow: hidden;
white-space: nowrap;
padding-left: 24px;
padding-bottom: 2px;
border-bottom: 1px solid #D7D7D7;
font-family: monospace;
color: DarkGreen;
}
.breakpointCondition {
white-space: nowrap;
padding-left: 24px;
padding-bottom: 2px;
border-bottom: 1px solid #D7D7D7;
font-family: monospace;
color: Gray;
}
.breakpointBlock-breakpoints > .groupHeader {
display: none;
}
.breakpointBlock-monitors > .breakpointCode {
padding: 0;
}
.breakpointBlock-errorBreakpoints .breakpointCheckbox,
.breakpointBlock-monitors .breakpointCheckbox {
display: none;
}
.breakpointHeader {
margin: 0 !important;
border-top: none !important;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,20 +1,20 @@
/************************************************************************************************/
#fbToolbarSearch {
background-image: url(search.gif) !important;
}
/************************************************************************************************/
.fbErrors {
background-image: url(errorIcon.gif) !important;
}
/************************************************************************************************/
.logRow-info {
background-image: url(infoIcon.gif) !important;
}
.logRow-warning {
background-image: url(warningIcon.gif) !important;
}
.logRow-error {
background-image: url(errorIcon.gif) !important;
}
/************************************************************************************************/
#fbToolbarSearch {
background-image: url(search.gif) !important;
}
/************************************************************************************************/
.fbErrors {
background-image: url(errorIcon.gif) !important;
}
/************************************************************************************************/
.logRow-info {
background-image: url(infoIcon.gif) !important;
}
.logRow-warning {
background-image: url(warningIcon.gif) !important;
}
.logRow-error {
background-image: url(errorIcon.gif) !important;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,215 +1,215 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/DTD/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Firebug Lite</title>
<!-- An empty script to avoid FOUC when loading the stylesheet -->
<script type="text/javascript"></script>
<style type="text/css" media="screen">@import "firebug.css";</style>
<style>html,body{margin:0;padding:0;overflow:hidden;}</style>
</head>
<body class="fbBody">
<table id="fbChrome" cellpadding="0" cellspacing="0" border="0">
<tbody>
<tr>
<!-- Interface - Top Area -->
<td id="fbTop" colspan="2">
<!--
<div>
--><!-- <span id="fbToolbarErrors" class="fbErrors">2 errors</span> --><!--
<input type="text" id="fbToolbarSearch" />
</div>
-->
<!-- Window Buttons -->
<div id="fbWindowButtons">
<a id="fbWindow_btDeactivate" class="fbSmallButton fbHover" title="Deactivate Firebug for this web page">&nbsp;</a>
<a id="fbWindow_btDetach" class="fbSmallButton fbHover" title="Open Firebug in popup window">&nbsp;</a>
<a id="fbWindow_btClose" class="fbSmallButton fbHover" title="Minimize Firebug">&nbsp;</a>
</div>
<!-- Toolbar buttons and Status Bar -->
<div id="fbToolbar">
<div id="fbToolbarContent">
<!-- Firebug Button -->
<span id="fbToolbarIcon">
<a id="fbFirebugButton" class="fbIconButton" class="fbHover" target="_blank">&nbsp;</a>
</span>
<!--
<span id="fbLeftToolbarErrors" class="fbErrors">2 errors</span>
-->
<!-- Toolbar Buttons -->
<span id="fbToolbarButtons">
<!-- Fixed Toolbar Buttons -->
<span id="fbFixedButtons">
<a id="fbChrome_btInspect" class="fbButton fbHover" title="Click an element in the page to inspect">Inspect</a>
</span>
<!-- Console Panel Toolbar Buttons -->
<span id="fbConsoleButtons" class="fbToolbarButtons">
<a id="fbConsole_btClear" class="fbButton fbHover" title="Clear the console">Clear</a>
</span>
<!-- HTML Panel Toolbar Buttons -->
<!--
<span id="fbHTMLButtons" class="fbToolbarButtons">
<a id="fbHTML_btEdit" class="fbHover" title="Edit this HTML">Edit</a>
</span>
-->
</span>
<!-- Status Bar -->
<span id="fbStatusBarBox">
<span class="fbToolbarSeparator"></span>
<!-- HTML Panel Status Bar -->
<!--
<span id="fbHTMLStatusBar" class="fbStatusBar fbToolbarButtons">
</span>
-->
</span>
</div>
</div>
<!-- PanelBars -->
<div id="fbPanelBarBox">
<!-- Main PanelBar -->
<div id="fbPanelBar1" class="fbPanelBar">
<a id="fbConsoleTab" class="fbTab fbHover">
<span class="fbTabL"></span>
<span class="fbTabText">Console</span>
<span class="fbTabMenuTarget"></span>
<span class="fbTabR"></span>
</a>
<a id="fbHTMLTab" class="fbTab fbHover">
<span class="fbTabL"></span>
<span class="fbTabText">HTML</span>
<span class="fbTabR"></span>
</a>
<a class="fbTab fbHover">
<span class="fbTabL"></span>
<span class="fbTabText">CSS</span>
<span class="fbTabR"></span>
</a>
<a class="fbTab fbHover">
<span class="fbTabL"></span>
<span class="fbTabText">Script</span>
<span class="fbTabR"></span>
</a>
<a class="fbTab fbHover">
<span class="fbTabL"></span>
<span class="fbTabText">DOM</span>
<span class="fbTabR"></span>
</a>
</div>
<!-- Side PanelBars -->
<div id="fbPanelBar2Box" class="hide">
<div id="fbPanelBar2" class="fbPanelBar">
<!--
<a class="fbTab fbHover">
<span class="fbTabL"></span>
<span class="fbTabText">Style</span>
<span class="fbTabR"></span>
</a>
<a class="fbTab fbHover">
<span class="fbTabL"></span>
<span class="fbTabText">Layout</span>
<span class="fbTabR"></span>
</a>
<a class="fbTab fbHover">
<span class="fbTabL"></span>
<span class="fbTabText">DOM</span>
<span class="fbTabR"></span>
</a>
-->
</div>
</div>
</div>
<!-- Horizontal Splitter -->
<div id="fbHSplitter">&nbsp;</div>
</td>
</tr>
<!-- Interface - Main Area -->
<tr id="fbContent">
<!-- Panels -->
<td id="fbPanelBox1">
<div id="fbPanel1" class="fbFitHeight">
<div id="fbConsole" class="fbPanel"></div>
<div id="fbHTML" class="fbPanel"></div>
</div>
</td>
<!-- Side Panel Box -->
<td id="fbPanelBox2" class="hide">
<!-- VerticalSplitter -->
<div id="fbVSplitter" class="fbVSplitter">&nbsp;</div>
<!-- Side Panels -->
<div id="fbPanel2" class="fbFitHeight">
<!-- HTML Side Panels -->
<div id="fbHTML_Style" class="fbPanel"></div>
<div id="fbHTML_Layout" class="fbPanel"></div>
<div id="fbHTML_DOM" class="fbPanel"></div>
</div>
<!-- Large Command Line -->
<textarea id="fbLargeCommandLine" class="fbFitHeight"></textarea>
<!-- Large Command Line Buttons -->
<div id="fbLargeCommandButtons">
<a id="fbCommand_btRun" class="fbButton fbHover">Run</a>
<a id="fbCommand_btClear" class="fbButton fbHover">Clear</a>
<a id="fbSmallCommandLineIcon" class="fbSmallButton fbHover"></a>
</div>
</td>
</tr>
<!-- Interface - Bottom Area -->
<tr id="fbBottom" class="hide">
<!-- Command Line -->
<td id="fbCommand" colspan="2">
<div id="fbCommandBox">
<div id="fbCommandIcon">&gt;&gt;&gt;</div>
<input id="fbCommandLine" name="fbCommandLine" type="text" />
<a id="fbLargeCommandLineIcon" class="fbSmallButton fbHover"></a>
</div>
</td>
</tr>
</tbody>
</table>
<span id="fbMiniChrome">
<span id="fbMiniContent">
<span id="fbMiniIcon" title="Open Firebug Lite"></span>
<span id="fbMiniErrors" class="fbErrors"><!-- 2 errors --></span>
</span>
</span>
<!--
<div id="fbErrorPopup">
<div id="fbErrorPopupContent">
<div id="fbErrorIndicator" class="fbErrors">2 errors</div>
</div>
</div>
-->
</body>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/DTD/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Firebug Lite</title>
<!-- An empty script to avoid FOUC when loading the stylesheet -->
<script type="text/javascript"></script>
<style type="text/css" media="screen">@import "firebug.css";</style>
<style>html,body{margin:0;padding:0;overflow:hidden;}</style>
</head>
<body class="fbBody">
<table id="fbChrome" cellpadding="0" cellspacing="0" border="0">
<tbody>
<tr>
<!-- Interface - Top Area -->
<td id="fbTop" colspan="2">
<!--
<div>
--><!-- <span id="fbToolbarErrors" class="fbErrors">2 errors</span> --><!--
<input type="text" id="fbToolbarSearch" />
</div>
-->
<!-- Window Buttons -->
<div id="fbWindowButtons">
<a id="fbWindow_btDeactivate" class="fbSmallButton fbHover" title="Deactivate Firebug for this web page">&nbsp;</a>
<a id="fbWindow_btDetach" class="fbSmallButton fbHover" title="Open Firebug in popup window">&nbsp;</a>
<a id="fbWindow_btClose" class="fbSmallButton fbHover" title="Minimize Firebug">&nbsp;</a>
</div>
<!-- Toolbar buttons and Status Bar -->
<div id="fbToolbar">
<div id="fbToolbarContent">
<!-- Firebug Button -->
<span id="fbToolbarIcon">
<a id="fbFirebugButton" class="fbIconButton" class="fbHover" target="_blank">&nbsp;</a>
</span>
<!--
<span id="fbLeftToolbarErrors" class="fbErrors">2 errors</span>
-->
<!-- Toolbar Buttons -->
<span id="fbToolbarButtons">
<!-- Fixed Toolbar Buttons -->
<span id="fbFixedButtons">
<a id="fbChrome_btInspect" class="fbButton fbHover" title="Click an element in the page to inspect">Inspect</a>
</span>
<!-- Console Panel Toolbar Buttons -->
<span id="fbConsoleButtons" class="fbToolbarButtons">
<a id="fbConsole_btClear" class="fbButton fbHover" title="Clear the console">Clear</a>
</span>
<!-- HTML Panel Toolbar Buttons -->
<!--
<span id="fbHTMLButtons" class="fbToolbarButtons">
<a id="fbHTML_btEdit" class="fbHover" title="Edit this HTML">Edit</a>
</span>
-->
</span>
<!-- Status Bar -->
<span id="fbStatusBarBox">
<span class="fbToolbarSeparator"></span>
<!-- HTML Panel Status Bar -->
<!--
<span id="fbHTMLStatusBar" class="fbStatusBar fbToolbarButtons">
</span>
-->
</span>
</div>
</div>
<!-- PanelBars -->
<div id="fbPanelBarBox">
<!-- Main PanelBar -->
<div id="fbPanelBar1" class="fbPanelBar">
<a id="fbConsoleTab" class="fbTab fbHover">
<span class="fbTabL"></span>
<span class="fbTabText">Console</span>
<span class="fbTabMenuTarget"></span>
<span class="fbTabR"></span>
</a>
<a id="fbHTMLTab" class="fbTab fbHover">
<span class="fbTabL"></span>
<span class="fbTabText">HTML</span>
<span class="fbTabR"></span>
</a>
<a class="fbTab fbHover">
<span class="fbTabL"></span>
<span class="fbTabText">CSS</span>
<span class="fbTabR"></span>
</a>
<a class="fbTab fbHover">
<span class="fbTabL"></span>
<span class="fbTabText">Script</span>
<span class="fbTabR"></span>
</a>
<a class="fbTab fbHover">
<span class="fbTabL"></span>
<span class="fbTabText">DOM</span>
<span class="fbTabR"></span>
</a>
</div>
<!-- Side PanelBars -->
<div id="fbPanelBar2Box" class="hide">
<div id="fbPanelBar2" class="fbPanelBar">
<!--
<a class="fbTab fbHover">
<span class="fbTabL"></span>
<span class="fbTabText">Style</span>
<span class="fbTabR"></span>
</a>
<a class="fbTab fbHover">
<span class="fbTabL"></span>
<span class="fbTabText">Layout</span>
<span class="fbTabR"></span>
</a>
<a class="fbTab fbHover">
<span class="fbTabL"></span>
<span class="fbTabText">DOM</span>
<span class="fbTabR"></span>
</a>
-->
</div>
</div>
</div>
<!-- Horizontal Splitter -->
<div id="fbHSplitter">&nbsp;</div>
</td>
</tr>
<!-- Interface - Main Area -->
<tr id="fbContent">
<!-- Panels -->
<td id="fbPanelBox1">
<div id="fbPanel1" class="fbFitHeight">
<div id="fbConsole" class="fbPanel"></div>
<div id="fbHTML" class="fbPanel"></div>
</div>
</td>
<!-- Side Panel Box -->
<td id="fbPanelBox2" class="hide">
<!-- VerticalSplitter -->
<div id="fbVSplitter" class="fbVSplitter">&nbsp;</div>
<!-- Side Panels -->
<div id="fbPanel2" class="fbFitHeight">
<!-- HTML Side Panels -->
<div id="fbHTML_Style" class="fbPanel"></div>
<div id="fbHTML_Layout" class="fbPanel"></div>
<div id="fbHTML_DOM" class="fbPanel"></div>
</div>
<!-- Large Command Line -->
<textarea id="fbLargeCommandLine" class="fbFitHeight"></textarea>
<!-- Large Command Line Buttons -->
<div id="fbLargeCommandButtons">
<a id="fbCommand_btRun" class="fbButton fbHover">Run</a>
<a id="fbCommand_btClear" class="fbButton fbHover">Clear</a>
<a id="fbSmallCommandLineIcon" class="fbSmallButton fbHover"></a>
</div>
</td>
</tr>
<!-- Interface - Bottom Area -->
<tr id="fbBottom" class="hide">
<!-- Command Line -->
<td id="fbCommand" colspan="2">
<div id="fbCommandBox">
<div id="fbCommandIcon">&gt;&gt;&gt;</div>
<input id="fbCommandLine" name="fbCommandLine" type="text" />
<a id="fbLargeCommandLineIcon" class="fbSmallButton fbHover"></a>
</div>
</td>
</tr>
</tbody>
</table>
<span id="fbMiniChrome">
<span id="fbMiniContent">
<span id="fbMiniIcon" title="Open Firebug Lite"></span>
<span id="fbMiniErrors" class="fbErrors"><!-- 2 errors --></span>
</span>
</span>
<!--
<div id="fbErrorPopup">
<div id="fbErrorPopupContent">
<div id="fbErrorIndicator" class="fbErrors">2 errors</div>
</div>
</div>
-->
</body>
</html>

View File

@@ -1,272 +1,272 @@
/* See license.txt for terms of usage */
.panelNode-html {
-moz-box-sizing: padding-box;
padding: 4px 0 0 2px;
}
.nodeBox {
position: relative;
font-family: Monaco, monospace;
padding-left: 13px;
-moz-user-select: -moz-none;
}
.nodeBox.search-selection {
-moz-user-select: text;
}
.twisty {
position: absolute;
left: 0px;
top: 0px;
width: 14px;
height: 14px;
}
.nodeChildBox {
margin-left: 12px;
display: none;
}
.nodeLabel,
.nodeCloseLabel {
margin: -2px 2px 0 2px;
border: 2px solid transparent;
-moz-border-radius: 3px;
padding: 0 2px;
color: #000088;
}
.nodeCloseLabel {
display: none;
}
.nodeTag {
cursor: pointer;
color: blue;
}
.nodeValue {
color: #FF0000;
font-weight: normal;
}
.nodeText,
.nodeComment {
margin: 0 2px;
vertical-align: top;
}
.nodeText {
color: #333333;
}
.nodeWhiteSpace {
border: 1px solid LightGray;
white-space: pre; /* otherwise the border will be collapsed around zero pixels */
margin-left: 1px;
color: gray;
}
.nodeWhiteSpace_Space {
border: 1px solid #ddd;
}
.nodeTextEntity {
border: 1px solid gray;
white-space: pre; /* otherwise the border will be collapsed around zero pixels */
margin-left: 1px;
}
.nodeComment {
color: DarkGreen;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
.nodeBox.highlightOpen > .nodeLabel {
background-color: #EEEEEE;
}
.nodeBox.highlightOpen > .nodeCloseLabel,
.nodeBox.highlightOpen > .nodeChildBox,
.nodeBox.open > .nodeCloseLabel,
.nodeBox.open > .nodeChildBox {
display: block;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
.nodeBox.selected > .nodeLabel > .nodeLabelBox,
.nodeBox.selected > .nodeLabel {
border-color: Highlight;
background-color: Highlight;
color: HighlightText !important;
}
.nodeBox.selected > .nodeLabel > .nodeLabelBox,
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeTag,
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeText {
color: inherit !important;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
.nodeBox.highlighted > .nodeLabel {
border-color: Highlight !important;
background-color: cyan !important;
color: #000000 !important;
}
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox,
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeTag,
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeText {
color: #000000 !important;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox,
.nodeBox.nodeHidden .nodeCloseLabel,
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeText,
.nodeBox.nodeHidden .nodeText {
color: #888888;
}
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeTag,
.nodeBox.nodeHidden .nodeCloseLabel > .nodeCloseLabelBox > .nodeTag {
color: #5F82D9;
}
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue {
color: #D86060;
}
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox,
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeTag,
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeText {
color: SkyBlue !important;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
.nodeBox.mutated > .nodeLabel,
.nodeAttr.mutated,
.nodeValue.mutated,
.nodeText.mutated,
.nodeBox.mutated > .nodeText {
background-color: #EFFF79;
color: #FF0000 !important;
}
.nodeBox.selected.mutated > .nodeLabel,
.nodeBox.selected.mutated > .nodeLabel > .nodeLabelBox,
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr.mutated > .nodeValue,
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue.mutated,
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeText.mutated {
background-color: #EFFF79;
border-color: #EFFF79;
color: #FF0000 !important;
}
/************************************************************************************************/
.logRow-dirxml {
padding-left: 0;
}
.soloElement > .nodeBox {
padding-left: 0;
}
.useA11y .nodeLabel.focused {
outline: 2px solid #FF9933;
-moz-outline-radius: 3px;
outline-offset: -2px;
}
.useA11y .nodeLabelBox:focus {
outline: none;
}
/************************************************************************************************/
.breakpointCode .twisty {
display: none;
}
.breakpointCode .nodeBox.containerNodeBox,
.breakpointCode .nodeLabel {
padding-left: 0px;
margin-left: 0px;
font-family: Monaco, monospace !important;
}
.breakpointCode .nodeTag,
.breakpointCode .nodeAttr,
.breakpointCode .nodeText,
.breakpointCode .nodeValue,
.breakpointCode .nodeLabel {
color: DarkGreen !important;
}
.breakpointMutationType {
position: absolute;
top: 4px;
right: 20px;
color: gray;
}
/************************************************************************************************/
/************************************************************************************************/
/************************************************************************************************/
/************************************************************************************************/
/************************************************************************************************/
/************************************************************************************************/
/************************************************************************************************/
/************************************************************************************************/
/************************************************************************************************/
/************************************************************************************************/
/************************************************************************************************/
/* Twisties */
.twisty,
.logRow-errorMessage > .hasTwisty > .errorTitle,
.logRow-log > .objectBox-array.hasTwisty,
.logRow-spy .spyHead .spyTitle,
.logGroup > .logRow,
.memberRow.hasChildren > .memberLabelCell > .memberLabel,
.hasHeaders .netHrefLabel,
.netPageRow > .netCol > .netPageTitle {
background-image: url(twistyClosed.png);
background-repeat: no-repeat;
background-position: 2px 2px;
min-height: 12px;
}
.logRow-errorMessage > .hasTwisty.opened > .errorTitle,
.logRow-log > .objectBox-array.hasTwisty.opened,
.logRow-spy.opened .spyHead .spyTitle,
.logGroup.opened > .logRow,
.memberRow.hasChildren.opened > .memberLabelCell > .memberLabel,
.nodeBox.highlightOpen > .nodeLabel > .twisty,
.nodeBox.open > .nodeLabel > .twisty,
.netRow.opened > .netCol > .netHrefLabel,
.netPageRow.opened > .netCol > .netPageTitle {
background-image: url(twistyOpen.png);
}
.twisty {
background-position: 4px 4px;
/* See license.txt for terms of usage */
.panelNode-html {
-moz-box-sizing: padding-box;
padding: 4px 0 0 2px;
}
.nodeBox {
position: relative;
font-family: Monaco, monospace;
padding-left: 13px;
-moz-user-select: -moz-none;
}
.nodeBox.search-selection {
-moz-user-select: text;
}
.twisty {
position: absolute;
left: 0px;
top: 0px;
width: 14px;
height: 14px;
}
.nodeChildBox {
margin-left: 12px;
display: none;
}
.nodeLabel,
.nodeCloseLabel {
margin: -2px 2px 0 2px;
border: 2px solid transparent;
-moz-border-radius: 3px;
padding: 0 2px;
color: #000088;
}
.nodeCloseLabel {
display: none;
}
.nodeTag {
cursor: pointer;
color: blue;
}
.nodeValue {
color: #FF0000;
font-weight: normal;
}
.nodeText,
.nodeComment {
margin: 0 2px;
vertical-align: top;
}
.nodeText {
color: #333333;
}
.nodeWhiteSpace {
border: 1px solid LightGray;
white-space: pre; /* otherwise the border will be collapsed around zero pixels */
margin-left: 1px;
color: gray;
}
.nodeWhiteSpace_Space {
border: 1px solid #ddd;
}
.nodeTextEntity {
border: 1px solid gray;
white-space: pre; /* otherwise the border will be collapsed around zero pixels */
margin-left: 1px;
}
.nodeComment {
color: DarkGreen;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
.nodeBox.highlightOpen > .nodeLabel {
background-color: #EEEEEE;
}
.nodeBox.highlightOpen > .nodeCloseLabel,
.nodeBox.highlightOpen > .nodeChildBox,
.nodeBox.open > .nodeCloseLabel,
.nodeBox.open > .nodeChildBox {
display: block;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
.nodeBox.selected > .nodeLabel > .nodeLabelBox,
.nodeBox.selected > .nodeLabel {
border-color: Highlight;
background-color: Highlight;
color: HighlightText !important;
}
.nodeBox.selected > .nodeLabel > .nodeLabelBox,
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeTag,
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeText {
color: inherit !important;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
.nodeBox.highlighted > .nodeLabel {
border-color: Highlight !important;
background-color: cyan !important;
color: #000000 !important;
}
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox,
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeTag,
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeText {
color: #000000 !important;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox,
.nodeBox.nodeHidden .nodeCloseLabel,
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeText,
.nodeBox.nodeHidden .nodeText {
color: #888888;
}
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeTag,
.nodeBox.nodeHidden .nodeCloseLabel > .nodeCloseLabelBox > .nodeTag {
color: #5F82D9;
}
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue {
color: #D86060;
}
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox,
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeTag,
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeText {
color: SkyBlue !important;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
.nodeBox.mutated > .nodeLabel,
.nodeAttr.mutated,
.nodeValue.mutated,
.nodeText.mutated,
.nodeBox.mutated > .nodeText {
background-color: #EFFF79;
color: #FF0000 !important;
}
.nodeBox.selected.mutated > .nodeLabel,
.nodeBox.selected.mutated > .nodeLabel > .nodeLabelBox,
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr.mutated > .nodeValue,
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue.mutated,
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeText.mutated {
background-color: #EFFF79;
border-color: #EFFF79;
color: #FF0000 !important;
}
/************************************************************************************************/
.logRow-dirxml {
padding-left: 0;
}
.soloElement > .nodeBox {
padding-left: 0;
}
.useA11y .nodeLabel.focused {
outline: 2px solid #FF9933;
-moz-outline-radius: 3px;
outline-offset: -2px;
}
.useA11y .nodeLabelBox:focus {
outline: none;
}
/************************************************************************************************/
.breakpointCode .twisty {
display: none;
}
.breakpointCode .nodeBox.containerNodeBox,
.breakpointCode .nodeLabel {
padding-left: 0px;
margin-left: 0px;
font-family: Monaco, monospace !important;
}
.breakpointCode .nodeTag,
.breakpointCode .nodeAttr,
.breakpointCode .nodeText,
.breakpointCode .nodeValue,
.breakpointCode .nodeLabel {
color: DarkGreen !important;
}
.breakpointMutationType {
position: absolute;
top: 4px;
right: 20px;
color: gray;
}
/************************************************************************************************/
/************************************************************************************************/
/************************************************************************************************/
/************************************************************************************************/
/************************************************************************************************/
/************************************************************************************************/
/************************************************************************************************/
/************************************************************************************************/
/************************************************************************************************/
/************************************************************************************************/
/************************************************************************************************/
/* Twisties */
.twisty,
.logRow-errorMessage > .hasTwisty > .errorTitle,
.logRow-log > .objectBox-array.hasTwisty,
.logRow-spy .spyHead .spyTitle,
.logGroup > .logRow,
.memberRow.hasChildren > .memberLabelCell > .memberLabel,
.hasHeaders .netHrefLabel,
.netPageRow > .netCol > .netPageTitle {
background-image: url(twistyClosed.png);
background-repeat: no-repeat;
background-position: 2px 2px;
min-height: 12px;
}
.logRow-errorMessage > .hasTwisty.opened > .errorTitle,
.logRow-log > .objectBox-array.hasTwisty.opened,
.logRow-spy.opened .spyHead .spyTitle,
.logGroup.opened > .logRow,
.memberRow.hasChildren.opened > .memberLabelCell > .memberLabel,
.nodeBox.highlightOpen > .nodeLabel > .twisty,
.nodeBox.open > .nodeLabel > .twisty,
.netRow.opened > .netCol > .netHrefLabel,
.netPageRow.opened > .netCol > .netPageTitle {
background-image: url(twistyOpen.png);
}
.twisty {
background-position: 4px 4px;
}

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg">
<rect fill="white" x="0" y="0" width="100%" height="100%" />
<rect fill="highlight" x="0" y="0" width="100%" height="100%" rx="2px"/>
</svg>
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg">
<rect fill="white" x="0" y="0" width="100%" height="100%" />
<rect fill="highlight" x="0" y="0" width="100%" height="100%" rx="2px"/>
</svg>

Before

Width:  |  Height:  |  Size: 234 B

After

Width:  |  Height:  |  Size: 228 B

21
vendor/jquery/MIT-LICENSE.txt vendored Normal file
View File

@@ -0,0 +1,21 @@
Copyright 2012 jQuery Foundation and other contributors
http://jquery.com/
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

417
vendor/jquery/README.md vendored Normal file
View File

@@ -0,0 +1,417 @@
[jQuery](http://jquery.com/) - New Wave JavaScript
==================================================
Contribution Guides
--------------------------------------
In the spirit of open source software development, jQuery always encourages community code contribution. To help you get started and before you jump into writing code, be sure to read these important contribution guidelines thoroughly:
1. [Getting Involved](http://docs.jquery.com/Getting_Involved)
2. [Core Style Guide](http://docs.jquery.com/JQuery_Core_Style_Guidelines)
3. [Tips For Bug Patching](http://docs.jquery.com/Tips_for_jQuery_Bug_Patching)
What you need to build your own jQuery
--------------------------------------
In order to build jQuery, you need to have GNU make 3.8 or later, Node.js/npm latest, and git 1.7 or later.
(Earlier versions might work OK, but are not tested.)
Windows users have two options:
1. Install [msysgit](https://code.google.com/p/msysgit/) (Full installer for official Git),
[GNU make for Windows](http://gnuwin32.sourceforge.net/packages/make.htm), and a
[binary version of Node.js](http://node-js.prcn.co.cc/). Make sure all three packages are installed to the same
location (by default, this is C:\Program Files\Git).
2. Install [Cygwin](http://cygwin.com/) (make sure you install the git, make, and which packages), then either follow
the [Node.js build instructions](https://github.com/ry/node/wiki/Building-node.js-on-Cygwin-%28Windows%29) or install
the [binary version of Node.js](http://node-js.prcn.co.cc/).
Mac OS users should install Xcode (comes on your Mac OS install DVD, or downloadable from
[Apple's Xcode site](http://developer.apple.com/technologies/xcode.html)) and
[Homebrew](http://mxcl.github.com/homebrew/). Once Homebrew is installed, run `brew install git` to install git,
and `brew install node` to install Node.js.
Linux/BSD users should use their appropriate package managers to install make, git, and node, or build from source
if you swing that way. Easy-peasy.
How to build your own jQuery
----------------------------
First, clone a copy of the main jQuery git repo by running:
```bash
git clone git://github.com/jquery/jquery.git
```
Enter the directory and install the Node dependencies:
```bash
cd jquery && npm install
```
Make sure you have `grunt` installed by testing:
```bash
grunt -version
```
Then, to get a complete, minified (w/ Uglify.js), linted (w/ JSHint) version of jQuery, type the following:
```bash
grunt
```
The built version of jQuery will be put in the `dist/` subdirectory.
### Modules (new in 1.8)
Starting in jQuery 1.8, special builds can now be created that optionally exclude or include any of the following modules:
- ajax
- css
- dimensions
- effects
- offset
Before creating a custom build for use in production, be sure to check out the latest stable version:
```bash
git pull; git checkout $(git describe --abbrev=0 --tags)
```
Then, make sure all Node dependencies are installed and all Git submodules are checked out:
```bash
npm install && grunt
```
To create a custom build, use the following special `grunt` commands:
Exclude **ajax**:
```bash
grunt custom:-ajax
```
Exclude **css**:
```bash
grunt custom:-css
```
Exclude **deprecated**:
```bash
grunt custom:-deprecated
```
Exclude **dimensions**:
```bash
grunt custom:-dimensions
```
Exclude **effects**:
```bash
grunt custom:-effects
```
Exclude **offset**:
```bash
grunt custom:-offset
```
Exclude **all** optional modules:
```bash
grunt custom:-ajax,-css,-deprecated,-dimensions,-effects,-offset
```
Note: dependencies will be handled internally, by the build process.
Running the Unit Tests
--------------------------------------
Start grunt to auto-build jQuery as you work:
```bash
cd jquery && grunt watch
```
Run the unit tests with a local server that supports PHP. No database is required. Pre-configured php local servers are available for Windows and Mac. Here are some options:
- Windows: [WAMP download](http://www.wampserver.com/en/)
- Mac: [MAMP download](http://www.mamp.info/en/index.html)
- Linux: [Setting up LAMP](https://www.linux.com/learn/tutorials/288158-easy-lamp-server-installation)
- [Mongoose (most platforms)](http://code.google.com/p/mongoose/)
Building to a different directory
---------------------------------
If you want to build jQuery to a directory that is different from the default location:
```bash
grunt && grunt dist:/path/to/special/location/
```
With this example, the output files would be:
```bash
/path/to/special/location/jquery.js
/path/to/special/location/jquery.min.js
```
If you want to add a permanent copy destination, create a file in `dist/` called ".destination.json". Inside the file, paste and customize the following:
```json
{
"/Absolute/path/to/other/destination": true
}
```
Additionally, both methods can be combined.
Updating Submodules
-------------------
Update the submodules to what is probably the latest upstream code.
```bash
grunt update_submodules
```
Note: This task will also be run any time the default `grunt` command is used.
Git for dummies
---------------
As the source code is handled by the version control system Git, it's useful to know some features used.
### Submodules ###
The repository uses submodules, which normally are handled directly by the Makefile, but sometimes you want to
be able to work with them manually.
Following are the steps to manually get the submodules:
```bash
git clone https://github.com/jquery/jquery.git
cd jquery
git submodule init
git submodule update
```
Or:
```bash
git clone https://github.com/jquery/jquery.git
cd jquery
git submodule update --init
```
Or:
```bash
git clone --recursive https://github.com/jquery/jquery.git
cd jquery
```
If you want to work inside a submodule, it is possible, but first you need to checkout a branch:
```bash
cd src/sizzle
git checkout master
```
After you've committed your changes to the submodule, you'll update the jquery project to point to the new commit,
but remember to push the submodule changes before pushing the new jquery commit:
```bash
cd src/sizzle
git push origin master
cd ..
git add src/sizzle
git commit
```
### cleaning ###
If you want to purge your working directory back to the status of upstream, following commands can be used (remember everything you've worked on is gone after these):
```bash
git reset --hard upstream/master
git clean -fdx
```
### rebasing ###
For feature/topic branches, you should always used the `--rebase` flag to `git pull`, or if you are usually handling many temporary "to be in a github pull request" branches, run following to automate this:
```bash
git config branch.autosetuprebase local
```
(see `man git-config` for more information)
### handling merge conflicts ###
If you're getting merge conflicts when merging, instead of editing the conflicted files manually, you can use the feature
`git mergetool`. Even though the default tool `xxdiff` looks awful/old, it's rather useful.
Following are some commands that can be used there:
* `Ctrl + Alt + M` - automerge as much as possible
* `b` - jump to next merge conflict
* `s` - change the order of the conflicted lines
* `u` - undo an merge
* `left mouse button` - mark a block to be the winner
* `middle mouse button` - mark a line to be the winner
* `Ctrl + S` - save
* `Ctrl + Q` - quit
[QUnit](http://docs.jquery.com/QUnit) Reference
-----------------
### Test methods ###
```js
expect( numAssertions );
stop();
start();
```
note: QUnit's eventual addition of an argument to stop/start is ignored in this test suite so that start and stop can be passed as callbacks without worrying about their parameters
### Test assertions ###
```js
ok( value, [message] );
equal( actual, expected, [message] );
notEqual( actual, expected, [message] );
deepEqual( actual, expected, [message] );
notDeepEqual( actual, expected, [message] );
strictEqual( actual, expected, [message] );
notStrictEqual( actual, expected, [message] );
raises( block, [expected], [message] );
```
Test Suite Convenience Methods Reference (See [test/data/testinit.js](https://github.com/jquery/jquery/blob/master/test/data/testinit.js))
------------------------------
### Returns an array of elements with the given IDs ###
```js
q( ... );
```
Example:
```js
q("main", "foo", "bar");
=> [ div#main, span#foo, input#bar ]
```
### Asserts that a selection matches the given IDs ###
```js
t( testName, selector, [ "array", "of", "ids" ] );
```
Example:
```js
t("Check for something", "//[a]", ["foo", "baar"]);
```
### Fires a native DOM event without going through jQuery ###
```js
fireNative( node, eventType )
```
Example:
```js
fireNative( jQuery("#elem")[0], "click" );
```
### Add random number to url to stop caching ###
```js
url( "some/url.php" );
```
Example:
```js
url("data/test.html");
=> "data/test.html?10538358428943"
url("data/test.php?foo=bar");
=> "data/test.php?foo=bar&10538358345554"
```
### Load tests in an iframe ###
Loads a given page constructing a url with fileName: `"./data/" + fileName + ".html"`
and fires the given callback on jQuery ready (using the jQuery loading from that page)
and passes the iFrame's jQuery to the callback.
```js
testIframe( fileName, testName, callback );
```
Callback arguments:
```js
callback( jQueryFromIFrame, iFrameWindow, iFrameDocument );
```
### Load tests in an iframe (window.iframeCallback) ###
Loads a given page constructing a url with fileName: `"./data/" + fileName + ".html"`
The given callback is fired when window.iframeCallback is called by the page
The arguments passed to the callback are the same as the
arguments passed to window.iframeCallback, whatever that may be
```js
testIframeWithCallback( testName, fileName, callback );
```
Questions?
----------
If you have any questions, please feel free to ask on the
[Developing jQuery Core forum](http://forum.jquery.com/developing-jquery-core) or in #jquery on irc.freenode.net.

9440
vendor/jquery/jquery.js vendored Normal file

File diff suppressed because it is too large Load Diff

20
vendor/json3/LICENSE vendored Normal file
View File

@@ -0,0 +1,20 @@
Copyright (c) 2012 Kit Cambridge.
http://kitcambridge.github.com
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

124
vendor/json3/README.md vendored Normal file
View File

@@ -0,0 +1,124 @@
# JSON 3 #
![JSON 3 Logo](http://bestiejs.github.com/json3/page/logo.png)
**JSON 3** is a modern JSON implementation compatible with a variety of JavaScript platforms, including Internet Explorer 6, Opera 7, Safari 2, and Netscape 6. The current version is **3.2.4**.
- [Development Version](http://cdnjs.cloudflare.com/ajax/libs/json3/3.2.4/json3.js) *(36.5 KB; uncompressed with comments)*
- [Production Version](http://cdnjs.cloudflare.com/ajax/libs/json3/3.2.4/json3.min.js) *(3.0 KB; compressed and `gzip`-ped)*
[JSON](http://json.org/) is a language-independent data interchange format based on a loose subset of the JavaScript grammar. Originally popularized by [Douglas Crockford](http://www.crockford.com/), the format was standardized in the [fifth edition](http://es5.github.com/) of the ECMAScript specification. The 5.1 edition, ratified in June 2011, incorporates several modifications to the grammar pertaining to the serialization of dates.
JSON 3 exposes two functions: `stringify()` for [serializing](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/JSON/stringify) a JavaScript value to JSON, and `parse()` for [producing](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/JSON/parse) a JavaScript value from a JSON source string. It is a **drop-in replacement** for [JSON 2](http://json.org/js). The functions behave exactly as described in the ECMAScript spec, **except** for the date serialization discrepancy noted below.
The JSON 3 parser does **not** use `eval` or regular expressions. This provides security and performance benefits in obsolete and mobile environments, where the margin is particularly significant. The complete [benchmark suite](http://jsperf.com/json3) is available on [jsPerf](http://jsperf.com/).
The project is [hosted on GitHub](http://git.io/json3), along with the [unit tests](http://bestiejs.github.com/json3/test/test_browser.html). It is part of the [BestieJS](https://github.com/bestiejs) family, a collection of best-in-class JavaScript libraries that promote cross-platform support, specification precedents, unit testing, and plenty of documentation.
# Changes from JSON 2 #
JSON 3...
* Correctly serializes primitive wrapper objects.
* Throws a `TypeError` when serializing cyclic structures (JSON 2 recurses until the call stack overflows).
* Utilizes **feature tests** to detect broken or incomplete *native* JSON implementations (JSON 2 only checks for the presence of the native functions). The tests are only executed once at runtime, so there is no additional performance cost when parsing or serializing values.
**As of v3.2.3**, JSON 3 is compatible with [Prototype](http://prototypejs.org) 1.6.1 and older.
In contrast to JSON 2, JSON 3 **does not**...
* Add `toJSON()` methods to the `Boolean`, `Number`, and `String` prototypes. These are not part of any standard, and are made redundant by the design of the `stringify()` implementation.
* Add `toJSON()` or `toISOString()` methods to `Date.prototype`. See the note about date serialization below.
## Date Serialization
**JSON 3 deviates from the specification in one important way**: it does not define `Date#toISOString()` or `Date#toJSON()`. This preserves CommonJS compatibility and avoids polluting native prototypes. Instead, date serialization is performed internally by the `stringify()` implementation: if a date object does not define a custom `toJSON()` method, it is serialized as a [simplified ISO 8601 date-time string](http://es5.github.com/#x15.9.1.15).
**Several native `Date#toJSON()` implementations produce date time strings that do *not* conform to the grammar outlined in the spec**. For instance, all versions of Safari 4, as well as JSON 2, fail to serialize extended years correctly. Furthermore, JSON 2 and older implementations omit the milliseconds from the date-time string (optional in ES 5, but required in 5.1). Finally, in all versions of Safari 4 and 5, serializing an invalid date will produce the string `"Invalid Date"`, rather than `null`. Because these environments exhibit other serialization bugs, however, JSON 3 will override the native `stringify()` implementation.
Portions of the date serialization code are adapted from the [`date-shim`](https://github.com/Yaffle/date-shim) project.
# Usage #
## Web Browsers
<script src="//cdnjs.cloudflare.com/ajax/libs/json3/3.2.4/json3.min.js"></script>
<script>
JSON.stringify({"Hello": 123});
// => '{"Hello":123}'
JSON.parse("[[1, 2, 3], 1, 2, 3, 4]", function (key, value) {
if (typeof value == "number") {
value = value % 2 ? "Odd" : "Even";
}
return value;
});
// => [["Odd", "Even", "Odd"], "Odd", "Even", "Odd", "Even"]
</script>
## CommonJS Environments
var JSON3 = require("./path/to/json3");
JSON3.parse("[1, 2, 3]");
// => [1, 2, 3]
## JavaScript Engines
load("path/to/json3.js");
JSON.stringify({"Hello": 123, "Good-bye": 456}, ["Hello"], "\t");
// => '{\n\t"Hello": 123\n}'
# Compatibility #
JSON 3 has been **tested** with the following web browsers, CommonJS environments, and JavaScript engines.
## Web Browsers
- Windows [Internet Explorer](http://www.microsoft.com/windows/internet-explorer), version 6.0 and higher
- Mozilla [Firefox](http://www.mozilla.com/firefox), version 1.0 and higher
- Apple [Safari](http://www.apple.com/safari), version 2.0 and higher
- [Opera](http://www.opera.com) 7.02 and higher
- [Mozilla](http://sillydog.org/narchive/gecko.php) 1.0, [Netscape](http://sillydog.org/narchive/) 6.2.3, and [SeaMonkey](http://www.seamonkey-project.org/) 1.0 and higher
## CommonJS Environments
- [Node](http://nodejs.org/) 0.2.6 and higher
- [RingoJS](http://ringojs.org/) 0.4 and higher
- [Narwhal](http://narwhaljs.org/) 0.3.2 and higher
## JavaScript Engines
- Mozilla [Rhino](http://www.mozilla.org/rhino) 1.5R5 and higher
- WebKit [JSC](https://trac.webkit.org/wiki/JSC)
- Google [V8](http://code.google.com/p/v8)
## Known Incompatibilities
* Attempting to serialize the `arguments` object may produce inconsistent results across environments due to specification version differences. As a workaround, please convert the `arguments` object to an array first: `JSON.stringify([].slice.call(arguments, 0))`.
## Required Native Methods
JSON 3 assumes that the following methods exist and function as described in the ECMAScript specification:
- The `Number`, `String`, `Array`, `Object`, `Date`, `SyntaxError`, and `TypeError` constructors.
- `String.fromCharCode`
- `Object#toString`
- `Function#call`
- `Math.floor`
- `Number#toString`
- `Date#valueOf`
- `String.prototype`: `indexOf`, `charCodeAt`, `charAt`, `slice`.
- `Array.prototype`: `push`, `pop`, `join`.
# Contribute #
Check out a working copy of the JSON 3 source code with [Git](http://git-scm.com/):
$ git clone git://github.com/bestiejs/json3.git
$ cd json3
$ git submodule update --init
If you'd like to contribute a feature or bug fix, you can [fork](http://help.github.com/fork-a-repo/) JSON 3, commit your changes, and [send a pull request](http://help.github.com/send-pull-requests/). Please make sure to update the unit tests in the `test` directory as well.
Alternatively, you can use the [GitHub issue tracker](https://github.com/bestiejs/json3/issues) to submit bug reports, feature requests, and questions, or send tweets to [@kitcambridge](http://twitter.com/kitcambridge).
JSON 3 is released under the [MIT License](http://kit.mit-license.org/).

783
vendor/json3/lib/json3.js vendored Normal file
View File

@@ -0,0 +1,783 @@
/*! JSON v3.2.4 | http://bestiejs.github.com/json3 | Copyright 2012, Kit Cambridge | http://kit.mit-license.org */
;(function () {
// Convenience aliases.
var getClass = {}.toString, isProperty, forEach, undef;
// Detect the `define` function exposed by asynchronous module loaders. The
// strict `define` check is necessary for compatibility with `r.js`.
var isLoader = typeof define === "function" && define.amd, JSON3 = !isLoader && typeof exports == "object" && exports;
if (JSON3 || isLoader) {
if (typeof JSON == "object" && JSON) {
// Delegate to the native `stringify` and `parse` implementations in
// asynchronous module loaders and CommonJS environments.
if (isLoader) {
JSON3 = JSON;
} else {
JSON3.stringify = JSON.stringify;
JSON3.parse = JSON.parse;
}
} else if (isLoader) {
JSON3 = this.JSON = {};
}
} else {
// Export for web browsers and JavaScript engines.
JSON3 = this.JSON || (this.JSON = {});
}
// Local variables.
var Escapes, toPaddedString, quote, serialize;
var fromCharCode, Unescapes, abort, lex, get, walk, update, Index, Source;
// Test the `Date#getUTC*` methods. Based on work by @Yaffle.
var isExtended = new Date(-3509827334573292), floor, Months, getDay;
try {
// The `getUTCFullYear`, `Month`, and `Date` methods return nonsensical
// results for certain dates in Opera >= 10.53.
isExtended = isExtended.getUTCFullYear() == -109252 && isExtended.getUTCMonth() === 0 && isExtended.getUTCDate() == 1 &&
// Safari < 2.0.2 stores the internal millisecond time value correctly,
// but clips the values returned by the date methods to the range of
// signed 32-bit integers ([-2 ** 31, 2 ** 31 - 1]).
isExtended.getUTCHours() == 10 && isExtended.getUTCMinutes() == 37 && isExtended.getUTCSeconds() == 6 && isExtended.getUTCMilliseconds() == 708;
} catch (exception) {}
// Internal: Determines whether the native `JSON.stringify` and `parse`
// implementations are spec-compliant. Based on work by Ken Snyder.
function has(name) {
var stringifySupported, parseSupported, value, serialized = '{"A":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}', all = name == "json";
if (all || name == "json-stringify" || name == "json-parse") {
// Test `JSON.stringify`.
if (name == "json-stringify" || all) {
if ((stringifySupported = typeof JSON3.stringify == "function" && isExtended)) {
// A test function object with a custom `toJSON` method.
(value = function () {
return 1;
}).toJSON = value;
try {
stringifySupported =
// Firefox 3.1b1 and b2 serialize string, number, and boolean
// primitives as object literals.
JSON3.stringify(0) === "0" &&
// FF 3.1b1, b2, and JSON 2 serialize wrapped primitives as object
// literals.
JSON3.stringify(new Number()) === "0" &&
JSON3.stringify(new String()) == '""' &&
// FF 3.1b1, 2 throw an error if the value is `null`, `undefined`, or
// does not define a canonical JSON representation (this applies to
// objects with `toJSON` properties as well, *unless* they are nested
// within an object or array).
JSON3.stringify(getClass) === undef &&
// IE 8 serializes `undefined` as `"undefined"`. Safari <= 5.1.7 and
// FF 3.1b3 pass this test.
JSON3.stringify(undef) === undef &&
// Safari <= 5.1.7 and FF 3.1b3 throw `Error`s and `TypeError`s,
// respectively, if the value is omitted entirely.
JSON3.stringify() === undef &&
// FF 3.1b1, 2 throw an error if the given value is not a number,
// string, array, object, Boolean, or `null` literal. This applies to
// objects with custom `toJSON` methods as well, unless they are nested
// inside object or array literals. YUI 3.0.0b1 ignores custom `toJSON`
// methods entirely.
JSON3.stringify(value) === "1" &&
JSON3.stringify([value]) == "[1]" &&
// Prototype <= 1.6.1 serializes `[undefined]` as `"[]"` instead of
// `"[null]"`.
JSON3.stringify([undef]) == "[null]" &&
// YUI 3.0.0b1 fails to serialize `null` literals.
JSON3.stringify(null) == "null" &&
// FF 3.1b1, 2 halts serialization if an array contains a function:
// `[1, true, getClass, 1]` serializes as "[1,true,],". These versions
// of Firefox also allow trailing commas in JSON objects and arrays.
// FF 3.1b3 elides non-JSON values from objects and arrays, unless they
// define custom `toJSON` methods.
JSON3.stringify([undef, getClass, null]) == "[null,null,null]" &&
// Simple serialization test. FF 3.1b1 uses Unicode escape sequences
// where character escape codes are expected (e.g., `\b` => `\u0008`).
JSON3.stringify({ "A": [value, true, false, null, "\0\b\n\f\r\t"] }) == serialized &&
// FF 3.1b1 and b2 ignore the `filter` and `width` arguments.
JSON3.stringify(null, value) === "1" &&
JSON3.stringify([1, 2], null, 1) == "[\n 1,\n 2\n]" &&
// JSON 2, Prototype <= 1.7, and older WebKit builds incorrectly
// serialize extended years.
JSON3.stringify(new Date(-8.64e15)) == '"-271821-04-20T00:00:00.000Z"' &&
// The milliseconds are optional in ES 5, but required in 5.1.
JSON3.stringify(new Date(8.64e15)) == '"+275760-09-13T00:00:00.000Z"' &&
// Firefox <= 11.0 incorrectly serializes years prior to 0 as negative
// four-digit years instead of six-digit years. Credits: @Yaffle.
JSON3.stringify(new Date(-621987552e5)) == '"-000001-01-01T00:00:00.000Z"' &&
// Safari <= 5.1.5 and Opera >= 10.53 incorrectly serialize millisecond
// values less than 1000. Credits: @Yaffle.
JSON3.stringify(new Date(-1)) == '"1969-12-31T23:59:59.999Z"';
} catch (exception) {
stringifySupported = false;
}
}
if (!all) {
return stringifySupported;
}
}
// Test `JSON.parse`.
if (name == "json-parse" || all) {
if (typeof JSON3.parse == "function") {
try {
// FF 3.1b1, b2 will throw an exception if a bare literal is provided.
// Conforming implementations should also coerce the initial argument to
// a string prior to parsing.
if (JSON3.parse("0") === 0 && !JSON3.parse(false)) {
// Simple parsing test.
value = JSON3.parse(serialized);
if ((parseSupported = value.A.length == 5 && value.A[0] == 1)) {
try {
// Safari <= 5.1.2 and FF 3.1b1 allow unescaped tabs in strings.
parseSupported = !JSON3.parse('"\t"');
} catch (exception) {}
if (parseSupported) {
try {
// FF 4.0 and 4.0.1 allow leading `+` signs, and leading and
// trailing decimal points. FF 4.0, 4.0.1, and IE 9-10 also
// allow certain octal literals.
parseSupported = JSON3.parse("01") != 1;
} catch (exception) {}
}
}
}
} catch (exception) {
parseSupported = false;
}
}
if (!all) {
return parseSupported;
}
}
return stringifySupported && parseSupported;
}
}
if (!has("json")) {
// Define additional utility methods if the `Date` methods are buggy.
if (!isExtended) {
floor = Math.floor;
// A mapping between the months of the year and the number of days between
// January 1st and the first of the respective month.
Months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
// Internal: Calculates the number of days between the Unix epoch and the
// first day of the given month.
getDay = function (year, month) {
return Months[month] + 365 * (year - 1970) + floor((year - 1969 + (month = +(month > 1))) / 4) - floor((year - 1901 + month) / 100) + floor((year - 1601 + month) / 400);
};
}
// Internal: Determines if a property is a direct property of the given
// object. Delegates to the native `Object#hasOwnProperty` method.
if (!(isProperty = {}.hasOwnProperty)) {
isProperty = function (property) {
var members = {}, constructor;
if ((members.__proto__ = null, members.__proto__ = {
// The *proto* property cannot be set multiple times in recent
// versions of Firefox and SeaMonkey.
"toString": 1
}, members).toString != getClass) {
// Safari <= 2.0.3 doesn't implement `Object#hasOwnProperty`, but
// supports the mutable *proto* property.
isProperty = function (property) {
// Capture and break the object's prototype chain (see section 8.6.2
// of the ES 5.1 spec). The parenthesized expression prevents an
// unsafe transformation by the Closure Compiler.
var original = this.__proto__, result = property in (this.__proto__ = null, this);
// Restore the original prototype chain.
this.__proto__ = original;
return result;
};
} else {
// Capture a reference to the top-level `Object` constructor.
constructor = members.constructor;
// Use the `constructor` property to simulate `Object#hasOwnProperty` in
// other environments.
isProperty = function (property) {
var parent = (this.constructor || constructor).prototype;
return property in this && !(property in parent && this[property] === parent[property]);
};
}
members = null;
return isProperty.call(this, property);
};
}
// Internal: Normalizes the `for...in` iteration algorithm across
// environments. Each enumerated key is yielded to a `callback` function.
forEach = function (object, callback) {
var size = 0, Properties, members, property, forEach;
// Tests for bugs in the current environment's `for...in` algorithm. The
// `valueOf` property inherits the non-enumerable flag from
// `Object.prototype` in older versions of IE, Netscape, and Mozilla.
(Properties = function () {
this.valueOf = 0;
}).prototype.valueOf = 0;
// Iterate over a new instance of the `Properties` class.
members = new Properties();
for (property in members) {
// Ignore all properties inherited from `Object.prototype`.
if (isProperty.call(members, property)) {
size++;
}
}
Properties = members = null;
// Normalize the iteration algorithm.
if (!size) {
// A list of non-enumerable properties inherited from `Object.prototype`.
members = ["valueOf", "toString", "toLocaleString", "propertyIsEnumerable", "isPrototypeOf", "hasOwnProperty", "constructor"];
// IE <= 8, Mozilla 1.0, and Netscape 6.2 ignore shadowed non-enumerable
// properties.
forEach = function (object, callback) {
var isFunction = getClass.call(object) == "[object Function]", property, length;
for (property in object) {
// Gecko <= 1.0 enumerates the `prototype` property of functions under
// certain conditions; IE does not.
if (!(isFunction && property == "prototype") && isProperty.call(object, property)) {
callback(property);
}
}
// Manually invoke the callback for each non-enumerable property.
for (length = members.length; property = members[--length]; isProperty.call(object, property) && callback(property));
};
} else if (size == 2) {
// Safari <= 2.0.4 enumerates shadowed properties twice.
forEach = function (object, callback) {
// Create a set of iterated properties.
var members = {}, isFunction = getClass.call(object) == "[object Function]", property;
for (property in object) {
// Store each property name to prevent double enumeration. The
// `prototype` property of functions is not enumerated due to cross-
// environment inconsistencies.
if (!(isFunction && property == "prototype") && !isProperty.call(members, property) && (members[property] = 1) && isProperty.call(object, property)) {
callback(property);
}
}
};
} else {
// No bugs detected; use the standard `for...in` algorithm.
forEach = function (object, callback) {
var isFunction = getClass.call(object) == "[object Function]", property, isConstructor;
for (property in object) {
if (!(isFunction && property == "prototype") && isProperty.call(object, property) && !(isConstructor = property === "constructor")) {
callback(property);
}
}
// Manually invoke the callback for the `constructor` property due to
// cross-environment inconsistencies.
if (isConstructor || isProperty.call(object, (property = "constructor"))) {
callback(property);
}
};
}
return forEach(object, callback);
};
// Public: Serializes a JavaScript `value` as a JSON string. The optional
// `filter` argument may specify either a function that alters how object and
// array members are serialized, or an array of strings and numbers that
// indicates which properties should be serialized. The optional `width`
// argument may be either a string or number that specifies the indentation
// level of the output.
if (!has("json-stringify")) {
// Internal: A map of control characters and their escaped equivalents.
Escapes = {
"\\": "\\\\",
'"': '\\"',
"\b": "\\b",
"\f": "\\f",
"\n": "\\n",
"\r": "\\r",
"\t": "\\t"
};
// Internal: Converts `value` into a zero-padded string such that its
// length is at least equal to `width`. The `width` must be <= 6.
toPaddedString = function (width, value) {
// The `|| 0` expression is necessary to work around a bug in
// Opera <= 7.54u2 where `0 == -0`, but `String(-0) !== "0"`.
return ("000000" + (value || 0)).slice(-width);
};
// Internal: Double-quotes a string `value`, replacing all ASCII control
// characters (characters with code unit values between 0 and 31) with
// their escaped equivalents. This is an implementation of the
// `Quote(value)` operation defined in ES 5.1 section 15.12.3.
quote = function (value) {
var result = '"', index = 0, symbol;
for (; symbol = value.charAt(index); index++) {
// Escape the reverse solidus, double quote, backspace, form feed, line
// feed, carriage return, and tab characters.
result += '\\"\b\f\n\r\t'.indexOf(symbol) > -1 ? Escapes[symbol] :
// If the character is a control character, append its Unicode escape
// sequence; otherwise, append the character as-is.
(Escapes[symbol] = symbol < " " ? "\\u00" + toPaddedString(2, symbol.charCodeAt(0).toString(16)) : symbol);
}
return result + '"';
};
// Internal: Recursively serializes an object. Implements the
// `Str(key, holder)`, `JO(value)`, and `JA(value)` operations.
serialize = function (property, object, callback, properties, whitespace, indentation, stack) {
var value = object[property], className, year, month, date, time, hours, minutes, seconds, milliseconds, results, element, index, length, prefix, any, result;
if (typeof value == "object" && value) {
className = getClass.call(value);
if (className == "[object Date]" && !isProperty.call(value, "toJSON")) {
if (value > -1 / 0 && value < 1 / 0) {
// Dates are serialized according to the `Date#toJSON` method
// specified in ES 5.1 section 15.9.5.44. See section 15.9.1.15
// for the ISO 8601 date time string format.
if (getDay) {
// Manually compute the year, month, date, hours, minutes,
// seconds, and milliseconds if the `getUTC*` methods are
// buggy. Adapted from @Yaffle's `date-shim` project.
date = floor(value / 864e5);
for (year = floor(date / 365.2425) + 1970 - 1; getDay(year + 1, 0) <= date; year++);
for (month = floor((date - getDay(year, 0)) / 30.42); getDay(year, month + 1) <= date; month++);
date = 1 + date - getDay(year, month);
// The `time` value specifies the time within the day (see ES
// 5.1 section 15.9.1.2). The formula `(A % B + B) % B` is used
// to compute `A modulo B`, as the `%` operator does not
// correspond to the `modulo` operation for negative numbers.
time = (value % 864e5 + 864e5) % 864e5;
// The hours, minutes, seconds, and milliseconds are obtained by
// decomposing the time within the day. See section 15.9.1.10.
hours = floor(time / 36e5) % 24;
minutes = floor(time / 6e4) % 60;
seconds = floor(time / 1e3) % 60;
milliseconds = time % 1e3;
} else {
year = value.getUTCFullYear();
month = value.getUTCMonth();
date = value.getUTCDate();
hours = value.getUTCHours();
minutes = value.getUTCMinutes();
seconds = value.getUTCSeconds();
milliseconds = value.getUTCMilliseconds();
}
// Serialize extended years correctly.
value = (year <= 0 || year >= 1e4 ? (year < 0 ? "-" : "+") + toPaddedString(6, year < 0 ? -year : year) : toPaddedString(4, year)) +
"-" + toPaddedString(2, month + 1) + "-" + toPaddedString(2, date) +
// Months, dates, hours, minutes, and seconds should have two
// digits; milliseconds should have three.
"T" + toPaddedString(2, hours) + ":" + toPaddedString(2, minutes) + ":" + toPaddedString(2, seconds) +
// Milliseconds are optional in ES 5.0, but required in 5.1.
"." + toPaddedString(3, milliseconds) + "Z";
} else {
value = null;
}
} else if (typeof value.toJSON == "function" && ((className != "[object Number]" && className != "[object String]" && className != "[object Array]") || isProperty.call(value, "toJSON"))) {
// Prototype <= 1.6.1 adds non-standard `toJSON` methods to the
// `Number`, `String`, `Date`, and `Array` prototypes. JSON 3
// ignores all `toJSON` methods on these objects unless they are
// defined directly on an instance.
value = value.toJSON(property);
}
}
if (callback) {
// If a replacement function was provided, call it to obtain the value
// for serialization.
value = callback.call(object, property, value);
}
if (value === null) {
return "null";
}
className = getClass.call(value);
if (className == "[object Boolean]") {
// Booleans are represented literally.
return "" + value;
} else if (className == "[object Number]") {
// JSON numbers must be finite. `Infinity` and `NaN` are serialized as
// `"null"`.
return value > -1 / 0 && value < 1 / 0 ? "" + value : "null";
} else if (className == "[object String]") {
// Strings are double-quoted and escaped.
return quote(value);
}
// Recursively serialize objects and arrays.
if (typeof value == "object") {
// Check for cyclic structures. This is a linear search; performance
// is inversely proportional to the number of unique nested objects.
for (length = stack.length; length--;) {
if (stack[length] === value) {
// Cyclic structures cannot be serialized by `JSON.stringify`.
throw TypeError();
}
}
// Add the object to the stack of traversed objects.
stack.push(value);
results = [];
// Save the current indentation level and indent one additional level.
prefix = indentation;
indentation += whitespace;
if (className == "[object Array]") {
// Recursively serialize array elements.
for (index = 0, length = value.length; index < length; any || (any = true), index++) {
element = serialize(index, value, callback, properties, whitespace, indentation, stack);
results.push(element === undef ? "null" : element);
}
result = any ? (whitespace ? "[\n" + indentation + results.join(",\n" + indentation) + "\n" + prefix + "]" : ("[" + results.join(",") + "]")) : "[]";
} else {
// Recursively serialize object members. Members are selected from
// either a user-specified list of property names, or the object
// itself.
forEach(properties || value, function (property) {
var element = serialize(property, value, callback, properties, whitespace, indentation, stack);
if (element !== undef) {
// According to ES 5.1 section 15.12.3: "If `gap` {whitespace}
// is not the empty string, let `member` {quote(property) + ":"}
// be the concatenation of `member` and the `space` character."
// The "`space` character" refers to the literal space
// character, not the `space` {width} argument provided to
// `JSON.stringify`.
results.push(quote(property) + ":" + (whitespace ? " " : "") + element);
}
any || (any = true);
});
result = any ? (whitespace ? "{\n" + indentation + results.join(",\n" + indentation) + "\n" + prefix + "}" : ("{" + results.join(",") + "}")) : "{}";
}
// Remove the object from the traversed object stack.
stack.pop();
return result;
}
};
// Public: `JSON.stringify`. See ES 5.1 section 15.12.3.
JSON3.stringify = function (source, filter, width) {
var whitespace, callback, properties, index, length, value;
if (typeof filter == "function" || typeof filter == "object" && filter) {
if (getClass.call(filter) == "[object Function]") {
callback = filter;
} else if (getClass.call(filter) == "[object Array]") {
// Convert the property names array into a makeshift set.
properties = {};
for (index = 0, length = filter.length; index < length; value = filter[index++], ((getClass.call(value) == "[object String]" || getClass.call(value) == "[object Number]") && (properties[value] = 1)));
}
}
if (width) {
if (getClass.call(width) == "[object Number]") {
// Convert the `width` to an integer and create a string containing
// `width` number of space characters.
if ((width -= width % 1) > 0) {
for (whitespace = "", width > 10 && (width = 10); whitespace.length < width; whitespace += " ");
}
} else if (getClass.call(width) == "[object String]") {
whitespace = width.length <= 10 ? width : width.slice(0, 10);
}
}
// Opera <= 7.54u2 discards the values associated with empty string keys
// (`""`) only if they are used directly within an object member list
// (e.g., `!("" in { "": 1})`).
return serialize("", (value = {}, value[""] = source, value), callback, properties, whitespace, "", []);
};
}
// Public: Parses a JSON source string.
if (!has("json-parse")) {
fromCharCode = String.fromCharCode;
// Internal: A map of escaped control characters and their unescaped
// equivalents.
Unescapes = {
"\\": "\\",
'"': '"',
"/": "/",
"b": "\b",
"t": "\t",
"n": "\n",
"f": "\f",
"r": "\r"
};
// Internal: Resets the parser state and throws a `SyntaxError`.
abort = function() {
Index = Source = null;
throw SyntaxError();
};
// Internal: Returns the next token, or `"$"` if the parser has reached
// the end of the source string. A token may be a string, number, `null`
// literal, or Boolean literal.
lex = function () {
var source = Source, length = source.length, symbol, value, begin, position, sign;
while (Index < length) {
symbol = source.charAt(Index);
if ("\t\r\n ".indexOf(symbol) > -1) {
// Skip whitespace tokens, including tabs, carriage returns, line
// feeds, and space characters.
Index++;
} else if ("{}[]:,".indexOf(symbol) > -1) {
// Parse a punctuator token at the current position.
Index++;
return symbol;
} else if (symbol == '"') {
// Advance to the next character and parse a JSON string at the
// current position. String tokens are prefixed with the sentinel
// `@` character to distinguish them from punctuators.
for (value = "@", Index++; Index < length;) {
symbol = source.charAt(Index);
if (symbol < " ") {
// Unescaped ASCII control characters are not permitted.
abort();
} else if (symbol == "\\") {
// Parse escaped JSON control characters, `"`, `\`, `/`, and
// Unicode escape sequences.
symbol = source.charAt(++Index);
if ('\\"/btnfr'.indexOf(symbol) > -1) {
// Revive escaped control characters.
value += Unescapes[symbol];
Index++;
} else if (symbol == "u") {
// Advance to the first character of the escape sequence.
begin = ++Index;
// Validate the Unicode escape sequence.
for (position = Index + 4; Index < position; Index++) {
symbol = source.charAt(Index);
// A valid sequence comprises four hexdigits that form a
// single hexadecimal value.
if (!(symbol >= "0" && symbol <= "9" || symbol >= "a" && symbol <= "f" || symbol >= "A" && symbol <= "F")) {
// Invalid Unicode escape sequence.
abort();
}
}
// Revive the escaped character.
value += fromCharCode("0x" + source.slice(begin, Index));
} else {
// Invalid escape sequence.
abort();
}
} else {
if (symbol == '"') {
// An unescaped double-quote character marks the end of the
// string.
break;
}
// Append the original character as-is.
value += symbol;
Index++;
}
}
if (source.charAt(Index) == '"') {
Index++;
// Return the revived string.
return value;
}
// Unterminated string.
abort();
} else {
// Parse numbers and literals.
begin = Index;
// Advance the scanner's position past the sign, if one is
// specified.
if (symbol == "-") {
sign = true;
symbol = source.charAt(++Index);
}
// Parse an integer or floating-point value.
if (symbol >= "0" && symbol <= "9") {
// Leading zeroes are interpreted as octal literals.
if (symbol == "0" && (symbol = source.charAt(Index + 1), symbol >= "0" && symbol <= "9")) {
// Illegal octal literal.
abort();
}
sign = false;
// Parse the integer component.
for (; Index < length && (symbol = source.charAt(Index), symbol >= "0" && symbol <= "9"); Index++);
// Floats cannot contain a leading decimal point; however, this
// case is already accounted for by the parser.
if (source.charAt(Index) == ".") {
position = ++Index;
// Parse the decimal component.
for (; position < length && (symbol = source.charAt(position), symbol >= "0" && symbol <= "9"); position++);
if (position == Index) {
// Illegal trailing decimal.
abort();
}
Index = position;
}
// Parse exponents.
symbol = source.charAt(Index);
if (symbol == "e" || symbol == "E") {
// Skip past the sign following the exponent, if one is
// specified.
symbol = source.charAt(++Index);
if (symbol == "+" || symbol == "-") {
Index++;
}
// Parse the exponential component.
for (position = Index; position < length && (symbol = source.charAt(position), symbol >= "0" && symbol <= "9"); position++);
if (position == Index) {
// Illegal empty exponent.
abort();
}
Index = position;
}
// Coerce the parsed value to a JavaScript number.
return +source.slice(begin, Index);
}
// A negative sign may only precede numbers.
if (sign) {
abort();
}
// `true`, `false`, and `null` literals.
if (source.slice(Index, Index + 4) == "true") {
Index += 4;
return true;
} else if (source.slice(Index, Index + 5) == "false") {
Index += 5;
return false;
} else if (source.slice(Index, Index + 4) == "null") {
Index += 4;
return null;
}
// Unrecognized token.
abort();
}
}
// Return the sentinel `$` character if the parser has reached the end
// of the source string.
return "$";
};
// Internal: Parses a JSON `value` token.
get = function (value) {
var results, any, key;
if (value == "$") {
// Unexpected end of input.
abort();
}
if (typeof value == "string") {
if (value.charAt(0) == "@") {
// Remove the sentinel `@` character.
return value.slice(1);
}
// Parse object and array literals.
if (value == "[") {
// Parses a JSON array, returning a new JavaScript array.
results = [];
for (;; any || (any = true)) {
value = lex();
// A closing square bracket marks the end of the array literal.
if (value == "]") {
break;
}
// If the array literal contains elements, the current token
// should be a comma separating the previous element from the
// next.
if (any) {
if (value == ",") {
value = lex();
if (value == "]") {
// Unexpected trailing `,` in array literal.
abort();
}
} else {
// A `,` must separate each array element.
abort();
}
}
// Elisions and leading commas are not permitted.
if (value == ",") {
abort();
}
results.push(get(value));
}
return results;
} else if (value == "{") {
// Parses a JSON object, returning a new JavaScript object.
results = {};
for (;; any || (any = true)) {
value = lex();
// A closing curly brace marks the end of the object literal.
if (value == "}") {
break;
}
// If the object literal contains members, the current token
// should be a comma separator.
if (any) {
if (value == ",") {
value = lex();
if (value == "}") {
// Unexpected trailing `,` in object literal.
abort();
}
} else {
// A `,` must separate each object member.
abort();
}
}
// Leading commas are not permitted, object property names must be
// double-quoted strings, and a `:` must separate each property
// name and value.
if (value == "," || typeof value != "string" || value.charAt(0) != "@" || lex() != ":") {
abort();
}
results[value.slice(1)] = get(lex());
}
return results;
}
// Unexpected token encountered.
abort();
}
return value;
};
// Internal: Updates a traversed object member.
update = function(source, property, callback) {
var element = walk(source, property, callback);
if (element === undef) {
delete source[property];
} else {
source[property] = element;
}
};
// Internal: Recursively traverses a parsed JSON object, invoking the
// `callback` function for each value. This is an implementation of the
// `Walk(holder, name)` operation defined in ES 5.1 section 15.12.2.
walk = function (source, property, callback) {
var value = source[property], length;
if (typeof value == "object" && value) {
if (getClass.call(value) == "[object Array]") {
for (length = value.length; length--;) {
update(value, length, callback);
}
} else {
// `forEach` can't be used to traverse an array in Opera <= 8.54,
// as `Object#hasOwnProperty` returns `false` for array indices
// (e.g., `![1, 2, 3].hasOwnProperty("0")`).
forEach(value, function (property) {
update(value, property, callback);
});
}
}
return callback.call(source, property, value);
};
// Public: `JSON.parse`. See ES 5.1 section 15.12.2.
JSON3.parse = function (source, callback) {
var result, value;
Index = 0;
Source = source;
result = get(lex());
// If a JSON string contains multiple tokens, it is invalid.
if (lex() != "$") {
abort();
}
// Reset the parser state.
Index = Source = null;
return callback && getClass.call(callback) == "[object Function]" ? walk((value = {}, value[""] = result, value), "", callback) : result;
};
}
}
// Export for asynchronous module loaders.
if (isLoader) {
define(function () {
return JSON3;
});
}
}).call(this);

20
vendor/platform.js/LICENSE.txt vendored Normal file
View File

@@ -0,0 +1,20 @@
Copyright 2011-2012 John-David Dalton <http://allyoucanleet.com/>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

98
vendor/platform.js/README.md vendored Normal file
View File

@@ -0,0 +1,98 @@
# Platform.js <sup>v1.0.0</sup>
A platform detection library that works on nearly all JavaScript platforms<sup><a name="fnref1" href="#fn1">1</a></sup>.
## Disclaimer
Platform.js is for informational purposes only and **not** intended as a substitution for [feature detection/inference](http://allyoucanleet.com/post/18087210413/feature-testing-costs#screencast2) checks.
## BestieJS
Platform.js is part of the BestieJS *"Best in Class"* module collection. This means we promote solid browser/environment support, ES5 precedents, unit testing, and plenty of documentation.
## Documentation
The documentation for Platform.js can be viewed here: [/doc/README.md](https://github.com/bestiejs/platform.js/blob/master/doc/README.md#readme)
For a list of upcoming features, check out our [roadmap](https://github.com/bestiejs/platform.js/wiki/Roadmap).
## Support
Platform.js has been tested in at least Adobe AIR 3.1, Chrome 5-21, Firefox 1-14, IE 6-9, Opera 9.25-12, Safari 3-6, Node.js 0.8.6, Narwhal 0.3.2, RingoJS 0.8, and Rhino 1.7RC5.
## Installation and usage
In a browser or Adobe AIR:
```html
<script src="platform.js"></script>
```
Via [npm](http://npmjs.org/):
```bash
npm install platform
```
In [Node.js](http://nodejs.org/) and [RingoJS](http://ringojs.org/):
```js
var platform = require('platform');
```
In [Rhino](http://www.mozilla.org/rhino/):
```js
load('platform.js');
```
In an AMD loader like [RequireJS](http://requirejs.org/):
```js
require({
'paths': {
'platform': 'path/to/platform'
}
},
['platform'], function(platform) {
console.log(platform.name);
});
```
Usage example:
```js
// on IE10 x86 platform preview running in IE7 compatibility mode on Windows 7 64 bit edition
platform.name; // 'IE'
platform.version; // '10.0'
platform.layout; // 'Trident'
platform.os; // 'Windows Server 2008 R2 / 7 x64'
platform.description; // 'IE 10.0 x86 (platform preview; running in IE 7 mode) on Windows Server 2008 R2 / 7 x64'
// or on an iPad
platform.name; // 'Safari'
platform.version; // '5.1'
platform.product; // 'iPad'
platform.manufacturer; // 'Apple'
platform.layout; // 'WebKit'
platform.os; // 'iOS 5.0'
platform.description; // 'Safari 5.1 on Apple iPad (iOS 5.0)'
// or parsing a given UA string
var info = platform.parse('Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7.2; en; rv:2.0) Gecko/20100101 Firefox/4.0 Opera 11.52');
info.name; // 'Opera'
info.version; // '11.52'
info.layout; // 'Presto'
info.os; // 'Mac OS X 10.7.2'
info.description; // 'Opera 11.52 (identifying as Firefox 4.0) on Mac OS X 10.7.2'
```
## Author
* [John-David Dalton](http://allyoucanleet.com/)
[![twitter/jdalton](http://gravatar.com/avatar/299a3d891ff1920b69c364d061007043?s=70)](https://twitter.com/jdalton "Follow @jdalton on Twitter")
## Contributors
* [Mathias Bynens](http://mathiasbynens.be/)
[![twitter/mathias](http://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](https://twitter.com/mathias "Follow @mathias on Twitter")

996
vendor/platform.js/platform.js vendored Normal file
View File

@@ -0,0 +1,996 @@
/*!
* Platform.js v1.0.0 <http://mths.be/platform>
* Copyright 2010-2012 John-David Dalton <http://allyoucanleet.com/>
* Available under MIT license <http://mths.be/mit>
*/
;(function(window) {
'use strict';
/** Backup possible window/global object */
var oldWin = window;
/** Detect free variable `exports` */
var freeExports = typeof exports == 'object' && exports;
/** Detect free variable `global` */
var freeGlobal = typeof global == 'object' && global &&
(global == global.global ? (window = global) : global);
/** Opera regexp */
var reOpera = /Opera/;
/** Used to resolve a value's internal [[Class]] */
var toString = {}.toString;
/** Detect Java environment */
var java = /Java/.test(getClassOf(window.java)) && window.java;
/** A character to represent alpha */
var alpha = java ? 'a' : '\u03b1';
/** A character to represent beta */
var beta = java ? 'b' : '\u03b2';
/** Browser document object */
var doc = window.document || {};
/** Used to check for own properties of an object */
var hasOwnProperty = {}.hasOwnProperty;
/** Browser navigator object */
var nav = window.navigator || {};
/**
* Detect Opera browser
* http://www.howtocreate.co.uk/operaStuff/operaObject.html
* http://dev.opera.com/articles/view/opera-mini-web-content-authoring-guidelines/#operamini
*/
var opera = window.operamini || window.opera;
/** Opera [[Class]] */
var operaClass = reOpera.test(operaClass = getClassOf(opera)) ? operaClass : (opera = null);
/** Possible global object */
var thisBinding = this;
/** Browser user agent string */
var userAgent = nav.userAgent || '';
/*--------------------------------------------------------------------------*/
/**
* Capitalizes a string value.
*
* @private
* @param {String} string The string to capitalize.
* @returns {String} The capitalized string.
*/
function capitalize(string) {
string = String(string);
return string.charAt(0).toUpperCase() + string.slice(1);
}
/**
* An iteration utility for arrays and objects.
*
* @private
* @param {Array|Object} object The object to iterate over.
* @param {Function} callback The function called per iteration.
*/
function each(object, callback) {
var index = -1,
length = object.length;
if (length == length >>> 0) {
while (++index < length) {
callback(object[index], index, object);
}
} else {
forOwn(object, callback);
}
}
/**
* Trim and conditionally capitalize string values.
*
* @private
* @param {String} string The string to format.
* @returns {String} The formatted string.
*/
function format(string) {
string = trim(string);
return /^(?:webOS|i(?:OS|P))/.test(string)
? string
: capitalize(string);
}
/**
* Iterates over an object's own properties, executing the `callback` for each.
*
* @private
* @param {Object} object The object to iterate over.
* @param {Function} callback The function executed per own property.
*/
function forOwn(object, callback) {
for (var key in object) {
hasKey(object, key) && callback(object[key], key, object);
}
}
/**
* Gets the internal [[Class]] of a value.
*
* @private
* @param {Mixed} value The value.
* @returns {String} The [[Class]].
*/
function getClassOf(value) {
return value == null
? capitalize(value)
: toString.call(value).slice(8, -1);
}
/**
* Checks if an object has the specified key as a direct property.
*
* @private
* @param {Object} object The object to check.
* @param {String} key The key to check for.
* @returns {Boolean} Returns `true` if key is a direct property, else `false`.
*/
function hasKey() {
// lazy define for others (not as accurate)
hasKey = function(object, key) {
var parent = object != null && (object.constructor || Object).prototype;
return !!parent && key in Object(object) && !(key in parent && object[key] === parent[key]);
};
// for modern browsers
if (getClassOf(hasOwnProperty) == 'Function') {
hasKey = function(object, key) {
return object != null && hasOwnProperty.call(object, key);
};
}
// for Safari 2
else if ({}.__proto__ == Object.prototype) {
hasKey = function(object, key) {
var result = false;
if (object != null) {
object = Object(object);
object.__proto__ = [object.__proto__, object.__proto__ = null, result = key in object][0];
}
return result;
};
}
return hasKey.apply(this, arguments);
}
/**
* Host objects can return type values that are different from their actual
* data type. The objects we are concerned with usually return non-primitive
* types of object, function, or unknown.
*
* @private
* @param {Mixed} object The owner of the property.
* @param {String} property The property to check.
* @returns {Boolean} Returns `true` if the property value is a non-primitive, else `false`.
*/
function isHostType(object, property) {
var type = object != null ? typeof object[property] : 'number';
return !/^(?:boolean|number|string|undefined)$/.test(type) &&
(type == 'object' ? !!object[property] : true);
}
/**
* Prepares a string for use in a RegExp constructor by making hyphens and
* spaces optional.
*
* @private
* @param {String} string The string to qualify.
* @returns {String} The qualified string.
*/
function qualify(string) {
return String(string).replace(/([ -])(?!$)/g, '$1?');
}
/**
* A bare-bones` Array#reduce` like utility function.
*
* @private
* @param {Array} array The array to iterate over.
* @param {Function} callback The function called per iteration.
* @param {Mixed} accumulator Initial value of the accumulator.
* @returns {Mixed} The accumulator.
*/
function reduce(array, callback) {
var accumulator = null;
each(array, function(value, index) {
accumulator = callback(accumulator, value, index, array);
});
return accumulator;
}
/**
* Removes leading and trailing whitespace from a string.
*
* @private
* @param {String} string The string to trim.
* @returns {String} The trimmed string.
*/
function trim(string) {
return String(string).replace(/^ +| +$/g, '');
}
/*--------------------------------------------------------------------------*/
/**
* Creates a new platform object.
*
* @memberOf platform
* @param {String} [ua = navigator.userAgent] The user agent string.
* @returns {Object} A platform object.
*/
function parse(ua) {
ua || (ua = userAgent);
/** Temporary variable used over the script's lifetime */
var data;
/** The CPU architecture */
var arch = ua;
/** Platform description array */
var description = [];
/** Platform alpha/beta indicator */
var prerelease = null;
/** A flag to indicate that environment features should be used to resolve the platform */
var useFeatures = ua == userAgent;
/** The browser/environment version */
var version = useFeatures && opera && typeof opera.version == 'function' && opera.version();
/* Detectable layout engines (order is important) */
var layout = getLayout([
{ 'label': 'WebKit', 'pattern': 'AppleWebKit' },
'iCab',
'Presto',
'NetFront',
'Tasman',
'Trident',
'KHTML',
'Gecko'
]);
/* Detectable browser names (order is important) */
var name = getName([
'Adobe AIR',
'Arora',
'Avant Browser',
'Camino',
'Epiphany',
'Fennec',
'Flock',
'Galeon',
'GreenBrowser',
'iCab',
'Iceweasel',
'Iron',
'K-Meleon',
'Konqueror',
'Lunascape',
'Maxthon',
'Midori',
'Nook Browser',
'PhantomJS',
'Raven',
'Rekonq',
'RockMelt',
'SeaMonkey',
{ 'label': 'Silk', 'pattern': '(?:Cloud9|Silk-Accelerated)' },
'Sleipnir',
'SlimBrowser',
'Sunrise',
'Swiftfox',
'WebPositive',
'Opera Mini',
'Opera',
'Chrome',
{ 'label': 'Chrome Mobile', 'pattern': '(?:CriOS|CrMo)' },
{ 'label': 'Firefox', 'pattern': '(?:Firefox|Minefield)' },
{ 'label': 'IE', 'pattern': 'MSIE' },
'Safari'
]);
/* Detectable products (order is important) */
var product = getProduct([
'BlackBerry',
{ 'label': 'Galaxy S', 'pattern': 'GT-I9000' },
{ 'label': 'Galaxy S2', 'pattern': 'GT-I9100' },
'Google TV',
'iPad',
'iPod',
'iPhone',
'Kindle',
{ 'label': 'Kindle Fire', 'pattern': '(?:Cloud9|Silk-Accelerated)' },
'Nook',
'PlayBook',
'PlayStation Vita',
'TouchPad',
'Transformer',
'Xoom'
]);
/* Detectable manufacturers */
var manufacturer = getManufacturer({
'Apple': { 'iPad': 1, 'iPhone': 1, 'iPod': 1 },
'Amazon': { 'Kindle': 1, 'Kindle Fire': 1 },
'Asus': { 'Transformer': 1 },
'Barnes & Noble': { 'Nook': 1 },
'BlackBerry': { 'PlayBook': 1 },
'Google': { 'Google TV': 1 },
'HP': { 'TouchPad': 1 },
'LG': { },
'Motorola': { 'Xoom': 1 },
'Nokia': { },
'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1 },
'Sony': { 'PlayStation Vita': 1 }
});
/* Detectable OSes (order is important) */
var os = getOS([
'Android',
'CentOS',
'Debian',
'Fedora',
'FreeBSD',
'Gentoo',
'Haiku',
'Kubuntu',
'Linux Mint',
'Red Hat',
'SuSE',
'Ubuntu',
'Xubuntu',
'Cygwin',
'Symbian OS',
'hpwOS',
'webOS ',
'webOS',
'Tablet OS',
'Linux',
'Mac OS X',
'Macintosh',
'Mac',
'Windows 98;',
'Windows '
]);
/*------------------------------------------------------------------------*/
/**
* Picks the layout engine from an array of guesses.
*
* @private
* @param {Array} guesses An array of guesses.
* @returns {String|Null} The detected layout engine.
*/
function getLayout(guesses) {
return reduce(guesses, function(result, guess) {
return result || RegExp('\\b' + (
guess.pattern || qualify(guess)
) + '\\b', 'i').exec(ua) && (guess.label || guess);
});
}
/**
* Picks the manufacturer from an array of guesses.
*
* @private
* @param {Array} guesses An array of guesses.
* @returns {String|Null} The detected manufacturer.
*/
function getManufacturer(guesses) {
return reduce(guesses, function(result, value, key) {
// lookup the manufacturer by product or scan the UA for the manufacturer
return result || (
value[product] ||
value[0/*Opera 9.25 fix*/, /^[a-z]+(?: +[a-z]+\b)*/i.exec(product)] ||
RegExp('\\b' + (key.pattern || qualify(key)) + '(?:\\b|\\w*\\d)', 'i').exec(ua)
) && (key.label || key);
});
}
/**
* Picks the browser name from an array of guesses.
*
* @private
* @param {Array} guesses An array of guesses.
* @returns {String|Null} The detected browser name.
*/
function getName(guesses) {
return reduce(guesses, function(result, guess) {
return result || RegExp('\\b' + (
guess.pattern || qualify(guess)
) + '\\b', 'i').exec(ua) && (guess.label || guess);
});
}
/**
* Picks the OS name from an array of guesses.
*
* @private
* @param {Array} guesses An array of guesses.
* @returns {String|Null} The detected OS name.
*/
function getOS(guesses) {
return reduce(guesses, function(result, guess) {
var pattern = guess.pattern || qualify(guess);
if (!result && (result =
RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua))) {
// platform tokens defined at
// http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx
// http://web.archive.org/web/20081122053950/http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx
data = {
'6.2': '8',
'6.1': 'Server 2008 R2 / 7',
'6.0': 'Server 2008 / Vista',
'5.2': 'Server 2003 / XP 64-bit',
'5.1': 'XP',
'5.01': '2000 SP1',
'5.0': '2000',
'4.0': 'NT',
'4.90': 'ME'
};
// detect Windows version from platform tokens
if (/^Win/i.test(result) &&
(data = data[0/*Opera 9.25 fix*/, /[\d.]+$/.exec(result)])) {
result = 'Windows ' + data;
}
// correct character case and cleanup
result = format(String(result)
.replace(RegExp(pattern, 'i'), guess.label || guess)
.replace(/ ce$/i, ' CE')
.replace(/hpw/i, 'web')
.replace(/Macintosh/, 'Mac OS')
.replace(/_PowerPC/i, ' OS')
.replace(/(OS X) [^ \d]+/i, '$1')
.replace(/\/(\d)/, ' $1')
.replace(/_/g, '.')
.replace(/(?: BePC|[ .]*fc[ \d.]+)$/i, '')
.replace(/x86\.64/gi, 'x86_64')
.split(' on ')[0]);
}
return result;
});
}
/**
* Picks the product name from an array of guesses.
*
* @private
* @param {Array} guesses An array of guesses.
* @returns {String|Null} The detected product name.
*/
function getProduct(guesses) {
return reduce(guesses, function(result, guess) {
var pattern = guess.pattern || qualify(guess);
if (!result && (result =
RegExp('\\b' + pattern + ' *\\d+[.\\w_]*', 'i').exec(ua) ||
RegExp('\\b' + pattern + '(?:; *(?:[a-z]+[_-])?[a-z]+\\d+|[^ ();-]*)', 'i').exec(ua)
)) {
// split by forward slash and append product version if needed
if ((result = String(guess.label || result).split('/'))[1] && !/[\d.]+/.test(result[0])) {
result[0] += ' ' + result[1];
}
// correct character case and cleanup
guess = guess.label || guess;
result = format(result[0]
.replace(RegExp(pattern, 'i'), guess)
.replace(RegExp('; *(?:' + guess + '[_-])?', 'i'), ' ')
.replace(RegExp('(' + guess + ')(\\w)', 'i'), '$1 $2'));
}
return result;
});
}
/**
* Resolves the version using an array of UA patterns.
*
* @private
* @param {Array} patterns An array of UA patterns.
* @returns {String|Null} The detected version.
*/
function getVersion(patterns) {
return reduce(patterns, function(result, pattern) {
return result || (RegExp(pattern +
'(?:-[\\d.]+/|(?: for [\\w-]+)?[ /-])([\\d.]+[^ ();/_-]*)', 'i').exec(ua) || 0)[1] || null;
});
}
/*------------------------------------------------------------------------*/
/**
* Returns `platform.description` when the platform object is coerced to a string.
*
* @name toString
* @memberOf platform
* @returns {String} Returns `platform.description` if available, else an empty string.
*/
function toStringPlatform() {
return this.description || '';
}
/*------------------------------------------------------------------------*/
// convert layout to an array so we can add extra details
layout && (layout = [layout]);
// detect product names that contain their manufacturer's name
if (manufacturer && !product) {
product = getProduct([manufacturer]);
}
// clean up Google TV
if ((data = /Google TV/.exec(product))) {
product = data[0];
}
// detect simulators
if (/\bSimulator\b/i.test(ua)) {
product = (product ? product + ' ' : '') + 'Simulator';
}
// detect iOS
if (/^iP/.test(product)) {
name || (name = 'Safari');
os = 'iOS' + ((data = / OS ([\d_]+)/i.exec(ua))
? ' ' + data[1].replace(/_/g, '.')
: '');
}
// detect Kubuntu
else if (name == 'Konqueror' && !/buntu/i.test(os)) {
os = 'Kubuntu';
}
// detect Android browsers
else if (manufacturer && manufacturer != 'Google' &&
/Chrome|Vita/.test(name + ';' + product)) {
name = 'Android Browser';
os = /Android/.test(os) ? os : 'Android';
}
// detect false positives for Firefox/Safari
else if (!name || (data = !/\bMinefield\b/i.test(ua) && /Firefox|Safari/.exec(name))) {
// escape the `/` for Firefox 1
if (name && !product && /[\/,]|^[^(]+?\)/.test(ua.slice(ua.indexOf(data + '/') + 8))) {
// clear name of false positives
name = null;
}
// reassign a generic name
if ((data = product || manufacturer || os) &&
(product || manufacturer || /Android|Symbian OS|Tablet OS|webOS/.test(os))) {
name = /[a-z]+(?: Hat)?/i.exec(/Android/.test(os) ? os : data) + ' Browser';
}
}
// detect non-Opera versions (order is important)
if (!version) {
version = getVersion([
'(?:Cloud9|CriOS|CrMo|Opera ?Mini|Raven|Silk(?!/[\\d.]+$))',
'Version',
qualify(name),
'(?:Firefox|Minefield|NetFront)'
]);
}
// detect stubborn layout engines
if (layout == 'iCab' && parseFloat(version) > 3) {
layout = ['WebKit'];
} else if (data =
/Opera/.test(name) && 'Presto' ||
/\b(?:Midori|Nook|Safari)\b/i.test(ua) && 'WebKit' ||
!layout && /\bMSIE\b/i.test(ua) && (/^Mac/.test(os) ? 'Tasman' : 'Trident')) {
layout = [data];
}
// leverage environment features
if (useFeatures) {
// detect server-side environments
// Rhino has a global function while others have a global object
if (isHostType(window, 'global')) {
if (java) {
data = java.lang.System;
arch = data.getProperty('os.arch');
os = os || data.getProperty('os.name') + ' ' + data.getProperty('os.version');
}
if (typeof exports == 'object' && exports) {
// if `thisBinding` is the [ModuleScope]
if (thisBinding == oldWin && typeof system == 'object' && (data = [system])[0]) {
os || (os = data[0].os || null);
try {
data[1] = require('ringo/engine').version;
version = data[1].join('.');
name = 'RingoJS';
} catch(e) {
if (data[0].global == freeGlobal) {
name = 'Narwhal';
}
}
} else if (typeof process == 'object' && (data = process)) {
name = 'Node.js';
arch = data.arch;
os = data.platform;
version = /[\d.]+/.exec(data.version)[0];
}
} else if (getClassOf(window.environment) == 'Environment') {
name = 'Rhino';
}
}
// detect Adobe AIR
else if (getClassOf(data = window.runtime) == 'ScriptBridgingProxyObject') {
name = 'Adobe AIR';
os = data.flash.system.Capabilities.os;
}
// detect PhantomJS
else if (getClassOf(data = window.phantom) == 'RuntimeObject') {
name = 'PhantomJS';
version = (data = data.version || null) && (data.major + '.' + data.minor + '.' + data.patch);
}
// detect IE compatibility modes
else if (typeof doc.documentMode == 'number' && (data = /\bTrident\/(\d+)/i.exec(ua))) {
// we're in compatibility mode when the Trident version + 4 doesn't
// equal the document mode
version = [version, doc.documentMode];
if ((data = +data[1] + 4) != version[1]) {
description.push('IE ' + version[1] + ' mode');
layout[1] = '';
version[1] = data;
}
version = name == 'IE' ? String(version[1].toFixed(1)) : version[0];
}
os = os && format(os);
}
// detect prerelease phases
if (version && (data =
/(?:[ab]|dp|pre|[ab]\d+pre)(?:\d+\+?)?$/i.exec(version) ||
/(?:alpha|beta)(?: ?\d)?/i.exec(ua + ';' + (useFeatures && nav.appMinorVersion)) ||
/\bMinefield\b/i.test(ua) && 'a')) {
prerelease = /b/i.test(data) ? 'beta' : 'alpha';
version = version.replace(RegExp(data + '\\+?$'), '') +
(prerelease == 'beta' ? beta : alpha) + (/\d+\+?/.exec(data) || '');
}
// rename code name "Fennec"
if (name == 'Fennec') {
name = 'Firefox Mobile';
}
// obscure Maxthon's unreliable version
else if (name == 'Maxthon' && version) {
version = version.replace(/\.[\d.]+/, '.x');
}
// detect Silk desktop/accelerated modes
else if (name == 'Silk') {
if (!/Mobi/i.test(ua)) {
os = 'Android';
description.unshift('desktop mode');
}
if (/Accelerated *= *true/i.test(ua)) {
description.unshift('accelerated');
}
}
// detect Windows Phone desktop mode
else if (name == 'IE' && (data = (/; *(?:XBLWP|ZuneWP)(\d+)/i.exec(ua) || 0)[1])) {
name += ' Mobile';
os = 'Windows Phone OS ' + data + '.x';
description.unshift('desktop mode');
}
// add mobile postfix
else if ((name == 'IE' || name && !product && !/Browser|Mobi/.test(name)) &&
(os == 'Windows CE' || /Mobi/i.test(ua))) {
name += ' Mobile';
}
// detect IE platform preview
else if (name == 'IE' && useFeatures && typeof external == 'object' && !external) {
description.unshift('platform preview');
}
// detect BlackBerry OS version
// http://docs.blackberry.com/en/developers/deliverables/18169/HTTP_headers_sent_by_BB_Browser_1234911_11.jsp
else if (/BlackBerry/.test(product) && (data =
(RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] ||
version)) {
os = 'Device Software ' + data;
version = null;
}
// detect Opera identifying/masking itself as another browser
// http://www.opera.com/support/kb/view/843/
else if (this != forOwn && (
(useFeatures && opera) ||
(/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) ||
(name == 'Firefox' && /OS X (?:\d+\.){2,}/.test(os)) ||
(name == 'IE' && (
(os && !/^Win/.test(os) && version > 5.5) ||
/Windows XP/.test(os) && version > 8 ||
version == 8 && !/Trident/.test(ua)
))
) && !reOpera.test(data = parse.call(forOwn, ua.replace(reOpera, '') + ';')) && data.name) {
// when "indentifying", the UA contains both Opera and the other browser's name
data = 'ing as ' + data.name + ((data = data.version) ? ' ' + data : '');
if (reOpera.test(name)) {
if (/IE/.test(data) && os == 'Mac OS') {
os = null;
}
data = 'identify' + data;
}
// when "masking", the UA contains only the other browser's name
else {
data = 'mask' + data;
if (operaClass) {
name = format(operaClass.replace(/([a-z])([A-Z])/g, '$1 $2'));
} else {
name = 'Opera';
}
if (/IE/.test(data)) {
os = null;
}
if (!useFeatures) {
version = null;
}
}
layout = ['Presto'];
description.push(data);
}
// detect WebKit Nightly and approximate Chrome/Safari versions
if ((data = (/\bAppleWebKit\/([\d.]+\+?)/i.exec(ua) || 0)[1])) {
// correct build for numeric comparison
// (e.g. "532.5" becomes "532.05")
data = [parseFloat(data.replace(/\.(\d)$/, '.0$1')), data];
// nightly builds are postfixed with a `+`
if (name == 'Safari' && data[1].slice(-1) == '+') {
name = 'WebKit Nightly';
prerelease = 'alpha';
version = data[1].slice(0, -1);
}
// clear incorrect browser versions
else if (version == data[1] ||
version == (/\bSafari\/([\d.]+\+?)/i.exec(ua) || 0)[1]) {
version = null;
}
// use the full Chrome version when available
data = [data[0], (/\bChrome\/([\d.]+)/i.exec(ua) || 0)[1]];
// detect JavaScriptCore
// http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androi
if (!useFeatures || (/internal|\n/i.test(toString.toString()) && !data[1])) {
layout[1] = 'like Safari';
data = (data = data[0], data < 400 ? 1 : data < 500 ? 2 : data < 526 ? 3 : data < 533 ? 4 : data < 534 ? '4+' : data < 535 ? 5 : '5');
} else {
layout[1] = 'like Chrome';
data = data[1] || (data = data[0], data < 530 ? 1 : data < 532 ? 2 : data < 532.05 ? 3 : data < 533 ? 4 : data < 534.03 ? 5 : data < 534.07 ? 6 : data < 534.10 ? 7 : data < 534.13 ? 8 : data < 534.16 ? 9 : data < 534.24 ? 10 : data < 534.30 ? 11 : data < 535.01 ? 12 : data < 535.02 ? '13+' : data < 535.07 ? 15 : data < 535.11 ? 16 : data < 535.19 ? 17 : data < 536.05 ? 18 : data < 536.10 ? 19 : data < 537.01 ? 20 : '21');
}
// add the postfix of ".x" or "+" for approximate versions
layout[1] += ' ' + (data += typeof data == 'number' ? '.x' : /[.+]/.test(data) ? '' : '+');
// obscure version for some Safari 1-2 releases
if (name == 'Safari' && (!version || parseInt(version) > 45)) {
version = data;
}
}
// detect Opera desktop modes
if (name == 'Opera' && (data = /(?:zbov|zvav)$/.exec(os))) {
name += ' ';
description.unshift('desktop mode');
if (data == 'zvav') {
name += 'Mini';
version = null;
} else {
name += 'Mobile';
}
}
// detect Chrome desktop mode
else if (name == 'Safari' && /Chrome/.exec(layout[1])) {
description.unshift('desktop mode');
name = 'Chrome Mobile';
version = null;
if (/Mac OS X/.test(os)) {
manufacturer = 'Apple';
os = 'iOS 4.3+';
} else {
os = null;
}
}
// strip incorrect OS versions
if (version && version.indexOf(data = /[\d.]+$/.exec(os)) == 0 &&
ua.indexOf('/' + data + '-') > -1) {
os = trim(os.replace(data, ''));
}
// add layout engine
if (layout && !/Avant|Nook/.test(name) && (
/Browser|Lunascape|Maxthon/.test(name) ||
/^(?:Adobe|Arora|Midori|Phantom|Rekonq|Rock|Sleipnir|Web)/.test(name) && layout[1])) {
// don't add layout details to description if they are falsey
(data = layout[layout.length - 1]) && description.push(data);
}
// combine contextual information
if (description.length) {
description = ['(' + description.join('; ') + ')'];
}
// append manufacturer
if (manufacturer && product && product.indexOf(manufacturer) < 0) {
description.push('on ' + manufacturer);
}
// append product
if (product) {
description.push((/^on /.test(description[description.length -1]) ? '' : 'on ') + product);
}
// parse OS into an object
if (os) {
data = / ([\d.+]+)$/.exec(os);
os = {
'architecture': 32,
'family': data ? os.replace(data[0], '') : os,
'version': data ? data[1] : null,
'toString': function() {
var version = this.version;
return this.family + (version ? ' ' + version : '') + (this.architecture == 64 ? ' 64-bit' : '');
}
};
}
// add browser/OS architecture
if ((data = /\b(?:AMD|IA|Win|WOW|x86_|x)64\b/i.exec(arch)) && !/\bi686\b/i.test(arch)) {
if (os) {
os.architecture = 64;
os.family = os.family.replace(RegExp(' *' + data), '');
}
if (name && (/WOW64/i.test(ua) ||
(useFeatures && /\w(?:86|32)$/.test(nav.cpuClass || nav.platform)))) {
description.unshift('32-bit');
}
}
ua || (ua = null);
/*------------------------------------------------------------------------*/
/**
* The platform object.
*
* @name platform
* @type Object
*/
return {
/**
* The browser/environment version.
*
* @memberOf platform
* @type String|Null
*/
'version': name && version && (description.unshift(version), version),
/**
* The name of the browser/environment.
*
* @memberOf platform
* @type String|Null
*/
'name': name && (description.unshift(name), name),
/**
* The name of the operating system.
*
* @memberOf platform
* @type Object
*/
'os': os
? (name &&
!(os == String(os).split(' ')[0] && (os == name.split(' ')[0] || product)) &&
description.push(product ? '(' + os + ')' : 'on ' + os), os)
: {
/**
* The CPU architecture the OS is built for.
*
* @memberOf platform.os
* @type String|Null
*/
'architecture': null,
/**
* The family of the OS.
*
* @memberOf platform.os
* @type String|Null
*/
'family': null,
/**
* The version of the OS.
*
* @memberOf platform.os
* @type String|Null
*/
'version': null,
/**
* Returns the OS string.
*
* @memberOf platform.os
* @returns {String} The OS string.
*/
'toString': function() { return 'null'; }
},
/**
* The platform description.
*
* @memberOf platform
* @type String|Null
*/
'description': description.length ? description.join(' ') : ua,
/**
* The name of the browser layout engine.
*
* @memberOf platform
* @type String|Null
*/
'layout': layout && layout[0],
/**
* The name of the product's manufacturer.
*
* @memberOf platform
* @type String|Null
*/
'manufacturer': manufacturer,
/**
* The alpha/beta release indicator.
*
* @memberOf platform
* @type String|Null
*/
'prerelease': prerelease,
/**
* The name of the product hosting the browser.
*
* @memberOf platform
* @type String|Null
*/
'product': product,
/**
* The browser's user agent string.
*
* @memberOf platform
* @type String|Null
*/
'ua': ua,
// parses a user agent string into a platform object
'parse': parse,
// returns the platform description
'toString': toStringPlatform
};
}
/*--------------------------------------------------------------------------*/
// expose platform
// some AMD build optimizers, like r.js, check for specific condition patterns like the following:
if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
// define as an anonymous module so, through path mapping, it can be aliased
define(function() {
return parse();
});
}
// check for `exports` after `define` in case a build optimizer adds an `exports` object
else if (freeExports) {
// in Narwhal, Node.js, or RingoJS
forOwn(parse(), function(value, key) {
freeExports[key] = value;
});
}
// in a browser or Rhino
else {
// use square bracket notation so Closure Compiler won't munge `platform`
// http://code.google.com/closure/compiler/docs/api-tutorial3.html#export
window['platform'] = parse();
}
}(this));

1
vendor/qunit vendored

Submodule vendor/qunit deleted from 3f5e8b2123

1
vendor/qunit-clib vendored

Submodule vendor/qunit-clib deleted from 2ed9f21633

20
vendor/qunit-clib/LICENSE.txt vendored Normal file
View File

@@ -0,0 +1,20 @@
Copyright 2011-2012 John-David Dalton <http://allyoucanleet.com/>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

57
vendor/qunit-clib/README.md vendored Normal file
View File

@@ -0,0 +1,57 @@
# QUnit CLIB <sup>v1.0.0</sup>
## command-line interface boilerplate
QUnit CLIB helps extend QUnit's CLI support to many common CLI environments.
## Screenshot
![QUnit CLIB brings QUnit to your favorite shell.](http://i.imgur.com/jpu9l.png)
## Support
QUnit CLIB has been tested in at least Node.js 0.4.8-0.8.6, Narwhal v0.3.2, RingoJS v0.8.0, and Rhino v1.7RC3-RC5.
## Usage
```js
(function(window) {
// use a single load function
var load = typeof require == 'function' ? require : window.load;
// load QUnit and CLIB if needed
var QUnit =
window.QUnit || (
window.setTimeout || (window.addEventListener = window.setTimeout = / /),
window.QUnit = load('path/to/qunit.js') || window.QUnit,
load('path/to/qunit-clib.js'),
(window.addEventListener || 0).test && delete window.addEventListener,
window.QUnit
);
// explicitly call `QUnit.module()` instead of `module()`
// in case we are in a CLI environment
QUnit.module('A Test Module');
test('A Test', function() {
// ...
});
// must call `QUnit.start()` if using QUnit < 1.3.0 with Node.js or any
// version of QUnit with Narwhal, Rhino, or RingoJS
if (!window.document) {
QUnit.start();
}
}(typeof global == 'object' && global || this));
```
## Footnotes
1. QUnit v1.3.0 does not work with Narwhal or Ringo < v0.8.0
2. Rhino v1.7RC4 does not support timeout fallbacks `clearTimeout` and `setTimeout`
## Author
* [John-David Dalton](http://allyoucanleet.com/)
[![twitter/jdalton](http://gravatar.com/avatar/299a3d891ff1920b69c364d061007043?s=70)](https://twitter.com/jdalton "Follow @jdalton on Twitter")

324
vendor/qunit-clib/qunit-clib.js vendored Normal file
View File

@@ -0,0 +1,324 @@
/*!
* QUnit CLI Boilerplate v1.0.0
* Copyright 2011-2012 John-David Dalton <http://allyoucanleet.com/>
* Based on a gist by Jörn Zaefferer <https://gist.github.com/722381>
* Available under MIT license <http://mths.be/mit>
*/
;(function(global) {
'use strict';
/** Add `console.log()` support for Narwhal, Rhino, and RingoJS */
global.console || (global.console = { 'log': global.print });
/** Reduce global.QUnit.QUnit -> global.QUnit */
global.QUnit && (QUnit = QUnit.QUnit || QUnit);
/*--------------------------------------------------------------------------*/
/** Used as a horizontal rule in console output */
var hr = '----------------------------------------';
/** Shortcut used to convert array-like objects to arrays */
var slice = [].slice;
/** Used to resolve a value's internal [[Class]] */
var toString = {}.toString;
/** Used by timer methods */
var doneCalled,
timer,
counter = 0,
ids = {};
/*--------------------------------------------------------------------------*/
/**
* An iteration utility for arrays.
*
* @private
* @param {Array} array The array to iterate over.
* @param {Function} callback The function called per iteration.
*/
function each(array, callback) {
var index = -1,
length = array.length;
while (++index < length) {
callback(array[index], index, array);
}
}
/**
* Checks if the specified `value` is a function.
*
* @private
* @param {Mixed} value The value to check.
* @returns {Boolean} Returns `true` if `value` is a function, else `false`.
*/
function isFunction(value) {
return toString.call(value) == '[object Function]';
}
/*--------------------------------------------------------------------------*/
/**
* Timeout fallbacks based on the work of Andrea Giammarchi and Weston C.
* https://github.com/WebReflection/wru/blob/master/src/rhinoTimers.js
* http://stackoverflow.com/questions/2261705/how-to-run-a-javascript-function-asynchronously-without-using-settimeout
*/
/**
* Clears the delay set by `setInterval` or `setTimeout`.
*
* @memberOf global
* @param {Number} id The ID of the timeout to be cleared.
*/
function clearTimer(id) {
if (ids[id]) {
ids[id].cancel();
timer.purge();
delete ids[id];
}
}
/**
* Schedules timer-based callbacks.
*
* @private
* @param {Function} fn The function to call.
* @oaram {Number} delay The number of milliseconds to delay the `fn` call.
* @param [arg1, arg2, ...] Arguments to invoke `fn` with.
* @param {Boolean} repeated A flag to specify whether `fn` is called repeatedly.
* @returns {Number} The the ID of the timeout.
*/
function schedule(fn, delay, args, repeated) {
// Rhino 1.7RC4 will error assigning `task` below
// https://bugzilla.mozilla.org/show_bug.cgi?id=775566
var task = ids[++counter] = new JavaAdapter(java.util.TimerTask, {
'run': function() {
fn.apply(global, args);
}
});
// support non-functions
if (!isFunction(fn)) {
fn = (function(code) {
code = String(code);
return function() { eval(code); };
}(fn));
}
// used by setInterval
if (repeated) {
timer.schedule(task, delay, delay);
}
// used by setTimeout
else {
timer.schedule(task, delay);
}
return counter;
}
/**
* Executes a code snippet or function repeatedly, with a delay between each call.
*
* @memberOf global
* @param {Function|String} fn The function to call or string to evaluate.
* @oaram {Number} delay The number of milliseconds to delay each `fn` call.
* @param [arg1, arg2, ...] Arguments to invoke `fn` with.
* @returns {Number} The the ID of the timeout.
*/
function setInterval(fn, delay) {
return schedule(fn, delay, slice.call(arguments, 2), true);
}
/**
* Executes a code snippet or a function after specified delay.
*
* @memberOf global
* @param {Function|String} fn The function to call or string to evaluate.
* @oaram {Number} delay The number of milliseconds to delay the `fn` call.
* @param [arg1, arg2, ...] Arguments to invoke `fn` with.
* @returns {Number} The the ID of the timeout.
*/
function setTimeout(fn, delay) {
return schedule(fn, delay, slice.call(arguments, 2));
}
/*--------------------------------------------------------------------------*/
/**
* A logging callback triggered when all testing is completed.
*
* @memberOf QUnit
* @param {Object} details An object with properties `failed`, `passed`,
* `runtime`, and `total`.
*/
function done(details) {
// stop `asyncTest()` from erroneously calling `done()` twice in
// environments w/o timeouts
if (doneCalled) {
return;
}
doneCalled = true;
console.log(hr);
console.log(' PASS: ' + details.passed + ' FAIL: ' + details.failed + ' TOTAL: ' + details.total);
console.log(' Finished in ' + details.runtime + ' milliseconds.');
console.log(hr);
// exit out of Rhino
try {
quit();
} catch(e) { }
// exit out of Node.js
try {
if (details.failed) {
console.error('Error: ' + details.failed + ' of ' + details.total + ' tests failed.');
process.exit(1);
} else {
process.exit(0);
}
} catch(e) { }
}
/**
* A logging callback triggered after every assertion.
*
* @memberOf QUnit
* @param {Object} details An object with properties `actual`, `expected`,
* `message`, and `result`.
*/
function log(details) {
var expected = details.expected,
result = details.result,
type = typeof expected != 'undefined' ? 'EQ' : 'OK';
var assertion = [
result ? 'PASS' : 'FAIL',
type,
details.message || 'ok'
];
if (!result && type == 'EQ') {
assertion.push('Expected: ' + expected + ', Actual: ' + details.actual);
}
QUnit.config.testStats.assertions.push(assertion.join(' | '));
}
/**
* A logging callback triggered at the start of every test module.
*
* @memberOf QUnit
* @param {Object} details An object with property `name`.
*/
function moduleStart(details) {
console.log(hr);
console.log(details.name);
console.log(hr);
}
/**
* Converts an object into a string representation.
*
* @memberOf QUnit
* @type Function
* @param {Object} object The object to stringify.
* @returns {String} The result string.
*/
var parseObject = (function() {
var func = QUnit.jsDump.parsers.object;
return function(object) {
// fork to support Rhino's error objects
if (typeof object.rhinoException == 'object') {
return object.name +
' { message: "' + object.message +
'", fileName: "' + object.fileName +
'", lineNumber: ' + object.lineNumber + ' }';
}
return func(object);
};
}());
/**
* A logging callback triggered after a test is completed.
*
* @memberOf QUnit
* @param {Object} details An object with properties `failed`, `name`,
* `passed`, and `total`.
*/
function testDone(details) {
var assertions = QUnit.config.testStats.assertions,
testName = details.name;
if (details.failed > 0) {
console.log(' FAIL - '+ testName);
each(assertions, function(value) {
console.log(' ' + value);
});
}
else {
console.log(' PASS - ' + testName);
}
assertions.length = 0;
}
/*--------------------------------------------------------------------------*/
/**
* An object used to hold information about the current running test.
*
* @memberOf QUnit.config
* @type Object
*/
QUnit.config.testStats = {
/**
* An array of test summaries (pipe separated).
*
* @memberOf QUnit.config.testStats
* @type Array
*/
'assertions': []
};
// add shortcuts to the global
// exclude `module` because some environments have it as a built-in object
each(['asyncTest', 'deepEqual', 'equal', 'equals', 'expect', 'notDeepEqual',
'notEqual', 'notStrictEqual', 'ok', 'raises', 'same', 'start', 'stop',
'strictEqual', 'test', 'throws'], function(funcName) {
var func = QUnit[funcName];
if (func) {
global[funcName] = func;
}
});
// expose timer methods to global
try {
timer = new java.util.Timer;
if (!isFunction(global.clearInterval)) {
global.clearInterval = clearTimer;
}
if (!isFunction(global.clearTimeout)) {
global.clearTimeout = clearTimer;
}
if (!isFunction(global.setInterval)) {
global.setInterval = setInterval;
}
if (!isFunction(global.setTimeout)) {
global.setTimeout = setTimeout;
}
} catch(e) { }
// add callbacks
QUnit.done(done);
QUnit.log(log);
QUnit.moduleStart(moduleStart);
QUnit.testDone(testDone);
// add wrapped function
QUnit.jsDump.parsers.object = parseObject;
// must call `QUnit.start()` in the test file if using QUnit < 1.3.0 with
// Node.js or any version of QUnit with Narwhal, Rhino, or RingoJS
QUnit.init();
}(typeof global == 'object' && global || this));

59
vendor/qunit/README.md vendored Normal file
View File

@@ -0,0 +1,59 @@
[QUnit](http://qunitjs.com) - A JavaScript Unit Testing framework.
================================
QUnit is a powerful, easy-to-use, JavaScript test suite. It's used by the jQuery
project to test its code and plugins but is capable of testing any generic
JavaScript code (and even capable of testing JavaScript code on the server-side).
QUnit is especially useful for regression testing: Whenever a bug is reported,
write a test that asserts the existence of that particular bug. Then fix it and
commit both. Every time you work on the code again, run the tests. If the bug
comes up again - a regression - you'll spot it immediately and know how to fix
it, because you know what code you just changed.
Having good unit test coverage makes safe refactoring easy and cheap. You can
run the tests after each small refactoring step and always know what change
broke something.
QUnit is similar to other unit testing frameworks like JUnit, but makes use of
the features JavaScript provides and helps with testing code in the browser, e.g.
with its stop/start facilities for testing asynchronous code.
If you are interested in helping developing QUnit, you are in the right place.
For related discussions, visit the
[QUnit and Testing forum](http://forum.jquery.com/qunit-and-testing).
Planning for a qunitjs.com site and other testing tools related work now happens
on the [jQuery Testing Team planning wiki](http://jquerytesting.pbworks.com/w/page/41556026/FrontPage).
Development
-----------
To submit patches, fork the repository, create a branch for the change. Then implement
the change, run `grunt` to lint and test it, then commit, push and create a pull request.
Include some background for the change in the commit message and `Fixes #nnn`, referring
to the issue number you're addressing.
To run `grunt`, you need `node` and `npm`, then `npm install grunt -g`. That gives you a global
grunt binary. For additional grunt tasks, also run `npm install`.
Releases
--------
Install git-extras and run `git changelog` to update History.md.
Update qunit/qunit.js|css and package.json to the release version, commit and
tag, update them again to the next version, commit and push commits and tags
(`git push --tags origin master`).
Put the 'v' in front of the tag, e.g. `v1.8.0`. Clean up the changelog, removing merge commits
or whitespace cleanups.
To upload to code.jquery.com (replace $version accordingly):
scp -q qunit/qunit.js jqadmin@code.origin.jquery.com:/var/www/html/code.jquery.com/qunit/qunit-$version.js
scp -q qunit/qunit.css jqadmin@code.origin.jquery.com:/var/www/html/code.jquery.com/qunit/qunit-$version.css
Then update /var/www/html/code.jquery.com/index.html and purge it with:
curl -s http://code.origin.jquery.com/?reload

1863
vendor/qunit/qunit/qunit-1.8.0.js vendored Normal file

File diff suppressed because it is too large Load Diff

235
vendor/qunit/qunit/qunit.css vendored Normal file
View File

@@ -0,0 +1,235 @@
/**
* QUnit v1.10.0 - A JavaScript Unit Testing Framework
*
* http://qunitjs.com
*
* Copyright 2012 jQuery Foundation and other contributors
* Released under the MIT license.
* http://jquery.org/license
*/
/** Font Family and Sizes */
#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
}
#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
#qunit-tests { font-size: smaller; }
/** Resets */
#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
margin: 0;
padding: 0;
}
/** Header */
#qunit-header {
padding: 0.5em 0 0.5em 1em;
color: #8699a4;
background-color: #0d3349;
font-size: 1.5em;
line-height: 1em;
font-weight: normal;
border-radius: 5px 5px 0 0;
-moz-border-radius: 5px 5px 0 0;
-webkit-border-top-right-radius: 5px;
-webkit-border-top-left-radius: 5px;
}
#qunit-header a {
text-decoration: none;
color: #c2ccd1;
}
#qunit-header a:hover,
#qunit-header a:focus {
color: #fff;
}
#qunit-testrunner-toolbar label {
display: inline-block;
padding: 0 .5em 0 .1em;
}
#qunit-banner {
height: 5px;
}
#qunit-testrunner-toolbar {
padding: 0.5em 0 0.5em 2em;
color: #5E740B;
background-color: #eee;
overflow: hidden;
}
#qunit-userAgent {
padding: 0.5em 0 0.5em 2.5em;
background-color: #2b81af;
color: #fff;
text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
}
#qunit-modulefilter-container {
float: right;
}
/** Tests: Pass/Fail */
#qunit-tests {
list-style-position: inside;
}
#qunit-tests li {
padding: 0.4em 0.5em 0.4em 2.5em;
border-bottom: 1px solid #fff;
list-style-position: inside;
}
#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running {
display: none;
}
#qunit-tests li strong {
cursor: pointer;
}
#qunit-tests li a {
padding: 0.5em;
color: #c2ccd1;
text-decoration: none;
}
#qunit-tests li a:hover,
#qunit-tests li a:focus {
color: #000;
}
#qunit-tests ol {
margin-top: 0.5em;
padding: 0.5em;
background-color: #fff;
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
}
#qunit-tests table {
border-collapse: collapse;
margin-top: .2em;
}
#qunit-tests th {
text-align: right;
vertical-align: top;
padding: 0 .5em 0 0;
}
#qunit-tests td {
vertical-align: top;
}
#qunit-tests pre {
margin: 0;
white-space: pre-wrap;
word-wrap: break-word;
}
#qunit-tests del {
background-color: #e0f2be;
color: #374e0c;
text-decoration: none;
}
#qunit-tests ins {
background-color: #ffcaca;
color: #500;
text-decoration: none;
}
/*** Test Counts */
#qunit-tests b.counts { color: black; }
#qunit-tests b.passed { color: #5E740B; }
#qunit-tests b.failed { color: #710909; }
#qunit-tests li li {
padding: 5px;
background-color: #fff;
border-bottom: none;
list-style-position: inside;
}
/*** Passing Styles */
#qunit-tests li li.pass {
color: #3c510c;
background-color: #fff;
border-left: 10px solid #C6E746;
}
#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
#qunit-tests .pass .test-name { color: #366097; }
#qunit-tests .pass .test-actual,
#qunit-tests .pass .test-expected { color: #999999; }
#qunit-banner.qunit-pass { background-color: #C6E746; }
/*** Failing Styles */
#qunit-tests li li.fail {
color: #710909;
background-color: #fff;
border-left: 10px solid #EE5757;
white-space: pre;
}
#qunit-tests > li:last-child {
border-radius: 0 0 5px 5px;
-moz-border-radius: 0 0 5px 5px;
-webkit-border-bottom-right-radius: 5px;
-webkit-border-bottom-left-radius: 5px;
}
#qunit-tests .fail { color: #000000; background-color: #EE5757; }
#qunit-tests .fail .test-name,
#qunit-tests .fail .module-name { color: #000000; }
#qunit-tests .fail .test-actual { color: #EE5757; }
#qunit-tests .fail .test-expected { color: green; }
#qunit-banner.qunit-fail { background-color: #EE5757; }
/** Result */
#qunit-testresult {
padding: 0.5em 0.5em 0.5em 2.5em;
color: #2b81af;
background-color: #D2E0E6;
border-bottom: 1px solid white;
}
#qunit-testresult .module-name {
font-weight: bold;
}
/** Fixture */
#qunit-fixture {
position: absolute;
top: -10000px;
left: -10000px;
width: 1000px;
height: 1000px;
}

1977
vendor/qunit/qunit/qunit.js vendored Normal file

File diff suppressed because it is too large Load Diff

1
vendor/requirejs vendored

Submodule vendor/requirejs deleted from 07de481552

58
vendor/requirejs/LICENSE vendored Normal file
View File

@@ -0,0 +1,58 @@
RequireJS is released under two licenses: new BSD, and MIT. You may pick the
license that best suits your development needs. The text of both licenses are
provided below.
The "New" BSD License:
----------------------
Copyright (c) 2010-2011, The Dojo Foundation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the Dojo Foundation nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
MIT License
-----------
Copyright (c) 2010-2011, The Dojo Foundation
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

51
vendor/requirejs/README.md vendored Normal file
View File

@@ -0,0 +1,51 @@
# RequireJS
RequireJS loads plain JavaScript files as well as more defined modules. It is
optimized for in-browser use, including in
[a Web Worker](http://requirejs.org/docs/api.html#webworker), but it can be used
in other JavaScript environments, like Rhino and
[Node](http://requirejs.org/docs/node.html). It implements the
[Asynchronous Module](https://github.com/amdjs/amdjs-api/wiki/AMD)
API.
RequireJS uses plain script tags to load modules/files, so it should allow for
easy debugging. It can be used
[simply to load existing JavaScript files](http://requirejs.org/docs/api.html#jsfiles),
so you can add it to your existing project without having to re-write your
JavaScript files.
RequireJS includes [an optimization tool](http://requirejs.org/docs/optimization.html)
you can run as part of your packaging steps for deploying your code. The
optimization tool can combine and minify your JavaScript files to allow for
better performance.
If the JavaScript file defines a JavaScript module via
[define()](http://requirejs.org/docs/api.html#define), then there are other benefits
RequireJS can offer: [improvements over traditional CommonJS modules](http://requirejs.org/docs/commonjs.html)
and [loading multiple versions](http://requirejs.org/docs/api.html#multiversion)
of a module in a page. RequireJS also has a plugin system that supports features like
[i18n string bundles](http://requirejs.org/docs/api.html#i18n), and
[text file dependencies](http://requirejs.org/docs/api.html#text).
RequireJS does not have any dependencies on a JavaScript framework.
It is dual-licensed -- new BSD or MIT.
The standard require.js file is around 5.5KB when minified via Closure Compiler
and gzipped.
RequireJS works in IE 6+, Firefox 2+, Safari 3.2+, Chrome 3+, and Opera 10+.
[Latest Release](http://requirejs.org/docs/download.html)
## Directories
* **dist**: Scripts and assets to generate the requirejs.org docs, and for
generating a require.js release.
* **docs**: The raw HTML files for the requirejs.org docs. Only includes the
body of each page. Files in **dist** are used to generate a complete HTML page.
* **tests**: Tests for require.js.
* **testBaseUrl.js**: A file used in the tests inside **tests**. Purposely
placed outside the tests directory for testing paths that go outside a baseUrl.
* **updatesubs.sh**: Updates projects that depend on require.js Assumes the
projects are siblings to this directory and have specific names. Useful to
copy require.js to dependent projects easily while in development.

1993
vendor/requirejs/require.js vendored Normal file

File diff suppressed because it is too large Load Diff

1
vendor/uglifyjs vendored

Submodule vendor/uglifyjs deleted from ef4d776aed

1
vendor/underscore vendored

Submodule vendor/underscore deleted from 7229edc46e

22
vendor/underscore/LICENSE vendored Normal file
View File

@@ -0,0 +1,22 @@
Copyright (c) 2009-2012 Jeremy Ashkenas, DocumentCloud
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

19
vendor/underscore/README.md vendored Normal file
View File

@@ -0,0 +1,19 @@
__
/\ \ __
__ __ ___ \_\ \ __ _ __ ____ ___ ___ _ __ __ /\_\ ____
/\ \/\ \ /' _ `\ /'_ \ /'__`\/\ __\/ ,__\ / ___\ / __`\/\ __\/'__`\ \/\ \ /',__\
\ \ \_\ \/\ \/\ \/\ \ \ \/\ __/\ \ \//\__, `\/\ \__//\ \ \ \ \ \//\ __/ __ \ \ \/\__, `\
\ \____/\ \_\ \_\ \___,_\ \____\\ \_\\/\____/\ \____\ \____/\ \_\\ \____\/\_\ _\ \ \/\____/
\/___/ \/_/\/_/\/__,_ /\/____/ \/_/ \/___/ \/____/\/___/ \/_/ \/____/\/_//\ \_\ \/___/
\ \____/
\/___/
Underscore.js is a utility-belt library for JavaScript that provides
support for the usual functional suspects (each, map, reduce, filter...)
without extending any core JavaScript objects.
For Docs, License, Tests, and pre-packed downloads, see:
http://underscorejs.org
Many thanks to our contributors:
https://github.com/documentcloud/underscore/contributors

200
vendor/underscore/test/arrays.js vendored Normal file
View File

@@ -0,0 +1,200 @@
$(document).ready(function() {
module("Arrays");
test("first", function() {
equal(_.first([1,2,3]), 1, 'can pull out the first element of an array');
equal(_([1, 2, 3]).first(), 1, 'can perform OO-style "first()"');
equal(_.first([1,2,3], 0).join(', '), "", 'can pass an index to first');
equal(_.first([1,2,3], 2).join(', '), '1, 2', 'can pass an index to first');
equal(_.first([1,2,3], 5).join(', '), '1, 2, 3', 'can pass an index to first');
var result = (function(){ return _.first(arguments); })(4, 3, 2, 1);
equal(result, 4, 'works on an arguments object.');
result = _.map([[1,2,3],[1,2,3]], _.first);
equal(result.join(','), '1,1', 'works well with _.map');
result = (function() { return _.take([1,2,3], 2); })();
equal(result.join(','), '1,2', 'aliased as take');
equal(_.first(null), undefined, 'handles nulls');
});
test("rest", function() {
var numbers = [1, 2, 3, 4];
equal(_.rest(numbers).join(", "), "2, 3, 4", 'working rest()');
equal(_.rest(numbers, 0).join(", "), "1, 2, 3, 4", 'working rest(0)');
equal(_.rest(numbers, 2).join(', '), '3, 4', 'rest can take an index');
var result = (function(){ return _(arguments).tail(); })(1, 2, 3, 4);
equal(result.join(', '), '2, 3, 4', 'aliased as tail and works on arguments object');
result = _.map([[1,2,3],[1,2,3]], _.rest);
equal(_.flatten(result).join(','), '2,3,2,3', 'works well with _.map');
result = (function(){ return _(arguments).drop(); })(1, 2, 3, 4);
equal(result.join(', '), '2, 3, 4', 'aliased as drop and works on arguments object');
});
test("initial", function() {
equal(_.initial([1,2,3,4,5]).join(", "), "1, 2, 3, 4", 'working initial()');
equal(_.initial([1,2,3,4],2).join(", "), "1, 2", 'initial can take an index');
var result = (function(){ return _(arguments).initial(); })(1, 2, 3, 4);
equal(result.join(", "), "1, 2, 3", 'initial works on arguments object');
result = _.map([[1,2,3],[1,2,3]], _.initial);
equal(_.flatten(result).join(','), '1,2,1,2', 'initial works with _.map');
});
test("last", function() {
equal(_.last([1,2,3]), 3, 'can pull out the last element of an array');
equal(_.last([1,2,3], 0).join(', '), "", 'can pass an index to last');
equal(_.last([1,2,3], 2).join(', '), '2, 3', 'can pass an index to last');
equal(_.last([1,2,3], 5).join(', '), '1, 2, 3', 'can pass an index to last');
var result = (function(){ return _(arguments).last(); })(1, 2, 3, 4);
equal(result, 4, 'works on an arguments object');
result = _.map([[1,2,3],[1,2,3]], _.last);
equal(result.join(','), '3,3', 'works well with _.map');
equal(_.last(null), undefined, 'handles nulls');
});
test("compact", function() {
equal(_.compact([0, 1, false, 2, false, 3]).length, 3, 'can trim out all falsy values');
var result = (function(){ return _.compact(arguments).length; })(0, 1, false, 2, false, 3);
equal(result, 3, 'works on an arguments object');
});
test("flatten", function() {
var list = [1, [2], [3, [[[4]]]]];
deepEqual(_.flatten(list), [1,2,3,4], 'can flatten nested arrays');
deepEqual(_.flatten(list, true), [1,2,3,[[[4]]]], 'can shallowly flatten nested arrays');
var result = (function(){ return _.flatten(arguments); })(1, [2], [3, [[[4]]]]);
deepEqual(result, [1,2,3,4], 'works on an arguments object');
});
test("without", function() {
var list = [1, 2, 1, 0, 3, 1, 4];
equal(_.without(list, 0, 1).join(', '), '2, 3, 4', 'can remove all instances of an object');
var result = (function(){ return _.without(arguments, 0, 1); })(1, 2, 1, 0, 3, 1, 4);
equal(result.join(', '), '2, 3, 4', 'works on an arguments object');
var list = [{one : 1}, {two : 2}];
ok(_.without(list, {one : 1}).length == 2, 'uses real object identity for comparisons.');
ok(_.without(list, list[0]).length == 1, 'ditto.');
});
test("uniq", function() {
var list = [1, 2, 1, 3, 1, 4];
equal(_.uniq(list).join(', '), '1, 2, 3, 4', 'can find the unique values of an unsorted array');
var list = [1, 1, 1, 2, 2, 3];
equal(_.uniq(list, true).join(', '), '1, 2, 3', 'can find the unique values of a sorted array faster');
var list = [{name:'moe'}, {name:'curly'}, {name:'larry'}, {name:'curly'}];
var iterator = function(value) { return value.name; };
equal(_.map(_.uniq(list, false, iterator), iterator).join(', '), 'moe, curly, larry', 'can find the unique values of an array using a custom iterator');
equal(_.map(_.uniq(list, iterator), iterator).join(', '), 'moe, curly, larry', 'can find the unique values of an array using a custom iterator without specifying whether array is sorted');
var iterator = function(value) { return value +1; };
var list = [1, 2, 2, 3, 4, 4];
equal(_.uniq(list, true, iterator).join(', '), '1, 2, 3, 4', 'iterator works with sorted array');
var result = (function(){ return _.uniq(arguments); })(1, 2, 1, 3, 1, 4);
equal(result.join(', '), '1, 2, 3, 4', 'works on an arguments object');
});
test("intersection", function() {
var stooges = ['moe', 'curly', 'larry'], leaders = ['moe', 'groucho'];
equal(_.intersection(stooges, leaders).join(''), 'moe', 'can take the set intersection of two arrays');
equal(_(stooges).intersection(leaders).join(''), 'moe', 'can perform an OO-style intersection');
var result = (function(){ return _.intersection(arguments, leaders); })('moe', 'curly', 'larry');
equal(result.join(''), 'moe', 'works on an arguments object');
});
test("union", function() {
var result = _.union([1, 2, 3], [2, 30, 1], [1, 40]);
equal(result.join(' '), '1 2 3 30 40', 'takes the union of a list of arrays');
var result = _.union([1, 2, 3], [2, 30, 1], [1, 40, [1]]);
equal(result.join(' '), '1 2 3 30 40 1', 'takes the union of a list of nested arrays');
});
test("difference", function() {
var result = _.difference([1, 2, 3], [2, 30, 40]);
equal(result.join(' '), '1 3', 'takes the difference of two arrays');
var result = _.difference([1, 2, 3, 4], [2, 30, 40], [1, 11, 111]);
equal(result.join(' '), '3 4', 'takes the difference of three arrays');
});
test('zip', function() {
var names = ['moe', 'larry', 'curly'], ages = [30, 40, 50], leaders = [true];
var stooges = _.zip(names, ages, leaders);
equal(String(stooges), 'moe,30,true,larry,40,,curly,50,', 'zipped together arrays of different lengths');
});
test('object', function() {
var result = _.object(['moe', 'larry', 'curly'], [30, 40, 50]);
var shouldBe = {moe: 30, larry: 40, curly: 50};
ok(_.isEqual(result, shouldBe), 'two arrays zipped together into an object');
result = _.object([['one', 1], ['two', 2], ['three', 3]]);
shouldBe = {one: 1, two: 2, three: 3};
ok(_.isEqual(result, shouldBe), 'an array of pairs zipped together into an object');
var stooges = {moe: 30, larry: 40, curly: 50};
ok(_.isEqual(_.object(_.pairs(stooges)), stooges), 'an object converted to pairs and back to an object');
ok(_.isEqual(_.object(null), {}), 'handles nulls');
});
test("indexOf", function() {
var numbers = [1, 2, 3];
numbers.indexOf = null;
equal(_.indexOf(numbers, 2), 1, 'can compute indexOf, even without the native function');
var result = (function(){ return _.indexOf(arguments, 2); })(1, 2, 3);
equal(result, 1, 'works on an arguments object');
equal(_.indexOf(null, 2), -1, 'handles nulls properly');
var numbers = [10, 20, 30, 40, 50], num = 35;
var index = _.indexOf(numbers, num, true);
equal(index, -1, '35 is not in the list');
numbers = [10, 20, 30, 40, 50]; num = 40;
index = _.indexOf(numbers, num, true);
equal(index, 3, '40 is in the list');
numbers = [1, 40, 40, 40, 40, 40, 40, 40, 50, 60, 70]; num = 40;
index = _.indexOf(numbers, num, true);
equal(index, 1, '40 is in the list');
numbers = [1, 2, 3, 1, 2, 3, 1, 2, 3];
index = _.indexOf(numbers, 2, 5);
equal(index, 7, 'supports the fromIndex argument');
});
test("lastIndexOf", function() {
var numbers = [1, 0, 1];
equal(_.lastIndexOf(numbers, 1), 2);
numbers = [1, 0, 1, 0, 0, 1, 0, 0, 0];
numbers.lastIndexOf = null;
equal(_.lastIndexOf(numbers, 1), 5, 'can compute lastIndexOf, even without the native function');
equal(_.lastIndexOf(numbers, 0), 8, 'lastIndexOf the other element');
var result = (function(){ return _.lastIndexOf(arguments, 1); })(1, 0, 1, 0, 0, 1, 0, 0, 0);
equal(result, 5, 'works on an arguments object');
equal(_.indexOf(null, 2), -1, 'handles nulls properly');
numbers = [1, 2, 3, 1, 2, 3, 1, 2, 3];
index = _.lastIndexOf(numbers, 2, 2);
equal(index, 1, 'supports the fromIndex argument');
});
test("range", function() {
equal(_.range(0).join(''), '', 'range with 0 as a first argument generates an empty array');
equal(_.range(4).join(' '), '0 1 2 3', 'range with a single positive argument generates an array of elements 0,1,2,...,n-1');
equal(_.range(5, 8).join(' '), '5 6 7', 'range with two arguments a &amp; b, a&lt;b generates an array of elements a,a+1,a+2,...,b-2,b-1');
equal(_.range(8, 5).join(''), '', 'range with two arguments a &amp; b, b&lt;a generates an empty array');
equal(_.range(3, 10, 3).join(' '), '3 6 9', 'range with three arguments a &amp; b &amp; c, c &lt; b-a, a &lt; b generates an array of elements a,a+c,a+2c,...,b - (multiplier of a) &lt; c');
equal(_.range(3, 10, 15).join(''), '3', 'range with three arguments a &amp; b &amp; c, c &gt; b-a, a &lt; b generates an array with a single element, equal to a');
equal(_.range(12, 7, -2).join(' '), '12 10 8', 'range with three arguments a &amp; b &amp; c, a &gt; b, c &lt; 0 generates an array of elements a,a-c,a-2c and ends with the number not less than b');
equal(_.range(0, -10, -1).join(' '), '0 -1 -2 -3 -4 -5 -6 -7 -8 -9', 'final example in the Python docs');
});
});

59
vendor/underscore/test/chaining.js vendored Normal file
View File

@@ -0,0 +1,59 @@
$(document).ready(function() {
module("Chaining");
test("map/flatten/reduce", function() {
var lyrics = [
"I'm a lumberjack and I'm okay",
"I sleep all night and I work all day",
"He's a lumberjack and he's okay",
"He sleeps all night and he works all day"
];
var counts = _(lyrics).chain()
.map(function(line) { return line.split(''); })
.flatten()
.reduce(function(hash, l) {
hash[l] = hash[l] || 0;
hash[l]++;
return hash;
}, {}).value();
ok(counts['a'] == 16 && counts['e'] == 10, 'counted all the letters in the song');
});
test("select/reject/sortBy", function() {
var numbers = [1,2,3,4,5,6,7,8,9,10];
numbers = _(numbers).chain().select(function(n) {
return n % 2 == 0;
}).reject(function(n) {
return n % 4 == 0;
}).sortBy(function(n) {
return -n;
}).value();
equal(numbers.join(', '), "10, 6, 2", "filtered and reversed the numbers");
});
test("select/reject/sortBy in functional style", function() {
var numbers = [1,2,3,4,5,6,7,8,9,10];
numbers = _.chain(numbers).select(function(n) {
return n % 2 == 0;
}).reject(function(n) {
return n % 4 == 0;
}).sortBy(function(n) {
return -n;
}).value();
equal(numbers.join(', '), "10, 6, 2", "filtered and reversed the numbers");
});
test("reverse/concat/unshift/pop/map", function() {
var numbers = [1,2,3,4,5];
numbers = _(numbers).chain()
.reverse()
.concat([5, 5, 5])
.unshift(17)
.pop()
.map(function(n){ return n * 2; })
.value();
equal(numbers.join(', '), "34, 10, 8, 6, 4, 2, 10, 10", 'can chain together array functions.');
});
});

445
vendor/underscore/test/collections.js vendored Normal file
View File

@@ -0,0 +1,445 @@
$(document).ready(function() {
module("Collections");
test("each", function() {
_.each([1, 2, 3], function(num, i) {
equal(num, i + 1, 'each iterators provide value and iteration count');
});
var answers = [];
_.each([1, 2, 3], function(num){ answers.push(num * this.multiplier);}, {multiplier : 5});
equal(answers.join(', '), '5, 10, 15', 'context object property accessed');
answers = [];
_.forEach([1, 2, 3], function(num){ answers.push(num); });
equal(answers.join(', '), '1, 2, 3', 'aliased as "forEach"');
answers = [];
var obj = {one : 1, two : 2, three : 3};
obj.constructor.prototype.four = 4;
_.each(obj, function(value, key){ answers.push(key); });
equal(answers.join(", "), 'one, two, three', 'iterating over objects works, and ignores the object prototype.');
delete obj.constructor.prototype.four;
answer = null;
_.each([1, 2, 3], function(num, index, arr){ if (_.include(arr, num)) answer = true; });
ok(answer, 'can reference the original collection from inside the iterator');
answers = 0;
_.each(null, function(){ ++answers; });
equal(answers, 0, 'handles a null properly');
});
test('map', function() {
var doubled = _.map([1, 2, 3], function(num){ return num * 2; });
equal(doubled.join(', '), '2, 4, 6', 'doubled numbers');
doubled = _.collect([1, 2, 3], function(num){ return num * 2; });
equal(doubled.join(', '), '2, 4, 6', 'aliased as "collect"');
var tripled = _.map([1, 2, 3], function(num){ return num * this.multiplier; }, {multiplier : 3});
equal(tripled.join(', '), '3, 6, 9', 'tripled numbers with context');
var doubled = _([1, 2, 3]).map(function(num){ return num * 2; });
equal(doubled.join(', '), '2, 4, 6', 'OO-style doubled numbers');
if (document.querySelectorAll) {
var ids = _.map(document.querySelectorAll('#map-test *'), function(n){ return n.id; });
deepEqual(ids, ['id1', 'id2'], 'Can use collection methods on NodeLists.');
}
var ids = _.map($('#map-test').children(), function(n){ return n.id; });
deepEqual(ids, ['id1', 'id2'], 'Can use collection methods on jQuery Array-likes.');
var ids = _.map(document.images, function(n){ return n.id; });
ok(ids[0] == 'chart_image', 'can use collection methods on HTMLCollections');
var ifnull = _.map(null, function(){});
ok(_.isArray(ifnull) && ifnull.length === 0, 'handles a null properly');
});
test('reduce', function() {
var sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num; }, 0);
equal(sum, 6, 'can sum up an array');
var context = {multiplier : 3};
sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num * this.multiplier; }, 0, context);
equal(sum, 18, 'can reduce with a context object');
sum = _.inject([1, 2, 3], function(sum, num){ return sum + num; }, 0);
equal(sum, 6, 'aliased as "inject"');
sum = _([1, 2, 3]).reduce(function(sum, num){ return sum + num; }, 0);
equal(sum, 6, 'OO-style reduce');
var sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num; });
equal(sum, 6, 'default initial value');
var ifnull;
try {
_.reduce(null, function(){});
} catch (ex) {
ifnull = ex;
}
ok(ifnull instanceof TypeError, 'handles a null (without inital value) properly');
ok(_.reduce(null, function(){}, 138) === 138, 'handles a null (with initial value) properly');
equal(_.reduce([], function(){}, undefined), undefined, 'undefined can be passed as a special case');
raises(function() { _.reduce([], function(){}); }, TypeError, 'throws an error for empty arrays with no initial value');
});
test('reduceRight', function() {
var list = _.reduceRight(["foo", "bar", "baz"], function(memo, str){ return memo + str; }, '');
equal(list, 'bazbarfoo', 'can perform right folds');
var list = _.foldr(["foo", "bar", "baz"], function(memo, str){ return memo + str; }, '');
equal(list, 'bazbarfoo', 'aliased as "foldr"');
var list = _.foldr(["foo", "bar", "baz"], function(memo, str){ return memo + str; });
equal(list, 'bazbarfoo', 'default initial value');
var ifnull;
try {
_.reduceRight(null, function(){});
} catch (ex) {
ifnull = ex;
}
ok(ifnull instanceof TypeError, 'handles a null (without inital value) properly');
var sum = _.reduceRight({a: 1, b: 2, c: 3}, function(sum, num){ return sum + num; });
equal(sum, 6, 'default initial value on object');
ok(_.reduceRight(null, function(){}, 138) === 138, 'handles a null (with initial value) properly');
equal(_.reduceRight([], function(){}, undefined), undefined, 'undefined can be passed as a special case');
raises(function() { _.reduceRight([], function(){}); }, TypeError, 'throws an error for empty arrays with no initial value');
// Assert that the correct arguments are being passed.
var args,
memo = {},
object = {a: 1, b: 2},
lastKey = _.keys(object).pop();
var expected = lastKey == 'a'
? [memo, 1, 'a', object]
: [memo, 2, 'b', object];
_.reduceRight(object, function() {
args || (args = _.toArray(arguments));
}, memo);
deepEqual(args, expected);
// And again, with numeric keys.
object = {'2': 'a', '1': 'b'};
lastKey = _.keys(object).pop();
args = null;
expected = lastKey == '2'
? [memo, 'a', '2', object]
: [memo, 'b', '1', object];
_.reduceRight(object, function() {
args || (args = _.toArray(arguments));
}, memo);
deepEqual(args, expected);
});
test('find', function() {
var array = [1, 2, 3, 4];
strictEqual(_.find(array, function(n) { return n > 2; }), 3, 'should return first found `value`');
strictEqual(_.find(array, function() { return false; }), void 0, 'should return `undefined` if `value` is not found');
});
test('detect', function() {
var result = _.detect([1, 2, 3], function(num){ return num * 2 == 4; });
equal(result, 2, 'found the first "2" and broke the loop');
});
test('select', function() {
var evens = _.select([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
equal(evens.join(', '), '2, 4, 6', 'selected each even number');
evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
equal(evens.join(', '), '2, 4, 6', 'aliased as "filter"');
});
test('reject', function() {
var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
equal(odds.join(', '), '1, 3, 5', 'rejected each even number');
var context = "obj";
var evens = _.reject([1, 2, 3, 4, 5, 6], function(num){
equal(context, "obj");
return num % 2 != 0;
}, context);
equal(evens.join(', '), '2, 4, 6', 'rejected each odd number');
});
test('all', function() {
ok(_.all([], _.identity), 'the empty set');
ok(_.all([true, true, true], _.identity), 'all true values');
ok(!_.all([true, false, true], _.identity), 'one false value');
ok(_.all([0, 10, 28], function(num){ return num % 2 == 0; }), 'even numbers');
ok(!_.all([0, 11, 28], function(num){ return num % 2 == 0; }), 'an odd number');
ok(_.all([1], _.identity) === true, 'cast to boolean - true');
ok(_.all([0], _.identity) === false, 'cast to boolean - false');
ok(_.every([true, true, true], _.identity), 'aliased as "every"');
ok(!_.all([undefined, undefined, undefined], _.identity), 'works with arrays of undefined');
});
test('any', function() {
var nativeSome = Array.prototype.some;
Array.prototype.some = null;
ok(!_.any([]), 'the empty set');
ok(!_.any([false, false, false]), 'all false values');
ok(_.any([false, false, true]), 'one true value');
ok(_.any([null, 0, 'yes', false]), 'a string');
ok(!_.any([null, 0, '', false]), 'falsy values');
ok(!_.any([1, 11, 29], function(num){ return num % 2 == 0; }), 'all odd numbers');
ok(_.any([1, 10, 29], function(num){ return num % 2 == 0; }), 'an even number');
ok(_.any([1], _.identity) === true, 'cast to boolean - true');
ok(_.any([0], _.identity) === false, 'cast to boolean - false');
ok(_.some([false, false, true]), 'aliased as "some"');
Array.prototype.some = nativeSome;
});
test('include', function() {
ok(_.include([1,2,3], 2), 'two is in the array');
ok(!_.include([1,3,9], 2), 'two is not in the array');
ok(_.contains({moe:1, larry:3, curly:9}, 3) === true, '_.include on objects checks their values');
ok(_([1,2,3]).include(2), 'OO-style include');
});
test('invoke', function() {
var list = [[5, 1, 7], [3, 2, 1]];
var result = _.invoke(list, 'sort');
equal(result[0].join(', '), '1, 5, 7', 'first array sorted');
equal(result[1].join(', '), '1, 2, 3', 'second array sorted');
});
test('invoke w/ function reference', function() {
var list = [[5, 1, 7], [3, 2, 1]];
var result = _.invoke(list, Array.prototype.sort);
equal(result[0].join(', '), '1, 5, 7', 'first array sorted');
equal(result[1].join(', '), '1, 2, 3', 'second array sorted');
});
// Relevant when using ClojureScript
test('invoke when strings have a call method', function() {
String.prototype.call = function() {
return 42;
};
var list = [[5, 1, 7], [3, 2, 1]];
var s = "foo";
equal(s.call(), 42, "call function exists");
var result = _.invoke(list, 'sort');
equal(result[0].join(', '), '1, 5, 7', 'first array sorted');
equal(result[1].join(', '), '1, 2, 3', 'second array sorted');
delete String.prototype.call;
equal(s.call, undefined, "call function removed");
});
test('pluck', function() {
var people = [{name : 'moe', age : 30}, {name : 'curly', age : 50}];
equal(_.pluck(people, 'name').join(', '), 'moe, curly', 'pulls names out of objects');
});
test('where', function() {
var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}];
var result = _.where(list, {a: 1});
equal(result.length, 3);
equal(result[result.length - 1].b, 4);
result = _.where(list, {b: 2});
equal(result.length, 2);
equal(result[0].a, 1);
});
test('max', function() {
equal(3, _.max([1, 2, 3]), 'can perform a regular Math.max');
var neg = _.max([1, 2, 3], function(num){ return -num; });
equal(neg, 1, 'can perform a computation-based max');
equal(-Infinity, _.max({}), 'Maximum value of an empty object');
equal(-Infinity, _.max([]), 'Maximum value of an empty array');
equal(_.max({'a': 'a'}), -Infinity, 'Maximum value of a non-numeric collection');
equal(299999, _.max(_.range(1,300000)), "Maximum value of a too-big array");
});
test('min', function() {
equal(1, _.min([1, 2, 3]), 'can perform a regular Math.min');
var neg = _.min([1, 2, 3], function(num){ return -num; });
equal(neg, 3, 'can perform a computation-based min');
equal(Infinity, _.min({}), 'Minimum value of an empty object');
equal(Infinity, _.min([]), 'Minimum value of an empty array');
equal(_.min({'a': 'a'}), Infinity, 'Minimum value of a non-numeric collection');
var now = new Date(9999999999);
var then = new Date(0);
equal(_.min([now, then]), then);
equal(1, _.min(_.range(1,300000)), "Minimum value of a too-big array");
});
test('sortBy', function() {
var people = [{name : 'curly', age : 50}, {name : 'moe', age : 30}];
people = _.sortBy(people, function(person){ return person.age; });
equal(_.pluck(people, 'name').join(', '), 'moe, curly', 'stooges sorted by age');
var list = [undefined, 4, 1, undefined, 3, 2];
equal(_.sortBy(list, _.identity).join(','), '1,2,3,4,,', 'sortBy with undefined values');
var list = ["one", "two", "three", "four", "five"];
var sorted = _.sortBy(list, 'length');
equal(sorted.join(' '), 'one two four five three', 'sorted by length');
function Pair(x, y) {
this.x = x;
this.y = y;
}
var collection = [
new Pair(1, 1), new Pair(1, 2),
new Pair(1, 3), new Pair(1, 4),
new Pair(1, 5), new Pair(1, 6),
new Pair(2, 1), new Pair(2, 2),
new Pair(2, 3), new Pair(2, 4),
new Pair(2, 5), new Pair(2, 6),
new Pair(undefined, 1), new Pair(undefined, 2),
new Pair(undefined, 3), new Pair(undefined, 4),
new Pair(undefined, 5), new Pair(undefined, 6)
];
var actual = _.sortBy(collection, function(pair) {
return pair.x;
});
deepEqual(actual, collection, 'sortBy should be stable');
});
test('groupBy', function() {
var parity = _.groupBy([1, 2, 3, 4, 5, 6], function(num){ return num % 2; });
ok('0' in parity && '1' in parity, 'created a group for each value');
equal(parity[0].join(', '), '2, 4, 6', 'put each even number in the right group');
var list = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"];
var grouped = _.groupBy(list, 'length');
equal(grouped['3'].join(' '), 'one two six ten');
equal(grouped['4'].join(' '), 'four five nine');
equal(grouped['5'].join(' '), 'three seven eight');
var context = {};
_.groupBy([{}], function(){ ok(this === context); }, context);
grouped = _.groupBy([4.2, 6.1, 6.4], function(num) {
return Math.floor(num) > 4 ? 'hasOwnProperty' : 'constructor';
});
equal(grouped.constructor.length, 1);
equal(grouped.hasOwnProperty.length, 2);
var array = [{}];
_.groupBy(array, function(value, index, obj){ ok(obj === array); });
var array = [1, 2, 1, 2, 3];
var grouped = _.groupBy(array);
equal(grouped['1'].length, 2);
equal(grouped['3'].length, 1);
});
test('countBy', function() {
var parity = _.countBy([1, 2, 3, 4, 5], function(num){ return num % 2 == 0; });
equal(parity['true'], 2);
equal(parity['false'], 3);
var list = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"];
var grouped = _.countBy(list, 'length');
equal(grouped['3'], 4);
equal(grouped['4'], 3);
equal(grouped['5'], 3);
var context = {};
_.countBy([{}], function(){ ok(this === context); }, context);
grouped = _.countBy([4.2, 6.1, 6.4], function(num) {
return Math.floor(num) > 4 ? 'hasOwnProperty' : 'constructor';
});
equal(grouped.constructor, 1);
equal(grouped.hasOwnProperty, 2);
var array = [{}];
_.countBy(array, function(value, index, obj){ ok(obj === array); });
var array = [1, 2, 1, 2, 3];
var grouped = _.countBy(array);
equal(grouped['1'], 2);
equal(grouped['3'], 1);
});
test('sortedIndex', function() {
var numbers = [10, 20, 30, 40, 50], num = 35;
var indexForNum = _.sortedIndex(numbers, num);
equal(indexForNum, 3, '35 should be inserted at index 3');
var indexFor30 = _.sortedIndex(numbers, 30);
equal(indexFor30, 2, '30 should be inserted at index 2');
var objects = [{x: 10}, {x: 20}, {x: 30}, {x: 40}];
var iterator = function(obj){ return obj.x; };
strictEqual(_.sortedIndex(objects, {x: 25}, iterator), 2);
strictEqual(_.sortedIndex(objects, {x: 35}, 'x'), 3);
var context = {1: 2, 2: 3, 3: 4};
iterator = function(obj){ return this[obj]; };
strictEqual(_.sortedIndex([1, 3], 2, iterator, context), 1);
});
test('shuffle', function() {
var numbers = _.range(10);
var shuffled = _.shuffle(numbers).sort();
notStrictEqual(numbers, shuffled, 'original object is unmodified');
equal(shuffled.join(','), numbers.join(','), 'contains the same members before and after shuffle');
});
test('toArray', function() {
ok(!_.isArray(arguments), 'arguments object is not an array');
ok(_.isArray(_.toArray(arguments)), 'arguments object converted into array');
var a = [1,2,3];
ok(_.toArray(a) !== a, 'array is cloned');
equal(_.toArray(a).join(', '), '1, 2, 3', 'cloned array contains same elements');
var numbers = _.toArray({one : 1, two : 2, three : 3});
equal(numbers.join(', '), '1, 2, 3', 'object flattened into array');
// test in IE < 9
try {
var actual = _.toArray(document.childNodes);
} catch(ex) { }
ok(_.isArray(actual), 'should not throw converting a node list');
});
test('size', function() {
equal(_.size({one : 1, two : 2, three : 3}), 3, 'can compute the size of an object');
equal(_.size([1, 2, 3]), 3, 'can compute the size of an array');
var func = function() {
return _.size(arguments);
};
equal(func(1, 2, 3, 4), 4, 'can test the size of the arguments object');
equal(_.size('hello'), 5, 'can compute the size of a string');
equal(_.size(null), 0, 'handles nulls');
});
});

286
vendor/underscore/test/functions.js vendored Normal file
View File

@@ -0,0 +1,286 @@
$(document).ready(function() {
module("Functions");
test("bind", function() {
var context = {name : 'moe'};
var func = function(arg) { return "name: " + (this.name || arg); };
var bound = _.bind(func, context);
equal(bound(), 'name: moe', 'can bind a function to a context');
bound = _(func).bind(context);
equal(bound(), 'name: moe', 'can do OO-style binding');
bound = _.bind(func, null, 'curly');
equal(bound(), 'name: curly', 'can bind without specifying a context');
func = function(salutation, name) { return salutation + ': ' + name; };
func = _.bind(func, this, 'hello');
equal(func('moe'), 'hello: moe', 'the function was partially applied in advance');
var func = _.bind(func, this, 'curly');
equal(func(), 'hello: curly', 'the function was completely applied in advance');
var func = function(salutation, firstname, lastname) { return salutation + ': ' + firstname + ' ' + lastname; };
func = _.bind(func, this, 'hello', 'moe', 'curly');
equal(func(), 'hello: moe curly', 'the function was partially applied in advance and can accept multiple arguments');
func = function(context, message) { equal(this, context, message); };
_.bind(func, 0, 0, 'can bind a function to `0`')();
_.bind(func, '', '', 'can bind a function to an empty string')();
_.bind(func, false, false, 'can bind a function to `false`')();
// These tests are only meaningful when using a browser without a native bind function
// To test this with a modern browser, set underscore's nativeBind to undefined
var F = function () { return this; };
var Boundf = _.bind(F, {hello: "moe curly"});
var newBoundf = new Boundf();
equal(newBoundf.hello, undefined, "function should not be bound to the context, to comply with ECMAScript 5");
equal(Boundf().hello, "moe curly", "When called without the new operator, it's OK to be bound to the context");
ok(newBoundf instanceof F, "a bound instance is an instance of the original function");
});
test("bindAll", function() {
var curly = {name : 'curly'}, moe = {
name : 'moe',
getName : function() { return 'name: ' + this.name; },
sayHi : function() { return 'hi: ' + this.name; }
};
curly.getName = moe.getName;
_.bindAll(moe, 'getName', 'sayHi');
curly.sayHi = moe.sayHi;
equal(curly.getName(), 'name: curly', 'unbound function is bound to current object');
equal(curly.sayHi(), 'hi: moe', 'bound function is still bound to original object');
curly = {name : 'curly'};
moe = {
name : 'moe',
getName : function() { return 'name: ' + this.name; },
sayHi : function() { return 'hi: ' + this.name; }
};
_.bindAll(moe);
curly.sayHi = moe.sayHi;
equal(curly.sayHi(), 'hi: moe', 'calling bindAll with no arguments binds all functions to the object');
});
test("memoize", function() {
var fib = function(n) {
return n < 2 ? n : fib(n - 1) + fib(n - 2);
};
var fastFib = _.memoize(fib);
equal(fib(10), 55, 'a memoized version of fibonacci produces identical results');
equal(fastFib(10), 55, 'a memoized version of fibonacci produces identical results');
var o = function(str) {
return str;
};
var fastO = _.memoize(o);
equal(o('toString'), 'toString', 'checks hasOwnProperty');
equal(fastO('toString'), 'toString', 'checks hasOwnProperty');
});
asyncTest("delay", 2, function() {
var delayed = false;
_.delay(function(){ delayed = true; }, 100);
setTimeout(function(){ ok(!delayed, "didn't delay the function quite yet"); }, 50);
setTimeout(function(){ ok(delayed, 'delayed the function'); start(); }, 150);
});
asyncTest("defer", 1, function() {
var deferred = false;
_.defer(function(bool){ deferred = bool; }, true);
_.delay(function(){ ok(deferred, "deferred the function"); start(); }, 50);
});
asyncTest("throttle", 2, function() {
var counter = 0;
var incr = function(){ counter++; };
var throttledIncr = _.throttle(incr, 100);
throttledIncr(); throttledIncr(); throttledIncr();
setTimeout(throttledIncr, 70);
setTimeout(throttledIncr, 120);
setTimeout(throttledIncr, 140);
setTimeout(throttledIncr, 190);
setTimeout(throttledIncr, 220);
setTimeout(throttledIncr, 240);
_.delay(function(){ equal(counter, 1, "incr was called immediately"); }, 30);
_.delay(function(){ equal(counter, 4, "incr was throttled"); start(); }, 400);
});
asyncTest("throttle arguments", 2, function() {
var value = 0;
var update = function(val){ value = val; };
var throttledUpdate = _.throttle(update, 100);
throttledUpdate(1); throttledUpdate(2); throttledUpdate(3);
setTimeout(function(){ throttledUpdate(4); }, 120);
setTimeout(function(){ throttledUpdate(5); }, 140);
setTimeout(function(){ throttledUpdate(6); }, 250);
_.delay(function(){ equal(value, 1, "updated to latest value"); }, 40);
_.delay(function(){ equal(value, 6, "updated to latest value"); start(); }, 400);
});
asyncTest("throttle once", 2, function() {
var counter = 0;
var incr = function(){ return ++counter; };
var throttledIncr = _.throttle(incr, 100);
var result = throttledIncr();
_.delay(function(){
equal(result, 1, "throttled functions return their value");
equal(counter, 1, "incr was called once"); start();
}, 220);
});
asyncTest("throttle twice", 1, function() {
var counter = 0;
var incr = function(){ counter++; };
var throttledIncr = _.throttle(incr, 100);
throttledIncr(); throttledIncr();
_.delay(function(){ equal(counter, 2, "incr was called twice"); start(); }, 220);
});
asyncTest("throttle repeatedly with results", 9, function() {
var counter = 0;
var incr = function(){ return ++counter; };
var throttledIncr = _.throttle(incr, 100);
var results = [];
var saveResult = function() { results.push(throttledIncr()); };
saveResult(); saveResult(); saveResult();
setTimeout(saveResult, 70);
setTimeout(saveResult, 120);
setTimeout(saveResult, 140);
setTimeout(saveResult, 190);
setTimeout(saveResult, 240);
setTimeout(saveResult, 260);
_.delay(function() {
equal(results[0], 1, "incr was called once");
equal(results[1], 1, "incr was throttled");
equal(results[2], 1, "incr was throttled");
equal(results[3], 1, "incr was throttled");
equal(results[4], 2, "incr was called twice");
equal(results[5], 2, "incr was throttled");
equal(results[6], 2, "incr was throttled");
equal(results[7], 3, "incr was called thrice");
equal(results[8], 3, "incr was throttled");
start();
}, 400);
});
asyncTest("throttle triggers trailing call after repeatedly invoked", 2, function() {
var actual;
var counter = 0;
var limit = 80;
var incr = function(){ counter++; };
var throttledIncr = _.throttle(incr, 32);
var stamp = new Date;
while ((new Date - stamp) < limit) {
throttledIncr();
}
_.delay(function() {
actual = counter + 2;
throttledIncr();
throttledIncr();
}, 64);
_.delay(function() {
equal(counter, actual);
start();
}, 128);
ok(counter > 1);
});
asyncTest("debounce", 1, function() {
var counter = 0;
var incr = function(){ counter++; };
var debouncedIncr = _.debounce(incr, 50);
debouncedIncr(); debouncedIncr(); debouncedIncr();
setTimeout(debouncedIncr, 30);
setTimeout(debouncedIncr, 60);
setTimeout(debouncedIncr, 90);
setTimeout(debouncedIncr, 120);
setTimeout(debouncedIncr, 150);
_.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 220);
});
asyncTest("debounce asap", 5, function() {
var a, b, c;
var counter = 0;
var incr = function(){ return ++counter; };
var debouncedIncr = _.debounce(incr, 50, true);
a = debouncedIncr();
b = debouncedIncr();
c = debouncedIncr();
equal(a, 1);
equal(b, 1);
equal(c, 1);
equal(counter, 1, 'incr was called immediately');
setTimeout(debouncedIncr, 30);
setTimeout(debouncedIncr, 60);
setTimeout(debouncedIncr, 90);
setTimeout(debouncedIncr, 120);
setTimeout(debouncedIncr, 150);
_.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 220);
});
asyncTest("debounce asap recursively", 2, function() {
var counter = 0;
var debouncedIncr = _.debounce(function(){
counter++;
if (counter < 5) debouncedIncr();
}, 50, true);
debouncedIncr();
equal(counter, 1, 'incr was called immediately');
_.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 70);
});
test("once", function() {
var num = 0;
var increment = _.once(function(){ num++; });
increment();
increment();
equal(num, 1);
});
test("wrap", function() {
var greet = function(name){ return "hi: " + name; };
var backwards = _.wrap(greet, function(func, name){ return func(name) + ' ' + name.split('').reverse().join(''); });
equal(backwards('moe'), 'hi: moe eom', 'wrapped the saluation function');
var inner = function(){ return "Hello "; };
var obj = {name : "Moe"};
obj.hi = _.wrap(inner, function(fn){ return fn() + this.name; });
equal(obj.hi(), "Hello Moe");
var noop = function(){};
var wrapped = _.wrap(noop, function(fn){ return Array.prototype.slice.call(arguments, 0); });
var ret = wrapped(['whats', 'your'], 'vector', 'victor');
deepEqual(ret, [noop, ['whats', 'your'], 'vector', 'victor']);
});
test("compose", function() {
var greet = function(name){ return "hi: " + name; };
var exclaim = function(sentence){ return sentence + '!'; };
var composed = _.compose(exclaim, greet);
equal(composed('moe'), 'hi: moe!', 'can compose a function that takes another');
composed = _.compose(greet, exclaim);
equal(composed('moe'), 'hi: moe!', 'in this case, the functions are also commutative');
});
test("after", function() {
var testAfter = function(afterAmount, timesCalled) {
var afterCalled = 0;
var after = _.after(afterAmount, function() {
afterCalled++;
});
while (timesCalled--) after();
return afterCalled;
};
equal(testAfter(5, 5), 1, "after(N) should fire after being called N times");
equal(testAfter(5, 4), 0, "after(N) should not fire unless called N times");
equal(testAfter(0, 0), 1, "after(0) should fire immediately");
});
});

558
vendor/underscore/test/objects.js vendored Normal file
View File

@@ -0,0 +1,558 @@
$(document).ready(function() {
module("Objects");
test("keys", function() {
equal(_.keys({one : 1, two : 2}).join(', '), 'one, two', 'can extract the keys from an object');
// the test above is not safe because it relies on for-in enumeration order
var a = []; a[1] = 0;
equal(_.keys(a).join(', '), '1', 'is not fooled by sparse arrays; see issue #95');
raises(function() { _.keys(null); }, TypeError, 'throws an error for `null` values');
raises(function() { _.keys(void 0); }, TypeError, 'throws an error for `undefined` values');
raises(function() { _.keys(1); }, TypeError, 'throws an error for number primitives');
raises(function() { _.keys('a'); }, TypeError, 'throws an error for string primitives');
raises(function() { _.keys(true); }, TypeError, 'throws an error for boolean primitives');
});
test("values", function() {
equal(_.values({one: 1, two: 2}).join(', '), '1, 2', 'can extract the values from an object');
equal(_.values({one: 1, two: 2, length: 3}).join(', '), '1, 2, 3', '... even when one of them is "length"');
});
test("pairs", function() {
deepEqual(_.pairs({one: 1, two: 2}), [['one', 1], ['two', 2]], 'can convert an object into pairs');
deepEqual(_.pairs({one: 1, two: 2, length: 3}), [['one', 1], ['two', 2], ['length', 3]], '... even when one of them is "length"');
});
test("invert", function() {
var obj = {first: 'Moe', second: 'Larry', third: 'Curly'};
equal(_.keys(_.invert(obj)).join(' '), 'Moe Larry Curly', 'can invert an object');
ok(_.isEqual(_.invert(_.invert(obj)), obj), 'two inverts gets you back where you started');
var obj = {length: 3};
ok(_.invert(obj)['3'] == 'length', 'can invert an object with "length"')
});
test("functions", function() {
var obj = {a : 'dash', b : _.map, c : (/yo/), d : _.reduce};
ok(_.isEqual(['b', 'd'], _.functions(obj)), 'can grab the function names of any passed-in object');
var Animal = function(){};
Animal.prototype.run = function(){};
equal(_.functions(new Animal).join(''), 'run', 'also looks up functions on the prototype');
});
test("extend", function() {
var result;
equal(_.extend({}, {a:'b'}).a, 'b', 'can extend an object with the attributes of another');
equal(_.extend({a:'x'}, {a:'b'}).a, 'b', 'properties in source override destination');
equal(_.extend({x:'x'}, {a:'b'}).x, 'x', 'properties not in source dont get overriden');
result = _.extend({x:'x'}, {a:'a'}, {b:'b'});
ok(_.isEqual(result, {x:'x', a:'a', b:'b'}), 'can extend from multiple source objects');
result = _.extend({x:'x'}, {a:'a', x:2}, {a:'b'});
ok(_.isEqual(result, {x:2, a:'b'}), 'extending from multiple source objects last property trumps');
result = _.extend({}, {a: void 0, b: null});
equal(_.keys(result).join(''), 'ab', 'extend does not copy undefined values');
try {
result = {};
_.extend(result, null, undefined, {a:1});
} catch(ex) {}
equal(result.a, 1, 'should not error on `null` or `undefined` sources');
});
test("pick", function() {
var result;
result = _.pick({a:1, b:2, c:3}, 'a', 'c');
ok(_.isEqual(result, {a:1, c:3}), 'can restrict properties to those named');
result = _.pick({a:1, b:2, c:3}, ['b', 'c']);
ok(_.isEqual(result, {b:2, c:3}), 'can restrict properties to those named in an array');
result = _.pick({a:1, b:2, c:3}, ['a'], 'b');
ok(_.isEqual(result, {a:1, b:2}), 'can restrict properties to those named in mixed args');
var Obj = function(){};
Obj.prototype = {a: 1, b: 2, c: 3};
ok(_.isEqual(_.pick(new Obj, 'a', 'c'), {a:1, c: 3}), 'include prototype props');
});
test("omit", function() {
var result;
result = _.omit({a:1, b:2, c:3}, 'b');
ok(_.isEqual(result, {a:1, c:3}), 'can omit a single named property');
result = _.omit({a:1, b:2, c:3}, 'a', 'c');
ok(_.isEqual(result, {b:2}), 'can omit several named properties');
result = _.omit({a:1, b:2, c:3}, ['b', 'c']);
ok(_.isEqual(result, {a:1}), 'can omit properties named in an array');
var Obj = function(){};
Obj.prototype = {a: 1, b: 2, c: 3};
ok(_.isEqual(_.omit(new Obj, 'b'), {a:1, c: 3}), 'include prototype props');
});
test("defaults", function() {
var result;
var options = {zero: 0, one: 1, empty: "", nan: NaN, string: "string"};
_.defaults(options, {zero: 1, one: 10, twenty: 20});
equal(options.zero, 0, 'value exists');
equal(options.one, 1, 'value exists');
equal(options.twenty, 20, 'default applied');
_.defaults(options, {empty: "full"}, {nan: "nan"}, {word: "word"}, {word: "dog"});
equal(options.empty, "", 'value exists');
ok(_.isNaN(options.nan), "NaN isn't overridden");
equal(options.word, "word", 'new value is added, first one wins');
try {
options = {};
_.defaults(options, null, undefined, {a:1});
} catch(ex) {}
equal(options.a, 1, 'should not error on `null` or `undefined` sources');
});
test("clone", function() {
var moe = {name : 'moe', lucky : [13, 27, 34]};
var clone = _.clone(moe);
equal(clone.name, 'moe', 'the clone as the attributes of the original');
clone.name = 'curly';
ok(clone.name == 'curly' && moe.name == 'moe', 'clones can change shallow attributes without affecting the original');
clone.lucky.push(101);
equal(_.last(moe.lucky), 101, 'changes to deep attributes are shared with the original');
equal(_.clone(undefined), void 0, 'non objects should not be changed by clone');
equal(_.clone(1), 1, 'non objects should not be changed by clone');
equal(_.clone(null), null, 'non objects should not be changed by clone');
});
test("isEqual", function() {
function First() {
this.value = 1;
}
First.prototype.value = 1;
function Second() {
this.value = 1;
}
Second.prototype.value = 2;
// Basic equality and identity comparisons.
ok(_.isEqual(null, null), "`null` is equal to `null`");
ok(_.isEqual(), "`undefined` is equal to `undefined`");
ok(!_.isEqual(0, -0), "`0` is not equal to `-0`");
ok(!_.isEqual(-0, 0), "Commutative equality is implemented for `0` and `-0`");
ok(!_.isEqual(null, undefined), "`null` is not equal to `undefined`");
ok(!_.isEqual(undefined, null), "Commutative equality is implemented for `null` and `undefined`");
// String object and primitive comparisons.
ok(_.isEqual("Curly", "Curly"), "Identical string primitives are equal");
ok(_.isEqual(new String("Curly"), new String("Curly")), "String objects with identical primitive values are equal");
ok(_.isEqual(new String("Curly"), "Curly"), "String primitives and their corresponding object wrappers are equal");
ok(_.isEqual("Curly", new String("Curly")), "Commutative equality is implemented for string objects and primitives");
ok(!_.isEqual("Curly", "Larry"), "String primitives with different values are not equal");
ok(!_.isEqual(new String("Curly"), new String("Larry")), "String objects with different primitive values are not equal");
ok(!_.isEqual(new String("Curly"), {toString: function(){ return "Curly"; }}), "String objects and objects with a custom `toString` method are not equal");
// Number object and primitive comparisons.
ok(_.isEqual(75, 75), "Identical number primitives are equal");
ok(_.isEqual(new Number(75), new Number(75)), "Number objects with identical primitive values are equal");
ok(_.isEqual(75, new Number(75)), "Number primitives and their corresponding object wrappers are equal");
ok(_.isEqual(new Number(75), 75), "Commutative equality is implemented for number objects and primitives");
ok(!_.isEqual(new Number(0), -0), "`new Number(0)` and `-0` are not equal");
ok(!_.isEqual(0, new Number(-0)), "Commutative equality is implemented for `new Number(0)` and `-0`");
ok(!_.isEqual(new Number(75), new Number(63)), "Number objects with different primitive values are not equal");
ok(!_.isEqual(new Number(63), {valueOf: function(){ return 63; }}), "Number objects and objects with a `valueOf` method are not equal");
// Comparisons involving `NaN`.
ok(_.isEqual(NaN, NaN), "`NaN` is equal to `NaN`");
ok(!_.isEqual(61, NaN), "A number primitive is not equal to `NaN`");
ok(!_.isEqual(new Number(79), NaN), "A number object is not equal to `NaN`");
ok(!_.isEqual(Infinity, NaN), "`Infinity` is not equal to `NaN`");
// Boolean object and primitive comparisons.
ok(_.isEqual(true, true), "Identical boolean primitives are equal");
ok(_.isEqual(new Boolean, new Boolean), "Boolean objects with identical primitive values are equal");
ok(_.isEqual(true, new Boolean(true)), "Boolean primitives and their corresponding object wrappers are equal");
ok(_.isEqual(new Boolean(true), true), "Commutative equality is implemented for booleans");
ok(!_.isEqual(new Boolean(true), new Boolean), "Boolean objects with different primitive values are not equal");
// Common type coercions.
ok(!_.isEqual(true, new Boolean(false)), "Boolean objects are not equal to the boolean primitive `true`");
ok(!_.isEqual("75", 75), "String and number primitives with like values are not equal");
ok(!_.isEqual(new Number(63), new String(63)), "String and number objects with like values are not equal");
ok(!_.isEqual(75, "75"), "Commutative equality is implemented for like string and number values");
ok(!_.isEqual(0, ""), "Number and string primitives with like values are not equal");
ok(!_.isEqual(1, true), "Number and boolean primitives with like values are not equal");
ok(!_.isEqual(new Boolean(false), new Number(0)), "Boolean and number objects with like values are not equal");
ok(!_.isEqual(false, new String("")), "Boolean primitives and string objects with like values are not equal");
ok(!_.isEqual(12564504e5, new Date(2009, 9, 25)), "Dates and their corresponding numeric primitive values are not equal");
// Dates.
ok(_.isEqual(new Date(2009, 9, 25), new Date(2009, 9, 25)), "Date objects referencing identical times are equal");
ok(!_.isEqual(new Date(2009, 9, 25), new Date(2009, 11, 13)), "Date objects referencing different times are not equal");
ok(!_.isEqual(new Date(2009, 11, 13), {
getTime: function(){
return 12606876e5;
}
}), "Date objects and objects with a `getTime` method are not equal");
ok(!_.isEqual(new Date("Curly"), new Date("Curly")), "Invalid dates are not equal");
// Functions.
ok(!_.isEqual(First, Second), "Different functions with identical bodies and source code representations are not equal");
// RegExps.
ok(_.isEqual(/(?:)/gim, /(?:)/gim), "RegExps with equivalent patterns and flags are equal");
ok(!_.isEqual(/(?:)/g, /(?:)/gi), "RegExps with equivalent patterns and different flags are not equal");
ok(!_.isEqual(/Moe/gim, /Curly/gim), "RegExps with different patterns and equivalent flags are not equal");
ok(!_.isEqual(/(?:)/gi, /(?:)/g), "Commutative equality is implemented for RegExps");
ok(!_.isEqual(/Curly/g, {source: "Larry", global: true, ignoreCase: false, multiline: false}), "RegExps and RegExp-like objects are not equal");
// Empty arrays, array-like objects, and object literals.
ok(_.isEqual({}, {}), "Empty object literals are equal");
ok(_.isEqual([], []), "Empty array literals are equal");
ok(_.isEqual([{}], [{}]), "Empty nested arrays and objects are equal");
ok(!_.isEqual({length: 0}, []), "Array-like objects and arrays are not equal.");
ok(!_.isEqual([], {length: 0}), "Commutative equality is implemented for array-like objects");
ok(!_.isEqual({}, []), "Object literals and array literals are not equal");
ok(!_.isEqual([], {}), "Commutative equality is implemented for objects and arrays");
// Arrays with primitive and object values.
ok(_.isEqual([1, "Larry", true], [1, "Larry", true]), "Arrays containing identical primitives are equal");
ok(_.isEqual([(/Moe/g), new Date(2009, 9, 25)], [(/Moe/g), new Date(2009, 9, 25)]), "Arrays containing equivalent elements are equal");
// Multi-dimensional arrays.
var a = [new Number(47), false, "Larry", /Moe/, new Date(2009, 11, 13), ['running', 'biking', new String('programming')], {a: 47}];
var b = [new Number(47), false, "Larry", /Moe/, new Date(2009, 11, 13), ['running', 'biking', new String('programming')], {a: 47}];
ok(_.isEqual(a, b), "Arrays containing nested arrays and objects are recursively compared");
// Overwrite the methods defined in ES 5.1 section 15.4.4.
a.forEach = a.map = a.filter = a.every = a.indexOf = a.lastIndexOf = a.some = a.reduce = a.reduceRight = null;
b.join = b.pop = b.reverse = b.shift = b.slice = b.splice = b.concat = b.sort = b.unshift = null;
// Array elements and properties.
ok(_.isEqual(a, b), "Arrays containing equivalent elements and different non-numeric properties are equal");
a.push("White Rocks");
ok(!_.isEqual(a, b), "Arrays of different lengths are not equal");
a.push("East Boulder");
b.push("Gunbarrel Ranch", "Teller Farm");
ok(!_.isEqual(a, b), "Arrays of identical lengths containing different elements are not equal");
// Sparse arrays.
ok(_.isEqual(Array(3), Array(3)), "Sparse arrays of identical lengths are equal");
ok(!_.isEqual(Array(3), Array(6)), "Sparse arrays of different lengths are not equal when both are empty");
// Simple objects.
ok(_.isEqual({a: "Curly", b: 1, c: true}, {a: "Curly", b: 1, c: true}), "Objects containing identical primitives are equal");
ok(_.isEqual({a: /Curly/g, b: new Date(2009, 11, 13)}, {a: /Curly/g, b: new Date(2009, 11, 13)}), "Objects containing equivalent members are equal");
ok(!_.isEqual({a: 63, b: 75}, {a: 61, b: 55}), "Objects of identical sizes with different values are not equal");
ok(!_.isEqual({a: 63, b: 75}, {a: 61, c: 55}), "Objects of identical sizes with different property names are not equal");
ok(!_.isEqual({a: 1, b: 2}, {a: 1}), "Objects of different sizes are not equal");
ok(!_.isEqual({a: 1}, {a: 1, b: 2}), "Commutative equality is implemented for objects");
ok(!_.isEqual({x: 1, y: undefined}, {x: 1, z: 2}), "Objects with identical keys and different values are not equivalent");
// `A` contains nested objects and arrays.
a = {
name: new String("Moe Howard"),
age: new Number(77),
stooge: true,
hobbies: ["acting"],
film: {
name: "Sing a Song of Six Pants",
release: new Date(1947, 9, 30),
stars: [new String("Larry Fine"), "Shemp Howard"],
minutes: new Number(16),
seconds: 54
}
};
// `B` contains equivalent nested objects and arrays.
b = {
name: new String("Moe Howard"),
age: new Number(77),
stooge: true,
hobbies: ["acting"],
film: {
name: "Sing a Song of Six Pants",
release: new Date(1947, 9, 30),
stars: [new String("Larry Fine"), "Shemp Howard"],
minutes: new Number(16),
seconds: 54
}
};
ok(_.isEqual(a, b), "Objects with nested equivalent members are recursively compared");
// Instances.
ok(_.isEqual(new First, new First), "Object instances are equal");
ok(!_.isEqual(new First, new Second), "Objects with different constructors and identical own properties are not equal");
ok(!_.isEqual({value: 1}, new First), "Object instances and objects sharing equivalent properties are not equal");
ok(!_.isEqual({value: 2}, new Second), "The prototype chain of objects should not be examined");
// Circular Arrays.
(a = []).push(a);
(b = []).push(b);
ok(_.isEqual(a, b), "Arrays containing circular references are equal");
a.push(new String("Larry"));
b.push(new String("Larry"));
ok(_.isEqual(a, b), "Arrays containing circular references and equivalent properties are equal");
a.push("Shemp");
b.push("Curly");
ok(!_.isEqual(a, b), "Arrays containing circular references and different properties are not equal");
// More circular arrays #767.
a = ["everything is checked but", "this", "is not"];
a[1] = a;
b = ["everything is checked but", ["this", "array"], "is not"];
ok(!_.isEqual(a, b), "Comparison of circular references with non-circular references are not equal");
// Circular Objects.
a = {abc: null};
b = {abc: null};
a.abc = a;
b.abc = b;
ok(_.isEqual(a, b), "Objects containing circular references are equal");
a.def = 75;
b.def = 75;
ok(_.isEqual(a, b), "Objects containing circular references and equivalent properties are equal");
a.def = new Number(75);
b.def = new Number(63);
ok(!_.isEqual(a, b), "Objects containing circular references and different properties are not equal");
// More circular objects #767.
a = {everything: "is checked", but: "this", is: "not"};
a.but = a;
b = {everything: "is checked", but: {that:"object"}, is: "not"};
ok(!_.isEqual(a, b), "Comparison of circular references with non-circular object references are not equal");
// Cyclic Structures.
a = [{abc: null}];
b = [{abc: null}];
(a[0].abc = a).push(a);
(b[0].abc = b).push(b);
ok(_.isEqual(a, b), "Cyclic structures are equal");
a[0].def = "Larry";
b[0].def = "Larry";
ok(_.isEqual(a, b), "Cyclic structures containing equivalent properties are equal");
a[0].def = new String("Larry");
b[0].def = new String("Curly");
ok(!_.isEqual(a, b), "Cyclic structures containing different properties are not equal");
// Complex Circular References.
a = {foo: {b: {foo: {c: {foo: null}}}}};
b = {foo: {b: {foo: {c: {foo: null}}}}};
a.foo.b.foo.c.foo = a;
b.foo.b.foo.c.foo = b;
ok(_.isEqual(a, b), "Cyclic structures with nested and identically-named properties are equal");
// Chaining.
ok(!_.isEqual(_({x: 1, y: undefined}).chain(), _({x: 1, z: 2}).chain()), 'Chained objects containing different values are not equal');
a = _({x: 1, y: 2}).chain();
b = _({x: 1, y: 2}).chain();
equal(_.isEqual(a.isEqual(b), _(true)), true, '`isEqual` can be chained');
// Objects from another frame.
ok(_.isEqual({}, iObject));
});
test("isEmpty", function() {
ok(!_([1]).isEmpty(), '[1] is not empty');
ok(_.isEmpty([]), '[] is empty');
ok(!_.isEmpty({one : 1}), '{one : 1} is not empty');
ok(_.isEmpty({}), '{} is empty');
ok(_.isEmpty(new RegExp('')), 'objects with prototype properties are empty');
ok(_.isEmpty(null), 'null is empty');
ok(_.isEmpty(), 'undefined is empty');
ok(_.isEmpty(''), 'the empty string is empty');
ok(!_.isEmpty('moe'), 'but other strings are not');
var obj = {one : 1};
delete obj.one;
ok(_.isEmpty(obj), 'deleting all the keys from an object empties it');
});
// Setup remote variables for iFrame tests.
var iframe = document.createElement('iframe');
jQuery(iframe).appendTo(document.body);
var iDoc = iframe.contentDocument || iframe.contentWindow.document;
iDoc.write(
"<script>\
parent.iElement = document.createElement('div');\
parent.iArguments = (function(){ return arguments; })(1, 2, 3);\
parent.iArray = [1, 2, 3];\
parent.iString = new String('hello');\
parent.iNumber = new Number(100);\
parent.iFunction = (function(){});\
parent.iDate = new Date();\
parent.iRegExp = /hi/;\
parent.iNaN = NaN;\
parent.iNull = null;\
parent.iBoolean = new Boolean(false);\
parent.iUndefined = undefined;\
parent.iObject = {};\
</script>"
);
iDoc.close();
test("isElement", function() {
ok(!_.isElement('div'), 'strings are not dom elements');
ok(_.isElement($('html')[0]), 'the html tag is a DOM element');
ok(_.isElement(iElement), 'even from another frame');
});
test("isArguments", function() {
var args = (function(){ return arguments; })(1, 2, 3);
ok(!_.isArguments('string'), 'a string is not an arguments object');
ok(!_.isArguments(_.isArguments), 'a function is not an arguments object');
ok(_.isArguments(args), 'but the arguments object is an arguments object');
ok(!_.isArguments(_.toArray(args)), 'but not when it\'s converted into an array');
ok(!_.isArguments([1,2,3]), 'and not vanilla arrays.');
ok(_.isArguments(iArguments), 'even from another frame');
});
test("isObject", function() {
ok(_.isObject(arguments), 'the arguments object is object');
ok(_.isObject([1, 2, 3]), 'and arrays');
ok(_.isObject($('html')[0]), 'and DOM element');
ok(_.isObject(iElement), 'even from another frame');
ok(_.isObject(function () {}), 'and functions');
ok(_.isObject(iFunction), 'even from another frame');
ok(!_.isObject(null), 'but not null');
ok(!_.isObject(undefined), 'and not undefined');
ok(!_.isObject('string'), 'and not string');
ok(!_.isObject(12), 'and not number');
ok(!_.isObject(true), 'and not boolean');
ok(_.isObject(new String('string')), 'but new String()');
});
test("isArray", function() {
ok(!_.isArray(arguments), 'the arguments object is not an array');
ok(_.isArray([1, 2, 3]), 'but arrays are');
ok(_.isArray(iArray), 'even from another frame');
});
test("isString", function() {
ok(!_.isString(document.body), 'the document body is not a string');
ok(_.isString([1, 2, 3].join(', ')), 'but strings are');
ok(_.isString(iString), 'even from another frame');
});
test("isNumber", function() {
ok(!_.isNumber('string'), 'a string is not a number');
ok(!_.isNumber(arguments), 'the arguments object is not a number');
ok(!_.isNumber(undefined), 'undefined is not a number');
ok(_.isNumber(3 * 4 - 7 / 10), 'but numbers are');
ok(_.isNumber(NaN), 'NaN *is* a number');
ok(_.isNumber(Infinity), 'Infinity is a number');
ok(_.isNumber(iNumber), 'even from another frame');
ok(!_.isNumber('1'), 'numeric strings are not numbers');
});
test("isBoolean", function() {
ok(!_.isBoolean(2), 'a number is not a boolean');
ok(!_.isBoolean("string"), 'a string is not a boolean');
ok(!_.isBoolean("false"), 'the string "false" is not a boolean');
ok(!_.isBoolean("true"), 'the string "true" is not a boolean');
ok(!_.isBoolean(arguments), 'the arguments object is not a boolean');
ok(!_.isBoolean(undefined), 'undefined is not a boolean');
ok(!_.isBoolean(NaN), 'NaN is not a boolean');
ok(!_.isBoolean(null), 'null is not a boolean');
ok(_.isBoolean(true), 'but true is');
ok(_.isBoolean(false), 'and so is false');
ok(_.isBoolean(iBoolean), 'even from another frame');
});
test("isFunction", function() {
ok(!_.isFunction([1, 2, 3]), 'arrays are not functions');
ok(!_.isFunction('moe'), 'strings are not functions');
ok(_.isFunction(_.isFunction), 'but functions are');
ok(_.isFunction(iFunction), 'even from another frame');
});
test("isDate", function() {
ok(!_.isDate(100), 'numbers are not dates');
ok(!_.isDate({}), 'objects are not dates');
ok(_.isDate(new Date()), 'but dates are');
ok(_.isDate(iDate), 'even from another frame');
});
test("isRegExp", function() {
ok(!_.isRegExp(_.identity), 'functions are not RegExps');
ok(_.isRegExp(/identity/), 'but RegExps are');
ok(_.isRegExp(iRegExp), 'even from another frame');
});
test("isFinite", function() {
ok(!_.isFinite(undefined), 'undefined is not Finite');
ok(!_.isFinite(null), 'null is not Finite');
ok(!_.isFinite(NaN), 'NaN is not Finite');
ok(!_.isFinite(Infinity), 'Infinity is not Finite');
ok(!_.isFinite(-Infinity), '-Infinity is not Finite');
ok(_.isFinite('12'), 'Numeric strings are numbers');
ok(!_.isFinite('1a'), 'Non numeric strings are not numbers');
ok(!_.isFinite(''), 'Empty strings are not numbers');
var obj = new Number(5);
ok(_.isFinite(obj), 'Number instances can be finite');
ok(_.isFinite(0), '0 is Finite');
ok(_.isFinite(123), 'Ints are Finite');
ok(_.isFinite(-12.44), 'Floats are Finite');
});
test("isNaN", function() {
ok(!_.isNaN(undefined), 'undefined is not NaN');
ok(!_.isNaN(null), 'null is not NaN');
ok(!_.isNaN(0), '0 is not NaN');
ok(_.isNaN(NaN), 'but NaN is');
ok(_.isNaN(iNaN), 'even from another frame');
ok(_.isNaN(new Number(NaN)), 'wrapped NaN is still NaN');
});
test("isNull", function() {
ok(!_.isNull(undefined), 'undefined is not null');
ok(!_.isNull(NaN), 'NaN is not null');
ok(_.isNull(null), 'but null is');
ok(_.isNull(iNull), 'even from another frame');
});
test("isUndefined", function() {
ok(!_.isUndefined(1), 'numbers are defined');
ok(!_.isUndefined(null), 'null is defined');
ok(!_.isUndefined(false), 'false is defined');
ok(!_.isUndefined(NaN), 'NaN is defined');
ok(_.isUndefined(), 'nothing is undefined');
ok(_.isUndefined(undefined), 'undefined is undefined');
ok(_.isUndefined(iUndefined), 'even from another frame');
});
if (window.ActiveXObject) {
test("IE host objects", function() {
var xml = new ActiveXObject("Msxml2.DOMDocument.3.0");
ok(!_.isNumber(xml));
ok(!_.isBoolean(xml));
ok(!_.isNaN(xml));
ok(!_.isFunction(xml));
ok(!_.isNull(xml));
ok(!_.isUndefined(xml));
});
}
test("tap", function() {
var intercepted = null;
var interceptor = function(obj) { intercepted = obj; };
var returned = _.tap(1, interceptor);
equal(intercepted, 1, "passes tapped object to interceptor");
equal(returned, 1, "returns tapped object");
returned = _([1,2,3]).chain().
map(function(n){ return n * 2; }).
max().
tap(interceptor).
value();
ok(returned == 6 && intercepted == 6, 'can use tapped objects in a chain');
});
});

252
vendor/underscore/test/utility.js vendored Normal file
View File

@@ -0,0 +1,252 @@
$(document).ready(function() {
var templateSettings;
module("Utility", {
setup: function() {
templateSettings = _.clone(_.templateSettings);
},
teardown: function() {
_.templateSettings = templateSettings;
}
});
test("#750 - Return _ instance.", 2, function() {
var instance = _([]);
ok(_(instance) === instance);
ok(new _(instance) === instance);
});
test("identity", function() {
var moe = {name : 'moe'};
equal(_.identity(moe), moe, 'moe is the same as his identity');
});
test("uniqueId", function() {
var ids = [], i = 0;
while(i++ < 100) ids.push(_.uniqueId());
equal(_.uniq(ids).length, ids.length, 'can generate a globally-unique stream of ids');
});
test("times", function() {
var vals = [];
_.times(3, function (i) { vals.push(i); });
ok(_.isEqual(vals, [0,1,2]), "is 0 indexed");
//
vals = [];
_(3).times(function(i) { vals.push(i); });
ok(_.isEqual(vals, [0,1,2]), "works as a wrapper");
// collects return values
ok(_.isEqual([0, 1, 2], _.times(3, function(i) { return i; })), "collects return values");
});
test("mixin", function() {
_.mixin({
myReverse: function(string) {
return string.split('').reverse().join('');
}
});
equal(_.myReverse('panacea'), 'aecanap', 'mixed in a function to _');
equal(_('champ').myReverse(), 'pmahc', 'mixed in a function to the OOP wrapper');
});
test("_.escape", function() {
equal(_.escape("Curly & Moe"), "Curly &amp; Moe");
equal(_.escape("Curly &amp; Moe"), "Curly &amp;amp; Moe");
equal(_.escape(null), '');
});
test("_.unescape", function() {
var string = "Curly & Moe";
equal(_.unescape("Curly &amp; Moe"), string);
equal(_.unescape("Curly &amp;amp; Moe"), "Curly &amp; Moe");
equal(_.unescape(null), '');
equal(_.unescape(_.escape(string)), string);
});
test("template", function() {
var basicTemplate = _.template("<%= thing %> is gettin' on my noives!");
var result = basicTemplate({thing : 'This'});
equal(result, "This is gettin' on my noives!", 'can do basic attribute interpolation');
var sansSemicolonTemplate = _.template("A <% this %> B");
equal(sansSemicolonTemplate(), "A B");
var backslashTemplate = _.template("<%= thing %> is \\ridanculous");
equal(backslashTemplate({thing: 'This'}), "This is \\ridanculous");
var escapeTemplate = _.template('<%= a ? "checked=\\"checked\\"" : "" %>');
equal(escapeTemplate({a: true}), 'checked="checked"', 'can handle slash escapes in interpolations.');
var fancyTemplate = _.template("<ul><% \
for (key in people) { \
%><li><%= people[key] %></li><% } %></ul>");
result = fancyTemplate({people : {moe : "Moe", larry : "Larry", curly : "Curly"}});
equal(result, "<ul><li>Moe</li><li>Larry</li><li>Curly</li></ul>", 'can run arbitrary javascript in templates');
var escapedCharsInJavascriptTemplate = _.template("<ul><% _.each(numbers.split('\\n'), function(item) { %><li><%= item %></li><% }) %></ul>");
result = escapedCharsInJavascriptTemplate({numbers: "one\ntwo\nthree\nfour"});
equal(result, "<ul><li>one</li><li>two</li><li>three</li><li>four</li></ul>", 'Can use escaped characters (e.g. \\n) in Javascript');
var namespaceCollisionTemplate = _.template("<%= pageCount %> <%= thumbnails[pageCount] %> <% _.each(thumbnails, function(p) { %><div class=\"thumbnail\" rel=\"<%= p %>\"></div><% }); %>");
result = namespaceCollisionTemplate({
pageCount: 3,
thumbnails: {
1: "p1-thumbnail.gif",
2: "p2-thumbnail.gif",
3: "p3-thumbnail.gif"
}
});
equal(result, "3 p3-thumbnail.gif <div class=\"thumbnail\" rel=\"p1-thumbnail.gif\"></div><div class=\"thumbnail\" rel=\"p2-thumbnail.gif\"></div><div class=\"thumbnail\" rel=\"p3-thumbnail.gif\"></div>");
var noInterpolateTemplate = _.template("<div><p>Just some text. Hey, I know this is silly but it aids consistency.</p></div>");
result = noInterpolateTemplate();
equal(result, "<div><p>Just some text. Hey, I know this is silly but it aids consistency.</p></div>");
var quoteTemplate = _.template("It's its, not it's");
equal(quoteTemplate({}), "It's its, not it's");
var quoteInStatementAndBody = _.template("<%\
if(foo == 'bar'){ \
%>Statement quotes and 'quotes'.<% } %>");
equal(quoteInStatementAndBody({foo: "bar"}), "Statement quotes and 'quotes'.");
var withNewlinesAndTabs = _.template('This\n\t\tis: <%= x %>.\n\tok.\nend.');
equal(withNewlinesAndTabs({x: 'that'}), 'This\n\t\tis: that.\n\tok.\nend.');
var template = _.template("<i><%- value %></i>");
var result = template({value: "<script>"});
equal(result, '<i>&lt;script&gt;</i>');
var stooge = {
name: "Moe",
template: _.template("I'm <%= this.name %>")
};
equal(stooge.template(), "I'm Moe");
if (!$.browser.msie) {
var fromHTML = _.template($('#template').html());
equal(fromHTML({data : 12345}).replace(/\s/g, ''), '<li>24690</li>');
}
_.templateSettings = {
evaluate : /\{\{([\s\S]+?)\}\}/g,
interpolate : /\{\{=([\s\S]+?)\}\}/g
};
var custom = _.template("<ul>{{ for (key in people) { }}<li>{{= people[key] }}</li>{{ } }}</ul>");
result = custom({people : {moe : "Moe", larry : "Larry", curly : "Curly"}});
equal(result, "<ul><li>Moe</li><li>Larry</li><li>Curly</li></ul>", 'can run arbitrary javascript in templates');
var customQuote = _.template("It's its, not it's");
equal(customQuote({}), "It's its, not it's");
var quoteInStatementAndBody = _.template("{{ if(foo == 'bar'){ }}Statement quotes and 'quotes'.{{ } }}");
equal(quoteInStatementAndBody({foo: "bar"}), "Statement quotes and 'quotes'.");
_.templateSettings = {
evaluate : /<\?([\s\S]+?)\?>/g,
interpolate : /<\?=([\s\S]+?)\?>/g
};
var customWithSpecialChars = _.template("<ul><? for (key in people) { ?><li><?= people[key] ?></li><? } ?></ul>");
result = customWithSpecialChars({people : {moe : "Moe", larry : "Larry", curly : "Curly"}});
equal(result, "<ul><li>Moe</li><li>Larry</li><li>Curly</li></ul>", 'can run arbitrary javascript in templates');
var customWithSpecialCharsQuote = _.template("It's its, not it's");
equal(customWithSpecialCharsQuote({}), "It's its, not it's");
var quoteInStatementAndBody = _.template("<? if(foo == 'bar'){ ?>Statement quotes and 'quotes'.<? } ?>");
equal(quoteInStatementAndBody({foo: "bar"}), "Statement quotes and 'quotes'.");
_.templateSettings = {
interpolate : /\{\{(.+?)\}\}/g
};
var mustache = _.template("Hello {{planet}}!");
equal(mustache({planet : "World"}), "Hello World!", "can mimic mustache.js");
var templateWithNull = _.template("a null undefined {{planet}}");
equal(templateWithNull({planet : "world"}), "a null undefined world", "can handle missing escape and evaluate settings");
});
test('_.template provides the generated function source, when a SyntaxError occurs', function() {
try {
_.template('<b><%= if x %></b>');
} catch (ex) {
var source = ex.source;
}
ok(/__p/.test(source));
});
test('_.template handles \\u2028 & \\u2029', function() {
var tmpl = _.template('<p>\u2028<%= "\\u2028\\u2029" %>\u2029</p>');
strictEqual(tmpl(), '<p>\u2028\u2028\u2029\u2029</p>');
});
test('result calls functions and returns primitives', function() {
var obj = {w: '', x: 'x', y: function(){ return this.x; }};
strictEqual(_.result(obj, 'w'), '');
strictEqual(_.result(obj, 'x'), 'x');
strictEqual(_.result(obj, 'y'), 'x');
strictEqual(_.result(obj, 'z'), undefined);
strictEqual(_.result(null, 'x'), null);
});
test('_.templateSettings.variable', function() {
var s = '<%=data.x%>';
var data = {x: 'x'};
strictEqual(_.template(s, data, {variable: 'data'}), 'x');
_.templateSettings.variable = 'data';
strictEqual(_.template(s)(data), 'x');
});
test('#547 - _.templateSettings is unchanged by custom settings.', function() {
ok(!_.templateSettings.variable);
_.template('', {}, {variable: 'x'});
ok(!_.templateSettings.variable);
});
test('#556 - undefined template variables.', function() {
var template = _.template('<%=x%>');
strictEqual(template({x: null}), '');
strictEqual(template({x: undefined}), '');
var templateEscaped = _.template('<%-x%>');
strictEqual(templateEscaped({x: null}), '');
strictEqual(templateEscaped({x: undefined}), '');
var templateWithProperty = _.template('<%=x.foo%>');
strictEqual(templateWithProperty({x: {} }), '');
strictEqual(templateWithProperty({x: {} }), '');
var templateWithPropertyEscaped = _.template('<%-x.foo%>');
strictEqual(templateWithPropertyEscaped({x: {} }), '');
strictEqual(templateWithPropertyEscaped({x: {} }), '');
});
test('interpolate evaluates code only once.', 2, function() {
var count = 0;
var template = _.template('<%= f() %>');
template({f: function(){ ok(!(count++)); }});
var countEscaped = 0;
var templateEscaped = _.template('<%- f() %>');
templateEscaped({f: function(){ ok(!(countEscaped++)); }});
});
test('#746 - _.template settings are not modified.', 1, function() {
var settings = {};
_.template('', null, settings);
deepEqual(settings, {});
});
test('#779 - delimeters are applied to unescaped text.', 1, function() {
var template = _.template('<<\nx\n>>', null, {evaluate: /<<(.*?)>>/g});
strictEqual(template(), '<<\nx\n>>');
});
});

5
vendor/underscore/underscore-min.js vendored Normal file

File diff suppressed because one or more lines are too long

1221
vendor/underscore/underscore.js vendored Normal file

File diff suppressed because it is too large Load Diff