Compare commits
893 Commits
starting
...
2.0.0-alph
Author | SHA1 | Date | |
---|---|---|---|
d53c898499 | |||
552985e305 | |||
20e874d3c6 | |||
471a1b6d12 | |||
f999d5a156 | |||
f74d7727ca | |||
3baf815d76 | |||
96cadcc29e | |||
31b6687894 | |||
381d4cb30a | |||
5030ffb01c | |||
9ce0870f6c | |||
246151b2f9 | |||
83f1856d6a | |||
c280fe816c | |||
b071b66b45 | |||
fde65c7e88 | |||
bae6b91e7d | |||
2b714df64e | |||
c7572ac1f9 | |||
ec3a78289f | |||
f303f0c17a | |||
f543834be9 | |||
6bef1c4169 | |||
652ed0cf6d | |||
559f54e92b | |||
17e1d7f117 | |||
5fa54a92bc | |||
ba7956f521 | |||
c2fa4b7191 | |||
d32f58926d | |||
6a0fe93ba9 | |||
1fae8d6377 | |||
dc060e8b64 | |||
b746e0c9f0 | |||
e67b7e87b2 | |||
0a0b84a07d | |||
927b4d01a9 | |||
5035a42287 | |||
40150379ae | |||
1d24e2cf23 | |||
9e36539052 | |||
0602f68ae3 | |||
2b60d1bae1 | |||
0b43e3cf32 | |||
c9d636aa11 | |||
be88cc7697 | |||
ba07f39347 | |||
4c8e11a577 | |||
3d6c44e2a7 | |||
c60091b949 | |||
a504fa835e | |||
8811337622 | |||
921fb9f2ce | |||
e93b5a1d5b | |||
db7a1f19ba | |||
ef27919f7f | |||
c571b2693e | |||
8bcfb2d465 | |||
93f464a145 | |||
95b7896d9b | |||
ad26bed0ed | |||
62a95823e0 | |||
c8d83dba7d | |||
22f5925202 | |||
cd52d8a3be | |||
a9d6fd9afa | |||
5c53cf6486 | |||
74882c6c38 | |||
c8947d77bf | |||
4f3acdb004 | |||
6404dd8293 | |||
f19970a481 | |||
6f0631c978 | |||
e5d06e479a | |||
d523613329 | |||
cfcae6b293 | |||
000a8e25a2 | |||
8a3b0b366f | |||
383f0a1f30 | |||
e323c07ab9 | |||
f9908cd436 | |||
24bc4b66d0 | |||
2351896cc0 | |||
307011a96c | |||
6f3368ef16 | |||
cdf791f0c5 | |||
75578f41e7 | |||
ffb219fb91 | |||
eb2784eb81 | |||
28ee0612cb | |||
a80921b45d | |||
0db88f34b8 | |||
35f0ee510a | |||
d7df853bde | |||
0387221da8 | |||
c39c8ebcd0 | |||
5d2af54730 | |||
a9be2ebf1b | |||
ec2d8cc2c8 | |||
05d66bba3f | |||
b14417498a | |||
05becf8431 | |||
160c38b5ca | |||
9b0fa0dedc | |||
533c64d4ea | |||
c1157d62a8 | |||
7b1e9286d8 | |||
01fb8e6635 | |||
9d90128463 | |||
34cfc9f474 | |||
ebe1e73b1a | |||
8ce0a67c81 | |||
c065fb1422 | |||
cda35101df | |||
c32dbad747 | |||
30b6542fc8 | |||
2b6a653050 | |||
34d75e8918 | |||
2c25055828 | |||
96f629d441 | |||
a2770c8a52 | |||
4a3fd5e855 | |||
608017776e | |||
0c7f05f56a | |||
c6335c128e | |||
fb42d5908e | |||
8609543ad0 | |||
f83f1ee0ce | |||
1db6870a81 | |||
c19c69f336 | |||
b390f441a1 | |||
79f564be46 | |||
23d59df81a | |||
ef3e12e803 | |||
5fe88d63ef | |||
0f3a8f369a | |||
26d5d17ebe | |||
bb7ffce7eb | |||
551586ced0 | |||
1dc8ba6920 | |||
d773b6a00a | |||
f6cd26b0a6 | |||
5a52c0b71d | |||
662da0d728 | |||
df59e969cf | |||
d27e5512c0 | |||
d48fae3566 | |||
3525c9c074 | |||
05774f6c8a | |||
16447ce75c | |||
15f1eb28a2 | |||
e50f537667 | |||
ed8364741b | |||
6c1cb089b5 | |||
4b98ed114e | |||
d308e55e12 | |||
10bc7e948c | |||
9988471fb8 | |||
05fa9bc9fb | |||
57b88ec2d6 | |||
b1c9bf14b2 | |||
588fbfd848 | |||
b2a24e021f | |||
661a04798e | |||
665ccafd73 | |||
f35dbb99b5 | |||
a393f84fa4 | |||
92c2c33a84 | |||
9802debf71 | |||
2287938f5a | |||
5103f080e9 | |||
1f20ef9787 | |||
1ad6558229 | |||
d61a0dfa22 | |||
ac510b67cc | |||
5ed091e260 | |||
cc2c8f6b00 | |||
c28952c707 | |||
30c3e5a84e | |||
2ff3873881 | |||
aec51d616b | |||
c5996529c3 | |||
00c3693daa | |||
fed86fc8ac | |||
705ee46f31 | |||
f210c41c1f | |||
863eb3c559 | |||
b6b52e62b2 | |||
dd9b08cce8 | |||
e61d82b9be | |||
aabc898f3b | |||
bdeac30a96 | |||
4afd2b4138 | |||
dee4ecbb3f | |||
4210b0e66a | |||
2d6c44b54a | |||
c45283216f | |||
826af401a9 | |||
28c2b8f432 | |||
c9ab8e4be8 | |||
1054f6a9ab | |||
f6eeb9aa66 | |||
91ccc9af98 | |||
ec90fcd290 | |||
a664f5a6de | |||
7643d979c7 | |||
d18463dcdc | |||
f9f917bfa4 | |||
e89bf01c2b | |||
d04a515eb0 | |||
0ae89ac096 | |||
6ec5d5daaf | |||
62b1a08f06 | |||
c54f5e0ba2 | |||
37a8f1037e | |||
4ba81bf3eb | |||
c204835969 | |||
ac28ac324d | |||
8aa3fcfb63 | |||
1beadb8607 | |||
bd8724e652 | |||
73d15edef5 | |||
adaa157317 | |||
791caf0037 | |||
8ab773538b | |||
5c88f662cd | |||
cd7aef2139 | |||
50c6efa187 | |||
302c5d5005 | |||
b6b9ede425 | |||
118f0520a2 | |||
ba80bd43ad | |||
ed6298c33f | |||
db5486a347 | |||
b9b58f7ed9 | |||
33f5aafd6c | |||
4b34ef9036 | |||
8c409e9251 | |||
398e70ad39 | |||
9407c12923 | |||
a4693ef679 | |||
9d5f760597 | |||
8bebcfb844 | |||
8a0eb08745 | |||
1dce4699de | |||
7bff919782 | |||
c6dc78183d | |||
9a72f19b97 | |||
25a952755e | |||
b2da2978ee | |||
8b9400ad92 | |||
3571450b42 | |||
72bb5bdd5a | |||
04a9eb8820 | |||
0f002a5b18 | |||
b066b8d15a | |||
7b511462af | |||
3a53f67911 | |||
155b1e2b35 | |||
aad5795408 | |||
83b97c485b | |||
5db89071d4 | |||
c29ab86d85 | |||
6b02cb9b44 | |||
88c607da03 | |||
f9fd4926ef | |||
986038242a | |||
8e84f8a1c4 | |||
edfbc25768 | |||
05a1c6c183 | |||
534cbb4bf5 | |||
d9ceb42bfe | |||
8d6943227d | |||
3011cd86bd | |||
cfba38b462 | |||
11e4385173 | |||
ad29b12cde | |||
842459aa46 | |||
b033416a45 | |||
7310b09a1a | |||
bb2eda2d15 | |||
0114cd97b6 | |||
fc13cdab3a | |||
3644036693 | |||
c397297eef | |||
1eea2b254e | |||
0e04467b8a | |||
9fbb3adbe2 | |||
b6f29b4448 | |||
421d8916a6 | |||
a38a0d6f87 | |||
7a4a635399 | |||
557d54b3de | |||
c47902a471 | |||
25cd6e4321 | |||
6ad5fa0d9d | |||
666336be1a | |||
77bf90dff1 | |||
8ad0205948 | |||
7ff17db113 | |||
1d11fdecdc | |||
b1ef30aa20 | |||
28659efa69 | |||
6c59894a29 | |||
47b8b48ee7 | |||
3969009fe7 | |||
ecb068019b | |||
5114411749 | |||
08f21dbf51 | |||
d8c7c274e4 | |||
fadabf79e3 | |||
23cec1e8e2 | |||
c36ea0221e | |||
685a6507b6 | |||
846354473d | |||
390cfb793b | |||
17392f663f | |||
8b6fa1cf19 | |||
909233f724 | |||
0e82970a29 | |||
cdbb2473bb | |||
c20060d259 | |||
38926f7123 | |||
0efd89ae5d | |||
718d2ae2ee | |||
af9dcad8e3 | |||
772b529a8e | |||
111fa60a93 | |||
e9f236b70f | |||
78d3f62b6a | |||
d310a9c0b4 | |||
7dc524ed58 | |||
032f8b7840 | |||
4f2b9a4c28 | |||
1ac7bb3bb8 | |||
f302f70330 | |||
555dd93ed9 | |||
96b0a1c75e | |||
c8a0ed40bd | |||
e11c20541a | |||
c75e216871 | |||
fd1d60f03b | |||
e8a6c95e2a | |||
358a6750ed | |||
4320859e1b | |||
98e7a38e50 | |||
229e770a1d | |||
5036086fb3 | |||
97d24563f4 | |||
655ed851f0 | |||
f8f79dc76c | |||
a574154108 | |||
7f976381d5 | |||
ac80df0959 | |||
aff85b5037 | |||
5691063ba0 | |||
7498758584 | |||
92d6aa1f32 | |||
3256ff1c73 | |||
f9c1de46b3 | |||
a9ce0f7afb | |||
1a4ab2c57a | |||
77d1fc149a | |||
c2a42d5d2b | |||
01d5c29513 | |||
7844e3a275 | |||
a5638a940c | |||
4665726f48 | |||
e8ad0d1776 | |||
28022f472d | |||
4f3433b5bd | |||
2185e7cee9 | |||
c82cc47767 | |||
66f5e30d7c | |||
1a0da11e55 | |||
abc8878547 | |||
75e9d3f634 | |||
248caefb7e | |||
853d1de6ec | |||
84dc6ae76b | |||
05219a54cd | |||
4b62a722f0 | |||
61b69c63ed | |||
09b39bf77a | |||
42f6baeaec | |||
8ef183b593 | |||
2cb066215a | |||
200e190f70 | |||
44f829dbc6 | |||
401c9efad7 | |||
900bf8e483 | |||
271ced8ac4 | |||
c5bd3f0773 | |||
ad23921814 | |||
31cbec0857 | |||
d717529e9a | |||
c68fa27444 | |||
d2507ac760 | |||
4ce0d5e024 | |||
5d9e573b3e | |||
51839ca677 | |||
7225416661 | |||
5e4fa5cf07 | |||
fa28b28d0a | |||
f0ef72d6cc | |||
a58c9f83bd | |||
624a33f7f8 | |||
20a033e4c9 | |||
93c331d103 | |||
51c477925a | |||
1daa8aa3a1 | |||
62bf777ef1 | |||
aaf3edd131 | |||
6bba289a3c | |||
b0c735f72c | |||
0e2047f9ca | |||
e30ad2ec2c | |||
c509057f65 | |||
e138add584 | |||
49777648b3 | |||
cb87fa0970 | |||
649e276610 | |||
5ef11774c2 | |||
75db2c5241 | |||
c8ebd11d63 | |||
6651aa1e1d | |||
3f28d08778 | |||
ab28676d02 | |||
577a80371f | |||
01fdb4afc6 | |||
be7504d451 | |||
169e4e862d | |||
abc3de7efe | |||
0b1bb172c9 | |||
0856516ae9 | |||
705d3aacff | |||
1d0078415f | |||
9d1df21d91 | |||
3f36a3c119 | |||
8c15ccecd1 | |||
e966869744 | |||
6b017fb388 | |||
bb6f59e423 | |||
c9cec60007 | |||
f356d03362 | |||
0520ca68b4 | |||
8e1d53b5e9 | |||
f5b56c627b | |||
740d85cad8 | |||
33bba094d2 | |||
f88c4b77ca | |||
75da6e4c4a | |||
1864f60afb | |||
457c15cd6c | |||
28feac9411 | |||
9153331303 | |||
9d5c33f9dd | |||
2713b7877b | |||
2f0fef8ee1 | |||
259f872cea | |||
68ed8f1b6b | |||
ef7014fe19 | |||
46ad3552c7 | |||
4965226f3f | |||
ea546f5069 | |||
cf32213079 | |||
ce6a2ba836 | |||
0f4a089c32 | |||
3c77855b39 | |||
c1579222bd | |||
f863ea0db5 | |||
e4342743c0 | |||
9e8d31d532 | |||
f75a50c1dd | |||
c671706518 | |||
ead21c91a4 | |||
87dcd5eb6f | |||
8faf6364dc | |||
b71fe311fc | |||
bb50fc131b | |||
3aac2fefd7 | |||
fb67e37339 | |||
648c514c28 | |||
511e832ee2 | |||
09f8d8f7ba | |||
1205f54d01 | |||
b5032fd374 | |||
a7a9463624 | |||
59824e40e8 | |||
a51a5c2968 | |||
e3c11045bf | |||
414e58edb5 | |||
3bb3bff1f2 | |||
d2d4e7d783 | |||
ee1b574baf | |||
c0f3778dda | |||
d4925b61ff | |||
5b104936ae | |||
14988d4415 | |||
cd953ceb48 | |||
726fecbfb6 | |||
818bb9b697 | |||
e4586249fa | |||
4c1e978536 | |||
3d62546314 | |||
b9eab463f7 | |||
dff4795e49 | |||
ab74e1ed4e | |||
902984cc10 | |||
ce431f279e | |||
7fb2f2069c | |||
c269bd5d3c | |||
b72eb0783b | |||
a801da6f7c | |||
6fcd3709cf | |||
1b2754dacd | |||
e617ca6323 | |||
15376a6d24 | |||
867705bd2c | |||
6ab19dd095 | |||
99fdb9ac41 | |||
2827ca1559 | |||
8ea03d0380 | |||
d1ec2e18cd | |||
aa58e4bba5 | |||
0a97f0b645 | |||
8a5cf896d0 | |||
22c79df98d | |||
a52798543a | |||
1cbdb9cd17 | |||
4c9b8ebb0c | |||
6aea629cd3 | |||
649fd5a7a9 | |||
40c4eb7240 | |||
cd05ed8de9 | |||
42e7fc5252 | |||
7740fc071c | |||
bdf6af9bd6 | |||
2f83efaac8 | |||
32c5ab956c | |||
b111ca9471 | |||
725f909ff8 | |||
427f0d021c | |||
9fc9d53566 | |||
6dece68bb8 | |||
0676fef61f | |||
1d52cfba13 | |||
bfa381b35a | |||
f78406392b | |||
623edcd2d8 | |||
b5e350b18c | |||
87cf434929 | |||
4bab25b366 | |||
6896305e34 | |||
8ccafb0524 | |||
8a92a1f13e | |||
d0059b5d75 | |||
fa8e059f28 | |||
8e18d6c6cf | |||
afe0e45453 | |||
2e3e41ba64 | |||
d74dd1126b | |||
0ff99081bd | |||
6f4b6783c0 | |||
b1bc792b56 | |||
d4b8a86509 | |||
642e7e5c46 | |||
4650d25a53 | |||
7551a28f1a | |||
e51a48fe4c | |||
22c6c09daf | |||
e70a2f21dd | |||
97e6fb6835 | |||
14a7b9f794 | |||
fa1ec48549 | |||
f7f06c5ad4 | |||
e23004df52 | |||
fe70c2647a | |||
ada1e642c5 | |||
817c79ca77 | |||
a97a2266d3 | |||
8b3c808cb0 | |||
2d929e73ec | |||
681d06386d | |||
77b31ab42f | |||
5b4eb0c6d7 | |||
5c25248582 | |||
64ad74acbe | |||
02997f473a | |||
abda569b55 | |||
447018b54b | |||
0a200aff70 | |||
883e1c1541 | |||
aabe83cf63 | |||
fbd6851860 | |||
d6dae0cc85 | |||
376d508934 | |||
a00cb1de50 | |||
56f3429cc9 | |||
4943c0f887 | |||
00e2d70f05 | |||
e52d71060f | |||
01869f9fa8 | |||
526c51d1a6 | |||
2b4d30d931 | |||
3dc4df2ffa | |||
f830cfca12 | |||
eac5c88893 | |||
abfe175c9e | |||
0fc66daef6 | |||
5a095bb257 | |||
de31aca7a7 | |||
97220dd2ba | |||
e1b0bab9a6 | |||
66a2f9b23a | |||
a8533b2133 | |||
87ac100c66 | |||
487c4d23c1 | |||
8906cdbab8 | |||
88963b438f | |||
4fd4a1d15c | |||
371c8b8a1c | |||
eb87f5f851 | |||
27d227283c | |||
ea9d24be31 | |||
5408abca68 | |||
233cb0f96a | |||
8b28e99373 | |||
923d90bce8 | |||
97fc248e00 | |||
7bd682bb27 | |||
e927342e58 | |||
ae84eb7462 | |||
f89bb8eaf3 | |||
0d0b3a35da | |||
cf7bef58b0 | |||
c65fd31e86 | |||
6600ac7031 | |||
957384ceeb | |||
d3e391d176 | |||
0658d5602e | |||
458213d055 | |||
cd1295a823 | |||
5d302c504e | |||
68faddbf5c | |||
dc9c614da2 | |||
8c1adabe1c | |||
213dabdceb | |||
6ecaa9aebb | |||
cb2e646332 | |||
fef1dee7aa | |||
e14543498c | |||
c25478380c | |||
e819e97f9a | |||
f149ae79c6 | |||
ffe13078e5 | |||
f0d0fe0801 | |||
d630d5baa5 | |||
7cac7c5157 | |||
aba61f22a6 | |||
8475c63a6a | |||
2d09f84182 | |||
ef6e0d8eb8 | |||
db97d73c3b | |||
0e3d0fbec6 | |||
896a1564ef | |||
8b97cf1479 | |||
b5c9f9ed9b | |||
bda120d862 | |||
3177576ad6 | |||
896a0457f8 | |||
caf8e2723d | |||
0107543a33 | |||
7d29636087 | |||
70433e6b73 | |||
3667854a8f | |||
c5c1c9e38e | |||
308823b6ea | |||
c05bad381c | |||
4a961f4ecb | |||
6c8398df9b | |||
ff6e7754ae | |||
28ba179e31 | |||
b96e560c8d | |||
7c95cea3a8 | |||
34501aaae6 | |||
dbfc4c1c16 | |||
301863b105 | |||
ef8dc40492 | |||
6dbd4d969b | |||
3dd0ac1f0a | |||
5b42272365 | |||
1f6c6dbf2f | |||
0012caa4d5 | |||
8499cf84c3 | |||
daf0f472b3 | |||
a3decad4c2 | |||
7b790a3369 | |||
e18920884e | |||
6f8fef4f13 | |||
e295940833 | |||
2ed7622239 | |||
6ce085a21a | |||
e34146fc14 | |||
4e2316c742 | |||
785900f722 | |||
5ce5a87abe | |||
afe5465862 | |||
678d541da7 | |||
f0477e164a | |||
b5002fb46b | |||
82127571b5 | |||
f6e9d1f857 | |||
2cab7c79c3 | |||
bba849909c | |||
cac74c73e1 | |||
f375dbd013 | |||
ea58ef85fc | |||
bf7933714a | |||
564477b8a0 | |||
7e2c04e805 | |||
8fa1539bac | |||
f45281a10a | |||
e9f70293ac | |||
61cb99ea42 | |||
5408a9a72d | |||
22c1a0d030 | |||
8c3007e4b5 | |||
838aa2aaa9 | |||
3285ffba16 | |||
17e8857efc | |||
226cbc7db3 | |||
cc7c7b3321 | |||
70cea03b4b | |||
a027912891 | |||
3bdf669ddf | |||
b94b04c074 | |||
cfc5dd830c | |||
a3097aaf05 | |||
69c3bff086 | |||
50098767fc | |||
de581ea8b3 | |||
9f8a9c6fc7 | |||
ad083ed28f | |||
105ba30ce9 | |||
ee8bf0b3c0 | |||
41262f4265 | |||
c349eb4fa4 | |||
ca958464c4 | |||
d6003ee0ab | |||
bc248e9a15 | |||
42c0171b40 | |||
1a99090b45 | |||
b7eea4f577 | |||
9c62b5867e | |||
2560af731a | |||
86211eb5f0 | |||
a3387b7f48 | |||
94a48e8640 | |||
d8aeb40b49 | |||
52c55d0ee8 | |||
438c2b31e4 | |||
57e308dd46 | |||
c922b5a112 | |||
d552303cd5 | |||
1d4d18d9db | |||
069bbf3ed0 | |||
a4a2d4e56d | |||
d77f409093 | |||
25c709c58e | |||
bc909d1d0f | |||
a6736ff9f2 | |||
894a0f0ee5 | |||
abea92af59 | |||
bcbed2812d | |||
c0b04ca0bc | |||
86dc3e5b07 | |||
c1aa65239e | |||
be5ccf6957 | |||
09067ebdc5 | |||
08697e71fa | |||
90d9a1df3f | |||
a96c149793 | |||
1037cef22e | |||
09948f4403 | |||
788461b7e2 | |||
4f56628566 | |||
bcbf1ccc68 | |||
ae30d7ba40 | |||
9adf41ca2d | |||
1d79d534d9 | |||
60e4197026 | |||
2fabca77b9 | |||
47542b0cb0 | |||
6c60c3e547 | |||
814d389b6e | |||
e81e5fb2b9 | |||
f68cdf3878 | |||
91e0e9e1dd | |||
59c1299168 | |||
27c6afbeb4 | |||
514ba54282 | |||
a11f683e7b | |||
b65b145122 | |||
982bb8b01d | |||
eb7b7581ca | |||
adab6c0728 | |||
609201e109 | |||
54a4e4a67c | |||
aca4604879 | |||
48811cd805 | |||
136f64f4ac | |||
123ee8e06f | |||
a55efbd8b8 | |||
7bf9525353 | |||
3915e1b242 | |||
ed5975d3e5 | |||
1a788e6b0d | |||
d822793229 | |||
b46d0bc48c | |||
65320126c2 | |||
c63b3164bd | |||
dbffa88dc2 | |||
8c5d9d372f | |||
50f8892c6b | |||
3bfbfa8ae0 | |||
8598c87ef4 | |||
33bfc4c24a | |||
3afb744e77 | |||
e92918bbfe | |||
723e8fde93 | |||
507f7ea70a | |||
6b985d56a5 | |||
c8385ad998 | |||
9d21a6f40d | |||
d304f41197 | |||
8d85b839b6 | |||
dd235f38a3 | |||
5306b6dd0c | |||
b09624024b | |||
edc3709451 | |||
e706f3477b | |||
6298cb3999 | |||
878fce6482 | |||
b02bd65871 | |||
ee36aaf163 | |||
ff84506bd5 | |||
0ae33b7e3c | |||
b1dc6239ef | |||
3ce0f1146f | |||
3ec837bfdb | |||
18ff2be9bb | |||
c0d296334c | |||
9a0a2e319c | |||
a0d86ac2bb | |||
99045b2f6a | |||
c34ca36778 | |||
58dd75a1c8 | |||
f995b07876 | |||
101a4aa3cf | |||
65d759316b | |||
19c1773133 | |||
9b3b3d325f | |||
43f4374944 | |||
81e6d13241 | |||
f8e7a37c0d | |||
c686e7ea30 | |||
7e89af8190 | |||
539e8e2cce | |||
aab084866c | |||
0e61a86763 | |||
1c9938ed98 | |||
47c1a0f381 | |||
514529b5d9 | |||
a12dc7d75a | |||
41b53e71e1 | |||
0fb9f3bd6c | |||
81f3f32217 | |||
b35f288794 | |||
4e82cc0861 | |||
c735644c57 | |||
5d479fa0ae | |||
8baedca972 | |||
02aa8e7945 | |||
ee523efcb4 | |||
eef5f7e06d | |||
83402930f2 | |||
bd48c927d0 | |||
b61b8d60b7 | |||
f1fca5abb6 | |||
045ce3c77a | |||
f822066e2a |
3
.clang-format
Normal file
3
.clang-format
Normal file
@ -0,0 +1,3 @@
|
||||
Language: JavaScript
|
||||
BasedOnStyle: Google
|
||||
ColumnLimit: 100
|
19
.gitignore
vendored
19
.gitignore
vendored
@ -1,11 +1,17 @@
|
||||
.DS_STORE
|
||||
|
||||
# Don’t commit the following directories created by pub.
|
||||
packages
|
||||
pubspec.lock
|
||||
.pub
|
||||
|
||||
/dist/
|
||||
packages/
|
||||
.buildlog
|
||||
node_modules
|
||||
bower_components
|
||||
.pub
|
||||
.DS_STORE
|
||||
|
||||
# Or broccoli working directory
|
||||
tmp
|
||||
|
||||
# Or the files created by dart2js.
|
||||
*.dart.js
|
||||
@ -14,6 +20,10 @@ bower_components
|
||||
*.js.deps
|
||||
*.js.map
|
||||
|
||||
# Or type definitions we mirror from github
|
||||
**/typings/**/*.d.ts
|
||||
**/typings/tsd.cached.json
|
||||
|
||||
# Include when developing application packages.
|
||||
pubspec.lock
|
||||
.c9
|
||||
@ -23,4 +33,7 @@ pubspec.lock
|
||||
# Don't check in secret files
|
||||
*secret.js
|
||||
|
||||
# Ignore npm debug log
|
||||
npm-debug.log
|
||||
|
||||
/docs/bower_components/
|
||||
|
12
.settings/settings.json
Normal file
12
.settings/settings.json
Normal file
@ -0,0 +1,12 @@
|
||||
// Place your settings in this file to overwrite default and user settings.
|
||||
{
|
||||
"search.excludeFolders": [
|
||||
".git",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"packages",
|
||||
"build",
|
||||
"dist",
|
||||
"tmp"
|
||||
]
|
||||
}
|
35
.travis.yml
35
.travis.yml
@ -1,32 +1,61 @@
|
||||
language: node_js
|
||||
sudo: false
|
||||
node_js:
|
||||
- '0.10'
|
||||
- '0.12'
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- node_modules
|
||||
- $HOME/.pub-cache
|
||||
|
||||
env:
|
||||
global:
|
||||
- KARMA_BROWSERS=DartiumWithWebPlatform
|
||||
- E2E_BROWSERS=Dartium
|
||||
- LOGS_DIR=/tmp/angular-build/logs
|
||||
- ARCH=linux-x64
|
||||
# Token for tsd to increase github rate limit
|
||||
# See https://github.com/DefinitelyTyped/tsd#tsdrc
|
||||
# This does not use http://docs.travis-ci.com/user/environment-variables/#Secure-Variables
|
||||
# because those are not visible for pull requests, and those should also be reliable.
|
||||
# This SSO token belongs to github account angular-github-ratelimit-token which has no access
|
||||
# (password is in Valentine)
|
||||
- TSDRC='{"token":"ef474500309daea53d5991b3079159a29520a40b"}'
|
||||
matrix:
|
||||
- MODE=js DART_CHANNEL=dev
|
||||
# Dissabled until Dart v1.9 hits stable
|
||||
# - MODE=dart DART_CHANNEL=stable
|
||||
- MODE=dart DART_CHANNEL=stable
|
||||
- MODE=dart DART_CHANNEL=dev
|
||||
|
||||
addons:
|
||||
firefox: "38.0"
|
||||
|
||||
before_install:
|
||||
- echo ${TSDRC} > .tsdrc
|
||||
- export DISPLAY=:99.0
|
||||
- export GIT_SHA=$(git rev-parse HEAD)
|
||||
- ./scripts/ci/init_android.sh
|
||||
- ./scripts/ci/install_dart.sh ${DART_CHANNEL} ${ARCH}
|
||||
- sh -e /etc/init.d/xvfb start
|
||||
- if [[ -e SKIP_TRAVIS_TESTS ]]; then { cat SKIP_TRAVIS_TESTS ; exit 0; } fi
|
||||
|
||||
install:
|
||||
# Update npm
|
||||
- npm install -g npm@2.9.1
|
||||
- npm --version
|
||||
# Check the size of caches
|
||||
- du -sh ./node_modules || true
|
||||
# Install npm dependecies and ensure that npm cache is not stale
|
||||
- tools/npm/install-dependencies.sh
|
||||
|
||||
before_script:
|
||||
- mkdir -p $LOGS_DIR
|
||||
|
||||
script:
|
||||
- ./scripts/ci/build_and_test.sh ${MODE}
|
||||
|
||||
after_script:
|
||||
- ./scripts/ci/print-logs.sh
|
||||
|
||||
notifications:
|
||||
webhooks:
|
||||
urls:
|
||||
|
403
CHANGELOG.md
Normal file
403
CHANGELOG.md
Normal file
@ -0,0 +1,403 @@
|
||||
<a name"2.0.0-alpha.26"></a>
|
||||
### 2.0.0-alpha.26 (2015-06-03)
|
||||
|
||||
|
||||
#### Bug Fixes
|
||||
|
||||
* format a file that slipped in. ([471a1b6d](https://github.com/angular/angular/commit/471a1b6d))
|
||||
* fix clang errors ([01fb8e66](https://github.com/angular/angular/commit/01fb8e66))
|
||||
* **ShadowCss:** keyframes tests failing in Safari ([4c8e11a5](https://github.com/angular/angular/commit/4c8e11a5), closes [#2283](https://github.com/angular/angular/issues/2283))
|
||||
* **Tools:** Moves files out of dart2js/**/web. ([40150379](https://github.com/angular/angular/commit/40150379))
|
||||
* **ast:** fix the size of a list in _evalListCache ([0387221d](https://github.com/angular/angular/commit/0387221d))
|
||||
* **benchpress:**
|
||||
* support nested intervals ([c280fe81](https://github.com/angular/angular/commit/c280fe81))
|
||||
* add index to root of module ([383f0a1f](https://github.com/angular/angular/commit/383f0a1f))
|
||||
* **binding:** unbalanced curly brackets in documentation ([a80921b4](https://github.com/angular/angular/commit/a80921b4))
|
||||
* **browser_adapter:**
|
||||
* HTMLStyleElement.innerText does not trigger creation of CSS rules (Firefox) ([b2a24e02](https://github.com/angular/angular/commit/b2a24e02))
|
||||
* event creation fails (IE11, Firefox) ([665ccafd](https://github.com/angular/angular/commit/665ccafd))
|
||||
* element.getBoundingClientRect fails when element not in DOM (IE11) ([f35dbb99](https://github.com/angular/angular/commit/f35dbb99))
|
||||
* element.matches only available with prefix (IE11) ([a393f84f](https://github.com/angular/angular/commit/a393f84f))
|
||||
* assigning null to document.title sets the title to "null" (IE11, Firefox) ([92c2c33a](https://github.com/angular/angular/commit/92c2c33a))
|
||||
* **build:**
|
||||
* remove nonexistant dart format task from gulpfile ([f74d7727](https://github.com/angular/angular/commit/f74d7727))
|
||||
* make dart formatter errors more readable ([31b66878](https://github.com/angular/angular/commit/31b66878))
|
||||
* also run ts tests in node. ([05774f6c](https://github.com/angular/angular/commit/05774f6c))
|
||||
* **collection:**
|
||||
* iterator on Map keys is not supported (Safari) ([4b98ed11](https://github.com/angular/angular/commit/4b98ed11), closes [#2096](https://github.com/angular/angular/issues/2096))
|
||||
* new Map(iterable) is not supported (Safari) ([d308e55e](https://github.com/angular/angular/commit/d308e55e))
|
||||
* new Set(iterable) is not supported (IE11, Safari) ([57b88ec2](https://github.com/angular/angular/commit/57b88ec2), closes [#2063](https://github.com/angular/angular/issues/2063))
|
||||
* **core:** resurrect OnChange interface ([d48fae35](https://github.com/angular/angular/commit/d48fae35))
|
||||
* **dartdocs:** Hide duplicate exports from guinness. ([17e1d7f1](https://github.com/angular/angular/commit/17e1d7f1))
|
||||
* **deps:** Update clang-format to 1.0.14. ([15f1eb28](https://github.com/angular/angular/commit/15f1eb28))
|
||||
* **di:** allow `@Inject(…)` to work in dart2js and dynamic reflection ([4a3fd5e8](https://github.com/angular/angular/commit/4a3fd5e8), closes [#2185](https://github.com/angular/angular/issues/2185))
|
||||
* **docs:** generate d.ts file only for angular2/angular2. ([0a0b84a0](https://github.com/angular/angular/commit/0a0b84a0))
|
||||
* **dom:**
|
||||
* allow to correctly clone document fragments ([2351896c](https://github.com/angular/angular/commit/2351896c))
|
||||
* `querySelectorAll` should only query child nodes ([307011a9](https://github.com/angular/angular/commit/307011a9))
|
||||
* **example:** unused event ([f83f1ee0](https://github.com/angular/angular/commit/f83f1ee0))
|
||||
* **examples:** update form example to use NgIf ([1ad65582](https://github.com/angular/angular/commit/1ad65582))
|
||||
* **facade:**
|
||||
* Make PromiseWrapper#all semantics equivalent ([22f59252](https://github.com/angular/angular/commit/22f59252))
|
||||
* Fix bug in TS indexOf ([cda35101](https://github.com/angular/angular/commit/cda35101))
|
||||
* **fake_async:** fixed fakeAsync to throw instead of crashing on cjs ([5c53cf64](https://github.com/angular/angular/commit/5c53cf64))
|
||||
* **forms:** disabled form tests on cjs until fakeAsync is fixed ([cd52d8a3](https://github.com/angular/angular/commit/cd52d8a3))
|
||||
* **gulp:** prevent duplicate error messages ([381d4cb3](https://github.com/angular/angular/commit/381d4cb3), closes [#2021](https://github.com/angular/angular/issues/2021))
|
||||
* **injectable:** add missing @Injectables annotations ([0c7f05f5](https://github.com/angular/angular/commit/0c7f05f5), closes [#2173](https://github.com/angular/angular/issues/2173))
|
||||
* **package.json:** add `reflect-metadata` to package.json ([60801777](https://github.com/angular/angular/commit/60801777), closes [#2170](https://github.com/angular/angular/issues/2170))
|
||||
* **render:**
|
||||
* only look for content tags in views that might have them. ([ba7956f5](https://github.com/angular/angular/commit/ba7956f5), closes [#2297](https://github.com/angular/angular/issues/2297))
|
||||
* don’t store a document fragment as bound element ([24bc4b66](https://github.com/angular/angular/commit/24bc4b66))
|
||||
* **router:** event.defaultPrevented is not reliable (IE11) ([2287938f](https://github.com/angular/angular/commit/2287938f))
|
||||
* **selector:** support multiple `:not` clauses ([62a95823](https://github.com/angular/angular/commit/62a95823), closes [#2243](https://github.com/angular/angular/issues/2243))
|
||||
* **test:**
|
||||
* clang formatting errors ([05d66bba](https://github.com/angular/angular/commit/05d66bba))
|
||||
* solve CSS discrepancies across browsers ([fb42d590](https://github.com/angular/angular/commit/fb42d590), closes [#2177](https://github.com/angular/angular/issues/2177))
|
||||
* use a not expandable CSS rule in ShadowCSS spec (Firefox) ([588fbfd8](https://github.com/angular/angular/commit/588fbfd8), closes [#2061](https://github.com/angular/angular/issues/2061))
|
||||
* adds longer timers for NgZone and PromisePipe tests (IE11) ([661a0479](https://github.com/angular/angular/commit/661a0479), closes [#2055](https://github.com/angular/angular/issues/2055))
|
||||
* native shadow DOM is required (IE11, Firefox) ([9802debf](https://github.com/angular/angular/commit/9802debf))
|
||||
* function.name is not available (IE11) ([5103f080](https://github.com/angular/angular/commit/5103f080))
|
||||
* **tests:** disable mobile emulation so benchmarks run on current chrome ([b071b66b](https://github.com/angular/angular/commit/b071b66b))
|
||||
* **types:** parametrize QueryList. ([552985e3](https://github.com/angular/angular/commit/552985e3))
|
||||
|
||||
|
||||
#### Features
|
||||
|
||||
* add support for the safe navigation (aka Elvis) operator ([a9be2ebf](https://github.com/angular/angular/commit/a9be2ebf), closes [#791](https://github.com/angular/angular/issues/791))
|
||||
* **Directive:** convert properties to an array ([d7df853b](https://github.com/angular/angular/commit/d7df853b), closes [#2013](https://github.com/angular/angular/issues/2013))
|
||||
* **ElementInjector:** support an arbitrary number of bindings ([b1c9bf14](https://github.com/angular/angular/commit/b1c9bf14), closes [#1853](https://github.com/angular/angular/issues/1853))
|
||||
* **OpaqueToken:** now a const constructor ([c571b269](https://github.com/angular/angular/commit/c571b269))
|
||||
* **RegExpWrapper:** implement a test method ([551586ce](https://github.com/angular/angular/commit/551586ce))
|
||||
* **benchpress:** Add extension for ff metrics reporting ([b390f441](https://github.com/angular/angular/commit/b390f441), closes [#1976](https://github.com/angular/angular/issues/1976))
|
||||
* **binding:** throw on binding to a blank alias ([ec2d8cc2](https://github.com/angular/angular/commit/ec2d8cc2), closes [#2068](https://github.com/angular/angular/issues/2068))
|
||||
* **broccoli:** add incremental dartfmt plugin ([e5d06e47](https://github.com/angular/angular/commit/e5d06e47), closes [#2211](https://github.com/angular/angular/issues/2211))
|
||||
* **change_detection:** added onInit and onCheck hooks ([c39c8ebc](https://github.com/angular/angular/commit/c39c8ebc))
|
||||
* **change_detection.ts:** export PipeFactory ([93f464a1](https://github.com/angular/angular/commit/93f464a1), closes [#2245](https://github.com/angular/angular/issues/2245))
|
||||
* **core:**
|
||||
* added support for detecting lifecycle events based on interfaces ([30b6542f](https://github.com/angular/angular/commit/30b6542f))
|
||||
* added missing interfaces for onDestroy and onAllChangesDone lifecycle events ([2b6a6530](https://github.com/angular/angular/commit/2b6a6530))
|
||||
* **di:** added optional self parameter to Parent, Ancestor, and Unbounded ([34cfc9f4](https://github.com/angular/angular/commit/34cfc9f4))
|
||||
* **dom:** add `setData()` method. ([6f3368ef](https://github.com/angular/angular/commit/6f3368ef))
|
||||
* **facade:** add read/write access to global variables ([cdf791f0](https://github.com/angular/angular/commit/cdf791f0))
|
||||
* **fakeAsync:** flush the microtasks before returning ([c7572ac1](https://github.com/angular/angular/commit/c7572ac1), closes [#2269](https://github.com/angular/angular/issues/2269))
|
||||
* **form:** implemented an imperative way of updating the view by updating the value of a co ([652ed0cf](https://github.com/angular/angular/commit/652ed0cf))
|
||||
* **forms:**
|
||||
* added support for status classes ([3baf815d](https://github.com/angular/angular/commit/3baf815d))
|
||||
* added touched and untouched to Control ([ec3a7828](https://github.com/angular/angular/commit/ec3a7828))
|
||||
* renamed control, control-group into ng-control and ng-control-group ([f543834b](https://github.com/angular/angular/commit/f543834b))
|
||||
* changed the selector of TemplatdrivenFormDirective to match <form> ([6bef1c41](https://github.com/angular/angular/commit/6bef1c41))
|
||||
* added ng-model ([559f54e9](https://github.com/angular/angular/commit/559f54e9))
|
||||
* implemented template-driven forms ([a9d6fd9a](https://github.com/angular/angular/commit/a9d6fd9a))
|
||||
* **key_event:** alias esc to escape ([10bc7e94](https://github.com/angular/angular/commit/10bc7e94), closes [#2010](https://github.com/angular/angular/issues/2010))
|
||||
* **reflector:** added a method to get type's interfaces ([34d75e89](https://github.com/angular/angular/commit/34d75e89))
|
||||
* **render:** re-export render and export `DirectiveResolver` ([662da0d7](https://github.com/angular/angular/commit/662da0d7), closes [#2026](https://github.com/angular/angular/issues/2026))
|
||||
* **router:** add the router bundle to the bundle task. ([05fa9bc9](https://github.com/angular/angular/commit/05fa9bc9))
|
||||
* **router.js:**
|
||||
* export router injectables ([28ee0612](https://github.com/angular/angular/commit/28ee0612))
|
||||
* export routerDirectives ([1f20ef97](https://github.com/angular/angular/commit/1f20ef97))
|
||||
* **test:**
|
||||
* added not.toBeNull ([74882c6c](https://github.com/angular/angular/commit/74882c6c))
|
||||
* add element probe ([f9908cd4](https://github.com/angular/angular/commit/f9908cd4), closes [#1992](https://github.com/angular/angular/issues/1992))
|
||||
* **test_lib:**
|
||||
* add method to compare stringified DOM element ([c6335c12](https://github.com/angular/angular/commit/c6335c12), closes [#2106](https://github.com/angular/angular/issues/2106))
|
||||
* add `containsRegex` ([23d59df8](https://github.com/angular/angular/commit/23d59df8))
|
||||
* **tests:** add TestComponentBuilder ([c32dbad7](https://github.com/angular/angular/commit/c32dbad7), closes [#1812](https://github.com/angular/angular/issues/1812))
|
||||
* **transformers:** added support for lifecycle events ([f19970a4](https://github.com/angular/angular/commit/f19970a4))
|
||||
* **view:**
|
||||
* introduce free embedded views ([5030ffb0](https://github.com/angular/angular/commit/5030ffb0))
|
||||
* add `AppViewListener` interface ([75578f41](https://github.com/angular/angular/commit/75578f41))
|
||||
|
||||
|
||||
#### Breaking Changes
|
||||
|
||||
*
|
||||
- `Renderer.detachFreeHostView` was renamed to
|
||||
`Renderer.detachFreeView`
|
||||
- `DomRenderer.getHostElement()` was generalized into
|
||||
`DomRenderer.getRootNodes()`
|
||||
|
||||
([5030ffb0](https://github.com/angular/angular/commit/5030ffb0))
|
||||
*
|
||||
now a `const` constructor
|
||||
|
||||
([c571b269](https://github.com/angular/angular/commit/c571b269))
|
||||
*
|
||||
Before
|
||||
|
||||
@Directive(properties: {
|
||||
'sameName': 'sameName',
|
||||
'directiveProp': 'elProp | pipe'
|
||||
})
|
||||
|
||||
After
|
||||
|
||||
@Directive(properties: [
|
||||
'sameName',
|
||||
'directiveProp: elProp | pipe'
|
||||
])
|
||||
|
||||
([d7df853b](https://github.com/angular/angular/commit/d7df853b))
|
||||
|
||||
|
||||
<a name"2.0.0-alpha.25"></a>
|
||||
### 2.0.0-alpha.25 (2015-05-21)
|
||||
|
||||
|
||||
#### Bug Fixes
|
||||
|
||||
* don't call onAllChangesDone on checkNoChanges ([a664f5a6](https://github.com/angular/angular/commit/a664f5a6))
|
||||
* **XHRImpl:** fix errors, add a spec ([91ccc9af](https://github.com/angular/angular/commit/91ccc9af), closes [#1715](https://github.com/angular/angular/issues/1715))
|
||||
* **browser:** template elements should have content imported instead of the element itself. ([c9ab8e4b](https://github.com/angular/angular/commit/c9ab8e4b))
|
||||
* **di:** changed host and view injector to respect visibility ([705ee46f](https://github.com/angular/angular/commit/705ee46f))
|
||||
* **element_injector:**
|
||||
* fixed element injector to inject view dependencies into its components ([b6b52e62](https://github.com/angular/angular/commit/b6b52e62))
|
||||
* fixed element injector to resolve dependencies of regular services ([28c2b8f4](https://github.com/angular/angular/commit/28c2b8f4))
|
||||
* **forms:** changed forms to create only one value accessor instead of always creating Defau ([30c3e5a8](https://github.com/angular/angular/commit/30c3e5a8))
|
||||
* **gulp:** continue watching when tasks throw ([ac28ac32](https://github.com/angular/angular/commit/ac28ac32), closes [#1915](https://github.com/angular/angular/issues/1915))
|
||||
* **router:** router link should navigate to non-base Url. ([c4528321](https://github.com/angular/angular/commit/c4528321))
|
||||
* **test_lib:** fixes nested beforeEach. ([826af401](https://github.com/angular/angular/commit/826af401))
|
||||
|
||||
|
||||
#### Features
|
||||
|
||||
* **CD:** add support for === and !== ([0ae89ac0](https://github.com/angular/angular/commit/0ae89ac0))
|
||||
* **PromisePipe:** remove ref onDestroy ([4afd2b41](https://github.com/angular/angular/commit/4afd2b41))
|
||||
* **di:** changed toFactory to support dependency annotations ([f210c41c](https://github.com/angular/angular/commit/f210c41c))
|
||||
* **forms:** migrated forms to typescript ([00c3693d](https://github.com/angular/angular/commit/00c3693d))
|
||||
* **injector:** support forwardRef in toAlias ([fed86fc8](https://github.com/angular/angular/commit/fed86fc8))
|
||||
|
||||
|
||||
<a name"2.0.0-alpha.24"></a>
|
||||
### 2.0.0-alpha.24 (2015-05-19)
|
||||
|
||||
|
||||
#### Bug Fixes
|
||||
|
||||
* **Compiler:** add an error when a directive is null or undefined ([25cd6e43](https://github.com/angular/angular/commit/25cd6e43), closes [#1908](https://github.com/angular/angular/issues/1908))
|
||||
* **benchmark:**
|
||||
* change If for NgIf ([cdbb2473](https://github.com/angular/angular/commit/cdbb2473))
|
||||
* fixes ng-if ng-for renaming for templates. ([38926f71](https://github.com/angular/angular/commit/38926f71))
|
||||
* **build:** npm shrinkwrap to pick up changed SHA1. ([04a9eb88](https://github.com/angular/angular/commit/04a9eb88))
|
||||
* **directives:** fix import path ([c20060d2](https://github.com/angular/angular/commit/c20060d2))
|
||||
* **errors:** require passing stack traces explicitly in ng2 own code ([8ab77353](https://github.com/angular/angular/commit/8ab77353))
|
||||
* **examples:** prefix directives with Ng ([0e82970a](https://github.com/angular/angular/commit/0e82970a))
|
||||
* **facade:** MapWrapper.createFromPairs ([af9dcad8](https://github.com/angular/angular/commit/af9dcad8), closes [#1640](https://github.com/angular/angular/issues/1640))
|
||||
* **ng1 benchmarks:** revert *ng-if to ng-if ([909233f7](https://github.com/angular/angular/commit/909233f7))
|
||||
* **router:**
|
||||
* use appRootComponentToken to get root route configs ([791caf00](https://github.com/angular/angular/commit/791caf00), closes [#1947](https://github.com/angular/angular/issues/1947))
|
||||
* improve route matching priorities ([5db89071](https://github.com/angular/angular/commit/5db89071))
|
||||
* generate links for router-link with baseHref ([390cfb79](https://github.com/angular/angular/commit/390cfb79))
|
||||
* sort possible routes by cost ([17392f66](https://github.com/angular/angular/commit/17392f66))
|
||||
* **tree-differ:** treat symlinks to deleted paths as removals ([aad57954](https://github.com/angular/angular/commit/aad57954), closes [#1961](https://github.com/angular/angular/issues/1961))
|
||||
|
||||
|
||||
#### Features
|
||||
|
||||
* allow for forward references in injection ([1eea2b25](https://github.com/angular/angular/commit/1eea2b25), closes [#1891](https://github.com/angular/angular/issues/1891))
|
||||
* **change_detection:**
|
||||
* json pipe ([98603824](https://github.com/angular/angular/commit/98603824), closes [#1957](https://github.com/angular/angular/issues/1957))
|
||||
* uppercase and lowercase pipes ([7a4a6353](https://github.com/angular/angular/commit/7a4a6353))
|
||||
* implemented change detection that can be configured with pregenerated change det ([08f21dbf](https://github.com/angular/angular/commit/08f21dbf))
|
||||
* **compiler:**
|
||||
* special-case class attribute in hostAttributes ([3011cd86](https://github.com/angular/angular/commit/3011cd86), closes [#1774](https://github.com/angular/angular/issues/1774), [#1841](https://github.com/angular/angular/issues/1841))
|
||||
* added support for [()] syntax ([685a6507](https://github.com/angular/angular/commit/685a6507))
|
||||
* **di:**
|
||||
* added hostInjector and viewInjector to the Directive annotation ([b066b8d1](https://github.com/angular/angular/commit/b066b8d1))
|
||||
* removed publishAs ([3a53f679](https://github.com/angular/angular/commit/3a53f679))
|
||||
* **element_injector:** allow @Optional for ProtoViewRef ([bb2eda2d](https://github.com/angular/angular/commit/bb2eda2d))
|
||||
* **errors:** preserve stack traces of user exceptions in Dart ([b6f29b44](https://github.com/angular/angular/commit/b6f29b44))
|
||||
* **facade:** toUpperCase and toLowerCase ([557d54b3](https://github.com/angular/angular/commit/557d54b3))
|
||||
* **fakeAsync:** allow simulating the passage of time ([0f002a5b](https://github.com/angular/angular/commit/0f002a5b))
|
||||
* **forms:** improved error messages ([11e43851](https://github.com/angular/angular/commit/11e43851), closes [#1839](https://github.com/angular/angular/issues/1839))
|
||||
* **pipe:** reexported pipes to genereate docs ([155b1e2b](https://github.com/angular/angular/commit/155b1e2b))
|
||||
|
||||
|
||||
#### Breaking Changes
|
||||
|
||||
* `AppViewManager.createInPlaceHostView` is replaced by
|
||||
`AppViewManager.createRootHostView` (for bootstrap) and
|
||||
`AppViewManager.createFreeHostView` (for imperative components).
|
||||
|
||||
The later creates new host elements that are not attached anywhere.
|
||||
To attach them, use `DomRenderer.getHostElement(hostviewRef)`
|
||||
to get the host element.
|
||||
|
||||
Closes #1920
|
||||
|
||||
([421d8916](https://github.com/angular/angular/commit/421d8916))
|
||||
* - renames `DirectiveMetadataReader` into `DirectiveResolver`
|
||||
and removes `src/core/compiler/directive_metadata`.
|
||||
|
||||
Fixes #1712
|
||||
Fixes #1713
|
||||
([ecb06801](https://github.com/angular/angular/commit/ecb06801))
|
||||
|
||||
|
||||
<a name"2.0.0-alpha.23"></a>
|
||||
### 2.0.0-alpha.23 (2015-05-12)
|
||||
|
||||
|
||||
#### Bug Fixes
|
||||
|
||||
* **change_detection:** updated dynamic change detector not to mutate when throwing ([d717529e](https://github.com/angular/angular/commit/d717529e), closes [#1762](https://github.com/angular/angular/issues/1762))
|
||||
* **dart:** Remove unused imports. ([4ce0d5e0](https://github.com/angular/angular/commit/4ce0d5e0))
|
||||
* **forms:** export directives as const in Dart ([5036086f](https://github.com/angular/angular/commit/5036086f), closes [#1283](https://github.com/angular/angular/issues/1283))
|
||||
* **gulpfile:** fixed test.unit.dart to format dart code before running test ([92d6aa1f](https://github.com/angular/angular/commit/92d6aa1f))
|
||||
* **location:** dartium does not like pushState with null. ([c2a42d5d](https://github.com/angular/angular/commit/c2a42d5d))
|
||||
* **router:**
|
||||
* add baseUrl to relative paths, but not absolute. ([a5741541](https://github.com/angular/angular/commit/a5741541), closes [#1783](https://github.com/angular/angular/issues/1783))
|
||||
* reuse common parent components ([ac80df09](https://github.com/angular/angular/commit/ac80df09))
|
||||
* router-link works without params ([77d1fc14](https://github.com/angular/angular/commit/77d1fc14))
|
||||
* strip base href from URLs when navigating ([853d1de6](https://github.com/angular/angular/commit/853d1de6))
|
||||
* **test_lib:** spy funcs should match null arguments ([84dc6ae7](https://github.com/angular/angular/commit/84dc6ae7))
|
||||
* **transformer:** remove classDefParser in favor of hardcoded strings to speed up build ([01d5c295](https://github.com/angular/angular/commit/01d5c295))
|
||||
* **view:** fixed ProtoViewFactory to get all property bindings ([7f976381](https://github.com/angular/angular/commit/7f976381))
|
||||
|
||||
|
||||
#### Features
|
||||
|
||||
* **PromisePipe:** add pipe for promises ([74987585](https://github.com/angular/angular/commit/74987585))
|
||||
* **VmTurnZone:** Rework the implementation to minimize change detection runs ([e8a6c95e](https://github.com/angular/angular/commit/e8a6c95e))
|
||||
* **change_detection.js:** export null pipes ([4b62a722](https://github.com/angular/angular/commit/4b62a722), closes [#1624](https://github.com/angular/angular/issues/1624))
|
||||
* **compiler:**
|
||||
* added support for host actions ([f9c1de46](https://github.com/angular/angular/commit/f9c1de46))
|
||||
* allow setting attributes on a host element ([51839ca6](https://github.com/angular/angular/commit/51839ca6), closes [#1402](https://github.com/angular/angular/issues/1402))
|
||||
* **di:**
|
||||
* support type literals in DI ([358a6750](https://github.com/angular/angular/commit/358a6750))
|
||||
* expose parent injector ([2185e7ce](https://github.com/angular/angular/commit/2185e7ce))
|
||||
* components can self-publish via publishAs ([1a0da11e](https://github.com/angular/angular/commit/1a0da11e))
|
||||
* **directives:** export collection of core directives ([a5638a94](https://github.com/angular/angular/commit/a5638a94), closes [#1524](https://github.com/angular/angular/issues/1524))
|
||||
* **dom:** add getBaseHref method ([05219a54](https://github.com/angular/angular/commit/05219a54))
|
||||
* **facade:** add equals method to StringMapWrapper ([aff85b50](https://github.com/angular/angular/commit/aff85b50))
|
||||
* **gulpfuile:** added watch.js.dev ([3256ff1c](https://github.com/angular/angular/commit/3256ff1c))
|
||||
* **lang:** support const expressions in TS/JS and Dart ([4665726f](https://github.com/angular/angular/commit/4665726f), closes [#1796](https://github.com/angular/angular/issues/1796))
|
||||
* **material:**
|
||||
* add early version of md-grid-list. ([8ef183b5](https://github.com/angular/angular/commit/8ef183b5), closes [#1683](https://github.com/angular/angular/issues/1683))
|
||||
* early version of md-input ([ad239218](https://github.com/angular/angular/commit/ad239218), closes [#1753](https://github.com/angular/angular/issues/1753))
|
||||
* **view:** allow to transplant a view into a ViewContainer at another place. ([4f3433b5](https://github.com/angular/angular/commit/4f3433b5), closes [#1492](https://github.com/angular/angular/issues/1492))
|
||||
|
||||
|
||||
#### Breaking Changes
|
||||
|
||||
*
|
||||
VmTurnZone has been renamed to NgZone.
|
||||
|
||||
- The public API has not chnanged,
|
||||
- The "outer" zone is now named "mount" zone (private to NgZone).
|
||||
|
||||
([e11c2054](https://github.com/angular/angular/commit/e11c2054))
|
||||
*
|
||||
A collection of all the form directives is exported
|
||||
under `formDirectives`
|
||||
while those were previously available
|
||||
under `FormDirectives`.
|
||||
|
||||
Closes #1804
|
||||
|
||||
([229e770a](https://github.com/angular/angular/commit/229e770a))
|
||||
|
||||
|
||||
<a name"2.0.0-alpha.22"></a>
|
||||
### 2.0.0-alpha.22 (2015-05-07)
|
||||
|
||||
|
||||
#### Bug Fixes
|
||||
|
||||
* **brocolli:** escape special regexp characters when building regexps ([a58c9f83](https://github.com/angular/angular/commit/a58c9f83), closes [#1721](https://github.com/angular/angular/issues/1721), [#1752](https://github.com/angular/angular/issues/1752))
|
||||
* **build:**
|
||||
* build the broccoli tools with correct typescript version. ([6bba289a](https://github.com/angular/angular/commit/6bba289a))
|
||||
* use correct tsd command to get typings at requested versions ([1205f54d](https://github.com/angular/angular/commit/1205f54d))
|
||||
* revert typescript upgrade which broke the build. ([b5032fd3](https://github.com/angular/angular/commit/b5032fd3))
|
||||
* refer to newest version of hammerjs typings ([a7a94636](https://github.com/angular/angular/commit/a7a94636))
|
||||
* **bundle:** update the bundle config to point to rx.js ([cf322130](https://github.com/angular/angular/commit/cf322130))
|
||||
* **change_detector:** ensure that locals are only used when implicit receiver ([d4925b61](https://github.com/angular/angular/commit/d4925b61), closes [#1542](https://github.com/angular/angular/issues/1542))
|
||||
* **compiler:**
|
||||
* clone templates before compiling them ([9e8d31d5](https://github.com/angular/angular/commit/9e8d31d5), closes [#1058](https://github.com/angular/angular/issues/1058))
|
||||
* changed the compiler to set up event listeners and host properties on host view ([e3c11045](https://github.com/angular/angular/commit/e3c11045), closes [#1584](https://github.com/angular/angular/issues/1584))
|
||||
* only sets viewDefinition absUrl if the view has either a template or templateUrl ([3d625463](https://github.com/angular/angular/commit/3d625463), closes [#1326](https://github.com/angular/angular/issues/1326), [#1327](https://github.com/angular/angular/issues/1327))
|
||||
* **decorators:**
|
||||
* incorrect annotation to decorator adapter ([b0c735f7](https://github.com/angular/angular/commit/b0c735f7))
|
||||
* fixed decorators ([49777648](https://github.com/angular/angular/commit/49777648))
|
||||
* fixes decorator reflection. ([be7504d4](https://github.com/angular/angular/commit/be7504d4))
|
||||
* updates missing benchmark and fixes typo. ([87dcd5eb](https://github.com/angular/angular/commit/87dcd5eb))
|
||||
* **decorators.es6:** export Directive decorator ([93c331d1](https://github.com/angular/angular/commit/93c331d1), closes [#1688](https://github.com/angular/angular/issues/1688))
|
||||
* **di:** improve error messages for invalid bindings ([ee1b574b](https://github.com/angular/angular/commit/ee1b574b), closes [#1515](https://github.com/angular/angular/issues/1515), [#1573](https://github.com/angular/angular/issues/1573))
|
||||
* **docs:** fix broken docs test after addition of .ts extension to dgeni regex. ([62bf777e](https://github.com/angular/angular/commit/62bf777e))
|
||||
* **exception_handler:** log errors via `console.error` ([ead21c91](https://github.com/angular/angular/commit/ead21c91))
|
||||
* **formatter:** point to the newest clang-format ([51c47792](https://github.com/angular/angular/commit/51c47792))
|
||||
* **router:**
|
||||
* fix for leading slash in dart ([c9cec600](https://github.com/angular/angular/commit/c9cec600))
|
||||
* navigate on popstate event ([2713b787](https://github.com/angular/angular/commit/2713b787))
|
||||
* throw if config does not contain required fields ([259f872c](https://github.com/angular/angular/commit/259f872c))
|
||||
* infer top-level routing from app component ([46ad3552](https://github.com/angular/angular/commit/46ad3552), closes [#1600](https://github.com/angular/angular/issues/1600))
|
||||
* use lists for RouteConfig annotations ([4965226f](https://github.com/angular/angular/commit/4965226f))
|
||||
* **view:** changed view manager to hydrate change detector after creating directives ([c1579222](https://github.com/angular/angular/commit/c1579222))
|
||||
|
||||
|
||||
#### Features
|
||||
|
||||
* **benchmark:** added an implementation of the tree benchmark in React ([e4342743](https://github.com/angular/angular/commit/e4342743))
|
||||
* **benchmarks:** Add basic dart transformer benchmarks. ([1864f60a](https://github.com/angular/angular/commit/1864f60a))
|
||||
* **decorators:**
|
||||
* adds decorator versions of DI annotations. ([457c15cd](https://github.com/angular/angular/commit/457c15cd))
|
||||
* adds support for parameter decorators. ([f863ea0d](https://github.com/angular/angular/commit/f863ea0d))
|
||||
* adds decorators to be used by TS and Babel transpiled apps. ([fb67e373](https://github.com/angular/angular/commit/fb67e373))
|
||||
* **dom:** add location and history as DOM-like APIs. ([f356d033](https://github.com/angular/angular/commit/f356d033))
|
||||
* **material:** add prototype dialog component w/ demo. ([f88c4b77](https://github.com/angular/angular/commit/f88c4b77))
|
||||
* **router:**
|
||||
* adds the router to the self-executing bundle. ([8e1d53b5](https://github.com/angular/angular/commit/8e1d53b5))
|
||||
* export decorator version of RouteConfig ([75da6e4c](https://github.com/angular/angular/commit/75da6e4c))
|
||||
* route redirects ([91533313](https://github.com/angular/angular/commit/91533313))
|
||||
* sibling outlets ([9d5c33f9](https://github.com/angular/angular/commit/9d5c33f9))
|
||||
* export routerInjectables ([ef7014fe](https://github.com/angular/angular/commit/ef7014fe))
|
||||
* add location service ([ea546f50](https://github.com/angular/angular/commit/ea546f50))
|
||||
|
||||
|
||||
#### Breaking Changes
|
||||
|
||||
* Previously, `Directive` was the abstract base class of several directives.
|
||||
Now, `Directive` is the former `Decorator`, and `Component` inherits from it.
|
||||
|
||||
([f75a50c1](https://github.com/angular/angular/commit/f75a50c1))
|
||||
* A dynamic component is just a component that has no @View annotation…
|
||||
([8faf6364](https://github.com/angular/angular/commit/8faf6364))
|
||||
|
||||
|
||||
<a name="2.0.0-alpha.21"></a>
|
||||
# 2.0.0-alpha.21 (2015-04-27)
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- **dart/transform:** Dedup getters, setters, & methods
|
||||
([15376a6d](https://github.com/angular/angular/commit/15376a6d243740c73cf90f55525d1710cdd156f5))
|
||||
- **facade:** add isType method
|
||||
([e617ca63](https://github.com/angular/angular/commit/e617ca6323902bd98c0f1eb990b82f6b8d3c98e3))
|
||||
- **parser:** support === and !== operators
|
||||
([afe0e454](https://github.com/angular/angular/commit/afe0e454537f9252f9cf313647e649cfa464f96f),
|
||||
[#1496](https://github.com/angular/angular/issues/1496), [#1500](https://github.com/angular/angular/issues/1500))
|
||||
- **router:** add initial implementation
|
||||
([1b2754da](https://github.com/angular/angular/commit/1b2754dacdd15e8fea429d56cdacb28eae76d2b1))
|
||||
- **view:** reimplemented property setters using change detection
|
||||
([8ccafb05](https://github.com/angular/angular/commit/8ccafb0524e3ac4c51af34ef88e0fe27482336a6))
|
||||
|
||||
|
||||
## Performance Improvements
|
||||
|
||||
- **benchmarks:**
|
||||
- benchmark that measure cost of dynamic components
|
||||
([427f0d02](https://github.com/angular/angular/commit/427f0d021c51ea6923edd07574a4cc74a1ef84e6))
|
||||
- benchmark measuring cost of decorators (fixes #1479)
|
||||
([9fc9d535](https://github.com/angular/angular/commit/9fc9d535667c620017367877dbc2a3bc56d358b7))
|
||||
|
||||
|
||||
## Other (malformed commit messages)
|
||||
|
||||
- **other:**
|
||||
- feat: alllow specifying directives as bindings
|
||||
([4bab25b3](https://github.com/angular/angular/commit/4bab25b3666f4247434ad5cb871906fb063fef51),
|
||||
[#1498](https://github.com/angular/angular/issues/1498))
|
||||
- fix: export ShadowDom strategies
|
||||
([6896305e](https://github.com/angular/angular/commit/6896305e34082c246769829e4258631c1d2363d1),
|
||||
[#1510](https://github.com/angular/angular/issues/1510), [#1511](https://github.com/angular/angular/issues/1511))
|
||||
|
@ -18,7 +18,7 @@ Help us keep Angular open and inclusive. Please read and follow our [Code of Con
|
||||
## <a name="question"></a> Got a Question or Problem?
|
||||
|
||||
If you have questions about how to *use* Angular, please direct them to the [Google Group][angular-group]
|
||||
discussion list or [StackOverflow][stackoverflow]. We are also available on [Gitter][gitter].
|
||||
discussion list or [StackOverflow][stackoverflow]. Please note that Angular 2 is still in early developer preview, and the core team's capacity to answer usage questions is limited. We are also available on [Gitter][gitter].
|
||||
|
||||
## <a name="issue"></a> Found an Issue?
|
||||
If you find a bug in the source code or a mistake in the documentation, you can help us by
|
||||
@ -27,27 +27,16 @@ If you find a bug in the source code or a mistake in the documentation, you can
|
||||
|
||||
## <a name="feature"></a> Want a Feature?
|
||||
You can *request* a new feature by [submitting an issue](#submit-issue) to our [GitHub
|
||||
Repository][github]. If you would like to *implement* a new feature then consider what kind of
|
||||
change it is:
|
||||
Repository][github]. If you would like to *implement* a new feature, please submit an issue with
|
||||
a proposal for your work first, to be sure that we can use it. Angular 2 is in developer preview
|
||||
and we are not ready to accept major contributions ahead of the full release.
|
||||
Please consider what kind of change it is:
|
||||
|
||||
* For a **Major Feature**, first open an issue and outline your proposal so that it can be
|
||||
discussed. This will also allow us to better coordinate our efforts, prevent duplication of work,
|
||||
and help you to craft the change so that it is successfully accepted into the project.
|
||||
* **Small Features** can be crafted and directly [submitted as a Pull Request](#submit-pr).
|
||||
|
||||
## <a name="docs"></a> Want a Doc Fix?
|
||||
If you want to help improve the docs, then consider what kind of improvement it is:
|
||||
|
||||
* For **Major Changes**, it's a good idea to let others know what you're working on to
|
||||
minimize duplication of effort. Before starting, check out the issue queue for
|
||||
issues labeled [#docs](https://github.com/angular/angular/labels/%23docs).
|
||||
Comment on an issue to let others know what you're working on, or [create a new issue](#submit-issue)
|
||||
if your work doesn't fit within the scope of any of the existing doc issues.
|
||||
Please build and test the documentation before [submitting the Pull Request](#submit-pr), to be sure
|
||||
you haven't accidentally introduced any layout or formatting issues. Also ensure that your commit
|
||||
message is labeled "docs" and follows the [Commit Message Guidelines](#commit) given below.
|
||||
* For **Small Changes**, there is no need to file an issue first. Simply [submit a Pull Request](#submit-pr).
|
||||
|
||||
## <a name="submit"></a> Submission Guidelines
|
||||
|
||||
### <a name="submit-issue"></a> Submitting an Issue
|
||||
@ -60,7 +49,6 @@ chances of your issue being dealt with quickly:
|
||||
|
||||
* **Overview of the Issue** - if an error is being thrown a non-minified stack trace helps
|
||||
* **Motivation for or Use Case** - explain why this is a bug for you
|
||||
* **Angular Version(s)** - is it a regression?
|
||||
* **Browsers and Operating System** - is this a problem with all browsers?
|
||||
* **Reproduce the Error** - provide a live example (using [Plunker][plunker],
|
||||
[JSFiddle][jsfiddle] or [Runnable][runnable]) or a unambiguous set of steps.
|
||||
@ -71,7 +59,7 @@ chances of your issue being dealt with quickly:
|
||||
### <a name="submit-pr"></a> Submitting a Pull Request (PR)
|
||||
Before you submit your Pull Request (PR) consider the following guidelines:
|
||||
|
||||
* Search [GitHub](https://github.com/angular/angular.dart/pulls) for an open or closed PR
|
||||
* Search [GitHub](https://github.com/angular/angular/pulls) for an open or closed PR
|
||||
that relates to your submission. You don't want to duplicate effort.
|
||||
* Please sign our [Contributor License Agreement (CLA)](#cla) before sending PRs.
|
||||
We cannot accept code without this.
|
||||
@ -180,7 +168,7 @@ Must be one of the following:
|
||||
* **docs**: Documentation only changes
|
||||
* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing
|
||||
semi-colons, etc)
|
||||
* **refactor**: A code change that neither fixes a bug or adds a feature
|
||||
* **refactor**: A code change that neither fixes a bug nor adds a feature
|
||||
* **perf**: A code change that improves performance
|
||||
* **test**: Adding missing tests
|
||||
* **chore**: Changes to the build process or auxiliary tools and libraries such as documentation
|
||||
|
195
DEVELOPER.md
195
DEVELOPER.md
@ -3,56 +3,60 @@
|
||||
This document describes how to set up your development environment to build and test Angular, both
|
||||
JS and Dart versions. It also explains the basic mechanics of using `git`, `node`, and `npm`.
|
||||
|
||||
See the [contributing guidelines](https://github.com/angular/angular/blob/master/CONTRIBUTING.md)
|
||||
for how to contribute your own code to
|
||||
* [Prerequisite Software](#prerequisite-software)
|
||||
* [Getting the Sources](#getting-the-sources)
|
||||
* [Environment Variable Setup](#environment-variable-setup)
|
||||
* [Installing NPM Modules and Dart Packages](#installing-npm-modules-and-dart-packages)
|
||||
* [Running Tests Locally](#running-tests-locally)
|
||||
* [Formatting](#formatting)
|
||||
* [Project Information](#project-information)
|
||||
* [CI using Travis](#ci-using-travis)
|
||||
* [Transforming Dart code](#transforming-dart-code)
|
||||
* [Debugging](#debugging)
|
||||
|
||||
1. [Prerequisite Software](#prerequisite-software)
|
||||
2. [Getting the Sources](#getting-the-sources)
|
||||
3. [Environment Variable Setup](#environment-variable-setup)
|
||||
4. [Installing NPM Modules and Dart Packages](#installing-npm-modules-and-dart-packages)
|
||||
5. [Running Tests Locally](#running-tests-locally)
|
||||
6. [Project Information](#project-information)
|
||||
7. [CI using Travis](#ci-using-travis)
|
||||
8. [Debugging](#debugging)
|
||||
See the [contribution guidelines](https://github.com/angular/angular/blob/master/CONTRIBUTING.md)
|
||||
if you'd like to contribute to Angular.
|
||||
|
||||
## Prerequisite Software
|
||||
|
||||
Before you can build and test Angular, you must install and configure the
|
||||
following products on your development machine:
|
||||
|
||||
* [Dart](https://www.dartlang.org) (version `>=1.9.0-dev.8.0`), specifically the Dart-SDK and
|
||||
* [Dart](https://www.dartlang.org) (version ` >=1.10.0-dev.1.10 <2.0.0`), specifically the Dart-SDK and
|
||||
Dartium (a version of [Chromium](http://www.chromium.org) with native support for Dart through
|
||||
the Dart VM). One of the **simplest** ways to get both is to install the **Dart Editor bundle**,
|
||||
which includes the editor, SDK and Dartium. See the [Dart tools](https://www.dartlang.org/tools)
|
||||
download [page for instructions](https://www.dartlang.org/tools/download.html); note that you can
|
||||
download [page for instructions](https://www.dartlang.org/tools/download.html). You can also
|
||||
download both **stable** and **dev** channel versions from the [download
|
||||
archive](https://www.dartlang.org/tools/download-archive).
|
||||
|
||||
* [Git](http://git-scm.com) and/or the **Github app** (for [Mac](http://mac.github.com) or
|
||||
[Windows](http://windows.github.com)): the [Github Guide to Installing
|
||||
* [Git](http://git-scm.com) and/or the **GitHub app** (for [Mac](http://mac.github.com) or
|
||||
[Windows](http://windows.github.com)); [GitHub's Guide to Installing
|
||||
Git](https://help.github.com/articles/set-up-git) is a good source of information.
|
||||
|
||||
* [Node.js](http://nodejs.org) which is used to run a development web server, run tests, and
|
||||
generate distributable files. We also use Node's Package Manager (`npm`). Depending on your
|
||||
system, you can install Node either from source or as a pre-packaged bundle.
|
||||
* [Node.js](http://nodejs.org), which is used to run a development web server, run tests, and
|
||||
generate distributable files. We also use Node's Package Manager, `npm`, which comes with Node.
|
||||
Depending on your system, you can install Node either from source or as a pre-packaged bundle.
|
||||
|
||||
* [Chrome Canary](https://www.google.com/chrome/browser/canary.html), a version of Chrome with
|
||||
bleeding edge functionality, built especially for developers (and early adopters).
|
||||
|
||||
* [Bower](http://bower.io/).
|
||||
|
||||
|
||||
## Getting the Sources
|
||||
|
||||
Forking and cloning the Angular repository:
|
||||
Fork and clone the Angular repository:
|
||||
|
||||
1. Login to your Github account or create one by following the instructions given
|
||||
1. Login to your GitHub account or create one by following the instructions given
|
||||
[here](https://github.com/signup/free).
|
||||
2. [Fork](http://help.github.com/forking) the [main Angular
|
||||
repository](https://github.com/angular/angular).
|
||||
3. Clone your fork of the Angular repository and define an `upstream` remote pointing back to
|
||||
the Angular repository that you forked in the first place:
|
||||
the Angular repository that you forked in the first place.
|
||||
|
||||
```shell
|
||||
# Clone your Github repository:
|
||||
# Clone your GitHub repository:
|
||||
git clone git@github.com:<github username>/angular.git
|
||||
|
||||
# Go to the Angular directory:
|
||||
@ -90,32 +94,31 @@ PATH+=":$DART_SDK/bin"
|
||||
|
||||
## Installing NPM Modules and Dart Packages
|
||||
|
||||
Next, install the modules and packages needed to build Angular and run tests:
|
||||
Next, install the JavaScript modules and Dart packages needed to build and test Angular:
|
||||
|
||||
```shell
|
||||
# Install Angular project dependencies (package.json)
|
||||
npm install
|
||||
|
||||
# Ensure protractor has the latest webdriver
|
||||
$(npm bin)/webdriver-manager update
|
||||
|
||||
# Install Dart packages
|
||||
pub get
|
||||
```
|
||||
|
||||
**Optional**: In this document, we make use of project local `npm` package scripts and binaries
|
||||
(stored under `./node_modules/.bin`) by prefixing these command invocations with `$(npm bin)`; in
|
||||
particular `gulp` and `protractor` commands. If you prefer, you can drop this path prefix by
|
||||
globally installing these two packages as follows:
|
||||
particular `gulp` and `protractor` commands. If you prefer, you can drop this path prefix by either:
|
||||
|
||||
*Option 1*: globally installing these two packages as follows:
|
||||
|
||||
* `npm install -g gulp` (you might need to prefix this command with `sudo`)
|
||||
* `npm install -g protractor` (you might need to prefix this command with `sudo`)
|
||||
|
||||
Since global installs can become stale, we avoid their use in these instructions.
|
||||
Since global installs can become stale, and required versions can vary by project, we avoid their
|
||||
use in these instructions.
|
||||
|
||||
*Option 2*: defining a bash alias like `alias nbin='PATH=$(npm bin):$PATH'` as detailed in this
|
||||
[Stackoverflow answer](http://stackoverflow.com/questions/9679932/how-to-use-package-installed-locally-in-node-modules/15157360#15157360) and used like this: e.g., `nbin gulp build`.
|
||||
|
||||
## Build commands
|
||||
|
||||
To build Angular and prepare tests run
|
||||
To build Angular and prepare tests, run:
|
||||
|
||||
```shell
|
||||
$(npm bin)/gulp build
|
||||
@ -124,42 +127,60 @@ $(npm bin)/gulp build
|
||||
Notes:
|
||||
* Results are put in the `dist` folder.
|
||||
* This will also run `pub get` for the subfolders in `modules` and run `dartanalyzer` for
|
||||
every file that matches `<module>/src/<module>.dart`, e.g. `di/src/di.dart`
|
||||
every file that matches `<module>/src/<module>.dart`, e.g. `di/src/di.dart`.
|
||||
|
||||
You can selectively build either the JS or Dart versions as follows:
|
||||
|
||||
* `$(npm bin)/gulp build.js`
|
||||
* `$(npm bin)/gulp build.dart`
|
||||
|
||||
To clean out the `dist` folder, run:
|
||||
|
||||
To clean out the `dist` folder use:
|
||||
```shell
|
||||
$(npm bin)/gulp clean
|
||||
```
|
||||
|
||||
## Running Tests Locally
|
||||
|
||||
### Basic tests
|
||||
### Full test suite
|
||||
|
||||
1. `$(npm bin)/gulp test.unit.js`: JS tests in a browser; runs in **watch mode** (i.e. karma
|
||||
watches the test files for changes and re-runs tests when files are updated).
|
||||
2. `$(npm bin)/gulp test.unit.cjs`: JS tests in NodeJS; runs in **watch mode**
|
||||
3. `$(npm bin)/gulp test.unit.dart`: Dart tests in Dartium; runs in **watch mode**.
|
||||
* `npm test`: full test suite for both JS and Dart versions of Angular. These are the same tests
|
||||
that run on Travis.
|
||||
|
||||
If you prefer running tests in "single-run" mode rather than watch mode use
|
||||
You can selectively run either the JS or Dart versions as follows:
|
||||
|
||||
* `$(npm bin)/gulp test.all.js`
|
||||
* `$(npm bin)/gulp test.all.dart`
|
||||
|
||||
### Unit tests
|
||||
|
||||
You can run just the unit tests as follows:
|
||||
|
||||
* `$(npm bin)/gulp test.unit.js`: JS tests in a browser; runs in **watch mode** (i.e.
|
||||
watches the test files for changes and re-runs tests when files are updated).
|
||||
* `$(npm bin)/gulp test.unit.cjs`: JS tests in NodeJS; runs in **watch mode**.
|
||||
* `$(npm bin)/gulp test.unit.dart`: Dart tests in Dartium; runs in **watch mode**.
|
||||
|
||||
If you prefer running tests in "single-run" mode rather than watch mode use:
|
||||
|
||||
* `$(npm bin)/gulp test.unit.js/ci`
|
||||
* `$(npm bin)/gulp test.unit.cjs/ci`
|
||||
* `$(npm bin)/gulp test.unit.dart/ci`
|
||||
|
||||
**Note**: If you want to only run a single test you can alter the test you wish
|
||||
to run by changing `it` to `iit` or `describe` to `ddescribe`. This will only
|
||||
run that individual test and make it much easier to debug. `xit` and `xdescribe`
|
||||
can also be useful to exclude a test and a group of tests respectively.
|
||||
The task updates the dist folder with transpiled code whenever a source or test file changes, and
|
||||
Karma is run against the new output.
|
||||
|
||||
**Note** for transpiler tests: The karma preprocessor is setup in a way so that after every test
|
||||
run the transpiler is reloaded. With that it is possible to make changes to the preprocessor and
|
||||
run the tests without exiting karma (just touch a test file that you would like to run).
|
||||
**Note**: If you want to only run a single test you can alter the test you wish to run by changing
|
||||
`it` to `iit` or `describe` to `ddescribe`. This will only run that individual test and make it
|
||||
much easier to debug. `xit` and `xdescribe` can also be useful to exclude a test and a group of
|
||||
tests respectively.
|
||||
|
||||
### E2e tests
|
||||
|
||||
1. `$(npm bin)/gulp build.js.cjs` (builds benchpress and tests into `dist/js/cjs` folder).
|
||||
2. `$(npm bin)/gulp serve.js.prod serve.js.dart2js` (runs local webserver).
|
||||
2. `$(npm bin)/gulp serve.js.prod serve.js.dart2js` (runs a local webserver).
|
||||
3. `$(npm bin)/protractor protractor-js.conf.js`: JS e2e tests.
|
||||
4. `$(npm bin)/protractor protractor-dart2js.conf.js`: Dart2JS e2e tests.
|
||||
4. `$(npm bin)/protractor protractor-dart2js.conf.js`: dart2js e2e tests.
|
||||
|
||||
Angular specific command line options when running protractor:
|
||||
- `$(npm bin)/protractor protractor-{js|dart2js}-conf.js --ng-help`
|
||||
@ -167,13 +188,56 @@ Angular specific command line options when running protractor:
|
||||
### Performance tests
|
||||
|
||||
1. `$(npm bin)/gulp build.js.cjs` (builds benchpress and tests into `dist/js/cjs` folder)
|
||||
2. `$(npm bin)/gulp serve.js.prod serve.js.dart2js` (runs local webserver)
|
||||
2. `$(npm bin)/gulp serve.js.prod serve.js.dart2js` (runs a local webserver)
|
||||
3. `$(npm bin)/protractor protractor-js.conf.js --benchmark`: JS performance tests
|
||||
4. `$(npm bin)/protractor protractor-dart2js.conf.js --benchmark`: Dart2JS performance tests
|
||||
4. `$(npm bin)/protractor protractor-dart2js.conf.js --benchmark`: dart2js performance tests
|
||||
|
||||
Angular specific command line options when running protractor (e.g. force gc, ...):
|
||||
`$(npm bin)/protractor protractor-{js|dart2js}-conf.js --ng-help`
|
||||
|
||||
## Formatting
|
||||
|
||||
We use [clang-format](http://clang.llvm.org/docs/ClangFormat.html) to automatically enforce code style for our TypeScript code.
|
||||
This allows us to focus our code reviews more on the content, and less on style nit-picking.
|
||||
It also lets us encode our style guide in the `.clang-format` file in the repository,
|
||||
allowing many tools and editors to share our settings.
|
||||
|
||||
To check the formatting of your code, run
|
||||
|
||||
gulp check-format
|
||||
|
||||
Note that the continuous build on Travis runs `gulp enforce-format`.
|
||||
Unlike the `check-format` task, this will actually fail the build if files aren't formatted according to the style guide.
|
||||
|
||||
Your life will be easier if you include the formatter in your standard workflow.
|
||||
Otherwise, you'll likely forget to check the formatting,
|
||||
and waste time waiting for a build on Travis that fails due to some whitespace difference.
|
||||
|
||||
* **git pre-commit hook** is available at
|
||||
[llvm.org](https://llvm.org/svn/llvm-project/cfe/trunk/tools/clang-format/git-clang-format).
|
||||
This will automatically format your delta regions when you commit a change.
|
||||
To install, first patch this file to add `.ts` to the `default_extensions` section.
|
||||
Then copy the file somewhere in your path, for example, `/usr/local/git/current/bin/git-clang-format`.
|
||||
Make sure it is executable. Then, in the angular repo, run
|
||||
|
||||
```
|
||||
$ echo -e '#!/bin/sh\nexec git clang-format' > .git/hooks/pre-commit
|
||||
$ chmod u+x !$
|
||||
```
|
||||
|
||||
* **WebStorm** can run clang-format on the current file.
|
||||
1. Under Preferences, open Tools > External Tools.
|
||||
1. Plus icon to Create Tool
|
||||
1. Fill in the form:
|
||||
- Name: clang-format
|
||||
- Description: Format
|
||||
- Synchronize files after execution: checked
|
||||
- Open console: not checked
|
||||
- Show in: Editor menu
|
||||
- Program: [path to clang-format, try `$ echo $(npm config get prefix)/bin/clang-format`]
|
||||
- Parameters: `-i -style=file $FilePath$`
|
||||
- Working directory: `$ProjectFileDir$`
|
||||
|
||||
## Project Information
|
||||
|
||||
### Folder structure
|
||||
@ -184,16 +248,20 @@ Angular specific command line options when running protractor (e.g. force gc, ..
|
||||
|
||||
### File suffixes
|
||||
|
||||
* `*.js`: javascript files that get transpiled to Dart and EcmaScript 5
|
||||
* `*.es6`: javascript files that get transpiled only to EcmaScript 5
|
||||
* `*.es5`: javascript files that don't get transpiled
|
||||
* `*.dart`: dart files that don't get transpiled
|
||||
* `*.js`: JavaScript files that get transpiled to Dart and EcmaScript 5
|
||||
* `*.es6`: JavaScript files that get transpiled only to EcmaScript 5
|
||||
* `*.es5`: JavaScript files that don't get transpiled
|
||||
* `*.dart`: Dart files that don't get transpiled
|
||||
|
||||
## CI using Travis
|
||||
|
||||
For instructions on setting up Continuous Integration using Travis, see the instructions given
|
||||
[here](https://github.com/angular/angular.dart/blob/master/travis.md).
|
||||
|
||||
## Transforming Dart code
|
||||
|
||||
See the [wiki](//github.com/angular/angular/wiki/Angular-2-Dart-Transformer).
|
||||
|
||||
## Debugging
|
||||
|
||||
### Debug the transpiler
|
||||
@ -219,17 +287,18 @@ Notes:
|
||||
|
||||
If you need to debug the tests:
|
||||
|
||||
- add a `debugger;` statement to the test you want to debug (oe the source code),
|
||||
- add a `debugger;` statement to the test you want to debug (or the source code),
|
||||
- execute karma `$(npm bin)/gulp test.js`,
|
||||
- press the top right "DEBUG" button,
|
||||
- open the dev tools and press F5,
|
||||
- the execution halt at the `debugger;` statement
|
||||
- open the DevTools and press F5,
|
||||
- the execution halts at the `debugger;` statement
|
||||
|
||||
**Note (WebStorm users)**:
|
||||
You can create a Karma run config from WebStorm.
|
||||
Then in the "Run" menu, press "Debug 'karma-js.conf.js'", WebStorm will stop in the generated code
|
||||
on the `debugger;` statement.
|
||||
You can then step into the code and add watches.
|
||||
|
||||
1. Create a Karma run config from WebStorm.
|
||||
2. Then in the "Run" menu, press "Debug 'karma-js.conf.js'", and WebStorm will stop in the generated
|
||||
code on the `debugger;` statement.
|
||||
3. You can then step into the code and add watches.
|
||||
|
||||
The `debugger;` statement is needed because WebStorm will stop in a transpiled file. Breakpoints in
|
||||
the original source files are not supported at the moment.
|
||||
|
||||
|
38
README.md
38
README.md
@ -1,15 +1,25 @@
|
||||
Angular [](https://travis-ci.org/angular/angular) [](https://gitter.im/angular/angular?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://travis-ci.org/angular/angular)
|
||||
[](https://gitter.im/angular/angular?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](http://issuestats.com/github/angular/angular)
|
||||
[](http://issuestats.com/github/angular/angular)
|
||||
[](http://badge.fury.io/js/angular2)
|
||||
[](https://npmjs.org/package/angular2)
|
||||
|
||||
Angular
|
||||
=========
|
||||
|
||||
Angular is a development platform for building mobile and desktop web applications. This is the
|
||||
repository for [Angular 2][ng2], both the JavaScript (JS) and [Dart][dart] versions.
|
||||
|
||||
Angular 2 is currently in **Alpha Preview**. We recommend using Angular 1.X for production
|
||||
Angular 2 is currently in **Developer Preview**. We recommend using Angular 1.X for production
|
||||
applications:
|
||||
|
||||
* [AngularJS][ngJS]: [angular/angular.js](http://github.com/angular/angular.js).
|
||||
* [AngularDart][ngDart]: [angular/angular.dart](http://github.com/angular/angular.dart).
|
||||
|
||||
## Quickstart
|
||||
|
||||
[Get started in 5 minutes][quickstart]
|
||||
|
||||
## Setup & Install Angular 2
|
||||
|
||||
@ -18,35 +28,15 @@ Follow the instructions given on the [Angular download page][download].
|
||||
|
||||
## Want to help?
|
||||
|
||||
Want to file a bug, or contribute some code or improve documentation? Excellent! Read up on our
|
||||
Want to file a bug, contribute some code, or improve documentation? Excellent! Read up on our
|
||||
guidelines for [contributing][contributing].
|
||||
|
||||
|
||||
## Examples
|
||||
|
||||
To see the examples, first build the project as described
|
||||
[here](http://github.com/angular/angular/blob/master/DEVELOPER.md).
|
||||
|
||||
### Hello World Example
|
||||
|
||||
This example consists of three basic pieces - a component, a decorator and a
|
||||
service. They are all constructed via injection. For more information see the
|
||||
comments in the source `modules/examples/src/hello_world/index.js`.
|
||||
|
||||
You can build this example as either JS or Dart app:
|
||||
|
||||
* JS:
|
||||
* `$(npm bin)/gulp serve.js.dev`, and
|
||||
* open `localhost:8000/examples/src/hello_world/` in Chrome.
|
||||
* Dart:
|
||||
* `$(npm bin)/gulp serve/examples.dart`, and
|
||||
* open `localhost:8080/src/hello_world` in Chrome (for dart2js) or
|
||||
[Dartium][dartium] (for Dart VM).
|
||||
|
||||
[contributing]: http://github.com/angular/angular/blob/master/CONTRIBUTING.md
|
||||
[dart]: http://www.dartlang.org
|
||||
[dartium]: http://www.dartlang.org/tools/dartium
|
||||
[download]: http://angular.io/download
|
||||
[quickstart]: https://angular.io/docs/js/latest/quickstart.html
|
||||
[ng2]: http://angular.io
|
||||
[ngDart]: http://angulardart.org
|
||||
[ngJS]: http://angularjs.org
|
||||
|
168
TRIAGE_AND_LABELS.md
Normal file
168
TRIAGE_AND_LABELS.md
Normal file
@ -0,0 +1,168 @@
|
||||
# Triage Process and Github Labels for Angular 2
|
||||
|
||||
This document describes how the Angular team uses labels and milestones to triage issues on github.
|
||||
|
||||
# Issues and PRs
|
||||
## Triaged vs Untriaged Issues
|
||||
|
||||
Every triaged issue must have four attributes assigned to it:
|
||||
|
||||
* `priority` -- P0 through P4. P0 issues are "drop everything and do this now". P4 are nice to have.
|
||||
* `component` -- Which area of Angular knowledge this relates to.
|
||||
* `effort` -- Rough assessment of how much work this issue is. E.g. `effort: hour` means
|
||||
"probably a few hours of work".
|
||||
* `type` -- Whether this issue is a bug, feature, or other kind of task.
|
||||
|
||||
Untriaged issues are any issues in the queue that don't yet have these four attributes.
|
||||
|
||||
You can view a report of untriaged issues here, in our
|
||||
[Angular Triage Dashboard](http://mhevery.github.io/github_issues/).
|
||||
|
||||
Issues should also have a clear action to complete that can be addressed or resolved within the
|
||||
scope of Angular 2. We'll close issues that don't meet these criteria.
|
||||
|
||||
### Assigning Issues to Milestones
|
||||
|
||||
Any issue that is being worked on must have:
|
||||
|
||||
* An `assignee`: The person doing the work.
|
||||
* A `Milestone`: When we expect to complete this work.
|
||||
|
||||
We aim to only have at most three milestones open at a time:
|
||||
|
||||
* Closing Milestone: A milestone with a very small number of issues, about to release.
|
||||
* Current Milestone: Work that we plan to complete within one week.
|
||||
* Next Milestone: Work that is > 1 week but current for the team.
|
||||
|
||||
The [backlog](https://github.com/angular/angular/issues?q=is%3Aopen+is%3Aissue+no%3Amilestone)
|
||||
consists of all issues that have been triaged but do not have an assignee or milestone.
|
||||
|
||||
## Triaged vs Untriaged PRs
|
||||
|
||||
Because of the cumulative pain associated with rebasing PRs, we triage PRs daily, and
|
||||
closing or reviewing PRs is a top priority ahead of other ongoing work.
|
||||
|
||||
Every triaged PR must have a `pr_action` label assigned to it and an assignee:
|
||||
|
||||
* `pr_action: cleanup` -- more work is needed from the current assignee.
|
||||
* `pr_action: discuss` -- discussion is needed, to be led by the current assignee.
|
||||
* `pr_action: merge` -- OK to merge this as soon as tests are green, `pr_state: LGTM`, and `CLA:
|
||||
yes` are true. assignee (or anyone else) can merge.
|
||||
* `pr_action: review` -- work is complete and comment is needed from the assignee.
|
||||
|
||||
In addition, PRs can have the following states:
|
||||
|
||||
* `pr_state: LGTM` -- PR may have outstanding changes but does not require further review.
|
||||
* `pr_state: WIP` -- PR is experimental or rapidly changing. Not ready for review or triage.
|
||||
* `pr_state: blocked` -- PR is blocked on an issue or other PR. Not ready for review or triage.
|
||||
|
||||
Note that an LGTM state does not mean a PR is ready to merge: for example, a reviewer might set the
|
||||
LGTM state but request a minor tweak that doesn't need further review, e.g., a rebase or small
|
||||
uncontroversial change.
|
||||
|
||||
PRs do not need to be assigned to milestones, unless a milestone release should be held for that
|
||||
PR to land.
|
||||
|
||||
Victor (`vsavkin`) and Tobias (`tbosch`) are owners of the PR queue. Here is a list of [current
|
||||
untriaged PRs](https://github.com/angular/angular/pulls?utf8=%E2%9C%93&q=is%3Aopen+no%3Amilestone+is%3Apr+-label%3A%22pr_action%3A+cleanup%22+-label%3A%22pr_action%3A+merge%22+-label%3A%22pr_action%3A+review%22+-label%3A%22pr_action%3A+discuss%22+-label%3A%22pr_state%3A+blocked%22+-label%3A%22pr_state%3A+WIP%22+).
|
||||
|
||||
# Prioritization of Work
|
||||
|
||||
What should you be working on?
|
||||
|
||||
1. Any PRs that are assigned to you that don't have `pr_state: WIP` or `pr_state: blocked`
|
||||
1. Any issues that are assigned to you in the lowest-numbered Milestone
|
||||
1. Any issues that are assigned to you in any Milestone
|
||||
|
||||
If there are no issues assigned to you in any Milestone, pick an issue, self-assign it, and add
|
||||
it to the most appropriate Milestone based on effort.
|
||||
|
||||
Here are some suggestions for what to work on next:
|
||||
|
||||
* Filter for issues in a component that you are knowledgeable about, and pick something that has a
|
||||
high priority.
|
||||
* Filter for any small effort task that has the special `cust: GT` or `cust:Ionic` tags,
|
||||
and priority > P3.
|
||||
* Add a new task that's really important, add `component`, `priority`, `effort`, `type` and
|
||||
assign it to yourself and the most appropriate milestone.
|
||||
|
||||
# Labels Used in Triage
|
||||
|
||||
## Priority
|
||||
How urgent is this issue? We use priority to determine what should be worked on in each new
|
||||
milestone.
|
||||
|
||||
* `P0: critical` -- drop everything to work on this
|
||||
* `P1: urgent` -- resolve quickly in the current milestone. people are blocked
|
||||
* `P2: required` -- needed for development but not urgent yet. workaround exists, or e.g. new API
|
||||
* `P3: important` -- must complete before Angular 2 is ready for release
|
||||
* `P4: nice to have` -- a good idea, but maybe not until after release
|
||||
|
||||
|
||||
## Effort
|
||||
Rough, non-binding estimate of how much work this issue represents. Please change this assessment
|
||||
for anything you're working on to better reflect reality.
|
||||
|
||||
* `effort: hour` -- straightforward issue that can be resolved in a few hours, e.g. < 1 day of work.
|
||||
* `effort: day` -- issue that will be a few days of work. Can be completed within a single
|
||||
milestone.
|
||||
* `effort: week` -- issue that will likely take more than 1 milestone to complete.
|
||||
|
||||
<!-- We don't like these label names as
|
||||
they're not absolute (what is one developer-hour, really?) but decided it wasn't worth arguing
|
||||
over terms. -->
|
||||
|
||||
## Component
|
||||
Which area of Angular knowledge is this issue most closely related to? Helpful when deciding what
|
||||
to work on next.
|
||||
|
||||
* `comp: benchpress` -- benchmarks and performance testing → *tbosch*, *crossj*
|
||||
* `comp: build/dev-productivity` -- build process, e.g. CLI and related tasks → *iminar*, *caitp*
|
||||
* `comp: build/pipeline` -- build pipeline, e.g. ts2dart → *mprobst*, *alexeagle*
|
||||
* `comp: core` -- general core Angular issues, not related to a sub-category (see below) →
|
||||
*mhevery*
|
||||
* `comp: core/animations` -- animations framework → *matsko*
|
||||
* `comp: core/change_detection` -- change detection → *vsavkin*
|
||||
* `comp: core/di` -- dependency injection → *vicb*, *rkirov*
|
||||
* `comp: core/directives` -- directives
|
||||
* `comp: core/forms` -- forms → *vsavkin*
|
||||
* `comp: core/pipes` -- pipes
|
||||
* `comp: core/templating` -- templating
|
||||
* `comp: core/testbed` -- e2e tests and support for them
|
||||
* `comp: dart-transformer` -- Dart transforms → *kegluneq*, *jakemac*
|
||||
* `comp: data-access` -- → *jeffbcross*
|
||||
* `comp: docs` -- API docs and doc generation → *naomiblack*, *petebacondarwin*
|
||||
* `comp: material-components` -- Angular Material components built in Angular 2 → *jelbourn*
|
||||
* `comp: router` -- Component Router → *btford*, *igorminar*, *matsko*
|
||||
* `comp: wrenchjs`
|
||||
|
||||
## Type
|
||||
What kind of problem is this?
|
||||
|
||||
* `type RFC / discussion / question`
|
||||
* `type bug`
|
||||
* `type chore`
|
||||
* `type feature`
|
||||
* `type performance`
|
||||
* `type refactor`
|
||||
|
||||
## Special Labels
|
||||
|
||||
### action:design
|
||||
More active discussion is needed before the issue can be worked on. Typically used for `type:
|
||||
feature` or `type: RFC/discussion/question`
|
||||
|
||||
<!-- TODO: Seems like this it's redundant to also have type:discussion, no? -->
|
||||
|
||||
[See all issues that need discussion](https://github.com/angular/angular/labels/action:%20Design)
|
||||
|
||||
### cla
|
||||
Managed by googlebot. Indicates whether a PR has a CLA on file for its author(s). Only issues with
|
||||
`cla:yes` should be merged into master.
|
||||
|
||||
### cust
|
||||
This is an issue causing user pain for early adopter customers `cust: GT` or `cust: Ionic`.
|
||||
|
||||
### WORKS_AS_INTENDED
|
||||
|
||||
Only used on closed issues, to indicate to the reporter why we closed it.
|
48
docs/angular.io-package/index.js
Normal file
48
docs/angular.io-package/index.js
Normal file
@ -0,0 +1,48 @@
|
||||
var path = require('canonical-path');
|
||||
var Package = require('dgeni').Package;
|
||||
var basePackage = require('../public-docs-package');
|
||||
|
||||
var PARTIAL_PATH = 'partials';
|
||||
var MODULES_DOCS_PATH = PARTIAL_PATH + '/api';
|
||||
|
||||
module.exports = new Package('angular.io', [basePackage])
|
||||
|
||||
.factory(require('./services/renderMarkdown'))
|
||||
.processor(require('./processors/addJadeDataDocsProcessor'))
|
||||
|
||||
// Configure rendering
|
||||
.config(function(templateFinder, templateEngine) {
|
||||
|
||||
templateFinder.templateFolders
|
||||
.unshift(path.resolve(__dirname, 'templates'));
|
||||
})
|
||||
|
||||
.config(function(writeFilesProcessor) {
|
||||
writeFilesProcessor.outputFolder = 'dist/angular.io';
|
||||
})
|
||||
|
||||
|
||||
.config(function(computeIdsProcessor, computePathsProcessor, EXPORT_DOC_TYPES) {
|
||||
|
||||
computePathsProcessor.pathTemplates.push({
|
||||
docTypes: ['module'],
|
||||
pathTemplate: '${id}/',
|
||||
outputPathTemplate: MODULES_DOCS_PATH + '/${id}/index.jade'
|
||||
});
|
||||
|
||||
computePathsProcessor.pathTemplates.push({
|
||||
docTypes: EXPORT_DOC_TYPES,
|
||||
pathTemplate: '${moduleDoc.id}/${name}-${docType}.html',
|
||||
outputPathTemplate: MODULES_DOCS_PATH + '/${moduleDoc.id}/${name}-${docType}.jade',
|
||||
});
|
||||
|
||||
computePathsProcessor.pathTemplates.push({
|
||||
docTypes: ['jade-data'],
|
||||
pathTemplate: '${originalDoc.id}/_data',
|
||||
outputPathTemplate: MODULES_DOCS_PATH + '/${path}.json'
|
||||
});
|
||||
})
|
||||
|
||||
.config(function(getLinkInfo) {
|
||||
getLinkInfo.relativeLinks = true;
|
||||
});
|
@ -0,0 +1,76 @@
|
||||
var _ = require('lodash');
|
||||
var path = require('canonical-path');
|
||||
|
||||
var titleCase = function(text) {
|
||||
return text.replace(/(.)(.*)/, function(_, first, rest) {
|
||||
return first.toUpperCase() + rest;
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
* Create _data.json file for Harp pages
|
||||
*
|
||||
* http://harpjs.com/docs/development/metadata
|
||||
*
|
||||
* This method creates the meta data required for each page
|
||||
* such as the title, description, etc. This meta data is used
|
||||
* in the harp static site generator to create the title for headers
|
||||
* and the navigation used in the API docs
|
||||
*
|
||||
*/
|
||||
|
||||
module.exports = function addJadeDataDocsProcessor() {
|
||||
return {
|
||||
$runAfter: ['adding-extra-docs'],
|
||||
$runBefore: ['extra-docs-added'],
|
||||
$process: function(docs) {
|
||||
var extraDocs = [];
|
||||
var modules = [];
|
||||
|
||||
|
||||
/*
|
||||
* Create Data for Modules
|
||||
*
|
||||
* Modules must be public and have content
|
||||
*/
|
||||
|
||||
_.forEach(docs, function(doc) {
|
||||
if (doc.docType === 'module' && doc.public && doc.exports.length) {
|
||||
modules.push(doc);
|
||||
|
||||
// GET DATA FOR INDEX PAGE OF MODULE SECTION
|
||||
var indexPageInfo = [{
|
||||
name: 'index',
|
||||
title: _.map(path.basename(doc.fileInfo.baseName).split('_'), function(part) {
|
||||
return titleCase(part);
|
||||
}).join(' '),
|
||||
intro: doc.description.replace('"', '\"').replace(/\r?\n|\r/g,"")
|
||||
}];
|
||||
|
||||
// GET DATA FOR EACH PAGE (CLASS, VARS, FUNCTIONS)
|
||||
var modulePageInfo = _.map(doc.exports, function(exportDoc) {
|
||||
return {
|
||||
name: exportDoc.name + '-' + exportDoc.docType,
|
||||
title: exportDoc.name + ' ' + titleCase(exportDoc.docType)
|
||||
};
|
||||
});
|
||||
|
||||
//COMBINE PAGE DATA
|
||||
var allPageData = indexPageInfo.concat(modulePageInfo);
|
||||
|
||||
// PUSH DATA TO EXTRA DOCS ARRAY
|
||||
extraDocs.push({
|
||||
id: doc.id + "-data",
|
||||
aliases: [doc.id + "-data"],
|
||||
docType: 'jade-data',
|
||||
originalDoc: doc,
|
||||
data: allPageData
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return docs.concat(extraDocs);
|
||||
}
|
||||
};
|
||||
};
|
50
docs/angular.io-package/services/renderMarkdown.js
Normal file
50
docs/angular.io-package/services/renderMarkdown.js
Normal file
@ -0,0 +1,50 @@
|
||||
var marked = require('marked');
|
||||
var Encoder = require('node-html-encoder').Encoder;
|
||||
var html2jade = require('html2jade');
|
||||
var indentString = require('indent-string');
|
||||
var S = require('string');
|
||||
|
||||
// entity type encoder
|
||||
var encoder = new Encoder('entity');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @dgService renderMarkdown
|
||||
* @description
|
||||
* Render the markdown in the given string as HTML.
|
||||
*/
|
||||
module.exports = function renderMarkdown(trimIndentation) {
|
||||
|
||||
var renderer = new marked.Renderer();
|
||||
|
||||
renderer.code = function(code, lang, escaped) {
|
||||
|
||||
var cssClasses = ['prettyprint', 'linenums'];
|
||||
var trimmedCode = trimIndentation(code);
|
||||
|
||||
if(lang) {
|
||||
if(lang=='html') {
|
||||
trimmedCode = encoder.htmlEncode(trimmedCode);
|
||||
}
|
||||
cssClasses.push(this.options.langPrefix + escape(lang, true));
|
||||
}
|
||||
|
||||
return 'pre(class="' + cssClasses.join(' ') + '")\n' + indentString('code.\n', ' ', 2) + trimmedCode;
|
||||
};
|
||||
|
||||
renderer.heading = function (text, level, raw) {
|
||||
var headingText = marked.Renderer.prototype.heading.call(renderer, text, level, raw);
|
||||
var title = 'h2 ' + S(headingText).stripTags().s;
|
||||
|
||||
if (level==2) {
|
||||
title = '.l-main-section\n' + indentString(title, ' ', 2) ;
|
||||
}
|
||||
|
||||
return title;
|
||||
};
|
||||
|
||||
return function(content) {
|
||||
return marked(content, { renderer: renderer });
|
||||
};
|
||||
};
|
50
docs/angular.io-package/templates/class.template.html
Normal file
50
docs/angular.io-package/templates/class.template.html
Normal file
@ -0,0 +1,50 @@
|
||||
{% include "lib/githubLinks.html" -%}
|
||||
{% include "lib/paramList.html" -%}
|
||||
{% extends 'layout/base.template.html' -%}
|
||||
|
||||
{% block body %}
|
||||
p.location-badge.
|
||||
exported from {@link {$ doc.moduleDoc.id $} {$doc.moduleDoc.id $} }
|
||||
defined in {$ githubViewLink(doc) $}
|
||||
|
||||
:markdown
|
||||
{$ doc.description | indent(2, true) $}
|
||||
|
||||
{%- if doc.constructorDoc or doc.members.length -%}
|
||||
.l-main-section
|
||||
h2 Members
|
||||
|
||||
{%- if doc.constructorDoc %}
|
||||
.l-sub-section
|
||||
h3 {$ doc.constructorDoc.name $}
|
||||
|
||||
{% if doc.constructorDoc.parameters %}
|
||||
pre.prettyprint
|
||||
code.
|
||||
{$ doc.constructorDoc.name $}{$ paramList(doc.constructorDoc.parameters) | indent(4, true) | trim $}
|
||||
{% endif %}
|
||||
:markdown
|
||||
{$ doc.constructorDoc.description | indent(6, true) | replace('## Example', '') | replace('# Example', '') $}
|
||||
|
||||
|
||||
{% endif -%}
|
||||
|
||||
{%- for member in doc.members %}{% if not member.private %}
|
||||
.l-sub-section
|
||||
h3 {$ member.name $}
|
||||
|
||||
{% if member.parameters %}
|
||||
pre.prettyprint
|
||||
code.
|
||||
{$ member.name $}{$ paramList(member.parameters) | indent(4, true) | trim $}{$ returnType(doc.returnType) $}
|
||||
{% endif %}
|
||||
:markdown
|
||||
|
||||
{$ member.description | indent(6, true) | replace('## Example', '') | replace('# Example', '') $}
|
||||
|
||||
|
||||
|
||||
{% endif %}{% endfor %}
|
||||
{%- endif -%}
|
||||
|
||||
{% endblock %}
|
22
docs/angular.io-package/templates/function.template.html
Normal file
22
docs/angular.io-package/templates/function.template.html
Normal file
@ -0,0 +1,22 @@
|
||||
{% include "lib/githubLinks.html" -%}
|
||||
{% include "lib/paramList.html" -%}
|
||||
{% extends 'layout/base.template.html' -%}
|
||||
|
||||
{% block body %}
|
||||
.l-main-section
|
||||
h2(class="function export") {$ doc.name $}
|
||||
|
||||
{% if doc.parameters %}
|
||||
pre.prettyprint
|
||||
code.
|
||||
{$ doc.name $}{$ paramList(doc.parameters) | indent(4, true) | trim $}{$ returnType(doc.returnType) $}
|
||||
{% endif %}
|
||||
|
||||
p.location-badge.
|
||||
exported from {@link {$ doc.moduleDoc.id $} {$doc.moduleDoc.id $} }
|
||||
defined in {$ githubViewLink(doc) $}
|
||||
|
||||
:markdown
|
||||
{$ doc.description | indent(4, true) $}
|
||||
|
||||
{% endblock %}
|
@ -0,0 +1,8 @@
|
||||
{
|
||||
{%- for item in doc.data %}
|
||||
"{$ item.name $}" : {
|
||||
"title" : "{$ item.title $}"{% if item.intro %},
|
||||
"intro" : "{$ item.intro $}"{% endif %}
|
||||
}{% if not loop.last %},{% endif %}
|
||||
{% endfor -%}
|
||||
}
|
@ -0,0 +1 @@
|
||||
{% block body %}{% endblock %}
|
12
docs/angular.io-package/templates/lib/paramList.html
Normal file
12
docs/angular.io-package/templates/lib/paramList.html
Normal file
@ -0,0 +1,12 @@
|
||||
{% macro paramList(params) -%}
|
||||
{%- if params -%}
|
||||
({%- for param in params -%}
|
||||
{$ param | escape $}{% if not loop.last %}, {% endif %}
|
||||
{%- endfor %})
|
||||
{%- endif %}
|
||||
{%- endmacro -%}
|
||||
|
||||
|
||||
{% macro returnType(returnType) -%}
|
||||
{%- if returnType %} : {$ returnType | escape $}{% endif -%}
|
||||
{%- endmacro -%}
|
15
docs/angular.io-package/templates/module.template.html
Normal file
15
docs/angular.io-package/templates/module.template.html
Normal file
@ -0,0 +1,15 @@
|
||||
{% include "lib/githubLinks.html" -%}
|
||||
{% extends 'layout/base.template.html' -%}
|
||||
{% block body -%}
|
||||
p.location-badge.
|
||||
defined in {$ githubViewLink(doc) $}
|
||||
|
||||
ul
|
||||
for page, slug in public.docs[current.path[1]][current.path[2]][current.path[3]][current.path[4]]._data
|
||||
if slug != 'index'
|
||||
url = "/docs/" + current.path[1] + "/" + current.path[2] + "/" + current.path[3] + "/" + current.path[4] + "/" + slug + ".html"
|
||||
|
||||
li.c8
|
||||
!= partial("../../../../../_includes/_hover-card", {name: page.title, url: url })
|
||||
|
||||
{% endblock %}
|
13
docs/angular.io-package/templates/var.template.html
Normal file
13
docs/angular.io-package/templates/var.template.html
Normal file
@ -0,0 +1,13 @@
|
||||
{% include "lib/githubLinks.html" -%}
|
||||
{% extends 'layout/base.template.html' %}
|
||||
|
||||
{% block body %}
|
||||
.l-main-section
|
||||
h2 {$ doc.name $} <span class="type">variable</span>
|
||||
p.location-badge.
|
||||
exported from {@link {$ doc.moduleDoc.id $} {$doc.moduleDoc.id $} }
|
||||
defined in {$ githubViewLink(doc) $}
|
||||
|
||||
:markdown
|
||||
{$ doc.description | indent(4, true) $}
|
||||
{% endblock %}
|
@ -364,3 +364,16 @@ md-content.demo-source-container > hljs > pre > code.highlight {
|
||||
padding-left:32px !important;
|
||||
padding-right:32px !important;
|
||||
}
|
||||
|
||||
|
||||
.member .name {
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
font-family: monospace;
|
||||
font-size: 1.17em;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.left-nav {
|
||||
min-width: 300px;
|
||||
}
|
@ -28,7 +28,7 @@
|
||||
|
||||
<section layout="row">
|
||||
|
||||
<md-content>
|
||||
<md-content class="left-nav">
|
||||
<h2>Navigation</h2>
|
||||
<section ng-repeat="area in nav.areas">
|
||||
<h3>{{ area.name }}</h3>
|
||||
@ -47,7 +47,7 @@
|
||||
|
||||
|
||||
<md-content class="md-padding">
|
||||
<ng-include src="nav.currentPage.partial"></ng-include>
|
||||
<ng-include autoscroll src="nav.currentPage.partial"></ng-include>
|
||||
</md-content>
|
||||
|
||||
</section>
|
||||
|
@ -14,7 +14,6 @@ angular.module('app', ['ngMaterial', 'navigation-modules', 'navigation-guides',
|
||||
];
|
||||
|
||||
this.updateCurrentPage = function(path) {
|
||||
path = path.replace(/^\//, '');
|
||||
console.log('path', path);
|
||||
this.currentPage = null;
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
require('../../tools/transpiler/index.js').init();
|
||||
|
||||
var versionInfo = require('./versionInfo');
|
||||
var Package = require('dgeni').Package;
|
||||
var jsdocPackage = require('dgeni-packages/jsdoc');
|
||||
var nunjucksPackage = require('dgeni-packages/nunjucks');
|
||||
var linksPackage = require('../links-package');
|
||||
var path = require('canonical-path');
|
||||
|
||||
var PARTIAL_PATH = 'partials';
|
||||
@ -10,25 +12,21 @@ var MODULES_DOCS_PATH = PARTIAL_PATH + '/modules';
|
||||
var GUIDES_PATH = PARTIAL_PATH + '/guides';
|
||||
|
||||
// Define the dgeni package for generating the docs
|
||||
module.exports = new Package('angular', [jsdocPackage, nunjucksPackage])
|
||||
module.exports = new Package('angular', [jsdocPackage, nunjucksPackage, linksPackage])
|
||||
|
||||
// Register the services and file readers
|
||||
.factory(require('./services/modules'))
|
||||
.factory(require('./services/atParser'))
|
||||
.factory(require('./services/getJSDocComment'))
|
||||
.factory(require('./services/SourceFile'))
|
||||
.factory(require('./services/TraceurParser'))
|
||||
.factory(require('./services/traceurOptions'))
|
||||
.factory(require('./services/ParseTreeVisitor'))
|
||||
.factory(require('./services/AttachCommentTreeVisitor'))
|
||||
.factory(require('./services/ExportTreeVisitor'))
|
||||
|
||||
.factory(require('./readers/atScript'))
|
||||
.factory(require('./services/tsParser'))
|
||||
.factory(require('./services/tsParser/createCompilerHost'))
|
||||
.factory(require('./services/tsParser/getFileInfo'))
|
||||
.factory(require('./services/tsParser/getExportDocType'))
|
||||
.factory(require('./services/tsParser/getContent'))
|
||||
.factory(require('./readers/ngdoc'))
|
||||
|
||||
.factory('EXPORT_DOC_TYPES', function() {
|
||||
return [
|
||||
'class',
|
||||
'interface',
|
||||
'function',
|
||||
'var',
|
||||
'const'
|
||||
@ -37,28 +35,58 @@ module.exports = new Package('angular', [jsdocPackage, nunjucksPackage])
|
||||
|
||||
|
||||
// Register the processors
|
||||
.processor(require('./processors/generateDocsFromComments'))
|
||||
.processor(require('./processors/processModuleDocs'))
|
||||
.processor(require('./processors/processClassDocs'))
|
||||
.processor(require('./processors/readTypeScriptModules'))
|
||||
.processor(require('./processors/generateNavigationDoc'))
|
||||
.processor(require('./processors/extractTitleFromGuides'))
|
||||
.processor(require('./processors/createOverviewDump'))
|
||||
.processor(require('./processors/createTypeDefinitionFile'))
|
||||
|
||||
|
||||
// Configure the log service
|
||||
.config(function(log) {
|
||||
log.level = 'info';
|
||||
log.level = 'warn';
|
||||
})
|
||||
|
||||
|
||||
.config(function(renderDocsProcessor) {
|
||||
renderDocsProcessor.extraData.versionInfo = versionInfo;
|
||||
})
|
||||
|
||||
// Configure file reading
|
||||
.config(function(readFilesProcessor, atScriptFileReader, ngdocFileReader) {
|
||||
readFilesProcessor.fileReaders = [atScriptFileReader, ngdocFileReader];
|
||||
.config(function(readFilesProcessor, ngdocFileReader, readTypeScriptModules) {
|
||||
readFilesProcessor.fileReaders = [ngdocFileReader];
|
||||
readFilesProcessor.basePath = path.resolve(__dirname, '../..');
|
||||
readFilesProcessor.sourceFiles = [
|
||||
{ include: 'modules/*/*.js', basePath: 'modules' },
|
||||
{ include: 'modules/*/src/**/*.js', basePath: 'modules' },
|
||||
{ include: 'modules/*/docs/**/*.md', basePath: 'modules' },
|
||||
{ include: 'docs/content/**/*.md', basePath: 'docs/content' }
|
||||
];
|
||||
|
||||
readTypeScriptModules.sourceFiles = [
|
||||
'*/*.@(js|es6|ts)',
|
||||
'*/src/**/*.@(js|es6|ts)'
|
||||
];
|
||||
readTypeScriptModules.basePath = 'modules';
|
||||
})
|
||||
|
||||
|
||||
.config(function(parseTagsProcessor, getInjectables) {
|
||||
parseTagsProcessor.tagDefinitions.push(require('./tag-defs/public'));
|
||||
parseTagsProcessor.tagDefinitions.push(require('./tag-defs/private'));
|
||||
parseTagsProcessor.tagDefinitions.push(require('./tag-defs/exportedAs'));
|
||||
|
||||
// We actually don't want to parse param docs in this package as we are getting the data out using TS
|
||||
parseTagsProcessor.tagDefinitions.forEach(function(tagDef) {
|
||||
if (tagDef.name === 'param') {
|
||||
tagDef.ignore = true;
|
||||
}
|
||||
});
|
||||
|
||||
})
|
||||
|
||||
|
||||
// Configure links
|
||||
.config(function(getLinkInfo) {
|
||||
getLinkInfo.useFirstAmbiguousLink = true;
|
||||
})
|
||||
|
||||
|
||||
@ -93,12 +121,6 @@ module.exports = new Package('angular', [jsdocPackage, nunjucksPackage])
|
||||
// Configure ids and paths
|
||||
.config(function(computeIdsProcessor, computePathsProcessor, EXPORT_DOC_TYPES) {
|
||||
|
||||
computeIdsProcessor.idTemplates.push({
|
||||
docTypes: EXPORT_DOC_TYPES,
|
||||
idTemplate: '${moduleDoc.id}.${name}',
|
||||
getAliases: function(doc) { return [doc.id]; }
|
||||
});
|
||||
|
||||
computeIdsProcessor.idTemplates.push({
|
||||
docTypes: ['member'],
|
||||
idTemplate: '${classDoc.id}.${name}',
|
||||
@ -122,7 +144,7 @@ module.exports = new Package('angular', [jsdocPackage, nunjucksPackage])
|
||||
|
||||
computePathsProcessor.pathTemplates.push({
|
||||
docTypes: ['module'],
|
||||
pathTemplate: '${id}',
|
||||
pathTemplate: '/${id}',
|
||||
outputPathTemplate: MODULES_DOCS_PATH + '/${id}/index.html'
|
||||
});
|
||||
|
||||
@ -141,7 +163,7 @@ module.exports = new Package('angular', [jsdocPackage, nunjucksPackage])
|
||||
|
||||
computePathsProcessor.pathTemplates.push({
|
||||
docTypes: ['guide'],
|
||||
pathTemplate: '${id}',
|
||||
pathTemplate: '/${id}',
|
||||
outputPathTemplate: GUIDES_PATH + '/${id}.html'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
1
docs/dgeni-package/mocks/importedSrc.ts
Normal file
1
docs/dgeni-package/mocks/importedSrc.ts
Normal file
@ -0,0 +1 @@
|
||||
export var x = 100;
|
@ -0,0 +1,4 @@
|
||||
export var __esModule = true;
|
||||
export class OKToExport {}
|
||||
export function _thisIsPrivate() {}
|
||||
export var thisIsOK = '!';
|
@ -0,0 +1,12 @@
|
||||
export class Test {
|
||||
firstItem;
|
||||
constructor() {
|
||||
this.doStuff();
|
||||
}
|
||||
otherMethod() {
|
||||
|
||||
}
|
||||
doStuff() {
|
||||
|
||||
}
|
||||
}
|
38
docs/dgeni-package/mocks/testSrc.ts
Normal file
38
docs/dgeni-package/mocks/testSrc.ts
Normal file
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* @module
|
||||
* @description
|
||||
* This is the module description
|
||||
*/
|
||||
|
||||
export * from 'importedSrc';
|
||||
|
||||
/**
|
||||
* This is some random other comment
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is MyClass
|
||||
*/
|
||||
export class MyClass {
|
||||
message: String;
|
||||
|
||||
/**
|
||||
* Create a new MyClass
|
||||
* @param {String} name The name to say hello to
|
||||
*/
|
||||
constructor(name) {
|
||||
this.message = 'hello ' + name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a greeting message
|
||||
*/
|
||||
greet() {
|
||||
return this.message;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An exported function
|
||||
*/
|
||||
export var myFn = (val:number) => return val*2;
|
24
docs/dgeni-package/processors/createOverviewDump.js
Normal file
24
docs/dgeni-package/processors/createOverviewDump.js
Normal file
@ -0,0 +1,24 @@
|
||||
var _ = require('lodash');
|
||||
|
||||
module.exports = function createOverviewDump() {
|
||||
|
||||
return {
|
||||
$runAfter: ['processing-docs'],
|
||||
$runBefore: ['docs-processed'],
|
||||
$process: function(docs) {
|
||||
var overviewDoc = {
|
||||
id: 'overview-dump',
|
||||
aliases: ['overview-dump'],
|
||||
path: 'overview-dump',
|
||||
outputPath: 'overview-dump.html',
|
||||
modules: []
|
||||
};
|
||||
_.forEach(docs, function(doc) {
|
||||
if ( doc.docType === 'module' ) {
|
||||
overviewDoc.modules.push(doc);
|
||||
}
|
||||
});
|
||||
docs.push(overviewDoc);
|
||||
}
|
||||
};
|
||||
};
|
26
docs/dgeni-package/processors/createTypeDefinitionFile.js
Normal file
26
docs/dgeni-package/processors/createTypeDefinitionFile.js
Normal file
@ -0,0 +1,26 @@
|
||||
var _ = require('lodash');
|
||||
|
||||
module.exports = function createTypeDefinitionFile() {
|
||||
|
||||
return {
|
||||
$runAfter: ['processing-docs'],
|
||||
$runBefore: ['docs-processed'],
|
||||
$process: function(docs) {
|
||||
var typeDefDoc = {
|
||||
id: 'type-definition',
|
||||
aliases: ['type-definition'],
|
||||
path: 'type-definition',
|
||||
outputPath: 'angular2.d.ts',
|
||||
modules: []
|
||||
};
|
||||
_.forEach(docs, function(doc) {
|
||||
// The shape of the public API is determined by what is reexported into
|
||||
// angular2/angular2.
|
||||
if (doc.id === 'angular2/angular2') {
|
||||
typeDefDoc.modules.push(doc);
|
||||
}
|
||||
});
|
||||
docs.push(typeDefDoc);
|
||||
}
|
||||
};
|
||||
};
|
@ -1,34 +0,0 @@
|
||||
var _ = require('lodash');
|
||||
|
||||
module.exports = function generateDocsFromComments(log) {
|
||||
return {
|
||||
$runAfter: ['files-read'],
|
||||
$runBefore: ['parsing-tags'],
|
||||
$process: function(docs) {
|
||||
var commentDocs = [];
|
||||
docs = _.filter(docs, function(doc) {
|
||||
if (doc.docType !== 'atScriptFile') {
|
||||
return true;
|
||||
} else {
|
||||
_.forEach(doc.fileInfo.comments, function(comment) {
|
||||
|
||||
// we need to check for `/**` at the start of the comment to find all the jsdoc style comments
|
||||
comment.range.toString().replace(/^\/\*\*([\w\W]*)\*\/$/g, function(match, commentBody) {
|
||||
|
||||
// Create a doc from this comment
|
||||
commentDocs.push({
|
||||
fileInfo: doc.fileInfo,
|
||||
startingLine: comment.range.start.line,
|
||||
endingLine: comment.range.end.line,
|
||||
content: commentBody,
|
||||
codeTree: comment.treeAfter,
|
||||
docType: 'atScriptDoc'
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
return docs.concat(commentDocs);
|
||||
}
|
||||
};
|
||||
};
|
@ -27,13 +27,15 @@ module.exports = function generateNavigationDoc() {
|
||||
modulesDoc.value.sections.push(moduleNavItem);
|
||||
|
||||
_.forEach(doc.exports, function(exportDoc) {
|
||||
var exportNavItem = {
|
||||
path: exportDoc.path,
|
||||
partial: exportDoc.outputPath,
|
||||
name: exportDoc.name,
|
||||
type: exportDoc.docType
|
||||
};
|
||||
moduleNavItem.pages.push(exportNavItem);
|
||||
if (!exportDoc.private) {
|
||||
var exportNavItem = {
|
||||
path: exportDoc.path,
|
||||
partial: exportDoc.outputPath,
|
||||
name: exportDoc.name,
|
||||
type: exportDoc.docType
|
||||
};
|
||||
moduleNavItem.pages.push(exportNavItem);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -1,47 +0,0 @@
|
||||
var _ = require('lodash');
|
||||
|
||||
module.exports = function processClassDocs(log, getJSDocComment) {
|
||||
|
||||
return {
|
||||
$runAfter: ['processModuleDocs'],
|
||||
$runBefore: ['parsing-tags', 'generateDocsFromComments'],
|
||||
ignorePrivateMembers: false,
|
||||
$process: function(docs) {
|
||||
var memberDocs = [];
|
||||
var ignorePrivateMembers = this.ignorePrivateMembers;
|
||||
_.forEach(docs, function(classDoc) {
|
||||
if ( classDoc.docType === 'class' ) {
|
||||
|
||||
classDoc.members = [];
|
||||
|
||||
// Create a new doc for each member of the class
|
||||
_.forEach(classDoc.elements, function(memberDoc) {
|
||||
|
||||
if (ignorePrivateMembers && memberDoc.name.literalToken.value.charAt(0) === '_') return;
|
||||
|
||||
classDoc.members.push(memberDoc);
|
||||
memberDocs.push(memberDoc);
|
||||
|
||||
memberDoc.docType = 'member';
|
||||
memberDoc.classDoc = classDoc;
|
||||
memberDoc.name = memberDoc.name.literalToken.value;
|
||||
|
||||
|
||||
if (memberDoc.commentBefore ) {
|
||||
// If this export has a comment, remove it from the list of
|
||||
// comments collected in the module
|
||||
var index = classDoc.moduleDoc.comments.indexOf(memberDoc.commentBefore);
|
||||
if ( index !== -1 ) {
|
||||
classDoc.moduleDoc.comments.splice(index, 1);
|
||||
}
|
||||
|
||||
_.assign(memberDoc, getJSDocComment(memberDoc.commentBefore));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return docs.concat(memberDocs);
|
||||
}
|
||||
};
|
||||
};
|
@ -1,46 +0,0 @@
|
||||
var _ = require('lodash');
|
||||
|
||||
module.exports = function processModuleDocs(log, ExportTreeVisitor, getJSDocComment) {
|
||||
|
||||
return {
|
||||
$runAfter: ['files-read'],
|
||||
$runBefore: ['parsing-tags', 'generateDocsFromComments'],
|
||||
$process: function(docs) {
|
||||
var exportDocs = [];
|
||||
_.forEach(docs, function(doc) {
|
||||
if ( doc.docType === 'module' ) {
|
||||
|
||||
log.debug('processing', doc.moduleTree.moduleName);
|
||||
|
||||
doc.exports = [];
|
||||
|
||||
if ( doc.moduleTree.visit ) {
|
||||
var visitor = new ExportTreeVisitor();
|
||||
visitor.visit(doc.moduleTree);
|
||||
|
||||
_.forEach(visitor.exports, function(exportDoc) {
|
||||
|
||||
doc.exports.push(exportDoc);
|
||||
exportDocs.push(exportDoc);
|
||||
exportDoc.moduleDoc = doc;
|
||||
|
||||
if (exportDoc.comment) {
|
||||
// If this export has a comment, remove it from the list of
|
||||
// comments collected in the module
|
||||
var index = doc.comments.indexOf(exportDoc.comment);
|
||||
if ( index !== -1 ) {
|
||||
doc.comments.splice(index, 1);
|
||||
}
|
||||
|
||||
_.assign(exportDoc, getJSDocComment(exportDoc.comment));
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return docs.concat(exportDocs);
|
||||
}
|
||||
};
|
||||
};
|
235
docs/dgeni-package/processors/readTypeScriptModules.js
Normal file
235
docs/dgeni-package/processors/readTypeScriptModules.js
Normal file
@ -0,0 +1,235 @@
|
||||
var glob = require('glob');
|
||||
var path = require('canonical-path');
|
||||
var _ = require('lodash');
|
||||
var ts = require('typescript');
|
||||
|
||||
module.exports = function readTypeScriptModules(tsParser, readFilesProcessor, modules, getFileInfo, getExportDocType, getContent, log) {
|
||||
|
||||
return {
|
||||
$runAfter: ['files-read'],
|
||||
$runBefore: ['parsing-tags'],
|
||||
|
||||
$validate: {
|
||||
sourceFiles: {presence: true},
|
||||
basePath: {presence: true},
|
||||
hidePrivateMembers: { inclusion: [true, false] },
|
||||
sortClassMembers: { inclusion: [true, false] },
|
||||
ignoreExportsMatching: {}
|
||||
},
|
||||
|
||||
// A collection of globs that identify those modules for which we should create docs
|
||||
sourceFiles: [],
|
||||
// The base path from which to load the source files
|
||||
basePath: '.',
|
||||
// We can ignore members of classes that are private
|
||||
hidePrivateMembers: true,
|
||||
// We can sort class members alphabetically
|
||||
sortClassMembers: true,
|
||||
// We can provide a collection of strings or regexes to ignore exports whose export names match
|
||||
ignoreExportsMatching: ['___esModule'],
|
||||
|
||||
$process: function(docs) {
|
||||
|
||||
// Convert ignoreExportsMatching to an array of regexes
|
||||
var ignoreExportsMatching = convertToRegexCollection(this.ignoreExportsMatching);
|
||||
|
||||
var hidePrivateMembers = this.hidePrivateMembers;
|
||||
var sortClassMembers = this.sortClassMembers;
|
||||
|
||||
var basePath = path.resolve(readFilesProcessor.basePath, this.basePath);
|
||||
var filesPaths = expandSourceFiles(this.sourceFiles, basePath);
|
||||
var parseInfo = tsParser.parse(filesPaths, this.basePath);
|
||||
var moduleSymbols = parseInfo.moduleSymbols;
|
||||
|
||||
// Iterate through each of the modules that were parsed and generate a module doc
|
||||
// as well as docs for each module's exports.
|
||||
moduleSymbols.forEach(function(moduleSymbol) {
|
||||
|
||||
var moduleDoc = createModuleDoc(moduleSymbol, basePath);
|
||||
|
||||
// Add this module doc to the module lookup collection and the docs collection
|
||||
modules[moduleDoc.id] = moduleDoc;
|
||||
docs.push(moduleDoc);
|
||||
|
||||
// Iterate through this module's exports and generate a doc for each
|
||||
moduleSymbol.exportArray.forEach(function(exportSymbol) {
|
||||
|
||||
// Ignore exports starting with an underscore
|
||||
if (anyMatches(ignoreExportsMatching, exportSymbol.name)) return;
|
||||
|
||||
// If the symbol is an Alias then for most things we want the original resolved symbol
|
||||
var resolvedExport = exportSymbol.resolvedSymbol || exportSymbol;
|
||||
var exportDoc = createExportDoc(exportSymbol.name, resolvedExport, moduleDoc, basePath, parseInfo.typeChecker);
|
||||
log.debug('>>>> EXPORT: ' + exportDoc.name + ' (' + exportDoc.docType + ') from ' + moduleDoc.id);
|
||||
|
||||
// Generate docs for each of the export's members
|
||||
if (resolvedExport.flags & ts.SymbolFlags.HasMembers) {
|
||||
|
||||
exportDoc.members = [];
|
||||
for(var memberName in resolvedExport.members) {
|
||||
log.silly('>>>>>> member: ' + memberName + ' from ' + exportDoc.id + ' in ' + moduleDoc.id);
|
||||
var memberSymbol = resolvedExport.members[memberName];
|
||||
var memberDoc = createMemberDoc(memberSymbol, exportDoc, basePath, parseInfo.typeChecker);
|
||||
|
||||
// We special case the constructor and sort the other members alphabetically
|
||||
if (memberSymbol.flags & ts.SymbolFlags.Constructor) {
|
||||
exportDoc.constructorDoc = memberDoc;
|
||||
docs.push(memberDoc);
|
||||
} else if (!hidePrivateMembers || memberSymbol.name.charAt(0) !== '_') {
|
||||
docs.push(memberDoc);
|
||||
exportDoc.members.push(memberDoc);
|
||||
}
|
||||
}
|
||||
|
||||
if (sortClassMembers) {
|
||||
exportDoc.members.sort(function(a, b) {
|
||||
if (a.name > b.name) return 1;
|
||||
if (a.name < b.name) return -1;
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Add this export doc to its module doc
|
||||
moduleDoc.exports.push(exportDoc);
|
||||
docs.push(exportDoc);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
function createModuleDoc(moduleSymbol, basePath) {
|
||||
var id = moduleSymbol.name.replace(/^"|"$/g, '');
|
||||
var moduleDoc = {
|
||||
docType: 'module',
|
||||
id: id,
|
||||
aliases: [id],
|
||||
moduleTree: moduleSymbol,
|
||||
content: getContent(moduleSymbol),
|
||||
exports: [],
|
||||
fileInfo: getFileInfo(moduleSymbol, basePath),
|
||||
location: getLocation(moduleSymbol)
|
||||
};
|
||||
return moduleDoc;
|
||||
}
|
||||
|
||||
function createExportDoc(name, exportSymbol, moduleDoc, basePath, typeChecker) {
|
||||
var exportDoc = {
|
||||
docType: getExportDocType(exportSymbol),
|
||||
name: name,
|
||||
id: name,
|
||||
aliases: [name],
|
||||
moduleDoc: moduleDoc,
|
||||
content: getContent(exportSymbol),
|
||||
fileInfo: getFileInfo(exportSymbol, basePath),
|
||||
location: getLocation(exportSymbol)
|
||||
};
|
||||
if(exportSymbol.flags & ts.SymbolFlags.Function) {
|
||||
exportDoc.parameters = getParameters(typeChecker, exportSymbol);
|
||||
}
|
||||
if(exportSymbol.flags & ts.SymbolFlags.Value) {
|
||||
exportDoc.returnType = getReturnType(typeChecker, exportSymbol);
|
||||
}
|
||||
return exportDoc;
|
||||
}
|
||||
|
||||
function createMemberDoc(memberSymbol, classDoc, basePath, typeChecker) {
|
||||
var memberDoc = {
|
||||
docType: 'member',
|
||||
classDoc: classDoc,
|
||||
name: memberSymbol.name,
|
||||
id: memberSymbol.name,
|
||||
content: getContent(memberSymbol),
|
||||
fileInfo: getFileInfo(memberSymbol, basePath),
|
||||
location: getLocation(memberSymbol)
|
||||
};
|
||||
|
||||
if (memberSymbol.flags & ts.SymbolFlags.Method) {
|
||||
// NOTE: we use the property name `parameters` here so we don't conflict
|
||||
// with the `params` property that will be updated by dgeni reading the
|
||||
// `@param` tags from the docs
|
||||
memberDoc.parameters = getParameters(typeChecker, memberSymbol);
|
||||
}
|
||||
|
||||
if (memberSymbol.flags & ts.SymbolFlags.Constructor) {
|
||||
memberDoc.parameters = getParameters(typeChecker, memberSymbol);
|
||||
memberDoc.name = 'constructor';
|
||||
}
|
||||
|
||||
if(memberSymbol.flags & ts.SymbolFlags.Value) {
|
||||
memberDoc.returnType = getReturnType(typeChecker, memberSymbol);
|
||||
}
|
||||
|
||||
return memberDoc;
|
||||
}
|
||||
|
||||
function getParameters(typeChecker, symbol) {
|
||||
var declaration = symbol.valueDeclaration || symbol.declarations[0];
|
||||
var sourceFile = ts.getSourceFileOfNode(declaration);
|
||||
if(!declaration.parameters) {
|
||||
var location = getLocation(symbol);
|
||||
throw new Error('missing declaration parameters for "' + symbol.name +
|
||||
'" in ' + sourceFile.fileName +
|
||||
' at line ' + location.start.line);
|
||||
}
|
||||
return declaration.parameters.map(function(parameter) {
|
||||
return getText(sourceFile, parameter).trim();
|
||||
});
|
||||
}
|
||||
|
||||
function getReturnType(typeChecker, symbol) {
|
||||
var declaration = symbol.valueDeclaration || symbol.declarations[0];
|
||||
var sourceFile = ts.getSourceFileOfNode(declaration);
|
||||
if (declaration.type) {
|
||||
return getText(sourceFile, declaration.type).trim();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function expandSourceFiles(sourceFiles, basePath) {
|
||||
var filePaths = [];
|
||||
sourceFiles.forEach(function(sourcePattern) {
|
||||
filePaths = filePaths.concat(glob.sync(sourcePattern, { cwd: basePath }));
|
||||
});
|
||||
return filePaths;
|
||||
}
|
||||
|
||||
|
||||
function getText(sourceFile, node) {
|
||||
return sourceFile.text.substring(node.pos, node.end);
|
||||
}
|
||||
|
||||
|
||||
function getLocation(symbol) {
|
||||
var node = symbol.valueDeclaration || symbol.declarations[0];
|
||||
var sourceFile = ts.getSourceFileOfNode(node);
|
||||
var location = {
|
||||
start: ts.getLineAndCharacterOfPosition(sourceFile, node.pos),
|
||||
end: ts.getLineAndCharacterOfPosition(sourceFile, node.end)
|
||||
};
|
||||
return location;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
function convertToRegexCollection(items) {
|
||||
if (!items) return [];
|
||||
|
||||
// Must be an array
|
||||
if (!_.isArray(items)) {
|
||||
items = [items];
|
||||
}
|
||||
|
||||
// Convert string to exact matching regexes
|
||||
return items.map(function(item) {
|
||||
return _.isString(item) ? new RegExp('^' + item + '$') : item;
|
||||
});
|
||||
}
|
||||
|
||||
function anyMatches(regexes, item) {
|
||||
for(var i=0; i<regexes.length; ++i) {
|
||||
if ( item.match(regexes[i]) ) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
81
docs/dgeni-package/processors/readTypeScriptModules.spec.js
Normal file
81
docs/dgeni-package/processors/readTypeScriptModules.spec.js
Normal file
@ -0,0 +1,81 @@
|
||||
var mockPackage = require('../mocks/mockPackage');
|
||||
var Dgeni = require('dgeni');
|
||||
var path = require('canonical-path');
|
||||
var _ = require('lodash');
|
||||
|
||||
describe('readTypeScriptModules', function() {
|
||||
var dgeni, injector, processor;
|
||||
|
||||
beforeEach(function() {
|
||||
dgeni = new Dgeni([mockPackage()]);
|
||||
injector = dgeni.configureInjector();
|
||||
processor = injector.get('readTypeScriptModules');
|
||||
processor.basePath = path.resolve(__dirname, '../mocks/readTypeScriptModules');
|
||||
});
|
||||
|
||||
|
||||
describe('ignoreExportsMatching', function() {
|
||||
it('should ignore exports that match items in the `ignoreExportsMatching` property', function() {
|
||||
processor.sourceFiles = [ 'ignoreExportsMatching.ts'];
|
||||
processor.ignoreExportsMatching = [/^_/];
|
||||
var docs = [];
|
||||
processor.$process(docs);
|
||||
|
||||
var moduleDoc = docs[0];
|
||||
expect(moduleDoc.docType).toEqual('module');
|
||||
expect(moduleDoc.exports).toEqual([
|
||||
jasmine.objectContaining({ name: 'OKToExport' }),
|
||||
jasmine.objectContaining({ name: 'thisIsOK' })
|
||||
]);
|
||||
});
|
||||
|
||||
it('should only ignore `___esModule` exports by default', function() {
|
||||
processor.sourceFiles = [ 'ignoreExportsMatching.ts'];
|
||||
var docs = [];
|
||||
processor.$process(docs);
|
||||
|
||||
var moduleDoc = docs[0];
|
||||
expect(moduleDoc.docType).toEqual('module');
|
||||
expect(getNames(moduleDoc.exports)).toEqual([
|
||||
'OKToExport',
|
||||
'_thisIsPrivate',
|
||||
'thisIsOK'
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('ordering of members', function() {
|
||||
it('should order class members alphabetically (by default)', function() {
|
||||
processor.sourceFiles = ['orderingOfMembers.ts'];
|
||||
var docs = [];
|
||||
processor.$process(docs);
|
||||
var classDoc = _.find(docs, { docType: 'class' });
|
||||
expect(classDoc.docType).toEqual('class');
|
||||
expect(getNames(classDoc.members)).toEqual([
|
||||
'doStuff',
|
||||
'firstItem',
|
||||
'otherMethod'
|
||||
]);
|
||||
});
|
||||
|
||||
|
||||
it('should not order class members if not sortClassMembers is false', function() {
|
||||
processor.sourceFiles = ['orderingOfMembers.ts'];
|
||||
processor.sortClassMembers = false;
|
||||
var docs = [];
|
||||
processor.$process(docs);
|
||||
var classDoc = _.find(docs, { docType: 'class' });
|
||||
expect(classDoc.docType).toEqual('class');
|
||||
expect(getNames(classDoc.members)).toEqual([
|
||||
'firstItem',
|
||||
'otherMethod',
|
||||
'doStuff'
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function getNames(collection) {
|
||||
return collection.map(function(item) { return item.name; });
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
var path = require('canonical-path');
|
||||
|
||||
|
||||
/**
|
||||
* @dgService atScriptFileReader
|
||||
* @description
|
||||
* This file reader will create a simple doc for each
|
||||
* file including a code AST of the AtScript in the file.
|
||||
*/
|
||||
module.exports = function atScriptFileReader(log, atParser, modules) {
|
||||
var reader = {
|
||||
name: 'atScriptFileReader',
|
||||
defaultPattern: /\.js$/,
|
||||
getDocs: function(fileInfo) {
|
||||
|
||||
var moduleDoc = atParser.parseModule(fileInfo);
|
||||
moduleDoc.docType = 'module';
|
||||
moduleDoc.id = moduleDoc.moduleTree.moduleName;
|
||||
moduleDoc.aliases = [moduleDoc.id];
|
||||
|
||||
modules[moduleDoc.id] = moduleDoc;
|
||||
|
||||
// Readers return a collection of docs read from the file
|
||||
// but in this read there is only one document (module) to return
|
||||
return [moduleDoc];
|
||||
}
|
||||
};
|
||||
|
||||
return reader;
|
||||
|
||||
|
||||
};
|
@ -1,55 +0,0 @@
|
||||
var mockPackage = require('../mocks/mockPackage');
|
||||
var Dgeni = require('dgeni');
|
||||
|
||||
describe('atScript file reader', function() {
|
||||
|
||||
var dgeni, injector, reader;
|
||||
|
||||
var fileContent =
|
||||
'import {CONST} from "facade/lang";\n' +
|
||||
'\n' +
|
||||
'/**\n' +
|
||||
'* A parameter annotation that creates a synchronous eager dependency.\n' +
|
||||
'*\n' +
|
||||
'* class AComponent {\n' +
|
||||
'* constructor(@Inject("aServiceToken") aService) {}\n' +
|
||||
'* }\n' +
|
||||
'*\n' +
|
||||
'*/\n' +
|
||||
'export class Inject {\n' +
|
||||
'token;\n' +
|
||||
'@CONST()\n' +
|
||||
'constructor(token) {\n' +
|
||||
'this.token = token;\n' +
|
||||
'}\n' +
|
||||
'}';
|
||||
|
||||
|
||||
beforeEach(function() {
|
||||
dgeni = new Dgeni([mockPackage()]);
|
||||
injector = dgeni.configureInjector();
|
||||
reader = injector.get('atScriptFileReader');
|
||||
});
|
||||
|
||||
|
||||
it('should provide a default pattern', function() {
|
||||
expect(reader.defaultPattern).toEqual(/\.js$/);
|
||||
});
|
||||
|
||||
|
||||
it('should parse the file using the atParser and return a single doc', function() {
|
||||
|
||||
var atParser = injector.get('atParser');
|
||||
spyOn(atParser, 'parseModule').and.callThrough();
|
||||
|
||||
var docs = reader.getDocs({
|
||||
content: fileContent,
|
||||
relativePath: 'di/src/annotations.js'
|
||||
});
|
||||
|
||||
expect(atParser.parseModule).toHaveBeenCalled();
|
||||
expect(docs.length).toEqual(1);
|
||||
expect(docs[0].docType).toEqual('module');
|
||||
});
|
||||
|
||||
});
|
@ -1,47 +0,0 @@
|
||||
module.exports = function AttachCommentTreeVisitor(ParseTreeVisitor, log) {
|
||||
|
||||
function AttachCommentTreeVisitorImpl() {
|
||||
ParseTreeVisitor.call(this);
|
||||
}
|
||||
|
||||
AttachCommentTreeVisitorImpl.prototype = {
|
||||
|
||||
__proto__: ParseTreeVisitor.prototype,
|
||||
|
||||
|
||||
visit: function(tree, comments) {
|
||||
this.comments = comments;
|
||||
this.index = 0;
|
||||
this.currentComment = this.comments[this.index];
|
||||
|
||||
if (this.currentComment) log.silly('comment: ' +
|
||||
this.currentComment.range.start.line + ' - ' +
|
||||
this.currentComment.range.end.line + ' : ' +
|
||||
this.currentComment.range.toString());
|
||||
|
||||
ParseTreeVisitor.prototype.visit.call(this, tree);
|
||||
},
|
||||
|
||||
// Really we ought to subclass ParseTreeVisitor but this is fiddly in ES5 so
|
||||
// it is easier to simply override the prototype's method on the instance
|
||||
visitAny: function(tree) {
|
||||
if (tree && tree.location && tree.location.start && this.currentComment &&
|
||||
this.currentComment.range.end.offset < tree.location.start.offset) {
|
||||
log.silly('tree: ' + tree.constructor.name + ' - ' + tree.location.start.line);
|
||||
while (this.currentComment &&
|
||||
this.currentComment.range.end.offset < tree.location.start.offset) {
|
||||
log.silly('comment: ' + this.currentComment.range.start.line + ' - ' +
|
||||
this.currentComment.range.end.line + ' : ' +
|
||||
this.currentComment.range.toString());
|
||||
tree.commentBefore = this.currentComment;
|
||||
this.currentComment.treeAfter = tree;
|
||||
this.index++;
|
||||
this.currentComment = this.comments[this.index];
|
||||
}
|
||||
}
|
||||
return ParseTreeVisitor.prototype.visitAny.call(this, tree);
|
||||
}
|
||||
};
|
||||
|
||||
return AttachCommentTreeVisitorImpl;
|
||||
};
|
@ -1,103 +0,0 @@
|
||||
module.exports = function ExportTreeVisitor(ParseTreeVisitor, log) {
|
||||
|
||||
function ExportTreeVisitorImpl() {
|
||||
ParseTreeVisitor.call(this);
|
||||
}
|
||||
ExportTreeVisitorImpl.prototype = {
|
||||
|
||||
__proto__: ParseTreeVisitor.prototype,
|
||||
|
||||
visitExportDeclaration: function(tree) {
|
||||
// We are entering an export declaration - create an object to track it
|
||||
this.currentExport = {
|
||||
comment: tree.commentBefore,
|
||||
location: tree.location
|
||||
};
|
||||
log.silly('enter', tree.type, tree.commentBefore ? 'has comment' : '');
|
||||
ParseTreeVisitor.prototype.visitExportDeclaration.call(this, tree);
|
||||
log.silly('exit', this.currentExport);
|
||||
|
||||
if(this.currentExport) {
|
||||
// We are exiting the export declaration - store the export object
|
||||
this.exports.push(this.currentExport);
|
||||
}
|
||||
this.currentExport = null;
|
||||
},
|
||||
|
||||
visitVariableDeclaration: function(tree) {
|
||||
if ( this.currentExport ) {
|
||||
this.updateExport(tree);
|
||||
this.currentExport.docType = 'var';
|
||||
this.currentExport.name = tree.lvalue.identifierToken.value;
|
||||
this.currentExport.variableDeclaration = tree;
|
||||
}
|
||||
},
|
||||
|
||||
visitFunctionDeclaration: function(tree) {
|
||||
if ( this.currentExport ) {
|
||||
this.updateExport(tree);
|
||||
this.currentExport.name = tree.name.identifierToken.value;
|
||||
this.currentExport.functionKind = tree.functionKind;
|
||||
this.currentExport.parameters = tree.parameterList.parameters;
|
||||
this.currentExport.typeAnnotation = tree.typeAnnotation;
|
||||
this.currentExport.annotations = tree.annotations;
|
||||
this.currentExport.docType = 'function';
|
||||
|
||||
log.silly(tree.type, tree.commentBefore ? 'has comment' : '');
|
||||
}
|
||||
},
|
||||
visitClassDeclaration: function(tree) {
|
||||
if ( this.currentExport ) {
|
||||
this.updateExport(tree);
|
||||
this.currentExport.name = tree.name.identifierToken.value;
|
||||
this.currentExport.superClass = tree.superClass;
|
||||
this.currentExport.annotations = tree.annotations;
|
||||
this.currentExport.elements = tree.elements;
|
||||
this.currentExport.docType = 'class';
|
||||
}
|
||||
},
|
||||
visitAsyncFunctionDeclaration: function(tree) {
|
||||
if ( this.currentExport ) {
|
||||
this.updateExport(tree);
|
||||
}
|
||||
},
|
||||
|
||||
visitExportDefault: function(tree) {
|
||||
if ( this.currentExport ) {
|
||||
this.updateExport(tree);
|
||||
this.currentExport.name = 'DEFAULT';
|
||||
this.currentExport.defaultExport = tree;
|
||||
// Default exports are either classes, functions or expressions
|
||||
// So we let the super class continue down...
|
||||
ParseTreeVisitor.prototype.visitExportDefault.call(this, tree);
|
||||
}
|
||||
},
|
||||
|
||||
visitNamedExport: function(tree) {
|
||||
this.currentExport = null;
|
||||
// if ( this.currentExport ) {
|
||||
// this.updateExport(tree);
|
||||
|
||||
// this.currentExport.namedExport = tree;
|
||||
// this.currentExport.name = 'NAMED_EXPORT';
|
||||
// // TODO: work out this bit!!
|
||||
// // We need to cope with any export specifiers in the named export
|
||||
// }
|
||||
},
|
||||
|
||||
// TODO - if the export is an expression, find the thing that is being
|
||||
// exported and use it and its comments for docs
|
||||
|
||||
updateExport: function(tree) {
|
||||
this.currentExport.comment = this.currentExport.comment || tree.commentBefore;
|
||||
this.currentExport.docType = tree.type;
|
||||
},
|
||||
|
||||
visit: function(tree) {
|
||||
this.exports = [];
|
||||
ParseTreeVisitor.prototype.visit.call(this, tree);
|
||||
}
|
||||
};
|
||||
|
||||
return ExportTreeVisitorImpl;
|
||||
};
|
@ -1,6 +0,0 @@
|
||||
var traceur = require('traceur/src/node/traceur.js');
|
||||
|
||||
module.exports = function ParseTreeVisitor() {
|
||||
console.log(System.map.traceur);
|
||||
return System.get(System.map.traceur + '/src/syntax/ParseTreeVisitor.js').ParseTreeVisitor;
|
||||
};
|
@ -1,5 +0,0 @@
|
||||
var traceur = require('traceur/src/node/traceur.js');
|
||||
|
||||
module.exports = function SourceFile() {
|
||||
return System.get(System.map.traceur + '/src/syntax/SourceFile.js').SourceFile;
|
||||
};
|
@ -1,3 +0,0 @@
|
||||
module.exports = function TraceurParser() {
|
||||
return System.get('transpiler/src/parser').Parser;
|
||||
};
|
@ -1,74 +0,0 @@
|
||||
var file2modulename = require('../../../tools/build/file2modulename');
|
||||
/**
|
||||
* Wrapper around traceur that can parse the contents of a file
|
||||
*/
|
||||
module.exports = function atParser(AttachCommentTreeVisitor, SourceFile, TraceurParser, traceurOptions, log) {
|
||||
|
||||
var service = {
|
||||
/**
|
||||
* The options to pass to traceur
|
||||
*/
|
||||
traceurOptions: {
|
||||
annotations: true, // parse annotations
|
||||
types: true, // parse types
|
||||
memberVariables: true, // parse class fields
|
||||
commentCallback: true // handle comments
|
||||
},
|
||||
|
||||
/**
|
||||
* Parse a module AST from the contents of a file.
|
||||
* @param {Object} fileInfo information about the file to parse
|
||||
* @return { { moduleTree: Object, comments: Array } } An object containing the parsed module
|
||||
* AST and an array of all the comments found in the file
|
||||
*/
|
||||
parseModule: parseModule
|
||||
};
|
||||
|
||||
return service;
|
||||
|
||||
|
||||
// Parse the contents of the file using traceur
|
||||
function parseModule(fileInfo) {
|
||||
|
||||
var moduleName = file2modulename(fileInfo.relativePath);
|
||||
var sourceFile = new SourceFile(moduleName, fileInfo.content);
|
||||
var comments = [];
|
||||
var moduleTree;
|
||||
var parser = new TraceurParser(sourceFile);
|
||||
|
||||
// Configure the parser
|
||||
parser.handleComment = function(range) {
|
||||
comments.push({ range: range });
|
||||
};
|
||||
traceurOptions.setFromObject(service.traceurOptions);
|
||||
|
||||
try {
|
||||
// Parse the file as a module, attaching the comments
|
||||
moduleTree = parser.parseModule();
|
||||
attachComments(moduleTree, comments);
|
||||
} catch(ex) {
|
||||
// HACK: sometime traceur crashes for various reasons including
|
||||
// Not Yet Implemented (NYI)!
|
||||
log.error(ex.stack);
|
||||
moduleTree = {};
|
||||
}
|
||||
log.debug(moduleName);
|
||||
moduleTree.moduleName = moduleName;
|
||||
|
||||
// We return the module AST but also a collection of all the comments
|
||||
// since it can be helpful to iterate through them without having to
|
||||
// traverse the AST again
|
||||
return {
|
||||
moduleTree: moduleTree,
|
||||
comments: comments
|
||||
};
|
||||
}
|
||||
|
||||
// attach the comments to their nearest code tree
|
||||
function attachComments(tree, comments) {
|
||||
|
||||
var visitor = new AttachCommentTreeVisitor();
|
||||
// Visit every node of the tree using our custom method
|
||||
visitor.visit(tree, comments);
|
||||
}
|
||||
};
|
@ -1,80 +0,0 @@
|
||||
var mockPackage = require('../mocks/mockPackage');
|
||||
var Dgeni = require('dgeni');
|
||||
|
||||
describe('atParser service', function() {
|
||||
|
||||
var dgeni, injector, parser;
|
||||
|
||||
var fileContent =
|
||||
'import {CONST} from "facade/lang";\n' +
|
||||
'\n' +
|
||||
'/**\n' +
|
||||
'* A parameter annotation that creates a synchronous eager dependency.\n' +
|
||||
'*\n' +
|
||||
'* class AComponent {\n' +
|
||||
'* constructor(@Inject("aServiceToken") aService) {}\n' +
|
||||
'* }\n' +
|
||||
'*\n' +
|
||||
'*/\n' +
|
||||
'export class Inject {\n' +
|
||||
'token;\n' +
|
||||
'@CONST()\n' +
|
||||
'constructor({a,b}:{a:string, b:string}) {\n' +
|
||||
'this.token = a;\n' +
|
||||
'}\n' +
|
||||
'}';
|
||||
|
||||
beforeEach(function() {
|
||||
dgeni = new Dgeni([mockPackage()]);
|
||||
injector = dgeni.configureInjector();
|
||||
parser = injector.get('atParser');
|
||||
});
|
||||
|
||||
it('should extract the comments from the file', function() {
|
||||
var result = parser.parseModule({
|
||||
content: fileContent,
|
||||
relativePath: 'di/src/annotations.js'
|
||||
});
|
||||
|
||||
expect(result.comments[0].range.toString()).toEqual(
|
||||
'/**\n' +
|
||||
'* A parameter annotation that creates a synchronous eager dependency.\n' +
|
||||
'*\n' +
|
||||
'* class AComponent {\n' +
|
||||
'* constructor(@Inject("aServiceToken") aService) {}\n' +
|
||||
'* }\n' +
|
||||
'*\n' +
|
||||
'*/'
|
||||
);
|
||||
});
|
||||
|
||||
it('should extract a module AST from the file', function() {
|
||||
var result = parser.parseModule({
|
||||
content: fileContent,
|
||||
relativePath: 'di/src/annotations.js'
|
||||
});
|
||||
|
||||
expect(result.moduleTree.moduleName).toEqual('di/src/annotations');
|
||||
expect(result.moduleTree.scriptItemList[0].type).toEqual('IMPORT_DECLARATION');
|
||||
|
||||
expect(result.moduleTree.scriptItemList[1].type).toEqual('EXPORT_DECLARATION');
|
||||
});
|
||||
|
||||
it('should attach comments to their following AST', function() {
|
||||
var result = parser.parseModule({
|
||||
content: fileContent,
|
||||
relativePath: 'di/src/annotations.js'
|
||||
});
|
||||
|
||||
expect(result.moduleTree.scriptItemList[1].commentBefore.range.toString()).toEqual(
|
||||
'/**\n' +
|
||||
'* A parameter annotation that creates a synchronous eager dependency.\n' +
|
||||
'*\n' +
|
||||
'* class AComponent {\n' +
|
||||
'* constructor(@Inject("aServiceToken") aService) {}\n' +
|
||||
'* }\n' +
|
||||
'*\n' +
|
||||
'*/'
|
||||
);
|
||||
});
|
||||
});
|
@ -1,28 +0,0 @@
|
||||
var LEADING_STAR = /^[^\S\r\n]*\*[^\S\n\r]?/gm;
|
||||
|
||||
/**
|
||||
* Extact comment info from a comment object
|
||||
* @param {Object} comment object to process
|
||||
* @return { {startingLine, endingLine, content, codeTree}= } a comment info object
|
||||
* or undefined if the comment is not a jsdoc style comment
|
||||
*/
|
||||
module.exports = function getJSDocComment() {
|
||||
return function(comment) {
|
||||
|
||||
var commentInfo;
|
||||
|
||||
// we need to check for `/**` at the start of the comment to find all the jsdoc style comments
|
||||
comment.range.toString().replace(/^\/\*\*([\w\W]*)\*\/$/g, function(match, commentBody) {
|
||||
commentBody = commentBody.replace(LEADING_STAR, '').trim();
|
||||
|
||||
commentInfo = {
|
||||
startingLine: comment.range.start.line,
|
||||
endingLine: comment.range.end.line,
|
||||
content: commentBody,
|
||||
codeTree: comment.treeAfter
|
||||
};
|
||||
});
|
||||
|
||||
return commentInfo;
|
||||
};
|
||||
};
|
@ -1,67 +0,0 @@
|
||||
var mockPackage = require('../mocks/mockPackage');
|
||||
var Dgeni = require('dgeni');
|
||||
|
||||
describe('getJSDocComment service', function() {
|
||||
|
||||
var dgeni, injector, getJSDocComment;
|
||||
|
||||
function createComment(commentString, start, end, codeTree) {
|
||||
return {
|
||||
range: {
|
||||
toString: function() { return commentString; },
|
||||
start: { line: start },
|
||||
end: { line: end },
|
||||
},
|
||||
treeAfter: codeTree
|
||||
};
|
||||
}
|
||||
|
||||
beforeEach(function() {
|
||||
dgeni = new Dgeni([mockPackage()]);
|
||||
injector = dgeni.configureInjector();
|
||||
getJSDocComment = injector.get('getJSDocComment');
|
||||
});
|
||||
|
||||
it('should only return an object if the comment starts with /** and ends with */', function() {
|
||||
var result = getJSDocComment(createComment('/** this is a jsdoc comment */'));
|
||||
expect(result).toBeDefined();
|
||||
|
||||
result = getJSDocComment(createComment('/* this is a normal comment */'));
|
||||
expect(result).toBeUndefined();
|
||||
|
||||
result = getJSDocComment(createComment('this is not a valid comment */'));
|
||||
expect(result).toBeUndefined();
|
||||
|
||||
result = getJSDocComment(createComment('nor is this'));
|
||||
expect(result).toBeUndefined();
|
||||
|
||||
result = getJSDocComment(createComment('/* or even this'));
|
||||
expect(result).toBeUndefined();
|
||||
|
||||
result = getJSDocComment(createComment('/** and this'));
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
|
||||
|
||||
it('should return a result that contains info about the comment', function() {
|
||||
var codeTree = {};
|
||||
var result = getJSDocComment(createComment('/** this is a comment */', 10, 20, codeTree));
|
||||
expect(result.startingLine).toEqual(10);
|
||||
expect(result.endingLine).toEqual(20);
|
||||
expect(result.codeTree).toBe(codeTree);
|
||||
});
|
||||
|
||||
it('should strip off leading stars from each line', function() {
|
||||
var result = getJSDocComment(createComment(
|
||||
'/** this is a jsdoc comment */\n' +
|
||||
' *\n' +
|
||||
' * some content\n' +
|
||||
' */'
|
||||
));
|
||||
expect(result.content).toEqual(
|
||||
'this is a jsdoc comment */\n' +
|
||||
'\n' +
|
||||
'some content'
|
||||
);
|
||||
});
|
||||
});
|
@ -1,3 +0,0 @@
|
||||
module.exports = function traceurOptions() {
|
||||
return System.get(System.map.traceur + '/src/Options.js').options;
|
||||
};
|
74
docs/dgeni-package/services/tsParser.js
Normal file
74
docs/dgeni-package/services/tsParser.js
Normal file
@ -0,0 +1,74 @@
|
||||
var ts = require('typescript');
|
||||
var path = require('canonical-path');
|
||||
|
||||
module.exports = function tsParser(createCompilerHost, log) {
|
||||
|
||||
return {
|
||||
|
||||
// These are the extension that we should consider when trying to load a module
|
||||
// During migration from Traceur, there is a mix of `.ts`, `.es6` and `.js` (atScript)
|
||||
// files in the project and the TypeScript compiler only looks for `.ts` files when trying
|
||||
// to load imports.
|
||||
extensions: ['.ts', '.js', '.es6'],
|
||||
|
||||
// The options for the TS compiler
|
||||
options: {
|
||||
allowNonTsExtensions: true,
|
||||
charset: 'utf8'
|
||||
},
|
||||
|
||||
parse: function(fileNames, baseDir) {
|
||||
|
||||
// "Compile" a program from the given module filenames, to get hold of a
|
||||
// typeChecker that can be used to interrogate the modules, exports and so on.
|
||||
var host = createCompilerHost(this.options, baseDir, this.extensions);
|
||||
var program = ts.createProgram(fileNames, this.options, host);
|
||||
var typeChecker = program.getTypeChecker();
|
||||
|
||||
// Create an array of module symbols for each file we were given
|
||||
var moduleSymbols = [];
|
||||
fileNames.forEach(function(fileName) {
|
||||
var sourceFile = program.getSourceFile(fileName);
|
||||
|
||||
if (!sourceFile) {
|
||||
throw new Error('Invalid source file: ' + fileName);
|
||||
} else if (!sourceFile.symbol) {
|
||||
// Some files contain only a comment and no actual module code
|
||||
log.warn('No module code found in ' + fileName);
|
||||
} else {
|
||||
moduleSymbols.push(sourceFile.symbol);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
moduleSymbols.forEach(function(tsModule) {
|
||||
|
||||
// The type checker has a nice helper function that returns an array of Symbols
|
||||
// representing the exports for a given module
|
||||
tsModule.exportArray = typeChecker.getExportsOfModule(tsModule);
|
||||
|
||||
// Although 'star' imports (e.g. `export * from 'some/module';) get resolved automatically
|
||||
// by the compiler/binder, it seems that explicit imports (e.g. `export {SomeClass} from 'some/module'`)
|
||||
// do not so we have to do a little work.
|
||||
tsModule.exportArray.forEach(function(moduleExport) {
|
||||
if (moduleExport.flags & ts.SymbolFlags.Alias) {
|
||||
// To maintain the alias information (particularly the alias name)
|
||||
// we just attach the original "resolved" symbol to the alias symbol
|
||||
moduleExport.resolvedSymbol = typeChecker.getAliasedSymbol(moduleExport);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
moduleSymbols.typeChecker = typeChecker;
|
||||
|
||||
return {
|
||||
moduleSymbols: moduleSymbols,
|
||||
typeChecker: typeChecker,
|
||||
program: program,
|
||||
host: host
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
};
|
21
docs/dgeni-package/services/tsParser.spec.js
Normal file
21
docs/dgeni-package/services/tsParser.spec.js
Normal file
@ -0,0 +1,21 @@
|
||||
var mockPackage = require('../mocks/mockPackage');
|
||||
var Dgeni = require('dgeni');
|
||||
var path = require('canonical-path');
|
||||
|
||||
describe('tsParser', function() {
|
||||
var dgeni, injector, parser;
|
||||
|
||||
beforeEach(function() {
|
||||
dgeni = new Dgeni([mockPackage()]);
|
||||
injector = dgeni.configureInjector();
|
||||
parser = injector.get('tsParser');
|
||||
});
|
||||
|
||||
it("should parse a TS file", function() {
|
||||
var parseInfo = parser.parse(['testSrc.ts'], path.resolve(__dirname, '../mocks/'));
|
||||
var tsModules = parseInfo.moduleSymbols;
|
||||
expect(tsModules.length).toEqual(1);
|
||||
expect(tsModules[0].exportArray.length).toEqual(3);
|
||||
expect(tsModules[0].exportArray.map(function(i) { return i.name; })).toEqual(['MyClass', 'myFn', 'x']);
|
||||
});
|
||||
});
|
62
docs/dgeni-package/services/tsParser/createCompilerHost.js
Normal file
62
docs/dgeni-package/services/tsParser/createCompilerHost.js
Normal file
@ -0,0 +1,62 @@
|
||||
var ts = require('typescript');
|
||||
var fs = require('fs');
|
||||
var path = require('canonical-path');
|
||||
|
||||
// We need to provide our own version of CompilerHost because we want to set the
|
||||
// base directory and specify what extensions to consider when trying to load a source
|
||||
// file
|
||||
module.exports = function createCompilerHost(log) {
|
||||
|
||||
return function createCompilerHost(options, baseDir, extensions) {
|
||||
|
||||
return {
|
||||
getSourceFile: function(fileName, languageVersion, onError) {
|
||||
var text, resolvedPath, resolvedPathWithExt;
|
||||
|
||||
// Strip off the extension and resolve relative to the baseDir
|
||||
baseFilePath = fileName.replace(/\.[^.]+$/, '');
|
||||
resolvedPath = path.resolve(baseDir, baseFilePath);
|
||||
|
||||
// Iterate through each possible extension and return the first source file that is actually found
|
||||
for(var i=0; i<extensions.length; i++) {
|
||||
|
||||
// Try reading the content from files using each of the given extensions
|
||||
try {
|
||||
resolvedPathWithExt = resolvedPath + extensions[i];
|
||||
log.silly('getSourceFile:', resolvedPathWithExt);
|
||||
text = fs.readFileSync(resolvedPathWithExt, { encoding: options.charset });
|
||||
log.debug('found source file:', fileName, resolvedPathWithExt);
|
||||
return ts.createSourceFile(baseFilePath + extensions[i], text, languageVersion);
|
||||
}
|
||||
catch(e) {
|
||||
// Try again if the file simply did not exist, otherwise report the error as a warning
|
||||
if(e.code !== 'ENOENT') {
|
||||
if (onError) onError(e.message);
|
||||
log.warn('Error reading ' + resolvedPathWithExt + ' : ' + e.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
getDefaultLibFileName: function(options) {
|
||||
return path.resolve(path.dirname(ts.sys.getExecutingFilePath()), ts.getDefaultLibFileName(options));
|
||||
},
|
||||
writeFile: function(fileName, data, writeByteOrderMark, onError) {
|
||||
// no-op
|
||||
},
|
||||
getCurrentDirectory: function() {
|
||||
return baseDir;
|
||||
},
|
||||
useCaseSensitiveFileNames: function() {
|
||||
return ts.sys.useCaseSensitiveFileNames;
|
||||
},
|
||||
getCanonicalFileName: function(fileName) {
|
||||
// if underlying system can distinguish between two files whose names differs only in cases then file name already in canonical form.
|
||||
// otherwise use toLowerCase as a canonical form.
|
||||
return ts.sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
|
||||
},
|
||||
getNewLine: function() {
|
||||
return ts.sys.newLine;
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
@ -0,0 +1,80 @@
|
||||
var mockPackage = require('../../mocks/mockPackage');
|
||||
var Dgeni = require('dgeni');
|
||||
var path = require('canonical-path');
|
||||
var ts = require('typescript');
|
||||
|
||||
describe('createCompilerHost', function() {
|
||||
var dgeni, injector, options, host, baseDir, extensions;
|
||||
|
||||
beforeEach(function() {
|
||||
dgeni = new Dgeni([mockPackage()]);
|
||||
injector = dgeni.configureInjector();
|
||||
var createCompilerHost = injector.get('createCompilerHost');
|
||||
|
||||
options = { charset: 'utf8' };
|
||||
baseDir = path.resolve(__dirname, '../../mocks/');
|
||||
extensions = ['.ts', '.js'];
|
||||
|
||||
host = createCompilerHost(options, baseDir, extensions);
|
||||
});
|
||||
|
||||
describe('getSourceFile', function() {
|
||||
it('should return a SourceFile object for a given path, with fileName relative to baseDir', function() {
|
||||
var sourceFile = host.getSourceFile('testSrc.ts');
|
||||
expect(sourceFile.fileName).toEqual('testSrc.ts');
|
||||
expect(sourceFile.pos).toEqual(0);
|
||||
expect(sourceFile.text).toEqual(jasmine.any(String));
|
||||
});
|
||||
|
||||
it('should try each of the configured extensions and update the filename to the correct extension', function() {
|
||||
var sourceFile = host.getSourceFile('testSrc.js');
|
||||
expect(sourceFile.fileName).toEqual('testSrc.ts');
|
||||
|
||||
sourceFile = host.getSourceFile('mockPackage.ts');
|
||||
expect(sourceFile.fileName).toEqual('mockPackage.js');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('getDefaultLibFileName', function() {
|
||||
it('should return a path to the default library', function() {
|
||||
expect(host.getDefaultLibFileName(options)).toContain('typescript/bin/lib.d.ts');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('writeFile', function() {
|
||||
it('should do nothing', function() {
|
||||
host.writeFile();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('getCurrentDirectory', function() {
|
||||
it('should return the baseDir', function() {
|
||||
expect(host.getCurrentDirectory()).toEqual(baseDir);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('useCaseSensitiveFileNames', function() {
|
||||
it('should return true if the OS is case sensitive', function() {
|
||||
expect(host.useCaseSensitiveFileNames()).toBe(ts.sys.useCaseSensitiveFileNames);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('getCanonicalFileName', function() {
|
||||
it('should lower case the filename', function() {
|
||||
var expectedFilePath = host.useCaseSensitiveFileNames() ? 'SomeFile.ts' : 'somefile.ts';
|
||||
expect(host.getCanonicalFileName('SomeFile.ts')).toEqual(expectedFilePath);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('getNewLine', function() {
|
||||
it('should return the newline character for the OS', function() {
|
||||
expect(host.getNewLine()).toEqual(require('os').EOL);
|
||||
});
|
||||
});
|
||||
});
|
49
docs/dgeni-package/services/tsParser/getContent.js
Normal file
49
docs/dgeni-package/services/tsParser/getContent.js
Normal file
@ -0,0 +1,49 @@
|
||||
var ts = require('typescript');
|
||||
var LEADING_STAR = /^[^\S\r\n]*\*[^\S\n\r]?/gm;
|
||||
|
||||
module.exports = function getContent() {
|
||||
return function(symbol) {
|
||||
|
||||
var content = "";
|
||||
|
||||
if (!symbol.declarations) return content;
|
||||
|
||||
symbol.declarations.forEach(function(declaration) {
|
||||
|
||||
// If this is left side of dotted module declaration, there is no doc comment associated with this declaration
|
||||
if (declaration.kind === ts.SyntaxKind.ModuleDeclaration && declaration.body.kind === ts.SyntaxKind.ModuleDeclaration) {
|
||||
return content;
|
||||
}
|
||||
|
||||
// If this is dotted module name, get the doc comments from the parent
|
||||
while (declaration.kind === ts.SyntaxKind.ModuleDeclaration && declaration.parent.kind === ts.SyntaxKind.ModuleDeclaration) {
|
||||
declaration = declaration.parent;
|
||||
}
|
||||
|
||||
// If this is a variable declaration then we get the doc comments from the grand parent
|
||||
if (declaration.kind === ts.SyntaxKind.VariableDeclaration) {
|
||||
declaration = declaration.parent.parent;
|
||||
}
|
||||
|
||||
// Get the source file of this declaration
|
||||
var sourceFile = ts.getSourceFileOfNode(declaration);
|
||||
var commentRanges = ts.getJsDocComments(declaration, sourceFile);
|
||||
|
||||
if (commentRanges) {
|
||||
commentRanges.forEach(function(commentRange) {
|
||||
content += sourceFile.text
|
||||
.substring(commentRange.pos+ '/**'.length, commentRange.end - '*/'.length)
|
||||
.replace(LEADING_STAR, '')
|
||||
.trim();
|
||||
if (commentRange.hasTrailingNewLine) {
|
||||
content += '\n';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
content += '\n';
|
||||
});
|
||||
|
||||
return content;
|
||||
};
|
||||
};
|
46
docs/dgeni-package/services/tsParser/getExportDocType.js
Normal file
46
docs/dgeni-package/services/tsParser/getExportDocType.js
Normal file
@ -0,0 +1,46 @@
|
||||
var ts = require('typescript');
|
||||
|
||||
module.exports = function getExportDocType() {
|
||||
|
||||
return function(symbol) {
|
||||
if(symbol.flags & ts.SymbolFlags.FunctionScopedVariable) {
|
||||
return 'var';
|
||||
}
|
||||
if(symbol.flags & ts.SymbolFlags.BlockScopedVariable) {
|
||||
return getBlockScopedVariableDocType(symbol);
|
||||
}
|
||||
if(symbol.flags & ts.SymbolFlags.Function) {
|
||||
return 'function';
|
||||
}
|
||||
if(symbol.flags & ts.SymbolFlags.Class) {
|
||||
return 'class';
|
||||
}
|
||||
if(symbol.flags & ts.SymbolFlags.Interface) {
|
||||
return 'interface';
|
||||
}
|
||||
if(symbol.flags & ts.SymbolFlags.ConstEnum) {
|
||||
return 'enum';
|
||||
}
|
||||
if(symbol.flags & ts.SymbolFlags.RegularEnum) {
|
||||
return 'enum';
|
||||
}
|
||||
if(symbol.flags & ts.SymbolFlags.Property) {
|
||||
return 'module-property';
|
||||
}
|
||||
|
||||
log.warn('Unknown symbol type', symbol.name, symbol.flags, symbol.target);
|
||||
return 'unknown';
|
||||
}
|
||||
|
||||
function getBlockScopedVariableDocType(symbol) {
|
||||
|
||||
var node = symbol.valueDeclaration;
|
||||
while(node) {
|
||||
if ( node.flags & 0x2000 /* const */) {
|
||||
return 'const';
|
||||
}
|
||||
node = node.parent;
|
||||
}
|
||||
return 'let';
|
||||
}
|
||||
};
|
20
docs/dgeni-package/services/tsParser/getFileInfo.js
Normal file
20
docs/dgeni-package/services/tsParser/getFileInfo.js
Normal file
@ -0,0 +1,20 @@
|
||||
var path = require('canonical-path');
|
||||
var ts = require('typescript');
|
||||
|
||||
module.exports = function getFileInfo(log) {
|
||||
|
||||
return function (symbol, basePath) {
|
||||
var fileName = ts.getSourceFileOfNode(symbol.declarations[0]).fileName;
|
||||
|
||||
var file = path.resolve(basePath, fileName);
|
||||
var fileInfo = {
|
||||
filePath: file,
|
||||
baseName: path.basename(file, path.extname(file)),
|
||||
extension: path.extname(file).replace(/^\./, ''),
|
||||
basePath: basePath,
|
||||
relativePath: fileName,
|
||||
projectRelativePath: fileName
|
||||
};
|
||||
return fileInfo;
|
||||
};
|
||||
};
|
4
docs/dgeni-package/tag-defs/exportedAs.js
Normal file
4
docs/dgeni-package/tag-defs/exportedAs.js
Normal file
@ -0,0 +1,4 @@
|
||||
module.exports = {
|
||||
name: 'exportedAs',
|
||||
multi: true
|
||||
};
|
4
docs/dgeni-package/tag-defs/private.js
Normal file
4
docs/dgeni-package/tag-defs/private.js
Normal file
@ -0,0 +1,4 @@
|
||||
module.exports = {
|
||||
name: 'private',
|
||||
transforms: function(doc, tag) { return true; }
|
||||
};
|
4
docs/dgeni-package/tag-defs/public.js
Normal file
4
docs/dgeni-package/tag-defs/public.js
Normal file
@ -0,0 +1,4 @@
|
||||
module.exports = {
|
||||
name: 'public',
|
||||
transforms: function(doc, tag) { return true; }
|
||||
};
|
@ -1,14 +1,35 @@
|
||||
{% extends 'layout/base.template.html' %}
|
||||
{% include "lib/paramList.html" -%}
|
||||
{% include "lib/githubLinks.html" -%}
|
||||
{% extends 'layout/base.template.html' -%}
|
||||
|
||||
{% block body %}
|
||||
<h1>{$ doc.name $} <span class="type">class</span></h1>
|
||||
<p class="module">exported from <a href="/{$ doc.moduleDoc.path $}">{$ doc.moduleDoc.id $}</a></p>
|
||||
<h1 class="class export">{$ doc.name $} <span class="type">{$ doc.docType $}</span></h1>
|
||||
<p class="module">exported from {@link {$ doc.moduleDoc.id $} {$doc.moduleDoc.id $} }<br/>
|
||||
defined in {$ githubViewLink(doc) $}
|
||||
</p>
|
||||
<p>{$ doc.description | marked $}</p>
|
||||
|
||||
{%- if doc.constructorDoc or doc.members.length -%}
|
||||
<h2>Members</h2>
|
||||
{% for member in doc.members %}
|
||||
<h3>{$ member.name $}</h3>
|
||||
<p>{$ member.description | marked $}</p>
|
||||
{% endfor %}
|
||||
|
||||
{%- if doc.constructorDoc %}
|
||||
<section class="member constructor">
|
||||
<h1 id="constructor" class="name">{$ doc.constructorDoc.name $}{$ paramList(doc.constructorDoc.params) $}</h1>
|
||||
{% marked %}
|
||||
{$ doc.constructorDoc.description $}
|
||||
{% endmarked %}
|
||||
</section>
|
||||
{% endif -%}
|
||||
|
||||
{%- for member in doc.members %}{% if not member.private %}
|
||||
<section class="member">
|
||||
<h1 id="{$ member.name $}" class="name">{$ member.name $}{$ paramList(member.params) $}</h1>
|
||||
{% marked %}
|
||||
{$ member.description $}
|
||||
{% endmarked %}
|
||||
</section>
|
||||
|
||||
{% endif %}{% endfor %}
|
||||
{%- endif -%}
|
||||
|
||||
{% endblock %}
|
1
docs/dgeni-package/templates/const.template.html
Normal file
1
docs/dgeni-package/templates/const.template.html
Normal file
@ -0,0 +1 @@
|
||||
{% extends 'var.template.html' -%}
|
11
docs/dgeni-package/templates/function.template.html
Normal file
11
docs/dgeni-package/templates/function.template.html
Normal file
@ -0,0 +1,11 @@
|
||||
{% include "lib/paramList.html" -%}
|
||||
{% include "lib/githubLinks.html" -%}
|
||||
{% extends 'layout/base.template.html' -%}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="function export">{$ doc.name $}{$ paramList(doc.parameters) $}</h1>
|
||||
<p class="module">exported from {@link {$ doc.moduleDoc.id $} {$doc.moduleDoc.id $} }<br/>
|
||||
defined in {$ githubViewLink(doc) $}</p>
|
||||
<p>{$ doc.description | marked $}</p>
|
||||
|
||||
{% endblock %}
|
1
docs/dgeni-package/templates/interface.template.html
Normal file
1
docs/dgeni-package/templates/interface.template.html
Normal file
@ -0,0 +1 @@
|
||||
{% extends 'class.template.html' -%}
|
3
docs/dgeni-package/templates/lib/githubLinks.html
Normal file
3
docs/dgeni-package/templates/lib/githubLinks.html
Normal file
@ -0,0 +1,3 @@
|
||||
{% macro githubViewLink(doc) -%}
|
||||
<a href="https://github.com/{$ versionInfo.gitRepoInfo.owner $}/{$ versionInfo.gitRepoInfo.repo $}/tree/{$ versionInfo.currentVersion.isSnapshot and 'master' or versionInfo.currentVersion.raw $}/modules/{$ doc.fileInfo.relativePath $}#L{$ doc.location.start.line+1 $}-L{$ doc.location.end.line+1 $}">
|
||||
{%- endmacro -%}
|
7
docs/dgeni-package/templates/lib/paramList.html
Normal file
7
docs/dgeni-package/templates/lib/paramList.html
Normal file
@ -0,0 +1,7 @@
|
||||
{% macro paramList(params) -%}
|
||||
{%- if params -%}<span class="params">(
|
||||
{%- for param in params -%}
|
||||
<span class="param">{$ param | escape $}{% if not loop.last %}, {% endif %}</span>
|
||||
{%- endfor %})</span>
|
||||
{%- endif %}
|
||||
{%- endmacro -%}
|
@ -1,15 +1,18 @@
|
||||
{% include "lib/githubLinks.html" -%}
|
||||
{% extends 'layout/base.template.html' %}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="id">{$ doc.id $} <span class="type">module</span></h1>
|
||||
|
||||
<p>defined in {$ githubViewLink(doc) $}</p>
|
||||
<p>{$ doc.description | marked $}</p>
|
||||
|
||||
{% if doc.exports.length %}
|
||||
<h2>Exports</h2>
|
||||
<ul>
|
||||
{%- for exportDoc in doc.exports %}
|
||||
<li><a href="/{$ exportDoc.path $}">{$ exportDoc.name $} {$ exportDoc.docType $}</a></li>
|
||||
{% if not exportDoc.private -%}
|
||||
<li><a href="{$ exportDoc.path $}"><strong>{$ exportDoc.name $}</strong> {$ exportDoc.docType $}</a></li>
|
||||
{%- endif %}
|
||||
{%- endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
43
docs/dgeni-package/templates/overview-dump.template.html
Normal file
43
docs/dgeni-package/templates/overview-dump.template.html
Normal file
@ -0,0 +1,43 @@
|
||||
{% include "lib/paramList.html" -%}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
<style>
|
||||
h2 {
|
||||
padding-left: 20px;
|
||||
}
|
||||
h3 {
|
||||
padding-left: 50px;
|
||||
}
|
||||
h4 {
|
||||
padding-left: 60px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
<h1>Modules</h1>
|
||||
|
||||
{% for module in doc.modules %}
|
||||
|
||||
<h2>{$ module.id $}
|
||||
{%- if module.public %} (public){% endif %}</h2>
|
||||
|
||||
{% for export in module.exports %}
|
||||
<h3>{$ export.name $}</h3>
|
||||
|
||||
{%- if export.constructorDoc %}
|
||||
<h4>{$ doc.constructorDoc.name $}{$ paramList(doc.constructorDoc.params) $}</h4>
|
||||
{% endif -%}
|
||||
{%- for member in export.members %}
|
||||
<h4>{$ member.name $}{$ paramList(member.params) $}</h4>
|
||||
{% endfor %}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
</body>
|
||||
</html>
|
46
docs/dgeni-package/templates/type-definition.template.html
Normal file
46
docs/dgeni-package/templates/type-definition.template.html
Normal file
@ -0,0 +1,46 @@
|
||||
{%- macro commentBlock(doc, level) -%}
|
||||
{%- if doc.content | trim %}
|
||||
|
||||
{% if level > 1 %}{$ '/**' | indent(level-1, true) | replace(r/\n$/, "") $}{% else %}/**{% endif %}
|
||||
{$ doc.content | trim | replace(r/^/gm, "* ") | indent(level, true) | replace(r/\n$/, "") $}
|
||||
{$ '*/' | indent(level, true) | replace(r/\n$/, "") $}{% endif -%}
|
||||
{%- endmacro -%}
|
||||
|
||||
// Type definitions for Angular v2.0.0-alpha.22
|
||||
// Project: http://angular.io/
|
||||
// Definitions by: angular team <https://github.com/angular/>
|
||||
// Definitions: https://github.com/borisyankov/DefinitelyTyped
|
||||
|
||||
// ***********************************************************
|
||||
// This file is generated by the Angular build process.
|
||||
// Please do not create manual edits or send pull requests
|
||||
// modifying this file.
|
||||
// ***********************************************************
|
||||
{% for module in doc.modules %}
|
||||
{$ commentBlock(module, 1) $}
|
||||
declare module "{$ module.id $}" {
|
||||
|
||||
{%- for export in module.exports -%}
|
||||
{%- if export.content -%}
|
||||
{$ commentBlock(export, 3) $}
|
||||
{%- endif %}
|
||||
{$ export.docType $} {$ export.name $}
|
||||
{%- if export.docType == 'class' or export.docType == 'interface' %} {
|
||||
{%- for member in export.members -%}
|
||||
{$ commentBlock(member, 5) $}
|
||||
{$ member.name $}
|
||||
{%- if member.parameters %}({% for param in member.parameters %}{$ param $}{% if not loop.last %}, {% endif %}{% endfor %}){%- endif %}
|
||||
{%- if member.returnType %}: {$ member.returnType $}{% endif -%}
|
||||
;
|
||||
{%- endfor %}
|
||||
}
|
||||
{%- else -%}
|
||||
{% if export.parameters %}({% for param in export.parameters %}{$ param $}{% if not loop.last %}, {% endif %}{% endfor %}){%- endif %}
|
||||
{%- if export.returnType %} : {$ export.returnType $} {% endif -%}
|
||||
;
|
||||
{%- endif %}
|
||||
{% endfor %}
|
||||
}
|
||||
|
||||
{% endfor %}
|
||||
|
10
docs/dgeni-package/templates/var.template.html
Normal file
10
docs/dgeni-package/templates/var.template.html
Normal file
@ -0,0 +1,10 @@
|
||||
{% include "lib/githubLinks.html" -%}
|
||||
{% extends 'layout/base.template.html' %}
|
||||
|
||||
{% block body %}
|
||||
<h1>{$ doc.name $} <span class="type">variable</span></h1>
|
||||
<p class="module">exported from {@link {$ doc.moduleDoc.id $} {$doc.moduleDoc.id $} }<br/>
|
||||
defined in {$ githubViewLink(doc) $}</p>
|
||||
<p>{$ doc.description | marked $}</p>
|
||||
|
||||
{% endblock %}
|
181
docs/dgeni-package/versionInfo.js
Normal file
181
docs/dgeni-package/versionInfo.js
Normal file
@ -0,0 +1,181 @@
|
||||
'use strict';
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var shell = require('shelljs');
|
||||
var semver = require('semver');
|
||||
var _ = require('lodash');
|
||||
|
||||
var currentPackage, previousVersions, gitRepoInfo;
|
||||
|
||||
|
||||
/**
|
||||
* Load information about this project from the package.json
|
||||
* @return {Object} The package information
|
||||
*/
|
||||
var getPackage = function() {
|
||||
// Search up the folder hierarchy for the first package.json
|
||||
var packageFolder = path.resolve('.');
|
||||
while (!fs.existsSync(path.join(packageFolder, 'package.json'))) {
|
||||
var parent = path.dirname(packageFolder);
|
||||
if (parent === packageFolder) { break; }
|
||||
packageFolder = parent;
|
||||
}
|
||||
return JSON.parse(fs.readFileSync(path.join(packageFolder,'package.json'), 'UTF-8'));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Parse the github URL for useful information
|
||||
* @return {Object} An object containing the github owner and repository name
|
||||
*/
|
||||
var getGitRepoInfo = function() {
|
||||
var GITURL_REGEX = /^https:\/\/github.com\/([^\/]+)\/(.+).git$/;
|
||||
var match = GITURL_REGEX.exec(currentPackage.repository.url);
|
||||
var git = {
|
||||
owner: match[1],
|
||||
repo: match[2]
|
||||
};
|
||||
return git;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Extract the code name from the tagged commit's message - it should contain the text of the form:
|
||||
* "codename(some-code-name)"
|
||||
* @param {String} tagName Name of the tag to look in for the codename
|
||||
* @return {String} The codename if found, otherwise null/undefined
|
||||
*/
|
||||
var getCodeName = function(tagName) {
|
||||
var gitCatOutput = shell.exec('git cat-file -p ' + tagName, {silent:true}).output;
|
||||
var tagMessage = gitCatOutput.match(/^.*codename.*$/mg)[0];
|
||||
var codeName = tagMessage && tagMessage.match(/codename\((.*)\)/)[1];
|
||||
if (!codeName) {
|
||||
throw new Error("Could not extract release code name. The message of tag " + tagName +
|
||||
" must match '*codename(some release name)*'");
|
||||
}
|
||||
return codeName;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Compute a build segment for the version, from the Jenkins build number and current commit SHA
|
||||
* @return {String} The build segment of the version
|
||||
*/
|
||||
function getBuild() {
|
||||
var hash = shell.exec('git rev-parse --short HEAD', {silent: true}).output.replace('\n', '');
|
||||
return 'sha.' + hash;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If the current commit is tagged as a version get that version
|
||||
* @return {SemVer} The version or null
|
||||
*/
|
||||
var getTaggedVersion = function() {
|
||||
var gitTagResult = shell.exec('git describe --exact-match', {silent:true});
|
||||
|
||||
if (gitTagResult.code === 0) {
|
||||
var tag = gitTagResult.output.trim();
|
||||
var version = semver.parse(tag);
|
||||
|
||||
if (version && semver.satisfies(version, currentPackage.version)) {
|
||||
version.codeName = getCodeName(tag);
|
||||
version.full = version.version;
|
||||
version.branch = 'v' + currentPackage.branchPattern.replace('*', 'x');
|
||||
return version;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a collection of all the previous versions sorted by semantic version
|
||||
* @return {Array.<SemVer>} The collection of previous versions
|
||||
*/
|
||||
var getPreviousVersions = function() {
|
||||
// always use the remote tags as the local clone might
|
||||
// not contain all commits when cloned with git clone --depth=...
|
||||
// Needed e.g. for Travis
|
||||
var repo_url = currentPackage.repository.url;
|
||||
var tagResults = shell.exec('git ls-remote --tags ' + repo_url,
|
||||
{silent: true});
|
||||
if (tagResults.code === 0) {
|
||||
return _(tagResults.output.match(/v[0-9].*[0-9]$/mg))
|
||||
.map(function(tag) {
|
||||
var version = semver.parse(tag);
|
||||
return version;
|
||||
})
|
||||
.filter()
|
||||
.map(function(version) {
|
||||
// angular.js didn't follow semantic version until 1.20rc1
|
||||
if ((version.major === 1 && version.minor === 0 && version.prerelease.length > 0) || (version.major === 1 && version.minor === 2 && version.prerelease[0] === 'rc1')) {
|
||||
version.version = [version.major, version.minor, version.patch].join('.') + version.prerelease.join('');
|
||||
version.raw = 'v' + version.version;
|
||||
}
|
||||
version.docsUrl = 'http://code.angularjs.org/' + version.version + '/docs';
|
||||
// Versions before 1.0.2 had a different docs folder name
|
||||
if (version.major < 1 || (version.major === 1 && version.minor === 0 && version.patch < 2)) {
|
||||
version.docsUrl += '-' + version.version;
|
||||
version.isOldDocsUrl = true;
|
||||
}
|
||||
return version;
|
||||
})
|
||||
.sort(semver.compare)
|
||||
.value();
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the unstable snapshot version
|
||||
* @return {SemVer} The snapshot version
|
||||
*/
|
||||
var getSnapshotVersion = function() {
|
||||
var version = _(previousVersions)
|
||||
.filter(function(tag) {
|
||||
return semver.satisfies(tag, currentPackage.version);
|
||||
})
|
||||
.last();
|
||||
|
||||
if (!version) {
|
||||
// a snapshot version before the first tag on the branch
|
||||
version = semver(currentPackage.branchPattern.replace('*','0-alpha.1'));
|
||||
}
|
||||
|
||||
// We need to clone to ensure that we are not modifying another version
|
||||
version = semver(version.raw);
|
||||
|
||||
var jenkinsBuild = process.env.TRAVIS_BUILD_NUMBER || process.env.BUILD_NUMBER;
|
||||
if (!version.prerelease || !version.prerelease.length) {
|
||||
// last release was a non beta release. Increment the patch level to
|
||||
// indicate the next release that we will be doing.
|
||||
// E.g. last release was 1.3.0, then the snapshot will be
|
||||
// 1.3.1-build.1, which is lesser than 1.3.1 accorind the semver!
|
||||
|
||||
// If the last release was a beta release we don't update the
|
||||
// beta number by purpose, as otherwise the semver comparison
|
||||
// does not work any more when the next beta is released.
|
||||
// E.g. don't generate 1.3.0-beta.2.build.1
|
||||
// as this is bigger than 1.3.0-beta.2 according to semver
|
||||
version.patch++;
|
||||
}
|
||||
version.prerelease = jenkinsBuild ? ['build', jenkinsBuild] : ['local'];
|
||||
version.build = getBuild();
|
||||
version.codeName = 'snapshot';
|
||||
version.isSnapshot = true;
|
||||
version.format();
|
||||
version.full = version.version + '+' + version.build;
|
||||
version.branch = 'master';
|
||||
|
||||
return version;
|
||||
};
|
||||
|
||||
|
||||
exports.currentPackage = currentPackage = getPackage();
|
||||
exports.gitRepoInfo = gitRepoInfo = getGitRepoInfo();
|
||||
exports.previousVersions = previousVersions = getPreviousVersions();
|
||||
exports.currentVersion = getTaggedVersion() || getSnapshotVersion();
|
12
docs/links-package/index.js
Normal file
12
docs/links-package/index.js
Normal file
@ -0,0 +1,12 @@
|
||||
var Package = require('dgeni').Package;
|
||||
|
||||
module.exports = new Package('links', [])
|
||||
|
||||
.factory(require('./inline-tag-defs/link'))
|
||||
.factory(require('dgeni-packages/ngdoc/services/getAliases'))
|
||||
.factory(require('dgeni-packages/ngdoc/services/getDocFromAlias'))
|
||||
.factory(require('./services/getLinkInfo'))
|
||||
|
||||
.config(function(inlineTagProcessor, linkInlineTagDef) {
|
||||
inlineTagProcessor.inlineTagDefinitions.push(linkInlineTagDef);
|
||||
});
|
33
docs/links-package/inline-tag-defs/link.js
Normal file
33
docs/links-package/inline-tag-defs/link.js
Normal file
@ -0,0 +1,33 @@
|
||||
var INLINE_LINK = /(\S+)(?:\s+([\s\S]+))?/;
|
||||
|
||||
/**
|
||||
* @dgService linkInlineTagDef
|
||||
* @description
|
||||
* Process inline link tags (of the form {@link some/uri Some Title}), replacing them with HTML anchors
|
||||
* @kind function
|
||||
* @param {Object} url The url to match
|
||||
* @param {Function} docs error message
|
||||
* @return {String} The html link information
|
||||
*
|
||||
* @property {boolean} relativeLinks Whether we expect the links to be relative to the originating doc
|
||||
*/
|
||||
module.exports = function linkInlineTagDef(getLinkInfo, createDocMessage, log) {
|
||||
return {
|
||||
name: 'link',
|
||||
description: 'Process inline link tags (of the form {@link some/uri Some Title}), replacing them with HTML anchors',
|
||||
handler: function(doc, tagName, tagDescription) {
|
||||
|
||||
// Parse out the uri and title
|
||||
return tagDescription.replace(INLINE_LINK, function(match, uri, title) {
|
||||
|
||||
var linkInfo = getLinkInfo(uri, title, doc);
|
||||
|
||||
if ( !linkInfo.valid ) {
|
||||
log.warn(createDocMessage(linkInfo.error, doc));
|
||||
}
|
||||
|
||||
return "<a href='" + linkInfo.url + "'>" + linkInfo.title + "</a>";
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
72
docs/links-package/services/getLinkInfo.js
Normal file
72
docs/links-package/services/getLinkInfo.js
Normal file
@ -0,0 +1,72 @@
|
||||
var _ = require('lodash');
|
||||
var path = require('canonical-path');
|
||||
|
||||
/**
|
||||
* @dgService getLinkInfo
|
||||
* @description
|
||||
* Get link information to a document that matches the given url
|
||||
* @kind function
|
||||
* @param {String} url The url to match
|
||||
* @param {String} title An optional title to return in the link information
|
||||
* @return {Object} The link information
|
||||
*
|
||||
* @property {boolean} relativeLinks Whether we expect the links to be relative to the originating doc
|
||||
*/
|
||||
module.exports = function getLinkInfo(getDocFromAlias, encodeCodeBlock, log) {
|
||||
|
||||
return function getLinkInfoImpl(url, title, currentDoc) {
|
||||
var linkInfo = {
|
||||
url: url,
|
||||
type: 'url',
|
||||
valid: true,
|
||||
title: title || url
|
||||
};
|
||||
|
||||
if ( !url ) {
|
||||
throw new Error('Invalid url');
|
||||
}
|
||||
|
||||
var docs = getDocFromAlias(url, currentDoc);
|
||||
|
||||
if ( !getLinkInfoImpl.useFirstAmbiguousLink && docs.length > 1 ) {
|
||||
|
||||
linkInfo.valid = false;
|
||||
linkInfo.errorType = 'ambiguous';
|
||||
linkInfo.error = 'Ambiguous link: "' + url + '".\n' +
|
||||
docs.reduce(function(msg, doc) { return msg + '\n "' + doc.id + '" ('+ doc.docType + ') : (' + doc.path + ' / ' + doc.fileInfo.relativePath + ')'; }, 'Matching docs: ');
|
||||
|
||||
} else if ( docs.length >= 1 ) {
|
||||
|
||||
linkInfo.url = docs[0].path;
|
||||
linkInfo.title = title || encodeCodeBlock(docs[0].name, true);
|
||||
linkInfo.type = 'doc';
|
||||
|
||||
if ( getLinkInfoImpl.relativeLinks && currentDoc && currentDoc.path ) {
|
||||
var currentFolder = path.dirname(currentDoc.path);
|
||||
var docFolder = path.dirname(linkInfo.url);
|
||||
var relativeFolder = path.relative(path.join('/', currentFolder), path.join('/', docFolder));
|
||||
linkInfo.url = path.join(relativeFolder, path.basename(linkInfo.url));
|
||||
log.debug(currentDoc.path, docs[0].path, linkInfo.url);
|
||||
}
|
||||
|
||||
} else if ( url.indexOf('#') > 0 ) {
|
||||
var pathAndHash = url.split('#');
|
||||
linkInfo = getLinkInfoImpl(pathAndHash[0], title, currentDoc);
|
||||
linkInfo.url = linkInfo.url + '#' + pathAndHash[1];
|
||||
return linkInfo;
|
||||
|
||||
} else if ( url.indexOf('/') === -1 && url.indexOf('#') !== 0 ) {
|
||||
|
||||
linkInfo.valid = false;
|
||||
linkInfo.errorType = 'missing';
|
||||
linkInfo.error = 'Invalid link (does not match any doc): "' + url + '"';
|
||||
|
||||
} else {
|
||||
|
||||
linkInfo.title = title || (( url.indexOf('#') === 0 ) ? url.substring(1) : path.basename(url, '.html'));
|
||||
|
||||
}
|
||||
|
||||
return linkInfo;
|
||||
};
|
||||
};
|
@ -1,18 +1,25 @@
|
||||
var Package = require('dgeni').Package;
|
||||
var basePackage = require('../dgeni-package');
|
||||
|
||||
|
||||
module.exports = new Package('angular-public', [basePackage])
|
||||
|
||||
.processor(require('./processors/filterPublicDocs'))
|
||||
|
||||
.config(function(parseTagsProcessor) {
|
||||
parseTagsProcessor.tagDefinitions.push({ name: 'publicModule' });
|
||||
.config(function(readTypeScriptModules) {
|
||||
readTypeScriptModules.sourceFiles = [
|
||||
'angular2/annotations.ts',
|
||||
'angular2/change_detection.ts',
|
||||
'angular2/core.ts',
|
||||
'angular2/di.ts',
|
||||
'angular2/directives.ts',
|
||||
'angular2/forms.ts',
|
||||
'angular2/router.js',
|
||||
'angular2/test.ts',
|
||||
'angular2/pipes.ts'
|
||||
];
|
||||
readTypeScriptModules.hidePrivateMembers = true;
|
||||
})
|
||||
|
||||
.config(function(processClassDocs, filterPublicDocs, EXPORT_DOC_TYPES) {
|
||||
processClassDocs.ignorePrivateMembers = true;
|
||||
filterPublicDocs.docTypes = EXPORT_DOC_TYPES;
|
||||
.config(function(getLinkInfo) {
|
||||
getLinkInfo.useFirstAmbiguousLink = false;
|
||||
})
|
||||
|
||||
// Configure file writing
|
||||
|
@ -1,51 +0,0 @@
|
||||
var _ = require('lodash');
|
||||
|
||||
module.exports = function filterPublicDocs(modules) {
|
||||
return {
|
||||
$runAfter: ['tags-parsed'],
|
||||
$runBefore: ['computing-ids'],
|
||||
docTypes: [],
|
||||
$validate: {
|
||||
docTypes: { presence: true }
|
||||
},
|
||||
$process: function(docs) {
|
||||
|
||||
docTypes = this.docTypes;
|
||||
|
||||
|
||||
docs = _.filter(docs, function(doc) {
|
||||
|
||||
if (docTypes.indexOf(doc.docType) === -1) return true;
|
||||
if (!doc.publicModule) return false;
|
||||
|
||||
updateModule(doc);
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
docs = _.filter(docs, function(doc) {
|
||||
return doc.docType !== 'module' || doc.isPublic;
|
||||
});
|
||||
return docs;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
function updateModule(classDoc) {
|
||||
|
||||
var originalModule = classDoc.moduleDoc;
|
||||
var publicModule = modules[classDoc.publicModule];
|
||||
|
||||
if (!publicModule) {
|
||||
throw new Error('Missing module definition: "' + classDoc.publicModule + '"\n' +
|
||||
'Referenced in class: "' + classDoc.moduleDoc.id + '/' + classDoc.name + '"');
|
||||
}
|
||||
|
||||
publicModule.isPublic = true;
|
||||
|
||||
_.remove(classDoc.moduleDoc.exports, function(doc) { return doc === classDoc; });
|
||||
classDoc.moduleDoc = publicModule;
|
||||
publicModule.exports.push(classDoc);
|
||||
|
||||
}
|
||||
};
|
1126
gulpfile.js
1126
gulpfile.js
File diff suppressed because it is too large
Load Diff
@ -1,81 +1,51 @@
|
||||
// Karma configuration
|
||||
// Generated on Thu Sep 25 2014 11:52:02 GMT-0700 (PDT)
|
||||
var file2moduleName = require('./tools/build/file2modulename');
|
||||
|
||||
module.exports = function(config) {
|
||||
config.set({
|
||||
|
||||
frameworks: ['dart-unittest'],
|
||||
|
||||
files: [
|
||||
// Init and configure guiness.
|
||||
{pattern: 'test-init.dart', included: true},
|
||||
// Unit test files needs to be included.
|
||||
// Karma-dart generates `__adapter_unittest.dart` that imports these files.
|
||||
{pattern: 'modules/*/test/**/*_spec.js', included: true},
|
||||
{pattern: 'tools/transpiler/spec/**/*_spec.js', included: true},
|
||||
{pattern: 'dist/dart/**/*_spec.dart', included: true, watched: false},
|
||||
|
||||
// These files are not included, they are imported by the unit tests above.
|
||||
{pattern: 'modules/**', included: false},
|
||||
{pattern: 'tools/transpiler/spec/**/*', included: false},
|
||||
// Karma-dart via the dart-unittest framework generates
|
||||
// `__adapter_unittest.dart` that imports these files.
|
||||
{pattern: 'dist/dart/**', included: false, watched: false},
|
||||
|
||||
// Dependencies, installed with `pub install`.
|
||||
{pattern: 'packages/**/*.dart', included: false, watched: false},
|
||||
|
||||
// Init and configure guiness.
|
||||
{pattern: 'test-main.dart', included: true}
|
||||
{pattern: 'test-main.dart', included: true},
|
||||
{pattern: 'modules/**/test/**/static_assets/**', included: false, watched: false},
|
||||
],
|
||||
|
||||
exclude: [
|
||||
'dist/dart/**/packages/**',
|
||||
],
|
||||
|
||||
karmaDartImports: {
|
||||
guinness: 'package:guinness/guinness_html.dart'
|
||||
},
|
||||
|
||||
// TODO(vojta): Remove the localhost:9877 from urls, once the proxy fix is merged:
|
||||
// https://github.com/karma-runner/karma/pull/1207
|
||||
//
|
||||
// Map packages to the correct urls where Karma serves them.
|
||||
proxies: {
|
||||
// Dependencies installed with `pub install`.
|
||||
'/packages/unittest': 'http://localhost:9877/base/packages/unittest',
|
||||
'/packages/guinness': 'http://localhost:9877/base/packages/guinness',
|
||||
'/packages/matcher': 'http://localhost:9877/base/packages/matcher',
|
||||
'/packages/stack_trace': 'http://localhost:9877/base/packages/stack_trace',
|
||||
'/packages/collection': 'http://localhost:9877/base/packages/collection',
|
||||
'/packages/path': 'http://localhost:9877/base/packages/path',
|
||||
'/packages/unittest': '/base/packages/unittest',
|
||||
'/packages/guinness': '/base/packages/guinness',
|
||||
'/packages/matcher': '/base/packages/matcher',
|
||||
'/packages/stack_trace': '/base/packages/stack_trace',
|
||||
'/packages/collection': '/base/packages/collection',
|
||||
'/packages/path': '/base/packages/path',
|
||||
|
||||
// Local dependencies, transpiled from the source.
|
||||
'/packages/angular': 'http://localhost:9877/base/modules/angular',
|
||||
'/packages/benchpress': 'http://localhost:9877/base/modules/benchpress',
|
||||
'/packages/core': 'http://localhost:9877/base/modules/core',
|
||||
'/packages/change_detection': 'http://localhost:9877/base/modules/change_detection',
|
||||
'/packages/reflection': 'http://localhost:9877/base/modules/reflection',
|
||||
'/packages/di': 'http://localhost:9877/base/modules/di',
|
||||
'/packages/directives': 'http://localhost:9877/base/modules/directives',
|
||||
'/packages/facade': 'http://localhost:9877/base/modules/facade',
|
||||
'/packages/forms': 'http://localhost:9877/base/modules/forms',
|
||||
'/packages/test_lib': 'http://localhost:9877/base/modules/test_lib',
|
||||
'/packages/mock': 'http://localhost:9877/base/modules/mock',
|
||||
},
|
||||
|
||||
preprocessors: {
|
||||
'modules/**/*.js': ['traceur'],
|
||||
'tools/**/*.js': ['traceur']
|
||||
},
|
||||
|
||||
traceurPreprocessor: {
|
||||
options: {
|
||||
outputLanguage: 'dart',
|
||||
sourceMaps: true,
|
||||
script: false,
|
||||
modules: 'register',
|
||||
memberVariables: true,
|
||||
types: true,
|
||||
// typeAssertions: true,
|
||||
// typeAssertionModule: 'assert',
|
||||
annotations: true
|
||||
},
|
||||
resolveModuleName: file2moduleName,
|
||||
transformPath: function(fileName) {
|
||||
return fileName.replace('.js', '.dart');
|
||||
}
|
||||
'/packages/angular2': '/base/dist/dart/angular2/lib',
|
||||
'/packages/angular2_material': '/base/dist/dart/angular2_material/lib',
|
||||
'/packages/benchpress': '/base/dist/dart/benchpress/lib',
|
||||
'/packages/examples': '/base/dist/dart/examples/lib'
|
||||
},
|
||||
|
||||
customLaunchers: {
|
||||
@ -87,7 +57,4 @@ module.exports = function(config) {
|
||||
|
||||
port: 9877
|
||||
});
|
||||
|
||||
|
||||
config.plugins.push(require('./tools/transpiler/karma-traceur-preprocessor'));
|
||||
};
|
||||
|
@ -1,7 +1,5 @@
|
||||
// Karma configuration
|
||||
// Generated on Thu Sep 25 2014 11:52:02 GMT-0700 (PDT)
|
||||
var file2moduleName = require('./tools/build/file2modulename');
|
||||
|
||||
module.exports = function(config) {
|
||||
config.set({
|
||||
|
||||
@ -10,59 +8,40 @@ module.exports = function(config) {
|
||||
files: [
|
||||
// Sources and specs.
|
||||
// Loaded through the es6-module-loader, in `test-main.js`.
|
||||
{pattern: 'modules/**', included: false},
|
||||
{pattern: 'tools/transpiler/spec/**', included: false},
|
||||
{pattern: 'dist/js/dev/es5/**', included: false, watched: false},
|
||||
|
||||
// zone-microtask must be included first as it contains a Promise monkey patch
|
||||
'node_modules/zone.js/dist/zone-microtask.js',
|
||||
'node_modules/zone.js/dist/long-stack-trace-zone.js',
|
||||
|
||||
'node_modules/traceur/bin/traceur-runtime.js',
|
||||
'node_modules/es6-module-loader/dist/es6-module-loader-sans-promises.src.js',
|
||||
// Including systemjs because it defines `__eval`, which produces correct stack traces.
|
||||
'node_modules/systemjs/dist/system.src.js',
|
||||
'node_modules/systemjs/lib/extension-register.js',
|
||||
'node_modules/zone.js/zone.js',
|
||||
'node_modules/zone.js/long-stack-trace-zone.js',
|
||||
|
||||
'node_modules/systemjs/lib/extension-cjs.js',
|
||||
'node_modules/rx/dist/rx.js',
|
||||
'node_modules/reflect-metadata/Reflect.js',
|
||||
'tools/build/file2modulename.js',
|
||||
'test-main.js'
|
||||
'test-main.js',
|
||||
{pattern: 'modules/**/test/**/static_assets/**', included: false, watched: false},
|
||||
'modules/angular2/src/test_lib/shims_for_IE.es6'
|
||||
],
|
||||
|
||||
exclude: [
|
||||
'modules/**/e2e_test/**'
|
||||
'dist/js/dev/es5/**/e2e_test/**',
|
||||
],
|
||||
|
||||
preprocessors: {
|
||||
'modules/**/*.js': ['traceur'],
|
||||
'modules/**/*.es6': ['traceur'],
|
||||
'tools/transpiler/spec/**/*.js': ['traceur'],
|
||||
'tools/transpiler/spec/**/*.es6': ['traceur'],
|
||||
},
|
||||
|
||||
traceurPreprocessor: {
|
||||
options: {
|
||||
outputLanguage: 'es5',
|
||||
sourceMaps: true,
|
||||
script: false,
|
||||
memberVariables: true,
|
||||
modules: 'instantiate',
|
||||
types: true,
|
||||
typeAssertions: true,
|
||||
typeAssertionModule: 'rtts_assert/rtts_assert',
|
||||
annotations: true
|
||||
},
|
||||
resolveModuleName: file2moduleName,
|
||||
transformPath: function(fileName) {
|
||||
return fileName.replace(/\.es6$/, '.js');
|
||||
}
|
||||
},
|
||||
|
||||
customLaunchers: {
|
||||
DartiumWithWebPlatform: {
|
||||
base: 'Dartium',
|
||||
flags: ['--enable-experimental-web-platform-features'] }
|
||||
flags: ['--enable-experimental-web-platform-features'] },
|
||||
ChromeNoSandbox: {
|
||||
base: 'Chrome',
|
||||
flags: ['--no-sandbox'] }
|
||||
},
|
||||
browsers: ['ChromeCanary'],
|
||||
|
||||
port: 9876
|
||||
});
|
||||
|
||||
config.plugins.push(require('./tools/transpiler/karma-traceur-preprocessor'));
|
||||
};
|
||||
|
@ -1 +0,0 @@
|
||||
karma-js.conf.js
|
8
modules/angular2/angular2.js
vendored
8
modules/angular2/angular2.js
vendored
@ -1,8 +0,0 @@
|
||||
/**
|
||||
* Define public API for Angular here.
|
||||
*/
|
||||
export * from './change_detection';
|
||||
export * from './core';
|
||||
export * from './annotations';
|
||||
export * from './directives';
|
||||
export * from './forms';
|
9
modules/angular2/angular2.ts
Normal file
9
modules/angular2/angular2.ts
Normal file
@ -0,0 +1,9 @@
|
||||
export * from './change_detection';
|
||||
export * from './core';
|
||||
export * from './annotations';
|
||||
export * from './directives';
|
||||
export * from './forms';
|
||||
export * from './di';
|
||||
export {Observable, EventEmitter} from 'angular2/src/facade/async';
|
||||
export * from 'angular2/src/render/api';
|
||||
export {DomRenderer, DOCUMENT_TOKEN} from 'angular2/src/render/dom/dom_renderer';
|
3
modules/angular2/angular2_sfx.dart
Normal file
3
modules/angular2/angular2_sfx.dart
Normal file
@ -0,0 +1,3 @@
|
||||
library angular2.sfx;
|
||||
|
||||
// empty as we don't have a version for Dart
|
30
modules/angular2/angular2_sfx.ts
Normal file
30
modules/angular2/angular2_sfx.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import * as ng from './angular2';
|
||||
// the router should have its own SFX bundle
|
||||
// But currently the module arithemtic 'angular2/router_sfx - angular2/angular2',
|
||||
// is not support by system builder.
|
||||
import * as router from './router';
|
||||
|
||||
var angular: AngularOne = <any>ng;
|
||||
(<AngularWindow>window).angular = angular;
|
||||
|
||||
var _prevAngular = (<AngularWindow>window).angular;
|
||||
|
||||
|
||||
angular.router = router;
|
||||
/**
|
||||
* Calling noConflict will restore window.angular to its pre-angular loading state
|
||||
* and return the angular module object.
|
||||
*/
|
||||
angular.noConflict = function() {
|
||||
(<AngularWindow>window).angular = _prevAngular;
|
||||
return angular;
|
||||
};
|
||||
|
||||
interface AngularOne {
|
||||
router: any;
|
||||
noConflict(): any;
|
||||
}
|
||||
|
||||
interface AngularWindow extends Window {
|
||||
angular: any;
|
||||
}
|
4
modules/angular2/annotations.js
vendored
4
modules/angular2/annotations.js
vendored
@ -1,4 +0,0 @@
|
||||
/**
|
||||
* Define public API for Angular here.
|
||||
*/
|
||||
export * from './src/core/annotations/annotations';
|
14
modules/angular2/annotations.ts
Normal file
14
modules/angular2/annotations.ts
Normal file
@ -0,0 +1,14 @@
|
||||
/**
|
||||
* @module
|
||||
* @public
|
||||
* @description
|
||||
*
|
||||
* Annotations provide the additional information that Angular requires in order to run your
|
||||
* application. This module
|
||||
* contains {@link Component}, {@link Directive}, and {@link View} annotations, as well as
|
||||
* {@link Parent} and {@link Ancestor} annotations that are
|
||||
* used by Angular to resolve dependencies.
|
||||
*
|
||||
*/
|
||||
export * from './src/core/annotations/annotations';
|
||||
export * from './src/core/annotations/decorators';
|
72
modules/angular2/change_detection.js
vendored
72
modules/angular2/change_detection.js
vendored
@ -1,72 +0,0 @@
|
||||
export {AST} from './src/change_detection/parser/ast';
|
||||
export {Lexer} from './src/change_detection/parser/lexer';
|
||||
export {Parser} from './src/change_detection/parser/parser';
|
||||
export {Locals}
|
||||
from './src/change_detection/parser/locals';
|
||||
export {ExpressionChangedAfterItHasBeenChecked, ChangeDetectionError}
|
||||
from './src/change_detection/exceptions';
|
||||
export {ChangeRecord, ChangeDispatcher, ChangeDetector,
|
||||
CHECK_ONCE, CHECK_ALWAYS, DETACHED, CHECKED} from './src/change_detection/interfaces';
|
||||
export {ProtoChangeDetector, DynamicProtoChangeDetector, JitProtoChangeDetector, BindingRecord}
|
||||
from './src/change_detection/proto_change_detector';
|
||||
export {DynamicChangeDetector}
|
||||
from './src/change_detection/dynamic_change_detector';
|
||||
export * from './src/change_detection/pipes/pipe_registry';
|
||||
export {uninitialized} from './src/change_detection/change_detection_util';
|
||||
export * from './src/change_detection/pipes/pipe';
|
||||
|
||||
import {ProtoChangeDetector, DynamicProtoChangeDetector, JitProtoChangeDetector}
|
||||
from './src/change_detection/proto_change_detector';
|
||||
import {PipeRegistry} from './src/change_detection/pipes/pipe_registry';
|
||||
import {ArrayChangesFactory} from './src/change_detection/pipes/array_changes';
|
||||
import {KeyValueChangesFactory} from './src/change_detection/pipes/keyvalue_changes';
|
||||
import {NullPipeFactory} from './src/change_detection/pipes/null_pipe';
|
||||
|
||||
export class ChangeDetection {
|
||||
createProtoChangeDetector(name:string):ProtoChangeDetector{
|
||||
// TODO: this should be abstract, once supported in AtScript
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export var defaultPipes = {
|
||||
"iterableDiff" : [
|
||||
new ArrayChangesFactory(),
|
||||
new NullPipeFactory()
|
||||
],
|
||||
"keyValDiff" : [
|
||||
new KeyValueChangesFactory(),
|
||||
new NullPipeFactory()
|
||||
]
|
||||
};
|
||||
|
||||
export class DynamicChangeDetection extends ChangeDetection {
|
||||
registry:PipeRegistry;
|
||||
|
||||
constructor(registry:PipeRegistry) {
|
||||
super();
|
||||
this.registry = registry;
|
||||
}
|
||||
|
||||
createProtoChangeDetector(name:string):ProtoChangeDetector{
|
||||
return new DynamicProtoChangeDetector(this.registry);
|
||||
}
|
||||
}
|
||||
|
||||
export class JitChangeDetection extends ChangeDetection {
|
||||
registry:PipeRegistry;
|
||||
|
||||
constructor(registry:PipeRegistry) {
|
||||
super();
|
||||
this.registry = registry;
|
||||
}
|
||||
|
||||
createProtoChangeDetector(name:string):ProtoChangeDetector{
|
||||
return new JitProtoChangeDetector(this.registry);
|
||||
}
|
||||
}
|
||||
|
||||
var _registry = new PipeRegistry(defaultPipes);
|
||||
|
||||
export var dynamicChangeDetection = new DynamicChangeDetection(_registry);
|
||||
export var jitChangeDetection = new JitChangeDetection(_registry);
|
59
modules/angular2/change_detection.ts
Normal file
59
modules/angular2/change_detection.ts
Normal file
@ -0,0 +1,59 @@
|
||||
/**
|
||||
* @module
|
||||
* @public
|
||||
* @description
|
||||
* Change detection enables data binding in Angular.
|
||||
*/
|
||||
|
||||
export {
|
||||
ASTWithSource,
|
||||
AST,
|
||||
AstTransformer,
|
||||
AccessMember,
|
||||
LiteralArray,
|
||||
ImplicitReceiver
|
||||
} from './src/change_detection/parser/ast';
|
||||
|
||||
export {Lexer} from './src/change_detection/parser/lexer';
|
||||
export {Parser} from './src/change_detection/parser/parser';
|
||||
export {Locals} from './src/change_detection/parser/locals';
|
||||
|
||||
export {
|
||||
ExpressionChangedAfterItHasBeenChecked,
|
||||
ChangeDetectionError
|
||||
} from './src/change_detection/exceptions';
|
||||
export {
|
||||
ProtoChangeDetector,
|
||||
ChangeDispatcher,
|
||||
ChangeDetector,
|
||||
ChangeDetection,
|
||||
ChangeDetectorDefinition
|
||||
} from './src/change_detection/interfaces';
|
||||
export {
|
||||
CHECK_ONCE,
|
||||
CHECK_ALWAYS,
|
||||
DETACHED,
|
||||
CHECKED,
|
||||
ON_PUSH,
|
||||
DEFAULT
|
||||
} from './src/change_detection/constants';
|
||||
export {
|
||||
DynamicProtoChangeDetector,
|
||||
JitProtoChangeDetector
|
||||
} from './src/change_detection/proto_change_detector';
|
||||
export {BindingRecord} from './src/change_detection/binding_record';
|
||||
export {DirectiveIndex, DirectiveRecord} from './src/change_detection/directive_record';
|
||||
export {DynamicChangeDetector} from './src/change_detection/dynamic_change_detector';
|
||||
export {ChangeDetectorRef} from './src/change_detection/change_detector_ref';
|
||||
export {PipeRegistry} from './src/change_detection/pipes/pipe_registry';
|
||||
export {uninitialized} from './src/change_detection/change_detection_util';
|
||||
export {WrappedValue, Pipe, PipeFactory} from './src/change_detection/pipes/pipe';
|
||||
export {NullPipe, NullPipeFactory} from './src/change_detection/pipes/null_pipe';
|
||||
export {
|
||||
defaultPipes,
|
||||
DynamicChangeDetection,
|
||||
JitChangeDetection,
|
||||
PreGeneratedChangeDetection,
|
||||
preGeneratedProtoDetectors,
|
||||
defaultPipeRegistry
|
||||
} from './src/change_detection/change_detection';
|
13
modules/angular2/core.js
vendored
13
modules/angular2/core.js
vendored
@ -1,13 +0,0 @@
|
||||
export * from './src/core/annotations/visibility';
|
||||
export * from './src/core/compiler/interfaces';
|
||||
export * from './src/core/annotations/template';
|
||||
export * from './src/core/application';
|
||||
|
||||
export * from './src/core/compiler/compiler';
|
||||
|
||||
export * from './src/core/compiler/template_loader';
|
||||
export * from './src/core/compiler/view';
|
||||
export * from './src/core/compiler/view_container';
|
||||
export * from './src/core/compiler/binding_propagation_config';
|
||||
|
||||
export * from './src/core/dom/element';
|
22
modules/angular2/core.ts
Normal file
22
modules/angular2/core.ts
Normal file
@ -0,0 +1,22 @@
|
||||
/**
|
||||
* @module
|
||||
* @public
|
||||
* @description
|
||||
* Define angular core API here.
|
||||
*/
|
||||
export * from './src/core/annotations/visibility';
|
||||
export * from './src/core/annotations/view';
|
||||
export * from './src/core/application';
|
||||
export * from './src/core/application_tokens';
|
||||
export * from './src/core/annotations/di';
|
||||
|
||||
export * from './src/core/compiler/compiler';
|
||||
export * from './src/core/compiler/interfaces';
|
||||
export * from './src/core/compiler/query_list';
|
||||
export * from './src/core/compiler/directive_resolver';
|
||||
export * from './src/core/compiler/dynamic_component_loader';
|
||||
export {ViewRef, ProtoViewRef} from './src/core/compiler/view_ref';
|
||||
export {ViewContainerRef} from './src/core/compiler/view_container_ref';
|
||||
export {ElementRef} from './src/core/compiler/element_ref';
|
||||
|
||||
export {NgZone} from './src/core/zone/ng_zone';
|
2
modules/angular2/debug.ts
Normal file
2
modules/angular2/debug.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './src/debug/debug_element';
|
||||
export {inspectDomElement, ELEMENT_PROBE_CONFIG} from './src/debug/debug_element_view_listener';
|
7
modules/angular2/di.js
vendored
7
modules/angular2/di.js
vendored
@ -1,7 +0,0 @@
|
||||
export {Inject, InjectPromise, InjectLazy, Injectable, Optional, DependencyAnnotation} from './src/di/annotations';
|
||||
export {Injector} from './src/di/injector';
|
||||
export {Binding, Dependency, bind} from './src/di/binding';
|
||||
export {Key, KeyRegistry} from './src/di/key';
|
||||
export {KeyMetadataError, NoProviderError, ProviderError, AsyncBindingError, CyclicDependencyError,
|
||||
InstantiationError, InvalidBindingError, NoAnnotationError} from './src/di/exceptions';
|
||||
export {OpaqueToken} from './src/di/opaque_token';
|
23
modules/angular2/di.ts
Normal file
23
modules/angular2/di.ts
Normal file
@ -0,0 +1,23 @@
|
||||
/**
|
||||
* @module
|
||||
* @public
|
||||
* @description
|
||||
* The `di` module provides dependency injection container services.
|
||||
*/
|
||||
|
||||
export * from './src/di/annotations';
|
||||
export * from './src/di/decorators';
|
||||
export * from './src/di/forward_ref';
|
||||
export {resolveBindings, Injector} from './src/di/injector';
|
||||
export {Binding, BindingBuilder, ResolvedBinding, Dependency, bind} from './src/di/binding';
|
||||
export {Key, KeyRegistry, TypeLiteral} from './src/di/key';
|
||||
export {
|
||||
NoBindingError,
|
||||
AbstractBindingError,
|
||||
AsyncBindingError,
|
||||
CyclicDependencyError,
|
||||
InstantiationError,
|
||||
InvalidBindingError,
|
||||
NoAnnotationError
|
||||
} from './src/di/exceptions';
|
||||
export {OpaqueToken} from './src/di/opaque_token';
|
6
modules/angular2/di_annotations.ts
Normal file
6
modules/angular2/di_annotations.ts
Normal file
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* @module
|
||||
* @public
|
||||
* @description
|
||||
* Annotations which control how the dependencies are resolved by the {@link Injector}.
|
||||
*/
|
6
modules/angular2/di_errors.ts
Normal file
6
modules/angular2/di_errors.ts
Normal file
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* @module
|
||||
* @public
|
||||
* @description
|
||||
* Errors thrown by the {@link Injector}.
|
||||
*/
|
4
modules/angular2/directives.js
vendored
4
modules/angular2/directives.js
vendored
@ -1,4 +0,0 @@
|
||||
export * from './src/directives/foreach';
|
||||
export * from './src/directives/if';
|
||||
export * from './src/directives/non_bindable';
|
||||
export * from './src/directives/switch';
|
63
modules/angular2/directives.ts
Normal file
63
modules/angular2/directives.ts
Normal file
@ -0,0 +1,63 @@
|
||||
/**
|
||||
* @module
|
||||
* @public
|
||||
* @description
|
||||
* Common directives shipped with Angular.
|
||||
*/
|
||||
|
||||
import {CONST_EXPR, Type} from './src/facade/lang';
|
||||
import {NgFor} from './src/directives/ng_for';
|
||||
import {NgIf} from './src/directives/ng_if';
|
||||
import {NgNonBindable} from './src/directives/ng_non_bindable';
|
||||
import {NgSwitch, NgSwitchWhen, NgSwitchDefault} from './src/directives/ng_switch';
|
||||
|
||||
export * from './src/directives/class';
|
||||
export * from './src/directives/ng_for';
|
||||
export * from './src/directives/ng_if';
|
||||
export * from './src/directives/ng_non_bindable';
|
||||
export * from './src/directives/ng_switch';
|
||||
|
||||
/**
|
||||
* A collection of the Angular core directives that are likely to be used in each and every Angular
|
||||
* application.
|
||||
*
|
||||
* This collection can be used to quickly enumerate all the built-in directives in the `@View`
|
||||
* annotation. For example,
|
||||
* instead of writing:
|
||||
*
|
||||
* ```
|
||||
* import {If, NgFor, NgSwitch, NgSwitchWhen, NgSwitchDefault} from 'angular2/angular2';
|
||||
* import {OtherDirective} from 'myDirectives';
|
||||
*
|
||||
* @Component({
|
||||
* selector: 'my-component'
|
||||
* })
|
||||
* @View({
|
||||
* templateUrl: 'myComponent.html',
|
||||
* directives: [If, NgFor, NgSwitch, NgSwitchWhen, NgSwitchDefault, OtherDirective]
|
||||
* })
|
||||
* export class MyComponent {
|
||||
* ...
|
||||
* }
|
||||
* ```
|
||||
* one could enumerate all the core directives at once:
|
||||
*
|
||||
* ```
|
||||
* import {coreDirectives} from 'angular2/angular2';
|
||||
* import {OtherDirective} from 'myDirectives';
|
||||
*
|
||||
* @Component({
|
||||
* selector: 'my-component'
|
||||
* })
|
||||
* @View({
|
||||
* templateUrl: 'myComponent.html',
|
||||
* directives: [coreDirectives, OtherDirective]
|
||||
* })
|
||||
* export class MyComponent {
|
||||
* ...
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
export const coreDirectives: List<Type> =
|
||||
CONST_EXPR([NgFor, NgIf, NgNonBindable, NgSwitch, NgSwitchWhen, NgSwitchDefault]);
|
@ -5,7 +5,7 @@ projected to DOM as well as which DOM events should invoke which methods on the
|
||||
syntax which is core to Angular and allows for data-binding, event-binding, template-instantiation.
|
||||
|
||||
The design of the template syntax has these properties:
|
||||
|
||||
|
||||
|
||||
* All data-binding expressions are easily identifiable. (i.e. there is never an ambiguity whether the value should be
|
||||
interpreted as string literal or as an expression.)
|
||||
@ -187,7 +187,7 @@ Example:
|
||||
<pre>
|
||||
```
|
||||
<ul>
|
||||
<li template="foreach: #item in items">
|
||||
<li template="for: #item of items">
|
||||
{{item}}
|
||||
</li>
|
||||
</ul>
|
||||
@ -201,8 +201,8 @@ Example:
|
||||
<pre>
|
||||
```
|
||||
<ul>
|
||||
<template def-foreach:"item"
|
||||
bind-foreach-in="items">
|
||||
<template def-for:"item"
|
||||
bind-for-in="items">
|
||||
<li>
|
||||
{{item}}
|
||||
</li>
|
||||
@ -221,8 +221,8 @@ Example:
|
||||
|
||||
<pre>
|
||||
```
|
||||
<template #foreach="item"
|
||||
[foreach-in]="items">
|
||||
<template #for="item"
|
||||
[for-in]="items">
|
||||
_some_content_to_repeat_
|
||||
</template>
|
||||
```
|
||||
@ -234,8 +234,8 @@ Example:
|
||||
Example:
|
||||
<pre>
|
||||
```
|
||||
<template def-foreach="item"
|
||||
bind-foreach-in="items">
|
||||
<template def-for="item"
|
||||
bind-for-in="items">
|
||||
_some_content_to_repeat_
|
||||
</template>
|
||||
```
|
||||
@ -282,7 +282,7 @@ Key points:
|
||||
* The binding is to the element property not the element attribute.
|
||||
* To prevent custom element from accidentally reading the literal `expression` on the title element, the attribute name
|
||||
is escaped. In our case the `title` is escaped to `[title]` through the addition of square brackets `[]`.
|
||||
* A binding value (in this case `user.firstName` will always be an expression, never a string literal)
|
||||
* A binding value (in this case `user.firstName` will always be an expression, never a string literal).
|
||||
|
||||
NOTE: Unlike Angular v1, Angular v2 binds to properties of elements rather than attributes of elements. This is
|
||||
done to better support custom elements, and to allow binding for values other than strings.
|
||||
@ -372,8 +372,8 @@ Where:
|
||||
inserted. The template can be defined implicitly with `template` attribute, which turns the current element into
|
||||
a template, or explicitly with `<template>` element. Explicit declaration is longer, but it allows for having
|
||||
templates which have more than one root DOM node.
|
||||
* `viewport` is required for templates. The Viewport directive is responsible for deciding when
|
||||
and in which order should child views be inserted into this location. An Viewport directive usually has one or
|
||||
* `viewport` is required for templates. The directive is responsible for deciding when
|
||||
and in which order should child views be inserted into this location. Such a directive usually has one or
|
||||
more bindings and can be represented as either `viewport-directive-bindings` or
|
||||
`viewport-directive-microsyntax` on `template` element or attribute. See template microsyntax for more details.
|
||||
|
||||
@ -382,48 +382,46 @@ Example of conditionally included template:
|
||||
|
||||
```
|
||||
Hello {{user}}!
|
||||
<div template="if: isAdministrator">
|
||||
<div template="ng-if: isAdministrator">
|
||||
...administrator menu here...
|
||||
</div>
|
||||
```
|
||||
|
||||
In the above example the `if` Viewport determines whether the child view (an instance of the child template) should be
|
||||
inserted into the root view. The `if` makes this decision based on if the `isAdministrator` binding is true.
|
||||
In the above example the `ng-if` directive determines whether the child view (an instance of the child template) should be
|
||||
inserted into the root view. The `ng-if` makes this decision based on if the `isAdministrator` binding is true.
|
||||
|
||||
The above example is in the short form, for better clarity let's rewrite it in the canonical form, which is functionally
|
||||
identical.
|
||||
|
||||
```
|
||||
Hello {{user}}!
|
||||
<template [if]="isAdministrator">
|
||||
<template [ng-if]="isAdministrator">
|
||||
<div>
|
||||
...administrator menu here...
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
NOTE: Only Viewport directives can be placed on the template element. (Decorators and Components are not allowed.)
|
||||
|
||||
|
||||
### Template Microsyntax
|
||||
|
||||
Often times it is necessary to encode a lot of different bindings into a template to control how the instantiation
|
||||
of the templates occurs. One such example is `foreach`.
|
||||
of the templates occurs. One such example is `ng-for`.
|
||||
|
||||
```
|
||||
<form #foo=form>
|
||||
</form>
|
||||
<ul>
|
||||
<template foreach #person [in]="people" #i="index">
|
||||
<template [ng-for] #person [ng-for-of]="people" #i="index">
|
||||
<li>{{i}}. {{person}}<li>
|
||||
</template>
|
||||
</ul>
|
||||
```
|
||||
|
||||
Where:
|
||||
* `foreach` triggers the foreach directive.
|
||||
* `[in]="people"` binds an iterable object to the `foreach` controller.
|
||||
* `#person` exports the implicit `foreach` item.
|
||||
* `[ng-for]` triggers the for directive.
|
||||
* `#person` exports the implicit `ng-for` item.
|
||||
* `[ng-for-of]="people"` binds an iterable object to the `ng-for` controller.
|
||||
* `#i=index` exports item index as `i`.
|
||||
|
||||
The above example is explicit but quite wordy. For this reason in most situations a short hand version of the
|
||||
@ -431,7 +429,7 @@ syntax is preferable.
|
||||
|
||||
```
|
||||
<ul>
|
||||
<li template="foreach; #person; in=people; #i=index;">{{i}}. {{person}}<li>
|
||||
<li template="ng-for; #person; of=people; #i=index;">{{i}}. {{person}}<li>
|
||||
</ul>
|
||||
```
|
||||
|
||||
@ -441,19 +439,28 @@ which allows us to further shorten the text.
|
||||
|
||||
```
|
||||
<ul>
|
||||
<li template="foreach #person in people #i=index">{{i}}. {{person}}<li>
|
||||
<li template="ng-for #person of people #i=index">{{i}}. {{person}}<li>
|
||||
</ul>
|
||||
```
|
||||
|
||||
We can also optionally use `var` instead of `#` and add `:` to `foreach` which creates the following recommended
|
||||
microsyntax for `foreach`.
|
||||
We can also optionally use `var` instead of `#` and add `:` to `for` which creates the following recommended
|
||||
microsyntax for `ng-for`.
|
||||
|
||||
```
|
||||
<ul>
|
||||
<li template="foreach: var person in people; var i=index">{{i}}. {{person}}<li>
|
||||
<li template="ng-for: var person of people; var i=index">{{i}}. {{person}}<li>
|
||||
</ul>
|
||||
```
|
||||
|
||||
Finally, we can move the `ng-for` keyword to the left hand side and prefix it with `*` as so:
|
||||
|
||||
```
|
||||
<ul>
|
||||
<li *ng-for="var person of people; var i=index">{{i}}. {{person}}<li>
|
||||
</ul>
|
||||
```
|
||||
|
||||
|
||||
The format is intentionally defined freely, so that developers of directives can build an expressive microsyntax for
|
||||
their directives. The following code describes a more formal definition.
|
||||
|
||||
@ -480,7 +487,7 @@ Where
|
||||
|
||||
|
||||
NOTE: the `template` attribute must be present to make it clear to the user that a sub-template is being created. This
|
||||
goes along the philosophy that the developer should be able to reason about the template without understanding the
|
||||
goes along with the philosophy that the developer should be able to reason about the template without understanding the
|
||||
semantics of the instantiator directive.
|
||||
|
||||
|
||||
@ -503,13 +510,14 @@ Binding events allows wiring events from DOM (or other components) to the Angula
|
||||
|
||||
Where:
|
||||
* `some-element` Any element which can generate DOM events (or has an angular directive which generates the event).
|
||||
* `some-event` (escaped with `()` or `bind-`) is the name of the event `some-event`. In this case the
|
||||
* `some-event` (escaped with `()` or `on-`) is the name of the event `some-event`. In this case the
|
||||
dash-case is converted into camel-case `someEvent`.
|
||||
* `statement` is a valid statement (as defined in section below).
|
||||
If the execution of the statement returns `false`, then `preventDefault`is applied on the DOM event.
|
||||
|
||||
By default, angular only listens to the element on the event, and ignores events which bubble. To listen to bubbled
|
||||
events (as in the case of clicking on any child) use the bubble option (`(^event)` or `on-bubble-event`) as shown
|
||||
bellow.
|
||||
events (as in the case of clicking on any child) use the bubble option (`(event)` or `on-bubble-event`) as shown
|
||||
below.
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
@ -561,7 +569,7 @@ Angular are:
|
||||
<div title="{{expression}}">{{expression}}</div>
|
||||
<div [title]="expression">...</div>
|
||||
<div bind-title="expression">...</div>
|
||||
<div template="if: expression">...</div>
|
||||
<div template="ng-if: expression">...</div>
|
||||
```
|
||||
|
||||
Expressions are simplified version of expression in the language in which you are writing your application. (i.e.
|
||||
|
@ -6,17 +6,12 @@ Directives are the cornerstone of an Angular application. We use Directives to b
|
||||
|
||||
Angular applications do not have a main method. Instead they have a root Component. Dependency Injection then assembles the directives into a working Angular application.
|
||||
|
||||
There are three different kinds of directives (described in more detail in later sections).
|
||||
|
||||
1. *Decorators*: can be placed on any DOM element and can be combined with other directives.
|
||||
2. *Components*: Components have an encapsulated view and can configure injectors.
|
||||
3. *Viewport*: is responsible for adding or removing child views in a parent view. (i.e. foreach, if)
|
||||
|
||||
Directives with an encapsulated view and an optional injector are called *Components*.
|
||||
|
||||
|
||||
## CSS Selectors
|
||||
|
||||
Decorators are instantiated whenever the decorator CSS selector matches the DOM structure.
|
||||
Directives are instantiated whenever the CSS selector matches the DOM structure.
|
||||
|
||||
Angular supports these CSS selector constructs:
|
||||
* Element name: `name`
|
||||
@ -26,15 +21,16 @@ Angular supports these CSS selector constructs:
|
||||
* Class: `.class`
|
||||
* AND operation: `name[attribute]`
|
||||
* OR operation: `name,.class`
|
||||
* NOT operation: `:not(.class)`
|
||||
|
||||
Angular does not support these (and any CSS selector which crosses element boundaries):
|
||||
* Descendant: `body div`
|
||||
* Direct descendant: `body > div`
|
||||
* Direct descendant: `body > div`
|
||||
* Adjacent: `div + table`
|
||||
* Sibling: `div ~ table`
|
||||
* Wildcard: `*`
|
||||
* ID: `#id`
|
||||
* Pseudo selectors: `:pseudo`
|
||||
* Pseudo selectors: `:pseudo` other than `:not`
|
||||
|
||||
|
||||
|
||||
@ -50,36 +46,36 @@ These CSS selectors will match:
|
||||
|
||||
CSS Selectors can be combined:
|
||||
* `input[type=text]`: Triggers on element name `input` which is of `type` `text`.
|
||||
* `input[type=text], textarea`: triggers on element name `input` which is of `type` `text` or element name `textarea`
|
||||
* `input[type=text], textarea`: triggers on element name `input` which is of `type` `text` or element name `textarea`.
|
||||
|
||||
|
||||
|
||||
## Decorators
|
||||
## Directives
|
||||
|
||||
The simplest kind of directive is a decorator. Directives are usefull for encapsulating behavior.
|
||||
|
||||
* Multiple decorators can be placed on a single element.
|
||||
* Decorators do not introduce new evaluation context.
|
||||
* Decorators are registered through the `@Decorator` meta-data annotation.
|
||||
* Directives do not introduce new evaluation context.
|
||||
* Directives are registered through the `@Directive` meta-data annotation.
|
||||
|
||||
Here is a trivial example of a tooltip decorator. The directive will log a tooltip into the console on every time mouse enters a region:
|
||||
|
||||
```
|
||||
@Decorator({
|
||||
selector: '[tooltip]', // CSS Selector which triggers the decorator
|
||||
bind: { // List which properties need to be bound
|
||||
text: 'tooltip' // - DOM element tooltip property should be
|
||||
}, // mapped to the directive text property.
|
||||
event: { // List which events need to be mapped.
|
||||
mouseover: 'show' // - Invoke the show() method every time
|
||||
} // the mouseover event is fired.
|
||||
})
|
||||
class Form { // Directive controller class, instantiated
|
||||
// when CSS matches.
|
||||
text:string; // text property on the Decorator Controller.
|
||||
|
||||
show(event) { // Show method which implements the show action.
|
||||
console.log(this.text);
|
||||
@Directive({
|
||||
selector: '[tooltip]', | CSS Selector which triggers the decorator
|
||||
properties: [ | List which properties need to be bound
|
||||
'text: tooltip' | - DOM element tooltip property should be
|
||||
], | mapped to the directive text property.
|
||||
hostListeners: { | List which events need to be mapped.
|
||||
mouseover: 'show' | - Invoke the show() method every time
|
||||
} | the mouseover event is fired.
|
||||
}) |
|
||||
class Form { | Directive controller class, instantiated
|
||||
| when CSS matches.
|
||||
text:string; | text property on the Directive Controller.
|
||||
|
|
||||
show(event) { | Show method which implements the show action.
|
||||
console.log(this.text); |
|
||||
}
|
||||
}
|
||||
```
|
||||
@ -112,23 +108,23 @@ Example of a component:
|
||||
```
|
||||
@Component({ | Component annotation
|
||||
selector: 'pane', | CSS selector on <pane> element
|
||||
bind: { | List which property need to be bound
|
||||
'title': 'title', | - title mapped to component title
|
||||
'open': 'open' | - open attribute mapped to component's open property
|
||||
}, |
|
||||
properties: [ | List which property need to be bound
|
||||
'title', | - title mapped to component title
|
||||
'open' | - open attribute mapped to component's open property
|
||||
], |
|
||||
}) |
|
||||
@Template({ | Template annotation
|
||||
url: 'pane.html' | - URL of template HTML
|
||||
@View({ | View annotation
|
||||
templateUrl: 'pane.html' | - URL of template HTML
|
||||
}) |
|
||||
class Pane { | Component controller class
|
||||
title:string; | - title property
|
||||
title:string; | - title property
|
||||
open:boolean;
|
||||
|
||||
|
||||
constructor() {
|
||||
this.title = '';
|
||||
this.open = true;
|
||||
}
|
||||
|
||||
|
||||
// Public API
|
||||
toggle() => this.open = !this.open;
|
||||
open() => this.open = true;
|
||||
@ -140,7 +136,7 @@ class Pane { | Component controller class
|
||||
```
|
||||
<div class="outer">
|
||||
<h1>{{title}}</h1>
|
||||
<div class="inner" [hidden]="!visible">
|
||||
<div class="inner" [hidden]="!open">
|
||||
<content></content>
|
||||
</div>
|
||||
</div>
|
||||
@ -163,39 +159,39 @@ Example of usage:
|
||||
|
||||
|
||||
|
||||
## Viewport
|
||||
## Directives that use a ViewContainer
|
||||
|
||||
Viewport is a directive which can control instantiation of child views which are then inserted into the DOM. (Examples are `if` and `foreach`.)
|
||||
Directives that use a ViewContainer can control instantiation of child views which are then inserted into the DOM. (Examples are `ng-if` and `ng-for`.)
|
||||
|
||||
* Viewports can only be placed on `<template>` elements (or the short hand version which uses `<element template>` attribute.)
|
||||
* Only one viewport can be present per DOM template element.
|
||||
* The viewport is created over the `template` element. This is known as the `ViewContainer`.
|
||||
* Viewport can insert child views into the `ViewContainer`. The child views show up as siblings of the `Viewport` in the DOM.
|
||||
* Every `template` element creates a `ProtoView` which can be used to create Views via the ViewContainer.
|
||||
* The child views show up as siblings of the directive in the DOM.
|
||||
|
||||
>> TODO(misko): Relationship with Injection
|
||||
>> TODO(misko): Instantiator can not be injected into child Views
|
||||
|
||||
|
||||
```
|
||||
@Viewport({
|
||||
@Directive({
|
||||
selector: '[if]',
|
||||
bind: {
|
||||
'condition': 'if'
|
||||
}
|
||||
properties: [
|
||||
'condition: if'
|
||||
]
|
||||
})
|
||||
export class If {
|
||||
viewContainer: ViewContainer;
|
||||
viewContainer: ViewContainerRef;
|
||||
protoViewRef: ProtoViewRef;
|
||||
view: View;
|
||||
|
||||
constructor(viewContainer: ViewContainer) {
|
||||
constructor(viewContainer: ViewContainerRef, protoViewRef: ProtoViewRef) {
|
||||
this.viewContainer = viewContainer;
|
||||
this.protoViewRef = protoViewRef;
|
||||
this.view = null;
|
||||
}
|
||||
|
||||
set condition(value) {
|
||||
if (value) {
|
||||
if (this.view === null) {
|
||||
this.view = this.viewContainer.create();
|
||||
this.view = this.viewContainer.create(protoViewRef);
|
||||
}
|
||||
} else {
|
||||
if (this.view !== null) {
|
||||
@ -213,37 +209,37 @@ Dependency Injection (DI) is a key aspect of directives. DI allows directives to
|
||||
|
||||
When Angular directives are instantiated, the directive can ask for other related directives to be injected into it. By assembling the directives in different order and subtypes the application behavior can be controlled. A good mental model is that the DOM structure controls the directive instantiation graph.
|
||||
|
||||
Directive instantiation is triggered by the directive CSS selector matching the DOM structure. The directive in its constructor can ask for other directives or application services. When asking for directives the dependency is locating by following the DOM hierarchy and if not found using the application level injector.
|
||||
Directive instantiation is triggered by the directive CSS selector matching the DOM structure. In a directive's constructor, it can ask for other directives or application services. When asking for directives, the dependency is attempted to be located by its DOM hierarchy first, then if not found, by using the application level injector.
|
||||
|
||||
To better understand the kinds of injections which are supported in Angular we have broken them down into use case examples.
|
||||
|
||||
|
||||
### Injecting Services
|
||||
|
||||
Service injection is the most straight forward kind of injection which Angular supports. It involves a component configuring the `services` and then letting the directive ask for the configured service.
|
||||
Service injection is the most straight forward kind of injection which Angular supports. It involves a component configuring the `appInjector` and then letting the directive ask for the configured service.
|
||||
|
||||
This example illustrates how to inject `MyService` into `House` directive.
|
||||
|
||||
|
||||
```
|
||||
class MyService {} | Assume a service which needs to be injected
|
||||
class MyService {} | Assume a service which needs to be injected
|
||||
| into a directive.
|
||||
|
|
||||
@Component({ | Assume a top level application component which
|
||||
@Component({ | Assume a top level application component which
|
||||
selector: 'my-app', | configures the services to be injected.
|
||||
services: [MyService] |
|
||||
appInjector: [MyService] |
|
||||
}) |
|
||||
@Template({ | Assume we have a template that needs to be
|
||||
url: 'my_app.html', | configured with directives to be injected.
|
||||
directives: [House] |
|
||||
@View({ | Assume we have a template that needs to be
|
||||
templateUrl: 'my_app.html', | configured with directives to be injected.
|
||||
directives: [House] |
|
||||
}) |
|
||||
class MyApp {} |
|
||||
|
|
||||
@Decorator({ | This is the directive into which we would like
|
||||
@Directive({ | This is the directive into which we would like
|
||||
selector: '[house]' | to inject the MyService.
|
||||
}) |
|
||||
class House { |
|
||||
constructor(myService:MyService) { | Notice that in the constructor we can simply
|
||||
constructor(myService:MyService) { | Notice that in the constructor we can simply
|
||||
} | ask for MyService.
|
||||
} |
|
||||
|
||||
@ -252,7 +248,7 @@ class House { |
|
||||
|
||||
Assume the following DOM structure for `my_app.html`:
|
||||
```
|
||||
<div house> | The house attribute triggers the creation of the House directive.
|
||||
<div house> | The house attribute triggers the creation of the House directive.
|
||||
</div> | This is equivalent to:
|
||||
| new House(injector.get(MyService));
|
||||
```
|
||||
@ -260,58 +256,58 @@ Assume the following DOM structure for `my_app.html`:
|
||||
|
||||
### Injecting other Directives
|
||||
|
||||
Injecting other directives into directives follows a similar mechanism as injecting services, but with added constraint of visibility governed by DOM structure.
|
||||
Injecting other directives into directives follows a similar mechanism as injecting services into directives, but with added constraint of visibility governed by DOM structure.
|
||||
|
||||
There are five kinds of visibilities:
|
||||
|
||||
* (no annotation): Inject dependant directives only if they are on the current element.
|
||||
* (no annotation): Inject dependant directives only if they are on the current element.
|
||||
* `@ancestor`: Inject a directive if it is at any element above the current element.
|
||||
* `@parent`: Inject a directive which is direct parent of the current element.
|
||||
* `@parent`: Inject a directive which is a direct parent of the current element.
|
||||
* `@child`: Inject a list of direct children which match a given type. (Used with `Query`)
|
||||
* `@descendant`: Inject a list of any children which match a given type. (Used with `Query`)
|
||||
|
||||
NOTE: if the injection constraint can not be satisfied by the current visibility constraint, then it is forward to the normal injector which may provide a default value for the directive or it may throw an error.
|
||||
NOTE: if the injection constraint can not be satisfied by the current visibility constraint, then it is forwarded to the normal injector which either provides a default value for the directive or throws an error.
|
||||
|
||||
Here is an example of the kinds of injections which can be achieved:
|
||||
|
||||
|
||||
```
|
||||
@Component({ |
|
||||
selector: 'my-app', |
|
||||
template: new TemplateConfig({ |
|
||||
url: 'my_app.html', |
|
||||
directives: [Form, FieldSet, |
|
||||
Field, Primary] |
|
||||
}) |
|
||||
selector: 'my-app' |
|
||||
}) |
|
||||
@View({ |
|
||||
templateUrl: 'my_app.html', |
|
||||
directives: [Form, FieldSet, |
|
||||
Field, Primary] |
|
||||
}) |
|
||||
class MyApp {} |
|
||||
|
|
||||
@Decorator({ selector: 'form' }) |
|
||||
@Directive({ selector: 'form' }) |
|
||||
class Form { |
|
||||
constructor( |
|
||||
@descendant sets:Query<FieldSet> |
|
||||
) { |
|
||||
} |
|
||||
) { |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
@Decorator({ selector: 'fieldset' }) |
|
||||
@Directive({ selector: 'fieldset' }) |
|
||||
class FieldSet { |
|
||||
constructor( |
|
||||
@child sets:Query<Field> |
|
||||
) { ... } |
|
||||
) { ... } |
|
||||
} |
|
||||
|
|
||||
@Decorator({ selector: 'field' }) |
|
||||
@Directive({ selector: 'field' }) |
|
||||
class Field { |
|
||||
constructor( |
|
||||
@ancestor field:Form, |
|
||||
@parent field:FieldSet, |
|
||||
) { ... } |
|
||||
) { ... } |
|
||||
} |
|
||||
|
|
||||
@Decorator({ selector: '[primary]'}) |
|
||||
@Directive({ selector: '[primary]'}) |
|
||||
class Primary { |
|
||||
constructor(field:Field ) { ... } |
|
||||
constructor(field:Field ) { ... } |
|
||||
} |
|
||||
```
|
||||
|
||||
@ -322,17 +318,74 @@ Assume the following DOM structure for `my_app.html`:
|
||||
<fieldset> |
|
||||
<field primary></field> |
|
||||
<field></field> |
|
||||
</div> |
|
||||
</fieldset> |
|
||||
</form> |
|
||||
</fieldset> |
|
||||
</div> |
|
||||
</form> |
|
||||
```
|
||||
|
||||
#### Shadow DOM effects on Directive DI
|
||||
|
||||
### Shadow DOM effects on Dependency Injection
|
||||
Shadow DOM provides an encapsulation for components, so as a general rule it does not allow directive injections to cross the shadow DOM boundaries. To remedy this, declaritively specify the required component as an injectable.
|
||||
|
||||
Shadow DOM provides an encapsulation for components, so as a general rule it does not allow directive injections to cross the shadow DOM boundaries.
|
||||
```
|
||||
@Component({
|
||||
selector: '[kid]',
|
||||
appInjector: []
|
||||
})
|
||||
@View({
|
||||
templateUrl: 'kid.html',
|
||||
directives: []
|
||||
})
|
||||
class Kid {
|
||||
constructor(
|
||||
@Parent() dad:Dad,
|
||||
@Optional() grandpa:Grandpa
|
||||
) {
|
||||
this.name = 'Billy';
|
||||
this.dad = dad.name;
|
||||
this.grandpa = grandpa.name;
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: '[dad]',
|
||||
appInjector: [Grandpa]
|
||||
})
|
||||
@View({
|
||||
templateUrl: 'dad.html',
|
||||
directives: [Kid]
|
||||
})
|
||||
class Dad {
|
||||
constructor(@Parent() dad:Grandpa) {
|
||||
this.name = 'Joe Jr';
|
||||
this.dad = dad.name;
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: '[grandpa]',
|
||||
appInjector: []
|
||||
})
|
||||
@View({
|
||||
templateUrl: 'grandpa.html',
|
||||
directives: [Dad]
|
||||
})
|
||||
class Grandpa {
|
||||
constructor() {
|
||||
this.name = 'Joe';
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Assume the following DOM structure for `grandpa.html`: The Dad has access to the Grandpa.
|
||||
```
|
||||
Name: {{name}}: <br> Children: <div dad></div>
|
||||
```
|
||||
|
||||
Assume the following DOM structure for `dad.html`: Here the rendered Kid will also have access to Grandpa.
|
||||
```
|
||||
Name: {{name}}: <br> Dad: {{dad}} <br> Children: <div kid></div>
|
||||
```
|
||||
|
||||
## Further Reading
|
||||
|
||||
|
@ -1,15 +0,0 @@
|
||||
# Formatters
|
||||
|
||||
Formatters can be appended on the end of the expressions to translate the value to a different format. Typically used
|
||||
to control the stringification of numbers, dates, and other data, but can also be used for ordering, mapping, and
|
||||
reducing arrays. Formatters can be chained.
|
||||
|
||||
NOTE: Formatters are known as filters in Angular v1.
|
||||
|
||||
Formatters syntax is:
|
||||
|
||||
```
|
||||
// TODO: provide syntax of formatter here
|
||||
```
|
||||
|
||||
|
27
modules/angular2/docs/core/03_pipes.md
Normal file
27
modules/angular2/docs/core/03_pipes.md
Normal file
@ -0,0 +1,27 @@
|
||||
# Pipes
|
||||
|
||||
Pipes can be appended on the end of the expressions to translate the value to a different format. Typically used
|
||||
to control the stringification of numbers, dates, and other data, but can also be used for ordering, mapping, and
|
||||
reducing arrays. Pipes can be chained.
|
||||
|
||||
NOTE: Pipes are known as filters in Angular v1.
|
||||
|
||||
Pipes syntax is:
|
||||
|
||||
```
|
||||
<div class="movie-copy">
|
||||
<p>
|
||||
{{ model.getValue('copy') | async | uppercase }}
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<b>Starring</b>: {{ model.getValue('starring') | async }}
|
||||
</li>
|
||||
<li>
|
||||
<b>Genres</b>: {{ model.getValue('genres') | async }}
|
||||
</li>
|
||||
<ul>
|
||||
</div>
|
||||
```
|
||||
|
||||
|
@ -2,24 +2,24 @@
|
||||
|
||||
## Overview
|
||||
|
||||
This document explains the concept of a View.
|
||||
A View is a core primitive used by angular to render the DOM tree.
|
||||
A ViewPort is location in a View which can accept child Views.
|
||||
Every ViewPort has an associated ViewContainer than can contain any number of child Views.
|
||||
This document explains the concept of a View.
|
||||
A View is a core primitive used by angular to render the DOM tree.
|
||||
A ViewContainer is location in a View which can accept child Views.
|
||||
Every ViewContainer has an associated ViewContainerRef than can contain any number of child Views.
|
||||
Views form a tree structure which mimics the DOM tree.
|
||||
|
||||
* View is a core rendering construct. A running application is just a collection of Views which are
|
||||
nested in a tree like structure. The View tree is a simplified version of the DOM tree. A View can
|
||||
have a single DOM Element or large DOM structures. The key is that the DOM tree in the View can
|
||||
* View is a core rendering construct. A running application is just a collection of Views which are
|
||||
nested in a tree like structure. The View tree is a simplified version of the DOM tree. A View can
|
||||
have a single DOM Element or large DOM structures. The key is that the DOM tree in the View can
|
||||
not undergo structural changes (only property changes).
|
||||
* Views represent a running instance of a DOM Template. This implies that while elements in a View
|
||||
can change properties, they can not change structurally. (Structural changes such as, adding or
|
||||
* Views represent a running instance of a DOM View. This implies that while elements in a View
|
||||
can change properties, they can not change structurally. (Structural changes such as, adding or
|
||||
removing elements requires adding or removing child Views into ViewContainers).
|
||||
* View can have zero or more ViewPorts. A ViewPort is a marker in the DOM which allows
|
||||
* View can have zero or more ViewContainers. A ViewContainer is a marker in the DOM which allows
|
||||
the insertion of child Views.
|
||||
* Views are created from a ProtoView. A ProtoView is a compiled DOM Template which is efficient at
|
||||
* Views are created from a ProtoView. A ProtoView is a compiled DOM View which is efficient at
|
||||
creating Views.
|
||||
* View contains a context object. The context represents the object instance against which all
|
||||
* View contains a context object. The context represents the object instance against which all
|
||||
expressions are evaluated.
|
||||
* View contains a ChangeDetector for looking for detecting changes to the model.
|
||||
* View contains ElementInjector for creating Directives.
|
||||
@ -40,7 +40,7 @@ class Greeter {
|
||||
}
|
||||
```
|
||||
|
||||
And assume following HTML Template:
|
||||
And assume following HTML View:
|
||||
|
||||
```
|
||||
<div>
|
||||
@ -51,9 +51,9 @@ And assume following HTML Template:
|
||||
</div>
|
||||
```
|
||||
|
||||
The above template is compiled by the Compiler to create a ProtoView. The ProtoView is then used to
|
||||
create an instance of the View. The instantiation process involves cloning the above template and
|
||||
locating all of the elements which contain bindings and finally instantiating the Directives
|
||||
The above template is compiled by the Compiler to create a ProtoView. The ProtoView is then used to
|
||||
create an instance of the View. The instantiation process involves cloning the above template and
|
||||
locating all of the elements which contain bindings and finally instantiating the Directives
|
||||
associated with the template. (See compilation for more details.)
|
||||
|
||||
```
|
||||
@ -81,20 +81,20 @@ Note:
|
||||
* View knows which expressions need to be watched.
|
||||
* View knows what needs to be updated if the watched expression changes.
|
||||
* All DOM elements are owned by single instance of the view.
|
||||
* The structure of the DOM can not change during runtime. To allow structural changes to the DOM we need
|
||||
* The structure of the DOM can not change during runtime. To allow structural changes to the DOM we need
|
||||
to understand Composed View.
|
||||
|
||||
|
||||
## Composed View
|
||||
|
||||
An important part of an application is to be able to change the DOM structure to render data for the
|
||||
user. In Angular this is done by inserting child views into the ViewPort.
|
||||
An important part of an application is to be able to change the DOM structure to render data for the
|
||||
user. In Angular this is done by inserting child views into the ViewContainer.
|
||||
|
||||
Let's start with a Template such as:
|
||||
Let's start with a View such as:
|
||||
|
||||
```
|
||||
<ul>
|
||||
<li template="foreach: person in people">{{person}}</li>
|
||||
<li template="ng-for: #person of people">{{person}}</li>
|
||||
</ul>
|
||||
```
|
||||
|
||||
@ -108,7 +108,7 @@ and
|
||||
|
||||
```
|
||||
<ul> | protoViewA(someContext)
|
||||
<template></template> | protoViewA(someContext): new ProtoViewPort(protoViewB)
|
||||
<template></template> | protoViewA(someContext): protoViewB
|
||||
</ul> | protoViewA(someContext)
|
||||
```
|
||||
|
||||
@ -119,49 +119,49 @@ The next step is to compose these two ProtoViews into an actual view which is re
|
||||
|
||||
```
|
||||
<ul> | viewA(someContext)
|
||||
<template></template> | viewA(someContext): new Foreach(new ViewPort(protoViewB))
|
||||
<template></template> | viewA(someContext): new NgFor(new ViewContainer(protoViewB))
|
||||
</ul> | viewA(someContext)
|
||||
```
|
||||
|
||||
*Step2:* Instantiate `Foreach` directive which will receive the `ViewContainer`. (The ViewContainer
|
||||
*Step2:* Instantiate `NgFor` directive which will receive the `ViewContainerRef`. (The ViewContainerRef
|
||||
has a reference to `protoViewA`).
|
||||
|
||||
|
||||
*Step3:* As the `Foreach` directive unrolls it asks the `ViewContainer` to instantiate `protoViewB` and insert
|
||||
it after the `ViewPort` anchor. This is repeated for each `person` in `people`. Notice that
|
||||
*Step3:* As the `NgFor` directive unrolls it asks the `ViewContainerRef` to instantiate `protoViewB` and insert
|
||||
it after the `ViewContainer` anchor. This is repeated for each `person` in `people`. Notice that
|
||||
|
||||
```
|
||||
<ul> | viewA(someContext)
|
||||
<template></template> | viewA(someContext): new Foreach(new ViewPort(protoViewB))
|
||||
<template></template> | viewA(someContext): new NgFor(new ViewContainer(protoViewB))
|
||||
<li>{{person}}</li> | viewB0(locals0(someContext))
|
||||
<li>{{person}}</li> | viewB1(locals0(someContext))
|
||||
</ul> | viewA(someContext)
|
||||
```
|
||||
|
||||
*Step4:* All of the bindings in the child Views are updated. Notice that in the case of `Foreach`
|
||||
the evaluation context for the `viewB0` and `viewB1` are `locals0` and `locals1` respectively.
|
||||
Locals allow the introduction of new local variables visible only within the scope of the View, and
|
||||
*Step4:* All of the bindings in the child Views are updated. Notice that in the case of `NgFor`
|
||||
the evaluation context for the `viewB0` and `viewB1` are `locals0` and `locals1` respectively.
|
||||
Locals allow the introduction of new local variables visible only within the scope of the View, and
|
||||
delegate any unknown references to the parent context.
|
||||
|
||||
```
|
||||
<ul> | viewA
|
||||
<template></template> | viewA: new Foreach(new ViewPort(protoViewB))
|
||||
<template></template> | viewA: new NgFor(new ViewContainer(protoViewB))
|
||||
<li>Alice</li> | viewB0
|
||||
<li>Bob</li> | viewB1
|
||||
</ul> | viewA
|
||||
```
|
||||
|
||||
Each View can have zero or more ViewPorts. By inserting and removing child Views to and from the
|
||||
ViewContainers, the application can mutate the DOM structure to any desirable state. A View may contain
|
||||
individual nodes or a complex DOM structure. The insertion points for the child Views, known as
|
||||
ViewContainers, contain a DOM element which acts as an anchor. The anchor is either a `template` or
|
||||
a `script` element depending on your browser. It is used to identify where the child Views will be
|
||||
Each View can have zero or more ViewContainers. By inserting and removing child Views to and from the
|
||||
ViewContainers, the application can mutate the DOM structure to any desirable state. A View may contain
|
||||
individual nodes or a complex DOM structure. The insertion points for the child Views, known as
|
||||
ViewContainers, contain a DOM element which acts as an anchor. The anchor is either a `template` or
|
||||
a `script` element depending on your browser. It is used to identify where the child Views will be
|
||||
inserted.
|
||||
|
||||
## Component Views
|
||||
|
||||
A View can also contain Components. Components contain Shadow DOM for encapsulating their internal
|
||||
rendering state. Unlike ViewPorts which can contain zero or more Views, the Component always contains
|
||||
A View can also contain Components. Components contain Shadow DOM for encapsulating their internal
|
||||
rendering state. Unlike ViewContainers which can contain zero or more Views, the Component always contains
|
||||
exactly one Shadow View.
|
||||
|
||||
```
|
||||
@ -194,7 +194,7 @@ class Greeter {
|
||||
}
|
||||
```
|
||||
|
||||
And assume the following HTML Template:
|
||||
And assume the following HTML View:
|
||||
|
||||
```
|
||||
<div> | viewA(greeter)
|
||||
@ -205,7 +205,7 @@ And assume the following HTML Template:
|
||||
</div> | viewA(greeter)
|
||||
```
|
||||
|
||||
The above UI is built using a single View, and hence a single context `greeter`. It can be expressed
|
||||
The above UI is built using a single View, and hence a single context `greeter`. It can be expressed
|
||||
in this pseudo-code.
|
||||
|
||||
```
|
||||
@ -215,15 +215,15 @@ var greeter = new Greeter();
|
||||
The View contains two bindings:
|
||||
|
||||
1. `greeting`: This is bound to the `greeting` property on the `Greeter` instance.
|
||||
2. `name.value`: This poses a problem. There is no `name` property on the `Greeter` instance. To solve
|
||||
2. `name.value`: This poses a problem. There is no `name` property on the `Greeter` instance. To solve
|
||||
this we wrap the `Greeter` instance in the `Local` instance like so:
|
||||
```
|
||||
var greeter = new Locals(new Greeter(), {name: ref_to_input_element })
|
||||
```
|
||||
|
||||
|
||||
By wrapping the `Greeter` instance into the `Locals` we allow the view to introduce variables which
|
||||
are in addition to the `Greeter` instance. During the resolution of the expressions we first check
|
||||
By wrapping the `Greeter` instance into the `Locals` we allow the view to introduce variables which
|
||||
are in addition to the `Greeter` instance. During the resolution of the expressions we first check
|
||||
the locals, and then the `Greeter` instance.
|
||||
|
||||
|
||||
@ -233,14 +233,14 @@ the locals, and then the `Greeter` instance.
|
||||
Views transition through a particular set of states:
|
||||
|
||||
1. View is created from the ProtoView.
|
||||
2. View can be attached to an existing ViewContainer.
|
||||
3. Upon attaching View to the ViewContainer the View needs to be hydrated. The hydration process
|
||||
2. View can be attached to an existing ViewContainerRef.
|
||||
3. Upon attaching View to the ViewContainerRef the View needs to be hydrated. The hydration process
|
||||
involves instantiating all of the Directives associated with the current View.
|
||||
4. At this point the view is ready and renderable. Multiple changes can be delivered to the
|
||||
4. At this point the view is ready and renderable. Multiple changes can be delivered to the
|
||||
Directives from the ChangeDetection.
|
||||
5. At some point the View can be removed. At this point all of the directives are destroyed during
|
||||
5. At some point the View can be removed. At this point all of the directives are destroyed during
|
||||
the dehydration process and the view becomes inactive.
|
||||
6. The View has to wait until it is detached from the DOM. The delay in detaching could be caused
|
||||
6. The View has to wait until it is detached from the DOM. The delay in detaching could be caused
|
||||
because an animation is animating the view away.
|
||||
7. After the View is detached from the DOM it is ready to be reused. The view reuse allows the
|
||||
7. After the View is detached from the DOM it is ready to be reused. The view reuse allows the
|
||||
application to be faster in subsequent renderings.
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user