Compare commits
893 commits
Author | SHA1 | Date | |
---|---|---|---|
|
98081097b4 | ||
|
f753392d49 | ||
|
38a209a970 | ||
|
bd7bf20810 | ||
|
955ebdd747 | ||
|
fdcd8a93f1 | ||
|
b5c52adf5e | ||
|
b7761a3627 | ||
|
e0d72fce14 | ||
|
139fdf8e2b | ||
|
4313f6eff8 | ||
|
91c004ebfd | ||
|
96056f43ef | ||
|
32e58fa8af | ||
|
5ebbd87afc | ||
|
006920b686 | ||
|
97448b389f | ||
|
f1ecc9eb0b | ||
|
ca2684fcf3 | ||
|
d9c53514fe | ||
|
e195b89bbd | ||
|
e66498a861 | ||
|
901eb4a513 | ||
|
cbf44e3dfe | ||
|
8b492d6dc8 | ||
|
b83f366284 | ||
|
1ac06d973c | ||
|
9af3754bc8 | ||
|
8169f24072 | ||
|
b9fb4a2829 | ||
|
9b52d0e081 | ||
|
14dc3687cd | ||
|
0a6e7918ef | ||
|
4a7595e76d | ||
|
e899179314 | ||
|
44fec58985 | ||
|
29a25c28a8 | ||
|
76c727cd61 | ||
|
693e6f5e10 | ||
|
a1d4c99ff6 | ||
|
55f2425501 | ||
|
f9c139c19e | ||
|
d51a22c5a9 | ||
|
567bc9d69d | ||
|
15f512efef | ||
|
5e6fb6290c | ||
|
8695297a0f | ||
|
216a19476b | ||
|
a0c9530c91 | ||
|
277644f59d | ||
|
0ffc01b3fb | ||
|
9471efb6bd | ||
|
fc8ac6eef1 | ||
|
9cc700c64d | ||
|
64ffc78f45 | ||
|
322da431eb | ||
|
3c7c8812a4 | ||
|
0d6963ebb0 | ||
|
c4d0bf8ce4 | ||
|
3406f2e04d | ||
|
a4c905df4e | ||
|
5f1fe4dc3f | ||
|
2515073393 | ||
|
a04cd0d395 | ||
|
da9e44afa0 | ||
|
e290244404 | ||
|
6e1878413f | ||
|
77846cfcb7 | ||
|
1ffc513617 | ||
|
3886e62a7b | ||
|
ad2ba33db6 | ||
|
cf9f54c738 | ||
|
f323796030 | ||
|
a080b82e7f | ||
|
1174123b60 | ||
|
35f77129ad | ||
|
a56991aede | ||
|
672b456193 | ||
|
21518c8696 | ||
|
29bf2a23e8 | ||
|
61eac509de | ||
|
4cc420eb63 | ||
|
ec3e09c578 | ||
|
3e03e0ebbf | ||
|
9ab7e7e170 | ||
|
5af2b8f216 | ||
|
8af66b1b2c | ||
|
9b2193ad8c | ||
|
1a8c7810be | ||
|
d87bb7c75c | ||
|
aceb3ff31e | ||
|
f26c6cf0b7 | ||
|
42f4ecb37b | ||
|
64f4249f44 | ||
|
958bd8c70c | ||
|
3830946723 | ||
|
3482e799fd | ||
|
e016b923a4 | ||
|
bb546779cd | ||
|
3829d32390 | ||
|
9783a5ee1e | ||
|
12fc0c71f6 | ||
|
c2cb8949eb | ||
|
4e7bf02749 | ||
|
3203c2b4d0 | ||
|
1ec9dc20e4 | ||
|
1af4728073 | ||
|
785e16eeae | ||
|
d08cb3f95e | ||
|
271fc7ebd0 | ||
|
9d590295cb | ||
|
dc4d44951e | ||
|
767414ad9f | ||
|
1ec897b8c8 | ||
|
00e2aefb4e | ||
|
aec0f104b8 | ||
|
db6d2e77da | ||
|
9585dce511 | ||
|
78acd7e0b0 | ||
|
328c1a14f3 | ||
|
10ac64c574 | ||
|
edce66c44d | ||
|
74df2559a4 | ||
|
a6694a3f72 | ||
|
8c7a657499 | ||
|
90f77cd4f7 | ||
|
af4dc869c0 | ||
|
2cae12e1ab | ||
|
49102ea474 | ||
|
f2a7cc1f19 | ||
|
a5d5cd6000 | ||
|
391a1d8b24 | ||
|
cc17c1ed38 | ||
|
eee1febbf9 | ||
|
c8f6374ac8 | ||
|
ed76162b63 | ||
|
1eb4187691 | ||
|
4a7dd54aca | ||
|
efd6258c7e | ||
|
f4d1b8ba35 | ||
|
47a74dd77b | ||
|
33276444c7 | ||
|
1124d76475 | ||
|
4ffa9460f5 | ||
|
44753dbfe1 | ||
|
77f76b1b5a | ||
|
e544d6a6db | ||
|
780e66632b | ||
|
de4f51bb5c | ||
|
5d0da4c5f1 | ||
|
9079d1bffc | ||
|
962881a35d | ||
|
8483b62603 | ||
|
e3b4dac1e1 | ||
|
8998e3858c | ||
|
ce51eeca8c | ||
|
3178f6e650 | ||
|
7ee96bf6c6 | ||
|
b740fef8fe | ||
|
55b031ccb7 | ||
|
9df389060e | ||
|
153cc38d1a | ||
|
4ff9619837 | ||
|
a6c1c0c730 | ||
|
529dec09a3 | ||
|
ddbaac513f | ||
|
ba943b20f1 | ||
|
4deb3f5ab9 | ||
|
47d0faadf2 | ||
|
9800cc27c6 | ||
|
7840e09e5f | ||
|
687b957737 | ||
|
9ce989eba5 | ||
|
2c85590d65 | ||
|
2b34d84715 | ||
|
013e3c7f21 | ||
|
8d771543d8 | ||
|
50639e8a0a | ||
|
9d52aa9c74 | ||
|
545706e17a | ||
|
95901e17e8 | ||
|
9dbbdf1150 | ||
|
4ee4aeaad2 | ||
|
bfdce21a66 | ||
|
53d4beddec | ||
|
d455ced683 | ||
|
d8698ef6f2 | ||
|
1374da35da | ||
|
2d0d0403b1 | ||
|
2d50f24be6 | ||
|
876c61a18e | ||
|
b0deafc53e | ||
|
a647d80efa | ||
|
559ad230ce | ||
|
26dfcbf823 | ||
|
915defcd1b | ||
|
dde097ea75 | ||
|
3706cd83e7 | ||
|
575a3ec8bf | ||
|
b2bf9978aa | ||
|
0441850504 | ||
|
3ae4072b5d | ||
|
00ecb0f6bb | ||
|
45a15da896 | ||
|
a96c8ae75c | ||
|
a137c21d2d | ||
|
952cf4e79f | ||
|
53bc4ee1c8 | ||
|
c60f7f4525 | ||
|
8df2cd8732 | ||
|
2c6da79df3 | ||
|
6e913efbae | ||
|
db81962c91 | ||
|
8330ef9679 | ||
|
696ff396b0 | ||
|
b16617286f | ||
|
fee011bba6 | ||
|
d16709e8e7 | ||
|
0ad10c0f5a | ||
|
d11278b63b | ||
|
2652d53e9b | ||
|
dc8d274487 | ||
|
2fd972ddce | ||
|
bba8231e8c | ||
|
1229e92feb | ||
|
ba3d5f07dd | ||
|
d47d7e50e7 | ||
|
af2c6ebef1 | ||
|
a9f19815e4 | ||
|
460de840b6 | ||
|
36ed85312e | ||
|
991c4cabdb | ||
|
38004c1f1f | ||
|
cd796f3ade | ||
|
c57015cb15 | ||
|
9223295320 | ||
|
b4bffbe427 | ||
|
6296df1102 | ||
|
2e0acfc170 | ||
|
99b21be27b | ||
|
2c60d7335c | ||
|
6f6e5bea06 | ||
|
6f0d391aaa | ||
|
b1a64c6e7a | ||
|
59b3d254dd | ||
|
f3539f54bf | ||
|
75ccfb0ab3 | ||
|
7b5bd53c28 | ||
|
5302f03196 | ||
|
536c458981 | ||
|
f64612f99b | ||
|
cbc38e0c93 | ||
|
42d671c05b | ||
|
08109ee5de | ||
|
0952c0f3c9 | ||
|
25b4d388de | ||
|
8b738f3d28 | ||
|
da94cd0c8b | ||
|
e9e6b1dc09 | ||
|
e84dfbaa33 | ||
|
cb95e027c4 | ||
|
8e50efb3c1 | ||
|
5ab5f6fec2 | ||
|
cbf1ec3afb | ||
|
d3315d962d | ||
|
ae05fb35d3 | ||
|
9e6ce90950 | ||
|
3868910dde | ||
|
5c1261892f | ||
|
9ada1ca935 | ||
|
df5cc4e1a8 | ||
|
ce073028c8 | ||
|
7d869d7b63 | ||
|
73e8f2d4c8 | ||
|
68f0e91259 | ||
|
b07941834c | ||
|
b914065bb3 | ||
|
33fc27ffd1 | ||
|
7ca7f0862f | ||
|
c604e69d77 | ||
|
fb12c7e202 | ||
|
9ab1c9c647 | ||
|
28d960459e | ||
|
ef84209de1 | ||
|
2d920cf66a | ||
|
40a97a5ae9 | ||
|
186129807e | ||
|
87228c27c1 | ||
|
6d8392d2e7 | ||
|
0960159265 | ||
|
88e98c7342 | ||
|
3f6f020ce1 | ||
|
8e958ec9a8 | ||
|
9debcdde39 | ||
|
b4ad51e69d | ||
|
9b95e91f1a | ||
|
c46e85529e | ||
|
85408a14d3 | ||
|
3b8a5d0c2e | ||
|
6f88c2a7eb | ||
|
f1e62fb6c1 | ||
|
0c52188014 | ||
|
7c0e0f731f | ||
|
1ba339b3be | ||
|
6129a27ecf | ||
|
d51e3f3b52 | ||
|
1317186f63 | ||
|
d6527ea80e | ||
|
a133702be2 | ||
|
d2074ada79 | ||
|
00286fcc29 | ||
|
01cd624bfa | ||
|
a5f793fe54 | ||
|
d1aa62d382 | ||
|
3f161c1076 | ||
|
4da3a9d55f | ||
|
90c5bc26fc | ||
|
5d8ff3efce | ||
|
95b8b52224 | ||
|
55853c60f4 | ||
|
5b90c38b22 | ||
|
c03d6dd5f6 | ||
|
51d5d77629 | ||
|
ce2d462578 | ||
|
4533a0f2fe | ||
|
5851d57eef | ||
|
e1441acde0 | ||
|
d1f75c8c24 | ||
|
83b58d43d5 | ||
|
3759851621 | ||
|
a176cdf231 | ||
|
9df974a037 | ||
|
bd4072f81c | ||
|
6a2646c9cd | ||
|
2f4fe525ce | ||
|
518782e1c7 | ||
|
7c9b6a2205 | ||
|
8026969799 | ||
|
4b500a4428 | ||
|
0778179ba7 | ||
|
bfd23c6d32 | ||
|
9cb3074245 | ||
|
e4d193572f | ||
|
0f85abfda2 | ||
|
887c3f7570 | ||
|
667f5653a7 | ||
|
48b93b2269 | ||
|
9ad4684825 | ||
|
f516e1e73d | ||
|
2588636837 | ||
|
644df6fcdc | ||
|
c10a4f4837 | ||
|
304722b528 | ||
|
a9c67e70d4 | ||
|
ed3e4780d2 | ||
|
b013499c76 | ||
|
5270c5a611 | ||
|
5cfa8ffdc7 | ||
|
814c1acc0f | ||
|
62e2acdd52 | ||
|
151e96f803 | ||
|
bc1f212c93 | ||
|
b9190233b1 | ||
|
5e0e44b436 | ||
|
1fbfd56d57 | ||
|
a32f98bde2 | ||
|
6cc827d11c | ||
|
de16420796 | ||
|
e49e5c258a | ||
|
4dc32d7d2e | ||
|
9d821c920b | ||
|
6b1220b533 | ||
|
4f3d12d7a5 | ||
|
7b4a072fd8 | ||
|
175a3ee73e | ||
|
b13587456d | ||
|
f023a18069 | ||
|
e640048386 | ||
|
98725b3ee4 | ||
|
8a95262f2c | ||
|
ed89f80f49 | ||
|
47bca5907e | ||
|
5163794698 | ||
|
0b6348e13f | ||
|
ce1205f6d7 | ||
|
96d25cc91d | ||
|
a9ef6feebd | ||
|
98e2de68da | ||
|
4c68fd90ca | ||
|
cda0c21a0b | ||
|
a44edbb17e | ||
|
aa96d074af | ||
|
4f9b9460ad | ||
|
a63cd02bc6 | ||
|
fb6c8a74a7 | ||
|
5db8e27496 | ||
|
87dc20fa50 | ||
|
154257d062 | ||
|
497c6ae017 | ||
|
9600983311 | ||
|
cbcdd912c9 | ||
|
1d13da4ab5 | ||
|
d359eb063a | ||
|
4187dbd803 | ||
|
d549083cce | ||
|
bc8660c83e | ||
|
c0b35280f6 | ||
|
31078c554e | ||
|
ea20ba45b3 | ||
|
37b989c38e | ||
|
759ec7845b | ||
|
cfb8f51214 | ||
|
1cd7e22c40 | ||
|
ad1889dfc5 | ||
|
cbc8e6cdd4 | ||
|
f8556c30a5 | ||
|
8af1e69460 | ||
|
d1e8ecbf3b | ||
|
8e38469b1f | ||
|
abb997c75c | ||
|
be8efa6025 | ||
|
439527c464 | ||
|
f68deea202 | ||
|
b61cdb04fc | ||
|
5c67fcbff7 | ||
|
2eeb0a671f | ||
|
fb427a11f0 | ||
|
7a09a1c620 | ||
|
103ed5cbd7 | ||
|
b1a7e548a2 | ||
|
52c340b8f5 | ||
|
9299ca5f2c | ||
|
261ed49977 | ||
|
e2d9b6aef2 | ||
|
1042fb020d | ||
|
7f1c04015e | ||
|
f75d5253b3 | ||
|
bb6566a45e | ||
|
2529e0d44f | ||
|
139837e997 | ||
|
d8cd536a95 | ||
|
29913cd10b | ||
|
d004e98ada | ||
|
d2e097fd05 | ||
|
fe0da255dd | ||
|
6e75274737 | ||
|
6c9d464a9f | ||
|
517cfcb913 | ||
|
0ee1b3284a | ||
|
b976c13db2 | ||
|
c0955d7c5e | ||
|
332bb2ec08 | ||
|
179849b639 | ||
|
4f6dae304c | ||
|
3479fb7ff7 | ||
|
c113253fc5 | ||
|
e46aa54ba3 | ||
|
4602ded8a4 | ||
|
14ea18a967 | ||
|
8180a8cc71 | ||
|
da5191171a | ||
|
26a8cddd14 | ||
|
407ac1f29c | ||
|
fc2849824f | ||
|
6f3c74b7f1 | ||
|
c3dbd59280 | ||
|
0e7e649f56 | ||
|
6e03132f1b | ||
|
b2a4acc99d | ||
|
7eae8deacb | ||
|
62c489cba7 | ||
|
3051723bcf | ||
|
858ca66d69 | ||
|
a0c0dcbc79 | ||
|
6e6d33abbe | ||
|
8b1d85c3ca | ||
|
56d3ef8bea | ||
|
ba9e26bc05 | ||
|
9ac24f7468 | ||
|
fe1c57b458 | ||
|
9d85dab975 | ||
|
ab76b77bdd | ||
|
9513087bbd | ||
|
2c64b67abd | ||
|
be6a2401b6 | ||
|
0764133d11 | ||
|
129e3db946 | ||
|
7eacda2ae7 | ||
|
f775629371 | ||
|
0085ce71e6 | ||
|
fc044294f1 | ||
|
20da1ef39f | ||
|
42bb2cd86a | ||
|
dc55bae243 | ||
|
b6da38e29e | ||
|
2b036bfb4e | ||
|
3e4ff59a82 | ||
|
08f89ee630 | ||
|
86a6e92bc3 | ||
|
b978247785 | ||
|
0aeb6caadb | ||
|
97d2868fad | ||
|
658f102a4e | ||
|
b52523e7be | ||
|
e72ae5df94 | ||
|
a56c4eb110 | ||
|
85dcad928f | ||
|
a79d6a824c | ||
|
38c323a18a | ||
|
518773d6e1 | ||
|
33bcfc1505 | ||
|
d80d33761d | ||
|
df59c28aa8 | ||
|
b4d1250959 | ||
|
c0a220abc9 | ||
|
eb4073c228 | ||
|
98fae4b721 | ||
|
0cfbe41d95 | ||
|
c256d0891b | ||
|
6d6a5099e9 | ||
|
8d613eab33 | ||
|
d193c9a53c | ||
|
40453242fa | ||
|
12417d8cd3 | ||
|
e3db00f229 | ||
|
e2c0ce7c22 | ||
|
113a5a2530 | ||
|
959260f234 | ||
|
dbc2ff75df | ||
|
df29e48d8c | ||
|
2eae89a6b7 | ||
|
c90460802e | ||
|
a9831946d0 | ||
|
bf733b57d2 | ||
|
15b8440fbc | ||
|
c58a8da1a6 | ||
|
8afef1bc4a | ||
|
8ac8aad105 | ||
|
2466a0912f | ||
|
3d7a2ef5b1 | ||
|
a2cde20f8f | ||
|
da3795a2c2 | ||
|
6d2efefbbc | ||
|
7d0b56da19 | ||
|
87228a9631 | ||
|
0f740e751a | ||
|
afa4422608 | ||
|
7ec9feff80 | ||
|
b3c7e12d9a | ||
|
bc139608c2 | ||
|
05c1e4c60d | ||
|
ca981898d4 | ||
|
77d353464b | ||
|
8f230736dc | ||
|
bb013787b6 | ||
|
20a32afe3b | ||
|
c5564e02fc | ||
|
4949f0dbd6 | ||
|
99d07d2d65 | ||
|
fdf03ac83a | ||
|
1562d8fcfe | ||
|
e5e8a3dcbb | ||
|
e093ca5a30 | ||
|
4328a6205f | ||
|
01872e740e | ||
|
6ae391265e | ||
|
ea18479822 | ||
|
0e79f2ae4b | ||
|
7156fab3e2 | ||
|
97c118a20b | ||
|
b396b94477 | ||
|
e916ea32dc | ||
|
816d5adf94 | ||
|
8864dbbdcf | ||
|
44a183ed7b | ||
|
e4e6043ded | ||
|
24caafba74 | ||
|
3b8199aac6 | ||
|
2f0b0f39e5 | ||
|
1d4d7f07e2 | ||
|
9af3f04f4d | ||
|
ec8dbbb4a7 | ||
|
26977d06a8 | ||
|
1bbc72fff0 | ||
|
bca85337cc | ||
|
e858a2a773 | ||
|
ee9a49d7c6 | ||
|
88297b4eaa | ||
|
93341719a9 | ||
|
db3cf0490f | ||
|
9605b24640 | ||
|
e8746ee7d9 | ||
|
a37f60060c | ||
|
4e506ad290 | ||
|
67c4912c62 | ||
|
10a2782f85 | ||
|
2c3b387e42 | ||
|
d6a239d6b4 | ||
|
466b1716a5 | ||
|
9699b41159 | ||
|
c1acaba941 | ||
|
5b9eedc830 | ||
|
5065655436 | ||
|
3ee8d41298 | ||
|
f75ad41a82 | ||
|
bb87c9c2db | ||
|
a8b698b11c | ||
|
cc412ac491 | ||
|
ac60370d6f | ||
|
40b7e95b68 | ||
|
743c9b3af9 | ||
|
a86101dda0 | ||
|
8f0b350a2d | ||
|
c60e103d97 | ||
|
7150b9fcce | ||
|
bc8ce0fee4 | ||
|
12cb675bb5 | ||
|
c9a79468f4 | ||
|
ebaae084ae | ||
|
e646585a7a | ||
|
0e17ec11ec | ||
|
5649798e4b | ||
|
c20e503785 | ||
|
17870e7a4c | ||
|
b49cb7766a | ||
|
fb563c6eed | ||
|
03ba3a89f1 | ||
|
05495b0224 | ||
|
18d8929bf1 | ||
|
50f98aebea | ||
|
dad048eb20 | ||
|
c76de5b1d5 | ||
|
3f9077b380 | ||
|
b722d2d3b0 | ||
|
5e180ac10e | ||
|
686d80e274 | ||
|
7275beb163 | ||
|
40bd9ed95a | ||
|
1ab8703008 | ||
|
eed5ff76ef | ||
|
959aa693f3 | ||
|
7f8110b6be | ||
|
ceb2699760 | ||
|
cc2e3b9358 | ||
|
8c16c60554 | ||
|
cc986368be | ||
|
dd78c0c379 | ||
|
0df17c4aa0 | ||
|
2ade375c20 | ||
|
11d13445fb | ||
|
7734272737 | ||
|
43fafb8e6f | ||
|
5819447828 | ||
|
997a4b7329 | ||
|
35d6dbd0b4 | ||
|
1810faacbe | ||
|
40f89b1c61 | ||
|
82b7c7e5ac | ||
|
0a0ff2fdab | ||
|
045bd3fd73 | ||
|
79aa7717ed | ||
|
0bb7b1523d | ||
|
03eacde753 | ||
|
a164dccc94 | ||
|
20bd959c69 | ||
|
b0fac7648a | ||
|
f8c11f234d | ||
|
5fab6de48a | ||
|
0ace202ace | ||
|
0a62eb3299 | ||
|
afa0cc96b9 | ||
|
f41ece6f1c | ||
|
b8ae2c4b6a | ||
|
c76657ecb4 | ||
|
8255653d24 | ||
|
04a3027368 | ||
|
cbd9395142 | ||
|
bb5ba4861d | ||
|
4afab70414 | ||
|
a7338f8960 | ||
|
117b7910bf | ||
|
ce1ad3e24b | ||
|
df84bd9e1d | ||
|
eef8a281cb | ||
|
6f91ce5ff5 | ||
|
e65a5e2d1c | ||
|
bda740491c | ||
|
700119cc9e | ||
|
07e4ac3865 | ||
|
499593fc82 | ||
|
f59a5775ae | ||
|
73e7c38873 | ||
|
30fc943833 | ||
|
a996734c79 | ||
|
30894a313f | ||
|
fe3012136d | ||
|
59b471ac62 | ||
|
120c2c0b67 | ||
|
0065b201c7 | ||
|
8ed2b3ffc1 | ||
|
9c1543de64 | ||
|
8f100d99cb | ||
|
0562134157 | ||
|
0a109895f7 | ||
|
c0f63abc59 | ||
|
d97b5c2977 | ||
|
7f83f86460 | ||
|
03446f548a | ||
|
d02c836805 | ||
|
a4d31241a8 | ||
|
b13ebc6716 | ||
|
1370b63311 | ||
|
2219e0d0dd | ||
|
8b19c9e340 | ||
|
3843cab643 | ||
|
1efd78ad7b | ||
|
49084b98dd | ||
|
fac59f346f | ||
|
ec96d69876 | ||
|
9515152315 | ||
|
aace6796f5 | ||
|
61e27a4dcb | ||
|
823c0c5990 | ||
|
698adf69cd | ||
|
cd31452c79 | ||
|
ca74e8c5fc | ||
|
d1c390636a | ||
|
4723c62b20 | ||
|
4bbb9df5af | ||
|
40cb7606e3 | ||
|
0b64b6371f | ||
|
eaffc346fd | ||
|
6b2887e8da | ||
|
4a8b017144 | ||
|
9070bfc836 | ||
|
d3bc3e3d18 | ||
|
75260496be | ||
|
61465ff148 | ||
|
8d372f780d | ||
|
3e38fba215 | ||
|
e761e1693c | ||
|
158e2d5383 | ||
|
7de89cfa0f | ||
|
4a2f3203bd | ||
|
8a55491dab | ||
|
b36dc03f59 | ||
|
549c086af4 | ||
|
19dabe81cc | ||
|
370499e453 | ||
|
d7759c8c07 | ||
|
c89a6771ea | ||
|
4cb1dfe401 | ||
|
21e2418281 | ||
|
b8c8f25c83 | ||
|
b58f55353a | ||
|
03e98e617b | ||
|
57181e208f | ||
|
da30078ef4 | ||
|
5b5fc86a3b | ||
|
15ca43d49f | ||
|
0140d68e87 | ||
|
d4d992a0da | ||
|
34ecf4f70b | ||
|
c77e3b2da5 | ||
|
6eff5e640e | ||
|
ceb335e728 | ||
|
dc60c3f3ed | ||
|
796f4d57a1 | ||
|
b4c75649ba | ||
|
f4eb9250ad | ||
|
449c2084bb | ||
|
44bb0020bc | ||
|
fae69133be | ||
|
bdac00bc10 | ||
|
848bb11c08 | ||
|
d5cec3844b | ||
|
a3f1d51bc6 | ||
|
da090e60db | ||
|
c308e276e8 | ||
|
63b528c8bf | ||
|
9db5ce551e | ||
|
f71d552504 | ||
|
beb52bc471 | ||
|
4478ca43b8 | ||
|
b9247d2692 | ||
|
3b24165fd0 | ||
|
9cedf69432 | ||
|
3050f1413a | ||
|
5510cb2e99 | ||
|
3b65ad923b | ||
|
713063e578 | ||
|
b66b75615a | ||
|
77e8716588 | ||
|
fcc1dbdd11 | ||
|
23543ac7ad | ||
|
d778016571 | ||
|
00c54b7d66 | ||
|
980fca9844 | ||
|
2274155801 | ||
|
1774f8c530 | ||
|
2b2f6e6dc4 | ||
|
17da8441f4 | ||
|
4005b301ac | ||
|
804afc3e1d | ||
|
ede1dfb91c | ||
|
30e9a27663 | ||
|
aed423214f | ||
|
6b2386a545 | ||
|
293e68da05 | ||
|
a6951920eb | ||
|
69bdb0bf01 | ||
|
194a4dc975 | ||
|
52cbd57367 | ||
|
6df8da16bc | ||
|
dc725c3b9a | ||
|
17a9a2d23a | ||
|
6eff2d91c9 | ||
|
720f67cee7 | ||
|
6997142fd9 | ||
|
e6954eb37a | ||
|
70a4f54399 | ||
|
5fe03641cb | ||
|
4161f70d2e | ||
|
7d4da81272 | ||
|
17bccd809a | ||
|
e5c9af8f95 | ||
|
27942546b8 | ||
|
872ae90832 | ||
|
6c22ebcc51 | ||
|
b72536853f | ||
|
f5912d511d | ||
|
6e1797183e | ||
|
97e9f999d9 | ||
|
1f9078638e | ||
|
5cf3416dc6 | ||
|
2989406954 | ||
|
b0860ef670 | ||
|
1d12aed3eb | ||
|
11f921b058 | ||
|
c08868a5c1 | ||
|
45adda93b1 | ||
|
2a3fa80540 | ||
|
8c51108a0c | ||
|
44ae6730a6 | ||
|
437c73b0fe | ||
|
e569a0376d | ||
|
af4a958f59 | ||
|
da0da1a117 | ||
|
837e4bde1b | ||
|
5a60135392 | ||
|
c1d963d669 | ||
|
8bb96d12a6 | ||
|
6a8921ae6d | ||
|
074eaf0bd3 | ||
|
324719e531 | ||
|
b10f0cef0e | ||
|
a5bd0440a8 | ||
|
ca5928113d | ||
|
de62a08307 | ||
|
4833dd8da6 | ||
|
11a87582c7 | ||
|
13d6ab56e5 | ||
|
7bb7f345f1 | ||
|
317f0c245e | ||
|
fb80f56a7d | ||
|
134d4171f8 | ||
|
6653d10edf | ||
|
be99ad8285 | ||
|
799f6e4623 | ||
|
df9c0a93bc | ||
|
e8c55df4e8 | ||
|
5a3ab025b7 | ||
|
031e35e50c | ||
|
d2d67d5d6c | ||
|
e6c4313184 | ||
|
a2ce20b564 | ||
|
bd1e1ffe81 | ||
|
3040c004f0 | ||
|
0de7333d6a | ||
|
5ed1fd3156 | ||
|
0a9a1c27d8 | ||
|
c9bba0cdb2 | ||
|
6659a97f28 | ||
|
fd9c27c631 | ||
|
e27d64e643 | ||
|
2e6f04d0be | ||
|
a8d0d9da09 | ||
|
7de642ccb2 | ||
|
8a6d434fc3 | ||
|
f21a3d114f | ||
|
7eb8ae37ee | ||
|
7d6acb7014 | ||
|
a2fe1399e4 |
1
.agignore
Normal file
|
@ -0,0 +1 @@
|
||||||
|
app/assets/javascripts/metamaps.secret.bundle.js
|
10
.babelrc
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"presets": [
|
||||||
|
"react",
|
||||||
|
"es2015"
|
||||||
|
],
|
||||||
|
"plugins": [
|
||||||
|
"lodash",
|
||||||
|
"transform-class-properties"
|
||||||
|
]
|
||||||
|
}
|
|
@ -1 +1,2 @@
|
||||||
|
https://github.com/heroku/heroku-buildpack-nodejs.git
|
||||||
https://github.com/heroku/heroku-buildpack-ruby.git
|
https://github.com/heroku/heroku-buildpack-ruby.git
|
||||||
|
|
38
.codeclimate.yml
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
---
|
||||||
|
engines:
|
||||||
|
brakeman:
|
||||||
|
enabled: true
|
||||||
|
bundler-audit:
|
||||||
|
enabled: true
|
||||||
|
duplication:
|
||||||
|
enabled: true
|
||||||
|
config:
|
||||||
|
languages:
|
||||||
|
count_threshold: 3 # rule of three
|
||||||
|
ruby:
|
||||||
|
mass_threshold: 36 # default: 18
|
||||||
|
javascript:
|
||||||
|
mass_threshold: 80 # default: 40
|
||||||
|
eslint:
|
||||||
|
enabled: true
|
||||||
|
channel: "eslint-3"
|
||||||
|
fixme:
|
||||||
|
enabled: true
|
||||||
|
rubocop:
|
||||||
|
enabled: true
|
||||||
|
exclude_fingerprints:
|
||||||
|
- 74f18007b920e8d81148d2f6a2756534
|
||||||
|
ratings:
|
||||||
|
paths:
|
||||||
|
- 'Gemfile.lock'
|
||||||
|
- '**.erb'
|
||||||
|
- '**.rb'
|
||||||
|
- '**.js'
|
||||||
|
- '**.jsx'
|
||||||
|
exclude_paths:
|
||||||
|
- app/assets/images/
|
||||||
|
- app/assets/javascripts/lib/
|
||||||
|
- frontend/src/patched/
|
||||||
|
- db/
|
||||||
|
- script/
|
||||||
|
- spec/
|
3
.eslintignore
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
**/*{.,-}min.js
|
||||||
|
frontend/src/patched/*
|
||||||
|
app/assets/javascripts/lib/*
|
26
.eslintrc.js
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
module.exports = {
|
||||||
|
"sourceType": "module",
|
||||||
|
"parser": "babel-eslint",
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaFeatures": {
|
||||||
|
"jsx": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"extends": "standard",
|
||||||
|
"installedESLint": true,
|
||||||
|
"env": {
|
||||||
|
"es6": true,
|
||||||
|
"node": true
|
||||||
|
},
|
||||||
|
"plugins": [
|
||||||
|
"promise",
|
||||||
|
"standard",
|
||||||
|
"react"
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"react/jsx-uses-react": [2],
|
||||||
|
"react/jsx-uses-vars": [2],
|
||||||
|
"space-before-function-paren": [2, "never"],
|
||||||
|
"yoda": [2, "never", { "exceptRange": true }]
|
||||||
|
}
|
||||||
|
}
|
15
.example-env
|
@ -1,21 +1,27 @@
|
||||||
|
# Node JS env
|
||||||
|
export NODE_REALTIME_PORT='5000' # should match REALTIME_SERVER, below
|
||||||
|
|
||||||
|
# Rails env
|
||||||
export DB_USERNAME='postgres'
|
export DB_USERNAME='postgres'
|
||||||
export DB_PASSWORD='3112'
|
export DB_PASSWORD='3112'
|
||||||
export DB_HOST='localhost'
|
export DB_HOST='localhost'
|
||||||
export DB_PORT='5432'
|
export DB_PORT='5432'
|
||||||
export DB_NAME='metamap002'
|
export DB_NAME='metamaps'
|
||||||
|
|
||||||
export REALTIME_SERVER='http://localhost:5001'
|
export REALTIME_SERVER='http://localhost:5000'
|
||||||
export MAILER_DEFAULT_URL='localhost:3000'
|
export MAILER_DEFAULT_URL='localhost:3000'
|
||||||
export DEVISE_MAILER_SENDER='team@metamaps.cc'
|
export DEVISE_MAILER_SENDER='team@metamaps.cc'
|
||||||
|
|
||||||
export DEVISE_SECRET_KEY='f71c467e526f23d614b3b08866cad4788c502bed869c282f06e73ee6c94675b62fe1f6d52fa7ba8196b33031f0d2f3b67e27ea07693c52ecebccb01700cad614'
|
export DEVISE_SECRET_KEY='f71c467e526f23d614b3b08866cad4788c502bed869c282f06e73ee6c94675b62fe1f6d52fa7ba8196b33031f0d2f3b67e27ea07693c52ecebccb01700cad614'
|
||||||
|
export SECRET_KEY_BASE='267c8a84f63963282f45bc3010eaddf027abfab58fc759d6e239c8005f85ee99d6d01b1ab6394cdee9ca7f8c9213a0cf91d3d8d3350f096123e2caccbcc0924f'
|
||||||
|
|
||||||
# # you can safely leave these blank, unless you're deploying an instance, in
|
# # you can safely leave these blank, unless you're deploying an instance, in
|
||||||
# # which case you'll need to set them up
|
# # which case you'll need to set them up
|
||||||
#
|
#
|
||||||
|
# export S3_REGION
|
||||||
# export S3_BUCKET_NAME
|
# export S3_BUCKET_NAME
|
||||||
# export AWS_ACCESS_KEY_ID
|
# export AWS_ACCESS_KEY_ID
|
||||||
# export AWS_SECRET_ACCESS_KEY
|
# export AWS_SECRET_ACCESS_KEY
|
||||||
# export SSO_KEY
|
|
||||||
#
|
#
|
||||||
# export SMTP_DOMAIN
|
# export SMTP_DOMAIN
|
||||||
# export SMTP_PASSWORD
|
# export SMTP_PASSWORD
|
||||||
|
@ -23,6 +29,9 @@ export DEVISE_SECRET_KEY='f71c467e526f23d614b3b08866cad4788c502bed869c282f06e73e
|
||||||
# export SMTP_SERVER
|
# export SMTP_SERVER
|
||||||
# export SMTP_USERNAME
|
# export SMTP_USERNAME
|
||||||
|
|
||||||
|
# # send exception notifications to a slack incoming webhook
|
||||||
|
# export SLACK_EN_WEBHOOK_URL
|
||||||
|
|
||||||
# ruby garbage collection stuff
|
# ruby garbage collection stuff
|
||||||
|
|
||||||
export RUBY_GC_TUNE=0 #set to 1 to enable GC test
|
export RUBY_GC_TUNE=0 #set to 1 to enable GC test
|
||||||
|
|
9
.gitignore
vendored
|
@ -5,13 +5,17 @@
|
||||||
# git config --global core.excludesfile ~/.gitignore_global
|
# git config --global core.excludesfile ~/.gitignore_global
|
||||||
|
|
||||||
#assety stuff
|
#assety stuff
|
||||||
realtime/node_modules
|
|
||||||
public/assets
|
public/assets
|
||||||
public/metamaps_mobile
|
public/metamaps_mobile
|
||||||
|
public/api/index.html
|
||||||
vendor/
|
vendor/
|
||||||
|
node_modules
|
||||||
|
npm-debug.log
|
||||||
|
app/assets/javascripts/webpacked
|
||||||
|
|
||||||
#secrets and config
|
#secrets and config
|
||||||
.env
|
.env
|
||||||
|
*.swp
|
||||||
|
|
||||||
# Ignore bundler config
|
# Ignore bundler config
|
||||||
.bundle
|
.bundle
|
||||||
|
@ -19,6 +23,7 @@ vendor/
|
||||||
# Ignore all logfiles and tempfiles.
|
# Ignore all logfiles and tempfiles.
|
||||||
log/*.log
|
log/*.log
|
||||||
tmp
|
tmp
|
||||||
|
.tmp
|
||||||
|
|
||||||
coverage
|
coverage
|
||||||
|
|
||||||
|
@ -26,3 +31,5 @@ coverage
|
||||||
*/.DS_Store
|
*/.DS_Store
|
||||||
.DS_Store?
|
.DS_Store?
|
||||||
.vagrant
|
.vagrant
|
||||||
|
gentle/
|
||||||
|
startserver.sh
|
||||||
|
|
1
.nvmrc
Normal file
|
@ -0,0 +1 @@
|
||||||
|
6.2.2
|
29
.rubocop.yml
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
AllCops:
|
||||||
|
TargetRubyVersion: 2.3
|
||||||
|
Exclude:
|
||||||
|
- 'db/**/*'
|
||||||
|
- 'tmp/**/*'
|
||||||
|
- 'bin/**/*'
|
||||||
|
- 'vendor/**/*'
|
||||||
|
- 'app/assets/javascripts/node_modules/**/*'
|
||||||
|
- 'Vagrantfile'
|
||||||
|
|
||||||
|
Rails:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Metrics/LineLength:
|
||||||
|
Max: 120
|
||||||
|
|
||||||
|
Metrics/AbcSize:
|
||||||
|
Max: 16
|
||||||
|
|
||||||
|
Style/Documentation:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/EmptyMethod:
|
||||||
|
EnforcedStyle: expanded
|
||||||
|
|
||||||
|
# I like this cop, but occasionally code is more readable without a guard clause,
|
||||||
|
# and I don't want to write rubocop:disable comments every time that happens
|
||||||
|
Style/GuardClause:
|
||||||
|
Enabled: false
|
|
@ -1 +1 @@
|
||||||
metamaps_gen002
|
metamaps
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
ruby-2.1.3
|
2.3.0
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
if ENV['COVERAGE'] == 'on'
|
if ENV['COVERAGE'] == 'on'
|
||||||
SimpleCov.start 'rails'
|
SimpleCov.start 'rails' do
|
||||||
|
add_group 'Policies', 'app/policies'
|
||||||
|
add_group 'Services', 'app/services'
|
||||||
|
add_group 'Serializers', 'app/serializers'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
18
.travis.yml
|
@ -1,9 +1,25 @@
|
||||||
sudo: false
|
sudo: false
|
||||||
language: ruby
|
language: ruby
|
||||||
|
cache:
|
||||||
|
bundler: true
|
||||||
|
directories:
|
||||||
|
- app/assets/javascripts/node_modules
|
||||||
rvm:
|
rvm:
|
||||||
- 2.1.3
|
- 2.3.0
|
||||||
before_script:
|
before_script:
|
||||||
|
- echo "Rspec setup"
|
||||||
- export RAILS_ENV=test
|
- export RAILS_ENV=test
|
||||||
- cp .example-env .env
|
- cp .example-env .env
|
||||||
- bundle exec rake db:create
|
- bundle exec rake db:create
|
||||||
- bundle exec rake db:schema:load
|
- bundle exec rake db:schema:load
|
||||||
|
- echo "node setup"
|
||||||
|
- . $HOME/.nvm/nvm.sh
|
||||||
|
- nvm install stable
|
||||||
|
- nvm use stable
|
||||||
|
- npm install --no-optional
|
||||||
|
script:
|
||||||
|
- bundle exec rspec && bundle exec brakeman -q -z && npm test
|
||||||
|
addons:
|
||||||
|
code_climate:
|
||||||
|
repo_token: 479d3bf56798fbc7fff3fc8151a5ed09e8ac368fd5af332c437b9e07dbebb44e
|
||||||
|
postgresql: "9.4"
|
||||||
|
|
75
Gemfile
|
@ -1,68 +1,57 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
source 'https://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
ruby '2.1.3'
|
ruby '2.3.0'
|
||||||
|
|
||||||
gem 'rails', '4.2.4'
|
gem 'rails', '~> 5.0.0'
|
||||||
|
|
||||||
|
gem 'active_model_serializers'
|
||||||
|
gem 'aws-sdk', '~> 2.7.0'
|
||||||
|
gem 'best_in_place'
|
||||||
|
gem 'delayed_job'
|
||||||
|
gem 'delayed_job_active_record'
|
||||||
gem 'devise'
|
gem 'devise'
|
||||||
gem 'redis'
|
gem 'doorkeeper'
|
||||||
|
gem 'dotenv-rails'
|
||||||
|
gem 'exception_notification'
|
||||||
|
gem 'httparty'
|
||||||
|
gem 'json'
|
||||||
|
gem 'kaminari'
|
||||||
|
gem 'mailboxer'
|
||||||
|
gem 'paperclip'
|
||||||
gem 'pg'
|
gem 'pg'
|
||||||
|
gem 'puma'
|
||||||
gem 'pundit'
|
gem 'pundit'
|
||||||
gem 'pundit_extra'
|
gem 'pundit_extra'
|
||||||
gem 'doorkeeper'
|
gem 'rack-attack'
|
||||||
gem 'formula'
|
gem 'rack-cors'
|
||||||
gem 'formtastic'
|
gem 'redis', '~> 3.3.3'
|
||||||
gem 'json'
|
gem 'slack-notifier'
|
||||||
gem 'rails3-jquery-autocomplete'
|
|
||||||
gem 'best_in_place' #in-place editing
|
|
||||||
gem 'kaminari' # pagination
|
|
||||||
gem 'uservoice-ruby'
|
|
||||||
gem 'dotenv'
|
|
||||||
gem 'snorlax'
|
gem 'snorlax'
|
||||||
gem 'httparty'
|
gem 'sucker_punch'
|
||||||
gem 'active_model_serializers', '~> 0.8.1'
|
|
||||||
gem 'delayed_job', '~> 4.0.2'
|
|
||||||
gem 'delayed_job_active_record', '~> 4.0.1'
|
|
||||||
|
|
||||||
gem 'paperclip'
|
|
||||||
gem 'aws-sdk', '< 2.0'
|
|
||||||
|
|
||||||
|
# asset stuff
|
||||||
gem 'jquery-rails'
|
gem 'jquery-rails'
|
||||||
gem 'jquery-ui-rails'
|
gem 'jquery-ui-rails'
|
||||||
gem 'jbuilder'
|
|
||||||
|
|
||||||
#gem 'therubyracer' #optional
|
|
||||||
#gem 'rb-readline'
|
|
||||||
|
|
||||||
# Gems used only for assets and not required
|
|
||||||
# in production environments by default.
|
|
||||||
group :assets do
|
|
||||||
gem 'sass-rails'
|
gem 'sass-rails'
|
||||||
gem 'coffee-rails'
|
|
||||||
|
|
||||||
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
|
|
||||||
# gem 'therubyracer'
|
|
||||||
|
|
||||||
gem 'uglifier'
|
gem 'uglifier'
|
||||||
end
|
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
|
gem 'brakeman', require: false
|
||||||
|
gem 'factory_bot_rails'
|
||||||
|
gem 'json-schema'
|
||||||
gem 'rspec-rails'
|
gem 'rspec-rails'
|
||||||
gem 'factory_girl_rails'
|
|
||||||
gem 'shoulda-matchers'
|
gem 'shoulda-matchers'
|
||||||
gem 'simplecov', require: false
|
gem 'simplecov', require: false
|
||||||
gem 'json-schema'
|
|
||||||
end
|
|
||||||
|
|
||||||
group :production do #this is used on heroku
|
|
||||||
#gem 'rmagick'
|
|
||||||
gem 'rails_12factor'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
group :development, :test do
|
group :development, :test do
|
||||||
gem 'pry-rails'
|
|
||||||
gem 'pry-byebug'
|
|
||||||
gem 'better_errors'
|
gem 'better_errors'
|
||||||
gem 'binding_of_caller'
|
gem 'binding_of_caller'
|
||||||
gem 'quiet_assets'
|
gem 'faker'
|
||||||
|
gem 'pry-byebug'
|
||||||
|
gem 'pry-rails'
|
||||||
|
gem 'rubocop', '~> 0.48.1' # match code climate https://github.com/tootsuite/mastodon/issues/1758
|
||||||
|
gem 'timecop'
|
||||||
gem 'tunemygc'
|
gem 'tunemygc'
|
||||||
end
|
end
|
||||||
|
|
451
Gemfile.lock
|
@ -1,303 +1,350 @@
|
||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
actionmailer (4.2.4)
|
actioncable (5.0.5)
|
||||||
actionpack (= 4.2.4)
|
actionpack (= 5.0.5)
|
||||||
actionview (= 4.2.4)
|
nio4r (>= 1.2, < 3.0)
|
||||||
activejob (= 4.2.4)
|
websocket-driver (~> 0.6.1)
|
||||||
|
actionmailer (5.0.5)
|
||||||
|
actionpack (= 5.0.5)
|
||||||
|
actionview (= 5.0.5)
|
||||||
|
activejob (= 5.0.5)
|
||||||
mail (~> 2.5, >= 2.5.4)
|
mail (~> 2.5, >= 2.5.4)
|
||||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
rails-dom-testing (~> 2.0)
|
||||||
actionpack (4.2.4)
|
actionpack (5.0.5)
|
||||||
actionview (= 4.2.4)
|
actionview (= 5.0.5)
|
||||||
activesupport (= 4.2.4)
|
activesupport (= 5.0.5)
|
||||||
rack (~> 1.6)
|
rack (~> 2.0)
|
||||||
rack-test (~> 0.6.2)
|
rack-test (~> 0.6.3)
|
||||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
rails-dom-testing (~> 2.0)
|
||||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
||||||
actionview (4.2.4)
|
actionview (5.0.5)
|
||||||
activesupport (= 4.2.4)
|
activesupport (= 5.0.5)
|
||||||
builder (~> 3.1)
|
builder (~> 3.1)
|
||||||
erubis (~> 2.7.0)
|
erubis (~> 2.7.0)
|
||||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
rails-dom-testing (~> 2.0)
|
||||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
||||||
active_model_serializers (0.8.3)
|
active_model_serializers (0.10.6)
|
||||||
activemodel (>= 3.0)
|
actionpack (>= 4.1, < 6)
|
||||||
activejob (4.2.4)
|
activemodel (>= 4.1, < 6)
|
||||||
activesupport (= 4.2.4)
|
case_transform (>= 0.2)
|
||||||
globalid (>= 0.3.0)
|
jsonapi-renderer (>= 0.1.1.beta1, < 0.2)
|
||||||
activemodel (4.2.4)
|
activejob (5.0.5)
|
||||||
activesupport (= 4.2.4)
|
activesupport (= 5.0.5)
|
||||||
builder (~> 3.1)
|
globalid (>= 0.3.6)
|
||||||
activerecord (4.2.4)
|
activemodel (5.0.5)
|
||||||
activemodel (= 4.2.4)
|
activesupport (= 5.0.5)
|
||||||
activesupport (= 4.2.4)
|
activerecord (5.0.5)
|
||||||
arel (~> 6.0)
|
activemodel (= 5.0.5)
|
||||||
activesupport (4.2.4)
|
activesupport (= 5.0.5)
|
||||||
|
arel (~> 7.0)
|
||||||
|
activesupport (5.0.5)
|
||||||
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||||
i18n (~> 0.7)
|
i18n (~> 0.7)
|
||||||
json (~> 1.7, >= 1.7.7)
|
|
||||||
minitest (~> 5.1)
|
minitest (~> 5.1)
|
||||||
thread_safe (~> 0.3, >= 0.3.4)
|
|
||||||
tzinfo (~> 1.1)
|
tzinfo (~> 1.1)
|
||||||
addressable (2.3.8)
|
addressable (2.5.2)
|
||||||
arel (6.0.3)
|
public_suffix (>= 2.0.2, < 4.0)
|
||||||
aws-sdk (1.66.0)
|
arel (7.1.4)
|
||||||
aws-sdk-v1 (= 1.66.0)
|
ast (2.3.0)
|
||||||
aws-sdk-v1 (1.66.0)
|
aws-sdk (2.7.0)
|
||||||
json (~> 1.4)
|
aws-sdk-resources (= 2.7.0)
|
||||||
nokogiri (>= 1.4.4)
|
aws-sdk-core (2.7.0)
|
||||||
|
aws-sigv4 (~> 1.0)
|
||||||
|
jmespath (~> 1.0)
|
||||||
|
aws-sdk-resources (2.7.0)
|
||||||
|
aws-sdk-core (= 2.7.0)
|
||||||
|
aws-sigv4 (1.0.2)
|
||||||
bcrypt (3.1.11)
|
bcrypt (3.1.11)
|
||||||
best_in_place (3.1.0)
|
best_in_place (3.1.1)
|
||||||
actionpack (>= 3.2)
|
actionpack (>= 3.2)
|
||||||
railties (>= 3.2)
|
railties (>= 3.2)
|
||||||
better_errors (2.1.1)
|
better_errors (2.3.0)
|
||||||
coderay (>= 1.0.0)
|
coderay (>= 1.0.0)
|
||||||
erubis (>= 2.6.6)
|
erubi (>= 1.0.0)
|
||||||
rack (>= 0.9.0)
|
rack (>= 0.9.0)
|
||||||
binding_of_caller (0.7.2)
|
binding_of_caller (0.7.2)
|
||||||
debug_inspector (>= 0.0.1)
|
debug_inspector (>= 0.0.1)
|
||||||
builder (3.2.2)
|
brakeman (3.7.2)
|
||||||
byebug (8.2.2)
|
builder (3.2.3)
|
||||||
climate_control (0.0.3)
|
byebug (9.1.0)
|
||||||
activesupport (>= 3.0)
|
carrierwave (1.1.0)
|
||||||
|
activemodel (>= 4.0.0)
|
||||||
|
activesupport (>= 4.0.0)
|
||||||
|
mime-types (>= 1.16)
|
||||||
|
case_transform (0.2)
|
||||||
|
activesupport
|
||||||
|
climate_control (0.2.0)
|
||||||
cocaine (0.5.8)
|
cocaine (0.5.8)
|
||||||
climate_control (>= 0.0.3, < 1.0)
|
climate_control (>= 0.0.3, < 1.0)
|
||||||
coderay (1.1.1)
|
coderay (1.1.2)
|
||||||
coffee-rails (4.1.1)
|
concurrent-ruby (1.0.5)
|
||||||
coffee-script (>= 2.2.0)
|
debug_inspector (0.0.3)
|
||||||
railties (>= 4.0.0, < 5.1.x)
|
delayed_job (4.1.3)
|
||||||
coffee-script (2.4.1)
|
activesupport (>= 3.0, < 5.2)
|
||||||
coffee-script-source
|
delayed_job_active_record (4.1.2)
|
||||||
execjs
|
activerecord (>= 3.0, < 5.2)
|
||||||
coffee-script-source (1.10.0)
|
delayed_job (>= 3.0, < 5)
|
||||||
concurrent-ruby (1.0.1)
|
devise (4.3.0)
|
||||||
debug_inspector (0.0.2)
|
|
||||||
delayed_job (4.0.6)
|
|
||||||
activesupport (>= 3.0, < 5.0)
|
|
||||||
delayed_job_active_record (4.0.3)
|
|
||||||
activerecord (>= 3.0, < 5.0)
|
|
||||||
delayed_job (>= 3.0, < 4.1)
|
|
||||||
devise (3.5.6)
|
|
||||||
bcrypt (~> 3.0)
|
bcrypt (~> 3.0)
|
||||||
orm_adapter (~> 0.1)
|
orm_adapter (~> 0.1)
|
||||||
railties (>= 3.2.6, < 5)
|
railties (>= 4.1.0, < 5.2)
|
||||||
responders
|
responders
|
||||||
thread_safe (~> 0.1)
|
|
||||||
warden (~> 1.2.3)
|
warden (~> 1.2.3)
|
||||||
diff-lcs (1.2.5)
|
diff-lcs (1.3)
|
||||||
docile (1.1.5)
|
docile (1.1.5)
|
||||||
doorkeeper (3.1.0)
|
doorkeeper (4.2.6)
|
||||||
railties (>= 3.2)
|
railties (>= 4.2)
|
||||||
dotenv (2.1.0)
|
dotenv (2.2.1)
|
||||||
|
dotenv-rails (2.2.1)
|
||||||
|
dotenv (= 2.2.1)
|
||||||
|
railties (>= 3.2, < 5.2)
|
||||||
|
erubi (1.6.1)
|
||||||
erubis (2.7.0)
|
erubis (2.7.0)
|
||||||
execjs (2.6.0)
|
exception_notification (4.2.2)
|
||||||
ezcrypto (0.7.2)
|
actionmailer (>= 4.0, < 6)
|
||||||
factory_girl (4.5.0)
|
activesupport (>= 4.0, < 6)
|
||||||
|
execjs (2.7.0)
|
||||||
|
factory_bot (4.8.2)
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0)
|
||||||
factory_girl_rails (4.6.0)
|
factory_bot_rails (4.8.2)
|
||||||
factory_girl (~> 4.5.0)
|
factory_bot (~> 4.8.2)
|
||||||
railties (>= 3.0.0)
|
railties (>= 3.0.0)
|
||||||
formtastic (3.1.3)
|
faker (1.8.4)
|
||||||
actionpack (>= 3.2.13)
|
i18n (~> 0.5)
|
||||||
formula (1.1.1)
|
ffi (1.9.18)
|
||||||
rails (> 3.0.0)
|
globalid (0.4.0)
|
||||||
globalid (0.3.6)
|
activesupport (>= 4.2.0)
|
||||||
activesupport (>= 4.1.0)
|
httparty (0.15.6)
|
||||||
httparty (0.13.7)
|
|
||||||
json (~> 1.8)
|
|
||||||
multi_xml (>= 0.5.2)
|
multi_xml (>= 0.5.2)
|
||||||
i18n (0.7.0)
|
i18n (0.9.3)
|
||||||
jbuilder (2.4.1)
|
concurrent-ruby (~> 1.0)
|
||||||
activesupport (>= 3.0.0, < 5.1)
|
jmespath (1.3.1)
|
||||||
multi_json (~> 1.2)
|
jquery-rails (4.3.1)
|
||||||
jquery-rails (4.1.1)
|
|
||||||
rails-dom-testing (>= 1, < 3)
|
rails-dom-testing (>= 1, < 3)
|
||||||
railties (>= 4.2.0)
|
railties (>= 4.2.0)
|
||||||
thor (>= 0.14, < 2.0)
|
thor (>= 0.14, < 2.0)
|
||||||
jquery-ui-rails (5.0.5)
|
jquery-ui-rails (6.0.1)
|
||||||
railties (>= 3.2.16)
|
railties (>= 3.2.16)
|
||||||
json (1.8.3)
|
json (2.1.0)
|
||||||
json-schema (2.6.1)
|
json-schema (2.8.0)
|
||||||
addressable (~> 2.3.8)
|
addressable (>= 2.4)
|
||||||
kaminari (0.16.3)
|
jsonapi-renderer (0.1.3)
|
||||||
actionpack (>= 3.0.0)
|
kaminari (1.0.1)
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 4.1.0)
|
||||||
|
kaminari-actionview (= 1.0.1)
|
||||||
|
kaminari-activerecord (= 1.0.1)
|
||||||
|
kaminari-core (= 1.0.1)
|
||||||
|
kaminari-actionview (1.0.1)
|
||||||
|
actionview
|
||||||
|
kaminari-core (= 1.0.1)
|
||||||
|
kaminari-activerecord (1.0.1)
|
||||||
|
activerecord
|
||||||
|
kaminari-core (= 1.0.1)
|
||||||
|
kaminari-core (1.0.1)
|
||||||
loofah (2.0.3)
|
loofah (2.0.3)
|
||||||
nokogiri (>= 1.5.9)
|
nokogiri (>= 1.5.9)
|
||||||
mail (2.6.4)
|
mail (2.6.6)
|
||||||
mime-types (>= 1.16, < 4)
|
mime-types (>= 1.16, < 4)
|
||||||
|
mailboxer (0.15.1)
|
||||||
|
carrierwave (>= 0.5.8)
|
||||||
|
rails (>= 5.0.0)
|
||||||
method_source (0.8.2)
|
method_source (0.8.2)
|
||||||
mime-types (3.0)
|
mime-types (3.1)
|
||||||
mime-types-data (~> 3.2015)
|
mime-types-data (~> 3.2015)
|
||||||
mime-types-data (3.2016.0221)
|
mime-types-data (3.2016.0521)
|
||||||
mimemagic (0.3.0)
|
mimemagic (0.3.2)
|
||||||
mini_portile2 (2.0.0)
|
mini_portile2 (2.3.0)
|
||||||
minitest (5.8.4)
|
minitest (5.11.1)
|
||||||
multi_json (1.11.2)
|
multi_xml (0.6.0)
|
||||||
multi_xml (0.5.5)
|
nio4r (2.1.0)
|
||||||
nokogiri (1.6.7.2)
|
nokogiri (1.8.1)
|
||||||
mini_portile2 (~> 2.0.0.rc2)
|
mini_portile2 (~> 2.3.0)
|
||||||
oauth (0.5.1)
|
|
||||||
orm_adapter (0.5.0)
|
orm_adapter (0.5.0)
|
||||||
paperclip (4.3.5)
|
paperclip (5.2.0)
|
||||||
activemodel (>= 3.2.0)
|
activemodel (>= 4.2.0)
|
||||||
activesupport (>= 3.2.0)
|
activesupport (>= 4.2.0)
|
||||||
cocaine (~> 0.5.5)
|
cocaine (~> 0.5.5)
|
||||||
mime-types
|
mime-types
|
||||||
mimemagic (= 0.3.0)
|
mimemagic (~> 0.3.0)
|
||||||
pg (0.18.4)
|
parser (2.4.0.2)
|
||||||
pry (0.10.3)
|
ast (~> 2.3)
|
||||||
|
pg (0.21.0)
|
||||||
|
powerpack (0.1.1)
|
||||||
|
pry (0.10.4)
|
||||||
coderay (~> 1.1.0)
|
coderay (~> 1.1.0)
|
||||||
method_source (~> 0.8.1)
|
method_source (~> 0.8.1)
|
||||||
slop (~> 3.4)
|
slop (~> 3.4)
|
||||||
pry-byebug (3.3.0)
|
pry-byebug (3.5.0)
|
||||||
byebug (~> 8.0)
|
byebug (~> 9.1)
|
||||||
pry (~> 0.10)
|
pry (~> 0.10)
|
||||||
pry-rails (0.3.4)
|
pry-rails (0.3.6)
|
||||||
pry (>= 0.9.10)
|
pry (>= 0.10.4)
|
||||||
|
public_suffix (3.0.0)
|
||||||
|
puma (3.10.0)
|
||||||
pundit (1.1.0)
|
pundit (1.1.0)
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0)
|
||||||
pundit_extra (0.1.1)
|
pundit_extra (0.3.0)
|
||||||
quiet_assets (1.1.0)
|
rack (2.0.3)
|
||||||
railties (>= 3.1, < 5.0)
|
rack-attack (5.0.1)
|
||||||
rack (1.6.4)
|
rack
|
||||||
|
rack-cors (1.0.1)
|
||||||
rack-test (0.6.3)
|
rack-test (0.6.3)
|
||||||
rack (>= 1.0)
|
rack (>= 1.0)
|
||||||
rails (4.2.4)
|
rails (5.0.5)
|
||||||
actionmailer (= 4.2.4)
|
actioncable (= 5.0.5)
|
||||||
actionpack (= 4.2.4)
|
actionmailer (= 5.0.5)
|
||||||
actionview (= 4.2.4)
|
actionpack (= 5.0.5)
|
||||||
activejob (= 4.2.4)
|
actionview (= 5.0.5)
|
||||||
activemodel (= 4.2.4)
|
activejob (= 5.0.5)
|
||||||
activerecord (= 4.2.4)
|
activemodel (= 5.0.5)
|
||||||
activesupport (= 4.2.4)
|
activerecord (= 5.0.5)
|
||||||
bundler (>= 1.3.0, < 2.0)
|
activesupport (= 5.0.5)
|
||||||
railties (= 4.2.4)
|
bundler (>= 1.3.0)
|
||||||
sprockets-rails
|
railties (= 5.0.5)
|
||||||
rails-deprecated_sanitizer (1.0.3)
|
sprockets-rails (>= 2.0.0)
|
||||||
activesupport (>= 4.2.0.alpha)
|
rails-dom-testing (2.0.3)
|
||||||
rails-dom-testing (1.0.7)
|
activesupport (>= 4.2.0)
|
||||||
activesupport (>= 4.2.0.beta, < 5.0)
|
nokogiri (>= 1.6)
|
||||||
nokogiri (~> 1.6.0)
|
|
||||||
rails-deprecated_sanitizer (>= 1.0.1)
|
|
||||||
rails-html-sanitizer (1.0.3)
|
rails-html-sanitizer (1.0.3)
|
||||||
loofah (~> 2.0)
|
loofah (~> 2.0)
|
||||||
rails3-jquery-autocomplete (1.0.15)
|
railties (5.0.5)
|
||||||
rails (>= 3.2)
|
actionpack (= 5.0.5)
|
||||||
rails_12factor (0.0.3)
|
activesupport (= 5.0.5)
|
||||||
rails_serve_static_assets
|
method_source
|
||||||
rails_stdout_logging
|
|
||||||
rails_serve_static_assets (0.0.5)
|
|
||||||
rails_stdout_logging (0.0.4)
|
|
||||||
railties (4.2.4)
|
|
||||||
actionpack (= 4.2.4)
|
|
||||||
activesupport (= 4.2.4)
|
|
||||||
rake (>= 0.8.7)
|
rake (>= 0.8.7)
|
||||||
thor (>= 0.18.1, < 2.0)
|
thor (>= 0.18.1, < 2.0)
|
||||||
rake (11.1.1)
|
rainbow (2.2.2)
|
||||||
redis (3.2.2)
|
rake
|
||||||
responders (2.1.1)
|
rake (12.3.0)
|
||||||
railties (>= 4.2.0, < 5.1)
|
rb-fsevent (0.10.2)
|
||||||
rspec-core (3.4.4)
|
rb-inotify (0.9.10)
|
||||||
rspec-support (~> 3.4.0)
|
ffi (>= 0.5.0, < 2)
|
||||||
rspec-expectations (3.4.0)
|
redis (3.3.3)
|
||||||
|
responders (2.4.0)
|
||||||
|
actionpack (>= 4.2.0, < 5.3)
|
||||||
|
railties (>= 4.2.0, < 5.3)
|
||||||
|
rspec-core (3.6.0)
|
||||||
|
rspec-support (~> 3.6.0)
|
||||||
|
rspec-expectations (3.6.0)
|
||||||
diff-lcs (>= 1.2.0, < 2.0)
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
rspec-support (~> 3.4.0)
|
rspec-support (~> 3.6.0)
|
||||||
rspec-mocks (3.4.1)
|
rspec-mocks (3.6.0)
|
||||||
diff-lcs (>= 1.2.0, < 2.0)
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
rspec-support (~> 3.4.0)
|
rspec-support (~> 3.6.0)
|
||||||
rspec-rails (3.4.2)
|
rspec-rails (3.6.1)
|
||||||
actionpack (>= 3.0, < 4.3)
|
actionpack (>= 3.0)
|
||||||
activesupport (>= 3.0, < 4.3)
|
activesupport (>= 3.0)
|
||||||
railties (>= 3.0, < 4.3)
|
railties (>= 3.0)
|
||||||
rspec-core (~> 3.4.0)
|
rspec-core (~> 3.6.0)
|
||||||
rspec-expectations (~> 3.4.0)
|
rspec-expectations (~> 3.6.0)
|
||||||
rspec-mocks (~> 3.4.0)
|
rspec-mocks (~> 3.6.0)
|
||||||
rspec-support (~> 3.4.0)
|
rspec-support (~> 3.6.0)
|
||||||
rspec-support (3.4.1)
|
rspec-support (3.6.0)
|
||||||
sass (3.4.21)
|
rubocop (0.48.1)
|
||||||
sass-rails (5.0.4)
|
parser (>= 2.3.3.1, < 3.0)
|
||||||
railties (>= 4.0.0, < 5.0)
|
powerpack (~> 0.1)
|
||||||
|
rainbow (>= 1.99.1, < 3.0)
|
||||||
|
ruby-progressbar (~> 1.7)
|
||||||
|
unicode-display_width (~> 1.0, >= 1.0.1)
|
||||||
|
ruby-progressbar (1.9.0)
|
||||||
|
sass (3.5.1)
|
||||||
|
sass-listen (~> 4.0.0)
|
||||||
|
sass-listen (4.0.0)
|
||||||
|
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||||
|
rb-inotify (~> 0.9, >= 0.9.7)
|
||||||
|
sass-rails (5.0.6)
|
||||||
|
railties (>= 4.0.0, < 6)
|
||||||
sass (~> 3.1)
|
sass (~> 3.1)
|
||||||
sprockets (>= 2.8, < 4.0)
|
sprockets (>= 2.8, < 4.0)
|
||||||
sprockets-rails (>= 2.0, < 4.0)
|
sprockets-rails (>= 2.0, < 4.0)
|
||||||
tilt (>= 1.1, < 3)
|
tilt (>= 1.1, < 3)
|
||||||
shoulda-matchers (3.1.1)
|
shoulda-matchers (3.1.2)
|
||||||
activesupport (>= 4.0.0)
|
activesupport (>= 4.0.0)
|
||||||
simplecov (0.11.2)
|
simplecov (0.15.0)
|
||||||
docile (~> 1.1.0)
|
docile (~> 1.1.0)
|
||||||
json (~> 1.8)
|
json (>= 1.8, < 3)
|
||||||
simplecov-html (~> 0.10.0)
|
simplecov-html (~> 0.10.0)
|
||||||
simplecov-html (0.10.0)
|
simplecov-html (0.10.2)
|
||||||
|
slack-notifier (2.3.1)
|
||||||
slop (3.6.0)
|
slop (3.6.0)
|
||||||
snorlax (0.1.5)
|
snorlax (0.1.6)
|
||||||
rails (> 4.1)
|
rails (> 4.1)
|
||||||
sprockets (3.5.2)
|
sprockets (3.7.1)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
rack (> 1, < 3)
|
rack (> 1, < 3)
|
||||||
sprockets-rails (3.0.4)
|
sprockets-rails (3.2.1)
|
||||||
actionpack (>= 4.0)
|
actionpack (>= 4.0)
|
||||||
activesupport (>= 4.0)
|
activesupport (>= 4.0)
|
||||||
sprockets (>= 3.0.0)
|
sprockets (>= 3.0.0)
|
||||||
thor (0.19.1)
|
sucker_punch (2.0.3)
|
||||||
thread_safe (0.3.5)
|
concurrent-ruby (~> 1.0.0)
|
||||||
tilt (2.0.2)
|
thor (0.20.0)
|
||||||
tunemygc (1.0.65)
|
thread_safe (0.3.6)
|
||||||
tzinfo (1.2.2)
|
tilt (2.0.8)
|
||||||
|
timecop (0.9.1)
|
||||||
|
tunemygc (1.0.69)
|
||||||
|
tzinfo (1.2.4)
|
||||||
thread_safe (~> 0.1)
|
thread_safe (~> 0.1)
|
||||||
uglifier (2.7.2)
|
uglifier (3.2.0)
|
||||||
execjs (>= 0.3.0)
|
execjs (>= 0.3.0, < 3)
|
||||||
json (>= 1.8.0)
|
unicode-display_width (1.3.0)
|
||||||
uservoice-ruby (0.0.11)
|
warden (1.2.7)
|
||||||
ezcrypto (>= 0.7.2)
|
|
||||||
json (>= 1.7.5)
|
|
||||||
oauth (>= 0.4.7)
|
|
||||||
warden (1.2.6)
|
|
||||||
rack (>= 1.0)
|
rack (>= 1.0)
|
||||||
|
websocket-driver (0.6.5)
|
||||||
|
websocket-extensions (>= 0.1.0)
|
||||||
|
websocket-extensions (0.1.2)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
ruby
|
ruby
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
active_model_serializers (~> 0.8.1)
|
active_model_serializers
|
||||||
aws-sdk (< 2.0)
|
aws-sdk (~> 2.7.0)
|
||||||
best_in_place
|
best_in_place
|
||||||
better_errors
|
better_errors
|
||||||
binding_of_caller
|
binding_of_caller
|
||||||
coffee-rails
|
brakeman
|
||||||
delayed_job (~> 4.0.2)
|
delayed_job
|
||||||
delayed_job_active_record (~> 4.0.1)
|
delayed_job_active_record
|
||||||
devise
|
devise
|
||||||
doorkeeper
|
doorkeeper
|
||||||
dotenv
|
dotenv-rails
|
||||||
factory_girl_rails
|
exception_notification
|
||||||
formtastic
|
factory_bot_rails
|
||||||
formula
|
faker
|
||||||
httparty
|
httparty
|
||||||
jbuilder
|
|
||||||
jquery-rails
|
jquery-rails
|
||||||
jquery-ui-rails
|
jquery-ui-rails
|
||||||
json
|
json
|
||||||
json-schema
|
json-schema
|
||||||
kaminari
|
kaminari
|
||||||
|
mailboxer
|
||||||
paperclip
|
paperclip
|
||||||
pg
|
pg
|
||||||
pry-byebug
|
pry-byebug
|
||||||
pry-rails
|
pry-rails
|
||||||
|
puma
|
||||||
pundit
|
pundit
|
||||||
pundit_extra
|
pundit_extra
|
||||||
quiet_assets
|
rack-attack
|
||||||
rails (= 4.2.4)
|
rack-cors
|
||||||
rails3-jquery-autocomplete
|
rails (~> 5.0.0)
|
||||||
rails_12factor
|
redis (~> 3.3.3)
|
||||||
redis
|
|
||||||
rspec-rails
|
rspec-rails
|
||||||
|
rubocop (~> 0.48.1)
|
||||||
sass-rails
|
sass-rails
|
||||||
shoulda-matchers
|
shoulda-matchers
|
||||||
simplecov
|
simplecov
|
||||||
|
slack-notifier
|
||||||
snorlax
|
snorlax
|
||||||
|
sucker_punch
|
||||||
|
timecop
|
||||||
tunemygc
|
tunemygc
|
||||||
uglifier
|
uglifier
|
||||||
uservoice-ruby
|
|
||||||
|
RUBY VERSION
|
||||||
|
ruby 2.3.0p0
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
1.11.2
|
1.16.1
|
||||||
|
|
2
Procfile
|
@ -1,3 +1,3 @@
|
||||||
web: bundle exec rails server -p $PORT
|
web: bundle exec puma -p $PORT
|
||||||
worker: bundle exec rake jobs:work
|
worker: bundle exec rake jobs:work
|
||||||
|
|
||||||
|
|
97
README.md
|
@ -1,79 +1,62 @@
|
||||||
Metamaps
|
Metamaps
|
||||||
=======
|
=======
|
||||||
|
|
||||||
[![Join the chat at https://gitter.im/metamaps/metamaps_gen002](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/metamaps/metamaps_gen002?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
[![Build Status](https://travis-ci.org/metamaps/metamaps.svg?branch=develop)](https://travis-ci.org/metamaps/metamaps)
|
||||||
[![Build Status](https://travis-ci.org/metamaps/metamaps_gen002.svg)](https://travis-ci.org/metamaps/metamaps_gen002)
|
[![Code Climate](https://codeclimate.com/github/metamaps/metamaps/badges/gpa.svg)](https://codeclimate.com/github/metamaps/metamaps)
|
||||||
|
|
||||||
Welcome to the Metamaps GitHub repo.
|
## What is Metamaps?
|
||||||
|
|
||||||
## About
|
Metamaps is a free and open-source technology for changemakers, innovators, educators and students. It enables individuals and communities to build and visualize their shared knowledge and unlock their collective intelligence.
|
||||||
|
|
||||||
Metamaps is a free and AGPL open source technology for changemakers, innovators, educators and students. It enables individuals and communities to build and visualize their shared knowledge and unlock their collective intelligence. You can find out about more about the project at the [blog][site-blog].
|
You can find a version of this software running at [metamaps.cc][site-beta], where the technology is being tested in an open beta.
|
||||||
|
|
||||||
You can find a version of this software running at [metamaps.cc][site-beta], where the technology is being tested in a private beta.
|
Metamaps is developed and maintained by a distributed, nomadic community comprised of technologists, artists and storytellers. You can get in touch by using whichever of these channels you prefer:
|
||||||
|
|
||||||
Metamaps is created and maintained by a distributed, nomadic community comprised of technologists, artists and storytellers. You can get in touch with us at team@metamaps.cc or @metamapps on twitter.
|
## How do I learn more?
|
||||||
|
|
||||||
To get connected with the community interested in Metamaps, join our [Google+ community][community].
|
- Contact: [team@metamaps.cc](mailto:team@metamaps.cc) or [@metamapps](https://twitter.com/metamapps) on Twitter
|
||||||
|
- User Documentation: [docs.metamaps.cc](https://docs.metamaps.cc)
|
||||||
|
- User Community: [hylo.com/c/metamaps](https://www.hylo.com/c/metamaps)
|
||||||
|
- To see what we're developing, or to weigh in on what you'd like to see developed, see our [Metamaps Feedback and Features](https://trello.com/b/uFOA6a2x/metamaps-feedback-feature-ideas-requests) board on trello
|
||||||
|
- To follow along with, or contribute,to our design process, see our [Metamaps Design](https://trello.com/b/8HlCikOX/metamaps-design) board on trello
|
||||||
|
- To follow along with, or contribute to, our development process, see our [Github Issues and Pull Requests](https://github.com/metamaps/metamaps/issues)
|
||||||
|
- Request an invite to the open beta [here](https://metamaps.cc/request)
|
||||||
|
|
||||||
## Installation
|
<!-- markdown hack to split two lists -->
|
||||||
|
|
||||||
If you are on Mac or Ubuntu you can use the following instructions to quickly get a local copy of metamaps up and running using a Vagrant virtualbox. Don't be intimidated, it's easy!
|
|
||||||
```
|
|
||||||
git clone git@github.com:metamaps/metamaps_gen002.git
|
|
||||||
```
|
|
||||||
Now ensure you have VirtualBox and Vagrant installed on your computer
|
|
||||||
```
|
|
||||||
cd metamaps_gen002
|
|
||||||
./bin/configure.sh
|
|
||||||
```
|
|
||||||
This will do all the setup steps to make Metamaps work with a bit of behind the scenes ninja magick.
|
|
||||||
|
|
||||||
To start servers which will run metamaps you can then run:
|
|
||||||
```
|
|
||||||
./bin/start
|
|
||||||
```
|
|
||||||
To stop them:
|
|
||||||
```
|
|
||||||
./bin/stop
|
|
||||||
```
|
|
||||||
With your webservers running, open a web browser and go to `http://localhost:3000`
|
|
||||||
|
|
||||||
You can sign in with the default account
|
|
||||||
email: `user@user.com`
|
|
||||||
password: `toolsplusconsciousness`
|
|
||||||
OR create a new account at `/join`, and use access code `qwertyui`
|
|
||||||
|
|
||||||
Start mapping and programming!
|
|
||||||
|
|
||||||
We haven't figured out Vagrant for Windows yet, but we have a set of manual instructions here:
|
|
||||||
|
|
||||||
- [For Windows][windows-installation]
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
Cloning this repository directly is primarily for those wishing to contribute to our codebase. Check out our [contributing instructions][contributing] to get involved.
|
|
||||||
|
|
||||||
## Community
|
|
||||||
|
|
||||||
|
- To send us a personal message get in touch with us via email, Twitter, or Hylo
|
||||||
- If you would like to report a bug, please check the [issues][contributing-issues] section in our [contributing instructions][contributing].
|
- If you would like to report a bug, please check the [issues][contributing-issues] section in our [contributing instructions][contributing].
|
||||||
- To participate in discussions and a public forum about Metamaps, join the [Google+ community][community]
|
- If you would like to get set up as a developer, that's great! Read on for help getting your development environment set up.
|
||||||
- For contributors, read more instructions in [CONTRIBUTING.md][contributing].
|
|
||||||
|
## Installation for local use or development of Metamaps
|
||||||
|
|
||||||
|
First off is getting the code downloaded to your computer. You can download a zip file from github, but if you've got `git` you can just run `git clone https://github.com/metamaps/metamaps` in your terminal.
|
||||||
|
|
||||||
|
There are instructions for setup on various platforms, with particular support for Mac and Ubuntu, which can be found here:
|
||||||
|
- [Mac Install Walkthrough][mac-installation]
|
||||||
|
- [Ubuntu Install Walkthrough][ubuntu-installation]
|
||||||
|
|
||||||
|
If you prefer to isolate your install in a virtual machine, you may find it simpler to setup using Vagrant:
|
||||||
|
- [Vagrant installation][vagrant-installation]
|
||||||
|
|
||||||
|
We don't promise support for Windows, but at one point we had it running and we've kept those docs available for reference
|
||||||
|
- [Outdated Windows Walkthrough][windows-installation]
|
||||||
|
|
||||||
## Licensing information
|
## Licensing information
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or(at your option) any later version.
|
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
|
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
|
||||||
|
|
||||||
The license can be read [here][license].
|
The license can be read [here][license].
|
||||||
|
|
||||||
Copyright (c) 2015 Connor Turland
|
Copyright (c) 2017 Connor Turland
|
||||||
|
|
||||||
|
|
||||||
[site-blog]: http://blog.metamaps.cc
|
|
||||||
[site-beta]: http://metamaps.cc
|
[site-beta]: http://metamaps.cc
|
||||||
[community]: https://plus.google.com/u/0/communities/115060009262157699234
|
[license]: https://github.com/metamaps/metamaps/blob/develop/LICENSE
|
||||||
[license]: https://github.com/metamaps/metamaps_gen002/blob/develop/LICENSE
|
[contributing]: https://github.com/metamaps/metamaps/blob/develop/doc/CONTRIBUTING.md
|
||||||
[contributing]: https://github.com/metamaps/metamaps_gen002/blob/develop/doc/CONTRIBUTING.md
|
[contributing-issues]: https://github.com/metamaps/metamaps/blob/develop/doc/CONTRIBUTING.md#reporting-bugs-and-other-issues
|
||||||
[contributing-issues]: https://github.com/metamaps/metamaps_gen002/blob/develop/doc/CONTRIBUTING.md#reporting-bugs-and-other-issues
|
[mac-installation]: https://github.com/metamaps/metamaps/blob/develop/doc/MacInstallation.md
|
||||||
[windows-installation]: https://github.com/metamaps/metamaps_gen002/blob/develop/doc/WindowsInstallation.md
|
[ubuntu-installation]: https://github.com/metamaps/metamaps/blob/develop/doc/UbuntuInstallation.md
|
||||||
|
[vagrant-installation]: https://github.com/metamaps/metamaps/blob/develop/doc/VagrantInstallation.md
|
||||||
|
[windows-installation]: https://github.com/metamaps/metamaps/blob/develop/doc/WindowsInstallation.md
|
||||||
|
|
2
Rakefile
Normal file → Executable file
|
@ -1,4 +1,6 @@
|
||||||
#!/usr/bin/env rake
|
#!/usr/bin/env rake
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
||||||
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
||||||
|
|
||||||
|
|
16
Vagrantfile
vendored
|
@ -9,7 +9,7 @@ sudo apt-get install git curl -y
|
||||||
|
|
||||||
# rvm and ruby
|
# rvm and ruby
|
||||||
su - vagrant -c 'curl -sSL https://rvm.io/mpapis.asc | gpg --import -'
|
su - vagrant -c 'curl -sSL https://rvm.io/mpapis.asc | gpg --import -'
|
||||||
su - vagrant -c 'curl -sSL https://get.rvm.io | bash -s stable --ruby=2.1.3'
|
su - vagrant -c 'curl -sSL https://get.rvm.io | bash -s stable --ruby=2.3.0'
|
||||||
|
|
||||||
# install some other deps
|
# install some other deps
|
||||||
sudo apt-get install nodejs -y
|
sudo apt-get install nodejs -y
|
||||||
|
@ -31,15 +31,15 @@ sudo -u postgres psql -c "ALTER USER postgres WITH PASSWORD '3112';"
|
||||||
|
|
||||||
SCRIPT
|
SCRIPT
|
||||||
|
|
||||||
VAGRANTFILE_API_VERSION = "2"
|
VAGRANTFILE_API_VERSION = '2'
|
||||||
|
|
||||||
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
||||||
config.vm.box = "trusty64"
|
config.vm.box = 'trusty64'
|
||||||
config.vm.box_url = "http://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box"
|
config.vm.box_url = 'http://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box'
|
||||||
config.vm.network :forwarded_port, guest: 3000, host: 3000
|
config.vm.network :forwarded_port, guest: 3000, host: 3000
|
||||||
config.vm.network :forwarded_port, guest: 5001, host: 5001
|
config.vm.network :forwarded_port, guest: 5000, host: 5000
|
||||||
config.vm.network "private_network", ip: "10.0.1.11"
|
config.vm.network 'private_network', ip: '10.0.1.11'
|
||||||
config.vm.synced_folder ".", "/vagrant", :nfs => true
|
config.vm.synced_folder '.', '/vagrant', nfs: true
|
||||||
|
|
||||||
config.vm.provision "shell", inline: $script
|
config.vm.provision 'shell', inline: $script
|
||||||
end
|
end
|
||||||
|
|
7
app/assets/config/manifest.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
// eslint-disable spaced-comment
|
||||||
|
// JS and CSS bundles
|
||||||
|
//= link_directory ../javascripts .js
|
||||||
|
//= link_directory ../stylesheets .css
|
||||||
|
|
||||||
|
// Other
|
||||||
|
//= link_tree ../images
|
BIN
app/assets/images/.DS_Store
vendored
BIN
app/assets/images/addcollab_sprite.png
Normal file
After Width: | Height: | Size: 322 B |
Before Width: | Height: | Size: 543 B |
BIN
app/assets/images/exploremaps_sprite.png
Executable file → Normal file
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 3.1 KiB |
BIN
app/assets/images/import-example.png
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
app/assets/images/junto.gif
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
app/assets/images/junto_spinner_darkgrey.gif
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
app/assets/images/map_control_sprite.png
Normal file
After Width: | Height: | Size: 5.3 KiB |
BIN
app/assets/images/menu-alt-256.png
Normal file
After Width: | Height: | Size: 2 KiB |
BIN
app/assets/images/metadata.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
app/assets/images/metamaps-intro-poster.webp
Normal file
After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.9 KiB |
BIN
app/assets/images/mm_logo.png
Normal file
After Width: | Height: | Size: 3 KiB |
BIN
app/assets/images/newmap_sprite.png
Normal file
After Width: | Height: | Size: 667 B |
BIN
app/assets/images/pincarousel_sprite.png
Normal file
After Width: | Height: | Size: 822 B |
BIN
app/assets/images/removecollab_sprite.png
Normal file
After Width: | Height: | Size: 418 B |
BIN
app/assets/images/sounds/MM_sounds.mp3
Normal file
BIN
app/assets/images/sounds/MM_sounds.ogg
Normal file
BIN
app/assets/images/starmap_sprite.png
Normal file
After Width: | Height: | Size: 739 B |
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 3.4 KiB |
BIN
app/assets/images/user_sprite.png
Executable file → Normal file
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 2.6 KiB |
BIN
app/assets/images/view-only.png
Normal file
After Width: | Height: | Size: 421 B |
21
app/assets/javascripts/Metamaps.ServerData.js.erb
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
/* global Metamaps */
|
||||||
|
|
||||||
|
/* erb variables from rails */
|
||||||
|
Metamaps.ServerData = Metamaps.ServerData || {}
|
||||||
|
Metamaps.ServerData['junto_spinner_darkgrey.gif'] = '<%= asset_path('junto_spinner_darkgrey.gif') %>'
|
||||||
|
Metamaps.ServerData['user.png'] = '<%= asset_path('user.png') %>'
|
||||||
|
Metamaps.ServerData['icons/wildcard.png'] = '<%= asset_path('icons/wildcard.png') %>'
|
||||||
|
Metamaps.ServerData['topic_description_signifier.png'] = '<%= asset_path('topic_description_signifier.png') %>'
|
||||||
|
Metamaps.ServerData['topic_link_signifier.png'] = '<%= asset_path('topic_link_signifier.png') %>'
|
||||||
|
Metamaps.ServerData['synapse16.png'] = '<%= asset_path('synapse16.png') %>'
|
||||||
|
Metamaps.ServerData['sounds/MM_sounds.mp3'] = '<%= asset_path 'sounds/MM_sounds.mp3' %>'
|
||||||
|
Metamaps.ServerData['sounds/MM_sounds.ogg'] = '<%= asset_path 'sounds/MM_sounds.ogg' %>'
|
||||||
|
Metamaps.ServerData['exploremaps_sprite.png'] = '<%= asset_path 'exploremaps_sprite.png' %>'
|
||||||
|
Metamaps.ServerData['map_control_sprite.png'] = '<%= asset_path 'map_control_sprite.png' %>'
|
||||||
|
Metamaps.ServerData['user_sprite.png'] = '<%= asset_path 'user_sprite.png' %>'
|
||||||
|
Metamaps.ServerData.Metacodes = <%= Metacode.all.to_json.gsub(%r[(icon.*?)(\"},)], '\1?purple=stupid\2').html_safe %>
|
||||||
|
Metamaps.ServerData.REALTIME_SERVER = '<%= ENV['REALTIME_SERVER'] %>'
|
||||||
|
Metamaps.ServerData.RAILS_ENV = '<%= ENV['RAILS_ENV'] %>'
|
||||||
|
Metamaps.ServerData.VERSION = '<%= METAMAPS_VERSION %>'
|
||||||
|
Metamaps.ServerData.BUILD = '<%= METAMAPS_BUILD %>'
|
||||||
|
Metamaps.ServerData.LAST_UPDATED = '<%= METAMAPS_LAST_UPDATED %>'
|
23
app/assets/javascripts/application-secret.js
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
||||||
|
// listed below.
|
||||||
|
//
|
||||||
|
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
||||||
|
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
||||||
|
//
|
||||||
|
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
||||||
|
// the compiled file.
|
||||||
|
//
|
||||||
|
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
|
||||||
|
// GO AFTER THE REQUIRES BELOW.
|
||||||
|
//
|
||||||
|
/* eslint-disable spaced-comment */
|
||||||
|
//= require jquery
|
||||||
|
//= require jquery-ui
|
||||||
|
//= require jquery_ujs
|
||||||
|
//= require action_cable
|
||||||
|
//= require_directory ./lib
|
||||||
|
//= require ./cloudcarousel-secret
|
||||||
|
//= require ./metamaps.secret.bundle
|
||||||
|
//= require ./Metamaps.ServerData
|
||||||
|
//= require homepageVimeoFallback
|
||||||
|
/* eslint-enable spaced-comment */
|
|
@ -10,23 +10,13 @@
|
||||||
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
|
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
|
||||||
// GO AFTER THE REQUIRES BELOW.
|
// GO AFTER THE REQUIRES BELOW.
|
||||||
//
|
//
|
||||||
|
/* eslint-disable spaced-comment */
|
||||||
//= require jquery
|
//= require jquery
|
||||||
//= require jquery-ui
|
//= require jquery-ui
|
||||||
//= require jquery_ujs
|
//= require jquery_ujs
|
||||||
//= require ./orderedLibraries/underscore
|
//= require action_cable
|
||||||
//= require ./orderedLibraries/backbone
|
|
||||||
//= require_directory ./lib
|
//= require_directory ./lib
|
||||||
//= require ./src/Metamaps.GlobalUI
|
//= require ./webpacked/metamaps.bundle
|
||||||
//= require ./src/Metamaps.Router
|
//= require ./Metamaps.ServerData
|
||||||
//= require ./src/Metamaps.Backbone
|
//= require homepageVimeoFallback
|
||||||
//= require ./src/Metamaps.Views
|
/* eslint-enable spaced-comment */
|
||||||
//= require ./src/views/chatView
|
|
||||||
//= require ./src/views/videoView
|
|
||||||
//= require ./src/views/room
|
|
||||||
//= require ./src/JIT
|
|
||||||
//= require ./src/Metamaps
|
|
||||||
//= require ./src/Metamaps.Import
|
|
||||||
//= require ./src/Metamaps.JIT
|
|
||||||
//= require_directory ./shims
|
|
||||||
//= require_directory ./require
|
|
||||||
//= require_directory ./famous
|
|
||||||
|
|
438
app/assets/javascripts/cloudcarousel-secret.js
Normal file
|
@ -0,0 +1,438 @@
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// CloudCarousel V1.0.5
|
||||||
|
// (c) 2011 by R Cecco. <http://www.professorcloud.com>
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Reflection code based on plugin by Christophe Beyls <http://www.digitalia.be>
|
||||||
|
//
|
||||||
|
// Please retain this copyright header in all versions of the software
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
var matched, browser;
|
||||||
|
|
||||||
|
jQuery.uaMatch = function( ua ) {
|
||||||
|
ua = ua.toLowerCase();
|
||||||
|
|
||||||
|
var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
|
||||||
|
/(webkit)[ \/]([\w.]+)/.exec( ua ) ||
|
||||||
|
/(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
|
||||||
|
/(msie) ([\w.]+)/.exec( ua ) ||
|
||||||
|
ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
|
||||||
|
[];
|
||||||
|
|
||||||
|
return {
|
||||||
|
browser: match[ 1 ] || "",
|
||||||
|
version: match[ 2 ] || "0"
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
matched = jQuery.uaMatch( navigator.userAgent );
|
||||||
|
browser = {};
|
||||||
|
|
||||||
|
if ( matched.browser ) {
|
||||||
|
browser[ matched.browser ] = true;
|
||||||
|
browser.version = matched.version;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chrome is Webkit, but Webkit is also Safari.
|
||||||
|
if ( browser.chrome ) {
|
||||||
|
browser.webkit = true;
|
||||||
|
} else if ( browser.webkit ) {
|
||||||
|
browser.safari = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
jQuery.browser = browser;
|
||||||
|
|
||||||
|
(function($) {
|
||||||
|
|
||||||
|
// START Reflection object.
|
||||||
|
// Creates a reflection for underneath an image.
|
||||||
|
// IE uses an image with IE specific filter properties, other browsers use the Canvas tag.
|
||||||
|
// The position and size of the reflection gets updated by updateAll() in Controller.
|
||||||
|
function Reflection(img, reflHeight, opacity) {
|
||||||
|
|
||||||
|
var reflection, cntx, imageWidth = img.width, imageHeight = img.width, gradient, parent;
|
||||||
|
|
||||||
|
parent = $(img.parentNode);
|
||||||
|
this.element = reflection = parent.append("<canvas class='reflection' style='position:absolute'/>").find(':last')[0];
|
||||||
|
if ( !reflection.getContext && $.browser.msie) {
|
||||||
|
this.element = reflection = parent.append("<img class='reflection' style='position:absolute'/>").find(':last')[0];
|
||||||
|
reflection.src = img.src;
|
||||||
|
reflection.style.filter = "flipv progid:DXImageTransform.Microsoft.Alpha(opacity=" + (opacity * 100) + ", style=1, finishOpacity=0, startx=0, starty=0, finishx=0, finishy=" + (reflHeight / imageHeight * 100) + ")";
|
||||||
|
|
||||||
|
} else {
|
||||||
|
cntx = reflection.getContext("2d");
|
||||||
|
try {
|
||||||
|
|
||||||
|
|
||||||
|
$(reflection).attr({width: imageWidth, height: reflHeight});
|
||||||
|
cntx.save();
|
||||||
|
cntx.translate(0, imageHeight-1);
|
||||||
|
cntx.scale(1, -1);
|
||||||
|
cntx.drawImage(img, 0, 0, imageWidth, imageHeight);
|
||||||
|
cntx.restore();
|
||||||
|
cntx.globalCompositeOperation = "destination-out";
|
||||||
|
gradient = cntx.createLinearGradient(0, 0, 0, reflHeight);
|
||||||
|
gradient.addColorStop(0, "rgba(255, 255, 255, " + (1 - opacity) + ")");
|
||||||
|
gradient.addColorStop(1, "rgba(255, 255, 255, 1.0)");
|
||||||
|
cntx.fillStyle = gradient;
|
||||||
|
cntx.fillRect(0, 0, imageWidth, reflHeight);
|
||||||
|
} catch(e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Store a copy of the alt and title attrs into the reflection
|
||||||
|
$(reflection).attr({ 'alt': $(img).attr('alt'), title: $(img).attr('title')} );
|
||||||
|
|
||||||
|
} //END Reflection object
|
||||||
|
|
||||||
|
// START Item object.
|
||||||
|
// A wrapper object for items within the carousel.
|
||||||
|
var Item = function(imgIn, options)
|
||||||
|
{
|
||||||
|
this.orgWidth = imgIn.width;
|
||||||
|
this.orgHeight = imgIn.height;
|
||||||
|
this.image = imgIn;
|
||||||
|
this.reflection = null;
|
||||||
|
this.alt = imgIn.alt;
|
||||||
|
this.title = imgIn.title;
|
||||||
|
this.imageOK = false;
|
||||||
|
this.options = options;
|
||||||
|
|
||||||
|
this.imageOK = true;
|
||||||
|
|
||||||
|
if (this.options.reflHeight > 0)
|
||||||
|
{
|
||||||
|
this.reflection = new Reflection(this.image, this.options.reflHeight, this.options.reflOpacity);
|
||||||
|
}
|
||||||
|
$(this.image).css('position','absolute'); // Bizarre. This seems to reset image width to 0 on webkit!
|
||||||
|
};// END Item object
|
||||||
|
|
||||||
|
|
||||||
|
// Controller object.
|
||||||
|
// This handles moving all the items, dealing with mouse clicks etc.
|
||||||
|
var Controller = function(container, images, options)
|
||||||
|
{
|
||||||
|
var items = [], funcSin = Math.sin, funcCos = Math.cos, ctx=this;
|
||||||
|
this.controlTimer = 0;
|
||||||
|
this.stopped = false;
|
||||||
|
//this.imagesLoaded = 0;
|
||||||
|
this.container = container;
|
||||||
|
this.xRadius = options.xRadius;
|
||||||
|
this.yRadius = options.yRadius;
|
||||||
|
this.showFrontTextTimer = 0;
|
||||||
|
this.autoRotateTimer = 0;
|
||||||
|
if (options.xRadius === 0)
|
||||||
|
{
|
||||||
|
this.xRadius = ($(container).width()/2.3);
|
||||||
|
}
|
||||||
|
if (options.yRadius === 0)
|
||||||
|
{
|
||||||
|
this.yRadius = ($(container).height()/6);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.xCentre = options.xPos;
|
||||||
|
this.yCentre = options.yPos;
|
||||||
|
this.frontIndex = 0; // Index of the item at the front
|
||||||
|
|
||||||
|
// Start with the first item at the front.
|
||||||
|
this.rotation = this.destRotation = Math.PI/2;
|
||||||
|
this.timeDelay = 1000/options.FPS;
|
||||||
|
|
||||||
|
// Turn on the infoBox
|
||||||
|
if(options.altBox !== null)
|
||||||
|
{
|
||||||
|
$(options.altBox).css('display','block');
|
||||||
|
$(options.titleBox).css('display','block');
|
||||||
|
}
|
||||||
|
// Turn on relative position for container to allow absolutely positioned elements
|
||||||
|
// within it to work.
|
||||||
|
$(container).css({ position:'relative', overflow:'hidden'} );
|
||||||
|
|
||||||
|
$(options.buttonLeft).css('display','inline');
|
||||||
|
$(options.buttonRight).css('display','inline');
|
||||||
|
|
||||||
|
// Setup the buttons.
|
||||||
|
$(options.buttonLeft).bind('mouseup',this,function(event){
|
||||||
|
event.data.rotate(-1);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
$(options.buttonRight).bind('mouseup',this,function(event){
|
||||||
|
event.data.rotate(1);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// START METAMAPS CODE
|
||||||
|
// Add code that makes tab and shift+tab scroll through metacodes
|
||||||
|
$('.new_topic').bind('keydown',this,function(event){
|
||||||
|
if (event.keyCode == 9 && event.shiftKey) {
|
||||||
|
$(container).show()
|
||||||
|
event.data.rotate(-1);
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
} else if (event.keyCode == 9) {
|
||||||
|
$(container).show()
|
||||||
|
event.data.rotate(1);
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// END METAMAPS CODE
|
||||||
|
|
||||||
|
// You will need this plugin for the mousewheel to work: http://plugins.jquery.com/project/mousewheel
|
||||||
|
if (options.mouseWheel)
|
||||||
|
{
|
||||||
|
// START METAMAPS CODE
|
||||||
|
/*$('body').bind('mousewheel',this,function(event, delta) {
|
||||||
|
if (Metamaps.Create.newTopic.beingCreated &&
|
||||||
|
!Metamaps.Create.isSwitchingSet &&
|
||||||
|
!Metamaps.Create.newTopic.pinned) {
|
||||||
|
event.data.rotate(delta);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});*/
|
||||||
|
// END METAMAPS CODE
|
||||||
|
// ORIGINAL CODE
|
||||||
|
// $(container).bind('mousewheel',this,function(event, delta) {
|
||||||
|
// event.data.rotate(delta);
|
||||||
|
// return false;
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
}
|
||||||
|
$(container).unbind('mouseover click').bind('mouseover click',this,function(event){
|
||||||
|
|
||||||
|
clearInterval(event.data.autoRotateTimer); // Stop auto rotation if mouse over.
|
||||||
|
var text = $(event.target).attr('alt');
|
||||||
|
// If we have moved over a carousel item, then show the alt and title text.
|
||||||
|
|
||||||
|
if ( text !== undefined && text !== null )
|
||||||
|
{
|
||||||
|
|
||||||
|
clearTimeout(event.data.showFrontTextTimer);
|
||||||
|
$(options.altBox).html( ($(event.target).attr('alt') ));
|
||||||
|
//$(options.titleBox).html( ($(event.target).attr('title') ));
|
||||||
|
if ( options.bringToFront && event.type == 'click' )
|
||||||
|
{
|
||||||
|
$(options.titleBox).html( ($(event.target).attr('title') ));
|
||||||
|
// START METAMAPS CODE
|
||||||
|
Metamaps.Create.newTopic.metacode = $(event.target).attr('data-id');
|
||||||
|
// END METAMAPS CODE
|
||||||
|
var idx = $(event.target).data('itemIndex');
|
||||||
|
var frontIndex = event.data.frontIndex;
|
||||||
|
//var diff = idx - frontIndex;
|
||||||
|
var diff = (idx - frontIndex) % images.length;
|
||||||
|
if (Math.abs(diff) > images.length / 2) {
|
||||||
|
diff += (diff > 0 ? -images.length : images.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
event.data.rotate(-diff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// START METAMAPS CODE - initialize newTopic.metacode
|
||||||
|
var first = $(this.container).find('img').get(0)
|
||||||
|
Metamaps.Create.newTopic.metacode = $(first).data('id')
|
||||||
|
// END METAMAPS CODE
|
||||||
|
|
||||||
|
// If we have moved out of a carousel item (or the container itself),
|
||||||
|
// restore the text of the front item in 1 second.
|
||||||
|
$(container).bind('mouseout',this,function(event){
|
||||||
|
var context = event.data;
|
||||||
|
clearTimeout(context.showFrontTextTimer);
|
||||||
|
context.showFrontTextTimer = setTimeout( function(){context.showFrontText();},1000);
|
||||||
|
context.autoRotate(); // Start auto rotation.
|
||||||
|
});
|
||||||
|
|
||||||
|
// Prevent items from being selected as mouse is moved and clicked in the container.
|
||||||
|
$(container).bind('mousedown',this,function(event){
|
||||||
|
|
||||||
|
event.data.container.focus();
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
container.onselectstart = function () { return false; }; // For IE.
|
||||||
|
|
||||||
|
this.innerWrapper = $(container).wrapInner('<div style="position:absolute;width:100%;height:100%;"/>').children()[0];
|
||||||
|
|
||||||
|
// Shows the text from the front most item.
|
||||||
|
this.showFrontText = function()
|
||||||
|
{
|
||||||
|
if ( items[this.frontIndex] === undefined ) { return; } // Images might not have loaded yet.
|
||||||
|
// METAMAPS CODE
|
||||||
|
Metamaps.Create.newTopic.setMetacode($(items[this.frontIndex].image).attr('data-id'))
|
||||||
|
// NOT METAMAPS CODE
|
||||||
|
//$(options.titleBox).html( $(items[this.frontIndex].image).attr('title'));
|
||||||
|
//$(options.altBox).html( $(items[this.frontIndex].image).attr('alt'));
|
||||||
|
};
|
||||||
|
|
||||||
|
this.go = function()
|
||||||
|
{
|
||||||
|
if(this.controlTimer !== 0) { return; }
|
||||||
|
var context = this;
|
||||||
|
this.controlTimer = setTimeout( function(){context.updateAll();},this.timeDelay);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.stop = function()
|
||||||
|
{
|
||||||
|
clearTimeout(this.controlTimer);
|
||||||
|
this.controlTimer = 0;
|
||||||
|
// METAMAPS CODE
|
||||||
|
$(container).hide()
|
||||||
|
// END METAMAPS CODE
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Starts the rotation of the carousel. Direction is the number (+-) of carousel items to rotate by.
|
||||||
|
this.rotate = function(direction)
|
||||||
|
{
|
||||||
|
this.frontIndex -= direction;
|
||||||
|
if (this.frontIndex == -1) this.frontIndex = items.length - 1;
|
||||||
|
this.frontIndex %= items.length;
|
||||||
|
this.destRotation += ( Math.PI / items.length ) * ( 2*direction );
|
||||||
|
this.showFrontText();
|
||||||
|
this.go();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
this.autoRotate = function()
|
||||||
|
{
|
||||||
|
if ( options.autoRotate !== 'no' )
|
||||||
|
{
|
||||||
|
var dir = (options.autoRotate === 'right')? 1 : -1;
|
||||||
|
this.autoRotateTimer = setInterval( function(){ctx.rotate(dir); }, options.autoRotateDelay );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is the main loop function that moves everything.
|
||||||
|
this.updateAll = function()
|
||||||
|
{
|
||||||
|
var minScale = options.minScale; // This is the smallest scale applied to the furthest item.
|
||||||
|
var smallRange = (1-minScale) * 0.5;
|
||||||
|
var w,h,x,y,scale,item,sinVal;
|
||||||
|
|
||||||
|
var change = (this.destRotation - this.rotation);
|
||||||
|
var absChange = Math.abs(change);
|
||||||
|
|
||||||
|
this.rotation += change * options.speed;
|
||||||
|
if ( absChange < 0.001 ) { this.rotation = this.destRotation; }
|
||||||
|
var itemsLen = items.length;
|
||||||
|
var spacing = (Math.PI / itemsLen) * 2;
|
||||||
|
//var wrapStyle = null;
|
||||||
|
var radians = this.rotation;
|
||||||
|
var isMSIE = $.browser.msie;
|
||||||
|
|
||||||
|
// Turn off display. This can reduce repaints/reflows when making style and position changes in the loop.
|
||||||
|
// See http://dev.opera.com/articles/view/efficient-javascript/?page=3
|
||||||
|
this.innerWrapper.style.display = 'none';
|
||||||
|
|
||||||
|
var style;
|
||||||
|
var px = 'px', reflHeight;
|
||||||
|
var context = this;
|
||||||
|
for (var i = 0; i<itemsLen ;i++)
|
||||||
|
{
|
||||||
|
item = items[i];
|
||||||
|
|
||||||
|
sinVal = funcSin(radians);
|
||||||
|
|
||||||
|
scale = ((sinVal+1) * smallRange) + minScale;
|
||||||
|
|
||||||
|
x = this.xCentre + (( (funcCos(radians) * this.xRadius) - (item.orgWidth*0.5)) * scale);
|
||||||
|
y = this.yCentre + (( (sinVal * this.yRadius) ) * scale);
|
||||||
|
|
||||||
|
if (item.imageOK)
|
||||||
|
{
|
||||||
|
var img = item.image;
|
||||||
|
|
||||||
|
img.style.zIndex = "" + (scale * 100)>>0; // >>0 = Math.foor(). Firefox doesn't like fractional decimals in z-index.
|
||||||
|
w = img.width = item.orgWidth * scale;
|
||||||
|
h = img.height = item.orgHeight * scale;
|
||||||
|
img.style.left = x + px ;
|
||||||
|
img.style.top = y + px;
|
||||||
|
if (item.reflection !== null)
|
||||||
|
{
|
||||||
|
reflHeight = options.reflHeight * scale;
|
||||||
|
style = item.reflection.element.style;
|
||||||
|
style.left = x + px;
|
||||||
|
style.top = y + h + options.reflGap * scale + px;
|
||||||
|
style.width = w + px;
|
||||||
|
if (isMSIE)
|
||||||
|
{
|
||||||
|
style.filter.finishy = (reflHeight / h * 100);
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
style.height = reflHeight + px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
radians += spacing;
|
||||||
|
}
|
||||||
|
// Turn display back on.
|
||||||
|
this.innerWrapper.style.display = 'block';
|
||||||
|
|
||||||
|
// If we have a preceptable change in rotation then loop again next frame.
|
||||||
|
if ( absChange >= 0.001 )
|
||||||
|
{
|
||||||
|
this.controlTimer = setTimeout( function(){context.updateAll();},this.timeDelay);
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
// Otherwise just stop completely.
|
||||||
|
this.stop();
|
||||||
|
}
|
||||||
|
}; // END updateAll
|
||||||
|
|
||||||
|
// Create an Item object for each image
|
||||||
|
// func = function(){return;ctx.updateAll();} ;
|
||||||
|
|
||||||
|
// Check if images have loaded. We need valid widths and heights for the reflections.
|
||||||
|
this.checkImagesLoaded = function()
|
||||||
|
{
|
||||||
|
var i;
|
||||||
|
for(i=0;i<images.length;i++) {
|
||||||
|
if ( (images[i].width === undefined) || ( (images[i].complete !== undefined) && (!images[i].complete) ))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(i=0;i<images.length;i++) {
|
||||||
|
items.push( new Item( images[i], options ) );
|
||||||
|
$(images[i]).data('itemIndex',i);
|
||||||
|
}
|
||||||
|
// If all images have valid widths and heights, we can stop checking.
|
||||||
|
clearInterval(this.tt);
|
||||||
|
// METAMAPS COMMENT this.showFrontText();
|
||||||
|
this.autoRotate();
|
||||||
|
this.updateAll();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
this.tt = setInterval( function(){ctx.checkImagesLoaded();},50);
|
||||||
|
}; // END Controller object
|
||||||
|
|
||||||
|
// The jQuery plugin part. Iterates through items specified in selector and inits a Controller class for each one.
|
||||||
|
$.fn.CloudCarousel = function(options) {
|
||||||
|
|
||||||
|
this.each( function() {
|
||||||
|
|
||||||
|
options = $.extend({}, {
|
||||||
|
reflHeight:0,
|
||||||
|
reflOpacity:0.5,
|
||||||
|
reflGap:0,
|
||||||
|
minScale:0.5,
|
||||||
|
xPos:0,
|
||||||
|
yPos:0,
|
||||||
|
xRadius:0,
|
||||||
|
yRadius:0,
|
||||||
|
altBox:null,
|
||||||
|
titleBox:null,
|
||||||
|
FPS: 30,
|
||||||
|
autoRotate: 'no',
|
||||||
|
autoRotateDelay: 1500,
|
||||||
|
speed:0.2,
|
||||||
|
mouseWheel: false,
|
||||||
|
bringToFront: false
|
||||||
|
},options );
|
||||||
|
// Create a Controller for each carousel.
|
||||||
|
$(this).data('cloudcarousel', new Controller( this, $('.cloudcarousel',$(this)), options) );
|
||||||
|
});
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
})(jQuery);
|
50
app/assets/javascripts/famous/famous.min.js
vendored
29
app/assets/javascripts/homepageVimeoFallback.js.erb
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/* global $ */
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
if (window.location.pathname === '/') {
|
||||||
|
$.ajax({
|
||||||
|
type: 'GET',
|
||||||
|
url: 'https://i.vimeocdn.com/video/',
|
||||||
|
error: function(e) {
|
||||||
|
$('.homeVideo').hide()
|
||||||
|
$('.homeVideo').replaceWith($('<video/>', {
|
||||||
|
poster: '<%= asset_path('metamaps-intro-poster.webp') %>',
|
||||||
|
width: '560',
|
||||||
|
height: '315',
|
||||||
|
class: 'homeVideo',
|
||||||
|
controls: ''
|
||||||
|
}))
|
||||||
|
$('.homeVideo').append($('<source/>', {
|
||||||
|
src: 'https://metamaps.cc/videos/metamaps-intro.mp4',
|
||||||
|
type: 'video/mp4'
|
||||||
|
}))
|
||||||
|
$('.homeVideo').append(
|
||||||
|
'<p>You can watch our instruction video at ' +
|
||||||
|
'<a href="https://metamaps.cc/videos/metamaps-intro.mp4">' +
|
||||||
|
'https://metamaps.cc/videos/metamaps-intro.mp4</a>.'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}// if
|
||||||
|
})
|
161
app/assets/javascripts/lib/ajaxq.js
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
// AjaxQ jQuery Plugin
|
||||||
|
// Copyright (c) 2012 Foliotek Inc.
|
||||||
|
// MIT License
|
||||||
|
// https://github.com/Foliotek/ajaxq
|
||||||
|
// Uses CommonJS, AMD or browser globals to create a jQuery plugin.
|
||||||
|
|
||||||
|
(function (factory) {
|
||||||
|
if (typeof define === 'function' && define.amd) {
|
||||||
|
// AMD. Register as an anonymous module.
|
||||||
|
define(['jquery'], factory);
|
||||||
|
} else if (typeof module === 'object' && module.exports) {
|
||||||
|
// Node/CommonJS
|
||||||
|
module.exports = factory(require('jquery'));
|
||||||
|
} else {
|
||||||
|
// Browser globals
|
||||||
|
factory(jQuery);
|
||||||
|
}
|
||||||
|
}(function ($) {
|
||||||
|
var queues = {};
|
||||||
|
var activeReqs = {};
|
||||||
|
|
||||||
|
// Register an $.ajaxq function, which follows the $.ajax interface, but allows a queue name which will force only one request per queue to fire.
|
||||||
|
// opts can be the regular $.ajax settings plainObject, or a callback returning the settings object, to be evaluated just prior to the actual call to $.ajax.
|
||||||
|
$.ajaxq = function(qname, opts) {
|
||||||
|
|
||||||
|
if (typeof opts === "undefined") {
|
||||||
|
throw ("AjaxQ: queue name is not provided");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Will return a Deferred promise object extended with success/error/callback, so that this function matches the interface of $.ajax
|
||||||
|
var deferred = $.Deferred(),
|
||||||
|
promise = deferred.promise();
|
||||||
|
|
||||||
|
promise.success = promise.done;
|
||||||
|
promise.error = promise.fail;
|
||||||
|
promise.complete = promise.always;
|
||||||
|
|
||||||
|
// Check whether options are to be evaluated at call time or not.
|
||||||
|
var deferredOpts = typeof opts === 'function';
|
||||||
|
// Create a deep copy of the arguments, and enqueue this request.
|
||||||
|
var clonedOptions = !deferredOpts ? $.extend(true, {}, opts) : null;
|
||||||
|
enqueue(function() {
|
||||||
|
// Send off the ajax request now that the item has been removed from the queue
|
||||||
|
var jqXHR = $.ajax.apply(window, [deferredOpts ? opts() : clonedOptions]);
|
||||||
|
|
||||||
|
// Notify the returned deferred object with the correct context when the jqXHR is done or fails
|
||||||
|
// Note that 'always' will automatically be fired once one of these are called: http://api.jquery.com/category/deferred-object/.
|
||||||
|
jqXHR.done(function() {
|
||||||
|
deferred.resolve.apply(this, arguments);
|
||||||
|
});
|
||||||
|
jqXHR.fail(function() {
|
||||||
|
deferred.reject.apply(this, arguments);
|
||||||
|
});
|
||||||
|
|
||||||
|
jqXHR.always(dequeue); // make sure to dequeue the next request AFTER the done and fail callbacks are fired
|
||||||
|
|
||||||
|
return jqXHR;
|
||||||
|
});
|
||||||
|
|
||||||
|
return promise;
|
||||||
|
|
||||||
|
|
||||||
|
// If there is no queue, create an empty one and instantly process this item.
|
||||||
|
// Otherwise, just add this item onto it for later processing.
|
||||||
|
function enqueue(cb) {
|
||||||
|
if (!queues[qname]) {
|
||||||
|
queues[qname] = [];
|
||||||
|
var xhr = cb();
|
||||||
|
activeReqs[qname] = xhr;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
queues[qname].push(cb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the next callback from the queue and fire it off.
|
||||||
|
// If the queue was empty (this was the last item), delete it from memory so the next one can be instantly processed.
|
||||||
|
function dequeue() {
|
||||||
|
if (!queues[qname]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var nextCallback = queues[qname].shift();
|
||||||
|
if (nextCallback) {
|
||||||
|
var xhr = nextCallback();
|
||||||
|
activeReqs[qname] = xhr;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
delete queues[qname];
|
||||||
|
delete activeReqs[qname];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Register a $.postq and $.getq method to provide shortcuts for $.get and $.post
|
||||||
|
// Copied from jQuery source to make sure the functions share the same defaults as $.get and $.post.
|
||||||
|
$.each( [ "getq", "postq" ], function( i, method ) {
|
||||||
|
$[ method ] = function( qname, url, data, callback, type ) {
|
||||||
|
|
||||||
|
if ( $.isFunction( data ) ) {
|
||||||
|
type = type || callback;
|
||||||
|
callback = data;
|
||||||
|
data = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $.ajaxq(qname, {
|
||||||
|
type: method === "postq" ? "post" : "get",
|
||||||
|
url: url,
|
||||||
|
data: data,
|
||||||
|
success: callback,
|
||||||
|
dataType: type
|
||||||
|
});
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
var isQueueRunning = function(qname) {
|
||||||
|
return (queues.hasOwnProperty(qname) && queues[qname].length > 0) || activeReqs.hasOwnProperty(qname);
|
||||||
|
};
|
||||||
|
|
||||||
|
var isAnyQueueRunning = function() {
|
||||||
|
for (var i in queues) {
|
||||||
|
if (isQueueRunning(i)) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
$.ajaxq.isRunning = function(qname) {
|
||||||
|
if (qname) return isQueueRunning(qname);
|
||||||
|
else return isAnyQueueRunning();
|
||||||
|
};
|
||||||
|
|
||||||
|
$.ajaxq.getActiveRequest = function(qname) {
|
||||||
|
if (!qname) throw ("AjaxQ: queue name is required");
|
||||||
|
|
||||||
|
return activeReqs[qname];
|
||||||
|
};
|
||||||
|
|
||||||
|
$.ajaxq.abort = function(qname) {
|
||||||
|
if (!qname) throw ("AjaxQ: queue name is required");
|
||||||
|
|
||||||
|
var current = $.ajaxq.getActiveRequest(qname);
|
||||||
|
delete queues[qname];
|
||||||
|
delete activeReqs[qname];
|
||||||
|
if (current) current.abort();
|
||||||
|
};
|
||||||
|
|
||||||
|
$.ajaxq.clear = function(qname) {
|
||||||
|
if (!qname) {
|
||||||
|
for (var i in queues) {
|
||||||
|
if (queues.hasOwnProperty(i)) {
|
||||||
|
queues[i] = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (queues[qname]) {
|
||||||
|
queues[qname] = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}));
|
|
@ -1,39 +0,0 @@
|
||||||
var attachMediaStream = function (stream, el, options) {
|
|
||||||
var URL = window.URL;
|
|
||||||
var opts = {
|
|
||||||
autoplay: true,
|
|
||||||
mirror: false,
|
|
||||||
muted: false
|
|
||||||
};
|
|
||||||
var element = el || document.createElement('video');
|
|
||||||
var item;
|
|
||||||
|
|
||||||
if (options) {
|
|
||||||
for (item in options) {
|
|
||||||
opts[item] = options[item];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opts.autoplay) element.autoplay = 'autoplay';
|
|
||||||
if (opts.muted) element.muted = true;
|
|
||||||
if (opts.mirror) {
|
|
||||||
['', 'moz', 'webkit', 'o', 'ms'].forEach(function (prefix) {
|
|
||||||
var styleName = prefix ? prefix + 'Transform' : 'transform';
|
|
||||||
element.style[styleName] = 'scaleX(-1)';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// this first one should work most everywhere now
|
|
||||||
// but we have a few fallbacks just in case.
|
|
||||||
if (URL && URL.createObjectURL) {
|
|
||||||
element.src = URL.createObjectURL(stream);
|
|
||||||
} else if (element.srcObject) {
|
|
||||||
element.srcObject = stream;
|
|
||||||
} else if (element.mozSrcObject) {
|
|
||||||
element.mozSrcObject = stream;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return element;
|
|
||||||
};
|
|
685
app/assets/javascripts/lib/best_in_place.js
Normal file
|
@ -0,0 +1,685 @@
|
||||||
|
/*
|
||||||
|
* BestInPlace (for jQuery)
|
||||||
|
* version: 3.0.0.alpha (2014)
|
||||||
|
*
|
||||||
|
* By Bernat Farrero based on the work of Jan Varwig.
|
||||||
|
* Examples at http://bernatfarrero.com
|
||||||
|
*
|
||||||
|
* Licensed under the MIT:
|
||||||
|
* http://www.opensource.org/licenses/mit-license.php
|
||||||
|
*
|
||||||
|
* @requires jQuery
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
*
|
||||||
|
* Attention.
|
||||||
|
* The format of the JSON object given to the select inputs is the following:
|
||||||
|
* [["key", "value"],["key", "value"]]
|
||||||
|
* The format of the JSON object given to the checkbox inputs is the following:
|
||||||
|
* ["falseValue", "trueValue"]
|
||||||
|
|
||||||
|
*/
|
||||||
|
//= require jquery.autosize
|
||||||
|
|
||||||
|
function BestInPlaceEditor(e) {
|
||||||
|
'use strict';
|
||||||
|
this.element = e;
|
||||||
|
this.initOptions();
|
||||||
|
this.bindForm();
|
||||||
|
this.initPlaceHolder();
|
||||||
|
jQuery(this.activator).bind('click', {editor: this}, this.clickHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
BestInPlaceEditor.prototype = {
|
||||||
|
// Public Interface Functions //////////////////////////////////////////////
|
||||||
|
|
||||||
|
activate: function () {
|
||||||
|
'use strict';
|
||||||
|
var to_display;
|
||||||
|
if (this.isPlaceHolder()) {
|
||||||
|
to_display = "";
|
||||||
|
} else if (this.original_content) {
|
||||||
|
to_display = this.original_content;
|
||||||
|
} else {
|
||||||
|
switch (this.formType) {
|
||||||
|
case 'input':
|
||||||
|
case 'textarea':
|
||||||
|
if (this.display_raw) {
|
||||||
|
to_display = this.element.html().replace(/&/gi, '&');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var value = this.element.data('bipValue');
|
||||||
|
if (typeof value === 'undefined') {
|
||||||
|
to_display = '';
|
||||||
|
} else if (typeof value === 'string') {
|
||||||
|
to_display = this.element.data('bipValue').replace(/&/gi, '&');
|
||||||
|
} else {
|
||||||
|
to_display = this.element.data('bipValue');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'select':
|
||||||
|
to_display = this.element.html();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.oldValue = this.isPlaceHolder() ? "" : this.element.html();
|
||||||
|
this.display_value = to_display;
|
||||||
|
jQuery(this.activator).unbind("click", this.clickHandler);
|
||||||
|
this.activateForm();
|
||||||
|
this.element.trigger(jQuery.Event("best_in_place:activate"));
|
||||||
|
},
|
||||||
|
|
||||||
|
abort: function () {
|
||||||
|
'use strict';
|
||||||
|
this.activateText(this.oldValue);
|
||||||
|
jQuery(this.activator).bind('click', {editor: this}, this.clickHandler);
|
||||||
|
this.element.trigger(jQuery.Event("best_in_place:abort"));
|
||||||
|
this.element.trigger(jQuery.Event("best_in_place:deactivate"));
|
||||||
|
},
|
||||||
|
|
||||||
|
abortIfConfirm: function () {
|
||||||
|
'use strict';
|
||||||
|
if (!this.useConfirm) {
|
||||||
|
this.abort();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (confirm(BestInPlaceEditor.defaults.locales[''].confirmMessage)) {
|
||||||
|
this.abort();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
update: function () {
|
||||||
|
'use strict';
|
||||||
|
var editor = this,
|
||||||
|
value = this.getValue();
|
||||||
|
|
||||||
|
// Avoid request if no change is made
|
||||||
|
if (this.formType in {"input": 1, "textarea": 1} && value === this.oldValue) {
|
||||||
|
this.abort();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
editor.ajax({
|
||||||
|
"type": this.requestMethod(),
|
||||||
|
"dataType": BestInPlaceEditor.defaults.ajaxDataType,
|
||||||
|
"data": editor.requestData(),
|
||||||
|
"success": function (data, status, xhr) {
|
||||||
|
editor.loadSuccessCallback(data, status, xhr);
|
||||||
|
},
|
||||||
|
"error": function (request, error) {
|
||||||
|
editor.loadErrorCallback(request, error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
switch (this.formType) {
|
||||||
|
case "select":
|
||||||
|
this.previousCollectionValue = value;
|
||||||
|
|
||||||
|
// search for the text for the span
|
||||||
|
$.each(this.values, function(index, arr){ if (String(arr[0]) === String(value)) editor.element.html(arr[1]); });
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "checkbox":
|
||||||
|
$.each(this.values, function(index, arr){ if (String(arr[0]) === String(value)) editor.element.html(arr[1]); });
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (value !== "") {
|
||||||
|
if (this.display_raw) {
|
||||||
|
editor.element.html(value);
|
||||||
|
} else {
|
||||||
|
editor.element.text(value);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
editor.element.html(this.placeHolder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
editor.element.data('bipValue', value);
|
||||||
|
editor.element.attr('data-bip-value', value);
|
||||||
|
|
||||||
|
editor.element.trigger(jQuery.Event("best_in_place:update"));
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
activateForm: function () {
|
||||||
|
'use strict';
|
||||||
|
alert(BestInPlaceEditor.defaults.locales[''].uninitializedForm);
|
||||||
|
},
|
||||||
|
|
||||||
|
activateText: function (value) {
|
||||||
|
'use strict';
|
||||||
|
this.element.html(value);
|
||||||
|
if (this.isPlaceHolder()) {
|
||||||
|
this.element.html(this.placeHolder);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Helper Functions ////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
initOptions: function () {
|
||||||
|
// Try parent supplied info
|
||||||
|
'use strict';
|
||||||
|
var self = this;
|
||||||
|
self.element.parents().each(function () {
|
||||||
|
var $parent = jQuery(this);
|
||||||
|
self.url = self.url || $parent.data("bipUrl");
|
||||||
|
self.activator = self.activator || $parent.data("bipActivator");
|
||||||
|
self.okButton = self.okButton || $parent.data("bipOkButton");
|
||||||
|
self.okButtonClass = self.okButtonClass || $parent.data("bipOkButtonClass");
|
||||||
|
self.cancelButton = self.cancelButton || $parent.data("bipCancelButton");
|
||||||
|
self.cancelButtonClass = self.cancelButtonClass || $parent.data("bipCancelButtonClass");
|
||||||
|
self.skipBlur = self.skipBlur || $parent.data("bipSkipBlur");
|
||||||
|
});
|
||||||
|
|
||||||
|
// Load own attributes (overrides all others)
|
||||||
|
self.url = self.element.data("bipUrl") || self.url || document.location.pathname;
|
||||||
|
self.collection = self.element.data("bipCollection") || self.collection;
|
||||||
|
self.formType = self.element.data("bipType") || "input";
|
||||||
|
self.objectName = self.element.data("bipObject") || self.objectName;
|
||||||
|
self.attributeName = self.element.data("bipAttribute") || self.attributeName;
|
||||||
|
self.activator = self.element.data("bipActivator") || self.element;
|
||||||
|
self.okButton = self.element.data("bipOkButton") || self.okButton;
|
||||||
|
self.okButtonClass = self.element.data("bipOkButtonClass") || self.okButtonClass || BestInPlaceEditor.defaults.okButtonClass;
|
||||||
|
self.cancelButton = self.element.data("bipCancelButton") || self.cancelButton;
|
||||||
|
self.cancelButtonClass = self.element.data("bipCancelButtonClass") || self.cancelButtonClass || BestInPlaceEditor.defaults.cancelButtonClass;
|
||||||
|
self.skipBlur = self.element.data("bipSkipBlur") || self.skipBlur || BestInPlaceEditor.defaults.skipBlur;
|
||||||
|
self.isNewObject = self.element.data("bipNewObject");
|
||||||
|
self.dataExtraPayload = self.element.data("bipExtraPayload");
|
||||||
|
|
||||||
|
// Fix for default values of 0
|
||||||
|
if (self.element.data("bipPlaceholder") == null) {
|
||||||
|
self.placeHolder = BestInPlaceEditor.defaults.locales[''].placeHolder;
|
||||||
|
} else {
|
||||||
|
self.placeHolder = self.element.data("bipPlaceholder");
|
||||||
|
}
|
||||||
|
|
||||||
|
self.inner_class = self.element.data("bipInnerClass");
|
||||||
|
self.html_attrs = self.element.data("bipHtmlAttrs");
|
||||||
|
self.original_content = self.element.data("bipOriginalContent") || self.original_content;
|
||||||
|
|
||||||
|
// if set the input won't be satinized
|
||||||
|
self.display_raw = self.element.data("bip-raw");
|
||||||
|
|
||||||
|
self.useConfirm = self.element.data("bip-confirm");
|
||||||
|
|
||||||
|
if (self.formType === "select" || self.formType === "checkbox") {
|
||||||
|
self.values = self.collection;
|
||||||
|
self.collectionValue = self.element.data("bipValue") || self.collectionValue;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
bindForm: function () {
|
||||||
|
'use strict';
|
||||||
|
this.activateForm = BestInPlaceEditor.forms[this.formType].activateForm;
|
||||||
|
this.getValue = BestInPlaceEditor.forms[this.formType].getValue;
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
initPlaceHolder: function () {
|
||||||
|
'use strict';
|
||||||
|
// TODO add placeholder for select and checkbox
|
||||||
|
if (this.element.html() === "") {
|
||||||
|
this.element.addClass('bip-placeholder');
|
||||||
|
this.element.html(this.placeHolder);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
isPlaceHolder: function () {
|
||||||
|
'use strict';
|
||||||
|
// TODO: It only work when form is deactivated.
|
||||||
|
// Condition will fail when form is activated
|
||||||
|
return this.element.html() === "" || this.element.html() === this.placeHolder;
|
||||||
|
},
|
||||||
|
|
||||||
|
getValue: function () {
|
||||||
|
'use strict';
|
||||||
|
alert(BestInPlaceEditor.defaults.locales[''].uninitializedForm);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Trim and Strips HTML from text
|
||||||
|
sanitizeValue: function (s) {
|
||||||
|
'use strict';
|
||||||
|
return jQuery.trim(s);
|
||||||
|
},
|
||||||
|
|
||||||
|
requestMethod: function() {
|
||||||
|
'use strict';
|
||||||
|
return this.isNewObject ? 'post' : BestInPlaceEditor.defaults.ajaxMethod;
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Generate the data sent in the POST request */
|
||||||
|
requestData: function () {
|
||||||
|
'use strict';
|
||||||
|
// To prevent xss attacks, a csrf token must be defined as a meta attribute
|
||||||
|
var csrf_token = jQuery('meta[name=csrf-token]').attr('content'),
|
||||||
|
csrf_param = jQuery('meta[name=csrf-param]').attr('content');
|
||||||
|
|
||||||
|
var data = {}
|
||||||
|
data['_method'] = this.requestMethod()
|
||||||
|
|
||||||
|
data[this.objectName] = this.dataExtraPayload || {}
|
||||||
|
|
||||||
|
data[this.objectName][this.attributeName] = this.getValue()
|
||||||
|
|
||||||
|
if (csrf_param !== undefined && csrf_token !== undefined) {
|
||||||
|
data[csrf_param] = csrf_token
|
||||||
|
}
|
||||||
|
return jQuery.param(data);
|
||||||
|
},
|
||||||
|
|
||||||
|
ajax: function (options) {
|
||||||
|
'use strict';
|
||||||
|
options.url = this.url;
|
||||||
|
options.beforeSend = function (xhr) {
|
||||||
|
xhr.setRequestHeader("Accept", "application/json");
|
||||||
|
};
|
||||||
|
return jQuery.ajax(options);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Handlers ////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
loadSuccessCallback: function (data, status, xhr) {
|
||||||
|
'use strict';
|
||||||
|
data = jQuery.trim(data);
|
||||||
|
//Update original content with current text.
|
||||||
|
if (this.display_raw) {
|
||||||
|
this.original_content = this.element.html();
|
||||||
|
} else {
|
||||||
|
this.original_content = this.element.text();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data && data !== "") {
|
||||||
|
var response = jQuery.parseJSON(data);
|
||||||
|
if (response !== null && response.hasOwnProperty("display_as")) {
|
||||||
|
this.element.data('bip-original-content', this.element.text());
|
||||||
|
this.element.html(response.display_as);
|
||||||
|
}
|
||||||
|
if (this.isNewObject && response && response[this.objectName]) {
|
||||||
|
if (response[this.objectName]["id"]) {
|
||||||
|
this.isNewObject = false
|
||||||
|
this.url += "/" + response[this.objectName]["id"] // in REST a POST /thing url should become PUT /thing/123
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.element.toggleClass('bip-placeholder', this.isPlaceHolder());
|
||||||
|
|
||||||
|
this.element.trigger(jQuery.Event("best_in_place:success"), [data, status, xhr]);
|
||||||
|
this.element.trigger(jQuery.Event("ajax:success"), [data, status, xhr]);
|
||||||
|
|
||||||
|
// Binding back after being clicked
|
||||||
|
jQuery(this.activator).bind('click', {editor: this}, this.clickHandler);
|
||||||
|
this.element.trigger(jQuery.Event("best_in_place:deactivate"));
|
||||||
|
|
||||||
|
if (this.collectionValue !== null && this.formType === "select") {
|
||||||
|
this.collectionValue = this.previousCollectionValue;
|
||||||
|
this.previousCollectionValue = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
loadErrorCallback: function (request, error) {
|
||||||
|
'use strict';
|
||||||
|
this.activateText(this.oldValue);
|
||||||
|
|
||||||
|
this.element.trigger(jQuery.Event("best_in_place:error"), [request, error]);
|
||||||
|
this.element.trigger(jQuery.Event("ajax:error"), request, error);
|
||||||
|
|
||||||
|
// Binding back after being clicked
|
||||||
|
jQuery(this.activator).bind('click', {editor: this}, this.clickHandler);
|
||||||
|
this.element.trigger(jQuery.Event("best_in_place:deactivate"));
|
||||||
|
},
|
||||||
|
|
||||||
|
clickHandler: function (event) {
|
||||||
|
'use strict';
|
||||||
|
event.preventDefault();
|
||||||
|
event.data.editor.activate();
|
||||||
|
},
|
||||||
|
|
||||||
|
setHtmlAttributes: function () {
|
||||||
|
'use strict';
|
||||||
|
var formField = this.element.find(this.formType);
|
||||||
|
|
||||||
|
if (this.html_attrs) {
|
||||||
|
var attrs = this.html_attrs;
|
||||||
|
$.each(attrs, function (key, val) {
|
||||||
|
formField.attr(key, val);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
placeButtons: function (output, field) {
|
||||||
|
'use strict';
|
||||||
|
if (field.okButton) {
|
||||||
|
output.append(
|
||||||
|
jQuery(document.createElement('input'))
|
||||||
|
.attr('type', 'submit')
|
||||||
|
.attr('class', field.okButtonClass)
|
||||||
|
.attr('value', field.okButton)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (field.cancelButton) {
|
||||||
|
output.append(
|
||||||
|
jQuery(document.createElement('input'))
|
||||||
|
.attr('type', 'button')
|
||||||
|
.attr('class', field.cancelButtonClass)
|
||||||
|
.attr('value', field.cancelButton)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Button cases:
|
||||||
|
// If no buttons, then blur saves, ESC cancels
|
||||||
|
// If just Cancel button, then blur saves, ESC or clicking Cancel cancels (careful of blur event!)
|
||||||
|
// If just OK button, then clicking OK saves (careful of blur event!), ESC or blur cancels
|
||||||
|
// If both buttons, then clicking OK saves, ESC or clicking Cancel or blur cancels
|
||||||
|
BestInPlaceEditor.forms = {
|
||||||
|
"input": {
|
||||||
|
activateForm: function () {
|
||||||
|
'use strict';
|
||||||
|
var output = jQuery(document.createElement('form'))
|
||||||
|
.addClass('form_in_place')
|
||||||
|
.attr('action', 'javascript:void(0);')
|
||||||
|
.attr('style', 'display:inline');
|
||||||
|
var input_elt = jQuery(document.createElement('input'))
|
||||||
|
.attr('type', 'text')
|
||||||
|
.attr('name', this.attributeName)
|
||||||
|
.val(this.display_value);
|
||||||
|
|
||||||
|
// Add class to form input
|
||||||
|
if (this.inner_class) {
|
||||||
|
input_elt.addClass(this.inner_class);
|
||||||
|
}
|
||||||
|
|
||||||
|
output.append(input_elt);
|
||||||
|
this.placeButtons(output, this);
|
||||||
|
|
||||||
|
this.element.html(output);
|
||||||
|
this.setHtmlAttributes();
|
||||||
|
|
||||||
|
this.element.find("input[type='text']")[0].select();
|
||||||
|
this.element.find("form").bind('submit', {editor: this}, BestInPlaceEditor.forms.input.submitHandler);
|
||||||
|
if (this.cancelButton) {
|
||||||
|
this.element.find("input[type='button']").bind('click', {editor: this}, BestInPlaceEditor.forms.input.cancelButtonHandler);
|
||||||
|
}
|
||||||
|
if (!this.okButton) {
|
||||||
|
this.element.find("input[type='text']").bind('blur', {editor: this}, BestInPlaceEditor.forms.input.inputBlurHandler);
|
||||||
|
}
|
||||||
|
this.element.find("input[type='text']").bind('keyup', {editor: this}, BestInPlaceEditor.forms.input.keyupHandler);
|
||||||
|
this.blurTimer = null;
|
||||||
|
this.userClicked = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
getValue: function () {
|
||||||
|
'use strict';
|
||||||
|
return this.sanitizeValue(this.element.find("input").val());
|
||||||
|
},
|
||||||
|
|
||||||
|
// When buttons are present, use a timer on the blur event to give precedence to clicks
|
||||||
|
inputBlurHandler: function (event) {
|
||||||
|
'use strict';
|
||||||
|
if (event.data.editor.okButton) {
|
||||||
|
event.data.editor.blurTimer = setTimeout(function () {
|
||||||
|
if (!event.data.editor.userClicked) {
|
||||||
|
event.data.editor.abort();
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
|
} else {
|
||||||
|
if (event.data.editor.cancelButton) {
|
||||||
|
event.data.editor.blurTimer = setTimeout(function () {
|
||||||
|
if (!event.data.editor.userClicked) {
|
||||||
|
event.data.editor.update();
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
|
} else {
|
||||||
|
event.data.editor.update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
submitHandler: function (event) {
|
||||||
|
'use strict';
|
||||||
|
event.data.editor.userClicked = true;
|
||||||
|
clearTimeout(event.data.editor.blurTimer);
|
||||||
|
event.data.editor.update();
|
||||||
|
},
|
||||||
|
|
||||||
|
cancelButtonHandler: function (event) {
|
||||||
|
'use strict';
|
||||||
|
event.data.editor.userClicked = true;
|
||||||
|
clearTimeout(event.data.editor.blurTimer);
|
||||||
|
event.data.editor.abort();
|
||||||
|
event.stopPropagation(); // Without this, click isn't handled
|
||||||
|
},
|
||||||
|
|
||||||
|
keyupHandler: function (event) {
|
||||||
|
'use strict';
|
||||||
|
if (event.keyCode === 27) {
|
||||||
|
event.data.editor.abort();
|
||||||
|
event.stopImmediatePropagation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"select": {
|
||||||
|
activateForm: function () {
|
||||||
|
'use strict';
|
||||||
|
var output = jQuery(document.createElement('form'))
|
||||||
|
.attr('action', 'javascript:void(0)')
|
||||||
|
.attr('style', 'display:inline'),
|
||||||
|
selected = '',
|
||||||
|
select_elt = jQuery(document.createElement('select'))
|
||||||
|
.attr('class', this.inner_class !== null ? this.inner_class : ''),
|
||||||
|
currentCollectionValue = this.collectionValue,
|
||||||
|
key, value,
|
||||||
|
a = this.values;
|
||||||
|
|
||||||
|
$.each(a, function(index, arr){
|
||||||
|
key = arr[0];
|
||||||
|
value = arr[1];
|
||||||
|
var option_elt = jQuery(document.createElement('option'))
|
||||||
|
.val(key)
|
||||||
|
.html(value);
|
||||||
|
|
||||||
|
if (currentCollectionValue) {
|
||||||
|
if (String(key) === String(currentCollectionValue)) option_elt.attr('selected', 'selected');
|
||||||
|
}
|
||||||
|
select_elt.append(option_elt);
|
||||||
|
});
|
||||||
|
output.append(select_elt);
|
||||||
|
|
||||||
|
this.element.html(output);
|
||||||
|
this.setHtmlAttributes();
|
||||||
|
this.element.find("select").bind('change', {editor: this}, BestInPlaceEditor.forms.select.blurHandler);
|
||||||
|
this.element.find("select").bind('blur', {editor: this}, BestInPlaceEditor.forms.select.blurHandler);
|
||||||
|
this.element.find("select").bind('keyup', {editor: this}, BestInPlaceEditor.forms.select.keyupHandler);
|
||||||
|
this.element.find("select")[0].focus();
|
||||||
|
|
||||||
|
// automatically click on the select so you
|
||||||
|
// don't have to click twice
|
||||||
|
try {
|
||||||
|
var e = document.createEvent("MouseEvents");
|
||||||
|
e.initMouseEvent("mousedown", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
|
||||||
|
this.element.find("select")[0].dispatchEvent(e);
|
||||||
|
}
|
||||||
|
catch(e) {
|
||||||
|
// browser doesn't support this, e.g. IE8
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getValue: function () {
|
||||||
|
'use strict';
|
||||||
|
return this.sanitizeValue(this.element.find("select").val());
|
||||||
|
},
|
||||||
|
|
||||||
|
blurHandler: function (event) {
|
||||||
|
'use strict';
|
||||||
|
event.data.editor.update();
|
||||||
|
},
|
||||||
|
|
||||||
|
keyupHandler: function (event) {
|
||||||
|
'use strict';
|
||||||
|
if (event.keyCode === 27) {
|
||||||
|
event.data.editor.abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"checkbox": {
|
||||||
|
activateForm: function () {
|
||||||
|
'use strict';
|
||||||
|
this.collectionValue = !this.getValue();
|
||||||
|
this.setHtmlAttributes();
|
||||||
|
this.update();
|
||||||
|
},
|
||||||
|
|
||||||
|
getValue: function () {
|
||||||
|
'use strict';
|
||||||
|
return this.collectionValue;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"textarea": {
|
||||||
|
activateForm: function () {
|
||||||
|
'use strict';
|
||||||
|
// grab width and height of text
|
||||||
|
var width = this.element.css('width');
|
||||||
|
var height = this.element.css('height');
|
||||||
|
|
||||||
|
// construct form
|
||||||
|
var output = jQuery(document.createElement('form'))
|
||||||
|
.addClass('form_in_place')
|
||||||
|
.attr('action', 'javascript:void(0);')
|
||||||
|
.attr('style', 'display:inline');
|
||||||
|
var textarea_elt = jQuery(document.createElement('textarea'))
|
||||||
|
.attr('name', this.attributeName)
|
||||||
|
.val(this.sanitizeValue(this.display_value));
|
||||||
|
|
||||||
|
if (this.inner_class !== null) {
|
||||||
|
textarea_elt.addClass(this.inner_class);
|
||||||
|
}
|
||||||
|
|
||||||
|
output.append(textarea_elt);
|
||||||
|
|
||||||
|
this.placeButtons(output, this);
|
||||||
|
|
||||||
|
this.element.html(output);
|
||||||
|
this.setHtmlAttributes();
|
||||||
|
|
||||||
|
// set width and height of textarea
|
||||||
|
jQuery(this.element.find("textarea")[0]).css({'min-width': width, 'min-height': height});
|
||||||
|
jQuery(this.element.find("textarea")[0]).autosize();
|
||||||
|
|
||||||
|
this.element.find("textarea")[0].focus();
|
||||||
|
this.element.find("form").bind('submit', {editor: this}, BestInPlaceEditor.forms.textarea.submitHandler);
|
||||||
|
|
||||||
|
if (this.cancelButton) {
|
||||||
|
this.element.find("input[type='button']").bind('click', {editor: this}, BestInPlaceEditor.forms.textarea.cancelButtonHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.skipBlur) {
|
||||||
|
this.element.find("textarea").bind('blur', {editor: this}, BestInPlaceEditor.forms.textarea.blurHandler);
|
||||||
|
}
|
||||||
|
this.element.find("textarea").bind('keyup', {editor: this}, BestInPlaceEditor.forms.textarea.keyupHandler);
|
||||||
|
this.blurTimer = null;
|
||||||
|
this.userClicked = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
getValue: function () {
|
||||||
|
'use strict';
|
||||||
|
return this.sanitizeValue(this.element.find("textarea").val());
|
||||||
|
},
|
||||||
|
|
||||||
|
// When buttons are present, use a timer on the blur event to give precedence to clicks
|
||||||
|
blurHandler: function (event) {
|
||||||
|
'use strict';
|
||||||
|
if (event.data.editor.okButton) {
|
||||||
|
event.data.editor.blurTimer = setTimeout(function () {
|
||||||
|
if (!event.data.editor.userClicked) {
|
||||||
|
event.data.editor.abortIfConfirm();
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
|
} else {
|
||||||
|
if (event.data.editor.cancelButton) {
|
||||||
|
event.data.editor.blurTimer = setTimeout(function () {
|
||||||
|
if (!event.data.editor.userClicked) {
|
||||||
|
event.data.editor.update();
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
|
} else {
|
||||||
|
event.data.editor.update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
submitHandler: function (event) {
|
||||||
|
'use strict';
|
||||||
|
event.data.editor.userClicked = true;
|
||||||
|
clearTimeout(event.data.editor.blurTimer);
|
||||||
|
event.data.editor.update();
|
||||||
|
},
|
||||||
|
|
||||||
|
cancelButtonHandler: function (event) {
|
||||||
|
'use strict';
|
||||||
|
event.data.editor.userClicked = true;
|
||||||
|
clearTimeout(event.data.editor.blurTimer);
|
||||||
|
event.data.editor.abortIfConfirm();
|
||||||
|
event.stopPropagation(); // Without this, click isn't handled
|
||||||
|
},
|
||||||
|
|
||||||
|
keyupHandler: function (event) {
|
||||||
|
'use strict';
|
||||||
|
if (event.keyCode === 27) {
|
||||||
|
event.data.editor.abortIfConfirm();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BestInPlaceEditor.defaults = {
|
||||||
|
locales: {},
|
||||||
|
ajaxMethod: "put", //TODO Change to patch when support to 3.2 is dropped
|
||||||
|
ajaxDataType: 'text',
|
||||||
|
okButtonClass: '',
|
||||||
|
cancelButtonClass: '',
|
||||||
|
skipBlur: false
|
||||||
|
};
|
||||||
|
|
||||||
|
// Default locale
|
||||||
|
BestInPlaceEditor.defaults.locales[''] = {
|
||||||
|
confirmMessage: "Are you sure you want to discard your changes?",
|
||||||
|
uninitializedForm: "The form was not properly initialized. getValue is unbound",
|
||||||
|
placeHolder: '-'
|
||||||
|
};
|
||||||
|
|
||||||
|
jQuery.fn.best_in_place = function () {
|
||||||
|
'use strict';
|
||||||
|
function setBestInPlace(element) {
|
||||||
|
if (!element.data('bestInPlaceEditor')) {
|
||||||
|
element.data('bestInPlaceEditor', new BestInPlaceEditor(element));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
jQuery(this.context).delegate(this.selector, 'click', function () {
|
||||||
|
var el = jQuery(this);
|
||||||
|
if (setBestInPlace(el)) {
|
||||||
|
el.click();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.each(function () {
|
||||||
|
setBestInPlace(jQuery(this));
|
||||||
|
});
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,780 +0,0 @@
|
||||||
/*
|
|
||||||
BestInPlace (for jQuery)
|
|
||||||
version: 0.1.0 (01/01/2011)
|
|
||||||
@requires jQuery >= v1.4
|
|
||||||
@requires jQuery.purr to display pop-up windows
|
|
||||||
|
|
||||||
By Bernat Farrero based on the work of Jan Varwig.
|
|
||||||
Examples at http://bernatfarrero.com
|
|
||||||
|
|
||||||
Licensed under the MIT:
|
|
||||||
http://www.opensource.org/licenses/mit-license.php
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
|
|
||||||
Attention.
|
|
||||||
The format of the JSON object given to the select inputs is the following:
|
|
||||||
[["key", "value"],["key", "value"]]
|
|
||||||
The format of the JSON object given to the checkbox inputs is the following:
|
|
||||||
["falseValue", "trueValue"]
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
function BestInPlaceEditor(e) {
|
|
||||||
this.element = e;
|
|
||||||
this.initOptions();
|
|
||||||
this.bindForm();
|
|
||||||
this.initNil();
|
|
||||||
jQuery(this.activator).bind('click', {editor: this}, this.clickHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
BestInPlaceEditor.prototype = {
|
|
||||||
// Public Interface Functions //////////////////////////////////////////////
|
|
||||||
|
|
||||||
activate : function() {
|
|
||||||
var to_display = "";
|
|
||||||
if (this.isNil()) {
|
|
||||||
to_display = "";
|
|
||||||
}
|
|
||||||
else if (this.original_content) {
|
|
||||||
to_display = this.original_content;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (this.sanitize) {
|
|
||||||
to_display = this.element.text();
|
|
||||||
} else {
|
|
||||||
to_display = this.element.html();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.oldValue = this.isNil() ? "" : this.element.html();
|
|
||||||
this.display_value = to_display;
|
|
||||||
jQuery(this.activator).unbind("click", this.clickHandler);
|
|
||||||
this.activateForm();
|
|
||||||
this.element.trigger(jQuery.Event("best_in_place:activate"));
|
|
||||||
},
|
|
||||||
|
|
||||||
abort : function() {
|
|
||||||
this.activateText(this.oldValue);
|
|
||||||
jQuery(this.activator).bind('click', {editor: this}, this.clickHandler);
|
|
||||||
this.element.trigger(jQuery.Event("best_in_place:abort"));
|
|
||||||
this.element.trigger(jQuery.Event("best_in_place:deactivate"));
|
|
||||||
},
|
|
||||||
|
|
||||||
abortIfConfirm : function () {
|
|
||||||
if (!this.useConfirm) {
|
|
||||||
this.abort();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (confirm("Are you sure you want to discard your changes?")) {
|
|
||||||
this.abort();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
update : function() {
|
|
||||||
var editor = this;
|
|
||||||
if (this.formType in {"input":1, "textarea":1} && this.getValue() == this.oldValue)
|
|
||||||
{ // Avoid request if no change is made
|
|
||||||
this.abort();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
editor.ajax({
|
|
||||||
"type" : "post",
|
|
||||||
"dataType" : "text",
|
|
||||||
"data" : editor.requestData(),
|
|
||||||
"success" : function(data){ editor.loadSuccessCallback(data); },
|
|
||||||
"error" : function(request, error){ editor.loadErrorCallback(request, error); }
|
|
||||||
});
|
|
||||||
if (this.formType == "select") {
|
|
||||||
var value = this.getValue();
|
|
||||||
this.previousCollectionValue = value;
|
|
||||||
|
|
||||||
jQuery.each(this.values, function(i, v) {
|
|
||||||
if (value == v[0]) {
|
|
||||||
editor.element.html(v[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else if (this.formType == "checkbox") {
|
|
||||||
editor.element.html(this.getValue() ? this.values[1] : this.values[0]);
|
|
||||||
} else {
|
|
||||||
if (this.getValue() !== "") {
|
|
||||||
editor.element.text(this.getValue());
|
|
||||||
} else {
|
|
||||||
editor.element.html(this.nil);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
editor.element.trigger(jQuery.Event("best_in_place:update"));
|
|
||||||
},
|
|
||||||
|
|
||||||
activateForm : function() {
|
|
||||||
alert("The form was not properly initialized. activateForm is unbound");
|
|
||||||
},
|
|
||||||
|
|
||||||
activateText : function(value){
|
|
||||||
this.element.html(value);
|
|
||||||
if(this.isNil()) this.element.html(this.nil);
|
|
||||||
},
|
|
||||||
|
|
||||||
// Helper Functions ////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
initOptions : function() {
|
|
||||||
// Try parent supplied info
|
|
||||||
var self = this;
|
|
||||||
self.element.parents().each(function(){
|
|
||||||
$parent = jQuery(this);
|
|
||||||
self.url = self.url || $parent.attr("data-url");
|
|
||||||
self.collection = self.collection || $parent.attr("data-collection");
|
|
||||||
self.formType = self.formType || $parent.attr("data-type");
|
|
||||||
self.objectName = self.objectName || $parent.attr("data-object");
|
|
||||||
self.attributeName = self.attributeName || $parent.attr("data-attribute");
|
|
||||||
self.activator = self.activator || $parent.attr("data-activator");
|
|
||||||
self.okButton = self.okButton || $parent.attr("data-ok-button");
|
|
||||||
self.okButtonClass = self.okButtonClass || $parent.attr("data-ok-button-class");
|
|
||||||
self.cancelButton = self.cancelButton || $parent.attr("data-cancel-button");
|
|
||||||
self.cancelButtonClass = self.cancelButtonClass || $parent.attr("data-cancel-button-class");
|
|
||||||
self.nil = self.nil || $parent.attr("data-nil");
|
|
||||||
self.inner_class = self.inner_class || $parent.attr("data-inner-class");
|
|
||||||
self.html_attrs = self.html_attrs || $parent.attr("data-html-attrs");
|
|
||||||
self.original_content = self.original_content || $parent.attr("data-original-content");
|
|
||||||
self.collectionValue = self.collectionValue || $parent.attr("data-value");
|
|
||||||
});
|
|
||||||
|
|
||||||
// Try Rails-id based if parents did not explicitly supply something
|
|
||||||
self.element.parents().each(function(){
|
|
||||||
var res = this.id.match(/^(\w+)_(\d+)$/i);
|
|
||||||
if (res) {
|
|
||||||
self.objectName = self.objectName || res[1];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Load own attributes (overrides all others)
|
|
||||||
self.url = self.element.attr("data-url") || self.url || document.location.pathname;
|
|
||||||
self.collection = self.element.attr("data-collection") || self.collection;
|
|
||||||
self.formType = self.element.attr("data-type") || self.formtype || "input";
|
|
||||||
self.objectName = self.element.attr("data-object") || self.objectName;
|
|
||||||
self.attributeName = self.element.attr("data-attribute") || self.attributeName;
|
|
||||||
self.activator = self.element.attr("data-activator") || self.element;
|
|
||||||
self.okButton = self.element.attr("data-ok-button") || self.okButton;
|
|
||||||
self.okButtonClass = self.element.attr("data-ok-button-class") || self.okButtonClass || "";
|
|
||||||
self.cancelButton = self.element.attr("data-cancel-button") || self.cancelButton;
|
|
||||||
self.cancelButtonClass = self.element.attr("data-cancel-button-class") || self.cancelButtonClass || "";
|
|
||||||
self.nil = self.element.attr("data-nil") || self.nil || "—";
|
|
||||||
self.inner_class = self.element.attr("data-inner-class") || self.inner_class || null;
|
|
||||||
self.html_attrs = self.element.attr("data-html-attrs") || self.html_attrs;
|
|
||||||
self.original_content = self.element.attr("data-original-content") || self.original_content;
|
|
||||||
self.collectionValue = self.element.attr("data-value") || self.collectionValue;
|
|
||||||
|
|
||||||
if (!self.element.attr("data-sanitize")) {
|
|
||||||
self.sanitize = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
self.sanitize = (self.element.attr("data-sanitize") == "true");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!self.element.attr("data-use-confirm")) {
|
|
||||||
self.useConfirm = true;
|
|
||||||
} else {
|
|
||||||
self.useConfirm = (self.element.attr("data-use-confirm") != "false");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((self.formType == "select" || self.formType == "checkbox") && self.collection !== null)
|
|
||||||
{
|
|
||||||
self.values = jQuery.parseJSON(self.collection);
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
bindForm : function() {
|
|
||||||
this.activateForm = BestInPlaceEditor.forms[this.formType].activateForm;
|
|
||||||
this.getValue = BestInPlaceEditor.forms[this.formType].getValue;
|
|
||||||
},
|
|
||||||
|
|
||||||
initNil: function() {
|
|
||||||
if (this.element.html() === "")
|
|
||||||
{
|
|
||||||
this.element.html(this.nil);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
isNil: function() {
|
|
||||||
// TODO: It only work when form is deactivated.
|
|
||||||
// Condition will fail when form is activated
|
|
||||||
return this.element.html() === "" || this.element.html() === this.nil;
|
|
||||||
},
|
|
||||||
|
|
||||||
getValue : function() {
|
|
||||||
alert("The form was not properly initialized. getValue is unbound");
|
|
||||||
},
|
|
||||||
|
|
||||||
// Trim and Strips HTML from text
|
|
||||||
sanitizeValue : function(s) {
|
|
||||||
return jQuery.trim(s);
|
|
||||||
},
|
|
||||||
|
|
||||||
/* Generate the data sent in the POST request */
|
|
||||||
requestData : function() {
|
|
||||||
// To prevent xss attacks, a csrf token must be defined as a meta attribute
|
|
||||||
csrf_token = jQuery('meta[name=csrf-token]').attr('content');
|
|
||||||
csrf_param = jQuery('meta[name=csrf-param]').attr('content');
|
|
||||||
|
|
||||||
var data = "_method=put";
|
|
||||||
data += "&" + this.objectName + '[' + this.attributeName + ']=' + encodeURIComponent(this.getValue());
|
|
||||||
|
|
||||||
if (csrf_param !== undefined && csrf_token !== undefined) {
|
|
||||||
data += "&" + csrf_param + "=" + encodeURIComponent(csrf_token);
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
},
|
|
||||||
|
|
||||||
ajax : function(options) {
|
|
||||||
options.url = this.url;
|
|
||||||
options.beforeSend = function(xhr){ xhr.setRequestHeader("Accept", "application/json"); };
|
|
||||||
return jQuery.ajax(options);
|
|
||||||
},
|
|
||||||
|
|
||||||
// Handlers ////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
loadSuccessCallback : function(data) {
|
|
||||||
data = jQuery.trim(data);
|
|
||||||
|
|
||||||
if(data && data!=""){
|
|
||||||
var response = jQuery.parseJSON(jQuery.trim(data));
|
|
||||||
if (response !== null && response.hasOwnProperty("display_as")) {
|
|
||||||
this.element.attr("data-original-content", this.element.text());
|
|
||||||
this.original_content = this.element.text();
|
|
||||||
this.element.html(response["display_as"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.element.trigger(jQuery.Event("best_in_place:success"), data);
|
|
||||||
this.element.trigger(jQuery.Event("ajax:success"), data);
|
|
||||||
} else {
|
|
||||||
this.element.trigger(jQuery.Event("best_in_place:success"));
|
|
||||||
this.element.trigger(jQuery.Event("ajax:success"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Binding back after being clicked
|
|
||||||
jQuery(this.activator).bind('click', {editor: this}, this.clickHandler);
|
|
||||||
this.element.trigger(jQuery.Event("best_in_place:deactivate"));
|
|
||||||
|
|
||||||
if (this.collectionValue !== null && this.formType == "select") {
|
|
||||||
this.collectionValue = this.previousCollectionValue;
|
|
||||||
this.previousCollectionValue = null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
loadErrorCallback : function(request, error) {
|
|
||||||
this.activateText(this.oldValue);
|
|
||||||
|
|
||||||
this.element.trigger(jQuery.Event("best_in_place:error"), [request, error]);
|
|
||||||
this.element.trigger(jQuery.Event("ajax:error"), request, error);
|
|
||||||
|
|
||||||
// Binding back after being clicked
|
|
||||||
jQuery(this.activator).bind('click', {editor: this}, this.clickHandler);
|
|
||||||
this.element.trigger(jQuery.Event("best_in_place:deactivate"));
|
|
||||||
},
|
|
||||||
|
|
||||||
clickHandler : function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
event.data.editor.activate();
|
|
||||||
},
|
|
||||||
|
|
||||||
setHtmlAttributes : function() {
|
|
||||||
var formField = this.element.find(this.formType);
|
|
||||||
|
|
||||||
if(this.html_attrs){
|
|
||||||
var attrs = jQuery.parseJSON(this.html_attrs);
|
|
||||||
for(var key in attrs){
|
|
||||||
formField.attr(key, attrs[key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Button cases:
|
|
||||||
// If no buttons, then blur saves, ESC cancels
|
|
||||||
// If just Cancel button, then blur saves, ESC or clicking Cancel cancels (careful of blur event!)
|
|
||||||
// If just OK button, then clicking OK saves (careful of blur event!), ESC or blur cancels
|
|
||||||
// If both buttons, then clicking OK saves, ESC or clicking Cancel or blur cancels
|
|
||||||
BestInPlaceEditor.forms = {
|
|
||||||
"input" : {
|
|
||||||
activateForm : function() {
|
|
||||||
var output = jQuery(document.createElement('form'))
|
|
||||||
.addClass('form_in_place')
|
|
||||||
.attr('action', 'javascript:void(0);')
|
|
||||||
.attr('style', 'display:inline');
|
|
||||||
var input_elt = jQuery(document.createElement('input'))
|
|
||||||
.attr('type', 'text')
|
|
||||||
.attr('name', this.attributeName)
|
|
||||||
.val(this.display_value);
|
|
||||||
if(this.inner_class !== null) {
|
|
||||||
input_elt.addClass(this.inner_class);
|
|
||||||
}
|
|
||||||
output.append(input_elt);
|
|
||||||
if(this.okButton) {
|
|
||||||
output.append(
|
|
||||||
jQuery(document.createElement('input'))
|
|
||||||
.attr('type', 'submit')
|
|
||||||
.attr('class', this.okButtonClass)
|
|
||||||
.attr('value', this.okButton)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if(this.cancelButton) {
|
|
||||||
output.append(
|
|
||||||
jQuery(document.createElement('input'))
|
|
||||||
.attr('type', 'button')
|
|
||||||
.attr('class', this.cancelButtonClass)
|
|
||||||
.attr('value', this.cancelButton)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.element.html(output);
|
|
||||||
this.setHtmlAttributes();
|
|
||||||
// START METAMAPS CODE
|
|
||||||
//this.element.find("input[type='text']")[0].select();
|
|
||||||
this.element.find("input[type='text']")[0].focus();
|
|
||||||
// END METAMAPS CODE
|
|
||||||
this.element.find("form").bind('submit', {editor: this}, BestInPlaceEditor.forms.input.submitHandler);
|
|
||||||
if (this.cancelButton) {
|
|
||||||
this.element.find("input[type='button']").bind('click', {editor: this}, BestInPlaceEditor.forms.input.cancelButtonHandler);
|
|
||||||
}
|
|
||||||
this.element.find("input[type='text']").bind('blur', {editor: this}, BestInPlaceEditor.forms.input.inputBlurHandler);
|
|
||||||
// START METAMAPS CODE
|
|
||||||
this.element.find("input[type='text']").bind('keydown', {editor: this}, BestInPlaceEditor.forms.input.keydownHandler);
|
|
||||||
// END METAMAPS CODE
|
|
||||||
this.element.find("input[type='text']").bind('keyup', {editor: this}, BestInPlaceEditor.forms.input.keyupHandler);
|
|
||||||
this.blurTimer = null;
|
|
||||||
this.userClicked = false;
|
|
||||||
},
|
|
||||||
|
|
||||||
getValue : function() {
|
|
||||||
return this.sanitizeValue(this.element.find("input").val());
|
|
||||||
},
|
|
||||||
|
|
||||||
// When buttons are present, use a timer on the blur event to give precedence to clicks
|
|
||||||
inputBlurHandler : function(event) {
|
|
||||||
if (event.data.editor.okButton) {
|
|
||||||
event.data.editor.blurTimer = setTimeout(function () {
|
|
||||||
if (!event.data.editor.userClicked) {
|
|
||||||
event.data.editor.abort();
|
|
||||||
}
|
|
||||||
}, 500);
|
|
||||||
} else {
|
|
||||||
if (event.data.editor.cancelButton) {
|
|
||||||
event.data.editor.blurTimer = setTimeout(function () {
|
|
||||||
if (!event.data.editor.userClicked) {
|
|
||||||
event.data.editor.update();
|
|
||||||
}
|
|
||||||
}, 500);
|
|
||||||
} else {
|
|
||||||
event.data.editor.update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
submitHandler : function(event) {
|
|
||||||
event.data.editor.userClicked = true;
|
|
||||||
clearTimeout(event.data.editor.blurTimer);
|
|
||||||
event.data.editor.update();
|
|
||||||
},
|
|
||||||
|
|
||||||
cancelButtonHandler : function(event) {
|
|
||||||
event.data.editor.userClicked = true;
|
|
||||||
clearTimeout(event.data.editor.blurTimer);
|
|
||||||
event.data.editor.abort();
|
|
||||||
event.stopPropagation(); // Without this, click isn't handled
|
|
||||||
},
|
|
||||||
|
|
||||||
keyupHandler : function(event) {
|
|
||||||
if (event.keyCode == 27) {
|
|
||||||
event.data.editor.abort();
|
|
||||||
}
|
|
||||||
// START METAMAPS CODE
|
|
||||||
else if (event.keyCode == 13 && !event.shiftKey) {
|
|
||||||
event.data.editor.update();
|
|
||||||
}
|
|
||||||
// END METAMAPS CODE
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
"date" : {
|
|
||||||
activateForm : function() {
|
|
||||||
var that = this,
|
|
||||||
output = jQuery(document.createElement('form'))
|
|
||||||
.addClass('form_in_place')
|
|
||||||
.attr('action', 'javascript:void(0);')
|
|
||||||
.attr('style', 'display:inline'),
|
|
||||||
input_elt = jQuery(document.createElement('input'))
|
|
||||||
.attr('type', 'text')
|
|
||||||
.attr('name', this.attributeName)
|
|
||||||
.attr('value', this.sanitizeValue(this.display_value));
|
|
||||||
if(this.inner_class !== null) {
|
|
||||||
input_elt.addClass(this.inner_class);
|
|
||||||
}
|
|
||||||
output.append(input_elt)
|
|
||||||
|
|
||||||
this.element.html(output);
|
|
||||||
this.setHtmlAttributes();
|
|
||||||
this.element.find('input')[0].select();
|
|
||||||
this.element.find("form").bind('submit', {editor: this}, BestInPlaceEditor.forms.input.submitHandler);
|
|
||||||
this.element.find("input").bind('keyup', {editor: this}, BestInPlaceEditor.forms.input.keyupHandler);
|
|
||||||
|
|
||||||
this.element.find('input')
|
|
||||||
.datepicker({
|
|
||||||
onClose: function() {
|
|
||||||
that.update();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.datepicker('show');
|
|
||||||
},
|
|
||||||
|
|
||||||
getValue : function() {
|
|
||||||
return this.sanitizeValue(this.element.find("input").val());
|
|
||||||
},
|
|
||||||
|
|
||||||
submitHandler : function(event) {
|
|
||||||
event.data.editor.update();
|
|
||||||
},
|
|
||||||
|
|
||||||
// START METAMAPS CODE
|
|
||||||
keydownHandler : function(event) {
|
|
||||||
if (event.keyCode == 13 && !event.shiftKey) {
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// END METAMAPS CODE
|
|
||||||
|
|
||||||
keyupHandler : function(event) {
|
|
||||||
if (event.keyCode == 27) {
|
|
||||||
event.data.editor.abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
"select" : {
|
|
||||||
activateForm : function() {
|
|
||||||
var output = jQuery(document.createElement('form'))
|
|
||||||
.attr('action', 'javascript:void(0)')
|
|
||||||
.attr('style', 'display:inline');
|
|
||||||
selected = '',
|
|
||||||
oldValue = this.oldValue,
|
|
||||||
select_elt = jQuery(document.createElement('select'))
|
|
||||||
.attr('class', this.inned_class !== null ? this.inner_class : '' ),
|
|
||||||
currentCollectionValue = this.collectionValue;
|
|
||||||
|
|
||||||
jQuery.each(this.values, function (index, value) {
|
|
||||||
var option_elt = jQuery(document.createElement('option'))
|
|
||||||
// .attr('value', value[0])
|
|
||||||
.val(value[0])
|
|
||||||
.html(value[1]);
|
|
||||||
if(value[0] == currentCollectionValue) {
|
|
||||||
option_elt.attr('selected', 'selected');
|
|
||||||
}
|
|
||||||
select_elt.append(option_elt);
|
|
||||||
});
|
|
||||||
output.append(select_elt);
|
|
||||||
|
|
||||||
this.element.html(output);
|
|
||||||
this.setHtmlAttributes();
|
|
||||||
this.element.find("select").bind('change', {editor: this}, BestInPlaceEditor.forms.select.blurHandler);
|
|
||||||
this.element.find("select").bind('blur', {editor: this}, BestInPlaceEditor.forms.select.blurHandler);
|
|
||||||
this.element.find("select").bind('keyup', {editor: this}, BestInPlaceEditor.forms.select.keyupHandler);
|
|
||||||
this.element.find("select")[0].focus();
|
|
||||||
},
|
|
||||||
|
|
||||||
getValue : function() {
|
|
||||||
return this.sanitizeValue(this.element.find("select").val());
|
|
||||||
// return this.element.find("select").val();
|
|
||||||
},
|
|
||||||
|
|
||||||
blurHandler : function(event) {
|
|
||||||
event.data.editor.update();
|
|
||||||
},
|
|
||||||
|
|
||||||
keyupHandler : function(event) {
|
|
||||||
if (event.keyCode == 27) event.data.editor.abort();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
"checkbox" : {
|
|
||||||
activateForm : function() {
|
|
||||||
this.collectionValue = !this.getValue();
|
|
||||||
this.setHtmlAttributes();
|
|
||||||
this.update();
|
|
||||||
},
|
|
||||||
|
|
||||||
getValue : function() {
|
|
||||||
return this.collectionValue;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
"textarea" : {
|
|
||||||
activateForm : function() {
|
|
||||||
// grab width and height of text
|
|
||||||
width = this.element.css('width');
|
|
||||||
height = this.element.css('height');
|
|
||||||
|
|
||||||
// construct form
|
|
||||||
var output = jQuery(document.createElement('form'))
|
|
||||||
.attr('action', 'javascript:void(0)')
|
|
||||||
.attr('style', 'display:inline')
|
|
||||||
.append(jQuery(document.createElement('textarea'))
|
|
||||||
.val(this.sanitizeValue(this.display_value)));
|
|
||||||
if(this.okButton) {
|
|
||||||
output.append(
|
|
||||||
jQuery(document.createElement('input'))
|
|
||||||
.attr('type', 'submit')
|
|
||||||
.attr('value', this.okButton)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if(this.cancelButton) {
|
|
||||||
output.append(
|
|
||||||
jQuery(document.createElement('input'))
|
|
||||||
.attr('type', 'button')
|
|
||||||
.attr('value', this.cancelButton)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.element.html(output);
|
|
||||||
this.setHtmlAttributes();
|
|
||||||
|
|
||||||
// set width and height of textarea
|
|
||||||
jQuery(this.element.find("textarea")[0]).css({ 'min-width': width, 'min-height': height });
|
|
||||||
jQuery(this.element.find("textarea")[0]).elastic();
|
|
||||||
|
|
||||||
this.element.find("textarea")[0].focus();
|
|
||||||
this.element.find("form").bind('submit', {editor: this}, BestInPlaceEditor.forms.textarea.submitHandler);
|
|
||||||
if (this.cancelButton) {
|
|
||||||
this.element.find("input[type='button']").bind('click', {editor: this}, BestInPlaceEditor.forms.textarea.cancelButtonHandler);
|
|
||||||
}
|
|
||||||
this.element.find("textarea").bind('blur', {editor: this}, BestInPlaceEditor.forms.textarea.blurHandler);
|
|
||||||
// START METAMAPS CODE
|
|
||||||
this.element.find("textarea").bind('keydown', {editor: this}, BestInPlaceEditor.forms.textarea.keydownHandler);
|
|
||||||
// END METAMAPS CODE
|
|
||||||
this.element.find("textarea").bind('keyup', {editor: this}, BestInPlaceEditor.forms.textarea.keyupHandler);
|
|
||||||
this.blurTimer = null;
|
|
||||||
this.userClicked = false;
|
|
||||||
},
|
|
||||||
|
|
||||||
getValue : function() {
|
|
||||||
return this.sanitizeValue(this.element.find("textarea").val());
|
|
||||||
},
|
|
||||||
|
|
||||||
// When buttons are present, use a timer on the blur event to give precedence to clicks
|
|
||||||
blurHandler : function(event) {
|
|
||||||
if (event.data.editor.okButton) {
|
|
||||||
event.data.editor.blurTimer = setTimeout(function () {
|
|
||||||
if (!event.data.editor.userClicked) {
|
|
||||||
event.data.editor.abortIfConfirm();
|
|
||||||
}
|
|
||||||
}, 500);
|
|
||||||
} else {
|
|
||||||
if (event.data.editor.cancelButton) {
|
|
||||||
event.data.editor.blurTimer = setTimeout(function () {
|
|
||||||
if (!event.data.editor.userClicked) {
|
|
||||||
event.data.editor.update();
|
|
||||||
}
|
|
||||||
}, 500);
|
|
||||||
} else {
|
|
||||||
event.data.editor.update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
submitHandler : function(event) {
|
|
||||||
event.data.editor.userClicked = true;
|
|
||||||
clearTimeout(event.data.editor.blurTimer);
|
|
||||||
event.data.editor.update();
|
|
||||||
},
|
|
||||||
|
|
||||||
cancelButtonHandler : function(event) {
|
|
||||||
event.data.editor.userClicked = true;
|
|
||||||
clearTimeout(event.data.editor.blurTimer);
|
|
||||||
event.data.editor.abortIfConfirm();
|
|
||||||
event.stopPropagation(); // Without this, click isn't handled
|
|
||||||
},
|
|
||||||
|
|
||||||
// START METAMAPS CODE
|
|
||||||
keydownHandler : function(event) {
|
|
||||||
if (event.keyCode == 13 && !event.shiftKey) {
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// END METAMAPS CODE
|
|
||||||
|
|
||||||
keyupHandler : function(event) {
|
|
||||||
if (event.keyCode == 27) {
|
|
||||||
event.data.editor.abortIfConfirm();
|
|
||||||
}
|
|
||||||
// START METAMAPS CODE
|
|
||||||
else if (event.keyCode == 13 && !event.shiftKey) {
|
|
||||||
event.data.editor.update();
|
|
||||||
}
|
|
||||||
// END METAMAPS CODE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
jQuery.fn.best_in_place = function() {
|
|
||||||
|
|
||||||
function setBestInPlace(element) {
|
|
||||||
if (!element.data('bestInPlaceEditor')) {
|
|
||||||
element.data('bestInPlaceEditor', new BestInPlaceEditor(element));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
jQuery(this.context).delegate(this.selector, 'click', function () {
|
|
||||||
var el = jQuery(this);
|
|
||||||
if (setBestInPlace(el))
|
|
||||||
el.click();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.each(function () {
|
|
||||||
setBestInPlace(jQuery(this));
|
|
||||||
});
|
|
||||||
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @name Elastic
|
|
||||||
* @descripton Elastic is Jquery plugin that grow and shrink your textareas automaticliy
|
|
||||||
* @version 1.6.5
|
|
||||||
* @requires Jquery 1.2.6+
|
|
||||||
*
|
|
||||||
* @author Jan Jarfalk
|
|
||||||
* @author-email jan.jarfalk@unwrongest.com
|
|
||||||
* @author-website http://www.unwrongest.com
|
|
||||||
*
|
|
||||||
* @licens MIT License - http://www.opensource.org/licenses/mit-license.php
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function(jQuery){
|
|
||||||
if (typeof jQuery.fn.elastic !== 'undefined') return;
|
|
||||||
|
|
||||||
jQuery.fn.extend({
|
|
||||||
elastic: function() {
|
|
||||||
// We will create a div clone of the textarea
|
|
||||||
// by copying these attributes from the textarea to the div.
|
|
||||||
var mimics = [
|
|
||||||
'paddingTop',
|
|
||||||
'paddingRight',
|
|
||||||
'paddingBottom',
|
|
||||||
'paddingLeft',
|
|
||||||
'fontSize',
|
|
||||||
'lineHeight',
|
|
||||||
'fontFamily',
|
|
||||||
'width',
|
|
||||||
'fontWeight'];
|
|
||||||
|
|
||||||
return this.each( function() {
|
|
||||||
|
|
||||||
// Elastic only works on textareas
|
|
||||||
if ( this.type != 'textarea' ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var $textarea = jQuery(this),
|
|
||||||
$twin = jQuery('<div />').css({'position': 'absolute','display':'none','word-wrap':'break-word'}),
|
|
||||||
lineHeight = parseInt($textarea.css('line-height'),10) || parseInt($textarea.css('font-size'),'10'),
|
|
||||||
minheight = parseInt($textarea.css('height'),10) || lineHeight*3,
|
|
||||||
maxheight = parseInt($textarea.css('max-height'),10) || Number.MAX_VALUE,
|
|
||||||
goalheight = 0,
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
// Opera returns max-height of -1 if not set
|
|
||||||
if (maxheight < 0) { maxheight = Number.MAX_VALUE; }
|
|
||||||
|
|
||||||
// Append the twin to the DOM
|
|
||||||
// We are going to meassure the height of this, not the textarea.
|
|
||||||
$twin.appendTo($textarea.parent());
|
|
||||||
|
|
||||||
// Copy the essential styles (mimics) from the textarea to the twin
|
|
||||||
i = mimics.length;
|
|
||||||
while(i--){
|
|
||||||
$twin.css(mimics[i].toString(),$textarea.css(mimics[i].toString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Sets a given height and overflow state on the textarea
|
|
||||||
function setHeightAndOverflow(height, overflow){
|
|
||||||
curratedHeight = Math.floor(parseInt(height,10));
|
|
||||||
if($textarea.height() != curratedHeight){
|
|
||||||
$textarea.css({'height': curratedHeight + 'px','overflow':overflow});
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// This function will update the height of the textarea if necessary
|
|
||||||
function update() {
|
|
||||||
|
|
||||||
// Get curated content from the textarea.
|
|
||||||
var textareaContent = $textarea.val().replace(/&/g,'&').replace(/ /g, ' ').replace(/<|>/g, '>').replace(/\n/g, '<br />');
|
|
||||||
|
|
||||||
// Compare curated content with curated twin.
|
|
||||||
var twinContent = $twin.html().replace(/<br>/ig,'<br />');
|
|
||||||
|
|
||||||
if(textareaContent+' ' != twinContent){
|
|
||||||
|
|
||||||
// Add an extra white space so new rows are added when you are at the end of a row.
|
|
||||||
$twin.html(textareaContent+' ');
|
|
||||||
|
|
||||||
// Change textarea height if twin plus the height of one line differs more than 3 pixel from textarea height
|
|
||||||
if(Math.abs($twin.height() + lineHeight - $textarea.height()) > 3){
|
|
||||||
|
|
||||||
var goalheight = $twin.height()+lineHeight;
|
|
||||||
if(goalheight >= maxheight) {
|
|
||||||
setHeightAndOverflow(maxheight,'auto');
|
|
||||||
} else if(goalheight <= minheight) {
|
|
||||||
setHeightAndOverflow(minheight,'hidden');
|
|
||||||
} else {
|
|
||||||
setHeightAndOverflow(goalheight,'hidden');
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hide scrollbars
|
|
||||||
$textarea.css({'overflow':'hidden'});
|
|
||||||
|
|
||||||
// Update textarea size on keyup, change, cut and paste
|
|
||||||
$textarea.bind('keyup change cut paste', function(){
|
|
||||||
update();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Compact textarea on blur
|
|
||||||
// Lets animate this....
|
|
||||||
$textarea.bind('blur',function(){
|
|
||||||
if($twin.height() < maxheight){
|
|
||||||
if($twin.height() > minheight) {
|
|
||||||
$textarea.height($twin.height());
|
|
||||||
} else {
|
|
||||||
$textarea.height(minheight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// And this line is to catch the browser paste event
|
|
||||||
$textarea.on("input paste", function(e){ setTimeout( update, 250); });
|
|
||||||
|
|
||||||
// Run update once when elastic is initialized
|
|
||||||
update();
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})(jQuery);
|
|
2
app/assets/javascripts/lib/canvas-to-blob.min.js
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
!function(t){"use strict";var e=t.HTMLCanvasElement&&t.HTMLCanvasElement.prototype,o=t.Blob&&function(){try{return Boolean(new Blob)}catch(t){return!1}}(),n=o&&t.Uint8Array&&function(){try{return 100===new Blob([new Uint8Array(100)]).size}catch(t){return!1}}(),r=t.BlobBuilder||t.WebKitBlobBuilder||t.MozBlobBuilder||t.MSBlobBuilder,a=/^data:((.*?)(;charset=.*?)?)(;base64)?,/,i=(o||r)&&t.atob&&t.ArrayBuffer&&t.Uint8Array&&function(t){var e,i,l,u,b,c,d,B,f;if(e=t.match(a),!e)throw new Error("invalid data URI");for(i=e[2]?e[1]:"text/plain"+(e[3]||";charset=US-ASCII"),l=!!e[4],u=t.slice(e[0].length),b=l?atob(u):decodeURIComponent(u),c=new ArrayBuffer(b.length),d=new Uint8Array(c),B=0;B<b.length;B+=1)d[B]=b.charCodeAt(B);return o?new Blob([n?d:c],{type:i}):(f=new r,f.append(c),f.getBlob(i))};t.HTMLCanvasElement&&!e.toBlob&&(e.mozGetAsFile?e.toBlob=function(t,o,n){t(n&&e.toDataURL&&i?i(this.toDataURL(o,n)):this.mozGetAsFile("blob",o))}:e.toDataURL&&i&&(e.toBlob=function(t,e,o){t(i(this.toDataURL(e,o)))})),"function"==typeof define&&define.amd?define(function(){return i}):"object"==typeof module&&module.exports?module.exports=i:t.dataURLtoBlob=i}(window);
|
||||||
|
//# sourceMappingURL=canvas-to-blob.min.js.map
|
|
@ -161,38 +161,43 @@ jQuery.browser = browser;
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// START METAMAPS CODE
|
||||||
// Add code that makes tab and shift+tab scroll through metacodes
|
// Add code that makes tab and shift+tab scroll through metacodes
|
||||||
$('.new_topic').bind('keydown',this,function(event){
|
$('.new_topic').bind('keydown',this,function(event){
|
||||||
if (event.keyCode == 9 && event.shiftKey) {
|
if (event.keyCode == 9) {
|
||||||
event.data.rotate(-1);
|
if (event.shiftKey) {
|
||||||
event.preventDefault();
|
event.data.rotate(-1)
|
||||||
event.stopPropagation();
|
} else {
|
||||||
} else if (event.keyCode == 9) {
|
event.data.rotate(1)
|
||||||
event.data.rotate(1);
|
}
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
Metamaps.Create.newTopic.metacode = $(items[event.data.frontIndex].image).attr('data-id');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// END METAMAPS CODE
|
||||||
|
|
||||||
// You will need this plugin for the mousewheel to work: http://plugins.jquery.com/project/mousewheel
|
// You will need this plugin for the mousewheel to work: http://plugins.jquery.com/project/mousewheel
|
||||||
if (options.mouseWheel)
|
if (options.mouseWheel)
|
||||||
{
|
{
|
||||||
// START METAMAPS CODE
|
// START METAMAPS CODE
|
||||||
$('body').bind('mousewheel',this,function(event, delta) {
|
$('body').bind('mousewheel',this,function(event, delta) {
|
||||||
if (Metamaps.Create.newTopic.beingCreated && !Metamaps.Create.isSwitchingSet) {
|
if (Metamaps.Create.newTopic.beingCreated &&
|
||||||
|
!Metamaps.Create.isSwitchingSet &&
|
||||||
|
!Metamaps.Create.newTopic.pinned) {
|
||||||
event.data.rotate(delta);
|
event.data.rotate(delta);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// END METAMAPS CODE
|
// END METAMAPS CODE
|
||||||
/* ORIGINAL CODE
|
// ORIGINAL CODE
|
||||||
$(container).bind('mousewheel',this,function(event, delta) {
|
// $(container).bind('mousewheel',this,function(event, delta) {
|
||||||
event.data.rotate(delta);
|
// event.data.rotate(delta);
|
||||||
return false;
|
// return false;
|
||||||
});
|
// });
|
||||||
*/
|
//
|
||||||
}
|
}
|
||||||
$(container).bind('mouseover click',this,function(event){
|
$(container).unbind('mouseover click').bind('mouseover click',this,function(event){
|
||||||
|
|
||||||
clearInterval(event.data.autoRotateTimer); // Stop auto rotation if mouse over.
|
clearInterval(event.data.autoRotateTimer); // Stop auto rotation if mouse over.
|
||||||
var text = $(event.target).attr('alt');
|
var text = $(event.target).attr('alt');
|
||||||
|
@ -207,9 +212,9 @@ jQuery.browser = browser;
|
||||||
if ( options.bringToFront && event.type == 'click' )
|
if ( options.bringToFront && event.type == 'click' )
|
||||||
{
|
{
|
||||||
$(options.titleBox).html( ($(event.target).attr('title') ));
|
$(options.titleBox).html( ($(event.target).attr('title') ));
|
||||||
// METAMAPS CODE
|
// START METAMAPS CODE
|
||||||
Metamaps.Create.newTopic.metacode = $(event.target).attr('data-id');
|
Metamaps.Create.newTopic.metacode = $(event.target).attr('data-id');
|
||||||
// NOT METAMAPS CODE
|
// END METAMAPS CODE
|
||||||
var idx = $(event.target).data('itemIndex');
|
var idx = $(event.target).data('itemIndex');
|
||||||
var frontIndex = event.data.frontIndex;
|
var frontIndex = event.data.frontIndex;
|
||||||
//var diff = idx - frontIndex;
|
//var diff = idx - frontIndex;
|
||||||
|
@ -222,6 +227,11 @@ jQuery.browser = browser;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// START METAMAPS CODE - initialize newTopic.metacode
|
||||||
|
var first = $(this.container).find('img').get(0)
|
||||||
|
Metamaps.Create.newTopic.metacode = $(first).data('id')
|
||||||
|
// END METAMAPS CODE
|
||||||
|
|
||||||
// If we have moved out of a carousel item (or the container itself),
|
// If we have moved out of a carousel item (or the container itself),
|
||||||
// restore the text of the front item in 1 second.
|
// restore the text of the front item in 1 second.
|
||||||
$(container).bind('mouseout',this,function(event){
|
$(container).bind('mouseout',this,function(event){
|
||||||
|
@ -245,11 +255,6 @@ jQuery.browser = browser;
|
||||||
this.showFrontText = function()
|
this.showFrontText = function()
|
||||||
{
|
{
|
||||||
if ( items[this.frontIndex] === undefined ) { return; } // Images might not have loaded yet.
|
if ( items[this.frontIndex] === undefined ) { return; } // Images might not have loaded yet.
|
||||||
// METAMAPS CODE
|
|
||||||
Metamaps.Create.newTopic.metacode = $(items[this.frontIndex].image).attr('data-id');
|
|
||||||
//$('img.cloudcarousel').css({"background":"none", "width":"","height":""});
|
|
||||||
//$(items[this.frontIndex].image).css({"width":"45px","height":"45px"});
|
|
||||||
// NOT METAMAPS CODE
|
|
||||||
$(options.titleBox).html( $(items[this.frontIndex].image).attr('title'));
|
$(options.titleBox).html( $(items[this.frontIndex].image).attr('title'));
|
||||||
$(options.altBox).html( $(items[this.frontIndex].image).attr('alt'));
|
$(options.altBox).html( $(items[this.frontIndex].image).attr('alt'));
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,180 +0,0 @@
|
||||||
/**
|
|
||||||
* jquery.purr.js
|
|
||||||
* Copyright (c) 2008 Net Perspective (net-perspective.com)
|
|
||||||
* Licensed under the MIT License (http://www.opensource.org/licenses/mit-license.php)
|
|
||||||
*
|
|
||||||
* @author R.A. Ray
|
|
||||||
* @projectDescription jQuery plugin for dynamically displaying unobtrusive messages in the browser. Mimics the behavior of the MacOS program "Growl."
|
|
||||||
* @version 0.1.0
|
|
||||||
*
|
|
||||||
* @requires jquery.js (tested with 1.2.6)
|
|
||||||
*
|
|
||||||
* @param fadeInSpeed int - Duration of fade in animation in miliseconds
|
|
||||||
* default: 500
|
|
||||||
* @param fadeOutSpeed int - Duration of fade out animationin miliseconds
|
|
||||||
default: 500
|
|
||||||
* @param removeTimer int - Timeout, in miliseconds, before notice is removed once it is the top non-sticky notice in the list
|
|
||||||
default: 4000
|
|
||||||
* @param isSticky bool - Whether the notice should fade out on its own or wait to be manually closed
|
|
||||||
default: false
|
|
||||||
* @param usingTransparentPNG bool - Whether or not the notice is using transparent .png images in its styling
|
|
||||||
default: false
|
|
||||||
*/
|
|
||||||
|
|
||||||
( function( $ ) {
|
|
||||||
|
|
||||||
$.purr = function ( notice, options )
|
|
||||||
{
|
|
||||||
// Convert notice to a jQuery object
|
|
||||||
notice = $( notice );
|
|
||||||
|
|
||||||
// Add a class to denote the notice as not sticky
|
|
||||||
if ( !options.isSticky )
|
|
||||||
{
|
|
||||||
notice.addClass( 'not-sticky' );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get the container element from the page
|
|
||||||
var cont = document.getElementById( 'purr-container' );
|
|
||||||
|
|
||||||
// If the container doesn't yet exist, we need to create it
|
|
||||||
if ( !cont )
|
|
||||||
{
|
|
||||||
cont = '<div id="purr-container"></div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert cont to a jQuery object
|
|
||||||
cont = $( cont );
|
|
||||||
|
|
||||||
// Add the container to the page
|
|
||||||
$( 'body' ).append( cont );
|
|
||||||
|
|
||||||
notify();
|
|
||||||
|
|
||||||
function notify ()
|
|
||||||
{
|
|
||||||
// Set up the close button
|
|
||||||
var close = document.createElement( 'a' );
|
|
||||||
$( close ).attr(
|
|
||||||
{
|
|
||||||
className: 'close',
|
|
||||||
href: '#close',
|
|
||||||
innerHTML: 'Close'
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.appendTo( notice )
|
|
||||||
.click( function ()
|
|
||||||
{
|
|
||||||
removeNotice();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Add the notice to the page and keep it hidden initially
|
|
||||||
notice.appendTo( cont )
|
|
||||||
.hide();
|
|
||||||
|
|
||||||
if ( jQuery.browser.msie && options.usingTransparentPNG )
|
|
||||||
{
|
|
||||||
// IE7 and earlier can't handle the combination of opacity and transparent pngs, so if we're using transparent pngs in our
|
|
||||||
// notice style, we'll just skip the fading in.
|
|
||||||
notice.show();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//Fade in the notice we just added
|
|
||||||
notice.fadeIn( options.fadeInSpeed );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up the removal interval for the added notice if that notice is not a sticky
|
|
||||||
if ( !options.isSticky )
|
|
||||||
{
|
|
||||||
var topSpotInt = setInterval( function ()
|
|
||||||
{
|
|
||||||
// Check to see if our notice is the first non-sticky notice in the list
|
|
||||||
if ( notice.prevAll( '.not-sticky' ).length == 0 )
|
|
||||||
{
|
|
||||||
// Stop checking once the condition is met
|
|
||||||
clearInterval( topSpotInt );
|
|
||||||
|
|
||||||
// Call the close action after the timeout set in options
|
|
||||||
setTimeout( function ()
|
|
||||||
{
|
|
||||||
removeNotice();
|
|
||||||
}, options.removeTimer
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}, 200 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeNotice ()
|
|
||||||
{
|
|
||||||
// IE7 and earlier can't handle the combination of opacity and transparent pngs, so if we're using transparent pngs in our
|
|
||||||
// notice style, we'll just skip the fading out.
|
|
||||||
if ( jQuery.browser.msie && options.usingTransparentPNG )
|
|
||||||
{
|
|
||||||
notice.css( { opacity: 0 } )
|
|
||||||
.animate(
|
|
||||||
{
|
|
||||||
height: '0px'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
duration: options.fadeOutSpeed,
|
|
||||||
complete: function ()
|
|
||||||
{
|
|
||||||
notice.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Fade the object out before reducing its height to produce the sliding effect
|
|
||||||
notice.animate(
|
|
||||||
{
|
|
||||||
opacity: '0'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
duration: options.fadeOutSpeed,
|
|
||||||
complete: function ()
|
|
||||||
{
|
|
||||||
notice.animate(
|
|
||||||
{
|
|
||||||
height: '0px'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
duration: options.fadeOutSpeed,
|
|
||||||
complete: function ()
|
|
||||||
{
|
|
||||||
notice.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
$.fn.purr = function ( options )
|
|
||||||
{
|
|
||||||
options = options || {};
|
|
||||||
options.fadeInSpeed = options.fadeInSpeed || 500;
|
|
||||||
options.fadeOutSpeed = options.fadeOutSpeed || 500;
|
|
||||||
options.removeTimer = options.removeTimer || 4000;
|
|
||||||
options.isSticky = options.isSticky || false;
|
|
||||||
options.usingTransparentPNG = options.usingTransparentPNG || false;
|
|
||||||
|
|
||||||
this.each( function()
|
|
||||||
{
|
|
||||||
new $.purr( this, options );
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
})( jQuery );
|
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
function SocketIoConnection(config) {
|
|
||||||
this.connection = io.connect(config.url, config.socketio);
|
|
||||||
}
|
|
||||||
|
|
||||||
SocketIoConnection.prototype.on = function (ev, fn) {
|
|
||||||
this.connection.on(ev, fn);
|
|
||||||
};
|
|
||||||
|
|
||||||
SocketIoConnection.prototype.emit = function () {
|
|
||||||
this.connection.emit.apply(this.connection, arguments);
|
|
||||||
};
|
|
||||||
|
|
||||||
SocketIoConnection.prototype.removeAllListeners = function () {
|
|
||||||
this.connection.removeAllListeners();
|
|
||||||
};
|
|
||||||
|
|
||||||
SocketIoConnection.prototype.getSessionid = function () {
|
|
||||||
return this.connection.socket.sessionid;
|
|
||||||
};
|
|
||||||
|
|
||||||
SocketIoConnection.prototype.disconnect = function () {
|
|
||||||
return this.connection.disconnect();
|
|
||||||
};
|
|
|
@ -1,41 +0,0 @@
|
||||||
var USERVOICE;
|
|
||||||
if(USERVOICE == undefined) {
|
|
||||||
USERVOICE = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
USERVOICE.load = function (name, id, email, sso_token) {
|
|
||||||
// Include the UserVoice JavaScript SDK (only needed once on a page)
|
|
||||||
UserVoice=window.UserVoice||[];(function(){var uv=document.createElement('script');uv.type='text/javascript';uv.async=true;uv.src='//widget.uservoice.com/wybK0nSMNuhlWkIKzTyWg.js';var s=document.getElementsByTagName('script')[0];s.parentNode.insertBefore(uv,s)})();
|
|
||||||
|
|
||||||
//
|
|
||||||
// UserVoice Javascript SDK developer documentation:
|
|
||||||
// https://www.uservoice.com/o/javascript-sdk
|
|
||||||
//
|
|
||||||
|
|
||||||
// Set colors
|
|
||||||
UserVoice.push(['set', {
|
|
||||||
accent_color: '#448dd6',
|
|
||||||
trigger_color: 'white',
|
|
||||||
trigger_background_color: 'rgba(46, 49, 51, 0.6)'
|
|
||||||
}]);
|
|
||||||
|
|
||||||
// Identify the user and pass traits
|
|
||||||
// To enable, replace sample data with actual user traits and uncomment the line
|
|
||||||
if (name) {
|
|
||||||
UserVoice.push(['setSSO', sso_token]);
|
|
||||||
UserVoice.push(['identify', {
|
|
||||||
'email': email, // User’s email address
|
|
||||||
'name': name, // User’s real name
|
|
||||||
'id': id, // Optional: Unique id of the user
|
|
||||||
}]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add default trigger to the bottom-left corner of the window:
|
|
||||||
UserVoice.push(['addTrigger', { mode: 'contact', trigger_position: 'bottom-left' }]);
|
|
||||||
|
|
||||||
// Or, use your own custom trigger:
|
|
||||||
//UserVoice.push(['addTrigger', '#barometer_tab', { mode: 'contact' }]);
|
|
||||||
|
|
||||||
// Autoprompt for Satisfaction and SmartVote (only displayed under certain conditions)
|
|
||||||
UserVoice.push(['autoprompt', {}]);
|
|
||||||
};
|
|
3836
app/assets/javascripts/metamaps.secret.bundle.js
Normal file
|
@ -1,36 +0,0 @@
|
||||||
/*
|
|
||||||
RequireJS 2.1.11 Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved.
|
|
||||||
Available via the MIT or new BSD license.
|
|
||||||
see: http://github.com/jrburke/requirejs for details
|
|
||||||
*/
|
|
||||||
var requirejs,require,define;
|
|
||||||
(function(ca){function G(b){return"[object Function]"===M.call(b)}function H(b){return"[object Array]"===M.call(b)}function v(b,c){if(b){var d;for(d=0;d<b.length&&(!b[d]||!c(b[d],d,b));d+=1);}}function U(b,c){if(b){var d;for(d=b.length-1;-1<d&&(!b[d]||!c(b[d],d,b));d-=1);}}function s(b,c){return ga.call(b,c)}function j(b,c){return s(b,c)&&b[c]}function B(b,c){for(var d in b)if(s(b,d)&&c(b[d],d))break}function V(b,c,d,g){c&&B(c,function(c,h){if(d||!s(b,h))g&&"object"===typeof c&&c&&!H(c)&&!G(c)&&!(c instanceof
|
|
||||||
RegExp)?(b[h]||(b[h]={}),V(b[h],c,d,g)):b[h]=c});return b}function t(b,c){return function(){return c.apply(b,arguments)}}function da(b){throw b;}function ea(b){if(!b)return b;var c=ca;v(b.split("."),function(b){c=c[b]});return c}function C(b,c,d,g){c=Error(c+"\nhttp://requirejs.org/docs/errors.html#"+b);c.requireType=b;c.requireModules=g;d&&(c.originalError=d);return c}function ha(b){function c(a,e,b){var f,n,c,d,g,h,i,I=e&&e.split("/");n=I;var m=l.map,k=m&&m["*"];if(a&&"."===a.charAt(0))if(e){n=
|
|
||||||
I.slice(0,I.length-1);a=a.split("/");e=a.length-1;l.nodeIdCompat&&R.test(a[e])&&(a[e]=a[e].replace(R,""));n=a=n.concat(a);d=n.length;for(e=0;e<d;e++)if(c=n[e],"."===c)n.splice(e,1),e-=1;else if(".."===c)if(1===e&&(".."===n[2]||".."===n[0]))break;else 0<e&&(n.splice(e-1,2),e-=2);a=a.join("/")}else 0===a.indexOf("./")&&(a=a.substring(2));if(b&&m&&(I||k)){n=a.split("/");e=n.length;a:for(;0<e;e-=1){d=n.slice(0,e).join("/");if(I)for(c=I.length;0<c;c-=1)if(b=j(m,I.slice(0,c).join("/")))if(b=j(b,d)){f=b;
|
|
||||||
g=e;break a}!h&&(k&&j(k,d))&&(h=j(k,d),i=e)}!f&&h&&(f=h,g=i);f&&(n.splice(0,g,f),a=n.join("/"))}return(f=j(l.pkgs,a))?f:a}function d(a){z&&v(document.getElementsByTagName("script"),function(e){if(e.getAttribute("data-requiremodule")===a&&e.getAttribute("data-requirecontext")===i.contextName)return e.parentNode.removeChild(e),!0})}function g(a){var e=j(l.paths,a);if(e&&H(e)&&1<e.length)return e.shift(),i.require.undef(a),i.require([a]),!0}function u(a){var e,b=a?a.indexOf("!"):-1;-1<b&&(e=a.substring(0,
|
|
||||||
b),a=a.substring(b+1,a.length));return[e,a]}function m(a,e,b,f){var n,d,g=null,h=e?e.name:null,l=a,m=!0,k="";a||(m=!1,a="_@r"+(M+=1));a=u(a);g=a[0];a=a[1];g&&(g=c(g,h,f),d=j(p,g));a&&(g?k=d&&d.normalize?d.normalize(a,function(a){return c(a,h,f)}):c(a,h,f):(k=c(a,h,f),a=u(k),g=a[0],k=a[1],b=!0,n=i.nameToUrl(k)));b=g&&!d&&!b?"_unnormalized"+(Q+=1):"";return{prefix:g,name:k,parentMap:e,unnormalized:!!b,url:n,originalName:l,isDefine:m,id:(g?g+"!"+k:k)+b}}function q(a){var e=a.id,b=j(k,e);b||(b=k[e]=new i.Module(a));
|
|
||||||
return b}function r(a,e,b){var f=a.id,n=j(k,f);if(s(p,f)&&(!n||n.defineEmitComplete))"defined"===e&&b(p[f]);else if(n=q(a),n.error&&"error"===e)b(n.error);else n.on(e,b)}function w(a,e){var b=a.requireModules,f=!1;if(e)e(a);else if(v(b,function(e){if(e=j(k,e))e.error=a,e.events.error&&(f=!0,e.emit("error",a))}),!f)h.onError(a)}function x(){S.length&&(ia.apply(A,[A.length,0].concat(S)),S=[])}function y(a){delete k[a];delete W[a]}function F(a,e,b){var f=a.map.id;a.error?a.emit("error",a.error):(e[f]=
|
|
||||||
!0,v(a.depMaps,function(f,c){var d=f.id,g=j(k,d);g&&(!a.depMatched[c]&&!b[d])&&(j(e,d)?(a.defineDep(c,p[d]),a.check()):F(g,e,b))}),b[f]=!0)}function D(){var a,e,b=(a=1E3*l.waitSeconds)&&i.startTime+a<(new Date).getTime(),f=[],c=[],h=!1,k=!0;if(!X){X=!0;B(W,function(a){var i=a.map,m=i.id;if(a.enabled&&(i.isDefine||c.push(a),!a.error))if(!a.inited&&b)g(m)?h=e=!0:(f.push(m),d(m));else if(!a.inited&&(a.fetched&&i.isDefine)&&(h=!0,!i.prefix))return k=!1});if(b&&f.length)return a=C("timeout","Load timeout for modules: "+
|
|
||||||
f,null,f),a.contextName=i.contextName,w(a);k&&v(c,function(a){F(a,{},{})});if((!b||e)&&h)if((z||fa)&&!Y)Y=setTimeout(function(){Y=0;D()},50);X=!1}}function E(a){s(p,a[0])||q(m(a[0],null,!0)).init(a[1],a[2])}function K(a){var a=a.currentTarget||a.srcElement,e=i.onScriptLoad;a.detachEvent&&!Z?a.detachEvent("onreadystatechange",e):a.removeEventListener("load",e,!1);e=i.onScriptError;(!a.detachEvent||Z)&&a.removeEventListener("error",e,!1);return{node:a,id:a&&a.getAttribute("data-requiremodule")}}function L(){var a;
|
|
||||||
for(x();A.length;){a=A.shift();if(null===a[0])return w(C("mismatch","Mismatched anonymous define() module: "+a[a.length-1]));E(a)}}var X,$,i,N,Y,l={waitSeconds:7,baseUrl:"./",paths:{},bundles:{},pkgs:{},shim:{},config:{}},k={},W={},aa={},A=[],p={},T={},ba={},M=1,Q=1;N={require:function(a){return a.require?a.require:a.require=i.makeRequire(a.map)},exports:function(a){a.usingExports=!0;if(a.map.isDefine)return a.exports?p[a.map.id]=a.exports:a.exports=p[a.map.id]={}},module:function(a){return a.module?
|
|
||||||
a.module:a.module={id:a.map.id,uri:a.map.url,config:function(){return j(l.config,a.map.id)||{}},exports:a.exports||(a.exports={})}}};$=function(a){this.events=j(aa,a.id)||{};this.map=a;this.shim=j(l.shim,a.id);this.depExports=[];this.depMaps=[];this.depMatched=[];this.pluginMaps={};this.depCount=0};$.prototype={init:function(a,e,b,f){f=f||{};if(!this.inited){this.factory=e;if(b)this.on("error",b);else this.events.error&&(b=t(this,function(a){this.emit("error",a)}));this.depMaps=a&&a.slice(0);this.errback=
|
|
||||||
b;this.inited=!0;this.ignore=f.ignore;f.enabled||this.enabled?this.enable():this.check()}},defineDep:function(a,e){this.depMatched[a]||(this.depMatched[a]=!0,this.depCount-=1,this.depExports[a]=e)},fetch:function(){if(!this.fetched){this.fetched=!0;i.startTime=(new Date).getTime();var a=this.map;if(this.shim)i.makeRequire(this.map,{enableBuildCallback:!0})(this.shim.deps||[],t(this,function(){return a.prefix?this.callPlugin():this.load()}));else return a.prefix?this.callPlugin():this.load()}},load:function(){var a=
|
|
||||||
this.map.url;T[a]||(T[a]=!0,i.load(this.map.id,a))},check:function(){if(this.enabled&&!this.enabling){var a,e,b=this.map.id;e=this.depExports;var f=this.exports,c=this.factory;if(this.inited)if(this.error)this.emit("error",this.error);else{if(!this.defining){this.defining=!0;if(1>this.depCount&&!this.defined){if(G(c)){if(this.events.error&&this.map.isDefine||h.onError!==da)try{f=i.execCb(b,c,e,f)}catch(d){a=d}else f=i.execCb(b,c,e,f);this.map.isDefine&&void 0===f&&((e=this.module)?f=e.exports:this.usingExports&&
|
|
||||||
(f=this.exports));if(a)return a.requireMap=this.map,a.requireModules=this.map.isDefine?[this.map.id]:null,a.requireType=this.map.isDefine?"define":"require",w(this.error=a)}else f=c;this.exports=f;if(this.map.isDefine&&!this.ignore&&(p[b]=f,h.onResourceLoad))h.onResourceLoad(i,this.map,this.depMaps);y(b);this.defined=!0}this.defining=!1;this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}else this.fetch()}},callPlugin:function(){var a=
|
|
||||||
this.map,b=a.id,d=m(a.prefix);this.depMaps.push(d);r(d,"defined",t(this,function(f){var d,g;g=j(ba,this.map.id);var J=this.map.name,u=this.map.parentMap?this.map.parentMap.name:null,p=i.makeRequire(a.parentMap,{enableBuildCallback:!0});if(this.map.unnormalized){if(f.normalize&&(J=f.normalize(J,function(a){return c(a,u,!0)})||""),f=m(a.prefix+"!"+J,this.map.parentMap),r(f,"defined",t(this,function(a){this.init([],function(){return a},null,{enabled:!0,ignore:!0})})),g=j(k,f.id)){this.depMaps.push(f);
|
|
||||||
if(this.events.error)g.on("error",t(this,function(a){this.emit("error",a)}));g.enable()}}else g?(this.map.url=i.nameToUrl(g),this.load()):(d=t(this,function(a){this.init([],function(){return a},null,{enabled:!0})}),d.error=t(this,function(a){this.inited=!0;this.error=a;a.requireModules=[b];B(k,function(a){0===a.map.id.indexOf(b+"_unnormalized")&&y(a.map.id)});w(a)}),d.fromText=t(this,function(f,c){var g=a.name,J=m(g),k=O;c&&(f=c);k&&(O=!1);q(J);s(l.config,b)&&(l.config[g]=l.config[b]);try{h.exec(f)}catch(j){return w(C("fromtexteval",
|
|
||||||
"fromText eval for "+b+" failed: "+j,j,[b]))}k&&(O=!0);this.depMaps.push(J);i.completeLoad(g);p([g],d)}),f.load(a.name,p,d,l))}));i.enable(d,this);this.pluginMaps[d.id]=d},enable:function(){W[this.map.id]=this;this.enabling=this.enabled=!0;v(this.depMaps,t(this,function(a,b){var c,f;if("string"===typeof a){a=m(a,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap);this.depMaps[b]=a;if(c=j(N,a.id)){this.depExports[b]=c(this);return}this.depCount+=1;r(a,"defined",t(this,function(a){this.defineDep(b,
|
|
||||||
a);this.check()}));this.errback&&r(a,"error",t(this,this.errback))}c=a.id;f=k[c];!s(N,c)&&(f&&!f.enabled)&&i.enable(a,this)}));B(this.pluginMaps,t(this,function(a){var b=j(k,a.id);b&&!b.enabled&&i.enable(a,this)}));this.enabling=!1;this.check()},on:function(a,b){var c=this.events[a];c||(c=this.events[a]=[]);c.push(b)},emit:function(a,b){v(this.events[a],function(a){a(b)});"error"===a&&delete this.events[a]}};i={config:l,contextName:b,registry:k,defined:p,urlFetched:T,defQueue:A,Module:$,makeModuleMap:m,
|
|
||||||
nextTick:h.nextTick,onError:w,configure:function(a){a.baseUrl&&"/"!==a.baseUrl.charAt(a.baseUrl.length-1)&&(a.baseUrl+="/");var b=l.shim,c={paths:!0,bundles:!0,config:!0,map:!0};B(a,function(a,b){c[b]?(l[b]||(l[b]={}),V(l[b],a,!0,!0)):l[b]=a});a.bundles&&B(a.bundles,function(a,b){v(a,function(a){a!==b&&(ba[a]=b)})});a.shim&&(B(a.shim,function(a,c){H(a)&&(a={deps:a});if((a.exports||a.init)&&!a.exportsFn)a.exportsFn=i.makeShimExports(a);b[c]=a}),l.shim=b);a.packages&&v(a.packages,function(a){var b,
|
|
||||||
a="string"===typeof a?{name:a}:a;b=a.name;a.location&&(l.paths[b]=a.location);l.pkgs[b]=a.name+"/"+(a.main||"main").replace(ja,"").replace(R,"")});B(k,function(a,b){!a.inited&&!a.map.unnormalized&&(a.map=m(b))});if(a.deps||a.callback)i.require(a.deps||[],a.callback)},makeShimExports:function(a){return function(){var b;a.init&&(b=a.init.apply(ca,arguments));return b||a.exports&&ea(a.exports)}},makeRequire:function(a,e){function g(f,c,d){var j,l;e.enableBuildCallback&&(c&&G(c))&&(c.__requireJsBuild=
|
|
||||||
!0);if("string"===typeof f){if(G(c))return w(C("requireargs","Invalid require call"),d);if(a&&s(N,f))return N[f](k[a.id]);if(h.get)return h.get(i,f,a,g);j=m(f,a,!1,!0);j=j.id;return!s(p,j)?w(C("notloaded",'Module name "'+j+'" has not been loaded yet for context: '+b+(a?"":". Use require([])"))):p[j]}L();i.nextTick(function(){L();l=q(m(null,a));l.skipMap=e.skipMap;l.init(f,c,d,{enabled:!0});D()});return g}e=e||{};V(g,{isBrowser:z,toUrl:function(b){var e,d=b.lastIndexOf("."),g=b.split("/")[0];if(-1!==
|
|
||||||
d&&(!("."===g||".."===g)||1<d))e=b.substring(d,b.length),b=b.substring(0,d);return i.nameToUrl(c(b,a&&a.id,!0),e,!0)},defined:function(b){return s(p,m(b,a,!1,!0).id)},specified:function(b){b=m(b,a,!1,!0).id;return s(p,b)||s(k,b)}});a||(g.undef=function(b){x();var c=m(b,a,!0),e=j(k,b);d(b);delete p[b];delete T[c.url];delete aa[b];U(A,function(a,c){a[0]===b&&A.splice(c,1)});e&&(e.events.defined&&(aa[b]=e.events),y(b))});return g},enable:function(a){j(k,a.id)&&q(a).enable()},completeLoad:function(a){var b,
|
|
||||||
c,f=j(l.shim,a)||{},d=f.exports;for(x();A.length;){c=A.shift();if(null===c[0]){c[0]=a;if(b)break;b=!0}else c[0]===a&&(b=!0);E(c)}c=j(k,a);if(!b&&!s(p,a)&&c&&!c.inited){if(l.enforceDefine&&(!d||!ea(d)))return g(a)?void 0:w(C("nodefine","No define call for "+a,null,[a]));E([a,f.deps||[],f.exportsFn])}D()},nameToUrl:function(a,b,c){var f,d,g;(f=j(l.pkgs,a))&&(a=f);if(f=j(ba,a))return i.nameToUrl(f,b,c);if(h.jsExtRegExp.test(a))f=a+(b||"");else{f=l.paths;a=a.split("/");for(d=a.length;0<d;d-=1)if(g=a.slice(0,
|
|
||||||
d).join("/"),g=j(f,g)){H(g)&&(g=g[0]);a.splice(0,d,g);break}f=a.join("/");f+=b||(/^data\:|\?/.test(f)||c?"":".js");f=("/"===f.charAt(0)||f.match(/^[\w\+\.\-]+:/)?"":l.baseUrl)+f}return l.urlArgs?f+((-1===f.indexOf("?")?"?":"&")+l.urlArgs):f},load:function(a,b){h.load(i,a,b)},execCb:function(a,b,c,d){return b.apply(d,c)},onScriptLoad:function(a){if("load"===a.type||ka.test((a.currentTarget||a.srcElement).readyState))P=null,a=K(a),i.completeLoad(a.id)},onScriptError:function(a){var b=K(a);if(!g(b.id))return w(C("scripterror",
|
|
||||||
"Script error for: "+b.id,a,[b.id]))}};i.require=i.makeRequire();return i}var h,x,y,D,K,E,P,L,q,Q,la=/(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,ma=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,R=/\.js$/,ja=/^\.\//;x=Object.prototype;var M=x.toString,ga=x.hasOwnProperty,ia=Array.prototype.splice,z=!!("undefined"!==typeof window&&"undefined"!==typeof navigator&&window.document),fa=!z&&"undefined"!==typeof importScripts,ka=z&&"PLAYSTATION 3"===navigator.platform?/^complete$/:/^(complete|loaded)$/,
|
|
||||||
Z="undefined"!==typeof opera&&"[object Opera]"===opera.toString(),F={},r={},S=[],O=!1;if("undefined"===typeof define){if("undefined"!==typeof requirejs){if(G(requirejs))return;r=requirejs;requirejs=void 0}"undefined"!==typeof require&&!G(require)&&(r=require,require=void 0);h=requirejs=function(b,c,d,g){var u,m="_";!H(b)&&"string"!==typeof b&&(u=b,H(c)?(b=c,c=d,d=g):b=[]);u&&u.context&&(m=u.context);(g=j(F,m))||(g=F[m]=h.s.newContext(m));u&&g.configure(u);return g.require(b,c,d)};h.config=function(b){return h(b)};
|
|
||||||
h.nextTick="undefined"!==typeof setTimeout?function(b){setTimeout(b,4)}:function(b){b()};require||(require=h);h.version="2.1.11";h.jsExtRegExp=/^\/|:|\?|\.js$/;h.isBrowser=z;x=h.s={contexts:F,newContext:ha};h({});v(["toUrl","undef","defined","specified"],function(b){h[b]=function(){var c=F._;return c.require[b].apply(c,arguments)}});if(z&&(y=x.head=document.getElementsByTagName("head")[0],D=document.getElementsByTagName("base")[0]))y=x.head=D.parentNode;h.onError=da;h.createNode=function(b){var c=
|
|
||||||
b.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml","html:script"):document.createElement("script");c.type=b.scriptType||"text/javascript";c.charset="utf-8";c.async=!0;return c};h.load=function(b,c,d){var g=b&&b.config||{};if(z)return g=h.createNode(g,c,d),g.setAttribute("data-requirecontext",b.contextName),g.setAttribute("data-requiremodule",c),g.attachEvent&&!(g.attachEvent.toString&&0>g.attachEvent.toString().indexOf("[native code"))&&!Z?(O=!0,g.attachEvent("onreadystatechange",b.onScriptLoad)):
|
|
||||||
(g.addEventListener("load",b.onScriptLoad,!1),g.addEventListener("error",b.onScriptError,!1)),g.src=d,L=g,D?y.insertBefore(g,D):y.appendChild(g),L=null,g;if(fa)try{importScripts(d),b.completeLoad(c)}catch(j){b.onError(C("importscripts","importScripts failed for "+c+" at "+d,j,[c]))}};z&&!r.skipDataMain&&U(document.getElementsByTagName("script"),function(b){y||(y=b.parentNode);if(K=b.getAttribute("data-main"))return q=K,r.baseUrl||(E=q.split("/"),q=E.pop(),Q=E.length?E.join("/")+"/":"./",r.baseUrl=
|
|
||||||
Q),q=q.replace(R,""),h.jsExtRegExp.test(q)&&(q=K),r.deps=r.deps?r.deps.concat(q):[q],!0});define=function(b,c,d){var g,h;"string"!==typeof b&&(d=c,c=b,b=null);H(c)||(d=c,c=null);!c&&G(d)&&(c=[],d.length&&(d.toString().replace(la,"").replace(ma,function(b,d){c.push(d)}),c=(1===d.length?["require"]:["require","exports","module"]).concat(c)));if(O){if(!(g=L))P&&"interactive"===P.readyState||U(document.getElementsByTagName("script"),function(b){if("interactive"===b.readyState)return P=b}),g=P;g&&(b||
|
|
||||||
(b=g.getAttribute("data-requiremodule")),h=F[g.getAttribute("data-requirecontext")])}(h?h.defQueue:S).push([b,c,d])};define.amd={jQuery:!0};h.exec=function(b){return eval(b)};h(r)}})(this);
|
|
|
@ -1,138 +0,0 @@
|
||||||
|
|
||||||
/*
|
|
||||||
* classList.js: Cross-browser full element.classList implementation.
|
|
||||||
* 2011-06-15
|
|
||||||
*
|
|
||||||
* By Eli Grey, http://eligrey.com
|
|
||||||
* Public Domain.
|
|
||||||
* NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*global self, document, DOMException */
|
|
||||||
|
|
||||||
/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js*/
|
|
||||||
|
|
||||||
if (typeof document !== "undefined" && !("classList" in document.createElement("a"))) {
|
|
||||||
|
|
||||||
(function (view) {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var
|
|
||||||
classListProp = "classList"
|
|
||||||
, protoProp = "prototype"
|
|
||||||
, elemCtrProto = (view.HTMLElement || view.Element)[protoProp]
|
|
||||||
, objCtr = Object
|
|
||||||
, strTrim = String[protoProp].trim || function () {
|
|
||||||
return this.replace(/^\s+|\s+$/g, "");
|
|
||||||
}
|
|
||||||
, arrIndexOf = Array[protoProp].indexOf || function (item) {
|
|
||||||
var
|
|
||||||
i = 0
|
|
||||||
, len = this.length
|
|
||||||
;
|
|
||||||
for (; i < len; i++) {
|
|
||||||
if (i in this && this[i] === item) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
// Vendors: please allow content code to instantiate DOMExceptions
|
|
||||||
, DOMEx = function (type, message) {
|
|
||||||
this.name = type;
|
|
||||||
this.code = DOMException[type];
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
, checkTokenAndGetIndex = function (classList, token) {
|
|
||||||
if (token === "") {
|
|
||||||
throw new DOMEx(
|
|
||||||
"SYNTAX_ERR"
|
|
||||||
, "An invalid or illegal string was specified"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (/\s/.test(token)) {
|
|
||||||
throw new DOMEx(
|
|
||||||
"INVALID_CHARACTER_ERR"
|
|
||||||
, "String contains an invalid character"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return arrIndexOf.call(classList, token);
|
|
||||||
}
|
|
||||||
, ClassList = function (elem) {
|
|
||||||
var
|
|
||||||
trimmedClasses = strTrim.call(elem.className)
|
|
||||||
, classes = trimmedClasses ? trimmedClasses.split(/\s+/) : []
|
|
||||||
, i = 0
|
|
||||||
, len = classes.length
|
|
||||||
;
|
|
||||||
for (; i < len; i++) {
|
|
||||||
this.push(classes[i]);
|
|
||||||
}
|
|
||||||
this._updateClassName = function () {
|
|
||||||
elem.className = this.toString();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
, classListProto = ClassList[protoProp] = []
|
|
||||||
, classListGetter = function () {
|
|
||||||
return new ClassList(this);
|
|
||||||
}
|
|
||||||
;
|
|
||||||
// Most DOMException implementations don't allow calling DOMException's toString()
|
|
||||||
// on non-DOMExceptions. Error's toString() is sufficient here.
|
|
||||||
DOMEx[protoProp] = Error[protoProp];
|
|
||||||
classListProto.item = function (i) {
|
|
||||||
return this[i] || null;
|
|
||||||
};
|
|
||||||
classListProto.contains = function (token) {
|
|
||||||
token += "";
|
|
||||||
return checkTokenAndGetIndex(this, token) !== -1;
|
|
||||||
};
|
|
||||||
classListProto.add = function (token) {
|
|
||||||
token += "";
|
|
||||||
if (checkTokenAndGetIndex(this, token) === -1) {
|
|
||||||
this.push(token);
|
|
||||||
this._updateClassName();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
classListProto.remove = function (token) {
|
|
||||||
token += "";
|
|
||||||
var index = checkTokenAndGetIndex(this, token);
|
|
||||||
if (index !== -1) {
|
|
||||||
this.splice(index, 1);
|
|
||||||
this._updateClassName();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
classListProto.toggle = function (token) {
|
|
||||||
token += "";
|
|
||||||
if (checkTokenAndGetIndex(this, token) === -1) {
|
|
||||||
this.add(token);
|
|
||||||
} else {
|
|
||||||
this.remove(token);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
classListProto.toString = function () {
|
|
||||||
return this.join(" ");
|
|
||||||
};
|
|
||||||
|
|
||||||
if (objCtr.defineProperty) {
|
|
||||||
var classListPropDesc = {
|
|
||||||
get: classListGetter
|
|
||||||
, enumerable: true
|
|
||||||
, configurable: true
|
|
||||||
};
|
|
||||||
try {
|
|
||||||
objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
|
|
||||||
} catch (ex) { // IE 8 doesn't support enumerable:true
|
|
||||||
if (ex.number === -0x7FF5EC54) {
|
|
||||||
classListPropDesc.enumerable = false;
|
|
||||||
objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (objCtr[protoProp].__defineGetter__) {
|
|
||||||
elemCtrProto.__defineGetter__(classListProp, classListGetter);
|
|
||||||
}
|
|
||||||
|
|
||||||
}(self));
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
if (!Function.prototype.bind) {
|
|
||||||
Function.prototype.bind = function (oThis) {
|
|
||||||
if (typeof this !== "function") {
|
|
||||||
// closest thing possible to the ECMAScript 5 internal IsCallable function
|
|
||||||
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
|
|
||||||
}
|
|
||||||
|
|
||||||
var aArgs = Array.prototype.slice.call(arguments, 1),
|
|
||||||
fToBind = this,
|
|
||||||
fNOP = function () {},
|
|
||||||
fBound = function () {
|
|
||||||
return fToBind.apply(this instanceof fNOP && oThis
|
|
||||||
? this
|
|
||||||
: oThis,
|
|
||||||
aArgs.concat(Array.prototype.slice.call(arguments)));
|
|
||||||
};
|
|
||||||
|
|
||||||
fNOP.prototype = this.prototype;
|
|
||||||
fBound.prototype = new fNOP();
|
|
||||||
|
|
||||||
return fBound;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
// adds requestAnimationFrame functionality
|
|
||||||
// Source: http://strd6.com/2011/05/better-window-requestanimationframe-shim/
|
|
||||||
|
|
||||||
window.requestAnimationFrame || (window.requestAnimationFrame =
|
|
||||||
window.webkitRequestAnimationFrame ||
|
|
||||||
window.mozRequestAnimationFrame ||
|
|
||||||
window.oRequestAnimationFrame ||
|
|
||||||
window.msRequestAnimationFrame ||
|
|
||||||
function(callback, element) {
|
|
||||||
return window.setTimeout(function() {
|
|
||||||
callback(+new Date());
|
|
||||||
}, 1000 / 60);
|
|
||||||
});
|
|
|
@ -1,247 +0,0 @@
|
||||||
Metamaps.Backbone = {};
|
|
||||||
Metamaps.Backbone.Map = Backbone.Model.extend({
|
|
||||||
urlRoot: '/maps',
|
|
||||||
blacklist: ['created_at', 'updated_at', 'created_at_clean', 'updated_at_clean', 'user_name', 'contributor_count', 'topic_count', 'synapse_count', 'topics', 'synapses', 'mappings', 'mappers'],
|
|
||||||
toJSON: function (options) {
|
|
||||||
return _.omit(this.attributes, this.blacklist);
|
|
||||||
},
|
|
||||||
save: function (key, val, options) {
|
|
||||||
|
|
||||||
var attrs;
|
|
||||||
|
|
||||||
// Handle both `"key", value` and `{key: value}` -style arguments.
|
|
||||||
if (key == null || typeof key === 'object') {
|
|
||||||
attrs = key;
|
|
||||||
options = val;
|
|
||||||
} else {
|
|
||||||
(attrs = {})[key] = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
var newOptions = options || {};
|
|
||||||
var s = newOptions.success;
|
|
||||||
|
|
||||||
newOptions.success = function (model, response, opt) {
|
|
||||||
if (s) s(model, response, opt);
|
|
||||||
model.trigger('saved');
|
|
||||||
};
|
|
||||||
return Backbone.Model.prototype.save.call(this, attrs, newOptions);
|
|
||||||
},
|
|
||||||
initialize: function () {
|
|
||||||
this.on('changeByOther', this.updateView);
|
|
||||||
this.on('saved', this.savedEvent);
|
|
||||||
},
|
|
||||||
savedEvent: function() {
|
|
||||||
Metamaps.Realtime.sendMapChange(this);
|
|
||||||
},
|
|
||||||
authorizeToEdit: function (mapper) {
|
|
||||||
if (mapper && (this.get('permission') === "commons" || this.get('user_id') === mapper.get('id'))) return true;
|
|
||||||
else return false;
|
|
||||||
},
|
|
||||||
authorizePermissionChange: function (mapper) {
|
|
||||||
if (mapper && this.get('user_id') === mapper.get('id')) return true;
|
|
||||||
else return false;
|
|
||||||
},
|
|
||||||
getUser: function () {
|
|
||||||
return Metamaps.Mapper.get(this.get('user_id'));
|
|
||||||
},
|
|
||||||
fetchContained: function () {
|
|
||||||
var bb = Metamaps.Backbone;
|
|
||||||
var that = this;
|
|
||||||
var start = function (data) {
|
|
||||||
that.set('mappers', new bb.MapperCollection(data.mappers));
|
|
||||||
that.set('topics', new bb.TopicCollection(data.topics));
|
|
||||||
that.set('synapses', new bb.SynapseCollection(data.synapses));
|
|
||||||
that.set('mappings', new bb.MappingCollection(data.mappings));
|
|
||||||
};
|
|
||||||
|
|
||||||
var e = $.ajax({
|
|
||||||
url: "/maps/" + this.id + "/contains.json",
|
|
||||||
success: start,
|
|
||||||
error: errorFunc,
|
|
||||||
async: false
|
|
||||||
});
|
|
||||||
},
|
|
||||||
getTopics: function () {
|
|
||||||
if (!this.get('topics')) {
|
|
||||||
this.fetchContained();
|
|
||||||
}
|
|
||||||
return this.get('topics');
|
|
||||||
},
|
|
||||||
getSynapses: function () {
|
|
||||||
if (!this.get('synapses')) {
|
|
||||||
this.fetchContained();
|
|
||||||
}
|
|
||||||
return this.get('synapses');
|
|
||||||
},
|
|
||||||
getMappings: function () {
|
|
||||||
if (!this.get('mappings')) {
|
|
||||||
this.fetchContained();
|
|
||||||
}
|
|
||||||
return this.get('mappings');
|
|
||||||
},
|
|
||||||
getMappers: function () {
|
|
||||||
if (!this.get('mappers')) {
|
|
||||||
this.fetchContained();
|
|
||||||
}
|
|
||||||
return this.get('mappers');
|
|
||||||
},
|
|
||||||
attrForCards: function () {
|
|
||||||
function capitalize(string) {
|
|
||||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
var n = this.get('name');
|
|
||||||
var d = this.get('desc');
|
|
||||||
|
|
||||||
var maxNameLength = 32;
|
|
||||||
var maxDescLength = 118;
|
|
||||||
var truncatedName = n ? (n.length > maxNameLength ? n.substring(0, maxNameLength) + "..." : n) : "";
|
|
||||||
var truncatedDesc = d ? (d.length > maxDescLength ? d.substring(0, maxDescLength) + "..." : d) : "";
|
|
||||||
|
|
||||||
var obj = {
|
|
||||||
id: this.id,
|
|
||||||
name: truncatedName,
|
|
||||||
fullName: n,
|
|
||||||
desc: truncatedDesc,
|
|
||||||
permission: this.get("permission") ? capitalize(this.get("permission")) : "Commons",
|
|
||||||
editPermission: this.authorizeToEdit(Metamaps.Active.Mapper) ? 'canEdit' : 'cannotEdit',
|
|
||||||
contributor_count_number: '<span class="cCountColor">' + this.get('contributor_count') + '</span>',
|
|
||||||
contributor_count_string: this.get('contributor_count') == 1 ? ' contributor' : ' contributors',
|
|
||||||
topic_count_number: '<span class="tCountColor">' + this.get('topic_count') + '</span>',
|
|
||||||
topic_count_string: this.get('topic_count') == 1 ? ' topic' : ' topics',
|
|
||||||
synapse_count_number: '<span class="sCountColor">' + this.get('synapse_count') + '</span>',
|
|
||||||
synapse_count_string: this.get('synapse_count') == 1 ? ' synapse' : ' synapses',
|
|
||||||
screenshot: '<img src="' + this.get('screenshot_url') + '" />'
|
|
||||||
};
|
|
||||||
return obj;
|
|
||||||
},
|
|
||||||
updateView: function() {
|
|
||||||
var map = Metamaps.Active.Map;
|
|
||||||
var isActiveMap = this.id === map.id;
|
|
||||||
var authorized = map && map.authorizeToEdit(Metamaps.Active.Mapper) ? 'canEditMap' : '';
|
|
||||||
var commonsMap = map && map.get('permission') === 'commons' ? 'commonsMap' : '';
|
|
||||||
if (isActiveMap) {
|
|
||||||
Metamaps.Map.InfoBox.updateNameDescPerm(this.get('name'), this.get('desc'), this.get('permission'));
|
|
||||||
this.updateMapWrapper();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
updateMapWrapper: function() {
|
|
||||||
var map = Metamaps.Active.Map;
|
|
||||||
var isActiveMap = this.id === map.id;
|
|
||||||
var authorized = map && map.authorizeToEdit(Metamaps.Active.Mapper) ? 'canEditMap' : '';
|
|
||||||
var commonsMap = map && map.get('permission') === 'commons' ? 'commonsMap' : '';
|
|
||||||
if (isActiveMap) {
|
|
||||||
$('.wrapper').removeClass('canEditMap commonsMap').addClass(authorized + ' ' + commonsMap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Metamaps.Backbone.MapsCollection = Backbone.Collection.extend({
|
|
||||||
model: Metamaps.Backbone.Map,
|
|
||||||
initialize: function(models, options) {
|
|
||||||
this.id = options.id;
|
|
||||||
this.sortBy = options.sortBy;
|
|
||||||
|
|
||||||
if (options.mapperId) {
|
|
||||||
this.mapperId = options.mapperId;
|
|
||||||
}
|
|
||||||
|
|
||||||
// this.page represents the NEXT page to fetch
|
|
||||||
this.page = models.length > 0 ? (models.length < 20 ? "loadedAll" : 2) : 1;
|
|
||||||
},
|
|
||||||
url: function() {
|
|
||||||
if (!this.mapperId) {
|
|
||||||
return '/explore/' + this.id + '.json';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return '/explore/mapper/' + this.mapperId + '.json';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
comparator: function (a, b) {
|
|
||||||
a = a.get(this.sortBy);
|
|
||||||
b = b.get(this.sortBy);
|
|
||||||
var temp;
|
|
||||||
if (this.sortBy === 'name') {
|
|
||||||
a = a ? a.toLowerCase() : "";
|
|
||||||
b = b ? b.toLowerCase() : "";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// this is for updated_at and created_at
|
|
||||||
temp = a;
|
|
||||||
a = b;
|
|
||||||
b = temp;
|
|
||||||
a = (new Date(a)).getTime();
|
|
||||||
b = (new Date(b)).getTime();
|
|
||||||
}
|
|
||||||
return a > b ? 1 : a < b ? -1 : 0;
|
|
||||||
},
|
|
||||||
getMaps: function (cb) {
|
|
||||||
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
Metamaps.Loading.show();
|
|
||||||
|
|
||||||
if (this.page != "loadedAll") {
|
|
||||||
var numBefore = this.length;
|
|
||||||
this.fetch({
|
|
||||||
remove: false,
|
|
||||||
silent: true,
|
|
||||||
data: { page: this.page },
|
|
||||||
success: function (collection, response, options) {
|
|
||||||
// you can pass additional options to the event you trigger here as well
|
|
||||||
if (collection.length - numBefore < 20) {
|
|
||||||
self.page = "loadedAll";
|
|
||||||
}
|
|
||||||
else self.page += 1;
|
|
||||||
self.trigger('successOnFetch', cb);
|
|
||||||
},
|
|
||||||
error: function (collection, response, options) {
|
|
||||||
// you can pass additional options to the event you trigger here as well
|
|
||||||
self.trigger('errorOnFetch');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
self.trigger('successOnFetch', cb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Metamaps.Backbone.Message = Backbone.Model.extend({
|
|
||||||
urlRoot: '/messages',
|
|
||||||
blacklist: ['created_at', 'updated_at'],
|
|
||||||
toJSON: function (options) {
|
|
||||||
return _.omit(this.attributes, this.blacklist);
|
|
||||||
},
|
|
||||||
prepareLiForFilter: function () {
|
|
||||||
/*var li = '';
|
|
||||||
li += '<li data-id="' + this.id.toString() + '">';
|
|
||||||
li += '<img src="' + this.get("image") + '" data-id="' + this.id.toString() + '"';
|
|
||||||
li += ' alt="' + this.get('name') + '" />';
|
|
||||||
li += '<p>' + this.get('name') + '</p></li>';
|
|
||||||
return li;*/
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Metamaps.Backbone.MessageCollection = Backbone.Collection.extend({
|
|
||||||
model: Metamaps.Backbone.Message,
|
|
||||||
url: '/messages'
|
|
||||||
});
|
|
||||||
|
|
||||||
Metamaps.Backbone.Mapper = Backbone.Model.extend({
|
|
||||||
urlRoot: '/users',
|
|
||||||
blacklist: ['created_at', 'updated_at'],
|
|
||||||
toJSON: function (options) {
|
|
||||||
return _.omit(this.attributes, this.blacklist);
|
|
||||||
},
|
|
||||||
prepareLiForFilter: function () {
|
|
||||||
var li = '';
|
|
||||||
li += '<li data-id="' + this.id.toString() + '">';
|
|
||||||
li += '<img src="' + this.get("image") + '" data-id="' + this.id.toString() + '"';
|
|
||||||
li += ' alt="' + this.get('name') + '" />';
|
|
||||||
li += '<p>' + this.get('name') + '</p></li>';
|
|
||||||
return li;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Metamaps.Backbone.MapperCollection = Backbone.Collection.extend({
|
|
||||||
model: Metamaps.Backbone.Mapper,
|
|
||||||
url: '/users'
|
|
||||||
});
|
|
|
@ -1,697 +0,0 @@
|
||||||
var Metamaps = {}; // this variable declaration defines a Javascript object that will contain all the variables and functions used by us, broken down into 'sub-modules' that look something like this
|
|
||||||
/*
|
|
||||||
|
|
||||||
* unless you are on a page with the Javascript InfoVis Toolkit (Topic or Map) the only section in the metamaps
|
|
||||||
* object will be these
|
|
||||||
GlobalUI
|
|
||||||
Active
|
|
||||||
Maps
|
|
||||||
Mappers
|
|
||||||
Backbone
|
|
||||||
|
|
||||||
* all these get added when you are on a page with the Javascript Infovis Toolkit
|
|
||||||
Settings
|
|
||||||
Touch
|
|
||||||
Mouse
|
|
||||||
Selected
|
|
||||||
Metacodes
|
|
||||||
Topics
|
|
||||||
Synapses
|
|
||||||
Mappings
|
|
||||||
Create
|
|
||||||
TopicCard
|
|
||||||
SynapseCard
|
|
||||||
Visualize
|
|
||||||
Util
|
|
||||||
Realtime
|
|
||||||
Control
|
|
||||||
Filter
|
|
||||||
Listeners
|
|
||||||
Organize
|
|
||||||
Map
|
|
||||||
Mapper
|
|
||||||
Topic
|
|
||||||
Synapse
|
|
||||||
JIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
Metamaps.Active = {
|
|
||||||
Map: null,
|
|
||||||
Topic: null,
|
|
||||||
Mapper: null
|
|
||||||
};
|
|
||||||
Metamaps.Maps = {};
|
|
||||||
|
|
||||||
$(document).ready(function () {
|
|
||||||
function init() {
|
|
||||||
for (var prop in Metamaps) {
|
|
||||||
|
|
||||||
// this runs the init function within each sub-object on the Metamaps one
|
|
||||||
if (Metamaps.hasOwnProperty(prop) &&
|
|
||||||
Metamaps[prop] != null &&
|
|
||||||
Metamaps[prop].hasOwnProperty('init') &&
|
|
||||||
typeof (Metamaps[prop].init) == 'function'
|
|
||||||
) {
|
|
||||||
Metamaps[prop].init();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// initialize the famous ui
|
|
||||||
var callFamous = function(){
|
|
||||||
if (Metamaps.Famous) {
|
|
||||||
Metamaps.Famous.build();
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
setTimeout(callFamous, 100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
callFamous();
|
|
||||||
});
|
|
||||||
|
|
||||||
Metamaps.GlobalUI = {
|
|
||||||
notifyTimeout: null,
|
|
||||||
lightbox: null,
|
|
||||||
init: function () {
|
|
||||||
var self = Metamaps.GlobalUI;
|
|
||||||
|
|
||||||
self.Search.init();
|
|
||||||
self.CreateMap.init();
|
|
||||||
self.Account.init();
|
|
||||||
|
|
||||||
//bind lightbox clicks
|
|
||||||
$('.openLightbox').click(function (event) {
|
|
||||||
self.openLightbox($(this).attr('data-open'));
|
|
||||||
event.preventDefault();
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#lightbox_screen, #lightbox_close').click(self.closeLightbox);
|
|
||||||
|
|
||||||
// initialize global backbone models and collections
|
|
||||||
if (Metamaps.Active.Mapper) Metamaps.Active.Mapper = new Metamaps.Backbone.Mapper(Metamaps.Active.Mapper);
|
|
||||||
|
|
||||||
var myCollection = Metamaps.Maps.Mine ? Metamaps.Maps.Mine : [];
|
|
||||||
var mapperCollection = [];
|
|
||||||
var mapperOptionsObj = {id: 'mapper', sortBy: 'updated_at' };
|
|
||||||
if (Metamaps.Maps.Mapper) {
|
|
||||||
mapperCollection = Metamaps.Maps.Mapper.models;
|
|
||||||
mapperOptionsObj.mapperId = Metamaps.Maps.Mapper.id;
|
|
||||||
}
|
|
||||||
var featuredCollection = Metamaps.Maps.Featured ? Metamaps.Maps.Featured : [];
|
|
||||||
var activeCollection = Metamaps.Maps.Active ? Metamaps.Maps.Active : [];
|
|
||||||
Metamaps.Maps.Mine = new Metamaps.Backbone.MapsCollection(myCollection, {id: 'mine', sortBy: 'updated_at' });
|
|
||||||
// 'Mapper' refers to another mapper
|
|
||||||
Metamaps.Maps.Mapper = new Metamaps.Backbone.MapsCollection(mapperCollection, mapperOptionsObj);
|
|
||||||
Metamaps.Maps.Featured = new Metamaps.Backbone.MapsCollection(featuredCollection, {id: 'featured', sortBy: 'updated_at' });
|
|
||||||
Metamaps.Maps.Active = new Metamaps.Backbone.MapsCollection(activeCollection, {id: 'active', sortBy: 'updated_at' });
|
|
||||||
},
|
|
||||||
openLightbox: function (which) {
|
|
||||||
var self = Metamaps.GlobalUI;
|
|
||||||
|
|
||||||
$('.lightboxContent').hide();
|
|
||||||
$('#' + which).show();
|
|
||||||
|
|
||||||
self.lightbox = which;
|
|
||||||
|
|
||||||
$('#lightbox_overlay').show();
|
|
||||||
|
|
||||||
var heightOfContent = '-' + ($('#lightbox_main').height() / 2) + 'px';
|
|
||||||
// animate the content in from the bottom
|
|
||||||
$('#lightbox_main').animate({
|
|
||||||
'top': '50%',
|
|
||||||
'margin-top': heightOfContent
|
|
||||||
}, 200, 'easeOutCubic');
|
|
||||||
|
|
||||||
// fade the black overlay in
|
|
||||||
$('#lightbox_screen').animate({
|
|
||||||
'opacity': '0.42'
|
|
||||||
}, 200);
|
|
||||||
|
|
||||||
if (which == "switchMetacodes") {
|
|
||||||
Metamaps.Create.isSwitchingSet = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
closeLightbox: function (event) {
|
|
||||||
var self = Metamaps.GlobalUI;
|
|
||||||
|
|
||||||
if (event) event.preventDefault();
|
|
||||||
|
|
||||||
// animate the lightbox content offscreen
|
|
||||||
$('#lightbox_main').animate({
|
|
||||||
'top': '100%',
|
|
||||||
'margin-top': '0'
|
|
||||||
}, 200, 'easeInCubic');
|
|
||||||
|
|
||||||
// fade the black overlay out
|
|
||||||
$('#lightbox_screen').animate({
|
|
||||||
'opacity': '0.0'
|
|
||||||
}, 200, function () {
|
|
||||||
$('#lightbox_overlay').hide();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (self.lightbox === 'forkmap') Metamaps.GlobalUI.CreateMap.reset('fork_map');
|
|
||||||
if (self.lightbox === 'newmap') Metamaps.GlobalUI.CreateMap.reset('new_map');
|
|
||||||
if (Metamaps.Create && Metamaps.Create.isSwitchingSet) {
|
|
||||||
Metamaps.Create.cancelMetacodeSetSwitch();
|
|
||||||
}
|
|
||||||
self.lightbox = null;
|
|
||||||
},
|
|
||||||
notifyUser: function (message, leaveOpen) {
|
|
||||||
var self = Metamaps.GlobalUI;
|
|
||||||
|
|
||||||
function famousReady() {
|
|
||||||
Metamaps.Famous.toast.surf.setContent(message);
|
|
||||||
Metamaps.Famous.toast.show();
|
|
||||||
clearTimeout(self.notifyTimeOut);
|
|
||||||
if (!leaveOpen) {
|
|
||||||
self.notifyTimeOut = setTimeout(function () {
|
|
||||||
Metamaps.Famous.toast.hide();
|
|
||||||
}, 8000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// initialize the famous ui
|
|
||||||
var callFamous = function(){
|
|
||||||
if (Metamaps.Famous && Metamaps.Famous.toast) {
|
|
||||||
famousReady();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
setTimeout(callFamous, 100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
callFamous();
|
|
||||||
},
|
|
||||||
clearNotify: function() {
|
|
||||||
var self = Metamaps.GlobalUI;
|
|
||||||
|
|
||||||
clearTimeout(self.notifyTimeOut);
|
|
||||||
Metamaps.Famous.toast.hide();
|
|
||||||
},
|
|
||||||
shareInvite: function(inviteLink) {
|
|
||||||
window.prompt("To copy the invite link, press: Ctrl+C, Enter", inviteLink);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Metamaps.GlobalUI.CreateMap = {
|
|
||||||
newMap: null,
|
|
||||||
emptyMapForm: "",
|
|
||||||
emptyForkMapForm: "",
|
|
||||||
topicsToMap: [],
|
|
||||||
synapsesToMap: [],
|
|
||||||
init: function () {
|
|
||||||
var self = Metamaps.GlobalUI.CreateMap;
|
|
||||||
|
|
||||||
self.newMap = new Metamaps.Backbone.Map({ permission: 'commons' });
|
|
||||||
|
|
||||||
self.bindFormEvents();
|
|
||||||
|
|
||||||
self.emptyMapForm = $('#new_map').html();
|
|
||||||
|
|
||||||
},
|
|
||||||
bindFormEvents: function () {
|
|
||||||
var self = Metamaps.GlobalUI.CreateMap;
|
|
||||||
|
|
||||||
$('.new_map button.cancel').unbind().bind('click', function (event) {
|
|
||||||
event.preventDefault();
|
|
||||||
Metamaps.GlobalUI.closeLightbox();
|
|
||||||
});
|
|
||||||
$('.new_map button.submitMap').unbind().bind('click', self.submit);
|
|
||||||
|
|
||||||
// bind permission changer events on the createMap form
|
|
||||||
$('.permIcon').unbind().bind('click', self.switchPermission);
|
|
||||||
},
|
|
||||||
closeSuccess: function () {
|
|
||||||
$('#mapCreatedSuccess').fadeOut(300, function(){
|
|
||||||
$(this).remove();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
generateSuccessMessage: function (id) {
|
|
||||||
var stringStart = "<div id='mapCreatedSuccess'><h6>SUCCESS!</h6>Your map has been created. Do you want to: <a id='mapGo' href='/maps/";
|
|
||||||
stringStart += id;
|
|
||||||
stringStart += "' onclick='Metamaps.GlobalUI.CreateMap.closeSuccess();'>Go to your new map</a>";
|
|
||||||
stringStart += "<span>OR</span><a id='mapStay' href='#' onclick='Metamaps.GlobalUI.CreateMap.closeSuccess(); return false;'>Stay on this ";
|
|
||||||
var page = Metamaps.Active.Map ? 'map' : 'page';
|
|
||||||
var stringEnd = "</a></div>";
|
|
||||||
return stringStart + page + stringEnd;
|
|
||||||
},
|
|
||||||
switchPermission: function () {
|
|
||||||
var self = Metamaps.GlobalUI.CreateMap;
|
|
||||||
|
|
||||||
self.newMap.set('permission', $(this).attr('data-permission'));
|
|
||||||
$(this).siblings('.permIcon').find('.mapPermIcon').removeClass('selected');
|
|
||||||
$(this).find('.mapPermIcon').addClass('selected');
|
|
||||||
|
|
||||||
var permText = $(this).find('.tip').html();
|
|
||||||
$(this).parents('.new_map').find('.permText').html(permText);
|
|
||||||
},
|
|
||||||
submit: function (event) {
|
|
||||||
if (event) event.preventDefault();
|
|
||||||
|
|
||||||
var self = Metamaps.GlobalUI.CreateMap;
|
|
||||||
|
|
||||||
if (Metamaps.GlobalUI.lightbox === 'forkmap') {
|
|
||||||
self.newMap.set('topicsToMap', self.topicsToMap);
|
|
||||||
self.newMap.set('synapsesToMap', self.synapsesToMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
var formId = Metamaps.GlobalUI.lightbox === 'forkmap' ? '#fork_map' : '#new_map';
|
|
||||||
var $form = $(formId);
|
|
||||||
|
|
||||||
self.newMap.set('name', $form.find('#map_name').val());
|
|
||||||
self.newMap.set('desc', $form.find('#map_desc').val());
|
|
||||||
|
|
||||||
if (self.newMap.get('name').length===0){
|
|
||||||
self.throwMapNameError();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.newMap.save(null, {
|
|
||||||
success: self.success
|
|
||||||
// TODO add error message
|
|
||||||
});
|
|
||||||
|
|
||||||
Metamaps.GlobalUI.closeLightbox();
|
|
||||||
Metamaps.GlobalUI.notifyUser('Working...');
|
|
||||||
},
|
|
||||||
throwMapNameError: function () {
|
|
||||||
var self = Metamaps.GlobalUI.CreateMap;
|
|
||||||
|
|
||||||
var formId = Metamaps.GlobalUI.lightbox === 'forkmap' ? '#fork_map' : '#new_map';
|
|
||||||
var $form = $(formId);
|
|
||||||
|
|
||||||
var message = $("<div class='feedback_message'>Please enter a map name...</div>");
|
|
||||||
|
|
||||||
$form.find('#map_name').after(message);
|
|
||||||
setTimeout(function(){
|
|
||||||
message.fadeOut('fast', function(){
|
|
||||||
message.remove();
|
|
||||||
});
|
|
||||||
}, 5000);
|
|
||||||
},
|
|
||||||
success: function (model) {
|
|
||||||
var self = Metamaps.GlobalUI.CreateMap;
|
|
||||||
|
|
||||||
//push the new map onto the collection of 'my maps'
|
|
||||||
Metamaps.Maps.Mine.add(model);
|
|
||||||
|
|
||||||
var formId = Metamaps.GlobalUI.lightbox === 'forkmap' ? '#fork_map' : '#new_map';
|
|
||||||
var form = $(formId);
|
|
||||||
|
|
||||||
Metamaps.GlobalUI.clearNotify();
|
|
||||||
$('#wrapper').append(self.generateSuccessMessage(model.id));
|
|
||||||
|
|
||||||
},
|
|
||||||
reset: function (id) {
|
|
||||||
var self = Metamaps.GlobalUI.CreateMap;
|
|
||||||
|
|
||||||
var form = $('#' + id);
|
|
||||||
|
|
||||||
if (id === "fork_map") {
|
|
||||||
self.topicsToMap = [];
|
|
||||||
self.synapsesToMap = [];
|
|
||||||
form.html(self.emptyForkMapForm);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
form.html(self.emptyMapForm);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.bindFormEvents();
|
|
||||||
self.newMap = new Metamaps.Backbone.Map({ permission: 'commons' });
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
Metamaps.GlobalUI.Account = {
|
|
||||||
isOpen: false,
|
|
||||||
changing: false,
|
|
||||||
init: function () {
|
|
||||||
var self = Metamaps.GlobalUI.Account;
|
|
||||||
|
|
||||||
$('.sidebarAccountIcon').click(self.toggleBox);
|
|
||||||
$('.sidebarAccountBox').click(function(event){
|
|
||||||
event.stopPropagation();
|
|
||||||
});
|
|
||||||
$('body').click(self.close);
|
|
||||||
},
|
|
||||||
toggleBox: function (event) {
|
|
||||||
var self = Metamaps.GlobalUI.Account;
|
|
||||||
|
|
||||||
if (self.isOpen) self.close();
|
|
||||||
else self.open();
|
|
||||||
|
|
||||||
event.stopPropagation();
|
|
||||||
},
|
|
||||||
open: function () {
|
|
||||||
var self = Metamaps.GlobalUI.Account;
|
|
||||||
|
|
||||||
Metamaps.Filter.close();
|
|
||||||
$('.sidebarAccountIcon .tooltipsUnder').addClass('hide');
|
|
||||||
|
|
||||||
|
|
||||||
if (!self.isOpen && !self.changing) {
|
|
||||||
self.changing = true;
|
|
||||||
$('.sidebarAccountBox').fadeIn(200, function () {
|
|
||||||
self.changing = false;
|
|
||||||
self.isOpen = true;
|
|
||||||
$('.sidebarAccountBox #user_email').focus();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
close: function () {
|
|
||||||
var self = Metamaps.GlobalUI.Account;
|
|
||||||
|
|
||||||
$('.sidebarAccountIcon .tooltipsUnder').removeClass('hide');
|
|
||||||
if (!self.changing) {
|
|
||||||
self.changing = true;
|
|
||||||
$('.sidebarAccountBox #user_email').blur();
|
|
||||||
$('.sidebarAccountBox').fadeOut(200, function () {
|
|
||||||
self.changing = false;
|
|
||||||
self.isOpen = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Metamaps.GlobalUI.Search = {
|
|
||||||
locked: false,
|
|
||||||
isOpen: false,
|
|
||||||
limitTopicsToMe: false,
|
|
||||||
limitMapsToMe: false,
|
|
||||||
timeOut: null,
|
|
||||||
changing: false,
|
|
||||||
optionsInitialized: false,
|
|
||||||
init: function () {
|
|
||||||
var self = Metamaps.GlobalUI.Search;
|
|
||||||
|
|
||||||
var loader = new CanvasLoader('searchLoading');
|
|
||||||
loader.setColor('#4fb5c0'); // default is '#000000'
|
|
||||||
loader.setDiameter(24); // default is 40
|
|
||||||
loader.setDensity(41); // default is 40
|
|
||||||
loader.setRange(0.9); // default is 1.3
|
|
||||||
loader.show(); // Hidden by default
|
|
||||||
|
|
||||||
// bind the hover events
|
|
||||||
$(".sidebarSearch").hover(function () {
|
|
||||||
self.open()
|
|
||||||
}, function () {
|
|
||||||
self.close(800, false)
|
|
||||||
});
|
|
||||||
|
|
||||||
$('.sidebarSearchIcon').click(function (e) {
|
|
||||||
$('.sidebarSearchField').focus();
|
|
||||||
});
|
|
||||||
$('.sidebarSearch').click(function (e) {
|
|
||||||
e.stopPropagation();
|
|
||||||
});
|
|
||||||
$('body').click(function (e) {
|
|
||||||
self.close(0, false);
|
|
||||||
});
|
|
||||||
|
|
||||||
// open if the search is closed and user hits ctrl+/
|
|
||||||
// close if they hit ESC
|
|
||||||
$('body').bind('keyup', function (e) {
|
|
||||||
switch (e.which) {
|
|
||||||
case 191:
|
|
||||||
if ((e.ctrlKey && !self.isOpen) || (e.ctrlKey && self.locked)) {
|
|
||||||
self.open(true); // true for focus
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 27:
|
|
||||||
if (self.isOpen) {
|
|
||||||
self.close(0, true);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break; //console.log(e.which);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
self.startTypeahead();
|
|
||||||
},
|
|
||||||
lock: function() {
|
|
||||||
var self = Metamaps.GlobalUI.Search;
|
|
||||||
self.locked = true;
|
|
||||||
},
|
|
||||||
unlock: function() {
|
|
||||||
var self = Metamaps.GlobalUI.Search;
|
|
||||||
self.locked = false;
|
|
||||||
},
|
|
||||||
open: function (focus) {
|
|
||||||
var self = Metamaps.GlobalUI.Search;
|
|
||||||
|
|
||||||
clearTimeout(self.timeOut);
|
|
||||||
if (!self.isOpen && !self.changing && !self.locked) {
|
|
||||||
self.changing = true;
|
|
||||||
$('.sidebarSearch .twitter-typeahead, .sidebarSearch .tt-hint, .sidebarSearchField').animate({
|
|
||||||
width: '400px'
|
|
||||||
}, 300, function () {
|
|
||||||
if (focus) $('.sidebarSearchField').focus();
|
|
||||||
$('.sidebarSearchField, .sidebarSearch .tt-hint').css({
|
|
||||||
padding: '7px 10px 3px 10px',
|
|
||||||
width: '380px'
|
|
||||||
});
|
|
||||||
self.changing = false;
|
|
||||||
self.isOpen = true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
close: function (closeAfter, bypass) {
|
|
||||||
var self = Metamaps.GlobalUI.Search;
|
|
||||||
|
|
||||||
self.timeOut = setTimeout(function () {
|
|
||||||
if (!self.locked && !self.changing && self.isOpen && (bypass || $('.sidebarSearchField.tt-input').val() == '')) {
|
|
||||||
self.changing = true;
|
|
||||||
$('.sidebarSearchField, .sidebarSearch .tt-hint').css({
|
|
||||||
padding: '7px 0 3px 0',
|
|
||||||
width: '400px'
|
|
||||||
});
|
|
||||||
$('.sidebarSearch .twitter-typeahead, .sidebarSearch .tt-hint, .sidebarSearchField').animate({
|
|
||||||
width: '0'
|
|
||||||
}, 300, function () {
|
|
||||||
$('.sidebarSearchField').typeahead('val', '');
|
|
||||||
$('.sidebarSearchField').blur();
|
|
||||||
self.changing = false;
|
|
||||||
self.isOpen = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, closeAfter);
|
|
||||||
},
|
|
||||||
startTypeahead: function () {
|
|
||||||
var self = Metamaps.GlobalUI.Search;
|
|
||||||
|
|
||||||
var mapheader = Metamaps.Active.Mapper ? '<div class="searchMapsHeader searchHeader"><h3 class="search-heading">Maps</h3><input type="checkbox" class="limitToMe" id="limitMapsToMe"></input><label for="limitMapsToMe" class="limitToMeLabel">added by me</label><div class="minimizeResults minimizeMapResults"></div><div class="clearfloat"></div></div>' : '<div class="searchMapsHeader searchHeader"><h3 class="search-heading">Maps</h3><div class="minimizeResults minimizeMapResults"></div><div class="clearfloat"></div></div>';
|
|
||||||
var topicheader = Metamaps.Active.Mapper ? '<div class="searchTopicsHeader searchHeader"><h3 class="search-heading">Topics</h3><input type="checkbox" class="limitToMe" id="limitTopicsToMe"></input><label for="limitTopicsToMe" class="limitToMeLabel">added by me</label><div class="minimizeResults minimizeTopicResults"></div><div class="clearfloat"></div></div>' : '<div class="searchTopicsHeader searchHeader"><h3 class="search-heading">Topics</h3><div class="minimizeResults minimizeTopicResults"></div><div class="clearfloat"></div></div>';
|
|
||||||
var mapperheader = '<div class="searchMappersHeader searchHeader"><h3 class="search-heading">Mappers</h3><div class="minimizeResults minimizeMapperResults"></div><div class="clearfloat"></div></div>';
|
|
||||||
|
|
||||||
var topics = {
|
|
||||||
name: 'topics',
|
|
||||||
limit: 9999,
|
|
||||||
|
|
||||||
display: function(s) { return s.label; },
|
|
||||||
templates: {
|
|
||||||
notFound: function(s) {
|
|
||||||
return Hogan.compile(topicheader + $('#topicSearchTemplate').html()).render({
|
|
||||||
value: "No results",
|
|
||||||
label: "No results",
|
|
||||||
typeImageURL: "<%= asset_path('icons/wildcard.png') %>",
|
|
||||||
rtype: "noresult"
|
|
||||||
});
|
|
||||||
},
|
|
||||||
header: topicheader,
|
|
||||||
suggestion: function(s) {
|
|
||||||
return Hogan.compile($('#topicSearchTemplate').html()).render(s);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
source: new Bloodhound({
|
|
||||||
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
|
|
||||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
|
||||||
remote: {
|
|
||||||
url: '/search/topics',
|
|
||||||
prepare: function(query, settings) {
|
|
||||||
settings.url += '?term=' + query;
|
|
||||||
if (Metamaps.Active.Mapper && self.limitTopicsToMe) {
|
|
||||||
settings.url += "&user=" + Metamaps.Active.Mapper.id.toString();
|
|
||||||
}
|
|
||||||
return settings;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
var maps = {
|
|
||||||
name: 'maps',
|
|
||||||
limit: 9999,
|
|
||||||
display: function(s) { return s.label; },
|
|
||||||
templates: {
|
|
||||||
notFound: function(s) {
|
|
||||||
return Hogan.compile(mapheader + $('#mapSearchTemplate').html()).render({
|
|
||||||
value: "No results",
|
|
||||||
label: "No results",
|
|
||||||
rtype: "noresult"
|
|
||||||
});
|
|
||||||
},
|
|
||||||
header: mapheader,
|
|
||||||
suggestion: function(s) {
|
|
||||||
return Hogan.compile($('#mapSearchTemplate').html()).render(s);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
source: new Bloodhound({
|
|
||||||
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
|
|
||||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
|
||||||
remote: {
|
|
||||||
url: '/search/maps',
|
|
||||||
prepare: function(query, settings) {
|
|
||||||
settings.url += '?term=' + query;
|
|
||||||
if (Metamaps.Active.Mapper && self.limitMapsToMe) {
|
|
||||||
settings.url += "&user=" + Metamaps.Active.Mapper.id.toString();
|
|
||||||
}
|
|
||||||
return settings;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
var mappers = {
|
|
||||||
name: 'mappers',
|
|
||||||
limit: 9999,
|
|
||||||
display: function(s) { return s.label; },
|
|
||||||
templates: {
|
|
||||||
notFound: function(s) {
|
|
||||||
return Hogan.compile(mapperheader + $('#mapperSearchTemplate').html()).render({
|
|
||||||
value: "No results",
|
|
||||||
label: "No results",
|
|
||||||
rtype: "noresult",
|
|
||||||
profile: "<%= asset_path('user.png') %>",
|
|
||||||
});
|
|
||||||
},
|
|
||||||
header: mapperheader,
|
|
||||||
suggestion: function(s) {
|
|
||||||
return Hogan.compile($('#mapperSearchTemplate').html()).render(s);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
source: new Bloodhound({
|
|
||||||
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
|
|
||||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
|
||||||
remote: {
|
|
||||||
url: '/search/mappers?term=%QUERY',
|
|
||||||
wildcard: '%QUERY',
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Take all that crazy setup data and put it together into one beautiful typeahead call!
|
|
||||||
$('.sidebarSearchField').typeahead(
|
|
||||||
{
|
|
||||||
highlight: true,
|
|
||||||
},
|
|
||||||
[topics, maps, mappers]
|
|
||||||
);
|
|
||||||
|
|
||||||
//Set max height of the search results box to prevent it from covering bottom left footer
|
|
||||||
$('.sidebarSearchField').bind('typeahead:render', function (event) {
|
|
||||||
self.initSearchOptions();
|
|
||||||
self.hideLoader();
|
|
||||||
var h = $(window).height();
|
|
||||||
$(".tt-dropdown-menu").css('max-height', h - 100);
|
|
||||||
if (self.limitTopicsToMe) {
|
|
||||||
$('#limitTopicsToMe').prop('checked', true);
|
|
||||||
}
|
|
||||||
if (self.limitMapsToMe) {
|
|
||||||
$('#limitMapsToMe').prop('checked', true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$(window).resize(function () {
|
|
||||||
var h = $(window).height();
|
|
||||||
$(".tt-dropdown-menu").css('max-height', h - 100);
|
|
||||||
});
|
|
||||||
|
|
||||||
// tell the autocomplete to launch a new tab with the topic, map, or mapper you clicked on
|
|
||||||
$('.sidebarSearchField').bind('typeahead:select', self.handleResultClick);
|
|
||||||
|
|
||||||
// don't do it, if they clicked on a 'addToMap' button
|
|
||||||
$('.sidebarSearch button.addToMap').click(function (event) {
|
|
||||||
event.stopPropagation();
|
|
||||||
});
|
|
||||||
|
|
||||||
// make sure that when you click on 'limit to me' or 'toggle section' it works
|
|
||||||
$('.sidebarSearchField.tt-input').keyup(function(){
|
|
||||||
if ($('.sidebarSearchField.tt-input').val() === '') {
|
|
||||||
self.hideLoader();
|
|
||||||
} else {
|
|
||||||
self.showLoader();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
},
|
|
||||||
handleResultClick: function (event, datum, dataset) {
|
|
||||||
var self = Metamaps.GlobalUI.Search;
|
|
||||||
|
|
||||||
self.hideLoader();
|
|
||||||
|
|
||||||
if (["topic", "map", "mapper"].indexOf(datum.rtype) !== -1) {
|
|
||||||
self.close(0, true);
|
|
||||||
var win;
|
|
||||||
if (datum.rtype == "topic") {
|
|
||||||
Metamaps.Router.topics(datum.id);
|
|
||||||
} else if (datum.rtype == "map") {
|
|
||||||
Metamaps.Router.maps(datum.id);
|
|
||||||
} else if (datum.rtype == "mapper") {
|
|
||||||
Metamaps.Router.explore("mapper", datum.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
initSearchOptions: function () {
|
|
||||||
var self = Metamaps.GlobalUI.Search;
|
|
||||||
|
|
||||||
function toggleResultSet(set) {
|
|
||||||
var s = $('.tt-dataset-' + set + ' .tt-suggestion, .tt-dataset-' + set + ' .resultnoresult');
|
|
||||||
if (s.is(':visible')) {
|
|
||||||
s.hide();
|
|
||||||
$(this).removeClass('minimizeResults').addClass('maximizeResults');
|
|
||||||
} else {
|
|
||||||
s.show();
|
|
||||||
$(this).removeClass('maximizeResults').addClass('minimizeResults');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$('.limitToMe').unbind().bind("change", function (e) {
|
|
||||||
if ($(this).attr('id') == 'limitTopicsToMe') {
|
|
||||||
self.limitTopicsToMe = !self.limitTopicsToMe;
|
|
||||||
}
|
|
||||||
if ($(this).attr('id') == 'limitMapsToMe') {
|
|
||||||
self.limitMapsToMe = !self.limitMapsToMe;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the value of the search equal to itself to retrigger the
|
|
||||||
// autocomplete event
|
|
||||||
var searchQuery = $('.sidebarSearchField.tt-input').val();
|
|
||||||
$(".sidebarSearchField").typeahead('val', '')
|
|
||||||
.typeahead('val', searchQuery);
|
|
||||||
});
|
|
||||||
|
|
||||||
// when the user clicks minimize section, hide the results for that section
|
|
||||||
$('.minimizeMapperResults').unbind().click(function (e) {
|
|
||||||
toggleResultSet.call(this, 'mappers');
|
|
||||||
});
|
|
||||||
$('.minimizeTopicResults').unbind().click(function (e) {
|
|
||||||
toggleResultSet.call(this, 'topics');
|
|
||||||
});
|
|
||||||
$('.minimizeMapResults').unbind().click(function (e) {
|
|
||||||
toggleResultSet.call(this, 'maps');
|
|
||||||
});
|
|
||||||
},
|
|
||||||
hideLoader: function () {
|
|
||||||
$('#searchLoading').hide();
|
|
||||||
},
|
|
||||||
showLoader: function () {
|
|
||||||
$('#searchLoading').show();
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,333 +0,0 @@
|
||||||
/*
|
|
||||||
* Example tab-separated input:
|
|
||||||
* Some fields will be ignored
|
|
||||||
*
|
|
||||||
* Topics
|
|
||||||
* Id Name Metacode X Y Description Link User Permission
|
|
||||||
* 8 topic8 Action -231 131 admin commons
|
|
||||||
* 5 topic Action -229 -131 admin commons
|
|
||||||
* 7 topic7.1 Action -470 -55 hey admin commons
|
|
||||||
* 2 topic2 Event -57 -63 admin commons
|
|
||||||
* 1 topic1 Catalyst -51 50 admin commons
|
|
||||||
* 6 topic6 Action -425 63 admin commons
|
|
||||||
*
|
|
||||||
* Synapses
|
|
||||||
* Topic1 Topic2 Category Description User Permission
|
|
||||||
* 6 2 from-to admin commons
|
|
||||||
* 6 1 from-to admin commons
|
|
||||||
* 6 5 from-to admin commons
|
|
||||||
* 2 7 from-to admin commons
|
|
||||||
* 8 6 from-to admin commons
|
|
||||||
* 8 1 from-to admin commons
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
Metamaps.Import = {
|
|
||||||
// note that user is not imported
|
|
||||||
topicWhitelist: [
|
|
||||||
'id', 'name', 'metacode', 'x', 'y', 'description', 'link', 'permission'
|
|
||||||
],
|
|
||||||
synapseWhitelist: [
|
|
||||||
'topic1', 'topic2', 'category', 'desc', 'description', 'permission'
|
|
||||||
],
|
|
||||||
cidMappings: {}, //to be filled by import_id => cid mappings
|
|
||||||
|
|
||||||
init: function() {
|
|
||||||
var self = Metamaps.Import;
|
|
||||||
|
|
||||||
$('body').bind('paste', function(e) {
|
|
||||||
if (e.target.tagName === "INPUT") return;
|
|
||||||
|
|
||||||
var text = e.originalEvent.clipboardData.getData('text/plain');
|
|
||||||
|
|
||||||
var results;
|
|
||||||
if (text[0] === '{') {
|
|
||||||
try {
|
|
||||||
results = JSON.parse(text);
|
|
||||||
} catch (e) {
|
|
||||||
results = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
results = self.parseTabbedString(text);
|
|
||||||
}
|
|
||||||
if (results === false) return;
|
|
||||||
|
|
||||||
var topics = results.topics;
|
|
||||||
var synapses = results.synapses;
|
|
||||||
|
|
||||||
if (topics.length > 0 || synapses.length > 0) {
|
|
||||||
if (confirm("Are you sure you want to create " + topics.length +
|
|
||||||
" new topics and " + synapses.length + " new synapses?")) {
|
|
||||||
self.importTopics(topics);
|
|
||||||
self.importSynapses(synapses);
|
|
||||||
}//if
|
|
||||||
}//if
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
abort: function(message) {
|
|
||||||
console.error(message);
|
|
||||||
},
|
|
||||||
|
|
||||||
simplify: function(string) {
|
|
||||||
return string
|
|
||||||
.replace(/(^\s*|\s*$)/g, '')
|
|
||||||
.toLowerCase();
|
|
||||||
},
|
|
||||||
|
|
||||||
parseTabbedString: function(text) {
|
|
||||||
var self = Metamaps.Import;
|
|
||||||
|
|
||||||
// determine line ending and split lines
|
|
||||||
var delim = "\n";
|
|
||||||
if (text.indexOf("\r\n") !== -1) {
|
|
||||||
delim = "\r\n";
|
|
||||||
} else if (text.indexOf("\r") !== -1) {
|
|
||||||
delim = "\r";
|
|
||||||
}//if
|
|
||||||
|
|
||||||
var STATES = {
|
|
||||||
ABORT: -1,
|
|
||||||
UNKNOWN: 0,
|
|
||||||
TOPICS_NEED_HEADERS: 1,
|
|
||||||
SYNAPSES_NEED_HEADERS: 2,
|
|
||||||
TOPICS: 3,
|
|
||||||
SYNAPSES: 4,
|
|
||||||
};
|
|
||||||
|
|
||||||
// state & lines determine parser behaviour
|
|
||||||
var state = STATES.UNKNOWN;
|
|
||||||
var lines = text.split(delim);
|
|
||||||
var results = { topics: [], synapses: [] }
|
|
||||||
var topicHeaders = [];
|
|
||||||
var synapseHeaders = [];
|
|
||||||
|
|
||||||
lines.forEach(function(line_raw, index) {
|
|
||||||
var line = line_raw.split("\t");
|
|
||||||
var noblanks = line.filter(function(elt) {
|
|
||||||
return elt !== "";
|
|
||||||
});
|
|
||||||
switch(state) {
|
|
||||||
case STATES.UNKNOWN:
|
|
||||||
if (noblanks.length === 0) {
|
|
||||||
state = STATES.UNKNOWN;
|
|
||||||
break;
|
|
||||||
} else if (noblanks.length === 1 && self.simplify(line[0]) === 'topics') {
|
|
||||||
state = STATES.TOPICS_NEED_HEADERS;
|
|
||||||
break;
|
|
||||||
} else if (noblanks.length === 1 && self.simplify(line[0]) === 'synapses') {
|
|
||||||
state = STATES.SYNAPSES_NEED_HEADERS;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
state = STATES.TOPICS_NEED_HEADERS;
|
|
||||||
// FALL THROUGH - if we're not sure what to do, pretend
|
|
||||||
// we're on the TOPICS_NEED_HEADERS state and parse some headers
|
|
||||||
|
|
||||||
case STATES.TOPICS_NEED_HEADERS:
|
|
||||||
if (noblanks.length < 2) {
|
|
||||||
self.abort("Not enough topic headers on line " + index);
|
|
||||||
state = STATES.ABORT;
|
|
||||||
}
|
|
||||||
topicHeaders = line.map(function(header, index) {
|
|
||||||
return header.toLowerCase().replace('description', 'desc');
|
|
||||||
});
|
|
||||||
state = STATES.TOPICS;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case STATES.SYNAPSES_NEED_HEADERS:
|
|
||||||
if (noblanks.length < 2) {
|
|
||||||
self.abort("Not enough synapse headers on line " + index);
|
|
||||||
state = STATES.ABORT;
|
|
||||||
}
|
|
||||||
synapseHeaders = line.map(function(header, index) {
|
|
||||||
return header.toLowerCase().replace('description', 'desc');
|
|
||||||
});
|
|
||||||
state = STATES.SYNAPSES;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case STATES.TOPICS:
|
|
||||||
if (noblanks.length === 0) {
|
|
||||||
state = STATES.UNKNOWN;
|
|
||||||
} else if (noblanks.length === 1 && line[0].toLowerCase() === 'topics') {
|
|
||||||
state = STATES.TOPICS_NEED_HEADERS;
|
|
||||||
} else if (noblanks.length === 1 && line[0].toLowerCase() === 'synapses') {
|
|
||||||
state = STATES.SYNAPSES_NEED_HEADERS;
|
|
||||||
} else {
|
|
||||||
var topic = {};
|
|
||||||
line.forEach(function(field, index) {
|
|
||||||
var header = topicHeaders[index];
|
|
||||||
if (self.topicWhitelist.indexOf(header) === -1) return;
|
|
||||||
topic[header] = field;
|
|
||||||
if (['id', 'x', 'y'].indexOf(header) !== -1) {
|
|
||||||
topic[header] = parseInt(topic[header]);
|
|
||||||
}//if
|
|
||||||
});
|
|
||||||
results.topics.push(topic);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case STATES.SYNAPSES:
|
|
||||||
if (noblanks.length === 0) {
|
|
||||||
state = STATES.UNKNOWN;
|
|
||||||
} else if (noblanks.length === 1 && line[0].toLowerCase() === 'topics') {
|
|
||||||
state = STATES.TOPICS_NEED_HEADERS;
|
|
||||||
} else if (noblanks.length === 1 && line[0].toLowerCase() === 'synapses') {
|
|
||||||
state = STATES.SYNAPSES_NEED_HEADERS;
|
|
||||||
} else {
|
|
||||||
var synapse = {};
|
|
||||||
line.forEach(function(field, index) {
|
|
||||||
var header = synapseHeaders[index];
|
|
||||||
if (self.synapseWhitelist.indexOf(header) === -1) return;
|
|
||||||
synapse[header] = field;
|
|
||||||
if (['id', 'topic1', 'topic2'].indexOf(header) !== -1) {
|
|
||||||
synapse[header] = parseInt(synapse[header]);
|
|
||||||
}//if
|
|
||||||
});
|
|
||||||
results.synapses.push(synapse);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case STATES.ABORT:
|
|
||||||
;
|
|
||||||
default:
|
|
||||||
self.abort("Invalid state while parsing import data. Check code.");
|
|
||||||
state = STATES.ABORT;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (state === STATES.ABORT) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
importTopics: function(parsedTopics) {
|
|
||||||
var self = Metamaps.Import;
|
|
||||||
|
|
||||||
// up to 25 topics: scale 100
|
|
||||||
// up to 81 topics: scale 200
|
|
||||||
// up to 169 topics: scale 300
|
|
||||||
var scale = Math.floor((Math.sqrt(parsedTopics.length) - 1) / 4) * 100;
|
|
||||||
if (scale < 100) scale = 100;
|
|
||||||
var autoX = -scale;
|
|
||||||
var autoY = -scale;
|
|
||||||
|
|
||||||
parsedTopics.forEach(function(topic) {
|
|
||||||
var x, y;
|
|
||||||
if (topic.x && topic.y) {
|
|
||||||
x = topic.x;
|
|
||||||
y = topic.y;
|
|
||||||
} else {
|
|
||||||
x = autoX;
|
|
||||||
y = autoY;
|
|
||||||
autoX += 50;
|
|
||||||
if (autoX > scale) {
|
|
||||||
autoY += 50;
|
|
||||||
autoX = -scale;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.createTopicWithParameters(
|
|
||||||
topic.name, topic.metacode, topic.permission,
|
|
||||||
topic.desc, topic.link, x, y, topic.id
|
|
||||||
);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
importSynapses: function(parsedSynapses) {
|
|
||||||
var self = Metamaps.Import;
|
|
||||||
|
|
||||||
parsedSynapses.forEach(function(synapse) {
|
|
||||||
//only createSynapseWithParameters once both topics are persisted
|
|
||||||
var topic1 = Metamaps.Topics.get(self.cidMappings[synapse.topic1]);
|
|
||||||
var topic2 = Metamaps.Topics.get(self.cidMappings[synapse.topic2]);
|
|
||||||
if (!topic1 || !topic2) {
|
|
||||||
console.error("One of the two topics doesn't exist!")
|
|
||||||
console.error(synapse)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
var synapse_created = false
|
|
||||||
topic1.once('sync', function() {
|
|
||||||
if (topic1.id && topic2.id && !synapse_created) {
|
|
||||||
synapse_created = true
|
|
||||||
self.createSynapseWithParameters(
|
|
||||||
synapse.desc, synapse.category, synapse.permission,
|
|
||||||
topic1, topic2
|
|
||||||
);
|
|
||||||
}//if
|
|
||||||
});
|
|
||||||
topic2.once('sync', function() {
|
|
||||||
if (topic1.id && topic2.id && !synapse_created) {
|
|
||||||
synapse_created = true
|
|
||||||
self.createSynapseWithParameters(
|
|
||||||
synapse.desc, synapse.category, synapse.permission,
|
|
||||||
topic1, topic2
|
|
||||||
);
|
|
||||||
}//if
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
createTopicWithParameters: function(name, metacode_name, permission, desc,
|
|
||||||
link, xloc, yloc, import_id) {
|
|
||||||
var self = Metamaps.Import;
|
|
||||||
$(document).trigger(Metamaps.Map.events.editedByActiveMapper);
|
|
||||||
var metacode = Metamaps.Metacodes.where({name: metacode_name})[0] || null;
|
|
||||||
if (metacode === null) return console.error("metacode not found");
|
|
||||||
|
|
||||||
var topic = new Metamaps.Backbone.Topic({
|
|
||||||
name: name,
|
|
||||||
metacode_id: metacode.id,
|
|
||||||
permission: permission || Metamaps.Active.Map.get('permission'),
|
|
||||||
desc: desc,
|
|
||||||
link: link,
|
|
||||||
});
|
|
||||||
Metamaps.Topics.add(topic);
|
|
||||||
self.cidMappings[import_id] = topic.cid;
|
|
||||||
|
|
||||||
var mapping = new Metamaps.Backbone.Mapping({
|
|
||||||
xloc: xloc,
|
|
||||||
yloc: yloc,
|
|
||||||
mappable_id: topic.cid,
|
|
||||||
mappable_type: "Topic",
|
|
||||||
});
|
|
||||||
Metamaps.Mappings.add(mapping);
|
|
||||||
|
|
||||||
// this function also includes the creation of the topic in the database
|
|
||||||
Metamaps.Topic.renderTopic(mapping, topic, true, true);
|
|
||||||
|
|
||||||
|
|
||||||
Metamaps.Famous.viz.hideInstructions();
|
|
||||||
},
|
|
||||||
|
|
||||||
createSynapseWithParameters: function(description, category, permission,
|
|
||||||
topic1, topic2) {
|
|
||||||
var self = Metamaps.Import;
|
|
||||||
var node1 = topic1.get('node');
|
|
||||||
var node2 = topic2.get('node');
|
|
||||||
|
|
||||||
if (!topic1.id || !topic2.id) {
|
|
||||||
console.error("missing topic id when creating synapse")
|
|
||||||
return;
|
|
||||||
}//if
|
|
||||||
|
|
||||||
var synapse = new Metamaps.Backbone.Synapse({
|
|
||||||
desc: description,
|
|
||||||
category: category,
|
|
||||||
permission: permission,
|
|
||||||
node1_id: topic1.id,
|
|
||||||
node2_id: topic2.id
|
|
||||||
});
|
|
||||||
Metamaps.Synapses.add(synapse);
|
|
||||||
|
|
||||||
var mapping = new Metamaps.Backbone.Mapping({
|
|
||||||
mappable_type: "Synapse",
|
|
||||||
mappable_id: synapse.cid,
|
|
||||||
});
|
|
||||||
Metamaps.Mappings.add(mapping);
|
|
||||||
|
|
||||||
Metamaps.Synapse.renderSynapse(mapping, synapse, node1, node2, true);
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -1,262 +0,0 @@
|
||||||
(function () {
|
|
||||||
|
|
||||||
Metamaps.currentPage = "";
|
|
||||||
|
|
||||||
var Router = Backbone.Router.extend({
|
|
||||||
routes: {
|
|
||||||
"": "home", // #home
|
|
||||||
"explore/:section": "explore", // #explore/active
|
|
||||||
"explore/:section/:id": "explore", // #explore/mapper/1234
|
|
||||||
"maps/:id": "maps" // #maps/7
|
|
||||||
},
|
|
||||||
home: function () {
|
|
||||||
clearTimeout(Metamaps.routerTimeoutId);
|
|
||||||
|
|
||||||
if (Metamaps.Active.Mapper) document.title = 'Explore Active Maps | Metamaps';
|
|
||||||
else document.title = 'Home | Metamaps';
|
|
||||||
|
|
||||||
Metamaps.currentSection = "";
|
|
||||||
Metamaps.currentPage = "";
|
|
||||||
$('.wrapper').removeClass('mapPage topicPage');
|
|
||||||
|
|
||||||
var classes = Metamaps.Active.Mapper ? "homePage explorePage" : "homePage";
|
|
||||||
$('.wrapper').addClass(classes);
|
|
||||||
|
|
||||||
var navigate = function() {
|
|
||||||
Metamaps.routerTimeoutId = setTimeout(function() {
|
|
||||||
Metamaps.Router.navigate("");
|
|
||||||
}, 300);
|
|
||||||
};
|
|
||||||
// all this only for the logged in home page
|
|
||||||
if (Metamaps.Active.Mapper) {
|
|
||||||
|
|
||||||
Metamaps.Famous.yield.hide();
|
|
||||||
|
|
||||||
Metamaps.Famous.explore.set('active');
|
|
||||||
Metamaps.Famous.maps.resetScroll(); // sets the scroll back to the top
|
|
||||||
Metamaps.Famous.explore.show();
|
|
||||||
|
|
||||||
Metamaps.Famous.maps.show();
|
|
||||||
|
|
||||||
Metamaps.GlobalUI.Search.open();
|
|
||||||
Metamaps.GlobalUI.Search.lock();
|
|
||||||
|
|
||||||
Metamaps.Views.exploreMaps.setCollection( Metamaps.Maps.Active );
|
|
||||||
if (Metamaps.Maps.Active.length === 0) {
|
|
||||||
Metamaps.Maps.Active.getMaps(navigate); // this will trigger an explore maps render
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Metamaps.Views.exploreMaps.render(navigate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// logged out home page
|
|
||||||
else {
|
|
||||||
|
|
||||||
Metamaps.Famous.yield.show();
|
|
||||||
|
|
||||||
Metamaps.Famous.explore.hide();
|
|
||||||
|
|
||||||
Metamaps.GlobalUI.Search.unlock();
|
|
||||||
Metamaps.GlobalUI.Search.close(0, true);
|
|
||||||
|
|
||||||
Metamaps.Famous.maps.hide();
|
|
||||||
Metamaps.routerTimeoutId = setTimeout(navigate, 500);
|
|
||||||
}
|
|
||||||
|
|
||||||
Metamaps.Famous.viz.hide();
|
|
||||||
Metamaps.Map.end();
|
|
||||||
Metamaps.Topic.end();
|
|
||||||
Metamaps.Active.Map = null;
|
|
||||||
Metamaps.Active.Topic = null;
|
|
||||||
},
|
|
||||||
explore: function (section, id) {
|
|
||||||
clearTimeout(Metamaps.routerTimeoutId);
|
|
||||||
|
|
||||||
// just capitalize the variable section
|
|
||||||
// either 'featured', 'mapper', or 'active'
|
|
||||||
var capitalize = section.charAt(0).toUpperCase() + section.slice(1);
|
|
||||||
|
|
||||||
if (section === "featured" || section === "active") {
|
|
||||||
document.title = 'Explore ' + capitalize + ' Maps | Metamaps';
|
|
||||||
}
|
|
||||||
else if (section === "mapper") {
|
|
||||||
$.ajax({
|
|
||||||
url: "/users/" + id + ".json",
|
|
||||||
success: function (response) {
|
|
||||||
document.title = response.name + ' | Metamaps';
|
|
||||||
},
|
|
||||||
error: function () {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else if (section === "mine") {
|
|
||||||
document.title = 'Explore My Maps | Metamaps';
|
|
||||||
}
|
|
||||||
|
|
||||||
$('.wrapper').removeClass('homePage mapPage topicPage');
|
|
||||||
$('.wrapper').addClass('explorePage');
|
|
||||||
|
|
||||||
Metamaps.currentSection = "explore";
|
|
||||||
Metamaps.currentPage = section;
|
|
||||||
|
|
||||||
// this will mean it's a mapper page being loaded
|
|
||||||
if (id) {
|
|
||||||
if (Metamaps.Maps.Mapper.mapperId !== id) {
|
|
||||||
// empty the collection if we are trying to load the maps
|
|
||||||
// collection of a different mapper than we had previously
|
|
||||||
Metamaps.Maps.Mapper.reset();
|
|
||||||
Metamaps.Maps.Mapper.page = 1;
|
|
||||||
}
|
|
||||||
Metamaps.Maps.Mapper.mapperId = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
Metamaps.Views.exploreMaps.setCollection( Metamaps.Maps[capitalize] );
|
|
||||||
|
|
||||||
var navigate = function(){
|
|
||||||
var path = "/explore/" + Metamaps.currentPage;
|
|
||||||
|
|
||||||
// alter url if for mapper profile page
|
|
||||||
if (Metamaps.currentPage == "mapper") {
|
|
||||||
path += "/" + Metamaps.Maps.Mapper.mapperId;
|
|
||||||
}
|
|
||||||
|
|
||||||
Metamaps.Router.navigate(path);
|
|
||||||
};
|
|
||||||
var navigateTimeout = function() {
|
|
||||||
Metamaps.routerTimeoutId = setTimeout(navigate, 300);
|
|
||||||
};
|
|
||||||
if (Metamaps.Maps[capitalize].length === 0) {
|
|
||||||
Metamaps.Loading.show();
|
|
||||||
setTimeout(function(){
|
|
||||||
Metamaps.Maps[capitalize].getMaps(navigate); // this will trigger an explore maps render
|
|
||||||
}, 300); // wait 300 milliseconds till the other animations are done to do the fetch
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (id) {
|
|
||||||
Metamaps.Views.exploreMaps.fetchUserThenRender(navigateTimeout);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Metamaps.Views.exploreMaps.render(navigateTimeout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Metamaps.GlobalUI.Search.open();
|
|
||||||
Metamaps.GlobalUI.Search.lock();
|
|
||||||
|
|
||||||
Metamaps.Famous.yield.hide();
|
|
||||||
|
|
||||||
Metamaps.Famous.maps.resetScroll(); // sets the scroll back to the top
|
|
||||||
Metamaps.Famous.maps.show();
|
|
||||||
Metamaps.Famous.explore.set(section, id);
|
|
||||||
Metamaps.Famous.explore.show();
|
|
||||||
|
|
||||||
Metamaps.Famous.viz.hide();
|
|
||||||
Metamaps.Map.end();
|
|
||||||
Metamaps.Topic.end();
|
|
||||||
Metamaps.Active.Map = null;
|
|
||||||
Metamaps.Active.Topic = null;
|
|
||||||
},
|
|
||||||
maps: function (id) {
|
|
||||||
clearTimeout(Metamaps.routerTimeoutId);
|
|
||||||
|
|
||||||
document.title = 'Map ' + id + ' | Metamaps';
|
|
||||||
|
|
||||||
Metamaps.currentSection = "map";
|
|
||||||
Metamaps.currentPage = id;
|
|
||||||
|
|
||||||
$('.wrapper').removeClass('homePage explorePage topicPage');
|
|
||||||
$('.wrapper').addClass('mapPage');
|
|
||||||
// another class will be added to wrapper if you
|
|
||||||
// can edit this map '.canEditMap'
|
|
||||||
|
|
||||||
Metamaps.Famous.yield.hide();
|
|
||||||
Metamaps.Famous.maps.hide();
|
|
||||||
Metamaps.Famous.explore.hide();
|
|
||||||
|
|
||||||
// clear the visualization, if there was one, before showing its div again
|
|
||||||
if (Metamaps.Visualize.mGraph) {
|
|
||||||
Metamaps.Visualize.mGraph.graph.empty();
|
|
||||||
Metamaps.Visualize.mGraph.plot();
|
|
||||||
Metamaps.JIT.centerMap(Metamaps.Visualize.mGraph.canvas);
|
|
||||||
}
|
|
||||||
Metamaps.Famous.viz.show();
|
|
||||||
Metamaps.Topic.end();
|
|
||||||
Metamaps.Active.Topic = null;
|
|
||||||
|
|
||||||
Metamaps.GlobalUI.Search.unlock();
|
|
||||||
Metamaps.GlobalUI.Search.close(0, true);
|
|
||||||
|
|
||||||
Metamaps.Loading.show();
|
|
||||||
Metamaps.Map.end();
|
|
||||||
Metamaps.Map.launch(id);
|
|
||||||
},
|
|
||||||
topics: function (id) {
|
|
||||||
clearTimeout(Metamaps.routerTimeoutId);
|
|
||||||
|
|
||||||
document.title = 'Topic ' + id + ' | Metamaps';
|
|
||||||
|
|
||||||
Metamaps.currentSection = "topic";
|
|
||||||
Metamaps.currentPage = id;
|
|
||||||
|
|
||||||
$('.wrapper').removeClass('homePage explorePage mapPage');
|
|
||||||
$('.wrapper').addClass('topicPage');
|
|
||||||
|
|
||||||
Metamaps.Famous.yield.hide();
|
|
||||||
Metamaps.Famous.maps.hide();
|
|
||||||
Metamaps.Famous.explore.hide();
|
|
||||||
|
|
||||||
// clear the visualization, if there was one, before showing its div again
|
|
||||||
if (Metamaps.Visualize.mGraph) {
|
|
||||||
Metamaps.Visualize.mGraph.graph.empty();
|
|
||||||
Metamaps.Visualize.mGraph.plot();
|
|
||||||
Metamaps.JIT.centerMap(Metamaps.Visualize.mGraph.canvas);
|
|
||||||
}
|
|
||||||
Metamaps.Famous.viz.show();
|
|
||||||
Metamaps.Map.end();
|
|
||||||
Metamaps.Active.Map = null;
|
|
||||||
|
|
||||||
Metamaps.GlobalUI.Search.unlock();
|
|
||||||
Metamaps.GlobalUI.Search.close(0, true);
|
|
||||||
|
|
||||||
Metamaps.Topic.end();
|
|
||||||
Metamaps.Topic.launch(id);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Metamaps.Router = new Router();
|
|
||||||
|
|
||||||
|
|
||||||
Metamaps.Router.intercept = function (evt) {
|
|
||||||
var segments;
|
|
||||||
|
|
||||||
var href = {
|
|
||||||
prop: $(this).prop("href"),
|
|
||||||
attr: $(this).attr("href")
|
|
||||||
};
|
|
||||||
var root = location.protocol + "//" + location.host + Backbone.history.options.root;
|
|
||||||
|
|
||||||
if (href.prop && href.prop === root) href.attr = "";
|
|
||||||
|
|
||||||
if (href.prop && href.prop.slice(0, root.length) === root) {
|
|
||||||
evt.preventDefault();
|
|
||||||
|
|
||||||
segments = href.attr.split('/');
|
|
||||||
segments.splice(0,1); // pop off the element created by the first /
|
|
||||||
|
|
||||||
if (href.attr === "") Metamaps.Router.home();
|
|
||||||
else {
|
|
||||||
Metamaps.Router[segments[0]](segments[1], segments[2]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Metamaps.Router.init = function () {
|
|
||||||
Backbone.history.start({
|
|
||||||
silent: true,
|
|
||||||
pushState: true,
|
|
||||||
root: '/'
|
|
||||||
});
|
|
||||||
$(document).on("click", "a:not([data-bypass])", Metamaps.Router.intercept);
|
|
||||||
};
|
|
||||||
})();
|
|
|
@ -1,133 +0,0 @@
|
||||||
(function () {
|
|
||||||
Metamaps.Views = {};
|
|
||||||
|
|
||||||
var initialized = false;
|
|
||||||
|
|
||||||
Metamaps.Views.init = function () {
|
|
||||||
|
|
||||||
Metamaps.Views.MapperCard = Backbone.View.extend({
|
|
||||||
|
|
||||||
template: Hogan.compile( $('#mapperCardTemplate').html() ),
|
|
||||||
|
|
||||||
tagNamea: "div",
|
|
||||||
|
|
||||||
className: "mapper",
|
|
||||||
|
|
||||||
render: function () {
|
|
||||||
this.$el.html( this.template.render(this.model) );
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Metamaps.Views.MapCard = Backbone.View.extend({
|
|
||||||
|
|
||||||
template: Hogan.compile( $('#mapCardTemplate').html() ),
|
|
||||||
|
|
||||||
tagName: "div",
|
|
||||||
|
|
||||||
className: "map",
|
|
||||||
|
|
||||||
id: function() {
|
|
||||||
return this.model.id;
|
|
||||||
},
|
|
||||||
|
|
||||||
initialize: function () {
|
|
||||||
this.listenTo(this.model, "change", this.render);
|
|
||||||
},
|
|
||||||
|
|
||||||
render: function () {
|
|
||||||
this.$el.html( this.template.render(this.model.attrForCards()) );
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
var mapsWrapper = Backbone.View.extend({
|
|
||||||
|
|
||||||
initialize: function (opts) {
|
|
||||||
|
|
||||||
},
|
|
||||||
setCollection: function (collection) {
|
|
||||||
if (this.collection) this.stopListening(this.collection);
|
|
||||||
this.collection = collection;
|
|
||||||
this.listenTo(this.collection, 'add', this.render);
|
|
||||||
this.listenTo(this.collection, 'successOnFetch', this.handleSuccess);
|
|
||||||
this.listenTo(this.collection, 'errorOnFetch', this.handleError);
|
|
||||||
},
|
|
||||||
render: function (mapperObj, cb) {
|
|
||||||
|
|
||||||
var that = this;
|
|
||||||
|
|
||||||
if (typeof mapperObj === "function") {
|
|
||||||
var cb = mapperObj;
|
|
||||||
mapperObj = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.el.innerHTML = "";
|
|
||||||
|
|
||||||
// in case it is a page where we have to display the mapper card
|
|
||||||
if (mapperObj) {
|
|
||||||
var view = new Metamaps.Views.MapperCard({ model: mapperObj });
|
|
||||||
|
|
||||||
that.el.appendChild( view.render().el );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
this.collection.each(function (map) {
|
|
||||||
var view = new Metamaps.Views.MapCard({ model: map });
|
|
||||||
|
|
||||||
that.el.appendChild( view.render().el );
|
|
||||||
});
|
|
||||||
this.$el.append('<div class="clearfloat"></div>');
|
|
||||||
var m = Metamaps.Famous.maps.surf;
|
|
||||||
m.setContent(this.el);
|
|
||||||
|
|
||||||
var updateHeight = function(){
|
|
||||||
var height = $(that.el).height() + 32 + 56;
|
|
||||||
m.setSize([undefined, height]);
|
|
||||||
Metamaps.Famous.maps.lock = false;
|
|
||||||
if (cb) cb();
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!initialized) {
|
|
||||||
m.deploy(m._currTarget);
|
|
||||||
initialized = true;
|
|
||||||
setTimeout(updateHeight, 100);
|
|
||||||
} else {
|
|
||||||
setTimeout(updateHeight, 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
Metamaps.Loading.hide();
|
|
||||||
},
|
|
||||||
handleSuccess: function (cb) {
|
|
||||||
var that = this;
|
|
||||||
|
|
||||||
if (this.collection && this.collection.id === "mapper") {
|
|
||||||
this.fetchUserThenRender(cb);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.render(cb);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
handleError: function () {
|
|
||||||
console.log('error loading maps!'); //TODO
|
|
||||||
},
|
|
||||||
fetchUserThenRender: function (cb) {
|
|
||||||
var that = this;
|
|
||||||
// first load the mapper object and then call the render function
|
|
||||||
$.ajax({
|
|
||||||
url: "/users/" + this.collection.mapperId + "/details.json",
|
|
||||||
success: function (response) {
|
|
||||||
that.render(response, cb);
|
|
||||||
},
|
|
||||||
error: function () {
|
|
||||||
that.render(cb);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Metamaps.Views.exploreMaps = new mapsWrapper();
|
|
||||||
};
|
|
||||||
|
|
||||||
})();
|
|
|
@ -1,339 +0,0 @@
|
||||||
Metamaps.Views = Metamaps.Views || {};
|
|
||||||
|
|
||||||
Metamaps.Views.chatView = (function () {
|
|
||||||
var
|
|
||||||
chatView,
|
|
||||||
linker = new Autolinker({ newWindow: true, truncate: 50, email: false, phone: false, twitter: false });
|
|
||||||
|
|
||||||
var Private = {
|
|
||||||
messageHTML: "<div class='chat-message'>" +
|
|
||||||
"<div class='chat-message-user'><img src='{{ user_image }}' title='{{user_name }}'/></div>" +
|
|
||||||
"<div class='chat-message-text'>{{ message }}</div>" +
|
|
||||||
"<div class='chat-message-time'>{{ timestamp }}</div>" +
|
|
||||||
"<div class='clearfloat'></div>" +
|
|
||||||
"</div>",
|
|
||||||
participantHTML: "<div class='participant participant-{{ id }} {{ selfClass }}'>" +
|
|
||||||
"<div class='chat-participant-image'><img src='{{ image }}' style='border: 2px solid {{ color }};' /></div>" +
|
|
||||||
"<div class='chat-participant-name'>{{ username }} {{ selfName }}</div>" +
|
|
||||||
"<button type='button' class='button chat-participant-invite-call' onclick='Metamaps.Realtime.inviteACall({{ id}});'></button>" +
|
|
||||||
"<button type='button' class='button chat-participant-invite-join' onclick='Metamaps.Realtime.inviteToJoin({{ id}});'></button>" +
|
|
||||||
"<span class='chat-participant-participating'><div class='green-dot'></div></span>" +
|
|
||||||
"<div class='clearfloat'></div>" +
|
|
||||||
"</div>",
|
|
||||||
templates: function() {
|
|
||||||
_.templateSettings = {
|
|
||||||
interpolate: /\{\{(.+?)\}\}/g
|
|
||||||
};
|
|
||||||
this.messageTemplate = _.template(Private.messageHTML);
|
|
||||||
|
|
||||||
this.participantTemplate = _.template(Private.participantHTML);
|
|
||||||
},
|
|
||||||
createElements: function() {
|
|
||||||
this.$unread = $('<div class="chat-unread"></div>');
|
|
||||||
this.$button = $('<div class="chat-button"><div class="tooltips">Chat</div></div>');
|
|
||||||
this.$messageInput = $('<textarea placeholder="Send a message..." class="chat-input"></textarea>');
|
|
||||||
this.$juntoHeader = $('<div class="junto-header">PARTICIPANTS</div>');
|
|
||||||
this.$videoToggle = $('<div class="video-toggle"></div>');
|
|
||||||
this.$cursorToggle = $('<div class="cursor-toggle"></div>');
|
|
||||||
this.$participants = $('<div class="participants"></div>');
|
|
||||||
this.$conversationInProgress = $('<div class="conversation-live">LIVE <span class="call-action leave" onclick="Metamaps.Realtime.leaveCall();">LEAVE</span><span class="call-action join" onclick="Metamaps.Realtime.joinCall();">JOIN</span></div>');
|
|
||||||
this.$chatHeader = $('<div class="chat-header">CHAT</div>');
|
|
||||||
this.$soundToggle = $('<div class="sound-toggle active"></div>');
|
|
||||||
this.$messages = $('<div class="chat-messages"></div>');
|
|
||||||
this.$container = $('<div class="chat-box"></div>');
|
|
||||||
},
|
|
||||||
attachElements: function() {
|
|
||||||
this.$button.append(this.$unread);
|
|
||||||
|
|
||||||
this.$juntoHeader.append(this.$videoToggle);
|
|
||||||
this.$juntoHeader.append(this.$cursorToggle);
|
|
||||||
|
|
||||||
this.$chatHeader.append(this.$soundToggle);
|
|
||||||
|
|
||||||
this.$participants.append(this.$conversationInProgress);
|
|
||||||
|
|
||||||
this.$container.append(this.$juntoHeader);
|
|
||||||
this.$container.append(this.$participants);
|
|
||||||
this.$container.append(this.$chatHeader);
|
|
||||||
this.$container.append(this.$button);
|
|
||||||
this.$container.append(this.$messages);
|
|
||||||
this.$container.append(this.$messageInput);
|
|
||||||
},
|
|
||||||
addEventListeners: function() {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
this.participants.on('add', function (participant) {
|
|
||||||
Private.addParticipant.call(self, participant);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.participants.on('remove', function (participant) {
|
|
||||||
Private.removeParticipant.call(self, participant);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.$button.on('click', function () {
|
|
||||||
Handlers.buttonClick.call(self);
|
|
||||||
});
|
|
||||||
this.$videoToggle.on('click', function () {
|
|
||||||
Handlers.videoToggleClick.call(self);
|
|
||||||
});
|
|
||||||
this.$cursorToggle.on('click', function () {
|
|
||||||
Handlers.cursorToggleClick.call(self);
|
|
||||||
});
|
|
||||||
this.$soundToggle.on('click', function () {
|
|
||||||
Handlers.soundToggleClick.call(self);
|
|
||||||
});
|
|
||||||
this.$messageInput.on('keyup', function (event) {
|
|
||||||
Handlers.keyUp.call(self, event);
|
|
||||||
});
|
|
||||||
this.$messageInput.on('focus', function () {
|
|
||||||
Handlers.inputFocus.call(self);
|
|
||||||
});
|
|
||||||
this.$messageInput.on('blur', function () {
|
|
||||||
Handlers.inputBlur.call(self);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
initializeSounds: function() {
|
|
||||||
this.sound = new Howl({
|
|
||||||
urls: ["<%= asset_path 'sounds/sounds.mp3' %>", "<%= asset_path 'sounds/sounds.ogg' %>"],
|
|
||||||
sprite: {
|
|
||||||
laser: [3000, 700]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
incrementUnread: function() {
|
|
||||||
this.unreadMessages++;
|
|
||||||
this.$unread.html(this.unreadMessages);
|
|
||||||
this.$unread.show();
|
|
||||||
},
|
|
||||||
addMessage: function(message, isInitial) {
|
|
||||||
|
|
||||||
if (!this.isOpen && !isInitial) Private.incrementUnread.call(this);
|
|
||||||
|
|
||||||
function addZero(i) {
|
|
||||||
if (i < 10) {
|
|
||||||
i = "0" + i;
|
|
||||||
}
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
var m = _.clone(message.attributes);
|
|
||||||
|
|
||||||
var today = new Date();
|
|
||||||
m.timestamp = new Date(m.created_at);
|
|
||||||
|
|
||||||
var date = (m.timestamp.getMonth() + 1) + '/' + m.timestamp.getDate();
|
|
||||||
date += " " + addZero(m.timestamp.getHours()) + ":" + addZero(m.timestamp.getMinutes());
|
|
||||||
m.timestamp = date;
|
|
||||||
m.image = m.user_image || 'http://www.hotpepper.ca/wp-content/uploads/2014/11/default_profile_1_200x200.png'; // TODO: remove
|
|
||||||
m.message = linker.link(m.message);
|
|
||||||
var $html = $(this.messageTemplate(m));
|
|
||||||
this.$messages.append($html);
|
|
||||||
if (!isInitial) this.scrollMessages(200);
|
|
||||||
|
|
||||||
if (!isInitial && this.alertSound) this.sound.play('laser');
|
|
||||||
},
|
|
||||||
initialMessages: function() {
|
|
||||||
var messages = this.messages.models;
|
|
||||||
for (var i = 0; i < messages.length; i++) {
|
|
||||||
Private.addMessage.call(this, messages[i], true);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
handleInputMessage: function() {
|
|
||||||
var message = {
|
|
||||||
message: this.$messageInput.val(),
|
|
||||||
};
|
|
||||||
this.$messageInput.val('');
|
|
||||||
$(document).trigger(chatView.events.message + '-' + this.room, [message]);
|
|
||||||
},
|
|
||||||
addParticipant: function(participant) {
|
|
||||||
var p = _.clone(participant.attributes);
|
|
||||||
if (p.self) {
|
|
||||||
p.selfClass = 'is-self';
|
|
||||||
p.selfName = '(me)';
|
|
||||||
} else {
|
|
||||||
p.selfClass = '';
|
|
||||||
p.selfName = '';
|
|
||||||
}
|
|
||||||
var html = this.participantTemplate(p);
|
|
||||||
this.$participants.append(html);
|
|
||||||
},
|
|
||||||
removeParticipant: function(participant) {
|
|
||||||
this.$container.find('.participant-' + participant.get('id')).remove();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var Handlers = {
|
|
||||||
buttonClick: function() {
|
|
||||||
if (this.isOpen) this.close();
|
|
||||||
else if (!this.isOpen) this.open();
|
|
||||||
},
|
|
||||||
videoToggleClick: function() {
|
|
||||||
this.$videoToggle.toggleClass('active');
|
|
||||||
this.videosShowing = !this.videosShowing;
|
|
||||||
$(document).trigger(this.videosShowing ? chatView.events.videosOn : chatView.events.videosOff);
|
|
||||||
},
|
|
||||||
cursorToggleClick: function() {
|
|
||||||
this.$cursorToggle.toggleClass('active');
|
|
||||||
this.cursorsShowing = !this.cursorsShowing;
|
|
||||||
$(document).trigger(this.cursorsShowing ? chatView.events.cursorsOn : chatView.events.cursorsOff);
|
|
||||||
},
|
|
||||||
soundToggleClick: function() {
|
|
||||||
this.alertSound = !this.alertSound;
|
|
||||||
this.$soundToggle.toggleClass('active');
|
|
||||||
},
|
|
||||||
keyUp: function(event) {
|
|
||||||
switch(event.which) {
|
|
||||||
case 13: // enter
|
|
||||||
Private.handleInputMessage.call(this);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
inputFocus: function() {
|
|
||||||
$(document).trigger(chatView.events.inputFocus);
|
|
||||||
},
|
|
||||||
inputBlur: function() {
|
|
||||||
$(document).trigger(chatView.events.inputBlur);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
chatView = function(messages, mapper, room) {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
this.room = room;
|
|
||||||
this.mapper = mapper;
|
|
||||||
this.messages = messages; // backbone collection
|
|
||||||
|
|
||||||
this.isOpen = false;
|
|
||||||
this.alertSound = false; // whether to play sounds on arrival of new messages or not
|
|
||||||
this.cursorsShowing = true;
|
|
||||||
this.videosShowing = true;
|
|
||||||
this.unreadMessages = 0;
|
|
||||||
this.participants = new Backbone.Collection();
|
|
||||||
|
|
||||||
Private.templates.call(this);
|
|
||||||
Private.createElements.call(this);
|
|
||||||
Private.attachElements.call(this);
|
|
||||||
Private.addEventListeners.call(this);
|
|
||||||
Private.initialMessages.call(this);
|
|
||||||
Private.initializeSounds.call(this);
|
|
||||||
this.$container.css({
|
|
||||||
right: '-300px'
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
chatView.prototype.conversationInProgress = function (participating) {
|
|
||||||
this.$conversationInProgress.show();
|
|
||||||
this.$participants.addClass('is-live');
|
|
||||||
if (participating) this.$participants.addClass('is-participating');
|
|
||||||
this.$button.addClass('active');
|
|
||||||
|
|
||||||
// hide invite to call buttons
|
|
||||||
}
|
|
||||||
|
|
||||||
chatView.prototype.conversationEnded = function () {
|
|
||||||
this.$conversationInProgress.hide();
|
|
||||||
this.$participants.removeClass('is-live');
|
|
||||||
this.$participants.removeClass('is-participating');
|
|
||||||
this.$button.removeClass('active');
|
|
||||||
this.$participants.find('.participant').removeClass('active');
|
|
||||||
this.$participants.find('.participant').removeClass('pending');
|
|
||||||
}
|
|
||||||
|
|
||||||
chatView.prototype.leaveConversation = function () {
|
|
||||||
this.$participants.removeClass('is-participating');
|
|
||||||
}
|
|
||||||
|
|
||||||
chatView.prototype.mapperJoinedCall = function (id) {
|
|
||||||
this.$participants.find('.participant-' + id).addClass('active');
|
|
||||||
}
|
|
||||||
|
|
||||||
chatView.prototype.mapperLeftCall = function (id) {
|
|
||||||
this.$participants.find('.participant-' + id).removeClass('active');
|
|
||||||
}
|
|
||||||
|
|
||||||
chatView.prototype.invitationPending = function (id) {
|
|
||||||
this.$participants.find('.participant-' + id).addClass('pending');
|
|
||||||
}
|
|
||||||
|
|
||||||
chatView.prototype.invitationAnswered = function (id) {
|
|
||||||
this.$participants.find('.participant-' + id).removeClass('pending');
|
|
||||||
}
|
|
||||||
|
|
||||||
chatView.prototype.addParticipant = function (participant) {
|
|
||||||
this.participants.add(participant);
|
|
||||||
}
|
|
||||||
|
|
||||||
chatView.prototype.removeParticipant = function (username) {
|
|
||||||
var p = this.participants.find(function (p) { return p.get('username') === username; });
|
|
||||||
if (p) {
|
|
||||||
this.participants.remove(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
chatView.prototype.removeParticipants = function () {
|
|
||||||
this.participants.remove(this.participants.models);
|
|
||||||
}
|
|
||||||
|
|
||||||
chatView.prototype.open = function () {
|
|
||||||
this.$container.css({
|
|
||||||
right: '0'
|
|
||||||
});
|
|
||||||
this.$messageInput.focus();
|
|
||||||
this.isOpen = true;
|
|
||||||
this.unreadMessages = 0;
|
|
||||||
this.$unread.hide();
|
|
||||||
this.scrollMessages(0);
|
|
||||||
$(document).trigger(chatView.events.openTray);
|
|
||||||
}
|
|
||||||
|
|
||||||
chatView.prototype.addMessage = function(message, isInitial) {
|
|
||||||
this.messages.add(message);
|
|
||||||
Private.addMessage.call(this, message, isInitial);
|
|
||||||
}
|
|
||||||
|
|
||||||
chatView.prototype.scrollMessages = function(duration) {
|
|
||||||
duration = duration || 0;
|
|
||||||
|
|
||||||
this.$messages.animate({
|
|
||||||
scrollTop: this.$messages[0].scrollHeight
|
|
||||||
}, duration);
|
|
||||||
}
|
|
||||||
|
|
||||||
chatView.prototype.clearMessages = function () {
|
|
||||||
this.unreadMessages = 0;
|
|
||||||
this.$unread.hide();
|
|
||||||
this.$messages.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
chatView.prototype.close = function () {
|
|
||||||
this.$container.css({
|
|
||||||
right: '-300px'
|
|
||||||
});
|
|
||||||
this.$messageInput.blur();
|
|
||||||
this.isOpen = false;
|
|
||||||
$(document).trigger(chatView.events.closeTray);
|
|
||||||
}
|
|
||||||
|
|
||||||
chatView.prototype.remove = function () {
|
|
||||||
this.$button.off();
|
|
||||||
this.$container.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @class
|
|
||||||
* @static
|
|
||||||
*/
|
|
||||||
chatView.events = {
|
|
||||||
message: 'ChatView:message',
|
|
||||||
openTray: 'ChatView:openTray',
|
|
||||||
closeTray: 'ChatView:closeTray',
|
|
||||||
inputFocus: 'ChatView:inputFocus',
|
|
||||||
inputBlur: 'ChatView:inputBlur',
|
|
||||||
cursorsOff: 'ChatView:cursorsOff',
|
|
||||||
cursorsOn: 'ChatView:cursorsOn',
|
|
||||||
videosOff: 'ChatView:videosOff',
|
|
||||||
videosOn: 'ChatView:videosOn'
|
|
||||||
};
|
|
||||||
|
|
||||||
return chatView;
|
|
||||||
|
|
||||||
})();
|
|
|
@ -1,194 +0,0 @@
|
||||||
Metamaps.Views = Metamaps.Views || {};
|
|
||||||
|
|
||||||
Metamaps.Views.room = (function () {
|
|
||||||
|
|
||||||
var ChatView = Metamaps.Views.chatView;
|
|
||||||
var VideoView = Metamaps.Views.videoView;
|
|
||||||
|
|
||||||
var room = function(opts) {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
this.isActiveRoom = false;
|
|
||||||
this.socket = opts.socket;
|
|
||||||
this.webrtc = opts.webrtc;
|
|
||||||
//this.roomRef = opts.firebase;
|
|
||||||
this.room = opts.room;
|
|
||||||
this.config = opts.config;
|
|
||||||
this.peopleCount = 0;
|
|
||||||
|
|
||||||
this.$myVideo = opts.$video;
|
|
||||||
this.myVideo = opts.myVideoView;
|
|
||||||
|
|
||||||
this.messages = new Backbone.Collection();
|
|
||||||
this.currentMapper = new Backbone.Model({ name: opts.username, image: opts.image });
|
|
||||||
this.chat = new ChatView(this.messages, this.currentMapper, this.room);
|
|
||||||
|
|
||||||
this.videos = {};
|
|
||||||
|
|
||||||
this.init();
|
|
||||||
};
|
|
||||||
|
|
||||||
room.prototype.join = function(cb) {
|
|
||||||
this.isActiveRoom = true;
|
|
||||||
this.webrtc.joinRoom(this.room, cb);
|
|
||||||
this.chat.conversationInProgress(true); // true indicates participation
|
|
||||||
}
|
|
||||||
|
|
||||||
room.prototype.conversationInProgress = function() {
|
|
||||||
this.chat.conversationInProgress(false); // false indicates not participating
|
|
||||||
}
|
|
||||||
|
|
||||||
room.prototype.conversationEnding = function() {
|
|
||||||
this.chat.conversationEnded();
|
|
||||||
}
|
|
||||||
|
|
||||||
room.prototype.leaveVideoOnly = function() {
|
|
||||||
this.chat.leaveConversation(); // the conversation will carry on without you
|
|
||||||
for (var id in this.videos) {
|
|
||||||
this.removeVideo(id);
|
|
||||||
}
|
|
||||||
this.isActiveRoom = false;
|
|
||||||
this.webrtc.leaveRoom();
|
|
||||||
}
|
|
||||||
|
|
||||||
room.prototype.leave = function() {
|
|
||||||
for (var id in this.videos) {
|
|
||||||
this.removeVideo(id);
|
|
||||||
}
|
|
||||||
this.isActiveRoom = false;
|
|
||||||
this.webrtc.leaveRoom();
|
|
||||||
this.chat.conversationEnded();
|
|
||||||
this.chat.removeParticipants();
|
|
||||||
this.chat.clearMessages();
|
|
||||||
this.messages.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
room.prototype.setPeopleCount = function(count) {
|
|
||||||
this.peopleCount = count;
|
|
||||||
}
|
|
||||||
|
|
||||||
room.prototype.init = function () {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
$(document).on(VideoView.events.audioControlClick, function (event, videoView) {
|
|
||||||
if (!videoView.audioStatus) self.webrtc.mute();
|
|
||||||
else if (videoView.audioStatus) self.webrtc.unmute();
|
|
||||||
});
|
|
||||||
$(document).on(VideoView.events.videoControlClick, function (event, videoView) {
|
|
||||||
if (!videoView.videoStatus) self.webrtc.pauseVideo();
|
|
||||||
else if (videoView.videoStatus) self.webrtc.resumeVideo();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.webrtc.webrtc.off('peerStreamAdded');
|
|
||||||
this.webrtc.webrtc.off('peerStreamRemoved');
|
|
||||||
this.webrtc.on('peerStreamAdded', function (peer) {
|
|
||||||
var mapper = Metamaps.Realtime.mappersOnMap[peer.nick];
|
|
||||||
peer.avatar = mapper.image;
|
|
||||||
peer.username = mapper.name;
|
|
||||||
if (self.isActiveRoom) {
|
|
||||||
self.addVideo(peer);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.webrtc.on('peerStreamRemoved', function (peer) {
|
|
||||||
if (self.isActiveRoom) {
|
|
||||||
self.removeVideo(peer);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.webrtc.on('mute', function (data) {
|
|
||||||
var v = self.videos[data.id];
|
|
||||||
if (!v) return;
|
|
||||||
|
|
||||||
if (data.name === 'audio') {
|
|
||||||
v.audioStatus = false;
|
|
||||||
}
|
|
||||||
else if (data.name === 'video') {
|
|
||||||
v.videoStatus = false;
|
|
||||||
v.$avatar.show();
|
|
||||||
}
|
|
||||||
if (!v.audioStatus && !v.videoStatus) v.$container.hide();
|
|
||||||
});
|
|
||||||
this.webrtc.on('unmute', function (data) {
|
|
||||||
var v = self.videos[data.id];
|
|
||||||
if (!v) return;
|
|
||||||
|
|
||||||
if (data.name === 'audio') {
|
|
||||||
v.audioStatus = true;
|
|
||||||
}
|
|
||||||
else if (data.name === 'video') {
|
|
||||||
v.videoStatus = true;
|
|
||||||
v.$avatar.hide();
|
|
||||||
}
|
|
||||||
v.$container.show();
|
|
||||||
});
|
|
||||||
|
|
||||||
var sendChatMessage = function (event, data) {
|
|
||||||
self.sendChatMessage(data);
|
|
||||||
};
|
|
||||||
$(document).on(ChatView.events.message + '-' + this.room, sendChatMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
room.prototype.videoAdded = function (callback) {
|
|
||||||
this._videoAdded = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
room.prototype.addVideo = function (peer) {
|
|
||||||
var
|
|
||||||
id = this.webrtc.getDomId(peer),
|
|
||||||
video = attachMediaStream(peer.stream);
|
|
||||||
|
|
||||||
var
|
|
||||||
v = new VideoView(video, null, id, false, { DOUBLE_CLICK_TOLERANCE: 200, avatar: peer.avatar, username: peer.username });
|
|
||||||
|
|
||||||
this.videos[peer.id] = v;
|
|
||||||
if (this._videoAdded) this._videoAdded(v, peer.nick);
|
|
||||||
}
|
|
||||||
|
|
||||||
room.prototype.removeVideo = function (peer) {
|
|
||||||
var id = typeof peer == 'string' ? peer : peer.id;
|
|
||||||
if (this.videos[id]) {
|
|
||||||
this.videos[id].remove();
|
|
||||||
delete this.videos[id];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
room.prototype.sendChatMessage = function (data) {
|
|
||||||
var self = this;
|
|
||||||
//this.roomRef.child('messages').push(data);
|
|
||||||
var m = new Metamaps.Backbone.Message({
|
|
||||||
message: data.message,
|
|
||||||
resource_id: Metamaps.Active.Map.id,
|
|
||||||
resource_type: "Map"
|
|
||||||
});
|
|
||||||
m.save(null, {
|
|
||||||
success: function (model, response) {
|
|
||||||
self.addMessages(new Metamaps.Backbone.MessageCollection(model));
|
|
||||||
$(document).trigger(room.events.newMessage, [model]);
|
|
||||||
},
|
|
||||||
error: function (model, response) {
|
|
||||||
console.log('error!', response);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// they should be instantiated as backbone models before they get
|
|
||||||
// passed to this function
|
|
||||||
room.prototype.addMessages = function (messages, isInitial) {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
messages.models.forEach(function (message) {
|
|
||||||
self.chat.addMessage(message, isInitial);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @class
|
|
||||||
* @static
|
|
||||||
*/
|
|
||||||
room.events = {
|
|
||||||
newMessage: "Room:newMessage"
|
|
||||||
};
|
|
||||||
|
|
||||||
return room;
|
|
||||||
})();
|
|
|
@ -1,207 +0,0 @@
|
||||||
Metamaps.Views = Metamaps.Views || {};
|
|
||||||
|
|
||||||
Metamaps.Views.videoView = (function () {
|
|
||||||
|
|
||||||
var videoView;
|
|
||||||
|
|
||||||
var Private = {
|
|
||||||
addControls: function() {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
this.$audioControl = $('<div class="video-audio"></div>');
|
|
||||||
this.$videoControl = $('<div class="video-video"></div>');
|
|
||||||
|
|
||||||
this.$audioControl.on('click', function () {
|
|
||||||
Handlers.audioControlClick.call(self);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.$videoControl.on('click', function () {
|
|
||||||
Handlers.videoControlClick.call(self);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.$container.append(this.$audioControl);
|
|
||||||
this.$container.append(this.$videoControl);
|
|
||||||
},
|
|
||||||
cancelClick: function() {
|
|
||||||
this.mouseIsDown = false;
|
|
||||||
|
|
||||||
if (this.hasMoved) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
$(document).trigger(videoView.events.dragEnd);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var Handlers = {
|
|
||||||
mousedown: function(event) {
|
|
||||||
this.mouseIsDown = true;
|
|
||||||
this.hasMoved = false;
|
|
||||||
this.mouseMoveStart = {
|
|
||||||
x: event.pageX,
|
|
||||||
y: event.pageY
|
|
||||||
};
|
|
||||||
this.posStart = {
|
|
||||||
x: parseInt(this.$container.css('left'), '10'),
|
|
||||||
y: parseInt(this.$container.css('top'), '10')
|
|
||||||
}
|
|
||||||
|
|
||||||
$(document).trigger(videoView.events.mousedown);
|
|
||||||
},
|
|
||||||
mouseup: function(event) {
|
|
||||||
$(document).trigger(videoView.events.mouseup, [this]);
|
|
||||||
|
|
||||||
var storedTime = this.lastClick;
|
|
||||||
var now = Date.now();
|
|
||||||
this.lastClick = now;
|
|
||||||
|
|
||||||
if (now - storedTime < this.config.DOUBLE_CLICK_TOLERANCE) {
|
|
||||||
$(document).trigger(videoView.events.doubleClick, [this]);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mousemove: function(event) {
|
|
||||||
var
|
|
||||||
diffX,
|
|
||||||
diffY,
|
|
||||||
newX,
|
|
||||||
newY;
|
|
||||||
|
|
||||||
if (this.$parent && this.mouseIsDown) {
|
|
||||||
this.manuallyPositioned = true;
|
|
||||||
this.hasMoved = true;
|
|
||||||
diffX = event.pageX - this.mouseMoveStart.x;
|
|
||||||
diffY = this.mouseMoveStart.y - event.pageY;
|
|
||||||
newX = this.posStart.x + diffX;
|
|
||||||
newY = this.posStart.y - diffY;
|
|
||||||
this.$container.css({
|
|
||||||
top: newY,
|
|
||||||
left: newX
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
audioControlClick: function() {
|
|
||||||
if (this.audioStatus) {
|
|
||||||
this.audioOff();
|
|
||||||
} else {
|
|
||||||
this.audioOn();
|
|
||||||
}
|
|
||||||
$(document).trigger(videoView.events.audioControlClick, [this]);
|
|
||||||
},
|
|
||||||
videoControlClick: function() {
|
|
||||||
if (this.videoStatus) {
|
|
||||||
this.videoOff();
|
|
||||||
} else {
|
|
||||||
this.videoOn();
|
|
||||||
}
|
|
||||||
$(document).trigger(videoView.events.videoControlClick, [this]);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
var videoView = function(video, $parent, id, isMyself, config) {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
this.$parent = $parent; // mapView
|
|
||||||
|
|
||||||
this.video = video;
|
|
||||||
this.id = id;
|
|
||||||
|
|
||||||
this.config = config;
|
|
||||||
|
|
||||||
this.mouseIsDown = false;
|
|
||||||
this.mouseDownOffset = { x: 0, y: 0 };
|
|
||||||
this.lastClick = null;
|
|
||||||
this.hasMoved = false;
|
|
||||||
|
|
||||||
this.audioStatus = true;
|
|
||||||
this.videoStatus = true;
|
|
||||||
|
|
||||||
this.$container = $('<div></div>');
|
|
||||||
this.$container.addClass('collaborator-video' + (isMyself ? ' my-video' : ''));
|
|
||||||
this.$container.attr('id', 'container_' + id);
|
|
||||||
|
|
||||||
|
|
||||||
var $vidContainer = $('<div></div>');
|
|
||||||
$vidContainer.addClass('video-cutoff');
|
|
||||||
$vidContainer.append(this.video);
|
|
||||||
|
|
||||||
this.avatar = config.avatar;
|
|
||||||
this.$avatar = $('<img draggable="false" class="collaborator-video-avatar" src="' + config.avatar + '" width="150" height="150" />');
|
|
||||||
$vidContainer.append(this.$avatar);
|
|
||||||
|
|
||||||
this.$container.append($vidContainer);
|
|
||||||
|
|
||||||
this.$container.on('mousedown', function (event) {
|
|
||||||
Handlers.mousedown.call(self, event);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (isMyself) {
|
|
||||||
Private.addControls.call(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// suppress contextmenu
|
|
||||||
this.video.oncontextmenu = function () { return false; };
|
|
||||||
|
|
||||||
if (this.$parent) this.setParent(this.$parent);
|
|
||||||
};
|
|
||||||
|
|
||||||
videoView.prototype.setParent = function($parent) {
|
|
||||||
var self = this;
|
|
||||||
this.$parent = $parent;
|
|
||||||
this.$parent.off('.video' + this.id);
|
|
||||||
this.$parent.on('mouseup.video' + this.id, function (event) {
|
|
||||||
Handlers.mouseup.call(self, event);
|
|
||||||
Private.cancelClick.call(self);
|
|
||||||
});
|
|
||||||
this.$parent.on('mousemove.video' + this.id, function (event) {
|
|
||||||
Handlers.mousemove.call(self, event);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
videoView.prototype.setAvatar = function (src) {
|
|
||||||
this.$avatar.attr('src', src);
|
|
||||||
this.avatar = src;
|
|
||||||
}
|
|
||||||
|
|
||||||
videoView.prototype.remove = function () {
|
|
||||||
this.$container.off();
|
|
||||||
if (this.$parent) this.$parent.off('.video' + this.id);
|
|
||||||
this.$container.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
videoView.prototype.videoOff = function () {
|
|
||||||
this.$videoControl.addClass('active');
|
|
||||||
this.$avatar.show();
|
|
||||||
this.videoStatus = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
videoView.prototype.videoOn = function () {
|
|
||||||
this.$videoControl.removeClass('active');
|
|
||||||
this.$avatar.hide();
|
|
||||||
this.videoStatus = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
videoView.prototype.audioOff = function () {
|
|
||||||
this.$audioControl.addClass('active');
|
|
||||||
this.audioStatus = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
videoView.prototype.audioOn = function () {
|
|
||||||
this.$audioControl.removeClass('active');
|
|
||||||
this.audioStatus = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @class
|
|
||||||
* @static
|
|
||||||
*/
|
|
||||||
videoView.events = {
|
|
||||||
mousedown: "VideoView:mousedown",
|
|
||||||
mouseup: "VideoView:mouseup",
|
|
||||||
doubleClick: "VideoView:doubleClick",
|
|
||||||
dragEnd: "VideoView:dragEnd",
|
|
||||||
audioControlClick: "VideoView:audioControlClick",
|
|
||||||
videoControlClick: "VideoView:videoControlClick",
|
|
||||||
};
|
|
||||||
|
|
||||||
return videoView;
|
|
||||||
})();
|
|
12
app/assets/secret_stylesheets/application-secret.scss.erb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
/*
|
||||||
|
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
||||||
|
* listed below.
|
||||||
|
*
|
||||||
|
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
||||||
|
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
||||||
|
*
|
||||||
|
* You're free to add application-wide styles to this file and they'll appear at the top of the
|
||||||
|
* compiled file, but it's generally better to create a new file per style scope.
|
||||||
|
*
|
||||||
|
*= require ./special
|
||||||
|
*/
|
109
app/assets/secret_stylesheets/special.scss.erb
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
#metacodeSelector {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.metacodeSelect {
|
||||||
|
border-top: 1px solid #DDD;
|
||||||
|
padding: 0;
|
||||||
|
background: #FFF;
|
||||||
|
|
||||||
|
.metacodeFilterInput {
|
||||||
|
width: 100px;
|
||||||
|
outline: none;
|
||||||
|
border: 0;
|
||||||
|
padding: 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 14px;
|
||||||
|
color: #424242;
|
||||||
|
font-family: 'din-medium', helvetica, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metacodeList {
|
||||||
|
list-style: none;
|
||||||
|
background: #FFF;
|
||||||
|
|
||||||
|
li {
|
||||||
|
padding: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover, &.keySelect {
|
||||||
|
background: #4CAF50;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
padding-right: 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.selectedMetacode {
|
||||||
|
float: left;
|
||||||
|
background: #FFF;
|
||||||
|
border-top-left-radius: 2px;
|
||||||
|
border-bottom-left-radius: 2px;
|
||||||
|
padding: 5px 10px 5px 6px;
|
||||||
|
vertical-align: top;
|
||||||
|
border-right: 1px solid #DDD;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.selectedMetacode:hover, .selectedMetacode.isBeingSelected {
|
||||||
|
background: #EDEDED;
|
||||||
|
}
|
||||||
|
.selectedMetacode img {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
.selectedMetacode span {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
.selectedMetacode .downArrow {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 8px 6px 0 6px;
|
||||||
|
border-color: #777 transparent transparent transparent;
|
||||||
|
margin-left: 2px;
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
.new_topic {
|
||||||
|
margin: 0;
|
||||||
|
margin-top: -17px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
#new_topic .twitter-typeahead {
|
||||||
|
position: relative !important;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
.new_topic #topic_name,
|
||||||
|
.new_topic .tt-hint {
|
||||||
|
border-radius: none;
|
||||||
|
border-top-right-radius: 2px;
|
||||||
|
border-bottom-right-radius: 2px;
|
||||||
|
}
|
||||||
|
.openMetacodeSwitcher {
|
||||||
|
top: -16px;
|
||||||
|
left: -16px;
|
||||||
|
}
|
||||||
|
#metacodeImg {
|
||||||
|
height: 120px;
|
||||||
|
width: 380px;
|
||||||
|
display: none;
|
||||||
|
position: absolute !important;
|
||||||
|
top: -30px;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
#metacodeImgTitle {
|
||||||
|
display: none;
|
||||||
|
float: left;
|
||||||
|
width: 120px;
|
||||||
|
text-align: center;
|
||||||
|
margin-left: 110px;
|
||||||
|
}
|
|
@ -56,16 +56,15 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
li.toggledOff {
|
li.toggledOff {
|
||||||
opacity: 0.4;
|
opacity: 0.6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.blackBox {
|
.centerContent {
|
||||||
width: 760px;
|
width: 760px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 20px 0 60px 20px;
|
padding: 80px 0 60px 20px;
|
||||||
background: rgba(0, 0, 0, 0.4);
|
background: rgba(125, 125, 125, 0.4);
|
||||||
color: white;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
@ -85,10 +84,10 @@
|
||||||
display: table-row;
|
display: table-row;
|
||||||
}
|
}
|
||||||
tr:nth-child(odd) {
|
tr:nth-child(odd) {
|
||||||
background: rgba(0, 0, 0, 0.2);
|
background: rgba(125, 125, 125, 0.2);
|
||||||
}
|
}
|
||||||
tr:nth-child(even) {
|
tr:nth-child(even) {
|
||||||
background: rgba(0, 0, 0, 0.3);
|
background: rgba(125, 125, 125, 0.3);
|
||||||
}
|
}
|
||||||
th,
|
th,
|
||||||
td {
|
td {
|
||||||
|
|
|
@ -78,11 +78,18 @@ html {
|
||||||
|
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
background: #d8d9da url(<%= asset_data_uri('shattered_@2X.png') %>);
|
background: #d8d9da url(<%= asset_path('shattered_@2X.png') %>);
|
||||||
font-family: 'din-medium', helvetica, sans-serif;
|
font-family: 'din-medium', helvetica, sans-serif;
|
||||||
color: #424242;
|
color: #424242;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
overflow-x: hidden;
|
||||||
|
|
||||||
|
&.controller-main,
|
||||||
|
&.controller-maps,
|
||||||
|
&.controller-topics,
|
||||||
|
&.controller-explore {
|
||||||
|
overflow-y: hidden;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
h1,
|
h1,
|
||||||
h2,
|
h2,
|
||||||
|
@ -142,6 +149,7 @@ button.button.btn-no:hover {
|
||||||
.toast .toast-button {
|
.toast .toast-button {
|
||||||
margin-top: -10px;
|
margin-top: -10px;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
|
margin-bottom: -10px;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Utility
|
* Utility
|
||||||
|
@ -185,10 +193,6 @@ button.button.btn-no:hover {
|
||||||
display: block;
|
display: block;
|
||||||
width: 830px;
|
width: 830px;
|
||||||
}
|
}
|
||||||
.requestInvite {
|
|
||||||
display: block;
|
|
||||||
margin: -720px auto 0;
|
|
||||||
}
|
|
||||||
.new_session,
|
.new_session,
|
||||||
.new_user,
|
.new_user,
|
||||||
.edit_user,
|
.edit_user,
|
||||||
|
@ -523,10 +527,12 @@ button.button.btn-no:hover {
|
||||||
left: -1000px;
|
left: -1000px;
|
||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 340px;
|
|
||||||
margin: -40px 0 0 -35px;
|
margin: -40px 0 0 -35px;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
body:not(.action-conversation) .new_topic {
|
||||||
|
width: 340px;
|
||||||
|
}
|
||||||
|
|
||||||
#new_topic .twitter-typeahead {
|
#new_topic .twitter-typeahead {
|
||||||
position: absolute !important;
|
position: absolute !important;
|
||||||
|
@ -567,6 +573,26 @@ button.button.btn-no:hover {
|
||||||
.openMetacodeSwitcher:hover {
|
.openMetacodeSwitcher:hover {
|
||||||
background-position: -16px 0;
|
background-position: -16px 0;
|
||||||
}
|
}
|
||||||
|
.pinCarousel {
|
||||||
|
cursor: pointer;
|
||||||
|
display: block;
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
background-image: url(<%= asset_data_uri('pincarousel_sprite.png') %>);
|
||||||
|
position: absolute;
|
||||||
|
z-index: 2;
|
||||||
|
top: 20px;
|
||||||
|
right: 16px;
|
||||||
|
}
|
||||||
|
.pinCarousel:hover {
|
||||||
|
background-position: 0 -16px;
|
||||||
|
}
|
||||||
|
.pinCarousel.isPinned {
|
||||||
|
background-position: -16px 0;
|
||||||
|
}
|
||||||
|
.pinCarousel.isPinned:hover {
|
||||||
|
background-position: -16px -16px;
|
||||||
|
}
|
||||||
#metacodeImg {
|
#metacodeImg {
|
||||||
height: 120px;
|
height: 120px;
|
||||||
}
|
}
|
||||||
|
@ -642,9 +668,21 @@ label {
|
||||||
position: relative;
|
position: relative;
|
||||||
/*overflow:hidden; */
|
/*overflow:hidden; */
|
||||||
}
|
}
|
||||||
.main.compressed {
|
.compressed {
|
||||||
width: calc(100% - 300px);
|
.upperRightUI {
|
||||||
|
right: 324px;
|
||||||
}
|
}
|
||||||
|
.upperRightMapButtons {
|
||||||
|
right: 434px;
|
||||||
|
}
|
||||||
|
.mapControls {
|
||||||
|
right: 324px;
|
||||||
|
}
|
||||||
|
.infoAndHelp {
|
||||||
|
right: 370px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#infovis-canvas {
|
#infovis-canvas {
|
||||||
-webkit-touch-callout: none;
|
-webkit-touch-callout: none;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
|
@ -745,9 +783,9 @@ label {
|
||||||
}
|
}
|
||||||
.sidebarAccountIcon img {
|
.sidebarAccountIcon img {
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
|
width: 32px;
|
||||||
}
|
}
|
||||||
.sidebarAccountBox {
|
.sidebarAccountBox {
|
||||||
display: none;
|
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
.authenticated .sidebarAccountBox {
|
.authenticated .sidebarAccountBox {
|
||||||
|
@ -788,6 +826,7 @@ label {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 14px;
|
line-height: 14px;
|
||||||
color: #757575;
|
color: #757575;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.accountListItem:hover {
|
.accountListItem:hover {
|
||||||
color: #424242;
|
color: #424242;
|
||||||
|
@ -798,7 +837,7 @@ label {
|
||||||
position:absolute;
|
position:absolute;
|
||||||
pointer-events:none;
|
pointer-events:none;
|
||||||
background-repeat:no-repeat;
|
background-repeat:no-repeat;
|
||||||
background-image: url(<%= asset_data_uri('user_sprite.png') %>);
|
background-image: url(<%= asset_path('user_sprite.png') %>);
|
||||||
}
|
}
|
||||||
.accountSettings .accountIcon {
|
.accountSettings .accountIcon {
|
||||||
background-position: 0 0;
|
background-position: 0 0;
|
||||||
|
@ -806,6 +845,9 @@ label {
|
||||||
.accountAdmin .accountIcon {
|
.accountAdmin .accountIcon {
|
||||||
background-position: 0 -32px;
|
background-position: 0 -32px;
|
||||||
}
|
}
|
||||||
|
.accountApps .accountIcon {
|
||||||
|
background-position: 0 -32px;
|
||||||
|
}
|
||||||
.accountInvite .accountIcon {
|
.accountInvite .accountIcon {
|
||||||
background-position: 0 -64px;
|
background-position: 0 -64px;
|
||||||
}
|
}
|
||||||
|
@ -1006,7 +1048,6 @@ label[for="user_remember_me"] {
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebarFilterBox {
|
.sidebarFilterBox {
|
||||||
display:none;
|
|
||||||
width: 319px;
|
width: 319px;
|
||||||
padding: 16px 0;
|
padding: 16px 0;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
@ -1217,7 +1258,7 @@ h3.filterBox {
|
||||||
box-shadow: 0px 3px 3px rgba(0,0,0,0.12), 0 3px 3px rgba(0,0,0,0.24);
|
box-shadow: 0px 3px 3px rgba(0,0,0,0.12), 0 3px 3px rgba(0,0,0,0.24);
|
||||||
}
|
}
|
||||||
.rightclickmenu .rc-permission:hover > ul,
|
.rightclickmenu .rc-permission:hover > ul,
|
||||||
.rightclickmenu .rc-metacode:hover > ul,
|
.rightclickmenu .rc-metacode:hover #metacodeOptions > ul,
|
||||||
.rightclickmenu .rc-siblings:hover > ul {
|
.rightclickmenu .rc-siblings:hover > ul {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
@ -1246,11 +1287,12 @@ h3.filterBox {
|
||||||
.rightclickmenu li.toPrivate .rc-perm-icon {
|
.rightclickmenu li.toPrivate .rc-perm-icon {
|
||||||
background-position: -24px 0;
|
background-position: -24px 0;
|
||||||
}
|
}
|
||||||
.rightclickmenu .rc-metacode > ul > li,
|
.rightclickmenu .rc-metacode #metacodeOptions > ul > li,
|
||||||
.rightclickmenu .rc-siblings > ul > li {
|
.rightclickmenu .rc-siblings > ul > li {
|
||||||
padding: 6px 24px 6px 8px;
|
padding: 6px 24px 6px 8px;
|
||||||
width: auto;
|
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
width: auto;
|
||||||
|
min-width: 5em;
|
||||||
}
|
}
|
||||||
.rightclickmenu .rc-metacode ul ul,
|
.rightclickmenu .rc-metacode ul ul,
|
||||||
.rightclickmenu .rc-siblings ul ul {
|
.rightclickmenu .rc-siblings ul ul {
|
||||||
|
@ -1504,9 +1546,8 @@ h3.filterBox {
|
||||||
background-image: url(<%= asset_data_uri('permissions32_sprite.png') %>);
|
background-image: url(<%= asset_data_uri('permissions32_sprite.png') %>);
|
||||||
}
|
}
|
||||||
/* map info box */
|
/* map info box */
|
||||||
/* map info box */
|
|
||||||
|
|
||||||
.wrapper div.mapInfoBox {
|
.wrapper .mapInfoBox {
|
||||||
display: none;
|
display: none;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 40px;
|
bottom: 40px;
|
||||||
|
@ -1514,12 +1555,74 @@ h3.filterBox {
|
||||||
background-color: #424242;
|
background-color: #424242;
|
||||||
color: #F5F5F5;
|
color: #F5F5F5;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
|
box-shadow: 0 3px 3px rgba(0,0,0,0.23), 0px 3px 3px rgba(0,0,0,0.16);
|
||||||
|
text-align: center;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
.import-dialog{
|
||||||
|
button {
|
||||||
|
margin: 1em 0.5em;
|
||||||
|
}
|
||||||
|
.import-blue-button {
|
||||||
|
display: inline-block;
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin: 0.75em;
|
||||||
|
padding: 0.75em;
|
||||||
|
padding-top: 0.85em;
|
||||||
|
height: 3em;
|
||||||
|
background-color: #AAB0FB;
|
||||||
|
border-radius: 0.3em;
|
||||||
|
color: white;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.fileupload {
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin: 0.75em;
|
||||||
|
padding: 0.75em;
|
||||||
|
height: 3em;
|
||||||
|
border: 3px dashed #AAB0FB;
|
||||||
|
width: 75%;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.wrapper .mapInfoBox {
|
||||||
width: 360px;
|
width: 360px;
|
||||||
min-height: 300px;
|
min-height: 300px;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
font-style: normal;
|
}
|
||||||
|
.requestTitle {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
background: black;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
box-shadow: 0 3px 3px rgba(0,0,0,0.23), 0px 3px 3px rgba(0,0,0,0.16);
|
text-transform: none;
|
||||||
|
color: white;
|
||||||
|
border-radius: 2px;
|
||||||
|
font-family: din-regular;
|
||||||
|
line-height: 18px;
|
||||||
|
font-size: 15px;
|
||||||
|
padding: 3px 5px 2px;
|
||||||
|
white-space: nowrap;
|
||||||
|
font-style: normal;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -100px;
|
||||||
|
top: -15px;
|
||||||
|
}
|
||||||
|
.mapRequestTitle .requestTitle {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.requestTitle:after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 23px;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -8px;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-top: 10px solid #000000;
|
||||||
|
border-left: 8px solid transparent;
|
||||||
|
border-right: 8px solid transparent;
|
||||||
}
|
}
|
||||||
.mapInfoName {
|
.mapInfoName {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
|
@ -1569,13 +1672,19 @@ h3.filterBox {
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.commonsMap .mapContributors {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
.mapContributors {
|
.mapContributors {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
margin: 9px 0px 9px 56px;
|
margin: 9px 0px 9px 44px;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
width: 64px;
|
width: 64px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#mapContribs {
|
#mapContribs {
|
||||||
float: left;
|
float: left;
|
||||||
border: 2px solid #424242;
|
border: 2px solid #424242;
|
||||||
|
@ -1591,7 +1700,7 @@ h3.filterBox {
|
||||||
#mapContribs.multiple {
|
#mapContribs.multiple {
|
||||||
box-shadow: 1px 1px 0 0 #B5B5B5,3px 2px 0 0 #424242,4px 3px 0 0 #B5B5B5,5px 4px 0 0 #424242;
|
box-shadow: 1px 1px 0 0 #B5B5B5,3px 2px 0 0 #424242,4px 3px 0 0 #B5B5B5,5px 4px 0 0 #424242;
|
||||||
}
|
}
|
||||||
.mapContributors span {
|
.mapContributors span.count {
|
||||||
height: 20px;
|
height: 20px;
|
||||||
padding-top: 5px;
|
padding-top: 5px;
|
||||||
padding-left: 8px;
|
padding-left: 8px;
|
||||||
|
@ -1626,10 +1735,11 @@ h3.filterBox {
|
||||||
.mapContributors .tip {
|
.mapContributors .tip {
|
||||||
top: 45px;
|
top: 45px;
|
||||||
left: -10px;
|
left: -10px;
|
||||||
|
min-width: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mapContributors .tip ul {
|
.mapContributors .tip ul {
|
||||||
max-height: 188px;
|
max-height: 144px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1652,7 +1762,7 @@ h3.filterBox {
|
||||||
.mapContributors .tip li a {
|
.mapContributors .tip li a {
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
.mapContributors div:after {
|
.mapContributors div.tip:after {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: -4px;
|
top: -4px;
|
||||||
|
@ -1672,6 +1782,90 @@ h3.filterBox {
|
||||||
border-radius: 14px;
|
border-radius: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mapContributors span.twitter-typeahead {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collabSearchField {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collabNameWrapper {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collabIconWrapper img.icon {
|
||||||
|
position: relative;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collabIconWrapper {
|
||||||
|
position: relative;
|
||||||
|
float: left;
|
||||||
|
padding: 0 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mapContributors .collabName {
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 28px;
|
||||||
|
color: #424242;
|
||||||
|
padding: 0 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.removeCollaborator {
|
||||||
|
position: absolute;
|
||||||
|
top: 11px;
|
||||||
|
right: 8px;
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
background-image: url(<%= asset_data_uri('removecollab_sprite.png') %>);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.removeCollaborator:hover {
|
||||||
|
background-position: -16px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.addCollab {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
background-image: url(<%= asset_data_uri('addcollab_sprite.png') %>);
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin: 0 12px 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.collaboratorSearchField {
|
||||||
|
background: #FFFFFF;
|
||||||
|
height: 14px;
|
||||||
|
margin: 0;
|
||||||
|
padding: 10px 6px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 2px;
|
||||||
|
outline: none;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 14px;
|
||||||
|
color: #424242;
|
||||||
|
font-family: 'din-medium', helvetica, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tt-dataset.tt-dataset-collaborators {
|
||||||
|
padding: 2px;
|
||||||
|
background: #E0E0E0;
|
||||||
|
min-width: 156px;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tt-dataset.tt-dataset .collabResult {
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collabResult.tt-suggestion.tt-cursor, .collabResult.tt-suggestion:hover {
|
||||||
|
background-color: #CCCCCC;
|
||||||
|
}
|
||||||
|
|
||||||
.mapInfoBox .mapPermission .tooltips {
|
.mapInfoBox .mapPermission .tooltips {
|
||||||
top: -20px;
|
top: -20px;
|
||||||
right: 36px;
|
right: 36px;
|
||||||
|
@ -1721,14 +1915,10 @@ h3.filterBox {
|
||||||
background-position: -32px 0;
|
background-position: -32px 0;
|
||||||
}
|
}
|
||||||
.yourMap .mapPermission:hover {
|
.yourMap .mapPermission:hover {
|
||||||
background-image: url(<%= asset_data_uri('arrowperms_sprite.png') %>);
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background-position: -32px 0;
|
|
||||||
}
|
}
|
||||||
.yourMap .mapPermission.minimize {
|
.yourMap .mapPermission.minimize {
|
||||||
background-image: url(<%= asset_data_uri('arrowperms_sprite.png') %>) !important;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background-position: 0 0;
|
|
||||||
}
|
}
|
||||||
.mapInfoBox .mapPermission .permissionSelect {
|
.mapInfoBox .mapPermission .permissionSelect {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
@ -1829,6 +2019,7 @@ h3.filterBox {
|
||||||
position: relative;
|
position: relative;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: none;
|
display: none;
|
||||||
|
padding: 0 2px;
|
||||||
}
|
}
|
||||||
.mapInfoShareIcon {
|
.mapInfoShareIcon {
|
||||||
width: 24px;
|
width: 24px;
|
||||||
|
@ -1868,6 +2059,43 @@ and it won't be important on password protected instances */
|
||||||
.yourMap .mapInfoDelete {
|
.yourMap .mapInfoDelete {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mapInfoButtonsWrapper .mapInfoThumbnail {
|
||||||
|
display: block;
|
||||||
|
background-image: url(<%= asset_path('screenshot_sprite.png') %>);
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
|
||||||
|
& > span {
|
||||||
|
bottom: -8px;
|
||||||
|
right: 2px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #e0e0e0;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-position: -32px 0;
|
||||||
|
|
||||||
|
.tooltip {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 30px;
|
||||||
|
background: black;
|
||||||
|
color: white;
|
||||||
|
border-radius: 2px;
|
||||||
|
padding: 3px 5px 2px 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.mapInfoButtonsWrapper span {
|
.mapInfoButtonsWrapper span {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -1882,17 +2110,17 @@ and it won't be important on password protected instances */
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
position: fixed;
|
position: absolute;
|
||||||
z-index: 1000000;
|
z-index: 1000000;
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
#lightbox_main {
|
#lightbox_main {
|
||||||
width: 800px;
|
width: 800px;
|
||||||
height: auto;
|
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 50%;
|
top: 5vh;
|
||||||
|
height: 90vh;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
||||||
|
@ -1931,8 +2159,10 @@ and it won't be important on password protected instances */
|
||||||
background-position: center center;
|
background-position: center center;
|
||||||
}
|
}
|
||||||
#lightbox_content {
|
#lightbox_content {
|
||||||
width: 552px;
|
width: 800px;
|
||||||
height: 434px;
|
max-height: 90vh;
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow-y: auto;
|
||||||
background-color: #e0e0e0;
|
background-color: #e0e0e0;
|
||||||
padding: 64px 124px 64px 124px;
|
padding: 64px 124px 64px 124px;
|
||||||
box-shadow: 0px 6px 3px rgba(0, 0, 0, 0.23), 10px 10px 10px rgba(0, 0, 0, 0.19);
|
box-shadow: 0px 6px 3px rgba(0, 0, 0, 0.23), 10px 10px 10px rgba(0, 0, 0, 0.19);
|
||||||
|
@ -2014,42 +2244,35 @@ and it won't be important on password protected instances */
|
||||||
color: #00bcd4;
|
color: #00bcd4;
|
||||||
}
|
}
|
||||||
.lightbox_links .lightboxAboutIcon {
|
.lightbox_links .lightboxAboutIcon {
|
||||||
background-image: url(<%= asset_data_uri('about_sprite.png') %>);
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
width:32px;
|
width:32px;
|
||||||
height:32px;
|
height:32px;
|
||||||
margin:10px auto;
|
margin:10px auto;
|
||||||
}
|
}
|
||||||
#lightbox_metamapps .lightboxAboutIcon {
|
.icon_twitter .lightboxAboutIcon,
|
||||||
|
.icon_source_code .lightboxAboutIcon,
|
||||||
|
.icon_terms .lightboxAboutIcon {
|
||||||
|
background-image: url(<%= asset_data_uri('about_sprite.png') %>);
|
||||||
|
background-repeat: no-repeat;
|
||||||
background-position: 0 0;
|
background-position: 0 0;
|
||||||
}
|
}
|
||||||
#lightbox_community .lightboxAboutIcon {
|
.icon_twitter .lightboxAboutIcon {
|
||||||
background-position: -32px 0;
|
background-position: 0 0;
|
||||||
}
|
&:hover {
|
||||||
#lightbox_source .lightboxAboutIcon {
|
|
||||||
background-position: -64px 0;
|
|
||||||
}
|
|
||||||
#lightbox_blog .lightboxAboutIcon {
|
|
||||||
background-position: -96px 0;
|
|
||||||
}
|
|
||||||
#lightbox_term .lightboxAboutIcon {
|
|
||||||
background-position: -128px 0;
|
|
||||||
}
|
|
||||||
#lightbox_metamapps:hover .lightboxAboutIcon {
|
|
||||||
background-position: 0 -32px;
|
background-position: 0 -32px;
|
||||||
}
|
}
|
||||||
#lightbox_community:hover .lightboxAboutIcon {
|
|
||||||
background-position: -32px -32px;
|
|
||||||
}
|
}
|
||||||
#lightbox_source:hover .lightboxAboutIcon {
|
.icon_source_code .lightboxAboutIcon {
|
||||||
|
background-position: -64px 0;
|
||||||
|
&:hover {
|
||||||
background-position: -64px -32px;
|
background-position: -64px -32px;
|
||||||
}
|
}
|
||||||
#lightbox_blog:hover .lightboxAboutIcon {
|
|
||||||
background-position: -96px -32px;
|
|
||||||
}
|
}
|
||||||
#lightbox_term:hover .lightboxAboutIcon {
|
.icon_terms .lightboxAboutIcon {
|
||||||
|
background-position: -128px 0;
|
||||||
|
&:hover {
|
||||||
background-position: -128px -32px;
|
background-position: -128px -32px;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* jquery ui tabs */
|
/* jquery ui tabs */
|
||||||
|
|
||||||
|
@ -2092,6 +2315,9 @@ and it won't be important on password protected instances */
|
||||||
}
|
}
|
||||||
/* switch metacode set */
|
/* switch metacode set */
|
||||||
|
|
||||||
|
#switchMetacodes > p {
|
||||||
|
margin: 16px 0 16px 0;
|
||||||
|
}
|
||||||
#metacodeSwitchTabs {
|
#metacodeSwitchTabs {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
font-size: 17px;
|
font-size: 17px;
|
||||||
|
@ -2099,29 +2325,44 @@ and it won't be important on password protected instances */
|
||||||
border: none;
|
border: none;
|
||||||
background: none;
|
background: none;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
|
||||||
#metacodeSwitchTabs .setDesc {
|
.setDesc,
|
||||||
|
.selectAll,
|
||||||
|
.selectNone {
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
font-family: 'din-medium', helvetica, sans-serif;
|
font-family: 'din-medium', helvetica, sans-serif;
|
||||||
color: #424242;
|
color: #424242;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
text-align: justify;
|
text-align: justify;
|
||||||
padding-right: 16px;
|
padding-right: 16px;
|
||||||
|
display: inline-block;
|
||||||
}
|
}
|
||||||
#switchMetacodes > p {
|
|
||||||
margin: 16px 0 16px 0;
|
.selectAll,
|
||||||
|
.selectNone {
|
||||||
|
float: right;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&.selected {
|
||||||
|
color: #00bcd4;
|
||||||
}
|
}
|
||||||
#metacodeSwitchTabs > ul {
|
}
|
||||||
|
|
||||||
|
& > ul {
|
||||||
width: 130px;
|
width: 130px;
|
||||||
}
|
|
||||||
#metacodeSwitchTabs > ul li {
|
li {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
#metacodeSwitchTabs li.ui-state-active a {
|
}
|
||||||
|
|
||||||
|
li.ui-state-active a {
|
||||||
color: #00BCD4;
|
color: #00BCD4;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
.metacodeSwitchTab {
|
.metacodeSwitchTab {
|
||||||
max-height: 300px;
|
max-height: 300px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
@ -2689,146 +2930,18 @@ and it won't be important on password protected instances */
|
||||||
color: #424242;
|
color: #424242;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Admin Pages */
|
|
||||||
|
|
||||||
.blackBox {
|
|
||||||
width: 760px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 20px 0 60px 20px;
|
|
||||||
background: rgba(0, 0, 0, 0.4);
|
|
||||||
color: white;
|
|
||||||
overflow: hidden;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.blackBox .metacodeSetsDescription {
|
|
||||||
width: 314px;
|
|
||||||
}
|
|
||||||
.blackBox td.metacodeSetDesc {
|
|
||||||
width: 314px;
|
|
||||||
word-wrap: break-word;
|
|
||||||
}
|
|
||||||
.blackBox .metacodeSetImage {
|
|
||||||
width: 36px;
|
|
||||||
height: 36px;
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
.blackBox tr {
|
|
||||||
display: table-row;
|
|
||||||
}
|
|
||||||
.blackBox tr:nth-child(odd) {
|
|
||||||
background: rgba(0, 0, 0, 0.2);
|
|
||||||
}
|
|
||||||
.blackBox tr:nth-child(even) {
|
|
||||||
background: rgba(0, 0, 0, 0.3);
|
|
||||||
}
|
|
||||||
.blackBox th,
|
|
||||||
.blackBox td {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
.blackBox td.iconURL {
|
|
||||||
max-width: 415px;
|
|
||||||
word-wrap: break-word;
|
|
||||||
}
|
|
||||||
.blackBox td.iconColor {
|
|
||||||
|
|
||||||
}
|
|
||||||
.blackBox .field {
|
|
||||||
margin: 15px 0 5px;
|
|
||||||
}
|
|
||||||
.blackBox label {
|
|
||||||
float: left;
|
|
||||||
width: 100px;
|
|
||||||
margin-right: 15px;
|
|
||||||
}
|
|
||||||
.blackBox input[type="text"] {
|
|
||||||
width: 336px;
|
|
||||||
height: 32px;
|
|
||||||
font-size: 15px;
|
|
||||||
direction: ltr;
|
|
||||||
-webkit-appearance: none;
|
|
||||||
appearance: none;
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0 8px;
|
|
||||||
background: #fff;
|
|
||||||
border: 1px solid #d9d9d9;
|
|
||||||
border-top: 1px solid #c0c0c0;
|
|
||||||
-webkit-box-sizing: border-box;
|
|
||||||
-moz-box-sizing: border-box;
|
|
||||||
box-sizing: border-box;
|
|
||||||
-webkit-border-radius: 1px;
|
|
||||||
-moz-border-radius: 1px;
|
|
||||||
border-radius: 1px;
|
|
||||||
font: -webkit-small-control;
|
|
||||||
color: initial;
|
|
||||||
letter-spacing: normal;
|
|
||||||
word-spacing: normal;
|
|
||||||
text-transform: none;
|
|
||||||
text-indent: 0px;
|
|
||||||
text-shadow: none;
|
|
||||||
display: inline-block;
|
|
||||||
text-align: start;
|
|
||||||
font-family: arial;
|
|
||||||
}
|
|
||||||
.blackBox input[type="text"]:hover,
|
|
||||||
.blackBox textarea:hover {
|
|
||||||
border: 1px solid #b9b9b9;
|
|
||||||
border-top: 1px solid #a0a0a0;
|
|
||||||
-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
|
||||||
-moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
|
||||||
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
.blackBox textarea {
|
|
||||||
padding: 8px;
|
|
||||||
border: 1px solid #d9d9d9;
|
|
||||||
border-top: 1px solid #c0c0c0;
|
|
||||||
resize: none;
|
|
||||||
font: -webkit-small-control;
|
|
||||||
letter-spacing: normal;
|
|
||||||
word-spacing: normal;
|
|
||||||
text-transform: none;
|
|
||||||
text-indent: 0px;
|
|
||||||
text-shadow: none;
|
|
||||||
text-align: start;
|
|
||||||
font-family: arial;
|
|
||||||
font-size: 15px;
|
|
||||||
line-height: 17px;
|
|
||||||
width: 318px;
|
|
||||||
}
|
|
||||||
.blackBox .allMetacodes {
|
|
||||||
padding: 5px 0;
|
|
||||||
}
|
|
||||||
.blackBox a.button {
|
|
||||||
margin-right: 20px;
|
|
||||||
line-height: 40px;
|
|
||||||
}
|
|
||||||
.blackBox a.button,
|
|
||||||
.blackBox input.add {
|
|
||||||
float: left;
|
|
||||||
margin-top: 5px;
|
|
||||||
height: 40px;
|
|
||||||
font-size: 17px;
|
|
||||||
width: auto;
|
|
||||||
padding: 0 30px;
|
|
||||||
cursor: pointer;
|
|
||||||
font-weight: normal;
|
|
||||||
}
|
|
||||||
.blackBox a.button:hover,
|
|
||||||
.blackBox input.add:hover {
|
|
||||||
-webkit-box-shadow: none;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* request */
|
/* request */
|
||||||
|
|
||||||
#wrapper .requestInvite {
|
.requestInvite {
|
||||||
width: 700px;
|
width: 700px;
|
||||||
margin: 0 auto;
|
|
||||||
padding: 0 0 60px 0;
|
|
||||||
background: #FFFFFF;
|
background: #FFFFFF;
|
||||||
color: white;
|
color: white;
|
||||||
height: 100%;
|
height: calc(100% - 52px);
|
||||||
overflow: hidden;
|
z-index: 1;
|
||||||
|
position: relative;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -350px;
|
||||||
|
margin-top: 52px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.home_bg {
|
.home_bg {
|
||||||
|
@ -2898,3 +3011,21 @@ script.data-gratipay-username {
|
||||||
display: inline;
|
display: inline;
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.inline {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topicFollow {
|
||||||
|
height: 24px;
|
||||||
|
line-height: 24px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: helvetica, sans-serif;
|
||||||
|
float: left;
|
||||||
|
width: 72px;
|
||||||
|
text-align: right;
|
||||||
|
padding: 12px 0;
|
||||||
|
color: #4fb5c0;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
|
@ -1,17 +1,14 @@
|
||||||
.centerContent {
|
.centerContent {
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: 92px auto 0 auto;
|
margin: 0 auto;
|
||||||
padding: 20px 0 60px 20px;
|
width: auto;
|
||||||
width: 760px;
|
max-width: 800px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-shadow: 0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24);
|
box-shadow: 0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24);
|
||||||
background: #fff;
|
background: #fff;
|
||||||
-webkit-border-radius: 3px;
|
box-sizing: border-box;
|
||||||
-moz-border-radius: 3px;
|
|
||||||
border-radius: 3px;
|
|
||||||
border: 1px solid #dcdcdc;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
|
font-family: 'din-regular', sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
.centerContent .page-header {
|
.centerContent .page-header {
|
||||||
|
@ -129,3 +126,9 @@
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.centerContent.withPadding {
|
||||||
|
margin-top: 1em;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
|
$mid-gray: #8A8A8A;
|
||||||
|
$mid-gray-opacity: rgba(66, 66, 66, 0.6);
|
||||||
|
|
||||||
.nameCounter {
|
.nameCounter {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 1px;
|
bottom: 1px;
|
||||||
right: 2px;
|
right: 2px;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
font-family: helvetica;
|
font-family: helvetica, sans-serif;
|
||||||
color: #727272;
|
color: #727272;
|
||||||
line-height: 11px;
|
line-height: 11px;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.riek-editing + .nameCounter {
|
||||||
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nameCounter.forMap {
|
.nameCounter.forMap {
|
||||||
|
@ -17,7 +25,6 @@
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#center-container {
|
#center-container {
|
||||||
position:relative;
|
position:relative;
|
||||||
height:100%;
|
height:100%;
|
||||||
|
@ -29,7 +36,6 @@
|
||||||
|
|
||||||
.showcard {
|
.showcard {
|
||||||
position:absolute;
|
position:absolute;
|
||||||
display:none;
|
|
||||||
top:100px;
|
top:100px;
|
||||||
left:100px;
|
left:100px;
|
||||||
width:300px;
|
width:300px;
|
||||||
|
@ -39,7 +45,7 @@
|
||||||
z-index:2;
|
z-index:2;
|
||||||
color: #424242;
|
color: #424242;
|
||||||
border-radius:2px;
|
border-radius:2px;
|
||||||
box-shadow: 0px 3px 3px rgba(0,0,0,0.23), 0 3px 3px rgba(0,0,0,0.16);
|
box-shadow: 2px 3px 3px rgba(125, 125, 125, 0.23), -2px -1px 3px rgba(125, 125, 125, 0.16);
|
||||||
}
|
}
|
||||||
|
|
||||||
.text {
|
.text {
|
||||||
|
@ -49,6 +55,7 @@
|
||||||
#infovis {
|
#infovis {
|
||||||
width:100%;
|
width:100%;
|
||||||
height:100%;
|
height:100%;
|
||||||
|
position: absolute;
|
||||||
}
|
}
|
||||||
|
|
||||||
.showcard .permission {
|
.showcard .permission {
|
||||||
|
@ -60,7 +67,6 @@
|
||||||
display:block;
|
display:block;
|
||||||
position:relative;
|
position:relative;
|
||||||
width:100%;
|
width:100%;
|
||||||
min-height:360px;
|
|
||||||
z-index: 25;
|
z-index: 25;
|
||||||
}
|
}
|
||||||
.CardOnGraph.hasAttachment {
|
.CardOnGraph.hasAttachment {
|
||||||
|
@ -68,11 +74,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.CardOnGraph .title {
|
.CardOnGraph .title {
|
||||||
font-size: 18px;
|
word-break: break-word;
|
||||||
line-height: 22px;
|
font-size: 20px;
|
||||||
|
line-height: 24px;
|
||||||
display: table;
|
display: table;
|
||||||
padding: 8px 0 16px;
|
padding: 20px 0;
|
||||||
height: 80px;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-family: 'din-regular', sans-serif;
|
font-family: 'din-regular', sans-serif;
|
||||||
width: 300px;
|
width: 300px;
|
||||||
|
@ -91,12 +97,11 @@
|
||||||
cursor: text;
|
cursor: text;
|
||||||
}
|
}
|
||||||
|
|
||||||
.showcard .best_in_place_name textarea, .showcard .best_in_place_name input {
|
.showcard .title .riek-editing {
|
||||||
font-family: 'din-regular', sans-serif;
|
font-family: 'din-regular', sans-serif;
|
||||||
color: #424242;
|
color: #424242;
|
||||||
font-size: 18px;
|
font-size: 20px;
|
||||||
line-height: 22px;
|
line-height: 24px;
|
||||||
height: 15px;
|
|
||||||
padding: 5px 0;
|
padding: 5px 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
@ -110,44 +115,76 @@
|
||||||
.CardOnGraph .scroll {
|
.CardOnGraph .scroll {
|
||||||
display:block;
|
display:block;
|
||||||
padding: 8px 0 8px 16px;
|
padding: 8px 0 8px 16px;
|
||||||
height: 152px;
|
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
line-height:15px;
|
line-height:15px;
|
||||||
font-family: helvetica, sans-serif;
|
font-family: helvetica, sans-serif;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
||||||
|
p.emptyDesc {
|
||||||
|
color: $mid-gray-opacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.mdSupport {
|
||||||
|
color: #4fb5c0;
|
||||||
|
font-size: 11px;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.riek-editing + .mdSupport {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.CardOnGraph.hasAttachment .scroll {
|
.CardOnGraph.hasAttachment .scroll {
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.CardOnGraph .best_in_place_desc textarea {
|
.CardOnGraph .desc .riek-editing {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
line-height:15px;
|
line-height:15px;
|
||||||
font-family: helvetica, sans-serif;
|
font-family: helvetica, sans-serif;
|
||||||
color: #424242;
|
color: #424242;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
width: 100%;
|
width: 258px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
border: 0;
|
border: 0;
|
||||||
outline: none;
|
outline: none;
|
||||||
font-size: 12px;
|
|
||||||
line-height: 15px;
|
|
||||||
background: none;
|
background: none;
|
||||||
resize: none;
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
.CardOnGraph .desc h3 {
|
/*
|
||||||
|
* Styling for Markdown in topic cards
|
||||||
|
*/
|
||||||
|
|
||||||
|
.CardOnGraph .desc {
|
||||||
|
p, ol, ul {
|
||||||
|
padding: 0.15em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
margin-top:5px;
|
padding: 0.25em 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.CardOnGraph .best_in_place_desc {
|
ol,
|
||||||
display:block;
|
ul {
|
||||||
margin-top:2px;
|
margin-left: 1em;
|
||||||
padding-right: 18px;
|
|
||||||
margin-right: 8px;
|
|
||||||
}
|
}
|
||||||
.canEdit .CardOnGraph .best_in_place_desc:hover {
|
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* End Markdown styling
|
||||||
|
*/
|
||||||
|
|
||||||
|
.CardOnGraph .riek_desc {
|
||||||
|
display:block;
|
||||||
|
padding-right: 26px;
|
||||||
|
}
|
||||||
|
.canEdit .CardOnGraph .riek_desc:not(.riek-editing):hover {
|
||||||
background-image: url(<%= asset_data_uri('edit.png') %>);
|
background-image: url(<%= asset_data_uri('edit.png') %>);
|
||||||
background-position: top right;
|
background-position: top right;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
|
@ -160,117 +197,136 @@
|
||||||
|
|
||||||
.CardOnGraph .links {
|
.CardOnGraph .links {
|
||||||
position: relative;
|
position: relative;
|
||||||
border-bottom: 1px solid #BDBDBD;
|
z-index: 2;
|
||||||
border-top: 1px solid #BDBDBD;
|
|
||||||
background-color: #e0e0e0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.linkItem {
|
.linkItem {
|
||||||
float: left;
|
float: left;
|
||||||
height:46px;
|
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
position: relative;
|
position: relative;
|
||||||
color: #424242;
|
color: #424242;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 14px;
|
line-height: 14px;
|
||||||
height:12px;
|
|
||||||
padding:17px 0;
|
a {
|
||||||
}
|
|
||||||
.linkItem a {
|
|
||||||
color: #424242;
|
color: #424242;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.CardOnGraph .icon {
|
.icon {
|
||||||
position:absolute;
|
|
||||||
width:100%;
|
|
||||||
z-index:1;
|
|
||||||
padding: 0;
|
padding: 0;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
}
|
margin-right: 10px;
|
||||||
.linkItem.contributor {
|
|
||||||
margin-left:40px;
|
.metacodeImage {
|
||||||
z-index:1;
|
cursor: move;
|
||||||
padding:17px 16px 17px 30px;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.contributor .contributorIcon {
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 8px;
|
left: -18px;
|
||||||
left: 0;
|
top: 6px;
|
||||||
border-radius: 16px;
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
background-size:36px 36px;
|
||||||
|
background-position:0 0;
|
||||||
|
background-repeat:no-repeat;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.contributor:hover .contributorName {
|
.CardOnGraph .info {
|
||||||
display: block;
|
position: relative;
|
||||||
|
|
||||||
|
.linkItem {
|
||||||
|
float: left;
|
||||||
|
z-index: 1;
|
||||||
|
position: relative;
|
||||||
|
color: $mid-gray-opacity;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 14px;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $mid-gray-opacity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.contributor {
|
||||||
|
bottom: 7px;
|
||||||
|
margin-left: 16px;
|
||||||
|
|
||||||
|
.contributorIcon {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
border-radius: 16px;
|
||||||
|
margin: 5px 5px 5px 0;
|
||||||
|
top: 11px;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-family: 'din-regular', sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.contributorName {
|
.contributorName {
|
||||||
display: none;
|
|
||||||
position: absolute;
|
|
||||||
background: black;
|
|
||||||
text-align: center;
|
|
||||||
color: white;
|
|
||||||
border-radius: 2px;
|
|
||||||
font-family: din-regular;
|
font-family: din-regular;
|
||||||
line-height: 15px;
|
margin-top: 20px;
|
||||||
font-size: 12px;
|
display: inline-block;
|
||||||
padding: 3px 5px 2px;
|
vertical-align: middle;
|
||||||
|
width: 97px;
|
||||||
|
padding: 0 8px 0 4px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
margin-top: 36px;
|
overflow: hidden;
|
||||||
margin-left: -32px;
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.contributor div:before {
|
.mapCount {
|
||||||
content: '';
|
padding:17px 38px 17px 0;
|
||||||
position: absolute;
|
width: 22px;
|
||||||
top: 128%;
|
text-align: right;
|
||||||
left: 13px;
|
|
||||||
margin-top: -30px;
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
border-bottom: 4px solid #000000;
|
|
||||||
border-left: 5px solid transparent;
|
|
||||||
border-right: 5px solid transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.linkItem.mapCount {
|
.mapCountIcon {
|
||||||
margin-left: 12px;
|
|
||||||
width: 24px;
|
|
||||||
padding:17px 0 17px 36px;
|
|
||||||
}
|
|
||||||
.linkItem.mapCount .mapCountIcon {
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 8px;
|
top: 8px;
|
||||||
left: 0;
|
right: 0;
|
||||||
width: 32px;
|
width: 32px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
background-image: url(<%= asset_data_uri('map32_sprite.png') %>);
|
background-image: url(<%= asset_data_uri('map32_sprite.png') %>);
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: 0 0;
|
background-position: 0 0;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
opacity: 0.6;
|
||||||
}
|
}
|
||||||
.linkItem.mapCount:hover .mapCountIcon {
|
|
||||||
|
&:hover .mapCountIcon {
|
||||||
background-position: 0 -32px;
|
background-position: 0 -32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.linkItem.mapCount:hover .hoverTip {
|
.tip, .hoverTip {
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.CardOnGraph .mapCount .tip, .CardonGraph .mapCount .hoverTip {
|
|
||||||
top: 44px;
|
top: 44px;
|
||||||
left: 0px;
|
right: 0px;
|
||||||
font-size: 12px !important;
|
font-size: 12px !important;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 26px;
|
||||||
|
right: 10px;
|
||||||
|
margin-top: -30px;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-bottom: 4px solid $mid-gray;
|
||||||
|
border-left: 5px solid transparent;
|
||||||
|
border-right: 5px solid transparent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.hoverTip {
|
.hoverTip {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
font-family: 'din-regular';
|
font-family: 'din-regular';
|
||||||
top: 44px;
|
top: 44px;
|
||||||
left: 0px;
|
|
||||||
font-size: 12px !important;
|
font-size: 12px !important;
|
||||||
display: none;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background: black;
|
background: $mid-gray;
|
||||||
color: white;
|
color: white;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
line-height: 17px;
|
line-height: 17px;
|
||||||
|
@ -278,21 +334,15 @@
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tip a {
|
||||||
.CardOnGraph .mapCount .tip:before, .CardOnGraph .mapCount .hoverTip:before {
|
color: white;
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: 26px;
|
|
||||||
left: 10px;
|
|
||||||
margin-top: -30px;
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
border-bottom: 4px solid #000000;
|
|
||||||
border-left: 5px solid transparent;
|
|
||||||
border-right: 5px solid transparent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.CardOnGraph .mapCount .tip li {
|
.tip a:hover {
|
||||||
|
color: #757575;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tip li {
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
@ -305,49 +355,34 @@
|
||||||
line-height: 14px;
|
line-height: 14px;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.CardOnGraph .mapCount li.hideExtra {
|
|
||||||
display: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.showMore {
|
.synapseCount {
|
||||||
cursor: pointer;
|
width: 22px;
|
||||||
color: #4FC059;
|
padding:17px 38px 17px 0;
|
||||||
}
|
text-align: right;
|
||||||
|
margin-right: 4px;
|
||||||
|
|
||||||
.mapCount .tip a {
|
.synapseCountIcon {
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mapCount .tip a:hover {
|
|
||||||
color: #757575;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.linkItem.synapseCount {
|
|
||||||
margin-left: 2px;
|
|
||||||
width: 24px;
|
|
||||||
padding:17px 0 17px 32px;
|
|
||||||
}
|
|
||||||
.linkItem.synapseCount .synapseCountIcon {
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 8px;
|
top: 8px;
|
||||||
left: 0;
|
right: 0;
|
||||||
width: 32px;
|
width: 32px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
background-image: url(<%= asset_data_uri('synapse32_sprite.png') %>);
|
background-image: url(<%= asset_data_uri('synapse32_sprite.png') %>);
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: 0 0;
|
background-position: 0 0;
|
||||||
|
opacity: 0.6;
|
||||||
}
|
}
|
||||||
.linkItem.synapseCount:hover .synapseCountIcon {
|
hover .synapseCountIcon {
|
||||||
background-position: 0 -32px;
|
background-position: 0 -32px;
|
||||||
}
|
}
|
||||||
|
.tip {
|
||||||
.CardOnGraph .synapseCount .tip {
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background: black;
|
background: $mid-gray;
|
||||||
width: auto;
|
width: auto;
|
||||||
top: 44px;
|
top: 44px;
|
||||||
|
right: 0px;
|
||||||
color: white;
|
color: white;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
|
@ -358,22 +393,28 @@
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
.CardOnGraph .synapseCount:hover .tip {
|
.tip:before {
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.CardOnGraph .synapseCount .tip:before {
|
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
margin-top: -8px;
|
margin-top: -8px;
|
||||||
margin-left: 6px;
|
right: 12px;
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
border-bottom: 4px solid black;
|
border-bottom: 4px solid $mid-gray;
|
||||||
border-left: 5px solid transparent;
|
border-left: 5px solid transparent;
|
||||||
border-right: 5px solid transparent;
|
border-right: 5px solid transparent;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.showMore {
|
||||||
|
cursor: pointer;
|
||||||
|
color: #4FC059;
|
||||||
|
}
|
||||||
|
|
||||||
|
.linkItem.mapPerm {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
.mapPerm {
|
.mapPerm {
|
||||||
width: 32px;
|
width: 32px;
|
||||||
|
@ -396,13 +437,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.yourTopic .mapPerm:hover, .yourEdge .mapPerm:hover {
|
.yourTopic .mapPerm:hover, .yourEdge .mapPerm:hover {
|
||||||
background-image: url(<%= asset_data_uri('arrowperms_sprite.png') %>);
|
|
||||||
background-position: -32px 0;
|
|
||||||
cursor:pointer;
|
cursor:pointer;
|
||||||
}
|
}
|
||||||
.yourTopic .mapPerm.minimize, .yourEdge .mapPerm.minimize {
|
.yourTopic .mapPerm.minimize, .yourEdge .mapPerm.minimize {
|
||||||
background-image: url(<%= asset_data_uri('arrowperms_sprite.png') %>) !important;
|
|
||||||
background-position: 0 0;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.mapPerm .permissionSelect {
|
.mapPerm .permissionSelect {
|
||||||
|
@ -439,60 +476,52 @@ cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.CardOnGraph .metacodeTitle {
|
.CardOnGraph .metacodeTitle {
|
||||||
font-style: italic;
|
font-family: 'din-regular';
|
||||||
font-family: 'vinyl';
|
|
||||||
text-transform: uppercase;
|
|
||||||
position: absolute;
|
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
height:24px;
|
height: 26px;
|
||||||
font-size: 24px;
|
font-size: 18px;
|
||||||
display: none;
|
padding: 13px 24px 9px 24px;
|
||||||
width: 90%;
|
|
||||||
padding: 13px 0 9px 10%;
|
|
||||||
background-color: #E0E0E0;
|
|
||||||
color: #424242;
|
color: #424242;
|
||||||
|
width: 120px;
|
||||||
|
max-width: 120px;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.permission.canEdit .metacodeTitle {
|
.permission.canEdit .metacodeTitle {
|
||||||
cursor:pointer;
|
cursor:pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.permission.canEdit .expandMetacodeSelect {
|
.permission.canEdit .expandMetacodeSelect {
|
||||||
position: absolute;
|
position: relative;
|
||||||
top: 16px;
|
top: 2px;
|
||||||
right: 16px;
|
left: 4px;
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
background-image: url(<%= asset_data_uri('arrowright_sprite.png') %>);
|
background-image: url(<%= asset_data_uri('arrowright_sprite.png') %>);
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: 0 -32px;
|
background-position: 0 -32px;
|
||||||
|
display: inline-block;
|
||||||
|
-webkit-transform: rotate(90deg);
|
||||||
|
transform: rotate(90deg);
|
||||||
}
|
}
|
||||||
.permission.canEdit .minimize .expandMetacodeSelect {
|
.permission.canEdit .minimize .expandMetacodeSelect {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.CardOnGraph .metacodeImage {
|
.CardOnGraph .metacodeName {
|
||||||
cursor:move;
|
display: inline-block;
|
||||||
width:46px;
|
|
||||||
height:46px;
|
|
||||||
position:absolute;
|
|
||||||
left:-23px;
|
|
||||||
top:0;
|
|
||||||
background-size:46px 46px;
|
|
||||||
background-position:0 0;
|
|
||||||
background-repeat:no-repeat;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#metacodeOptions {
|
|
||||||
display:none;
|
|
||||||
}
|
|
||||||
.CardOnGraph .metacodeSelect {
|
.CardOnGraph .metacodeSelect {
|
||||||
display:none;
|
display:none;
|
||||||
width:auto;
|
width:auto;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
position: absolute;
|
|
||||||
background: #EAEAEA;
|
background: #EAEAEA;
|
||||||
left: 300px;
|
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
position: absolute;
|
||||||
|
top: 48px;
|
||||||
|
box-shadow: 2px 2px 2px rgba(125, 125, 125, 0.23), -2px -1px 3px rgba(125, 125, 125, 0.16);
|
||||||
}
|
}
|
||||||
.CardOnGraph .metacodeSelect ul {
|
.CardOnGraph .metacodeSelect ul {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -580,15 +609,14 @@ background-color: #E0E0E0;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.CardOnGraph .hoverForTip:hover .tip, .mapCard .hoverForTip:hover .tip, #mapContribs:hover .tip {
|
.CardOnGraph .hoverForTip:hover .tip, #mapContribs:hover .tip {
|
||||||
display:block;
|
display:block;
|
||||||
}
|
}
|
||||||
.CardOnGraph .tip, .mapCard .tip {
|
.CardOnGraph .tip {
|
||||||
display:none;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background: black;
|
background: $mid-gray;
|
||||||
top: 35px;
|
top: 35px;
|
||||||
left: 0;
|
right: 0;
|
||||||
color: white;
|
color: white;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
font-size:15px !important;
|
font-size:15px !important;
|
||||||
|
@ -597,21 +625,18 @@ background-color: #E0E0E0;
|
||||||
z-index:100;
|
z-index:100;
|
||||||
}
|
}
|
||||||
|
|
||||||
#embedlyLink {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
#embedlyLinkLoader {
|
#embedlyLinkLoader {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
width: 28px;
|
width: 28px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.CardOnGraph .attachments {
|
.CardOnGraph .link-adder {
|
||||||
border-top: 1px solid #BDBDBD;
|
|
||||||
width:100%;
|
width:100%;
|
||||||
height:47px;
|
height:47px;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.attachments a {
|
.link-adder a {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
@ -670,9 +695,9 @@ background-color: #E0E0E0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#addLinkInput input{
|
#addLinkInput input{
|
||||||
padding: 9px 7px 9px 31px;
|
padding: 9px 27px 9px 31px;
|
||||||
height: 12px;
|
height: 12px;
|
||||||
width: 198px;
|
width: 210px;
|
||||||
margin: 0 0 0 0;
|
margin: 0 0 0 0;
|
||||||
border: none;
|
border: none;
|
||||||
outline: none;
|
outline: none;
|
||||||
|
@ -726,7 +751,6 @@ font-family: 'din-regular', helvetica, sans-serif;
|
||||||
-moz-border-radius-bottomright: 8px;
|
-moz-border-radius-bottomright: 8px;
|
||||||
-webkit-border-bottom-right-radius: 8px;
|
-webkit-border-bottom-right-radius: 8px;
|
||||||
border-bottom-right-radius: 8px;
|
border-bottom-right-radius: 8px;
|
||||||
display: none;
|
|
||||||
margin: 8px;
|
margin: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -813,10 +837,10 @@ font-family: 'din-regular', helvetica, sans-serif;
|
||||||
line-height: 16px;
|
line-height: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.canEdit #edit_synapse_desc:hover {
|
.canEdit span.titleWrapper:hover {
|
||||||
background-image: url(<%= asset_data_uri('edit.png') %>);
|
background-image: url(<%= asset_data_uri('edit.png') %>);
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: 164px center;
|
background-position: 95% 95%;
|
||||||
cursor: text;
|
cursor: text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -940,124 +964,14 @@ font-family: 'din-regular', helvetica, sans-serif;
|
||||||
background-position: 0 -24px;
|
background-position: 0 -24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Map Cards */
|
|
||||||
|
|
||||||
.map {
|
|
||||||
display:inline-block;
|
|
||||||
width:220px;
|
|
||||||
height:340px;
|
|
||||||
font-size: 12px;
|
|
||||||
text-align: left;
|
|
||||||
overflow: visible;
|
|
||||||
background: #424242;
|
|
||||||
border-radius:2px;
|
|
||||||
margin:16px 16px 16px 19px;
|
|
||||||
box-shadow: 0px 3px 3px rgba(0,0,0,0.23), 0 3px 3px rgba(0,0,0,0.16);
|
|
||||||
}
|
|
||||||
|
|
||||||
.mapCard {
|
|
||||||
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
|
|
||||||
display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
|
|
||||||
display: -ms-flexbox; /* TWEENER - IE 10 */
|
|
||||||
display: -webkit-flex; /* NEW - Chrome */
|
|
||||||
display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
-moz-box-orient: vertical;
|
|
||||||
-webkit-box-direction: normal;
|
|
||||||
-moz-box-direction: normal;
|
|
||||||
-ms-flex-direction: column;
|
|
||||||
-webkit-flex-direction: column;
|
|
||||||
flex-direction: column;
|
|
||||||
position:relative;
|
|
||||||
width:100%;
|
|
||||||
height:308px;
|
|
||||||
padding: 16px 0;
|
|
||||||
color:#F5F5F5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mapCard .title {
|
|
||||||
word-wrap: break-word;
|
|
||||||
font-size:18px;
|
|
||||||
line-height:22px;
|
|
||||||
height: 44px;
|
|
||||||
display:block;
|
|
||||||
padding: 0 16px;
|
|
||||||
text-align: center;
|
|
||||||
-webkit-box-flex: none; /* OLD - iOS 6-, Safari 3.1-6 */
|
|
||||||
-moz-box-flex: none; /* OLD - Firefox 19- */
|
|
||||||
-webkit-flex: none; /* Chrome */
|
|
||||||
-ms-flex: none; /* IE 10 */
|
|
||||||
flex: none; /* NEW, Spec - Opera 12.1, Firefox 20+ */
|
|
||||||
font-family: 'din-regular', sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mapCard .mapScreenshot {
|
|
||||||
width: 188px;
|
|
||||||
height: 126px;
|
|
||||||
padding: 8px 16px;
|
|
||||||
}
|
|
||||||
.mapCard .mapScreenshot img {
|
|
||||||
width: 188px;
|
|
||||||
height: 126px;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mapCard .scroll {
|
|
||||||
display:block;
|
|
||||||
-webkit-box-flex: 1; /* OLD - iOS 6-, Safari 3.1-6 */
|
|
||||||
-moz-box-flex: 1; /* OLD - Firefox 19- */
|
|
||||||
-webkit-flex: 1; /* Chrome */
|
|
||||||
-ms-flex: 1; /* IE 10 */
|
|
||||||
flex: 1; /* NEW, Spec - Opera 12.1, Firefox 20+ */
|
|
||||||
padding:0 16px 8px;
|
|
||||||
font-family: helvetica, sans-serif;
|
|
||||||
font-style: italic;
|
|
||||||
font-size: 12px;
|
|
||||||
word-wrap: break-word;
|
|
||||||
}
|
|
||||||
.mCS_no_scrollbar {
|
|
||||||
padding-right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mapCard .mapMetadata {
|
|
||||||
font-family: 'din-regular', sans-serif;
|
|
||||||
font-size: 12px;
|
|
||||||
position:relative;
|
|
||||||
border-top: 1px solid #BDBDBD;
|
|
||||||
-webkit-box-flex: none; /* OLD - iOS 6-, Safari 3.1-6 */
|
|
||||||
-moz-box-flex: none; /* OLD - Firefox 19- */
|
|
||||||
-webkit-flex: none; /* Chrome */
|
|
||||||
-ms-flex: none; /* IE 10 */
|
|
||||||
flex: none; /* NEW, Spec - Opera 12.1, Firefox 20+ */
|
|
||||||
}
|
|
||||||
|
|
||||||
.mapCard .metadataSection {
|
|
||||||
padding: 8px 16px 0 16px;
|
|
||||||
width: 78px;
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mapPermission {
|
|
||||||
font-family: 'din-medium', sans-serif;
|
|
||||||
}
|
|
||||||
.cCountColor {
|
|
||||||
font-family: 'din-medium', sans-serif;
|
|
||||||
color: #DB5D5D;
|
|
||||||
}
|
|
||||||
.tCountColor {
|
|
||||||
font-family: 'din-medium', sans-serif;
|
|
||||||
color: #4FC059;
|
|
||||||
}
|
|
||||||
.sCountColor {
|
|
||||||
font-family: 'din-medium', sans-serif;
|
|
||||||
color: #DAB539;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* mapper card */
|
/* mapper card */
|
||||||
|
|
||||||
.mapper {
|
.mapper {
|
||||||
float: left;
|
display: inline-block;
|
||||||
|
vertical-align: bottom;
|
||||||
width:220px;
|
width:220px;
|
||||||
height:340px;
|
height:340px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
@ -1065,7 +979,7 @@ font-family: 'din-regular', helvetica, sans-serif;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
background: #E0E0E0;
|
background: #E0E0E0;
|
||||||
border-radius:2px;
|
border-radius:2px;
|
||||||
margin:16px 16px 16px 19px;
|
margin:16px;
|
||||||
box-shadow: 0px 3px 3px rgba(0,0,0,0.23), 0 3px 3px rgba(0,0,0,0.16);
|
box-shadow: 0px 3px 3px rgba(0,0,0,0.23), 0 3px 3px rgba(0,0,0,0.16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1089,10 +1003,10 @@ font-family: 'din-regular', helvetica, sans-serif;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-top: 24px;
|
margin-top: 24px;
|
||||||
padding: 0 16px;
|
padding: 0 5%;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
width: 189px;
|
width: 90%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,21 +24,13 @@
|
||||||
backface-visibility: visible !important;
|
backface-visibility: visible !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#famousOverlay {
|
#yield {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
margin:0;
|
box-sizing: border-box;
|
||||||
z-index: 0;
|
padding-top: 92px;
|
||||||
}
|
overflow-y: auto;
|
||||||
|
|
||||||
#yield {
|
|
||||||
display:none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#toast {
|
|
||||||
display: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*.animations {
|
/*.animations {
|
||||||
|
@ -55,16 +47,6 @@
|
||||||
transition-timing-function: ease-in-out;
|
transition-timing-function: ease-in-out;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
.mapElement {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.mapPage .mapElement, .topicPage .mapElement {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.mapPage .mapElementHidden {
|
|
||||||
display:none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* loading */
|
/* loading */
|
||||||
|
|
||||||
#loading {
|
#loading {
|
||||||
|
@ -120,8 +102,6 @@
|
||||||
top: 10px;
|
top: 10px;
|
||||||
left: 24px;
|
left: 24px;
|
||||||
z-index:3;
|
z-index:3;
|
||||||
box-shadow: 0px 1px 1.5px rgba(0,0,0,0.12), 0 1px 1px rgba(0,0,0,0.24);
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
}
|
||||||
.explorePage .upperLeftUI {
|
.explorePage .upperLeftUI {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
|
@ -131,23 +111,24 @@
|
||||||
display:none;
|
display:none;
|
||||||
}
|
}
|
||||||
.homeButton {
|
.homeButton {
|
||||||
width: 40px;
|
|
||||||
height: 32px;
|
|
||||||
background-color: #757575;
|
|
||||||
background-image: url(<%= asset_data_uri('home_light.png') %>);
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: center center;
|
|
||||||
border-top-left-radius: 2px;
|
|
||||||
border-bottom-left-radius: 2px;
|
|
||||||
float:left;
|
float:left;
|
||||||
|
margin-right: 16px;
|
||||||
}
|
}
|
||||||
.homeButton:hover {
|
.homeButton:hover {
|
||||||
background-image: url(<%= asset_data_uri('home_light.png') %>);
|
|
||||||
}
|
}
|
||||||
.homeButton a {
|
.homeButton a {
|
||||||
display:block;
|
display:block;
|
||||||
width: 40px;
|
color: #747474;
|
||||||
height: 32px;
|
font-family: "vinyl", sans-serif;
|
||||||
|
font-style: italic;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 30px;
|
||||||
|
line-height: 38px;
|
||||||
|
}
|
||||||
|
.homeButton a:hover {
|
||||||
|
color: #616161;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* end upperLeftUI */
|
/* end upperLeftUI */
|
||||||
|
@ -187,43 +168,64 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.upperRightMapButtons {
|
.upperRightMapButtons {
|
||||||
top: -42px; /* puts it just offscreen */
|
right: 138px;
|
||||||
|
padding-right: 7px;
|
||||||
|
border-right: 1px solid #747474;
|
||||||
}
|
}
|
||||||
.mapPage .upperRightMapButtons, .topicPage .upperRightMapButtons {
|
.unauthenticated .upperRightMapButtons {
|
||||||
top: 0;
|
right: 115px;
|
||||||
|
padding-right: 0;
|
||||||
|
border-right: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.upperRightIcon {
|
.upperRightIcon {
|
||||||
width: 32px;
|
width: 32px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
background-image: url(<%= asset_data_uri('topright_sprite.png') %>);
|
background-image: url(<%= asset_path('topright_sprite.png') %>);
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebarFilterIcon {
|
.sidebarFilterIcon {
|
||||||
background-position: -64px 0;
|
background-position: -32px 0;
|
||||||
}
|
}
|
||||||
.sidebarForkIcon {
|
.sidebarForkIcon {
|
||||||
background-position: -96px 0;
|
background-position: -64px 0;
|
||||||
}
|
}
|
||||||
.addMap {
|
.addMap {
|
||||||
|
background-position: -96px 0;
|
||||||
|
}
|
||||||
|
.notificationsIcon {
|
||||||
background-position: -128px 0;
|
background-position: -128px 0;
|
||||||
margin-right:10px;
|
margin-right: 10px; // make it look more natural next to the account menu icon
|
||||||
|
}
|
||||||
|
.notificationsIcon:hover {
|
||||||
|
background-position: -128px -32px;
|
||||||
|
}
|
||||||
|
.importDialog:hover {
|
||||||
|
background-position: 0 -32px;
|
||||||
}
|
}
|
||||||
.sidebarFilterIcon:hover {
|
.sidebarFilterIcon:hover {
|
||||||
background-position: -64px -32px;
|
background-position: -32px -32px;
|
||||||
}
|
}
|
||||||
.sidebarForkIcon:hover {
|
.sidebarForkIcon:hover {
|
||||||
background-position: -96px -32px;
|
background-position: -64px -32px;
|
||||||
}
|
}
|
||||||
.addMap:hover {
|
.addMap:hover {
|
||||||
background-position: -128px -32px;
|
background-position: -96px -32px;
|
||||||
margin-right:10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* end upperRightUI */
|
/* end upperRightUI */
|
||||||
|
|
||||||
|
/* map wrapper */
|
||||||
|
.mapWrapper {
|
||||||
|
position:absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* end map wrapper */
|
||||||
|
|
||||||
/* yield */
|
/* yield */
|
||||||
|
|
||||||
|
@ -333,41 +335,26 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.fullWidthWrapper.withPartners {
|
.fullWidthWrapper.withPartners {
|
||||||
background: url(<%= asset_data_uri('homepage_bg_fade.png') %>) no-repeat center -300px;
|
background: url(<%= asset_path('homepage_bg_fade.png') %>) no-repeat center -300px;
|
||||||
}
|
}
|
||||||
.homeWrapper.homePartners {
|
.homeWrapper.homePartners {
|
||||||
padding: 64px 0 280px;
|
padding: 64px 0 280px;
|
||||||
height: 96px;
|
height: 96px;
|
||||||
background: url(<%= asset_data_uri('partner_logos.png') %>) no-repeat 0 64px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.github-fork-ribbon-wrapper {
|
|
||||||
display:none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.homePage .github-fork-ribbon-wrapper {
|
|
||||||
display: block;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* end home page */
|
/* end home page */
|
||||||
|
|
||||||
/* infoAndHelp */
|
/* infoAndHelp */
|
||||||
|
|
||||||
.mapPage .infoAndHelp, .topicPage .infoAndHelp {
|
.openCheatsheet .tooltipsAbove {
|
||||||
right: 70px;
|
right: 1px;
|
||||||
}
|
left: auto;
|
||||||
.mapPage .openCheatsheet .tooltipsAbove, .topicPage .openCheatsheet .tooltipsAbove {
|
|
||||||
left: 29px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.unauthenticated .homePage .infoAndHelp {
|
|
||||||
display:none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.infoAndHelp {
|
.infoAndHelp {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 20px;
|
bottom: 20px;
|
||||||
right: 20px;
|
right: 70px;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
width: auto;
|
width: auto;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
|
@ -380,7 +367,7 @@
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.openCheatsheet {
|
.openCheatsheet {
|
||||||
background-image: url(<%= asset_data_uri('help_sprite.png') %>);
|
background-image: url(<%= asset_path('help_sprite.png') %>);
|
||||||
background-repeat:no-repeat;
|
background-repeat:no-repeat;
|
||||||
}
|
}
|
||||||
.openCheatsheet:hover {
|
.openCheatsheet:hover {
|
||||||
|
@ -388,15 +375,27 @@
|
||||||
}
|
}
|
||||||
.mapInfoIcon {
|
.mapInfoIcon {
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 56px; /* puts it just offscreen */
|
background-image: url(<%= asset_path('mapinfo_sprite.png') %>);
|
||||||
background-image: url(<%= asset_data_uri('mapinfo_sprite.png') %>);
|
|
||||||
background-repeat:no-repeat;
|
background-repeat:no-repeat;
|
||||||
}
|
}
|
||||||
.mapInfoIcon:hover {
|
.mapInfoIcon:hover {
|
||||||
background-position: 0 -32px;
|
background-position: 0 -32px;
|
||||||
}
|
}
|
||||||
.mapPage .mapInfoIcon {
|
|
||||||
top: 0;
|
.starMap {
|
||||||
|
background-image: url(<%= asset_path('starmap_sprite.png') %>);
|
||||||
|
background-position: 0 0;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
width: 32px;
|
||||||
|
}
|
||||||
|
.starMap:hover {
|
||||||
|
background-position: 0 -32px !important;
|
||||||
|
}
|
||||||
|
.starMap.starred {
|
||||||
|
background-position: 0 -64px;
|
||||||
|
}
|
||||||
|
.starMap.starred:hover {
|
||||||
|
background-position: 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* end infoAndHelp */
|
/* end infoAndHelp */
|
||||||
|
@ -407,17 +406,10 @@
|
||||||
.mapControls {
|
.mapControls {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 24px;
|
bottom: 24px;
|
||||||
right:-32px; /* puts it just offscreen */
|
right:24px;
|
||||||
width:32px;
|
width:32px;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
}
|
}
|
||||||
.mapPage .mapControls, .topicPage .mapControls {
|
|
||||||
right: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.topicPage .zoomExtents {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mapControl {
|
.mapControl {
|
||||||
width:32px;
|
width:32px;
|
||||||
|
@ -432,31 +424,18 @@
|
||||||
z-index: 4;
|
z-index: 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.takeScreenshot {
|
|
||||||
margin-bottom: 5px;
|
|
||||||
border-radius: 2px;
|
|
||||||
background-image: url(<%= asset_data_uri 'screenshot_sprite.png' %>);
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.takeScreenshot:hover {
|
|
||||||
background-position: -32px 0;
|
|
||||||
}
|
|
||||||
.canEditMap .takeScreenshot {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.zoomExtents {
|
.zoomExtents {
|
||||||
margin-bottom:5px;
|
margin-bottom:5px;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
background-image: url(<%= asset_data_uri('extents_sprite.png') %>);
|
background-image: url(<%= asset_path('extents_sprite.png') %>);
|
||||||
}
|
}
|
||||||
|
|
||||||
.zoomExtents:hover {
|
.zoomExtents:hover {
|
||||||
background-position: -32px 0;
|
background-position: -32px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.zoomExtents:hover .tooltips, .zoomIn:hover .tooltips, .zoomOut:hover .tooltips, .takeScreenshot:hover .tooltips, .sidebarFilterIcon:hover .tooltipsUnder, .sidebarForkIcon:hover .tooltipsUnder, .addMap:hover .tooltipsUnder, .authenticated .sidebarAccountIcon:hover .tooltipsUnder,
|
.zoomExtents:hover .tooltips, .zoomIn:hover .tooltips, .zoomOut:hover .tooltips, .sidebarFilterIcon:hover .tooltipsUnder, .sidebarForkIcon:hover .tooltipsUnder, .notificationsIcon:hover .tooltipsUnder, .addMap:hover .tooltipsUnder, .authenticated .sidebarAccountIcon:hover .tooltipsUnder,
|
||||||
.mapInfoIcon:hover .tooltipsAbove, .openCheatsheet:hover .tooltipsAbove, .chat-button:hover .tooltips {
|
.mapInfoIcon:hover .tooltipsAbove, .openCheatsheet:hover .tooltipsAbove, .chat-button:hover .tooltips, .importDialog:hover .tooltipsUnder, .starMap:hover .tooltipsAbove, .openMetacodeSwitcher:hover .tooltipsAbove, .pinCarousel:not(.isPinned):hover .tooltipsAbove.helpPin, .pinCarousel.isPinned:hover .tooltipsAbove.helpUnpin {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -512,14 +491,44 @@
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.importDialog .tooltipsUnder {
|
||||||
|
left: -22px;
|
||||||
|
}
|
||||||
|
|
||||||
.sidebarFilterIcon .tooltipsUnder {
|
.sidebarFilterIcon .tooltipsUnder {
|
||||||
margin-left: -4px;
|
margin-left: -4px;
|
||||||
}
|
}
|
||||||
|
.notificationsIcon .tooltipsUnder {
|
||||||
|
left: -20px;
|
||||||
|
}
|
||||||
|
|
||||||
.sidebarForkIcon .tooltipsUnder {
|
.sidebarForkIcon .tooltipsUnder {
|
||||||
margin-left: -34px;
|
margin-left: -34px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.openMetacodeSwitcher .tooltipsAbove {
|
||||||
|
left: -50px;
|
||||||
|
top: -5px;
|
||||||
|
}
|
||||||
|
.pinCarousel .tooltipsAbove {
|
||||||
|
top: -5px;
|
||||||
|
}
|
||||||
|
.pinCarousel .tooltipsAbove.helpPin {
|
||||||
|
left: -24px;
|
||||||
|
}
|
||||||
|
.pinCarousel .tooltipsAbove.helpUnpin {
|
||||||
|
left: -14px;
|
||||||
|
}
|
||||||
|
.openMetacodeSwitcher .tooltipsAbove:after {
|
||||||
|
left: 50%;
|
||||||
|
}
|
||||||
|
.pinCarousel .tooltipsAbove.helpPin:after {
|
||||||
|
left: 46%;
|
||||||
|
}
|
||||||
|
.pinCarousel .tooltipsAbove.helpUnpin:after {
|
||||||
|
left: 42%;
|
||||||
|
}
|
||||||
|
|
||||||
.sidebarForkIcon div:after{
|
.sidebarForkIcon div:after{
|
||||||
left: 45%;
|
left: 45%;
|
||||||
}
|
}
|
||||||
|
@ -540,8 +549,11 @@
|
||||||
top: 10px;
|
top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.openCheatsheet .tooltipsAbove {
|
.starMap .tooltipsAbove {
|
||||||
left: -4px;
|
left: -2px;
|
||||||
|
}
|
||||||
|
.starMap.starred .tooltipsAbove {
|
||||||
|
left: -8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebarAccountIcon .tooltipsUnder {
|
.sidebarAccountIcon .tooltipsUnder {
|
||||||
|
@ -549,7 +561,7 @@
|
||||||
margin-top: 40px;
|
margin-top: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.zoomExtents div::after, .zoomIn div::after, .zoomOut div::after, .takeScreenshot div:after, .chat-button div.tooltips::after {
|
.zoomExtents div::after, .zoomIn div::after, .zoomOut div::after, .chat-button div.tooltips::after {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 57%;
|
top: 57%;
|
||||||
|
@ -562,7 +574,12 @@
|
||||||
border-bottom: 5px solid transparent;
|
border-bottom: 5px solid transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebarFilterIcon div:after, .sidebarForkIcon div:after, .addMap div:after, .sidebarAccountIcon .tooltipsUnder:after {
|
.addMap div:after,
|
||||||
|
.importDialog div:after,
|
||||||
|
.sidebarForkIcon div:after,
|
||||||
|
.sidebarFilterIcon div:after,
|
||||||
|
.notificationsIcon div:after,
|
||||||
|
.sidebarAccountIcon .tooltipsUnder:after {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 40%;
|
right: 40%;
|
||||||
|
@ -573,11 +590,17 @@
|
||||||
border-left: 5px solid transparent;
|
border-left: 5px solid transparent;
|
||||||
border-right: 5px solid transparent;
|
border-right: 5px solid transparent;
|
||||||
}
|
}
|
||||||
|
.notificationsIcon .unread-notifications-dot:after {
|
||||||
|
content: none;
|
||||||
|
}
|
||||||
.sidebarFilterIcon div:after {
|
.sidebarFilterIcon div:after {
|
||||||
right: 37% !important;
|
right: 37% !important;
|
||||||
}
|
}
|
||||||
|
.notificationsIcon div:after {
|
||||||
|
right: 46% !important;
|
||||||
|
}
|
||||||
|
|
||||||
.mapInfoIcon div:after, .openCheatsheet div:after {
|
.mapInfoIcon div:after, .openCheatsheet div:after, .starMap div:after, .openMetacodeSwitcher div:after, .pinCarousel div:after {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 76%;
|
top: 76%;
|
||||||
|
@ -591,7 +614,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.zoomIn {
|
.zoomIn {
|
||||||
background-image: url(<%= asset_data_uri('zoom_sprite.png') %>);
|
background-image: url(<%= asset_path('zoom_sprite.png') %>);
|
||||||
background-position: 0 /…0;
|
background-position: 0 /…0;
|
||||||
border-top-left-radius: 2px;
|
border-top-left-radius: 2px;
|
||||||
border-top-right-radius: 2px;
|
border-top-right-radius: 2px;
|
||||||
|
@ -600,7 +623,7 @@
|
||||||
background-position: -32px 0;
|
background-position: -32px 0;
|
||||||
}
|
}
|
||||||
.zoomOut {
|
.zoomOut {
|
||||||
background-image: url(<%= asset_data_uri('zoom_sprite.png') %>);
|
background-image: url(<%= asset_path('zoom_sprite.png') %>);
|
||||||
background-position:0 -32px;
|
background-position:0 -32px;
|
||||||
border-bottom-left-radius: 2px;
|
border-bottom-left-radius: 2px;
|
||||||
border-bottom-right-radius: 2px;
|
border-bottom-right-radius: 2px;
|
||||||
|
@ -611,48 +634,84 @@
|
||||||
|
|
||||||
/* end mapControls */
|
/* end mapControls */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* explore maps */
|
/* explore maps */
|
||||||
|
|
||||||
.exploreMapsBar {
|
#react-app {
|
||||||
z-index:2;
|
position: absolute;
|
||||||
background-color:#FAFAFA;
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.exploreMapsMenu {
|
#exploreMaps {
|
||||||
display: block;
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-top:52px;
|
overflow-y: auto;
|
||||||
height:42px;
|
}
|
||||||
background-color:#EEEEEE;
|
|
||||||
|
#exploreMaps > div {
|
||||||
|
margin: 110px auto 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.loadMore {
|
||||||
|
margin: 10px auto 20px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.requestInviteHeader {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
z-index:2;
|
||||||
|
background-color:#FAFAFA;
|
||||||
|
height: 52px;
|
||||||
box-shadow: 0px 3px 3px rgba(0,0,0,0.23), 0 3px 3px rgba(0,0,0,0.16);
|
box-shadow: 0px 3px 3px rgba(0,0,0,0.23), 0 3px 3px rgba(0,0,0,0.16);
|
||||||
}
|
}
|
||||||
|
|
||||||
.exploreMapsCenter {
|
#navBar {
|
||||||
z-index: 3 !important;
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.exploreMapsButton {
|
.navBarContainer {
|
||||||
|
z-index:2;
|
||||||
|
background-color:#FAFAFA;
|
||||||
|
height: 42px;
|
||||||
|
padding-top: 52px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navBarMenu {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height:42px;
|
||||||
|
background-color:#EEEEEE;
|
||||||
|
box-shadow: 0px 3px 3px rgba(0,0,0,0.23), 0 3px 3px rgba(0,0,0,0.16);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navBarCenter {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navBarButton {
|
||||||
color: #757575;
|
color: #757575;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-family: 'din-medium';
|
font-family: 'din-medium';
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
height: 14px;
|
padding: 0 8px;
|
||||||
padding: 14px 16px 12px 40px;
|
|
||||||
border-bottom: 2px solid rgba(0,0,0,0);
|
border-bottom: 2px solid rgba(0,0,0,0);
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
position:relative;
|
position:relative;
|
||||||
}
|
}
|
||||||
.exploreMapsButton:hover, .exploreMapsButton.active {
|
.navBarButton:hover, .navBarButton.active {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: #424242;
|
color: #424242;
|
||||||
border-bottom: 2px solid #00BCD4;
|
border-bottom: 2px solid #00BCD4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.exploreMapsButton.mapperButton {
|
.navBarButton.mapperButton {
|
||||||
height: 40px;
|
height: 40px;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
@ -669,34 +728,70 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.exploreMapsButton .exploreMapsIcon {
|
.navBarButton .navBarIcon {
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
width:32px;
|
width:32px;
|
||||||
height:32px;
|
height:32px;
|
||||||
position:absolute;
|
margin-top:5px;
|
||||||
top:5px;
|
margin-left:5px;
|
||||||
left:5px;
|
margin-right: 5px;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
.exploreMapsCenter .myMaps .exploreMapsIcon {
|
|
||||||
background-image: url(<%= asset_data_uri 'exploremaps_sprite.png' %>);
|
.navBarLinkText {
|
||||||
background-position: 0 0;
|
padding: 11px 0 12px 0;
|
||||||
|
display: inline-block;
|
||||||
}
|
}
|
||||||
.exploreMapsCenter .activeMaps .exploreMapsIcon {
|
|
||||||
background-image: url(<%= asset_data_uri 'exploremaps_sprite.png' %>);
|
.navBarCenter .authedApps .navBarIcon {
|
||||||
background-position: -32px 0;
|
background-image: url(<%= asset_path('user_sprite.png') %>);
|
||||||
}
|
|
||||||
.exploreMapsCenter .featuredMaps .exploreMapsIcon {
|
|
||||||
background-image: url(<%= asset_data_uri 'exploremaps_sprite.png' %>);
|
|
||||||
background-position: -64px 0;
|
|
||||||
}
|
|
||||||
.myMaps:hover .exploreMapsIcon, .myMaps.active .exploreMapsIcon {
|
|
||||||
background-position: 0 -32px;
|
background-position: 0 -32px;
|
||||||
}
|
}
|
||||||
.activeMaps:hover .exploreMapsIcon, .activeMaps.active .exploreMapsIcon {
|
.navBarCenter .myMaps .navBarIcon {
|
||||||
|
background-image: url(<%= asset_path 'exploremaps_sprite.png' %>);
|
||||||
|
background-position: -32px 0;
|
||||||
|
}
|
||||||
|
.navBarCenter .sharedMaps .navBarIcon {
|
||||||
|
background-image: url(<%= asset_path 'exploremaps_sprite.png' %>);
|
||||||
|
background-position: -128px 0;
|
||||||
|
}
|
||||||
|
.navBarCenter .activeMaps .navBarIcon {
|
||||||
|
background-image: url(<%= asset_path 'exploremaps_sprite.png' %>);
|
||||||
|
background-position: 0 0;
|
||||||
|
}
|
||||||
|
.navBarCenter .featuredMaps .navBarIcon {
|
||||||
|
background-image: url(<%= asset_path 'exploremaps_sprite.png' %>);
|
||||||
|
background-position: -96px 0;
|
||||||
|
}
|
||||||
|
.navBarCenter .starredMaps .navBarIcon {
|
||||||
|
background-image: url(<%= asset_path 'exploremaps_sprite.png' %>);
|
||||||
|
background-position: -96px 0;
|
||||||
|
}
|
||||||
|
.navBarCenter .notificationsLink .navBarIcon {
|
||||||
|
background-image: url(<%= asset_path 'topright_sprite.png' %>);
|
||||||
|
background-position: -128px 0;
|
||||||
|
}
|
||||||
|
.authedApps:hover .navBarIcon, .authedApps.active .navBarIcon {
|
||||||
|
background-position-x: -32px;
|
||||||
|
}
|
||||||
|
.myMaps:hover .navBarIcon, .myMaps.active .navBarIcon {
|
||||||
background-position: -32px -32px;
|
background-position: -32px -32px;
|
||||||
}
|
}
|
||||||
.featuredMaps:hover .exploreMapsIcon, .featuredMaps.active .exploreMapsIcon {
|
.activeMaps:hover .navBarIcon, .activeMaps.active .navBarIcon {
|
||||||
background-position: -64px -32px;
|
background-position: 0 -32px;
|
||||||
|
}
|
||||||
|
.featuredMaps:hover .navBarIcon, .featuredMaps.active .navBarIcon {
|
||||||
|
background-position: -96px -32px;
|
||||||
|
}
|
||||||
|
.starredMaps:hover .navBarIcon, .starredMaps.active .navBarIcon {
|
||||||
|
background-position: -96px -32px;
|
||||||
|
}
|
||||||
|
.sharedMaps:hover .navBarIcon, .sharedMaps.active .navBarIcon {
|
||||||
|
background-position: -128px -32px;
|
||||||
|
}
|
||||||
|
.notificationsLink:hover .navBarIcon, .notificationsLink.active .navBarIcon {
|
||||||
|
background-position-y: -32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mapsWrapper {
|
.mapsWrapper {
|
||||||
|
@ -706,10 +801,31 @@
|
||||||
|
|
||||||
/* end explore maps */
|
/* end explore maps */
|
||||||
|
|
||||||
|
/* instructions */
|
||||||
|
|
||||||
|
#instructions {
|
||||||
|
width: 220px;
|
||||||
|
height: 80px;
|
||||||
|
font-family: 'din-regular', helvetica, sans-serif;
|
||||||
|
font-size: 32px;
|
||||||
|
text-align: center;
|
||||||
|
color: #999999;
|
||||||
|
z-index: 0;
|
||||||
|
top: 50%;
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
margin-top: -40px;
|
||||||
|
margin-left: -110px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* end instructions */
|
||||||
|
|
||||||
/* toast */
|
/* toast */
|
||||||
|
|
||||||
.toast {
|
.toast {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 20px;
|
||||||
|
left: 20px;
|
||||||
background-color: #323232;
|
background-color: #323232;
|
||||||
color: #F5F5F5;
|
color: #F5F5F5;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
|
|
263
app/assets/stylesheets/emoji-mart-0.3.5.css
Normal file
|
@ -0,0 +1,263 @@
|
||||||
|
.emoji-mart,
|
||||||
|
.emoji-mart * {
|
||||||
|
box-sizing: border-box;
|
||||||
|
line-height: 1.15;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
display: inline-block;
|
||||||
|
color: #222427;
|
||||||
|
border: 1px solid #d9d9d9;
|
||||||
|
border-radius: 5px;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart .emoji-mart-emoji {
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-bar:first-child {
|
||||||
|
border-top-left-radius: 5px;
|
||||||
|
border-top-right-radius: 5px;
|
||||||
|
}
|
||||||
|
.emoji-mart-bar:last-child {
|
||||||
|
border-bottom-left-radius: 5px;
|
||||||
|
border-bottom-right-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-anchors {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 0 6px;
|
||||||
|
color: #858585;
|
||||||
|
line-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-anchor {
|
||||||
|
position: relative;
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
padding: 12px 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: color .1s ease-out;
|
||||||
|
}
|
||||||
|
.emoji-mart-anchor:hover,
|
||||||
|
.emoji-mart-anchor-selected {
|
||||||
|
color: #464646;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-anchor-selected .emoji-mart-anchor-bar {
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-anchor-bar {
|
||||||
|
position: absolute;
|
||||||
|
bottom: -3px; left: 0;
|
||||||
|
width: 100%; height: 3px;
|
||||||
|
background-color: #464646;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-anchors i {
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-anchors svg {
|
||||||
|
fill: currentColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-scroll {
|
||||||
|
overflow-y: scroll;
|
||||||
|
height: 270px;
|
||||||
|
padding: 0 6px 6px 6px;
|
||||||
|
border: solid #d9d9d9;
|
||||||
|
border-width: 1px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-search {
|
||||||
|
font-size: 16px;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
padding: .2em .6em;
|
||||||
|
margin-top: 6px;
|
||||||
|
border-radius: 25px;
|
||||||
|
border: 1px solid #d9d9d9;
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-category .emoji-mart-emoji span {
|
||||||
|
z-index: 1;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-category .emoji-mart-emoji:hover:before {
|
||||||
|
z-index: 0;
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0; left: 0;
|
||||||
|
width: 100%; height: 100%;
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
border-radius: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-category-label {
|
||||||
|
z-index: 2;
|
||||||
|
position: relative;
|
||||||
|
position: -webkit-sticky;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-category-label span {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
font-weight: 500;
|
||||||
|
padding: 5px 6px;
|
||||||
|
background-color: #fff;
|
||||||
|
background-color: rgba(255, 255, 255, .95);
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-emoji {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-no-results {
|
||||||
|
font-size: 14px;
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 70px;
|
||||||
|
color: #858585;
|
||||||
|
}
|
||||||
|
.emoji-mart-no-results span {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-preview {
|
||||||
|
position: relative;
|
||||||
|
height: 70px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-preview-emoji,
|
||||||
|
.emoji-mart-preview-data,
|
||||||
|
.emoji-mart-preview-skins {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-preview-emoji {
|
||||||
|
left: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-preview-data {
|
||||||
|
left: 68px; right: 12px;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-preview-skins {
|
||||||
|
right: 30px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-preview-name {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-preview-shortname {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
.emoji-mart-preview-shortname + .emoji-mart-preview-shortname,
|
||||||
|
.emoji-mart-preview-shortname + .emoji-mart-preview-emoticon,
|
||||||
|
.emoji-mart-preview-emoticon + .emoji-mart-preview-emoticon {
|
||||||
|
margin-left: .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-preview-emoticon {
|
||||||
|
font-size: 11px;
|
||||||
|
color: #bbb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-title span {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-title .emoji-mart-emoji {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-title-label {
|
||||||
|
color: #999A9C;
|
||||||
|
font-size: 26px;
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-skin-swatches {
|
||||||
|
font-size: 0;
|
||||||
|
padding: 2px 0;
|
||||||
|
border: 1px solid #d9d9d9;
|
||||||
|
border-radius: 12px;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-skin-swatches-opened .emoji-mart-skin-swatch {
|
||||||
|
width: 16px;
|
||||||
|
padding: 0 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-skin-swatches-opened .emoji-mart-skin-swatch-selected:after {
|
||||||
|
opacity: .75;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-skin-swatch {
|
||||||
|
display: inline-block;
|
||||||
|
width: 0;
|
||||||
|
vertical-align: middle;
|
||||||
|
transition-property: width, padding;
|
||||||
|
transition-duration: .125s;
|
||||||
|
transition-timing-function: ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-skin-swatch:nth-child(1) { transition-delay: 0 }
|
||||||
|
.emoji-mart-skin-swatch:nth-child(2) { transition-delay: .03s }
|
||||||
|
.emoji-mart-skin-swatch:nth-child(3) { transition-delay: .06s }
|
||||||
|
.emoji-mart-skin-swatch:nth-child(4) { transition-delay: .09s }
|
||||||
|
.emoji-mart-skin-swatch:nth-child(5) { transition-delay: .12s }
|
||||||
|
.emoji-mart-skin-swatch:nth-child(6) { transition-delay: .15s }
|
||||||
|
|
||||||
|
.emoji-mart-skin-swatch-selected {
|
||||||
|
position: relative;
|
||||||
|
width: 16px;
|
||||||
|
padding: 0 2px;
|
||||||
|
}
|
||||||
|
.emoji-mart-skin-swatch-selected:after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 50%; left: 50%;
|
||||||
|
width: 4px; height: 4px;
|
||||||
|
margin: -2px 0 0 -2px;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 100%;
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity .2s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-skin {
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%; padding-top: 100%;
|
||||||
|
max-width: 12px;
|
||||||
|
border-radius: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-skin-tone-1 { background-color: #ffc93a }
|
||||||
|
.emoji-mart-skin-tone-2 { background-color: #fadcbc }
|
||||||
|
.emoji-mart-skin-tone-3 { background-color: #e0bb95 }
|
||||||
|
.emoji-mart-skin-tone-4 { background-color: #bf8f68 }
|
||||||
|
.emoji-mart-skin-tone-5 { background-color: #9b643d }
|
||||||
|
.emoji-mart-skin-tone-6 { background-color: #594539 }
|
|
@ -1,77 +0,0 @@
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
*
|
|
||||||
* Owner: mark@famo.us
|
|
||||||
* @license MPL 2.0
|
|
||||||
* @copyright Famous Industries, Inc. 2014
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
html {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
overflow: hidden;
|
|
||||||
-webkit-transform-style: preserve-3d;
|
|
||||||
transform-style: preserve-3d;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
-webkit-transform-style: preserve-3d;
|
|
||||||
transform-style: preserve-3d;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
-webkit-tap-highlight-color: transparent;
|
|
||||||
-webkit-perspective: 0;
|
|
||||||
perspective: none;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.famous-container, .famous-group {
|
|
||||||
position: absolute;
|
|
||||||
top: 0px;
|
|
||||||
left: 0px;
|
|
||||||
bottom: 0px;
|
|
||||||
right: 0px;
|
|
||||||
overflow: visible;
|
|
||||||
-webkit-transform-style: preserve-3d;
|
|
||||||
transform-style: preserve-3d;
|
|
||||||
-webkit-backface-visibility: visible;
|
|
||||||
backface-visibility: visible;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.famous-group {
|
|
||||||
width: 0px;
|
|
||||||
height: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
-webkit-transform-style: preserve-3d;
|
|
||||||
transform-style: preserve-3d;
|
|
||||||
}
|
|
||||||
|
|
||||||
.famous-surface {
|
|
||||||
position: absolute;
|
|
||||||
-webkit-transform-origin: center center;
|
|
||||||
transform-origin: center center;
|
|
||||||
-webkit-backface-visibility: hidden;
|
|
||||||
backface-visibility: hidden;
|
|
||||||
-webkit-transform-style: flat;
|
|
||||||
transform-style: preserve-3d; /* performance */
|
|
||||||
-webkit-box-sizing: border-box;
|
|
||||||
-moz-box-sizing: border-box;
|
|
||||||
-webkit-tap-highlight-color: transparent;
|
|
||||||
pointer-events: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.famous-container-group {
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
|
@ -1,11 +1,9 @@
|
||||||
/* =USERVOICE ICON DEFINE
|
.unauthenticated .feedback-icon {
|
||||||
--------------------------------------------------------*/
|
|
||||||
|
|
||||||
.unauthenticated .uv-icon {
|
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.uv-icon.uv-bottom-left {
|
.feedback-icon {
|
||||||
|
position: fixed;
|
||||||
background-image: url(<%= asset_data_uri 'feedback_sprite.png' %>);
|
background-image: url(<%= asset_data_uri 'feedback_sprite.png' %>);
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
color:#FFFFFF;
|
color:#FFFFFF;
|
||||||
|
@ -20,6 +18,8 @@ div.uv-icon.uv-bottom-left {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.uv-icon.uv-bottom-left:hover {
|
.feedback-icon:hover {
|
||||||
background-position: 0 -110px;
|
background-position: 0 -110px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,140 +0,0 @@
|
||||||
/*!
|
|
||||||
* "Fork me on GitHub" CSS ribbon v0.1.1 | MIT License
|
|
||||||
* https://github.com/simonwhitaker/github-fork-ribbon-css
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Left will inherit from right (so we don't need to duplicate code) */
|
|
||||||
.github-fork-ribbon {
|
|
||||||
/* The right and left classes determine the side we attach our banner to */
|
|
||||||
position: absolute;
|
|
||||||
|
|
||||||
/* Add a bit of padding to give some substance outside the "stitching" */
|
|
||||||
padding: 2px 0;
|
|
||||||
|
|
||||||
/* Set the base colour */
|
|
||||||
background-color: #9150bc;
|
|
||||||
|
|
||||||
/* Set a gradient: transparent black at the top to almost-transparent black at the bottom */
|
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0)), to(rgba(0, 0, 0, 0.15)));
|
|
||||||
background-image: -webkit-linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.15));
|
|
||||||
background-image: -moz-linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.15));
|
|
||||||
background-image: -ms-linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.15));
|
|
||||||
background-image: -o-linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.15));
|
|
||||||
background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.15));
|
|
||||||
|
|
||||||
/* Add a drop shadow */
|
|
||||||
-webkit-box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.5);
|
|
||||||
-moz-box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.5);
|
|
||||||
box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.5);
|
|
||||||
|
|
||||||
/* Set the font */
|
|
||||||
font: 700 13px "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
||||||
|
|
||||||
z-index: 9999;
|
|
||||||
pointer-events: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.github-fork-ribbon a,
|
|
||||||
.github-fork-ribbon a:hover {
|
|
||||||
/* Set the text properties */
|
|
||||||
color: #fff;
|
|
||||||
text-decoration: none;
|
|
||||||
text-shadow: 0 -1px rgba(0, 0, 0, 0.5);
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
/* Set the geometry. If you fiddle with these you'll also need
|
|
||||||
to tweak the top and right values in .github-fork-ribbon. */
|
|
||||||
width: 200px;
|
|
||||||
line-height: 20px;
|
|
||||||
|
|
||||||
/* Set the layout properties */
|
|
||||||
display: inline-block;
|
|
||||||
padding: 2px 0;
|
|
||||||
|
|
||||||
/* Add "stitching" effect */
|
|
||||||
border-width: 1px 0;
|
|
||||||
border-style: dotted;
|
|
||||||
border-color: #fff;
|
|
||||||
border-color: rgba(255, 255, 255, 0.7);
|
|
||||||
}
|
|
||||||
|
|
||||||
.github-fork-ribbon-wrapper {
|
|
||||||
width: 150px;
|
|
||||||
height: 150px;
|
|
||||||
position: absolute;
|
|
||||||
overflow: hidden;
|
|
||||||
top: 0;
|
|
||||||
z-index: 9999;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.github-fork-ribbon-wrapper.fixed {
|
|
||||||
position: fixed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.github-fork-ribbon-wrapper.left {
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.github-fork-ribbon-wrapper.right {
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.github-fork-ribbon-wrapper.left-bottom {
|
|
||||||
position: fixed;
|
|
||||||
top: inherit;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.github-fork-ribbon-wrapper.right-bottom {
|
|
||||||
position: fixed;
|
|
||||||
top: inherit;
|
|
||||||
bottom: 0;
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.github-fork-ribbon-wrapper.right .github-fork-ribbon {
|
|
||||||
top: 42px;
|
|
||||||
right: -43px;
|
|
||||||
|
|
||||||
-webkit-transform: rotate(45deg);
|
|
||||||
-moz-transform: rotate(45deg);
|
|
||||||
-ms-transform: rotate(45deg);
|
|
||||||
-o-transform: rotate(45deg);
|
|
||||||
transform: rotate(45deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.github-fork-ribbon-wrapper.left .github-fork-ribbon {
|
|
||||||
top: 42px;
|
|
||||||
left: -43px;
|
|
||||||
|
|
||||||
-webkit-transform: rotate(-45deg);
|
|
||||||
-moz-transform: rotate(-45deg);
|
|
||||||
-ms-transform: rotate(-45deg);
|
|
||||||
-o-transform: rotate(-45deg);
|
|
||||||
transform: rotate(-45deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.github-fork-ribbon-wrapper.left-bottom .github-fork-ribbon {
|
|
||||||
top: 80px;
|
|
||||||
left: -43px;
|
|
||||||
|
|
||||||
-webkit-transform: rotate(45deg);
|
|
||||||
-moz-transform: rotate(45deg);
|
|
||||||
-ms-transform: rotate(45deg);
|
|
||||||
-o-transform: rotate(45deg);
|
|
||||||
transform: rotate(45deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.github-fork-ribbon-wrapper.right-bottom .github-fork-ribbon {
|
|
||||||
top: 80px;
|
|
||||||
right: -43px;
|
|
||||||
|
|
||||||
-webkit-transform: rotate(-45deg);
|
|
||||||
-moz-transform: rotate(-45deg);
|
|
||||||
-ms-transform: rotate(-45deg);
|
|
||||||
-o-transform: rotate(-45deg);
|
|
||||||
transform: rotate(-45deg);
|
|
||||||
}
|
|
|
@ -1,348 +0,0 @@
|
||||||
.collaborator-video {
|
|
||||||
z-index: 1;
|
|
||||||
position: absolute;
|
|
||||||
width: 150px;
|
|
||||||
height: 150px;
|
|
||||||
cursor: default;
|
|
||||||
color: #FFF;
|
|
||||||
}
|
|
||||||
.collaborator-video .video-receive {
|
|
||||||
position: absolute;
|
|
||||||
width: 160px;
|
|
||||||
padding: 20px 20px 20px 170px;
|
|
||||||
background: #424242;
|
|
||||||
height: 110px;
|
|
||||||
border-top-left-radius: 75px;
|
|
||||||
border-bottom-left-radius: 75px;
|
|
||||||
border-top-right-radius: 2px;
|
|
||||||
border-bottom-right-radius: 2px;
|
|
||||||
}
|
|
||||||
.collaborator-video .video-receive .video-statement {
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
.collaborator-video .video-receive .btn-group .btn-yes {
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
.collaborator-video .video-receive .btn-group .btn-no {
|
|
||||||
background-color: #c04f4f;
|
|
||||||
}
|
|
||||||
.collaborator-video .video-receive .btn-group .btn-no:hover {
|
|
||||||
background-color: #A54242;
|
|
||||||
}
|
|
||||||
.collaborator-video .video-cutoff {
|
|
||||||
width: 150px;
|
|
||||||
height: 150px;
|
|
||||||
overflow: hidden;
|
|
||||||
border-radius: 75px;
|
|
||||||
z-index: 0;
|
|
||||||
position: relative;
|
|
||||||
-webkit-box-shadow: 0px 6px 3px rgba(0, 0, 0, 0.23), 10px 10px 10px rgba(0, 0, 0, 0.19);
|
|
||||||
-moz-box-shadow: 0px 6px 3px rgba(0, 0, 0, 0.23), 10px 10px 10px rgba(0, 0, 0, 0.19);
|
|
||||||
box-shadow: 0px 6px 3px rgba(0, 0, 0, 0.23), 10px 10px 10px rgba(0, 0, 0, 0.19);
|
|
||||||
}
|
|
||||||
.collaborator-video .video-cutoff video {
|
|
||||||
height: 150px;
|
|
||||||
margin-left: -25px;
|
|
||||||
}
|
|
||||||
.collaborator-video .video-cutoff .collaborator-video-avatar {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
-webkit-user-select: none;
|
|
||||||
-khtml-user-select: none;
|
|
||||||
-moz-user-select: none;
|
|
||||||
-o-user-select: none;
|
|
||||||
user-select: none;
|
|
||||||
-webkit-user-drag: none;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.collaborator-video .video-audio {
|
|
||||||
position: absolute;
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
top: 85%;
|
|
||||||
right: 0px;
|
|
||||||
cursor: pointer;
|
|
||||||
background: url(<%= asset_path 'audio_sprite.png' %>) no-repeat;
|
|
||||||
}
|
|
||||||
.collaborator-video .video-audio:hover {
|
|
||||||
background-position-x: -24px;
|
|
||||||
}
|
|
||||||
.collaborator-video .video-audio.active {
|
|
||||||
background-position-y: -24px;
|
|
||||||
}
|
|
||||||
.collaborator-video .video-video {
|
|
||||||
position: absolute;
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
top: 85%;
|
|
||||||
left: 0px;
|
|
||||||
cursor: pointer;
|
|
||||||
background: url(<%= asset_path 'camera_sprite.png' %>) no-repeat;
|
|
||||||
}
|
|
||||||
.collaborator-video .video-video:hover {
|
|
||||||
background-position-x: -24px;
|
|
||||||
}
|
|
||||||
.collaborator-video .video-video.active {
|
|
||||||
background-position-y: -24px;
|
|
||||||
}
|
|
||||||
.collaborator-video.my-video {
|
|
||||||
left: 30px;
|
|
||||||
top: 72px;
|
|
||||||
}
|
|
||||||
.chat-box {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
z-index: 1;
|
|
||||||
width: 300px;
|
|
||||||
float: right;
|
|
||||||
height: 100%;
|
|
||||||
background: #424242;
|
|
||||||
box-shadow: 0px 0px 16px 8px rgba(0, 0, 0, 0.23), -2px 10px 10px rgba(0, 0, 0, 0.19);
|
|
||||||
}
|
|
||||||
.chat-box .chat-button {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: -36px;
|
|
||||||
width: 36px;
|
|
||||||
height: 49px;
|
|
||||||
background: url(<%= asset_path 'junto.png' %>) no-repeat 2px 9px, url(<%= asset_path 'tray_tab.png' %>) no-repeat;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.chat-box .chat-button.active {
|
|
||||||
background: url(<%= asset_path 'junto_spinner_dark.gif' %>) no-repeat 2px 8px, url(<%= asset_path 'tray_tab.png' %>) no-repeat !important;
|
|
||||||
}
|
|
||||||
.chat-box .chat-button .chat-unread {
|
|
||||||
display: none;
|
|
||||||
background: #DAB539;
|
|
||||||
position: absolute;
|
|
||||||
top: -3px;
|
|
||||||
left: -11px;
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
border-radius: 11px;
|
|
||||||
border: 2px solid #424242;
|
|
||||||
color: #424242;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: bold;
|
|
||||||
line-height: 20px;
|
|
||||||
}
|
|
||||||
.chat-box .junto-header {
|
|
||||||
width: 100%;
|
|
||||||
padding: 16px 8px 16px 16px;
|
|
||||||
font-size: 16px;
|
|
||||||
text-align: left;
|
|
||||||
font-weight: bold;
|
|
||||||
background-color: #000000;
|
|
||||||
color: #f5f5f5;
|
|
||||||
box-shadow: 0px 6px 3px rgba(0, 0, 0, 0.23), 10px 10px 10px rgba(0, 0, 0, 0.19);
|
|
||||||
}
|
|
||||||
.chat-box .junto-header .cursor-toggle {
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
margin-right: 8px;
|
|
||||||
margin-top: -8px;
|
|
||||||
float: right;
|
|
||||||
background: url(<%= asset_path 'cursor_sprite.png' %>) no-repeat;
|
|
||||||
}
|
|
||||||
.chat-box .junto-header .cursor-toggle:hover {
|
|
||||||
background-position-x: -32px;
|
|
||||||
}
|
|
||||||
.chat-box .junto-header .cursor-toggle.active {
|
|
||||||
background-position-y: -32px;
|
|
||||||
}
|
|
||||||
.chat-box .junto-header .video-toggle {
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
margin-right: 32px;
|
|
||||||
margin-top: -8px;
|
|
||||||
float: right;
|
|
||||||
background: url(<%= asset_path 'video_sprite.png' %>) no-repeat;
|
|
||||||
}
|
|
||||||
.chat-box .junto-header .video-toggle:hover {
|
|
||||||
background-position-x: -32px;
|
|
||||||
}
|
|
||||||
.chat-box .junto-header .video-toggle.active {
|
|
||||||
background-position-y: -32px;
|
|
||||||
}
|
|
||||||
.chat-box .participants {
|
|
||||||
width: 100%;
|
|
||||||
min-height: 150px;
|
|
||||||
padding: 16px 0px 16px 0px;
|
|
||||||
text-align: left;
|
|
||||||
color: #f5f5f5;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
.chat-box .participants .conversation-live {
|
|
||||||
display: none;
|
|
||||||
padding: 5px 10px 5px 10px;
|
|
||||||
background: #c04f4f;
|
|
||||||
margin: 5px 10px;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
.chat-box .participants .conversation-live .call-action {
|
|
||||||
float: right;
|
|
||||||
cursor: pointer;
|
|
||||||
color: #EBFF00;
|
|
||||||
}
|
|
||||||
.chat-box .participants .conversation-live .leave {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.chat-box .participants.is-participating .conversation-live .leave {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.chat-box .participants.is-participating .conversation-live .join {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.chat-box .participants .participant {
|
|
||||||
width: 89%;
|
|
||||||
padding: 8px 8px 2px 8px;
|
|
||||||
color: #f5f5f5;
|
|
||||||
font-family: arial, sans-serif;
|
|
||||||
font-size: 13px;
|
|
||||||
line-height: 14px;
|
|
||||||
}
|
|
||||||
.chat-box .participants .participant .chat-participant-image {
|
|
||||||
width: 15%;
|
|
||||||
float: left;
|
|
||||||
overflow: hidden;
|
|
||||||
color: #BBB;
|
|
||||||
padding-top: 2px;
|
|
||||||
}
|
|
||||||
.chat-box .participants .participant .chat-participant-image img {
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
border-radius: 18px;
|
|
||||||
}
|
|
||||||
.chat-box .participants .participant .chat-participant-name {
|
|
||||||
width: 53%;
|
|
||||||
float: left;
|
|
||||||
font-size: 13px;
|
|
||||||
font-weight: bold;
|
|
||||||
margin-top: 12px;
|
|
||||||
padding: 2px 8px 0;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
.chat-box .participants .participant.is-self .chat-participant-invite-call,
|
|
||||||
.chat-box .participants .participant.is-self .chat-participant-invite-join {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
.chat-box .participants.is-live .participant .chat-participant-invite-call {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.chat-box .participants .participant .chat-participant-invite-join {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.chat-box .participants.is-live.is-participating .participant:not(.active) .chat-participant-invite-join {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.chat-box .participants .participant .chat-participant-invite-call,
|
|
||||||
.chat-box .participants .participant .chat-participant-invite-join
|
|
||||||
{
|
|
||||||
float: right;
|
|
||||||
background: #4FC059 url(<%= asset_path 'invitepeer16.png' %>) no-repeat center center;
|
|
||||||
}
|
|
||||||
.chat-box .participants .participant.pending .chat-participant-invite-call,
|
|
||||||
.chat-box .participants .participant.pending .chat-participant-invite-join {
|
|
||||||
background: #dab539 url(<%= asset_path 'ellipsis.gif' %>) no-repeat center center;
|
|
||||||
}
|
|
||||||
.chat-box .participants .participant .chat-participant-participating {
|
|
||||||
float: right;
|
|
||||||
display: none;
|
|
||||||
margin-top: 14px;
|
|
||||||
}
|
|
||||||
.chat-box .participants .participant .chat-participant-participating .green-dot {
|
|
||||||
background: #4fc059;
|
|
||||||
width: 12px;
|
|
||||||
height: 12px;
|
|
||||||
border-radius: 6px;
|
|
||||||
}
|
|
||||||
.chat-box .participants .participant.active .chat-participant-participating {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.chat-box .chat-header {
|
|
||||||
width: 100%;
|
|
||||||
padding: 16px 8px 16px 16px;
|
|
||||||
font-size: 16px;
|
|
||||||
text-align: left;
|
|
||||||
font-weight: bold;
|
|
||||||
background-color: #000000;
|
|
||||||
color: #f5f5f5;
|
|
||||||
box-shadow: 0px 6px 3px rgba(0, 0, 0, 0.23), 10px 10px 10px rgba(0, 0, 0, 0.19);
|
|
||||||
}
|
|
||||||
.chat-box .chat-header .sound-toggle {
|
|
||||||
display: none;
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
margin-right: 32px;
|
|
||||||
margin-top: -2px;
|
|
||||||
float: right;
|
|
||||||
background: url(<%= asset_path 'sound_sprite.png' %>) no-repeat;
|
|
||||||
}
|
|
||||||
.chat-box .chat-header .sound-toggle:hover {
|
|
||||||
background-position-x: -24px;
|
|
||||||
}
|
|
||||||
.chat-box .chat-header .sound-toggle.active {
|
|
||||||
background-position-y: -24px;
|
|
||||||
}
|
|
||||||
.chat-box .chat-input {
|
|
||||||
min-height: 80px;
|
|
||||||
width: 94%;
|
|
||||||
padding: 8px 3% 8px 3%;
|
|
||||||
font-size: 13px;
|
|
||||||
outline: none;
|
|
||||||
resize: none;
|
|
||||||
}
|
|
||||||
.chat-box .chat-messages {
|
|
||||||
width: 100%;
|
|
||||||
padding: 16px 0px 0px 0px;
|
|
||||||
overflow-y: auto;
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
.chat-box .chat-messages .chat-message {
|
|
||||||
width: 89%;
|
|
||||||
padding: 8px 8px 2px 8px;
|
|
||||||
color: #f5f5f5;
|
|
||||||
font-family: arial, sans-serif;
|
|
||||||
font-size: 13px;
|
|
||||||
line-height: 14px;
|
|
||||||
}
|
|
||||||
.chat-box .chat-messages .chat-message a:link {
|
|
||||||
color: #4fb5c0;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
.chat-box .chat-messages .chat-message a:visited {
|
|
||||||
color: #aea9fd;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
.chat-box .chat-messages .chat-message a:hover {
|
|
||||||
color: #dab539;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
.chat-box .chat-messages .chat-message .chat-message-user {
|
|
||||||
width: 15%;
|
|
||||||
float: left;
|
|
||||||
overflow: hidden;
|
|
||||||
color: #BBB;
|
|
||||||
padding-top: 2px;
|
|
||||||
}
|
|
||||||
.chat-box .chat-messages .chat-message .chat-message-user img {
|
|
||||||
border: 2px solid #424242;
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
border-radius: 18px;
|
|
||||||
}
|
|
||||||
.chat-box .chat-messages .chat-message .chat-message-text {
|
|
||||||
width: 73%;
|
|
||||||
float: left;
|
|
||||||
margin-top: 12px;
|
|
||||||
padding: 2px 8px 0;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
.chat-box .chat-messages .chat-message .chat-message-time {
|
|
||||||
float: right;
|
|
||||||
font-size: 10px;
|
|
||||||
color: #757575;
|
|
||||||
}
|
|
375
app/assets/stylesheets/junto.scss.erb
Normal file
|
@ -0,0 +1,375 @@
|
||||||
|
.collaborator-video {
|
||||||
|
z-index: 1;
|
||||||
|
position: absolute;
|
||||||
|
width: 150px;
|
||||||
|
height: 150px;
|
||||||
|
cursor: default;
|
||||||
|
color: #FFF;
|
||||||
|
|
||||||
|
.video-receive {
|
||||||
|
position: absolute;
|
||||||
|
width: 160px;
|
||||||
|
padding: 20px 20px 20px 170px;
|
||||||
|
background: #424242;
|
||||||
|
height: 110px;
|
||||||
|
border-top-left-radius: 75px;
|
||||||
|
border-bottom-left-radius: 75px;
|
||||||
|
border-top-right-radius: 2px;
|
||||||
|
border-bottom-right-radius: 2px;
|
||||||
|
|
||||||
|
.video-statement {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.btn-group {
|
||||||
|
.btn-yes {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
.btn-no {
|
||||||
|
background-color: #c04f4f;
|
||||||
|
&:hover {
|
||||||
|
background-color: #A54242;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-cutoff {
|
||||||
|
width: 150px;
|
||||||
|
height: 150px;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 75px;
|
||||||
|
z-index: 0;
|
||||||
|
position: relative;
|
||||||
|
-webkit-box-shadow: 0px 6px 3px rgba(0, 0, 0, 0.23), 10px 10px 10px rgba(0, 0, 0, 0.19);
|
||||||
|
-moz-box-shadow: 0px 6px 3px rgba(0, 0, 0, 0.23), 10px 10px 10px rgba(0, 0, 0, 0.19);
|
||||||
|
box-shadow: 0px 6px 3px rgba(0, 0, 0, 0.23), 10px 10px 10px rgba(0, 0, 0, 0.19);
|
||||||
|
|
||||||
|
video {
|
||||||
|
height: 150px;
|
||||||
|
margin-left: -25px;
|
||||||
|
}
|
||||||
|
.collaborator-video-avatar {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-khtml-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-o-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
-webkit-user-drag: none;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.video-audio {
|
||||||
|
position: absolute;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
top: 85%;
|
||||||
|
right: 0px;
|
||||||
|
cursor: pointer;
|
||||||
|
background: url(<%= asset_path 'audio_sprite.png' %>) no-repeat;
|
||||||
|
}
|
||||||
|
.video-audio:hover {
|
||||||
|
background-position-x: -24px;
|
||||||
|
}
|
||||||
|
.video-audio.active {
|
||||||
|
background-position-y: -24px;
|
||||||
|
}
|
||||||
|
.video-video {
|
||||||
|
position: absolute;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
top: 85%;
|
||||||
|
left: 0px;
|
||||||
|
cursor: pointer;
|
||||||
|
background: url(<%= asset_path 'camera_sprite.png' %>) no-repeat;
|
||||||
|
}
|
||||||
|
.video-video:hover {
|
||||||
|
background-position-x: -24px;
|
||||||
|
}
|
||||||
|
.video-video.active {
|
||||||
|
background-position-y: -24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.collaborator-video.my-video {
|
||||||
|
left: 30px;
|
||||||
|
top: 72px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-box {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
z-index: 1;
|
||||||
|
height: 100%;
|
||||||
|
background: #424242;
|
||||||
|
box-shadow: -8px 0px 16px 2px rgba(0, 0, 0, 0.23);
|
||||||
|
|
||||||
|
.chat-panel {
|
||||||
|
width: 300px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-button {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: -36px;
|
||||||
|
width: 36px;
|
||||||
|
height: 49px;
|
||||||
|
background: url(<%= asset_path 'junto.png' %>) no-repeat 2px 9px, url(<%= asset_path 'tray_tab.png' %>) no-repeat;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background: url(<%= asset_path 'junto_spinner_dark.gif' %>) no-repeat 2px 8px, url(<%= asset_path 'tray_tab.png' %>) no-repeat !important;
|
||||||
|
}
|
||||||
|
.chat-unread {
|
||||||
|
background: #DAB539;
|
||||||
|
position: absolute;
|
||||||
|
top: -3px;
|
||||||
|
left: -11px;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border-radius: 11px;
|
||||||
|
border: 2px solid #424242;
|
||||||
|
color: #424242;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.junto-header {
|
||||||
|
width: 276px;
|
||||||
|
padding: 16px 8px 16px 16px;
|
||||||
|
font-size: 16px;
|
||||||
|
text-align: left;
|
||||||
|
font-weight: bold;
|
||||||
|
background-color: #000000;
|
||||||
|
color: #f5f5f5;
|
||||||
|
box-shadow: 0px 6px 3px rgba(0, 0, 0, 0.23);
|
||||||
|
|
||||||
|
.cursor-toggle {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
margin-right: 8px;
|
||||||
|
margin-top: -8px;
|
||||||
|
float: right;
|
||||||
|
background: url(<%= asset_path 'cursor_sprite.png' %>) no-repeat;
|
||||||
|
}
|
||||||
|
.cursor-toggle:hover {
|
||||||
|
background-position-x: -32px;
|
||||||
|
}
|
||||||
|
.cursor-toggle.active {
|
||||||
|
background-position-y: -32px;
|
||||||
|
}
|
||||||
|
.video-toggle {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-top: -8px;
|
||||||
|
float: right;
|
||||||
|
background: url(<%= asset_path 'video_sprite.png' %>) no-repeat;
|
||||||
|
}
|
||||||
|
.video-toggle:hover {
|
||||||
|
background-position-x: -32px;
|
||||||
|
}
|
||||||
|
.video-toggle.active {
|
||||||
|
background-position-y: -32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.participants {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 150px;
|
||||||
|
padding: 16px 0px 16px 0px;
|
||||||
|
text-align: left;
|
||||||
|
color: #f5f5f5;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
.conversation-live {
|
||||||
|
padding: 5px 10px 5px 10px;
|
||||||
|
background: #c04f4f;
|
||||||
|
margin: 5px 10px;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
.conversation-live .call-action {
|
||||||
|
float: right;
|
||||||
|
cursor: pointer;
|
||||||
|
color: #EBFF00;
|
||||||
|
}
|
||||||
|
.participant {
|
||||||
|
width: 89%;
|
||||||
|
padding: 8px 8px 2px 8px;
|
||||||
|
color: #f5f5f5;
|
||||||
|
font-family: arial, sans-serif;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 14px;
|
||||||
|
|
||||||
|
.chat-participant-image {
|
||||||
|
width: 15%;
|
||||||
|
float: left;
|
||||||
|
overflow: hidden;
|
||||||
|
color: #BBB;
|
||||||
|
padding-top: 2px;
|
||||||
|
}
|
||||||
|
.chat-participant-image img {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
border-radius: 18px;
|
||||||
|
}
|
||||||
|
.chat-participant-name {
|
||||||
|
width: 53%;
|
||||||
|
float: left;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-top: 12px;
|
||||||
|
padding: 2px 8px 0;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.chat-participant-invite-call,
|
||||||
|
.chat-participant-invite-join
|
||||||
|
{
|
||||||
|
float: right;
|
||||||
|
background: #4FC059 url(<%= asset_path 'invitepeer16.png' %>) no-repeat center center;
|
||||||
|
}
|
||||||
|
.chat-participant-invite-call.pending,
|
||||||
|
.chat-participant-invite-join.pending {
|
||||||
|
background: #dab539 url(<%= asset_path 'ellipsis.gif' %>) no-repeat center center;
|
||||||
|
}
|
||||||
|
.chat-participant-participating {
|
||||||
|
float: right;
|
||||||
|
margin-top: 14px;
|
||||||
|
}
|
||||||
|
.chat-participant-participating .green-dot {
|
||||||
|
background: #4fc059;
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-header {
|
||||||
|
width: 276px;
|
||||||
|
padding: 16px 8px 16px 16px;
|
||||||
|
font-size: 16px;
|
||||||
|
text-align: left;
|
||||||
|
font-weight: bold;
|
||||||
|
background-color: #000000;
|
||||||
|
color: #f5f5f5;
|
||||||
|
box-shadow: 0px 6px 3px rgba(0, 0, 0, 0.23);
|
||||||
|
|
||||||
|
.sound-toggle {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-top: -2px;
|
||||||
|
float: right;
|
||||||
|
background: url(<%= asset_path 'sound_sprite.png' %>) no-repeat;
|
||||||
|
}
|
||||||
|
.sound-toggle:hover {
|
||||||
|
background-position-x: -24px;
|
||||||
|
}
|
||||||
|
.sound-toggle.active {
|
||||||
|
background-position-y: -24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$chat_font_size: 16px;
|
||||||
|
|
||||||
|
.chat-input {
|
||||||
|
min-height: 80px;
|
||||||
|
width: 88%;
|
||||||
|
padding: 8px 9% 8px 3%;
|
||||||
|
font-size: $chat_font_size;
|
||||||
|
outline: none;
|
||||||
|
resize: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-messages {
|
||||||
|
width: 100%;
|
||||||
|
padding: 16px 0px;
|
||||||
|
overflow-y: auto;
|
||||||
|
flex-grow: 1;
|
||||||
|
|
||||||
|
.chat-message {
|
||||||
|
width: 89%;
|
||||||
|
padding: 8px 8px 2px 8px;
|
||||||
|
color: #f5f5f5;
|
||||||
|
font-family: arial, sans-serif;
|
||||||
|
font-size: $chat_font_size;
|
||||||
|
line-height: $chat_font_size + 1px;
|
||||||
|
|
||||||
|
a:link {
|
||||||
|
color: #4fb5c0;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
a:visited {
|
||||||
|
color: #aea9fd;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color: #dab539;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
.chat-message-user {
|
||||||
|
width: 12%;
|
||||||
|
float: left;
|
||||||
|
overflow: hidden;
|
||||||
|
color: #BBB;
|
||||||
|
padding-top: 2px;
|
||||||
|
}
|
||||||
|
.chat-message-user img {
|
||||||
|
border: 2px solid #424242;
|
||||||
|
width: 28px;
|
||||||
|
height: 28px;
|
||||||
|
border-radius: 16px;
|
||||||
|
}
|
||||||
|
.chat-message-meta {
|
||||||
|
padding: 0 8px;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.chat-message-username {
|
||||||
|
color: #4fc059;
|
||||||
|
}
|
||||||
|
.chat-message-text {
|
||||||
|
width: 80%;
|
||||||
|
float: left;
|
||||||
|
padding: 2px 8px 0;
|
||||||
|
text-align: left;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
.chat-message-time {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #757575;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.new-message-area {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.emoji-mart {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 98px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.extra-message-options {
|
||||||
|
height: 20px;
|
||||||
|
position: absolute;
|
||||||
|
right: 2px;
|
||||||
|
bottom: 74px;
|
||||||
|
|
||||||
|
.emoji-picker-button {
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
288
app/assets/stylesheets/mapcard.scss.erb
Normal file
|
@ -0,0 +1,288 @@
|
||||||
|
/* Map Cards */
|
||||||
|
|
||||||
|
.map {
|
||||||
|
display:inline-block;
|
||||||
|
width:220px;
|
||||||
|
height:340px;
|
||||||
|
font-size: 12px;
|
||||||
|
text-align: left;
|
||||||
|
overflow: visible;
|
||||||
|
background: #e8e8e8;
|
||||||
|
border-radius:2px;
|
||||||
|
margin:16px;
|
||||||
|
box-shadow: 0px 3px 3px rgba(0,0,0,0.23), 0 3px 3px rgba(0,0,0,0.16);
|
||||||
|
|
||||||
|
&.newMap {
|
||||||
|
float: left;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #dcdcdc;
|
||||||
|
|
||||||
|
.newMapImage {
|
||||||
|
background-position: 0 -72px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
height: 340px;
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.newMapImage {
|
||||||
|
display: block;
|
||||||
|
width: 72px;
|
||||||
|
height: 72px;
|
||||||
|
background-image: url("<%= asset_data_uri('newmap_sprite.png') %>");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: 0 0;
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -36px;
|
||||||
|
top: 50%;
|
||||||
|
margin-top: -36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-family: 'din-regular', sans-serif;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 22px;
|
||||||
|
text-align: center;
|
||||||
|
display: block;
|
||||||
|
padding-top: 220px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mapCard {
|
||||||
|
position:relative;
|
||||||
|
width:100%;
|
||||||
|
height:308px;
|
||||||
|
padding: 0 0 16px 0;
|
||||||
|
color: #424242;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
.dropdownMenu .menuToggle .circle {
|
||||||
|
background-color: #FFF;
|
||||||
|
}
|
||||||
|
.dropdownMenu .menuToggle:hover .circle {
|
||||||
|
background-color: #DDD;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mainContent {
|
||||||
|
filter: blur(2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mapMetadata {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mapHasMapper, .mapHasConversation {
|
||||||
|
position: absolute;
|
||||||
|
top: 8px;
|
||||||
|
left: 8px;
|
||||||
|
min-width: 32px;
|
||||||
|
min-height: 32px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #FFF;
|
||||||
|
border-radius: 2px;
|
||||||
|
|
||||||
|
.mapperList {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mapperList {
|
||||||
|
display: none;
|
||||||
|
padding: 8px;
|
||||||
|
list-style-type: none;
|
||||||
|
|
||||||
|
li {
|
||||||
|
&.live {
|
||||||
|
height: 32px;
|
||||||
|
padding-left: 32px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
border-radius: 12px;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
padding-left: 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.mapHasMapper {
|
||||||
|
background: url('<%= asset_path('junto.png') %>') no-repeat 4px 0;
|
||||||
|
}
|
||||||
|
.mapHasConversation {
|
||||||
|
background: url('<%= asset_path('junto.gif') %>') no-repeat 4px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdownMenu {
|
||||||
|
position: absolute;
|
||||||
|
top: 8px;
|
||||||
|
right: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
.menuToggle {
|
||||||
|
width: 30px;
|
||||||
|
height: 10px;
|
||||||
|
|
||||||
|
.circle {
|
||||||
|
display: inline-block;
|
||||||
|
background-color: #454545;
|
||||||
|
width: 6px;
|
||||||
|
height: 6px;
|
||||||
|
border-radius: 3px;
|
||||||
|
margin: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover .circle {
|
||||||
|
background-color: #222;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.menuItems {
|
||||||
|
position: absolute;
|
||||||
|
top: 18px;
|
||||||
|
right: 0px;
|
||||||
|
background: #FFF;
|
||||||
|
border-radius: 2px;
|
||||||
|
list-style-type: none;
|
||||||
|
color: #454545;
|
||||||
|
|
||||||
|
li {
|
||||||
|
white-space: nowrap;
|
||||||
|
padding: 6px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #DDD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mapScreenshot {
|
||||||
|
width: 100%;
|
||||||
|
height: 220px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mapScreenshot img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
word-wrap: break-word;
|
||||||
|
font-size:18px;
|
||||||
|
line-height:22px;
|
||||||
|
height: 71px;
|
||||||
|
display:table;
|
||||||
|
padding: 0 16px;
|
||||||
|
font-family: 'din-regular', sans-serif;
|
||||||
|
margin: 0 auto;
|
||||||
|
|
||||||
|
.innerTitle {
|
||||||
|
display: table-cell;
|
||||||
|
vertical-align: middle;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.creatorAndPerm {
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.creatorImage {
|
||||||
|
display: inline-block;
|
||||||
|
border-radius: 16px;
|
||||||
|
vertical-align: middle;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.creatorName {
|
||||||
|
margin-left: 8px;
|
||||||
|
max-width: 162px;
|
||||||
|
display: inline-block;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.creatorAndPerm.cardHasViewOnly span.creatorName {
|
||||||
|
max-width: 95px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardViewOnly {
|
||||||
|
float: right;
|
||||||
|
line-height: 32px;
|
||||||
|
padding-right: 10px;
|
||||||
|
color: #454545;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll {
|
||||||
|
display:block;
|
||||||
|
font-family: helvetica, sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
word-wrap: break-word;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.mapMetadata {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
padding: 40px 20px 0;
|
||||||
|
height: 300px;
|
||||||
|
font-family: 'din-regular', sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #FFF;
|
||||||
|
background: -moz-linear-gradient(top, rgba(0,0,0,0.65) 0%, rgba(0,0,0,0.43) 81%, rgba(0,0,0,0) 100%);
|
||||||
|
background: -webkit-linear-gradient(top, rgba(0,0,0,0.65) 0%,rgba(0,0,0,0.43) 81%,rgba(0,0,0,0) 100%);
|
||||||
|
background: linear-gradient(to bottom, rgba(0,0,0,0.65) 0%,rgba(0,0,0,0.43) 81%,rgba(0,0,0,0) 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#a6000000', endColorstr='#00000000',GradientType=0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
.metadataSection {
|
||||||
|
padding: 16px 0;
|
||||||
|
width: 90px;
|
||||||
|
float: left;
|
||||||
|
font-family: 'din-medium', sans-serif;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
div {
|
||||||
|
background: url('<%= asset_path('metadata.png') %>') no-repeat;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.numTopicsIcon {
|
||||||
|
background-position: 0 -32px;
|
||||||
|
}
|
||||||
|
.numStarsIcon {
|
||||||
|
background-position: 0 0;
|
||||||
|
}
|
||||||
|
.numSynapsesIcon {
|
||||||
|
background-position: -32px -32px;
|
||||||
|
}
|
||||||
|
.numContributorsIcon {
|
||||||
|
background-position: -32px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
295
app/assets/stylesheets/mobile.scss.erb
Normal file
|
@ -0,0 +1,295 @@
|
||||||
|
@media only screen and (max-width : 752px) and (min-width : 504px) {
|
||||||
|
.sidebarSearch .tt-hint, .sidebarSearch .sidebarSearchField {
|
||||||
|
width: 160px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* when this switches to two lines */
|
||||||
|
@media only screen and (max-width : 728px) {
|
||||||
|
.controller-notifications .notificationsPage .notification .notification-read-unread a {
|
||||||
|
margin-top: -20px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width : 390px) {
|
||||||
|
.map .mapCard .mobileMetadata {
|
||||||
|
width: 190px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media only screen and (min-width : 390px) {
|
||||||
|
.map .mapCard .mobileMetadata {
|
||||||
|
width: 390px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* 800 is the max-width for centerContent */
|
||||||
|
@media only screen and (max-width : 800px) {
|
||||||
|
.centerContent.withPadding {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Smartphones (portrait and landscape) ----------- the minimum space that two map cards can fit side by side */
|
||||||
|
@media only screen and (max-width : 504px) {
|
||||||
|
.upperLeftUI, .upperRightUI, .openCheatsheet, .mapInfoIcon, .feedback-icon, .chat-box, #navBar {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notificationsPage .page-header {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.controller-notifications .notificationsPage .notification .notification-read-unread {
|
||||||
|
display: block !important;
|
||||||
|
}
|
||||||
|
.controller-notifications .notificationsPage .notification .notification-date {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.homeWrapper {
|
||||||
|
width: 96%;
|
||||||
|
padding: 0 2%;
|
||||||
|
}
|
||||||
|
.homeWrapper.homeText {
|
||||||
|
margin-top: 80px;
|
||||||
|
}
|
||||||
|
.homeTitle {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.homeIntro {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.fullWidthWrapper.withVideo {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
.homeVideo {
|
||||||
|
width: 100% !important;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
.fullWidthWrapper.withPartners {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.learnMoreCTA {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#yield {
|
||||||
|
padding-top: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.new_session, .new_user, .edit_user, .login, .forgotPassword {
|
||||||
|
position: relative;
|
||||||
|
top: auto;
|
||||||
|
left: auto;
|
||||||
|
width: 78%;
|
||||||
|
padding: 16px 10%;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.centerGreyForm input[type="text"], .centerGreyForm input[type="email"], .centerGreyForm input[type="password"] {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrapper .mapInfoBox {
|
||||||
|
position: fixed;
|
||||||
|
top: 50px;
|
||||||
|
right: 0px;
|
||||||
|
bottom: auto;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 360px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.requestInviteHeader {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.requestInvite {
|
||||||
|
width: 100%;
|
||||||
|
height: calc(100% - 50px);
|
||||||
|
z-index: 1;
|
||||||
|
position: relative;
|
||||||
|
left: 0;
|
||||||
|
margin-left: 0px;
|
||||||
|
margin-top: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#exploreMaps > div {
|
||||||
|
margin-top: 70px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mapper {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 0 30px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map.newMap {
|
||||||
|
a {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.newMapImage {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
height: 40px;
|
||||||
|
width: 40px;
|
||||||
|
left: auto;
|
||||||
|
top: auto;
|
||||||
|
margin: 0 0 0 8px;
|
||||||
|
background-size: 40px 80px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
vertical-align: middle;
|
||||||
|
padding: 16px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.map.newMap:hover .newMapImage {
|
||||||
|
background-position: 0 -40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 0 30px 0;
|
||||||
|
height: auto;
|
||||||
|
|
||||||
|
.mapCard {
|
||||||
|
height: auto;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
.mainContent {
|
||||||
|
filter: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.mobileHasMapper, .mobileHasConversation {
|
||||||
|
.mapperList {
|
||||||
|
padding: 8px 16px;
|
||||||
|
list-style-type: none;
|
||||||
|
|
||||||
|
li {
|
||||||
|
&.live {
|
||||||
|
height: 32px;
|
||||||
|
padding-left: 32px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
border-radius: 12px;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
padding-left: 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.mobileHasMapper {
|
||||||
|
background: url('<%= asset_path('junto.png') %>') no-repeat 12px 0;
|
||||||
|
}
|
||||||
|
.mobileHasConversation {
|
||||||
|
background: url('<%= asset_path('junto.gif') %>') no-repeat 12px 0;
|
||||||
|
}
|
||||||
|
.mobileMetadata {
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.title {
|
||||||
|
text-align: left;
|
||||||
|
display: block;
|
||||||
|
height: auto;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
.desc {
|
||||||
|
padding: 0 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#mobile_header {
|
||||||
|
height: 50px;
|
||||||
|
background: #EEE;
|
||||||
|
width: 100%;
|
||||||
|
box-shadow: 0px 3px 3px rgba(0,0,0,0.23), 0 3px 3px rgba(0,0,0,0.16);
|
||||||
|
position: fixed;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#menu_icon {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
border-right: 1px solid #DDD;
|
||||||
|
position: absolute;
|
||||||
|
background: #EEE url('<%= asset_path('menu-alt-256.png') %>') no-repeat center center;
|
||||||
|
background-size: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header_content {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
padding: 0 10px 0 60px;
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mobile_header #menu_icon .unread-notifications-dot {
|
||||||
|
top: 5px;
|
||||||
|
left: 29px;
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
border: 3px solid #eee;
|
||||||
|
border-radius: 9px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mobile_menu {
|
||||||
|
background: #EEE;
|
||||||
|
position: fixed;
|
||||||
|
top: 50px;
|
||||||
|
border-top: 1px solid #DDD;
|
||||||
|
padding: 10px;
|
||||||
|
width: 200px;
|
||||||
|
box-shadow: 3px 3px 3px rgba(0,0,0,0.23), 3px 3px 3px rgba(0,0,0,0.16);
|
||||||
|
z-index: 2;
|
||||||
|
|
||||||
|
li {
|
||||||
|
padding: 7px 10px;
|
||||||
|
list-style: none;
|
||||||
|
font-family: 'din-regular', arial, sans-serif;
|
||||||
|
|
||||||
|
.sprite {
|
||||||
|
margin-right: 6px;
|
||||||
|
margin-top: -2px;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.notifications {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.unread-notifications-dot {
|
||||||
|
top: 50%;
|
||||||
|
left: 0px;
|
||||||
|
margin-top: -4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
li.mobileMenuUser {
|
||||||
|
border-bottom: 1px solid #BBB;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobileMenuUser img {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-right: 10px;
|
||||||
|
border-radius: 16px;
|
||||||
|
}
|
237
app/assets/stylesheets/notifications.scss.erb
Normal file
|
@ -0,0 +1,237 @@
|
||||||
|
$notifications-border-color: #DDDDDD;
|
||||||
|
$notifications-hover-color: #F6F6F6;
|
||||||
|
$unread_notifications_dot_size: 8px;
|
||||||
|
|
||||||
|
.unread-notifications-dot {
|
||||||
|
width: $unread_notifications_dot_size;
|
||||||
|
height: $unread_notifications_dot_size;
|
||||||
|
background-color: #e22;
|
||||||
|
border-radius: $unread_notifications_dot_size / 2;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upperRightUI {
|
||||||
|
.notificationsIcon {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notificationsBox {
|
||||||
|
position: absolute;
|
||||||
|
background: #FFFFFF;
|
||||||
|
border-radius: 2px;
|
||||||
|
width: 350px;
|
||||||
|
right: 0;
|
||||||
|
top: 50px;
|
||||||
|
box-shadow: 0 3px 6px rgba(0,0,0,0.16);
|
||||||
|
border: 1px solid $notifications-border-color;
|
||||||
|
|
||||||
|
.notificationsBoxTriangle {
|
||||||
|
min-width: 0 !important;
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
right: 48px;
|
||||||
|
width: 20px !important;
|
||||||
|
height: 20px !important;
|
||||||
|
margin-left: -10px;
|
||||||
|
top: -11px;
|
||||||
|
border-left: 1px solid $notifications-border-color;
|
||||||
|
border-top: 1px solid $notifications-border-color;
|
||||||
|
border-bottom: 0 !important;
|
||||||
|
border-right: 0 !important;
|
||||||
|
background-color: #fff;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
-webkit-transform: rotate(45deg);
|
||||||
|
-ms-transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.notifications {
|
||||||
|
max-height: 500px;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
.notification {
|
||||||
|
font-size: 13px;
|
||||||
|
|
||||||
|
.notification-body {
|
||||||
|
border-bottom: 1px solid $notifications-border-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.notificationsEmpty {
|
||||||
|
font-family: din-regular, helvetica, sans-serif;
|
||||||
|
margin: 50px 10px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.notificationsBoxSeeAll {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
padding: 6px 0;
|
||||||
|
font-family: din-regular, helvetica, sans-serif;
|
||||||
|
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #333;
|
||||||
|
background: $notifications-hover-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.controller-notifications {
|
||||||
|
.notificationPage,
|
||||||
|
.notificationsPage {
|
||||||
|
font-family: 'din-regular', Sans-Serif;
|
||||||
|
|
||||||
|
& a:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > .notification-title {
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
padding-bottom: 0.25em;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back {
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.notificationsPage {
|
||||||
|
header {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emptyInbox {
|
||||||
|
padding-top: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.notificationPage {
|
||||||
|
.thirty-two-avatar {
|
||||||
|
display: inline-block;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
border-radius: 16px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
line-height: 32px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.decline {
|
||||||
|
background: #DB5D5D;
|
||||||
|
&:hover {
|
||||||
|
background: #DC4B4B;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-body {
|
||||||
|
p, div {
|
||||||
|
margin: 1em auto;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.notifications {
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
li:nth-last-child(2) {
|
||||||
|
.notification-body {
|
||||||
|
border-bottom: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification {
|
||||||
|
padding: 10px 10px 0 10px;
|
||||||
|
position: relative;
|
||||||
|
font-family: 'din-regular', Sans-Serif;
|
||||||
|
|
||||||
|
&.unread {
|
||||||
|
background: #EEE;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $notifications-hover-color;
|
||||||
|
|
||||||
|
.notification-read-unread {
|
||||||
|
display:block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-date {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& > a {
|
||||||
|
float: left;
|
||||||
|
width: 85%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-actor {
|
||||||
|
float: left;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
border-radius: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-body {
|
||||||
|
margin-left: 50px;
|
||||||
|
line-height: 20px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
|
||||||
|
.in-bold {
|
||||||
|
font-family: 'din-medium', Sans-Serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action {
|
||||||
|
background: #4fb5c0;
|
||||||
|
color: #FFF;
|
||||||
|
padding: 2px 6px;
|
||||||
|
border-radius: 3px;
|
||||||
|
display: inline-block;
|
||||||
|
margin: 5px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-date {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
right: 10px;
|
||||||
|
color: #607d8b;
|
||||||
|
margin-top: -6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-read-unread {
|
||||||
|
display: none;
|
||||||
|
float: left;
|
||||||
|
width: 15%;
|
||||||
|
|
||||||
|
a, div {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
margin-top: -10px;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
87
app/assets/stylesheets/request_access.scss.erb
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
.viewOnly {
|
||||||
|
float: left;
|
||||||
|
margin-left: 16px;
|
||||||
|
height: 32px;
|
||||||
|
border: 1px solid #BDBDBD;
|
||||||
|
border-radius: 2px;
|
||||||
|
background-color: #424242;
|
||||||
|
color: #FFF;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 32px;
|
||||||
|
|
||||||
|
&.isViewOnly {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eyeball {
|
||||||
|
background: url('<%= asset_path('view-only.png') %>') no-repeat 4px 0;
|
||||||
|
padding-left: 40px;
|
||||||
|
border-right: #747474;
|
||||||
|
padding-right: 10px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.requestNotice {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.requestAccess {
|
||||||
|
background-color: #a354cd;
|
||||||
|
&:hover {
|
||||||
|
background-color: #9150bc;
|
||||||
|
}
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.requestPending {
|
||||||
|
background-color: #4fc059;
|
||||||
|
}
|
||||||
|
|
||||||
|
.requestNotAccepted {
|
||||||
|
background-color: #c04f4f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.request_access {
|
||||||
|
position: absolute;
|
||||||
|
width: 90%;
|
||||||
|
margin: 0 5%;
|
||||||
|
|
||||||
|
.monkey {
|
||||||
|
width: 250px;
|
||||||
|
height: 250px;
|
||||||
|
border: 6px solid #424242;
|
||||||
|
border-radius: 125px;
|
||||||
|
background: url(https://s3.amazonaws.com/metamaps-assets/site/monkeyselfie.jpg) no-repeat;
|
||||||
|
background-position: 50% 20%;
|
||||||
|
background-size: 100%;
|
||||||
|
margin: 80px auto 20px auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.explainer_text {
|
||||||
|
padding: 0 20% 0 20%;
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 30px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.make_request {
|
||||||
|
background-color: #a354cd;
|
||||||
|
display: block;
|
||||||
|
width: 220px;
|
||||||
|
height: 14px;
|
||||||
|
padding: 16px 0;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 2px;
|
||||||
|
font-size: 14px;
|
||||||
|
box-shadow: 0px 1px 1.5px rgba(0,0,0,0.12), 0 1px 1px rgba(0,0,0,0.24);
|
||||||
|
margin: 0 auto 20px auto;
|
||||||
|
text-decoration: none;
|
||||||
|
color: #FFFFFF !important;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|