Compare commits
857 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 | ||
|
e569a0376d | ||
|
c1d963d669 | ||
|
8bb96d12a6 | ||
|
6a8921ae6d | ||
|
074eaf0bd3 | ||
|
324719e531 | ||
|
b10f0cef0e | ||
|
a5bd0440a8 | ||
|
ca5928113d | ||
|
de62a08307 | ||
|
4833dd8da6 | ||
|
11a87582c7 | ||
|
13d6ab56e5 |
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 }]
|
||||||
|
}
|
||||||
|
}
|
12
.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
|
||||||
|
|
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 @@
|
||||||
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"
|
||||||
|
|
52
Gemfile
|
@ -1,50 +1,44 @@
|
||||||
|
# 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', '~> 0.8.1'
|
gem 'active_model_serializers'
|
||||||
gem 'aws-sdk', '< 2.0'
|
gem 'aws-sdk', '~> 2.7.0'
|
||||||
gem 'best_in_place' #in-place editing
|
gem 'best_in_place'
|
||||||
gem 'delayed_job', '~> 4.0.2'
|
gem 'delayed_job'
|
||||||
gem 'delayed_job_active_record', '~> 4.0.1'
|
gem 'delayed_job_active_record'
|
||||||
gem 'devise'
|
gem 'devise'
|
||||||
gem 'doorkeeper'
|
gem 'doorkeeper'
|
||||||
gem 'dotenv'
|
gem 'dotenv-rails'
|
||||||
gem 'exception_notification'
|
gem 'exception_notification'
|
||||||
gem 'formtastic'
|
|
||||||
gem 'formula'
|
|
||||||
gem 'httparty'
|
gem 'httparty'
|
||||||
gem 'json'
|
gem 'json'
|
||||||
gem 'kaminari' # pagination
|
gem 'kaminari'
|
||||||
|
gem 'mailboxer'
|
||||||
gem 'paperclip'
|
gem 'paperclip'
|
||||||
gem 'pg'
|
gem 'pg'
|
||||||
|
gem 'puma'
|
||||||
gem 'pundit'
|
gem 'pundit'
|
||||||
gem 'pundit_extra'
|
gem 'pundit_extra'
|
||||||
|
gem 'rack-attack'
|
||||||
gem 'rack-cors'
|
gem 'rack-cors'
|
||||||
gem 'rails3-jquery-autocomplete'
|
gem 'redis', '~> 3.3.3'
|
||||||
gem 'redis'
|
|
||||||
gem 'slack-notifier'
|
gem 'slack-notifier'
|
||||||
gem 'snorlax'
|
gem 'snorlax'
|
||||||
gem 'uservoice-ruby'
|
gem 'sucker_punch'
|
||||||
|
|
||||||
|
# asset stuff
|
||||||
gem 'jquery-rails'
|
gem 'jquery-rails'
|
||||||
gem 'jquery-ui-rails'
|
gem 'jquery-ui-rails'
|
||||||
gem 'jbuilder'
|
gem 'sass-rails'
|
||||||
|
gem 'uglifier'
|
||||||
group :assets do
|
|
||||||
gem 'coffee-rails'
|
|
||||||
gem 'sass-rails'
|
|
||||||
gem 'uglifier'
|
|
||||||
# gem 'therubyracer'
|
|
||||||
end
|
|
||||||
|
|
||||||
group :production do
|
|
||||||
gem 'rails_12factor'
|
|
||||||
end
|
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
gem 'factory_girl_rails'
|
gem 'brakeman', require: false
|
||||||
|
gem 'factory_bot_rails'
|
||||||
gem 'json-schema'
|
gem 'json-schema'
|
||||||
gem 'rspec-rails'
|
gem 'rspec-rails'
|
||||||
gem 'shoulda-matchers'
|
gem 'shoulda-matchers'
|
||||||
|
@ -54,8 +48,10 @@ end
|
||||||
group :development, :test do
|
group :development, :test do
|
||||||
gem 'better_errors'
|
gem 'better_errors'
|
||||||
gem 'binding_of_caller'
|
gem 'binding_of_caller'
|
||||||
|
gem 'faker'
|
||||||
gem 'pry-byebug'
|
gem 'pry-byebug'
|
||||||
gem 'pry-rails'
|
gem 'pry-rails'
|
||||||
gem 'quiet_assets'
|
gem 'rubocop', '~> 0.48.1' # match code climate https://github.com/tootsuite/mastodon/issues/1758
|
||||||
|
gem 'timecop'
|
||||||
gem 'tunemygc'
|
gem 'tunemygc'
|
||||||
end
|
end
|
||||||
|
|
453
Gemfile.lock
|
@ -1,311 +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)
|
||||||
exception_notification (4.1.4)
|
exception_notification (4.2.2)
|
||||||
actionmailer (~> 4.0)
|
actionmailer (>= 4.0, < 6)
|
||||||
activesupport (~> 4.0)
|
activesupport (>= 4.0, < 6)
|
||||||
execjs (2.6.0)
|
execjs (2.7.0)
|
||||||
ezcrypto (0.7.2)
|
factory_bot (4.8.2)
|
||||||
factory_girl (4.5.0)
|
|
||||||
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 (0.4.0)
|
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 (1.5.1)
|
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
|
||||||
exception_notification
|
exception_notification
|
||||||
factory_girl_rails
|
factory_bot_rails
|
||||||
formtastic
|
faker
|
||||||
formula
|
|
||||||
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
|
||||||
rack-cors
|
rack-cors
|
||||||
rails (= 4.2.4)
|
rails (~> 5.0.0)
|
||||||
rails3-jquery-autocomplete
|
redis (~> 3.3.3)
|
||||||
rails_12factor
|
|
||||||
redis
|
|
||||||
rspec-rails
|
rspec-rails
|
||||||
|
rubocop (~> 0.48.1)
|
||||||
sass-rails
|
sass-rails
|
||||||
shoulda-matchers
|
shoulda-matchers
|
||||||
simplecov
|
simplecov
|
||||||
slack-notifier
|
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
|
||||||
|
|
||||||
|
|
91
README.md
|
@ -1,79 +1,62 @@
|
||||||
Metamaps
|
Metamaps
|
||||||
=======
|
=======
|
||||||
|
|
||||||
[](https://gitter.im/metamaps/metamaps?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
[](https://travis-ci.org/metamaps/metamaps)
|
||||||
[](https://travis-ci.org/metamaps/metamaps)
|
[](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?
|
||||||
|
|
||||||
|
- 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)
|
||||||
|
|
||||||
To get connected with the community interested in Metamaps, join our [Google+ community][community].
|
<!-- markdown hack to split two lists -->
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
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.git
|
|
||||||
```
|
|
||||||
Now ensure you have VirtualBox and Vagrant installed on your computer
|
|
||||||
```
|
|
||||||
cd metamaps
|
|
||||||
./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/blob/develop/LICENSE
|
||||||
[contributing]: https://github.com/metamaps/metamaps/blob/develop/doc/CONTRIBUTING.md
|
[contributing]: https://github.com/metamaps/metamaps/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/blob/develop/doc/CONTRIBUTING.md#reporting-bugs-and-other-issues
|
||||||
|
[mac-installation]: https://github.com/metamaps/metamaps/blob/develop/doc/MacInstallation.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
|
[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/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/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 */
|
|
@ -9,25 +9,14 @@
|
||||||
//
|
//
|
||||||
// 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.Admin
|
|
||||||
//= 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
|
|
@ -156,43 +156,48 @@ jQuery.browser = browser;
|
||||||
event.data.rotate(-1);
|
event.data.rotate(-1);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
$(options.buttonRight).bind('mouseup',this,function(event){
|
$(options.buttonRight).bind('mouseup',this,function(event){
|
||||||
event.data.rotate(1);
|
event.data.rotate(1);
|
||||||
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 &&
|
||||||
event.data.rotate(delta);
|
!Metamaps.Create.isSwitchingSet &&
|
||||||
return false;
|
!Metamaps.Create.newTopic.pinned) {
|
||||||
}
|
event.data.rotate(delta);
|
||||||
});
|
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');
|
||||||
|
@ -206,22 +211,27 @@ jQuery.browser = browser;
|
||||||
//$(options.titleBox).html( ($(event.target).attr('title') ));
|
//$(options.titleBox).html( ($(event.target).attr('title') ));
|
||||||
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;
|
||||||
var diff = (idx - frontIndex) % images.length;
|
var diff = (idx - frontIndex) % images.length;
|
||||||
if (Math.abs(diff) > images.length / 2) {
|
if (Math.abs(diff) > images.length / 2) {
|
||||||
diff += (diff > 0 ? -images.length : images.length);
|
diff += (diff > 0 ? -images.length : images.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
event.data.rotate(-diff);
|
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),
|
// 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'));
|
||||||
};
|
};
|
||||||
|
@ -423,4 +428,4 @@ jQuery.browser = browser;
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
})(jQuery);
|
})(jQuery);
|
||||||
|
|
|
@ -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,256 +0,0 @@
|
||||||
/* global Metamaps, Backbone, _, $ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Metamaps.Backbone.js.erb
|
|
||||||
*
|
|
||||||
* Dependencies:
|
|
||||||
* - Metamaps.Active
|
|
||||||
* - Metamaps.Loading
|
|
||||||
* - Metamaps.Map
|
|
||||||
* - Metamaps.Mapper
|
|
||||||
* - Metamaps.Realtime
|
|
||||||
*/
|
|
||||||
|
|
||||||
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))
|
|
||||||
}
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url: '/maps/' + this.id + '/contains.json',
|
|
||||||
success: start,
|
|
||||||
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
|
|
||||||
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,13 +0,0 @@
|
||||||
/*
|
|
||||||
* Metamaps.Debug.js.erb
|
|
||||||
*
|
|
||||||
* Dependencies: none!
|
|
||||||
*/
|
|
||||||
|
|
||||||
Metamaps.Debug = function() {
|
|
||||||
console.debug(Metamaps)
|
|
||||||
console.debug(`Metamaps Version: ${Metamaps.VERSION}`)
|
|
||||||
}
|
|
||||||
Metamaps.debug = function() {
|
|
||||||
Metamaps.Debug()
|
|
||||||
}
|
|
|
@ -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,322 +0,0 @@
|
||||||
/* global Metamaps, $ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Metamaps.Import.js.erb
|
|
||||||
*
|
|
||||||
* Dependencies:
|
|
||||||
* - Metamaps.Active
|
|
||||||
* - Metamaps.Backbone
|
|
||||||
* - Metamaps.Famous // TODO remove dependency
|
|
||||||
* - Metamaps.Map
|
|
||||||
* - Metamaps.Mappings
|
|
||||||
* - Metamaps.Metacodes
|
|
||||||
* - Metamaps.Synapses
|
|
||||||
* - Metamaps.Topics
|
|
||||||
*/
|
|
||||||
|
|
||||||
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.trimLeft()[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 (window.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: // eslint-disable-line
|
|
||||||
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 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,270 +0,0 @@
|
||||||
/* global Metamaps, Backbone, $ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Metamaps.Router.js.erb
|
|
||||||
*
|
|
||||||
* Dependencies:
|
|
||||||
* - Metamaps.Active
|
|
||||||
* - Metamaps.Famous
|
|
||||||
* - Metamaps.GlobalUI
|
|
||||||
* - Metamaps.JIT
|
|
||||||
* - Metamaps.Loading
|
|
||||||
* - Metamaps.Map
|
|
||||||
* - Metamaps.Maps
|
|
||||||
* - Metamaps.Topic
|
|
||||||
* - Metamaps.Views
|
|
||||||
* - Metamaps.Visualize
|
|
||||||
*/
|
|
||||||
|
|
||||||
;(function () {
|
|
||||||
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.Router.timeoutId)
|
|
||||||
|
|
||||||
if (Metamaps.Active.Mapper) document.title = 'Explore Active Maps | Metamaps'
|
|
||||||
else document.title = 'Home | Metamaps'
|
|
||||||
|
|
||||||
Metamaps.Router.currentSection = ''
|
|
||||||
Metamaps.Router.currentPage = ''
|
|
||||||
$('.wrapper').removeClass('mapPage topicPage')
|
|
||||||
|
|
||||||
var classes = Metamaps.Active.Mapper ? 'homePage explorePage' : 'homePage'
|
|
||||||
$('.wrapper').addClass(classes)
|
|
||||||
|
|
||||||
var navigate = function () {
|
|
||||||
Metamaps.Router.timeoutId = 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)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// logged out home page
|
|
||||||
Metamaps.Famous.yield.show()
|
|
||||||
|
|
||||||
Metamaps.Famous.explore.hide()
|
|
||||||
|
|
||||||
Metamaps.GlobalUI.Search.unlock()
|
|
||||||
Metamaps.GlobalUI.Search.close(0, true)
|
|
||||||
|
|
||||||
Metamaps.Famous.maps.hide()
|
|
||||||
Metamaps.Router.timeoutId = 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.Router.timeoutId)
|
|
||||||
|
|
||||||
// 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.Router.currentSection = 'explore'
|
|
||||||
Metamaps.Router.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.Router.currentPage
|
|
||||||
|
|
||||||
// alter url if for mapper profile page
|
|
||||||
if (Metamaps.Router.currentPage === 'mapper') {
|
|
||||||
path += '/' + Metamaps.Maps.Mapper.mapperId
|
|
||||||
}
|
|
||||||
|
|
||||||
Metamaps.Router.navigate(path)
|
|
||||||
}
|
|
||||||
var navigateTimeout = function () {
|
|
||||||
Metamaps.Router.timeoutId = 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.Router.timeoutId)
|
|
||||||
|
|
||||||
document.title = 'Map ' + id + ' | Metamaps'
|
|
||||||
|
|
||||||
Metamaps.Router.currentSection = 'map'
|
|
||||||
Metamaps.Router.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.Router.timeoutId)
|
|
||||||
|
|
||||||
document.title = 'Topic ' + id + ' | Metamaps'
|
|
||||||
|
|
||||||
Metamaps.Router.currentSection = 'topic'
|
|
||||||
Metamaps.Router.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.currentPage = ''
|
|
||||||
Metamaps.Router.currentSection = undefined
|
|
||||||
Metamaps.Router.timeoutId = undefined
|
|
||||||
|
|
||||||
Metamaps.Router.intercept = function (evt) {
|
|
||||||
var segments
|
|
||||||
|
|
||||||
var href = {
|
|
||||||
prop: $(this).prop('href'),
|
|
||||||
attr: $(this).attr('href')
|
|
||||||
}
|
|
||||||
var root = window.location.protocol + '//' + window.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,129 +0,0 @@
|
||||||
/* global Metamaps, $, Hogan, Backbone */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Metamaps.Views.js.erb
|
|
||||||
*
|
|
||||||
* Dependencies:
|
|
||||||
* - Metamaps.Famous
|
|
||||||
* - Metamaps.Loading
|
|
||||||
*/
|
|
||||||
|
|
||||||
Metamaps.Views = {
|
|
||||||
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, cbArg) {
|
|
||||||
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 (!Metamaps.Views.initialized) {
|
|
||||||
m.deploy(m._currTarget)
|
|
||||||
Metamaps.Views.initialized = true
|
|
||||||
setTimeout(updateHeight, 100)
|
|
||||||
} else {
|
|
||||||
setTimeout(updateHeight, 100)
|
|
||||||
}
|
|
||||||
|
|
||||||
Metamaps.Loading.hide()
|
|
||||||
},
|
|
||||||
handleSuccess: function (cb) {
|
|
||||||
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,343 +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"></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/MM_sounds.mp3' %>", "<%= asset_path 'sounds/MM_sounds.ogg' %>"],
|
|
||||||
sprite: {
|
|
||||||
joinmap: [0, 561],
|
|
||||||
leavemap: [1000, 592],
|
|
||||||
receivechat: [2000, 318],
|
|
||||||
sendchat: [3000, 296],
|
|
||||||
sessioninvite: [4000, 5393, true]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
incrementUnread: function() {
|
|
||||||
this.unreadMessages++;
|
|
||||||
this.$unread.html(this.unreadMessages);
|
|
||||||
this.$unread.show();
|
|
||||||
},
|
|
||||||
addMessage: function(message, isInitial, wasMe) {
|
|
||||||
|
|
||||||
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 (!wasMe && !isInitial && this.alertSound) this.sound.play('receivechat');
|
|
||||||
},
|
|
||||||
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 = true; // 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, wasMe) {
|
|
||||||
this.messages.add(message);
|
|
||||||
Private.addMessage.call(this, message, isInitial, wasMe);
|
|
||||||
}
|
|
||||||
|
|
||||||
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,195 +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);
|
|
||||||
if (self.chat.alertSound) self.chat.sound.play('sendchat');
|
|
||||||
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), false, true);
|
|
||||||
$(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, wasMe) {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
messages.models.forEach(function (message) {
|
|
||||||
self.chat.addMessage(message, isInitial, wasMe);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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,41 +2244,34 @@ 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 {
|
.icon_source_code .lightboxAboutIcon {
|
||||||
background-position: -32px -32px;
|
background-position: -64px 0;
|
||||||
}
|
&:hover {
|
||||||
#lightbox_source:hover .lightboxAboutIcon {
|
|
||||||
background-position: -64px -32px;
|
background-position: -64px -32px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#lightbox_blog:hover .lightboxAboutIcon {
|
.icon_terms .lightboxAboutIcon {
|
||||||
background-position: -96px -32px;
|
background-position: -128px 0;
|
||||||
}
|
&:hover {
|
||||||
#lightbox_term:hover .lightboxAboutIcon {
|
|
||||||
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,28 +2325,43 @@ 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,
|
||||||
margin-bottom: 5px;
|
.selectAll,
|
||||||
font-family: 'din-medium', helvetica, sans-serif;
|
.selectNone {
|
||||||
color: #424242;
|
margin-bottom: 5px;
|
||||||
font-size: 14px;
|
font-family: 'din-medium', helvetica, sans-serif;
|
||||||
text-align: justify;
|
color: #424242;
|
||||||
padding-right: 16px;
|
font-size: 14px;
|
||||||
}
|
text-align: justify;
|
||||||
#switchMetacodes > p {
|
padding-right: 16px;
|
||||||
margin: 16px 0 16px 0;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
#metacodeSwitchTabs > ul {
|
|
||||||
width: 130px;
|
.selectAll,
|
||||||
}
|
.selectNone {
|
||||||
#metacodeSwitchTabs > ul li {
|
float: right;
|
||||||
font-size: 14px;
|
cursor: pointer;
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
&:hover,
|
||||||
#metacodeSwitchTabs li.ui-state-active a {
|
&.selected {
|
||||||
color: #00BCD4;
|
color: #00bcd4;
|
||||||
cursor: pointer;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& > ul {
|
||||||
|
width: 130px;
|
||||||
|
|
||||||
|
li {
|
||||||
|
font-size: 14px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
li.ui-state-active a {
|
||||||
|
color: #00BCD4;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.metacodeSwitchTab {
|
.metacodeSwitchTab {
|
||||||
max-height: 300px;
|
max-height: 300px;
|
||||||
|
@ -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 {
|
||||||
|
@ -14,22 +22,20 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.nameCounter.forTopic {
|
.nameCounter.forTopic {
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#center-container {
|
#center-container {
|
||||||
position:relative;
|
position:relative;
|
||||||
height:100%;
|
height:100%;
|
||||||
width:100%;
|
width:100%;
|
||||||
|
|
||||||
/* background-color:#031924; */
|
/* background-color:#031924; */
|
||||||
color:#444;
|
color:#444;
|
||||||
}
|
}
|
||||||
|
|
||||||
.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 {
|
/*
|
||||||
font-style:normal;
|
* Styling for Markdown in topic cards
|
||||||
margin-top:5px;
|
*/
|
||||||
|
|
||||||
|
.CardOnGraph .desc {
|
||||||
|
p, ol, ul {
|
||||||
|
padding: 0.15em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
font-style: normal;
|
||||||
|
padding: 0.25em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol,
|
||||||
|
ul {
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.CardOnGraph .best_in_place_desc {
|
/*
|
||||||
|
* End Markdown styling
|
||||||
|
*/
|
||||||
|
|
||||||
|
.CardOnGraph .riek_desc {
|
||||||
display:block;
|
display:block;
|
||||||
margin-top:2px;
|
padding-right: 26px;
|
||||||
padding-right: 18px;
|
|
||||||
margin-right: 8px;
|
|
||||||
}
|
}
|
||||||
.canEdit .CardOnGraph .best_in_place_desc:hover {
|
.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;
|
||||||
|
@ -159,155 +196,215 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.CardOnGraph .links {
|
.CardOnGraph .links {
|
||||||
position:relative;
|
|
||||||
border-bottom: 1px solid #BDBDBD;
|
|
||||||
border-top: 1px solid #BDBDBD;
|
|
||||||
background-color: #e0e0e0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.linkItem {
|
|
||||||
float:left;
|
|
||||||
height:46px;
|
|
||||||
z-index: 1;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
color: #424242;
|
z-index: 2;
|
||||||
font-size: 14px;
|
|
||||||
line-height:14px;
|
.linkItem {
|
||||||
height:12px;
|
float: left;
|
||||||
padding:17px 0;
|
z-index: 1;
|
||||||
}
|
position: relative;
|
||||||
.linkItem a {
|
color: #424242;
|
||||||
color: #424242;
|
font-size: 14px;
|
||||||
|
line-height: 14px;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #424242;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
padding: 0;
|
||||||
|
height: 48px;
|
||||||
|
margin-right: 10px;
|
||||||
|
|
||||||
|
.metacodeImage {
|
||||||
|
cursor: move;
|
||||||
|
position: absolute;
|
||||||
|
left: -18px;
|
||||||
|
top: 6px;
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
background-size:36px 36px;
|
||||||
|
background-position:0 0;
|
||||||
|
background-repeat:no-repeat;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.CardOnGraph .icon {
|
.CardOnGraph .info {
|
||||||
position:absolute;
|
|
||||||
width:100%;
|
|
||||||
z-index:1;
|
|
||||||
padding: 0;
|
|
||||||
height: 48px;
|
|
||||||
}
|
|
||||||
.linkItem.contributor {
|
|
||||||
margin-left:40px;
|
|
||||||
z-index:1;
|
|
||||||
padding:17px 16px 17px 30px;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
|
||||||
.contributor .contributorIcon {
|
|
||||||
position: absolute;
|
|
||||||
top: 8px;
|
|
||||||
left: 0;
|
|
||||||
border-radius: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contributor:hover .contributorName {
|
.linkItem {
|
||||||
display: block;
|
float: left;
|
||||||
}
|
z-index: 1;
|
||||||
|
position: relative;
|
||||||
|
color: $mid-gray-opacity;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 14px;
|
||||||
|
|
||||||
.contributorName {
|
a {
|
||||||
display: none;
|
color: $mid-gray-opacity;
|
||||||
position: absolute;
|
}
|
||||||
background: black;
|
}
|
||||||
text-align: center;
|
|
||||||
color: white;
|
|
||||||
border-radius: 2px;
|
|
||||||
font-family: din-regular;
|
|
||||||
line-height: 15px;
|
|
||||||
font-size: 12px;
|
|
||||||
padding: 3px 5px 2px;
|
|
||||||
white-space: nowrap;
|
|
||||||
margin-top: 36px;
|
|
||||||
margin-left: -32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contributor div:before {
|
.contributor {
|
||||||
content: '';
|
bottom: 7px;
|
||||||
position: absolute;
|
margin-left: 16px;
|
||||||
top: 128%;
|
|
||||||
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 {
|
.contributorIcon {
|
||||||
margin-left: 12px;
|
position: relative;
|
||||||
width: 24px;
|
display: inline-block;
|
||||||
padding:17px 0 17px 36px;
|
vertical-align: middle;
|
||||||
}
|
border-radius: 16px;
|
||||||
.linkItem.mapCount .mapCountIcon {
|
margin: 5px 5px 5px 0;
|
||||||
position: absolute;
|
top: 11px;
|
||||||
top: 8px;
|
left: 0;
|
||||||
left: 0;
|
}
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
background-image: url(<%= asset_data_uri('map32_sprite.png') %>);
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: 0 0;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.linkItem.mapCount:hover .mapCountIcon {
|
|
||||||
background-position: 0 -32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.linkItem.mapCount:hover .hoverTip {
|
span {
|
||||||
display: block;
|
font-family: 'din-regular', sans-serif;
|
||||||
}
|
font-size: 14px;
|
||||||
.CardOnGraph .mapCount .tip, .CardonGraph .mapCount .hoverTip {
|
}
|
||||||
top: 44px;
|
|
||||||
left: 0px;
|
|
||||||
font-size: 12px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hoverTip {
|
.contributorName {
|
||||||
white-space: nowrap;
|
font-family: din-regular;
|
||||||
font-family: 'din-regular';
|
margin-top: 20px;
|
||||||
top: 44px;
|
display: inline-block;
|
||||||
left: 0px;
|
vertical-align: middle;
|
||||||
font-size: 12px !important;
|
width: 97px;
|
||||||
display: none;
|
padding: 0 8px 0 4px;
|
||||||
position: absolute;
|
white-space: nowrap;
|
||||||
background: black;
|
overflow: hidden;
|
||||||
color: white;
|
text-overflow: ellipsis;
|
||||||
border-radius: 4px;
|
}
|
||||||
line-height: 17px;
|
}
|
||||||
padding: 3px 5px 2px;
|
|
||||||
z-index: 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
.mapCount {
|
||||||
|
padding:17px 38px 17px 0;
|
||||||
|
width: 22px;
|
||||||
|
text-align: right;
|
||||||
|
|
||||||
.CardOnGraph .mapCount .tip:before, .CardOnGraph .mapCount .hoverTip:before {
|
.mapCountIcon {
|
||||||
content: '';
|
position: absolute;
|
||||||
position: absolute;
|
top: 8px;
|
||||||
top: 26px;
|
right: 0;
|
||||||
left: 10px;
|
width: 32px;
|
||||||
margin-top: -30px;
|
height: 32px;
|
||||||
width: 0;
|
background-image: url(<%= asset_data_uri('map32_sprite.png') %>);
|
||||||
height: 0;
|
background-repeat: no-repeat;
|
||||||
border-bottom: 4px solid #000000;
|
background-position: 0 0;
|
||||||
border-left: 5px solid transparent;
|
cursor: pointer;
|
||||||
border-right: 5px solid transparent;
|
opacity: 0.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
.CardOnGraph .mapCount .tip li {
|
&:hover .mapCountIcon {
|
||||||
list-style-type: none;
|
background-position: 0 -32px;
|
||||||
white-space: nowrap;
|
}
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
padding: 6px 10px;
|
|
||||||
display: block;
|
|
||||||
height: 14px;
|
|
||||||
font-family: 'din-regular', helvetica, sans-serif;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 14px;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.CardOnGraph .mapCount li.hideExtra {
|
.tip, .hoverTip {
|
||||||
display: none;
|
top: 44px;
|
||||||
|
right: 0px;
|
||||||
|
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 {
|
||||||
|
white-space: nowrap;
|
||||||
|
font-family: 'din-regular';
|
||||||
|
top: 44px;
|
||||||
|
font-size: 12px !important;
|
||||||
|
position: absolute;
|
||||||
|
background: $mid-gray;
|
||||||
|
color: white;
|
||||||
|
border-radius: 4px;
|
||||||
|
line-height: 17px;
|
||||||
|
padding: 3px 5px 2px;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tip a {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tip a:hover {
|
||||||
|
color: #757575;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tip li {
|
||||||
|
list-style-type: none;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
padding: 6px 10px;
|
||||||
|
display: block;
|
||||||
|
height: 14px;
|
||||||
|
font-family: 'din-regular', helvetica, sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 14px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.synapseCount {
|
||||||
|
width: 22px;
|
||||||
|
padding:17px 38px 17px 0;
|
||||||
|
text-align: right;
|
||||||
|
margin-right: 4px;
|
||||||
|
|
||||||
|
.synapseCountIcon {
|
||||||
|
position: absolute;
|
||||||
|
top: 8px;
|
||||||
|
right: 0;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
background-image: url(<%= asset_data_uri('synapse32_sprite.png') %>);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: 0 0;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
hover .synapseCountIcon {
|
||||||
|
background-position: 0 -32px;
|
||||||
|
}
|
||||||
|
.tip {
|
||||||
|
position: absolute;
|
||||||
|
background: $mid-gray;
|
||||||
|
width: auto;
|
||||||
|
top: 44px;
|
||||||
|
right: 0px;
|
||||||
|
color: white;
|
||||||
|
white-space: nowrap;
|
||||||
|
border-radius: 2px;
|
||||||
|
font-size: 12px !important;
|
||||||
|
font-family: 'din-regular';
|
||||||
|
line-height: 12px;
|
||||||
|
padding: 4px 4px 4px;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tip:before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
margin-top: -8px;
|
||||||
|
right: 12px;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-bottom: 4px solid $mid-gray;
|
||||||
|
border-left: 5px solid transparent;
|
||||||
|
border-right: 5px solid transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.showMore {
|
.showMore {
|
||||||
|
@ -315,66 +412,10 @@
|
||||||
color: #4FC059;
|
color: #4FC059;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mapCount .tip a {
|
.linkItem.mapPerm {
|
||||||
color: white;
|
margin-right: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mapCount .tip a:hover {
|
|
||||||
color: #757575;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.linkItem.synapseCount {
|
|
||||||
margin-left: 2px;
|
|
||||||
width: 24px;
|
|
||||||
padding:17px 0 17px 32px;
|
|
||||||
}
|
|
||||||
.linkItem.synapseCount .synapseCountIcon {
|
|
||||||
position: absolute;
|
|
||||||
top: 8px;
|
|
||||||
left: 0;
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
background-image: url(<%= asset_data_uri('synapse32_sprite.png') %>);
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: 0 0;
|
|
||||||
}
|
|
||||||
.linkItem.synapseCount:hover .synapseCountIcon {
|
|
||||||
background-position: 0 -32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.CardOnGraph .synapseCount .tip {
|
|
||||||
position: absolute;
|
|
||||||
background: black;
|
|
||||||
width: auto;
|
|
||||||
top: 44px;
|
|
||||||
color: white;
|
|
||||||
white-space: nowrap;
|
|
||||||
border-radius: 2px;
|
|
||||||
font-size: 12px !important;
|
|
||||||
font-family: 'din-regular';
|
|
||||||
line-height: 12px;
|
|
||||||
padding: 4px 4px 4px;
|
|
||||||
z-index: 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
.CardOnGraph .synapseCount:hover .tip {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.CardOnGraph .synapseCount .tip:before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
margin-top: -8px;
|
|
||||||
margin-left: 6px;
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
border-bottom: 4px solid black;
|
|
||||||
border-left: 5px solid transparent;
|
|
||||||
border-right: 5px solid transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.mapPerm {
|
.mapPerm {
|
||||||
width: 32px;
|
width: 32px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
|
@ -396,14 +437,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.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;
|
cursor: pointer;
|
||||||
background-position: 0 0;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
}
|
||||||
.mapPerm .permissionSelect {
|
.mapPerm .permissionSelect {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
@ -439,63 +476,55 @@ 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;
|
||||||
line-height: 14px;
|
line-height: 14px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-family: helvetica, sans-serif;
|
font-family: helvetica, sans-serif;
|
||||||
|
@ -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,26 +625,23 @@ 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;
|
||||||
display: block;
|
display: block;
|
||||||
margin-left: 40px;
|
margin-left: 40px;
|
||||||
padding-top:9px;
|
padding-top:9px;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
line-height: 16px;
|
line-height: 16px;
|
||||||
|
@ -626,7 +651,7 @@ background-color: #E0E0E0;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 102px;
|
width: 102px;
|
||||||
height: 12px;
|
height: 12px;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
padding: 18px 0 18px 48px;
|
padding: 18px 0 18px 48px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #9e9e9e;
|
color: #9e9e9e;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -924,11 +948,11 @@ font-family: 'din-regular', helvetica, sans-serif;
|
||||||
}
|
}
|
||||||
#edit_synapse_right {
|
#edit_synapse_right {
|
||||||
background-image: url(<%= asset_data_uri('synapsedirectionright_sprite.png') %>);
|
background-image: url(<%= asset_data_uri('synapsedirectionright_sprite.png') %>);
|
||||||
right: 16px;
|
right: 16px;
|
||||||
}
|
}
|
||||||
#edit_synapse_left {
|
#edit_synapse_left {
|
||||||
background-image: url(<%= asset_data_uri('synapsedirectionleft_sprite.png') %>);
|
background-image: url(<%= asset_data_uri('synapsedirectionleft_sprite.png') %>);
|
||||||
right: 56px;
|
right: 56px;
|
||||||
}
|
}
|
||||||
#edit_synapse_left.checked, #edit_synapse_right.checked {
|
#edit_synapse_left.checked, #edit_synapse_right.checked {
|
||||||
background-position: 0 -48px;
|
background-position: 0 -48px;
|
||||||
|
@ -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,24 +406,17 @@
|
||||||
.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;
|
||||||
height:32px;
|
height:32px;
|
||||||
background-color: #424242;
|
background-color: #424242;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: 0 0;
|
background-position: 0 0;
|
||||||
cursor:pointer;
|
cursor:pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
color: #757575;
|
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;
|
||||||
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,347 +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 {
|
|
||||||
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -8,20 +8,14 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.unauthenticated {
|
.unauthenticated {
|
||||||
.homePage .sidebarSearchIcon {
|
.homePage .sidebarSearch {
|
||||||
border-radius: 2px;
|
display: none;
|
||||||
}
|
|
||||||
|
|
||||||
.homePage .sidebarSearchField,
|
|
||||||
.homePage .sidebarSearch .tt-hint {
|
|
||||||
border-top-left-radius: 2px;
|
|
||||||
border-bottom-left-radius: 2px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebarSearchIcon {
|
.sidebarSearchIcon {
|
||||||
float: left;
|
float: left;
|
||||||
width: 72px;
|
width: 50px;
|
||||||
border-top-right-radius: 2px;
|
border-top-right-radius: 2px;
|
||||||
border-bottom-right-radius: 2px;
|
border-bottom-right-radius: 2px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
|
@ -99,13 +93,15 @@
|
||||||
|
|
||||||
.sidebarSearchField {
|
.sidebarSearchField {
|
||||||
float: left;
|
float: left;
|
||||||
|
width: 379px;
|
||||||
|
padding: 7px 10px 3px 10px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
border-top: 1px solid #BDBDBD;
|
border-top: 1px solid #BDBDBD;
|
||||||
border-bottom: 1px solid #BDBDBD;
|
border-bottom: 1px solid #BDBDBD;
|
||||||
border-left: none;
|
border-left: 1px solid #BDBDBD;
|
||||||
border-right: none;
|
border-right: none;
|
||||||
padding: 5px 0 5px 0;
|
border-top-left-radius: 2px;
|
||||||
width: 0px;
|
border-bottom-left-radius: 2px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
outline: none;
|
outline: none;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
@ -117,13 +113,13 @@
|
||||||
|
|
||||||
.tt-hint {
|
.tt-hint {
|
||||||
color: transparent;
|
color: transparent;
|
||||||
|
width: 380px;
|
||||||
|
padding: 7px 10px 3px 10px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
border-top: 1px solid #BDBDBD;
|
border-top: 1px solid #BDBDBD;
|
||||||
border-bottom: 1px solid #BDBDBD;
|
border-bottom: 1px solid #BDBDBD;
|
||||||
border-left: none;
|
border-left: none;
|
||||||
border-right: none;
|
border-right: none;
|
||||||
padding: 5px 0 5px 0;
|
|
||||||
width: 0px;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
outline: none;
|
outline: none;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
|
6
app/channels/application_cable/channel.rb
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module ApplicationCable
|
||||||
|
class Channel < ActionCable::Channel::Base
|
||||||
|
end
|
||||||
|
end
|
23
app/channels/application_cable/connection.rb
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module ApplicationCable
|
||||||
|
class Connection < ActionCable::Connection::Base
|
||||||
|
identified_by :current_user
|
||||||
|
|
||||||
|
def connect
|
||||||
|
self.current_user = find_verified_user
|
||||||
|
logger.add_tags 'ActionCable', current_user.name
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def find_verified_user
|
||||||
|
verified_user = User.find_by(id: cookies.signed['user.id'])
|
||||||
|
if verified_user && cookies.signed['user.expires_at'] > Time.now.getlocal
|
||||||
|
verified_user
|
||||||
|
else
|
||||||
|
reject_unauthorized_connection
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
18
app/channels/map_channel.rb
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class MapChannel < ApplicationCable::Channel
|
||||||
|
# Called when the consumer has successfully
|
||||||
|
# become a subscriber of this channel.
|
||||||
|
def subscribed
|
||||||
|
map = Map.find(params[:id])
|
||||||
|
return unless Pundit.policy(current_user, map).show?
|
||||||
|
stream_from "map_#{params[:id]}"
|
||||||
|
Events::UserPresentOnMap.publish!(map, current_user)
|
||||||
|
end
|
||||||
|
|
||||||
|
def unsubscribed
|
||||||
|
map = Map.find(params[:id])
|
||||||
|
return unless Pundit.policy(current_user, map).show?
|
||||||
|
Events::UserNotPresentOnMap.publish!(map, current_user)
|
||||||
|
end
|
||||||
|
end
|
90
app/controllers/access_controller.rb
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AccessController < ApplicationController
|
||||||
|
before_action :require_user, only: %i[access access_request
|
||||||
|
approve_access approve_access_post
|
||||||
|
deny_access deny_access_post request_access]
|
||||||
|
before_action :set_map, only: %i[access access_request
|
||||||
|
approve_access approve_access_post
|
||||||
|
deny_access deny_access_post request_access]
|
||||||
|
after_action :verify_authorized
|
||||||
|
|
||||||
|
# GET maps/:id/request_access
|
||||||
|
def request_access
|
||||||
|
@map = nil
|
||||||
|
respond_to do |format|
|
||||||
|
format.html do
|
||||||
|
render 'maps/request_access'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# POST maps/:id/access_request
|
||||||
|
def access_request
|
||||||
|
AccessRequest.create(user: current_user, map: @map)
|
||||||
|
respond_to do |format|
|
||||||
|
format.json { head :ok }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# POST maps/:id/access
|
||||||
|
def access
|
||||||
|
user_ids = params[:access].to_a.map(&:to_i) || []
|
||||||
|
|
||||||
|
@map.add_new_collaborators(user_ids)
|
||||||
|
@map.remove_old_collaborators(user_ids)
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.json { head :ok }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# GET maps/:id/approve_access/:request_id
|
||||||
|
def approve_access
|
||||||
|
request = AccessRequest.find(params[:request_id])
|
||||||
|
request.approve # also marks mailboxer notification as read
|
||||||
|
respond_to do |format|
|
||||||
|
format.html { redirect_to map_path(@map), notice: 'Request was approved' }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# GET maps/:id/deny_access/:request_id
|
||||||
|
def deny_access
|
||||||
|
request = AccessRequest.find(params[:request_id])
|
||||||
|
request.deny # also marks mailboxer notification as read
|
||||||
|
respond_to do |format|
|
||||||
|
format.html { redirect_to map_path(@map), notice: 'Request was turned down' }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# POST maps/:id/approve_access/:request_id
|
||||||
|
def approve_access_post
|
||||||
|
request = AccessRequest.find(params[:request_id])
|
||||||
|
request.approve
|
||||||
|
respond_to do |format|
|
||||||
|
format.js
|
||||||
|
format.json do
|
||||||
|
head :ok
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# POST maps/:id/deny_access/:request_id
|
||||||
|
def deny_access_post
|
||||||
|
request = AccessRequest.find(params[:request_id])
|
||||||
|
request.deny
|
||||||
|
respond_to do |format|
|
||||||
|
format.js
|
||||||
|
format.json do
|
||||||
|
head :ok
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_map
|
||||||
|
@map = Map.find(params[:id])
|
||||||
|
authorize @map
|
||||||
|
end
|
||||||
|
end
|