mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-01-30 15:07:50 +00:00
Compare commits
647 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d7c74b8004 | ||
|
|
aaa8003418 | ||
|
|
86890b13c6 | ||
|
|
39158b0eb6 | ||
|
|
87f1d55bc2 | ||
|
|
14343b5410 | ||
|
|
ffdac30b3c | ||
|
|
244c8dc391 | ||
|
|
e593344461 | ||
|
|
74c46f6e93 | ||
|
|
bbfd8aa249 | ||
|
|
2705a488ad | ||
|
|
850c253e08 | ||
|
|
80e0e3fcd7 | ||
|
|
2cc2d696f1 | ||
|
|
8a83a6b5be | ||
|
|
002d5338a0 | ||
|
|
743aa472f0 | ||
|
|
ba85d5d351 | ||
|
|
4e2ef908dc | ||
|
|
f5dd05ba8e | ||
|
|
17eda2a4cc | ||
|
|
d219c6e019 | ||
|
|
2dc539747b | ||
|
|
e941de50e8 | ||
|
|
63052257a2 | ||
|
|
ac5d2a714e | ||
|
|
59f78c16b1 | ||
|
|
3f7f8133df | ||
|
|
fef5e1ce2c | ||
|
|
0b97b3864f | ||
|
|
3d1330c85d | ||
|
|
041c0cc322 | ||
|
|
e72712640c | ||
|
|
6830195127 | ||
|
|
f9b5d6644d | ||
|
|
40f9eeda36 | ||
|
|
0fa0b0b1ea | ||
|
|
ff0b23f200 | ||
|
|
5456d4081b | ||
|
|
8948fae780 | ||
|
|
ee4542a699 | ||
|
|
31e4e631f9 | ||
|
|
cbf20b3271 | ||
|
|
a65fd50723 | ||
|
|
63a6aac2d8 | ||
|
|
afde4804c9 | ||
|
|
bc8ec9cd3e | ||
|
|
b63ab18e29 | ||
|
|
e7325f58c3 | ||
|
|
7b35bb8c96 | ||
|
|
e84671ce5d | ||
|
|
b01d50fe05 | ||
|
|
3f163051b1 | ||
|
|
4f1d03e1d4 | ||
|
|
fc39e4a225 | ||
|
|
bf88ad7fc8 | ||
|
|
11ba02067e | ||
|
|
952afa05ce | ||
|
|
3131cc3160 | ||
|
|
792f768479 | ||
|
|
ff312a15dd | ||
|
|
36207c9a98 | ||
|
|
b92105e888 | ||
|
|
35bd7c55d0 | ||
|
|
9f19c302d8 | ||
|
|
87b1ac776f | ||
|
|
41e401b05e | ||
|
|
d88da3589d | ||
|
|
9638c393bb | ||
|
|
9961ddc2a8 | ||
|
|
2d40dfd8d4 | ||
|
|
99c9bdf71d | ||
|
|
4fcd25ec88 | ||
|
|
440218da67 | ||
|
|
fefdb9fc8d | ||
|
|
21a0eff593 | ||
|
|
8825a094ae | ||
|
|
aa49ce5c56 | ||
|
|
1522d3385d | ||
|
|
510c41440a | ||
|
|
aa0c34ba1c | ||
|
|
af87e6ef62 | ||
|
|
30291ce6e6 | ||
|
|
890c2eb564 | ||
|
|
67a269b89c | ||
|
|
4b9ee81a78 | ||
|
|
4343f4d229 | ||
|
|
2162baa6c0 | ||
|
|
7e7f792710 | ||
|
|
1bbd9e24b0 | ||
|
|
6435aaa64f | ||
|
|
999aae0a33 | ||
|
|
ba795639b4 | ||
|
|
4c4b205721 | ||
|
|
b3c550b7c0 | ||
|
|
eb8953e784 | ||
|
|
b88b292d5d | ||
|
|
5f42c3b319 | ||
|
|
5b27ae0371 | ||
|
|
f26b1da1b5 | ||
|
|
7a853e2dcb | ||
|
|
9b22748bd0 | ||
|
|
c1e9dd3373 | ||
|
|
8cbbc47043 | ||
|
|
81b3567133 | ||
|
|
fc6568f390 | ||
|
|
8e30fe2946 | ||
|
|
6c811a3261 | ||
|
|
afbe5aa540 | ||
|
|
324afd2d6c | ||
|
|
58d94ef61e | ||
|
|
39974b0982 | ||
|
|
323d7306e2 | ||
|
|
251e228ce4 | ||
|
|
a99f3f217a | ||
|
|
e2acbee113 | ||
|
|
37b69eddf2 | ||
|
|
f0322e6f2c | ||
|
|
756587d080 | ||
|
|
1ad2c92324 | ||
|
|
e5433adf78 | ||
|
|
ed765f75d8 | ||
|
|
4136f1b377 | ||
|
|
860339b90e | ||
|
|
03254a0c0f | ||
|
|
a76081c979 | ||
|
|
71a207079f | ||
|
|
f6e724c4c5 | ||
|
|
4251b36b25 | ||
|
|
b8f39cbfdf | ||
|
|
088c621862 | ||
|
|
2459a53350 | ||
|
|
7093e9c0d4 | ||
|
|
4bc49978d1 | ||
|
|
96bac9c149 | ||
|
|
8dcc15f4d3 | ||
|
|
8183740c04 | ||
|
|
25e4231d7b | ||
|
|
3ed9e0e905 | ||
|
|
45bec0c440 | ||
|
|
5133e39d45 | ||
|
|
cb3b4e446e | ||
|
|
9829a2f3b4 | ||
|
|
7eadf11145 | ||
|
|
2a2bc44f43 | ||
|
|
9ccfa5cec9 | ||
|
|
02687f3c78 | ||
|
|
7ea7a6cbb1 | ||
|
|
a15a28fe5b | ||
|
|
265dedfae1 | ||
|
|
5ddbb8bc56 | ||
|
|
4101b8e937 | ||
|
|
56b6d50479 | ||
|
|
506f585d78 | ||
|
|
577dfb7220 | ||
|
|
7e4286adde | ||
|
|
1090228628 | ||
|
|
aeea861b73 | ||
|
|
997c43bbdd | ||
|
|
958d4dbd2e | ||
|
|
f2b350eb62 | ||
|
|
a3464780a1 | ||
|
|
fe1eb92196 | ||
|
|
0b2d26ec92 | ||
|
|
8024a25f2b | ||
|
|
d287ecbb34 | ||
|
|
d9c95e7730 | ||
|
|
c3b1af31ce | ||
|
|
465576b5cb | ||
|
|
9ecbcd0075 | ||
|
|
c1f62d72ae | ||
|
|
1b27834c41 | ||
|
|
77804907b6 | ||
|
|
9dfa2609be | ||
|
|
8ffb3ab3c4 | ||
|
|
65e1da34fa | ||
|
|
282110807c | ||
|
|
25e5f43d1c | ||
|
|
ce0441694d | ||
|
|
db29699927 | ||
|
|
9a4e2d7617 | ||
|
|
fbf64585b7 | ||
|
|
6d1c6dfd16 | ||
|
|
e78df4d981 | ||
|
|
a757b4d5dc | ||
|
|
d28036ee91 | ||
|
|
d2ba0d4e7a | ||
|
|
5787436177 | ||
|
|
f5ab24b8d2 | ||
|
|
05c0f32a24 | ||
|
|
7b918f77a9 | ||
|
|
d87929d61c | ||
|
|
a926829c33 | ||
|
|
d58e366c40 | ||
|
|
0fb4f7e1c4 | ||
|
|
6ee606e3e2 | ||
|
|
22d4a7690f | ||
|
|
f3a2f5018a | ||
|
|
d2a7589f7c | ||
|
|
f87b4e04f1 | ||
|
|
b5aa4c1f0c | ||
|
|
0c1eb6d288 | ||
|
|
8a03c5f998 | ||
|
|
60aa50ae45 | ||
|
|
aae6bbbb66 | ||
|
|
5ca903c428 | ||
|
|
e86b07f760 | ||
|
|
d7fea5dc78 | ||
|
|
c1eff5aebb | ||
|
|
f2dc490d6f | ||
|
|
b296e1b340 | ||
|
|
8adb060edb | ||
|
|
c3b984fea7 | ||
|
|
afbb2c338b | ||
|
|
6632241ab5 | ||
|
|
be50df81db | ||
|
|
9763b6e2cf | ||
|
|
812b848daf | ||
|
|
4907a7389f | ||
|
|
17dff36b65 | ||
|
|
904921d8c4 | ||
|
|
ac4c075d32 | ||
|
|
ddde64ece9 | ||
|
|
91c097e88d | ||
|
|
894658a3f5 | ||
|
|
a4454ea5f9 | ||
|
|
8ea8fa3a8a | ||
|
|
7480603295 | ||
|
|
079b749d5d | ||
|
|
4815600e85 | ||
|
|
1c63e2d295 | ||
|
|
cf13eca58c | ||
|
|
3cf4607870 | ||
|
|
23c3ba6ad7 | ||
|
|
17fc3c2317 | ||
|
|
af234cbe54 | ||
|
|
c8517c0ec9 | ||
|
|
20b226454b | ||
|
|
98eccf223a | ||
|
|
0fc2ab4d41 | ||
|
|
641b6efe7f | ||
|
|
4c83435b4b | ||
|
|
9f7319cff4 | ||
|
|
dd9baa1502 | ||
|
|
41b4d0daa1 | ||
|
|
e41b181163 | ||
|
|
288ac115d0 | ||
|
|
6774d46a6f | ||
|
|
607abf89f7 | ||
|
|
27f1e5e2f2 | ||
|
|
a457675ce1 | ||
|
|
82049096e6 | ||
|
|
6c965e0223 | ||
|
|
8b4d952929 | ||
|
|
873cc63f94 | ||
|
|
39fc839ff2 | ||
|
|
4edef4c959 | ||
|
|
1d9ced8037 | ||
|
|
4cb77d1429 | ||
|
|
b52d9d1bdd | ||
|
|
5fe7ca5e70 | ||
|
|
62fb440de2 | ||
|
|
96fbd7c7ba | ||
|
|
c9bec8e636 | ||
|
|
769e03e7f2 | ||
|
|
ab83f2d5e2 | ||
|
|
b60d0cdb17 | ||
|
|
677503dbf1 | ||
|
|
25efa29470 | ||
|
|
21a90f8f8f | ||
|
|
64e8d6ae99 | ||
|
|
16a204335e | ||
|
|
0a53f762fe | ||
|
|
6ba4778c1b | ||
|
|
0404c2266c | ||
|
|
e5e914282f | ||
|
|
9867d4bdc3 | ||
|
|
e4cb7112cf | ||
|
|
2d202e90b7 | ||
|
|
016391e442 | ||
|
|
1eff48a429 | ||
|
|
ce33af6bb5 | ||
|
|
fb9d4303f1 | ||
|
|
4e631c9e8f | ||
|
|
766d67d80d | ||
|
|
e2c2a37221 | ||
|
|
2b23020695 | ||
|
|
8d43c6b1a8 | ||
|
|
7362dd1a7c | ||
|
|
316caf7e8c | ||
|
|
87dc6631ee | ||
|
|
62246d7d43 | ||
|
|
a14be3a42c | ||
|
|
7fdf00d5e9 | ||
|
|
99e02f30fb | ||
|
|
716a5b9b5a | ||
|
|
87f880ca52 | ||
|
|
8ec7b84a78 | ||
|
|
05cf5bc8db | ||
|
|
ac25e21a0c | ||
|
|
cc1e0daaa4 | ||
|
|
f4120a9c8c | ||
|
|
e3b80a5e09 | ||
|
|
ef7cb26b01 | ||
|
|
408a5c168f | ||
|
|
0ad6ac95b2 | ||
|
|
bda4747e9c | ||
|
|
bd8f882c94 | ||
|
|
32b5b5b1c4 | ||
|
|
c1e543c9fe | ||
|
|
3908fa5c57 | ||
|
|
1b347fc185 | ||
|
|
282a5e0b01 | ||
|
|
e9d23cc1ea | ||
|
|
34173fd60f | ||
|
|
d0d3c8ef57 | ||
|
|
11912008dd | ||
|
|
c122007e17 | ||
|
|
69dfa1a175 | ||
|
|
bfea443e55 | ||
|
|
680798c28f | ||
|
|
9f0cc45c45 | ||
|
|
0ac97f467f | ||
|
|
647746ea72 | ||
|
|
7bea30b2e6 | ||
|
|
12bc852c89 | ||
|
|
0d42e84045 | ||
|
|
897b85b607 | ||
|
|
5c55cf0efb | ||
|
|
eccd6463f6 | ||
|
|
4a0897c734 | ||
|
|
c86a16df7f | ||
|
|
2ae0e9d902 | ||
|
|
bba18cd56b | ||
|
|
2f20781e16 | ||
|
|
3bee212876 | ||
|
|
6c8893a550 | ||
|
|
9c52ecc19b | ||
|
|
692c884ca2 | ||
|
|
3ef51d7fae | ||
|
|
73d95de122 | ||
|
|
04a568ac9b | ||
|
|
a45499cf04 | ||
|
|
b847d672ab | ||
|
|
3ffefdf6b5 | ||
|
|
cca4c4be80 | ||
|
|
cb9e044cb3 | ||
|
|
fd25dd83bd | ||
|
|
584bb00cfc | ||
|
|
5b9369d344 | ||
|
|
a64506a0de | ||
|
|
2fc83ef80b | ||
|
|
8bee3ebd65 | ||
|
|
99686fdd73 | ||
|
|
33bc3d6a1e | ||
|
|
90597530a4 | ||
|
|
b2af8da9a2 | ||
|
|
05dbf41fdc | ||
|
|
c56bb56708 | ||
|
|
4def1ea1dc | ||
|
|
0ba05e4de0 | ||
|
|
24fce89155 | ||
|
|
1a3c20f91d | ||
|
|
fe3e78cc1c | ||
|
|
749f49b1a0 | ||
|
|
f14010a09d | ||
|
|
0b48b9c7d4 | ||
|
|
13d62b01d1 | ||
|
|
4e7b71db1d | ||
|
|
069fc1f97b | ||
|
|
8684f75254 | ||
|
|
11cd924ce1 | ||
|
|
e2fd0cfc4e | ||
|
|
5eb3106706 | ||
|
|
1831efbe9d | ||
|
|
38edbadca5 | ||
|
|
6fcd80b979 | ||
|
|
cf5e5dbe55 | ||
|
|
a451861bf1 | ||
|
|
7313dd74a6 | ||
|
|
32b9de05f2 | ||
|
|
c79bed22f8 | ||
|
|
cdeb50132d | ||
|
|
090fb09955 | ||
|
|
54b862bd79 | ||
|
|
e37e1c109a | ||
|
|
939123785b | ||
|
|
221b347bd9 | ||
|
|
af9bf3e852 | ||
|
|
ed8746df77 | ||
|
|
bb187db49d | ||
|
|
081e72b3ea | ||
|
|
6188c38053 | ||
|
|
12b0186f5a | ||
|
|
9bccc9c53c | ||
|
|
351b2b320e | ||
|
|
94258feb09 | ||
|
|
8b0f033a78 | ||
|
|
f58f255fc8 | ||
|
|
e3eabcf648 | ||
|
|
9aa506cbd7 | ||
|
|
d8cff7b90f | ||
|
|
07e7bca9eb | ||
|
|
e1f442be90 | ||
|
|
c5d579e0e3 | ||
|
|
5271c2e08f | ||
|
|
9010a7ddbc | ||
|
|
bb95fb7d07 | ||
|
|
2edb11376d | ||
|
|
e7f5ebf912 | ||
|
|
da9758c2f3 | ||
|
|
3e11d58d73 | ||
|
|
6b35c097d6 | ||
|
|
619ba13265 | ||
|
|
529c5b8abf | ||
|
|
3a5ed6e800 | ||
|
|
52cddc015b | ||
|
|
4a01f4f65f | ||
|
|
f9768cb5a3 | ||
|
|
221e0e550c | ||
|
|
d2d1d42d0f | ||
|
|
faf018a097 | ||
|
|
a2a71a107e | ||
|
|
fc9c937e67 | ||
|
|
b4f2e9b442 | ||
|
|
1672645e73 | ||
|
|
4a42c44101 | ||
|
|
383b1a5769 | ||
|
|
77bac4cf9e | ||
|
|
e2b8e530c9 | ||
|
|
e9f752bd67 | ||
|
|
4b31921eb4 | ||
|
|
3df9fc6225 | ||
|
|
b57fe466ce | ||
|
|
bd4bff3b6b | ||
|
|
9d4618a223 | ||
|
|
93636180df | ||
|
|
fcceaa168f | ||
|
|
2639cc6138 | ||
|
|
4a99c2e928 | ||
|
|
7d5af3df05 | ||
|
|
c88b80d2a0 | ||
|
|
819d4abaa2 | ||
|
|
20630aeb47 | ||
|
|
0c0db3babb | ||
|
|
e7761f7e57 | ||
|
|
064fd497ae | ||
|
|
49c60b6b75 | ||
|
|
ca7f36506c | ||
|
|
155f0a9736 | ||
|
|
25e1eb3ce9 | ||
|
|
f2f980928b | ||
|
|
1d121a97a7 | ||
|
|
211d13da09 | ||
|
|
11343d469e | ||
|
|
d7c8041aa1 | ||
|
|
9587e30af8 | ||
|
|
76fa7affaf | ||
|
|
2971dd8672 | ||
|
|
2a33fe3564 | ||
|
|
46cdf5da70 | ||
|
|
28c801bfd4 | ||
|
|
c22cd40293 | ||
|
|
56bd430983 | ||
|
|
d873890e46 | ||
|
|
d29b8eca3c | ||
|
|
6f258000fe | ||
|
|
255211cd07 | ||
|
|
f6d28a90e3 | ||
|
|
ed66ff88a1 | ||
|
|
82e58f2bf9 | ||
|
|
797a87ca26 | ||
|
|
ec6a709393 | ||
|
|
07cbfdb424 | ||
|
|
3b9bd944fb | ||
|
|
934e585cb3 | ||
|
|
3a68f4cf54 | ||
|
|
bd00fcb875 | ||
|
|
905dd5a70f | ||
|
|
c65250ec39 | ||
|
|
607eec6ff0 | ||
|
|
14fb3bde60 | ||
|
|
6782bc8ca2 | ||
|
|
3db6841305 | ||
|
|
f478fa8029 | ||
|
|
d255f8400f | ||
|
|
a1545c60d6 | ||
|
|
ed48603ab5 | ||
|
|
23a0507439 | ||
|
|
482e013887 | ||
|
|
265727c30f | ||
|
|
4d3f4e096b | ||
|
|
7629bca62d | ||
|
|
2712f17262 | ||
|
|
86a37559ba | ||
|
|
b504a557f4 | ||
|
|
e849b46f6b | ||
|
|
738dc50a6f | ||
|
|
3138523b5b | ||
|
|
537643a4c3 | ||
|
|
04bfe098ed | ||
|
|
c507887bdd | ||
|
|
ee261313ac | ||
|
|
c9c152bc8a | ||
|
|
6c8e19a321 | ||
|
|
218e3b66f2 | ||
|
|
1d3488fa8e | ||
|
|
f4c1682592 | ||
|
|
28ac6623c7 | ||
|
|
16ab179e1d | ||
|
|
a8ff5385dc | ||
|
|
9dc33c6086 | ||
|
|
b17c576705 | ||
|
|
96f8f2891b | ||
|
|
581d73afe0 | ||
|
|
1baefebe8f | ||
|
|
39fb05033f | ||
|
|
c6093c084c | ||
|
|
dfec6d9a6d | ||
|
|
08b1261c75 | ||
|
|
2ad6faae3a | ||
|
|
4eff301db3 | ||
|
|
447e43e8f4 | ||
|
|
7457001275 | ||
|
|
fcabd5e79e | ||
|
|
594002316c | ||
|
|
eccf92ebaf | ||
|
|
ad9ddc5621 | ||
|
|
1825dd916e | ||
|
|
dfcde8171e | ||
|
|
b0361183df | ||
|
|
71fe13b249 | ||
|
|
442f51224d | ||
|
|
974678f500 | ||
|
|
8329409c03 | ||
|
|
06c2ac2724 | ||
|
|
04e9e8f9d8 | ||
|
|
7a3330cb8c | ||
|
|
cae29941ea | ||
|
|
15cf2ad076 | ||
|
|
2f16f6dc23 | ||
|
|
528aebffe4 | ||
|
|
e82b2f0cbe | ||
|
|
73e64f3e4a | ||
|
|
15f5b1f830 | ||
|
|
1b0a77f9a8 | ||
|
|
0f82ae3644 | ||
|
|
de3b01b54b | ||
|
|
c17e3646d5 | ||
|
|
26aed3e89e | ||
|
|
74caea8f8f | ||
|
|
2cf07fa072 | ||
|
|
1181cd2fd7 | ||
|
|
850d55ab45 | ||
|
|
a0c91b8754 | ||
|
|
937bdc05c8 | ||
|
|
453755bfa1 | ||
|
|
400b6fbb61 | ||
|
|
8c4e882fa3 | ||
|
|
84eec23793 | ||
|
|
7dfe69f6a5 | ||
|
|
ada6115073 | ||
|
|
e1643566f9 | ||
|
|
053a9a6317 | ||
|
|
425b976cc0 | ||
|
|
5f5f1b1e09 | ||
|
|
e6f4935c7b | ||
|
|
6452e5976b | ||
|
|
2383dff317 | ||
|
|
de3e5042fb | ||
|
|
0dcc35152c | ||
|
|
8eecfcbfaf | ||
|
|
efa3e60f89 | ||
|
|
782df659bc | ||
|
|
0aa158824f | ||
|
|
da7fb44e5d | ||
|
|
4b59ef802e | ||
|
|
be5789cd56 | ||
|
|
9adf0e5d59 | ||
|
|
e2de22470e | ||
|
|
3b7ab2e553 | ||
|
|
8617dedc46 | ||
|
|
0b8f1a9a58 | ||
|
|
16748c0920 | ||
|
|
01ec585a44 | ||
|
|
b5f2295f37 | ||
|
|
d6ca0199b7 | ||
|
|
2257c5e547 | ||
|
|
b5a3d39799 | ||
|
|
a26c3e9d3c | ||
|
|
98a09532eb | ||
|
|
d736789bbc | ||
|
|
82a6cfc03a | ||
|
|
62e9c7c75a | ||
|
|
eb32bd45e7 | ||
|
|
4b95f07923 | ||
|
|
dea8ad4c49 | ||
|
|
96553b217c | ||
|
|
3f79ed5d91 | ||
|
|
1e4283aad3 | ||
|
|
1dda31a28c | ||
|
|
10c87012be | ||
|
|
bda00bf512 | ||
|
|
c8f871ff2a | ||
|
|
58dc0b1aef | ||
|
|
4cd4d8f31a | ||
|
|
b751fd738d | ||
|
|
f97c6fb94c | ||
|
|
219138ade6 | ||
|
|
9086d189b9 | ||
|
|
d1178defe0 | ||
|
|
691a561a95 | ||
|
|
aaaac93bd0 | ||
|
|
fd790566b2 | ||
|
|
db3b429784 | ||
|
|
40ed3278d4 | ||
|
|
d174b13111 | ||
|
|
1708663b32 | ||
|
|
6fdce4ad0d | ||
|
|
fff8d5f07d | ||
|
|
9c8e1f4706 | ||
|
|
0a1036c78f | ||
|
|
0e881a7972 | ||
|
|
839e52ba30 | ||
|
|
8f7d5dcb4d | ||
|
|
1104b28bc1 | ||
|
|
48521cb1e4 | ||
|
|
17e113dafb | ||
|
|
c33825a904 | ||
|
|
b07ef98c8f | ||
|
|
b3d68893df | ||
|
|
1329599987 | ||
|
|
2adf3f364c | ||
|
|
436ee34a02 | ||
|
|
4a6e17b214 | ||
|
|
6e9cbccde6 | ||
|
|
a0cb8ec124 | ||
|
|
21217dfda3 | ||
|
|
25ba18e570 | ||
|
|
a210377f35 | ||
|
|
07b9ca457f | ||
|
|
5f1372d39c | ||
|
|
01b84c79f0 | ||
|
|
4017443b1e | ||
|
|
fd2a17d244 | ||
|
|
126804f7c3 |
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
* text=auto
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,3 +1,5 @@
|
||||
*.custom.*
|
||||
.DS_Store
|
||||
*.custom.*
|
||||
node_modules/
|
||||
vendor/closure-compiler/
|
||||
vendor/uglifyjs/
|
||||
|
||||
16
.jamignore
16
.jamignore
@@ -1,14 +1,12 @@
|
||||
*.custom.*
|
||||
.*
|
||||
*.custom.*
|
||||
*.md
|
||||
*.txt
|
||||
build.js
|
||||
index.js
|
||||
build/
|
||||
doc/*.php
|
||||
doc/
|
||||
node_modules/
|
||||
perf/*.sh
|
||||
test/*.sh
|
||||
test/test-build.js
|
||||
test/template/
|
||||
vendor/closure-compiler
|
||||
vendor/docdown
|
||||
vendor/uglifyjs
|
||||
perf/
|
||||
test/
|
||||
vendor/
|
||||
|
||||
14
.npmignore
14
.npmignore
@@ -1,15 +1,27 @@
|
||||
*.custom.*
|
||||
.*
|
||||
*.custom.*
|
||||
*.d.ts
|
||||
CONTRIBUTING.md
|
||||
doc/*.php
|
||||
node_modules/
|
||||
perf/*.html
|
||||
perf/*-ui.js
|
||||
perf/*.sh
|
||||
test/*.html
|
||||
test/*-ui.js
|
||||
test/*.sh
|
||||
vendor/*.gz
|
||||
vendor/backbone/
|
||||
vendor/benchmark.js/*.jar
|
||||
vendor/closure-compiler/
|
||||
vendor/docdown/
|
||||
vendor/firebug-lite/
|
||||
vendor/json3/
|
||||
vendor/jquery/
|
||||
vendor/platform.js/
|
||||
vendor/qunit/qunit/*.css
|
||||
vendor/qunit/qunit/*-1.8.0.js
|
||||
vendor/requirejs/
|
||||
vendor/underscore/*-min.js
|
||||
vendor/uglifyjs/
|
||||
vendor/underscore/test/
|
||||
|
||||
18
.travis.yml
18
.travis.yml
@@ -1,4 +1,20 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 0.6
|
||||
- 0.8
|
||||
- 0.9
|
||||
env:
|
||||
- TEST_COMMAND="phantomjs ./test/test.js ../dist/lodash.compat.js"
|
||||
- TEST_COMMAND="phantomjs ./test/test.js ../dist/lodash.compat.min.js"
|
||||
- TEST_COMMAND="node ./test/test.js ../dist/lodash.js"
|
||||
- TEST_COMMAND="node ./test/test.js ../dist/lodash.min.js"
|
||||
- TEST_COMMAND="node ./test/test-build.js --time-limit 49m40s"
|
||||
git:
|
||||
depth: 1
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
before_script:
|
||||
- "tar -xzvf vendor/closure-compiler.tar.gz -C vendor"
|
||||
- "tar -xzvf vendor/uglifyjs.tar.gz -C vendor"
|
||||
script:
|
||||
$TEST_COMMAND
|
||||
|
||||
35
CONTRIBUTING.md
Normal file
35
CONTRIBUTING.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# Contributing to Lo-Dash
|
||||
|
||||
If you’d like to contribute a feature or bug fix, you can [fork](https://help.github.com/articles/fork-a-repo) Lo-Dash, commit your changes, and [send a pull request](https://help.github.com/articles/using-pull-requests).
|
||||
Please make sure to [search the issue tracker](https://github.com/bestiejs/lodash/issues) first; your issue may have already been discussed or fixed in `master`.
|
||||
|
||||
## Tests
|
||||
|
||||
Include updated unit tests in the `test` directory as part of your pull request.
|
||||
You can run the tests from the command line via `npm test`, or open `test/index.html` in a web browser.
|
||||
The `test/run-test.sh` script attempts to run the tests in [Rhino](https://developer.mozilla.org/en-US/docs/Rhino), [Narwhal](https://github.com/280north/narwhal), [RingoJS](http://ringojs.org/), [PhantomJS](http://phantomjs.org/), and [Node](http://nodejs.org/), before running them in your default browser.
|
||||
The [Backbone](http://backbonejs.org/) and [Underscore](http://http://underscorejs.org/) test suites are included as well.
|
||||
|
||||
## Contributor License Agreement
|
||||
|
||||
Lo-Dash is a member of the [Dojo Foundation](http://dojofoundation.org/).
|
||||
As such, we request that all contributors sign the Dojo Foundation [contributor license agreement](http://dojofoundation.org/about/claForm).
|
||||
|
||||
For more information about CLAs, please check out Alex Russell’s excellent post, ["Why Do I Need to Sign This?"](http://infrequently.org/2008/06/why-do-i-need-to-sign-this/).
|
||||
|
||||
## Coding Guidelines
|
||||
|
||||
In addition to the following guidelines, please follow the conventions already established in the code.
|
||||
|
||||
- **Spacing**:<br>
|
||||
Use two spaces for indentation. No tabs.
|
||||
|
||||
- **Naming**:<br>
|
||||
Keep variable and method names concise and descriptive.<br>
|
||||
Variable names `index`, `collection`, and `callback` are preferable to `i`, `arr`, and `fn`.
|
||||
|
||||
- **Quotes**:<br>
|
||||
Single-quoted strings are preferred to double-quoted strings; however, please use a double-quoted string if the value contains a single-quote character to avoid unnecessary escaping.
|
||||
|
||||
- **Comments**:<br>
|
||||
Please use single-line comments to annotate significant additions, and [JSDoc-style](http://www.2ality.com/2011/08/jsdoc-intro.html) comments for new methods.
|
||||
@@ -1,6 +1,6 @@
|
||||
Copyright 2012 John-David Dalton <http://allyoucanleet.com/>
|
||||
Based on Underscore.js 1.3.3, copyright 2009-2012 Jeremy Ashkenas,
|
||||
DocumentCloud Inc. <http://documentcloud.github.com/underscore>
|
||||
Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
|
||||
Based on Underscore.js 1.4.3, copyright 2009-2013 Jeremy Ashkenas,
|
||||
DocumentCloud Inc. <http://underscorejs.org/>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
||||
250
README.md
250
README.md
@@ -1,54 +1,84 @@
|
||||
# Lo-Dash <sup>v0.8.0</sup>
|
||||
# Lo-Dash <sup>v1.1.0</sup>
|
||||
[](http://travis-ci.org/bestiejs/lodash)
|
||||
|
||||
A drop-in replacement<sup>[*](https://github.com/bestiejs/lodash/wiki/Drop-in-Disclaimer)</sup> for Underscore.js, from the devs behind [jsPerf.com](http://jsperf.com), delivering [performance](http://lodash.com/benchmarks), [bug fixes](https://github.com/bestiejs/lodash#resolved-underscorejs-issues), and [additional features](http://lodash.com/#features).
|
||||
|
||||
Lo-Dash’s performance is gained by avoiding slower native methods, instead opting for simplified non-ES5 compliant methods optimized for common usage, and by leveraging function compilation to reduce the number of overall function calls.
|
||||
A low-level utility library delivering consistency, [customization](https://github.com/bestiejs/lodash#custom-builds), [performance](http://lodash.com/benchmarks), and [extra features](https://github.com/bestiejs/lodash#features).
|
||||
|
||||
## Download
|
||||
|
||||
* [Development build](https://raw.github.com/bestiejs/lodash/v0.8.0/lodash.js)
|
||||
* [Production build](https://raw.github.com/bestiejs/lodash/v0.8.0/lodash.min.js)
|
||||
* [Underscore build](https://raw.github.com/bestiejs/lodash/v0.8.0/lodash.underscore.min.js) tailored for projects already using Underscore
|
||||
* CDN copies of ≤ [v0.8.0](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/0.8.0/lodash.min.js) are available on [cdnjs](http://cdnjs.com/) thanks to [CloudFlare](http://www.cloudflare.com/)
|
||||
* For optimal file size, [create a custom build](https://github.com/bestiejs/lodash#custom-builds) with only the features you need
|
||||
* Lo-Dash builds (for modern environments):<br>
|
||||
[Development](https://raw.github.com/bestiejs/lodash/v1.1.0/dist/lodash.js) and
|
||||
[Production](https://raw.github.com/bestiejs/lodash/v1.1.0/dist/lodash.min.js)
|
||||
|
||||
* Lo-Dash compatibility builds (for legacy and modern environments):<br>
|
||||
[Development](https://raw.github.com/bestiejs/lodash/v1.1.0/dist/lodash.compat.js) and
|
||||
[Production](https://raw.github.com/bestiejs/lodash/v1.1.0/dist/lodash.compat.min.js)
|
||||
|
||||
* Underscore compatibility builds:<br>
|
||||
[Development](https://raw.github.com/bestiejs/lodash/v1.1.0/dist/lodash.underscore.js) and
|
||||
[Production](https://raw.github.com/bestiejs/lodash/v1.1.0/dist/lodash.underscore.min.js)
|
||||
|
||||
* CDN copies of ≤ v1.1.0’s builds are available on [cdnjs](http://cdnjs.com/) thanks to [CloudFlare](http://www.cloudflare.com/):<br>
|
||||
[Lo-Dash dev](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.1.0/lodash.js),
|
||||
[Lo-Dash prod](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.1.0/lodash.min.js),<br>
|
||||
[Lo-Dash compat-dev](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.1.0/lodash.compat.js),
|
||||
[Lo-Dash compat-prod](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.1.0/lodash.compat.min.js),<br>
|
||||
[Underscore compat-dev](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.1.0/lodash.underscore.js), and
|
||||
[Underscore compat-prod](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.1.0/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
|
||||
|
||||
We’ve 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
|
||||
## Resources
|
||||
|
||||
For more information check out these screencasts over Lo-Dash:
|
||||
For more information check out these articles, screencasts, and other videos over Lo-Dash:
|
||||
|
||||
* [Introducing Lo-Dash](https://vimeo.com/44154599)
|
||||
* [Lo-Dash optimizations and custom builds](https://vimeo.com/44154601)
|
||||
* [Lo-Dash’s origin and why it’s a better utility belt](https://vimeo.com/44154600)
|
||||
* [Unit testing in Lo-Dash](https://vimeo.com/45865290)
|
||||
* [Lo-Dash’s approach to native method use](https://vimeo.com/48576012)
|
||||
* Posts
|
||||
- [Say “Hello” to Lo-Dash](http://kitcambridge.be/blog/say-hello-to-lo-dash/)
|
||||
|
||||
* Videos
|
||||
- [Introducing Lo-Dash](https://vimeo.com/44154599)
|
||||
- [Lo-Dash optimizations and custom builds](https://vimeo.com/44154601)
|
||||
- [Lo-Dash’s origin and why it’s a better utility belt](https://vimeo.com/44154600)
|
||||
- [Unit testing in Lo-Dash](https://vimeo.com/45865290)
|
||||
- [Lo-Dash’s 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 ([RequireJS](http://requirejs.org/), [curl.js](https://github.com/cujojs/curl), etc.)
|
||||
* [_.clone](http://lodash.com/docs#clone) supports *“deep”* cloning
|
||||
* [_(…)](http://lodash.com/docs#_) supports intuitive chaining
|
||||
* [_.at](http://lodash.com/docs#at) for cherry-picking collection values
|
||||
* [_.bindKey](http://lodash.com/docs#bindKey) for binding [*“lazy”* defined](http://michaux.ca/articles/lazy-function-definition-pattern) methods
|
||||
* [_.cloneDeep](http://lodash.com/docs#cloneDeep) for deep cloning arrays and objects
|
||||
* [_.contains](http://lodash.com/docs#contains) accepts a `fromIndex` argument
|
||||
* [_.createCallback](http://lodash.com/docs#createCallback) to customize how callback arguments are handled and support callback shorthands in mixins
|
||||
* [_.findIndex](http://lodash.com/docs#findIndex) and [_.findKey](http://lodash.com/docs#findKey) for finding indexes and keys of collections
|
||||
* [_.forEach](http://lodash.com/docs#forEach) is chainable and supports exiting iteration early
|
||||
* [_.forIn](http://lodash.com/docs#forIn) for iterating over an object’s own and inherited properties
|
||||
* [_.forOwn](http://lodash.com/docs#forOwn) for iterating over an object’s own properties
|
||||
* [_.lateBind](http://lodash.com/docs#lateBind) for late binding
|
||||
* [_.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) accept `callback` and `thisArg` arguments
|
||||
* [_.template](http://lodash.com/docs#template) utilizes [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) for easier debugging
|
||||
* [_.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)
|
||||
* [_.parseInt](http://lodash.com/docs#parseInt) for consistent cross-environment behavior
|
||||
* [_.partial](http://lodash.com/docs#partial) and [_.partialRight](http://lodash.com/docs#partialRight) for partial application without `this` binding
|
||||
* [_.runInContext](http://lodash.com/docs#runInContext) for easier mocking and extended environment support
|
||||
* [_.support](http://lodash.com/docs#support) to flag environment features
|
||||
* [_.template](http://lodash.com/docs#template) supports [*“imports”* options](http://lodash.com/docs#templateSettings_imports), [ES6 template delimiters](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-7.8.6), and [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
|
||||
* [_.where](http://lodash.com/docs#where) supports deep object comparisons
|
||||
* [_.clone](http://lodash.com/docs#clone), [_.omit](http://lodash.com/docs#omit), [_.pick](http://lodash.com/docs#pick),
|
||||
[and more…](http://lodash.com/docs "_.assign, _.cloneDeep, _.first, _.initial, _.isEqual, _.last, _.merge, _.rest") accept `callback` and `thisArg` arguments
|
||||
* [_.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, _.pluck, _.reduce, _.reduceRight, _.reject, _.some, _.sortBy, _.where") accept strings
|
||||
[and more…](http://lodash.com/docs "_.at, _.countBy, _.every, _.filter, _.find, _.forEach, _.groupBy, _.invoke, _.map, _.max, _.min, _.pluck, _.reduce, _.reduceRight, _.reject, _.shuffle, _.some, _.sortBy, _.where") accept strings
|
||||
* [_.filter](http://lodash.com/docs#filter), [_.find](http://lodash.com/docs#find), [_.map](http://lodash.com/docs#map),
|
||||
[and more…](http://lodash.com/docs "_.countBy, _.every, _.first, _.groupBy, _.initial, _.last, _.max, _.min, _.reject, _.rest, _.some, _.sortBy, _.sortedIndex, _.uniq") support *“_.pluck”* and *“_.where”* `callback` shorthands
|
||||
|
||||
## Support
|
||||
|
||||
Lo-Dash has been tested in at least Chrome 5-22, Firefox 1-15, IE 6-10, Opera 9.25-12, Safari 3-6, Node.js 0.4.8-0.8.11, Narwhal 0.3.2, RingoJS 0.8, and Rhino 1.7RC5.
|
||||
Lo-Dash has been tested in at least Chrome 5~25, Firefox 2~19, IE 6-10, Opera 9.25-12, Safari 3-6, Node.js 0.4.8-0.10.1, Narwhal 0.3.2, PhantomJS 1.8.1, RingoJS 0.9, and Rhino 1.7RC5.
|
||||
|
||||
## Custom builds
|
||||
|
||||
@@ -60,17 +90,23 @@ To top it off, we handle all method dependency and alias mapping for you.
|
||||
lodash backbone
|
||||
```
|
||||
|
||||
* CSP builds, supporting default Content Security Policy restrictions, may be created using the `csp` modifier argument.
|
||||
* CSP builds, supporting default [Content Security Policy](https://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 alias of the `mobile` modifier. Lo-Dash may be used in Chrome extensions by using either the `csp`, `mobile`, or `underscore` build and using precompiled templates, or loading Lo-Dash in a [sandbox](http://developer.chrome.com/stable/extensions/sandboxingEval.html).
|
||||
```bash
|
||||
lodash csp
|
||||
```
|
||||
|
||||
* Legacy builds, tailored for older browsers without [ES5 support](http://es5.github.com/), may be created using the `legacy` modifier argument.
|
||||
* Legacy builds, tailored for older environments without [ES5 support](http://es5.github.com/), may be created using the `legacy` modifier argument.
|
||||
```bash
|
||||
lodash legacy
|
||||
```
|
||||
|
||||
* Mobile builds, with IE < 9 bug fixes and method compilation removed, may be created using the `mobile` modifier argument.
|
||||
* Modern builds, tailored for newer environments with ES5 support, may be created using the `modern` modifier argument.
|
||||
```bash
|
||||
lodash modern
|
||||
```
|
||||
|
||||
* Mobile builds, without method compilation and most bug fixes for old browsers, may be created using the `mobile` modifier argument.
|
||||
```bash
|
||||
lodash mobile
|
||||
```
|
||||
@@ -124,28 +160,34 @@ 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
|
||||
* 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
|
||||
* Use the `settings` argument to pass the template settings used when precompiling templates.
|
||||
```bash
|
||||
lodash settings="{interpolate:/\\{\\{([\\s\\S]+?)\\}\\}/g}"
|
||||
lodash settings="{interpolate:/\{\{([\s\S]+?)\}\}/g}"
|
||||
```
|
||||
|
||||
All arguments, except `legacy` with `csp` or `mobile`, may be combined.<br>
|
||||
* 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`, `mobile`, `modern`, or `underscore`, 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` Write output to standard output
|
||||
* `-d`, `--debug` Write only the debug output
|
||||
* `-h`, `--help` Display help information
|
||||
* `-m`, `--minify` Write only the minified output
|
||||
* `-o`, `--output` Write output to a given path/filename
|
||||
* `-s`, `--silent` Skip status updates normally logged to the console
|
||||
* `-V`, `--version` Output current version of Lo-Dash
|
||||
* `-c`, `--stdout` ......... Write output to standard output
|
||||
* `-d`, `--debug` ........... Write only the non-minified development output
|
||||
* `-h`, `--help` ............. Display help information
|
||||
* `-m`, `--minify` ......... Write only the minified production output
|
||||
* `-o`, `--output` ......... Write output to a given path/filename
|
||||
* `-p`, `--source-map` .. Generate a source map for the minified output, using an optional source map URL
|
||||
* `-s`, `--silent` ......... Skip status updates normally logged to the console
|
||||
* `-V`, `--version` ....... 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`).
|
||||
|
||||
@@ -157,20 +199,33 @@ In browsers:
|
||||
<script src="lodash.js"></script>
|
||||
```
|
||||
|
||||
Using [npm](http://npmjs.org/):
|
||||
Using [`npm`](http://npmjs.org/):
|
||||
|
||||
```bash
|
||||
npm install lodash
|
||||
|
||||
npm install -g lodash
|
||||
npm link lodash
|
||||
```
|
||||
|
||||
In [Node.js](http://nodejs.org/) and [RingoJS v0.8.0+](http://ringojs.org/):
|
||||
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
|
||||
var _ = require('lodash');
|
||||
|
||||
// or as a drop-in replacement for Underscore
|
||||
var _ = require('lodash/dist/lodash.underscore');
|
||||
```
|
||||
|
||||
In [RingoJS v0.7.0-](http://ringojs.org/):
|
||||
**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 project’s root directory before requiring it.
|
||||
|
||||
In [RingoJS ≤ v0.7.0](http://ringojs.org/):
|
||||
|
||||
```js
|
||||
var _ = require('lodash')._;
|
||||
@@ -195,110 +250,27 @@ require({
|
||||
});
|
||||
```
|
||||
|
||||
## Resolved Underscore.js issues
|
||||
|
||||
* Add AMD loader support [[#431](https://github.com/documentcloud/underscore/pull/431), [test](https://github.com/bestiejs/lodash/blob/v0.8.0/test/test.js#L118-140)]
|
||||
* Allow iteration of objects with a `length` property [[#799](https://github.com/documentcloud/underscore/pull/799), [test](https://github.com/bestiejs/lodash/blob/v0.8.0/test/test.js#L510-516)]
|
||||
* Ensure *“Collections”* methods allow string `collection` arguments [[#247](https://github.com/documentcloud/underscore/issues/247), [#276](https://github.com/documentcloud/underscore/issues/276), [#561](https://github.com/documentcloud/underscore/pull/561), [test](https://github.com/bestiejs/lodash/blob/v0.8.0/test/test.js#L470-487)]
|
||||
* 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/v0.8.0/test/test.js#L526-546)]
|
||||
* 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/v0.8.0/test/test.js#L142-148)]
|
||||
* `_.clone` should allow `deep` cloning [[#595](https://github.com/documentcloud/underscore/pull/595), [test](https://github.com/bestiejs/lodash/blob/v0.8.0/test/test.js#L215-224)]
|
||||
* `_.contains` should work with strings [[#667](https://github.com/documentcloud/underscore/pull/667), [test](https://github.com/bestiejs/lodash/blob/v0.8.0/test/test.js#L267-276)]
|
||||
* `_.extend` should recursively extend objects [[#379](https://github.com/documentcloud/underscore/pull/379), [#718](https://github.com/documentcloud/underscore/issues/718), [test](https://github.com/bestiejs/lodash/blob/v0.8.0/test/test.js#L946-968)]
|
||||
* `_.forEach` should be chainable [[#142](https://github.com/documentcloud/underscore/issues/142), [test](https://github.com/bestiejs/lodash/blob/v0.8.0/test/test.js#L465-468)]
|
||||
* `_.forEach` should allow exiting iteration early [[#211](https://github.com/documentcloud/underscore/issues/211), [test](https://github.com/bestiejs/lodash/blob/v0.8.0/test/test.js#L556-570)]
|
||||
* `_.isEmpty` should support jQuery/MooTools DOM query collections [[#690](https://github.com/documentcloud/underscore/pull/690), [test](https://github.com/bestiejs/lodash/blob/v0.8.0/test/test.js#L703-708)]
|
||||
* `_.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/v0.8.0/test/test.js#L763-775)]
|
||||
* `_.keys` should work with `arguments` objects cross-browser [[#396](https://github.com/documentcloud/underscore/issues/396), [test](https://github.com/bestiejs/lodash/blob/v0.8.0/test/test.js#L856-858)]
|
||||
* `_.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/v0.8.0/test/test.js#L1222-1225)]
|
||||
* `_.throttle` should work when called in a loop [[#502](https://github.com/documentcloud/underscore/issues/502), [test](https://github.com/bestiejs/lodash/blob/v0.8.0/test/test.js#L1525-1535)]
|
||||
|
||||
## Optimized methods <sup>(50+)</sup>
|
||||
|
||||
* `_.bind`
|
||||
* `_.bindAll`
|
||||
* `_.compact`
|
||||
* `_.contains`, `_.include`
|
||||
* `_.defaults`
|
||||
* `_.difference`
|
||||
* `_.each`
|
||||
* `_.every`, `_.all`
|
||||
* `_.extend`
|
||||
* `_.filter`, `_.select`
|
||||
* `_.find`, `_.detect`
|
||||
* `_.flatten`
|
||||
* `_.forEach`, `_.each`
|
||||
* `_.functions`, `_.methods`
|
||||
* `_.groupBy`
|
||||
* `_.indexOf`
|
||||
* `_.intersection`
|
||||
* `_.invert`
|
||||
* `_.invoke`
|
||||
* `_.isArguments`
|
||||
* `_.isDate`
|
||||
* `_.isFinite`
|
||||
* `_.isFunction`
|
||||
* `_.isObject`
|
||||
* `_.isNumber`
|
||||
* `_.isRegExp`
|
||||
* `_.isString`
|
||||
* `_.keys`
|
||||
* `_.lastIndexOf`
|
||||
* `_.map`, `_.collect`
|
||||
* `_.max`
|
||||
* `_.memoize`
|
||||
* `_.min`
|
||||
* `_.mixin`
|
||||
* `_.omit`
|
||||
* `_.pairs`
|
||||
* `_.pick`
|
||||
* `_.pluck`
|
||||
* `_.reduce`, `_.foldl`, `_.inject`
|
||||
* `_.reject`
|
||||
* `_.result`
|
||||
* `_.shuffle`
|
||||
* `_.some`, `_.any`
|
||||
* `_.sortBy`
|
||||
* `_.sortedIndex`
|
||||
* `_.template`
|
||||
* `_.throttle`
|
||||
* `_.toArray`
|
||||
* `_.union`
|
||||
* `_.uniq`, `_.unique`
|
||||
* `_.values`
|
||||
* `_.where`
|
||||
* `_.without`
|
||||
* `_.wrap`
|
||||
* `_.zip`
|
||||
* plus all `_(…)` method wrappers
|
||||
|
||||
## Release Notes
|
||||
|
||||
### <sup>v0.8.0</sup>
|
||||
### <sup>v1.1.0</sup>
|
||||
|
||||
#### Compatibility Warnings ####
|
||||
|
||||
* Made `_.random` return `0` or `1` when no arguments are passed
|
||||
* Moved late bind functionality from `_.bind` to [_.lateBind](http://lodash.com/docs#lateBind)
|
||||
* Removed first argument falsey checks from methods
|
||||
* Removed support for custom `clone`, `isEqual`, `toArray` methods from<br>
|
||||
`_.clone`, `_.isEqual`, and `_.toArray`
|
||||
|
||||
#### Changes ####
|
||||
|
||||
* Added `-d`/`--debug`, `-m/--minify`, `minus`, `plus`, `settings`, and `template` build options
|
||||
* Added `_.isPlainObject` and `_.lateBind`
|
||||
* Allowed `_.sortedIndex` to accept a property name as the `callback` argument
|
||||
* Ensured methods accept a `thisArg` of `null`
|
||||
* Fixed the `iife` build option to accept more values
|
||||
* Made `_.times` return an array of `callback` results
|
||||
* Simplified `_.max`, `_.min`, and `_.reduceRight`
|
||||
* Added `rhino -require` support
|
||||
* Added `_.createCallback`, `_findIndex`, `_.findKey`, `_.parseInt`, `_.runInContext`, and `_.support`
|
||||
* Added support for `callback` and `thisArg` arguments to `_.flatten`
|
||||
* Added CommonJS/Node support to precompiled templates
|
||||
* Ensured the `exports` object is not a DOM element
|
||||
* Ensured `_.isPlainObject` returns `false` for objects without a `[[Class]]` of “Object”
|
||||
* Made `_.cloneDeep`’s `callback` support more closely follow its documentation
|
||||
* Made the template precompiler create nonexistent directories of `--output` paths
|
||||
* Made `_.object` an alias of `_.zipObject`
|
||||
* Optimized method chaining, object iteration, `_.find`, and `_.pluck` (an average of 18% overall better performance)
|
||||
* Updated `backbone` build Lo-Dash method dependencies
|
||||
|
||||
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
|
||||
|
||||
|
||||
688
build/minify.js
688
build/minify.js
@@ -2,42 +2,98 @@
|
||||
;(function() {
|
||||
'use strict';
|
||||
|
||||
/** The Node filesystem, path, `zlib`, and child process modules */
|
||||
/** Load Node.js modules */
|
||||
var fs = require('fs'),
|
||||
gzip = require('zlib').gzip,
|
||||
https = require('https'),
|
||||
path = require('path'),
|
||||
spawn = require('child_process').spawn;
|
||||
|
||||
/** The directory that is the base of the repository */
|
||||
var basePath = fs.realpathSync(path.join(__dirname, '..'));
|
||||
|
||||
/** The directory where the Closure Compiler is located */
|
||||
var closurePath = path.join(basePath, 'vendor', 'closure-compiler', 'compiler.jar');
|
||||
spawn = require('child_process').spawn,
|
||||
zlib = require('zlib');
|
||||
|
||||
/** Load other modules */
|
||||
var preprocess = require('./pre-compile'),
|
||||
postprocess = require('./post-compile'),
|
||||
uglifyJS = require('../vendor/uglifyjs/uglify-js');
|
||||
var _ = require('../lodash.js'),
|
||||
mkdirpSync = require('./mkdirp-sync.js'),
|
||||
preprocess = require('./pre-compile.js'),
|
||||
postprocess = require('./post-compile.js'),
|
||||
tar = require('../vendor/tar/tar.js');
|
||||
|
||||
/** Closure Compiler command-line options */
|
||||
var closureOptions = [
|
||||
'--compilation_level=ADVANCED_OPTIMIZATIONS',
|
||||
'--warning_level=QUIET'
|
||||
];
|
||||
|
||||
/** Reassign `existsSync` for older versions of Node */
|
||||
/** Add `fs.existsSync` for older versions of Node.js */
|
||||
fs.existsSync || (fs.existsSync = path.existsSync);
|
||||
|
||||
/** Add `path.sep` for older versions of Node.js */
|
||||
path.sep || (path.sep = process.platform == 'win32' ? '\\' : '/');
|
||||
|
||||
/** The Git object ID of `closure-compiler.tar.gz` */
|
||||
var closureId = 'a95a8007892aa824ce90c6aa3d3abb0489bf0fff';
|
||||
|
||||
/** The Git object ID of `uglifyjs.tar.gz` */
|
||||
var uglifyId = '41308bd569db41a32d4f08af115875d0342e8bfb';
|
||||
|
||||
/** 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 path to the Closure Compiler `.jar` */
|
||||
var closurePath = path.join(vendorPath, 'closure-compiler', 'compiler.jar');
|
||||
|
||||
/** The path to the UglifyJS module */
|
||||
var uglifyPath = path.join(vendorPath, 'uglifyjs', 'tools', 'node.js');
|
||||
|
||||
/** The Closure Compiler command-line options */
|
||||
var closureOptions = ['--warning_level=QUIET'];
|
||||
|
||||
/** The media type for raw blob data */
|
||||
var mediaType = 'application/vnd.github.v3.raw';
|
||||
|
||||
/** Used to detect the Node.js executable in command-line arguments */
|
||||
var reNode = RegExp('(?:^|' + path.sep + ')node(?:\\.exe)?$');
|
||||
|
||||
/** 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': origin + pathname,
|
||||
'origin': origin,
|
||||
'pathname': pathname
|
||||
};
|
||||
}());
|
||||
|
||||
/** The Closure Compiler optimization modes */
|
||||
var optimizationModes = {
|
||||
'simple': 'SIMPLE_OPTIMIZATIONS',
|
||||
'advanced': 'ADVANCED_OPTIMIZATIONS'
|
||||
};
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* The exposed `minify` function minifies a given Lo-Dash `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 {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, options) {
|
||||
// used to specify the source map URL
|
||||
var sourceMapURL;
|
||||
|
||||
// used to specify the default minifer modes
|
||||
var modes = ['simple', 'advanced', 'hybrid'];
|
||||
|
||||
source || (source = '');
|
||||
options || (options = {});
|
||||
|
||||
@@ -46,28 +102,106 @@
|
||||
// convert commands to an options object
|
||||
options = source;
|
||||
|
||||
// used to report invalid command-line arguments
|
||||
var invalidArgs = _.reject(options.slice(reNode.test(options[0]) ? 2 : 0), function(value, index, options) {
|
||||
if (/^(?:-o|--output)$/.test(options[index - 1]) ||
|
||||
/^modes=.*$/.test(value)) {
|
||||
return true;
|
||||
}
|
||||
var result = [
|
||||
'-o', '--output',
|
||||
'-p', '--source-map',
|
||||
'-s', '--silent',
|
||||
'-t', '--template'
|
||||
].indexOf(value) > -1;
|
||||
|
||||
if (!result && /^(?:-p|--source-map)$/.test(options[index - 1])) {
|
||||
result = true;
|
||||
sourceMapURL = value;
|
||||
}
|
||||
return result;
|
||||
});
|
||||
|
||||
// report invalid arguments
|
||||
if (invalidArgs.length) {
|
||||
console.log(
|
||||
'\n' +
|
||||
'Invalid argument' + (invalidArgs.length > 1 ? 's' : '') +
|
||||
' passed: ' + invalidArgs.join(', ')
|
||||
);
|
||||
return;
|
||||
}
|
||||
var filePath = options[options.length - 1],
|
||||
isSilent = options.indexOf('-s') > -1 || options.indexOf('--silent') > -1,
|
||||
isTemplate = options.indexOf('-t') > -1 || options.indexOf('--template') > -1,
|
||||
isMapped = _.contains(options, '-p') || _.contains(options, '--source-map'),
|
||||
isSilent = _.contains(options, '-s') || _.contains(options, '--silent'),
|
||||
isTemplate = _.contains(options, '-t') || _.contains(options, '--template'),
|
||||
outputPath = path.join(path.dirname(filePath), path.basename(filePath, '.js') + '.min.js');
|
||||
|
||||
modes = options.reduce(function(result, value) {
|
||||
var match = value.match(/modes=(.*)$/);
|
||||
return match ? match[1].split(/, */) : result;
|
||||
}, modes);
|
||||
|
||||
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));
|
||||
var dirname = path.dirname(result);
|
||||
mkdirpSync(dirname);
|
||||
result = path.join(fs.realpathSync(dirname), path.basename(result));
|
||||
}
|
||||
return result;
|
||||
}, outputPath);
|
||||
|
||||
options = {
|
||||
'filePath': filePath,
|
||||
'isMapped': isMapped,
|
||||
'isSilent': isSilent,
|
||||
'isTemplate': isTemplate,
|
||||
'outputPath': outputPath
|
||||
'modes': modes,
|
||||
'outputPath': outputPath,
|
||||
'sourceMapURL': sourceMapURL
|
||||
};
|
||||
|
||||
source = fs.readFileSync(filePath, 'utf8');
|
||||
}
|
||||
new Minify(source, options);
|
||||
|
||||
modes = options.modes || modes;
|
||||
if (options.isMapped) {
|
||||
modes = modes.filter(function(mode) {
|
||||
return mode != 'hybrid';
|
||||
});
|
||||
}
|
||||
if (options.isTemplate) {
|
||||
modes = modes.filter(function(mode) {
|
||||
return mode != 'advanced';
|
||||
});
|
||||
}
|
||||
options.modes = modes;
|
||||
|
||||
// fetch the Closure Compiler
|
||||
getDependency({
|
||||
'id': 'closure-compiler',
|
||||
'hashId': closureId,
|
||||
'path': vendorPath,
|
||||
'title': 'the Closure Compiler',
|
||||
'onComplete': function(exception) {
|
||||
var error = exception;
|
||||
|
||||
// fetch UglifyJS
|
||||
getDependency({
|
||||
'id': 'uglifyjs',
|
||||
'hashId': uglifyId,
|
||||
'title': 'UglifyJS',
|
||||
'path': vendorPath,
|
||||
'onComplete': function(exception) {
|
||||
error || (error = exception);
|
||||
if (!error) {
|
||||
new Minify(source, options);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -77,6 +211,10 @@
|
||||
* @constructor
|
||||
* @param {String} source The source to minify.
|
||||
* @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, options) {
|
||||
// juggle arguments
|
||||
@@ -84,22 +222,118 @@
|
||||
options = source || options;
|
||||
source = options.source || '';
|
||||
}
|
||||
this.compiled = {};
|
||||
this.hybrid = {};
|
||||
this.compiled = { 'simple': {}, 'advanced': {} };
|
||||
this.hybrid = { 'simple': {}, 'advanced': {} };
|
||||
this.uglified = {};
|
||||
|
||||
this.filePath = options.filePath;
|
||||
this.isMapped = !!options.isMapped;
|
||||
this.isSilent = !!options.isSilent;
|
||||
this.isTemplate = !!options.isTemplate;
|
||||
this.outputPath = options.outputPath;
|
||||
this.sourceMapURL = options.sourceMapURL;
|
||||
|
||||
source = preprocess(source, options);
|
||||
this.source = source;
|
||||
var modes = this.modes = options.modes;
|
||||
source = this.source = preprocess(source, options);
|
||||
|
||||
this.onComplete = options.onComplete || function(source) {
|
||||
fs.writeFileSync(this.outputPath, source, 'utf8');
|
||||
this.onComplete = options.onComplete || function(data) {
|
||||
var outputPath = this.outputPath,
|
||||
sourceMap = data.sourceMap;
|
||||
|
||||
fs.writeFileSync(outputPath, data.source, 'utf8');
|
||||
if (sourceMap) {
|
||||
fs.writeFileSync(getMapPath(outputPath), sourceMap, 'utf8');
|
||||
}
|
||||
};
|
||||
|
||||
// begin the minification process
|
||||
closureCompile.call(this, source, onClosureCompile.bind(this));
|
||||
if (_.contains(modes, 'simple')) {
|
||||
closureCompile.call(this, source, 'simple', onClosureSimpleCompile.bind(this));
|
||||
} else if (_.contains(modes, 'advanced')) {
|
||||
onClosureSimpleGzip.call(this);
|
||||
} else {
|
||||
onClosureAdvancedGzip.call(this);
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* 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 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 ran,
|
||||
destPath = options.path,
|
||||
hashId = options.hashId,
|
||||
id = options.id,
|
||||
onComplete = options.onComplete,
|
||||
title = options.title;
|
||||
|
||||
// exit early if dependency exists
|
||||
if (fs.existsSync(path.join(destPath, id))) {
|
||||
onComplete();
|
||||
return;
|
||||
}
|
||||
var callback = function(exception) {
|
||||
if (ran) {
|
||||
return;
|
||||
}
|
||||
if (exception) {
|
||||
console.error([
|
||||
'There was a problem installing ' + title + '.',
|
||||
'Try running the command as root, via `sudo`, or manually install by running:',
|
||||
'',
|
||||
"curl -H 'Accept: " + mediaType + "' " + location.href + '/' + hashId + " | tar xvz -C '" + destPath + "'",
|
||||
''
|
||||
].join('\n'));
|
||||
}
|
||||
ran = true;
|
||||
process.removeListener('uncaughtException', callback);
|
||||
onComplete(exception);
|
||||
};
|
||||
|
||||
console.log('Downloading ' + title + '...');
|
||||
process.on('uncaughtException', callback);
|
||||
|
||||
https.get({
|
||||
'host': location.host,
|
||||
'path': location.pathname + '/' + hashId,
|
||||
'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': destPath });
|
||||
|
||||
parser.on('end', callback);
|
||||
response.pipe(decompressor).pipe(parser);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the source map path from the given output path.
|
||||
*
|
||||
* @private
|
||||
* @param {String} outputPath The output path.
|
||||
* @returns {String} Returns the source map path.
|
||||
*/
|
||||
function getMapPath(outputPath) {
|
||||
return path.join(path.dirname(outputPath), path.basename(outputPath, '.js') + '.map');
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -110,56 +344,86 @@
|
||||
*
|
||||
* @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) {
|
||||
var options = closureOptions.slice();
|
||||
function closureCompile(source, mode, callback) {
|
||||
var filePath = this.filePath,
|
||||
isAdvanced = mode == 'advanced',
|
||||
isMapped = this.isMapped,
|
||||
options = closureOptions.slice(),
|
||||
outputPath = this.outputPath,
|
||||
mapPath = getMapPath(outputPath),
|
||||
sourceMapURL = this.sourceMapURL || path.basename(mapPath);
|
||||
|
||||
// use simple optimizations when minifying template files
|
||||
if (this.isTemplate) {
|
||||
options = options.map(function(value) {
|
||||
return value.replace(/^(compilation_level)=.+$/, '$1=SIMPLE_OPTIMIZATIONS');
|
||||
});
|
||||
// remove copyright header to make other modifications easier
|
||||
var license = (/^(?:\s*\/\/.*\s*|\s*\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/\s*)*/.exec(source) || [''])[0];
|
||||
if (license) {
|
||||
source = source.replace(license, '');
|
||||
}
|
||||
|
||||
// the standard error stream, standard output stream, and Closure Compiler process
|
||||
var error = '',
|
||||
output = '',
|
||||
compiler = spawn('java', ['-jar', closurePath].concat(options));
|
||||
var hasIIFE = /^;?\(function[^{]+{/.test(source),
|
||||
isStrict = hasIIFE && /^;?\(function[^{]+{\s*["']use strict["']/.test(source);
|
||||
|
||||
// juggle arguments
|
||||
if (typeof message == 'function') {
|
||||
callback = message;
|
||||
message = null;
|
||||
// to avoid stripping the IIFE, convert it to a function call
|
||||
if (hasIIFE && isAdvanced) {
|
||||
source = source
|
||||
.replace(/\(function/, '__iife__$&')
|
||||
.replace(/\(this\)\)([\s;]*(\n\/\/.+)?)$/, ', this)$1');
|
||||
}
|
||||
|
||||
options.push('--compilation_level=' + optimizationModes[mode]);
|
||||
if (isMapped) {
|
||||
options.push('--create_source_map=' + mapPath, '--source_map_format=V3');
|
||||
}
|
||||
|
||||
var compiler = spawn('java', ['-jar', closurePath].concat(options));
|
||||
if (!this.isSilent) {
|
||||
console.log(message == null
|
||||
? 'Compressing ' + path.basename(this.outputPath, '.js') + ' using the Closure Compiler...'
|
||||
: message
|
||||
);
|
||||
console.log('Compressing ' + path.basename(outputPath, '.js') + ' using the Closure Compiler (' + mode + ')...');
|
||||
}
|
||||
|
||||
compiler.stdout.on('data', function(data) {
|
||||
// append the data to the output stream
|
||||
output += data;
|
||||
});
|
||||
|
||||
var error = '';
|
||||
compiler.stderr.on('data', function(data) {
|
||||
// append the error message to the error stream
|
||||
error += data;
|
||||
});
|
||||
|
||||
compiler.on('exit', function(status) {
|
||||
var exception = null;
|
||||
var output = '';
|
||||
compiler.stdout.on('data', function(data) {
|
||||
output += data;
|
||||
});
|
||||
|
||||
compiler.on('exit', function(status) {
|
||||
// `status` contains the process exit code
|
||||
if (status) {
|
||||
exception = new Error(error);
|
||||
var exception = new Error(error);
|
||||
exception.status = status;
|
||||
}
|
||||
callback(exception, output);
|
||||
// restore IIFE and move exposed vars inside the IIFE
|
||||
if (hasIIFE && isAdvanced) {
|
||||
output = output
|
||||
.replace(/__iife__\(/, '(')
|
||||
.replace(/,\s*this\)([\s;]*(\n\/\/.+)?)$/, '(this))$1')
|
||||
.replace(/^((?:var (?:\w+=(?:!0|!1|null)[,;])+)?)([\s\S]*?function[^{]+{)/, '$2$1');
|
||||
}
|
||||
// inject "use strict" directive
|
||||
if (isStrict) {
|
||||
output = output.replace(/^[\s\S]*?function[^{]+{/, '$&"use strict";');
|
||||
}
|
||||
// restore copyright header
|
||||
if (license) {
|
||||
output = license + output;
|
||||
}
|
||||
if (isMapped) {
|
||||
var mapOutput = fs.readFileSync(mapPath, 'utf8');
|
||||
fs.unlinkSync(mapPath);
|
||||
output = output.replace(/[\s;]*$/, '\n/*\n//@ sourceMappingURL=' + sourceMapURL) + '\n*/';
|
||||
|
||||
mapOutput = JSON.parse(mapOutput);
|
||||
mapOutput.file = path.basename(outputPath);
|
||||
mapOutput.sources = [path.basename(filePath)];
|
||||
mapOutput = JSON.stringify(mapOutput, null, 2);
|
||||
}
|
||||
callback(exception, output, mapOutput);
|
||||
});
|
||||
|
||||
// proxy the standard input to the Closure Compiler
|
||||
@@ -173,89 +437,147 @@
|
||||
*
|
||||
* @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) {
|
||||
var exception,
|
||||
result,
|
||||
ugly = uglifyJS.uglify;
|
||||
|
||||
// juggle arguments
|
||||
if (typeof message == 'function') {
|
||||
callback = message;
|
||||
message = null;
|
||||
}
|
||||
|
||||
function uglify(source, label, callback) {
|
||||
if (!this.isSilent) {
|
||||
console.log(message == null
|
||||
? 'Compressing ' + path.basename(this.outputPath, '.js') + ' using UglifyJS...'
|
||||
: message
|
||||
);
|
||||
console.log('Compressing ' + path.basename(this.outputPath, '.js') + ' using ' + label + '...');
|
||||
}
|
||||
|
||||
try {
|
||||
result = ugly.gen_code(
|
||||
// enable unsafe transformations
|
||||
ugly.ast_squeeze_more(
|
||||
ugly.ast_squeeze(
|
||||
// munge variable and function names, excluding the special `define`
|
||||
// function exposed by AMD loaders
|
||||
ugly.ast_mangle(uglifyJS.parser.parse(source), {
|
||||
'except': ['define']
|
||||
}
|
||||
))), {
|
||||
'ascii_only': true
|
||||
var uglifyJS = require(uglifyPath);
|
||||
|
||||
// 1. parse
|
||||
var toplevel = uglifyJS.parse(source);
|
||||
|
||||
// 2. compress
|
||||
// enable unsafe comparisons
|
||||
toplevel.figure_out_scope();
|
||||
toplevel = toplevel.transform(uglifyJS.Compressor({
|
||||
'comparisons': false,
|
||||
'unsafe': true,
|
||||
'unsafe_comps': true,
|
||||
'warnings': false
|
||||
}));
|
||||
|
||||
// 3. mangle
|
||||
// excluding the `define` function exposed by AMD loaders
|
||||
toplevel.figure_out_scope();
|
||||
toplevel.compute_char_frequency();
|
||||
toplevel.mangle_names({
|
||||
'except': ['define']
|
||||
});
|
||||
} catch(e) {
|
||||
exception = e;
|
||||
|
||||
// 4. output
|
||||
// restrict lines to 500 characters for consistency with the Closure Compiler
|
||||
var stream = uglifyJS.OutputStream({
|
||||
'ascii_only': true,
|
||||
'comments': /@cc_on|@license|@preserve/i,
|
||||
'max_line_len': 500,
|
||||
});
|
||||
|
||||
toplevel.print(stream);
|
||||
}
|
||||
// lines are restricted to 500 characters for consistency with the Closure Compiler
|
||||
callback(exception, result && ugly.split_lines(result, 500));
|
||||
catch(e) {
|
||||
var exception = e;
|
||||
}
|
||||
callback(exception, stream && String(stream));
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @param {String} map The source map output.
|
||||
*/
|
||||
function onClosureCompile(exception, result) {
|
||||
function onClosureSimpleCompile(exception, result, map) {
|
||||
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);
|
||||
|
||||
var simple = this.compiled.simple;
|
||||
simple.source = result;
|
||||
simple.sourceMap = map;
|
||||
zlib.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;
|
||||
}
|
||||
if (!this.isSilent) {
|
||||
console.log('Done. Size: %d bytes.', result.length);
|
||||
if (result != null) {
|
||||
if (!this.isSilent) {
|
||||
console.log('Done. Size: %d bytes.', result.length);
|
||||
}
|
||||
this.compiled.simple.gzip = result;
|
||||
}
|
||||
// compile the source using advanced optimizations
|
||||
if (_.contains(this.modes, 'advanced')) {
|
||||
closureCompile.call(this, this.source, 'advanced', onClosureAdvancedCompile.bind(this));
|
||||
} else {
|
||||
onClosureAdvancedGzip.call(this);
|
||||
}
|
||||
|
||||
// store the gzipped result and report the size
|
||||
this.compiled.gzip = result;
|
||||
|
||||
// next, minify the source using only UglifyJS
|
||||
uglify.call(this, this.source, onUglify.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.
|
||||
* @param {String} map The source map output.
|
||||
*/
|
||||
function onClosureAdvancedCompile(exception, result, map) {
|
||||
if (exception) {
|
||||
throw exception;
|
||||
}
|
||||
result = postprocess(result);
|
||||
|
||||
var advanced = this.compiled.advanced;
|
||||
advanced.source = result;
|
||||
advanced.sourceMap = map;
|
||||
zlib.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 (result != null) {
|
||||
if (!this.isSilent) {
|
||||
console.log('Done. Size: %d bytes.', result.length);
|
||||
}
|
||||
this.compiled.advanced.gzip = result;
|
||||
}
|
||||
// minify the source using UglifyJS
|
||||
if (!this.isMapped) {
|
||||
uglify.call(this, this.source, 'UglifyJS', onUglify.bind(this));
|
||||
} else {
|
||||
onComplete.call(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The UglifyJS callback.
|
||||
*
|
||||
* @private
|
||||
* @param {Object|Undefined} exception The error object.
|
||||
@@ -265,9 +587,9 @@
|
||||
if (exception) {
|
||||
throw exception;
|
||||
}
|
||||
// store the post-processed Uglified result and gzip it
|
||||
this.uglified.source = result = postprocess(result);
|
||||
gzip(result, onUglifyGzip.bind(this));
|
||||
result = postprocess(result);
|
||||
this.uglified.source = result;
|
||||
zlib.gzip(result, onUglifyGzip.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -281,77 +603,143 @@
|
||||
if (exception) {
|
||||
throw exception;
|
||||
}
|
||||
if (!this.isSilent) {
|
||||
console.log('Done. Size: %d bytes.', result.length);
|
||||
if (result != null) {
|
||||
if (!this.isSilent) {
|
||||
console.log('Done. Size: %d bytes.', result.length);
|
||||
}
|
||||
this.uglified.gzip = result;
|
||||
}
|
||||
// minify the already Closure Compiler simple optimized source using UglifyJS
|
||||
var modes = this.modes;
|
||||
if (_.contains(modes, 'hybrid')) {
|
||||
if (_.contains(modes, 'simple')) {
|
||||
uglify.call(this, this.compiled.simple.source, 'hybrid (simple)', onSimpleHybrid.bind(this));
|
||||
} else if (_.contains(modes, 'advanced')) {
|
||||
onSimpleHybridGzip.call(this);
|
||||
}
|
||||
} else {
|
||||
onComplete.call(this);
|
||||
}
|
||||
var message = 'Compressing ' + path.basename(this.outputPath, '.js') + ' using hybrid minification...';
|
||||
|
||||
// store the gzipped result and report the size
|
||||
this.uglified.gzip = result;
|
||||
|
||||
// next, minify the Closure Compiler minified source using UglifyJS
|
||||
uglify.call(this, this.compiled.source, message, onHybrid.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;
|
||||
zlib.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;
|
||||
}
|
||||
if (!this.isSilent) {
|
||||
console.log('Done. Size: %d bytes.', result.length);
|
||||
if (result != null) {
|
||||
if (!this.isSilent) {
|
||||
console.log('Done. Size: %d bytes.', result.length);
|
||||
}
|
||||
this.hybrid.simple.gzip = result;
|
||||
}
|
||||
// store the gzipped result and report the size
|
||||
this.hybrid.gzip = result;
|
||||
// minify the already Closure Compiler advance optimized source using UglifyJS
|
||||
if (_.contains(this.modes, 'advanced')) {
|
||||
uglify.call(this, this.compiled.advanced.source, 'hybrid (advanced)', onAdvancedHybrid.bind(this));
|
||||
} else {
|
||||
onComplete.call(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;
|
||||
zlib.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 (result != null) {
|
||||
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,
|
||||
uglified = this.uglified;
|
||||
var compiledSimple = this.compiled.simple,
|
||||
compiledAdvanced = this.compiled.advanced,
|
||||
uglified = this.uglified,
|
||||
hybridSimple = this.hybrid.simple,
|
||||
hybridAdvanced = this.hybrid.advanced;
|
||||
|
||||
var objects = [
|
||||
compiledSimple,
|
||||
compiledAdvanced,
|
||||
uglified,
|
||||
hybridSimple,
|
||||
hybridAdvanced
|
||||
];
|
||||
|
||||
var gzips = objects
|
||||
.map(function(data) { return data.gzip; })
|
||||
.filter(Boolean);
|
||||
|
||||
// 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);
|
||||
// official minified release (ties go to the Closure Compiler)
|
||||
var min = gzips.reduce(function(min, gzip) {
|
||||
var length = gzip.length;
|
||||
return min > length ? length : min;
|
||||
}, Infinity);
|
||||
|
||||
// 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
|
||||
);
|
||||
// pass the minified source to the "onComplete" callback
|
||||
objects.some(function(data) {
|
||||
var gzip = data.gzip;
|
||||
if (gzip && gzip.length == min) {
|
||||
data.outputPath = this.outputPath;
|
||||
this.onComplete(data);
|
||||
return true;
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
43
build/mkdirp-sync.js
Executable file
43
build/mkdirp-sync.js
Executable file
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env node
|
||||
;(function() {
|
||||
'use strict';
|
||||
|
||||
/** Load Node.js modules */
|
||||
var fs = require('fs'),
|
||||
path = require('path');
|
||||
|
||||
/** Add `path.sep` for older versions of Node.js */
|
||||
path.sep || (path.sep = process.platform == 'win32' ? '\\' : '/');
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Makes the given `dirname` directory, without throwing errors for existing
|
||||
* directories and making parent directories as needed.
|
||||
*
|
||||
* @param {String} dirname The path of the directory.
|
||||
* @param {Number|String} [mode='0777'] The permission mode.
|
||||
*/
|
||||
function mkdirpSync(dirname, mode) {
|
||||
var sep = path.sep;
|
||||
|
||||
// ensure relative paths are prefixed with `./`
|
||||
if (!RegExp('^\\.?' + sep).test(dirname)) {
|
||||
dirname = '.' + sep + dirname;
|
||||
}
|
||||
dirname.split(sep).reduce(function(currPath, segment) {
|
||||
currPath += sep + segment;
|
||||
try {
|
||||
currPath = fs.realpathSync(currPath);
|
||||
} catch(e) {
|
||||
fs.mkdirSync(currPath, mode);
|
||||
}
|
||||
return currPath;
|
||||
});
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
// expose
|
||||
module.exports = mkdirpSync;
|
||||
}());
|
||||
@@ -2,19 +2,17 @@
|
||||
;(function() {
|
||||
'use strict';
|
||||
|
||||
/** The Node filesystem module */
|
||||
/** The Node.js filesystem module */
|
||||
var fs = require('fs');
|
||||
|
||||
/** The minimal license/copyright template */
|
||||
var licenseTemplate = {
|
||||
'lodash':
|
||||
'/*!\n' +
|
||||
' Lo-Dash @VERSION lodash.com/license\n' +
|
||||
' Underscore.js 1.4.0 underscorejs.org/LICENSE\n' +
|
||||
'*/',
|
||||
'underscore':
|
||||
'/*! Underscore.js @VERSION underscorejs.org/LICENSE */'
|
||||
};
|
||||
var licenseTemplate = [
|
||||
'/**',
|
||||
' * @license',
|
||||
' * Lo-Dash <%= VERSION %> lodash.com/license',
|
||||
' * Underscore.js 1.4.4 underscorejs.org/LICENSE',
|
||||
' */'
|
||||
].join('\n');
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
@@ -26,29 +24,39 @@
|
||||
* @returns {String} Returns the processed source.
|
||||
*/
|
||||
function postprocess(source) {
|
||||
// move vars exposed by Closure Compiler into the IIFE
|
||||
source = source.replace(/^((?:(['"])use strict\2;)?(?:var (?:[a-z]+=(?:!0|!1|null)[,;])+)?)([\s\S]*?function[^)]+\){)/, '$3$1');
|
||||
// remove copyright header
|
||||
source = source.replace(/^\/\**[\s\S]+?\*\/\n/, '');
|
||||
|
||||
// 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 overly aggressive Closure Compiler advanced optimizations
|
||||
source = source
|
||||
.replace(/prototype\s*=\s*{\s*valueOf\s*:\s*1\s*}/, 'prototype={valueOf:1,y:1}')
|
||||
.replace(/(document[^&]+&&)\s*(?:\w+|!\d)/, '$1!({toString:0}+"")')
|
||||
|
||||
source = source.replace(/(\w+\.prototype\s*=\s*)\w+(?=\.prototype;)/, function(match, left) {
|
||||
return left + /\w+(?=\.VERSION)/.exec(source);
|
||||
});
|
||||
|
||||
// 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');
|
||||
// flip `typeof` expressions to help optimize Safari and
|
||||
// correct the AMD module definition for AMD build optimizers
|
||||
// (e.g. from `"number" == typeof x` to `typeof x == "number")
|
||||
source = source.replace(/(\w)?("[^"]+")\s*([!=]=)\s*(typeof(?:\s*\([^)]+\)|\s+[.\w]+(?!\[)))/g, function(match, other, type, equality, expression) {
|
||||
return (other ? other + ' ' : '') + expression + equality + type;
|
||||
});
|
||||
|
||||
// add trailing semicolon
|
||||
if (source) {
|
||||
source = source.replace(/[\s;]*$/, ';');
|
||||
source = source.replace(/[\s;]*?(\s*\/\/.*\s*|\s*\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/\s*)*$/, ';$1');
|
||||
}
|
||||
// exit early if version snippet isn't found
|
||||
var snippet = /VERSION\s*[=:]\s*([\'"])(.*?)\1/.exec(source);
|
||||
if (!snippet) {
|
||||
return source;
|
||||
}
|
||||
// add license
|
||||
return licenseTemplate[/call\(this\);?$/.test(source) ? 'underscore' : 'lodash']
|
||||
.replace('@VERSION', snippet[2]) + '\n;' + source;
|
||||
// add new copyright header
|
||||
var version = snippet[2];
|
||||
source = licenseTemplate.replace('<%= VERSION %>', version) + '\n;' + source;
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
@@ -2,96 +2,49 @@
|
||||
;(function() {
|
||||
'use strict';
|
||||
|
||||
/** The Node filesystem module */
|
||||
/** The Node.js filesystem module */
|
||||
var fs = require('fs');
|
||||
|
||||
/** Used to minify variables embedded in compiled strings */
|
||||
var compiledVars = [
|
||||
'args',
|
||||
'argsIndex',
|
||||
'argsLength',
|
||||
'callback',
|
||||
'collection',
|
||||
'concat',
|
||||
'createCallback',
|
||||
'ctor',
|
||||
'guard',
|
||||
'hasOwnProperty',
|
||||
'identity',
|
||||
'index',
|
||||
'iteratee',
|
||||
'isArguments',
|
||||
'isArray',
|
||||
'isString',
|
||||
'iterable',
|
||||
'length',
|
||||
'nativeKeys',
|
||||
'keys',
|
||||
'lodash',
|
||||
'object',
|
||||
'objectTypes',
|
||||
'ownIndex',
|
||||
'ownProps',
|
||||
'prop',
|
||||
'propertyIsEnumerable',
|
||||
'propIndex',
|
||||
'props',
|
||||
'result',
|
||||
'skipProto',
|
||||
'slice',
|
||||
'stringClass',
|
||||
'thisArg',
|
||||
'toString',
|
||||
'undefined',
|
||||
'value',
|
||||
|
||||
// lesser used variables
|
||||
'accumulator',
|
||||
'args',
|
||||
'arrayLikeClasses',
|
||||
'ArrayProto',
|
||||
'bind',
|
||||
'callee',
|
||||
'className',
|
||||
'compareAscending',
|
||||
'forIn',
|
||||
'found',
|
||||
'funcs',
|
||||
'indexOf',
|
||||
'indicator',
|
||||
'isArguments',
|
||||
'isArr',
|
||||
'isArray',
|
||||
'isFunc',
|
||||
'isFunction',
|
||||
'isPlainObject',
|
||||
'methodName',
|
||||
'noaccum',
|
||||
'noop',
|
||||
'objectClass',
|
||||
'objectTypes',
|
||||
'pass',
|
||||
'properties',
|
||||
'property',
|
||||
'propsLength',
|
||||
'source',
|
||||
'stackA',
|
||||
'stackB',
|
||||
'stackLength',
|
||||
'target'
|
||||
'thisArg'
|
||||
];
|
||||
|
||||
/** Used to minify `compileIterator` option properties */
|
||||
/** Used to minify `iteratorTemplate` data properties */
|
||||
var iteratorOptions = [
|
||||
'args',
|
||||
'array',
|
||||
'arrayBranch',
|
||||
'beforeLoop',
|
||||
'arrays',
|
||||
'bottom',
|
||||
'firstArg',
|
||||
'hasDontEnumBug',
|
||||
'inLoop',
|
||||
'init',
|
||||
'isKeysFast',
|
||||
'object',
|
||||
'objectBranch',
|
||||
'noArgsEnum',
|
||||
'noCharByIndex',
|
||||
'shadowed',
|
||||
'loop',
|
||||
'shadowedProps',
|
||||
'top',
|
||||
'useHas',
|
||||
'useStrict'
|
||||
'useKeys'
|
||||
];
|
||||
|
||||
/** Used to minify variables and string values to a single character */
|
||||
@@ -102,24 +55,40 @@
|
||||
|
||||
/** Used to protect the specified properties from getting minified */
|
||||
var propWhitelist = [
|
||||
'Array',
|
||||
'Boolean',
|
||||
'Date',
|
||||
'Function',
|
||||
'Math',
|
||||
'Number',
|
||||
'Object',
|
||||
'RegExp',
|
||||
'String',
|
||||
'TypeError',
|
||||
'VERSION',
|
||||
'_',
|
||||
'__chain__',
|
||||
'__wrapped__',
|
||||
'after',
|
||||
'all',
|
||||
'amd',
|
||||
'any',
|
||||
'argsClass',
|
||||
'argsObject',
|
||||
'assign',
|
||||
'at',
|
||||
'attachEvent',
|
||||
'bind',
|
||||
'bindAll',
|
||||
'chain',
|
||||
'bindKey',
|
||||
'clearTimeout',
|
||||
'clone',
|
||||
'cloneDeep',
|
||||
'collect',
|
||||
'compact',
|
||||
'compose',
|
||||
'contains',
|
||||
'countBy',
|
||||
'createCallback',
|
||||
'criteria',
|
||||
'debounce',
|
||||
'defaults',
|
||||
@@ -129,14 +98,19 @@
|
||||
'difference',
|
||||
'drop',
|
||||
'each',
|
||||
'enumPrototypes',
|
||||
'environment',
|
||||
'escape',
|
||||
'evaluate',
|
||||
'every',
|
||||
'exports',
|
||||
'extend',
|
||||
'fastBind',
|
||||
'fastKeys',
|
||||
'filter',
|
||||
'find',
|
||||
'findIndex',
|
||||
'findKey',
|
||||
'first',
|
||||
'flatten',
|
||||
'foldl',
|
||||
@@ -145,10 +119,12 @@
|
||||
'forIn',
|
||||
'forOwn',
|
||||
'functions',
|
||||
'global',
|
||||
'groupBy',
|
||||
'has',
|
||||
'head',
|
||||
'identity',
|
||||
'imports',
|
||||
'include',
|
||||
'index',
|
||||
'indexOf',
|
||||
@@ -180,7 +156,6 @@
|
||||
'keys',
|
||||
'last',
|
||||
'lastIndexOf',
|
||||
'lateBind',
|
||||
'map',
|
||||
'max',
|
||||
'memoize',
|
||||
@@ -189,12 +164,17 @@
|
||||
'min',
|
||||
'mixin',
|
||||
'noConflict',
|
||||
'nodeClass',
|
||||
'nonEnumArgs',
|
||||
'nonEnumShadows',
|
||||
'object',
|
||||
'omit',
|
||||
'once',
|
||||
'opera',
|
||||
'ownLast',
|
||||
'pairs',
|
||||
'parseInt',
|
||||
'partial',
|
||||
'partialRight',
|
||||
'pick',
|
||||
'pluck',
|
||||
'random',
|
||||
@@ -204,7 +184,9 @@
|
||||
'reject',
|
||||
'rest',
|
||||
'result',
|
||||
'runInContext',
|
||||
'select',
|
||||
'setImmediate',
|
||||
'setTimeout',
|
||||
'shuffle',
|
||||
'size',
|
||||
@@ -212,16 +194,18 @@
|
||||
'sortBy',
|
||||
'sortedIndex',
|
||||
'source',
|
||||
'spliceObjects',
|
||||
'support',
|
||||
'tail',
|
||||
'take',
|
||||
'tap',
|
||||
'template',
|
||||
'templates',
|
||||
'templateSettings',
|
||||
'throttle',
|
||||
'times',
|
||||
'toArray',
|
||||
'unescape',
|
||||
'unindexedChars',
|
||||
'union',
|
||||
'uniq',
|
||||
'unique',
|
||||
@@ -229,15 +213,16 @@
|
||||
'value',
|
||||
'values',
|
||||
'variable',
|
||||
'VERSION',
|
||||
'where',
|
||||
'without',
|
||||
'wrap',
|
||||
'zip',
|
||||
'zipObject',
|
||||
|
||||
// properties used by underscore.js
|
||||
'_chain',
|
||||
'_wrapped'
|
||||
// properties used by the `backbone` and `underscore` builds
|
||||
'__chain__',
|
||||
'chain',
|
||||
'findWhere'
|
||||
];
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -253,26 +238,27 @@
|
||||
source || (source = '');
|
||||
options || (options = {});
|
||||
|
||||
// remove unrecognized JSDoc tags so Closure Compiler won't complain
|
||||
// remove unrecognized JSDoc tags so the Closure Compiler won't complain
|
||||
source = source.replace(/@(?:alias|category)\b.*/g, '');
|
||||
|
||||
if (options.isTemplate) {
|
||||
return source;
|
||||
}
|
||||
|
||||
// remove copyright to add later in post-compile.js
|
||||
source = source.replace(/\/\*![\s\S]+?\*\//, '');
|
||||
|
||||
// add brackets to whitelisted properties so Closure Compiler won't mung them
|
||||
// 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'), "['$1']");
|
||||
source = source.replace(RegExp('\\.(' + propWhitelist.join('|') + ')\\b', 'g'), function(match, prop) {
|
||||
return "['" + prop.replace(/['\n\r\t]/g, '\\$&') + "']";
|
||||
});
|
||||
|
||||
// remove brackets from `_.escape()` in `_.template`
|
||||
// remove brackets from `lodash.createCallback` in `eachIteratorOptions`
|
||||
source = source.replace('lodash[\'createCallback\'](callback, thisArg)"', 'lodash.createCallback(callback, thisArg)"');
|
||||
|
||||
// remove brackets from `lodash.createCallback` in `_.assign`
|
||||
source = source.replace("' var callback = lodash['createCallback']", "'var callback=lodash.createCallback");
|
||||
|
||||
// remove brackets from `_.escape` in `_.template`
|
||||
source = source.replace(/__e *= *_\['escape']/g, '__e=_.escape');
|
||||
|
||||
// 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)');
|
||||
|
||||
@@ -280,85 +266,60 @@
|
||||
source = source.replace("result[length]['value']", 'result[length].value');
|
||||
|
||||
// remove whitespace from string literals
|
||||
source = source.replace(/'(?:(?=(\\?))\1.)*?'/g, function(string) {
|
||||
source = source.replace(/^((?:[ "'\w]+:)? *)"[^"\\\n]*(?:\\.[^"\\\n]*)*"|'[^'\\\n]*(?:\\.[^'\\\n]*)*'/gm, function(string, left) {
|
||||
// clip after an object literal property name or leading spaces
|
||||
if (left) {
|
||||
string = string.slice(left.length);
|
||||
}
|
||||
// avoids removing the '\n' of the `stringEscapes` object
|
||||
return string.replace(/\[object |delete |else |function | in |return\s+[\w']|throw |typeof |use strict|var |@ |'\\n'|\\\\n|\\n|\s+/g, function(match) {
|
||||
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;
|
||||
});
|
||||
// unclip
|
||||
return (left || '') + string;
|
||||
});
|
||||
|
||||
// add newline to `+"__p+='"` in underscore.js `_.template`
|
||||
source = source.replace(/\+"__p\+='"/g, '+"\\n__p+=\'"');
|
||||
|
||||
// remove whitespace from `_.template` related regexes
|
||||
source = source.replace(/(?:reEmptyString\w+|reInsertVariable) *=.+/g, function(match) {
|
||||
source = source.replace(/reEmptyString\w+ *=.+/g, function(match) {
|
||||
return match.replace(/ |\\n/g, '');
|
||||
});
|
||||
|
||||
// remove newline from double-quoted strings in `_.template`
|
||||
source = source
|
||||
.replace('"\';\\n__with ("', '"\';__with("')
|
||||
.replace('"\\n}__\\n__p += \'"', '"}____p+=\'"')
|
||||
.replace('"__p = \'"', '"__p=\'"')
|
||||
.replace('"\';\\n"', '"\';"')
|
||||
.replace("') {\\n'", "'){'")
|
||||
|
||||
// remove `useSourceURL` variable
|
||||
source = source.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *try *\{(?:\s*\/\/.*)*\n *var useSourceURL[\s\S]+?catch[^}]+}\n/, '');
|
||||
.replace('"__p += \'"', '"__p+=\'"')
|
||||
.replace('"\';\n"', '"\';"')
|
||||
|
||||
// remove debug sourceURL use in `_.template`
|
||||
source = source.replace(/(?:\s*\/\/.*\n)* *var sourceURL[^;]+;|\+ *sourceURL/g, '');
|
||||
|
||||
// minify internal properties used by 'compareAscending', `_.merge`, and `_.sortBy`
|
||||
// minify internal properties used by 'compareAscending' and `_.sortBy`
|
||||
(function() {
|
||||
var properties = ['criteria', 'index', 'value'],
|
||||
snippets = source.match(/( +)(?:function compareAscending|var merge|var sortBy)\b[\s\S]+?\n\1}/g);
|
||||
snippets = source.match(/( +)function (?:compareAscending|sortBy)\b[\s\S]+?\n\1}/g);
|
||||
|
||||
if (!snippets) {
|
||||
return;
|
||||
}
|
||||
snippets.forEach(function(snippet) {
|
||||
var modified = snippet,
|
||||
isCompilable = /(?:var merge|var sortBy)\b/.test(modified),
|
||||
isInlined = !/\bcreateIterator\b/.test(modified);
|
||||
var modified = snippet;
|
||||
|
||||
// minify properties
|
||||
properties.forEach(function(property, index) {
|
||||
var reBracketProp = RegExp("\\['(" + property + ")'\\]", 'g'),
|
||||
var minName = minNames[index],
|
||||
reBracketProp = RegExp("\\['(" + property + ")'\\]", 'g'),
|
||||
reDotProp = RegExp('\\.' + property + '\\b', 'g'),
|
||||
rePropColon = RegExp("([^?\\s])\\s*([\"'])?\\b" + property + "\\2 *:", 'g');
|
||||
|
||||
if (isCompilable) {
|
||||
// add quotes around properties in the inlined `_.merge` and `_.sortBy`
|
||||
// of the mobile build so Closure Compiler won't mung them
|
||||
if (isInlined) {
|
||||
modified = modified
|
||||
.replace(reBracketProp, "['" + minNames[index] + "']")
|
||||
.replace(reDotProp, "['" + minNames[index] + "']")
|
||||
.replace(rePropColon, "$1'" + minNames[index] + "':");
|
||||
}
|
||||
else {
|
||||
modified = modified
|
||||
.replace(reBracketProp, '.' + minNames[index])
|
||||
.replace(reDotProp, '.' + minNames[index])
|
||||
.replace(rePropColon, '$1' + minNames[index] + ':');
|
||||
}
|
||||
}
|
||||
else {
|
||||
modified = modified
|
||||
.replace(reBracketProp, "['" + minNames[index] + "']")
|
||||
.replace(reDotProp, '.' + minNames[index])
|
||||
.replace(rePropColon, "$1'" + minNames[index] + "':")
|
||||
|
||||
// correct `value.source` in regexp branch of `_.clone`
|
||||
if (property == 'source') {
|
||||
modified = modified.replace("value['" + minNames[index] + "']", "value['source']");
|
||||
}
|
||||
}
|
||||
modified = modified
|
||||
.replace(reBracketProp, "['" + minName + "']")
|
||||
.replace(reDotProp, "['" + minName + "']")
|
||||
.replace(rePropColon, "$1'" + minName + "':");
|
||||
});
|
||||
|
||||
// replace with modified snippet
|
||||
source = source.replace(snippet, modified);
|
||||
source = source.replace(snippet, function() {
|
||||
return modified;
|
||||
});
|
||||
});
|
||||
}());
|
||||
|
||||
@@ -368,7 +329,7 @@
|
||||
// match the `iteratorTemplate`
|
||||
'( +)var iteratorTemplate\\b[\\s\\S]+?\\n\\1}',
|
||||
// match methods created by `createIterator` calls
|
||||
'createIterator\\((?:{|[a-zA-Z]+)[\\s\\S]+?\\);\\n',
|
||||
'createIterator\\((?:{|[a-zA-Z]+)[\\s\\S]*?\\);\\n',
|
||||
// match variables storing `createIterator` options
|
||||
'( +)var [a-zA-Z]+IteratorOptions\\b[\\s\\S]+?\\n\\2}',
|
||||
// match the the `createIterator` function
|
||||
@@ -386,51 +347,43 @@
|
||||
isIteratorTemplate = /var iteratorTemplate\b/.test(snippet),
|
||||
modified = snippet;
|
||||
|
||||
// add brackets to whitelisted properties so Closure Compiler won't mung them
|
||||
modified = modified.replace(RegExp('\\.(' + iteratorOptions.join('|') + ')\\b', 'g'), "['$1']");
|
||||
|
||||
if (isCreateIterator) {
|
||||
// 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
|
||||
modified = modified.replace(RegExp('([^.]\\b)' + variable + '\\b(?!\' *[\\]:])', 'g'), '$1' + minNames[index]);
|
||||
|
||||
// correct `typeof x == 'object'`
|
||||
if (variable == 'object') {
|
||||
modified = modified.replace(RegExp("(typeof [^']+')" + minNames[index] + "'", 'g'), "$1object'");
|
||||
}
|
||||
// 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, '\\$&') + "']";
|
||||
});
|
||||
|
||||
// minify `createIterator` option property names
|
||||
iteratorOptions.forEach(function(property, index) {
|
||||
if (isIteratorTemplate) {
|
||||
// minify property names as interpolated template variables
|
||||
modified = modified.replace(RegExp('\\b' + property + '\\b', 'g'), minNames[index]);
|
||||
var minName = minNames[index];
|
||||
|
||||
// minify variables in `iteratorTemplate` or property names in everything else
|
||||
modified = isIteratorTemplate
|
||||
? modified.replace(RegExp('\\b' + property + '\\b', 'g'), minName)
|
||||
: modified.replace(RegExp("'" + property + "'", 'g'), "'" + minName + "'");
|
||||
});
|
||||
|
||||
// minify snippet variables / arguments
|
||||
compiledVars.forEach(function(varName, index) {
|
||||
var minName = minNames[index];
|
||||
|
||||
// minify variable names present in strings
|
||||
if (isCreateIterator) {
|
||||
modified = modified.replace(RegExp('(([\'"])[^\\n\\2]*?)\\b' + varName + '\\b(?=[^\\n\\2]*\\2[ ,+]+$)', 'gm'), '$1' + minName);
|
||||
}
|
||||
// ensure properties in compiled strings aren't minified
|
||||
else {
|
||||
if (property == 'array' || property == 'object') {
|
||||
// minify "array" and "object" sub property names
|
||||
modified = modified.replace(RegExp("'" + property + "'( *[\\]:])", 'g'), "'" + minNames[index] + "'$1");
|
||||
}
|
||||
else {
|
||||
// minify property name strings
|
||||
modified = modified.replace(RegExp("'" + property + "'", 'g'), "'" + minNames[index] + "'");
|
||||
// minify property names in regexes and accessors
|
||||
if (isCreateIterator) {
|
||||
modified = modified.replace(RegExp('([\\.|/])' + property + '\\b' , 'g'), '$1' + minNames[index]);
|
||||
}
|
||||
}
|
||||
modified = modified.replace(RegExp('([^.])\\b' + varName + '\\b(?!\' *[\\]:])', 'g'), '$1' + minName);
|
||||
}
|
||||
// correct `typeof` values
|
||||
if (/^(?:boolean|function|object|number|string|undefined)$/.test(varName)) {
|
||||
modified = modified.replace(RegExp("(typeof [^']+')" + minName + "'", 'g'), '$1' + varName + "'");
|
||||
}
|
||||
});
|
||||
|
||||
// replace with modified snippet
|
||||
source = source.replace(snippet, modified);
|
||||
source = source.replace(snippet, function() {
|
||||
return modified;
|
||||
});
|
||||
});
|
||||
|
||||
return source;
|
||||
|
||||
5438
dist/lodash.compat.js
vendored
Normal file
5438
dist/lodash.compat.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
46
dist/lodash.compat.min.js
vendored
Normal file
46
dist/lodash.compat.min.js
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* @license
|
||||
* Lo-Dash 1.1.0 (Custom Build) lodash.com/license
|
||||
* Build: `lodash -o ./dist/lodash.compat.js`
|
||||
* Underscore.js 1.4.4 underscorejs.org/LICENSE
|
||||
*/
|
||||
;(function(n){function t(r){function a(n){return n&&typeof n=="object"&&!fe(n)&&Vt.call(n,"__wrapped__")?n:new K(n)}function q(n,t,e){var r=n.length,u=r-t>=e;if(u){var a={};for(e=t-1;++e<r;){var o=qt(n[e]);(Vt.call(a,o)?a[o]:a[o]=[]).push(n[e])}}return function(e){if(u){var r=qt(e);return Vt.call(a,r)&&-1<yt(a[r],e)}return-1<yt(n,e,t)}}function B(n){return n.charCodeAt(0)}function F(n,t){var e=n.b,r=t.b;if(n=n.a,t=t.a,n!==t){if(n>t||typeof n=="undefined")return 1;if(n<t||typeof t=="undefined")return-1
|
||||
}return e<r?-1:1}function R(n,t,e,r){function u(){var r=arguments,c=o?this:t;return a||(n=t[i]),e.length&&(r=r.length?(r=V(r),f?r.concat(e):e.concat(r)):e),this instanceof u?(M.prototype=n.prototype,c=new M,M.prototype=null,r=n.apply(c,r),Z(r)?r:c):n.apply(c,r)}var a=Y(n),o=!e,i=t;if(o){var f=r;e=t}else if(!a){if(!r)throw new Bt;t=n}return u}function T(){for(var n,t={g:_,b:"k(m)",c:"",e:"m",f:"",h:"",i:!0,j:!!le},e=0;n=arguments[e];e++)for(var r in n)t[r]=n[r];if(n=t.a,t.d=/^[^,]+/.exec(n)[0],e=At,r="var i,m="+t.d+",u="+t.e+";if(!m)return u;"+t.h+";",t.b?(r+="var n=m.length;i=-1;if("+t.b+"){",ie.unindexedChars&&(r+="if(l(m)){m=m.split('')}"),r+="while(++i<n){"+t.f+"}}else{"):ie.nonEnumArgs&&(r+="var n=m.length;i=-1;if(n&&j(m)){while(++i<n){i+='';"+t.f+"}}else{"),ie.enumPrototypes&&(r+="var v=typeof m=='function';"),t.i&&t.j)r+="var s=-1,t=r[typeof m]?o(m):[],n=t.length;while(++s<n){i=t[s];",ie.enumPrototypes&&(r+="if(!(v&&i=='prototype')){"),r+=t.f,ie.enumPrototypes&&(r+="}"),r+="}";
|
||||
else if(r+="for(i in m){",(ie.enumPrototypes||t.i)&&(r+="if(",ie.enumPrototypes&&(r+="!(v&&i=='prototype')"),ie.enumPrototypes&&t.i&&(r+="&&"),t.i&&(r+="h.call(m,i)"),r+="){"),r+=t.f+";",(ie.enumPrototypes||t.i)&&(r+="}"),r+="}",ie.nonEnumShadows){r+="var f=m.constructor;";for(var u=0;7>u;u++)r+="i='"+t.g[u]+"';if(","constructor"==t.g[u]&&(r+="!(f&&f.prototype===m)&&"),r+="h.call(m,i)){"+t.f+"}"}return(t.b||ie.nonEnumArgs)&&(r+="}"),r+=t.c+";return u",e("h,j,k,l,o,p,r","return function("+n+"){"+r+"}")(Vt,H,fe,tt,le,a,P)
|
||||
}function D(n){return"\\"+N[n]}function z(n){return se[n]}function L(n){return typeof n.toString!="function"&&typeof(n+"")=="string"}function K(n){this.__wrapped__=n}function M(){}function U(n){var t=!1;if(!n||Qt.call(n)!=E||!ie.argsClass&&H(n))return t;var e=n.constructor;return(Y(e)?e instanceof e:ie.nodeClass||!L(n))?ie.ownLast?(ye(n,function(n,e,r){return t=Vt.call(r,e),!1}),!0===t):(ye(n,function(n,e){t=e}),!1===t||Vt.call(n,t)):t}function V(n,t,e){t||(t=0),typeof e=="undefined"&&(e=n?n.length:0);
|
||||
var r=-1;e=e-t||0;for(var u=Ot(0>e?0:e);++r<e;)u[r]=n[t+r];return u}function G(n){return ve[n]}function H(n){return Qt.call(n)==C}function J(n,t,r,u,o,i){var f=n;if(typeof t=="function"&&(u=r,r=t,t=!1),typeof r=="function"){if(r=typeof u=="undefined"?r:a.createCallback(r,u,1),f=r(f),typeof f!="undefined")return f;f=n}if(u=Z(f)){var c=Qt.call(f);if(!I[c]||!ie.nodeClass&&L(f))return f;var l=fe(f)}if(!u||!t)return u?l?V(f):ge({},f):f;switch(u=oe[c],c){case j:case k:return new u(+f);case O:case A:return new u(f);
|
||||
case S:return u(f.source,v.exec(f))}for(o||(o=[]),i||(i=[]),c=o.length;c--;)if(o[c]==n)return i[c];return f=l?u(f.length):{},l&&(Vt.call(n,"index")&&(f.index=n.index),Vt.call(n,"input")&&(f.input=n.input)),o.push(n),i.push(f),(l?ft:me)(n,function(n,u){f[u]=J(n,t,r,e,o,i)}),f}function Q(n){var t=[];return ye(n,function(n,e){Y(n)&&t.push(e)}),t.sort()}function W(n){for(var t=-1,e=le(n),r=e.length,u={};++t<r;){var a=e[t];u[n[a]]=a}return u}function X(n,t,e,r,u,o){var f=e===i;if(e&&!f){e=typeof r=="undefined"?e:a.createCallback(e,r,2);
|
||||
var c=e(n,t);if(typeof c!="undefined")return!!c}if(n===t)return 0!==n||1/n==1/t;var l=typeof n,p=typeof t;if(n===n&&(!n||"function"!=l&&"object"!=l)&&(!t||"function"!=p&&"object"!=p))return!1;if(null==n||null==t)return n===t;if(p=Qt.call(n),l=Qt.call(t),p==C&&(p=E),l==C&&(l=E),p!=l)return!1;switch(p){case j:case k:return+n==+t;case O:return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case S:case A:return n==qt(t)}if(l=p==w,!l){if(Vt.call(n,"__wrapped__")||Vt.call(t,"__wrapped__"))return X(n.__wrapped__||n,t.__wrapped__||t,e,r,u,o);
|
||||
if(p!=E||!ie.nodeClass&&(L(n)||L(t)))return!1;var p=!ie.argsObject&&H(n)?Nt:n.constructor,s=!ie.argsObject&&H(t)?Nt:t.constructor;if(p!=s&&(!Y(p)||!(p instanceof p&&Y(s)&&s instanceof s)))return!1}for(u||(u=[]),o||(o=[]),p=u.length;p--;)if(u[p]==n)return o[p]==t;var v=0,c=!0;if(u.push(n),o.push(t),l){if(p=n.length,v=t.length,c=v==n.length,!c&&!f)return c;for(;v--;)if(l=p,s=t[v],f)for(;l--&&!(c=X(n[l],s,e,r,u,o)););else if(!(c=X(n[v],s,e,r,u,o)))break;return c}return ye(t,function(t,a,i){return Vt.call(i,a)?(v++,c=Vt.call(n,a)&&X(n[a],t,e,r,u,o)):void 0
|
||||
}),c&&!f&&ye(n,function(n,t,e){return Vt.call(e,t)?c=-1<--v:void 0}),c}function Y(n){return typeof n=="function"}function Z(n){return n?P[typeof n]:!1}function nt(n){return typeof n=="number"||Qt.call(n)==O}function tt(n){return typeof n=="string"||Qt.call(n)==A}function et(n,t,e){var r=arguments,u=0,o=2;if(!Z(n))return n;if(e===i)var f=r[3],c=r[4],l=r[5];else c=[],l=[],typeof e!="number"&&(o=r.length),3<o&&"function"==typeof r[o-2]?f=a.createCallback(r[--o-1],r[o--],2):2<o&&"function"==typeof r[o-1]&&(f=r[--o]);
|
||||
for(;++u<o;)(fe(r[u])?ft:me)(r[u],function(t,e){var r,u,a=t,o=n[e];if(t&&((u=fe(t))||de(t))){for(a=c.length;a--;)if(r=c[a]==t){o=l[a];break}r||(o=u?fe(o)?o:[]:de(o)?o:{},f&&(a=f(o,t),typeof a!="undefined"&&(o=a)),c.push(t),l.push(o),f||(o=et(o,t,i,f,c,l)))}else f&&(a=f(o,t),typeof a=="undefined"&&(a=t)),typeof a!="undefined"&&(o=a);n[e]=o});return n}function rt(n){for(var t=-1,e=le(n),r=e.length,u=Ot(r);++t<r;)u[t]=n[e[t]];return u}function ut(n,t,e){var r=-1,u=n?n.length:0,a=!1;return e=(0>e?te(0,u+e):e)||0,typeof u=="number"?a=-1<(tt(n)?n.indexOf(t,e):yt(n,t,e)):pe(n,function(n){return++r<e?void 0:!(a=n===t)
|
||||
}),a}function at(n,t,e){var r=!0;if(t=a.createCallback(t,e),fe(n)){e=-1;for(var u=n.length;++e<u&&(r=!!t(n[e],e,n)););}else pe(n,function(n,e,u){return r=!!t(n,e,u)});return r}function ot(n,t,e){var r=[];if(t=a.createCallback(t,e),fe(n)){e=-1;for(var u=n.length;++e<u;){var o=n[e];t(o,e,n)&&r.push(o)}}else pe(n,function(n,e,u){t(n,e,u)&&r.push(n)});return r}function it(n,t,e){if(t=a.createCallback(t,e),!fe(n)){var r;return pe(n,function(n,e,u){return t(n,e,u)?(r=n,!1):void 0}),r}e=-1;for(var u=n.length;++e<u;){var o=n[e];
|
||||
if(t(o,e,n))return o}}function ft(n,t,e){if(t&&typeof e=="undefined"&&fe(n)){e=-1;for(var r=n.length;++e<r&&!1!==t(n[e],e,n););}else pe(n,t,e);return n}function ct(n,t,e){var r=-1,u=n?n.length:0,o=Ot(typeof u=="number"?u:0);if(t=a.createCallback(t,e),fe(n))for(;++r<u;)o[r]=t(n[r],r,n);else pe(n,function(n,e,u){o[++r]=t(n,e,u)});return o}function lt(n,t,e){var r=-1/0,u=r;if(!t&&fe(n)){e=-1;for(var o=n.length;++e<o;){var i=n[e];i>u&&(u=i)}}else t=!t&&tt(n)?B:a.createCallback(t,e),pe(n,function(n,e,a){e=t(n,e,a),e>r&&(r=e,u=n)
|
||||
});return u}function pt(n,t,e,r){var u=3>arguments.length;if(t=a.createCallback(t,r,4),fe(n)){var o=-1,i=n.length;for(u&&(e=n[++o]);++o<i;)e=t(e,n[o],o,n)}else pe(n,function(n,r,a){e=u?(u=!1,n):t(e,n,r,a)});return e}function st(n,t,e,r){var u=n,o=n?n.length:0,i=3>arguments.length;if(typeof o!="number")var f=le(n),o=f.length;else ie.unindexedChars&&tt(n)&&(u=n.split(""));return t=a.createCallback(t,r,4),ft(n,function(n,r,a){r=f?f[--o]:--o,e=i?(i=!1,u[r]):t(e,u[r],r,a)}),e}function vt(n,t,e){var r;
|
||||
if(t=a.createCallback(t,e),fe(n)){e=-1;for(var u=n.length;++e<u&&!(r=t(n[e],e,n)););}else pe(n,function(n,e,u){return!(r=t(n,e,u))});return!!r}function gt(n,t,e){if(n){var r=0,u=n.length;if(typeof t!="number"&&null!=t){var o=-1;for(t=a.createCallback(t,e);++o<u&&t(n[o],o,n);)r++}else if(r=t,null==r||e)return n[0];return V(n,0,ee(te(0,r),u))}}function ht(n,t,e,r){var u=-1,o=n?n.length:0,i=[];for(typeof t!="boolean"&&null!=t&&(r=e,e=t,t=!1),null!=e&&(e=a.createCallback(e,r));++u<o;)r=n[u],e&&(r=e(r,u,n)),fe(r)?Gt.apply(i,t?r:ht(r)):i.push(r);
|
||||
return i}function yt(n,t,e){var r=-1,u=n?n.length:0;if(typeof e=="number")r=(0>e?te(0,u+e):e||0)-1;else if(e)return r=dt(n,t),n[r]===t?r:-1;for(;++r<u;)if(n[r]===t)return r;return-1}function mt(n,t,e){if(typeof t!="number"&&null!=t){var r=0,u=-1,o=n?n.length:0;for(t=a.createCallback(t,e);++u<o&&t(n[u],u,n);)r++}else r=null==t||e?1:te(0,t);return V(n,r)}function dt(n,t,e,r){var u=0,o=n?n.length:u;for(e=e?a.createCallback(e,r,1):jt,t=e(t);u<o;)r=u+o>>>1,e(n[r])<t?u=r+1:o=r;return u}function bt(n,t,e,r){var u=-1,o=n?n.length:0,i=[],f=i;
|
||||
typeof t!="boolean"&&null!=t&&(r=e,e=t,t=!1);var c=!t&&75<=o;if(c)var l={};for(null!=e&&(f=[],e=a.createCallback(e,r));++u<o;){r=n[u];var p=e?e(r,u,n):r;if(c)var s=qt(p),s=Vt.call(l,s)?!(f=l[s]):f=l[s]=[];(t?!u||f[f.length-1]!==p:s||0>yt(f,p))&&((e||c)&&f.push(p),i.push(r))}return i}function _t(n,t){for(var e=-1,r=n?n.length:0,u={};++e<r;){var a=n[e];t?u[a]=t[e]:u[a[0]]=a[1]}return u}function Ct(n,t){return ie.fastBind||Wt&&2<arguments.length?Wt.call.apply(Wt,arguments):R(n,t,V(arguments,2))}function wt(n){var t=V(arguments,1);
|
||||
return Jt(function(){n.apply(e,t)},1)}function jt(n){return n}function kt(n){ft(Q(n),function(t){var e=a[t]=n[t];a.prototype[t]=function(){var n=this.__wrapped__,t=[n];return Gt.apply(t,arguments),t=e.apply(a,t),n&&typeof n=="object"&&n==t?this:new K(t)}})}function xt(){return this.__wrapped__}r=r?$.defaults(n.Object(),r,$.pick(n,b)):n;var Ot=r.Array,Et=r.Boolean,St=r.Date,At=r.Function,It=r.Math,Pt=r.Number,Nt=r.Object,$t=r.RegExp,qt=r.String,Bt=r.TypeError,Ft=Ot(),Rt=Nt(),Tt=r._,Dt=$t("^"+qt(Rt.valueOf).replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),zt=It.ceil,Lt=r.clearTimeout,Kt=Ft.concat,Mt=It.floor,Ut=Dt.test(Ut=Nt.getPrototypeOf)&&Ut,Vt=Rt.hasOwnProperty,Gt=Ft.push,Ht=r.setImmediate,Jt=r.setTimeout,Qt=Rt.toString,Wt=Dt.test(Wt=V.bind)&&Wt,Xt=Dt.test(Xt=Ot.isArray)&&Xt,Yt=r.isFinite,Zt=r.isNaN,ne=Dt.test(ne=Nt.keys)&&ne,te=It.max,ee=It.min,re=r.parseInt,ue=It.random,It=Dt.test(r.attachEvent),ae=Wt&&!/\n|true/.test(Wt+It),oe={};
|
||||
oe[w]=Ot,oe[j]=Et,oe[k]=St,oe[E]=Nt,oe[O]=Pt,oe[S]=$t,oe[A]=qt;var ie=a.support={};(function(){var n=function(){this.x=1},t={0:1,length:1},e=[];n.prototype={valueOf:1,y:1};for(var r in new n)e.push(r);for(r in arguments);ie.argsObject=arguments.constructor==Nt,ie.argsClass=H(arguments),ie.enumPrototypes=n.propertyIsEnumerable("prototype"),ie.fastBind=Wt&&!ae,ie.ownLast="x"!=e[0],ie.nonEnumArgs=0!=r,ie.nonEnumShadows=!/valueOf/.test(e),ie.spliceObjects=(Ft.splice.call(t,0,1),!t[0]),ie.unindexedChars="xx"!="x"[0]+Nt("x")[0];
|
||||
try{ie.nodeClass=!(Qt.call(document)==E&&!({toString:0}+""))}catch(u){ie.nodeClass=!0}})(1),a.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:g,variable:"",imports:{_:a}},Et={a:"q,w,g",h:"var a=arguments,b=0,c=typeof g=='number'?2:a.length;while(++b<c){m=a[b];if(m&&r[typeof m]){",f:"if(typeof u[i]=='undefined')u[i]=m[i]",c:"}}"},Pt={a:"e,d,x",h:"d=d&&typeof x=='undefined'?d:p.createCallback(d,x)",b:"typeof n=='number'",f:"if(d(m[i],i,e)===false)return u"},It={h:"if(!r[typeof m])return u;"+Pt.h,b:!1},K.prototype=a.prototype,ie.argsClass||(H=function(n){return n?Vt.call(n,"callee"):!1
|
||||
});var fe=Xt||function(n){return ie.argsObject&&n instanceof Ot||Qt.call(n)==w},ce=T({a:"q",e:"[]",h:"if(!(r[typeof q]))return u",f:"u.push(i)",b:!1}),le=ne?function(n){return Z(n)?ie.enumPrototypes&&typeof n=="function"||ie.nonEnumArgs&&n.length&&H(n)?ce(n):ne(n):[]}:ce,pe=T(Pt),se={"&":"&","<":"<",">":">",'"':""","'":"'"},ve=W(se),ge=T(Et,{h:Et.h.replace(";",";if(c>3&&typeof a[c-2]=='function'){var d=p.createCallback(a[--c-1],a[c--],2);}else if(c>2&&typeof a[c-1]=='function'){d=a[--c];}"),f:"u[i]=d?d(u[i],m[i]):m[i]"}),he=T(Et),ye=T(Pt,It,{i:!1}),me=T(Pt,It);
|
||||
Y(/x/)&&(Y=function(n){return n instanceof At||Qt.call(n)==x});var de=Ut?function(n){if(!n||Qt.call(n)!=E||!ie.argsClass&&H(n))return!1;var t=n.valueOf,e=typeof t=="function"&&(e=Ut(t))&&Ut(e);return e?n==e||Ut(n)==e:U(n)}:U;return ae&&u&&typeof Ht=="function"&&(wt=Ct(Ht,r)),Ht=8==re("08")?re:function(n,t){return re(tt(n)?n.replace(h,""):n,t||0)},a.after=function(n,t){return 1>n?t():function(){return 1>--n?t.apply(this,arguments):void 0}},a.assign=ge,a.at=function(n){var t=-1,e=Kt.apply(Ft,V(arguments,1)),r=e.length,u=Ot(r);
|
||||
for(ie.unindexedChars&&tt(n)&&(n=n.split(""));++t<r;)u[t]=n[e[t]];return u},a.bind=Ct,a.bindAll=function(n){for(var t=Kt.apply(Ft,arguments),e=1<t.length?0:(t=Q(n),-1),r=t.length;++e<r;){var u=t[e];n[u]=Ct(n[u],n)}return n},a.bindKey=function(n,t){return R(n,t,V(arguments,2),i)},a.compact=function(n){for(var t=-1,e=n?n.length:0,r=[];++t<e;){var u=n[t];u&&r.push(u)}return r},a.compose=function(){var n=arguments;return function(){for(var t=arguments,e=n.length;e--;)t=[n[e].apply(this,t)];return t[0]
|
||||
}},a.countBy=function(n,t,e){var r={};return t=a.createCallback(t,e),ft(n,function(n,e,u){e=qt(t(n,e,u)),Vt.call(r,e)?r[e]++:r[e]=1}),r},a.createCallback=function(n,t,e){if(null==n)return jt;var r=typeof n;if("function"!=r){if("object"!=r)return function(t){return t[n]};var u=le(n);return function(t){for(var e=u.length,r=!1;e--&&(r=X(t[u[e]],n[u[e]],i)););return r}}return typeof t!="undefined"?1===e?function(e){return n.call(t,e)}:2===e?function(e,r){return n.call(t,e,r)}:4===e?function(e,r,u,a){return n.call(t,e,r,u,a)
|
||||
}:function(e,r,u){return n.call(t,e,r,u)}:n},a.debounce=function(n,t,e){function r(){i=null,e||(a=n.apply(o,u))}var u,a,o,i;return function(){var f=e&&!i;return u=arguments,o=this,Lt(i),i=Jt(r,t),f&&(a=n.apply(o,u)),a}},a.defaults=he,a.defer=wt,a.delay=function(n,t){var r=V(arguments,2);return Jt(function(){n.apply(e,r)},t)},a.difference=function(n){for(var t=-1,e=n?n.length:0,r=Kt.apply(Ft,arguments),r=q(r,e,100),u=[];++t<e;){var a=n[t];r(a)||u.push(a)}return u},a.filter=ot,a.flatten=ht,a.forEach=ft,a.forIn=ye,a.forOwn=me,a.functions=Q,a.groupBy=function(n,t,e){var r={};
|
||||
return t=a.createCallback(t,e),ft(n,function(n,e,u){e=qt(t(n,e,u)),(Vt.call(r,e)?r[e]:r[e]=[]).push(n)}),r},a.initial=function(n,t,e){if(!n)return[];var r=0,u=n.length;if(typeof t!="number"&&null!=t){var o=u;for(t=a.createCallback(t,e);o--&&t(n[o],o,n);)r++}else r=null==t||e?1:t||r;return V(n,0,ee(te(0,u-r),u))},a.intersection=function(n){var t=arguments,e=t.length,r={0:{}},u=-1,a=n?n.length:0,o=100<=a,i=[],f=i;n:for(;++u<a;){var c=n[u];if(o)var l=qt(c),l=Vt.call(r[0],l)?!(f=r[0][l]):f=r[0][l]=[];
|
||||
if(l||0>yt(f,c)){o&&f.push(c);for(var p=e;--p;)if(!(r[p]||(r[p]=q(t[p],0,100)))(c))continue n;i.push(c)}}return i},a.invert=W,a.invoke=function(n,t){var e=V(arguments,2),r=-1,u=typeof t=="function",a=n?n.length:0,o=Ot(typeof a=="number"?a:0);return ft(n,function(n){o[++r]=(u?t:n[t]).apply(n,e)}),o},a.keys=le,a.map=ct,a.max=lt,a.memoize=function(n,t){var e={};return function(){var r=qt(t?t.apply(this,arguments):arguments[0]);return Vt.call(e,r)?e[r]:e[r]=n.apply(this,arguments)}},a.merge=et,a.min=function(n,t,e){var r=1/0,u=r;
|
||||
if(!t&&fe(n)){e=-1;for(var o=n.length;++e<o;){var i=n[e];i<u&&(u=i)}}else t=!t&&tt(n)?B:a.createCallback(t,e),pe(n,function(n,e,a){e=t(n,e,a),e<r&&(r=e,u=n)});return u},a.omit=function(n,t,e){var r=typeof t=="function",u={};if(r)t=a.createCallback(t,e);else var o=Kt.apply(Ft,arguments);return ye(n,function(n,e,a){(r?!t(n,e,a):0>yt(o,e,1))&&(u[e]=n)}),u},a.once=function(n){var t,e;return function(){return t?e:(t=!0,e=n.apply(this,arguments),n=null,e)}},a.pairs=function(n){for(var t=-1,e=le(n),r=e.length,u=Ot(r);++t<r;){var a=e[t];
|
||||
u[t]=[a,n[a]]}return u},a.partial=function(n){return R(n,V(arguments,1))},a.partialRight=function(n){return R(n,V(arguments,1),null,i)},a.pick=function(n,t,e){var r={};if(typeof t!="function")for(var u=0,o=Kt.apply(Ft,arguments),i=Z(n)?o.length:0;++u<i;){var f=o[u];f in n&&(r[f]=n[f])}else t=a.createCallback(t,e),ye(n,function(n,e,u){t(n,e,u)&&(r[e]=n)});return r},a.pluck=ct,a.range=function(n,t,e){n=+n||0,e=+e||1,null==t&&(t=n,n=0);var r=-1;t=te(0,zt((t-n)/e));for(var u=Ot(t);++r<t;)u[r]=n,n+=e;
|
||||
return u},a.reject=function(n,t,e){return t=a.createCallback(t,e),ot(n,function(n,e,r){return!t(n,e,r)})},a.rest=mt,a.shuffle=function(n){var t=-1,e=n?n.length:0,r=Ot(typeof e=="number"?e:0);return ft(n,function(n){var e=Mt(ue()*(++t+1));r[t]=r[e],r[e]=n}),r},a.sortBy=function(n,t,e){var r=-1,u=n?n.length:0,o=Ot(typeof u=="number"?u:0);for(t=a.createCallback(t,e),ft(n,function(n,e,u){o[++r]={a:t(n,e,u),b:r,c:n}}),u=o.length,o.sort(F);u--;)o[u]=o[u].c;return o},a.tap=function(n,t){return t(n),n},a.throttle=function(n,t){function e(){i=new St,o=null,u=n.apply(a,r)
|
||||
}var r,u,a,o,i=0;return function(){var f=new St,c=t-(f-i);return r=arguments,a=this,0<c?o||(o=Jt(e,c)):(Lt(o),o=null,i=f,u=n.apply(a,r)),u}},a.times=function(n,t,e){n=-1<(n=+n)?n:0;var r=-1,u=Ot(n);for(t=a.createCallback(t,e,1);++r<n;)u[r]=t(r);return u},a.toArray=function(n){return n&&typeof n.length=="number"?ie.unindexedChars&&tt(n)?n.split(""):V(n):rt(n)},a.union=function(){return bt(Kt.apply(Ft,arguments))},a.uniq=bt,a.values=rt,a.where=ot,a.without=function(n){for(var t=-1,e=n?n.length:0,r=q(arguments,1,30),u=[];++t<e;){var a=n[t];
|
||||
r(a)||u.push(a)}return u},a.wrap=function(n,t){return function(){var e=[n];return Gt.apply(e,arguments),t.apply(this,e)}},a.zip=function(n){for(var t=-1,e=n?lt(ct(arguments,"length")):0,r=Ot(e);++t<e;)r[t]=ct(arguments,t);return r},a.zipObject=_t,a.collect=ct,a.drop=mt,a.each=ft,a.extend=ge,a.methods=Q,a.object=_t,a.select=ot,a.tail=mt,a.unique=bt,kt(a),a.clone=J,a.cloneDeep=function(n,t,e){return J(n,!0,t,e)},a.contains=ut,a.escape=function(n){return null==n?"":qt(n).replace(m,z)},a.every=at,a.find=it,a.findIndex=function(n,t,e){var r=-1,u=n?n.length:0;
|
||||
for(t=a.createCallback(t,e);++r<u;)if(t(n[r],r,n))return r;return-1},a.findKey=function(n,t,e){var r;return t=a.createCallback(t,e),me(n,function(n,e,u){return t(n,e,u)?(r=e,!1):void 0}),r},a.has=function(n,t){return n?Vt.call(n,t):!1},a.identity=jt,a.indexOf=yt,a.isArguments=H,a.isArray=fe,a.isBoolean=function(n){return!0===n||!1===n||Qt.call(n)==j},a.isDate=function(n){return n instanceof St||Qt.call(n)==k},a.isElement=function(n){return n?1===n.nodeType:!1},a.isEmpty=function(n){var t=!0;if(!n)return t;
|
||||
var e=Qt.call(n),r=n.length;return e==w||e==A||(ie.argsClass?e==C:H(n))||e==E&&typeof r=="number"&&Y(n.splice)?!r:(me(n,function(){return t=!1}),t)},a.isEqual=X,a.isFinite=function(n){return Yt(n)&&!Zt(parseFloat(n))},a.isFunction=Y,a.isNaN=function(n){return nt(n)&&n!=+n},a.isNull=function(n){return null===n},a.isNumber=nt,a.isObject=Z,a.isPlainObject=de,a.isRegExp=function(n){return n instanceof $t||Qt.call(n)==S},a.isString=tt,a.isUndefined=function(n){return typeof n=="undefined"},a.lastIndexOf=function(n,t,e){var r=n?n.length:0;
|
||||
for(typeof e=="number"&&(r=(0>e?te(0,r+e):ee(e,r-1))+1);r--;)if(n[r]===t)return r;return-1},a.mixin=kt,a.noConflict=function(){return r._=Tt,this},a.parseInt=Ht,a.random=function(n,t){return null==n&&null==t&&(t=1),n=+n||0,null==t&&(t=n,n=0),n+Mt(ue()*((+t||0)-n+1))},a.reduce=pt,a.reduceRight=st,a.result=function(n,t){var r=n?n[t]:e;return Y(r)?n[t]():r},a.runInContext=t,a.size=function(n){var t=n?n.length:0;return typeof t=="number"?t:le(n).length},a.some=vt,a.sortedIndex=dt,a.template=function(n,t,r){var u=a.templateSettings;
|
||||
n||(n=""),r=he({},r,u);var o,i=he({},r.imports,u.imports),u=le(i),i=rt(i),p=0,v=r.interpolate||y,h="__p+='",v=$t((r.escape||y).source+"|"+v.source+"|"+(v===g?s:y).source+"|"+(r.evaluate||y).source+"|$","g");n.replace(v,function(t,e,r,u,a,i){return r||(r=u),h+=n.slice(p,i).replace(d,D),e&&(h+="'+__e("+e+")+'"),a&&(o=!0,h+="';"+a+";__p+='"),r&&(h+="'+((__t=("+r+"))==null?'':__t)+'"),p=i+t.length,t}),h+="';\n",v=r=r.variable,v||(r="obj",h="with("+r+"){"+h+"}"),h=(o?h.replace(f,""):h).replace(c,"$1").replace(l,"$1;"),h="function("+r+"){"+(v?"":r+"||("+r+"={});")+"var __t,__p='',__e=_.escape"+(o?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+h+"return __p}";
|
||||
try{var m=At(u,"return "+h).apply(e,i)}catch(b){throw b.source=h,b}return t?m(t):(m.source=h,m)},a.unescape=function(n){return null==n?"":qt(n).replace(p,G)},a.uniqueId=function(n){var t=++o;return qt(null==n?"":n)+t},a.all=at,a.any=vt,a.detect=it,a.foldl=pt,a.foldr=st,a.include=ut,a.inject=pt,me(a,function(n,t){a.prototype[t]||(a.prototype[t]=function(){var t=[this.__wrapped__];return Gt.apply(t,arguments),n.apply(a,t)})}),a.first=gt,a.last=function(n,t,e){if(n){var r=0,u=n.length;if(typeof t!="number"&&null!=t){var o=u;
|
||||
for(t=a.createCallback(t,e);o--&&t(n[o],o,n);)r++}else if(r=t,null==r||e)return n[u-1];return V(n,te(0,u-r))}},a.take=gt,a.head=gt,me(a,function(n,t){a.prototype[t]||(a.prototype[t]=function(t,e){var r=n(this.__wrapped__,t,e);return null==t||e&&typeof t!="function"?r:new K(r)})}),a.VERSION="1.1.0",a.prototype.toString=function(){return qt(this.__wrapped__)},a.prototype.value=xt,a.prototype.valueOf=xt,pe(["join","pop","shift"],function(n){var t=Ft[n];a.prototype[n]=function(){return t.apply(this.__wrapped__,arguments)
|
||||
}}),pe(["push","reverse","sort","unshift"],function(n){var t=Ft[n];a.prototype[n]=function(){return t.apply(this.__wrapped__,arguments),this}}),pe(["concat","slice","splice"],function(n){var t=Ft[n];a.prototype[n]=function(){return new K(t.apply(this.__wrapped__,arguments))}}),ie.spliceObjects||pe(["pop","shift","splice"],function(n){var t=Ft[n],e="splice"==n;a.prototype[n]=function(){var n=this.__wrapped__,r=t.apply(n,arguments);return 0===n.length&&delete n[0],e?new K(r):r}}),a}var e,r=typeof exports=="object"&&exports,u=typeof module=="object"&&module&&module.exports==r&&module,a=typeof global=="object"&&global;
|
||||
a.global===a&&(n=a);var o=0,i={},f=/\b__p\+='';/g,c=/\b(__p\+=)''\+/g,l=/(__e\(.*?\)|\b__t\))\+'';/g,p=/&(?:amp|lt|gt|quot|#39);/g,s=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,v=/\w*$/,g=/<%=([\s\S]+?)%>/g,h=/^0+(?=.$)/,y=/($^)/,m=/[&<>"']/g,d=/['\n\r\t\u2028\u2029\\]/g,b="Array Boolean Date Function Math Number Object RegExp String _ attachEvent clearTimeout isFinite isNaN parseInt setImmediate setTimeout".split(" "),_="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),C="[object Arguments]",w="[object Array]",j="[object Boolean]",k="[object Date]",x="[object Function]",O="[object Number]",E="[object Object]",S="[object RegExp]",A="[object String]",I={};
|
||||
I[x]=!1,I[C]=I[w]=I[j]=I[k]=I[O]=I[E]=I[S]=I[A]=!0;var P={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,undefined:!1},N={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"},$=t();typeof define=="function"&&typeof define.amd=="object"&&define.amd?(n._=$,define(function(){return $})):r&&!r.nodeType?u?(u.exports=$)._=$:r._=$:n._=$})(this);
|
||||
5217
dist/lodash.js
vendored
Normal file
5217
dist/lodash.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
42
dist/lodash.min.js
vendored
Normal file
42
dist/lodash.min.js
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* @license
|
||||
* Lo-Dash 1.1.0 (Custom Build) lodash.com/license
|
||||
* Build: `lodash modern -o ./dist/lodash.js`
|
||||
* Underscore.js 1.4.4 underscorejs.org/LICENSE
|
||||
*/
|
||||
;(function(n){function t(r){function a(n){return n&&typeof n=="object"&&!ae(n)&&Ut.call(n,"__wrapped__")?n:new z(n)}function $(n,t,e){var r=n.length,u=r-t>=e;if(u){var a={};for(e=t-1;++e<r;){var o=$t(n[e]);(Ut.call(a,o)?a[o]:a[o]=[]).push(n[e])}}return function(e){if(u){var r=$t(e);return Ut.call(a,r)&&-1<gt(a[r],e)}return-1<gt(n,e,t)}}function q(n){return n.charCodeAt(0)}function B(n,t){var e=n.b,r=t.b;if(n=n.a,t=t.a,n!==t){if(n>t||typeof n=="undefined")return 1;if(n<t||typeof t=="undefined")return-1
|
||||
}return e<r?-1:1}function F(n,t,e,r){function u(){var r=arguments,c=o?this:t;return a||(n=t[i]),e.length&&(r=r.length?(r=M(r),f?r.concat(e):e.concat(r)):e),this instanceof u?(P.prototype=n.prototype,c=new P,P.prototype=null,r=n.apply(c,r),W(r)?r:c):n.apply(c,r)}var a=Q(n),o=!e,i=t;if(o){var f=r;e=t}else if(!a){if(!r)throw new qt;t=n}return u}function R(){for(var n,t={b:"k(m)",c:"",e:"m",f:"",h:"",i:!0,j:!!oe},e=0;n=arguments[e];e++)for(var r in n)t[r]=n[r];return n=t.a,t.d=/^[^,]+/.exec(n)[0],e=Nt,r="var i,m="+t.d+",u="+t.e+";if(!m)return u;"+t.h+";",t.b&&(r+="var n=m.length;i=-1;if("+t.b+"){while(++i<n){"+t.f+"}}else{"),t.i&&t.j?r+="var s=-1,t=r[typeof m]?o(m):[],n=t.length;while(++s<n){i=t[s];"+t.f+"}":(r+="for(i in m){",t.i&&(r+="if(",t.i&&(r+="h.call(m,i)"),r+="){"),r+=t.f+";",t.i&&(r+="}"),r+="}"),t.b&&(r+="}"),r+=t.c+";return u",e("h,j,k,l,o,p,r","return function("+n+"){"+r+"}")(Ut,V,ae,Y,oe,a,I)
|
||||
}function T(n){return"\\"+S[n]}function D(n){return ie[n]}function z(n){this.__wrapped__=n}function P(){}function K(n){var t=!1;if(!n||Jt.call(n)!=x)return t;var e=n.constructor;return(Q(e)?e instanceof e:ue.nodeClass||!isNode(n))?(pe(n,function(n,e){t=e}),!1===t||Ut.call(n,t)):t}function M(n,t,e){t||(t=0),typeof e=="undefined"&&(e=n?n.length:0);var r=-1;e=e-t||0;for(var u=Ct(0>e?0:e);++r<e;)u[r]=n[t+r];return u}function U(n){return fe[n]}function V(n){return Jt.call(n)==_}function G(n,t,r,u,o,i){var f=n;
|
||||
if(typeof t=="function"&&(u=r,r=t,t=!1),typeof r=="function"){if(r=typeof u=="undefined"?r:a.createCallback(r,u,1),f=r(f),typeof f!="undefined")return f;f=n}if(u=W(f)){var c=Jt.call(f);if(!E[c])return f;var l=ae(f)}if(!u||!t)return u?l?M(f):ce({},f):f;switch(u=re[c],c){case w:case j:return new u(+f);case C:case N:return new u(f);case O:return u(f.source,v.exec(f))}for(o||(o=[]),i||(i=[]),c=o.length;c--;)if(o[c]==n)return i[c];return f=l?u(f.length):{},l&&(Ut.call(n,"index")&&(f.index=n.index),Ut.call(n,"input")&&(f.input=n.input)),o.push(n),i.push(f),(l?at:se)(n,function(n,u){f[u]=G(n,t,r,e,o,i)
|
||||
}),f}function H(n){var t=[];return pe(n,function(n,e){Q(n)&&t.push(e)}),t.sort()}function J(n){for(var t=-1,e=oe(n),r=e.length,u={};++t<r;){var a=e[t];u[n[a]]=a}return u}function L(n,t,e,r,u,o){var f=e===i;if(e&&!f){e=typeof r=="undefined"?e:a.createCallback(e,r,2);var c=e(n,t);if(typeof c!="undefined")return!!c}if(n===t)return 0!==n||1/n==1/t;var l=typeof n,p=typeof t;if(n===n&&(!n||"function"!=l&&"object"!=l)&&(!t||"function"!=p&&"object"!=p))return!1;if(null==n||null==t)return n===t;if(p=Jt.call(n),l=Jt.call(t),p==_&&(p=x),l==_&&(l=x),p!=l)return!1;
|
||||
switch(p){case w:case j:return+n==+t;case C:return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case O:case N:return n==$t(t)}if(l=p==k,!l){if(Ut.call(n,"__wrapped__")||Ut.call(t,"__wrapped__"))return L(n.__wrapped__||n,t.__wrapped__||t,e,r,u,o);if(p!=x)return!1;var p=n.constructor,s=t.constructor;if(p!=s&&(!Q(p)||!(p instanceof p&&Q(s)&&s instanceof s)))return!1}for(u||(u=[]),o||(o=[]),p=u.length;p--;)if(u[p]==n)return o[p]==t;var v=0,c=!0;if(u.push(n),o.push(t),l){if(p=n.length,v=t.length,c=v==n.length,!c&&!f)return c;
|
||||
for(;v--;)if(l=p,s=t[v],f)for(;l--&&!(c=L(n[l],s,e,r,u,o)););else if(!(c=L(n[v],s,e,r,u,o)))break;return c}return pe(t,function(t,a,i){return Ut.call(i,a)?(v++,c=Ut.call(n,a)&&L(n[a],t,e,r,u,o)):void 0}),c&&!f&&pe(n,function(n,t,e){return Ut.call(e,t)?c=-1<--v:void 0}),c}function Q(n){return typeof n=="function"}function W(n){return n?I[typeof n]:!1}function X(n){return typeof n=="number"||Jt.call(n)==C}function Y(n){return typeof n=="string"||Jt.call(n)==N}function Z(n,t,e){var r=arguments,u=0,o=2;
|
||||
if(!W(n))return n;if(e===i)var f=r[3],c=r[4],l=r[5];else c=[],l=[],typeof e!="number"&&(o=r.length),3<o&&"function"==typeof r[o-2]?f=a.createCallback(r[--o-1],r[o--],2):2<o&&"function"==typeof r[o-1]&&(f=r[--o]);for(;++u<o;)(ae(r[u])?at:se)(r[u],function(t,e){var r,u,a=t,o=n[e];if(t&&((u=ae(t))||ve(t))){for(a=c.length;a--;)if(r=c[a]==t){o=l[a];break}r||(o=u?ae(o)?o:[]:ve(o)?o:{},f&&(a=f(o,t),typeof a!="undefined"&&(o=a)),c.push(t),l.push(o),f||(o=Z(o,t,i,f,c,l)))}else f&&(a=f(o,t),typeof a=="undefined"&&(a=t)),typeof a!="undefined"&&(o=a);
|
||||
n[e]=o});return n}function nt(n){for(var t=-1,e=oe(n),r=e.length,u=Ct(r);++t<r;)u[t]=n[e[t]];return u}function tt(n,t,e){var r=-1,u=n?n.length:0,a=!1;return e=(0>e?Zt(0,u+e):e)||0,typeof u=="number"?a=-1<(Y(n)?n.indexOf(t,e):gt(n,t,e)):se(n,function(n){return++r<e?void 0:!(a=n===t)}),a}function et(n,t,e){var r=!0;t=a.createCallback(t,e),e=-1;var u=n?n.length:0;if(typeof u=="number")for(;++e<u&&(r=!!t(n[e],e,n)););else se(n,function(n,e,u){return r=!!t(n,e,u)});return r}function rt(n,t,e){var r=[];
|
||||
t=a.createCallback(t,e),e=-1;var u=n?n.length:0;if(typeof u=="number")for(;++e<u;){var o=n[e];t(o,e,n)&&r.push(o)}else se(n,function(n,e,u){t(n,e,u)&&r.push(n)});return r}function ut(n,t,e){t=a.createCallback(t,e),e=-1;var r=n?n.length:0;if(typeof r!="number"){var u;return se(n,function(n,e,r){return t(n,e,r)?(u=n,!1):void 0}),u}for(;++e<r;){var o=n[e];if(t(o,e,n))return o}}function at(n,t,e){var r=-1,u=n?n.length:0;if(typeof u=="number")for(t=t&&typeof e=="undefined"?t:a.createCallback(t,e);++r<u&&!1!==t(n[r],r,n););else se(n,t,e);
|
||||
return n}function ot(n,t,e){var r=-1,u=n?n.length:0;if(t=a.createCallback(t,e),typeof u=="number")for(var o=Ct(u);++r<u;)o[r]=t(n[r],r,n);else o=[],se(n,function(n,e,u){o[++r]=t(n,e,u)});return o}function it(n,t,e){var r=-1/0,u=r;if(!t&&ae(n)){e=-1;for(var o=n.length;++e<o;){var i=n[e];i>u&&(u=i)}}else t=!t&&Y(n)?q:a.createCallback(t,e),at(n,function(n,e,a){e=t(n,e,a),e>r&&(r=e,u=n)});return u}function ft(n,t){var e=-1,r=n?n.length:0;if(typeof r=="number")for(var u=Ct(r);++e<r;)u[e]=n[e][t];return u||ot(n,t)
|
||||
}function ct(n,t,e,r){if(!n)return e;var u=3>arguments.length;t=a.createCallback(t,r,4);var o=-1,i=n.length;if(typeof i=="number")for(u&&(e=n[++o]);++o<i;)e=t(e,n[o],o,n);else se(n,function(n,r,a){e=u?(u=!1,n):t(e,n,r,a)});return e}function lt(n,t,e,r){var u=n?n.length:0,o=3>arguments.length;if(typeof u!="number")var i=oe(n),u=i.length;return t=a.createCallback(t,r,4),at(n,function(r,a,f){a=i?i[--u]:--u,e=o?(o=!1,n[a]):t(e,n[a],a,f)}),e}function pt(n,t,e){var r;t=a.createCallback(t,e),e=-1;var u=n?n.length:0;
|
||||
if(typeof u=="number")for(;++e<u&&!(r=t(n[e],e,n)););else se(n,function(n,e,u){return!(r=t(n,e,u))});return!!r}function st(n,t,e){if(n){var r=0,u=n.length;if(typeof t!="number"&&null!=t){var o=-1;for(t=a.createCallback(t,e);++o<u&&t(n[o],o,n);)r++}else if(r=t,null==r||e)return n[0];return M(n,0,ne(Zt(0,r),u))}}function vt(n,t,e,r){var u=-1,o=n?n.length:0,i=[];for(typeof t!="boolean"&&null!=t&&(r=e,e=t,t=!1),null!=e&&(e=a.createCallback(e,r));++u<o;)r=n[u],e&&(r=e(r,u,n)),ae(r)?Vt.apply(i,t?r:vt(r)):i.push(r);
|
||||
return i}function gt(n,t,e){var r=-1,u=n?n.length:0;if(typeof e=="number")r=(0>e?Zt(0,u+e):e||0)-1;else if(e)return r=yt(n,t),n[r]===t?r:-1;for(;++r<u;)if(n[r]===t)return r;return-1}function ht(n,t,e){if(typeof t!="number"&&null!=t){var r=0,u=-1,o=n?n.length:0;for(t=a.createCallback(t,e);++u<o&&t(n[u],u,n);)r++}else r=null==t||e?1:Zt(0,t);return M(n,r)}function yt(n,t,e,r){var u=0,o=n?n.length:u;for(e=e?a.createCallback(e,r,1):kt,t=e(t);u<o;)r=u+o>>>1,e(n[r])<t?u=r+1:o=r;return u}function mt(n,t,e,r){var u=-1,o=n?n.length:0,i=[],f=i;
|
||||
typeof t!="boolean"&&null!=t&&(r=e,e=t,t=!1);var c=!t&&75<=o;if(c)var l={};for(null!=e&&(f=[],e=a.createCallback(e,r));++u<o;){r=n[u];var p=e?e(r,u,n):r;if(c)var s=$t(p),s=Ut.call(l,s)?!(f=l[s]):f=l[s]=[];(t?!u||f[f.length-1]!==p:s||0>gt(f,p))&&((e||c)&&f.push(p),i.push(r))}return i}function bt(n,t){for(var e=-1,r=n?n.length:0,u={};++e<r;){var a=n[e];t?u[a]=t[e]:u[a[0]]=a[1]}return u}function dt(n,t){return ue.fastBind||Lt&&2<arguments.length?Lt.call.apply(Lt,arguments):F(n,t,M(arguments,2))}function _t(n){var t=M(arguments,1);
|
||||
return Ht(function(){n.apply(e,t)},1)}function kt(n){return n}function wt(n){at(H(n),function(t){var e=a[t]=n[t];a.prototype[t]=function(){var n=this.__wrapped__,t=[n];return Vt.apply(t,arguments),t=e.apply(a,t),n&&typeof n=="object"&&n==t?this:new z(t)}})}function jt(){return this.__wrapped__}r=r?A.defaults(n.Object(),r,A.pick(n,d)):n;var Ct=r.Array,xt=r.Boolean,Ot=r.Date,Nt=r.Function,Et=r.Math,It=r.Number,St=r.Object,At=r.RegExp,$t=r.String,qt=r.TypeError,Bt=Ct(),Ft=St(),Rt=r._,Tt=At("^"+$t(Ft.valueOf).replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),Dt=Et.ceil,zt=r.clearTimeout,Pt=Bt.concat,Kt=Et.floor,Mt=Tt.test(Mt=St.getPrototypeOf)&&Mt,Ut=Ft.hasOwnProperty,Vt=Bt.push,Gt=r.setImmediate,Ht=r.setTimeout,Jt=Ft.toString,Lt=Tt.test(Lt=M.bind)&&Lt,Qt=Tt.test(Qt=Ct.isArray)&&Qt,Wt=r.isFinite,Xt=r.isNaN,Yt=Tt.test(Yt=St.keys)&&Yt,Zt=Et.max,ne=Et.min,te=r.parseInt,ee=Et.random,Et=Tt.test(r.attachEvent),Et=Lt&&!/\n|true/.test(Lt+Et),re={};
|
||||
re[k]=Ct,re[w]=xt,re[j]=Ot,re[x]=St,re[C]=It,re[O]=At,re[N]=$t;var ue=a.support={};ue.fastBind=Lt&&!Et,a.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:g,variable:"",imports:{_:a}},xt={a:"q,w,g",h:"var a=arguments,b=0,c=typeof g=='number'?2:a.length;while(++b<c){m=a[b];if(m&&r[typeof m]){",f:"if(typeof u[i]=='undefined')u[i]=m[i]",c:"}}"},It={a:"e,d,x",h:"d=d&&typeof x=='undefined'?d:p.createCallback(d,x)",b:!1,f:"if(d(m[i],i,e)===false)return u"},St={h:"if(!r[typeof m])return u;"+It.h,b:!1},z.prototype=a.prototype;
|
||||
var ae=Qt||function(n){return n instanceof Ct||Jt.call(n)==k},Qt=R({a:"q",e:"[]",h:"if(!(r[typeof q]))return u",f:"u.push(i)",b:!1}),oe=Yt?function(n){return W(n)?Yt(n):[]}:Qt,ie={"&":"&","<":"<",">":">",'"':""","'":"'"},fe=J(ie),ce=R(xt,{h:xt.h.replace(";",";if(c>3&&typeof a[c-2]=='function'){var d=p.createCallback(a[--c-1],a[c--],2);}else if(c>2&&typeof a[c-1]=='function'){d=a[--c];}"),f:"u[i]=d?d(u[i],m[i]):m[i]"}),le=R(xt),pe=R(It,St,{i:!1}),se=R(It,St),ve=function(n){if(!n||Jt.call(n)!=x)return!1;
|
||||
var t=n.valueOf,e=typeof t=="function"&&(e=Mt(t))&&Mt(e);return e?n==e||Mt(n)==e:K(n)};return Et&&u&&typeof Gt=="function"&&(_t=dt(Gt,r)),Gt=8==te("08")?te:function(n,t){return te(Y(n)?n.replace(h,""):n,t||0)},a.after=function(n,t){return 1>n?t():function(){return 1>--n?t.apply(this,arguments):void 0}},a.assign=ce,a.at=function(n){for(var t=-1,e=Pt.apply(Bt,M(arguments,1)),r=e.length,u=Ct(r);++t<r;)u[t]=n[e[t]];return u},a.bind=dt,a.bindAll=function(n){for(var t=Pt.apply(Bt,arguments),e=1<t.length?0:(t=H(n),-1),r=t.length;++e<r;){var u=t[e];
|
||||
n[u]=dt(n[u],n)}return n},a.bindKey=function(n,t){return F(n,t,M(arguments,2),i)},a.compact=function(n){for(var t=-1,e=n?n.length:0,r=[];++t<e;){var u=n[t];u&&r.push(u)}return r},a.compose=function(){var n=arguments;return function(){for(var t=arguments,e=n.length;e--;)t=[n[e].apply(this,t)];return t[0]}},a.countBy=function(n,t,e){var r={};return t=a.createCallback(t,e),at(n,function(n,e,u){e=$t(t(n,e,u)),Ut.call(r,e)?r[e]++:r[e]=1}),r},a.createCallback=function(n,t,e){if(null==n)return kt;var r=typeof n;
|
||||
if("function"!=r){if("object"!=r)return function(t){return t[n]};var u=oe(n);return function(t){for(var e=u.length,r=!1;e--&&(r=L(t[u[e]],n[u[e]],i)););return r}}return typeof t!="undefined"?1===e?function(e){return n.call(t,e)}:2===e?function(e,r){return n.call(t,e,r)}:4===e?function(e,r,u,a){return n.call(t,e,r,u,a)}:function(e,r,u){return n.call(t,e,r,u)}:n},a.debounce=function(n,t,e){function r(){i=null,e||(a=n.apply(o,u))}var u,a,o,i;return function(){var f=e&&!i;return u=arguments,o=this,zt(i),i=Ht(r,t),f&&(a=n.apply(o,u)),a
|
||||
}},a.defaults=le,a.defer=_t,a.delay=function(n,t){var r=M(arguments,2);return Ht(function(){n.apply(e,r)},t)},a.difference=function(n){for(var t=-1,e=n?n.length:0,r=Pt.apply(Bt,arguments),r=$(r,e,100),u=[];++t<e;){var a=n[t];r(a)||u.push(a)}return u},a.filter=rt,a.flatten=vt,a.forEach=at,a.forIn=pe,a.forOwn=se,a.functions=H,a.groupBy=function(n,t,e){var r={};return t=a.createCallback(t,e),at(n,function(n,e,u){e=$t(t(n,e,u)),(Ut.call(r,e)?r[e]:r[e]=[]).push(n)}),r},a.initial=function(n,t,e){if(!n)return[];
|
||||
var r=0,u=n.length;if(typeof t!="number"&&null!=t){var o=u;for(t=a.createCallback(t,e);o--&&t(n[o],o,n);)r++}else r=null==t||e?1:t||r;return M(n,0,ne(Zt(0,u-r),u))},a.intersection=function(n){var t=arguments,e=t.length,r={0:{}},u=-1,a=n?n.length:0,o=100<=a,i=[],f=i;n:for(;++u<a;){var c=n[u];if(o)var l=$t(c),l=Ut.call(r[0],l)?!(f=r[0][l]):f=r[0][l]=[];if(l||0>gt(f,c)){o&&f.push(c);for(var p=e;--p;)if(!(r[p]||(r[p]=$(t[p],0,100)))(c))continue n;i.push(c)}}return i},a.invert=J,a.invoke=function(n,t){var e=M(arguments,2),r=-1,u=typeof t=="function",a=n?n.length:0,o=Ct(typeof a=="number"?a:0);
|
||||
return at(n,function(n){o[++r]=(u?t:n[t]).apply(n,e)}),o},a.keys=oe,a.map=ot,a.max=it,a.memoize=function(n,t){var e={};return function(){var r=$t(t?t.apply(this,arguments):arguments[0]);return Ut.call(e,r)?e[r]:e[r]=n.apply(this,arguments)}},a.merge=Z,a.min=function(n,t,e){var r=1/0,u=r;if(!t&&ae(n)){e=-1;for(var o=n.length;++e<o;){var i=n[e];i<u&&(u=i)}}else t=!t&&Y(n)?q:a.createCallback(t,e),at(n,function(n,e,a){e=t(n,e,a),e<r&&(r=e,u=n)});return u},a.omit=function(n,t,e){var r=typeof t=="function",u={};
|
||||
if(r)t=a.createCallback(t,e);else var o=Pt.apply(Bt,arguments);return pe(n,function(n,e,a){(r?!t(n,e,a):0>gt(o,e,1))&&(u[e]=n)}),u},a.once=function(n){var t,e;return function(){return t?e:(t=!0,e=n.apply(this,arguments),n=null,e)}},a.pairs=function(n){for(var t=-1,e=oe(n),r=e.length,u=Ct(r);++t<r;){var a=e[t];u[t]=[a,n[a]]}return u},a.partial=function(n){return F(n,M(arguments,1))},a.partialRight=function(n){return F(n,M(arguments,1),null,i)},a.pick=function(n,t,e){var r={};if(typeof t!="function")for(var u=0,o=Pt.apply(Bt,arguments),i=W(n)?o.length:0;++u<i;){var f=o[u];
|
||||
f in n&&(r[f]=n[f])}else t=a.createCallback(t,e),pe(n,function(n,e,u){t(n,e,u)&&(r[e]=n)});return r},a.pluck=ft,a.range=function(n,t,e){n=+n||0,e=+e||1,null==t&&(t=n,n=0);var r=-1;t=Zt(0,Dt((t-n)/e));for(var u=Ct(t);++r<t;)u[r]=n,n+=e;return u},a.reject=function(n,t,e){return t=a.createCallback(t,e),rt(n,function(n,e,r){return!t(n,e,r)})},a.rest=ht,a.shuffle=function(n){var t=-1,e=n?n.length:0,r=Ct(typeof e=="number"?e:0);return at(n,function(n){var e=Kt(ee()*(++t+1));r[t]=r[e],r[e]=n}),r},a.sortBy=function(n,t,e){var r=-1,u=n?n.length:0,o=Ct(typeof u=="number"?u:0);
|
||||
for(t=a.createCallback(t,e),at(n,function(n,e,u){o[++r]={a:t(n,e,u),b:r,c:n}}),u=o.length,o.sort(B);u--;)o[u]=o[u].c;return o},a.tap=function(n,t){return t(n),n},a.throttle=function(n,t){function e(){i=new Ot,o=null,u=n.apply(a,r)}var r,u,a,o,i=0;return function(){var f=new Ot,c=t-(f-i);return r=arguments,a=this,0<c?o||(o=Ht(e,c)):(zt(o),o=null,i=f,u=n.apply(a,r)),u}},a.times=function(n,t,e){n=-1<(n=+n)?n:0;var r=-1,u=Ct(n);for(t=a.createCallback(t,e,1);++r<n;)u[r]=t(r);return u},a.toArray=function(n){return n&&typeof n.length=="number"?M(n):nt(n)
|
||||
},a.union=function(){return mt(Pt.apply(Bt,arguments))},a.uniq=mt,a.values=nt,a.where=rt,a.without=function(n){for(var t=-1,e=n?n.length:0,r=$(arguments,1,30),u=[];++t<e;){var a=n[t];r(a)||u.push(a)}return u},a.wrap=function(n,t){return function(){var e=[n];return Vt.apply(e,arguments),t.apply(this,e)}},a.zip=function(n){for(var t=-1,e=n?it(ft(arguments,"length")):0,r=Ct(e);++t<e;)r[t]=ft(arguments,t);return r},a.zipObject=bt,a.collect=ot,a.drop=ht,a.each=at,a.extend=ce,a.methods=H,a.object=bt,a.select=rt,a.tail=ht,a.unique=mt,wt(a),a.clone=G,a.cloneDeep=function(n,t,e){return G(n,!0,t,e)
|
||||
},a.contains=tt,a.escape=function(n){return null==n?"":$t(n).replace(m,D)},a.every=et,a.find=ut,a.findIndex=function(n,t,e){var r=-1,u=n?n.length:0;for(t=a.createCallback(t,e);++r<u;)if(t(n[r],r,n))return r;return-1},a.findKey=function(n,t,e){var r;return t=a.createCallback(t,e),se(n,function(n,e,u){return t(n,e,u)?(r=e,!1):void 0}),r},a.has=function(n,t){return n?Ut.call(n,t):!1},a.identity=kt,a.indexOf=gt,a.isArguments=V,a.isArray=ae,a.isBoolean=function(n){return!0===n||!1===n||Jt.call(n)==w},a.isDate=function(n){return n instanceof Ot||Jt.call(n)==j
|
||||
},a.isElement=function(n){return n?1===n.nodeType:!1},a.isEmpty=function(n){var t=!0;if(!n)return t;var e=Jt.call(n),r=n.length;return e==k||e==N||e==_||e==x&&typeof r=="number"&&Q(n.splice)?!r:(se(n,function(){return t=!1}),t)},a.isEqual=L,a.isFinite=function(n){return Wt(n)&&!Xt(parseFloat(n))},a.isFunction=Q,a.isNaN=function(n){return X(n)&&n!=+n},a.isNull=function(n){return null===n},a.isNumber=X,a.isObject=W,a.isPlainObject=ve,a.isRegExp=function(n){return n instanceof At||Jt.call(n)==O},a.isString=Y,a.isUndefined=function(n){return typeof n=="undefined"
|
||||
},a.lastIndexOf=function(n,t,e){var r=n?n.length:0;for(typeof e=="number"&&(r=(0>e?Zt(0,r+e):ne(e,r-1))+1);r--;)if(n[r]===t)return r;return-1},a.mixin=wt,a.noConflict=function(){return r._=Rt,this},a.parseInt=Gt,a.random=function(n,t){return null==n&&null==t&&(t=1),n=+n||0,null==t&&(t=n,n=0),n+Kt(ee()*((+t||0)-n+1))},a.reduce=ct,a.reduceRight=lt,a.result=function(n,t){var r=n?n[t]:e;return Q(r)?n[t]():r},a.runInContext=t,a.size=function(n){var t=n?n.length:0;return typeof t=="number"?t:oe(n).length
|
||||
},a.some=pt,a.sortedIndex=yt,a.template=function(n,t,r){var u=a.templateSettings;n||(n=""),r=le({},r,u);var o,i=le({},r.imports,u.imports),u=oe(i),i=nt(i),p=0,v=r.interpolate||y,h="__p+='",v=At((r.escape||y).source+"|"+v.source+"|"+(v===g?s:y).source+"|"+(r.evaluate||y).source+"|$","g");n.replace(v,function(t,e,r,u,a,i){return r||(r=u),h+=n.slice(p,i).replace(b,T),e&&(h+="'+__e("+e+")+'"),a&&(o=!0,h+="';"+a+";__p+='"),r&&(h+="'+((__t=("+r+"))==null?'':__t)+'"),p=i+t.length,t}),h+="';\n",v=r=r.variable,v||(r="obj",h="with("+r+"){"+h+"}"),h=(o?h.replace(f,""):h).replace(c,"$1").replace(l,"$1;"),h="function("+r+"){"+(v?"":r+"||("+r+"={});")+"var __t,__p='',__e=_.escape"+(o?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+h+"return __p}";
|
||||
try{var m=Nt(u,"return "+h).apply(e,i)}catch(d){throw d.source=h,d}return t?m(t):(m.source=h,m)},a.unescape=function(n){return null==n?"":$t(n).replace(p,U)},a.uniqueId=function(n){var t=++o;return $t(null==n?"":n)+t},a.all=et,a.any=pt,a.detect=ut,a.foldl=ct,a.foldr=lt,a.include=tt,a.inject=ct,se(a,function(n,t){a.prototype[t]||(a.prototype[t]=function(){var t=[this.__wrapped__];return Vt.apply(t,arguments),n.apply(a,t)})}),a.first=st,a.last=function(n,t,e){if(n){var r=0,u=n.length;if(typeof t!="number"&&null!=t){var o=u;
|
||||
for(t=a.createCallback(t,e);o--&&t(n[o],o,n);)r++}else if(r=t,null==r||e)return n[u-1];return M(n,Zt(0,u-r))}},a.take=st,a.head=st,se(a,function(n,t){a.prototype[t]||(a.prototype[t]=function(t,e){var r=n(this.__wrapped__,t,e);return null==t||e&&typeof t!="function"?r:new z(r)})}),a.VERSION="1.1.0",a.prototype.toString=function(){return $t(this.__wrapped__)},a.prototype.value=jt,a.prototype.valueOf=jt,at(["join","pop","shift"],function(n){var t=Bt[n];a.prototype[n]=function(){return t.apply(this.__wrapped__,arguments)
|
||||
}}),at(["push","reverse","sort","unshift"],function(n){var t=Bt[n];a.prototype[n]=function(){return t.apply(this.__wrapped__,arguments),this}}),at(["concat","slice","splice"],function(n){var t=Bt[n];a.prototype[n]=function(){return new z(t.apply(this.__wrapped__,arguments))}}),a}var e,r=typeof exports=="object"&&exports,u=typeof module=="object"&&module&&module.exports==r&&module,a=typeof global=="object"&&global;a.global===a&&(n=a);var o=0,i={},f=/\b__p\+='';/g,c=/\b(__p\+=)''\+/g,l=/(__e\(.*?\)|\b__t\))\+'';/g,p=/&(?:amp|lt|gt|quot|#39);/g,s=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,v=/\w*$/,g=/<%=([\s\S]+?)%>/g,h=/^0+(?=.$)/,y=/($^)/,m=/[&<>"']/g,b=/['\n\r\t\u2028\u2029\\]/g,d="Array Boolean Date Function Math Number Object RegExp String _ attachEvent clearTimeout isFinite isNaN parseInt setImmediate setTimeout".split(" "),_="[object Arguments]",k="[object Array]",w="[object Boolean]",j="[object Date]",C="[object Number]",x="[object Object]",O="[object RegExp]",N="[object String]",E={"[object Function]":!1};
|
||||
E[_]=E[k]=E[w]=E[j]=E[C]=E[x]=E[O]=E[N]=!0;var I={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,undefined:!1},S={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"},A=t();typeof define=="function"&&typeof define.amd=="object"&&define.amd?(n._=A,define(function(){return A})):r&&!r.nodeType?u?(u.exports=A)._=A:r._=A:n._=A})(this);
|
||||
4357
dist/lodash.underscore.js
vendored
Normal file
4357
dist/lodash.underscore.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
34
dist/lodash.underscore.min.js
vendored
Normal file
34
dist/lodash.underscore.min.js
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* @license
|
||||
* Lo-Dash 1.1.0 (Custom Build) lodash.com/license
|
||||
* Build: `lodash underscore exports="amd,commonjs,global,node" -o ./dist/lodash.underscore.js`
|
||||
* Underscore.js 1.4.4 underscorejs.org/LICENSE
|
||||
*/
|
||||
;(function(n){function t(n,t){var r;if(n&&st[typeof n])for(r in t||(t=W),n)if(jt.call(n,r)&&t(n[r],r,n)===Z)break}function r(n,t){var r;if(n&&st[typeof n])for(r in t||(t=W),n)if(t(n[r],r,n)===Z)break}function e(n){var t,r=[];if(!n||!st[typeof n])return r;for(t in n)jt.call(n,t)&&r.push(t);return r}function u(n){return n instanceof u?n:new c(n)}function o(n,t){var r=n.b,e=t.b;if(n=n.a,t=t.a,n!==t){if(n>t||typeof n=="undefined")return 1;if(n<t||typeof t=="undefined")return-1}return r<e?-1:1}function i(n,t,r){function e(){var f=arguments,c=o?this:t;
|
||||
return u||(n=t[i]),r.length&&(f=f.length?(f=xt.call(f),a?f.concat(r):r.concat(f)):r),this instanceof e?(l.prototype=n.prototype,c=new l,l.prototype=J,f=n.apply(c,f),d(f)?f:c):n.apply(c,f)}var u=b(n),o=!r,i=t;if(o){var a=void 0;r=t}else if(!u)throw new TypeError;return e}function a(n){return"\\"+vt[n]}function f(n){return It[n]}function c(n){this.__wrapped__=n}function l(){}function p(n){return zt[n]}function s(n){return Ot.call(n)==ut}function v(n){if(!n)return n;for(var t=1,r=arguments.length;t<r;t++){var e=arguments[t];
|
||||
if(e)for(var u in e)n[u]=e[u]}return n}function g(n){if(!n)return n;for(var t=1,r=arguments.length;t<r;t++){var e=arguments[t];if(e)for(var u in e)n[u]==J&&(n[u]=e[u])}return n}function h(n){var t=[];return r(n,function(n,r){b(n)&&t.push(r)}),t.sort()}function y(n){for(var t=-1,r=$t(n),e=r.length,u={};++t<e;){var o=r[t];u[n[o]]=o}return u}function m(n){if(!n)return H;if(Tt(n)||w(n))return!n.length;for(var t in n)if(jt.call(n,t))return K;return H}function _(n,t,e,o){if(n===t)return 0!==n||1/n==1/t;
|
||||
var i=typeof n,a=typeof t;if(n===n&&(!n||"function"!=i&&"object"!=i)&&(!t||"function"!=a&&"object"!=a))return K;if(n==J||t==J)return n===t;if(a=Ot.call(n),i=Ot.call(t),a!=i)return K;switch(a){case it:case at:return+n==+t;case ft:return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case lt:case pt:return n==t+""}if(i=a==ot,!i){if(n instanceof u||t instanceof u)return _(n.__wrapped__||n,t.__wrapped__||t,e,o);if(a!=ct)return K;var a=n.constructor,f=t.constructor;if(a!=f&&(!b(a)||!(a instanceof a&&b(f)&&f instanceof f)))return K
|
||||
}for(e||(e=[]),o||(o=[]),a=e.length;a--;)if(e[a]==n)return o[a]==t;var c=H,l=0;if(e.push(n),o.push(t),i){if(l=t.length,c=l==n.length)for(;l--&&(c=_(n[l],t[l],e,o)););return c}return r(t,function(t,r,u){return jt.call(u,r)?(l++,!(c=jt.call(n,r)&&_(n[r],t,e,o))&&Z):void 0}),c&&r(n,function(n,t,r){return jt.call(r,t)?!(c=-1<--l)&&Z:void 0}),c}function b(n){return typeof n=="function"}function d(n){return n?st[typeof n]:K}function j(n){return typeof n=="number"||Ot.call(n)==ft}function w(n){return typeof n=="string"||Ot.call(n)==pt
|
||||
}function A(n){for(var t=-1,r=$t(n),e=r.length,u=Array(e);++t<e;)u[t]=n[r[t]];return u}function x(n,r){var e=K;return typeof(n?n.length:0)=="number"?e=-1<I(n,r):t(n,function(n){return(e=n===r)&&Z}),e}function O(n,r,e){var u=H;r=V(r,e),e=-1;var o=n?n.length:0;if(typeof o=="number")for(;++e<o&&(u=!!r(n[e],e,n)););else t(n,function(n,t,e){return!(u=!!r(n,t,e))&&Z});return u}function E(n,r,e){var u=[];r=V(r,e),e=-1;var o=n?n.length:0;if(typeof o=="number")for(;++e<o;){var i=n[e];r(i,e,n)&&u.push(i)}else t(n,function(n,t,e){r(n,t,e)&&u.push(n)
|
||||
});return u}function S(n,r,e){r=V(r,e),e=-1;var u=n?n.length:0;if(typeof u!="number"){var o;return t(n,function(n,t,e){return r(n,t,e)?(o=n,Z):void 0}),o}for(;++e<u;){var i=n[e];if(r(i,e,n))return i}}function N(n,r,e){var u=-1,o=n?n.length:0;if(typeof o=="number")for(r=r&&typeof e=="undefined"?r:V(r,e);++u<o&&r(n[u],u,n)!==Z;);else t(n,r)}function k(n,r,e){var u=-1,o=n?n.length:0;if(r=V(r,e),typeof o=="number")for(var i=Array(o);++u<o;)i[u]=r(n[u],u,n);else i=[],t(n,function(n,t,e){i[++u]=r(n,t,e)
|
||||
});return i}function B(n,t,r){var e=-1/0,u=e,o=-1,i=n?n.length:0;if(t||typeof i!="number")t=V(t,r),N(n,function(n,r,o){r=t(n,r,o),r>e&&(e=r,u=n)});else for(;++o<i;)r=n[o],r>u&&(u=r);return u}function F(n,t){var r=-1,e=n?n.length:0;if(typeof e=="number")for(var u=Array(e);++r<e;)u[r]=n[r][t];return u||k(n,t)}function R(n,r,e,u){if(!n)return e;var o=3>arguments.length;r=V(r,u,4);var i=-1,a=n.length;if(typeof a=="number")for(o&&(e=n[++i]);++i<a;)e=r(e,n[i],i,n);else t(n,function(n,t,u){e=o?(o=K,n):r(e,n,t,u)
|
||||
});return e}function q(n,t,r,e){var u=n?n.length:0,o=3>arguments.length;if(typeof u!="number")var i=$t(n),u=i.length;return t=V(t,e,4),N(n,function(e,a,f){a=i?i[--u]:--u,r=o?(o=K,n[a]):t(r,n[a],a,f)}),r}function D(n,r,e){var u;r=V(r,e),e=-1;var o=n?n.length:0;if(typeof o=="number")for(;++e<o&&!(u=r(n[e],e,n)););else t(n,function(n,t,e){return(u=r(n,t,e))&&Z});return!!u}function M(n,t,r){return r&&m(t)?J:(r?S:E)(n,t)}function T(n,t,r){if(n){var e=0,u=n.length;if(typeof t!="number"&&t!=J){var o=-1;
|
||||
for(t=V(t,r);++o<u&&t(n[o],o,n);)e++}else if(e=t,e==J||r)return n[0];return xt.call(n,0,Rt(Ft(0,e),u))}}function $(n,t){for(var r=-1,e=n?n.length:0,u=[];++r<e;){var o=n[r];Tt(o)?wt.apply(u,t?o:$(o)):u.push(o)}return u}function I(n,t,r){var e=-1,u=n?n.length:0;if(typeof r=="number")e=(0>r?Ft(0,u+r):r||0)-1;else if(r)return e=C(n,t),n[e]===t?e:-1;for(;++e<u;)if(n[e]===t)return e;return-1}function z(n,t,r){if(typeof t!="number"&&t!=J){var e=0,u=-1,o=n?n.length:0;for(t=V(t,r);++u<o&&t(n[u],u,n);)e++}else e=t==J||r?1:Ft(0,t);
|
||||
return xt.call(n,e)}function C(n,t,r,e){var u=0,o=n?n.length:u;for(r=r?V(r,e,1):W,t=r(t);u<o;)e=u+o>>>1,r(n[e])<t?u=e+1:o=e;return u}function P(n,t,r,e){var u=-1,o=n?n.length:0,i=[],a=i;for(typeof t!="boolean"&&t!=J&&(e=r,r=t,t=K),r!=J&&(a=[],r=V(r,e));++u<o;){e=n[u];var f=r?r(e,u,n):e;(t?!u||a[a.length-1]!==f:0>I(a,f))&&(r&&a.push(f),i.push(e))}return i}function U(n,t){return Mt.fastBind||Et&&2<arguments.length?Et.call.apply(Et,arguments):i(n,t,xt.call(arguments,2))}function V(n,t,r){if(n==J)return W;
|
||||
var e=typeof n;if("function"!=e){if("object"!=e)return function(t){return t[n]};var u=$t(n);return function(t){for(var r=u.length,e=K;r--&&(e=t[u[r]]===n[u[r]]););return e}}return typeof t!="undefined"?1===r?function(r){return n.call(t,r)}:2===r?function(r,e){return n.call(t,r,e)}:4===r?function(r,e,u,o){return n.call(t,r,e,u,o)}:function(r,e,u){return n.call(t,r,e,u)}:n}function W(n){return n}function G(n){N(h(n),function(t){var r=u[t]=n[t];u.prototype[t]=function(){var n=[this.__wrapped__];return wt.apply(n,arguments),n=r.apply(u,n),this.__chain__&&(n=new c(n),n.__chain__=H),n
|
||||
}})}var H=!0,J=null,K=!1,L=typeof exports=="object"&&exports,Q=typeof module=="object"&&module&&module.exports==L&&module,X=typeof global=="object"&&global;X.global===X&&(n=X);var Y=0,Z={},nt=/&(?:amp|lt|gt|quot|#39);/g,tt=/($^)/,rt=/[&<>"']/g,et=/['\n\r\t\u2028\u2029\\]/g,ut="[object Arguments]",ot="[object Array]",it="[object Boolean]",at="[object Date]",ft="[object Number]",ct="[object Object]",lt="[object RegExp]",pt="[object String]",st={"boolean":K,"function":H,object:H,number:K,string:K,undefined:K},vt={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"},gt=[],X={},ht=n._,yt=RegExp("^"+(X.valueOf+"").replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),mt=Math.ceil,_t=n.clearTimeout,bt=gt.concat,dt=Math.floor,jt=X.hasOwnProperty,wt=gt.push,At=n.setTimeout,xt=gt.slice,Ot=X.toString,Et=yt.test(Et=xt.bind)&&Et,St=yt.test(St=Array.isArray)&&St,Nt=n.isFinite,kt=n.isNaN,Bt=yt.test(Bt=Object.keys)&&Bt,Ft=Math.max,Rt=Math.min,qt=Math.random,X=yt.test(n.attachEvent),Dt=Et&&!/\n|true/.test(Et+X),Mt={};
|
||||
(function(){var n={0:1,length:1};Mt.argsObject=arguments.constructor==Object,Mt.fastBind=Et&&!Dt,Mt.spliceObjects=(gt.splice.call(n,0,1),!n[0])})(1),u.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:""},c.prototype=u.prototype,s(arguments)||(s=function(n){return n?jt.call(n,"callee"):K});var Tt=St||function(n){return Mt.argsObject&&n instanceof Array||Ot.call(n)==ot},$t=Bt?function(n){return d(n)?Bt(n):[]}:e,It={"&":"&","<":"<",">":">",'"':""","'":"'"},zt=y(It);
|
||||
b(/x/)&&(b=function(n){return n instanceof Function||"[object Function]"==Ot.call(n)}),u.after=function(n,t){return 1>n?t():function(){return 1>--n?t.apply(this,arguments):void 0}},u.bind=U,u.bindAll=function(n){for(var t=bt.apply(gt,arguments),r=1<t.length?0:(t=h(n),-1),e=t.length;++r<e;){var u=t[r];n[u]=U(n[u],n)}return n},u.compact=function(n){for(var t=-1,r=n?n.length:0,e=[];++t<r;){var u=n[t];u&&e.push(u)}return e},u.compose=function(){var n=arguments;return function(){for(var t=arguments,r=n.length;r--;)t=[n[r].apply(this,t)];
|
||||
return t[0]}},u.countBy=function(n,t,r){var e={};return t=V(t,r),N(n,function(n,r,u){r=t(n,r,u)+"",jt.call(e,r)?e[r]++:e[r]=1}),e},u.debounce=function(n,t,r){function e(){a=J,r||(o=n.apply(i,u))}var u,o,i,a;return function(){var f=r&&!a;return u=arguments,i=this,_t(a),a=At(e,t),f&&(o=n.apply(i,u)),o}},u.defaults=g,u.defer=function(n){var t=xt.call(arguments,1);return At(function(){n.apply(void 0,t)},1)},u.delay=function(n,t){var r=xt.call(arguments,2);return At(function(){n.apply(void 0,r)},t)},u.difference=function(n){for(var t=-1,r=n.length,e=bt.apply(gt,arguments),u=[];++t<r;){var o=n[t];
|
||||
0>I(e,o,r)&&u.push(o)}return u},u.filter=E,u.flatten=$,u.forEach=N,u.functions=h,u.groupBy=function(n,t,r){var e={};return t=V(t,r),N(n,function(n,r,u){r=t(n,r,u)+"",(jt.call(e,r)?e[r]:e[r]=[]).push(n)}),e},u.initial=function(n,t,r){if(!n)return[];var e=0,u=n.length;if(typeof t!="number"&&t!=J){var o=u;for(t=V(t,r);o--&&t(n[o],o,n);)e++}else e=t==J||r?1:t||e;return xt.call(n,0,Rt(Ft(0,u-e),u))},u.intersection=function(n){var t=arguments,r=t.length,e=-1,u=n?n.length:0,o=[];n:for(;++e<u;){var i=n[e];
|
||||
if(0>I(o,i)){for(var a=r;--a;)if(0>I(t[a],i))continue n;o.push(i)}}return o},u.invert=y,u.invoke=function(n,t){var r=xt.call(arguments,2),e=-1,u=typeof t=="function",o=n?n.length:0,i=Array(typeof o=="number"?o:0);return N(n,function(n){i[++e]=(u?t:n[t]).apply(n,r)}),i},u.keys=$t,u.map=k,u.max=B,u.memoize=function(n,t){var r={};return function(){var e=(t?t.apply(this,arguments):arguments[0])+"";return jt.call(r,e)?r[e]:r[e]=n.apply(this,arguments)}},u.min=function(n,t,r){var e=1/0,u=e,o=-1,i=n?n.length:0;
|
||||
if(t||typeof i!="number")t=V(t,r),N(n,function(n,r,o){r=t(n,r,o),r<e&&(e=r,u=n)});else for(;++o<i;)r=n[o],r<u&&(u=r);return u},u.omit=function(n){var t=bt.apply(gt,arguments),e={};return r(n,function(n,r){0>I(t,r,1)&&(e[r]=n)}),e},u.once=function(n){var t,r;return function(){return t?r:(t=H,r=n.apply(this,arguments),n=J,r)}},u.pairs=function(n){for(var t=-1,r=$t(n),e=r.length,u=Array(e);++t<e;){var o=r[t];u[t]=[o,n[o]]}return u},u.partial=function(n){return i(n,xt.call(arguments,1))},u.pick=function(n){for(var t=0,r=bt.apply(gt,arguments),e=r.length,u={};++t<e;){var o=r[t];
|
||||
o in n&&(u[o]=n[o])}return u},u.pluck=F,u.range=function(n,t,r){n=+n||0,r=+r||1,t==J&&(t=n,n=0);var e=-1;t=Ft(0,mt((t-n)/r));for(var u=Array(t);++e<t;)u[e]=n,n+=r;return u},u.reject=function(n,t,r){return t=V(t,r),E(n,function(n,r,e){return!t(n,r,e)})},u.rest=z,u.shuffle=function(n){var t=-1,r=n?n.length:0,e=Array(typeof r=="number"?r:0);return N(n,function(n){var r=dt(qt()*(++t+1));e[t]=e[r],e[r]=n}),e},u.sortBy=function(n,t,r){var e=-1,u=n?n.length:0,i=Array(typeof u=="number"?u:0);for(t=V(t,r),N(n,function(n,r,u){i[++e]={a:t(n,r,u),b:e,c:n}
|
||||
}),u=i.length,i.sort(o);u--;)i[u]=i[u].c;return i},u.tap=function(n,t){return t(n),n},u.throttle=function(n,t){function r(){a=new Date,i=J,u=n.apply(o,e)}var e,u,o,i,a=0;return function(){var f=new Date,c=t-(f-a);return e=arguments,o=this,0<c?i||(i=At(r,c)):(_t(i),i=J,a=f,u=n.apply(o,e)),u}},u.times=function(n,t,r){for(var e=-1,u=Array(-1<n?n:0);++e<n;)u[e]=t.call(r,e);return u},u.toArray=function(n){return Tt(n)?xt.call(n):n&&typeof n.length=="number"?k(n):A(n)},u.union=function(){return P(bt.apply(gt,arguments))
|
||||
},u.uniq=P,u.values=A,u.where=M,u.without=function(n){for(var t=-1,r=n.length,e=[];++t<r;){var u=n[t];0>I(arguments,u,1)&&e.push(u)}return e},u.wrap=function(n,t){return function(){var r=[n];return wt.apply(r,arguments),t.apply(this,r)}},u.zip=function(n){for(var t=-1,r=n?B(F(arguments,"length")):0,e=Array(r);++t<r;)e[t]=F(arguments,t);return e},u.collect=k,u.drop=z,u.each=N,u.extend=v,u.methods=h,u.object=function(n,t){for(var r=-1,e=n?n.length:0,u={};++r<e;){var o=n[r];t?u[o]=t[r]:u[o[0]]=o[1]}return u
|
||||
},u.select=E,u.tail=z,u.unique=P,u.clone=function(n){return d(n)?Tt(n)?xt.call(n):v({},n):n},u.contains=x,u.escape=function(n){return n==J?"":(n+"").replace(rt,f)},u.every=O,u.find=S,u.findWhere=function(n,t){return M(n,t,H)},u.has=function(n,t){return n?jt.call(n,t):K},u.identity=W,u.indexOf=I,u.isArguments=s,u.isArray=Tt,u.isBoolean=function(n){return n===H||n===K||Ot.call(n)==it},u.isDate=function(n){return n instanceof Date||Ot.call(n)==at},u.isElement=function(n){return n?1===n.nodeType:K},u.isEmpty=m,u.isEqual=_,u.isFinite=function(n){return Nt(n)&&!kt(parseFloat(n))
|
||||
},u.isFunction=b,u.isNaN=function(n){return j(n)&&n!=+n},u.isNull=function(n){return n===J},u.isNumber=j,u.isObject=d,u.isRegExp=function(n){return n instanceof RegExp||Ot.call(n)==lt},u.isString=w,u.isUndefined=function(n){return typeof n=="undefined"},u.lastIndexOf=function(n,t,r){var e=n?n.length:0;for(typeof r=="number"&&(e=(0>r?Ft(0,e+r):Rt(r,e-1))+1);e--;)if(n[e]===t)return e;return-1},u.mixin=G,u.noConflict=function(){return n._=ht,this},u.random=function(n,t){return n==J&&t==J&&(t=1),n=+n||0,t==J&&(t=n,n=0),n+dt(qt()*((+t||0)-n+1))
|
||||
},u.reduce=R,u.reduceRight=q,u.result=function(n,t){var r=n?n[t]:J;return b(r)?n[t]():r},u.size=function(n){var t=n?n.length:0;return typeof t=="number"?t:$t(n).length},u.some=D,u.sortedIndex=C,u.template=function(n,t,r){n||(n=""),r=g({},r,u.templateSettings);var e=0,o="__p+='",i=r.variable;n.replace(RegExp((r.escape||tt).source+"|"+(r.interpolate||tt).source+"|"+(r.evaluate||tt).source+"|$","g"),function(t,r,u,i,f){return o+=n.slice(e,f).replace(et,a),r&&(o+="'+_['escape']("+r+")+'"),i&&(o+="';"+i+";__p+='"),u&&(o+="'+((__t=("+u+"))==null?'':__t)+'"),e=f+t.length,t
|
||||
}),o+="';\n",i||(i="obj",o="with("+i+"||{}){"+o+"}"),o="function("+i+"){var __t,__p='',__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}"+o+"return __p}";try{var f=Function("_","return "+o)(u)}catch(c){throw c.source=o,c}return t?f(t):(f.source=o,f)},u.unescape=function(n){return n==J?"":(n+"").replace(nt,p)},u.uniqueId=function(n){var t=++Y+"";return n?n+t:t},u.all=O,u.any=D,u.detect=S,u.foldl=R,u.foldr=q,u.include=x,u.inject=R,u.first=T,u.last=function(n,t,r){if(n){var e=0,u=n.length;
|
||||
if(typeof t!="number"&&t!=J){var o=u;for(t=V(t,r);o--&&t(n[o],o,n);)e++}else if(e=t,e==J||r)return n[u-1];return xt.call(n,Ft(0,u-e))}},u.take=T,u.head=T,u.chain=function(n){return n=new c(n),n.__chain__=H,n},u.VERSION="1.1.0",G(u),u.prototype.chain=function(){return this.__chain__=H,this},u.prototype.value=function(){return this.__wrapped__},N("pop push reverse shift sort splice unshift".split(" "),function(n){var t=gt[n];u.prototype[n]=function(){var n=this.__wrapped__;return t.apply(n,arguments),!Mt.spliceObjects&&0===n.length&&delete n[0],this
|
||||
}}),N(["concat","join","slice"],function(n){var t=gt[n];u.prototype[n]=function(){var n=t.apply(this.__wrapped__,arguments);return this.__chain__&&(n=new c(n),n.__chain__=H),n}}),typeof define=="function"&&typeof define.amd=="object"&&define.amd?(n._=u,define(function(){return u})):L&&!L.nodeType?Q?(Q.exports=u)._=u:L._=u:n._=u})(this);
|
||||
4217
doc/README.md
4217
doc/README.md
File diff suppressed because it is too large
Load Diff
@@ -20,9 +20,10 @@
|
||||
|
||||
// generate Markdown
|
||||
$markdown = docdown(array(
|
||||
'path' => '../' . $file,
|
||||
'title' => 'Lo-Dash <sup>v0.8.0</sup>',
|
||||
'url' => 'https://github.com/bestiejs/lodash/blob/master/lodash.js'
|
||||
'path' => '../' . $file,
|
||||
'title' => 'Lo-Dash <sup>v1.1.0</sup>',
|
||||
'toc' => 'categories',
|
||||
'url' => 'https://github.com/bestiejs/lodash/blob/master/lodash.js'
|
||||
));
|
||||
|
||||
// save to a .md file
|
||||
|
||||
39
lodash.min.js
vendored
39
lodash.min.js
vendored
@@ -1,39 +0,0 @@
|
||||
/*!
|
||||
Lo-Dash 0.8.0 lodash.com/license
|
||||
Underscore.js 1.4.0 underscorejs.org/LICENSE
|
||||
*/
|
||||
;(function(e,t){function s(e){if(e&&e.__wrapped__)return e;if(!(this instanceof s))return new s(e);this.__wrapped__=e}function o(e,t,n){t||(t=0);var r=e.length,i=r-t>=(n||H),s=i?{}:e;if(i)for(var o=t-1;++o<r;)n=e[o]+"",(Q.call(s,n)?s[n]:s[n]=[]).push(e[o]);return function(e){if(i){var n=e+"";return Q.call(s,n)&&-1<x(s[n],e)}return-1<x(s,e,t)}}function u(e,n){var r=e.b,i=n.b,e=e.a,n=n.a;if(e!==n){if(e>n||e===t)return 1;if(e<n||n===t)return-1}return r<i?-1:1}function a(e,t,n){function r(){var u=arguments
|
||||
,a=s?this:t;return i||(e=t[o]),n.length&&(u=u.length?n.concat(Z.call(u)):n),this instanceof r?(p.prototype=e.prototype,a=new p,(u=e.apply(a,u))&&Pt[typeof u]?u:a):e.apply(a,u)}var i=m(e),s=!n,o=e;return s&&(n=t),r}function f(e,n){return e?"function"!=typeof e?function(t){return t[e]}:n!==t?function(t,r,i){return e.call(n,t,r,i)}:e:A}function l(){for(var e,t,n,s=-1,o=arguments.length,a={e:"",p:"",c:{d:""},l:{d:""}};++s<o;)for(t in e=arguments[s],e)n=(n=e[t])==r?"":n,/d|h/.test(t)?("string"==typeof
|
||||
n&&(n={b:n,k:n}),a.c[t]=n.b||"",a.l[t]=n.k||""):a[t]=n;e=a.a,t=/^[^,]+/.exec(e)[0],n=a.i,s=a.r,a.f=t,a.g=wt,a.i=n==r?t:n,a.j=Ot,a.m=xt,a.o=J,a.q=a.q!==i,a.r=s==r?Mt:s,a.n==r&&(a.n=Ct);if("d"!=t||!a.c.h)a.c=r;t="",a.r&&(t+="'use strict';"),t+="var j,B,k="+a.f+",u",a.i&&(t+="="+a.i),t+=";"+a.p+";",a.c&&(t+="var l=k.length;j=-1;",a.l&&(t+="if(l===+l){"),a.n&&(t+="if(z.call(k)==x){k=k.split('')}"),t+=a.c.d+";while(++j<l){B=k[j];"+a.c.h+"}",a.l&&(t+="}"));if(a.l){a.c?t+="else {":a.m&&(t+="var l=k.length;j=-1;if(l&&P(k)){while(++j<l){B=k[j+=''];"+
|
||||
a.l.h+"}}else {"),a.g||(t+="var v=typeof k=='function'&&r.call(k,'prototype');");if(a.j&&a.q)t+="var o=-1,p=Z[typeof k]?m(k):[],l=p.length;"+a.l.d+";while(++o<l){j=p[o];",a.g||(t+="if(!(v&&j=='prototype')){"),t+="B=k[j];"+a.l.h+"",a.g||(t+="}");else{t+=a.l.d+";for(j in k){";if(!a.g||a.q)t+="if(",a.g||(t+="!(v&&j=='prototype')"),!a.g&&a.q&&(t+="&&"),a.q&&(t+="h.call(k,j)"),t+="){";t+="B=k[j];"+a.l.h+";";if(!a.g||a.q)t+="}"}t+="}";if(a.g){t+="var g=k.constructor;";for(n=0;7>n;n++)t+="j='"+a.o[n]+"';if("
|
||||
,"constructor"==a.o[n]&&(t+="!(g&&g.prototype===k)&&"),t+="h.call(k,j)){B=k[j];"+a.l.h+"}"}if(a.c||a.m)t+="}"}return t+=a.e+";return u",Function("E,F,G,J,e,f,K,h,i,N,P,R,T,U,Y,Z,m,r,w,x,z,A","var H=function("+e+"){"+t+"};return H")(_t,_,L,u,K,f,Zt,Q,A,x,v,Vt,m,$t,vt,Pt,ot,Y,Z,gt,et)}function c(e){return"\\"+Ht[e]}function h(e){return Kt[e]}function p(){}function d(e){return Qt[e]}function v(e){return et.call(e)==lt}function m(e){return"function"==typeof e}function g(e){var t=i;if(!e||"object"!=typeof
|
||||
e||v(e))return t;var n=e.constructor;return(!kt||"function"==typeof e.toString||"string"!=typeof (e+""))&&(!m(n)||n instanceof n)?St?(Zt(e,function(e,n,r){return t=!Q.call(r,n),i}),t===i):(Zt(e,function(e,n){t=n}),t===i||Q.call(e,t)):t}function y(e,t,s,o,u){if(e==r)return e;s&&(t=i);if(s=Pt[typeof e]){var a=et.call(e);if(!Dt[a]||Tt&&v(e))return e;var f=a==ct,s=f||(a==vt?$t(e):s)}if(!s||!t)return s?f?Z.call(e):Yt({},e):e;s=e.constructor;switch(a){case ht:return new s(e==n);case pt:return new s(+e)
|
||||
;case dt:case gt:return new s(e);case mt:return s(e.source,U.exec(e))}o||(o=[]),u||(u=[]);for(a=o.length;a--;)if(o[a]==e)return u[a];var l=f?s(a=e.length):{};o.push(e),u.push(l);if(f)for(f=-1;++f<a;)l[f]=y(e[f],t,r,o,u);else en(e,function(e,n){l[n]=y(e,t,r,o,u)});return l}function b(e,t,s,o){if(e==r||t==r)return e===t;if(e===t)return 0!==e||1/e==1/t;if(Pt[typeof e]||Pt[typeof t])e=e.__wrapped__||e,t=t.__wrapped__||t;var u=et.call(e);if(u!=et.call(t))return i;switch(u){case ht:case pt:return+e==+t
|
||||
;case dt:return e!=+e?t!=+t:0==e?1/e==1/t:e==+t;case mt:case gt:return e==t+""}var a=_t[u];if(Tt&&!a&&(a=v(e))&&!v(t)||!a&&(u!=vt||kt&&("function"!=typeof e.toString&&"string"==typeof (e+"")||"function"!=typeof t.toString&&"string"==typeof (t+""))))return i;s||(s=[]),o||(o=[]);for(u=s.length;u--;)if(s[u]==e)return o[u]==t;var u=-1,f=n,l=0;s.push(e),o.push(t);if(a){l=e.length;if(f=l==t.length)for(;l--&&(f=b(e[l],t[l],s,o)););return f}a=e.constructor,f=t.constructor;if(a!=f&&(!m(a)||!(a instanceof
|
||||
a&&m(f)&&f instanceof f)))return i;for(var c in e)if(Q.call(e,c)&&(l++,!Q.call(t,c)||!b(e[c],t[c],s,o)))return i;for(c in t)if(Q.call(t,c)&&!(l--))return i;if(wt)for(;7>++u;)if(c=J[u],Q.call(e,c)&&(!Q.call(t,c)||!b(e[c],t[c],s,o)))return i;return n}function w(e,t,n,r){var s=e,o=e.length,u=3>arguments.length;if(o!==+o)var a=rn(e),o=a.length;else Ct&&et.call(e)==gt&&(s=e.split(""));return vn(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 E(e,t,n){return t==r||n?e[0
|
||||
]:Z.call(e,0,t)}function S(e,t){for(var n,r=-1,i=e.length,s=[];++r<i;)n=e[r],Vt(n)?G.apply(s,t?n:S(n)):s.push(n);return s}function x(e,t,n){var r=-1,i=e.length;if(n){if("number"!=typeof n)return r=C(e,t),e[r]===t?r:-1;r=(0>n?ut(0,i+n):n)-1}for(;++r<i;)if(e[r]===t)return r;return-1}function T(e,t,n){for(var r=-Infinity,i=-1,s=e?e.length:0,o=r,t=f(t,n);++i<s;)n=t(e[i],i,e),n>r&&(r=n,o=e[i]);return o}function N(e,t,n){return Z.call(e,t==r||n?1:t)}function C(e,t,n,r){for(var i=0,s=e.length,n=f(n,r),t=
|
||||
n(t);i<s;)r=i+s>>>1,n(e[r])<t?i=r+1:s=r;return i}function k(e,t,n,r){var s=-1,o=e.length,u=[],a=[];"function"==typeof t&&(r=n,n=t,t=i);for(n=f(n,r);++s<o;)if(r=n(e[s],s,e),t?!s||a[a.length-1]!==r:0>x(a,r))a.push(r),u.push(e[s]);return u}function L(e,t){return At||tt&&2<arguments.length?tt.call.apply(tt,arguments):a(e,t,Z.call(arguments,2))}function A(e){return e}function O(e){vn(tn(e),function(t){var r=s[t]=e[t];s.prototype[t]=function(){var e=[this.__wrapped__];return arguments.length&&G.apply(e
|
||||
,arguments),e=r.apply(s,e),this.__chain__&&(e=new s(e),e.__chain__=n),e}})}var n=!0,r=null,i=!1,M="object"==typeof exports&&exports&&("object"==typeof global&&global&&global==global.global&&(e=global),exports),_=Array.prototype,D=Object.prototype,P=0,H=30,B=e._,j=/[-?+=!~*%&^<>|{(\/]|\[\D|\b(?:delete|in|instanceof|new|typeof|void)\b/,F=/&(?:amp|lt|gt|quot|#x27);/g,I=/\b__p\+='';/g,q=/\b(__p\+=)''\+/g,R=/(__e\(.*?\)|\b__t\))\+'';/g,U=/\w*$/,z=/(?:__e|__t=)\(\s*(?![\d\s"']|this\.)/g,W=RegExp("^"+(D
|
||||
.valueOf+"").replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),X=/($^)/,V=/[&<>"']/g,$=/['\n\r\t\u2028\u2029\\]/g,J="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),K=_.concat,Q=D.hasOwnProperty,G=_.push,Y=D.propertyIsEnumerable,Z=_.slice,et=D.toString,tt=W.test(tt=Z.bind)&&tt,nt=Math.floor,rt=W.test(rt=Object.getPrototypeOf)&&rt,it=W.test(it=Array.isArray)&&it,st=e.isFinite,ot=W.test(ot=Object.keys)&&ot,
|
||||
ut=Math.max,at=Math.min,ft=Math.random,lt="[object Arguments]",ct="[object Array]",ht="[object Boolean]",pt="[object Date]",dt="[object Number]",vt="[object Object]",mt="[object RegExp]",gt="[object String]",yt=e.clearTimeout,bt=e.setTimeout,wt,Et,St,xt=n;(function(){function e(){this.x=1}var t={0:1,length:1},n=[];e.prototype={valueOf:1,y:1};for(var r in new e)n.push(r);for(r in arguments)xt=!r;wt=4>(n+"").length,St="x"!=n[0],Et=(n.splice.call(t,0,1),t[0])})(1);var Tt=!v(arguments),Nt="x"!=Z.call("x"
|
||||
)[0],Ct="xx"!="x"[0]+Object("x")[0];try{var kt=("[object Object]",et.call(e.document||0)==vt)}catch(Lt){}var At=tt&&/\n|Opera/.test(tt+et.call(e.opera)),Ot=ot&&/^.+$|true/.test(ot+!!e.attachEvent),Mt=!At,_t={};_t[ht]=_t[pt]=_t["[object Function]"]=_t[dt]=_t[vt]=_t[mt]=i,_t[lt]=_t[ct]=_t[gt]=n;var Dt={};Dt[lt]=Dt["[object Function]"]=i,Dt[ct]=Dt[ht]=Dt[pt]=Dt[dt]=Dt[vt]=Dt[mt]=Dt[gt]=n;var Pt={"boolean":i,"function":n,object:n,number:i,string:i,"undefined":i,unknown:n},Ht={"\\":"\\","'":"'","\n":"n"
|
||||
,"\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"};s.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:""};var Bt={a:"d,c,y",i:"d",p:"c=f(c,y)",h:"if(c(B,j,d)===false)return u"},jt={i:"{}",p:"c=f(c,y)",h:"var q=c(B,j,d);(h.call(u,q)?u[q]++:u[q]=1)"},Ft={i:"true",h:"if(!c(B,j,d))return!u"},It={q:i,r:i,a:"n",i:"n",p:"for(var a=1,b=arguments.length;a<b;a++){if(k=arguments[a]){",h:"u[j]=B",e:"}}"},qt={i:"[]",h:"c(B,j,d)&&u.push(B)"},Rt={p
|
||||
:"c=f(c,y)"},Ut={h:{k:Bt.h}},zt={i:"",d:{b:"u=Array(l)",k:"u="+(Ot?"Array(l)":"[]")},h:{b:"u[j]=c(B,j,d)",k:"u"+(Ot?"[o]=":".push")+"(c(B,j,d))"}},Wt={q:i,a:"n,c,y",i:"{}",p:"var S=typeof c=='function';if(S)c=f(c,y);else var t=e.apply(F,arguments)",h:"if(S?!c(B,j,n):N(t,j)<0)u[j]=B"},Xt=l({a:"n",i:"{}",h:"u[B]=j"});Tt&&(v=function(e){return!!e&&!!Q.call(e,"callee")});var Vt=it||function(e){return et.call(e)==ct};m(/x/)&&(m=function(e){return"[object Function]"==et.call(e)});var $t=rt?function(e){
|
||||
if(!e||"object"!=typeof e)return i;var t=e.valueOf,n="function"==typeof t&&(n=rt(t))&&rt(n);return n?e==n||rt(e)==n&&!v(e):g(e)}:g,Jt=l({a:"n",i:"[]",p:"if(!(n&&Z[typeof n]))throw TypeError()",h:"u.push(j)"}),Kt={"&":"&","<":"<",">":">",'"':""","'":"'"},Qt=Xt(Kt),Gt=l(It,{h:"if(u[j]==null)"+It.h}),Yt=l(It),Zt=l(Bt,Rt,Ut,{q:i}),en=l(Bt,Rt,Ut),tn=l({q:i,a:"n",i:"[]",h:"if(T(B))u.push(j)",e:"u.sort()"}),nn=l({a:"B",i:"true",p:"if(!B)return u;var I=z.call(B),l=B.length;if(E[I]"+(Tt?"||P(B)"
|
||||
:"")+"||(I==Y&&l===+l&&T(B.splice)))return!l",h:{k:"return false"}}),rn=ot?function(e){return"function"==typeof e&&Y.call(e,"prototype")?Jt(e):ot(e)}:Jt,sn=l(It,{a:"n,ee,O",p:"var Q,D=arguments,a=0;if(O==J){var b=2,ff=D[3],gg=D[4]}else var b=D.length,ff=[],gg=[];while(++a<b){if(k=D[a]){",h:"if((ee=B)&&((Q=R(ee))||U(ee))){var L=false,hh=ff.length;while(hh--)if(L=ff[hh]==ee)break;if(L){u[j]=gg[hh]}else {ff.push(ee);gg.push(B=(B=u[j])&&Q?(R(B)?B:[]):(U(B)?B:{}));u[j]=H(B,ee,J,ff,gg)}}else if(ee!=null)u[j]=ee"
|
||||
}),on=l(Wt),un=l({a:"n",i:"[]",h:"u"+(Ot?"[o]=":".push")+"([j,B])"}),an=l(Wt,{p:"if(typeof c!='function'){var q,t=e.apply(F,arguments),l=t.length;for(j=1;j<l;j++){q=t[j];if(q in n)u[q]=n[q]}}else {c=f(c,y)",h:"if(c(B,j,n))u[j]=B",e:"}"}),fn=l({a:"n",i:"[]",h:"u.push(B)"}),ln=l({a:"d,ii",i:"false",n:i,d:{b:"if(z.call(d)==x)return d.indexOf(ii)>-1"},h:"if(B===ii)return true"}),cn=l(Bt,jt),hn=l(Bt,Ft),pn=l(Bt,qt),dn=l(Bt,Rt,{i:"",h:"if(c(B,j,d))return B"}),vn=l(Bt,Rt),mn=l(Bt,jt,{h:"var q=c(B,j,d);(h.call(u,q)?u[q]:u[q]=[]).push(B)"
|
||||
}),gn=l(zt,{a:"d,V",p:"var D=w.call(arguments,2),S=typeof V=='function'",h:{b:"u[j]=(S?V:B[V]).apply(B,D)",k:"u"+(Ot?"[o]=":".push")+"((S?V:B[V]).apply(B,D))"}}),yn=l(Bt,zt),bn=l(zt,{a:"d,cc",h:{b:"u[j]=B[cc]",k:"u"+(Ot?"[o]=":".push")+"(B[cc])"}}),wn=l({a:"d,c,C,y",i:"C",p:"var W=arguments.length<3;c=f(c,y)",d:{b:"if(W)u=k[++j]"},h:{b:"u=c(u,B,j,d)",k:"u=W?(W=false,B):c(u,B,j,d)"}}),En=l(Bt,qt,{h:"!"+qt.h}),Sn=l(Bt,Ft,{i:"false",h:Ft.h.replace("!","")}),xn=l(Bt,jt,zt,{h:{b:"u[j]={a:c(B,j,d),b:j,c:B}"
|
||||
,k:"u"+(Ot?"[o]=":".push")+"({a:c(B,j,d),b:j,c:B})"},e:"u.sort(J);l=u.length;while(l--)u[l]=u[l].c"}),Tn=l(qt,{a:"d,bb",p:"var t=[];K(bb,function(B,q){t.push(q)});var dd=t.length",h:"for(var q,aa=true,s=0;s<dd;s++){q=t[s];if(!(aa=B[q]===bb[q]))break}aa&&u.push(B)"}),Nn=l({q:i,r:i,a:"n",p:"var M=arguments,l=M.length;if(l>1){for(var j=1;j<l;j++)u[M[j]]=G(u[M[j]],u);return u}",h:"if(T(u[j]))u[j]=G(u[j],u)"});s.VERSION="0.8.0",s.after=function(e,t){return 1>e?t():function(){if(1>--e)return t.apply(this
|
||||
,arguments)}},s.bind=L,s.bindAll=Nn,s.chain=function(e){return e=new s(e),e.__chain__=n,e},s.clone=y,s.compact=function(e){for(var t=-1,n=e.length,r=[];++t<n;)e[t]&&r.push(e[t]);return r},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=ln,s.countBy=cn,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,yt(a),a=bt(i,t),r&&(o=e.apply
|
||||
(u,s)),o}},s.defaults=Gt,s.defer=function(e){var n=Z.call(arguments,1);return bt(function(){return e.apply(t,n)},1)},s.delay=function(e,n){var r=Z.call(arguments,2);return bt(function(){return e.apply(t,r)},n)},s.difference=function(e){for(var t=-1,n=e.length,r=K.apply(_,arguments),r=o(r,n),i=[];++t<n;)r(e[t])||i.push(e[t]);return i},s.escape=function(e){return e==r?"":(e+"").replace(V,h)},s.every=hn,s.extend=Yt,s.filter=pn,s.find=dn,s.first=E,s.flatten=S,s.forEach=vn,s.forIn=Zt,s.forOwn=en,s.functions=
|
||||
tn,s.groupBy=mn,s.has=function(e,t){return Q.call(e,t)},s.identity=A,s.indexOf=x,s.initial=function(e,t,n){return Z.call(e,0,-(t==r||n?1:t))},s.intersection=function(e){var t,n=arguments.length,r=[],i=-1,s=e.length,u=[];e:for(;++i<s;)if(t=e[i],0>x(u,t)){for(var a=1;a<n;a++)if(!(r[a]||(r[a]=o(arguments[a])))(t))continue e;u.push(t)}return u},s.invert=Xt,s.invoke=gn,s.isArguments=v,s.isArray=Vt,s.isBoolean=function(e){return e===n||e===i||et.call(e)==ht},s.isDate=function(e){return et.call(e)==pt},
|
||||
s.isElement=function(e){return e?1===e.nodeType:i},s.isEmpty=nn,s.isEqual=b,s.isFinite=function(e){return st(e)&&et.call(e)==dt},s.isFunction=m,s.isNaN=function(e){return et.call(e)==dt&&e!=+e},s.isNull=function(e){return e===r},s.isNumber=function(e){return et.call(e)==dt},s.isObject=function(e){return e?Pt[typeof e]:i},s.isPlainObject=$t,s.isRegExp=function(e){return et.call(e)==mt},s.isString=function(e){return et.call(e)==gt},s.isUndefined=function(e){return e===t},s.keys=rn,s.last=function(e
|
||||
,t,n){var i=e.length;return t==r||n?e[i-1]:Z.call(e,-t||i)},s.lastIndexOf=function(e,t,n){var r=e.length;for(n&&"number"==typeof n&&(r=(0>n?ut(0,r+n):at(n,r-1))+1);r--;)if(e[r]===t)return r;return-1},s.lateBind=function(e,t){return a(t,e,Z.call(arguments,2))},s.map=yn,s.max=T,s.memoize=function(e,t){var n={};return function(){var r=t?t.apply(this,arguments):arguments[0];return Q.call(n,r)?n[r]:n[r]=e.apply(this,arguments)}},s.merge=sn,s.min=function(e,t,n){for(var r=Infinity,i=-1,s=e?e.length:0,o=
|
||||
r,t=f(t,n);++i<s;)n=t(e[i],i,e),n<r&&(r=n,o=e[i]);return o},s.mixin=O,s.noConflict=function(){return e._=B,this},s.object=function(e,t){for(var n=-1,r=e.length,i={};++n<r;)t?i[e[n]]=t[n]:i[e[n][0]]=e[n][1];return i},s.omit=on,s.once=function(e){var t,s=i;return function(){return s?t:(s=n,t=e.apply(this,arguments),e=r,t)}},s.pairs=un,s.partial=function(e){return a(e,Z.call(arguments,1))},s.pick=an,s.pluck=bn,s.random=function(e,t){return e==r&&t==r&&(t=1),e=+e||0,t==r&&(t=e,e=0),e+nt(ft()*((+t||0)-
|
||||
e+1))},s.range=function(e,t,n){e=+e||0,n=+n||1,t==r&&(t=e,e=0);for(var i=-1,t=ut(0,Math.ceil((t-e)/n)),s=Array(t);++i<t;)s[i]=e,e+=n;return s},s.reduce=wn,s.reduceRight=w,s.reject=En,s.rest=N,s.result=function(e,t){var n=e?e[t]:r;return m(n)?e[t]():n},s.shuffle=function(e){for(var t,n=-1,r=e.length,i=Array(r);++n<r;)t=nt(ft()*(n+1)),i[n]=i[t],i[t]=e[n];return i},s.size=function(e){var t=e?e.length:0;return t===+t?t:rn(e).length},s.some=Sn,s.sortBy=xn,s.sortedIndex=C,s.tap=function(e,t){return t(e
|
||||
),e},s.template=function(e,t,n){n||(n={});var r,i,o=0,u=s.templateSettings,a="__p += '",f=n.variable||u.variable,l=f;e.replace(RegExp((n.escape||u.escape||X).source+"|"+(n.interpolate||u.interpolate||X).source+"|"+(n.evaluate||u.evaluate||X).source+"|$","g"),function(t,n,i,s,u){a+=e.slice(o,u).replace($,c),a+=n?"'+__e("+n+")+'":s?"';"+s+";__p+='":i?"'+((__t=("+i+"))==null?'':__t)+'":"",r||(r=s||j.test(n||i)),o=u+t.length}),a+="';",l||(f="obj",r?a="with("+f+"){"+a+"}":(n=RegExp("(\\(\\s*)"+f+"\\."+
|
||||
f+"\\b","g"),a=a.replace(z,"$&"+f+".").replace(n,"$1__d"))),a=(r?a.replace(I,""):a).replace(q,"$1").replace(R,"$1;"),a="function("+f+"){"+(l?"":f+"||("+f+"={});")+"var __t,__p='',__e=_.escape"+(r?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":(l?"":",__d="+f+"."+f+"||"+f)+";")+a+"return __p}";try{i=Function("_","return "+a)(s)}catch(h){throw h.source=a,h}return t?i(t):(i.source=a,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 r=new Date,f=t-(r-a);return i=arguments,o=this,0>=f?(a=r,s=e.apply(o,i)):u||(u=bt(n,f)),s}},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){var t=e?e.length:0;return t===+t?(Nt?et.call(e)==gt:"string"==typeof e)?e.split(""):Z.call(e):fn(e)},s.unescape=function(e){return e==r?"":(e+"").replace(F,d)},s.union=function(){for(var e=-1,t=K.apply(_,arguments),n=t.length,r=[];++e<n;)0>x(r,t[e])&&r.push(t[e]);return r},s.uniq=k,s.uniqueId=
|
||||
function(e){var t=P++;return e?e+t:t},s.values=fn,s.where=Tn,s.without=function(e){for(var t=-1,n=e.length,r=o(arguments,1,20),i=[];++t<n;)r(e[t])||i.push(e[t]);return i},s.wrap=function(e,t){return function(){var n=[e];return arguments.length&&G.apply(n,arguments),t.apply(this,n)}},s.zip=function(e){for(var t=-1,n=T(bn(arguments,"length")),r=Array(n);++t<n;)r[t]=bn(arguments,t);return r},s.all=hn,s.any=Sn,s.collect=yn,s.detect=dn,s.drop=N,s.each=vn,s.foldl=wn,s.foldr=w,s.head=E,s.include=ln,s.inject=
|
||||
wn,s.methods=tn,s.select=pn,s.tail=N,s.take=E,s.unique=k,O(s),s.prototype.chain=function(){return this.__chain__=n,this},s.prototype.value=function(){return this.__wrapped__},vn("pop push reverse shift sort splice unshift".split(" "),function(e){var t=_[e];s.prototype[e]=function(){var e=this.__wrapped__;return t.apply(e,arguments),Et&&e.length===0&&delete e[0],this.__chain__&&(e=new s(e),e.__chain__=n),e}}),vn(["concat","join","slice"],function(e){var t=_[e];s.prototype[e]=function(){var e=t.apply
|
||||
(this.__wrapped__,arguments);return this.__chain__&&(e=new s(e),e.__chain__=n),e}}),typeof define=="function"&&typeof define.amd=="object"&&define.amd?(e._=s,define(function(){return s})):M?"object"==typeof module&&module&&module.exports==M?(module.exports=s)._=s:M._=s:e._=s})(this);
|
||||
35
lodash.underscore.min.js
vendored
35
lodash.underscore.min.js
vendored
@@ -1,35 +0,0 @@
|
||||
/*!
|
||||
Lo-Dash 0.8.0 lodash.com/license
|
||||
Underscore.js 1.4.0 underscorejs.org/LICENSE
|
||||
*/
|
||||
;(function(e,t){function s(e,t,r){var s,t=T(t,r),o=e.length,r=-1;if(o===+o){for(;++r<o;)if(s=e[r],t(s,r,e))return n}else for(r in e)if(st.call(e,r)&&(s=e[r],t(s,r,e)))return n;return i}function o(e,t,n,r){var s,o,u=n,a=3>arguments.length,t=T(t,r),f=e.length;s=-1;if(f===+f)for(a&&(u=e[++s]);++s<f;)o=e[s],u=t(u,o,s,e);else for(s in e)st.call(e,s)&&(o=e[s],u=a?(a=i,o):t(u,o,s,e));return u}function u(e,t){var n,r,i,s=e.length;n=-1;if(s===+s)for(i=Array(s);++n<s;)r=e[n],i[n]=r[t];else for(n in i=[],e)st
|
||||
.call(e,n)&&(r=e[n],i.push(r[t]));return i}function a(e,t,n){var r,i,t=T(t,n),s=e.length,n=-1;if(s===+s)for(i=Array(s);++n<s;)r=e[n],i[n]=t(r,n,e);else for(n in i=[],e)st.call(e,n)&&(r=e[n],i.push(t(r,n,e)));return i}function f(e,t,n){var r,t=T(t,n),i=e.length,n=-1;if(i===+i)for(;++n<i;)r=e[n],t(r,n,e);else for(n in e)st.call(e,n)&&(r=e[n],t(r,n,e));return e}function l(e,t,n){var r,t=T(t,n),i=e.length,n=-1;if(i===+i){for(;++n<i;)if(r=e[n],t(r,n,e))return r}else for(n in e)if(st.call(e,n)&&(r=e[n]
|
||||
,t(r,n,e)))return r}function c(e,t,n){var r,i=[],t=T(t,n),s=e.length,n=-1;if(s===+s)for(;++n<s;)r=e[n],t(r,n,e)&&i.push(r);else for(n in e)st.call(e,n)&&(r=e[n],t(r,n,e)&&i.push(r));return i}function h(e,t,r){var s,t=T(t,r),o=e.length,r=-1;if(o===+o){for(;++r<o;)if(s=e[r],!t(s,r,e))return i}else for(r in e)if(st.call(e,r)&&(s=e[r],!t(s,r,e)))return i;return n}function p(e,t){var r,s,o=e.length;r=-1;if(o===+o){if(ft.call(e)==Tt)return-1<e.indexOf(t);for(;++r<o;)if(s=e[r],s===t)return n}else for(r in
|
||||
e)if(st.call(e,r)&&(s=e[r],s===t))return n;return i}function d(e){var t,n,r=[];for(t in e)st.call(e,t)&&(n=e[t],r.push(n));return r}function v(e){var t,n,r=[];for(t in e)n=e[t],A(n)&&r.push(t);return r.sort(),r}function m(e,t,n){var r,t=T(t,n);for(r in e)n=e[r],t(n,r,e);return e}function g(e){for(var t,n,r=e,i=1,s=arguments.length;i<s;i++)if(r=arguments[i])for(t in r)n=r[t],e[t]=n;return e}function y(e){var t,n=[];if(!e||!Lt[typeof e])throw TypeError();for(t in e)st.call(e,t)&&n.push(t);return n}
|
||||
function b(e){var t,n,r={};for(t in e)st.call(e,t)&&(n=e[t],r[n]=t);return r}function w(e){if(e&&e.__wrapped__)return e;if(!(this instanceof w))return new w(e);this.__wrapped__=e}function E(e,t){return function(n){return-1<H(e,n,t||0)}}function S(e,n){var r=e.b,i=n.b,e=e.a,n=n.a;if(e!==n){if(e>n||e===t)return 1;if(e<n||n===t)return-1}return r<i?-1:1}function x(e,t,n){function r(){var i=arguments,s=t;return n.length&&(i=i.length?n.concat(at.call(i)):n),this instanceof r?(k.prototype=e.prototype,s=new
|
||||
k,(i=e.apply(s,i))&&Lt[typeof i]?i:s):e.apply(s,i)}return r}function T(e,n){return e?"function"!=typeof e?function(t){return t[e]}:n!==t?function(t,r,i){return e.call(n,t,r,i)}:e:R}function N(e){return"\\"+At[e]}function C(e){return Mt[e]}function k(){}function L(e){return _t[e]}function A(e){return"function"==typeof e}function O(e){var t=i;if(!e||"object"!=typeof e||isArguments(e))return t;var n=e.constructor;return!A(n)||n instanceof n?(m(e,function(e,n){t=n}),t===i||st.call(e,t)):t}function M(
|
||||
e,t,s,o){if(e==r||t==r)return e===t;if(e===t)return 0!==e||1/e==1/t;if(Lt[typeof e]||Lt[typeof t])e=e.__wrapped__||e,t=t.__wrapped__||t;var u=ft.call(e);if(u!=ft.call(t))return i;switch(u){case bt:case wt:return+e==+t;case Et:return e!=+e?t!=+t:0==e?1/e==1/t:e==+t;case xt:case Tt:return e==t+""}var a=Ot(e);if(!a&&u!=St)return i;s||(s=[]),o||(o=[]);for(u=s.length;u--;)if(s[u]==e)return o[u]==t;var f=n,u=0;s.push(e),o.push(t);if(a){u=e.length;if(f=u==t.length)for(;u--&&(f=M(e[u],t[u],s,o)););return f
|
||||
}a=e.constructor,f=t.constructor;if(a!=f&&(!A(a)||!(a instanceof a&&A(f)&&f instanceof f)))return i;for(var l in e)if(st.call(e,l)&&(u++,!st.call(t,l)||!M(e[l],t[l],s,o)))return i;for(l in t)if(st.call(t,l)&&!(u--))return i;return n}function _(e,t,n,r){var s=e.length,o=3>arguments.length;if(s!==+s)var u=Dt(e),s=u.length;return f(e,function(a,f,l){f=u?u[--s]:--s,n=o?(o=i,e[f]):t.call(r,n,e[f],f,l)}),n}function D(e,t,n){return t==r||n?e[0]:at.call(e,0,t)}function P(e,t){for(var n,r=-1,i=e.length,s=
|
||||
[];++r<i;)n=e[r],Ot(n)?ot.apply(s,t?n:P(n)):s.push(n);return s}function H(e,t,n){var r=-1,i=e.length;if(n){if("number"!=typeof n)return r=F(e,t),e[r]===t?r:-1;r=(0>n?mt(0,i+n):n)-1}for(;++r<i;)if(e[r]===t)return r;return-1}function B(e,t,n){for(var r=-Infinity,i=-1,s=e?e.length:0,o=r,t=T(t,n);++i<s;)n=t(e[i],i,e),n>r&&(r=n,o=e[i]);return o}function j(e,t,n){return at.call(e,t==r||n?1:t)}function F(e,t,n,r){for(var i=0,s=e.length,n=T(n,r),t=n(t);i<s;)r=i+s>>>1,n(e[r])<t?i=r+1:s=r;return i}function I
|
||||
(e,t,n,r){var s=-1,o=e.length,u=[],a=[];"function"==typeof t&&(r=n,n=t,t=i);for(n=T(n,r);++s<o;)if(r=n(e[s],s,e),t?!s||a[a.length-1]!==r:0>H(a,r))a.push(r),u.push(e[s]);return u}function q(e,t){return kt||lt&&2<arguments.length?lt.call.apply(lt,arguments):x(e,t,at.call(arguments,2))}function R(e){return e}function U(e){f(v(e),function(t){var r=w[t]=e[t];w.prototype[t]=function(){var e=[this.__wrapped__];return arguments.length&&ot.apply(e,arguments),e=r.apply(w,e),this.__chain__&&(e=new w(e),e.__chain__=
|
||||
n),e}})}var n=!0,r=null,i=!1,z="object"==typeof exports&&exports&&("object"==typeof global&&global&&global==global.global&&(e=global),exports),W=Array.prototype,X=Object.prototype,V=0,$=e._,J=/[-?+=!~*%&^<>|{(\/]|\[\D|\b(?:delete|in|instanceof|new|typeof|void)\b/,K=/&(?:amp|lt|gt|quot|#x27);/g,Q=/\b__p\+='';/g,G=/\b(__p\+=)''\+/g,Y=/(__e\(.*?\)|\b__t\))\+'';/g,Z=/(?:__e|__t=)\(\s*(?![\d\s"']|this\.)/g,et=RegExp("^"+(X.valueOf+"").replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g
|
||||
,".+?")+"$"),tt=/($^)/,nt=/[&<>"']/g,rt=/['\n\r\t\u2028\u2029\\]/g,it=W.concat,st=X.hasOwnProperty,ot=W.push,ut=X.propertyIsEnumerable,at=W.slice,ft=X.toString,lt=et.test(lt=at.bind)&<,ct=Math.floor,ht=et.test(ht=Object.getPrototypeOf)&&ht,pt=et.test(pt=Array.isArray)&&pt,dt=e.isFinite,vt=et.test(vt=Object.keys)&&vt,mt=Math.max,gt=Math.min,yt=Math.random,bt="[object Boolean]",wt="[object Date]",Et="[object Number]",St="[object Object]",xt="[object RegExp]",Tt="[object String]",Nt=e.clearTimeout
|
||||
,Ct=e.setTimeout,kt=lt&&/\n|Opera/.test(lt+ft.call(e.opera)),Lt={"boolean":i,"function":n,object:n,number:i,string:i,"undefined":i,unknown:n},At={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"};w.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:""},w.isArguments=function(e){return"[object Arguments]"==ft.call(e)},w.isArguments(arguments)||(w.isArguments=function(e){return!!e&&!!st.call(e,"callee")});var Ot=
|
||||
pt||function(e){return"[object Array]"==ft.call(e)};A(/x/)&&(A=function(e){return"[object Function]"==ft.call(e)});var X=ht?function(e){if(!e||"object"!=typeof e)return i;var t=e.valueOf,n="function"==typeof t&&(n=ht(t))&&ht(n);return n?e==n||ht(e)==n&&!isArguments(e):O(e)}:O,Mt={"&":"&","<":"<",">":">",'"':""","'":"'"},_t=b(Mt),Dt=vt?function(e){return"function"==typeof e&&ut.call(e,"prototype")?y(e):vt(e)}:y;w.VERSION="0.8.0",w.after=function(e,t){return 1>e?t():function(){if(1>--
|
||||
e)return t.apply(this,arguments)}},w.bind=q,w.bindAll=function(e){var t,n=e,r=e,i=arguments,s=i.length;if(1<s){for(t=1;t<s;t++)r[i[t]]=q(r[i[t]],r);return r}for(t in n)A(r[t])&&(r[t]=q(r[t],r));return r},w.chain=function(e){return e=new w(e),e.__chain__=n,e},w.clone=function(e){return e&&Lt[typeof e]?Ot(e)?at.call(e):g({},e):e},w.compact=function(e){for(var t=-1,n=e.length,r=[];++t<n;)e[t]&&r.push(e[t]);return r},w.compose=function(){var e=arguments;return function(){for(var t=arguments,n=e.length
|
||||
;n--;)t=[e[n].apply(this,t)];return t[0]}},w.contains=p,w.countBy=function(e,t,n){var r,i={},t=T(t,n),s=e.length,n=-1;if(s===+s)for(;++n<s;)r=e[n],r=t(r,n,e),st.call(i,r)?i[r]++:i[r]=1;else for(n in e)st.call(e,n)&&(r=e[n],r=t(r,n,e),st.call(i,r)?i[r]++:i[r]=1);return i},w.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,Nt(a),a=Ct(i,t),r&&(o=e.apply(u,s)),o}},w.defaults=function(e){for(var t,n,i=e,s=1,o=arguments.length
|
||||
;s<o;s++)if(i=arguments[s])for(t in i)n=i[t],e[t]==r&&(e[t]=n);return e},w.defer=function(e){var n=at.call(arguments,1);return Ct(function(){return e.apply(t,n)},1)},w.delay=function(e,n){var r=at.call(arguments,2);return Ct(function(){return e.apply(t,r)},n)},w.difference=function(e){for(var t=-1,n=e.length,r=it.apply(W,arguments),r=E(r,n),i=[];++t<n;)r(e[t])||i.push(e[t]);return i},w.escape=function(e){return e==r?"":(e+"").replace(nt,C)},w.every=h,w.extend=g,w.filter=c,w.find=l,w.first=D,w.flatten=
|
||||
P,w.forEach=f,w.forIn=m,w.forOwn=function(e,t,n){var r,t=T(t,n);for(r in e)st.call(e,r)&&(n=e[r],t(n,r,e));return e},w.functions=v,w.groupBy=function(e,t,n){var r,i={},t=T(t,n),s=e.length,n=-1;if(s===+s)for(;++n<s;){r=e[n];var o=t(r,n,e);(st.call(i,o)?i[o]:i[o]=[]).push(r)}else for(n in e)st.call(e,n)&&(r=e[n],o=t(r,n,e),(st.call(i,o)?i[o]:i[o]=[]).push(r));return i},w.has=function(e,t){return st.call(e,t)},w.identity=R,w.indexOf=H,w.initial=function(e,t,n){return at.call(e,0,-(t==r||n?1:t))},w.intersection=
|
||||
function(e){var t,n=arguments.length,r=[],i=-1,s=e.length,o=[];e:for(;++i<s;)if(t=e[i],0>H(o,t)){for(var u=1;u<n;u++)if(!(r[u]||(r[u]=E(arguments[u])))(t))continue e;o.push(t)}return o},w.invert=b,w.invoke=function(e,t){var n,r,i=e,s,o=at.call(arguments,2),u="function"==typeof t,a=i.length;n=-1;if(a===+a)for(s=Array(a);++n<a;)r=i[n],s[n]=(u?t:r[t]).apply(r,o);else for(n in s=[],i)st.call(i,n)&&(r=i[n],s.push((u?t:r[t]).apply(r,o)));return s},w.isArray=Ot,w.isBoolean=function(e){return e===n||e===
|
||||
i||ft.call(e)==bt},w.isDate=function(e){return ft.call(e)==wt},w.isElement=function(e){return e?1===e.nodeType:i},w.isEmpty=function(e){var t;if(!e)return n;var r=ft.call(e),s=e.length;if(Ot(e)||r==Tt||r==St&&s===+s&&A(e.splice))return!s;for(t in e)if(st.call(e,t))return i;return n},w.isEqual=M,w.isFinite=function(e){return dt(e)&&ft.call(e)==Et},w.isFunction=A,w.isNaN=function(e){return ft.call(e)==Et&&e!=+e},w.isNull=function(e){return e===r},w.isNumber=function(e){return ft.call(e)==Et},w.isObject=
|
||||
function(e){return e?Lt[typeof e]:i},w.isPlainObject=X,w.isRegExp=function(e){return ft.call(e)==xt},w.isString=function(e){return ft.call(e)==Tt},w.isUndefined=function(e){return e===t},w.keys=Dt,w.last=function(e,t,n){var i=e.length;return t==r||n?e[i-1]:at.call(e,-t||i)},w.lastIndexOf=function(e,t,n){var r=e.length;for(n&&"number"==typeof n&&(r=(0>n?mt(0,r+n):gt(n,r-1))+1);r--;)if(e[r]===t)return r;return-1},w.map=a,w.max=B,w.memoize=function(e,t){var n={};return function(){var r=t?t.apply(this
|
||||
,arguments):arguments[0];return st.call(n,r)?n[r]:n[r]=e.apply(this,arguments)}},w.min=function(e,t,n){for(var r=Infinity,i=-1,s=e?e.length:0,o=r,t=T(t,n);++i<s;)n=t(e[i],i,e),n<r&&(r=n,o=e[i]);return o},w.mixin=U,w.noConflict=function(){return e._=$,this},w.object=function(e,t){for(var n=-1,r=e.length,i={};++n<r;)t?i[e[n]]=t[n]:i[e[n][0]]=e[n][1];return i},w.omit=function(e,t,n){var r,i,s=e,o={},u="function"==typeof t;if(u)t=T(t,n);else var a=it.apply(W,arguments);for(r in s)if(i=s[r],u?!t(i,r,e
|
||||
):0>H(a,r))o[r]=i;return o},w.once=function(e){var t,s=i;return function(){return s?t:(s=n,t=e.apply(this,arguments),e=r,t)}},w.pairs=function(e){var t,n,r=[];for(t in e)st.call(e,t)&&(n=e[t],r.push([t,n]));return r},w.pick=function(e,t,n){var r,i,s=e,o={};if("function"!=typeof t){var s=it.apply(W,arguments),u=s.length;for(r=1;r<u;r++)i=s[r],i in e&&(o[i]=e[i])}else for(r in t=T(t,n),s)i=s[r],t(i,r,e)&&(o[r]=i);return o},w.pluck=u,w.random=function(e,t){return e==r&&t==r&&(t=1),e=+e||0,t==r&&(t=e
|
||||
,e=0),e+ct(yt()*((+t||0)-e+1))},w.range=function(e,t,n){e=+e||0,n=+n||1,t==r&&(t=e,e=0);for(var i=-1,t=mt(0,Math.ceil((t-e)/n)),s=Array(t);++i<t;)s[i]=e,e+=n;return s},w.reduce=o,w.reduceRight=_,w.reject=function(e,t,n){var r,i=[],t=T(t,n),s=e.length,n=-1;if(s===+s)for(;++n<s;)r=e[n],!t(r,n,e)&&i.push(r);else for(n in e)st.call(e,n)&&(r=e[n],!t(r,n,e)&&i.push(r));return i},w.rest=j,w.result=function(e,t){var n=e?e[t]:r;return A(n)?e[t]():n},w.shuffle=function(e){for(var t,n=-1,r=e.length,i=Array(
|
||||
r);++n<r;)t=ct(yt()*(n+1)),i[n]=i[t],i[t]=e[n];return i},w.size=function(e){var t=e?e.length:0;return t===+t?t:Dt(e).length},w.some=s,w.sortBy=function(e,t,n){var r,i,t=T(t,n),s=e.length,n=-1;if(s===+s)for(i=Array(s);++n<s;)r=e[n],i[n]={a:t(r,n,e),b:n,c:r};else for(n in i=[],e)st.call(e,n)&&(r=e[n],i.push({a:t(r,n,e),b:n,c:r}));i.sort(S);for(s=i.length;s--;)i[s]=i[s].c;return i},w.sortedIndex=F,w.tap=function(e,t){return t(e),e},w.template=function(e,t,n){n||(n={});var r,i,s=0,o=w.templateSettings
|
||||
,u="__p += '",a=n.variable||o.variable,f=a;e.replace(RegExp((n.escape||o.escape||tt).source+"|"+(n.interpolate||o.interpolate||tt).source+"|"+(n.evaluate||o.evaluate||tt).source+"|$","g"),function(t,n,i,o,a){u+=e.slice(s,a).replace(rt,N),u+=n?"'+__e("+n+")+'":o?"';"+o+";__p+='":i?"'+((__t=("+i+"))==null?'':__t)+'":"",r||(r=o||J.test(n||i)),s=a+t.length}),u+="';",f||(a="obj",r?u="with("+a+"){"+u+"}":(n=RegExp("(\\(\\s*)"+a+"\\."+a+"\\b","g"),u=u.replace(Z,"$&"+a+".").replace(n,"$1__d"))),u=(r?u.replace
|
||||
(Q,""):u).replace(G,"$1").replace(Y,"$1;"),u="function("+a+"){"+(f?"":a+"||("+a+"={});")+"var __t,__p='',__e=_.escape"+(r?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":(f?"":",__d="+a+"."+a+"||"+a)+";")+u+"return __p}";try{i=Function("_","return "+u)(w)}catch(l){throw l.source=u,l}return t?i(t):(i.source=u,i)},w.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 r=new Date,f=t-(r-a);return i=arguments,o=this,0>=f?(a=
|
||||
r,s=e.apply(o,i)):u||(u=Ct(n,f)),s}},w.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},w.toArray=function(e){var t=e?e.length:0;return t===+t?"string"==typeof e?e.split(""):at.call(e):d(e)},w.unescape=function(e){return e==r?"":(e+"").replace(K,L)},w.union=function(){for(var e=-1,t=it.apply(W,arguments),n=t.length,r=[];++e<n;)0>H(r,t[e])&&r.push(t[e]);return r},w.uniq=I,w.uniqueId=function(e){var t=V++;return e?e+t:t},w.values=d,w.where=function(e,t){var r,
|
||||
i,s=[],o=[];m(t,function(e,t){o.push(t)});var u=o.length,a=e.length;r=-1;if(a===+a)for(;++r<a;){i=e[r];var f;f=n;for(var l=0;l<u&&(f=o[l],f=i[f]===t[f]);l++);f&&s.push(i)}else for(r in e)if(st.call(e,r)){i=e[r],f=n;for(l=0;l<u&&(f=o[l],f=i[f]===t[f]);l++);f&&s.push(i)}return s},w.without=function(e){for(var t=-1,n=e.length,r=E(arguments,1),i=[];++t<n;)r(e[t])||i.push(e[t]);return i},w.wrap=function(e,t){return function(){var n=[e];return arguments.length&&ot.apply(n,arguments),t.apply(this,n)}},w
|
||||
.zip=function(e){for(var t=-1,n=B(u(arguments,"length")),r=Array(n);++t<n;)r[t]=u(arguments,t);return r},w.all=h,w.any=s,w.collect=a,w.detect=l,w.drop=j,w.each=f,w.foldl=o,w.foldr=_,w.head=D,w.include=p,w.inject=o,w.methods=v,w.select=c,w.tail=j,w.take=D,w.unique=I,U(w),w.prototype.chain=function(){return this.__chain__=n,this},w.prototype.value=function(){return this.__wrapped__},f("pop push reverse shift sort splice unshift".split(" "),function(e){var t=W[e];w.prototype[e]=function(){var e=this
|
||||
.__wrapped__;return t.apply(e,arguments),this.__chain__&&(e=new w(e),e.__chain__=n),e}}),f(["concat","join","slice"],function(e){var t=W[e];w.prototype[e]=function(){var e=t.apply(this.__wrapped__,arguments);return this.__chain__&&(e=new w(e),e.__chain__=n),e}}),z?"object"==typeof module&&module&&module.exports==z?(module.exports=w)._=w:z._=w:e._=w})(this);
|
||||
10
package.json
10
package.json
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"name": "lodash",
|
||||
"version": "0.8.0",
|
||||
"description": "A drop-in replacement for Underscore.js delivering performance, bug fixes, and additional features.",
|
||||
"version": "1.1.0",
|
||||
"description": "A low-level utility library delivering consistency, customization, performance, and extra features.",
|
||||
"homepage": "http://lodash.com",
|
||||
"main": "./lodash",
|
||||
"main": "./dist/lodash",
|
||||
"keywords": [
|
||||
"browser",
|
||||
"client",
|
||||
@@ -46,7 +46,7 @@
|
||||
"main": "./lodash.js"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "node build",
|
||||
"test": "node test/test && node test/test-build"
|
||||
"build": "node ./build.js",
|
||||
"test": "node ./test/test.js ./dist/lodash.js && node ./test/test.js ./dist/lodash.min.js && node ./test/test-build.js"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,17 +13,35 @@
|
||||
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.min.js"></script>
|
||||
<div id="perf-toolbar"></div>
|
||||
<script src="../vendor/platform.js/platform.js"></script>
|
||||
<script src="../lodash.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-min.js"></script>
|
||||
<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>
|
||||
document.write('<script src="../' + ui.otherPath + '"><\/script>');
|
||||
</script>
|
||||
<script src="perf.js"></script>
|
||||
<script>
|
||||
(function() {
|
||||
@@ -39,7 +57,12 @@
|
||||
if (!fbCommandLine) {
|
||||
return setTimeout(init, 15);
|
||||
}
|
||||
fbUI.style.height = fbDoc.body.style.height = fbDoc.documentElement.style.height = '100%';
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
136
perf/perf-ui.js
Normal file
136
perf/perf-ui.js
Normal file
@@ -0,0 +1,136 @@
|
||||
;(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 'dist/lodash.compat.js';
|
||||
case 'lodash-modern': return 'dist/lodash.min.js';
|
||||
case 'lodash-underscore': return 'dist/lodash.underscore.min.js';
|
||||
case 'lodash-custom': return 'lodash.custom.min.js';
|
||||
}
|
||||
return 'dist/lodash.compat.min.js';
|
||||
}());
|
||||
|
||||
// expose other library file path
|
||||
ui.otherPath = (function() {
|
||||
switch (other) {
|
||||
case 'lodash-dev': return 'dist/lodash.compat.js';
|
||||
case 'lodash-prod': return 'dist/lodash.compat.min.js';
|
||||
case 'lodash-modern': return 'dist/lodash.min.js';
|
||||
case 'lodash-underscore': return 'dist/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-modern">Lo-Dash (modern)</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-modern">Lo-Dash (modern)</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-modern': return 2;
|
||||
case 'lodash-underscore': return 3;
|
||||
case 'lodash-custom': return 4;
|
||||
}
|
||||
return 1;
|
||||
}());
|
||||
|
||||
otherList.selectedIndex = (function() {
|
||||
switch (other) {
|
||||
case 'underscore-dev': return 0;
|
||||
case 'lodash-dev': return 2;
|
||||
case 'lodash-prod': return 3;
|
||||
case 'lodash-modern': return 4;
|
||||
case 'lodash-underscore': return 5;
|
||||
case 'lodash-custom': return 6;
|
||||
}
|
||||
return 1;
|
||||
}());
|
||||
|
||||
addListener(buildList, 'change', eventHandler);
|
||||
addListener(otherList, 'change', eventHandler);
|
||||
});
|
||||
|
||||
// expose `ui`
|
||||
window.ui = ui;
|
||||
|
||||
}(this));
|
||||
1133
perf/perf.js
1133
perf/perf.js
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,14 @@
|
||||
cd "$(dirname "$0")"
|
||||
for cmd in node narwhal ringo rhino; do
|
||||
echo ""
|
||||
echo "Running performance suite in $cmd..."
|
||||
$cmd perf.js
|
||||
|
||||
echo "Running performance suite in node..."
|
||||
node perf.js ../dist/lodash.js && node perf.js ../dist/lodash.min.js
|
||||
|
||||
for cmd in rhino "rhino -require" narwhal ringo phantomjs; do
|
||||
echo ""
|
||||
echo "Running performance suite in $cmd..."
|
||||
$cmd perf.js ../dist/lodash.compat.js && $cmd perf.js ../dist/lodash.compat.min.js
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "Running performance suite in a browser..."
|
||||
open index.html
|
||||
open index.html
|
||||
|
||||
@@ -3,38 +3,43 @@
|
||||
<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>
|
||||
<div id="qunit"></div>
|
||||
<h1 id="qunit-header"><a href="#">Backbone Speed Suite</a></h1>
|
||||
<h1 id="qunit-header"></h1>
|
||||
<div id="qunit-fixture">
|
||||
<div id='testElement'>
|
||||
<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/jslitmus.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="../vendor/qunit/qunit/qunit.js"></script>
|
||||
<script src="test-ui.js"></script>
|
||||
<script src="../lodash.js"></script>
|
||||
<script>
|
||||
document.write('<script src="../' + QUnit.config.lodashFilename + '.js"><\/script>');
|
||||
var lodash = _.noConflict();
|
||||
document.write('<script src="../' + ui.buildPath + '"><\/script>');
|
||||
</script>
|
||||
<script>
|
||||
_.mixin({
|
||||
'debounce': lodash.debounce,
|
||||
'defer': lodash.defer
|
||||
});
|
||||
if (!_.chain) {
|
||||
_.mixin({
|
||||
'chain': function(value) {
|
||||
return new _(value);
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<script src="../vendor/backbone/backbone.js"></script>
|
||||
<script src="../vendor/backbone/test/environment.js"></script>
|
||||
|
||||
@@ -4,25 +4,25 @@
|
||||
<meta charset="utf-8">
|
||||
<title>Lo-Dash Test Suite</title>
|
||||
<link rel="stylesheet" href="../vendor/qunit/qunit/qunit.css">
|
||||
<style>
|
||||
#exports {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="qunit"></div>
|
||||
<script src="../vendor/qunit/qunit/qunit.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>
|
||||
<div id="qunit"></div>
|
||||
<div id="exports"></div>
|
||||
<script>
|
||||
// set a bad shim
|
||||
Object._keys = Object.keys;
|
||||
Object.keys = function() { return []; };
|
||||
|
||||
// load Lo-Dash and expose it to the bad `Object.keys` shim
|
||||
document.write('<script src="../' + QUnit.config.lodashFilename + '.js"><\/script>');
|
||||
document.write('<script src="../' + ui.buildPath + '"><\/script>');
|
||||
</script>
|
||||
<script>
|
||||
// store Lo-Dash to test for bad shim detection
|
||||
@@ -33,7 +33,7 @@
|
||||
delete Object._keys;
|
||||
|
||||
// load Lo-Dash again to overwrite the existing `_` value
|
||||
document.write('<script src="../' + QUnit.config.lodashFilename + '.js"><\/script>');
|
||||
document.write('<script src="../' + ui.buildPath + '"><\/script>');
|
||||
|
||||
// load test.js if not using require.js
|
||||
document.write(QUnit.urlParams.norequire
|
||||
@@ -47,20 +47,24 @@
|
||||
shimmedModule,
|
||||
underscoreModule;
|
||||
|
||||
window.require && require({
|
||||
'baseUrl': '../vendor/requirejs/',
|
||||
'urlArgs': 't=' + (+new Date),
|
||||
'paths': {
|
||||
'lodash': '../../' + QUnit.config.lodashFilename,
|
||||
'shimmed': './../../' + QUnit.config.lodashFilename,
|
||||
'underscore': '../underscore/../../' + QUnit.config.lodashFilename
|
||||
},
|
||||
'shim': {
|
||||
'shimmed': {
|
||||
'exports': '_'
|
||||
window.require && require(
|
||||
(function() {
|
||||
var modulePath = ui.buildPath.replace(/\.js$/, '');
|
||||
return {
|
||||
'baseUrl': '../vendor/requirejs/',
|
||||
'urlArgs': 't=' + (+new Date),
|
||||
'paths': {
|
||||
'lodash': '../../' + modulePath,
|
||||
'shimmed': './../../' + modulePath,
|
||||
'underscore': '../underscore/../../' + modulePath
|
||||
},
|
||||
'shim': {
|
||||
'shimmed': {
|
||||
'exports': '_'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
}()),
|
||||
['lodash', 'shimmed', 'underscore'], function(lodash, shimmed, underscore) {
|
||||
if (lodash && lodash.noConflict) {
|
||||
lodashModule = lodash.noConflict();
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
cd "$(dirname "$0")"
|
||||
for cmd in rhino ringo narwhal node; do
|
||||
echo ""
|
||||
|
||||
for cmd in rhino "rhino -require" narwhal ringo phantomjs; do
|
||||
echo "Testing in $cmd..."
|
||||
$cmd test.js
|
||||
$cmd test.js ../dist/lodash.compat.js && $cmd test.js ../dist/lodash.compat.min.js
|
||||
echo ""
|
||||
done
|
||||
|
||||
echo "Testing in node..."
|
||||
node test.js ../dist/lodash.js && node test.js ../dist/lodash.min.js
|
||||
|
||||
echo ""
|
||||
echo "Testing build..."
|
||||
node test-build.js
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<ul>
|
||||
<% _.forEach(people, function(name) { %><li><%= name %></li><% }); %>
|
||||
<% _.forEach(people, function(name) { %><li><%- name %></li><% }); %>
|
||||
</ul>
|
||||
1
test/template/c.jst
Normal file
1
test/template/c.jst
Normal file
@@ -0,0 +1 @@
|
||||
Hello ${ name }!
|
||||
File diff suppressed because it is too large
Load Diff
@@ -10,16 +10,22 @@
|
||||
/** A flag to determine if RequireJS should be loaded */
|
||||
var norequire = /[?&]norequire=true(?:&|$)/.test(location.search);
|
||||
|
||||
/** The `ui` object */
|
||||
var ui = {};
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
// assign `QUnit.config` properties
|
||||
QUnit.config.lodashFilename = (function() {
|
||||
// expose Lo-Dash build file path
|
||||
ui.buildPath = (function() {
|
||||
switch (build) {
|
||||
case 'prod': return 'lodash.min';
|
||||
case 'custom': return 'lodash.custom.min';
|
||||
case 'custom-debug': return 'lodash.custom';
|
||||
case 'lodash-prod': return 'dist/lodash.compat.min.js';
|
||||
case 'lodash-underscore': return 'dist/lodash.underscore.min.js';
|
||||
case 'lodash-modern': return 'dist/lodash.min.js';
|
||||
case 'lodash-modern-debug': return 'dist/lodash.js';
|
||||
case 'lodash-custom': return 'lodash.custom.min.js';
|
||||
case 'lodash-custom-debug': return 'lodash.custom.js';
|
||||
}
|
||||
return 'lodash';
|
||||
return 'lodash.js';
|
||||
}());
|
||||
|
||||
// assign `QUnit.urlParams` properties
|
||||
@@ -28,7 +34,7 @@
|
||||
'norequire': norequire
|
||||
});
|
||||
|
||||
// initialize the build dropdown
|
||||
// initialize controls
|
||||
addEvent(window, 'load', function() {
|
||||
function eventHandler(event) {
|
||||
var search = location.search.replace(/^\?|&?(?:build|norequire)=[^&]*&?/g, '');
|
||||
@@ -39,8 +45,8 @@
|
||||
}
|
||||
location.href =
|
||||
location.href.split('?')[0] + '?' +
|
||||
(search ? search + '&' : '') + 'build=' +
|
||||
dropdown[dropdown.selectedIndex].value +
|
||||
(search ? search + '&' : '') +
|
||||
'build=' + buildList[buildList.selectedIndex].value +
|
||||
(checkbox.checked ? '&norequire=true' : '');
|
||||
}
|
||||
|
||||
@@ -50,18 +56,21 @@
|
||||
toolbar.appendChild(span1);
|
||||
toolbar.appendChild(span2);
|
||||
|
||||
dropdown.selectedIndex = (function() {
|
||||
buildList.selectedIndex = (function() {
|
||||
switch (build) {
|
||||
case 'prod': return 1;
|
||||
case 'custom': return 2;
|
||||
case 'custom-debug': return 3;
|
||||
case 'lodash-prod': return 1;
|
||||
case 'lodash-underscore': return 2;
|
||||
case 'lodash-modern': return 3;
|
||||
case 'lodash-modern-debug': return 4;
|
||||
case 'lodash-custom': return 5;
|
||||
case 'lodash-custom-debug': return 6;
|
||||
}
|
||||
return 0;
|
||||
}());
|
||||
|
||||
checkbox.checked = norequire;
|
||||
addEvent(checkbox, 'click', eventHandler);
|
||||
addEvent(dropdown, 'change', eventHandler);
|
||||
addEvent(buildList, 'change', eventHandler);
|
||||
}
|
||||
else {
|
||||
setTimeout(init, 15);
|
||||
@@ -78,16 +87,22 @@
|
||||
span2.innerHTML =
|
||||
'<label for="qunit-build">Build: </label>' +
|
||||
'<select id="qunit-build">' +
|
||||
'<option value="dev">Developement</option>' +
|
||||
'<option value="prod">Production</option>' +
|
||||
'<option value="custom">Custom</option>' +
|
||||
'<option value="custom-debug">Custom (debug)</option>' +
|
||||
'<option value="lodash-dev">Developement</option>' +
|
||||
'<option value="lodash-prod">Production</option>' +
|
||||
'<option value="lodash-underscore">Underscore</option>' +
|
||||
'<option value="lodash-modern">Modern</option>' +
|
||||
'<option value="lodash-modern-debug">Modern (debug)</option>' +
|
||||
'<option value="lodash-custom">Custom</option>' +
|
||||
'<option value="lodash-custom-debug">Custom (debug)</option>' +
|
||||
'</select>';
|
||||
|
||||
var checkbox = span1.firstChild,
|
||||
dropdown = span2.lastChild;
|
||||
buildList = span2.lastChild;
|
||||
|
||||
init();
|
||||
});
|
||||
|
||||
// expose `ui`
|
||||
window.ui = ui;
|
||||
|
||||
}(this));
|
||||
|
||||
1887
test/test.js
1887
test/test.js
File diff suppressed because it is too large
Load Diff
@@ -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 {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
@@ -17,21 +17,74 @@
|
||||
<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/jslitmus.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="../vendor/qunit/qunit/qunit.js"></script>
|
||||
<script src="test-ui.js"></script>
|
||||
<script>
|
||||
document.write('<script src="../' + QUnit.config.lodashFilename + '.js"><\/script>');
|
||||
document.write('<script src="../' + ui.buildPath + '"><\/script>');
|
||||
</script>
|
||||
<script>
|
||||
(function() {
|
||||
var arrayProto = Array.prototype,
|
||||
concat = arrayProto.concat,
|
||||
pop = arrayProto.pop,
|
||||
push = arrayProto.push,
|
||||
slice = arrayProto.slice;
|
||||
|
||||
if (_.chain) {
|
||||
return;
|
||||
}
|
||||
_.mixin = function(object) {
|
||||
_.forEach(_.functions(object), function(methodName) {
|
||||
var func = _[methodName] = object[methodName];
|
||||
_.prototype[methodName] = function() {
|
||||
var args = [this.__wrapped__];
|
||||
push.apply(args, arguments);
|
||||
|
||||
var result = func.apply(_, args);
|
||||
if (this.__chain__) {
|
||||
result = new _(result);
|
||||
result.__chain__ = true;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
_.mixin(_);
|
||||
|
||||
_.mixin({
|
||||
'findWhere': _.find
|
||||
});
|
||||
|
||||
_.chain = function(value) {
|
||||
value = new _(value);
|
||||
value.__chain__ = true;
|
||||
return value;
|
||||
};
|
||||
|
||||
_.prototype.chain = function() {
|
||||
this.__chain__ = true;
|
||||
return this;
|
||||
};
|
||||
|
||||
_.prototype.concat = function() {
|
||||
var result = concat.apply(this.__wrapped__, arguments);
|
||||
if (this.__chain__) {
|
||||
result = new _(result);
|
||||
result.__chain__ = true;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
_.prototype.pop = function() {
|
||||
pop.apply(this.__wrapped__, arguments);
|
||||
return this;
|
||||
};
|
||||
}());
|
||||
</script>
|
||||
<script src="../vendor/underscore/test/collections.js"></script>
|
||||
<script src="../vendor/underscore/test/arrays.js"></script>
|
||||
|
||||
4
vendor/backbone/LICENSE
vendored
4
vendor/backbone/LICENSE
vendored
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2010-2012 Jeremy Ashkenas, DocumentCloud
|
||||
Copyright (c) 2010-2013 Jeremy Ashkenas, DocumentCloud
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
@@ -19,4 +19,4 @@ 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.
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
1557
vendor/backbone/backbone.js
vendored
1557
vendor/backbone/backbone.js
vendored
File diff suppressed because it is too large
Load Diff
504
vendor/backbone/test/collection.js
vendored
504
vendor/backbone/test/collection.js
vendored
@@ -18,17 +18,21 @@ $(document).ready(function() {
|
||||
|
||||
}));
|
||||
|
||||
test("new and sort", 7, function() {
|
||||
test("new and sort", 9, function() {
|
||||
var counter = 0;
|
||||
col.on('sort', function(){ counter++; });
|
||||
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(counter, 1);
|
||||
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(counter, 2);
|
||||
equal(col.first(), d, "d should be first");
|
||||
equal(col.last(), a, "a should be last");
|
||||
equal(col.length, 4);
|
||||
@@ -58,22 +62,29 @@ $(document).ready(function() {
|
||||
strictEqual(collection.last().get('a'), 4);
|
||||
});
|
||||
|
||||
test("get, getByCid", 3, function() {
|
||||
test("get", 6, function() {
|
||||
equal(col.get(0), d);
|
||||
equal(col.get(d.clone()), d);
|
||||
equal(col.get(2), b);
|
||||
equal(col.getByCid(col.first().cid), col.first());
|
||||
equal(col.get({id: 1}), c);
|
||||
equal(col.get(c.clone()), c);
|
||||
equal(col.get(col.first().cid), col.first());
|
||||
});
|
||||
|
||||
test("get with non-default ids", 2, function() {
|
||||
test("get with non-default ids", 5, function() {
|
||||
var col = new Backbone.Collection();
|
||||
var MongoModel = Backbone.Model.extend({
|
||||
idAttribute: '_id'
|
||||
});
|
||||
var MongoModel = Backbone.Model.extend({idAttribute: '_id'});
|
||||
var model = new MongoModel({_id: 100});
|
||||
col.push(model);
|
||||
col.add(model);
|
||||
equal(col.get(100), model);
|
||||
model.set({_id: 101});
|
||||
equal(col.get(101), model);
|
||||
equal(col.get(model.cid), model);
|
||||
equal(col.get(model), model);
|
||||
equal(col.get(101), void 0);
|
||||
|
||||
var col2 = new Backbone.Collection();
|
||||
col2.model = MongoModel;
|
||||
col2.add(model.attributes);
|
||||
equal(col2.get(model.clone()), col2.first());
|
||||
});
|
||||
|
||||
test("update index when id changes", 3, function() {
|
||||
@@ -214,6 +225,19 @@ $(document).ready(function() {
|
||||
equal(col.at(0).get('value'), 2);
|
||||
});
|
||||
|
||||
test("add with parse and merge", function() {
|
||||
var Model = Backbone.Model.extend({
|
||||
parse: function (data) {
|
||||
return data.model;
|
||||
}
|
||||
});
|
||||
var collection = new Backbone.Collection();
|
||||
collection.model = Model;
|
||||
collection.add({id: 1});
|
||||
collection.add({model: {id: 1, name: 'Alf'}}, {parse: true, merge: true});
|
||||
equal(collection.first().get('name'), 'Alf');
|
||||
});
|
||||
|
||||
test("add model to collection with sort()-style comparator", 3, function() {
|
||||
var col = new Backbone.Collection;
|
||||
col.comparator = function(a, b) {
|
||||
@@ -304,13 +328,13 @@ $(document).ready(function() {
|
||||
var colE = new Backbone.Collection([e]);
|
||||
var colF = new Backbone.Collection([f]);
|
||||
ok(e != f);
|
||||
ok(colE.length == 1);
|
||||
ok(colF.length == 1);
|
||||
ok(colE.length === 1);
|
||||
ok(colF.length === 1);
|
||||
colE.remove(e);
|
||||
equal(passed, false);
|
||||
ok(colE.length == 0);
|
||||
ok(colE.length === 0);
|
||||
colF.remove(e);
|
||||
ok(colF.length == 0);
|
||||
ok(colF.length === 0);
|
||||
equal(passed, true);
|
||||
});
|
||||
|
||||
@@ -338,24 +362,24 @@ $(document).ready(function() {
|
||||
});
|
||||
equal(colE, e.collection);
|
||||
colF.remove(e);
|
||||
ok(colF.length == 0);
|
||||
ok(colE.length == 1);
|
||||
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);
|
||||
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({}); };
|
||||
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);
|
||||
ok(colE.length === 0);
|
||||
ok(colF.length === 0);
|
||||
equal(undefined, e.collection);
|
||||
});
|
||||
|
||||
@@ -365,8 +389,8 @@ $(document).ready(function() {
|
||||
var colE = new Backbone.Collection([e]);
|
||||
var colF = new Backbone.Collection([e]);
|
||||
e.destroy();
|
||||
ok(colE.length == 0);
|
||||
ok(colF.length == 0);
|
||||
ok(colE.length === 0);
|
||||
ok(colF.length === 0);
|
||||
equal(undefined, e.collection);
|
||||
});
|
||||
|
||||
@@ -382,6 +406,28 @@ $(document).ready(function() {
|
||||
equal(this.syncArgs.options.parse, false);
|
||||
});
|
||||
|
||||
test("fetch with an error response triggers an error event", 1, function () {
|
||||
var collection = new Backbone.Collection();
|
||||
collection.on('error', function () {
|
||||
ok(true);
|
||||
});
|
||||
collection.sync = function (method, model, options) { options.error(); };
|
||||
collection.fetch();
|
||||
});
|
||||
|
||||
test("ensure fetch only parses once", 1, function() {
|
||||
var collection = new Backbone.Collection;
|
||||
var counter = 0;
|
||||
collection.parse = function(models) {
|
||||
counter++;
|
||||
return models;
|
||||
};
|
||||
collection.url = '/test';
|
||||
collection.fetch();
|
||||
this.syncArgs.options.success();
|
||||
equal(counter, 1);
|
||||
});
|
||||
|
||||
test("create", 4, function() {
|
||||
var collection = new Backbone.Collection;
|
||||
collection.url = '/test';
|
||||
@@ -392,7 +438,7 @@ $(document).ready(function() {
|
||||
equal(model.collection, collection);
|
||||
});
|
||||
|
||||
test("create enforces validation", 1, function() {
|
||||
test("create with validate:true enforces validation", 2, function() {
|
||||
var ValidatingModel = Backbone.Model.extend({
|
||||
validate: function(attrs) {
|
||||
return "fail";
|
||||
@@ -402,10 +448,13 @@ $(document).ready(function() {
|
||||
model: ValidatingModel
|
||||
});
|
||||
var col = new ValidatingCollection();
|
||||
equal(col.create({"foo":"bar"}), false);
|
||||
col.on('invalid', function (collection, attrs, options) {
|
||||
equal(options.validationError, 'fail');
|
||||
});
|
||||
equal(col.create({"foo":"bar"}, {validate:true}), false);
|
||||
});
|
||||
|
||||
test("a failing create runs the error callback", 1, function() {
|
||||
test("a failing create returns model with errors", function() {
|
||||
var ValidatingModel = Backbone.Model.extend({
|
||||
validate: function(attrs) {
|
||||
return "fail";
|
||||
@@ -414,11 +463,10 @@ $(document).ready(function() {
|
||||
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);
|
||||
var m = col.create({"foo":"bar"});
|
||||
equal(m.validationError, 'fail');
|
||||
equal(col.length, 1);
|
||||
});
|
||||
|
||||
test("initialize", 1, function() {
|
||||
@@ -435,9 +483,10 @@ $(document).ready(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() {
|
||||
test("where and findWhere", 8, function() {
|
||||
var model = new Backbone.Model({a: 1});
|
||||
var coll = new Backbone.Collection([
|
||||
{a: 1},
|
||||
model,
|
||||
{a: 1},
|
||||
{a: 1, b: 2},
|
||||
{a: 2, b: 2},
|
||||
@@ -449,6 +498,8 @@ $(document).ready(function() {
|
||||
equal(coll.where({b: 1}).length, 0);
|
||||
equal(coll.where({b: 2}).length, 2);
|
||||
equal(coll.where({a: 1, b: 2}).length, 1);
|
||||
equal(coll.findWhere({a: 1}), model);
|
||||
equal(coll.findWhere({a: 4}), void 0);
|
||||
});
|
||||
|
||||
test("Underscore methods", 13, function() {
|
||||
@@ -458,10 +509,10 @@ $(document).ready(function() {
|
||||
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(!_.include(col.rest(), a));
|
||||
ok(_.include(col.rest(), d));
|
||||
ok(!col.isEmpty());
|
||||
ok(!_.include(col.without(d)), d);
|
||||
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()
|
||||
@@ -471,7 +522,19 @@ $(document).ready(function() {
|
||||
[4, 0]);
|
||||
});
|
||||
|
||||
test("reset", 10, function() {
|
||||
test("sortedIndex", function () {
|
||||
var model = new Backbone.Model({key: 2});
|
||||
var collection = new (Backbone.Collection.extend({
|
||||
comparator: 'key'
|
||||
}))([model, {key: 1}]);
|
||||
equal(collection.sortedIndex(model), 1);
|
||||
equal(collection.sortedIndex(model, 'key'), 1);
|
||||
equal(collection.sortedIndex(model, function (model) {
|
||||
return model.get('key');
|
||||
}), 1);
|
||||
});
|
||||
|
||||
test("reset", 12, function() {
|
||||
var resetCount = 0;
|
||||
var models = col.models;
|
||||
col.on('reset', function() { resetCount += 1; });
|
||||
@@ -488,6 +551,22 @@ $(document).ready(function() {
|
||||
equal(col.length, 4);
|
||||
ok(col.last() !== d);
|
||||
ok(_.isEqual(col.last().attributes, d.attributes));
|
||||
col.reset();
|
||||
equal(col.length, 0);
|
||||
equal(resetCount, 4);
|
||||
});
|
||||
|
||||
test ("reset with different values", function(){
|
||||
var col = new Backbone.Collection({id: 1});
|
||||
col.reset({id: 1, a: 1});
|
||||
equal(col.get(1).get('a'), 1);
|
||||
});
|
||||
|
||||
test("same references in reset", function() {
|
||||
var model = new Backbone.Model({id: 1});
|
||||
var collection = new Backbone.Collection({id: 1});
|
||||
collection.reset(model);
|
||||
equal(collection.get(1), model);
|
||||
});
|
||||
|
||||
test("reset passes caller options", 3, function() {
|
||||
@@ -542,8 +621,7 @@ $(document).ready(function() {
|
||||
equal(col.length, 0);
|
||||
});
|
||||
|
||||
test("#861, adding models to a collection which do not pass validation", 1, function() {
|
||||
raises(function() {
|
||||
test("#861, adding models to a collection which do not pass validation, with validate:true", function() {
|
||||
var Model = Backbone.Model.extend({
|
||||
validate: function(attrs) {
|
||||
if (attrs.id == 3) return "id can't be 3";
|
||||
@@ -554,26 +632,26 @@ $(document).ready(function() {
|
||||
model: Model
|
||||
});
|
||||
|
||||
var col = new Collection;
|
||||
var collection = new Collection;
|
||||
collection.on("error", function() { ok(true); });
|
||||
|
||||
col.add([{id: 1}, {id: 2}, {id: 3}, {id: 4}, {id: 5}, {id: 6}]);
|
||||
}, function(e) {
|
||||
return e.message === "Can't add an invalid model to a collection";
|
||||
});
|
||||
collection.add([{id: 1}, {id: 2}, {id: 3}, {id: 4}, {id: 5}, {id: 6}], {validate:true});
|
||||
deepEqual(collection.pluck('id'), [1, 2, 4, 5, 6]);
|
||||
});
|
||||
|
||||
test("throwing during add leaves consistent state", 4, function() {
|
||||
var col = new Backbone.Collection();
|
||||
col.on('test', function() { ok(false); });
|
||||
col.model = Backbone.Model.extend({
|
||||
test("Invalid models are discarded with validate:true.", 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 col.model({id: 1, valid: true});
|
||||
raises(function() { col.add([model, {id: 2}]); });
|
||||
var model = new collection.model({id: 1, valid: true});
|
||||
collection.add([model, {id: 2}], {validate:true});
|
||||
model.trigger('test');
|
||||
ok(!col.getByCid(model.cid));
|
||||
ok(!col.get(1));
|
||||
equal(col.length, 0);
|
||||
ok(collection.get(model.cid));
|
||||
ok(collection.get(1));
|
||||
ok(!collection.get(2));
|
||||
equal(collection.length, 1);
|
||||
});
|
||||
|
||||
test("multiple copies of the same model", 3, function() {
|
||||
@@ -632,19 +710,34 @@ $(document).ready(function() {
|
||||
}
|
||||
};
|
||||
col.sync = m.sync = function( method, collection, options ){
|
||||
options.success();
|
||||
options.success(collection, [], options);
|
||||
};
|
||||
col.fetch(opts);
|
||||
col.create(m, opts);
|
||||
});
|
||||
|
||||
test("#1412 - Trigger 'sync' event.", 2, function() {
|
||||
test("#1412 - Trigger 'request' and 'sync' events.", 4, function() {
|
||||
var collection = new Backbone.Collection;
|
||||
collection.url = '/test';
|
||||
collection.on('sync', function() { ok(true); });
|
||||
Backbone.ajax = function(settings){ settings.success(); };
|
||||
|
||||
collection.on('request', function(obj, xhr, options) {
|
||||
ok(obj === collection, "collection has correct 'request' event after fetching");
|
||||
});
|
||||
collection.on('sync', function(obj, response, options) {
|
||||
ok(obj === collection, "collection has correct 'sync' event after fetching");
|
||||
});
|
||||
collection.fetch();
|
||||
collection.off();
|
||||
|
||||
collection.on('request', function(obj, xhr, options) {
|
||||
ok(obj === collection.get(1), "collection has correct 'request' event after one of its models save");
|
||||
});
|
||||
collection.on('sync', function(obj, response, options) {
|
||||
ok(obj === collection.get(1), "collection has correct 'sync' event after one of its models save");
|
||||
});
|
||||
collection.create({id: 1});
|
||||
collection.off();
|
||||
});
|
||||
|
||||
test("#1447 - create with wait adds model.", 1, function() {
|
||||
@@ -701,4 +794,307 @@ $(document).ready(function() {
|
||||
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});
|
||||
});
|
||||
|
||||
test("#1407 parse option on constructor parses collection and models", 2, function() {
|
||||
var model = {
|
||||
namespace : [{id: 1}, {id:2}]
|
||||
};
|
||||
var Collection = Backbone.Collection.extend({
|
||||
model: Backbone.Model.extend({
|
||||
parse: function(model) {
|
||||
model.name = 'test';
|
||||
return model;
|
||||
}
|
||||
}),
|
||||
parse: function(model) {
|
||||
return model.namespace;
|
||||
}
|
||||
});
|
||||
var c = new Collection(model, {parse:true});
|
||||
|
||||
equal(c.length, 2);
|
||||
equal(c.at(0).get('name'), 'test');
|
||||
});
|
||||
|
||||
test("#1407 parse option on reset parses collection and models", 2, function() {
|
||||
var model = {
|
||||
namespace : [{id: 1}, {id:2}]
|
||||
};
|
||||
var Collection = Backbone.Collection.extend({
|
||||
model: Backbone.Model.extend({
|
||||
parse: function(model) {
|
||||
model.name = 'test';
|
||||
return model;
|
||||
}
|
||||
}),
|
||||
parse: function(model) {
|
||||
return model.namespace;
|
||||
}
|
||||
});
|
||||
var c = new Collection();
|
||||
c.reset(model, {parse:true});
|
||||
|
||||
equal(c.length, 2);
|
||||
equal(c.at(0).get('name'), 'test');
|
||||
});
|
||||
|
||||
|
||||
test("Reset includes previous models in triggered event.", 1, function() {
|
||||
var model = new Backbone.Model();
|
||||
var collection = new Backbone.Collection([model])
|
||||
.on('reset', function(collection, options) {
|
||||
deepEqual(options.previousModels, [model]);
|
||||
});
|
||||
collection.reset([]);
|
||||
});
|
||||
|
||||
test("set", function() {
|
||||
var m1 = new Backbone.Model();
|
||||
var m2 = new Backbone.Model({id: 2});
|
||||
var m3 = new Backbone.Model();
|
||||
var c = new Backbone.Collection([m1, m2]);
|
||||
|
||||
// Test add/change/remove events
|
||||
c.on('add', function(model) {
|
||||
strictEqual(model, m3);
|
||||
});
|
||||
c.on('change', function(model) {
|
||||
strictEqual(model, m2);
|
||||
});
|
||||
c.on('remove', function(model) {
|
||||
strictEqual(model, m1);
|
||||
});
|
||||
|
||||
// remove: false doesn't remove any models
|
||||
c.set([], {remove: false});
|
||||
strictEqual(c.length, 2);
|
||||
|
||||
// add: false doesn't add any models
|
||||
c.set([m1, m2, m3], {add: false});
|
||||
strictEqual(c.length, 2);
|
||||
|
||||
// merge: false doesn't change any models
|
||||
c.set([m1, {id: 2, a: 1}], {merge: false});
|
||||
strictEqual(m2.get('a'), void 0);
|
||||
|
||||
// add: false, remove: false only merges existing models
|
||||
c.set([m1, {id: 2, a: 0}, m3, {id: 4}], {add: false, remove: false});
|
||||
strictEqual(c.length, 2);
|
||||
strictEqual(m2.get('a'), 0);
|
||||
|
||||
// default options add/remove/merge as appropriate
|
||||
c.set([{id: 2, a: 1}, m3]);
|
||||
strictEqual(c.length, 2);
|
||||
strictEqual(m2.get('a'), 1);
|
||||
|
||||
// Test removing models not passing an argument
|
||||
c.off('remove').on('remove', function(model) {
|
||||
ok(model === m2 || model === m3);
|
||||
});
|
||||
c.set([]);
|
||||
strictEqual(c.length, 0);
|
||||
});
|
||||
|
||||
test("set with only cids", 3, function() {
|
||||
var m1 = new Backbone.Model;
|
||||
var m2 = new Backbone.Model;
|
||||
var c = new Backbone.Collection;
|
||||
c.set([m1, m2]);
|
||||
equal(c.length, 2);
|
||||
c.set([m1]);
|
||||
equal(c.length, 1);
|
||||
c.set([m1, m1, m1, m2, m2], {remove: false});
|
||||
equal(c.length, 2);
|
||||
});
|
||||
|
||||
test("set with only idAttribute", 3, function() {
|
||||
var m1 = { _id: 1 };
|
||||
var m2 = { _id: 2 };
|
||||
var col = Backbone.Collection.extend({
|
||||
model: Backbone.Model.extend({
|
||||
idAttribute: '_id'
|
||||
})
|
||||
});
|
||||
var c = new col;
|
||||
c.set([m1, m2]);
|
||||
equal(c.length, 2);
|
||||
c.set([m1]);
|
||||
equal(c.length, 1);
|
||||
c.set([m1, m1, m1, m2, m2], {remove: false});
|
||||
equal(c.length, 2);
|
||||
});
|
||||
|
||||
test("set + merge with default values defined", function() {
|
||||
var Model = Backbone.Model.extend({
|
||||
defaults: {
|
||||
key: 'value'
|
||||
}
|
||||
});
|
||||
var m = new Model({id: 1});
|
||||
var col = new Backbone.Collection([m], {model: Model});
|
||||
equal(col.first().get('key'), 'value');
|
||||
|
||||
col.set({id: 1, key: 'other'});
|
||||
equal(col.first().get('key'), 'other');
|
||||
|
||||
col.set({id: 1, other: 'value'});
|
||||
equal(col.first().get('key'), 'value');
|
||||
equal(col.length, 1);
|
||||
});
|
||||
|
||||
test("`set` and model level `parse`", function() {
|
||||
var Model = Backbone.Model.extend({
|
||||
parse: function (res) { return res.model; }
|
||||
});
|
||||
var Collection = Backbone.Collection.extend({
|
||||
model: Model,
|
||||
parse: function (res) { return res.models; }
|
||||
});
|
||||
var model = new Model({id: 1});
|
||||
var collection = new Collection(model);
|
||||
collection.set({models: [
|
||||
{model: {id: 1}},
|
||||
{model: {id: 2}}
|
||||
]}, {parse: true});
|
||||
equal(collection.first(), model);
|
||||
});
|
||||
|
||||
test("`set` data is only parsed once", function() {
|
||||
var collection = new Backbone.Collection();
|
||||
collection.model = Backbone.Model.extend({
|
||||
parse: function (data) {
|
||||
equal(data.parsed, void 0);
|
||||
data.parsed = true;
|
||||
return data;
|
||||
}
|
||||
});
|
||||
collection.set({}, {parse: true});
|
||||
});
|
||||
|
||||
test("#1894 - Push should not trigger a sort", 0, function() {
|
||||
var Collection = Backbone.Collection.extend({
|
||||
comparator: 'id',
|
||||
sort: function() {
|
||||
ok(false);
|
||||
}
|
||||
});
|
||||
new Collection().push({id: 1});
|
||||
});
|
||||
|
||||
test("`set` with non-normal id", function() {
|
||||
var Collection = Backbone.Collection.extend({
|
||||
model: Backbone.Model.extend({idAttribute: '_id'})
|
||||
});
|
||||
var collection = new Collection({_id: 1});
|
||||
collection.set([{_id: 1, a: 1}], {add: false});
|
||||
equal(collection.first().get('a'), 1);
|
||||
});
|
||||
|
||||
test("#1894 - `sort` can optionally be turned off", 0, function() {
|
||||
var Collection = Backbone.Collection.extend({
|
||||
comparator: 'id',
|
||||
sort: function() { ok(true); }
|
||||
});
|
||||
new Collection().add({id: 1}, {sort: false});
|
||||
});
|
||||
|
||||
test("#1915 - `parse` data in the right order in `set`", function() {
|
||||
var collection = new (Backbone.Collection.extend({
|
||||
parse: function (data) {
|
||||
strictEqual(data.status, 'ok');
|
||||
return data.data;
|
||||
}
|
||||
}));
|
||||
var res = {status: 'ok', data:[{id: 1}]};
|
||||
collection.set(res, {parse: true});
|
||||
});
|
||||
|
||||
asyncTest("#1939 - `parse` is passed `options`", 1, function () {
|
||||
var collection = new (Backbone.Collection.extend({
|
||||
url: '/',
|
||||
parse: function (data, options) {
|
||||
strictEqual(options.xhr.someHeader, 'headerValue');
|
||||
return data;
|
||||
}
|
||||
}));
|
||||
var ajax = Backbone.ajax;
|
||||
Backbone.ajax = function (params) {
|
||||
_.defer(params.success);
|
||||
return {someHeader: 'headerValue'};
|
||||
};
|
||||
collection.fetch({
|
||||
success: function () { start(); }
|
||||
});
|
||||
Backbone.ajax = ajax;
|
||||
});
|
||||
|
||||
test("`add` only `sort`s when necessary", 2, function () {
|
||||
var collection = new (Backbone.Collection.extend({
|
||||
comparator: 'a'
|
||||
}))([{id: 1}, {id: 2}, {id: 3}]);
|
||||
collection.on('sort', function () { ok(true); });
|
||||
collection.add({id: 4}); // do sort, new model
|
||||
collection.add({id: 1, a: 1}, {merge: true}); // do sort, comparator change
|
||||
collection.add({id: 1, b: 1}, {merge: true}); // don't sort, no comparator change
|
||||
collection.add({id: 1, a: 1}, {merge: true}); // don't sort, no comparator change
|
||||
collection.add(collection.models); // don't sort, nothing new
|
||||
collection.add(collection.models, {merge: true}); // don't sort
|
||||
});
|
||||
|
||||
test("`add` only `sort`s when necessary with comparator function", 3, function () {
|
||||
var collection = new (Backbone.Collection.extend({
|
||||
comparator: function(a, b) {
|
||||
return a.get('a') > b.get('a') ? 1 : (a.get('a') < b.get('a') ? -1 : 0);
|
||||
}
|
||||
}))([{id: 1}, {id: 2}, {id: 3}]);
|
||||
collection.on('sort', function () { ok(true); });
|
||||
collection.add({id: 4}); // do sort, new model
|
||||
collection.add({id: 1, a: 1}, {merge: true}); // do sort, model change
|
||||
collection.add({id: 1, b: 1}, {merge: true}); // do sort, model change
|
||||
collection.add({id: 1, a: 1}, {merge: true}); // don't sort, no model change
|
||||
collection.add(collection.models); // don't sort, nothing new
|
||||
collection.add(collection.models, {merge: true}); // don't sort
|
||||
});
|
||||
|
||||
test("Attach options to collection.", 3, function() {
|
||||
var url = '/somewhere';
|
||||
var model = new Backbone.Model;
|
||||
var comparator = function(){};
|
||||
|
||||
var collection = new Backbone.Collection([], {
|
||||
url: url,
|
||||
model: model,
|
||||
comparator: comparator
|
||||
});
|
||||
|
||||
strictEqual(collection.url, url);
|
||||
ok(collection.model === model);
|
||||
ok(collection.comparator === comparator);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
6
vendor/backbone/test/environment.js
vendored
6
vendor/backbone/test/environment.js
vendored
@@ -8,6 +8,10 @@
|
||||
|
||||
sync: Backbone.sync,
|
||||
|
||||
emulateHTTP: Backbone.emulateHTTP,
|
||||
|
||||
emulateJSON: Backbone.emulateJSON,
|
||||
|
||||
setup: function() {
|
||||
var env = this;
|
||||
|
||||
@@ -32,6 +36,8 @@
|
||||
this.ajaxSettings = null;
|
||||
Backbone.sync = this.sync;
|
||||
Backbone.ajax = this.ajax;
|
||||
Backbone.emulateHTTP = this.emulateHTTP;
|
||||
Backbone.emulateJSON = this.emulateJSON;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
283
vendor/backbone/test/events.js
vendored
283
vendor/backbone/test/events.js
vendored
@@ -17,7 +17,7 @@ $(document).ready(function() {
|
||||
|
||||
test("binding and triggering multiple events", 4, function() {
|
||||
var obj = { counter: 0 };
|
||||
_.extend(obj,Backbone.Events);
|
||||
_.extend(obj, Backbone.Events);
|
||||
|
||||
obj.on('a b c', function() { obj.counter += 1; });
|
||||
|
||||
@@ -35,6 +35,130 @@ $(document).ready(function() {
|
||||
equal(obj.counter, 5);
|
||||
});
|
||||
|
||||
test("binding and triggering with event maps", function() {
|
||||
var obj = { counter: 0 };
|
||||
_.extend(obj, Backbone.Events);
|
||||
|
||||
var increment = function() {
|
||||
this.counter += 1;
|
||||
};
|
||||
|
||||
obj.on({
|
||||
a: increment,
|
||||
b: increment,
|
||||
c: increment
|
||||
}, obj);
|
||||
|
||||
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: increment,
|
||||
c: increment
|
||||
}, obj);
|
||||
obj.trigger('a b c');
|
||||
equal(obj.counter, 5);
|
||||
});
|
||||
|
||||
test("listenTo and stopListening", 1, function() {
|
||||
var a = _.extend({}, Backbone.Events);
|
||||
var b = _.extend({}, Backbone.Events);
|
||||
a.listenTo(b, 'all', function(){ ok(true); });
|
||||
b.trigger('anything');
|
||||
a.listenTo(b, 'all', function(){ ok(false); });
|
||||
a.stopListening();
|
||||
b.trigger('anything');
|
||||
});
|
||||
|
||||
test("listenTo and stopListening with event maps", 4, function() {
|
||||
var a = _.extend({}, Backbone.Events);
|
||||
var b = _.extend({}, Backbone.Events);
|
||||
var cb = function(){ ok(true); };
|
||||
a.listenTo(b, {event: cb});
|
||||
b.trigger('event');
|
||||
a.listenTo(b, {event2: cb});
|
||||
b.on('event2', cb);
|
||||
a.stopListening(b, {event2: cb});
|
||||
b.trigger('event event2');
|
||||
a.stopListening();
|
||||
b.trigger('event event2');
|
||||
});
|
||||
|
||||
test("stopListening with omitted args", 2, function () {
|
||||
var a = _.extend({}, Backbone.Events);
|
||||
var b = _.extend({}, Backbone.Events);
|
||||
var cb = function () { ok(true); };
|
||||
a.listenTo(b, 'event', cb);
|
||||
b.on('event', cb);
|
||||
a.listenTo(b, 'event2', cb);
|
||||
a.stopListening(null, {event: cb});
|
||||
b.trigger('event event2');
|
||||
b.off();
|
||||
a.listenTo(b, 'event event2', cb);
|
||||
a.stopListening(null, 'event');
|
||||
a.stopListening();
|
||||
b.trigger('event2');
|
||||
});
|
||||
|
||||
test("listenToOnce and stopListening", 1, function() {
|
||||
var a = _.extend({}, Backbone.Events);
|
||||
var b = _.extend({}, Backbone.Events);
|
||||
a.listenToOnce(b, 'all', function() { ok(true); });
|
||||
b.trigger('anything');
|
||||
b.trigger('anything');
|
||||
a.listenToOnce(b, 'all', function() { ok(false); });
|
||||
a.stopListening();
|
||||
b.trigger('anything');
|
||||
});
|
||||
|
||||
test("listenTo, listenToOnce and stopListening", 1, function() {
|
||||
var a = _.extend({}, Backbone.Events);
|
||||
var b = _.extend({}, Backbone.Events);
|
||||
a.listenToOnce(b, 'all', function() { ok(true); });
|
||||
b.trigger('anything');
|
||||
b.trigger('anything');
|
||||
a.listenTo(b, 'all', function() { ok(false); });
|
||||
a.stopListening();
|
||||
b.trigger('anything');
|
||||
});
|
||||
|
||||
test("listenTo and stopListening with event maps", 1, function() {
|
||||
var a = _.extend({}, Backbone.Events);
|
||||
var b = _.extend({}, Backbone.Events);
|
||||
a.listenTo(b, {change: function(){ ok(true); }});
|
||||
b.trigger('change');
|
||||
a.listenTo(b, {change: function(){ ok(false); }});
|
||||
a.stopListening();
|
||||
b.trigger('change');
|
||||
});
|
||||
|
||||
test("listenTo yourself", 1, function(){
|
||||
var e = _.extend({}, Backbone.Events);
|
||||
e.listenTo(e, "foo", function(){ ok(true); });
|
||||
e.trigger("foo");
|
||||
});
|
||||
|
||||
test("listenTo yourself cleans yourself up with stopListening", 1, function(){
|
||||
var e = _.extend({}, Backbone.Events);
|
||||
e.listenTo(e, "foo", function(){ ok(true); });
|
||||
e.trigger("foo");
|
||||
e.stopListening();
|
||||
e.trigger("foo");
|
||||
});
|
||||
|
||||
test("listenTo with empty callback doesn't throw an error", 1, function(){
|
||||
var e = _.extend({}, Backbone.Events);
|
||||
e.listenTo(e, "foo", null);
|
||||
e.trigger("foo");
|
||||
ok(true);
|
||||
});
|
||||
|
||||
test("trigger all for each event", 3, function() {
|
||||
var a, b, obj = { counter: 0 };
|
||||
_.extend(obj, Backbone.Events);
|
||||
@@ -154,6 +278,13 @@ $(document).ready(function() {
|
||||
_.extend({}, Backbone.Events).on('test').trigger('test');
|
||||
});
|
||||
|
||||
test("if callback is truthy but not a function, `on` should throw an error just like jQuery", 1, function() {
|
||||
var view = _.extend({}, Backbone.Events).on('test', 'noop');
|
||||
throws(function() {
|
||||
view.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); });
|
||||
@@ -172,18 +303,6 @@ $(document).ready(function() {
|
||||
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);
|
||||
@@ -192,4 +311,142 @@ $(document).ready(function() {
|
||||
obj.trigger('event');
|
||||
});
|
||||
|
||||
test("once", 2, function() {
|
||||
// Same as the previous test, but we use once rather than having to explicitly unbind
|
||||
var obj = { counterA: 0, counterB: 0 };
|
||||
_.extend(obj, Backbone.Events);
|
||||
var incrA = function(){ obj.counterA += 1; obj.trigger('event'); };
|
||||
var incrB = function(){ obj.counterB += 1; };
|
||||
obj.once('event', incrA);
|
||||
obj.once('event', incrB);
|
||||
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("once variant one", 3, function() {
|
||||
var f = function(){ ok(true); };
|
||||
|
||||
var a = _.extend({}, Backbone.Events).once('event', f);
|
||||
var b = _.extend({}, Backbone.Events).on('event', f);
|
||||
|
||||
a.trigger('event');
|
||||
|
||||
b.trigger('event');
|
||||
b.trigger('event');
|
||||
});
|
||||
|
||||
test("once variant two", 3, function() {
|
||||
var f = function(){ ok(true); };
|
||||
var obj = _.extend({}, Backbone.Events);
|
||||
|
||||
obj
|
||||
.once('event', f)
|
||||
.on('event', f)
|
||||
.trigger('event')
|
||||
.trigger('event');
|
||||
});
|
||||
|
||||
test("once with off", 0, function() {
|
||||
var f = function(){ ok(true); };
|
||||
var obj = _.extend({}, Backbone.Events);
|
||||
|
||||
obj.once('event', f);
|
||||
obj.off('event', f);
|
||||
obj.trigger('event');
|
||||
});
|
||||
|
||||
test("once with event maps", function() {
|
||||
var obj = { counter: 0 };
|
||||
_.extend(obj, Backbone.Events);
|
||||
|
||||
var increment = function() {
|
||||
this.counter += 1;
|
||||
};
|
||||
|
||||
obj.once({
|
||||
a: increment,
|
||||
b: increment,
|
||||
c: increment
|
||||
}, obj);
|
||||
|
||||
obj.trigger('a');
|
||||
equal(obj.counter, 1);
|
||||
|
||||
obj.trigger('a b');
|
||||
equal(obj.counter, 2);
|
||||
|
||||
obj.trigger('c');
|
||||
equal(obj.counter, 3);
|
||||
|
||||
obj.trigger('a b c');
|
||||
equal(obj.counter, 3);
|
||||
});
|
||||
|
||||
test("once with off only by context", 0, function() {
|
||||
var context = {};
|
||||
var obj = _.extend({}, Backbone.Events);
|
||||
obj.once('event', function(){ ok(false); }, context);
|
||||
obj.off(null, null, context);
|
||||
obj.trigger('event');
|
||||
});
|
||||
|
||||
test("Backbone object inherits Events", function() {
|
||||
ok(Backbone.on === Backbone.Events.on);
|
||||
});
|
||||
|
||||
asyncTest("once with asynchronous events", 1, function() {
|
||||
var func = _.debounce(function() { ok(true); start(); }, 50);
|
||||
var obj = _.extend({}, Backbone.Events).once('async', func);
|
||||
|
||||
obj.trigger('async');
|
||||
obj.trigger('async');
|
||||
});
|
||||
|
||||
test("once with multiple events.", 2, function() {
|
||||
var obj = _.extend({}, Backbone.Events);
|
||||
obj.once('x y', function() { ok(true); });
|
||||
obj.trigger('x y');
|
||||
});
|
||||
|
||||
test("Off during iteration with once.", 2, function() {
|
||||
var obj = _.extend({}, Backbone.Events);
|
||||
var f = function(){ this.off('event', f); };
|
||||
obj.on('event', f);
|
||||
obj.once('event', function(){});
|
||||
obj.on('event', function(){ ok(true); });
|
||||
|
||||
obj.trigger('event');
|
||||
obj.trigger('event');
|
||||
});
|
||||
|
||||
test("`once` on `all` should work as expected", 1, function() {
|
||||
Backbone.once('all', function() {
|
||||
ok(true);
|
||||
Backbone.trigger('all');
|
||||
});
|
||||
Backbone.trigger('all');
|
||||
});
|
||||
|
||||
test("once without a callback is a noop", 0, function() {
|
||||
_.extend({}, Backbone.Events).once('event').trigger('event');
|
||||
});
|
||||
|
||||
test("event functions are chainable", function() {
|
||||
var obj = _.extend({}, Backbone.Events);
|
||||
var obj2 = _.extend({}, Backbone.Events);
|
||||
var fn = function() {};
|
||||
equal(obj, obj.trigger('noeventssetyet'));
|
||||
equal(obj, obj.off('noeventssetyet'));
|
||||
equal(obj, obj.stopListening('noeventssetyet'));
|
||||
equal(obj, obj.on('a', fn));
|
||||
equal(obj, obj.once('c', fn));
|
||||
equal(obj, obj.trigger('a'));
|
||||
equal(obj, obj.listenTo(obj2, 'a', fn));
|
||||
equal(obj, obj.listenToOnce(obj2, 'b', fn));
|
||||
equal(obj, obj.off('a c'));
|
||||
equal(obj, obj.stopListening(obj2, 'a'));
|
||||
equal(obj, obj.stopListening());
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
493
vendor/backbone/test/model.js
vendored
493
vendor/backbone/test/model.js
vendored
@@ -46,15 +46,38 @@ $(document).ready(function() {
|
||||
|
||||
test("initialize with parsed attributes", 1, function() {
|
||||
var Model = Backbone.Model.extend({
|
||||
parse: function(obj) {
|
||||
obj.value += 1;
|
||||
return obj;
|
||||
parse: function(attrs) {
|
||||
attrs.value += 1;
|
||||
return attrs;
|
||||
}
|
||||
});
|
||||
var model = new Model({value: 1}, {parse: true});
|
||||
equal(model.get('value'), 2);
|
||||
});
|
||||
|
||||
test("initialize with defaults", 2, function() {
|
||||
var Model = Backbone.Model.extend({
|
||||
defaults: {
|
||||
first_name: 'Unknown',
|
||||
last_name: 'Unknown'
|
||||
}
|
||||
});
|
||||
var model = new Model({'first_name': 'John'});
|
||||
equal(model.get('first_name'), 'John');
|
||||
equal(model.get('last_name'), 'Unknown');
|
||||
});
|
||||
|
||||
test("parse can return null", 1, function() {
|
||||
var Model = Backbone.Model.extend({
|
||||
parse: function(attrs) {
|
||||
attrs.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');
|
||||
@@ -88,7 +111,24 @@ $(document).ready(function() {
|
||||
equal(model.url(), '/nested/1/collection/2');
|
||||
});
|
||||
|
||||
test("clone", 8, function() {
|
||||
test('url and urlRoot are directly attached if passed in the options', 2, function () {
|
||||
var model = new Backbone.Model({a: 1}, {url: '/test'});
|
||||
var model2 = new Backbone.Model({a: 2}, {urlRoot: '/test2'});
|
||||
equal(model.url, '/test');
|
||||
equal(model2.urlRoot, '/test2');
|
||||
});
|
||||
|
||||
test("underscore methods", 5, function() {
|
||||
var model = new Backbone.Model({ 'foo': 'a', 'bar': 'b', 'baz': 'c' });
|
||||
var model2 = model.clone();
|
||||
deepEqual(model.keys(), ['foo', 'bar', 'baz']);
|
||||
deepEqual(model.values(), ['a', 'b', 'c']);
|
||||
deepEqual(model.invert(), { 'a': 'foo', 'b': 'bar', 'c': 'baz' });
|
||||
deepEqual(model.pick('foo', 'baz'), {'foo': 'a', 'baz': 'c'});
|
||||
deepEqual(model.omit('foo', 'bar'), {'baz': 'c'});
|
||||
});
|
||||
|
||||
test("clone", 10, function() {
|
||||
var a = new Backbone.Model({ 'foo': 1, 'bar': 2, 'baz': 3});
|
||||
var b = a.clone();
|
||||
equal(a.get('foo'), 1);
|
||||
@@ -100,6 +140,12 @@ $(document).ready(function() {
|
||||
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().attributes, {unset: true});
|
||||
equal(foo.get('p'), 1);
|
||||
equal(bar.get('p'), undefined);
|
||||
});
|
||||
|
||||
test("isNew", 6, function() {
|
||||
@@ -173,9 +219,9 @@ $(document).ready(function() {
|
||||
ok(changeCount == 1, "Change count should NOT have incremented.");
|
||||
|
||||
a.validate = function(attrs) {
|
||||
equal(attrs.foo, void 0, "don't ignore values when unsetting");
|
||||
equal(attrs.foo, void 0, "validate:true passed while unsetting");
|
||||
};
|
||||
a.unset('foo');
|
||||
a.unset('foo', {validate: true});
|
||||
equal(a.get('foo'), void 0, "Foo should have changed");
|
||||
delete a.validate;
|
||||
ok(changeCount == 2, "Change count should have incremented for unset.");
|
||||
@@ -184,6 +230,46 @@ $(document).ready(function() {
|
||||
equal(a.id, undefined, "Unsetting the id should remove the id property.");
|
||||
});
|
||||
|
||||
test("#2030 - set with failed validate, followed by another set triggers change", function () {
|
||||
var attr = 0, main = 0, error = 0;
|
||||
var Model = Backbone.Model.extend({
|
||||
validate: function (attr) {
|
||||
if (attr.x > 1) {
|
||||
error++;
|
||||
return "this is an error";
|
||||
}
|
||||
}
|
||||
});
|
||||
var model = new Model({x:0});
|
||||
model.on('change:x', function () { attr++; });
|
||||
model.on('change', function () { main++; });
|
||||
model.set({x:2}, {validate:true});
|
||||
model.set({x:1}, {validate:true});
|
||||
deepEqual([attr, main, error], [1, 1, 1]);
|
||||
});
|
||||
|
||||
test("set triggers changes in the correct order", function() {
|
||||
var value = null;
|
||||
var model = new Backbone.Model;
|
||||
model.on('last', function(){ value = 'last'; });
|
||||
model.on('first', function(){ value = 'first'; });
|
||||
model.trigger('first');
|
||||
model.trigger('last');
|
||||
equal(value, 'last');
|
||||
});
|
||||
|
||||
test("set falsy values in the correct order", 2, function() {
|
||||
var model = new Backbone.Model({result: 'result'});
|
||||
model.on('change', function() {
|
||||
equal(model.changed.result, void 0);
|
||||
equal(model.previous('result'), false);
|
||||
});
|
||||
model.set({result: void 0}, {silent: true});
|
||||
model.set({result: null}, {silent: true});
|
||||
model.set({result: false}, {silent: true});
|
||||
model.set({result: void 0});
|
||||
});
|
||||
|
||||
test("multiple unsets", 1, function() {
|
||||
var i = 0;
|
||||
var counter = function(){ i++; };
|
||||
@@ -195,14 +281,12 @@ $(document).ready(function() {
|
||||
equal(i, 2, 'Unset does not fire an event for missing attributes.');
|
||||
});
|
||||
|
||||
test("unset and changedAttributes", 2, function() {
|
||||
test("unset and changedAttributes", 1, 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.');
|
||||
model.on('change', function() {
|
||||
ok('a' in model.changedAttributes(), 'changedAttributes should contain unset properties');
|
||||
});
|
||||
model.unset('a');
|
||||
});
|
||||
|
||||
test("using a non-default id attribute.", 5, function() {
|
||||
@@ -222,6 +306,21 @@ $(document).ready(function() {
|
||||
equal(model.get('name'), '');
|
||||
});
|
||||
|
||||
test("setting an object", 1, function() {
|
||||
var model = new Backbone.Model({
|
||||
custom: { foo: 1 }
|
||||
});
|
||||
model.on('change', function() {
|
||||
ok(1);
|
||||
});
|
||||
model.set({
|
||||
custom: { foo: 1 } // no change should be fired
|
||||
});
|
||||
model.set({
|
||||
custom: { foo: 2 } // change event should be fired
|
||||
});
|
||||
});
|
||||
|
||||
test("clear", 3, function() {
|
||||
var changed;
|
||||
var model = new Backbone.Model({id: 1, name : "Model"});
|
||||
@@ -242,9 +341,9 @@ $(document).ready(function() {
|
||||
"two": 2
|
||||
}
|
||||
});
|
||||
var model = new Defaulted({two: null});
|
||||
var model = new Defaulted({two: undefined});
|
||||
equal(model.get('one'), 1);
|
||||
equal(model.get('two'), null);
|
||||
equal(model.get('two'), 2);
|
||||
Defaulted = Backbone.Model.extend({
|
||||
defaults: function() {
|
||||
return {
|
||||
@@ -253,14 +352,14 @@ $(document).ready(function() {
|
||||
};
|
||||
}
|
||||
});
|
||||
var model = new Defaulted({two: null});
|
||||
model = new Defaulted({two: undefined});
|
||||
equal(model.get('one'), 3);
|
||||
equal(model.get('two'), null);
|
||||
equal(model.get('two'), 4);
|
||||
});
|
||||
|
||||
test("change, hasChanged, changedAttributes, previous, previousAttributes", 12, function() {
|
||||
var model = new Backbone.Model({name : "Tim", age : 10});
|
||||
equal(model.changedAttributes(), false);
|
||||
test("change, hasChanged, changedAttributes, previous, previousAttributes", 9, function() {
|
||||
var model = new Backbone.Model({name: "Tim", age: 10});
|
||||
deepEqual(model.changedAttributes(), false);
|
||||
model.on('change', function() {
|
||||
ok(model.hasChanged('name'), 'name changed');
|
||||
ok(!model.hasChanged('age'), 'age did not');
|
||||
@@ -270,18 +369,13 @@ $(document).ready(function() {
|
||||
});
|
||||
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();
|
||||
model.set({name : 'Rob'});
|
||||
equal(model.get('name'), 'Rob');
|
||||
|
||||
});
|
||||
|
||||
test("changedAttributes", 3, function() {
|
||||
var model = new Backbone.Model({a: 'a', b: 'b'});
|
||||
equal(model.changedAttributes(), false);
|
||||
deepEqual(model.changedAttributes(), false);
|
||||
equal(model.changedAttributes({a: 'a'}), false);
|
||||
equal(model.changedAttributes({a: 'b'}).a, 'b');
|
||||
});
|
||||
@@ -292,8 +386,7 @@ $(document).ready(function() {
|
||||
model.on('change', function(model, options) {
|
||||
value = options.prefix + model.get('name');
|
||||
});
|
||||
model.set({name: 'Bob'}, {silent: true});
|
||||
model.change({prefix: 'Mr. '});
|
||||
model.set({name: 'Bob'}, {prefix: 'Mr. '});
|
||||
equal(value, 'Mr. Bob');
|
||||
model.set({name: 'Sue'}, {prefix: 'Ms. '});
|
||||
equal(value, 'Ms. Sue');
|
||||
@@ -319,7 +412,7 @@ $(document).ready(function() {
|
||||
model.set({lastName: 'Hicks'});
|
||||
});
|
||||
|
||||
test("validate after save", 1, function() {
|
||||
test("validate after save", 2, function() {
|
||||
var lastError, model = new Backbone.Model();
|
||||
model.validate = function(attrs) {
|
||||
if (attrs.admin) return "Can't change admin status.";
|
||||
@@ -327,23 +420,13 @@ $(document).ready(function() {
|
||||
model.sync = function(method, model, options) {
|
||||
options.success.call(this, {admin: true});
|
||||
};
|
||||
model.save(null, {error: function(model, error) {
|
||||
model.on('invalid', function(model, error) {
|
||||
lastError = error;
|
||||
}});
|
||||
});
|
||||
model.save(null);
|
||||
|
||||
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);
|
||||
equal(model.validationError, "Can't change admin status.");
|
||||
});
|
||||
|
||||
test("save", 2, function() {
|
||||
@@ -352,6 +435,33 @@ $(document).ready(function() {
|
||||
ok(_.isEqual(this.syncArgs.model, doc));
|
||||
});
|
||||
|
||||
test("save, fetch, destroy triggers error event when an error occurs", 3, function () {
|
||||
var model = new Backbone.Model();
|
||||
model.on('error', function () {
|
||||
ok(true);
|
||||
});
|
||||
model.sync = function (method, model, options) {
|
||||
options.error();
|
||||
};
|
||||
model.save({data: 2, id: 1});
|
||||
model.fetch();
|
||||
model.destroy();
|
||||
});
|
||||
|
||||
test("save with PATCH", function() {
|
||||
doc.clear().set({id: 1, a: 1, b: 2, c: 3, d: 4});
|
||||
doc.save();
|
||||
equal(this.syncArgs.method, 'update');
|
||||
equal(this.syncArgs.options.attrs, undefined);
|
||||
|
||||
doc.save({b: 2, d: 4}, {patch: true});
|
||||
equal(this.syncArgs.method, 'patch');
|
||||
equal(_.size(this.syncArgs.options.attrs), 2);
|
||||
equal(this.syncArgs.options.attrs.d, 4);
|
||||
equal(this.syncArgs.options.attrs.a, undefined);
|
||||
equal(this.ajaxSettings.data, "{\"b\":2,\"d\":4}");
|
||||
});
|
||||
|
||||
test("save in positional style", 1, function() {
|
||||
var model = new Backbone.Model();
|
||||
model.sync = function(method, model, options) {
|
||||
@@ -361,7 +471,18 @@ $(document).ready(function() {
|
||||
equal(model.get('title'), 'Twelfth Night');
|
||||
});
|
||||
|
||||
|
||||
test("save with non-object success response", 2, function () {
|
||||
var model = new Backbone.Model();
|
||||
model.sync = function(method, model, options) {
|
||||
options.success('', options);
|
||||
options.success(null, options);
|
||||
};
|
||||
model.save({testing:'empty'}, {
|
||||
success: function (model) {
|
||||
deepEqual(model.attributes, {testing:'empty'});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test("fetch", 2, function() {
|
||||
doc.fetch();
|
||||
@@ -385,22 +506,22 @@ $(document).ready(function() {
|
||||
ok(true, "non-persisted model should not call sync");
|
||||
});
|
||||
|
||||
test("validate", 7, function() {
|
||||
test("validate", 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) {
|
||||
model.on('invalid', 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});
|
||||
result = model.set({admin: true});
|
||||
equal(model.get('admin'), true);
|
||||
result = model.set({a: 200, admin: false});
|
||||
result = model.set({a: 200, admin: false}, {validate:true});
|
||||
equal(lastError, "Can't change admin status.");
|
||||
equal(result, false);
|
||||
equal(model.get('a'), 100);
|
||||
@@ -418,10 +539,10 @@ $(document).ready(function() {
|
||||
model.set({name: "Two"});
|
||||
equal(model.get('name'), 'Two');
|
||||
equal(error, undefined);
|
||||
model.unset('name');
|
||||
model.unset('name', {validate: true});
|
||||
equal(error, true);
|
||||
equal(model.get('name'), 'Two');
|
||||
model.clear();
|
||||
model.clear({validate:true});
|
||||
equal(model.get('name'), 'Two');
|
||||
delete model.validate;
|
||||
model.clear();
|
||||
@@ -434,21 +555,18 @@ $(document).ready(function() {
|
||||
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) {
|
||||
model.on('invalid', function(model, error) {
|
||||
boundError = true;
|
||||
});
|
||||
var result = model.set({a: 100}, {error: callback});
|
||||
var result = model.set({a: 100}, {validate:true});
|
||||
equal(result, model);
|
||||
equal(model.get('a'), 100);
|
||||
equal(lastError, undefined);
|
||||
equal(model.validationError, null);
|
||||
equal(boundError, undefined);
|
||||
result = model.set({a: 200, admin: true}, {error: callback});
|
||||
result = model.set({a: 200, admin: true}, {validate:true});
|
||||
equal(result, false);
|
||||
equal(model.get('a'), 100);
|
||||
equal(lastError, "Can't change admin status.");
|
||||
equal(model.validationError, "Can't change admin status.");
|
||||
equal(boundError, true);
|
||||
});
|
||||
|
||||
@@ -543,9 +661,16 @@ $(document).ready(function() {
|
||||
ok(model.get('x') === a);
|
||||
});
|
||||
|
||||
test("unset fires change for undefined attributes", 1, function() {
|
||||
test("set same value does not trigger change", 0, function() {
|
||||
var model = new Backbone.Model({x: 1});
|
||||
model.on('change change:x', function() { ok(false); });
|
||||
model.set({x: 1});
|
||||
model.set({x: 1});
|
||||
});
|
||||
|
||||
test("unset does not fire a change for undefined attributes", 0, function() {
|
||||
var model = new Backbone.Model({x: undefined});
|
||||
model.on('change:x', function(){ ok(true); });
|
||||
model.on('change:x', function(){ ok(false); });
|
||||
model.unset('x');
|
||||
});
|
||||
|
||||
@@ -554,19 +679,29 @@ $(document).ready(function() {
|
||||
ok('x' in model.attributes);
|
||||
});
|
||||
|
||||
test("change fires change:attr", 1, function() {
|
||||
test("hasChanged works outside of change events, and true within", 6, 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.on('change:x', function() {
|
||||
ok(model.hasChanged('x'));
|
||||
equal(model.get('x'), 1);
|
||||
});
|
||||
model.set({x: 2}, {silent: true});
|
||||
ok(model.hasChanged());
|
||||
model.set({x: 1}, {silent: true});
|
||||
equal(model.hasChanged('x'), true);
|
||||
model.set({x: 1});
|
||||
ok(model.hasChanged());
|
||||
equal(model.hasChanged('x'), true);
|
||||
});
|
||||
|
||||
test("hasChanged gets cleared on the following set", 4, function() {
|
||||
var model = new Backbone.Model;
|
||||
model.set({x: 1});
|
||||
ok(model.hasChanged());
|
||||
model.set({x: 1});
|
||||
ok(!model.hasChanged());
|
||||
model.set({x: 2});
|
||||
ok(model.hasChanged());
|
||||
model.set({});
|
||||
ok(!model.hasChanged());
|
||||
});
|
||||
|
||||
@@ -622,13 +757,20 @@ $(document).ready(function() {
|
||||
equal(model.get('x'), 3);
|
||||
});
|
||||
|
||||
test("save with wait validates attributes", 1, function() {
|
||||
test("save with wait validates attributes", function() {
|
||||
var model = new Backbone.Model();
|
||||
model.url = '/test';
|
||||
model.validate = function() { ok(true); };
|
||||
model.save({x: 1}, {wait: true});
|
||||
});
|
||||
|
||||
test("save turns on parse flag", function () {
|
||||
var Model = Backbone.Model.extend({
|
||||
sync: function(method, model, options) { ok(options.parse); }
|
||||
});
|
||||
new Model().save();
|
||||
});
|
||||
|
||||
test("nested `set` during `'change:attr'`", 2, function() {
|
||||
var events = [];
|
||||
var model = new Backbone.Model();
|
||||
@@ -642,25 +784,19 @@ $(document).ready(function() {
|
||||
model.set({x: true});
|
||||
deepEqual(events, ['change:y', 'change:x', 'change']);
|
||||
events = [];
|
||||
model.change();
|
||||
deepEqual(events, ['change:z', 'change']);
|
||||
model.set({z: true});
|
||||
deepEqual(events, []);
|
||||
});
|
||||
|
||||
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});
|
||||
});
|
||||
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();
|
||||
@@ -672,13 +808,13 @@ $(document).ready(function() {
|
||||
model.set({y: true});
|
||||
break;
|
||||
case 1:
|
||||
deepEqual(this.changedAttributes(), {y: true});
|
||||
equal(model.previous('x'), true);
|
||||
deepEqual(this.changedAttributes(), {x: true, y: true});
|
||||
equal(model.previous('x'), undefined);
|
||||
model.set({z: true});
|
||||
break;
|
||||
case 2:
|
||||
deepEqual(this.changedAttributes(), {z: true});
|
||||
equal(model.previous('y'), true);
|
||||
deepEqual(this.changedAttributes(), {x: true, y: true, z: true});
|
||||
equal(model.previous('y'), undefined);
|
||||
break;
|
||||
default:
|
||||
ok(false);
|
||||
@@ -687,30 +823,34 @@ $(document).ready(function() {
|
||||
model.set({x: true});
|
||||
});
|
||||
|
||||
test("nested `'change'` with silent", 3, function() {
|
||||
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:y', function() { ok(false); });
|
||||
model.on('change', function() {
|
||||
switch(count++) {
|
||||
case 0:
|
||||
deepEqual(this.changedAttributes(), {x: true});
|
||||
model.set({y: true}, {silent: true});
|
||||
model.set({z: true});
|
||||
break;
|
||||
case 1:
|
||||
deepEqual(this.changedAttributes(), {y: true, z: true});
|
||||
deepEqual(this.changedAttributes(), {x: true, y: true, z: true});
|
||||
break;
|
||||
case 2:
|
||||
deepEqual(this.changedAttributes(), {z: false});
|
||||
break;
|
||||
default:
|
||||
ok(false);
|
||||
}
|
||||
});
|
||||
model.set({x: true});
|
||||
model.set({z: true});
|
||||
model.set({z: false});
|
||||
});
|
||||
|
||||
test("nested `'change:attr'` with silent", 1, function() {
|
||||
test("nested `change:attr` with silent", 0, function() {
|
||||
var model = new Backbone.Model();
|
||||
model.on('change:y', function(){ ok(true); });
|
||||
model.on('change:y', function(){ ok(false); });
|
||||
model.on('change', function() {
|
||||
model.set({y: true}, {silent: true});
|
||||
model.set({z: true});
|
||||
@@ -728,21 +868,25 @@ $(document).ready(function() {
|
||||
equal(val, 2);
|
||||
});
|
||||
model.set({x: true});
|
||||
model.change();
|
||||
});
|
||||
|
||||
test("multiple nested changes with silent", 2, function() {
|
||||
test("multiple nested changes with silent", 1, 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, 1]);
|
||||
model.change();
|
||||
deepEqual(changes, [0, 1, 1, 2, 1]);
|
||||
deepEqual(changes, [0, 1]);
|
||||
});
|
||||
|
||||
test("basic silent change semantics", 1, function() {
|
||||
var model = new Backbone.Model;
|
||||
model.set({x: 1});
|
||||
model.on('change', function(){ ok(true); });
|
||||
model.set({x: 2}, {silent: true});
|
||||
model.set({x: 1});
|
||||
});
|
||||
|
||||
test("nested set multiple times", 1, function() {
|
||||
@@ -757,12 +901,6 @@ $(document).ready(function() {
|
||||
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 = {};
|
||||
@@ -794,9 +932,8 @@ $(document).ready(function() {
|
||||
|
||||
test("#1412 - Trigger 'sync' event.", 3, function() {
|
||||
var model = new Backbone.Model({id: 1});
|
||||
model.url = '/test';
|
||||
model.sync = function (method, model, options) { options.success(); };
|
||||
model.on('sync', function(){ ok(true); });
|
||||
Backbone.ajax = function(settings){ settings.success(); };
|
||||
model.fetch();
|
||||
model.save();
|
||||
model.destroy();
|
||||
@@ -816,4 +953,150 @@ $(document).ready(function() {
|
||||
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('invalid', 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 triggers a change.", 1, function() {
|
||||
var model = new Backbone.Model({x:1});
|
||||
model.on('change:x', function() { ok(true); });
|
||||
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.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']);
|
||||
deepEqual(model.attributes, {a: 'c', b: 2});
|
||||
});
|
||||
|
||||
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 triggers 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'});
|
||||
deepEqual(changes, ['a', 'a']);
|
||||
});
|
||||
|
||||
test("#1943 change calculations should use _.isEqual", function() {
|
||||
var model = new Backbone.Model({a: {key: 'value'}});
|
||||
model.set('a', {key:'value'}, {silent:true});
|
||||
equal(model.changedAttributes(), false);
|
||||
});
|
||||
|
||||
test("#1964 - final `change` event is always fired, regardless of interim changes", 1, function () {
|
||||
var model = new Backbone.Model();
|
||||
model.on('change:property', function() {
|
||||
model.set('property', 'bar');
|
||||
});
|
||||
model.on('change', function() {
|
||||
ok(true);
|
||||
});
|
||||
model.set('property', 'foo');
|
||||
});
|
||||
|
||||
test("isValid", 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}, {validate:true}), false);
|
||||
equal(model.isValid(), true);
|
||||
model.set({valid:false});
|
||||
equal(model.isValid(), false);
|
||||
ok(!model.set('valid', false, {validate: 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("#1961 - Creating a model with {validate:true} will call validate and use the error callback", function () {
|
||||
var Model = Backbone.Model.extend({
|
||||
validate: function (attrs) {
|
||||
if (attrs.id === 1) return "This shouldn't happen";
|
||||
}
|
||||
});
|
||||
var model = new Model({id: 1}, {validate: true});
|
||||
equal(model.validationError, "This shouldn't happen");
|
||||
});
|
||||
|
||||
test("toJSON receives attrs during save(..., {wait: true})", 1, function() {
|
||||
var Model = Backbone.Model.extend({
|
||||
url: '/test',
|
||||
toJSON: function() {
|
||||
strictEqual(this.attributes.x, 1);
|
||||
return _.clone(this.attributes);
|
||||
}
|
||||
});
|
||||
var model = new Model;
|
||||
model.save({x: 1}, {wait: true});
|
||||
});
|
||||
|
||||
test("#2034 - nested set with silent only triggers one change", 1, function() {
|
||||
var model = new Backbone.Model();
|
||||
model.on('change', function() {
|
||||
model.set({b: true}, {silent: true});
|
||||
ok(true);
|
||||
});
|
||||
model.set({a: true});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
182
vendor/backbone/test/router.js
vendored
182
vendor/backbone/test/router.js
vendored
@@ -57,6 +57,15 @@ $(document).ready(function() {
|
||||
|
||||
});
|
||||
|
||||
var ExternalObject = {
|
||||
value: 'unset',
|
||||
|
||||
routingFunction: function(value) {
|
||||
this.value = value;
|
||||
}
|
||||
};
|
||||
_.bindAll(ExternalObject);
|
||||
|
||||
var Router = Backbone.Router.extend({
|
||||
|
||||
count: 0,
|
||||
@@ -69,9 +78,15 @@ $(document).ready(function() {
|
||||
"contacts": "contacts",
|
||||
"contacts/new": "newContact",
|
||||
"contacts/:id": "loadContact",
|
||||
"route-event/:arg": "routeEvent",
|
||||
"optional(/:item)": "optionalItem",
|
||||
"named/optional/(y:z)": "namedOptional",
|
||||
"splat/*args/end": "splat",
|
||||
"*first/complex-:part/*rest": "complex",
|
||||
":repo/compare/*from...*to": "github",
|
||||
"decode/:named/*splat": "decode",
|
||||
"*first/complex-*part/*rest": "complex",
|
||||
":entity?*args": "query",
|
||||
"function/:value": ExternalObject.routingFunction,
|
||||
"*anything": "anything"
|
||||
},
|
||||
|
||||
@@ -105,23 +120,45 @@ $(document).ready(function() {
|
||||
this.contact = 'load';
|
||||
},
|
||||
|
||||
splat : function(args) {
|
||||
optionalItem: function(arg){
|
||||
this.arg = arg != void 0 ? arg : null;
|
||||
},
|
||||
|
||||
splat: function(args) {
|
||||
this.args = args;
|
||||
},
|
||||
|
||||
complex : function(first, part, rest) {
|
||||
github: function(repo, from, to) {
|
||||
this.repo = repo;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
},
|
||||
|
||||
complex: function(first, part, rest) {
|
||||
this.first = first;
|
||||
this.part = part;
|
||||
this.rest = rest;
|
||||
},
|
||||
|
||||
query : function(entity, args) {
|
||||
query: function(entity, args) {
|
||||
this.entity = entity;
|
||||
this.queryArgs = args;
|
||||
},
|
||||
|
||||
anything : function(whatever) {
|
||||
anything: function(whatever) {
|
||||
this.anything = whatever;
|
||||
},
|
||||
|
||||
namedOptional: function(z) {
|
||||
this.z = z;
|
||||
},
|
||||
|
||||
decode: function(named, path) {
|
||||
this.named = named;
|
||||
this.path = path;
|
||||
},
|
||||
|
||||
routeEvent: function(arg) {
|
||||
}
|
||||
|
||||
});
|
||||
@@ -134,11 +171,20 @@ $(document).ready(function() {
|
||||
location.replace('http://example.com#search/news');
|
||||
Backbone.history.checkUrl();
|
||||
equal(router.query, 'news');
|
||||
equal(router.page, undefined);
|
||||
equal(router.page, void 0);
|
||||
equal(lastRoute, 'search');
|
||||
equal(lastArgs[0], 'news');
|
||||
});
|
||||
|
||||
test("routes (simple, but unicode)", 4, function() {
|
||||
location.replace('http://example.com#search/тест');
|
||||
Backbone.history.checkUrl();
|
||||
equal(router.query, "тест");
|
||||
equal(router.page, void 0);
|
||||
equal(lastRoute, 'search');
|
||||
equal(lastArgs[0], "тест");
|
||||
});
|
||||
|
||||
test("routes (two part)", 2, function() {
|
||||
location.replace('http://example.com#search/nyc/p10');
|
||||
Backbone.history.checkUrl();
|
||||
@@ -199,6 +245,23 @@ $(document).ready(function() {
|
||||
equal(router.args, 'long-list/of/splatted_99args');
|
||||
});
|
||||
|
||||
test("routes (github)", 3, function() {
|
||||
location.replace('http://example.com#backbone/compare/1.0...braddunbar:with/slash');
|
||||
Backbone.history.checkUrl();
|
||||
equal(router.repo, 'backbone');
|
||||
equal(router.from, '1.0');
|
||||
equal(router.to, 'braddunbar:with/slash');
|
||||
});
|
||||
|
||||
test("routes (optional)", 2, function() {
|
||||
location.replace('http://example.com#optional');
|
||||
Backbone.history.checkUrl();
|
||||
ok(!router.arg);
|
||||
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();
|
||||
@@ -223,6 +286,23 @@ $(document).ready(function() {
|
||||
equal(router.anything, 'doesnt-match-a-route');
|
||||
});
|
||||
|
||||
test("routes (function)", 3, function() {
|
||||
router.on('route', function(name) {
|
||||
ok(name === '');
|
||||
});
|
||||
equal(ExternalObject.value, 'unset');
|
||||
location.replace('http://example.com#function/set');
|
||||
Backbone.history.checkUrl();
|
||||
equal(ExternalObject.value, 'set');
|
||||
});
|
||||
|
||||
test("Decode named parameters, not splats.", 2, function() {
|
||||
location.replace('http://example.com#decode/a%2Fb/c%2Fd/e');
|
||||
Backbone.history.checkUrl();
|
||||
strictEqual(router.named, 'a/b');
|
||||
strictEqual(router.path, 'c/d/e');
|
||||
});
|
||||
|
||||
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');
|
||||
@@ -251,12 +331,12 @@ $(document).ready(function() {
|
||||
if (!Backbone.history.iframe) ok(true);
|
||||
});
|
||||
|
||||
test("route callback gets passed decoded values", 3, function() {
|
||||
test("#967 - Route callback gets passed encoded 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');
|
||||
strictEqual(router.first, 'has/slash');
|
||||
strictEqual(router.part, 'has#hash');
|
||||
strictEqual(router.rest, 'has space');
|
||||
});
|
||||
|
||||
test("correctly handles URLs with % (#868)", 3, function() {
|
||||
@@ -265,7 +345,7 @@ $(document).ready(function() {
|
||||
location.replace('http://example.com#search/fat');
|
||||
Backbone.history.checkUrl();
|
||||
equal(router.query, 'fat');
|
||||
equal(router.page, undefined);
|
||||
equal(router.page, void 0);
|
||||
equal(lastRoute, 'search');
|
||||
});
|
||||
|
||||
@@ -449,4 +529,84 @@ $(document).ready(function() {
|
||||
});
|
||||
});
|
||||
|
||||
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');
|
||||
});
|
||||
|
||||
test("#1980 - Optional parameters.", 2, function() {
|
||||
location.replace('http://example.com#named/optional/y');
|
||||
Backbone.history.checkUrl();
|
||||
strictEqual(router.z, undefined);
|
||||
location.replace('http://example.com#named/optional/y123');
|
||||
Backbone.history.checkUrl();
|
||||
strictEqual(router.z, '123');
|
||||
});
|
||||
|
||||
test("#2062 - Trigger 'route' event on router instance.", 2, function() {
|
||||
router.on('route', function(name, args) {
|
||||
strictEqual(name, 'routeEvent');
|
||||
deepEqual(args, ['x']);
|
||||
});
|
||||
location.replace('http://example.com#route-event/x');
|
||||
Backbone.history.checkUrl();
|
||||
});
|
||||
|
||||
test("#2255 - Extend routes by making routes a function.", 1, function() {
|
||||
var RouterBase = Backbone.Router.extend({
|
||||
routes: function() {
|
||||
return {
|
||||
home: "root",
|
||||
index: "index.html"
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
var RouterExtended = RouterBase.extend({
|
||||
routes: function() {
|
||||
var _super = RouterExtended.__super__.routes;
|
||||
return _.extend(_super(),
|
||||
{ show: "show",
|
||||
search: "search" });
|
||||
}
|
||||
});
|
||||
|
||||
var router = new RouterExtended();
|
||||
deepEqual({home: "root", index: "index.html", show: "show", search: "search"}, router.routes);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
76
vendor/backbone/test/sync.js
vendored
76
vendor/backbone/test/sync.js
vendored
@@ -17,6 +17,11 @@ $(document).ready(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;
|
||||
}
|
||||
|
||||
}));
|
||||
@@ -59,8 +64,10 @@ $(document).ready(function() {
|
||||
});
|
||||
|
||||
test("update with emulateHTTP and emulateJSON", 7, function() {
|
||||
Backbone.emulateHTTP = Backbone.emulateJSON = true;
|
||||
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
|
||||
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');
|
||||
@@ -69,12 +76,12 @@ $(document).ready(function() {
|
||||
equal(data.id, '2-the-tempest');
|
||||
equal(data.author, 'Tim Shakespeare');
|
||||
equal(data.length, 123);
|
||||
Backbone.emulateHTTP = Backbone.emulateJSON = false;
|
||||
});
|
||||
|
||||
test("update with just emulateHTTP", 6, function() {
|
||||
Backbone.emulateHTTP = true;
|
||||
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
|
||||
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');
|
||||
@@ -82,12 +89,12 @@ $(document).ready(function() {
|
||||
equal(data.id, '2-the-tempest');
|
||||
equal(data.author, 'Tim Shakespeare');
|
||||
equal(data.length, 123);
|
||||
Backbone.emulateHTTP = false;
|
||||
});
|
||||
|
||||
test("update with just emulateJSON", 6, function() {
|
||||
Backbone.emulateJSON = true;
|
||||
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
|
||||
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');
|
||||
@@ -95,7 +102,6 @@ $(document).ready(function() {
|
||||
equal(data.id, '2-the-tempest');
|
||||
equal(data.author, 'Tim Shakespeare');
|
||||
equal(data.length, 123);
|
||||
Backbone.emulateJSON = false;
|
||||
});
|
||||
|
||||
test("read model", 3, function() {
|
||||
@@ -116,12 +122,13 @@ $(document).ready(function() {
|
||||
|
||||
test("destroy with emulateHTTP", 3, function() {
|
||||
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
|
||||
Backbone.emulateHTTP = Backbone.emulateJSON = true;
|
||||
library.first().destroy();
|
||||
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"}');
|
||||
Backbone.emulateHTTP = Backbone.emulateJSON = false;
|
||||
});
|
||||
|
||||
test("urlError", 2, function() {
|
||||
@@ -157,4 +164,49 @@ $(document).ready(function() {
|
||||
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);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
9266
vendor/backbone/test/vendor/jquery-1.7.1.js
vendored
9266
vendor/backbone/test/vendor/jquery-1.7.1.js
vendored
File diff suppressed because it is too large
Load Diff
649
vendor/backbone/test/vendor/jslitmus.js
vendored
649
vendor/backbone/test/vendor/jslitmus.js
vendored
@@ -1,649 +0,0 @@
|
||||
// JSLitmus.js
|
||||
//
|
||||
// Copyright (c) 2010, Robert Kieffer, http://broofa.com
|
||||
// Available under MIT license (http://en.wikipedia.org/wiki/MIT_License)
|
||||
|
||||
(function() {
|
||||
// Private methods and state
|
||||
|
||||
// Get platform info but don't go crazy trying to recognize everything
|
||||
// that's out there. This is just for the major platforms and OSes.
|
||||
var platform = 'unknown platform', ua = navigator.userAgent;
|
||||
|
||||
// Detect OS
|
||||
var oses = ['Windows','iPhone OS','(Intel |PPC )?Mac OS X','Linux'].join('|');
|
||||
var pOS = new RegExp('((' + oses + ') [^ \);]*)').test(ua) ? RegExp.$1 : null;
|
||||
if (!pOS) pOS = new RegExp('((' + oses + ')[^ \);]*)').test(ua) ? RegExp.$1 : null;
|
||||
|
||||
// Detect browser
|
||||
var pName = /(Chrome|MSIE|Safari|Opera|Firefox)/.test(ua) ? RegExp.$1 : null;
|
||||
|
||||
// Detect version
|
||||
var vre = new RegExp('(Version|' + pName + ')[ \/]([^ ;]*)');
|
||||
var pVersion = (pName && vre.test(ua)) ? RegExp.$2 : null;
|
||||
var platform = (pOS && pName && pVersion) ? pName + ' ' + pVersion + ' on ' + pOS : 'unknown platform';
|
||||
|
||||
/**
|
||||
* A smattering of methods that are needed to implement the JSLitmus testbed.
|
||||
*/
|
||||
var jsl = {
|
||||
/**
|
||||
* Enhanced version of escape()
|
||||
*/
|
||||
escape: function(s) {
|
||||
s = s.replace(/,/g, '\\,');
|
||||
s = escape(s);
|
||||
s = s.replace(/\+/g, '%2b');
|
||||
s = s.replace(/ /g, '+');
|
||||
return s;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get an element by ID.
|
||||
*/
|
||||
$: function(id) {
|
||||
return document.getElementById(id);
|
||||
},
|
||||
|
||||
/**
|
||||
* Null function
|
||||
*/
|
||||
F: function() {},
|
||||
|
||||
/**
|
||||
* Set the status shown in the UI
|
||||
*/
|
||||
status: function(msg) {
|
||||
var el = jsl.$('jsl_status');
|
||||
if (el) el.innerHTML = msg || '';
|
||||
},
|
||||
|
||||
/**
|
||||
* Convert a number to an abbreviated string like, "15K" or "10M"
|
||||
*/
|
||||
toLabel: function(n) {
|
||||
if (n == Infinity) {
|
||||
return 'Infinity';
|
||||
} else if (n > 1e9) {
|
||||
n = Math.round(n/1e8);
|
||||
return n/10 + 'B';
|
||||
} else if (n > 1e6) {
|
||||
n = Math.round(n/1e5);
|
||||
return n/10 + 'M';
|
||||
} else if (n > 1e3) {
|
||||
n = Math.round(n/1e2);
|
||||
return n/10 + 'K';
|
||||
}
|
||||
return n;
|
||||
},
|
||||
|
||||
/**
|
||||
* Copy properties from src to dst
|
||||
*/
|
||||
extend: function(dst, src) {
|
||||
for (var k in src) dst[k] = src[k]; return dst;
|
||||
},
|
||||
|
||||
/**
|
||||
* Like Array.join(), but for the key-value pairs in an object
|
||||
*/
|
||||
join: function(o, delimit1, delimit2) {
|
||||
if (o.join) return o.join(delimit1); // If it's an array
|
||||
var pairs = [];
|
||||
for (var k in o) pairs.push(k + delimit1 + o[k]);
|
||||
return pairs.join(delimit2);
|
||||
},
|
||||
|
||||
/**
|
||||
* Array#indexOf isn't supported in IE, so we use this as a cross-browser solution
|
||||
*/
|
||||
indexOf: function(arr, o) {
|
||||
if (arr.indexOf) return arr.indexOf(o);
|
||||
for (var i = 0; i < this.length; i++) if (arr[i] === o) return i;
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Test manages a single test (created with
|
||||
* JSLitmus.test())
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
var Test = function (name, f) {
|
||||
if (!f) throw new Error('Undefined test function');
|
||||
if (!/function[^\(]*\(([^,\)]*)/.test(f.toString())) {
|
||||
throw new Error('"' + name + '" test: Test is not a valid Function object');
|
||||
}
|
||||
this.loopArg = RegExp.$1;
|
||||
this.name = name;
|
||||
this.f = f;
|
||||
};
|
||||
|
||||
jsl.extend(Test, /** @lends Test */ {
|
||||
/** Calibration tests for establishing iteration loop overhead */
|
||||
CALIBRATIONS: [
|
||||
new Test('calibrating loop', function(count) {while (count--);}),
|
||||
new Test('calibrating function', jsl.F)
|
||||
],
|
||||
|
||||
/**
|
||||
* Run calibration tests. Returns true if calibrations are not yet
|
||||
* complete (in which case calling code should run the tests yet again).
|
||||
* onCalibrated - Callback to invoke when calibrations have finished
|
||||
*/
|
||||
calibrate: function(onCalibrated) {
|
||||
for (var i = 0; i < Test.CALIBRATIONS.length; i++) {
|
||||
var cal = Test.CALIBRATIONS[i];
|
||||
if (cal.running) return true;
|
||||
if (!cal.count) {
|
||||
cal.isCalibration = true;
|
||||
cal.onStop = onCalibrated;
|
||||
//cal.MIN_TIME = .1; // Do calibrations quickly
|
||||
cal.run(2e4);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
jsl.extend(Test.prototype, {/** @lends Test.prototype */
|
||||
/** Initial number of iterations */
|
||||
INIT_COUNT: 10,
|
||||
/** Max iterations allowed (i.e. used to detect bad looping functions) */
|
||||
MAX_COUNT: 1e9,
|
||||
/** Minimum time a test should take to get valid results (secs) */
|
||||
MIN_TIME: .5,
|
||||
|
||||
/** Callback invoked when test state changes */
|
||||
onChange: jsl.F,
|
||||
|
||||
/** Callback invoked when test is finished */
|
||||
onStop: jsl.F,
|
||||
|
||||
/**
|
||||
* Reset test state
|
||||
*/
|
||||
reset: function() {
|
||||
delete this.count;
|
||||
delete this.time;
|
||||
delete this.running;
|
||||
delete this.error;
|
||||
},
|
||||
|
||||
/**
|
||||
* Run the test (in a timeout). We use a timeout to make sure the browser
|
||||
* has a chance to finish rendering any UI changes we've made, like
|
||||
* updating the status message.
|
||||
*/
|
||||
run: function(count) {
|
||||
count = count || this.INIT_COUNT;
|
||||
jsl.status(this.name + ' x ' + count);
|
||||
this.running = true;
|
||||
var me = this;
|
||||
setTimeout(function() {me._run(count);}, 200);
|
||||
},
|
||||
|
||||
/**
|
||||
* The nuts and bolts code that actually runs a test
|
||||
*/
|
||||
_run: function(count) {
|
||||
var me = this;
|
||||
|
||||
// Make sure calibration tests have run
|
||||
if (!me.isCalibration && Test.calibrate(function() {me.run(count);})) return;
|
||||
this.error = null;
|
||||
|
||||
try {
|
||||
var start, f = this.f, now, i = count;
|
||||
|
||||
// Start the timer
|
||||
start = new Date();
|
||||
|
||||
// Now for the money shot. If this is a looping function ...
|
||||
if (this.loopArg) {
|
||||
// ... let it do the iteration itself
|
||||
f(count);
|
||||
} else {
|
||||
// ... otherwise do the iteration for it
|
||||
while (i--) f();
|
||||
}
|
||||
|
||||
// Get time test took (in secs)
|
||||
this.time = Math.max(1,new Date() - start)/1000;
|
||||
|
||||
// Store iteration count and per-operation time taken
|
||||
this.count = count;
|
||||
this.period = this.time/count;
|
||||
|
||||
// Do we need to do another run?
|
||||
this.running = this.time <= this.MIN_TIME;
|
||||
|
||||
// ... if so, compute how many times we should iterate
|
||||
if (this.running) {
|
||||
// Bump the count to the nearest power of 2
|
||||
var x = this.MIN_TIME/this.time;
|
||||
var pow = Math.pow(2, Math.max(1, Math.ceil(Math.log(x)/Math.log(2))));
|
||||
count *= pow;
|
||||
if (count > this.MAX_COUNT) {
|
||||
throw new Error('Max count exceeded. If this test uses a looping function, make sure the iteration loop is working properly.');
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// Exceptions are caught and displayed in the test UI
|
||||
this.reset();
|
||||
this.error = e;
|
||||
}
|
||||
|
||||
// Figure out what to do next
|
||||
if (this.running) {
|
||||
me.run(count);
|
||||
} else {
|
||||
jsl.status('');
|
||||
me.onStop(me);
|
||||
}
|
||||
|
||||
// Finish up
|
||||
this.onChange(this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the number of operations per second for this test.
|
||||
*
|
||||
* @param normalize if true, iteration loop overhead taken into account
|
||||
*/
|
||||
getHz: function(/**Boolean*/ normalize) {
|
||||
var p = this.period;
|
||||
|
||||
// Adjust period based on the calibration test time
|
||||
if (normalize && !this.isCalibration) {
|
||||
var cal = Test.CALIBRATIONS[this.loopArg ? 0 : 1];
|
||||
|
||||
// If the period is within 20% of the calibration time, then zero the
|
||||
// it out
|
||||
p = p < cal.period*1.2 ? 0 : p - cal.period;
|
||||
}
|
||||
|
||||
return Math.round(1/p);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get a friendly string describing the test
|
||||
*/
|
||||
toString: function() {
|
||||
return this.name + ' - ' + this.time/this.count + ' secs';
|
||||
}
|
||||
});
|
||||
|
||||
// CSS we need for the UI
|
||||
var STYLESHEET = '<style> \
|
||||
#jslitmus {font-family:sans-serif; font-size: 12px;} \
|
||||
#jslitmus a {text-decoration: none;} \
|
||||
#jslitmus a:hover {text-decoration: underline;} \
|
||||
#jsl_status { \
|
||||
margin-top: 10px; \
|
||||
font-size: 10px; \
|
||||
color: #888; \
|
||||
} \
|
||||
A IMG {border:none} \
|
||||
#test_results { \
|
||||
margin-top: 10px; \
|
||||
font-size: 12px; \
|
||||
font-family: sans-serif; \
|
||||
border-collapse: collapse; \
|
||||
border-spacing: 0px; \
|
||||
} \
|
||||
#test_results th, #test_results td { \
|
||||
border: solid 1px #ccc; \
|
||||
vertical-align: top; \
|
||||
padding: 3px; \
|
||||
} \
|
||||
#test_results th { \
|
||||
vertical-align: bottom; \
|
||||
background-color: #ccc; \
|
||||
padding: 1px; \
|
||||
font-size: 10px; \
|
||||
} \
|
||||
#test_results #test_platform { \
|
||||
color: #444; \
|
||||
text-align:center; \
|
||||
} \
|
||||
#test_results .test_row { \
|
||||
color: #006; \
|
||||
cursor: pointer; \
|
||||
} \
|
||||
#test_results .test_nonlooping { \
|
||||
border-left-style: dotted; \
|
||||
border-left-width: 2px; \
|
||||
} \
|
||||
#test_results .test_looping { \
|
||||
border-left-style: solid; \
|
||||
border-left-width: 2px; \
|
||||
} \
|
||||
#test_results .test_name {white-space: nowrap;} \
|
||||
#test_results .test_pending { \
|
||||
} \
|
||||
#test_results .test_running { \
|
||||
font-style: italic; \
|
||||
} \
|
||||
#test_results .test_done {} \
|
||||
#test_results .test_done { \
|
||||
text-align: right; \
|
||||
font-family: monospace; \
|
||||
} \
|
||||
#test_results .test_error {color: #600;} \
|
||||
#test_results .test_error .error_head {font-weight:bold;} \
|
||||
#test_results .test_error .error_body {font-size:85%;} \
|
||||
#test_results .test_row:hover td { \
|
||||
background-color: #ffc; \
|
||||
text-decoration: underline; \
|
||||
} \
|
||||
#chart { \
|
||||
margin: 10px 0px; \
|
||||
width: 250px; \
|
||||
} \
|
||||
#chart img { \
|
||||
border: solid 1px #ccc; \
|
||||
margin-bottom: 5px; \
|
||||
} \
|
||||
#chart #tiny_url { \
|
||||
height: 40px; \
|
||||
width: 250px; \
|
||||
} \
|
||||
#jslitmus_credit { \
|
||||
font-size: 10px; \
|
||||
color: #888; \
|
||||
margin-top: 8px; \
|
||||
} \
|
||||
</style>';
|
||||
|
||||
// HTML markup for the UI
|
||||
var MARKUP = '<div id="jslitmus"> \
|
||||
<button onclick="JSLitmus.runAll(event)">Run Tests</button> \
|
||||
<button id="stop_button" disabled="disabled" onclick="JSLitmus.stop()">Stop Tests</button> \
|
||||
<br \> \
|
||||
<br \> \
|
||||
<input type="checkbox" style="vertical-align: middle" id="test_normalize" checked="checked" onchange="JSLitmus.renderAll()""> Normalize results \
|
||||
<table id="test_results"> \
|
||||
<colgroup> \
|
||||
<col /> \
|
||||
<col width="100" /> \
|
||||
</colgroup> \
|
||||
<tr><th id="test_platform" colspan="2">' + platform + '</th></tr> \
|
||||
<tr><th>Test</th><th>Ops/sec</th></tr> \
|
||||
<tr id="test_row_template" class="test_row" style="display:none"> \
|
||||
<td class="test_name"></td> \
|
||||
<td class="test_result">Ready</td> \
|
||||
</tr> \
|
||||
</table> \
|
||||
<div id="jsl_status"></div> \
|
||||
<div id="chart" style="display:none"> \
|
||||
<a id="chart_link" target="_blank"><img id="chart_image"></a> \
|
||||
TinyURL (for chart): \
|
||||
<iframe id="tiny_url" frameBorder="0" scrolling="no" src=""></iframe> \
|
||||
</div> \
|
||||
<a id="jslitmus_credit" title="JSLitmus home page" href="http://code.google.com/p/jslitmus" target="_blank">Powered by JSLitmus</a> \
|
||||
</div>';
|
||||
|
||||
/**
|
||||
* The public API for creating and running tests
|
||||
*/
|
||||
window.JSLitmus = {
|
||||
/** The list of all tests that have been registered with JSLitmus.test */
|
||||
_tests: [],
|
||||
/** The queue of tests that need to be run */
|
||||
_queue: [],
|
||||
|
||||
/**
|
||||
* The parsed query parameters the current page URL. This is provided as a
|
||||
* convenience for test functions - it's not used by JSLitmus proper
|
||||
*/
|
||||
params: {},
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*/
|
||||
_init: function() {
|
||||
// Parse query params into JSLitmus.params[] hash
|
||||
var match = (location + '').match(/([^?#]*)(#.*)?$/);
|
||||
if (match) {
|
||||
var pairs = match[1].split('&');
|
||||
for (var i = 0; i < pairs.length; i++) {
|
||||
var pair = pairs[i].split('=');
|
||||
if (pair.length > 1) {
|
||||
var key = pair.shift();
|
||||
var value = pair.length > 1 ? pair.join('=') : pair[0];
|
||||
this.params[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Write out the stylesheet. We have to do this here because IE
|
||||
// doesn't honor sheets written after the document has loaded.
|
||||
document.write(STYLESHEET);
|
||||
|
||||
// Setup the rest of the UI once the document is loaded
|
||||
if (window.addEventListener) {
|
||||
window.addEventListener('load', this._setup, false);
|
||||
} else if (document.addEventListener) {
|
||||
document.addEventListener('load', this._setup, false);
|
||||
} else if (window.attachEvent) {
|
||||
window.attachEvent('onload', this._setup);
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Set up the UI
|
||||
*/
|
||||
_setup: function() {
|
||||
var el = jsl.$('jslitmus_container');
|
||||
if (!el) document.body.appendChild(el = document.createElement('div'));
|
||||
|
||||
el.innerHTML = MARKUP;
|
||||
|
||||
// Render the UI for all our tests
|
||||
for (var i=0; i < JSLitmus._tests.length; i++)
|
||||
JSLitmus.renderTest(JSLitmus._tests[i]);
|
||||
},
|
||||
|
||||
/**
|
||||
* (Re)render all the test results
|
||||
*/
|
||||
renderAll: function() {
|
||||
for (var i = 0; i < JSLitmus._tests.length; i++)
|
||||
JSLitmus.renderTest(JSLitmus._tests[i]);
|
||||
JSLitmus.renderChart();
|
||||
},
|
||||
|
||||
/**
|
||||
* (Re)render the chart graphics
|
||||
*/
|
||||
renderChart: function() {
|
||||
var url = JSLitmus.chartUrl();
|
||||
jsl.$('chart_link').href = url;
|
||||
jsl.$('chart_image').src = url;
|
||||
jsl.$('chart').style.display = '';
|
||||
|
||||
// Update the tiny URL
|
||||
jsl.$('tiny_url').src = 'http://tinyurl.com/api-create.php?url='+escape(url);
|
||||
},
|
||||
|
||||
/**
|
||||
* (Re)render the results for a specific test
|
||||
*/
|
||||
renderTest: function(test) {
|
||||
// Make a new row if needed
|
||||
if (!test._row) {
|
||||
var trow = jsl.$('test_row_template');
|
||||
if (!trow) return;
|
||||
|
||||
test._row = trow.cloneNode(true);
|
||||
test._row.style.display = '';
|
||||
test._row.id = '';
|
||||
test._row.onclick = function() {JSLitmus._queueTest(test);};
|
||||
test._row.title = 'Run ' + test.name + ' test';
|
||||
trow.parentNode.appendChild(test._row);
|
||||
test._row.cells[0].innerHTML = test.name;
|
||||
}
|
||||
|
||||
var cell = test._row.cells[1];
|
||||
var cns = [test.loopArg ? 'test_looping' : 'test_nonlooping'];
|
||||
|
||||
if (test.error) {
|
||||
cns.push('test_error');
|
||||
cell.innerHTML =
|
||||
'<div class="error_head">' + test.error + '</div>' +
|
||||
'<ul class="error_body"><li>' +
|
||||
jsl.join(test.error, ': ', '</li><li>') +
|
||||
'</li></ul>';
|
||||
} else {
|
||||
if (test.running) {
|
||||
cns.push('test_running');
|
||||
cell.innerHTML = 'running';
|
||||
} else if (jsl.indexOf(JSLitmus._queue, test) >= 0) {
|
||||
cns.push('test_pending');
|
||||
cell.innerHTML = 'pending';
|
||||
} else if (test.count) {
|
||||
cns.push('test_done');
|
||||
var hz = test.getHz(jsl.$('test_normalize').checked);
|
||||
cell.innerHTML = hz != Infinity ? hz : '∞';
|
||||
cell.title = 'Looped ' + test.count + ' times in ' + test.time + ' seconds';
|
||||
} else {
|
||||
cell.innerHTML = 'ready';
|
||||
}
|
||||
}
|
||||
cell.className = cns.join(' ');
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a new test
|
||||
*/
|
||||
test: function(name, f) {
|
||||
// Create the Test object
|
||||
var test = new Test(name, f);
|
||||
JSLitmus._tests.push(test);
|
||||
|
||||
// Re-render if the test state changes
|
||||
test.onChange = JSLitmus.renderTest;
|
||||
|
||||
// Run the next test if this one finished
|
||||
test.onStop = function(test) {
|
||||
if (JSLitmus.onTestFinish) JSLitmus.onTestFinish(test);
|
||||
JSLitmus.currentTest = null;
|
||||
JSLitmus._nextTest();
|
||||
};
|
||||
|
||||
// Render the new test
|
||||
this.renderTest(test);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add all tests to the run queue
|
||||
*/
|
||||
runAll: function(e) {
|
||||
e = e || window.event;
|
||||
var reverse = e && e.shiftKey, len = JSLitmus._tests.length;
|
||||
for (var i = 0; i < len; i++) {
|
||||
JSLitmus._queueTest(JSLitmus._tests[!reverse ? i : (len - i - 1)]);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove all tests from the run queue. The current test has to finish on
|
||||
* it's own though
|
||||
*/
|
||||
stop: function() {
|
||||
while (JSLitmus._queue.length) {
|
||||
var test = JSLitmus._queue.shift();
|
||||
JSLitmus.renderTest(test);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Run the next test in the run queue
|
||||
*/
|
||||
_nextTest: function() {
|
||||
if (!JSLitmus.currentTest) {
|
||||
var test = JSLitmus._queue.shift();
|
||||
if (test) {
|
||||
jsl.$('stop_button').disabled = false;
|
||||
JSLitmus.currentTest = test;
|
||||
test.run();
|
||||
JSLitmus.renderTest(test);
|
||||
if (JSLitmus.onTestStart) JSLitmus.onTestStart(test);
|
||||
} else {
|
||||
jsl.$('stop_button').disabled = true;
|
||||
JSLitmus.renderChart();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Add a test to the run queue
|
||||
*/
|
||||
_queueTest: function(test) {
|
||||
if (jsl.indexOf(JSLitmus._queue, test) >= 0) return;
|
||||
JSLitmus._queue.push(test);
|
||||
JSLitmus.renderTest(test);
|
||||
JSLitmus._nextTest();
|
||||
},
|
||||
|
||||
/**
|
||||
* Generate a Google Chart URL that shows the data for all tests
|
||||
*/
|
||||
chartUrl: function() {
|
||||
var n = JSLitmus._tests.length, markers = [], data = [];
|
||||
var d, min = 0, max = -1e10;
|
||||
var normalize = jsl.$('test_normalize').checked;
|
||||
|
||||
// Gather test data
|
||||
for (var i=0; i < JSLitmus._tests.length; i++) {
|
||||
var test = JSLitmus._tests[i];
|
||||
if (test.count) {
|
||||
var hz = test.getHz(normalize);
|
||||
var v = hz != Infinity ? hz : 0;
|
||||
data.push(v);
|
||||
markers.push('t' + jsl.escape(test.name + '(' + jsl.toLabel(hz)+ ')') + ',000000,0,' +
|
||||
markers.length + ',10');
|
||||
max = Math.max(v, max);
|
||||
}
|
||||
}
|
||||
if (markers.length <= 0) return null;
|
||||
|
||||
// Build chart title
|
||||
var title = document.getElementsByTagName('title');
|
||||
title = (title && title.length) ? title[0].innerHTML : null;
|
||||
var chart_title = [];
|
||||
if (title) chart_title.push(title);
|
||||
chart_title.push('Ops/sec (' + platform + ')');
|
||||
|
||||
// Build labels
|
||||
var labels = [jsl.toLabel(min), jsl.toLabel(max)];
|
||||
|
||||
var w = 250, bw = 15;
|
||||
var bs = 5;
|
||||
var h = markers.length*(bw + bs) + 30 + chart_title.length*20;
|
||||
|
||||
var params = {
|
||||
chtt: escape(chart_title.join('|')),
|
||||
chts: '000000,10',
|
||||
cht: 'bhg', // chart type
|
||||
chd: 't:' + data.join(','), // data set
|
||||
chds: min + ',' + max, // max/min of data
|
||||
chxt: 'x', // label axes
|
||||
chxl: '0:|' + labels.join('|'), // labels
|
||||
chsp: '0,1',
|
||||
chm: markers.join('|'), // test names
|
||||
chbh: [bw, 0, bs].join(','), // bar widths
|
||||
// chf: 'bg,lg,0,eeeeee,0,eeeeee,.5,ffffff,1', // gradient
|
||||
chs: w + 'x' + h
|
||||
};
|
||||
return 'http://chart.apis.google.com/chart?' + jsl.join(params, '=', '&');
|
||||
}
|
||||
};
|
||||
|
||||
JSLitmus._init();
|
||||
})();
|
||||
481
vendor/backbone/test/vendor/json2.js
vendored
481
vendor/backbone/test/vendor/json2.js
vendored
@@ -1,481 +0,0 @@
|
||||
/*
|
||||
http://www.JSON.org/json2.js
|
||||
2009-09-29
|
||||
|
||||
Public Domain.
|
||||
|
||||
NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
||||
|
||||
See http://www.JSON.org/js.html
|
||||
|
||||
|
||||
This code should be minified before deployment.
|
||||
See http://javascript.crockford.com/jsmin.html
|
||||
|
||||
USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
|
||||
NOT CONTROL.
|
||||
|
||||
|
||||
This file creates a global JSON object containing two methods: stringify
|
||||
and parse.
|
||||
|
||||
JSON.stringify(value, replacer, space)
|
||||
value any JavaScript value, usually an object or array.
|
||||
|
||||
replacer an optional parameter that determines how object
|
||||
values are stringified for objects. It can be a
|
||||
function or an array of strings.
|
||||
|
||||
space an optional parameter that specifies the indentation
|
||||
of nested structures. If it is omitted, the text will
|
||||
be packed without extra whitespace. If it is a number,
|
||||
it will specify the number of spaces to indent at each
|
||||
level. If it is a string (such as '\t' or ' '),
|
||||
it contains the characters used to indent at each level.
|
||||
|
||||
This method produces a JSON text from a JavaScript value.
|
||||
|
||||
When an object value is found, if the object contains a toJSON
|
||||
method, its toJSON method will be called and the result will be
|
||||
stringified. A toJSON method does not serialize: it returns the
|
||||
value represented by the name/value pair that should be serialized,
|
||||
or undefined if nothing should be serialized. The toJSON method
|
||||
will be passed the key associated with the value, and this will be
|
||||
bound to the value
|
||||
|
||||
For example, this would serialize Dates as ISO strings.
|
||||
|
||||
Date.prototype.toJSON = function (key) {
|
||||
function f(n) {
|
||||
// Format integers to have at least two digits.
|
||||
return n < 10 ? '0' + n : n;
|
||||
}
|
||||
|
||||
return this.getUTCFullYear() + '-' +
|
||||
f(this.getUTCMonth() + 1) + '-' +
|
||||
f(this.getUTCDate()) + 'T' +
|
||||
f(this.getUTCHours()) + ':' +
|
||||
f(this.getUTCMinutes()) + ':' +
|
||||
f(this.getUTCSeconds()) + 'Z';
|
||||
};
|
||||
|
||||
You can provide an optional replacer method. It will be passed the
|
||||
key and value of each member, with this bound to the containing
|
||||
object. The value that is returned from your method will be
|
||||
serialized. If your method returns undefined, then the member will
|
||||
be excluded from the serialization.
|
||||
|
||||
If the replacer parameter is an array of strings, then it will be
|
||||
used to select the members to be serialized. It filters the results
|
||||
such that only members with keys listed in the replacer array are
|
||||
stringified.
|
||||
|
||||
Values that do not have JSON representations, such as undefined or
|
||||
functions, will not be serialized. Such values in objects will be
|
||||
dropped; in arrays they will be replaced with null. You can use
|
||||
a replacer function to replace those with JSON values.
|
||||
JSON.stringify(undefined) returns undefined.
|
||||
|
||||
The optional space parameter produces a stringification of the
|
||||
value that is filled with line breaks and indentation to make it
|
||||
easier to read.
|
||||
|
||||
If the space parameter is a non-empty string, then that string will
|
||||
be used for indentation. If the space parameter is a number, then
|
||||
the indentation will be that many spaces.
|
||||
|
||||
Example:
|
||||
|
||||
text = JSON.stringify(['e', {pluribus: 'unum'}]);
|
||||
// text is '["e",{"pluribus":"unum"}]'
|
||||
|
||||
|
||||
text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
|
||||
// text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
|
||||
|
||||
text = JSON.stringify([new Date()], function (key, value) {
|
||||
return this[key] instanceof Date ?
|
||||
'Date(' + this[key] + ')' : value;
|
||||
});
|
||||
// text is '["Date(---current time---)"]'
|
||||
|
||||
|
||||
JSON.parse(text, reviver)
|
||||
This method parses a JSON text to produce an object or array.
|
||||
It can throw a SyntaxError exception.
|
||||
|
||||
The optional reviver parameter is a function that can filter and
|
||||
transform the results. It receives each of the keys and values,
|
||||
and its return value is used instead of the original value.
|
||||
If it returns what it received, then the structure is not modified.
|
||||
If it returns undefined then the member is deleted.
|
||||
|
||||
Example:
|
||||
|
||||
// Parse the text. Values that look like ISO date strings will
|
||||
// be converted to Date objects.
|
||||
|
||||
myData = JSON.parse(text, function (key, value) {
|
||||
var a;
|
||||
if (typeof value === 'string') {
|
||||
a =
|
||||
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
|
||||
if (a) {
|
||||
return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
|
||||
+a[5], +a[6]));
|
||||
}
|
||||
}
|
||||
return value;
|
||||
});
|
||||
|
||||
myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
|
||||
var d;
|
||||
if (typeof value === 'string' &&
|
||||
value.slice(0, 5) === 'Date(' &&
|
||||
value.slice(-1) === ')') {
|
||||
d = new Date(value.slice(5, -1));
|
||||
if (d) {
|
||||
return d;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
});
|
||||
|
||||
|
||||
This is a reference implementation. You are free to copy, modify, or
|
||||
redistribute.
|
||||
*/
|
||||
|
||||
/*jslint evil: true, strict: false */
|
||||
|
||||
/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
|
||||
call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
|
||||
getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
|
||||
lastIndex, length, parse, prototype, push, replace, slice, stringify,
|
||||
test, toJSON, toString, valueOf
|
||||
*/
|
||||
|
||||
|
||||
// Create a JSON object only if one does not already exist. We create the
|
||||
// methods in a closure to avoid creating global variables.
|
||||
|
||||
if (!this.JSON) {
|
||||
this.JSON = {};
|
||||
}
|
||||
|
||||
(function () {
|
||||
|
||||
function f(n) {
|
||||
// Format integers to have at least two digits.
|
||||
return n < 10 ? '0' + n : n;
|
||||
}
|
||||
|
||||
if (typeof Date.prototype.toJSON !== 'function') {
|
||||
|
||||
Date.prototype.toJSON = function (key) {
|
||||
|
||||
return isFinite(this.valueOf()) ?
|
||||
this.getUTCFullYear() + '-' +
|
||||
f(this.getUTCMonth() + 1) + '-' +
|
||||
f(this.getUTCDate()) + 'T' +
|
||||
f(this.getUTCHours()) + ':' +
|
||||
f(this.getUTCMinutes()) + ':' +
|
||||
f(this.getUTCSeconds()) + 'Z' : null;
|
||||
};
|
||||
|
||||
String.prototype.toJSON =
|
||||
Number.prototype.toJSON =
|
||||
Boolean.prototype.toJSON = function (key) {
|
||||
return this.valueOf();
|
||||
};
|
||||
}
|
||||
|
||||
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
|
||||
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
|
||||
gap,
|
||||
indent,
|
||||
meta = { // table of character substitutions
|
||||
'\b': '\\b',
|
||||
'\t': '\\t',
|
||||
'\n': '\\n',
|
||||
'\f': '\\f',
|
||||
'\r': '\\r',
|
||||
'"' : '\\"',
|
||||
'\\': '\\\\'
|
||||
},
|
||||
rep;
|
||||
|
||||
|
||||
function quote(string) {
|
||||
|
||||
// If the string contains no control characters, no quote characters, and no
|
||||
// backslash characters, then we can safely slap some quotes around it.
|
||||
// Otherwise we must also replace the offending characters with safe escape
|
||||
// sequences.
|
||||
|
||||
escapable.lastIndex = 0;
|
||||
return escapable.test(string) ?
|
||||
'"' + string.replace(escapable, function (a) {
|
||||
var c = meta[a];
|
||||
return typeof c === 'string' ? c :
|
||||
'\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
|
||||
}) + '"' :
|
||||
'"' + string + '"';
|
||||
}
|
||||
|
||||
|
||||
function str(key, holder) {
|
||||
|
||||
// Produce a string from holder[key].
|
||||
|
||||
var i, // The loop counter.
|
||||
k, // The member key.
|
||||
v, // The member value.
|
||||
length,
|
||||
mind = gap,
|
||||
partial,
|
||||
value = holder[key];
|
||||
|
||||
// If the value has a toJSON method, call it to obtain a replacement value.
|
||||
|
||||
if (value && typeof value === 'object' &&
|
||||
typeof value.toJSON === 'function') {
|
||||
value = value.toJSON(key);
|
||||
}
|
||||
|
||||
// If we were called with a replacer function, then call the replacer to
|
||||
// obtain a replacement value.
|
||||
|
||||
if (typeof rep === 'function') {
|
||||
value = rep.call(holder, key, value);
|
||||
}
|
||||
|
||||
// What happens next depends on the value's type.
|
||||
|
||||
switch (typeof value) {
|
||||
case 'string':
|
||||
return quote(value);
|
||||
|
||||
case 'number':
|
||||
|
||||
// JSON numbers must be finite. Encode non-finite numbers as null.
|
||||
|
||||
return isFinite(value) ? String(value) : 'null';
|
||||
|
||||
case 'boolean':
|
||||
case 'null':
|
||||
|
||||
// If the value is a boolean or null, convert it to a string. Note:
|
||||
// typeof null does not produce 'null'. The case is included here in
|
||||
// the remote chance that this gets fixed someday.
|
||||
|
||||
return String(value);
|
||||
|
||||
// If the type is 'object', we might be dealing with an object or an array or
|
||||
// null.
|
||||
|
||||
case 'object':
|
||||
|
||||
// Due to a specification blunder in ECMAScript, typeof null is 'object',
|
||||
// so watch out for that case.
|
||||
|
||||
if (!value) {
|
||||
return 'null';
|
||||
}
|
||||
|
||||
// Make an array to hold the partial results of stringifying this object value.
|
||||
|
||||
gap += indent;
|
||||
partial = [];
|
||||
|
||||
// Is the value an array?
|
||||
|
||||
if (Object.prototype.toString.apply(value) === '[object Array]') {
|
||||
|
||||
// The value is an array. Stringify every element. Use null as a placeholder
|
||||
// for non-JSON values.
|
||||
|
||||
length = value.length;
|
||||
for (i = 0; i < length; i += 1) {
|
||||
partial[i] = str(i, value) || 'null';
|
||||
}
|
||||
|
||||
// Join all of the elements together, separated with commas, and wrap them in
|
||||
// brackets.
|
||||
|
||||
v = partial.length === 0 ? '[]' :
|
||||
gap ? '[\n' + gap +
|
||||
partial.join(',\n' + gap) + '\n' +
|
||||
mind + ']' :
|
||||
'[' + partial.join(',') + ']';
|
||||
gap = mind;
|
||||
return v;
|
||||
}
|
||||
|
||||
// If the replacer is an array, use it to select the members to be stringified.
|
||||
|
||||
if (rep && typeof rep === 'object') {
|
||||
length = rep.length;
|
||||
for (i = 0; i < length; i += 1) {
|
||||
k = rep[i];
|
||||
if (typeof k === 'string') {
|
||||
v = str(k, value);
|
||||
if (v) {
|
||||
partial.push(quote(k) + (gap ? ': ' : ':') + v);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
// Otherwise, iterate through all of the keys in the object.
|
||||
|
||||
for (k in value) {
|
||||
if (Object.hasOwnProperty.call(value, k)) {
|
||||
v = str(k, value);
|
||||
if (v) {
|
||||
partial.push(quote(k) + (gap ? ': ' : ':') + v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Join all of the member texts together, separated with commas,
|
||||
// and wrap them in braces.
|
||||
|
||||
v = partial.length === 0 ? '{}' :
|
||||
gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
|
||||
mind + '}' : '{' + partial.join(',') + '}';
|
||||
gap = mind;
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
// If the JSON object does not yet have a stringify method, give it one.
|
||||
|
||||
if (typeof JSON.stringify !== 'function') {
|
||||
JSON.stringify = function (value, replacer, space) {
|
||||
|
||||
// The stringify method takes a value and an optional replacer, and an optional
|
||||
// space parameter, and returns a JSON text. The replacer can be a function
|
||||
// that can replace values, or an array of strings that will select the keys.
|
||||
// A default replacer method can be provided. Use of the space parameter can
|
||||
// produce text that is more easily readable.
|
||||
|
||||
var i;
|
||||
gap = '';
|
||||
indent = '';
|
||||
|
||||
// If the space parameter is a number, make an indent string containing that
|
||||
// many spaces.
|
||||
|
||||
if (typeof space === 'number') {
|
||||
for (i = 0; i < space; i += 1) {
|
||||
indent += ' ';
|
||||
}
|
||||
|
||||
// If the space parameter is a string, it will be used as the indent string.
|
||||
|
||||
} else if (typeof space === 'string') {
|
||||
indent = space;
|
||||
}
|
||||
|
||||
// If there is a replacer, it must be a function or an array.
|
||||
// Otherwise, throw an error.
|
||||
|
||||
rep = replacer;
|
||||
if (replacer && typeof replacer !== 'function' &&
|
||||
(typeof replacer !== 'object' ||
|
||||
typeof replacer.length !== 'number')) {
|
||||
throw new Error('JSON.stringify');
|
||||
}
|
||||
|
||||
// Make a fake root object containing our value under the key of ''.
|
||||
// Return the result of stringifying the value.
|
||||
|
||||
return str('', {'': value});
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// If the JSON object does not yet have a parse method, give it one.
|
||||
|
||||
if (typeof JSON.parse !== 'function') {
|
||||
JSON.parse = function (text, reviver) {
|
||||
|
||||
// The parse method takes a text and an optional reviver function, and returns
|
||||
// a JavaScript value if the text is a valid JSON text.
|
||||
|
||||
var j;
|
||||
|
||||
function walk(holder, key) {
|
||||
|
||||
// The walk method is used to recursively walk the resulting structure so
|
||||
// that modifications can be made.
|
||||
|
||||
var k, v, value = holder[key];
|
||||
if (value && typeof value === 'object') {
|
||||
for (k in value) {
|
||||
if (Object.hasOwnProperty.call(value, k)) {
|
||||
v = walk(value, k);
|
||||
if (v !== undefined) {
|
||||
value[k] = v;
|
||||
} else {
|
||||
delete value[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return reviver.call(holder, key, value);
|
||||
}
|
||||
|
||||
|
||||
// Parsing happens in four stages. In the first stage, we replace certain
|
||||
// Unicode characters with escape sequences. JavaScript handles many characters
|
||||
// incorrectly, either silently deleting them, or treating them as line endings.
|
||||
|
||||
cx.lastIndex = 0;
|
||||
if (cx.test(text)) {
|
||||
text = text.replace(cx, function (a) {
|
||||
return '\\u' +
|
||||
('0000' + a.charCodeAt(0).toString(16)).slice(-4);
|
||||
});
|
||||
}
|
||||
|
||||
// In the second stage, we run the text against regular expressions that look
|
||||
// for non-JSON patterns. We are especially concerned with '()' and 'new'
|
||||
// because they can cause invocation, and '=' because it can cause mutation.
|
||||
// But just to be safe, we want to reject all unexpected forms.
|
||||
|
||||
// We split the second stage into 4 regexp operations in order to work around
|
||||
// crippling inefficiencies in IE's and Safari's regexp engines. First we
|
||||
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
|
||||
// replace all simple value tokens with ']' characters. Third, we delete all
|
||||
// open brackets that follow a colon or comma or that begin the text. Finally,
|
||||
// we look to see that the remaining characters are only whitespace or ']' or
|
||||
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
|
||||
|
||||
if (/^[\],:{}\s]*$/.
|
||||
test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
|
||||
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
|
||||
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
|
||||
|
||||
// In the third stage we use the eval function to compile the text into a
|
||||
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
|
||||
// in JavaScript: it can begin a block or an object literal. We wrap the text
|
||||
// in parens to eliminate the ambiguity.
|
||||
|
||||
j = eval('(' + text + ')');
|
||||
|
||||
// In the optional fourth stage, we recursively walk the new structure, passing
|
||||
// each name/value pair to a reviver function for possible transformation.
|
||||
|
||||
return typeof reviver === 'function' ?
|
||||
walk({'': j}, '') : j;
|
||||
}
|
||||
|
||||
// If the text is not JSON parseable, then a SyntaxError is thrown.
|
||||
|
||||
throw new SyntaxError('JSON.parse');
|
||||
};
|
||||
}
|
||||
}());
|
||||
235
vendor/backbone/test/vendor/qunit.css
vendored
235
vendor/backbone/test/vendor/qunit.css
vendored
@@ -1,235 +0,0 @@
|
||||
/**
|
||||
* 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/backbone/test/vendor/qunit.js
vendored
1977
vendor/backbone/test/vendor/qunit.js
vendored
File diff suppressed because it is too large
Load Diff
102
vendor/backbone/test/view.js
vendored
102
vendor/backbone/test/view.js
vendored
@@ -7,17 +7,20 @@ $(document).ready(function() {
|
||||
setup: function() {
|
||||
view = new Backbone.View({
|
||||
id : 'test-view',
|
||||
className : 'test-view'
|
||||
className : 'test-view',
|
||||
other : 'non-special-option'
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
test("constructor", 4, function() {
|
||||
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() {
|
||||
@@ -26,22 +29,6 @@ $(document).ready(function() {
|
||||
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() {
|
||||
@@ -98,6 +85,13 @@ $(document).ready(function() {
|
||||
equal(view.counter, 3);
|
||||
});
|
||||
|
||||
|
||||
test("delegateEvents ignore undefined methods", 0, function() {
|
||||
var view = new Backbone.View({el: '<p></p>'});
|
||||
view.delegateEvents({'click': 'undefinedMethod'});
|
||||
view.$el.trigger('click');
|
||||
});
|
||||
|
||||
test("undelegateEvents", 6, function() {
|
||||
var counter1 = 0, counter2 = 0;
|
||||
|
||||
@@ -162,6 +156,30 @@ $(document).ready(function() {
|
||||
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: {
|
||||
@@ -283,14 +301,11 @@ $(document).ready(function() {
|
||||
ok(new View().$el.is('p'));
|
||||
});
|
||||
|
||||
test("dispose", 0, function() {
|
||||
test("views stopListening", 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);
|
||||
this.listenTo(this.model, 'all x', function(){ ok(false); }, this);
|
||||
this.listenTo(this.collection, 'all x', function(){ ok(false); }, this);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -299,17 +314,44 @@ $(document).ready(function() {
|
||||
collection: new Backbone.Collection
|
||||
});
|
||||
|
||||
view.dispose();
|
||||
view.stopListening();
|
||||
view.model.trigger('x');
|
||||
view.collection.trigger('x');
|
||||
view.$el.click();
|
||||
});
|
||||
|
||||
test("view#remove calls dispose.", 1, function() {
|
||||
var view = new Backbone.View();
|
||||
test("Provide function for el.", 1, function() {
|
||||
var View = Backbone.View.extend({
|
||||
el: function() {
|
||||
return "<p><a></a></p>";
|
||||
}
|
||||
});
|
||||
|
||||
view.dispose = function() { ok(true); };
|
||||
view.remove();
|
||||
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);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
4
vendor/benchmark.js/LICENSE.txt
vendored
4
vendor/benchmark.js/LICENSE.txt
vendored
@@ -1,4 +1,4 @@
|
||||
Copyright 2010-2012 Mathias Bynens <http://mathiasbynens.be/>
|
||||
Copyright 2010-2013 Mathias Bynens <http://mathiasbynens.be/>
|
||||
Based on JSLitmus.js, copyright Robert Kieffer <http://broofa.com/>
|
||||
Modified by John-David Dalton <http://allyoucanleet.com/>
|
||||
|
||||
@@ -19,4 +19,4 @@ 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.
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
26
vendor/benchmark.js/README.md
vendored
26
vendor/benchmark.js/README.md
vendored
@@ -15,13 +15,16 @@ For a list of upcoming features, check out our [roadmap](https://github.com/best
|
||||
|
||||
## 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.
|
||||
Benchmark.js has been tested in at least Chrome 5~25, Firefox 1~19, IE 6-10, Opera 9.25-12, Safari 3-6, Node.js 0.4.8-0.10.1, Narwhal 0.3.2, PhantomJS 1.8.1, RingoJS 0.9, and Rhino 1.7RC5.
|
||||
|
||||
## Installation and usage
|
||||
|
||||
In a browser or Adobe AIR:
|
||||
Benchmark.js’ only hard dependency is [Lo-Dash](http://lodash.com/).
|
||||
|
||||
In a browser:
|
||||
|
||||
```html
|
||||
<script src="lodash.js"></script>
|
||||
<script src="benchmark.js"></script>
|
||||
```
|
||||
|
||||
@@ -68,25 +71,14 @@ 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',
|
||||
'lodash': 'path/to/lodash',
|
||||
'platform': 'path/to/platform'
|
||||
}
|
||||
},
|
||||
['benchmark', 'platform'], function(Benchmark, platform) {
|
||||
Benchmark.platform = platform;
|
||||
['benchmark'], function(Benchmark) {
|
||||
console.log(Benchmark.platform.name);
|
||||
});
|
||||
```
|
||||
@@ -108,7 +100,7 @@ suite.add('RegExp#test', function() {
|
||||
console.log(String(event.target));
|
||||
})
|
||||
.on('complete', function() {
|
||||
console.log('Fastest is ' + this.filter('fastest').pluck('name'));
|
||||
console.log('Fastest is ' + _.pluck(this.filter('fastest'), 'name'));
|
||||
})
|
||||
// run async
|
||||
.run({ 'async': true });
|
||||
@@ -121,7 +113,7 @@ suite.add('RegExp#test', function() {
|
||||
|
||||
## 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.
|
||||
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
|
||||
|
||||
|
||||
6434
vendor/benchmark.js/benchmark.js
vendored
6434
vendor/benchmark.js/benchmark.js
vendored
File diff suppressed because it is too large
Load Diff
2
vendor/docdown/LICENSE.txt
vendored
2
vendor/docdown/LICENSE.txt
vendored
@@ -1,4 +1,4 @@
|
||||
Copyright 2011-2012 John-David Dalton <http://allyoucanleet.com/>
|
||||
Copyright 2011-2013 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
|
||||
|
||||
4
vendor/docdown/docdown.php
vendored
4
vendor/docdown/docdown.php
vendored
@@ -1,14 +1,14 @@
|
||||
<?php
|
||||
/*!
|
||||
* Docdown v1.0.0-pre
|
||||
* Copyright 2011-2012 John-David Dalton <http://allyoucanleet.com/>
|
||||
* Copyright 2011-2013 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
|
||||
|
||||
132
vendor/docdown/src/DocDown/Alias.php
vendored
132
vendor/docdown/src/DocDown/Alias.php
vendored
@@ -22,21 +22,23 @@ class Alias {
|
||||
* @param {String} $name The alias name.
|
||||
* @param {Object} $owner The alias owner.
|
||||
*/
|
||||
public function __construct($name, $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->_isCtor = $owner->isCtor();
|
||||
$this->_isLicense = $owner->isLicense();
|
||||
$this->_isPlugin = $owner->isPlugin();
|
||||
$this->_isPrivate = $owner->isPrivate();
|
||||
$this->_isStatic = $owner->isStatic();
|
||||
$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();
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -65,6 +67,16 @@ class Alias {
|
||||
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.
|
||||
*
|
||||
@@ -85,6 +97,66 @@ class Alias {
|
||||
return $this->_example;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 a license.
|
||||
*
|
||||
* @memberOf Alias
|
||||
* @returns {Boolean} Returns `true` if a license, else `false`.
|
||||
*/
|
||||
public function isLicense() {
|
||||
return $this->_isLicense;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the owner entry's line number.
|
||||
*
|
||||
@@ -150,55 +222,5 @@ class Alias {
|
||||
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;
|
||||
}
|
||||
}
|
||||
?>
|
||||
201
vendor/docdown/src/DocDown/Entry.php
vendored
201
vendor/docdown/src/DocDown/Entry.php
vendored
@@ -152,6 +152,27 @@ class Entry {
|
||||
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.
|
||||
*
|
||||
@@ -166,7 +187,10 @@ class Entry {
|
||||
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 = preg_replace('/:\n *\* */', ":<br>\n", $result[1]);
|
||||
$result = preg_replace('/(?:^|\n) *\*\n *\* */', "\n\n", $result);
|
||||
$result = preg_replace('/(?:^|\n) *\* ?/', ' ', $result);
|
||||
$result = trim($result);
|
||||
$result = ($type == 'Function' ? '' : '(' . str_replace('|', ', ', trim($type, '{}')) . '): ') . $result;
|
||||
}
|
||||
$this->_desc = $result;
|
||||
@@ -193,6 +217,100 @@ class Entry {
|
||||
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 a license.
|
||||
*
|
||||
* @memberOf Entry
|
||||
* @returns {Boolean} Returns `true` if a license, else `false`.
|
||||
*/
|
||||
public function isLicense() {
|
||||
if (!isset($this->_isLicense)) {
|
||||
$this->_isLicense = !!preg_match('/\* *@license\b/', $this->entry);
|
||||
}
|
||||
return $this->_isLicense;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = $this->isLicense() || !!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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the entry's line number.
|
||||
*
|
||||
@@ -320,86 +438,5 @@ class Entry {
|
||||
$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;
|
||||
}
|
||||
}
|
||||
?>
|
||||
348
vendor/docdown/src/DocDown/Generator.php
vendored
348
vendor/docdown/src/DocDown/Generator.php
vendored
@@ -7,6 +7,15 @@ require(dirname(__FILE__) . "/Entry.php");
|
||||
*/
|
||||
class Generator {
|
||||
|
||||
/**
|
||||
* The HTML for the close tag.
|
||||
*
|
||||
* @static
|
||||
* @memberOf Generator
|
||||
* @type String
|
||||
*/
|
||||
public $closeTag = "\n<!-- /div -->\n";
|
||||
|
||||
/**
|
||||
* An array of JSDoc entries.
|
||||
*
|
||||
@@ -15,6 +24,15 @@ class Generator {
|
||||
*/
|
||||
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.
|
||||
*
|
||||
@@ -24,7 +42,7 @@ class Generator {
|
||||
public $options = array();
|
||||
|
||||
/**
|
||||
* The entire file's source code.
|
||||
* The file's source code.
|
||||
*
|
||||
* @memberOf Generator
|
||||
* @type String
|
||||
@@ -65,6 +83,9 @@ class Generator {
|
||||
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']);
|
||||
@@ -86,7 +107,7 @@ class Generator {
|
||||
* @param {String} $string The string to format.
|
||||
* @returns {String} The formatted string.
|
||||
*/
|
||||
private static function format($string) {
|
||||
private static function format( $string ) {
|
||||
$counter = 0;
|
||||
|
||||
// tokenize inline code snippets
|
||||
@@ -121,7 +142,7 @@ class Generator {
|
||||
* @param {Array|Object} $object The template object.
|
||||
* @returns {String} The modified string.
|
||||
*/
|
||||
private static function interpolate($string, $object) {
|
||||
private static function interpolate( $string, $object ) {
|
||||
preg_match_all('/#\{([^}]+)\}/', $string, $tokens);
|
||||
$tokens = array_unique(array_pop($tokens));
|
||||
|
||||
@@ -149,6 +170,63 @@ class Generator {
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* 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> [Ⓢ](#{href} \"View in source\") [Ⓣ][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.
|
||||
*
|
||||
@@ -204,9 +282,11 @@ class Generator {
|
||||
*/
|
||||
public function generate() {
|
||||
$api = array();
|
||||
$byCategory = $this->options['toc'] == 'categories';
|
||||
$categories = array();
|
||||
$closeTag = $this->closeTag;
|
||||
$compiling = false;
|
||||
$openTag = "\n<!-- div -->\n";
|
||||
$closeTag = "\n<!-- /div -->\n";
|
||||
$openTag = $this->openTag;
|
||||
$result = array('# ' . $this->options['title']);
|
||||
$toc = 'toc';
|
||||
|
||||
@@ -223,14 +303,14 @@ class Generator {
|
||||
|
||||
foreach ($members as $member) {
|
||||
// create api category arrays
|
||||
if (!isset($api[$member]) && $member) {
|
||||
if ($member && !isset($api[$member])) {
|
||||
// create temporary entry to be replaced later
|
||||
$api[$member] = new Entry('', '', $entry->lang);
|
||||
$api[$member] = new stdClass;
|
||||
$api[$member]->static = array();
|
||||
$api[$member]->plugin = array();
|
||||
}
|
||||
|
||||
// append entry to api category
|
||||
// append entry to api member
|
||||
if (!$member || $entry->isCtor() || ($entry->getType() == 'Object' &&
|
||||
!preg_match('/[=:]\s*(?:null|undefined)\s*[,;]?$/', $entry->entry))) {
|
||||
|
||||
@@ -261,6 +341,26 @@ class Generator {
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
@@ -268,19 +368,19 @@ class Generator {
|
||||
function sortCompare($a, $b) {
|
||||
$score = array( 'a' => 0, 'b' => 0);
|
||||
foreach (array( 'a' => $a, 'b' => $b) as $key => $value) {
|
||||
// capitalized keys that represent constructor properties are last
|
||||
// capitalized properties are last
|
||||
if (preg_match('/[#.][A-Z]/', $value)) {
|
||||
$score[$key] = 0;
|
||||
}
|
||||
// lowercase keys with prototype properties are next to last
|
||||
// lowercase prototype properties are next to last
|
||||
else if (preg_match('/#[a-z]/', $value)) {
|
||||
$score[$key] = 1;
|
||||
}
|
||||
// lowercase keys with static properties next to first
|
||||
// lowercase static properties next to first
|
||||
else if (preg_match('/\.[a-z]/', $value)) {
|
||||
$score[$key] = 2;
|
||||
}
|
||||
// lowercase keys with no properties are first
|
||||
// root properties are first
|
||||
else if (preg_match('/^[^#.]+$/', $value)) {
|
||||
$score[$key] = 3;
|
||||
}
|
||||
@@ -310,48 +410,90 @@ class Generator {
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
// 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;
|
||||
|
||||
foreach ($api as $key => $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);
|
||||
|
||||
$compiling = $compiling ? ($result[] = $closeTag) : true;
|
||||
|
||||
// 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`' : '`')
|
||||
);
|
||||
// compile TOC by categories
|
||||
if ($byCategory) {
|
||||
foreach ($categories as $category => $entries) {
|
||||
if ($compiling) {
|
||||
$result[] = $closeTag;
|
||||
} else {
|
||||
$compiling = true;
|
||||
}
|
||||
foreach ($entry->{$kind} as $subentry) {
|
||||
$subentry->hash = $this->getHash($subentry);
|
||||
$subentry->href = $this->getLineUrl($subentry);
|
||||
$subentry->member = $member;
|
||||
$subentry->separator = $this->getSeparator($subentry);
|
||||
$result[] = Generator::interpolate('* [`#{member}#{separator}#{name}`](##{hash})', $subentry);
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -364,81 +506,51 @@ class Generator {
|
||||
$compiling = false;
|
||||
$result[] = $openTag;
|
||||
|
||||
foreach ($api as $entry) {
|
||||
// skip aliases
|
||||
if ($entry->isAlias()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// add root entry
|
||||
$member = $entry->member . $entry->getName();
|
||||
$compiling = $compiling ? ($result[] = $closeTag) : true;
|
||||
|
||||
array_push($result, $openTag, '## `' . $member . '`');
|
||||
|
||||
foreach (array($entry, 'static', 'plugin') as $kind) {
|
||||
$subentries = is_string($kind) ? $entry->{$kind} : array($kind);
|
||||
|
||||
// title
|
||||
if ($kind != 'static' && $entry->getType() != 'Object' &&
|
||||
count($subentries) && $subentries[0] != $kind) {
|
||||
if ($kind == 'plugin') {
|
||||
$result[] = $closeTag;
|
||||
}
|
||||
array_push(
|
||||
$result,
|
||||
$openTag,
|
||||
'## `' . $member . ($kind == 'plugin' ? '.prototype`' : '`')
|
||||
);
|
||||
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 . '`');
|
||||
|
||||
// body
|
||||
foreach ($subentries as $subentry) {
|
||||
// skip aliases
|
||||
if ($subentry->isAlias()) {
|
||||
continue;
|
||||
}
|
||||
foreach (array($entry, 'static', 'plugin') as $kind) {
|
||||
$subentries = is_string($kind) ? $entry->{$kind} : array($kind);
|
||||
|
||||
// description
|
||||
array_push(
|
||||
$result,
|
||||
$openTag,
|
||||
Generator::interpolate("### <a id=\"#{hash}\"></a>`#{member}#{separator}#{call}`\n<a href=\"##{hash}\">#</a> [Ⓢ](#{href} \"View in source\") [Ⓣ][1]\n\n#{desc}", $subentry)
|
||||
);
|
||||
|
||||
// @alias
|
||||
if (count($aliases = $subentry->getAliases())) {
|
||||
array_push($result, '', '#### Aliases');
|
||||
foreach ($aliases as $index => $alias) {
|
||||
$aliases[$index] = $alias->getName();
|
||||
// add sub-entry name
|
||||
if ($kind != 'static' && $entry->getType() != 'Object' &&
|
||||
count($subentries) && $subentries[0] != $kind) {
|
||||
if ($kind == 'plugin') {
|
||||
$result[] = $closeTag;
|
||||
}
|
||||
$result[] = '*' . implode(', ', $aliases) . '*';
|
||||
}
|
||||
// @param
|
||||
if (count($params = $subentry->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 = $subentry->getReturns())) {
|
||||
array_push(
|
||||
$result, '',
|
||||
'#### Returns',
|
||||
Generator::interpolate('(#{type}): #{desc}', array('desc' => $returns[1], 'type' => $returns[0]))
|
||||
$result,
|
||||
$openTag,
|
||||
'## `' . $member . ($kind == 'plugin' ? '.prototype`' : '`')
|
||||
);
|
||||
}
|
||||
// @example
|
||||
if ($example = $subentry->getExample()) {
|
||||
array_push($result, '', '#### Example', $example);
|
||||
}
|
||||
array_push($result, "\n* * *", $closeTag);
|
||||
$this->addEntries($result, $subentries);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1049
vendor/firebug-lite/changelog.txt
vendored
1049
vendor/firebug-lite/changelog.txt
vendored
File diff suppressed because it is too large
Load Diff
662
vendor/firebug-lite/skin/xp/debugger.css
vendored
662
vendor/firebug-lite/skin/xp/debugger.css
vendored
@@ -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;
|
||||
}
|
||||
|
||||
1634
vendor/firebug-lite/skin/xp/firebug-1.3a2.css
vendored
1634
vendor/firebug-lite/skin/xp/firebug-1.3a2.css
vendored
File diff suppressed because it is too large
Load Diff
40
vendor/firebug-lite/skin/xp/firebug.IE6.css
vendored
40
vendor/firebug-lite/skin/xp/firebug.IE6.css
vendored
@@ -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;
|
||||
}
|
||||
|
||||
6294
vendor/firebug-lite/skin/xp/firebug.css
vendored
6294
vendor/firebug-lite/skin/xp/firebug.css
vendored
File diff suppressed because it is too large
Load Diff
428
vendor/firebug-lite/skin/xp/firebug.html
vendored
428
vendor/firebug-lite/skin/xp/firebug.html
vendored
@@ -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"> </a>
|
||||
<a id="fbWindow_btDetach" class="fbSmallButton fbHover" title="Open Firebug in popup window"> </a>
|
||||
<a id="fbWindow_btClose" class="fbSmallButton fbHover" title="Minimize Firebug"> </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"> </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"> </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"> </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">>>></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"> </a>
|
||||
<a id="fbWindow_btDetach" class="fbSmallButton fbHover" title="Open Firebug in popup window"> </a>
|
||||
<a id="fbWindow_btClose" class="fbSmallButton fbHover" title="Minimize Firebug"> </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"> </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"> </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"> </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">>>></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>
|
||||
542
vendor/firebug-lite/skin/xp/html.css
vendored
542
vendor/firebug-lite/skin/xp/html.css
vendored
@@ -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;
|
||||
}
|
||||
12
vendor/firebug-lite/skin/xp/roundCorner.svg
vendored
12
vendor/firebug-lite/skin/xp/roundCorner.svg
vendored
@@ -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
21
vendor/jquery/MIT-LICENSE.txt
vendored
Normal 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
417
vendor/jquery/README.md
vendored
Normal 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.
|
||||
File diff suppressed because it is too large
Load Diff
20
vendor/json3/LICENSE
vendored
Normal file
20
vendor/json3/LICENSE
vendored
Normal 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
124
vendor/json3/README.md
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
# JSON 3 #
|
||||
|
||||

|
||||
|
||||
**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
783
vendor/json3/lib/json3.js
vendored
Normal 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);
|
||||
2
vendor/platform.js/LICENSE.txt
vendored
2
vendor/platform.js/LICENSE.txt
vendored
@@ -1,4 +1,4 @@
|
||||
Copyright 2011-2012 John-David Dalton <http://allyoucanleet.com/>
|
||||
Copyright 2011-2013 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
|
||||
|
||||
4
vendor/platform.js/README.md
vendored
4
vendor/platform.js/README.md
vendored
@@ -8,7 +8,7 @@ Platform.js is for informational purposes only and **not** intended as a substit
|
||||
|
||||
## 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.
|
||||
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
|
||||
|
||||
@@ -18,7 +18,7 @@ For a list of upcoming features, check out our [roadmap](https://github.com/best
|
||||
|
||||
## 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.
|
||||
Platform.js has been tested in at least Chrome 5~25, Firefox 1~19, IE 6-10, Opera 9.25-12, Safari 3-6, Node.js 0.4.8-0.10.1, Narwhal 0.3.2, PhantomJS 1.8.1, RingoJS 0.9, and Rhino 1.7RC5.
|
||||
|
||||
## Installation and usage
|
||||
|
||||
|
||||
55
vendor/platform.js/platform.js
vendored
55
vendor/platform.js/platform.js
vendored
@@ -1,6 +1,6 @@
|
||||
/*!
|
||||
* Platform.js v1.0.0 <http://mths.be/platform>
|
||||
* Copyright 2010-2012 John-David Dalton <http://allyoucanleet.com/>
|
||||
* Copyright 2010-2013 John-David Dalton <http://allyoucanleet.com/>
|
||||
* Available under MIT license <http://mths.be/mit>
|
||||
*/
|
||||
;(function(window) {
|
||||
@@ -20,11 +20,14 @@
|
||||
var reOpera = /Opera/;
|
||||
|
||||
/** Used to resolve a value's internal [[Class]] */
|
||||
var toString = {}.toString;
|
||||
var toString = Object.prototype.toString;
|
||||
|
||||
/** Detect Java environment */
|
||||
var java = /Java/.test(getClassOf(window.java)) && window.java;
|
||||
|
||||
/** Detect Rhino */
|
||||
var rhino = java && getClassOf(window.environment) == 'Environment';
|
||||
|
||||
/** A character to represent alpha */
|
||||
var alpha = java ? 'a' : '\u03b1';
|
||||
|
||||
@@ -581,10 +584,11 @@
|
||||
// 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')) {
|
||||
} 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
|
||||
@@ -597,7 +601,7 @@
|
||||
arch = data.getProperty('os.arch');
|
||||
os = os || data.getProperty('os.name') + ' ' + data.getProperty('os.version');
|
||||
}
|
||||
if (typeof exports == 'object' && exports) {
|
||||
if (freeExports) {
|
||||
// if `thisBinding` is the [ModuleScope]
|
||||
if (thisBinding == oldWin && typeof system == 'object' && (data = [system])[0]) {
|
||||
os || (os = data[0].os || null);
|
||||
@@ -610,23 +614,28 @@
|
||||
name = 'Narwhal';
|
||||
}
|
||||
}
|
||||
} else if (typeof process == 'object' && (data = process)) {
|
||||
}
|
||||
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') {
|
||||
else if (rhino) {
|
||||
name = 'Rhino';
|
||||
}
|
||||
}
|
||||
else if (rhino) {
|
||||
name = 'Rhino';
|
||||
}
|
||||
}
|
||||
// detect Adobe AIR
|
||||
else if (getClassOf(data = window.runtime) == 'ScriptBridgingProxyObject') {
|
||||
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') {
|
||||
else if (getClassOf((data = window.phantom)) == 'RuntimeObject') {
|
||||
name = 'PhantomJS';
|
||||
version = (data = data.version || null) && (data.major + '.' + data.minor + '.' + data.patch);
|
||||
}
|
||||
@@ -646,9 +655,10 @@
|
||||
}
|
||||
// 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')) {
|
||||
/(?:[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) || '');
|
||||
@@ -689,8 +699,9 @@
|
||||
// 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)) {
|
||||
(RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] ||
|
||||
version
|
||||
)) {
|
||||
os = 'Device Software ' + data;
|
||||
version = null;
|
||||
}
|
||||
@@ -705,7 +716,7 @@
|
||||
/Windows XP/.test(os) && version > 8 ||
|
||||
version == 8 && !/Trident/.test(ua)
|
||||
))
|
||||
) && !reOpera.test(data = parse.call(forOwn, ua.replace(reOpera, '') + ';')) && data.name) {
|
||||
) && !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 : '');
|
||||
@@ -793,7 +804,7 @@
|
||||
}
|
||||
}
|
||||
// strip incorrect OS versions
|
||||
if (version && version.indexOf(data = /[\d.]+$/.exec(os)) == 0 &&
|
||||
if (version && version.indexOf((data = /[\d.]+$/.exec(os))) == 0 &&
|
||||
ua.indexOf('/' + data + '-') > -1) {
|
||||
os = trim(os.replace(data, ''));
|
||||
}
|
||||
@@ -885,7 +896,7 @@
|
||||
* The CPU architecture the OS is built for.
|
||||
*
|
||||
* @memberOf platform.os
|
||||
* @type String|Null
|
||||
* @type Number|Null
|
||||
*/
|
||||
'architecture': null,
|
||||
|
||||
@@ -981,7 +992,7 @@
|
||||
});
|
||||
}
|
||||
// check for `exports` after `define` in case a build optimizer adds an `exports` object
|
||||
else if (freeExports) {
|
||||
else if (freeExports && !freeExports.nodeType) {
|
||||
// in Narwhal, Node.js, or RingoJS
|
||||
forOwn(parse(), function(value, key) {
|
||||
freeExports[key] = value;
|
||||
@@ -989,8 +1000,6 @@
|
||||
}
|
||||
// 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();
|
||||
window.platform = parse();
|
||||
}
|
||||
}(this));
|
||||
|
||||
2
vendor/qunit-clib/LICENSE.txt
vendored
2
vendor/qunit-clib/LICENSE.txt
vendored
@@ -1,4 +1,4 @@
|
||||
Copyright 2011-2012 John-David Dalton <http://allyoucanleet.com/>
|
||||
Copyright 2011-2013 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
|
||||
|
||||
32
vendor/qunit-clib/README.md
vendored
32
vendor/qunit-clib/README.md
vendored
@@ -1,7 +1,7 @@
|
||||
# QUnit CLIB <sup>v1.0.0</sup>
|
||||
# QUnit CLIB <sup>v1.3.0</sup>
|
||||
## command-line interface boilerplate
|
||||
|
||||
QUnit CLIB helps extend QUnit's CLI support to many common CLI environments.
|
||||
QUnit CLIB helps extend QUnit’s CLI support to many common CLI environments.
|
||||
|
||||
## Screenshot
|
||||
|
||||
@@ -9,25 +9,29 @@ QUnit CLIB helps extend QUnit's CLI support to many common CLI environments.
|
||||
|
||||
## 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.
|
||||
QUnit CLIB has been tested in at least Node.js 0.4.8-0.10.1, Narwhal 0.3.2, PhantomJS 1.8.1, RingoJS 0.9, and Rhino 1.7RC5.
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
(function(window) {
|
||||
;(function(window) {
|
||||
'use strict';
|
||||
|
||||
// use a single load function
|
||||
// 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,
|
||||
var QUnit = (function() {
|
||||
var noop = Function.prototype;
|
||||
return window.QUnit || (
|
||||
window.addEventListener || (window.addEventListener = noop),
|
||||
window.setTimeout || (window.setTimeout = noop),
|
||||
window.QUnit = load('../vendor/qunit/qunit/qunit.js') || window.QUnit,
|
||||
(load('../vendor/qunit-clib/qunit-clib.js') || { 'runInContext': noop }).runInContext(window),
|
||||
addEventListener === noop && delete window.addEventListener,
|
||||
window.QUnit
|
||||
);
|
||||
}());
|
||||
|
||||
// explicitly call `QUnit.module()` instead of `module()`
|
||||
// in case we are in a CLI environment
|
||||
@@ -37,9 +41,8 @@ QUnit CLIB has been tested in at least Node.js 0.4.8-0.8.6, Narwhal v0.3.2, Ring
|
||||
// ...
|
||||
});
|
||||
|
||||
// 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) {
|
||||
// call `QUnit.start()` for Narwhal, Node.js, PhantomJS, Rhino, and RingoJS
|
||||
if (!window.document || window.phantom) {
|
||||
QUnit.start();
|
||||
}
|
||||
}(typeof global == 'object' && global || this));
|
||||
@@ -48,7 +51,6 @@ QUnit CLIB has been tested in at least Node.js 0.4.8-0.8.6, Narwhal v0.3.2, Ring
|
||||
## 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
|
||||
|
||||
566
vendor/qunit-clib/qunit-clib.js
vendored
566
vendor/qunit-clib/qunit-clib.js
vendored
@@ -1,324 +1,292 @@
|
||||
/*!
|
||||
* QUnit CLI Boilerplate v1.0.0
|
||||
* QUnit CLI Boilerplate v1.3.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) {
|
||||
;(function(window) {
|
||||
'use strict';
|
||||
|
||||
/** Add `console.log()` support for Narwhal, Rhino, and RingoJS */
|
||||
global.console || (global.console = { 'log': global.print });
|
||||
/** Detect free variable `exports` */
|
||||
var freeExports = typeof exports == 'object' && exports;
|
||||
|
||||
/** 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]';
|
||||
/** Detect free variable `global` and use it as `window` */
|
||||
var freeGlobal = typeof global == 'object' && global;
|
||||
if (freeGlobal.global === freeGlobal) {
|
||||
window = freeGlobal;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* 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`.
|
||||
* Installs the CLI boilerplate additions on the given `context` object.
|
||||
*
|
||||
* @memberOf global
|
||||
* @param {Number} id The ID of the timeout to be cleared.
|
||||
* @memberOf exports
|
||||
* @param {Object} context The context object.
|
||||
*/
|
||||
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) {
|
||||
function runInContext(context) {
|
||||
// exit early if no `context` is provided or if `QUnit` does not exist
|
||||
if (!context || !context.QUnit) {
|
||||
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);
|
||||
/**
|
||||
* Schedules timer-based callbacks.
|
||||
*
|
||||
* @private
|
||||
* @param {Function|String} 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(context, args);
|
||||
}
|
||||
});
|
||||
// support non-functions
|
||||
if (typeof fn != 'function') {
|
||||
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;
|
||||
}
|
||||
else {
|
||||
console.log(' PASS - ' + testName);
|
||||
|
||||
/**
|
||||
* Clears the delay set by `setInterval` or `setTimeout`.
|
||||
*
|
||||
* @memberOf context
|
||||
* @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];
|
||||
}
|
||||
}
|
||||
assertions.length = 0;
|
||||
|
||||
/**
|
||||
* Executes a code snippet or function repeatedly, with a delay between each call.
|
||||
*
|
||||
* @memberOf context
|
||||
* @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 context
|
||||
* @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));
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
/** Add `console.log()` support for Narwhal, Rhino, and RingoJS */
|
||||
var console = context.console || (context.console = { 'log': context.print });
|
||||
|
||||
/** Shorten `context.QUnit.QUnit` to `context.QUnit` */
|
||||
var QUnit = context.QUnit = context.QUnit.QUnit || context.QUnit;
|
||||
|
||||
/** Used as a horizontal rule in console output */
|
||||
var hr = '----------------------------------------';
|
||||
|
||||
/**
|
||||
* A logging callback triggered when all testing is completed.
|
||||
*
|
||||
* @memberOf QUnit
|
||||
* @param {Object} details An object with properties `failed`, `passed`, `runtime`, and `total`.
|
||||
*/
|
||||
QUnit.done(function() {
|
||||
var ran;
|
||||
return function(details) {
|
||||
// stop `asyncTest()` from erroneously calling `done()` twice in
|
||||
// environments w/o timeouts
|
||||
if (ran) {
|
||||
return;
|
||||
}
|
||||
ran = 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 Narhwal, Rhino, or Ringo
|
||||
try {
|
||||
quit();
|
||||
} catch(e) { }
|
||||
|
||||
// exit out of Node.js or PhantomJS
|
||||
try {
|
||||
var process = context.process || context.phantom;
|
||||
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`.
|
||||
*/
|
||||
QUnit.log(function(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`.
|
||||
*/
|
||||
QUnit.moduleStart(function(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.
|
||||
*/
|
||||
QUnit.jsDump.parsers.object = (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`.
|
||||
*/
|
||||
QUnit.testDone(function(details) {
|
||||
var assertions = QUnit.config.testStats.assertions,
|
||||
testName = details.name;
|
||||
|
||||
if (details.failed > 0) {
|
||||
console.log(' FAIL - '+ testName);
|
||||
assertions.forEach(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': []
|
||||
};
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
// 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
|
||||
try {
|
||||
var counter = 0,
|
||||
ids = {},
|
||||
slice = Array.prototype.slice,
|
||||
timer = new java.util.Timer;
|
||||
|
||||
context.clearInterval =
|
||||
context.clearTimeout = clearTimer;
|
||||
context.setInterval = setInterval;
|
||||
context.setTimeout = setTimeout;
|
||||
} catch(e) { }
|
||||
|
||||
// expose shortcuts
|
||||
// exclude `module` because some environments have it as a built-in object
|
||||
('asyncTest deepEqual equal equals expect notDeepEqual notEqual notStrictEqual ' +
|
||||
'ok raises same start stop strictEqual test throws').replace(/\S+/g, function(methodName) {
|
||||
context[methodName] = QUnit[methodName];
|
||||
});
|
||||
|
||||
// must call `QUnit.start()` in the test file if using QUnit < 1.3.0 with
|
||||
// Node.js or any version of QUnit with Narwhal, PhantomJS, Rhino, or RingoJS
|
||||
QUnit.init();
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* 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));
|
||||
// expose QUnit CLIB
|
||||
if (freeExports) {
|
||||
freeExports.runInContext = runInContext;
|
||||
} else {
|
||||
runInContext(window);
|
||||
}
|
||||
}(this));
|
||||
|
||||
17
vendor/qunit/README.md
vendored
17
vendor/qunit/README.md
vendored
@@ -23,9 +23,6 @@ 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
|
||||
-----------
|
||||
|
||||
@@ -49,11 +46,17 @@ tag, update them again to the next version, commit and push commits and tags
|
||||
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):
|
||||
To upload to code.jquery.com (replace $version accordingly), ssh to code.origin.jquery.com:
|
||||
|
||||
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
|
||||
cp qunit/qunit.js /var/www/html/code.jquery.com/qunit/qunit-$version.js
|
||||
cp qunit/qunit.css /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
|
||||
curl -s http://code.origin.jquery.com/?reload
|
||||
|
||||
Update web-base-template to link to those files for qunitjs.com.
|
||||
|
||||
Publish to npm via
|
||||
|
||||
npm publish
|
||||
|
||||
1863
vendor/qunit/qunit/qunit-1.8.0.js
vendored
1863
vendor/qunit/qunit/qunit-1.8.0.js
vendored
File diff suppressed because it is too large
Load Diff
15
vendor/qunit/qunit/qunit.css
vendored
15
vendor/qunit/qunit/qunit.css
vendored
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* QUnit v1.10.0 - A JavaScript Unit Testing Framework
|
||||
* QUnit v1.11.0 - A JavaScript Unit Testing Framework
|
||||
*
|
||||
* http://qunitjs.com
|
||||
*
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
/** Resets */
|
||||
|
||||
#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
|
||||
#qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
@@ -111,7 +111,12 @@
|
||||
color: #000;
|
||||
}
|
||||
|
||||
#qunit-tests ol {
|
||||
#qunit-tests li .runtime {
|
||||
float: right;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
.qunit-assert-list {
|
||||
margin-top: 0.5em;
|
||||
padding: 0.5em;
|
||||
|
||||
@@ -122,6 +127,10 @@
|
||||
-webkit-border-radius: 5px;
|
||||
}
|
||||
|
||||
.qunit-collapsed {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#qunit-tests table {
|
||||
border-collapse: collapse;
|
||||
margin-top: .2em;
|
||||
|
||||
491
vendor/qunit/qunit/qunit.js
vendored
491
vendor/qunit/qunit/qunit.js
vendored
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* QUnit v1.10.0 - A JavaScript Unit Testing Framework
|
||||
* QUnit v1.11.0 - A JavaScript Unit Testing Framework
|
||||
*
|
||||
* http://qunitjs.com
|
||||
*
|
||||
@@ -11,6 +11,7 @@
|
||||
(function( window ) {
|
||||
|
||||
var QUnit,
|
||||
assert,
|
||||
config,
|
||||
onErrorFnPrev,
|
||||
testId = 0,
|
||||
@@ -20,18 +21,67 @@ var QUnit,
|
||||
// Keep a local reference to Date (GH-283)
|
||||
Date = window.Date,
|
||||
defined = {
|
||||
setTimeout: typeof window.setTimeout !== "undefined",
|
||||
sessionStorage: (function() {
|
||||
var x = "qunit-test-string";
|
||||
try {
|
||||
sessionStorage.setItem( x, x );
|
||||
sessionStorage.removeItem( x );
|
||||
return true;
|
||||
} catch( e ) {
|
||||
return false;
|
||||
setTimeout: typeof window.setTimeout !== "undefined",
|
||||
sessionStorage: (function() {
|
||||
var x = "qunit-test-string";
|
||||
try {
|
||||
sessionStorage.setItem( x, x );
|
||||
sessionStorage.removeItem( x );
|
||||
return true;
|
||||
} catch( e ) {
|
||||
return false;
|
||||
}
|
||||
}())
|
||||
},
|
||||
/**
|
||||
* Provides a normalized error string, correcting an issue
|
||||
* with IE 7 (and prior) where Error.prototype.toString is
|
||||
* not properly implemented
|
||||
*
|
||||
* Based on http://es5.github.com/#x15.11.4.4
|
||||
*
|
||||
* @param {String|Error} error
|
||||
* @return {String} error message
|
||||
*/
|
||||
errorString = function( error ) {
|
||||
var name, message,
|
||||
errorString = error.toString();
|
||||
if ( errorString.substring( 0, 7 ) === "[object" ) {
|
||||
name = error.name ? error.name.toString() : "Error";
|
||||
message = error.message ? error.message.toString() : "";
|
||||
if ( name && message ) {
|
||||
return name + ": " + message;
|
||||
} else if ( name ) {
|
||||
return name;
|
||||
} else if ( message ) {
|
||||
return message;
|
||||
} else {
|
||||
return "Error";
|
||||
}
|
||||
} else {
|
||||
return errorString;
|
||||
}
|
||||
}())
|
||||
};
|
||||
},
|
||||
/**
|
||||
* Makes a clone of an object using only Array or Object as base,
|
||||
* and copies over the own enumerable properties.
|
||||
*
|
||||
* @param {Object} obj
|
||||
* @return {Object} New object with only the own properties (recursively).
|
||||
*/
|
||||
objectValues = function( obj ) {
|
||||
// Grunt 0.3.x uses an older version of jshint that still has jshint/jshint#392.
|
||||
/*jshint newcap: false */
|
||||
var key, val,
|
||||
vals = QUnit.is( "array", obj ) ? [] : {};
|
||||
for ( key in obj ) {
|
||||
if ( hasOwn.call( obj, key ) ) {
|
||||
val = obj[key];
|
||||
vals[key] = val === Object(val) ? objectValues(val) : val;
|
||||
}
|
||||
}
|
||||
return vals;
|
||||
};
|
||||
|
||||
function Test( settings ) {
|
||||
extend( this, settings );
|
||||
@@ -44,11 +94,11 @@ Test.count = 0;
|
||||
Test.prototype = {
|
||||
init: function() {
|
||||
var a, b, li,
|
||||
tests = id( "qunit-tests" );
|
||||
tests = id( "qunit-tests" );
|
||||
|
||||
if ( tests ) {
|
||||
b = document.createElement( "strong" );
|
||||
b.innerHTML = this.name;
|
||||
b.innerHTML = this.nameHtml;
|
||||
|
||||
// `a` initialized at top of scope
|
||||
a = document.createElement( "a" );
|
||||
@@ -92,6 +142,7 @@ Test.prototype = {
|
||||
teardown: function() {}
|
||||
}, this.moduleTestEnvironment );
|
||||
|
||||
this.started = +new Date();
|
||||
runLoggingCallbacks( "testStart", QUnit, {
|
||||
name: this.testName,
|
||||
module: this.module
|
||||
@@ -111,7 +162,7 @@ Test.prototype = {
|
||||
try {
|
||||
this.testEnvironment.setup.call( this.testEnvironment );
|
||||
} catch( e ) {
|
||||
QUnit.pushFailure( "Setup failed on " + this.testName + ": " + e.message, extractStacktrace( e, 1 ) );
|
||||
QUnit.pushFailure( "Setup failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) );
|
||||
}
|
||||
},
|
||||
run: function() {
|
||||
@@ -120,22 +171,28 @@ Test.prototype = {
|
||||
var running = id( "qunit-testresult" );
|
||||
|
||||
if ( running ) {
|
||||
running.innerHTML = "Running: <br/>" + this.name;
|
||||
running.innerHTML = "Running: <br/>" + this.nameHtml;
|
||||
}
|
||||
|
||||
if ( this.async ) {
|
||||
QUnit.stop();
|
||||
}
|
||||
|
||||
this.callbackStarted = +new Date();
|
||||
|
||||
if ( config.notrycatch ) {
|
||||
this.callback.call( this.testEnvironment, QUnit.assert );
|
||||
this.callbackRuntime = +new Date() - this.callbackStarted;
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
this.callback.call( this.testEnvironment, QUnit.assert );
|
||||
this.callbackRuntime = +new Date() - this.callbackStarted;
|
||||
} catch( e ) {
|
||||
QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + e.message, extractStacktrace( e, 0 ) );
|
||||
this.callbackRuntime = +new Date() - this.callbackStarted;
|
||||
|
||||
QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + ( e.message || e ), extractStacktrace( e, 0 ) );
|
||||
// else next test will carry the responsibility
|
||||
saveGlobal();
|
||||
|
||||
@@ -148,38 +205,43 @@ Test.prototype = {
|
||||
teardown: function() {
|
||||
config.current = this;
|
||||
if ( config.notrycatch ) {
|
||||
if ( typeof this.callbackRuntime === "undefined" ) {
|
||||
this.callbackRuntime = +new Date() - this.callbackStarted;
|
||||
}
|
||||
this.testEnvironment.teardown.call( this.testEnvironment );
|
||||
return;
|
||||
} else {
|
||||
try {
|
||||
this.testEnvironment.teardown.call( this.testEnvironment );
|
||||
} catch( e ) {
|
||||
QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + e.message, extractStacktrace( e, 1 ) );
|
||||
QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) );
|
||||
}
|
||||
}
|
||||
checkPollution();
|
||||
},
|
||||
finish: function() {
|
||||
config.current = this;
|
||||
if ( config.requireExpects && this.expected == null ) {
|
||||
if ( config.requireExpects && this.expected === null ) {
|
||||
QUnit.pushFailure( "Expected number of assertions to be defined, but expect() was not called.", this.stack );
|
||||
} else if ( this.expected != null && this.expected != this.assertions.length ) {
|
||||
} else if ( this.expected !== null && this.expected !== this.assertions.length ) {
|
||||
QUnit.pushFailure( "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack );
|
||||
} else if ( this.expected == null && !this.assertions.length ) {
|
||||
} else if ( this.expected === null && !this.assertions.length ) {
|
||||
QUnit.pushFailure( "Expected at least one assertion, but none were run - call expect(0) to accept zero assertions.", this.stack );
|
||||
}
|
||||
|
||||
var assertion, a, b, i, li, ol,
|
||||
var i, assertion, a, b, time, li, ol,
|
||||
test = this,
|
||||
good = 0,
|
||||
bad = 0,
|
||||
tests = id( "qunit-tests" );
|
||||
|
||||
this.runtime = +new Date() - this.started;
|
||||
config.stats.all += this.assertions.length;
|
||||
config.moduleStats.all += this.assertions.length;
|
||||
|
||||
if ( tests ) {
|
||||
ol = document.createElement( "ol" );
|
||||
ol.className = "qunit-assert-list";
|
||||
|
||||
for ( i = 0; i < this.assertions.length; i++ ) {
|
||||
assertion = this.assertions[i];
|
||||
@@ -208,22 +270,22 @@ Test.prototype = {
|
||||
}
|
||||
|
||||
if ( bad === 0 ) {
|
||||
ol.style.display = "none";
|
||||
addClass( ol, "qunit-collapsed" );
|
||||
}
|
||||
|
||||
// `b` initialized at top of scope
|
||||
b = document.createElement( "strong" );
|
||||
b.innerHTML = this.name + " <b class='counts'>(<b class='failed'>" + bad + "</b>, <b class='passed'>" + good + "</b>, " + this.assertions.length + ")</b>";
|
||||
b.innerHTML = this.nameHtml + " <b class='counts'>(<b class='failed'>" + bad + "</b>, <b class='passed'>" + good + "</b>, " + this.assertions.length + ")</b>";
|
||||
|
||||
addEvent(b, "click", function() {
|
||||
var next = b.nextSibling.nextSibling,
|
||||
display = next.style.display;
|
||||
next.style.display = display === "none" ? "block" : "none";
|
||||
var next = b.parentNode.lastChild,
|
||||
collapsed = hasClass( next, "qunit-collapsed" );
|
||||
( collapsed ? removeClass : addClass )( next, "qunit-collapsed" );
|
||||
});
|
||||
|
||||
addEvent(b, "dblclick", function( e ) {
|
||||
var target = e && e.target ? e.target : window.event.srcElement;
|
||||
if ( target.nodeName.toLowerCase() == "span" || target.nodeName.toLowerCase() == "b" ) {
|
||||
if ( target.nodeName.toLowerCase() === "span" || target.nodeName.toLowerCase() === "b" ) {
|
||||
target = target.parentNode;
|
||||
}
|
||||
if ( window.location && target.nodeName.toLowerCase() === "strong" ) {
|
||||
@@ -231,13 +293,19 @@ Test.prototype = {
|
||||
}
|
||||
});
|
||||
|
||||
// `time` initialized at top of scope
|
||||
time = document.createElement( "span" );
|
||||
time.className = "runtime";
|
||||
time.innerHTML = this.runtime + " ms";
|
||||
|
||||
// `li` initialized at top of scope
|
||||
li = id( this.id );
|
||||
li.className = bad ? "fail" : "pass";
|
||||
li.removeChild( li.firstChild );
|
||||
a = li.firstChild;
|
||||
li.appendChild( b );
|
||||
li.appendChild ( a );
|
||||
li.appendChild( a );
|
||||
li.appendChild( time );
|
||||
li.appendChild( ol );
|
||||
|
||||
} else {
|
||||
@@ -255,7 +323,8 @@ Test.prototype = {
|
||||
module: this.module,
|
||||
failed: bad,
|
||||
passed: this.assertions.length - bad,
|
||||
total: this.assertions.length
|
||||
total: this.assertions.length,
|
||||
duration: this.runtime
|
||||
});
|
||||
|
||||
QUnit.reset();
|
||||
@@ -321,7 +390,7 @@ QUnit = {
|
||||
|
||||
test: function( testName, expected, callback, async ) {
|
||||
var test,
|
||||
name = "<span class='test-name'>" + escapeInnerText( testName ) + "</span>";
|
||||
nameHtml = "<span class='test-name'>" + escapeText( testName ) + "</span>";
|
||||
|
||||
if ( arguments.length === 2 ) {
|
||||
callback = expected;
|
||||
@@ -329,11 +398,11 @@ QUnit = {
|
||||
}
|
||||
|
||||
if ( config.currentModule ) {
|
||||
name = "<span class='module-name'>" + config.currentModule + "</span>: " + name;
|
||||
nameHtml = "<span class='module-name'>" + escapeText( config.currentModule ) + "</span>: " + nameHtml;
|
||||
}
|
||||
|
||||
test = new Test({
|
||||
name: name,
|
||||
nameHtml: nameHtml,
|
||||
testName: testName,
|
||||
expected: expected,
|
||||
async: async,
|
||||
@@ -360,6 +429,18 @@ QUnit = {
|
||||
},
|
||||
|
||||
start: function( count ) {
|
||||
// QUnit hasn't been initialized yet.
|
||||
// Note: RequireJS (et al) may delay onLoad
|
||||
if ( config.semaphore === undefined ) {
|
||||
QUnit.begin(function() {
|
||||
// This is triggered at the top of QUnit.load, push start() to the event loop, to allow QUnit.load to finish first
|
||||
setTimeout(function() {
|
||||
QUnit.start( count );
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
config.semaphore -= count || 1;
|
||||
// don't start until equal number of stop-calls
|
||||
if ( config.semaphore > 0 ) {
|
||||
@@ -368,6 +449,8 @@ QUnit = {
|
||||
// ignore if start is called more often then stop
|
||||
if ( config.semaphore < 0 ) {
|
||||
config.semaphore = 0;
|
||||
QUnit.pushFailure( "Called start() while already started (QUnit.config.semaphore was 0 already)", null, sourceFromStacktrace(2) );
|
||||
return;
|
||||
}
|
||||
// A slight delay, to avoid any current callbacks
|
||||
if ( defined.setTimeout ) {
|
||||
@@ -403,11 +486,14 @@ QUnit = {
|
||||
}
|
||||
};
|
||||
|
||||
// `assert` initialized at top of scope
|
||||
// Asssert helpers
|
||||
// All of these must call either QUnit.push() or manually do:
|
||||
// All of these must either call QUnit.push() or manually do:
|
||||
// - runLoggingCallbacks( "log", .. );
|
||||
// - config.current.assertions.push({ .. });
|
||||
QUnit.assert = {
|
||||
// We attach it to the QUnit object *after* we expose the public API,
|
||||
// otherwise `assert` will become a global variable in browsers (#341).
|
||||
assert = {
|
||||
/**
|
||||
* Asserts rough true-ish result.
|
||||
* @name ok
|
||||
@@ -428,14 +514,14 @@ QUnit.assert = {
|
||||
message: msg
|
||||
};
|
||||
|
||||
msg = escapeInnerText( msg || (result ? "okay" : "failed" ) );
|
||||
msg = escapeText( msg || (result ? "okay" : "failed" ) );
|
||||
msg = "<span class='test-message'>" + msg + "</span>";
|
||||
|
||||
if ( !result ) {
|
||||
source = sourceFromStacktrace( 2 );
|
||||
if ( source ) {
|
||||
details.source = source;
|
||||
msg += "<table><tr class='test-source'><th>Source: </th><td><pre>" + escapeInnerText( source ) + "</pre></td></tr></table>";
|
||||
msg += "<table><tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr></table>";
|
||||
}
|
||||
}
|
||||
runLoggingCallbacks( "log", QUnit, details );
|
||||
@@ -453,6 +539,7 @@ QUnit.assert = {
|
||||
* @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" );
|
||||
*/
|
||||
equal: function( actual, expected, message ) {
|
||||
/*jshint eqeqeq:false */
|
||||
QUnit.push( expected == actual, actual, expected, message );
|
||||
},
|
||||
|
||||
@@ -461,9 +548,30 @@ QUnit.assert = {
|
||||
* @function
|
||||
*/
|
||||
notEqual: function( actual, expected, message ) {
|
||||
/*jshint eqeqeq:false */
|
||||
QUnit.push( expected != actual, actual, expected, message );
|
||||
},
|
||||
|
||||
/**
|
||||
* @name propEqual
|
||||
* @function
|
||||
*/
|
||||
propEqual: function( actual, expected, message ) {
|
||||
actual = objectValues(actual);
|
||||
expected = objectValues(expected);
|
||||
QUnit.push( QUnit.equiv(actual, expected), actual, expected, message );
|
||||
},
|
||||
|
||||
/**
|
||||
* @name notPropEqual
|
||||
* @function
|
||||
*/
|
||||
notPropEqual: function( actual, expected, message ) {
|
||||
actual = objectValues(actual);
|
||||
expected = objectValues(expected);
|
||||
QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message );
|
||||
},
|
||||
|
||||
/**
|
||||
* @name deepEqual
|
||||
* @function
|
||||
@@ -496,8 +604,9 @@ QUnit.assert = {
|
||||
QUnit.push( expected !== actual, actual, expected, message );
|
||||
},
|
||||
|
||||
throws: function( block, expected, message ) {
|
||||
"throws": function( block, expected, message ) {
|
||||
var actual,
|
||||
expectedOutput = expected,
|
||||
ok = false;
|
||||
|
||||
// 'expected' is optional
|
||||
@@ -518,18 +627,20 @@ QUnit.assert = {
|
||||
// we don't want to validate thrown error
|
||||
if ( !expected ) {
|
||||
ok = true;
|
||||
expectedOutput = null;
|
||||
// expected is a regexp
|
||||
} else if ( QUnit.objectType( expected ) === "regexp" ) {
|
||||
ok = expected.test( actual );
|
||||
ok = expected.test( errorString( actual ) );
|
||||
// expected is a constructor
|
||||
} else if ( actual instanceof expected ) {
|
||||
ok = true;
|
||||
// expected is a validation function which returns true is validation passed
|
||||
} else if ( expected.call( {}, actual ) === true ) {
|
||||
expectedOutput = null;
|
||||
ok = true;
|
||||
}
|
||||
|
||||
QUnit.push( ok, actual, null, message );
|
||||
QUnit.push( ok, actual, expectedOutput, message );
|
||||
} else {
|
||||
QUnit.pushFailure( message, null, 'No exception was thrown.' );
|
||||
}
|
||||
@@ -538,15 +649,16 @@ QUnit.assert = {
|
||||
|
||||
/**
|
||||
* @deprecate since 1.8.0
|
||||
* Kept assertion helpers in root for backwards compatibility
|
||||
* Kept assertion helpers in root for backwards compatibility.
|
||||
*/
|
||||
extend( QUnit, QUnit.assert );
|
||||
extend( QUnit, assert );
|
||||
|
||||
/**
|
||||
* @deprecated since 1.9.0
|
||||
* Kept global "raises()" for backwards compatibility
|
||||
* Kept root "raises()" for backwards compatibility.
|
||||
* (Note that we don't introduce assert.raises).
|
||||
*/
|
||||
QUnit.raises = QUnit.assert.throws;
|
||||
QUnit.raises = assert[ "throws" ];
|
||||
|
||||
/**
|
||||
* @deprecated since 1.0.0, replaced with error pushes since 1.3.0
|
||||
@@ -622,6 +734,15 @@ config = {
|
||||
moduleDone: []
|
||||
};
|
||||
|
||||
// Export global variables, unless an 'exports' object exists,
|
||||
// in that case we assume we're in CommonJS (dealt with on the bottom of the script)
|
||||
if ( typeof exports === "undefined" ) {
|
||||
extend( window, QUnit );
|
||||
|
||||
// Expose QUnit object
|
||||
window.QUnit = QUnit;
|
||||
}
|
||||
|
||||
// Initialize more QUnit.config and QUnit.urlParams
|
||||
(function() {
|
||||
var i,
|
||||
@@ -655,18 +776,11 @@ config = {
|
||||
QUnit.isLocal = location.protocol === "file:";
|
||||
}());
|
||||
|
||||
// Export global variables, unless an 'exports' object exists,
|
||||
// in that case we assume we're in CommonJS (dealt with on the bottom of the script)
|
||||
if ( typeof exports === "undefined" ) {
|
||||
extend( window, QUnit );
|
||||
|
||||
// Expose QUnit object
|
||||
window.QUnit = QUnit;
|
||||
}
|
||||
|
||||
// Extend QUnit object,
|
||||
// these after set here because they should not be exposed as global functions
|
||||
extend( QUnit, {
|
||||
assert: assert,
|
||||
|
||||
config: config,
|
||||
|
||||
// Initialize the configuration options
|
||||
@@ -681,7 +795,7 @@ extend( QUnit, {
|
||||
autorun: false,
|
||||
filter: "",
|
||||
queue: [],
|
||||
semaphore: 0
|
||||
semaphore: 1
|
||||
});
|
||||
|
||||
var tests, banner, result,
|
||||
@@ -689,7 +803,7 @@ extend( QUnit, {
|
||||
|
||||
if ( qunit ) {
|
||||
qunit.innerHTML =
|
||||
"<h1 id='qunit-header'>" + escapeInnerText( document.title ) + "</h1>" +
|
||||
"<h1 id='qunit-header'>" + escapeText( document.title ) + "</h1>" +
|
||||
"<h2 id='qunit-banner'></h2>" +
|
||||
"<div id='qunit-testrunner-toolbar'></div>" +
|
||||
"<h2 id='qunit-userAgent'></h2>" +
|
||||
@@ -745,7 +859,7 @@ extend( QUnit, {
|
||||
|
||||
// Safe object type checking
|
||||
is: function( type, obj ) {
|
||||
return QUnit.objectType( obj ) == type;
|
||||
return QUnit.objectType( obj ) === type;
|
||||
},
|
||||
|
||||
objectType: function( obj ) {
|
||||
@@ -757,7 +871,8 @@ extend( QUnit, {
|
||||
return "null";
|
||||
}
|
||||
|
||||
var type = toString.call( obj ).match(/^\[object\s(.*)\]$/)[1] || "";
|
||||
var match = toString.call( obj ).match(/^\[object\s(.*)\]$/),
|
||||
type = match && match[1] || "";
|
||||
|
||||
switch ( type ) {
|
||||
case "Number":
|
||||
@@ -794,16 +909,16 @@ extend( QUnit, {
|
||||
expected: expected
|
||||
};
|
||||
|
||||
message = escapeInnerText( message ) || ( result ? "okay" : "failed" );
|
||||
message = escapeText( message ) || ( result ? "okay" : "failed" );
|
||||
message = "<span class='test-message'>" + message + "</span>";
|
||||
output = message;
|
||||
|
||||
if ( !result ) {
|
||||
expected = escapeInnerText( QUnit.jsDump.parse(expected) );
|
||||
actual = escapeInnerText( QUnit.jsDump.parse(actual) );
|
||||
expected = escapeText( QUnit.jsDump.parse(expected) );
|
||||
actual = escapeText( QUnit.jsDump.parse(actual) );
|
||||
output += "<table><tr class='test-expected'><th>Expected: </th><td><pre>" + expected + "</pre></td></tr>";
|
||||
|
||||
if ( actual != expected ) {
|
||||
if ( actual !== expected ) {
|
||||
output += "<tr class='test-actual'><th>Result: </th><td><pre>" + actual + "</pre></td></tr>";
|
||||
output += "<tr class='test-diff'><th>Diff: </th><td><pre>" + QUnit.diff( expected, actual ) + "</pre></td></tr>";
|
||||
}
|
||||
@@ -812,7 +927,7 @@ extend( QUnit, {
|
||||
|
||||
if ( source ) {
|
||||
details.source = source;
|
||||
output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeInnerText( source ) + "</pre></td></tr>";
|
||||
output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr>";
|
||||
}
|
||||
|
||||
output += "</table>";
|
||||
@@ -839,19 +954,19 @@ extend( QUnit, {
|
||||
message: message
|
||||
};
|
||||
|
||||
message = escapeInnerText( message ) || "error";
|
||||
message = escapeText( message ) || "error";
|
||||
message = "<span class='test-message'>" + message + "</span>";
|
||||
output = message;
|
||||
|
||||
output += "<table>";
|
||||
|
||||
if ( actual ) {
|
||||
output += "<tr class='test-actual'><th>Result: </th><td><pre>" + escapeInnerText( actual ) + "</pre></td></tr>";
|
||||
output += "<tr class='test-actual'><th>Result: </th><td><pre>" + escapeText( actual ) + "</pre></td></tr>";
|
||||
}
|
||||
|
||||
if ( source ) {
|
||||
details.source = source;
|
||||
output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeInnerText( source ) + "</pre></td></tr>";
|
||||
output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr>";
|
||||
}
|
||||
|
||||
output += "</table>";
|
||||
@@ -876,7 +991,8 @@ extend( QUnit, {
|
||||
querystring += encodeURIComponent( key ) + "=" +
|
||||
encodeURIComponent( params[ key ] ) + "&";
|
||||
}
|
||||
return window.location.pathname + querystring.slice( 0, -1 );
|
||||
return window.location.protocol + "//" + window.location.host +
|
||||
window.location.pathname + querystring.slice( 0, -1 );
|
||||
},
|
||||
|
||||
extend: extend,
|
||||
@@ -907,7 +1023,7 @@ extend( QUnit.constructor.prototype, {
|
||||
// testStart: { name }
|
||||
testStart: registerLoggingCallback( "testStart" ),
|
||||
|
||||
// testDone: { name, failed, passed, total }
|
||||
// testDone: { name, failed, passed, total, duration }
|
||||
testDone: registerLoggingCallback( "testDone" ),
|
||||
|
||||
// moduleStart: { name }
|
||||
@@ -925,9 +1041,10 @@ QUnit.load = function() {
|
||||
runLoggingCallbacks( "begin", QUnit, {} );
|
||||
|
||||
// Initialize the config, saving the execution queue
|
||||
var banner, filter, i, label, len, main, ol, toolbar, userAgent, val, urlConfigCheckboxes, moduleFilter,
|
||||
numModules = 0,
|
||||
moduleFilterHtml = "",
|
||||
var banner, filter, i, label, len, main, ol, toolbar, userAgent, val,
|
||||
urlConfigCheckboxesContainer, urlConfigCheckboxes, moduleFilter,
|
||||
numModules = 0,
|
||||
moduleFilterHtml = "",
|
||||
urlConfigHtml = "",
|
||||
oldconfig = extend( {}, config );
|
||||
|
||||
@@ -948,14 +1065,24 @@ QUnit.load = function() {
|
||||
};
|
||||
}
|
||||
config[ val.id ] = QUnit.urlParams[ val.id ];
|
||||
urlConfigHtml += "<input id='qunit-urlconfig-" + val.id + "' name='" + val.id + "' type='checkbox'" + ( config[ val.id ] ? " checked='checked'" : "" ) + " title='" + val.tooltip + "'><label for='qunit-urlconfig-" + val.id + "' title='" + val.tooltip + "'>" + val.label + "</label>";
|
||||
urlConfigHtml += "<input id='qunit-urlconfig-" + escapeText( val.id ) +
|
||||
"' name='" + escapeText( val.id ) +
|
||||
"' type='checkbox'" + ( config[ val.id ] ? " checked='checked'" : "" ) +
|
||||
" title='" + escapeText( val.tooltip ) +
|
||||
"'><label for='qunit-urlconfig-" + escapeText( val.id ) +
|
||||
"' title='" + escapeText( val.tooltip ) + "'>" + val.label + "</label>";
|
||||
}
|
||||
|
||||
moduleFilterHtml += "<label for='qunit-modulefilter'>Module: </label><select id='qunit-modulefilter' name='modulefilter'><option value='' " + ( config.module === undefined ? "selected" : "" ) + ">< All Modules ></option>";
|
||||
moduleFilterHtml += "<label for='qunit-modulefilter'>Module: </label><select id='qunit-modulefilter' name='modulefilter'><option value='' " +
|
||||
( config.module === undefined ? "selected='selected'" : "" ) +
|
||||
">< All Modules ></option>";
|
||||
|
||||
for ( i in config.modules ) {
|
||||
if ( config.modules.hasOwnProperty( i ) ) {
|
||||
numModules += 1;
|
||||
moduleFilterHtml += "<option value='" + encodeURIComponent(i) + "' " + ( config.module === i ? "selected" : "" ) + ">" + i + "</option>";
|
||||
moduleFilterHtml += "<option value='" + escapeText( encodeURIComponent(i) ) + "' " +
|
||||
( config.module === i ? "selected='selected'" : "" ) +
|
||||
">" + escapeText(i) + "</option>";
|
||||
}
|
||||
}
|
||||
moduleFilterHtml += "</select>";
|
||||
@@ -1014,22 +1141,28 @@ QUnit.load = function() {
|
||||
label.innerHTML = "Hide passed tests";
|
||||
toolbar.appendChild( label );
|
||||
|
||||
urlConfigCheckboxes = document.createElement( 'span' );
|
||||
urlConfigCheckboxes.innerHTML = urlConfigHtml;
|
||||
addEvent( urlConfigCheckboxes, "change", function( event ) {
|
||||
var params = {};
|
||||
params[ event.target.name ] = event.target.checked ? true : undefined;
|
||||
urlConfigCheckboxesContainer = document.createElement("span");
|
||||
urlConfigCheckboxesContainer.innerHTML = urlConfigHtml;
|
||||
urlConfigCheckboxes = urlConfigCheckboxesContainer.getElementsByTagName("input");
|
||||
// For oldIE support:
|
||||
// * Add handlers to the individual elements instead of the container
|
||||
// * Use "click" instead of "change"
|
||||
// * Fallback from event.target to event.srcElement
|
||||
addEvents( urlConfigCheckboxes, "click", function( event ) {
|
||||
var params = {},
|
||||
target = event.target || event.srcElement;
|
||||
params[ target.name ] = target.checked ? true : undefined;
|
||||
window.location = QUnit.url( params );
|
||||
});
|
||||
toolbar.appendChild( urlConfigCheckboxes );
|
||||
toolbar.appendChild( urlConfigCheckboxesContainer );
|
||||
|
||||
if (numModules > 1) {
|
||||
moduleFilter = document.createElement( 'span' );
|
||||
moduleFilter.setAttribute( 'id', 'qunit-modulefilter-container' );
|
||||
moduleFilter.innerHTML = moduleFilterHtml;
|
||||
addEvent( moduleFilter, "change", function() {
|
||||
addEvent( moduleFilter.lastChild, "change", function() {
|
||||
var selectBox = moduleFilter.getElementsByTagName("select")[0],
|
||||
selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value);
|
||||
selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value);
|
||||
|
||||
window.location = QUnit.url( { module: ( selectedModule === "" ) ? undefined : selectedModule } );
|
||||
});
|
||||
@@ -1106,7 +1239,7 @@ function done() {
|
||||
" milliseconds.<br/>",
|
||||
"<span class='passed'>",
|
||||
passed,
|
||||
"</span> tests of <span class='total'>",
|
||||
"</span> assertions of <span class='total'>",
|
||||
config.stats.all,
|
||||
"</span> passed, <span class='failed'>",
|
||||
config.stats.bad,
|
||||
@@ -1199,7 +1332,7 @@ function validTest( test ) {
|
||||
function extractStacktrace( e, offset ) {
|
||||
offset = offset === undefined ? 3 : offset;
|
||||
|
||||
var stack, include, i, regex;
|
||||
var stack, include, i;
|
||||
|
||||
if ( e.stacktrace ) {
|
||||
// Opera
|
||||
@@ -1213,7 +1346,7 @@ function extractStacktrace( e, offset ) {
|
||||
if ( fileName ) {
|
||||
include = [];
|
||||
for ( i = offset; i < stack.length; i++ ) {
|
||||
if ( stack[ i ].indexOf( fileName ) != -1 ) {
|
||||
if ( stack[ i ].indexOf( fileName ) !== -1 ) {
|
||||
break;
|
||||
}
|
||||
include.push( stack[ i ] );
|
||||
@@ -1242,17 +1375,27 @@ function sourceFromStacktrace( offset ) {
|
||||
}
|
||||
}
|
||||
|
||||
function escapeInnerText( s ) {
|
||||
/**
|
||||
* Escape text for attribute or text content.
|
||||
*/
|
||||
function escapeText( s ) {
|
||||
if ( !s ) {
|
||||
return "";
|
||||
}
|
||||
s = s + "";
|
||||
return s.replace( /[\&<>]/g, function( s ) {
|
||||
// Both single quotes and double quotes (for attributes)
|
||||
return s.replace( /['"<>&]/g, function( s ) {
|
||||
switch( s ) {
|
||||
case "&": return "&";
|
||||
case "<": return "<";
|
||||
case ">": return ">";
|
||||
default: return s;
|
||||
case '\'':
|
||||
return ''';
|
||||
case '"':
|
||||
return '"';
|
||||
case '<':
|
||||
return '<';
|
||||
case '>':
|
||||
return '>';
|
||||
case '&':
|
||||
return '&';
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1300,7 +1443,7 @@ function saveGlobal() {
|
||||
}
|
||||
}
|
||||
|
||||
function checkPollution( name ) {
|
||||
function checkPollution() {
|
||||
var newGlobals,
|
||||
deletedGlobals,
|
||||
old = config.pollution;
|
||||
@@ -1349,16 +1492,53 @@ function extend( a, b ) {
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} elem
|
||||
* @param {string} type
|
||||
* @param {Function} fn
|
||||
*/
|
||||
function addEvent( elem, type, fn ) {
|
||||
// Standards-based browsers
|
||||
if ( elem.addEventListener ) {
|
||||
elem.addEventListener( type, fn, false );
|
||||
} else if ( elem.attachEvent ) {
|
||||
elem.attachEvent( "on" + type, fn );
|
||||
// IE
|
||||
} else {
|
||||
fn();
|
||||
elem.attachEvent( "on" + type, fn );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Array|NodeList} elems
|
||||
* @param {string} type
|
||||
* @param {Function} fn
|
||||
*/
|
||||
function addEvents( elems, type, fn ) {
|
||||
var i = elems.length;
|
||||
while ( i-- ) {
|
||||
addEvent( elems[i], type, fn );
|
||||
}
|
||||
}
|
||||
|
||||
function hasClass( elem, name ) {
|
||||
return (" " + elem.className + " ").indexOf(" " + name + " ") > -1;
|
||||
}
|
||||
|
||||
function addClass( elem, name ) {
|
||||
if ( !hasClass( elem, name ) ) {
|
||||
elem.className += (elem.className ? " " : "") + name;
|
||||
}
|
||||
}
|
||||
|
||||
function removeClass( elem, name ) {
|
||||
var set = " " + elem.className + " ";
|
||||
// Class name may appear multiple times
|
||||
while ( set.indexOf(" " + name + " ") > -1 ) {
|
||||
set = set.replace(" " + name + " " , " ");
|
||||
}
|
||||
// If possible, trim it for prettiness, but not neccecarily
|
||||
elem.className = window.jQuery ? jQuery.trim( set ) : ( set.trim ? set.trim() : set );
|
||||
}
|
||||
|
||||
function id( name ) {
|
||||
return !!( typeof document !== "undefined" && document && document.getElementById ) &&
|
||||
document.getElementById( name );
|
||||
@@ -1372,7 +1552,6 @@ function registerLoggingCallback( key ) {
|
||||
|
||||
// Supports deprecated method of completely overwriting logging callbacks
|
||||
function runLoggingCallbacks( key, scope, args ) {
|
||||
//debugger;
|
||||
var i, callbacks;
|
||||
if ( QUnit.hasOwnProperty( key ) ) {
|
||||
QUnit[ key ].call(scope, args );
|
||||
@@ -1414,6 +1593,7 @@ QUnit.equiv = (function() {
|
||||
|
||||
// for string, boolean, number and null
|
||||
function useStrictEquality( b, a ) {
|
||||
/*jshint eqeqeq:false */
|
||||
if ( b instanceof a.constructor || a instanceof b.constructor ) {
|
||||
// to catch short annotaion VS 'new' annotation of a
|
||||
// declaration
|
||||
@@ -1610,7 +1790,8 @@ QUnit.jsDump = (function() {
|
||||
|
||||
var reName = /^function (\w+)/,
|
||||
jsDump = {
|
||||
parse: function( obj, type, stack ) { //type is used mostly internally, you can fix a (custom)type in advance
|
||||
// type is used mostly internally, you can fix a (custom)type in advance
|
||||
parse: function( obj, type, stack ) {
|
||||
stack = stack || [ ];
|
||||
var inStack, res,
|
||||
parser = this.parsers[ type || this.typeOf(obj) ];
|
||||
@@ -1618,18 +1799,16 @@ QUnit.jsDump = (function() {
|
||||
type = typeof parser;
|
||||
inStack = inArray( obj, stack );
|
||||
|
||||
if ( inStack != -1 ) {
|
||||
if ( inStack !== -1 ) {
|
||||
return "recursion(" + (inStack - stack.length) + ")";
|
||||
}
|
||||
//else
|
||||
if ( type == "function" ) {
|
||||
if ( type === "function" ) {
|
||||
stack.push( obj );
|
||||
res = parser.call( this, obj, stack );
|
||||
stack.pop();
|
||||
return res;
|
||||
}
|
||||
// else
|
||||
return ( type == "string" ) ? parser : this.parsers.error;
|
||||
return ( type === "string" ) ? parser : this.parsers.error;
|
||||
},
|
||||
typeOf: function( obj ) {
|
||||
var type;
|
||||
@@ -1656,6 +1835,8 @@ QUnit.jsDump = (function() {
|
||||
( typeof obj.length === "number" && typeof obj.item !== "undefined" && ( obj.length ? obj.item(0) === obj[0] : ( obj.item( 0 ) === null && typeof obj[0] === "undefined" ) ) )
|
||||
) {
|
||||
type = "array";
|
||||
} else if ( obj.constructor === Error.prototype.constructor ) {
|
||||
type = "error";
|
||||
} else {
|
||||
type = typeof obj;
|
||||
}
|
||||
@@ -1664,7 +1845,8 @@ QUnit.jsDump = (function() {
|
||||
separator: function() {
|
||||
return this.multiline ? this.HTML ? "<br />" : "\n" : this.HTML ? " " : " ";
|
||||
},
|
||||
indent: function( extra ) {// extra can be a number, shortcut for increasing-calling-decreasing
|
||||
// extra can be a number, shortcut for increasing-calling-decreasing
|
||||
indent: function( extra ) {
|
||||
if ( !this.multiline ) {
|
||||
return "";
|
||||
}
|
||||
@@ -1693,13 +1875,16 @@ QUnit.jsDump = (function() {
|
||||
parsers: {
|
||||
window: "[Window]",
|
||||
document: "[Document]",
|
||||
error: "[ERROR]", //when no parser is found, shouldn"t happen
|
||||
error: function(error) {
|
||||
return "Error(\"" + error.message + "\")";
|
||||
},
|
||||
unknown: "[Unknown]",
|
||||
"null": "null",
|
||||
"undefined": "undefined",
|
||||
"function": function( fn ) {
|
||||
var ret = "function",
|
||||
name = "name" in fn ? fn.name : (reName.exec(fn) || [])[1];//functions never have name in IE
|
||||
// functions never have name in IE
|
||||
name = "name" in fn ? fn.name : (reName.exec(fn) || [])[1];
|
||||
|
||||
if ( name ) {
|
||||
ret += " " + name;
|
||||
@@ -1715,13 +1900,9 @@ QUnit.jsDump = (function() {
|
||||
object: function( map, stack ) {
|
||||
var ret = [ ], keys, key, val, i;
|
||||
QUnit.jsDump.up();
|
||||
if ( Object.keys ) {
|
||||
keys = Object.keys( map );
|
||||
} else {
|
||||
keys = [];
|
||||
for ( key in map ) {
|
||||
keys.push( key );
|
||||
}
|
||||
keys = [];
|
||||
for ( key in map ) {
|
||||
keys.push( key );
|
||||
}
|
||||
keys.sort();
|
||||
for ( i = 0; i < keys.length; i++ ) {
|
||||
@@ -1733,21 +1914,34 @@ QUnit.jsDump = (function() {
|
||||
return join( "{", ret, "}" );
|
||||
},
|
||||
node: function( node ) {
|
||||
var a, val,
|
||||
var len, i, val,
|
||||
open = QUnit.jsDump.HTML ? "<" : "<",
|
||||
close = QUnit.jsDump.HTML ? ">" : ">",
|
||||
tag = node.nodeName.toLowerCase(),
|
||||
ret = open + tag;
|
||||
ret = open + tag,
|
||||
attrs = node.attributes;
|
||||
|
||||
for ( a in QUnit.jsDump.DOMAttrs ) {
|
||||
val = node[ QUnit.jsDump.DOMAttrs[a] ];
|
||||
if ( val ) {
|
||||
ret += " " + a + "=" + QUnit.jsDump.parse( val, "attribute" );
|
||||
if ( attrs ) {
|
||||
for ( i = 0, len = attrs.length; i < len; i++ ) {
|
||||
val = attrs[i].nodeValue;
|
||||
// IE6 includes all attributes in .attributes, even ones not explicitly set.
|
||||
// Those have values like undefined, null, 0, false, "" or "inherit".
|
||||
if ( val && val !== "inherit" ) {
|
||||
ret += " " + attrs[i].nodeName + "=" + QUnit.jsDump.parse( val, "attribute" );
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret + close + open + "/" + tag + close;
|
||||
ret += close;
|
||||
|
||||
// Show content of TextNode or CDATASection
|
||||
if ( node.nodeType === 3 || node.nodeType === 4 ) {
|
||||
ret += node.nodeValue;
|
||||
}
|
||||
|
||||
return ret + open + "/" + tag + close;
|
||||
},
|
||||
functionArgs: function( fn ) {//function calls it internally, it's the arguments part of the function
|
||||
// function calls it internally, it's the arguments part of the function
|
||||
functionArgs: function( fn ) {
|
||||
var args,
|
||||
l = fn.length;
|
||||
|
||||
@@ -1757,54 +1951,34 @@ QUnit.jsDump = (function() {
|
||||
|
||||
args = new Array(l);
|
||||
while ( l-- ) {
|
||||
args[l] = String.fromCharCode(97+l);//97 is 'a'
|
||||
// 97 is 'a'
|
||||
args[l] = String.fromCharCode(97+l);
|
||||
}
|
||||
return " " + args.join( ", " ) + " ";
|
||||
},
|
||||
key: quote, //object calls it internally, the key part of an item in a map
|
||||
functionCode: "[code]", //function calls it internally, it's the content of the function
|
||||
attribute: quote, //node calls it internally, it's an html attribute value
|
||||
// object calls it internally, the key part of an item in a map
|
||||
key: quote,
|
||||
// function calls it internally, it's the content of the function
|
||||
functionCode: "[code]",
|
||||
// node calls it internally, it's an html attribute value
|
||||
attribute: quote,
|
||||
string: quote,
|
||||
date: quote,
|
||||
regexp: literal, //regex
|
||||
regexp: literal,
|
||||
number: literal,
|
||||
"boolean": literal
|
||||
},
|
||||
DOMAttrs: {
|
||||
//attributes to dump from nodes, name=>realName
|
||||
id: "id",
|
||||
name: "name",
|
||||
"class": "className"
|
||||
},
|
||||
HTML: false,//if true, entities are escaped ( <, >, \t, space and \n )
|
||||
indentChar: " ",//indentation unit
|
||||
multiline: true //if true, items in a collection, are separated by a \n, else just a space.
|
||||
// if true, entities are escaped ( <, >, \t, space and \n )
|
||||
HTML: false,
|
||||
// indentation unit
|
||||
indentChar: " ",
|
||||
// if true, items in a collection, are separated by a \n, else just a space.
|
||||
multiline: true
|
||||
};
|
||||
|
||||
return jsDump;
|
||||
}());
|
||||
|
||||
// from Sizzle.js
|
||||
function getText( elems ) {
|
||||
var i, elem,
|
||||
ret = "";
|
||||
|
||||
for ( i = 0; elems[i]; i++ ) {
|
||||
elem = elems[i];
|
||||
|
||||
// Get the text from text nodes and CDATA nodes
|
||||
if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
|
||||
ret += elem.nodeValue;
|
||||
|
||||
// Traverse everything else, except comment nodes
|
||||
} else if ( elem.nodeType !== 8 ) {
|
||||
ret += getText( elem.childNodes );
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// from jquery.js
|
||||
function inArray( elem, array ) {
|
||||
if ( array.indexOf ) {
|
||||
@@ -1835,13 +2009,14 @@ function inArray( elem, array ) {
|
||||
* QUnit.diff( "the quick brown fox jumped over", "the quick fox jumps over" ) == "the quick <del>brown </del> fox <del>jumped </del><ins>jumps </ins> over"
|
||||
*/
|
||||
QUnit.diff = (function() {
|
||||
/*jshint eqeqeq:false, eqnull:true */
|
||||
function diff( o, n ) {
|
||||
var i,
|
||||
ns = {},
|
||||
os = {};
|
||||
|
||||
for ( i = 0; i < n.length; i++ ) {
|
||||
if ( ns[ n[i] ] == null ) {
|
||||
if ( !hasOwn.call( ns, n[i] ) ) {
|
||||
ns[ n[i] ] = {
|
||||
rows: [],
|
||||
o: null
|
||||
@@ -1851,7 +2026,7 @@ QUnit.diff = (function() {
|
||||
}
|
||||
|
||||
for ( i = 0; i < o.length; i++ ) {
|
||||
if ( os[ o[i] ] == null ) {
|
||||
if ( !hasOwn.call( os, o[i] ) ) {
|
||||
os[ o[i] ] = {
|
||||
rows: [],
|
||||
n: null
|
||||
@@ -1864,7 +2039,7 @@ QUnit.diff = (function() {
|
||||
if ( !hasOwn.call( ns, i ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( ns[i].rows.length == 1 && typeof os[i] != "undefined" && os[i].rows.length == 1 ) {
|
||||
if ( ns[i].rows.length === 1 && hasOwn.call( os, i ) && os[i].rows.length === 1 ) {
|
||||
n[ ns[i].rows[0] ] = {
|
||||
text: n[ ns[i].rows[0] ],
|
||||
row: os[i].rows[0]
|
||||
@@ -1970,7 +2145,7 @@ QUnit.diff = (function() {
|
||||
|
||||
// for CommonJS enviroments, export everything
|
||||
if ( typeof exports !== "undefined" ) {
|
||||
extend(exports, QUnit);
|
||||
extend( exports, QUnit );
|
||||
}
|
||||
|
||||
// get at whatever the global object is, like window in browsers
|
||||
|
||||
866
vendor/requirejs/require.js
vendored
866
vendor/requirejs/require.js
vendored
File diff suppressed because it is too large
Load Diff
4
vendor/underscore/LICENSE
vendored
4
vendor/underscore/LICENSE
vendored
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2009-2012 Jeremy Ashkenas, DocumentCloud
|
||||
Copyright (c) 2009-2013 Jeremy Ashkenas, DocumentCloud
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
@@ -19,4 +19,4 @@ 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.
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
26
vendor/underscore/test/arrays.js
vendored
26
vendor/underscore/test/arrays.js
vendored
@@ -14,6 +14,8 @@ $(document).ready(function() {
|
||||
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() {
|
||||
@@ -47,22 +49,22 @@ $(document).ready(function() {
|
||||
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 _(arguments).compact().length; })(0, 1, false, 2, false, 3);
|
||||
var result = (function(){ return _.compact(arguments).length; })(0, 1, false, 2, false, 3);
|
||||
equal(result, 3, 'works on an arguments object');
|
||||
});
|
||||
|
||||
test("flatten", function() {
|
||||
if (window.JSON) {
|
||||
var list = [1, [2], [3, [[[4]]]]];
|
||||
equal(JSON.stringify(_.flatten(list)), '[1,2,3,4]', 'can flatten nested arrays');
|
||||
equal(JSON.stringify(_.flatten(list, true)), '[1,2,3,[[[4]]]]', 'can shallowly flatten nested arrays');
|
||||
var result = (function(){ return _.flatten(arguments); })(1, [2], [3, [[[4]]]]);
|
||||
equal(JSON.stringify(result), '[1,2,3,4]', 'works on an arguments object');
|
||||
}
|
||||
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() {
|
||||
@@ -87,6 +89,8 @@ $(document).ready(function() {
|
||||
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');
|
||||
@@ -136,6 +140,8 @@ $(document).ready(function() {
|
||||
|
||||
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() {
|
||||
@@ -144,6 +150,7 @@ $(document).ready(function() {
|
||||
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);
|
||||
@@ -172,9 +179,10 @@ $(document).ready(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);
|
||||
var index = _.lastIndexOf(numbers, 2, 2);
|
||||
equal(index, 1, 'supports the fromIndex argument');
|
||||
});
|
||||
|
||||
|
||||
65
vendor/underscore/test/collections.js
vendored
65
vendor/underscore/test/collections.js
vendored
@@ -22,9 +22,13 @@ $(document).ready(function() {
|
||||
equal(answers.join(", "), 'one, two, three', 'iterating over objects works, and ignores the object prototype.');
|
||||
delete obj.constructor.prototype.four;
|
||||
|
||||
answer = null;
|
||||
var 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() {
|
||||
@@ -50,6 +54,9 @@ $(document).ready(function() {
|
||||
|
||||
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() {
|
||||
@@ -69,6 +76,15 @@ $(document).ready(function() {
|
||||
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');
|
||||
});
|
||||
@@ -83,9 +99,19 @@ $(document).ready(function() {
|
||||
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');
|
||||
|
||||
@@ -145,6 +171,14 @@ $(document).ready(function() {
|
||||
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() {
|
||||
@@ -226,6 +260,14 @@ $(document).ready(function() {
|
||||
equal(result[0].a, 1);
|
||||
});
|
||||
|
||||
test('findWhere', function() {
|
||||
var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}, {a: 2, b: 4}];
|
||||
var result = _.findWhere(list, {a: 1});
|
||||
deepEqual(result, {a: 1, b: 2});
|
||||
result = _.findWhere(list, {b: 4});
|
||||
deepEqual(result, {a: 1, b: 4});
|
||||
});
|
||||
|
||||
test('max', function() {
|
||||
equal(3, _.max([1, 2, 3]), 'can perform a regular Math.max');
|
||||
|
||||
@@ -234,6 +276,7 @@ $(document).ready(function() {
|
||||
|
||||
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");
|
||||
});
|
||||
@@ -246,6 +289,7 @@ $(document).ready(function() {
|
||||
|
||||
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);
|
||||
@@ -312,6 +356,11 @@ $(document).ready(function() {
|
||||
|
||||
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() {
|
||||
@@ -336,6 +385,11 @@ $(document).ready(function() {
|
||||
|
||||
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() {
|
||||
@@ -372,6 +426,13 @@ $(document).ready(function() {
|
||||
|
||||
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() {
|
||||
@@ -385,6 +446,8 @@ $(document).ready(function() {
|
||||
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');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
132
vendor/underscore/test/functions.js
vendored
132
vendor/underscore/test/functions.js
vendored
@@ -18,10 +18,10 @@ $(document).ready(function() {
|
||||
func = _.bind(func, this, 'hello');
|
||||
equal(func('moe'), 'hello: moe', 'the function was partially applied in advance');
|
||||
|
||||
var func = _.bind(func, this, 'curly');
|
||||
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 = 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');
|
||||
|
||||
@@ -34,10 +34,17 @@ $(document).ready(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"});
|
||||
equal(new Boundf().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");
|
||||
});
|
||||
|
||||
test("partial", function() {
|
||||
var obj = {name: 'moe'};
|
||||
var func = function() { return this.name + ' ' + _.toArray(arguments).join(' '); };
|
||||
|
||||
obj.func = _.partial(func, 'a', 'b');
|
||||
equal(obj.func('c', 'd'), 'moe a b c d', 'can partially apply');
|
||||
});
|
||||
|
||||
test("bindAll", function() {
|
||||
var curly = {name : 'curly'}, moe = {
|
||||
name : 'moe',
|
||||
@@ -93,118 +100,117 @@ $(document).ready(function() {
|
||||
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);
|
||||
var throttledIncr = _.throttle(incr, 32);
|
||||
throttledIncr(); throttledIncr();
|
||||
|
||||
equal(counter, 1, "incr was called immediately");
|
||||
_.delay(function(){ equal(counter, 2, "incr was throttled"); start(); }, 64);
|
||||
});
|
||||
|
||||
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);
|
||||
var throttledUpdate = _.throttle(update, 32);
|
||||
throttledUpdate(1); throttledUpdate(2);
|
||||
_.delay(function(){ throttledUpdate(3); }, 64);
|
||||
equal(value, 1, "updated to latest value");
|
||||
_.delay(function(){ equal(value, 3, "updated to latest value"); start(); }, 96);
|
||||
});
|
||||
|
||||
asyncTest("throttle once", 2, function() {
|
||||
var counter = 0;
|
||||
var incr = function(){ return ++counter; };
|
||||
var throttledIncr = _.throttle(incr, 100);
|
||||
var throttledIncr = _.throttle(incr, 32);
|
||||
var result = throttledIncr();
|
||||
_.delay(function(){
|
||||
equal(result, 1, "throttled functions return their value");
|
||||
equal(counter, 1, "incr was called once"); start();
|
||||
}, 220);
|
||||
}, 64);
|
||||
});
|
||||
|
||||
asyncTest("throttle twice", 1, function() {
|
||||
var counter = 0;
|
||||
var incr = function(){ counter++; };
|
||||
var throttledIncr = _.throttle(incr, 100);
|
||||
var throttledIncr = _.throttle(incr, 32);
|
||||
throttledIncr(); throttledIncr();
|
||||
_.delay(function(){ equal(counter, 2, "incr was called twice"); start(); }, 220);
|
||||
_.delay(function(){ equal(counter, 2, "incr was called twice"); start(); }, 64);
|
||||
});
|
||||
|
||||
asyncTest("throttle repeatedly with results", 9, function() {
|
||||
asyncTest("throttle repeatedly with results", 6, function() {
|
||||
var counter = 0;
|
||||
var incr = function(){ return ++counter; };
|
||||
var throttledIncr = _.throttle(incr, 100);
|
||||
var throttledIncr = _.throttle(incr, 64);
|
||||
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);
|
||||
saveResult(); saveResult();
|
||||
_.delay(saveResult, 32);
|
||||
_.delay(saveResult, 80);
|
||||
_.delay(saveResult, 96);
|
||||
_.delay(saveResult, 144);
|
||||
_.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");
|
||||
equal(results[3], 2, "incr was called twice");
|
||||
equal(results[4], 2, "incr was throttled");
|
||||
equal(results[5], 3, "incr was called trailing");
|
||||
start();
|
||||
}, 400);
|
||||
}, 192);
|
||||
});
|
||||
|
||||
asyncTest("throttle triggers trailing call when invoked repeatedly", 2, function() {
|
||||
var counter = 0;
|
||||
var limit = 48;
|
||||
var incr = function(){ counter++; };
|
||||
var throttledIncr = _.throttle(incr, 32);
|
||||
|
||||
var stamp = new Date;
|
||||
while ((new Date - stamp) < limit) {
|
||||
throttledIncr();
|
||||
}
|
||||
var lastCount = counter;
|
||||
ok(counter > 1);
|
||||
|
||||
_.delay(function() {
|
||||
ok(counter > lastCount);
|
||||
start();
|
||||
}, 96);
|
||||
});
|
||||
|
||||
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);
|
||||
var debouncedIncr = _.debounce(incr, 32);
|
||||
debouncedIncr(); debouncedIncr();
|
||||
_.delay(debouncedIncr, 16);
|
||||
_.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 96);
|
||||
});
|
||||
|
||||
asyncTest("debounce asap", 5, function() {
|
||||
var a, b, c;
|
||||
asyncTest("debounce asap", 4, function() {
|
||||
var a, b;
|
||||
var counter = 0;
|
||||
var incr = function(){ return ++counter; };
|
||||
var debouncedIncr = _.debounce(incr, 50, true);
|
||||
var debouncedIncr = _.debounce(incr, 64, 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);
|
||||
_.delay(debouncedIncr, 16);
|
||||
_.delay(debouncedIncr, 32);
|
||||
_.delay(debouncedIncr, 48);
|
||||
_.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 128);
|
||||
});
|
||||
|
||||
asyncTest("debounce asap recursively", 2, function() {
|
||||
var counter = 0;
|
||||
var debouncedIncr = _.debounce(function(){
|
||||
counter++;
|
||||
if (counter < 5) debouncedIncr();
|
||||
}, 50, true);
|
||||
if (counter < 10) debouncedIncr();
|
||||
}, 32, true);
|
||||
debouncedIncr();
|
||||
equal(counter, 1, 'incr was called immediately');
|
||||
_.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 70);
|
||||
equal(counter, 1, "incr was called immediately");
|
||||
_.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 96);
|
||||
});
|
||||
|
||||
test("once", function() {
|
||||
|
||||
42
vendor/underscore/test/objects.js
vendored
42
vendor/underscore/test/objects.js
vendored
@@ -53,6 +53,13 @@ $(document).ready(function() {
|
||||
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() {
|
||||
@@ -96,6 +103,13 @@ $(document).ready(function() {
|
||||
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() {
|
||||
@@ -337,16 +351,10 @@ $(document).ready(function() {
|
||||
|
||||
// Chaining.
|
||||
ok(!_.isEqual(_({x: 1, y: undefined}).chain(), _({x: 1, z: 2}).chain()), 'Chained objects containing different values are not equal');
|
||||
equal(_({x: 1, y: 2}).chain().isEqual(_({x: 1, y: 2}).chain()).value(), true, '`isEqual` can be chained');
|
||||
|
||||
// Custom `isEqual` methods.
|
||||
var isEqualObj = {isEqual: function (o) { return o.isEqual == this.isEqual; }, unique: {}};
|
||||
var isEqualObjClone = {isEqual: isEqualObj.isEqual, unique: {}};
|
||||
|
||||
ok(_.isEqual(isEqualObj, isEqualObjClone), 'Both objects implement identical `isEqual` methods');
|
||||
ok(_.isEqual(isEqualObjClone, isEqualObj), 'Commutative equality is implemented for objects with custom `isEqual` methods');
|
||||
ok(!_.isEqual(isEqualObj, {}), 'Objects that do not implement equivalent `isEqual` methods are not equal');
|
||||
ok(!_.isEqual({}, isEqualObj), 'Commutative equality is implemented for objects with different `isEqual` methods');
|
||||
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));
|
||||
@@ -485,7 +493,9 @@ $(document).ready(function() {
|
||||
ok(!_.isFinite(NaN), 'NaN is not Finite');
|
||||
ok(!_.isFinite(Infinity), 'Infinity is not Finite');
|
||||
ok(!_.isFinite(-Infinity), '-Infinity is not Finite');
|
||||
ok(!_.isFinite('12'), 'Strings are not numbers');
|
||||
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');
|
||||
@@ -545,4 +555,16 @@ $(document).ready(function() {
|
||||
value();
|
||||
ok(returned == 6 && intercepted == 6, 'can use tapped objects in a chain');
|
||||
});
|
||||
|
||||
test("has", function () {
|
||||
var obj = {foo: "bar", func: function () {} };
|
||||
ok (_.has(obj, "foo"), "has() checks that the object has a property.");
|
||||
ok (_.has(obj, "baz") == false, "has() returns false if the object doesn't have the property.");
|
||||
ok (_.has(obj, "func"), "has() works for functions too.");
|
||||
obj.hasOwnProperty = null;
|
||||
ok (_.has(obj, "foo"), "has() works even when the hasOwnProperty method is deleted.");
|
||||
var child = {};
|
||||
child.prototype = obj;
|
||||
ok (_.has(child, "foo") == false, "has() does not check the prototype chain for a property.")
|
||||
});
|
||||
});
|
||||
|
||||
31
vendor/underscore/test/utility.js
vendored
31
vendor/underscore/test/utility.js
vendored
@@ -25,6 +25,20 @@ $(document).ready(function() {
|
||||
equal(_.identity(moe), moe, 'moe is the same as his identity');
|
||||
});
|
||||
|
||||
test("random", function() {
|
||||
var array = _.range(1000);
|
||||
var min = Math.pow(2, 31);
|
||||
var max = Math.pow(2, 62);
|
||||
|
||||
ok(_.every(array, function() {
|
||||
return _.random(min, max) >= min;
|
||||
}), "should produce a random number greater than or equal to the minimum number");
|
||||
|
||||
ok(_.some(array, function() {
|
||||
return _.random(Number.MAX_VALUE) > 0;
|
||||
}), "should produce a random number when passed `Number.MAX_VALUE`");
|
||||
});
|
||||
|
||||
test("uniqueId", function() {
|
||||
var ids = [], i = 0;
|
||||
while(i++ < 100) ids.push(_.uniqueId());
|
||||
@@ -37,8 +51,10 @@ $(document).ready(function() {
|
||||
ok(_.isEqual(vals, [0,1,2]), "is 0 indexed");
|
||||
//
|
||||
vals = [];
|
||||
_(3).times(function (i) { vals.push(i); });
|
||||
_(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() {
|
||||
@@ -80,7 +96,7 @@ $(document).ready(function() {
|
||||
equal(escapeTemplate({a: true}), 'checked="checked"', 'can handle slash escapes in interpolations.');
|
||||
|
||||
var fancyTemplate = _.template("<ul><% \
|
||||
for (key in people) { \
|
||||
for (var 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');
|
||||
@@ -135,7 +151,7 @@ $(document).ready(function() {
|
||||
interpolate : /\{\{=([\s\S]+?)\}\}/g
|
||||
};
|
||||
|
||||
var custom = _.template("<ul>{{ for (key in people) { }}<li>{{= people[key] }}</li>{{ } }}</ul>");
|
||||
var custom = _.template("<ul>{{ for (var 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');
|
||||
|
||||
@@ -150,7 +166,7 @@ $(document).ready(function() {
|
||||
interpolate : /<\?=([\s\S]+?)\?>/g
|
||||
};
|
||||
|
||||
var customWithSpecialChars = _.template("<ul><? for (key in people) { ?><li><?= people[key] ?></li><? } ?></ul>");
|
||||
var customWithSpecialChars = _.template("<ul><? for (var 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');
|
||||
|
||||
@@ -173,10 +189,11 @@ $(document).ready(function() {
|
||||
|
||||
test('_.template provides the generated function source, when a SyntaxError occurs', function() {
|
||||
try {
|
||||
_.template('<b><%= if %></b>');
|
||||
} catch (e) {
|
||||
ok(e.source.indexOf('( if )') > 0);
|
||||
_.template('<b><%= if x %></b>');
|
||||
} catch (ex) {
|
||||
var source = ex.source;
|
||||
}
|
||||
ok(/__p/.test(source));
|
||||
});
|
||||
|
||||
test('_.template handles \\u2028 & \\u2029', function() {
|
||||
|
||||
670
vendor/underscore/test/vendor/jslitmus.js
vendored
670
vendor/underscore/test/vendor/jslitmus.js
vendored
@@ -1,670 +0,0 @@
|
||||
// JSLitmus.js
|
||||
//
|
||||
// History:
|
||||
// 2008-10-27: Initial release
|
||||
// 2008-11-09: Account for iteration loop overhead
|
||||
// 2008-11-13: Added OS detection
|
||||
// 2009-02-25: Create tinyURL automatically, shift-click runs tests in reverse
|
||||
//
|
||||
// Copyright (c) 2008-2009, Robert Kieffer
|
||||
// All Rights Reserved
|
||||
//
|
||||
// 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 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.
|
||||
|
||||
(function() {
|
||||
// Private methods and state
|
||||
|
||||
// Get platform info but don't go crazy trying to recognize everything
|
||||
// that's out there. This is just for the major platforms and OSes.
|
||||
var platform = 'unknown platform', ua = navigator.userAgent;
|
||||
|
||||
// Detect OS
|
||||
var oses = ['Windows','iPhone OS','(Intel |PPC )?Mac OS X','Linux'].join('|');
|
||||
var pOS = new RegExp('((' + oses + ') [^ \);]*)').test(ua) ? RegExp.$1 : null;
|
||||
if (!pOS) pOS = new RegExp('((' + oses + ')[^ \);]*)').test(ua) ? RegExp.$1 : null;
|
||||
|
||||
// Detect browser
|
||||
var pName = /(Chrome|MSIE|Safari|Opera|Firefox)/.test(ua) ? RegExp.$1 : null;
|
||||
|
||||
// Detect version
|
||||
var vre = new RegExp('(Version|' + pName + ')[ \/]([^ ;]*)');
|
||||
var pVersion = (pName && vre.test(ua)) ? RegExp.$2 : null;
|
||||
var platform = (pOS && pName && pVersion) ? pName + ' ' + pVersion + ' on ' + pOS : 'unknown platform';
|
||||
|
||||
/**
|
||||
* A smattering of methods that are needed to implement the JSLitmus testbed.
|
||||
*/
|
||||
var jsl = {
|
||||
/**
|
||||
* Enhanced version of escape()
|
||||
*/
|
||||
escape: function(s) {
|
||||
s = s.replace(/,/g, '\\,');
|
||||
s = escape(s);
|
||||
s = s.replace(/\+/g, '%2b');
|
||||
s = s.replace(/ /g, '+');
|
||||
return s;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get an element by ID.
|
||||
*/
|
||||
$: function(id) {
|
||||
return document.getElementById(id);
|
||||
},
|
||||
|
||||
/**
|
||||
* Null function
|
||||
*/
|
||||
F: function() {},
|
||||
|
||||
/**
|
||||
* Set the status shown in the UI
|
||||
*/
|
||||
status: function(msg) {
|
||||
var el = jsl.$('jsl_status');
|
||||
if (el) el.innerHTML = msg || '';
|
||||
},
|
||||
|
||||
/**
|
||||
* Convert a number to an abbreviated string like, "15K" or "10M"
|
||||
*/
|
||||
toLabel: function(n) {
|
||||
if (n == Infinity) {
|
||||
return 'Infinity';
|
||||
} else if (n > 1e9) {
|
||||
n = Math.round(n/1e8);
|
||||
return n/10 + 'B';
|
||||
} else if (n > 1e6) {
|
||||
n = Math.round(n/1e5);
|
||||
return n/10 + 'M';
|
||||
} else if (n > 1e3) {
|
||||
n = Math.round(n/1e2);
|
||||
return n/10 + 'K';
|
||||
}
|
||||
return n;
|
||||
},
|
||||
|
||||
/**
|
||||
* Copy properties from src to dst
|
||||
*/
|
||||
extend: function(dst, src) {
|
||||
for (var k in src) dst[k] = src[k]; return dst;
|
||||
},
|
||||
|
||||
/**
|
||||
* Like Array.join(), but for the key-value pairs in an object
|
||||
*/
|
||||
join: function(o, delimit1, delimit2) {
|
||||
if (o.join) return o.join(delimit1); // If it's an array
|
||||
var pairs = [];
|
||||
for (var k in o) pairs.push(k + delimit1 + o[k]);
|
||||
return pairs.join(delimit2);
|
||||
},
|
||||
|
||||
/**
|
||||
* Array#indexOf isn't supported in IE, so we use this as a cross-browser solution
|
||||
*/
|
||||
indexOf: function(arr, o) {
|
||||
if (arr.indexOf) return arr.indexOf(o);
|
||||
for (var i = 0; i < this.length; i++) if (arr[i] === o) return i;
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Test manages a single test (created with
|
||||
* JSLitmus.test())
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
var Test = function (name, f) {
|
||||
if (!f) throw new Error('Undefined test function');
|
||||
if (!(/function[^\(]*\(([^,\)]*)/).test(f.toString())) {
|
||||
throw new Error('"' + name + '" test: Test is not a valid Function object');
|
||||
}
|
||||
this.loopArg = RegExp.$1;
|
||||
this.name = name;
|
||||
this.f = f;
|
||||
};
|
||||
|
||||
jsl.extend(Test, /** @lends Test */ {
|
||||
/** Calibration tests for establishing iteration loop overhead */
|
||||
CALIBRATIONS: [
|
||||
new Test('calibrating loop', function(count) {while (count--);}),
|
||||
new Test('calibrating function', jsl.F)
|
||||
],
|
||||
|
||||
/**
|
||||
* Run calibration tests. Returns true if calibrations are not yet
|
||||
* complete (in which case calling code should run the tests yet again).
|
||||
* onCalibrated - Callback to invoke when calibrations have finished
|
||||
*/
|
||||
calibrate: function(onCalibrated) {
|
||||
for (var i = 0; i < Test.CALIBRATIONS.length; i++) {
|
||||
var cal = Test.CALIBRATIONS[i];
|
||||
if (cal.running) return true;
|
||||
if (!cal.count) {
|
||||
cal.isCalibration = true;
|
||||
cal.onStop = onCalibrated;
|
||||
//cal.MIN_TIME = .1; // Do calibrations quickly
|
||||
cal.run(2e4);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
jsl.extend(Test.prototype, {/** @lends Test.prototype */
|
||||
/** Initial number of iterations */
|
||||
INIT_COUNT: 10,
|
||||
/** Max iterations allowed (i.e. used to detect bad looping functions) */
|
||||
MAX_COUNT: 1e9,
|
||||
/** Minimum time a test should take to get valid results (secs) */
|
||||
MIN_TIME: .5,
|
||||
|
||||
/** Callback invoked when test state changes */
|
||||
onChange: jsl.F,
|
||||
|
||||
/** Callback invoked when test is finished */
|
||||
onStop: jsl.F,
|
||||
|
||||
/**
|
||||
* Reset test state
|
||||
*/
|
||||
reset: function() {
|
||||
delete this.count;
|
||||
delete this.time;
|
||||
delete this.running;
|
||||
delete this.error;
|
||||
},
|
||||
|
||||
/**
|
||||
* Run the test (in a timeout). We use a timeout to make sure the browser
|
||||
* has a chance to finish rendering any UI changes we've made, like
|
||||
* updating the status message.
|
||||
*/
|
||||
run: function(count) {
|
||||
count = count || this.INIT_COUNT;
|
||||
jsl.status(this.name + ' x ' + count);
|
||||
this.running = true;
|
||||
var me = this;
|
||||
setTimeout(function() {me._run(count);}, 200);
|
||||
},
|
||||
|
||||
/**
|
||||
* The nuts and bolts code that actually runs a test
|
||||
*/
|
||||
_run: function(count) {
|
||||
var me = this;
|
||||
|
||||
// Make sure calibration tests have run
|
||||
if (!me.isCalibration && Test.calibrate(function() {me.run(count);})) return;
|
||||
this.error = null;
|
||||
|
||||
try {
|
||||
var start, f = this.f, now, i = count;
|
||||
|
||||
// Start the timer
|
||||
start = new Date();
|
||||
|
||||
// Now for the money shot. If this is a looping function ...
|
||||
if (this.loopArg) {
|
||||
// ... let it do the iteration itself
|
||||
f(count);
|
||||
} else {
|
||||
// ... otherwise do the iteration for it
|
||||
while (i--) f();
|
||||
}
|
||||
|
||||
// Get time test took (in secs)
|
||||
this.time = Math.max(1,new Date() - start)/1000;
|
||||
|
||||
// Store iteration count and per-operation time taken
|
||||
this.count = count;
|
||||
this.period = this.time/count;
|
||||
|
||||
// Do we need to do another run?
|
||||
this.running = this.time <= this.MIN_TIME;
|
||||
|
||||
// ... if so, compute how many times we should iterate
|
||||
if (this.running) {
|
||||
// Bump the count to the nearest power of 2
|
||||
var x = this.MIN_TIME/this.time;
|
||||
var pow = Math.pow(2, Math.max(1, Math.ceil(Math.log(x)/Math.log(2))));
|
||||
count *= pow;
|
||||
if (count > this.MAX_COUNT) {
|
||||
throw new Error('Max count exceeded. If this test uses a looping function, make sure the iteration loop is working properly.');
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// Exceptions are caught and displayed in the test UI
|
||||
this.reset();
|
||||
this.error = e;
|
||||
}
|
||||
|
||||
// Figure out what to do next
|
||||
if (this.running) {
|
||||
me.run(count);
|
||||
} else {
|
||||
jsl.status('');
|
||||
me.onStop(me);
|
||||
}
|
||||
|
||||
// Finish up
|
||||
this.onChange(this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the number of operations per second for this test.
|
||||
*
|
||||
* @param normalize if true, iteration loop overhead taken into account
|
||||
*/
|
||||
getHz: function(/**Boolean*/ normalize) {
|
||||
var p = this.period;
|
||||
|
||||
// Adjust period based on the calibration test time
|
||||
if (normalize && !this.isCalibration) {
|
||||
var cal = Test.CALIBRATIONS[this.loopArg ? 0 : 1];
|
||||
|
||||
// If the period is within 20% of the calibration time, then zero the
|
||||
// it out
|
||||
p = p < cal.period*1.2 ? 0 : p - cal.period;
|
||||
}
|
||||
|
||||
return Math.round(1/p);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get a friendly string describing the test
|
||||
*/
|
||||
toString: function() {
|
||||
return this.name + ' - ' + this.time/this.count + ' secs';
|
||||
}
|
||||
});
|
||||
|
||||
// CSS we need for the UI
|
||||
var STYLESHEET = '<style> \
|
||||
#jslitmus {font-family:sans-serif; font-size: 12px;} \
|
||||
#jslitmus a {text-decoration: none;} \
|
||||
#jslitmus a:hover {text-decoration: underline;} \
|
||||
#jsl_status { \
|
||||
margin-top: 10px; \
|
||||
font-size: 10px; \
|
||||
color: #888; \
|
||||
} \
|
||||
A IMG {border:none} \
|
||||
#test_results { \
|
||||
margin-top: 10px; \
|
||||
font-size: 12px; \
|
||||
font-family: sans-serif; \
|
||||
border-collapse: collapse; \
|
||||
border-spacing: 0px; \
|
||||
} \
|
||||
#test_results th, #test_results td { \
|
||||
border: solid 1px #ccc; \
|
||||
vertical-align: top; \
|
||||
padding: 3px; \
|
||||
} \
|
||||
#test_results th { \
|
||||
vertical-align: bottom; \
|
||||
background-color: #ccc; \
|
||||
padding: 1px; \
|
||||
font-size: 10px; \
|
||||
} \
|
||||
#test_results #test_platform { \
|
||||
color: #444; \
|
||||
text-align:center; \
|
||||
} \
|
||||
#test_results .test_row { \
|
||||
color: #006; \
|
||||
cursor: pointer; \
|
||||
} \
|
||||
#test_results .test_nonlooping { \
|
||||
border-left-style: dotted; \
|
||||
border-left-width: 2px; \
|
||||
} \
|
||||
#test_results .test_looping { \
|
||||
border-left-style: solid; \
|
||||
border-left-width: 2px; \
|
||||
} \
|
||||
#test_results .test_name {white-space: nowrap;} \
|
||||
#test_results .test_pending { \
|
||||
} \
|
||||
#test_results .test_running { \
|
||||
font-style: italic; \
|
||||
} \
|
||||
#test_results .test_done {} \
|
||||
#test_results .test_done { \
|
||||
text-align: right; \
|
||||
font-family: monospace; \
|
||||
} \
|
||||
#test_results .test_error {color: #600;} \
|
||||
#test_results .test_error .error_head {font-weight:bold;} \
|
||||
#test_results .test_error .error_body {font-size:85%;} \
|
||||
#test_results .test_row:hover td { \
|
||||
background-color: #ffc; \
|
||||
text-decoration: underline; \
|
||||
} \
|
||||
#chart { \
|
||||
margin: 10px 0px; \
|
||||
width: 250px; \
|
||||
} \
|
||||
#chart img { \
|
||||
border: solid 1px #ccc; \
|
||||
margin-bottom: 5px; \
|
||||
} \
|
||||
#chart #tiny_url { \
|
||||
height: 40px; \
|
||||
width: 250px; \
|
||||
} \
|
||||
#jslitmus_credit { \
|
||||
font-size: 10px; \
|
||||
color: #888; \
|
||||
margin-top: 8px; \
|
||||
} \
|
||||
</style>';
|
||||
|
||||
// HTML markup for the UI
|
||||
var MARKUP = '<div id="jslitmus"> \
|
||||
<button onclick="JSLitmus.runAll(event)">Run Tests</button> \
|
||||
<button id="stop_button" disabled="disabled" onclick="JSLitmus.stop()">Stop Tests</button> \
|
||||
<br \> \
|
||||
<br \> \
|
||||
<input type="checkbox" style="vertical-align: middle" id="test_normalize" checked="checked" onchange="JSLitmus.renderAll()""> Normalize results \
|
||||
<table id="test_results"> \
|
||||
<colgroup> \
|
||||
<col /> \
|
||||
<col width="100" /> \
|
||||
</colgroup> \
|
||||
<tr><th id="test_platform" colspan="2">' + platform + '</th></tr> \
|
||||
<tr><th>Test</th><th>Ops/sec</th></tr> \
|
||||
<tr id="test_row_template" class="test_row" style="display:none"> \
|
||||
<td class="test_name"></td> \
|
||||
<td class="test_result">Ready</td> \
|
||||
</tr> \
|
||||
</table> \
|
||||
<div id="jsl_status"></div> \
|
||||
<div id="chart" style="display:none"> \
|
||||
<a id="chart_link" target="_blank"><img id="chart_image"></a> \
|
||||
TinyURL (for chart): \
|
||||
<iframe id="tiny_url" frameBorder="0" scrolling="no" src=""></iframe> \
|
||||
</div> \
|
||||
<a id="jslitmus_credit" title="JSLitmus home page" href="http://code.google.com/p/jslitmus" target="_blank">Powered by JSLitmus</a> \
|
||||
</div>';
|
||||
|
||||
/**
|
||||
* The public API for creating and running tests
|
||||
*/
|
||||
window.JSLitmus = {
|
||||
/** The list of all tests that have been registered with JSLitmus.test */
|
||||
_tests: [],
|
||||
/** The queue of tests that need to be run */
|
||||
_queue: [],
|
||||
|
||||
/**
|
||||
* The parsed query parameters the current page URL. This is provided as a
|
||||
* convenience for test functions - it's not used by JSLitmus proper
|
||||
*/
|
||||
params: {},
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*/
|
||||
_init: function() {
|
||||
// Parse query params into JSLitmus.params[] hash
|
||||
var match = (location + '').match(/([^?#]*)(#.*)?$/);
|
||||
if (match) {
|
||||
var pairs = match[1].split('&');
|
||||
for (var i = 0; i < pairs.length; i++) {
|
||||
var pair = pairs[i].split('=');
|
||||
if (pair.length > 1) {
|
||||
var key = pair.shift();
|
||||
var value = pair.length > 1 ? pair.join('=') : pair[0];
|
||||
this.params[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Write out the stylesheet. We have to do this here because IE
|
||||
// doesn't honor sheets written after the document has loaded.
|
||||
document.write(STYLESHEET);
|
||||
|
||||
// Setup the rest of the UI once the document is loaded
|
||||
if (window.addEventListener) {
|
||||
window.addEventListener('load', this._setup, false);
|
||||
} else if (document.addEventListener) {
|
||||
document.addEventListener('load', this._setup, false);
|
||||
} else if (window.attachEvent) {
|
||||
window.attachEvent('onload', this._setup);
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Set up the UI
|
||||
*/
|
||||
_setup: function() {
|
||||
var el = jsl.$('jslitmus_container');
|
||||
if (!el) document.body.appendChild(el = document.createElement('div'));
|
||||
|
||||
el.innerHTML = MARKUP;
|
||||
|
||||
// Render the UI for all our tests
|
||||
for (var i=0; i < JSLitmus._tests.length; i++)
|
||||
JSLitmus.renderTest(JSLitmus._tests[i]);
|
||||
},
|
||||
|
||||
/**
|
||||
* (Re)render all the test results
|
||||
*/
|
||||
renderAll: function() {
|
||||
for (var i = 0; i < JSLitmus._tests.length; i++)
|
||||
JSLitmus.renderTest(JSLitmus._tests[i]);
|
||||
JSLitmus.renderChart();
|
||||
},
|
||||
|
||||
/**
|
||||
* (Re)render the chart graphics
|
||||
*/
|
||||
renderChart: function() {
|
||||
var url = JSLitmus.chartUrl();
|
||||
jsl.$('chart_link').href = url;
|
||||
jsl.$('chart_image').src = url;
|
||||
jsl.$('chart').style.display = '';
|
||||
|
||||
// Update the tiny URL
|
||||
jsl.$('tiny_url').src = 'http://tinyurl.com/api-create.php?url='+escape(url);
|
||||
},
|
||||
|
||||
/**
|
||||
* (Re)render the results for a specific test
|
||||
*/
|
||||
renderTest: function(test) {
|
||||
// Make a new row if needed
|
||||
if (!test._row) {
|
||||
var trow = jsl.$('test_row_template');
|
||||
if (!trow) return;
|
||||
|
||||
test._row = trow.cloneNode(true);
|
||||
test._row.style.display = '';
|
||||
test._row.id = '';
|
||||
test._row.onclick = function() {JSLitmus._queueTest(test);};
|
||||
test._row.title = 'Run ' + test.name + ' test';
|
||||
trow.parentNode.appendChild(test._row);
|
||||
test._row.cells[0].innerHTML = test.name;
|
||||
}
|
||||
|
||||
var cell = test._row.cells[1];
|
||||
var cns = [test.loopArg ? 'test_looping' : 'test_nonlooping'];
|
||||
|
||||
if (test.error) {
|
||||
cns.push('test_error');
|
||||
cell.innerHTML =
|
||||
'<div class="error_head">' + test.error + '</div>' +
|
||||
'<ul class="error_body"><li>' +
|
||||
jsl.join(test.error, ': ', '</li><li>') +
|
||||
'</li></ul>';
|
||||
} else {
|
||||
if (test.running) {
|
||||
cns.push('test_running');
|
||||
cell.innerHTML = 'running';
|
||||
} else if (jsl.indexOf(JSLitmus._queue, test) >= 0) {
|
||||
cns.push('test_pending');
|
||||
cell.innerHTML = 'pending';
|
||||
} else if (test.count) {
|
||||
cns.push('test_done');
|
||||
var hz = test.getHz(jsl.$('test_normalize').checked);
|
||||
cell.innerHTML = hz != Infinity ? hz : '∞';
|
||||
} else {
|
||||
cell.innerHTML = 'ready';
|
||||
}
|
||||
}
|
||||
cell.className = cns.join(' ');
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a new test
|
||||
*/
|
||||
test: function(name, f) {
|
||||
// Create the Test object
|
||||
var test = new Test(name, f);
|
||||
JSLitmus._tests.push(test);
|
||||
|
||||
// Re-render if the test state changes
|
||||
test.onChange = JSLitmus.renderTest;
|
||||
|
||||
// Run the next test if this one finished
|
||||
test.onStop = function(test) {
|
||||
if (JSLitmus.onTestFinish) JSLitmus.onTestFinish(test);
|
||||
JSLitmus.currentTest = null;
|
||||
JSLitmus._nextTest();
|
||||
};
|
||||
|
||||
// Render the new test
|
||||
this.renderTest(test);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add all tests to the run queue
|
||||
*/
|
||||
runAll: function(e) {
|
||||
e = e || window.event;
|
||||
var reverse = e && e.shiftKey, len = JSLitmus._tests.length;
|
||||
for (var i = 0; i < len; i++) {
|
||||
JSLitmus._queueTest(JSLitmus._tests[!reverse ? i : (len - i - 1)]);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove all tests from the run queue. The current test has to finish on
|
||||
* it's own though
|
||||
*/
|
||||
stop: function() {
|
||||
while (JSLitmus._queue.length) {
|
||||
var test = JSLitmus._queue.shift();
|
||||
JSLitmus.renderTest(test);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Run the next test in the run queue
|
||||
*/
|
||||
_nextTest: function() {
|
||||
if (!JSLitmus.currentTest) {
|
||||
var test = JSLitmus._queue.shift();
|
||||
if (test) {
|
||||
jsl.$('stop_button').disabled = false;
|
||||
JSLitmus.currentTest = test;
|
||||
test.run();
|
||||
JSLitmus.renderTest(test);
|
||||
if (JSLitmus.onTestStart) JSLitmus.onTestStart(test);
|
||||
} else {
|
||||
jsl.$('stop_button').disabled = true;
|
||||
JSLitmus.renderChart();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Add a test to the run queue
|
||||
*/
|
||||
_queueTest: function(test) {
|
||||
if (jsl.indexOf(JSLitmus._queue, test) >= 0) return;
|
||||
JSLitmus._queue.push(test);
|
||||
JSLitmus.renderTest(test);
|
||||
JSLitmus._nextTest();
|
||||
},
|
||||
|
||||
/**
|
||||
* Generate a Google Chart URL that shows the data for all tests
|
||||
*/
|
||||
chartUrl: function() {
|
||||
var n = JSLitmus._tests.length, markers = [], data = [];
|
||||
var d, min = 0, max = -1e10;
|
||||
var normalize = jsl.$('test_normalize').checked;
|
||||
|
||||
// Gather test data
|
||||
for (var i=0; i < JSLitmus._tests.length; i++) {
|
||||
var test = JSLitmus._tests[i];
|
||||
if (test.count) {
|
||||
var hz = test.getHz(normalize);
|
||||
var v = hz != Infinity ? hz : 0;
|
||||
data.push(v);
|
||||
markers.push('t' + jsl.escape(test.name + '(' + jsl.toLabel(hz)+ ')') + ',000000,0,' +
|
||||
markers.length + ',10');
|
||||
max = Math.max(v, max);
|
||||
}
|
||||
}
|
||||
if (markers.length <= 0) return null;
|
||||
|
||||
// Build chart title
|
||||
var title = document.getElementsByTagName('title');
|
||||
title = (title && title.length) ? title[0].innerHTML : null;
|
||||
var chart_title = [];
|
||||
if (title) chart_title.push(title);
|
||||
chart_title.push('Ops/sec (' + platform + ')');
|
||||
|
||||
// Build labels
|
||||
var labels = [jsl.toLabel(min), jsl.toLabel(max)];
|
||||
|
||||
var w = 250, bw = 15;
|
||||
var bs = 5;
|
||||
var h = markers.length*(bw + bs) + 30 + chart_title.length*20;
|
||||
|
||||
var params = {
|
||||
chtt: escape(chart_title.join('|')),
|
||||
chts: '000000,10',
|
||||
cht: 'bhg', // chart type
|
||||
chd: 't:' + data.join(','), // data set
|
||||
chds: min + ',' + max, // max/min of data
|
||||
chxt: 'x', // label axes
|
||||
chxl: '0:|' + labels.join('|'), // labels
|
||||
chsp: '0,1',
|
||||
chm: markers.join('|'), // test names
|
||||
chbh: [bw, 0, bs].join(','), // bar widths
|
||||
// chf: 'bg,lg,0,eeeeee,0,eeeeee,.5,ffffff,1', // gradient
|
||||
chs: w + 'x' + h
|
||||
};
|
||||
return 'http://chart.apis.google.com/chart?' + jsl.join(params, '=', '&');
|
||||
}
|
||||
};
|
||||
|
||||
JSLitmus._init();
|
||||
})();
|
||||
235
vendor/underscore/test/vendor/qunit.css
vendored
235
vendor/underscore/test/vendor/qunit.css
vendored
@@ -1,235 +0,0 @@
|
||||
/**
|
||||
* 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/underscore/test/vendor/qunit.js
vendored
1977
vendor/underscore/test/vendor/qunit.js
vendored
File diff suppressed because it is too large
Load Diff
6
vendor/underscore/underscore-min.js
vendored
6
vendor/underscore/underscore-min.js
vendored
File diff suppressed because one or more lines are too long
183
vendor/underscore/underscore.js
vendored
183
vendor/underscore/underscore.js
vendored
@@ -1,6 +1,6 @@
|
||||
// Underscore.js 1.4.0
|
||||
// Underscore.js 1.4.4
|
||||
// http://underscorejs.org
|
||||
// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
|
||||
// (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
|
||||
// Underscore may be freely distributed under the MIT license.
|
||||
|
||||
(function() {
|
||||
@@ -24,7 +24,6 @@
|
||||
var push = ArrayProto.push,
|
||||
slice = ArrayProto.slice,
|
||||
concat = ArrayProto.concat,
|
||||
unshift = ArrayProto.unshift,
|
||||
toString = ObjProto.toString,
|
||||
hasOwnProperty = ObjProto.hasOwnProperty;
|
||||
|
||||
@@ -61,11 +60,11 @@
|
||||
}
|
||||
exports._ = _;
|
||||
} else {
|
||||
root['_'] = _;
|
||||
root._ = _;
|
||||
}
|
||||
|
||||
// Current version.
|
||||
_.VERSION = '1.4.0';
|
||||
_.VERSION = '1.4.4';
|
||||
|
||||
// Collection Functions
|
||||
// --------------------
|
||||
@@ -74,6 +73,7 @@
|
||||
// Handles objects with the built-in `forEach`, arrays, and raw objects.
|
||||
// Delegates to **ECMAScript 5**'s native `forEach` if available.
|
||||
var each = _.each = _.forEach = function(obj, iterator, context) {
|
||||
if (obj == null) return;
|
||||
if (nativeForEach && obj.forEach === nativeForEach) {
|
||||
obj.forEach(iterator, context);
|
||||
} else if (obj.length === +obj.length) {
|
||||
@@ -93,6 +93,7 @@
|
||||
// Delegates to **ECMAScript 5**'s native `map` if available.
|
||||
_.map = _.collect = function(obj, iterator, context) {
|
||||
var results = [];
|
||||
if (obj == null) return results;
|
||||
if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
|
||||
each(obj, function(value, index, list) {
|
||||
results[results.length] = iterator.call(context, value, index, list);
|
||||
@@ -100,10 +101,13 @@
|
||||
return results;
|
||||
};
|
||||
|
||||
var reduceError = 'Reduce of empty array with no initial value';
|
||||
|
||||
// **Reduce** builds up a single result from a list of values, aka `inject`,
|
||||
// or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
|
||||
_.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
|
||||
var initial = arguments.length > 2;
|
||||
if (obj == null) obj = [];
|
||||
if (nativeReduce && obj.reduce === nativeReduce) {
|
||||
if (context) iterator = _.bind(iterator, context);
|
||||
return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
|
||||
@@ -116,7 +120,7 @@
|
||||
memo = iterator.call(context, memo, value, index, list);
|
||||
}
|
||||
});
|
||||
if (!initial) throw new TypeError('Reduce of empty array with no initial value');
|
||||
if (!initial) throw new TypeError(reduceError);
|
||||
return memo;
|
||||
};
|
||||
|
||||
@@ -124,9 +128,10 @@
|
||||
// Delegates to **ECMAScript 5**'s native `reduceRight` if available.
|
||||
_.reduceRight = _.foldr = function(obj, iterator, memo, context) {
|
||||
var initial = arguments.length > 2;
|
||||
if (obj == null) obj = [];
|
||||
if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
|
||||
if (context) iterator = _.bind(iterator, context);
|
||||
return arguments.length > 2 ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
|
||||
return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
|
||||
}
|
||||
var length = obj.length;
|
||||
if (length !== +length) {
|
||||
@@ -142,7 +147,7 @@
|
||||
memo = iterator.call(context, memo, obj[index], index, list);
|
||||
}
|
||||
});
|
||||
if (!initial) throw new TypeError('Reduce of empty array with no initial value');
|
||||
if (!initial) throw new TypeError(reduceError);
|
||||
return memo;
|
||||
};
|
||||
|
||||
@@ -163,6 +168,7 @@
|
||||
// Aliased as `select`.
|
||||
_.filter = _.select = function(obj, iterator, context) {
|
||||
var results = [];
|
||||
if (obj == null) return results;
|
||||
if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
|
||||
each(obj, function(value, index, list) {
|
||||
if (iterator.call(context, value, index, list)) results[results.length] = value;
|
||||
@@ -172,11 +178,9 @@
|
||||
|
||||
// Return all the elements for which a truth test fails.
|
||||
_.reject = function(obj, iterator, context) {
|
||||
var results = [];
|
||||
each(obj, function(value, index, list) {
|
||||
if (!iterator.call(context, value, index, list)) results[results.length] = value;
|
||||
});
|
||||
return results;
|
||||
return _.filter(obj, function(value, index, list) {
|
||||
return !iterator.call(context, value, index, list);
|
||||
}, context);
|
||||
};
|
||||
|
||||
// Determine whether all of the elements match a truth test.
|
||||
@@ -185,6 +189,7 @@
|
||||
_.every = _.all = function(obj, iterator, context) {
|
||||
iterator || (iterator = _.identity);
|
||||
var result = true;
|
||||
if (obj == null) return result;
|
||||
if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
|
||||
each(obj, function(value, index, list) {
|
||||
if (!(result = result && iterator.call(context, value, index, list))) return breaker;
|
||||
@@ -198,6 +203,7 @@
|
||||
var any = _.some = _.any = function(obj, iterator, context) {
|
||||
iterator || (iterator = _.identity);
|
||||
var result = false;
|
||||
if (obj == null) return result;
|
||||
if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
|
||||
each(obj, function(value, index, list) {
|
||||
if (result || (result = iterator.call(context, value, index, list))) return breaker;
|
||||
@@ -208,19 +214,19 @@
|
||||
// Determine if the array or object contains a given value (using `===`).
|
||||
// Aliased as `include`.
|
||||
_.contains = _.include = function(obj, target) {
|
||||
var found = false;
|
||||
if (obj == null) return false;
|
||||
if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
|
||||
found = any(obj, function(value) {
|
||||
return any(obj, function(value) {
|
||||
return value === target;
|
||||
});
|
||||
return found;
|
||||
};
|
||||
|
||||
// Invoke a method (with arguments) on every item in a collection.
|
||||
_.invoke = function(obj, method) {
|
||||
var args = slice.call(arguments, 2);
|
||||
var isFunc = _.isFunction(method);
|
||||
return _.map(obj, function(value) {
|
||||
return (_.isFunction(method) ? method : value[method]).apply(value, args);
|
||||
return (isFunc ? method : value[method]).apply(value, args);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -230,10 +236,10 @@
|
||||
};
|
||||
|
||||
// Convenience version of a common use case of `filter`: selecting only objects
|
||||
// with specific `key:value` pairs.
|
||||
_.where = function(obj, attrs) {
|
||||
if (_.isEmpty(attrs)) return [];
|
||||
return _.filter(obj, function(value) {
|
||||
// containing specific `key:value` pairs.
|
||||
_.where = function(obj, attrs, first) {
|
||||
if (_.isEmpty(attrs)) return first ? null : [];
|
||||
return _[first ? 'find' : 'filter'](obj, function(value) {
|
||||
for (var key in attrs) {
|
||||
if (attrs[key] !== value[key]) return false;
|
||||
}
|
||||
@@ -241,6 +247,12 @@
|
||||
});
|
||||
};
|
||||
|
||||
// Convenience version of a common use case of `find`: getting the first object
|
||||
// containing specific `key:value` pairs.
|
||||
_.findWhere = function(obj, attrs) {
|
||||
return _.where(obj, attrs, true);
|
||||
};
|
||||
|
||||
// Return the maximum element or (element-based computation).
|
||||
// Can't optimize arrays of integers longer than 65,535 elements.
|
||||
// See: https://bugs.webkit.org/show_bug.cgi?id=80797
|
||||
@@ -249,7 +261,7 @@
|
||||
return Math.max.apply(Math, obj);
|
||||
}
|
||||
if (!iterator && _.isEmpty(obj)) return -Infinity;
|
||||
var result = {computed : -Infinity};
|
||||
var result = {computed : -Infinity, value: -Infinity};
|
||||
each(obj, function(value, index, list) {
|
||||
var computed = iterator ? iterator.call(context, value, index, list) : value;
|
||||
computed >= result.computed && (result = {value : value, computed : computed});
|
||||
@@ -263,7 +275,7 @@
|
||||
return Math.min.apply(Math, obj);
|
||||
}
|
||||
if (!iterator && _.isEmpty(obj)) return Infinity;
|
||||
var result = {computed : Infinity};
|
||||
var result = {computed : Infinity, value: Infinity};
|
||||
each(obj, function(value, index, list) {
|
||||
var computed = iterator ? iterator.call(context, value, index, list) : value;
|
||||
computed < result.computed && (result = {value : value, computed : computed});
|
||||
@@ -312,7 +324,7 @@
|
||||
// An internal function used for aggregate "group by" operations.
|
||||
var group = function(obj, value, context, behavior) {
|
||||
var result = {};
|
||||
var iterator = lookupIterator(value);
|
||||
var iterator = lookupIterator(value || _.identity);
|
||||
each(obj, function(value, index) {
|
||||
var key = iterator.call(context, value, index, obj);
|
||||
behavior(result, key, value);
|
||||
@@ -332,7 +344,7 @@
|
||||
// either a string attribute to count by, or a function that returns the
|
||||
// criterion.
|
||||
_.countBy = function(obj, value, context) {
|
||||
return group(obj, value, context, function(result, key, value) {
|
||||
return group(obj, value, context, function(result, key) {
|
||||
if (!_.has(result, key)) result[key] = 0;
|
||||
result[key]++;
|
||||
});
|
||||
@@ -354,12 +366,14 @@
|
||||
// Safely convert anything iterable into a real, live array.
|
||||
_.toArray = function(obj) {
|
||||
if (!obj) return [];
|
||||
if (obj.length === +obj.length) return slice.call(obj);
|
||||
if (_.isArray(obj)) return slice.call(obj);
|
||||
if (obj.length === +obj.length) return _.map(obj, _.identity);
|
||||
return _.values(obj);
|
||||
};
|
||||
|
||||
// Return the number of elements in an object.
|
||||
_.size = function(obj) {
|
||||
if (obj == null) return 0;
|
||||
return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;
|
||||
};
|
||||
|
||||
@@ -370,6 +384,7 @@
|
||||
// values in the array. Aliased as `head` and `take`. The **guard** check
|
||||
// allows it to work with `_.map`.
|
||||
_.first = _.head = _.take = function(array, n, guard) {
|
||||
if (array == null) return void 0;
|
||||
return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
|
||||
};
|
||||
|
||||
@@ -384,6 +399,7 @@
|
||||
// Get the last element of an array. Passing **n** will return the last N
|
||||
// values in the array. The **guard** check allows it to work with `_.map`.
|
||||
_.last = function(array, n, guard) {
|
||||
if (array == null) return void 0;
|
||||
if ((n != null) && !guard) {
|
||||
return slice.call(array, Math.max(array.length - n, 0));
|
||||
} else {
|
||||
@@ -401,7 +417,7 @@
|
||||
|
||||
// Trim out all falsy values from an array.
|
||||
_.compact = function(array) {
|
||||
return _.filter(array, function(value){ return !!value; });
|
||||
return _.filter(array, _.identity);
|
||||
};
|
||||
|
||||
// Internal implementation of a recursive `flatten` function.
|
||||
@@ -430,6 +446,11 @@
|
||||
// been sorted, you have the option of using a faster algorithm.
|
||||
// Aliased as `unique`.
|
||||
_.uniq = _.unique = function(array, isSorted, iterator, context) {
|
||||
if (_.isFunction(isSorted)) {
|
||||
context = iterator;
|
||||
iterator = isSorted;
|
||||
isSorted = false;
|
||||
}
|
||||
var initial = iterator ? _.map(array, iterator, context) : array;
|
||||
var results = [];
|
||||
var seen = [];
|
||||
@@ -482,6 +503,7 @@
|
||||
// pairs, or two parallel arrays of the same length -- one of keys, and one of
|
||||
// the corresponding values.
|
||||
_.object = function(list, values) {
|
||||
if (list == null) return {};
|
||||
var result = {};
|
||||
for (var i = 0, l = list.length; i < l; i++) {
|
||||
if (values) {
|
||||
@@ -500,6 +522,7 @@
|
||||
// If the array is large and already in sort order, pass `true`
|
||||
// for **isSorted** to use binary search.
|
||||
_.indexOf = function(array, item, isSorted) {
|
||||
if (array == null) return -1;
|
||||
var i = 0, l = array.length;
|
||||
if (isSorted) {
|
||||
if (typeof isSorted == 'number') {
|
||||
@@ -516,6 +539,7 @@
|
||||
|
||||
// Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
|
||||
_.lastIndexOf = function(array, item, from) {
|
||||
if (array == null) return -1;
|
||||
var hasIndex = from != null;
|
||||
if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
|
||||
return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
|
||||
@@ -550,25 +574,23 @@
|
||||
// Function (ahem) Functions
|
||||
// ------------------
|
||||
|
||||
// Reusable constructor function for prototype setting.
|
||||
var ctor = function(){};
|
||||
|
||||
// Create a function bound to a given object (assigning `this`, and arguments,
|
||||
// optionally). Binding with arguments is also known as `curry`.
|
||||
// Delegates to **ECMAScript 5**'s native `Function.bind` if available.
|
||||
// We check for `func.bind` first, to fail fast when `func` is undefined.
|
||||
_.bind = function bind(func, context) {
|
||||
var bound, args;
|
||||
// optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
|
||||
// available.
|
||||
_.bind = function(func, context) {
|
||||
if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
|
||||
if (!_.isFunction(func)) throw new TypeError;
|
||||
args = slice.call(arguments, 2);
|
||||
return bound = function() {
|
||||
if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
|
||||
ctor.prototype = func.prototype;
|
||||
var self = new ctor;
|
||||
var result = func.apply(self, args.concat(slice.call(arguments)));
|
||||
if (Object(result) === result) return result;
|
||||
return self;
|
||||
var args = slice.call(arguments, 2);
|
||||
return function() {
|
||||
return func.apply(context, args.concat(slice.call(arguments)));
|
||||
};
|
||||
};
|
||||
|
||||
// Partially apply a function by creating a version that has had some of its
|
||||
// arguments pre-filled, without changing its dynamic `this` context.
|
||||
_.partial = function(func) {
|
||||
var args = slice.call(arguments, 1);
|
||||
return function() {
|
||||
return func.apply(this, args.concat(slice.call(arguments)));
|
||||
};
|
||||
};
|
||||
|
||||
@@ -576,7 +598,7 @@
|
||||
// all callbacks defined on an object belong to it.
|
||||
_.bindAll = function(obj) {
|
||||
var funcs = slice.call(arguments, 1);
|
||||
if (funcs.length == 0) funcs = _.functions(obj);
|
||||
if (funcs.length === 0) funcs = _.functions(obj);
|
||||
each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
|
||||
return obj;
|
||||
};
|
||||
@@ -607,25 +629,26 @@
|
||||
// Returns a function, that, when invoked, will only be triggered at most once
|
||||
// during a given window of time.
|
||||
_.throttle = function(func, wait) {
|
||||
var context, args, timeout, throttling, more, result;
|
||||
var whenDone = _.debounce(function(){ more = throttling = false; }, wait);
|
||||
var context, args, timeout, result;
|
||||
var previous = 0;
|
||||
var later = function() {
|
||||
previous = new Date;
|
||||
timeout = null;
|
||||
result = func.apply(context, args);
|
||||
};
|
||||
return function() {
|
||||
context = this; args = arguments;
|
||||
var later = function() {
|
||||
var now = new Date;
|
||||
var remaining = wait - (now - previous);
|
||||
context = this;
|
||||
args = arguments;
|
||||
if (remaining <= 0) {
|
||||
clearTimeout(timeout);
|
||||
timeout = null;
|
||||
if (more) {
|
||||
result = func.apply(context, args);
|
||||
}
|
||||
whenDone();
|
||||
};
|
||||
if (!timeout) timeout = setTimeout(later, wait);
|
||||
if (throttling) {
|
||||
more = true;
|
||||
} else {
|
||||
throttling = true;
|
||||
previous = now;
|
||||
result = func.apply(context, args);
|
||||
} else if (!timeout) {
|
||||
timeout = setTimeout(later, remaining);
|
||||
}
|
||||
whenDone();
|
||||
return result;
|
||||
};
|
||||
};
|
||||
@@ -743,8 +766,10 @@
|
||||
// Extend a given object with all the properties in passed-in object(s).
|
||||
_.extend = function(obj) {
|
||||
each(slice.call(arguments, 1), function(source) {
|
||||
for (var prop in source) {
|
||||
obj[prop] = source[prop];
|
||||
if (source) {
|
||||
for (var prop in source) {
|
||||
obj[prop] = source[prop];
|
||||
}
|
||||
}
|
||||
});
|
||||
return obj;
|
||||
@@ -773,8 +798,10 @@
|
||||
// Fill in a given object with default properties.
|
||||
_.defaults = function(obj) {
|
||||
each(slice.call(arguments, 1), function(source) {
|
||||
for (var prop in source) {
|
||||
if (obj[prop] == null) obj[prop] = source[prop];
|
||||
if (source) {
|
||||
for (var prop in source) {
|
||||
if (obj[prop] == null) obj[prop] = source[prop];
|
||||
}
|
||||
}
|
||||
});
|
||||
return obj;
|
||||
@@ -939,7 +966,7 @@
|
||||
|
||||
// Is a given object a finite number?
|
||||
_.isFinite = function(obj) {
|
||||
return _.isNumber(obj) && isFinite(obj);
|
||||
return isFinite(obj) && !isNaN(parseFloat(obj));
|
||||
};
|
||||
|
||||
// Is the given value `NaN`? (NaN is the only number which does not equal itself).
|
||||
@@ -985,7 +1012,9 @@
|
||||
|
||||
// Run a function **n** times.
|
||||
_.times = function(n, iterator, context) {
|
||||
for (var i = 0; i < n; i++) iterator.call(context, i);
|
||||
var accum = Array(n);
|
||||
for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
|
||||
return accum;
|
||||
};
|
||||
|
||||
// Return a random integer between min and max (inclusive).
|
||||
@@ -994,7 +1023,7 @@
|
||||
max = min;
|
||||
min = 0;
|
||||
}
|
||||
return min + (0 | Math.random() * (max - min + 1));
|
||||
return min + Math.floor(Math.random() * (max - min + 1));
|
||||
};
|
||||
|
||||
// List of HTML entities for escaping.
|
||||
@@ -1050,7 +1079,7 @@
|
||||
// Useful for temporary DOM ids.
|
||||
var idCounter = 0;
|
||||
_.uniqueId = function(prefix) {
|
||||
var id = idCounter++;
|
||||
var id = ++idCounter + '';
|
||||
return prefix ? prefix + id : id;
|
||||
};
|
||||
|
||||
@@ -1085,6 +1114,7 @@
|
||||
// Underscore templating handles arbitrary delimiters, preserves whitespace,
|
||||
// and correctly escapes quotes within interpolated code.
|
||||
_.template = function(text, data, settings) {
|
||||
var render;
|
||||
settings = _.defaults({}, settings, _.templateSettings);
|
||||
|
||||
// Combine delimiters into one regular expression via alternation.
|
||||
@@ -1100,11 +1130,18 @@
|
||||
text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
|
||||
source += text.slice(index, offset)
|
||||
.replace(escaper, function(match) { return '\\' + escapes[match]; });
|
||||
source +=
|
||||
escape ? "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'" :
|
||||
interpolate ? "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'" :
|
||||
evaluate ? "';\n" + evaluate + "\n__p+='" : '';
|
||||
|
||||
if (escape) {
|
||||
source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
|
||||
}
|
||||
if (interpolate) {
|
||||
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
|
||||
}
|
||||
if (evaluate) {
|
||||
source += "';\n" + evaluate + "\n__p+='";
|
||||
}
|
||||
index = offset + match.length;
|
||||
return match;
|
||||
});
|
||||
source += "';\n";
|
||||
|
||||
@@ -1116,7 +1153,7 @@
|
||||
source + "return __p;\n";
|
||||
|
||||
try {
|
||||
var render = new Function(settings.variable || 'obj', '_', source);
|
||||
render = new Function(settings.variable || 'obj', '_', source);
|
||||
} catch (e) {
|
||||
e.source = source;
|
||||
throw e;
|
||||
|
||||
Reference in New Issue
Block a user