1
0
mirror of https://shylinux.com/x/volcanos synced 2025-04-26 17:24:06 +08:00

Compare commits

..

1518 Commits

Author SHA1 Message Date
shy
b9db5b8b8d add some 2025-04-25 18:23:50 +08:00
shy
b24bdc33f2 add some 2025-03-22 12:54:03 +08:00
shy
4fba3f0a65 opt some 2025-03-15 10:32:07 +08:00
shy
58c1f57814 add some 2025-03-10 18:38:42 +08:00
shy
fb526f0c8e add some 2025-03-08 08:38:23 +08:00
shy
7426ac64cb add some 2025-03-05 23:33:52 +08:00
shy
27b6505a44 add some 2025-03-04 09:58:28 +08:00
shy
2da6711ce3 add some 2025-03-03 18:39:54 +08:00
shy
d95a8e99b4 add some 2025-03-02 22:08:23 +08:00
shy
6ce0e580de add some 2025-03-01 11:36:52 +08:00
shy
87841a9e2f add some 2025-02-28 14:17:32 +08:00
shy
82b234b002 add some 2025-02-27 16:27:44 +08:00
shy
4a81d5e87b add some 2025-02-25 21:54:45 +08:00
shy
68f8c3b873 add some 2025-02-25 12:14:46 +08:00
root
71fd4be1c9 add some 2025-02-25 07:32:52 +08:00
root
ebeecd3423 add some 2025-02-19 21:00:52 +08:00
root
a34814261a add some 2025-02-18 11:18:25 +08:00
root
647dbf6d91 add some 2025-02-17 19:54:58 +08:00
shy
6b0fc20430 add some 2025-02-16 08:27:28 +08:00
shy
c76ef839aa add some 2025-02-15 18:35:03 +08:00
shy
ee60a8b9bc add some 2025-02-15 12:32:12 +08:00
shy
39fcf84f40 add some 2025-02-13 22:35:39 +08:00
shy
7a44753dca opt some 2025-02-13 11:27:55 +08:00
shy
31f888755f opt some 2025-02-10 23:27:08 +08:00
shy
a63f1d4dab opt some 2025-02-10 23:04:58 +08:00
shy
b70e92c19d opt some 2025-02-10 10:11:57 +08:00
root
d442e0c168 add some 2025-02-10 08:30:07 +08:00
root
044d57c509 add some 2025-02-08 18:16:55 +08:00
root
7aaf056db8 add some 2025-02-08 15:00:11 +08:00
root
37b896bed1 add some 2025-02-08 12:02:53 +08:00
root
34686ad781 add some 2025-02-05 09:44:32 +08:00
root
808124b782 add some 2025-02-04 11:59:32 +08:00
shy
1aa5603a82 add some 2025-02-03 20:42:06 +08:00
shy
39499d7f4b add some 2025-02-02 23:54:47 +08:00
root
0fb76d1569 add some 2025-01-29 12:00:57 +08:00
shy
4d59ba0b77 add some 2025-01-25 15:15:52 +08:00
shy
d409358c30 add some 2025-01-23 21:36:49 +08:00
shy
47d96e5e0a add some 2025-01-23 19:44:14 +08:00
shy
9fa440245a add some 2025-01-23 18:59:35 +08:00
shy
98916131e3 add some 2025-01-22 16:36:36 +08:00
shy
9f6650df0d add some 2025-01-22 16:12:27 +08:00
root
943c1ec129 add some 2025-01-22 15:32:34 +08:00
root
33bb1ef07b add some 2025-01-14 08:42:17 +08:00
shy
81f8598691 add some 2025-01-10 15:04:49 +08:00
shy
a6a2b12072 add some 2025-01-06 21:38:50 +08:00
shy
af2222ca55 add some 2025-01-05 12:01:35 +08:00
shy
32abbf3a70 add some 2025-01-02 20:48:31 +08:00
shy
6263444d07 add some 2025-01-01 09:23:40 +08:00
shy
4d9d3a6bda add some 2024-12-31 15:46:04 +08:00
shy
6313d57ff6 opt some 2024-12-31 12:10:20 +08:00
shy
e354cf4d2f add some 2024-12-23 10:48:33 +08:00
shy
69c73c5593 add some 2024-12-08 22:27:34 +08:00
shy
3a3def6e96 add some 2024-12-06 18:14:04 +08:00
shy
e70b727c94 add some 2024-12-06 09:00:28 +08:00
shy
cb5d5d992e add some 2024-12-03 22:45:10 +08:00
shy
b06d344082 add some 2024-11-26 23:12:56 +08:00
shy
f893b961a6 add some 2024-11-25 19:39:32 +08:00
root
29d9275a65 add some 2024-11-25 10:42:18 +08:00
shy
1020f41d5d add some 2024-11-21 23:12:38 +08:00
shy
33a7151166 add some 2024-11-20 22:50:00 +08:00
root
0f61c3acbd add some 2024-11-18 09:11:40 +08:00
shy
9d89082b3e add some 2024-11-15 20:09:13 +08:00
root
d87ec7d9c4 add some 2024-11-15 10:09:07 +08:00
root
d5e5e2747f add some 2024-11-12 13:11:48 +08:00
root
1ca51e3895 add some 2024-11-10 09:06:48 +08:00
root
ec5d230bd9 add some 2024-11-09 11:35:37 +08:00
root
e7c8114430 add some 2024-11-04 10:27:16 +08:00
shy
46d4aaf0f4 add some 2024-11-01 11:41:37 +08:00
root
c9d4795809 add some 2024-10-25 17:49:41 +08:00
root
8577dd764d add some 2024-10-22 07:35:53 +08:00
root
1ead9f4b25 add some 2024-10-20 22:55:25 +08:00
root
b4dbf11528 add some 2024-10-20 08:16:16 +08:00
root
fb9687dd55 add some 2024-10-18 14:45:27 +08:00
root
daba956955 add some 2024-10-18 14:09:07 +08:00
root
78af0b3d1c add some 2024-10-17 23:45:30 +08:00
root
d7c0a536ea add some 2024-10-17 12:13:45 +08:00
root
b11fba0426 add some 2024-10-16 10:30:52 +08:00
b8eefca8f5 opt some 2024-10-15 18:52:11 +08:00
root
284c73cff2 add some 2024-10-15 18:25:32 +08:00
root
a158908876 add some 2024-10-13 18:25:41 +08:00
root
4f80806c45 add some 2024-10-13 08:24:22 +08:00
root
76a97837f3 add some 2024-10-12 11:06:24 +08:00
shy
0e28e0c39b add some 2024-10-10 22:23:48 +08:00
shy
912f0133f3 add some 2024-10-09 14:41:22 +08:00
shy
97e784c584 add some 2024-10-06 22:19:11 +08:00
shy
f34d04c775 add some 2024-10-04 18:43:16 +08:00
shy
20f812aff3 add some 2024-10-04 12:23:37 +08:00
shy
3bfb3f7af3 add some 2024-10-03 19:08:42 +08:00
shy
4b4acce081 add some 2024-10-03 07:42:03 +08:00
shy
e31dcbad3d add some 2024-10-02 22:24:12 +08:00
shy
02e368768b add some 2024-10-01 00:12:48 +08:00
shy
df5510d467 add some 2024-09-29 22:21:06 +08:00
shy
0cdd17355f add some 2024-09-27 23:58:16 +08:00
shy
d377063c0f add some 2024-09-26 13:00:40 +08:00
shy
eeea6f5a77 add some 2024-09-25 22:38:24 +08:00
shy
134235b106 add some 2024-09-25 17:16:25 +08:00
shy
ff1a17fcdf add some 2024-09-24 13:10:58 +08:00
shy
15e9e790be add some 2024-09-20 20:53:44 +08:00
shy
8ba9cefd0f add some 2024-09-19 20:58:58 +08:00
shy
5f3ccc5c65 add some 2024-09-18 20:40:50 +08:00
shy
aec86f5d34 add some 2024-09-18 13:32:47 +08:00
shy
7ca69339be add some 2024-09-15 20:00:24 +08:00
shy
833b44685e add some 2024-09-14 00:36:46 +08:00
shy
e30eb0bfd5 add some 2024-09-12 00:38:24 +08:00
shy
d6d648ff90 add some 2024-09-12 00:13:02 +08:00
shy
a4437facdb add some 2024-09-10 08:06:56 +08:00
shy
f15c99f3bd add some 2024-09-08 11:01:38 +08:00
shy
aca43dd83b add some 2024-09-07 17:11:55 +08:00
shy
d27c8223b2 add some 2024-09-05 20:03:01 +08:00
shy
e44c12376c add some 2024-09-03 22:42:28 +08:00
shy
cafaf8a308 add some 2024-09-03 18:29:21 +08:00
shy
7f93fb9f88 add some 2024-09-02 17:34:11 +08:00
shy
4bd2db3315 add some 2024-09-01 23:45:05 +08:00
shy
e695611fd7 add some 2024-08-30 21:56:35 +08:00
shy
7430e2b312 add some 2024-08-29 11:09:30 +08:00
shy
d8d9ba3b24 add some 2024-08-26 22:15:12 +08:00
shy
459cb45bf4 add some 2024-08-24 20:22:48 +08:00
shy
2e63b0259f add some 2024-08-20 19:54:15 +08:00
shy
904bb34a06 add some 2024-08-18 23:10:19 +08:00
jingganjiaoyu
f394b6f97c opt some 2024-08-18 02:27:32 +08:00
root
134e960e64 add some 2024-08-16 09:19:26 +08:00
shy
5f202a293e add some 2024-08-16 07:53:31 +08:00
shy
6032d02915 add some 2024-08-11 02:04:26 +08:00
shy
75245d87cb add some 2024-08-09 00:04:18 +08:00
shy
8671f50f74 add some 2024-08-06 19:10:26 +08:00
shy
4ef7126abc add some 2024-08-06 01:35:26 +08:00
shy
f392e90f37 add some 2024-08-05 23:20:56 +08:00
shy
29415a6eb2 add some 2024-08-05 02:10:14 +08:00
shy
5f2e629b12 add some 2024-08-04 14:55:12 +08:00
shy
b601a77be5 add some 2024-08-04 01:49:35 +08:00
shy
e035f043ee add some 2024-08-03 09:20:45 +08:00
shy
a23ab72753 add some 2024-08-02 18:41:48 +08:00
shy
118dbaa70c add some 2024-07-31 22:20:32 +08:00
shy
58182dc2a2 add some 2024-07-29 22:49:51 +08:00
shy
68edc8fa54 opt portal 2024-07-28 23:22:04 +08:00
jingganjiaoyu
c9c365e8b0 opt some 2024-07-26 21:40:07 +08:00
shy
f87f4686c9 opt some 2024-07-24 21:54:32 +08:00
shy
fe3eb04c7b add some 2024-07-23 16:04:37 +08:00
shy
c6a90754c3 add some 2024-07-21 14:50:48 +08:00
shy
968f15104c add some 2024-07-20 20:50:29 +08:00
shy
50cfffbf2a add some 2024-07-20 11:05:19 +08:00
shy
d6987088c3 add some 2024-07-19 18:11:07 +08:00
shy
d5f0783828 add some 2024-07-19 00:08:26 +08:00
shy
a5c441a574 add some 2024-07-16 22:24:44 +08:00
shy
ebab2d09ac add some 2024-07-15 17:55:59 +08:00
shy
ff0189dcf4 add some 2024-07-15 09:36:51 +08:00
shy
c2111a2f51 add some 2024-07-12 16:30:12 +08:00
shy
2261a365a7 add some 2024-07-11 01:54:23 +08:00
shy
ad98d694d2 add some 2024-07-09 10:10:19 +08:00
shy
4ef839d9b3 add some 2024-07-08 19:46:47 +08:00
shy
a3469971d1 add some 2024-07-07 18:24:17 +08:00
shy
0bf940b4df add some 2024-07-04 19:34:55 +08:00
shy
2d79b9871b add some 2024-07-04 03:02:10 +08:00
shy
a52eecd1c3 add some 2024-07-03 19:24:26 +08:00
shy
91c12528f2 opt some 2024-07-03 14:32:10 +08:00
shy
a843684da8 opt some 2024-07-01 20:44:40 +08:00
shy
bf970aa2a7 add some 2024-07-01 20:42:23 +08:00
shy
5b9f0bdb66 add some 2024-06-30 19:52:29 +08:00
shy
1e2dce32ad add some 2024-06-29 23:57:08 +08:00
shy
533d4cbf5f add some 2024-06-28 18:39:24 +08:00
shy
78e18b47b3 add some 2024-06-20 10:50:27 +08:00
shy
ad17b22061 add some 2024-06-19 09:11:33 +08:00
shy
20950d875f add some 2024-06-18 10:11:51 +08:00
shy
c67fc1a905 opt some 2024-06-17 21:37:11 +08:00
shy
23f1142ae7 add some 2024-06-17 18:27:19 +08:00
shy
d9e09c0dc3 add some 2024-06-15 23:41:29 +08:00
shy
a0032c60ba add some 2024-06-15 23:40:56 +08:00
shy
9cec65ee5f add some 2024-06-15 18:47:54 +08:00
shy
a8d158616b add some 2024-06-13 07:33:30 +08:00
shy
f2475b7ecc opt some 2024-06-11 20:49:36 +08:00
shy
923ba3ff64 add some 2024-06-11 11:04:20 +08:00
shy
e99a96006f add some 2024-06-10 09:31:57 +08:00
shy
42b2905107 add some 2024-06-09 23:32:15 +08:00
shy
fe30334244 opt some 2024-06-09 22:57:41 +08:00
shy
3774877186 add some 2024-06-08 23:06:28 +08:00
shy
119465db1d add some 2024-06-08 08:01:46 +08:00
shy
8d5f3edf7a add some 2024-06-08 07:56:21 +08:00
shy
68eedc76f1 opt some 2024-06-06 00:03:58 +08:00
shy
8fcb2dfdfa add some 2024-06-06 00:02:04 +08:00
shy
7622ca567f add some 2024-06-05 15:32:43 +08:00
shy
c2b6b3825e add some 2024-06-04 19:58:28 +08:00
shy
b72eabf2fb add some 2024-06-03 18:36:22 +08:00
shy
0dc8cec0d7 add some 2024-06-03 12:43:28 +08:00
shy
6ae43d0f06 add some 2024-06-03 07:53:55 +08:00
shy
f8635d242a add some 2024-06-01 23:04:33 +08:00
shy
50302be95a add some 2024-05-31 19:57:50 +08:00
shy
8f3c12ee99 add some 2024-05-31 02:34:52 +08:00
shy
bbd9ed606b add some 2024-05-30 19:57:12 +08:00
shy
2f2a17e776 add some 2024-05-28 22:42:47 +08:00
shy
3069641bf3 add some 2024-05-28 18:48:40 +08:00
shy
97fcd91e6a add some 2024-05-27 19:32:09 +08:00
shy
8f249670a6 add some 2024-05-27 07:29:27 +08:00
shy
c172f673aa add some 2024-05-26 11:27:53 +08:00
shy
b16bc2632d add some 2024-05-26 08:28:08 +08:00
shy
9e256717c2 add some 2024-05-26 08:07:19 +08:00
shy
2d34d204d8 add some 2024-05-25 20:56:52 +08:00
shy
3282bcede9 add some 2024-05-25 19:56:56 +08:00
shy
8865d923da add some 2024-05-24 19:27:23 +08:00
shy
b21017d1e6 add some 2024-05-23 23:41:29 +08:00
shy
be157798aa add some 2024-05-23 19:16:31 +08:00
shy
8542f11991 add some 2024-05-22 23:07:10 +08:00
shy
78b615141c add some 2024-05-22 18:44:28 +08:00
shy
72a558797e add some 2024-05-21 23:46:00 +08:00
shy
11c15b0aa7 add some 2024-05-21 19:22:48 +08:00
shy
0fd53c1e23 add some 2024-05-21 07:39:21 +08:00
shy
fa4e9d6178 add some 2024-05-20 20:52:36 +08:00
shy
7510c10f2f add some 2024-05-20 07:27:26 +08:00
shy
769f1293ba add some 2024-05-20 01:32:02 +08:00
shy
d80ac7b091 add some 2024-05-19 23:49:40 +08:00
shy
c76de6fef0 add some 2024-05-19 17:14:31 +08:00
shy
94b4faee59 add some 2024-05-19 17:02:46 +08:00
shy
1dd54cbd5d add some 2024-05-18 23:13:52 +08:00
shy
a953d011b4 add some 2024-05-18 22:20:18 +08:00
shy
78ae374e42 add some 2024-05-18 21:02:24 +08:00
shy
a8c2a9ea3b add some 2024-05-17 23:57:57 +08:00
shy
c0bba74b3b add some 2024-05-17 23:42:59 +08:00
shy
0701ed916c add some 2024-05-17 19:39:41 +08:00
shy
bfb6e331a9 add some 2024-05-17 00:24:05 +08:00
shy
c161b906f6 add some 2024-05-16 19:31:53 +08:00
shy
92751f7de6 add some 2024-05-16 08:19:29 +08:00
shy
1dbbba48d9 add some 2024-05-15 18:40:23 +08:00
shy
68f3c17005 add some 2024-05-15 15:58:54 +08:00
shy
f1961220c0 add some 2024-05-14 23:27:35 +08:00
shy
0f1566a0a8 add some 2024-05-14 19:13:28 +08:00
shy
ac01242ec1 add some 2024-05-14 00:02:26 +08:00
shy
54a7872244 add tutor 2024-05-13 20:33:29 +08:00
root
12de0b692a add some 2024-05-13 14:25:44 +08:00
shy
288ad7d59b add some 2024-05-12 15:03:51 +08:00
shy
09a7e4e48f add some 2024-05-11 22:20:22 +08:00
shy
347e43f2b4 add some 2024-05-11 18:21:02 +08:00
root
81935e42a5 add some 2024-05-10 22:16:04 +08:00
shy
e601da8c29 add some 2024-05-10 22:05:23 +08:00
shy
24b4085cc0 add some 2024-05-10 21:54:07 +08:00
shy
7914b395f3 add some 2024-05-10 10:29:19 +08:00
shy
6411732f6a add some 2024-05-09 23:14:38 +08:00
shy
c6c5ec00f1 add some 2024-05-09 22:24:35 +08:00
shy
efda5a480e add some 2024-05-09 15:59:23 +08:00
shy
3d45725678 add some 2024-05-09 11:33:20 +08:00
shy
0b3ee1d4fa add some 2024-05-09 07:25:31 +08:00
shy
b808b4a9ce add some 2024-05-08 00:14:21 +08:00
shy
ffac2c4016 opt table.js 2024-05-07 15:21:18 +08:00
shy
6d3f37c7bc add studio 2024-05-06 23:06:04 +08:00
shy
3587d7ab28 add some 2024-05-06 08:12:16 +08:00
shy
1e774bde03 add some 2024-05-05 23:24:53 +08:00
shy
c515c8229f add some 2024-05-05 17:32:29 +08:00
shy
05049d36a8 add some 2024-05-04 19:20:40 +08:00
shy
994afcf03b add some 2024-05-04 00:31:39 +08:00
shy
59c850714c add some 2024-05-02 07:13:44 +08:00
shy
6042b1a00a add some 2024-05-01 18:43:11 +08:00
shy
c66b9ab28b add some 2024-05-01 18:25:52 +08:00
shy
13260d13c8 add some 2024-04-30 22:11:54 +08:00
shy
1710964e37 add some 2024-04-30 02:34:58 +08:00
shy
517c285808 add some 2024-04-29 14:49:04 +08:00
shy
df13edfa46 add some 2024-04-28 23:26:42 +08:00
shy
8a85e91e35 add some 2024-04-27 20:43:35 +08:00
shy
0ded98804e add some 2024-04-27 18:35:09 +08:00
shy
fda39d8e6d add some 2024-04-27 09:20:46 +08:00
shy
9fb348c414 add some 2024-04-25 21:11:24 +08:00
shy
fa52a9cbb8 add some 2024-04-25 12:38:12 +08:00
shy
430777ed94 add some 2024-04-24 18:10:17 +08:00
shy
0d52e524c2 add some 2024-04-24 16:26:39 +08:00
shy
0ba1d4dbe5 add some 2024-04-24 10:23:08 +08:00
shy
c233f75a13 add some 2024-04-22 15:47:53 +08:00
shy
607f070a7b add some 2024-04-22 15:27:45 +08:00
shy
2e712bdaf7 add some 2024-04-22 11:54:35 +08:00
shy
88f12f173f add some 2024-04-22 10:34:18 +08:00
3054e59506 opt some 2024-04-22 00:38:59 +08:00
da9675602d opt some 2024-04-21 16:01:47 +08:00
shy
4086075a75 add some 2024-04-20 19:26:22 +08:00
shy
2bc798aceb add some 2024-04-20 15:56:20 +08:00
shy
80ff408dc0 add some 2024-04-20 07:25:54 +08:00
shy
6a46ee4983 add some 2024-04-19 21:45:11 +08:00
shy
d9b8c2e788 add some 2024-04-19 19:35:41 +08:00
shy
d221885a7d add some 2024-04-19 17:58:07 +08:00
shy
30c19f8e33 add some 2024-04-19 12:34:06 +08:00
shy
e28c879a36 add some 2024-04-19 02:42:48 +08:00
shy
0b34393e62 add some 2024-04-18 23:35:49 +08:00
shy
8cb7df23d5 add some 2024-04-18 22:47:36 +08:00
shy
739b1aa70c add some 2024-04-18 22:17:54 +08:00
shy
ef6b2ce54e opt border 2024-04-18 22:15:15 +08:00
shy
8064c877aa add some 2024-04-18 13:40:50 +08:00
shy
05964c5450 add some 2024-04-18 10:48:33 +08:00
shy
57fbc4d2dd add some 2024-04-18 00:11:04 +08:00
shy
2a0b5dcc29 add studiolayout 2024-04-17 04:15:08 +08:00
shy
d3e9a345ef add some 2024-04-15 12:25:10 +08:00
shy
42f98ddae1 add some 2024-04-14 23:26:10 +08:00
shy
9efab283d5 add some 2024-04-14 19:26:30 +08:00
root
229b889ce9 add some 2024-04-13 23:18:19 +08:00
shy
eb94b02785 add some 2024-04-12 22:21:31 +08:00
shy
020df619b1 add some 2024-04-11 23:59:49 +08:00
root
6d34e48d2c add some 2024-04-11 21:58:15 +08:00
shy
40ba82b5b2 add some 2024-04-10 13:33:18 +08:00
shy
09810f9d1b add some 2024-04-10 00:32:53 +08:00
shy
9cb7b31bba add some 2024-04-09 18:25:40 +08:00
shy
01b614e608 add some 2024-04-09 13:19:04 +08:00
shy
7514b2004e add some 2024-04-08 21:05:40 +08:00
shy
a62e460dd2 add some 2024-04-08 17:13:59 +08:00
shy
21da385bc1 add some 2024-04-08 13:31:08 +08:00
shy
8ec4c8a04c add some 2024-04-08 12:59:34 +08:00
shy
b296e255e1 add some 2024-04-08 11:20:12 +08:00
shy
b0d687654e add some 2024-04-07 23:14:14 +08:00
shy
9d635cb45e add some 2024-04-07 15:33:17 +08:00
shy
f8d3357648 add some 2024-04-07 13:31:24 +08:00
shy
dea931acee add some 2024-04-07 13:28:43 +08:00
shy
264f0b1afa add some 2024-04-07 12:16:43 +08:00
shy
cc87ddf937 add some 2024-04-07 00:02:24 +08:00
shy
840a166ad1 add some 2024-04-06 23:08:30 +08:00
shy
25424870c6 add some 2024-04-06 22:32:19 +08:00
shy
6276ab803a add some 2024-04-06 15:05:24 +08:00
shy
6ee21fc9ca add some 2024-04-06 00:23:45 +08:00
shy
d083550bb1 add some 2024-04-05 21:15:41 +08:00
shy
eae861fe3a add some 2024-04-04 23:11:36 +08:00
shy
51d98031c1 add some 2024-04-04 13:49:10 +08:00
shy
1ed6f504e4 add some 2024-04-03 02:55:46 +08:00
shy
7dbb612bbe add some 2024-04-02 20:14:53 +08:00
shy
ff697bd057 add some 2024-04-01 20:08:45 +08:00
shy
7e4557cd58 add some 2024-03-30 18:08:55 +08:00
shy
1a00d31ec5 add some 2024-03-29 22:32:10 +08:00
shy
1452695a3b add package 2024-03-28 23:45:07 +08:00
shy
35c87a4d6b add some 2024-03-27 22:17:33 +08:00
shy
d11bd2085d add some 2024-03-27 20:16:47 +08:00
shy
434af52bef add some 2024-03-27 13:25:47 +08:00
shy
741bf23c81 add some 2024-03-27 08:46:12 +08:00
shy
3de5506baf add some 2024-03-27 00:03:34 +08:00
shy
c549f04c3b add some 2024-03-26 15:32:45 +08:00
shy
ff08155c03 add some 2024-03-25 16:47:02 +08:00
shy
f692558ac0 add some 2024-03-23 21:15:21 +08:00
shy
91627380b1 add some 2024-03-21 14:44:21 +08:00
shy
d1612da0e9 add some 2024-03-20 13:18:58 +08:00
shy
e7c34be246 add some 2024-03-17 23:19:48 +08:00
shy
a3f41ef85b add some 2024-03-17 22:13:16 +08:00
shy
68372c797f add some 2024-03-17 15:40:21 +08:00
shy
0fb30b2266 add some 2024-03-17 14:27:44 +08:00
shy
7c21cbaf63 add some 2024-03-17 11:54:37 +08:00
shy
2e1f36d3fd add some 2024-03-16 14:26:31 +08:00
shy
b7cfd28753 add some 2024-03-16 12:38:45 +08:00
shy
3491a13916 add some 2024-03-15 14:41:13 +08:00
shy
1ebf4a5a29 add some 2024-03-15 09:54:33 +08:00
shy
ab89d47fd7 add some 2024-03-15 00:32:43 +08:00
shy
b0f1c06420 add some 2024-03-14 21:13:53 +08:00
shy
3e64f738f0 add some 2024-03-14 20:48:24 +08:00
shy
b9043ce03c add some 2024-03-14 00:51:12 +08:00
shy
f345c7e825 add some 2024-03-13 21:41:53 +08:00
shy
6fe918550a add some 2024-03-13 20:35:35 +08:00
shy
7577841e7b add some 2024-03-13 19:40:34 +08:00
shy
78000870a4 add some 2024-03-13 16:16:00 +08:00
shy
f9e10441d7 add some 2024-03-13 11:56:15 +08:00
shy
24398da793 add some 2024-03-12 18:16:01 +08:00
shy
509d07d1d0 add some 2024-03-12 16:28:01 +08:00
shy
0652d3ae6f add some 2024-03-12 10:20:31 +08:00
shy
d042b34f12 add some 2024-03-12 09:52:07 +08:00
shy
06132ef554 add some 2024-03-11 23:30:19 +08:00
shy
d6ae056435 add some 2024-03-11 17:34:49 +08:00
shy
a9d5334dd6 opt some 2024-03-11 13:10:19 +08:00
shy
f33fa5b9fe add some 2024-03-10 19:48:53 +08:00
shy
b8ad3a3719 add some 2024-03-10 10:52:26 +08:00
shy
79a67bbf44 add some 2024-03-09 15:07:52 +08:00
shy
04c7a8e0d2 add some 2024-03-08 23:52:37 +08:00
shy
bd1096e2fa add some 2024-03-08 21:39:51 +08:00
shy
d7cabef5d0 add some 2024-03-08 20:37:29 +08:00
shy
8fd1bfd572 add some 2024-03-08 19:10:09 +08:00
shy
1c3f272dd6 add some 2024-03-08 19:04:10 +08:00
shy
2b93afe8a7 add some 2024-03-08 11:37:47 +08:00
shy
c4120fb091 add some 2024-03-08 02:17:00 +08:00
shy
16026eefde add ssh.cloud.tencent 2024-03-07 20:32:32 +08:00
shy
2c9d61a11a add some 2024-03-07 10:39:39 +08:00
shy
cdf51bb165 add some 2024-03-07 08:19:38 +08:00
shy
19ca1d8487 add some 2024-03-07 00:03:51 +08:00
shy
74bbce10ea add some 2024-03-06 22:30:55 +08:00
shy
c7f5311300 add some 2024-03-06 19:46:47 +08:00
shy
78581cb912 add some 2024-03-06 14:45:16 +08:00
shy
b92fb496fe add some 2024-03-06 12:43:27 +08:00
shy
6211076e0e add some 2024-03-06 01:46:20 +08:00
shy
263d9a4145 add some 2024-03-06 01:36:42 +08:00
shy
2eb2940fad add some 2024-03-05 22:57:58 +08:00
shy
28603fedec add some 2024-03-05 19:13:54 +08:00
shy
be00b86826 add some 2024-03-05 16:49:52 +08:00
shy
3aae308a3b opt portal 2024-03-05 13:55:38 +08:00
shy
48b32e8324 add some 2024-03-04 23:27:54 +08:00
shy
d27e6eddb2 add some 2024-03-04 19:16:42 +08:00
shy
8f248dc3b0 add some 2024-03-04 16:51:44 +08:00
shy
ea16fd5313 add some 2024-03-04 12:45:42 +08:00
shy
524de99f34 add some 2024-03-04 10:48:27 +08:00
shy
acca353827 add some 2024-03-04 02:36:21 +08:00
shy
0850d12bec add some 2024-03-03 21:14:35 +08:00
shy
d7011fdaa2 add some 2024-03-03 20:15:34 +08:00
shy
b9d09d67c3 add some 2024-03-03 20:15:32 +08:00
shy
1f02e3cf18 add some 2024-03-03 19:32:48 +08:00
shy
0a487409dc add some 2024-03-03 17:17:36 +08:00
shy
7e4aaa6ffe add some 2024-03-03 14:26:46 +08:00
shy
0d198bcec6 add some 2024-03-02 17:26:13 +08:00
shy
f76bb5ec41 add some 2024-03-02 14:56:59 +08:00
shy
2defb8e708 add some 2024-03-01 21:22:02 +08:00
shy
e430ac98d7 add some 2024-03-01 20:35:46 +08:00
shy
b513ad8678 add some 2024-03-01 17:28:27 +08:00
shy
b372a51fc4 add some 2024-03-01 15:58:06 +08:00
shy
d0c96d0a31 add some 2024-03-01 15:18:36 +08:00
shy
b0a2f00577 add some 2024-03-01 13:36:00 +08:00
shy
a7b1c95407 add some 2024-03-01 12:01:47 +08:00
shy
c69eeac9f7 add some 2024-02-29 20:14:34 +08:00
shy
78db3a2b2f add web.stream 2024-02-29 14:04:18 +08:00
shy
e0d7ac0d51 add some 2024-02-29 02:36:47 +08:00
shy
dc07cb9703 add some 2024-02-29 00:29:13 +08:00
shy
1fc2989b36 add some 2024-02-28 23:29:56 +08:00
shy
0e52de58dc add some 2024-02-28 15:18:30 +08:00
shy
668e6faf22 add some 2024-02-28 02:15:00 +08:00
shy
800cdb86fc add some 2024-02-27 22:02:24 +08:00
shy
3bfba9c573 add some 2024-02-27 13:43:59 +08:00
shy
d03091a3c6 add some 2024-02-27 11:37:13 +08:00
shy
3989ec58b9 add web.group 2024-02-27 00:59:05 +08:00
shy
a7cbb6a36a add some 2024-02-25 22:45:59 +08:00
shy
5632a7816f add some 2024-02-25 20:35:07 +08:00
shy
6b7d66c572 add some 2024-02-24 23:27:58 +08:00
shy
71a1172e7d add some 2024-02-24 18:18:53 +08:00
shy
7e29a981aa add some 2024-02-24 12:32:51 +08:00
shy
9af1ed2523 opt some 2024-02-24 00:39:50 +08:00
shy
e1126b2b7c add some 2024-02-23 19:03:01 +08:00
shy
b806c0213e add some 2024-02-22 13:27:55 +08:00
shy
d795b96f6f add some 2024-02-22 11:06:29 +08:00
shy
72651edd89 add some 2024-02-22 09:19:53 +08:00
shy
bd3bc2ba54 add some 2024-02-22 08:23:24 +08:00
shy
df5a01a1f2 add some 2024-02-22 08:18:34 +08:00
shy
b4285c26a3 add some 2024-02-22 08:16:27 +08:00
shy
7f2e447ac4 add some 2024-02-21 14:16:15 +08:00
shy
bcd73814cb add some 2024-02-21 00:41:53 +08:00
shy
66ece69382 add some 2024-02-19 23:45:24 +08:00
shy
f991e6a08d add some 2024-02-18 18:48:03 +08:00
shy
16e292e7bc add some 2024-02-18 13:47:47 +08:00
shy
66bd01d5a7 add some 2024-02-18 13:44:09 +08:00
shy
3c344197bb add some 2024-02-18 12:56:57 +08:00
shy
8a220a4cfd add some 2024-02-18 12:52:45 +08:00
shy
aad3f75d8b add some 2024-02-18 12:30:50 +08:00
shy
bb62f1eca3 opt process 2024-02-17 18:15:59 +08:00
shy
4a484c99aa add some 2024-02-17 08:19:11 +08:00
shy
1bb69d83ef opt toast 2024-02-16 16:05:44 +08:00
shy
996fc59e3f add some 2024-02-16 00:46:19 +08:00
shy
89a3257202 add some 2024-02-16 00:06:47 +08:00
shy
bfe33df671 add some 2024-02-15 19:12:07 +08:00
shy
72b70b97d1 add toast hash 2024-02-15 15:58:00 +08:00
shy
dfc0a9bd01 add some 2024-02-14 23:29:05 +08:00
shy
668427c13f opt matrix 2024-02-14 17:59:16 +08:00
shy
b62f94974e add some 2024-02-13 22:10:23 +08:00
shy
2ba61c67a6 add some 2024-02-13 21:22:04 +08:00
shy
10c9624738 opt matrix 2024-02-13 18:40:33 +08:00
shy
aa139537a9 add matrix 2024-02-13 15:48:22 +08:00
shy
8eff6488df add island.matrix 2024-02-13 03:55:47 +08:00
shy
3cdc5944a3 add some 2024-02-12 13:16:11 +08:00
shy
87c5ea6877 add some 2024-02-11 22:55:57 +08:00
shy
700f90662b add some 2024-02-09 14:19:09 +08:00
shy
459517a18d opt traceid 2024-02-08 10:33:25 +08:00
shy
4b2457b105 add some 2024-02-07 17:45:01 +08:00
shy
930db5d3ce add some 2024-02-07 17:20:56 +08:00
shy
dc9cce0755 opt aaa 2024-02-06 17:56:30 +08:00
shy
790a0e7376 opt aaa.apply 2024-02-06 15:07:51 +08:00
shy
50959a3646 add some 2024-02-05 23:04:11 +08:00
shy
9c867786fb opt some 2024-02-05 22:45:42 +08:00
shy
dd058c0fd4 add some 2024-02-05 13:47:44 +08:00
shy
89df38d885 add some 2024-02-04 11:13:56 +08:00
shy
0151684485 add some 2024-02-04 11:04:17 +08:00
shy
0dfff9f0b8 opt theme 2024-02-03 17:56:36 +08:00
shy
c239ad75b6 add some 2024-02-02 22:27:09 +08:00
shy
8e3aa6317b add some 2024-02-02 17:38:50 +08:00
shy
17d7f3c9ac add island 2024-02-02 17:29:45 +08:00
shy
04b3991922 add island.group 2024-02-02 00:06:01 +08:00
shy
b0416f781c add some 2024-01-31 23:36:52 +08:00
shy
f2658d166b add some 2024-01-31 15:16:38 +08:00
shy
1e1889b618 add process 2024-01-31 14:15:51 +08:00
shy
b37c87c28e add some 2024-01-31 09:54:13 +08:00
shy
59cc180939 add some 2024-01-30 23:52:21 +08:00
shy
786981b1b5 add some 2024-01-30 21:54:04 +08:00
shy
1cea97c11e add some 2024-01-30 19:23:26 +08:00
shy
d136018a20 add some 2024-01-30 18:32:53 +08:00
shy
9986e99cfe add some 2024-01-29 15:19:06 +08:00
shy
64a79a5510 opt some 2024-01-29 15:08:20 +08:00
shy
889840ed13 add some 2024-01-29 10:57:00 +08:00
shy
724b0e2080 add some 2024-01-29 08:40:31 +08:00
shy
5371306bd6 add some 2024-01-28 20:02:02 +08:00
shy
01b353d548 add some 2024-01-28 19:11:23 +08:00
shy
8b931b2ad5 add some 2024-01-28 15:27:08 +08:00
shy
dd73e2fe4d add some 2024-01-28 14:33:02 +08:00
shy
d38fb0cc42 add some 2024-01-28 14:28:20 +08:00
shy
50c1a077be opt some 2024-01-28 14:00:12 +08:00
shy
33c3087831 opt some 2024-01-28 13:58:18 +08:00
shy
54cd4ce662 add some 2024-01-28 12:27:27 +08:00
shy
3c35967f67 add some 2024-01-27 23:55:19 +08:00
shy
983533635d add some 2024-01-27 22:37:54 +08:00
shy
76a213c323 add some 2024-01-27 17:35:13 +08:00
shy
056d1ef39a add some 2024-01-27 12:08:44 +08:00
shy
9073ab33ab add some 2024-01-26 20:55:35 +08:00
shy
6930b1df50 add some 2024-01-26 16:07:55 +08:00
shy
4db3c85026 add some 2024-01-26 16:07:51 +08:00
shy
a83109fb83 add some 2024-01-26 13:12:48 +08:00
shy
ad17bfc6e9 add some 2024-01-26 11:49:02 +08:00
shy
1c926185f9 opt const 2024-01-26 11:04:11 +08:00
shy
35fbfeaf95 opt const 2024-01-26 10:19:17 +08:00
shy
9d779919cc add some 2024-01-25 23:58:54 +08:00
shy
6fa53f36b5 add some 2024-01-25 15:02:59 +08:00
shy
1e4f9e3e8f add some 2024-01-25 13:06:28 +08:00
shy
1a9e64b92d opt chat.message 2024-01-25 13:03:11 +08:00
shy
9df7dcd411 add some 2024-01-25 00:01:24 +08:00
shy
6fc261bae5 add some 2024-01-24 21:43:16 +08:00
shy
e574bca6a8 add chat.message 2024-01-24 19:15:11 +08:00
shy
854d4969ac add some 2024-01-24 09:29:42 +08:00
shy
d9658156a7 add web.store 2024-01-23 14:54:22 +08:00
shy
65514c5382 opt script 2024-01-22 22:24:21 +08:00
shy
bdccc3f40c add some 2024-01-22 17:28:19 +08:00
shy
9419e1aa6c add some 2024-01-22 17:28:12 +08:00
shy
4ab71713cf add some 2024-01-22 14:33:18 +08:00
shy
964a79885e add chat.script 2024-01-21 21:18:13 +08:00
shy
74358a88fa add some 2024-01-21 17:02:07 +08:00
shy
d1bc801c7b add some 2024-01-21 17:02:03 +08:00
shy
66dda357b1 add chat.script 2024-01-21 16:00:57 +08:00
shy
b37f8302fb add chat.script 2024-01-21 10:08:23 +08:00
shy
7126201495 add ice.port 2024-01-20 22:01:26 +08:00
shy
e76809d434 add some 2024-01-20 21:14:32 +08:00
shy
a833ce5fc6 add some 2024-01-20 19:21:07 +08:00
shy
8fbff9a445 add some 2024-01-20 12:10:44 +08:00
shy
f3ee78a0c7 add some 2024-01-19 22:56:22 +08:00
shy
738e7bc810 add some 2024-01-19 21:10:11 +08:00
shy
53031524db add some 2024-01-19 20:33:09 +08:00
shy
0217e10c5f add some 2024-01-19 18:34:47 +08:00
shy
410c25fca9 add some 2024-01-19 14:11:40 +08:00
shy
c879020d3a add some 2024-01-19 09:28:37 +08:00
shy
2a5d9bed64 add some 2024-01-18 22:10:38 +08:00
shy
4253571235 add some 2024-01-17 22:47:21 +08:00
shy
d3a86baffe add some 2024-01-17 19:30:44 +08:00
shy
6af856f3a4 add some 2024-01-17 14:57:21 +08:00
shy
640c60baae add some 2024-01-17 14:35:26 +08:00
shy
91adc0293c add some 2024-01-17 11:25:56 +08:00
shy
154f8d6006 opt some 2024-01-16 22:09:38 +08:00
shy
636ae5a7d9 add some 2024-01-16 18:27:37 +08:00
shy
9179b141a3 add some 2024-01-16 15:28:41 +08:00
shy
6c3dfa04bc add some 2024-01-16 13:15:11 +08:00
shy
3ff489512c add some 2024-01-16 08:48:26 +08:00
shy
184aea2674 add some 2024-01-15 23:14:04 +08:00
shy
21e9a3ef83 add some 2024-01-15 20:37:52 +08:00
shy
46daafd178 add some 2024-01-15 19:12:05 +08:00
shy
17e3b0cd16 opt document 2024-01-15 12:20:01 +08:00
shy
0c5f68e865 opt dream 2024-01-15 09:07:05 +08:00
shy
de409684f4 add some 2024-01-14 22:59:29 +08:00
shy
5a05aacbe9 add some 2024-01-14 22:59:27 +08:00
shy
51528abbd0 add spide token 2024-01-14 19:51:26 +08:00
shy
4bf12ea5e2 add some 2024-01-14 16:09:33 +08:00
shy
3034cb83a7 add some 2024-01-14 13:40:11 +08:00
shy
2f36d36600 add some 2024-01-14 13:11:08 +08:00
shy
98e621c0bd add some 2024-01-14 01:55:34 +08:00
shy
e32ab4ae6b opt island 2024-01-13 22:52:24 +08:00
shy
6d07bd045f opt island 2024-01-13 22:39:23 +08:00
shy
63144fe733 opt island 2024-01-13 15:32:00 +08:00
shy
9232ee3c5d add some 2024-01-13 08:47:23 +08:00
shy
b5795f61f3 opt island 2024-01-12 23:37:18 +08:00
shy
eff1c72a71 opt some 2024-01-12 17:02:38 +08:00
shy
70aca051fb add some 2024-01-12 10:59:55 +08:00
shy
112c0ad987 add some 2024-01-12 10:56:49 +08:00
shy
3201dc2472 add mdb.DevDataAction 2024-01-12 00:41:02 +08:00
shy
45857948b3 opt layout 2024-01-11 19:03:43 +08:00
shy
8930b335b0 opt layout 2024-01-11 12:33:07 +08:00
shy
e6663423af opt layout 2024-01-11 00:07:10 +08:00
shy
5a9d23b1a1 add some 2024-01-10 21:06:50 +08:00
shy
0836be6d9f add some 2024-01-10 14:41:06 +08:00
shy
3e53826abf add some 2024-01-10 13:31:21 +08:00
shy
6fd4389ace add some 2024-01-09 22:30:08 +08:00
shy
e9a63583a4 add some 2024-01-09 20:01:58 +08:00
shy
bf84c5cc93 add some 2024-01-09 10:40:33 +08:00
shy
3b13a9a674 add some 2024-01-09 08:50:09 +08:00
shy
23af0374f7 add some 2024-01-08 22:29:35 +08:00
shy
741d465f0b add some 2024-01-08 21:47:32 +08:00
shy
476774e81e opt aaa.offer 2024-01-08 20:57:41 +08:00
shy
6a9320d28d opt aaa.offer 2024-01-08 18:59:44 +08:00
shy
2374b09767 add some 2024-01-08 11:13:27 +08:00
shy
2720601296 opt some 2024-01-07 17:46:15 +08:00
shy
0b62138431 opt relay 2024-01-06 09:10:03 +08:00
shy
83ca1d0398 opt ice.MSG_DAEMON 2024-01-05 12:25:49 +08:00
shy
9135c80974 add MergeLink 2024-01-04 17:33:42 +08:00
shy
970cc8b523 opt dream 2024-01-04 10:50:20 +08:00
shy
6c66c0ece4 add some 2024-01-04 10:16:50 +08:00
shy
2f34511460 fix grant 2024-01-03 22:40:39 +08:00
shy
6451c99072 add some 2024-01-03 19:42:09 +08:00
shy
18ed99b931 add some 2024-01-02 20:33:27 +08:00
shy
f54f37c715 opt login 2024-01-02 19:38:31 +08:00
shy
ac6f274052 opt aaa.sesss 2024-01-02 17:37:07 +08:00
shy
20ad6179b6 opt aaa.sess 2024-01-02 16:15:38 +08:00
shy
3fc9862372 opt aaa.apply 2024-01-02 12:59:53 +08:00
shylinux@163.com
4f62a19f7b opt aaa.apply 2024-01-02 12:21:03 +08:00
shy
7fd26d6cd5 add aaa.apply 2024-01-01 20:35:11 +08:00
shy
07ba12d6a2 fix MergeURL 2023-12-31 11:07:56 +08:00
shy
9a8d799e90 opt git 2023-12-31 10:33:02 +08:00
shy
9c1a69290d opt git 2023-12-30 20:18:30 +08:00
shy
99cdfe1ded opt dream 2023-12-30 11:23:48 +08:00
shy
890a227ab1 opt auto 2023-12-29 22:58:30 +08:00
shy
568f0e96ac opt url 2023-12-29 17:58:49 +08:00
shylinux
8aa1f22883 add some 2023-12-29 09:43:32 +08:00
shy
d6f6f88624 add status.source 2023-12-28 23:15:53 +08:00
shy
c558c8785b opt portal 2023-12-28 13:14:43 +08:00
shy
bb0213d093 opt some 2023-12-28 10:18:12 +08:00
shy
954e067c7e opt portal 2023-12-28 10:00:33 +08:00
shy
6063fa8fab add some 2023-12-27 10:31:51 +08:00
shy
e8f4b92df3 opt icon 2023-12-27 08:51:38 +08:00
shy
b72d067451 opt icon 2023-12-26 18:34:42 +08:00
shy
ff590400ba opt icon 2023-12-26 15:18:28 +08:00
shy
d900548b10 opt desktop 2023-12-26 11:43:38 +08:00
shy
e2c60c41b1 opt some 2023-12-25 23:20:00 +08:00
shy
d4ee97fd23 opt state.js 2023-12-25 15:33:06 +08:00
shy
fe8c3fb5e2 opt some 2023-12-25 10:28:25 +08:00
shy
befe9011b3 opt some 2023-12-24 21:15:33 +08:00
shy
25cdf367d7 add can.dir 2023-12-24 19:37:04 +08:00
shy
ff638822af add can.dir 2023-12-24 12:23:21 +08:00
shy
31f8748684 add can.dir 2023-12-24 12:23:15 +08:00
shy
8d6cf1d3a1 opt status 2023-12-24 00:18:18 +08:00
shy
35842bd525 add some 2023-12-23 17:02:56 +08:00
shy
80ce58801f opt debug 2023-12-22 22:59:48 +08:00
shy
7babe206ea opt debug 2023-12-22 17:48:53 +08:00
shy
467b944d68 opt space 2023-12-21 12:29:40 +08:00
shy
76d030b0bc opt repos 2023-12-20 23:59:59 +08:00
shy
aed3cd4490 add some 2023-12-20 13:49:04 +08:00
shy
53cf24c4f3 add some 2023-12-19 19:07:06 +08:00
shy
f4dc0782d1 add some 2023-12-14 08:53:45 +08:00
shy
b090c17020 opt icons 2023-12-13 19:10:18 +08:00
shy
eada9edfc4 add some 2023-12-13 18:09:27 +08:00
shy
db88f7d2e3 add some 2023-12-13 12:23:02 +08:00
shy
7ccc8dce08 add some 2023-12-13 09:49:09 +08:00
shy
0709df0188 add some 2023-12-13 00:00:23 +08:00
shy
af0c7e7bf2 add some 2023-12-12 21:42:32 +08:00
shy
c47aec91c0 add some 2023-12-12 15:28:34 +08:00
shy
b7853a10c1 add some 2023-12-12 12:32:29 +08:00
shy
2497ec18ec add some 2023-12-12 12:07:11 +08:00
shy
b6d0bfb5a9 opt some 2023-12-12 11:32:45 +08:00
shy
0c23bd3a25 add some 2023-12-12 08:42:12 +08:00
shy
6fdd3b1f9a add web.count 2023-12-11 22:15:29 +08:00
shy
526579041e add some 2023-12-11 19:08:25 +08:00
shy
7a2534baeb add some 2023-12-11 16:40:41 +08:00
shy
c0b9ce8eb1 add checkbox 2023-12-11 15:38:15 +08:00
shy
1500290674 opt button 2023-12-11 11:46:57 +08:00
shy
bc1150252d fix vimer 2023-12-10 23:25:53 +08:00
shy
9a1bd48da6 opt height and width 2023-12-10 20:39:50 +08:00
shy
9f936179e2 opt mp 2023-12-10 09:50:07 +08:00
shy
0fd8b5a59f add some 2023-12-10 00:21:15 +08:00
shy
28895d9f77 add mp 2023-12-10 00:16:33 +08:00
shy
ce82ffa815 add wx.ide autogen 2023-12-09 18:03:40 +08:00
shy
961559455c add some 2023-12-09 11:27:20 +08:00
shy
ca1818a101 add some 2023-12-09 10:33:06 +08:00
shy
b3a09d726f opt m.FormatMeta 2023-12-09 08:32:08 +08:00
shy
1d3975e844 opt web.stats 2023-12-08 19:37:33 +08:00
shy
3ebb207715 opt some 2023-12-08 12:00:05 +08:00
shy
30744696d6 add usr/program/ 2023-12-07 22:48:04 +08:00
shy
20ef4cfbcd opt some 2023-12-07 11:16:02 +08:00
shy
4712feea55 fix share 2023-12-07 08:57:31 +08:00
shy
bbb85952d7 fix footer.js 2023-12-05 23:18:00 +08:00
shy
655b11ac77 add some 2023-12-05 21:56:42 +08:00
shy
b6dc209117 opt grow 2023-12-05 04:04:27 +08:00
shy
903f3bb993 opt header 2023-12-04 13:15:08 +08:00
shy
e9b053d595 add some 2023-12-03 10:52:15 +08:00
shy
1fd4be665b add some 2023-12-03 00:34:56 +08:00
shy
e7933a68f3 add some 2023-12-02 22:58:26 +08:00
shy
06aa27ecc6 add some 2023-12-02 18:15:00 +08:00
shy
a88b3efdaf add some 2023-12-02 17:04:49 +08:00
shy
c68319b019 add relay 2023-12-02 15:38:31 +08:00
shy
bc98b926da add rc_local.sh 2023-12-01 23:33:36 +08:00
shy
ef7463f33d add some 2023-12-01 20:15:25 +08:00
shy
4cc99a45d3 opt state.js 2023-12-01 12:05:37 +08:00
shy
02f0d1b657 add some 2023-11-30 14:21:10 +08:00
shy
77f2094f5d add some 2023-11-30 13:49:12 +08:00
shy
d11548d75e add some 2023-11-30 13:14:31 +08:00
shy
6d5c7e7ac3 opt some 2023-11-30 00:46:50 +08:00
shy
a52753244f add wx.login 2023-11-30 00:39:11 +08:00
shy
ebdd932d40 opt wx.ide 2023-11-29 16:10:34 +08:00
shy
fd85b603ad add flex 2023-11-27 23:30:27 +08:00
shy
f3e128d91f add some 2023-11-27 14:00:38 +08:00
shy
5f353c212f add some 2023-11-27 13:18:48 +08:00
shy
9cffc62371 add some 2023-11-27 00:06:43 +08:00
shy
ed1512f9d4 add main.css 2023-11-26 21:08:45 +08:00
shy
bb44266637 add some 2023-11-26 14:43:05 +08:00
shy
6b45a242d6 add some 2023-11-26 14:31:52 +08:00
shy
8fb302feea fix some 2023-11-26 14:08:49 +08:00
shy
d75cfdadd2 opt desktop 2023-11-26 13:42:59 +08:00
shy
a8ab134d8e opt favor 2023-11-26 00:03:29 +08:00
shy
15837b45f6 add some 2023-11-24 20:33:26 +08:00
shy
d934ca02b0 add some 2023-11-24 20:21:59 +08:00
shy
44461f941c add some 2023-11-24 17:46:35 +08:00
shy
1444daee71 add some 2023-11-23 23:28:05 +08:00
shy
e6926b334f opt theme 2023-11-23 23:14:34 +08:00
shy
82f7917d58 opt theme 2023-11-23 23:02:06 +08:00
shy
135b82dee7 add body.width6 2023-11-23 10:18:12 +08:00
shy
90fad13d86 add some 2023-11-22 22:43:22 +08:00
shy
e7302da259 add some 2023-11-22 14:50:32 +08:00
shy
2f5a9d4d97 add some 2023-11-22 10:48:49 +08:00
shy
a101a5379d opt css size 2023-11-22 10:17:00 +08:00
shy
0076697bf0 add some 2023-11-22 00:03:21 +08:00
shy
c22051ac58 add some 2023-11-21 21:10:20 +08:00
shy
87c9232f65 add mp 2023-11-21 15:53:00 +08:00
shy
bfabe57ea3 add wifi 2023-11-21 12:25:26 +08:00
shy
25c2e34512 add wx.ide 2023-11-20 22:33:20 +08:00
shy
fb8c552161 add some 2023-11-20 22:30:22 +08:00
shy
e79536baae add mp/theme.json 2023-11-19 23:19:44 +08:00
shy
01839c4e74 add mp 2023-11-19 00:06:45 +08:00
shy
8bad0dc706 add some 2023-11-18 18:59:03 +08:00
shy
3ae4c800db add mp 2023-11-18 16:20:04 +08:00
shy
7e5ff58415 add mp 2023-11-18 13:00:13 +08:00
shy
044f44955b add mp 2023-11-18 00:03:04 +08:00
shy
7597d12bda add some 2023-11-16 21:35:35 +08:00
shy
d5830c34cd add stats 2023-11-16 16:49:02 +08:00
shy
b0653a81e5 add stats 2023-11-16 13:11:09 +08:00
shy
df18a7ef70 add some 2023-11-15 11:11:31 +08:00
shy
bc89016e4f add some 2023-11-14 08:46:19 +08:00
shy
a7d3b0daf6 opt header 2023-11-12 10:53:53 +08:00
shy
1f65b13893 add some 2023-11-11 18:22:43 +08:00
shy
c1fc8c9c32 add some 2023-11-11 14:06:15 +08:00
shy
8c75857b90 add some 2023-11-11 00:07:00 +08:00
shy
117e3a6d20 add wx.shy 2023-11-10 17:33:59 +08:00
shy
fa2f3dceb4 add wx.shy 2023-11-10 02:12:56 +08:00
shy
59b9e5b39c add some 2023-11-08 17:36:32 +08:00
shy
24a9f27fe3 add location.js 2023-11-08 00:59:12 +08:00
shy
60f81b5d51 add some 2023-11-07 09:30:14 +08:00
shy
1a71629774 add some 2023-11-06 16:02:19 +08:00
shy
35f77e68c5 add some 2023-11-06 13:47:25 +08:00
shy
77e5c4b82a add some 2023-11-05 23:30:27 +08:00
shy
83bfa89856 add some 2023-11-05 13:27:53 +08:00
shy
e595dc54fd add china 2023-11-05 08:33:21 +08:00
shy
db2d0d8b6a add some 2023-11-03 12:20:36 +08:00
shy
563208cd88 add some 2023-11-02 23:25:35 +08:00
shy
c7cb5b63ae add some 2023-11-02 17:07:55 +08:00
shy
32c28a9f1a add some 2023-11-02 11:50:54 +08:00
shy
fff6937c88 add some 2023-11-02 09:57:33 +08:00
shy
9230508c2b add some 2023-11-02 09:05:26 +08:00
shy
e35c4f02f8 add some 2023-11-01 20:08:49 +08:00
shy
f73b5a9c51 add some 2023-11-01 19:35:47 +08:00
shy
9e3ceb941e add some 2023-10-31 10:00:09 +08:00
shy
220861638c add some 2023-10-31 07:35:27 +08:00
shy
e4e7b65243 add some 2023-10-29 22:32:16 +08:00
shy
dd89856447 add some 2023-10-28 23:59:31 +08:00
shy
51cd8ca01a add some 2023-10-27 13:38:55 +08:00
shy
dcc5f9062d add some 2023-10-27 00:19:13 +08:00
shy
a123b51e68 add mall/goods.js 2023-10-26 17:59:25 +08:00
shy
56d7ecc7ad add some 2023-10-23 22:30:29 +08:00
shy
3b43f9f0d6 add some 2023-10-19 21:07:58 +08:00
shy
181adb5589 add some 2023-10-17 16:19:08 +08:00
shy
57d741653a add some 2023-10-17 10:42:38 +08:00
shy
a2546c5fac add some 2023-10-16 19:55:36 +08:00
shy
aca36e480c add some 2023-10-16 18:27:53 +08:00
shy
cc0aa5084f add some 2023-10-14 12:56:20 +08:00
shy
92cf6348a6 add some 2023-10-13 22:27:28 +08:00
shy
77564345e7 add some 2023-10-13 21:05:04 +08:00
shy
da233802e5 add some 2023-10-13 00:43:00 +08:00
shy
9e6b449738 add some 2023-10-12 20:14:22 +08:00
shy
8adf3b2e4b add some 2023-10-12 17:25:06 +08:00
shy
23407ebd50 add some 2023-10-12 11:53:35 +08:00
shy
357f865e9a add m.Status 2023-10-12 08:54:12 +08:00
shy
503a8aab0b opt git 2023-10-11 11:53:08 +08:00
shy
d7a654b2f0 opt git 2023-10-09 20:21:56 +08:00
shy
57f26fff6d opt wiki 2023-10-09 13:07:10 +08:00
shy
4646f45cc2 opt draw 2023-10-08 16:58:49 +08:00
shy
9c534a841e add some 2023-10-08 09:15:12 +08:00
shy
714fbeec64 opt draw 2023-10-07 07:48:36 +08:00
shy
49abd4f131 add some 2023-10-05 23:35:45 +08:00
shy
ba1aa7c641 add some 2023-10-05 22:18:26 +08:00
shy
2cc0b2c5c2 opt feel 2023-10-05 21:14:23 +08:00
shy
62b943844e add some 2023-10-05 13:03:36 +08:00
shy
ad435c076d opt code 2023-10-04 15:00:35 +08:00
shy
15400bf0c1 add some 2023-10-03 20:03:19 +08:00
shy
dd5f0b0c46 add some 2023-10-03 17:49:46 +08:00
shy
01d6896d28 add some 2023-10-02 09:53:51 +08:00
shy
f5fcce9505 add some 2023-09-30 08:58:38 +08:00
shy
79b82f7c5a add some 2023-09-29 12:26:51 +08:00
shy
5dd245749b add some 2023-09-27 19:18:51 +08:00
shy
0c6afe560d opt some 2023-09-26 10:06:32 +08:00
shy
dd846ade9e add some 2023-09-25 21:40:13 +08:00
shy
dcfdfcd9b5 opt chat 2023-09-25 18:45:27 +08:00
shy
5355a465fd opt location.js 2023-09-22 07:16:46 +08:00
shy
c81f803764 add ctx.CmdAction 2023-09-21 01:33:16 +08:00
shy
9706ddbc29 opt base 2023-09-19 21:36:02 +08:00
shy
add0dfc832 add icon 2023-09-18 22:07:51 +08:00
shy
ec8910c462 add some 2023-09-18 18:28:48 +08:00
shy
f1d2863645 add some 2023-09-18 15:20:52 +08:00
shy
6d39c2ff34 add some 2023-09-17 09:06:52 +08:00
shy
c9fb8d2a3e add some 2023-09-16 12:04:11 +08:00
shy
01548ab7cf add some 2023-09-14 15:22:29 +08:00
shy
c7df105dbb add some 2023-09-13 09:40:53 +08:00
shy
780ff3decc add some 2023-09-12 08:07:14 +08:00
shy
7fdd6bd314 add some 2023-09-11 09:26:08 +08:00
shy
e46897bdc8 add some 2023-09-10 18:00:31 +08:00
shy
1cb6f755e9 add some 2023-09-10 17:14:42 +08:00
shy
7d4ce180dd opt oauth 2023-09-10 11:23:12 +08:00
shy
4f9b4fb8cf opt some 2023-09-09 18:27:50 +08:00
shy
bf3ca5d28f add clock 2023-09-08 18:19:22 +08:00
shy
deb7479057 add clock 2023-09-08 18:19:08 +08:00
root
1143e38b72 add some 2023-09-06 22:28:59 +08:00
shy
1dae347fe7 add some 2023-09-06 16:06:01 +08:00
shy
89cb1a379a add some 2023-09-05 12:27:01 +08:00
shy
99900b8b2a add some 2023-09-04 11:39:40 +08:00
shy
ff20374049 add git.search 2023-09-03 23:33:43 +08:00
shy
ee1b6eea5c add some 2023-09-03 09:40:11 +08:00
shy
f9ca819136 add some 2023-09-03 09:35:20 +08:00
shy
6eebf8f8e0 add some 2023-09-01 18:25:21 +08:00
shy
2eea75f52f add some 2023-09-01 16:52:26 +08:00
shy
2fbaf9398a add some 2023-09-01 15:57:00 +08:00
shy
ffd0ee57d0 add monaco 2023-08-30 22:08:58 +08:00
shy
183f0a02d9 add some 2023-08-28 22:56:14 +08:00
shy
a5db16e1d7 opt index.css 2023-08-28 19:42:21 +08:00
shy
256b4169ff opt theme 2023-08-28 13:47:03 +08:00
shy
4c70281715 opt studio 2023-08-27 21:06:17 +08:00
shy
6ce3d264f5 add some 2023-08-26 22:45:41 +08:00
shy
4068d72b80 add some 2023-08-26 21:09:17 +08:00
shy
83924c5520 add some 2023-08-23 11:14:23 +08:00
shy
514256ec07 add some 2023-08-21 19:05:38 +08:00
shy
a25e5d1901 add mail 2023-08-21 01:33:49 +08:00
shy
2cf9dcee54 add email 2023-08-19 22:07:06 +08:00
shy
2498178ae7 add some 2023-08-18 17:46:28 +08:00
shy
c5f08a07a1 add some 2023-08-18 17:37:01 +08:00
shy
8db38ea90b add some 2023-08-18 17:25:26 +08:00
shy
7db574432a add some 2023-08-18 17:17:27 +08:00
shy
c497990efe add some 2023-08-18 17:05:35 +08:00
shy
64956c0f00 add const.js 2023-08-18 13:04:06 +08:00
shylinux
8659354723 add some 2023-08-16 23:38:24 +08:00
shylinux
beae5a971c add some 2023-08-16 08:12:02 +08:00
shy
18ab2b8534 add some 2023-08-16 00:12:59 +08:00
shy
3d919855ec add some 2023-08-14 23:12:40 +08:00
shy
85d4f28161 opt some 2023-08-14 11:04:57 +08:00
821432e63d opt some 2023-08-14 11:03:37 +08:00
shy
ce293a085d add some 2023-08-13 22:14:14 +08:00
shy
417fb04154 add some 2023-08-13 09:59:35 +08:00
shy
966388c537 add some 2023-08-12 01:13:20 +08:00
6c9ded301c add some 2023-08-11 18:24:00 +08:00
aab5701f29 add some 2023-08-10 21:28:09 +08:00
74b1e175ea add some 2023-08-09 16:22:47 +08:00
ac7f9778ab add some 2023-08-08 10:56:24 +08:00
009c1ff57b add some 2023-08-08 03:45:02 +08:00
c001c90cf9 add some 2023-08-04 18:19:19 +08:00
5a85b2ea2e opt some 2023-08-04 12:25:19 +08:00
8364935dfb add some 2023-08-03 13:51:23 +08:00
fcbe972200 add some 2023-08-03 12:14:44 +08:00
5caedfb8bb add some 2023-08-01 10:04:54 +08:00
bf5fe5632d add some 2023-07-31 16:48:48 +08:00
047375297d add some 2023-07-31 00:17:45 +08:00
297c99ca10 opt web.flows 2023-07-30 23:35:12 +08:00
f756084084 add web.flows 2023-07-30 09:48:04 +08:00
98b5ba2c2b opt web.route 2023-07-28 22:49:24 +08:00
6556451c77 add web.route 2023-07-28 00:49:06 +08:00
5b142ba206 add some 2023-07-26 22:48:00 +08:00
6fb00ba9e8 add some 2023-07-26 17:57:09 +08:00
fb13dabd77 add web.count 2023-07-26 14:23:34 +08:00
66ef36e047 add some 2023-07-25 17:46:46 +08:00
f3a6de8624 opt some 2023-07-22 16:55:50 +08:00
619e35c71a opt some 2023-07-22 10:57:10 +08:00
f934e2b0e5 opt some 2023-07-22 09:04:46 +08:00
40d267a29d opt some 2023-07-17 11:26:44 +08:00
6b11901e4f opt some 2023-07-17 10:42:44 +08:00
b33b3ae6ff opt some 2023-07-17 09:01:00 +08:00
2e381381f9 opt some 2023-07-16 22:18:53 +08:00
85fcfa4f1d opt some 2023-07-16 14:04:35 +08:00
bd44981a94 opt some 2023-07-15 10:14:31 +08:00
6f68ae72dd opt some 2023-07-14 16:37:43 +08:00
6718744523 opt some 2023-07-14 13:01:30 +08:00
99e03c3faa opt some 2023-07-14 12:58:38 +08:00
dfb425bdb5 opt some 2023-07-13 15:01:35 +08:00
20ac545320 opt some 2023-07-12 22:47:14 +08:00
065db9b1d6 opt some 2023-07-12 12:49:45 +08:00
1b3aeec89f opt some 2023-07-11 17:58:59 +08:00
1fe6bf2adc opt some 2023-07-11 11:04:57 +08:00
a258be41cf opt some 2023-07-10 12:48:25 +08:00
4ec47af1cc opt some 2023-07-08 17:12:12 +08:00
a859e8e805 opt some 2023-07-08 16:04:22 +08:00
36c8b11cf1 opt some 2023-07-08 12:42:51 +08:00
171c29d73d opt some 2023-07-08 08:55:59 +08:00
shy
651d6ba166 opt some 2023-07-08 08:40:40 +08:00
8d0a8e579a opt some 2023-07-08 08:29:53 +08:00
727c9d1e29 opt some 2023-07-07 16:34:47 +08:00
0714432ee1 opt feel 2023-07-06 18:47:33 +08:00
c71aa49a57 opt some 2023-07-05 15:57:48 +08:00
0bf2b069c6 opt portal 2023-07-05 00:45:29 +08:00
b66da3f811 opt some 2023-07-04 11:05:08 +08:00
524d19cd04 opt some 2023-07-01 22:35:59 +08:00
072eeb97fa opt portal 2023-07-01 13:44:25 +08:00
c846b98501 opt portal 2023-06-29 21:23:53 +08:00
98be025830 add portal 2023-06-28 21:55:06 +08:00
899fab6bf6 add theme 2023-06-24 11:55:34 +08:00
029cbf5de9 add cssvar 2023-06-23 18:30:54 +08:00
d276fb2efd opt vue 2023-06-04 21:27:44 +08:00
e56c93ffbc add some 2023-06-03 17:07:21 +08:00
3de3c9afa6 add node 2023-06-03 10:17:02 +08:00
5a501e9831 add node 2023-06-03 09:06:44 +08:00
e41a18978e add some 2023-05-28 20:06:54 +08:00
da34282cf3 add some 2023-05-27 12:19:51 +08:00
10c8fd0ee9 add some 2023-05-27 10:33:54 +08:00
e7ab94cae3 add some 2023-05-26 15:51:37 +08:00
1ec02d142a add some 2023-05-25 16:00:45 +08:00
4fb9445046 opt procstat 2023-05-24 14:22:26 +08:00
ab8a779aea add procstat 2023-05-24 01:42:37 +08:00
a6d6250839 add some 2023-05-22 22:19:52 +08:00
0e13a4be84 add some 2023-05-22 15:48:19 +08:00
75ee12eed9 add some 2023-05-21 17:44:42 +08:00
88e3ce86a2 add some 2023-05-20 14:37:32 +08:00
fdd7848616 opt some 2023-05-16 09:23:12 +08:00
346a051790 opt some 2023-05-14 16:11:45 +08:00
53bab2b443 add some 2023-05-14 16:01:31 +08:00
b5c6bc0cf6 opt iterm 2023-05-13 20:45:32 +08:00
322e7b1c95 add iterm.go 2023-05-13 00:46:45 +08:00
77b8d8c649 opt some 2023-05-12 00:02:51 +08:00
97239bcca5 opt some 2023-05-11 13:10:10 +08:00
a0ab7e58a0 opt some 2023-05-10 10:38:36 +08:00
3888cd8593 opt some 2023-05-07 22:24:00 +08:00
fe17b61034 opt some 2023-05-05 00:21:05 +08:00
1a00d79809 opt some 2023-05-04 14:18:18 +08:00
ac6f14877c opt macos 2023-05-03 23:23:59 +08:00
71462d8c0e add searchs 2023-05-03 16:46:57 +08:00
fbb0ef2c5f opt some 2023-05-02 21:51:38 +08:00
4b0bd0b112 opt desktop 2023-05-02 17:29:52 +08:00
ddaa548f24 opt some 2023-05-02 07:42:19 +08:00
e1b3ec589f opt some 2023-04-30 13:03:06 +08:00
3280bf81d5 opt macos 2023-04-30 10:50:07 +08:00
64190c395d opt some 2023-04-29 23:17:25 +08:00
695b5b658e opt theme 2023-04-29 20:19:13 +08:00
0e50b34b2f add macosx 2023-04-28 22:34:53 +08:00
6e497a4e98 opt some 2023-04-27 14:33:58 +08:00
dad3076a88 opt some 2023-04-27 14:25:22 +08:00
2372a78e57 opt service 2023-04-26 23:37:04 +08:00
92ce8ced89 opt some 2023-04-26 00:32:21 +08:00
666dea06eb opt some 2023-04-25 22:55:09 +08:00
ed492b649e add space 2023-04-25 22:41:50 +08:00
8d4d047ca0 opt some 2023-04-24 21:45:10 +08:00
52a02bef40 opt some 2023-04-24 16:02:06 +08:00
019791e42f opt some 2023-04-23 21:24:21 +08:00
942aac2df3 opt const 2023-04-23 12:07:09 +08:00
c12d47c82d add some 2023-04-22 21:23:59 +08:00
63538d7bf9 opt svg 2023-04-21 14:25:01 +08:00
0386cc5bf1 opt some 2023-04-21 07:59:53 +08:00
0ad3e4ca3d opt vimer.js 2023-04-20 21:00:49 +08:00
116eea85b8 add vimer.css 2023-04-20 11:34:23 +08:00
1472a2fb4d opt vimer 2023-04-19 23:59:46 +08:00
33b4e32926 opt vimer.layout 2023-04-19 21:48:42 +08:00
3c0644f37d opt vimer 2023-04-19 07:08:24 +08:00
c50f7ef5bb add some 2023-04-18 07:32:23 +08:00
6779eed0c5 add some 2023-04-17 21:21:01 +08:00
84280ccb94 add some 2023-04-17 21:16:09 +08:00
e2d43aca05 add some 2023-04-17 21:16:04 +08:00
b2f9a84a5b add git 2023-04-15 00:26:35 +08:00
bfe2f0cf95 opt some 2023-04-14 11:58:38 +08:00
be7a780b67 opt some 2023-04-14 10:20:48 +08:00
ce07afec9f opt story 2023-04-13 23:43:47 +08:00
b5850b98a0 opt wiki 2023-04-13 02:52:53 +08:00
f3ad90a0a8 opt some 2023-04-12 10:44:10 +08:00
9680710c57 opt wiki 2023-04-12 10:35:11 +08:00
11c33fca04 opt kit 2023-04-10 00:25:50 +08:00
313bb594e5 opt stack 2023-04-07 21:41:50 +08:00
8af43adc3d add yac.type 2023-04-06 15:35:47 +08:00
c879088861 opt some 2023-04-02 15:40:11 +08:00
6da40b1ed1 add exp 2023-04-02 08:22:39 +08:00
bd50dc9dd9 opt yac 2023-03-31 13:01:42 +08:00
6427a5344f opt yac 2023-03-29 15:15:21 +08:00
ea55af9bbf opt some 2023-03-29 14:05:13 +08:00
ec5102aee6 opt yac 2023-03-29 12:54:59 +08:00
fad25a8ce4 opt yac 2023-03-28 22:38:01 +08:00
aeef98d18b opt base 2023-03-27 21:23:10 +08:00
00761617e8 opt broad 2023-03-26 17:55:31 +08:00
32ab2bd5fc opt space 2023-03-26 01:57:23 +08:00
9556bb6618 opt some 2023-03-23 21:32:32 +08:00
c2d7e27afe opt mdb 2023-03-23 00:13:33 +08:00
4cac13c155 opt lock 2023-03-22 17:31:22 +08:00
17221e83ea opt some 2023-03-20 11:51:08 +08:00
37dc4148e8 opt some 2023-03-20 01:26:41 +08:00
bdf3dbaf13 opt some 2023-03-19 22:49:22 +08:00
2a26065a2e opt some 2023-03-19 20:44:35 +08:00
e7b7f8a968 opt code 2023-03-19 15:18:44 +08:00
13a9429bd5 opt code 2023-03-17 08:08:53 +08:00
1ca5eea8e1 opt code 2023-03-16 23:05:26 +08:00
a0d8bc8764 opt vimer.js 2023-03-15 20:37:20 +08:00
9d08978d94 opt some 2023-03-14 16:59:07 +08:00
44bcf724d9 opt some 2023-03-14 12:15:32 +08:00
b02f8be174 opt xterm.js 2023-03-14 12:08:55 +08:00
24403b7292 opt some 2023-03-12 10:11:08 +08:00
f99d6d5320 opt some 2023-03-11 17:20:47 +08:00
727b7a378b opt some 2023-03-11 10:17:08 +08:00
9a1092dade opt some 2023-03-10 22:14:31 +08:00
13614b1ee0 opt some 2023-03-10 17:21:13 +08:00
fc91e54ae1 opt xterm 2023-03-10 07:24:27 +08:00
d0c61aae3f opt code 2023-03-09 11:39:27 +08:00
3aee99aa22 opt code 2023-03-07 23:41:51 +08:00
3154844147 opt code 2023-03-07 03:44:23 +08:00
f57aba1296 opt module 2023-03-06 18:59:11 +08:00
48bfa27388 opt word.js 2023-03-05 10:47:38 +08:00
7ef36d23a5 opt some 2023-03-04 21:18:41 +08:00
7ab6da8005 opt some 2023-03-04 21:05:47 +08:00
7f8b1a5619 opt div.item 2023-03-04 21:00:44 +08:00
a9e3f1138f opt sh.go 2023-03-04 16:47:30 +08:00
cfeede0cd5 opt some 2023-03-03 08:50:55 +08:00
be78b4a184 opt some 2023-03-02 20:38:28 +08:00
649c8d8074 opt some 2023-03-02 18:39:24 +08:00
bcc466d95d opt some 2023-03-02 13:29:15 +08:00
169d5eadd0 opt some 2023-03-02 09:59:26 +08:00
bc8bdb41c6 opt some 2023-03-01 12:42:41 +08:00
34e068893f opt some 2023-02-28 21:46:07 +08:00
9e0324a609 opt some 2023-02-28 17:17:27 +08:00
shaoying
caf59837b7 opt some 2023-02-26 12:23:21 +08:00
1b5d0525e5 opt some 2023-02-26 00:02:46 +08:00
harveyshao
d24d8120ea opt some 2023-02-21 21:12:33 +08:00
harveyshao
9a3285e742 opt intshell 2023-02-21 13:26:36 +08:00
harveyshao
15345d1224 opt some 2023-02-21 09:04:32 +08:00
harveyshao
60874e2f3e opt code 2023-02-20 19:17:04 +08:00
harveyshao
1d4df49812 opt some 2023-02-20 09:08:03 +08:00
harveyshao
f469683ee9 opt module 2023-02-20 01:07:31 +08:00
b70ead0537 opt some 2023-02-19 19:32:15 +08:00
harveyshao
21cc8ee8c5 opt code 2023-02-19 19:14:21 +08:00
harveyshao
c767b91172 opt some 2023-02-19 07:39:15 +08:00
harveyshao
e74f7b5957 opt some 2023-02-18 13:05:57 +08:00
harveyshao
a8775c39b5 opt some 2023-02-18 11:23:02 +08:00
shaoying
0acab85b0b opt some 2023-02-18 09:07:18 +08:00
shylinux
05c735bf53 opt some 2023-02-18 00:09:38 +08:00
shylinux
4b0a552887 opt some 2023-02-17 22:14:16 +08:00
harveyshao
0202603b85 opt table.js 2023-02-16 21:49:41 +08:00
harveyshao
f9f88bc461 opt input.js 2023-02-16 14:45:09 +08:00
harveyshao
d4e8cbd4a9 opt some 2023-02-15 19:32:17 +08:00
harveyshao
412d38c33a opt some 2023-02-15 10:30:03 +08:00
harveyshao
3601129c3a opt windows 2023-02-14 19:47:50 +08:00
shylinux
803c6ed691 opt some 2023-02-14 19:46:02 +08:00
harveyshao
44d88552bf opt some 2023-02-14 11:32:11 +08:00
shaoying
27f83c4aa9 opt some 2023-02-13 23:26:28 +08:00
harveyshao
59a72ade26 opt some 2023-02-13 22:30:45 +08:00
harveyshao
49d0c1ab0e opt some 2023-02-13 09:52:42 +08:00
shaoying
c87e93a221 opt some 2023-02-13 09:05:44 +08:00
harveyshao
e715794e76 opt date.js 2023-02-12 23:43:47 +08:00
shaoying
a912f2f8a4 opt date.js 2023-02-12 09:04:48 +08:00
harveyshao
300e58f7e5 opt date.js 2023-02-11 23:56:16 +08:00
shaoying
58d8223aaf opt some 2023-02-11 19:37:26 +08:00
harveyshao
6e4d0037f1 opt key.js 2023-02-11 13:58:34 +08:00
shaoying
89e5630ea3 opt river.js 2023-02-10 13:27:04 +08:00
shaoying
6b2d9a1793 opt some 2023-02-09 01:13:56 +08:00
shaoying
df5be1bcba opt lib 2023-02-08 23:09:20 +08:00
shaoying
672f5fc594 opt some 2023-02-04 10:00:43 +08:00
harveyshao
4cab052f01 opt some 2023-01-31 16:35:54 +08:00
harveyshao
ef95c993e5 opt search.js 2023-01-31 00:00:08 +08:00
harveyshao
44b1d7edfd opt search.js 2023-01-30 15:04:16 +08:00
harveyshao
95aae74d9c opt search.js 2023-01-29 23:18:46 +08:00
harveyshao
6dda44645e opt panel 2023-01-29 10:07:00 +08:00
harveyshao
0fea145163 opt panel 2023-01-28 23:18:02 +08:00
harveyshao
2005643e05 opt footer.js 2023-01-28 11:33:20 +08:00
5961931e3a opt some 2023-01-28 08:07:11 +08:00
harveyshao
775851f248 opt action.js 2023-01-27 22:51:10 +08:00
harveyshao
8cff6f4572 opt action.js 2023-01-27 20:54:00 +08:00
harveyshao
5917a5f752 opt some 2023-01-26 22:14:20 +08:00
harveyshao
dabcaa5421 opt vimer.js 2023-01-26 20:51:17 +08:00
harveyshao
00394e2c84 opt inner.js 2023-01-26 13:26:32 +08:00
harveyshao
2dfd2306da opt inner.js 2023-01-25 23:13:23 +08:00
9230c610a4 opt some 2023-01-25 09:33:19 +08:00
harveyshao
8ec1f532b1 opt vimer.js 2023-01-25 00:35:37 +08:00
harveyshao
78806f186f opt some 2023-01-23 14:49:04 +08:00
harveyshao
225747a388 opt can.debug 2023-01-23 14:20:29 +08:00
harveyshao
05461aeba5 opt can.debug 2023-01-22 15:56:26 +08:00
harveyshao
a6726463e0 opt can.debug 2023-01-21 19:02:29 +08:00
harveyshao
ba3b7713b4 add can.page.AppendData 2023-01-21 00:46:00 +08:00
harveyshao
ecf90a81da opt log 2023-01-20 14:50:58 +08:00
shaoying
13b2165d84 opt table.js 2023-01-18 19:08:08 +08:00
harveyshao
4d69f1f5ed opt onappend 2023-01-18 17:01:58 +08:00
harveyshao
65b749e9bb opt onappend 2023-01-17 23:28:26 +08:00
harveyshao
d107762a55 opt frame.js 2023-01-16 22:20:56 +08:00
harveyshao
bcc185bd3e opt index.css 2023-01-15 18:00:08 +08:00
harveyshao
8745ff5ec6 opt some 2023-01-14 08:44:36 +08:00
harveyshao
1b1e55d308 opt index.css 2023-01-13 16:11:27 +08:00
harveyshao
67d3e2e8c3 opt some 2023-01-12 22:26:02 +08:00
harveyshao
20197d3317 opt inner.css 2023-01-12 20:21:17 +08:00
harveyshao
4a083e6b85 opt some 2023-01-11 04:56:19 +08:00
harveyshao
9148445d60 add dark 2023-01-10 21:42:22 +08:00
39042db745 opt some 2023-01-04 18:36:22 +08:00
c62c8e381a opt some 2023-01-03 21:27:06 +08:00
763df8c2d3 opt some 2023-01-03 15:11:43 +08:00
harveyshao
4156dcc267 opt some 2023-01-02 20:29:02 +08:00
harveyshao
5b180ca402 opt some 2023-01-02 14:20:49 +08:00
harveyshao
12b0be7eb0 opt some 2023-01-01 22:45:05 +08:00
harveyshao
0055c7a5e3 opt some 2022-12-31 20:59:31 +08:00
harveyshao
3bc6fd060b opt some 2022-12-31 18:38:41 +08:00
harveyshao
877acf5ba8 opt some 2022-12-30 21:08:06 +08:00
harveyshao
ae2ea11c4f opt some 2022-12-27 19:26:00 +08:00
shaoying
58ddba5619 opt some 2022-12-27 11:52:03 +08:00
harveyshao
0c0c9c5994 opt some 2022-12-26 23:14:56 +08:00
harveyshao
39ddf4a282 opt page/index.css 2022-12-26 21:31:06 +08:00
harveyshao
3495b8ac4d opt some 2022-12-26 15:25:23 +08:00
harveyshao
20b03f623b opt css 2022-12-26 10:34:11 +08:00
harveyshao
dd8cbd7b00 opt some 2022-12-24 23:44:09 +08:00
harveyshao
13b66860da opt some 2022-12-24 15:13:34 +08:00
70ed2bca57 opt some 2022-12-23 20:29:19 +08:00
harveyshao
c3f5e3d659 opt some 2022-12-23 20:18:31 +08:00
harveyshao
15b9683bb7 opt some 2022-12-23 11:13:54 +08:00
harveyshao
41f180370b opt some 2022-12-22 20:43:45 +08:00
harveyshao
166f4b389c opt vimer 2022-12-22 12:04:26 +08:00
harveyshao
e8119173d6 opt some 2022-12-21 16:23:00 +08:00
shaoying
00bf48ccd9 opt some 2022-12-20 10:42:43 +08:00
bda5e90625 opt some 2022-12-19 19:47:20 +08:00
harveyshao
7a9b171341 opt vimer.css 2022-12-19 19:03:05 +08:00
shaoying
80ba98e696 opt html 2022-12-17 09:11:51 +08:00
harveyshao
799b541472 opt some 2022-12-16 23:53:17 +08:00
harveyshao
327d71534e opt some 2022-12-16 22:16:24 +08:00
harveyshao
4e44a7fbe2 opt lib 2022-12-16 22:13:05 +08:00
harveyshao
4bb9ed7ca4 opt some 2022-12-16 14:37:58 +08:00
harveyshao
a0f51ba901 opt some 2022-12-16 14:37:24 +08:00
harveyshao
cfc47ab273 opt some 2022-12-16 10:27:59 +08:00
harveyshao
787fc01510 opt some 2022-12-15 11:10:01 +08:00
harveyshao
6d38dfdfa4 opt some 2022-12-15 10:46:39 +08:00
shaoying
5e516f3b86 opt some 2022-12-15 09:14:44 +08:00
harveyshao
12af5ef04f opt chrome 2022-12-14 23:00:31 +08:00
harveyshao
dfd8a1221c opt chrome 2022-12-14 13:41:55 +08:00
harveyshao
73a1af3b46 opt some 2022-12-13 22:29:44 +08:00
harveyshao
e7491633f3 opt some 2022-12-13 21:50:44 +08:00
harveyshao
4a5f41fe6f opt vim 2022-12-13 21:26:45 +08:00
harveyshao
90df54ba48 opt vim 2022-12-12 19:42:12 +08:00
harveyshao
65c8ff8de6 opt bash 2022-12-11 20:18:27 +08:00
harveyshao
d81a08d4ae opt git 2022-12-08 20:55:12 +08:00
harveyshao
6c9d6564c2 opt git 2022-12-07 21:46:21 +08:00
harveyshao
ba256721af opt git 2022-12-07 03:12:40 +08:00
d66000028c opt some 2022-12-05 09:46:47 +08:00
harveyshao
5c1c67b4b4 opt code 2022-12-04 15:38:49 +08:00
harveyshao
a8c028dd33 opt code 2022-12-04 13:05:08 +08:00
shaoying
5e44892381 opt code 2022-12-04 09:17:24 +08:00
shaoying
a8fd58f4e7 opt some 2022-11-30 17:36:08 +08:00
shaoying
e4a3a8b5ab opt space 2022-11-29 08:55:57 +08:00
harveyshao
fd72021cba opt web.serve 2022-11-28 20:32:56 +08:00
shaoying
d308b90c7f opt some 2022-11-27 09:32:10 +08:00
shaoying
ff6b553d3e opt nfs 2022-11-26 12:29:50 +08:00
harveyshao
05e8573cdc opt mdb 2022-11-25 14:38:51 +08:00
harveyshao
1b366f158e opt mdb 2022-11-24 23:37:08 +08:00
harveyshao
2e1c210bbb opt gdb 2022-11-24 10:56:49 +08:00
shaoying
a4736333e9 opt aaa 2022-11-23 18:23:31 +08:00
harveyshao
ef5b194859 opt aaa 2022-11-23 13:37:31 +08:00
harveyshao
db406e7a64 opt some 2022-11-23 00:13:03 +08:00
harveyshao
d526f0e289 opt offer 2022-11-22 15:13:38 +08:00
harveyshao
050490cb8b opt cli 2022-11-22 00:07:34 +08:00
harveyshao
cb05b4edf3 opt some 2022-11-20 23:40:02 +08:00
harveyshao
87b862d1c4 opt chat 2022-11-19 22:54:58 +08:00
harveyshao
c441f340ae opt dream 2022-11-18 21:59:31 +08:00
harveyshao
a16a560319 opt chat 2022-11-18 14:40:37 +08:00
harveyshao
af332b70f0 opt keyboard 2022-11-17 23:52:45 +08:00
harveyshao
0a8ee276c0 add chat/favor.go 2022-11-17 15:43:38 +08:00
shaoying
8bcbafa368 opt chat 2022-11-17 09:29:31 +08:00
harveyshao
4ecd492927 opt chat 2022-11-16 13:13:21 +08:00
d5c4ae3971 opt some 2022-11-15 23:14:10 +08:00
harveyshao
c91ae59193 opt base/cli/runtime.go 2022-11-15 23:01:52 +08:00
harveyshao
da0c773b02 opt chat 2022-11-15 10:42:36 +08:00
harveyshao
526ab7a700 opt some 2022-11-14 23:19:22 +08:00
harveyshao
4cb5d8b414 opt some 2022-11-13 14:52:44 +08:00
harveyshao
241c4021ad opt chat 2022-11-12 22:14:50 +08:00
shaoying
eeb842e1e4 opt some 2022-11-12 09:04:32 +08:00
harveyshao
a2aabed8c0 opt chat 2022-11-12 00:33:42 +08:00
harveyshao
6d8459e767 opt chat 2022-11-11 17:41:13 +08:00
harveyshao
7e658a4206 opt chat 2022-11-11 14:13:43 +08:00
harveyshao
bf2e9f9d34 opt some 2022-11-10 23:22:33 +08:00
harveyshao
85a11e33cc opt feel.js 2022-11-10 23:10:18 +08:00
941835dbb0 opt some 2022-11-10 19:21:47 +08:00
harveyshao
2f819595d3 opt draw.js 2022-11-10 19:02:30 +08:00
shaoying
d4873437c5 opt spide.js 2022-11-10 17:51:30 +08:00
harveyshao
172b2174f6 opt draw.js 2022-11-10 15:22:33 +08:00
harveyshao
0cc0dbc2df opt some 2022-11-09 21:48:04 +08:00
harveyshao
c8334e8bbd opt draw.js 2022-11-08 23:43:54 +08:00
shaoying
28fcaa1af5 opt some 2022-11-08 08:24:24 +08:00
harveyshao
8231ca15df opt lunar.js 2022-11-07 23:19:34 +08:00
harveyshao
eefab21cd5 opt some 2022-11-07 22:27:45 +08:00
harveyshao
4757ae50dc opt lunar.js 2022-11-07 19:57:57 +08:00
harveyshao
b2afbbd953 opt draw.js 2022-11-07 14:04:29 +08:00
harveyshao
7f5de5f51c opt some 2022-11-06 21:41:36 +08:00
shaoying
7dfada5990 opt draw 2022-11-06 18:12:37 +08:00
harveyshao
e5922c6d1d opt draw.js 2022-11-06 15:31:21 +08:00
harveyshao
6adbb002b5 opt some 2022-11-05 23:31:22 +08:00
harveyshao
394f0475c8 opt wiki 2022-11-05 14:46:19 +08:00
harveyshao
2c2629f88b opt chart.go 2022-11-04 16:25:48 +08:00
harveyshao
d258e33088 opt wiki 2022-11-04 02:40:50 +08:00
harveyshao
accf794358 opt team 2022-11-03 14:21:25 +08:00
harveyshao
9f992b8f99 opt some 2022-11-02 23:23:48 +08:00
shaoying
279c56202c opt some 2022-11-02 20:39:44 +08:00
harveyshao
20318a125c opt some 2022-11-02 19:35:59 +08:00
shaoying
13ee6498b7 opt some 2022-11-02 17:45:29 +08:00
harveyshao
aef13fd991 opt team 2022-11-02 15:17:29 +08:00
harveyshao
1505c294bd opt some 2022-11-01 20:00:41 +08:00
shaoying
bd6145197b opt some 2022-11-01 18:02:43 +08:00
harveyshao
179261633f opt some 2022-11-01 13:41:40 +08:00
shaoying
6ac0fe64b9 opt some 2022-11-01 08:57:09 +08:00
harveyshao
45f75acbca opt proto.js 2022-10-31 23:38:54 +08:00
shaoying
9c84770fde opt some 2022-10-31 18:52:10 +08:00
harveyshao
0a7a10f311 opt some 2022-10-31 12:33:50 +08:00
harveyshao
88a7170b9e opt some 2022-10-31 10:51:06 +08:00
harveyshao
24b9dc98ca opt some 2022-10-30 22:36:12 +08:00
harveyshao
726ff8c6fe opt some 2022-10-29 23:55:09 +08:00
harveyshao
4e7163d295 opt some 2022-10-29 14:09:51 +08:00
harveyshao
af1540163e opt some 2022-10-29 12:56:54 +08:00
shaoying
c7e818db41 opt input 2022-10-29 09:29:50 +08:00
harveyshao
b50208ed8b opt input 2022-10-28 22:42:47 +08:00
harveyshao
a41445b91f opt some 2022-10-28 14:16:42 +08:00
shaoying
4b6410c645 opt key.js 2022-10-28 10:23:29 +08:00
harveyshao
3795bbf6e2 opt some 2022-10-27 22:28:39 +08:00
harveyshao
cbf2f78673 opt some 2022-10-27 15:22:08 +08:00
harveyshao
f3dd6ad821 opt some 2022-10-27 14:17:27 +08:00
harveyshao
291243c067 opt frame.js 2022-10-27 13:19:34 +08:00
shaoying
10bda20cd3 opt proto.js 2022-10-27 09:20:55 +08:00
harveyshao
76d59b8467 opt lib 2022-10-26 23:08:47 +08:00
shaoying
2bf0381d86 opt some 2022-10-26 09:00:31 +08:00
harveyshao
40eba0d9ad opt frame.js 2022-10-25 21:32:57 +08:00
harveyshao
307c9a1703 opt table.js 2022-10-24 23:08:22 +08:00
harveyshao
9682cd9dd6 opt state.js 2022-10-24 17:38:03 +08:00
shaoying
7e401a9249 opt state.js 2022-10-24 16:00:21 +08:00
harveyshao
5bee32804f opt state.js 2022-10-24 13:58:06 +08:00
shaoying
25819d0e87 opt action.js 2022-10-24 08:47:31 +08:00
harveyshao
81928d6aaf opt action.js 2022-10-23 23:43:53 +08:00
harveyshao
a520cd25f8 opt some 2022-10-23 17:50:38 +08:00
shaoying
290a04b08b opt some 2022-10-23 14:26:54 +08:00
harveyshao
675dc57b69 opt some 2022-10-23 12:49:29 +08:00
shaoying
bf1f82955c opt some 2022-10-23 09:52:57 +08:00
harveyshao
e19514bf86 opt some 2022-10-23 00:21:47 +08:00
harveyshao
782bf8e490 opt some 2022-10-22 16:36:17 +08:00
harveyshao
a73134d5da opt some 2022-10-22 11:24:46 +08:00
harveyshao
b4fd344163 opt some 2022-10-21 22:17:02 +08:00
harveyshao
636f535588 opt some 2022-10-20 20:27:37 +08:00
harveyshao
43824fddb3 opt some 2022-10-20 13:57:08 +08:00
shaoying
ee25388aaf opt some 2022-10-20 09:40:38 +08:00
harveyshao
e3f879e74f opt some 2022-10-19 21:56:35 +08:00
harveyshao
81f7175f64 opt some 2022-10-19 12:28:05 +08:00
harveyshao
3ab43d66a5 opt some 2022-10-18 23:38:49 +08:00
shaoying
592835bb3b opt some 2022-10-18 15:49:23 +08:00
harveyshao
b0f51bcec5 opt some 2022-10-18 12:23:50 +08:00
shaoying
ca866003ca opt some 2022-10-18 09:28:55 +08:00
harveyshao
1c4947dc63 opt some 2022-10-17 23:10:16 +08:00
73ee223d22 opt some 2022-10-17 16:49:37 +08:00
harveyshao
91a538e866 opt plan.js 2022-10-17 14:06:18 +08:00
shaoying
587d5325c7 opt some 2022-10-17 08:15:42 +08:00
harveyshao
dfce6de0f4 opt some 2022-10-16 22:39:44 +08:00
harveyshao
68348b0176 opt some 2022-10-16 13:55:39 +08:00
shaoying
7ffb347240 opt some 2022-10-16 08:20:00 +08:00
harveyshao
be90a47487 opt plan 2022-10-15 23:17:54 +08:00
shaoying
741d70d78f opt some 2022-10-15 07:15:36 +08:00
harveyshao
f397ce266a opt code 2022-10-15 01:50:10 +08:00
harveyshao
9008e1bb4d opt some 2022-10-11 19:48:50 +08:00
shaoying
f104e1a3c4 opt some 2022-10-08 10:26:40 +08:00
harveyshao
3ec543539f opt some 2022-10-08 09:22:49 +08:00
shaoying
312f81ac4b opt some 2022-10-08 07:09:56 +08:00
harveyshao
46f561953c opt some 2022-10-07 22:39:44 +08:00
harveyshao
a2d3977792 opt some 2022-10-07 13:48:27 +08:00
shaoying
0a810ac42b opt some 2022-10-06 08:59:29 +08:00
harveyshao
e10a087a3b opt vimer.js 2022-10-05 22:31:47 +08:00
shaoying
503848ed97 opt some 2022-10-05 07:00:40 +08:00
shaoying
8e4943c854 opt some 2022-10-04 22:59:15 +08:00
harveyshao
f5ccf8e0a8 opt some 2022-10-04 15:23:20 +08:00
harveyshao
54de21d8b9 opt some 2022-10-04 12:22:51 +08:00
shaoying
1f918afb98 opt some 2022-10-04 08:28:59 +08:00
harveyshao
163d4e1504 opt Vimer 2022-10-03 23:41:04 +08:00
shaoying
e515fa852e opt some 2022-10-03 19:56:37 +08:00
harveyshao
4412a89c61 opt inner 2022-10-03 18:12:25 +08:00
shaoying
efad4ad4c4 opt some 2022-10-03 12:08:09 +08:00
shaoying
706d97257a opt some 2022-10-03 08:24:44 +08:00
shylinux@163.com
9bebf4a4da opt some 2022-10-03 07:11:51 +08:00
faa1fc3dd3 opt some 2022-10-02 20:36:19 +08:00
shylinux@163.com
4bb09e9bd0 opt some 2022-10-02 18:55:23 +08:00
b64e0bfa8a opt some 2022-10-01 14:34:25 +08:00
shylinux@163.com
46b73fe181 opt some 2022-09-30 19:53:14 +08:00
756d131cc8 opt some 2022-09-30 09:19:00 +08:00
shaoying
7647e24f80 opt some 2022-09-30 07:13:02 +08:00
c16c2bec18 opt some 2022-09-29 21:22:44 +08:00
100df45867 opt some 2022-09-29 18:41:11 +08:00
cc25eedb5d opt chat 2022-09-29 17:18:08 +08:00
44d0c00b7f opt chat 2022-09-29 10:34:25 +08:00
shylinux@163.com
877e70e952 opt some 2022-09-25 22:50:06 +08:00
ded4c85207 opt some 2022-09-25 16:46:56 +08:00
54d7f079ec opt some 2022-09-25 08:30:54 +08:00
9c8bb45958 opt action.js 2022-09-25 08:08:26 +08:00
2dd2a70384 opt some 2022-09-24 11:14:30 +08:00
shylinux@163.com
ff625f8782 opt some 2022-09-24 10:16:39 +08:00
shylinux@163.com
85521f7dd1 add iframe 2022-09-23 23:37:33 +08:00
shylinux@163.com
0139cd75aa opt code 2022-09-22 16:08:40 +08:00
shaoying
58f746753c opt some 2022-09-21 20:37:31 +08:00
shylinux@163.com
d63260e7d1 opt some 2022-09-21 17:45:21 +08:00
shaoying
c062d2e73b opt some 2022-09-20 12:42:38 +08:00
shylinux@163.com
0d20eb0634 opt some 2022-09-20 07:35:07 +08:00
shylinux@163.com
7cfca1b0f2 opt vimer 2022-09-19 23:07:13 +08:00
shylinux@163.com
341bf3c671 opt xterm 2022-09-17 22:42:28 +08:00
shylinux@163.com
e232e95427 opt some 2022-09-16 18:27:53 +08:00
shylinux@163.com
9c472a98b0 opt some 2022-09-16 12:44:09 +08:00
shylinux@163.com
5bf4b85ca0 opt some 2022-09-15 21:02:19 +08:00
shylinux@163.com
6893d781b3 opt some 2022-09-14 22:21:37 +08:00
shylinux@163.com
cbc6ada341 opt some 2022-09-14 13:37:46 +08:00
shylinux@163.com
97e51a9546 opt some 2022-09-13 15:35:11 +08:00
shylinux@163.com
43af770a54 opt some 2022-09-13 11:42:16 +08:00
shylinux@163.com
de5ae0f0a4 opt some 2022-09-12 14:14:21 +08:00
0234a49f90 opt some 2022-09-11 22:11:18 +08:00
shylinux@163.com
5733782825 opt some 2022-09-11 19:18:23 +08:00
shylinux@163.com
1fde613b1f opt some 2022-09-09 07:41:23 +08:00
ac36c7d51b opt some 2022-09-08 13:34:30 +08:00
bf49a4b3f9 opt some 2022-09-04 23:01:51 +08:00
39582da9f8 opt some 2022-09-03 16:43:06 +08:00
shylinux@163.com
1029e1cf10 opt some 2022-08-30 07:20:20 +08:00
d9e3c7a220 opt some 2022-08-28 11:51:05 +08:00
6455009aba opt some 2022-08-28 09:09:42 +08:00
shylinux@163.com
92dc86115c opt some 2022-08-27 18:50:42 +08:00
shylinux@163.com
e1167a14df opt some 2022-08-26 10:39:13 +08:00
023ec3ede7 opt some 2022-08-24 07:59:59 +08:00
46445a6f92 opt some 2022-08-21 15:56:28 +08:00
da1c6269dd opt some 2022-08-19 19:18:51 +08:00
09ab86a009 opt some 2022-08-17 20:23:49 +08:00
harveyshao
4745c03a16 opt some 2022-08-16 14:38:26 +08:00
24c5421e66 opt some 2022-08-16 10:40:58 +08:00
shy
f8abb7e7c8 opt some 2022-08-14 22:11:39 +08:00
harveyshao
d615acf189 opt some 2022-08-09 15:14:55 +08:00
harveyshao
304bbee81f opt some 2022-08-09 14:34:24 +08:00
shy
ec5aeb30aa opt some 2022-08-09 11:27:18 +08:00
harveyshao
34c9800a2f opt some 2022-08-09 11:00:43 +08:00
harveyshao
84c49951e2 opt some 2022-08-09 08:36:33 +08:00
shy
81d238982c opt media 2022-08-08 08:22:37 +08:00
harveyshao
b883657926 opt chat 2022-08-05 17:28:01 +08:00
harveyshao
2b3dda7525 opt base 2022-08-03 08:14:29 +08:00
harveyshao
ac0cc20e3a opt base 2022-08-01 18:09:47 +08:00
harveyshao
bd57313ac3 opt some 2022-07-25 18:12:29 +08:00
shy
cf209601e1 opt some 2022-07-25 15:07:03 +08:00
harveyshao
1b92d0fbba opt some 2022-07-25 09:51:33 +08:00
harveyshao
7b2b1447ab opt xterm.js 2022-07-25 08:11:09 +08:00
harveyshao
9834321291 opt xterm.js 2022-07-24 19:56:51 +08:00
shy
8a55bd00c5 opt xterm.js 2022-07-24 08:04:17 +08:00
harveyshao
825dcefeb2 opt xterm 2022-07-23 05:23:01 +08:00
shy
d7e011d898 add xterm.js 2022-07-23 00:03:33 +08:00
shy
28a1a7604a add location.js 2022-07-23 00:02:49 +08:00
harveyshao
742784d317 opt some 2022-07-18 15:04:59 +08:00
harveyshao
fbf958ea92 opt some 2022-07-18 00:00:31 +08:00
harveyshao
7036228d5b opt some 2022-07-17 23:52:55 +08:00
shy
6c1bb50cf6 opt some 2022-07-17 22:28:03 +08:00
harveyshao
f52d4ee3a5 opt some 2022-07-17 17:33:00 +08:00
harveyshao
81ca364f5e opt div.js 2022-07-17 12:51:45 +08:00
harveyshao
4cedaed642 opt some 2022-07-15 21:34:03 +08:00
shy
d6dd6560a6 opt some 2022-07-15 21:26:17 +08:00
harveyshao
209a92d7bc opt index.css 2022-07-15 18:14:51 +08:00
harveyshao
2cddbcc870 opt vimer.js 2022-07-14 23:19:41 +08:00
harveyshao
14c72af026 opt vimer.js 2022-07-14 18:38:43 +08:00
harveyshao
4a064c121b opt vimer.js 2022-07-13 17:47:01 +08:00
harveyshao
44983d30b6 opt vimer.js 2022-07-13 08:20:03 +08:00
harveyshao
1019455633 opt some 2022-07-12 08:44:02 +08:00
harveyshao
032086531e opt inner.css 2022-07-11 22:42:12 +08:00
harveyshao
e6c9339039 opt inner.css 2022-07-11 22:39:44 +08:00
harveyshao
bdc17cf8d1 opt some 2022-07-11 08:41:05 +08:00
harveyshao
72532d6239 opt inner.js 2022-07-10 22:32:38 +08:00
harveyshao
a1e524ba97 opt some 2022-07-10 05:53:44 +08:00
harveyshao
66bc003803 opt some 2022-07-09 21:05:07 +08:00
harveyshao
c755f002c6 opt css 2022-07-09 20:13:27 +08:00
harveyshao
98079f9ed1 opt plan.js 2022-07-08 18:25:18 +08:00
shy
c3806a7c75 opt some 2022-07-08 01:02:10 +08:00
harveyshao
9c3454825a opt some 2022-07-07 18:50:25 +08:00
harveyshao
cbb68260c9 opt some 2022-07-07 15:49:47 +08:00
shy
7331f498f9 opt mobile 2022-07-07 15:37:07 +08:00
harveyshao
8c5c161598 opt data.js 2022-07-07 13:06:56 +08:00
harveyshao
09dbfcc3df opt data.js 2022-07-07 13:06:42 +08:00
shy
1296591da7 opt word.js 2022-07-07 10:00:10 +08:00
shy
e9709de6a1 opt word.js 2022-07-07 01:18:45 +08:00
harveyshao
636c1d7fc9 opt draw.js 2022-07-06 17:57:00 +08:00
harveyshao
1e42313ffc opt draw.js 2022-07-05 23:49:44 +08:00
harveyshao
63308b4ea5 opt draw.js 2022-07-05 18:00:48 +08:00
harveyshao
7eb4b28e3d opt can 2022-07-05 08:48:59 +08:00
harveyshao
3bc3e7aaa8 opt some 2022-07-04 19:07:47 +08:00
harveyshao
a256c59d19 opt search.js 2022-07-04 18:02:06 +08:00
harveyshao
0a54310d91 opt header.js 2022-07-04 10:36:13 +08:00
harveyshao
3afd7fcdc6 opt search.js 2022-07-04 00:34:52 +08:00
shaoying
6067b86006 opt footer.js 2022-07-03 21:03:13 +08:00
shaoying
b3740c74ee opt action.js 2022-07-03 17:45:28 +08:00
shaoying
aa7aa6cfd4 opt frame.js 2022-07-03 16:09:05 +08:00
harveyshao
7daf7880c3 opt river 2022-07-03 01:01:02 +08:00
shaoying
d6fffd47f4 opt some 2022-07-02 22:57:12 +08:00
harveyshao
521e25fe6d opt some 2022-07-02 12:33:33 +08:00
shaoying
e88b01b3e8 opt some 2022-07-01 23:20:19 +08:00
shy
a261df7e75 opt some 2022-07-01 21:32:20 +08:00
shy
8e8558217f opt some 2022-06-28 20:53:20 +08:00
harveyshao
0fd0940fcc opt some 2022-06-26 14:29:35 +08:00
shy
c38d2e94f7 opt some 2022-06-26 14:03:24 +08:00
shaoying
50e4194769 opt some 2022-06-26 11:36:54 +08:00
shy
e37e6ab051 opt some 2022-06-26 11:35:20 +08:00
harveyshao
b5986cc682 opt some 2022-06-19 23:39:18 +08:00
harveyshao
accb6b4989 opt some 2022-06-19 22:31:01 +08:00
harveyshao
46a55e0725 opt some 2022-06-19 20:02:06 +08:00
harveyshao
51dad23f24 opt some 2022-06-19 16:00:27 +08:00
harveyshao
b8e386ef5c opt some 2022-06-14 17:17:24 +08:00
harveyshao
61875e177b opt some 2022-06-06 01:15:49 +08:00
harveyshao
cf801cdc6a add coder 2022-06-03 01:11:26 +08:00
harveyshao
4efab3b3ce opt some 2022-05-23 08:31:21 +08:00
harveyshao
aafa3f52f3 opt some 2022-05-21 14:37:42 +08:00
harveyshao
6aeb3794ec opt some 2022-05-17 10:15:43 +08:00
harveyshao
bff37c9302 opt some 2022-05-16 12:02:15 +08:00
harveyshao
ca2be7d101 opt vimer 2022-05-16 00:56:36 +08:00
harveyshao
90ecceda72 opt vimer 2022-05-15 23:28:39 +08:00
shy
1cdc59fc65 opt some 2022-05-14 15:45:56 +08:00
harveyshao
afe84a7730 opt some 2022-05-14 15:23:18 +08:00
harveyshao
ac8c1cdb55 opt some 2022-05-10 11:08:43 +08:00
harveyshao
e9c1566672 opt some 2022-05-09 21:30:28 +08:00
harveyshao
d75d499726 opt zml 2022-05-09 10:06:39 +08:00
harveyshao
77d928bb7e add complete 2022-05-08 18:27:15 +08:00
harveyshao
cf3ad56147 opt some 2022-05-07 17:31:48 +08:00
harveyshao
e813389f3c fix some 2022-05-07 16:15:50 +08:00
shaoying
1ef60927f1 opt some 2022-05-05 20:11:47 +08:00
harveyshao
c9b73467c0 opt some 2022-05-05 10:34:06 +08:00
harveyshao
9870f700a2 add parse 2022-05-04 23:23:45 +08:00
harveyshao
8a8d33b6b4 opt some 2022-04-30 18:31:12 +08:00
harveyshao
48383f7139 add oauth 2022-04-30 15:12:59 +08:00
harveyshao
078f9fb814 opt some 2022-04-30 02:04:31 +08:00
harveyshao
788173b548 opt some 2022-04-23 11:21:58 +08:00
harveyshao
b8ff1d2d28 opt some 2022-04-23 09:36:41 +08:00
harveyshao
233fca4ff3 opt some 2022-04-23 09:16:03 +08:00
harveyshao
58a4fcf7ec opt some 2022-04-23 05:11:33 +08:00
harveyshao
0590f1cf08 opt some 2022-04-22 19:11:54 +08:00
harveyshao
f8c369ad4d opt some 2022-04-21 11:29:58 +08:00
harveyshao
f99c2d34db opt some 2022-04-18 13:18:32 +08:00
shy
6f966dcac2 opt some 2022-04-13 17:04:11 +08:00
harveyshao
405acf541e opt some 2022-04-12 10:14:00 +08:00
harveyshao
d138af4c29 opt some 2022-04-12 07:44:05 +08:00
harveyshao
9e494114c8 opt some 2022-04-12 07:34:18 +08:00
shaoying
fcbb7cd587 opt some 2022-04-11 21:47:03 +08:00
harveyshao
6877b02421 opt some 2022-04-11 10:22:31 +08:00
harveyshao
e3d2746cfc opt some 2022-04-10 23:04:05 +08:00
harveyshao
2a698564f3 opt some 2022-04-09 23:42:47 +08:00
harveyshao
c277f85ad2 opt some 2022-04-09 23:28:24 +08:00
harveyshao
59877656c3 opt webview 2022-04-09 17:56:08 +08:00
harveyshao
dc7c8bf577 opt some 2022-04-08 18:24:55 +08:00
harveyshao
e1b94b5efb opt search 2022-04-08 12:29:23 +08:00
harveyshao
4841116501 opt some 2022-04-06 12:28:48 +08:00
shy
fe46ea610f opt some 2022-04-06 12:27:00 +08:00
shy
17dab20a35 opt some 2022-04-05 00:46:42 +08:00
harveyshao
0e48f88874 opt inner 2022-04-04 09:59:50 +08:00
harveyshao
6685ff8486 opt some 2022-04-02 15:20:57 +08:00
harveyshao
50ff4779e9 opt some 2022-04-01 16:15:17 +08:00
harveyshao
31afa597b5 opt some 2022-04-01 09:27:47 +08:00
harveyshao
52e78f66ef opt full 2022-03-31 12:26:45 +08:00
harveyshao
416a02869e opt some 2022-03-30 19:18:54 +08:00
shy
a3351649af opt css 2022-03-27 21:34:13 +08:00
harveyshao
fbfac0fe6c opt action 2022-03-27 15:32:09 +08:00
shy
ce214722c7 opt some 2022-03-26 23:07:30 +08:00
shy
aaf6925782 opt css 2022-03-26 22:48:06 +08:00
shy
69e05ce1ab opt windows 2022-03-26 19:26:30 +08:00
harveyshao
d444150ca2 opt some 2022-03-26 08:00:14 +08:00
harveyshao
23ae6ef757 opt some 2022-03-25 12:14:14 +08:00
harveyshao
f33ba0c897 opt some 2022-03-23 10:17:54 +08:00
shy
337f4dbf8a opt some 2022-03-21 12:56:15 +08:00
shy
c74590b7ce opt css 2022-03-21 12:40:05 +08:00
harveyshao
9e4d9bbae8 opt some 2022-03-21 12:27:35 +08:00
harveyshao
258cfff654 opt css 2022-03-21 01:55:27 +08:00
harveyshao
6014ea052e opt css 2022-03-20 14:28:03 +08:00
harveyshao
dd4cea5809 opt css 2022-03-20 12:21:49 +08:00
harveyshao
c2a077ec51 opt some 2022-03-20 00:28:23 +08:00
harveyshao
c5f162567b add some 2022-03-19 23:58:56 +08:00
harveyshao
edef2eb8cc opt some 2022-03-19 19:06:55 +08:00
harveyshao
937ac50c56 opt some 2022-03-19 00:20:16 +08:00
harveyshao
c28a0091b5 opt some 2022-03-17 20:58:50 +08:00
harveyshao
f0f5488f5f opt some 2022-03-17 13:30:59 +08:00
harveyshao
7a564c6358 opt some 2022-03-16 18:16:18 +08:00
harveyshao
0a1a911c34 opt iml 2022-03-15 03:29:35 +08:00
harveyshao
d8a4cfed3c add iml 2022-03-15 02:28:55 +08:00
harveyshao
6bfdb68f37 opt some 2022-03-14 21:23:45 +08:00
harveyshao
d7ab130ce3 opt some 2022-03-12 21:52:31 +08:00
harveyshao
f995ec046d opt some 2022-03-12 19:13:20 +08:00
harveyshao
6189e00f04 opt some 2022-03-10 10:28:11 +08:00
harveyshao
0bef91933a opt some 2022-03-08 23:53:09 +08:00
harveyshao
80c3b436c4 opt some 2022-03-07 14:29:35 +08:00
harveyshao
8c022446de opt some 2022-03-07 11:10:46 +08:00
shy
d569d76299 opt windows 2022-03-04 23:33:14 +08:00
harveyshao
b1656ca505 opt some 2022-03-03 14:40:40 +08:00
harveyshao
06f5715a67 opt some 2022-03-03 10:38:10 +08:00
harveyshao
08adaff93d opt some 2022-03-01 16:36:33 +08:00
04df850e48 opt some 2022-02-25 19:38:44 +08:00
shy
49abf4a2c1 add media.js 2022-02-25 19:08:07 +08:00
harveyshao
53793ec8cd opt render 2022-02-24 17:30:41 +08:00
shy
95aad80057 opt login 2022-02-23 12:16:17 +08:00
harveyshao
d29d97dc19 opt some 2022-02-22 13:38:09 +08:00
shy
0f749dadda opt some 2022-02-21 11:21:52 +08:00
harveyshao
6eb5e36a78 opt code 2022-02-20 23:01:14 +08:00
harveyshao
c156f3ace6 opt code 2022-02-20 22:31:46 +08:00
harveyshao
23983001b2 opt code 2022-02-19 19:51:14 +08:00
harveyshao
9ea85cd499 opt webpack 2022-02-18 11:16:09 +08:00
harveyshao
a58b5f619e opt code 2022-02-17 11:26:27 +08:00
harveyshao
08f0df672d opt cli 2022-02-16 09:51:27 +08:00
harveyshao
d1b5111f5f opt some 2022-02-14 16:04:07 +08:00
shy
1dcae093d8 opt some 2022-02-14 13:04:42 +08:00
harveyshao
82e812a24c add todo 2022-02-14 01:49:47 +08:00
shy
b8a0c6de42 opt some 2022-02-13 20:27:57 +08:00
harveyshao
9040c970c2 opt tutor 2022-02-13 14:24:37 +08:00
harveyshao
c4c32a2405 add forever 2022-02-12 15:20:26 +08:00
shy
4c9105e8b0 opt some 2022-02-11 18:36:51 +08:00
shy
1ffdf336f1 opt some 2022-02-11 09:30:00 +08:00
harveyshao
472b856a8e opt website 2022-02-10 17:51:52 +08:00
shy
7fdd934211 opt website 2022-02-10 16:05:54 +08:00
7ee56726fd mix some 2022-02-09 20:56:21 +08:00
harveyshao
084e413a3b opt some 2022-02-09 20:52:59 +08:00
shy
af9b60ac3f opt some 2022-02-09 19:30:11 +08:00
harveyshao
349dc29694 opt key.js 2022-02-09 17:15:04 +08:00
5ff053e9e3 opt website 2022-02-08 10:31:42 +08:00
63958262c8 opt website 2022-02-06 20:16:07 +08:00
f3e5d748f5 opt some 2022-02-01 13:59:47 +08:00
b2a6b7a006 opt some 2022-01-31 22:50:16 +08:00
harveyshao
d85ad69278 opt frame 2022-01-27 16:07:14 +08:00
46983dedc4 opt some 2022-01-27 12:23:53 +08:00
shy
5af0a3538d opt some 2022-01-26 22:18:17 +08:00
harveyshao
55b49df60a opt can 2022-01-26 17:46:36 +08:00
3fc7aba1b3 opt some 2022-01-26 11:00:47 +08:00
shy
8b747fa704 opt can 2022-01-26 10:20:57 +08:00
shy
74d1aa9afc opt some 2022-01-26 03:11:00 +08:00
shy
73d4c76f1c opt css 2022-01-26 02:51:05 +08:00
harveyshao
3865cbb3b9 opt css 2022-01-26 01:40:20 +08:00
harveyshao
bbfe26a28e opt vimer 2022-01-24 17:29:22 +08:00
harveyshao
9efd9f6215 opt website 2022-01-23 16:53:03 +08:00
bergyu
699d7e7895 opt some 2022-01-23 14:16:12 +08:00
harveyshao
fb53df69a3 opt some 2022-01-22 13:51:07 +08:00
shy
fce46d83ae opt spide.js 2022-01-22 10:48:59 +08:00
90ed83a252 add template.js 2022-01-22 10:12:05 +08:00
36cf01676d opt vimer.js 2022-01-22 10:11:44 +08:00
harveyshao
c83313029e opt vimer.js 2022-01-21 17:48:17 +08:00
711534702a opt inner.js 2022-01-20 09:32:34 +08:00
harveyshao
e2c81e458b opt vimer.js 2022-01-19 17:33:36 +08:00
fd95a53b92 opt inner.js 2022-01-19 09:42:35 +08:00
harveyshao
0d60be84d0 opt vimer.js 2022-01-18 17:57:51 +08:00
7692d4069f opt inner.js 2022-01-18 09:30:52 +08:00
f7090d6ba2 opt inner.js 2022-01-18 00:31:08 +08:00
harveyshao
04a094dbd8 opt inner.js 2022-01-17 17:59:18 +08:00
7fa7058f36 opt inner.js 2022-01-17 09:31:15 +08:00
harveyshao
7a28d921c7 opt inner.js 2022-01-17 08:06:15 +08:00
93594ff636 opt inner.js 2022-01-17 00:16:51 +08:00
harveyshao
2fb7172f21 opt inner.js 2022-01-16 16:41:01 +08:00
harveyshao
3220d61d14 opt inner.js 2022-01-16 09:35:01 +08:00
harveyshao
9ba7097749 opt inner.js 2022-01-16 09:34:52 +08:00
73563a6e07 opt some 2022-01-15 02:41:15 +08:00
harveyshao
ff12cb5bc9 opt inner.js 2022-01-14 17:59:29 +08:00
f5774929c4 opt inner.js 2022-01-14 09:25:16 +08:00
harveyshao
1c939babd1 opt action.js 2022-01-13 18:04:01 +08:00
9fcb69e8db opt action.js 2022-01-13 00:25:37 +08:00
harveyshao
02fcf73f17 opt action.js 2022-01-12 18:13:27 +08:00
a0ab9b8020 opt some 2022-01-11 16:30:12 +08:00
157 changed files with 12558 additions and 9431 deletions

2
.gitignore vendored
View File

@ -5,4 +5,4 @@ page/can.js
page/can.css page/can.css
page/cache.js page/cache.js
page/cache.css page/cache.css
pack/ node_modules/

View File

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2021 码神 Copyright (c) 2017-2025 shylinux
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,4 +1,2 @@
# volcanos # Volcanos
Volcanos 是一个前端框架,通过集群化、模块化、自动化的方式,快速的开发、创建、共享各种应用程序和数据。
volcanos是一个前端框架通过模块化、集群化、自动化快速的创建、共享应用程序和数据。

570
const.js Normal file
View File

@ -0,0 +1,570 @@
var kit = {proto: function(sub, sup) { return sub.__proto__ = sup, sub },
Dict: function() { var res = {}, arg = arguments; for (var i = 0; i < arg.length; i += 2) { var key = arg[i]
if (typeof key == "object") { i--
if (key.length == undefined) {
for (var k in key) { res[k] = key[k] }
} else {
for (var j = 0; j < key.length; j += 2) { res[key[j]] = key[j+1] }
}
} else if (typeof key == "string" && key) { res[key] = arg[i+1] }
} return res },
}
var ice = {
TB: "\t", SP: " ", DF: ":", EQ: "=", AT: "@", QS: "?", PS: "/", PT: ".", FS: ",", NL: "\n", LT: "<", GT: ">",
OK: "ok", TRUE: "true", FALSE: "false", SUCCESS: "success", PROCESS: "process", FAILURE: "failure",
CONTEXTS: "contexts",
HTTP: "http", HOME: "home",
HELP: "help", COPY: "copy",
MAIN: "main", AUTO: "auto",
LIST: "list", BACK: "back",
MODE: "mode", EXEC: "exec",
INFO: "info",
APP: "app", CAN: "can", CAN_PLUGIN: "can._plugin",
OPS: "ops", DEV: "dev", POD: "pod", CTX: "ctx", CMD: "cmd", ARG: "arg",
NFS: "nfs", USR: "usr",
MSG_FIELDS: "fields", MSG_SESSID: "sessid", MSG_METHOD: "method", MSG_DEBUG: "debug",
MSG_DETAIL: "detail", MSG_OPTION: "option", MSG_APPEND: "append", MSG_RESULT: "result",
MSG_HANDLE: "_handle", MSG_UPLOAD: "_upload",
MSG_SOURCE: "_source", MSG_TARGET: "_target",
MSG_ACTION: "_action", MSG_STATUS: "_status",
MSG_PROCESS: "_process", MSG_DISPLAY: "_display", MSG_TOOLKIT: "_toolkit",
MSG_DISPLAY_CSS: "_display_css",
MSG_USERWEB: "user.web", MSG_USERPOD: "user.pod",
MSG_USERROLE: "user.role", MSG_USERNAME: "user.name", MSG_USERNICK: "user.nick", MSG_LANGUAGE: "user.lang",
MSG_TITLE: "sess.title", MSG_THEME: "sess.theme", MSG_BG: "sess.bg", MSG_FG: "sess.fg", MSG_DAEMON: "sess.daemon",
LOG_DISABLE: "log.disable", LOG_TRACEID: "log.id",
MSG_RIVER: "sess.river", MSG_STORM: "sess.storm",
MSG_COST: "sess.cost", MSG_MODE: "sess.mode",
MSG_NODETYPE: "node.type", MSG_NODENAME: "node.name",
TABLE_CHECKBOX: "table.checkbox", FROM_DAEMON: "from.daemon",
PROCESS_REWRITE: "_rewrite",
PROCESS_FIELD: "_field",
PROCESS_AGAIN: "_again",
PROCESS_HOLD: "_hold",
FIELD_PREFIX: "_prefix",
MSG_PREFIX: "_prefix",
MSG_INDEX: "_index",
ErrWarn: "warn: ",
ErrNotLogin: "not login: ",
ErrNotRight: "not right: ",
ErrNotValid: "not valid: ",
ErrNotFound: "not found: ",
}
var ctx = {
CONTEXT: "context", COMMAND: "command", CONFIG: "config", INPUTS: "inputs", FEATURE: "feature",
INDEX: "index", ARGS: "args", STYLE: "style", DISPLAY: "display", ACTION: "action", RUN: "run", CMDS: "cmds",
EXTRA_INDEX: "extra.index", EXTRA_ARGS: "extra.args",
FEATURE_TRANS: "feature._trans",
}
var mdb = {FOREACH: "*", RANDOMS: "%",
DICT: "dict", META: "meta", HASH: "hash", LIST: "list",
SHORT: "short", FIELD: "field", COUNT: "count", TOTAL: "total", LIMIT: "limit",
TIME: "time", ZONE: "zone", ID: "id",
TYPE: "type", NAME: "name", TEXT: "text", ICON: "icon", ICONS: "icons",
KEY: "key", VALUE: "value", STATUS: "status", EXTRA: "extra",
KEYWORD: "keyword",
CURRENT: "current",
SWITCH: "switch",
NOTFOUND: "notfound",
NICK: "nick",
ENABLE: "enable", DISABLE: "disable",
INDEX: "index", ORDER: "order", WEIGHT: "weight",
DATA: "data", VIEW: "view", INFO: "info", HELP: "help",
INPUTS: "inputs", CREATE: "create", REMOVE: "remove", UPDATE: "update",
INSERT: "insert", DELETE: "delete", MODIFY: "modify", SELECT: "select",
PRUNES: "prunes", EXPORT: "export", IMPORT: "import",
SEARCH: "search", ENGINE: "engine", RENDER: "render", PLUGIN: "plugin",
DETAIL: "detail", NORMAL: "normal", PRUNE: "prune",
RENAME: "rename", CANCEL: "cancel", EXPIRE: "expire", FINISH: "finish",
BEGIN_TIME: "begin_time", END_TIME: "end_time",
CANCEL_TIME: "cancel_time", EXPIRE_TIME: "expire_time", FINISH_TIME: "finish_time",
MAIN: "main", PAGE: "page", NEXT: "next", PREV: "prev", LIMIT: "limit", OFFEND: "offend",
QS: ice.QS, AT: ice.AT,
EQ: ice.EQ, FS: ice.FS,
}
var web = {
SERVE: "serve", SPACE: "space", DREAM: "dream", ROUTE: "route",
SHARE: "share", TOKEN: "token", STATS: "stats", COUNT: "count",
SPIDE: "spide", STORE: "store", ADMIN: "admin", MATRIX: "matrix",
GRANT: "grant", CHAT_GRANT: "web.chat.grant",
WORKER: "worker", SERVER: "server", ORIGIN: "origin", VENDOR: "vendor",
GATEWAY: "gateway", ONLINE: "online", OFFLINE: "offline",
SHOW: "show",
FULL: "full", OPEN: "open", LINK: "link", HTTP: "http", DOMAIN: "domain", URL: "url",
DRAW: "draw", PLAY: "play", CLEAR: "clear", RESIZE: "resize", FILTER: "filter",
CANCEL: "cancel", SUBMIT: "submit", CONFIRM: "confirm", REFRESH: "refresh",
UPLOAD: "upload", DOWNLOAD: "download", PREVIEW: "preview", TOIMAGE: "toimage",
CLIENT_NAME: "client.name",
SHARE_CACHE: "/share/cache/", SHARE_LOCAL: "/share/local/", BASIC_LOGIN: "/basic/login",
CHAT_SSO: "/chat/sso/", CHAT_POD: "/chat/pod/", CHAT_CMD: "/chat/cmd/",
CHAT: "chat",
PORTAL: "portal", DESKTOP: "desktop",
STUDIO: "studio", SERVICE: "service",
MESSAGE: "message",
STATUS: "status",
VIMER: "vimer",
WORD: "word",
PLAN: "plan",
CODE_GIT_SEARCH: "web.code.git.search",
CODE_GIT_STATUS: "web.code.git.status",
CODE_GIT_REPOS: "web.code.git.repos",
CODE_COMPILE: "web.code.compile",
CODE_VIMER: "web.code.vimer",
CODE_INNER: "web.code.inner",
CODE_XTERM: "web.code.xterm",
WIKI_DRAW: "web.wiki.draw",
WIKI_WORD: "web.wiki.word",
WIKI_PORTAL: "web.wiki.portal",
CHAT_OAUTH_CLIENT: "web.chat.oauth.client",
CHAT_MACOS_DESKTOP: "web.chat.macos.desktop",
CHAT_MACOS_SESSION: "web.chat.macos.session",
CHAT_MESSAGE: "web.chat.message",
CHAT_HEADER: "web.chat.header",
CHAT_IFRAME: "web.chat.iframe",
CHAT_FAVOR: "web.chat.favor",
CHAT_FLOWS: "web.chat.flows",
TEAM_PLAN: "web.team.plan",
MALL_GOODS: "web.mall.goods",
AT: ice.AT, QS: ice.QS,
}
var aaa = {
USER: "user", AUTH: "auth", SESS: "sess", ROLE: "role",
EMAIL: "email", OFFER: "offer", APPLY: "apply",
LOGIN: "login", LOGOUT: "logout",
BACKGROUND: "background", AVATAR: "avatar", MOBILE: "mobile", SECRET: "secret",
LANGUAGE: "language", ENGLISH: "english", CHINESE: "chinese",
PROVINCE: "province", COUNTRY: "country", CITY: "city",
LONGITUDE: "longitude", LATITUDE: "latitude",
IP: "ip", UA: "ua",
LOCATION: "location",
USERNICK: "usernick", USERNAME: "username", PASSWORD: "password", USERROLE: "userrole", USERZONE: "userzone",
VOID: "void", TECH: "tech", ROOT: "root",
PUBLIC: "public", PRIVATE: "private",
}
var lex = {
SPLIT: "split", PARSE: "parse",
PREFIX: "prefix", SUFFIX: "suffix",
TB: ice.TB, SP: ice.SP, NL: ice.NL,
}
var yac = {
STASK: "stack",
}
var ssh = {
SHELL: "shell",
CLOUD_PROFILE: "ssh.cloud.profile",
}
var gdb = {
SIGNAL: "signal",
}
var tcp = {
CLIENT: "client", SERVER: "server",
PROTO: "proto", HOST: "host", PORT: "port",
SERVICE: "service", HOSTNAME: "hostname",
WIFI: "wifi", SSID: "ssid",
LOCALHOST: "localhost",
DIAL: "dial",
DIRECT: "direct", SEND: "send", RECV: "recv",
}
var nfs = {
DIR: "dir", CAT: "cat", DEFS: "defs", PACK: "pack", TRASH: "trash", DIR_ROOT: "dir_root",
COPY: "copy", EDIT: "edit", SAVE: "save", LOAD: "load", FIND: "find", GREP: "grep", TAGS: "tags",
PATH: "path", FILE: "file", LINE: "line", SIZE: "size",
MODULE: "module",
SOURCE: "source",
TARGET: "target",
BINARY: "binary",
SCRIPT: "script",
CLONE: "clone",
REPOS: "repos",
BRANCH: "branch",
VERSION: "version",
TEMPLATE: "template", SUBJECT: "subject", CONTENT: "content",
REPLACE: "replace", FROM: "from", TO: "to",
RECENT: "recent", PUSH: "push", PULL: "pull",
IMAGE: "image",
_JS: ".js", _CSS: ".css",
JS: "js", SVG: "svg", CSS: "css", HTML: "html",
GO: "go", SH: "sh", SHY: "shy", CSV: "csv", JSON: "json",
TXT: "txt", PNG: "png", WEBM: "webm",
PWD: "./", SRC: "src/", SRC_MAIN_ICO: "src/main.ico",
SRC_TEMPLATE: "src/template/",
SRC_DOCUMENT: "src/document/",
USR_LEARNING_PORTAL: "usr/learning/portal/",
USR: "usr/", USR_LOCAL_WORK: "usr/local/work/",
USR_WEBSOCKET: "usr/websocket/", USR_GO_QRCODE: "usr/go-qrcode/", USR_GO_GIT: "usr/go-git/",
USR_ICONS: "usr/icons/", USR_GEOAREA: "usr/geoarea/", USR_PROGRAM: "usr/program/",
USR_INTSHELL: "usr/intshell/", USR_VOLCANOS: "usr/volcanos/", USR_LEARNING: "usr/learning/",
USR_NODE_MODULES: "usr/node_modules/",
USR_ICONS_ICEBERGS: "usr/icons/icebergs.jpg",
USR_ICONS_VOLCANOS: "usr/icons/volcanos.jpg",
V: "/v/",
M: "/m/",
P: "/p/",
X: "/x/",
S: "/s/",
C: "/c/",
REQUIRE: "/require/", REQUIRE_MODULES: "/require/modules/",
SHARE_CACHE: "/share/cache/", SHARE_LOCAL: "/share/local/",
WIKI_PORTAL: "/wiki/portal/",
CHAT_RIVER: "/chat/river/", CHAT_ACTION: "/chat/action/",
DF: ice.DF, PS: ice.PS, PT: ice.PT,
BACKGROUND_JPG: "usr/icons/background.jpg",
AVATAR_JPG: "usr/icons/avatar.jpg",
}
var cli = {
RUNTIME: "runtime", SYSTEM: "system", DAEMON: "daemon",
BEGIN: "begin", END: "end", START: "start", RESTART: "restart", STOP: "stop", OPEN: "open", CLOSE: "close",
PID: "pid",
OPENS: "opens", BUILD: "build", ORDER: "order", DELAY: "delay", REBOOT: "reboot",
PLAY: "play", STEP: "step", DONE: "done", COST: "cost", FROM: "from", PWD: "pwd",
QRCODE: "qrcode", COLOR: "color", BLACK: "black", WHITE: "white", BLUE: "blue", RED: "red", GRAY: "gray", CYAN: "cyan", GREEN: "green", PURPLE: "purple", YELLOW: "yellow",
MAGENTA: "magenta", SILVER: "silver", ALICEBLUE: "aliceblue", TRANSPARENT: "transparent",
LINUX: "linux", DARWIN: "darwin", WINDOWS: "windows",
XTERM: "xterm",
SH: "sh",
}
var log = {
INFO: "info", WARN: "warn", ERROR: "error", DEBUG: "debug", TRACE: "trace",
}
var code = {
FAVOR: "favor", XTERM: "xterm", INNER: "inner", VIMER: "vimer",
WEBPACK: "webpack", BINPACK: "binpack", AUTOGEN: "autogen", COMPILE: "compile", PUBLISH: "publish", UPGRADE: "upgrade",
TEMPLATE: "template", COMPLETE: "complete", NAVIGATE: "navigate", CURRENT: "current",
STATUS: "status", PULL: "pull", PUSH: "push",
INSTALL: "install",
COMMENT: "comment", KEYWORD: "keyword", DATATYPE: "datatype", PACKAGE: "package",
FUNCTION: "function", CONSTANT: "constant", STRING: "string", NUMBER: "number", BOOLEAN: "boolean",
OBJECT: "object", ARRAY: "array", UNDEFINED: "undefined",
META: "Meta", ALT: "Alt", CONTROL: "Control", SHIFT: "Shift", TAB: "Tab", ESCAPE: "Escape", ENTER: "Enter",
CMD: "Cmd", CTRL: "Ctrl", SPACE: "Space", BACKSPACE: "Backspace", ESC: "Esc", PS: "/",
}
var wiki = {
DRAW: "draw", WORD: "word", PORTAL: "portal",
FEEL: "feel",
TITLE: "title", BRIEF: "brief", REFER: "refer", SPARK: "spark", SHELL: "shell",
ORDER: "order", TABLE: "table", CHART: "chart", IMAGE: "image", VIDEO: "video",
FIELD: "field", LOCAL: "local", PARSE: "parse",
NAVMENU: "navmenu", PREMENU: "premenu", CONTENT: "content",
STORY_ITEM: ".story", H2: "h2.story", H3: "h3.story",
}
var chat = {
LIB: "lib", PAGE: "page", PANEL: "panel", PLUGIN: "plugin", STORY: "story", PLUG: "plug",
TOAST: "toast", CARTE: "carte", INPUT: "input", UPLOAD: "upload", CONTEXTS: "contexts",
LAYOUT: "layout", PROJECT: "project", CONTENT: "content", DISPLAY: "display", PROFILE: "profile", ACTIONS: "actions",
TITLE: "title", THEME: "theme", BLACK: "black", WHITE: "white", PRINT: "print", LIGHT: "light", DARK: "dark",
SHARE: "share", RIVER: "river", STORM: "storm", FIELD: "field", TOOL: "tool",
STATE: "state", MENUS: "menus", SSO: "sso", LOCATION: "location", IFRAME: "iframe", DESKTOP: "desktop",
OUTPUT: "output", SIMPLE: "simple", FLOAT: "float", FULL: "full", CMD: "cmd",
MESSAGE: "message", REQUEST: "request", RESPONSE: "response",
MATRIX: "matrix",
TUTOR: "tutor",
FLOWS: "flows",
ADMIN: "admin",
HEADER: "Header", ACTION: "Action", FOOTER: "Footer",
libs: ["base.js", "core.js", "date.js", "misc.js", "page.js", "user.js"].map(function(p) { return "/lib/"+p }),
panel_list: [{name: "Header", style: "head"}, {name: "River", style: "left"}, {name: "Action", style: "main"}, {name: "Search", style: "auto"}, {name: "Footer", style: "foot"}],
plugin_list: ["state.js", "input.js", "table.js",
"input/key.js",
"input/date.js",
].concat(navigator.userAgent.indexOf("Mobile") > -1? []: [
"story/json.js",
"story/stats.js",
"story/spides.js",
"story/trends.js",
"local/code/xterm.js",
"local/code/vimer.js",
"local/code/inner.js",
"local/code/inner/syntax.js",
"local/wiki/draw/path.js",
"local/wiki/draw.js",
"local/wiki/feel.js",
"local/wiki/word.js",
"local/team/plan.js",
]).map(function(p) { return "/v/plugin/"+p }),
PLUGIN_LOCAL: "/plugin/local/", PLUGIN_STORY: "/plugin/story/", PLUGIN_INPUT: "/plugin/input/",
PLUGIN_INPUT_JS: "/plugin/input.js", PLUGIN_TABLE_JS: "/plugin/table.js", PLUGIN_STATE_JS: "/plugin/state.js",
FRAME_JS: "/v/frame.js",
ONENGINE: "onengine", ONDAEMON: "ondaemon", ONAPPEND: "onappend", ONLAYOUT: "onlayout", ONMOTION: "onmotion", ONKEYMAP: "onkeymap",
ONIMPORT: "onimport", ONACTION: "onaction", ONDETAIL: "ondetail", ONEXPORT: "onexport",
ONSYNTAX: "onsyntax", ONFIGURE: "onfigure", ONPLUGIN: "onplugin", ONINPUTS: "oninputs",
ONSIZE: "onsize", ONMAIN: "onmain", ONLOGIN: "onlogin", ONREMOTE: "onremote", ONSEARCH: "onsearch",
ONRESIZE: "onresize", ONKEYUP: "onkeyup", ONKEYDOWN: "onkeydown", ONMOUSEENTER: "onmouseenter", ORIENTATIONCHANGE: "orientationchange",
ONSTORM_SELECT: "onstorm_select", ONACTION_NOSTORM: "onaction_nostorm", ONACTION_NOTOOL: "onaction_notool", ONACTION_TOUCH: "onaction_touch", ONACTION_CMD: "onaction_cmd", ONACTION_REMOVE: "onaction_remove",
ONOPENSEARCH: "onopensearch", ONSEARCH_FOCUS: "onsearch_focus", ONCOMMAND_FOCUS: "oncommand_focus",
ONTHEMECHANGE: "onthemechange", ONLAYOUT: "onlayout", ONUNLOAD: "onunload", ONWEBPACK: "onwebpack",
ONTOAST: "ontoast", ONSHARE: "onshare", ONPRINT: "onprint", ONDEBUGS: "ondebugs",
_INIT: "_init", _DELAY_INIT: "_delay_init",
_TRANS: "_trans", _STYLE: "_style", _ENGINE: "_engine", _SEARCH: "_search", _NAMES: "_names", _TOAST: "_toast",
PAGES_HOME: "/pages/action/home",
PAGES_DREAM: "/pages/action/dream",
PAGES_DESKTOP: "/pages/action/desktop",
PAGES_MY: "/pages/action/my",
PAGES_SEARCH: "/pages/action/search",
PAGES_ACTION: "/pages/action/action",
PAGES_INSERT: "/pages/insert/insert",
PAGES_RIVER: "/pages/river/river",
PAGES_GRANT: "/pages/web-chat/grant",
WX_LOGIN_SESS: "/chat/wx/login/action/sess",
WX_LOGIN_USER: "/chat/wx/login/action/user",
WX_LOGIN_SCAN: "/chat/wx/login/action/scan",
API_HEADER: "/chat/header/",
API_SEARCH: "/chat/search/",
API_ACTION: "/chat/action/",
}
var team = {
TASK: "task", PLAN: "plan", ASSET: "asset",
BEGIN_TIME: "begin_time", END_TIME: "end_time",
LONG: "long", YEAR: "year", MONTH: "month", WEEK: "week", DAY: "day", HOUR: "hour",
TASK_POD: "task.pod", TASK_ZONE: "task.zone", TASK_ID: "task.id",
}
var mall = {
GOODS: "goods", PRICE: "price", COUNT: "count", UNITS: "units", AMOUNT: "amount",
ASSET: "asset", SALARY: "salary",
}
var http = {
GET: "GET", PUT: "PUT", POST: "POST", DELETE: "DELETE",
Accept: "Accept", ContentType: "Content-Type", ApplicationJSON: "application/json", ApplicationFORM: "application/x-www-form-urlencoded",
}
var html = {
value: {
PROJECT_WIDTH: 230, RIVER_WIDTH: 230,
FLOAT_HEIGHT: 480, FLOAT_WIDTH: 1200,
PLUGIN_PADDING: 0, PLUGIN_MARGIN: 0,
IFRAME_HEIGHT: 420,
HEADER_HEIGHT: 48, ACTION_HEIGHT: 32, STATUS_HEIGHT: 32,
QRCODE_HEIGHT: 363, QRCODE_WIDTH: 360,
CARD_HEIGHT: 160, CARD_WIDTH: 280,
STORY_HEIGHT: 480,
PLUG_HEIGHT: 480, PLUG_WIDTH: 800,
DESKTOP_HEIGHT: 684, DESKTOP_WIDTH: 1200,
DESKTOP_MENU_HEIGHT: 25,
ACTION_BUTTON: 3, TABLE_BUTTON: 5, CARD_BUTTON: 5,
RIVER_MARGIN: 80, ACTION_MARGIN: 200,
ORDER_SHOW_LIMIT: 30, ORDER_SHOW_DELAY: 150,
CODE_FONT_SIZE: 14, CODE_LINE_HEIGHT: 20,
},
STORY: "story",
FIELDSET: "fieldset", LEGEND: "legend", OPTION: "option", ACTION: "action", OUTPUT: "output", STATUS: "status",
OPTION_ARGS: "select.args,input.args,textarea.args", INPUT_ARGS: "input.args,textarea.args", INPUT_BUTTON: "input[type=button]", INPUT_FILE: "input[type=file]",
FORM_OPTION: "form.option", DIV_ACTION: "div.action", DIV_OUTPUT: "div.output", DIV_STATUS: "div.status",
FIELDSET_HEAD: "fieldset.head", FIELDSET_FOOT: "fieldset.foot", FIELDSET_LEFT: "fieldset.left", FIELDSET_MAIN: "fieldset.main",
FIELDSET_PANEL: "fieldset.panel", FIELDSET_PLUGIN: "fieldset.plugin", FIELDSET_STORY: "fieldset.story", FIELDSET_PLUG: "fieldset.plug",
FIELDSET_FLOAT: "fieldset.float", FIELDSET_INPUT: "fieldset.input",
FIELDSET_OUTPUT: "fieldset.output",
H1: "h1", H2: "h2", H3: "h3", UL: "ul", OL: "ol", LI: "li", BR: "br", HR: "hr",
A: "a", SPAN: "span", CODE: "code", DIV: "div",
SVG: "svg", IMG: "img", IMAGE: "image", VIDEO: "video", AUDIO: "audio", CANVAS: "canvas", IFRAME: "iframe",
WSS: "wss", WEBVIEW: "webview", CHROME: "chrome", WINDOWS: "windows", MOBILE: "mobile", LANDSCAPE: "landscape",
BODY: "body", FORM: "form", LABEL: "label", TITLE: "title", INNER: "inner", SPACE: "space", CLICK: "click",
SELECT: "select", INPUT: "input", TEXT: "text", FILE: "file", TEXTAREA: "textarea", BUTTON: "button", CHECKBOX: "checkbox", MULTIPLE: "multiple",
CANCEL: "cancel", SUBMIT: "submit", UPLOAD: "upload", USERNAME: "username", PASSWORD: "password",
CONFIRM: "confirm", CLOSE: "close", CLICK: "click", FOCUS: "focus", BLUR: "blur",
TABLE: "table", THEAD: "thead", TBODY: "tbody", TR: "tr", TH: "th", TD: "td",
HEADER: "header", NAV: "nav", MAIN: "main", ASIDE: "aside", FOOTER: "footer",
NEED: "need", MUST: "must",
TAIL: "tail",
FAVICON: "favicon",
BACKGROUND_COLOR: "background-color", COLOR: "color",
PADDING: "padding", BORDER: "border", MARGIN: "margin", MARGIN_TOP: "margin-top", MARGIN_X: "margin-x", MARGIN_Y: "margin-y",
HEIGHT: "height", WIDTH: "width", MIN_HEIGHT: "min-height", MAX_HEIGHT: "max-height", MIN_WIDTH: "min-width", MAX_WIDTH: "max-width",
DISPLAY: "display", BLOCK: "block", NONE: "none", OVERFLOW: "overflow", HIDDEN: "hidden", SCROLL: "scroll", FLOAT: "float", CLEAR: "clear", BOTH: "both",
LEFT: "left", TOP: "top", RIGHT: "right", BOTTOM: "bottom",
SCROLLBAR: "scrollbar", VERTICAL: "vertical", HORIZON: "horizon",
VISIBILITY: "visibility", TRANSPARENT: "transparent",
NOTICE: "notice", DANGER: "danger", PICKER: "picker",
CURSOR: "cursor", POINTER: "pointer", CROSSHAIR: "crosshair", MOVE: "move", RESIZE: "resize",
SIZE: "size", OPACITY: "opacity", VISIBLE: "visible",
CLASS: "class", DARK: "dark", LIGHT: "light", WHITE: "white", BLACK: "black",
FILTER: "filter", TOGGLE: "toggle", EXPAND: "expand", SPEED: "speed", HOVER: "hover", HOVER_SELECT: "hover,select",
ICONS: "icons",
FULL: "full",
ICON: "icon",
VALUE: "value",
PROCESS: "process",
TOIMAGE: "toimage", NOT_HIDE: ":not(.hide)",
CONTAINER: "container", FLEX: "flex", FLOW: "flow",
MORE: "more",
PAGE: "page", TABS: "tabs", MENU: "menu", NODE: "node", PLUG: "plug",
ZONE: "zone", LIST: "list", ITEM: "item", NAME: "name", ICON: "icon", VIEW: "view",
HEAD: "head", LEFT: "left", MAIN: "main", FOOT: "foot", AUTO: "auto", SHOW: "show", HIDE: "hide",
PLUGIN: "plugin", LAYOUT: "layout", PROJECT: "project", DISPLAY: "display", PROFILE: "profile", CONTENT: "content", TABVIEW: "tabview",
DIV_PAGE: "div.page", DIV_TABS: "div.tabs", DIV_PATH: "div.path", DIV_CODE: "div.code", DIV_PLUG: "div.plug",
DIV_ZONE: "div.zone", DIV_LIST: "div.list", DIV_ITEM: "div.item", DIV_NAME: "div.name", SPAN_ITEM: "span.item", SPAN_ICON: "span.icon", SPAN_NAME: "span.name",
DIV_CONTENT: "div.content", TABLE_CONTENT: "table.content", TABLE_LAYOUT: "table.layout", DIV_TOGGLE: "div.toggle",
DIV_LAYOUT: "div.layout", DIV_LAYOUT_HEAD: "div.layout.head", DIV_LAYOUT_FOOT: "div.layout.foot", DIV_LAYOUT_LEFT: "div.layout.left",
DIV_FLOAT: "div.float", DIV_TOAST: "div.toast", DIV_CARTE: "div.carte",
DESKTOP: "desktop", DIV_DESKTOP: "div.desktop", DIV_EXPAND: "div.expand",
ITEM_CARD: "item.card",
DIV_ITEM_TEXT: "div.item.text",
DIV_ITEM_SELECT: "div.item.select",
DIV_TABS_SELECT: "div.tabs.select",
DIV_PROFILE: "div.profile", DIV_DISPLAY: "div.display",
IMAGE_PNG: "image/png", VIDEO_WEBM: "video/webm",
BACKGROUND_JPG: "usr/icons/background.jpg",
BACKGROUND_PNG: "usr/icons/background.png",
AVATAR_JPG: "usr/icons/avatar.jpg",
}
var icon = {
CHEVRON_DOWN: "bi bi-chevron-down", SEARCH: "bi bi-search", TERMINAL: "bi bi-terminal", SUN: "bi bi-sun", MOON: "bi bi-moon-stars",
portal: "bi bi-globe", desktop: "bi bi-window-desktop", admin: "bi bi-window-sidebar",
dream: "bi bi-box", space: "bi bi-box", store: "bi bi-shop",
word: "bi bi-book", repos: "bi bi-git", vimer: "bi bi-bug", build: "bi bi-tools", xterm: "bi bi-terminal", shell: "bi bi-terminal",
stats: "bi bi-card-list",
matrix: "bi bi-grid-3x3-gap",
feel: "bi bi-images",
plan: "bi bi-calendar4-week",
status: "bi bi-git",
access: "bi bi-file-earmark-lock",
sso: "bi bi-shield-check", login: "bi bi-person-check", token: "bi bi-key",
username: "bi bi-person-gear", nodename: "bi bi-globe",
password: "bi bi-shield-lock",
database: "bi bi-database",
table: "bi bi-table",
domain: "bi bi-globe",
origin: "bi bi-globe",
server: "bi bi-globe",
vendor: "bi bi-shop",
full: "bi bi-arrows-fullscreen", open: "bi bi-box-arrow-up-right",
more: "bi bi-three-dots-vertical", actions: "bi bi-three-dots",
search: "bi bi-search", favor: "bi bi-star",
plugs: "bi bi-tools",
tools: "bi bi-grid",
key: "bi bi-hash", hash: "bi bi-hash", zone: "bi bi-diagram-3", id: "bi bi-sort-numeric-down",
modify: "bi bi-pencil-square",
rename: "bi bi-pencil-square",
remove: "bi bi-trash",
detail: "bi bi-file-earmark-text",
enable: "bi bi-toggle-off", disable: "bi bi-toggle-on",
expire: "bi bi-clock-history",
name: "bi bi-sort-alpha-down",
time: "bi bi-clock-history",
size: "bi bi-calculator",
sess: "bi bi-telephone-forward",
path: "bi bi-folder2", file: "bi bi-file-earmark-text", line: "bi bi-sort-numeric-down",
start: "bi bi-play-circle", stop: "bi bi-stop-circle",
load: "bi bi-folder-plus", save: "bi bi-floppy",
trash: "bi bi-trash",
copy: "bi bi-copy",
pull: "bi bi-cloud-download", push: "bi bi-cloud-upload",
upload: "bi bi-box-arrow-in-up", download: "bi bi-box-arrow-down",
"import": "bi bi-folder-plus", "export": "bi bi-floppy",
"begin_time": "bi bi-clock-history", "end_time": "bi bi-clock-history",
// scale: "bi bi-arrows-fullscreen",
pie: "bi bi-pie-chart",
tags: "bi bi-tags",
version: "bi bi-tags",
compile: "bi bi-tools",
publish: "bi bi-send-check",
upgrade: "bi bi-rocket-takeoff",
install: "bi bi-cloud-download",
runtime: "bi bi-info-square",
inspect: "bi bi-info-square",
info: "bi bi-info-square",
template: "bi bi-file-earmark-medical",
reboot: "bi bi-bootstrap-reboot",
restart: "bi bi-bootstrap-reboot",
binary: "bi bi-disc",
images: "bi bi-disc",
qrcode: "bi bi-qr-code",
main: "bi bi-house-door", top: "bi bi-globe",
configs: "bi bi-gear", config: "bi bi-gear", conf: "bi bi-gear", logs: "bi bi-calendar4-week", tag: "bi bi-tags",
data: "bi bi-database",
branch: "bi bi-diagram-3", commit: "bi bi-hash",
message: "bi bi-wechat",
address: "bi bi-pin-map",
plugin: "bi bi-window-stack",
preview: "bi bi-window-stack", show: "bi bi-window-stack",
display: "bi bi-window-desktop", exec: "bi bi-window-desktop",
chat: "bi bi-chat-dots", help: "bi bi-question-square", doc: "bi bi-question-square",
record: "bi bi-record-circle", record1: "bi bi-images", record2: "bi bi-record-circle",
"client.name": "bi bi-globe",
machine: "bi bi-pc-display",
host: "bi bi-pc-display",
port: "bi bi-hash",
arch: "bi bi-cpu", os: "bi bi-ubuntu",
cpu: "bi bi-cpu",
role: "bi bi-person-square",
title: "bi bi-textarea-t",
type: "bi bi-card-list",
scan: "bi bi-card-list",
send: "bi bi-send-check",
cmds: "bi bi-terminal",
localCreate: "bi bi-cloud-download",
notifications: "bi bi-chat-right-text",
play: "bi bi-play-circle",
app: "bi bi-box-arrow-down-left",
dev: "bi bi-git",
"Close": "bi bi-x-lg",
"Close Other": "bi bi-x-lg",
"Rename Tabs": "bi bi-pencil-square",
}
var svg = {
GROUP: "group", PID: "pid", GRID: "grid",
FIGURE: "figure", DATA: "data", SHIP: "ship", TRANS: "trans",
GO: "go",
SHAPE: "shape", TEXT: "text", RECT: "rect", LINE: "line", CIRCLE: "circle", ELLIPSE: "ellipse", BLOCK: "block",
STROKE_WIDTH: "stroke-width", STROKE: "stroke", FILL: "fill", FONT_SIZE: "font-size", FONT_FAMILY: "font-family", TEXT_ANCHOR: "text-anchor",
G: "g", X: "x", Y: "y", R: "r", RX: "rx", RY: "ry", CX: "cx", CY: "cy", X1: "x1", Y1: "y1", X2: "x2", Y2: "y2",
PATH: "path", PATH2V: "path2v", PATH2H: "path2h",
M: "M", Q: "Q", T: "T",
TEXT_LENGTH: "textLength",
}
try { module.exports = {
kit: kit, ice: ice,
ctx: ctx, mdb: mdb, web: web, aaa: aaa,
lex: lex, yac: lex, ssh: ssh, gdb: gdb,
tcp: tcp, nfs: nfs, cli: cli, log: log,
code: code, wiki: wiki, chat: chat, team: team, mall: mall,
http: http, html: html, icon: icon, svg: svg
} } catch (e) {}
var UID = "uid"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

2328
frame.js

File diff suppressed because it is too large Load Diff

1108
index.css Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,240 +1,184 @@
Volcanos("base", {help: "数据类型", Volcanos("base", {
Int: function(val, def) { Int: function(val, def) { return parseInt(val)||def||0 },
return parseInt(val)||def||0 Min: function(val, min, max) {
}, if (max < min) { max = min }
Obj: function(val, def) { if (val == "max") { return max }
try { return val < min? min: val > max? max: val
val = typeof val == lang.STRING && val != ""? JSON.parse(val): val },
if (val && val.length == 0 && def && def.length > 0) { return def } Max: function(val, max, min) {
return val||def if (min > max) { min = max }
} catch (e) { return val > max? max: val < min? min: val
return [val] },
} Obj: function(val, def) {
}, try {
Copy: function(to, from) { if (typeof val == code.STRING) { if (val == "") { return def } val = JSON.parse(val) }
if (arguments.length == 2) { if (typeof val == code.NUMBER) { return [val] }
for (var k in from) { to[k] = from[k] } if (val.length > 0) { return val } for (var k in val) { return val } return def
return to } catch (e) { return typeof val == code.STRING && val.split(mdb.FS) || def }
} },
for (var i = 2; i < arguments.length; i++) { CopyStr: function(to, from) { if (!from) { return to }
var k = arguments[i]; to[k] = from[k] for (var k in from) { typeof from[k] == code.STRING && (to[k] = from[k]) }
} return to
return to },
}, Copy: function(to, from, merge) { if (!from) { return to }
Eq: function(to, from) { var call = arguments.callee if (arguments.length == 2 || typeof merge == code.BOOLEAN) { for (var k in from) { if (k == undefined) { continue }
if (typeof to != typeof from) { return false } if (merge && to.hasOwnProperty(k) && to[k] != undefined && to[k] != "") { continue }
if (from[k] === "") { delete(to[k]) } else { to[k] = from[k] }
} return to } for (var i = 2; i < arguments.length; i++) { var k = arguments[i]; to[k] = from[k] } return to
},
Eq: function(to, from, skip) { var call = arguments.callee; if (typeof to != typeof from) { return false }
if (typeof to == code.OBJECT) { if (to.length != from.length) { return false }
for (var i = 0; i < to.length; i++) { if (!call(to[i], from[i])) { return false } }
for (var k in to) { if (k.indexOf("_") == 0) { continue }
if (k != skip && !call(to[k], from[k])) { return false }
} return true
} return to === from
},
if (typeof to == lang.OBJECT) { Ext: function(path) {
if (to.length != from.length) { return false } return (path||"").split("?")[0].split("#")[0].split("/").pop().split(".").pop().toLowerCase()
for (var i = 0; i < to.length; i++) { },
if (!call(to[i], from[i])) { return false } Dir: function(path) { return path.endsWith(nfs.PS)? path: path.slice(0, path.lastIndexOf(nfs.PS)+1) },
}
for (var k in to) {
if (!call(to[k], from[k])) { return false }
}
return true
}
return to === from
},
Ext: function(path) { Path: function(path) { var res = "", arg = arguments; for (var i = 0; i < arg.length; i++) { if (!arg[i]) { continue }
return (path.split(ice.PS).pop().split(ice.PT).pop()).toLowerCase() res += (arg[i][0]==nfs.PS || res=="" || res[res.length-1]==nfs.PS? "": nfs.PS) + arg[i].trim()
}, } return res },
Path: function(path) { var res = "" Args: function() { var res = [], arg = arguments; function encode(k, v) { k && v != undefined && v != null && res.push(encodeURIComponent(k)+mdb.EQ+encodeURIComponent(v)) }
for (var i = 0; i < arguments.length; i++) { for (var i = 0; i < arg.length; i += 2) { if (typeof arg[i] == code.OBJECT) {
res += (arguments[i][0]==ice.PS || res=="" || res[res.length-1]==ice.PS? "": ice.PS) + arguments[i].trim() if (arg[i].length > 0) { for (var j = 0; j < arg[i].length; j += 2) { encode(arg[i][j], arg[i][j+1]) } } else { for (var k in arg[i]) { encode(k, arg[i][k]) } } i--
} } else { encode(arg[i], arg[i+1]) } } return res.join("&")
return res },
}, _parse: function(url, res) { var list = url.split("#")[0].split(ice.QS); res = res||{}, res._origin = list[0]
Args: function(obj) { var res = [] list[1] && list[1].split("&").forEach(function(item) { var ls = item.split(mdb.EQ); res[decodeURIComponent(ls[0])] = decodeURIComponent(ls[1]) })
for (var k in obj) { return res
res.push(encodeURIComponent(k)+"="+encodeURIComponent(obj[k])) },
} MergeURL: function(url) { var arg = this._parse(url); delete(arg._origin); for (var i = 1; i < arguments.length; i += 2) { delete(arg[arguments[i]]) }
return res.join("&") var arg = this.Args.apply(this, [arg].concat(Array.prototype.slice.call(arguments, 1))); return url.split(ice.QS)[0]+(arg? ice.QS+arg: "")
}, },
MergeURL: function(url) { ParseURL: function(url) { var res = this._parse(url); res.link = url, res.origin = res._origin; return res },
var args = {}; (url.split("?")[1]||"").split("&").forEach(function(item) { if (!item) { return } ParseJSON: function(str) { var res; if (typeof str == code.OBJECT) { return str }
var ls = item.split("="); args[decodeURIComponent(ls[0])] = decodeURIComponent(ls[1]) if (str.indexOf(ice.HTTP) == 0) { var res = this._parse(str, {type: web.LINK, name: "", text: str}); return res.name = res._origin.split("://").pop().split(nfs.PS)[0], res }
}) try { res = JSON.parse(str), res.text = res.text||str, res.type = res.type||nfs.JSON } catch (e) { res = {type: mdb.TEXT, text: str} } return res
for (var i = 1; i < arguments.length; i++) { },
switch (typeof arguments[i]) { ParseSize: function(size) { size = (size||"").toLowerCase().split(" ")[0]
case lang.STRING: if (size.endsWith("tb") || size.endsWith("t")) { return parseFloat(size) * this._unit.t }
args[arguments[i]] = arguments[i+1], i++ if (size.endsWith("gb") || size.endsWith("g") || size.endsWith("gib")) { return parseFloat(size) * this._unit.g }
break if (size.endsWith("mb") || size.endsWith("m") || size.endsWith("mib")) { return parseFloat(size) * this._unit.m }
case lang.OBJECT: if (size.endsWith("kb") || size.endsWith("k")) { return parseFloat(size) * this._unit.k }
if (arguments[i].length > 0) { return parseFloat(size)
for (var j = 0; j < arguments[i].length; j += 2) { }, _unit: {k: 1024, m: 1024*1024, g: 1024*1024*1024, t: 1024*1024*1024*1024},
args[arguments[i][j]] = arguments[i][j] Size: function(size) { var n = 100, k = this._unit.k, m = this._unit.m, g = this._unit.g, t = this._unit.t
} if (size > t) { return parseFloat(size/t).toFixed(2)+"T" }
} else { if (size > g) { return parseFloat(size/g).toFixed(2)+"G" }
for (var k in arguments[i]) { if (size > m) { return parseFloat(size/m).toFixed(2)+"M" }
args[k] = arguments[i][k] if (size > k) { return parseFloat(size/k).toFixed(2)+"K" }
} return size
} },
break Number: function(d, n) { var res = []
} while (d > 0) { res.push(d%10); d = parseInt(d/10); n-- } while (n > 0) { res.push("0"); n-- }
} return res.reverse(), res.join("")
var list = []; for (var k in args) { },
list.push(encodeURIComponent(k)+"="+encodeURIComponent(args[k])) Format: function(obj) { return JSON.stringify(obj) },
} Simple: function() { var res = []; for (var i = 0; i < arguments.length; i++) { var val = arguments[i]; switch (typeof val) {
return url.split("?")[0]+(list.length>0? "?"+list.join("&"): "") case code.OBJECT: if (val.length > 0) { res = res.concat(val); break }
}, for (var k in val) { k && val[k] && res.push(k, val[k]) } break
ParseURL: function(url) { var res = {link: url} default: res.push(val)
var list = url.split("?"); res["origin"] = list[0] } } return res },
list[1] && list[1].split("&").forEach(function(item) { AddUniq: function(list, value) { list = list||[], list.indexOf(value) == -1 && list.push(value); return list },
var ls = item.split("="); res[decodeURIComponent(ls[0])] = decodeURIComponent(ls[1]) isIn: function(item) { var arg = arguments; for (var i = 1; i < arg.length; i++) {
}) if (typeof arg[i] == code.OBJECT && arg[i].length > 0 && arg[i].indexOf(item) > -1) { return true }
return res if (item == arg[i]) { return true }
}, } },
ParseJSON: function(str) { var res TimeTrim: function(value) { var prefix = ""
if (typeof str == lang.OBJECT) { return str } if (!value) { return }
if (str.indexOf("http") == 0) { var ls = str.split("?") var now = new Date(), year = now.getFullYear()+"-", pre = this.Time(now, "%y-%m-%d ")
res = {type: mdb.LINK, name: "", text: str} if (value.indexOf(pre) == -1) { var list = ["昨天", "前天", "", "", "", "", ""]
res.name = ls[0].split("://").pop().split(ice.PS)[0] for (var i = 0; i < list.length; i++) {
ls[1] && ls[1].split("&").forEach(function(item) { var ls = item.split("=") var yestoday = this.Time(new Date(now - (i+1)*24*60*60*1000), "%y-%m-%d ")
res[decodeURIComponent(ls[0])] = decodeURIComponent(ls[1]) if (value.indexOf(yestoday) == 0) {
}) prefix = (list[i] || ["周日", "周一", "周二", "周三", "周四", "周五", "周六", "周日"][new Date(value.replaceAll("-", "/").split(".")[0]).getDay()])+" ", pre = yestoday; break
return res }
} }
try { res = JSON.parse(str) }
res.text = res.text||str if (value.indexOf(year) == -1) {
res.type = res.type||nfs.JSON return value.split(" ")[0]
} catch (e) { }
res = {type: mdb.TEXT, text: str} return prefix+this.trimPrefix(value.split(":").slice(0, 2).join(":"), pre, year)
} },
return res Time: function(time, fmt) { var now = this.Date(time)
}, fmt = fmt||"%y-%m-%d %H:%M:%S"
ParseSize: function(size) { size = size.toLowerCase() fmt = fmt.replace("%y", now.getFullYear())
if (size.endsWith("tb") || size.endsWith("t")) { fmt = fmt.replace("%m", this.Number(now.getMonth()+1, 2))
return parseInt(size) * 1024 * 1024 * 1024 * 1024 fmt = fmt.replace("%d", this.Number(now.getDate(), 2))
} fmt = fmt.replace("%w", ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"][now.getDay()])
if (size.endsWith("gb") || size.endsWith("g")) { fmt = fmt.replace("%H", this.Number(now.getHours(), 2))
return parseInt(size) * 1024 * 1024 * 1024 fmt = fmt.replace("%M", this.Number(now.getMinutes(), 2))
} fmt = fmt.replace("%S", this.Number(now.getSeconds(), 2))
if (size.endsWith("mb") || size.endsWith("m")) { fmt = fmt.replace("%s", this.Number(now.getMilliseconds(), 3))
return parseInt(size) * 1024 * 1024 return fmt
} },
if (size.endsWith("kb") || size.endsWith("k")) { Date: function(time) { var now = new Date(); if (typeof time == code.STRING && time != "") { var ls = time.split(lex.SP)
return parseInt(size) * 1024 var vs = ls[0].split("-"); now.setFullYear(parseInt(vs[0])), now.setMonth(parseInt(vs[1])-1), now.setDate(parseInt(vs[2]))
} var vs = ls[1].split(nfs.DF); now.setHours(parseInt(vs[0])), now.setMinutes(parseInt(vs[1])), now.setSeconds(parseInt(vs[2]))
return parseInt(size) } else if (time) { now = time } return now },
}, DateAdd: function(stamp, days) { return new Date(stamp - stamp%(24*3600*1000) - 8*3600*1000 + days*24*3600*1000) },
Duration: function(n) { var res = "", h = 0; n = parseInt(n)
Size: function(size) { size = parseInt(size) h = parseInt(n/3600000/24), h > 0 && (res += h+"d"), n = n % (3600000*24)
if (size > 1000000000) { h = parseInt(n/3600000), h > 0 && (res += h+"h"), n = n % 3600000
return parseInt(size/1000000000) + ice.PT + parseInt(size/10000000%100) + "G" h = parseInt(n/60000), h > 0 && (res += h+"m"), n = n % 60000
} h = parseInt(n/1000), h > 0 && (res += h), n = n % 1000
if (size > 1000000) { return res + (n > 0? nfs.PT+this.Number(parseInt(n/10), 2): "") + "s"
return parseInt(size/1000000) + ice.PT + parseInt(size/10000%100) + "M" },
} isNight: function() { var now = new Date(); return now.getHours() < 7 || now.getHours() > 17 },
if (size > 1000) { isNumber: function(val) { return typeof val == code.NUMBER },
return parseInt(size/1000) + ice.PT + parseInt(size/10%100) + "K" isString: function(val) { return typeof val == code.STRING },
} isObject: function(val) { return typeof val == code.OBJECT },
return size + "B" isArray: function(val) { return Array.isArray(val) },
}, isFunc: function(val) { return typeof val == code.FUNCTION },
Number: function(d, n) { var result = [] isUndefined: function(val) { return val == undefined },
while (d > 0) { result.push(d%10); d = parseInt(d/10); n-- } isNull: function(val) { return val == null },
while (n > 0) { result.push("0"); n-- } toLast: function(list, value) { if (!list) { return }
return result.reverse(), result.join("") for (var i = 0; i < list.length-1; i++) { if (list[i] == value) {
}, for (i; i < list.length-1; i++) { list[i] = list[i+1] }
Format: function(obj) { list[list.length-1] = value
return JSON.stringify(obj) } }
}, },
Simple: function() { var res = [] getValid: function() { for (var i = 0; i < arguments.length; i++) { var v = arguments[i]
for (var i = 0; i < arguments.length; i++) { if (typeof v == code.OBJECT) { if (v == null) { continue }
var arg = arguments[i]; switch (typeof arguments[i]) { if (v.length > 0) { return v } for (var k in v) { return v }
case lang.NUMBER: res.push(arg); break } else if (typeof v == code.STRING) { if (v == "") { continue } else { return v }
case lang.STRING: res.push(arg); break } else if (v == undefined) { continue } else { return v }
case lang.OBJECT: } },
if (arg.length > 0) { res = res.concat(arg); break } replaceAll: function(str) { if (!str) { return str } var arg = arguments; for (var i = 1; i < arg.length; i += 2) { if (!arg[i]) { continue }
for (var k in arg) { k && arg[k] && res.push(k, arg[k]) } if (str.replaceAll) { str = str.replaceAll(arg[i], arg[i+1]); continue }
break if (arg[i] && str.replace) { while (str.indexOf(arg[i]) > -1) { str = str.replace(arg[i], arg[i+1]) } }
default: res.push(arg); } return str },
} contains: function(str) { var arg = arguments; for (var i = 1; i < arg.length; i++) { if (!arg[i] || str.indexOf(arg[i]) > -1) { return true } } },
} capital: function(str) { return str.slice(0, 1).toUpperCase()+str.slice(1) },
return res beginWith: function(str) {
}, for (var i = 1; i < arguments.length; i++) {
AddUniq: function(list, value) { list = list||[] if (typeof str == code.STRING && str.trim().indexOf(arguments[i]) == 0) { return true }
return list.indexOf(value) == -1 && list.push(value), list if (typeof str == code.OBJECT) { var begin = true
}, for (var j = 0; j < arguments[i].length; j++) {
if (str[j] != arguments[i][j]) { begin = false; break }
Date: function(time) { var now = new Date() } if (begin) { return true }
if (typeof time == lang.STRING && time != "") { var ls = time.split(ice.SP) }
var vs = ls[0].split("-") }
now.setFullYear(parseInt(vs[0])) },
now.setMonth(parseInt(vs[1])-1) endWith: function(str) { var arg = arguments; for (var i = 1; i < arg.length; i++) { if (typeof str == code.STRING && str.lastIndexOf(arg[i]) > 0 && str.lastIndexOf(arg[i]) + arg[i].length == str.length) { return true } } },
now.setDate(parseInt(vs[2])) trimPrefix: function(str, pre) { if (typeof str != code.STRING) { return str } var arg = arguments, callee = arg.callee
if (arg.length > 2) { for (var i = 1; i < arg.length; i++) { str = callee(str, arg[i]) } return str }
var vs = ls[1].split(":") if (str.indexOf(pre) == -1) { return str } return str.slice(pre.length)
now.setHours(parseInt(vs[0])) },
now.setMinutes(parseInt(vs[1])) trimSuffix: function(str, end, once) { while (str) { var index = str.lastIndexOf(end)
now.setSeconds(parseInt(vs[2])) if (index == -1 || index+end.length != str.length) { break } str = str.slice(0, index)
} else if (time) { if (once) { break }
now = time } return str },
} trim: function(arg) { if (this.isString(arg)) { return arg.trim() }
return now if (this.isArray(arg)) { for (var i = arg.length-1; i >= 0; i--) { if (!arg[i]) { arg.pop() } else { break } } } return arg
}, },
Time: function(time, fmt) { var now = this.Date(time) join: function(list, sp) { return typeof list == code.STRING? list: (list||[]).join(sp||lex.SP) },
var list = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"] joins: function(list, inner, outer) { for (var i = 0; i < list.length; i++) { list[i] = typeof list[i] == code.STRING? list[i]: list[i].join(inner||mdb.FS) } return list.join(outer||lex.SP) },
fmt = fmt||"%H:%M:%S" joinKV: function(list, inner, outer) { var res = []; for (var i = 0; i < list.length-1; i += 2) { res.push(list[i]+(inner||": ")+list[i+1]) } return res.join(outer||lex.SP) },
fmt = fmt.replace("%y", now.getFullYear()) random: function(max, min) { return min = min||0, parseInt(Math.random()*(max-min))+min },
fmt = fmt.replace("%m", this.Number(now.getMonth()+1, 2))
fmt = fmt.replace("%d", this.Number(now.getDate(), 2))
fmt = fmt.replace("%w", list[now.getDay()])
fmt = fmt.replace("%H", this.Number(now.getHours(), 2))
fmt = fmt.replace("%M", this.Number(now.getMinutes(), 2))
fmt = fmt.replace("%S", this.Number(now.getSeconds(), 2))
return fmt
},
TimeAdd: function(t, d) {
return new Date(t - t%(24*3600*1000) - 8*3600*1000 + d*24*3600*1000)
},
Duration: function(n) { var res = "", h = 0
h = parseInt(n/3600000/24), h > 0 && (res += h+"d"), n = n % (3600000*24)
h = parseInt(n/3600000), h > 0 && (res += h+"h"), n = n % 3600000
h = parseInt(n/60000), h > 0 && (res += h+"m"), n = n % 60000
h = parseInt(n/1000), h > 0 && (res += h), n = n % 1000
return res + (n > 0? ice.PT+parseInt(n/10): "") + "s"
},
isNumber: function(val) { return typeof val == lang.NUMBER },
isString: function(val) { return typeof val == lang.STRING },
isObject: function(val) { return typeof val == lang.OBJECT },
isArray: function(val) { return typeof val == lang.OBJECT && val.length != undefined },
isFunc: function(val) { return typeof val == lang.FUNCTION },
isFunction: function(val) { return typeof val == lang.FUNCTION },
isCallback: function(key, value) { return key.indexOf("on") == 0 && typeof value == lang.FUNCTION },
isUndefined: function(val) { return val == undefined },
isNull: function(val) { return val == null },
isNight: function() { var now = new Date()
return now.getHours() < 7 || now.getHours() > 17
},
endWith: function(str, end) {
return str.lastIndexOf(end) + end.length == str.length
},
trim: function(args) { if (this.isString(args)) { return args.trim() }
if (this.isArray(args)) { for (var i = args.length-1; i >= 0; i--) { if (!args[i]) { args.pop() } else { break } } }
return args
},
trimPrefix: function(str, pre) {
if (str.indexOf(pre) == -1) {
return str
}
return str.slice(pre.length)
},
trimSuffix: function(str, end) {
if (str.indexOf(end) == -1) {
return str
}
return str.slice(0, str.indexOf(end))
},
join: function(list, sp) { return (list||[]).join(sp||ice.SP) },
joins: function(list, inner, outer) {
for (var i = 0; i < list.length; i++) {
list[i] = typeof list[i] == lang.STRING? list[i]: list[i].join(inner||ice.FS)
}
return list.join(outer||ice.SP)
},
}) })

View File

@ -1,199 +1,148 @@
Volcanos("core", {help: "数据结构", Volcanos("core", {
Keys: shy("连接器", function() { var list = [] Defer: function(cb) { var defer = []; cb(defer)
for (var i = 0; i < arguments.length; i++) { var v = arguments[i] while (defer.length > 0) { defer.pop()() }
switch (typeof v) { },
case lang.OBJECT: Keys: function() { var list = []
for (var j = 0; j < v.length; j++) { for (var i = 0; i < arguments.length; i++) { var v = arguments[i]; switch (typeof v) {
list.push(v[j]) case code.OBJECT: for (var j = 0; j < v.length; j++) { v[j] && list.push(v[j]) } break
} case code.NUMBER: list.push(v+""); break
break case code.FUNCTION: v = v()
case lang.FUNCTION: v = v() default: v && list.push(v+"")
default: v && list.push(v+"") } } return list.join(nfs.PT)
} },
} Value: function(data, key, value) { if (data == undefined) { return } if (key == undefined) { return data }
return list.join(ice.PT) if (typeof key == code.OBJECT) { if (key.length != undefined) { key = key.join(nfs.PT) } else { for (var k in key) { arguments.callee.call(this, data, k, key[k]) } return data } }
}), if (value != undefined) { var _node = data, keys = key.split(nfs.PT)
Value: shy("存储器", function(data, key, value) { for (var i = 0; i < keys.length; i++) { var _next = _node[keys[i]]||{}; _node[keys[i]] = _next
if (data == undefined) { return } if (i < keys.length - 1) { _node = _next } else {
if (key == undefined) { return data } if (value === "") {
delete(_node[keys[i]])
if (typeof key == lang.OBJECT) { for (var k in key) { } else {
arguments.callee.call(this, data, k, key[k]) _node[keys[i]] = value
}; return data } }
}
if (value != undefined) { data[key] = value } }
if (data[key] != undefined) { return data[key] } }
var node = data, keys = key.split(nfs.PT); while (node && keys.length > 0) { if (typeof node == "string") { return }
var p = data, ls = key.split(ice.PT); while (p && ls.length > 0) { if (keys[0] == "-1") { keys[0] = node.length-1 } node = node[keys[0]], keys = keys.slice(1)
if (ls[0] == "-1") { ls[0] = p.length-1 } } return node == undefined? data[key]: node
p = p[ls[0]], ls = ls.slice(1) },
}; return p Split: function(str) { if (!str || !str.length) { return [] }
}), var opt = {detail: false}, arg = []; for (var i = 1; i < arguments.length; i++) { var v = arguments[i]; typeof v == code.OBJECT? opt = v: arg.push(v) }
Split: shy("分词器", function(str) { if (!str || !str.length) { return [] } function _list(str) { var res = {}; for (var i = 0; i < str.length; i++) { res[str[i]] = true }; return res }
var opt = {detail: false}, arg = []; for (var i = 1; i < arguments.length; i++) { var space = _list(arg[0]||"\t ,;\n") // 空白符
typeof arguments[i] == lang.OBJECT? opt = arguments[i]: arg.push(arguments[i]) var block = _list(arg[1]||"{[()]}") // 分隔符
} var quote = _list(arg[2]||"'\"`") // 引用符
var trans = _list(arg[3]||"\\") // 转义符
// 字符定义 var res = [], begin = 0; function push(obj) { obj && res.push(typeof obj == code.STRING || opt.detail? obj: obj.text), begin = -1 }
function _list(str) { var res = {}; for (var i = 0; i < str.length; i++) { res[str[i]] = true }; return res } for (var s = "", i = 0; i < str.length; i++) {
var space = _list(arg[0]||"\t ,;\n") // 空白符 if (space[str[i]]) { if (s) { continue }
var block = _list(arg[1]||"{[()]}") // 分隔符 begin > -1 && push(str.slice(begin, i)), opt.detail && push({type: code.SPACE, text: str.slice(i, i+1)})
var quote = _list(arg[2]||"'\"`") // 引用符 } else if (block[str[i]]) { if (s) { continue }
var trans = _list(arg[3]||"\\") // 转义符 begin > -1 && push(str.slice(begin, i)), push(str.slice(i, i+1))
} else if (quote[str[i]]) {
var res = [], begin = 0; function push(obj) { if (s == "") {
obj && res.push(typeof obj == lang.STRING || opt.detail? obj: obj.text), begin = -1 begin > -1 && push(str.slice(begin, i)), s = str[i], begin = i+1
} } else if (s == str[i]) {
push({type: code.STRING, text: str.slice(begin, i), left: s, right: str[i]}), s = "", begin = -1
// 开始分词 }
for (var s = "", i = 0; i < str.length; i++) { } else if (trans[str[i]]) { begin == -1 && (begin = i), i++
if (space[str[i]]) { // 空白符 } else { begin == -1 && (begin = i) }
if (s) { continue } } return begin > -1 && (s? push({type: code.STRING, text: str.slice(begin), left: s, right: ""}): push(str.slice(begin))), res
begin > -1 && push(str.slice(begin, i)) },
opt.detail && push({type: "space", text: str.slice(i, i+1)}) SplitInput: function(item, type) { if (typeof item == code.OBJECT) { return item } type = type||html.TEXT; switch (item) {
case ctx.RUN: return {type: html.BUTTON, name: item}
} else if (block[str[i]]) { // 分隔符 case ice.LIST: return {type: html.BUTTON, name: item, action: ice.AUTO}
if (s) { continue } case ice.BACK: return {type: html.BUTTON, name: item}
begin > -1 && push(str.slice(begin, i)) case mdb.NAME: return {type: html.TEXT, name: item}
push(str.slice(i, i+1)) case mdb.TEXT: return {type: html.TEXTAREA, name: item}
case ctx.ARGS: return {type: html.TEXTAREA, name: item}
} else if (quote[str[i]]) { // 引用符 default: var ls = this.Split(item, lex.SP, "*:=@"), res = {type: type, name: ls[0]}; for (var i = 1; i < ls.length; i += 2) { switch (ls[i]) {
if (s == "") { case "*": res["need"] = "must", i--; break
s = str[i], begin = i+1 case nfs.DF: res[mdb.TYPE] = ls[i+1]; break
} else if (s == str[i]) { case mdb.EQ:
push({type: lang.STRING, text: str.slice(begin, i), left: s, right: str[i]}) if (res[mdb.TYPE] == html.SELECT) { res.values = this.Split(ls[i+1]); for (var j = 1; j < res.values.length; j++) {
s = "", begin = -1 if (res.values[0] == "" || res.values[0] == res.values[j]) { res.value = res.values[0], res.values = res.values.slice(1); break }
} } } else { res.value = ls[i+1] } break
case ice.AT: res[ctx.ACTION] = ls[i+1]; break
} else if (trans[str[i]]) { // 转义符 } } return res
begin == -1 && (begin = i++) } },
CallFunc: function(func, args, mod) { args = args||{}; var can = args["can"]||args[0], msg = args["msg"]||args[1], cb = args["cb"]
} else { // 普通符 if (Array.isArray(args)) { this.List(args, function(arg) { if (!arg) { return } if (arg.request && arg.run) { can = arg } else if (arg.Append && arg.Result) { msg = arg } else if (typeof arg == code.FUNCTION) { cb = arg } }) }
begin == -1 && (begin = i) func = typeof func == code.FUNCTION? func: typeof func == code.OBJECT && func.length > 0? this.Value(func[0], this.Keys(func.slice(1))): typeof func == code.STRING? this.Value(mod||can, func): null
} if (typeof func != code.FUNCTION) { if (typeof cb == code.FUNCTION) { cb() } return }
} var list = [], echo = false; args.length > 0? list = args: this.List(func.toString().split(")")[0].split("(")[1].split(mdb.FS), function(item, index) { item = item.trim(); if (item == "") { return }
list.push(args[item] || msg&&msg.Option&&msg.Option(item) || can&&can.Conf&&can.Conf(item) || null); if (item == "cb") { echo = true }
// 剩余字符 }); var res = func.apply(mod||can, list); if (msg && msg.Defer) { msg.Defer() }
begin >= 0 && (s? push({type: lang.STRING, text: str.slice(begin), left: s, right: ""}): push(str.slice(begin))) if (!echo && typeof cb == code.FUNCTION) { res && msg&&msg.Echo&&msg.Echo(res), arguments.callee.apply(this, [cb, {msg: msg, res: res}]) } return res
return res },
}), List: function(list, cb, interval, cbs) {
CallFunc: shy("调用器", function(func, args, mod) { args = args||{} if (typeof list == code.STRING) { list = [list] } else if (typeof list == code.NUMBER) { // [end cb interval]|[begin end interval]
var can = args["can"]||args[0], msg = args["msg"]||args[1], cmds = args["cmds"]||[], event = args["event"]||{} var begin = 0, end = list, step = typeof interval == code.NUMBER? interval: 1; if (typeof cb == code.NUMBER) { begin = list, end = cb, cb = null }
list = []; for (var i = begin; i < end; i += step) { list.push(i) }
// 查找调用 } list = list||[]
func = typeof func == lang.FUNCTION? func: typeof func == lang.STRING? this.Value(mod||can, func): if (interval > 0) {
typeof func == lang.OBJECT && func.length > 0? this.Value(func[0], this.Keys(func.slice(1))): null function loop(i) { i >= list.length? typeof cbs == code.FUNCTION && cbs(list): cb(list[i], i, list), setTimeout(function() { loop(i+1) }, interval) }
if (typeof func != lang.FUNCTION) { return } typeof cb == code.FUNCTION && list.length > 0 && setTimeout(function() { loop(0) }, interval/4)
} else { var res = []
// 解析参数 for (var i = 0; i < list.length; i++) { var _res = typeof cb == code.FUNCTION? cb(list[i], i, list): list[i]; _res != undefined && res.push(_res) }
var list = [], echo = false, cb = args["cb"] list = res
this.List(func.toString().split(")")[0].split("(")[1].split(ice.FS), function(item, index) { item = item.trim(); if (item == "") { return } } return list
var arg = args[item] || msg&&msg.Option&&msg.Option(item) || can&&can.Conf&&can.Conf(item) || },
event&&!(event instanceof Event)&&event[item] || args[index] || cmds[index] || null Next: function(list, cb, cbs, data) {
if (item == "cb") { echo = true } switch (typeof list) {
list.push(arg) case code.OBJECT:
}) if (list == null) { list = []; break } if (list.length == undefined) { var ls = []; for (var k in list) { ls.push(k) } list = ls } break
default: if (list == undefined) { list = []; break } list = [list]
// 执行调用 }
var res = func.apply(mod||can, list) function next(i) {
if (!echo && typeof cb == lang.FUNCTION) { res && msg && msg.Echo(res), arguments.callee.apply(this, [cb, {msg: msg, res: res}]) } data = (i < list.length?
return res typeof cb == code.FUNCTION && cb(list[i], function(_data) { data = _data||data, next(i+1) }, i, list, data):
}), typeof cbs == code.FUNCTION && cbs(list))||data
}
List: shy("迭代器", function(list, cb, interval, cbs) { return next(0), list
if (typeof list == lang.STRING) { // 默认序列 },
list = [list] Item: function(obj, cb) { var list = [], keys = []
} else if (typeof list == lang.NUMBER) { // 等差序列 [end cb interval]|[begin end interval] if (obj && obj.detail && obj.option) {
var begin = 0, end = list, step = typeof interval == lang.NUMBER? interval: 1 obj["detail"] && keys.push("detail")
if (typeof cb == lang.NUMBER) { begin = list, end = cb, cb = null } obj["option"] && keys.push("option")
list = []; for (var i = begin; i < end; i += step) { list.push(i) } keys = keys.concat(obj.option, obj.append||[])
} obj["append"] && keys.push("append")
obj["result"] && keys.push("result")
list = list||[] } else {
for (var k in obj) { keys.push(k) }
if (interval > 0) { // 时间序列 }
function loop(i) { if (i >= list.length) { return typeof cbs == lang.FUNCTION && cbs(list) } for (var i = 0; i < keys.length; i++) { var k = keys[i]; var res = typeof cb == code.FUNCTION? cb(k, obj[k], list): k; res != undefined && list.push(res) }
cb(list[i], i, list), setTimeout(function() { loop(i+1) }, interval) return list
} },
typeof cb == lang.FUNCTION && list.length > 0 && setTimeout(function() { loop(0) }, interval/4) ItemKeys: function(obj, cb) { var list = [], keys = []; for (var k in obj) { keys.push(k) } keys.sort()
} else { // 选择序列 for (var i in keys) { var k = keys[i]; var res = typeof cb == code.FUNCTION? cb(k, obj[k]): k; res != undefined && list.push(res) }
var slice = [], res return list
for (var i = 0; i < list.length; i++) { },
typeof cb == lang.FUNCTION? (res = cb(list[i], i, list)) != undefined && slice.push(res): slice.push(list[i]) ItemOrder: function(obj, key, cb) { var list = [], order = [], keys = {}, vals = {}, i = 0
}; list = slice for (var k in obj) { o = obj[k][key]||i++, order.push(o), keys[o] = k, vals[o] = obj[k] } order.sort()
} for (var i in order) { var k = order[i], res = typeof cb == code.FUNCTION? cb(keys[k], vals[k]): k; res != undefined && list.push(res) }
return list return list
}), },
Next: shy("迭代器", function(list, cb, cbs) { ItemForm: function(obj, cb) { var list = []
function next(i) { for (var k in obj) { list = list.concat(this.List(obj[k], function(v, i) { return typeof cb == code.FUNCTION && cb(v, i, k, obj) })) }
i < list.length? cb(list[i], function() { return list
next(i+1) },
}, i, list): typeof cbs == lang.FUNCTION && cbs(list) ItemCB: function(meta, cb, can, item) { var list = []
} for (var k in meta) { if (k.indexOf("on") == 0 && typeof meta[k] == code.FUNCTION) { (function(k) { list.push(k)
if (typeof cb == code.FUNCTION) {
switch (typeof list) { cb(k, meta[k])
case undefined: list = []; break } else { cb[k] = function(event) { can.misc.Event(event, can, function(msg) {
case lang.OBJECT: meta[k](event, can, item)
if (list.length == undefined) { }) } }
var ls = []; for (var k in list) { ls.push(k) } })(k) } } return list
list = ls },
} Timer: shy("定时器, value, [1,2,3,4], {delay, interval, length}", function(interval, cb, cbs) { var timer = {stop: false}
break if (interval == "0") { return cb && cb(), cbs && cbs() }
default: list = [list] function loop(i) { timer.stop || i >= interval.length && interval.length >= 0 || cb(timer, interval.interval||interval[i], i, interval)?
} typeof cbs == code.FUNCTION && cbs(timer, interval): setTimeout(function() { loop(i+1) }, interval.interval||interval[i+1])
} interval = typeof interval == code.OBJECT? interval: [interval]; if (interval.interval == 0) { return cb(), timer }
list && list.length > 0 && typeof cb == lang.FUNCTION? next(0): typeof cbs == lang.FUNCTION && cbs(list) var delay = interval.delay||interval.interval/2||interval[0]
}), return typeof cb == code.FUNCTION && (timer._timer = setTimeout(function() { loop(0) }, delay)), timer
Items: shy("迭代器", function(obj, cb) { var list = [] }),
for (var k in obj) {
list = list.concat(this.List(obj[k], function(v, i) {
return typeof cb == lang.FUNCTION && cb(v, i, k, obj)
}))
}
return list
}),
Item: shy("迭代器", function(obj, cb) { var list = []
for (var k in obj) {
var res = typeof cb == lang.FUNCTION? cb(k, obj[k]): k
res != undefined && list.push(res)
}
return list
}),
ItemCB: shy("迭代器", function(meta, cb, can, item) { var list = []
for (var k in meta) { (function(k) {
if (k.indexOf("on") == 0 && typeof meta[k] == lang.FUNCTION) {
if (typeof cb == lang.FUNCTION) {
cb(k, meta[k])
} else {
cb[k] = function(event) { meta[k](event, can, item) }
}
list.push(k)
}
})(k) }
return list
}),
Timer300ms: function(cb) { this.Timer(300, cb) },
Timer300: function(cb) { this.Timer(300, cb) },
Timer3s: function(cb) { this.Timer(3000, cb) },
Timer: shy("定时器, value, [1,2,3,4], {interval, length}", function(interval, cb, cbs) {
var timer = {stop: false}; function loop(i) {
timer.stop || i >= interval.length && interval.length >= 0 || cb(timer, interval.interval||interval[i], i, interval)?
typeof cbs == lang.FUNCTION && cbs(timer, interval): setTimeout(function() { loop(i+1) }, interval.interval||interval[i+1])
}
interval = typeof interval == lang.OBJECT? interval: [interval]
if (interval.interval == 0) { cb(); return timer }
typeof cb == lang.FUNCTION && setTimeout(function() { loop(0) }, interval.interval||interval[0])
return timer
}),
Delay: shy("延时器", function(list, interval, cb, cbs) { list = list || []
list.push(cb); this.Timer(interval, function() {
var cb = list.pop(); list.length = 0
typeof cb == lang.FUNCTION && cb()
}, cbs)
return list
}),
}) })

254
lib/date.js Normal file
View File

@ -0,0 +1,254 @@
Volcanos("date", {
List: function(can, cb, now, head) { var list = [{th: head||(can.user.info.language == "en"? ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]: ["日", "一", "二", "三", "四", "五", "六"])}]
var tr; function _cb(day, type) { if (day.getDay() == 0) { list.push(tr = {type: html.TR, list: []}) } var lunar = can.date.solar2lunar(day), _day = new Date(day)
tr.list.push({view: [can.base.isIn(can.base.Time(day, "%y-%m-%d"), can.base.Time(now, "%y-%m-%d"))? html.SELECT: type, html.TD],
onclick: function(event) { cb(event, _day) }, list: [{text: day.getDate()+""}, {text: [lunar.autoDay, "", lunar.autoClass]}],
})
}
var first = new Date(now); first.setDate(1); var last = new Date(first); last.setMonth(last.getMonth()+1)
var begin = new Date(first); begin.setDate(first.getDate()-first.getDay()); var end = new Date(last); end.setDate(last.getDate()+7-last.getDay())
for (var day = new Date(begin); day < first; day.setDate(day.getDate()+1)) { _cb(day, mdb.PREV) }
for (var day = new Date(first); day < last; day.setDate(day.getDate()+1)) { _cb(day, mdb.MAIN) }
for (var day = new Date(last); day.getDay() != 0 && day < end; day.setDate(day.getDate()+1)) { _cb(day, mdb.NEXT) }
return list
},
// @1900-2100区间内的公历转农历
solar2lunar: function(date) { var y = date.getFullYear(), m = date.getMonth()+1, d = date.getDate()
var day = (Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()) - Date.UTC(1900,0,31))/86400000
for (var year = 1900, days = 0; year < 2101 && day > 0; year++) { days = this.lYearDays(year), day -= days } if (day < 0) { day += days, year-- }
var isLeap = false, leap = this.leapMonth(year); for (var month = 1; month < 13 && day > 0; month++) {
if (leap > 0 && month == leap+1 && isLeap == false) { month--, isLeap = true, days = this.leapDays(year) } else { days = this.monthDays(year, month) }
if (isLeap == true && month == leap+1) { isLeap = false } day -= days
} if (day == 0 && leap > 0 && month == leap+1) { if (isLeap) { isLeap = false } else { isLeap = true, month-- } } if (day < 0) { day += days, month-- } day++
// 节气
var term = null, firstTerm = this.getTerm(y, (m*2-1)), secondTerm = this.getTerm(y, (m*2))
if (d == firstTerm) { term = this.termName[m*2-2] } else if (d == secondTerm) { term = this.termName[m*2-1] }
// 干支
var gzY = this.toGanZhiYear(year)
var gzM = this.toGanZhi((y-1900)*12+m+(d >= firstTerm? 12: 11))
var gzD = this.toGanZhi(Date.UTC(y,m-1,1,0,0,0,0)/86400000+25567+10+d-1)
// 节日
var nWeek = date.getDay(), cWeek = this.nStr3[nWeek]; if (nWeek == 0) { nWeek = 7 }
function getFestival(list, m, d) { return list[m+"-"+d]? list[m+"-"+d].title: null }
var res = {Date: y+'-'+m+'-'+d, lunarDate: year+'-'+month+'-'+day,
Year: y, Month: m, Day: d, lYear: year, lMonth: month, lDay: day, gzYear: gzY, gzMonth: gzM, gzDay: gzD,
Animal: this.getAnimal(year), cnMonth: (isLeap?"\u95f0":'')+this.toChinaMonth(month), cnDay: this.toChinaDay(day),
isLeap: isLeap, Term: term, Astro: this.toAstro(m, d), nWeek: nWeek, ncWeek: "\u661f\u671f"+cWeek,
lunarFestival: getFestival(this.lfestival, month, day), Festival: getFestival(this.festival, m, d),
}
res.autoDay = res.lunarFestival||res.Festival||term||(day==1? this.toChinaMonth(month): this.toChinaDay(day))
res.autoClass = "lunar"+(res.lunarFestival||res.Festival? " fest":"")+(term? " term": "")
return res
},
// 天干表 ["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"]
Gan: ["\u7532","\u4e59","\u4e19","\u4e01","\u620a","\u5df1","\u5e9a","\u8f9b","\u58ec","\u7678"],
// 地支表 ["子","丑","寅","卯","辰","巳","午","未","申","酉","j戌","亥"]
Zhi: ["\u5b50","\u4e11","\u5bc5","\u536f","\u8fb0","\u5df3","\u5348","\u672a","\u7533","\u9149","\u620c","\u4ea5"],
toGanZhi: function(offset) { return this.Gan[offset%10] + this.Zhi[offset%12] },
toGanZhiYear: function(lYear) { // 农历年份转换为干支纪年
var ganKey = (lYear-3)%10; if (ganKey == 0) { ganKey = 10 }
var zhiKey = (lYear-3)%12; if (zhiKey == 0) { zhiKey = 12 }
return this.Gan[ganKey-1] + this.Zhi[zhiKey-1]
},
// 生肖表 ["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"]
Animals: ["\u9f20","\u725b","\u864e","\u5154","\u9f99","\u86c7","\u9a6c","\u7f8a","\u7334","\u9e21","\u72d7","\u732a"],
// 年份转生肖,精确划分生肖分界线是"立春"
getAnimal: function(y) { return this.Animals[(y - 4) % 12] },
// 月份表 ['正','一','二','三','四','五','六','七','八','九','十','冬','腊']
nStr1: ["\u6b63","\u4e8c","\u4e09","\u56db","\u4e94","\u516d","\u4e03","\u516b","\u4e5d","\u5341","\u51ac","\u814a"],
// 月旬表 ['初','十','廿','卅']
nStr2: ["\u521d","\u5341","\u5eff","\u5345"],
// 日子表 ['日','一','二','三','四','五','六','七','八','九','十']
nStr3: ["\u65e5","\u4e00","\u4e8c","\u4e09","\u56db","\u4e94","\u516d","\u4e03","\u516b","\u4e5d","\u5341"],
toChinaMonth: function(m) { return this.nStr1[m-1]+"\u6708" },
toChinaDay: function(d) { switch (d) {
case 10: return '\u521d\u5341'
case 20: return '\u4e8c\u5341'
case 30: return '\u4e09\u5341'
default: return this.nStr2[Math.floor(d/10)]+this.nStr3[d%10]
} },
// 公历每个月份的天数普通表
solarMonth: [31,28,31,30,31,30,31,31,30,31,30,31],
// 返回公历y年m月的天数
solarDays: function(y, m) { var ms = m-1; if (ms == 1) { return ((y%4 == 0) && (y%100 != 0) || (y%400 == 0))? 29: 28 } else { return this.solarMonth[ms] } },
// 公历月、日判断所属星座
toAstro: function(m, d) { var arr = [20,19,21,21,21,22,23,23,23,23,22,22]
var s = "\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf"
return s.substr(m*2 - (d < arr[m-1]? 2: 0), 2) + "\u5ea7"
},
festival: { // 公历节日
'1-1': {title: '元旦节'},
'12-24': {title: '平安夜'},
'12-25': {title: '圣诞节'},
'2-14': {title: '情人节'},
'3-8': {title: '妇女节'},
'4-1': {title: '愚人节'},
'5-1': {title: '劳动节'},
'5-4': {title: '青年节'},
'6-1': {title: '儿童节'},
'9-10': {title: '教师节'},
'7-1': {title: '建党节'},
'8-1': {title: '建军节'},
'10-1': {title: '国庆节'},
},
lfestival: { // 农历节日
'12-30': {title: '除夕'},
'1-1': {title: '春节'},
'1-15': {title: '元宵'},
'5-5': {title: '端午'},
'7-7': {title: '七夕'},
'8-15': {title: '中秋'},
'9-9': {title: '重阳'},
},
// 返回农历y年m月非闰月的总天数计算m为闰月时的天数请使用leapDays方法
monthDays: function(y, m) { return (this.lunarInfo[y-1900] & (0x10000>>m))? 30: 29 },
// 返回农历y年闰月是哪个月若y年没有闰月则返回0
leapMonth: function(y) { return this.lunarInfo[y-1900] & 0xf },
// 返回农历y年闰月的天数 若该年没有闰月则返回0
leapDays: function(y) { if (this.leapMonth(y)) { return (this.lunarInfo[y-1900] & 0x10000)? 30: 29 } return 0 },
// 返回农历y年一整年的总天数
lYearDays: function(y) { var i, sum = 348
for (i = 0x8000; i > 0x8; i >>= 1) { sum += (this.lunarInfo[y-1900] & i)? 1: 0 }
return sum+this.leapDays(y)
},
lunarInfo: [ // 农历1900-2100的润大小信息表
0x04bd8,0x04ae0,0x0a570,0x054d5,0x0d260,0x0d950,0x16554,0x056a0,0x09ad0,0x055d2,//1900-1909
0x04ae0,0x0a5b6,0x0a4d0,0x0d250,0x1d255,0x0b540,0x0d6a0,0x0ada2,0x095b0,0x14977,//1910-1919
0x04970,0x0a4b0,0x0b4b5,0x06a50,0x06d40,0x1ab54,0x02b60,0x09570,0x052f2,0x04970,//1920-1929
0x06566,0x0d4a0,0x0ea50,0x16a95,0x05ad0,0x02b60,0x186e3,0x092e0,0x1c8d7,0x0c950,//1930-1939
0x0d4a0,0x1d8a6,0x0b550,0x056a0,0x1a5b4,0x025d0,0x092d0,0x0d2b2,0x0a950,0x0b557,//1940-1949
0x06ca0,0x0b550,0x15355,0x04da0,0x0a5b0,0x14573,0x052b0,0x0a9a8,0x0e950,0x06aa0,//1950-1959
0x0aea6,0x0ab50,0x04b60,0x0aae4,0x0a570,0x05260,0x0f263,0x0d950,0x05b57,0x056a0,//1960-1969
0x096d0,0x04dd5,0x04ad0,0x0a4d0,0x0d4d4,0x0d250,0x0d558,0x0b540,0x0b6a0,0x195a6,//1970-1979
0x095b0,0x049b0,0x0a974,0x0a4b0,0x0b27a,0x06a50,0x06d40,0x0af46,0x0ab60,0x09570,//1980-1989
0x04af5,0x04970,0x064b0,0x074a3,0x0ea50,0x06b58,0x05ac0,0x0ab60,0x096d5,0x092e0,//1990-1999
0x0c960,0x0d954,0x0d4a0,0x0da50,0x07552,0x056a0,0x0abb7,0x025d0,0x092d0,0x0cab5,//2000-2009
0x0a950,0x0b4a0,0x0baa4,0x0ad50,0x055d9,0x04ba0,0x0a5b0,0x15176,0x052b0,0x0a930,//2010-2019
0x07954,0x06aa0,0x0ad50,0x05b52,0x04b60,0x0a6e6,0x0a4e0,0x0d260,0x0ea65,0x0d530,//2020-2029
0x05aa0,0x076a3,0x096d0,0x04afb,0x04ad0,0x0a4d0,0x1d0b6,0x0d250,0x0d520,0x0dd45,//2030-2039
0x0b5a0,0x056d0,0x055b2,0x049b0,0x0a577,0x0a4b0,0x0aa50,0x1b255,0x06d20,0x0ada0,//2040-2049
0x14b63,0x09370,0x049f8,0x04970,0x064b0,0x168a6,0x0ea50,0x06b20,0x1a6c4,0x0aae0,//2050-2059
0x092e0,0x0d2e3,0x0c960,0x0d557,0x0d4a0,0x0da50,0x05d55,0x056a0,0x0a6d0,0x055d4,//2060-2069
0x052d0,0x0a9b8,0x0a950,0x0b4a0,0x0b6a6,0x0ad50,0x055a0,0x0aba4,0x0a5b0,0x052b0,//2070-2079
0x0b273,0x06930,0x07337,0x06aa0,0x0ad50,0x14b55,0x04b60,0x0a570,0x054e4,0x0d160,//2080-2089
0x0e968,0x0d520,0x0daa0,0x16aa6,0x056d0,0x04ae0,0x0a9d4,0x0a2d0,0x0d150,0x0f252,//2090-2099
0x0d520, //2100
],
getTerm: function(y, n) { // 传入公历y年获得该年第n个节气的公历日期
var _table = this.termInfo[y-1900]
var _info = [
parseInt('0x'+_table.substr(0,5)).toString(),
parseInt('0x'+_table.substr(5,5)).toString(),
parseInt('0x'+_table.substr(10,5)).toString(),
parseInt('0x'+_table.substr(15,5)).toString(),
parseInt('0x'+_table.substr(20,5)).toString(),
parseInt('0x'+_table.substr(25,5)).toString(),
]
var _calday = [
_info[0].substr(0,1),
_info[0].substr(1,2),
_info[0].substr(3,1),
_info[0].substr(4,2),
_info[1].substr(0,1),
_info[1].substr(1,2),
_info[1].substr(3,1),
_info[1].substr(4,2),
_info[2].substr(0,1),
_info[2].substr(1,2),
_info[2].substr(3,1),
_info[2].substr(4,2),
_info[3].substr(0,1),
_info[3].substr(1,2),
_info[3].substr(3,1),
_info[3].substr(4,2),
_info[4].substr(0,1),
_info[4].substr(1,2),
_info[4].substr(3,1),
_info[4].substr(4,2),
_info[5].substr(0,1),
_info[5].substr(1,2),
_info[5].substr(3,1),
_info[5].substr(4,2),
]; return parseInt(_calday[n-1])
},
// 二十四节气速查表 ["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"]
termName: ["\u5c0f\u5bd2","\u5927\u5bd2","\u7acb\u6625","\u96e8\u6c34","\u60ca\u86f0","\u6625\u5206","\u6e05\u660e","\u8c37\u96e8","\u7acb\u590f","\u5c0f\u6ee1","\u8292\u79cd","\u590f\u81f3","\u5c0f\u6691","\u5927\u6691","\u7acb\u79cb","\u5904\u6691","\u767d\u9732","\u79cb\u5206","\u5bd2\u9732","\u971c\u964d","\u7acb\u51ac","\u5c0f\u96ea","\u5927\u96ea","\u51ac\u81f3"],
termInfo: [ // 1900-2100各年的24节气日期速查表
'9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf97c3598082c95f8c965cc920f',
'97bd0b06bdb0722c965ce1cfcc920f','b027097bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e',
'97bcf97c359801ec95f8c965cc920f','97bd0b06bdb0722c965ce1cfcc920f','b027097bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f','97bd0b06bdb0722c965ce1cfcc920f',
'b027097bd097c36b0b6fc9274c91aa','9778397bd19801ec9210c965cc920e','97b6b97bd19801ec95f8c965cc920f',
'97bd09801d98082c95f8e1cfcc920f','97bd097bd097c36b0b6fc9210c8dc2','9778397bd197c36c9210c9274c91aa',
'97b6b97bd19801ec95f8c965cc920e','97bd09801d98082c95f8e1cfcc920f','97bd097bd097c36b0b6fc9210c8dc2',
'9778397bd097c36c9210c9274c91aa','97b6b97bd19801ec95f8c965cc920e','97bcf97c3598082c95f8e1cfcc920f',
'97bd097bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c91aa','97b6b97bd19801ec9210c965cc920e',
'97bcf97c3598082c95f8c965cc920f','97bd097bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e','97bcf97c3598082c95f8c965cc920f','97bd097bd097c35b0b6fc920fb0722',
'9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f',
'97bd097bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e',
'97bcf97c359801ec95f8c965cc920f','97bd097bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f','97bd097bd07f595b0b6fc920fb0722',
'9778397bd097c36b0b6fc9210c8dc2','9778397bd19801ec9210c9274c920e','97b6b97bd19801ec95f8c965cc920f',
'97bd07f5307f595b0b0bc920fb0722','7f0e397bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c920e',
'97b6b97bd19801ec95f8c965cc920f','97bd07f5307f595b0b0bc920fb0722','7f0e397bd097c36b0b6fc9210c8dc2',
'9778397bd097c36c9210c9274c91aa','97b6b97bd19801ec9210c965cc920e','97bd07f1487f595b0b0bc920fb0722',
'7f0e397bd097c36b0b6fc9210c8dc2','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e',
'97bcf7f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e','97bcf7f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722',
'9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf7f1487f531b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e',
'97bcf7f1487f531b0b0bb0b6fb0722','7f0e397bd07f595b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c9274c920e','97bcf7f0e47f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722',
'9778397bd097c36b0b6fc9210c91aa','97b6b97bd197c36c9210c9274c920e','97bcf7f0e47f531b0b0bb0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c920e',
'97b6b7f0e47f531b0723b0b6fb0722','7f0e37f5307f595b0b0bc920fb0722','7f0e397bd097c36b0b6fc9210c8dc2',
'9778397bd097c36b0b70c9274c91aa','97b6b7f0e47f531b0723b0b6fb0721','7f0e37f1487f595b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc9210c8dc2','9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa',
'97b6b7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722',
'9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9274c91aa',
'97b6b7f0e47f531b0723b0787b0721','7f0e27f0e47f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722',
'9778397bd097c36b0b6fc9210c91aa','97b6b7f0e47f149b0723b0787b0721','7f0e27f0e47f531b0723b0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9210c8dc2','977837f0e37f149b0723b0787b0721',
'7f07e7f0e47f531b0723b0b6fb0722','7f0e37f5307f595b0b0bc920fb0722','7f0e397bd097c35b0b6fc9210c8dc2',
'977837f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0721','7f0e37f1487f595b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc9210c8dc2','977837f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','977837f0e37f14998082b0787b06bd',
'7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722',
'977837f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722','977837f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','977837f0e37f14998082b0787b06bd',
'7f07e7f0e47f149b0723b0787b0721','7f0e27f0e47f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722',
'977837f0e37f14998082b0723b06bd','7f07e7f0e37f149b0723b0787b0721','7f0e27f0e47f531b0723b0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722','977837f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b0721',
'7f07e7f0e47f531b0723b0b6fb0722','7f0e37f1487f595b0b0bb0b6fb0722','7f0e37f0e37f14898082b0723b02d5',
'7ec967f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0722','7f0e37f1487f531b0b0bb0b6fb0722',
'7f0e37f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721',
'7f0e37f1487f531b0b0bb0b6fb0722','7f0e37f0e37f14898082b072297c35','7ec967f0e37f14998082b0787b06bd',
'7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e37f0e37f14898082b072297c35',
'7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722',
'7f0e37f0e366aa89801eb072297c35','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f149b0723b0787b0721',
'7f0e27f1487f531b0b0bb0b6fb0722','7f0e37f0e366aa89801eb072297c35','7ec967f0e37f14998082b0723b06bd',
'7f07e7f0e47f149b0723b0787b0721','7f0e27f0e47f531b0723b0b6fb0722','7f0e37f0e366aa89801eb072297c35',
'7ec967f0e37f14998082b0723b06bd','7f07e7f0e37f14998083b0787b0721','7f0e27f0e47f531b0723b0b6fb0722',
'7f0e37f0e366aa89801eb072297c35','7ec967f0e37f14898082b0723b02d5','7f07e7f0e37f14998082b0787b0721',
'7f07e7f0e47f531b0723b0b6fb0722','7f0e36665b66aa89801e9808297c35','665f67f0e37f14898082b0723b02d5',
'7ec967f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0722','7f0e36665b66a449801e9808297c35',
'665f67f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721',
'7f0e36665b66a449801e9808297c35','665f67f0e37f14898082b072297c35','7ec967f0e37f14998082b0787b06bd',
'7f07e7f0e47f531b0723b0b6fb0721','7f0e26665b66a449801e9808297c35','665f67f0e37f1489801eb072297c35',
'7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722'],
})
Volcanos("page", {trans: function(can, text) {
return can.base.replaceAll(text, "&", "&amp;", "<", "&lt;", ">", "&gt;")
}})

View File

@ -1,282 +1,403 @@
Volcanos("misc", {help: "通信协议", Message: function(event, can) { var msg = {} Volcanos("misc", {
var proto = {_event: event, _can: can, Event: function(event, can, cb) { for (var i = 3; i < arguments.length; i++) { can.request(event, arguments[i]) } cb(can.request(event)) },
RunAction: function(event, sub, cmds) { var msg = can.request(event) Message: function(event, can) { var msg = kit.proto({}, {_event: event, _can: can, _target: can._target,
if (msg.Option(ice.MSG_HANDLE) == ice.TRUE) { return } RunAction: function(event, sub, cmds, meta) { var msg = can.request(event); meta = meta || sub&&sub.onaction || {}
if (cmds && cmds[0] == ctx.ACTION && sub && sub.onaction[cmds[1]]) { if (!msg._method) {
return msg.Option(ice.MSG_HANDLE, ice.TRUE), can.core.CallFunc(sub.onaction[cmds[1]], {event: event, can: sub, msg: msg, button: cmds[1], cmd: cmds[1]}), true if (!cmds || cmds.length == 0 || cmds[0] != ctx.ACTION) {
} msg._method = http.GET
return false } else if (can.base.isIn(cmds[1], mdb.CREATE, mdb.INSERT)) {
}, msg._method = http.PUT
OptionStatus: function() { return msg.Option(ice.MSG_STATUS) }, } else if (can.base.isIn(cmds[1], mdb.REMOVE, mdb.DELETE)) {
OptionProcess: function() { return msg.Option(ice.MSG_PROCESS) }, msg._method = http.DELETE
Option: function(key, val) { } else {
if (key == undefined) { return msg && msg.option || [] } msg._method = http.POST
if (can.base.isObject(key)) { can.core.Item(key, msg.Option) } }
if (val == undefined) { return msg && msg[key] && msg[key][0] || "" } }
return msg.option = can.base.AddUniq(msg.option, key), msg[key] = can.core.List(arguments).slice(1), val if (msg.Option(ice.MSG_HANDLE) != ice.TRUE && cmds && cmds[0] == ctx.ACTION && can.base.isFunc(meta[cmds[1]])) { msg.Option(ice.MSG_HANDLE, ice.TRUE)
}, return can.core.CallFunc(meta[cmds[1]], {event: event._event||event, can: sub, msg: msg, button: cmds[1], cmd: cmds[1]}), true
Append: function(key, val) { }
if (key == undefined) { return msg && msg.append || [] } },
if (can.base.isObject(key)) { can.core.Item(key, msg.Append) } Display: function(file) { return msg.Option(ice.MSG_DISPLAY, file) },
if (val == undefined) { return msg && msg[key] && msg[key][0] || "" } DisplayStory: function(file) { return msg.Option(ice.MSG_DISPLAY, chat.PLUGIN_STORY+file) },
return msg.append = can.base.AddUniq(msg.append, key), msg[key] = can.core.List(arguments).slice(1), val SearchOrOption: function(key) { return can.misc.Search(can, key)||msg.Option(key) },
}, OptionProcess: function() { return msg.Option(ice.MSG_PROCESS) },
Result: function() { return msg.result && msg.result.join("") || "" }, OptionStatus: function() { return msg.Option(ice.MSG_STATUS) },
StatusTimeCount: function(obj) { msg.append && msg.Status(can.base.Copy(kit.Dict(mdb.TIME, can.base.Time(), mdb.COUNT, msg.Length()+"x"+msg.append.length), obj)) },
Status: function(obj) { return msg.Option(ice.MSG_STATUS, JSON.stringify(can.core.Item(obj, function(key, value) { return {name: key, value: value} }))) },
OptionDefault: function(key, val) { var arg = arguments; for (var i = 0; i < arg.length; i += 2) { msg.Option(arg[i]) || msg.Option(arg[i], arg[i+1]) } return msg.Option(key) },
OptionSimple: function(key) { var arg = arguments, res = []
for (var i = 0; i < arg.length; i++) { res.push(arg[i], msg.Option(arg[i])) }
return res
},
Option: function(key, val) { if (key == undefined) { return msg.option || [] }
if (can.base.isObject(key)) { return can.core.Item(key, function(key, value) { msg.Option(key, value) }) }
if (val == undefined) { return can.base.isIn(key, msg.option) && msg[key] && msg[key][0] || "" }
return msg.option = can.base.AddUniq(msg.option, key), msg[key] = can.core.List(arguments).slice(1), val
},
Append: function(key, val) { if (key == undefined) { return msg.append || [] }
if (can.base.isObject(key)) { return can.core.Item(key, msg.Append) }
if (msg.IsDetail()) {
for (var i = 0; i < msg.key.length; i++) {
if (msg.key[i] == key) {
if (val != undefined) { msg.value[i] = val }
return msg.value[i]
}
}
return
}
if (val == undefined) { return can.base.isIn(key, msg.append) && msg[key] && msg[key][0] || "" }
return msg.append = can.base.AddUniq(msg.append, key), msg[key] = can.core.List(arguments).slice(1), val
},
Result: function() { if (!msg.result) { return "" } return msg.result[0] == ice.ErrWarn? msg.result.join(lex.SP): msg.result.join("") },
Results: function() { return msg.result && msg.result[0] == ice.ErrWarn? "": msg.Result() },
TableDetail: function() { var item = can.Option(); return msg.Table(function(value) { can.core.Value(item, value.key, value.value) }), item },
IsDetail: function() {
return msg.Option("fields") == "detail" || msg.append && msg.append.length == 2 && msg.append[0] == "key" && msg.append[1] == "value"
},
Table: function(cb) { return can.core.List(msg.Length(), function(index) { var item = {}
can.core.List(msg.append, function(k) { item[k] = msg[k]&&msg[k][index]||"" })
return can.base.isFunc(cb)? cb(item, index): item
}) },
Length: function() { var max = 0; can.core.List(msg.append, function(k) { if (msg[k] && msg[k].length > max) { max = msg[k].length } }); return max },
Clear: function(key) { switch (key||ice.MSG_APPEND) {
case ice.MSG_OPTION:
case ice.MSG_APPEND: can.core.List(msg[key], function(key) { delete(msg[key]) })
default: delete(msg[key])
} },
Copy: function(res) { if (!res) { return msg }
res.append && res.append.length > 0 && (msg.append = res.append) && res.append.forEach(function(key) {
var i = msg.option && msg.option.indexOf(key); if (i > -1) { msg.option[i] = "", delete(msg[key]) }
res[key] && (msg[key] = (msg[key]||[]).concat(res[key]))
}), res.result && res.result.length > 0 && (msg.result = (msg.result||[]).concat(res.result))
res.option && res.option.length > 0 && (msg.option = res.option) && res.option.forEach(function(key) { res[key] && (msg[key] = res[key]) })
res._option && (msg._option = res._option) && res._option.forEach(function(key) { res[key] && (msg[key] = res[key]) })
return msg
},
Sort: function(key, swap) { var n = msg.Length()
key = key||msg.append[0], swap = swap||function(i, j) { return msg[key][i] > msg[key][j] }
switch (swap) {
case "str": swap = function(i, j) { return msg[key][i] > msg[key][j] }; break
case "str_r": swap = function(i, j) { return msg[key][i] < msg[key][j] }; break
case "int": swap = function(i, j) { return can.base.ParseSize(msg[key][i]) > can.base.ParseSize(msg[key][j]) }; break
case "int_r": swap = function(i, j) { return can.base.ParseSize(msg[key][i]) < can.base.ParseSize(msg[key][j]) }; break
}
for (var i = 0; i < n-1; i++) {
for (var j = i+1; j < n; j++) { var _swap = swap(i, j)
if (_swap === true) {
can.core.List(msg.append, function(k) {
var temp = msg[k][i]; msg[k][i] = msg[k][j], msg[k][j] = temp
})
} else if (_swap === false) {
continue
} else {
Length: function() { }
var max = "", len = 0; can.core.List(msg.append, function(key, index) { }
if (msg[key] && msg[key].length > len) { max = key, len = msg[key].length } }
}) },
return len Push: function(key, value, detail) {
}, if (can.base.isObject(key)) { can.core.List(value||msg.append||can.base.Obj(msg.Option(ice.MSG_FIELDS))||can.core.Item(key), function(item) {
Table: function(cb) { if (!msg.append || msg.append.length == 0) { return } detail? msg.Push(mdb.KEY, item).Push(mdb.VALUE, key[item]||""): msg.Push(item, key[item]||"")
var max = "", len = 0; can.core.List(msg.append, function(key, index) { }); return msg }
if (msg[key] && msg[key].length > len) { max = key, len = msg[key].length } var i = msg.option && msg.option.indexOf(key); if (i > -1) { msg.option[i] = "", msg[key] = [] }
}) msg.append = can.base.AddUniq(msg.append, key), msg[key] = msg[key]||[]
msg[key].push(can.base.isString(value)||can.base.isFunc(value)? value: JSON.stringify(value)); return msg
return can.core.List(msg[max], function(value, index, array) { var one = {}, res },
can.core.List(msg.append, function(key) { one[key] = (msg[key]&&msg[key][index]||"") }) PushButton: function(button) { var args = can.core.List(arguments)
return can.base.isFunc(cb) && (res = cb(one, index, array)) && res != undefined && res || one msg.Push(ctx.ACTION, can.core.List(args, function(button) {
}) return can.page.Format(html.INPUT, "", mdb.TYPE, html.BUTTON, mdb.NAME, button, mdb.VALUE, can.user.trans(can, button))
}, }).join("")); return msg
Clear: function(key) { switch (key||ice.MSG_APPEND) { },
case ice.MSG_APPEND: PushAction: function(button) { var args = can.core.List(arguments)
case ice.MSG_OPTION: can.core.List(msg.Length(), function() {
can.core.List(msg[key], function(item) { delete(msg[item]) }) msg.Push(ctx.ACTION, can.core.List(args, function(button) {
default: msg[key] = [] return can.page.Format(html.INPUT, "", mdb.TYPE, html.BUTTON, mdb.NAME, button, mdb.VALUE, can.user.trans(can, button))
} }, }).join(""))
Copy: function(res) { if (!res) { return msg } }); return msg
res.result && (msg.result = (msg.result||[]).concat(res.result)) },
res.append && (msg.append = res.append) && res.append.forEach(function(item) { Echo: function(res) { msg.result = (msg.result||[]).concat(can.core.List(arguments)); return msg._hand = true, msg },
var i = msg.option && msg.option.indexOf(item); if (i > -1) { Dump: function(can, target) { can = can||msg._can; if (can.user.isNodejs) { return }
msg.option[i] = "", delete(msg[item]) target = target||can._output
} can.onmotion.clear(can, target), can.onappend.table(can, msg, null, target), can.onappend.board(can, msg, target), can.onmotion.story.auto(can)
res[item] && (msg[item] = (msg[item]||[]).concat(res[item])) },
}) Show: function(can) { can = can||msg._can; if (can.user.isNodejs) { return }
res.option && (msg.option = res.option) && res.option.forEach(function(item) { can.onmotion.clear(can), can.onappend.table(can, msg), can.onappend.board(can, msg), can.onmotion.story.auto(can)
res[item] && (msg[item] = res[item]) },
}) Defer: function(cb) { msg._defer = msg._defer||[]
res._option && (msg._option = res._option) && res._option.forEach(function(item) { if (arguments.length == 0) { msg._defer = can.core.List(msg._defer.reverse(), function(cb) { can.base.isFunc(cb) && cb() }) } else { msg._defer.push(cb) }
res[item] && (msg[item] = res[item]) },
}) IsErr: function() { return msg.result && msg.result[0] == "warn: " },
return msg _caller: function(skip) { msg.Option("log.caller") || msg.Option("log.caller", can.misc.fileLine((skip||2)+3).link); return msg },
}, isDebug: function() { return msg.Option(log.DEBUG) == ice.TRUE },
Push: function(key, value, detail) { }); return msg },
if (can.base.isObject(key)) { Inputs: function(can, msg, cmds, cb, meta) { var event = msg._event
value = value || can.core.Item(key), can.core.List(value, function(item) { if (msg.Option(ice.MSG_HANDLE) != ice.TRUE && cmds && cmds[0] == ctx.ACTION && meta.feature[cmds[1]]) { msg.Option(ctx.ACTION, cmds[1])
detail? msg.Push(mdb.KEY, item).Push(mdb.VALUE, key[item]||""): var action = meta.feature[cmds[1]]; if (can.base.isFunc(action)) { cb = cb||function() { can.Update() }
msg.Push(item, key[item]||"") return action.list && action.list.length > 0? can.user.input(event, can, action.list, function(data) {
}) can.core.CallFunc(action, {can: can, msg: can.request(event, data), arg: cmds.slice(2), cb: cb})
return msg }): can.core.CallFunc(action, {sup: meta.can, can: can, msg: can.request(event), arg: cmds.slice(2), cb: cb})
} }
var input = can.user.input(event, can, meta.feature[cmds[1]], function(args) { msg.result = []
msg.append = can.base.AddUniq(msg.append, key), msg[key] = msg[key] || [] can.onmotion.delay(can, function() { can.page.ClassList.add(can, input._target, html.PROCESS) })
msg[key].push(can.base.isString(value)||can.base.isFunction(value)? value: JSON.stringify(value)) can.Update(can.request(event, can.Option(), {_handle: ice.TRUE, _cancel: function(event) {
return msg can.page.ClassList.del(can, input._target, html.PROCESS)
}, }}, msg), cmds.slice(0, 2).concat(args), function(msg) { can.page.ClassList.del(can, input._target, html.PROCESS)
Echo: function(res) { msg.result = msg.result || [] if (msg.IsErr()) { input.focus()
for (var i = 0; i < arguments.length; i++) { msg.result.push(arguments[i]) } can.onappend.style(can, "warn", can.user.toastFailure(can, msg.Result())._target)
return msg._hand = true, msg } else {
}, if (cb && cb(msg)) { return }
}; input.cancel({}, can)
return can.misc.proto(msg, proto) return true
}, }
POST: function(can, msg, url, form, cb) { // _method _accept _upload _progress }); return true
var xhr = new XMLHttpRequest(); msg._xhr = xhr }); return true
xhr.open(msg._method||"POST", url), xhr.onreadystatechange = function() { } return false
if (xhr.readyState != 4) { return } },
ParseCmd: function(can, msg, cb, cbs) { var list = []
try { // 解析响应 return msg.Table(function(field, order) {
var res = JSON.parse(xhr.responseText) field.feature = can.base.Obj(field.meta, {})
} catch (e) { field.inputs = can.base.Obj(field.list, [])
var res = {result: [xhr.responseText]} field.name = can.core.Split(field.name)[0]
} if (!field.inputs || field.inputs.length === 0) {
if (xhr.status == 200) { return can.onmotion.delay(can, function() { cb(field, order) })
return can.base.isFunc(cb) && cb(msg.Copy(res)) }
} can.core.List(field.inputs, function(input, index) {
can.user.toast(can, res, xhr.status) input.action = input.action || input.value
} input.value == ice.AUTO && (input.value = "")
if (input.value && input.value.indexOf("@") == 0) {
if (msg._upload) { // 上传文件 input.action = input.value.slice(1), input.value = ""
var data = new FormData(); can.core.Items(form, function(value, index, key) { }
data.append(key, value) if (input.type == html.SELECT) {
}), data.append(html.UPLOAD, msg._upload), data.append(ice.MSG_UPLOAD, "upload") input.values = input.values || can.core.Split(input.value)
}
xhr.upload.onprogress = function(event) { if (can.base.isIn(input.type, html.TEXT, html.TEXTAREA)) {
can.base.isFunc(msg._progress) && msg._progress(event, parseInt(event.loaded*100/event.total), event.total, event.loaded) // input.placeholder = can.user.trans(can, input.placeholder||input.name, field, html.INPUT)
} }
} else { // 请求数据 if (input.type == html.BUTTON) {
var data = can.core.Items(form, function(value, index, key) { return key+"="+encodeURIComponent(value) }).join("&") input.value = can.user.trans(can, input.value||input.name, field)
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded") } else {
} cbs && cbs(input, index, field, order)
}
// 发送请求 input.type == html.BUTTON && input.action == ice.AUTO && can.onmotion.delay(can, function() { cb(field, order) })
xhr.setRequestHeader("Accept", msg._accept||"application/json") })
try { xhr.send(data) } catch(e) { can.misc.Log(e) } return field
}, })
Run: function(event, can, dataset, cmds, cb) { },
var msg = can.request(event||{}), skip = {_handle: true} Run: function(event, can, dataset, cmds, cb) { var msg = can.request(event), _can = msg._can; _can._fields && _can.sup && (_can = _can.sup)
var form = {cmds: cmds||msg.cmd}; msg.option && msg.option.forEach(function(item) { var form = {cmds: cmds}; can.core.List(msg.option, function(key) { !can.base.isIn(key, "log.caller", "_handle", "_toast") && msg[key] && (form[key] = msg[key]) })
!skip[item] && msg[item] && (form[item] = msg[item]) can.misc.POST(can, msg, dataset.names.toLowerCase(), form, cb)
}) },
GET: function(can, path, cb) { can.misc.POST(can, can.request({}, {_method: http.GET}), path, {}, function(msg) {
can.misc.POST(can, msg, can.base.MergeURL(dataset.names.toLowerCase(), cb(msg._xhr.responseText)
"_", (msg._can.sup||msg._can)._name, ice.MSG_DAEMON, msg.__daemon||dataset.daemon||"" }) },
), form, cb) POST: function(can, msg, url, form, cb, cbs) { var xhr = new XMLHttpRequest(), begin = new Date(); msg._xhr = xhr, xhr._begin = begin
}, var data = can.core.ItemForm(form, function(v, i, k) { return k+mdb.EQ+encodeURIComponent(v) }).join("&")
WSS: function(can, args, cb, onopen, onclose, onerror) { if (can.user.isIE) { return } if (can.user.isMailMaster && location.protocol == "http:") { msg._method = http.GET }
var url = location.protocol.replace("http", "ws")+"//"+location.host+"/space/" if (data && can.base.isIn(msg._method, http.GET, http.DELETE)) { url += (url.indexOf("?") == -1? "?": "&")+data, data = "" }
if (url.indexOf("chrome") == 0) { url = "ws://localhost:9020/space/" } xhr.open(msg._method||http.POST, url), xhr.onreadystatechange = function() { if (xhr.readyState != 4) { return }
try { var res = JSON.parse(xhr.responseText) } catch (e) {
var socket = new WebSocket(can.base.MergeURL(url, args)) if (xhr.responseText.indexOf("warn: ")) { var res = {result: [xhr.responseText]} } else { var res = {result: [xhr.responseText]} }
socket.onclose = function() { can.misc.Log(html.WSS, cli.CLOSE, args) } msg.Option("_cost", new Date() - begin), msg.detail || (msg.detail = res.detail), msg.Copy(res)
can.base.isFunc(onclose)? onclose(socket): can.core.Timer(1000, function() { if (xhr.status == 200) { return can.base.isFunc(cb) && cb(msg) } typeof msg._failure == code.FUNCTION && msg._failure()
can.misc.WSS(can, args, cb, onopen, onerror, onclose) can.user.toastFailure(msg._can||can, msg.Result(), msg.Option(ice.MSG_TITLE)), can.misc.Warn(xhr.status, res, url, form), cbs && cbs(xhr)
}) }, xhr.setRequestHeader(http.Accept, msg._accept||http.ApplicationJSON)
}, socket.onerror = function() { can.misc.Log(html.WSS, cli.ERROR, args) if (msg._upload) { var data = new FormData(); can.core.ItemForm(form, function(v, i, k) { data.append(k, v) })
can.base.isFunc(onerror)? onerror(socket): socket.close() data.append(ice.MSG_UPLOAD, web.UPLOAD), data.append(web.UPLOAD, msg._upload)
xhr.upload.onprogress = function(event) { can.base.isFunc(msg._progress) && msg._progress(event, parseInt(event.loaded*100/event.total), event.total, event.loaded) }
}, socket.onopen = function() { can.misc.Log(html.WSS, cli.OPEN, args) } else {
can.base.isFunc(onopen) && onopen(socket) xhr.setRequestHeader(http.ContentType, http.ApplicationFORM)
} } try { xhr.send(data) } catch(e) { can.misc.Warn(e), cbs && cbs(e) }
},
socket.onmessage = function(event) { WSS: function(can, args, cb, onopen, onclose, onerror, _msg) { if (can.user.isIE) { return }
try { // 解析命令 args.debug = can.misc.Search(can, ice.MSG_DEBUG)
var data = JSON.parse(event.data) args[ice.FROM_DAEMON] = can.misc.Search(can, ice.FROM_DAEMON)
} catch (e) { args.text = location.pathname+location.search, args.module = "shylinux.com/x/volcanos", args.version = can.base.trimPrefix(window._version, "?_v=")
var data = {detail: [event.data]} var msg = can.request(); can.page.exportValue(can, msg), can.core.List(msg.Option(), function(value) { args[value] = msg.Option(value) })
} var url = location.protocol.replace(ice.HTTP, "ws")+"//"+location.host+"/space/"; if (url.indexOf(html.CHROME) == 0) { url = "ws://localhost:9020/space/" }
try { var socket = new WebSocket(can.base.MergeURL(url, args)); _msg = _msg || can.request()._caller() } catch (e) {}
var msg = can.request(event); msg.Reply = function() { // 回复命令 can._socket = socket, socket.onclose = function() { can.misc.Log(html.WSS, cli.CLOSE, args); if (socket._close) { return }
msg.result = (msg.result||[]).concat(can.core.List(arguments)) can.base.isFunc(onclose)? onclose(socket): can.core.Timer(can.base.random(3000, 300), function() {
args.name = args.name||can._wss_name, can.misc.WSS(can, args, cb, onopen, onerror, onclose, _msg)
msg.Option({_handle: true, _source: (msg[ice.MSG_TARGET]||[]).reverse().slice(1).join(ice.PT)||"",_target: (msg[ice.MSG_SOURCE]||[]).reverse().join(".")}) })
can.misc.Log(html.WSS, ice.MSG_RESULT, msg.result, msg) }, socket.onerror = function() { can.misc.Log(html.WSS, log.ERROR, args)
can.base.isFunc(onerror)? onerror(socket): socket.close()
delete(msg._event), delete(msg._can) }, socket.onopen = function() { can.misc.Log(html.WSS, cli.OPEN, args, _msg)
socket.send(JSON.stringify(msg)) can.base.isFunc(onopen) && onopen(socket)
}, msg.detail = data.detail, msg.Copy(data) }, socket.onmessage = function(event) { can.misc.Event(event, can, function(msg) {
try { var data = JSON.parse(event.data) } catch (e) { var data = {detail: [event.data]} }
// 执行命令 msg.Reply = function() { if (msg.Option("space.noecho") == ice.TRUE) { return }
try { var res = can.request({}, {_handle: ice.TRUE})
can.misc.Log(html.WSS, ice.MSG_DETAIL, msg.detail, msg) res._target = (msg[ice.MSG_SOURCE]||[]).reverse(), res._source = (msg[ice.MSG_TARGET]||[]).reverse().slice(1)||[]
can.base.isFunc(cb) && cb(event, msg, msg.detail[0], msg.detail.slice(1)) res.append = msg.append, can.core.List(msg.append, function(key) { res[key] = msg[key] }), res.result = (msg.result||[]).concat(can.core.List(arguments))
} catch (e) { // 执行失败 res.Option(ice.LOG_DISABLE, msg.Option(ice.LOG_DISABLE)) != ice.TRUE && can.misc.Log(html.WSS, ice.MSG_RESULT, msg.result&&msg.result.length>0? msg.result: undefined, msg, _msg)
can.misc.Log(e), msg.Reply() res.Option(ice.LOG_TRACEID, msg.Option(ice.LOG_TRACEID))
} res.Option(ice.MSG_DEBUG, msg.Option(ice.MSG_DEBUG))
} socket.send(JSON.stringify(res))
}, msg.Option("space.noecho", ice.TRUE)
}, msg.detail = data.detail||[], msg.Copy(data), msg[ice.MSG_TARGET] = data[ice.MSG_TARGET]||[]
CookieSessid: shy("会话变量", function(can, value, path) { try { msg.Option(ice.LOG_DISABLE) != ice.TRUE && can.misc.Log(html.WSS, ice.MSG_DETAIL, msg.detail, msg, _msg)
var name = ice.MSG_SESSID+"_"+location.host.replaceAll(".", "_").replaceAll(":", "_") can.core.CallFunc(cb, {event: event, msg: msg, cmd: msg.detail[0], arg: msg.detail.slice(1), cb: function() { msg.Reply() }})
return can.misc.Cookie(can, name, value, path) } catch (e) { can.misc.Warn(e), msg.Reply() }
}), }) }
Cookie: shy("会话变量", function(can, key, value, path) { return socket
function set(k, v) { document.cookie = k+"="+v+";path="+(path||ice.PS) } },
ResourceFavicon: function(can, path, space) { return can.misc.Resource(can, path||can.user.info.favicon||nfs.SRC_MAIN_ICO, space) },
if (can.base.isObject(key)) { ResourceIcons: function(can, path, space, serve) {
for (var k in key) { set(k, key[k]) } if (!path) {
key = undefined if (can.user.info.nodetype == web.WORKER) {
} return can.misc.Resource(can, can.user.info.favicon, can.user.info.nodename)
if (key == undefined) { var cs = {} }
document.cookie.split("; ").forEach(function(item) { }
var ls = item.split("="); cs[ls[0]] = ls[1] return can.misc.Resource(can, path||(can.page.isDark(can)? "usr/icons/volcanos.png": "usr/icons/icebergs.png"), space, serve)
}) },
return cs Resource: function(can, path, space, serve) { if (!path) { return "" }
} if (!can.base.beginWith(path, web.HTTP, nfs.PS)) { path = nfs.P+path+(path.indexOf("usr/icons/") == -1? (space? can.core.Split(_version, "&")[0]: _version): "") }
if (!can.base.beginWith(path, web.HTTP)) { if (serve && serve.indexOf(location.origin) == -1) { var u = can.base.ParseURL(serve); path = u.origin + path } }
value != undefined && set(key, value) if (!space && !can.base.beginWith(path, web.HTTP)) { return location.origin+path }
var val = (new RegExp(key+"=([^;]*);?")).exec(document.cookie) if (!space && path.indexOf("pod=") > 0) { return path }
return val && val.length > 0? val[1]: "" if (can.base.beginWith(path, "/") && path.indexOf("pod=") > 0) { return path }
}), return can.base.MergeURL(path, ice.POD, space||can.ConfSpace()||can.misc.Search(can, ice.POD))
Search: shy("请求参数", function(can, key, value) { var args = {} },
if (value == undefined && can.base.isString(key)) { ShareLocal: function(can, path, space) { if (can.base.beginWith(path, web.HTTP, nfs.PS)) { return path }
var ls = location.pathname.split(ice.PS) return can.base.MergeURL(nfs.SHARE_LOCAL+path+_version, ice.POD, space||can.ConfSpace())
if (ls[1] == chat.SHARE) { args[chat.SHARE] = ls[2] } },
if (ls[1] == "chat" && ls[2] == ice.POD) { args[ice.POD] = ls[3] } ShareCache: function(can, path, space) { if (can.base.beginWith(path, web.HTTP, nfs.PS)) { return path }
} return can.base.MergeURL(nfs.SHARE_CACHE+path+_version, ice.POD, space||can.ConfSpace()||can.misc.Search(can, ice.POD))
},
location.search && location.search.slice(1).split("&").forEach(function(item) { var x = item.split("=") Template: function(can, path, file) { return can.base.Path(nfs.SRC_TEMPLATE, can.ConfIndex(), path, file) },
x[1] != "" && (args[x[0]] = decodeURIComponent(x[1])) MergePath: function(can, file, path) { return file.indexOf(nfs.PS) == 0 || file.indexOf(ice.HTTP) == 0? file: can.base.Path(path, file) },
}) MergeCache: function(can, hash, pod) { return can.base.MergeURL(can.misc.MergeURL(can, {_path: can.base.Path(web.SHARE_CACHE, hash)}, true), ice.POD, pod||can.ConfSpace()||can.misc.Search(can, ice.POD)) },
MergePodCmd: function(can, obj) {
if (can.base.isObject(key)) { if (can.base.beginWith(obj.pod, nfs.PS, web.HTTP)) {
can.core.Item(key, function(key, value) { if (location.search.indexOf("debug=true") > 0 && obj.pod.indexOf("debug=true") == -1) {
if (value != undefined) {args[key] = value} var ls = obj.pod.split("#"); ls[0] += (ls[0].indexOf("?") > 0? "&": "?") + "debug=true", obj.pod = ls.join("#")
args[key] == "" && delete(args[key]) } return obj.pod
}) }
} else if (key == undefined) { obj.pod = obj.pod == undefined? can.misc.Search(can, ice.POD): obj.pod; return can.misc.MergeURL(can, obj, true)
return args },
} else if (value == undefined) { MergeURL: function(can, obj, clear) { var path = location.pathname; obj._path && (path = obj._path), delete(obj._path)
return args[key] can.misc.Search(can, log.DEBUG) && (obj.debug = ice.TRUE); var hash = obj._hash||""; delete(obj._hash)
} else { var args = []; can.core.List([ice.POD, ice.CMD], function(key) { obj[key] && args.push(key == ice.POD? "s": "c", obj[key]), delete(obj[key]) })
args[key] = value, args[key] == "" && delete(args[key]) var _location = location; if (can.user.isExtension) { var _location = new URL(Volcanos.meta.iceberg) }
} return can.base.MergeURL(_location.origin+(args.length > 0? nfs.PS+args.join(nfs.PS): path)+(clear? "": _location.search), obj)+(hash? "#"+hash: "")
},
return location.search = can.core.Item(args, function(key, value) { ParseURL: function(can, url) { url = url||location.href; var args = can.base.ParseURL(url)
return key+"="+encodeURIComponent(value) delete(args.link), delete(args.origin), delete(args._origin)
}).join("&") var raw = new RegExp("(https?://[^/]+)([^?#]*)([^#]*)(.*)").exec(url)
}), var ls = can.core.Split(raw[2], nfs.PS);
MergeURL: shy("地址链接", function(can, objs, clear) { if (ls[0] == chat.SHARE) { args[chat.SHARE] = ls[1] }
var path = location.pathname; objs._path && (path = objs._path, delete(objs._path)) if (ls[0] == "s") { args[ice.POD] = decodeURIComponent(ls[1]); if (ls[2] == "c") { args[ice.CMD] = ls[3] } }
objs && objs.pod && (path = "/chat/pod/"+objs.pod, delete(objs.pod)) if (ls[0] == "c") { args[ice.CMD] = ls[1] }
return can.base.MergeURL(location.origin+path+(clear?"":location.search), objs) for (var i = 1; i < ls.length; i += 2) { if (can.base.isIn(ls[i], [ice.POD, ice.CMD])) { args[ls[i]] = ls[i+1] } }
}), return args
},
concat: function(to, from) { SplitPath: function(can, path) {
if (from[0] == "_search") { return from } if (path.indexOf("http") == 0) { return [path] }
return to.concat(from) if (path.indexOf("/require/") == 0) { return [path] }
}, if (path.indexOf("/p/") == 0) { return [path] }
proto: function(sub, sup) { if (path.indexOf("/plugin/") == 0) { return ["usr/volcanos/", path.split("?")[0]] }
if (navigator.userAgent.indexOf("MSIE") > -1) { var ls = path.split(nfs.PS); if (ls.length == 1) { return [nfs.PWD, ls[0]] }
for (var k in sup) { sub[k] = sub[k]||sup[k] } if (ls[0] == ice.USR) { return [ls.slice(0, 2).join(nfs.PS)+nfs.PS, ls.slice(2).join(nfs.PS)] }
} else { return [ls.slice(0, 1).join(nfs.PS)+nfs.PS, ls.slice(1).join(nfs.PS)]
sub.__proto__ = sup },
} PathJoin: function(dir, file, ext) { file = file||""
return sub if (file.indexOf(nfs.PS) == 0 || file.indexOf(web.HTTP) == 0) { return file }
}, if (dir.indexOf(nfs.SRC) == 0 || dir.indexOf(nfs.USR) == 0) { dir = nfs.P+dir }
return dir+file+(ext? nfs.PT+ext: "")
Log: function() { },
var args = [this._time(), this.FileLine(2, 3)] isDebug: function(can) { return can.misc.Search(can, log.DEBUG) == ice.TRUE },
for (var i in arguments) { args.push(arguments[i]) } isImage: function(can, path) { return can.base.isIn(can.base.Ext(path), "png", "jpg", "jpeg") },
console.log.apply(console, args) isVideo: function(can, path) { return can.base.isIn(can.base.Ext(path), "mp4", "m4v", "mov", "webm") },
}, isAudio: function(can, path) { return can.base.isIn(can.base.Ext(path), "mp3") },
Info: function() { Search: function(can, key, value) { var args = this.ParseURL(can, location.href)
var args = [this._time(), this.FileLine(2, 3)] if (can.base.isUndefined(key)) { return args } else if (can.base.isObject(key)) {
for (var i in arguments) { args.push(arguments[i]) } can.core.Item(key, function(k, v) { v === ""? delete(args[k]): (args[k] = v) })
console.log.apply(console, args) } else if (can.base.isUndefined(value)) { return args[key] } else {
}, value === ""? delete(args[key]): (args[key] = value)
Warn: function() { }
var args = [this._time(), this.FileLine(2, 3), "warn"] location.pathname.indexOf("/chat/pod/") == 0 && delete(args["pod"])
for (var i in arguments) { args.push(arguments[i]) } location.pathname.indexOf("/s/") == 0 && delete(args["pod"])
args.push(ice.NL, this._fileLine().split(ice.NL).slice(2).join(ice.NL)) var search = can.base.Args(args)
console.log.apply(console, args) return search? (location.search = search): (location.href = location.href.split(ice.QS)[0])
}, },
Debug: function() { SearchHash: function(can) { var hash = location.hash
var args = [this._time(), this.FileLine(2, 3), "debug"] if (arguments.length > 1) {
for (var i in arguments) { args.push(arguments[i]) } hash = can.core.List(arguments, function(item) {
args.push(this.fileLine(2, 3)) if (can.base.isArray(item)) { return item.join(nfs.DF) }
console.log.apply(console, args) return can.base.replaceAll(item, ":", "%3A")
navigator.userAgent.indexOf("Mobile") > -1 && alert(JSON.stringify(args.join(ice.SP))) }).slice(1).join(nfs.DF)
}, if (can.isCmdMode() || can._name == "River" || can._name == "Action") { location.hash = hash }
FileLine: function(depth, length) { }
return this.fileLine(depth+1).split(ice.PS).slice(3).slice(-length).join(ice.PS).split(")")[0] return can.core.List(can.core.Split(can.base.trimPrefix(location.hash, "#"), nfs.DF)||[], function(item) { return decodeURIComponent(item) })
}, },
fileLine: function(depth) { SearchOrConf: function(can, key, def) { return can.misc.Search(can, key)||Volcanos.meta.args[key]||can.misc.sessionStorage(can, "can."+key)||can.misc.localStorage(can, "can."+key)||can.Conf(key)||def },
return (this._fileLine().split(ice.NL)[1+depth]||"").trim() CookieSessid: function(can, value, path) {
}, return can.misc.Cookie(can, ice.MSG_SESSID+"_"+(location.port||(location.protocol == "https:"? "443": "80")), value, path)||can.misc.Cookie(can, ice.MSG_SESSID, value, path)
_fileLine: function() { var obj = {} },
Error.captureStackTrace && Error.captureStackTrace(obj, arguments.callee) Cookie: function(can, key, value, path) {
return obj.stack || "" function set(k, v) { var expires = new Date(); expires.setTime(expires.getTime() + 30*24*3600000)
}, document.cookie = k+mdb.EQ+v+";path="+(path||nfs.PS)+";expires="+expires.toGMTString()
_time: function() { var now = new Date() }
var hour = now.getHours() if (can.base.isObject(key)) { for (var k in key) { set(k, key[k]) } key = undefined }
if (hour < 10) { hour = "0"+hour } if (can.base.isUndefined(key)) { var cs = {}; if (!document.cookie) { return } return document.cookie.split("; ").forEach(function(item) { var ls = item.split(mdb.EQ); cs[ls[0]] = ls[1] }), cs }
var minute = now.getMinutes() if (value === "") { var expires = new Date(); expires.setTime(expires.getTime() - 10)
if (minute < 10) { minute = "0"+minute } return document.cookie = key+mdb.EQ+value+";path="+(path||nfs.PS)+";expires="+expires.toGMTString()
var second = now.getSeconds() } can.base.isUndefined(value) || set(key, value)
if (second < 10) { second = "0"+second } var val = (new RegExp(key+"=([^;]*);?")).exec(document.cookie); return val && val.length > 1? val[1]: ""
return hour+":"+minute+":"+second },
}, sessionStorage: function(can, key, value) {
if (can.base.isUndefined(key)) { var res = {}; can.core.Item(sessionStorage, function(name, value) { can.base.isFunc(value) || name == "length" || (res[name] = value) }); return res }
if (can.base.isArray(key)) { key = key.join(":") }
if (!can.base.isUndefined(value)) {
if (value === "") { return sessionStorage.removeItem(key) } sessionStorage.setItem(key, value)
} return can.base.Obj(sessionStorage.getItem(key))||sessionStorage.getItem(key)
},
localStorage: function(can, key, value) {
if (can.base.isUndefined(key)) { var res = {}; can.core.Item(localStorage, function(name, value) { can.base.isFunc(value) || name == "length" || (res[name] = value) }); return res }
if (!can.base.isUndefined(value)) { if (value === "") { return localStorage.removeItem(key) } localStorage.setItem(key, value) } return can.base.Obj(localStorage.getItem(key))
},
Log: function() { var args = this._args("", arguments)
if (arguments[0].indexOf && arguments[0].indexOf("on") == 0) { args[1] = this.FileLine((arguments[0] == "onremote"? 1: 1)+this._skip) }
for (var i in arguments) { var arg = arguments[i]; if (arg && arg.Option && arg.Option("log.caller")) { args[1] = arg.Option("log.caller") } }
console.log.apply(console, args), this._signal(args)
},
Info: function() { var args = this._args(log.INFO, arguments); console.info.apply(console, args), this._signal(args) },
Warn: function() { var args = this._args(log.WARN, arguments); console.warn.apply(console, args), this._signal(args); },
Error: function() { var args = this._args(log.ERROR, arguments); args.push(lex.NL, this._stacks().slice(1).join(lex.NL)), console.error.apply(console, args), this._signal(args); debugger },
Debug: function() { var args = this._args(log.DEBUG, arguments); args.push(lex.NL, this._stacks().slice(1, 4).join(lex.NL)), console.debug.apply(console, args), this._signal(args) },
Trace: function() { var output = false
for (var i in arguments) { var arg = arguments[i]; if (arg.Conf && arg.Conf("log.trace") == ice.TRUE || arg.Option && arg.Option("log.trace") == ice.TRUE) { output = true } } if (!output) { return }
var args = this._args(log.TRACE, arguments); args.push(lex.NL, this._stacks().slice(1, 4).join(lex.NL)), console.debug.apply(console, args), this._signal(args)
},
FileLine: function(depth, length) { var file = this.fileLine(depth+1, length||9); return file.link },
fileLine: function(depth, length) { var list = this._stacks()
function split(i) { if (!list[i]) { return {} }
var ls = /(https*:\/\/[^/]+)*([^:]+):([0-9]+):([0-9]+)/.exec(list[i]); if (!ls) { return {} }
var name = ""; list[i].lastIndexOf(lex.TB) > 0 && (name = list[i].split(lex.TB).pop())
if (ls[0].indexOf(ice.QS) > -1) { ls[0] = ls[0].split(ice.QS)[0]+nfs.DF+ls[3]+nfs.DF+ls[4] }
return {name: name, link: ls[0], path: ls[2], file: ls[2].split(nfs.PS).slice(-length).join(nfs.PS), line: ls[3], cols: ls[4]}
}
if (depth < 0) { var current = split(-depth)
for (var i = -depth+1; i < list.length; i++) { var pos = split(i); if (pos.path != current.path) { return pos } }
} return split(depth)||{}
},
_stacks: function(n, s) { var list = ((s||(new Error())).stack||"").split(lex.NL).slice(typeof n == "undefined"? 2: n)
for (var i = 0; i < list.length; i++) { var ls = list[i].trim().split(lex.SP)
list[i] = ls.pop().trim()
if (list[i][0] == "(") { list[i] = list[i].slice(1, -1) } // ")"
list[i] = " "+list[i]; if (ls.length > 1) { list[i] += " "+ls.pop() }
list[i] = list[i].replace(/\?[^:]+/, "").replace(location.origin, "")
} return list
}, _stack: function() { return ((new Error()).stack||"").split(lex.NL).slice(2) },
_time: function() { var now = new Date()
var hour = now.getHours(); hour < 10 && (hour = "0"+hour)
var minute = now.getMinutes(); minute < 10 && (minute = "0"+minute)
var second = now.getSeconds(); second < 10 && (second = "0"+second)
var mill = now.getMilliseconds(); mill < 10 && (mill = "00"+mill) || mill < 100 && (mill = "0"+mill)
return [hour, minute, second].join(nfs.DF)+nfs.PT+mill
},
_args: function(level, arg) { var args = [this._time(), this.FileLine(this._skip+1, 3)].concat(level? [level]: [])
for (var i in arg) { arg[i] != undefined && args.push(arg[i]) } return args
},
_signal: function(args) { this._list.push(args) }, _list: [], _skip: navigator && navigator.userAgent.indexOf("Chrome") > -1? 3: 3,
}) })

View File

@ -1,358 +1,526 @@
Volcanos("page", {help: "用户界面", ClassList: { Volcanos("page", {
has: function(can, obj, key) { var list = obj.className? obj.className.split(ice.SP): [] ClassList: {
return list.indexOf(key) > -1 has: function(can, target, key) { var list = target.className && target.className.split? target.className.split(lex.SP): []; return list.indexOf(key) > -1 },
}, add: function(can, target, key) { Array.isArray(key) && (key = key.join(lex.SP))
add: function(can, obj, key) { var list = obj.className? obj.className.split(ice.SP): [] var list = target.className? target.className.split(lex.SP): []; can.core.List(can.core.Split(key, " .,"), function(key) { can.base.AddUniq(list, key) })
var value = can.base.AddUniq(list, key).join(ice.SP).trim() var value = list.join(lex.SP).trim(); return value != target.className && (target.className = value), value
return value != obj.className && (obj.className = value), value },
}, del: function(can, target, key) { var list = target.className? target.className.split(lex.SP): []
del: function(can, obj, key) { var list = obj.className? obj.className.split(ice.SP): [] return target.className = can.core.List(list, function(value) { return value == key? undefined: value }).join(lex.SP).trim()
return obj.className = can.core.List(list, function(value) { },
return value == key? undefined: value set: function(can, target, key, condition) {
}).join(ice.SP).trim() return (condition? this.add(can, target, key): this.del(can, target, key)).indexOf(key) > -1 },
}, neg: function(can, target, key) { return (this.has(can, target, key)? this.del(can, target, key): this.add(can, target, key)).indexOf(key) > -1 },
set: function(can, obj, key, condition) { tag: function(can, target) { return [document.body.tagName.toLowerCase()].concat(document.body.classList).join(lex.PT) }
condition? this.add(can, obj, key): this.del(can, obj, key) },
}, SelectArgs: function(can, target, key, cb) {
neg: function(can, obj, key) { if (can.base.isUndefined(target)) { return can.page.SelectArgs(can, can._option, "").concat(can.page.SelectArgs(can, can._action, "")) }
return (this.has(can, obj, key)? this.del(can, obj, key): this.add(can, obj, key)).indexOf > -1 // if (can.base.isUndefined(key)) { var value = {}; can.page.SelectArgs(can, target, "", function(item) { item.name && item.value && (value[item.name] = item.value) }); return [value] }
}, if (can.base.isUndefined(key)) { var value = {}; can.page.SelectArgs(can, target, "", function(item) { item.name && (value[item.name] = item.value||"") }); return [value] }
}, if (can.base.isObject(key)) { return can.core.Item(key, function(key, value) { can.page.SelectArgs(can, target, key, value) }), [key] }
SelectArgs: function(can, option, key, cb) { if (!can.base.isFunc(cb)) { var value = cb; cb = function(target) {
if (can.base.isUndefined(key)) { var value = {} can.base.isUndefined(value) || can.page.Select(can, target.parentNode, "span.value", function(target) { target.innerText = value })
can.page.SelectArgs(can, option, "", function(item) { return target.name && (can.base.isUndefined(value)? target.value: (target.value = value))||""
item.name && item.value && (value[item.name] = item.value) } }
}); return [value] if (key.indexOf(nfs.PT) > -1) { return [""] } key && can.base.isString(cb) && can.page.Select(can, target, "div.item."+key+">span.value", cb)
} return can.page.Select(can, target, key? "select[name="+key+"],"+"input.select[type=button][name="+key+"],"+"input[type=text][name="+key+"],"+"textarea[name="+key+"]": ".args", cb)
if (can.base.isObject(key)) { },
return can.core.Item(key, function(key, value) { can.page.SelectArgs(can, option, key, value) }), [key] SelectInput: function(can, target, name, cb) { return can.page.Select(can, target, "input[name="+name+"]", cb)[0] },
} SelectChild: function(can, target, key, cb) { return can.core.List(can.page.Select(can, target, key||"*", function(node) { if (node.parentNode == target) { return node } }), cb) },
if (!can.base.isFunc(cb)) { var value = cb; cb = function(item) { if (item.type == html.BUTTON) { return } SelectOne: function(can, target, key, cb) { return can.page.Select(can, target, key, function(target, index) { return index == 0 && can.base.isFunc(cb) && cb(target), target })[0] },
return item.name && (can.base.isUndefined(value)? item.value: (item.value = value))||"" Select: function(can, target, key, cb, interval, cbs) { target = target || document.body, key = key||"*"
} } return can.core.List(key == nfs.PT? [target]: target.querySelectorAll(can.page.Keys(key)), cb, interval, cbs)
if (key.indexOf(ice.PT) > -1) { return [""]} },
return can.page.Select(can, option, key? "textarea[name="+key+"],"+"input[name="+key+"],"+"select[name="+key+"]": ".args", cb) Modify: function(can, target, value) { target = can.base.isString(target)? document.querySelector(target): target; if (!target) { return }
}, can.base.isString(value)? (target.innerHTML = value): can.core.Item(value, function(key, val) { if (key == "view") { return }
SelectAll: shy("选择节点", function(can, target, key, cb, interval, cbs) { key == "className" && can.base.isArray(val) && (val = val.join(lex.SP)), !can.base.isObject(val)? (target[key] = val): can.core.Item(val, function(k, v) {
can.page.Select(can, target, html.IFRAME, function(item) { if (can.base.isIn(k, "height", "width", "min-height", "max-height", "min-width", "max-width") && parseInt(v) < 0) { return target[key] && (target[key][k] = "") }
can.page.SelectAll(can, item.contentWindow.document.body, key, cb, interval, cbs) if (can.base.isIn(k, "height", "width", "min-height", "max-height", "min-width", "max-width", "left", "top", "right", "bottom", "margin-left", "margin-top", "margin", "padding", "font-size") && v && (can.base.isNumber(v) || !can.base.endWith(v, "px"))) { v += "px" }
}) target[key] && (target[key][k] = v)
return can.core.List(target && target.querySelectorAll(key), cb, interval, cbs) })
}), }); return target
Select: shy("选择节点", function(can, target, key, cb, interval, cbs) { if (key == ice.PT) { cb(target); return [] } },
return can.core.List(target && target.querySelectorAll(key), cb, interval, cbs) Create: function(can, key, value) { return can.page.Modify(can, document.createElement(key), value) },
}), Remove: function(can, target) { return target && target.parentNode && target.parentNode.removeChild(target), target },
Modify: shy("修改节点", function(can, target, value) { target = target||{} Append: function(can, target, key, value) { if (can.base.isString(key)) { var res = can.page.Create(can, key, value); return target.appendChild(res), res }
target = can.base.isObject(target)? target: document.querySelector(target) value = value||{}, can.core.List(key, function(item) { if (!item) { return } if (item.nodeName) { target.appendChild(item); return }
can.base.isString(value)? (target.innerHTML = value): can.core.Item(value, function(key, val) { if (can.base.isString(item)) { item = {view: [item]} }
!can.base.isObject(val)? (target[key] = val): can.core.Item(val, function(k, v) { var type = item.type||html.DIV, data = item.data||{}, name = item.name||data.name||""; data.className = data.className||""
var size = { can.core.Item(item, function(key, value) { switch (key) {
"height": true, "max-height": true, "min-height": true, case mdb.TYPE: break
"width": true, "max-width": true, "min-width": true, case mdb.NAME: break
} case mdb.DATA: break
if (size[k] && parseInt(v) < 0) { return target[key] && (target[key][k] = "") } case mdb.LIST: break
case html.CLICK: data.onclick = item.click; break
case html.INNER: data.innerHTML = item.inner; break
default: can.base.isUndefined(item[key]) || (data[key] = item[key])
} })
if (item.view) { var list = can.core.List(item.view); if (can.base.isArray(list[0])) {
list[0] = can.base.replaceAll(can.core.List(list[0], function(v) { return v }).join(lex.SP), ".", " ")
}
list[0] && can.page.ClassList.add(can, data, list[0]), type = list[1]||type, data.innerHTML = list[2]||data.innerHTML||"", name = list[3]||name
} else if (item.text) { var list = can.core.List(item.text); if (can.base.isArray(list[2])) { list[2] = list[2].join(lex.SP) }
data.innerHTML = list[0]||data.innerHTML||"", type = list[1]||item.type||html.SPAN, list[2] && can.page.ClassList.add(can, data, list[2])
} else if (item.icon) { var list = can.core.List(item.icon)
if (icon[item.icon]) {
type = "i", data.className = icon[item.icon]
} else if (can.page.unicode[list[0]]) {
type = html.SPAN, name = list[0], data.className = "icon "+list[0], data.innerText = can.page.unicode[list[0]]
} else {
type = "i", data.className = list[0]
}
} else if (item.button) { var list = can.core.List(item.button); type = html.BUTTON, name = list[0]||name, data.innerText = can.user.trans(can, name)
data.onclick = function(event) { can.misc.Event(event, can, function(msg) { can.base.isFunc(list[1]) && list[1](event, name), can.onkeymap.prevent(event) }) }
} else if (item.select) { var list = item.select; type = html.SELECT, name = list[0][0], data.className = data.className||list[0][0]
data.onchange = function(event) { can.misc.Event(event, can, function(msg) { can.base.isFunc(list[1]) && list[1](event, event.target.value, name) }) }
item.list = list[0].slice(1).map(function(value) { return {type: html.OPTION, value: value, inner: can.user.trans(can, value)} })
} else if (item.input) { var list = can.core.List(item.input); type = html.INPUT, name = list[0], data.className = data.className||list[0], data.type = data.type||html.TEXT
data.onkeydown = function(event) { can.base.isFunc(list[1]) && list[1](event) }
data.onkeyup = function(event) { can.base.isFunc(list[2]) && list[2](event) }
} else if (item.username) { var list = can.core.List(item.username); type = html.INPUT, name = list[0]||name||html.USERNAME
// data.className = list[1]||data.className||name, data.autocomplete = data.autocomplete||html.USERNAME
data.className = list[1]||data.className||name
} else if (item.password) { var list = can.core.List(item.password); type = html.INPUT, name = list[0]||name||html.PASSWORD
// data.className = list[1]||data.className||name, data.type = html.PASSWORD, data.autocomplete = data.autocomplete||"current-password"
data.className = list[1]||data.className||name, data.type = html.PASSWORD
} else if (item.img) {
var list = can.core.List(item.img); type = html.IMG, data.src = list[0]
if (can.base.contains(data.src, ".jpg")) { data.className = data.className||"jpg" }
} else if (item.row) { type = html.TR, item.list = item.row.map(function(text) { return {text: [text, item.sub||html.TD]} })
} else if (item.th) { type = html.TR, item.list = item.th.map(function(text) { return {text: [text, html.TH]} })
} else if (item.td) { type = html.TR, item.list = item.td.map(function(text) { return can.base.isObject(text)? text: {text: [text||"", html.TD]} }) }
// if (type == html.SELECT) { data.title = can.user.trans(can, data.title||name) }
if (type == html.INPUT) {
if (data.type == html.TEXT || data.type == html.PASSWORD || !data.type) {
// data.autocomplete = data.autocomplete||"new-password"
if (!can.user.isMobile) {
data.placeholder = (data.placeholder||name||"").split(nfs.PT).pop(), data.title = can.user.trans(can, data.title||data.placeholder, null, html.INPUT)
}
} else if (data.type == html.BUTTON) {
// data.value = can.user.trans(can, data.value)
}
}
if (type == html.TEXTAREA) {
if (!can.user.isMobile) {
data.placeholder = can.user.trans(can, (data.placeholder||name||"").split(nfs.PT).pop(), null, html.INPUT)
}
}
can.core.List(["className", "placeholder", "title"], function(key) { data[key] || delete(data[key]) })
name && (data.name = name); var node = can.page.Create(can, type, data)
value[data.type] = node
value[type] = value[name] = value[can.core.Split(data.className)[0]] = node, value._target = value._target||node, value.first = value.first||node, value.last = node
item.list && can.page.Append(can, node, item.list, value), target && target.appendChild && target.appendChild(node), can.base.isFunc(item._init) && item._init(node, value)
}); return value },
Appends: function(can, target, key, value) { return target.innerHTML = "", can.page.Append(can, target, key, value) },
AppendData: function(can, target, prefix, key, value, cb) { var open = can.page.unicode.opens, close = can.page.unicode.closes
function short(value, length) {
if (length == undefined) {
value.indexOf(lex.NL) > -1 && (value = value.trim().split(lex.NL)[0]+can.page.unicode.inner)
return can.page.trans(can, value)
} else {
if (length > 5) {
return can.page.unicode.inner
}
} return value
}
function show(value, deep) { deep = deep == undefined? 2: 0; switch (typeof value) {
case code.OBJECT: if (!value) { return {} }
if (value._path) { return {value: "@\""+value._path+"\""} }
if (value.tagName) { return {type: nfs.TARGET, value: "$"+value.tagName.toLowerCase()+(value.className? nfs.PT+value.className.replaceAll(lex.SP, nfs.PT):"")} }
if (deep < 0) { return {value: value.length == undefined? "{"+can.page.unicode.inner+"}": "["+can.page.unicode.inner+"]"} }
if (value.length != undefined) { return {value: (value.length > 3? value.length+lex.SP: "")+"["+can.core.List(value, function(value, index) { if (index < 6) { return short(show(value, deep-1).value, index+1) } }).join(mdb.FS)+"]"} }
return {value: "{"+can.core.Item(value, function(key, val, list) { if (value.hasOwnProperty(key) && val && list.length < 7) { return short(key+nfs.DF+show(val, deep-1).value, list.length) } }).join(mdb.FS)+"}"}
case code.STRING: return {open: "s", close: "s", value: "\""+(deep == 2? value.replaceAll("\n", "\\n"): short(value))+"\""}
case code.NUMBER: return {open: "n", close: "n", value: value}
case code.BOOLEAN: return {open: "b", close: "b", value: value}
case code.FUNCTION: return {open: "f", close: "f", value: deep == 2? (""+value).split(lex.NL)[0]: "function(...) {...}"}
default: return {value: value}
} } var loaded = false, _show = show(value); _show.open = _show.open||open, _show.close = _show.close||close
var ui = can.page.Append(can, target, [!key && value.tagName? can.page.AppendView(can, value): {view: [[html.ITEM, _show.type||typeof(value)], key == ""? html.SPAN: html.DIV], list: [
{view: [mdb.ICON, html.SPAN, _show.close+lex.SP]}, {view: [mdb.NAME, html.SPAN, key || key === 0? key+lex.SP: ""]}, {view: [mdb.VALUE, html.SPAN, _show.value]},
], onclick: function() {
cb && cb(prefix, value); if (!can.base.isIn(typeof value, code.OBJECT, code.FUNCTION)) { return }
ui.icon.innerText = (can.onmotion.toggle(can, ui.list)? _show.open: _show.close)+lex.SP
if (typeof value == code.FUNCTION) { return ui.list.innerText = value.toString() }
var size = { if (loaded) { return } loaded = true, ui.icon.innerText = _show.open+lex.SP
"margin-top": true, "margin-left": true, "font-size": true, if (value.tagName) { can.page.Append(can, ui.list, [can.page.AppendView(can, value)]), can.onappend.style(can, mdb.VIEW, ui.list)
"left": true, "right": true, "top": true, "bottom": true, can.core.List(can.core.Item(target, function(key, value) { if (["textContent", "innerHTML", "outerHTML"].indexOf(key) > -1 || typeof value == code.FUNCTION || key.toUpperCase() == key) { return } return key }).sort(), function(key) {
"height": true, "max-height": true, "min-height": true, target[key] && can.page.AppendData(can, ui.list, can.core.Keys(prefix, key), key, target[key], cb)
"width": true, "max-width": true, "min-width": true, })
} } else if (value.length != undefined) {
can.core.List(value, function(value, index) { can.page.AppendData(can, ui.list, can.core.Keys(prefix, index), index, value, cb) })
} else {
can.core.List(can.core.Item(value, function(key, val) { if (
(value["preventDefault"] && val && typeof val != code.FUNCTION) || (value["responseText"] && val && typeof val != code.FUNCTION) ||
value.hasOwnProperty(key) && val) { return key } }).sort(), function(key) { can.page.AppendData(can, ui.list, can.core.Keys(prefix, key), key, value[key], cb) })
var key = "__proto__"; value[key] && can.core.Item(value[key]).length > 0 && can.page.AppendData(can, ui.list, can.core.Keys(prefix, key), key, value[key], cb)
}
}}, {view: [[html.LIST, _show.type||typeof(value), html.HIDE]]}]); return ui
},
AppendView: function(can, target, tag, list, loaded, cb) {
function field(target) { return target? can.core.List(target.attributes, function(item) {
return item.value == ""? undefined: {type: html.SPAN, list: [{text: lex.SP}, {text: item.name}, {text: mdb.EQ}, {className: code.STRING, text: JSON.stringify(item.value)}]}
}): [] }
var ui = {}; tag = tag||target.tagName.toLowerCase(), isclose = tag != mdb.META && tag != web.LINK, _field = field(target)
var inner = list || target.children.length > 0 && target.innerText != target.innerHTML? can.page.unicode.inner: ""
return {view: mdb.VIEW, list: [
{view: [[html.ITEM, target.tagName && target.tagName.toLowerCase()]], list: [
{text: [(inner? can.page.unicode.closes: ""), "", html.TOGGLE], _init: function(target) { ui.toggle = target }},
{className: code.KEYWORD, text: can.page.trans(can, ice.LT)}, {className: code.KEYWORD, text: tag}, {type: html.SPAN, list: _field}, {className: code.KEYWORD, text: can.page.trans(can, ice.GT)},
inner? {text: [inner, "", code.INNER], _init: function(target) { ui.inner = target }}:
target.innerText? {text: target.innerText, _init: function(target) { ui.inner = target }}:
null,
{className: code.KEYWORD, text: can.page.trans(can, ice.LT+nfs.PS+tag+ice.GT), _init: function(target) { ui._close = target }},
], onclick: inner && function(event) {
ui.toggle.innerText = (can.onmotion.toggle(can, ui.list)? can.page.unicode.opens: can.page.unicode.closes)+lex.SP
if (target.children.length == 0 && !list) { return }
ui.inner && can.onmotion.toggle(can, ui.inner), can.onmotion.toggle(can, ui.close), can.onmotion.toggle(can, ui._close)
if (!loaded) { if (can.page.tagis(target, ctx.STYLE, nfs.SCRIPT)) { can.page.Append(can, ui.list, [{text: target.innerHTML}]) } else {
can.page.Append(can, ui.list, can.core.List(target.children, function(node) { return can.page.AppendView(can, node, "", null, false, cb) }))
} } loaded = true, can.base.isFunc(cb) && cb(target)
}, onmouseenter: function() { can.page.Select(can, document.body, nfs.PT+html.PICKER, function(target) { can.page.ClassList.del(can, target, html.PICKER) })
!can.page.tagis(target, nfs.SCRIPT) && can.onappend.style(can, html.PICKER, target)
}, _init: function(target) { can.onmotion.delay(can, function() { loaded && target.click() }) }},
inner && {view: [[html.LIST, html.HIDE]], _init: function(target) { ui.list = target }, list: list},
inner && {view: [[html.ITEM, html.HIDE]], list: [{text: ["", "", html.TOGGLE]}, {className: code.KEYWORD, text: can.page.trans(can, ice.LT+nfs.PS+tag+ice.GT)}], _init: function(target) { ui.close = target }},
]}
},
AppendStyle: function(can, style) {
var styleElement = document.createElement('style'); styleElement.type = 'text/css'
document.getElementsByTagName('head')[0].appendChild(styleElement)
styleElement.appendChild(document.createTextNode(style))
},
AppendTable: function(can, msg, target, list, cb) { if (!msg.append||msg.append.length == 0) { return }
var ui = can.page.Append(can, target, [{type: html.TABLE, list: [
{type: "colgroup", list: can.core.List(list, function(key) { if (key[0] != "_") {
try { var value = can.Option(key) } catch (e) {}
if (value == undefined) { return {view: [key, "col"]} } return {view: [[key, "option"], "col"]}
} }) }, {type: html.THEAD}, {type: html.TBODY},
]}])
var option = can.core.Item(can.Option())
can.page.Append(can, ui.thead, [{type: html.TR, data: {dataset: {index: -1}}, list: can.core.List(list, function(key) {
if (key[0] != "_") { return {className: option.indexOf(key) > -1? ice.MSG_OPTION: key == ctx.ACTION? ctx.ACTION: "", type: html.TH, list: [{text: can.user.trans(can, key, null, html.INPUT)}, {icon: "bi bi-sort-down-alt"}, {icon: "bi bi-sort-up"}]} }
}) }])
can.page.Append(can, ui.tbody, can.core.List(msg.Table(), function(item, index, array) {
return {dataset: {index: index}, className: item[mdb.STATUS], td: can.core.List(list, function(key) { if (key[0] != "_") { return cb(can.page.Color(item[key]).trim(), key, index, item, array) } }) }
}))
if (msg.Option(ice.TABLE_CHECKBOX) == ice.TRUE && !msg.IsDetail()) { can.onappend.checkbox(can, ui._target, msg), can.onappend.style(can, html.CHECKBOX, ui._target) }
return can.page.OrderTable(can, ui._target)
},
OrderTable: function(can, table) { can.page.Select(can, table, html.TH, function(th, index) { th.onclick = function(event) {
var dataset = event.currentTarget.dataset
can.onmotion.select(can, th.parentNode, html.TH, th)
can.page.RangeTable(can, table, index, (dataset["asc"] = (dataset["asc"] == "1") ? 0: 1) == "1")
} }); return table },
RangeTable: function(can, table, index, asc) { index = can.base.isArray(index)? can.core.List(index, function(item) { if (item > -1) { return item } }): [index]; if (index.length == 0) { return }
var list = can.page.Select(can, table, html.TR, function(tr) { if (can.page.isDisplay(tr)) { return tr } }).slice(1)
var is_time = true, is_number = true; can.core.List(list, function(tr) { var text = tr.childNodes[index[0]].innerHTML;
is_time = is_time && Date.parse(text) > 0, is_number = is_number && !isNaN(parseFloat(text||"0"))
})
var num_list = can.core.List(list, function(tr) { var text = tr.childNodes[index[0]].innerHTML; return is_time? Date.parse(text): is_number? can.base.ParseSize(text)||0: text })
function less(a, b) {
if (can.base.endWith(a, nfs.PS) && !can.base.endWith(b, nfs.PS)) { return true }
if (!can.base.endWith(a, nfs.PS) && can.base.endWith(b, nfs.PS)) { return false }
return a < b
}
function isless(a, b, index) { if (a.childNodes[index[0]] && b.childNodes[index[0]]) {
if (a.childNodes[index[0]].innerHTML < b.childNodes[index[0]].innerHTML) { return true }
if (a.childNodes[index[0]].innerHTML > b.childNodes[index[0]].innerHTML) { return false }
} return index.length > 1 && isless(a, b, index.slice(1)) }
for (var i = 0; i < num_list.length; i++) { var min = i
for (var j = i+1; j < num_list.length; j++) {
if (asc? less(num_list[min], num_list[j]): less(num_list[j], num_list[min])) { min = j; continue }
if (num_list[min] == num_list[j] && index.length > 1) { if (asc? isless(list[min], list[j], index.slice(1)): isless(list[j], list[min], index.slice(1))) { min = j } }
}
if (min != i) {
var temp = num_list[i]; num_list[i] = num_list[min]; num_list[min] = temp
var temp = list[i]; list[i] = list[min]; list[min] = temp
}
var tbody = list[i].parentElement; list[i].parentElement && tbody.removeChild(list[i]), tbody.appendChild(list[i])
}
},
Format: function(type) { var arg = arguments; switch (type) {
case html.A: return `<a href="${arg[1]}" target="_blank">${arg[2]||arg[1]}</a>`
case html.IMG: return arg[3]? `<img src="${arg[1]}" height="${arg[2]}" width=${arg[3]}>`: arg[2]? `<img src="${arg[1]}" height="${arg[2]}">`: `<img src="${arg[1]}">`
case html.SPAN: arg[2] && typeof arg[2] == code.OBJECT && arg[2].join && (arg[2] = arg[2].join(lex.SP))
return arg[2]? `<span class="${arg[2]}">${arg[1]}</span>`: arg[1]
default: /* type inner arg... */
var list = ["<"+type]; for (var i = 2; i < arg.length; i += 2) { list.push(lex.SP+arg[i]+mdb.EQ+arg[i+1]) }
return list.concat(">", arg[1], "</", type, ">").join("")
} },
ColorList: [
"#8085e9",
"#95a2ff",
"#73abf5",
"#3cb9fc",
"#0082fc",
"#87e885",
"#90ed7d",
"#22ed7c",
"#05f8d6",
"#cb9bff",
"#bf19ff",
"#f47a75",
"#fa8080",
"#f7a35c",
"#ffc076",
"#f9e264",
"#fae768",
"#5f45ff",
"#02cdff",
"#0090ff",
"#854cff",
"#09b0d3",
"#1d27c9",
"#765005",
"#314976",
"#009db2",
"#024b51",
"#0780cf",
],
Color: function(text) { if (typeof text != code.STRING) { return "" } text = text.replace(/\\n/g, "<br>")
if (text.indexOf(ice.HTTP) == 0 && text.length > 10) { var ls = text.split(lex.SP); text = "<a href='"+ls[0]+"' target='_blank'>"+decodeURI(ls[0])+"</a>"+ls.slice(1).join(lex.SP) }
if (text.indexOf("export ctx_dev=") == 0 && text.length > 10) {
return "<div class='story' data-type='spark' data-name='shell'><div>"+"<span>"+text+"</span>"+"</div></div>"
} if (text.indexOf("\033\[") == -1) { return text }
text = text.replace(/\033\[41m/g, "<span style='background-color:#f00'>")
text = text.replace(/\033\[31m/g, "<span style='color:#f00'>")
text = text.replace(/\033\[32m/g, "<span style='color:#0f0'>")
text = text.replace(/\033\[33m/g, "<span style='color:#ff0'>")
text = text.replace(/\033\[34m/g, "<span style='color:#00f'>")
text = text.replace(/\033\[36m/g, "<span style='color:#0ff'>")
text = text.replace(/\033\[37m/g, "<span style='color:gray'>")
text = text.replace(/\033\[34;1m/g, "<span style='color:#00f'>")
text = text.replace(/\033\[37;1m/g, "<span style='color:#fff'>")
text = text.replace(/\033\[1m/g, "<span style='font-weight:bold'>")
text = text.replace(/\033\[0m/g, "</span>")
text = text.replace(/\033\[m/g, "</span>")
return text // }
},
Keys: function() { var list = []; /* FS SP GT PT */ for (var i = 0; i < arguments.length; i++) { var v = arguments[i]; if (typeof v == code.OBJECT) {
for (var j = 0; j < v.length; j++) { if (typeof v[j] == code.OBJECT) {
for (var k = 0; k < v[j].length; k++) { if (typeof v[j][k] == code.OBJECT) { v[j][k] = v[j][k].join(nfs.PT) } }
v[j] = v[j].join(ice.GT)
} } list.push(v.join(lex.SP))
} else { list.push(v+"") } } return list.join(mdb.FS) },
Cache: function(name, output, data) { if (!name) { return } var cache = output._cache||{}; output._cache = cache
if (data) { if (output.children.length == 0) { return } var temp = document.createDocumentFragment()
while (output.childNodes.length > 0) { var item = output.childNodes[0]; item.parentNode.removeChild(item), temp.appendChild(item) }
return cache[name] = {node: temp, data: data}, name
} output.innerHTML = ""; var list = cache[name]; if (!list) { return }
while (list.node.childNodes.length > 0) { var item = list.node.childNodes[0]; item.parentNode.removeChild(item), output.appendChild(item) }
return delete(cache[name]), list.data
},
parentNode: function(can, target, tag) {
for (target; target; target = target.parentNode) {
if (can.page.tagis(target, tag)) { return target }
}
},
insertBefore: function(can, target, before, parent) {
if (typeof before == code.STRING) { before = can.page.SelectOne(can, parent, before) }
parent = parent||before.parentNode
if (can.base.isArray(target)) {
return can.core.List(target, function(item) { if (!item) { return }
var target = can.page.Append(can, parent, [item])._target
return parent.insertBefore(target, before), target
})[0]
} return before && parent.insertBefore(target, before), target
},
styleHeight: function(can, target, value) { return can.page.style(can, target, html.HEIGHT, value), target.offsetHeight },
styleWidth: function(can, target, value) { return can.page.style(can, target, html.WIDTH, value), target.offsetWidth },
styleClass: function(can, target, value) { return can.page.Modify(can, target, {className: value}), target.className },
style: function(can, target, style) { var value = {}; for (var i = 2; i < arguments.length; i += 2) {
if (typeof arguments[i] == code.OBJECT) { can.page.Modify(can, target, {style: arguments[i--]}) } else { value[arguments[i]] = arguments[i+1] }
} return can.page.Modify(can, target, {style: value}), value },
tagis: function(target) { if (!target || !target.tagName) { return }
function isin(ls, list) {
for (var i = 0; i < ls.length; i++) { var has = false
for (var j = 0; j < list.length; j++) { if (ls[i] == list[j]) { has = true } }
if (!has) { return false }
} return true
}
var type = target.tagName.toLowerCase(); for (var i = 1; i < arguments.length; i++) {
var ls = arguments[i].split("."); if (type != ls[0]) { continue }
if (isin(ls.slice(1), target.classList)) { return true }
}
},
tagClass: function(target) { return target.tagName.toLowerCase()+(target.className? nfs.PT+target.className.replaceAll(lex.SP, nfs.PT): "") },
isDark: function(can) {
return can.page.tagis(document.body, "body.dark")
},
isDisplay: function(target) { return target && target.style.display != html.NONE && target.className.indexOf(html.HIDE) == -1 },
isSelect: function(target) { return target && target.className.indexOf(html.SELECT) > -1 },
isIconInput: function(can, name) {
return can.base.isIn(name, mdb.CREATE, mdb.INSERT, mdb.PRUNES, mdb.PRUNE, ice.HELP, cli.START, cli.CLOSE, web.REFRESH) || icon[name] || can.Conf("feature._icons."+name) || can.core.Value(can.onaction, ["_trans.icons", name])
},
editable: function(can, item, ok) { item.setAttribute("contenteditable", ok) },
draggable: function(can, item, ok) { item.setAttribute("draggable", ok) },
height: function() { return window.innerHeight },
width: function() { return window.innerWidth },
ismodkey: function(event) { return [code.META, code.ALT, code.CONTROL, code.SHIFT].indexOf(event.key) > -1 },
unicode: { // https://symbl.cc/cn/
refresh: "↻",
goback: "↺", play: "▶", create: "+", insert: "+", prunes: "♻︎", prune: "♻︎",
select: "▿", remove: "✕", delete: "✕", close: "✕",
menu: "☰",
opens: "▾", closes: "▸",
prev: "", next: "",
if (size[k] && v && (can.base.isNumber(v) || v.indexOf && v.indexOf("px") == -1)) { start: "+", // play: "▸",
v += "px" back: "◀", reback: "▶",
} push: "⇈", pull: "⇊",
target[key] && (target[key][k] = v) lt: "", gt: "",
}) inner: "...",
}) favor: "\u2606",
return target help: "\u2753",
}), },
Remove: shy("删除节点", function(can, target) { inputs: function(can, list, type) {
target && target.parentNode && target.parentNode.removeChild(target) var _list = []; for (var i = 0; i < list.length; i++) {
}), switch (list[i]) {
Create: shy("创建节点", function(can, key, value) { case "": _list.push(""); break
return can.page.Modify(can, document.createElement(key), value) case ice.AUTO:
}), _list.push({type: html.BUTTON, name: ice.LIST})
Append: shy("添加节点", function(can, target, key, value) { value = value||{} _list.push({type: html.BUTTON, name: ice.BACK})
if (can.base.isString(key)) { var res = can.page.Create(can, key, value); return target.appendChild(res), res } break
case web.FILTER:
can.core.List(key, function(item, index) { if (!item) { return } _list.push({type: html.TEXT, name: web.FILTER, icon: icon.search})
if (can.base.isString(item)) { target.innerHTML = item; return } break
if (item.nodeName) { target.appendChild(item); return } case mdb.PAGE:
_list.push({type: html.TEXT, name: mdb.OFFEND, value: can._msg.Option(mdb.OFFEND)})
// 基本结构: type name data list _list.push({type: html.TEXT, name: mdb.LIMIT, value: can._msg.Option(mdb.LIMIT), _init: function(target) {
var type = item.type||html.DIV, data = item.data||{} can.onappend.figure(can, {action: "key", run: function(event, cmds, cb) {
var name = item.name||data.name||"" var msg = can.request(event)
msg.Push(cmds[1], "10")
// 数据调整 msg.Push(cmds[1], "30")
can.core.Item(item, function(key, value) { msg.Push(cmds[1], "50")
switch (key) { msg.Push(cmds[1], "100")
case mdb.TYPE: break cb(msg)
case mdb.NAME: break }}, target, function() { can.Update() })
case mdb.DATA: break }})
case mdb.LIST: break _list.push(mdb.NEXT, mdb.PREV)
case html.INNER: data.innerHTML = item.inner; break break
case html.CLICK: data.onclick = item.click; break default: (function() { var item = can.core.SplitInput(list[i], type||html.BUTTON)
default: data[key] = item[key] if (item.type == html.SELECT) {
} item._init = function(target) { target.value = item.value||item.values[0]
}) target.onchange = function(event) { can.misc.Event(event, can, function(msg) { can.run(event) }) }
}
// 基本类型: view text button select input username password }
// 基本类型: img row th td item.action && (function() { item._init = function(target) {
if (item.view) { var list = can.core.List(item.view) can.onappend.figure(can, item, target, function() { can.Update({}, ) })
list.length > 0 && list[0] && can.page.ClassList.add(can, data, list[0]) } })()
type = list[1]||html.DIV _list.push(item), type = item.type
data.innerHTML = list[2]||data.innerHTML||"" })()
name = name||list[3]||"" }
}
} else if (item.text) { var list = can.core.List(item.text) return _list
data.innerHTML = list[0]||data.innerHTML||"" },
type = list[1]||html.SPAN button: function(can, name, cb) {
list[2] && can.page.ClassList.add(can, data, list[2]) var icon = can.Conf("_icons."+name)
if (icon) { return {icon: icon, onclick: cb||function(event) { can.Update(event, [ctx.ACTION, name]) }} }
} else if (item.button) { var list = can.core.List(item.button) return {view: [["item.button"]], list: [
type = html.BUTTON, name = name||list[0] {type: html.INPUT, data: {type: html.BUTTON, name: name, value: can.user.trans(can, name)}, onclick: cb||function(event) { can.Update(event, [ctx.ACTION, name]) }},
data.innerText = can.user.trans(can, list[0]), data.onclick = function(event) { {text: name},
can.base.isFunction(list[1]) && list[1](event, name) ]}
event.stopPropagation(), event.preventDefault() },
return true input: function(can, item, value) { var input = {type: html.INPUT, name: item.name, data: item, style: item.style||{}, dataset: {}, _init: item._init}
} item.value == ice.AUTO && (item.value = "", item.action = ice.AUTO), item.action == ice.AUTO && (input.dataset.action = ice.AUTO)
switch (item.type = item.type||html.TEXT) {
} else if (item.select) { var list = item.select case html.SELECT: input.type = html.SELECT, item.className||can.page.ClassList.add(can, item, ctx.ARGS)
type = html.SELECT, data.name = name = name||list[0][0] item.values = can.base.isString(item.values)? can.core.Split(item.values): item.values
data.title = can.user.trans(can, data.title||name) if (!item.values && item.value) { item.values = can.core.Split(item.value), item.value = item.values[0] }
data.className = data.className||list[0][0]||"" if (item.values.slice(1).indexOf(item.values[0]) > -1) { item.value = item.value||item.values[0], item.values = item.values.slice(1) }
item.value = value||item.value, input.list = item.values.map(function(value) {
item.list = list[0].slice(1).map(function(value) { return {type: html.OPTION, value: value, inner: can.user.trans(can, value, null, html.VALUE)}
return {type: html.OPTION, value: value, inner: can.user.trans(can, value)} }); break
}) case html.TEXTAREA: input.type = html.TEXTAREA // no break
data.onchange = function(event) { case html.USERNAME: // no break
can.base.isFunction(list[1]) && list[1](event, event.target.value, name) case html.PASSWORD: // no break
} case html.TEXT:
case html.FILTER:
} else if (item.input) { var list = can.core.List(item.input) item.className||can.page.ClassList.add(can, item, ctx.ARGS), item.name = item.name||item.type, item.value = value||item.value||"";
type = html.INPUT, name = name||list[0]||"", data.name = data.name||name //item.placeholder = item.placeholder||item.name
data.className = data.className||data.name break
data.autocomplete = "off" case html.UPLOAD: item.type = html.FILE, input.name = html.UPLOAD; break
case html.BUTTON: item.value = item.value||item.name||mdb.LIST; break
data.onfocus = data.onfocus||function(event) { } return input
event.target.setSelectionRange(0, -1) },
} icons: function(can, name, space) { if (!name) { return }
data.onkeydown = function(event) { if (can.base.contains(name, "/") && can.misc.isImage(can, name)) { return {img: can.misc.Resource(can, name, space)} }
can.base.isFunction(list[1]) && list[1](event) // if (can.page.unicode[name]) { return {text: [can.page.unicode[name], "", "icon"]} }
} if (can.base.beginWith(name, "bi ")) { return {icon: name} }
data.onkeyup = function(event) { if (name == mdb.DELETE) { return {icon: "bi bi-trash"} }
can.base.isFunction(list[2]) && list[2](event) var _icon = can.base.getValid(can.Conf("_icons."+name), can.Conf("_trans.icons."+name), can.core.Value(can.onaction, ["_trans.icons."+name]), icon[name])
} if (_icon) { return {icon: _icon} }
} else if (item.username) { var list = can.core.List(item.username) },
type = html.INPUT, name = name||list[0]||html.USERNAME, data.name = data.name||name requireChina: function(can, title, list, name, path) {
data.className = list[1]||data.className||data.name can.onappend.plugin(can, {title: title, display: "/plugin/story/china.js", style: html.FLOAT, height: can.ConfHeight(), width: can.ConfHeight()}, function(sub) {
data.autocomplete = data.autocomplete||html.USERNAME sub.run = function(event, cmds, cb) { var msg = can.request(event, {title: title, name: name, path: path})
can.core.List(list, function(item) { msg.Push(mdb.NAME, item.name), msg.Push(mdb.VALUE, item.value) }), cb(msg)
} else if (item.password) { var list = can.core.List(item.password) can.onmotion.resize(can, sub._target, function(height, width) { sub.onimport.size(sub, height, width, true) })
type = html.INPUT, name = name||list[0]||html.PASSWORD, data.name = data.name||name }
data.className = list[1]||data.className||data.name })
data.autocomplete = data.autocomplete||"current-password" },
data.type = html.PASSWORD requireModules: function(can, libs, cb, cbs) { if (!libs || libs.length == 0) { return cb && cb() }
for (var i = 0; i < libs.length; i++) { if (libs[i].indexOf(nfs.PS) == 0 || libs[i].indexOf(ice.HTTP) == 0) { continue }
} else if (item.img) { var list = can.core.List(item.img) if (libs[i].indexOf(nfs._CSS) == -1 && libs[i].indexOf(nfs._JS) == -1) { libs[i] = libs[i]+"/lib/"+libs[i]+nfs._JS }
type = html.IMG, data.src = list[0] libs[i] = nfs.M+libs[i]
} can.require(libs, cb, cbs)
} else if (item.row) { type = html.TR },
item.list = item.row.map(function(text) { return {text: [text, item.sub||html.TD]} }) requireDraw: function(can, cb) { can.require([chat.PLUGIN_LOCAL+"wiki/draw.js", chat.PLUGIN_LOCAL+"wiki/draw/path.js"], function() {
} else if (item.th) { type = html.TR can.onimport._last_init(can, can.request()), can.onappend.style(can, wiki.DRAW, can._fields), cb()
item.list = item.th.map(function(text) { return {text: [text, html.TH]} }) }, function(can, mod, sub) { mod == chat.ONIMPORT && (can[mod]._last_init = sub._init) }) },
} else if (item.td) { type = html.TR drawText: function(can, text, size, margin, fonts) { text = text.slice(0, 1), size = size||80, margin = margin == undefined? 10: margin
item.list = item.td.map(function(text) { return {text: [text, html.TD]} }) var colors = ["rgb(239,150,26)", 'rgb(255,58,201)', "rgb(111,75,255)", "rgb(36,174,34)", "rgb(80,80,80)"]
} var canvas = can.page.Create(can, html.CANVAS, {width: size, height: size}), ctx = canvas.getContext("2d")
ctx.fillStyle = colors[Math.floor(Math.random()*(colors.length))], ctx.fillRect(margin, margin, size-2*margin, size-2*margin)
// 语言转换 ctx.fillStyle = cli.WHITE, ctx.font = (fonts||can.base.Min(size/text.length-30, 16))+"px Arial", ctx.textAlign = "center", ctx.textBaseline = "middle", ctx.fillText(text, size/2, size/2)
if (type == html.INPUT) { data.type == html.BUTTON && (data.value = can.user.trans(can, data.value)) return canvas.toDataURL(html.IMAGE_PNG, 1)
if (data.type == html.TEXT||data.type == html.PASSWORD||!data.type) { data.autocomplete = data.autocomplete||"off" },
data.placeholder = can.user.trans(can, (data.placeholder||data.name||"").split(ice.PT).pop()) position: function(event, target) { var p = target.getBoundingClientRect(); return {x: event.clientX - p.x, y: event.clientY - p.y} },
data.title = can.user.trans(can, data.title||data.placeholder) getquery: function(can, target) {
} var list = []; for (var p = target; p; p = p.parentNode) {
} if (can.page.tagis(p, "body")) { list.pop(); break }
if (type == html.TEXTAREA) { list.push(can.core.Keys(p.tagName.toLowerCase(), can.core.List(p.classList).join(".")), ">")
data.placeholder = can.user.trans(can, (data.placeholder||data.name||"").split(ice.PT).pop()) if (can.page.tagis(p, html.FIELDSET)) {
} if (can.page.tagis(p, "fieldset.web.chat.tutor")) { return "" }
list.pop(); break
// 创建节点 }
!data.name && item.name && (data.name = item.name) }
var node = can.page.Create(can, type, data) return list.reverse().join("")
},
// 创建索引 theme: function(cb) { var themeMedia = window.matchMedia("(prefers-color-scheme: dark)")
name = name||data.className||type||"" cb && themeMedia.addListener(function(event) { cb(event.matches? html.DARK: html.LIGHT) })
value[name||""] = value[data.className||""] = value[type] = node cb && cb(themeMedia.matches? html.DARK: html.LIGHT)
value.first = value.first||node, value.last = node return themeMedia.matches? html.DARK: html.LIGHT
value._target = value._target||node },
appendAction: function(can, value, target) { if (!value.action) { return } target.innerHTML = value.action
// 递归节点 can.page.Select(can, target, html.INPUT_BUTTON, function(target) {
item.list && can.page.Append(can, node, item.list, value) var style = can.Conf(["_trans.input",can.ConfIndex().split(".").pop(), "style", target.name])||can.Conf("_style."+target.name)||can.page.buttonStyle(can, target.name); style && can.onappend.style(can, style, target)
target && target.appendChild && target.appendChild(node) target.onclick = function(event) {
can.base.isFunc(item._init) && item._init(node) if (can.page.ClassList.has(can, can._fields, "_process")) { return } can.onappend.style(can, "_process")
}) can.onkeymap.prevent(event), can.Update(can.request(event, value, {_toast: can.user.trans(can, target.name)}), [ctx.ACTION, target.name])
return value }
}), })
Appends: shy("添加节点", function(can, target, key, value) { },
return target.innerHTML = "", can.page.Append(can, target, key, value) parseAction: function(can, value) { var action = []
}), can.page.Select(can, can.page.Create(can, html.DIV, value.action), html.INPUT, function(target) {
action.push(target.name), target.name != target.value && can.user.trans(can, kit.Dict(target.name, target.value))
AppendTable: shy("添加表格", function(can, msg, target, list, cb) { })
if (!msg.append||msg.append.length == 0) {return} return action
},
var table = can.page.Append(can, target, html.TABLE) buttonStyle: function(can, name) {
can.page.Append(can, table, [{type: html.TR, data: {dataset: {index: -1}}, list: return can.Conf(["_trans.input", can.ConfIndex().split(".").pop(), "style", name])||can.Conf("_style."+name)||
can.core.List(list, function(key) { can.core.Value(can.onaction, ["_trans", "style", name])||(can.base.isIn(name, mdb.CREATE, mdb.INSERT, mdb.IMPORT, nfs.CLONE, cli.START, ctx.RUN, web.UPLOAD, web.CONFIRM, aaa.LOGIN, code.AUTOGEN, "sso", "add", "pull", "push", "submit", "commit", "preview", "auto-preview", ice.APP)? html.NOTICE:
return key[0] == "_"? undefined: {text: [key.trim(), html.TH]} can.base.isIn(name, mdb.REMOVE, "rename", mdb.DELETE, mdb.PRUNES, mdb.PRUNE, nfs.TRASH, cli.RESTART, cli.STOP, cli.CLOSE, cli.REBOOT, web.CANCEL, code.UPGRADE, "reject", "del", "drop", "access", "kill", "prockill")? html.DANGER: "")
}) },
}]) exportValue: function(can, msg, target) { target = target||can._output
can.page.Append(can, table, can.core.List(msg.Table(), function(line, index, array) { msg.OptionDefault(ice.MSG_THEME, can.getHeaderTheme())
var _list = can.core.List(list, function(key) { if (key.indexOf("_") == 0) { return } msg.OptionDefault(ice.MSG_BG, can.page.styleValue(can, "--plugin-bg-color", target))
return cb(can.page.Color(line[key]).trim(), key, index, line, array) msg.OptionDefault(ice.MSG_FG, can.page.styleValue(can, "--plugin-fg-color", target))
}) can.user.info.language && msg.OptionDefault(ice.MSG_LANGUAGE, can.user.info.language)
return _list.length > 0? {type: html.TR, dataset: {index: index}, list: _list}: undefined return msg
})) },
return can.page.OrderTable(can, table) styleValue: function(can, key, target) { const styles = getComputedStyle(target||document.body); return styles.getPropertyValue(key) },
}), styleValueInt: function(can, key, target) { return parseInt(can.base.trimSuffix(can.page.styleValue(can, key, target), "px")) }
OrderTable: function(can, table) {
can.page.Select(can, table, html.TH, function(th, index) {
th.onclick = function(event) { var dataset = event.target.dataset
dataset["sort_asc"] = (dataset["sort_asc"] == "1") ? 0: 1
can.page.RangeTable(can, table, index, dataset["sort_asc"] == "1")
}
})
return table
},
RangeTable: function(can, table, index, sort_asc) {
var list = can.page.Select(can, table, html.TR, function(tr) {
return tr.style.display == html.NONE||can.page.ClassList.has(can, tr, "hide")? null: tr
}).slice(1)
index = can.base.isObject(index)? index: [index]
index = can.core.List(index, function(item) { if (item > -1) { return item} })
if (index.length == 0) { return }
var is_time = true, is_number = true
can.core.List(list, function(tr) {
var text = tr.childNodes[index[0]].innerText
is_time = is_time && Date.parse(text) > 0
is_number = is_number && !isNaN(parseInt(text))
})
var num_list = can.core.List(list, function(tr) {
var text = tr.childNodes[index[0]].innerText
return is_time? Date.parse(text):
is_number? can.base.ParseSize(text): text
})
function isless(a, b, index) {
if (a.childNodes[index[0]] && b.childNodes[index[0]]) {
if (a.childNodes[index[0]].innerText < b.childNodes[index[0]].innerText) { return true }
if (a.childNodes[index[0]].innerText > b.childNodes[index[0]].innerText) { return false }
}
return index.length > 1 && isless(a, b, index.slice(1))
}
// 选择排序
for (var i = 0; i < num_list.length; i++) { var min = i
for (var j = i+1; j < num_list.length; j++) {
if (num_list[min] == num_list[j] && index.length > 1 && list[index[1]]) {
if (sort_asc? isless(list[min], list[j], index.slice(1)): isless(list[j], list[min], index.slice(1))) {
min = j
}
} else if (sort_asc? num_list[min] < num_list[j]: num_list[j] < num_list[min]) {
min = j
}
}
if (min != i) {
var temp = num_list[i]; num_list[i] = num_list[min]; num_list[min] = temp
var temp = list[i]; list[i] = list[min]; list[min] = temp
}
var tbody = list[i].parentElement
list[i].parentElement && tbody.removeChild(list[i])
tbody.appendChild(list[i])
}
},
Cache: function(name, output, data) { var cache = output._cache||{}; output._cache = cache
if (data) { if (output.children.length == 0) { return }
var temp = document.createDocumentFragment()
while (output.childNodes.length > 0) { // 写缓存
var item = output.childNodes[0]
item.parentNode.removeChild(item),
temp.appendChild(item)
}
return cache[name] = {node: temp, data: data}, name
}
output.innerHTML = ""
var list = cache[name]; if (!list) { return }
while (list.node.childNodes.length > 0) { // 读缓存
var item = list.node.childNodes[0]
item.parentNode.removeChild(item)
output.appendChild(item)
}
return delete(cache[name]), list.data
},
Format: function(type) {
switch (type) {
case html.A: return "<a href='"+arguments[1]+"' target='_blank'>"+(arguments[2]||arguments[1])+"</a>"
case html.IMG: return arguments[2]? "<img src='"+arguments[1]+"' height="+arguments[2]+">": "<img src='"+arguments[1]+"'>"
}
},
Color: function(text) { if (typeof text != lang.STRING) { return "" }
if (text.indexOf("http://") == 0 || text.indexOf("https://") == 0 || text.indexOf("ftp://") == 0) {
var ls = text.split(ice.SP);
text = "<a href='"+ls[0]+"' target='_blank'>"+ls[0]+"</a>"+ls.slice(1).join(ice.SP)
}; text = text.replace(/\\n/g, "<br>")
if (text.indexOf("\033\[") == -1) { return text }
text = text.replace(/\033\[31m/g, "<span style='color:#f00'>")
text = text.replace(/\033\[32m/g, "<span style='color:#0f0'>")
text = text.replace(/\033\[33m/g, "<span style='color:#ff0'>")
text = text.replace(/\033\[34m/g, "<span style='color:#00f'>")
text = text.replace(/\033\[36m/g, "<span style='color:#0ff'>")
text = text.replace(/\033\[34;1m/g, "<span style='color:#00f'>")
text = text.replace(/\033\[37;1m/g, "<span style='color:#fff'>")
text = text.replace(/\033\[1m/g, "<span style='font-weight:bold'>")
text = text.replace(/\033\[0m/g, "</span>")
text = text.replace(/\033\[m/g, "</span>")
return text
},
input: function(can, item, value) {
var input = {type: html.INPUT, name: item.name, data: item, dataset: {}, _init: item._init, style: item.style||{}}
item.value == ice.AUTO && (item.value = "", item.action = ice.AUTO), item.action == ice.AUTO && (input.dataset.action = ice.AUTO)
switch (item.type = item.type||html.TEXT) {
case html.TEXTAREA: input.type = html.TEXTAREA
input.style.height = input.style.height||can.Conf(["feature", html.TEXTAREA, item.name, html.HEIGHT].join(ice.PT))||can.Conf(["feature", html.TEXTAREA, html.HEIGHT].join(ice.PT))
input.style.width = input.style.width||can.Conf(["feature", html.TEXTAREA, item.name, html.WIDTH].join(ice.PT))||can.Conf(["feature", html.TEXTAREA, html.WIDTH].join(ice.PT))
// no break
case html.PASSWORD:
// no break
case html.TEXT:
if (item.username) { item.type = html.TEXT; return item }
if (item.password) { return item }
item.autocomplete = "off"
item.value = value||item.value||""
item.className || can.page.ClassList.add(can, item, "args")
break
case html.SELECT: input.type = html.SELECT
item.values = can.base.isString(item.values)? can.core.Split(item.values): item.values
if (!item.values && item.value) { item.values = can.core.Split(item.value), item.value = item.values[0] }
item.value = value||item.value, input.list = item.values.map(function(value) {
return {type: html.OPTION, value: value, inner: value}
}), item.className || can.page.ClassList.add(can, item, "args")
break
case html.BUTTON: item.value = item.value||item.name||"list"; break
case "upfile": item.type = html.FILE; break
case html.UPLOAD: item.type = html.FILE, input.name = html.UPLOAD; break
default:
}
return input
},
}) })

View File

@ -1,330 +1,454 @@
Volcanos("user", {help: "用户操作", agent: { Volcanos("user", {
scanQRCode: function(cb, can) { agent: {
can.user.input(event, can, [{type: html.TEXTAREA, name: "text", text: ""}], function(ev, button, data, list, args) { getLocation: function(can, cb) { var call = arguments.callee; if (call._res) { return cb(call._res) }
cb(list[0], can.base.ParseJSON(list[0])) navigator.geolocation.getCurrentPosition(function(res) {
}) cb(call._res = {type: "ip", name: "当前位置", text: "某某大街", latitude: res.coords.latitude.toFixed(6), longitude: res.coords.longitude.toFixed(6)})
}, }, function(some) { can.base.isFunc(cb) && cb({type: "location", name: "北京市", text: "天安门", latitude: 39.98412, longitude: 116.30748}) } )
getLocation: function(cb) { },
navigator.geolocation.getCurrentPosition(function(res) { openLocation: function(can, msg) {
cb({latitude: parseInt(res.coords.latitude*100000), longitude: parseInt(res.coords.longitude*100000)}) window.open("https://map.baidu.com/search/"+encodeURIComponent(msg.Option(mdb.TEXT))
}, function(some) { +"/@12958750.085,4825785.55,16z?querytype=s&da_src=shareurl&wd="+encodeURIComponent(msg.Option(mdb.TEXT)))
typeof cb == lang.FUNCTION && cb({name: "some"}) },
} ); chooseImage: function(can, cb, count) { can.base.isFunc(cb) && cb([]) },
}, uploadImage: function(can, id, cb) {},
openLocation: function(msg) { previewImage: function(can, url, list) {},
window.open("https://map.baidu.com/search/"+encodeURIComponent(msg.Option(mdb.TEXT)) scanQRCode: function(can, cb) { can.user.input(event, can, [{type: html.TEXTAREA, name: mdb.TEXT, text: ""}], function(list) { cb(can.base.ParseJSON(list[0])) }) },
+"/@12958750.085,4825785.55,16z?querytype=s&da_src=shareurl&wd="+encodeURIComponent(msg.Option(mdb.TEXT))) connectWifi: function(can, ssid, password, cb, cbs) {},
}, getClipboard: function(can, cb) {},
chooseImage: function(cb) { enableDebug: function(can) {},
typeof cb == lang.FUNCTION && cb([]) init: function(can, content, icons) { can.user.agent.cmd = can, can.user.agent._init_content = content, can.user.agent._init_icons = icons }, _init_content: [],
}, }, info: {},
}, isIPad: false,
isWeiXin: navigator.userAgent.indexOf("MicroMessenger") > -1, isTesla: navigator.userAgent.indexOf("Tesla") > -1,
isIPhone: navigator.userAgent.indexOf("iPhone") > -1, isChrome: navigator.userAgent.indexOf("Chrome") > -1,
isMobile: navigator.userAgent.indexOf("Mobile") > -1, isSafari: navigator.userAgent.indexOf("Safari") > -1,
isMacOSX: navigator.userAgent.indexOf("Mac OS X") > -1, isMailMaster: navigator.userAgent.indexOf("MailMaster") > -1,
isWindows: navigator.userAgent.indexOf("Windows") > -1, isWeiXin: navigator.userAgent.indexOf("MicroMessenger") > -1,
isIE: navigator.userAgent.indexOf("MSIE") > -1, isIPhone: navigator.userAgent.indexOf("iPhone") > -1,
isExtension: location && location.protocol && location.protocol == "chrome-extension:", isMobile: navigator.userAgent.indexOf("Mobile") > -1,
isLocalFile: location && location.protocol && location.protocol == "file:", isMacOSX: navigator.userAgent.indexOf("Mac OS X") > -1,
isLandscape: function() { return window.innerWidth > window.innerHeight }, isWindows: navigator.userAgent.indexOf("Windows") > -1,
mod: { isNodejs: navigator.userAgent.indexOf("nodejs") > -1,
isPod: location && location.pathname && (location.pathname.indexOf("/chat/pod/") == 0), isIE: navigator.userAgent.indexOf("MSIE") > -1,
isDiv: location && location.pathname && (location.pathname.indexOf("/chat/div/") == 0), isWebview: window.webview != undefined,
isCmd: location && location.pathname && (location.pathname.indexOf("/chat/pod/") == 0 && location.pathname.indexOf("/cmd/") > 0 || isExtension: location && location.protocol && location.protocol == "chrome-extension:",
location.pathname.indexOf("/chat/cmd/") == 0 || location.pathname.indexOf("/help/") == 0), isLocalFile: location && location.protocol && location.protocol == "file:",
}, isLandscape: function() { return window.innerWidth > window.innerHeight },
isTechOrRoot: function(can) { return can.base.isIn(can.user.info.userrole, aaa.TECH, aaa.ROOT) },
mod: {
isPod: location && location.pathname && (location.pathname.indexOf(web.CHAT_POD) == 0 || location.pathname.indexOf("/x/") == 0 || location.pathname.indexOf("/s/") == 0),
isCmd: location && location.pathname && (location.pathname.indexOf(web.CHAT_POD) == 0 && location.pathname.indexOf("/cmd/") > 0
|| location.pathname.indexOf(web.CHAT_CMD) == 0 || location.pathname.indexOf(nfs.WIKI_PORTAL) == 0
),
},
alert: function(text) { alert(JSON.stringify(text)) },
confirm: function(text) { return confirm(JSON.stringify(text)) },
prompt: function(tip, def, cb, silent) { (text = silent? def: prompt(tip, def||"")) != undefined && typeof cb == code.FUNCTION && cb(text); return text },
reload: function(force) { (force || confirm("重新加载页面?")) && location.reload() },
jumps: function(url) {
location.href = url
},
opens: function(url) {
if (window.parent && window.parent.openurl) { return window.parent.openurl(url) }
window.openurl? window.openurl(url): this.open(url)
},
open: function(url) { if (!url) { return }
if (location.search.indexOf("debug=true") > 0 && url.indexOf("debug=true") == -1) {
var ls = url.split("#"); ls[0] += (ls[0].indexOf("?") > 0? "&": "?") + "debug=true", url = ls.join("#")
}
window.open(url) || (location.hostname != tcp.LOCALHOST && (location.href = url))
},
close: function(url) { return window.close() },
theme: function(can, name) { can.base.isString(name) && (name = [name]) || name || []
name.push(html.WIDTH+parseInt((can.page.width()+32)/320))
can.user.mod.isCmd && name.push(chat.CMD), can.user.mod.cmd && name.push(can.base.replaceAll(can.user.mod.cmd, ".", " "))
// if (window.innerWidth <= 1080) { can.user.isIPad = true }
can.user.isIPad && name.push("pad") && can.user.isLandscape() && name.push(html.LANDSCAPE)
can.user.isWindows && name.push(html.WINDOWS), can.user.isWebview && name.push(html.WEBVIEW)
can.user.isMobile && name.push(html.MOBILE) && can.user.isLandscape() && name.push(html.LANDSCAPE)
can.user.isWeiXin && name.push("weixin")
can.user.language(can) && name.push(can.core.Split(can.user.language(can), "-_.")[0])
can.user.info.userrole && name.push(can.user.info.userrole)
can.misc.isDebug(can) && name.push(log.DEBUG)
can.page.styleClass(can, document.body, name.join(lex.SP))
},
title: function(text) {
if (window.webview) { return title(text) }
return text && (document.title = text), document.title
},
language: function(can) { return (can.misc.SearchOrConf(can, aaa.LANGUAGE)||can.user.info.language||"") },
isEnglish: function(can) { return can.base.isIn(can.core.Split(can.user.language(can).toLowerCase()||"en", "_-.")[0], "en", "en-us") },
transValue: function(can, value, key) {
if (value.Append) { return can.user.trans(can, value.Append(key), null, "value."+key) }
if (value.Option) { return can.user.trans(can, value.Option(key), null, "value."+key) }
return can.user.trans(can, value[key], null, "value."+key)
},
trans: function(can, text, list, zone) { if (can.base.isNumber(text)) { return text+"" } if (can.user.isEnglish(can)) { return text }
if (can.base.isObject(text)) { return can.core.Item(text, function(k, v) { can.core.Value(can._trans, can.core.Keys(zone, k), v) }) }
if (can.base.isFunc(text)) { text = text.name||"" } if (list && can.base.isString(list)) { return list }
var key = can.core.Keys(zone, text)
if (text == can.Conf("index") && can.Conf("help")) { return can.Conf("help") }
return can.core.Value(list, key) ||
can.Conf(["feature._trans", zone||"input", (can.ConfIndex()||"").split(".").pop(), text]) ||
can.Conf(["feature._trans", zone, (can.ConfIndex()||"").split(".").pop(), text]) ||
can.Conf(["feature._trans", key]) || can.Conf(["trans", key]) ||
can.core.Value(can._trans, key) ||
can.core.Value(can.user._trans, key) || text
}, _trans: {"_week_header": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]},
time: function(can, time, fmt) {
var now = can.base.Date(time), list = can.user._trans["_week_header"]
return fmt == "%W"? list: can.base.Time(time, (fmt||"%y-%m-%d %H:%M:%S").replace("%w", list[now.getDay()]))
},
toastConfirm: function(can, content, title, action) {
if (!action.list || action.list.length == 0) { action = shy({confirm: action}, [html.CANCEL, html.CONFIRM]) }
var carte = can.user.toast(can, {content: content, title: title, action: action||[cli.CLOSE], duration: -1})
can.page.style(can, carte._target, html.TOP, 200, html.BOTTOM, ""); return carte
},
toastProcess: function(can, content, title, progress) {
content = can.user.trans(can, content||""), content += can.user.trans(can, " process", "中...")
return can.user.toast(can, {content: "🕑 "+content, title: title, duration: -1, progress: progress})
},
toastFailure: function(can, content, title) {
content = can.user.trans(can, content||"")
if (content.length < 8) { content += can.user.trans(can, " failure", "失败") }
return can.user.toast(can, {content: "❌ "+content, title: title, duration: -1})
},
toastSuccess: function(can, content, title, duration) {
content = can.user.trans(can, content||""), content += can.user.trans(can, " success", "成功")
return can.user.toast(can, {content: "✅ "+content, title: title, duration: duration||1000})
},
toast: function(can, content, title, duration, progress, hash) { can = can._fields? can.sup: can
var meta = can.base.isObject(content)? content: {content: content, title: title, duration: duration, progress: progress, hash: hash}
// var list = can.core.Split(content, " ", " ")
// content = can.core.List(list, function(text) { return can.user.trans(can, text) }).join("")
if (meta.title == can.ConfIndex()) { meta.title = can.user.trans(can, meta.title, can.ConfHelp()) }
meta.title = meta.title||can.user.trans(can, can.core.Keys(can.ConfSpace(), can.ConfIndex()), can.ConfHelp())||can._name.split(nfs.PS).slice(-2).join(nfs.PS)
meta.title = can.base.replaceAll(can.user.trans(can, meta.title||""), "%2F", "/")
meta.hash && can.misc.isDebug(can) && (meta.title += " "+meta.hash.slice(0, 6)), meta.action = meta.action||[""]
var width = meta.width||(html.QRCODE_WIDTH+2*html.PLUGIN_PADDING+10); if (width < 0) { width = can.page.width() + width }
if (can.user.isMobile && !can.user.isLandscape()) { width = window.innerWidth }
var ui = can.page.Append(can, meta.action.list||meta.action.length > 1 || !can._root||!can._root.Action||!can._root.Action._toast? document.body: can._root.Action._toast,
[{view: [[chat.TOAST, can.ConfIndex(), meta.style, html.FLOAT]], style: {width: width}, list: [
{view: [html.TITLE, "", meta.title], title: "点击复制", onclick: function(event) { can.user.copy(event, can, meta.title) }},
{view: [cli.CLOSE, "", can.page.unicode.close], title: "点击关闭", onclick: function() { action.close() }},
{view: "duration", title: "点击关闭", onclick: function() { action.close() }},
can.base.isObject(meta.content)? meta.content: {view: [[nfs.CONTENT, html.FLEX], "", meta.content||""]},
html.ACTION, !can.base.isUndefined(meta.progress) && {view: "progress", style: {width: width-2*html.PLUGIN_PADDING}, list: [
{view: "current", style: {width: (meta.progress||0)*(width-2*html.PLUGIN_PADDING-2)/100}},
]},
]}]
);
can.onengine.signal(can, chat.ONTOAST, can.request({}, {time: can.misc._time(), title: meta.title, content: meta.content}))
// meta.action.meta && can.core.Item(meta.action.meta, function(key, cb) { cb.help && can.core.Value(meta.action.meta, ["_trans", key], cb.help) })
var action = can.onappend._action(can, meta.action.list? meta.action.list.reverse(): meta.action, ui.action, {_trans: meta.action.meta? meta.action.meta._trans: {},
_engine: function(event, button) { can.core.CallFunc(meta.action.meta? meta.action.meta[button]: meta.action, [event, button]), action.close(event) },
open: function(event) { meta.content.indexOf(ice.HTTP) == 0 && can.user.open(meta.content), meta.title.indexOf(ice.HTTP) == 0 && can.user.open(meta.title) },
close: function() {
// event && event.isTrusted && can.onengine.signal(can, "onevent", can.request(event, {_type: "close"}))
action.timer.stop = true, can.page.Remove(can, ui._target), delete(can.__toast)
can._toast && (typeof can._toast.close == code.FUNCTION) && delete(can._toast)
},
cancel: function() { action.close() },
timer: can.core.Timer({interval: 100, length: (meta.duration||1000)/100}, function(event, interval, index) {
if (index > 30) { ui.duration.innerHTML = index/10+(index%10==0?".0":"")+"s..." }
}, function() {
can.page.style(can, ui._target, "margin-right", "-400px")
can.onmotion.delay(can, function() { action.close() }, 1000)
}), _target: ui._target,
}); can.onmotion.story.auto(can, ui._target)
if (meta.action && meta.action.length == 1 && meta.action[0] === "") {
can.page.Select(can, action._target, html.DIV_ACTION, function(target) { can.onmotion.hidden(can, target) })
}
if (action._target.parentNode == document.body) { can.onmotion.delay(can, function() {
can.page.style(can, action._target, html.TOP, (can.page.height() - action._target.offsetHeight)/2, html.LEFT, (can.page.width()-action._target.offsetWidth)/2)
}) }
can._toast && (typeof can._toast.close == code.FUNCTION && can._toast.close(), delete(can._toast))
can._root && can._root.Action && can._root.Action._toast && (can._root.Action._toast.scrollTop += 10000)
if (meta.hash) { var list = can._root.Action._toastList = can._root.Action._toastList||{}
list[meta.hash] && can.page.insertBefore(can, action._target, list[meta.hash]._target), can.__toast = action
list[meta.hash] && (can.page.Remove(can, list[meta.hash]._target), list[meta.hash].close(), delete(list[meta.hash])), list[meta.hash] = action
} else {
can._toast = action
}
return action
},
space: function(can) { return can.Conf(web.SPACE)||can.Conf(ice.POD)||can.misc.Search(can, ice.POD) },
template: function(can, file) { return can.base.MergeURL(can.base.Path(nfs.SRC_TEMPLATE, can.Conf(ctx.INDEX), file), ice.POD, can.user.space(can)) },
share: function(can, msg, cmds) { can.page.exportValue(can, msg)
can.run(msg, cmds||[ctx.ACTION, chat.SHARE], function(msg) { can.user.copy(msg._event, can, msg.Append(mdb.NAME))
var ui = can.user.toast(can, {style: cli.QRCODE, title: msg.Append(mdb.NAME), duration: -1, content: msg.Append(mdb.TEXT), action: [cli.CLOSE, cli.OPEN], resize: html.IMG})
})
},
copy: function(event, can, text) { if (!text) { return }
if (navigator.clipboard) { var ok = false; navigator.clipboard.writeText(text).then(function() { ok = true })
if (ok) { return can.user.toastSuccess(can, text, "copy success"), can.misc.Log(nfs.COPY, text), text }
}
var input = can.page.Append(can, document.body, [{type: html.TEXTAREA, value: text}])._target
can.onmotion.focus(can, input), document.execCommand("Copy"), can.page.Remove(can, input)
return can.user.toastSuccess(can, text, can.user.trans(can, "copy success", "复制成功")), can.misc.Log(nfs.COPY, text), text
},
carte: function(event, can, meta, list, cb, parent, trans) { var msg = can.request(event); event = msg._event
function remove_sub(carte) { carte._sub && can.page.Remove(can, carte._sub._target), delete(carte._sub) } parent? remove_sub(parent): can.onmotion.clearCarte(can)
meta = meta||can.ondetail||can.onaction||{}, list = can.base.getValid(list, meta.list, can.core.Item(meta, function(key) {
if (can.base.beginWith(key, "_")) { return }
return key
})), trans = trans||meta._trans; if (!list || list.length == 0) { return }
var _events = event._events||event
function click(event, button, index) { can.misc.Event(event, can, function() { can.request(event, {action: button}), can.onkeymap.prevent(event), event._events = _events;
can.onengine.signal(can, "onevent", can.request(event, {_type: html.ACTION}));
(can.base.isFunc(cb)? cb(event, button, meta, carte, index): meta[button]? can.core.CallFunc([meta, button], {event: event, can: can, msg: msg, button: button}): can.Update(event, [ctx.ACTION, button])) || can.onmotion.clearCarte(can)
}) }
var isinput = can.page.tagis(event.target, html.INPUT)
var ui = can.page.Append(can, document.body, [{view: [[chat.CARTE,
can.Conf(ctx.INDEX)||can.ConfIndex(), msg.Option(ctx.ACTION), meta._style||msg.Option("_style"), chat.FLOAT,
]], list: can.core.List(list, function(item, index) {
if (typeof item == code.FUNCTION) { item = item(can); if (!item) { return } }
if (item === "") { return {type: html.HR} }
if (item == web.FILTER) { return {
input: [html.FILTER, function(event) { if (event.key == code.ESCAPE) { return carte.close() } can.onkeymap.selectItems(event, can, carte._target) } ],
_init: function(target) { can.onmotion.delay(can, function() { target.placeholder = "search in "+(can.core.List(list, function(item) { if (item) { return item } }).length-1)+" items", target.focus() }) }
} }
if (can.base.isString(item)||can.base.isNumber(item)) {
if (can.base.beginWith(item, "<")) {
return {view: [html.ITEM, html.DIV, item]}
}
var _style = can.page.buttonStyle(can, item)
return {
view: [[html.ITEM, item, _style]],
// list: [can.page.icons(can, item), {text: [can.user.trans(can, item, trans), "", "name"]}],
list: [{text: [can.user.trans(can, item, trans), "", "name"]}],
onclick: function(event) { click(event, item, index) },
onmouseenter: function(event) { remove_sub(carte) },
}
}
if (can.base.isArray(item)) {
function subs(event) { var sub = can.user.carte(event, can, meta, item.slice(1), cb||function(event, button) {
can.onimport && can.onimport[item[0]]? can.onimport[item[0]](can, button, event): click(event, button, index)
}, carte, trans); carte._sub = sub }
return {view: html.ITEM, list: [
// can.page.icons(can, item[0]),
{text: [can.user.trans(can, item[0], trans), "", "name"]},
{text: [lex.SP+can.page.unicode.next, "", [html.ICON, "next"]]}
], onmouseenter: subs, onclick: subs}
}
return item
})}]); can.onkeymap.prevent(event), can.page.Select(can, ui._target, html.IMG, function(target) { target.onload = function() { can.onlayout.figure(event, can, ui._target) } })
var carte = {_target: ui._target, _parent: parent, layout: can.onlayout.figure(event, can, ui._target, parent), close: function() { can.page.Remove(can, ui._target) }}
return parent && (parent._sub = carte), carte
},
carteRight: function(event, can, meta, list, cb, parent) { var carte = can.user.carte(event, can, meta, list, cb, parent)
return carte && can.onlayout.figure(event, can, carte._target, true), carte
},
carteItem: function(event, can, item) { if (!item.action) { return }
var trans = {}, list = can.page.Select(can, can.page.Create(can, html.DIV, item.action), "", function(target) { trans[target.name] = can.user.trans(can, target.value); return target.name })
can.user.carteRight(event, can, {_trans: trans}, list, function(_event, button) {
can.Update(can.request(_event, event._msg, item), [ctx.ACTION, button]) })
},
input: function(event, can, form, cb, button) { if (!form || form.length == 0) { return cb() }
event = event||{}; var msg = can.request(event); event = event._event||event; var need = {}
var title = can.user.trans(can, msg.Option(ctx.ACTION))
var ui = can.page.Append(can, document.body, [{view: [[html.INPUT, can.Conf(ctx.INDEX)||can.ConfIndex(), msg.Option(ctx.ACTION), msg.Option(mdb.TYPE), chat.FLOAT]], list: [
{view: html.OPTION, list: [{type: html.TABLE, list: can.core.List(form, function(item) {
item = can.base.isString(item)? {type: html.TEXT, name: item}: item.length > 0? {type: html.SELECT, name: item[0], values: item.slice(1)}: item
item.type = item.type||(item.values? html.SELECT: item.name == html.TEXT? html.TEXTAREA: html.TEXT), need[item.name] = item.need
item._init = function(target) {
if (item.name && item.name != ctx.ACTION) { target.value = item.value||msg.Option(item.name)||can.Option(item.name)||target.value||"" }
// item.mode = chat.SIMPLE,
can.onappend.figure(can, can.base.Copy({space: msg.Option(web.SPACE), run: function(event, cmds, cb) { var _msg = can.request(event, {_handle: ice.TRUE, action: msg.Option(html.ACTION)}, msg, can.Option())
can.page.Select(can, ui.table, html.OPTION_ARGS, function(item) { item.name && item.value && _msg.Option(item.name, item.value) }); (item.run||can.run)(event, cmds, cb, true)
}, _enter: function(event) { return action.submit(event, can, html.SUBMIT), true }}, item), target)
}, item.onkeydown = function(event) { if (event.key == code.ESCAPE) { event.target.blur() } }
// item.placeholder = can.user.trans(can, item.placeholder||item.name, null, html.INPUT)
// item.title = can.user.trans(can, item.title||item.placeholder||item.name, null, html.INPUT)
return {view: [[item.name, item.type, item.action], html.TR], list: [
{type: html.TD, list: [
{text: [can.user.trans(can, item.name||"", item._trans, html.INPUT), html.LABEL]},
item.need == "must" && {text: ["*", "", "must"]},
]}, {type: html.TD, list: []},
{type: html.TD, _init: function(target) { can.onappend.input(can, item, msg.Option(item.name)||(can._msg? can._msg.Option(item.name): ""), target) }},
], onclick: function(event) {
can.page.Select(can, event.currentTarget, "input", function(target) { target.focus() })
}}
})}]}, html.ACTION,
], onclick: function(event) { if (!can.page.tagis(event.target, html.INPUT, html.TEXTAREA)) { can.onmotion.clearCarte(can) } }}])
var action = can.onappend._action(can, button||[html.SUBMIT, html.CANCEL], ui.action, {
_trans: {submit: msg.Option(web.SUBMIT)},
focus: function(key) { can.onmotion.focus(can, can.page.Select(can, ui._target, key? "input.args[name="+key+"]": html.INPUT_ARGS)[0]) },
Option: function(key, value, hidden) {
if (!key) { var data = kit.Dict(msg.OptionSimple())
can.page.Select(can, ui._target, "input.args", function(target) { data[target.name] = target.value })
return data
}
var target = can.page.Select(can, ui._target, "input.args[name="+key+"]")[0]
if (!target) { return }
if (value != undefined) { target.value = target.value||value }
if (target.value && hidden) { can.onmotion.hidden(can, can.page.parentNode(can, target, html.TR)) }
return target.value
},
layout: function(event) {
if (event && event.target) { can.onlayout.figure(event, can, ui._target)
can.user.isMobile && can.page.style(can, ui._target, html.LEFT, (can.page.width()-ui._target.offsetWidth)/2, html.TOP, 40)
} else {
can.getActionSize(function(left, top, height) { can.page.style(can, ui._target, html.LEFT, left||0, html.TOP, (height/4||0)) })
} can.onmotion.resize(can, ui._target)
alert: function(text) { alert(JSON.stringify(text)) }, },
confirm: function(text) { return confirm(JSON.stringify(text)) }, cancel: function(event, can, button) {
prompt: function(tip, def, cb, silent) { (text = silent? def: prompt(tip, def||"")) != undefined && typeof cb == lang.FUNCTION && cb(text); return text }, can.page.ClassList.del(can, can._fields||can._target, "_process")
reload: function(force) { (force || confirm("重新加载页面?")) && location.reload() }, button == "cancel" && msg._cancel && msg._cancel(event), callback("afterInputs", button)
jumps: function(url) { location.href = url }, can.onengine.signal(can, "onremove", can.request(event, {query: can.page.getquery(can, ui._target)})), can.page.Remove(can, ui._target)
open: function(url) { window.open(url) }, },
time: function(can, time, fmt) { var now = can.base.Date(time) submit: function(event, can, button) { var args = [], data = {}, err = false
var list = can.user.language(can) == "en"? ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]: ["周日", "周一", "周二", "周三", "周四", "周五", "周六"] var list = can.page.Select(can, ui._target, html.OPTION_ARGS, function(item) {
return can.base.Time(time, (fmt||"%y-%m-%d %H:%M:%S").replace("%w", list[now.getDay()])) if (item.value == "" && need[item.name] == "must") { err = true, item.focus(), can.user.toast(can, item.name+" 是必选字段, 请重新输入") }
}, return item.name && args.push(item.name, item.value||""), data[item.name] = item.value||""
}); if (err) { return } can.onkeymap.prevent(event)
title: function(text) { var _msg = can.request(event); _msg.Option(ctx.ACTION, msg.Option(ctx.ACTION)), _msg.Option("_toast", msg.Option("_toast"))
return text && (document.title = text), document.title if (can.core.CallFunc(cb, {event: can.request(event, {_handle: ice.TRUE})._event, button: button, data: data, list: list, args: args, input: action})) {
}, callback("afterInputs", button)
topic: function(can, name) { } else {
can.user.isMobile && (name += " mobile") && can.user.isLandscape() && (name += " landscape") action.cancel(event, can, button)
can.page.Modify(can, document.body, {className: name}) }
}, }, _target: ui._target, _engine: function(event, can, button) { action.submit(event, can, button) },
language: function(can) { });
return can.misc.Search(can, "language") can.page.Select(can, action._target, "input", function(target) {
}, target.onfocus = target.onfocus||function(event) { can.onengine.signal(can, "onevent", can.request(event)) }
trans: function(can, text) { var onclick = target.onclick; target.onclick = function(event) { can.onengine.signal(can, "onevent", can.request(event, {_type: target.name})), onclick && onclick(event) }
if (can.user.language(can) == "en") { return text } })
if (can.base.isObject(text)) { title && can.page.Select(can, action._target, "input[name=submit]", function(target) { target.value = can.user.trans(can, title) })
return can.core.Item(text, function(k, v) { can.core.Value(can._trans, k, v) }) action.layout(event), can.onmotion.delay(can, function() { action.focus() }, 300)
} function callback(key, button) { var sub = can._fields? can: can.sub; sub && sub.onaction && sub.onaction[key] && sub.onaction[key](event, sub, button, action) }
callback("beforeInputs")
if (can.base.isFunction(text)) { text = text.name||"" } // ui._target._layout = action.layout
return can._trans&&can._trans[text] || can.Conf("trans."+text) || can.Conf("feature._trans."+text) || { return button === true && action.submit(event, can, html.SUBMIT), action
"create": "创建", "remove": "删除", "insert": "添加", "delete": "删除", "modify": "编辑", },
"inputs": "补全", "prunes": "清理", "export": "导出", "import": "导入", select: function(event, can, type, fields, cb, cbs) {
"list": "查看", "back": "返回", "run": "执行", "done": "完成", "share": "共享", can.search(can.request(event, {fields: fields||"type,name,text"}), ["Search.onimport.select", type, "", ""], function(list) {
"edit": "编辑", "save": "保存", "copy": "复制", "show": "显示", "hide": "隐藏", can.core.Next(list, cb, cbs||function() { can.user.toastSuccess(can) })
"project": "项目", "profile": "详情", "actions": "参数", })
},
"open": "打开", "close": "关闭", upload: function(event, can, cb, silent) { var begin = new Date()
"start": "启动", "stop": "停止", var ui = can.page.Append(can, document.body, [{view: [[html.UPLOAD, can.Conf(ctx.INDEX)||can.ConfIndex(), chat.FLOAT]], list: [
"begin": "开始", "end": "结束", html.ACTION, {view: html.OUTPUT, list: ["progress"]}, {view: html.STATUS, list: [html.SHOW, cli.COST, nfs.SIZE]},
"clear": "清空", "refresh": "刷新", ]}])
"submit": "提交", "cancel": "取消", can.user.isMobile && can.page.style(can, ui._target, html.LEFT, 0, html.WIDTH, window.innerWidth)
"label": "标签", "exec": "执行", can.onlayout.figure(event, can, ui._target)
}[text]||text var action = can.onappend._action(can, [{type: html.UPLOAD, onchange: function(event) { action.show(event, 0, event.target.files[0].size, 0) }}, {type: html.BUTTON, name: cli.CLOSE}], ui.action, {
}, begin: function() { begin = new Date(), can.user.toastProcess(can, "upload")
toastSuccess: function(can) { var upload = can.page.Select(can, ui.action, html.INPUT_FILE)[0]; if (upload.files.length == 0) { return upload.focus() }
can.user.toast(can, ice.SUCCESS) var msg = can.request(event, can.Option(), {_handle: ice.TRUE}); msg._upload = upload.files[0], msg._progress = action.show
}, can.runAction(event, html.UPLOAD, [], function(msg) {
toast: function(can, content, title, duration, progress) { if (msg.IsErr()) {
var meta = can.base.isObject(content)? content: {content: content, title: title||can._help, duration: duration, progress: progress} action.close(), can.user.toastFailure(can, msg.Result())
var width = meta.width||400, height = meta.height||100; if (width < 0) { width = window.innerWidth + width } return
}
var ui = can.page.Append(can, document.body, [{view: chat.TOAST, style: { can.base.isFunc(cb)? cb(msg): can.Update(), action.close(), can.user.toastSuccess(can, "upload")
left: (window.innerWidth-width)/2, width: width, bottom: 100, })
}, list: [ }, close: function(event) { can.page.Remove(can, ui._target) },
{text: [meta.title||"", html.DIV, html.TITLE], title: "点击复制", onclick: function(event) { show: function (event, value, total, loaded) {
can.user.copy(event, can, meta.title) ui.cost.innerHTML = can.base.Duration(new Date() - begin)
}}, ui.show.innerHTML = value+"%", value == 0 && action.begin(event)
{view: "duration", title: "点击关闭", onclick: function() { action.close() }}, ui.size.innerHTML = can.base.Size(loaded)+nfs.PS+can.base.Size(total)
can.base.isObject(meta.content)? meta.content: {text: [meta.content||"执行成功", html.DIV, "content"]}, can.page.styleWidth(can, ui.progress, value*(ui.output.offsetWidth-2)/100)
if (silent) { can.user.toast(can, ui.size.innerHTML, ui.cost.innerHTML, -1, value) }
{view: chat.ACTION}, meta.progress != undefined && {view: "progress", style: {width: width}, list: [ }, _target: ui._target,
{view: "current", style: {width: (meta.progress||0)/100*width}}, }); can.page.Select(can, ui.action, html.INPUT_FILE)[0].click(), silent && can.onmotion.hidden(can, ui._target); return action
]}, },
] }]) downloads: function(can, text, name, ext) { return text && can.user.download(can, URL.createObjectURL(new Blob([text])), name, ext) },
download: function(can, path, name, ext) {
var action = can.onappend._action(can, meta.action||[], ui.action, { var a = can.page.Append(can, document.body, [{type: html.A, href: path, download: can.core.Keys(name, ext)||path.split(nfs.PS).pop()}])._target
close: function(event) { can.page.Remove(can, action._target), action.timer.stop = true }, return a.click(), can.page.Remove(can, a), path
timer: can.core.Timer({interval: 100, length: (parseInt(meta.duration||1000))/100}, function(event, interval, index) { },
if (index > 30) { ui.duration.innerHTML = parseInt(index/10)+ice.PT+(index%10)+"s..." } toimage: function(can, name, target, silent) { var toast = can.user.toastProcess(can, "生成中...")
}, function() { action.close() }), _target: ui._target, ui: ui, can.require(["/require/modules/html2canvas/dist/html2canvas.min.js"], function() { toast.close()
}); can.onmotion.story.auto(can, ui._target) html2canvas(target||can._target).then(function (canvas) { var url = canvas.toDataURL(html.IMAGE_PNG)
silent? (can.user.download(can, url, name, nfs.PNG), can.user.toastSuccess(can)): can.user.toastImage(can, name, url)
can.onengine.signal(can, chat.ONTOAST, can.request({}, { })
title: meta.title, content: meta.content, })
time: can.base.Time(), fileline: can.misc.FileLine(2, 2), },
})) toastImage: function(can, name, url) { var toast = can.user.toast(can, {content: {img: url, style: {"max-height": window.innerHeight/2, display: html.BLOCK}}, title: name, duration: -1,
return action action: shy([cli.CLOSE, web.DOWNLOAD], function(event, button) {
}, can.user.input(event, can, [{name: mdb.NAME, value: name}], function(list) { can.user.download(can, url, list[0], nfs.PNG) })
share: function(can, msg, cmd) { }), resize: html.IMG,
can.run(msg._event, cmd||[ctx.ACTION, chat.SHARE], function(msg) { }) },
can.user.toast(can, {height: 300, width: 500, login: function(can, _cb, _msg) {
title: msg.Append(mdb.NAME), duration: -1, can.misc.CookieSessid(can, ""), can.misc.Cookie(can, "sessid", "")
content: msg.Append(mdb.TEXT), action: [cli.CLOSE], can.page.ClassList.add(can, document.body.parentNode, aaa.LOGIN), can.onimport.theme(can)
}), can.user.copy(msg._event, can, msg.Append(mdb.NAME)) function check() {
}) if (can.misc.CookieSessid(can) || can.user.info.sessid) { can.page.ClassList.del(can, document.body.parentNode, aaa.LOGIN), can.onimport.theme(can)
}, can.onmotion.clearFloat(can), can.onmotion.delay(can, function() { socket._close = true, socket.close() })
login: function(can, cb, method) { return can.base.isFunc(_cb) && _cb(), _cb = null, true
var ui = can.user.input({}, can, [ } can.core.Timer(1000, function() { check() })
{username: html.USERNAME}, {password: html.PASSWORD}, }
], function(event, button, data, list) { return { var ui, socket = can.ondaemon._init(can, "", aaa.LOGIN, function(event, msg, cmd, arg) {
"登录": function() { if (cmd == ice.MSG_SESSID) {
can.run({}, [aaa.LOGIN, data[html.USERNAME], data[html.PASSWORD]], function(msg) { if (!can.misc.CookieSessid(can, arg[0])) { can.user.info.sessid = arg[0] } check()
if (msg.Option(ice.MSG_USERNAME)) { } else if (cmd == cli.PWD) { if (check() || ui) { return } can._wss_name = can.ondaemon._list[0] = arg[0]
can.page.Remove(can, ui._target), can.base.isFunc(cb) && cb() var hassso = false
} else { var _list = [], list = {}; _msg.Table(function(value) { if (!value.order) { return }
can.user.toast(can, "用户名或密码错误") can.user.trans(can, kit.Dict(value.name, value.help))
} if (value.type == "oauth") { hassso = true }
}) if (value.type == cli.QRCODE) {
return true _list.push(value.name), list[value.name] = function(target) {
}, can.user.isWeiXin || can.page.Modify(can, target, arg[2])
"扫码": function() { }
can.misc.WSS(can, {type: html.CHROME, cmd: "pwd"}, function(event, msg, cmd, arg) { if (!msg) { return } } else if (value.type == mdb.PLUGIN) {
if (cmd == "pwd") { _list.push(value.name), list[value.name] = function(target) {
return can.user.toast(can, arg[2], arg[1], -1), msg.Reply() can.onappend.plugin(can, {space: value.space, index: value.index, args: can.core.Split(value.args), height: html.IFRAME_HEIGHT, width: html.IFRAME_HEIGHT, style: html.OUTPUT}, function(sub) {
} var run = sub.run; sub.run = function(event, cmds, cb) { var msg = can.request(event, {space: arg[0]}); can.page.exportValue(can, msg), run(event, cmds, cb) }
if (cmd == ice.MSG_SESSID) { }, ui.output)
return can.misc.CookieSessid(can, arg[0]), msg.Reply(), can.user.reload(true) }
} }
can.search(event, msg[ice.MSG_DETAIL]||[], function(msg) { msg.Reply() }) })
}) var _cmd = "space login "+arg[0]
}, ui = can.onappend.tabview(can, list, _list, can.page.Append(can, document.body, [{view: "input login float flex"}])._target)
"授权": function() { can.user.title(can.user.info.titles)
can.misc.WSS(can, {type: html.CHROME, cmd: "sso", "user.web": location.href}, function(event, msg, cmd, arg) { if (!msg) { return } can.page.Append(can, ui._target, [{view: [[html.DISPLAY, html.FLEX]], list: [
if (cmd == "pwd") { {text: [can.user.trans(can, "or command login", "或命令行授权: "), html.LABEL]},
return location.href = arg[1] {text: ["$ "+_cmd, "", html.ITEM], title: "点击复制,并后台执行此命令,即可登录", style: {cursor: "copy"}, onclick: function() { can.user.copy(event, can, _cmd) }},
} hassso && {text: [can.user.trans(can, "or oauth login", "或第三方授权: "), html.LABEL]},
if (cmd == ice.MSG_SESSID) { hassso && {view: [["sso", html.FLEX]], list: _msg.Table(function(value) {
return can.misc.CookieSessid(can, arg[0]), msg.Reply(), can.user.reload(true) return value.type == "oauth" && {view: [[html.ITEM, value.name, html.FLEX]], title: value.link, list: [
} {img: can.misc.Resource(can, value.icons)}, {text: can.user.trans(can, value.name, value.help)},
can.search(event, msg[ice.MSG_DETAIL]||[], function(msg) { msg.Reply() }) ], onclick: function() {
}) can.user.jumps(can.base.MergeURL(value.link, ice.BACK, location.href))
}, }, _init: function(target) {
"飞书": function() { location.href = "/chat/lark/sso" }, if (document.referrer) { var u = new URL(document.referrer)
}[button]() }, can.base.Obj(method, ["登录", "扫码", "授权"])) value.link.indexOf(u.origin) == 0 && can.onmotion.delay(can, function() { target.click() }, 300)
}
can.page.Modify(can, ui._target, {className: "input login", style: {left: (window.innerWidth-ui._target.offsetWidth)/2, top: window.innerHeight/6}}) }}
}, }) },
logout: function(can, force) { if (force||can.user.confirm("logout?")) { // {text: [can.user.info.titles]},
can.run({}, [ctx.ACTION, aaa.LOGOUT], function(msg) { ]}]), window.parent != window && window.innerHeight < 480 && can.onmotion.hidden(can, ui.output)
can.misc.Search(can, chat.SHARE)? can.misc.Search(can, chat.SHARE, ""): can.user.reload(true) can.page.style(can, ui._target, {
}) left: (can.page.width()-ui._target.offsetWidth)/2,
} }, top: can.user.isMobile? 20: can.page.height() < 480? (can.page.height()-ui._target.offsetHeight)/2: (can.page.height()-can.base.Min(ui._target.offsetHeight, html.IFRAME_HEIGHT)-html.HEADER_HEIGHT-html.ACTION_HEIGHT)/4+html.HEADER_HEIGHT,
})
toPNG: function(can, name, text, height, width) { }
if (text.indexOf("<svg") != 0) { })
text = '<svg xmlns="http://www.w3.org/2000/svg">'+text+"</svg>" },
} logout: function(can) { can.user.toastConfirm(can, aaa.LOGOUT, "", function() { can.runAction({}, aaa.LOGOUT, [], function(msg) {
var img = document.createElement(html.IMG) can.misc.Cookie(can, "user_uid", "")
img.onload = function() { can.misc.CookieSessid(can, ""), can.misc.Search(can, chat.SHARE)? can.misc.Search(can, chat.SHARE, ""): can.user.reload(true)
var canvas = document.createElement("canvas") }) }) },
canvas.height = height, canvas.width = width header: function(can) { if (!can._root) { return } var header = can._root.Header
canvas.getContext("2d").drawImage(img, 0, 0) var meta = {
time: !can.user.isMobile && {view: [[html.ITEM, "state", mdb.TIME, html.FLEX]], _init: function(target) {
var a = document.createElement("a") can.onappend.figure(can, {action: "date", _hold: true}, target, function(sub, value) {})
a.href = canvas.toDataURL("image/png") can.core.Timer({interval: 100}, function() { can.page.Modify(can, target, can.user.time(can, null, "%w %H:%M:%S")) })
a.download = name, a.click() }},
}, img.src = "data:image/svg+xml,"+encodeURIComponent(text) avatar: {view: [[html.ITEM, "state", aaa.AVATAR]], list: [{img: can.misc.Resource(can, can.user.info.avatar)}], onclick: function(event) { header && header.onaction.avatar(event, header) }},
}, usernick: {view: [[html.ITEM, "state", aaa.USERNICK, html.FLEX], "", can.user.info.usernick], onclick: function(event) { header && header.onaction.usernick(event, header) }, _init: function(target) {
copy: function(event, can, text) { can = can._fields? can.sup: can
if (navigator.clipboard) { var ok = false can.ui.head = target.parentNode
navigator.clipboard.writeText(text).then(function() { ok = true }) }},
if (ok) { return can.user.toastSuccess(can) } qrcode: {view: [[html.ITEM, "state", cli.QRCODE]], list: [{icon: icon.qrcode}], onclick: function(event) { var _can = can._fields? can.sup: can; _can.onaction["生成链接"](event, _can) }},
} }; return can.core.List(can.base.getValid(can.core.List(arguments).slice(1), [html.SPACE, mdb.TIME, aaa.AVATAR, aaa.USERNICK, cli.QRCODE]), function(item) { return meta[item] })
},
var input = can.page.Append(can, event.target.parentNode, [{type: html.TEXTAREA, value: text}]).first email: function(can) {
input.setSelectionRange(0,-1), input.focus(), document.execCommand("Copy") can.page.Select(can, document.body, html.IFRAME, function(target) {
can.page.Remove(can, input), can.user.toastSuccess(can) can.page.style(can, target, html.HEIGHT, can.page.height())
event.stopPropagation(), event.preventDefault() can.page.style(can, target, html.WIDTH, can.page.width())
}, })
carte: function(event, can, meta, list, cb, parent) { },
meta = meta||can.ondetail||can.onaction||{}, list = list&&list.length > 0? list: meta.list||[]; if (list.length == 0) { return }
cb = cb||function(event, item, meta) { var cb = meta[item]||meta["_engine"]; can.base.isFunc(cb) && cb(event, can, item) }
var ui = can.page.Append(can, document.body, [{view: chat.CARTE, style: {left: 0, top: 0}, onmouseleave: function(event) {
// can.page.Remove(can, ui._target)
}, list: can.core.List(list, function(item, index) {
return can.base.isString(item)? {view: html.ITEM, list: [{text: can.user.trans(can, item), click: function(event) {
can.user.isMobile && can.page.Remove(can, ui._target)
can.base.isFunc(cb) && cb(event, item, meta, index)
}, onmouseenter: function(event) {
carte._float && can.page.Remove(can, carte._float._target)
} }] }: {view: html.ITEM, list: [{text: can.user.trans(can, item[0])}], onmouseenter: function(event) {
var sub = can.user.carte(event, can, meta, item.slice(1), cb, carte)
carte._float && can.page.Remove(can, carte._float._target), carte._float = sub
can.onlayout.figure(event, can, sub._target, true)
} }
}) }] ); can.onlayout.figure(event, can, ui._target)
var carte = {_target: ui._target, _parent: parent}
null && can.onmotion.float.add(can, chat.CARTE, carte)
ui._target.onmouseover = function(event) {
event.stopPropagation(), event.preventDefault()
}
return event.stopPropagation(), event.preventDefault(), carte
},
carteRight: function(event, can, meta, list, cb, parent) {
var carte = can.user.carte(event, can, meta, list, cb, parent)
can.page.Modify(can, carte._target, {style: {
left: event.clientX-event.offsetX+event.target.offsetWidth-3,
top: carte._target.offsetTop-event.target.offsetHeight+5,
}})
return carte
},
carteClient: function(event, can, meta, list, cb, parent) {
var ui = can.user.carte(event, can, meta, list, cb, parent)
can.page.Modify(can, ui._target, {style: {left: event.clientX, top: event.clientY}})
},
input: function(event, can, form, cb, button) { // form [ string, array, object, {type: "select", values: []}
var msg = can.request(event)
var ui = can.page.Append(can, document.body, [{view: [html.INPUT], style: {left: 0, top: 0}, list: [
{view: [chat.OPTION, html.TABLE], list: can.core.List(form, function(item) {
item = can.base.isString(item)? {type: html.TEXT, name: item}: item.length > 0? {type: html.SELECT, name: item[0], values: item.slice(1)}: item
item.type = item.type||(item.values? html.SELECT: item.name == html.TEXT? html.TEXTAREA: html.TEXT)
item._init = function(target) {
item.run = function(event, cmds, cb) {
can.request(event, function() { var value = {_handle: ice.TRUE, action: msg.Option(chat.ACTION)}
can.page.Select(can, ui.table, "textarea,input,select", function(item) {
item.name && item.value && (value[item.name] = item.value)
}); return value
}, msg, can.Option()); can.run(event, cmds, cb, true)
}
target.value = target.value||(item.name&&(msg.Option(item.name)||can.Option(item.name)))||""
can.onappend.figure(can, item, target)
}
return {type: html.TR, list: [{type: html.TD, list: [{text: item._trans||can.user.trans(can, item.name)||""}]}, {type: html.TD, list: [can.page.input(can, item)]} ]}
})}, {view: chat.ACTION},
]}]); can.onlayout.figure(event, can, ui._target)
var action = can.onappend._action(can, button||[html.SUBMIT, html.CANCEL], ui.action, {
cancel: function(event) { can.page.Remove(can, ui._target) },
_engine: function(event, can, button) { action.submit(event, can, button) },
submit: function(event, can, button) { var data = {}, args = [], list = []
list = can.page.Select(can, ui.table, "textarea,input,select", function(item) {
return item.name && item.value && args.push(item.name, item.value), data[item.name] = item.value
})
var msg = can.request(event, {_handle: ice.TRUE})
can.base.isFunc(cb) && !cb(event, button, data, list, args) && action.cancel()
}, _target: ui._target,
})
can.page.Select(can, ui._target, "textarea,input", function(item, index) {
index == 0 && can.onmotion.focus(can, item)
})
return action
},
select: function(event, can, type, fields, cb, cbs) {
var msg = can.request(event, {fields: fields||"type,name,text"})
can.search(msg._event, ["Search.onimport.select", type, "", ""], function(list) {
can.core.Next(list, cb, cbs||function() {
can.user.toastSuccess(can)
})
})
},
upload: function(event, can) { var begin = new Date()
var ui = can.page.Append(can, document.body, [{view: html.UPLOAD, style: {left: 0, top: 0}, list: [
{view: html.ACTION}, {view: html.OUTPUT, list: [{view: "progress"}]},
{view: html.STATUS, list: [{view: html.SHOW}, {view: "cost"}, {view: "size"}]},
]}]); can.onlayout.figure(event, can, ui._target)
var action = can.onappend._action(can, [
{type: html.UPLOAD, onchange: function(event) {
action.show(event, 0, event.target.files[0].size, 0)
}}, cli.CLOSE,
], ui.action, {
close: function(event) { can.page.Remove(can, ui._target) },
begin: function(event) { begin = new Date()
var upload = can.page.Select(can, ui.action, "input[type=file]")
if (upload[0].files.length == 0) { return upload[0].focus() }
var msg = can.request(event, can.Option(), {_handle: "true"})
msg._upload = upload[0].files[0], msg._progress = action.show
can.run(event, [ctx.ACTION, html.UPLOAD], function(msg) {
can.user.toastSuccess(can), can.Update(), action.close()
}, true)
},
show: function (event, value, total, loaded) { now = new Date()
value == 0 && action.begin(event)
ui.show.innerHTML = value+"%"
ui.cost.innerHTML = can.base.Duration(now - begin)
ui.size.innerHTML = can.base.Size(loaded)+ice.PS+can.base.Size(total)
can.page.Modify(can, ui.progress, {style: {width: value*(ui.output.offsetWidth-2)/100}})
},
}); can.page.Select(can, ui.action, "input[type=file]")[0].click()
return action
},
download: function(can, path, name) {
var a = can.page.Append(can, document.body, [{type: html.A, href: path, download: name||path.split(ice.PS).pop()}]).first
a.click(), can.page.Remove(can, a)
},
downloads: function(can, text, name) { can.user.download(can, URL.createObjectURL(new Blob([text])), name) },
camera: function(can, msg, cb) {
navigator.getUserMedia({video: true}, cb, function(error) {
can.misc.Log(error)
})
},
}) })

View File

@ -1,19 +1,10 @@
{ {
"manifest_version": 2, "manifest_version": 2, "name": "volcanos", "version": "0.0.1",
"name": "volcanos", "version": "0.0.1", "background": {"page": "/publish/chrome/daemon.html"},
"background": {"page": "/publish/chrome/chrome.html"}, "browser_action": {"default_popup": "/publish/chrome/popup.html"},
"browser_action": {"default_popup": "/publish/chrome/popup.html"}, "content_scripts": [
"content_scripts": [{"matches": ["<all_urls>"], "css": [ {"matches": ["<all_urls>"], "permissions": [
"/page/can.css", "/publish/chrome/contexts.css" "tabs", "history", "cookies", "bookmarks", "contextMenus", "notifications", "http://localhost:9020/*"
], "js": [ ], "css": ["/publish/chrome/contexts.css"], "js": ["/proto.js", "/page/cache.js", "/publish/chrome/contexts.js"]}
"/page/can.js", "/publish/chrome/contexts.js" ]
]}], "permissions": [
"tabs",
"history",
"cookies",
"bookmarks",
"contextMenus",
"notifications",
"http://localhost:9020/*"
]
} }

View File

@ -1,714 +0,0 @@
body {
margin:0; padding:0;
background:black;
color:cyan;
}
a {
color:yellow;
}
h1, h2, h3 {
clear:both;
}
tr.show {
background:red;
}
h1:hover, h2:hover, h3:hover {
background:green; cursor:pointer;
}
.hide {
display:none;
}
.hidden {
display:none;
}
div.item {
cursor:pointer;
}
div.code {
background-color:#343a3445; color:white;
font-size:14px; font-family:monospace;
box-shadow: 4px 4px 20px 4px #626bd0;
border:solid 3px green; padding:10px;
text-align:left; white-space:pre;
clear:both; overflow:auto;
}
div.story {
text-align:left; white-space:pre;
}
div.story[data-type=spark] {
background-color:#2169a9a6; color:white;
font-size:14px; font-family:monospace;
box-shadow:4px 4px 10px 1px #626bd0;
margin:10px 0px; padding:4px 10px;
border-left:solid 4px blue;
overflow:auto; cursor:copy;
}
div.story[data-type=spark] span:hover {
box-shadow: 4px 4px 10px 1px #29318e;
background-color:#c10c8a;
}
p.story[data-type=brief] {
font-size:20px; font-family:cursive; font-weight:bolder;
}
select {
background-color:black; color:cyan;
font-size:14px; font-family:monospace;
box-shadow: 4px 4px 10px 1px #626bd0;
height:25px; padding:0 10px;
cursor:pointer;
}
option {
font-family:monospace;
}
textarea {
background-color:cyan;
width:400px; height:60px;
}
input[type=button] {
background-color:black; color:cyan;
font-family:monospace;
letter-spacing:4px;
padding-left:10px;
cursor:pointer;
}
input[type=button]:hover {
background-color:gray; color:cyan;
}
input[type=text] {
background-color:cyan; color:black;
box-shadow:4px 4px 10px 1px #626bd0;
height:21px; width:82px;
font-size:16px;
padding:0 4px;
}
input[type=text]:hover {
background-color:white;
}
input[name=date] {
width:150px;
}
input[name=path] {
width:160px;
}
input[name=line] {
width:40px;
}
input[name=text] {
width:160px;
}
input[name=url] {
width:320px;
}
input[name=cmd] {
background-color:black; color:white;
width:240px;
}
input[name=cmd]:hover {
background-color:white; color:black;
}
table.layout {
margin:0; border:0; padding:0;
border-spacing:0;
}
table.layout tr {
margin:0; border:0; padding:0;
}
table.layout th {
margin:0; border:0; padding:0;
}
table.layout td {
margin:0; border:0; padding:0;
vertical-align:top;
}
table.layout td.content {
position:relative;
}
table.layout div.toggle>div {
display: table-cell;
vertical-align: middle;
color:white;
height:95px;
}
table.layout div.toggle {
background:#e1aeae45;
height:100px; top:20%;
position:absolute;
}
table.layout div.toggle.display>div {
height:20px; width:100px;
text-align:center;
color:white;
}
table.layout div.toggle.display {
margin-top:-10px;
height:10px; width:100px;
position:sticky; left:20%;
border-top-left-radius:10px;
border-top-right-radius:10px;
}
table.layout div.toggle.project {
left:0px;
min-width:10px;
border-top-right-radius:10px;
border-bottom-right-radius:10px;
}
table.layout div.toggle.profile {
right:0px;
min-width:10px;
border-top-left-radius:10px;
border-bottom-left-radius:10px;
}
table.content {
font-size:14px; font-family:monospace;
border:0; white-space:pre;
overflow: auto;
}
table.content tr {
background-color:#04272f45;
}
table.content tr.select {
background-color:green;
}
table.content tr:hover {
background-color:green;
}
table.content th {
background-color:#0fbd45;
padding:2px 6px;
cursor:pointer;
}
table.content th:hover {
background-color:red;
}
table.content td {
padding:2px 6px;
max-width:800px;
overflow:auto;
/* white-space:break-spaces; */
}
table.content td.done {
background-color:green;
}
table.content td.select {
background-color:red;
}
table.content td:hover {
background-color:red;
}
td>input[type=button][name=create] {
background-color:blue;
}
td>input[type=button][name=remove] {
background-color:red;
}
td>input[type=button][name=start] {
background-color:blue;
}
td>input[type=button][name=stop] {
background-color:red;
}
legend {
box-shadow:4px 4px 20px 4px #626bd0;
cursor:pointer;
}
fieldset {
margin:0; border:0; padding:0;
}
fieldset>div.legend {
float:left; padding:0 10px; margin-right:3px;
height:25px; font-size:18px;
background-color:darkcyan;
cursor:pointer;
}
fieldset>form.option {
float:left;
display:contents;
}
fieldset>form.option>div.item {
float:left; margin-right:3px;
min-height:25px; vertical-align:middle;
}
fieldset>form.option>div.item>label {
display:none;
}
fieldset>form.option>div.item input.args.char {
width:20px;
}
fieldset>form.option>div.item input.args.tiny {
width:40px;
}
fieldset>form.option>div.item input.args.long {
width:240px;
}
fieldset>form.option>div.item input.args.full {
width:480px;
}
fieldset>form.option>div.item input.args[name=ID] {
width:48px;
}
fieldset>form.option>div.item input.args[name=id] {
width:48px;
}
fieldset>form.option>div.item input.args[name=limit] {
width:48px;
}
fieldset>form.option>div.item input.args[name=offset] {
width:48px;
}
fieldset>form.option>div.item input.args[name=offend] {
width:48px;
}
fieldset>form.option>div.item.textarea {
clear:both; margin-top:4px;
}
fieldset>div.action {
float:left; display:contents;
}
fieldset>div.action>div.item {
float:left; margin-right:3px;
vertical-align:middle;
}
fieldset>div.action>div.item.space {
width:10px;
}
fieldset div.action>div.item>label {
display:none;
}
fieldset>div.status {
clear:both;
}
fieldset>div.status>div.item {
float:left; padding:4px;
height:18px;
}
fieldset>div.status>div.item>label {
font-size:10px; color:#bdb8b8e0;
}
fieldset>div.output {
clear:both; overflow:auto;
position:relative;
}
fieldset>div.output div.project {
min-width:88px; max-width:240px;
float:left; overflow:auto;
}
fieldset>div.output div.project div.item {
padding:2px 10px; text-align:left;
clear:both; cursor:pointer;
white-space:pre;
}
fieldset>div.output div.project div.item.select {
background-color:red;
}
fieldset>div.output div.project div.item:hover {
background-color:red;
}
fieldset>div.output div.project div.list {
margin-left:10px;
}
fieldset>div.output td.project {
background-color:#435f8c8c;
}
fieldset>div.output td.profile {
background-color:#71909c91;
}
fieldset>div.output td.profile div.profile {
overflow:auto;
}
fieldset.panel>legend {
display:none;
}
fieldset.plugin {
box-shadow:2px 2px 10px 4px #626bd0;
background-color:#061c3c9e;
margin:10px; padding:10px;
}
fieldset.plugin>div.status {
border-top:1px solid darkcyan;
}
fieldset.output {
margin:0; padding:0;
}
fieldset.output>legend {
display:none;
}
fieldset.output>form.option {
display:none;
}
fieldset.output>div.action {
display:none;
}
fieldset.output>div.status {
display:none;
}
fieldset.story>legend {
display:block;
padding:2px 20px;
letter-spacing:4px;
}
fieldset.story>div.status {
border-top:1px solid darkcyan;
}
fieldset.float {
background-color:#023531cf;
margin:0px; padding:0px;
position:absolute;
}
fieldset.float>legend {
display:none;
}
fieldset.float table {
color:white;
}
body>fieldset.input {
background-color:#0d4142a6;
position:fixed; top:32px;
}
body>fieldset.input div.output {
max-height:400px;
}
body>fieldset.input table {
color:white;
}
body>fieldset.input td {
word-break:keep-all;
}
body>fieldset.input.key {
}
body>fieldset.input.date {
}
body>fieldset.input.date table {
text-align:center;
width:280px;
}
body>fieldset.input.date table td:hover {
background-color:red;
}
body>div.toast {
background:#0e3369b3; color:yellow;
padding:5px; overflow:auto;
position:fixed;
}
body>div.toast a {
color:yellow;
}
body>div.toast div.title {
float:left; word-break:break-all;
color:#cae850; font-size:14px;
cursor:copy;
}
body>div.toast div.duration {
color:gray; font-size:14px;
float:right;
cursor:pointer;
}
body>div.toast div.content {
text-align:center;
white-space:pre;
clear:both;
}
body>div.toast div.action div.item {
float:left;
}
body>div.toast div.progress {
height:10px; border:solid 2px green;
margin-left:-2px;
clear:both;
}
body>div.toast div.progress div.current {
height:10px; background:red;
}
body>div.carte {
position:fixed;
background:#295b61;
color:white;
padding:4px;
min-width:80px;
z-index:0;
}
body>div.carte div.item {
padding:3px 12px;
}
body>div.carte div.item:hover {
background:red;
}
body>div.input {
position:fixed;
background-color:#0d4142a6;
z-index:0;
}
body>div.input input[type=text] {
width:171px;
}
body>div.input input[name=username] {
width:171px;
}
body>div.input input[name=password] {
width:171px;
}
body>div.input textarea {
box-shadow: 4px 4px 10px 1px #626bd0;
border:2px inset #14a58e;
width:171px; height:60px;
background-color: cyan;
padding:4px;
}
body>div.input div.item {
float:left;
}
body>div.input.login {
padding:10px;
}
body>div.input.login input {
font-size:18px;
}
body>div.upload {
background:black; color:yellow;
position:fixed;
padding:5px;
}
body>div.upload div.item {
float:left;
}
body>div.upload div.output {
border:solid 1px red;
clear:both;
}
body>div.upload div.progress {
width:0; height:10px;
background:red;
}
body>div.upload div.status div.cost {
float:left;
}
body>div.upload div.status div.show {
float:right;
}
body>div.upload div.status div.size {
text-align:center;
}
body>div.upload input[type=file] {
width: 240px;
}
body.white {
background-color:rgba(5,34,56,0.75); color:white;
}
body.white select {
background-color:#99CC66; color:white;
border-radius:10px 10px 10px 10px;
border:2px solid #99CC66;
}
body.white input[type=button] {
background-color:#FF9900; color:white;
border:2px solid #FF9900;
border-radius:10px;
}
body.white input[type=button]:hover {
background-color:#FFCC33;
border:2px solid #FFCC33;
}
body.white input[type=text] {
background-color:white; color:black;
border:2px solid #14a58e;
border-radius:6px;
}
body.white input[type=text]:hover {
background-color:cyan;
}
body.white input[name=cmd] {
background-color:black; color:white;
width:240px;
}
body.white input[name=cmd]:hover {
background-color:white; color:black;
}
body.white table {
color:black;
}
body.white table tr {
background-color:#e1f1ff1f;
}
body.white table th {
background-color:#99CCFF;
}
body.white table.content tr:hover {
background-color:green;
}
body.white table input[type=button][value=结束] {
background:red;
}
body.white table input[type=button][value=停止] {
background:red;
}
body.white table input[type=button][value=启动] {
background:#52ce78;
}
body.white td>input[type=button][name=create] {
background-color:blue;
}
body.white td>input[type=button][name=remove] {
background-color:red;
}
body.white fieldset>div.legend {
/* background-color:honeydew; */
}
body.white fieldset>div.status>div.item>label {
font-size:10px; color:#cefbfbe0;
}
body.white fieldset.Action {
color:black;
}
body.white fieldset.Action>div.action {
color:white;
}
body.white fieldset.Action>div.action div.item {
height:21px;
}
body.white fieldset.Action fieldset.plugin {
background-color:#ffffff78;
}
body.white fieldset.Action fieldset.plugin legend {
background-color:#339999; color:white;
border-radius:10px 10px 10px 10px;
}
body.white fieldset.Action fieldset.plugin legend:hover {
background-color:#6ee4e4;
}
body.white>div.input textarea {
border-radius:6px;
border:2px solid #14a58e;
}
body.print {
background-color:white;
color:black;
}
body.print a {
color:blue;
}
body.print select {
box-shadow:0px 0px 0px 0px #626bd0;
}
body.print input[type=text] {
box-shadow:0px 0px 0px 0px #626bd0;
}
body.print div.code {
background-color:white;
}
body.print legend {
box-shadow:0px 0px 0px 0px #626bd0;
}
body.print fieldset.Header {
background-color:white;
color:black;
}
body.print fieldset.River {
background-color:white;
color:black;
}
body.print fieldset.River>div.output div.list div.item {
background-color:white;
}
body.print fieldset.River>div.output div.item.select {
background-color:white;
border:solid 2px red;
}
body.print fieldset.Action {
background-color:white;
}
body.print fieldset.Action fieldset.plugin {
padding-left:40px;
}
body.print fieldset.Footer {
background-color:white;
color:black;
}
body.mobile select {
font-size:18px;
margin-top:5px;
}
body.mobile input {
font-size:18px;
}
body.mobile input[type=text] {
margin-top:5px;
height:26px;
}
body.mobile fieldset.Header.head {
position:fixed; top:0;
width:-webkit-fill-available;
height:2em; font-size:24px;
background-color:#000000b8;
}
body.mobile fieldset.Header.head div.output {
height:2em;
}
body.mobile fieldset.Header>div.output>div {
height:1.5em;
}
body.mobile fieldset.Header>div.output div.menu {
height:1.5em;
}
body.mobile fieldset.Header.head div.state.time {
display:none;
}
body.mobile fieldset.River.left {
position:fixed; top:48px;
background-color:#243950bf;
min-width:240px; font-size:24px;
/* width:-webkit-fill-available; */
}
body.mobile fieldset.River>div.output div.list div.item {
font-size:24px;
}
body.mobile fieldset.Action.main.cmd {
margin-top:0; margin-bottom:0;
}
body.mobile fieldset.Action.main {
margin-top:48px; margin-bottom:64px;
}
body.mobile fieldset.Footer.foot {
position:fixed; bottom:0;
width:-webkit-fill-available;
height:64px; font-size:24px;
background-color:#000000b8;
display:none;
}
body.mobile.landscape fieldset.Header.head {
position:unset;
}
body.mobile.landscape fieldset.Header.head div.state.time {
display:block;
}
body.mobile.landscape fieldset.Action.main {
margin-top:0; margin-bottom:0;
}
body.mobile.landscape fieldset.Footer.foot {
position:unset;
}
body.mobile>div.carte {
font-size:24px;
}
body.mobile>div.input.login input {
font-size:24px
}
body.en input[type=button] {
letter-spacing:2px;
}

View File

@ -1,14 +0,0 @@
<!DOCTYPE html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=0.8,user-scalable=no">
<meta charset="utf-8"><title>volcanos</title>
<link rel="shortcut icon" type="image/ico" href="/favicon.ico">
<link rel="stylesheet" type="text/css" href="/page/cache.css">
<link rel="stylesheet" type="text/css" href="/page/index.css">
</head>
<body>
<script src="/proto.js"></script>
<script src="/page/cache.js"></script>
<script src="/page/index.js"></script>
</body>

View File

@ -1,116 +0,0 @@
Volcanos({name: "chat", panels: [
{name: "Header", help: "标题栏", pos: chat.HEAD, state: ["time", "usernick", "avatar"]},
{name: "River", help: "群聊组", pos: chat.LEFT, action: ["create", "refresh"]},
{name: "Action", help: "工作台", pos: chat.MAIN},
{name: "Footer", help: "状态条", pos: chat.FOOT, state: ["ncmd"]},
{name: "Search", help: "搜索框", pos: chat.AUTO},
], main: {name: "Header", list: ["/publish/order.js"]}, river: {
serivce: {name: "运营群", storm: {
wx: {name: "公众号 wx", list: [
{name: "微信公众号", help: "wx", index: "web.wiki.word", args: ["usr/icebergs/misc/wx/wx.shy"]},
]},
mp: {name: "小程序 mp", list: [
{name: "微信小程序", help: "mp", index: "web.wiki.word", args: ["usr/icebergs/misc/mp/mp.shy"]},
]},
lark: {name: "机器人 lark", list: [
{name: "飞书机器人", help: "lark", index: "web.wiki.word", args: ["usr/icebergs/misc/lark/lark.shy"]},
]},
}},
product: {name: "产品群", storm: {
office: {name: "办公 office", list: [
{name: "feel", help: "影音媒体", index: "web.wiki.feel"},
{name: "draw", help: "思维导图", index: "web.wiki.draw"},
{name: "data", help: "数据表格", index: "web.wiki.data"},
{name: "plan", help: "计划任务", index: "web.team.plan"},
{name: "think", help: "智库", index: "web.wiki.word", args: ["usr/learning/"]},
{name: "index", help: "索引", index: "web.wiki.word", args: ["usr/learning/index.shy"]},
{name: "context", help: "编程", index: "web.wiki.word", args: ["src/main.shy"]},
]},
english: {name: "英汉 english", list: [
{name: "english", help: "英汉", index: "web.wiki.alpha.alpha", args: ["word", "hi"]},
{name: "chinese", help: "汉英", index: "web.wiki.alpha.alpha", args: ["line", "你好"]},
{name: "wubi", help: "五笔", index: "web.code.input.wubi", args: ["word", "wqvb"]},
{name: "wubi", help: "五笔", index: "web.code.input.wubi", args: ["line", "你好"]},
]},
learning: {name: "学习 learning", list: [
{name: "golang", help: "编程", index: "web.wiki.word", args: ["usr/golang-story/src/main.shy"]},
{name: "tmux", help: "粘贴", index: "web.code.tmux.text"},
{name: "study", help: "学习", index: "web.wiki.word", args: ["usr/learning/study.shy"]},
]},
chrome: {name: "爬虫 chrome", list: [
{name: "feel", help: "网页爬虫", index: "web.wiki.feel", args: ["spide/"], feature: {
display: "/plugin/local/wiki/feel.js",
height: 200, limit: 3,
}},
{name: "cached", help: "爬虫缓存", index: "web.code.chrome.cache", args: []},
{name: "spided", help: "网页爬虫", index: "web.code.chrome.spide", args: location && location.protocol && location.protocol=="chrome-extension:"? ["1", "", "spide"]: ["1"]},
{name: "modify", help: "编辑页面", index: "web.code.chrome.modify", args: []},
]},
}},
project: {name: "研发群", storm: {
studio: {name: "研发 studio", list: [
{name: "vimer", help: "编辑器", index: "web.code.vimer", args: ["src/", "main.go"], _action: ["autogen", "compile", "binpack"]},
{name: "repos", help: "代码库", index: "web.code.git.status"},
{name: "plan", help: "任务表", index: "web.team.plan"},
{name: "ctx", help: "上下文", index: "web.wiki.word", args: ["src/main.shy"]},
]},
web: {name: "网页 web", list: [
{name: "HTML5", help: "浏览器", index: "web.wiki.word", args: ["usr/icebergs/misc/chrome/chrome.shy"]},
]},
cli: {name: "命令 cli", list: [
{name: "bash", help: "命令行", index: "web.wiki.word", args: ["usr/icebergs/misc/bash/bash.shy"]},
{name: "git", help: "代码库", index: "web.wiki.word", args: ["usr/icebergs/misc/git/git.shy"]},
{name: "vim", help: "编辑器", index: "web.wiki.word", args: ["usr/icebergs/misc/vim/vim.shy"]},
{name: "tmux", help: "命令行", index: "web.wiki.word", args: ["usr/icebergs/misc/tmux/tmux.shy"]},
]},
linux: {name: "系统 linux", list: [
{name: "idc", help: "平台", index: "web.wiki.word", args: ["usr/linux-story/idc/idc.shy"]},
{name: "iso", help: "系统", index: "web.wiki.word", args: ["usr/linux-story/iso/iso.shy"]},
{name: "iot", help: "设备", index: "web.wiki.word", args: ["usr/linux-story/iot/iot.shy"]},
{name: "cli", help: "命令", index: "web.wiki.word", args: ["usr/linux-story/cli/cli.shy"]},
{name: "linux", help: "系统", index: "web.wiki.word", args: ["usr/linux-story/src/main.shy"]},
]},
nginx: {name: "代理 nginx", list: [
{name: "nginx", help: "代理", index: "web.wiki.word", args: ["usr/nginx-story/src/main.shy"]},
]},
context: {name: "编程 context", list: [
{name: "golang", help: "编程", index: "web.wiki.word", args: ["usr/golang-story/src/main.shy"]},
]},
redis: {name: "缓存 redis", list: [
{name: "redis", help: "缓存", index: "web.wiki.word", args: ["usr/redis-story/src/main.shy"]},
{name: "kafka", help: "队列", index: "web.wiki.word", args: ["usr/redis-story/src/kafka/kafka.shy"]},
]},
mysql: {name: "存储 mysql", list: [
{name: "mysql", help: "数据存储", index: "web.wiki.word", args: ["usr/mysql-story/src/main.shy"]},
{name: "clickhouse", help: "数据存储", index: "web.wiki.word", args: ["usr/mysql-story/src/clickhouse/clickhouse.shy"]},
]},
}},
profile: {name: "测试群", storm: {
website: {name: "定制 website", index: [
"web.chat.div", "web.chat.website",
]},
release: {name: "发布 release", index: [
"web.code.publish", "web.code.compile", "web.code.autogen", "web.code.git.server",
]},
research: {name: "测试 research", index: [
"web.code.favor", "web.code.bench", "web.code.pprof",
"web.code.case",
]},
}},
operate: {name: "运维群", storm: {
aaa: {name: "权限 aaa", index: [
"user", "totp", "sess", "role",
]},
web: {name: "应用 web", index: [
"serve", "space", "dream", "route",
"share", "spide", "cache", "story",
]},
cli: {name: "系统 cli", index: [
"qrcode", "daemon", "system", "runtime",
]},
nfs: {name: "文件 nfs", index: [
"cat", "dir", "tail", "trash",
]},
}},
},
})

View File

@ -1,96 +1,28 @@
fieldset.Action { fieldset.Action { min-width:var(--project-width); }
background-color:#7299a28c; fieldset.Action>div.output { overflow-x:hidden; }
min-width:160px; fieldset.Action>div.action:not(.flex) { width:100%; display:none; background-color:var(--plugin-bg-color); }
} fieldset.Action>div.action div.item { font-style:italic; font-size:1.1rem; padding:10px 20px; }
fieldset.Action>div.action { fieldset.Action.tabs>div.action { display:flex; justify-content:center; display:none; }
display:none; fieldset.Action.tabs>div.output>fieldset>legend { display:none; }
} fieldset.Action.tabs>div.output>fieldset.plugin:not(.select) { display:none; }
fieldset.Action>div.action.tabs { fieldset.Header div.Action { display:contents; }
width:-webkit-fill-available; fieldset.Action.tabview:not(.cmd)>div.output>fieldset.plugin>legend { float:left !important; }
background-color:#159cc7b0; fieldset.Action.tabview>div.output>fieldset.plugin:not(.select) { display:none; }
display:block; height:28px; fieldset.Action.vertical>div.output>fieldset.plugin { float:left; }
padding:0; margin:0; fieldset.Action.horizon>div.output>fieldset.plugin { float:left; }
position:absolute; fieldset.Action.horizon>div.output>fieldset.plugin>div.status { display:none; }
} fieldset.Action.flow>div.output>fieldset.plugin { float:left; }
fieldset.Action>div.action div.item { fieldset.Action.free>div.output>fieldset.plugin { position:absolute; z-index:5; }
padding:4px; margin:0; fieldset.Action.free>div.output>fieldset.plugin.select { z-index:9; }
} fieldset.Action.free>div.output { overflow:hidden; }
fieldset.Action>div.action div.item:hover { fieldset.Action.grid>div.output>fieldset.plugin { float:left; }
border-bottom:solid 2px red; fieldset.Action.grid>div.output>fieldset.plugin>div.status { display:none; }
background-color:#2e515f; fieldset.Action.tabview>div.project.toggle { display:none; }
} fieldset.Action.vertical>div.project.toggle { display:none; }
fieldset.Action>div.action div.item.select { fieldset.Action.horizon>div.project.toggle { display:none; }
border-bottom:solid 2px red; fieldset.Action.free>div.project.toggle { display:none; }
background-color:#2e515f; fieldset.Action.grid>div.project.toggle { display:none; }
} fieldset.Action>div.toggle.project { padding-top:50px; height:150px; top:30%; }
body:not(.mobile) fieldset.Action>div.project.toggle { display:none; }
fieldset.Action div.output fieldset.plugin.fixed { body.mobile fieldset.Action>div.project.toggle { top:60%; }
position:fixed; // body.mobile fieldset.Action>div.action div.item { display:none; }
left:0px;
top:0px;
margin:0px;
padding:0px;
background-color:black;
height: -webkit-fill-available;
width: -webkit-fill-available;
overflow: auto;
background-color: #061c3cd9;
}
fieldset.Action div.output.tabs {
margin-top:28px;
}
fieldset.Action div.output.flow fieldset.plugin {
float:left;
}
fieldset.Action div.output.grid fieldset.plugin {
width:480px; height:320px; overflow:auto;
float:left;
}
fieldset.Action div.output.grid fieldset.plugin>div.output {
width:480px; height:320px; overflow:auto;
}
fieldset.Action div.output.tabs fieldset.plugin {
display:none;
float:left;
}
fieldset.Action div.output.tabs fieldset.plugin.select {
display:block;
}
fieldset.Action div.output.free fieldset.plugin {
position:absolute;
}
fieldset.Action div.output.free fieldset.plugin.select {
display:block;
}
fieldset.Action div.output fieldset.plugin:hover {
box-shadow:4px 4px 12px 6px #626bd0;
}
fieldset.Action div.output fieldset.plugin legend {
font-size:16px; font-family:monospace;
margin-top:4px 5px; padding:2px 20px;
background-color:#0c739cd9;
}
fieldset.Action div.output fieldset.plugin legend:hover {
background:red;
}
fieldset.panel.cmd>div.legend {
display:none;
}
fieldset.panel.cmd>div.output>fieldset.plugin {
margin:0; padding:0;
}
fieldset.panel.cmd>div.output>fieldset.plugin>legend {
display:none;
}
fieldset.panel.cmd>div.output>fieldset.plugin>div.legend {
float:left; padding:0 10px; margin-right:3px;
height:25px; font-size:18px;
background-color:darkcyan;
cursor:pointer;
}
body.white fieldset.panel.cmd>div.output>fieldset.plugin>div.legend {
background-color:honeydew;
}

View File

@ -1,238 +1,204 @@
Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg) { (function() { const ALL = "all", TABS = "tabs", TABVIEW = "tabview", VERTICAL = "vertical", HORIZON = "horizon", GRID = "grid", FREE = "free", FLOW = "flow", PAGE = "page", CAN_LAYOUT = "can.layout"
var river = can.Conf(chat.RIVER), storm = can.Conf(chat.STORM) Volcanos(chat.ONIMPORT, {
can.onmotion.clear(can), can.core.Next(msg.Table(), function(item, next) { item.type = chat.PLUGIN _init: function(can, msg) { var river = can.Conf(chat.RIVER), storm = can.Conf(chat.STORM), list = can.db.list
item.height = parseInt(can.Conf(html.HEIGHT))-240, item.width = parseInt(can.Conf(html.WIDTH))-40 var _select; can.onmotion.clear(can), can.onaction.layout(can, list[3])
item.feature = can.base.Obj(item.feature||item.meta), item.inputs = can.base.Obj(item.inputs||item.list) can.core.Next(msg.Table(), function(item, next, index) { item.type = chat.PLUGIN, item.mode = can.Mode(); if (item.deleted == ice.TRUE) { return next() }
if (msg.Length() == 1) { item.height = can.ConfHeight()-can.Conf(html.MARGIN_Y), can.base.isIn(item.index, web.CHAT_MACOS_DESKTOP, web.CHAT_MESSAGE, web.WIKI_PORTAL) && (item.style = html.OUTPUT) }
can.onappend.plugin(can, item, function(sub, meta, skip) { can.base.isIn(item.index, ssh.CLOUD_PROFILE) && (item.style = html.OUTPUT)
can.onimport._plugin(can, river, storm, sub, meta), skip || next() if (list.length == 0) {
}) can.user.info.nodetype == web.SERVER && item._command == web.DREAM && (list = [river, storm, item._command])
}, function() { can.user.info.nodetype == web.WORKER && item._command == web.VIMER && (list = [river, storm, item._command])
can.onaction.layout(can, can.misc.Search(can, chat.LAYOUT)||can.Conf(chat.LAYOUT)) }
!can.user.isMobile && can.onimport._menu(can, msg) can.onappend.plugin(can, item, function(sub, meta, skip) {
}) can.user.isMobile || sub.Conf(ice.AUTO, cli.DELAY)
}, if (msg.detail && can.base.isIn(meta.index, "can._notfound")) { sub.Conf(ctx.INDEX, msg.detail[index+3]) }
_plugin: function(can, river, storm, sub, meta) { sub.run = function(event, cmds, cb) { return can.run(can.request(event, {pod: meta.pod||meta.space}), (can.base.beginWith(meta.index, "can.")? [meta.index]: [river, storm, meta.id||meta.index]).concat(cmds), cb) }
sub.run = function(event, cmds, cb) { var msg = sub.request(event); cmds = cmds||[] sub.onexport.output = function() { msg.Length() > 1 && can.onexport.isauto(can) && can.page.style(can, sub._output, html.HEIGHT, "", html.MAX_HEIGHT, ""), can.onaction.layout(can, list[3]) }
var toast = msg.Option("_toast") && can.user.toast(can, msg.Option("_toast"), "", -1) can.onaction.layout(can, list[3]), can.onimport._tabs(can, sub, meta), can._plugins = (can._plugins||[]).concat([sub])
return can.run(event, can.misc.concat([river, storm, meta.id||meta.index||can.core.Keys(meta.key, meta.name)], cmds), function(msg) { can.onexport.layout(can) && list[0] == river && list[1] == storm? (can.base.isIn(list[2], sub.ConfIndex()) && (_select = sub)): (index == 0 && (_select = sub)), _select = _select||sub, skip || next()
toast && toast.close(), can.base.isFunc(cb) && cb(msg) })
}) }, function() { can.onaction.layout(can, list[3]), _select._tabs.click() })
}, can._plugins = (can._plugins||[]).concat([sub]) },
_tabs: function(can, sub, meta) { var _init = true
can.page.Modify(can, sub._output, {style: {"max-width": meta.width}}) var tabs = [{view: [[html.TABS, meta.name], "", can.user.trans(can, meta.name, meta.help)], title: meta.help, onclick: function(event) { can._current = sub
can.page.Append(can, can._action, [{view: [html.ITEM, html.DIV, meta.name], onclick: function(event) { can.onmotion.select(can, can._output, html.FIELDSET_PLUGIN, sub._target)
can.onmotion.select(can, can._output, "fieldset.plugin", sub._target) can.onmotion.select(can, can._action, html.DIV_ITEM, sub._tabs)
can.onmotion.select(can, can._action, "div.item", event.target) can.onmotion.select(can, can._header_tabs, html.DIV_TABS, sub._header_tabs)
}}]) can.user.mod.isPod && can.user.title(["后台", sub.ConfHelp(), can.user.info.titles].join(" "))
// can.onmotion.delay(can, function() { sub._header_tabs.scrollIntoViewIfNeeded() })
sub._option.dataset = sub._option.dataset||{} var layout = can.onexport.layout(can); layout == FREE || (can._output.scrollTop = sub._target.offsetTop-10)
meta.id && (sub._option.dataset.id = meta.id) can.isCmdMode() || can.misc.SearchHash(can, can.Conf(chat.RIVER), can.Conf(chat.STORM), sub.ConfIndex(), layout)
sub._target.Meta = meta sub.Conf(ice.AUTO) == cli.DELAY && sub._output.innerHTML == "" && sub.Update(event)
}, sub.onimport.size(sub, can.ConfHeight()-can.Conf(html.MARGIN_Y), can.ConfWidth()-can.Conf(html.MARGIN_X), can.onexport.isauto(can))
_menu: function(can, msg) { if (can.user.mod.isPod||can.user.isMobile) { return } can.onengine.signal(can, "onindex", can.request(_init? {target: event.target, type: "click", isTrusted: true}: event, {index: sub.ConfIndex()})), _init = false
can._menu && can.page.Remove(can, can._menu) // can.onengine.signal(can, "onevent", can.request(_init? {target: event.target, type: "click", isTrusted: true}: event)), _init = false
can._menu = can.search({}, ["Header.onimport.menu", ctx.ACTION].concat( }, oncontextmenu: sub._legend.onclick}]; sub._header_tabs = can.page.Append(can, can._header_tabs, tabs)._target, sub._tabs = can.page.Append(can, can._action, tabs)._target
can.base.Obj(msg.Option("menus"), [ },
["help", "tutor", "manual", "service", "devops", "refer"], _menu: function(can, msg) { if (can.user.isMobile) { return } if (!can.user.isTechOrRoot(can)) { return }
]) var target = can.setHeaderMenu(can.base.Obj(can.Conf(chat.MENUS)||msg.Option(chat.MENUS), can.onaction._menus), function(event, button, list) { list && can.core.CallFunc([can.onaction, list[0]], [can, button]) })
), function(event, button, list) { can.onmotion.hidden(can, can._header_tabs = can.page.Append(can, target, ["_tabs"])._target)
list[0] == "help"? can.user.open("/help/"+button+".shy"): can.onaction.layout(can, button) },
})
},
_share: function(can, share) { if (!share) { return }
can.run({}, ["_share", share], function(msg) {
can.user.topic(can, can.misc.Search(can, chat.TOPIC)||msg.Option(chat.TOPIC))
can.user.title(can.misc.Search(can, chat.TITLE)||msg.Option(chat.TITLE))
can.onaction.layout(can, "auto")
if (msg[mdb.INDEX].length == 1) {
can.user.mod.isCmd = true, can.page.ClassList.add(can, can._target, "cmd")
can.page.Select(can, document.body, "fieldset.panel", function(item) {
item != can._target && can.onmotion.hidden(can, item)
})
can.Conf({height: window.innerHeight, width: window.innerWidth+40})
} else {
can.Conf({height: window.innerHeight, width: window.innerWidth})
}
can.Conf(chat.RIVER, "_share"), can.Conf(chat.STORM, share)
can.onimport._init(can, msg)
})
},
}) })
Volcanos("onengine", {help: "解析引擎", list: [], _engine: function(event, page, msg, can, cmds, cb) { Volcanos(chat.ONACTION, {
if (!can._root.river) { return false } _init: function(can, target) { can.db.list = can.misc.SearchHash(can)
var list = can._root.river; var river = list[cmds[0]] can.db.list.length == 0 && can.misc.Search(can, chat.RIVER) && can.misc.Search(can, chat.STORM) && (can.db.list = [can.misc.Search(can, chat.RIVER), can.misc.Search(can, chat.STORM)])
var storm = river && river.storm[cmds[1]] can.Conf(html.MARGIN_X, 2*html.PLUGIN_PADDING+2*html.PLUGIN_MARGIN), can.Conf(html.MARGIN_Y, 2*html.PLUGIN_PADDING+2*html.PLUGIN_MARGIN+html.ACTION_HEIGHT)
if (!storm || cmds.length != 2) { return false } can.core.List(["ontouchstart", "ontouchmove", "ontouchend"], function(item) {
can.onengine.listen(can, item, function(event, msg) { can.onaction[item](event, can), can.onengine.signal(can, chat.ONACTION_TOUCH, msg) }, target)
})
can._toast = can.page.Append(can, can._target, ["toast"])._target
},
onsize: function(can, msg, height, width) { can.Conf({height: can.base.Min(height, 240), width: width})
can.page.style(can, can._toast, html.MAX_HEIGHT, can.page.height()-can.getHeaderHeight()-can.getFooterHeight()-(html.PLUGIN_MARGIN+html.PLUGIN_PADDING+html.ACTION_HEIGHT))
},
onlogin: function(can, msg) {
can.Conf(html.MARGIN_Y, 2*html.PLUGIN_PADDING+2*html.PLUGIN_MARGIN+html.ACTION_HEIGHT)
can.Conf(html.MARGIN_X, 2*html.PLUGIN_PADDING+2*html.PLUGIN_MARGIN)
can.onimport._menu(can, msg), can.onkeymap._build(can)
can._root.River && can.onmotion.delay(can, function() { if (can.Mode()) { return }
var gt = can.page.unicode.next, lt = can.page.unicode.prev, river = can._root.River._target
var target = can.page.Append(can, can._target, [{view: [[html.TOGGLE, chat.PROJECT], "", can.page.isDisplay(river)? lt: gt], onclick: function(event) {
can.page.Modify(can, target, (can._river_show = can.onmotion.toggle(can, river))? lt: gt), can.onaction.layout(can)
can.misc.sessionStorage(can, "river:hide", can._river_show? "": ice.TRUE)
}}])._target; can._toggle = target
can.misc.sessionStorage(can, "river:hide") == ice.TRUE && target.click()
}); if (!can.Conf(chat.TOOL) && !can.user.mod.isCmd) { return }
if (can.base.beginWith(location.pathname, "/share/")) { can._names = location.pathname }
can.Conf(chat.TOOL)? can.onappend.layout(can, can.core.List(can.Conf(chat.TOOL), function(item, index, list) { item.type = chat.PLUGIN
if (list.length == 1) { can.user.mod.cmd = item.index
can.onaction._onaction_cmd(can), item.mode = chat.CMD, item.opts = can.misc.Search(can)
can.onappend.style(can, ice.CMD, document.body), can.onappend.style(can, item.index, document.body)
} return item
}), FLOW).layout(can.page.height(), can.page.width()): can.runAction(can.request(), ctx.COMMAND, [], function(msg) {
if (msg.Length() == 1) { can.onaction._onaction_cmd(can) } can.onimport._init(can, msg)
})
},
onstorm_select: function(can, msg, river, storm) { can.misc.SearchHash(can, river, storm)
if (can.onmotion.cache(can, function(save, load) { save({plugins: can._plugins, current: can._current}), can._plugins = []
return load(can.core.Keys(can.Conf(chat.RIVER, river), can.Conf(chat.STORM, storm)), function(bak) { can._plugins = bak.plugins, can._current = bak.current })
}, can._output, can._action, can._header_tabs)) {
if (msg.Option(web.REFRESH) != ice.TRUE) { return can._current && can._current._tabs.click(), can.onaction.layout(can) }
}
can.run(can.request({}, {_method: http.GET}), [river, storm], function(msg) {
if (msg.Length() == 0) { return can.user.isLocalFile? can.user.toastFailure(can, "miss data"): can.onengine.signal(can, chat.ONACTION_NOTOOL, can.request({}, {river: river, storm: storm})) }
return can.onimport._init(can, msg)
})
},
_onaction_cmd: function(can) { can.onengine.signal(can, chat.ONACTION_CMD), can.onlayout._init(can) },
onaction_cmd: function(can, msg) { can.user.mod.isCmd = true, can.page.ClassList.add(can, can._target, can.Mode(chat.CMD)), can.Conf(html.MARGIN_Y, 128), can.Conf(html.MARGIN_X, 0) },
onsearch: function(can, msg, arg) { var fields = msg.Option(ice.MSG_FIELDS).split(mdb.FS); if (arg[0] == mdb.PLUGIN) { can.onexport.plugin(can, msg, arg, fields) } if (arg[0] == ctx.COMMAND) { can.onexport.command(can, msg, arg, fields) } },
onresize: function(can) { can.onaction.layout(can) },
onkeydown: function(event, can, mode) {
if (can.isCmdMode() && !event.metaKey) { var sub = can._plugins[0].sub; sub && can.core.CallFunc([sub, "onaction.onkeydown"], {event: event, can: sub}); return }
// if (can._current && !event.metaKey) { var sub = can._current.sub; sub && can.core.CallFunc([sub, "onaction.onkeydown"], {event: event, can: sub}); return }
can.onkeymap.selectCtrlN(event, can, can._action, html.DIV_TABS) || can.onkeymap._parse(event, can, mode)
},
if (storm.index) { cmds = [ctx.ACTION, ctx.COMMAND].concat(storm.index) ontouchstart: function(event, can) { can.touch = can.touch || {}, can.touch.isStart = true, can.touch.startX = event.touches[0].clientX },
can.run(event, cmds, cb) // 命令详情 ontouchmove: function(event, can) { can.touch.isMove = true, can.touch.distanceX = event.touches[0].clientX - can.touch.startX },
} else { // 命令列表 ontouchend: function(event, can) {
can.core.List(storm.list, function(value) { if (can.touch.isMove && Math.abs(can.touch.distanceX) > 50) {
msg.Push(mdb.NAME, value.name||"") if (can.touch.distanceX > 0) { can.onengine.signal(can, "onslideright") } else { can.onengine.signal(can, "onslideleft") }
msg.Push(mdb.HELP, value.help||"") } can.touch.isMove = false, can.touch.distanceX = 0, can.touch.isStart = false, can.touch.startX = 0
msg.Push(ctx.INPUTS, JSON.stringify(value.inputs)) },
msg.Push(ctx.FEATURE, JSON.stringify(value.feature))
msg.Push(ctx.INDEX, value.index||"") store: function(can) { can.user.opens(can.misc.MergePodCmd(can, {cmd: web.STORE})) },
msg.Push(ctx.ARGS, value.args||"[]") dream: function(can) { can.user.opens(can.misc.MergePodCmd(can, {cmd: web.DREAM})) },
msg.Push("_action", value._action||"") portal: function(can) { can.user.opens(can.misc.MergePodCmd(can, {cmd: web.PORTAL})) },
}), can.base.isFunc(cb) && cb(msg) desktop: function(can) { can.user.opens(can.misc.MergePodCmd(can, {cmd: web.DESKTOP})) },
} layout: function(can, button, skip) { var before = can._layout||can.onlayout._storage(can); button = button||before||(can.user.isMobile? ALL: TABVIEW)
return true var list = can.misc.SearchHash(can); list.length > 2 && (list[3] = button); can.isCmdMode() || can.misc.SearchHash(can, list[0], list[1], list[2], list[3])
}, can.page.ClassList.del(can, can._target, before), can._header_tabs && can.onmotion.hidden(can, can._header_tabs)
button = (can.onlayout._storage(can, can._layout = button))||can.misc.SearchOrConf(can, html.LAYOUT), can.page.ClassList.add(can, can._target, button)
can.onengine.signal(can, chat.ONLAYOUT, can.request({}, {layout: button, before: before}))
can._root.River && can._river_show === false && can.onmotion.hidden(can, can._root.River._target), skip || can.onlayout._init(can)
can.getActionSize(function(height, width) { var cb = can.onlayout[button]; can.base.isFunc(cb) && cb(can, height, width) || can.onlayout._plugin(can, button) })
},
// _menus: [[html.LAYOUT, ALL, TABS, TABVIEW, VERTICAL, HORIZON, GRID, FREE, FLOW, PAGE]],
_trans: kit.Dict(html.LAYOUT, "布局", ALL, "详情布局", TABS, "标签布局", TABVIEW, "标签分屏", VERTICAL, "上下分屏", HORIZON, "左右分屏", GRID, "网格布局", FREE, "自由布局", FLOW, "流动布局", PAGE, "网页布局"),
}) })
Volcanos("onaction", {help: "交互操作", list: [], _init: function(can, msg, list, cb, target) { Volcanos(chat.ONLAYOUT, {
can._target.ontouchstart = function(event) { tabs: function(can, height, width) { can.ConfHeight(height+html.ACTION_HEIGHT), can.ConfWidth(width) },
can.onengine.signal(can, "onaction_touch", can.request(event)) tabview: function(can, height, width) { can.ConfHeight(height+html.ACTION_HEIGHT), can.ConfWidth(width), can.onmotion.toggle(can, can._header_tabs, true)
} can.page.SelectOne(can, can._header_tabs, html.DIV_ITEM_SELECT)
can.base.isFunc(cb) && cb() // || can.page.Select(can, can._header_tabs, html.DIV_ITEM, function(target, index) { index == 0 && target.click() })
}, },
onmain: function(can, msg) { horizon: function(can, height, width) { can.ConfHeight(height), can.ConfWidth(width/2) },
can.onimport._share(can, can.misc.Search(can, web.SHARE)) vertical: function(can, height, width) { can.ConfHeight(height/2), can.ConfWidth(width) },
can.onkeypop._init(can) grid: function(can, height, width) { var m = can.user.isMobile? 1: 2, n = 2, h = height/n, w = width/m; can.ConfHeight(h+html.ACTION_HEIGHT), can.ConfWidth(w) },
}, free: function(can, height, width) { can.ConfHeight(height*3/4), can.ConfWidth(width*3/4), can.onmotion.toggle(can, can._header_tabs, true)
onlogin: function(can) { if (!can.user.mod.isCmd) { return } can.core.List(can._plugins, function(sub, index, array) { can.onmotion.move(can, sub._target, {left: (width/array.length/8*5+20)*index, top: (height/array.length/8*5)*index}) })
can.page.ClassList.add(can, can._target, "cmd") },
can._names = location.pathname flow: function(can, height, width) { can.ConfHeight(height-html.ACTION_MARGIN), can.ConfWidth(width) },
can.Conf(chat.TOOL)? can.core.Next(can.Conf(chat.TOOL), function(item, next) { page: function(can) { can.page.styleHeight(can, can._output, ""), can.page.style(can, document.body, kit.Dict(html.OVERFLOW, "")) },
can.core.Timer(500, function() { can.onaction._plugin(can, item, next) }) _plugin: function(can, button) { can.core.List(can._plugins, function(sub) {
if (can.isCmdMode()) { return sub.onimport.size(sub, can.page.height(), can.page.width(), false) }
}): can.run(can.request()._event, [ctx.ACTION, ctx.COMMAND], function(msg) { if (can.page.ClassList.has(can, sub._target, html.OUTPUT)) {
can.core.Next(msg.Table(), function(item, next) { return sub.onimport.size(sub, can.ConfHeight()-(can.user.isMobile? 2*html.PLUGIN_PADDING: can.Conf(html.MARGIN_Y)-([ALL, TABS].indexOf(can.onexport.layout(can)) > -1? html.ACTION_HEIGHT: 0)), can.ConfWidth()-can.Conf(html.MARGIN_X), can.onexport.isauto(can))
can.onaction._plugin(can, item, next) }
}) sub.onimport.size(sub, can.ConfHeight()-can.Conf(html.MARGIN_Y)-(can._plugins.length == 1 || button && button != ALL || sub.isCmdMode()? 0: html.ACTION_MARGIN),
}) can.ConfWidth()-can.Conf(html.MARGIN_X), can._plugins.length > 1 && can.onexport.isauto(can)) && can.page.style(can, sub._output, html.HEIGHT, "", html.MAX_HEIGHT, "")
}, }) },
_plugin: function(can, item, next) { _storage: function(can, value) { return can.user.isMobile? "all": (can.misc.sessionStorage(can, can.core.Keys(CAN_LAYOUT, location.pathname), value)||[])[0] },
can.base.Copy(item, {height: window.innerHeight, width: window.innerWidth, opts: can.misc.Search(can)})
can.onappend.plugin(can, item, function(sub, meta) { can.user.title(meta.name), next() })
},
onstorm_select: function(can, msg, river, storm) { can.onlayout._init(can)
function key(name) { return can.core.Keys(can.Conf(chat.RIVER), can.Conf(chat.STORM), name) }
can.page.Cache(key(html.ACTION), can._action, can._output.scrollTop+1)
can.page.Cache(key(html.OUTPUT), can._output, can._output.scrollTop+1)
can.Conf(chat.RIVER, river), can.Conf(chat.STORM, storm) // 转场
var position = can.page.Cache(key(html.ACTION), can._action)
var position = can.page.Cache(key(html.OUTPUT), can._output)
if (position) { can._output.scrollTo(0, position-1); return }
can.run({}, [river, storm], function(msg) {
if (msg.Length() == 0) { // 添加工具
can.onengine.signal(can, "onaction_nostorm", can.request({}, {river: river, storm: storm}))
} else {
can.onimport._init(can, msg)
}
})
},
onsearch: function(can, msg, word) {
if (word[0] == "*" || word[0] == mdb.PLUGIN) { can.onexport.plugin(can, msg, word) }
},
onsize: function(can, msg, width, height) { can.Conf({width: width, height: height}) },
layout: function(can, layout) { if (!layout) { return }
var trans = {
"默认布局": "auto",
"流动布局": "flow",
"网格布局": "grid",
"标签布局": "tabs",
"自由布局": "free",
}
layout = trans[layout]||layout, can.Conf(chat.LAYOUT, layout)
can.page.Modify(can, can._action, {className: "action "+layout})
can.page.Modify(can, can._output, {className: "output "+layout})
if (layout == "tabs" && !can.tabs) {
can.onmotion.select(can, can._output, "fieldset.plugin", 0)
can.onmotion.select(can, can._action, "div.item", 0)
can.tabs = true
}
if (layout == "free" && !can.free) {
can.page.Select(can, can._target, "div.output>fieldset.plugin", function(item, index) {
can.page.Modify(can, item, {style: {left: 20*index, top: 20*index}})
can.onmotion.move(can, item, {left: 20*index, top: 20*index})
}), can.free = true
}
can.onlayout._init(can)
},
}) })
Volcanos("onkeypop", {help: "键盘交互", list: [], _focus: [], _init: function(can, target) { Volcanos(chat.ONEXPORT, {
can.onkeypop._build(can), can.onengine.listen(can, "onkeydown", function(msg, model) { size: function(can, msg) {
can._keylist = can.onkeypop._parse(msg._event, can, model, can._keylist||[], can._output) msg.Option(html.LEFT, can._output.offsetLeft), msg.Option(html.TOP, can._output.offsetTop)
}) msg.Option(html.HEIGHT, can._output.offsetHeight||window.innerHeight), msg.Option(html.WIDTH, can._output.offsetWidth||window.innerWidth)
}, msg.Option(html.MARGIN_Y, can.Conf(html.MARGIN_Y)), msg.Option(html.MARGIN_X, can.Conf(html.MARGIN_X))
_mode: { },
normal: { layout: function(can) { return can._layout||can.onlayout._storage(can)||can.misc.SearchOrConf(can, html.LAYOUT)||"" },
j: function(event, can, target) { target.scrollBy(0, event.ctrlKey? 300: 30) }, isauto: function(can) { return ["", ALL, FLOW, PAGE].indexOf(can.onexport.layout(can)) > -1 },
k: function(event, can, target) { target.scrollBy(0, event.ctrlKey? -300: -30) }, args: function(can, msg, cb) { can.core.Next(can._plugins, function(sub, next, index, list) {
cb(can.base.trim(can.page.SelectArgs(can, sub._option, "", function(item) { return item.value })), sub, next, index, list)
b: function(event, can, target) { can.search(event, ["Header.onaction.black"]) }, }) },
w: function(event, can, target) { can.search(event, ["Header.onaction.white"]) }, plugin: function(can, msg, arg, fields) { can.core.List(can._plugins, function(sub) { var meta = sub.Conf(); if (!can.base.contains(meta.index, arg[1])) { return }
var data = {ctx: ice.CAN, cmd: can._name, type: chat.PLUGIN, name: sub._index, text: shy(sub._legend.innerHTML, function(event) { sub._target.click() })}
s: function(event, can, target) { can.search(event, ["River.ondetail.添加应用"]) }, if (meta.index) { data.context = "", data.command = meta.index } else if (meta.cmd) { data.context = meta.ctx, data.command = meta.cmd } else { return } msg.Push(data, fields)
t: function(event, can, target) { can.search(event, ["River.ondetail.添加工具"]) }, }) },
command: function(can, msg, arg, fields) { var meta = can.onengine.plugin.meta; can.core.Item(arg[1] == ""? meta: meta[arg[1]]? kit.Dict(arg[1], meta[arg[1]]): {}, function(name, command) {
":": function(event, can, target) { msg.Push(kit.Dict(ice.CTX, ice.CAN, ice.CMD, ctx.COMMAND, mdb.TYPE, ice.CAN, mdb.NAME, name||command.name, mdb.TEXT, command.help, ctx.CONTEXT, ice.CAN, ctx.COMMAND, name, ctx.INDEX, can.core.Keys(ice.CAN, name)), fields)
can.onengine.signal(can, "oncommandfocus") }) }
},
" ": function(event, can, target) {
can.onengine.signal(can, "onsearchfocus")
},
enter: function(event, can, target) { can.misc.Log("enter") },
escape: function(event, can, target) {
can.page.Select(can, document.body, "fieldset.float,div.float", function(item) {
can.page.Remove(can, item)
})
can.page.Select(can, document.body, "fieldset.auto", function(item) {
can.onmotion.hidden(can, item)
})
can.search(event, ["Search.onaction.hide"])
can.misc.Log("enter")
},
},
}, _engine: {},
}) })
Volcanos("onexport", {help: "导出数据", list: [], Volcanos(chat.ONENGINE, {
args: function(can, msg, list, cb, target) { _engine: function(event, sup, msg, can, cmds, cb) {
can.core.Next(can.page.Select(can, target, "fieldset.plugin>form.option"), function(item, next, index, array) { var storm = can.core.Value(can._root, can.core.Keys(chat.RIVER, cmds[0], chat.STORM, cmds[1])); if (!storm || cmds.length != 2) { return false }
var list = can.page.Select(can, item, '.args', function(item) { return item.value||"" }) if (storm.index) {
item.dataset.args = JSON.stringify(list), cb(item, next, index, array) can.runAction(event, ctx.COMMAND, [].concat(can.core.List(storm.index, function(item) {
}) if (typeof item == code.FUNCTION) { item = item(can) } if (item) { return item.index||item }
}, })), function(msg) {
size: function(can, msg) { can.core.List(storm.index, function(item) { if (!item || typeof item == code.FUNCTION) { return }
msg.Option(chat.TOP, can._target.offsetTop) msg.Push(ctx.ARGS, JSON.stringify(item.args||[]))
msg.Option(chat.LEFT, can._target.offsetLeft) msg.Push(ctx.STYLE, item.style||"").Push(ctx.DISPLAY, item.display||"")
msg.Option(html.WIDTH, can._target.offsetWidth) msg.Push(web.SPACE, item.space||"").Push("_ismain", ice.TRUE)
msg.Option(html.HEIGHT, can._target.offsetHeight) }), cb(msg)
msg.Option(chat.SCROLL, can.user.isMobile? can._target.parentNode.parentNode.scrollTop: can._output.scrollTop) })
}, } else { can.core.List(storm.list, function(item) { can.base.isString(item) && (item = {index: item})
layout: function(can, msg) { return can.Conf(chat.LAYOUT) }, msg.Push(ctx.INDEX, item.index||"").Push(mdb.ICONS, item.icons||"")
plugin: function(can, msg, word) { msg.Push(mdb.NAME, item.name||"").Push(mdb.HELP, item.help||"")
var fields = msg.Option(ice.MSG_FIELDS).split(ice.FS) msg.Push(ctx.INPUTS, JSON.stringify(item.inputs)).Push(ctx.FEATURE, JSON.stringify(item.feature))
can.page.Select(can, can._output, "fieldset.plugin>legend", function(item) { msg.Push(ctx.ARGS, item.args||"[]").Push(ctx.STYLE, item.style||"").Push(ctx.DISPLAY, item.display||"")
if (item.innerHTML.indexOf(word[1]) == -1) { return } msg.Push(web.SPACE, item.space||"").Push("_ismain", ice.TRUE)
}), can.base.isFunc(cb) && cb(msg) } return true
var meta = item.parentNode.Meta },
var list = can.page.Select(can, item.nextSibling, '.args', function(item) { return item.value||"" })
var data = {ctx: "web.chat", cmd: ctx.ACTION,
type: mdb.PLUGIN, name: item.innerHTML, text: shy("跳转", function(event) {
var input = can.page.Select(can, item.parentNode, "input.args")[0]
input && input.focus()
}), argument: JSON.stringify(list),
}
if (meta.index) {
data.context = "", data.command = meta.index
} else if (meta.cmd) {
data.context = meta.ctx, data.command = meta.cmd
} else {
return
}
can.core.List(fields, function(key) { msg.Push(key, data[key]||"") })
})
},
}) })
Volcanos(chat.ONKEYMAP, {
_mode: {
plugin: {
Enter: function(event, can) { can.onengine.signal(can, chat.ONOPENSEARCH, can.request(event, {type: "*"})) },
Escape: function(event, can) { can.onmotion.clearFloat(can) || can._root.Search && can.onmotion.hidden(can, can._root.Search._target) },
},
}, _engine: {},
toggleTheme: function(can, theme) { can.setHeader(chat.THEME, can.getHeaderTheme() == theme? ice.AUTO: theme) },
toggleLayout: function(can, layout) { can.onaction.layout(can, can.onexport.layout(can) == layout? ice.AUTO: layout) },
})
Volcanos(chat.ONPLUGIN, {
_filter: shy("表格", [ice.LIST, html.FILTER]),
_plugin: shy("插件", [mdb.NAME, ice.LIST, ice.BACK]),
_action: shy("操作", [ice.LIST]),
_display: shy("操作", [ice.LIST]),
_output: shy("操作", [ice.LIST], function(can, sub) { can.onappend.style(sub, html.OUTPUT) }),
_notfound: shy("缺失", [ctx.INDEX, web.SPACE, ice.LIST], function(can, msg, arg, sub) { msg.Echo("not found "+(arg[0]||sub.ConfIndex())+" "+(arg[1]||can.ConfSpace())) }),
layout: shy("界面布局", {_init: function(can) { can.Option(chat.LAYOUT, can.getAction(chat.LAYOUT)) }}, ["layout:select=auto,tabs,tabview,horizon,vertical,grid,free,flow,page", ctx.RUN], function(can, msg, arg) { can.onaction.layout(can, arg[0]) }),
})
})()

View File

@ -1,36 +1,40 @@
fieldset.Footer { fieldset.Footer>div.output { font-style:italic; height:var(--footer-height); display:flex; }
height:32px; padding:0 5px; fieldset.Footer>div.output div.item { padding:7px; height:var(--footer-height); display:flex; align-items:center; }
clear:both; fieldset.Footer>div.output div.item.button { padding:7px 0; }
} fieldset.Footer>div.output div.title:first-child { margin-left:var(--header-height); white-space:pre; }
fieldset.Footer>div.output { fieldset.Footer:not(.tabview)>div.output div.title:first-child { font-weight:bold; text-align:center; width:var(--river-width); }
height:32px; overflow:hidden; fieldset.Footer>div.output input[type=button] { background-color:transparent; color:var(--panel-fg-color); font-style:italic; border:0; }
} fieldset.Footer>div.output div.toast { font-family:var(--status-font-family); line-height:18px; text-align:right; overflow:auto; flex-grow:1; justify-content:flex-end; }
fieldset.Footer>div.output>div { fieldset.Footer>div.output div.state { font-family:var(--status-font-family); line-height:18px; white-space:pre; }
height:22px; padding:5px; fieldset.Footer>div.output div.state label { font-size:var(--status-font-size); }
cursor:pointer; fieldset.Footer>div.output div.cmd { padding:0; margin-left:20px; }
} fieldset.Footer>div.output div.cmd>input[name=cmd] { padding-left:30px; }
fieldset.Footer>div.output>div:hover { fieldset.Footer>div.output div.menu>div.River { display:flex; justify-content:space-around; }
border-top:solid 2px red; fieldset.Footer>div.output div.menu>div.River>div.item { height:var(--footer-height); display:flex; flex-direction:column; text-align:center; flex-grow:1; }
background-color:#2e515f; fieldset.Footer>div.output div.menu>div.River>div.item>i { font-size:24px; margin-right:0; }
} fieldset.Footer>div.output div.menu>div.River>div.item>span { font-size:var(--status-font-size); }
fieldset.Footer>div.output div.title { body.mobile fieldset.Footer>div.output>div.menu { width:100%; }
float:left; body.mobile fieldset.Footer>div.output>div:not(.menu) { display:none; }
}
fieldset.Footer>div.output div.state {
float:right;
}
fieldset.Footer>div.output div.toast {
float:right; background-color:darkcyan;
}
fieldset.Footer>div.output div.cmd {
float:left; padding:0px;
}
fieldset.Footer>div.output input[name=cmd] { .picker {
width:120px; height:25px; box-shadow:var(--notice-bg-color) 0px 0px 20px 5px !important;
border-radius:0; background-color:var(--notice-bg-color) !important; color:white !important;
position:relative; left:-5px; top: -5px; transition:all 0.5s;
} }
fieldset.Footer>div.output input[name=cmd]:focus { .picker.danger {
width:320px; box-shadow:var(--danger-bg-color) 0px 0px 20px 5px !important;
background-color:var(--danger-bg-color) !important; color:white !important;
} }
div.view span.string { color:#f29766; }
div.view span.keyword { color:#5cadd4; }
div.item:not(.string):not(.number):not(.boolean)>span.value { color:var(--disable-fg-color); font-style:italic; }
span.item:not(.string):not(.number):not(.boolean)>span.value { color:var(--disable-fg-color); font-style:italic; }
fieldset.debug div.output table.content * { font-size:14px; }
fieldset.debug span.path { color:silver; font-style:italic; }
html.login body.width1 fieldset.Footer { display:none; }
html.login body.width1 fieldset.Header { display:none; }
body.dark fieldset.debug span.path { color:gray; }
body.dark fieldset.debug span.target { color:gray; }
body.dark div.item:not(.string):not(.number):not(.boolean)>span.value { color:gray; }
body.dark span.item:not(.string):not(.number):not(.boolean)>span.value { color:gray; }

View File

@ -1,96 +1,208 @@
Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) { (function() { var NTIP = "ntip", NLOG = "nlog", NCMD = "ncmd", NKEY = "nkey"
can.onmotion.clear(can) Volcanos(chat.ONIMPORT, {
can.onimport._title(can, msg, target) _init: function(can, msg, target) { can._wss = can.ondaemon._init(can)
can.onimport._state(can, msg, target) can.Conf(cli.BEGIN, can.base.Time(null, "%H:%M:%S"))
can.onimport._toast(can, msg, target) if (!can.user.isMobile && !can.misc.isDebug(can)) { can.onmotion.hidden(can); return }
can.onimport._cli(can, msg, target) can.Conf(nfs.VERSION, can.base.trimPrefix(window._version, "?_v=").split("&")[0])
can.base.isFunc(cb) && cb(msg) can.ConfHeight(can.page.height()), can.ConfWidth(can.page.width())
}, can.Conf(NKEY, can.core.Item(can.misc.localStorage(can)).length)
_title: function(can, msg, target) {
!can.user.isMobile && can.core.List(msg.result, function(item) {
can.page.Append(can, target, [{view: [chat.TITLE, html.DIV, item], title: "联系站长"}])
})
},
_state: function(can, msg, target) {
can.core.List(can.base.Obj(msg.Option(chat.STATE)||can.Conf(chat.STATE), ["ncmd"]), function(item) {
can.page.Append(can, target, [{view: [can.base.join([chat.STATE, item]), html.DIV, can.Conf(item)], list: [
{text: [item, html.LABEL]}, {text: [": ", html.LABEL]}, {text: [can.Conf(item)||"", html.SPAN, item]},
], onclick: function(event) {
can.show = can.show? (can.page.Remove(can, can.show), null): can.onaction._cmd(can)
can.page.Modify(can, can.show, {style: {left: "", top: "", right: 0, bottom: can.onexport.height(can)}})
}}])
})
},
_toast: function(can, msg, target) {
can.toast = can.page.Append(can, target, [{view: chat.TOAST, onclick: function(event) {
can.show = can.show? (can.page.Remove(can, can.show), null): can.onappend.float(can, can._toast).first
can.page.Modify(can, can.show, {style: {left: "", top: "", right: 0, bottom: can.onexport.height(can)}})
}}]).first
},
_cli: function(can, msg, target) {
can.onappend.input(can, {type: html.TEXT, name: "cmd", onkeydown: function(event) {
can.onkeypop.input(event, can); if (event.key != lang.ENTER) { return }
switch (event.target.value) {
case cli.CLEAR: can.cli && can.cli.close(); break
case cli.CLOSE: can.cli && can.cli.close(); break
default:
can.run(event, [ice.RUN].concat(can.core.Split(event.target.value, ice.SP)), function(msg) {
can.cli && can.cli.close()
can.cli = can.onappend.float(can, msg, function(value, key, index, line, list) {
}), can.page.Modify(can, can.cli.first, {style: {bottom: can.onexport.height(can), top: ""}}) can.onimport._title(can, msg, target)
}) can.onimport._storm(can, msg, target)
} can.core.List([
}}, "", target, "title cmd") // {index: chat.TUTOR},
}, // {index: chat.FLOWS, value: "流程"},
// {index: chat.MESSAGE},
toast: function(can, msg, title, content, fileline, time) { can._toast = can._toast||can.request() {index: web.SPIDE, value: can.user.trans(can, "spide", "服务")},
can.page.Modify(can, can.toast, [time.split(ice.SP).pop(), title, content].join(ice.SP)) {index: web.SPACE, value: can.user.trans(can, "space", "空间")},
can._toast.Push({time: time, fileline: fileline, title: title, content: content}) {index: cli.RUNTIME},
}, {index: code.XTERM, args: [cli.SH]},
ncmd: function(can, msg, _follow, _cmds) { var NCMD = "ncmd"; can._cmds = can._cmds||can.request() ], function(value) { value.type = html.BUTTON, value.name = value.index
can._cmds.Push({time: can.base.Time(), follow: _follow, cmds: _cmds}) value.onclick = function() { can.onappend._float(can, value.index, value.args) }
can.page.Select(can, can._output, can.core.Keys(html.SPAN, NCMD), function(item) { can.onappend.input(can, value, "", can._output)
item.innerHTML = can.Conf(NCMD, parseInt(can.Conf(NCMD)||"0")+1+"")+"" })
}) // can.onimport._command(can, msg, target)
}, can.onimport._toast(can, msg, target)
can.misc.isDebug(can) && can.onimport._state(can, msg, target)
},
_title: function(can, msg, target) { can.user.isMobile || can.core.List(can.Conf(chat.TITLE)||msg.result, function(item) {
if (can.base.contains(item, ice.AT)) { item = '<a href="mailto:'+item+'">'+item+'</a>' }
can.page.Append(can, target, [{view: [[html.ITEM, chat.TITLE], "", item], title: "联系站长"}])
}) },
_command: function(can, msg, target) { can.onappend.input(can, {type: html.TEXT, _className: "args trans", icon: icon.TERMINAL, name: ice.CMD, onkeydown: function(event) { can.onkeymap.input(event, can)
function close() { can.ui.cli && can.ui.cli.onaction.close() } if (event.key == code.ESCAPE) { return close() } if (event.key != code.ENTER) { return } close()
switch (event.target.value) {
case web.CLEAR:
case cli.CLOSE: break
default:
var list = can.core.Split(event.target.value, lex.SP)
can.onexport._float(can, "cli", {index: "can.console", display: "/plugin/local/code/xterm.js"}, list, function(sub) { can.getActionSize(function(left) { can.page.style(can, sub._target, html.LEFT, left+html.PLUGIN_MARGIN, html.RIGHT, "") }) })
}
}}, "", target, [chat.TITLE]) },
_storm: function(can, msg, target) { can.ui.storm = can.page.Append(can, can._output, [html.MENU])._target },
_state: function(can, msg, target) { can.user.isMobile || can.core.List(can.base.Obj(can.Conf(chat.STATE)||msg.Option(chat.STATE), can.onexport.list), function(item) {
can.page.Append(can, target, [{view: [[html.ITEM, chat.STATE]], list: [
{text: [item, html.LABEL]}, {text: [": ", html.LABEL]}, {text: [can.Conf(item)||"", "", item]},
], onclick: function(event) { can.core.CallFunc(can.onexport[item], [can]) }}]) })
},
_toast: function(can, msg, target) { can.ui.toast = can.page.Append(can, target, [{view: [[html.ITEM, chat.TOAST]], onclick: function(event) { can.onexport[NTIP](can) }}])._target },
_data: function(can, name, item) { can.db[name] = can.db[name]||can.request(), can.db[name].Push(item), can.onimport.count(can, name) },
tutor: function(event, can, type, text) { if (can.base.isIn(type, "keyup", "keydown")) { return }
!event._tutor && event.isTrusted && text && can.onimport._data(can, chat.TUTOR, {time: can.base.Time(), type: type, text: text}), event._tutor = true
},
value: function(can, name, value) { can.page.Select(can, can._output, "div.item>span."+name, function(target) { target.innerHTML = value }) },
count: function(can, name) { can.page.Select(can, can._output, can.core.Keys(html.SPAN, name), function(item) { item.innerHTML = can.Conf(name, parseInt(can.Conf(name)||"0")+1+"")+"" }) },
ntip: function(can, msg, time, title, content) { can.onimport._data(can, NTIP, {time: time, title: title, content: content}), can.page.Modify(can, can.ui.toast, [time, title, content].join(lex.SP)) },
ncmd: function(can, msg, _follow, _cmds) { can.onimport._data(can, NCMD, {time: can.base.Time(), follow: _follow, cmds: _cmds}), can.onimport.nlog(can, NLOG) },
nlog: function(can, name) { can.onimport.count(can, name) },
menu: function(can, cmds, cb, trans) { can.base.isString(cmds) && (cmds = [cmds])
return can.page.Append(can, can.ui.storm, [{view: cmds[0], list: can.core.List(can.base.getValid(cmds.slice(1), [cmds[0]]), function(item) {
return {view: [[html.ITEM, item.name]], list: [{icon: item.icon}, {text: item.name}], onclick: function(event) {
can.onmotion.select(can, event.currentTarget.parentNode, html.DIV_ITEM, event.currentTarget), cb(event, item.hash)
}}
}) }])._target
},
}) })
Volcanos("onaction", {help: "交互数据", list: [], _init: function(can, msg, list, cb, target) { Volcanos(chat.ONACTION, {_init: function(can) {},
can.base.isFunc(cb) && cb(msg) onsize: function(can) { can.ConfHeight(can._target.offsetHeight), can.ConfWidth(can._target.offsetWidth)
}, can.onimport.value(can, html.HEIGHT, can.page.height()), can.onimport.value(can, html.WIDTH, can.page.width())
onlogin: function(can, msg) { can.run({}, [], function(msg) { can.onimport._init(can, msg, [], null, can._output) }) }, },
ontoast: function(can, msg) { can.core.CallFunc(can.onimport.toast, {can: can, msg: msg}) }, onmain: function(can) {
onremote: function(can, msg) { can.core.CallFunc(can.onimport.ncmd, {can: can, msg: msg}) }, can.run(can.request({}, {_method: http.GET}), [], function(msg) {
oncommandfocus: function(can) { can.page.Appends(can, can._output, [{view: "item title", list: [{text: msg.Result()}]}])
can.page.Select(can, can._output, "div.cmd input", function(target) { target.focus() }) })
}, },
onlogin: function(can, msg) {
can.run(can.request({}, {_method: http.GET}), [], function(msg) { can.onmotion.clear(can), can.onimport._init(can, msg, can._output) })
},
ontoast: function(can, msg) { can.core.CallFunc(can.onimport.ntip, {can: can, msg: msg}) },
onremote: function(can, msg) { can.core.CallFunc(can.onimport.ncmd, {can: can, msg: msg}) },
onunload: function(can) { can._wss && can._wss.close() },
onrecord: function(can, msg) { var zone = can.misc.sessionStorage(can, "web.chat.script:zone"); zone && can.runAction(can.request(), nfs.SCRIPT, [zone].concat(msg.cmds[0])) },
onaction_cmd: function(can) { can.onappend.style(can, html.HIDE) },
onstorm_select: function(event, can, river, storm) { event.isTrusted != undefined && can.onimport._data(can, chat.TUTOR, {time: can.base.Time(), type: chat.STORM, text: [river, storm].join(",")}) },
_cmd: function(can) { ontheme: function(event, can, theme) { can.onimport.tutor(event, can, chat.THEME, theme) },
return can.onappend.float(can, can._cmds, function(value, key, index, line, list) { onevent: function(event, can, query) { var msg = can.request(event)
var cmds = can.base.Obj(line.cmds); switch (line.follow) { can.onimport.tutor(event, can, msg.Option("_type")||event.type, query||can.page.getquery(can, event.currentTarget||event.target))
case "chat.Action": cmds = cmds.slice(2); break },
case "chat.Footer": cmds = cmds.slice(2); break onindex: function(event, can, index) { can.onimport.tutor(event, can, ctx.INDEX, index) },
} onproject: function(event, can, query) { can.onimport.tutor(event, can, html.ITEM, query) },
switch (cmds[0]) { onremove: function(event, can, query) { can.onimport.tutor(event, can, mdb.REMOVE, query) },
case "web.wiki.word": cmds = cmds.slice(5); break
}
can.get("Action", "size", function(msg, top, left, width, height) { oncommand_focus: function(can) { can.page.Select(can, can._output, ["div.cmd", html.INPUT], function(target) { can.onmotion.focus(can, target) }) },
can.onappend.plugin(can, {index: cmds[0], args: cmds.slice(1), height: height-100, width: width}, function(sub) { onlayout: function(can, layout, before) { if (can.user.isMobile) { return }
sub.run = function(event, cmd, cb) { can.page.ClassList.del(can, can._target, before), can.page.ClassList.add(can, can._target, layout)
can.run(event, can.misc.concat([ctx.ACTION, ice.RUN, cmds[0]], cmd), cb) },
} ondebugs: function(can, msg) { can.runAction(msg, msg.Option(ctx.ACTION), [msg.Option(ctx.INDEX)], function(_msg) { _msg.Table(function(item) {
can.onappend._float(can, item, can.base.Obj(item.args, []), function(sub) {
can.page.Modify(can, sub._target, {style: {top: top+100, left: left}}) sub.run = function(event, cmds, cb) { can.run(can.request(event, {_method: http.POST, pod: sub.ConfSpace()}), [ctx.ACTION, msg.Option(ctx.ACTION), ctx.RUN].concat(cmds), cb) }
can.page.Modify(can, sub._legend, {style: {display: html.BLOCK}}) })
can.page.Modify(can, sub._output, {style: {"max-width": width}}) }) }) },
can.page.ClassList.add(can, sub._target, chat.FLOAT)
}, document.body)
})
}).first
},
}) })
Volcanos("onexport", {help: "导出数据", list: [], Volcanos(chat.ONEXPORT, {list: [cli.BEGIN, nfs.VERSION],
height: function(can) { return can._target.offsetHeight }, height: function(can) { can.onexport._float(can, html.HEIGHT, "can.view") },
width: function(can) { can.onexport._float(can, html.WIDTH, "can.data") },
ntip: function(can) { can.onexport._float(can, NTIP, "can.toast") },
nlog: function(can) { can.onexport._float(can, NLOG, "can.debug") },
ncmd: function(can) { can.onexport._float(can, NCMD, "can.debug", [chat.ONREMOTE]) },
nkey: function(can) { can.onexport._float(can, NKEY, "can.localStorage") },
begin: function(can) { can.onexport._float(can, NKEY, "can.data") },
version: function(can) { can.onexport._float(can, NKEY, "can.runtime") },
_float: function(can, name, index, args, cb) { can.ui[name]? can.ui[name].onaction.close(): can.onappend._float(can, index, args||[], function(sub) { can.ui[name] = sub
can.base.isFunc(cb) && cb(sub), can.onmotion.delay(can, function() { sub.onaction.close = function() { can.page.Remove(can, sub._target), delete(can.ui[name]) } })
}) },
}) })
Volcanos(chat.ONPLUGIN, {
toast: shy("提示", {}, [html.FILTER, ice.LIST], function(can, msg, arg) { if (!can.db[NTIP]) { return }
arg[0]? can.db[NTIP].Table(function(value) {
msg.append = [mdb.TIME, "title", "content"], (value.title == arg[0] || value.content.indexOf(arg[0]) > -1) && msg.Push(value)
}): msg.Copy(can.db[NTIP]), msg.StatusTimeCount()
}),
debug: shy("网页日志", {
"prune": shy("清空", function(can) { while(can.misc._list.pop()) {} can.onmotion.clear(can) }),
"w3schools": shy("教程", function(can) { can.user.open("https://www.w3schools.com/colors/colors_names.asp") }),
"mozilla": shy("文档", function(can) { can.user.open("https://developer.mozilla.org/en-US/") }),
"w3": shy("标准", function(can) { can.user.open("https://www.w3.org/TR/?tag=css") }),
}, ["type:select=log,info,warn,error,debug,onremote,wss", web.FILTER, ice.LIST, "prune", "w3schools", "mozilla", "w3"], function(can, msg, arg, cb) { var _can = can, can = msg._can
var stat = {}; var ui = can.page.Appends(can, can._output, [{view: [html.CONTENT, html.TABLE], list: [{type: html.TR, list: [
{text: [mdb.TEXT, html.TH]},
]}].concat(can.core.List(can.misc._list, function(list) { stat[list[2]] = ((stat[list[2]]||0)+1); return (!arg || !arg[0] || arg[0] == "log" || arg[0] == list[2]) && {type: html.TR, list: [
{type: html.TD, list: can.core.List(list, function(item, index) { var vimer
if (index == 1) { var _ls = new RegExp("(https*://[^/]+)*/*([^:]+):([0-9]+):([0-9]+)").exec(list[1])||[]; _ls[2] = (_ls[2]||"").split(ice.QS)[0]||""
return {view: [html.ITEM, html.SPAN], list: [{text: lex.SP+can.page.unicode.closes+lex.SP}, {text: [(_ls[1] == location.origin? "": _ls[1]||"")+_ls[2]+nfs.DF+_ls[3], "", nfs.PATH], onclick: function(event) {
if (can.onexport.record(can, list[1], web.LINK, {time: list[0], link: list[1], type: list[2], path: nfs.USR_VOLCANOS, file: _ls[2], line: _ls[3]})) { return }
if (vimer) { return can.page.Remove(can, vimer._target), vimer = null }
vimer = can.onappend.plugin(_can, {index: web.CODE_INNER, args: [nfs.USR_VOLCANOS, _ls[2], _ls[3]]}, function(sub) {}, event.target.parentNode)
}}]}
} if (!can.base.isObject(item)) { return item && {text: (index > 0? lex.SP: "")+item} }
return {view: [mdb.DATA, html.SPAN], _init: function(target) {
if (item.tagName) { var detail; var ui = can.page.Append(can, target, [{text: lex.SP},
{text: can.page.unicode.closes+lex.SP, _init: function(target) { can.onmotion.delay(can, function() { ui.toggle = target }) }},
{view: [[html.ITEM, nfs.TARGET], html.SPAN, can.page.tagClass(item)], onclick: function() {
if (detail) { return can.page.Remove(can, detail), detail = null, can.page.Modify(can, ui.toggle, can.page.unicode.closes+lex.SP) }
detail = can.page.AppendData(can, target, "", "", item)._target, detail.click(), can.page.Modify(can, ui.toggle, can.page.unicode.opens+lex.SP)
}},
]) } else { can.page.Append(can, target, [{text: lex.SP}]), can.page.AppendData(can, target, "", "", item) }
}}
})},
]} })) }]); arg && arg[1] && can.page.Select(can, can._output, html.TR, function(tr) { can.page.ClassList.set(can, tr, html.HIDE, tr.innerText.indexOf(arg[1]) == -1) })
can.onappend._status(can, [
{name: mdb.TIME, value: can.base.Time()}, {name: mdb.COUNT, value: can.page.Select(can, can._output, html.TR+html.NOT_HIDE).length+"x1"},
].concat(can.core.List([log.INFO, log.WARN, log.ERROR, chat.ONREMOTE, html.WSS], function(item) { return {name: item, value: stat[item]||"0"} })))
}),
view: shy("网页元素", [mdb.KEY], function(can, msg, arg, cb) { var can = msg._can
if (can.Conf("_target")) {
var ui = can.page.Append(can, can._output, [can.page.AppendView(can, can.Conf("_target"))])
can.onmotion.delay(can, function() { can.page.SelectOne(can, ui._target, html.DIV_ITEM, function(target) { target.click() }) })
} else if (arg[0]) {
can.page.Append(can, can._output, [can.page.AppendView(can, can.page.SelectOne(can, document.body, arg[0]))])
} else {
var ui = can.page.Append(can, can._output, [can.page.AppendView(can, document, "html", [
can.page.AppendView(can, document.head, html.HEAD), can.page.AppendView(can, document.body, html.BODY, null, false, function(target) {
var list = []; for (var p = target; p && p.tagName && p != document.body; p = p.parentNode) {
list.push(p.tagName.toLowerCase()+(p.className? nfs.PT+p.className.replaceAll(lex.SP, nfs.PT).replace(".picker", ""): ""))
} can.Option(mdb.KEY, list.reverse().join(ice.GT))
}),
], true)]); can.onmotion.delay(can, function() { can.page.Select(can, ui._target, "div.item.head,div.item.body", function(target) { target.click() }) })
}
}),
data: shy("网页数据", [mdb.KEY], function(can, msg, arg, cb) { var can = msg._can, root = can.Conf("_target")||can._root
arg[0]? can.page.AppendData(can, can._output, arg[0], arg[0].split(nfs.PT).pop(), can.core.Value(root, arg[0]), function(prefix, value) { can.Option(mdb.KEY, prefix) })._target.click():
can.page.AppendData(can, can._output, "", root._name, root, function(prefix, value) { can.Option(mdb.KEY, prefix) })._target.click()
can.onappend.style(can, "view")
}),
console: shy("网页终端", {
prompt: function(can, msg, arg, meta) { msg.detail = [], msg._can.onimport.grow(msg._can, msg, "only", ["\r", can.base.Time(null, "[%H:%M:%S]"), "can$ "].join("")) },
resize: function(can, msg, arg, meta) { msg.detail = [], meta.prompt(can, msg, arg, meta) },
input: function(can, msg, arg, meta) { can = msg._can, msg.detail = [], can._list = can._list||[]
var text = atob(arg[0]); function grow(text) { can.onimport.grow(can, msg, "only", text) }
if (text == "\r") { var cmd = can._list.join("")
if (!cmd) {
grow("\r\n"), can._list = []
} else { var res = window.eval(cmd)
grow("\r\n"+res+"\r\n"), can._list = []
}
meta.prompt(can, msg, arg, meta)
} else if (arg[0] == "fw==") {
grow("\u0008 \u0008"), can._list.pop()
} else if (arg[0] == "FQ==") {
grow("\u0008 \u0008".repeat(can._list.length)), can._list = []
} else {
grow(text), can._list = (can._list||[]).concat(text)
}
},
}, [ice.CMD], function(can, msg, arg) { msg._can.Option(ice.CMD, "")
msg.Display("/plugin/local/code/xterm.js")
}),
runtime: shy("网页环境", [mdb.KEY], function(can, msg, arg) {
msg.Echo(JSON.stringify({href: location.href, version: window._version,
height: can.page.height(), width: can.page.width(),
userAgent: navigator.userAgent,
history: history.length,
boot: can.db._boot,
daemon: can.misc.sessionStorage(can, "can.daemon"),
})).Display("/plugin/story/json.js")
}),
})
})()

View File

@ -1,43 +1,50 @@
fieldset.Header { fieldset.Header>div.output { line-height:21px; height:var(--header-height); overflow:hidden; }
height:32px; padding:0 5px; fieldset.Header>div.output div.item { background-color:var(--panel-output-bg-color); padding:13.5px; height:var(--header-height); float:left; display:flex; align-items:center; }
overflow:hidden; fieldset.Header>div.output div.item.title:first-child { font-size:var(--legend-font-size); font-style:italic; font-weight:bold; white-space:pre; overflow:hidden; }
z-index:10; fieldset.Header>div.output div.item.title img { padding:0; height:var(--action-height); width:var(--action-height); margin-right:var(--input-margin); }
} fieldset.Header>div.output div.item.state { padding:13.5px 10px; float:right; }
fieldset.Header>div.output { fieldset.Header>div.output div.item.layout>i { margin-left:var(--input-padding); }
height:32px; overflow:hidden; fieldset.Header>div.output div.item.layout:not(:hover)>i { visibility:hidden; }
} fieldset.Header>div.output div.item.layout { padding-right:0; }
fieldset.Header>div.output>div { fieldset.Header>div.output div.item.theme { white-space:pre; user-select:none; }
height:22px; padding:5px; fieldset.Header>div.output div.item.theme>i { margin-right:0; }
cursor:pointer; fieldset.Header>div.output div.item.theme>i:last-child { color:var(--disable-fg-color); }
} fieldset.Header>div.output div.item.theme>i.bi-moon-stars:last-child { font-size:12px; }
fieldset.Header>div.output>div:hover { fieldset.Header>div.output div.item.language { white-space:pre; user-select:none; }
border-bottom:solid 2px red; fieldset.Header>div.output div.item.language>span:last-child { color:var(--disable-fg-color); }
background-color:#2e515f; fieldset.Header>div.output div.item.usernick>i { margin-left:var(--input-padding); }
} fieldset.Header>div.output div.item.usernick:not(:hover)>i { visibility:hidden; }
fieldset.Header>div.output div.item.usernick { padding-right:0; }
fieldset.Header>div.output>div.title { fieldset.Header>div.output div.item.avatar { padding:0; }
float:left; fieldset.Header>div.output div.item.avatar>img { height:var(--header-height); clip-path:circle(40%); }
} fieldset.Header>div.output div.item.search { padding:13.5px 5px; }
fieldset.Header>div.output>div.state { fieldset.Header>div.output div.item.search { padding:7px 5px; }
float:right; fieldset.Header>div.output div.item.search>i { color:unset; padding:7px; left:3px; }
} fieldset.Header>div.output div.item.search>input { padding-left:25px; }
fieldset.Header>div.output>div.state.avatar>img { fieldset.Header>div.output div.item.search>span.icon { padding:var(--input-padding) var(--button-padding); }
height:1.4em; fieldset.Header>div.output div.Action>div._tabs { white-space:pre; padding-left:100px; height:100%; overflow:auto; display:flex; flex-wrap:wrap; }
} fieldset.Header>div.output div.Action>div._tabs div.tabs { font-style:italic; padding:13.5px 20px; display:flex; align-items:center; }
fieldset.Header>div.output>div.search { fieldset.Header>div.output div.Action>div._tabs div.tabs:only-child { display:none; }
float:left; margin-left:20px; body.mobile fieldset.Header>div.output div.item.usernick { display:none; }
} body.mobile fieldset.Header>div.output div.item.search>i { padding:0 10px; }
fieldset.Header>div.output>div.search>input { body.mobile fieldset.Header>div.output div.item.search>input { width:256px; }
height:25px; margin-top:-5px; body.mobile fieldset.Header>div.output div.item.search>input:not(:focus) { border-color:var(--disable-fg-color); }
border-radius:0; body:not(.mobile) fieldset.Header>div.output div.title:first-child { width:var(--river-width); }
} body:not(.mobile) fieldset.Header>div.output div.title img { margin-right:var(--button-margin); }
body:not(.mobile) fieldset.Header:not(.all):not(.tabs)>div.output div.title:first-child { padding-left:var(--button-padding); width:unset; }
fieldset.Header>div.output div.menu { body:not(.width6)>fieldset.Header:not(.all):not(.tabs)>div.output div.item.menu.search { padding-left:0 !important; margin-left:0; }
height:21px; padding:5px; body:not(.width6) fieldset.Header.tabview>div.output>div.Action>div.item.store { display:none; }
cursor:pointer; body:not(.width6) fieldset.Header.tabview>div.output>div.Action>div.item.dream { display:none; }
float:left; body:not(.width6) fieldset.Header.tabview>div.output>div.Action>div.item.desktop { display:none; }
} body:not(.width6) fieldset.Header>div.output>div.Action>div.item.portal { display:none; }
fieldset.Header>div.output div.menu:hover { body:not(.width6) fieldset.Header>div.output>div.item.language { display:none; }
border-bottom:solid 2px red; body.width3>fieldset.Header>div.output>div.item.time { display:none; }
background-color:#2e515f; body.width3>fieldset.Header>div.output>div.item.avatar { margin-right:var(--plugin-margin); }
} body.width2>fieldset.Header>div.output div.Action>div.tabs { padding-left:50px; }
body.width2>fieldset.Header>div.output>div.item.avatar { margin-right:var(--plugin-margin); }
body.width2>fieldset.Header>div.output>div.item.theme { display:none; }
body.width2>fieldset.Header>div.output>div.item.time { display:none; }
body.width2>fieldset.Header:not(.all):not(.tabs)>div.output div.item.title:first-child img { margin-right:0; }
// body.width2>fieldset.Header:not(.all):not(.tabs)>div.output div.item.title:first-child span { display:none; }
body.width2>fieldset.Footer:not(.all):not(.tabs)>div.output div.item.cmd { display:none; }
body.width2>fieldset.Footer:not(.all):not(.tabs)>div.output div.item.title { display:none; }

View File

@ -1,234 +1,245 @@
Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) { Volcanos(chat.ONIMPORT, {
can.Conf(aaa.USERNICK, msg.Option(aaa.USERNICK)||msg.Option(ice.MSG_USERNAME)||can.Conf(aaa.USERNICK)) _init: function(can, msg, target) {
can.onimport._title(can, msg, target), can.onimport._state(can, msg, target), can.onimport._search(can, msg, target)
can.onmotion.clear(can) can.onimport._avatar(can, msg, target), can.onimport._background(can, msg, target)
can.onimport._agent(can, msg, target) },
can.onimport._grant(can, msg, target) _title: function(can, msg, target) {
can.onimport._title(can, msg, target) can.core.List(can.base.getValid(can.Conf(chat.TITLE)||msg.result, [
can.onimport._state(can, msg, target) // can.user.title()||
can.onimport._search(can, msg, target) decodeURIComponent((window == top? can.user.info.titles: "")||can.misc.Search(can, ice.POD)||location.host)
can.onimport._background(can, msg, target) ]), function(item) {
can.onimport._avatar(can, msg, target) can.page.Append(can, target, [{view: [[html.ITEM, chat.TITLE, html.FLEX]], list: [{img: can.misc.ResourceFavicon(can)}, {text: item}], title: "返回主页", onclick: function(event) { can.onaction.title(event, can) }}])
can.onimport._menus(can, msg, target) })
can.base.isFunc(cb) && cb(msg) },
}, _state: function(can, msg, target) { can.core.List(can.base.Obj(can.Conf(chat.STATE)||msg.Option(chat.STATE), [cli.QRCODE, chat.THEME, aaa.LANGUAGE, aaa.USERNICK, aaa.AVATAR, mdb.TIME]).reverse(), function(item) {
_agent: function(can, msg, target) { if (can.user.isMobile && can.base.isIn(item, cli.QRCODE, chat.THEME, aaa.LANGUAGE, mdb.TIME)) { return }
if (can.user.mod.isPod) { can.page.Append(can, target, [{view: [[html.ITEM, chat.STATE, item], "", can.Conf(item)||msg.Option(item)||""], onclick: function(event) {
can.onaction.River(can) can.core.CallFunc([can.onaction, item], [event, can, item])
can.onaction.Footer(can) }, _init: function(target) { item == mdb.TIME && can.onimport._time(can, target)
} else if (can.user.isMobile) { item == aaa.AVATAR && can.page.Appends(can, target, [{img: lex.SP}])
can.onaction.River(can) item == aaa.USERNICK && !can.user.isMobile && can.page.Appends(can, target, [{text: can.Conf(aaa.USERNICK)}, {icon: icon.CHEVRON_DOWN}])
can.onaction.Footer(can) item == aaa.LANGUAGE && can.page.Appends(can, target, [{text: "EN"}, {text: " / "}, {text: "中"}])
} else if (can.user.isExtension) { item == chat.THEME && can.page.Appends(can, target, [{icon: icon.SUN}, {text: " / "}, {icon: icon.MOON}])
can.onaction.River(can) item == cli.QRCODE && can.page.Appends(can, target, [{icon: icon.qrcode, title: can.user.trans(can, cli.QRCODE)}])
} }}])
can.run({}, [chat.AGENT], function(msg) { if (!msg.Option(ssh.SCRIPT)) { return } }) },
can.require(can.base.Obj(msg.Option(ssh.SCRIPT)), function(can) { can.onaction.source(can, msg) }) _search: function(can, msg, target) { if (!can.user.isTechOrRoot(can)) { return }
}) can.page.Append(can, target, [{view: [[html.ITEM, chat.STATE]], list: [{icon: mdb.SEARCH}], onclick: function(event) {
}, can.onengine.signal(can, chat.ONOPENSEARCH, can.request(event, {type: mdb.FOREACH}))
_grant: function(can, msg, target) { }}])
if (can.misc.Search(can, chat.GRANT)) { return
if (can.user.confirm(chat.GRANT+ice.SP+can.misc.Search(can, chat.GRANT))) { can._search = can.onappend.input(can, {type: html.TEXT, _className: "args trans", icon: icon.SEARCH, name: mdb.SEARCH, value: can.misc.Search(can, "_search"), onkeydown: function(event) { can.onkeymap.input(event, can)
can.run(event, [ctx.ACTION, chat.GRANT, web.SPACE, can.misc.Search(can, chat.GRANT)]) event.key == code.ENTER && can.onengine.signal(can, chat.ONOPENSEARCH, can.request(event, {type: mdb.FOREACH, word: event.target.value||""}))
} }}, "", target, [chat.STATE])
can.misc.Search(can, chat.GRANT, "") can.onimport.menu(can, mdb.SEARCH, function() { can.onengine.signal(can, chat.ONOPENSEARCH, can.request(event, {type: mdb.FOREACH, word: can._search.value||""})) })
} },
}, _avatar: function(can, msg) { can.user.isExtension || can.user.isLocalFile || can.page.Modify(can, "div.state.avatar>img", {src: can.onexport.avatar(can)}) },
_title: function(can, msg, target) { _background: function(can, msg) { if (can.user.isExtension || can.user.isLocalFile) { return } can.onlayout.background(can, can.onexport.background(can)) },
can.user.title(can.misc.Search(can, chat.TITLE)||can.misc.Search(can, ice.POD)) _language: function(can) { can.page.Select(can, can._output, "div.item.language", function(target) {
!can.user.isMobile && can.core.List(msg.result||["shylinux.com/x/contexts"], function(item) { can.page.Appends(can, target, can.user.info.language.indexOf("zh") == 0? [{text: "中"}, {text: " / "}, {text: "EN"}]: [{text: "EN"}, {text: " / "}, {text: "中"}])
can.page.Append(can, target, [{view: [chat.TITLE, html.DIV, item], title: "返回主页", onclick: function(event) { }) },
can.onaction.title(event, can) _theme: function(can, theme) { return can.ui.diy&&can.ui.diy[theme]||theme },
}, onmouseenter: function(event) { _const: function(can) { can.core.Item(html.value, function(key, value) { html[key] = can.page.styleValueInt(can, "--"+can.base.replaceAll(key.toLowerCase(), "_", "-"))||value }) },
var list = msg.Table() _time: function(can, target) { can.core.Timer({interval: 100}, function() { can.onimport.time(can, target) }), can.onappend.figure(can, {action: "date"}, target) },
can.user.carte(event, can, {}, can.core.List(list, function(item) { return item.name }), function(event, item, meta, index) { time: function(can, target) { can.onimport.theme(can), target.innerHTML = can.user.time(can, null, can.Conf(mdb.TIME)||"%H:%M:%S %w") },
event.shiftKey? can.user.open(list[index].path): can.user.jumps(list[index].path) avatar: function(event, can, avatar) { can.user.isExtension || can.user.isLocalFile || can.runAction(event, aaa.AVATAR, [avatar], function(msg) {
}) can.user.info.avatar = avatar, can.onimport._avatar(can, msg), can.user.toastSuccess(can)
}}]) }) },
}) background: function(event, can, background) { can.user.isExtension || can.user.isLocalFile || can.runAction(event, aaa.BACKGROUND, [background], function(msg) {
}, can.user.info.background = background, can.onimport._background(can, msg), can.user.toastSuccess(can)
_state: function(can, msg, target) { }) },
can.core.List(can.base.Obj(msg.Option(chat.STATE)||can.Conf(chat.STATE), [mdb.TIME, aaa.USERNICK]), function(item) { language: function(can, language) { can.user.toastConfirm(can, can.user.trans(can, "change language to "+language), aaa.LANGUAGE, function() {
if (item == aaa.AVATAR ) { if (can.user.isLocalFile) { return } can.runAction(event, aaa.LANGUAGE, [language == ice.AUTO? "": language], function(msg) { can.user.reload(true) })
can.page.Append(can, target, [{view: can.base.join([chat.STATE, item]), list: [{img: ice.SP}], onmouseenter: function(event) { }) },
can.onaction.carte(event, can, [can.page.Format(html.IMG, "/share/local/avatar", 160)]) theme: function(can, theme, event) { theme && theme != ice.AUTO && can.runAction({}, chat.THEME, [theme])
}}]); return if (theme) { can.onengine.signal(can, "ontheme", can.request(event, {theme: theme})) }
} theme && can.require(["/chat/theme/"+theme+".css"])
theme && can.misc.localStorage(can, "can.theme", can._theme = theme == ice.AUTO? "": theme) && can.onengine.signal(can, chat.ONTHEMECHANGE, can.request(event, {theme: theme}))
can.page.Append(can, target, [{view: [can.base.join([chat.STATE, item]), html.DIV, (can.Conf(item)||"").slice(0, 10)], onmouseenter: function(event) { theme = can.onexport.theme(can); var list = [html.LIGHT, html.WHITE]
can.core.CallFunc([can.onaction, item], [event, can, item]) var change = can.page.ClassList.has(can, document.body, theme); can.user.theme(can, theme), change || can.onimport._const(can)
}, _init: function(target) { item == mdb.TIME && can.onimport._time(can, target) }}]) can.page.Select(can, can._output, "div.item.theme>i:first-child", function(target) {
}) if (list.indexOf(theme) == -1 && list.indexOf(theme[0]) == -1) { target.className = icon.MOON } else { target.className = icon.SUN }
}, })
_search: function(can, msg, target) { can.page.Select(can, can._output, "div.item.theme>i:last-child", function(target) {
var ui = can.onappend.input(can, {type: html.TEXT, name: mdb.SEARCH, onkeydown: function(event) { if (list.indexOf(theme) == -1 && list.indexOf(theme[0]) == -1) { target.className = icon.SUN } else { target.className = icon.MOON }
can.onkeypop.input(event, can); switch (event.key) { })
case lang.ENTER: can.onengine.signal(can, "onopensearch", can.request(event, {type: "*", word: event.target.value})) },
} menu: function(can, cmds, cb, trans) { can.base.isString(cmds) && (cmds = [cmds])
}}, "", target, "title search").parentNode return can.page.Append(can, can._output, [{view: cmds[0], list: can.core.List(can.base.getValid(cmds.slice(1), [cmds[0]]), function(item) {
can.user.isMobile && can.page.Modify(can, ui, {style: {float: html.RIGHT}}) return can.base.isString(item)? /* 1.string */ {view: [[html.ITEM, html.MENU, item], "", can.user.trans(can, item, trans)], onclick: function(event) { can.base.isFunc(cb) && cb(event, item, [item]) }}:
}, can.base.isArray(item)? /* 2.array */ {view: [[html.ITEM, html.MENU, item[0]]], list: [{text: can.user.trans(can, item[0], trans)}, {icon: icon.CHEVRON_DOWN}], onclick: function(event) { can.onkeymap.prevent(event)
_background: function(can, msg) { if (can.user.isExtension || can.user.isLocalFile) { return } can.onaction.carte(can.request(event, {_style: "header "+item[0]}), can, item.slice(1), function(event, button, meta) { can.base.isFunc(cb) && cb(event, button, item) }, trans)
msg.Option(aaa.BACKGROUND) && can.onlayout.background(can, "/share/local/background", document.body) }}: /* 3.others */ item
}, }) }])._target
_avatar: function(can, msg) { if (can.user.isExtension || can.user.isLocalFile) { return } },
msg.Option(aaa.AVATAR) && can.page.Modify(can, "div.state.avatar>img", {src: "/share/local/avatar"})
},
_menus: function(can, msg, target) {
var menus = can.base.Obj(msg.Option(chat.MENUS)||can.Conf(chat.MENUS), [chat.HEADER, ["setting", chat.BLACK, chat.WHITE, chat.PRINT]])
can.onimport.menu(can, can.user.mod.isPod||can.user.isMobile||can.user.isExtension? [chat.HEADER, chat.RIVER]: menus, function(event, button) {
can.core.CallFunc(can.onaction[button]||function(event, can) {
can.run(event, [button], function(msg) { can.user.toast(can, "执行成功", can.user.trans(can, button)) })
}, {event: event, can: can, button: button})
})
},
_time: function(can, target) {
can.core.Timer({interval: 500}, function() { can.onimport.time(can, target) })
can.onappend.figure(can, {action: "date", style: {"min-width": 306}}, target, function(sub) {
can.get("Action", "size", function(msg, top) {
can.page.Modify(can, sub._target, {style: {top: top, right: 0, left: null}})
})
}), target.onmouseenter = target.click
},
time: function(can, target) { can.onlayout.topic(can)
target.innerHTML = can.user.time(can, null, "%w %H:%M:%S")
},
background: function(event, can, url) { if (can.user.isExtension || can.user.isLocalFile) { return }
can.run(event, [ctx.ACTION, aaa.BACKGROUND, url], function(msg) { can.onimport._background(can, msg) })
},
avatar: function(event, can, url) { if (can.user.isExtension || can.user.isLocalFile) { return }
can.run(event, [ctx.ACTION, aaa.AVATAR, url], function(msg) { can.onimport._avatar(can, msg) })
},
menu: function(can, cmds, cb) {
return can.page.Append(can, can._output, [{type: cmds[0], list: can.core.List(cmds.slice(1), function(item) {
if (can.base.isString(item)) {
return {view: [html.MENU, html.DIV, can.user.trans(can, item)], onclick: function(event) {
can.base.isFunc(cb) && cb(event, item, cmds)
}}
} else if (can.base.isArray(item)) {
return {view: [html.MENU, html.DIV, can.user.trans(can, item[0])], onmouseenter: function(event) {
can.onaction.carte(event, can, item.slice(1), function(event, button) {
can.base.isFunc(cb) && cb(event, button, item)
})
}}
} else if (can.base.isObject(item)) {
return item
}
}) }]).first
},
}) })
Volcanos("onaction", {help: "交互数据", list: [], _init: function(can, meta, list, cb, target) { Volcanos(chat.ONACTION, {_init: function(can) {},
can.base.isFunc(cb) && cb() onsize: function(can) {
}, can.ConfHeight(can._target.offsetHeight), can.ConfWidth(can._target.offsetWidth), can.onimport.theme(can)
_trans: { },
"river": "菜单", onmain: function(can) {
"search": "搜索", if (window.parent == window && can.misc.Search(can, ice.MSG_SESSID) && can.misc.CookieSessid(can, can.misc.Search(can, ice.MSG_SESSID)) && !can.user.isMailMaster) {
"create": "创建", return can.misc.Search(can, ice.MSG_SESSID, "")
"share": "共享", } can.user.info.sessid = can.misc.Search(can, ice.MSG_SESSID)
function lang(msg, cb) { can.user.info.language = msg.SearchOrOption(aaa.LANGUAGE)||msg.Option(ice.MSG_LANGUAGE)
can.user.info.language? can.require([can.misc.Resource(can, nfs.SRC_TEMPLATE+web.CHAT_HEADER+"/language/"+can.user.info.language+".js")], cb, function(can, name, sub) { can.base.Copy(can.user._trans, sub._trans) }): cb && cb()
can.onmotion.delay(can, function() { can.onimport._language(can) })
}
function show(msg) { var p = can.misc.Search(can, "redirect_uri")
if (p && location.pathname == web.BASIC_LOGIN) { return location.replace(can.base.MergeURL(p, ice.MSG_SESSID, can.misc.CookieSessid(can))) }
var p = can.misc.Search(can, ice.BACK); if (p && location.pathname == web.CHAT_SSO) { return location.reload() }
can.user.info.nodetype = msg.Option(ice.MSG_NODETYPE)
can.user.info.nodename = msg.Option(ice.MSG_NODENAME)
can.user.info.userrole = msg.Option(ice.MSG_USERROLE)
can.user.info.username = msg.Option(ice.MSG_USERNAME)
can.user.info.usernick = can.Conf(aaa.USERNICK)
can.user.info.repos = msg.Option(nfs.REPOS)
can.user.info.email = msg.Option(aaa.EMAIL)
can.user.info.avatar = msg.Option(aaa.AVATAR)
can.user.info.background = msg.Option(aaa.BACKGROUND)
can.user.info.favicon = msg.Option("favicon")
can.user.info.titles = msg.Option("titles")||document.title
lang(msg, function() { can.onmotion.clear(can), can.onimport._init(can, can.request(), can._output), can.onengine.signal(can, chat.ONLOGIN) })
}
can.run(can.request({}, {_method: http.GET}), [], function(msg) { lang(msg)
if (msg.Option(ice.MSG_PROCESS) == "_open") {
// return can.user.jumps(msg.Option("_arg"))
}
can.ui.diy = can.base.Obj(msg.Option("diy"))||{}, can.__theme = can.onimport._theme(can, can.page.theme(function(theme) {
can.onengine.signal(can, chat.ONTHEMECHANGE, can.request(event, {theme: can.__theme = can.onimport._theme(can, theme)})), can.onimport.theme(can)
})), can.onimport.theme(can, can.misc.Search(can, "theme")||"")
can.onaction._menus[3] = [aaa.LANGUAGE, ice.AUTO].concat(can.core.List(msg["language.list"], function(item) { return can.base.trimSuffix(item, nfs._JS) }))
can.user.isMobile && (msg["theme.list"] = ["dark.css", "light.css"])
can.onaction._menus[2] = [chat.THEME, ice.AUTO].concat(can.core.List(msg["theme.list"], function(item) { return can.base.trimSuffix(item, nfs._CSS) }))
can.require(can.core.List(msg["theme.list"], function(item) { return nfs.SRC_TEMPLATE+web.CHAT_HEADER+"/theme/"+item }), function() {
can.user.info.titles = msg.Option("titles")||document.title
if (can.base.beginWith(location.pathname, nfs.WIKI_PORTAL, web.CHAT_CMD+web.WIKI_PORTAL, web.CHAT_CMD+web.CHAT_OAUTH_CLIENT)) { return show(msg) }
if (location.pathname == nfs.PS && can.base.beginWith(msg.Option(ice.MAIN)||"", nfs.WIKI_PORTAL, web.CHAT_CMD+web.WIKI_PORTAL)) { return show(msg) }
msg.Option(mdb.PLUGIN) && can.onappend.plugin(can, {space: msg.plugin[1], index: msg.Option(mdb.PLUGIN)}, function(sub) { can.onmotion.hidden(can, sub._target) }, document.body)
msg.Option(nfs.SCRIPT) && can.require(can.base.Obj(msg.Option(nfs.SCRIPT)), function(can) { can.onaction.source(can, msg) })
var tool = can._root.Action._conf.tool
if (can.Conf(aaa.USERNICK, (msg.Option(aaa.USERNICK)||msg.Option(ice.MSG_USERNICK)||msg.Option(ice.MSG_USERNAME)).slice(0, 8))
|| can.misc.Search(can, web.SHARE) || tool && can.base.isIn(can.user.info._cmd = tool[0]._command, "web.chat.oauth.client", web.PORTAL, aaa.OFFER, aaa.APPLY)) { return show(msg) }
can.onlayout._init(can), can.user.login(can, function() { can.onengine.signal(can, chat.ONMAIN, msg) }, msg)
})
})
},
onstorm_select: function(can, river, storm) { can.Conf(chat.RIVER, river), can.Conf(chat.STORM, storm) },
onaction_cmd: function(can) { can.onappend.style(can, html.HIDE), can.onmotion.delay(can, function() { can.onimport._const(can) }) },
onsearch_focus: function(can) { can._search && can._search.focus() },
onlayout: function(can, layout, before) { can.user.isMobile || can.page.ClassList.del(can, can._target, before), can.page.ClassList.add(can, can._target, layout) },
onshare: function(can, msg, args) { can.user.share(can, msg, [ctx.ACTION, chat.SHARE].concat(args||[])) },
onwebpack: function(can, msg) { can.user.input(msg._event, can, [{name: mdb.NAME, value: can.user.title()}], function(data) {
can.core.Item(Volcanos.meta.pack, function(key, msg) { can.core.List(["_event", "_can", "_xhr", ""], function(key) { delete(msg[key]) }) })
can.runAction(can.request({}, {args: "name,river,storm,title,theme,layout", _toast: "打包中...", content: JSON.stringify(Volcanos.meta.pack),
name: data.name, river: can.Conf(chat.RIVER), storm: can.Conf(chat.STORM), theme: can._theme, title: can.user.title(), layout: can.getAction(html.LAYOUT),
}), code.WEBPACK, [], function(msg) { can.user.download(can, web.SHARE_LOCAL+msg.Result(), name, nfs.HTML), can.user.toastSuccess(can, "打包成功", code.WEBPACK) })
}) },
"help": "帮助", title: function(event, can) { var args = {}; can.core.List(can.onaction._params, function(key) { var value = can.misc.Search(can, key); value && (args[key] = value) })
"tutor": "入门简介", var msg = can.request(event); can.onengine.signal(can, "ontitle", msg), can.core.List(msg.Append(), function(key) { args[key] = msg.Append(key) })
"manual": "使用手册", can.user.jumps(can.misc.MergeURL(can, args, true))
"service": "服务手册", },
"devops": "编程手册", avatar: function(event, can) { if (can.user.isMobile) { return can.onaction.usernick(event, can) }
"refer": "参考手册", var src = can.onexport.avatar(can); can.onaction.carte(can.request(event, {_style: "header avatar"}), can, ["<img src='"+src+"'>"])
},
usernick: function(event, can) { can.onaction.carte(can.request(event, {_style: "header usernick"}), can, can.onaction._menus) },
shareuser: function(event, can) { can.user.share(can, can.request(event), [ctx.ACTION, chat.SHARE, mdb.TYPE, aaa.LOGIN, mdb.NAME, can.user.title()]) },
theme: function(event, can) { can.page.Select(can, can._output, "div.item.theme>i:first-child", function(target) {
can.onimport.theme(can, can.onimport._theme(can, target.className == icon.SUN? html.DARK: html.LIGHT), event)
}) },
qrcode: function(event, can) { can.user.share(can, can.request(event, {link: location.href, _handle: ice.TRUE}), [ctx.ACTION, cli.QRCODE]) },
language: function(event, can) { can.onimport.language(can, can.user.info.language.indexOf("zh") == 0? "en-us": "zh-cn") },
email: function(event, can) { can.user.input(can.request(event, {to: can.user.info.email, subject: can.user.title()}), can, [{name: "to", _trans: "收件人", need: "must"}, "subject","content"], function(args) {
can.runAction(event, aaa.EMAIL, args, function() { can.user.toastSuccess(can) })
}) },
toimage: function(event, can) { can.onmotion.clearCarte(can), can.user.toimage(can, can.user.title(), can._target.parentNode) },
webpack: function(event, can) { can.onengine.signal(can, chat.ONWEBPACK, can.request(event)) },
setnick: function(event, can) { can.user.input(event, can, [{name: aaa.USERNICK, value: can.Conf(aaa.USERNICK)}], function(list) { can.runAction(event, aaa.USERNICK, [list[0]], function(msg) {
can.page.Select(can, can._output, can.core.Keys(html.DIV, aaa.USERNICK), function(item) { can.page.Modify(can, item, can.Conf(aaa.USERNICK, list[0])) }), can.user.toastSuccess(can)
}) }) },
setavatar: function(event, can) { can.user.input(event, can, [{name: aaa.AVATAR, value: can.Conf(aaa.AVATAR), action: mdb.ICONS}], function(list) { can.runAction(event, aaa.AVATAR, [list[0]], function(msg) {
can.page.Select(can, can._output, can.core.Keys(html.DIV, aaa.AVATAR)+" "+html.IMG, function(item) { item.src = can.misc.Resource(can, list[0]) }), can.user.toastSuccess(can)
}) }) },
setbackground: function(event, can) { can.user.input(event, can, [{name: aaa.BACKGROUND, value: can.Conf(aaa.BACKGROUND), action: mdb.ICONS}], function(list) { can.runAction(event, aaa.BACKGROUND, [list[0]], function(msg) {
}) }) },
clear: function(event, can) { can.onimport.background(event, can, "") },
logout: function(event, can) { can.user.logout(can) },
share: function(event, can, args) { can.user.share(can, can.request(event), [ctx.ACTION, chat.SHARE].concat(args||[])) },
carte: function(event, can, list, cb, trans) { return can.user.carte(event, can, can.onaction, list, cb, null, trans) },
"setting": "设置", _params: [log.DEBUG, chat.TITLE],
"black": "黑色主题", _menus: [
"white": "白色主题", cli.QRCODE, "shareuser",
"print": "打印主题", [chat.THEME], [aaa.LANGUAGE],
// [nfs.SAVE, aaa.EMAIL, web.TOIMAGE, code.WEBPACK],
[aaa.USER, "setnick", "setavatar", "setbackground", web.CLEAR, aaa.LOGOUT],
],
_trans: kit.Dict("shareuser", "共享用户", cli.QRCODE, "生成链接",
chat.THEME, "界面主题", aaa.LANGUAGE, "语言地区",
nfs.SAVE, "保存网页", aaa.EMAIL, "发送邮件", web.TOIMAGE, "生成图片", code.WEBPACK, "打包页面",
aaa.USER, "用户信息", "setnick", "设置昵称", "setavatar", "设置头像", "setbackground", "设置背景", aaa.PASSWORD, "修改密码", web.CLEAR, "清除背景", aaa.LOGOUT, "退出登录",
"shareuser": "共享用户", "change language to zh-cn", "切换语言为中文",
"setnick": "设置昵称", "change language to en-us", "切换语言为英文",
"language": "语言地区", "en-us", "英文", "zh-cn", "中文", "auto", "默认",
"chinese": "中文", "icons", {
"clear": "清除背景", shareuser: "bi bi-link-45deg",
}, theme: "bi bi-columns-gap",
onmain: function(can, msg) { language: "bi bi-spellcheck",
function init() { can.run({}, [], function(msg) { user: "bi bi-person-square",
can.base.Copy(can.onaction._trans, can.base.Obj(msg.Option(chat.TRANS), {})) },
can.onimport._init(can, msg, [], function(msg) { can.onengine.signal(can, chat.ONLOGIN, msg) }, can._output) ),
can.search({}, ["River.onmotion.toggle"])
}) }; can.search({}, ["River.onmotion.hidden"])
if (can.misc.Search(can, ice.MSG_SESSID)) {
can.misc.CookieSessid(can, can.misc.Search(can, ice.MSG_SESSID))
return can.misc.Search(can, ice.MSG_SESSID, "")
}
// 登录检查
can.user.isLocalFile? init(): can.run({}, [chat.CHECK], function(msg) {
can.Conf(aaa.USERNICK, msg.Option(ice.MSG_USERNICK)||msg.Option(ice.MSG_USERNAME))? init():
msg.Option(chat.SSO)? can.user.jumps(msg.Option(chat.SSO)):
can.user.login(can, init, msg.Option(aaa.LOGIN))
})
},
onstorm_select: function(can, msg, river, storm) { can.Conf(chat.RIVER, river), can.Conf(chat.STORM, storm) },
onsearchfocus: function(can) {
can.page.Select(can, can._output, "div.search input", function(target) { target.focus() })
},
title: function(event, can) {
var args = {}; can.core.List([chat.TITLE, chat.TOPIC, chat.LAYOUT], function(key) {
var value = can.misc.Search(can, key); value && (args[key] = value)
})
can.user.jumps(can.misc.MergeURL(can, args, true))
},
river: function(event, can) { can.onaction.River(can) },
black: function(event, can, button) { can.onlayout.topic(can, button), can.onlayout._init(can) },
white: function(event, can, button) { can.onlayout.topic(can, button), can.onlayout._init(can) },
print: function(event, can, button) { can.onlayout.topic(can, can.base.join([chat.WHITE, button]))
can.set("River", html.HEIGHT, -1), can.set("Action", html.HEIGHT, -1)
},
webpack: function(event, can) {
can.user.input(event, can, [{name: mdb.NAME, value: can.user.title()}], function(ev, button, meta, list) {
can.core.Item(Volcanos.meta.pack, function(key, msg) {
can.core.List(["_event", "_can", "_xhr", ice.MSG_SESSID, ""], function(key) { delete(msg[key]) })
})
var msg = can.request(event, {
name: meta.name, content: JSON.stringify(Volcanos.meta.pack),
river: can.Conf(chat.RIVER), storm: can.Conf(chat.STORM),
})
var toast = can.user.toast(can, "打包中...", code.WEBPACK, 1000000)
can.run(event, [code.WEBPACK], function(msg) {
toast.close(), can.user.toast(can, "打包成功", code.WEBPACK)
can.user.download(can, "/share/local/"+msg.Result(), name+".html")
})
})
},
carte: function(event, can, list, cb) { can.user.carte(event, can, can.onaction, list, cb) },
share: function(event, can, arg) { can.user.share(can, can.request(event), [ctx.ACTION, chat.SHARE].concat(arg||[])) },
usernick: function(event, can) {
can.onaction.carte(event, can, ["shareuser", "setnick", [aaa.LANGUAGE, aaa.CHINESE, aaa.ENGLISH], cli.CLEAR, aaa.LOGOUT])
},
shareuser: function(event, can) { can.user.share(can, can.request(event), [ctx.ACTION, chat.SHARE, mdb.TYPE, aaa.LOGIN]) },
setnick: function(event, can) {
var ui = can.user.input(event, can, [{name: aaa.USERNICK, value: can.Conf(aaa.USERNICK)}], function(ev, button, data, list, args) {
can.run(event, [aaa.USERNICK, list[0]], function(msg) {
can.page.Select(can, can._output, can.core.Keys(html.DIV, aaa.USERNICK), function(item) {
can.page.Modify(can, item, can.Conf(aaa.USERNICK, list[0]))
}), can.user.toastSuccess(can)
}, true)
})
can.user.isMobile && can.page.Modify(can, ui._target, {style: {top: 40, right: 0, left: ""}})
},
chinese: function(event, can) { can.misc.Search(can, aaa.LANGUAGE, "zh") },
english: function(event, can) { can.misc.Search(can, aaa.LANGUAGE, "en") },
clear: function(event, can) { can.onimport.background(event, can, ""), can.onimport.avatar(event, can, ""), can.user.reload(true) },
logout: function(event, can) { can.user.logout(can) },
River: function(can) { can.search({}, ["River.onmotion.toggle"]) },
Footer: function(can) { can.search({}, ["Footer.onmotion.toggle"]) },
}) })
Volcanos("onexport", {help: "导出数据", list: [], Volcanos(chat.ONEXPORT, {
height: function(can) { return can._target.offsetHeight }, language: function(can) { return can.user.info.language },
topic: function(can) { return can._topic }, avatar: function(can) { return can.misc.Resource(can, can.user.info.avatar == "void"? "": can.user.info.avatar) },
background: function(can) { return can.user.info.background == "void"? "": can.user.info.background },
theme: function(can) { return can._theme || can.misc.SearchOrConf(can, chat.THEME) || can.__theme || "" },
height: function(can) { return can._target.offsetHeight },
})
Volcanos(chat.ONPLUGIN, {
location: shy("请求地址", {copy: function(can) { can.user.copy(msg._event, can, location.href) }}, [web.LINK, ice.LIST, ice.COPY], function(can, msg, cb) {
can.runAction(can.request({}, kit.Dict(web.LINK, location.href)), web.SHARE, [], function(res) {
msg.Echo(res.Append(mdb.TEXT)).Status(kit.Dict(web.LINK, res.Append(mdb.NAME))), can.base.isFunc(cb) && cb(msg)
})
}),
sessionStorage: shy("会话存储", {
create: shy([mdb.NAME, mdb.VALUE], function(can, name, value) { can.misc.sessionStorage(can, name, value) }),
remove: shy(function(can, name) { name && can.misc.sessionStorage(can, name, "") }),
prunes: shy(function(can, name) { can.core.Item(can.misc.sessionStorage(can), function(key, value) { can.misc.sessionStorage(can, key, "") }) }),
modify: shy(function(can, msg, arg) { if (arg[0] == mdb.VALUE) { can.misc.sessionStorage(can, msg.Option(mdb.NAME), arg[1]) } else {
can.misc.sessionStorage(can, arg[1], msg.Option(mdb.VALUE)), can.misc.sessionStorage(can, msg.Option(mdb.NAME), "")
} }),
}, [web.FILTER, ice.LIST, mdb.CREATE, mdb.PRUNES], function(can, msg, arg) { msg.Defer(function() { msg.PushAction(mdb.REMOVE).StatusTimeCount() })
can.core.Item(can.misc.sessionStorage(can), function(name, value) { can.base.contains(name, arg[0]) && msg.Push(mdb.NAME, name).Push(mdb.VALUE, value) })
}),
localStorage: shy("本地存储", {
create: shy([mdb.NAME, mdb.VALUE], function(can, name, value) { can.misc.localStorage(can, name, value) }),
remove: shy(function(can, name) { name && can.misc.localStorage(can, name, "") }),
modify: shy(function(can, msg, arg) { if (arg[0] == mdb.VALUE) { can.misc.localStorage(can, msg.Option(mdb.NAME), arg[1]) } else {
can.misc.localStorage(can, arg[1], msg.Option(mdb.VALUE)), can.misc.localStorage(can, msg.Option(mdb.NAME), "")
} }),
}, [web.FILTER, ice.LIST, mdb.CREATE], function(can, msg, arg) { msg.Defer(function() { msg.PushAction(mdb.REMOVE).StatusTimeCount() })
can.core.Item(can.misc.localStorage(can), function(name, value) { can.base.contains(name, arg[0]) && msg.Push(mdb.NAME, name).Push(mdb.VALUE, value) })
}),
cookie: shy("会话参数", {
create: shy([mdb.NAME, mdb.VALUE], function(can, name, value) { can.misc.Cookie(can, name, value) }),
remove: shy(function(can, name) { name && can.misc.Cookie(can, name, "") }),
modify: shy(function(can, msg, arg) { if (arg[0] == mdb.VALUE) { can.misc.Cookie(can, msg.Option(mdb.NAME), arg[1]) } else {
can.misc.Cookie(can, arg[1], msg.Option(mdb.VALUE)), can.misc.Cookie(can, msg.Option(mdb.NAME), "")
} }),
}, [web.FILTER, ice.LIST, mdb.CREATE], function(can, msg, arg) { msg.Defer(function() { msg.PushAction(mdb.REMOVE).StatusTimeCount() })
can.core.Item(can.misc.Cookie(can), function(name, value) { can.base.contains(name, arg[0]) && msg.Push(mdb.NAME, name).Push(mdb.VALUE, value) })
}),
language: shy("语言地区", {_init: function(can) { can.Option(aaa.LANGUAGE, can.user.info.language||ice.AUTO) }}, ["language:select=auto,zh,en", ctx.RUN], function(can, msg, arg) { can.onimport.language(can, arg[0]) }),
avatar: shy("用户头像", function(can, sub, cb) { can.page.Append(can, sub._output, [{img: can.user.info.avatar, style: kit.Dict(html.MAX_HEIGHT, sub.ConfHeight(), html.MAX_WIDTH, sub.ConfWidth())}]) }),
background: shy("背景图片", function(can, sub, cb) { can.page.Append(can, sub._output, [{img: can.user.info.background, style: kit.Dict(html.MAX_HEIGHT, sub.ConfHeight(), html.MAX_WIDTH, sub.ConfWidth())}]) }),
theme: shy("界面主题", {_init: function(can) { can.Option(chat.THEME, can.getHeader(chat.THEME)) },
save: function(can, sup) { can.user.downloads(can, sup._themes[can.Option(chat.THEME)], can.Option(chat.THEME), nfs.CSS) },
}, ["theme:select=auto,dark,light,print,white,black", ctx.RUN, nfs.SAVE], function(can, msg, arg) {
if (arg[0] == ice.AUTO) { arg[0] = "", can._theme = "" } can.misc.localStorage(can, "can.theme", arg[0]), can.onimport.theme(can, arg[0])
}),
title: shy("网页标题", [chat.TITLE], function(can, msg, arg) { msg.Echo(can.user.title(arg[0])) }),
logout: shy("退出登录", kit.Dict(aaa.LOGOUT, shy("退出", function(can) { can.user.logout(can._root.Header) })), [aaa.LOGOUT]),
}) })

View File

@ -1,31 +1,36 @@
fieldset.River { fieldset.River { width:var(--river-width); float:left; position:relative; }
float:left; overflow:auto; fieldset.River>div.action:not(.hide) { margin-top:var(--plugin-margin); width:100%; position:absolute; }
} fieldset.River>div.action div.item.notice input { border:0; }
fieldset.River>div.output div.item { fieldset.River>div.action div.item:hover input { background-color:var(--notice-bg-color); color:var(--notice-fg-color); }
border-left:solid 3px #00ffae; fieldset.River>div.output { transition:all .3s; }
padding:3px 16px; fieldset.River>div.output div.item { font-family:var(--legend-font-family); padding:var(--legend-padding); border-left:#00ffae solid 3px; }
} fieldset.River>div.output div.item.select { color:var(--panel-hover-fg-color); }
fieldset.River>div.output div.item.select { fieldset.River>div.output div.item:hover { color:var(--panel-hover-fg-color); }
background-color:#2e515f; fieldset.River>div.output div.item>i:first-child { margin-right:var(--button-margin); }
} fieldset.River>div.output div.list div.item { border-left:#ccdc4c solid 3px; }
fieldset.River>div.output div.item:hover { fieldset.River>div.output div.list { margin-left:var(--legend-padding); }
background-color:#2e515f; fieldset.River>div.output { margin:var(--river-margin) 0; margin-bottom:20px; }
} fieldset.River>div.toggle { rotate:90deg; right:calc(50% - 5px); }
fieldset.River>div.output div.list { fieldset.River>div.toggle.prev { top:0; }
margin-left:8px; padding-left:5px; fieldset.River>div.toggle.next { bottom:-52px; }
} fieldset.River:not(:hover)>div.toggle { visibility:hidden; }
fieldset.River>div.output div.list div.item { fieldset.River:not(.all):not(.tabs):not(.page) { width:var(--header-height); }
border-left:solid 3px #ccdc4c; fieldset.River:not(.all):not(.tabs):not(.page)>div.action { flex-direction:column; overflow:hidden; }
background-color:#073540b5; fieldset.River:not(.all):not(.tabs):not(.page)>div.action div.item { margin-right:0; }
font-family:monospace; fieldset.River:not(.all):not(.tabs):not(.page)>div.action div.item.share { display:none; }
font-size:14px; fieldset.River:not(.all):not(.tabs):not(.page)>div.action div.item.refresh { display:none; }
} fieldset.River:not(.all):not(.tabs):not(.page)>div.action div.item>input { display:none; }
fieldset.River>div.output div.list div.item.select { fieldset.River:not(.all):not(.tabs):not(.page)>div.action div.item>span { display:unset; }
background-color:#2e515f; fieldset.River:not(.all):not(.tabs):not(.page)>div.output div.item { padding:var(--button-padding); }
} fieldset.River:not(.all):not(.tabs):not(.page)>div.output div.item>span { display:none; }
fieldset.River>div.output div.list div.item:hover { fieldset.River:not(.all):not(.tabs):not(.page)>div.output>div.item>i:last-child { display:none; }
background-color:#2e515f; fieldset.River:not(.all):not(.tabs):not(.page)>div.output>div.item>i:first-child { font-size:24px; }
} fieldset.River:not(.all):not(.tabs):not(.page)>div.output div.item>i:first-child { margin-right:0; }
body.mobile fieldset.River { fieldset.River:not(.all):not(.tabs):not(.page)>div.output>div.list { margin-left:var(--input-margin); }
z-index:10; fieldset.River.page { display:none; }
} fieldset.River.tabs>div.action:not(.hide) { margin-top:0; }
fieldset.River.tabview>div.action:not(.hide) { margin-top:calc(var(--plugin-margin) + var(--plugin-padding)); }
fieldset.River.tabview>div.output div.item { display:flex; align-items:center; justify-content:center; }
body.void fieldset.River>div.action { display:none; }
body.mobile fieldset.River>div.output { margin-top:16px; }
body.mobile fieldset.River>div.toggle.prev { top:-52px; }

View File

@ -1,286 +1,166 @@
Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) { (function() { const CAN_RIVER = "can.river", CAN_STORM = "can.storm"
if (msg.Option(ice.MSG_RIVER) == "_share") { return can.onmotion.hidden(can) } Volcanos(chat.ONIMPORT, {
can.onmotion.clear(can), can.river_list = {}, can.storm_list = {} _init: function(can, msg) { can.onimport._main(can, msg), can.onappend.style(can, html.FLEX, can._action)
var select; can.page.Appends(can, can._output, msg.Table(function(item, index) {
can.onimport._main(can, msg), can.onimport._menu(can, msg) return can.onimport._river(can, item, function(target) { (index == 0 || item.hash == can._main_river) && (select = target) })
var select; can.page.Append(can, can._output, msg.Table(function(item, index) { })), select && select.click(), can.onimport._menu(can, msg)
return can.onimport._river(can, item, function(target) { },
(index == 0 || item.hash == can._main_river) && (select = target) _main: function(can, msg) { can.ui = {river_list: {}, storm_list: {}, sublist: {}}
}) var ls = can.misc.SearchHash(can); msg.Table(function(item) { item.main && (can._main_river = item.hash) })
})), select && select.click() can._main_river = ls[0]||can.misc.SearchOrConf(can, chat.RIVER)||msg.Option(ice.MSG_RIVER)||can._main_river||(can.misc.Search(can, ice.MSG_DEBUG) == ice.TRUE? "project": "profile")
}, can._main_storm = ls[1]||can.misc.SearchOrConf(can, chat.STORM)||msg.Option(ice.MSG_STORM)
_main: function(can, msg) { can._main_river = "project", can._main_storm = "studio" },
if (can.user.isExtension) { var args = Volcanos.meta.args _river: function(can, meta, cb) { return {view: html.ITEM, title: meta.name, list: [{icon: meta.icon}, {text: meta.name}, {icon: icon.CHEVRON_DOWN}], _init: function(target) { can.ui.river_list[meta.hash] = target, cb(target) },
can._main_river = args.river||"product", can._main_storm = args.storm||"chrome" onclick: function(event) { can.onaction.storm(event, can, meta.hash) }, oncontextmenu: function(event) { can.onaction.carte(event, can, can.onaction._menu, meta.hash) },
} } },
if (can.user.isMobile) { can._main_river = "product", can._main_storm = "office" } _storm: function(can, meta, river) { return {view: html.ITEM, title: meta.name, list: [{icon: meta.icon}, {text: meta.name}], _init: function(target) { can.ui.storm_list[can.core.Keys(river, meta.hash)] = target },
if (can.user.isWeiXin) { can._main_river = "service", can._main_storm = "wx" } onclick: function(event) { can.onaction.action(event, can, river, meta.hash) }, oncontextmenu: function(event) { can.onaction.carte(event, can, can.ondetail._menu, river, meta.hash) },
} },
can._main_title = can.misc.Search(can, chat.TITLE)||msg.Option(ice.MSG_TITLE)||Volcanos.meta.args.title||can.misc.Search(can, ice.POD)||can._main_title _menu: function(can, msg) { can.user.isMobile || can.user.mod.isPod? can.onmotion.hidden(can, can._action): can.onappend._action(can, can.onaction.list, can._action) },
can._main_river = can.misc.Search(can, chat.RIVER)||msg.Option(ice.MSG_RIVER)||Volcanos.meta.args.river||can._main_river
can._main_storm = can.misc.Search(can, chat.STORM)||msg.Option(ice.MSG_STORM)||Volcanos.meta.args.storm||can._main_storm
},
_menu: function(can, msg) { if (can.user.mod.isPod) { return }
can.search({}, ["Header.onimport.menu"].concat(can.base.Obj(msg.Option(chat.MENUS), can.ondetail.menus)), function(event, button) {
can.core.CallFunc([can.ondetail, button], [event, can, button, can.Conf(chat.RIVER), can.Conf(chat.STORM)])
})
},
_carte: function(can, list, river, storm) { if (can.user.isMobile) { return }
can.onaction.carte(event, can, list, function(event, button, module) {
module[button](event, can, button, river, storm)
})
},
_river: function(can, meta, cb) {
return {text: [meta.name, html.DIV, html.ITEM], onclick: function(event) {
can.onaction.storm(event, can, meta.hash)
}, onmouseenter: function(event) {
can.onimport._carte(can, can.ondetail.list, meta.hash)
}, _init: function(target) { cb(target)
can.river_list[meta.hash] = target
}}
},
_storm: function(can, meta, river) {
return {text: [meta.name, html.DIV, html.ITEM], onclick: function(event) {
can.onaction.action(event, can, river, meta.hash)
can.user.title(can._main_title||meta.name)
}, onmouseenter: function(event) {
can.onimport._carte(can, can.ondetail.sublist, river, meta.hash)
}, _init: function(target) {
can.storm_list[can.core.Keys(river, meta.hash)] = target
}}
},
}) })
Volcanos("onengine", {help: "解析引擎", list: [], _engine: function(event, can, msg, panel, cmds, cb) { Volcanos(chat.ONACTION, {list: [mdb.CREATE, web.SHARE, web.REFRESH],
var list = can._root.river _init: function(can) {
cmds.length == 0 && can.core.Item(list, function(key, value) { can.db.storm_list = {}, can.onmotion.hidden(can)
msg.Push({hash: key, name: can.user.language(can) == "en"? key: value.name}) // 群组列表 var next = can.page.unicode.next, prev = can.page.unicode.prev
}); if (cmds.length != 1 && cmds[1] != chat.STORM) { return false } can._prev = can.page.Append(can, can._target, [{view: [[html.TOGGLE, mdb.PREV], "", prev], onclick: function(event) {
can._output.scrollBy && can._output.scrollBy(0, -10000)
var river = list[cmds[0]]; if (!river) { return false } }}])._target
can.core.Item(river.storm, function(key, value) { can._next = can.page.Append(can, can._target, [{view: [[html.TOGGLE, mdb.NEXT], "", next], onclick: function(event) {
msg.Push({hash: key, name: can.user.language(can) == "en"? key: value.name}) // 应用列表 can._output.scrollBy && can._output.scrollBy(0, 10000)
}), can.base.isFunc(cb) && cb(msg); return true }}])._target
}, can._output.onscroll = function() { can.onexport.scroll(can) }
},
onlogin: function(can, msg) { can.run(can.request({}, {_method: http.GET}), [], function(msg) { if (msg.Option(ice.MSG_RIVER)) { return can.page.Remove(can, can._target) }
can.onimport._init(can, msg); if (can.user.isMobile || can.user.isExtension) { return can.page.ClassList.add(can, can._target, ice.AUTO) }
can.onmotion.toggle(can, can._target, true), can.onlayout._init(can)
}) },
onaction_touch: function(can, msg) { can.user.isMobile && can.onmotion.hidden(can) },
onaction_notool: function(can, msg, river, storm) { can.ondetail["addcmd"](msg._event, can, "addcmd", river, storm) },
onsearch: function(can, msg, arg) { if (arg[0] == chat.STORM) { can.onexport.storm(can, msg, arg) } },
onlayout: function(can, layout, before) { can.page.ClassList.del(can, can._target, before), can.page.ClassList.add(can, can._target, layout) },
create: function(event, can) { can.user.input(can.request(event, {title: "创建群组"}), can, [
{name: mdb.TYPE, values: [aaa.TECH, aaa.VOID], _trans: "类型"},
{name: mdb.NAME, value: "hi", _trans: "群名", need: "must"},
{name: mdb.ICON, value: "", _trans: "图标"},
{name: mdb.TEXT, value: "hello", _trans: "简介"},
], function(args) { can.runAction(event, mdb.CREATE, args, function(msg) { can.misc.Search(can, {river: msg.Result()}) }) }) },
share: function(event, can) { can.core.CallFunc(can.ondetail.share, {event: event, can: can}) },
onsize: function(can, height) { var margin = 68, _margin = margin
can.page.style(can, can._output, html.MARGIN, "0px", html.HEIGHT, "", html.MAX_HEIGHT, "")
if (can.user.isMobile || !can.user.isTechOrRoot(can)) { margin = 16 }
if (can._output.offsetHeight < height-margin) {
margin += (height-margin-can._output.offsetHeight)/4
} else {
can.page.style(can, can._output, html.MAX_HEIGHT, height-margin-16)
}
can.page.style(can, can._output, html.MARGIN, margin+"px 0px "+(margin-_margin)+"px")
can._output.scrollTop = can._scrollTop
can.onexport.scroll(can)
},
refresh: function(event, can) { can.misc.Search(can, {river: can.Conf(chat.RIVER), storm: can.Conf(chat.STORM)}) },
storm: function(event, can, river) { can.onmotion.select(can, can._output, html.DIV_ITEM, can.ui.river_list[river])
function _menu(list) { can.onlayout._init(can), can.page.ClassList.set(can, can.ui.river_list[river], "open", can.page.isDisplay(list)) }
var list = can.ui.sublist[river]; if (list) { return can.onmotion.toggle(can, list), _menu(list) }
can.run({}, [river, chat.STORM], function(msg) { var next = can.ui.river_list[river].nextSibling
if (msg.Length() == 0) { return can.user.isLocalFile? can.user.toastFailure(can, "miss data"): can.onengine.signal(can, chat.ONACTION_NOSTORM, can.request({}, {river: river})) }
can.db.storm_list[river] = msg.Table()
var _main_storm; msg.Table(function(item) { item.main && (_main_storm = item.hash) }), _main_storm = can._main_storm || _main_storm || (
can.user.info.nodetype == web.WORKER? web.DESKTOP: can.misc.Search(can, ice.MSG_DEBUG) == ice.TRUE? "studio": (can.user.info.nodetype == web.SERVER? web.DREAM: "desktop")
)
var select = 0; list = can.page.Append(can, can._output, [{view: html.LIST, list: msg.Table(function(item, index) {
river == can._main_river && (item.hash == _main_storm) && (select = index)
return can.onimport._storm(can, item, river)
}) }])._target, next && can._output.insertBefore(list, next), can.ui.sublist[river] = list, _menu(list), list.children.length > 0 && list.children[select].click()
})
},
action: function(event, can, river, storm) {
can._scrollTop = can._output.scrollTop
can.page.Select(can, can._output, [html.DIV_LIST, html.DIV_ITEM], function(target) { can.page.ClassList.del(can, target, html.SELECT) })
can.onmotion.toggle(can, can.ui.sublist[river], true)
can.onmotion.select(can, can.ui.sublist[river], html.DIV_ITEM, can.ui.storm_list[can.core.Keys(river, storm)])
can.onmotion.select(can, can._output, html.DIV_ITEM, can.ui.river_list[river])
var list = can.db.storm_list[river];
can.user.isMobile && can.onmotion.hidden(can, can._root.Footer._target, list.length > 1)
can.user.isMobile && can.onmotion.delay(can, function() {
var menu = can.setFooterMenu(list, function(event, button, list) { can.onaction.action(event, can, river, button) })
can.page.SelectChild(can, menu, html.DIV_ITEM, function(target, index) { can.page.ClassList.set(can, target, html.SELECT, list[index].hash == can.Conf("storm")) })
}, 300), can.onengine.signal(can, chat.ONSTORM_SELECT, can.request(event, {river: can.Conf(chat.RIVER, river), storm: can.Conf(chat.STORM, storm)}))
},
carte: function(event, can, list, river, storm) { can.onkeymap.prevent(event); if (can.core.Value(can._root, can.core.Keys(chat.RIVER, river))) { return }
can.request(event, {river: river, storm: storm}); storm? can.user.carteRight(event, can, can.ondetail, list): can.user.carteRight(event, can, can.onaction, list)
},
_menu: ["addapp", "rename", "remove"],
_trans: {addapp: "添加应用", rename: "重命名群组", remove: "删除群组"},
addapp: function(event, can, button, river) { can.ondetail.create(event, can, button, river) },
rename: function(event, can, button, river) { can.user.input(event, can, [mdb.NAME, mdb.ICON], function(args) {
can.runAction(event, mdb.MODIFY, [mdb.HASH, river].concat(args), function(msg) { can.page.Modify(can, can.ui.river_list[river], args[1]), can.user.toastSuccess(can) })
}) },
remove: function(event, can, button, river) { can.runAction(event, mdb.REMOVE, [mdb.HASH, river], function(msg) { can.misc.Search(can, {river: "", storm: ""}) }) },
onaction_nostorm: function(can, msg, river) { can.ondetail.create({}, can, mdb.CREATE, river) },
onaction_remove: function(can, msg, river, storm, id) { can.run(can.request({}), [river, storm, chat.STORM, ctx.ACTION, mdb.DELETE, mdb.ID, id], function() { }) },
}) })
Volcanos("onaction", {help: "控件交互", list: [], _init: function(can, msg, list, cb, target) { Volcanos(chat.ONDETAIL, {
can.onengine.plugin(can, "info", shy("信息", {}, ["text", "list", "back"], function(msg, cmds) { _menu: ["share", "savearg", "addcmd", "rename", "remove"],
msg.Echo(JSON.stringify(can)) _trans: {share: "共享应用", savearg: "保存参数", addcmd: "添加工具", rename: "重命名应用", remove: "删除应用"},
})) share: function(event, can, button, river, storm) { can.onmotion.share(event, can, [{name: chat.TITLE, value: can.user.title()}, {name: chat.THEME, values: [ice.AUTO, html.DARK, html.LIGHT, cli.WHITE, cli.BLACK]}], [mdb.TYPE, chat.STORM, chat.RIVER, river, chat.STORM, storm]) },
can.onengine.plugin(can, "log", shy("日志", {}, ["text", "list", "back"], function(msg, cmds) { savearg: function(event, can, button, river, storm) { can.getAction(ctx.ARGS, function(args, sub, next, index, array) { var toast = can.user.toast(can, (index+1)+nfs.PS+array.length, button, 10000, (index+1)*100/array.length)
console.log(cmds[0]) can.run({}, [river, storm, chat.STORM, ctx.ACTION, mdb.MODIFY, mdb.ID, sub.Conf(mdb.ID), ctx.ARGS, JSON.stringify(args)], function() {
msg.Option(ice.MSG_DISPLAY, "/plugin/story/pie.js") can.onmotion.delay(can, function() { toast.close(), next(), index == array.length-1 && can.user.toastSuccess(can) })
})) })
can.onengine.plugin(can, "pie", shy("比例图", {}, ["list", "back"], function(msg, cmds) { }) },
msg.Option(ice.MSG_DISPLAY, "/plugin/story/pie.js") addcmd: function(event, can, button, river, storm) { can.user.input(can.request(event, {title: "添加工具"}), can, [
msg.Push("value", 200) {name: web.SPACE, _trans: "空间"},
msg.Push("value", 300) {name: ctx.INDEX, need: "must", _trans: "命令"}, {name: ctx.ARGS, _trans: "参数"},
msg.Push("value", 400) {name: mdb.ICON, _trans: "图标"}, {name: ctx.STYLE, _trans: "样式"}, {name: ctx.DISPLAY, _trans: "脚本"},
})) ], function(args) { can.run({}, [river, storm, chat.STORM, ctx.ACTION, mdb.INSERT].concat(args), function(msg) {
can.base.isFunc(cb) && cb() can.onengine.signal(can, chat.ONSTORM_SELECT, can.request(event, {river: can.Conf(chat.RIVER, river), storm: can.Conf(chat.STORM, storm), refresh: ice.TRUE}))
}, }) }) },
onlogin: function(can, msg) { rename: function(event, can, button, river, storm) { can.user.input(event, can, [mdb.NAME, mdb.ICON], function(args) {
can.onappend._action(can, can.Conf(ctx.ACTION)||can.onaction.list) can.run(event, [river, storm, chat.STORM, ctx.ACTION, mdb.MODIFY].concat(args), function() { can.page.Modify(can, can.ui.storm_list[can.core.Keys(river, storm)], args[1]), can.user.toastSuccess(can) })
can.run({}, [], function(msg) { can.onimport._init(can, msg, [], null, can._output) }) }) },
}, remove: function(event, can, button, river, storm) { can.run(event, [river, storm, chat.STORM, ctx.ACTION, mdb.REMOVE], function(msg) { can.misc.Search(can, {river: river, storm: ""}) }) },
onsearch: function(can, msg, word) { create: function(event, can, button, river) { can.user.input(can.request(event, {title: "添加应用"}), can, [
if (word[0] == "*" || word[0] == chat.STORM) { can.onexport.storm(can, msg, word) } {name: mdb.NAME, value: "hi", _trans: "名称", need: "must"},
}, {name: mdb.ICON, value: "", _trans: "图标"},
onstorm_select: function(can, msg, river, storm) { var args = {river: river, storm: storm} {name: mdb.TEXT, value: "hello", _trans: "简介"},
if (can.user.isExtension) { localStorage.setItem(ctx.ARGS, JSON.stringify(args)) } ], function(args) { can.run({}, [river, chat.STORM, ctx.ACTION, mdb.CREATE].concat(args), function(msg) { can.misc.Search(can, {river: river, storm: msg.Result()}) }) }) },
},
onaction_touch: function(can, msg) {
can.onmotion.float.del(can, chat.CARTE)
can.user.isMobile && can.onmotion.hidden(can)
},
onaction_nostorm: function(can, msg, river, storm) {
can.ondetail["添加工具"](msg._event, can, "添加工具", river, storm)
},
carte: function(event, can, list, cb) {
can.user.carteRight(event, can, can.ondetail, list, cb)
},
storm: function(event, can, river) { can.sublist = can.sublist||{}
can.onmotion.select(can, can._output, "div.item", can.river_list[river])
var list = can.sublist[river]; if (list) { return can.onmotion.toggle(can, list) }
can.run({}, [river, chat.STORM], function(msg) {
var select = 0; list = can.page.Append(can, can._output, [{view: html.LIST, list: msg.Table(function(item, index) {
river == can._main_river && item.hash == can._main_storm && (select = index)
return can.onimport._storm(can, item, river)
}) }]).first, list.children.length > 0 && list.children[select].click()
event.target.nextSibling && can._output.insertBefore(list, event.target.nextSibling)
can.sublist[river] = list
})
},
action: function(event, can, river, storm) {
can.page.Modify(can, can.sublist[river], {style: {display: html.BLOCK}})
can.onmotion.select(can, can._output, "div.item", can.river_list[river])
can.onmotion.select(can, can._output, "div.list div.item", can.storm_list[can.core.Keys(river, storm)])
can.onengine.signal(can, "onstorm_select", can.request(event, {
river: can.Conf(chat.RIVER, river), storm: can.Conf(chat.STORM, storm),
}))
},
create: function(event, can) {
can.user.trans(can, {"public": "公开群", "protected": "内部群", "private": "私有群"})
can.user.input(event, can, [
{name: mdb.TYPE, values: [chat.PUBLIC, chat.PROTECTED, chat.PRIVATE], _trans: "类型"},
{name: mdb.NAME, value: "hi", _trans: "群名"}, {name: mdb.TEXT, value: "hello", _trans: "简介"},
], function(event, button, meta, list, args) {
can.run(event, [ctx.ACTION, mdb.CREATE].concat(args), function(msg) {
can.misc.Search(can, {river: msg.Result()})
})
})
},
refresh: function(event, can) {
var args = {river: can.Conf(chat.RIVER), storm: can.Conf(chat.STORM),
topic: can.get("Header", "topic"), layout: can.get("Action", "layout"),
}
if (can.user.isExtension) { localStorage.setItem(ctx.ARGS, JSON.stringify(args)) }
can.misc.Search(can, args)
},
}) })
Volcanos("ondetail", {help: "菜单交互", Volcanos(chat.ONEXPORT, {
list: ["共享群组", "添加应用", "添加设备", "添加用户", "重命名群组", "删除群组"], width: function(can) { return can._target.offsetWidth },
sublist: ["共享应用", "添加工具", "保存参数", "重命名应用", "删除应用"], storm: function(can, msg, arg) { can.core.Item(can._root.river, function(river, value) { can.core.Item(value.storm, function(storm, item) { if (arg[1] != "" && storm.indexOf(arg[1]) == -1 && item.name.indexOf(arg[1]) == -1) { return }
menus: [chat.RIVER, msg.Push({ctx: ice.CAN, cmd: can._name, type: river, name: storm, text: shy("跳转", function(event) { can.onaction.action(event, can, river, storm) })})
["create", "创建群组", "添加应用", "添加工具", "添加设备", "创建空间"], }) }) },
["share", "共享群组", "共享应用", "共享工具", "共享主机", "访问空间"], scroll: function(can) { can.onmotion.delayOnce(can, function() {
], if (can._output.offsetHeight == can._output.scrollHeight) {
can.onmotion.hidden(can, can._prev), can.onmotion.hidden(can, can._next)
"创建群组": function(event, can) { can.onaction.create(event, can) }, } else {
"共享群组": function(event, can, button, river) { can.onmotion.toggle(can, can._prev, can._output.scrollTop > 10)
can.user.input(event, can, [{name: chat.TILTE, value: river, _trans: "标题"}], function(event, button, meta, list) { can.onmotion.toggle(can, can._next, can._output.scrollTop+can._output.offsetHeight < can._output.scrollHeight-10)
can.user.share(can, can.request(event), [river, ctx.ACTION, chat.SHARE, mdb.TYPE, chat.RIVER, mdb.NAME, list[0]]) }
}) }) },
},
"添加应用": function(event, can, button, river) { can.ondetail.create(event, can, button, river) },
"共享应用": function(event, can, button, river, storm) {
can.user.input(event, can, [{name: chat.TILTE, value: storm, _trans: "标题"}], function(event, button, meta, list) {
can.user.share(can, can.request(event), [river, ctx.ACTION, chat.SHARE, mdb.TYPE, chat.STORM, mdb.NAME, list[0],
chat.STORM, storm, chat.RIVER, river,
])
})
},
"添加工具": function(event, can, button, river, storm) {
can.user.select(event, can, ctx.COMMAND, "context,command", function(item, next) {
can.run({}, [river, chat.STORM, ctx.ACTION, mdb.INSERT, mdb.HASH, storm].concat([ice.POD, "", ice.CTX, item[0], ice.CMD, item[1]]), function(msg) {
next()
})
}, function() {
can.misc.Search(can, {river: river, storm: storm})
})
},
"共享工具": function(event, can, button, river, storm) {
can.user.select(event, can, mdb.PLUGIN, "name,context,command,argument", function(item, next) {
can.user.share(can, can.request(event), [river, ctx.ACTION, chat.SHARE, mdb.TYPE, chat.FIELD,
mdb.NAME, item[2], mdb.TEXT, item[3], chat.TITLE, item[0], chat.RIVER, river, chat.STORM, storm,
])
})
},
"添加设备": function(event, can, button, river) {
can.user.select(event, can, web.SPACE, "type,name,text", function(item, next) {
can.run({}, [river, chat.NODE, ctx.ACTION, mdb.INSERT, mdb.TYPE, item[0], mdb.NAME, item[1]], function(msg) {
next()
})
})
},
"共享主机": function(event, can, button, river, storm) {
can.run(event, [ctx.ACTION, aaa.INVITE], function(msg) {
can.user.toast(can, {
title: "共享主机", duration: -1, width: -300,
content: msg.Result(), action: [cli.CLOSE],
})
})
},
"创建空间": function(event, can, button, river, storm) { can.request(event, {action: button})
can.user.input(event, can, [{name: "name", value: "hi"}, {name: "repos"}, {name: "template"}], function(event, button, data, list, args) {
can.run(event, [ctx.ACTION, cli.START].concat(args, chat.RIVER, river), function(msg) {
var link = can.misc.MergeURL(can, {_path: "/chat/pod/"+can.core.Keys(can.misc.Search(can, ice.POD), msg.Option(mdb.NAME))})
can.user.toast(can, link), can.user.open(link)
})
})
},
"访问空间": function(event, can, button, river, storm) {
can.user.select({river: river}, can, web.SPACE, "time,type,name,text")
},
"添加用户": function(event, can, button, river) {
can.user.select(event, can, chat.USER, "usernick,username", function(item, next) {
can.run({}, [river, chat.USER, ctx.ACTION, mdb.INSERT, aaa.USERNAME, item[0]], function(msg) {
next()
})
})
},
"重命名群组": function(event, can, button, river) {
can.user.input(event, can, [mdb.NAME], function(event, button, meta, list) {
can.run(can.request(event, {hash: river})._event, [ctx.ACTION, mdb.MODIFY, mdb.NAME, meta.name], function(msg) {
can.misc.Search(can, {river: river})
})
})
},
"删除群组": function(event, can, button, river) {
can.run(can.request(event, {hash: river})._event, [ctx.ACTION, mdb.REMOVE], function(msg) { can.misc.Search(can, {}) })
},
"保存参数": function(event, can, button, river, storm) {
can.search(event, ["Action.onexport.args"], function(item, next, index, array) {
var msg = can.request({}, {hash: storm, id: item.dataset.id})
var toast = can.user.toast(can, (index+1)+ice.PS+array.length, "保存参数", 10000, (index+1)/array.length)
can.run(msg._event, [river, chat.STORM, ctx.ACTION, mdb.MODIFY, ice.ARG, item.dataset.args], function(msg) {
toast.close(), next()
})
})
},
"重命名应用": function(event, can, button, river, storm) {
can.user.input(event, can, [mdb.NAME], function(ev, button, meta, list, args) {
can.run(can.request(event, {hash: storm})._event, [river, chat.STORM, ctx.ACTION, mdb.MODIFY].concat(args), function(msg) {
can.misc.Search(can, {river: river, storm: storm})
})
})
},
"删除应用": function(event, can, button, river, storm) {
can.run(can.request(event, {hash: storm})._event, [river, chat.STORM, ctx.ACTION, mdb.REMOVE], function(msg) {
can.misc.Search(can, {river: river})
})
},
create: function(event, can, button, river) {
can.user.trans(can, {"public": "公开应用", "protected": "群组应用", "private": "个人应用"})
can.user.input(event, can, [
{name: mdb.TYPE, values: [chat.PUBLIC, chat.PROTECTED, chat.PRIVATE], _trans: "类型"},
{name: mdb.NAME, value: "hi", _trans: "名称"}, {name: mdb.TEXT, value: "hello", _trans: "简介"},
], function(event, button, meta, list, args) {
can.run({}, [river, chat.STORM, ctx.ACTION, mdb.CREATE].concat(args), function(msg) {
can.misc.Search(can, {river: river, storm: msg.Result()})
})
})
},
}) })
Volcanos("onexport", {help: "导出数据", list: [], Volcanos(chat.ONENGINE, {
width: function(can) { return can._target.offsetWidth }, _engine: function(event, can, msg, panel, cmds, cb) {
storm: function(can, msg, word) { function right(role) { if (!role || role == aaa.VOID) { return true }
var fields = (msg.Option(ice.MSG_FIELDS)||"ctx,cmd,type,name,text").split(",") return can.core.List(can.core.Split(can.user.info.userrole||aaa.VOID), function(userrole) {
can.core.Item(can._root.river, function(river, value) { if (can.base.isIn(userrole, role, aaa.TECH, aaa.ROOT)) { return true }
can.core.Item(value.storm, function(storm, item) { }).length > 0
if (word[1] != "" && word[1] != storm && word[1] != item.name) { return } }
if (typeof can.river == code.FUNCTION) { can.river = can.river(can) } var list = can.river
var data = {ctx: "web.chat", cmd: chat.STORM, cmds.length == 0 && can.core.ItemOrder(list, mdb.ORDER, function(key, value) { if (!value) { return }
type: river, name: storm, text: shy("跳转", function(event) { if (value.debug && can.misc.Search(can, ice.MSG_DEBUG) != ice.TRUE) { return }
can.onaction.action(event, can, river, storm) if (value.nodetype && value.nodetype != can.user.info.nodetype) { return }
}), if (right(value.type)) {
}; can.core.List(fields, function(key) { msg.Push(key, data[key]||"") }) can.core.Item(value.storm).length > 0 && msg.Push({hash: key, name: can.user.isEnglish(can)? key: value.name, icon: value.icon||"", main: value.main||false})
}) }
}) })
}, if (cmds.length != 1 && cmds[1] != chat.STORM) { return false } var river = list[cmds[0]]; if (!river) { return false }
can.core.ItemOrder(river.storm, mdb.ORDER, function(key, value) { if (!value) { return }
if (value.nodetype && value.nodetype != can.user.info.nodetype) { return }
if (right(value.type)) {
msg.Push({hash: key, name: can.user.isEnglish(can)? key: value.name||(can.user.trans(can, key)+" "+key), icon: value.icon||icon[key]||"", main: value.main||false})
}
}), can.base.isFunc(cb) && cb(msg); return true
},
}) })
})()

View File

@ -1,30 +1,3 @@
fieldset.Search { fieldset.Search { padding:var(--plugin-padding); position:fixed; left:var(--project-width); top:var(--header-height); }
background:#041a25bd; padding:10px; fieldset.Search>div.output>div.profile { max-width:unset; }
position:fixed; fieldset.Search>div.output table.content { width:100%; }
display:none;
}
body.white fieldset.Search table {
color:white;
}
fieldset.Search input.word {
width:-webkit-fill-available;
}
fieldset.Search div.output {
overflow:auto;
}
fieldset.Search div.output div.content {
overflow:auto;
}
fieldset.Search div.output div.content a {
color:yellow;
}
fieldset.Search div.output div.content table {
min-width:400px;
}
fieldset.Search div.output div.display {
max-height:200px;
overflow:auto;
}
fieldset.Search div.output div.profile {
overflow:auto;
}

View File

@ -1,110 +1,76 @@
Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) { Volcanos(chat.ONIMPORT, {
can.list = msg.Table(), can.onmotion.clear(can, can.ui.content) _init: function(can, msg) { can.onmotion.clear(can, can.ui.content)
var table = can.onappend.table(can, msg, function(value, key, index, line, array) { can.Status(mdb.TOTAL, index+1) var table = can.onappend.table(can, msg, function(value, key, index, data) { return {text: [can.base.isFunc(value) && value.help || value, html.TD], onclick: function(event) {
return {text: [key == mdb.TEXT && can.base.isFunc(line.text) && line.text.help || value, html.TD], onclick: function(event) { can.page.tagis(event.target, html.A) || can.onaction[can.db.type == mdb.FOREACH || event.ctrlKey? mdb.PLUGIN: mdb.SELECT](event, can, data)
can.onaction[can.type == "*"||event.ctrlKey? chat.PLUGIN: mdb.SELECT](event, can, index) }} }, can.ui.content, msg.append); can.onmotion.story.auto(can), can.onimport._size(can)
}} can.onmotion.toggle(can, can._status, can.db.type != mdb.FOREACH) && can.onappend._status(can, can.base.Obj(msg.Option(ice.MSG_STATUS), []).concat({name: mdb.SELECT, value: "0"}))
}, can.ui.content, can.core.List((msg.Option("sort")||"ctx,cmd,type,name,text").split(ice.FS), function(item) { can.onmotion.focus(can, can.ui.filter), msg.Length() == 1 && can.ui.profile.innerHTML == "" && can.page.Select(can, table, html.TD)[0].click()
return list.indexOf(item) },
})); table && can.page.Modify(can, can.ui.display, {style: {width: table.offsetWidth}}) _size: function(can) { can.ui && can.ui.content && can.getActionSize(function(left, top, width, height) {
can.page.style(can, can._target, {left: left||0, top: top||0, width: width})
can.onappend._status(can, can.base.Obj(msg.Option("_status"), []).concat({name: "selected", value: "0"})) can.page.style(can, can._output, html.MAX_HEIGHT, height -= 2*10+(can.user.isMobile? 2: 1)*html.ACTION_HEIGHT+can.onexport.statusHeight(can))
can.getActionSize(function(msg, height) { can.core.List([can.ui.content, can.ui.display], function(target) { can.page.style(can, target, html.MAX_WIDTH, can.ConfWidth(width-2*10)) })
can.page.Modify(can, can.ui.profile, kit.Dict(html.MAX_HEIGHT, height-table.offsetHeight)) can.ConfHeight(can.base.Min(height-can.ui.content.offsetHeight-can.ui.display.offsetHeight, height/2))
}) }) },
msg.Length() == 1 && can.page.Select(can, table, html.TD)[0].click() _input: function(can, msg, arg, fields) { if (can.base.contains(arg[1], ";")) { arg = can.core.Split(arg[1], "\t ;", "\t ;") }
}, can.run(can.request({}, {fields: fields.join(mdb.FS)}, msg), arg, function(res) { can.db.type = arg[0]
_word: function(can, msg, cmds, fields) { can.type = cmds[0] res.Option(ice.ARG, arg), can.onengine.signal(can, chat.ONSEARCH, res), can.onimport._init(can, res)
var cb = can.onaction[cmds[1]]; if (cb) { cb({}, can); return } }), can.onmotion.toggle(can, can._target, true)
},
var res = can.request({}, { select: function(can, msg, cmds, cb) { can.ui.filter.value = cmds[1], can.ui.input = function(event, word) { cmds[1] = word||cmds[1]; can.onimport._input(can, msg, cmds, fields) }
word: cmds, fields: fields.join(ice.FS), sort: msg.Option("sort"), var fields = (cmds[2]||msg.Option(ice.MSG_FIELDS)||"ctx,cmd,type,name,text").split(mdb.FS); can.page.Appends(can, can.ui.display, [{th: fields}]), can.onmotion.hidden(can, can.ui.display), can.onmotion.clear(can, can.ui.profile)
river: msg.Option(chat.RIVER), index: msg.Option("index"), can.ui.done = function() { can.base.isFunc(cb) && cb(can.onexport.select(can)), can.onmotion.hidden(can) }, can.db = {}, can._plugins = [], can.onimport._input(can, msg, cmds, fields)
}) },
can.onengine.signal(can, chat.ONSEARCH, res)
can.run(res._event, cmds, function(res) { can.onimport._init(can, res, fields) })
can.onmotion.show(can), can.onmotion.focus(can, can.ui.word)
},
select: function(can, msg, cmds, cb) { can.ui.word.value = cmds[1]
var fields = (cmds[2]||msg.Option(ice.MSG_FIELDS)||"ctx,cmd,type,name,text").split(ice.FS)
can.page.Appends(can, can.ui.display, [{th: fields}]), can.cb = function() {
can.base.isFunc(cb) && cb(can.onexport.select(can)), can.onmotion.hide(can)
}
can.input = function(event, word) { cmds[1] = word||cmds[1]
can.onimport._word(can, msg, cmds, fields)
}, can.onimport._word(can, msg, cmds, fields)
can.getActionSize(function(msg, top, left, width, height) {
can.page.Modify(can, can._target, {style: {top: top, left: left}})
can.page.Modify(can, can._output, {style: kit.Dict(html.MAX_HEIGHT, height-71, html.MAX_WIDTH, width)})
})
},
}) })
Volcanos("onaction", {help: "交互操作", list: [cli.CLEAR, cli.CLOSE, cli.DONE], _init: function(can, meta, list, cb, target) { Volcanos(chat.ONACTION, {_init: function(can) { can.onmotion.hidden(can) }, list: [cli.CLOSE, web.CLEAR, cli.DONE],
can.base.isFunc(cb) && cb() onsize: function(can, msg, height, width) { can.onimport._size(can), can.core.List(can._plugins, function(sub) { sub.onimport.size(sub, can.ConfHeight(), can.ConfWidth(), true) }) },
}, onlogin: function(can, msg) { can.ui = can.page.Append(can, can._output, [chat.CONTENT, {view: [[chat.DISPLAY, chat.CONTENT], html.TABLE]}, chat.PROFILE])
onlogin: function(can, msg) { can.onappend._action(can, (can.Conf(html.ACTION)||can.onaction.list).concat({type: html.TEXT, _className: "args trans", name: html.FILTER, icon: icon.search, _init: function(target) { can.ui.filter = target }, onkeydown: function(event) {
can.onappend._action(can, can.Conf(html.ACTION)||can.onaction.list) if (event.key == code.ESCAPE) { return event.target.blur() }
can.ui = can.page.Append(can, can._output, [ if (event.key == code.ENTER) { can.onkeymap.prevent(event); if (event.shiftKey) { return can.page.SelectOne(can, can.ui.content, [html.TBODY, html.TR, html.TD], function(target) { target.click() }) }
{input: ["word", function(event) { can.onkeypop.input(event, can) return event.ctrlKey? can.onaction.done(event, can): can.ui.input(event, event.target.value)
if (event.key == lang.ESCAPE) { can.onmotion.hide(can) } } if (event.ctrlKey) { return event.key == "0"? can.onaction.clear(event, can): can.onkeymap.selectCtrlN(event, can, can.ui.content, [html.TBODY, html.TR], function(target) { target.firstChild.click() }) }
event.key.length == 1 && can.onmotion.delayOnce(can, function() {
if (event.key == lang.ENTER) { event.stopPropagation(), event.preventDefault() can.onmotion.tableFilter(can, can.ui.content, event.target.value)
if (event.shiftKey) { var first = can.page.Select(can, can.ui.content, html.TR)[1] }, 100, can._delay_filter = can._delay_filter||[])
return can.onaction[can.type == "*"? chat.PLUGIN: html.SELECT](event, can, first.dataset.index) }}), null, null, null, 10)
} var key = can.misc.Search(can, "_search"); key && can.onmotion.delay(can, function() { can.onaction.onopensearch(can, can.request({}), "*", key) }, 1000)
if (event.ctrlKey) { return can.onaction[cli.DONE](event, can) } },
can.input(event, event.target.value) onopensearch: function(can, msg, type, word) { can.onimport.select(can, msg, [type||mdb.FOREACH, word||""]) },
} close: function(event, can) { can.onmotion.hidden(can) },
}]}, clear: function(event, can) { can.onmotion.clear(can, can.ui.profile) },
{view: chat.CONTENT}, {view: html.STATUS}, {view: [chat.DISPLAY, html.TABLE]},{view: chat.PROFILE}, done: function(event, can) { can.base.isFunc(can.ui.done) && can.ui.done() },
]), can.page.ClassList.add(can, can.ui.display, chat.CONTENT) select: function(event, can, data) { if (can.base.isFunc(data.text)) { return can.onmotion.hidden(can), data.text(event) }
}, function show() { can.page.style(can, can.ui.content, html.MAX_HEIGHT, "")
onopensearch: function(can, msg, type, word) { can.onimport.select(can, msg, [type||"*", word||""]) }, can.page.style(can, can.ui.content, html.MAX_HEIGHT, can._output.offsetHeight-can.ui.display.offsetHeight)
can.Status(mdb.SELECT, can.page.Select(can, can.ui.display, html.TR).length-1)
clear: function(event, can) { can.onmotion.clear(can, can.ui.profile) }, }
done: function(event, can) { can.base.isFunc(can.cb) && can.cb() }, var fields = can.page.Select(can, can.ui.display, html.TH, function(item) { return item.innerText }); can.onmotion.toggle(can, can.ui.display, true)
close: function(event, can) { can.onmotion.hide(can) }, var ui = can.page.Append(can, can.ui.display, [{td: can.core.List(fields, function(item) { return data[item] }), onclick: function(event) {
can.page.Remove(can, ui._target), show()
select: function(event, can, index) { var line = can.list[index] }}]); show()
if (can.base.isFunc(line.text)) { return can.onmotion.hide(can), line.text(event) } },
plugin: function(event, can, data) { if (can.base.isFunc(data.text)) { return can.onmotion.hidden(can), data.text(event) }
if (line.ctx == "web.chat" && line.cmd == "/search") { var cmd = data.cmd == ctx.COMMAND? can.core.Keys(data.type, data.name.split(lex.SP)[0]): can.core.Keys(data.ctx, data.cmd)
return can.onimport.select(can, msg, [line.type, line.name, line.text], can.cb) var meta = {type: chat.STORY, index: cmd||msg.Option(mdb.INDEX), args: cmd == web.WIKI_WORD? [data.name]: []}
} if (data.type == cli.OPENS) { return can.runAction(event, cli.OPENS, [data.text], null, true) }
if (data.type == ssh.SHELL) { meta = {index: web.CODE_XTERM, args: [data.text]} }
var fields = can.page.Select(can, can.ui.display, html.TH, function(item) { return item.innerText }) if (data.type == ctx.INDEX) { meta = {index: data.text.split(mdb.FS)[0], args: data.text.split(mdb.FS).slice(1) } }
can.page.Append(can, can.ui.display, [{td: can.core.List(fields, function(item) { if (data.type == nfs.FILE) { meta = {index: web.CODE_VIMER, args: can.misc.SplitPath(can, data.text)} }
return line[item] if (data.type == nfs.SHY) { meta = {index: web.WIKI_WORD, args: data.text} }
}), data: {index: index}, onclick: function(event) { can.page.Remove(can, event.target.parentNode) if (data.type == ice.CMD) { meta = {index: data.name, args: can.core.Split(data.text)} }
can.Status("selected", can.page.Select(can, can.ui.display, html.TR).length-1) function plugin(meta) { can.onappend.plugin(can, meta, function(sub) { can._plugins = (can._plugins||[]).concat(sub)
}}]), can.Status("selected", can.page.Select(can, can.ui.display, html.TR).length-1) can.onmotion.delay(can, function() { can.onmotion.scrollIntoView(can, can.ui.profile) }, 500)
}, sub.onimport.size(sub, can.ConfHeight(), can.ConfWidth()-1, true)
}, can.ui.profile) }
plugin: function(event, can, index) { var line = can.list[index] if (data.ctx == ice.NFS && data.cmd == nfs.PACK) { var ls = can.misc.SplitPath(can, data.text)
if (can.base.isFunc(line.text)) { return can.onmotion.hide(can), line.text(event) } can.runAction(event, ctx.RUN, [web.CODE_VIMER, ctx.ACTION, mdb.RENDER, data.type, ls[1], ls[0]], function(msg) {
msg.Table(function(meta) { plugin(meta) }), can.onappend.board(can, msg.Result(), can.ui.profile) })
var cmd = line.cmd == ctx.COMMAND? can.core.Keys(line.type, line.name.split(ice.SP)[0]): can.core.Keys(line.ctx, line.cmd) } else {
can.onappend.plugin(can, {type: chat.PLUGIN, index: cmd||msg.Option(mdb.INDEX)}, function(sub, meta) { plugin(meta)
can.getActionSize(function(msg, height, width) { height -= can.ui.content.offsetHeight+204 }
can.page.Modify(can, sub._output, {style: kit.Dict(html.MAX_HEIGHT, height-26, html.MAX_WIDTH, width-40)}) },
sub.Conf(html.HEIGHT, height+28), sub.Conf(html.WIDTH, width-60)
})
sub.run = function(event, cmds, cb) { var msg = can.request(event, line)
can.run(event, can.misc.concat([ctx.ACTION, ice.RUN, meta.index], cmds), cb, true)
}
}, can.ui.profile)
},
}) })
Volcanos("onexport", {help: "导出数据", list: [], Volcanos(chat.ONEXPORT, {statusHeight: function(can) { return can.db && can.db.type == mdb.FOREACH? 0: html.ACTION_HEIGHT },
select: function(can) { select: function(can) { return can.page.Select(can, can.ui.display, html.TR, function(tr) { return can.page.Select(can, tr, html.TD, function(td) { return td.innerHTML }) }).slice(1) },
return can.page.Select(can, can.ui.display, html.TR, function(tr) {
return can.page.Select(can, tr, html.TD, function(td) { return td.innerHTML })
}).slice(1)
},
}) })

View File

@ -1,37 +1,17 @@
Volcanos("onaction", {help: "控件交互", list: [], _init: function(can, meta, list, cb, target) { Volcanos(chat.ONACTION, {
can.base.isFunc(cb) && cb(); switch (meta.type) { run: function(event, can) { can.run(can.request(event, {_method: http.POST})) }, refresh: function(event, can) { can.run(can.request(event, {_method: http.GET})) },
case html.SELECT: meta.value && (target.value = meta.value); break list: function(event, can) { can.sup.isSimpleMode() || can.run(can.request(event, {_toast: event.isTrusted? ice.PROCESS: "" , _method: http.GET})) }, back: function(event, can) { can.sup.onimport.back(event, can.sup) },
case html.BUTTON: meta.action == ice.AUTO && target.click(); break onclick: function(event, can) { can.Conf(mdb.TYPE) == html.BUTTON && can.run(event, [ctx.ACTION, can.Conf(mdb.NAME)].concat(can.sup.Input())), can.onkeymap.prevent(event) },
} onchange: function(event, can) { if (can.Conf(mdb.TYPE) != html.SELECT) { return }
}, can.sup.onexport.session && can.sup.onexport.session(can.sup, "action:"+can.Conf(mdb.NAME), event.target.value)
can.run(can.request(event, {_toast: event.isTrusted? can.user.trans(can, ice.PROCESS, "处理"): "" , _method: http.GET}))
run: function(event, can) { },
var title = can.sup._name+ice.SP+can.sup.Input([], true) onkeydown: function(event, can) { can.onkeymap.input(event, can, event.target); if (can.Conf(mdb.TYPE) == html.TEXTAREA && !event.ctrlKey) { return }
var toast = can.user.toast(can, "执行中...", title, -1) if (event.key == code.ENTER) { return can.onkeymap.prevent(event), can.run(event), can.onmotion.focus(can, event.target) }
can.run(event, [], function() { toast.close(), can.user.toastSuccess(can) }) if (!event.ctrlKey) { return } switch (event.key) {
}, case "m": can.CloneField(); break
list: function(event, can) { can.run(event) }, case "b": can.CloneInput(); break
back: function(event, can) { can.sup.onimport._back(can.sup) }, default: can.onkeymap.selectOutput(event, can.sup); return
refresh: function(event, can) { can.run(event) }, } can.onkeymap.prevent(event)
},
onclick: function(event, can) {
if (can.Conf(mdb.TYPE) == html.BUTTON) { can.run(event, [ctx.ACTION, can.Conf(mdb.NAME)].concat(can.sup.Input())) }
},
onchange: function(event, can) {
if (can.Conf(mdb.TYPE) == html.SELECT) { can.run(event) }
},
onkeydown: function(event, can) { can.onkeypop.input(event, can, event.target)
if (can.Conf(mdb.TYPE) == html.TEXTAREA) { if (!event.ctrlKey) { return } }
if (event.key == lang.ENTER) {
can.run(event), event.target.setSelectionRange(0, -1)
event.stopPropagation(), event.preventDefault()
} if (!event.ctrlKey) { return }
switch (event.key) {
case "b": can.CloneInput(); break
case "m": can.CloneField(); break
default: return
} event.stopPropagation(), event.preventDefault()
},
}) })

54
plugin/input/color.js Normal file
View File

@ -0,0 +1,54 @@
Volcanos(chat.ONFIGURE, {color: {
_load: function(event, can, cb, target, name, value) {
if (target._done && target.value) { return can.onmotion.hidden(can, can._target, can.Status("total") > 0)} target._done = true
can.onmotion.focus(can, target), can.onmotion.hidden(can, can._target)
can.runAction(event, mdb.INPUTS, [name, value||""], function(msg) {
name == ctx.INDEX && can.core.Item(can.onengine.plugin.meta, function(key) { msg.Push(ctx.INDEX, can.core.Keys(ice.CAN, key)) })
can._show(can, msg, cb, target, name)
})
},
_show: function(can, msg, cb, target, name) {
if (msg.Length() == 0 || msg.Length() == 1 && msg.Append(name) == target.value && target.value != "") { return can.onmotion.hidden(can) }
if (can.base.isIn(msg.append[msg.append.length-1], ctx.ACTION, "cb")) { msg.append = msg.append.slice(0, -1) } var list = {}
msg.Option(ice.TABLE_CHECKBOX, "")
can.onmotion.clear(can), can.onappend.table(can, msg, function(value, key, index, item) { value = item[key]
if (msg.append.length == 1 && index < 100 && list[value]) { return } list[value] = true
return {text: [value, html.TD, value == ""? html.HR: ""], style: msg.append && msg.append.length == 1? kit.Dict(html.MIN_WIDTH, target.offsetWidth-16): {}, onclick: function(event) {
can.page.style(can, target, html.BACKGROUND_COLOR, value)
can.close(); if (msg.cb && msg.cb[index]) { return msg.cb[index](value) }
var _cb = can.Conf("select"); if (_cb) { return _cb(target.value = value) } can.base.isFunc(cb) && cb(can, value, target.value)
}, _init: function(target) {
if (key == mdb.NAME) {
can.page.style(can, target.parentNode, html.BACKGROUND_COLOR, value)
}
}}
})
can.showIcons = function(value, icons, title) { can.ui = can.ui||{}
if (!can.ui.img) {
can.ui.img = can.page.insertBefore(can, [{type: html.IMG}], target)
can.ui.span = can.page.insertBefore(can, [{type: html.SPAN}], target)
can.onappend.style(can, mdb.ICONS, can.page.parentNode(can, target, html.TR))
can.page.style(can, target, html.COLOR, html.TRANSPARENT)
target._clear = function() { can.ui.img.src = can.misc.Resource(can, "usr/icons/icebergs.png"), can.ui.span.innerHTML = "" }
}
can.ui.img.src = can.misc.Resource(can, icons), can.ui.span.innerText = title||value
target.value = value, can.onmotion.hidden(can, can._target)
}
can.core.CallFunc([can.oninputs, "_show"], {event: event, can: can, msg: msg, target: target, name: name})
var style = msg.Option(ice.MSG_DISPLAY)? can.base.ParseURL(msg.Option(ice.MSG_DISPLAY)).style||name: name
can.core.CallFunc([can.sup.sub, "oninputs", style], {event: event, can: can, msg: msg, target: target, name: name})
can.layout(msg)
},
onfocus: function(event, can, meta, target, cbs, mod) { meta._force && mod.onclick(event, can, meta, target, cbs) },
onclick: function(event, can, meta, target, cbs) { (target.value == "" || meta._force) && cbs(function(sub, cb) { if (sub.Status(mdb.TOTAL) > 0) { return }
sub.sup = can._fields? can.sup: can
meta.msg && meta.msg.Length() > 0? sub._show(sub, meta.msg, cb, target, meta.name): sub._load(event, sub, cb, target, meta.name, target.value)
}) },
onblur: function(event, can, sub, cb) { sub && can.onmotion.delay(can, sub.close, 300) },
onkeyup: function(event, can, meta, cb, target, sub, last) { if (event.key == code.TAB) { return }
if (event.key == code.ENTER) { return meta._enter && (!can.page.tagis(event.target, html.TEXTAREA) || event.ctrlKey) && meta._enter(event, target.value)? sub && sub.close(): last(event) }
if (!sub) { return } can.onmotion.toggle(can, sub._target, true)
sub.hidden() || can.onkeymap.selectCtrlN(event, can, sub._output, "tr:not(.hidden)>td:first-child", function(td) { return meta.select && (sub.close(), meta.select(target.value = td.innerText)), cb(sub, td.innerText, target.value), td })
|| can.onmotion.delayOnce(can, function() { can.onkeymap.selectInputs(event, sub, function() { sub._load(event, sub, cb, target, meta.name) }, target) }, target.value.length < 3? 500: 150)
},
}})

View File

@ -1,13 +0,0 @@
fieldset.input.date div.action div.space {
clear:both; width:0;
}
fieldset.input.date div.output td.prev {
color:gray;
}
fieldset.input.date div.output td.next {
color:gray;
}
fieldset.input.date div.output td {
padding:2px 12px;
}

View File

@ -1,60 +1,47 @@
Volcanos("onfigure", {help: "控件详情", list: [], date: {onclick: function(event, can, meta, cb, target) { cb(function(can, cbs) { Volcanos(chat.ONFIGURE, {date: {
function set(now) { target.value = can.user.time(can, now), can.close(), meta && meta.action == ice.AUTO && can.run({}) } onclick: function(event, can, meta, target, cbs) { cbs(function(can, cb) { if (can._output.innerHTML) { return }
const TODAY = "today", YEAR = "year", MONTH = "month", HOUR = "hour", MINUTE = "minute", SECOND = "second"
// 添加控件 var today = new Date(), now = can.base.Date((target.value||"").trim()); function _cb(_now) { cb(can, can.user.time(can, now = _now), target.value) }
var now = target.value? new Date(target.value): new Date() can.base.Copy(can._trans, kit.Dict(TODAY, "今天", mdb.NEXT, "下一月", mdb.PREV, "上一月"))
can.onmotion.clear(can, can._action), can.onappend._action(can, [cli.CLOSE, var meta = kit.Dict(cli.CLOSE, function() { can.close() },
["hour"].concat(can.core.List(24)), ["minute"].concat(can.core.List(0, 60, 5)), ["second"].concat(can.core.List(0, 60, 5)), HOUR, function(event, can, button, value) { now.setHours(parseInt(value)||0), show(now) },
"今天", "", "上一月", ["year"].concat(can.core.List(now.getFullYear() - 10, now.getFullYear() + 10)), MINUTE, function(event, can, button, value) { now.setMinutes(parseInt(value)||0), show(now) },
["month"].concat(can.core.List(1, 13)), "下一月", SECOND, function(event, can, button, value) { now.setSeconds(parseInt(value)||0), show(now) },
], can._action, { close: function(event) { can.close() }, TODAY, function() { show(today) },
"hour": function(event, can, key, value) { now.setHours(parseInt(value)||0), show(now) }, mdb.PREV, function() { now.setMonth(now.getMonth()-1), show(now) },
"minute": function(event, can, key, value) { now.setMinutes(parseInt(value)||0), show(now) }, YEAR, function(event, can, button, value) { now.setFullYear(parseInt(value)), show(now) },
"second": function(event, can, key, value) { now.setSeconds(parseInt(value)||0), show(now) }, MONTH, function(event, can, button, value) { now.setMonth(parseInt(value)-1), show(now) },
"今天": function(event) { now = new Date(), set(show(now)) }, mdb.NEXT, function() { now.setMonth(now.getMonth()+1), show(now) }
)
"上一月": function(event) { now.setMonth(now.getMonth()-1), show(now) }, var ui = can.page.Append(can, can._action, ["time", "date"])
"year": function(event, can, key, value) { now.setFullYear(parseInt(value)), show(now) }, can.onappend._action(can, [cli.CLOSE, [HOUR].concat(can.core.List(24)), [MINUTE].concat(can.core.List(0, 60, 5)), [SECOND].concat(can.core.List(0, 60, 5)), TODAY], ui.time, meta)
"month": function(event, can, key, value) { now.setMonth(parseInt(value)-1), show(now) }, can.onappend._action(can, [mdb.PREV, [YEAR].concat(can.core.List(now.getFullYear() - 10, now.getFullYear() + 10)), [MONTH].concat(can.core.List(1, 13)), mdb.NEXT], ui.date, meta)
"下一月": function(event) { now.setMonth(now.getMonth()+1), show(now) }, can._table = can.page.Appends(can, can._output, [{view: [chat.CONTENT, html.TABLE], list: [{type: html.TBODY}]}]).tbody
can.page.Append(can, can._output, [{text: "请先选择时间,再选择日期"}])
"随机": function(event) { now.setDate((Math.random() * 100 - 50) + now.getDate()), show(now) }, target.value == "" && (now.setMinutes(now.getMinutes()>30? 30: 0), now.setSeconds(0))
"前一年": function(event) { now.setFullYear(now.getFullYear()-1), show(now) }, function show(now) { can.Action(YEAR, now.getFullYear()), can.Action(MONTH, now.getMonth()+1)
"后一年": function(event) { now.setFullYear(now.getFullYear()+1), show(now) }, can.Action(HOUR, now.getHours()), can.Action(MINUTE, parseInt(now.getMinutes()/30)*30), can.Action(SECOND, 0)
}) can.page.Appends(can, can._table, can.date.List(can, function(event, day) {
day.setHours(can.Action(HOUR)), day.setMinutes(can.Action(MINUTE)), day.getSeconds(can.Action(SECOND)), _cb(day), can.close()
can.onmotion.clear(can, can._status) }, now))
can._table = can.page.Appends(can, can._output, [{view: [chat.CONTENT, html.TABLE]}]).first var l = can.date.solar2lunar(now); can.page.Appends(can, can._status, [{view: "today", inner: [l.gzYear, l.Animal+"年", l.cnMonth, l.cnDay, l.lunarFestival||l.festival||l.Term, l.Astro].join(lex.SP)}])
var today = new Date(); function show(now) { return now
// 设置控件 } show(now), can._show = function(d) { d? _cb(show(now = new Date(now.getTime()+d*24*3600*1000))): _cb(show(now)) }
can.Action("year", now.getFullYear()) })},
can.Action("month", now.getMonth()+1) onfocus: function(event, can, meta, target, cbs, mod) {
can.Action("hour", now.getHours()) if (target._selectonly) { can.onmotion.delay(can, function() { target.blur() }) }
can.Action("minute", parseInt(now.getMinutes()/5)*5) },
can.Action("second", parseInt(now.getSeconds()/5)*5) onblur: function(event, can, sub, cb, target) {
if (target._selectonly) { return }
// 设置组件 },
can.page.Appends(can, can._table, [{th: ["日", "一", "二", "三", "四", "五", "六"]}]) onkeydown: function(event, can, meta, cb, target, sub, last) { if (sub && sub.hidden()) { return last(event) } switch (event.key) {
var tr; function add(day, type) { if (day.getDay() == 0) { tr = can.page.Append(can, can._table, [{type: html.TR}]).last } case "n": can.page.SelectInput(can, sub._action, mdb.NEXT, function(target) { target.click(), sub._show() }); break
can.page.Append(can, tr, [{text: [day.getDate(), html.TD, can.base.Time(today, "%y-%m-%d") == can.base.Time(day, "%y-%m-%d")? html.SELECT: type], case "p": can.page.SelectInput(can, sub._action, mdb.PREV, function(target) { target.click(), sub._show() }); break
dataset: {date: day.getTime()}, onclick: function(event) { case "t": can.page.SelectInput(can, sub._action, "today", function(target) { target.click(), sub._show() }); break
set(now = new Date(parseInt(event.target.dataset.date))) case "j": sub._show(7); break
}, case "k": sub._show(-7); break
}]) case "h": sub._show(-1); break
} case "l": sub._show(1); break
default: last(event); return
// 时间区间 } can.onkeymap.prevent(event) },
var one = new Date(now); one.setDate(1) } })
var end = new Date(now); end.setMonth(now.getMonth()+1), end.setDate(1)
var head = new Date(one); head.setDate(one.getDate()-one.getDay())
var tail = new Date(end); tail.setDate(end.getDate()+7-end.getDay())
// 时间序列
for (var day = new Date(head); day < one; day.setDate(day.getDate()+1)) { add(day, mdb.PREV) }
for (var day = new Date(one); day < end; day.setDate(day.getDate()+1)) { add(day, mdb.MAIN) }
for (var day = new Date(end); end.getDay() != 0 && day < tail; day.setDate(day.getDate()+1)) { add(day, mdb.NEXT) }
return now
} show(now), can.onlayout.figure(event, can), can.base.isFunc(cbs) && cbs(can)
})}} }, [""])

31
plugin/input/icon.js Normal file
View File

@ -0,0 +1,31 @@
Volcanos(chat.ONFIGURE, {icon: {
_load: function(event, can, cb, target, name, value) {
can.runAction(event, ctx.RUN, ["web.chat.icon"], function(msg) { can._show(can, msg, cb, target, name) })
},
_show: function(can, msg, cb, target, name) { can.onmotion.clear(can)
var table = can.page.Append(can, can._output, [{type: html.TABLE}])._target, tr
msg.Table(function(value, index) { if (index%10 == 0) { tr = can.page.Append(can, table, [{type: html.TR}])._target }
can.page.Append(can, tr, [{type: html.TD, inner: value.icon, title: value.name, onclick: function() {
can.close(), can.base.isFunc(cb) && cb(can, value.name, target.value)
target._icon.className = value.name
}}])
}), can.layout(msg)
},
onfocus: function(event, can, meta, target, cbs, mod) { meta._force && mod.onclick(event, can, meta, target, cbs) },
onclick: function(event, can, meta, target, cbs) { cbs(function(sub, cb) { if (sub.Status(mdb.TOTAL) > 0) { return }
target._icon = target._icon || can.page.insertBefore(can, [{type: "i"}], target)
meta.msg && meta.msg.Length() > 0? sub._show(sub, meta.msg, cb, target, meta.name): sub._load(event, sub, cb, target, meta.name, target.value)
}) },
onblur: function(event, can, sub, cb) { sub && can.onmotion.delay(can, sub.close, 300) },
onkeyup: function(event, can, sub, cb) { if (!sub) { return }
can.page.Select(can, sub._output, html.TD, function(target) {
can.onmotion.hidden(can, target, target.title.indexOf(event.target.value) > -1)
})
can.page.Select(can, sub._output, html.TR, function(target) {
can.onmotion.hidden(can, target, can.page.Select(can, target, html.TD, function(target) {
if (!can.page.ClassList.has(can, target, html.HIDE)) { return target }
}).length > 0)
})
},
}})

18
plugin/input/icons.js Normal file
View File

@ -0,0 +1,18 @@
Volcanos(chat.ONFIGURE, {icons: {
_load: function(event, can, cb, target, name, value) {
can.runAction(event, mdb.INPUTS, [mdb.ICONS], function(msg) { can._show(can, msg, cb, target, name) })
},
_show: function(can, msg, cb, target, name) { var table = can.page.Appends(can, can._output, [{type: html.TABLE}])._target, tr
msg.Table(function(value, index) { if (index%5 == 0) { tr = can.page.Append(can, table, [{type: html.TR}])._target }
can.page.Append(can, tr, [{type: html.TD, title: value.icons, list: [{img: can.misc.Resource(can, value.icons), style: {width: 60, height: 60}}], onclick: function() {
can.close(), can.base.isFunc(cb) && cb(can, value.icons, target.value), target._icon.src = can.misc.Resource(can, value.icons)
}}])
}), can.layout(msg)
},
onfocus: function(event, can, meta, target, cbs, mod) { meta._force && mod.onclick(event, can, meta, target, cbs) },
onclick: function(event, can, meta, target, cbs) { cbs(function(sub, cb) { if (sub.Status(mdb.TOTAL) > 0) { return }
target._icon = target._icon || can.page.insertBefore(can, [{img: can.misc.Resource(can, "usr/icons/icebergs.png") }], target)
meta.msg && meta.msg.Length() > 0? sub._show(sub, meta.msg, cb, target, meta.name): sub._load(event, sub, cb, target, meta.name, target.value)
}) },
onblur: function(event, can, sub, cb) { sub && can.onmotion.delay(can, sub.close, 300) },
}})

19
plugin/input/img.js Normal file
View File

@ -0,0 +1,19 @@
Volcanos(chat.ONFIGURE, {img: {
_init: function(can, meta, target) { target.value == meta.value && (target.value = ""); var images = can.core.Split(target.value)
var count = parseInt(meta.value||"1"), width = target.parentNode.offsetWidth; for (var n = 1; n < 10; n++) { if (n*n >= count) { width = (width/n-10); break } }
// function add(target, hash) { target._hash = hash, can.page.Appends(can, target, [{img: can.base.MergeURL(can.misc.MergeURL(can, {_path: web.SHARE_CACHE+hash}, true), {pod: meta.space||undefined}), height: width, width: width}]) }
function add(target, hash) { target._hash = hash, can.page.Appends(can, target, [{img: hash, height: width, width: width}]) }
function set() { target.value = can.page.SelectChild(can, target.parentNode, html.DIV, function(target) { return target._hash }).join(mdb.FS) }
can.onmotion.hidden(can, target), can.onappend.style(can, html.FLEX, target.parentNode)
for (var i = 0; i < count; i++) {
can.page.Append(can, target.parentNode, [{view: html.FLEX, style: {
"clear": i%n == 0? "both": "none", height: width, width: width,
}, _init: function(target) {
if (images[i] && images[i].length > 10) { add(target, images[i]) } else { can.page.Append(can, target, [{text: "+"}]) }
target.onclick = function(event) { can.misc.Event(event, can, function(msg) {
can.user.upload(event, can, function(msg) { add(target, msg.Result()), set() }, true)
})}
} }])
}
},
}})

View File

@ -1,69 +1,79 @@
Volcanos("onfigure", {help: "控件详情", list: [], key: { Volcanos(chat.ONFIGURE, {key: {
_init: function(can, msg, target) { var call = arguments.callee _load: function(event, can, cb, target, name, value) {
can.onmotion.clear(can), can.onappend.table(can, msg, function(value, key, index, line) { if (target._done && target.value) { return can.onmotion.hidden(can, can._target, can.Status("total") > 0)} target._done = true
return {text: [value, html.TD], onclick: function(event) { target.value = line[key] can.onmotion.focus(can, target), can.onmotion.hidden(can, can._target)
if (msg.Option(ice.MSG_PROCESS) != ice.PROCESS_AGAIN) { return can.close() } can.runAction(event, mdb.INPUTS, [name, value||""], function(msg) {
can.run(event, [ctx.ACTION, mdb.INPUTS, can.Conf(mdb.NAME), target.value], function(msg) { name == ctx.INDEX && can.core.Item(can.onengine.plugin.meta, function(key) { msg.Push(ctx.INDEX, can.core.Keys(ice.CAN, key)) })
call(can, msg, target) can._show(can, msg, cb, target, name)
}) })
}} },
}) _show: function(can, msg, cb, target, name) {
}, // msg.Option(ice.TABLE_CHECKBOX, "")
_select: function(event, can, target) { if (msg.Option(ice.TABLE_CHECKBOX) == ice.TRUE) { target._hold = true
function select(order) { if (order == 0) { target.value = target._value } can.onappend._action(can, [html.CANCEL, html.CONFIRM, msg.Length() > 5? html.FILTER: ""], can._action, {
var index = 0; return can.page.Select(can, can._output, html.TR, function(tr) { cancel: function() { can.onmotion.focus(can, target), can.onmotion.hidden(can, can._target) },
if (can.page.ClassList.has(can, tr, html.HIDDEN)) { return } confirm: function() { var list = msg.Table()
can.page.ClassList.del(can, tr, html.SELECT); if (order != index++) { return tr } can.base.isFunc(cb) && cb(can, can.page.Select(can, can._output, html.TR, function(target) {
can.page.ClassList.add(can, tr, html.SELECT), can.page.Select(can, tr, html.TD, function(td, index) { if (can.page.ClassList.has(can, target, html.SELECT)) {
target._value = target._value||target.value, index == 0 && (target.value = td.innerText) return list[target.dataset.index][msg.append[0]]
}); return tr }
}).length }).join(","), target.value)
} can.onmotion.focus(can, target), can.onmotion.hidden(can, can._target)
switch (event.key) { },
case "n": })
var total = select(target._index) }
select(target._index = ((target._index)+1) % total) if (msg.Length() == 0 || msg.Length() == 1 && msg.Append(name) == target.value && target.value != "") { return can.onmotion.hidden(can) }
break if (can.base.isIn(msg.append[msg.append.length-1], ctx.ACTION, "cb")) { msg.append = msg.append.slice(0, -1) } var list = {}
case "p": can.onmotion.clear(can), can.onappend.table(can.sup, msg, function(value, key, index, item) { value = item[key]
var total = select(target._index) if (msg.append.length == 1 && index < 100 && list[value]) { return } list[value] = true
select(target._index = (target._index-1) < 0? total-1: (target._index-1)) return {text: [value, html.TD, [value == ""? html.HR: "", key]], style: msg.append && msg.append.length == 1? kit.Dict(html.MIN_WIDTH, target.offsetWidth-16): {}, onclick: function(event) {
break can.onengine.signal(can, "onevent", can.request(event))
default: target._index = 0, target._value = "" can.close(); if (msg.cb && msg.cb[index]) { return msg.cb[index](value) }
} var _cb = can.Conf("select"); if (_cb) { return _cb(target.value = value) } can.base.isFunc(cb) && cb(can, value, target.value)
}, }, _init: function(target) {
onclick: function(event, can, meta, cb, target) { cb(function(can, cbs) { can.onappend.style(can, "i-"+index, target.parentNode)
can.run(event, [ctx.ACTION, mdb.INPUTS, meta.name, target.value], function(msg) { // can.onappend.style(can, "s-"+can.base.replaceAll(item[name], "/", "_"), target.parentNode)
if (msg.Length() == 0) { return can.close() } }}
can.onfigure.key._init(can, msg, target), can.Status(mdb.TOTAL, msg.Length()) }, can._output)
target._msg = msg, target._figure = can.onlayout.figure(event, can) can.showIcons = function(value, icons, title) { can.ui = can.ui||{}
can.base.isFunc(cbs) && cbs(can) if (!can.ui.img) {
}) can.ui.img = can.page.insertBefore(can, [{type: html.IMG}], target)
}) }, can.ui.span = can.page.insertBefore(can, [{type: html.SPAN}], target)
onkeydown: function(event, can, meta, cb, target, last) { can.onappend.style(can, mdb.ICONS, can.page.parentNode(can, target, html.TR))
var msg = target._msg; msg && cb(function(can, cbs) { can.page.style(can, target, html.COLOR, html.TRANSPARENT)
if (event.ctrlKey) { can.onfigure.key._select(event, can, target) } else { target._clear = function() { can.ui.img.src = can.misc.Resource(can, "usr/icons/icebergs.png"), can.ui.span.innerHTML = "" }
target._index = 0, target._value = "" }
switch (event.key) { case lang.ENTER: can.close(); return } can.ui.img.src = can.misc.Resource(can, icons), can.ui.span.innerText = title||value
can.page.Select(can, can._output, html.TR, function(tr, index) { target.value = value, can.onmotion.hidden(can, can._target)
var has = false; can.page.Select(can, tr, html.TD, function(td) { }
has = has || td.innerText.indexOf(target.value)>-1 can.core.CallFunc([can.oninputs, "_show"], {event: event, can: can, msg: msg, target: target, name: name})
}), can.page.ClassList.set(can, tr, html.HIDDEN, !has && index != 0) var display = msg.Option(ice.MSG_DISPLAY)? can.base.ParseURL(msg.Option(ice.MSG_DISPLAY)): {name: name}
}) if (display.title && !msg[display.title]) { display.title = msg.append[1] }
} display.style && can.core.CallFunc([can.sup.sub, "oninputs", display.style], {event: event, can: can, msg: msg, target: target, name: display.name||name, title: display.title})
can.layout(msg)
can.onlayout.figure(event, can, can._target, false, target._figure) },
var total = can.page.Select(can, can._output, html.TR, function(tr) { onfocus: function(event, can, meta, target, cbs, mod) {
if (!can.page.ClassList.has(can, tr, html.HIDDEN)) { return tr} // can.onengine.signal(can, "onevent", can.request(event));
}).length-1 if (target._selectonly) { can.onmotion.delay(can, function() { target.blur() }) }
can.Status(kit.Dict(mdb.TOTAL, total, mdb.INDEX, target._index)) meta._force && mod.onclick(event, can, meta, target, cbs)
can.base.isFunc(cbs) && cbs(can) },
}) onclick: function(event, can, meta, target, cbs) {
// can.onengine.signal(can, "onevent", can.request(event));
if (event.ctrlKey && ["n", "p"].indexOf(event.key) > -1) { if (target._selectonly) { can.onmotion.delay(can, function() { target.blur() }) }
return event.stopPropagation(), event.preventDefault() (target.value == "" || meta._force || target._selectonly) && cbs(function(sub, cb) { if (sub.Status(mdb.TOTAL) > 0) { return }
} sub.sup = can._fields? can.sup: can
last(event, can) meta.msg && meta.msg.Length() > 0? sub._show(sub, meta.msg, cb, target, meta.name): sub._load(event, sub, cb, target, meta.name, target.value)
// can.onaction && can.onaction.onkeydown && can.onaction.onkeydown(event, can) }) },
}, onblur: function(event, can, sub, cb, target) {
if (target._hold) { return }
if (target._selectonly) { return }
// can.onengine.signal(can, "onevent", can.request(event, {query: can.page.getquery(can, target)+","+target.value}))
sub && can.onmotion.delay(can, sub.close, 300)
},
onkeyup: function(event, can, meta, cb, target, sub, last) { if (event.key == code.TAB) { return }
if (event.key == code.ENTER) { return meta._enter && (!can.page.tagis(event.target, html.TEXTAREA) || event.ctrlKey) && meta._enter(event, target.value)? sub && sub.close(): last(event) }
if (!sub) { return } can.onmotion.toggle(can, sub._target, true)
sub.hidden() || can.onkeymap.selectCtrlN(event, can, sub._output, "tr:not(.hidden)>td:first-child", function(td) { return meta.select && (sub.close(), meta.select(target.value = td.innerText)), cb(sub, td.innerText, target.value), td })
|| can.onmotion.delayOnce(can, function() { can.onkeymap.selectInputs(event, sub, function() { sub._load(event, sub, cb, target, meta.name) }, target) }, target.value.length < 3? 500: 150)
},
}}) }})

27
plugin/input/keyboard.css Normal file
View File

@ -0,0 +1,27 @@
fieldset.keyboard>div.output>br { clear:both; }
fieldset.keyboard>div.output>div.key {
font-size:24px; text-align:center;
background-color:green; color:white; padding:0; margin:5px;
height:40px; width:40px; float:left;
cursor:pointer;
}
fieldset.keyboard>div.output>div.key:hover { background-color:red; }
fieldset.keyboard>div.output>div.key.double { font-size:16px; white-space:pre; }
fieldset.keyboard>div.output>div.key.special { font-size:16px; background-color:red; }
fieldset.keyboard>div.output>div.key.special:hover { background-color:green; }
fieldset.keyboard>div.output>div.key.special.hold { background-color:green; }
fieldset.keyboard>div.output>div.key.tail { width:70px; }
fieldset.keyboard>div.output>div.key.Tab { width:60px; }
fieldset.keyboard>div.output>div.key.Ctrl { width:70px; }
fieldset.keyboard>div.output>div.key.Shift { width:90px; }
fieldset.keyboard>div.output>div.key.Cmd { width:60px; }
fieldset.keyboard>div.output>div.key.Alt { width:60px; }
fieldset.keyboard>div.output>div.key.Space { width:300px; }
fieldset.keyboard>div.output>div.key.Shift.tail { width:140px; }
fieldset.keyboard>div.output>div.key.Enter { width:110px; }
fieldset.keyboard>div.output>div.key.Backspace { width:90px; }
fieldset.keyboard>div.output>div.key>span { margin-top:2px; display:block; }
fieldset.keyboard>div.output>div.key.special>span { margin-top:10px; }
// table.content td input { width:50px; }
// body.mobile table.content td input { width:80px; }

54
plugin/input/keyboard.js Normal file
View File

@ -0,0 +1,54 @@
Volcanos(chat.ONFIGURE, {keyboard: {
_init: function(can, meta, target) { can.onfigure.keyboard[target.value] && (target.value = "") },
onclick: function(can, meta, target, cbs) { cbs(function(sub) { var msg = can.request()
can.page.style(can, can._output, html.MIN_WIDTH, sub[meta.value||"_normal"](sub, msg))
can.onfigure.keyboard._show(sub, msg, target)
}) },
_show: function(can, msg, target) { can.require(["/plugin/input/keyboard.css"]), can.onmotion.clear(can, can._output)
msg.Table(function(item) { item.type == html.HEAD && can.page.Append(can, can._output, html.BR)
function add(value) { target.value += value, target.focus(), can.user.toast(can, value||item.name) }
function hold() { can.page.ClassList.add(can, div, "hold") }
var div = can.page.Append(can, can._output, [{view: item.type+lex.SP+item.name+(item.name.indexOf(lex.NL)>-1? " double": item.name.length>1? " special": ""), list: [{text: [item.name]}], onclick: function(event) {
switch (item.name) {
case web.CLEAR: target.value = "", target.focus(); break
case cli.CLOSE: can.close(); break
case code.ESC: can.close(); break
case code.CTRL: can._ctrl = !can._ctrl, hold(); break
case code.SHIFT: can._shift = !can._shift, hold(); break
case code.BACKSPACE: target.value = target.value.slice(0, -1), add(""); break
case code.ENTER: break
default: can._shift = can._shift||event.shiftKey
if (item.name == code.TAB) {
add(lex.TB)
} else if (item.name == code.SPACE) {
add(lex.SP)
} else if (item.name.indexOf(lex.NL) > -1) { var ls = can.core.Split(item.name, lex.NL, lex.NL, lex.NL)
add(can._shift? ls[0]: ls[1])
} else {
add(can._shift? item.name.toUpperCase(): item.name)
} can._shift = false, can._ctrl = false, can.page.Select(can, can._output, "div.hold", function(target) { can.page.ClassList.del(can, div, "hold") })
}
} }])._target
})
},
_number: function(can, msg) {
can.core.List([
["1", "2", "3"],
["4", "5", "6"],
["7", "8", "9"],
], function(list) { can.core.List(list, function(item, index) {
msg.Push(can.base.isObject(item)? item: {type: [mdb.KEY, (index == 0? html.HEAD: "")].join(lex.SP), name: item})
}) }); return 150
},
_normal: function(can, msg) {
can.core.List([[code.ESC, "close", "clear"],
["~\n`", "!\n1", "@\n2", "#\n3", "$\n4", "%\n5", "^\n6", "&\n7", "*\n8", "(\n9", ")\n0", "_\n-", "+\n=", code.BACKSPACE],
[code.TAB, "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "{\n[", "}\n]", "|\n\\"],
[code.CTRL, "a", "s", "d", "f", "g", "h", "j", "k", "l", ":\n;", "\"\n'", code.ENTER],
[code.SHIFT, "z", "x", "c", "v", "b", "n", "m", "<\n,", ">\n.", "?\n/", code.SHIFT],
[code.CTRL, code.CMD, code.ALT, code.SPACE, code.ALT, code.CMD, code.CTRL],
], function(list) { can.core.List(list, function(item, index) {
msg.Push(can.base.isObject(item)? item: {type: [mdb.KEY, index == 0? html.HEAD: index == list.length-1? "tail": ""].join(lex.SP), name: item})
}) }); return 750
}
}})

View File

@ -1,9 +1,8 @@
Volcanos("onfigure", {help: "控件详情", list: [], province: {onclick: function(event, can, meta, cb, target) { cb(function(can, cbs) { Volcanos(chat.ONFIGURE, {province: {
can.require(["/require/shylinux.com/x/echarts/echarts.js", "/require/shylinux.com/x/echarts/china.js"], function() { onclick: function(event, can, meta, target, cbs) { cbs(function(can, cb) {
var china_chart = echarts.init(can.page.Append(can, can._output, [{type: html.DIV, style: {width: 600, height: 400}}]).first) can.require(["/require/shylinux.com/x/echarts/echarts.js", "/require/shylinux.com/x/echarts/china.js"], function() {
china_chart.setOption({geo: {map: 'china'}}), china_chart.on(html.CLICK, function (params) { var chart = echarts.init(can.page.Appends(can, can._output, [{type: html.DIV, style: {width: can.page.width()/2, height: can.page.height()/2}}])._target)
target.value = params.name, can.close() chart.setOption({geo: {map: 'china'}}), chart.on(html.CLICK, function(params) { target.value = params.name, can.close() })
}), can.Status(mdb.TOTAL, 34), can.onlayout.figure(event, can), can.base.isFunc(cbs) && cbs(can) }), can.onappend._action(can, [cli.CLOSE], can._action, {close: function() { can.close() }})
}) }) },
}) }}, }) }})

View File

@ -1,25 +1,13 @@
fieldset.div div.output td { fieldset.layout legend { display:none; }
vertical-align:top; fieldset.layout fieldset.plugin { padding:0; margin:0; }
}
fieldset.div div.output fieldset.span>fieldset { fieldset.div div.output td { vertical-align:top; }
float:left; overflow:auto; fieldset.div div.output fieldset.span>div.output>fieldset { overflow:auto; float:left; }
}
fieldset.panel.cmd.main fieldset.div { fieldset.panel.cmd.main fieldset.div>legend { display:none; }
padding:0; fieldset.panel.cmd.main fieldset.div>form.option { display:none; }
margin:0; fieldset.panel.cmd.main fieldset.div>div.action { display:none; }
} fieldset.panel.cmd.main fieldset.div div.project { display:none; }
fieldset.panel.cmd.main fieldset.div>legend { fieldset.panel.cmd.main fieldset.div div.profile { display:none; }
display: none; fieldset.panel.cmd.main fieldset.div>div.status { display:none; }
}
fieldset.panel.cmd.main fieldset.div>form.option {
display: none;
}
fieldset.panel.cmd.main fieldset.div>div.action {
display: none;
}
fieldset.panel.cmd.main fieldset.div div.project {
display: none;
}
fieldset.panel.cmd.main fieldset.div div.profile {
display: none;
}

View File

@ -1,96 +1,65 @@
Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) { Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb, target) {
var meta = {}; msg.Table(function(value) { meta[value.key] = value.value }) var meta = {}; msg.Table(function(value) { meta[value.key] = value.value })
can._meta = can.base.Obj(meta.text, {meta: {name: meta.name||"hi"}, list: []}) can._list = can.base.Obj(meta.text, {meta: {name: meta.name||html.DIV}, list: []})
can.base.isFunc(cb) && cb(msg) can.sup._keys = can.sup._keys||can._list.meta.name
can.onimport.layout(can, can._output)
can.base.isFunc(cb) && cb(msg)
},
_item: function(can, keys, item, target, width, height) { width = width||item.meta.width, height = height||item.meta.height
var ui = can.page.Append(can, target, [{view: [html.ITEM, html.DIV, item.meta.name||html.DIV], onclick: function(event) {
can.onmotion.select(can, can.ui.project, html.DIV_ITEM, event.target), can.current = event.target, can.onimport._profile(can, keys, item.meta)
}, _add: function(data) { item.list.push(data), can.onimport._list(can, keys, item, ui.list, width, height) }}, {view: html.LIST}])
can.ui = can.page.Appends(can, target, [{view: [chat.LAYOUT, html.TABLE], list: [{type: html.TR, list: [ var field = can.onappend.field(can, item.meta.index? chat.PLUGIN: html.LAYOUT, item.meta, target._target)
{type: html.TD, list: [{view: chat.PROJECT}]}, can.page.style(can, ui.list._target = field.output, {width: width, height: height})
{type: html.TD, list: [{view: chat.DISPLAY}]}, item.meta.style && can.page.ClassList.add(can, ui.list._target, item.meta.style)
{type: html.TD, list: [{view: chat.PROFILE}]},
]}] }]), can.ui.project._fieldset = can.ui.display
can.onimport._item(can, can._meta, can.ui.project, can.onimport._size(can)).click() item.meta.index && can.onappend.plugin(can, can.base.Copy({}, item.meta), function(sub) {
}, can.page.style(can, sub._output, {width: width, height: height-2*html.ACTION_HEIGHT})
_size: function(can) { }, target._target, field.fieldset)
var width = can.Conf(html.WIDTH)-260, height = can.Conf(html.HEIGHT)-100
if (can.Conf("auto.cmd")) {
width = can.Conf(html.WIDTH), height = can.Conf(html.HEIGHT)
can.onmotion.hidden(can, can.ui.project)
can.onmotion.hidden(can, can.ui.profile)
can.onmotion.hidden(can, can._option)
can.onmotion.hidden(can, can._action)
}
if (can.user.mod.isCmd || can.user.mod.isDiv) {
width = window.innerWidth, height = window.innerHeight
can.page.Modify(can, can._output, {style: {width: width, height: height}})
}
return width
},
_item: function(can, node, target, width) { width = width||node.meta.width
var ui = can.page.Append(can, target, [{view: [html.ITEM, html.DIV, node.meta.name||"hi"]}, {view: [html.LIST]}])
ui.list._fieldset = can.onimport._plugin(can, node.meta, target._fieldset, width)
var msg = can.request({}); msg.Push(node.meta, "", true) can.onimport._list(can, keys, item, ui.list, width, height)
ui.item.onclick = function(event) { can.sup._keys == keys && ui.item.click()
can.onmotion.select(can, can.ui.project, "div.item", ui.item) },
can.current = ui.item, can.onmotion.clear(can, can.ui.profile) _list: function(can, keys, item, target, width, height) {
can.onappend.table(can, msg, function(value, key, index, line, array) { if (item.meta.style == html.SPAN) { width = width / item.list.length } else { height = height / item.list.length }
return {text: [value, html.TD], ondblclick: function(event) { can.onmotion.clear(can, target), can.onmotion.clear(can, target._target)
key == "value" && can.onmotion.modifys(can, event.target, function(event, value, old) { can.core.List(item.list, function(item) { can.onimport._item(can, can.core.Keys(keys, item.meta.name), item, target, width, height) })
node.meta[line.key] = value },
}) _profile: function(can, keys, meta) { can.onmotion.clear(can, can.ui.profile)
}} var msg = can.request({}); msg.Push(mdb.KEY, "keys"), msg.Push(mdb.VALUE, keys)
}, can.ui.profile) can.core.List(can.core.Split("name,index,args,style,display,height,width"), function(k) {
} msg.Push(mdb.KEY, k), msg.Push(mdb.VALUE, meta[k])
}), can.sup._keys = keys
ui.item._add = function(data) { can.onappend.table(can, msg, function(value, key, index, line, array) {
if (node.meta.style == html.SPAN) { width = width * node.list.length } return {text: [value, html.TD], ondblclick: function(event) { var target = event.target
node.list.push(data) key == mdb.VALUE && can.onmotion.modify(can, event.target, function(event, value, old) {
if (node.meta.style == html.SPAN) { width = width / node.list.length } target.innerText = meta[line.key] = value, can.onimport.layout(can)
can.onmotion.clear(can, ui.list), can.onmotion.clear(can, ui.list._fieldset) }, {name: line.key})
can.core.List(node.list, function(node) { can.onimport._item(can, node, ui.list, width) }) }}
} }, can.ui.profile)
if (node.meta.style == html.SPAN) { width = width / node.list.length } },
can.core.List(node.list, function(node) { can.onimport._item(can, node, ui.list, width) }) layout: function(can, target) { target = target||can._output
return ui.item can.onmotion.clear(can, target), can.onappend.layout(can, null, "", target), can.ui.project._target = can.ui.content
}, var width = can.ConfWidth()-320, height = can.ConfHeight()
_plugin: function(can, meta, target, width) { if (can.isCmdMode()) {
var size = {width: width, height: meta.height} width = can.page.width(), height = can.page.height(), can.user.title(can._list.meta.name)
var field = can.onappend.field(can, chat.LAYOUT, {}, target).fieldset } else if (can.isFullMode()) {
can.page.ClassList.add(can, field, meta.style) width = can.ConfWidth(), height = can.ConfHeight()
can.page.Modify(can, field, {style: size}) can.onmotion.toggle(can, can.ui.project, false)
} else {
meta.index && can.run(event, [ctx.ACTION, ctx.COMMAND, meta.index], function(msg) { can.onmotion.toggle(can, can.ui.profile, true)
can.onappend._init(can, can.base.Copy({ }
feature: can.base.Obj(msg.Append("meta")), can.onimport._item(can, can._list.meta.name, can._list, can.ui.project, width, height)
inputs: can.base.Obj(msg.Append("list")), },
args: meta.args, }, [""])
name: meta.name, Volcanos(chat.ONACTION, {
}, size), ["/plugin/state.js"], function(sub) { "添加": function(event, can) {
can.page.Modify(can, sub._output, {style: size}) can.user.input(event, can, [mdb.NAME, ctx.INDEX, ctx.ARGS, ctx.STYLE, html.HEIGHT, html.WIDTH], function(data) {
sub.run = function(event, cmds, cb) { can.current._add({meta: data, list: []})
can.run(event, can.misc.concat([ctx.ACTION, ice.RUN, meta.index], cmds), cb, true) })
} },
}, target, field) "保存": function(event, can) { var msg = can.request(event, can.Option())
}, true) can.runAction(event, mdb.MODIFY, [mdb.TEXT, JSON.stringify(can._list)])
return field },
},
}, ["/plugin/local/chat/div.css"])
Volcanos("onaction", {help: "操作数据", list: [],
"添加": function(event, can) {
can.user.input(event, can, ["name", "index", "args", "style", "width", "height"], function(event, button, data, list, args) {
can.current._add({meta: data, list: []})
})
},
"保存": function(event, can) { var msg = can.request(event, can.Option())
can.run(event, [mdb.MODIFY, mdb.TEXT, JSON.stringify(can._meta)], function(msg) {
can.user.toastSuccess(can)
}, true)
},
"预览": function(event, can) {
can.request(event, {link: can.misc.MergeURL(can, {_path: "/chat/div/"+can.Option("hash")})})
can.search(event, ["Header.onaction.share"])
},
}) })
Volcanos("onexport", {help: "导出数据", list: []})

View File

@ -0,0 +1,13 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg) { can.db.current = msg.TableDetail()
// can.Conf("_width") && can.sup.onimport.size(can.sup, can.Conf("_height"), can.Conf("_width"), false)
can.page.style(can, can._output, "overflow-y", html.HIDDEN)
can.ui.target = can.page.Appends(can, can._output, [{type: html.IFRAME, src: can.db.current.link, height: can.ConfHeight(), width: can.ConfWidth()}])._target
can.sup.onexport.link = function() { return can.base.beginWith(can.db.current.link, "/")? location.origin+can.db.current.link: can.db.current.link }
},
layout: function(can) {
var item = can.db.current; can.sup.onexport.title(can, item.name||item.link.split(mdb.QS)[0])
can.page.style(can, can.ui.target, html.HEIGHT, can.ConfHeight(), html.WIDTH, can.ConfWidth())
},
})
Volcanos(chat.ONACTION, {open: function(event, can) { can.user.open(can.db.current.link) }})

View File

@ -0,0 +1,2 @@
fieldset.keyboard div.output div.item { float:left; margin:5px; }
fieldset.keyboard div.output div.space { clear:both; }

View File

@ -0,0 +1,24 @@
Volcanos(chat.ONIMPORT, {_init: function(can, msg) { can.onmotion.clear(can)
var data = msg.TableDetail(), list = can.base.Obj(data.list), meta = can.base.Obj(data.meta)
var ui = can.page.Append(can, can._output, ["global", "option", "legend"]); can.user.trans(can, meta._trans)
can.onimport._input(can, [
{type: html.BUTTON, name: "清屏", cmds: "onmotion.clearFloat"},
{type: html.TEXT},
{type: html.BUTTON, name: "下一个", cmds: ["ctrl", "next"]},
{type: html.BUTTON, name: "上一个", cmds: ["ctrl", "prev"]},
{type: html.BUTTON, name: "确定", cmds: ["ctrl", "ok"]},
], data, ui.global)
can.onimport._input(can, list, data, ui.option), can.onimport._input(can, can.sup.onaction.list, data, ui.legend)
},
_input: function(can, item, data, target) { item = can.base.isObject(item)? item: {type: html.BUTTON, name: item}
if (can.base.isArray(item)) { return can.page.Append(can, target, [{view: "space"}]), can.core.List(item, function(item) { can.onimport._input(can, item, data, target) }) }
item._init = item._init||function(target) { switch (target.type) {
case html.TEXT: target.onkeydown = function(event) { can.misc.Event(event, can, function(msg) { if (event.key == code.ENTER) {
can.runAction(can.request(event, data), web.SPACE, [ctx.ACTION, item.name, target.value], function() {})
} })}; break
case html.BUTTON: target.onclick = function(event) { can.misc.Event(event, can, function(msg) {
can.runAction(can.request(event, data), web.SPACE, [ctx.ACTION].concat(item.cmds||item.name), function() {})
})}; break
} }, can.onappend.input(can, item, "", target)
},
}, [""])

View File

@ -1,37 +0,0 @@
Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) {
can.ui = can.onlayout.display(can, target)
can.ui.canvas = can.page.Append(can, can.ui.display, [{type: "canvas", width: 320, height: 240, style: {display: "none"}}]).first
can.onappend.table(can, msg, function(value, key, index, line, array) {
return {text: [value, "td"], onclick: function(event) {
can.sup.onaction.change(event, can.sup, key, value, function(msg) {
can.run(event)
})
}}
}, can.ui.content)
can.onappend.board(can, msg.Result(), can.ui.display)
can.base.isFunc(cb) && cb(msg)
},
})
Volcanos("onaction", {help: "操作数据", list: [], _init: function(can, msg, list, cb, target) {
},
open: function(event, can) {
navigator.getUserMedia({video: {width: 320, height: 240}}, function(stream) {
var video = can.page.Append(can, can.ui.content, "video")
video.srcObject = stream, video.play()
can.ui.video = video
}, function(error) {
can.misc.Log("open camera", error)
})
},
snapshot: function(event, can) {
can.ui.canvas.getContext("2d").drawImage(can.ui.video, 0, 0)
can.page.Append(can, can.ui.display, [{type: "img", src: can.ui.canvas.toDataURL('image/webp')}])
},
})
Volcanos("onexport", {help: "导出数据", list: [],
})

View File

@ -1,34 +1,30 @@
Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) { Volcanos(chat.ONIMPORT, {_init: function(can, msg) { var height = 0.6
can.onmotion.clear(can) can.from = can.onimport._plugin(can, nfs.DIR, html.LEFT, height, "from", "to")
can.from = can.onimport._plugin(can, nfs.DIR, html.LEFT, "from", "to") can.to = can.onimport._plugin(can, nfs.DIR, html.RIGHT, height, "to", "from")
can.to = can.onimport._plugin(can, nfs.DIR, html.RIGHT, "to", "from") can.onmotion.delay(can, function() {
can.onimport._plugin(can, nfs.TRASH, html.LEFT, "from") can.from_trash = can.onimport._plugin(can, nfs.TRASH, html.LEFT, 1-height, "from")
can.onimport._plugin(can, nfs.TRASH, html.RIGHT, "to") can.to_trash = can.onimport._plugin(can, nfs.TRASH, html.RIGHT, 1-height, "to")
}, }, 100)
_plugin: function(can, index, pos, from, to) { },
return can.onappend.plugin(can, {type: chat.STORY, index: index}, function(sub) { _plugin: function(can, index, pos, height, from, to) {
can.page.Modify(can, sub._target, {style: {float: pos, clear: pos}}) return can.onappend.plugin(can, {type: chat.STORY, space: can.Option(from), index: index}, function(sub) {
sub.Conf(html.WIDTH, can.Conf(html.WIDTH)/2) sub._legend.innerHTML = can.Option(from)+nfs.PT+index, can.page.style(can, sub._target, {float: pos, clear: pos})
sub._legend.innerHTML = can.Option(from)+ice.SP+index sub.onexport.output = function() { sub.onimport.size(sub, can.ConfHeight()*height-20, can.ConfWidth()/2-20, false) }
can.page.Modify(can, sub._output, {style: {"max-width": can.Conf(html.WIDTH)/2}}) sub.onimport.size(sub, can.ConfHeight()*height-20, can.ConfWidth()/2-20, false)
sub.run = function(event, cmds, cb) { var msg = can.request(event); msg.Option("from", can.Option(from)), msg.Option("to", can.Option(to))
sub.run = function(event, cmds, cb) { if (can.onaction[cmds[1]]) { return can.onaction[cmds[1]](can, from, to, event, cmds, cb) }
if (can.onaction[cmds[1]]) { return can.onaction[cmds[1]](can, from, to, event, cmds, cb) } can.runActionCommand(event, index, cmds, function(msg) { cb && cb(msg)
if (cmds[0] == ctx.ACTION) {
var msg = sub.request(event, {_pod: can.Option(from)}) if (!to) { can[from].Update() } else { can[from+"_trash"].Update() }
can.run(event, can.misc.concat([ctx.ACTION, ice.RUN, index], cmds), cb, true) }
} })
}) }
}, })
},
}) })
Volcanos("onaction", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) { Volcanos(chat.ONACTION, {
}, send: function(can, from, to, event, cmds, cb) { var msg = can.request(event, {_handle: ice.TRUE})
send: function(can, from, to, event, cmds, cb) { var _from = can[from], _to = can[to] msg.Option("from_path", can[from].Option(nfs.PATH)), msg.Option("to_path", can[to].Option(nfs.PATH))
var path = can.request(event).Option(nfs.PATH) can.run(event, cmds, function() { can[to].Update() })
var msg = can.request(event, {_handle: ice.TRUE, },
from: can.Option(from), from_path: path,
to: can.Option(to), to_path: _to.Option(nfs.PATH)+path.split(ice.PS).pop(),
})
can.run(event, cmds, function() { _to.Update() }, true)
},
}) })

View File

@ -1,28 +0,0 @@
Volcanos("onaction", {source: function(can, msg) {
can.require(["https://res.wx.qq.com/open/js/jweixin-1.6.0.js"], function(can) {
wx.config({debug: msg.Option("debug") == ice.TRUE,
appId: msg.Option("appid"), signature: msg.Option("signature"),
nonceStr: msg.Option("noncestr"), timestamp: msg.Option("timestamp"),
jsApiList: can.core.Item({
scanQRCode: function(cb) { wx.scanQRCode({needResult: cb? 1: 0, scanType: ["qrCode","barCode"], success: function (res) {
can.base.isFunc(cb) && cb(res.resultStr, can.base.ParseJSON(res.resultStr))
} }) },
getLocation: function(cb) { wx.getLocation({type: "gcj02", success: function (res) {
can.base.isFunc(cb) && cb({type: "gcj02", name: "当前位置", text: "当前位置", latitude: parseInt(res.latitude*100000), longitude: parseInt(res.longitude*100000) })
} }) },
openLocation: function(msg) { wx.openLocation({
latitude: parseInt(msg.Option("latitude"))/100000,
longitude: parseInt(msg.Option("longitude"))/100000,
name: msg.Option(mdb.NAME), address: msg.Option(mdb.TEXT),
scale: msg.Option("scale")||14, infoUrl: msg.Option(mdb.LINK),
}) },
chooseImage: function(cb, count) { wx.chooseImage({count: count||9, sizeType: ['original', 'compressed'], sourceType: ['album', 'camera'], success: function (res) {
can.base.isFunc(cb) && cb(res.localIds)
} }) },
}, function(key, value) { return can.user.agent[key] = value, key }),
})
wx.error(function(err) { can.user.toast(err, "wx load") })
wx.ready(function() { can.misc.Log("ready") })
})
}})

View File

@ -1,104 +1,107 @@
fieldset.inner>div.action div.file { fieldset.inner>div.output div.content { position:relative; }
border:solid 2px red; padding:2px; fieldset.inner>div.output div.content td.text { height:var(--code-line-height); }
float:left; cursor:pointer; fieldset.inner>div.output div.content td.text span.keyword { color:var(--code-keyword); box-shadow:var(--keyword-box-shadow); }
fieldset.inner>div.output div.content td.text span.comment { color:var(--code-comment); }
fieldset.inner>div.output div.content td.text span.function { color:var(--code-function); }
fieldset.inner>div.output div.content td.text span.constant { color:var(--code-constant); }
fieldset.inner>div.output div.content td.text span.string { color:var(--code-string); box-shadow:var(--keyword-box-shadow); }
fieldset.inner>div.output div.content td.text span.package { color:var(--code-package); }
fieldset.inner>div.output div.content td.text span.datatype { color:var(--code-datatype); }
fieldset.inner>div.output div.content td.text span.object { color:var(--code-object); }
fieldset.inner>div.output>div.project { font-family:var(--code-font-family); }
fieldset.inner>div.output>div.project div.list { border-left:none; }
fieldset.inner>div.output>div.project div.item.select:not(:hover) { background-color:unset; }
fieldset.inner>div.output>div.layout>div.tabs>div.tabs>div.tabs { border-top:var(--box-border3); border-top-color:transparent; }
fieldset.inner>div.output>div.layout>div.tabs>div.tabs>div.tabs.select { box-shadow:var(--legend-box-shadow); background-color:var(--output-bg-color); border-top:var(--box-notice3); }
fieldset.inner>div.output>div.layout>div.tabs>div.tabs>div.tabs:hover { box-shadow:var(--legend-box-shadow); background-color:var(--output-bg-color); }
fieldset.inner>div.output>div.layout>div.path { font-size:var(--code-font-size); display:none; }
fieldset.inner>div.output>div.layout>div.path:not(.hide) { box-shadow:var(--legend-box-shadow); font-style:italic; cursor:pointer; justify-content:flex-start; align-items:center; }
fieldset.inner>div.output>div.layout>div.path>a { padding:var(--input-padding); }
fieldset.inner>div.output>div.layout>div.path>a:hover { background-color:var(--hover-bg-color); }
fieldset.inner>div.output>div.layout>div.path>span { padding:var(--input-padding); white-space:pre; }
fieldset.inner>div.output>div.layout>div.path>span:hover { background-color:var(--hover-bg-color); }
fieldset.inner>div.output>div.layout>div.path>span._space:hover { background-color:unset; }
fieldset.inner>div.output>div.layout>div.path>span.view { font-style:normal; font-size:22px; padding:0 var(--input-padding); }
body.windows fieldset.inner>div.output>div.layout>div.path>span.view { font-size:18px; }
fieldset.inner>div.output>div.layout>div.display h1 { border-bottom:var(--box-border); margin:var(--title-margin) 0; }
fieldset.inner>div.output>div.layout>div.display h2 { border-bottom:var(--box-border); margin:var(--title-margin) 0; }
fieldset.inner>div.output>div.layout>div.display pre>code { padding-left:var(--table-padding); border-left:var(--box-notice3); display:block; }
fieldset.inner>div.output>div.layout>div.display div.code { white-space:unset; padding:var(--table-padding); }
fieldset.inner>div.output>div.layout>div.display div.status { position:sticky; bottom:0; }
fieldset.inner>div.output>div.layout>div.display div.status>div { padding:var(--input-padding); float:left; }
fieldset.inner>div.output>div.layout>div.layout { justify-content:flex-start; }
fieldset.inner>div.output>div.layout>div.layout>div.profile h1 { border-bottom:var(--box-border); margin:var(--title-margin) 0; }
fieldset.inner>div.output>div.layout>div.layout>div.profile h2 { border-bottom:var(--box-border); margin:var(--title-margin) 0; }
fieldset.inner>div.output>div.layout>div.layout>div.profile pre>code { padding-left:var(--table-padding); border-left:var(--box-notice3); display:block; }
fieldset.inner>div.output>div.layout>div.layout>div.profile>div.code { white-space:unset; padding:var(--table-padding); }
fieldset.inner>div.output>div.layout>div.layout>div.profile>div.status { background-color:var(--output-bg-color); height:var(--action-height); overflow:auto; position:sticky; bottom:0; }
fieldset.inner>div.output>div.layout>div.layout>div.profile fieldset>form.option>div.item.text input { max-width:80px; }
fieldset.inner>div.output>div.layout>div.layout>div.profile fieldset>div.action>div.item.text input { max-width:80px; }
fieldset.inner>div.output>div.layout>div.layout>div.profile div.status>div { font-style:italic; font-size:var(--status-font-size); padding:var(--input-padding); float:left; }
fieldset.inner>div.output>div.layout>div.layout>div.content div.tips { color:var(--disable-fg-color); font-style:italic; line-height:var(--code-line-height); position:absolute; top:0; right:10px; }
fieldset.inner>div.output>div.layout>div.layout>fieldset.story { box-shadow:unset; }
fieldset.inner.cmd>div.output>div.layout>div.tabs:not(.hide) { background-color:var(--plugin-bg-color); height:var(--code-tabs-height); display:flex; }
fieldset.inner.cmd>div.output>div.layout>div.tabs>div { height:var(--code-tabs-height); }
fieldset.inner.cmd>div.output>div.layout>div.tabs>div.icon>div.icon { font-size:26px; line-height:32px; padding:2px 5px; position:sticky; top:0; }
fieldset.inner.cmd>div.output>div.layout>div.tabs>div.tabs { justify-content:flex-start; flex-grow:1; flex-wrap:wrap; overflow:auto; display:flex; }
fieldset.inner.cmd>div.output>div.layout>div.tabs>div.tabs:hover { background-color:unset; color:unset; }
fieldset.inner.cmd>div.output>div.layout>div.tabs>div.tabs>div.tabs { padding:var(--input-padding) var(--button-padding); height:var(--code-tabs-height); display:flex; align-items:center; }
fieldset.inner.cmd>div.output>div.layout>div.tabs>div.head { display:flex; flex-direction:row-reverse; flex-shrink:0; }
fieldset.inner.cmd>div.output>div.layout>div.tabs>div.head>div { padding:0 var(--input-padding); display:flex; align-items:center; flex-shrink:0; }
fieldset.inner.cmd>div.output>div.layout>div.tabs>div.head>div.online { margin-left:0 !important; margin-right:0 !important; flex-direction: row-reverse; }
fieldset.inner.cmd>div.output>div.layout>div.tabs>div.head>div.online img { height:24px; }
fieldset.inner.cmd>div.output>div.layout>div.tabs>div.head>div.avatar { padding:0; }
fieldset.inner.cmd>div.output>div.layout>div.tabs>div.head>div.qrcode i { margin-top:3px; }
fieldset.inner.cmd>div.output>div.layout>div.tabs>div.head>div.avatar>img { height:32px; clip-path:circle(40%); }
fieldset.inner.cmd>div.output>div.layout>div.path:not(.hide) { display:flex; }
fieldset.inner.cmd>div.output>div.layout>div.plug { box-shadow:var(--th-box-shadow); background-color:var(--plugin-bg-color); height:var(--action-height); overflow:auto; }
fieldset.inner.cmd>div.output>div.layout>div.plug>legend { padding:0 var(--input-padding); padding-right:0; margin-right:0; float:right; }
fieldset.inner.cmd>div.output>div.layout>div.plug>legend:hover { box-shadow:var(--notice-box-shadow); }
fieldset.inner.cmd>div.output>div.layout>div.plug>legend>span.remove { padding:0 var(--input-padding); }
fieldset.inner.cmd>div.output>div.layout>div.plug>legend>span.remove:hover { background-color:var(--hover-bg-color); }
fieldset.inner.cmd>div.output>div.layout>div.plug>legend:not(:hover)>span.remove { visibility:hidden; }
fieldset.inner fieldset.plug.can._plugin.search>form.option>div.item.value input { width:var(--project-width); }
fieldset.inner fieldset.plug.can._plugin.search>form.option>div.item.filter input { width:var(--project-width); }
fieldset.inner fieldset.plug.can._plugin.search>div.output>table.content tr td { cursor:pointer; }
fieldset.inner.float>div.output>div.layout>div.path { font-size:var(--code-font-size); display:flex; }
fieldset.Action.tabview fieldset.plugin.inner>div.output>div.layout>div.path:not(.hide) { font-size:var(--code-font-size); display:flex; }
fieldset.inner:not(.monaco)>div.output div.content>tr.line * { font-family:var(--code-font-family); font-size:var(--code-font-size); }
fieldset.inner.plugin>div.output>div.layout>div.layout div.content tr.line.select>td.line { background-color:var(--notice-bg-color); color:white; }
fieldset.vimer.plugin>div.output>div.layout>div.layout div.content tr.line.select>td.line { background-color:unset; color:unset; }
div.carte.inner.mode.float div.item { padding:var(--input-padding); }
div.carte.inner.path.float div.item { padding:var(--input-padding); }
div.carte.inner.path.float div.item.private { color:var(--disable-fg-color); }
div.input.inner.find.float div.action div.item { margin:var(--input-margin); }
div.input.inner.find.float div.action div.item.text input { width:var(--project-width); }
div.input.inner.find.float div.action div.item.close span { display:none; }
div.input.inner.find.float div.action div.item.replace input { border:var(--box-danger); }
div.input.inner.open.float td:first-child { display:none; }
div.input.inner.open.float div.item.text input[type=text] { width:100% !important; }
div.input.inner.open.float td:nth-child(2) { display:none; }
tr.line>td.line { border-right:var(--box-border); cursor:pointer; -webkit-user-select:none; }
tr.line>td.line { text-align:right; line-height:var(--code-line-height); padding:0 var(--button-padding); position:sticky; left:0; }
tr.line>td.text { white-space:pre; line-height:var(--code-line-height); padding-left:var(--input-padding); width:100%; }
tr.line:hover { background-color:var(--hover-bg-color); }
tr.line.delete { background-color:#3c2626; }
tr.line.insert { background-color:#283e2d; }
body div.input.inner.find.float div.action>div.item {
float:left;
} }
fieldset.inner>div.action div.file.over { body div.input.inner.find.float div.action>div.item>input {
background-color:blue; min-width:unset;
}
fieldset.inner>div.action div.file.select {
background-color:green;
}
fieldset.inner>div.output {
color:white;
}
fieldset.inner div.output div.toggle {
display:none;
}
fieldset.inner>div.output div.project {
font-size:14px; font-family:monospace;
max-width:180px; overflow:auto;
}
fieldset.inner>div.output div.content {
font-size:16px; font-family:monospace;
overflow:auto; padding-right:25px;
position:relative;
color:white;
}
fieldset.inner>div.output div.content table.layout {
width:-webkit-fill-available;
}
fieldset.inner>div.output div.content tr.select td.line {
border:solid 1px red;
border-right:solid 2px red;
background-color:blue;
}
fieldset.inner>div.output div.content td.line:hover {
background-color:green;
}
fieldset.inner>div.output div.content td.line {
text-align:right; padding:0 6px;
border-right:solid 2px red;
}
fieldset.inner>div.output div.content td.text {
text-align:left; height:20px;
padding-left:10px;
white-space:pre;
}
fieldset.inner>div.output div.content td.text span.comment {
color:cyan; background-color:blue;
}
fieldset.inner>div.output div.content td.text span.keyword {
color:yellow; font-weight:bold;
}
fieldset.inner>div.output div.content td.text span.function {
color:cyan; font-weight:bold;
}
fieldset.inner>div.output div.content td.text span.datatype {
color:lightgreen; font-weight:bold;
}
fieldset.inner>div.output div.content td.text span.constant {
color:magenta;
}
fieldset.inner>div.output div.content td.text span.string {
color:magenta;
}
fieldset.inner>div.output div.search {
padding:6px; border:solid 1px red;
}
fieldset.inner>div.output div.search div.tags {
text-align:left; overflow:auto;
}
fieldset.inner>div.output div.search div.tags table {
width:-webkit-fill-available;
}
fieldset.inner>div.output div.search td>div {
max-height:100px;
overflow:hidden;
}
body.white fieldset.inner>div.output div.project {
color:#a2dad2;
}
body.white fieldset.inner>div.output div.content {
background-color:#013b675c;
}
body.white fieldset.inner>div.output div.content td.text span.string {
color:#a703a7;
}
body.white fieldset.inner>div.output div.content tr {
background-color:#e1f1ff00;
}
.unselectable {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select:none;
user-select: none;
} }
body.light tr.line.delete { background-color:#ffeef0; }
body.light tr.line.insert { background-color:#e6ffed; }
body.white tr.line.delete { background-color:#e6ffed; }
body.white tr.line.insert { background-color:#ffeef0; }
body.width2 fieldset.inner>div.output>div.layout>div.path span.mode { display:none; }
body.mobile fieldset.inner>div.output>div.layout>div.path span.func { display:none; }
body.mobile fieldset.inner>div.output>div.layout>div.path span.mode { display:none; }
body.light fieldset.inner.cmd>div.output>div.layout>div.tabs>div.tabs>div.tabs { margin-right:var(--button-margin); }
body:not(.mobile) fieldset.inner>div.output>div.layout>fieldset.plug { bottom:var(--action-height); }
body:not(.windows) fieldset.inner>div.output>div.project * { font-family:var(--code-font-family); font-size:var(--code-font-size); }
body:not(.windows) fieldset.inner>div.output>div.layout>div.tabs { font-family:var(--code-font-family); font-size:var(--code-font-size); }
body:not(.windows) fieldset.inner>div.output>div.layout>div.path { font-family:var(--code-font-family); font-size:var(--code-font-size); }
body.windows fieldset.inner.cmd>div.output>div.layout>div.tabs>div.icon>div.icon { font-size:20px !important; padding-top:6px; }
body.windows fieldset.inner>div.output>div.layout>div.path span.view { margin-top:0; }
body.windows fieldset.inner>div.output>div.layout>div.path span.view { font-style:normal; }

View File

@ -1,340 +1,617 @@
Volcanos("onimport", {help: "导入数据", _init: function(can, msg, list, cb, target) { (function() {
can.onmotion.clear(can) const PROJECT_HIDE = "project:hide", TABVIEW_HIDE = "tabview:hide"
can.ui = can.onlayout.profile(can) const PROFILE_ARGS = "profile:args:", DISPLAY_ARGS = "display:args:"
can.onimport._content(can, target) const CURRENT_FILE = "web.code.inner:currentFile", SELECT_LINE = "selectLine"
can.onimport._output(can, target) const VIEW_CREATE = "tabview.view.create", VIEW_REMOVE = "tabview.view.remove", LINE_SELECT = "tabview.line.select"
// can.onimport._favor(can, target) Volcanos(chat.ONIMPORT, {
// can.onimport._search(can, target) _init: function(can, msg, cb) { can.onappend.style(can, code.INNER), can.Mode(msg.Option("mode")||can.Mode())
if (can.Mode() == ice.MSG_RESULT) {
can.history = can.history||[] can.Conf("_width", can.base.Max(can.ConfWidth(), window.innerWidth-12))
msg.Option({path: can.Option(nfs.PATH), file: can.Option(nfs.FILE), line: can.Option(nfs.LINE)||1}) msg.result = msg.result||[can._output.innerHTML], can.Mode(chat.SIMPLE), can.sup.Mode(chat.SIMPLE)
can.tabview = can.tabview||{}, can.tabview[can.Option(nfs.PATH)+can.Option(nfs.FILE)] = msg can.Option(nfs.FILE, can.Conf(nfs.FILE)||can.Option(nfs.FILE))
}
can.onimport.tabview(can, msg.Option(nfs.PATH), msg.Option(nfs.FILE), msg.Option(nfs.LINE)||1) can.onmotion.clear(can, can._output), msg.result = msg.result||[""]
can.onimport.project(can, msg.Option(nfs.PATH)) var paths = can.core.Split(can.Option(nfs.PATH)); can.Option(nfs.PATH, paths[0])
can.base.isFunc(cb) && cb(msg) can.core.List([nfs.PATH, nfs.FILE, nfs.LINE], function(key) { msg.Option(key) && can.Option(key, msg.Option(key)) })
}, can.db = {tabview: {}, history: [], _history: [], toolkit: {}}, can.db.tabview[can.onexport.keys(can)] = msg
_content: function(can, target) { can.db.hash = can.isCmdMode()? can.misc.SearchHash(can): []
var height = can.Conf(html.HEIGHT)-(can.user.mod.isCmd? 54: 320); height < 240 && (height = 240) can.ui = can.onappend.layout(can, [html.PROJECT, [html.TABS, nfs.PATH, [html.CONTENT, html.PROFILE], html.DISPLAY, html.PLUG]])
can.page.Modify(can, can.ui.project, {style: {"max-height": height}}) can.ui._content = can.ui.content, can.ui._profile = can.ui.profile, can.ui._display = can.ui.display
can.page.Modify(can, can.ui.content, {style: {"max-height": height}}) can.onmotion.clear(can, can.ui.project), can.onmotion.hidden(can, can.ui.project), can.onmotion.hidden(can, can.ui.tabs), can.onmotion.hidden(can, can.ui.plug)
can.page.Modify(can, can.ui.display, {style: {display: chat.NONE}}) can.db.value = {}
}, var show = !can.user.isMobile
_output: function(can, target) { switch (can.Mode()) {
var ui = can.page.Append(can, can.ui.display, [{view: html.ACTION}, {view: html.OUTPUT}]); can.ui.output = ui.output case chat.SIMPLE: // no break
case chat.FLOAT: break
can.onappend._action(can, ["exec", cli.CLEAR, cli.CLOSE], ui.action, { case chat.CMD: can.onappend.style(can, html.OUTPUT)
exec: function(event) { can.onaction["exec"](event, can) }, if (can.onexport.session(can, PROJECT_HIDE) == html.HIDE) { show = false }
clear: function(event) { can.onmotion.clear(can, can.ui.output) }, if (can.onexport.session(can, TABVIEW_HIDE) == html.HIDE) { show = false } else { can.onmotion.toggle(can, can.ui.tabs, true), can.onmotion.toggle(can, can.ui.plug, true) }
close: function(event) { can.onmotion.hidden(can, can.ui.display) }, var tool = (can.base.Obj(msg.Option(ice.MSG_TOOLKIT), []).reverse()); msg.Option(ice.MSG_TOOLKIT, "[]")
}) can.onimport._tabs(can), tool && tool.length > 0? can.core.Next(tool, function(item, next) { can.onimport.toolkit(can, item, next) }): can.onmotion.hidden(can, can.ui.plug)
}, case chat.FULL: // no break
_favor: function(can, target) { default: can.onmotion.toggle(can, can.ui.project, show), can.onimport.project(can, can.db.paths = paths), can.onkeymap._build(can)
can.onappend.plugin(can, {type: chat.STORY, index: "web.code.favor"}, function(sub) { } can.onimport.layout(can), can.onimport.tabview(can, can.Option(nfs.PATH), can.Option(nfs.FILE), can.Option(nfs.LINE), function() { cb && cb(msg) })
sub.run = function(event, cmds, cb) { var msg = can.request(event) },
if (cmds && cmds[0] == ctx.ACTION) { switch (cmds[1]) { _tabs: function(can) { if (!can.isCmdMode()) { return can.ui._tabs = can._action }
case code.INNER: can.onimport.tabview(can, msg.Option(nfs.PATH), msg.Option(nfs.FILE), msg.Option(nfs.LINE)); return var ui = can.page.Append(can, can.ui.tabs, ["tabs", "head"]); can.ui._tabs = ui.tabs, can.page.Append(can, ui.head, can.user.header(can))
} } },
_tabIcon: function(can) {
can.run(event, can.misc.concat([ctx.ACTION, code.FAVOR], cmds), function(msg) { can.page.Append(can, can.ui.path, can.core.Item({
can.base.isFunc(cb) && cb(msg), can.core.Timer(10, function() { "\u271A": shy({transform: "translate(0 2px)"}, function(event) { can.onaction.open(event, can, "open") }),
can.onappend._action(sub, [cli.CLOSE], sub._action, { "\u2756": shy({}, function(event) { can.onaction.plug(event, can, "plug") }),
close: function(event) { can.onmotion.hidden(sub, sub._target) }, "\u25E7": function(event) { var show = can.onmotion.toggle(can, can.ui.project); can.onimport.layout(can), can.isCmdMode() && can.onexport.session(can, PROJECT_HIDE, show? "": html.HIDE) },
}) "\u25E8": shy({transform: "rotate(90deg) translate"+(can.user.isWindows? "(-2px)": "(1px,-2px)")}, function(event) {
}) if (can.page.isDisplay(can.ui.display)) { return can.onmotion.hidden(can, can.ui.display), can.onimport.layout(can) } can.onaction.exec(event, can) }),
}, true) "\u25E8 ": shy({width: 32}, function(event) { if (can.page.isDisplay(can.ui.profile)) {
}, can.ui.favor = sub can._msg._profile_hidden = true
return can.onmotion.hidden(can, can.ui.profile), can.onimport.layout(can) } can.onaction.show(event, can) }),
can.onmotion.hidden(sub, sub._target) }, function(text, cb) { return cb && {text: [text, html.SPAN, html.VIEW], style: cb.meta, onclick: cb} }))
}, target) },
}, _tabMode: function(can) { var mode = can.db.mode||"", target = can.ui.current; if (target && mode != mdb.PLUGIN) { mode += lex.SP+target.selectionStart+nfs.PS+target.value.length }
_search: function(can, target) { can.page.Append(can, can.ui.path, [{text: [mode, "", [ice.MODE, can.db.mode||""]], onclick: function(event) {
var ui = can.page.Append(can, target, [ var list = {}; can.core.Item(can.onkeymap._mode[can.db.mode], function(k, cb) { list[k+" "+cb.help] = function(event, can, button) { can.core.CallFunc(cb, {event: event, can: can}) } })
{view: mdb.SEARCH, style: {display: chat.NONE}, list: [ can.core.Item(can.onkeymap._mode[can.db.mode+"_ctrl"], function(k, cb) { list["C-"+k+" "+cb.help] = function(event, can, button) { can.core.CallFunc(cb, {event: event, can: can}) } })
{view: chat.ACTION, list: [ list._style = "inner mode"
{input: ["word", function(event) { can.user.carte(event, can, list, [])
event.key == lang.ENTER && can.onaction.searchLine(event, can, ui.word.value) }}])
}], value: "main", onfocus: function(event) { event.target.setSelectionRange(0, -1) }}, },
{button: [mdb.SEARCH, function(event) { can.onaction.searchLine(event, can, ui.word.value) }]}, _tabFunc: function(can, target, cache) {
{button: ["back", function(event) { can.onaction["back"](event, can) }]}, if (cache) { var func = can.db._func||{list: []} } else { var func = can.onexport.func(can); can.db._func = func }
{button: ["close", function(event) { can.onaction["搜索"](event, can) }]}, if (func.list.length > 0) { can.db.tabFunc = can.db.tabFunc||{}
]}, var last = can.db.tabFunc[can.Option(nfs.PATH)+can.Option(nfs.FILE)]||{}; can.db.tabFunc[can.Option(nfs.PATH)+can.Option(nfs.FILE)] = last
{view: "tags", style: {"max-height": 160}}, var carte, list = [web.FILTER]; can.core.Item(last, function(key) { list.push(key) }), list = list.concat(func.list)
]}, }
]); can.base.Copy(can.ui, ui, mdb.SEARCH, "word", "tags") can.page.Append(can, target, [{view: [[html.ITEM, "func"], html.SPAN, (func.current||"func")+nfs.PS+can.ui.content._max+func.percent+lex.SP+can.base.Size(can._msg.result[0].length)], onclick: function(event) {
}, carte = can.user.carte(event, can, {_style: "inner "+nfs.PATH}, list, function(ev, button) { last[button] = true, carte.close()
var line = can.core.Split(button, nfs.DF, nfs.DF).pop()
project: function(can, path) { can.Option({path: path}) can.onimport.tabview(can, "", can.Option(nfs.FILE), line, function() { can.onaction.selectLine(can, line, true) })
var msg = can.request({}, {dir_root: path, dir_deep: true}) })
can.run(msg._event, ["./"], function(msg) { can.onmotion.clear(can, can.ui.project) carte && can.onmotion.delay(can, function() { can.page.Select(can, carte._target, html.DIV_ITEM, function(target) {
can.onappend.tree(can, msg.Table(), nfs.PATH, ice.PS, function(event, item) { can.onappend.style(can, can.base.beginWith(target.innerText, "- ")? aaa.PRIVATE: aaa.PUBLIC, target)
can.onimport.tabview(can, path, item.path) }) })
}, can.ui.project), can.Status("文件数", msg.Length()) }}])
}, true) },
}, __tabPath: function(can, cache) { var target = can.ui.path
tabview: function(can, path, file, line, cb) { function _space(grow) { can.page.Append(can, target, [{view: ["_space", html.SPAN], style: {"flex-grow": grow||"1"}}]) }
if (can.tabview[path+file]) { can.onimport._tabPath(can, nfs.PS, nfs.PATH, can.base.Path(can.Option(nfs.PATH), can.Option(nfs.FILE)), function(p) {
can._msg && can._msg.Option(nfs.LINE, can.Option(nfs.LINE)) var ls = can.onexport.split(can, p); can.onimport.tabview(can, ls[0], ls[1])
can._msg = can.tabview[path+file] }, target), _space(), can.onimport._tabFunc(can, target, cache), _space(), can.onimport._tabMode(can), _space("4"), can.onimport._tabIcon(can)
target.ondblclick = function(event) { if (event.target != target && !can.page.tagis(event.target, "span._space")) { return }
can.Option({path: path, file: file, line: line||parseInt(can._msg.Option(nfs.LINE))||1}) var show = can.onmotion.toggle(can, can.ui.tabs); can.onmotion.toggle(can, can.ui.plug, show), can.onmotion.toggle(can, can.ui.project, show), can.onimport.layout(can)
can._msg.Option(nfs.LINE, can.Option(nfs.LINE)) can.isCmdMode() && can.onexport.session(can, TABVIEW_HIDE, show? "": html.HIDE)
return can.onsyntax._init(can, can._msg), can.base.isFunc(cb) && cb() }
} },
_tabPath: function(can, ps, key, value, cb, target) { var args = value.split(mdb.FS); can.onmotion.clear(can, can.ui.path)
can.run({}, [path, file], function(msg) { can.core.List(can.core.Split(args[0], ps), function(value, index, list) {
msg.Option({path: path, file: file, line: line||1}) can.page.Append(can, target, [{text: [value+(index<list.length-1? " "+ps: ""), "", html.ITEM], onclick: function(event) {
can.tabview[path+file] = msg can.onimport.tabPath(event, can, ps, key, ps == nfs.PT? list.slice(0, index).join(ps): (list.slice(0, index).join(ps)||nfs.PT)+ps, cb)
}}])
msg._tab = can.page.Append(can, can._action, [ })
{text: [file.split(ice.PS).pop(), html.DIV, nfs.FILE], title: file, onclick: function(event) { },
can.onimport.tabview(can, path, file, "", cb) tabPath: function(event, can, ps, key, pre, cb, parent) { can.runAction(event, mdb.INPUTS, [key, pre, lex.SPLIT], function(msg) { var _trans = {}
}, _init: function(item) { var carte = (can.user[parent? "carteRight": "carte"](event, can, {_style: "inner "+key}, (msg.Length() > 10? [web.FILTER]: []).concat(msg.Table(function(value) {
can.core.Timer(10, function() { item.click() }) var p = can.core.Split(value[key], ps).pop()+(can.base.endWith(value[key], ps)? ps: ""); return _trans[p] = value[key], p
can.onaction.EnableDrop(can, can._action, "div.file", item) })), function(event, button) {
}} if (can.base.endWith(button, ps)) { can.onimport.tabPath(event, can, ps, key, pre+button, cb, carte); return true } else { cb(_trans[button], pre) }
]).last }, parent)||{})._target, file = can.core.Split(event.target.innerHTML.trim(), nfs.PT)[0]
}, true) carte && can.page.Select(can, carte, html.DIV_ITEM, function(target) {
}, target.innerHTML.trim() != event.target.innerHTML.trim() && can.base.beginWith(target.innerHTML, file+nfs.PT) && carte.insertBefore(target, carte.firstChild)
target.innerHTML.trim() == event.target.innerHTML.trim() && can.onappend.style(can, html.SELECT, target)
}), can.onmotion.delay(can, function() { carte.scrollTop = 0 })
}) },
openzone: function(can, path, file, line) {
if (line == web.SPACE) {
can.page.isDisplay(can.ui.zone.space._target) || can.ui.zone.space._legend.click()
} else if (line == ctx.INDEX) {
if (can.base.beginWith(file, "can.")) {
can.page.isDisplay(can.ui.zone.plugin._target) || can.ui.zone.plugin._legend.click()
} else {
can.page.isDisplay(can.ui.zone.command._target) || can.ui.zone.command._legend.click()
}
} else {
if (can.ui.zone && can.ui.zone.source) {
can.page.isDisplay(can.ui.zone.source._target) || can.ui.zone.source._legend.click()
}
return true
}
},
tabview: function(can, path, file, line, cb) { path = path||can.Option(nfs.PATH), line && can.Option(nfs.LINE, line); var key = can.onexport.keys(can, path, file)
function isIndex() { return line == ctx.INDEX } function isSpace() { return line == web.SPACE }
function show() { can._msg && can._msg.Option && can._msg.Option(nfs.LINE, can.Option(nfs.LINE)), can._msg = can.db.tabview[key]
can.Option(can.onimport.history(can, {path: path, file: file, line: can._msg.Option(nfs.LINE)||can.onexport.session(can, SELECT_LINE+nfs.DF+path+file)||1}))
can.onsyntax._init(can, can._msg, function(content) { var msg = can._msg; can.onexport.hash(can)
can.onexport.title(can, isIndex()||isSpace()? file: file.split("/").slice(-2).join("/"))
can.onmotion.select(can, can.ui._tabs, html.DIV_TABS, msg._tab), can.onmotion.toggle(can, can.ui.path, true)
if (isSpace()) { can.base.contains(file, "/") || can.onmotion.hidden(can, can.ui.path)
can.ui.path.innerHTML = can.page.Format(html.A, can.base.trimPrefix(can.misc.MergePodCmd(can, {pod: file}), location.origin))
} else if (isIndex()) { can.onmotion.hidden(can, can.ui.path)
} else { can.onimport.__tabPath(can) }
can.page.Select(can, can.ui.content.parentNode, "div.scrollbar", function(target) { can.page.style(can, target, "visibility", "hidden") })
can.page.SelectChild(can, can.ui._content.parentNode, can.page.Keys(html.DIV_CONTENT, html.DIV_LAYOUT, html.FIELDSET_STORY, [[[html.IFRAME, html.CONTENT]]]), function(target) {
can.onmotion.toggle(can, target, target == content)
}), can.ui.content._plugin = msg._plugin
can.page.SelectChild(can, can.ui._profile.parentNode, can.page.Keys(html.DIV_PROFILE, [[[html.IFRAME, html.PROFILE]]]), function(target) {
if (target == msg._profile) { can.ui.profile = msg._profile, msg._profile_hidden || can.onmotion.toggle(can, target, true) }
}), can.ui.profile._plugin = msg._profile
can.page.ClassList.set(can, can._output, nfs.SOURCE, can.onimport.openzone(can, path, file, line)), can.onimport.layout(can)
can.onaction.selectLine(can, can.Option(nfs.LINE)), can.base.isFunc(cb) && cb(msg), cb = null
var ls = can.onexport.path(can).split(nfs.PS); if (ls.length > 4) { ls = [ls.slice(0, 2).join(nfs.PS)+"/.../"+ls.slice(-2).join(nfs.PS)] } can.Status(kit.Dict(nfs.FILE, ls.join(nfs.PS)))
})
}
function load(msg) { can.db.tabview[key] = msg; var name = file
msg.result = msg.result||[""]
if (can.base.beginWith(file, web.HTTP)) { name = decodeURI(file.split(web.QS)[0])
var link = can.misc.ParseURL(can, name); if (link.pod) { name = link.pod }
name = can.base.trimPrefix(name, location.origin)
} else {
name = file.split(mdb.FS)[0].split(isIndex()? nfs.PT: nfs.PS).pop()
}
line && msg.Option(nfs.LINE, line)
var tabs = can.onimport.tabs(can, [{name: name, text: (isIndex() || isSpace()? "": path)+file, _menu: shy(can.base.Obj(msg.Option(ice.MSG_ACTION), []), function(event, button, meta) {
can.request(event, msg), can.onaction[button]? can.onaction[button](event, can, button): can.onaction._runs(event, can, button)
})}], function(event, tabs) {
can._tab = msg._tab = tabs._target, show(), msg._item && (can.page.isSelect(msg._item) || msg._item.click(), can.onmotion.scrollIntoView(can, msg._item))
}, function(tabs) { can.onengine.signal(can, VIEW_REMOVE, msg), delete(can.db.tabview[key])
msg._content != can.ui._content && can.page.Remove(can, msg._content), msg._profile != can.ui._profile && can.page.Remove(can, msg._profile)
can.onmotion.cacheClear(can, key, can.ui._content, can.ui._profile, can.ui._display)
}, can.ui._tabs)
}
can._msg._tab && can.onmotion.scrollIntoView(can, can._msg._tab)
if (can.db.tabview[key]) { return can.isSimpleMode()? show(): can._msg._tab? (can._msg._tab.click(), show()): load(can.db.tabview[key]) }
isIndex()||isSpace()? load(can.request({}, {index: file, line: line})): can.run({}, [path, file], load, true)
},
history: function(can, record) { can.base.Eq(record, can.db.history[can.db.history.length-1], mdb.TEXT) || can.db.history.push(record)
return can.Status(ice.BACK, can.db.history.length), record
},
project: function(can) { can.onimport.zone(can, can.core.Item(can.onfigure, function(name, cb) { if (can.base.isFunc(cb)) {
return {name: name, _toggle: function(zone) { var target = can.page.isDisplay(zone._target)? zone._target: can.ui.zone.source._target
can.core.Item(can.ui.zone, function(key, zone) { key.indexOf(nfs.PS) > 0 || zone.toggle(zone._target == target) }), can.onimport.layout(can)
}, _init: function(target, zone) { var onclick = zone._legend.onclick
zone._legend.onclick = function(event) { if (can.page.isDisplay(zone._target)) { return } onclick(event) }
return cb(can, target, zone, can.db.hash)
}}
} }), can.ui.project) },
profile: function(can, msg) { var _msg = can.db.tabview[can.onexport.keys(can)]; _msg.Option(html.WIDTH, msg.Option(html.WIDTH)), border = 1
var height = can.ui.content.offsetHeight, width = can.onexport.size(can, _msg.Option(html.WIDTH)||0.5, can.ConfWidth()-can.ui.project.offsetWidth)+border
if (msg.Result().indexOf("<iframe src=") > -1) { if (_msg._profile != can.ui._profile) { can.page.Remove(can, _msg._profile) }
var src = can.page.Select(can, can.page.Create(can, html.DIV, msg.Result()), html.IFRAME, function(target) { return target.src })[0]
can.ui.profile = _msg._profile = can.page.Append(can, can.ui._profile.parentNode, [{view: [html.PROFILE, html.IFRAME], src: src, style: {height: height, width: width}}])._target
can.onmotion.toggle(can, can.ui.profile, true), can.onmotion.delay(can, function() { can.onimport.layout(can)})
} else {
can.page.style(can, can.ui.profile, html.HEIGHT, height, html.WIDTH, width, html.FLEX, "0 0 "+width+"px"), can.ui.profile = _msg._profile = can.ui._profile
if (can.ui.profile._plugin && can.base.isIn(msg.Append(ctx.INDEX), web.CODE_XTERM)) {
if (can.onexport.session(can, PROFILE_ARGS+can.Option(nfs.PATH)+can.Option(nfs.FILE))) {
return can.onmotion.toggle(can, can.ui.profile, true), can.onimport.layout(can)
}
}
can.onimport.process(can, msg, can.ui.profile, height, width-border, function(sub) {
_msg._profile_plugin = sub
can.ui.profile._plugin = sub, can.page.style(can, sub._output, html.MAX_WIDTH, "")
sub.onaction.close = function() { can._msg._profile_hidden = true
can.onexport.session(can, PROFILE_ARGS+can.Option(nfs.PATH)+can.Option(nfs.FILE), "")
can.onmotion.hidden(can, can.ui.profile), can.onimport.layout(can)
}
sub.Conf(ctx.ARGS) && can.onexport.session(can, PROFILE_ARGS+can.Option(nfs.PATH)+can.Option(nfs.FILE), JSON.stringify(sub.Conf(ctx.ARGS)))
can.page.style(can, can.ui.profile, html.WIDTH, width+border, html.MAX_WIDTH, width+border), can.onimport.layout(can)
})
}
},
display: function(can, msg) { var _msg = can.db.tabview[can.onexport.keys(can)], border = 1; can.ui.display = _msg._display = can.ui._display
var height = can.onexport.size(can, 0.5, can.ui.project.offsetHeight||can.ConfHeight()), width = can.ConfWidth()-can.ui.project.offsetWidth
can.onimport.process(can, msg, can.ui.display, height-border, width, function(sub) { can.ui.display._plugin = _msg._display = sub
sub.onaction.close = function() { can.onmotion.hidden(can, can.ui.display), can.onimport.layout(can) }
sub.onimport.size(sub, height-border, width, true), can.onimport.layout(can)
})
},
process: function(can, msg, target, height, width, cb) { can.onmotion.clear(can, target)
if (msg.Option(ice.MSG_PROCESS) == ice.PROCESS_FIELD) {
msg.Table(function(item) { item.type = chat.STORY, item.height = height, item.width = width
item.display = msg.Option(ice.MSG_DISPLAY)
item.display_css = msg.Option(ice.MSG_DISPLAY_CSS)
if (can.base.isIn(item.index, web.WIKI_WORD)) { item.style = html.OUTPUT }
can.onimport.plug(can, item, function(sub) {
sub.onaction.close = function() { can.onmotion.hidden(can, target), can.onimport.layout(can) }
sub.onexport.output = function(_sub, _msg) { can.base.isFunc(cb) && cb(_sub.sup, _msg) }
}, target)
})
} else if (msg.Option(ice.MSG_DISPLAY) != "") {
can.onappend._output(can, msg, msg.Option(ice.MSG_DISPLAY), function(msg) { can.onimport.layout(can) }, target)
} else if (msg.Result().indexOf("<iframe src=") > -1) {
var src = can.page.Select(can, can.page.Create(can, html.DIV, msg.Result()), html.IFRAME, function(target) { return target.src })[0]
can.page.Append(can, target, [{type: html.IFRAME, src: src, style: {height: height, width: width}}])
} else if (msg.Length() > 0 || msg.Result() != "") {
can.onappend.table(can, msg, function(value, key, index, item) { return {text: [value, html.TD], onclick: function(event) {
if (event.target.type == html.BUTTON) { return can.runAction(can.request(event, item), event.target.name, [], function() {}) }
item.file && can.onimport.tabview(can, item.path, item.file||can.Option(nfs.FILE), item.line)
}} }, target), can.onappend.board(can, msg, target), msg.Option(ice.MSG_STATUS) && can.onappend._status(can, msg.Option(ice.MSG_STATUS), can.page.Append(can, target, [html.STATUS])._target)
} else {
return can.onmotion.toggle(can, target, false), can.onimport.layout(can), can.user.toastFailure(can, "nothing to display")
} return can.onmotion.toggle(can, target, true), can.onimport.layout(can)
},
toolkit: function(can, meta, cb) { can.base.isString(meta) && (meta = {index: meta})
var key = [meta.index].concat(meta.args).join(","), sub = can.db.toolkit[key]; if (sub) { sub.select(); return }
can.onimport.tool(can, [meta], function(sub) { can.db.toolkit[key] = sub
sub.onimport.size(sub, can.base.Max(can.ConfHeight()/2, can.ConfHeight(), 420), can.base.Max(can.ConfWidth()/2, can.ui.content.offsetWidth, html.PLUG_WIDTH), false)
sub.onexport.output = function() {
sub.onimport.size(sub, can.base.Max(can.ConfHeight()/2, can.ConfHeight(), 420), can.base.Max(can.ConfWidth()/2, can.ui.content.offsetWidth, html.PLUG_WIDTH), false)
}
sub.onaction._close = function() { delete(can.db.toolkit[key]), can.page.Remove(can, sub._target), can.page.Remove(can, sub._legend) }
sub.onexport.record = function(sub, value, key, data) { if (!data.file) { return }
can.onimport.tabview(can, data.path, can.base.trimPrefix(data.file, nfs.PWD), parseInt(data.line)); return true
}, meta.index != ice.CAN_PLUGIN && (sub._legend._list = {index: meta.index, args: meta.args}), cb && cb(sub)
}, can.ui.plug.parentNode, can.ui.plug)
},
exts: function(can, url, cb) { var sub = can.db.toolkit[url.split(web.QS)[0]]; if (sub) { return can.base.isFunc(cb)? cb(sub): sub.select() }
can.onimport.toolkit(can, {
icon: "bi bi-search",
index: ice.CAN_PLUGIN, style: url.split(nfs.PS).pop().split(nfs.PT)[0],
display: (url[0] == nfs.PS || url.indexOf(web.HTTP) == 0? "": can.base.Dir(can._path))+url,
}, function(sub) { can.db.toolkit[url.split(web.QS)[0]] = sub
sub.run = function(event, cmds, cb) {
if (cmds.length > 0 && cmds[0] == ctx.ACTION) {
can.run(can.request(event, can.Option()), cmds, cb||function(msg) { can.onappend._output(sub, msg, sub.Conf(ctx.DISPLAY)) })
} else { can.onappend._output(sub, can.request(event), sub.Conf(ctx.DISPLAY)) }
}, can.base.isFunc(cb)? cb(sub): sub.select(), can.page.Modify(can, sub._legend, can.base.trimPrefix(url, "inner/"))
})
},
grow: function(can, msg, arg) { can.onimport.exts(can, "inner/output.js", function(sub) { sub.Conf(ctx.INDEX, can.ConfIndex())
sub.select(true), can.onmotion.delay(can, function() {
can.page.Append(can, sub._output, [{text: arg}]), sub._output.scrollTop = sub._output.scrollHeight
can.misc.sessionStorage(can, [can.ConfIndex(), html.OUTPUT], sub._output.innerHTML)
})
}) },
layout: function(can) {
if (can.Conf(ctx.STYLE) == html.OUTPUT) { return can.page.style(can, can.ui.content, html.WIDTH, (can.Conf("__width")||can.ConfWidth())-(can.user.isMobile? 4: 2)) }
if (can.isSimpleMode() && !can.page.tagis(can._fields, html.FIELDSET_FLOAT)) { can.page.style(can, can._output, html.MAX_HEIGHT, "") }
if (can.isSimpleMode()) { can.ui.layout(can.ConfHeight(), can.ConfWidth()); return can.page.style(can, can.ui.content, html.WIDTH, can.ConfWidth()) }
if (can.isCmdMode()) { can.page.style(can, can._output, html.HEIGHT, can.ConfHeight(can.page.height())) }
can.ui.size = {profile: can._msg.Option(html.WIDTH), display: can._msg.Option(html.HEIGHT)}
can.ui.layout(can.ConfHeight(), can.ConfWidth(), 0, function(height, width) {
var sub = can._msg._profile_plugin; sub && can.page.isDisplay(can.ui.profile) && sub.onimport && sub.onimport.size(sub, can.ui.profile.offsetHeight, can.ui.profile.offsetWidth-1, false)
var sub = can.ui.content._plugin; if (!sub) { return } if (height == sub.ConfHeight()+sub.onexport.actionHeight(sub)+sub.onexport.statusHeight(sub) && width == sub.ConfWidth()) { return }
sub.onimport.size(sub, height, width, false), can.page.style(can, sub._target, html.HEIGHT, height)
})
can.page.SelectChild(can, can.ui.project, html.DIV_ZONE, function(target, index, list) {
can.page.SelectChild(can, target, html.DIV_ITEM, function(target) { var height = can.ui.project.offsetHeight - list.length*target.offsetHeight
if (can.page.tagis(target.nextSibling, html.DIV_ACTION)) { height -= target.nextSibling.offsetHeight }
can.page.SelectChild(can, target.parentNode, html.DIV_LIST, function(target) { can.page.style(can, target, html.HEIGHT, height) })
})
})
},
}, [""]) }, [""])
Volcanos("onsyntax", {help: "语法高亮", list: ["keyword", "prefix", "line"], _init: function(can, msg) { Volcanos(chat.ONFIGURE, {
// caches save source: function(can, target, zone, hash) {
can.file && can.core.List([chat.CONTENT, chat.PROFILE, chat.OUTPUT], function(item) { can.page.Cache(can.file, can.ui[item], { function show(target, zone, path) { can.run(can.request({}, {dir_root: path, dir_deep: true}), [nfs.PWD], function(msg) {
scrollTop: can.ui.content.scrollTop, current: can.current, max: can.max, can.onimport.tree(can, can.core.List(msg.Table(), function(item) { item._init = function(target) { can.ui.zone.source[path+item.path] = target }
}) }) if (can.Option(nfs.FILE).indexOf(item.path) == 0) { item.expand = true } return item
}), function(event, item, target) { can.base.endWith(item.path, nfs.PS) || can.onimport.tabview(can, path, item.path, "", function(msg) {
can.file = can.base.Path(msg.Option(nfs.PATH), msg.Option(nfs.FILE)) msg._item = target
can.parse = can.base.Ext(can.file) }) }, function() {}, target), zone._total(msg.Length())
can.Status("模式", "normal") can.isCmdMode() && hash.length > 1 && can.onimport.tabview(can, hash[0], hash[1], hash[2])
}, true) } show(target, zone, can.Option(nfs.PATH))
// caches load },
can.onmotion.select(can, can._action, "div.file", msg._tab) command: function(can, target, zone, hash) {
var cache = false; can.core.List([chat.CONTENT, chat.PROFILE, chat.OUTPUT], function(item) { zone._delay_init = function() { can.runAction({}, mdb.INPUTS, [ctx.INDEX], function(msg) {
var p = can.page.Cache(can.file, can.ui[item]); if (p != undefined && !cache) { cache = true can.onimport.tree(can, msg.Table(function(value) {
can.onaction.selectLine(can, parseInt(msg.Option(nfs.LINE))) value.expand = hash[2] == ctx.INDEX && hash[1] == value.index
can.ui.content.scrollTo(0, p.scrollTop) return value
can.max = p.max }), function(event, item, target) { can.onimport.tabview(can, "", item.index, ctx.INDEX, function(msg) {
} msg._item = target
}); if (cache) { return } }) }, function() {}, target, null, ctx.INDEX, nfs.PT), zone._total(msg.Length())
}) }, zone.toggle(false)
function init(p) { can.max = 0 },
can.core.List(can.ls = msg.Result().split(ice.NL), function(item) { plugin: function(can, target, zone, hash) { zone._delay_init = function() { var total = 0
can.onaction.appendLine(can, item) can.onimport.tree(can, can.core.ItemKeys(can.onengine.plugin.meta, function(key) { if (key[0] != "_") {
}), can.onaction.selectLine(can, msg.Option(nfs.LINE)||1) return total++, {index: key, expand: hash[2] == ctx.INDEX && hash[1] == "can."+key}
} } }), function(event, item, target) { can.onimport.tabview(can, "", can.core.Keys(ice.CAN, item.index), ctx.INDEX, function(msg) {
msg._item = target
// plugin }) }, function() {}, target, null, ctx.INDEX, nfs.PT), zone._total(total)
var p = can.onsyntax[can.parse]; !p? can.run({}, [ctx.ACTION, mdb.PLUGIN, can.parse, msg.Option(nfs.FILE), msg.Option(nfs.PATH)], function(msg) { }, zone.toggle(false) },
init(p = can.onsyntax[can.parse] = can.base.Obj(msg.Result()))
}, true): init(p)
},
_parse: function(can, line) { line = line||"", line = line.replace("<", "&lt;").replace(">", "&gt;")
var p = can.onsyntax[can.parse]; if (!p) { return line }
p = can.onsyntax[p.link]||p
function wrap(type, str) { return type? '<span class="'+type+'">'+str+'</span>': str }
p.keyword && (line = can.core.List(can.core.Split(line, p.split && p.split.space||ice.SP, p.split && p.split.operator || "{[(|)]}", {detail: true}), function(item, index, array) {
item = can.base.isObject(item)? item: {text: item}, p.word && (item = p.word(item, index, array))
var text = item.text; var key = item.keyword||p.keyword[text]
switch (item.type) { case "space": return text
case lang.STRING: return wrap(lang.STRING, item.left+text+item.right)
default: return wrap(key, text)
}
}).join(""))
p.prefix && can.core.Item(p.prefix, function(pre, type) {
if (line.trim().indexOf(pre) == 0) {
line = wrap(type, line)
} else {
var ls = line.split(pre); if (ls.length > 1) {
line = ls[0] + wrap(type, pre + ls[1])
}
}
})
p.suffix && can.core.Item(p.suffix, function(pre, type) {
if (line.endsWith(pre)) { line = wrap(type, line) }
})
return p.line? p.line(can, line): line
},
}) })
Volcanos("onaction", {help: "控件交互", list: ["项目", "收藏"], Volcanos(chat.ONSYNTAX, {
"back": function(event, can) { _init: function(can, msg, cb) { var key = can.onexport.keys(can)
var last = can.history.pop(); last = can.history.pop() can.onmotion.cache(can, function() { return key }, can.ui.profile, can.ui.display), can.onmotion.hidden(can, can.ui.profile), can.onmotion.hidden(can, can.ui.display)
last && can.onimport.tabview(can, last.path, last.file, last.line) if (msg._content) { return cb(can.ui.content = msg._content) }
can.Status("跳转数", can.history.length) if (msg.Option(ctx.INDEX)) { return can.onsyntax._index(can, msg, function(target) { cb(can.ui.content = msg._content = target) }, can.ui._content.parentNode) }
}, can.onsyntax._split(can, msg, cb, key)
"项目": function(event, can) { },
var width = can.Conf(html.WIDTH)-(can.onmotion.toggle(can, can.ui.project)? 170: 0) _space: function(can, msg, cb, parent) { if (can.Option(nfs.LINE) == web.SPACE) {
}, // can.ui.zone.space && can.onmotion.delay(can, function() { can.ui.zone.space.refresh() }, 3000)
"收藏": function(event, can) { can.onmotion.toggle(can, can.ui.favor._target) }, var target = can.page.Append(can, parent, [{view: [html.CONTENT, html.IFRAME], src: can.misc.MergePodCmd(can, {pod: can.Option(nfs.FILE)}), height: can.ui.content.offsetHeight, width: can.ui.content.offsetWidth}])._target
"搜索": function(event, can) { can.onmotion.toggle(can, can.ui.search) }, return can.base.isFunc(cb) && cb(target), true
"exec": function(event, can) { var msg = can.request(event, {_toast: "运行中..."}) } },
can.run(event, [ctx.ACTION, mdb.ENGINE, can.parse, can.Option(nfs.FILE), can.Option(nfs.PATH)], function(msg) { _index: function(can, msg, cb, parent) { if (can.onsyntax._space(can, msg, cb, parent)) { return }
can.onappend.table(can, msg, null, can.ui.output||can.ui.display) var index = can.core.Split(msg.Option(ctx.INDEX)), item = {type: chat.STORY, index: index[0], args: index.slice(1)}
can.onappend.board(can, msg.Result(), can.ui.output||can.ui.display) if (item.index == web.CODE_XTERM && item.args.length > 0) { item.style = html.OUTPUT }
can.page.Modify(can, can.ui.display, {style: {display: html.BLOCK}}) if (item.index == web.CHAT_MACOS_DESKTOP) { item.style = html.OUTPUT }
}, true) can.onimport.plug(can, item, function(sub) {
}, sub.onimport._open = function(_, msg, arg) { var link = can.misc.ParseURL(can, arg)
if (link.pod && arg.indexOf(location.origin) == 0) { can.onimport.tabview(can, "", link.pod, web.SPACE), sub.Update(); return }
appendLine: function(can, value) { can.onimport.tabview(can, "", arg, web.SPACE), sub.Update()
var ui = can.page.Append(can, can.ui.content, [{type: html.TR, list: [ }
{view: ["line unselectable", html.TD, ++can.max], onclick: function(event) { sub.onaction.close = function() { msg._tab._close() }
can.onaction.selectLine(can, ui.tr) sub.onexport.output = function() { can.onimport.layout(can) }
sub.onexport.record = function(_, value, key, item) { item.file && can.onimport.tabview(can, item.path, item.file, item.line); return true }
}, ondblclick: function(event) { sub.onexport.title = function(_, title) { can.page.Modify(can, can.page.SelectOne(can, msg._tab, html.SPAN_NAME), title) }
can.onaction.favorLine(can, ui.text.innerText) sub.onimport.size(sub, can.ui.content.offsetHeight, can.ui.content.offsetWidth, false)
}}, msg._plugin = sub, can.base.isFunc(cb) && cb(sub._target), sub.Focus()
{view: [html.TEXT, html.TD], list: [can.onsyntax._parse(can, value)], onclick: function(event) { }, parent)
can.onaction._selectLine(can, ui) },
_split: function(can, msg, cb, key) {
}, ondblclick: function(event) { function show(p) {
can.onaction._searchLine(can, ui) function include(list) { if (!list || list.length == 0) { return }
}} can.core.List(list, function(from) { p.split = p.split||can.onsyntax[from].split
]}]); return ui.tr p.keyword = p.keyword||{}, can.core.Item(can.onsyntax[from].keyword, function(key, value) { p.keyword[key] = p.keyword[key]||value })
}, can.core.Item(can.onsyntax[from], function(key, value) { p[key] = p[key]||value }), include(can.onsyntax[from].include)
modifyLine: function(can, line, value) { })
can.page.Select(can, can.ui.content, html.TR, function(item, index) { } p && include(p.include), p && p.prepare && can.core.ItemForm(p.prepare, function(value, index, key) { p.keyword = p.keyword||{}, p.keyword[value] = key })
if (item != line && index+1 != line) { return } if (can.db.history.length > 1) { can.ui.content = can.page.insertBefore(can, [{view: html.CONTENT, style: {width: can.ui.content.offsetWidth}}], can.ui._content), can.ui.content._cache_key = key }
can.ui.content._max = 0, can.ui.content._msg = msg, can.page.Appends(can, can.ui.content, [{view: ["tips", "", msg.Option(nfs.FILE).split(nfs.PS).slice(-2).join(nfs.PS)]}])
can.page.Select(can, item, "td.text", function(item) { if (msg.Length() > 0) { can.onsyntax._change(can, msg), can.onaction.rerankLine(can, "tr.line:not(.delete)>td.line")
can.page.Appends(can, item, [can.onsyntax._parse(can, value)]) can.page.Select(can, can.ui.content, "tr.line.delete>td.line", function(target) { target.innerHTML = "" })
}) } else {
}) can.core.List(msg.Result().split(lex.NL), function(item) { can.onaction.appendLine(can, item) })
}, }
rerankLine: function(can, value) { can.max = 0 can.onengine.signal(can, VIEW_CREATE, msg), can.base.isFunc(cb) && cb(msg._content = can.ui.content)
can.page.Select(can, can.ui.content, html.TR, function(item, index) { can.onmotion.delay(can, function() { can.onappend.scroll(can) })
can.max++, can.page.Select(can, item, "td.line", function(item) { }
item.innerText = index+1 can.require([chat.PLUGIN_LOCAL+"code/inner/syntax.js"], function() { var parse = can.onexport.parse(can); can.Conf(chat.PLUG) && (can.onsyntax[parse] = can.Conf(chat.PLUG))
}) var p = can.onsyntax[parse]; !p && msg.Option(nfs.FILE)? can.runAction({}, mdb.PLUGIN, [parse, msg.Option(nfs.FILE), msg.Option(nfs.PATH)], function(msg) { p = can.base.Obj(msg.Result())
}) p && p.script? can.require([p.script], function() { show(can.onsyntax[msg.Option(lex.PARSE)||parse]) }): show(can.onsyntax[parse] = p)
}, }): show(p)
selectLine: function(can, line) { if (!line) { return } })
can.page.Select(can, can.ui.content, html.TR, function(item, index) { },
can.page.ClassList.del(can, item, html.SELECT) _parse: function(can, line) { var parse = can.onexport.parse(can)
if (item != line && index+1 != line) { return } function wrap(text, type) { return can.page.Format(html.SPAN, can.page.trans(can, text), type) }
can.page.ClassList.add(can, item, html.SELECT) var p = can.onsyntax[parse]; if (!p) { return can.page.trans(can, line) } p = can.onsyntax[p.link]||p, p.split = p.split||{}, p.keyword = p.keyword||{}
if (p.prefix && can.core.Item(p.prefix, function(pre, type) { if (can.base.beginWith(line, pre)) { return line = wrap(line, type) } }).length > 0) { return line }
line = item if (p.suffix && can.core.Item(p.suffix, function(end, type) { if (can.base.endWith(line, end)) { return line = wrap(line, type) } }).length > 0) { return line }
can.Option(nfs.LINE, index+1) if (p.parse) { var text = p.parse(can, line, wrap); if (text != undefined) { return text } }
can.Status("文件名", can.file) if (!p.keyword) { return line }
can.Status("解析器", can.parse) line = can.core.List(can.core.Split(line, p.split.space||"\t ", p.split.operator||"{[(.,:;!?|$@&*+-<=>)]}", {detail: true}), function(item, index, array) {
can.Status("当前行", can.onexport.position(can, index+1)) item = can.base.isObject(item)? item: {text: item}; var text = item.text, type = p.keyword[text]
}) switch (item.type||type) {
case code.STRING: return wrap(item.left+text+item.right, code.STRING)
can.base.isObject(line) && can.page.Select(can, line, "td.text", function(item) { case code.COMMENT:
can.current = { case code.KEYWORD:
scroll: function(x, y) { case code.PACKAGE:
can.ui.content.scrollLeft += x case code.DATATYPE:
can.ui.content.scrollTop += y case code.FUNCTION:
// return can.ui.content.scrollBy(x, y) case code.CONSTANT:
}, case code.OBJECT: return wrap(text, type)
window: function() { return can.ui.content.offsetHeight }, default: var t = can.core.Item(p.regexp, function(reg, type) { var m = text.match(new RegExp(reg)); if (m && m.length > 0 && m[0] == text) { return type} })
offset: function() { return can.ui.content.scrollTop }, return t && t.length > 0? wrap(text, t[0]): type? wrap(text, type): wrap(text, "_")
}
prev: function() { return line.previousSibling }, }).join(""); return line
next: function() { return line.nextSibling }, },
line: line, text: function(text) { _change: function(can, msg) { var _delete = [], _insert = [], deletes = [], inserts = []
return text != undefined && can.onaction.modifyLine(can, line, text), item.innerText function scroll(item, type, length, index) {
}, height: function() { return line.offsetHeight }, var tr = can.onaction.appendLine(can, item); can.onappend.style(can, type, tr); if (index > 0) { return }
} var line = can.onexport.line(can, tr)||can.onexport.line(can, tr.previousSibling)
can.onmotion.delay(can, function() {
var push = {path: can.Option(nfs.PATH), file: can.Option(nfs.FILE), line: can.Option(nfs.LINE)} // var bar = can.onappend.scroll(can, can.ui.content, line/can.ui.content._max, length/can.ui.content._max); can.onappend.style(can, type, bar)
can.base.Eq({path: push.path, file: push.file}, can.history[can.history.length-1]) || can.history.push(push) // bar && (bar.onclick = function() { can.onimport.tabview(can, "", can.Option(nfs.FILE), line) })
can.Status("跳转数", can.history.length) })
}) }
function append() { var rest = []
if (can.current) { var offline = 5 while (deletes.length > 0 && inserts.length > 0 && deletes[0] == inserts[0]) { can.onaction.appendLine(can, deletes[0]), deletes = deletes.slice(1), inserts = inserts.slice(1) }
var pos = can.current.line.offsetTop-can.current.offset() while (deletes.length > 0 && inserts.length > 0 && deletes[deletes.length-1] == inserts[inserts.length-1]) { can.onaction.appendLine(can, deletes[deletes.length-1]), deletes.pop(), inserts.pop() }
if (pos > can.current.window()-offline*20) { while (deletes.length > 0 && inserts.length > 0 && deletes[0] == inserts[inserts.length-1]) { rest.push(deletes[0]), deletes = deletes.slice(1), inserts.pop() }
can.current.scroll(0, pos-can.current.window()+offline*20) can.core.List(deletes, function(item, index, list) { scroll(item, mdb.DELETE, list.length, index) }), deletes = []
} else if (pos < offline*20) { can.core.List(inserts, function(item, index, list) { scroll(item, mdb.INSERT, list.length, index) }), inserts = []
can.current.scroll(0, pos-offline*20) can.core.List(rest, function(item) { can.onaction.appendLine(can, item) })
} }
} can.onkeymap && can.onkeymap.selectLine(can) msg.Table(function(value) { can.core.List(value.text.split(lex.NL), function(item, index, list) {
}, if (index == list.length-1 && !can.base.endWith(value.text, lex.NL)) {
searchLine: function(event, can, value) { value = value.trim() if (value.type == mdb.DELETE) { _delete.push(item) } else if (value.type == mdb.INSERT) { _insert.push(item) } else { _delete.push(item), _insert.push(item) }
can.page.Modify(can, can.ui.search, {style: {display: ""}}) } else if (value.type == mdb.DELETE) {
value = can.ui.word.value = value||can.ui.word.value||"main" _delete.push(item), deletes.push(_delete.join("")), _delete = []
} else if (value.type == mdb.INSERT) {
can.request(event, {_toast: "搜索中..."}) _insert.push(item), inserts.push(_insert.join("")), _insert = []
can.run(event, [ctx.ACTION, mdb.SEARCH, can.parse, value, can.Option(nfs.PATH)], function(msg) { } else if (_delete.length > 0 || _insert.length > 0) {
can.onmotion.clear(can, can.ui.tags) _delete.push(item), _insert.push(item), deletes.push(_delete.join("")), _delete = [], inserts.push(_insert.join("")), _insert = []
can.onappend.table(can, msg, function(value, key, index, line) { } else { append(), can.onaction.appendLine(can, item) }
value = value.replace("<", "&lt;").replace(">", "&gt;"), value = value.replace("./", "") }) }), _delete.length > 0 && deletes.push(_delete.join("")), _insert.length > 0 && inserts.push(_insert.join("")), append()
var list = can.page.Select(can, can.ui.content, "tr.insert,tr.delete")
return {text: ["", html.TD], list: [{text: [value, html.DIV]}], onclick: function(event) { list && list[0] && can.onmotion.delay(can, function() { can.onimport.tabview(can, "", can.Option(nfs.FILE), can.onexport.line(can, list[0].previousSibling)) })
line.line && can.onimport.tabview(can, can.Option(nfs.PATH), line.file.replace("./", ""), parseInt(line.line), function() { },
can.onaction.selectLine(can, line.line)
})
}}
}, can.ui.tags), can.Status("标签数", msg.Length())
}, true)
},
_searchLine: function(can, ui) {
var s = document.getSelection().toString()
var str = ui.text.innerText
var begin = str.indexOf(s)
var end = begin+s.length
for (var i = begin; i >= 0; i--) {
if (str[i].match(/[a-zA-Z0-9_.]/)) {
s = str.slice(i, end)
} else {
break
}
}
if (s.indexOf("kit.") == 0) { s = s.replace("kit.", "toolkits.") }
if (s.indexOf(".") == 0) { s = s.slice(1) }
can.onaction.searchLine(event, can, s)
},
_selectLine: function(can, ui) {
can.onkeymap && can.onkeymap._mode(can, "insert")
can.onaction.selectLine(can, ui.tr)
},
favorLine: function(can, value) {
can.user.input(event, can, [
{name: "zone", value: "hi"},
{name: "name", value: "hello"},
], function(event, button, meta, list) {
can.run(event, [ctx.ACTION, code.FAVOR,
ctx.ACTION, mdb.INSERT, mdb.ZONE, meta.zone||"",
mdb.TYPE, can.parse, mdb.NAME, meta.name||"", mdb.TEXT, (value||"").trimRight(),
nfs.PATH, can.Option(nfs.PATH), nfs.FILE, can.Option(nfs.FILE), nfs.LINE, can.Option(nfs.LINE),
], function(msg) {
can.user.toastSuccess(can)
}, true)
})
},
EnableDrop: function(can, parent, search, target) {
return can.page.Modify(can, target, { draggable: true,
ondragstart: function(event) { var target = event.target; can.drop = function(event, tab) {
parent.insertBefore(target, tab)
can.page.Select(can, parent, search, function(item) {
can.page.ClassList.del(can, item, "over")
})
} },
ondragover: function(event) { event.preventDefault()
can.page.Select(can, parent, search, function(item) {
can.page.ClassList.del(can, item, "over")
}), can.page.ClassList.add(can, event.target, "over")
},
ondrop: function(event) { event.preventDefault()
can.drop(event, event.target)
},
})
},
}) })
Volcanos("onexport", {help: "导出数据", list: ["文件数", "解析器", "文件名", "当前行", "跳转数", "标签数"], Volcanos(chat.ONACTION, {
position: function(can, index, total) { total = total || can.max _getLine: function(can, line) { return can.page.Select(can, can.ui.content, "tr.line>td.line", function(td, index) { if (td.parentNode == line || index+1 == line) { return td.parentNode } })[0] },
return (parseInt(index))+ice.PS+parseInt(total)+" = "+parseInt((index)*100/total)+"%" _getContent: function(can, line) { can.onimport.__tabPath(can) },
}, appendLine: function(can, value, target) { var ui = can.page.Append(can, target||can.ui.content, [{view: [nfs.LINE, html.TR], list: [
content: function(can) { {view: [nfs.LINE, html.TD, ++can.ui.content._max], onclick: function(event) {
return can.page.Select(can, can.ui.content, "td.text", function(item) { can.onaction.selectLine(can, ui.tr), can.onaction._getContent(can, ui._target)
return item.innerText }, ondblclick: function(event) { can.onaction.find(event, can) }},
}).join(ice.NL)+ice.NL {view: [mdb.TEXT, html.TD, can.onsyntax._parse(can, value)], onclick: function(event) {
}, can.onaction.selectLine(can, ui.tr), can.onkeymap._insert && can.onkeymap._insert(event, can, 0, (event.offsetX)/8.5), can.onaction._getContent(can, ui._target)
}, ondblclick: function(event) { can.onaction.searchLine(event, can, can.onexport.selection(can, ui.text.innerText)) }}
]}]); return ui._target },
rerankLine: function(can, which, target) { can.ui.content._max = can.page.Select(can, target||can.ui.content, which||"tr.line:not(.delete)>td.line", function(td, index) { return td.innerText = index+1 }).length },
modifyLine: function(can, line, value) { can.page.Select(can, can.onaction._getLine(can, line), "td.text", function(td) { td.innerHTML = can.onsyntax._parse(can, value) }) },
selectLine: function(can, line, scroll) { var content = can.ui.content; if (!line) { return can.onexport.line(can, can.page.SelectOne(can, content, "tr.select")) }
can.page.Select(can, content, "tr.line>td.line", function(target) { var n = parseInt(target.innerText); target = target.parentNode
if (!can.page.ClassList.set(can, target, html.SELECT, n == line || target == line)) { return }
line = target, can.Status(nfs.LINE, can.onexport.position(can, can.Option(nfs.LINE, n)))
}); if (!can.base.isObject(line)) { return 0 }
can.page.Select(can, line, "td.text", function(target) {
can.current = {line: line,
next: function() { return can.page.tagis(line.nextSibling, "tr.line")? line.nextSibling: undefined },
prev: function() { return can.page.tagis(line.previousSibling, "tr.line")? line.previousSibling: undefined },
text: function(text) { return text != undefined && can.onaction.modifyLine(can, line, text), target.innerText },
scroll: function(count) { if (count) { content.scrollTop += count*can.current.line.offsetHeight }
return parseFloat((can.current.line.offsetTop-content.scrollTop)/can.current.line.offsetHeight)
}, window: function() { return parseFloat(content.offsetHeight/can.current.line.offsetHeight) },
}, can.onimport.history(can, {path: can.Option(nfs.PATH), file: can.Option(nfs.FILE), line: can.Option(nfs.LINE), text: can.current.text()})
var _scroll = can.current.scroll(), _window = can.current.window()
if (scroll) {
can.onaction.scrollIntoView(can)
} else if (0 < _scroll && _scroll < 2) {
can.current.scroll(-1)
} else if (_window-3 < _scroll && _scroll < _window) {
can.current.scroll(1)
} else if (_scroll < 2 || _scroll > _window-3) {
can.onaction.scrollIntoView(can)
}
can._msg.Option(nfs.LINE, can.Option(nfs.LINE)), can.onexport.hash(can), can.onimport.__tabPath(can, false)
can.isCmdMode() && can.onexport.session(can, SELECT_LINE+nfs.DF+can.Option(nfs.PATH)+can.Option(nfs.FILE))
can.onengine.signal(can, LINE_SELECT, can._msg), can.onaction._selectLine(can)
}); return can.onexport.hash(can), can.onexport.line(can, line)
}, _selectLine: function(can) {},
scrollIntoView: function(can, offset) { can.ui.content.scrollTo(0, (can.onexport.line(can, can.current.line)-12)*can.current.line.offsetHeight) },
searchLine: function(event, can, value) { var offset = 0; can.page.Select(can, can.ui.content, "tr.line", function(tr) {
tr == can.current.line && can.page.Select(can, tr, "td.text>span", function(span) { offset += span.innerText.length;
(span == event.target || span.innerText == value) && can.runAction(can.request(event, {name: value, text: can.current.text(), offset: offset-1}, can.Option()), code.NAVIGATE, [], function(msg) {
msg.Append(nfs.FILE)? can.onimport.tabview(can, msg.Append(nfs.PATH), msg.Append(nfs.FILE), msg.Append(nfs.LINE)): can.user.toastFailure(can, "not found "+value)
})
}), can.page.Select(can, tr, "td.text", function(td) { offset += td.innerText.length+1 }) }) },
show: function(event, can) { can._msg._profile_hidden = false, can.runAction(can.request(event, {_toast: "渲染", args: can.onexport.session(can, PROFILE_ARGS+can.Option(nfs.PATH)+can.Option(nfs.FILE))}), mdb.RENDER, [can.onexport.parse(can), can.Option(nfs.FILE), can.Option(nfs.PATH)], function(msg) { can.onimport.profile(can, msg) }) },
exec: function(event, can) { can.runAction(can.request(event, {_toast: "执行", args: can.onexport.session(can, DISPLAY_ARGS+can.Option(nfs.PATH)+can.Option(nfs.FILE))}), mdb.ENGINE, [can.onexport.parse(can), can.Option(nfs.FILE), can.Option(nfs.PATH)], function(msg) { can.onimport.display(can, msg) }) },
plug: function(event, can, button) {
function show(index, args) { input.cancel({}, can, "cancel"); can.onimport.toolkit(can, {index: index, args: can.core.Split(args||"")}, function(sub) { sub.select() }) }
var input = can.user.input(can.request(event, {type: button}), can, [{type: html.TEXT, name: ctx.INDEX, run: function(event, cmds, cb) { can.run(event, cmds, function(msg) {
if (cmds[0] == ctx.ACTION && cmds[1] == mdb.INPUTS && cmds[2] == ctx.INDEX) { var _msg = can.request({})
can.core.Item(can.db.toolkit, function(index) { _msg.Push(ctx.INDEX, index) }), _msg.Push(ctx.INDEX, ""), _msg.Copy(msg), cb(_msg)
} else { cb(msg) }
}, true) }}, ctx.ARGS], function(list) { show(list[0], list[1]) })
},
open: function(event, can, button) {
console.log(new Error())
var left = can._output.offsetWidth/4, width = can._output.offsetWidth/2; if (can.user.isMobile) { left = 0, width = can.page.width()-40 }
var input = can.user.input(can.request(event, {type: button}), can, [{name: nfs.FILE, style: {width: width}, _force: true, select: function(item) { input.submit(event, can, web.SUBMIT) }, run: function(event, cmds, cb) {
can.run(can.request(event, {paths: can.db.paths.join(mdb.FS)}), cmds, function(msg) { function push(type, name) { _msg.Push(nfs.PATH, can.core.List(arguments).join(nfs.DF)) }
if (cmds[0] == ctx.ACTION && cmds[1] == mdb.INPUTS) { var _msg = can.onengine.signal(can, "tabview.open.inputs"), func = can.onexport.func(can)
can.core.Item(can.db.tabview, function(key) { var ls = can.core.Split(key, nfs.DF); push(ls[0]+ls[1]) }), _msg.Copy(msg)
can.core.List(func.list, function(item) { var ls = can.core.Split(item, nfs.DF, nfs.DF); push(nfs.LINE, ""+ls[1]+nfs.DF+ls[0]) })
can.core.Item(can.onengine.plugin.meta, function(key, value) { push(ctx.INDEX, "can."+key) }), cb(_msg)
} else { cb(msg) }
}, true)
}}], function(list, input) { input.cancel({}, can, "cancel"); var ls = can.core.Split(list[0], nfs.DF, nfs.DF); switch (ls[0]) {
case web.HTTP: return can.onimport.tabview(can, "", list[0], web.SPACE)
case nfs.LINE: return can.onaction.selectLine(can, parseInt(ls[1]), true)
case web.SPACE: return can.onimport.tabview(can, "", ls[1].indexOf(web.HTTP) == 0? list[0].slice(6): ls[1], web.SPACE)
case ctx.INDEX: return can.onimport.tabview(can, "", ls[1], ls[0])
case ssh.SHELL: return can.onimport.tabview(can, "", [web.CODE_XTERM, list[0].slice(6)].join(mdb.FS), ctx.INDEX)
case cli.OPENS: return can.runAction(event, ls[0], ls[1], null, true)
default: var ls = can.onexport.split(can, list[0]); can.onimport.tabview(can, ls[0], ls[1])
} }); can.page.Modify(can, input._target, {className: "input inner open float"})
can.page.style(can, input._target, html.LEFT, left, html.TOP, can._output.offsetHeight/4, html.RIGHT, "")
},
find: function(event, can) { var last = can.onexport.line(can, can.current.line)
var ui = can.page.Append(can, can._output, [{view: "input inner find float", list: [html.ACTION, html.OUTPUT],
style: {left: can.ui.project.offsetWidth+can._output.offsetWidth/4-34, top: can._output.offsetHeight/2-60}}]); can.onmotion.move(can, ui._target)
function find(begin, text) { for (begin; begin <= can.ui.content._max; begin++) { if (can.onexport.text(can, can.onaction._getLine(can, begin)).indexOf(text) > -1) {
return last = begin, can.onaction.selectLine(can, begin, true)
} } last = 0, can.user.toast(can, "已经到最后一行") }
function complete(target, button) {
can.onappend.figure(can, {action: "key", mode: chat.SIMPLE, _enter: function(event) {
if (event.ctrlKey) { meta.grep() } else { meta[button](), can.onmotion.delay(can, function() { target.focus() }) } return true
}, run: function(event, cmds, cb) { var msg = can.request(event); can.core.List(can.core.Split(can.current.text(), "\t {([,:;=<>])}", {detail: true}), function(value) {
if (can.base.isObject(value)) { if (value.type == code.SPACE) { return }
value.type == code.STRING && msg.Push(mdb.VALUE, value.left+value.text+value.right), msg.Push(mdb.VALUE, value.text)
} else {
value.indexOf(nfs.PT) > -1 && msg.Push(mdb.VALUE, value.split(nfs.PT).pop()), msg.Push(mdb.VALUE, value)
}
}), cb(msg) }}, target)
}
function grep(value, file, path) { var arg = can.core.List(arguments); can.onimport.exts(can, "inner/search.js", function(sub) {
can.page.isDisplay(sub._target) || (sub._delay_init = false, sub.select()), sub.runAction(can.request({}, {value: value}), nfs.GREP, arg)
}) }
var from, to; var meta = can.onappend._action(can, [
{type: html.TEXT, name: nfs.FROM, _init: function(target) { from = target, complete(target, nfs.FIND), can.onmotion.delay(can, function() { target.focus() }) }},
{type: html.BUTTON, name: nfs.FIND}, {type: html.BUTTON, name: nfs.GREP}, {type: html.HR},
{type: html.TEXT, name: nfs.TO, _init: function(target) { to = target, complete(target, nfs.REPLACE) }},
{type: html.BUTTON, name: nfs.REPLACE}, {type: html.BUTTON, name: cli.CLOSE},
], ui.action, {_trans: {find: "查找", grep: "搜索", replace: "替换"},
find: function() {
grep(from.value, can.Option(nfs.PATH)+can.Option(nfs.FILE))
find(last+1, from.value) },
grep: function() {
grep(from.value, can.Option(nfs.PATH), "src/", "usr/release/", "usr/icebergs/", "usr/toolkits/", "usr/volcanos/")
},
replace: function() { var text = can.current.text(), line = can.onexport.line(can, can.current.line)
can.db.undo.push(function() { can.onaction.selectLine(can, line), can.onaction.modifyLine(can, line, text) })
grep(from.value, can.Option(nfs.FILE), can.Option(nfs.PATH))
can.current.text(text.replace(from.value, to.value)), can.current.text().indexOf(from.value) == -1, find(last+1, from.value)
}, close: function() { can.page.Remove(can, ui._target) },
})
},
clear: function(event, can) { if (can.onmotion.clearFloat(can)) { return }
if (can.page.Select(can, document.body, "div.vimer.find.float", function(target) { return can.page.Remove(can, target) }).length > 0) { return }
if (can.page.Select(can, can.ui.plug, "legend.select", function(target) { return target.click(), target }).length > 0) { return }
if (can.page.isDisplay(can.ui.display)) { return can.onmotion.hidden(can, can.ui.display), can.onimport.layout(can) }
if (can.page.isDisplay(can.ui.profile)) { return can.onmotion.hidden(can, can.ui.profile), can.onimport.layout(can) }
},
}) })
Volcanos(chat.ONEXPORT, {
path: function(can) { return can.Option(nfs.PATH)+can.Option(nfs.FILE) },
line: function(can, line) { return parseInt(can.core.Value(can.page.SelectOne(can, line, "td.line"), "innerText")) },
text: function(can, line) { return can.core.Value(can.page.SelectOne(can, line, "td.text"), "innerText") },
size: function(can, size, full) { if (size > 1) { return size } if (size > 0) { return size*full } },
keys: function(can, path, file) { return [path||can.Option(nfs.PATH), file||can.Option(nfs.FILE)].join(nfs.DF) },
content: function(can) { var block = "()[]{}", deep = 0, parse = can.onexport.parse(can)
return can.page.Select(can, can.current&&can.current.content||can.ui.content, "td.text", function(item) { var text = item.innerText.trimEnd()
if (can.base.isIn(parse, nfs.JS, nfs.CSS, nfs.JSON) && !can.base.beginWith(text, block[0])) { var list = []
for (var i = 0; i < text.length; i++) {
for (var j = 0; j < block.length; j += 2) {
if (text[i] == block[j]) {
list.push(text[i])
break
} else if (text[i] == block[j+1]) {
if (list[list.length-1] == block[j]) {
list.pop()
} else {
list.push(text[i])
}
break
}
}
}
for (var j = 0; j < block.length; j += 2) { if (list.indexOf(block[j+1]) > -1) { deep--; break } }
if (deep < 0) { deep = 0 }
text = "\t".repeat(deep < 0? 0: deep)+text.trimStart()
can.base.beginWith(text, "+") && (text = "\t"+text)
for (var j = 0; j < block.length; j += 2) { if (list.indexOf(block[j]) > -1) { deep++; break } }
}
return text
}).join(lex.NL)
},
position: function(can, index, total) { total = total||can.ui.content._max; return (parseInt(index))+nfs.PS+parseInt(total)+" = "+parseInt((index)*100/total)+"%" },
selection: function(can, str) { var s = document.getSelection().toString(), begin = str.indexOf(s), end = begin+s.length
for (var i = begin; i >= 0; i--) { if (str[i].match(/[a-zA-Z0-9_.]/)) { s = str.slice(i, end) } else { break } } return s
},
parse: function(can) {
return can._msg.Option(lex.PARSE)||can.base.Ext(can.Option(nfs.FILE))
},
split: function(can, file) { var ls = file.split(nfs.PS); if (ls.length == 1) { return [nfs.PWD, ls[0]] }
if (ls[0] == ice.USR) { return [ls.slice(0, 2).join(nfs.PS)+nfs.PS, ls.slice(2).join(nfs.PS)] }
return [ls.slice(0, 1).join(nfs.PS)+nfs.PS, ls.slice(1).join(nfs.PS)]
},
func: function(can) { var p = can.onsyntax[can.onexport.parse(can)]||{}, opts = {}
function indent(text) { var indent = 0; for (var i = 0; i < text.length; i++) { switch (text[i]) {
case lex.TB: indent+=4; break
case lex.SP: indent++; break
default: return indent
} } }
var list = [], current = can.Option(nfs.LINE), percent = " = "+parseInt(can.Option(nfs.LINE)*100/(can.ui.content._max||1))+"%"
can.page.Select(can, can.ui.content, "tr.line>td.text", function(item, index) { var text = item.innerText, _indent = indent(text)
function push(item) { list.push(item+(item? nfs.DF+(index+1): "")); if (index < can.Option(nfs.LINE)) { current = list[list.length-1], percent = " = "+parseInt((index+1)*100/(can.ui.content._max||1))+"%" } }
p.func && p.func(can, push, text, _indent, opts)
}); return {list: list, current: current, percent: percent}
},
})
Volcanos(chat.ONKEYMAP, {
_mode: {plugin: {
Escape: shy("清除浮窗", function(event, can) { can.onaction.clear(event, can) }),
" ": shy("打开文件", function(event, can) { can.onaction.open(event, can) }),
f: shy("打开文件", function(event, can) { can.onaction.open(event, can) }),
g: shy("查找搜索", function(event, can) { can.onaction.find(event, can) }),
d: shy("查找函数", function(event, can) { can.page.Select(can, can.ui.path, "span.func", function(target) { target.click() }) }),
v: shy("渲染界面", function(event, can) { can.onaction.show(event, can) }),
r: shy("执行命令", function(event, can) { can.onaction.exec(event, can) }),
l: shy("打开右边标签", function(can) { var next = can._tab.nextSibling; next && next.click() }),
h: shy("打开左边标签", function(can) { var prev = can._tab.previousSibling; prev && prev.click() }),
x: shy("关闭标签", function(can) { can._tab._close() }),
}}, _engine: {},
})
})()

View File

@ -0,0 +1,6 @@
Volcanos(chat.ONIMPORT, {list: [mdb.VALUE, "close:button"],
_init: function(can, msg) { msg.Defer(function() { can.onappend.scroll(can) }), can.page.style(can, can._output, html.VISIBILITY, "")
can.onappend.table(can, msg), can.onappend.board(can, msg), can.onmotion.highlight(can, can.Option(mdb.VALUE, msg.Option(mdb.VALUE)))
can.page.Select(can, can._option, "input[name=value]", function(target) { can.onmotion.hidden(can, target) })
},
})

View File

@ -0,0 +1,397 @@
Volcanos(chat.ONSYNTAX, {
makefile: {prefix: {"#": code.COMMENT}, split: {operator: "($?.,):+="}, keyword: {
"export": code.KEYWORD,
"if": code.KEYWORD, "else": code.KEYWORD, "endif": code.KEYWORD,
"ifeq": code.KEYWORD, "ifneq": code.KEYWORD,
"ifdef": code.KEYWORD, "ifndef": code.KEYWORD,
"define": code.KEYWORD, "endef": code.KEYWORD,
"shell": code.KEYWORD,
"PHONY": code.FUNCTION,
}, include: ["sh"], func: function(can, push, text, indent) { var ls = can.core.Split(text, "", ":=")
if (indent == 0 && ls[1] == ":" && ls[2] != "=") { push(text) }
}, parse: function(can, text, wrap) { var ls = can.core.Split(text, "", ":=")
if (ls[1] == ":" && ls[2] != "=" && can.base.beginWith(text, ls[0])) { return wrap(text, code.OBJECT) }
}},
man: {prefix: {
"NAME": code.KEYWORD,
"SYNOPSIS": code.KEYWORD,
"DESCRIPTION": code.KEYWORD,
"AUTHOR": code.KEYWORD,
"COPYRIGHT": code.KEYWORD,
"LIBRARY": code.KEYWORD,
"STANDARDS": code.KEYWORD,
"SEE ALSO": code.KEYWORD,
"HISTORY": code.KEYWORD,
"BUGS": code.KEYWORD,
}},
vim: {prefix: {"\"": "comment"}, keyword: {
"source": code.KEYWORD,
"finish": code.KEYWORD,
"set": code.KEYWORD,
"let": code.KEYWORD,
"end": code.KEYWORD,
"if": code.KEYWORD,
"else": code.KEYWORD,
"elseif": code.KEYWORD,
"endif": code.KEYWORD,
"for": code.KEYWORD,
"in": code.KEYWORD,
"continue": code.KEYWORD,
"break": code.KEYWORD,
"endfor": code.KEYWORD,
"try": code.KEYWORD,
"catch": code.KEYWORD,
"finally": code.KEYWORD,
"endtry": code.KEYWORD,
"call": code.KEYWORD,
"function": code.KEYWORD,
"return": code.KEYWORD,
"endfunction": code.KEYWORD,
"autocmd": code.KEYWORD,
"command": code.KEYWORD,
"execute": code.KEYWORD,
"nnoremap": code.KEYWORD,
"cnoremap": code.KEYWORD,
"inoremap": code.KEYWORD,
"colorscheme": code.KEYWORD,
"highlight": code.KEYWORD,
"syntax": code.KEYWORD,
"has": code.FUNCTION,
"type": code.FUNCTION,
"empty": code.FUNCTION,
"exists": code.FUNCTION,
"executable": code.FUNCTION,
}}, vimrc: {link: "vim"},
c: {
prefix: {
"//": code.COMMENT,
"/*": code.COMMENT,
"*": code.COMMENT,
"*/": code.COMMENT,
"#": code.KEYWORD,
},
regexp: {
"^u_\\w $": code.DATATYPE,
"^\\w+_t$": code.DATATYPE,
"^\\w+_pt$": code.DATATYPE,
"^[-]*\\d+$": code.CONSTANT,
"^[A-Z0-9_]+$": code.CONSTANT,
},
keyword: {
"#include": code.KEYWORD, "#error": code.KEYWORD, "#line": code.KEYWORD,
"#define": code.KEYWORD, "#undef": code.KEYWORD, "#ifndef": code.KEYWORD, "#ifdef": code.KEYWORD,
"#if": code.KEYWORD, "#elif": code.KEYWORD, "#else": code.KEYWORD, "#endif": code.KEYWORD,
"if": code.KEYWORD, "else": code.KEYWORD,
"for": code.KEYWORD, "while": code.KEYWORD, "do": code.KEYWORD, "break": code.KEYWORD, "continue": code.KEYWORD,
"switch": code.KEYWORD, "case": code.KEYWORD, "default": code.KEYWORD,
"return": code.KEYWORD, "goto": code.KEYWORD,
"void": code.DATATYPE, "char": code.DATATYPE, "int": code.DATATYPE, "float": code.DATATYPE, "double": code.DATATYPE,
"unsigned": code.DATATYPE, "signed": code.DATATYPE, "short": code.DATATYPE, "long": code.DATATYPE,
"struct": code.DATATYPE, "union": code.DATATYPE, "enum": code.DATATYPE,
"auto": code.DATATYPE, "register": code.DATATYPE, "volatile": code.DATATYPE, "const": code.DATATYPE,
"static": code.DATATYPE, "extern": code.DATATYPE, "typedef": code.DATATYPE,
"sizeof": code.FUNCTION, "defined": code.FUNCTION,
},
}, h: {link: "c"},
sh: {prefix: {"#": code.COMMENT}, suffix: {" {": code.COMMENT}, split: {operator: "{[($.,:;&<|>=)]}"}, regexp: {"[A-Z0-9_]+": code.CONSTANT, "ish_[A-Za-z0-9_]+": code.FUNCTION},
keyword: {
"source": code.KEYWORD, "return": code.KEYWORD, "exit": code.KEYWORD,
"require": code.KEYWORD, "request": code.KEYWORD,
"local": code.KEYWORD, "export": code.KEYWORD,
"if": code.KEYWORD, "then": code.KEYWORD, "elif": code.KEYWORD, "else": code.KEYWORD, "fi": code.KEYWORD,
"for": code.KEYWORD, "while": code.KEYWORD, "do": code.KEYWORD, "done": code.KEYWORD, "continue": code.KEYWORD, "break": code.KEYWORD,
"case": code.KEYWORD, "in": code.KEYWORD, "esac": code.KEYWORD,
"true": code.CONSTANT, "false": code.CONSTANT,
"history": code.FUNCTION, "alias": code.FUNCTION, "complete": code.FUNCTION, "compgen": code.FUNCTION, "bind": code.FUNCTION,
"printf": code.FUNCTION, "echo": code.FUNCTION, "eval": code.FUNCTION, "test": code.FUNCTION, "trap": code.FUNCTION, "shift": code.FUNCTION,
"set": code.FUNCTION, "xargs": code.FUNCTION,
"/dev/null": code.CONSTANT, "/dev/stdout": code.CONSTANT, "/dev/stderr": code.CONSTANT,
"mkdir": code.FUNCTION, "rmdir": code.FUNCTION, "mktemp": code.FUNCTION, "du": code.FUNCTION, "df": code.FUNCTION,
"cd": code.FUNCTION, "ls": code.FUNCTION, "ln": code.FUNCTION, "mv": code.FUNCTION, "rm": code.FUNCTION, "cp": code.FUNCTION,
"groupadd": code.FUNCTION, "useradd": code.FUNCTION, "chown": code.FUNCTION, "sudo": code.FUNCTION,
"curl": code.FUNCTION, "wget": code.FUNCTION, "apk": code.FUNCTION, "yum": code.FUNCTION,
"cat": code.FUNCTION, "head": code.FUNCTION, "tail": code.FUNCTION,
"grep": code.FUNCTION, "cut": code.FUNCTION, "sed": code.FUNCTION, "tr": code.FUNCTION,
"make": code.FUNCTION, "file": code.FUNCTION, "vim": code.FUNCTION, "gcc": code.FUNCTION, "git": code.FUNCTION, "go": code.FUNCTION,
"docker": code.FUNCTION,
},
func: function(can, push, text) { if (can.base.endWith(text, "() {")) { var ls = can.core.Split(text, "\t (){"); push(ls[0]) } },
}, configure: {link: "sh"},
shy: {
prefix: {
"#": code.COMMENT,
"~": code.COMMENT,
},
regexp: {"[A-Z_0-9]+": code.CONSTANT},
keyword: {
"source": code.KEYWORD, "return": code.KEYWORD,
"command": code.KEYWORD, "config": code.KEYWORD,
"create": code.FUNCTION, "modify": code.FUNCTION, "insert": code.FUNCTION,
"spide": code.DATATYPE, "serve": code.DATATYPE, "dream": code.DATATYPE,
"user": code.DATATYPE,
"title": code.KEYWORD, "navmenu": code.KEYWORD, "premenu": code.KEYWORD, "chapter": code.KEYWORD, "section": code.KEYWORD, "endmenu": code.KEYWORD,
"refer": code.KEYWORD, "brief": code.KEYWORD, "spark": code.KEYWORD, "shell": code.KEYWORD, "parse": code.KEYWORD,
"order": code.KEYWORD, "table": code.KEYWORD, "chart": code.KEYWORD, "label": code.KEYWORD, "chain": code.KEYWORD, "sequence": code.KEYWORD,
"field": code.KEYWORD, "image": code.KEYWORD, "video": code.KEYWORD, "audio": code.KEYWORD,
"style": code.KEYWORD,
"inner": code.KEYWORD,
"project": code.KEYWORD,
"product": code.KEYWORD,
"material": code.KEYWORD,
"publish": code.KEYWORD,
"username": code.FUNCTION, "usernick": code.FUNCTION,
"repos": code.FUNCTION, "binary": code.FUNCTION,
"language": code.FUNCTION, "avatar": code.FUNCTION,
},
func: function(can, push, text, indent, opts) { var ls = can.core.Split(text, "\t ")
opts.chapter = opts.chapter||0
if (ls[0] == "chapter") { opts.chapter++, opts.section = 0, push(opts.chapter+lex.SP+ls[1]) }
if (ls[0] == "section") { opts.section++, push(opts.chapter+nfs.PT+opts.section+lex.SP+ls[1]) }
},
},
py: {prefix: {"#!": code.COMMENT, "# ": code.COMMENT}, keyword: {"import": code.KEYWORD, "from": code.KEYWORD, "return": code.KEYWORD, "print": code.FUNCTION}},
proto: {prefix: {"// ": code.COMMENT}, regexp: {"[A-Z_0-9]+": code.CONSTANT}, keyword: {
"syntax": code.KEYWORD, "package": code.KEYWORD, "option": code.FUNCTION,
"service": code.KEYWORD, "rpc": code.KEYWORD, "returns": code.KEYWORD,
"message": code.KEYWORD, "repeated": code.FUNCTION, "string": code.DATATYPE, "int64": code.DATATYPE,
}},
go: {prefix: {"// ": code.COMMENT}, regexp: {"[A-Z_0-9]+": code.CONSTANT},
keyword: {
"package": code.KEYWORD, "import": code.KEYWORD, "const": code.KEYWORD, "type": code.KEYWORD, "struct": code.KEYWORD, "interface": code.KEYWORD, "func": code.KEYWORD, "var": code.KEYWORD,
"if": code.KEYWORD, "else": code.KEYWORD,
"for": code.KEYWORD, "range": code.KEYWORD, "break": code.KEYWORD, "continue": code.KEYWORD,
"switch": code.KEYWORD, "case": code.KEYWORD, "default": code.KEYWORD, "fallthrough": code.KEYWORD,
"go": code.KEYWORD, "select": code.KEYWORD, "defer": code.KEYWORD, "return": code.KEYWORD,
"iota": code.CONSTANT, "true": code.CONSTANT, "false": code.CONSTANT, "nil": code.CONSTANT,
"int": code.DATATYPE, "int8": code.DATATYPE, "int16": code.DATATYPE, "int32": code.DATATYPE, "int64": code.DATATYPE,
"uint": code.DATATYPE, "uint8": code.DATATYPE, "uint16": code.DATATYPE, "uint32": code.DATATYPE, "uint64": code.DATATYPE,
"float32": code.DATATYPE, "float64": code.DATATYPE, "complex64": code.DATATYPE, "complex128": code.DATATYPE,
"rune": code.DATATYPE, "string": code.DATATYPE, "byte": code.DATATYPE, "uintptr": code.DATATYPE,
"bool": code.DATATYPE, "error": code.DATATYPE, "chan": code.DATATYPE, "map": code.DATATYPE,
"init": code.FUNCTION, "main": code.FUNCTION, "print": code.FUNCTION, "println": code.FUNCTION, "panic": code.FUNCTION, "recover": code.FUNCTION,
"new": code.FUNCTION, "make": code.FUNCTION, "len": code.FUNCTION, "cap": code.FUNCTION, "copy": code.FUNCTION, "append": code.FUNCTION, "delete": code.FUNCTION, "close": code.FUNCTION,
"complex": code.FUNCTION, "real": code.FUNCTION, "imag": code.FUNCTION,
"If": code.KEYWORD, "For": code.KEYWORD, "Switch": code.KEYWORD,
"kit": code.PACKAGE, "ice": code.PACKAGE, "m": code.OBJECT, "msg": code.OBJECT,
"Any": code.DATATYPE, "List": code.DATATYPE, "Map": code.DATATYPE, "Maps": code.DATATYPE, "Message": code.DATATYPE,
},
func: function(can, push, text, indent, opts) { var ls = can.core.Split(text, "\t *", "({:})")
function isKey() { return opts.block == "cmds" && ls[1] == ":" && ls[2] == "{" } function isEnd() { return ls[0] == "}" }
function prefix(key, pre) { return key.slice(0, 1).toLowerCase() == key.slice(0, 1)? "- ": ("+ "+(pre? pre+nfs.PT: "")) }
if (indent == 0) { switch (ls[0]) {
case "package": opts.package = ls[1]; break
case "func": if (ls[1] == "(") { var p = ls.indexOf(")"); push(prefix(ls[p+1])+ls[2]+nfs.PT+ls[p+1]+"()"); break }
case "const":
case "var": if (ls[1] == "(") { break } // ")"
case "type": push(prefix(ls[1])+ls[1]+(ls[0]=="type"? "{}": ls[0]=="func"? "()": "")); break
} opts.stack = [ls[0]] } else if (indent == 4 && opts.stack[0] == "func") {
if (text.indexOf("MergeCommands(") > -1) { opts.block = "cmds" } else if (text.indexOf("}") == 0) { opts.block = "" }
} else if (indent == 8) {
if (isKey()) { push(prefix(ls[0], opts.package)+ls[0]), opts.cmds = ls[0] }
// if (isKey()) { push(prefix(ls[0], opts.package)+ls[0]), opts.cmds = opts.package+nfs.PT+ls[0] }
} else if (indent == 12) {
if (isKey()) { push("+ "+opts.cmds+lex.SP+ls[0]) }
}
},
},
mod: {prefix: {"//": code.COMMENT}, split: {operator: "(=>)"}, keyword: {
"go": code.KEYWORD, "module": code.KEYWORD, "require": code.KEYWORD, "replace": code.KEYWORD,
}}, sum: {}, work: {keyword: {go: code.KEYWORD, use: code.KEYWORD}},
js: {prefix: {"// ": code.COMMENT}, regexp: {"[A-Z_0-9]+": code.CONSTANT},
keyword: {
"let": code.KEYWORD, "const": code.KEYWORD, "var": code.KEYWORD,
"if": code.KEYWORD, "else": code.KEYWORD,
"switch": code.KEYWORD, "case": code.KEYWORD, "default": code.KEYWORD,
"for": code.KEYWORD, "in": code.KEYWORD, "while": code.KEYWORD, "break": code.KEYWORD, "continue": code.KEYWORD,
"try": code.KEYWORD, "catch": code.KEYWORD, "debugger": code.KEYWORD,
"function": code.KEYWORD, "return": code.KEYWORD, "arguments": code.OBJECT, "callee": code.OBJECT, "this": code.OBJECT,
"true": code.CONSTANT, "false": code.CONSTANT, "null": code.CONSTANT, "undefined": code.CONSTANT,
"parseInt": code.FUNCTION, "parseFloat": code.FUNCTION, "encodeURIComponent": code.FUNCTION, "decodeURIComponent": code.FUNCTION,
"setTimeout": code.FUNCTION, "alert": code.FUNCTION, "confirm": code.FUNCTION, "prompt": code.FUNCTION,
"document": code.OBJECT, "console": code.OBJECT,
"location": code.OBJECT, "history": code.OBJECT,
"window": code.OBJECT, "navigator": code.OBJECT,
"localStorage": code.OBJECT, "sessionStorage": code.OBJECT,
"typeof": code.KEYWORD, "new": code.KEYWORD, "delete": code.KEYWORD,
"import": code.KEYWORD, "from": code.KEYWORD, "export": code.KEYWORD, "default": code.KEYWORD,
"class": code.KEYWORD, "static": code.KEYWORD,
"async": code.KEYWORD, "await": code.KEYWORD,
"Array": code.DATATYPE, "JSON": code.DATATYPE, "Date": code.DATATYPE, "Math": code.DATATYPE, "XMLHttpRequest": code.DATATYPE, "WebSocket": code.DATATYPE,
"hasOwnProperty": code.FUNCTION, "isArray": code.FUNCTION, "forEach": code.FUNCTION, "apply": code.FUNCTION, "call": code.FUNCTION,
"length": code.FUNCTION, "split": code.FUNCTION, "trim": code.FUNCTION, "toLowerCase": code.FUNCTION, "indexOf": code.FUNCTION, "lastIndexOf": code.FUNCTION,
"concat": code.FUNCTION, "reverse": code.FUNCTION, "slice": code.FUNCTION, "join": code.FUNCTION, "sort": code.FUNCTION, "push": code.FUNCTION, "pop": code.FUNCTION,
"stringify": code.FUNCTION, "parse": code.FUNCTION,
"require": code.FUNCTION,
"kit": code.CONSTANT, "ice": code.CONSTANT,
"ctx": code.CONSTANT, "mdb": code.CONSTANT, "web": code.CONSTANT, "aaa": code.CONSTANT,
"tcp": code.CONSTANT, "nfs": code.CONSTANT, "cli": code.CONSTANT, "log": code.CONSTANT,
"code": code.CONSTANT, "wiki": code.CONSTANT, "chat": code.CONSTANT, "team": code.CONSTANT, "mall": code.CONSTANT,
"http": code.CONSTANT, "html": code.CONSTANT, "icon": code.CONSTANT, "svg": code.CONSTANT,
"can": code.OBJECT, "msg": code.OBJECT, "cb": code.FUNCTION, "target": code.OBJECT, "event": code.OBJECT,
"Volcanos": code.FUNCTION, "shy": code.FUNCTION, "cbs": code.FUNCTION,
"res": code.OBJECT, "sub": code.OBJECT, "sup": code.OBJECT,
},
complete: function(event, can, msg, target, pre, key) {
var ls = can.core.Split(can.core.Split(pre, "\t {(:,)}").pop(), nfs.PT), list = {event: event, can: can, msg: msg, target: target, window: window}
can.core.ItemKeys(key == ""? list: can.core.Value(list, ls)||can.core.Value(window, ls)||window, function(k, v) {
msg.Push(mdb.NAME, k).Push(mdb.TEXT, (v+"").split(lex.NL)[0])
})
},
func: function(can, push, text, indent, opts) { var ls = can.core.Split(text, "\t (,", nfs.DF)
if (indent == 0 && can.base.beginWith(text, "Volcanos")) {
var _block = can.base.trimPrefix(ls[1], "chat.").toLowerCase()
if (_block != opts.block) { push("") } opts.block = _block
if (text.indexOf(chat._INIT) > -1) { push(opts.block+nfs.PT+chat._INIT) }
} else if (indent == 0 && can.base.beginWith(text, "var ")) {
opts.block = ls[1]
} else if (indent == 4 && ls[1] == nfs.DF) {
ls[0] && push(opts.block+nfs.PT+ls[0])
}
},
}, json: {split: {operator: "{[:,]}"}, keyword: {"true": code.CONSTANT, "false": code.CONSTANT}},
css: {
prefix: {"// ": code.COMMENT, "/* ": code.COMMENT},
split: {operator: "{[(.,:;<!=>)]}"},
regexp: {
"#[^ ;]+": code.STRING, "[-0-9]+(deg|rem|px|s|%)?": code.STRING,
"--[^ ();]+": code.CONSTANT,
},
keyword: {
"not": code.DATATYPE, "first-child": code.DATATYPE, "last-child": code.DATATYPE, "nth-child": code.DATATYPE,
"placeholder": code.DATATYPE, "hover": code.DATATYPE, "focus": code.DATATYPE,
"$body": code.KEYWORD, "$fieldset": code.KEYWORD,
"$option": code.KEYWORD, "$action": code.KEYWORD, "$output": code.KEYWORD, "$status": code.KEYWORD,
"$content": code.KEYWORD, "$profile": code.KEYWORD, "$display": code.KEYWORD, "$project": code.KEYWORD,
"output": code.KEYWORD,
"background-color": code.FUNCTION, "color": code.FUNCTION,
"font-family": code.FUNCTION, "font-weight": code.FUNCTION, "font-style": code.FUNCTION, "font-size": code.FUNCTION, "line-height": code.FUNCTION,
"text-align": code.FUNCTION, "white-space": code.FUNCTION, "word-break": code.FUNCTION, "letter-space": code.FUNCTION, "tab-size": code.FUNCTION,
"vertical-align": code.FUNCTION,
"padding": code.FUNCTION, "padding-left": code.FUNCTION, "padding-top": code.FUNCTION, "padding-right": code.FUNCTION, "padding-bottom": code.FUNCTION,
"border": code.FUNCTION, "border-left": code.FUNCTION, "border-top": code.FUNCTION, "border-right": code.FUNCTION, "border-bottom": code.FUNCTION,
"margin": code.FUNCTION, "margin-left": code.FUNCTION, "margin-top": code.FUNCTION, "margin-right": code.FUNCTION, "margin-bottom": code.FUNCTION,
"box-sizing": code.FUNCTION, "border-radius": code.FUNCTION, "outline": code.FUNCTION, "box-shadow": code.FUNCTION,
"height": code.FUNCTION, "width": code.FUNCTION, "min-width": code.FUNCTION, "max-width": code.FUNCTION, "min-height": code.FUNCTION, "max-height": code.FUNCTION,
"display": code.FUNCTION, "float": code.FUNCTION, "clear": code.FUNCTION, "visibility": code.FUNCTION, "overflow": code.FUNCTION,
"flex": code.FUNCTION, "align-items": code.FUNCTION, "justify-content": code.FUNCTION, "flex-direction": code.FUNCTION,
"flex-grow": code.FUNCTION, "flex-shrink": code.FUNCTION, "flex-wrap": code.FUNCTION,
"position": code.FUNCTION, "z-index": code.FUNCTION, "cursor": code.FUNCTION, "transition": code.FUNCTION,
"transform": code.FUNCTION, "translate": code.FUNCTION, "rotate": code.FUNCTION,
"stroke-width": code.FUNCTION, "stroke": code.FUNCTION, "fill": code.FUNCTION,
"transparent": code.CONSTANT,
"monospace": code.CONSTANT, "bold": code.CONSTANT, "italic": code.CONSTANT, "normal": code.CONSTANT,
"center": code.CONSTANT,
"border-box": code.CONSTANT,
"calc": code.KEYWORD, "important": code.KEYWORD,
"solid": code.CONSTANT, "dashed": code.CONSTANT,
"0": code.CONSTANT, "none": code.CONSTANT, "unset": code.CONSTANT,
"block": code.CONSTANT, "both": code.CONSTANT, "hidden": code.CONSTANT, "visible": code.CONSTANT, "auto": code.CONSTANT,
"wrap": code.CONSTANT, "column": code.CONSTANT, "row-reverse": code.CONSTANT,
"relative": code.CONSTANT, "absolute": code.CONSTANT, "sticky": code.CONSTANT, "static": code.CONSTANT, "fixed": code.CONSTANT,
"left": code.FUNCTION, "top": code.FUNCTION, "right": code.FUNCTION, "bottom": code.FUNCTION,
"pointer": code.CONSTANT, "copy": code.CONSTANT,
"black": code.CONSTANT, "white": code.CONSTANT,
"silver": code.CONSTANT, "gray": code.CONSTANT,
"red": code.CONSTANT, "blue": code.CONSTANT,
"cyan": code.CONSTANT, "aliceblue": code.CONSTANT,
"--plugin-bg-color": code.CONSTANT, "--plugin-fg-color": code.CONSTANT,
"--input-bg-color": code.CONSTANT, "--output-bg-color": code.CONSTANT,
"--danger-bg-color": code.CONSTANT, "--notice-bg-color": code.CONSTANT,
"--hover-bg-color": code.CONSTANT, "--hover-fg-color": code.CONSTANT,
"--body-bg-color": code.CONSTANT, "--body-fg-color": code.CONSTANT,
/*
"text-shadow": code.FUNCTION,
"caret-color": code.FUNCTION,
"type": code.FUNCTION, "name": code.FUNCTION,
"background": code.FUNCTION, "background-position": code.FUNCTION, "background-size": code.FUNCTION,
"dark": code.CONSTANT, "light": code.CONSTANT,
"yellow": code.CONSTANT,
"green": code.CONSTANT,
"purple": code.CONSTANT,
"navy": code.CONSTANT,
"teal": code.CONSTANT,
"gold": code.CONSTANT,
"orange": code.CONSTANT,
"lavender": code.CONSTANT,
"chocolate": code.CONSTANT,
"dimgray": code.CONSTANT,
"brown": code.CONSTANT,
"snow": code.CONSTANT,
"skyblue": code.CONSTANT,
"cadetblue": code.CONSTANT,
"cornflowerblue": code.CONSTANT,
"royalblue": code.CONSTANT,
"steelblue": code.CONSTANT,
"darkblue": code.CONSTANT,
"darkcyan": code.CONSTANT,
"darkgray": code.CONSTANT,
"darkgreen": code.CONSTANT,
"lightblue": code.CONSTANT,
"lightgray": code.CONSTANT,
"lightgreen": code.CONSTANT,
"magenta": code.CONSTANT,
"vertical-align": code.FUNCTION,
"url": code.FUNCTION,
"contexts": code.CONSTANT,
*/
}, include: ["html"],
func: function(can, push, text) { text.indexOf("/* ") == 0 && push(can.base.trimPrefix(can.base.trimSuffix(text, " */"), "/* ")) },
},
html: {split: {operator: "<!=/>"}, keyword: {
"DOCTYPE": code.KEYWORD, "html": code.KEYWORD, "head": code.KEYWORD, "body": code.KEYWORD,
"meta": code.KEYWORD, "title": code.KEYWORD, "link": code.KEYWORD, "script": code.KEYWORD,
"src": code.FUNCTION, "href": code.FUNCTION, "rel": code.FUNCTION, "style": code.FUNCTION,
"h1": code.KEYWORD, "h2": code.KEYWORD, "h3": code.KEYWORD,
"p": code.KEYWORD, "em": code.KEYWORD, "strong": code.KEYWORD, "sub": code.KEYWORD, "sup": code.KEYWORD, "i": code.KEYWORD, "b": code.KEYWORD, "u": code.KEYWORD,
"pre": code.KEYWORD, "code": code.KEYWORD, "var": code.KEYWORD, "kbd": code.KEYWORD, "samp": code.KEYWORD,
"ul": code.KEYWORD, "ol": code.KEYWORD, "li": code.KEYWORD,
"table": code.KEYWORD, "thead": code.KEYWORD, "tbody": code.KEYWORD, "tfoot": code.KEYWORD,
"tr": code.KEYWORD, "th": code.KEYWORD, "td": code.KEYWORD,
"colgroup": code.KEYWORD, "col": code.KEYWORD, "colspan": code.FUNCTION, "rowspan": code.FUNCTION,
"header": code.KEYWORD, "nav": code.KEYWORD, "main": code.KEYWORD, "aside": code.KEYWORD, "footer": code.KEYWORD, "article": code.KEYWORD, "section": code.KEYWORD,
"a": code.KEYWORD, "div": code.KEYWORD, "span": code.KEYWORD, "br": code.KEYWORD, "hr": code.KEYWORD,
"img": code.KEYWORD, "video": code.KEYWORD, "audio": code.KEYWORD, "canvas": code.KEYWORD, "iframe": code.KEYWORD,
"svg": code.KEYWORD, "rect": code.KEYWORD, "circle": code.KEYWORD,
"fieldset": code.KEYWORD, "legend": code.KEYWORD, "form": code.KEYWORD, "label": code.KEYWORD,
"select": code.KEYWORD, "option": code.KEYWORD, "input": code.KEYWORD, "textarea": code.KEYWORD, "button": code.KEYWORD,
"height": code.FUNCTION, "width": code.FUNCTION,
}},
})

View File

@ -1,32 +0,0 @@
Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) {
can.onmotion.clear(can)
if (msg.Option("content")) {
can.onappend.plugin(can, {index: "web.code.vimer", style: "full"}, function(sub) {
sub.run = function(event, cmds, cb) { var res = can.request(event)
if (cmds[1] == "plugin") {
can.run(event, can.misc.concat(["action", "vimer"], cmds), cb, true)
return
}
if (cmds[1] == "main.go") { res.Echo(msg.Option("content"))
can.core.Timer(100, function() { can.sub && can.sub.onaction["项目"]({}, can.sub) })
}
cb(res), can.sub = can.core.Value(sub, "_outputs.-1")
}
}, can._output)
return
}
can.onappend.table(can, msg)
can.onappend.board(can, msg)
},
})
Volcanos("onaction", {help: "操作数据", list: [], _init: function(can, msg, list, cb, target) {
},
run: function(event, can, msg) {
can.run(event, [ctx.ACTION, ice.RUN, "go", "hi.go", can.sub.onexport.content(can.sub)], function(msg) {
can.onappend.board(can, msg)
}, true)
},
})
Volcanos("onexport", {help: "导出数据", list: [], _init: function(can, msg, list, cb, target) {
}})

View File

@ -1,55 +1,22 @@
fieldset.inner>div.output td.content { fieldset.vimer>div.output.source>div.project div.item.select { border-right:var(--box-border3); }
position:relative; fieldset.vimer>div.output.source>div.layout>div.tabs>div.tabs>div.tabs.select { border-top:var(--box-border3); }
} fieldset.vimer>div.output.source.normal>div.project div.expand.open { color:var(--notice-bg-color); }
fieldset.inner>div.output input.current { fieldset.vimer>div.output.source.normal>div.project div.item.select { border-right:var(--box-notice3); }
position:absolute; padding:0; margin:0; fieldset.vimer>div.output.source.normal>div.layout>div.tabs>div.tabs>div.tabs.select { border-top:var(--box-notice3); }
font-size:16px; font-family:monospace; fieldset.vimer>div.output.source.normal>div.layout>div.path span.mode.normal { color:var(--notice-bg-color); }
padding-left:9px; fieldset.vimer>div.output.source.normal>div.layout>div.layout>div.content tr.line.select>td.line { background-color:var(--notice-bg-color); color:white; }
fieldset.vimer>div.output.source.normal>div.layout>div.layout>div.content input.current { border:var(--box-notice); caret-color:var(--notice-bg-color); }
background-color:#00000000; color:#00000000; fieldset.vimer>div.output.source.insert>div.project div.expand.open { color:var(--danger-bg-color); }
width:-webkit-fill-available; fieldset.vimer>div.output.source.insert>div.project div.item.select { border-right:var(--box-danger3); }
} fieldset.vimer>div.output.source.insert>div.layout>div.tabs>div.tabs>div.tabs.select { border-top:var(--box-danger3); }
fieldset.inner>div.output input.current.insert { fieldset.vimer>div.output.source.insert>div.layout>div.path span.mode.insert { color:var(--danger-bg-color); }
caret-color:yellow; fieldset.vimer>div.output.source.insert>div.layout>div.layout>div.content tr.line.select>td.line { background-color:var(--danger-bg-color); color:white; }
} fieldset.vimer>div.output.source.insert>div.layout>div.layout>div.content input.current { border:var(--box-danger); caret-color:var(--danger-bg-color); }
fieldset.inner>div.output input.current.normal { fieldset.vimer>div.output.source.insert>div.layout>div.layout>div.content div.complete:not(.hide) { display:block; top:unset; }
caret-color:blue; fieldset.vimer>div.output.source>div.layout>div.layout input.current { background-color:transparent; color:transparent; padding-left:var(--input-padding); height:var(--code-line-height); position:absolute; }
} fieldset.vimer>div.output.source>div.layout>div.layout>div.content div.complete { background-color:unset; padding-top:0; height:1px; overflow:visible; display:none; position:absolute; }
fieldset.inner>div.output input.current.command { fieldset.vimer>div.output.source>div.layout>div.layout>div.content div.complete div.prefix { color:transparent; white-space:pre; float:left; }
display:none; fieldset.vimer>div.output.source>div.layout>div.layout>div.content div.complete table.content { box-shadow:var(--plugin-box-shadow); padding-left:var(--input-padding); width:unset; max-width:600px; display:block; }
} fieldset.vimer>div.output.source>div.layout>div.layout>div.content div.complete table.content thead { display:none; }
fieldset.vimer>div.output.source>div.layout>div.layout>div.content div.complete table.content td:first-child { padding-left:0; }
fieldset.inner>div.output input.command { fieldset.vimer>div.output>div.layout>div.tabs>div.tabs>div.tabs.origin.select { border-top:var(--box-danger3); }
font-size:16px; font-family:monospace;
background-color:black; color:white;
caret-color:red;
border:solid 1px red;
border-left:solid 3px green;
width:-webkit-fill-available;
margin:0; padding:0 12px;
}
fieldset.inner>div.output input.command.normal {
display:none;
}
fieldset.inner>div.output input.command.insert {
display:none;
}
fieldset.inner>div.output div.display {
border:solid 1px greenyellow;
padding:10px;
}
fieldset.inner>div.output div.display input.cmd {
font-size:16px; font-family:monospace;
background-color:black; color:white;
min-width:480px; padding-left:5px;
margin-left:2px;
}
fieldset.inner>div.output div.display div.output {
overflow:auto;
}
fieldset.inner>div.output div.display div.output {
max-height:160px;
}

View File

@ -1,308 +1,323 @@
Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) { Volcanos(chat.ONIMPORT, {
can.require(["/plugin/local/code/inner.js"], function(can) { _init: function(can, msg, cb) { can.onappend.style(can, code.VIMER); if (can.user.mod.isPod) { delete(can.onfigure.space) }
can.onimport.inner_init(can, msg, list, function() { can.require(["/plugin/local/code/inner.js"], function(can) { can.onimport._last_init(can, msg, function() {
can.onimport._input(can), can.onimport._output(can) can.db.undo = [], can.db.redo = [], can.onimport._input(can), cb && cb(msg)
can.keylist = [], can.onkeymap._init(can, "insert") }) })
can.base.isFunc(cb) && cb(msg) },
}, target) _input: function(can) { var ui = can.page.Append(can, can.ui.content.parentNode, [
}, function(can, name, sub) { {view: [code.CURRENT, html.INPUT], spellcheck: false, onkeydown: function(event) { if (event.metaKey) { return }
sub._name == "onimport" && (can.onimport.inner_init = sub._init) can.onimport._value(can), can.onkeymap._parse(event, can, can.db.mode+(event.ctrlKey? "_ctrl": ""), can.ui.current)
}) if (can.db.mode == mdb.INSERT) { can.ui.current._keylist = [] }
}, if (can.db.mode == mdb.NORMAL) { can.onkeymap.prevent(event) }
_input: function(can) { }, onkeyup: function(event) { if (event.metaKey) { return }
var ui = can.page.Append(can, can.ui.content.parentNode, [ can.onimport._value(can); can.onkeymap._complete(event, can)
{view: ["current", "input"], onkeydown: function(event) { }, onclick: function(event) { can.onkeymap._insert(event, can)
can.onkeymap.parse(event, can, "insert") }}, {view: [[code.COMPLETE]]},
can.core.Timer(10, function() { ]); can.ui.current = ui.current, can.ui.complete = ui.complete, can.onkeymap._plugin(can) },
can.current.text(can.ui.current.value) _value: function(can) { can.onimport.__tabPath(can, true)
}) can.db.mode == mdb.INSERT && can.onmotion.delay(can, function() { can.current.text(can.ui.current.value) })
}, onblur: function(event) { },
can.current.text(can.ui.current.value)
}, onfocus: function(event) {
can._output.scrollLeft += -1000
can.current.scroll(-1000, 0)
}, onclick: function(event) {
can.onkeymap._insert(can)
}},
{view: ["command", "input"], onkeydown: function(event) {
can.onkeymap.parse(event, can, "command")
}, onfocus: function(event) {
can._output.scrollLeft += -1000
can.current.scroll(-1000, 0)
}},
]); can.base.Copy(can.ui, ui, "current", "command")
},
_output: function(can) {
var ui = can.page.Appends(can, can.ui.display, [
{view: "action", list: [
{input: ["cmd", function(event) {
can.onkeymap.parse(event, can, "command")
}], value: "", onfocus: function(event) {
event.target.setSelectionRange(0, -1)
can.onkeymap._command(can)
}},
{button: ["run", function(event) {
can.onkeymap.command.Enter(event, can, can.ui.cmd.value)
}]},
{button: ["清空", function(event) {
can.onmotion.clear(can, ui.output)
} ]},
{button: ["关闭", function(event) {
can.onmotion.hidden(can, can.ui.display)
} ]},
]}, {view: "output"},
]); can.base.Copy(can.ui, ui, "output", "cmd")
},
}, [""]) }, [""])
Volcanos("onkeymap", {help: "键盘交互", list: ["command", "normal", "insert"], _init: function(can, mode) { Volcanos(chat.ONFIGURE, {
can.core.List(can.onkeymap.list, function(item) { var engine = {} source: function(can, target, zone, hash) { var args = [can.Option(nfs.PATH), can.Option(nfs.FILE)]
can.core.Item(can.onkeymap[item], function(key, cb) { var map = engine can.run({}, [ctx.ACTION, nfs.REPOS], function(msg) { var paths = can.db.paths
for (var i = key.length-1; i > -1; i--) { can.core.List(paths.concat(msg.Table(function(value) { return value.path })), function(p) {
map = map[key[i]] = i == 0? cb: (map[key[i]]||{}) if (can.base.beginWith(p, nfs.USR_LOCAL_WORK) || can.base.isIn(p,
} nfs.USR_ICONS,
}), can.onkeymap[item]._engine = engine "usr/material/",
}), can.onkeymap._mode(can, mode||"normal") nfs.USR_NODE_MODULES,
}, nfs.USR_WEBSOCKET,
_mode: function(can, value) { can.Status("模式", can.mode = value) nfs.USR_GO_QRCODE,
can.page.Modify(can, can.ui.current, {className: "current "+can.mode}) nfs.USR_GO_GIT,
can.page.Modify(can, can.ui.command, {className: "command "+can.mode}) nfs.USR_GEOAREA,
return value )) { return }
}, if (p && paths.indexOf(p) == -1 && p[0] != nfs.PS) { paths.push(p) }
_command: function(can) { can.onkeymap._mode(can, "command") })
if (can.ui.display.style.display == "none") { function show(target, zone, path) { can.run(can.request({}, {dir_root: path, dir_deep: true}), [nfs.PWD], function(msg) {
can.page.Modify(can, can.ui.command, {style: {display: ""}}) var cache, list = can.core.List(msg.Table(), function(value) {
can.ui.command.focus() if (path == nfs.SRC && can.base.isIn(value.path,
} else { "main.svg",
can.page.Modify(can, can.ui.display, {style: {display: "block"}}) "main.ico",
can.ui.cmd.focus() "main.png",
} "main.jpg",
}, "qrcode.jpg",
_normal: function(can) { can.onkeymap._mode(can, "normal") "version.go",
can.ui.current.focus() "binpack.go",
}, "binpack_usr.go",
_insert: function(can) { can.onkeymap._mode(can, "insert") )) { return }
can.ui.current.focus() if (path == nfs.USR_RELEASE && can.base.isIn(value.path, "conf.go", "binpack.go")) { return }
}, if (path == args[0] && args[1] == value.path) { value.expand = true }
return value
_remote: function(event, can, key, arg, cb) { can.request(event, {_toast: "执行中..."}) }); can.onmotion.clear(can, target), zone._total(msg.Length())
can.run(event, arg||["action", key, can.parse, can.Option("file"), can.Option("path")], cb||function(msg) { cache = can.onimport.tree(can, list, function(event, item, target) {
can.onappend.table(can, msg, function(value, key, index) { return {text: [value, "td"]} }, can.ui.output) can.base.endWith(item.path, nfs.PS) || can.onimport.tabview(can, path, item.path, "", function(msg) { msg._item = target })
can.onappend.board(can, msg.Result(), can.ui.output) }, function(event, item, target) {
}, true) var msg = can.request(event); msg.Option(nfs.PATH, path), msg.Option(nfs.FILE, item.path)
}, }, target, cache)
_engine: { can.onmotion.delay(can, function() { hash.length > 1 && can.onimport.openzone(can, hash[0], hash[1], hash[2]) && can.onimport.tabview(can, hash[0], hash[1], hash[2]), hash = [] })
e: function(event, can, line, ls) { can.onimport.tabview(can, can.Option("path"), ls[1]) }, can.onimport._zone_icon(can, msg, zone, function(event, button) { can.onaction._runs(event, can, button) })
p: function(event, can) { can.onaction["项目"](event, can) }, }, true) } if (paths.length == 1) { return show(target, zone, paths[0]) } can.page.Remove(can, zone._action)
q: function(event, can) { can.onmotion.hidden(can, can.ui.display) }, can.onimport.zone(can, can.core.List(paths, function(path) {
w: function(event, can) { can.onaction.save(event, can) }, return kit.Dict(mdb.NAME, path, path == args[0]? chat._INIT: chat._DELAY_INIT, function(target, zone) { show(target, zone, path) })
}, }), target)
})
parse: function(event, can, mode) { },
can.keylist.push(event.key); if (can.mode != mode) { space: function(can, target, zone, hash) { can.onimport._zone(can, zone, web.DREAM, mdb.NAME, hash), zone.toggle(false) },
event.stopPropagation(), event.preventDefault()
}; can.mode == "normal" && can.Status("按键", can.keylist.join(""))
for (var pre = 0; pre < can.keylist.length; pre++) {
if ("0" <= can.keylist[pre] && can.keylist[pre] <= "9") { continue } break
}; can.count = parseInt(can.keylist.slice(0, pre).join(""))||1
function repeat(cb, count) {
for (var i = 1; i <= count; i++) { if (cb(event, can, count)) { break } }
can.keylist.length > 0 && (can.lastcmd = can.keylist), can.keylist = []
can.Status("按键", can.keylist.join(""))
}
var p = can.onsyntax[can.parse]
var cb = (p && p.keymap || can.onkeymap[can.mode])[event.key]; if (can.base.isFunc(cb)) {
return repeat(cb, can.count)
}
var map = can.onkeymap[can.mode]._engine; for (var i = can.keylist.length-1; i > pre-1; i--) {
var cb = map[can.keylist[i]]; if (can.base.isFunc(cb)) {
return repeat(cb, can.count)
}; if (can.base.isObject(cb)) { map = cb; continue }; break
}
},
command: {
Escape: function(event, can) { can.onkeymap._normal(can) },
Enter: function(event, can) { can.onmotion.hidden(can, can.ui.command)
can.page.Modify(can, can.ui.display, {style: {display: "block"}})
var line = can.ui.command.value || can.ui.cmd.value
can.ui.cmd.value = line, can.ui.cmd.focus()
can.ui.cmd.setSelectionRange(0, -1)
can.ui.command.value = ""
can.onmotion.clear(can, can.ui.output)
var ls = can.core.Split(line+" ", " ", ",")
var cb = can.onkeymap._engine[ls[0]]; if (can.base.isFunc(cb)) {
can.onmotion.hidden(can, can.ui.display)
can.onkeymap._normal(can)
cb(event, can, line, ls)
} else {
can.onkeymap._remote(event, can, line, [ctx.ACTION, "engine"].concat(ls))
}
},
jk: function(event, can) { can.keylist = can.keylist.slice(0, -1)
can.onkeymap.command.Enter(event, can)
},
},
normal: {
":": function(event, can) {
can.onkeymap._command(can)
can.ui.command.value = ""
},
".": function(event, can) {
can.keylist = can.lastcmd
can.onkeymap.parse({key: ""}, can, "normal")
},
H: function(event, can) {
can.ui.current.setSelectionRange(0, 0)
},
h: function(event, can) {
can.ui.current.setSelectionRange(can.ui.current.selectionStart-1, can.ui.current.selectionStart-1)
},
l: function(event, can) {
can.ui.current.setSelectionRange(can.ui.current.selectionStart+1, can.ui.current.selectionStart+1)
},
L: function(event, can) {
can.ui.current.setSelectionRange(-1, -1)
},
j: function(event, can) {
can.onaction.selectLine(can, can.current.next())
},
k: function(event, can) {
can.onaction.selectLine(can, can.current.prev())
},
gg: function(event, can, count) { count = count || 1
can.onaction.selectLine(can, count)
var pos = can.current.offset()-can.ui.current.offsetTop
can.current.scroll(0, -(pos+can.current.height()*5))
return true
},
G: function(event, can, count) { count = count > 1? count: can.max
can.onaction.selectLine(can, count)
var pos = can.current.offset()-can.ui.current.offsetTop
can.current.scroll(0, -(pos+can.current.height()*5))
return true
},
zt: function(event, can, count) { count = count || 2
var pos = can.current.offset()-can.ui.current.offsetTop
can.current.scroll(0, -(pos+can.current.height()*count))
return true
},
zz: function(event, can, count) { count = count || 5
var pos = can.current.offset()-can.ui.current.offsetTop
can.current.scroll(0, -(pos+can.current.height()*count))
return true
},
zb: function(event, can, count) { count = count || 3
var pos = can.current.offset()-can.ui.current.offsetTop
can.current.scroll(0, -(pos+can.current.window()-can.current.height()*count))
return true
},
i: function(event, can) { can.onkeymap._insert(can)
},
I: function(event, can) { can.onkeymap._insert(can)
can.ui.current.setSelectionRange(0, 0)
},
a: function(event, can) { can.onkeymap._insert(can)
},
A: function(event, can) { can.onkeymap._insert(can)
can.ui.current.setSelectionRange(-1, -1)
},
o: function(event, can) { can.onkeymap._insert(can)
can.onaction.selectLine(can, can.onkeymap.insertLine(can, "", can.current.next()))
},
O: function(event, can) { can.onkeymap._insert(can)
can.onaction.selectLine(can, can.onkeymap.insertLine(can, "", can.current.line))
},
yy: function(event, can) { can.last = can.current.text() },
dd: function(event, can) { can.last = can.current.text()
var next = can.current.next()
can.onkeymap.deleteLine(can, can.current.line)
can.onaction.selectLine(can, next)
},
p: function(event, can) {
can.onkeymap.insertLine(can, can.last, can.current.next())
},
P: function(event, can) {
can.onkeymap.insertLine(can, can.last, can.current.line)
},
},
insert: {
Escape: function(event, can) { can.onkeymap._normal(can)
can.onaction.modifyLine(can, can.current, can.ui.current.value)
event.stopPropagation(), event.preventDefault()
},
Enter: function(event, can) {
var before = can.ui.current.value.slice(0, event.target.selectionEnd)
var left = can.ui.current.value.slice(event.target.selectionEnd)
can.current.text(before||"")
can.onaction.selectLine(can, can.onkeymap.insertLine(can, left, can.current.next()))
can.ui.current && can.ui.current.setSelectionRange(0, 0)
},
Backspace: function(event, can) {
if (can.ui.current.selectionStart > 0) { return }
event.stopPropagation(), event.preventDefault()
if (!can.current.prev()) { return }
var rest = can.current.text()
can.onaction.selectLine(can, can.current.prev())
var pos = can.current.text().length
rest = can.current.text()+rest
can.ui.current.value = rest
can.current.text(rest)
can.ui.current.setSelectionRange(pos, pos)
can.onkeymap.deleteLine(can, can.current.next())
},
ArrowDown: function(event, can) {
can.onaction.selectLine(can, can.current.next())
can.ui.current.setSelectionRange(can.ui.current.selectionStart, can.ui.current.selectionEnd)
},
ArrowUp: function(event, can) {
can.onaction.selectLine(can, can.current.prev())
can.ui.current.setSelectionRange(can.ui.current.selectionStart, can.ui.current.selectionEnd)
},
jk: function(event, can) {
can.onkeypop.DelText(can.ui.current, can.ui.current.selectionStart-1, 1)
can.onkeymap.insert.Escape(event, can)
},
},
selectLine: function(can) { var line = can.current.line
can.page.Select(can, can.current.line, "td.text", function(item) { line = item })
can.page.Modify(can, can.ui.current, {className: "current "+can.mode, value: can.current.text(), style: {
left: line.offsetLeft, top: line.offsetTop-can.current.offset()-2,
height: line.offsetHeight, width: line.offsetWidth
}})
// can.ui.current.focus()
can.ui.current.setSelectionRange(event.offsetX/13, event.offsetX/13)
can.page.Modify(can, can.ui.command, {className: "command "+can.mode})
},
insertLine: function(can, value, before) {
var line = can.onaction.appendLine(can, value)
before && can.ui.content.insertBefore(line, before)
return can.onaction.rerankLine(can), line
},
deleteLine: function(can, line) {
can.page.Remove(can, line)
can.onaction.rerankLine(can)
},
}) })
Volcanos("onaction", {help: "控件交互", list: ["run"], Volcanos(chat.ONACTION, {_trans: {input: {main: "程序", top: "顶域"}},
save: function(event, can) { var msg = can.request(event, {content: can.onexport.content(can)}) _run: function(event, can, button, args, cb) { can.runAction(event, button, args, cb||function(msg) {
can.run(event, [ctx.ACTION, "save", can.parse, can.Option("file"), can.Option("path")], function(msg) { can.onmotion.delay(can, function() { can.onimport.tabview(can, msg.Option(nfs.PATH), msg.Option(nfs.FILE)) }, 300)
can.user.toastSuccess(can) can.ui.zone.source.refresh()
}, true) }) },
}, _runs: function(event, can, button, cb) { var meta = can.Conf(), msg = can.request(event); msg.Option(ctx.ACTION, button)
}) can.user.input(event, can, meta.feature[button], function(data, args) { msg.Option(data), can.onaction._run(event, can, button, args, cb) })
Volcanos("onexport", {help: "导出数据", list: ["文件数", "模式", "按键", "解析器", "文件名", "当前行", "跳转数"]}) },
save: function(event, can, button) {
can.request(event, {file: can.Option(nfs.FILE), content: can.onexport.content(can), _toast: button})
can.onaction._run(event, can, button, [can.onexport.parse(can), can.Option(nfs.FILE), can.Option(nfs.PATH)], function(msg) {
can.onaction.reload(can, msg)
})
},
reload: function(can, msg) {
function imports(str) { var block = "", count = 0; can.core.List(str.split(lex.NL), function(text) {
if (can.base.beginWith(text, "import (")) { block = can.core.Split(text)[0]; return }
if (can.base.beginWith(text, ")")) { block = ""; return }
if (can.base.beginWith(text, "import ")) { count++; return }
if (block == "import") { count++ }
}); return count }
if (can.onexport.parse(can) == nfs.GO) {
var line = can.onaction.selectLine(can); can.onmotion.clear(can, can.ui.content), can.ui.content._max = 0
can.core.List(msg.Result().split(lex.NL), function(text) { can.onaction.appendLine(can, text) })
can.onaction.selectLine(can, line+imports(msg.Result())-imports(msg.Option(nfs.CONTENT)))
}
if (can.base.isIn(can.onexport.parse(can), nfs.JS, nfs.JSON)) {
var line = can.onaction.selectLine(can); can.onmotion.clear(can, can.ui.content), can.ui.content._max = 0
can.core.List(msg.Option("content").split(lex.NL), function(text) { can.onaction.appendLine(can, text) })
can.onaction.selectLine(can, line)
}
},
trash: function(event, can, button) { var msg = can.request(event), p = msg.Option(nfs.PATH)+msg.Option(nfs.FILE)
can.onaction._run(event, can, button, [p], function(msg) { can.ui.zone.source.refresh() })
},
script: function(event, can, button) { can.onaction._runs(event, can, button) },
create: function(event, can, button) { can.onaction._runs(event, can, button) },
module: function(event, can, button) { can.onaction._runs(can.request(event, {title: can.user.trans(can, button, "创建模块")}), can, button) },
compile: function(event, can, button) { var msg = can.request(event, {_toast: button})
can.runAction(event, button, [], function(msg) { can.ui.search && can.ui.search.hidden()
if (msg.Length() > 0 || msg.Result()) { return can.onimport.exts(can, "inner/search.js", function(sub) { can.ui.search = sub, sub.select()
can.onmotion.delay(can, function() { can.onappend._output(sub, msg, sub.Conf(ctx.DISPLAY)) })
}) } var toast = can.user.toastProcess(can, cli.RESTART); can.onmotion.delay(can, function() { toast.close(), can.user.toastSuccess(can, cli.RESTART) }, 3000)
})
},
"命令": function(event, can) { can.user.input(event, can, [{name: ctx.INDEX, need: "must"}, ctx.ARGS], function(data) {
can.onimport.tabview(can, "", data.index+(data.args? mdb.FS+data.args: ""), ctx.INDEX)
}) },
"插件": function(event, can) { can.user.input(can.request(event, {type: "plug"}), can, [{name: ctx.INDEX, need: "must"}, ctx.ARGS], function(list, data) {
var key = list.join(","), sub = can.db.toolkit[key]; if (sub) { return sub.select() }
can.onimport.toolkit(can, {index: data.index, args: can.core.Split(data.args||"")}, function(sub) { can.db.toolkit[key] = sub.select() })
}) },
"扩展": function(event, can) { can.user.input(can.request(event, {action: "extension"}), can, ["url"], function(list) {
var sub = can.db.toolkit[list[0]]; sub? sub.select(): can.onimport.exts(can, list[0])
}) },
insertLine: function(can, text, before) {
var line = can.onaction.appendLine(can, text)
before && can.ui.content.insertBefore(line, can.onaction._getLine(can, before))
return can.onaction.rerankLine(can), can.onexport.line(can, line)
},
deleteLine: function(can, line) {
line = can.onaction._getLine(can, line)
var next = line.nextSibling||line.previousSibling;
return can.page.Remove(can, line), can.onaction.rerankLine(can), next
},
_selectLine: function(can) { can.current && can.page.Select(can, can.current.line, "td.text", function(td) { var target = can.ui.current; if (!target) { return }
can.current.line.appendChild(target), can.page.style(can, target, html.LEFT, td.offsetLeft-1, html.TOP, td.offsetTop, html.WIDTH, can.base.Min(td.offsetWidth, can.ui.content.offsetWidth-can.page.Select(can, can.current.line, "td.line")[0].offsetWidth))
target.value = td.innerText, can.db.mode == mdb.NORMAL && can.onkeymap._normal(can)
can.onmotion.delay(can, function() { can.page.SelectChild(can, can.ui.complete, html.DIV, function(target) {
target.innerText = can.ui.current.value.slice(0, can.ui.current.selectionStart)
}) })
}) },
})
Volcanos(chat.ONKEYMAP, {
scrollHold: function(can, count, begin) { var top = can.ui.content.scrollTop, left = can.ui.content.scrollLeft
can.ui.current.focus(), count != undefined && can.onkeymap.cursorMove(can.ui.current, count, begin == undefined? count: begin)
can.ui.content.scrollTop = top, can.ui.content.scrollLeft = left
},
cursorDown: function(can, target) { if (!can.current.next()) { return }
var p = can.onkeymap.cursorMove(target); can.onaction.selectLine(can, can.current.next()), can.onkeymap.cursorMove(target, 0, p)
},
cursorUp: function(can, target) { if (!can.current.prev()) { return }
var p = can.onkeymap.cursorMove(target); can.onaction.selectLine(can, can.current.prev()), can.onkeymap.cursorMove(target, 0, p)
},
_model: function(can, mode) { can.db.mode = mode, can.onimport.__tabPath(can, true), can.onmotion.toggle(can, can.ui.complete, false)
can.core.List([mdb.NORMAL, mdb.INSERT], function(mode) { can.page.ClassList.del(can, can._output, mode) }), can.page.ClassList.add(can, can._output, mode)
},
_plugin: function(can) { can.onkeymap._model(can, mdb.PLUGIN), can.ui.current.blur() },
_normal: function(can) { can.onkeymap._model(can, mdb.NORMAL), can.onkeymap.scrollHold(can) },
_insert: function(event, can, count, begin) { can.onkeymap._model(can, mdb.INSERT), can.onkeymap.scrollHold(can, count, begin), can.onkeymap.prevent(event) },
_complete: function(event, can, target) { if (event == undefined || event.type == "click") { return } target = target||can.ui.complete
var pre = can.ui.current.value.slice(0, can.ui.current.selectionStart), key = can.core.Split(pre, "\t .[]", lex.SP).pop()||"", end = can.ui.current.value.slice(can.ui.current.selectionStart)
function show() { can.current.line.appendChild(target), key && can.onmotion.toggle(can, target, true)
can.page.style(can, target, html.LEFT, can.ui.current.offsetLeft, html.MARGIN_TOP, can.user.isChrome? can.current.line.offsetHeight: 5)
} show()
function update() { target._pre = pre, target._end = end, target._index = -1
can.runAction(can.request(event, {text: pre}, can.Option()), code.COMPLETE, [], function(msg) { can.page.Appends(can, target, [{view: [lex.PREFIX, html.DIV, pre]}])
var parse = can.onsyntax[can.onexport.parse(can)]; can.core.CallFunc(can.core.Value(parse, code.COMPLETE), [event, can, msg, target, pre, key])
can.core.Item(can.core.Value(parse, code.KEYWORD), function(key, value) { msg.Push(mdb.NAME, key) })
var table = can.onappend.table(can, msg, function(value, key, index) { return {text: [value, html.TD], onclick: function(event) { change(value) }} }, target)
can.page.style(can, table, html.MAX_HEIGHT, can.ui.content.offsetHeight-(can.current.line.offsetTop-can.ui.content.scrollTop)-can.current.line.offsetHeight)
show()
})
}
function change(key) { can.current.text(can.ui.current.value = target._pre+key+target._end), can.onkeymap.cursorMove(can.ui.current, target._pre.length+key.length, 0) }
function filter() { can.page.ClassList.set(can, can.ui.complete, html.HIDE, can.page.Select(can, target, [html.TBODY, html.TR], function(tr) {
if (!can.page.ClassList.set(can, tr, html.HIDE, can.page.Select(can, tr, html.TD, function(td) { if (td.innerText.toLowerCase().indexOf(key.toLowerCase()) == 0) { return td } }).length == 0)) { return tr }
}).length == 0) }
function select(index, total) { index = (index+(total+1))%(total+1); if (index == total) { can.current.text(can.ui.current.value = target._pre+target._end) }
can.page.Select(can, target, [html.TBODY, html.TR+html.NOT_HIDE], function(tr, i) { if (can.page.ClassList.set(can, tr, html.SELECT, i == index)) {
change(can.page.Select(can, tr, html.TD)[0].innerText)
} }); return index
}
if (event.ctrlKey) { if (event.type == "keyup") { var total = can.page.Select(can, target, [html.TBODY, html.TR+html.NOT_HIDE]).length; switch (event.key) {
case "n": target._index = select(target._index+1, total); can.onkeymap.prevent(event); break
case "p": target._index = select(target._index-1, total); can.onkeymap.prevent(event); break
default: return can.onkeymap.selectCtrlN(event, can, target, [html.TBODY, html.TR+html.NOT_HIDE], function(tr) { change(can.page.Select(can, tr, html.TD)[0].innerText) })
} return can.onkeymap.prevent(event) } return }
switch (pre.slice(-1)) {
case lex.TB:
case lex.SP:
case nfs.PT:
case "[": // ]
case "(": // )
case "{": update(); break // }
case "":
default: filter()
}
},
_mode: {
plugin: {
Escape: shy("清除浮窗", function(event, can) { can.onaction.clear(event, can) }),
f: shy("打开文件", function(event, can) { can.onaction.open(event, can) }),
g: shy("查找搜索", function(event, can) { can.onaction.find(event, can) }),
d: shy("查找函数", function(event, can) { can.page.Select(can, can.ui.path, "span.func", function(target) { target.click() }) }),
n: shy("命令模式", function(event, can) { can.onaction.selectLine(can, can.onaction.selectLine(can)), can.onkeymap._normal(can) }),
i: shy("插入模式", function(event, can) { can.onaction.selectLine(can, can.onaction.selectLine(can)), can.onkeymap._insert(event, can) }),
s: shy("保存文件", function(event, can) { can.onaction.save(event, can, nfs.SAVE) }),
c: shy("编译项目", function(event, can) { can.onaction.compile(event, can, code.COMPILE) }),
v: shy("渲染界面", function(event, can) { can.onaction.show(event, can) }),
r: shy("执行命令", function(event, can) { can.onaction.exec(event, can) }),
t: shy("添加命令", function(event, can) { can.onaction["命令"](event, can) }),
p: shy("添加插件", function(event, can) { can.onaction["插件"](event, can) }),
l: shy("打开右边标签", function(can) { var next = can._tab.nextSibling; next && next.click() }),
h: shy("打开左边标签", function(can) { var prev = can._tab.previousSibling; prev && prev.click() }),
x: shy("关闭标签", function(can) { can._tab._close() }),
},
normal: {
s: shy("保存文件", function(event, can) { can.onaction.save(event, can, nfs.SAVE) }),
c: shy("编译项目", function(event, can) { can.onaction.compile(event, can, code.COMPILE) }),
v: shy("渲染界面", function(event, can) { can.onaction.show(event, can) }),
r: shy("执行命令", function(event, can) { can.onaction.exec(event, can) }),
Escape: shy("切换模式", function(can) { can.onkeymap._plugin(can) }),
ArrowLeft: shy("光标左移", function(can, target) { can.onkeymap.cursorMove(target, -1) }),
ArrowRight: shy("光标右移", function(can, target) { can.onkeymap.cursorMove(target, 1) }),
ArrowDown: shy("光标下移", function(can, target) { can.onkeymap.cursorDown(can, target) }),
ArrowUp: shy("光标上移", function(can, target) { can.onkeymap.cursorUp(can, target) }),
H: shy("跳到行首", function(can, target) { can.onkeymap.cursorMove(target, 0, 0) }),
L: shy("跳到行尾", function(can, target) { can.onkeymap.cursorMove(target, 0, -1) }),
h: shy("光标左移", function(can, target) { can.onkeymap.cursorMove(target, -1) }),
l: shy("光标右移", function(can, target) { can.onkeymap.cursorMove(target, 1) }),
j: shy("光标下移", function(can, target) { can.onkeymap.cursorDown(can, target) }),
k: shy("光标上移", function(can, target) { can.onkeymap.cursorUp(can, target) }),
I: shy("插入行首", function(event, can) { can.onkeymap._insert(event, can, 0, 0) }),
A: shy("插入行尾", function(event, can) { can.onkeymap._insert(event, can, 0, -1) }),
i: shy("插入模式", function(event, can) { can.onkeymap._insert(event, can) }),
a: shy("插入模式", function(event, can) { can.onkeymap._insert(event, can) }),
o: shy("插入下一行", function(event, can) { var text = can.current.text()
text = text.substr(0, text.indexOf(text.trimLeft()))+(can.base.endWith(text, "{")? lex.TB: "")
can.onaction.selectLine(can, can.onaction.insertLine(can, text, can.current.next()))
can.onkeymap._insert(event, can, 0, -1)
}),
O: shy("插入上一行", function(event, can) { var text = can.current.text()
text = text.substr(0, text.indexOf(text.trimLeft()))+(can.base.beginWith(text, "}")? lex.TB: "")
can.onaction.selectLine(can, can.onaction.insertLine(can, text, can.current.line))
can.onkeymap._insert(event, can, 0, -1)
}),
yy: shy("复制当前行", function(event, can, target, count) { var list = [], line = can.current.line
for (var i = 0; i < count; i++) { list.push(can.onexport.text(can, line)), line = line.nextSibling } can.db._last_text = list; return true
}),
dd: shy("剪切当前行", function(event, can, target, count) { var line = can.onaction.selectLine(can), callee = arguments.callee
var list = []; for (var i = 0; i < count; i++) { (function() { var line = can.onaction.selectLine(can), text = can.current.text(); list.push(text)
can.onaction.selectLine(can, can.onaction.deleteLine(can, line)), can.db.undo.push(function() { can.onaction.insertLine(can, text, line), can.onaction.selectLine(can, line) })
})() } can.db._last_text = list, can.db.redo.push(function() { callee(event, can, target, count) })
return true
}),
p: shy("向后粘贴", function(can) { if (!can.db._last_text) { return } var line = can.onaction.selectLine(can), callee = arguments.callee
for (var i = can.db._last_text.length-1; i >= 0; i--) { (function() { var line = can.onaction.insertLine(can, can.db._last_text[i], can.current.next())
can.db.undo.push(function() { can.onaction.deleteLine(can, line), can.onaction.selectLine(can, line-1) })
})() } can.db.redo.push(function() { callee(event, can, target, count) })
}),
P: shy("向前粘贴", function(can) { if (!can.db._last_text) { return } var line = can.onaction.selectLine(can), callee = arguments.callee
for (var i = 0; i < can.db._last_text.length; i++) { (function() { var line = can.onaction.insertLine(can, can.db._last_text[i], can.current.line)
can.db.undo.push(function() { can.onaction.deleteLine(can, line), can.onaction.selectLine(can, line+1) })
})() } can.db.redo.push(function() { callee(event, can, target, count) })
}),
J: shy("合并两行", function(can) { var next = can.current.next(); if (!next) { return }
var line = can.onaction.selectLine(can), text = can.current.text(), rest = can.onexport.text(can, next)
can.ui.current.value = can.current.text(text.trimRight()+(can.base.endWith(text.trim(), "(", "[")||can.base.beginWith(rest.trim(), ",", "]", ")")? "": lex.SP)+rest.trimLeft())
can.onkeymap.cursorMove(can.ui.current, text.length, 0), can.onaction.deleteLine(can, next)
can.db.undo.push(function() { can.onaction.modifyLine(can, line, text), can.onaction.insertLine(can, rest, line+1) })
}),
".": shy("重复操作", function(can) { var cb = can.db.redo.pop(); cb && cb() }),
u: shy("撤销操作", function(can) { var cb = can.db.undo.pop(); cb && cb() }),
gg: shy("跳到某行", function(can, count) { return can.onaction.selectLine(can, count), true }),
G: shy("跳到某行", function(can, count) { return can.onaction.selectLine(can, count = count>1? count: can.db.max), true }),
zt: shy("屏幕最上", function(can, count) { return can.current.scroll(can.current.scroll()-(count>1? count: 3)), true }),
zz: shy("屏幕中间", function(can, count) { return can.current.scroll(can.current.scroll()-(count = count>1? count: can.current.window()/2)), true }),
zb: shy("屏幕最下", function(can, count) { return can.current.scroll(can.current.scroll()-can.current.window()+(count>1? count: 5)), true }),
F5: shy("刷新网页", function(can, target) { can.user.reload(true) }),
},
normal_ctrl: {
e: shy("向上滚屏", function(can) { can.current.scroll(1); if (can.current.scroll()<2) { can.onaction.selectLine(can, can.current.next()) } }),
y: shy("向下滚屏", function(can) { can.current.scroll(-1); if (can.current.scroll()>can.current.window()-3) { can.onaction.selectLine(can, can.current.prev()) } }),
f: shy("向下翻页", function(can, count) { can.current.scroll(can.current.window()) }),
b: shy("向上翻页", function(can, count) { can.current.scroll(-can.current.window()) }),
r: shy("刷新页面", function(can) { can.user.reload(true) }),
},
insert_ctrl: {
a: shy("光标行首", function(can, target) { for (var i = 0; i < target.value.length; i++) { if (target.value[i] != lex.TB) { break } } can.onkeymap.cursorMove(target, i, 0), can.onkeymap.prevent(event) }),
e: shy("光标行尾", function(can, target) { can.user.isWindows && can.onkeymap.cursorMove(target, 0, -1) }),
b: shy("光标左移", function(can, target) { can.user.isWindows && can.onkeymap.cursorMove(target, -1) }),
f: shy("光标右移", function(can, target) { can.user.isWindows && can.onkeymap.cursorMove(target, 1) }),
d: shy("删除字符", function(can, target) { can.user.isWindows && can.onkeymap.deleteText(target, target.selectionStart, 1) }),
},
insert: {
Escape: shy("退出编辑", function(can) { can.onkeymap._normal(can), can.ui.current._keylist = [] }),
ArrowUp: shy("光标上移", function(can, target) { can.onkeymap.cursorUp(can, target) }),
ArrowDown: shy("光标下移", function(can, target) { can.onkeymap.cursorDown(can, target) }),
Backspace: shy("删除字符", function(event, can, target) { if (target.selectionStart > 0 || !can.current.prev()) { return } can.onkeymap.prevent(event)
var rest = can.current.text(); can.onaction.selectLine(can, can.current.prev()), can.onaction.deleteLine(can, can.current.next())
var text = can.current.text(); can.ui.current.value = text+rest, can.onkeymap.cursorMove(target, 0, text.length)
}),
Tab: shy("添加缩进", function(event, can) { can.onkeymap.insertText(can.ui.current, lex.TB), can.onkeymap.prevent(event) }),
Enter: shy("插入换行", function(can, target) {
var rest = can.onkeymap.deleteText(target, target.selectionEnd).trimLeft(), text = can.ui.current.value
var left = text.substr(0, text.indexOf(text.trimLeft()))||(text.trimRight() == ""? text: "")
var line = can.onaction.selectLine(can), next = rest; for (var i = line; i < can.db.max; i++) { next += can.onexport.text(can, can.onaction._getLine(can, i)).trimLeft(); if (next != "") { break } }
function deep(text) { var deep = 0; for (var i = 0; i < text.length; i++) { if (text[i] == lex.TB) { deep += 4 } else if (text[i] == lex.SP) { deep++ } else { break } } return deep }
text.trim() && can.core.List(["{}", "[]", "()", "``"], function(item) { if (can.base.endWith(text, item[0])) {
if (can.base.beginWith(next, item[1])) {
can.onaction.insertLine(can, left+rest, can.current.next()), rest = ""
} else if (deep(text) >= deep(can.onexport.text(can, can.onaction._getLine(can, line+1))) && rest == "") {
can.onaction.insertLine(can, left+item[1], can.current.next())
} left += lex.TB
} else if (can.base.beginWith(rest, item[1])) { left = left.slice(0, -1) }})
var line = can.onaction.insertLine(can, left+rest, can.current.next())
can.current.text(text.trimRight()||text), can.onaction.selectLine(can, line), can.onkeymap._insert(event, can, 0, left.length)
}),
},
}, _engine: {},
})

View File

@ -0,0 +1,76 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg, cb) { can.page.requireModules(can, ["xterm/css/xterm.css", "xterm", "xterm-addon-fit", "xterm-addon-web-links"], function() {
if (can.Option(mdb.HASH) || can.Option("args0") || can.ConfIndex() == "can._filter") { var item = can.base.Obj(msg.TableDetail()); item.hash = item.hash||can.Option(mdb.HASH)||can.Option("args0")||"current"
can.onimport._connect(can, item, can._output)
} else {
can.ui = can.onappend.layout(can), can.onimport._project(can, msg, can.db.hash)
} cb && cb(msg)
}) },
_project: function(can, msg, hash) { msg.Table(function(value) {
value.nick = `${value.hash}(${value.name||value.type||"ish"})`, value._select = value.hash == hash[0]
can.onimport.item(can, value, function(event, item, show, target) {
can.onimport.tabsCache(can, value, target, function() { can.onappend._status(can)
value._term = can.onimport._connect(can, value, can.ui.content)
})
})
}) },
_connect: function(can, item, target, text) { can.onimport.layout(can)
var term = new Terminal({fontSize: html.CODE_FONT_SIZE, tabStopWidth: 4, cursorBlink: true, theme: can.onimport._theme(can, item)}); term._item = item
term.onTitleChange(function(title) { can.onexport.title(can, term, title) }), can.onexport.title(can, term, item.nick)
term.onResize(function(size) { can.onimport._resize(can, term, size) })
term.onData(function(data) { can.onimport._input(can, term, data) })
term.onCursorMove(function() { can.onexport.term(can, term) })
var fitAddon = new FitAddon.FitAddon(); term.loadAddon(fitAddon), term._fit = fitAddon, can.onmotion.delay(can, function() { fitAddon.fit() })
term.loadAddon(new WebLinksAddon.WebLinksAddon())
can.onmotion.clear(can, target), term.open(target), term.focus(), can.onmotion.delay(can, function() { term.focus() })
can.onengine.listen(can, chat.ONTHEMECHANGE, function() { term.selectAll(), can.onimport._connect(can, item, target, can.base.trimSuffix(term.getSelection(), lex.NL)) })
can.page.style(can, target, html.BACKGROUND_COLOR, term._publicOptions.theme.background||cli.BLACK)
return can.db[item.hash] = term
},
_theme: function(can, item) { return can.base.Obj(item.theme)||(
can.getHeaderTheme() == html.LIGHT? {background: "#0000", foreground: cli.BLACK, cursor: cli.BLUE}:
can.getHeaderTheme() == html.DARK? {background: "#0000", foreground: cli.SILVER, cursor: cli.SILVER}:
can.getHeaderTheme() == chat.BLACK? {background: "#0000", foreground: cli.CYAN, cursor: cli.WHITE}:
{background: "#0000", foreground: cli.BLACK, cursor: cli.BLUE}
) },
_resize: function(can, term, size) {
can.runAction(can.request({}, size, term._item), web.RESIZE, [], function(msg) {})
},
_input: function(can, term, data) {
can.runAction(can.request({}, {rows: term.rows, cols: term.cols}, term._item), html.INPUT, [btoa(data)], function(msg) {})
},
input: function(can, msg, hash, text) { var arg = msg.detail.slice(1); arg = [hash||arg[0], text||arg[1]]
term = can.db[arg[0]], can.onimport._input(can, term, arg[1])
},
grow: function(can, msg, hash, text) { var arg = msg.detail.slice(1); arg = [hash||arg[0], text||arg[1]], term = can.db[arg[0]]
if (arg[1] == "~~~end~~~") { arg[0] == "current"? can.sup.onmotion._close({}, can.sup): can.sup.onimport._back(can.sup) } else { term.write(arg[1]) }
},
layout: function(can) {
can.page.style(can, can._output, html.HEIGHT, can.ConfHeight())
can.ui.layout(can.ConfHeight(), can.ConfWidth(), 0, function() {
can.core.Item(can.db, function(hash, term) { term._fit && term._fit.fit() })
can.db.value && can.db.value._term && can.onexport.term(can, can.db.value._term)
}), can.core.Item(can.db, function(hash, term) { term._fit && term._fit.fit() })
},
})
Volcanos(chat.ONACTION, {
create: function(event, can) { can.user.input(event, can, [mdb.TYPE, mdb.NAME, mdb.TEXT], function(data) {
can.runAction(can.request({}, data), mdb.CREATE, [], function(msg) { var hash = msg.Result()
can.run(event, [hash], function(msg) { var _msg = can.request(); _msg.Push(msg.TableDetail())
can.onimport._project(can, _msg, [hash])
})
})
}) },
remove: function(event, can) { var item = event._msg.Option("_item")
can.runAction(event, mdb.REMOVE, [], function(msg) {
var value = item._item; value._tabs && value._tabs._close(), can.page.Remove(can, item)
})
},
})
Volcanos(chat.ONEXPORT, {list: [mdb.TIME, mdb.HASH, mdb.TYPE, mdb.NAME, "rows", "cols", "cursorY", "cursorX"],
term: function(can, term) { item = term._item, can.onexport.title(can, term, item.nick||item.name||item.type)
can.core.List(can.onexport.list, function(key) { if (key == mdb.TIME && !item[key]) { return } can.Status(key, can.base.getValid(item[key], term[key], term.buffer.active[key], "")+"") })
can.core.List([mdb.TIME, mdb.HASH, mdb.TYPE, mdb.NAME], function(key) { if (key == mdb.TIME && !item[key]) { return } can.Status(key, item[key]||"") })
},
title: function(can, term, title) { can.Status(mdb.NAME, title), can.sup.onexport.title(can.sup, title) },
})

View File

@ -0,0 +1,19 @@
fieldset.goods>div.output>div.project { flex:0 0 90px; }
fieldset.goods>div.output>div.project>div.item { border-right:var(--box-border3); text-align:center; padding:20px 10px; }
fieldset.goods>div.output>div.project>div.item.select {
border-right:var(--box-notice3);
position:unset;
}
fieldset.goods>div.output>div.layout>div.layout>div.content>div.item:not(.hide) {
box-shadow:var(--th-box-shadow); border:var(--plugin-border); border-radius:var(--plugin-radius);
background-color:var(--plugin-bg-color); margin:10px; float:left; }
fieldset.goods>div.output>div.layout>div.layout>div.content>div.item>div { padding:10px; float:left; clear:none; }
fieldset.goods>div.output>div.layout>div.layout>div.content>div.item>div.image { flex-grow:0; }
fieldset.goods>div.output>div.layout>div.layout>div.content>div.item>div.image>img { height:120px; width:120px; }
fieldset.goods>div.output>div.layout>div.layout>div.content>div.item>div.content { flex-grow:1; }
fieldset.goods>div.output>div.layout>div.layout>div.content>div.item>div.content div.title { font-weight:bold; white-space:break-spaces; overflow:hidden; height:32px; }
fieldset.goods>div.output>div.layout>div.layout>div.content>div.item>div.content div.content { height:24px; }
fieldset.goods>div.output>div.layout>div.layout>div.content>div.item>div.content div.display { line-height:32px; }
fieldset.goods>div.output>div.layout>div.layout>div.content>div.item>div.content div.display>div { float:left; margin-right:5px; }
fieldset.goods>div.output>div.layout>div.layout>div.content>div.item>div.content div.price { color:red; }
body:not(.mobile) fieldset.goods>div.output>div.layout>div.layout>div.content>div.item:not(.hide) { height:150px; }

View File

@ -0,0 +1,33 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg) { if (msg.IsDetail()) { return msg.Dump(can) }
var list = {}; can.ui = can.onappend.layout(can), can.onmotion.clear(can, can.ui.project)
can.page.Appends(can, can.ui.content, msg.Table(function(item, index) { var style = {}
if (!list[item.zone]) { if (can.user.isMobile && index > 0) { style["margin-top"] = "40px" }
list[item.zone] = item, item._zone = can.onimport.item(can, {name: item.zone}, function() {
can.onmotion.scrollIntoView(can, item._target, 10)
})
}
return {view: [[html.ITEM, html.FLEX]], style: style, list: [
{view: wiki.IMAGE, list: [{img: can.misc.MergeCache(can, can.core.Split(item.image)[0], item.space)}]},
{view: wiki.CONTENT, list: [
{view: [html.TITLE, html.DIV, item.name]},
{view: [html.CONTENT, html.DIV, item.text]},
{view: html.DISPLAY, list: [
item.area? {view: [mall.PRICE, html.DIV, "¥ "+(item.price||0)+" 万"]}: {view: [mall.PRICE, html.DIV, "¥ "+(item.price||0)]},
item.area? {view: [mall.COUNT, html.DIV, "面积 "+(item.area||0)+" 平"]}: {view: [mall.COUNT, html.DIV, "剩 "+(item.count||0)+" "+item.units]},
]},
{view: html.ACTION, inner: item.action},
]},
], _init: function(target) { item._target = target }, onclick: function(event) {
if (can.page.tagis(event.target, html.INPUT) && event.target.type == html.BUTTON) {
can.run(can.request(event, item), [ctx.ACTION, event.target.name])
}
}}
})), can.onmotion.select(can, can.ui.project, html.DIV_ITEM, 0)
can.ui.content.onscroll = function(event) { can.core.Item(list, function(zone, item) {
if (item._target.offsetTop > can.ui.content.scrollTop && item._target.offsetTop < can.ui.content.scrollTop+can.ui.content.offsetHeight/4) {
can.onmotion.select(can, can.ui.project, html.DIV_ITEM, item._zone)
}
}) }
},
}, [""])

View File

@ -1,30 +1,22 @@
fieldset.plan>div.output div.prepare { fieldset.plan>div.output td.content { position:relative; }
background-color:blue; fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td { vertical-align:top; }
color:white; fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td.over { border:var(--box-danger); }
} fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td.select { background-color:var(--hover-bg-color); box-shadow:var(--th-box-shadow); }
fieldset.plan>div.output div.process { fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td:hover { background-color:var(--hover-bg-color); }
background-color:green; fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td.over { background-color:var(--hover-bg-color); }
color:white; fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td div { color:white; padding:10px; margin:10px; }
} fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td div.date { color:gray; }
fieldset.plan>div.output div.cancel { fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td div.date span.lunar { font-size:12px; }
background-color:yellow; fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td div.date span.lunar.fest { color:red; }
color:white; fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td div.date span.lunar.term { color:green; }
} fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td div.prepare { background-color:#0000ff70; }
fieldset.plan>div.output div.finish { fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td div.process { background-color:#00800070; }
background-color:red; fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td div.cancel { background-color:#ff000070; text-decoration:line-through; }
color:white; fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td div.finish { background-color:#8080809c; }
} fieldset.plan>div.output>div.layout>div.layout>div.content>table.content tr:first-child { height:30px; position:sticky; top:2px; z-index:2; }
fieldset.plan>div.output>div.layout>div.layout>div.profile>table.content tr:first-child { height:30px; position:sticky; top:2px; z-index:2; }
fieldset.plan>div.output td { fieldset.plan>div.output>div.layout>div.layout>div.content>table.content thead tr:first-child { z-index:2; }
vertical-align:top; fieldset.plan>div.output>div.layout>div.layout>div.content>table.content th:first-child { width:40px; position:sticky; left:2px; z-index:1; }
} fieldset.plan>div.output>div.layout>div.layout>div.profile>table.content tr:first-child { height:30px; position:sticky; top:2px; }
fieldset.plan>div.output td.over { fieldset.plan>div.output>fieldset.plug { position:absolute; }
border:solid 2px red; fieldset.plan.story>form.option>div.item.scale { display:none; }
}
fieldset.plan>div.output td div.date {
color:gray;
}
fieldset.plan>div.output div.project {
max-height:400px;
overflow:auto;
}

View File

@ -1,208 +1,156 @@
Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) { Volcanos(chat.ONIMPORT, {
can.onmotion.clear(can, target) _init: function(can, msg, target) {
can.ui = can.onlayout.profile(can) can._display_heights = {}, can.list = {}; var ls = can.misc.SearchHash(can)
can.onmotion.hidden(can, can._action) can.ui = can.onappend.layout(can), can.ui.toggle = can.onappend.toggle(can)
can.onimport[can.Option("scale")||"week"](can, msg) can.onmotion.hidden(can, can.ui.project), can.isCmdMode() || can.onmotion.hidden(can, can._action)
can.page.Modify(can, can.ui.project, {style: {"max-height": can.ui.content.offsetHeight}}) can.onimport[can.Option("scale")||team.WEEK](can, msg), can.Status(mdb.COUNT, msg.Length())
can.page.Modify(can, can.ui.profile, {style: {"max-height": can.ui.content.offsetHeight}}) // can.ui.filter.placeholder = `search in ${ msg.Length() } items`
can.page.Modify(can, can.ui.profile, {style: {display: "block"}}) can.onimport.layout(can)
can.base.isFunc(cb) && cb(msg) var item; if (can.isCmdMode() && ls.length > 0) { item = can.list[can.core.Keys(ls)] } else if (can.sup.task) { item = can.list[can.core.Keys(can.sup.task.space, can.sup.task.zone, can.sup.task.id)] } item && item.click()
}, },
_content: function(can, msg, head, list, key, get, set) { _content: function(can, msg, head, list, key, get, set) { var begin_time = can.base.Date(can.Option(team.BEGIN_TIME)); can.sup.task && (can.sup.task._target = null)
var hash = {}; msg.Table(function(value, index) { var hash = {}; msg.Table(function(value, index) { var k = key(can.base.Date(value.begin_time)); hash[k] = (hash[k]||[]).concat([value]) })
var k = key(can.base.Date(value.begin_time)); hash[k] = (hash[k]||[]).concat([value]) can.ui.table = can.page.Append(can, can.ui.content, [{view: [[chat.CONTENT, team.PLAN], html.TABLE], list: [{type: html.TBODY, list: can.core.List(list, function(hour, row) {
}) return {type: html.TR, list: can.core.List(head, function(week, col) {
if (row == 0) { return {text: [can.user.trans(can, week), html.TH]} } if (col == 0) { return {text: [hour, html.TH]} }
can.sup.task && (can.sup.task._target = null) return can.onimport._task(can, msg, get(begin_time, col, row, hash), set(begin_time, col, row))
var begin_time = can.base.Date(can.Option("begin_time")) })}
can.page.Append(can, can.ui.content, [{view: [chat.CONTENT, html.TABLE], list: can.core.List(list, function(hour, row) { }) }] }])._target, can.onmotion.delay(can, function() { var target = can.sup.task && can.sup.task._target; target && target.click(), can.Status(mdb.COUNT, msg.Length()) })
return {type: html.TR, list: can.core.List(head, function(week, col) { },
if (row == 0) { return {text: [week, html.TH]} } _task: function(can, msg, list, time) { return {type: html.TD, className: time == can.base.Time().slice(0, time.length)? html.SELECT: "",
if (col == 0) { return {text: [hour, html.TD]} } ondblclick: function(event) { can.onaction.insertTask(event, can, time+can.base.Time().slice(time.length)) },
return can.onimport._task(can, msg, get(begin_time, col, row, hash), set(begin_time, col, row)) ondrop: function(event) { can.onkeymap.prevent(event), can.drop(event, event.target, time) },
})} ondragover: function(event) { can.onkeymap.prevent(event), can.page.Select(can, can.ui.content, html.TD, function(td) { can.page.ClassList.set(can, td, "over", td == event.target) }) },
}) }]) list: can.core.List(list, function(task) { return can.base.isString(task)? {text: [task, html.DIV, "date"]}:
can.core.Timer(10, function() { if (!can.sup.task) { return } {text: [can.core.CallFunc([can.onexport, can.Action(html.VIEW)||mdb.TEXT], [can, task])||task.name, html.DIV, can.onexport.style(can, task)],
var target = can.sup.task._target||can.task._target ondragstart: function(event) { var target = event.target; can.drop = function(event, td, time) { td.append(target)
can.sup.task = null, target.click() can.onaction.modifyTask(event, can, task, team.BEGIN_TIME, time+task.begin_time.slice(time.length), task.begin_time)
can.Status("count", msg.Length()) } }, draggable: time != undefined, title: can.onexport.title(can, task.name), _init: function(target) {
}) var item = can.onimport.item(can, {nick: task.name+nfs.DF+task.text}, function() { can.onmotion.delay(can, function() {
}, can.onmotion.select(can, can.ui.content, html.TD, target.parentNode), can.onimport._profile(can, task), can.onimport._display(can, task), can.onimport.layout(can)
_task: function(can, msg, list, time) { return {text: ["", html.TD], }) }); task._target = target, target.onclick = function(event) { item.click() }, can.list[can.core.Keys(task.space, task.zone, task.id)] = target
ondblclick: function(event) { }}
can.onaction.insertTask(event, can, time+can.base.Time(null, "%y-%m-%d %H:%M:%S").slice(time.length)) }),
}, } },
ondrop: function(event) { event.preventDefault() _profile: function(can, task) { can.onmotion.toggle(can, can.ui.profile, true), can.onexport.hash(can, task), can.onexport.title(can, task.name, task.text)
can.drop(event, event.target, time) if (can.onmotion.cache(can, function() { return can.sup.task = task, can.Status(task), [task.space, task.zone, task.id].join(nfs.PT) }, can.ui.profile)) { return }
}, task.extra && can.core.Item(can.base.Obj(task.extra), function(key, value) { task[key] = value }), delete(task.extra)
ondragover: function(event) { event.preventDefault() var table = can.page.Appends(can, can.ui.profile, [{view: [[chat.CONTENT, mdb.DETAIL], html.TABLE], list: [{th: [can.user.trans(can, mdb.KEY, "字段"), can.user.trans(can, mdb.VALUE, "属性")]}]}])._target
can.page.Select(can, can.ui.content, html.TD, function(item) { can.core.Item(task, function(key, value) { key != "_target" && can.page.Append(can, table, [{
can.page.ClassList[event.target == item? "add": "del"](can, item, "over") className: key,
}) td: [can.user.trans(can, key, null, html.INPUT), key == web.SPACE && value != ""? can.page.Format(html.A, can.misc.MergeURL(can, {pod: value}), value): value],
}, onclick: function(event) { can.page.tagis(event.target, html.INPUT) && event.target.type == html.BUTTON && can.run(can.request(event, task), [ctx.ACTION, event.target.name]) },
list: can.core.List(list, function(task) { return can.base.isString(task)? {text: [task, html.DIV, "date"]}: ondblclick: function(event) { if ([web.SPACE, mdb.ZONE, mdb.ID].indexOf(key) > -1) { return }
{text: [can.onexport[can.Action("view")||"text"](can, task), html.DIV, can.onexport.style(can, task)], can.onmotion.modify(can, event.target, function(sub, value) { can.onaction.modifyTask(event, can, task, key, value) }, {name: key, action: key.indexOf(mdb.TIME) > 0? "date": "key"})
ondragstart: function(event) { var target = event.target; can.drop = function(event, td, time) { td.append(target) },
can.onaction.modifyTask(event, can, task, "begin_time", time+task.begin_time.slice(time.length), task.begin_time) }]) }), can.onmotion.story.auto(can, can.ui.profile)
} }, draggable: time != undefined, },
_display: function(can, task) { can.onmotion.toggle(can, can.ui.display, true)
title: can.onexport.title(can, task), _init: function(target) { if (can.onmotion.cache(can, function(save, load) { save({_plugin_display: can._plugin_display}), can.sup.task = task, can.Status(task)
var item = can.onappend.item(can, html.ITEM, {nick: task.name+":"+task.text}, function() { return load([task.space, task.zone, task.id].join(nfs.PT), function(bak) { can._plugin_display = bak._plugin_display })
can.core.Timer(10, function() { can.onmotion.select(can, can.ui.content, html.TD, target.parentNode) }) }, can.ui.display)) { return }
can.onimport._profile(can, task) var index = task[ctx.INDEX]||task[ctx.EXTRA_INDEX]
}, function() { index && can.onappend.plugin(can, {space: task.space, index: index, args: task[ctx.ARGS]||task[ctx.EXTRA_ARGS], height: can.ConfHeight()/2-2*html.ACTION_HEIGHT}, function(sub, meta) {
sub.run = function(event, cmds, cb) { can.request(event, kit.Dict(team.TASK_POD, task.space, team.TASK_ZONE, task.zone, team.TASK_ID, task.id))
}, can.ui.project); task._target = target, can.task = can.task||task, can.sup.task = can.sup.task||task can.page.style(can, sub._output, html.MAX_HEIGHT, ""), can.runAction(event, ctx.RUN, [task[mdb.ZONE], task[mdb.ID]].concat(cmds), cb)
can.sup.task.zone == task.zone && can.sup.task.id == task.id && (can.sup.task._target = target) }
target.onclick = function(event) { item.click() } can._plugin_display = sub
}, sub.onaction.close = function() { can.onmotion.toggle(can, can.ui.display), can.onimport.layout(can) }
} sub.onexport.output = function() { can.onmotion.delay(can, function() { sub.onimport.display_size(can, sub), can.onimport.layout(can) }) }
}), }, can.ui.display)
} }, },
_profile: function(can, task) { day: function(can, msg) { var head = [team.HOUR, team.TASK]
function keys(task, key) { return [task.pod, task.zone, task.id, key].join(".") } var list = [0]; for (var i = 7; i < 24; i++) { list.push(can.base.Number(i, 2)) }
function key(time) { return can.base.Number(time.getHours(), 2) }
if (can.sup.task) { if (can.sup.task.pod == task.pod && can.sup.task.id == task.id) { return } function get(begin_time, col, row, hash) { return hash[list[row]] }
can.page.Cache(keys(can.sup.task, chat.PROFILE), can.ui.profile, can.sup.task.id) function set(begin_time, col, row) { return can.base.Time(begin_time, "%y-%m-%d ")+list[row] }
can.page.Cache(keys(can.sup.task, chat.DISPLAY), can.ui.display, can.sup.task.id) can.onimport._content(can, msg, head, list, key, get, set)
} },
week: function(can, msg) { var head = can.onexport.head(can, team.HOUR)
can.sup.task = task, can.Status(task) var list = [0]; for (var i = 7; i < 24; i++) { list.push(can.base.Number(i, 2)) }
var profile = can.page.Cache(keys(task, "profile"), can.ui.profile) function key(time) { return time.getDay()+" "+can.base.Number(time.getHours(), 2) }
var display = can.page.Cache(keys(task, "display"), can.ui.display) function get(begin_time, col, row, hash) { return hash[col-1+" "+list[row]] }
if (profile || display) { return } function set(begin_time, col, row) { return can.base.Time(can.base.DateAdd(begin_time, -begin_time.getDay()+col-1), "%y-%m-%d ")+list[row] }
can.onimport._content(can, msg, head, list, key, get, set)
task.extra && can.core.Item(can.base.Obj(task.extra), function(key, value) { task["extra."+key] = value }), delete(task.extra) },
var table = can.page.Appends(can, can.ui.profile, [{view: [chat.CONTENT, html.TABLE], list: [{th: ["key", "value"]}]}]).first month: function(can, msg) { var head = can.onexport.head(can, "order")
can.core.Item(task, function(key, value) { key != "_target" && can.page.Append(can, table, [{ var list = [0]; for (var i = 1; i < 6; i++) { list.push(i) }
td: [key, key == "pod" && value != ""? can.page.Format("a", can.misc.MergeURL(can, {pod: value}), value): value], function key(time) { return can.base.Time(time, "%y-%m-%d") }
onclick: function(event) { if (event.target.type == "button") { var msg = can.request(event, can.sup.task) function get(begin_time, col, row, hash) {
can.run(event, [ctx.ACTION, event.target.name], function(msg) { can.Update() }, true) var begin = can.base.DateAdd(begin_time, -(begin_time.getDate()-1))
} }, var last = can.base.DateAdd(begin_time, -(begin_time.getDate()-1)-begin.getDay())
ondblclick: function(event) { can.onmotion.modify(can, event.target, function(ev, value, old) { var day = can.base.DateAdd(last, (row-1)*7+col)
can.onaction.modifyTask(event, can, task, key, value) var l = can.date.solar2lunar(day)
}, {name: key, action: key.indexOf("time") > 0? "date": "key"}) }, return [can.page.Format(html.SPAN, day.getDate(), "day")+" "+can.page.Format(html.SPAN, l.autoDay, l.autoClass)].concat(hash[key(day)]||[])
}]) }), can.onimport._display(can, task) }
}, function set(begin_time, col, row) {
_display: function(can, task) { if (!task["extra.cmd"]) { return } var begin = can.base.DateAdd(begin_time, -(begin_time.getDate()-1))
can.onappend.plugin(can, {type: chat.STORY, ctx: task["extra.ctx"], cmd: task["extra.cmd"], arg: task["extra.arg"]}, function(sub, meta) { var last = can.base.DateAdd(begin_time, -(begin_time.getDate()-1)-begin.getDay())
sub.run = function(event, cmds, cb) { var msg = can.request(event, kit.Dict("task.pod", task["pod"], "task.zone", task.zone, "task.id", task.id)) var day = can.base.DateAdd(last, (row-1)*7+col)
can.run(event, can.misc.concat([ctx.ACTION, ice.RUN, task[mdb.ZONE], task[mdb.ID]], cmds), cb, true) return key(day)
} }
}, can.ui.display) can.onimport._content(can, msg, head, list, key, get, set)
can.page.Modify(can, can.ui.display, {style: {display: html.BLOCK}}) },
}, year: function(can, msg) { var head = can.onexport.head(can, team.MONTH)
var list = [0]; for (var i = 1; i < 13; i++) { list.push(i) }
day: function(can, msg) { function key(time) { return can.base.Time(time, "%y-%m ")+time.getDay() }
var head = ["hour", "task"] function get(begin_time, col, row, hash) { return hash[begin_time.getFullYear()+"-"+can.base.Number(row, 2)+" "+(col-1)] }
var list = [0]; for (var i = 7; i < 24; i++) { list.push(can.base.Number(i, 2)) } function set(begin_time, col, row) { return begin_time.getFullYear()+"-"+can.base.Number(list[row], 2) }
can.onimport._content(can, msg, head, list, key, get, set)
function key(time) { return can.base.Number(time.getHours(), 2) } },
function get(begin_time, col, row, hash) { return hash[list[row]] } long: function(can, msg) {
function set(begin_time, col, row) { return can.base.Time(begin_time, "%y-%m-%d ")+list[row] } var begin_time = can.base.Date(can.base.Time(can.Option(team.BEGIN_TIME), "%y-%m-%d %H:%M:%S")), begin = begin_time.getFullYear() - 5
var head = [team.MONTH]; for (var i = 0; i < 10; i++) { head.push(begin+i) }
can.onimport._content(can, msg, head, list, key, get, set) var list = [0]; for (var i = 1; i < 13; i++) { list.push(i) }
}, function key(time) { return can.base.Time(time, "%y-%m") }
week: function(can, msg) { function get(begin_time, col, row, hash) { return hash[begin+col-1+"-"+can.base.Number(row, 2)] }
var head = ["hour"].concat(["周日", "周一", "周二", "周三", "周四", "周五", "周六"]) function set(begin_time, col, row) { return begin+col-1+"-"+can.base.Number(row, 2) }
var list = [0]; for (var i = 7; i < 24; i++) { list.push(can.base.Number(i, 2)) } can.onimport._content(can, msg, head, list, key, get, set)
},
function key(time) { return time.getDay()+" "+can.base.Number(time.getHours(), 2) } layout: function(can) { can.ui.layout(can.ConfHeight(), can.ConfWidth());
function get(begin_time, col, row, hash) { return hash[col-1+" "+list[row]] } (can.Conf("_auto") || can.user.isMobile) && can.page.style(can, can.ui.content, html.HEIGHT, "")
function set(begin_time, col, row) { return can.base.Time(can.base.TimeAdd(begin_time, -begin_time.getDay()+col-1), "%y-%m-%d ")+list[row] } var sub = can._plugin_display; sub && sub.onimport.display_size(can, sub)
can.ui.toggle && can.ui.toggle.layout()
can.onimport._content(can, msg, head, list, key, get, set) }
},
month: function(can, msg) {
var head = ["order"].concat(["周日", "周一", "周二", "周三", "周四", "周五", "周六"])
var list = [0]; for (var i = 1; i < 6; i++) { list.push(i) }
function key(time) { return can.base.Time(time, "%y-%m-%d") }
function get(begin_time, col, row, hash) {
var begin = can.base.TimeAdd(begin_time, -(begin_time.getDate()-1))
var last = can.base.TimeAdd(begin_time, -(begin_time.getDate()-1)-begin.getDay())
var day = can.base.TimeAdd(last, (row-1)*7+col)
return [day.getDate()+""].concat(hash[key(day)]||[])
}
function set(begin_time, col, row) {
var begin = can.base.TimeAdd(begin_time, -(begin_time.getDate()-1))
var last = can.base.TimeAdd(begin_time, -(begin_time.getDate()-1)-begin.getDay())
var day = can.base.TimeAdd(last, (row-1)*7+col)
return key(day)
}
can.onimport._content(can, msg, head, list, key, get, set)
},
year: function(can, msg) {
var head = ["month"].concat(["周日", "周一", "周二", "周三", "周四", "周五", "周六"]);
var list = [0]; for (var i = 1; i < 13; i++) { list.push(i) }
function key(time) { return can.base.Time(time, "%y-%m ")+time.getDay() }
function get(begin_time, col, row, hash) { return hash[begin_time.getFullYear()+"-"+can.base.Number(row, 2)+" "+(col-1)] }
function set(begin_time, col, row) { return begin_time.getFullYear()+"-"+can.base.Number(list[row], 2) }
can.onimport._content(can, msg, head, list, key, get, set)
},
long: function(can, msg) {
var begin_time = can.base.Date(can.base.Time(can.Option("begin_time"), "%y-%m-%d %H:%M:%S"))
var begin = begin_time.getFullYear() - 5
var head = ["month"]; for (var i = 0; i < 10; i++) { head.push(begin+i) }
var list = [0]; for (var i = 1; i < 13; i++) { list.push(i) }
function key(time) { return can.base.Time(time, "%y-%m") }
function get(begin_time, col, row, hash) { return hash[begin+col-1+"-"+can.base.Number(row, 2)] }
function set(begin_time, col, row) { return begin+col-1+"-"+can.base.Number(row, 2) }
can.onimport._content(can, msg, head, list, key, get, set)
},
}, [""]) }, [""])
Volcanos("onaction", {help: "组件交互", list: [ Volcanos(chat.ONACTION, {list: [
["level", "all", "l1", "l2", "l3", "l4", "l5"], ["status", "status", "prepare", "process", "cancel", "finish"],
["status", "all", "prepare", "process", "cancel", "finish"], ["level", "level", "l1", "l2", "l3", "l4", "l5"],
["score", "all", "s1", "s2", "s3", "s4", "s5"], ["score", "score", "s1", "s2", "s3", "s4", "s5"],
["view", "", "name", "text", "level", "score"], ["view", "text", "name", "text", "level", "score"],
], ], _trans: {"task": "任务", "hour": "时间", "month": "月份", "order": "周序"},
insertTask: function(event, can, time) { var msg = can.sup.request(event, {begin_time: time}) prev: function(event, can) { var begin = can.base.Date(can.Option(team.BEGIN_TIME)||can.base.Time())
can.user.input(event, can, can.Conf("feature.insert"), function(event, button, data, list) { can.Option(team.BEGIN_TIME, can.base.Time(new Date(begin-can.onexport.span(can)))), can.Update()
can.run(event, can.base.Simple(ctx.ACTION, mdb.INSERT, data, "begin_time", time), true) },
}) next: function(event, can) { var begin = can.base.Date(can.Option(team.BEGIN_TIME)||can.base.Time())
}, can.Option(team.BEGIN_TIME, can.base.Time(new Date(begin-(-can.onexport.span(can))))), can.Update()
modifyTask: function(event, can, task, key, value) { var msg = can.request(event, task) },
can.run(event, [ctx.ACTION, mdb.MODIFY, key, value, task[key]]) insertTask: function(event, can, time) { var msg = can.sup.request(event, {begin_time: time})
}, can.user.input(event, can, can.Conf([ctx.FEATURE, mdb.INSERT]), function(args) {
can.runAction(event, mdb.INSERT, [web.SPACE, args[1], mdb.ZONE, args[3], team.BEGIN_TIME, time].concat(args.slice(4)))
_filter: function(event, can, key, value) { var count = 0 })
if (value == "all") { },
can.page.Select(can, can.ui.content, "div.item", function(item) { modifyTask: function(event, can, task, key, value) { can.runAction(can.request(event, task, can.Option()), mdb.MODIFY, [key, value], function() { can.Update() }) },
can.page.ClassList.del(can, item, "hide"), count++ _filter: function(event, can, key, value) { var count = 0
}) if (value == key) {
} else { can.page.Select(can, can.ui.content, html.DIV_ITEM, function(item) { can.page.ClassList.del(can, item, html.HIDE), count++ })
can.page.Select(can, can.ui.content, "div.item", function(item) { } else {
can.page.ClassList.add(can, item, "hide") can.page.Select(can, can.ui.content, html.DIV_ITEM, function(item) { can.page.ClassList.add(can, item, html.HIDE) })
}) can.page.Select(can, can.ui.content, can.core.Keys(html.DIV, value), function(item) { can.page.ClassList.del(can, item, html.HIDE), count++ })
can.page.Select(can, can.ui.content, "div."+value, function(item) { } can.Action(key, value), can.Status(mdb.COUNT, count)
can.page.ClassList.del(can, item, "hide"), count++ },
}) status: function(event, can, key, value) { can.onaction._filter(event, can, key, value) },
} level: function(event, can, key, value) { can.onaction._filter(event, can, key, value) },
can.Action(key, value), can.Status("count", count) score: function(event, can, key, value) { can.onaction._filter(event, can, key, value) },
}, view: function(event, can, key, value) { can.Action(key, value), can.onmotion.clear(can, can.ui.project), can.onmotion.clear(can, can.ui.content), can.core.CallFunc([can.onimport, can.Option("scale")], [can, can._msg]) },
level: function(event, can, key, value) { can.onaction._filter(event, can, key, value) },
status: function(event, can, key, value) { can.onaction._filter(event, can, key, value) },
score: function(event, can, key, value) { can.onaction._filter(event, can, key, value) },
view: function(event, can, key, value) {
can.Action(key, value)
can.onmotion.clear(can, can.ui.project)
can.onmotion.clear(can, can.ui.content)
can.onimport[can.Option("scale")](can, can._msg)
},
}) })
Volcanos("onexport", {help: "导出数据", list: ["count", "begin_time", "zone", "id", "type", "name", "text"], Volcanos(chat.ONEXPORT, {list: [mdb.COUNT, team.BEGIN_TIME, mdb.ZONE, mdb.ID, mdb.TYPE, mdb.NAME, mdb.TEXT, web.SPACE],
name: function(can, task) { return task.name }, span: function(can) { return kit.Dict(team.DAY, 24*3600*1000, team.WEEK, 7*24*3600*1000, team.MONTH, 30*24*3600*1000, team.YEAR, 365*24*3600*1000, team.LONG, 365*24*3600*1000)[can.Option("scale")]||0 },
text: function(can, task) { return task.name+": "+(task.text||"") }, hash: function(can, task) { if (!can.isCmdMode()) { return } location.hash = [task.space, task.zone, task.id].join(nfs.DF) },
level: function(can, task) { return "l-"+(task.level||3)+": "+(task.name||"") }, head: function(can, scale) { if ([team.YEAR, team.LONG].indexOf(scale) > -1) { return } return [scale].concat(can.user.time(can, "", "%W")) },
score: function(can, task) { return "s-"+(task.level||3)+": "+(task.name||"") }, name: function(can, task) { return task.name },
title: function(can, task) { return task.zone+": "+(task.type||"") }, text: function(can, task) { return task.name+": "+(task.text||"") },
style: function(can, task) { return ["item", task.status, "id"+task.id, "l"+(task.level||""), "s"+(task.score||"")].join(" ") }, level: function(can, task) { return "l-"+(task.level||3)+": "+(task.name||"") },
score: function(can, task) { return "s-"+(task.level||3)+": "+(task.name||"") },
style: function(can, task) { return [html.ITEM, task.status, mdb.ID+task.id, "l"+(task.level||""), "s"+(task.score||"")].join(lex.SP) },
}) })

View File

@ -0,0 +1,2 @@
fieldset.data div.output table.content tr.select { background-color:gray; }
fieldset.data div.output table.content tr.over { background-color:gray; }

View File

@ -1,143 +1,77 @@
Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb) { Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb) {
can.ui = can.onlayout.display(can) if (can.Option(mdb.TYPE)) { return can.onimport[can.Option(mdb.TYPE)](can, msg, can.Option(mdb.FIELD)) }
can.base.isFunc(cb) && cb(msg) can.ui = can.onappend.layout(can), can.table = can.onappend.table(can, msg, function(value, key, index, line) { return can.onimport._value(can, value) }, can.ui.content)
cb && cb(msg), can.onappend._status(can, msg.append), can.onaction._compute(event, can)
can.table = can.onappend.table(can, msg, function(value, key, index, line) { },
return {text: [value, "td"], oncontextmenu: function(event) { _value: function(can, value) {
can.user.carte(event, can, can.ondetail, can.ondetail.list, function(ev, cmd, meta) { return {text: [value, html.TD], oncontextmenu: function(event) {
var cb = meta[cmd]; cb && cb(event, can, cmd, value, key, index, line) can.user.carte(event, can, can.ondetail, can.ondetail.list, function(ev, button, meta) { var cb = meta[button]; can.base.isFunc(cb) && cb(event, can, button) })
}) }, ondblclick: function(event) { can.page.editable(can, event.target, true) }}
}, ondblclick: function(event) { },
can.page.Modify(can, event.target, {contenteditable: true}) _story: function(can, msg, display) { return can.onappend.plugin(can, {msg: msg, mode: chat.OUTPUT, display: can.misc.MergePath(can, display, chat.PLUGIN_STORY)}) },
}, onclick: function(event) { "折线图": function(can, msg, field) { return can.onimport._story(can, msg, can.base.MergeURL("trend.js", {field: field, view: "折线图"})) },
if (key == "path") { can.run(event, [can.Option("path", value)]) } "柱状图": function(can, msg, field) { return can.onimport._story(can, msg, can.base.MergeURL("trend.js", {field: field, view: "柱状图"})) },
}} "比例图": function(can, msg, field) { return can.onimport._story(can, msg, can.base.MergeURL("pie.js", {field: field})) },
}, can.ui.content) }, [""])
Volcanos(chat.ONFIGURE, {
can.onexport.list = msg.append "求和": function(event, can, res, td, index) { res[index] = parseFloat(td.innerText) + (res[index]||0) },
can.onaction._compute(event, can) "最大": function(event, can, res, td, index) { (res[index] === undefined || parseFloat(td.innerText) > parseFloat(res[index])) && (res[index] = parseFloat(td.innerText)) },
}, "最小": function(event, can, res, td, index) { (res[index] === undefined || parseFloat(td.innerText) < parseFloat(res[index])) && (res[index] = parseFloat(td.innerText)) },
"平均": function(event, can, res, td, index, cols, rows, nrow) { res[index] = parseFloat(td.innerText) + (res[index]||0); if (nrow == rows.length - 1) { res[index] = res[index] / nrow } },
}) })
Volcanos("onfigure", {help: "组件菜单", list: [], Volcanos(chat.ONACTION, {list: [nfs.SAVE,
"求和": function(event, can, res, td, index) { [ice.MODE, "全选", "多选", "块选", "反选", "拖动", "编辑"],
res[index] = parseInt(td.innerText) + (res[index]||0); [ice.EXEC, "求和", "最大", "最小", "平均"],
}, ],
"最大": function(event, can, res, td, index) { _compute: function(event, can) { var method = can.onfigure[can.Action(ice.EXEC)], res = {}
var n = parseInt(td.innerText); var mul = html.TR + (can.Action(ice.MODE) == "全选"? "": ".select"); can.page.Select(can, can.table, mul, function(tr, nrow, rows) {
n > (res[index]||-10000) && (res[index] = n); (mul != html.TR || nrow > 0) && can.page.Select(can, tr, html.TD, function(td, ncol, cols) { method && method(event, can, res, td, ncol, cols, rows, nrow) })
}, }), can.core.Item(res, function(key, value) { can.Status(can._msg.append[key], value||"") })
"最小": function(event, can, res, td, index) { },
var n = parseInt(td.innerText); save: function(event, can, button) { can.runAction(event, button, [can.Option(nfs.PATH), can.onexport.content(can)]) },
n < (res[index]||10000) && (res[index] = n); exec: function(event, can, button) { can.onaction._compute(event, can) },
}, push: function(event, can, button) {
"平均": function(event, can, res, td, ncol, cols, rows, nrow) { can.user.input(event, can, can.page.Select(can, can.table, html.TH, function(th, index) { return {name: th.innerText, run: function(event, cmds, cb) {
res[ncol] = parseInt(td.innerText) + (res[ncol]||0); var msg = can.request(event); can.page.Select(can, can.table, html.TR, function(tr, _index) { _index > 0 && msg.Push(mdb.VALUE, tr.children[index].innerText) }), cb(msg)
if (nrow == rows.length - 1) { }} }), function(list) { can.runAction(event, button, [can.Option(nfs.PATH)].concat(list), function() { can.Update() }) })
res[ncol] = res[ncol] / nrow },
} draw: function(event, can, button) {
}, can.user.input(event, can, [[mdb.TYPE, "折线图", "比例图"], {name: mdb.FIELD, run: function(event, cmds, cb) {
var msg = can.request(event); can.page.Select(can, can.table, html.TH, function(th) { msg.Push(mdb.VALUE, th.innerText) }), cb(msg)
}}], function(list) { can.onimport[list[0]](can, can._msg, list[1]) })
},
_foreach: function(can, button, cb) { button && can.Action(ice.MODE, button), can.page.Select(can, can.table, "tbody>tr", function(target) { cb(target) }) },
"全选": function(event, can, button) { can.onaction._foreach(can, button, function(target) {
can.page.ClassList.del(can, target, html.SELECT), can.page.ClassList.del(can, target, "over")
can.page.editable(can, target, false), can.page.draggable(can, target, false)
target.onmouseenter = null, target.onclick = null
}), can.onaction._compute(event, can) },
"多选": function(event, can, button) { can.onaction._foreach(can, button, function(target) {
target.onmouseenter = function() {}, target.onclick = function() { can.page.ClassList.neg(can, target, html.SELECT), can.onaction._compute(event, can) }
}) },
"块选": function(event, can, button) { can.onaction._foreach(can, button, function(target) {
target.onmouseenter = function() { can.page.ClassList.add(can, target, html.SELECT), can.onaction._compute(event, can) }
}) },
"反选": function(event, can, button) { can.onaction._foreach(can, button, function(target) {
target.onmouseenter = function() { can.page.ClassList.del(can, target, html.SELECT), can.onaction._compute(event, can) }
}) },
"拖动": function(event, can, button) { can.onaction["全选"](event, can, button), can.onaction._foreach(can, "", function(target) { can.page.draggable(can, target, true)
target.ondragstart = function(event) { can.drag = target }
target.ondragover = function(event) { event.preventDefault(), can.page.ClassList.add(can, target, "over")}
target.ondragleave = function(event) { can.page.ClassList.del(can, target, "over") }
target.ondrop = function(event) { event.preventDefault(), can.page.ClassList.del(can, target, "over"), can.page.Select(can, can.table, html.TBODY, function(tbody) { tbody.insertBefore(can.drag, target) }) }
}) },
"编辑": function(event, can, button) { can.onaction._foreach(can, button, function(target) { can.page.editable(can, target, true) }) },
}) })
Volcanos("onaction", {help: "组件菜单", list: ["保存", ["mode", "全选", "块选", "反选", "多选", "拖动", "编辑"], ["some", "求和", "最大", "最小", "平均"]], Volcanos(chat.ONDETAIL, {list: ["复制", "删除"],
_compute: function(event, can) { "复制": function(event, can) { var list = can.page.Select(can, event.target.parentNode, html.TD, function(target) { return target.innerHTML })
var mul = "tr" + (can.Action("mode") == "全选"? "": ".select") can.page.insertBefore(can, [{type: html.TR, list: can.page.Select(can, can.table, html.TH, function(key, index) { return can.onimport._value(can, list[index]) })}], event.target.parentNode, can.table)
var method = can.onfigure[can.Action("some")], res = {} },
"删除": function(event, can) { can.page.Remove(can, event.target.parentNode) },
can.page.Select(can, can.ui.content, mul, function(tr, nrow, rows) {
(mul != "tr" || nrow > 0) && can.page.Select(can, tr, "td", function(td, ncol, cols) {
method && method(event, can, res, td, ncol, cols, rows, nrow)
})
})
can.core.Item(res, function(key, value) {
can.Status(can._msg.append[key], value||"")
})
},
"保存": function(event, can, cmd) {
can.run(event, [ctx.ACTION, cmd, can.Option("path"), can.onexport.file(can)], function(msg) {
can.user.toastSuccess(can)
}, true)
},
some: function(event, can, cmd) {
can.onaction._compute(event, can)
},
"全选": function(event, can, cmd) {
cmd && can.Action("mode", cmd)
can.page.Select(can, can.ui.content, "tr", function(item) {
can.page.ClassList.del(can, item, "over")
can.page.ClassList.del(can, item, "select")
item.setAttribute("contenteditable", false)
item.setAttribute("draggable", false)
item.onmouseenter = null
item.onclick = null
})
can.onaction._compute(event, can)
},
"块选": function(event, can, cmd) {
cmd && can.Action("mode", cmd)
can.page.Select(can, can.ui.content, "tr", function(item) {
item.onmouseenter = function() {
can.page.ClassList.add(can, item, "select")
can.onaction._compute(event, can)
}
})
},
"反选": function(event, can, cmd) {
cmd && can.Action("mode", cmd)
can.page.Select(can, can.ui.content, "tr", function(item) {
item.onmouseenter = function() {
can.page.ClassList.del(can, item, "select")
can.onaction._compute(event, can)
}
})
},
"多选": function(event, can, cmd) {
cmd && can.Action("mode", cmd)
can.page.Select(can, can.ui.content, "tr", function(item) {
item.onclick = function() {
can.page.ClassList.neg(can, item, "select")
can.onaction._compute(event, can)
}
})
},
"拖动": function(event, can, cmd) {
can.onaction["全选"](event, can, cmd)
can.page.Select(can, can.ui.content, "tr", function(item) {
item.setAttribute("draggable", true)
item.ondragstart = function(event) { can.drag = item }
item.ondragover = function(event) { event.preventDefault(), can.page.ClassList.add(can, item, "over")}
item.ondragleave = function(event) { can.page.ClassList.del(can, item, "over") }
item.ondrop = function(event) { event.preventDefault()
can.page.Select(can, can.ui.content, "table", function(table) {
table.insertBefore(can.drag, item)
})
}
})
},
"编辑": function(event, can, cmd) {
cmd && can.Action("mode", cmd)
can.page.Select(can, can.ui.content, "tr", function(item) {
item.setAttribute("contenteditable", true)
})
},
}) })
Volcanos("ondetail", {help: "组件详情", list: ["复制", "删除"], Volcanos(chat.ONEXPORT, {
"复制": function(event, can, cmd, value, key, index, line) { content: function(can) { return can.page.Select(can, can.ui.content, html.TR, function(tr) {
var end = can.page.Append(can, can.table, [{type: "tr", list: can.core.List(can._msg.append, function(key) { return can.page.Select(can, tr, can.page.Keys(html.TH, html.TD), function(td) {return td.innerHTML}).join(mdb.FS)
return {text: [line[key], "td"]} }).join(lex.NL) },
})}]).tr
can.table.insertBefore(end, event.target.parentNode)
},
"删除": function(event, can, cmd) {
can.page.Remove(can, event.target.parentNode)
},
}) })
Volcanos("onexport", {help: "导出数据", list: [],
file: function(can) {
return can.page.Select(can, can.ui.content, "tr", function(tr) {
return can.page.Select(can, tr, "th,td", function(td) {return td.innerHTML}).join(",")
}).join("\n")
},
})

View File

@ -1,14 +0,0 @@
fieldset.draw div.output {
background-color:#1b5b738c;
font-size:20px;
}
fieldset.draw div.output div.content svg {
background-color:#1b5b738c;
}
fieldset.draw div.output div.profile div.action div.item {
float:left;
}
fieldset.draw div.output div.display {
max-height:400px;
overflow:auto;
}

View File

@ -1,590 +1,399 @@
Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) { Volcanos(chat.ONIMPORT, {
can.onmotion.clear(can), can.onmotion.hidden(can, can._action) _init: function(can, msg) {
can.onimport._show(can, msg), can.base.isFunc(cb) && cb(msg) can.isCmdMode() || can.onmotion.hidden(can, can._action)
can.keylist = [], can.onkeypop._build(can) can.OptionPath = function(value) { return can.Option(nfs.PATH, value) }
}, can.OptionPid = function(value) { return can.Option(svg.PID, value) }
_show: function(can, msg) { can.point = [] can.ActionGo = function(value) { return can.Action(svg.GO, value) }
can.svg = null, can.group = null, can.temp = null, can.current = null can.ActionMode = function(value) { return can.Action(ice.MODE, value) }
can.ActionShape = function(value) { return can.Action(svg.SHAPE, value) }
can._temp = []
if (can.ConfIndex() == web.WIKI_DRAW) { can.ui = can.onappend.layout(can), can.onexport.title(can, can.OptionPath())
if (can.isCmdMode() && !can.user.isMobile) { can.onmotion.toggle(can, can.ui.profile, true) } else { can.onmotion.hidden(can, can._action), can.onmotion.hidden(can, can.ui.project) }
} else { can.ui.content || (can.ui = {content: can._output}) } can.page.Modify(can, can.ui.content, msg.Results()||can.onexport.content(can))
can.page.Select(can, can.ui.content, html.SVG, function(target) { can.ui.svg = can.ui.group = can.onimport._block(can, target), can.onimport._project(can, target), can.ui.profile && can.core.ItemCB(can.onaction, target, can)
can.page.Select(can, target, "", function(target) { can.onimport._block(can, target), can.page.tagis(target, svg.G) && target.Value(html.CLASS) && can.onimport._project(can, target) })
}), can.ondetail._select(can, can.db.hash[1]||can.OptionPid()||can.ui.svg.Value(svg.PID)), can.ui.points = []
},
_block: function(can, target) {
target.Value = function(key, value) { if (can.base.isUndefined(key)) { return } if (can.base.isObject(key)) { return can.core.Item(key, target.Value), key }
var figure = can.onfigure._get(can, target); key = can.core.Value(figure, [svg.DATA, svg.TRANS, key])||key
var _cb = can.core.Value(figure, [svg.DATA, key]); if (can.base.isFunc(_cb)) { return _cb(can, value, key, target) }
if (value == ice.AUTO) { return target.removeAttribute(key) }
if (key == html.INNER) { return value != undefined && (target.innerHTML = value), target.innerHTML }
if (key == svg.SHIP) { return value != undefined && target.setAttribute(key, JSON.stringify(value)), can.base.Obj(target.getAttribute(key), []) }
try { return value != undefined && target.setAttribute(key, value), target.getAttribute(key) || can.core.Value(target[key], "baseVal.value") || can.core.Value(target[key], "baseVal") || undefined } catch(e) { }
}, target.Val = function(key, value) { return parseInt(target.Value(key, value == undefined? value: parseInt(value)||0))||0 }
target.Group = function() { for (var node = target; node; node = node.parentNode) { if (can.page.tagis(node, svg.G, html.SVG)) { return node } } return can.ui.svg }
target.Groups = function() { if (target == can.ui.svg) { return html.SVG } var list = []
for (var node = target; node && !can.page.tagis(node, html.SVG); node = node.parentNode) { can.page.tagis(node, svg.G) && node.Value(html.CLASS) && list.push(node.Value(html.CLASS)) }
return list.reverse().join(nfs.PT)
}; return target
},
_project: function(can, target) { var groups = target.Groups(); if (!groups || !can.ui.project) { return }
var item = can.onimport.item(can, {name: groups}, function(event) { can.ui.group = target
can.misc.SearchHash(can, groups, can.OptionPid()), can.Status(svg.GROUP, groups), can.onaction.show(event, can)
can.core.List([svg.FONT_SIZE, svg.STROKE_WIDTH, svg.STROKE, svg.FILL], function(key) { can.Action(key, target.Value(key)||key) })
}, function(event) { return {meta: can.onaction, list: can.onaction.menu_list} }); target._item = item
groups == can.db.hash[0] && can.onmotion.delay(can, function() { item.click() })
},
_profile: function(can, target) { if (!can.ui.profile) { return }
can.misc.SearchHash(can, target.Groups()||html.SVG, can.OptionPid(can.onexport._pid(can, target)))
var figure = can.onfigure._get(can, target), ui = can.page.Appends(can, can.ui.profile, [html.OUTPUT, html.ACTION])
can.page.Appends(can, ui.output, [{view: [html.CONTENT, html.TABLE], list: [
{th: [mdb.KEY, mdb.VALUE]}, {td: [mdb.TYPE, target.tagName]}, {td: [svg.PID, target.Value(svg.PID)]}, {td: [mdb.TEXT, target.Value(mdb.TEXT)]},
].concat(can.core.List([].concat(can.core.Value(figure, "data.copy"), [svg.X, svg.Y, mdb.INDEX, ctx.ARGS]), function(key) {
return key = can.core.Value(figure.data, can.core.Keys(svg.TRANS, key))||key, {td: [key, target.Value(key)], ondblclick: function(event) {
var _target = event.target
can.onmotion.modify(can, _target, function(event, value) {
target.Value(key, _target.innerHTML = value), can.ondetail._move(can, target)
if (key == ctx.INDEX || key == ctx.ARGS) { can.onimport._display(can, target) }
}, {name: key, action: "key"})
}}
})) }])
// can.onappend._action(can, can.ondetail.list, ui.action, {_engine: function(event, can, button) { can.ondetail[button]({target: target}, can, button) }})
},
_display: function(can, target) { if (!can.ui.display) { return }
if (!target.Value(ctx.INDEX)) { return can.onmotion.hidden(can, can.ui.display) } can.onmotion.toggle(can, can.ui.display, true)
if (can.onmotion.cache(can, function() { return target.Value(svg.PID) }, can.ui.display)) { return can.onimport.layout(can) }
can.onappend.plugin(can, {index: target.Value(ctx.INDEX), args: target.Value(ctx.ARGS), height: can.ConfHeight()/2}, function(sub) {
sub.onexport.output = function() { can.onmotion.delay(can, function() { can.page.style(can, sub._output, html.MAX_HEIGHT, "")
sub.onimport.size(sub, can.base.Max(sub._target.offsetHeight, can.ConfHeight()/2), can.ConfWidth()-can.ui.project.offsetWidth, true), can.onimport.layout(can)
}) }
sub.onaction._close = function() { can.onmotion.hidden(can, can.ui.display), can.onimport.layout(can) }
}, can.ui.display)
},
block: function(can, type, value, group) { group = group||can.ui.group
var target = document.createElementNS("http://www.w3.org/2000/svg", type)
return group.appendChild(can.onimport._block(can, target)), target.Value(value), target
},
group: function(can, name, value, group) { var target = can.onimport.block(can, svg.G, {}, group||can.ui.svg)
return target.Value(html.CLASS, name), target.Value(value), can.onimport._project(can, target), target
},
draw: function(can, meta, group) { group = group||can.ui.svg
var figure = can.onfigure[meta.shape], data = figure.draw({}, can, meta.points, meta.style||{}); can.core.Item(meta.style, function(key, value) { data[key] = value })
var target = can.onimport.block(can, figure.data.name||meta.shape, data, group); can.core.ItemCB(meta, target, can)
return meta._init && meta._init(target), target
},
layout: function(can) {
can.ui.svg && can.page.style(can, can.ui.svg, html.MIN_HEIGHT, can.ConfHeight()-1, html.MIN_WIDTH, can.ConfWidth())
can.ui.layout && can.ui.layout(can.ConfHeight(), can.ConfWidth(), 0, function(height, width) {
can.page.style(can, can.ui.svg, html.MIN_HEIGHT, height-1, html.MIN_WIDTH, width)
})
},
})
Volcanos(chat.ONACTION, {
list: [
[svg.GO, ctx.RUN, ice.AUTO, "manual"], [ice.MODE, web.DRAW, html.MOVE, html.RESIZE],
[svg.SHAPE, svg.RECT, svg.LINE, svg.TEXT, svg.BLOCK, svg.CIRCLE, svg.ELLIPSE],
[svg.STROKE_WIDTH, svg.STROKE_WIDTH, 1, 2, 3, 4, 5],
[svg.STROKE, svg.STROKE, cli.RED, cli.YELLOW, cli.GREEN, cli.CYAN, cli.BLUE, cli.PURPLE, cli.BLACK, cli.WHITE],
[svg.FILL, svg.FILL, cli.RED, cli.YELLOW, cli.GREEN, cli.CYAN, cli.BLUE, cli.PURPLE, cli.BLACK, cli.WHITE],
[svg.FONT_SIZE, svg.FONT_SIZE, 12, 16, 18, 24, 32], [svg.GRID, svg.GRID, 1, 2, 3, 4, 5, 10, 20],
], _change: function(can, key, value) {
value == "" && (value = key), can.Action(key, value)
key == value && (value = ice.AUTO), can.ui.group.Value(key, value)
can.user.toast(can, key+" "+value)
},
"stroke-width": function(event, can, key, value) { can.onaction._change(can, key, value) },
stroke: function(event, can, key, value) { can.onaction._change(can, key, value) },
fill: function(event, can, key, value) { can.onaction._change(can, key, value) },
"font-size": function(event, can, key, value) { can.onaction._change(can, key, value) },
save: function(event, can, button) { can.runAction(can.request(event, {text: can.onexport.content(can, can.ui.svg)}), button, [can.OptionPath()]) },
// 加载图形 menu_list: [html.HIDE, html.SHOW, web.CLEAR, mdb.CREATE, mdb.REMOVE],
can.ui = can.onlayout.profile(can), can.onmotion.hidden(can, can.ui.project) hide: function(event, can) { can.onmotion.hide(can, {interval: 50, length: 10}, null, can.ui.group) },
can.page.Modify(can, can.ui.content, msg.Result()||can.onexport.content(can)) show: function(event, can) { can.onmotion.show(can, {interval: 50, length: 10}, null, can.ui.group) },
can.page.Select(can, can.ui.content, html.SVG, function(svg) { clear: function(event, can) { can.onmotion.clear(can, can.ui.group), delete(can.ui.temp), can.ui.points = [] },
can.svg = can.group = can.onimport._block(can, svg), can.onimport._group(can, svg).click() create: function(event, can) { can.user.input(event, can, [svg.GROUP], function(list) { can.onimport.group(can, list[0], {}, can.ui.group) }) },
can.core.ItemCB(can.onaction, function(key, cb) { svg[key] = function(event) { cb(event, can) } }) remove: function(event, can) {
can.page.Select(can, svg, "*", function(item, index) { can.onimport._block(can, item) if (can.ui.group == can.ui.svg) { return can.onmotion.clear(can, can.ui.svg) }
item.tagName == svg.G && item.Value(html.CLASS) && can.onimport._group(can, item) can.page.Remove(can, can.ui.group._item), can.page.Remove(can, can.ui.group)
}) },
})
// 默认参数
can.core.Timer(10, function() {
can.core.Item({
"stroke-width": 2, stroke: cli.YELLOW, fill: cli.PURPLE,
"font-size": 24, "font-family": html.MONOSPACE,
go: ice.RUN, shape: "rect", grid: 10,
}, function(key, value) { can.svg.Value(key, can.Action(key, can.svg.Value(key)||value)) })
var pid = can.Option("pid")||can.svg.Value("pid"); can.onmotion.hidden(can, can.ui.profile, true) _mode: {
pid && can.page.Select(can, can.svg, ice.PT+pid, function(item) { draw: function(event, can, points) { var shape = can.ActionShape(), figure = can.onfigure[shape]
can.ondetail.run({target: item}, can), can.onimport._profile(can, item) figure.grid && figure.grid(event, can, points); if (figure.data.points && points.length < figure.data.points) { return }
}) || can.onimport._profile(can, can.svg), can.onmotion.hidden(can, can.ui.profile) var data = figure.draw && figure.draw(event, can, points, {}), target = data && can.onimport.block(can, figure.data.name||shape, data, can.ui.group)
can.page.Modify(can, can.ui.display, {style: {"min-height": 80, "max-height": can.Conf("height")-can.svg.Val("height")-52}}) if (event.type != html.CLICK) { return target } can.ui.points = []; if (!target) { return } var pid = can.onexport._pid(can, target)
}) can.core.List(points, function(p, i) { p.target && p.target.Value(svg.SHIP, p.target.Value(svg.SHIP).concat([{pid: pid, which: i+1, anchor: p.anchor}])) })
}, },
_group: function(can, target) { var name = target.Groups() move: function(event, can, points) { var target = event.target
function show(event) { can.group = target if (event.type == html.CLICK) { if (points.length > 1) { return can.ui.points = [], delete(can.ui.current) }
can.core.List([html.STROKE_WIDTH, html.STROKE, html.FILL, html.FONT_SIZE], function(key) { return can.ui.current = {target: target, begin: can.core.List([target], function(target) { if (can.page.tagis(target, svg.G)) { return }
can.Action(key, target.Value(key)||can.Action(key)) return {target: target, height: target.Val(html.HEIGHT), width: target.Val(html.WIDTH), x: target.Val(svg.X), y: target.Val(svg.Y),
}) ship: can.core.List(target.Value(svg.SHIP), function(ship) { return ship.pid && (ship.target = can.ondetail._select(can, ship.pid)) && ship })
} }
return (name || target == can.svg) && can.onappend.item(can, html.ITEM, {name: name||html.SVG}, function(event) { show(event) }), pos: can.onexport.cursor(event, can, target)}
can.onaction.show(event, can) }
}, function(event) { can.ui.current && can.core.List(can.ui.current.begin, function(item) { var figure = can.onfigure._get(can, item.target)
can.user.carteRight(event, can, can.onaction, [ice.HIDE, ice.SHOW, mdb.CREATE, cli.CLEAR, mdb.REMOVE]) can.onexport.resize(item.target, 5, points[0], points[1], item), can.ondetail._move(can, item.target, item.ship)
}, can.ui.project) can.ondetail._select(can, item.target.Value(mdb.TEXT), function(text) { text.Value(can.onexport._text(can, item.target, figure, {})) })
}, })
_block: function(can, target) { },
target.oncontextmenu = function(event) { resize: function(event, can, points) { var target = event.target
var carte = can.user.carte(event, can, can.ondetail, null, function(ev, button, meta) { if (event.type == html.CLICK) { if (points.length > 1) { return can.ui.points = [], delete(can.ui.current) }
meta[button](event, can, button) return can.ui.current = {target: target, begin: can.core.List([target], function(target) { if (can.page.tagis(target, svg.G)) { return }
}); can.page.Modify(can, carte._target, {style: {left: event.clientX, top: event.clientY}}) return {target: target, height: target.Val(html.HEIGHT), width: target.Val(html.WIDTH), x: target.Val(svg.X), y: target.Val(svg.Y),
} ship: can.core.List(target.Value(svg.SHIP), function(ship) { return ship.pid && (ship.target = can.ondetail._select(can, ship.pid)) && ship })
target.Val = function(key, value) { }
return parseInt(target.Value(key, value == undefined? value: parseInt(value)||0))||0 }), pos: can.onexport.cursor(event, can, target)}
} }
target.Value = function(key, value) { if (can.base.isUndefined(key)) { return } can.ui.current && can.core.List(can.ui.current.begin, function(item) { var figure = can.onfigure._get(can, item.target)
if (can.base.isObject(key)) { can.core.Item(key, target.Value); return } can.onexport.resize(item.target, can.ui.current.pos, points[0], points[1], item), can.ondetail._move(can, item.target, item.ship)
can.ondetail._select(can, item.target.Value(mdb.TEXT), function(text) { text.Value(can.onexport._text(can, item.target, figure, {})) })
var figure = can.onfigure._get(can, target) })
key = figure && figure.data && figure.data.size && figure.data.size[key] || key },
if (figure && figure.data && can.base.isFunc(figure.data[key])) { },
return figure.data[key](can, value, key, target) _figure: function(event, can, points) {
} can._undo && can._undo(), can._undo = function() { can.ui.temp && can.page.Remove(can, can.ui.temp) && delete(can.ui.temp), delete(can._undo) }
can.ui.temp = can.core.CallFunc([can.onaction._mode, can.ActionMode()], [event, can, points]), can.ui.points.length == 0 && can._undo && can._undo()
if (key == html.INNER) { },
return value != undefined && (target.innerHTML = value), target.innerHTML _group: function(can) {
} can._undo && can._undo(), can._temp = can.onimport.block(can, svg.G, {}, can.ui.group)
if (key == ice.SHIP) { can._undo = function() { can._temp && can.page.Remove(can, can._temp) && delete(can._temp), delete(can._undo) }
return value != undefined && target.setAttribute(key, JSON.stringify(value)), can.base.Obj(target.getAttribute(key), []) return can._temp
} },
return value != undefined && target.setAttribute(key, value), target.getAttribute(key||html.CLASS) _auto: function(can, target) { if (can.ui.points.length > 0 || can.page.tagis(target, html.TEXT)) { return }
|| target[key]&&target[key].baseVal&&target[key].baseVal.value || target[key]&&target[key].baseVal || "" var pos = can.onexport.cursor(event, can, target); if (target == can.ui.svg) { switch (pos) {
} case 5: can.ActionMode(web.DRAW), can.ActionShape(html.BLOCK), can.page.style(can, target, {cursor: html.CROSSHAIR}); break
target.Group = function() { var item = target default: can.ActionMode(html.RESIZE)
while (item) { if ([html.SVG, svg.G].indexOf(item.tagName) > -1) { return item }; item = item.parentNode } } } else { switch (pos) {
return can.svg case 5: can.ActionMode(html.MOVE); break
} case 9: can.ActionMode(html.RESIZE); break
target.Groups = function() { var item = target default: can.ActionMode(web.DRAW), can.ActionShape(svg.LINE)
var list = []; while (item && item.tagName != html.SVG) { } }
item.tagName == svg.G && item.Value(html.CLASS) && list.push(item.Value(html.CLASS)) },
item = item.parentNode onmouseover: function(event, can) { can.onexport._show(can, event.target) },
} onmousemove: function(event, can) {
return list.reverse().join(ice.PT) if (can.ActionGo() == ctx.RUN) { return can.page.style(can, can.ui.svg, {cursor: html.POINTER}) }
} if (can.ActionGo() == ice.AUTO) { can.onaction._auto(can, event.target) }
return target if (can.ActionGo() == "manual") { if (event.target == can.ui.svg) { can.onexport._cursor(can, "") }
}, if (can.ActionMode()== html.MOVE) {
_profile: function(can, target, list) { can.Option("pid", can.onfigure._pid(can, target)) if (event.target != can.ui.svg) { can.onexport._cursor(can, html.MOVE) }
can.pid && can.page.Cache(can.pid, can.ui.profile, "some"), can.pid = target.Value("pid") } else if (can.ActionMode() == html.RESIZE) {
var cache = can.page.Cache(can.pid, can.ui.profile); if (cache) { return } if (event.target != can.ui.svg) { can.onaction._auto(can, event.target), can.ActionMode(html.RESIZE) }
} else { var shape = can.ActionShape()
var action = can.page.Append(can, can.ui.profile, [{view: "action"}]).first can.onaction._auto(can, event.target), can.ActionMode("draw"), can.ActionShape(shape)
can.onappend._action(can, can.ondetail.list, action, {_engine: function(event, can, button) { }
can.ondetail[button]({target: target}, can, button) }
}}) can.onaction._figure(event, can, can.ui.points.concat(can.onexport._point(event, can)))
can.ui.temp && can.onexport._show(can, can.ui.temp||event.target)
var figure = can.onfigure._get(can, target) },
list = (list||[]).concat(figure.data.copy, [svg.X, svg.Y, mdb.INDEX, ctx.ARGS]) onclick: function(event, can) {
can.page.Append(can, can.ui.profile, [{type: html.TABLE, className: "content", list: [ if (can.ActionGo() == ctx.RUN) { return can.ondetail._select(can, event.target.Value(svg.PID)) }
{th: [mdb.KEY, mdb.VALUE]}, {td: [mdb.TYPE, target.tagName]}, {td: ["pid", target.Value("pid")]}, can.onaction._figure(event, can, can.ui.points = can.ui.points.concat(can.onexport._point(event, can)))
].concat(can.core.List(list, function(key) { },
return key = figure.data.size[key]||key, {td: [key, target.Value(key)], ondblclick: function(event) { ondblclick: function(event, can) { can.page.style(can, can.ondetail.label(event, can)._target, {left: event.clientX, top: event.clientY}) },
can.onmotion.modify(can, event.target, function(event, value, old) { oncontextmenu: function(event, can) { can.page.style(can, can.user.carte(event, can, can.ondetail)._target, {left: event.clientX, top: event.clientY}) },
target.Value(key, value), can.onfigure._move(can, target) })
}) Volcanos(chat.ONDETAIL, {list: [cli.START, nfs.COPY, html.LABEL, mdb.REMOVE], _trans: {copy: "复制", label: "标签"},
}} _select: function(can, name, cb) { if (!name) { return } var target = can.page.SelectOne(can, can.ui.svg, nfs.PT+name, cb); if (!target) { return }
})) }]) can.onimport._profile(can, target), can.onimport._display(can, target), can.onimport.layout(can); return target
},
}, _move: function(can, target, list) {
draw: function(event, can, value) { can.core.List(list||target.Value(svg.SHIP), function(ship) { var p = can.onexport.anchor(target, ship.anchor, {})
var figure = can.onfigure[value.shape] ship.target = can.page.SelectOne(can, can.ui.svg, nfs.PT+ship.pid)
var data = figure.draw(event, can, value.point, value.style) if (ship.which == 1) { ship.target.Val(svg.X1, p.x), ship.target.Val(svg.Y1, p.y) } else if (ship.which == 2) { ship.target.Val(svg.X2, p.x), ship.target.Val(svg.Y2, p.y) }
can.core.Item(value.style, function(key, value) { data[key] = value }) })
var item = can.onfigure._push(can, figure.data.name||value.shape, data, can.group||can.svg) },
can.core.ItemCB(value, function(key, cb) { item[key] = cb }) start: function(event, can) { event = event._events||event; var target = event.target; if (target == can.ui.svg) { return }
can.onimport._block(can, item), can.onfigure._pid(can, item) var list = [target], dict = {}
return value._init && value._init(item), item for (var i = 0; i < list.length; i++) { var ship = list[i].Value(svg.SHIP)
}, for (var j = 0; j < ship.length; j++) { var pid = ship[j].pid
}, ["/plugin/local/wiki/draw.css"]) can.ondetail._select(can, pid, function(target) { var pid = target.Value(svg.SHIP)[1].pid
Volcanos("onfigure", {help: "图形绘制", list: [], can.ondetail._select(can, pid, function(target) { !dict[pid] && list.push(target), dict[pid] = true })
_get: function(can, item, name) { })
return can.onfigure[name]||can.onfigure[item.getAttribute(mdb.NAME)]||can.onfigure[item.tagName] }
}, }
_pid: function(can, item) { if (item.Value("pid")) { return item.Value("pid") } can.core.Next(list, function(target, next) {
var pid = "p"+can.svg.Val(mdb.COUNT, can.svg.Val(mdb.COUNT)+1) can.onimport._display(can, target), can.user.toast(can, target.Value(ctx.INDEX))
item.Value(html.CLASS, (item.Value(html.CLASS)+ice.SP+item.Value("pid", pid)).trim()) can.onmotion.show(can, {interval: 500, length: 10}, null, target)
return pid can.onmotion.delay(can, function() { next() }, 1000)
}, }, function() { can.user.toastSuccess(can) })
_push: function(can, type, data, target) { },
var item = document.createElementNS("http://www.w3.org/2000/svg", type) copy: function(event, can) { event = event._events||event; var target = event.target; if (target == can.ui.svg) { return }
target.appendChild(can.onimport._block(can, item)), item.Value(data) var figure = can.onfigure._get(can, target), trans = can.core.Value(figure, [svg.DATA, svg.TRANS])||{}, data = {}
return item data[trans.x||svg.X] = target.Val(trans.x||svg.X)+10, data[trans.y||svg.Y] = target.Val(trans.y||svg.Y)+10
}, can.core.List(figure.data.copy, function(key) { data[key] = target.Value(key) })
_copy: function(event, can, target) { return can.onimport.block(can, target.tagName, data, can.ui.group)
var data = {}, figure = can.onfigure._get(can, target), size = figure.data.size },
can.core.List(figure.data.copy, function(item) { data[item] = target.Value(item) }) label: function(event, can) { event = event._events||event; var target = event.target; if (target == can.ui.svg) { return }
data[size.x||svg.X] = target.Val(size.x||svg.X)+10 var _target, text = target.Value(mdb.TEXT); can.ondetail._select(can, text, function(target) { _target = target, text = target.Value(html.INNER) })
data[size.y||svg.Y] = target.Val(size.y||svg.Y)+10 return can.user.input(event, can, [{name: html.LABEL, value: text}], function(list) {
return can.onfigure._push(can, target.tagName, data, can.group||can.svg) if (_target) { _target.Value(html.INNER, list[0]); return } if (can.page.tagis(target, html.TEXT)) { target.innerHTML = list[0]; return }
}, target.Value(mdb.TEXT, can.onexport._pid(can, can.onimport.block(can, html.TEXT, can.onexport._text(can, target, can.onfigure._get(can, target), {inner: list[0]}), target.Group()) ))
_move: function(can, target, list) { })
can.core.List(list||target.Value(ice.SHIP), function(ship) { },
ship.target = can.page.Select(can, can.svg, ice.PT+ship.pid)[0] remove: function(event, can) { event = event._events||event; var target = event.target; if (target == can.ui.svg) { return }
var p = can.onexport.anchor(target, ship.anchor, {}) can.core.List(target.Value(svg.SHIP), function(item) { can.ondetail._select(can, item.pid, function(target) { can.page.Remove(can, target) }) })
if (ship.which == 1) { can.ondetail._select(can, target.Value(mdb.TEXT), function(target) { can.page.Remove(can, target) }), can.page.Remove(can, target)
ship.target.Val("x1", p.x), ship.target.Val("y1", p.y) },
} else if (ship.which == 2) { })
ship.target.Val("x2", p.x), ship.target.Val("y2", p.y) Volcanos(chat.ONEXPORT, {list: [svg.GROUP, svg.FIGURE, ctx.INDEX, "pos"],
} _point: function(event, can) { var p = can.ui.svg.getBoundingClientRect(), point = {x: event.clientX-p.x, y: event.clientY-p.y}
}) point.x = point.x - point.x % can.onexport.grid(can), point.y = point.y - point.y % can.onexport.grid(can)
}, return can.Status("pos", point.x+mdb.FS+point.y), point
},
svg: { // <svg height="200" width="600" count="0" grid="10" stroke-width="2" stroke="yellow" fill="purple" font-size="24"/> _pid: function(can, target) { if (target.Value(svg.PID)) { return target.Value(svg.PID) }
data: {size: {}, copy: []}, var pid = "p"+can.ui.svg.Val(mdb.COUNT, can.ui.svg.Val(mdb.COUNT)+1)
show: function(can, target, figure) { return can.onexport._size(can, target, figure) } return target.Value(html.CLASS, [target.Value(html.CLASS), target.Value(svg.PID, pid)].join(lex.SP).trim()), pid
}, },
text: { // <text x="60" y="10">hi<text> _text: function(can, target, figure, data) { var trans = can.core.Value(figure.data, svg.TRANS)||{}
data: {points: 1, size: {}, copy: [html.INNER]}, if (figure.text) { return figure.text(can, target, data) }
draw: function(event, can, point, style) { if (point.length < 1 || event.type == "mousemove") { return } return data.x = target.Val(trans[svg.X]||svg.X), data.y = target.Val(trans[svg.Y]||svg.Y), data
var p0 = point[0], text = style&&style.inner||can.user.prompt(mdb.TEXT) },
return text? {x: p0.x, y: p0.y, inner: text}: null _size: function(can, target, figure) { var trans = can.core.Value(figure.data, svg.TRANS)||{}
}, return "<("+target.Val(trans[html.WIDTH]||html.WIDTH)+mdb.FS+target.Val(trans[html.HEIGHT]||html.HEIGHT)+")"
show: function(can, target, figure) { return can.onexport._position(can, target, figure) } },
}, _position: function(can, target, figure) { var trans = can.core.Value(figure.data, svg.TRANS)||{}
circle: { // <circle r="20" cx="25" cy="75"/> return "@("+target.Val(trans[svg.X]||svg.X)+mdb.FS+target.Val(trans[svg.Y]||svg.Y)+")"
data: {points: 2, size: {height: svg.R, width: svg.R, x: "cx", y: "cy"}, copy: [svg.R]}, },
draw: function(event, can, point) { if (point.length < 2) { return } _show: function(can, target) { var figure = can.onfigure._get(can, target)
var p0 = point[0], p1 = point[1] function show() { return can.onexport._position(can, target, figure)+lex.SP+can.onexport._size(can, target, figure) }
return {r: parseInt(Math.sqrt(Math.pow(p0.x-p1.x, 2)+Math.pow(p0.y-p1.y, 2))), cx: p0.x, cy: p0.y} can.Status(svg.FIGURE, can.core.Keys(target.tagName, target.Value(svg.PID))+lex.SP+(figure? (figure.show||show)(can, target, figure): ""))
}, can.Status(svg.GROUP, target.Groups()||can.ui.group.Groups()||html.SVG)
}, can.Status(ctx.INDEX, target.Value(ctx.INDEX)||"")
ellipse: { // <ellipse ry="5" rx="20" cx="75" cy="75"/> },
data: {points: 2, size: {height: "ry", width: "rx", x: "cx", y: "cy"}, copy: ["ry", "rx"]}, content: function(can, target) {
draw: function(event, can, point) { if (point.length < 2) { return } return ['<svg xmlns="https://www.w3.org/2000/svg" vertion="1.1" text-anchor="middle" dominant-baseline="middle"'].concat(
var p0 = point[0], p1 = point[1] target? can.core.List([mdb.COUNT, svg.PID], function(item) { return target.Value(item)? can.base.joinKV([item, target.Value(item)], mdb.EQ): ""}).join(lex.SP): "").concat([">", target? target.innerHTML: "", "</svg>"]).join("")
return {ry: Math.abs(p0.y - p1.y), rx: Math.abs(p0.x - p1.x), cx: p0.x, cy: p0.y} },
}, grid: function(can) { var grid = can.Action(svg.GRID); return grid == svg.GRID || grid == ice.AUTO? 10: grid },
}, _cursor: function(can, cursor) { can.page.style(can, can.ui.svg, {cursor: cursor}) },
rect: { // <rect height="30" width="30" ry="10" rx="10" x="60" y="10"/> cursor: function(event, can, target) {
data: {points: 2, ry: 4, rx: 4, size: {}, copy: [html.HEIGHT, html.WIDTH, "ry", "rx"]}, var p = target.getBoundingClientRect(), q = {x: event.clientX, y: event.clientY}, pos = 5, margin = 20
draw: function(event, can, point) { if (point.length < 2) { return } var y = (q.y-p.y)/p.height; if (y < 0.2 && q.y-p.y < margin) { pos -= 3 } else if (y > 0.8 && q.y-p.y-p.height > -margin) { pos += 3 }
var p0 = point[0], p1 = point[1] var x = (q.x-p.x)/p.width; if (x < 0.2 && q.x-p.x < margin) { pos -= 1 } else if (x > 0.8 && q.x-p.x- p.width > -margin) { pos += 1 }
return { return can.ui.svg.style.cursor = ["nw-resize", "n-resize", "ne-resize", "w-resize", html.MOVE, "e-resize", "sw-resize", "s-resize", "se-resize"][pos-1], pos
height: Math.abs(p0.y-p1.y), width: Math.abs(p0.x-p1.x), ry: this.data.ry, rx: this.data.rx, },
x: p0.x > p1.x? p1.x: p0.x, y: p0.y > p1.y? p1.y: p0.y, anchor: function(target, pos, point) {
} switch (pos) {
}, case 1:
text: function(can, data, target) { return data.x = target.Val(svg.X)+target.Val(html.WIDTH)/2, data.y = target.Val(svg.Y)+target.Val(html.HEIGHT)/2, data }, case 2:
}, case 3: point.y = target.Val(svg.Y); break
block: { // <rect height="30" width="30" ry="10" rx="10" x="60" y="10"/> case 4:
data: {points: 2, ry: 4, rx: 4, size: {}, copy: [html.HEIGHT, html.WIDTH, "ry", "rx"]}, case 5:
draw: function(event, can, point) { if (point.length < 2) { return } case 6: point.y = target.Val(svg.Y) + target.Val(html.HEIGHT)/2; break
this._temp && can.page.Remove(can, this._temp) && delete(this._temp) case 7:
this._temp = can.onfigure._push(can, svg.G, {}, can.group||can.svg) case 8:
case 9: point.y = target.Val(svg.Y) + target.Val(html.HEIGHT); break
var rect = can.onfigure._push(can, "rect", can.onfigure.rect.draw(event, can, point), this._temp) }
if (event.type == html.CLICK) { switch (pos) {
can.onfigure._pid(can, rect), delete(this._temp) case 1:
} case 4:
}, case 7: point.x = target.Val(svg.X); break
text: function(can, data, target) { can.onfigure.rect.text(can, data, target) }, case 2:
}, case 5:
line: { // <line x1="10" y1="50" x2="110" y2="150" xx="100" yy="100"/> case 8: point.x = target.Val(svg.X) + target.Val(html.WIDTH)/2; break
data: {points: 2, size: {x: "x1", y: "y1"}, copy: ["x1", "y1", "x2", "y2"]}, case 3:
grid: function(event, can, point) { var target = event.target case 6:
if (target == can.svg) { return } case 9: point.x = target.Val(svg.X) + target.Val(html.WIDTH); break
var p = point[point.length-1], pos = can.onexport.cursor(event, can, target) } return point
target.Val && can.onexport.anchor(target, pos, p) },
return p.target = target, p.anchor = pos, point resize: function(target, pos, p0, p1, begin) {
}, if (pos == 5) { target.Value(svg.X, begin.x + p1.x - p0.x), target.Value(svg.Y, begin.y + p1.y - p0.y); return }
draw: function(event, can, point) { if (point.length < 2) { return } switch (pos) {
var p0 = point[0], p1 = point[1], ship = [] case 1:
p0.target && p0.target.Value && ship.push({pid: p0.target.Value("pid")}) case 2:
p1.target && p1.target.Value && ship.push({pid: p1.target.Value("pid")}) case 3: target.Value(svg.Y, begin.y + p1.y - p0.y), target.Value(html.HEIGHT, begin.height - p1.y + p0.y); break
return {x1: p0.x, y1: p0.y, x2: p1.x, y2: p1.y, ship: ship} case 7:
}, case 8:
text: function(can, target, data) { return data.x = (target.Val("x1")+target.Val("x2"))/2, data.y = (target.Val("y1")+target.Val("y2"))/2, data }, case 9: target.Value(html.HEIGHT, begin.height + p1.y - p0.y); break
show: function(can, target, figure) { return "<("+(target.Val("y2")-target.Val("y1"))+ice.FS+(target.Val("x2")-target.Val("x1"))+")"+can.onexport._position(can, target, figure) }, }
}, switch (pos) {
case 1:
case 4:
case 7: target.Value(svg.X, begin.x + p1.x - p0.x), target.Value(html.WIDTH, begin.width - p1.x + p0.x); break
case 3:
case 6:
case 9: target.Value(html.WIDTH, begin.width + p1.x - p0.x); break
}
},
})
Volcanos(chat.ONFIGURE, {
_get: function(can, target, name) { return can.onfigure[name]||can.onfigure[target.getAttribute(mdb.NAME)]||can.onfigure[target.tagName] },
svg: {show: function(can, target, figure) { return can.onexport._size(can, target, figure) }},
rect: { // <rect x="60" y="10" height="30" width="30" rx="10" ry="10"/>
data: {points: 2, rx: 4, ry: 4, copy: [html.HEIGHT, html.WIDTH, svg.RX, svg.RY]},
draw: function(event, can, points, style) { var p0 = points[0], p1 = points[1]
return {x: Math.min(p0.x, p1.x), y: Math.min(p0.y, p1.y), height: Math.abs(p0.y-p1.y), width: Math.abs(p0.x-p1.x), rx: style.rx == undefined? this.data.rx: style.rx, ry: style.ry == undefined? this.data.ry: style.ry}
},
text: function(can, target, data) { return data.x = target.Val(svg.X)+target.Val(html.WIDTH)/2, data.y = target.Val(svg.Y)+target.Val(html.HEIGHT)/2, data },
},
line: { // <line x1="10" y1="10" x2="110" y2="150"/>
data: {points: 2, trans: {x: svg.X1, y: svg.Y1}, copy: [svg.X1, svg.Y1, svg.X2, svg.Y2]},
grid: function(event, can, points) { var target = event.target; if (target == can.ui.svg) { return }
var p = points[points.length-1], pos = can.onexport.cursor(event, can, target); can.onexport.anchor(target, pos, p)
return p.target = target, p.anchor = pos, points
},
draw: function(event, can, points) { var p0 = points[0], p1 = points[1], ship = []
p0.target && p0.target.Value && ship.push({pid: p0.target.Value(svg.PID)})
p1.target && p1.target.Value && ship.push({pid: p1.target.Value(svg.PID)})
return {x1: p0.x, y1: p0.y, x2: p1.x, y2: p1.y, ship: ship.length > 0? ship: undefined}
},
text: function(can, target, data) { return data.x = (target.Val(svg.X1)+target.Val(svg.X2))/2, data.y = (target.Val(svg.Y1)+target.Val(svg.Y2))/2, data },
show: function(can, target, figure) { return can.onexport._position(can, target, figure)+" <("+(target.Val(svg.X2)-target.Val(svg.X1))+mdb.FS+(target.Val(svg.Y2)-target.Val(svg.Y1))+")" },
},
text: { // <text x="60" y="10">hi</text>
data: {points: 1, copy: [html.INNER]},
draw: function(event, can, points, style) { if (event.type == "mousemove") { return }
var p0 = points[0]; return {x: p0.x, y: p0.y, inner: style.inner||can.user.prompt(mdb.TEXT)}
},
show: function(can, target, figure) { return can.onexport._position(can, target, figure) }
},
block: { // <rect x="60" y="10" height="30" width="30" rx="10" ry="10"/>
data: {points: 2, rx: 4, ry: 4, copy: [html.HEIGHT, html.WIDTH, svg.RX, svg.RY]},
draw: function(event, can, points, style) { var group = can.onaction._group(can)
var target = can.onimport.block(can, svg.RECT, can.onfigure.rect.draw(event, can, points, style), group)
if (event.type == html.CLICK) { can.onexport._pid(can, target), delete(can._temp) }
},
text: function(can, target, data) { can.onfigure.rect.text(can, data, target) },
},
circle: { // <cx="25" cy="75" r="20"/>
data: {points: 2, trans: {x: svg.CX, y: svg.CY, height: svg.R, width: svg.R}, copy: [svg.R]},
draw: function(event, can, points) { var p0 = points[0], p1 = points[1]; return {cx: p0.x, cy: p0.y, r: parseInt(Math.sqrt(Math.pow(p0.x-p1.x, 2)+Math.pow(p0.y-p1.y, 2)))} },
},
ellipse: { // <ellipse cx="75" cy="75" rx="20" ry="5"/>
data: {points: 2, trans: {x: svg.CX, y: svg.CY, height: svg.RY, width: svg.RX}, copy: [svg.RY, svg.RX]},
draw: function(event, can, points) { var p0 = points[0], p1 = points[1]; return {cx: p0.x, cy: p0.y, ry: Math.abs(p0.y - p1.y), rx: Math.abs(p0.x - p1.x)} },
},
}, []) }, [])
Volcanos("onkeypop", {help: "键盘交互", list: [], Volcanos(chat.ONKEYMAP, {
_mode: { _mode: {
normal: { plugin: {
gr: function(event, can) { can.Action("go", "run") }, Escape: function(event, can) { can._undo && can._undo(), can.ui.points = [] },
ga: function(event, can) { can.Action("go", "auto") }, gr: function(event, can) { can.ActionGo(ctx.RUN) },
gm: function(event, can) { can.Action("go", "manual") }, ga: function(event, can) { can.ActionGo(ice.AUTO) },
gm: function(event, can) { can.ActionGo("manual") },
ad: function(event, can) { can.Action("mode", "draw") }, ad: function(event, can) { can.ActionMode(web.DRAW) },
ar: function(event, can) { can.Action("mode", "resize") }, am: function(event, can) { can.ActionMode(html.MOVE) },
ar: function(event, can) { can.ActionMode(html.RESIZE) },
st: function(event, can) { can.Action("shape", "text") }, st: function(event, can) { can.ActionShape(svg.TEXT) },
sr: function(event, can) { can.Action("shape", "rect") }, sr: function(event, can) { can.ActionShape(svg.RECT) },
sl: function(event, can) { can.Action("shape", "line") }, sl: function(event, can) { can.ActionShape(svg.LINE) },
sc: function(event, can) { can.Action("shape", "circle") }, ss: function(event, can) { can.ActionShape(svg.LINE) },
se: function(event, can) { can.Action("shape", "ellipse") }, sc: function(event, can) { can.ActionShape(svg.CIRCLE) },
se: function(event, can) { can.ActionShape(svg.ELLIPSE) },
cr: function(event, can) { can.onaction._change(can, "stroke", "red") }, cr: function(event, can) { can.onaction._change(can, svg.STROKE, cli.RED) },
cb: function(event, can) { can.onaction._change(can, "stroke", "blue") }, cb: function(event, can) { can.onaction._change(can, svg.STROKE, cli.BLUE) },
cg: function(event, can) { can.onaction._change(can, "stroke", "green") }, cg: function(event, can) { can.onaction._change(can, svg.STROKE, cli.GREEN) },
cy: function(event, can) { can.onaction._change(can, "stroke", "yellow") }, cy: function(event, can) { can.onaction._change(can, svg.STROKE, cli.YELLOW) },
cp: function(event, can) { can.onaction._change(can, "stroke", "purple") }, cp: function(event, can) { can.onaction._change(can, svg.STROKE, cli.PURPLE) },
cc: function(event, can) { can.onaction._change(can, "stroke", "cyan") }, cc: function(event, can) { can.onaction._change(can, svg.STROKE, cli.CYAN) },
ch: function(event, can) { can.onaction._change(can, "stroke", "black") }, ch: function(event, can) { can.onaction._change(can, svg.STROKE, cli.BLACK) },
cw: function(event, can) { can.onaction._change(can, "stroke", "white") }, cw: function(event, can) { can.onaction._change(can, svg.STROKE, cli.WHITE) },
fr: function(event, can) { can.onaction._change(can, "fill", "red") }, fr: function(event, can) { can.onaction._change(can, svg.FILL, cli.RED) },
fb: function(event, can) { can.onaction._change(can, "fill", "blue") }, fb: function(event, can) { can.onaction._change(can, svg.FILL, cli.BLUE) },
fg: function(event, can) { can.onaction._change(can, "fill", "green") }, fg: function(event, can) { can.onaction._change(can, svg.FILL, cli.GREEN) },
fy: function(event, can) { can.onaction._change(can, "fill", "yellow") }, fy: function(event, can) { can.onaction._change(can, svg.FILL, cli.YELLOW) },
fp: function(event, can) { can.onaction._change(can, "fill", "purple") }, fp: function(event, can) { can.onaction._change(can, svg.FILL, cli.PURPLE) },
fc: function(event, can) { can.onaction._change(can, "fill", "cyan") }, fc: function(event, can) { can.onaction._change(can, svg.FILL, cli.CYAN) },
fh: function(event, can) { can.onaction._change(can, "fill", "black") }, fh: function(event, can) { can.onaction._change(can, svg.FILL, cli.BLACK) },
fw: function(event, can) { can.onaction._change(can, "fill", "white") }, fw: function(event, can) { can.onaction._change(can, svg.FILL, cli.WHITE) },
}, },
}, _engine: {}, }, _engine: {},
}) })
Volcanos("onaction", {help: "组件菜单", list: [
["stroke-width", 1, 2, 3, 4, 5],
["stroke", cli.RED, cli.YELLOW, cli.GREEN, cli.CYAN, cli.BLUE, cli.PURPLE, cli.BLACK, cli.WHITE],
["fill", cli.RED, cli.YELLOW, cli.GREEN, cli.CYAN, cli.BLUE, cli.PURPLE, cli.BLACK, cli.WHITE, "#0000"],
["font-size", 12, 16, 18, 24, 32],
["go", ice.RUN, ice.AUTO, "manual"],
["mode", "draw", "resize"],
["shape", "text", "circle", "ellipse", "rect", "block", "line"],
["grid", 1, 2, 3, 4, 5, 10, 20],
],
_change: function(can, key, value) { can.Action(key, value), can.group.Value(key, value) },
"stroke-width": function(event, can, key, value) { can.onaction._change(can, key, value) },
stroke: function(event, can, key, value) { can.onaction._change(can, key, value) },
fill: function(event, can, key, value) { can.onaction._change(can, key, value) },
"font-size": function(event, can, key, value) { can.onaction._change(can, key, value) },
go: function(event, can, key, value) { can.Action(key, value) },
mode: function(event, can, key, value) { can.Action(key, value) },
shape: function(event, can, key, value) { can.Action(key, value) },
edit: function(event, can) { can.Action("go", can.Action("go") == ice.RUN? ice.AUTO: ice.RUN) },
save: function(event, can, button) {
var msg = can.request(event, {content: can.onexport.content(can, can.svg)})
can.run(event, [ctx.ACTION, button, can.Option(nfs.PATH)], function(msg) {
can.user.toastSuccess(can)
}, true)
},
project: function(event, can) { can.onmotion.toggle(can, can.ui.project) },
profile: function(event, can) { can.onmotion.toggle(can, can.ui.profile) },
show: function(event, can) { can.onmotion.show(can, {interval: 100, length: 10}, null, can.group) },
hide: function(event, can) { can.onmotion.hide(can, {interval: 100, length: 10}, null, can.group) },
create: function(event, can) {
can.user.prompt("group", "some", function(name) {
var group = document.createElementNS('http://www.w3.org/2000/svg', svg.G)
can.group.append(group), can.onimport._block(can, group)
group.Value(html.CLASS, name), can.core.List([html.STROKE_WIDTH, html.STROKE, html.FILL, html.FONT_SIZE], function(name) {
group.Value(name, can.Action(name))
}), can.onimport._group(can, group).click()
})
},
remove: function(event, can) { if (can.group == can.svg) { return }
can.page.Remove(can, can.group)
},
clear: function(event, can) {
can.onmotion.clear(can, can.group), can.point = [], delete(can.temp)
},
_mode: {
draw: function(event, can, point) {
var shape = can.Action("shape")
var figure = can.onfigure[shape]
figure.grid && figure.grid(event, can, point)
var data = figure.draw && figure.draw(event, can, point)
var item = data && can.onfigure._push(can, figure.data.name||shape, data, can.group||can.svg)
event.type == html.CLICK && point.length === figure.data.points && (can.point = [])
if (event.type == html.CLICK && item) {
var pid = can.onfigure._pid(can, item); can.core.List(point, function(p, i) { if (!p.target) { return }
p.target.Value(ice.SHIP, p.target.Value(ice.SHIP).concat([{pid: pid, which: i+1, anchor: p.anchor}]))
})
}
return item
},
resize: function(event, can, point, target) { target = target||event.target
if (event.type == html.CLICK) {
if (point.length == 1) {
can.current = {target: target, begin: can.core.List([target], function(item) { if (item.tagName == svg.G) { return }
return {
height: item.Val(html.HEIGHT), width: item.Val(html.WIDTH), x: item.Val(svg.X), y: item.Val(svg.Y),
target: item, ship: can.core.List(item.Value(ice.SHIP), function(ship) {
return ship.pid && (ship.target = can.page.Select(can, can.svg, ice.PT+ship.pid)[0]) && ship
})
}
}), pos: can.onexport.cursor(event, can, target)}
return
}
return can.point = [], delete(can.current)
}
can.current && can.core.List(can.current.begin, function(item) { var figure = can.onfigure._get(can, item.target)
can.onexport.resize(event, item.target, item, point[0], point[1], can.current.pos)
can.page.Select(can, can.svg, ice.PT+item.target.Value(mdb.TEXT), function(text) {
text.Value(can.onexport._text(can, item.target, figure, {}))
})
can.onfigure._move(can, item.target, item.ship)
})
},
run: function(event, can) {
can.onimport._profile(can, event.target)
},
},
_auto: function(can, target) {
if (can.point.length > 0) { return }
if (target.tagName == mdb.TEXT) { return }
var pos = can.onexport.cursor(event, can, event.target)
if (target == can.svg) {
if (pos == 5) {
can.Action(ice.MODE, "draw"), can.Action("shape", html.BLOCK)
can.page.Modify(can, target, {style: {cursor: "crosshair"}})
} else {
can.Action(ice.MODE, "resize")
}
} else {
switch (pos) {
case 5:
case 9: can.Action(ice.MODE, "resize"); break
default: can.Action(ice.MODE, "draw"), can.Action("shape", "line")
}
}
},
_figure: function(event, can, points, target) {
can.temp && can.page.Remove(can, can.temp) && delete(can.temp)
can.temp = can.core.CallFunc([can.onaction._mode, can.Action(ice.MODE)], [event, can, points, target])
can.point.length == 0 && delete(can.temp)
},
onmouseover: function(event, can) { can.onexport._show(can, event.target) },
onmousemove: function(event, can) { var point = can.onexport._point(event, can)
if (can.Action("go") == ice.RUN) { return }
can.onexport.cursor(event, can, event.target)
if (can.Action("go") == ice.AUTO) { can.onaction._auto(can, event.target) }
can.onaction._figure(event, can, can.point.concat(point))
},
onclick: function(event, can) { var point = can.onexport._point(event, can)
if (can.Action("go") == ice.RUN) { can.onimport._profile(can, event.target)
return event.shiftKey? can.onaction._mode.run(event, can): can.ondetail.run(event, can)
}
can.onaction._figure(event, can, can.point = can.point.concat(point))
},
ondblclick: function(event, can) {
can.ondetail.label(event, can)
},
})
Volcanos("ondetail", {help: "组件详情", list: [cli.START, ice.RUN, ice.COPY, html.LABEL, mdb.MODIFY, mdb.DELETE],
start: function(event, can) { var target = event.target
var list = [target], dict = {}
for (var i = 0; i < list.length; i++) { var ship = list[i].Value("ship")
for (var j = 0; j < ship.length; j++) { var pid = ship[j].pid
can.page.Select(can, can.svg, ice.PT+pid, function(item) {
var pid = item.Value("ship")[1].pid
can.page.Select(can, can.svg, ice.PT+pid, function(item) {
!dict[pid] && list.push(item), dict[pid] = true
})
})
}
}
can.core.Next(list, function(item, next) { can.core.Timer(3000, function() {
can.onmotion.show(can, {interval: 300, length: 10}, null, item)
can.user.toast(can, item.Value("index"))
can.ondetail.run({target: item}, can), next()
}) })
},
run: function(event, can) { var target = event.target
if (!target.Value("pid")) { can.onfigure._pid(can, target) }
can._pid && can.page.Cache(can._pid, can.ui.display, "some"), can._pid = target.Value("pid")
var cache = can.page.Cache(can._pid, can.ui.display); if (cache) { return }
can.onmotion.clear(can, can.ui.display), can.svg.Value("pid", target.Value("pid"))
var index = target.Value(mdb.INDEX); index && can.onappend.plugin(can, {type: chat.STORY, index: index, args: target.Value(ctx.ARGS)}, function(sub) {
sub.Conf("height", can.Conf("height")-can.svg.Val("height")-52), sub.Conf("width", can.Conf("width"))
sub.run = function(event, cmds, cb) { can.run(event, can.misc.concat([ice.RUN, index], cmds), cb, true) }
can.onmotion.hidden(can, sub._legend), can.onmotion.hidden(can, can.ui.display, true)
}, can.ui.display)
},
copy: function(event, can) { can.onfigure._copy(event, can, event.target) },
label: function(event, can) { var target = event.target
var def = target.Value(mdb.TEXT); def && can.page.Select(can, can.svg, ice.PT+def, function(item) {
def = item.Value(html.INNER)
})
can.user.prompt(html.LABEL, def, function(text) {
if (target.tagName == html.TEXT) { return target.innerHTML = text }
if (def && can.page.Select(can, can.svg, ice.PT+def, function(item) {
item.Value(html.INNER, text)
}).length > 0) {
return
}
var figure = can.onfigure._get(can, target)
var data = can.onexport._text(can, target, figure, {inner: text})
var item = can.onfigure._push(can, html.TEXT, data, target.Group())
target.Value(mdb.TEXT, can.onfigure._pid(can, item))
})
},
modify: function(event, can) { can.onimport._profile(can, event.target) },
"delete": function(event, can) { var target = event.target
if (target == can.svg) { return }
can.core.List(target.Value(ice.SHIP), function(value) {
can.page.Select(can, can.svg, ice.PT+value.pid, function(item) {
can.page.Remove(can, item)
})
})
target.Value(mdb.TEXT) && can.page.Select(can, can.svg, ice.PT+target.Value(mdb.TEXT), function(item) {
can.page.Remove(can, item)
})
can.page.Remove(can, target)
},
})
Volcanos("onexport", {help: "导出数据", list: ["group", "figure", "index", "pos"],
_show: function(can, target) { var figure = can.onfigure._get(can, target)
function show() { return can.onexport._size(can, target, figure)+ice.SP+can.onexport._position(can, target, figure) }
can.Status("figure", target.tagName+":"+target.Value("pid")+ice.SP+(figure? (figure.show||show)(can, target, figure): ""))
can.Status("group", target.Groups()||can.group.Groups()||html.SVG)
can.Status("index", target.Value("index"))
},
_size: function(can, target, figure) { var size = figure.data.size||{}
return "<("+target.Val(size[html.HEIGHT]||html.HEIGHT)+ice.FS+target.Val(size[html.WIDTH]||html.WIDTH)+")"
},
_position: function(can, target, figure) { var size = figure.data.size||{}
return "@("+target.Val(size[svg.X]||svg.X)+ice.FS+target.Val(size[svg.Y]||svg.Y)+")"
},
_text: function(can, target, figure, data) { var size = figure.data.size||{}
if (figure.text) { return figure.text(can, data, target) }
return data.x = target.Val(size[svg.X]||svg.X), data.y = target.Val(size[svg.Y]||svg.Y), data
},
_point: function(event, can) {
var p = can.svg.getBoundingClientRect()
var point = {x: event.clientX-p.x, y: event.clientY-p.y}
point.x = point.x - point.x % parseInt(can.Action("grid"))
point.y = point.y - point.y % parseInt(can.Action("grid"))
return can.Status("pos", point.x+ice.FS+point.y), point
},
content: function(can, svg) {
return ['<svg vertion="1.1" xmlns="https://www.w3.org/2000/svg" text-anchor="middle" dominant-baseline="middle"'].concat(
svg? can.core.List([html.HEIGHT, html.WIDTH, mdb.COUNT, "pid", "grid", html.STROKE_WIDTH, html.STROKE, html.FILL, html.FONT_SIZE], function(item) {
return svg.Value(item)? ice.SP + item + '="' + svg.Value(item) + '"': ""
}): [" height="+((can.Conf(html.HEIGHT)||450)-50)+" width="+(can.Conf(html.WIDTH)||600)]).concat(['>', svg? svg.innerHTML: "", "</svg>"]).join("")
},
cursor: function(event, can, item, show) {
var p = item.getBoundingClientRect()
var q = {x: event.clientX, y: event.clientY}
var pos = 5, margin = 20
var y = (q.y-p.y)/p.height
if (y < 0.2 && q.y-p.y < margin) {
pos -= 3
} else if (y > 0.8 && q.y-p.y-p.height > -margin) {
pos += 3
}
var x = (q.x-p.x)/p.width
if (x < 0.2 && q.x-p.x < margin) {
pos -= 1
} else if (x > 0.8 && q.x-p.x- p.width > -margin) {
pos += 1
}
return (show||can.svg).style.cursor = [
"nw-resize", "n-resize", "ne-resize",
"w-resize", "move", "e-resize",
"sw-resize", "s-resize", "se-resize",
][pos-1], pos
},
anchor: function(target, pos, point) {
switch (pos) {
case 1:
case 2:
case 3:
point.y = target.Val(svg.Y)
break
case 4:
case 5:
case 6:
point.y = target.Val(svg.Y) + target.Val(html.HEIGHT) / 2
break
case 7:
case 8:
case 9:
point.y = target.Val(svg.Y) + target.Val(html.HEIGHT)
break
}
switch (pos) {
case 1:
case 4:
case 7:
point.x = target.Val(svg.X)
break
case 2:
case 5:
case 8:
point.x = target.Val(svg.X) + target.Val(html.WIDTH) / 2
break
case 3:
case 6:
case 9:
point.x = target.Val(svg.X) + target.Val(html.WIDTH)
break
}
return point
},
resize: function(event, item, begin, p0, p1, pos) {
switch (pos) {
case 5:
item.Value(svg.X, begin.x + p1.x - p0.x)
item.Value(svg.Y, begin.y + p1.y - p0.y)
return
}
switch (pos) {
case 1:
case 2:
case 3:
item.Value(svg.Y, begin.y + p1.y - p0.y)
item.Value(html.HEIGHT, begin.height - p1.y + p0.y)
break
}
switch (pos) {
case 1:
case 4:
case 7:
item.Value(sve.X, begin.x + p1.x - p0.x)
item.Value(html.WIDTH, begin.width - p1.x + p0.x)
break
}
switch (pos) {
case 3:
case 6:
case 9:
item.Value(html.WIDTH, begin.width + p1.x - p0.x)
break
}
switch (pos) {
case 7:
case 8:
case 9:
item.Value(html.HEIGHT, begin.height + p1.y - p0.y)
break
}
},
})

View File

@ -1,4 +1,4 @@
Volcanos("heart", {help: "心形", list: [], Volcanos("heart", {
data: {name: "path", size: {}, data: {name: "path", size: {},
copy: ["d", "name", "meta", "tt", "xx", "yy"], copy: ["d", "name", "meta", "tt", "xx", "yy"],
x: function(event, can, value, cmd, target) { x: function(event, can, value, cmd, target) {
@ -57,4 +57,3 @@ Volcanos("heart", {help: "心形", list: [],
return "heart " + target.Value("tt") return "heart " + target.Value("tt")
}, },
}) })

View File

@ -1,4 +1,4 @@
Volcanos("onfigure", {help: "图形绘制", list: [], Volcanos(chat.ONFIGURE, {
path2v: { // <path d="M x0,y0 Q x2,y2 x3,y3 T x1,y1"/> path2v: { // <path d="M x0,y0 Q x2,y2 x3,y3 T x1,y1"/>
data: {name: "path", size: {}, copy: []}, data: {name: "path", size: {}, copy: []},
draw: function(event, can, point) { draw: function(event, can, point) {
@ -60,7 +60,8 @@ Volcanos("onfigure", {help: "图形绘制", list: [],
if (i < skip) {return} if (i < skip) {return}
switch (i) { switch (i) {
case 0: k = "M"; break case 0: k = "M"; break
default: k = can._temp[i] || p.k || "L"; break default: k = p.k || "L"; break
// default: k = can._temp[i] || p.k || "L"; break
} }
if (end) {return} if (end) {return}
@ -149,4 +150,3 @@ Volcanos("onfigure", {help: "图形绘制", list: [],
show: function(can, target) { return target.tagName + " " + target.Value("d") }, show: function(can, target) { return target.tagName + " " + target.Value("d") },
}, },
}) })

View File

@ -1,8 +1,8 @@
Volcanos("onimport", {help: "导入数据", list: [], Volcanos(chat.ONIMPORT, {
init: function(can, msg, cb, output, action, option) {output.innerHTML = ""; init: function(can, msg, cb, output, action, option) {output.innerHTML = "";
if (!msg.result || msg.result.length == 0) { if (!msg.result || msg.result.length == 0) {
var table = can.page.AppendTable(can, msg, output, msg.append); var table = can.page.AppendTable(can, msg, output, msg.append);
table.onclick = function(event) {switch (event.target.tagName) { table.onclick = function(event) { can.misc.Event(event, can, function(msg) { switch (event.target.tagName) {
case "TD": case "TD":
can.onimport.which(event, table, msg.append, function(index, key) { can.onimport.which(event, table, msg.append, function(index, key) {
can.Option("file", event.target.innerHTML.trim()) can.Option("file", event.target.innerHTML.trim())
@ -13,7 +13,7 @@ Volcanos("onimport", {help: "导入数据", list: [],
break break
case "TR": case "TR":
case "TABLE": case "TABLE":
}} } }) }
return can.base.isFunc(cb) && cb(msg), table; return can.base.isFunc(cb) && cb(msg), table;
} }
@ -147,4 +147,3 @@ Volcanos("onimport", {help: "导入数据", list: [],
}) })
}, },
}) })

View File

@ -1,14 +1,44 @@
fieldset.feel div.output img { fieldset.feel>form.option>div.item.file { display:none; }
display:block; float:left; body.mobile fieldset.feel>form.option>div.item.file { display:none; }
} fieldset.feel.fullscreen>div.action>div.item:not(.fullscreen) { display:none; }
fieldset.feel div.output video { fieldset.feel>div.output>div.project>div.albums { display:flex; flex-wrap:wrap; }
display:block; float:left; fieldset.feel>div.output>div.project>div.albums>div.item.album { border-bottom:var(--box-notice3); border-color:transparent; width:33.3%; display:flex; flex-direction:column; }
} fieldset.feel>div.output>div.project>div.albums>div.item.album.select { border-bottom:var(--box-notice3); border-right:none; }
fieldset.feel.float>legend { fieldset.feel>div.output>div.project>div.albums>div.item.album.create { height:calc(var(--project-width)/3 - 10px); font-size:42px; display:flex; justify-content:center; align-items:center; }
display:none; fieldset.feel>div.output>div.project>div.albums>div.item.album img { height:calc(var(--project-width)/3 - 10px); width:100%; object-fit:cover; }
} fieldset.feel>div.output>div.project>div.item.select { border-width:3px; }
fieldset.feel.float { fieldset.feel>div.output>div.project>div.item>img { padding:5px; }
margin:0 10px; padding:0 10px; fieldset.feel>div.output>div.project>div.item>span.name { flex-grow:1; overflow:hidden; }
background-color:#4eaad0c2; fieldset.feel>div.output>div.project>div.item>span.progress { color:var(--notice-bg-color); margin-left:10px; }
position:absolute; fieldset.feel>div.output>div.project>div.item>span.size { color:var(--disable-fg-color); font-size:var(--status-font-size); margin-left:10px; }
} fieldset.feel>div.output>div.project>div.item>span.time { color:var(--disable-fg-color); font-size:var(--status-font-size); margin-left:10px; }
fieldset.feel>div.output>div.layout>div.display { overflow:hidden; position:relative; }
fieldset.feel>div.output>div.layout>div.display:not(.hide) { height:100px; display:flex; justify-content:center; align-items:center; gap:10px; }
fieldset.feel>div.output>div.layout>div.display>.select { border:var(--box-notice); border-width:3px; }
fieldset.feel>div.output>div.layout>div.display>img { height:100px; width:100px; object-fit:contain; }
fieldset.feel>div.output>div.layout>div.display>video { height:100px; width:100px; object-fit:contain; }
fieldset.feel>div.output>div.layout>div.display>div.audio { word-break:break-all; height:100px; width:100px; display:flex; align-items:end; }
fieldset.feel>div.output>div.layout>div.display>div.audio:not(.select) { border:var(--box-border); }
fieldset.feel>div.output>div.layout>div.display>div.audio img.cover { height:98px; width:98px; position:absolute; }
fieldset.feel>div.output>div.layout>div.display>div.audio.select img.cover { height:94px; width:94px; position:absolute; }
fieldset.feel>div.output>div.layout>div.display>div.audio span.name { background-color:var(--hover-bg-color); color:white; z-index:5; }
fieldset.feel>div.output>div.layout>div.display>*.select { background-color:var(--hover-bg-color); }
fieldset.feel>div.output>div.layout>div.display>*:hover { background-color:var(--hover-bg-color); cursor:pointer; }
fieldset.feel>div.output>div.layout>div.display>img:hover { background-color:var(--hover-bg-color); cursor:pointer; }
fieldset.feel>div.output>div.layout>div.display>video:hover { background-color:var(--hover-bg-color); cursor:pointer; }
fieldset.feel>div.output>div.layout>div.display>div.audio:hover { background-color:var(--hover-bg-color); cursor:pointer; }
fieldset.feel>div.output>div.layout>div.display>div.toggle { font-size:32px; padding:5px; padding-top:32px; height:100px; position:absolute; }
fieldset.feel>div.output>div.layout>div.display>div.toggle.prev { left:0; }
fieldset.feel>div.output>div.layout>div.display>div.toggle.next { right:0; }
fieldset.feel>div.output>div.layout>div.layout>div.content { padding:0; overflow:hidden; }
fieldset.feel>div.output>div.layout>div.layout>div.content>img { height:100%; width:100%; object-fit:scale-down; cursor:pointer; }
fieldset.feel>div.output>div.layout>div.layout>div.content>video { height:100%; width:100%; }
fieldset.feel>div.output>div.layout>div.layout>div.content>div.audio { height:100%; width: 100%; display:flex; flex-direction:column; justify-content:center; align-items:center; }
fieldset.feel>div.output>div.layout>div.layout>div.content>div.audio img.cover { height:calc(100% - 120px); }
fieldset.feel>div.output>div.layout>div.layout>div.content>div.audio span.name { padding:10px; }
fieldset.feel>div.output>div.layout>div.layout>div.content>div.progress { background-color:var(--notice-bg-color); height:3px; position:absolute; bottom:2px; }
fieldset.feel>div.output>div.layout>div.layout>div.content>div.toggle { font-size:32px; padding:5px; padding-top:32px; height:100px; top:40%; z-index:5; }
fieldset.feel>div.output>div.layout>div.layout>div.content>div.toggle.next { right:0; }
fieldset.feel>div.output>div.layout>div.layout>div.content>div.toggle.prev { left:0; }
div.toggle { -webkit-user-select:none; }
img { -webkit-user-select:none; }

View File

@ -1,125 +1,206 @@
Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) { Volcanos(chat.ONIMPORT, {
can.path = can.request(), can.list = [], msg.Table(function(value) { _init: function(can, msg, cb) { can.onappend.style(can, wiki.FEEL)
value.path.lastIndexOf(ice.PS)==value.path.length-1? can.path.Push(value): can.list.push(value) can.run({}, [], function(_msg) { can.db.albums = _msg
}) can.ui = can.onappend.layout(can)
// can.user.isMobile && (can.onaction.list = [web.UPLOAD])
can.base.isFunc(cb) && cb(msg) cb && cb(msg)
can.ui = can.onlayout.display(can, target) if (can.base.isIn(can.Action("sort")||"", mdb.TIME, "")) {
can.onappend.table(can, can.path, null, can.ui.content) can.onimport._project(can, msg)
can.dir_root = msg.Option("dir_root") } else {
can.onaction.sort({}, can, "sort", can.Action("sort"))
can.Action("height", msg.Option("height")||"100") } can.onimport.page(can, can.db.list, can.db.begin = 0)
can.Action("limit", msg.Option("limit")||"6") can.onmotion.toggle(can, can.ui.display, can.page.isDisplay(can.ui.project)), can.onimport.layout(can)
can.Action("rate", msg.Option("rate")||"1") })
can.onmotion.hidden(can, can._action) can.onmotion.toggle(can, can._action, true)
},
can.begin = msg.Option("begin")||"0" _project: function(can, msg) { can.db.list = [], can.db.dir_root = msg.Option(nfs.DIR_ROOT)
can.onimport.page(can, can.list) can.ui.albums = can.page.Appends(can, can.ui.project, ["albums"])._target
}, can.db.albums.Table(function(value) {
_file: function(can, path, index) { var p = location.href.indexOf("http") == 0? "": "http://localhost:9020" can.page.Append(can, can.ui.albums, [{view: "item album "+(can.base.beginWith(can.Option(nfs.PATH), value.path)? "select": ""), background: value.cover, list: [
return path.indexOf("http") == 0? path: p+can.base.Path("/share/local", can.dir_root||"", path) {img: can.misc.Resource(can, value.cover||"usr/icons/background.jpg")}, {text: value.name},
}, ], onclick: function(event) {
file: function(can, path, index) { path = can.onimport._file(can, path, index) can.Option(nfs.PATH, value.path), can.Update()
var cb = can.onfigure[can.base.Ext(path)]; can.Status("file", path) }, oncontextmenu: function(event) {
can.base.isFunc(cb) && can.page.Append(can, can.ui.display, [cb(can, path, index)]) can.user.carteItem(event, can, value)
}, }}])
page: function(can, list, begin, limit) { can.onmotion.clear(can, can.ui.display) })
begin = parseInt(begin||can.begin), limit = parseInt(limit||can.Action("limit")) can.page.Append(can, can.ui.albums, [{view: ["item album create", "", "+"], onclick: function(event) {
for (var i = begin; i < begin+limit; i++) { list && list[i] && can.onimport.file(can, list[i].path, i) } can.Update(event, [ctx.ACTION, mdb.CREATE])
can.Status({begin: begin, limit: limit, total: can.list.length}) }}])
}, can.ui.filter = can.onappend.filter(can, can.ui.project)
}, ["/plugin/local/wiki/feel.css"]) msg.Table(function(item) { item.name = can.base.trimPrefix(item.path, can.Option(nfs.PATH))
Volcanos("onfigure", {help: "组件菜单", list: [], can.base.endWith(item.path, "/") && (item.nick = [{img: can.misc.Resource(can, "usr/icons/dir.png")}, {text: [item.name, "", mdb.NAME]}])
png: function(can, path, index) { return can.onfigure.image(can, path, index) }, can.base.endWith(item.path, nfs.PS)? can.onimport.item(can, item, function(event) { can.Option(nfs.PATH, item.path) && can.Update(event) }): can.db.list.push(item)
jpg: function(can, path, index) { return can.onfigure.image(can, path, index) }, })
jpeg: function(can, path, index) { return can.onfigure.image(can, path, index) }, can.onmotion.cacheClear(can, "", can.ui.content)
image: function(can, path, index) { return {img: path, height: can.Action("height"), onclick: function(event) { can.db.hash[0] && msg.path.indexOf(can.db.hash[0]) == -1 && (can.db.hash[0] = "")
can.ondetail._init(can, index) can.core.List(can.db.list, function(item, index) { var last = can.onexport.progress(can, "p."+item.path);
}, _init: function(target) { can.Status("file", path) }, (!can.db.hash[0] || can.db.hash[0] == can.Option(nfs.PATH) || can.db.hash[0].indexOf(can.Option(nfs.PATH)) == -1) && (can.db.hash[0] = item.path)
onmouseover: function(event) { can.Status("file", path) }, item.nick = [item.cover? {img: can.misc.Resource(can, item.cover)}:
} }, can.misc.isImage(can, item.path)? {img: can.misc.Resource(can, item.path)}:
can.misc.isVideo(can, item.path)? {img: can.misc.Resource(can, "usr/icons/QuickTime Player.png")}:
video: function(can, path) { var auto = can.user.isMobile&&can.Action("limit")!="1"? false: true, loop = true, total = 0; function cb(event) { } can.misc.isAudio(can, item.path)? {img: can.misc.Resource(can, "usr/icons/Music.png")}: null,
return {type: "video", style: {height: parseInt(can.Action("height"))}, className: "preview", {text: [item.name, "", mdb.NAME]}, {text: [last||"", "", "progress"]},
data: {src: path, controls: "controls", autoplay: auto, loop: loop, playbackRate: parseFloat(can.Action("rate"))}, can.Option(nfs.PATH) != "usr/icons/" && can.base.isIn(can.Action("sort")||"", mdb.TIME, "")? {text: [can.base.TimeTrim(item.time), "", mdb.TIME]}: {text: [item.size, "", nfs.SIZE]},
oncontextmenu: cb, onplay: cb, onpause: cb, onended: cb, ]
onmouseover: function(event) { can.Status("file", path) }, item.title = [item.time, item.path, item.size].join("\n")
onloadedmetadata: function(event) { total = event.timeStamp item._hash = item.path, item._title = item.path.split("/").pop()
event.target.currentTime = can._msg.currentTime || 0 item._target = can.onimport.item(can, item, function(event, item, show, target) { can.onimport._content(can, item, index, target) })
}, onloadeddata: cb, ontimeupdate: function(event) { item.title = ""
can.Status("file") == path && can.Status("position", can.onexport.position(can, (can._msg.currentTime=event.target.currentTime)-1, event.target.duration)) })
}, },
} _content: function(can, item, index, target) { can.Option(nfs.FILE, item.name), can.Status(item), can.ui.video = item._video, can.ui.current = item
}, if (can.onexport.progress(can, "p."+item.path) == "100%") { can.onexport.progress(can, "p."+item.path, ""), can.onexport.progress(can, item.path, "") }
mp4: function(can, path) { return can.onfigure.video(can, path) }, if (can.misc.isImage(can, item.path)) { can.onmotion.delay(can, function() { can.onaction.playnext(can) }, 5000) }
m4v: function(can, path) { return can.onfigure.video(can, path) }, if (!can.onmotion.cache(can, function() { return item.path }, can.ui.content)) { var progress
mov: function(can, path) { return can.onfigure.video(can, path) }, item._cb = function(event, video) { can.ui.video = item._video = video
var p = parseInt(video.currentTime*100/video.duration); can.page.Select(can, target, "span.progress", function(target) { target.innerText = p+"%" })
if (!progress) { progress = can.page.Append(can, can.ui.content, ["progress"])._target } can.page.style(can, progress, html.WIDTH, can.ui.content.offsetWidth*p/100)
}
var _target = can.onimport.file(can, item.path, item, index, can.ui.content, true); _target.focus()
can.onappend._toggle(can, can.ui.content, function() { can.onaction.prev({}, can) }, function() { can.onaction.next({}, can) })
}
if (index < can.db.begin || index >= can.db.begin+can.db.limit) {
can.onimport.page(can, can.db.list, can.db.begin = index-index%can.db.limit)
} can.onmotion.select(can, can.ui.display, "*", item._display)
},
_file: function(can, path) {
return can.misc.Resource(can, can.db.dir_root+path, can.ConfSpace())
},
file: function(can, path, item, index, target, auto) { item._path = path = can.onimport._file(can, path)
var cb = can.onfigure[can.base.Ext(path)]||can.onfigure[wiki.IMAGE]
return cb && can.page.Append(can, target||can.ui.display, [cb(can, item, auto)])._target
},
page: function(can, list, begin) { can.onmotion.clear(can, can.ui.display)
begin = parseInt(begin||can.db.begin||0), can.db.limit = can.base.Min((parseInt(can.ui.display.offsetWidth/110)||5)-1, 3)
for (var i = begin; i < begin+can.db.limit; i++) { if (list && list[i]) { list[i]._display = can.onimport.file(can, list[i].path, list[i], i) } }
can.onappend._toggle(can, can.ui.display, function(event) { can.onaction.prevpage(event, can) }, function(event) { can.onaction.nextpage(event, can) })
can.Status({begin: begin, limit: can.db.limit, total: list.length})
},
}, [""])
Volcanos(chat.ONFIGURE, {
png: function(can, item) { return can.onfigure.image(can, item) },
gif: function(can, item) { return can.onfigure.image(can, item) },
jpg: function(can, item) { return can.onfigure.image(can, item) },
jpeg: function(can, item) { return can.onfigure.image(can, item) },
image: function(can, item) { return {img: item._path, title: item.title, onclick: function(event) { item._target.click() }} },
video: function(can, item, auto) { var init, last = can.onexport.progress(can, item.path)||0
var meta = {type: html.VIDEO, title: item.title, data: {src: item._path, controls: auto, autoplay: auto},
onclick: function(event) { item._target.click() },
onratechange: function(event) { can.onexport.storage(can, "rate", event.target.playbackRate) },
onvolumechange: function(event) { can.onexport.storage(can, "volume", event.target.volume) },
onloadedmetadata: function(event) { item._cb && item._cb(event, event.target)
event.target.volume = can.onexport.storage(can, "volume")||0.5
event.target.playbackRate = can.onexport.storage(can, "rate")||1
},
ontimeupdate: function(event) { if (event.target.currentTime == 0) { return } item._cb && item._cb(event, event.target)
can.Status("position", can.onexport.position(can, event.target.currentTime-1, event.target.duration))
can.onexport.progress(can, "p."+item.path, parseInt(event.target.currentTime*100/event.target.duration)+"%")
can.onexport.progress(can, item.path, event.target.currentTime)
if (!init) { init = true, event.target.currentTime = last }
},
onended: function(event) { can.onaction.playnext(can) },
}
if (!auto && can.misc.isVideo(can, item.path) && !can.user.isChrome) {
return {view: html.AUDIO, list: [{img: can.misc.Resource(can, item.cover||"usr/icons/QuickTime Player.png", can.ConfSpace()), className: "cover"}, {text: [item.name, "", mdb.NAME]}], onclick: meta.onclick}
}
return meta
},
audio: function(can, item, auto) { var meta = can.onfigure.video(can, item, auto); meta.type = html.AUDIO
return {view: html.AUDIO, list: [{img: can.misc.Resource(can, item.cover||"usr/icons/Music.png", can.ConfSpace()), className: "cover"}, {text: [item.name, "", mdb.NAME]}, meta], onclick: meta.onclick}
},
webm: function(can, item, auto) { return can.onfigure.video(can, item, auto) },
mov: function(can, item, auto) { return can.onfigure.video(can, item, auto) },
m4v: function(can, item, auto) { return can.onfigure.video(can, item, auto) },
mp4: function(can, item, auto) { return can.onfigure.video(can, item, auto) },
mp3: function(can, item, auto) { return can.onfigure.audio(can, item, auto) },
}) })
Volcanos("onaction", {help: "组件菜单", list: [ Volcanos(chat.ONACTION, {
["height", 100, 200, 400, 600, 800], list: [
["limit", 1, 3, 6, 9, 12, 15, 20, 30], "mkdir", "upload", "record1", "record2",
["rate", 0.1, 0.2, 0.5, 1, 2, 3, 5, 10], ["sort", mdb.TIME, nfs.PATH, nfs.SIZE],
], ["order", "repeat", "range", "loop", "random"],
"上一页": function(event, can, key, value) { ],
can.begin > 0 && (can.begin -= parseInt(can.Action("limit")), can.onimport.page(can, can.list)) record0: function(event, can, name, cb) { can.user.input(event, can, [{name: nfs.FILE, value: name}], function(list) {
}, var height = window.innerHeight, width = window.innerWidth
"下一页": function(event, can, key, value) { navigator.mediaDevices.getDisplayMedia({video: {height: height*8, width: width*8}}).then(function(stream) {
can.begin + parseInt(can.Action("limit")) < can.list.length && (can.begin += parseInt(can.Action("limit")), can.onimport.page(can, can.list)) can.core.Next([3, 2, 1], function(item, next) { can.user.toast(can, item + "s 后开始截图"), can.onmotion.delay(can, next, 1000) }, function() { can.onmotion.clearFloat(can)
}, can.onmotion.delay(can, function() {
cb(stream, function(blobs, ext) { var msg = can.request(event); msg._upload = new File(blobs, list[0]+nfs.PT+ext)
"height": function(event, can, key, value) { can.runAction(msg, html.UPLOAD, [], function(msg) { can.user.toast(can, "上传成功")
can.Action("height", value), can.onimport.page(can, can.list) can.db.hash = can.onexport.hash(can, encodeURIComponent(msg.Result())), can.Update()
}, }), can.core.List(stream.getTracks(), function(item) { item.stop() })
"limit": function(event, can, key, value) { })
can.Action("limit", value), can.onimport.page(can, can.list) }, 300)
}, })
"rate": function(event, can, key, value) { }).catch(function(err) { can.user.toast(can, err.name + ": " + err.message) })
can.Action("rate", value), can.onimport.page(can, can.list) }) },
}, record1: function(event, can) { can.onaction.record0(event, can, "Screenshot "+can.base.Time(null), function(stream, cb) { var height = window.innerHeight
var video = can.page.Append(can, document.body, [{type: html.VIDEO, height: height}])._target; video.srcObject = stream, video.onloadedmetadata = function() {
chooseImage: function(event, can) { var msg = can.request(event) video.play(), height = video.offsetHeight, width = video.offsetWidth
can.user.agent.chooseImage(function(list) { can.core.List(list, function(item) { var canvas = can.page.Append(can, document.body, [{type: html.CANVAS, height: height, width: width}])._target; canvas.getContext("2d").drawImage(video, 0, 0, width, height)
can.page.Append(can, can._output, [{img: item, height: 200}]) canvas.toBlob(function(blob) { cb([blob], nfs.PNG) })
}) }) }
}, }) },
record2: function(event, can) { if (can.ui.recorder) { return can.ui.recorder.stop() }
can.onaction.record0(event, can, "Screenshot "+can.base.Time(null), function(stream, cb) {
if (can.user.isChrome) {
var recorder = new MediaRecorder(stream, {mimeType: "video/webm;codecs=vp8"})
recorder.onstop = function() { delete(can.ui.recorder), cb(blobs, "webm") }
// var recorder = new MediaRecorder(stream, {mimeType: 'video/mp4; codecs="avc1.4d002a"'})
// recorder.onstop = function() { delete(can.ui.recorder), cb(blobs, "mp4") }
} else {
var recorder = new MediaRecorder(stream, {mimeType: "video/mp4"})
recorder.onstop = function() { delete(can.ui.recorder), cb(blobs, "mp4") }
}
var blobs = []; recorder.ondataavailable = function(res) { blobs.push(res.data) }
can.ui.recorder = recorder, recorder.start(1)
})
},
fullscreen: function(event, can, button) { var show = can.onmotion.toggle(can, can.ui.project)
can.onmotion.toggle(can, can.ui.display, show), can.onmotion.toggle(can, can._status, show)
can.page.ClassList.set(can, can._fields, button, !show), can.page.ClassList.set(can, can.ui.content, html.FLOAT, !show)
can.sup.onimport.size(can.sup, can.sup.ConfHeight(), can.sup.ConfWidth())
},
sort: function(event, can, button, value) {
switch (value) {
case mdb.TIME: can._msg.Sort(value, "str_r"); break
case nfs.PATH: can._msg.Sort(value, "str"); break
case nfs.SIZE: can._msg.Sort(value, "int_r"); break
} can.onimport._project(can, can._msg)
},
playnext: function(can) {
if (can.Action("order") == "repeat") {
if (can.ui.video) { can.ui.video.currentTime = 0, can.ui.video.play() }
}
if (can.Action("order") == "range") { var next = can.ui.current._target.nextSibling
next && can.onmotion.delay(can, function() { next.click() }, 300)
}
if (can.Action("order") == "loop") { var next = can.ui.current._target.nextSibling
next? can.onmotion.delay(can, function() { next.click() }, 300): can.db.list[0]._target.click()
}
if (can.Action("order") == "random") {
can.db.list[parseInt(Math.random()*can.db.list.length)]._target.click()
}
},
prev: function(event, can) { var target = can.ui.current._target; target.previousSibling? target.previousSibling.click(): can.user.toast(can, "已经是第一页了") },
next: function(event, can) { var target = can.ui.current._target; target.nextSibling? target.nextSibling.click(): can.user.toast(can, "已经是最后一页了") },
prevpage: function(event, can) { if (can.db.begin > 0) { can.db.begin -= can.db.limit, can.onimport.page(can, can.db.list) } else { can.user.toast(can, "已经是第一页了") } },
nextpage: function(event, can) { if (can.db.begin + can.db.limit < can.db.list.length) { can.db.begin += can.db.limit, can.onimport.page(can, can.db.list) } else { can.user.toast(can, "已经是最后一页了") } },
}) })
Volcanos("ondetail", {help: "组件菜单", list: ["关闭", "下载", "删除", "上一个", "下一个", "设置头像", "设置背景", "复制链接"], _init: function(can, index) { Volcanos(chat.ONEXPORT, {list: [cli.BEGIN, mdb.LIMIT, mdb.TOTAL, mdb.NAME, nfs.SIZE, mdb.TIME, "position"],
can.onappend._init(can, {type: "story feel float"}, [], function(sub) { can.sub = sub progress: function(can, path, time) { return can.onexport.storage(can, path.split("?")[0], time) },
sub.run = function(event, cmds, cb) { return can.run(event, cmds, cb, true) } position: function(can, index, total) { total = total || can.max; return parseInt((index+1)*100/total)+"%"+" = "+(parseInt(index)+1)+nfs.PS+parseInt(total) },
sub.search({}, ["Action.onexport.size"], function(msg, left, top, width, height) {
sub.page.Modify(sub, sub._target, {style: {left: left, top: top}})
sub.page.Modify(sub, sub._output, {style: {"max-width": width, "max-height": height}})
sub.onappend._action(can, can.ondetail.list, sub._action, can.ondetail)
can.order = index, can.show = function(order) {
path = can.onimport._file(can, can.list[order].path)
sub.page.Appends(sub, sub._output, [{img: path, style: {"max-width": width-40, "max-height": height-55}}])
sub.Status("begin", order+1+ice.PS+can.list.length), sub.Status("file", path)
}, can.show(can.order)
})
}, document.body)
},
"关闭": function(event, can) { can.page.Remove(can, can.sub._target) },
"下载": function(event, can) { can.user.download(can, path = can.onimport._file(can, can.list[can.order].path)) },
"删除": function(event, can) {
can.run(event, [ctx.ACTION, mdb.REMOVE, can.Status("file")], function(msg) { can.user.toast(can, "删除成功") }, true)
},
"上一个": function(event, can) { can.order > 0? can.show(--can.order): can.user.toast(can, "已经是第一张啦!") },
"下一个": function(event, can) { can.order < can.list.length-1? can.show(++can.order): can.user.toast(can, "已经是最后一张啦!") },
"设置头像": function(event, can) { var msg = can.request(event, {url: can.onimport._file(can, can.list[can.order].path)})
can.search(event, ["Header.onimport.avatar"], null, true)
},
"设置背景": function(event, can) { var msg = can.request(event, {url: can.onimport._file(can, can.list[can.order].path)})
can.search(event, ["Header.onimport.background"], null, true)
},
"复制链接": function(event, can) {
can.user.copy(event, can, can.misc.MergeURL(can, {_path: can.onimport._file(can, can.list[can.order].path)}, true))
},
}) })
Volcanos("onexport", {help: "导出数据", list: ["begin", "limit", "total", "position", "file"], Volcanos(chat.ONKEYMAP, {
position: function(can, index, total) { total = total || can.max _mode: {
return parseInt((index+1)*100/total)+"%"+" = "+(parseInt(index)+1)+ice.PS+parseInt(total) plugin: {
}, Escape: function(event, can) { can.onaction.fullscreen(event, can) },
ArrowLeft: function(event, can) { if (can.ui.video) { can.ui.video.currentTime -= 15 } else { can.onaction.prev(event, can) } },
ArrowRight: function(event, can) { if (can.ui.video) { can.ui.video.currentTime += 15 } else { can.onaction.next(event, can) } },
ArrowDown: function(event, can) { try { can.user.toast(can, "volume: "+parseInt((can.ui.video.volume -= 0.1)*100)) } catch (e) {} },
ArrowUp: function(event, can) { try { can.user.toast(can, "volume: "+parseInt((can.ui.video.volume += 0.1)*100)) } catch (e) {} },
" ": function(event, can) { if (can.ui.video) { can.ui.video.paused? can.ui.video.play(): can.ui.video.pause() } },
},
},
}) })

View File

@ -1,157 +1,41 @@
fieldset.word>div.legend { fieldset.word>div.output { padding:var(--plugin-padding); }
display:none; fieldset.word>div.output p { margin:var(--title-margin) auto; }
} fieldset.word>div.output h3 { margin-top:var(--title-margin); }
fieldset.word>div.output fieldset.span>fieldset { fieldset.word>div.output h2.story[data-type=spark][data-name=title] { text-align:center; }
float:left; overflow:auto; fieldset.word>div.output code { font-style: italic; }
} fieldset.word>div.output ul { margin:20px; font-family:var(--code-font-family); word-break:break-all; }
fieldset.word>div.output ul>li:hover { background-color:var(--hover-bg-color); color:var(--hover-fg-color); cursor:pointer; }
fieldset.word>div.output img { display:block; margin:auto; max-height:100%; max-width:100%; }
fieldset.word>div.output div.project img { margin:unset; }
fieldset.word>div.output table.content img { margin:unset; max-width:unset; }
fieldset.word>div.output table { width:100%; }
fieldset.word>div.output video { max-height:100%; width:100%; }
fieldset.word>div.output iframe { height:var(--iframe-height); width:100%; }
fieldset.word>div.output svg.story[data-index] text { cursor:pointer; }
fieldset.word>div.output input.story[type=button] { font-family:system-ui; font-weight:bold; padding:10px 40px; margin:var(--button-margin); height:var(--header-height); box-shadow:var(--input-box-shadow); }
body.mobile fieldset.word>div.output input.story[type=button] { padding:10px 20px; }
fieldset.word>div.output fieldset.web.code.inner.output div.output td.line { border-right:var(--box-border); }
fieldset.word>div.navmenu { background-color:inherit; overflow:auto; min-width:120px; clear:both; float:left; }
fieldset.word>div.navmenu div.list { margin-left:var(--title-margin); }
fieldset.word>div.navmenu div.item { font-size:1.4em; font-weight:bold; font-family:cursive; padding:var(--input-padding) var(--title-margin); }
fieldset.word>div.navmenu>div.item { font-size:1.6em; }
fieldset.word>div.navmenu { div.story[data-type=spark] label { padding:3px; -webkit-user-select:none; }
clear:both; div.story[data-type=spark_tabs] { margin-top:var(--title-margin); }
float:left; div.story[data-type=spark_tabs]>div.tabs>div.item { font-style:italic; padding:var(--input-padding) var(--button-padding); height:var(--action-height); float:left; }
min-width:120px; div.story[data-type=spark_tabs]>div.tabs>div.item.select { border-top:var(--box-notice3); }
background-color:inherit; body.dark div.story[data-type=spark_tabs]>div.tabs>div.item.select { background-color:var(--code-bg-color); }
margin-right:10px; div.story[data-type=spark_tabs]>div.story:not(.select) { display:none; }
overflow:auto;
}
fieldset.word>div.navmenu>div.item {
font-weight:bold;
font-size:24px;
padding:4px 10px;
}
fieldset.word>div.navmenu>div.list>div.item {
font-weight:bold;
font-size:18px;
}
fieldset.word>div.navmenu div.item {
font-family:cursive;
padding:4px 10px;
}
fieldset.word>div.navmenu div.item.select {
background-color:red;
}
fieldset.word>div.navmenu div.item:hover {
cursor:pointer;
background-color:red;
}
fieldset.word>div.navmenu div.list {
margin-left:20px;
}
fieldset.word a {
word-break:break-word;
}
fieldset.word ul.story[data-type=premenu] {
cursor:pointer;
}
fieldset.word ul.story[data-type=premenu] li:hover {
background:cyan;
color:blue;
}
fieldset.word ul.story[data-type=endmenu] {
clear:both;
}
fieldset.word ul.story li.H2 {
font-weight:bold;
font-size:20px;
}
fieldset.word br.story {
clear:both;
}
fieldset.word p.story {
white-space:pre;
}
fieldset.word p.story[data-name=inner] {
padding:4px 10px; margin:10px 0px;
background-color:#4b6c8a7a;
border-left:solid 4px blue;
}
fieldset.word p.story[data-name=inner]:hover {
background-color:#c10c8a;
cursor:copy;
}
fieldset.word svg.story {
display:block; float:left;
}
fieldset.word code.story {
display:block; border:solid 3px green;
color:white; background-color:#272822;
font-size:14px; font-family:monospace;
max-height:640px; overflow:auto;
padding:10px; white-space:pre;
clear:both;
}
fieldset.word video.story {
max-height:320px;
}
fieldset.word fieldset.story {
margin:10px; border:0;
clear:both; float:left;
box-shadow:4px 4px 10px 1px #626bd0;
}
fieldset.word fieldset.story:hover {
box-shadow:12px 12px 12px 6px #5764efd1;
}
fieldset.word.float {
width:-webkit-fill-available;
position:fixed; left:0; top:0;
background-color:aliceblue;
color:black;
}
fieldset.word.float>div.output {
background-color:#f0f8ff80;
overflow:auto;
padding:20px;
}
fieldset.word.float>div.output>div.project {
background:cornsilk;
left:0; top:25px;
position:fixed;
padding:10px;
z-index:100;
}
fieldset.word.float div.content div.page {
background-color:#194c79d4;
margin-top:30px;
display:none;
}
fieldset.word.float div.content div.page.show {
display:block;
}
fieldset.word.float div.content.grid div.page {
float:left; display:block;
width:200px; height:200px;
overflow:auto; margin:10px;
background-color:#a4cbecb5;
}
fieldset.word.float h1 {
text-align:center;
}
fieldset.word.float h2 {
text-align:center;
}
fieldset.word.float h3 {
text-align:center;
}
fieldset.word.float div.status {
clear:none;
}
fieldset.word.float div.status label {
color:black;
}
fieldset.word.float div.status span {
color:black;
}
fieldset.panel.cmd fieldset.word>form.option {
display:none;
}
fieldset.panel.cmd fieldset.word>div.action {
display:none;
}
fieldset.panel.cmd fieldset.word>div.status {
display:none;
}
fieldset.word.play.float { top:0; }
fieldset.word.play.float>div.action { display:contents; }
fieldset.word.play.float>div.status { clear:none; display:contents; }
fieldset.word.play.float>div.output>div.project { background-color:var(--plugin-bg-color); padding:var(--plugin-padding); position:fixed; right:0; top:var(--action-height); z-index:11; }
fieldset.word.play.float div.content div.page { display:none; }
fieldset.word.play.float div.content div.page.show { display:block; }
fieldset.word.play.float div.content div.page ul { text-align:left; }
fieldset.word.play.float div.content.grid div.page { background-color:var(--plugin-bg-color); margin:var(--plugin-padding); height:var(--qrcode-height); width:30%; overflow:auto; display:block; float:left; }
fieldset.word.play.float h1 { text-align:center; }
fieldset.word.play.float h2 { text-align:center; }
fieldset.word.play.float h3 { text-align:center; }
fieldset.word.play.float svg { display:block; margin:0 auto; }

View File

@ -1,193 +1,192 @@
Volcanos("onimport", {help: "导入数据", _init: function(can, msg, cb, target) { Volcanos(chat.ONIMPORT, {
can.onmotion.clear(can), can.base.isFunc(cb) && cb(msg) _init: function(can, msg, target) { can.Conf(html.PADDING, html.PLUGIN_PADDING)
if (msg.Length() > 0) { return can.onappend.table(can, msg) } can.page.Modify(can, target, msg.Results()), can.onimport._content(can, target)
can.onmotion.delay(can, function() { can.onappend.scroll(can) })
can.page.Modify(can, target, msg.Result()) can.onexport.title(can, can.Option(nfs.PATH))
can.page.Select(can, target, ".story", function(item) { var data = item.dataset||{} },
can.core.CallFunc([can.onimport, data.type], [can, data, item]) _content: function(can, target, cb) { can.onappend.style(can, web.WIKI_WORD)
can.page.Modify(can, item, {style: can.base.Obj(data.style)}) can.page.Select(can, target, wiki.STORY_ITEM, function(target) { var meta = target.dataset||{}; cb && cb(target, meta)
}) can.core.CallFunc([can.onimport, can.onimport[meta.name]? meta.name: meta.type||target.tagName.toLowerCase()], [can, meta, target])
}, var _meta = can.base.Obj(meta.meta);
navmenu: function(can, data, target) { var nav = can.sup._navmenu if (_meta && _meta.style) {
nav = nav||can.page.Append(can, can._fields, [{view: wiki.NAVMENU}]).first if (can.user.isMobile && _meta.style.width == "480px") { _meta.style.width = can.ConfWidth() - 2*can.Conf(html.PADDING) }
can.onmotion.clear(can, nav), can._fields.insertBefore(nav, can._output) can.page.style(can, target, can.base.Obj(_meta.style))
}
can.page.Modify(can, nav, {style: {height: can.Conf(html.HEIGHT)}}) meta.style && can.page.style(can, target, can.base.Obj(meta.style))
can.onappend.list(can, can.base.Obj(data.data), function(event, item) { })
var link = item.meta.link, list = can.core.Split(item.meta.link) can.page.Select(can, target, html.A, function(target) {
if (can.core.Value(can, list[0])) { return can.core.CallFunc([can, list[0]], list.slice(1)) } target.innerText = target.innerText || target.href, target.href = target.href || target.innerText, target.target = target || "_blank"
if (!link || link == can.Option(nfs.PATH)) { return false } })
},
can.page.Cache(can.Option(nfs.PATH), can._output, can._output.scrollTop+1) list: function(can, root, cb, cbs, target) { target = target||can._output
can.Option(nfs.PATH, link), can.user.mod.isCmd && can.user.title(item.meta.name) can.core.List(root.list, function(item) { var ui = can.page.Append(can, target, [{view: [[html.ITEM, "open"]], list: [{text: item.meta.name}, item.list && {icon: icon.CHEVRON_DOWN}], onclick: function(event) {
var position = can.page.Cache(can.Option(nfs.PATH), can._output) can.page.ClassList.set(can, ui.item, "open", can.base.isFunc(cb) && cb(event, item) || can.onmotion.toggle(can, ui.list))
if (position) { can._output.scrollTo(0, position-1); return true } can.onmotion.select(can, target, html.DIV_ITEM, event.currentTarget)
}, _init: function(target) { if (item.meta.name == "_") { target.innerHTML = "", can.onappend.style(can, html.SPACE, target) }
can.sup.Update(event, [link]) cbs && cbs(target, item)
return true }}, {view: html.LIST}]); can.onimport.list(can, item, cb, cbs, ui.list) })
}, nav), can.sup._navmenu = nav },
navmenu: function(can, meta, target) { var nav = can.sup._navmenu
can.Conf(html.WIDTH, can.Conf(html.WIDTH)-nav.offsetWidth-(can.user.mod.isCmd? 10: 20)) nav = can.onmotion.clear(can, nav||can.page.insertBefore(can, [wiki.NAVMENU], can._output)), can.sup._navmenu = nav
can.page.Modify(can, can._output, {style: kit.Dict( can.onimport.list(can, can.base.Obj(meta.data), function(event, item) {
html.HEIGHT, can.sup._navmenu.offsetHeight, html.MAX_WIDTH, can.Conf(html.WIDTH), var link = item.meta.link; if (!link || link == can.Option(nfs.PATH)) { return false }
html.FLOAT, html.LEFT, html.CLEAR, html.NONE if (can.base.beginWith(link, nfs.PS, web.HTTP)) { return can.user.opens(link) }
)}) if (can.onmotion.cache(can, function() { return can.onexport.title(can, item.meta.name), can.Option(nfs.PATH, link) })) { return }
}, return can.sup.Update(event, [link])
premenu: function(can, data, target) { }, function() {}, nav)
can.page.Select(can, can._output, "h2.story, h3.story", function(item) { can.onimport.layout(can)
can.page.Append(can, target, [{text: [item.innerHTML, html.LI, item.tagName], onclick: function() { },
item.scrollIntoView() premenu: function(can, meta, target) { can.page.Select(can, can._output, can.page.Keys(html.H2, html.H3), function(_target) {
}}]), item.onclick = function(event) { target.scrollIntoView() } can.onimport.item(can, {name: _target.innerHTML}, function() { can.onmotion.scrollIntoView(can, _target) }, function() {}, target)
}) _target.onclick = function(event) { can.onmotion.scrollIntoView(can, target) }
}, }) },
title: function(can, data, target) { endmenu: function(can, meta, target) { can.page.Select(can, can._output, can.page.Keys(html.H2, html.H3), function(_target) {
can.user.mod.isCmd && can.user.title(data.text) can.onimport.item(can, {name: _target.innerHTML}, function() { can.onmotion.scrollIntoView(can, _target) }, function() {}, target)
}, }) },
spark: function(can, data, target) { spark: function(can, meta, target) {
if (data[mdb.NAME] == html.INNER) { return can.onmotion.copy(can, target) } if (meta[mdb.NAME] == html.INNER) { return can.onmotion.copy(can, target) }
can.page.Select(can, target, html.A, function(item) { can.onmotion.link(can, item) }) can.page.Select(can, target, "kbd,samp", function(item) { can.onmotion.copy(can, item, function() {
can.page.Select(can, target, html.SPAN, function(item) { can.onmotion.copy(can, item) }) meta.type == "shell" && can.onappend.float(can, {index: web.CODE_XTERM, args: ["sh"]})
}, }) })
chart: function(can, data, target) { },
target.oncontextmenu = function(event) { spark_tabs: function(can, meta, target) { var select
can.user.carteClient(event, can, kit.Dict(mdb.EXPORT, function(event, can, button) { can.page.Select(can, target, "div.tabs>div.item", function(tabs, index) {
can.user.toPNG(can, can.user.prompt("please input file name", "hi")+".png", target.outerHTML, (index == 0 || can.user.isMacOSX && can.base.isIn(tabs.innerText, cli.DARWIN, "macos") || can.user.isWindows && tabs.innerText == cli.WINDOWS) && (select = tabs)
parseInt(target.getAttribute(html.HEIGHT))||200, parseInt(target.getAttribute(html.WIDTH))||200) tabs.onclick = function() { can.onmotion.select(can, tabs.parentNode, "div.tabs>div.item", tabs), can.onmotion.select(can, target, "div.story", index) }
}), [mdb.EXPORT]) return tabs
} }); select && select.click()
}, },
table: function(can, data, target) { table: function(can, meta, target) {
can.page.OrderTable(can, target), can.page.ClassList.add(can, target, chat.CONTENT) can.page.OrderTable(can, target), can.page.ClassList.add(can, target, chat.CONTENT)
can.page.Select(can, target, html.TD, function(item) { can.onmotion.copy(can, item) }) can.page.Select(can, target, html.TD, function(item) { can.onmotion.copy(can, item) })
}, },
field: function(can, data, target, width) { var item = can.base.Obj(data.meta) order: function(can, meta, target) {
can.onappend._init(can, item, ["/plugin/state.js"], function(sub) { target.onclick = function(event) {
sub.run = function(event, cmds, cb, silent) { can.user.copy(event, can, event.target.innerText)
can.run(event, can.misc.concat([ctx.ACTION, chat.STORY, data.type, data.name, data.text], cmds), cb, true) }
}, sub.Conf(html.WIDTH, item.width = (width||can.Conf(html.WIDTH))-20) },
chart: function(can, meta, target) {
can.core.Value(item, "auto.cmd") && can.core.Timer300ms(function() { if (!meta.fg && !meta.bg) { target.className.baseVal = "story auto" }
var msg = sub.request({}, can.core.Value(item, "opts")); msg.Option("_handle", ice.TRUE) target.onclick = function(event) { can.misc.Event(event, can, function(msg) {
sub.Update(msg._event, [ctx.ACTION, can.core.Value(item, "auto.cmd")]) meta.index && can.onappend._float(can, meta.index, can.base.Obj(meta.args, []).concat([event.target.innerHTML]))
}) }) }
}, can._output, target) target.oncontextmenu = function(event) { can.misc.Event(event, can, function(msg) {
}, var ui = can.user.carte(event, can, kit.Dict(mdb.EXPORT, function(event, can, button) {
iframe: function(can, data, target) { var meta = can.base.Obj(data.meta) can.user.toimage(can, "hi", target)
can.page.Modify(can, target, {width: can.Conf(html.WIDTH)-200}) })); can.page.style(can, ui._target, {left: event.clientX, top: event.clientY})
}, }) }
},
field: function(can, meta, target) { var item = can.base.Obj(meta.meta), padding = can.Conf(html.PADDING)
var height = can.base.Max(html.STORY_HEIGHT, can.ConfHeight()-4*html.ACTION_HEIGHT-2*padding), width = item.width||can.ConfWidth()-2*padding
can.core.Item(item, function(key, value) { if (can.base.beginWith(key, "meta.")) { can.core.Value(item, key, value), delete(item[key]) } })
can.onappend.plugin(can, item, function(sub) { can._plugins = (can._plugins||[]).concat([sub])
can.user.isMobile || sub.Conf("__width", item.width)
can.core.Value(item, "auto.cmd") && can.onmotion.delay(function() { sub.runAction(sub.request({}, can.core.Value(item, "opts")), can.core.Value(item, "auto.cmd")) })
var size = sub.onimport.size; sub.onimport.size = function(can, height, width, auto, mode) { size(can, height, width, auto, mode)
can.page.style(can, sub._output, html.MAX_HEIGHT, "", "overflow-y", "hidden")
sub.sub && sub.sub.ui.content && can.page.style(can, sub.sub.ui.content, html.HEIGHT, "", "overflow-y", "hidden")
}, sub.onimport.size(sub, height, width, true)
can.onimport.layout(can)
}, can._output, target)
},
layout: function(can) { padding = can.Conf(html.PADDING)
if (can.sup._navmenu) { can.ConfWidth(can.ConfWidth()-can.sup._navmenu.offsetWidth)
can.page.style(can, can.sup._navmenu, html.HEIGHT, can.ConfHeight())
can.page.style(can, can._output, html.HEIGHT, can.ConfHeight(), html.WIDTH, can.ConfWidth(), "clear", "none", "float", "left")
}
can.core.List(can._plugins, function(sub) { sub.onimport.size(sub, can.base.Min(can.ConfHeight()/2, 300, 600), (can.ConfWidth()-2*padding), true) })
can.page.Select(can, can._output, html.IMG, function(target) { can.page.style(can, target, html.MAX_HEIGHT, can.base.Max(can.ConfHeight(), 420)) })
},
}, [""]) }, [""])
Volcanos("onkeypop", {help: "键盘交互", list: [], Volcanos(chat.ONACTION, {
_mode: { play: function(event, can) { var list = [], current = []
normal: { can.page.Select(can, can._output, wiki.STORY_ITEM, function(item) { can.page.tagis(item, "h1", "h2", "h3") && list.push(current = []), current.push(item) })
"n": function(event, can) { can.ondetail.next(can.sub) }, can.onappend._init(can, {type: "story word play float", height: can.page.height(), width: can.page.width(), padding: 10}, [], function(sub) { sub._legend.onclick = can._legend.onclick
"j": function(event, can) { can.ondetail.next(can.sub) }, sub._trans = {input: {page: "页码", from: "开始"}}
"ArrowRight": function(event, can) { can.ondetail.next(can.sub) }, sub.run = can.run, sub.sup = can, can.sub = sub, can.onappend._action(sub, can.user.isMobile && can.page.height() > can.page.width()? [
"ArrowLeft": function(event, can) { can.ondetail.prev(can.sub) }, "大纲", "上一页", "下一页", "结束",
"k": function(event, can) { can.ondetail.prev(can.sub) }, ]: [
"p": function(event, can) { can.ondetail.prev(can.sub) }, ["布局", "开讲", "网格", "快闪"], "大纲", "首页", "上一页",
["菜单"].concat(can.core.List(list, function(page) { return page[0].innerHTML })),
"q": function(event, can) { can.ondetail["结束"](event, can.sub) }, "下一页", "隐藏", "结束",
"h": function(event, can) { can.ondetail["隐藏"](event, can.sub) }, ], sub._action, can.ondetail, false, 10), can.onkeymap._build(can)
}, sub.page.style(sub, sub._target, "background", can._root._target.style.background)
}, _engine: {}, sub.page.style(sub, sub._output, html.HEIGHT, can.page.height()-2*html.ACTION_HEIGHT)
sub.page.style(sub, sub._output, html.WIDTH, can.page.width())
sub.ui = sub.page.Append(sub, sub._output, [chat.PROJECT, chat.CONTENT])
can.core.List(sub.list = list, function(page, index) {
can.onimport.item(can, {name: page[0].innerHTML}, function(event) { can.ondetail.show(sub, index) }, function(event) {}, sub.ui.project)
sub.page.Append(sub, sub.ui.content, [{view: "page"+(index==0? " first": ""), list: can.core.List(page, function(item) { var data = item.dataset||{}
switch (data.type) {
case wiki.PREMENU: item = item.cloneNode(false); break
case chat.FIELD: item = can.onappend.field(can, chat.STORY, can.base.Copy(can.base.Obj(data.meta), {height: can.page.height(), width: can.page.width()}), sub.ui.content)._target; break
default: item = item.cloneNode(true)
}
return can.core.CallFunc([can.onimport, data.type], [sub, data, item, can.page.width()]), item
}), }])
}), can.onmotion.hidden(can, sub.ui.project), can.ondetail.show(sub, 0)
sub.onappend._status(sub, [mdb.PAGE, cli.FROM, cli.COST]), sub.Status(cli.FROM, can.base.Time()), sub.Status(mdb.PAGE, list.length)
var from = new Date(); can.core.Timer({interval: 100}, function() { var now = new Date(); sub.Status(cli.COST, can.base.Duration(now-from)) })
}, can._root._target)
},
}) })
Volcanos("onaction", {help: "控件交互", list: [], Volcanos(chat.ONDETAIL, {
play: function(event, can) { var list = [], current = [] show: function(sub, which) { sub.page.styleClass(sub, sub.ui.content, chat.CONTENT)
can.page.Select(can, can._output, ".story", function(item) { sub.page.Select(sub, sub.ui.content, html.DIV_PAGE, function(page, index) {
switch (item.tagName) { if (index == which || page == which) {
case "H1": sub.page.Select(sub, page, sub.page.Keys(html.H1, html.H2, html.H3), function(item) { sub.Action("菜单", item.innerHTML) })
case "H2": sub.onmotion.select(sub, sub.ui.project, html.DIV_ITEM, index)
case "H3": sub.Status(mdb.PAGE, index+1+nfs.PS+sub.list.length)
list.push(current = []) sub.page.ClassList.add(sub, page, html.SHOW)
break } else {
} sub.page.ClassList.del(sub, page, html.SHOW)
current.push(item) }
}) })
},
can.onappend._init(can, {type: "story word float"}, [], function(sub) { next: function(sub) { sub.page.Select(sub, sub.ui.content, sub.core.Keys(html.DIV_PAGE, html.SHOW), function(page) {
sub.run = can.run, sub.sup = can, can.sub = sub, can.onappend._action(sub, [ page.nextSibling? sub.sup.ondetail.show(sub, page.nextSibling): sub.user.toast(sub.sup, cli.END)
["布局", "开讲", "快闪", "网格"], "大纲", "首页", "上一页", }) },
["菜单"].concat(can.core.List(list, function(page) { return page[0].innerHTML })), prev: function(sub) { sub.page.Select(sub, sub.ui.content, sub.core.Keys(html.DIV_PAGE, html.SHOW), function(page) {
"下一页", "隐藏", "结束", page.previousSibling? sub.sup.ondetail.show(sub, page.previousSibling): sub.user.toast(sub.sup, cli.END)
], sub._action, can.ondetail) }) },
flash: function(sub) { sub.core.Next(sub.page.Select(sub, sub.ui.content, html.DIV_PAGE), function(page, next) {
can.onengine.signal(can, "keymap.focus", can.request(event, {cb: function(event) { sub.sup.ondetail.show(sub, page), sub.onmotion.delay(sub, next, 500)
can.keylist = can.onkeypop._parse(event, can, "normal", can.keylist) }) },
}})), can.onkeypop._build(can) grid: function(sub) {
sub.page.styleClass(sub, sub.ui.content, "content grid")
can.page.Modify(can, sub._target, {style: {background: document.body.style.background}}) },
sub.ui = sub.page.Append(sub, sub._output, [{view: chat.PROJECT}, {view: chat.CONTENT}]) "开讲": function(event, can) {
sub.page.Modify(sub, sub._output, {style: {height: window.innerHeight-93}}) can.page.SelectChild(can, can.ui.content, "", function(target) { can.page.style(can, target, html.HEIGHT, "", html.WIDTH, "") })
sub.page.Modify(sub, sub._output, {style: {width: window.innerWidth-40}}) can.sup.ondetail.show(can, 0)
},
can.core.List(sub.list = list, function(page, index) { "网格": function(event, can) { function size(p) { return (p-2*html.PLUGIN_PADDING)/3-2*html.PLUGIN_PADDING }
can.onappend.item(can, html.ITEM, {name: page[0].innerHTML}, function(event) { can.onlayout.expand(can, can.ui.content, can.base.Min(size(can.ConfWidth()), 320, 640), can.base.Min(size(can.ConfHeight()-2*html.ACTION_HEIGHT), 240, 320), html.DIV_PAGE)
can.ondetail.show(sub, index) can.sup.ondetail.grid(can)
}, function(event) {}, sub.ui.project) },
"快闪": function(event, can) {
sub.page.Append(sub, sub.ui.content, [{view: "page"+(index==0? " first": ""), list: can.core.List(page, function(item) { var data = item.dataset||{} can.page.SelectChild(can, can.ui.content, "", function(target) { can.page.style(can, target, html.HEIGHT, "", html.WIDTH, "") })
switch (data.type) { can.sup.ondetail.flash(can)
case wiki.PREMENU: item = item.cloneNode(false); break },
case chat.FIELD: item = can.onappend.field(can, chat.STORY, can.base.Obj(data.meta), sub.ui.content).first; break "大纲": function(event, can) { can.onmotion.toggle(can, can.ui.project) },
default: item = item.cloneNode(true) "首页": function(event, can) { can.sup.ondetail.show(can, 0) },
} "上一页": function(event, can) { can.sup.ondetail.prev(can, can.ui.content) },
return can.core.CallFunc([can.onimport, data.type], [sub, data, item, window.innerWidth-40]), item "菜单": function(event, can) { can.sup.ondetail.show(can, event.target.selectedIndex) },
}), }]) "下一页": function(event, can) { can.sup.ondetail.next(can, can.ui.content) },
}), can.onmotion.hidden(can, sub.ui.project), can.ondetail.show(sub, 0) "隐藏": function(event, can) { can.onmotion.toggle(can, can._output) },
"结束": function(event, can) { can.page.Remove(can, can._target) },
sub.onappend._status(sub, [mdb.PAGE, cli.FROM, cli.COST]), sub.Status(cli.FROM, can.base.Time()) "删除": function(event, sub) { sub.page.Remove(sub, sub._target) },
var from = new Date(); can.core.Timer({interval: 100}, function() { var now = new Date()
sub.Status(cli.COST, can.base.Duration(now-from))
})
}, document.body)
},
}) })
Volcanos("ondetail", {help: "交互操作", list: ["删除"], _init: function(can, msg, list, cb, target) { Volcanos(chat.ONKEYMAP, {
}, _mode: {
show: function(sub, which) { sub.page.Modify(sub, sub.ui.content, {className: chat.CONTENT}) plugin: {
sub.page.Select(sub, sub.ui.content, "div.page", function(page, index) { "j": function(event, can) { can.ondetail.next(can.sub) },
if (index == which || page == which) { "k": function(event, can) { can.ondetail.prev(can.sub) },
sub.page.Select(sub, page, "h1,h2,h3", function(item) { sub.Action("菜单", item.innerHTML) }) "n": function(event, can) { can.ondetail.next(can.sub) },
sub.onmotion.select(sub, sub.ui.project, "div.item", index) "p": function(event, can) { can.ondetail.prev(can.sub) },
sub.Status(mdb.PAGE, index+1+ice.PS+sub.list.length) "ArrowRight": function(event, can) { can.ondetail.next(can.sub) },
sub.page.ClassList.add(sub, page, html.SHOW) "ArrowLeft": function(event, can) { can.ondetail.prev(can.sub) },
} else { "q": function(event, can) { can.ondetail["结束"](event, can.sub) },
sub.page.ClassList.del(sub, page, html.SHOW) "h": function(event, can) { can.ondetail["隐藏"](event, can.sub) },
} },
}) }, _engine: {},
},
next: function(sub) {
sub.page.Select(sub, sub.ui.content, "div.page.show", function(page) {
page.nextSibling? sub.sup.ondetail.show(sub, page.nextSibling):
sub.user.toast(sub, "end")
})
},
prev: function(sub) {
sub.page.Select(sub, sub.ui.content, "div.page.show", function(page) {
page.previousSibling? sub.sup.ondetail.show(sub, page.previousSibling):
sub.user.toast(sub, "end")
})
},
flash: function(sub) {
sub.core.Next(sub.page.Select(sub, sub.ui.content, "div.page"), function(page, next) {
sub.core.Timer(500, function() { next() })
sub.sup.ondetail.show(sub, page)
})
},
grid: function(sub) { sub.page.Modify(sub, sub.ui.content, {className: "content grid"}) },
"开讲": function(event, can) { can.sup.ondetail.show(can, 0) },
"快闪": function(event, can) { can.sup.ondetail.flash(can) },
"网格": function(event, can) { can.sup.ondetail.grid(can) },
"大纲": function(event, can) { can.onmotion.toggle(can, can.ui.project) },
"首页": function(event, can) { can.sup.ondetail.show(can, 0) },
"上一页": function(event, can) { can.sup.ondetail.prev(can, can.ui.content) },
"菜单": function(event, can) { can.sup.ondetail.show(can, event.target.selectedIndex) },
"下一页": function(event, can) { can.sup.ondetail.next(can, can.ui.content) },
"隐藏": function(event, can) { can.onmotion.toggle(can, can._output) },
"结束": function(event, can) { can.page.Remove(can, can._target) },
"删除": function(event, sub) { sub.page.Remove(sub, sub._target) },
}) })

View File

@ -1,227 +1,384 @@
Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, conf, list, cb, target) {}, Volcanos(chat.ONIMPORT, {
_process: function(can, msg) { _process: function(can, msg) {
msg.OptionStatus() && can.onmotion.clear(can, can._status) && can.onappend._status(can, can.base.Obj(msg.OptionStatus())) if (msg.IsErr()) { can.onappend.style(can, "warn", can.user.toastFailure(can, msg.Result())._target) }
return can.core.CallFunc([can.onimport, msg.OptionProcess()], [can, msg]) if (can.onimport[msg.OptionProcess()]) { return can.core.CallFunc([can.onimport, msg.OptionProcess()], {can: can, sub: can.sub, msg: msg, arg: msg.Option("_arg")}), true }
}, },
_location: function(can, msg, arg) { can.user.jumps(arg) },
_location: function(can, msg) { location.href = msg._arg[0] }, _replace: function(can, msg, arg) { location.replace(arg) },
_rewrite: function(can, msg) { _history: function(can, msg) { history.length == 1? can.user.close(): history.back() },
for (var i = 0; i < msg._arg.length; i += 2) { _confirm: function(can, msg, arg) { can.user.toastConfirm(can, arg, "", function() { can.runAction(can.request({}, msg), "confirm") }) },
can.Option(msg._arg[i], msg._arg[i+1]) _refresh: function(can, msg, arg) { can.core.Timer(parseInt(arg||"30"), function() { can.Update(can.request({}, {_count: parseInt(msg.Option("_count")||"3")-1})) }) },
} _rewrite: function(can, msg) { var arg = msg._arg; for (var i = 0; i < arg.length; i += 2) {
can.Update() can.Option(arg[i], arg[i+1]), can.Action(arg[i], arg[i+1])
return true can.misc.sessionStorage(can, [can.ConfIndex(), ctx.ACTION, arg[i]], arg[i+1])
}, } can.Update() },
_refresh: function(can, msg) { _display: function(can, msg) { can.onappend._output(can, msg, msg.Option(ice.MSG_DISPLAY)) },
can.core.Timer(parseInt(msg.Option("_delay")||"500"), function() { _clear: function(can, msg) { can.onmotion.clear(can) },
var sub = can.request({}, {_count: parseInt(msg.Option("_count"))-1}) _inner: function(can, sub, msg) { sub = sub||can, can.onmotion.scrollIntoView(can, can.onappend.table(sub, msg)), can.onmotion.scrollIntoView(can, can.onappend.board(sub, msg)), can.onmotion.story.auto(sub) },
can.Update() _cookie: function(can, msg) { can.misc.Cookie(can, msg._arg[0], msg._arg[1])
}) if (msg._arg[2]) {
return true history.go(msg._arg[2])
}, can.onmotion.delay(can, function() { history.back() }, 300)
_display: function(can, msg) { } else {
Volcanos("some", {}, [msg.Option(ice.MSG_DISPLAY)].concat(Volcanos.meta.libs, Volcanos.meta.volcano), function(sub) { can.Update()
sub.Conf(can.Conf()), sub.run = can.run }
sub._option = can._option, sub._action = can._action },
sub.onimport._init(sub, msg, [], function() {}, can._output) _session: function(can, msg) { can.misc.sessionStorage(can, msg._arg[0], msg._arg[1]), can.Update() },
}) _field: function(can, msg, cb) {
return true can.user.isMobile && can.onmotion.clear(can, can._output)
}, can.page.style(can, can._target, "visibility", ""), can.page.style(can, can._output, "visibility", "")
_field: function(can, msg) { var height = can.ConfHeight()-can.onexport.actionHeight(can)-(can.onexport.statusHeight(can)||1), width = can.ConfWidth()
msg.Table(function(item) { can.onappend._plugin(can, item, {arg: can.base.Obj(item[ice.ARG], [])}, function(sub, meta) { var tabs = false, tabHash = msg.Option("field.tabs"); if (tabHash) {
var opt = can.base.Obj(item[ice.OPT], []) can.sub && can.sub.onimport.tabs(can.sub, [{name: tabHash.slice(0, 6)}], function() { can.onmotion.cache(can, function() { return tabHash }) }), tabs = true
sub.Conf(html.HEIGHT, can.Conf(html.HEIGHT)) } else {
sub.Conf(html.WIDTH, can.Conf(html.WIDTH)) if (msg.Length() > 1) {
sub.run = function(event, cmds, cb, silent) { height = height / msg.Length()
var res = can.request(event, can.Option()) } else if (can._output.innerHTML && !can.page.tagis(can._target, html.FIELDSET_OUTPUT)) {
for (var i = 0; i < opt.length; i += 2) { res.Option(opt[i], opt[i+1]) } height = can.base.Max(html.STORY_HEIGHT, height)
can.run(event, (msg[ice.MSG_PREFIX]||[]).concat(cmds), cb, true) }
} }
}) }) var option = can.base.Obj(msg.Option("field.option"))
return true msg.Table(function(item) { tabs && can.onmotion.cache(can, function() { return tabHash })
}, var sup = item.space? can._root.Action: can; height = can.base.Max(item._height||height, can.ConfHeight()), width = can.base.Max(item._width||width, can.ConfWidth())
_inner: function(can, msg) { can.onappend._plugin(sup, item, {index: item.index, args: can.base.Obj(item.args||item.arg, []), height: height, width: width, icons: item._icon}, function(sub) { can._plugins = (can._plugins||[]).concat([sub])
can.onappend.table(can, msg) sub.run = function(event, cmds, cb) { var index = msg.Option(ice.MSG_INDEX)||item.index; sup.run(can.request(event, {pod: item.space}, option), (msg[ice.FIELD_PREFIX]? msg[ice.FIELD_PREFIX]: index? [ctx.RUN, index]: []).concat(cmds), cb, true) }
can.onappend.board(can, msg) can.page.ClassList.has(can, sub._target, html.FLOAT)? can.onmotion.float(sub): sub.onimport.size(sub, height, width, !can.user.isMobile), cb && cb(sub)
can.onmotion.story.auto(can) if (item.style == html.FLOAT) { return } can.onmotion.delay(can, function() { can.onmotion.scrollIntoView(can, sub._target) }, 300)
can.page.Modify(can, can._output, {style: {display: html.BLOCK}}) sub.onexport.output = function() { if (tabs) { msg.Option(ice.MSG_ACTION) && can.onappend._action(can, msg.Option(ice.MSG_ACTION))
return true sub.sub.onimport.tabs(sub.sub, [{name: tabHash.slice(0, 6)}], function() { tabs || can.onmotion.cache(can, function() { return tabHash }) }), tabs = false
}, } }
}, item.style == html.FLOAT && can.page.tagis(can._target, "fieldset.story")? document.body: can._output)
_open: function(can, msg) { can.user.open(msg.Option("_arg")); return true }, })
_hold: function(can, msg) { return true }, },
_back: function(can) { _float: function(can, msg) { can.onimport._field(can, msg, function(sub) { can.onmotion.float(sub) }) },
can._history.pop(); for (var his = can._history.pop(); his; his = can._history.pop()) { _hold: function(can, msg, arg) { can.user.toast(can, arg||ice.SUCCESS) },
if (his[0] == ctx.ACTION) { continue } _back: function(can, msg, arg) { arg? (history.go(arg), can.onmotion.delay(can, function() { can.onimport.back({}, can) })): can.onimport.back({}, can) },
can.page.SelectArgs(can, can._option, "", function(item, index) { item.value = his[index]||"" }), can.Update() _rich: function(can, msg) { var sub = can.sub
break function _rich() {
} if (sub._rich_list.length == 0) { return } if (sub._rich_running) { return } sub._rich_running = true
!his && can.Update() var msg = sub._rich_list.shift(), list = msg.detail.slice(1)
return true if (!sub._rich._table) {
}, for (var i = 1; i < msg.detail.length; i += 2) { msg.Push(msg.detail[i], msg.detail[i+1]) }
sub._rich._table = can.page.SelectOne(can, can.onappend.table(sub._rich, msg), html.TBODY)
_grow: function(can, str) { } else { var list = []
if (can.page.Select(can, can._output, "div.code", function(div) { for (var i = 1; i < msg.detail.length; i += 2) { list.push(can.page.Color(msg.detail[i+1])) }
can.page.Modify(can, div, {style: {"max-height": 400}}) var tr = can.page.Append(can, sub._rich._table, [{td: list}]).tr; sub._rich._output.scrollTop += 100000
can.page.Append(can, div, [{text: [str]}]) can.onmotion.delayOnce(can, function() { can.onmotion.select(can, tr.parentNode, html.TR, tr) }, 500)
div.scrollBy(0, 10000) sub._rich.onappend._status(sub._rich, msg.Option(ice.MSG_STATUS), null, msg)
return true } can.core.Timer(msg.Option(cli.DELAY)||0, function() { sub._rich_running = false, _rich() })
}).length == 0) { }
can.onappend.board(can, str) if (sub._rich) {
} (sub._rich_list = sub._rich_list||[]).push(msg); return _rich()
}, } else {
(sub._rich_list = sub._rich_list||[]).push(msg); if (sub._rich_list.length > 1) { return }
}
var height = can.onexport.outputHeight(can)
can.onappend.plugin(can, {title: can.core.Keys(msg.Option(ice.MSG_TITLE)||"table.js"), index: "can._filter", height: height, style: "rich"}, function(sub) {
sub.onexport.output = function() {
can.page.style(can, sub._output, html.HEIGHT, "", html.MAX_HEIGHT, "")
can.sub._rich = sub.sub, _rich(), can.onmotion.scrollIntoView(can, sub._target)
}
}); return
},
_grow: function(can, msg, arg) {
var sub = can.sub
if (sub && sub.onimport && sub.onimport._grow) { return sub.onimport._grow(sub, msg, msg.detail[1], msg.detail[2]) }
if (sub && sub.onimport && sub.onimport.grow) { return sub.onimport.grow(sub, msg, msg.detail[1], msg.detail[2]) }
if (msg.Option(ctx.DISPLAY)) {
function _grow() { if (can.sub._grow_list.length == 0) { return } if (can.sub._grow_running) { return } can.sub._grow_running = true
var msg = can.sub._grow_list.shift(), text = msg.detail[1]; sub._grow.onappend._status(sub._grow, msg.Option(ice.MSG_STATUS), null, msg)
sub._grow._size = (sub._grow._size||0)+text.length, text && text.match(/\n/g) && (sub._grow._count = (sub._grow._count||0)+text.match(/\n/g).length)
if (msg.Option(cli.DELAY) && msg.Option(cli.DELAY) != "0") { var list = []; for (var i = 0; i < text.length; i++) { list.push(text[i]) }
can.core.Next(list, function(text, next) {
can.sub._grow.onimport.grow(can.sub._grow, msg, "current", text), can.core.Timer(msg.Option(cli.DELAY), next)
}, function() { can.sub._grow_running = false, _grow() })
} else {
can.sub._grow.onimport.grow(can.sub._grow, msg, "current", text), can.sub._grow_running = false, _grow()
} sub._grow.Status(mdb.COUNT, sub._grow._count), sub._grow.Status("msg", can.base.Size(sub._grow._size))
}
if (can.sub._grow) {
(can.sub._grow_list = can.sub._grow_list||[]).push(msg); return _grow()
} else {
(can.sub._grow_list = can.sub._grow_list||[]).push(msg); if (can.sub._grow_list.length > 1) { return }
}
var height = can.onexport.outputHeight(can)
can.onappend.plugin(can, {
index: "can._filter", display: msg.Option(ctx.DISPLAY), height: height,
title: can.core.Keys(msg.Option(ice.MSG_TITLE)||msg.Option(ctx.DISPLAY).split(nfs.PS).pop()),
}, function(sub) {
sub.onexport.output = function() { can.onmotion.scrollIntoView(can, sub._target), can.sub._grow = sub.sub, _grow() }
}); return
}
arg = can.page.Color(arg); if (!can.page.SelectOne(can, can._output, html.DIV_CODE, function(div) {
return can.page.style(can, div, html.MAX_HEIGHT, can.onexport.outputHeight(can)),
can.page.Append(can, div, [{text: arg}]), can._output.scrollTop = div.offsetTop, div.scrollBy(0, 10000), true
})) { can.onappend.board(can, arg) }
},
_open: function(can, msg, arg) { can.user.open(arg); msg._arg.length > 1 && can.Update() },
_close: function(can, msg) { can.user.close() || history.back() },
change: function(event, can, name, value, cb, data) { return can.page.SelectArgs(can, can._option, "", function(input) { if (input.name != name || value == input.value) { return }
can.page.Select(can, input.parentNode, "span.value", function(target) { target.innerText = value })
return input.value = value, can.Update(event, can.Input([], true, data), cb), input
})[0] },
_size: function(can, height, width, auto, mode) {},
size: function(can, height, width, auto, mode) { typeof width == code.STRING && (width = can.base.ParseSize(width))
can.Conf("_auto", auto), can.Mode(mode), can.ConfHeight(height), can.ConfWidth(width), height -= can.onexport.actionHeight(can)+(can.onexport.statusHeight(can)||(can.sub? 0: 1))
var padding = can.Conf("padding")||0, margin = can.Conf("margin")||0; height -= 2*padding, width -= 2*padding+2*margin
auto || auto == undefined? (can.page.style(can, can._output, html.HEIGHT, "", html.WIDTH, "", html.MAX_HEIGHT, height, html.MAX_WIDTH, width), can.page.style(can, can._target, html.HEIGHT, "", html.WIDTH, "")):
(can.page.style(can, can._output, html.HEIGHT, height, html.WIDTH, width, html.MAX_HEIGHT, "", html.MAX_WIDTH, ""), can.page.style(can, can._target, html.WIDTH, width))
if (can.misc.Search(can, log.DEBUG) == ice.TRUE) { can.Status(html.HEIGHT, can.base.Max(height, can._output.offsetHeight), html.WIDTH, width) }
can.page.style(can, can._status, html.MAX_WIDTH, width)
can.core.List(can._plugins, function(sub) { can.page.tagis(sub._target, "fieldset.float") || sub.onimport.size(sub, height, width, false) })
var sub = can.sub; if (!sub) { return auto } sub.Mode(mode), sub.ConfHeight(height), sub.ConfWidth(width), can.onimport._size(can)
mode? sub.onlayout[mode](sub, height, width): sub.onlayout._init(sub, height, width)
return auto
},
display_size: function(can, sub) { var border = 1
can.page.style(can, sub._output, html.MAX_HEIGHT, "")
var _height = can.base.Max(sub._target.offsetHeight+border, can.ConfHeight()/2)
sub.onimport.size(sub, _height-border, can.ConfWidth()-(can.ui && can.ui.project? can.ui.project.offsetWidth: 0), true)
},
back: function(event, can) { can._history.pop()
for (var i = 0, his = can._history.pop(); his; his = can._history.pop()) { if (his[0] == ctx.ACTION) { continue }
can.page.SelectArgs(can, can._option, "", function(target) { target.value = his[i++]||"", can.page.Select(can, target.parentNode, "span.value", function(target) { target.innerText = target.value||"" }) })
can.page.SelectArgs(can, can._action, "", function(target) { target.value = his[i++]||"" }); break
}
can.onexport.hash(can, ""), can.Update(event)
},
}) })
Volcanos("onaction", {help: "交互操作", list: [ Volcanos(chat.ONACTION, {
"共享工具", "生成链接", "生成脚本", "保存参数", "清空参数", "刷新数据", [ list: ["刷新数据",
"其它 ->", "复制数据", "下载数据", "清空数据", "删除工具", "摄像头", "生成图片", function(can) { if (!can.user.isMobile) { return "刷新界面" } },
], function(can) { if (!can.user.isMobile && !can.isCmdMode()) { return "切换浮动" } },
], _init: function(can, msg, list, cb, target) {}, function(can) { if (!can.user.isMobile && !can.isCmdMode()) { return "切换全屏" } },
_engine: function(event, can, button) { function(can) { if (can.isCmdMode()) { return "打开首页" } },
can.Update(event, [ctx.ACTION, button].concat(can.Input([], true))) function(can) { if (can.ConfSpace() || can.isCmdMode() && can.misc.Search(can, ice.POD)) { return "打开空间" } },
}, function(can) { if (!can.isCmdMode()) { return "打开链接" } },
"共享工具": function(event, can) { var meta = can.Conf() "生成链接", "共享工具", "发送聊天",
var ui = can.user.input(event, can, [{name: chat.TITLE, value: meta.name}], function(ev, button, data, list) { function(can) { if (can.Conf("_help")) { return "查看文档" } },
var msg = can.request(event, {arg: [mdb.TYPE, chat.FIELD, function(can) { if (can.misc.Search(can, ice.MSG_DEBUG)) { return "查看脚本" } },
mdb.NAME, meta.index, mdb.TEXT, JSON.stringify(can.Input([], true)), function(can) { if (can.misc.Search(can, ice.MSG_DEBUG)) { return "查看源码" } },
chat.TITLE, list[0], chat.RIVER, can.Conf(chat.RIVER), chat.STORM, can.Conf(chat.STORM), function(can) { if (can.misc.Search(can, ice.MSG_DEBUG)) { return "查看镜像" } },
]}) ["视图", "参数", "插件",
can.search(event, ["Header.onaction.share"]) function(can) { if (can._action.innerHTML) { return "操作" } },
}); can.onlayout.figure(event, can, ui._target, true) function(can) { if (can._status.innerHTML) { return "状态" } },
}, function(can) { if (can.sub && can.sub.ui.project) { return "专注" } },
"生成链接": function(event, can) { var meta = can.Conf() function(can) { if (can.sub && can.sub.ui.project) { return "项目" } },
var pre = "/chat/cmd/"; if (can.user.mod.isPod) { pre = "/chat/pod/"+can.misc.Search(can, ice.POD)+"/cmd/" } function(can) { if (can.sub && can.sub.ui.profile) { return "预览" } },
var args = can.Option(); args._path = pre+(meta.index||can.core.Keys(meta.ctx, meta.cmd)) function(can) { if (can.sub && can.sub.ui.display) { return "演示" } },
args._path.indexOf("/cmd/web.wiki.word") > -1 && (args = {_path: pre+args.path}) ],
function(can) { if (can.misc.Search(can, ice.MSG_DEBUG)) {
return ["调试",
function(can) { if (can.Conf("_help")) { return "查看文档" } },
"查看脚本", "查看源码", "查看镜像",
"查看通知", "查看视图", "查看数据", "会话存储", "本地存储",
"查看报文", "查看配置", "查看日志", "删除工具",
]
} },
],
_engine: function(event, can, button) { can.Update(event, [ctx.ACTION, button].concat(can.Input())) },
_switch: function(can, sub, mode, save, load) {
if (can.page.ClassList.neg(can, can._target, mode)) { can._mode_list = can._mode_list||[]
can._mode_list.push(kit.Dict(
html.HEIGHT, can.ConfHeight(), html.WIDTH, can.ConfWidth(), ice.MODE, can.Mode()||"",
html.ACTION, can.page.isDisplay(can._action), html.STATUS, can.page.isDisplay(can._status),
html.OUTPUT, can.base.Copy({}, can._output.style, html.HEIGHT, html.WIDTH, html.MAX_HEIGHT, html.MAX_WIDTH),
ctx.STYLE, can.base.Copy({}, can._target.style, html.LEFT, html.TOP, html.RIGHT, html.BOTTOM), save()
)), can.onimport.size(can, can.ConfHeight(), can.ConfWidth(), false, mode)
} else {
var back = (can._mode_list = can._mode_list||[]).pop(); if (!back) { return }
can.onmotion.toggle(can, can._action, back.action), can.onmotion.toggle(can, can._status, back.status)
can.onimport.size(can, back.height, back.width, false, back.mode), can.page.style(can, can._target, back.style), load && load(back)
}
},
"刷新数据": function(event, can) { can.Update(event, can.Input()), can.user.toastSuccess(can) },
"刷新界面": function(event, can) { var sub = can.sub; sub.onlayout._init(sub, sub.ConfHeight(), sub.ConfWidth()), can.user.toastSuccess(can) },
"切换浮动": function(event, can, button, sub) {
can.onaction._switch(can, sub, chat.FLOAT, function() { can.onmotion.float(can) })
},
"切换全屏": function(event, can, button, sub) { can.onaction._switch(can, sub, chat.FULL, function() {
can.page.style(can, can._target, html.LEFT, "", html.TOP, can.onexport.marginTop(), html.BOTTOM, "")
can.ConfHeight(can.page.height()-can.onexport.marginTop()-can.onexport.marginBottom(can)), can.ConfWidth(can.page.width())
}) },
"远程控制": function(event, can) { can.onaction.keyboard(event, can) },
"共享工具": function(event, can) { var meta = can.Conf(); can.onmotion.share(can.request(event, {pod: can.ConfSpace()}), can, [], [mdb.NAME, meta.index, mdb.TEXT, JSON.stringify(can.Input())]) },
"打开首页": function(event, can) { can.user.open(location.origin) },
"打开空间": function(event, can) { can.user.open(can.misc.MergePodCmd(can, {pod: can.ConfSpace()||can.misc.Search(can, ice.POD)})) },
"打开链接": function(event, can) { can.user.open(can.onexport.link(can)) },
"发送聊天": function(event, can) {
can.user.input(event, can, [{name: chat.MESSAGE, display: "/require/usr/icebergs/core/chat/message.js", run: function(event, cmds, cb) {
can._root.Header.run(can.request(event, {pod: can.ConfSpace()}), [ctx.ACTION, chat.MESSAGE].concat(cmds), function(msg) { cb(msg) })
}}], function(list) { var args = can.core.Item(can.Option(), function(key, value) { return value })
can._root.Header.run(can.request(event, {pod: can.ConfSpace()}), [ctx.ACTION, chat.MESSAGE, list[0],
mdb.TYPE, "plug", ctx.INDEX, can.ConfIndex(), ctx.ARGS, args.length < 2? args[0]||"": JSON.stringify(args)])
can.onappend._float(can, chat.MESSAGE)
})
},
"生成链接": function(event, can) { can.onmotion.share(event, can, [], [web.LINK, can.user.copy(event, can, can.onexport.link(can))]) },
"生成脚本": function(event, can) { var args = can.Input().join(lex.SP), list = [
"export ctx_dev="+location.origin+"; ctx_temp=$(mktemp); curl -o $ctx_temp -fsSL $ctx_dev;"+" source $ctx_temp cmd "+(can.Conf(ctx.INDEX))+lex.SP+args,
"ish_sys_dev_run_command "+args, "ish_sys_dev_run_action", "ish_sys_dev_run_source",
]; can.user.copy(event, can, list[0]) },
"生成图片": function(event, can) { can.user.toimage(can, can.name) },
var msg = can.request(event, {link: can.misc.MergeURL(can, args)}) _view: function(can, cb) { var sub = can.sub; cb(sub), sub.onimport.layout(sub) },
can.search(event, ["Header.onaction.share"]) "参数": function(event, can) { can.onaction._view(can, function(sub) { can.onmotion.toggle(can, can._option) }) },
}, "操作": function(event, can) { can.onaction._view(can, function(sub) { can.onmotion.toggle(can, can._action) }) },
"生成脚本": function(event, can, button) { var conf = can.Conf() "状态": function(event, can) { can.onaction._view(can, function(sub) { can.onmotion.toggle(can, can._status) }) },
var args = can.Input("", true).join(ice.SP); var list = [ "专注": function(event, can) { can.onaction._view(can, function(sub) { if (!sub.ui) { return }
"export ctx_dev="+location.origin+"; ctx_temp=$(mktemp); curl -fsSL $ctx_dev -o $ctx_temp;"+" source $ctx_temp "+(conf.index||"")+ice.SP+args, sub.ui.project && can.onmotion.hidden(can, sub.ui.project)
"ish_sys_dev_run_command "+args, "ish_sys_dev_run_action", "ish_sys_dev_run_source", sub.ui.profile && can.onmotion.hidden(can, sub.ui.profile)
] sub.ui.display && can.onmotion.hidden(can, sub.ui.display)
var ui = can.user.toast(can, {title: button, duration: -1, width: -300, }) },
content: '<div class="story" data-type="spark", data-name="shell">'+ "项目": function(event, can) { can.onaction._view(can, function(sub) { sub.ui && sub.ui.project && can.onmotion.toggle(can, sub.ui.project) }) },
'<label>$ </label>'+'<span>'+list.join("</span><br/><label>$ </label><span>")+'</span>'+'</div>', "预览": function(event, can) { can.onaction._view(can, function(sub) { sub.ui && sub.ui.project && can.onmotion.toggle(can, sub.ui.profile) }) },
action: [cli.CLOSE], "演示": function(event, can) { can.onaction._view(can, function(sub) { sub.ui && sub.ui.project && can.onmotion.toggle(can, sub.ui.display) }) },
}) "插件": function(event, can) {
can.onmotion.story.auto(can, ui._target) can.user.input(event, can, [ctx.INDEX, ctx.ARGS], function(data) {
can.user.copy(event, can, list[0]) var sub = can.sub; sub.onimport.tool(sub, [data], function(sub) { sub.select() })
}, })
"保存参数": function(event, can) { var meta = can.Conf() },
var msg = can.request(event, {river: can.Conf(chat.RIVER), storm: can.Conf(chat.STORM), id: meta.id})
can.search(event, ["River.ondetail.保存参数"], function(msg) { can.user.toastSuccess(can) }, true)
},
"清空参数": function(event, can) {
can.page.SelectArgs(can, can._option, "", function(item) { return item.value = "" })
},
"刷新数据": function(event, can) { can.Update({}, can.Input([], true)) },
"复制数据": function(event, can) { var meta = can.Conf(), msg = can._msg "保存参数": function(event, can) { can.search(event, ["River.ondetail.保存参数"]) },
var res = [msg.append && msg.append.join(",")]; msg.Table(function(line, index, array) { "清空参数": function(event, can) { can.page.SelectArgs(can, can._option, "", function(target) { return target.value = "" }) },
res.push(can.core.Item(line, function(key, value) { return value }).join(",")) "复制数据": function(event, can) { var sub = can.sub; can.user.copy(event, can, sub.onexport.table(sub)||sub.onexport.board(sub)) },
}) "下载数据": function(event, can) { var sub = can.sub; can.user.input(event, can, [{name: "filename", value: can.Conf(mdb.NAME)}], function(list) {
can.user.downloads(can, sub.onexport.table(sub), list[0], nfs.CSV), can.user.downloads(can, sub.onexport.board(sub), list[0], nfs.TXT)
}) },
"清空数据": function(event, can) { can.onmotion.clear(can, can._output) },
res.length > 1 && can.user.copy(event, can, res.join(ice.SP)) "查看文档": function(event, can) { can.requests(event, {action: ice.HELP}), can.onengine.signal(can, chat.ONDEBUGS, can.requestPodCmd(event)) },
msg.result && can.user.copy(event, can, msg.Result()) "查看脚本": function(event, can) { can.onappend._float(can, web.CODE_VIMER, can.misc.SplitPath(can, can.sub._path)) },
}, "查看源码": function(event, can) { can.requests(event, {action: nfs.SOURCE}), can.onengine.signal(can, chat.ONDEBUGS, can.requestPodCmd(event)) },
"下载数据": function(event, can) { var meta = can.Conf(), msg = can._msg "查看镜像": function(event, can) { can.onappend._float(can, {index: "web.code.compile"}) },
var res = [msg.append && msg.append.join(",")]; msg.Table(function(line, index, array) { "查看通知": function(event, can) { can.onappend._float(can, {index: "can.toast"}, [can.ConfIndex()]) },
res.push(can.core.Item(line, function(key, value) { return value }).join(",")) "查看视图": function(event, can) { can.onappend._float(can, {index: "can.view", _target: can._fields||can._target}) },
}) "查看数据": function(event, can) { can.onappend._float(can, {index: "can.data", _target: can}) },
"会话存储": function(event, can) { can.onappend._float(can, {index: "can.sessionStorage"}, [can.ConfIndex()]) },
"本地存储": function(event, can) { can.onappend._float(can, {index: "can.localStorage"}, [can.ConfIndex()]) },
"查看报文": function(event, can) { var msg = can._msg
can.onappend._float(can, {title: "msg(报文)", index: ice.CAN_PLUGIN, display: "/plugin/story/json.js"}, [], function(sub) {
sub.run = function(event, cmds, cb) { var _msg = can.request(event); _msg.result = [JSON.stringify(msg)], cb(_msg) }
})
},
"查看配置": function(event, can) { can.requests(event, {action: ctx.CONFIG}), can.onengine.signal(can, chat.ONDEBUGS, can.requestPodCmd(event)) },
"查看日志": function(event, can) { var logid = can.Status("log.id"); can.onappend._float(can, web.CODE_XTERM, ["sh", logid, "grep "+logid+" var/log/bench.log | grep -v grep | grep -v '"+logid+" $'"]) },
"打包页面": function(event, can) { can.onengine.signal(can, "onwebpack", can.request(event)) },
"删除工具": function(event, can) { can.onaction._close(event, can) },
res.length > 1 && can.user.downloads(can, res.join("\n"), meta.name+".csv") refresh: function(event, can) { can.onimport.size(can, can.ConfHeight(), can.ConfWidth(), true, can.Mode()) },
msg.result && can.user.downloads(can, msg.Result(), meta.name+".txt") detail: function(event, can) { var msg = can.request(event)
}, can.core.Item(can.Option(), function(key, value) {
"清空数据": function(event, can) { can.onmotion.clear(can, can._output) }, can.Option(key, msg.Option(key)||"")
"删除工具": function(event, can) { can.page.Remove(can, can._target) }, }), can.Update()
"生成图片": function(event, can) { },
can.user.toPNG(can, "hi.png", can._target.outerHTML, can.Conf(html.HEIGHT), can.Conf(html.WIDTH)) close: function(event, can) {
}, if (can.isCmdMode()) {
can.user.close()
"摄像头": function(event, can) { } else if (can.isFullMode()) {
var constraints = {audio: false, video: {width: 200, height: 200}} can.onaction["切换全屏"](event, can, "切换全屏", can.sub)
var ui = can.page.Append(can, can._output, [{view: ctx.ACTION}, {view: "capture", list: [{type: "video", _init: function(item) { } else if (can.isFloatMode()) {
navigator.mediaDevices.getUserMedia(constraints).then(function(stream) { can.onaction["切换浮动"](event, can, "切换浮动", can.sub)
item.srcObject = stream, item.onloadedmetadata = function(e) { } else {
item.play() can.onaction._close(event, can), can.onexport.close(can)
}, ui.stream = stream }
}).catch(function(err) { console.log(err.name + ": " + err.message); }) },
}}]}]) _close: function(event, can) {
can.onengine.signal(can, "onremove", can.request(event, {query: can.page.getquery(can, can._target)}))
can.onappend._action(can, ["关闭", "抓拍"], ui.action, { can.page.Remove(can, can._target)
"抓拍": function(event) { },
var canvas = can.page.Append(can, ui.capture, [{type: "canvas", width: ui.video.offsetWidth, height: ui.video.offsetHeight}]).first clear: function(event, can) { can.onmotion.clear(can, can._output) },
canvas.getContext("2d").drawImage(ui.video, 0, 0) actions: function(event, can) { can.onmotion.toggle(can, can._action) },
can.page.Append(can, ui.capture, [{img: canvas.toDataURL('image/png'), style: {width: ui.video.offsetWidth, height: ui.video.offsetHeight}}]) help: function(event, can) {
can.page.Remove(can, canvas) can.onappend._float(can, {index: web.WIKI_WORD}, [can.Conf("_help")])
}, },
"关闭": function(event) { full: function(event, can) { can.onaction["切换全屏"](event, can, "切换全屏", can.sub) },
can.core.List(ui.stream.getTracks(), function(track) { track.stop() }) prev: function(event, can) { can.runAction(event, mdb.PREV, [can.Status(mdb.TOTAL)||0, can.Option(mdb.LIMIT)||can.Action(mdb.LIMIT)||can._msg.Option("cache.limit")||"", can.Option(mdb.OFFEND)||can.Action(mdb.OFFEND)||""], function(msg) { can.onimport._process(can, msg) }) },
can.page.Remove(can, ui.action) next: function(event, can) { can.runAction(event, mdb.NEXT, [can.Status(mdb.TOTAL)||0, can.Option(mdb.LIMIT)||can.Action(mdb.LIMIT)||can._msg.Option("cache.limit")||"", can.Option(mdb.OFFEND)||can.Action(mdb.OFFEND)||""], function(msg) { can.onimport._process(can, msg) }) },
can.page.Remove(can, ui.video) upload: function(event, can) { can.user.upload(event, can) },
can.page.Remove(can, ui.capture) keyboard: function(event, can) {
}, can.base.isUndefined(can._daemon) && can.ondaemon._list[0] && (can._daemon = can.ondaemon._list.push(can)-1)
}) can.request(event, kit.Dict(ctx.INDEX, can._index, ice.MSG_DAEMON, can.core.Keys(can.ondaemon._list[0], can._daemon)))
}, can.runAction(event, "keyboard", [], function(msg) { can.user.copy(msg._event, can, msg.Append(mdb.NAME))
can.user.toast(can, {title: msg.Append(mdb.NAME), duration: -1, content: msg.Append(mdb.TEXT), action: [cli.CLOSE, cli.OPEN]})
actions: function(event, can) { can.onmotion.toggle(can, can._action) }, })
clear: function(event, can, name) { can.onmotion.clear(can, can._output) }, },
close: function(event, can) { can.page.Remove(can, can._target) },
upload: function(event, can) { can.user.upload(event, can) },
change: function(event, can, name, value, cb) {
return can.page.SelectArgs(can, can._option, "", function(input) {
if (input.name == name && value != input.value) { input.value = value
var data = input.dataset||{}; can.Update(event, can.Input(), cb)
return input
}
})
},
next: function(event, can) {
can.Update(event, [ctx.ACTION, "next", can.Status("total")||0, can.Option("limit"), can.Option("offend")])
},
prev: function(event, can) {
can.Update(event, [ctx.ACTION, "prev", can.Status("total")||0, can.Option("limit"), can.Option("offend")])
},
listTags: function(event, can, button) { var list = []
can.core.List([can.base, can.core, can.misc, can.page, can.user,
can.onengine, can.ondaemon, can.onappend, can.onlayout, can.onmotion, can.onkeypop,
], function(lib) {
can.core.Item(lib, function(key, value) { if (key.indexOf("_") == 0 || !lib.hasOwnProperty(key)) { return }
list.push({zone: lib._name, type: typeof value, name: key, text: can.base.isObject(value)? "": (value+"").split(ice.NL)[0],
path: "usr/volcanos/", file: lib._path, line: 1,
})
})
})
var msg = can.request(event, {_handle: true, text: can.base.Format(list)})
can.run(event, [ctx.ACTION, button], function() { can.user.toastSuccess(can) })
},
getClipboardData: function(event, can, button) {
function add(text) {
can.run(event, can.base.Simple(ctx.ACTION, button, can.base.ParseJSON(text)), function(msg) {
can.user.toastSuccess(can), can.Update()
}, true)
}
if (navigator.clipboard) {
navigator.clipboard.readText().then(add).catch(function(err) { can.misc.Log(err) })
} else {
can.user.input(event, can, [{type: html.TEXTAREA, name: mdb.TEXT}], function(ev, button, data, list, args) { add(list[0]) })
}
},
getLocation: function(event, can, button) {
can.user.agent.getLocation(function(data) { can.request(event, data)
can.user.input(event, can, [mdb.TYPE, mdb.NAME, mdb.TEXT, "latitude", "longitude"], function(ev, bu, data, list, args) {
can.run(event, [ctx.ACTION, button].concat(can.base.Simple(args, data)), function(msg) {
can.user.toastSuccess(can), can.Update()
}, true)
})
})
},
openLocation: function(event, can) { can.user.agent.openLocation(can.request(event)) },
getClipboardData: function(event, can, button) {
function add(text) { can.runAction(event, button, can.base.Simple(can.base.ParseJSON(text)), function() { can.Update() }) }
navigator.clipboard? navigator.clipboard.readText().then(add).catch(function(err) { can.misc.Log(err) }):
can.user.input(event, can, [{type: html.TEXTAREA, name: mdb.TEXT}], function(list) { add(list[0]) })
},
getLocation: function(event, can, button) { can.user.agent.getLocation(can, function(data) {
can.user.input(can.request(event, data), can, [mdb.TYPE, mdb.NAME, mdb.TEXT, aaa.LATITUDE, aaa.LONGITUDE], function(args) {
can.runAction(event, button, args, function() { can.Update() })
})
}) },
openLocation: function(event, can) { can.user.agent.openLocation(can, can.request(event)) },
scanQRCode0: function(event, can, button) { can.user.agent.scanQRCode(can) },
scanQRCode: function(event, can, button) { can.user.agent.scanQRCode(can, function(data) { can.runAction(event, button, can.base.Simple(data), function() { can.Update() }) }) },
record0: function(event, can, name, cb) { can.user.input(event, can, [{name: nfs.FILE, value: name}], function(list) {
navigator.mediaDevices.getDisplayMedia({video: {height: window.innerHeight}}).then(function(stream) { var toast
can.core.Next([3, 2, 1], function(item, next) { toast = can.user.toast(can, item + "s 后开始截图"), can.onmotion.delay(can, next, 1000) }, function() { toast.close()
cb(stream, function(blobs, ext) { var msg = can.request(event); msg._upload = new File(blobs, list[0]+nfs.PT+ext)
can.runAction(msg, html.UPLOAD, [], function() { can.user.toastSuccess(can), can.Update() })
can.core.List(stream.getTracks(), function(item) { item.stop() })
})
})
}).catch(function(err) { can.user.toast(can, err.name + ": " + err.message) })
}) },
record1: function(event, can) { can.onaction.record0(event, can, "shot", function(stream, cb) { var height = window.innerHeight
var video = can.page.Append(can, document.body, [{type: html.VIDEO, height: height}])._target; video.srcObject = stream, video.onloadedmetadata = function() { video.play(), width = video.offsetWidth
var canvas = can.page.Append(can, document.body, [{type: html.CANVAS, height: height, width: width}])._target; canvas.getContext("2d").drawImage(video, 0, 0, width, height)
canvas.toBlob(function(blob) { cb([blob], nfs.PNG) })
}
}) },
record2: function(event, can) { can.onaction.record0(event, can, "shot", function(stream, cb) {
var recorder = new MediaRecorder(stream, {mimeType: html.VIDEO_WEBM}), blobs = []; recorder.ondataavailable = function(res) { blobs.push(res.data) }
recorder.onstop = function() { cb(blobs, nfs.WEBM) }, recorder.start(1)
}) },
})
Volcanos(chat.ONEXPORT, {
_output: function(can, msg) {},
output: function(can, msg) {}, action: function(can, button, data) {}, record: function(can, value, key, data) {},
marginTop: function() { return 0 }, marginBottom: function() { return 0 }, outputMargin: function(can) { return 0 },
actionHeight: function(can) { return can.page.ClassList.has(can, can._target, html.OUTPUT)? 0: html.ACTION_HEIGHT },
outputHeight: function(can) { var height = can.ConfHeight() - can.onexport.actionHeight(can) - can.onexport.statusHeight(can)
if (can.user.isMobile) { return height } height -= can.onexport.outputMargin(can)
can.page.SelectChild(can, can._output, html.TABLE, function(target) { height -= target.offsetHeight })
return can.base.Max(can.base.Min(height, can.ConfHeight()/2), can.ConfHeight()-2*html.ACTION_HEIGHT, 320)
},
statusHeight: function(can) {
return can.page.ClassList.has(can, can._target, html.OUTPUT) || !can.page.isDisplay(can._status) || (can._target.offsetHeight > 0 && can._status.offsetHeight == 0) ||
can._status.innerHTML == "" && !can.page.ClassList.has(can, can._target, html.PLUG)? 0: html.STATUS_HEIGHT
},
session: function(can, key, value) { if (value) { value = JSON.stringify(value) }
return can.misc.sessionStorage(can, [can.ConfSpace()||can.misc.Search(can, ice.POD), can.ConfIndex(), key, location.pathname], value)
},
storage: function(can, key, value) { if (value) { value = JSON.stringify(value) }
return can.misc.localStorage(can, [can.ConfSpace()||can.misc.Search(can, ice.POD), can.ConfIndex(), key], value)
},
hash: function(can, hash) {
if (can.user.isMobile) { return }
can.misc.SearchHash(can, hash), can.onexport.storage(can, "hash", hash)
return hash
},
title: function(can, title) { if (!can.isCmdMode()) { return }
var list = []; function push(p) { p && list.indexOf(p) == -1 && list.push(p) }
if (!can.user.isMobile) {
if (arguments.length == 2 && !can.base.isIn(can.ConfIndex(), web.PORTAL, code.VIMER, wiki.FEEL)) { push(can.user.trans(can, can.ConfIndex().split(".").pop(), can.ConfHelp())) }
}
can.core.List(arguments, function(title, index) { index > 0 && push(title) })
can.user.isMobile || push(can.user.mod.isPod? can.user.info.titles||can.ConfSpace()||can.misc.Search(can, ice.POD): location.host)
can.user.title(list.join(" "))
},
args: function(can) { return can.Option() },
link: function(can) {
// if (can.sub && can.sub.onexport.link) { return can.sub.onexport.link(can.sub) }
var args = can.Option(); args.pod = can.ConfSpace()||can.misc.Search(can, ice.POD), args.cmd = can.ConfIndex()
can.core.Item(args, function(key, value) { key != ice.POD && !value && delete(args[key]) })
var hash = can.onexport.storage(can, "hash")||""; can.base.isArray(hash) && (hash = hash.join(":")), hash && (hash = "#"+hash)
return can.base.replaceAll(can.misc.MergePodCmd(can, args, true), "%2F", "/")+hash
},
close: function(can, msg) {},
}) })
Volcanos("onexport", {help: "导出数据", list: []})

27
plugin/story/china.js Normal file
View File

@ -0,0 +1,27 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg) { var field = can.Conf(mdb.FIELD)||mdb.VALUE, cache = {}, path = msg.Option(nfs.PATH)||can.Conf(nfs.PATH)||"10"
var max = 0, data = msg.Table(function(value) { if (parseFloat(value[field]) > max) { max = parseFloat(value[field]) } return {name: value.name, value: value[field]} })
var option = {title: {text: msg.Option("title")||can.Conf("title"), textStyle: {fontSize: '24'}, left: '5%'},
tooltip: {formatter: function (item) { return item.name+': '+(item.value||"0") }}, visualMap: {min: 0, max: max, text: [max]},
}
if (can.Conf(ctx.STYLE) == html.FLOAT && !can.page.ClassList.has(can, can._fields, html.FLOAT)) { msg.Option(ice.MSG_STATUS, ""), can.onlayout._float(can) }
can.page.requireModules(can, ["echarts/dist/echarts.min.js"], function() { can.misc.GET(can, "/wiki/geoarea/city.json", function(text) { can.onimport.adcode = JSON.parse(text)
!can.onimport.adcode[path] && can.core.Item(can.onimport.adcode, function(code, list) { list.name == path && (path = code) })
can.page.style(can, can._output, html.HEIGHT, can.ConfHeight(), html.WIDTH, can.ConfWidth())
function load(path, name) { if (cache[path]) { return cache[path]._tabs.click() } can.onimport.load(can, path, function(text) { echarts.registerMap(path, JSON.parse(text))
can.onimport.tabs(can, [{name: name}], function(event, tabs) { var list = can.onimport.adcode[path]; msg.Length() == 0 && can.Status(mdb.COUNT, list && list.list? can.core.Item(list.list).length: 0)
if (cache[path]) { return can.page.SelectChild(can, can._output, html.DIV_ITEM, function(target) { can.onmotion.toggle(can, target, target == cache[path]) }) }
var chart = echarts.init(cache[path] = can.page.Append(can, can._output, [{view: html.ITEM, style: {height: can.ConfHeight(), width: can.ConfWidth()}}])._target)
option.series = [{data: data, mapType: path, type: "map"}], option.geo = {map: path}, chart.setOption(option)
chart.on(html.CLICK, function(item) { if (list && list.list) { var code = list.list[item.name]; code && load(code, item.name) } })
cache[path]._tabs = tabs._target, can.page.SelectChild(can, can._output, html.DIV_ITEM, function(target) { can.onmotion.toggle(can, target, target == cache[path]) })
}, function() { can.page.Remove(can, cache[path]), delete(cache[path]) })
}) } load(path, can.onimport.adcode[path].name)
}) })
}, adcode: {},
load: function(can, path, cb) { var _path = path
path.length == 2 && (path += "0000"), path.length == 4 && (path += "00")
path = "/wiki/geoarea/"+path+(can.base.endWith(path, "00")? "_full": "")+".json"
can.misc.GET(can, path, function(text) { text? cb(text): can.misc.GET(can, path.replace("_full", ""), cb) })
},
})

42
plugin/story/editor.css Normal file
View File

@ -0,0 +1,42 @@
fieldset.tinymce div.tox-tinymce,
fieldset.tinymce div.tox:not(.tox-tinymce-inline) .tox-editor-header {
border:none;
}
fieldset.tinymce div.tox-promotion { display:none; }
fieldset.tinymce div.tox div.tox-sidebar-wrap div.tox-edit-area iframe {
background-color:var(--output-bg-color);
}
div.tox .tox-collection--list .tox-collection__item--active,
div.tox .tox-collection--list .tox-collection__item--active:not(.tox-collection__item--state-disabled),
div.tox .tox-collection--list .tox-collection__item--enabled,
fieldset.tinymce div.tox .tox-mbtn:hover:not(:disabled):not(.tox-mbtn--active),
fieldset.tinymce div.tox .tox-mbtn:focus:not(:disabled),
fieldset.tinymce div.tox .tox-mbtn--active,
fieldset.tinymce div.tox .tox-tbtn:hover {
background-color:var(--hover-bg-color);
color:var(--hover-fg-color);
}
div.tox .tox-menu,
div.tox .tox-collection__item,
fieldset.tinymce div.tox .tox-editor-header,
fieldset.tinymce div.tox .tox-mbtn,
fieldset.tinymce div.tox .tox-menubar,
fieldset.tinymce div.tox .tox-toolbar,
fieldset.tinymce div.tox .tox-toolbar-overlord,
fieldset.tinymce div.tox .tox-toolbar__overflow,
fieldset.tinymce div.tox .tox-toolbar__primary,
fieldset.tinymce div.tox .tox-statusbar,
fieldset.tinymce div.tox .tox-statusbar__path-item,
fieldset.tinymce div.tox .tox-statusbar__wordcount,
fieldset.tinymce div.tox .tox-statusbar a {
background-color:var(--plugin-bg-color);
color:var(--plugin-fg-color);
}
fieldset.tinymce div.tox .tox-tbtn svg,
fieldset.tinymce div.tox .tox-tbtn:disabled svg,
fieldset.tinymce div.tox .tox-tbtn:disabled:hover svg,
fieldset.tinymce div.tox .tox-tbtn--disabled svg,
fieldset.tinymce div.tox .tox-tbtn--disabled:hover svg,
fieldset.tinymce div.tox .tox-statusbar__branding svg {
fill:var(--plugin-fg-color);
}

67
plugin/story/editor.js Normal file
View File

@ -0,0 +1,67 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg, cb) {
can.require(["/require/modules/tinymce/tinymce.min.js", "/plugin/local/code/vimer.js"], function(can) { can.onimport._last_init(can, msg, function(msg) {
can.onappend.style(can, "tinymce"), cb && cb(msg)
}) })
},
content: function(can, text) { return can.ui.editor.setContent(text) },
layout: function(can) { can.page.style(can, can.ui.content, html.HEIGHT, can.ConfHeight(), html.WIDTH, can.ConfWidth()) },
}, [""])
Volcanos(chat.ONSYNTAX, {
_split: function(can, msg, target) {
var _target = can.page.Appends(can, target, [{type: html.TEXTAREA}])._target
tinymce.init({target: _target, height: can.ConfHeight(), // menubar: false,
save_onsavecallback: function () { can.onaction.save({}, can, nfs.SAVE) },
content_style: "body#tinymce { background:transparent; color:silver; }",
toolbar: [[
"save code undo redo cut copy paste",
"backcolor forecolor bold italic underline strikethrough subscript superscript",
"alignleft aligncenter alignright alignjustify outdent indent",
"bullist numlist table image media link charmap",
"blockquote removeformat hr pagebreak anchor insertdatetime",
"fullscreen wordcount preview print help",
].join("|")],
plugins: [
"save",
"code",
"lists",
"advlist",
"table",
"image",
"media",
"link",
"insertdatetime",
"charmap",
"anchor",
"pagebreak",
"fullscreen",
"wordcount",
"preview",
"help",
"autosave",
"codesample",
"directionality",
"emoticons",
"importcss",
"font_size",
"autolink",
"nonbreaking",
"searchreplace",
"visualblocks",
"visualchars",
].join(" ")
}).then(function(list) { can.ui.editor = list[0], can.ui.editor.setContent(msg.Result()) }).catch(function(err) { can.misc.Warn(err) })
},
})
Volcanos(chat.ONEXPORT, {
content: function(can) { return can.ui.editor.getContent() },
})
Volcanos(chat.ONPLUGIN, {
tinymce: shy("富文本", {
save: shy(function(can, msg) { can.user.toast(can, msg.Option(nfs.CONTENT)) }),
}, [nfs.PATH, nfs.FILE, nfs.LINE, ice.LIST, nfs.SAVE], function(can, msg, meta) {
msg.Display(meta._path)
}),
})

21
plugin/story/form.js Normal file
View File

@ -0,0 +1,21 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg) { can.onappend.style(can, html.FORM, can._output)
if (can.isCmdMode()) { can.onappend.style(can, html.OUTPUT) }
can.page.Append(can, can._output, msg.Table(function(item) {
return {view: [[html.ITEM, item.type]], list: [item.type != html.BUTTON && {text: [can.user.trans(can, item.name, item._trans, html.INPUT), "", mdb.NAME]}, item.need == "must" && {text: ["*", "", "need"]}], _init: function(target) {
item.type == html.BUTTON && (item.onclick = function(event) { var args = []
can.core.Item(can.page.SelectArgs(can, can._output)[0], function(key, value) { args.push(key, value) })
can.Update(can.request(event, {_handle: ice.TRUE}), [ctx.ACTION, item.name].concat(args), function(msg) {
if (msg.IsErr()) {
can.user.toastFailure(can, msg.Result())
return
}
can.Update()
})
}), can.onappend.input(can, item, "", target)
}, onclick: function(event) {
can.page.Select(can, event.currentTarget, html.INPUT, function(target) { target.focus() })
}}
})), can.onappend.board(can, msg)
},
})

View File

@ -1,25 +1,8 @@
fieldset.plugin div.output div.item div.item { div.output.json { font-family:var(--code-font-family); font-size:var(--code-font-size); white-space:pre; }
border:solid 1px #0000000d; div.output.json div.item { cursor:text; }
border-left:dashed 1px lightblue; div.output.json div.item:hover { background-color:transparent; color:unset; }
margin-left:5px; padding-left:15px; div.output.json div.item div.item { border:transparent solid 1px; border-left:var(--disable-fg-color) dashed 1px; padding-left:15px; margin-left:5px; }
font-size:14px; font-family:monospace; div.output.json div.item div.item:hover { border:var(--box-border); }
cursor:pointer; div.output.json div.item span.key { cursor:pointer; }
} div.output.json div.item span.string { color:var(--code-string); }
fieldset.plugin div.output div.item div.item:hover { div.output.json div.item label.nonce { color:var(--disable-fg-color); user-select:none; }
border:solid 1px red;
}
fieldset.plugin div.output div.item span.nonce {
font-size:12px; font-family:auto;
color:lightblue;
cursor:pointer;
}
fieldset.plugin div.output div.item span.key {
color:yellow;
}
fieldset.plugin div.output div.item span.string {
color:magenta;
}
fieldset.plugin div.output div.item span.const {
color:cyan;
}

View File

@ -1,60 +1,43 @@
Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) { Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) { can.onmotion.clear(can, target), can.onappend.table(can, msg)
can.onmotion.clear(can), can.base.isFunc(cb) && cb(msg) can.onappend.style(can, nfs.JSON, can._output), can.onimport.show(can, can.base.Obj(msg.Result(), {}), target, msg)
can.onimport.show(can, can.base.Obj(msg.Result(), {}), target) },
}, show: function(can, data, target, msg) {
show: function(can, data, target) { if (data.append && !can.page.tagis(can._fields, "fieldset.float")) {
function show(data, target, index, total) { var list var msg = can.request(); msg.Copy(data), can.onappend.table(can, msg)
switch (typeof data) { msg._xhr = {responseText: msg.Result()}
case lang.OBJECT: can.onmotion.delay(can, function() { can.onappend._status(can, msg) })
if (data == null) { return
return can.page.Append(can, list, [{text: "null"}]).item }
return var hidden = data.detail && data.option
} function show(data, target, index, total) { var list
function wrap(begin, end, add, cb) { switch (typeof data) {
can.page.Append(can, target, [{text: begin}]) case code.OBJECT: if (data == null) { can.page.Append(can, target, [{text: "null"}]); break }
add && can.page.Append(can, target, [{text: ["...", html.SPAN, "nonce"]}]), cb() function wrap(begin, end, add, cb, inner) { can.page.Append(can, target, [{text: begin}])
can.page.Append(can, target, [{text: end}]) add && can.page.Append(can, target, inner||[{text: [can.page.unicode.inner, html.LABEL, ["nonce", html.HIDE]]}]), cb(), can.page.Append(can, target, [{text: end}])
} }
function toggle(list) { list && can.onmotion.toggle(can, list) } function format(data) { return can.page.trans(can, JSON.stringify(data)) }
function _item() { function toggle(list) { return list && can.onmotion.toggle(can, list) }
list = list || can.page.Append(can, target, [{view: html.LIST}]).list function _item() { return can.page.Append(can, list = list || can.page.Append(can, target, [html.LIST])._target, [html.ITEM])._target }
return can.page.Append(can, list, [{view: html.ITEM}]).item if (can.base.isArray(data)) { var inner = ""
} if (hidden && can.core.List(data, function(item) { if (can.base.isIn(typeof item, code.STRING, code.NUMBER, code.BOOLEAN)) { return item } }).length == data.length) {
inner = [], can.core.List(data, function(item, index) { inner.push({text: [format(item), "", [code.STRING, code.INNER]]}, index < data.length-1 && {text: [", ", "", [code.INNER]]}) })
if (can.base.isArray(data)) { // 数组 }
wrap("[", "]", data.length > 0, function() { can.core.List(data, function(value, index) { var item = _item() wrap("[", "]", data.length > 0, function() { can.core.List(data, function(value, index) { var item = _item()
show(value, item, index, data.length) show(value, item, index, data.length)
}) }) }) }, inner)
} else { // 对象 } else { var length = can.core.Item(data).length, count = 0
var length = can.core.Item(data).length, count = 0 wrap("{", "}", length > 0, function() { can.core.Item(data, function(key, value) { var item = _item()
wrap("{", "}", length > 0, function() { can.core.Item(data, function(key, value) { var item = _item() can.page.Append(can, item, [{text: [format(key), "", mdb.KEY], onclick: function(event) { var display = !toggle(sub)
can.page.Append(can, item, [{text: ['"'+key+'"', html.SPAN, "key"], onclick: function(event) { toggle(sub) }}, {text: ': '}]) sub && can.page.SelectChild(can, sub.parentNode, "span.inner", function(target) { can.onmotion.toggle(can, target, display) })
var sub = show(value, item, count++, length) sub && can.page.SelectChild(can, sub.parentNode, "label.nonce", function(target) { can.onmotion.toggle(can, target, display) })
}) }) }}, {text: ": "}]); key == ice.MSG_STATUS && (value = can.base.Obj(value[0])||value)
} var sub = show(value, item, count++, length); hidden && sub && can.onmotion.hidden(can, sub)
break key == ice.MSG_STATUS && (can.page.SelectChild(can, item, "label.nonce", function(target) { can.onmotion.toggle(can, target, true) }))
case lang.STRING: /* 字串 */ can.page.Append(can, target, [{text: ['"'+data+'"', html.SPAN, lang.STRING]}]); break }) })
default: /* 其它 */ can.page.Append(can, target, [{text: [''+data+'', html.SPAN, "const"]}]) } break
} case code.STRING: can.page.Append(can, target, [{text: [format(data), "", code.STRING]}]); break
(index < total-1) && can.page.Append(can, target, [{text: ice.FS}]) default: can.page.Append(can, target, [{text: [format(data), "", code.CONSTANT]}])
return list } (index < total-1) && can.page.Append(can, target, [{text: mdb.FS}]); return list
}; show(data, can.page.Append(can, target, [{view: html.ITEM}]).item, 0, 0) }; show(data, can.page.Append(can, target, [html.ITEM])._target, 0, 0)
}, },
}, [""]) }, [""])
Volcanos("onaction", {help: "组件菜单", list: ["展开", "折叠", "复制"],
"展开": function(event, can) {
can.page.Select(can, can._output, "div.list div.list", function(list) {
can.onmotion.hidden(can, list, true)
})
},
"折叠": function(event, can) {
can.page.Select(can, can._output, "div.list div.list", function(list) {
can.onmotion.hidden(can, list)
})
},
"复制": function(event, can) {
can.user.copy(event, can, can._msg.Result())
},
})
Volcanos("onexport", {help: "导出数据", list: []})

6
plugin/story/monaco.css Normal file
View File

@ -0,0 +1,6 @@
fieldset.monaco .monaco-editor,
fieldset.monaco .monaco-editor .margin,
fieldset.monaco .monaco-editor-background,
fieldset.monaco .monaco-diff-editor {
background-color:var(--output-bg-color);
}

31
plugin/story/monaco.js Normal file
View File

@ -0,0 +1,31 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg, cb) {
can.require(["/require/modules/monaco-editor/min/vs/loader.js"], function() {
require.config({paths: {vs: "/require/modules/monaco-editor/min/vs"}})
require(["vs/editor/editor.main"], function () {
can.require(["/plugin/local/code/vimer.js"], function(can) { can.onimport._last_init(can, msg, function(msg) {
can.onappend.style(can, "monaco"), cb && cb(msg)
}) })
})
})
},
_theme: function(can) { if (can.base.isIn(can.getHeaderTheme(), html.LIGHT, html.WHITE)) { monaco.editor.setTheme("vs") } else { monaco.editor.setTheme("vs-dark") } },
layout: function(can) { can.page.style(can, can.ui.content, html.HEIGHT, can.ConfHeight(), html.WIDTH, can.ConfWidth()), can.ui.editor && can.ui.editor.layout() },
content: function(can, text) { return can.ui.editor.setValue(text) },
}, [""])
Volcanos(chat.ONSYNTAX, {
_split: function(can, msg, target) { can.onimport._theme(can), can.onengine.listen(can, chat.ONTHEMECHANGE, function() { can.onimport._theme(can) })
can.ui.editor = monaco.editor.create(target, {value: msg.Result(), language: "javascript", automaticLayout: true, resize: true})
can.ui.editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, function () { can.onaction.save({}, can, nfs.SAVE) })
},
})
Volcanos(chat.ONEXPORT, {
content: function(can) { return can.ui.editor.getValue() },
})
Volcanos(chat.ONPLUGIN, {
monaco: shy("编辑器", {
save: shy(function(can, msg) { can.user.toast(can, msg.Option(nfs.CONTENT)) }),
}, [nfs.PATH, nfs.FILE, nfs.LINE, ice.LIST, nfs.SAVE], function(can, msg, meta) {
msg.Display(meta._path)
}),
})

View File

@ -1,44 +1,86 @@
Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) { Volcanos(chat.ONIMPORT, {
can.require(["/plugin/local/wiki/draw.js", "/plugin/local/wiki/draw/path.js"], function() { _init: function(can, msg, cb) { can.ui = can.onappend.layout(can)
can.onmotion.clear(can), can.base.isFunc(cb) && cb(msg) can.page.requireDraw(can, function() { can.db.delay = 50, can.onappend.style(can, "pie"), can.onaction.list = []
can.onmotion.clear(can), can.onimport._show(can, msg) can.list = can.onimport._data(can, msg, can.Conf(mdb.FIELD)||msg.append[1]||mdb.VALUE)
var r = 200, margin = 20; can.svg.Val(html.WIDTH, 2*(r+margin)), can.svg.Val(html.HEIGHT, 2*(r+margin)) can.core.List(can.list, function(item) { msg.Push("weight", item.value.weight = parseInt(item.span*100/360)+"%").Push(cli.COLOR, '<span style="background-color:'+item.color+'"> </span>') })
can._args = can.base.Copy({field: "value"}, can.base.ParseURL(can._display)) can.onappend.table(can, msg, null, can.ui.profile), can.page.Select(can, can.ui.profile, html.TR, function(tr, index) { can.ui.table = tr.parentNode
can.onimport._draw(can, msg, can._args.field, r+margin, r+margin, r, margin, 0) can.page.Modify(can, tr, {onmouseenter: function(event) { can._draw(can.db.which = index-1) }})
can.onmotion.clear(can, can.ui.project), can.onappend.table(can, msg, null, can.ui.project) }), can.base.isFunc(cb) && cb(msg), can.onappend._status(can, msg.append)
can.onmotion.hidden(can, can.ui.project, true) })
can.page.Modify(can, can.ui.project, {style: {"max-width": 480}}) },
can.page.Select(can, can.ui.project, html.TR, function(tr, index) { _data: function(can, msg, field) { var list = []
can.page.Modify(can, tr, {onmouseenter: function(event) { var color = [
can.onmotion.clear(can, can.svg), can.onimport._draw(can, msg, can._args.field, r+margin, r+margin, r, margin, index-1) "#8085e9",
}}) "#95a2ff",
}) "#73abf5",
}) "#3cb9fc",
}, "#0082fc",
_draw: function(can, msg, field, x, y, r, margin, which) { "#87e885",
function pos(x, y, r, angle) { angle -= 90 "#90ed7d",
return [x + r * Math.cos(angle * Math.PI / 180), y + r * Math.sin(angle * Math.PI / 180)] "#22ed7c",
} "#05f8d6",
function pie(x, y, r, begin, span, color, cb) { can.onimport.draw({}, can, {shape: "path", style: { "#cb9bff",
"stroke-width": 1, stroke: color, fill: color, d: can.base.joins([ "#bf19ff",
["M", x, y], ["L"].concat(pos(x, y, r, begin)), ["A", r, r, "0", span>180? "1": "0", "1"].concat(pos(x, y, r, begin+span)), ["Z"] "#f47a75",
], ice.SP, ice.FS), "#fa8080",
}, onmouseenter: function(event) { "#f7a35c",
can.base.isFunc(cb) && cb(event) "#ffc076",
} }) } "#f9e264",
"#fae768",
"#5f45ff",
"#02cdff",
"#0090ff",
"#854cff",
"#09b0d3",
"#1d27c9",
"#765005",
"#314976",
"#009db2",
"#024b51",
"#0780cf",
]
var total = 0; msg.Table(function(value) { total += can.onimport._parseInt(can, value[field]) })
var begin = 0; msg[cli.COLOR] = [], msg["weight"] = [], msg.Table(function(value, index) {
list.push({span: can.onimport._parseInt(can, value[field])/total*360, color: color[index%color.length], value: value})
}); return list
},
_draw: function(can, x, y, r, margin, which) { if (which == can._last) { return } can._last = which
if (can.list.length == 1) { return can.onimport.draw(can, {shape: svg.CIRCLE, points: [{x: x, y: y}, {x: x, y: y+r}], style: {fill: cli.BLUE}}) }
function pos(x, y, r, angle) { angle -= 90; return [x + r * Math.cos(angle * Math.PI / 180), y + r * Math.sin(angle * Math.PI / 180)] }
function pie(x, y, r, begin, span, color, title, cb) { can.onimport.draw(can, {shape: svg.PATH, style: kit.Dict(
svg.STROKE, color, svg.FILL, color, "d", can.base.joins([
["M", x, y], ["L"].concat(pos(x, y, r, begin)), ["A", r, r, "0", span>180? "1": "0", "1"].concat(pos(x, y, r, begin+span)), ["Z"]
], lex.SP, mdb.FS),
), onmouseenter: function(event) { can.base.isFunc(cb) && cb(event) } }) }
can.onmotion.clear(can, can.ui.svg), can.ui.svg.Value(mdb.COUNT, 0)
var begin = 0; can.core.Next(can.list, function(item, next, index) { var p = index==which? pos(x, y, 1*margin, begin+item.span/2): [x, y]
pie(p[0], p[1], r, begin, item.span, item.color, item.name||item.command, function(event) { can.onimport._draw(can, x, y, r, margin, can.db.which = index) }), begin += item.span
index == which && (can.db.current = item.value)
can.onmotion.select(can, can.ui.table, html.TR, index), can.Status(item.value), can.onmotion.delay(can, next, can.db.delay)
}, function() {
can.onmotion.select(can, can.ui.table, html.TR, which), can.Status(can.db.current), can.db.delay = 0
})
},
_parseInt: function(can, value) { value = value.toLowerCase()
if (can.base.endWith(value, "m")) { return parseInt(value)*1000000 }
if (can.base.endWith(value, "g")) { return parseInt(value)*1000000000 }
if (can.base.endWith(value, "gi")) { return parseInt(value)*1000000000 }
if (can.base.endWith(value, "mi")) { return parseInt(value)*1000000 }
return parseInt(value)
},
layout: function(can) { if (!can.ui || !can.ui.svg) { return }
can.onmotion.hidden(can, can.ui.project), can.onmotion.hidden(can, can.ui.display), can.onmotion.toggle(can, can.ui.profile, true)
var _width = can.base.Max(can.ConfWidth()-can.ConfHeight(), 600, 200)
can.page.style(can, can.ui.profile, html.HEIGHT, can.ConfHeight(), html.WIDTH, _width, html.FLEX, "0 0 "+(_width)+"px")
var width = can.ConfWidth()-_width, height = can.ConfHeight()-4, margin = 40, r = can.base.Max(height, width)/2-1*margin-margin
can.page.style(can, can.ui.content, html.HEIGHT, can.ConfHeight(), html.WIDTH, width)
can.ui.svg.Val(html.WIDTH, width), can.ui.svg.Val(html.HEIGHT, height)
can._draw = function(which) { can.onimport._draw(can, width/2-margin/2, height/2-margin/2, r, margin, which) }, can._draw(can.db.which||0)
return
var total = 0; msg.Table(function(value) { total += parseInt(value[field]) }) var height = can.base.Max(can.ConfHeight(), can.ConfWidth()/2), margin = 10, r = height/2-1*margin-margin
var color = [cli.RED, cli.YELLOW, cli.GREEN, cli.CYAN, cli.BLUE, cli.PURPLE, cli.WHITE, cli.BLACK] can.page.style(can, can.ui.display, html.WIDTH, can.ConfWidth()-height-1), can.ui.svg.Val(html.HEIGHT, height), can.ui.svg.Val(html.WIDTH, height)
var begin = 0; msg["color"] = [], msg["weight"] = [], msg.Table(function(value, index) { var span = parseInt(value[field])/total*360 can._draw = function(which) { can.onimport._draw(can, height/2-margin/2, can.ConfHeight()/2-margin/2, r, margin, which) }, can._draw(can.db.which||0)
var p = index==which? pos(x, y, margin, begin+span/2): [x, y]; index == which && can.Status(value) can.page.style(can, can._output, html.HEIGHT, can.ConfHeight(), html.WIDTH, can.ConfWidth())
var c = color[index%color.length]; pie(p[0], p[1], r, begin, span, c, function(event) { },
if (index == can._last) { return } can._last = index
can.onmotion.clear(can, can.svg), can.svg.Value("count", 0)
can.onimport._draw(can, msg, field, x, y, r, margin, index)
can.onimport._profile(can, event.target)
}), begin += span, msg.Push("color", '<span style="background-color:'+c+'"> </span>')
msg.Push("weight", parseInt(parseInt(value[field])*10000/total)/100+"%")
})
},
}) })

3
plugin/story/qrcode.js Normal file
View File

@ -0,0 +1,3 @@
Volcanos(chat.ONIMPORT, {_init: function(can, msg) {
msg.Dump(can)
}})

View File

@ -1,9 +0,0 @@
fieldset.draw.spide div.output {
font-family:monospace;
}
fieldset.draw.spide div.output div.toggle {
display:none;
}
fieldset.inner.float div.output {
background-color:#332f1ecf;
}

View File

@ -1,204 +0,0 @@
Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) {
can.misc.Log("what------", can.Conf())
can.onmotion.clear(can), can.base.isFunc(cb) && cb(msg)
if (msg.Length() == 0) { return }
can._args = can.base.Copy({root: "ice", field: msg.append[0], split: ice.PS}, can.base.ParseURL(can._display))
can.dir_root = msg.Option(nfs.DIR_ROOT)||can._args.root||""
can._tree = can.onimport._tree(can, msg.Table(), can._args.field, can._args.split)
if (!can._tree[""]) { return }
can._tree[""].name = can._args.root
can.size = 30, can.margin = 30
can.require(["/plugin/local/wiki/draw.js", "/plugin/local/wiki/draw/path.js"], function() {
can.page.ClassList.add(can, can._fields, "draw")
can.onimport._show(can, msg), can.onmotion.hidden(can, can.ui.project)
var p = can.Action(ice.VIEW, can.sup.view||can.Action(ice.VIEW))
can.onaction[p](event, can, p)
})
},
_tree: function(can, list, field, split) {
var node = {}; can.core.List(list, function(item) { if (!item[field]) { return }
can.core.List(can.base.trimPrefix(item[field], can.dir_root+can._args.split).split(split), function(value, index, array) {
var last = array.slice(0, index).join(split)||"", name = array.slice(0, index+1).join(split)
if (!value || node[name]) { return }
node[last] = node[last]||{name: last, meta: {}, list: []}
node[last].list.push(node[name] = {
name: value+(index==array.length-1? "": split),
meta: item, list: [], last: node[last],
file: item[field]||item.file, hide: true,
})
})
})
return node
},
_height: function(can, tree, deep) { if (!tree) { return 0 }
tree.deep = deep||0
if (tree.list.length == 0 || tree.hide) { return tree.height = 1 }
var height = 0; can.core.List(tree.list, function(item) {
height += can.onimport._height(can, item, (deep||0)+1)
})
return tree.height = height
},
_width: function(can, tree, deep) { if (!tree) { return 0 }
tree.deep = deep||0
if (tree.list.length == 0 || tree.hide) {
tree.view = can.onimport.draw({}, can, {shape: html.TEXT, point: [{x: 0, y: 0}], style: {inner: tree.name}})
return tree.width = tree.view.Val("textLength")+can.margin
}
var width = 0; can.core.List(tree.list, function(item) {
width += can.onimport._width(can, item, (deep||0)+1)
})
return tree.width = width
},
_color: function(can, tree) {
return tree.meta&&tree.meta.color || (tree.list == 0? cli.PURPLE: cli.YELLOW)
},
}, [""])
Volcanos("onaction", {help: "用户操作", list: ["编辑", [ice.VIEW, "横向", "纵向"], "生成图片"],
"编辑": function(event, can) {
can.onmotion.toggle(can, can._action)
can.onmotion.toggle(can, can._status)
},
"横向": function(event, can) {
can.onimport._height(can, can._tree[""])
can.sup.view = "横向", can.onmotion.clear(can, can.svg)
can.svg.Val(html.HEIGHT, can._tree[""].height*can.size+2*can.margin)
can.width = 0, can.onaction._draw_horizontal(can, can._tree[""], can.margin, can.margin)
can.svg.Val(html.WIDTH, can.width+can.margin)
},
"纵向": function(event, can) {
can.onimport._width(can, can._tree[""])
can.sup.view = "纵向", can.onmotion.clear(can, can.svg)
can.svg.Val(html.WIDTH, can._tree[""].width+2*can.margin)
can.height = 0, can.onaction._draw_vertical(can, can._tree[""], can.margin, can.margin+can.size)
can.svg.Val(html.HEIGHT, can.height+can.margin)
},
"生成图片": function(event, can) {
can.user.toPNG(can, "hi.png", can.svg.outerHTML, can.svg.Val(html.HEIGHT), can.svg.Val(html.WIDTH))
},
_draw: function(can, tree, x, y, style) {
var color = can.onimport._color(can, tree)
tree.view = can.onimport.draw({}, can, {
shape: html.TEXT, point: [{x: x, y: y}], style: can.base.Copy({
stroke: color, fill: color, "text-anchor": "start", inner: tree.name||tree.file,
}, style),
}), can.core.ItemCB(can.ondetail, tree.view, can, tree)
},
_draw_vertical: function(can, tree, x, y) { tree.x = x, tree.y = y
can.onaction._draw(can, tree, x+tree.width/2, y, {"text-anchor": "middle"})
tree.height = can.size
if (y+tree.height > can.height) { can.height = y+tree.height }
if (tree.hide) { return }
var offset = 0; can.core.List(tree.list, function(item) {
can.onimport.draw({}, can, {shape: "path2v", point: [
{x: x+tree.width/2, y: y+tree.height-can.margin/2},
{x: x+offset+item.width/2, y: y+tree.height+can.margin/2},
], style: {stroke: cli.CYAN}})
can.onaction._draw_vertical(can, item, x+offset, y+tree.height+can.margin)
offset += item.width
})
},
_draw_horizontal: function(can, tree, x, y) { tree.x = x, tree.y = y
can.onaction._draw(can, tree, x, y+tree.height*can.size/2, {"text-anchor": "start"})
tree.width = tree.view.Val("textLength")
if (x+tree.width > can.width) { can.width = x+tree.width }
if (tree.hide) { return }
var offset = 0; can.core.List(tree.list, function(item) {
can.onimport.draw({}, can, {shape: "path2h", point: [
{x: x+tree.width+can.margin/8, y: y+tree.height*can.size/2},
{x: x+tree.width+can.margin*2-2*can.margin/8, y: y+offset+item.height*can.size/2}
], style: {stroke: cli.CYAN}})
can.onaction._draw_horizontal(can, item, x+tree.width+2*can.margin, y+offset)
offset += item.height*can.size
})
},
})
Volcanos("ondetail", {help: "用户交互", list: [],
onmouseenter: function(event, can, tree) { var y = tree.y+tree.height*can.size/2
can.page.Remove(can, can.pos), can.pos = can.onimport.draw({}, can, {
shape: svg.RECT, point: [
{x: tree.x-can.margin/4, y: y-can.size/2},
{x: tree.x+tree.width+can.margin/8, y: y+can.size/2},
], style: {stroke: cli.RED, fill: html.NONE},
}), event.stopPropagation(), event.preventDefault()
},
onclick: function(event, can, tree) {
if (tree.list.length > 0 || tree.tags || tree.name.endsWith(can._args.split)) {
return tree.hide = !tree.hide, can.onaction[can.Action(ice.VIEW)](event, can)
}
for (var node = tree; node; node = node.last) {
can.request(event, node.meta)
}
var msg = can.request(event, can.Option())
can.run(event, can.base.Obj(can._args.prefix, []).concat([can.Option(mdb.NAME)||"", tree.file||"", tree.name]), function(msg) {
if (msg.Length() == 0) {
return can.ondetail.plugin(can, tree, {}, "web.code.inner", [can.dir_root, tree.file, tree.line], [ctx.ACTION, "inner"])
}
if (msg.Append(mdb.INDEX)) { msg.Table(function(value) {
can.ondetail.plugin(can, tree, value, value.index, [], [ctx.ACTION, ice.RUN, value.index])
}); return }
tree.tags = true
if (msg.Option("split")) {
tree.list = can.onimport._tree(can, msg.Table(), msg.Option("field")||msg.append[0], msg.Option("split"))[""].list||[]
can.core.List(tree.list, function(item) { item.last = tree })
} else {
msg.Table(function(item) { tree.list.push({
type: "tags", name: item.name||item.file||item[msg.append[0]],
meta: item, list: [], last: tree,
file: item.file, line: item.line, hide: true,
}) })
}
tree.hide = !tree.hide, can.onaction[can.Action(ice.VIEW)](event, can)
}, true)
},
plugin: function(can, tree, value, index, args, prefix) {
for (var node = tree; node; node = node.last) {
can.base.Copy(value, node.meta)
}
can.onappend.plugin(can, can.base.Copy(value, {type: chat.FLOAT, index: index, args: args}), function(sub) {
sub.run = function(event, cmds, cb) { can.request(event, value, can.Option())
can.run(event, can.misc.concat(prefix, cmds), cb, true)
}, can.ondetail.figure(can, sub)
})
},
figure: function(can, sub, msg, cb) {
can.get("Action", "size", function(left, top, width, height) { left = left||0
if (height > window.innerHeight) { height = window.innerHeight }
var top = 120, margin = 20; if (can.user.isMobile) { margin = 0
if (can.user.isLandscape()) {
height += (can.user.mod.isCmd? -20: 200)
top = 24, sub.Conf(html.HEIGHT, height-top)
} else {
height += (can.user.mod.isCmd? -80: 200)
top = 48, sub.Conf(html.HEIGHT, height-top)
}
} else {
height += (can.user.mod.isCmd? 0: 300)
sub.Conf(html.HEIGHT, height-top)
}
var layout = {position: "fixed", left: left+margin, top: top}
can.onmotion.move(can, sub._target, layout)
can.page.Modify(can, sub._target, {style: layout})
can.page.Modify(can, sub._output, {style: {"max-width": width-margin*2}})
can.base.isFunc(cb) && cb(msg)
})
},
})

89
plugin/story/spides.js Normal file
View File

@ -0,0 +1,89 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg, cb) { can.page.requireDraw(can, function() { msg.append && can.ConfDefault({field: msg.append[0], split: nfs.PS})
can.db.count = msg.Length()
can.onmotion.toggle(can, can._action, true)
can.dir_root = can.Conf(nfs.DIR_ROOT)||msg.Option(nfs.DIR_ROOT), can._tree = can.onimport._tree(can, msg.Table(), can.Conf(mdb.FIELD), can.Conf(lex.SPLIT))
can.onaction.list = [], can.base.isFunc(cb) && cb(msg), can.onappend._status(can, msg.Option(ice.MSG_STATUS)), can.onimport.layout(can)
can.onappend.style(can, "spides")
}) },
_tree: function(can, list, field, split) { var node = {}; can.core.List(list, function(item) { can.core.List(item[field].split(split), function(value, index, array) {
var last = array.slice(0, index).join(split)||can.dir_root, name = array.slice(0, index+1).join(split)
value && !node[name] && (node[last] = node[last]||{name: last, meta: {}, list: []}).list.push(node[name] = {
name: value+(index==array.length-1? "": split), file: item.file||item[field]||item.file, hide: true, meta: item, list: [], last: node[last],
})
}) }); return node },
_height: function(can, tree) { tree.height = 0; if (tree.list.length == 0 || tree.hide) { return tree.height = 1 }
can.core.List(tree.list, function(item) { tree.height += can.onimport._height(can, item) }); return tree.height
},
_width: function(can, tree) { tree.width = 0; if (tree.list.length == 0 || tree.hide) {
return tree.width = can.onimport.draw(can, {shape: html.TEXT, points: [{x: 0, y: 0}], style: {inner: tree.name}}).Val(svg.TEXT_LENGTH)+can.margin
} can.core.List(tree.list, function(item) { tree.width += can.onimport._width(can, item) }); return tree.width },
_color: function(can, tree) {
return tree.meta.color || (tree.list == 0? cli.PURPLE: cli.YELLOW)
},
layout: function(can) {
can.ui.svg && can.ui.svg.Val(svg.FONT_SIZE, can.size = parseInt(can.Action(html.SIZE)||24)), can.margin = parseInt(can.Action(html.MARGIN)||10)
can._tree && can._tree[can.dir_root] && can.core.CallFunc(can.onaction[can.Action(html.VIEW)||"横向"], [event, can, can.Action(html.VIEW)])
},
})
Volcanos(chat.ONACTION, {list: [[html.VIEW, "横向", "纵向"], [html.SIZE, 24, 32, 48], [html.MARGIN, 10, 30, 50]],
size: function(event, can) { can.onimport.layout(can) }, margin: function(event, can) { can.onimport.layout(can) },
"横向": function(event, can, button) { can.onimport._height(can, can._tree[can.dir_root]), can.onmotion.clear(can, can.ui.svg)
can.ui.svg.Val(html.HEIGHT, can._tree[can.dir_root].height*(can.size+can.margin)+2*can.margin), can.ui.svg.Value(svg.TEXT_ANCHOR, "start")
can.onaction._draw_horizontal(can, can._tree[can.dir_root], can.margin, can.margin)
},
"纵向": function(event, can, button) { can.onimport._width(can, can._tree[can.dir_root]), can.onmotion.clear(can, can.ui.svg)
can.ui.svg.Val(html.WIDTH, can._tree[can.dir_root].width+2*can.margin), can.ui.svg.Value(svg.TEXT_ANCHOR, "middle")
can.onaction._draw_vertical(can, can._tree[can.dir_root], can.margin, can.margin+(can.size+can.margin)/2)
},
_draw: function(can, tree, x, y, style) { var color = can.onimport._color(can, tree)
tree.view = can.onimport.draw(can, {shape: html.TEXT, points: [{x: x, y: y-(can.user.isChrome? 4: 0)}], style: can.base.Copy(kit.Dict(html.INNER, tree.name||" "), style)})
tree.meta.status && tree.view.Value("class", tree.meta.status)
return can.core.ItemCB(can.ondetail, tree.view, can, tree), tree.view
},
_draw_vertical: function(can, tree, x, y) {
tree.height = can.size+can.margin, can.onaction._draw(can, tree, tree.x = x+tree.width/2, tree.y = y); if (y+tree.height > can.ui.svg.Val(html.HEIGHT)) { can.ui.svg.Val(html.HEIGHT, y+tree.height) }
var offset = 0; tree.hide || can.core.List(tree.list, function(item) {
can.onimport.draw(can, {shape: svg.PATH2V, points: [
{x: x+tree.width/2, y: y+tree.height/2-can.margin/2}, {x: x+offset+item.width/2, y: y+tree.height/2+8*can.margin-can.margin/2},
]}), can.onaction._draw_vertical(can, item, x+offset, y+tree.height+8*can.margin), offset += item.width
})
},
_draw_horizontal: function(can, tree, x, y) { var height = can.size+can.margin
tree.width = can.onaction._draw(can, tree, tree.x = x, tree.y = y+tree.height*(can.size+can.margin)/2).Val(svg.TEXT_LENGTH)||(tree.name.length*16); if (x+tree.width > can.ui.svg.Val(html.WIDTH)) { can.ui.svg.Val(html.WIDTH, x+tree.width) }
var offset = 0; tree.hide || can.core.List(tree.list, function(item) {
can.onimport.draw(can, {shape: svg.PATH2H, points: [
{x: x+tree.width+can.margin/2, y: y+tree.height*height/2-can.size/4}, {x: x+tree.width+8*can.margin-can.margin/2, y: y+offset+item.height*height/2-can.size/4}
]}), can.onaction._draw_horizontal(can, item, x+tree.width+8*can.margin, y+offset), offset += item.height*(can.size+can.margin)
})
},
})
Volcanos(chat.ONDETAIL, {
onclick: function(event, can, tree) {
if (tree.list.length > 0 || tree.name.endsWith(can.Conf(lex.SPLIT))) { return tree.hide = !tree.hide, can.onaction[can.Action(html.VIEW)||"横向"](event, can) }
for (var node = tree; node; node = node.last) { can.request(event, node.meta) }
can.run(can.request(event, can.Option()), can.base.Obj(can.Conf(lex.PREFIX), []).concat(can.Conf(ctx.ACTION)||[], [tree.file||"", tree.name]), function(msg) {
if (msg.Length() == 0) { return can.onappend._float(can, web.CODE_INNER, [can._msg.Option(nfs.DIR_ROOT), tree.file, tree.line]) }
if (msg.Append(mdb.INDEX)) {
return msg.Table(function(value) { value.style = html.FLOAT, can.onappend.plugin(can, value, function(sub) {}) })
}
can.Status(mdb.COUNT, can.db.count += msg.Length())
tree.list = can.onimport._tree(can, msg.Table(), can.Conf(mdb.FIELD), can.Conf(lex.SPLIT))[can.dir_root].list
tree.hide = false, can.onimport.layout(can)
}, true)
},
oncontextmenu: function(event, can, tree) {
can.user.carte(event, can, {}, [
wiki.PORTAL, chat.DESKTOP, chat.ADMIN, wiki.WORD, web.DREAM, web.STORE,
code.VIMER, code.STATUS, code.COMPILE, cli.RUNTIME, code.XTERM,
], function(event, button) {
if (button == web.ADMIN) {
can.onappend.plugin(can, {index: web.CHAT_IFRAME, args: [
can.misc.MergePodCmd(can, {pod: tree.file, cmd: web.ADMIN})
], title: tree.name+"."+web.ADMIN, style: html.FLOAT}, function(sub) {})
} else {
can.onappend.plugin(can, {space: tree.file, index: button, style: html.FLOAT}, function(sub) {})
}
})
},
})

23
plugin/story/stats.js Normal file
View File

@ -0,0 +1,23 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg) { can.onappend.style(can, [web.STATS, html.FLEX], can._output)
var FIELD = can.Conf(mdb.FIELD)||mdb.NAME, VALUE = can.Conf(mdb.VALUE)||mdb.VALUE
var list = {}, stats = {}, units = {}, trans = {}, index = {}; msg.Table(function(value) {
stats[value[FIELD]] = parseFloat(stats[value[FIELD]]||"0") + parseFloat(value[VALUE])
units[value[FIELD]] = value.units, trans[value[FIELD]] = value._trans
index[value[FIELD]] = value.index, list[value[FIELD]] = value
})
function fmts(value) { var ls = []
while (value > 0) { ls.push(value%1000)
if (ls.length == 1) { ls[0] = ls[0].toFixed(2) }
value = parseInt(value/1000)
} return ls.reverse().join(", ")
}
can.user.trans(can, trans, null, html.INPUT)
can.core.Item(stats, function(name, value) { can.page.Append(can, can._output, [{view: [[html.ITEM, name, html.FLEX]], list: [
{view: mdb.VALUE, list: [{text: can.base.trimSuffix(fmts(parseFloat(value).toFixed(2))+"", ".00")}, {text: [units[name], "", mall.UNITS]}]},
{view: [mdb.NAME, "", can.user.trans(can, name, trans[name]||null, html.INPUT)]},
], onclick: function() {
can.onappend.plugin(can, {space: list[name].space, index: index[name], style: html.FLOAT})
}}]) }), can.isCmdMode() && can.onappend.table(can, msg)
},
})

19
plugin/story/studio.js Normal file
View File

@ -0,0 +1,19 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg, cb) {
can.onmotion.hidden(can, can._status), cb && cb(msg), can.onimport._tabs(can, msg)
},
_tabs: function(can, msg) { can.onappend.style(can, web.STUDIO), can.onmotion.clear(can, can._action)
var margin = html.PLUGIN_MARGIN*2
msg.Table(function(value, index) { value.nick = can.user.trans(can, value.index.split(nfs.PT).pop(), value.help)
value._select = index == 0
var target = can.onimport.item(can, value, function() {
if (value._plugin) { return can.onmotion.select(can, can._output, html.FIELDSET, value._plugin._target) }
can.onappend.plugin(can, value, function(sub) { value._plugin = sub
can.onmotion.select(can, can._output, html.FIELDSET, value._plugin._target)
sub.onexport.output = function() { sub.onimport.size(sub, can.ConfHeight()-margin, can.ConfWidth()-margin, false) }
target.oncontextmenu = function(event) { sub._legend.onclick(event) }, can.onmotion.hidden(can, sub._legend)
}, can._output)
}, null, can._action); can.onappend.style(can, "cmds", target)
})
},
})

View File

@ -0,0 +1,9 @@
fieldset.studiolayout>div.output>div.layout>div.display>fieldset.story>form.option>div.item.delete { display:none; }
fieldset.studiolayout>div.output>div.layout>div.layout>div.content>fieldset.story>form.option>div.item.delete { display:none; }
fieldset.studiolayout>div.output>div.layout>div.layout>div.profile>fieldset.story>form.option>div.item.delete { display:none; }
fieldset.studiolayout>div.output>div.layout>div.layout>div.profile>fieldset.story>form.option>div.item.sess { display:none; }
fieldset.studiolayout>div.output>div.layout>div.layout>div.content>fieldset.story>form.option>div.item.sess { display:none; }
fieldset.studiolayout>div.output>div.layout>div.display>fieldset.story>form.option>div.item.sess { display:none; }
fieldset.studiolayout>div.output>div.layout>div.display>fieldset.story>div.action>div.item.full.state { display:none; }
fieldset.studiolayout>div.output>div.layout>div.layout>div.profile>fieldset.story>div.action>div.item.full.state { display:none; }
fieldset.studiolayout>div.output>div.layout>div.layout>div.content>fieldset.story>div.action>div.item.full.state { display:none; }

View File

@ -0,0 +1,19 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg) {
can.onimport.project(can, msg, aaa.SESS, function(event, sess, value) { return {
profile: {index: "web.code.redis.configs", args: sess, style: html.OUTPUT},
display: {index: "web.code.redis.shells", args: sess, style: html.OUTPUT},
content: {index: "web.code.redis.keys", args: sess},
} })
},
project: function(can, msg, key, cb) { can.ui = can.onappend.layout(can), can.onappend.style(can, "studiolayout")
msg.Table(function(value) { var hash = value[key]; value._hash = hash, value._title = hash
can.onimport.item(can, value, function(event, value, show, target) { if (value._tabs) { return value._tabs.click() }
var msg = can.request(event), list = cb(event, hash, value)
can.core.List("content,display,profile".split(","), function(field) {
list[field] && can.core.List("index,args,style,_init".split(","), function(key) { msg.Push(key, list[field][key]||"") })
}), can.onimport.tabsCache(can, value, target, msg)
})
})
},
}, [""])

View File

@ -1,4 +0,0 @@
fieldset.draw.trend div.output div.toggle {
display:none;
}

View File

@ -1,153 +0,0 @@
Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) {
can.onmotion.clear(can), can.base.isFunc(cb) && cb(msg)
if (msg.Option("branch")) { return can.onappend.table(can, msg) }
can.onappend._status(can, ["from", "commit", "total", "max", "date", "text", "add", "del"])
can.Conf(html.HEIGHT, can.Conf(html.HEIGHT)||200)
can.msg = msg, can.data = msg.Table(), can.onimport._sum(can)
can.Action(html.HEIGHT, msg.Option(html.HEIGHT)||can.user.mod.isCmd? "max": can.user.isMobile&&can.user.isLandscape()? "200": "400")
can.Action("speed", parseInt(msg.Option("speed")||"100"))
can.require(["/plugin/local/wiki/draw.js", "/plugin/local/wiki/draw/path.js"], function() {
can.page.ClassList.add(can, can._fields, "draw")
can.onimport._show(can, msg), can.onmotion.hidden(can, can.ui.project)
can.onaction[can.Action("view")](event, can)
})
},
_sum: function(can) {
var begin = "", count = 0, rest = 0, add = 0, del = 0, max = 0
can.max = 0, can.min = 0, can.list = can.core.List(can.data, function(value, index) {
var line = {
date: value[can.msg.append[0]],
text: value[can.msg.append[4]],
add: parseInt(value[can.msg.append[1]]),
del: parseInt(value[can.msg.append[2]]),
}
line.begin = rest
line.max = rest + line.add
line.min = rest - line.del
line.close = rest + line.add - line.del
begin = begin || value.date, count++
rest = line.close, add += line.add, del += line.del
if (line.max - line.min > max) { max = line.max - line.min }
if (line.max > can.max) { can.max = line.max }
if (line.min < can.min) { can.min = line.min }
return line
})
can.Status({"from": begin, "commit": count, "total": add+del, "max": max})
},
}, [""])
Volcanos("onaction", {help: "组件菜单", list: ["编辑", ["view", "趋势图", "柱状图", "数据源"], ["height", "100", "200", "400", "600", "800", "max"], ["speed", "10", "20", "50", "100"]],
"编辑": function(event, can) {
can.onmotion.toggle(can, can._action)
can.onmotion.toggle(can, can._status)
},
"趋势图": function(event, can) { var height = can.Action(html.HEIGHT)
if (height == "max") { height = can.Conf(html.HEIGHT) - chat.CMD_MARGIN }
height = parseInt(height)
var space = 10, width = parseInt(can.Conf(html.WIDTH))
var step = parseInt((width-2*space) / can.list.length)
can.onmotion.clear(can, can.svg)
can.svg.Val(html.HEIGHT, height)
can.svg.Val(html.WIDTH, width)
function scale(y) { return (y - can.min)/(can.max - can.min)*(height-2*space) }
function order(index, x, y) { return {x: space+step*index+x, y: height-space-scale(y)} }
can.core.Next(can.list, function(line, next, index) { can.Status(line, ["date", "text", "add", "del"])
can.onimport.draw({}, can, {
shape: "line", point: [
order(index, step/2, line.min), order(index, step/2, line.max),
], style: {
"stroke-width": 1, "stroke": line.begin < line.close? chat.WHITE: chat.BLACK,
},
})
can.onimport.draw({}, can, {
shape: "rect", point: [
order(index, step/4, line.close), order(index, step/4*3, line.begin),
], style: can.base.Copy({"stroke-width": 1, "rx": 0, "ry": 0}, line.begin < line.close? {
"stroke": chat.WHITE, "fill": chat.WHITE,
}: {
"stroke": chat.BLACK, "fill": chat.BLACK,
}),
_init: function(view) {
can.core.ItemCB(can.ondetail, function(key, cb) {
view[key] = function(event) { cb(event, can, line) }
})
},
})
can.core.Timer(parseInt(can.Action("speed")), next)
})
},
"柱状图": function(event, can) {
var max = {}, min = {}
can.core.List(can.msg.append, function(key, which) {
can.core.List(can.data, function(value, index) {
var v = parseInt(value[key])||0; if (index == 0) {
max[key] = v, min[key] = v
return
}
if (v > max[key]) { max[key] = v }
if (v < min[key]) { min[key] = v }
})
})
var height = parseInt(can.Action(html.HEIGHT))
var space = 10, width = parseInt(can.Conf(html.WIDTH))
var step = parseInt((width-2*space) / can.list.length)
can.onmotion.clear(can, can.svg)
can.svg.Val(html.HEIGHT, height)
can.svg.Val(html.WIDTH, width)
function scale(key, y) { return (y - min[key])/(max[key] - min[key])*(height-2*space) }
function order(index, key, x, y) { return {x: space+step*index+x, y: space+scale(key, y)} }
var width = (step-4)/can.msg.append.length
can.core.List(can.msg.append, function(key, which) {
max[key] != min[key] && can.core.Next(can.data, function(line, next, index) {
var y = scale(key, parseFloat(line[key]))
y && can.onimport.draw({}, can, {
shape: "rect", point: [
order(index, key, width*which+2, 0), order(index, key, width*which+2+width, y),
], style: {
"stroke-width": 1, "stroke": chat.WHITE, "fill": chat.WHITE, "rx": 0, "ry": 0,
},
_init: function(view) {
can.core.ItemCB(can.ondetail, function(key, cb) {
view[key] = function(event) { cb(event, can, line) }
})
},
})
can.core.Timer(parseInt(can.Action("speed")), next)
})
})
},
"数据源": function(event, can) {
can.onmotion.clear(can, can.ui.display)
can.onappend.table(can, can.msg, null, can.ui.display)
can.onmotion.show(can, can.ui.display)
},
height: function(event, can) {
can.onaction[can.Action("view")](event, can)
},
speed: function(event, can) {
can.onaction[can.Action("view")](event, can)
},
})
Volcanos("ondetail", {help: "用户交互", list: [],
onmouseenter: function(event, can, line) {
can.Status(line, ["date", "text", "add", "del"])
},
})
Volcanos("onexport", {help: "导出数据", list: []})

102
plugin/story/trends.js Normal file
View File

@ -0,0 +1,102 @@
Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb) {
can.page.requireDraw(can, function() { can.base.isFunc(cb) && cb(msg)
can.Conf(html.VIEW) && can.Action(html.VIEW, can.Conf(html.VIEW))
can.onmotion.toggle(can, can._option, !can.user.isMobile)
can.onmotion.toggle(can, can._action, can.page.tagis(document.body, "body.width6"))
can.db.data = msg.Table(), can.onimport.layout(can)
})
},
_sum: function(can) { if (can.db.list) { return can.db.list }
var begin = "", count = 0, rest = 0, add = 0, del = 0, max = 0
can.max = 0, can.min = 0, can.db.list = can.core.List(can.db.data, function(value, index) {
var item = {date: value[can._msg.append[0]], text: value[can._msg.append[4]], add: parseInt(value[can._msg.append[1]]), del: parseInt(value[can._msg.append[2]]), hash: value.hash}
item.begin = rest, item.max = rest + item.add, item.min = rest - item.del, item.close = rest + item.add - item.del
begin = begin || item.date, count++, rest = item.close, add += item.add, del += item.del
if (item.max - item.min > max) { max = item.max - item.min }
if (item.max > can.max) { can.max = item.max }
if (item.min < can.min) { can.min = item.min }
return item
}), can.Status({"from": begin, "commit": count, "total": add+del, "max": max})
return can.db.list
},
_layout: function(can) { var height = can.onexport.height(can), width = parseInt(can.ConfWidth())
can.onmotion.clear(can, can.ui.svg), can.ui.svg.Val(html.HEIGHT, height), can.ui.svg.Val(html.WIDTH, width)
var margin = can.onexport.margin(can), step = parseFloat((width-2*margin) / can._msg.Length())
can.page.style(can, can._output, html.MAX_HEIGHT, "")
return {height: height, width: width, margin: margin, step: step}
},
layout: function(can) { can.db.data && can.core.CallFunc(can.onaction[can.Action(html.VIEW)], [{}, can]) },
transform: function(can, target) { target.Value("transform", "translate(0, "+parseInt(can.ConfHeight())+") scale(1, -1)") },
})
Volcanos(chat.ONACTION, {list: [[html.VIEW, "趋势图", "柱状图", "折线图", "数据源"],
[html.HEIGHT, html.HEIGHT, 100, 200, 400, 600, 800, "max"], [html.MARGIN, html.MARGIN, 10, 20, 50, 100], [html.SPEED, html.SPEED, 10, 20, 50, 100],
],
"趋势图": function(event, can) { var args = can.onimport._layout(can)
function scale(y) { return (y - can.min)/(can.max - can.min)*(args.height-2*args.margin) }
function order(index, x, y) { return {x: args.margin+args.step*index+x, y: args.height-args.margin-scale(y)} }
var black = can.onimport.group(can, cli.BLACK, kit.Dict(svg.STROKE, cli.BLACK, svg.FILL, cli.BLACK))
var white = can.onimport.group(can, cli.WHITE, kit.Dict(svg.STROKE, cli.WHITE, svg.FILL, cli.WHITE))
can.core.Next(can.onimport._sum(can), function(item, next, index) { can.core.Timer(can.onexport.speed(can), next), can.Status(item)
can.onimport.draw(can, {shape: svg.LINE, points: [order(index, args.step/2, item.min), order(index, args.step/2, item.max)]}, item.begin < item.close? white: black)
can.onimport.draw(can, {shape: svg.RECT, points: [order(index, args.step/4, item.close), order(index, args.step/4*3, item.begin)], style: {rx: 0, ry:0}, _init: function(target) {
can.core.ItemCB(can.ondetail, function(key, cb) { target[key] = function(event) { can.misc.Event(event, can, function(msg) { cb(event, can, item) }) } })
}}, item.begin < item.close? white: black)
})
},
"折线图": function(event, can) { var args = can.onimport._layout(can); args.step = parseFloat((args.width-2*args.margin) / (can._msg.Length()-1))
var black = can.onimport.group(can, cli.BLACK, kit.Dict(svg.STROKE, cli.BLACK, svg.FILL, cli.BLACK))
var white = can.onimport.group(can, cli.WHITE, kit.Dict(svg.STROKE, cli.WHITE, svg.FILL, cli.WHITE))
var group = can.getHeaderTheme() == cli.BLACK? white: black;
var color = can.core.List(can.base.Obj(can.Conf(cli.COLOR), []), function(color) { return can.onimport.group(can, color, kit.Dict(svg.STROKE, color, svg.FILL, color)) })
can.onimport.transform(can, black), can.onimport.transform(can, white), can.core.List(color, function(color) { can.onimport.transform(can, color) })
var max, min; can.core.List(can.core.List(can.base.Obj(can.Conf(mdb.FIELD), can._msg.append), function(field) {
if (can.base.isIn(field, mdb.TIME, mdb.ID)) { return } return field
}), function(field, index) { max = can.db.data[0][field], min = can.db.data[0][field]
for (var i = 1; i < can.db.data.length; i += 1) { var value = can.db.data[i][field]; if (value > max) { max = value } if (value < min) { min = value } }
max = parseFloat(can.Conf("max")||max), min = parseFloat(can.Conf("min")||min)
function order(i) { return i*args.step+args.margin } function scale(y) { return (y - min)/(max - min)*(args.height-2*args.margin)+args.margin }
for (var i = 1; i < can.db.data.length; i += 1) { can.onimport.draw(can, {shape: svg.LINE, points: [{x: order(i-1), y: scale(can.db.data[i-1][field])}, {x: order(i), y: scale(can.db.data[i][field])}]}, color[index]||group) }
}), can.onappend._status(can, can._msg.Option(ice.MSG_STATUS))
var gray = can.onimport.group(can, cli.WHITE, kit.Dict(svg.STROKE, cli.GRAY, svg.FILL, cli.GRAY)); can.onimport.transform(can, gray)
var vline = can.onimport.draw(can, {shape: svg.LINE, points: [{x: 0, y: 0}, {x: 0, y: can.ConfHeight()}]}, gray)
var hline = can.onimport.draw(can, {shape: svg.LINE, points: [{x: 0, y: 0}, {x: can.ConfWidth(), y: 0}]}, gray)
can.ui.svg.onmousemove = function(event) { var p = can._output.getBoundingClientRect(); p = {x: event.clientX - p.x, y: event.clientY - p.y}
vline.Val("x1", p.x), vline.Val("x2", p.x), hline.Val("y1", can.ConfHeight()-p.y), hline.Val("y2", can.ConfHeight()-p.y)
var item = can.db.data[parseInt((p.x - args.margin)/args.step)]
item && can.Status(item), can.Status("cursor", parseInt((can.ConfHeight()-p.y-args.margin)/(can.ConfHeight()-2*args.margin)*max))
}
},
"柱状图": function(event, can) { var args = can.onimport._layout(can)
var black = can.onimport.group(can, cli.BLACK, kit.Dict(svg.STROKE, cli.BLACK, svg.FILL, cli.BLACK))
var white = can.onimport.group(can, cli.WHITE, kit.Dict(svg.STROKE, cli.WHITE, svg.FILL, cli.WHITE))
var group = can.getHeaderTheme() == cli.BLACK? black: white
can.onimport.transform(can, black), can.onimport.transform(can, white)
can.core.List(can.base.Obj(can.Conf(mdb.FIELD), can._msg.append), function(field) { var max = can.db.data[0][field], min = can.db.data[0][field]
for (var i = 1; i < can.db.data.length; i += 1) { var value = can.db.data[i][field]; if (value > max) { max = value } if (value < min) { min = value } }
function order(i) { return i*args.step+args.margin } function scale(y) { return (y - min)/(max - min)*(args.height-2*args.margin)+args.margin }
can.core.Next(can.db.data, function(item, next, i) { can.core.Timer(can.onexport.speed(can), next)
can.onimport.draw(can, {shape: svg.RECT, style: {rx: 0, ry: 0}, points: [{x: order(i)+args.step/8.0, y: args.margin}, {x: order(i)+args.step/8.0*7, y: scale(item[field])}], _init: function(target) {
can.core.ItemCB(can.ondetail, function(key, cb) { target[key] = function(event) { can.misc.Event(event, can, function(msg) { cb(event, can, item) }) } })
}}, group)
})
})
},
"数据源": function(event, can) { can.onmotion.clear(can), can.onappend.table(can, can._msg) },
height: function(event, can) { can.onimport.layout(can) },
margin: function(event, can) { can.onimport.layout(can) },
speed: function(event, can) { can.onimport.layout(can) },
})
Volcanos(chat.ONDETAIL, {
onmouseenter: function(event, can, item) { can.Status(item) },
onclick: function(event, can, item) { can.run(can.request(event, item, can.Option()), [mdb.DETAIL], function(msg) {
msg.Append(ctx.STYLE, html.FLOAT), can.sup.onimport._field(can.sup, msg)
}) },
})
Volcanos(chat.ONEXPORT, {list: ["from", "commit", "total", "max", "date", "text", "add", "del"],
height: function(can) {
var height = can.onexport.action_value(can, html.HEIGHT, can.ConfHeight())
return can.base.Min(height, 200, can.ConfHeight())
},
margin: function(can) { return parseInt(can.onexport.action_value(can, html.MARGIN, 10)) },
speed: function(can) { return parseInt(can.onexport.action_value(can, html.SPEED, 10)) },
})

View File

@ -1,48 +0,0 @@
Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) {
can.onimport.select(can, msg)
can.onmotion.clear(can), can.base.isFunc(cb) && cb(msg)
can.onappend.table(can, msg), can.onappend.board(can, msg)
can.core.Timer(12000, function() { can.onaction.play(event, can) })
can.page.Select(can, can._output, "td a", function(a) {
can.page.Modify(can, a, {target: ""})
})
},
select: function(can, msg) {
msg.Clear(), can.page.Select(can, document.body, can.Option("tags"), function(a, index) {
msg.Push(mdb.INDEX, index)
msg.Push(mdb.NAME, a.innerText)
msg.Push(mdb.LINK, a.href)
a.href == location.href && can.core.Timer(100, function() {
can.page.Select(can, can._output, html.TR, function(tr, i) {
i-1 == index && can.page.ClassList.add(can, tr, "select")
})
})
})
msg.Option(ice.MSG_STATUS, JSON.stringify([
{name: "time", value: can.base.Time(null, "%y-%m-%d %H:%M:%S")},
{name: "count", value: msg.Length()},
]))
},
})
Volcanos("onaction", {help: "控件交互", list: [],
next: function(event, can) { var msg = can._msg
msg.Table(function(line, index) {
if (line.link == location.href) {
location.href = msg.link[index+1]
}
})
},
play: function(event, can) {
can.page.SelectAll(can, document.body, html.VIDEO, function(video) {
video.playbackRate = parseFloat(can.Option("rate"))
video.currentTime = parseInt(can.Option("skip"))
video.ontimeupdate = function(event) {
if (video.currentTime > parseInt(can.Option("next"))) {
can.onaction.next(event, can)
}
}, video.play(), video.requestFullscreen()
})
},
})
Volcanos("onexport", {help: "导出数据", list: []})

81
plugin/story/weight.js Normal file
View File

@ -0,0 +1,81 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg, cb) { can.ui = can.onappend.layout(can)
can.page.requireDraw(can, function() { can.db.delay = 50, can.onappend.style(can, "pie"), can.onaction.list = []
can.list = can.onimport._data(can, msg, can.Conf(mdb.FIELD)||msg.append[1]||mdb.VALUE)
can.core.List(can.list, function(item) { msg.Push("weight", item.value.weight = parseInt(item.span*100/360)+"%").Push(cli.COLOR, '<span style="background-color:'+item.color+'"> </span>') })
can.onappend.table(can, msg, null, can.ui.profile), can.page.Select(can, can.ui.profile, html.TR, function(tr, index) { can.ui.table = tr.parentNode
can.page.Modify(can, tr, {onmouseenter: function(event) { can._draw(can.db.which = index-1) }})
}), can.base.isFunc(cb) && cb(msg), can.onappend._status(can, msg.append)
})
},
_data: function(can, msg, field) { var list = []
var color = [
"#8085e9",
"#95a2ff",
"#73abf5",
"#3cb9fc",
"#0082fc",
"#87e885",
"#90ed7d",
"#22ed7c",
"#05f8d6",
"#cb9bff",
"#bf19ff",
"#f47a75",
"#fa8080",
"#f7a35c",
"#ffc076",
"#f9e264",
"#fae768",
"#5f45ff",
"#02cdff",
"#0090ff",
"#854cff",
"#09b0d3",
"#1d27c9",
"#765005",
"#314976",
"#009db2",
"#024b51",
"#0780cf",
]
var total = 0; msg.Table(function(value) { total += can.onimport._parseInt(can, value[field]) })
var begin = 0; msg[cli.COLOR] = [], msg["weight"] = [], msg.Table(function(value, index) {
list.push({span: can.onimport._parseInt(can, value[field])/total*360, color: color[index%color.length], value: value})
}); return list
},
_draw: function(can, x, y, r, margin, which) { if (which == can._last) { return } can._last = which
if (can.list.length == 1) { return can.onimport.draw(can, {shape: svg.CIRCLE, points: [{x: x, y: y}, {x: x, y: y+r}], style: {fill: cli.BLUE}}) }
function pos(x, y, r, angle) { angle -= 90; return [x + r * Math.cos(angle * Math.PI / 180), y + r * Math.sin(angle * Math.PI / 180)] }
function pie(x, y, r, begin, span, color, title, cb) { can.onimport.draw(can, {shape: svg.PATH, style: kit.Dict(
svg.STROKE, color, svg.FILL, color, "d", can.base.joins([
["M", x, y], ["L"].concat(pos(x, y, r, begin)), ["A", r, r, "0", span>180? "1": "0", "1"].concat(pos(x, y, r, begin+span)), ["Z"]
], lex.SP, mdb.FS),
), onmouseenter: function(event) { can.base.isFunc(cb) && cb(event) } }) }
can.onmotion.clear(can, can.ui.svg), can.ui.svg.Value(mdb.COUNT, 0)
var begin = 0; can.core.Next(can.list, function(item, next, index) { var p = index==which? pos(x, y, 1*margin, begin+item.span/2): [x, y]
if (item.value.name == "rest") { return can.onmotion.delay(can, next, can.db.delay) }
pie(p[0], p[1], r, begin, item.span, item.color, item.name||item.command, function(event) { can.onimport._draw(can, x, y, r, margin, can.db.which = index) }), begin += item.span
index == which && (can.db.current = item.value)
can.onmotion.select(can, can.ui.table, html.TR, index), can.Status(item.value), can.onmotion.delay(can, next, can.db.delay)
}, function() {
can.onmotion.select(can, can.ui.table, html.TR, which), can.Status(can.db.current), can.db.delay = 0
})
},
_parseInt: function(can, value) { value = value.toLowerCase()
if (can.base.endWith(value, "m")) { return parseInt(value)*1000000 }
if (can.base.endWith(value, "g")) { return parseInt(value)*1000000000 }
if (can.base.endWith(value, "gi")) { return parseInt(value)*1000000000 }
if (can.base.endWith(value, "mi")) { return parseInt(value)*1000000 }
return parseInt(value)
},
layout: function(can) { if (!can.ui || !can.ui.svg) { return }
can.onmotion.hidden(can, can.ui.project), can.onmotion.hidden(can, can.ui.display), can.onmotion.toggle(can, can.ui.profile, true)
var _width = can.base.Max(can.ConfWidth()-can.ConfHeight(), 600, 200)
can.page.style(can, can.ui.profile, html.HEIGHT, can.ConfHeight(), html.WIDTH, _width, html.FLEX, "0 0 "+(_width)+"px")
var width = can.ConfWidth()-_width, height = can.ConfHeight()-4, margin = 40, r = can.base.Max(height, width)/2-1*margin-margin
can.page.style(can, can.ui.content, html.HEIGHT, can.ConfHeight(), html.WIDTH, width)
can.ui.svg.Val(html.WIDTH, width), can.ui.svg.Val(html.HEIGHT, height)
can._draw = function(which) { can.onimport._draw(can, width/2-margin/2, height/2-margin/2, r, margin, which) }, can._draw(can.db.which||-1)
},
})

View File

@ -1,16 +1,602 @@
Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) { Volcanos(chat.ONIMPORT, {
can.onmotion.clear(can) _init: function(can, msg, target, cb) {
can.onappend.table(can, msg) if (can.Mode() == html.ZONE) { return can.onimport._vimer_zone(can, msg, target), cb && cb(msg) }
can.onappend.board(can, msg) if (msg.index && msg.meta && msg.list) { return cb && cb(msg), can.sup.onimport._field(can.sup, msg) }
can.onmotion.story.auto(can) can.page.ClassList.del(can, can._fields, html.FORM), can.page.ClassList.del(can, can._fields, html.OUTPUT)
can.base.isFunc(cb) && cb(msg) if (can.isCmdMode() && can.Conf(ctx.STYLE) == html.FORM) { can.page.ClassList.add(can, can._fields, html.FORM), can.onappend.style(can, html.OUTPUT) }
}, var cbs = can.onimport[can.Conf(ctx.STYLE)||msg.Option(ctx.STYLE)]; if (can.base.isFunc(cbs)) {
can.onappend.style(can, can._args[ctx.STYLE], target), can.core.CallFunc(cbs, {can: can, msg: msg, target: target})
} else {
can.onappend.table(can, msg, null, target), can.onappend.board(can, msg, target), can.onmotion.story.auto(can, target)
} cb && cb(msg)
},
card: function(can, msg, target, filter) { target = target||can.ui.content||can._output
can.page.Append(can, target, msg.Table(function(value) { if (filter && filter(value)) { return }
var img = can.misc.ResourceIcons(can, value.icon = value.icons||value.icon||value.image)
return {view: [[html.ITEM, value.type, value.status, "s-"+value.name]], list: [
{view: [wiki.TITLE, html.DIV], list: [
img && {className: can.base.contains(img, ".jpg")? "jpg": "", img: img},
{view: wiki.TITLE, list: [{text: value.name}, value.exists == "true" && {text: ["●", "", "exists"]}, can.onappend.label(can, value)]},
]}, {view: [wiki.CONTENT, html.DIV, value.text]},
{view: html.ACTION, inner: value.action, _init: function(target) { can.onappend.mores(can, target, value, html.CARD_BUTTON)
can.page.Select(can, target, html.INPUT, function(target) { can.onappend.style(can, target.name, target) })
}},
]}
})), can.onimport.layout = can.onimport.layout||function() {
var height = can.onlayout.expand(can, target); can.sup.onexport.outputMargin = function() { return height }
can.onmotion.delay(can, function() { can.onlayout.expand(can, target) })
}
},
icon: function(can, msg, target, cb) { msg.Table(function(value) {
var icon = can.misc.Resource(can, value.icons||value.icon||can.page.drawText(can, value.name, 80), value.space||msg.Option(ice.MSG_USERPOD), msg.Option(ice.MSG_USERWEB))
return can.page.Append(can, target, [{view: [[html.ITEM, value.status]], list: [{view: html.ICON, list: [{img: icon}]}, {view: [mdb.NAME, "", value.name]}], _init: function(target) {
cb && cb(target, value)
}, onclick: function(event) { can.sup.onexport.record(can.sup, value.name, mdb.NAME, value) }}])._target
}) },
_icon: function(can, name, button, target) {
var _icon = can.page.icons(can, name) || (can.page.unicode[name] && {text: [can.page.unicode[name]||name, html.SPAN, [html.ICON, name]]})
if (!_icon) { return }
_icon.onclick = function(event) { can.base.isFunc(button)? button(event, button): can.onaction[button](event, can, button), can.onkeymap.prevent(event) }
can.page.Append(can, target, [_icon])
},
_vimer_zone: function(can, msg, target) { msg.Table(function(value) { value._select = value.name == can.Conf("_select")
can.onimport.item(can, value, function(event) { can.sup.onexport.record(can, value.name, mdb.NAME, value, event, event.currentTarget||event.target) })
}) },
_zone_icon: function(can, msg, zone, cb) {
var action = can.core.List(can.Conf(ctx.INPUTS), function(item) { if (item.type == html.BUTTON && [ice.LIST, ice.BACK].indexOf(item.name) == -1) { return item.name } })
var _menu = shy({}, action.concat(can.base.Obj(msg.Option(ice.MSG_ACTION), [])), function(event, button, meta, carte) {
cb? cb(event, button): can.Update(event, [ctx.ACTION, button]), carte.close() })
if (_menu.list.length == 0) {
zone._icon(kit.Dict(web.REFRESH, function(event) { zone.refresh() }))
return
}
zone._icon(kit.Dict(web.REFRESH, function(event) { zone.refresh() }, "menu", function() { can.user.carte(event, can, _menu.meta, _menu.list, _menu) }))
},
_zone: function(can, zone, index, field, hash) { zone._delay_init = function() { can.onimport.plug(can, can.base.isObject(index)? index: {
index: index, style: html.OUTPUT, mode: mdb.ZONE, field: field, _select: hash[2] == zone.name? hash[1]: "",
}, function(sub) { sub.run = function(event, cmds, cb) { can.runActionCommand(can.request(event, {mode: mdb.ZONE}), index.index||index, cmds, cb) }
sub.onexport.output = function(_sub, msg) { can.onimport._zone_icon(sub, msg, zone), zone._total(msg.Length())
sub.onimport.size(sub, zone._target.offsetHeight, zone._target.offsetWidth, false), can.page.style(can, sub._output, html.MAX_HEIGHT, "", html.HEIGHT, "")
can.user.toastSuccess(can)
}, can.ui.zone[zone.name].refresh = function() { sub.Update() }
sub.onimport._field = function(msg) {
msg.Table(function(value) { var pod = msg.Option(ice.MSG_USERPOD), cmd = value._command||value.index, args = can.base.Obj(value.args, [])
can.onimport.tabview(can, "", cmd == chat.IFRAME && args.length > 0? args[0]: "/s/"+pod+"/c/"+cmd, web.SPACE, function(msg) {
can.page.SelectOne(can, msg._tab, html.SPAN, function(target) { can.page.Modify(can, target, value.title||can.core.Keys(pod, cmd)) })
})
})
}
sub.onimport._open = function(msg, arg) { can.onimport.tabview(can, "", arg, web.SPACE, function(msg) {}) }
sub.onexport.record = function(sub, value, key, item, event, target) { can.onimport.tabview(can, "", value, zone.name, function(msg) {
can.onappend.style(can, [item.type, item.status], msg._tab)
msg._item = target
}) }
}, zone._target) } },
zone: function(can, list, target) { target = target||can.ui.project
return can.page.Append(can, target, can.core.List(list, function(zone) { can.base.isString(zone) && (zone = {name: zone}); if (!zone) { return }
zone._layout = function() { var height = target.offsetHeight, count = 0
can.page.SelectChild(can, target, "", function(target) {
can.page.SelectChild(can, target, html.DIV_ITEM, function(target) { height -= target.offsetHeight })
can.page.SelectChild(can, target, html.DIV_ACTION, function(target) { height -= target.offsetHeight })
can.page.SelectChild(can, target, html.DIV_LIST, function(target) { count += can.page.isDisplay(target)? 1: 0 })
})
count && can.page.SelectChild(can, target, "", function(target) {
can.page.SelectChild(can, target, html.DIV_LIST, function(target) {
can.page.style(can, target, html.HEIGHT, can.page.isDisplay(target)? can.base.Min(height/count, 180): "")
})
})
}
return {view: [[html.ZONE, zone.name]], list: [
{view: html.ITEM, list: [{text: can.user.trans(can, zone.name)}], _init: function(target) { zone._legend = target }, onclick: function() {
if (zone._delay_init) { zone._delay_init(zone._target, zone), delete(zone._delay_init) } zone.toggle(), zone._toggle && zone._toggle(zone)
}, oncontextmenu: function(event) { var menu = zone._menu
menu? can.user.carteRight(event, can, menu.meta, menu.list||can.core.Item(menu.meta), can.base.isFunc(menu)? menu: function(event, button, meta, carte) {
can.runAction(event, button), carte.close()
}): can.onmotion.clearCarte(can)
}},
{view: html.ACTION, _init: function(target) { var value; zone._action = target
can.onappend._action(can, [{type: html.TEXT, name: mdb.SEARCH, icon: icon.SEARCH, _init: function(target) { zone._search = target }, onkeyup: function(event) { value = event.target.value
can.page.Select(can, zone._target, html.DIV_EXPAND, function(target) { can.page.ClassList.set(can, target, cli.OPEN, value != "") })
can.page.Select(can, zone._target, html.DIV_LIST, function(item) { can.onmotion.toggle(can, item, value != "") })
can.onmotion.delayOnce(can, function() { value && can.onkeymap.selectItems(event, can, zone._target) }, value.length<3? 500: 150)
}}], target, {})
}},
{view: html.LIST, _init: function(target) { can.ui.zone = can.ui.zone||{}, can.ui.zone[zone.name] = zone, zone._target = target
zone._total = function(total) { return can.page.Modify(can, zone._search, {placeholder: "search in "+total+" items"}), total }
zone._icon = function(list) { can.page.Select(can, zone._legend, html.SPAN_ICON, function(target) { can.page.Remove(can, target) })
can.core.Item(list, function(name, button) { can.onimport._icon(can, name, button, zone._legend) })
}
zone.refresh = function() { can.onmotion.clear(can, target), zone._init(target, zone) }
zone.toggle = function(show) { can.onmotion.toggle(can, zone._target, show), can.onmotion.toggle(can, zone._action, show) }
can.base.isFunc(zone._init)? (zone._menu = zone._init(target, zone)||zone._menu): zone.toggle(false)
}},
]}
}))
},
_icons: function(can, item) { var icon = item.icons||item.icon||item.image
return icon && (can.base.contains(icon, ice.HTTP, ".ico", ".png", ".jpg")? {img: can.misc.Resource(can, icon)}: {icon: icon})
},
_nick: function(can, item) {
if (can.base.isArray(item.nick)) { return item.nick }
if (can.base.isObject(item.nick)) { return item.nick }
return {text: [item.nick||item.name||item.zone||item.sess, "", html.NAME], className: html.NAME}
},
_menu: function(event, can, item, cbs, target) { target = target||event.currentTarget
if (can.base.isFunc(cbs)) { var menu = cbs(event, item, target); if (menu) { return can.user.carteRight(event, can, menu.meta, menu.list, menu) } }
can.user.carteItem(event, can, item)
},
_item: function(can, item, cb, cbs) {
item._hash = item._hash||item.sess||item.hash||item.zone||item.path||item.name
item._hash && item._hash.replaceAll && (item._hash = item._hash.replaceAll(":", "_"))
item._title = item._title||item.name||item.path||item.zone||item.hash
item._select == undefined && can.db.hash[0] && (item._select = can.db.hash[0] == item._hash)
if (typeof item._hash == code.OBJECT) { item._select = true
for (var i = 0; i < item._hash.length; i++) {
if (item._hash[i] != can.db.hash[i]) { item._select = false; break }
}
}
return {view: [[html.ITEM, item.type, item.role, item.status]], title: item.title||item.nick, list: [
can.onimport._icons(can, item),
].concat(can.onimport._nick(can, item), item._label||[], [
(item.action||cbs) && {icon: "bi bi-three-dots", onclick: function(event) { can.onimport._menu(event, can, item, cbs) }},
]), _init: function(target) { target._item = item, item._item = target, can.ui[item.path] = target
item._select && can.onmotion.delay(can, function() { target.click() })
}, onclick: function(event) {
if (cb(event)) { return }
can.db.value = item, can.onexport.hash(can, item._hash)
item.__title? can.user.title(item.__title): can.onexport.title(can, item._title)
}, oncontextmenu: function(event) {
can.onimport._menu(event, can, item, cbs)
}}
},
item: function(can, item, cb, cbs, _target) {
return can.page.Append(can, _target||can.ui.project||can._output, [can.onimport._item(can, item, function(event) { var target = event.currentTarget
can.onmotion.select(can, target.parentNode, html.DIV_ITEM, target)
can.onengine.signal(can, "onproject", can.request(event, {type: "item", query: can.page.getquery(can, can._fields)+","+item.path}))
var show = target._list && can.onmotion.toggle(can, target._list); if (show === false) { return true }
return cb(event, item, show, target)
}, cbs)])._target
},
_itemselect: function(can, target) {
can.page.Select(can, can.ui.project, html.DIV_ITEM, function(target) { can.page.ClassList.del(can, target, html.SELECT) })
for (var p = target; p; p = p.parentNode.previousElementSibling) { can.page.ClassList.add(can, p, html.SELECT), can.onmotion.toggle(can, p.nextSibling, true) }
},
itemlist: function(can, list, cb, cbs, target) { if (!list || list.length == 0) { return }
if (!target) { return can.core.List(list, function(value) { can.onimport.item(can, value, cb, cbs) }) }
if (!target._list) { target._list = can.page.insertBefore(can, [html.LIST], target.nextSibling, target.parentNode) }
return can.page.Append(can, target._list, can.core.List(list, function(item) {
return can.onimport._item(can, item, function(event) { var target = event.currentTarget
if (target._list && target._list.childElementCount > 0 && target._list && can.onmotion.toggle(can, target._list) == false) { return true }
if (cb && cb(event, item, target._list && true, target)) { return }
can.onimport._itemselect(can, target)
}, cbs)
})), target._list
},
tree: function(can, list, cb, cbs, target, node, field, split) { node = node||{"": target||can.ui.project||can._output}, field = field||nfs.PATH, split = split||nfs.PS
can.core.List(list, function(item) { var key = item[field]; key && can.core.List(key.split(split), function(value, index, array) { if (!value) { return }
var last = array.slice(0, index).join(split), name = array.slice(0, index+1).join(split); if (node[name]) { return }
last && node[last] && can.page.Select(can, node[last].previousSibling, "div.expand", function(target) { target.innerHTML == "" && (target.innerHTML = can.page.unicode.closes) })
item.expand = item.expand||item._select||(can.db.hash && (can.db.hash[0] == key))
item._hash = item._hash||item.hash||item.zone||item.path||item.name
item._title = item._title||item.name||item.path||item.path||item.hash
var ui = can.page.Append(can, node[last], [{view: html.ITEM, list: [
{view: [[html.EXPAND], html.DIV, (index==array.length-1? "": can.page.unicode.closes)]},
{view: [mdb.NAME], list: [{text: [value, "", html.NAME]}].concat(item._label||[])},
item.action && {view: [mdb.ICON], list: [{icon: "bi bi-three-dots", onclick: function(event) { can.onimport._menu(event, can, item, cbs) }}]},
], onclick: function(event) { var target = event.currentTarget
if (index < array.length-1 && !can.page.ClassList.set(can, ui[html.EXPAND], cli.OPEN, !can.page.ClassList.neg(can, node[name], html.HIDE))) { return }
can.db.value = item, can.onexport.hash(can, item._hash), can.onexport.title(can, item._title)
can.onimport._itemselect(can, target), can.base.isFunc(cb) && cb(event, item, ui.item)
node[key] && can.page.ClassList.add(can, node[key].previousSibling, html.SELECT)
if (node[name].childElementCount == 2) { can.onmotion.delay(can, function() { node[name].firstChild.click() }) }
}, oncontextmenu: function(event) {
can.onimport._menu(event, can, item, cbs)
}, ondragenter: function(event) {
can.onkeymap.prevent(event)
}, ondragover: function(event) {
can.onkeymap.prevent(event)
}, ondrop: function(event) {
var msg = can.request(event, can.Option(), item, {_handle: ice.TRUE})
can.core.List(event.dataTransfer.files, function(file) {
debugger
msg._upload = file
can.runAction(event, html.UPLOAD, [], function(msg) {
})
})
// msg._upload = event.dataTransfer.files[0]
can.onkeymap.prevent(event)
}, _init: item._init}, {view: [[html.LIST, html.HIDE]]}]); node[name] = ui.list, item.expand && ui.item.click()
}) }); return node
},
tabs: function(can, list, cb, cbs, action) { action = action||can.ui.tabs||can._action; return can.page.Append(can, action, can.core.List(list, function(tabs) { if (typeof tabs == code.STRING) { tabs = {name: tabs} }
function close(target) {
if (can.page.ClassList.has(can, target, html.SELECT)) {
var next = can.page.tagis(target.nextSibling, html.DIV_TABS)? target.nextSibling: can.page.tagis(target.previousSibling, html.DIV_TABS)? target.previousSibling: null
if (!next) { return true } next && next.click()
} can.page.Remove(can, target), can.onexport.tabs && can.onexport.tabs(can)
}
return {view: [[html.TABS, tabs.type, tabs.role, tabs.status]], title: tabs.title||tabs.text, list: [].concat(
can.onimport._icons(can, tabs), can.onimport._nick(can, tabs), {icon: mdb.DELETE, onclick: function(event) { tabs._target._close(), can.onkeymap.prevent(event) }}
), onclick: function(event) {
can.onmotion.delay(can, function() { can.onmotion.scrollIntoView(can, tabs._target) })
if (can.page.ClassList.has(can, tabs._target, html.SELECT)) { return }
can.onmotion.select(can, action, html.DIV_TABS, tabs._target), can.base.isFunc(cb) && cb(event, tabs)
}, oncontextmenu: function(event) { var target = tabs._target, _action = can.page.parseAction(can, tabs)
var menu = tabs._menu||shy(function(event, button) { can.Update(event, [ctx.ACTION, button]) })
can.user.carte(event, can, kit.Dict(
"Close", function(event) { target._close() },
"Close Other", function(event) { target.click(), can.page.SelectChild(can, action, html.DIV_TABS, function(target) { target == tabs._target || target._close() }) },
"Rename Tabs", function(event) { can.user.input(event, can, [mdb.NAME], function(list) {
can.page.SelectOne(can, target, html.SPAN, function(target) { can.page.Modify(can, target, list[0]||tabs.name) })
}) }, menu.meta
), ["Close", "Close Other", "Rename Tabs", ""].concat(can.base.getValid(menu.list, can.core.Item(menu.meta)), _action), function(event, button, meta) {
(meta[button]||menu)(can.request(event, tabs), button, meta)
})
}, _init: function(target) {
action == can._action && can.page.Select(can, can._action, "div.item._space.state", function(space) { can.page.insertBefore(can, target, space) })
target._item = tabs, tabs._target = target, target._close = function() { close(target) || cbs && cbs(tabs) }, target.click()
can.page.Modify(can, target, {draggable: true,
ondragstart: function(event) { action._drop = function(before) { before.parentNode == action && action.insertBefore(target, before), can.onexport.tabs(can) } },
ondragover: function(event) { event.preventDefault(), action._drop(event.target) },
})
}}
}))._target },
tabsCache: function(can, value, target, cb) { if (value._tabs) { return value._tabs.click() }
value._tabs = can.onimport.tabs(can, [value], function() { can.page.isSelect(target) || can.onmotion.delay(can, function() { target.click() })
can.page.SelectOne(can, can._status, html.LEGEND) || can.onmotion.cache(can, function() { return value._hash }, can._status)
if (can.onmotion.cache(can, function() { return value._hash }, can.ui.content, can.ui.profile, can.ui.display)) { return can.onimport.layout(can) }
can.Status(value); if (can.base.isFunc(cb)) { return cb() } var msg = cb
if (msg.Append(ctx.INDEX)) { msg.Table(function(value, index) {
index == 0 && can.onappend.plugin(can, value, function(sub) { can.db.value._content_plugin = sub, can.onimport.layout(can) }, can.ui.content)
index == 1 && can.onappend.plugin(can, value, function(sub) {
can.onmotion.toggle(can, can.ui.display, true)
can.db.value._display_plugin = sub, can.onimport.layout(can)
}, can.ui.display)
index == 2 && can.onappend.plugin(can, value, function(sub) {
can.onmotion.toggle(can, can.ui.profile, true)
can.db.value._profile_plugin = sub, can.onimport.layout(can)
}, can.ui.profile)
can.onmotion.delay(can, function() { can.onimport.layout(can) })
can.onmotion.delay(can, function() { can.onimport.layout(can) }, 100)
can.onmotion.delay(can, function() { can.onimport.layout(can) }, 300)
}) } else { can.onappend.table(can, msg), can.onappend.board(can, msg) }
}, function() { delete(value._tabs), can.onmotion.cacheClear(can, value._hash, can.ui.content, can.ui.profile, can.ui.display) })
},
tool: function(can, list, cb, target, status) { target = target||can._status, status = status||can._status
var height = can.base.Max(html.PLUG_HEIGHT, can.ConfHeight()-3*html.ACTION_HEIGHT, 240), width = can.base.Max(html.PLUG_WIDTH, can.ConfWidth()-(can.user.isMobile? 0: html.PROJECT_WIDTH))
can.core.Next(list.reverse(), function(meta, next) { can.base.isString(meta) && (meta = {index: meta}), meta.mode = html.FLOAT
can.onimport.plug(can, meta, function(sub) {
sub.onexport.output = function() {
can.page.style(can, sub._output, html.MAX_HEIGHT, "", html.HEIGHT, "", html.WIDTH, "", html.MAX_WIDTH, "")
sub.onimport.size(sub, height, width, false), can.onmotion.delay(can, function() { sub.onimport.size(sub, height, width, false) })
}, sub.onimport.size(sub, height, width, false)
can.page.Append(can, sub._legend,[{text: [can.page.unicode.remove, "", mdb.REMOVE], onclick: function(event) {
can.page.Remove(can, sub._target), can.page.Remove(can, sub._legend), can.onexport.tool(can), can.onkeymap.prevent(event)
}}]), sub._legend._target = sub._target, sub._legend._meta = {index: meta.index}
status.appendChild(sub._legend), sub._legend.oncontextmenu = sub._legend.onclick, sub._legend.onclick = function(event) { can.misc.Event(event, can, function(msg) {
if (can.page.SelectOne(can, status, "legend.select", function(target) {
can.onmotion.hidden(can, target._target), can.page.ClassList.del(can, target, html.SELECT); return target }) == sub._legend) { return }
can.onmotion.select(can, status, html.LEGEND, sub._legend), can.onmotion.toggle(can, sub._target, true)
can.onmotion.select(can, target, html.FIELDSET_PLUG, sub._target)
sub.onimport.size(sub, sub.ConfHeight(), sub.ConfWidth(), false)
if (sub._delay_init || meta.msg) { sub._delay_init = false, meta.msg = false, (sub._inputs && sub._inputs.list || sub._inputs && sub._inputs.refresh) && sub.Update() }
}) }, sub._delay_init = true, sub.select = function(show) {
if (show && can.page.ClassList.has(can, sub._legend, html.SELECT)) { return sub }
return sub._legend.click(), sub
}, can.onmotion.hidden(can, sub._target)
sub.hidden = function() { can.onmotion.hidden(can, sub._target), can.page.ClassList.del(can, sub._legend, html.SELECT) }
sub.onaction._close = function() { can.page.Remove(can, sub._target), can.page.Remove(can, sub._legend), can.onexport.tool(can) }
sub.onaction.close = function() { sub.select() }, can.base.isFunc(cb) && cb(sub), can.onexport.tool(can)
next()
}, target)
})
},
plug: function(can, meta, cb, target, field) { if (!meta || !meta.index) { return }
meta.type = meta.type||html.PLUG, meta.name = meta.index, can.onappend.plugin(can, meta, function(sub) { sub.sup = can
sub.onaction.close = function() { can.onmotion.hidden(can, target) }, can.base.isFunc(cb) && cb(sub)
}, target, field)
},
_float: function(can, index, args) { args = args||[]
can.user.isMobile? can.user.jumps(can.misc.MergePodCmd(can, {cmd: index+"/"+args.join("/")})): can.onappend._float(can, index, args)
},
_process: function(can, msg) { myOption: function(can) { var sub = can.sub; if (!sub) { return } var plugin = sub._stacks_current[0]; current = plugin.current||{}
msg.Option(ice.MSG_TOAST) && can.user.toast(can, msg.Option(ice.MSG_TOAST)) if (plugin == sub._stacks_root) { var PLACE_UID = can.core.Item(can.Option())[0]
return can.core.CallFunc([can.onimport, msg.Option(ice.MSG_PROCESS)], [can, msg]) if (sub._stacks_current.length == 1) {
}, plugin.sub.onexport.hash(plugin.sub, can.Option(PLACE_UID))
} else {
plugin.sub.onexport.hash(plugin.sub, can.Option(PLACE_UID), can.ConfIndex(), can.Option(UID))
}
}
can.user.isMobile || sub._stacks_root.onexport.title(sub._stacks_root, current._name, can.ConfHelp(),
can._msg.Option("_share_title")||(can._msg && can._msg.IsDetail()? can._msg.Append(html.TITLE)||can._msg.Append(mdb.NAME)||(can._msg.Append(UID)||"").slice(0, 6): "")
// ||can.user.info.titles
)
can.user.agent.init(can,
can._msg.Option("_share_content")||(can._msg && can._msg.IsDetail()? can._msg.Append(html.CONTENT)||can._msg.Append(mdb.INFO)||"": "")||current.city_name+" "+current._street,
can._msg.Option("_share_icons")||(can.Conf(mdb.ICONS)? can.misc.Resource(can, can.Conf(mdb.ICONS)): can.user.info.nodetype == web.WORKER? can.misc.Resource(can, can.user.info.favicon, can.user.info.nodename): ""),
)
},
myField: function(can, sub) {
sub.onexport._output = function(_sub) {
_sub._stacks_current = can._stacks_current, _sub._stacks_root = can._stacks_root
can.core.Item(can.onimport, function(key, value) { _sub.onimport[key] = _sub.onimport[key]||value })
can.core.Item(can.onaction, function(key, value) { _sub.onaction[key] = _sub.onaction[key]||value })
can.core.Item(can.onexport, function(key, value) { _sub.onexport[key] = _sub.onexport[key]||value })
}
},
myPluginSelect: function(can, sub, _output) {
can.page.SelectChild(can, _output, html.FIELDSET, function(target) { can.onmotion.toggle(can, target, target == sub._target) })
can.page.SelectChild(can, sub._output, "*", function(target) { can.onmotion.toggle(can, target, true) })
can.page.style(can, sub._action, html.DISPLAY, html.NONE)
can.user.isMobile? sub.onimport.size(sub, window.innerHeight, window.innerWidth, false): sub.onimport.size(sub, sub.ConfHeight(), sub.ConfWidth(), false)
can.onimport.myOption(sub)
},
myPlugin: function(can, value, cb) {
var key = [value.space||can.ConfSpace(), value.index||can.ConfIndex()].concat(value.args||"").join(",")
var sup = can._stacks_root; sup._stacks = sup._stacks||{}; var sub = (sup._stacks[key]||[])[0]; if (sub) { return sub._select() }
var _output = sup._target.parentNode; value.height = sup.ConfHeight(), value.width = sup.ConfWidth()
value.style = html.OUTPUT
sup.onappend.plugin(can._root.Action, value, function(sub) { can.onimport.myField(can, sub)
sub.misc.localStorage(sub, [sub.ConfSpace(), sub.ConfIndex(), mdb.HASH].join(","), "")
sub.onexport.output = function(_sub, msg) { _sub._stacks_current = sup._stacks[key] = [sub], _sub._stacks_root = sup, sub._select() }
sub._select = function() { can.onimport.myPluginSelect(can, sub, _output) }, sub._select(), cb && cb(sub)
}, _output)
},
myStory: function(can, value) { var ACTION_HEIGHT = 48
if (!can._stacks_current) { var sup = can.sup; can._stacks_root = sup, sup._stacks = {}
var key = [can.ConfSpace(), can.ConfIndex()].concat(can.base.trim(can.core.Item(can.Option(), function(key, value) { return value }))).join(",")
can._stacks_current = sup._stacks[key] = [can.sup]
sup._select = function() { can.onimport.myPluginSelect(can, sup, sup._target.parentNode) }
} var plugin = can._stacks_current[0], _action = plugin._action, _output = plugin._output; current = plugin.current||{}
value.index == "web.team.renzhengshouquan.profile" && (ACTION_HEIGHT = 0)
value.index.split(".").pop() == "credit" && (ACTION_HEIGHT = 0)
value.type = html.STORY, value.style = html.OUTPUT, value.height = (can.user.isMobile? window.innerHeight: can.ConfHeight())-ACTION_HEIGHT
can.onappend.plugin(can, value, function(sub) {
can._stacks_current.push(sub)
can.core.List(["_trans", "_style", "_icons", "_trans.input", "_trans.value"], function(key) {
var value = sub.Conf(key); value && can.core.Item(can.Conf(key), function(k, v) { value[k] = value[k]||v })
})
var STREET_NAME = plugin.sub.Conf("_street_name"), PLACE_NAME = plugin.sub.Conf("_place_name")
var run = sub.run; sub.run = function(event, cmds, cb) {
run(sub.request(event, {
city_name: current[CITY_NAME], street_name: current[STREET_NAME], place_name: current[PLACE_NAME],
dashboard_uid: current["dashboard_uid"], storage_uid: current["storage_uid"],
command_uid: sub.Conf("command_uid"), portal_name: can.ConfHelp(),
}, can.base.Obj(sub.Conf("field.option"))), cmds, cb)
}
can.onimport.myField(can, sub), can.onmotion.slideIn(sub)
sub.onexport.output = function(_sub, msg) {
sub._select(), msg.Option(ice.MSG_ACTION) && can.onappend._action(sub, msg.Option(ice.MSG_ACTION), _action, null, true)
sub.sub.onaction._goback = goback
}
sub.onimport._field = function(msg) { var sup = sub
can.onmotion.clear(can, sub._output)
msg.Table(function(value) { value.style = html.OUTPUT
can.onappend.plugin(can, value, function(sub) { can.onimport.myField(can, sub)
can._stacks_current.push(sub)
sub.onexport.output = function(_sub, msg) { can.onimport.myOption(sub)
can.user.isMobile && sub.onimport.size(sub, window.innerHeight-ACTION_HEIGHT, window.innerWidth, false)
}
var run = sub.run; sub.run = function(event, cmds, cb) {
run(sub.request(event, {
city_name: current[CITY_NAME], street_name: current[STREET_NAME], place_name: current[PLACE_NAME],
dashboard_uid: current["dashboard_uid"], storage_uid: current["storage_uid"],
command_uid: sub.Conf("command_uid"), portal_name: can.ConfHelp(),
}, can.base.Obj(sub.Conf("field.option")), sup.Option()), cmds, cb)
}
}, sub._output)
})
}
function goback(event, cb) {
if (can._stacks_current.length == 1) { return cb && cb()}
if (sub._history.length > 1) { sub.request(event, {_toast: "reload"}); return sub.onimport.back(event, sub), cb && cb() }
var _last = can._stacks_current.pop()
can.onmotion.slideOut(_last, function() { var last = can._stacks_current[can._stacks_current.length-1]; last._select()
can.onmotion.delay(can, function() { can._root.Action.onlayout._init(can) })
last.request(event, {_toast: "reload"})
if (last.ConfIndex().split(".").pop() == "message") { last.Update(event) }
// can._stacks_current.length == 1 && last._output.innerHTML == "" && last.Update(event)
last._output.innerHTML == "" && last.Update(event)
cb && cb()
})
}
function reload(event) {
sub.Update(sub.request(event, {_toast: "reload"}))
}
sub._select = function() { can.onimport.myOption(sub)
can.page.SelectChild(can, _output, "*", function(target) { can.onmotion.toggle(can, target, target == sub._target) })
var list = [can.page.button(can, can.user.trans(can, "goback", "返回"), function(event) { goback(event) }), can.page.button(can, can.user.trans(can, "reload", "刷新"), function(event) { reload(event) })]
can.page.Appends(can, _action, list), can.page.style(can, _action, html.DISPLAY, html.BLOCK)
can.user.isMobile && sub.onimport.size(sub, window.innerHeight-ACTION_HEIGHT, window.innerWidth, false)
}, sub._select()
}, _output)
},
myTabs: function(can, key, list, target) { var last = can.misc.Cookie(can, key)
if (!target && !can.ui.tabs) { can.ui = can.page.Append(can, can._output, [html.TABS, html.LIST]) } target = target||can.ui.tabs
can.page.Append(can, target, can.core.List(list, function(value) {
return {text: [can.user.trans(can, value, "", "value."+key), "", [value, value == "all" && last == "" || value == last? html.SELECT: ""]], onclick: function(event) {
can.onmotion.select(can, target, "*", event.target), can.misc.Cookie(can, key, value == "all"? "": value), can.Update()
}}
}))
},
myView: function(can, msg, cb, cbs, target) {
can.onimport.itemcards(can, msg, cb, cbs, target||can.ui.list)
},
itemcards: function(can, msg, cb, cbs, target) { target = target||can.ui.list||can._output
if (msg.IsDetail()) { var value = msg.TableDetail(); msg.Show(can)
can.page.Select(can, target, html.TR, function(target) {
target.className.indexOf("_uid") > -1 && can.page.ClassList.add(can, target, "hide")
})
} else {
can.page.Append(can, target, msg.Table(function(value) {
return can.onimport.itemcard(can, value, cb(value), cbs)
})), msg.Result() && can.onappend.board(can, msg), can.onappend.style(can, msg.Option(ctx.STYLE))
}
can.page.Select(can, target, html.INPUT_BUTTON, function(target) {
var style = can.Conf("_style."+target.name); style && can.page.ClassList.add(can, target, style)
})
can.onimport.shareTitle(can, msg)
},
itemcard: function(can, value, list, cb) { if (!list) { return }
can.core.List(list, function(item) { if (!item || !item.list) { return }
for (var i = 0; i < item.list.length; i++) { if (item.list[i] && typeof item.list[i] == code.STRING) { item.list[i] = {text: item.list[i]} } }
})
cb = cb|| function(event) { var done = false
if (can.onaction.carddetail && can.onaction.carddetail(event, can, value)) { return }
if (value.uid) { return can.Option(UID, value.uid), can.Update() }
can.core.Item(can.Option(), function(k, v) {
if (!done && !v) { done = true, can.Option(k, value[k]), can.Update() }
})
}
return {view: [[html.ITEM_CARD, value._uid? "uid-"+value._uid: ""].concat(value._style||[])], list: [
{view: html.ACTION, _init: function(target) { can.page.appendAction(can, value, target)
can.user.isMobile && can.page.Select(can, target, "input.notice", function(target) { can.page.Remove(can, target) })
}},
{view: html.OUTPUT, list: [
{img: can.misc.ResourceIcons(can, value.icons||value.icon||value.avatar||
value.auth_avatar||value.command_icon||value.service_icon||value.user_avatar||can.Conf(mdb.ICONS), value.nodename,
), onclick: function(event) { can.onkeymap.prevent(event)
can.onaction.updateAvatar && can.onaction.updateAvatar(event, can)
}},
{view: html.CONTAINER, list: list},
], _init: function(target) {
value.action && can.onmotion.slideAction(can, target)
}},
], onclick: function(event) { cb && cb(event, value)
can.onmotion.select(can, event.currentTarget.parentNode, html.DIV_ITEM, event.currentTarget)
}}
},
textView: function(can, value, key, type) {
key || can.core.Item(value, function(k, v) { if (k == "status" || can.base.endWith(k, "_status")) { key = k } }); if (!type) { type = key.split("_").pop() }
return value[key] && !can.base.isIn(value[key], "finish", "done") && {text: [can.user.transValue(can, value, key), "", [type, value[key], can.Conf("_trans.value."+key+".style."+value[key])||""]]}
},
authView: function(can, value) { return can.base.isIn(value.auth_status, "issued", "2") && {view: [aaa.AUTH, html.SPAN], list: [{icon: "bi bi-patch-check-fill", style: {color: "var(--notice-bg-color)"}}]} },
timeView: function(can, value, key) {
if (key) { return {text: [can.user.trans(can, key, null, html.INPUT)+": "+can.base.TimeTrim(value[key]), "", mdb.TIME]} }
return {text: [can.base.TimeTrim(value[key]||value.browse_time||value.updated_at||value.created_at||value.time), "", mdb.TIME]}
},
unitView: function(can, value, key, unit) { if (!value[key]) { return }
return {text: [[can.user.trans(can, key, null, html.INPUT)+":", value[key]].concat(unit? [unit]: []).join(" "), "", key]}
},
typeStyle: function(can, value, key) { return can.Conf("_trans.value."+key+".style."+value[key])||"" },
roleStyle: function(can, value, key) { return can.Conf("_trans.value."+key+".style."+value[key])||"" },
shareTitle: function(can, msg, title, content, icons) { if (msg.IsDetail()) { var value = msg.TableDetail()
msg.Option("_share_title", msg.Option("_share_title")||(value[title]||value.title||value.name||value.uid).slice(0, 6))
msg.Option("_share_content", msg.Option("_share_content")||value[content]||value.content||value.info)
msg.Option("_share_icons", msg.Option("_share_icons")||value[icons]||value.icons||value.avatar)
} },
titleAction: function(can, value, filter) { var filter = can.core.List(arguments).slice(2)
return {view: html.ACTION, _init: function(target) {
if (value.Option) { return can.onappend._action(can, value.Option(ice.MSG_ACTION), target) }
can.page.appendAction(can, value, target)
can.page.Select(can, target, html.INPUT_BUTTON, function(target) {
target.value = can.user.trans(can, target.name)
if (filter.length > 0) {
filter.indexOf(target.name) == -1 && can.page.Remove(can, target)
} else {
can.page.tagis(target, "input.notice") || can.page.Remove(can, target)
}
})
}}
},
})
Volcanos(chat.ONLAYOUT, {
_init: function(can, height, width) { can.core.CallFunc([can.onimport, html.LAYOUT], {can: can, height: height, width: width}) },
zone: function(can, height, width) { can.onlayout._init(can, height, width) },
result: function(can, height, width) { can.onlayout._init(can, height, width) },
simple: function(can, height, width) { can.onlayout._init(can, height, width) },
output: function(can, height, width) { can.onlayout._init(can, height, width) },
float: function(can, height, width) { can.onlayout._init(can, height, width) },
full: function(can, height, width) { can.onlayout._init(can, height, width) },
cmd: function(can, height, width) { can.onlayout._init(can, height, width) },
})
Volcanos(chat.ONEXPORT, {
title: function(can, title) { can.sup.onexport.title.apply(can.sup.onexport, [can.sup].concat(can.core.List(arguments).slice(1))) },
action_value: function(can, key, def) { var value = can.Action(key); return can.base.isIn(value, ice.AUTO, key, undefined)? def: value },
tabs: function(can) {},
tool: function(can) { can.misc.sessionStorage(can, [can.ConfIndex(), "tool"], JSON.stringify(can.page.Select(can, can._status, html.LEGEND, function(target) { return target._meta }))) },
hash: function(can, hash) { hash = typeof hash == code.STRING? hash.split(":").concat(can.core.List(arguments).slice(2)||[]): hash || can.core.Item(can.Option(), function(key, value) { return value||"" })
return can.sup.onexport.hash(can.sup, hash)
},
session: function(can, key, value) { return can.sup.onexport.session(can.sup, key, value) },
storage: function(can, key, value) { return can.sup.onexport.storage(can.sup, key, value) },
table: function(can) { var msg = can._msg; if (msg.Length() == 0) { return } var res = [msg.append && msg.append.join(mdb.FS)]
msg.Table(function(line, index, array) { res.push(can.core.Item(line, function(key, value) { return value }).join(ice.FS)) })
return res.join(lex.NL)
},
board: function(can) { var msg = can._msg; return msg.Result() },
})
Volcanos(chat.ONACTION, {
onkeydown: function(event, can) {
if (can.onkeymap.selectCtrlN(event, can, can.ui.tabs||can._action, html.DIV_TABS)) { return }
can.onkeymap._parse(event, can)
},
onslidemove: function(event, can, data, direction) {
// can.user.toast(can, [direction, data.spanX, data.spanY].join(","))
},
onslideright: function(event, can, data, direction) {
can.onaction._goback && can.onaction._goback(event)
},
onslideleft: function(event, can, data, direction) {
return
var button = can.base.Obj(can._msg.Option("_action"), [])[0]; if (!button) { return }
can.run({}, [ctx.ACTION, button].concat(can.base.trim(can.core.Item(can.Option(), function(key, value) { return value }))))
},
onslidedown: function(event, can, data, direction) {
return
var target = can.ui.list||can.ui.output||can._output
if (target.scrollTop == 0) {
can.Update(can.request(event, {_toast: "reload"}))
}
},
onslideup: function(event, can, data, direction) {
return
var target = can.ui.list||can._output
if (target.offsetHeight+target.scrollTop == target.scrollHeight) {
can.Update(can.request(event, {_toast: "reload"}))
}
},
})
Volcanos(chat.ONKEYMAP, {
escape: function(event, can) {}, enter: function(event, can) {},
ctrln: function(event, can) { can.onkeymap.selectCtrlN(event, can, can._action, html.DIV_TABS) },
space: function(event, can) { can.ui.filter && (can.ui.filter.focus(), can.onkeymap.prevent(event)) },
tabx: function(event, can) { can.page.Select(can, can._action, html.DIV_TABS_SELECT, function(target) { target._close() }) },
tabs: function(event, can) {},
_mode: {
plugin: {
Escape: shy("清理屏幕", function(event, can) { can.onkeymap.escape(event, can) }),
Enter: shy("执行操作", function(event, can) { can.onkeymap.enter(event, can) }),
" ": shy("搜索项目", function(event, can) { can.onkeymap.space(event, can) }),
f: shy("搜索项目", function(event, can) { can.ui.filter && (can.ui.filter.focus(), can.onkeymap.prevent(event)) }),
a: shy("展示项目", function(event, can) { can.ui.project && (can.onmotion.toggle(can, can.ui.project), can.onimport.layout(can)) }),
v: shy("展示预览", function(event, can) { can.ui.profile && (can.onmotion.toggle(can, can.ui.profile), can.onimport.layout(can)) }),
r: shy("展示输出", function(event, can) { can.ui.display && (can.onmotion.toggle(can, can.ui.display), can.onimport.layout(can)) }),
p: shy("添加插件", function(event, can) { can.sup.onaction["添加工具"](event, can.sup) }),
t: shy("添加标签", function(event, can) { can.onkeymap.tabs(event, can) }),
x: shy("添加标签", function(event, can) { can.onkeymap.tabx(event, can) }),
l: shy("打开右边标签", function(event, can) { can.page.Select(can, can._action, html.DIV_TABS_SELECT, function(target) {
var next = target.nextSibling; next && can.page.ClassList.has(can, next, html.TABS) && next.click()
}) }),
h: shy("打开左边标签", function(event, can) { can.page.Select(can, can._action, html.DIV_TABS_SELECT, function(target) {
var prev = target.previousSibling; prev && can.page.ClassList.has(can, prev, html.TABS) && prev.click()
}) }),
},
}, _engine: {},
})
Volcanos(chat.ONINPUTS, {
_nameicon: function(event, can, msg, target, name, title) { name = name||mdb.NAME
can.page.Appends(can, can._output, msg.Table(function(value) {
var _title = can.user.trans(can.sup, value[title]||value[name]||value[mdb.NAME], null, "value."+name)
var icons = can.sup.Conf("_trans.value."+name+".icons."+value[name])||can.sup.Conf("_trans.value."+name+".icons."+value[title])||value.icons||"usr/icons/icebergs.png"
return {view: html.ITEM, list: [{img: can.misc.Resource(can, icons), },
{view: html.CONTAINER, list: [{view: [html.TITLE, "", _title]},
can.onappend.label(can, value, kit.Dict("version", icon.version, "time", icon.compile, name, icon.data)),
]},
], onclick: function(event) { can.showIcons(value[name]||value[mdb.NAME], icons, _title) }}
}))
},
dream: function(event, can, msg, target, name) { can.sup.sub.oninputs._nameicon(event, can, msg, target, name) },
}) })
Volcanos("onaction", {help: "控件交互", list: []})
Volcanos("onexport", {help: "导出数据", list: []})

496
proto.js
View File

@ -1,329 +1,171 @@
var kit = { function shy(help, meta, list, cb) { var arg = arguments, i = 0; function next(type) {
Dict: function() { var res = {} if (type == code.OBJECT) { if (typeof arg[i] == code.OBJECT && arg[i].length == undefined) { return arg[i++] }
for (var i = 0; i < arguments.length; i += 2) { } else if (type == code.ARRAY) { if (typeof arg[i] == code.OBJECT && arg[i].length != undefined) { return arg[i++] }
res[arguments[i]] = arguments[i+1] } else if (i < arg.length && (!type || type == typeof arg[i])) { return arg[i++] }
} return res } return cb = typeof arg[arg.length-1] == code.FUNCTION? arg[arg.length-1]: function() {}, cb.help = next(code.STRING)||"", cb.meta = next(code.OBJECT)||{}, cb.list = next(code.ARRAY)||[], cb
}
}
var ice = {
SP: " ", PS: "/", PT: ".", FS: ",", NL: "\n",
POD: "pod", CTX: "ctx", CMD: "cmd", ARG: "arg", OPT: "opt",
RUN: "run", RES: "res", ERR: "err",
OK: "ok", TRUE: "true", FALSE: "false", SUCCESS: "success", FAILURE: "failure", PROCESS: "process",
AUTO: "auto", HELP: "help", HTTP: "http",
VIEW: "view", MODE: "mode", SHIP: "ship",
COPY: "copy", SHOW: "show", HIDE: "hide",
MSG_DETAIL: "detail",
MSG_OPTION: "option",
MSG_APPEND: "append",
MSG_RESULT: "result",
MSG_FIELDS: "fields",
MSG_SESSID: "sessid",
MSG_SOURCE: "_source",
MSG_TARGET: "_target",
MSG_HANDLE: "_handle",
MSG_UPLOAD: "_upload",
MSG_DAEMON: "_daemon",
MSG_ACTION: "_action",
MSG_STATUS: "_status",
MSG_DISPLAY: "_display",
MSG_PROCESS: "_process",
MSG_USERNAME: "user.name",
MSG_USERNICK: "user.nick",
MSG_TITLE: "sess.title",
MSG_TOPIC: "sess.topic",
MSG_RIVER: "sess.river",
MSG_STORM: "sess.storm",
MSG_TOAST: "sess.toast",
PROCESS_AGAIN: "_again",
MSG_PREFIX: "_prefix",
ErrWarn: "warn: ",
ErrNotFound: "not found: ",
}
var ctx = {
CONTEXT: "context", COMMAND: "command", ACTION: "action", CONFIG: "config",
INPUTS: "inputs", FEATURE: "feature",
INDEX: "index", ARGS: "args",
}
var cli = {
CODE: "code", COST: "cost", FROM: "from", BACK: "back",
OPEN: "open", CLOSE: "close", BEGIN: "begin", END: "end",
START: "start", STOP: "stop", DONE: "done", ERROR: "error",
CLEAR: "clear", REFRESH: "refresh",
RED: "red", GREEN: "green", BLUE: "blue",
YELLOW: "yellow", CYAN: "cyan", PURPLE: "purple", MAGENTA: "magenta",
WHITE: "white", BLACK: "black",
}
var web = {
SPACE: "space", SHARE: "share",
}
var aaa = {
USERNAME: "username", USERNICK: "usernick", BACKGROUND: "background", AVATAR: "avatar",
LANGUAGE: "language", ENGLISH: "english", CHINESE: "chinese",
LOGIN: "login", LOGOUT: "logout", INVITE: "invite",
}
var mdb = {
DICT: "dict", META: "meta", HASH: "hash", LIST: "list",
ID: "id", KEY: "key", TIME: "time", ZONE: "zone", TYPE: "type", NAME: "name", TEXT: "text",
LINK: "link", SCAN: "scan", SHOW: "show", HELP: "help",
SHORT: "short", FIELD: "field", TOTAL: "total", COUNT: "count", LIMIT: "limit",
INDEX: "index", VALUE: "value", EXTRA: "extra", ALIAS: "alias", EXPIRE: "expire",
CREATE: "create", REMOVE: "remove", INSERT: "insert", DELETE: "delete",
MODIFY: "modify", SELECT: "select",
INPUTS: "inputs", PRUNES: "prunes", EXPORT: "export", IMPORT: "import",
PLUGIN: "plugin", RENDER: "render", SEARCH: "search", ENGINE: "engine",
NEXT: "next", PREV: "prev", PAGE: "page", MAIN: "main",
}
var ssh = {
SCRIPT: "script",
}
var nfs = {
HTML: "html", CSS: "css", JS: "js", GO: "go", SH: "sh", CSV: "csv", JSON: "json",
PATH: "path", FILE: "file", LINE: "line", SIZE: "size",
DIR: "dir", CAT: "cat", TRASH: "trash",
DIR_ROOT: "dir_root",
}
var tcp = {
HOST: "host", PORT: "port",
}
var code = {
VIMER: "vimer", INNER: "inner", FAVOR: "favor",
WEBPACK: "webpack",
}
var wiki = {
TITLE: "title", BRIEF: "brief", REFER: "refer", SPARK: "spark",
ORDER: "order", TABLE: "table", CHART: "chart", IMAGE: "image", VIDEO: "video",
FIELD: "field", SHELL: "shell", LOCAL: "local", PARSE: "parse",
NAVMENU: "navmenu", PREMENU: "premenu",
}
var chat = {
LIB: "lib", PAGE: "page", PANEL: "panel", PLUGIN: "plugin", OUTPUT: "output", INPUT: "input", UPLOAD: "upload",
STORY: "story", FLOAT: "float", CONTEXTS: "contexts", CARTE: "carte", TOAST: "toast",
LEGNED: "legend", OPTION: "option", ACTION: "action", OUTPUT: "output", STATUS: "status",
LAYOUT: "layout", PROJECT: "project", CONTENT: "content", DISPLAY: "display", PROFILE: "profile",
TITLE: "title", TOPIC: "topic", BLACK: "black", WHITE: "white", PRINT: "print",
SHARE: "share", RIVER: "river", STORM: "storm", FIELD: "field", TOAST: "toast",
PUBLIC: "public", PROTECTED: "protected", PRIVATE: "private",
USER: "user", TOOL: "tool", NODE: "node",
AGENT: "agent", CHECK: "check", GRANT: "grant",
STATE: "state", MENUS: "menus", TRANS: "trans",
ONMAIN: "onmain", ONLOGIN: "onlogin", ONSEARCH: "onsearch",
ONSIZE: "onsize", ONTOAST: "ontoast", ONREMOTE: "onremote",
HEAD: "head", LEFT: "left", MAIN: "main", AUTO: "auto", HIDE: "hide", FOOT: "foot",
SCROLL: "scroll", LEFT: "left", TOP: "top", RIGHT: "right", BOTTOM: "bottom",
HEADER: "header", FOOTER: "footer",
SSO: "sso", CMD_MARGIN: 53,
libs: ["/lib/base.js", "/lib/core.js", "/lib/misc.js", "/lib/page.js", "/lib/user.js"],
panel_list: [
{name: "Header", help: "标题栏", pos: "head", state: ["time", "usernick", "avatar"]},
{name: "River", help: "群聊组", pos: "left", action: ["create", "refresh"]},
{name: "Action", help: "工作台", pos: "main"},
{name: "Search", help: "搜索框", pos: "auto"},
{name: "Footer", help: "状态条", pos: "foot", state: ["ncmd"]},
],
plugin_list: [
"/plugin/state.js",
"/plugin/input.js",
"/plugin/table.js",
"/plugin/input/key.js",
"/plugin/input/date.js",
"/plugin/story/spide.js",
"/plugin/story/trend.js",
"/plugin/local/code/inner.js",
"/plugin/local/code/vimer.js",
"/plugin/local/wiki/draw/path.js",
"/plugin/local/wiki/draw.js",
"/plugin/local/wiki/word.js",
"/plugin/local/chat/div.js",
"/plugin/local/team/plan.js",
"/plugin/input/province.js",
],
}
var team = {
TASK: "task", PLAN: "plan",
}
var mall = {
ASSET: "asset", SALARY: "salary",
}
var svg = {
G: "g", X: "x", Y: "y", R: "r", RECT: "rect",
M: "M", Q: "Q", T: "T",
}
var html = {
FIELDSET: "fieldset", LEGEND: "legend", OPTION: "option", ACTION: "action", OUTPUT: "output", STATUS: "status",
FORM_OPTION: "form.option", DIV_ACTION: "div.action", DIV_OUTPUT: "div.output", DIV_STATUS: "div.status",
UPLOAD: "upload", USERNAME: "username", PASSWORD: "password",
INPUT: "input", INPUT_ARGS: ".args", TEXT: "text", TEXTAREA: "textarea", SELECT: "select", BUTTON: "button",
FORM: "form", FILE: "file", SPACE: "space", CLICK: "click", SUBMIT: "submit", CANCEL: "cancel",
DIV: "div", IMG: "img", CODE: "code", SPAN: "span", VIDEO: "video",
TABLE: "table", TR: "tr", TH: "th", TD: "td", BR: "br", UL: "ul", LI: "li",
A: "a", LABEL: "label", INNER: "inner", TITLE: "title",
CLASS: "class", BLOCK: "block", NONE: "none", FLOAT: "float", CLEAR: "clear",
STROKE_WIDTH: "stroke-width", STROKE: "stroke", FILL: "fill", FONT_SIZE: "font-size", MONOSPACE: "monospace",
SCROLL: "scroll", HEIGHT: "height", WIDTH: "width", LEFT: "left", TOP: "top", RIGHT: "right", BOTTOM: "bottom",
MAX_HEIGHT: "max-height", MAX_WIDTH: "max-width",
HIDDEN: "hidden", SELECT: "select",
WSS: "wss", SVG: "svg", CANVAS: "canvas", IFRAME: "iframe", CHROME: "chrome",
LIST: "list", ITEM: "item", MENU: "menu", NODE: "node",
HIDE: "hide", SHOW: "show",
}
var lang = {
STRING: "string", NUMBER: "number",
OBJECT: "object", FUNCTION: "function",
ESCAPE: "Escape", ENTER: "Enter", TAB: "Tab",
}
function shy(help, meta, list, cb) {
var index = 0, args = arguments; function next(type) {
if (index < args.length && (!type || type == typeof args[index])) {
return args[index++]
}
}
cb = args[args.length-1]||function() {}
cb.help = next(lang.STRING)||""
cb.meta = next(lang.OBJECT)|| {}
cb.list = next(lang.OBJECT)||[]
return cb
}; var _can_name = "", _can_path = "" }; var _can_name = "", _can_path = ""
var Volcanos = shy("火山架", {iceberg: "/chat/", volcano: "/frame.js", args: {}, pack: {}, libs: [], cache: {}}, function(name, can, libs, cb) { var Volcanos = shy({iceberg: "", volcano: "", frame: chat.FRAME_JS, _cache: {}, cache: {}, pack: {}, args: {}}, function(name, can, libs, cb) {
var meta = arguments.callee.meta, list = arguments.callee.list var meta = arguments.callee.meta, list = arguments.callee.list; if (typeof name == code.OBJECT) {
if (typeof name == lang.OBJECT) { var Config = name; Config.plugin = Config.plugin||chat.plugin_list if (name.length > 0) { return Volcanos({panels: [{name: chat.HEADER, style: html.HIDE, state: [mdb.TIME, aaa.USERNICK]}, {name: chat.ACTION, style: html.MAIN, tool: name}, {name: chat.FOOTER, style: html.HIDE}]}) }
Config.panels = Config.panels||chat.panel_list, Config.main = Config.main||{name: "Header"} var Config = name; name = Config.name||ice.CAN, meta.iceberg = Config.iceberg||meta.iceberg, meta.volcano = Config.volcano||meta.volcano
meta.libs = chat.libs, meta.iceberg = Config.iceberg||meta.iceberg meta.libs = (Config.libs||chat.libs).concat(Config.list), panels = Config.panels||chat.panel_list, delete(Config.panels)
libs = [], panels.forEach(function(p) { p && (libs = libs.concat(p.list = p.list||["/panel/"+p.name+nfs._JS, "/panel/"+p.name+nfs._CSS])) }), libs = libs.concat(Config.plugins||chat.plugin_list)
// 预加载 cb = can||function(can) { can.require([can.frame], function() { can.onengine._init(can, can.Conf(Config), panels, Config._init||meta._init, can._target) }, function(can, key, sub) { can[key] = sub }) }
libs = []; for (var i = 0; i < Config.panels.length; i++) { var panel = Config.panels[i] can = Config, can._follow = name, can._target = Config.target||meta.target, can._height = Config.height||meta._height, can._width = Config.width||meta._width, _can_name = ""
panel && (libs = libs.concat(panel.list = panel.list||["/panel/"+panel.name+".css", "/panel/"+panel.name+".js"])) }
}; libs = libs.concat(Config.plugin, Config.main.list) can = kit.proto(can||{}, kit.proto({_name: name, _path: _can_name,
_load: function(name, cbs) { var cache = meta.cache[name]||[]
// 根模块 for (list.reverse(); list.length > 0; list) { var sub = list.pop(); sub != can && cache.push(sub), sub._path = sub._path||name } meta.cache[name] = cache
_can_name = "", name = Config.name||"chat", cb = can||function(can) { cache.forEach(function(sub) { var name = sub._name
can.onengine._init(can, can.Conf(Config), Config.panels, Config._init, can._target) if (typeof cbs == code.FUNCTION && cbs(can, name, sub)) { return }
}, can = {_follow: name, _target: Config.target||document.body}, can._root = can can[name] = can[name]||{}, name == chat.ONIMPORT && (can[name]._last_init = sub._init)
for (var k in Config) { can[k] = Config[k] } for (var k in sub) { can[name].hasOwnProperty(k) || sub.hasOwnProperty(k) && (can[name][k] = sub[k]) }
} })
},
can = can||{} require: function(libs, cb, cbs) {
var proto = {__proto__: meta, _path: _can_path, _name: name, _load: function(name, each) { // 加载缓存 if (!libs || libs.length == 0) {
var cache = meta.cache[name]||[]; for (list.reverse(); list.length > 0; list) { if (navigator.userAgent == "nodejs") { return typeof cb == code.FUNCTION && cb(can) }
var sub = list.pop(); sub != can && cache.push(sub) return typeof cb == code.FUNCTION && setTimeout(function() { cb(can) }, 30)
}; meta.cache[name] = cache }
if (libs[0] == undefined) { return can.require(libs.slice(1), cb, cbs) }
// 加载模块 if (libs[0] == "") { libs[0] = can._path.replace(nfs._JS, nfs._CSS) }
for (var i = 0; i < cache.length; i++) { var sub = cache[i], name = sub._name if (libs[0].indexOf(nfs.SRC) == 0 || libs[0].indexOf(nfs.USR) == 0) { libs[0] = nfs.P+libs[0] }
if (typeof each == lang.FUNCTION && each(can, name, sub)) { continue } if (libs[0][0] != nfs.PS && libs[0].indexOf(web.HTTP) != 0) { libs[0] = can._path.slice(0, can._path.lastIndexOf(ice.PS)+1)+libs[0] }
!can[name] && (can[name] = {}); for (var k in sub) { // var name = (libs[0].indexOf(web.HTTP) == 0 || libs[0].indexOf("?pod=") > -1? libs[0]: libs[0].split(ice.QS)[0]).toLowerCase()
can[name].hasOwnProperty(k) || (can[name][k] = sub[k]) // var name = (libs[0].indexOf(web.HTTP) == 0 || libs[0].indexOf("?pod=") > -1? libs[0]: libs[0]).toLowerCase()
} var name = libs[0].indexOf(web.HTTP) == 0 || libs[0].indexOf("?pod=") > -1? libs[0]: libs[0]
} if (name.indexOf("pod=") == -1) { name = name.toLowerCase() }
}, function next() { can._load(name, cbs), can.require(libs.slice(1), cb, cbs) }
require: function(libs, cb, each) { if (!libs || libs.length == 0) { if (name.indexOf("/lib/") == 0) { name = "/v"+name }
typeof cb == lang.FUNCTION && setTimeout(function() { cb(can) }, 10) if (name.indexOf("/panel/") == 0) { name = "/v"+name }
return // 加载完成 if (name.indexOf("/plugin/") == 0) { name = "/v"+name }
} if (name.indexOf("/volcanos/") == 0 && meta.volcano) { name = meta.volcano+name }
if (name.indexOf("/require/") == 0 && meta.iceberg) { name = meta.iceberg+name }
if (!libs[0]) { return can.require(libs.slice(1), cb, each) } if (name.indexOf("/p/") == 0 && meta.iceberg) { name = meta.iceberg+name }
libs[0] = libs[0].toLowerCase() if (name.indexOf("/v/") == 0 && meta.iceberg) { name = meta.iceberg+name }
meta.cache[name]? next(): meta._load(name, next)
// 请求模块 },
var name = libs[0].split("?")[0] request: function(event) { event = event||{}, event = event._event||event
function next() { can._load(name, each), can.require(libs.slice(1), cb, each) } var msg = event._msg||can.misc.Message(event, can); event._msg = msg
meta.cache[name]? next(): (_can_path = libs[0], meta._load(name, next)) function set(key, value) {
}, if (key == "_method") { return msg._method = value }
request: function(event, option) { event = event||{} if (key == "action" && value.indexOf("<input") == 0) { return }
var msg = event._msg||can.misc.Message(event, can); event._msg = msg if (key == "extra") { return }
function set(key, value) { msg.Option(key) || value == "" || msg.Option(key, value) } if (typeof value == code.FUNCTION) { return msg[key] = value }
value == "" || msg.Option(key) || msg.Option(key, value)
can.core.List(arguments, function(option, index) { if (index == 0) { return } }
can.base.isFunc(option.Option)? can.core.List(option.Option(), function(key) { can.core.List(arguments, function(item, index) { if (!item || index == 0) { return }
set(key, option.Option(key)) can.base.isFunc(item.Option)? can.core.List(item.Option(), function(key) {
}): can.core.Item(can.base.isFunc(option)? option(): option, set) key.indexOf("_") == 0 || key.indexOf("user.") == 0 || set(key, item.Option(key))
}); return msg }): can.core.Item(can.base.isFunc(item)? item(): item, set)
}, })
return msg
set: function(name, key, value) { var msg = can.request({}); msg.Option(key, value) },
return can.search(msg._event, [can.core.Keys(name, "onimport", key)]) requests: function(event) { var msg = can.request(event); function set(key, value) { msg.Option(key, value) }
}, can.core.List(arguments, function(item, index) { if (!item || index == 0) { return } can.core.Item(item, set) }); return msg
get: function(name, key, cb) { },
if (can.user.mod.isCmd && name == "Action" && key == "size") { requestPodCmd: function(event) { return can.request(event, {pod: can.ConfSpace(), index: can.ConfIndex()}) },
var msg = can.request({}, {left: 0, top: 0, width: window.innerWidth, height: window.innerHeight}) requestAction: function(event, button) { return can.request(event, {action: button, _toast: event.isTrusted? can.user.trans(can, button): ""}) },
return can.core.CallFunc(cb, {msg: msg}) runActionInputs: function(event, cmds, cb) { var msg = can.request(event), meta = can.Conf()
} if (msg.Option(ice.MSG_HANDLE) != ice.TRUE && cmds && cmds[0] == ctx.ACTION && meta.feature[cmds[1]]) { var msg = can.request(event, {action: cmds[1]})
return can.search({}, [can.core.Keys(name, "onexport", key)], cb) if (can.base.isFunc(meta.feature[cmds[1]])) { return meta.feature[cmds[1]](can, msg, cmds.slice(2)) }
}, return can.user.input(event, can, meta.feature[cmds[1]], function(args) { can.Update(can.request(event, {_handle: ice.TRUE}, can.Option()), cmds.slice(0, 2).concat(args)) })
getActionSize: function(cb) { can.get("Action", "size", cb) }, } can.runAction(event, cmds[1], cmds.slice(2), cb, true)
search: function(event, cmds, cb) { return can.run && can.run(event, ["_search"].concat(cmds), cb, true) }, },
runActionCommand: function(event, index, args, cb) {
Conf: function(key, value) { return can.core.Value(can._conf, key, value) }, _conf: {}, var msg = can.request(event, {_handle: ice.TRUE}); can.request(event)._caller()
} can.run(event, [ctx.ACTION, ctx.RUN].concat(index, args||[]), cb, true)
},
if (navigator.userAgent.indexOf("MSIE") > -1) { runAction: function(event, action, args, cb, silent) {
for (var k in proto) { can[k] = proto[k] } var msg = can.request(event, {_handle: ice.TRUE}); can.request(event, can.Option())._caller()
} else { can.run(event, [ctx.ACTION].concat(action, args||[]), cb, silent)
can.__proto__ = proto },
} search: function(event, cmds, cb) {
if (cmds && typeof cmds == code.OBJECT && cmds.length > 0 && typeof cmds[0] == code.OBJECT && cmds[0].length > 0 ) { cmds[0] = cmds[0].join(nfs.PT) }
if (_can_name) { // 加入缓存 return (can._root||can).run(event, [chat._SEARCH].concat(cmds), cb, true)
meta.cache[_can_name] = meta.cache[_can_name]||[], meta.cache[_can_name].push(can) },
} else { // 加入队列 get: function(name, key, cb) { var value; can.search({}, [can.core.Keys(name, chat.ONEXPORT, key)], cb||function(msg) { value = msg.Result() }); return value },
list.push(can) set: function(name, key, value) { var msg = can.request(); msg.Option(key, value); return can.search(msg, [[name, chat.ONIMPORT, key]]) },
} setHeaderMenu: function(list, cb) { can._menu && can.page.Remove(can, can._menu)
if (can._follow) { libs = libs.concat(meta.libs, meta.volcano) } return can._menu = can.search(can.request({}, {trans: can.onaction._trans}), [[chat.HEADER, chat.ONIMPORT, html.MENU], can._name].concat(list), cb)
if (libs && libs.length > 0) { },
for (var i = 0; i < libs.length; i++) { setFooterMenu: function(list, cb) { can._footer_menu && can.page.Remove(can, can._footer_menu)
if (libs[i] == undefined) { return can._footer_menu = can.search(can.request({}, {trans: can.onaction._trans}), [[chat.FOOTER, chat.ONIMPORT, html.MENU], can._name].concat(list), cb)
},
} else if (libs[i] == "") { getHeaderTheme: function(cb) { return can.get(chat.HEADER, chat.THEME, cb) },
libs[i] = _can_path.replace(".js", ".css") getHeaderLanguage: function(cb) { return can.get(chat.HEADER, aaa.LANGUAGE, cb) },
} else if (libs[i][0] != ice.PS && libs[i].indexOf(ice.HTTP) != 0) { getHeaderHeight: function() { return can._root.Header? can._root.Header._target.offsetHeight: 0},
libs[i] = _can_path.slice(0, _can_path.lastIndexOf(ice.PS)+1)+libs[i] getFooterHeight: function() { return can._root.Footer? can._root.Footer._target.offsetHeight: 0},
} getHeader: function(key, cb) { return can.get(chat.HEADER, key, cb) },
} setHeader: function(key, value) { return can.set(chat.HEADER, key, value) },
} setAction: function(key, value) { return can.set(chat.ACTION, key, value) },
return can.require(libs, cb), can getAction: function(key, cb) { return can.get(chat.ACTION, key, cb) },
getActionSize: function(cb) { return can.get(chat.ACTION, nfs.SIZE, cb) },
getRiverWidth: function() { return can._root.River? can._root.River._target.offsetWidth: 0},
isPanelType: function() { return can.page.ClassList.has(can, can._fields||can._target, chat.PANEL) },
isPluginType: function() { return can.page.ClassList.has(can, can._fields||can._target, chat.PLUGIN) },
isStoryType: function() { return can.page.ClassList.has(can, can._fields||can._target, chat.STORY) },
isOutputStyle: function() { return can.page.ClassList.has(can, can._fields||can._target, chat.OUTPUT) },
isSimpleMode: function() { return can.Mode() == chat.SIMPLE },
isFloatMode: function() { return can.Mode() == chat.FLOAT },
isFullMode: function() { return can.Mode() == chat.FULL },
isZoneMode: function() { return can.Mode() == "zone" },
isCmdMode: function() { return can.Mode() == chat.CMD },
isAutoMode: function() { return can.Mode() == "" },
Mode: function(value) { return can.Conf(ice.MODE, value) },
ConfDefault: function(value) { can.core.Item(value, function(k, v) { can.Conf(k) || can.Conf(k, v) }) },
ConfSpace: function(space) { if (space) { can.Conf(web.SPACE, space) } return can.Conf("_space")||can.Conf(web.SPACE)||can.Conf("pod")||"" },
ConfIndex: function(index) { if (index) { can.Conf(ctx.INDEX, index) } return can.Conf("_command")||can.Conf(ctx.INDEX)||can.Conf("_index")||"can" },
ConfIcons: function() { return can.Conf(mdb.ICONS) },
ConfHeight: function(value) { return can.Conf(html.HEIGHT, value) },
ConfWidth: function(value) { return can.Conf(html.WIDTH, value)||can._output.offsetWidth },
ConfHelp: function() { return can.Conf("help") },
Conf: function(key, value) { var res = can._conf
for (var i = 0; i < arguments.length; i += 2) {
if (typeof key == code.OBJECT) { res = can.core.Value(can._conf, arguments[i]), i--; continue }
res = can.core.Value(can._conf, arguments[i], arguments[i+1])
} return can.base.isUndefined(res) && key.indexOf(ctx.FEATURE+nfs.PT) == -1? can.Conf(can.core.Keys(ctx.FEATURE, key)): res
}, _conf: {},
}, meta)); if (_can_name) { meta.cache[_can_name] = meta.cache[_can_name]||[], meta.cache[_can_name].push(can) } else { list.push(can) }
setTimeout(function() { can.require(can._follow? libs.concat(meta.libs, meta.frame): libs, cb) }, 1)
return can
}) })
Volcanos.meta._load = function(url, cb) { try { if (typeof(window) == code.OBJECT) { var meta = Volcanos.meta
switch (url.split("?")[0].split(ice.PT).pop().toLowerCase()) { try { var debug = location.search.indexOf("debug=true") > -1
case nfs.CSS: meta.version = window._version||"", window.parent.outerWidth-window.parent.innerWidth > 100 && (meta.version = "", debug = false)
var item = document.createElement(mdb.LINK) } catch (e) {
item.rel = "stylesheet", item.type = "text/css" meta.version = window._version, window.outerWidth-window.innerWidth > 100 && (meta.version = "", debug = false)
item.onload = cb, item.href = url }
return (document.head||document.body).appendChild(item), item meta._load = function(url, cb) {
case nfs.JS: if (meta.version && url.indexOf("/p/usr/icons/") == -1) { url += (url.indexOf(web.QS) == -1? web.QS: "&")+meta.version.slice(1) }
var item = document.createElement(ssh.SCRIPT) if (meta._cache[url]) { return meta._cache[url].push(cb) } else { meta._cache[url] = [cb] }
item.onload = cb, item.onerror = cb, item.src = url function _cb() { meta._cache[url].forEach(function(cb) { cb() }), delete(meta._cache[url]) }
return document.body.appendChild(item), item switch (url.split(web.QS)[0].split(nfs.PT).pop().toLowerCase()) {
} case nfs.CSS: var item = document.createElement(web.LINK); item.href = url, item.rel = "stylesheet", item.onload = _cb, document.head.appendChild(item); break
} default: var item = document.createElement(nfs.SCRIPT); item.src = url, item.onerror = _cb, item.onload = _cb, document.body.appendChild(item)
function can(tool) { }
Volcanos({name: "chat", panels: [ }
{name: "Header", help: "标题栏", pos: "hide", state: ["time", "usernick", "avatar"]}, document.ondrop = function(event) {
{name: "Action", help: "工作台", pos: chat.MAIN, tool: tool}, debugger
]}) }
} meta.target = document.body, meta._height = window.innerHeight, meta._width = window.innerWidth
meta._init = function(can) { var last = can.page.width() < can.page.height()
window.onresize = function(event) { can.misc.Event(event, can, function(msg) {
if (can.user.isMobile && last === can.page.width() < can.page.height()) { return } last = can.page.width() < can.page.height()
can.onmotion.delayOnce(can, function() { can.onengine.signal(can, chat.ONRESIZE, can.request(event, kit.Dict(html.HEIGHT, window.innerHeight, html.WIDTH, window.innerWidth))) }, 100, can._delay_resize = can._delay_resize||[])
}) }
window.onerror = function(message, source, lineno, colno, error) { debug? alert([message].concat(can.misc._stacks(0, error)).join(lex.NL)): can.misc.Error(message, lex.NL+[source, lineno, colno].join(ice.DF), error) }
window.onmousemove = function(event) { window._mousemove && (window._mousemove.onmousemove(event)) }
window.onmouseup = function(event) { window._mousemove && (window._mousemove.onmouseup(event)) }
window.onbeforeunload = function() { can.onengine.signal(can, chat.ONUNLOAD) }
}
} else { // nodejs
global.document = {}, global.location = {}, global.window = {}, global.navigator = {userAgent: "nodejs"}
global.kit = kit, global.ice = ice
global.ctx = ctx, global.mdb = mdb, global.web = web, global.aaa = aaa
global.lex = lex, global.yac = yac, global.ssh = ssh, global.gdb = gdb
global.tcp = tcp, global.nfs = nfs, global.cli = cli, global.log = log
global.code = code, global.wiki = wiki, global.chat = chat, global.team = team, global.mall = mall
global.http = http, global.html = html, global.icon = icon, global.svg = svg
global.shy = shy, global.Volcanos = Volcanos
} } catch (e) { console.log(e) }

View File

@ -1,9 +0,0 @@
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"></head>
<body>
<script src="/page/can.js"></script>
<script src="/publish/chrome/chrome.js"></script>
</body>
</html>

View File

@ -1,64 +0,0 @@
Volcanos({
chrome: function(can, msg, arg, cb) {
if (arg.length == 0 || arg[0] == "") { // 窗口列表
chrome.windows.getAll(function(wins) {
can.core.List(wins, function(win) { win.wid = win.id
msg.Push(win, ["wid", "state", html.LEFT, html.TOP, html.WIDTH, html.HEIGHT])
}), can.base.isFunc(cb) && cb(msg)
})
} else if (arg.length == 1 || arg[1] == "") { // 标签列表
chrome.tabs.getAllInWindow(parseInt(arg[0]), function(tabs) {
can.core.List(tabs, function(tab) { tab.tid = tab.id
msg.Push(tab, ["tid", "active", html.WIDTH, html.HEIGHT, "index", "title", "url"])
}), can.base.isFunc(cb) && cb(msg)
})
} else if (arg[1] == "current") { // 当前标签
chrome.tabs.query({currentWindow: true, active: true}, function(tabs) { arg[1] = tabs[0].id
chrome.tabs.sendMessage(parseInt(arg[1]), msg, function(res) {
can.base.isFunc(cb) && cb(msg.Copy(res))
})
})
} else { // 下发命令
chrome.tabs.sendMessage(parseInt(arg[1]), msg, function(res) {
can.base.isFunc(cb) && cb(msg.Copy(res))
})
}
},
_daemon: function(can) {
can.misc.WSS(can, {type: html.CHROME, name: html.CHROME}, function(event, msg, cmd, arg) {
if (msg.Option(ice.MSG_TARGET)) { msg.detail = ["", "", ""].concat(msg.detail)
chrome.tabs.sendMessage(parseInt(msg.Option(ice.MSG_TARGET)), msg, function(res) {
msg.Copy(res), msg.Reply()
})
return
}
can.core.CallFunc([can, cmd], {can: can, msg: msg, arg: arg, cb: function() { msg.Reply() }})
})
chrome.runtime.onMessage.addListener(function(req, sender, cb) {
var msg = can.request({}, {tid: sender.tab.id, url: sender.url})
can.core.List(req.option, function(key) { msg.Option(key, req[key][0]) })
msg.__daemon = can.core.Keys(html.CHROME, sender.tab.id)
can.run(msg._event, req.detail||[], cb)
return true
})
chrome.history.onVisited.addListener(function(item) {
can.run({}, ["sync", mdb.TYPE, "link", mdb.NAME, item.title, mdb.LINK, item.url, "tid", item.id])
})
},
_motion: function(can) {
can.user.toast = function(can, message, title) { chrome.notifications.create(null, {
message: message, title: title||can._name, iconUrl: "/favicon.ico", type: "basic",
})},
chrome.contextMenus.create({title: "volcanos", onclick: function(event) {
chrome.tabs.query({currentWindow: true, active: true}, function(tabs) {
var msg = can.request(event); msg.detail = [html.CHROME, "", "", "order"]
chrome.tabs.sendMessage(tabs[0].id, msg)
})
}})
},
}, function(can) {
can.run = function(event, cmds, cb) { var msg = can.request(event)
can.misc.Run(event, can, {names: "http://localhost:9020/code/chrome/"+cmds[0]}, cmds.slice(1), cb)
}, can._daemon(can), can._motion(can)
})

View File

@ -1,211 +1,110 @@
html, body {
--body-bg-color:white;
--body-fg-color:black;
--legend-bg-color:lightsteelblue;
--input-bg-color:white;
--input-fg-color:var(--body-fg-color);
--input-radius:5px;
--input-border:blue solid 1px;
--output-bg-color:var(--input-bg-color);
--status-border:transparent solid 1px;
--plugin-radius:10px;
--plugin-bg-color:aliceblue;
--plugin-fg-color:var(--body-fg-color);
--panel-output-bg-color:var(--body-bg-color);
--panel-output-fg-color:#d0d3da;
--panel-input-bg-color:#6b7488;
--panel-input-fg-color:white;
--panel-hover-bg-color:#2b3446;
--panel-hover-fg-color:white;
--panel-bg-color:var(--panel-output-bg-color);
--panel-fg-color:var(--panel-output-fg-color);
--float-fg-color:var(--plugin-fg-color);
--float-bg-color:var(--plugin-bg-color);
--carte-bg-color:var(--plugin-bg-color);
--hover-bg-color:var(--input-bg-color);
--hover-fg-color:var(--input-fg-color);
--th-fg-color:var(--plugin-fg-color);
--th-bg-color:var(--plugin-bg-color);
--td-hover-bg-color:var(--plugin-bg-color);
--tr-hover-bg-color:var(--plugin-bg-color);
}
@media (prefers-color-scheme: dark) {
html, body {
--body-bg-color:black;
--body-fg-color:silver;
--legend-bg-color:#212121;
--input-bg-color:#232526;
--input-fg-color:var(--body-fg-color);
--input-radius:5px;
--input-border:blue solid 1px;
--output-bg-color:var(--input-bg-color);
--status-border:gray solid 1px;
--plugin-radius:var(--input-radius);
--plugin-bg-color:var(--body-bg-color);
--plugin-fg-color:var(--body-fg-color);
--panel-output-bg-color:var(--body-bg-color);
--panel-output-fg-color:var(--body-fg-color);
--panel-bg-color:var(--panel-output-bg-color);
--panel-fg-color:var(--panel-output-fg-color);
--float-fg-color:var(--plugin-fg-color);
--float-bg-color:var(--plugin-bg-color);
--carte-bg-color:var(--plugin-bg-color);
--hover-bg-color:var(--input-bg-color);
--hover-fg-color:white;
--th-fg-color:var(--plugin-fg-color);
--th-bg-color:var(--plugin-bg-color);
--td-hover-bg-color:var(--plugin-bg-color);
--tr-hover-bg-color:var(--plugin-bg-color);
}
}
fieldset.contexts { fieldset.contexts {
color:white; background-color:var(--plugin-bg-color); color:var(--plugin-fg-color); border-radius:var(--plugin-radius);
position:fixed; padding:0; border:0; margin:0; position:fixed; top:400px; left:400px; z-index:100;
background:radial-gradient(black, #00000073);
top:100px;
left:100px;
z-index:10;
} }
fieldset.contexts legend { fieldset.contexts * { padding:0; border:0; margin:0; }
text-align:left; fieldset.contexts legend { font-size:1.2rem; line-height:30px; padding:0 10px; height:32px; float:left; }
cursor:pointer; fieldset.contexts select.hide { display:none; }
fieldset.contexts input { background-color:var(--input-bg-color); color:var(--input-fg-color); font-size:1rem; padding:0 20px; height:32px; min-width:80px; outline:none; }
fieldset.contexts form.option>div.item { float:left; margin-right:10px; height:32px; }
fieldset.contexts div.action>div.item { float:left; margin-right:10px; height:32px; }
fieldset.contexts div.status>div.item { float:left; padding:5px; height:31px; }
fieldset.contexts div.status>div.item>label { font-size:0.6rem; }
fieldset.contexts div.output { background-color:var(--output-bg-color); overflow:auto; clear:both; }
fieldset.auto, fieldset.full, fieldset.float, body>div.float { position:fixed; z-index:100; }
background:radial-gradient(black, #00000073); body>div.carte { padding:0; }
} body>div.carte input[name=filter] { margin:5px; width:calc(100% - 10px); position:sticky; top:5px; }
fieldset.contexts form.option div.item { body>div.carte div.item { white-space:pre; padding:5px 10px; }
float:left; margin-right:3px; body>div.carte div.item span.icon.next { float:right; }
min-height:25px; vertical-align:middle; body>div.carte div.item { background-color:var(--carte-bg-color); }
} body>div.carte div.item:hover { background-color:var(--hover-bg-color); }
fieldset.contexts div.output {
clear:both;
overflow:auto;
}
fieldset.contexts div.status div.item {
float:left; padding:4px;
height:18px;
}
fieldset.contexts div.status div.item>label {
font-size:10px;
/* color:#504242e0; */
}
fieldset.contexts select { /* icon */
height:25px; font-size:14px; fieldset.contexts form.option>div.icon { background-color:unset; font-size:26px; line-height:28px; padding:0 5px; height:32px; margin:0; }
box-shadow: 4px 4px 10px 1px #626bd0; fieldset.contexts form.option>div.item.icons>span.icon { font-size:26px; line-height:28px; padding:0 5px; height:32px; }
background-color:black; color:cyan; fieldset.contexts form.option>div.item.icons>span.icon.create { line-height:30px; }
padding:0 10px; fieldset.contexts div.action>div.item.icons>span.icon { font-size:26px; line-height:28px; padding:0 5px; height:32px; }
cursor:pointer; fieldset.contexts div.action>div.item.icons>span.icon.create { line-height:30px; }
} fieldset.contexts form.option>div.icon:first-child { margin-left:-5px; }
fieldset.contexts option { fieldset.contexts form.option>div.icon.refresh { line-height:26px; }
font-family:monospace; fieldset.contexts form.option>div.icon.goback { line-height:26px; }
} fieldset.contexts form.option>div.icon.delete { font-size:18px; margin-left:5px; margin-right:0px; }
fieldset.contexts textarea { fieldset.contexts form.option>div.icon.next { font-size:18px; }
width:400px; height:60px; fieldset.contexts form.option>div.icon.prev { font-size:18px; }
background-color:cyan; fieldset.contexts form.option>div.item.text>span.icon { margin-left:-20px; margin-right:3px; }
} fieldset.contexts form.option>div.item.select>span.icon { margin-left:-15px; margin-right:3px; visibility:hidden; }
fieldset.contexts input[type=button] { fieldset.contexts form.option>div.item.select:hover>span.icon { visibility:visible; }
background-color:black; color:cyan; fieldset.contexts div.item.text>span.icon.delete { font-size:20px; visibility:hidden; }
letter-spacing:4px; fieldset.contexts div.item.text:hover>span.icon.delete { visibility:visible; }
padding-left:10px; fieldset.contexts form.option>div.button.icons { display:none; }
cursor:pointer; fieldset.contexts div.action>div.button.icons { display:none; }
font-family:monospace;
}
fieldset.contexts input[type=button]:hover {
background-color:gray; color:cyan;
}
fieldset.contexts input[type=text] {
width:82px; height:21px; font-size:16px;
box-shadow:4px 4px 10px 1px #626bd0;
background-color:cyan; color:black;
padding:0 4px;
}
fieldset.contexts input[type=text]:hover {
background-color:white;
}
fieldset.contexts table.content a {
color:white;
}
fieldset.contexts table.content {
color:white;
}
fieldset.contexts div.code {
background-color:#343a3445; color:white;
font-size:14px; font-family:monospace;
box-shadow: 4px 4px 20px 4px #626bd0;
padding:10px; border:solid 3px green;
text-align:left; white-space:pre;
overflow:auto;
clear:both;
}
div.input.contexts input {
color:black;
}
table.content {
border:0; white-space:pre;
font-size:14px; font-family:monospace;
text-align:left;
overflow: auto;
}
table.content tr {
background-color:#04272f45;
}
table.content tr.select {
background-color:green;
}
table.content tr:hover {
background-color:green;
}
table.content th {
background-color:#0fbd45;
padding:2px 6px;
cursor:pointer;
}
table.content th:hover {
background-color:red;
}
table.content td {
padding:2px 6px;
overflow:auto;
}
table.content td.done {
background-color:green;
}
table.content td.select {
background-color:red;
}
table.content td:hover {
background-color:red;
}
body>div.toast {
background:#0e3369b3; color:yellow;
position:fixed;
padding:5px; overflow:auto;
z-index:10;
}
body>div.toast a {
color:yellow;
}
body>div.toast div.title {
float:left; word-break:break-all;
color:#cae850; font-size:14px;
cursor:copy;
}
body>div.toast div.duration {
color:gray; font-size:14px;
float:right;
cursor:pointer;
}
body>div.toast div.content {
text-align:center;
white-space:pre;
clear:both;
}
body>div.toast div.action div.item {
float:left;
}
body>div.toast div.progress {
height:10px; border:solid 2px green;
margin-left:-2px;
clear:both;
}
body>div.toast div.progress div.current {
height:10px; background:red;
}
body>div.carte {
position:fixed;
background:#295b61;
color:white;
padding:4px;
min-width:80px;
z-index:10;
}
body>div.carte div.item {
padding:3px 12px;
}
body>div.carte div.item:hover {
background:red;
}
body>div.input {
position:fixed;
background-color:#0d4142a6;
z-index:10;
}
body>div.input input[type=text] {
width:171px;
}
body>div.input input[name=username] {
width:171px;
}
body>div.input input[name=password] {
width:171px;
}
body>div.input textarea {
box-shadow: 4px 4px 10px 1px #626bd0;
border:2px inset #14a58e;
width:171px; height:60px;
background-color: cyan;
padding:4px;
}
body>div.input div.item {
float:left;
}
body>div.input.login {
padding:10px;
}
body>div.input.login input {
font-size:18px;
}
div.input input[type=button] {
background-color:black; color:cyan;
letter-spacing:4px;
padding-left:10px;
cursor:pointer;
font-family:monospace;
}
div.input input[type=button]:hover {
background-color:gray; color:cyan;
}

View File

@ -1,119 +1,112 @@
setTimeout(function() { Volcanos({Option: function() { return [] }, setTimeout(function() { Volcanos({
spide: function(can, msg, _target) { Option: function() { return [] },
if (!_target) { spide: function(can, msg, target) {
msg.Push(mdb.TYPE, mdb.LINK) if (!target) {
msg.Push(mdb.TYPE, web.LINK)
msg.Push(mdb.NAME, document.title) msg.Push(mdb.NAME, document.title)
msg.Push(mdb.LINK, location.href) msg.Push(web.LINK, location.href)
} }
var has = {}; target = target||document.body
var has = {}; _target = _target||document.body can.page.Select(can, target, html.AUDIO, function(target) {
can.page.Select(can, _target, html.IFRAME, function(item) { if (!target.src || has[target.src]) { return } has[target.src] = true
if (!item.src || has[item.src]) { return } has[item.src] = true var name = target.src.split("?")[0].split(nfs.PT).pop()
msg.Push(mdb.TYPE, html.AUDIO)
msg.Push(mdb.TYPE, html.IFRAME) msg.Push(mdb.NAME, html.AUDIO+nfs.PT+name)
msg.Push(mdb.NAME, "") msg.Push(web.LINK, target.src)
msg.Push(mdb.LINK, item.src)
can.spide(can, msg, item.contentWindow.document.body)
}) })
can.page.Select(can, _target, html.VIDEO, function(item) { can.page.Select(can, target, html.VIDEO, function(target) {
if (!item.src || has[item.src]) { return } has[item.src] = true if (!target.src || has[target.src]) { return } has[target.src] = true
var name = item.src.split("?")[0].split(ice.PT).pop() var name = target.src.split("?")[0].split(nfs.PT).pop()
var p = can.page.Select(can, _target, "p.title")[0]
msg.Push(mdb.TYPE, html.VIDEO) msg.Push(mdb.TYPE, html.VIDEO)
msg.Push(mdb.NAME, (p && p.innerText || html.VIDEO)+ice.PT+name) msg.Push(mdb.NAME, html.VIDEO+nfs.PT+name)
msg.Push(mdb.LINK, item.src) msg.Push(web.LINK, target.src)
}) })
can.page.Select(can, target, html.IMG, function(target) {
can.page.Select(can, _target, html.IMG, function(item) { if (!target.src || has[target.src]) { return } has[target.src] = true
if (!item.src || has[item.src]) { return } has[item.src] = true var name = target.src.split("?")[0].split(nfs.PS).pop()
var name = item.src.split("?")[0].split(ice.PS).pop()
msg.Push(mdb.TYPE, html.IMG) msg.Push(mdb.TYPE, html.IMG)
if (item.src.indexOf("data:image") == 0) { if (target.src.indexOf("data:image") == 0) {
msg.Push(mdb.NAME, item.src.slice(item.src.length-20)) msg.Push(mdb.NAME, target.src.slice(target.src.length-20))
} else { } else {
msg.Push(mdb.NAME, name||"image.jpg") msg.Push(mdb.NAME, name||"image.jpg")
} }
msg.Push(mdb.LINK, item.src) msg.Push(web.LINK, target.src)
}) })
}, can.page.Select(can, target, html.IFRAME, function(target) {
change: function(can, msg, arg) { if (!target.src || has[target.src]) { return } has[target.src] = true
arg.length > 1 && can.page.Modify(can, arg[0], can.base.Obj(arg[1])) msg.Push(mdb.TYPE, html.IFRAME)
arg.length > 0 && can.page.Select(can, document.body, arg[0], function(item) { msg.Push(mdb.NAME, "")
msg.Push(mdb.TEXT, item.outerHTML) msg.Push(web.LINK, target.src)
try {
can.spide(can, msg, target.contentWindow.document.body)
} catch(e) {
}
})
can.page.Select(can, target, html.A, function(target) {
msg.Push(mdb.TYPE, html.A)
msg.Push(mdb.NAME, "")
msg.Push(web.LINK, target.href)
}) })
},
order: function(can, msg, arg) {
var ui = can.user.input(event, can, [ctx.INDEX, ctx.ARGS, "selection", html.LEFT, html.TOP], function(event, button, data, list, args) {
can.run(event, [chat.FIELD, mdb.INSERT, mdb.ZONE, location.host].concat(args), function(res) {
can.user.toastSuccess(can)
})
}); can.page.Modify(can, ui._target, {style: {left: 200, top: 200}})
can.page.ClassList.add(can, ui._target, chat.CONTEXTS)
},
field: function(can, msg, arg) {
can.onappend.plugin(can, {type: chat.CONTEXTS, index: arg[0], args: can.base.Obj(arg[1])}, function(sub, meta) {
var pos = {left: msg.Option(chat.LEFT), top: msg.Option(chat.TOP), right: msg.Option(chat.RIGHT), bottom: msg.Option(chat.BOTTOM)}
can.page.Modify(can, sub._target, {style: pos})
can.onmotion.move(can, sub._target, pos, function(target) {
can.page.Modify(can, sub._output, {style: {
"max-height": window.innerHeight-target.offsetTop-80,
"max-width": window.innerWidth-target.offsetLeft-20,
}})
})
sub._legend.onclick = function(event) {
can.onmotion.toggle(can, sub._option)
can.onmotion.toggle(can, sub._action)
can.onmotion.toggle(can, sub._output)
can.onmotion.toggle(can, sub._status)
}, msg.Option("selection")||sub._legend.onclick()
sub.run = function(event, cmds, cb) { if (msg.RunAction(event, can, cmds)) { return }
can.run(event, can.misc.concat([ctx.ACTION, ice.RUN, meta.index], cmds), cb)
}
msg.Option("selection") && (can.onengine.listen(can, "onselection", function() {
sub.Option(msg.Option("selection"), window.getSelection()), sub.Update()
}))
sub.onaction["保存参数"] = function(event) {
can.request(event, {zone: location.host, id: msg.Option(mdb.ID)})
can.run(event, [chat.FIELD, mdb.MODIFY, chat.TOP, sub._target.offsetTop])
can.run(event, [chat.FIELD, mdb.MODIFY, chat.LEFT, sub._target.offsetLeft])
can.run(event, [chat.FIELD, mdb.MODIFY, "args", JSON.stringify(sub.Input([], true))])
can.user.toastSuccess(can)
}
}, document.body)
}, },
style: function(can, msg, arg) { style: function(can, msg, arg) {
can.core.List(arg[0].split(ice.FS), function(item) { if (arg[0] == "style") {
can.page.Select(can, document.body, item, function(target) { can.page.AppendStyle(can, arg[1])
can.page.Modify(can, target, can.base.Obj(arg[1])) } else {
}) can.core.List(arg[0].split(mdb.FS), function(item) {
}) can.page.Select(can, document.body, item, function(target) {
can.page.Modify(can, target, can.base.Obj(arg[1]))
})
})
}
},
field: function(can, msg, arg) { can.onappend.plugin(can, {type: chat.CONTEXTS, index: arg[0], args: can.base.Obj(arg[1])}, function(sub, meta) {
var height = can.base.Max(window.innerHeight-sub._target.offsetTop-2*html.ACTION_HEIGHT, 160), width = can.base.Max(window.innerWidth-sub._target.offsetLeft, 600)
sub.Conf({height: height, width: width}), sub._legend.innerText = meta.help
sub.run = function(event, cmds, cb) { msg.RunAction(event, can, cmds) || can.runActionCommand(event, meta.index, cmds, function(msg) {
can.onmotion.toggle(can, sub._option, true), can.onmotion.toggle(can, sub._action, true), can.onmotion.toggle(can, sub._output, true), can.onmotion.toggle(can, sub._status, true)
can.onimport.size(sub, height, width, true), can.base.isFunc(cb) && cb(msg)
}) }
can.onmotion.move(can, sub._target, {left: msg.Option(html.LEFT)||window.innerWidth-width, top: msg.Option(html.TOP)||window.innerHeight-height-2*html.ACTION_HEIGHT, right: msg.Option(html.RIGHT), bottom: msg.Option(html.BOTTOM)})
sub._target.onclick = function() { can.page.Select(can, document.body, can.page.Keys("div.carte.float"), function(target) { can.page.Remove(can, target) }) }
// sub._legend.onclick = function(event) { can.onmotion.toggle(can, sub._option), can.onmotion.toggle(can, sub._action), can.onmotion.toggle(can, sub._output), can.onmotion.toggle(can, sub._status) }
msg.Option("selection") && can.onengine.listen(can, "onselection", function() { sub.Option(msg.Option("selection"), window.getSelection()), sub.Update() })
sub.onaction["保存参数"] = function(event) { can.run(can.request(event, {domain: location.host, id: msg.Option(mdb.ID)}), [chat.FIELD, mdb.MODIFY, html.TOP, sub._target.offsetTop, html.LEFT, sub._target.offsetLeft, ctx.ARGS, JSON.stringify(sub.Input([], true))]) }
}, document.body) },
order: function(can, msg, arg) {
var ui = can.user.input(event, can, [ctx.INDEX, ctx.ARGS, "selection", html.LEFT, html.TOP], function(args) {
can.run(event, [chat.FIELD, mdb.INSERT, web.DOMAIN, location.host].concat(args), function(res) { can.user.toastSuccess(can) })
}); can.page.style(can, ui._target, {left: 200, top: 200})
can.page.ClassList.add(can, ui._target, chat.CONTEXTS)
}, },
info: function(can, msg, arg) {
msg.Push("title", document.title)
msg.Push("url", location.href)
},
_daemon: function(can) { _daemon: function(can) {
chrome.extension.onMessage.addListener(function(req, sender, cb) { var msg = can.request(); msg.Copy(req); can.misc.Log(req.detail, msg) chrome.extension.onMessage.addListener(function(req, sender, cb) { var msg = can.request(); msg.Copy(req); can.misc.Log(req.detail, msg)
can.core.CallFunc([can, req.detail[3]||"spide"], {can: can, msg: msg, cmds: req.detail.slice(4), arg: req.detail.slice(4), cb: function() { can.core.CallFunc([can, req.detail[0]||"spide"], {can: can, msg: msg, cmds: req.detail.slice(1), arg: req.detail.slice(1), cb: function() {
delete(msg._event), delete(msg._can), cb(msg) delete(msg._event), delete(msg._can), cb(msg)
}}) }})
}) })
}, },
_motion: function(can) { can.onmotion.float.auto(can, document.body) _motion: function(can) { can.onmotion.story.auto(can, document.body)
document.body.ondblclick = function(event) { can.onengine.signal(can, "onselection") } document.body.ondblclick = function(event) { can.onengine.signal(can, "onselection") }
can.runAction({}, ctx.COMMAND, [], function(msg) { msg.result && msg.result[0] && can.field(can, msg, msg.result) })
can.run({}, [ctx.ACTION, ctx.COMMAND], function(msg) { },
msg.result && msg.result[0] && can.field(can, msg, msg.result)
})
},
}, function(can) { }, function(can) {
can.page.theme(function(theme) {
if (theme == html.LIGHT) {
can.page.ClassList.add(can, document.body, html.LIGHT)
can.page.ClassList.del(can, document.body, html.DARK)
} else {
can.page.ClassList.add(can, document.body, html.DARK)
can.page.ClassList.del(can, document.body, html.LIGHT)
}
})
can.run = function(event, cmds, cb) { if (cmds[0] == "_search") { return } can.run = function(event, cmds, cb) { if (cmds[0] == "_search") { return }
var msg = can.request(event, {host: location.host}); msg.detail = can.misc.concat(["page"], cmds) var msg = can.request(event, {domain: location.host}); msg.detail = ["page"].concat(cmds)
chrome.runtime.sendMessage(msg, function(res) { can.base.isFunc(cb) && cb(msg.Copy(res)) }) chrome.runtime.sendMessage(msg, function(res) { can.base.isFunc(cb) && cb(msg.Copy(res)) })
}, can._daemon(can), can._motion(can) }, can._motion(can), can._daemon(can)
}) }, 1) }) }, 100)

View File

@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"></head>
<body>
<script src="/proto.js"></script>
<script src="/page/cache.js"></script>
<script src="/publish/chrome/daemon.js"></script>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show More