mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Compare commits
556 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d4d9190919 | ||
|
|
4d3d1a02a8 | ||
|
|
30c2aa96d6 | ||
|
|
4edb1f80b0 | ||
|
|
0a82459233 | ||
|
|
db87b0dfa5 | ||
|
|
cd42cf7583 | ||
|
|
2d5980ff2a | ||
|
|
d49c7a3adb | ||
|
|
4fdd09a262 | ||
|
|
d6878512c4 | ||
|
|
8b1b8250ff | ||
|
|
9dccbf747e | ||
|
|
08727e1938 | ||
|
|
7584820987 | ||
|
|
d572356642 | ||
|
|
3b5a2815a9 | ||
|
|
f3cf01df25 | ||
|
|
63e6e64ad3 | ||
|
|
e8d7b48bff | ||
|
|
12944d1ebd | ||
|
|
fa1ff6e393 | ||
|
|
98546b6e6a | ||
|
|
2fef6fd1fa | ||
|
|
20cf91f1dc | ||
|
|
2efa78d590 | ||
|
|
880af0671a | ||
|
|
62471e4531 | ||
|
|
b15f8535f8 | ||
|
|
7a3a4493da | ||
|
|
11078235c4 | ||
|
|
f3e05cd08a | ||
|
|
0ca3cabbe8 | ||
|
|
44a75c1291 | ||
|
|
4a4513a746 | ||
|
|
60ff8660de | ||
|
|
6fa0d671c0 | ||
|
|
f478d7c9f0 | ||
|
|
53e3e08d70 | ||
|
|
c4d1ccb6f5 | ||
|
|
e3520309fc | ||
|
|
27bf72372e | ||
|
|
ae4b1b17a9 | ||
|
|
94cb03f4b5 | ||
|
|
e691351976 | ||
|
|
3190de873e | ||
|
|
e8a637498d | ||
|
|
e1195ac00a | ||
|
|
6cd9ccc37c | ||
|
|
25345302e8 | ||
|
|
eccd5e9801 | ||
|
|
ff355af9f2 | ||
|
|
5967f4b0d4 | ||
|
|
ff18618032 | ||
|
|
20f03c356c | ||
|
|
27fdc9e56e | ||
|
|
52d9578a19 | ||
|
|
f4c2938b41 | ||
|
|
9f703de5ec | ||
|
|
a327fd85e2 | ||
|
|
9d22a86ec8 | ||
|
|
29e0b194dd | ||
|
|
ae9cf13fc2 | ||
|
|
64ae67586a | ||
|
|
838c7a5e89 | ||
|
|
89bfc90f40 | ||
|
|
acad9f57f9 | ||
|
|
0d08dc410e | ||
|
|
ebb3fb96cd | ||
|
|
f31f23ff07 | ||
|
|
d2aa3d1868 | ||
|
|
c9e2fce94d | ||
|
|
8b0e76dd55 | ||
|
|
884618adfe | ||
|
|
98f7271ac8 | ||
|
|
087cd121b8 | ||
|
|
2d52527fb4 | ||
|
|
fe289e62b5 | ||
|
|
2845475e3f | ||
|
|
b307492487 | ||
|
|
d48284f7ea | ||
|
|
7e416797e9 | ||
|
|
5d54ca7477 | ||
|
|
b979b4e61a | ||
|
|
2527f7984a | ||
|
|
d9350b2362 | ||
|
|
bd0b903f1a | ||
|
|
f243c0df19 | ||
|
|
7482978953 | ||
|
|
77966689d4 | ||
|
|
cf43939d65 | ||
|
|
391ac4b351 | ||
|
|
e1e48aadd9 | ||
|
|
0681f206c4 | ||
|
|
d257c6f3d3 | ||
|
|
fa45c82cdc | ||
|
|
e805b58da6 | ||
|
|
943976d207 | ||
|
|
3a2e5a6ccd | ||
|
|
35ef036246 | ||
|
|
e09c3bbdd3 | ||
|
|
3b12076d4b | ||
|
|
cfcf78ae28 | ||
|
|
341ff9bf5c | ||
|
|
10d8ca30b0 | ||
|
|
4ebb5d099e | ||
|
|
1e82b66bf0 | ||
|
|
06a5e4273b | ||
|
|
e123e7b0b0 | ||
|
|
aeadc40c65 | ||
|
|
7ef418ec52 | ||
|
|
2ed52820b6 | ||
|
|
e8fd7484b6 | ||
|
|
ce5242cfe8 | ||
|
|
af947879d8 | ||
|
|
3ed112cde6 | ||
|
|
99c6a9eccd | ||
|
|
2029f6ea0a | ||
|
|
e984e1f30f | ||
|
|
f21260370f | ||
|
|
fdae75c99b | ||
|
|
a0489f2a0d | ||
|
|
0123eacbdb | ||
|
|
53401b6aa7 | ||
|
|
9a5139f452 | ||
|
|
2ee0c8c228 | ||
|
|
c53562cc9c | ||
|
|
ec5d7c2e5c | ||
|
|
d6fc258485 | ||
|
|
f953612695 | ||
|
|
2ab93acca8 | ||
|
|
326c6c496e | ||
|
|
9f7f50664c | ||
|
|
f6f1436123 | ||
|
|
c3c519419d | ||
|
|
e569a80b72 | ||
|
|
284f437c1a | ||
|
|
1fd44a9958 | ||
|
|
cad34742f6 | ||
|
|
323359b3c8 | ||
|
|
35db8b45f0 | ||
|
|
50ae815ceb | ||
|
|
1a4389c90d | ||
|
|
fdaa5ce1da | ||
|
|
09d9936aed | ||
|
|
b3f6109b1c | ||
|
|
5fb3ffc240 | ||
|
|
360db252bb | ||
|
|
0b6e290271 | ||
|
|
7f0174e6db | ||
|
|
a25dad6c2e | ||
|
|
6191a49ed3 | ||
|
|
6252b075bc | ||
|
|
7face138fd | ||
|
|
382b83b093 | ||
|
|
691687d1bc | ||
|
|
5814b80a72 | ||
|
|
e147fbb1fa | ||
|
|
b9e256adfa | ||
|
|
3b7bf04e22 | ||
|
|
43408a724c | ||
|
|
5fbd5bf9e2 | ||
|
|
5e87828b29 | ||
|
|
9066cedc29 | ||
|
|
aa1cf0b228 | ||
|
|
06a6a4408f | ||
|
|
d5619d2b9d | ||
|
|
2f6ac42efe | ||
|
|
0bba3dd83d | ||
|
|
abe60b62e6 | ||
|
|
555b7df986 | ||
|
|
b3786700e6 | ||
|
|
ce9643d21b | ||
|
|
4a5cb7f2f5 | ||
|
|
42a7e902e6 | ||
|
|
aebe080e85 | ||
|
|
c316284924 | ||
|
|
8d98b228ab | ||
|
|
5b4c42ff05 | ||
|
|
a596a4551a | ||
|
|
0968f96982 | ||
|
|
5931e13b9c | ||
|
|
415c768ae4 | ||
|
|
b4c8bf21d5 | ||
|
|
5fe5db603d | ||
|
|
9f7dd7f5d4 | ||
|
|
e6d32aab7b | ||
|
|
08bd6d963c | ||
|
|
ff05fb14a6 | ||
|
|
22d942b705 | ||
|
|
0526372f28 | ||
|
|
f99051906a | ||
|
|
d1f7fd8bfd | ||
|
|
fc1436a96d | ||
|
|
d21568497b | ||
|
|
df4beef060 | ||
|
|
a52f195d41 | ||
|
|
419019a656 | ||
|
|
42b5635485 | ||
|
|
a8fc5b01f3 | ||
|
|
ead841d844 | ||
|
|
67d7930aef | ||
|
|
6f69995f4e | ||
|
|
05252fa239 | ||
|
|
1377439bb0 | ||
|
|
407123a280 | ||
|
|
750dd590c8 | ||
|
|
44112a9d18 | ||
|
|
b220bf0d99 | ||
|
|
d0d93d7070 | ||
|
|
4117961236 | ||
|
|
68a3d71ee6 | ||
|
|
bf5d741f0d | ||
|
|
55a33bc408 | ||
|
|
3ec35ed119 | ||
|
|
3d8d6953ec | ||
|
|
528db67c34 | ||
|
|
b847e962aa | ||
|
|
bbb9a3c63b | ||
|
|
322cebc48c | ||
|
|
1cceb3d880 | ||
|
|
effc64db9a | ||
|
|
7e5bd5f2c1 | ||
|
|
e32cc4d1af | ||
|
|
09a3cd850e | ||
|
|
b0c876019a | ||
|
|
6725f870d2 | ||
|
|
0e5adc1f0a | ||
|
|
57ebb93dc0 | ||
|
|
05dc0bfa1d | ||
|
|
2d0264116c | ||
|
|
3938550ea8 | ||
|
|
9f0c567794 | ||
|
|
8672fcd2bb | ||
|
|
3f2a92e801 | ||
|
|
771e43583a | ||
|
|
9353d5c1c4 | ||
|
|
5e462f0f02 | ||
|
|
a25f6fec9f | ||
|
|
519edce0ed | ||
|
|
0bc7702d95 | ||
|
|
18be0d6d26 | ||
|
|
1d4a435f20 | ||
|
|
34e46fc6d3 | ||
|
|
50956c51f7 | ||
|
|
dd7bb28b6a | ||
|
|
8516f41ba8 | ||
|
|
15c3cc60f6 | ||
|
|
716bca211b | ||
|
|
8179813fe1 | ||
|
|
d355de509b | ||
|
|
b04a2d4c08 | ||
|
|
6d3232a4f0 | ||
|
|
2753075180 | ||
|
|
d0166b25e4 | ||
|
|
73ee657d74 | ||
|
|
45913e5ee8 | ||
|
|
e6369820a9 | ||
|
|
22a5b339f7 | ||
|
|
2cea3b6435 | ||
|
|
5d2d06fb3e | ||
|
|
0dd7bc7fb9 | ||
|
|
0b0005337c | ||
|
|
d26fb02bb9 | ||
|
|
af683835d9 | ||
|
|
c43647ca86 | ||
|
|
6d02e70025 | ||
|
|
5498c6f87d | ||
|
|
11f59bc3ac | ||
|
|
94cb7de79f | ||
|
|
838f45775b | ||
|
|
1c1422e4b5 | ||
|
|
cd8ca6fc62 | ||
|
|
b7a0a9d7c2 | ||
|
|
7822ab113a | ||
|
|
e250a91f09 | ||
|
|
92a65dcda5 | ||
|
|
4b129d94e4 | ||
|
|
e7960d1d44 | ||
|
|
95589307cd | ||
|
|
20a0e4f3e0 | ||
|
|
6a9213da64 | ||
|
|
7a89e3cf33 | ||
|
|
64607df929 | ||
|
|
a62a1012fa | ||
|
|
14efd0b2f9 | ||
|
|
7ad2192df8 | ||
|
|
3cb5cbd8d5 | ||
|
|
cc9011cd68 | ||
|
|
dc3d89008d | ||
|
|
1893642187 | ||
|
|
a9ece5772d | ||
|
|
cf34716a57 | ||
|
|
1337831061 | ||
|
|
757e72100d | ||
|
|
a75b819858 | ||
|
|
da4a0f09ed | ||
|
|
87d847a074 | ||
|
|
84711beec0 | ||
|
|
f3cf58c8ff | ||
|
|
cf40497e6e | ||
|
|
dfebc4b78d | ||
|
|
15f41a2e7c | ||
|
|
ad6e55ca17 | ||
|
|
6b466d217a | ||
|
|
00dcb304c7 | ||
|
|
c6fb3d6f41 | ||
|
|
ac3143811f | ||
|
|
7e27dd7678 | ||
|
|
c2508296a5 | ||
|
|
a9b50ce6fc | ||
|
|
eac98a6d4d | ||
|
|
7e2b2a9a02 | ||
|
|
353de471eb | ||
|
|
85fc20b52d | ||
|
|
cc25a781f8 | ||
|
|
fc3012ba72 | ||
|
|
d93a92c1c8 | ||
|
|
f7f795f58a | ||
|
|
2700f8cdd2 | ||
|
|
6310de0d20 | ||
|
|
218794be77 | ||
|
|
af71ae649b | ||
|
|
9bc72c1a06 | ||
|
|
8d7c157751 | ||
|
|
558a66fbe5 | ||
|
|
f95b414d22 | ||
|
|
e793a1e1aa | ||
|
|
b76010cb5a | ||
|
|
52475df783 | ||
|
|
1f3f32d377 | ||
|
|
3f5ba10354 | ||
|
|
25f4a018d9 | ||
|
|
a11a279c00 | ||
|
|
fd4fdb31b5 | ||
|
|
1921796d6d | ||
|
|
543a2b9dc7 | ||
|
|
dd23e03342 | ||
|
|
5307c74f85 | ||
|
|
d701c406e2 | ||
|
|
3ba56a0a65 | ||
|
|
4adafb6d1e | ||
|
|
4453a51211 | ||
|
|
14429d2943 | ||
|
|
1a62a7831b | ||
|
|
242e35c212 | ||
|
|
ea763fdfd5 | ||
|
|
e762b7ff48 | ||
|
|
298068b2b9 | ||
|
|
cb4120ec4b | ||
|
|
5cfbb87bee | ||
|
|
9e472ed83c | ||
|
|
ebca753fc4 | ||
|
|
548f45cd56 | ||
|
|
8ffabf1813 | ||
|
|
1f40d4f941 | ||
|
|
41582045d0 | ||
|
|
fd9e3fc03a | ||
|
|
8c42b2bdb4 | ||
|
|
7b1787fdbb | ||
|
|
71fee0025d | ||
|
|
1204cf1ba0 | ||
|
|
7bd8d8c3ae | ||
|
|
2c4d5fa38d | ||
|
|
bedb2d943e | ||
|
|
a3640bd9bf | ||
|
|
7c0b9ffe06 | ||
|
|
161c7d30ca | ||
|
|
4ff6e792cd | ||
|
|
af5df890a5 | ||
|
|
9ba011003a | ||
|
|
bb168d35a8 | ||
|
|
3306d30094 | ||
|
|
6516e0dfd2 | ||
|
|
00a396014b | ||
|
|
13356047dc | ||
|
|
8a6488b067 | ||
|
|
1c2ea56f42 | ||
|
|
1d7ae300e2 | ||
|
|
6013e186ed | ||
|
|
207d3d3340 | ||
|
|
5a6cde1446 | ||
|
|
63f7d826bc | ||
|
|
ff8773f6bd | ||
|
|
a868cb97d9 | ||
|
|
915d73e6f2 | ||
|
|
5f4f6e37b5 | ||
|
|
9c350311e8 | ||
|
|
3c6ba72a2a | ||
|
|
816442f5f0 | ||
|
|
3b51d18ce7 | ||
|
|
6696b6661a | ||
|
|
8c87478636 | ||
|
|
d870b072d7 | ||
|
|
2ea2af7d2a | ||
|
|
f737ea96f3 | ||
|
|
05f90394db | ||
|
|
c24b0c6bb4 | ||
|
|
e07a4dc7ba | ||
|
|
fc6748a46b | ||
|
|
7697c46652 | ||
|
|
ed52e5afd1 | ||
|
|
33a5b84181 | ||
|
|
c09a407f4c | ||
|
|
d35784ec61 | ||
|
|
53e012f296 | ||
|
|
2a9d0a5e7d | ||
|
|
474f4572f2 | ||
|
|
bf57cb209f | ||
|
|
9bc41c1709 | ||
|
|
fe10b8650f | ||
|
|
3a311c9584 | ||
|
|
d1106f53e0 | ||
|
|
a3a1bba5ef | ||
|
|
028d66befc | ||
|
|
bb59cd5742 | ||
|
|
604e3068b2 | ||
|
|
27f1d3b704 | ||
|
|
d007623347 | ||
|
|
6a5cf7a1fa | ||
|
|
3adfe249b0 | ||
|
|
923893e160 | ||
|
|
256e5360d4 | ||
|
|
304c597a2f | ||
|
|
f86d3a69d2 | ||
|
|
d7c8adfd82 | ||
|
|
55cd069043 | ||
|
|
3ca0e9c420 | ||
|
|
1dd4323613 | ||
|
|
d78916f85f | ||
|
|
1840d15397 | ||
|
|
b98d1216b1 | ||
|
|
27db727321 | ||
|
|
3f6b1f6ccb | ||
|
|
6d633b372a | ||
|
|
91352e855a | ||
|
|
8bb9b594cf | ||
|
|
6d2fd2e641 | ||
|
|
422fbcb0b7 | ||
|
|
afce106186 | ||
|
|
f21c8154ed | ||
|
|
3988a648d6 | ||
|
|
1b632894d3 | ||
|
|
5e128f89f6 | ||
|
|
fff0b15ae5 | ||
|
|
a7e14f1093 | ||
|
|
94eeaeb8d3 | ||
|
|
64191e8303 | ||
|
|
21cfb71617 | ||
|
|
806457063f | ||
|
|
b9213b73bd | ||
|
|
d7f0102aa2 | ||
|
|
f09e61a59a | ||
|
|
d426aaa88a | ||
|
|
19e45389e1 | ||
|
|
6d2389945b | ||
|
|
14c48253f6 | ||
|
|
e5ff25b92d | ||
|
|
5c88888e02 | ||
|
|
10057de9b3 | ||
|
|
cc88ebd2b9 | ||
|
|
6baedf909d | ||
|
|
f39d9d6f1b | ||
|
|
ab61a95f83 | ||
|
|
10ceed30c6 | ||
|
|
2b9aa94f3a | ||
|
|
848fb975ed | ||
|
|
d7f59dac84 | ||
|
|
dd47e615ee | ||
|
|
8f2f7ea1a5 | ||
|
|
80a8efd8ce | ||
|
|
d9dce77ef4 | ||
|
|
ce7053a1fe | ||
|
|
0db1530171 | ||
|
|
3745504107 | ||
|
|
57533fd831 | ||
|
|
f57a0d4d6b | ||
|
|
22772ca33e | ||
|
|
dba6ff1d51 | ||
|
|
40146dedaf | ||
|
|
387b822f53 | ||
|
|
b9a3563e5b | ||
|
|
3d6468326a | ||
|
|
298e37ec53 | ||
|
|
5b137c457b | ||
|
|
5218a3fbac | ||
|
|
4569cb432d | ||
|
|
611e598756 | ||
|
|
937d79d28f | ||
|
|
23c2a771d3 | ||
|
|
58a890e836 | ||
|
|
6a869e120c | ||
|
|
ae7c298b1a | ||
|
|
53bfe12ac1 | ||
|
|
140ea683a6 | ||
|
|
0634a97598 | ||
|
|
3479c794de | ||
|
|
89cad116f7 | ||
|
|
19c84eb694 | ||
|
|
eae390acf5 | ||
|
|
10567afbb9 | ||
|
|
51bad3bf3c | ||
|
|
9134d8841d | ||
|
|
e9a026c131 | ||
|
|
9a2fd0e2b2 | ||
|
|
522f7e6844 | ||
|
|
cb4f46decc | ||
|
|
81256279a8 | ||
|
|
039bd1ddc0 | ||
|
|
0791d4797f | ||
|
|
6a06142e1e | ||
|
|
ef53dca062 | ||
|
|
6ce761edda | ||
|
|
d8fd218409 | ||
|
|
edc2310599 | ||
|
|
b1cd13d629 | ||
|
|
b81940351f | ||
|
|
a42e99c4aa | ||
|
|
ff40b521b7 | ||
|
|
85392496e7 | ||
|
|
29cae9975e | ||
|
|
170d6b28f8 | ||
|
|
9a8b404054 | ||
|
|
41af5187aa | ||
|
|
a844ca161f | ||
|
|
e09efba313 | ||
|
|
96a0dbea2d | ||
|
|
5b3b5271ad | ||
|
|
d7d13c12fe | ||
|
|
54220d0e71 | ||
|
|
4a2e3586f1 | ||
|
|
f808e85da9 | ||
|
|
1671d1f580 | ||
|
|
7de1bf9d95 | ||
|
|
7368b0cefb | ||
|
|
4af43d676a | ||
|
|
67dc848b2d | ||
|
|
7ec8f0d26b | ||
|
|
eaf08a9971 | ||
|
|
5bdb9e972e | ||
|
|
d4d87054c4 | ||
|
|
0f93929544 | ||
|
|
1c0e794f87 | ||
|
|
f9bce5a5f9 | ||
|
|
797ae096c8 | ||
|
|
6d76918424 | ||
|
|
2aced893c6 | ||
|
|
f0373cd789 | ||
|
|
2f88dc64fc | ||
|
|
781ca77794 | ||
|
|
c6e453fb00 | ||
|
|
a40b3dd377 | ||
|
|
096b3534d8 | ||
|
|
8dcc114873 | ||
|
|
8cc9aeba4a | ||
|
|
ba0823c38c |
34
.github/ISSUE_TEMPLATE.md
vendored
Normal file
34
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
<!--
|
||||
## Before you hit that Submit button....
|
||||
|
||||
This issue tracker is for problems with the Node-RED runtime, the editor or the core nodes.
|
||||
|
||||
If your issue is:
|
||||
- a general 'how-to' type question,
|
||||
- a feature request or suggestion for a change,
|
||||
- or problems with 3rd party (`node-red-contrib-`) nodes
|
||||
|
||||
please use the [Node-RED Forum](https://discourse.nodered.org) or [slack team](https://nodered.org/slack).
|
||||
|
||||
You could also consider asking a question on [Stack Overflow](https://stackoverflow.com/questions/tagged/node-red) and tag it `node-red`.
|
||||
|
||||
That way the whole Node-RED user community can help, rather than rely on the core development team.
|
||||
|
||||
## So you have a real issue to raise...
|
||||
|
||||
To help us understand the issue, please fill-in as much of the following information as you can:
|
||||
-->
|
||||
|
||||
### What are the steps to reproduce?
|
||||
|
||||
### What happens?
|
||||
|
||||
### What do you expect to happen?
|
||||
|
||||
### Please tell us about your environment:
|
||||
|
||||
- [ ] Node-RED version:
|
||||
- [ ] node.js version:
|
||||
- [ ] npm version:
|
||||
- [ ] Platform/OS:
|
||||
- [ ] Browser:
|
||||
34
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
34
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
<!--
|
||||
## Before you hit that Submit button....
|
||||
|
||||
Please read our [contribution guidelines](https://github.com/node-red/node-red/blob/master/CONTRIBUTING.md)
|
||||
before submitting a pull-request.
|
||||
|
||||
## Types of changes
|
||||
|
||||
What types of changes does your code introduce?
|
||||
Put an `x` in the boxes that apply
|
||||
-->
|
||||
|
||||
- [ ] Bugfix (non-breaking change which fixes an issue)
|
||||
- [ ] New feature (non-breaking change which adds functionality)
|
||||
|
||||
<!--
|
||||
If you want to raise a pull-request with a new feature, or a refactoring
|
||||
of existing code, it **may well get rejected** if it hasn't been discussed on
|
||||
the [forum](https://discourse.nodered.org) or
|
||||
[slack team](https://nodered.org/slack) first.
|
||||
|
||||
-->
|
||||
|
||||
## Proposed changes
|
||||
|
||||
<!-- Describe the nature of this change. What problem does it address? -->
|
||||
|
||||
## Checklist
|
||||
<!-- Put an `x` in the boxes that apply -->
|
||||
|
||||
- [ ] I have read the [contribution guidelines](https://github.com/node-red/node-red/blob/master/CONTRIBUTING.md)
|
||||
- [ ] For non-bugfix PRs, I have discussed this change on the mailing list/slack team.
|
||||
- [ ] I have run `grunt` to verify the unit tests pass
|
||||
- [ ] I have added suitable unit tests to cover the new/changed functionality
|
||||
29
.travis.yml
29
.travis.yml
@@ -1,21 +1,12 @@
|
||||
sudo: false
|
||||
language: node_js
|
||||
env:
|
||||
- CXX="g++-4.8"
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- g++-4.8
|
||||
- gcc-4.8
|
||||
node_js:
|
||||
- "8"
|
||||
- "7"
|
||||
- "6"
|
||||
- "4"
|
||||
script:
|
||||
- istanbul cover ./node_modules/.bin/grunt --report lcovonly && istanbul report text && ( cat coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js || true ) && rm -rf coverage
|
||||
before_script:
|
||||
- npm install -g istanbul
|
||||
- npm install coveralls
|
||||
matrix:
|
||||
include:
|
||||
- node_js: "10"
|
||||
script:
|
||||
- istanbul cover ./node_modules/.bin/grunt --report lcovonly && istanbul report text && ( cat coverage/lcov.info | $(npm get prefix)/bin/coveralls || true ) && rm -rf coverage
|
||||
before_script:
|
||||
- npm install -g istanbul coveralls
|
||||
- node_js: "8"
|
||||
- node_js: "6"
|
||||
- node_js: "4"
|
||||
|
||||
291
CHANGELOG.md
291
CHANGELOG.md
@@ -1,3 +1,258 @@
|
||||
#### 0.18.6: Maintenance Release
|
||||
|
||||
Editor Fixes
|
||||
|
||||
- Handle a node having wires in the editor on ports it no longer has Fixes #1724
|
||||
- Add missing ACE snippet files
|
||||
- Fix wireClippedNodes is not defined Fixes #1726
|
||||
- Split node html to isolate bad nodes when loading
|
||||
- Avoid unnecessary use of .html() where .text() will do
|
||||
|
||||
- Add editorTheme.projects.enabled to default settings.js"
|
||||
|
||||
#### 0.18.5: Maintenance Release
|
||||
|
||||
Projects
|
||||
|
||||
- Add clone project to welcome screen
|
||||
- Handle cloning a project without package.json
|
||||
- Keep remote branch state in sync between editor and runtime
|
||||
|
||||
New Features
|
||||
|
||||
- Add type checks to switch node options (#1714)
|
||||
- add output property select to HTML parse node (#1701)
|
||||
- Add Prevent Following Redirect to HTTP Request node (#615) (#1684)
|
||||
- Add debug and trace functions to function node (#1654)
|
||||
- Enable user defined icon for subflow
|
||||
- Add MQTT disconnect message and rework broker node UI (#1719)
|
||||
- Japanese message catalogue updates (#1723)
|
||||
- Show node load errors in the Palette Manager view
|
||||
|
||||
Editor Fixes
|
||||
|
||||
- Highlight subflow node when log msg comes from inside Fixes #1698
|
||||
- Ensure node wires array is not longer than outputs value Fixes #1678
|
||||
- Allow importing an unknown config node to be undone Fixes #1681
|
||||
- Ensure keyboard shortcuts get saved in runtime settings Fixes #1696
|
||||
- Don't mark a subflow changed when actually modified nothing (#1665)
|
||||
|
||||
Node Fixes
|
||||
|
||||
- bind to correct port when doing udp broadcast/multicast (#1686)
|
||||
- Provide full error stack in Function node log message (#1700)
|
||||
- Fix http request doc type Fixes #1690
|
||||
- Make debug slightly larger to pass WCAG AA rating
|
||||
- Make core nodes labels more consistent, to close #1673
|
||||
- Allow template node to be updated more than once Fixes #1671
|
||||
- Fix the problem that output labels of switch node sometimes disappear (#1664)
|
||||
- Chinese translations for core nodes (#1607)
|
||||
|
||||
Runtime Fixes
|
||||
|
||||
- Handle and display for invalid flow credentials when project is disabled #1689 (#1694)
|
||||
- node-red-pi: fix behavior with old bash version (#1713)
|
||||
- Fix ENOENT error on first start when no user dir (#1711)
|
||||
- Handle null error object in Flow.handleError Fixes #1721
|
||||
- update settings comments to describe how to setup for ipv6 (#1675)
|
||||
- Remove credential props after diffing flow to prevent future false positives Fixes #1359
|
||||
- Log error if settings unavailable when saving user settings Fixes #1645
|
||||
- Keep backup of .config.json
|
||||
- Add warning if using \_credentialSecret from .config.json
|
||||
- Filter req.user in /settings to prevent potentially leaking info
|
||||
|
||||
#### 0.18.4: Maintenance Release
|
||||
|
||||
Projects
|
||||
|
||||
- Ensure sshkey file path is properly escaped on Windows
|
||||
- Normalize ssh key paths for Windows file names
|
||||
- Ensure userDir is an absolute path when used with sshkeygen
|
||||
- Detect if there are no existing flows to migrate into a project
|
||||
- Use relative urls when retriving flow history
|
||||
- Add credentialSecret to clone pane
|
||||
- Delay clearing inflight when changing credentials key
|
||||
- Mark deploy inflight when reverting a file change
|
||||
- Handle missing_flow_file error on clone properly
|
||||
- Remote project from cached list on delete so it can be reused
|
||||
- Fix tests for existing file flag in settings
|
||||
|
||||
Editor Fixes
|
||||
|
||||
- Fix merging a remote diff
|
||||
- Fixed the problems when using a node without defaults
|
||||
- Disable user defined icon for subflow
|
||||
- getDefaultNodeIcon should handle subflow instance nodes Fixes #1635
|
||||
- Add Japanese info text for core nodes
|
||||
- Fix message lookup for core nodes in case of i18 locales directory exists
|
||||
- Prevent the last tab from being deleted
|
||||
|
||||
Node Fixes
|
||||
|
||||
- Ensure trigger gets reset when 2nd output is null
|
||||
|
||||
|
||||
#### 0.18.3: Maintenance Release
|
||||
|
||||
Projects
|
||||
|
||||
- Fix permissions on git/ssh scripts
|
||||
- Add support for GIT_SSH on older levels of git
|
||||
- Handle host key verification as auth error
|
||||
- Ensure commit list has a refs object even if empty
|
||||
- Make git error detection case-insensitive
|
||||
- Fix up merge conflict handling
|
||||
- Use flow-diff when looking at flow file changes
|
||||
|
||||
Node Fixes
|
||||
|
||||
- Ensure debug tools show for 'complete msg object'
|
||||
- Fix msg.parts handling in concat mode of Batch node
|
||||
|
||||
Editor Fixes
|
||||
|
||||
- Fix offset calculation when dragging node from palette
|
||||
- Allow a library entry to use non-default node-input- prefixes
|
||||
- Change remote-diff shortcut and add it to keymap Fixes #1628
|
||||
|
||||
#### 0.18.2: Maintenance Release
|
||||
|
||||
Projects
|
||||
|
||||
- Filter out %D from git log command for older git versions
|
||||
- Ensure projects are created as logged in user
|
||||
- Better error handling/reporting in project creation
|
||||
- Add Project Settings menu option
|
||||
- Refresh vc sidebar on remote add/remove
|
||||
- Fix auth prompt for ssh repos
|
||||
- Prevent http git urls from including username/pword
|
||||
- Fix fetch auth handling on non-default remote
|
||||
- Avoid exception if git not installed
|
||||
- Check version of git client on startup
|
||||
- Fix pull/push when no tracked branch
|
||||
- Add git_pull_unrelated_history handling
|
||||
- Handle delete of last remote in project settings
|
||||
|
||||
Node Fixes
|
||||
|
||||
- Fix and Add some Chinese translations
|
||||
- Update sort/batch docs
|
||||
- Don't assume node has defaults when exporting icon property
|
||||
- Ensure send is last thing trigger does
|
||||
- Ensure trigger doesn't set two simultaneous timeouts
|
||||
- Add missing property select var to HTML node
|
||||
- Add a default keepalive to tcp client mode
|
||||
- Move node.send in exec and httprequest nodes
|
||||
|
||||
|
||||
#### 0.18.1: Maintenance Release
|
||||
|
||||
Projects
|
||||
|
||||
- Handle more repo clone error cases
|
||||
- Relax validation of git urls
|
||||
- Revalidate project name on return to project-details view
|
||||
- Avoid unnecessary project refresh on branch-switch Fixes #1597
|
||||
- Add support for file:// git urls
|
||||
- Handle project first-run without existing flow file
|
||||
- Handle delete of last remote in project settings
|
||||
- Add git_pull_unrelated_history handling
|
||||
- Fix pull/push when no tracked branch
|
||||
- Remember to disable projects in editor when git not found
|
||||
|
||||
Node Fixes
|
||||
|
||||
- Trigger node migration - ensure bytopic not blank
|
||||
- Add HEAD to list of methods with no body in http req node #1598
|
||||
- Do not include payload in GET requests Fixes #1598
|
||||
- Update sort/batch docs Fixes #1601
|
||||
- Don't assume node has defaults when exporting icon property
|
||||
|
||||
|
||||
#### 0.18: Milestone Release
|
||||
|
||||
Runtime
|
||||
|
||||
- Beta: Projects - must be enabled in settings file
|
||||
- Allow port zero for Express (#1363)
|
||||
- Better error reporting when module provides duplicate type
|
||||
- Update jsonata to 1.5.0
|
||||
- add express-session memorystore without leaks (#1435)
|
||||
- Allow adminAuth.user to be a Function Fixes #1461
|
||||
- Ensure RED.server is set even if admin api disabled
|
||||
- Ensure strategy login button uses relative URL Fixes #1481
|
||||
- ignore `_msgid` when merging full objects
|
||||
- Move node install to spawn to allow for big stdout Fixes #1488
|
||||
- SIGINT handler should wait for stop to complete before exit
|
||||
|
||||
Editor
|
||||
|
||||
- allow a node's icon to be set dynamically (#1490)
|
||||
- Batch messages sent over comms to increase throughput
|
||||
- Migrate deploy confirmations to notifications
|
||||
- `oneditdelete` should be available to all node types Closes #1346
|
||||
- Sort typeSearch results based on position of match
|
||||
- Update ACE to test and add python highlighter (#1373)
|
||||
- Clear mouse state when typeSearch cancelled Fixes #1517
|
||||
- Handle scoped modules via palette editor
|
||||
- TypedInput: handle user defined value/labels options Fixes #1549
|
||||
|
||||
Nodes
|
||||
|
||||
- add msg. select to range and yaml nodes
|
||||
- add property choice to xml, sentiment nodes
|
||||
- mqtt: Add 'name' to mqtt-broker node, and label it by this if it is set. (#1364)
|
||||
- Add option to JSON node to ensure particular encoding
|
||||
- add parts support for HTML node (#1495)
|
||||
- Add passphrase to TLS node
|
||||
- Add rc property to exec node outputs 1 and 2 (#1401)
|
||||
- Add skip first n lines capability to csv node (#1535)
|
||||
- Add support for rejectUnauthorized msg property
|
||||
- Add TLS options to WebSocket client
|
||||
- Added parsed YAML support for template node (#1443)
|
||||
- Allow delay node in rate-limit mode to be reset Fixes #1360
|
||||
- Allow setTimeout in Function node to be promisified in node 8
|
||||
- Debug to status option (#1499)
|
||||
- enable template config via msg.template for stored or generated templates (#1503)
|
||||
- HTTP REQUEST: Adding PROPPATCH and PROPFIND http methods (#1531)
|
||||
- Initial support of merge & reduce mode for JOIN node (#1546)
|
||||
- Initial support of new BATCH node (#1548)
|
||||
- Initial support of sequence rules for SWITCH node (#1545)
|
||||
- initial support of SORT node (#1500)
|
||||
- Inject node - let once delay be editable (#1541)
|
||||
- Introduce `nodeMaxMessageBufferLength` setting for msg sequence nodes
|
||||
- Let CSV correct parts if we remove header row.
|
||||
- let default apply if msg.delay not set in override mode. (#1397)
|
||||
- let trigger node be reset by boolean message (#1554)
|
||||
- Let trigger node support per topic mode (#1398)
|
||||
- let HTML node return empty array for no matching input (#1582)
|
||||
- MQTT node - if Server/URL config contains '//' use it as a complete url; enabled ws:// and wss://
|
||||
- clone messages before delayed send (#1474)
|
||||
- Decrement connected client count rather than show disconnected
|
||||
- Don't end mqtt client on first error Fixes #1566
|
||||
- File out - create dirs synchronously to ensure they exist Fixes #1489
|
||||
- Fix debug message format for Buffer (#1444)
|
||||
- Fix global.keys() bug in function node (#1417)
|
||||
- Handle escape characters in template node which uses Mustache format and JSON output mode (#1377)
|
||||
- Move all node.send to end of timer functions in trigger node (issue #1527) (#1539)
|
||||
- Publish null/undefined to mqtt as blank not toString Fixes #1521
|
||||
- remove inject node at specific time spinner
|
||||
- restrict inject interval to less that 2^31 millisecs
|
||||
- tag UDP ports in use properly so they get closed correctly (#1508)
|
||||
|
||||
#### 0.17.5: Maintenance Release
|
||||
|
||||
- Add express-session missing dependency for oauth
|
||||
- Fix improper type tests is core test cases
|
||||
- File node: recreate write stream when file deleted Fixes #1351
|
||||
- Add flow stopping trace messages
|
||||
- Fix userDir test case when .config.json exists (#1350)
|
||||
- Do not try to send msg after http request error handled Fixes #1344
|
||||
- Fix boundary problem in range node (#1338)
|
||||
- Modify messages in node properties to refer messages.json (#1339)
|
||||
- Fix settings.js replacing webSocketVerifyClient by webSocketNodeVerifyClient (#1343)
|
||||
|
||||
|
||||
#### 0.17.4: Maintenance Release
|
||||
|
||||
- Add request node test case for POSTing 0
|
||||
@@ -876,7 +1131,7 @@ Fixes
|
||||
#### 0.10.10: Maintenance Release
|
||||
|
||||
- Fix permissions issue with packaged nrgpio script
|
||||
- Add better help message if deprecated node missing
|
||||
- Add better help message if deprecated node missing
|
||||
|
||||
|
||||
|
||||
@@ -888,16 +1143,16 @@ Fix packaging of bin scripts
|
||||
|
||||
#### 0.10.8: Maintenance Release
|
||||
|
||||
- Nodes moved out of core
|
||||
- still included as a dependency: twitter, serial, email, feedparser
|
||||
- Nodes moved out of core
|
||||
- still included as a dependency: twitter, serial, email, feedparser
|
||||
- no longer included: mongo, arduino, irc, redis
|
||||
- node icon defn can be a function
|
||||
- http_proxy support
|
||||
- httpNodeMiddleware setting
|
||||
- Trigger node ui refresh
|
||||
- editorTheme setting
|
||||
- Warn on deploy of unused config nodes
|
||||
- catch node prevents error loops
|
||||
- node icon defn can be a function
|
||||
- http_proxy support
|
||||
- httpNodeMiddleware setting
|
||||
- Trigger node ui refresh
|
||||
- editorTheme setting
|
||||
- Warn on deploy of unused config nodes
|
||||
- catch node prevents error loops
|
||||
|
||||
|
||||
|
||||
@@ -920,14 +1175,14 @@ Changes:
|
||||
|
||||
Changes:
|
||||
|
||||
- http request node passes on request url as msg.url
|
||||
- handle config nodes appearing out of order in flow file - don't assume they are always at the start
|
||||
- move subflow palette category to the top, to make it more obvious
|
||||
- fix labelling of Raspberry Pi pins
|
||||
- allow email node to mark mail as read
|
||||
- fix saving library content
|
||||
- add node-red and node-red-pi start scripts
|
||||
- use $HOME/.node-red for user data unless specified otherwise (or existing data is found in install dir)
|
||||
- http request node passes on request url as msg.url
|
||||
- handle config nodes appearing out of order in flow file - don't assume they are always at the start
|
||||
- move subflow palette category to the top, to make it more obvious
|
||||
- fix labelling of Raspberry Pi pins
|
||||
- allow email node to mark mail as read
|
||||
- fix saving library content
|
||||
- add node-red and node-red-pi start scripts
|
||||
- use $HOME/.node-red for user data unless specified otherwise (or existing data is found in install dir)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ We welcome contributions, but request you follow these guidelines.
|
||||
|
||||
This project adheres to the [Contributor Covenant 1.4](http://contributor-covenant.org/version/1/4/).
|
||||
By participating, you are expected to uphold this code. Please report unacceptable
|
||||
behavior to any of the [project's core team](https://github.com/orgs/node-red/teams/core).
|
||||
behavior to the project's core team at team@nodered.org.
|
||||
|
||||
## Raising issues
|
||||
|
||||
@@ -30,13 +30,13 @@ At a minimum, please include:
|
||||
|
||||
## Feature requests
|
||||
|
||||
For feature requests, please raise them on the [mailing list](https://groups.google.com/forum/#!forum/node-red).
|
||||
For feature requests, please raise them on the [forum](https://discourse.nodered.org).
|
||||
|
||||
## Pull-Requests
|
||||
|
||||
If you want to raise a pull-request with a new feature, or a refactoring
|
||||
of existing code, it may well get rejected if you haven't discussed it on
|
||||
the [mailing list](https://groups.google.com/forum/#!forum/node-red) first.
|
||||
the [forum](https://discourse.nodered.org) first.
|
||||
|
||||
All contributors need to sign the JS Foundation's Contributor License Agreement.
|
||||
It is an online process and quick to do. You can read the details of the agreement
|
||||
|
||||
30
Gruntfile.js
30
Gruntfile.js
@@ -41,16 +41,23 @@ module.exports = function(grunt) {
|
||||
core: { src: ["test/_spec.js","test/red/**/*_spec.js"]},
|
||||
nodes: { src: ["test/nodes/**/*_spec.js"]}
|
||||
},
|
||||
webdriver: {
|
||||
all: {
|
||||
configFile: 'test/editor/wdio.conf.js'
|
||||
}
|
||||
},
|
||||
mocha_istanbul: {
|
||||
options: {
|
||||
globals: ['expect'],
|
||||
timeout: 3000,
|
||||
ignoreLeaks: false,
|
||||
ui: 'bdd',
|
||||
reportFormats: ['lcov'],
|
||||
reportFormats: ['lcov','html'],
|
||||
print: 'both'
|
||||
},
|
||||
coverage: { src: ['test/**/*_spec.js'] }
|
||||
all: { src: ['test/**/*_spec.js'] },
|
||||
core: { src: ["test/_spec.js","test/red/**/*_spec.js"]},
|
||||
nodes: { src: ["test/nodes/**/*_spec.js"]}
|
||||
},
|
||||
jshint: {
|
||||
options: {
|
||||
@@ -151,6 +158,10 @@ module.exports = function(grunt) {
|
||||
"editor/js/ui/typeSearch.js",
|
||||
"editor/js/ui/subflow.js",
|
||||
"editor/js/ui/userSettings.js",
|
||||
"editor/js/ui/projects/projects.js",
|
||||
"editor/js/ui/projects/projectSettings.js",
|
||||
"editor/js/ui/projects/projectUserSettings.js",
|
||||
"editor/js/ui/projects/tab-versionControl.js",
|
||||
"editor/js/ui/touch/radialMenu.js"
|
||||
],
|
||||
dest: "public/red/red.js"
|
||||
@@ -381,9 +392,9 @@ module.exports = function(grunt) {
|
||||
mode: '755'
|
||||
},
|
||||
release: {
|
||||
// Target-specific file/dir lists and/or options go here.
|
||||
src: [
|
||||
path.resolve('<%= paths.dist %>/node-red-<%= pkg.version %>/nodes/core/hardware/nrgpio*')
|
||||
path.resolve('<%= paths.dist %>/node-red-<%= pkg.version %>/nodes/core/hardware/nrgpio*'),
|
||||
path.resolve('<%= paths.dist %>/node-red-<%= pkg.version %>/red/runtime/storage/localfilesystem/projects/git/node-red-*sh')
|
||||
]
|
||||
}
|
||||
},
|
||||
@@ -413,6 +424,7 @@ module.exports = function(grunt) {
|
||||
grunt.loadNpmTasks('grunt-chmod');
|
||||
grunt.loadNpmTasks('grunt-jsonlint');
|
||||
grunt.loadNpmTasks('grunt-mocha-istanbul');
|
||||
grunt.loadNpmTasks('grunt-webdriver');
|
||||
|
||||
grunt.registerMultiTask('attachCopyright', function() {
|
||||
var files = this.data.src;
|
||||
@@ -466,15 +478,19 @@ module.exports = function(grunt) {
|
||||
|
||||
grunt.registerTask('test-core',
|
||||
'Runs code style check and unit tests on core runtime code',
|
||||
['jshint:core','simplemocha:core']);
|
||||
['build','mocha_istanbul:core']);
|
||||
|
||||
grunt.registerTask('test-editor',
|
||||
'Runs code style check on editor code',
|
||||
['jshint:editor']);
|
||||
|
||||
grunt.registerTask('test-ui',
|
||||
'Builds editor content then runs unit tests on editor ui',
|
||||
['build','jshint:editor','webdriver:all']);
|
||||
|
||||
grunt.registerTask('test-nodes',
|
||||
'Runs unit tests on core nodes',
|
||||
['simplemocha:nodes']);
|
||||
['build','mocha_istanbul:nodes']);
|
||||
|
||||
grunt.registerTask('build',
|
||||
'Builds editor content',
|
||||
@@ -490,5 +506,5 @@ module.exports = function(grunt) {
|
||||
|
||||
grunt.registerTask('coverage',
|
||||
'Run Istanbul code test coverage task',
|
||||
['build','mocha_istanbul']);
|
||||
['build','mocha_istanbul:all']);
|
||||
};
|
||||
|
||||
@@ -14,7 +14,7 @@ A visual tool for wiring the Internet of Things.
|
||||
Check out http://nodered.org/docs/getting-started/ for full instructions on getting
|
||||
started.
|
||||
|
||||
1. `sudo npm install -g node-red`
|
||||
1. `sudo npm install -g --unsafe-perm node-red`
|
||||
2. `node-red`
|
||||
3. Open <http://localhost:1880>
|
||||
|
||||
@@ -22,8 +22,7 @@ started.
|
||||
|
||||
More documentation can be found [here](http://nodered.org/docs).
|
||||
|
||||
For further help, or general discussion, please use the
|
||||
[mailing list](https://groups.google.com/forum/#!forum/node-red).
|
||||
For further help, or general discussion, please use the [Node-RED Forum](https://discourse.nodered.org) or [slack team](https://nodered.org/slack).
|
||||
|
||||
## Developers
|
||||
|
||||
@@ -56,7 +55,7 @@ Before raising a pull-request, please read our
|
||||
|
||||
This project adheres to the [Contributor Covenant 1.4](http://contributor-covenant.org/version/1/4/).
|
||||
By participating, you are expected to uphold this code. Please report unacceptable
|
||||
behavior to any of the [project's core team](https://github.com/orgs/node-red/teams/core).
|
||||
behavior to any of the project's core team at team@nodered.org.
|
||||
|
||||
## Authors
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ done
|
||||
# Find the real location of this script
|
||||
CURRENT_PATH=`pwd`
|
||||
SCRIPT_PATH="${BASH_SOURCE[0]}";
|
||||
while([ -h "${SCRIPT_PATH}" ]); do
|
||||
while [ -h "${SCRIPT_PATH}" ]; do
|
||||
cd "`dirname "${SCRIPT_PATH}"`"
|
||||
SCRIPT_PATH="$(readlink "`basename "${SCRIPT_PATH}"`")";
|
||||
done
|
||||
|
||||
BIN
editor/icons/batch.png
Normal file
BIN
editor/icons/batch.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 712 B |
BIN
editor/icons/sort.png
Normal file
BIN
editor/icons/sort.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 793 B |
@@ -64,27 +64,31 @@ RED.comms = (function() {
|
||||
}
|
||||
}
|
||||
ws.onmessage = function(event) {
|
||||
var msg = JSON.parse(event.data);
|
||||
if (pendingAuth && msg.auth) {
|
||||
if (msg.auth === "ok") {
|
||||
pendingAuth = false;
|
||||
completeConnection();
|
||||
} else if (msg.auth === "fail") {
|
||||
// anything else is an error...
|
||||
active = false;
|
||||
RED.user.login({updateMenu:true},function() {
|
||||
connectWS();
|
||||
})
|
||||
var message = JSON.parse(event.data);
|
||||
for (var m = 0; m < message.length; m++) {
|
||||
var msg = message[m];
|
||||
if (pendingAuth && msg.auth) {
|
||||
if (msg.auth === "ok") {
|
||||
pendingAuth = false;
|
||||
completeConnection();
|
||||
} else if (msg.auth === "fail") {
|
||||
// anything else is an error...
|
||||
active = false;
|
||||
RED.user.login({updateMenu:true},function() {
|
||||
connectWS();
|
||||
})
|
||||
}
|
||||
}
|
||||
} else if (msg.topic) {
|
||||
for (var t in subscriptions) {
|
||||
if (subscriptions.hasOwnProperty(t)) {
|
||||
var re = new RegExp("^"+t.replace(/([\[\]\?\(\)\\\\$\^\*\.|])/g,"\\$1").replace(/\+/g,"[^/]+").replace(/\/#$/,"(\/.*)?")+"$");
|
||||
if (re.test(msg.topic)) {
|
||||
var subscribers = subscriptions[t];
|
||||
if (subscribers) {
|
||||
for (var i=0;i<subscribers.length;i++) {
|
||||
subscribers[i](msg.topic,msg.data);
|
||||
else if (msg.topic) {
|
||||
for (var t in subscriptions) {
|
||||
if (subscriptions.hasOwnProperty(t)) {
|
||||
var re = new RegExp("^"+t.replace(/([\[\]\?\(\)\\\\$\^\*\.|])/g,"\\$1").replace(/\+/g,"[^/]+").replace(/\/#$/,"(\/.*)?")+"$");
|
||||
if (re.test(msg.topic)) {
|
||||
var subscribers = subscriptions[t];
|
||||
if (subscribers) {
|
||||
for (var i=0;i<subscribers.length;i++) {
|
||||
subscribers[i](msg.topic,msg.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ RED.history = (function() {
|
||||
} else if (ev.t == "edit") {
|
||||
for (i in ev.changes) {
|
||||
if (ev.changes.hasOwnProperty(i)) {
|
||||
if (ev.node._def.defaults[i] && ev.node._def.defaults[i].type) {
|
||||
if (ev.node._def.defaults && ev.node._def.defaults[i] && ev.node._def.defaults[i].type) {
|
||||
// This is a config node property
|
||||
var currentConfigNode = RED.nodes.node(ev.node[i]);
|
||||
if (currentConfigNode) {
|
||||
@@ -229,10 +229,12 @@ RED.history = (function() {
|
||||
}
|
||||
});
|
||||
}
|
||||
RED.editor.validateNode(ev.node);
|
||||
RED.nodes.filterNodes({type:"subflow:"+ev.node.id}).forEach(function(n) {
|
||||
n.inputs = ev.node.in.length;
|
||||
n.outputs = ev.node.out.length;
|
||||
RED.editor.updateNodeProperties(n);
|
||||
RED.editor.validateNode(n);
|
||||
});
|
||||
} else {
|
||||
var outputMap;
|
||||
@@ -321,6 +323,9 @@ RED.history = (function() {
|
||||
},
|
||||
peek: function() {
|
||||
return undo_history[undo_history.length-1];
|
||||
},
|
||||
clear: function() {
|
||||
undo_history = [];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,11 @@
|
||||
"ctrl-e": "core:show-export-dialog",
|
||||
"ctrl-i": "core:show-import-dialog",
|
||||
"ctrl-space": "core:toggle-sidebar",
|
||||
"ctrl-,": "core:show-user-settings"
|
||||
"ctrl-,": "core:show-user-settings",
|
||||
"ctrl-alt-r": "core:show-remote-diff",
|
||||
"ctrl-alt-n": "core:new-project",
|
||||
"ctrl-alt-o": "core:open-project",
|
||||
"ctrl-g v": "core:show-version-control-tab"
|
||||
},
|
||||
"workspace": {
|
||||
"backspace": "core:delete-selection",
|
||||
|
||||
@@ -15,6 +15,25 @@
|
||||
**/
|
||||
(function() {
|
||||
|
||||
function appendNodeConfig(nodeConfig) {
|
||||
var m = /<!-- --- \[red-module:(\S+)\] --- -->/.exec(nodeConfig.trim());
|
||||
var moduleId;
|
||||
if (m) {
|
||||
moduleId = m[1];
|
||||
} else {
|
||||
moduleId = "unknown";
|
||||
}
|
||||
try {
|
||||
$("body").append(nodeConfig);
|
||||
} catch(err) {
|
||||
RED.notify(RED._("notification.errors.failedToAppendNode",{module:moduleId, error:err.toString()}),{
|
||||
type: "error",
|
||||
timeout: 10000
|
||||
});
|
||||
console.log("["+moduleId+"] "+err.toString());
|
||||
}
|
||||
}
|
||||
|
||||
function loadNodeList() {
|
||||
$.ajax({
|
||||
headers: {
|
||||
@@ -24,7 +43,25 @@
|
||||
url: 'nodes',
|
||||
success: function(data) {
|
||||
RED.nodes.setNodeList(data);
|
||||
RED.i18n.loadNodeCatalogs(loadNodes);
|
||||
RED.i18n.loadNodeCatalogs(function() {
|
||||
loadIconList(loadNodes);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function loadIconList(done) {
|
||||
$.ajax({
|
||||
headers: {
|
||||
"Accept":"application/json"
|
||||
},
|
||||
cache: false,
|
||||
url: 'icons',
|
||||
success: function(data) {
|
||||
RED.nodes.setIconSets(data);
|
||||
if (done) {
|
||||
done();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -37,17 +74,42 @@
|
||||
cache: false,
|
||||
url: 'nodes',
|
||||
success: function(data) {
|
||||
$("body").append(data);
|
||||
var configs = data.trim().split(/(?=<!-- --- \[red-module:\S+\] --- -->)/);
|
||||
configs.forEach(function(data) {
|
||||
appendNodeConfig(data);
|
||||
});
|
||||
|
||||
$("body").i18n();
|
||||
$("#palette > .palette-spinner").hide();
|
||||
$(".palette-scroll").removeClass("hide");
|
||||
$("#palette-search").removeClass("hide");
|
||||
loadFlows();
|
||||
loadFlows(function() {
|
||||
if (RED.settings.theme("projects.enabled",false)) {
|
||||
RED.projects.refresh(function(activeProject) {
|
||||
RED.sidebar.info.refresh()
|
||||
if (!activeProject) {
|
||||
// Projects enabled but no active project
|
||||
RED.menu.setDisabled('menu-item-projects-open',true);
|
||||
RED.menu.setDisabled('menu-item-projects-settings',true);
|
||||
if (activeProject === false) {
|
||||
// User previously decline the migration to projects.
|
||||
} else { // null/undefined
|
||||
RED.projects.showStartup();
|
||||
}
|
||||
}
|
||||
completeLoad();
|
||||
});
|
||||
} else {
|
||||
// Projects disabled by the user
|
||||
RED.sidebar.info.refresh()
|
||||
completeLoad();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function loadFlows() {
|
||||
function loadFlows(done) {
|
||||
$.ajax({
|
||||
headers: {
|
||||
"Accept":"application/json",
|
||||
@@ -55,114 +117,257 @@
|
||||
cache: false,
|
||||
url: 'flows',
|
||||
success: function(nodes) {
|
||||
var currentHash = window.location.hash;
|
||||
RED.nodes.version(nodes.rev);
|
||||
RED.nodes.import(nodes.flows);
|
||||
RED.nodes.dirty(false);
|
||||
RED.view.redraw(true);
|
||||
if (/^#flow\/.+$/.test(currentHash)) {
|
||||
RED.workspaces.show(currentHash.substring(6));
|
||||
if (nodes) {
|
||||
var currentHash = window.location.hash;
|
||||
RED.nodes.version(nodes.rev);
|
||||
RED.nodes.import(nodes.flows);
|
||||
RED.nodes.dirty(false);
|
||||
RED.view.redraw(true);
|
||||
if (/^#flow\/.+$/.test(currentHash)) {
|
||||
RED.workspaces.show(currentHash.substring(6));
|
||||
}
|
||||
}
|
||||
|
||||
var persistentNotifications = {};
|
||||
RED.comms.subscribe("notification/#",function(topic,msg) {
|
||||
var parts = topic.split("/");
|
||||
var notificationId = parts[1];
|
||||
if (notificationId === "runtime-deploy") {
|
||||
// handled in ui/deploy.js
|
||||
return;
|
||||
}
|
||||
if (notificationId === "node") {
|
||||
// handled below
|
||||
return;
|
||||
}
|
||||
if (msg.text) {
|
||||
var text = RED._(msg.text,{default:msg.text});
|
||||
if (!persistentNotifications.hasOwnProperty(notificationId)) {
|
||||
persistentNotifications[notificationId] = RED.notify(text,msg.type,msg.timeout === undefined,msg.timeout);
|
||||
} else {
|
||||
persistentNotifications[notificationId].update(text,msg.timeout);
|
||||
}
|
||||
} else if (persistentNotifications.hasOwnProperty(notificationId)) {
|
||||
persistentNotifications[notificationId].close();
|
||||
delete persistentNotifications[notificationId];
|
||||
}
|
||||
});
|
||||
RED.comms.subscribe("status/#",function(topic,msg) {
|
||||
var parts = topic.split("/");
|
||||
var node = RED.nodes.node(parts[1]);
|
||||
if (node) {
|
||||
if (msg.hasOwnProperty("text")) {
|
||||
if (msg.text[0] !== ".") {
|
||||
msg.text = node._(msg.text.toString(),{defaultValue:msg.text.toString()});
|
||||
}
|
||||
}
|
||||
node.status = msg;
|
||||
node.dirty = true;
|
||||
RED.view.redraw();
|
||||
}
|
||||
});
|
||||
RED.comms.subscribe("notification/node/#",function(topic,msg) {
|
||||
var i,m;
|
||||
var typeList;
|
||||
var info;
|
||||
if (topic == "notification/node/added") {
|
||||
var addedTypes = [];
|
||||
msg.forEach(function(m) {
|
||||
var id = m.id;
|
||||
RED.nodes.addNodeSet(m);
|
||||
addedTypes = addedTypes.concat(m.types);
|
||||
RED.i18n.loadCatalog(id, function() {
|
||||
$.get('nodes/'+id, function(data) {
|
||||
$("body").append(data);
|
||||
});
|
||||
});
|
||||
});
|
||||
if (addedTypes.length) {
|
||||
typeList = "<ul><li>"+addedTypes.join("</li><li>")+"</li></ul>";
|
||||
RED.notify(RED._("palette.event.nodeAdded", {count:addedTypes.length})+typeList,"success");
|
||||
}
|
||||
} else if (topic == "notification/node/removed") {
|
||||
for (i=0;i<msg.length;i++) {
|
||||
m = msg[i];
|
||||
info = RED.nodes.removeNodeSet(m.id);
|
||||
if (info.added) {
|
||||
typeList = "<ul><li>"+m.types.join("</li><li>")+"</li></ul>";
|
||||
RED.notify(RED._("palette.event.nodeRemoved", {count:m.types.length})+typeList,"success");
|
||||
}
|
||||
}
|
||||
} else if (topic == "notification/node/enabled") {
|
||||
if (msg.types) {
|
||||
info = RED.nodes.getNodeSet(msg.id);
|
||||
if (info.added) {
|
||||
RED.nodes.enableNodeSet(msg.id);
|
||||
typeList = "<ul><li>"+msg.types.join("</li><li>")+"</li></ul>";
|
||||
RED.notify(RED._("palette.event.nodeEnabled", {count:msg.types.length})+typeList,"success");
|
||||
} else {
|
||||
$.get('nodes/'+msg.id, function(data) {
|
||||
$("body").append(data);
|
||||
typeList = "<ul><li>"+msg.types.join("</li><li>")+"</li></ul>";
|
||||
RED.notify(RED._("palette.event.nodeAdded", {count:msg.types.length})+typeList,"success");
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (topic == "notification/node/disabled") {
|
||||
if (msg.types) {
|
||||
RED.nodes.disableNodeSet(msg.id);
|
||||
typeList = "<ul><li>"+msg.types.join("</li><li>")+"</li></ul>";
|
||||
RED.notify(RED._("palette.event.nodeDisabled", {count:msg.types.length})+typeList,"success");
|
||||
}
|
||||
} else if (topic == "node/upgraded") {
|
||||
RED.notify(RED._("palette.event.nodeUpgraded", {module:msg.module,version:msg.version}),"success");
|
||||
RED.nodes.registry.setModulePendingUpdated(msg.module,msg.version);
|
||||
}
|
||||
// Refresh flow library to ensure any examples are updated
|
||||
RED.library.loadFlowLibrary();
|
||||
});
|
||||
done();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function completeLoad() {
|
||||
var persistentNotifications = {};
|
||||
RED.comms.subscribe("notification/#",function(topic,msg) {
|
||||
var parts = topic.split("/");
|
||||
var notificationId = parts[1];
|
||||
if (notificationId === "runtime-deploy") {
|
||||
// handled in ui/deploy.js
|
||||
return;
|
||||
}
|
||||
if (notificationId === "node") {
|
||||
// handled below
|
||||
return;
|
||||
}
|
||||
if (notificationId === "project-update") {
|
||||
RED.nodes.clear();
|
||||
RED.history.clear();
|
||||
RED.view.redraw(true);
|
||||
RED.projects.refresh(function() {
|
||||
loadFlows(function() {
|
||||
var project = RED.projects.getActiveProject();
|
||||
var message = {
|
||||
"change-branch":"Change to local branch '"+project.git.branches.local+"'",
|
||||
"merge-abort":"Git merge aborted",
|
||||
"loaded":"Project '"+msg.project+"' loaded",
|
||||
"updated":"Project '"+msg.project+"' updated",
|
||||
"pull":"Project '"+msg.project+"' reloaded",
|
||||
"revert": "Project '"+msg.project+"' reloaded",
|
||||
"merge-complete":"Git merge completed"
|
||||
}[msg.action];
|
||||
RED.notify("<p>"+message+"</p>");
|
||||
RED.sidebar.info.refresh()
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg.text) {
|
||||
msg.default = msg.text;
|
||||
var text = RED._(msg.text,msg);
|
||||
var options = {
|
||||
type: msg.type,
|
||||
fixed: msg.timeout === undefined,
|
||||
timeout: msg.timeout,
|
||||
id: notificationId
|
||||
}
|
||||
if (notificationId === "runtime-state") {
|
||||
if (msg.error === "missing-types") {
|
||||
text+="<ul><li>"+msg.types.join("</li><li>")+"</li></ul>";
|
||||
if (!!RED.projects.getActiveProject()) {
|
||||
options.buttons = [
|
||||
{
|
||||
text: "Manage project dependencies",
|
||||
click: function() {
|
||||
persistentNotifications[notificationId].hideNotification();
|
||||
RED.projects.settings.show('deps');
|
||||
}
|
||||
}
|
||||
]
|
||||
// } else if (RED.settings.theme('palette.editable') !== false) {
|
||||
} else {
|
||||
options.buttons = [
|
||||
{
|
||||
text: "Close",
|
||||
click: function() {
|
||||
persistentNotifications[notificationId].hideNotification();
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
} else if (msg.error === "credentials_load_failed") {
|
||||
if (RED.settings.theme("projects.enabled",false)) {
|
||||
// projects enabled
|
||||
if (RED.user.hasPermission("projects.write")) {
|
||||
options.buttons = [
|
||||
{
|
||||
text: "Setup credentials",
|
||||
click: function() {
|
||||
persistentNotifications[notificationId].hideNotification();
|
||||
RED.projects.showCredentialsPrompt();
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
} else {
|
||||
options.buttons = [
|
||||
{
|
||||
text: "Close",
|
||||
click: function() {
|
||||
persistentNotifications[notificationId].hideNotification();
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
} else if (msg.error === "missing_flow_file") {
|
||||
if (RED.user.hasPermission("projects.write")) {
|
||||
options.buttons = [
|
||||
{
|
||||
text: "Setup project files",
|
||||
click: function() {
|
||||
persistentNotifications[notificationId].hideNotification();
|
||||
RED.projects.showFilesPrompt();
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
} else if (msg.error === "missing_package_file") {
|
||||
if (RED.user.hasPermission("projects.write")) {
|
||||
options.buttons = [
|
||||
{
|
||||
text: "Create default package file",
|
||||
click: function() {
|
||||
persistentNotifications[notificationId].hideNotification();
|
||||
RED.projects.createDefaultPackageFile();
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
} else if (msg.error === "project_empty") {
|
||||
if (RED.user.hasPermission("projects.write")) {
|
||||
options.buttons = [
|
||||
{
|
||||
text: "No thanks",
|
||||
click: function() {
|
||||
persistentNotifications[notificationId].hideNotification();
|
||||
}
|
||||
},
|
||||
{
|
||||
text: "Create default project files",
|
||||
click: function() {
|
||||
persistentNotifications[notificationId].hideNotification();
|
||||
RED.projects.createDefaultFileSet();
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
} else if (msg.error === "git_merge_conflict") {
|
||||
RED.nodes.clear();
|
||||
RED.sidebar.versionControl.refresh(true);
|
||||
if (RED.user.hasPermission("projects.write")) {
|
||||
options.buttons = [
|
||||
{
|
||||
text: "Show merge conflicts",
|
||||
click: function() {
|
||||
persistentNotifications[notificationId].hideNotification();
|
||||
RED.sidebar.versionControl.showLocalChanges();
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!persistentNotifications.hasOwnProperty(notificationId)) {
|
||||
persistentNotifications[notificationId] = RED.notify(text,options);
|
||||
} else {
|
||||
persistentNotifications[notificationId].update(text,options);
|
||||
}
|
||||
} else if (persistentNotifications.hasOwnProperty(notificationId)) {
|
||||
persistentNotifications[notificationId].close();
|
||||
delete persistentNotifications[notificationId];
|
||||
}
|
||||
});
|
||||
RED.comms.subscribe("status/#",function(topic,msg) {
|
||||
var parts = topic.split("/");
|
||||
var node = RED.nodes.node(parts[1]);
|
||||
if (node) {
|
||||
if (msg.hasOwnProperty("text")) {
|
||||
if (msg.text[0] !== ".") {
|
||||
msg.text = node._(msg.text.toString(),{defaultValue:msg.text.toString()});
|
||||
}
|
||||
}
|
||||
node.status = msg;
|
||||
node.dirty = true;
|
||||
RED.view.redraw();
|
||||
}
|
||||
});
|
||||
RED.comms.subscribe("notification/node/#",function(topic,msg) {
|
||||
var i,m;
|
||||
var typeList;
|
||||
var info;
|
||||
if (topic == "notification/node/added") {
|
||||
var addedTypes = [];
|
||||
msg.forEach(function(m) {
|
||||
var id = m.id;
|
||||
RED.nodes.addNodeSet(m);
|
||||
addedTypes = addedTypes.concat(m.types);
|
||||
RED.i18n.loadCatalog(id, function() {
|
||||
$.get('nodes/'+id, function(data) {
|
||||
appendNodeConfig(data);
|
||||
});
|
||||
});
|
||||
});
|
||||
if (addedTypes.length) {
|
||||
typeList = "<ul><li>"+addedTypes.join("</li><li>")+"</li></ul>";
|
||||
RED.notify(RED._("palette.event.nodeAdded", {count:addedTypes.length})+typeList,"success");
|
||||
}
|
||||
loadIconList();
|
||||
} else if (topic == "notification/node/removed") {
|
||||
for (i=0;i<msg.length;i++) {
|
||||
m = msg[i];
|
||||
info = RED.nodes.removeNodeSet(m.id);
|
||||
if (info.added) {
|
||||
typeList = "<ul><li>"+m.types.join("</li><li>")+"</li></ul>";
|
||||
RED.notify(RED._("palette.event.nodeRemoved", {count:m.types.length})+typeList,"success");
|
||||
}
|
||||
}
|
||||
loadIconList();
|
||||
} else if (topic == "notification/node/enabled") {
|
||||
if (msg.types) {
|
||||
info = RED.nodes.getNodeSet(msg.id);
|
||||
if (info.added) {
|
||||
RED.nodes.enableNodeSet(msg.id);
|
||||
typeList = "<ul><li>"+msg.types.join("</li><li>")+"</li></ul>";
|
||||
RED.notify(RED._("palette.event.nodeEnabled", {count:msg.types.length})+typeList,"success");
|
||||
} else {
|
||||
$.get('nodes/'+msg.id, function(data) {
|
||||
appendNodeConfig(data);
|
||||
typeList = "<ul><li>"+msg.types.join("</li><li>")+"</li></ul>";
|
||||
RED.notify(RED._("palette.event.nodeAdded", {count:msg.types.length})+typeList,"success");
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (topic == "notification/node/disabled") {
|
||||
if (msg.types) {
|
||||
RED.nodes.disableNodeSet(msg.id);
|
||||
typeList = "<ul><li>"+msg.types.join("</li><li>")+"</li></ul>";
|
||||
RED.notify(RED._("palette.event.nodeDisabled", {count:msg.types.length})+typeList,"success");
|
||||
}
|
||||
} else if (topic == "node/upgraded") {
|
||||
RED.notify(RED._("palette.event.nodeUpgraded", {module:msg.module,version:msg.version}),"success");
|
||||
RED.nodes.registry.setModulePendingUpdated(msg.module,msg.version);
|
||||
}
|
||||
// Refresh flow library to ensure any examples are updated
|
||||
RED.library.loadFlowLibrary();
|
||||
});
|
||||
}
|
||||
|
||||
function showAbout() {
|
||||
$.get('red/about', function(data) {
|
||||
var aboutHeader = '<div style="text-align:center;">'+
|
||||
@@ -176,6 +381,15 @@
|
||||
|
||||
function loadEditor() {
|
||||
var menuOptions = [];
|
||||
if (RED.settings.theme("projects.enabled",false)) {
|
||||
menuOptions.push({id:"menu-item-projects-menu",label:"Projects",options:[
|
||||
{id:"menu-item-projects-new",label:"New",disabled:false,onselect:"core:new-project"},
|
||||
{id:"menu-item-projects-open",label:"Open",disabled:false,onselect:"core:open-project"},
|
||||
{id:"menu-item-projects-settings",label:"Project Settings",disabled:false,onselect:"core:show-project-settings"}
|
||||
]});
|
||||
}
|
||||
|
||||
|
||||
menuOptions.push({id:"menu-item-view-menu",label:RED._("menu.label.view.view"),options:[
|
||||
// {id:"menu-item-view-show-grid",setting:"view-show-grid",label:RED._("menu.label.view.showGrid"),toggle:true,onselect:"core:toggle-show-grid"},
|
||||
// {id:"menu-item-view-snap-grid",setting:"view-snap-grid",label:RED._("menu.label.view.snapGrid"),toggle:true,onselect:"core:toggle-snap-grid"},
|
||||
@@ -219,12 +433,12 @@
|
||||
menuOptions.push(null);
|
||||
}
|
||||
|
||||
menuOptions.push({id:"menu-item-user-settings",label:RED._("menu.label.userSettings"),onselect:"core:show-user-settings"});
|
||||
menuOptions.push({id:"menu-item-user-settings",label:RED._("menu.label.settings"),onselect:"core:show-user-settings"});
|
||||
menuOptions.push(null);
|
||||
|
||||
menuOptions.push({id:"menu-item-keyboard-shortcuts",label:RED._("menu.label.keyboardShortcuts"),onselect:"core:show-help"});
|
||||
menuOptions.push({id:"menu-item-help",
|
||||
label: RED.settings.theme("menu.menu-item-help.label","Node-RED website"),
|
||||
label: RED.settings.theme("menu.menu-item-help.label",RED._("menu.label.help")),
|
||||
href: RED.settings.theme("menu.menu-item-help.url","http://nodered.org/docs")
|
||||
});
|
||||
menuOptions.push({id:"menu-item-node-red-version", label:"v"+RED.settings.version, onselect: "core:show-about" });
|
||||
@@ -238,9 +452,18 @@
|
||||
RED.palette.init();
|
||||
if (RED.settings.theme('palette.editable') !== false) {
|
||||
RED.palette.editor.init();
|
||||
} else {
|
||||
console.log("Palette editor disabled");
|
||||
}
|
||||
|
||||
RED.sidebar.init();
|
||||
|
||||
if (RED.settings.theme("projects.enabled",false)) {
|
||||
RED.projects.init();
|
||||
} else {
|
||||
console.log("Projects disabled");
|
||||
}
|
||||
|
||||
RED.subflow.init();
|
||||
RED.workspaces.init();
|
||||
RED.clipboard.init();
|
||||
@@ -251,6 +474,7 @@
|
||||
RED.menu.init({id:"btn-sidemenu",options: menuOptions});
|
||||
|
||||
RED.deploy.init(RED.settings.theme("deployButton",null));
|
||||
RED.notifications.init();
|
||||
|
||||
RED.actions.add("core:show-about", showAbout);
|
||||
RED.nodes.init();
|
||||
|
||||
@@ -40,6 +40,16 @@ RED.nodes = (function() {
|
||||
var nodeSets = {};
|
||||
var typeToId = {};
|
||||
var nodeDefinitions = {};
|
||||
var iconSets = {};
|
||||
|
||||
nodeDefinitions['tab'] = {
|
||||
defaults: {
|
||||
label: {value:""},
|
||||
disabled: {value: false},
|
||||
info: {value: ""}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var exports = {
|
||||
setModulePendingUpdated: function(module,version) {
|
||||
@@ -161,6 +171,12 @@ RED.nodes = (function() {
|
||||
},
|
||||
getNodeType: function(nt) {
|
||||
return nodeDefinitions[nt];
|
||||
},
|
||||
setIconSets: function(sets) {
|
||||
iconSets = sets;
|
||||
},
|
||||
getIconSets: function() {
|
||||
return iconSets;
|
||||
}
|
||||
};
|
||||
return exports;
|
||||
@@ -256,10 +272,19 @@ RED.nodes = (function() {
|
||||
if (updatedConfigNode) {
|
||||
RED.workspaces.refresh();
|
||||
}
|
||||
try {
|
||||
if (node._def.oneditdelete) {
|
||||
node._def.oneditdelete.call(node);
|
||||
}
|
||||
} catch(err) {
|
||||
console.log("oneditdelete",node.id,node.type,err.toString());
|
||||
}
|
||||
RED.events.emit('nodes:remove',node);
|
||||
}
|
||||
}
|
||||
if (node && node._def.onremove) {
|
||||
// Deprecated: never documented but used by some early nodes
|
||||
console.log("Deprecated API warning: node type ",node.type," has an onremove function - should be oneditremove - please report");
|
||||
node._def.onremove.call(n);
|
||||
}
|
||||
return {links:removedLinks,nodes:removedNodes};
|
||||
@@ -274,14 +299,7 @@ RED.nodes = (function() {
|
||||
|
||||
function addWorkspace(ws) {
|
||||
workspaces[ws.id] = ws;
|
||||
ws._def = {
|
||||
defaults: {
|
||||
label: {value:""},
|
||||
disabled: {value: false},
|
||||
info: {value: ""}
|
||||
}
|
||||
};
|
||||
|
||||
ws._def = RED.nodes.getType('tab');
|
||||
workspacesOrder.push(ws.id);
|
||||
}
|
||||
function getWorkspace(id) {
|
||||
@@ -337,7 +355,7 @@ RED.nodes = (function() {
|
||||
RED.nodes.registerType("subflow:"+sf.id, {
|
||||
defaults:{name:{value:""}},
|
||||
info: sf.info,
|
||||
icon:"subflow.png",
|
||||
icon: function() { return sf.icon||"subflow.png" },
|
||||
category: "subflows",
|
||||
inputs: sf.in.length,
|
||||
outputs: sf.out.length,
|
||||
@@ -473,7 +491,9 @@ RED.nodes = (function() {
|
||||
for (var j=0;j<wires.length;j++) {
|
||||
var w = wires[j];
|
||||
if (w.target.type != "subflow") {
|
||||
node.wires[w.sourcePort].push(w.target.id);
|
||||
if (w.sourcePort < node.wires.length) {
|
||||
node.wires[w.sourcePort].push(w.target.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -483,6 +503,12 @@ RED.nodes = (function() {
|
||||
if (n.outputs > 0 && n.outputLabels && !/^\s*$/.test(n.outputLabels.join(""))) {
|
||||
node.outputLabels = n.outputLabels.slice();
|
||||
}
|
||||
if ((!n._def.defaults || !n._def.defaults.hasOwnProperty("icon")) && n.icon) {
|
||||
var defIcon = RED.utils.getDefaultNodeIcon(n._def, n);
|
||||
if (n.icon !== defIcon.module+"/"+defIcon.file) {
|
||||
node.icon = n.icon;
|
||||
}
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
@@ -526,7 +552,11 @@ RED.nodes = (function() {
|
||||
if (node.out.length > 0 && n.outputLabels && !/^\s*$/.test(n.outputLabels.join(""))) {
|
||||
node.outputLabels = n.outputLabels.slice();
|
||||
}
|
||||
|
||||
if (n.icon) {
|
||||
if (n.icon !== "node-red/subflow.png") {
|
||||
node.icon = n.icon;
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
@@ -699,7 +729,9 @@ RED.nodes = (function() {
|
||||
if (!$.isArray(newNodes)) {
|
||||
newNodes = [newNodes];
|
||||
}
|
||||
var isInitialLoad = false;
|
||||
if (!initialLoad) {
|
||||
isInitialLoad = true;
|
||||
initialLoad = JSON.parse(JSON.stringify(newNodes));
|
||||
}
|
||||
var unknownTypes = [];
|
||||
@@ -720,10 +752,10 @@ RED.nodes = (function() {
|
||||
}
|
||||
|
||||
}
|
||||
if (unknownTypes.length > 0) {
|
||||
if (!isInitialLoad && unknownTypes.length > 0) {
|
||||
var typeList = "<ul><li>"+unknownTypes.join("</li><li>")+"</li></ul>";
|
||||
var type = "type"+(unknownTypes.length > 1?"s":"");
|
||||
RED.notify("<strong>"+RED._("clipboard.importUnrecognised",{count:unknownTypes.length})+"</strong>"+typeList,"error",false,10000);
|
||||
RED.notify("<p>"+RED._("clipboard.importUnrecognised",{count:unknownTypes.length})+"</p>"+typeList,"error",false,10000);
|
||||
}
|
||||
|
||||
var activeWorkspace = RED.workspaces.active();
|
||||
@@ -817,7 +849,7 @@ RED.nodes = (function() {
|
||||
|
||||
// Add a tab if there isn't one there already
|
||||
if (defaultWorkspace == null) {
|
||||
defaultWorkspace = { type:"tab", id:getID(), label:RED._('workspace.defaultName',{number:1})};
|
||||
defaultWorkspace = { type:"tab", id:getID(), disabled: false, info:"", label:RED._('workspace.defaultName',{number:1})};
|
||||
addWorkspace(defaultWorkspace);
|
||||
RED.workspaces.add(defaultWorkspace);
|
||||
new_workspaces.push(defaultWorkspace);
|
||||
@@ -870,7 +902,7 @@ RED.nodes = (function() {
|
||||
|
||||
}
|
||||
|
||||
if (!existingConfigNode) { //} || !compareNodes(existingConfigNode,n,true) || existingConfigNode._def.exclusive || existingConfigNode.z !== n.z) {
|
||||
if (!existingConfigNode || existingConfigNode._def.exclusive) { //} || !compareNodes(existingConfigNode,n,true) || existingConfigNode.z !== n.z) {
|
||||
configNode = {id:n.id, z:n.z, type:n.type, users:[], _config:{}};
|
||||
for (d in def.defaults) {
|
||||
if (def.defaults.hasOwnProperty(d)) {
|
||||
@@ -913,6 +945,7 @@ RED.nodes = (function() {
|
||||
wires:n.wires,
|
||||
inputLabels: n.inputLabels,
|
||||
outputLabels: n.outputLabels,
|
||||
icon: n.icon,
|
||||
changed:false,
|
||||
_config:{}
|
||||
};
|
||||
@@ -981,6 +1014,13 @@ RED.nodes = (function() {
|
||||
set: registry.getNodeSet("node-red/unknown")
|
||||
};
|
||||
node.users = [];
|
||||
// This is a config node, so delete the default
|
||||
// non-config node properties
|
||||
delete node.x;
|
||||
delete node.y;
|
||||
delete node.wires;
|
||||
delete node.inputLabels;
|
||||
delete node.outputLabels;
|
||||
}
|
||||
var orig = {};
|
||||
for (var p in n) {
|
||||
@@ -995,6 +1035,11 @@ RED.nodes = (function() {
|
||||
if (node._def.category != "config") {
|
||||
node.inputs = n.inputs||node._def.inputs;
|
||||
node.outputs = n.outputs||node._def.outputs;
|
||||
// If 'wires' is longer than outputs, clip wires
|
||||
if (node.hasOwnProperty('wires') && node.wires.length > node.outputs) {
|
||||
console.log("Warning: node.wires longer than node.outputs - trimming wires:",node.id," wires:",node.wires.length," outputs:",node.outputs);
|
||||
node.wires = node.wires.slice(0,node.outputs);
|
||||
}
|
||||
for (d in node._def.defaults) {
|
||||
if (node._def.defaults.hasOwnProperty(d)) {
|
||||
node[d] = n[d];
|
||||
@@ -1016,7 +1061,9 @@ RED.nodes = (function() {
|
||||
addNode(node);
|
||||
RED.editor.validateNode(node);
|
||||
node_map[n.id] = node;
|
||||
if (node._def.category != "config") {
|
||||
// If an 'unknown' config node, it will not have been caught by the
|
||||
// proper config node handling, so needs adding to new_nodes here
|
||||
if (node.type === "unknown" || node._def.category !== "config") {
|
||||
new_nodes.push(node);
|
||||
}
|
||||
}
|
||||
@@ -1198,12 +1245,13 @@ RED.nodes = (function() {
|
||||
RED.workspaces.remove(workspaces[id]);
|
||||
});
|
||||
defaultWorkspace = null;
|
||||
|
||||
RED.nodes.dirty(true);
|
||||
initialLoad = null;
|
||||
RED.nodes.dirty(false);
|
||||
RED.view.redraw(true);
|
||||
RED.palette.refresh();
|
||||
RED.workspaces.refresh();
|
||||
RED.sidebar.config.refresh();
|
||||
RED.sidebar.info.refresh();
|
||||
|
||||
// var node_defs = {};
|
||||
// var nodes = [];
|
||||
@@ -1270,6 +1318,9 @@ RED.nodes = (function() {
|
||||
enableNodeSet: registry.enableNodeSet,
|
||||
disableNodeSet: registry.disableNodeSet,
|
||||
|
||||
setIconSets: registry.setIconSets,
|
||||
getIconSets: registry.getIconSets,
|
||||
|
||||
registerType: registry.registerNodeType,
|
||||
getType: registry.getNodeType,
|
||||
convertNode: convertNode,
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
RED.settings = (function () {
|
||||
|
||||
var loadedSettings = {};
|
||||
var userSettings = {};
|
||||
var settingsDirty = false;
|
||||
var pendingSave;
|
||||
|
||||
var hasLocalStorage = function () {
|
||||
try {
|
||||
@@ -31,7 +34,12 @@ RED.settings = (function () {
|
||||
if (!hasLocalStorage()) {
|
||||
return;
|
||||
}
|
||||
localStorage.setItem(key, JSON.stringify(value));
|
||||
if (key === "auth-tokens") {
|
||||
localStorage.setItem(key, JSON.stringify(value));
|
||||
} else {
|
||||
userSettings[key] = value;
|
||||
saveUserSettings();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -44,14 +52,23 @@ RED.settings = (function () {
|
||||
if (!hasLocalStorage()) {
|
||||
return undefined;
|
||||
}
|
||||
return JSON.parse(localStorage.getItem(key));
|
||||
if (key === "auth-tokens") {
|
||||
return JSON.parse(localStorage.getItem(key));
|
||||
} else {
|
||||
return userSettings[key];
|
||||
}
|
||||
};
|
||||
|
||||
var remove = function (key) {
|
||||
if (!hasLocalStorage()) {
|
||||
return;
|
||||
}
|
||||
localStorage.removeItem(key);
|
||||
if (key === "auth-tokens") {
|
||||
localStorage.removeItem(key);
|
||||
} else {
|
||||
delete userSettings[key];
|
||||
saveUserSettings();
|
||||
}
|
||||
};
|
||||
|
||||
var setProperties = function(data) {
|
||||
@@ -68,6 +85,10 @@ RED.settings = (function () {
|
||||
loadedSettings = data;
|
||||
};
|
||||
|
||||
var setUserSettings = function(data) {
|
||||
userSettings = data;
|
||||
}
|
||||
|
||||
var init = function (done) {
|
||||
var accessTokenMatch = /[?&]access_token=(.*?)(?:$|&)/.exec(window.location.search);
|
||||
if (accessTokenMatch) {
|
||||
@@ -106,7 +127,7 @@ RED.settings = (function () {
|
||||
RED.settings.remove("auth-tokens");
|
||||
}
|
||||
console.log("Node-RED: " + data.version);
|
||||
done();
|
||||
loadUserSettings(done);
|
||||
},
|
||||
error: function(jqXHR,textStatus,errorThrown) {
|
||||
if (jqXHR.status === 401) {
|
||||
@@ -115,12 +136,52 @@ RED.settings = (function () {
|
||||
}
|
||||
RED.user.login(function() { load(done); });
|
||||
} else {
|
||||
console.log("Unexpected error:",jqXHR.status,textStatus);
|
||||
console.log("Unexpected error loading settings:",jqXHR.status,textStatus);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function loadUserSettings(done) {
|
||||
$.ajax({
|
||||
headers: {
|
||||
"Accept": "application/json"
|
||||
},
|
||||
dataType: "json",
|
||||
cache: false,
|
||||
url: 'settings/user',
|
||||
success: function (data) {
|
||||
setUserSettings(data);
|
||||
done();
|
||||
},
|
||||
error: function(jqXHR,textStatus,errorThrown) {
|
||||
console.log("Unexpected error loading user settings:",jqXHR.status,textStatus);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function saveUserSettings() {
|
||||
if (RED.user.hasPermission("settings.write")) {
|
||||
if (pendingSave) {
|
||||
clearTimeout(pendingSave);
|
||||
}
|
||||
pendingSave = setTimeout(function() {
|
||||
pendingSave = null;
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
contentType: 'application/json',
|
||||
url: 'settings/user',
|
||||
data: JSON.stringify(userSettings),
|
||||
success: function (data) {
|
||||
},
|
||||
error: function(jqXHR,textStatus,errorThrown) {
|
||||
console.log("Unexpected error saving user settings:",jqXHR.status,textStatus);
|
||||
}
|
||||
});
|
||||
},300);
|
||||
}
|
||||
}
|
||||
|
||||
function theme(property,defaultValue) {
|
||||
if (!RED.settings.editorTheme) {
|
||||
return defaultValue;
|
||||
@@ -143,10 +204,10 @@ RED.settings = (function () {
|
||||
return {
|
||||
init: init,
|
||||
load: load,
|
||||
loadUserSettings: loadUserSettings,
|
||||
set: set,
|
||||
get: get,
|
||||
remove: remove,
|
||||
theme: theme
|
||||
}
|
||||
})
|
||||
();
|
||||
})();
|
||||
|
||||
@@ -203,7 +203,8 @@ RED.clipboard = (function() {
|
||||
var nodes = null;
|
||||
if (type === 'export-range-selected') {
|
||||
var selection = RED.view.selection();
|
||||
nodes = RED.nodes.createExportableNodeSet(selection.nodes);
|
||||
// Don't include the subflow meta-port nodes in the exported selection
|
||||
nodes = RED.nodes.createExportableNodeSet(selection.nodes.filter(function(n) { return n.type !== 'subflow'}));
|
||||
} else if (type === 'export-range-flow') {
|
||||
var activeWorkspace = RED.workspaces.active();
|
||||
nodes = RED.nodes.filterNodes({z:activeWorkspace});
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
addLabel = 'add';
|
||||
}
|
||||
}
|
||||
$('<a href="#" class="editor-button editor-button-small" style="margin-top: 4px;"><i class="fa fa-plus"></i> '+addLabel+'</a>')
|
||||
$('<a href="#" class="editor-button editor-button-small red-ui-editableList-addButton" style="margin-top: 4px;"><i class="fa fa-plus"></i> '+addLabel+'</a>')
|
||||
.appendTo(this.topContainer)
|
||||
.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
@@ -85,7 +85,7 @@
|
||||
if (this.element.css("position") === "absolute") {
|
||||
["top","left","bottom","right"].forEach(function(s) {
|
||||
var v = that.element.css(s);
|
||||
if (s!=="auto" && s!=="") {
|
||||
if (v!=="auto" && v!=="") {
|
||||
that.topContainer.css(s,v);
|
||||
that.uiContainer.css(s,"0");
|
||||
that.element.css(s,'auto');
|
||||
@@ -116,6 +116,11 @@
|
||||
this.uiContainer.css("minHeight",minHeight);
|
||||
this.element.css("minHeight",0);
|
||||
}
|
||||
var maxHeight = this.element.css("maxHeight");
|
||||
if (maxHeight !== '0px') {
|
||||
this.uiContainer.css("maxHeight",maxHeight);
|
||||
this.element.css("maxHeight",null);
|
||||
}
|
||||
if (this.options.height !== 'auto') {
|
||||
this.uiContainer.css("overflow-y","scroll");
|
||||
if (!isNaN(this.options.height)) {
|
||||
|
||||
@@ -23,7 +23,7 @@ RED.popover = (function() {
|
||||
},
|
||||
"small": {
|
||||
top: 5,
|
||||
leftRight: 8,
|
||||
leftRight: 17,
|
||||
leftLeft: 16
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,7 @@ RED.popover = (function() {
|
||||
var trigger = options.trigger;
|
||||
var content = options.content;
|
||||
var delay = options.delay;
|
||||
var autoClose = options.autoClose;
|
||||
var width = options.width||"auto";
|
||||
var size = options.size||"default";
|
||||
if (!deltaSizes[size]) {
|
||||
@@ -43,7 +44,7 @@ RED.popover = (function() {
|
||||
var active;
|
||||
var div;
|
||||
|
||||
var openPopup = function() {
|
||||
var openPopup = function(instant) {
|
||||
if (active) {
|
||||
div = $('<div class="red-ui-popover red-ui-popover-'+direction+'"></div>').appendTo("body");
|
||||
if (size !== "default") {
|
||||
@@ -62,7 +63,6 @@ RED.popover = (function() {
|
||||
var targetPos = target.offset();
|
||||
var targetWidth = target.width();
|
||||
var targetHeight = target.height();
|
||||
|
||||
var divHeight = div.height();
|
||||
var divWidth = div.width();
|
||||
if (direction === 'right') {
|
||||
@@ -70,23 +70,29 @@ RED.popover = (function() {
|
||||
} else if (direction === 'left') {
|
||||
div.css({top: targetPos.top+targetHeight/2-divHeight/2-deltaSizes[size].top,left:targetPos.left-deltaSizes[size].leftLeft-divWidth});
|
||||
}
|
||||
|
||||
div.fadeIn("fast");
|
||||
if (instant) {
|
||||
div.show();
|
||||
} else {
|
||||
div.fadeIn("fast");
|
||||
}
|
||||
}
|
||||
}
|
||||
var closePopup = function() {
|
||||
var closePopup = function(instant) {
|
||||
if (!active) {
|
||||
if (div) {
|
||||
div.fadeOut("fast",function() {
|
||||
if (instant) {
|
||||
$(this).remove();
|
||||
});
|
||||
} else {
|
||||
div.fadeOut("fast",function() {
|
||||
$(this).remove();
|
||||
});
|
||||
}
|
||||
div = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (trigger === 'hover') {
|
||||
|
||||
target.on('mouseenter',function(e) {
|
||||
clearTimeout(timer);
|
||||
active = true;
|
||||
@@ -110,18 +116,26 @@ RED.popover = (function() {
|
||||
openPopup();
|
||||
}
|
||||
});
|
||||
} else if (autoClose) {
|
||||
setTimeout(function() {
|
||||
active = false;
|
||||
closePopup();
|
||||
},autoClose);
|
||||
}
|
||||
var res = {
|
||||
setContent: function(_content) {
|
||||
content = _content;
|
||||
return res;
|
||||
},
|
||||
open: function () {
|
||||
open: function (instant) {
|
||||
active = true;
|
||||
openPopup();
|
||||
openPopup(instant);
|
||||
return res;
|
||||
},
|
||||
close: function () {
|
||||
close: function (instant) {
|
||||
active = false;
|
||||
closePopup();
|
||||
closePopup(instant);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
|
||||
@@ -17,11 +17,31 @@
|
||||
RED.stack = (function() {
|
||||
function createStack(options) {
|
||||
var container = options.container;
|
||||
|
||||
container.addClass("red-ui-stack");
|
||||
var contentHeight = 0;
|
||||
var entries = [];
|
||||
|
||||
var visible = true;
|
||||
// TODO: make this a singleton function - and watch out for stacks no longer
|
||||
// in the DOM
|
||||
var resizeStack = function() {
|
||||
if (entries.length > 0) {
|
||||
var headerHeight = 0;
|
||||
entries.forEach(function(entry) {
|
||||
headerHeight += entry.header.outerHeight();
|
||||
});
|
||||
|
||||
var height = container.innerHeight();
|
||||
contentHeight = height - headerHeight - (entries.length-1);
|
||||
entries.forEach(function(e) {
|
||||
e.contentWrap.height(contentHeight);
|
||||
});
|
||||
}
|
||||
}
|
||||
if (options.fill && options.singleExpanded) {
|
||||
$(window).resize(resizeStack);
|
||||
$(window).focus(resizeStack);
|
||||
}
|
||||
return {
|
||||
add: function(entry) {
|
||||
entries.push(entry);
|
||||
@@ -30,7 +50,12 @@ RED.stack = (function() {
|
||||
entry.container.hide();
|
||||
}
|
||||
var header = $('<div class="palette-header"></div>').appendTo(entry.container);
|
||||
entry.content = $('<div></div>').appendTo(entry.container);
|
||||
entry.header = header;
|
||||
entry.contentWrap = $('<div></div>',{style:"position:relative"}).appendTo(entry.container);
|
||||
if (options.fill) {
|
||||
entry.contentWrap.css("height",contentHeight);
|
||||
}
|
||||
entry.content = $('<div></div>').appendTo(entry.contentWrap);
|
||||
if (entry.collapsible !== false) {
|
||||
header.click(function() {
|
||||
if (options.singleExpanded) {
|
||||
@@ -49,11 +74,13 @@ RED.stack = (function() {
|
||||
var icon = $('<i class="fa fa-angle-down"></i>').appendTo(header);
|
||||
|
||||
if (entry.expanded) {
|
||||
entry.container.addClass("palette-category-expanded");
|
||||
icon.addClass("expanded");
|
||||
} else {
|
||||
entry.content.hide();
|
||||
entry.contentWrap.hide();
|
||||
}
|
||||
} else {
|
||||
$('<i style="opacity: 0.5;" class="fa fa-angle-down expanded"></i>').appendTo(header);
|
||||
header.css("cursor","default");
|
||||
}
|
||||
entry.title = $('<span></span>').html(entry.title).appendTo(header);
|
||||
@@ -74,24 +101,35 @@ RED.stack = (function() {
|
||||
if (entry.onexpand) {
|
||||
entry.onexpand.call(entry);
|
||||
}
|
||||
if (options.singleExpanded) {
|
||||
entries.forEach(function(e) {
|
||||
if (e !== entry) {
|
||||
e.collapse();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
icon.addClass("expanded");
|
||||
entry.content.slideDown(200);
|
||||
entry.container.addClass("palette-category-expanded");
|
||||
entry.contentWrap.slideDown(200);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
entry.collapse = function() {
|
||||
if (entry.isExpanded()) {
|
||||
icon.removeClass("expanded");
|
||||
entry.content.slideUp(200);
|
||||
entry.container.removeClass("palette-category-expanded");
|
||||
entry.contentWrap.slideUp(200);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
entry.isExpanded = function() {
|
||||
return icon.hasClass("expanded");
|
||||
return entry.container.hasClass("palette-category-expanded");
|
||||
};
|
||||
|
||||
if (options.fill && options.singleExpanded) {
|
||||
resizeStack();
|
||||
}
|
||||
return entry;
|
||||
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
@@ -108,9 +146,13 @@ RED.stack = (function() {
|
||||
entry.container.show();
|
||||
});
|
||||
return this;
|
||||
},
|
||||
resize: function() {
|
||||
if (resizeStack) {
|
||||
resizeStack();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
this.uiSelect = this.elementDiv.wrap( "<div>" ).parent();
|
||||
var attrStyle = this.element.attr('style');
|
||||
var m;
|
||||
if ((m = /width\s*:\s*(\d+(%|px))/i.exec(attrStyle)) !== null) {
|
||||
if ((m = /width\s*:\s*(calc\s*\(.*\)|\d+(%|px))/i.exec(attrStyle)) !== null) {
|
||||
this.element.css('width','100%');
|
||||
this.uiSelect.width(m[1]);
|
||||
this.uiWidth = null;
|
||||
@@ -116,7 +116,9 @@
|
||||
this.options.types = this.options.types||Object.keys(allOptions);
|
||||
|
||||
this.selectTrigger = $('<button tabindex="0"></button>').prependTo(this.uiSelect);
|
||||
$('<i class="fa fa-sort-desc"></i>').appendTo(this.selectTrigger);
|
||||
if (this.options.types.length > 1) {
|
||||
$('<i class="fa fa-sort-desc"></i>').appendTo(this.selectTrigger);
|
||||
}
|
||||
this.selectLabel = $('<span></span>').appendTo(this.selectTrigger);
|
||||
|
||||
this.types(this.options.types);
|
||||
@@ -354,10 +356,27 @@
|
||||
return this.element.val();
|
||||
} else {
|
||||
if (this.typeMap[this.propertyType].options) {
|
||||
if (this.typeMap[this.propertyType].options.indexOf(value) === -1) {
|
||||
value = "";
|
||||
var validValue = false;
|
||||
var label;
|
||||
for (var i=0;i<this.typeMap[this.propertyType].options.length;i++) {
|
||||
var op = this.typeMap[this.propertyType].options[i];
|
||||
if (typeof op === "string") {
|
||||
if (op === value) {
|
||||
label = value;
|
||||
validValue = true;
|
||||
break;
|
||||
}
|
||||
} else if (op.value === value) {
|
||||
label = op.label||op.value;
|
||||
validValue = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.optionSelectLabel.text(value);
|
||||
if (!validValue) {
|
||||
value = "";
|
||||
label = "";
|
||||
}
|
||||
this.optionSelectLabel.text(label);
|
||||
}
|
||||
this.element.val(value);
|
||||
this.element.trigger('change',this.type(),value);
|
||||
@@ -394,11 +413,31 @@
|
||||
that.value(v);
|
||||
});
|
||||
var currentVal = this.element.val();
|
||||
if (opt.options.indexOf(currentVal) !== -1) {
|
||||
this.optionSelectLabel.text(currentVal);
|
||||
} else {
|
||||
this.value(opt.options[0]);
|
||||
var validValue = false;
|
||||
var op;
|
||||
for (var i=0;i<opt.options.length;i++) {
|
||||
op = opt.options[i];
|
||||
if (typeof op === "string") {
|
||||
if (op === currentVal) {
|
||||
this.optionSelectLabel.text(currentVal);
|
||||
validValue = true;
|
||||
break;
|
||||
}
|
||||
} else if (op.value === currentVal) {
|
||||
this.optionSelectLabel.text(op.label||op.value);
|
||||
validValue = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!validValue) {
|
||||
op = opt.options[0];
|
||||
if (typeof op === "string") {
|
||||
this.value(op);
|
||||
} else {
|
||||
this.value(op.value);
|
||||
}
|
||||
}
|
||||
console.log(validValue);
|
||||
}
|
||||
} else {
|
||||
if (this.optionMenu) {
|
||||
|
||||
@@ -97,113 +97,6 @@ RED.deploy = (function() {
|
||||
|
||||
RED.actions.add("core:deploy-flows",save);
|
||||
|
||||
$( "#node-dialog-confirm-deploy" ).dialog({
|
||||
title: RED._('deploy.confirm.button.confirm'),
|
||||
modal: true,
|
||||
autoOpen: false,
|
||||
width: 550,
|
||||
height: "auto",
|
||||
buttons: [
|
||||
{
|
||||
text: RED._("common.label.cancel"),
|
||||
click: function() {
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "node-dialog-confirm-deploy-review",
|
||||
text: RED._("deploy.confirm.button.review"),
|
||||
class: "primary disabled",
|
||||
click: function() {
|
||||
if (!$("#node-dialog-confirm-deploy-review").hasClass('disabled')) {
|
||||
RED.diff.showRemoteDiff();
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "node-dialog-confirm-deploy-merge",
|
||||
text: RED._("deploy.confirm.button.merge"),
|
||||
class: "primary disabled",
|
||||
click: function() {
|
||||
RED.diff.mergeDiff(currentDiff);
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "node-dialog-confirm-deploy-deploy",
|
||||
text: RED._("deploy.confirm.button.confirm"),
|
||||
class: "primary",
|
||||
click: function() {
|
||||
|
||||
var ignoreChecked = $( "#node-dialog-confirm-deploy-hide" ).prop("checked");
|
||||
if (ignoreChecked) {
|
||||
ignoreDeployWarnings[$( "#node-dialog-confirm-deploy-type" ).val()] = true;
|
||||
}
|
||||
save(true,/conflict/.test($("#node-dialog-confirm-deploy-type" ).val()));
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "node-dialog-confirm-deploy-overwrite",
|
||||
text: RED._("deploy.confirm.button.overwrite"),
|
||||
class: "primary",
|
||||
click: function() {
|
||||
save(true,/conflict/.test($("#node-dialog-confirm-deploy-type" ).val()));
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
}
|
||||
],
|
||||
create: function() {
|
||||
$("#node-dialog-confirm-deploy").parent().find("div.ui-dialog-buttonpane")
|
||||
.prepend('<div style="height:0; vertical-align: middle; display:inline-block; margin-top: 13px; float:left;">'+
|
||||
'<input style="vertical-align:top;" type="checkbox" id="node-dialog-confirm-deploy-hide">'+
|
||||
'<label style="display:inline;" for="node-dialog-confirm-deploy-hide"> do not warn about this again</label>'+
|
||||
'<input type="hidden" id="node-dialog-confirm-deploy-type">'+
|
||||
'</div>');
|
||||
},
|
||||
open: function() {
|
||||
var deployType = $("#node-dialog-confirm-deploy-type" ).val();
|
||||
if (/conflict/.test(deployType)) {
|
||||
$( "#node-dialog-confirm-deploy" ).dialog('option','title', RED._('deploy.confirm.button.review'));
|
||||
$("#node-dialog-confirm-deploy-deploy").hide();
|
||||
$("#node-dialog-confirm-deploy-review").addClass('disabled').show();
|
||||
$("#node-dialog-confirm-deploy-merge").addClass('disabled').show();
|
||||
$("#node-dialog-confirm-deploy-overwrite").toggle(deployType === "deploy-conflict");
|
||||
currentDiff = null;
|
||||
$("#node-dialog-confirm-deploy-conflict-checking").show();
|
||||
$("#node-dialog-confirm-deploy-conflict-auto-merge").hide();
|
||||
$("#node-dialog-confirm-deploy-conflict-manual-merge").hide();
|
||||
|
||||
var now = Date.now();
|
||||
RED.diff.getRemoteDiff(function(diff) {
|
||||
var ellapsed = Math.max(1000 - (Date.now()-now), 0);
|
||||
currentDiff = diff;
|
||||
setTimeout(function() {
|
||||
$("#node-dialog-confirm-deploy-conflict-checking").hide();
|
||||
var d = Object.keys(diff.conflicts);
|
||||
if (d.length === 0) {
|
||||
$("#node-dialog-confirm-deploy-conflict-auto-merge").show();
|
||||
$("#node-dialog-confirm-deploy-merge").removeClass('disabled')
|
||||
} else {
|
||||
$("#node-dialog-confirm-deploy-conflict-manual-merge").show();
|
||||
}
|
||||
$("#node-dialog-confirm-deploy-review").removeClass('disabled')
|
||||
},ellapsed);
|
||||
})
|
||||
|
||||
|
||||
$("#node-dialog-confirm-deploy-hide").parent().hide();
|
||||
} else {
|
||||
$( "#node-dialog-confirm-deploy" ).dialog('option','title', RED._('deploy.confirm.button.confirm'));
|
||||
$("#node-dialog-confirm-deploy-deploy").show();
|
||||
$("#node-dialog-confirm-deploy-overwrite").hide();
|
||||
$("#node-dialog-confirm-deploy-review").hide();
|
||||
$("#node-dialog-confirm-deploy-merge").hide();
|
||||
$("#node-dialog-confirm-deploy-hide").parent().show();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
RED.events.on('nodes:change',function(state) {
|
||||
if (state.dirty) {
|
||||
@@ -224,24 +117,30 @@ RED.deploy = (function() {
|
||||
if (currentRev === null || deployInflight || currentRev === msg.revision) {
|
||||
return;
|
||||
}
|
||||
var message = $('<div>'+RED._('deploy.confirm.backgroundUpdate')+
|
||||
'<br><br><div class="ui-dialog-buttonset">'+
|
||||
'<button>'+RED._('deploy.confirm.button.ignore')+'</button>'+
|
||||
'<button class="primary">'+RED._('deploy.confirm.button.review')+'</button>'+
|
||||
'</div></div>');
|
||||
$(message.find('button')[0]).click(function(evt) {
|
||||
evt.preventDefault();
|
||||
activeNotifyMessage.close();
|
||||
activeNotifyMessage = null;
|
||||
})
|
||||
$(message.find('button')[1]).click(function(evt) {
|
||||
evt.preventDefault();
|
||||
activeNotifyMessage.close();
|
||||
var nns = RED.nodes.createCompleteNodeSet();
|
||||
resolveConflict(nns,false);
|
||||
activeNotifyMessage = null;
|
||||
})
|
||||
activeNotifyMessage = RED.notify(message,null,true);
|
||||
var message = $('<p>').text(RED._('deploy.confirm.backgroundUpdate'));
|
||||
activeNotifyMessage = RED.notify(message,{
|
||||
modal: true,
|
||||
fixed: true,
|
||||
buttons: [
|
||||
{
|
||||
text: RED._('deploy.confirm.button.ignore'),
|
||||
click: function() {
|
||||
activeNotifyMessage.close();
|
||||
activeNotifyMessage = null;
|
||||
}
|
||||
},
|
||||
{
|
||||
text: RED._('deploy.confirm.button.review'),
|
||||
class: "primary",
|
||||
click: function() {
|
||||
activeNotifyMessage.close();
|
||||
var nns = RED.nodes.createCompleteNodeSet();
|
||||
resolveConflict(nns,false);
|
||||
activeNotifyMessage = null;
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -271,16 +170,99 @@ RED.deploy = (function() {
|
||||
}
|
||||
|
||||
function resolveConflict(currentNodes, activeDeploy) {
|
||||
$( "#node-dialog-confirm-deploy-config" ).hide();
|
||||
$( "#node-dialog-confirm-deploy-unknown" ).hide();
|
||||
$( "#node-dialog-confirm-deploy-unused" ).hide();
|
||||
$( "#node-dialog-confirm-deploy-conflict" ).show();
|
||||
$( "#node-dialog-confirm-deploy-type" ).val(activeDeploy?"deploy-conflict":"background-conflict");
|
||||
$( "#node-dialog-confirm-deploy" ).dialog( "open" );
|
||||
}
|
||||
var message = $('<div>');
|
||||
$('<p data-i18n="deploy.confirm.conflict"></p>').appendTo(message);
|
||||
var conflictCheck = $('<div id="node-dialog-confirm-deploy-conflict-checking" class="node-dialog-confirm-conflict-row">'+
|
||||
'<img src="red/images/spin.svg"/><div data-i18n="deploy.confirm.conflictChecking"></div>'+
|
||||
'</div>').appendTo(message);
|
||||
var conflictAutoMerge = $('<div class="node-dialog-confirm-conflict-row">'+
|
||||
'<i style="color: #3a3;" class="fa fa-check"></i><div data-i18n="deploy.confirm.conflictAutoMerge"></div>'+
|
||||
'</div>').hide().appendTo(message);
|
||||
var conflictManualMerge = $('<div id="node-dialog-confirm-deploy-conflict-manual-merge" class="node-dialog-confirm-conflict-row">'+
|
||||
'<i style="color: #999;" class="fa fa-exclamation"></i><div data-i18n="deploy.confirm.conflictManualMerge"></div>'+
|
||||
'</div>').hide().appendTo(message);
|
||||
|
||||
message.i18n();
|
||||
currentDiff = null;
|
||||
var buttons = [
|
||||
{
|
||||
text: RED._("common.label.cancel"),
|
||||
click: function() {
|
||||
conflictNotification.close();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "node-dialog-confirm-deploy-review",
|
||||
text: RED._("deploy.confirm.button.review"),
|
||||
class: "primary disabled",
|
||||
click: function() {
|
||||
if (!$("#node-dialog-confirm-deploy-review").hasClass('disabled')) {
|
||||
RED.diff.showRemoteDiff();
|
||||
conflictNotification.close();
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "node-dialog-confirm-deploy-merge",
|
||||
text: RED._("deploy.confirm.button.merge"),
|
||||
class: "primary disabled",
|
||||
click: function() {
|
||||
if (!$("#node-dialog-confirm-deploy-merge").hasClass('disabled')) {
|
||||
RED.diff.mergeDiff(currentDiff);
|
||||
conflictNotification.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
if (activeDeploy) {
|
||||
buttons.push({
|
||||
id: "node-dialog-confirm-deploy-overwrite",
|
||||
text: RED._("deploy.confirm.button.overwrite"),
|
||||
class: "primary",
|
||||
click: function() {
|
||||
save(true,activeDeploy);
|
||||
conflictNotification.close();
|
||||
}
|
||||
})
|
||||
}
|
||||
var conflictNotification = RED.notify(message,{
|
||||
modal: true,
|
||||
fixed: true,
|
||||
width: 600,
|
||||
buttons: buttons
|
||||
});
|
||||
|
||||
var now = Date.now();
|
||||
RED.diff.getRemoteDiff(function(diff) {
|
||||
var ellapsed = Math.max(1000 - (Date.now()-now), 0);
|
||||
currentDiff = diff;
|
||||
setTimeout(function() {
|
||||
conflictCheck.hide();
|
||||
var d = Object.keys(diff.conflicts);
|
||||
if (d.length === 0) {
|
||||
conflictAutoMerge.show();
|
||||
$("#node-dialog-confirm-deploy-merge").removeClass('disabled')
|
||||
} else {
|
||||
conflictManualMerge.show();
|
||||
}
|
||||
$("#node-dialog-confirm-deploy-review").removeClass('disabled')
|
||||
},ellapsed);
|
||||
})
|
||||
}
|
||||
function cropList(list) {
|
||||
if (list.length > 5) {
|
||||
var remainder = list.length - 5;
|
||||
list = list.slice(0,5);
|
||||
list.push(RED._("deploy.confirm.plusNMore",{count:remainder}));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
function save(skipValidation,force) {
|
||||
if (!$("#btn-deploy").hasClass("disabled")) {
|
||||
if (!RED.user.hasPermission("flows.write")) {
|
||||
RED.notify(RED._("user.errors.deploy"),"error");
|
||||
return;
|
||||
}
|
||||
if (!skipValidation) {
|
||||
var hasUnknown = false;
|
||||
var hasInvalid = false;
|
||||
@@ -310,39 +292,62 @@ RED.deploy = (function() {
|
||||
}
|
||||
});
|
||||
|
||||
$( "#node-dialog-confirm-deploy-config" ).hide();
|
||||
$( "#node-dialog-confirm-deploy-unknown" ).hide();
|
||||
$( "#node-dialog-confirm-deploy-unused" ).hide();
|
||||
$( "#node-dialog-confirm-deploy-conflict" ).hide();
|
||||
|
||||
var showWarning = false;
|
||||
|
||||
var notificationMessage;
|
||||
var notificationButtons = [];
|
||||
var notification;
|
||||
if (hasUnknown && !ignoreDeployWarnings.unknown) {
|
||||
showWarning = true;
|
||||
$( "#node-dialog-confirm-deploy-type" ).val("unknown");
|
||||
$( "#node-dialog-confirm-deploy-unknown" ).show();
|
||||
$( "#node-dialog-confirm-deploy-unknown-list" )
|
||||
.html("<li>"+unknownNodes.join("</li><li>")+"</li>");
|
||||
notificationMessage = "<p>"+RED._('deploy.confirm.unknown')+"</p>"+
|
||||
'<ul class="node-dialog-configm-deploy-list"><li>'+cropList(unknownNodes).join("</li><li>")+"</li></ul><p>"+
|
||||
RED._('deploy.confirm.confirm')+
|
||||
"</p>";
|
||||
|
||||
notificationButtons= [
|
||||
{
|
||||
id: "node-dialog-confirm-deploy-deploy",
|
||||
text: RED._("deploy.confirm.button.confirm"),
|
||||
class: "primary",
|
||||
click: function() {
|
||||
save(true);
|
||||
notification.close();
|
||||
}
|
||||
}
|
||||
];
|
||||
} else if (hasInvalid && !ignoreDeployWarnings.invalid) {
|
||||
showWarning = true;
|
||||
$( "#node-dialog-confirm-deploy-type" ).val("invalid");
|
||||
$( "#node-dialog-confirm-deploy-config" ).show();
|
||||
invalidNodes.sort(sortNodeInfo);
|
||||
$( "#node-dialog-confirm-deploy-invalid-list" )
|
||||
.html("<li>"+invalidNodes.map(function(A) { return (A.tab?"["+A.tab+"] ":"")+A.label+" ("+A.type+")"}).join("</li><li>")+"</li>");
|
||||
|
||||
} else if (hasUnusedConfig && !ignoreDeployWarnings.unusedConfig) {
|
||||
// showWarning = true;
|
||||
// $( "#node-dialog-confirm-deploy-type" ).val("unusedConfig");
|
||||
// $( "#node-dialog-confirm-deploy-unused" ).show();
|
||||
//
|
||||
// unusedConfigNodes.sort(sortNodeInfo);
|
||||
// $( "#node-dialog-confirm-deploy-unused-list" )
|
||||
// .html("<li>"+unusedConfigNodes.map(function(A) { return (A.tab?"["+A.tab+"] ":"")+A.label+" ("+A.type+")"}).join("</li><li>")+"</li>");
|
||||
notificationMessage = "<p>"+RED._('deploy.confirm.improperlyConfigured')+"</p>"+
|
||||
'<ul class="node-dialog-configm-deploy-list"><li>'+cropList(invalidNodes.map(function(A) { return (A.tab?"["+A.tab+"] ":"")+A.label+" ("+A.type+")"})).join("</li><li>")+"</li></ul><p>"+
|
||||
RED._('deploy.confirm.confirm')+
|
||||
"</p>";
|
||||
notificationButtons= [
|
||||
{
|
||||
id: "node-dialog-confirm-deploy-deploy",
|
||||
text: RED._("deploy.confirm.button.confirm"),
|
||||
class: "primary",
|
||||
click: function() {
|
||||
save(true);
|
||||
notification.close();
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
if (showWarning) {
|
||||
$( "#node-dialog-confirm-deploy-hide" ).prop("checked",false);
|
||||
$( "#node-dialog-confirm-deploy" ).dialog( "open" );
|
||||
notificationButtons.unshift(
|
||||
{
|
||||
text: RED._("common.label.cancel"),
|
||||
click: function() {
|
||||
notification.close();
|
||||
}
|
||||
}
|
||||
);
|
||||
notification = RED.notify(notificationMessage,{
|
||||
modal: true,
|
||||
fixed: true,
|
||||
buttons:notificationButtons
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -382,7 +387,7 @@ RED.deploy = (function() {
|
||||
'<p>'+RED._("deploy.successfulDeploy")+'</p>'+
|
||||
'<p>'+RED._("deploy.unusedConfigNodes")+' <a href="#" onclick="RED.sidebar.config.show(true); return false;">'+RED._("deploy.unusedConfigNodesLink")+'</a></p>',"success",false,6000);
|
||||
} else {
|
||||
RED.notify(RED._("deploy.successfulDeploy"),"success");
|
||||
RED.notify('<p>'+RED._("deploy.successfulDeploy")+'</p>',"success");
|
||||
}
|
||||
RED.nodes.eachNode(function(node) {
|
||||
if (node.changed) {
|
||||
@@ -403,9 +408,12 @@ RED.deploy = (function() {
|
||||
delete confNode.credentials;
|
||||
}
|
||||
});
|
||||
RED.nodes.eachSubflow(function(subflow) {
|
||||
subflow.changed = false;
|
||||
});
|
||||
RED.nodes.eachWorkspace(function(ws) {
|
||||
ws.changed = false;
|
||||
})
|
||||
});
|
||||
// Once deployed, cannot undo back to a clean state
|
||||
RED.history.markAllDirty();
|
||||
RED.view.redraw();
|
||||
@@ -437,6 +445,10 @@ RED.deploy = (function() {
|
||||
}
|
||||
}
|
||||
return {
|
||||
init: init
|
||||
init: init,
|
||||
setDeployInflight: function(state) {
|
||||
deployInflight = state;
|
||||
}
|
||||
|
||||
}
|
||||
})();
|
||||
|
||||
1430
editor/js/ui/diff.js
1430
editor/js/ui/diff.js
File diff suppressed because it is too large
Load Diff
@@ -48,7 +48,7 @@ RED.editor = (function() {
|
||||
isValid = validateNode(subflow);
|
||||
hasChanged = subflow.changed;
|
||||
}
|
||||
node.valid = isValid;
|
||||
node.valid = isValid && validateNodeProperties(node, node._def.defaults, node);
|
||||
node.changed = node.changed || hasChanged;
|
||||
} else if (node._def) {
|
||||
node.valid = validateNodeProperties(node, node._def.defaults, node);
|
||||
@@ -108,6 +108,17 @@ RED.editor = (function() {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node.icon) {
|
||||
var iconPath = RED.utils.separateIconPath(node.icon);
|
||||
if (!iconPath.module) {
|
||||
return isValid;
|
||||
}
|
||||
var iconSets = RED.nodes.getIconSets();
|
||||
var iconFileList = iconSets[iconPath.module];
|
||||
if (!iconFileList || iconFileList.indexOf(iconPath.file) === -1) {
|
||||
isValid = false;
|
||||
}
|
||||
}
|
||||
return isValid;
|
||||
}
|
||||
|
||||
@@ -159,7 +170,29 @@ RED.editor = (function() {
|
||||
}
|
||||
}
|
||||
}
|
||||
validateIcon(node);
|
||||
}
|
||||
|
||||
function validateIcon(node) {
|
||||
if (node._def.hasOwnProperty("defaults") && !node._def.defaults.hasOwnProperty("icon") && node.icon) {
|
||||
var iconPath = RED.utils.separateIconPath(node.icon);
|
||||
var iconSets = RED.nodes.getIconSets();
|
||||
var iconFileList = iconSets[iconPath.module];
|
||||
var iconModule = $("#node-settings-icon-module");
|
||||
var iconFile = $("#node-settings-icon-file");
|
||||
if (!iconFileList) {
|
||||
iconModule.addClass("input-error");
|
||||
iconFile.removeClass("input-error");
|
||||
} else if (iconFileList.indexOf(iconPath.file) === -1) {
|
||||
iconModule.removeClass("input-error");
|
||||
iconFile.addClass("input-error");
|
||||
} else {
|
||||
iconModule.removeClass("input-error");
|
||||
iconFile.removeClass("input-error");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function validateNodeEditorProperty(node,defaults,property,prefix) {
|
||||
var input = $("#"+prefix+"-"+property);
|
||||
if (input.length > 0) {
|
||||
@@ -489,13 +522,16 @@ RED.editor = (function() {
|
||||
|
||||
function getEditStackTitle() {
|
||||
var title = '<ul class="editor-tray-breadcrumbs">';
|
||||
for (var i=0;i<editStack.length;i++) {
|
||||
var label;
|
||||
for (var i=editStack.length-1;i<editStack.length;i++) {
|
||||
var node = editStack[i];
|
||||
var label = node.type;
|
||||
label = node.type;
|
||||
if (node.type === '_expression') {
|
||||
label = RED._("expressionEditor.title");
|
||||
} else if (node.type === '_json') {
|
||||
label = RED._("jsonEditor.title");
|
||||
} else if (node.type === '_markdown') {
|
||||
label = RED._("markdownEditor.title");
|
||||
} else if (node.type === '_buffer') {
|
||||
label = RED._("bufferEditor.title");
|
||||
} else if (node.type === 'subflow') {
|
||||
@@ -522,7 +558,7 @@ RED.editor = (function() {
|
||||
title += '<li>'+label+'</li>';
|
||||
}
|
||||
title += '</ul>';
|
||||
return title;
|
||||
return label;
|
||||
}
|
||||
|
||||
function buildEditForm(container,formId,type,ns) {
|
||||
@@ -624,7 +660,7 @@ RED.editor = (function() {
|
||||
return A.i-B.i;
|
||||
})
|
||||
rows.forEach(function(r,i) {
|
||||
r.r.find("label").html((i+1)+".");
|
||||
r.r.find("label").text((i+1)+".");
|
||||
r.r.appendTo(outputsDiv);
|
||||
})
|
||||
if (rows.length === 0) {
|
||||
@@ -660,12 +696,12 @@ RED.editor = (function() {
|
||||
function buildLabelRow(type, index, value, placeHolder) {
|
||||
var result = $('<div>',{class:"node-label-form-row"});
|
||||
if (type === undefined) {
|
||||
$('<span>').html("none").appendTo(result);
|
||||
$('<span>').text(RED._("editor.noDefaultLabel")).appendTo(result);
|
||||
result.addClass("node-label-form-none");
|
||||
} else {
|
||||
result.addClass("");
|
||||
var id = "node-label-form-"+type+"-"+index;
|
||||
$('<label>',{for:id}).html((index+1)+".").appendTo(result);
|
||||
$('<label>',{for:id}).text((index+1)+".").appendTo(result);
|
||||
var input = $('<input>',{type:"text",id:id, placeholder: placeHolder}).val(value).appendTo(result);
|
||||
var clear = $('<button class="editor-button editor-button-small"><i class="fa fa-times"></i></button>').appendTo(result);
|
||||
clear.click(function(evt) {
|
||||
@@ -710,10 +746,130 @@ RED.editor = (function() {
|
||||
} else {
|
||||
buildLabelRow().appendTo(outputsDiv);
|
||||
}
|
||||
|
||||
if ((!node._def.defaults || !node._def.defaults.hasOwnProperty("icon"))) {
|
||||
$('<div class="form-row"><div id="node-settings-icon"></div></div>').appendTo(dialogForm);
|
||||
var iconDiv = $("#node-settings-icon");
|
||||
$('<label data-i18n="editor.settingIcon">').appendTo(iconDiv);
|
||||
var iconForm = $('<div>',{class:"node-label-form-row"});
|
||||
iconForm.appendTo(iconDiv);
|
||||
$('<label>').appendTo(iconForm);
|
||||
|
||||
var selectIconModule = $('<select id="node-settings-icon-module"><option value=""></option></select>').appendTo(iconForm);
|
||||
var iconPath;
|
||||
if (node.icon) {
|
||||
iconPath = RED.utils.separateIconPath(node.icon);
|
||||
} else {
|
||||
iconPath = RED.utils.getDefaultNodeIcon(node._def, node);
|
||||
}
|
||||
var iconSets = RED.nodes.getIconSets();
|
||||
Object.keys(iconSets).forEach(function(moduleName) {
|
||||
selectIconModule.append($("<option></option>").val(moduleName).text(moduleName));
|
||||
});
|
||||
if (iconPath.module && !iconSets[iconPath.module]) {
|
||||
selectIconModule.append($("<option disabled></option>").val(iconPath.module).text(iconPath.module));
|
||||
}
|
||||
selectIconModule.val(iconPath.module);
|
||||
var iconModuleHidden = $('<input type="hidden" id="node-settings-icon-module-hidden"></input>').appendTo(iconForm);
|
||||
iconModuleHidden.val(iconPath.module);
|
||||
|
||||
var selectIconFile = $('<select id="node-settings-icon-file"><option value=""></option></select>').appendTo(iconForm);
|
||||
selectIconModule.change(function() {
|
||||
moduleChange(selectIconModule, selectIconFile, iconModuleHidden, iconFileHidden, iconSets, true);
|
||||
});
|
||||
var iconFileHidden = $('<input type="hidden" id="node-settings-icon-file-hidden"></input>').appendTo(iconForm);
|
||||
iconFileHidden.val(iconPath.file);
|
||||
selectIconFile.change(function() {
|
||||
selectIconFile.removeClass("input-error");
|
||||
var fileName = selectIconFile.val();
|
||||
iconFileHidden.val(fileName);
|
||||
});
|
||||
var clear = $('<button class="editor-button editor-button-small"><i class="fa fa-times"></i></button>').appendTo(iconForm);
|
||||
clear.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
var iconPath = RED.utils.getDefaultNodeIcon(node._def, node);
|
||||
selectIconModule.val(iconPath.module);
|
||||
moduleChange(selectIconModule, selectIconFile, iconModuleHidden, iconFileHidden, iconSets, true);
|
||||
selectIconFile.removeClass("input-error");
|
||||
selectIconFile.val(iconPath.file);
|
||||
iconFileHidden.val(iconPath.file);
|
||||
});
|
||||
|
||||
moduleChange(selectIconModule, selectIconFile, iconModuleHidden, iconFileHidden, iconSets, false);
|
||||
var iconFileList = iconSets[selectIconModule.val()];
|
||||
if (!iconFileList || iconFileList.indexOf(iconPath.file) === -1) {
|
||||
selectIconFile.append($("<option disabled></option>").val(iconPath.file).text(iconPath.file));
|
||||
}
|
||||
selectIconFile.val(iconPath.file);
|
||||
}
|
||||
}
|
||||
|
||||
function moduleChange(selectIconModule, selectIconFile, iconModuleHidden, iconFileHidden, iconSets, updateIconFile) {
|
||||
selectIconFile.children().remove();
|
||||
var moduleName = selectIconModule.val();
|
||||
if (moduleName !== null) {
|
||||
iconModuleHidden.val(moduleName);
|
||||
}
|
||||
var iconFileList = iconSets[moduleName];
|
||||
if (iconFileList) {
|
||||
iconFileList.forEach(function(fileName) {
|
||||
if (updateIconFile) {
|
||||
updateIconFile = false;
|
||||
iconFileHidden.val(fileName);
|
||||
}
|
||||
selectIconFile.append($("<option></option>").val(fileName).text(fileName));
|
||||
});
|
||||
}
|
||||
selectIconFile.prop("disabled", !iconFileList);
|
||||
selectIconFile.removeClass("input-error");
|
||||
selectIconModule.removeClass("input-error");
|
||||
}
|
||||
|
||||
function updateLabels(editing_node, changes, outputMap) {
|
||||
var inputLabels = $("#node-label-form-inputs").children().find("input");
|
||||
var outputLabels = $("#node-label-form-outputs").children().find("input");
|
||||
|
||||
var hasNonBlankLabel = false;
|
||||
var changed = false;
|
||||
var newValue = inputLabels.map(function() {
|
||||
var v = $(this).val();
|
||||
hasNonBlankLabel = hasNonBlankLabel || v!== "";
|
||||
return v;
|
||||
}).toArray().slice(0,editing_node.inputs);
|
||||
if ((editing_node.inputLabels === undefined && hasNonBlankLabel) ||
|
||||
(editing_node.inputLabels !== undefined && JSON.stringify(newValue) !== JSON.stringify(editing_node.inputLabels))) {
|
||||
changes.inputLabels = editing_node.inputLabels;
|
||||
editing_node.inputLabels = newValue;
|
||||
changed = true;
|
||||
}
|
||||
hasNonBlankLabel = false;
|
||||
newValue = new Array(editing_node.outputs);
|
||||
outputLabels.each(function() {
|
||||
var index = $(this).attr('id').substring(23); // node-label-form-output-<index>
|
||||
if (outputMap && outputMap.hasOwnProperty(index)) {
|
||||
index = parseInt(outputMap[index]);
|
||||
if (index === -1) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
var v = $(this).val();
|
||||
hasNonBlankLabel = hasNonBlankLabel || v!== "";
|
||||
newValue[index] = v;
|
||||
});
|
||||
|
||||
if ((editing_node.outputLabels === undefined && hasNonBlankLabel) ||
|
||||
(editing_node.outputLabels !== undefined && JSON.stringify(newValue) !== JSON.stringify(editing_node.outputLabels))) {
|
||||
changes.outputLabels = editing_node.outputLabels;
|
||||
editing_node.outputLabels = newValue;
|
||||
changed = true;
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
function showEditDialog(node) {
|
||||
var editing_node = node;
|
||||
var isDefaultIcon;
|
||||
var defaultIcon;
|
||||
editStack.push(node);
|
||||
RED.view.state(RED.state.EDITING);
|
||||
var type = node.type;
|
||||
@@ -882,6 +1038,8 @@ RED.editor = (function() {
|
||||
if (outputsChanged) {
|
||||
changed = true;
|
||||
}
|
||||
} else {
|
||||
newValue = parseInt(newValue);
|
||||
}
|
||||
}
|
||||
if (editing_node[d] != newValue) {
|
||||
@@ -923,41 +1081,35 @@ RED.editor = (function() {
|
||||
// }
|
||||
var removedLinks = updateNodeProperties(editing_node,outputMap);
|
||||
|
||||
var inputLabels = $("#node-label-form-inputs").children().find("input");
|
||||
var outputLabels = $("#node-label-form-outputs").children().find("input");
|
||||
|
||||
var hasNonBlankLabel = false;
|
||||
newValue = inputLabels.map(function() {
|
||||
var v = $(this).val();
|
||||
hasNonBlankLabel = hasNonBlankLabel || v!== "";
|
||||
return v;
|
||||
}).toArray().slice(0,editing_node.inputs);
|
||||
if ((editing_node.inputLabels === undefined && hasNonBlankLabel) ||
|
||||
(editing_node.inputLabels !== undefined && JSON.stringify(newValue) !== JSON.stringify(editing_node.inputLabels))) {
|
||||
changes.inputLabels = editing_node.inputLabels;
|
||||
editing_node.inputLabels = newValue;
|
||||
if (updateLabels(editing_node, changes, outputMap)) {
|
||||
changed = true;
|
||||
}
|
||||
hasNonBlankLabel = false;
|
||||
newValue = new Array(editing_node.outputs);
|
||||
outputLabels.each(function() {
|
||||
var index = $(this).attr('id').substring(23); // node-label-form-output-<index>
|
||||
if (outputMap && outputMap.hasOwnProperty(index)) {
|
||||
index = parseInt(outputMap[index]);
|
||||
if (index === -1) {
|
||||
return;
|
||||
|
||||
if (!editing_node._def.defaults || !editing_node._def.defaults.hasOwnProperty("icon")) {
|
||||
var iconModule = $("#node-settings-icon-module-hidden").val();
|
||||
var iconFile = $("#node-settings-icon-file-hidden").val();
|
||||
var icon = (iconModule && iconFile) ? iconModule+"/"+iconFile : "";
|
||||
if (!isDefaultIcon) {
|
||||
if (icon !== editing_node.icon) {
|
||||
changes.icon = editing_node.icon;
|
||||
editing_node.icon = icon;
|
||||
changed = true;
|
||||
}
|
||||
} else {
|
||||
if (icon !== defaultIcon) {
|
||||
changes.icon = editing_node.icon;
|
||||
editing_node.icon = icon;
|
||||
changed = true;
|
||||
} else {
|
||||
var iconPath = RED.utils.getDefaultNodeIcon(editing_node._def, editing_node);
|
||||
var currentDefaultIcon = iconPath.module+"/"+iconPath.file;
|
||||
if (defaultIcon !== currentDefaultIcon) {
|
||||
changes.icon = editing_node.icon;
|
||||
editing_node.icon = currentDefaultIcon;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
var v = $(this).val();
|
||||
hasNonBlankLabel = hasNonBlankLabel || v!== "";
|
||||
newValue[index] = v;
|
||||
})
|
||||
|
||||
if ((editing_node.outputLabels === undefined && hasNonBlankLabel) ||
|
||||
(editing_node.outputLabels !== undefined && JSON.stringify(newValue) !== JSON.stringify(editing_node.outputLabels))) {
|
||||
changes.outputLabels = editing_node.outputLabels;
|
||||
editing_node.outputLabels = newValue;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
@@ -1051,6 +1203,13 @@ RED.editor = (function() {
|
||||
} else {
|
||||
ns = node._def.set.id;
|
||||
}
|
||||
var iconPath = RED.utils.getDefaultNodeIcon(node._def,node);
|
||||
defaultIcon = iconPath.module+"/"+iconPath.file;
|
||||
if (node.icon && node.icon !== defaultIcon) {
|
||||
isDefaultIcon = false;
|
||||
} else {
|
||||
isDefaultIcon = true;
|
||||
}
|
||||
buildEditForm(nodeProperties.content,"dialog-form",type,ns);
|
||||
buildLabelForm(portLabels.content,node);
|
||||
|
||||
@@ -1207,7 +1366,7 @@ RED.editor = (function() {
|
||||
|
||||
dialogForm.i18n();
|
||||
if (node_def.hasUsers !== false) {
|
||||
$("#node-config-dialog-user-count").find("span").html(RED._("editor.nodesUse", {count:editing_config_node.users.length})).parent().show();
|
||||
$("#node-config-dialog-user-count").find("span").text(RED._("editor.nodesUse", {count:editing_config_node.users.length})).parent().show();
|
||||
}
|
||||
done();
|
||||
});
|
||||
@@ -1530,25 +1689,25 @@ RED.editor = (function() {
|
||||
editing_node.info = newDescription;
|
||||
changed = true;
|
||||
}
|
||||
var inputLabels = $("#node-label-form-inputs").children().find("input");
|
||||
var outputLabels = $("#node-label-form-outputs").children().find("input");
|
||||
|
||||
var newValue = inputLabels.map(function() { return $(this).val();}).toArray().slice(0,editing_node.inputs);
|
||||
if (JSON.stringify(newValue) !== JSON.stringify(editing_node.inputLabels)) {
|
||||
changes.inputLabels = editing_node.inputLabels;
|
||||
editing_node.inputLabels = newValue;
|
||||
if (updateLabels(editing_node, changes, null)) {
|
||||
changed = true;
|
||||
}
|
||||
newValue = outputLabels.map(function() { return $(this).val();}).toArray().slice(0,editing_node.outputs);
|
||||
if (JSON.stringify(newValue) !== JSON.stringify(editing_node.outputLabels)) {
|
||||
changes.outputLabels = editing_node.outputLabels;
|
||||
editing_node.outputLabels = newValue;
|
||||
var iconModule = $("#node-settings-icon-module-hidden").val();
|
||||
var iconFile = $("#node-settings-icon-file-hidden").val();
|
||||
var icon = (iconModule && iconFile) ? iconModule+"/"+iconFile : "";
|
||||
if ((editing_node.icon === undefined && icon !== "node-red/subflow.png") ||
|
||||
(editing_node.icon !== undefined && editing_node.icon !== icon)) {
|
||||
changes.icon = editing_node.icon;
|
||||
editing_node.icon = icon;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
RED.palette.refresh();
|
||||
|
||||
if (changed) {
|
||||
var wasChanged = editing_node.changed;
|
||||
editing_node.changed = true;
|
||||
validateNode(editing_node);
|
||||
var subflowInstances = [];
|
||||
RED.nodes.eachNode(function(n) {
|
||||
if (n.type == "subflow:"+editing_node.id) {
|
||||
@@ -1559,10 +1718,9 @@ RED.editor = (function() {
|
||||
n.changed = true;
|
||||
n.dirty = true;
|
||||
updateNodeProperties(n);
|
||||
validateNode(n);
|
||||
}
|
||||
});
|
||||
var wasChanged = editing_node.changed;
|
||||
editing_node.changed = true;
|
||||
RED.nodes.dirty(true);
|
||||
var historyEvent = {
|
||||
t:'edit',
|
||||
@@ -1638,9 +1796,10 @@ RED.editor = (function() {
|
||||
userCount++;
|
||||
}
|
||||
});
|
||||
$("#subflow-dialog-user-count").html(RED._("subflow.subflowInstances", {count:userCount})).show();
|
||||
$("#subflow-dialog-user-count").text(RED._("subflow.subflowInstances", {count:userCount})).show();
|
||||
|
||||
buildLabelForm(portLabels.content,subflow);
|
||||
validateIcon(subflow);
|
||||
trayBody.i18n();
|
||||
},
|
||||
close: function() {
|
||||
@@ -1680,6 +1839,7 @@ RED.editor = (function() {
|
||||
|
||||
var trayOptions = {
|
||||
title: getEditStackTitle(),
|
||||
width: "inherit",
|
||||
buttons: [
|
||||
{
|
||||
id: "node-dialog-cancel",
|
||||
@@ -1693,7 +1853,7 @@ RED.editor = (function() {
|
||||
text: RED._("common.label.done"),
|
||||
class: "primary",
|
||||
click: function() {
|
||||
$("#node-input-expression-help").html("");
|
||||
$("#node-input-expression-help").text("");
|
||||
onComplete(expressionEditor.getValue());
|
||||
RED.tray.close();
|
||||
}
|
||||
@@ -1838,12 +1998,12 @@ RED.editor = (function() {
|
||||
|
||||
tabs.addTab({
|
||||
id: 'expression-help',
|
||||
label: 'Function reference',
|
||||
label: RED._('expressionEditor.functionReference'),
|
||||
content: $("#node-input-expression-tab-help")
|
||||
});
|
||||
tabs.addTab({
|
||||
id: 'expression-tests',
|
||||
label: 'Test',
|
||||
label: RED._('expressionEditor.test'),
|
||||
content: $("#node-input-expression-tab-test")
|
||||
});
|
||||
testDataEditor = RED.editor.createEditor({
|
||||
@@ -1963,9 +2123,6 @@ RED.editor = (function() {
|
||||
},
|
||||
show: function() {}
|
||||
}
|
||||
if (editTrayWidthCache.hasOwnProperty(type)) {
|
||||
trayOptions.width = editTrayWidthCache[type];
|
||||
}
|
||||
RED.tray.show(trayOptions);
|
||||
}
|
||||
|
||||
@@ -1977,9 +2134,104 @@ RED.editor = (function() {
|
||||
editStack.push({type:type});
|
||||
RED.view.state(RED.state.EDITING);
|
||||
var expressionEditor;
|
||||
var changeTimer;
|
||||
|
||||
var checkValid = function() {
|
||||
var v = expressionEditor.getValue();
|
||||
try {
|
||||
JSON.parse(v);
|
||||
$("#node-dialog-ok").removeClass('disabled');
|
||||
return true;
|
||||
} catch(err) {
|
||||
$("#node-dialog-ok").addClass('disabled');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
var trayOptions = {
|
||||
title: options.title || getEditStackTitle(),
|
||||
width: "inherit",
|
||||
buttons: [
|
||||
{
|
||||
id: "node-dialog-cancel",
|
||||
text: RED._("common.label.cancel"),
|
||||
click: function() {
|
||||
RED.tray.close();
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "node-dialog-ok",
|
||||
text: RED._("common.label.done"),
|
||||
class: "primary",
|
||||
click: function() {
|
||||
if (options.requireValid && !checkValid()) {
|
||||
return;
|
||||
}
|
||||
onComplete(expressionEditor.getValue());
|
||||
RED.tray.close();
|
||||
}
|
||||
}
|
||||
],
|
||||
resize: function(dimensions) {
|
||||
editTrayWidthCache[type] = dimensions.width;
|
||||
|
||||
var rows = $("#dialog-form>div:not(.node-text-editor-row)");
|
||||
var editorRow = $("#dialog-form>div.node-text-editor-row");
|
||||
var height = $("#dialog-form").height();
|
||||
for (var i=0;i<rows.size();i++) {
|
||||
height -= $(rows[i]).outerHeight(true);
|
||||
}
|
||||
height -= (parseInt($("#dialog-form").css("marginTop"))+parseInt($("#dialog-form").css("marginBottom")));
|
||||
$(".node-text-editor").css("height",height+"px");
|
||||
expressionEditor.resize();
|
||||
},
|
||||
open: function(tray) {
|
||||
var trayBody = tray.find('.editor-tray-body');
|
||||
var dialogForm = buildEditForm(tray.find('.editor-tray-body'),'dialog-form',type,'editor');
|
||||
expressionEditor = RED.editor.createEditor({
|
||||
id: 'node-input-json',
|
||||
value: "",
|
||||
mode:"ace/mode/json"
|
||||
});
|
||||
expressionEditor.getSession().setValue(value||"",-1);
|
||||
if (options.requireValid) {
|
||||
expressionEditor.getSession().on('change', function() {
|
||||
clearTimeout(changeTimer);
|
||||
changeTimer = setTimeout(checkValid,200);
|
||||
});
|
||||
checkValid();
|
||||
}
|
||||
$("#node-input-json-reformat").click(function(evt) {
|
||||
evt.preventDefault();
|
||||
var v = expressionEditor.getValue()||"";
|
||||
try {
|
||||
v = JSON.stringify(JSON.parse(v),null,4);
|
||||
} catch(err) {
|
||||
// TODO: do an optimistic auto-format
|
||||
}
|
||||
expressionEditor.getSession().setValue(v||"",-1);
|
||||
});
|
||||
dialogForm.i18n();
|
||||
},
|
||||
close: function() {
|
||||
editStack.pop();
|
||||
expressionEditor.destroy();
|
||||
},
|
||||
show: function() {}
|
||||
}
|
||||
RED.tray.show(trayOptions);
|
||||
}
|
||||
|
||||
function editMarkdown(options) {
|
||||
var value = options.value;
|
||||
var onComplete = options.complete;
|
||||
var type = "_markdown"
|
||||
editStack.push({type:type});
|
||||
RED.view.state(RED.state.EDITING);
|
||||
var expressionEditor;
|
||||
|
||||
var trayOptions = {
|
||||
title: getEditStackTitle(),
|
||||
title: options.title || getEditStackTitle(),
|
||||
width: "inherit",
|
||||
buttons: [
|
||||
{
|
||||
id: "node-dialog-cancel",
|
||||
@@ -2015,21 +2267,14 @@ RED.editor = (function() {
|
||||
var trayBody = tray.find('.editor-tray-body');
|
||||
var dialogForm = buildEditForm(tray.find('.editor-tray-body'),'dialog-form',type,'editor');
|
||||
expressionEditor = RED.editor.createEditor({
|
||||
id: 'node-input-json',
|
||||
value: "",
|
||||
mode:"ace/mode/json"
|
||||
});
|
||||
expressionEditor.getSession().setValue(value||"",-1);
|
||||
$("#node-input-json-reformat").click(function(evt) {
|
||||
evt.preventDefault();
|
||||
var v = expressionEditor.getValue()||"";
|
||||
try {
|
||||
v = JSON.stringify(JSON.parse(v),null,4);
|
||||
} catch(err) {
|
||||
// TODO: do an optimistic auto-format
|
||||
}
|
||||
expressionEditor.getSession().setValue(v||"",-1);
|
||||
id: 'node-input-markdown',
|
||||
value: value,
|
||||
mode:"ace/mode/markdown"
|
||||
});
|
||||
if (options.header) {
|
||||
options.header.appendTo(tray.find('#node-input-markdown-title'));
|
||||
}
|
||||
|
||||
dialogForm.i18n();
|
||||
},
|
||||
close: function() {
|
||||
@@ -2038,9 +2283,6 @@ RED.editor = (function() {
|
||||
},
|
||||
show: function() {}
|
||||
}
|
||||
if (editTrayWidthCache.hasOwnProperty(type)) {
|
||||
trayOptions.width = editTrayWidthCache[type];
|
||||
}
|
||||
RED.tray.show(trayOptions);
|
||||
}
|
||||
|
||||
@@ -2083,6 +2325,7 @@ RED.editor = (function() {
|
||||
|
||||
var trayOptions = {
|
||||
title: getEditStackTitle(),
|
||||
width: "inherit",
|
||||
buttons: [
|
||||
{
|
||||
id: "node-dialog-cancel",
|
||||
@@ -2225,9 +2468,6 @@ RED.editor = (function() {
|
||||
},
|
||||
show: function() {}
|
||||
}
|
||||
if (editTrayWidthCache.hasOwnProperty(type)) {
|
||||
trayOptions.width = editTrayWidthCache[type];
|
||||
}
|
||||
RED.tray.show(trayOptions);
|
||||
}
|
||||
|
||||
@@ -2248,15 +2488,26 @@ RED.editor = (function() {
|
||||
editSubflow: showEditSubflowDialog,
|
||||
editExpression: editExpression,
|
||||
editJSON: editJSON,
|
||||
editMarkdown: editMarkdown,
|
||||
editBuffer: editBuffer,
|
||||
validateNode: validateNode,
|
||||
updateNodeProperties: updateNodeProperties, // TODO: only exposed for edit-undo
|
||||
|
||||
|
||||
createEditor: function(options) {
|
||||
var editor = ace.edit(options.id);
|
||||
var editor = ace.edit(options.id||options.element);
|
||||
editor.setTheme("ace/theme/tomorrow");
|
||||
var session = editor.getSession();
|
||||
session.on("changeAnnotation", function () {
|
||||
var annotations = session.getAnnotations() || [];
|
||||
var i = annotations.length;
|
||||
var len = annotations.length;
|
||||
while (i--) {
|
||||
if (/doctype first\. Expected/.test(annotations[i].text)) { annotations.splice(i, 1); }
|
||||
else if (/Unexpected End of file\. Expected/.test(annotations[i].text)) { annotations.splice(i, 1); }
|
||||
}
|
||||
if (len > annotations.length) { session.setAnnotations(annotations); }
|
||||
});
|
||||
if (options.mode) {
|
||||
session.setMode(options.mode);
|
||||
}
|
||||
@@ -2287,7 +2538,7 @@ RED.editor = (function() {
|
||||
if (options.globals) {
|
||||
setTimeout(function() {
|
||||
if (!!session.$worker) {
|
||||
session.$worker.send("setOptions", [{globals: options.globals, esversion:6}]);
|
||||
session.$worker.send("setOptions", [{globals: options.globals, esversion:6, sub:true, asi:true, maxerr:1000}]);
|
||||
}
|
||||
},100);
|
||||
}
|
||||
|
||||
@@ -57,8 +57,24 @@ RED.keyboard = (function() {
|
||||
173:189
|
||||
}
|
||||
|
||||
function migrateOldKeymap() {
|
||||
if ('localStorage' in window && window['localStorage'] !== null) {
|
||||
var oldKeyMap = localStorage.getItem("keymap");
|
||||
if (oldKeyMap !== null) {
|
||||
localStorage.removeItem("keymap");
|
||||
var currentEditorSettings = RED.settings.get('editor') || {};
|
||||
currentEditorSettings.keymap = JSON.parse(oldKeyMap);
|
||||
RED.settings.set('editor',currentEditorSettings);
|
||||
}
|
||||
}
|
||||
}
|
||||
function init() {
|
||||
var userKeymap = RED.settings.get('keymap') || {};
|
||||
// Migrate from pre-0.18
|
||||
migrateOldKeymap();
|
||||
|
||||
var currentEditorSettings = RED.settings.get('editor') || {};
|
||||
var userKeymap = currentEditorSettings.keymap || {};
|
||||
|
||||
$.getJSON("red/keymap.json",function(data) {
|
||||
for (var scope in data) {
|
||||
if (data.hasOwnProperty(scope)) {
|
||||
@@ -67,12 +83,12 @@ RED.keyboard = (function() {
|
||||
if (keys.hasOwnProperty(key)) {
|
||||
if (!userKeymap.hasOwnProperty(keys[key])) {
|
||||
addHandler(scope,key,keys[key],false);
|
||||
defaultKeyMap[keys[key]] = {
|
||||
scope:scope,
|
||||
key:key,
|
||||
user:false
|
||||
};
|
||||
}
|
||||
defaultKeyMap[keys[key]] = {
|
||||
scope:scope,
|
||||
key:key,
|
||||
user:false
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -89,7 +105,7 @@ RED.keyboard = (function() {
|
||||
|
||||
RED.userSettings.add({
|
||||
id:'keyboard',
|
||||
title: 'Keyboard',
|
||||
title: RED._("keyboard.keyboard"),
|
||||
get: getSettingsPane,
|
||||
focus: function() {
|
||||
setTimeout(function() {
|
||||
@@ -350,7 +366,8 @@ RED.keyboard = (function() {
|
||||
$(this).toggleClass("input-error",!valid);
|
||||
})
|
||||
|
||||
var scopeSelect = $('<select><option value="*">global</option><option value="workspace">workspace</option></select>').appendTo(scope);
|
||||
var scopeSelect = $('<select><option value="*" data-i18n="keyboard.global"></option><option value="workspace" data-i18n="keyboard.workspace"></option></select>').appendTo(scope);
|
||||
scopeSelect.i18n();
|
||||
scopeSelect.val(object.scope||'*');
|
||||
|
||||
var div = $('<div class="keyboard-shortcut-edit button-group-vertical"></div>').appendTo(scope);
|
||||
@@ -368,8 +385,12 @@ RED.keyboard = (function() {
|
||||
container.removeClass('keyboard-shortcut-entry-expanded');
|
||||
var shortcut = RED.keyboard.getShortcut(object.id);
|
||||
var userKeymap = RED.settings.get('keymap') || {};
|
||||
delete userKeymap[object.id];
|
||||
RED.settings.set('keymap',userKeymap);
|
||||
|
||||
var currentEditorSettings = RED.settings.get('editor') || {};
|
||||
var userKeymap = currentEditorSettings.keymap || {};
|
||||
userKeymap[object.id] = null;
|
||||
currentEditorSettings.keymap = userKeymap;
|
||||
RED.settings.set('editor',currentEditorSettings);
|
||||
|
||||
var obj = {
|
||||
id:object.id,
|
||||
@@ -418,9 +439,12 @@ RED.keyboard = (function() {
|
||||
object.scope = scope;
|
||||
RED.keyboard.add(object.scope,object.key,object.id,true);
|
||||
}
|
||||
var userKeymap = RED.settings.get('keymap') || {};
|
||||
|
||||
var currentEditorSettings = RED.settings.get('editor') || {};
|
||||
var userKeymap = currentEditorSettings.keymap || {};
|
||||
userKeymap[object.id] = RED.keyboard.getShortcut(object.id);
|
||||
RED.settings.set('keymap',userKeymap);
|
||||
currentEditorSettings.keymap = userKeymap;
|
||||
RED.settings.set('editor',currentEditorSettings);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -468,9 +492,9 @@ RED.keyboard = (function() {
|
||||
var pane = $('<div id="user-settings-tab-keyboard"></div>');
|
||||
|
||||
$('<div class="keyboard-shortcut-entry keyboard-shortcut-list-header">'+
|
||||
'<div class="keyboard-shortcut-entry-key keyboard-shortcut-entry-text"><input id="user-settings-tab-keyboard-filter" type="text" placeholder="filter actions"></div>'+
|
||||
'<div class="keyboard-shortcut-entry-key">shortcut</div>'+
|
||||
'<div class="keyboard-shortcut-entry-scope">scope</div>'+
|
||||
'<div class="keyboard-shortcut-entry-key keyboard-shortcut-entry-text"><input id="user-settings-tab-keyboard-filter" type="text" data-i18n="[placeholder]keyboard.filterActions"></div>'+
|
||||
'<div class="keyboard-shortcut-entry-key" data-i18n="keyboard.shortcut"></div>'+
|
||||
'<div class="keyboard-shortcut-entry-scope" data-i18n="keyboard.scope"></div>'+
|
||||
'</div>').appendTo(pane);
|
||||
|
||||
pane.find("input").searchBox({
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
**/
|
||||
RED.library = (function() {
|
||||
|
||||
|
||||
var exportToLibraryDialog;
|
||||
var elementPrefix = "node-input-";
|
||||
|
||||
function loadFlowLibrary() {
|
||||
$.getJSON("library/flows",function(data) {
|
||||
@@ -38,7 +38,7 @@ RED.library = (function() {
|
||||
li.className = "dropdown-submenu pull-left";
|
||||
a = document.createElement("a");
|
||||
a.href="#";
|
||||
var label = i.replace(/^node-red-contrib-/,"").replace(/^node-red-node-/,"").replace(/-/," ").replace(/_/," ");
|
||||
var label = i.replace(/^@.*\//,"").replace(/^node-red-contrib-/,"").replace(/^node-red-node-/,"").replace(/-/," ").replace(/_/," ");
|
||||
a.innerHTML = label;
|
||||
li.appendChild(a);
|
||||
li.appendChild(buildMenu(data.d[i],root+(root!==""?"/":"")+i));
|
||||
@@ -86,6 +86,7 @@ RED.library = (function() {
|
||||
var libraryData = {};
|
||||
var selectedLibraryItem = null;
|
||||
var libraryEditor = null;
|
||||
elementPrefix = options.elementPrefix || "node-input-";
|
||||
|
||||
// Orion editor has set/getText
|
||||
// ACE editor has set/getValue
|
||||
@@ -157,8 +158,8 @@ RED.library = (function() {
|
||||
return ul;
|
||||
}
|
||||
|
||||
$('#node-input-name').css("width","66%").after(
|
||||
'<div class="btn-group" style="margin-left: 5px;">'+
|
||||
$('#'+elementPrefix+"name").css("width","calc(100% - 52px)").after(
|
||||
'<div class="btn-group" style="margin-left:5px;">'+
|
||||
'<a id="node-input-'+options.type+'-lookup" class="editor-button" data-toggle="dropdown"><i class="fa fa-book"></i> <i class="fa fa-caret-down"></i></a>'+
|
||||
'<ul class="dropdown-menu pull-right" role="menu">'+
|
||||
'<li><a id="node-input-'+options.type+'-menu-open-library" tabindex="-1" href="#">'+RED._("library.openLibrary")+'</a></li>'+
|
||||
@@ -187,7 +188,7 @@ RED.library = (function() {
|
||||
|
||||
$('#node-input-'+options.type+'-menu-save-library').click(function(e) {
|
||||
//var found = false;
|
||||
var name = $("#node-input-name").val().replace(/(^\s*)|(\s*$)/g,"");
|
||||
var name = $("#"+elementPrefix+"name").val().replace(/(^\s*)|(\s*$)/g,"");
|
||||
|
||||
//var buildPathList = function(data,root) {
|
||||
// var paths = [];
|
||||
@@ -264,7 +265,7 @@ RED.library = (function() {
|
||||
if (selectedLibraryItem) {
|
||||
for (var i=0; i<options.fields.length; i++) {
|
||||
var field = options.fields[i];
|
||||
$("#node-input-"+field).val(selectedLibraryItem[field]);
|
||||
$("#"+elementPrefix+field).val(selectedLibraryItem[field]);
|
||||
}
|
||||
options.editor.setValue(libraryEditor.getValue(),-1);
|
||||
}
|
||||
@@ -286,7 +287,7 @@ RED.library = (function() {
|
||||
});
|
||||
|
||||
function saveToLibrary(overwrite) {
|
||||
var name = $("#node-input-name").val().replace(/(^\s*)|(\s*$)/g,"");
|
||||
var name = $("#"+elementPrefix+"name").val().replace(/(^\s*)|(\s*$)/g,"");
|
||||
if (name === "") {
|
||||
name = RED._("library.unnamedType",{type:options.type});
|
||||
}
|
||||
@@ -330,7 +331,7 @@ RED.library = (function() {
|
||||
if (field == "name") {
|
||||
data.name = name;
|
||||
} else {
|
||||
data[field] = $("#node-input-"+field).val();
|
||||
data[field] = $("#"+elementPrefix+field).val();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,10 +13,49 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
RED.notify = (function() {
|
||||
RED.notifications = (function() {
|
||||
|
||||
/*
|
||||
// Example usage for a modal dialog with buttons
|
||||
var myNotification = RED.notify("This is the message to display",{
|
||||
modal: true,
|
||||
fixed: true,
|
||||
type: 'warning',
|
||||
buttons: [
|
||||
{
|
||||
text: "cancel",
|
||||
click: function(e) {
|
||||
myNotification.close();
|
||||
}
|
||||
},
|
||||
{
|
||||
text: "okay",
|
||||
class:"primary",
|
||||
click: function(e) {
|
||||
myNotification.close();
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
*/
|
||||
|
||||
var persistentNotifications = {};
|
||||
|
||||
var currentNotifications = [];
|
||||
var c = 0;
|
||||
return function(msg,type,fixed,timeout) {
|
||||
function notify(msg,type,fixed,timeout) {
|
||||
var options = {};
|
||||
if (type !== null && typeof type === 'object') {
|
||||
options = type;
|
||||
fixed = options.fixed;
|
||||
timeout = options.timeout;
|
||||
type = options.type;
|
||||
}
|
||||
|
||||
if (options.modal) {
|
||||
$("#full-shade").show();
|
||||
}
|
||||
|
||||
if (currentNotifications.length > 4) {
|
||||
var ll = currentNotifications.length;
|
||||
for (var i = 0;ll > 4 && i<currentNotifications.length;i+=1) {
|
||||
@@ -35,38 +74,123 @@ RED.notify = (function() {
|
||||
if (type) {
|
||||
n.className = "notification notification-"+type;
|
||||
}
|
||||
if (options.width) {
|
||||
var parentWidth = $("#notifications").width();
|
||||
if (options.width > parentWidth) {
|
||||
var margin = -(options.width-parentWidth)/2;
|
||||
$(n).css({
|
||||
width: options.width+"px",
|
||||
marginLeft: margin+"px"
|
||||
})
|
||||
}
|
||||
}
|
||||
n.style.display = "none";
|
||||
if (typeof msg === "string") {
|
||||
if (!/<p>/i.test(msg)) {
|
||||
msg = "<p>"+msg+"</p>";
|
||||
}
|
||||
n.innerHTML = msg;
|
||||
} else {
|
||||
$(n).append(msg);
|
||||
}
|
||||
if (options.buttons) {
|
||||
var buttonSet = $('<div style="margin-top: 20px;" class="ui-dialog-buttonset"></div>').appendTo(n)
|
||||
options.buttons.forEach(function(buttonDef) {
|
||||
var b = $('<button>').text(buttonDef.text).click(buttonDef.click).appendTo(buttonSet);
|
||||
if (buttonDef.id) {
|
||||
b.attr('id',buttonDef.id);
|
||||
}
|
||||
if (buttonDef.class) {
|
||||
b.addClass(buttonDef.class);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
$("#notifications").append(n);
|
||||
$(n).slideDown(300);
|
||||
n.close = (function() {
|
||||
var nn = n;
|
||||
return function() {
|
||||
if (nn.closed) {
|
||||
return;
|
||||
}
|
||||
nn.closed = true;
|
||||
currentNotifications.splice(currentNotifications.indexOf(nn),1);
|
||||
if (options.id) {
|
||||
delete persistentNotifications[options.id];
|
||||
if (Object.keys(persistentNotifications).length === 0) {
|
||||
notificationButtonWrapper.hide();
|
||||
}
|
||||
}
|
||||
$(nn).slideUp(300, function() {
|
||||
nn.parentNode.removeChild(nn);
|
||||
});
|
||||
if (options.modal) {
|
||||
$("#full-shade").hide();
|
||||
}
|
||||
};
|
||||
})();
|
||||
n.hideNotification = (function() {
|
||||
var nn = n;
|
||||
return function() {
|
||||
if (nn.closed) {
|
||||
return
|
||||
}
|
||||
nn.hidden = true;
|
||||
$(nn).slideUp(300);
|
||||
}
|
||||
})();
|
||||
n.showNotification = (function() {
|
||||
var nn = n;
|
||||
return function() {
|
||||
if (nn.closed || !nn.hidden) {
|
||||
return
|
||||
}
|
||||
nn.hidden = false;
|
||||
$(nn).slideDown(300);
|
||||
}
|
||||
})();
|
||||
|
||||
n.update = (function() {
|
||||
var nn = n;
|
||||
return function(msg,timeout) {
|
||||
return function(msg,options) {
|
||||
if (typeof msg === "string") {
|
||||
if (!/<p>/i.test(msg)) {
|
||||
msg = "<p>"+msg+"</p>";
|
||||
}
|
||||
nn.innerHTML = msg;
|
||||
} else {
|
||||
$(nn).empty().append(msg);
|
||||
}
|
||||
var timeout;
|
||||
if (typeof options === 'number') {
|
||||
timeout = options;
|
||||
} else if (options !== undefined) {
|
||||
timeout = options.timeout;
|
||||
if (options.buttons) {
|
||||
var buttonSet = $('<div style="margin-top: 20px;" class="ui-dialog-buttonset"></div>').appendTo(nn)
|
||||
options.buttons.forEach(function(buttonDef) {
|
||||
var b = $('<button>').text(buttonDef.text).click(buttonDef.click).appendTo(buttonSet);
|
||||
if (buttonDef.id) {
|
||||
b.attr('id',buttonDef.id);
|
||||
}
|
||||
if (buttonDef.class) {
|
||||
b.addClass(buttonDef.class);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
if (timeout !== undefined && timeout > 0) {
|
||||
window.clearTimeout(nn.timeoutid);
|
||||
nn.timeoutid = window.setTimeout(nn.close,timeout);
|
||||
} else {
|
||||
window.clearTimeout(nn.timeoutid);
|
||||
}
|
||||
if (nn.hidden) {
|
||||
nn.showNotification();
|
||||
}
|
||||
|
||||
}
|
||||
})();
|
||||
|
||||
@@ -78,10 +202,48 @@ RED.notify = (function() {
|
||||
window.clearTimeout(nn.timeoutid);
|
||||
};
|
||||
})());
|
||||
n.timeoutid = window.setTimeout(n.close,timeout||3000);
|
||||
n.timeoutid = window.setTimeout(n.close,timeout||5000);
|
||||
}
|
||||
currentNotifications.push(n);
|
||||
if (options.id) {
|
||||
persistentNotifications[options.id] = n;
|
||||
notificationButtonWrapper.show();
|
||||
}
|
||||
c+=1;
|
||||
return n;
|
||||
}
|
||||
|
||||
RED.notify = notify;
|
||||
|
||||
|
||||
function hidePersistent() {
|
||||
for(var i in persistentNotifications) {
|
||||
if (persistentNotifications.hasOwnProperty(i)) {
|
||||
persistentNotifications[i].hideNotification();
|
||||
}
|
||||
}
|
||||
}
|
||||
function showPersistent() {
|
||||
for(var i in persistentNotifications) {
|
||||
if (persistentNotifications.hasOwnProperty(i)) {
|
||||
persistentNotifications[i].showNotification();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var notificationButtonWrapper;
|
||||
|
||||
return {
|
||||
init: function() {
|
||||
notificationButtonWrapper = $('<li>'+
|
||||
'<a id="btn-notifications" class="button" href="#">'+
|
||||
'<i class="fa fa-warning"></i>'+
|
||||
'</a>'+
|
||||
'</li>').prependTo(".header-toolbar").hide();
|
||||
$('#btn-notifications').click(function() {
|
||||
showPersistent();
|
||||
})
|
||||
},
|
||||
notify: notify
|
||||
}
|
||||
})();
|
||||
|
||||
@@ -75,27 +75,21 @@ RED.palette.editor = (function() {
|
||||
});
|
||||
})
|
||||
}
|
||||
function installNodeModule(id,version,shade,callback) {
|
||||
function installNodeModule(id,version,callback) {
|
||||
var requestBody = {
|
||||
module: id
|
||||
};
|
||||
if (callback === undefined) {
|
||||
callback = shade;
|
||||
shade = version;
|
||||
} else {
|
||||
if (version) {
|
||||
requestBody.version = version;
|
||||
}
|
||||
shade.show();
|
||||
$.ajax({
|
||||
url:"nodes",
|
||||
type: "POST",
|
||||
data: JSON.stringify(requestBody),
|
||||
contentType: "application/json; charset=utf-8"
|
||||
}).done(function(data,textStatus,xhr) {
|
||||
shade.hide();
|
||||
callback();
|
||||
}).fail(function(xhr,textStatus,err) {
|
||||
shade.hide();
|
||||
callback(xhr);
|
||||
});
|
||||
}
|
||||
@@ -214,6 +208,8 @@ RED.palette.editor = (function() {
|
||||
if (nodeEntry) {
|
||||
var activeTypeCount = 0;
|
||||
var typeCount = 0;
|
||||
var errorCount = 0;
|
||||
nodeEntry.errorList.empty();
|
||||
nodeEntries[module].totalUseCount = 0;
|
||||
nodeEntries[module].setUseCount = {};
|
||||
|
||||
@@ -222,7 +218,10 @@ RED.palette.editor = (function() {
|
||||
var inUseCount = 0;
|
||||
var set = moduleInfo.sets[setName];
|
||||
var setElements = nodeEntry.sets[setName];
|
||||
|
||||
if (set.err) {
|
||||
errorCount++;
|
||||
$("<li>").text(set.err).appendTo(nodeEntry.errorList);
|
||||
}
|
||||
if (set.enabled) {
|
||||
activeTypeCount += set.types.length;
|
||||
}
|
||||
@@ -248,24 +247,31 @@ RED.palette.editor = (function() {
|
||||
nodeEntries[module].totalUseCount += inUseCount;
|
||||
|
||||
if (inUseCount > 0) {
|
||||
setElements.enableButton.html(RED._('palette.editor.inuse'));
|
||||
setElements.enableButton.text(RED._('palette.editor.inuse'));
|
||||
setElements.enableButton.addClass('disabled');
|
||||
} else {
|
||||
setElements.enableButton.removeClass('disabled');
|
||||
if (set.enabled) {
|
||||
setElements.enableButton.html(RED._('palette.editor.disable'));
|
||||
setElements.enableButton.text(RED._('palette.editor.disable'));
|
||||
} else {
|
||||
setElements.enableButton.html(RED._('palette.editor.enable'));
|
||||
setElements.enableButton.text(RED._('palette.editor.enable'));
|
||||
}
|
||||
}
|
||||
setElements.setRow.toggleClass("palette-module-set-disabled",!set.enabled);
|
||||
}
|
||||
}
|
||||
|
||||
if (errorCount === 0) {
|
||||
nodeEntry.errorRow.hide()
|
||||
} else {
|
||||
nodeEntry.errorRow.show();
|
||||
}
|
||||
|
||||
var nodeCount = (activeTypeCount === typeCount)?typeCount:activeTypeCount+" / "+typeCount;
|
||||
nodeEntry.setCount.html(RED._('palette.editor.nodeCount',{count:typeCount,label:nodeCount}));
|
||||
nodeEntry.setCount.text(RED._('palette.editor.nodeCount',{count:typeCount,label:nodeCount}));
|
||||
|
||||
if (nodeEntries[module].totalUseCount > 0) {
|
||||
nodeEntry.enableButton.html(RED._('palette.editor.inuse'));
|
||||
nodeEntry.enableButton.text(RED._('palette.editor.inuse'));
|
||||
nodeEntry.enableButton.addClass('disabled');
|
||||
nodeEntry.removeButton.hide();
|
||||
} else {
|
||||
@@ -274,20 +280,20 @@ RED.palette.editor = (function() {
|
||||
nodeEntry.removeButton.css('display', 'inline-block');
|
||||
}
|
||||
if (activeTypeCount === 0) {
|
||||
nodeEntry.enableButton.html(RED._('palette.editor.enableall'));
|
||||
nodeEntry.enableButton.text(RED._('palette.editor.enableall'));
|
||||
} else {
|
||||
nodeEntry.enableButton.html(RED._('palette.editor.disableall'));
|
||||
nodeEntry.enableButton.text(RED._('palette.editor.disableall'));
|
||||
}
|
||||
nodeEntry.container.toggleClass("disabled",(activeTypeCount === 0));
|
||||
}
|
||||
}
|
||||
if (moduleInfo.pending_version) {
|
||||
nodeEntry.versionSpan.html(moduleInfo.version+' <i class="fa fa-long-arrow-right"></i> '+moduleInfo.pending_version).appendTo(nodeEntry.metaRow)
|
||||
nodeEntry.updateButton.html(RED._('palette.editor.updated')).addClass('disabled').show();
|
||||
nodeEntry.updateButton.text(RED._('palette.editor.updated')).addClass('disabled').show();
|
||||
} else if (loadedIndex.hasOwnProperty(module)) {
|
||||
if (semVerCompare(loadedIndex[module].version,moduleInfo.version) === 1) {
|
||||
nodeEntry.updateButton.show();
|
||||
nodeEntry.updateButton.html(RED._('palette.editor.update',{version:loadedIndex[module].version}));
|
||||
nodeEntry.updateButton.text(RED._('palette.editor.update',{version:loadedIndex[module].version}));
|
||||
} else {
|
||||
nodeEntry.updateButton.hide();
|
||||
}
|
||||
@@ -361,7 +367,7 @@ RED.palette.editor = (function() {
|
||||
loadedIndex = {};
|
||||
packageList.editableList('empty');
|
||||
|
||||
$(".palette-module-shade-status").html(RED._('palette.editor.loading'));
|
||||
$(".palette-module-shade-status").text(RED._('palette.editor.loading'));
|
||||
var catalogues = RED.settings.theme('palette.catalogues')||['https://catalogue.nodered.org/catalogue.json'];
|
||||
catalogueLoadStatus = [];
|
||||
catalogueLoadErrors = false;
|
||||
@@ -423,7 +429,7 @@ RED.palette.editor = (function() {
|
||||
|
||||
RED.userSettings.add({
|
||||
id:'palette',
|
||||
title: 'Palette',
|
||||
title: RED._("palette.editor.palette"),
|
||||
get: getSettingsPane,
|
||||
close: function() {
|
||||
settingsPane.detach();
|
||||
@@ -467,7 +473,7 @@ RED.palette.editor = (function() {
|
||||
if (filteredList[i].info.id === ns.module) {
|
||||
var installButton = filteredList[i].elements.installButton;
|
||||
installButton.addClass('disabled');
|
||||
installButton.html(RED._('palette.editor.installed'));
|
||||
installButton.text(RED._('palette.editor.installed'));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -483,7 +489,7 @@ RED.palette.editor = (function() {
|
||||
if (filteredList[i].info.id === ns.module) {
|
||||
var installButton = filteredList[i].elements.installButton;
|
||||
installButton.removeClass('disabled');
|
||||
installButton.html(RED._('palette.editor.install'));
|
||||
installButton.text(RED._('palette.editor.install'));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -589,61 +595,38 @@ RED.palette.editor = (function() {
|
||||
if (entry) {
|
||||
var headerRow = $('<div>',{class:"palette-module-header"}).appendTo(container);
|
||||
var titleRow = $('<div class="palette-module-meta palette-module-name"><i class="fa fa-cube"></i></div>').appendTo(headerRow);
|
||||
$('<span>').html(entry.name).appendTo(titleRow);
|
||||
$('<span>').text(entry.name).appendTo(titleRow);
|
||||
var metaRow = $('<div class="palette-module-meta palette-module-version"><i class="fa fa-tag"></i></div>').appendTo(headerRow);
|
||||
var versionSpan = $('<span>').html(entry.version).appendTo(metaRow);
|
||||
var versionSpan = $('<span>').text(entry.version).appendTo(metaRow);
|
||||
|
||||
var errorRow = $('<div class="palette-module-meta palette-module-errors"><i class="fa fa-warning"></i></div>').hide().appendTo(headerRow);
|
||||
var errorList = $('<ul class="palette-module-error-list"></ul>').appendTo(errorRow);
|
||||
var buttonRow = $('<div>',{class:"palette-module-meta"}).appendTo(headerRow);
|
||||
var setButton = $('<a href="#" class="editor-button editor-button-small palette-module-set-button"><i class="fa fa-angle-right palette-module-node-chevron"></i> </a>').appendTo(buttonRow);
|
||||
var setCount = $('<span>').appendTo(setButton);
|
||||
var buttonGroup = $('<div>',{class:"palette-module-button-group"}).appendTo(buttonRow);
|
||||
|
||||
var updateButton = $('<a href="#" class="editor-button editor-button-small"></a>').html(RED._('palette.editor.update')).appendTo(buttonGroup);
|
||||
var updateButton = $('<a href="#" class="editor-button editor-button-small"></a>').text(RED._('palette.editor.update')).appendTo(buttonGroup);
|
||||
updateButton.attr('id','up_'+Math.floor(Math.random()*1000000000));
|
||||
updateButton.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
if ($(this).hasClass('disabled')) {
|
||||
return;
|
||||
}
|
||||
$("#palette-module-install-confirm").data('module',entry.name);
|
||||
$("#palette-module-install-confirm").data('version',loadedIndex[entry.name].version);
|
||||
$("#palette-module-install-confirm").data('shade',shade);
|
||||
|
||||
$("#palette-module-install-confirm-body").html(entry.local?
|
||||
RED._("palette.editor.confirm.update.body"):
|
||||
RED._("palette.editor.confirm.cannotUpdate.body")
|
||||
);
|
||||
$(".palette-module-install-confirm-button-install").hide();
|
||||
$(".palette-module-install-confirm-button-remove").hide();
|
||||
if (entry.local) {
|
||||
$(".palette-module-install-confirm-button-update").show();
|
||||
} else {
|
||||
$(".palette-module-install-confirm-button-update").hide();
|
||||
}
|
||||
$("#palette-module-install-confirm")
|
||||
.dialog('option', 'title',RED._("palette.editor.confirm.update.title"))
|
||||
.dialog('open');
|
||||
update(entry,loadedIndex[entry.name].version,container,function(err){});
|
||||
})
|
||||
|
||||
|
||||
var removeButton = $('<a href="#" class="editor-button editor-button-small"></a>').html(RED._('palette.editor.remove')).appendTo(buttonGroup);
|
||||
var removeButton = $('<a href="#" class="editor-button editor-button-small"></a>').text(RED._('palette.editor.remove')).appendTo(buttonGroup);
|
||||
removeButton.attr('id','up_'+Math.floor(Math.random()*1000000000));
|
||||
removeButton.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
|
||||
$("#palette-module-install-confirm").data('module',entry.name);
|
||||
$("#palette-module-install-confirm").data('shade',shade);
|
||||
$("#palette-module-install-confirm-body").html(RED._("palette.editor.confirm.remove.body"));
|
||||
$(".palette-module-install-confirm-button-install").hide();
|
||||
$(".palette-module-install-confirm-button-remove").show();
|
||||
$(".palette-module-install-confirm-button-update").hide();
|
||||
$("#palette-module-install-confirm")
|
||||
.dialog('option', 'title', RED._("palette.editor.confirm.remove.title"))
|
||||
.dialog('open');
|
||||
remove(entry,container,function(err){});
|
||||
})
|
||||
if (!entry.local) {
|
||||
removeButton.hide();
|
||||
}
|
||||
var enableButton = $('<a href="#" class="editor-button editor-button-small"></a>').html(RED._('palette.editor.disableall')).appendTo(buttonGroup);
|
||||
var enableButton = $('<a href="#" class="editor-button editor-button-small"></a>').text(RED._('palette.editor.disableall')).appendTo(buttonGroup);
|
||||
|
||||
var contentRow = $('<div>',{class:"palette-module-content"}).appendTo(container);
|
||||
var shade = $('<div class="palette-module-shade hide"><img src="red/images/spin.svg" class="palette-spinner"/></div>').appendTo(container);
|
||||
@@ -652,6 +635,8 @@ RED.palette.editor = (function() {
|
||||
updateButton: updateButton,
|
||||
removeButton: removeButton,
|
||||
enableButton: enableButton,
|
||||
errorRow: errorRow,
|
||||
errorList: errorList,
|
||||
setCount: setCount,
|
||||
container: container,
|
||||
shade: shade,
|
||||
@@ -681,9 +666,8 @@ RED.palette.editor = (function() {
|
||||
set.types.forEach(function(t) {
|
||||
var typeDiv = $('<div>',{class:"palette-module-type"}).appendTo(setRow);
|
||||
typeSwatches[t] = $('<span>',{class:"palette-module-type-swatch"}).appendTo(typeDiv);
|
||||
$('<span>',{class:"palette-module-type-node"}).html(t).appendTo(typeDiv);
|
||||
$('<span>',{class:"palette-module-type-node"}).text(t).appendTo(typeDiv);
|
||||
})
|
||||
|
||||
var enableButton = $('<a href="#" class="editor-button editor-button-small"></a>').appendTo(buttonGroup);
|
||||
enableButton.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
@@ -721,7 +705,7 @@ RED.palette.editor = (function() {
|
||||
})
|
||||
refreshNodeModule(entry.name);
|
||||
} else {
|
||||
$('<div>',{class:"red-ui-search-empty"}).html(RED._('search.empty')).appendTo(container);
|
||||
$('<div>',{class:"red-ui-search-empty"}).text(RED._('search.empty')).appendTo(container);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -761,7 +745,7 @@ RED.palette.editor = (function() {
|
||||
});
|
||||
|
||||
|
||||
$('<span>').html(RED._("palette.editor.sort")+' ').appendTo(toolBar);
|
||||
$('<span>').text(RED._("palette.editor.sort")+' ').appendTo(toolBar);
|
||||
var sortGroup = $('<span class="button-group"></span>').appendTo(toolBar);
|
||||
var sortAZ = $('<a href="#" class="sidebar-header-button-toggle selected" data-i18n="palette.editor.sortAZ"></a>').appendTo(sortGroup);
|
||||
var sortRecent = $('<a href="#" class="sidebar-header-button-toggle" data-i18n="palette.editor.sortRecent"></a>').appendTo(sortGroup);
|
||||
@@ -803,13 +787,13 @@ RED.palette.editor = (function() {
|
||||
scrollOnAdd: false,
|
||||
addItem: function(container,i,object) {
|
||||
if (object.count) {
|
||||
$('<div>',{class:"red-ui-search-empty"}).html(RED._('palette.editor.moduleCount',{count:object.count})).appendTo(container);
|
||||
$('<div>',{class:"red-ui-search-empty"}).text(RED._('palette.editor.moduleCount',{count:object.count})).appendTo(container);
|
||||
return
|
||||
}
|
||||
if (object.more) {
|
||||
container.addClass('palette-module-more');
|
||||
var moreRow = $('<div>',{class:"palette-module-header palette-module"}).appendTo(container);
|
||||
var moreLink = $('<a href="#"></a>').html(RED._('palette.editor.more',{count:object.more})).appendTo(moreRow);
|
||||
var moreLink = $('<a href="#"></a>').text(RED._('palette.editor.more',{count:object.more})).appendTo(moreRow);
|
||||
moreLink.click(function(e) {
|
||||
e.preventDefault();
|
||||
packageList.editableList('removeItem',object);
|
||||
@@ -826,131 +810,158 @@ RED.palette.editor = (function() {
|
||||
var entry = object.info;
|
||||
var headerRow = $('<div>',{class:"palette-module-header"}).appendTo(container);
|
||||
var titleRow = $('<div class="palette-module-meta"><i class="fa fa-cube"></i></div>').appendTo(headerRow);
|
||||
$('<span>',{class:"palette-module-name"}).html(entry.name||entry.id).appendTo(titleRow);
|
||||
$('<span>',{class:"palette-module-name"}).text(entry.name||entry.id).appendTo(titleRow);
|
||||
$('<a target="_blank" class="palette-module-link"><i class="fa fa-external-link"></i></a>').attr('href',entry.url).appendTo(titleRow);
|
||||
var descRow = $('<div class="palette-module-meta"></div>').appendTo(headerRow);
|
||||
$('<div>',{class:"palette-module-description"}).html(entry.description).appendTo(descRow);
|
||||
$('<div>',{class:"palette-module-description"}).text(entry.description).appendTo(descRow);
|
||||
|
||||
var metaRow = $('<div class="palette-module-meta"></div>').appendTo(headerRow);
|
||||
$('<span class="palette-module-version"><i class="fa fa-tag"></i> '+entry.version+'</span>').appendTo(metaRow);
|
||||
$('<span class="palette-module-updated"><i class="fa fa-calendar"></i> '+formatUpdatedAt(entry.updated_at)+'</span>').appendTo(metaRow);
|
||||
var buttonRow = $('<div>',{class:"palette-module-meta"}).appendTo(headerRow);
|
||||
var buttonGroup = $('<div>',{class:"palette-module-button-group"}).appendTo(buttonRow);
|
||||
var shade = $('<div class="palette-module-shade hide"><img src="red/images/spin.svg" class="palette-spinner"/></div>').appendTo(container);
|
||||
var installButton = $('<a href="#" class="editor-button editor-button-small"></a>').html(RED._('palette.editor.install')).appendTo(buttonGroup);
|
||||
var installButton = $('<a href="#" class="editor-button editor-button-small"></a>').text(RED._('palette.editor.install')).appendTo(buttonGroup);
|
||||
installButton.click(function(e) {
|
||||
e.preventDefault();
|
||||
if (!$(this).hasClass('disabled')) {
|
||||
$("#palette-module-install-confirm").data('module',entry.id);
|
||||
$("#palette-module-install-confirm").data('version',entry.version);
|
||||
$("#palette-module-install-confirm").data('url',entry.url);
|
||||
$("#palette-module-install-confirm").data('shade',shade);
|
||||
$("#palette-module-install-confirm-body").html(RED._("palette.editor.confirm.install.body"));
|
||||
$(".palette-module-install-confirm-button-install").show();
|
||||
$(".palette-module-install-confirm-button-remove").hide();
|
||||
$(".palette-module-install-confirm-button-update").hide();
|
||||
$("#palette-module-install-confirm")
|
||||
.dialog('option', 'title', RED._("palette.editor.confirm.install.title"))
|
||||
.dialog('open');
|
||||
install(entry,container,function(xhr) {});
|
||||
}
|
||||
})
|
||||
if (nodeEntries.hasOwnProperty(entry.id)) {
|
||||
installButton.addClass('disabled');
|
||||
installButton.html(RED._('palette.editor.installed'));
|
||||
installButton.text(RED._('palette.editor.installed'));
|
||||
}
|
||||
|
||||
object.elements = {
|
||||
installButton:installButton
|
||||
}
|
||||
} else {
|
||||
$('<div>',{class:"red-ui-search-empty"}).html(RED._('search.empty')).appendTo(container);
|
||||
$('<div>',{class:"red-ui-search-empty"}).text(RED._('search.empty')).appendTo(container);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('<div id="palette-module-install-shade" class="palette-module-shade hide"><div class="palette-module-shade-status"></div><img src="red/images/spin.svg" class="palette-spinner"/></div>').appendTo(installTab);
|
||||
|
||||
$('<div id="palette-module-install-confirm" class="hide"><form class="form-horizontal"><div id="palette-module-install-confirm-body" class="node-dialog-confirm-row"></div></form></div>').appendTo(document.body);
|
||||
$("#palette-module-install-confirm").dialog({
|
||||
title: RED._('palette.editor.confirm.title'),
|
||||
}
|
||||
function update(entry,version,container,done) {
|
||||
if (RED.settings.theme('palette.editable') === false) {
|
||||
done(new Error('Palette not editable'));
|
||||
return;
|
||||
}
|
||||
var notification = RED.notify(RED._("palette.editor.confirm.update.body",{module:entry.name}),{
|
||||
modal: true,
|
||||
autoOpen: false,
|
||||
width: 550,
|
||||
height: "auto",
|
||||
fixed: true,
|
||||
buttons: [
|
||||
{
|
||||
text: RED._("common.label.cancel"),
|
||||
click: function() {
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
},
|
||||
{
|
||||
text: RED._("palette.editor.confirm.button.review"),
|
||||
class: "primary palette-module-install-confirm-button-install",
|
||||
click: function() {
|
||||
var url = $(this).data('url');
|
||||
window.open(url);
|
||||
}
|
||||
},
|
||||
{
|
||||
text: RED._("palette.editor.confirm.button.install"),
|
||||
class: "primary palette-module-install-confirm-button-install",
|
||||
click: function() {
|
||||
var id = $(this).data('module');
|
||||
var version = $(this).data('version');
|
||||
var shade = $(this).data('shade');
|
||||
installNodeModule(id,version,shade,function(xhr) {
|
||||
if (xhr) {
|
||||
if (xhr.responseJSON) {
|
||||
RED.notify(RED._('palette.editor.errors.installFailed',{module: id,message:xhr.responseJSON.message}));
|
||||
}
|
||||
}
|
||||
});
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
},
|
||||
{
|
||||
text: RED._("palette.editor.confirm.button.remove"),
|
||||
class: "primary palette-module-install-confirm-button-remove",
|
||||
click: function() {
|
||||
var id = $(this).data('module');
|
||||
var shade = $(this).data('shade');
|
||||
shade.show();
|
||||
removeNodeModule(id, function(xhr) {
|
||||
shade.hide();
|
||||
if (xhr) {
|
||||
if (xhr.responseJSON) {
|
||||
RED.notify(RED._('palette.editor.errors.removeFailed',{module: id,message:xhr.responseJSON.message}));
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
$( this ).dialog( "close" );
|
||||
notification.close();
|
||||
}
|
||||
},
|
||||
{
|
||||
text: RED._("palette.editor.confirm.button.update"),
|
||||
class: "primary palette-module-install-confirm-button-update",
|
||||
click: function() {
|
||||
var id = $(this).data('module');
|
||||
var version = $(this).data('version');
|
||||
var shade = $(this).data('shade');
|
||||
shade.show();
|
||||
installNodeModule(id,version,shade,function(xhr) {
|
||||
if (xhr) {
|
||||
if (xhr.responseJSON) {
|
||||
RED.notify(RED._('palette.editor.errors.updateFailed',{module: id,message:xhr.responseJSON.message}));
|
||||
}
|
||||
}
|
||||
var spinner = RED.utils.addSpinnerOverlay(container, true);
|
||||
installNodeModule(entry.name,version,function(xhr) {
|
||||
spinner.remove();
|
||||
if (xhr) {
|
||||
if (xhr.responseJSON) {
|
||||
RED.notify(RED._('palette.editor.errors.updateFailed',{module: entry.name,message:xhr.responseJSON.message}));
|
||||
}
|
||||
}
|
||||
done(xhr);
|
||||
});
|
||||
$( this ).dialog( "close" );
|
||||
notification.close();
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
function remove(entry,container,done) {
|
||||
if (RED.settings.theme('palette.editable') === false) {
|
||||
done(new Error('Palette not editable'));
|
||||
return;
|
||||
}
|
||||
var notification = RED.notify(RED._("palette.editor.confirm.remove.body",{module:entry.name}),{
|
||||
modal: true,
|
||||
fixed: true,
|
||||
buttons: [
|
||||
{
|
||||
text: RED._("common.label.cancel"),
|
||||
click: function() {
|
||||
notification.close();
|
||||
}
|
||||
},
|
||||
{
|
||||
text: RED._("palette.editor.confirm.button.remove"),
|
||||
class: "primary palette-module-install-confirm-button-remove",
|
||||
click: function() {
|
||||
var spinner = RED.utils.addSpinnerOverlay(container, true);
|
||||
removeNodeModule(entry.name, function(xhr) {
|
||||
spinner.remove();
|
||||
if (xhr) {
|
||||
if (xhr.responseJSON) {
|
||||
RED.notify(RED._('palette.editor.errors.removeFailed',{module: entry.name,message:xhr.responseJSON.message}));
|
||||
}
|
||||
}
|
||||
})
|
||||
notification.close();
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
function install(entry,container,done) {
|
||||
if (RED.settings.theme('palette.editable') === false) {
|
||||
done(new Error('Palette not editable'));
|
||||
return;
|
||||
}
|
||||
var buttons = [
|
||||
{
|
||||
text: RED._("common.label.cancel"),
|
||||
click: function() {
|
||||
notification.close();
|
||||
}
|
||||
}
|
||||
];
|
||||
if (entry.url) {
|
||||
buttons.push({
|
||||
text: RED._("palette.editor.confirm.button.review"),
|
||||
class: "primary palette-module-install-confirm-button-install",
|
||||
click: function() {
|
||||
var url = entry.url||"";
|
||||
window.open(url);
|
||||
}
|
||||
});
|
||||
}
|
||||
buttons.push({
|
||||
text: RED._("palette.editor.confirm.button.install"),
|
||||
class: "primary palette-module-install-confirm-button-install",
|
||||
click: function() {
|
||||
var spinner = RED.utils.addSpinnerOverlay(container, true);
|
||||
installNodeModule(entry.id,entry.version,function(xhr) {
|
||||
spinner.remove();
|
||||
if (xhr) {
|
||||
if (xhr.responseJSON) {
|
||||
RED.notify(RED._('palette.editor.errors.installFailed',{module: entry.id,message:xhr.responseJSON.message}));
|
||||
}
|
||||
}
|
||||
done(xhr);
|
||||
});
|
||||
notification.close();
|
||||
}
|
||||
});
|
||||
|
||||
var notification = RED.notify(RED._("palette.editor.confirm.install.body",{module:entry.id}),{
|
||||
modal: true,
|
||||
fixed: true,
|
||||
buttons: buttons
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
init: init
|
||||
init: init,
|
||||
install: install
|
||||
}
|
||||
})();
|
||||
|
||||
@@ -21,7 +21,7 @@ RED.palette = (function() {
|
||||
|
||||
var categoryContainers = {};
|
||||
|
||||
function createCategoryContainer(category, label){
|
||||
function createCategoryContainer(category, label) {
|
||||
label = (label || category).replace(/_/g, " ");
|
||||
var catDiv = $('<div id="palette-container-'+category+'" class="palette-category palette-close hide">'+
|
||||
'<div id="palette-header-'+category+'" class="palette-header"><i class="expanded fa fa-angle-down"></i><span>'+label+'</span></div>'+
|
||||
@@ -116,6 +116,12 @@ RED.palette = (function() {
|
||||
el.data('popover').setContent(popOverContent);
|
||||
}
|
||||
|
||||
function setIcon(element,sf) {
|
||||
var iconElement = element.find(".palette_icon");
|
||||
var icon_url = RED.utils.getNodeIcon(sf._def,sf);
|
||||
iconElement.attr("style", "background-image: url("+icon_url+")");
|
||||
}
|
||||
|
||||
function escapeNodeType(nt) {
|
||||
return nt.replace(" ","_").replace(".","_").replace(":","_");
|
||||
}
|
||||
@@ -206,11 +212,11 @@ RED.palette = (function() {
|
||||
RED.view.focus();
|
||||
var helpText;
|
||||
if (nt.indexOf("subflow:") === 0) {
|
||||
helpText = marked(RED.nodes.subflow(nt.substring(8)).info||"");
|
||||
helpText = marked(RED.nodes.subflow(nt.substring(8)).info||"")||('<span class="node-info-none">'+RED._("sidebar.info.none")+'</span>');
|
||||
} else {
|
||||
helpText = $("script[data-help-name='"+d.type+"']").html()||"";
|
||||
helpText = $("script[data-help-name='"+d.type+"']").html()||('<span class="node-info-none">'+RED._("sidebar.info.none")+'</span>');
|
||||
}
|
||||
RED.sidebar.info.set(helpText);
|
||||
RED.sidebar.info.set(helpText,RED._("sidebar.info.nodeHelp"));
|
||||
});
|
||||
var chart = $("#chart");
|
||||
var chartOffset = chart.offset();
|
||||
@@ -219,13 +225,19 @@ RED.palette = (function() {
|
||||
var mouseX;
|
||||
var mouseY;
|
||||
var spliceTimer;
|
||||
var paletteWidth;
|
||||
var paletteTop;
|
||||
$(d).draggable({
|
||||
helper: 'clone',
|
||||
appendTo: 'body',
|
||||
revert: true,
|
||||
revertDuration: 50,
|
||||
containment:'#main-container',
|
||||
start: function() {RED.view.focus();},
|
||||
start: function() {
|
||||
paletteWidth = $("#palette").width();
|
||||
paletteTop = $("#palette").parent().position().top + $("#palette-container").position().top;
|
||||
RED.view.focus();
|
||||
},
|
||||
stop: function() { d3.select('.link_splice').classed('link_splice',false); if (spliceTimer) { clearTimeout(spliceTimer); spliceTimer = null;}},
|
||||
drag: function(e,ui) {
|
||||
|
||||
@@ -235,9 +247,8 @@ RED.palette = (function() {
|
||||
ui.position.left += 17.5;
|
||||
|
||||
if (def.inputs > 0 && def.outputs > 0) {
|
||||
mouseX = ui.position.left+(ui.helper.width()/2) - chartOffset.left + chart.scrollLeft();
|
||||
mouseY = ui.position.top+(ui.helper.height()/2) - chartOffset.top + chart.scrollTop();
|
||||
|
||||
mouseX = ui.position.left-paletteWidth+(ui.helper.width()/2) - chartOffset.left + chart.scrollLeft();
|
||||
mouseY = ui.position.top-paletteTop+(ui.helper.height()/2) - chartOffset.top + chart.scrollTop();
|
||||
if (!spliceTimer) {
|
||||
spliceTimer = setTimeout(function() {
|
||||
var nodes = [];
|
||||
@@ -259,6 +270,7 @@ RED.palette = (function() {
|
||||
mouseY /= RED.view.scale();
|
||||
nodes = RED.view.getLinksAtPoint(mouseX,mouseY);
|
||||
}
|
||||
|
||||
for (var i=0;i<nodes.length;i++) {
|
||||
if (d3.select(nodes[i]).classed('link_background')) {
|
||||
var length = nodes[i].getTotalLength();
|
||||
@@ -325,14 +337,26 @@ RED.palette = (function() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function hideNodeType(nt) {
|
||||
var nodeTypeId = escapeNodeType(nt);
|
||||
$("#palette_node_"+nodeTypeId).hide();
|
||||
var paletteNode = $("#palette_node_"+nodeTypeId);
|
||||
paletteNode.hide();
|
||||
var categoryNode = paletteNode.closest(".palette-category");
|
||||
var cl = categoryNode.find(".palette_node");
|
||||
var c = 0;
|
||||
for (var i = 0; i < cl.length; i++) {
|
||||
if ($(cl[i]).css('display') === 'none') { c += 1; }
|
||||
}
|
||||
if (c === cl.length) { categoryNode.hide(); }
|
||||
}
|
||||
|
||||
function showNodeType(nt) {
|
||||
var nodeTypeId = escapeNodeType(nt);
|
||||
$("#palette_node_"+nodeTypeId).show();
|
||||
var paletteNode = $("#palette_node_"+nodeTypeId);
|
||||
var categoryNode = paletteNode.closest(".palette-category");
|
||||
categoryNode.show();
|
||||
paletteNode.show();
|
||||
}
|
||||
|
||||
function refreshNodeTypes() {
|
||||
@@ -357,6 +381,7 @@ RED.palette = (function() {
|
||||
portOutput.remove();
|
||||
}
|
||||
setLabel(sf.type+":"+sf.id,paletteNode,sf.name,marked(sf.info||""));
|
||||
setIcon(paletteNode,sf);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -396,21 +421,21 @@ RED.palette = (function() {
|
||||
RED.events.on('registry:node-type-removed', function(nodeType) {
|
||||
removeNodeType(nodeType);
|
||||
});
|
||||
|
||||
RED.events.on('registry:node-set-enabled', function(nodeSet) {
|
||||
for (var j=0;j<nodeSet.types.length;j++) {
|
||||
showNodeType(nodeSet.types[j]);
|
||||
var def = RED.nodes.getType(nodeSet.types[j]);
|
||||
if (def.onpaletteadd && typeof def.onpaletteadd === "function") {
|
||||
if (def && def.onpaletteadd && typeof def.onpaletteadd === "function") {
|
||||
def.onpaletteadd.call(def);
|
||||
}
|
||||
}
|
||||
});
|
||||
RED.events.on('registry:node-set-disabled', function(nodeSet) {
|
||||
console.log(nodeSet);
|
||||
for (var j=0;j<nodeSet.types.length;j++) {
|
||||
hideNodeType(nodeSet.types[j]);
|
||||
var def = RED.nodes.getType(nodeSet.types[j]);
|
||||
if (def.onpaletteremove && typeof def.onpaletteremove === "function") {
|
||||
if (def && def.onpaletteremove && typeof def.onpaletteremove === "function") {
|
||||
def.onpaletteremove.call(def);
|
||||
}
|
||||
}
|
||||
@@ -420,14 +445,13 @@ RED.palette = (function() {
|
||||
for (var j=0;j<nodeSet.types.length;j++) {
|
||||
removeNodeType(nodeSet.types[j]);
|
||||
var def = RED.nodes.getType(nodeSet.types[j]);
|
||||
if (def.onpaletteremove && typeof def.onpaletteremove === "function") {
|
||||
if (def && def.onpaletteremove && typeof def.onpaletteremove === "function") {
|
||||
def.onpaletteremove.call(def);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
$("#palette > .palette-spinner").show();
|
||||
|
||||
$("#palette-search input").searchBox({
|
||||
|
||||
1535
editor/js/ui/projects/projectSettings.js
Normal file
1535
editor/js/ui/projects/projectSettings.js
Normal file
File diff suppressed because it is too large
Load Diff
418
editor/js/ui/projects/projectUserSettings.js
Normal file
418
editor/js/ui/projects/projectUserSettings.js
Normal file
@@ -0,0 +1,418 @@
|
||||
/**
|
||||
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
RED.projects.userSettings = (function() {
|
||||
|
||||
var gitUsernameInput;
|
||||
var gitEmailInput;
|
||||
|
||||
function createGitUserSection(pane) {
|
||||
|
||||
var currentGitSettings = RED.settings.get('git') || {};
|
||||
currentGitSettings.user = currentGitSettings.user || {};
|
||||
|
||||
var title = $('<h3></h3>').text("Committer Details").appendTo(pane);
|
||||
|
||||
var gitconfigContainer = $('<div class="user-settings-section"></div>').appendTo(pane);
|
||||
$('<div style="color:#aaa;"></div>').appendTo(gitconfigContainer).text("Leave blank to use system default");
|
||||
|
||||
var row = $('<div class="user-settings-row"></div>').appendTo(gitconfigContainer);
|
||||
$('<label for=""></label>').text('Username').appendTo(row);
|
||||
gitUsernameInput = $('<input type="text">').appendTo(row);
|
||||
gitUsernameInput.val(currentGitSettings.user.name||"");
|
||||
|
||||
row = $('<div class="user-settings-row"></div>').appendTo(gitconfigContainer);
|
||||
$('<label for=""></label>').text('Email').appendTo(row);
|
||||
gitEmailInput = $('<input type="text">').appendTo(row);
|
||||
gitEmailInput.val(currentGitSettings.user.email||"");
|
||||
}
|
||||
|
||||
|
||||
function createSSHKeySection(pane) {
|
||||
var container = $('<div class="user-settings-section"></div>').appendTo(pane);
|
||||
var popover;
|
||||
var title = $('<h3></h3>').text("SSH Keys").appendTo(container);
|
||||
var subtitle = $('<div style="color:#aaa;"></div>').appendTo(container).text("Allows you to create secure connections to remote git repositories.");
|
||||
|
||||
var addKeyButton = $('<button id="user-settings-gitconfig-add-key" class="editor-button editor-button-small" style="float: right; margin-right: 10px;">add key</button>')
|
||||
.appendTo(subtitle)
|
||||
.click(function(evt) {
|
||||
addKeyButton.attr('disabled',true);
|
||||
saveButton.attr('disabled',true);
|
||||
// bg.children().removeClass("selected");
|
||||
// addLocalButton.click();
|
||||
addKeyDialog.slideDown(200);
|
||||
keyNameInput.focus();
|
||||
});
|
||||
|
||||
var validateForm = function() {
|
||||
var valid = /^[a-zA-Z0-9\-_]+$/.test(keyNameInput.val());
|
||||
keyNameInput.toggleClass('input-error',keyNameInputChanged&&!valid);
|
||||
|
||||
// var selectedButton = bg.find(".selected");
|
||||
// if (selectedButton[0] === addLocalButton[0]) {
|
||||
// valid = valid && localPublicKeyPathInput.val().length > 0 && localPrivateKeyPathInput.val().length > 0;
|
||||
// } else if (selectedButton[0] === uploadButton[0]) {
|
||||
// valid = valid && publicKeyInput.val().length > 0 && privateKeyInput.val().length > 0;
|
||||
// } else if (selectedButton[0] === generateButton[0]) {
|
||||
var passphrase = passphraseInput.val();
|
||||
var validPassphrase = passphrase.length === 0 || passphrase.length >= 8;
|
||||
passphraseInput.toggleClass('input-error',!validPassphrase);
|
||||
if (!validPassphrase) {
|
||||
passphraseInputSubLabel.text("Passphrase too short");
|
||||
} else if (passphrase.length === 0) {
|
||||
passphraseInputSubLabel.text("Optional");
|
||||
} else {
|
||||
passphraseInputSubLabel.text("");
|
||||
}
|
||||
valid = valid && validPassphrase;
|
||||
// }
|
||||
|
||||
saveButton.attr('disabled',!valid);
|
||||
|
||||
if (popover) {
|
||||
popover.close();
|
||||
popover = null;
|
||||
}
|
||||
};
|
||||
|
||||
var row = $('<div class="user-settings-row"></div>').appendTo(container);
|
||||
var addKeyDialog = $('<div class="projects-dialog-list-dialog"></div>').hide().appendTo(row);
|
||||
$('<div class="projects-dialog-list-dialog-header">').text('Add SSH Key').appendTo(addKeyDialog);
|
||||
var addKeyDialogBody = $('<div>').appendTo(addKeyDialog);
|
||||
|
||||
row = $('<div class="user-settings-row"></div>').appendTo(addKeyDialogBody);
|
||||
$('<div style="color:#aaa;"></div>').appendTo(row).text("Generate a new public/private key pair");
|
||||
// var bg = $('<div></div>',{class:"button-group", style:"text-align: center"}).appendTo(row);
|
||||
// var addLocalButton = $('<button class="editor-button toggle selected">use local key</button>').appendTo(bg);
|
||||
// var uploadButton = $('<button class="editor-button toggle">upload key</button>').appendTo(bg);
|
||||
// var generateButton = $('<button class="editor-button toggle">generate key</button>').appendTo(bg);
|
||||
// bg.children().click(function(e) {
|
||||
// e.preventDefault();
|
||||
// if ($(this).hasClass("selected")) {
|
||||
// return;
|
||||
// }
|
||||
// bg.children().removeClass("selected");
|
||||
// $(this).addClass("selected");
|
||||
// if (this === addLocalButton[0]) {
|
||||
// addLocalKeyPane.show();
|
||||
// generateKeyPane.hide();
|
||||
// uploadKeyPane.hide();
|
||||
// } else if (this === uploadButton[0]) {
|
||||
// addLocalKeyPane.hide();
|
||||
// generateKeyPane.hide();
|
||||
// uploadKeyPane.show();
|
||||
// } else if (this === generateButton[0]){
|
||||
// addLocalKeyPane.hide();
|
||||
// generateKeyPane.show();
|
||||
// uploadKeyPane.hide();
|
||||
// }
|
||||
// validateForm();
|
||||
// })
|
||||
|
||||
|
||||
row = $('<div class="user-settings-row"></div>').appendTo(addKeyDialogBody);
|
||||
$('<label for=""></label>').text('Name').appendTo(row);
|
||||
var keyNameInputChanged = false;
|
||||
var keyNameInput = $('<input type="text">').appendTo(row).on("change keyup paste",function() {
|
||||
keyNameInputChanged = true;
|
||||
validateForm();
|
||||
});
|
||||
$('<label class="projects-edit-form-sublabel"><small>Must contain only A-Z 0-9 _ -</small></label>').appendTo(row).find("small");
|
||||
|
||||
var generateKeyPane = $('<div>').appendTo(addKeyDialogBody);
|
||||
row = $('<div class="user-settings-row"></div>').appendTo(generateKeyPane);
|
||||
$('<label for=""></label>').text('Passphrase').appendTo(row);
|
||||
var passphraseInput = $('<input type="password">').appendTo(row).on("change keyup paste",validateForm);
|
||||
var passphraseInputSubLabel = $('<label class="projects-edit-form-sublabel"><small>Optional</small></label>').appendTo(row).find("small");
|
||||
|
||||
// var addLocalKeyPane = $('<div>').hide().appendTo(addKeyDialogBody);
|
||||
// row = $('<div class="user-settings-row"></div>').appendTo(addLocalKeyPane);
|
||||
// $('<label for=""></label>').text('Public key').appendTo(row);
|
||||
// var localPublicKeyPathInput = $('<input type="text">').appendTo(row).on("change keyup paste",validateForm);
|
||||
// $('<label class="projects-edit-form-sublabel"><small>Public key file path, for example: ~/.ssh/id_rsa.pub</small></label>').appendTo(row).find("small");
|
||||
// row = $('<div class="user-settings-row"></div>').appendTo(addLocalKeyPane);
|
||||
// $('<label for=""></label>').text('Private key').appendTo(row);
|
||||
// var localPrivateKeyPathInput = $('<input type="text">').appendTo(row).on("change keyup paste",validateForm);
|
||||
// $('<label class="projects-edit-form-sublabel"><small>Private key file path, for example: ~/.ssh/id_rsa</small></label>').appendTo(row).find("small");
|
||||
//
|
||||
// var uploadKeyPane = $('<div>').hide().appendTo(addKeyDialogBody);
|
||||
// row = $('<div class="user-settings-row"></div>').appendTo(uploadKeyPane);
|
||||
// $('<label for=""></label>').text('Public key').appendTo(row);
|
||||
// var publicKeyInput = $('<textarea>').appendTo(row).on("change keyup paste",validateForm);
|
||||
// $('<label class="projects-edit-form-sublabel"><small>Paste in public key contents, for example: ~/.ssh/id_rsa.pub</small></label>').appendTo(row).find("small");
|
||||
// row = $('<div class="user-settings-row"></div>').appendTo(uploadKeyPane);
|
||||
// $('<label for=""></label>').text('Private key').appendTo(row);
|
||||
// var privateKeyInput = $('<textarea>').appendTo(row).on("change keyup paste",validateForm);
|
||||
// $('<label class="projects-edit-form-sublabel"><small>Paste in private key contents, for example: ~/.ssh/id_rsa</small></label>').appendTo(row).find("small");
|
||||
|
||||
|
||||
|
||||
|
||||
var hideEditForm = function() {
|
||||
addKeyButton.attr('disabled',false);
|
||||
addKeyDialog.hide();
|
||||
|
||||
keyNameInput.val("");
|
||||
keyNameInputChanged = false;
|
||||
passphraseInput.val("");
|
||||
// localPublicKeyPathInput.val("");
|
||||
// localPrivateKeyPathInput.val("");
|
||||
// publicKeyInput.val("");
|
||||
// privateKeyInput.val("");
|
||||
if (popover) {
|
||||
popover.close();
|
||||
popover = null;
|
||||
}
|
||||
}
|
||||
var formButtons = $('<span class="button-row" style="position: relative; float: right; margin: 10px;"></span>').appendTo(addKeyDialog);
|
||||
$('<button class="editor-button">Cancel</button>')
|
||||
.appendTo(formButtons)
|
||||
.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
hideEditForm();
|
||||
});
|
||||
var saveButton = $('<button class="editor-button">Generate key</button>')
|
||||
.appendTo(formButtons)
|
||||
.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
var spinner = utils.addSpinnerOverlay(addKeyDialog).addClass('projects-dialog-spinner-contain');
|
||||
var payload = {
|
||||
name: keyNameInput.val()
|
||||
};
|
||||
|
||||
// var selectedButton = bg.find(".selected");
|
||||
// if (selectedButton[0] === addLocalButton[0]) {
|
||||
// payload.type = "local";
|
||||
// payload.publicKeyPath = localPublicKeyPathInput.val();
|
||||
// payload.privateKeyPath = localPrivateKeyPathInput.val();
|
||||
// } else if (selectedButton[0] === uploadButton[0]) {
|
||||
// payload.type = "upload";
|
||||
// payload.publicKey = publicKeyInput.val();
|
||||
// payload.privateKey = privateKeyInput.val();
|
||||
// } else if (selectedButton[0] === generateButton[0]) {
|
||||
payload.type = "generate";
|
||||
payload.comment = gitEmailInput.val();
|
||||
payload.password = passphraseInput.val();
|
||||
payload.size = 4096;
|
||||
// }
|
||||
var done = function(err) {
|
||||
spinner.remove();
|
||||
if (err) {
|
||||
return;
|
||||
}
|
||||
hideEditForm();
|
||||
}
|
||||
// console.log(JSON.stringify(payload,null,4));
|
||||
RED.deploy.setDeployInflight(true);
|
||||
utils.sendRequest({
|
||||
url: "settings/user/keys",
|
||||
type: "POST",
|
||||
responses: {
|
||||
0: function(error) {
|
||||
done(error);
|
||||
},
|
||||
200: function(data) {
|
||||
refreshSSHKeyList(payload.name);
|
||||
done();
|
||||
},
|
||||
400: {
|
||||
'unexpected_error': function(error) {
|
||||
console.log(error);
|
||||
done(error);
|
||||
}
|
||||
},
|
||||
}
|
||||
},payload);
|
||||
});
|
||||
|
||||
row = $('<div class="user-settings-row projects-dialog-list"></div>').appendTo(container);
|
||||
var emptyItem = { empty: true };
|
||||
var expandKey = function(container,entry) {
|
||||
var row = $('<div class="projects-dialog-ssh-public-key">',{style:"position:relative"}).appendTo(container);
|
||||
var keyBox = $('<pre>',{style:"min-height: 80px"}).appendTo(row);
|
||||
var spinner = utils.addSpinnerOverlay(keyBox).addClass('projects-dialog-spinner-contain');
|
||||
var options = {
|
||||
url: 'settings/user/keys/'+entry.name,
|
||||
type: "GET",
|
||||
responses: {
|
||||
200: function(data) {
|
||||
keyBox.text(data.publickey);
|
||||
spinner.remove();
|
||||
},
|
||||
400: {
|
||||
'unexpected_error': function(error) {
|
||||
console.log(error);
|
||||
spinner.remove();
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
utils.sendRequest(options);
|
||||
|
||||
var formButtons = $('<span class="button-row" style="position: relative; float: right; margin: 10px;"></span>').appendTo(row);
|
||||
$('<button class="editor-button editor-button-small">Copy public key to clipboard</button>')
|
||||
.appendTo(formButtons)
|
||||
.click(function(evt) {
|
||||
try {
|
||||
evt.stopPropagation();
|
||||
evt.preventDefault();
|
||||
document.getSelection().selectAllChildren(keyBox[0]);
|
||||
var ret = document.execCommand('copy');
|
||||
document.getSelection().empty();
|
||||
} catch(err) {
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return row;
|
||||
}
|
||||
var keyList = $('<ol class="projects-dialog-ssh-key-list">').appendTo(row).editableList({
|
||||
height: 'auto',
|
||||
addButton: false,
|
||||
scrollOnAdd: false,
|
||||
addItem: function(row,index,entry) {
|
||||
var container = $('<div class="projects-dialog-list-entry">').appendTo(row);
|
||||
if (entry.empty) {
|
||||
container.addClass('red-ui-search-empty');
|
||||
container.text("No SSH keys");
|
||||
return;
|
||||
}
|
||||
var topRow = $('<div class="projects-dialog-ssh-key-header">').appendTo(container);
|
||||
$('<span class="entry-icon"><i class="fa fa-key"></i></span>').appendTo(topRow);
|
||||
$('<span class="entry-name">').text(entry.name).appendTo(topRow);
|
||||
var tools = $('<span class="button-row entry-tools">').appendTo(topRow);
|
||||
var expandedRow;
|
||||
topRow.click(function(e) {
|
||||
if (expandedRow) {
|
||||
expandedRow.slideUp(200,function() {
|
||||
expandedRow.remove();
|
||||
expandedRow = null;
|
||||
})
|
||||
} else {
|
||||
expandedRow = expandKey(container,entry);
|
||||
}
|
||||
})
|
||||
if (!entry.system) {
|
||||
$('<button class="editor-button editor-button-small"><i class="fa fa-trash"></i></button>')
|
||||
.appendTo(tools)
|
||||
.click(function(e) {
|
||||
e.stopPropagation();
|
||||
var spinner = utils.addSpinnerOverlay(row).addClass('projects-dialog-spinner-contain');
|
||||
var notification = RED.notify("Are you sure you want to delete the SSH key '"+entry.name+"'? This cannot be undone.", {
|
||||
type: 'warning',
|
||||
modal: true,
|
||||
fixed: true,
|
||||
buttons: [
|
||||
{
|
||||
text: RED._("common.label.cancel"),
|
||||
click: function() {
|
||||
spinner.remove();
|
||||
notification.close();
|
||||
}
|
||||
},
|
||||
{
|
||||
text: "Delete key",
|
||||
click: function() {
|
||||
notification.close();
|
||||
var url = "settings/user/keys/"+entry.name;
|
||||
var options = {
|
||||
url: url,
|
||||
type: "DELETE",
|
||||
responses: {
|
||||
200: function(data) {
|
||||
row.fadeOut(200,function() {
|
||||
keyList.editableList('removeItem',entry);
|
||||
setTimeout(spinner.remove, 100);
|
||||
if (keyList.editableList('length') === 0) {
|
||||
keyList.editableList('addItem',emptyItem);
|
||||
}
|
||||
});
|
||||
},
|
||||
400: {
|
||||
'unexpected_error': function(error) {
|
||||
console.log(error);
|
||||
spinner.remove();
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
utils.sendRequest(options);
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
}
|
||||
if (entry.expand) {
|
||||
expandedRow = expandKey(container,entry);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var refreshSSHKeyList = function(justAdded) {
|
||||
$.getJSON("settings/user/keys",function(result) {
|
||||
if (result.keys) {
|
||||
result.keys.sort(function(A,B) {
|
||||
return A.name.localeCompare(B.name);
|
||||
});
|
||||
keyList.editableList('empty');
|
||||
result.keys.forEach(function(key) {
|
||||
if (key.name === justAdded) {
|
||||
key.expand = true;
|
||||
}
|
||||
keyList.editableList('addItem',key);
|
||||
});
|
||||
if (keyList.editableList('length') === 0) {
|
||||
keyList.editableList('addItem',emptyItem);
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
refreshSSHKeyList();
|
||||
|
||||
}
|
||||
|
||||
function createSettingsPane(activeProject) {
|
||||
var pane = $('<div id="user-settings-tab-gitconfig" class="project-settings-tab-pane node-help"></div>');
|
||||
createGitUserSection(pane);
|
||||
createSSHKeySection(pane);
|
||||
return pane;
|
||||
}
|
||||
|
||||
var utils;
|
||||
function init(_utils) {
|
||||
utils = _utils;
|
||||
RED.userSettings.add({
|
||||
id:'gitconfig',
|
||||
title: "Git config", // TODO: nls
|
||||
get: createSettingsPane,
|
||||
close: function() {
|
||||
var currentGitSettings = RED.settings.get('git') || {};
|
||||
currentGitSettings.user = currentGitSettings.user || {};
|
||||
currentGitSettings.user.name = gitUsernameInput.val();
|
||||
currentGitSettings.user.email = gitEmailInput.val();
|
||||
RED.settings.set('git', currentGitSettings);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
init: init,
|
||||
};
|
||||
})();
|
||||
2380
editor/js/ui/projects/projects.js
Normal file
2380
editor/js/ui/projects/projects.js
Normal file
File diff suppressed because it is too large
Load Diff
1368
editor/js/ui/projects/tab-versionControl.js
Normal file
1368
editor/js/ui/projects/tab-versionControl.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -125,7 +125,7 @@ RED.search = (function() {
|
||||
function createDialog() {
|
||||
dialog = $("<div>",{id:"red-ui-search",class:"red-ui-search"}).appendTo("#main-container");
|
||||
var searchDiv = $("<div>",{class:"red-ui-search-container"}).appendTo(dialog);
|
||||
searchInput = $('<input type="text" placeholder="search your flows">').appendTo(searchDiv).searchBox({
|
||||
searchInput = $('<input type="text" data-i18n="[placeholder]menu.label.searchInput">').appendTo(searchDiv).searchBox({
|
||||
delay: 200,
|
||||
change: function() {
|
||||
search($(this).val());
|
||||
@@ -166,6 +166,7 @@ RED.search = (function() {
|
||||
}
|
||||
}
|
||||
});
|
||||
searchInput.i18n();
|
||||
|
||||
var searchResultsDiv = $("<div>",{class:"red-ui-search-results-container"}).appendTo(dialog);
|
||||
searchResults = $('<ol>',{id:"search-result-list", style:"position: absolute;top: 5px;bottom: 5px;left: 5px;right: 5px;"}).appendTo(searchResultsDiv).editableList({
|
||||
@@ -173,7 +174,7 @@ RED.search = (function() {
|
||||
addItem: function(container,i,object) {
|
||||
var node = object.node;
|
||||
if (node === undefined) {
|
||||
$('<div>',{class:"red-ui-search-empty"}).html(RED._('search.empty')).appendTo(container);
|
||||
$('<div>',{class:"red-ui-search-empty"}).text(RED._('search.empty')).appendTo(container);
|
||||
|
||||
} else {
|
||||
var def = node._def;
|
||||
@@ -199,12 +200,12 @@ RED.search = (function() {
|
||||
} else {
|
||||
workspace = "flow:"+workspace.label;
|
||||
}
|
||||
$('<div>',{class:"red-ui-search-result-node-flow"}).html(workspace).appendTo(contentDiv);
|
||||
$('<div>',{class:"red-ui-search-result-node-flow"}).text(workspace).appendTo(contentDiv);
|
||||
}
|
||||
|
||||
$('<div>',{class:"red-ui-search-result-node-label"}).html(object.label || node.id).appendTo(contentDiv);
|
||||
$('<div>',{class:"red-ui-search-result-node-type"}).html(node.type).appendTo(contentDiv);
|
||||
$('<div>',{class:"red-ui-search-result-node-id"}).html(node.id).appendTo(contentDiv);
|
||||
$('<div>',{class:"red-ui-search-result-node-label"}).text(object.label || node.id).appendTo(contentDiv);
|
||||
$('<div>',{class:"red-ui-search-result-node-type"}).text(node.type).appendTo(contentDiv);
|
||||
$('<div>',{class:"red-ui-search-result-node-id"}).text(node.id).appendTo(contentDiv);
|
||||
|
||||
div.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
|
||||
@@ -35,7 +35,8 @@ RED.sidebar = (function() {
|
||||
tab.onremove.call(tab);
|
||||
}
|
||||
},
|
||||
minimumActiveTabWidth: 110
|
||||
minimumActiveTabWidth: 70
|
||||
// scrollable: true
|
||||
});
|
||||
|
||||
var knownTabs = {
|
||||
|
||||
@@ -139,7 +139,7 @@ RED.subflow = (function() {
|
||||
RED.view.select();
|
||||
RED.nodes.dirty(true);
|
||||
RED.view.redraw();
|
||||
$("#workspace-subflow-output .spinner-value").html(subflow.out.length);
|
||||
$("#workspace-subflow-output .spinner-value").text(subflow.out.length);
|
||||
}
|
||||
|
||||
function removeSubflowOutput(removedSubflowOutputs) {
|
||||
@@ -216,7 +216,7 @@ RED.subflow = (function() {
|
||||
$("#workspace-subflow-input-add").toggleClass("active", activeSubflow.in.length !== 0);
|
||||
$("#workspace-subflow-input-remove").toggleClass("active",activeSubflow.in.length === 0);
|
||||
|
||||
$("#workspace-subflow-output .spinner-value").html(activeSubflow.out.length);
|
||||
$("#workspace-subflow-output .spinner-value").text(activeSubflow.out.length);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,13 +50,15 @@ RED.sidebar.info = (function() {
|
||||
}).hide();
|
||||
|
||||
nodeSection = sections.add({
|
||||
title: "Node",
|
||||
collapsible: false
|
||||
title: RED._("sidebar.info.info"),
|
||||
collapsible: true
|
||||
});
|
||||
nodeSection.expand();
|
||||
infoSection = sections.add({
|
||||
title: "Information",
|
||||
collapsible: false
|
||||
title: RED._("sidebar.info.nodeHelp"),
|
||||
collapsible: true
|
||||
});
|
||||
infoSection.expand();
|
||||
infoSection.content.css("padding","6px");
|
||||
infoSection.container.css("border-bottom","none");
|
||||
|
||||
@@ -96,23 +98,7 @@ RED.sidebar.info = (function() {
|
||||
RED.sidebar.show("info");
|
||||
}
|
||||
|
||||
function jsonFilter(key,value) {
|
||||
if (key === "") {
|
||||
return value;
|
||||
}
|
||||
var t = typeof value;
|
||||
if ($.isArray(value)) {
|
||||
return "[array:"+value.length+"]";
|
||||
} else if (t === "object") {
|
||||
return "[object]"
|
||||
} else if (t === "string") {
|
||||
if (value.length > 30) {
|
||||
return value.substring(0,30)+" ...";
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
// TODO: DRY - projects.js
|
||||
function addTargetToExternalLinks(el) {
|
||||
$(el).find("a").each(function(el) {
|
||||
var href = $(this).attr('href');
|
||||
@@ -123,76 +109,42 @@ RED.sidebar.info = (function() {
|
||||
return el;
|
||||
}
|
||||
function refresh(node) {
|
||||
if (node === undefined) {
|
||||
refreshSelection();
|
||||
return;
|
||||
}
|
||||
sections.show();
|
||||
$(nodeSection.content).empty();
|
||||
$(infoSection.content).empty();
|
||||
|
||||
var table = $('<table class="node-info"></table>');
|
||||
var tableBody = $('<tbody>').appendTo(table);
|
||||
var propRow;
|
||||
|
||||
var table = $('<table class="node-info"></table>').appendTo(nodeSection.content);
|
||||
var tableBody = $('<tbody>').appendTo(table);
|
||||
var subflowNode;
|
||||
if (node.type === "tab") {
|
||||
nodeSection.title.html("Flow");
|
||||
propRow = $('<tr class="node-info-node-row"><td>Name</td><td></td></tr>').appendTo(tableBody);
|
||||
$(propRow.children()[1]).html(' '+(node.label||""))
|
||||
propRow = $('<tr class="node-info-node-row"><td>'+RED._("sidebar.info.id")+"</td><td></td></tr>").appendTo(tableBody);
|
||||
RED.utils.createObjectElement(node.id).appendTo(propRow.children()[1]);
|
||||
propRow = $('<tr class="node-info-node-row"><td>Status</td><td></td></tr>').appendTo(tableBody);
|
||||
$(propRow.children()[1]).html((!!!node.disabled)?"Enabled":"Disabled")
|
||||
var subflowUserCount;
|
||||
|
||||
var activeProject = RED.projects.getActiveProject();
|
||||
if (activeProject) {
|
||||
propRow = $('<tr class="node-info-node-row"><td>Project</td><td></td></tr>').appendTo(tableBody);
|
||||
$(propRow.children()[1]).text(activeProject.name||"");
|
||||
$('<tr class="node-info-property-expand blank"><td colspan="2"></td></tr>').appendTo(tableBody);
|
||||
$('<button class="editor-button editor-button-small" style="position:absolute;right:2px;"><i class="fa fa-ellipsis-h"></i></button>')
|
||||
.appendTo(propRow.children()[1])
|
||||
.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
RED.projects.editProject();
|
||||
});
|
||||
}
|
||||
infoSection.container.show();
|
||||
if (node === null) {
|
||||
return;
|
||||
} else if (Array.isArray(node)) {
|
||||
infoSection.container.hide();
|
||||
propRow = $('<tr class="node-info-node-row"><td>'+RED._("sidebar.info.selection")+"</td><td></td></tr>").appendTo(tableBody);
|
||||
$(propRow.children()[1]).text(RED._("sidebar.info.nodes",{count:node.length}))
|
||||
} else {
|
||||
nodeSection.title.html("Node");
|
||||
if (node.type !== "subflow" && node.name) {
|
||||
$('<tr class="node-info-node-row"><td>'+RED._("common.label.name")+'</td><td> <span class="bidiAware" dir="'+RED.text.bidi.resolveBaseTextDir(node.name)+'">'+node.name+'</span></td></tr>').appendTo(tableBody);
|
||||
}
|
||||
$('<tr class="node-info-node-row"><td>'+RED._("sidebar.info.type")+"</td><td> "+node.type+"</td></tr>").appendTo(tableBody);
|
||||
propRow = $('<tr class="node-info-node-row"><td>'+RED._("sidebar.info.id")+"</td><td></td></tr>").appendTo(tableBody);
|
||||
RED.utils.createObjectElement(node.id).appendTo(propRow.children()[1]);
|
||||
|
||||
var m = /^subflow(:(.+))?$/.exec(node.type);
|
||||
|
||||
if (!m && node.type != "subflow" && node.type != "comment") {
|
||||
if (node._def) {
|
||||
var count = 0;
|
||||
var defaults = node._def.defaults;
|
||||
for (var n in defaults) {
|
||||
if (n != "name" && defaults.hasOwnProperty(n)) {
|
||||
var val = node[n];
|
||||
var type = typeof val;
|
||||
count++;
|
||||
propRow = $('<tr class="node-info-property-row'+(expandedSections.property?"":" hide")+'"><td>'+n+"</td><td></td></tr>").appendTo(tableBody);
|
||||
if (defaults[n].type) {
|
||||
var configNode = RED.nodes.node(val);
|
||||
if (!configNode) {
|
||||
RED.utils.createObjectElement(undefined).appendTo(propRow.children()[1]);
|
||||
} else {
|
||||
var configLabel = RED.utils.getNodeLabel(configNode,val);
|
||||
var container = propRow.children()[1];
|
||||
|
||||
var div = $('<span>',{class:""}).appendTo(container);
|
||||
var nodeDiv = $('<div>',{class:"palette_node palette_node_small"}).appendTo(div);
|
||||
var colour = configNode._def.color;
|
||||
var icon_url = RED.utils.getNodeIcon(configNode._def);
|
||||
nodeDiv.css({'backgroundColor':colour, "cursor":"pointer"});
|
||||
var iconContainer = $('<div/>',{class:"palette_icon_container"}).appendTo(nodeDiv);
|
||||
$('<div/>',{class:"palette_icon",style:"background-image: url("+icon_url+")"}).appendTo(iconContainer);
|
||||
var nodeContainer = $('<span></span>').css({"verticalAlign":"top","marginLeft":"6px"}).html(configLabel).appendTo(container);
|
||||
|
||||
nodeDiv.on('dblclick',function() {
|
||||
RED.editor.editConfig("", configNode.type, configNode.id);
|
||||
})
|
||||
|
||||
}
|
||||
} else {
|
||||
RED.utils.createObjectElement(val).appendTo(propRow.children()[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count > 0) {
|
||||
$('<tr class="node-info-property-expand blank"><td colspan="2"><a href="#" class=" node-info-property-header'+(expandedSections.property?" expanded":"")+'"><span class="node-info-property-show-more">show more</span><span class="node-info-property-show-less">show less</span> <i class="fa fa-caret-down"></i></a></td></tr>').appendTo(tableBody);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m) {
|
||||
if (m[2]) {
|
||||
subflowNode = RED.nodes.subflow(m[2]);
|
||||
@@ -200,49 +152,122 @@ RED.sidebar.info = (function() {
|
||||
subflowNode = node;
|
||||
}
|
||||
|
||||
$('<tr class="blank"><th colspan="2">'+RED._("sidebar.info.subflow")+'</th></tr>').appendTo(tableBody);
|
||||
|
||||
var userCount = 0;
|
||||
subflowUserCount = 0;
|
||||
var subflowType = "subflow:"+subflowNode.id;
|
||||
RED.nodes.eachNode(function(n) {
|
||||
if (n.type === subflowType) {
|
||||
userCount++;
|
||||
subflowUserCount++;
|
||||
}
|
||||
});
|
||||
$('<tr class="node-info-subflow-row"><td>'+RED._("common.label.name")+'</td><td><span class="bidiAware" dir=\"'+RED.text.bidi.resolveBaseTextDir(subflowNode.name)+'">'+subflowNode.name+'</span></td></tr>').appendTo(tableBody);
|
||||
$('<tr class="node-info-subflow-row"><td>'+RED._("sidebar.info.instances")+"</td><td>"+userCount+'</td></tr>').appendTo(tableBody);
|
||||
}
|
||||
if (node.type === "tab" || node.type === "subflow") {
|
||||
propRow = $('<tr class="node-info-node-row"><td>'+RED._("sidebar.info."+(node.type==='tab'?'flow':'subflow'))+'</td><td></td></tr>').appendTo(tableBody);
|
||||
RED.utils.createObjectElement(node.id).appendTo(propRow.children()[1]);
|
||||
propRow = $('<tr class="node-info-node-row"><td>'+RED._("sidebar.info.tabName")+"</td><td></td></tr>").appendTo(tableBody);
|
||||
$(propRow.children()[1]).text(node.label||node.name||"");
|
||||
if (node.type === "tab") {
|
||||
propRow = $('<tr class="node-info-node-row"><td>'+RED._("sidebar.info.status")+'</td><td></td></tr>').appendTo(tableBody);
|
||||
$(propRow.children()[1]).text((!!!node.disabled)?RED._("sidebar.info.enabled"):RED._("sidebar.info.disabled"))
|
||||
}
|
||||
} else {
|
||||
propRow = $('<tr class="node-info-node-row"><td>'+RED._("sidebar.info.node")+"</td><td></td></tr>").appendTo(tableBody);
|
||||
RED.utils.createObjectElement(node.id).appendTo(propRow.children()[1]);
|
||||
|
||||
|
||||
if (node.type !== "subflow" && node.name) {
|
||||
propRow = $('<tr class="node-info-node-row"><td>'+RED._("common.label.name")+'</td><td></td></tr>').appendTo(tableBody);
|
||||
$('<span class="bidiAware" dir="'+RED.text.bidi.resolveBaseTextDir(node.name)+'"></span>').text(node.name).appendTo(propRow.children()[1]);
|
||||
}
|
||||
if (!m) {
|
||||
propRow = $('<tr class="node-info-node-row"><td>'+RED._("sidebar.info.type")+"</td><td></td></tr>").appendTo(tableBody);
|
||||
$(propRow.children()[1]).text(node.type);
|
||||
}
|
||||
|
||||
if (!m && node.type != "subflow" && node.type != "comment") {
|
||||
if (node._def) {
|
||||
var count = 0;
|
||||
var defaults = node._def.defaults;
|
||||
for (var n in defaults) {
|
||||
if (n != "name" && defaults.hasOwnProperty(n)) {
|
||||
var val = node[n];
|
||||
var type = typeof val;
|
||||
count++;
|
||||
propRow = $('<tr class="node-info-property-row'+(expandedSections.property?"":" hide")+'"><td>'+n+"</td><td></td></tr>").appendTo(tableBody);
|
||||
if (defaults[n].type) {
|
||||
var configNode = RED.nodes.node(val);
|
||||
if (!configNode) {
|
||||
RED.utils.createObjectElement(undefined).appendTo(propRow.children()[1]);
|
||||
} else {
|
||||
var configLabel = RED.utils.getNodeLabel(configNode,val);
|
||||
var container = propRow.children()[1];
|
||||
|
||||
var div = $('<span>',{class:""}).appendTo(container);
|
||||
var nodeDiv = $('<div>',{class:"palette_node palette_node_small"}).appendTo(div);
|
||||
var colour = configNode._def.color;
|
||||
var icon_url = RED.utils.getNodeIcon(configNode._def);
|
||||
nodeDiv.css({'backgroundColor':colour, "cursor":"pointer"});
|
||||
var iconContainer = $('<div/>',{class:"palette_icon_container"}).appendTo(nodeDiv);
|
||||
$('<div/>',{class:"palette_icon",style:"background-image: url("+icon_url+")"}).appendTo(iconContainer);
|
||||
var nodeContainer = $('<span></span>').css({"verticalAlign":"top","marginLeft":"6px"}).text(configLabel).appendTo(container);
|
||||
|
||||
nodeDiv.on('dblclick',function() {
|
||||
RED.editor.editConfig("", configNode.type, configNode.id);
|
||||
})
|
||||
|
||||
}
|
||||
} else {
|
||||
RED.utils.createObjectElement(val).appendTo(propRow.children()[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count > 0) {
|
||||
$('<tr class="node-info-property-expand blank"><td colspan="2"><a href="#" class=" node-info-property-header'+(expandedSections.property?" expanded":"")+'"><span class="node-info-property-show-more">'+RED._("sidebar.info.showMore")+'</span><span class="node-info-property-show-less">'+RED._("sidebar.info.showLess")+'</span> <i class="fa fa-caret-down"></i></a></td></tr>').appendTo(tableBody);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node.type !== 'tab') {
|
||||
if (m) {
|
||||
$('<tr class="blank"><th colspan="2">'+RED._("sidebar.info.subflow")+'</th></tr>').appendTo(tableBody);
|
||||
$('<tr class="node-info-subflow-row"><td>'+RED._("common.label.name")+'</td><td><span class="bidiAware" dir=\"'+RED.text.bidi.resolveBaseTextDir(subflowNode.name)+'">'+subflowNode.name+'</span></td></tr>').appendTo(tableBody);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m) {
|
||||
$('<tr class="node-info-subflow-row"><td>'+RED._("sidebar.info.instances")+"</td><td>"+subflowUserCount+'</td></tr>').appendTo(tableBody);
|
||||
}
|
||||
|
||||
var infoText = "";
|
||||
if (!subflowNode && node.type !== "comment" && node.type !== "tab") {
|
||||
infoSection.title.text(RED._("sidebar.info.nodeHelp"));
|
||||
var helpText = $("script[data-help-name='"+node.type+"']").html()||('<span class="node-info-none">'+RED._("sidebar.info.none")+'</span>');
|
||||
infoText = helpText;
|
||||
} else if (node.type === "tab") {
|
||||
infoSection.title.text(RED._("sidebar.info.flowDesc"));
|
||||
infoText = marked(node.info||"")||('<span class="node-info-none">'+RED._("sidebar.info.none")+'</span>');
|
||||
}
|
||||
|
||||
if (subflowNode) {
|
||||
infoText = infoText + (marked(subflowNode.info||"")||('<span class="node-info-none">'+RED._("sidebar.info.none")+'</span>'));
|
||||
infoSection.title.text(RED._("sidebar.info.subflowDesc"));
|
||||
} else if (node._def && node._def.info) {
|
||||
infoSection.title.text(RED._("sidebar.info.nodeHelp"));
|
||||
var info = node._def.info;
|
||||
var textInfo = (typeof info === "function" ? info.call(node) : info);
|
||||
// TODO: help
|
||||
infoText = infoText + marked(textInfo);
|
||||
}
|
||||
if (infoText) {
|
||||
setInfoText(infoText);
|
||||
}
|
||||
|
||||
|
||||
$(".node-info-property-header").click(function(e) {
|
||||
e.preventDefault();
|
||||
expandedSections["property"] = !expandedSections["property"];
|
||||
$(this).toggleClass("expanded",expandedSections["property"]);
|
||||
$(".node-info-property-row").toggle(expandedSections["property"]);
|
||||
});
|
||||
}
|
||||
$(table).appendTo(nodeSection.content);
|
||||
|
||||
var infoText = "";
|
||||
|
||||
if (!subflowNode && node.type !== "comment" && node.type !== "tab") {
|
||||
var helpText = $("script[data-help-name='"+node.type+"']").html()||"";
|
||||
infoText = helpText;
|
||||
} else if (node.type === "tab") {
|
||||
infoText = marked(node.info||"");
|
||||
}
|
||||
|
||||
if (subflowNode) {
|
||||
infoText = infoText + marked(subflowNode.info||"");
|
||||
} else if (node._def && node._def.info) {
|
||||
var info = node._def.info;
|
||||
var textInfo = (typeof info === "function" ? info.call(node) : info);
|
||||
// TODO: help
|
||||
infoText = infoText + marked(textInfo);
|
||||
}
|
||||
if (infoText) {
|
||||
setInfoText(infoText);
|
||||
}
|
||||
|
||||
|
||||
$(".node-info-property-header").click(function(e) {
|
||||
e.preventDefault();
|
||||
expandedSections["property"] = !expandedSections["property"];
|
||||
$(this).toggleClass("expanded",expandedSections["property"]);
|
||||
$(".node-info-property-row").toggle(expandedSections["property"]);
|
||||
});
|
||||
}
|
||||
function setInfoText(infoText) {
|
||||
var info = addTargetToExternalLinks($('<div class="node-help"><span class="bidiAware" dir=\"'+RED.text.bidi.resolveBaseTextDir(infoText)+'">'+infoText+'</span></div>')).appendTo(infoSection.content);
|
||||
@@ -342,22 +367,25 @@ RED.sidebar.info = (function() {
|
||||
})();
|
||||
|
||||
function clear() {
|
||||
sections.hide();
|
||||
//
|
||||
// sections.hide();
|
||||
refresh(null);
|
||||
}
|
||||
|
||||
function set(html) {
|
||||
function set(html,title) {
|
||||
// tips.stop();
|
||||
sections.show();
|
||||
nodeSection.container.hide();
|
||||
// sections.show();
|
||||
// nodeSection.container.hide();
|
||||
infoSection.title.text(title||"");
|
||||
refresh(null);
|
||||
$(infoSection.content).empty();
|
||||
setInfoText(html);
|
||||
$(".sidebar-node-info-stack").scrollTop(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
RED.events.on("view:selection-changed",function(selection) {
|
||||
function refreshSelection(selection) {
|
||||
if (selection === undefined) {
|
||||
selection = RED.view.selection();
|
||||
}
|
||||
if (selection.nodes) {
|
||||
if (selection.nodes.length == 1) {
|
||||
var node = selection.nodes[0];
|
||||
@@ -366,6 +394,8 @@ RED.sidebar.info = (function() {
|
||||
} else {
|
||||
refresh(node);
|
||||
}
|
||||
} else {
|
||||
refresh(selection.nodes);
|
||||
}
|
||||
} else {
|
||||
var activeWS = RED.workspaces.active();
|
||||
@@ -378,11 +408,15 @@ RED.sidebar.info = (function() {
|
||||
if (workspace && workspace.info) {
|
||||
refresh(workspace);
|
||||
} else {
|
||||
clear();
|
||||
refresh(null)
|
||||
// clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
RED.events.on("view:selection-changed",refreshSelection);
|
||||
|
||||
return {
|
||||
init: init,
|
||||
|
||||
@@ -32,7 +32,15 @@ RED.tray = (function() {
|
||||
// var growButton = $('<a class="editor-tray-resize-button" style="cursor: w-resize;"><i class="fa fa-angle-left"></i></a>').appendTo(resizer);
|
||||
// var shrinkButton = $('<a class="editor-tray-resize-button" style="cursor: e-resize;"><i style="margin-left: 1px;" class="fa fa-angle-right"></i></a>').appendTo(resizer);
|
||||
if (options.title) {
|
||||
$('<div class="editor-tray-titlebar">'+options.title+'</div>').appendTo(header);
|
||||
var titles = stack.map(function(e) { return e.options.title });
|
||||
titles.push(options.title);
|
||||
var title = '<ul class="editor-tray-breadcrumbs"><li>'+titles.join("</li><li>")+'</li></ul>';
|
||||
|
||||
$('<div class="editor-tray-titlebar">'+title+'</div>').appendTo(header);
|
||||
}
|
||||
if (options.width === Infinity) {
|
||||
options.maximized = true;
|
||||
resizer.addClass('editor-tray-resize-maximised');
|
||||
}
|
||||
var buttonBar = $('<div class="editor-tray-toolbar"></div>').appendTo(header);
|
||||
var primaryButton;
|
||||
@@ -44,7 +52,7 @@ RED.tray = (function() {
|
||||
b.attr('id',button.id);
|
||||
}
|
||||
if (button.text) {
|
||||
b.html(button.text);
|
||||
b.text(button.text);
|
||||
}
|
||||
if (button.click) {
|
||||
b.click((function(action) {
|
||||
@@ -74,7 +82,8 @@ RED.tray = (function() {
|
||||
};
|
||||
stack.push(tray);
|
||||
|
||||
el.draggable({
|
||||
if (!options.maximized) {
|
||||
el.draggable({
|
||||
handle: resizer,
|
||||
axis: "x",
|
||||
start:function(event,ui) {
|
||||
@@ -103,16 +112,17 @@ RED.tray = (function() {
|
||||
tray.width = -ui.position.left;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function finishBuild() {
|
||||
$("#header-shade").show();
|
||||
$("#editor-shade").show();
|
||||
$("#palette-shade").show();
|
||||
$(".sidebar-shade").show();
|
||||
|
||||
tray.preferredWidth = Math.max(el.width(),500);
|
||||
body.css({"minWidth":tray.preferredWidth-40});
|
||||
|
||||
if (!options.maximized) {
|
||||
body.css({"minWidth":tray.preferredWidth-40});
|
||||
}
|
||||
if (options.width) {
|
||||
if (options.width > $("#editor-stack").position().left-8) {
|
||||
options.width = $("#editor-stack").position().left-8;
|
||||
@@ -175,7 +185,7 @@ RED.tray = (function() {
|
||||
var tray = stack[stack.length-1];
|
||||
var trayHeight = tray.tray.height()-tray.header.outerHeight()-tray.footer.outerHeight();
|
||||
tray.body.height(trayHeight);
|
||||
if (tray.width > $("#editor-stack").position().left-8) {
|
||||
if (tray.options.maximized || tray.width > $("#editor-stack").position().left-8) {
|
||||
tray.width = $("#editor-stack").position().left-8;
|
||||
tray.tray.width(tray.width);
|
||||
// tray.body.parent().width(tray.width);
|
||||
@@ -204,8 +214,11 @@ RED.tray = (function() {
|
||||
});
|
||||
},
|
||||
show: function show(options) {
|
||||
if (stack.length > 0) {
|
||||
if (stack.length > 0 && !options.overlay) {
|
||||
var oldTray = stack[stack.length-1];
|
||||
if (options.width === "inherit") {
|
||||
options.width = oldTray.tray.width();
|
||||
}
|
||||
oldTray.tray.css({
|
||||
right: -(oldTray.tray.width()+10)+"px"
|
||||
});
|
||||
@@ -232,14 +245,21 @@ RED.tray = (function() {
|
||||
tray.tray.remove();
|
||||
if (stack.length > 0) {
|
||||
var oldTray = stack[stack.length-1];
|
||||
oldTray.tray.appendTo("#editor-stack");
|
||||
setTimeout(function() {
|
||||
if (!oldTray.options.overlay) {
|
||||
oldTray.tray.appendTo("#editor-stack");
|
||||
setTimeout(function() {
|
||||
handleWindowResize();
|
||||
oldTray.tray.css({right:0});
|
||||
if (oldTray.options.show) {
|
||||
oldTray.options.show();
|
||||
}
|
||||
},0);
|
||||
} else {
|
||||
handleWindowResize();
|
||||
oldTray.tray.css({right:0});
|
||||
if (oldTray.options.show) {
|
||||
oldTray.options.show();
|
||||
}
|
||||
},0);
|
||||
}
|
||||
}
|
||||
if (done) {
|
||||
done();
|
||||
|
||||
@@ -12,12 +12,14 @@ RED.typeSearch = (function() {
|
||||
|
||||
var activeFilter = "";
|
||||
var addCallback;
|
||||
var cancelCallback;
|
||||
|
||||
var typesUsed = {};
|
||||
|
||||
function search(val) {
|
||||
activeFilter = val.toLowerCase();
|
||||
var visible = searchResults.editableList('filter');
|
||||
searchResults.editableList('sort');
|
||||
setTimeout(function() {
|
||||
selected = 0;
|
||||
searchResults.children().removeClass('selected');
|
||||
@@ -100,6 +102,23 @@ RED.typeSearch = (function() {
|
||||
}
|
||||
return (activeFilter==="")||(data.index.indexOf(activeFilter) > -1);
|
||||
},
|
||||
sort: function(A,B) {
|
||||
if (activeFilter === "") {
|
||||
return A.i - B.i;
|
||||
}
|
||||
var Ai = A.index.indexOf(activeFilter);
|
||||
var Bi = B.index.indexOf(activeFilter);
|
||||
if (Ai === -1) {
|
||||
return 1;
|
||||
}
|
||||
if (Bi === -1) {
|
||||
return -1;
|
||||
}
|
||||
if (Ai === Bi) {
|
||||
return sortTypeLabels(A,B);
|
||||
}
|
||||
return Ai-Bi;
|
||||
},
|
||||
addItem: function(container,i,object) {
|
||||
var def = object.def;
|
||||
object.index = object.type.toLowerCase();
|
||||
@@ -128,7 +147,7 @@ RED.typeSearch = (function() {
|
||||
var label = object.label;
|
||||
object.index += "|"+label.toLowerCase();
|
||||
|
||||
$('<div>',{class:"red-ui-search-result-node-label"}).html(label).appendTo(contentDiv);
|
||||
$('<div>',{class:"red-ui-search-result-node-label"}).text(label).appendTo(contentDiv);
|
||||
|
||||
div.click(function(evt) {
|
||||
evt.preventDefault();
|
||||
@@ -155,11 +174,19 @@ RED.typeSearch = (function() {
|
||||
t = t.parent();
|
||||
}
|
||||
hide(true);
|
||||
if (cancelCallback) {
|
||||
cancelCallback();
|
||||
}
|
||||
}
|
||||
}
|
||||
function show(opts) {
|
||||
if (!visible) {
|
||||
RED.keyboard.add("*","escape",function(){hide()});
|
||||
RED.keyboard.add("*","escape",function(){
|
||||
hide();
|
||||
if (cancelCallback) {
|
||||
cancelCallback();
|
||||
}
|
||||
});
|
||||
if (dialog === null) {
|
||||
createDialog();
|
||||
}
|
||||
@@ -175,6 +202,7 @@ RED.typeSearch = (function() {
|
||||
}
|
||||
refreshTypeList();
|
||||
addCallback = opts.add;
|
||||
closeCallback = opts.close;
|
||||
RED.events.emit("type-search:open");
|
||||
//shade.show();
|
||||
dialog.css({left:opts.x+"px",top:opts.y+"px"}).show();
|
||||
@@ -215,7 +243,17 @@ RED.typeSearch = (function() {
|
||||
}
|
||||
return label;
|
||||
}
|
||||
|
||||
function sortTypeLabels(a,b) {
|
||||
var al = a.label.toLowerCase();
|
||||
var bl = b.label.toLowerCase();
|
||||
if (al < bl) {
|
||||
return -1;
|
||||
} else if (al === bl) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
function refreshTypeList() {
|
||||
var i;
|
||||
searchResults.editableList('empty');
|
||||
@@ -236,41 +274,37 @@ RED.typeSearch = (function() {
|
||||
var items = [];
|
||||
RED.nodes.registry.getNodeTypes().forEach(function(t) {
|
||||
var def = RED.nodes.getType(t);
|
||||
if (def.category !== 'config' && t !== 'unknown') {
|
||||
if (def.category !== 'config' && t !== 'unknown' && t !== 'tab') {
|
||||
items.push({type:t,def: def, label:getTypeLabel(t,def)});
|
||||
}
|
||||
});
|
||||
items.sort(function(a,b) {
|
||||
var al = a.label.toLowerCase();
|
||||
var bl = b.label.toLowerCase();
|
||||
if (al < bl) {
|
||||
return -1;
|
||||
} else if (al === bl) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
})
|
||||
items.sort(sortTypeLabels);
|
||||
|
||||
var commonCount = 0;
|
||||
var item;
|
||||
var index = 0;
|
||||
for(i=0;i<common.length;i++) {
|
||||
item = {
|
||||
type: common[i],
|
||||
common: true,
|
||||
def: RED.nodes.getType(common[i])
|
||||
};
|
||||
item.label = getTypeLabel(item.type,item.def);
|
||||
if (i === common.length-1) {
|
||||
item.separator = true;
|
||||
var itemDef = RED.nodes.getType(common[i]);
|
||||
if (itemDef) {
|
||||
item = {
|
||||
type: common[i],
|
||||
common: true,
|
||||
def: itemDef,
|
||||
i: index++
|
||||
};
|
||||
item.label = getTypeLabel(item.type,item.def);
|
||||
if (i === common.length-1) {
|
||||
item.separator = true;
|
||||
}
|
||||
searchResults.editableList('addItem', item);
|
||||
}
|
||||
searchResults.editableList('addItem', item);
|
||||
}
|
||||
for(i=0;i<Math.min(5,recentlyUsed.length);i++) {
|
||||
item = {
|
||||
type:recentlyUsed[i],
|
||||
def: RED.nodes.getType(recentlyUsed[i]),
|
||||
recent: true
|
||||
recent: true,
|
||||
i: index++
|
||||
};
|
||||
item.label = getTypeLabel(item.type,item.def);
|
||||
if (i === recentlyUsed.length-1) {
|
||||
@@ -279,6 +313,7 @@ RED.typeSearch = (function() {
|
||||
searchResults.editableList('addItem', item);
|
||||
}
|
||||
for (i=0;i<items.length;i++) {
|
||||
items[i].i = index++;
|
||||
searchResults.editableList('addItem', items[i]);
|
||||
}
|
||||
setTimeout(function() {
|
||||
|
||||
@@ -29,11 +29,15 @@ RED.userSettings = (function() {
|
||||
if (settingsVisible) {
|
||||
return;
|
||||
}
|
||||
if (!RED.user.hasPermission("settings.write")) {
|
||||
RED.notify(RED._("user.errors.settings"),"error");
|
||||
return;
|
||||
}
|
||||
settingsVisible = true;
|
||||
var tabContainer;
|
||||
|
||||
var trayOptions = {
|
||||
title: "User Settings",
|
||||
title: RED._("menu.label.userSettings"),
|
||||
buttons: [
|
||||
{
|
||||
id: "node-dialog-ok",
|
||||
@@ -100,7 +104,7 @@ RED.userSettings = (function() {
|
||||
|
||||
var viewSettings = [
|
||||
{
|
||||
title: "Grid",
|
||||
title: "menu.label.view.grid",
|
||||
options: [
|
||||
{setting:"view-show-grid",oldSetting:"menu-menu-item-view-show-grid",label:"menu.label.view.showGrid",toggle:true,onchange:"core:toggle-show-grid"},
|
||||
{setting:"view-snap-grid",oldSetting:"menu-menu-item-view-snap-grid",label:"menu.label.view.snapGrid",toggle:true,onchange:"core:toggle-snap-grid"},
|
||||
@@ -108,13 +112,13 @@ RED.userSettings = (function() {
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Nodes",
|
||||
title: "menu.label.nodes",
|
||||
options: [
|
||||
{setting:"view-node-status",oldSetting:"menu-menu-item-status",label:"menu.label.displayStatus",default: true, toggle:true,onchange:"core:toggle-status"}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Other",
|
||||
title: "menu.label.other",
|
||||
options: [
|
||||
{setting:"view-show-tips",oldSettings:"menu-menu-item-show-tips",label:"menu.label.showTips",toggle:true,default:true,onchange:"core:toggle-show-tips"}
|
||||
]
|
||||
@@ -127,10 +131,13 @@ RED.userSettings = (function() {
|
||||
|
||||
var pane = $('<div id="user-settings-tab-view" class="node-help"></div>');
|
||||
|
||||
var currentEditorSettings = RED.settings.get('editor') || {};
|
||||
currentEditorSettings.view = currentEditorSettings.view || {};
|
||||
|
||||
viewSettings.forEach(function(section) {
|
||||
$('<h3></h3>').text(section.title).appendTo(pane);
|
||||
$('<h3></h3>').text(RED._(section.title)).appendTo(pane);
|
||||
section.options.forEach(function(opt) {
|
||||
var initialState = RED.settings.get(opt.setting);
|
||||
var initialState = currentEditorSettings.view[opt.setting];
|
||||
var row = $('<div class="user-settings-row"></div>').appendTo(pane);
|
||||
var input;
|
||||
if (opt.toggle) {
|
||||
@@ -147,7 +154,10 @@ RED.userSettings = (function() {
|
||||
|
||||
function setSelected(id, value) {
|
||||
var opt = allSettings[id];
|
||||
RED.settings.set(opt.setting,value);
|
||||
var currentEditorSettings = RED.settings.get('editor') || {};
|
||||
currentEditorSettings.view = currentEditorSettings.view || {};
|
||||
currentEditorSettings.view[opt.setting] = value;
|
||||
RED.settings.set('editor', currentEditorSettings);
|
||||
var callback = opt.onchange;
|
||||
if (typeof callback === 'string') {
|
||||
callback = RED.actions.get(callback);
|
||||
@@ -158,8 +168,9 @@ RED.userSettings = (function() {
|
||||
}
|
||||
function toggle(id) {
|
||||
var opt = allSettings[id];
|
||||
var state = RED.settings.get(opt.setting);
|
||||
setSelected(id,!state);
|
||||
var currentEditorSettings = RED.settings.get('editor') || {};
|
||||
currentEditorSettings.view = currentEditorSettings.view || {};
|
||||
setSelected(id,!currentEditorSettings.view[opt.setting]);
|
||||
}
|
||||
|
||||
|
||||
@@ -169,7 +180,7 @@ RED.userSettings = (function() {
|
||||
|
||||
addPane({
|
||||
id:'view',
|
||||
title: 'View',
|
||||
title: RED._("menu.label.view.view"),
|
||||
get: createViewPane,
|
||||
close: function() {
|
||||
viewSettings.forEach(function(section) {
|
||||
@@ -185,21 +196,26 @@ RED.userSettings = (function() {
|
||||
}
|
||||
})
|
||||
|
||||
var currentEditorSettings = RED.settings.get('editor') || {};
|
||||
currentEditorSettings.view = currentEditorSettings.view || {};
|
||||
var editorSettingsChanged = false;
|
||||
viewSettings.forEach(function(section) {
|
||||
section.options.forEach(function(opt) {
|
||||
if (opt.oldSetting) {
|
||||
var oldValue = RED.settings.get(opt.oldSetting);
|
||||
if (oldValue !== undefined && oldValue !== null) {
|
||||
RED.settings.set(opt.setting,oldValue);
|
||||
currentEditorSettings.view[opt.setting] = oldValue;
|
||||
editorSettingsChanged = true;
|
||||
RED.settings.remove(opt.oldSetting);
|
||||
}
|
||||
}
|
||||
allSettings[opt.setting] = opt;
|
||||
if (opt.onchange) {
|
||||
var value = RED.settings.get(opt.setting);
|
||||
if (value === null && opt.hasOwnProperty('default')) {
|
||||
var value = currentEditorSettings.view[opt.setting];
|
||||
if ((value === null || value === undefined) && opt.hasOwnProperty('default')) {
|
||||
value = opt.default;
|
||||
RED.settings.set(opt.setting,value);
|
||||
currentEditorSettings.view[opt.setting] = value;
|
||||
editorSettingsChanged = true;
|
||||
}
|
||||
|
||||
var callback = opt.onchange;
|
||||
@@ -212,6 +228,9 @@ RED.userSettings = (function() {
|
||||
}
|
||||
});
|
||||
});
|
||||
if (editorSettingsChanged) {
|
||||
RED.settings.set('editor',currentEditorSettings);
|
||||
}
|
||||
|
||||
}
|
||||
return {
|
||||
|
||||
@@ -26,14 +26,14 @@ RED.utils = (function() {
|
||||
function buildMessageSummaryValue(value) {
|
||||
var result;
|
||||
if (Array.isArray(value)) {
|
||||
result = $('<span class="debug-message-object-value debug-message-type-meta"></span>').html('array['+value.length+']');
|
||||
result = $('<span class="debug-message-object-value debug-message-type-meta"></span>').text('array['+value.length+']');
|
||||
} else if (value === null) {
|
||||
result = $('<span class="debug-message-object-value debug-message-type-null">null</span>');
|
||||
} else if (typeof value === 'object') {
|
||||
if (value.hasOwnProperty('type') && value.type === 'Buffer' && value.hasOwnProperty('data')) {
|
||||
result = $('<span class="debug-message-object-value debug-message-type-meta"></span>').html('buffer['+value.length+']');
|
||||
result = $('<span class="debug-message-object-value debug-message-type-meta"></span>').text('buffer['+value.length+']');
|
||||
} else if (value.hasOwnProperty('type') && value.type === 'array' && value.hasOwnProperty('data')) {
|
||||
result = $('<span class="debug-message-object-value debug-message-type-meta"></span>').html('array['+value.length+']');
|
||||
result = $('<span class="debug-message-object-value debug-message-type-meta"></span>').text('array['+value.length+']');
|
||||
} else {
|
||||
result = $('<span class="debug-message-object-value debug-message-type-meta">object</span>');
|
||||
}
|
||||
@@ -50,24 +50,58 @@ RED.utils = (function() {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function makeExpandable(el,onexpand,expand) {
|
||||
function makeExpandable(el,onbuild,ontoggle,expand) {
|
||||
el.addClass("debug-message-expandable");
|
||||
el.prop('toggle',function() {
|
||||
return function(state) {
|
||||
var parent = el.parent();
|
||||
if (parent.hasClass('collapsed')) {
|
||||
if (state) {
|
||||
if (onbuild && !parent.hasClass('built')) {
|
||||
onbuild();
|
||||
parent.addClass('built');
|
||||
}
|
||||
parent.removeClass('collapsed');
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (!state) {
|
||||
parent.addClass('collapsed');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
el.click(function(e) {
|
||||
var parent = $(this).parent();
|
||||
if (parent.hasClass('collapsed')) {
|
||||
if (onexpand && !parent.hasClass('built')) {
|
||||
onexpand();
|
||||
parent.addClass('built');
|
||||
var currentState = !parent.hasClass('collapsed');
|
||||
if ($(this).prop('toggle')(!currentState)) {
|
||||
if (ontoggle) {
|
||||
ontoggle(!currentState);
|
||||
}
|
||||
parent.removeClass('collapsed');
|
||||
} else {
|
||||
parent.addClass('collapsed');
|
||||
}
|
||||
// if (parent.hasClass('collapsed')) {
|
||||
// if (onbuild && !parent.hasClass('built')) {
|
||||
// onbuild();
|
||||
// parent.addClass('built');
|
||||
// }
|
||||
// if (ontoggle) {
|
||||
// ontoggle(true);
|
||||
// }
|
||||
// parent.removeClass('collapsed');
|
||||
// } else {
|
||||
// parent.addClass('collapsed');
|
||||
// if (ontoggle) {
|
||||
// ontoggle(false);
|
||||
// }
|
||||
// }
|
||||
e.preventDefault();
|
||||
});
|
||||
if (expand) {
|
||||
el.click();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var pinnedPaths = {};
|
||||
@@ -137,7 +171,7 @@ RED.utils = (function() {
|
||||
}
|
||||
|
||||
function formatNumber(element,obj,sourceId,path,cycle,initialFormat) {
|
||||
var format = (formattedPaths[sourceId] && formattedPaths[sourceId][path]) || initialFormat || "dec";
|
||||
var format = (formattedPaths[sourceId] && formattedPaths[sourceId][path] && formattedPaths[sourceId][path]['number']) || initialFormat || "dec";
|
||||
if (cycle) {
|
||||
if (format === 'dec') {
|
||||
if ((obj.toString().length===13) && (obj<=2147483647000)) {
|
||||
@@ -153,10 +187,12 @@ RED.utils = (function() {
|
||||
format = 'dec';
|
||||
}
|
||||
formattedPaths[sourceId] = formattedPaths[sourceId]||{};
|
||||
formattedPaths[sourceId][path] = format;
|
||||
formattedPaths[sourceId][path] = formattedPaths[sourceId][path]||{};
|
||||
formattedPaths[sourceId][path]['number'] = format;
|
||||
} else if (initialFormat !== undefined){
|
||||
formattedPaths[sourceId] = formattedPaths[sourceId]||{};
|
||||
formattedPaths[sourceId][path] = format;
|
||||
formattedPaths[sourceId][path] = formattedPaths[sourceId][path]||{};
|
||||
formattedPaths[sourceId][path]['number'] = format;
|
||||
}
|
||||
if (format === 'dec') {
|
||||
element.text(""+obj);
|
||||
@@ -170,7 +206,7 @@ RED.utils = (function() {
|
||||
}
|
||||
|
||||
function formatBuffer(element,button,sourceId,path,cycle) {
|
||||
var format = (formattedPaths[sourceId] && formattedPaths[sourceId][path]) || "raw";
|
||||
var format = (formattedPaths[sourceId] && formattedPaths[sourceId][path] && formattedPaths[sourceId][path]['buffer']) || "raw";
|
||||
if (cycle) {
|
||||
if (format === 'raw') {
|
||||
format = 'string';
|
||||
@@ -178,7 +214,8 @@ RED.utils = (function() {
|
||||
format = 'raw';
|
||||
}
|
||||
formattedPaths[sourceId] = formattedPaths[sourceId]||{};
|
||||
formattedPaths[sourceId][path] = format;
|
||||
formattedPaths[sourceId][path] = formattedPaths[sourceId][path]||{};
|
||||
formattedPaths[sourceId][path]['buffer'] = format;
|
||||
}
|
||||
if (format === 'raw') {
|
||||
button.text('raw');
|
||||
@@ -189,10 +226,23 @@ RED.utils = (function() {
|
||||
}
|
||||
}
|
||||
|
||||
function buildMessageElement(obj,key,typeHint,hideKey,path,sourceId,rootPath,expandPaths) {
|
||||
function buildMessageElement(obj,options) {
|
||||
options = options || {};
|
||||
var key = options.key;
|
||||
var typeHint = options.typeHint;
|
||||
var hideKey = options.hideKey;
|
||||
var path = options.path;
|
||||
var sourceId = options.sourceId;
|
||||
var rootPath = options.rootPath;
|
||||
var expandPaths = options.expandPaths;
|
||||
var ontoggle = options.ontoggle;
|
||||
var exposeApi = options.exposeApi;
|
||||
|
||||
var subElements = {};
|
||||
var i;
|
||||
var e;
|
||||
var entryObj;
|
||||
var expandableHeader;
|
||||
var header;
|
||||
var headerHead;
|
||||
var value;
|
||||
@@ -254,10 +304,10 @@ RED.utils = (function() {
|
||||
element.addClass('collapsed');
|
||||
$('<i class="fa fa-caret-right debug-message-object-handle"></i> ').prependTo(header);
|
||||
makeExpandable(header, function() {
|
||||
$('<span class="debug-message-type-meta debug-message-object-type-header"></span>').html(typeHint||'string').appendTo(header);
|
||||
$('<span class="debug-message-type-meta debug-message-object-type-header"></span>').text(typeHint||'string').appendTo(header);
|
||||
var row = $('<div class="debug-message-object-entry collapsed"></div>').appendTo(element);
|
||||
$('<pre class="debug-message-type-string"></pre>').text(obj).appendTo(row);
|
||||
},checkExpanded(strippedKey,expandPaths));
|
||||
},function(state) {if (ontoggle) { ontoggle(path,state);}}, checkExpanded(strippedKey,expandPaths));
|
||||
}
|
||||
e = $('<span class="debug-message-type-string debug-message-object-header"></span>').html('"'+formatString(sanitize(obj))+'"').appendTo(entryObj);
|
||||
if (/^#[0-9a-f]{6}$/i.test(obj)) {
|
||||
@@ -308,7 +358,7 @@ RED.utils = (function() {
|
||||
element.addClass('debug-message-buffer-raw');
|
||||
}
|
||||
if (key) {
|
||||
headerHead = $('<span class="debug-message-type-meta"></span>').html(typeHint||(type+'['+originalLength+']')).appendTo(entryObj);
|
||||
headerHead = $('<span class="debug-message-type-meta"></span>').text(typeHint||(type+'['+originalLength+']')).appendTo(entryObj);
|
||||
} else {
|
||||
headerHead = $('<span class="debug-message-object-header"></span>').appendTo(entryObj);
|
||||
$('<span>[ </span>').appendTo(headerHead);
|
||||
@@ -331,7 +381,7 @@ RED.utils = (function() {
|
||||
|
||||
makeExpandable(header,function() {
|
||||
if (!key) {
|
||||
headerHead = $('<span class="debug-message-type-meta debug-message-object-type-header"></span>').html(typeHint||(type+'['+originalLength+']')).appendTo(header);
|
||||
headerHead = $('<span class="debug-message-type-meta debug-message-object-type-header"></span>').text(typeHint||(type+'['+originalLength+']')).appendTo(header);
|
||||
}
|
||||
if (type === 'buffer') {
|
||||
var stringRow = $('<div class="debug-message-string-rows"></div>').appendTo(element);
|
||||
@@ -344,7 +394,7 @@ RED.utils = (function() {
|
||||
}
|
||||
$('<pre class="debug-message-type-string"></pre>').text(stringEncoding).appendTo(sr);
|
||||
var bufferOpts = $('<span class="debug-message-buffer-opts"></span>').appendTo(headerHead);
|
||||
var switchFormat = $('<a href="#"></a>').addClass('selected').html('raw').appendTo(bufferOpts).click(function(e) {
|
||||
var switchFormat = $('<a href="#"></a>').addClass('selected').text('raw').appendTo(bufferOpts).click(function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
formatBuffer(element,$(this),sourceId,path,true);
|
||||
@@ -356,7 +406,20 @@ RED.utils = (function() {
|
||||
if (fullLength <= 10) {
|
||||
for (i=0;i<fullLength;i++) {
|
||||
row = $('<div class="debug-message-object-entry collapsed"></div>').appendTo(arrayRows);
|
||||
buildMessageElement(data[i],""+i,type==='buffer'?'hex':false,false,path+"["+i+"]",sourceId,rootPath,expandPaths).appendTo(row);
|
||||
subElements[path+"["+i+"]"] = buildMessageElement(
|
||||
data[i],
|
||||
{
|
||||
key: ""+i,
|
||||
typeHint: type==='buffer'?'hex':false,
|
||||
hideKey: false,
|
||||
path: path+"["+i+"]",
|
||||
sourceId: sourceId,
|
||||
rootPath: rootPath,
|
||||
expandPaths: expandPaths,
|
||||
ontoggle: ontoggle,
|
||||
exposeApi: exposeApi
|
||||
}
|
||||
).appendTo(row);
|
||||
}
|
||||
} else {
|
||||
for (i=0;i<fullLength;i+=10) {
|
||||
@@ -371,17 +434,35 @@ RED.utils = (function() {
|
||||
return function() {
|
||||
for (var i=min;i<=max;i++) {
|
||||
var row = $('<div class="debug-message-object-entry collapsed"></div>').appendTo(parent);
|
||||
buildMessageElement(data[i],""+i,type==='buffer'?'hex':false,false,path+"["+i+"]",sourceId,rootPath,expandPaths).appendTo(row);
|
||||
subElements[path+"["+i+"]"] = buildMessageElement(
|
||||
data[i],
|
||||
{
|
||||
key: ""+i,
|
||||
typeHint: type==='buffer'?'hex':false,
|
||||
hideKey: false,
|
||||
path: path+"["+i+"]",
|
||||
sourceId: sourceId,
|
||||
rootPath: rootPath,
|
||||
expandPaths: expandPaths,
|
||||
ontoggle: ontoggle,
|
||||
exposeApi: exposeApi
|
||||
|
||||
}
|
||||
).appendTo(row);
|
||||
}
|
||||
}
|
||||
})(),checkExpanded(strippedKey,expandPaths,minRange,Math.min(fullLength-1,(minRange+9))));
|
||||
})(),
|
||||
(function() { var path = path+"["+i+"]"; return function(state) {if (ontoggle) { ontoggle(path,state);}}})(),
|
||||
checkExpanded(strippedKey,expandPaths,minRange,Math.min(fullLength-1,(minRange+9))));
|
||||
$('<span class="debug-message-object-key"></span>').html("["+minRange+" … "+Math.min(fullLength-1,(minRange+9))+"]").appendTo(header);
|
||||
}
|
||||
if (fullLength < originalLength) {
|
||||
$('<div class="debug-message-object-entry collapsed"><span class="debug-message-object-key">['+fullLength+' … '+originalLength+']</span></div>').appendTo(arrayRows);
|
||||
}
|
||||
}
|
||||
},checkExpanded(strippedKey,expandPaths));
|
||||
},
|
||||
function(state) {if (ontoggle) { ontoggle(path,state);}},
|
||||
checkExpanded(strippedKey,expandPaths));
|
||||
}
|
||||
} else if (typeof obj === 'object') {
|
||||
element.addClass('collapsed');
|
||||
@@ -390,25 +471,43 @@ RED.utils = (function() {
|
||||
$('<i class="fa fa-caret-right debug-message-object-handle"></i> ').prependTo(header);
|
||||
makeExpandable(header, function() {
|
||||
if (!key) {
|
||||
$('<span class="debug-message-type-meta debug-message-object-type-header"></span>').html('object').appendTo(header);
|
||||
$('<span class="debug-message-type-meta debug-message-object-type-header"></span>').text('object').appendTo(header);
|
||||
}
|
||||
for (i=0;i<keys.length;i++) {
|
||||
var row = $('<div class="debug-message-object-entry collapsed"></div>').appendTo(element);
|
||||
var newPath = path;
|
||||
if (/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(keys[i])) {
|
||||
newPath += (newPath.length > 0?".":"")+keys[i];
|
||||
} else {
|
||||
newPath += "[\""+keys[i].replace(/"/,"\\\"")+"\"]"
|
||||
if (newPath !== undefined) {
|
||||
if (/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(keys[i])) {
|
||||
newPath += (newPath.length > 0?".":"")+keys[i];
|
||||
} else {
|
||||
newPath += "[\""+keys[i].replace(/"/,"\\\"")+"\"]"
|
||||
}
|
||||
}
|
||||
buildMessageElement(obj[keys[i]],keys[i],false,false,newPath,sourceId,rootPath,expandPaths).appendTo(row);
|
||||
subElements[newPath] = buildMessageElement(
|
||||
obj[keys[i]],
|
||||
{
|
||||
key: keys[i],
|
||||
typeHint: false,
|
||||
hideKey: false,
|
||||
path: newPath,
|
||||
sourceId: sourceId,
|
||||
rootPath: rootPath,
|
||||
expandPaths: expandPaths,
|
||||
ontoggle: ontoggle,
|
||||
exposeApi: exposeApi
|
||||
|
||||
}
|
||||
).appendTo(row);
|
||||
}
|
||||
if (keys.length === 0) {
|
||||
$('<div class="debug-message-object-entry debug-message-type-meta collapsed"></div>').text("empty").appendTo(element);
|
||||
}
|
||||
},checkExpanded(strippedKey,expandPaths));
|
||||
},
|
||||
function(state) {if (ontoggle) { ontoggle(path,state);}},
|
||||
checkExpanded(strippedKey,expandPaths));
|
||||
}
|
||||
if (key) {
|
||||
$('<span class="debug-message-type-meta"></span>').html('object').appendTo(entryObj);
|
||||
$('<span class="debug-message-type-meta"></span>').text('object').appendTo(entryObj);
|
||||
} else {
|
||||
headerHead = $('<span class="debug-message-object-header"></span>').appendTo(entryObj);
|
||||
$('<span>{ </span>').appendTo(headerHead);
|
||||
@@ -432,6 +531,28 @@ RED.utils = (function() {
|
||||
} else {
|
||||
$('<span class="debug-message-type-other"></span>').text(""+obj).appendTo(entryObj);
|
||||
}
|
||||
if (exposeApi) {
|
||||
element.prop('expand', function() { return function(targetPath, state) {
|
||||
if (path === targetPath) {
|
||||
if (header.prop('toggle')) {
|
||||
header.prop('toggle')(state);
|
||||
}
|
||||
} else if (subElements[targetPath] && subElements[targetPath].prop('expand') ) {
|
||||
subElements[targetPath].prop('expand')(targetPath,state);
|
||||
} else {
|
||||
for (var p in subElements) {
|
||||
if (subElements.hasOwnProperty(p)) {
|
||||
if (targetPath.indexOf(p) === 0) {
|
||||
if (subElements[p].prop('expand') ) {
|
||||
subElements[p].prop('expand')(targetPath,state);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}});
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
@@ -571,16 +692,25 @@ RED.utils = (function() {
|
||||
return result;
|
||||
}
|
||||
|
||||
function getNodeIcon(def,node) {
|
||||
if (def.category === 'config') {
|
||||
return "icons/node-red/cog.png"
|
||||
} else if (node && node.type === 'tab') {
|
||||
return "icons/node-red/subflow.png"
|
||||
} else if (node && node.type === 'unknown') {
|
||||
return "icons/node-red/alert.png"
|
||||
function separateIconPath(icon) {
|
||||
var result = {module: "", file: ""};
|
||||
if (icon) {
|
||||
var index = icon.indexOf('/');
|
||||
if (index !== -1) {
|
||||
result.module = icon.slice(0, index);
|
||||
result.file = icon.slice(index + 1);
|
||||
} else {
|
||||
result.file = icon;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getDefaultNodeIcon(def,node) {
|
||||
var icon_url;
|
||||
if (typeof def.icon === "function") {
|
||||
if (node && node.type === "subflow") {
|
||||
icon_url = "node-red/subflow.png";
|
||||
} else if (typeof def.icon === "function") {
|
||||
try {
|
||||
icon_url = def.icon.call(node);
|
||||
} catch(err) {
|
||||
@@ -590,7 +720,50 @@ RED.utils = (function() {
|
||||
} else {
|
||||
icon_url = def.icon;
|
||||
}
|
||||
return "icons/"+def.set.module+"/"+icon_url;
|
||||
|
||||
var iconPath = separateIconPath(icon_url);
|
||||
if (!iconPath.module) {
|
||||
if (def.set) {
|
||||
iconPath.module = def.set.module;
|
||||
} else {
|
||||
// Handle subflow instance nodes that don't have def.set
|
||||
iconPath.module = "node-red";
|
||||
}
|
||||
}
|
||||
return iconPath;
|
||||
}
|
||||
|
||||
function isIconExists(iconPath) {
|
||||
var iconSets = RED.nodes.getIconSets();
|
||||
var iconFileList = iconSets[iconPath.module];
|
||||
if (iconFileList && iconFileList.indexOf(iconPath.file) !== -1) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function getNodeIcon(def,node) {
|
||||
if (def.category === 'config') {
|
||||
return "icons/node-red/cog.png"
|
||||
} else if (node && node.type === 'tab') {
|
||||
return "icons/node-red/subflow.png"
|
||||
} else if (node && node.type === 'unknown') {
|
||||
return "icons/node-red/alert.png"
|
||||
} else if (node && node.icon) {
|
||||
var iconPath = separateIconPath(node.icon);
|
||||
if (isIconExists(iconPath)) {
|
||||
return "icons/" + node.icon;
|
||||
}
|
||||
}
|
||||
|
||||
var iconPath = getDefaultNodeIcon(def, node);
|
||||
if (def.category === 'subflows') {
|
||||
if (!isIconExists(iconPath)) {
|
||||
return "icons/node-red/subflow.png";
|
||||
}
|
||||
}
|
||||
return "icons/"+iconPath.module+"/"+iconPath.file;
|
||||
}
|
||||
|
||||
function getNodeLabel(node,defaultLabel) {
|
||||
@@ -610,12 +783,23 @@ RED.utils = (function() {
|
||||
return RED.text.bidi.enforceTextDirectionWithUCC(l);
|
||||
}
|
||||
|
||||
function addSpinnerOverlay(container,contain) {
|
||||
var spinner = $('<div class="projects-dialog-spinner "><img src="red/images/spin.svg"/></div>').appendTo(container);
|
||||
if (contain) {
|
||||
spinner.addClass('projects-dialog-spinner-contain');
|
||||
}
|
||||
return spinner;
|
||||
}
|
||||
|
||||
return {
|
||||
createObjectElement: buildMessageElement,
|
||||
getMessageProperty: getMessageProperty,
|
||||
normalisePropertyExpression: normalisePropertyExpression,
|
||||
validatePropertyExpression: validatePropertyExpression,
|
||||
separateIconPath: separateIconPath,
|
||||
getDefaultNodeIcon: getDefaultNodeIcon,
|
||||
getNodeIcon: getNodeIcon,
|
||||
getNodeLabel: getNodeLabel,
|
||||
addSpinnerOverlay: addSpinnerOverlay
|
||||
}
|
||||
})();
|
||||
|
||||
@@ -81,6 +81,9 @@ RED.view = (function() {
|
||||
.style("cursor","crosshair")
|
||||
.on("mousedown", function() {
|
||||
focusView();
|
||||
})
|
||||
.on("contextmenu", function(){
|
||||
d3.event.preventDefault();
|
||||
});
|
||||
|
||||
var vis = outer
|
||||
@@ -396,10 +399,10 @@ RED.view = (function() {
|
||||
}
|
||||
});
|
||||
$("#chart").focus(function() {
|
||||
$("#workspace-tabs").addClass("workspace-focussed")
|
||||
$("#workspace-tabs").addClass("workspace-focussed");
|
||||
});
|
||||
$("#chart").blur(function() {
|
||||
$("#workspace-tabs").removeClass("workspace-focussed")
|
||||
$("#workspace-tabs").removeClass("workspace-focussed");
|
||||
});
|
||||
|
||||
RED.actions.add("core:copy-selection-to-internal-clipboard",copySelection);
|
||||
@@ -487,6 +490,7 @@ RED.view = (function() {
|
||||
}
|
||||
} else {
|
||||
var subflow = RED.nodes.subflow(m[1]);
|
||||
nn.name = "";
|
||||
nn.inputs = subflow.in.length;
|
||||
nn.outputs = subflow.out.length;
|
||||
}
|
||||
@@ -546,6 +550,9 @@ RED.view = (function() {
|
||||
RED.typeSearch.show({
|
||||
x:d3.event.clientX-mainPos.left-node_width/2,
|
||||
y:d3.event.clientY-mainPos.top-node_height/2,
|
||||
cancel: function() {
|
||||
resetMouseVars();
|
||||
},
|
||||
add: function(type) {
|
||||
var result = addNode(type);
|
||||
if (!result) {
|
||||
@@ -683,7 +690,7 @@ RED.view = (function() {
|
||||
var mousePos;
|
||||
if (mouse_mode == RED.state.JOINING || mouse_mode === RED.state.QUICK_JOINING) {
|
||||
// update drag line
|
||||
if (drag_lines.length === 0) {
|
||||
if (drag_lines.length === 0 && mousedown_port_type !== null) {
|
||||
if (d3.event.shiftKey) {
|
||||
// Get all the wires we need to detach.
|
||||
var links = [];
|
||||
@@ -1141,7 +1148,6 @@ RED.view = (function() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var selectionJSON = activeWorkspace+":"+JSON.stringify(selection,function(key,value) {
|
||||
if (key === 'nodes') {
|
||||
return value.map(function(n) { return n.id })
|
||||
@@ -1348,7 +1354,7 @@ RED.view = (function() {
|
||||
mouseup_node = null;
|
||||
mousedown_link = null;
|
||||
mouse_mode = 0;
|
||||
mousedown_port_type = PORT_TYPE_OUTPUT;
|
||||
mousedown_port_type = null;
|
||||
activeSpliceLink = null;
|
||||
spliceActive = false;
|
||||
d3.select(".link_splice").classed("link_splice",false);
|
||||
@@ -1390,7 +1396,7 @@ RED.view = (function() {
|
||||
|
||||
function portMouseUp(d,portType,portIndex) {
|
||||
var i;
|
||||
if (mouse_mode === RED.state.QUICK_JOINING) {
|
||||
if (mouse_mode === RED.state.QUICK_JOINING && drag_lines.length > 0) {
|
||||
if (drag_lines[0].node===d) {
|
||||
return
|
||||
}
|
||||
@@ -2767,7 +2773,7 @@ RED.view = (function() {
|
||||
if (v === undefined) {
|
||||
return gridSize;
|
||||
} else {
|
||||
gridSize = v;
|
||||
gridSize = Math.max(5,v);
|
||||
updateGrid();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ RED.workspaces = (function() {
|
||||
workspaceIndex += 1;
|
||||
} while ($("#workspace-tabs a[title='"+RED._('workspace.defaultName',{number:workspaceIndex})+"']").size() !== 0);
|
||||
|
||||
ws = {type:"tab",id:tabId,label:RED._('workspace.defaultName',{number:workspaceIndex})};
|
||||
ws = {type:"tab",id:tabId,disabled: false,info:"",label:RED._('workspace.defaultName',{number:workspaceIndex})};
|
||||
RED.nodes.addWorkspace(ws);
|
||||
workspace_tabs.addTab(ws);
|
||||
workspace_tabs.activateTab(tabId);
|
||||
@@ -43,7 +43,7 @@ RED.workspaces = (function() {
|
||||
return ws;
|
||||
}
|
||||
function deleteWorkspace(ws) {
|
||||
if (workspace_tabs.count() == 1) {
|
||||
if (workspaceTabCount === 1) {
|
||||
return;
|
||||
}
|
||||
removeWorkspace(ws);
|
||||
@@ -65,7 +65,7 @@ RED.workspaces = (function() {
|
||||
buttons: [
|
||||
{
|
||||
id: "node-dialog-delete",
|
||||
class: 'leftButton'+((workspace_tabs.count() == 1)?" disabled":""),
|
||||
class: 'leftButton'+((workspaceTabCount === 1)?" disabled":""),
|
||||
text: RED._("common.label.delete"), //'<i class="fa fa-trash"></i>',
|
||||
click: function() {
|
||||
deleteWorkspace(workspace);
|
||||
@@ -172,12 +172,12 @@ RED.workspaces = (function() {
|
||||
i.addClass('fa-toggle-on');
|
||||
i.removeClass('fa-toggle-off');
|
||||
$("#node-input-disabled").prop("checked",false);
|
||||
$("#node-input-disabled-label").html(RED._("editor:workspace.enabled"));
|
||||
$("#node-input-disabled-label").text(RED._("editor:workspace.enabled"));
|
||||
} else {
|
||||
i.addClass('fa-toggle-off');
|
||||
i.removeClass('fa-toggle-on');
|
||||
$("#node-input-disabled").prop("checked",true);
|
||||
$("#node-input-disabled-label").html(RED._("editor:workspace.disabled"));
|
||||
$("#node-input-disabled-label").text(RED._("editor:workspace.disabled"));
|
||||
}
|
||||
})
|
||||
|
||||
@@ -185,13 +185,13 @@ RED.workspaces = (function() {
|
||||
$("#node-input-disabled").prop("checked",workspace.disabled);
|
||||
if (workspace.disabled) {
|
||||
dialogForm.find("#node-input-disabled-btn i").removeClass('fa-toggle-on').addClass('fa-toggle-off');
|
||||
$("#node-input-disabled-label").html(RED._("editor:workspace.disabled"));
|
||||
$("#node-input-disabled-label").text(RED._("editor:workspace.disabled"));
|
||||
} else {
|
||||
$("#node-input-disabled-label").html(RED._("editor:workspace.enabled"));
|
||||
$("#node-input-disabled-label").text(RED._("editor:workspace.enabled"));
|
||||
}
|
||||
} else {
|
||||
workspace.disabled = false;
|
||||
$("#node-input-disabled-label").html(RED._("editor:workspace.enabled"));
|
||||
$("#node-input-disabled-label").text(RED._("editor:workspace.enabled"));
|
||||
}
|
||||
|
||||
$('<input type="text" style="display: none;" />').prependTo(dialogForm);
|
||||
@@ -214,6 +214,7 @@ RED.workspaces = (function() {
|
||||
|
||||
|
||||
var workspace_tabs;
|
||||
var workspaceTabCount = 0;
|
||||
function createWorkspaceTabs() {
|
||||
workspace_tabs = RED.tabs.create({
|
||||
id: "workspace-tabs",
|
||||
@@ -240,14 +241,26 @@ RED.workspaces = (function() {
|
||||
}
|
||||
},
|
||||
onadd: function(tab) {
|
||||
if (tab.type === "tab") {
|
||||
workspaceTabCount++;
|
||||
}
|
||||
$('<span class="workspace-disabled-icon"><i class="fa fa-ban"></i> </span>').prependTo("#red-ui-tab-"+(tab.id.replace(".","-"))+" .red-ui-tab-label");
|
||||
if (tab.disabled) {
|
||||
$("#red-ui-tab-"+(tab.id.replace(".","-"))).addClass('workspace-disabled');
|
||||
}
|
||||
RED.menu.setDisabled("menu-item-workspace-delete",workspace_tabs.count() == 1);
|
||||
RED.menu.setDisabled("menu-item-workspace-delete",workspaceTabCount <= 1);
|
||||
if (workspaceTabCount === 1) {
|
||||
showWorkspace();
|
||||
}
|
||||
},
|
||||
onremove: function(tab) {
|
||||
RED.menu.setDisabled("menu-item-workspace-delete",workspace_tabs.count() == 1);
|
||||
if (tab.type === "tab") {
|
||||
workspaceTabCount--;
|
||||
}
|
||||
RED.menu.setDisabled("menu-item-workspace-delete",workspaceTabCount <= 1);
|
||||
if (workspaceTabCount === 0) {
|
||||
hideWorkspace();
|
||||
}
|
||||
},
|
||||
onreorder: function(oldOrder, newOrder) {
|
||||
RED.history.push({t:'reorder',order:oldOrder,dirty:RED.nodes.dirty()});
|
||||
@@ -260,6 +273,17 @@ RED.workspaces = (function() {
|
||||
addWorkspace();
|
||||
}
|
||||
});
|
||||
workspaceTabCount = 0;
|
||||
}
|
||||
function showWorkspace() {
|
||||
$("#workspace .red-ui-tabs").show()
|
||||
$("#chart").show()
|
||||
$("#workspace-footer").children().show()
|
||||
}
|
||||
function hideWorkspace() {
|
||||
$("#workspace .red-ui-tabs").hide()
|
||||
$("#chart").hide()
|
||||
$("#workspace-footer").children().hide()
|
||||
}
|
||||
|
||||
function init() {
|
||||
@@ -280,6 +304,8 @@ RED.workspaces = (function() {
|
||||
RED.actions.add("core:add-flow",addWorkspace);
|
||||
RED.actions.add("core:edit-flow",editWorkspace);
|
||||
RED.actions.add("core:remove-flow",removeWorkspace);
|
||||
|
||||
hideWorkspace();
|
||||
}
|
||||
|
||||
function editWorkspace(id) {
|
||||
@@ -294,6 +320,9 @@ RED.workspaces = (function() {
|
||||
workspace_tabs.removeTab(ws.id);
|
||||
}
|
||||
}
|
||||
if (ws.id === activeWorkspace) {
|
||||
activeWorkspace = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function setWorkspaceOrder(order) {
|
||||
@@ -313,7 +342,7 @@ RED.workspaces = (function() {
|
||||
return workspace_tabs.contains(id);
|
||||
},
|
||||
count: function() {
|
||||
return workspace_tabs.count();
|
||||
return workspaceTabCount;
|
||||
},
|
||||
active: function() {
|
||||
return activeWorkspace
|
||||
|
||||
@@ -50,7 +50,7 @@ RED.user = (function() {
|
||||
for (;i<data.prompts.length;i++) {
|
||||
var field = data.prompts[i];
|
||||
var row = $("<div/>",{class:"form-row"});
|
||||
$('<label for="node-dialog-login-'+field.id+'">'+field.label+':</label><br/>').appendTo(row);
|
||||
$('<label for="node-dialog-login-'+field.id+'">'+RED._(field.label)+':</label><br/>').appendTo(row);
|
||||
var input = $('<input style="width: 100%" id="node-dialog-login-'+field.id+'" type="'+field.type+'" tabIndex="'+(i+1)+'"/>').appendTo(row);
|
||||
|
||||
if (i<data.prompts.length-1) {
|
||||
@@ -188,6 +188,7 @@ RED.user = (function() {
|
||||
RED.settings.load(function() {
|
||||
RED.notify(RED._("user.loggedInAs",{name:RED.settings.user.username}),"success");
|
||||
updateUserMenu();
|
||||
RED.events.emit("login",RED.settings.user.username);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -230,10 +231,66 @@ RED.user = (function() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var readRE = /^((.+)\.)?read$/
|
||||
var writeRE = /^((.+)\.)?write$/
|
||||
|
||||
function hasPermission(permission) {
|
||||
if (permission === "") {
|
||||
return true;
|
||||
}
|
||||
if (!RED.settings.user) {
|
||||
return true;
|
||||
}
|
||||
return checkPermission(RED.settings.user.permissions||"",permission);
|
||||
}
|
||||
function checkPermission(userScope,permission) {
|
||||
if (permission === "") {
|
||||
return true;
|
||||
}
|
||||
var i;
|
||||
|
||||
if (Array.isArray(permission)) {
|
||||
// Multiple permissions requested - check each one
|
||||
for (i=0;i<permission.length;i++) {
|
||||
if (!checkPermission(userScope,permission[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// All permissions check out
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Array.isArray(userScope)) {
|
||||
if (userScope.length === 0) {
|
||||
return false;
|
||||
}
|
||||
for (i=0;i<userScope.length;i++) {
|
||||
if (checkPermission(userScope[i],permission)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (userScope === "*" || userScope === permission) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (userScope === "read" || userScope === "*.read") {
|
||||
return readRE.test(permission);
|
||||
} else if (userScope === "write" || userScope === "*.write") {
|
||||
return writeRE.test(permission);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
init: init,
|
||||
login: login,
|
||||
logout: logout
|
||||
logout: logout,
|
||||
hasPermission: hasPermission
|
||||
}
|
||||
|
||||
})();
|
||||
|
||||
@@ -66,4 +66,4 @@ $editor-button-background-primary-hover: #6E0A1E;
|
||||
$editor-button-color: #999;
|
||||
$editor-button-background: #fff;
|
||||
|
||||
$shade-color: rgba(200,200,200,0.5);
|
||||
$shade-color: rgba(160,160,160,0.5);
|
||||
|
||||
@@ -113,8 +113,8 @@
|
||||
|
||||
.debug-message-meta {
|
||||
background: #fff;
|
||||
font-size: 10px;
|
||||
color: #777;
|
||||
font-size: 11px;
|
||||
color: #707070;
|
||||
}
|
||||
.debug-message-date {
|
||||
padding: 1px 5px 1px 1px;
|
||||
@@ -125,7 +125,7 @@
|
||||
}
|
||||
.debug-message-name {
|
||||
padding: 1px 5px;
|
||||
color: #777;
|
||||
color: #707070;
|
||||
}
|
||||
.debug-message-tools {
|
||||
position: absolute;
|
||||
@@ -159,7 +159,7 @@
|
||||
.debug-message-element {
|
||||
color: #333;
|
||||
font-family: Menlo, monospace;
|
||||
font-size: 12px !important;
|
||||
font-size: 13px !important;
|
||||
line-height: 1.3em;
|
||||
}
|
||||
.debug-message-object-key {
|
||||
@@ -188,11 +188,9 @@
|
||||
.debug-message-element.collapsed>span>.debug-message-object-handle {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
.debug-message-object-entry.collapsed > .debug-message-object-entry {
|
||||
display:none;
|
||||
}
|
||||
|
||||
.debug-message-element.collapsed .debug-message-object-entry {
|
||||
display:none;
|
||||
}
|
||||
@@ -202,14 +200,13 @@
|
||||
.debug-message-element.collapsed .debug-message-buffer-opts {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.debug-message-element.collapsed .debug-message-object-type-header {
|
||||
display:none;
|
||||
}
|
||||
.debug-message-object-entry pre {
|
||||
font-family: Menlo, monospace;
|
||||
font-size: 12px;
|
||||
line-height: 1.4em;
|
||||
font-size: 13px;
|
||||
line-height: 1.2em;
|
||||
margin: 0 0 0 -1em;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,57 +15,65 @@
|
||||
**/
|
||||
|
||||
|
||||
#node-dialog-view-diff {
|
||||
height: 600px;
|
||||
.node-dialog-view-diff-panel {
|
||||
padding: 5px;
|
||||
padding-top: 30px;
|
||||
position: relative;
|
||||
|
||||
.red-ui-editableList-container {
|
||||
border-radius:1px;
|
||||
padding:0;
|
||||
background: #f9f9f9;
|
||||
}
|
||||
#node-dialog-view-diff-diff {
|
||||
position: absolute;
|
||||
top:80px;
|
||||
bottom:10px;
|
||||
left:10px;
|
||||
right:10px;
|
||||
.node-dialog-view-diff-diff {
|
||||
li {
|
||||
background: #f9f9f9;
|
||||
padding: 0px;
|
||||
border: none;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
}
|
||||
.red-ui-editableList-item-content {
|
||||
padding: 5px;
|
||||
// padding-bottom: 5px;
|
||||
}
|
||||
}
|
||||
#node-dialog-view-diff-headers {
|
||||
.node-diff-container {
|
||||
position: absolute;
|
||||
left:17px;
|
||||
right:32px;
|
||||
top: 55px;
|
||||
top: 40px;
|
||||
right:0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.node-dialog-view-diff-headers {
|
||||
position: absolute;
|
||||
left:232px;
|
||||
right:12px;
|
||||
top: 5px;
|
||||
height: 25px;
|
||||
.node-diff-node-entry-cell:not(:first-child) {
|
||||
div {
|
||||
height: 25px;
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
padding-top: 2px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
width: 50%;
|
||||
background: #f9f9f9;
|
||||
text-align: center;
|
||||
border-top: 1px solid $secondary-border-color;
|
||||
border-color:$secondary-border-color;
|
||||
border-left: 1px solid $secondary-border-color;
|
||||
}
|
||||
.node-diff-node-entry-cell:last-child {
|
||||
div:last-child {
|
||||
border-right: 1px solid $secondary-border-color;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.node-diff-toolbar {
|
||||
position:absolute;
|
||||
top:0;
|
||||
left:0;
|
||||
right:0;
|
||||
height: 43px;
|
||||
box-sizing: border-box;
|
||||
color: #666;
|
||||
text-align: right;
|
||||
@@ -106,10 +114,10 @@
|
||||
font-size: 0.9em;
|
||||
|
||||
&:first-child {
|
||||
border-top: 1px solid #eee;
|
||||
border-top: 1px solid $secondary-border-color;
|
||||
}
|
||||
&:not(:last-child) {
|
||||
border-bottom: 1px solid #eee;
|
||||
border-bottom: 1px solid $secondary-border-color;
|
||||
}
|
||||
|
||||
&.collapsed {
|
||||
@@ -132,14 +140,21 @@
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
table-layout:fixed;
|
||||
|
||||
// Fix for table-layout: fixed on safari:
|
||||
max-width: none;
|
||||
width: auto;
|
||||
min-width: 100%;
|
||||
width: calc(100% - 20px);
|
||||
margin-left: 20px;
|
||||
}
|
||||
col:first-child {
|
||||
width: 180px;
|
||||
}
|
||||
col:not(:first-child) {
|
||||
width: 100%;
|
||||
}
|
||||
td, th {
|
||||
border: 1px solid $secondary-border-color;
|
||||
border-top: 1px solid #f3f3f3;
|
||||
border-left: 1px solid $secondary-border-color;
|
||||
&:first-child {
|
||||
border-left: none;
|
||||
}
|
||||
padding: 0 0 0 3px;
|
||||
text-align: left;
|
||||
overflow-x: auto;
|
||||
@@ -150,13 +165,12 @@
|
||||
white-space:nowrap;
|
||||
overflow:hidden;
|
||||
}
|
||||
&:hover {
|
||||
background: #f9f9f9;
|
||||
}
|
||||
|
||||
}
|
||||
td:first-child {
|
||||
width: 140px;
|
||||
}
|
||||
td:not(:first-child) {
|
||||
width: calc( 100% - 140px);
|
||||
}
|
||||
|
||||
td {
|
||||
.node-diff-status {
|
||||
margin-left: 0;
|
||||
@@ -179,8 +193,8 @@
|
||||
width: 220px;
|
||||
}
|
||||
}
|
||||
td:not(:first-child) {
|
||||
width: calc( (100% - 140px) / 2);
|
||||
col:not(:first-child) {
|
||||
width:50%;
|
||||
}
|
||||
|
||||
.node-diff-node-entry {
|
||||
@@ -210,6 +224,9 @@
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
// background: #f6f6f6;
|
||||
&:hover {
|
||||
background: #f9f9f9;
|
||||
}
|
||||
}
|
||||
.node-diff-tab-title-meta {
|
||||
vertical-align: middle;
|
||||
@@ -218,6 +235,9 @@
|
||||
}
|
||||
.node-diff-node-entry-header {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: #f9f9f9;
|
||||
}
|
||||
}
|
||||
.node-diff-node-entry-node {
|
||||
vertical-align: middle;
|
||||
@@ -247,6 +267,9 @@
|
||||
}
|
||||
.node-diff-tab-title {
|
||||
cursor: default;
|
||||
&:hover {
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.node-diff-node-deleted {
|
||||
@@ -301,7 +324,7 @@
|
||||
}
|
||||
}
|
||||
.node-diff-node-entry-properties {
|
||||
margin: 5px ;
|
||||
margin: 0;
|
||||
color: #666;
|
||||
}
|
||||
.node-diff-status {
|
||||
@@ -313,6 +336,10 @@
|
||||
margin-bottom: 6px;
|
||||
text-align: center;
|
||||
}
|
||||
.node-diff-element {
|
||||
display: inline-block;
|
||||
width: calc(100% - 20px);
|
||||
}
|
||||
|
||||
.node-diff-node-description {
|
||||
color: $form-text-color;
|
||||
@@ -337,6 +364,7 @@
|
||||
.node-diff-added { color: #009900}
|
||||
.node-diff-deleted { color: #f80000}
|
||||
.node-diff-changed { color: #f89406}
|
||||
.node-diff-unchanged { color: #bbb}
|
||||
.node-diff-conflicted { color: purple}
|
||||
|
||||
|
||||
@@ -346,7 +374,7 @@
|
||||
box-sizing: border-box;
|
||||
width: calc( (100% - 20px) / 2);
|
||||
height: 32px;
|
||||
border-left: 1px solid #eee;
|
||||
border-left: 1px solid $secondary-border-color;
|
||||
padding-top: 2px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
@@ -480,37 +508,169 @@
|
||||
}
|
||||
|
||||
|
||||
#node-dialog-confirm-deploy {
|
||||
.node-dialog-confirm-row {
|
||||
text-align: left; padding-top: 10px;
|
||||
ul.node-dialog-configm-deploy-list {
|
||||
font-size: 0.9em;
|
||||
width: 400px;
|
||||
margin: 10px auto;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.node-dialog-confirm-conflict-row {
|
||||
img {
|
||||
vertical-align:middle;
|
||||
height: 30px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
ul {
|
||||
font-size: 0.9em;
|
||||
width: 400px;
|
||||
margin: 10px auto;
|
||||
text-align: left;
|
||||
i {
|
||||
vertical-align:middle;
|
||||
text-align: center;
|
||||
font-size: 30px;
|
||||
width: 30px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.node-dialog-confirm-conflict-row {
|
||||
img {
|
||||
vertical-align:middle;
|
||||
height: 30px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
i {
|
||||
vertical-align:middle;
|
||||
text-align: center;
|
||||
font-size: 30px;
|
||||
width: 30px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
div {
|
||||
vertical-align: middle;
|
||||
width: calc(100% - 60px);
|
||||
display:inline-block;
|
||||
}
|
||||
div {
|
||||
vertical-align: middle;
|
||||
width: calc(100% - 60px);
|
||||
display:inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
#node-diff-toolbar-resolved-conflicts .node-diff-status {
|
||||
margin:0;
|
||||
}
|
||||
.node-diff-text-diff-button {
|
||||
float: right;
|
||||
margin: 2px 3px;
|
||||
line-height: 14px;
|
||||
height: 16px;
|
||||
|
||||
}
|
||||
.node-text-diff {
|
||||
height: 100%;
|
||||
overflow-y:auto;
|
||||
|
||||
table.node-text-diff-content {
|
||||
margin: 10px;
|
||||
border: 1px solid $secondary-border-color;
|
||||
border-radius: 3px;
|
||||
table-layout: fixed;
|
||||
width: calc(100% - 20px);
|
||||
td {
|
||||
vertical-align: top;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
td.lineno {
|
||||
font-family: monospace;
|
||||
text-align: right;
|
||||
color: #aaa;
|
||||
background: #f6f6f6;
|
||||
padding: 1px 5px;
|
||||
}
|
||||
td.lineno:nth-child(3) {
|
||||
border-left: 1px solid $secondary-border-color;
|
||||
}
|
||||
td.linetext {
|
||||
font-family: monospace;
|
||||
white-space: pre-wrap;
|
||||
padding: 1px 5px;
|
||||
span.prefix {
|
||||
width: 30px;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
td.blank {
|
||||
background: #f6f6f6;
|
||||
}
|
||||
td.added {
|
||||
background: #eefaee;
|
||||
}
|
||||
td.removed {
|
||||
background: #fadddd;
|
||||
}
|
||||
tr.mergeHeader td {
|
||||
color: #800080;
|
||||
background: #e5f9ff;
|
||||
height: 26px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
tr.mergeHeader-separator td {
|
||||
color: #800080;
|
||||
background: darken(#e5f9ff, 10%);
|
||||
height: 0px;
|
||||
}
|
||||
tr.mergeHeader-ours td {
|
||||
border-top: 2px solid darken(#e5f9ff, 10%);
|
||||
}
|
||||
tr.mergeHeader-theirs td {
|
||||
border-bottom: 2px solid darken(#e5f9ff, 10%);
|
||||
}
|
||||
td.unchanged {
|
||||
color: #999;
|
||||
}
|
||||
tr.unchanged {
|
||||
background: #fefefe;
|
||||
}
|
||||
tr.start-block {
|
||||
border-top: 1px solid #f0f0f0;
|
||||
}
|
||||
tr.end-block {
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
tr.node-text-diff-file-header td {
|
||||
.filename {
|
||||
font-family: monospace;
|
||||
}
|
||||
background: #f3f3f3;
|
||||
padding: 5px 10px 5px 0;
|
||||
color: #333;
|
||||
cursor: pointer;
|
||||
i.node-diff-chevron {
|
||||
width: 30px;
|
||||
}
|
||||
}
|
||||
tr.node-text-diff-file-header.collapsed {
|
||||
td i.node-diff-chevron {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
}
|
||||
tr.node-text-diff-commit-header td {
|
||||
background: #f3f3f3;
|
||||
padding: 5px 10px;
|
||||
color: #333;
|
||||
h3 {
|
||||
font-size: 1.4em;
|
||||
margin: 0;
|
||||
}
|
||||
.commit-summary {
|
||||
border-top: 1px solid $secondary-border-color;
|
||||
padding-top: 5px;
|
||||
color: #999;
|
||||
}
|
||||
.commit-body {
|
||||
margin-bottom:15px;
|
||||
white-space: pre;
|
||||
line-height: 1.2em;
|
||||
}
|
||||
}
|
||||
|
||||
tr.node-text-diff-header > td:not(.flow-diff) {
|
||||
font-family: monospace;
|
||||
padding: 5px 10px;
|
||||
text-align: left;
|
||||
color: #666;
|
||||
background: #ffd;
|
||||
height: 30px;
|
||||
vertical-align: middle;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
tr.node-text-diff-expand td {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: #ffc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,6 +132,11 @@
|
||||
cursor: col-resize;
|
||||
border-left: 1px solid $primary-border-color;
|
||||
box-shadow: -1px 0 6px rgba(0,0,0,0.1);
|
||||
|
||||
&.editor-tray-resize-maximised {
|
||||
background: $background-color;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
.editor-tray-resize-button {
|
||||
@include workspace-button;
|
||||
@@ -153,7 +158,10 @@
|
||||
top: -1px;
|
||||
bottom: -1px;
|
||||
}
|
||||
|
||||
#full-shade {
|
||||
@include shade;
|
||||
z-index: 15;
|
||||
}
|
||||
|
||||
.dialog-form,#dialog-form, #node-config-dialog-edit-form {
|
||||
height: 100%;
|
||||
@@ -191,12 +199,16 @@
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.form-warning {
|
||||
border-color: #d6615f;
|
||||
}
|
||||
|
||||
.node-text-editor {
|
||||
border:1px solid #ccc;
|
||||
border-radius:5px;
|
||||
overflow: hidden;
|
||||
font-size: 14px !important;
|
||||
font-family: monospace !important;
|
||||
font-family: Menlo, Consolas, 'DejaVu Sans Mono', Courier, monospace !important;
|
||||
}
|
||||
|
||||
.editor-button {
|
||||
@@ -204,8 +216,10 @@
|
||||
height: 34px;
|
||||
line-height: 32px;
|
||||
font-size: 13px;
|
||||
border-radius: 4px;
|
||||
border-radius: 2px;
|
||||
padding: 0 10px;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
&.toggle {
|
||||
@include workspace-button-toggle;
|
||||
}
|
||||
@@ -214,6 +228,7 @@
|
||||
|
||||
.editor-button-small {
|
||||
height: 20px;
|
||||
min-width: 20px;
|
||||
line-height: 18px;
|
||||
font-size: 10px;
|
||||
border-radius: 2px;
|
||||
@@ -315,6 +330,13 @@
|
||||
input {
|
||||
width: calc(100% - 100px);
|
||||
}
|
||||
#node-settings-icon-module {
|
||||
width: calc(55% - 50px);
|
||||
}
|
||||
#node-settings-icon-file {
|
||||
width: calc(45% - 55px);
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
.node-label-form-none {
|
||||
span {
|
||||
|
||||
@@ -501,6 +501,11 @@ textarea.span1,
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
label.disabled {
|
||||
color: #bbb !important;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
input[disabled],
|
||||
select[disabled],
|
||||
textarea[disabled],
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
font-size: 14px;
|
||||
padding: 6px 14px;
|
||||
margin-right: 8px;
|
||||
border-radius: 2px;
|
||||
color: $editor-button-color;
|
||||
background: $editor-button-background;
|
||||
|
||||
@@ -142,3 +143,10 @@
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.ui-widget-overlay {
|
||||
@include shade;
|
||||
z-index: 100;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@@ -48,29 +48,30 @@
|
||||
text-decoration: none;
|
||||
cursor:pointer;
|
||||
|
||||
&.disabled {
|
||||
&.disabled, &:disabled {
|
||||
cursor: default;
|
||||
color: $workspace-button-color-disabled !important;
|
||||
}
|
||||
&:hover, &:focus {
|
||||
text-decoration: none;
|
||||
}
|
||||
&:not(.disabled):hover {
|
||||
&:not(.disabled):not(:disabled):hover, {
|
||||
color: $workspace-button-color-hover !important;
|
||||
background: $workspace-button-background-hover;
|
||||
}
|
||||
&:not(.disabled):focus {
|
||||
&:not(.disabled):not(:disabled):focus {
|
||||
color: $workspace-button-color-focus !important;
|
||||
}
|
||||
&:not(.disabled):active {
|
||||
&:not(.disabled):not(:disabled):active {
|
||||
color: $workspace-button-color-active !important;
|
||||
background: $workspace-button-background-active;
|
||||
text-decoration: none;
|
||||
}
|
||||
&.selected:not(.disabled) {
|
||||
color: $workspace-button-color-selected !important;
|
||||
background: $workspace-button-background-active;
|
||||
}
|
||||
// &.selected:not(.disabled):not(:disabled) {
|
||||
// color: $workspace-button-color-selected !important;
|
||||
// background: $workspace-button-background-active;
|
||||
// background: #9f9;
|
||||
// }
|
||||
.button-group &:not(:first-child) {
|
||||
border-left: none;
|
||||
border-top-left-radius: 0;
|
||||
@@ -94,9 +95,30 @@
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
.button-row &:not(:first-child) {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: 1px solid $workspace-button-color-focus-outline;
|
||||
}
|
||||
|
||||
&.primary {
|
||||
border-color: $editor-button-background-primary;
|
||||
color: $editor-button-color-primary !important;
|
||||
background: $editor-button-background-primary;
|
||||
&.disabled, &.ui-state-disabled {
|
||||
background: none;
|
||||
color: $editor-button-color !important;
|
||||
border-color: $form-input-border-color;
|
||||
}
|
||||
&:not(.disabled):not(.ui-button-disabled):hover {
|
||||
border-color: $editor-button-background-primary-hover;
|
||||
background: $editor-button-background-primary-hover;
|
||||
color: $editor-button-color-primary !important;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.button-group-vertical {
|
||||
display: inline-block;
|
||||
@@ -132,21 +154,21 @@
|
||||
color: $editor-button-color !important;
|
||||
background: $editor-button-background;
|
||||
|
||||
&.primary {
|
||||
border-color: $editor-button-background-primary;
|
||||
color: $editor-button-color-primary !important;
|
||||
background: $editor-button-background-primary;
|
||||
&.disabled, &.ui-state-disabled {
|
||||
background: none;
|
||||
color: $editor-button-color !important;
|
||||
border-color: $form-input-border-color;
|
||||
}
|
||||
&:not(.disabled):not(.ui-button-disabled):hover {
|
||||
border-color: $editor-button-background-primary-hover;
|
||||
background: $editor-button-background-primary-hover;
|
||||
color: $editor-button-color-primary !important;
|
||||
}
|
||||
}
|
||||
// &.primary {
|
||||
// border-color: $editor-button-background-primary;
|
||||
// color: $editor-button-color-primary !important;
|
||||
// background: $editor-button-background-primary;
|
||||
// &.disabled, &.ui-state-disabled {
|
||||
// background: none;
|
||||
// color: $editor-button-color !important;
|
||||
// border-color: $form-input-border-color;
|
||||
// }
|
||||
// &:not(.disabled):not(.ui-button-disabled):hover {
|
||||
// border-color: $editor-button-background-primary-hover;
|
||||
// background: $editor-button-background-primary-hover;
|
||||
// color: $editor-button-color-primary !important;
|
||||
// }
|
||||
// }
|
||||
&:not(.disabled):hover {
|
||||
//color: $editor-button-color;
|
||||
}
|
||||
@@ -224,4 +246,8 @@
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background: $shade-color;
|
||||
z-index: 5;
|
||||
}
|
||||
.component-shade {
|
||||
@include shade
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
**/
|
||||
|
||||
#notifications {
|
||||
z-index: 10000;
|
||||
z-index: 100;
|
||||
width: 500px;
|
||||
margin-left: -250px;
|
||||
left: 50%;
|
||||
@@ -34,6 +34,10 @@
|
||||
border-left-width: 16px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.notification p:first-child {
|
||||
font-size: 1.1em;
|
||||
font-weight: 400;
|
||||
}
|
||||
.notification a {
|
||||
text-decoration: none;
|
||||
&:hover {
|
||||
|
||||
@@ -49,7 +49,12 @@
|
||||
.palette-module-version {
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.palette-module-errors .fa-warning {
|
||||
opacity: 0.5;
|
||||
}
|
||||
ul.palette-module-error-list li {
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -76,48 +81,9 @@
|
||||
border-bottom: 1px solid $primary-border-color;
|
||||
text-align: right;
|
||||
}
|
||||
.palette-module-button-group {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
a {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
.palette-module-shade {
|
||||
@include shade;
|
||||
text-align: center;
|
||||
padding-top: 20px;
|
||||
}
|
||||
#palette-module-install-shade {
|
||||
padding-top: 80px;
|
||||
}
|
||||
.palette-module-shade-status {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.palette-module-meta {
|
||||
color: #666;
|
||||
position: relative;
|
||||
&.disabled {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.fa {
|
||||
width: 15px;
|
||||
text-align: center;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
.palette-module-name {
|
||||
white-space: nowrap;
|
||||
@include enable-selection;
|
||||
}
|
||||
.palette-module-version, .palette-module-updated, .palette-module-link {
|
||||
font-style:italic;
|
||||
font-size: 0.8em;
|
||||
@include enable-selection;
|
||||
}
|
||||
.palette-module-updated {
|
||||
margin-left: 10px;
|
||||
}
|
||||
@@ -224,3 +190,62 @@
|
||||
}
|
||||
|
||||
}
|
||||
.palette-module-meta {
|
||||
color: #666;
|
||||
position: relative;
|
||||
&.disabled {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.fa {
|
||||
width: 15px;
|
||||
text-align: center;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
.palette-module-name {
|
||||
white-space: nowrap;
|
||||
@include enable-selection;
|
||||
}
|
||||
.palette-module-version, .palette-module-updated, .palette-module-link {
|
||||
font-style:italic;
|
||||
font-size: 0.8em;
|
||||
@include enable-selection;
|
||||
}
|
||||
.palette-module-section {
|
||||
padding:0 !important;
|
||||
background: #f9f9f9 !important;
|
||||
font-size: 0.9em;
|
||||
color: #666;
|
||||
|
||||
}
|
||||
.palette-module-button-group {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
a {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
.palette-module-meta .fa-warning {
|
||||
color: #AD1625;
|
||||
}
|
||||
ul.palette-module-error-list {
|
||||
display: inline-block;
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
font-size: 0.9em;
|
||||
li {
|
||||
border: none;
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
|
||||
.palette-module-shade {
|
||||
@include shade;
|
||||
text-align: center;
|
||||
padding-top: 20px;
|
||||
}
|
||||
#palette-module-install-shade {
|
||||
padding-top: 80px;
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
text-overflow: ellipsis;
|
||||
|
||||
}
|
||||
.palette-header i {
|
||||
.palette-header > i {
|
||||
margin: 3px 10px 3px 3px;
|
||||
-webkit-transition: all 0.2s ease-in-out;
|
||||
-moz-transition: all 0.2s ease-in-out;
|
||||
|
||||
875
editor/sass/projects.scss
Normal file
875
editor/sass/projects.scss
Normal file
@@ -0,0 +1,875 @@
|
||||
/**
|
||||
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
#projects-dialog {
|
||||
.red-ui-editableList-container {
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
}
|
||||
#project-settings-tab-settings {
|
||||
overflow-y: scroll;
|
||||
}
|
||||
.sidebar-version-control-shade {
|
||||
background: #f3f3f3;
|
||||
}
|
||||
|
||||
.projects-edit-form form {
|
||||
margin: 0;
|
||||
.form-row {
|
||||
margin-bottom: 15px;
|
||||
label {
|
||||
color: #555;
|
||||
width: 100%;
|
||||
display: block;
|
||||
&.projects-edit-form-inline-label {
|
||||
font-weight: normal;
|
||||
color: inherit;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
input[type=text], input[type=password],textarea {
|
||||
width: 100%;
|
||||
}
|
||||
input[type=checkbox], input[type=radio] {
|
||||
width: auto;
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.projects-edit-form-sublabel {
|
||||
color: #999;
|
||||
text-align: right;
|
||||
margin-bottom: -15px;
|
||||
font-weight: normal;
|
||||
}
|
||||
.project-settings-tab-pane {
|
||||
& * .projects-edit-form-sublabel {
|
||||
margin-right: 50px;
|
||||
margin-top: -10px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
.projects-dialog-spinner {
|
||||
position: absolute;
|
||||
top: 1px;
|
||||
bottom: 1px;
|
||||
left: 1px;
|
||||
right: 1px;
|
||||
text-align: center;
|
||||
padding: 40px;
|
||||
background: white;
|
||||
&:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
vertical-align: middle;
|
||||
margin-right: -0.25em;
|
||||
}
|
||||
img {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
width: 80px;
|
||||
}
|
||||
&.projects-dialog-spinner-sidebar {
|
||||
background: white;
|
||||
padding:0;
|
||||
img {
|
||||
width: 40px;
|
||||
}
|
||||
}
|
||||
&.projects-version-control-spinner-sidebar {
|
||||
background: white;
|
||||
padding:0;
|
||||
img {
|
||||
width: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
&.projects-dialog-spinner-contain {
|
||||
padding: 0;
|
||||
img {
|
||||
width: auto;
|
||||
height: 100%;
|
||||
max-height: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.projects-dialog-screen-start {
|
||||
.projects-dialog-screen-start-hero {
|
||||
// background: url(https://nodered.org/images/title-wave.png) no-repeat 0% 100% #8f0000;
|
||||
// background-size: contain;
|
||||
text-align: center;
|
||||
font-size: 2em;
|
||||
padding: 10px;
|
||||
min-height: 60px;
|
||||
color: #555;
|
||||
h1 {
|
||||
text-align: center;
|
||||
color: #f0f0f0;
|
||||
font-size: 2em;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
.projects-dialog-screen-start-body {
|
||||
min-height: 400px;
|
||||
line-height: 1.6em;
|
||||
p {
|
||||
font-size: 1.1em;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
p:first-child {
|
||||
font-weight: 500;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
}
|
||||
button.editor-button {
|
||||
width: calc(50% - 80px);
|
||||
margin: 20px;
|
||||
height: auto;
|
||||
line-height: 2em;
|
||||
padding: 10px;
|
||||
border-color: #aaa;
|
||||
i {
|
||||
color: #aaa;
|
||||
}
|
||||
&:hover i {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
.button-group {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
.projects-dialog-screen-create {
|
||||
min-height: 500px;
|
||||
button.projects-dialog-screen-create-type {
|
||||
height: auto;
|
||||
padding: 10px;
|
||||
}
|
||||
.button-group {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.projects-dialog-screen-secret {
|
||||
min-height: auto;
|
||||
}
|
||||
.projects-dialog-project-list-container {
|
||||
border: 1px solid $secondary-border-color;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.projects-dialog-project-list-inner-container {
|
||||
height: 300px;
|
||||
overflow-y: scroll;
|
||||
position:relative;
|
||||
.red-ui-editableList-border {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
.projects-dialog-project-list {
|
||||
li {
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
.projects-dialog-project-list-entry {
|
||||
padding: 12px 0;
|
||||
border-left: 3px solid #fff;
|
||||
border-right: 3px solid #fff;
|
||||
&.projects-list-entry-current {
|
||||
&:not(.selectable) {
|
||||
background: #f9f9f9;
|
||||
}
|
||||
i {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
&.selectable {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: #f3f3f3;
|
||||
// border-left-color: #aaa;
|
||||
// border-right-color: #aaa;
|
||||
}
|
||||
}
|
||||
.projects-dialog-project-list-entry-icon {
|
||||
i {
|
||||
color: #ccc;
|
||||
font-size: 2em;
|
||||
|
||||
}
|
||||
}
|
||||
&.selected {
|
||||
background: #efefef;
|
||||
border-left-color:#999;
|
||||
border-right-color:#999;
|
||||
}
|
||||
span {
|
||||
display: inline-block;
|
||||
vertical-align:middle;
|
||||
}
|
||||
.projects-dialog-project-list-entry-icon {
|
||||
margin: 0 10px 0 5px;
|
||||
}
|
||||
.projects-dialog-project-list-entry-name {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
.projects-dialog-project-list-entry-current {
|
||||
float: right;
|
||||
margin-right: 20px;
|
||||
font-size: 0.9em;
|
||||
color: #999;
|
||||
padding-top: 4px;
|
||||
}
|
||||
.projects-dialog-project-list-entry-tools {
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
right: 30px;
|
||||
display: none;
|
||||
color: #999;
|
||||
}
|
||||
&:hover {
|
||||
.projects-dialog-project-list-entry-tools {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
.projects-dialog-screen-create-type.editor-button.toggle.selected:not(.disabled):not(:disabled) {
|
||||
background: #fff !important;
|
||||
color: #666 !important;
|
||||
}
|
||||
.projects-dialog-screen-input-status {
|
||||
text-align: right;
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 8px;
|
||||
width: 70px;
|
||||
height: 30px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.sidebar-version-control {
|
||||
height: 100%;
|
||||
}
|
||||
.sidebar-version-control-stack-info {
|
||||
height: 100px;
|
||||
box-sizing: border-box;
|
||||
border-bottom: 1px solid $secondary-border-color;
|
||||
color: #333;
|
||||
i {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
.sidebar-version-control-stack {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
overflow: hidden;
|
||||
|
||||
.palette-category {
|
||||
&:not(.palette-category-expanded) button {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#project-settings-tab-deps {
|
||||
.red-ui-editableList-container {
|
||||
padding: 0;
|
||||
}
|
||||
.red-ui-editableList-border {
|
||||
border-radius: 0;
|
||||
}
|
||||
.red-ui-editableList-item-content {
|
||||
padding: 0px 6px;
|
||||
}
|
||||
.palette-module-header {
|
||||
padding: 6px 4px;
|
||||
}
|
||||
.palette-module-button {
|
||||
float: right;
|
||||
}
|
||||
.palette-module-unused {
|
||||
& > * {
|
||||
color: #bbb;
|
||||
}
|
||||
// border: 1px dashed #bbb;
|
||||
}
|
||||
.palette-module-unknown {
|
||||
border: 1px dashed #aaa;
|
||||
background: #fafafa;
|
||||
}
|
||||
.palette-module-not-installed {
|
||||
border: 1px dashed #b07575;
|
||||
background: #fee;
|
||||
i.fa-warning {
|
||||
color: #b07575; //#b72828;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.project-settings-tab-pane {
|
||||
position: absolute;
|
||||
top:0;
|
||||
left:0;
|
||||
right:0;
|
||||
bottom:0;
|
||||
overflow-y: auto;
|
||||
padding: 8px 20px 20px;
|
||||
}
|
||||
.sidebar-version-control {
|
||||
.red-ui-editableList-container {
|
||||
background: #f9f9f9;
|
||||
padding: 0;
|
||||
li {
|
||||
padding:0;
|
||||
background: #fff;
|
||||
}
|
||||
}
|
||||
.red-ui-editableList-border {
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-version-control-change-container {
|
||||
position: relative;
|
||||
height: 50%;
|
||||
box-sizing: border-box;
|
||||
transition: height 0.2s ease-in-out;
|
||||
&:first-child {
|
||||
// border-bottom: 1px solid $primary-border-color;
|
||||
}
|
||||
}
|
||||
.sidebar-version-control-merging {
|
||||
.sidebar-version-control-change-container {
|
||||
height: 33%;
|
||||
}
|
||||
}
|
||||
.sidebar-version-control-slide-box {
|
||||
position:absolute;
|
||||
bottom: 0;
|
||||
left:0;
|
||||
right:0;
|
||||
height:0;
|
||||
transition: height 0.2s ease-in-out;
|
||||
background: #f6f6f6;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
&.sidebar-version-control-slide-box-top {
|
||||
z-index: 4;
|
||||
top: 0px;
|
||||
left: auto;
|
||||
width: 100%;
|
||||
max-width: 280px;
|
||||
border-left: 1px solid $primary-border-color;
|
||||
border-right: 1px solid $primary-border-color;
|
||||
border-bottom: 1px solid $primary-border-color;
|
||||
box-shadow: 1px 1px 4px rgba(0,0,0,0.2);
|
||||
|
||||
color: #666;
|
||||
background: #f6f6f6;
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
|
||||
}
|
||||
&.sidebar-version-control-slide-box-bottom {
|
||||
bottom: 0px;
|
||||
border-top: 1px solid $secondary-border-color;
|
||||
}
|
||||
|
||||
textarea {
|
||||
height: 110px;
|
||||
margin: 10px;
|
||||
width: calc(100% - 20px);
|
||||
box-sizing: border-box;
|
||||
border-radius: 1px;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
}
|
||||
.projects-branch-list {
|
||||
position: relative;
|
||||
.red-ui-searchBox-container {
|
||||
border-top: 1px solid $secondary-border-color;
|
||||
border-left: 1px solid $secondary-border-color;
|
||||
border-right: 1px solid $secondary-border-color;
|
||||
border-top-left-radius: 2px;
|
||||
border-top-right-radius: 2px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.red-ui-editableList {
|
||||
border: 1px solid $secondary-border-color;
|
||||
border-bottom-left-radius: 2px;
|
||||
border-bottom-right-radius: 2px;
|
||||
& > .red-ui-editableList-border {
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
}
|
||||
.red-ui-editableList-container {
|
||||
padding: 0;
|
||||
li {
|
||||
padding: 0;
|
||||
background: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.uneditable-input .projects-branch-list {
|
||||
.red-ui-editableList {
|
||||
border-left: none;
|
||||
border-bottom: none;
|
||||
border-right: none;
|
||||
}
|
||||
.red-ui-searchBox-container {
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
}
|
||||
}
|
||||
.sidebar-version-control-slide-box-header {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.sidebar-version-control-slide-box-toolbar {
|
||||
padding: 0 20px;
|
||||
text-align: right;
|
||||
}
|
||||
.sidebar-version-control-branch-list-entry {
|
||||
padding: 5px 8px;
|
||||
color: #666;
|
||||
cursor: pointer;
|
||||
&.selected {
|
||||
border-left-color:#999;
|
||||
border-right-color:#999;
|
||||
}
|
||||
border-left: 2px solid #fff;
|
||||
border-right: 2px solid #fff;
|
||||
margin: 0 1px;
|
||||
i { width: 16px; text-align: center}
|
||||
&.input-error {
|
||||
cursor: default;
|
||||
}
|
||||
&:not(.input-error):hover {
|
||||
background: #f3f3f3;
|
||||
border-left-color:#999;
|
||||
border-right-color:#999;
|
||||
}
|
||||
span {
|
||||
margin-left: 5px;
|
||||
}
|
||||
span.current {
|
||||
float: right;
|
||||
font-size: 0.8em;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-version-control-change-entry {
|
||||
height: 20px;
|
||||
padding: 5px 10px;
|
||||
position: relative;
|
||||
white-space: nowrap;
|
||||
span {
|
||||
margin: 0 6px;
|
||||
}
|
||||
a {
|
||||
color: currentColor;
|
||||
&.disabled {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
.sidebar-version-control-change-entry-tools {
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
right: 4px;
|
||||
display: none;
|
||||
button {
|
||||
width: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.sidebar-version-control-change-entry-tools {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
&.node-info-none {
|
||||
text-align: center;
|
||||
background: #fefefe;
|
||||
white-space: normal;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-version-control-commit-entry {
|
||||
min-height: 20px;
|
||||
padding: 5px 10px;
|
||||
position: relative;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: #eee;
|
||||
}
|
||||
}
|
||||
.sidebar-version-control-commit-more {
|
||||
color: #999;
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
font-style: italic;
|
||||
}
|
||||
.sidebar-version-control-commit-sha {
|
||||
float: right;
|
||||
font-family: monospace;
|
||||
color: #c38888;
|
||||
display: inline-block;
|
||||
font-size: 0.85em;
|
||||
margin-left: 5px;
|
||||
}
|
||||
.sidebar-version-control-commit-subject {
|
||||
color: #666;
|
||||
}
|
||||
.sidebar-version-control-commit-refs {
|
||||
min-height: 22px;
|
||||
}
|
||||
.sidebar-version-control-commit-ref {
|
||||
color: #aaa;
|
||||
font-size: 0.7em;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 10px;
|
||||
padding: 2px 5px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.sidebar-version-control-commit-date {
|
||||
color: #999;
|
||||
font-size: 0.85em;
|
||||
}
|
||||
.sidebar-version-control-commit-user {
|
||||
float: right;
|
||||
color: #999;
|
||||
font-size: 0.85em;
|
||||
}
|
||||
.sidebar-version-control-commit-head {
|
||||
}
|
||||
.sidebar-version-control-change-header {
|
||||
color: #666;
|
||||
background: #f6f6f6;
|
||||
padding: 4px 10px;
|
||||
height: 30px;
|
||||
box-sizing: border-box;
|
||||
border-top: 1px solid $secondary-border-color;
|
||||
border-bottom: 1px solid $secondary-border-color;
|
||||
i {
|
||||
transition: all 0.2s ease-in-out;
|
||||
}
|
||||
}
|
||||
.sidebar-version-control-repo-toolbar {
|
||||
color: #666;
|
||||
background: #f6f6f6;
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.sidebar-version-control-repo-count {
|
||||
margin-right: 8px;
|
||||
display: none;
|
||||
}
|
||||
.sidebar-version-control-repo-action {
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
}
|
||||
.sidebar-version-control-repo-sub-action {
|
||||
width: calc(50% - 5px);
|
||||
margin-right: 5px;
|
||||
&:not(:first-child) {
|
||||
margin-right: 0;
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.project-file-listing-container > .red-ui-editableList > .red-ui-editableList-border {
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
border-top: 1px solid $secondary-border-color;
|
||||
|
||||
}
|
||||
.red-ui-editableList-container .projects-dialog-file-list {
|
||||
.red-ui-editableList-border {
|
||||
border: none;
|
||||
}
|
||||
li {
|
||||
padding: 0 !important;
|
||||
border: none;
|
||||
}
|
||||
.red-ui-editableList-container {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
.projects-dialog-file-list-entry {
|
||||
padding: 3px 0;
|
||||
border-left: 2px solid #fff;
|
||||
border-right: 2px solid #fff;
|
||||
&.projects-list-entry-current {
|
||||
&:not(.selectable) {
|
||||
background: #f9f9f9;
|
||||
}
|
||||
i {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
&.selectable {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: #f3f3f3;
|
||||
border-left-color:#999;
|
||||
border-right-color:#999;
|
||||
}
|
||||
}
|
||||
&.unselectable {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
i {
|
||||
color: #999;
|
||||
width: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
&.selected {
|
||||
background: #efefef;
|
||||
border-left-color:#999;
|
||||
border-right-color:#999;
|
||||
}
|
||||
span {
|
||||
display: inline-block;
|
||||
vertical-align:middle;
|
||||
}
|
||||
.projects-dialog-file-list-entry-folder {
|
||||
margin: 0 10px 0 0px;
|
||||
|
||||
.fa-angle-right {
|
||||
color: #333;
|
||||
transition: all 0.2s ease-in-out;
|
||||
|
||||
}
|
||||
}
|
||||
.projects-dialog-file-list-entry-file {
|
||||
margin: 0 10px 0 20px;
|
||||
}
|
||||
.projects-dialog-file-list-entry-name {
|
||||
font-size: 1em;
|
||||
}
|
||||
&.expanded .fa-angle-right {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
.projects-dialog-file-list-entry-file-type-git { color: #999 }
|
||||
|
||||
.projects-dialog-remote-list {
|
||||
.red-ui-editableList-container {
|
||||
padding: 0;
|
||||
li {
|
||||
padding: 0;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.projects-dialog-sshkey-list {
|
||||
li {
|
||||
padding: 0 !important;
|
||||
}
|
||||
&.projects-dialog-sshkey-list-small {
|
||||
.projects-dialog-sshkey-list-entry {
|
||||
padding: 6px 0;
|
||||
i {
|
||||
font-size: 1em;
|
||||
}
|
||||
}
|
||||
.projects-dialog-sshkey-list-entry-name {
|
||||
font-size: 1em;
|
||||
}
|
||||
.projects-dialog-sshkey-list-entry-current {
|
||||
margin-right: 10px;
|
||||
padding-top: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.red-ui-editableList-container {
|
||||
.projects-dialog-sshkey-list {
|
||||
li:last-child {
|
||||
border-bottom: 0px none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.projects-dialog-sshkey-list-entry {
|
||||
padding: 12px 0;
|
||||
border-left: 3px solid #fff;
|
||||
border-right: 3px solid #fff;
|
||||
&.sshkey-list-entry-current {
|
||||
&:not(.selectable) {
|
||||
background: #f9f9f9;
|
||||
}
|
||||
i {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
&.selectable {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: #f3f3f3;
|
||||
border-left-color: #aaa;
|
||||
border-right-color: #aaa;
|
||||
}
|
||||
}
|
||||
i {
|
||||
color: #ccc;
|
||||
font-size: 2em;
|
||||
|
||||
}
|
||||
&.selected {
|
||||
background: #efefef;
|
||||
border-left-color:#999;
|
||||
border-right-color:#999;
|
||||
}
|
||||
span {
|
||||
display: inline-block;
|
||||
vertical-align:middle;
|
||||
}
|
||||
.projects-dialog-sshkey-list-entry-icon {
|
||||
margin: 0 10px 0 5px;
|
||||
}
|
||||
.projects-dialog-sshkey-list-entry-name {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
.projects-dialog-sshkey-list-entry-current {
|
||||
float: right;
|
||||
margin-right: 20px;
|
||||
font-size: 0.9em;
|
||||
color: #999;
|
||||
padding-top: 4px;
|
||||
}
|
||||
.projects-dialog-sshkey-list-button-remove {
|
||||
position: absolute;
|
||||
right: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
div.projects-dialog-ssh-public-key {
|
||||
position: relative;
|
||||
padding: 15px 20px 0;
|
||||
pre {
|
||||
position: relative;
|
||||
word-break: break-all;
|
||||
}
|
||||
&:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
}
|
||||
|
||||
.projects-dialog-ssh-key-list {
|
||||
li {
|
||||
padding: 0 !important;
|
||||
}
|
||||
.projects-dialog-ssh-key-header {
|
||||
padding: 10px 5px;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: #f3f3f3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.projects-dialog-list {
|
||||
position: relative;
|
||||
.red-ui-editableList-container {
|
||||
padding: 1px;
|
||||
background: #f6f6f6;
|
||||
li:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.projects-dialog-list-entry {
|
||||
&.red-ui-search-empty {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
}
|
||||
.entry-icon {
|
||||
text-align: center;
|
||||
min-width: 30px;
|
||||
vertical-align: top;
|
||||
color: #999;
|
||||
}
|
||||
.entry-name {
|
||||
min-width: 250px;
|
||||
}
|
||||
&.current .entry-name {
|
||||
font-weight: bold;
|
||||
}
|
||||
.entry-detail {
|
||||
color: #aaa;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.entry-remote-name {
|
||||
min-width: 250px;
|
||||
}
|
||||
|
||||
|
||||
.entry-tools {
|
||||
float: right;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
.projects-dialog-list-dialog {
|
||||
position: relative;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 20px;
|
||||
background: white;
|
||||
border-radius: 4px;
|
||||
border: 1px solid $secondary-border-color;
|
||||
.projects-edit-form-sublabel {
|
||||
margin-top: -8px !important;
|
||||
display: block !important;
|
||||
width: auto !important;
|
||||
}
|
||||
&:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.projects-dialog-list-dialog-header {
|
||||
font-weight: bold;
|
||||
background: #f3f3f3;
|
||||
margin-top: 0 !important;
|
||||
padding: 5px 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
@@ -48,12 +48,15 @@
|
||||
|
||||
@import "userSettings";
|
||||
|
||||
@import "projects";
|
||||
|
||||
|
||||
@import "ui/common/editableList";
|
||||
@import "ui/common/searchBox";
|
||||
@import "ui/common/typedInput";
|
||||
@import "ui/common/nodeList";
|
||||
@import "ui/common/checkboxSet";
|
||||
@import "ui/common/stack";
|
||||
|
||||
@import "dragdrop";
|
||||
|
||||
|
||||
@@ -87,17 +87,22 @@ table.node-info tr.blank {
|
||||
padding-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.node-info-none {
|
||||
font-style: italic;
|
||||
color: #aaa;
|
||||
}
|
||||
table.node-info tr:not(.blank) td:first-child{
|
||||
color: #666;
|
||||
color: #444;
|
||||
vertical-align: top;
|
||||
width: 90px;
|
||||
padding: 3px 3px 3px 6px;
|
||||
background:#f9f9f9;
|
||||
border-right: 1px solid #ddd;
|
||||
}
|
||||
table.node-info tr:not(.blank) td:last-child{
|
||||
padding: 3px 3px 3px 6px;
|
||||
color: #666;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
div.node-info {
|
||||
margin: 5px;
|
||||
|
||||
26
editor/sass/ui/common/stack.scss
Normal file
26
editor/sass/ui/common/stack.scss
Normal file
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
.red-ui-stack {
|
||||
background: white;
|
||||
.palette-category {
|
||||
background: white;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -64,9 +64,10 @@
|
||||
vertical-align: middle;
|
||||
color: #555;
|
||||
i {
|
||||
position:relative;
|
||||
top:-3px;
|
||||
margin-right:4px;
|
||||
position: relative;
|
||||
top: -3px;
|
||||
margin-left: 1px;
|
||||
margin-right: 2px;
|
||||
margin-top: 1px;
|
||||
vertical-align: middle;
|
||||
&.fa-ellipsis-h {
|
||||
|
||||
@@ -38,17 +38,26 @@
|
||||
label {
|
||||
display: inline-block;
|
||||
min-width: 100px;
|
||||
vertical-align: top;
|
||||
margin-top: 5px;
|
||||
input {
|
||||
vertical-align: top;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
}
|
||||
input {
|
||||
margin-bottom: 0;
|
||||
input, div.uneditable-input {
|
||||
//margin-bottom: 0;
|
||||
}
|
||||
div.uneditable-input {
|
||||
position: relative;
|
||||
}
|
||||
input[type='number'] {
|
||||
width: 60px;
|
||||
}
|
||||
h4 {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
#user-settings-tab-view {
|
||||
@@ -57,3 +66,18 @@
|
||||
.user-settings-row {
|
||||
padding: 5px 10px 2px;
|
||||
}
|
||||
.user-settings-section {
|
||||
position: relative;
|
||||
&:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
.uneditable-input, input, textarea {
|
||||
width: calc(100% - 150px);
|
||||
}
|
||||
textarea {
|
||||
resize: none;
|
||||
height: 10em;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,35 +77,11 @@
|
||||
<div id="sidebar-separator"></div>
|
||||
|
||||
</div>
|
||||
<div id="full-shade" class="hide"></div>
|
||||
|
||||
<div id="notifications"></div>
|
||||
<div id="dropTarget"><div data-i18n="[append]workspace.dropFlowHere"><br/><i class="fa fa-download"></i></div></div>
|
||||
|
||||
<div id="node-dialog-confirm-deploy" class="hide">
|
||||
<form class="form-horizontal">
|
||||
<div id="node-dialog-confirm-deploy-config" class="node-dialog-confirm-row" data-i18n="[prepend]deploy.confirm.improperlyConfigured;[append]deploy.confirm.confirm">
|
||||
<ul id="node-dialog-confirm-deploy-invalid-list"></ul>
|
||||
</div>
|
||||
<div id="node-dialog-confirm-deploy-unknown" class="node-dialog-confirm-row" data-i18n="[prepend]deploy.confirm.unknown;[append]deploy.confirm.confirm">
|
||||
<ul id="node-dialog-confirm-deploy-unknown-list"></ul>
|
||||
</div>
|
||||
<div id="node-dialog-confirm-deploy-conflict" class="node-dialog-confirm-row">
|
||||
<div style="margin-left: 40px; margin-bottom: 10px;">
|
||||
<span data-i18n="deploy.confirm.conflict"></span>
|
||||
</div>
|
||||
<div id="node-dialog-confirm-deploy-conflict-checking" class="node-dialog-confirm-conflict-row">
|
||||
<img src="red/images/spin.svg"/><div data-i18n="deploy.confirm.conflictChecking"></div>
|
||||
</div>
|
||||
<div id="node-dialog-confirm-deploy-conflict-auto-merge" class="node-dialog-confirm-conflict-row">
|
||||
<i style="color: #3a3;" class="fa fa-check"></i><div data-i18n="deploy.confirm.conflictAutoMerge"></div>
|
||||
</div>
|
||||
<div id="node-dialog-confirm-deploy-conflict-manual-merge" class="node-dialog-confirm-conflict-row">
|
||||
<i style="color: #999;" class="fa fa-exclamation"></i><div data-i18n="deploy.confirm.conflictManualMerge"></div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="node-dialog-library-save-confirm" class="hide">
|
||||
<form class="form-horizontal">
|
||||
<div style="text-align: center; padding-top: 30px;" id="node-dialog-library-save-content">
|
||||
@@ -209,6 +185,14 @@
|
||||
<div style="height: 200px;min-height: 150px;" class="node-text-editor" id="node-input-json"></div>
|
||||
</div>
|
||||
</script>
|
||||
<script type="text/x-red" data-template-name="_markdown">
|
||||
<div class="form-row" id="node-input-markdown-title" style="margin-bottom: 3px; text-align: right;">
|
||||
|
||||
</div>
|
||||
<div class="form-row node-text-editor-row">
|
||||
<div style="height: 200px;min-height: 150px;" class="node-text-editor" id="node-input-markdown"></div>
|
||||
</div>
|
||||
</script>
|
||||
<script type="text/x-red" data-template-name="_buffer">
|
||||
<div id="node-input-buffer-panels">
|
||||
<div id="node-input-buffer-panel-str" class="red-ui-panel">
|
||||
@@ -226,7 +210,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script src="vendor/vendor.js"></script>
|
||||
<script src="vendor/jsonata/jsonata.min.js"></script>
|
||||
<script src="vendor/ace/ace.js"></script>
|
||||
|
||||
2
editor/vendor/ace/ace.js
vendored
Executable file → Normal file
2
editor/vendor/ace/ace.js
vendored
Executable file → Normal file
File diff suppressed because one or more lines are too long
2
editor/vendor/ace/ext-language_tools.js
vendored
Executable file → Normal file
2
editor/vendor/ace/ext-language_tools.js
vendored
Executable file → Normal file
File diff suppressed because one or more lines are too long
2
editor/vendor/ace/ext-searchbox.js
vendored
Executable file → Normal file
2
editor/vendor/ace/ext-searchbox.js
vendored
Executable file → Normal file
File diff suppressed because one or more lines are too long
2
editor/vendor/ace/mode-css.js
vendored
Executable file → Normal file
2
editor/vendor/ace/mode-css.js
vendored
Executable file → Normal file
File diff suppressed because one or more lines are too long
2
editor/vendor/ace/mode-handlebars.js
vendored
Executable file → Normal file
2
editor/vendor/ace/mode-handlebars.js
vendored
Executable file → Normal file
File diff suppressed because one or more lines are too long
2
editor/vendor/ace/mode-html.js
vendored
Executable file → Normal file
2
editor/vendor/ace/mode-html.js
vendored
Executable file → Normal file
File diff suppressed because one or more lines are too long
2
editor/vendor/ace/mode-javascript.js
vendored
Executable file → Normal file
2
editor/vendor/ace/mode-javascript.js
vendored
Executable file → Normal file
File diff suppressed because one or more lines are too long
2
editor/vendor/ace/mode-json.js
vendored
Executable file → Normal file
2
editor/vendor/ace/mode-json.js
vendored
Executable file → Normal file
File diff suppressed because one or more lines are too long
2
editor/vendor/ace/mode-markdown.js
vendored
Executable file → Normal file
2
editor/vendor/ace/mode-markdown.js
vendored
Executable file → Normal file
File diff suppressed because one or more lines are too long
0
editor/vendor/ace/mode-properties.js
vendored
Executable file → Normal file
0
editor/vendor/ace/mode-properties.js
vendored
Executable file → Normal file
1
editor/vendor/ace/mode-python.js
vendored
Normal file
1
editor/vendor/ace/mode-python.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
ace.define("ace/mode/python_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="and|as|assert|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|not|or|pass|print|raise|return|try|while|with|yield|async|await",t="True|False|None|NotImplemented|Ellipsis|__debug__",n="abs|divmod|input|open|staticmethod|all|enumerate|int|ord|str|any|eval|isinstance|pow|sum|basestring|execfile|issubclass|print|super|binfile|iter|property|tuple|bool|filter|len|range|type|bytearray|float|list|raw_input|unichr|callable|format|locals|reduce|unicode|chr|frozenset|long|reload|vars|classmethod|getattr|map|repr|xrange|cmp|globals|max|reversed|zip|compile|hasattr|memoryview|round|__import__|complex|hash|min|set|apply|delattr|help|next|setattr|buffer|dict|hex|object|slice|coerce|dir|id|oct|sorted|intern",r=this.createKeywordMapper({"invalid.deprecated":"debugger","support.function":n,"constant.language":t,keyword:e},"identifier"),i="(?:r|u|ur|R|U|UR|Ur|uR)?",s="(?:(?:[1-9]\\d*)|(?:0))",o="(?:0[oO]?[0-7]+)",u="(?:0[xX][\\dA-Fa-f]+)",a="(?:0[bB][01]+)",f="(?:"+s+"|"+o+"|"+u+"|"+a+")",l="(?:[eE][+-]?\\d+)",c="(?:\\.\\d+)",h="(?:\\d+)",p="(?:(?:"+h+"?"+c+")|(?:"+h+"\\.))",d="(?:(?:"+p+"|"+h+")"+l+")",v="(?:"+d+"|"+p+")",m="\\\\(x[0-9A-Fa-f]{2}|[0-7]{3}|[\\\\abfnrtv'\"]|U[0-9A-Fa-f]{8}|u[0-9A-Fa-f]{4})";this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"string",regex:i+'"{3}',next:"qqstring3"},{token:"string",regex:i+'"(?=.)',next:"qqstring"},{token:"string",regex:i+"'{3}",next:"qstring3"},{token:"string",regex:i+"'(?=.)",next:"qstring"},{token:"constant.numeric",regex:"(?:"+v+"|\\d+)[jJ]\\b"},{token:"constant.numeric",regex:v},{token:"constant.numeric",regex:f+"[lL]\\b"},{token:"constant.numeric",regex:f+"\\b"},{token:r,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\+|\\-|\\*|\\*\\*|\\/|\\/\\/|%|<<|>>|&|\\||\\^|~|<|>|<=|=>|==|!=|<>|="},{token:"paren.lparen",regex:"[\\[\\(\\{]"},{token:"paren.rparen",regex:"[\\]\\)\\}]"},{token:"text",regex:"\\s+"}],qqstring3:[{token:"constant.language.escape",regex:m},{token:"string",regex:'"{3}',next:"start"},{defaultToken:"string"}],qstring3:[{token:"constant.language.escape",regex:m},{token:"string",regex:"'{3}",next:"start"},{defaultToken:"string"}],qqstring:[{token:"constant.language.escape",regex:m},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"start"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:m},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"start"},{defaultToken:"string"}]}};r.inherits(s,i),t.PythonHighlightRules=s}),ace.define("ace/mode/folding/pythonic",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=t.FoldMode=function(e){this.foldingStartMarker=new RegExp("([\\[{])(?:\\s*)$|("+e+")(?:\\s*)(?:#.*)?$")};r.inherits(s,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=e.getLine(n),i=r.match(this.foldingStartMarker);if(i)return i[1]?this.openingBracketBlock(e,i[1],n,i.index):i[2]?this.indentationBlock(e,n,i.index+i[2].length):this.indentationBlock(e,n)}}.call(s.prototype)}),ace.define("ace/mode/python",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/python_highlight_rules","ace/mode/folding/pythonic","ace/range"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./python_highlight_rules").PythonHighlightRules,o=e("./folding/pythonic").FoldMode,u=e("../range").Range,a=function(){this.HighlightRules=s,this.foldingRules=new o("\\:"),this.$behaviour=this.$defaultBehaviour};r.inherits(a,i),function(){this.lineCommentStart="#",this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"){var o=t.match(/^.*[\{\(\[:]\s*$/);o&&(r+=n)}return r};var e={pass:1,"return":1,raise:1,"break":1,"continue":1};this.checkOutdent=function(t,n,r){if(r!=="\r\n"&&r!=="\r"&&r!=="\n")return!1;var i=this.getTokenizer().getLineTokens(n.trim(),t).tokens;if(!i)return!1;do var s=i.pop();while(s&&(s.type=="comment"||s.type=="text"&&s.value.match(/^\s+$/)));return s?s.type=="keyword"&&e[s.value]:!1},this.autoOutdent=function(e,t,n){n+=1;var r=this.$getIndent(t.getLine(n)),i=t.getTabString();r.slice(-i.length)==i&&t.remove(new u(n,r.length-i.length,n,r.length))},this.$id="ace/mode/python"}.call(a.prototype),t.Mode=a})
|
||||
0
editor/vendor/ace/mode-sql.js
vendored
Executable file → Normal file
0
editor/vendor/ace/mode-sql.js
vendored
Executable file → Normal file
2
editor/vendor/ace/mode-swift.js
vendored
Executable file → Normal file
2
editor/vendor/ace/mode-swift.js
vendored
Executable file → Normal file
File diff suppressed because one or more lines are too long
2
editor/vendor/ace/mode-yaml.js
vendored
Executable file → Normal file
2
editor/vendor/ace/mode-yaml.js
vendored
Executable file → Normal file
@@ -1 +1 @@
|
||||
ace.define("ace/mode/yaml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"list.markup",regex:/^(?:-{3}|\.{3})\s*(?=#|$)/},{token:"list.markup",regex:/^\s*[\-?](?:$|\s)/},{token:"constant",regex:"!![\\w//]+"},{token:"constant.language",regex:"[&\\*][a-zA-Z0-9-_]+"},{token:["meta.tag","keyword"],regex:/^(\s*\w.*?)(:(?:\s+|$))/},{token:["meta.tag","keyword"],regex:/(\w+?)(\s*:(?:\s+|$))/},{token:"keyword.operator",regex:"<<\\w*:\\w*"},{token:"keyword.operator",regex:"-\\s*(?=[{])"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:/[|>][-+\d\s]*$/,onMatch:function(e,t,n,r){var i=/^\s*/.exec(r)[0];return n.length<1?n.push(this.next):n[0]="mlString",n.length<2?n.push(i.length):n[1]=i.length,this.token},next:"mlString"},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"constant.numeric",regex:/(\b|[+\-\.])[\d_]+(?:(?:\.[\d_]*)?(?:[eE][+\-]?[\d_]+)?)/},{token:"constant.numeric",regex:/[+\-]?\.inf\b|NaN\b|0x[\dA-Fa-f_]+|0b[10_]+/},{token:"constant.language.boolean",regex:"\\b(?:true|false|TRUE|FALSE|True|False|yes|no)\\b"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"}],mlString:[{token:"indent",regex:/^\s*$/},{token:"indent",regex:/^\s*/,onMatch:function(e,t,n){var r=n[1];return r>=e.length?(this.next="start",n.splice(0)):this.next="mlString",this.token},next:"mlString"},{token:"string",regex:".+"}]},this.normalizeRules()};r.inherits(s,i),t.YamlHighlightRules=s}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!="#")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++n<f){o=e.getLine(n);var h=o.search(i);if(h==-1)continue;if(o[h]!="#")break;c=n}if(c>l){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\S/),a=s.search(/\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u<a?"start":"","";if(u==-1){if(i==a&&r[i]=="#"&&s[i]=="#")return e.foldWidgets[n-1]="",e.foldWidgets[n+1]="","start"}else if(u==i&&r[i]=="#"&&o[i]=="#"&&e.getLine(n-2).search(/\S/)==-1)return e.foldWidgets[n-1]="start",e.foldWidgets[n+1]="","";return u!=-1&&u<i?e.foldWidgets[n-1]="start":e.foldWidgets[n-1]="",i<a?"start":""}}.call(o.prototype)}),ace.define("ace/mode/yaml",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/yaml_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/folding/coffee"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./yaml_highlight_rules").YamlHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("./folding/coffee").FoldMode,a=function(){this.HighlightRules=s,this.$outdent=new o,this.foldingRules=new u,this.$behaviour=this.$defaultBehaviour};r.inherits(a,i),function(){this.lineCommentStart="#",this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t);if(e=="start"){var i=t.match(/^.*[\{\(\[]\s*$/);i&&(r+=n)}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/yaml"}.call(a.prototype),t.Mode=a})
|
||||
ace.define("ace/mode/yaml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"list.markup",regex:/^(?:-{3}|\.{3})\s*(?=#|$)/},{token:"list.markup",regex:/^\s*[\-?](?:$|\s)/},{token:"constant",regex:"!![\\w//]+"},{token:"constant.language",regex:"[&\\*][a-zA-Z0-9-_]+"},{token:["meta.tag","keyword"],regex:/^(\s*\w.*?)(:(?=\s|$))/},{token:["meta.tag","keyword"],regex:/(\w+?)(\s*:(?=\s|$))/},{token:"keyword.operator",regex:"<<\\w*:\\w*"},{token:"keyword.operator",regex:"-\\s*(?=[{])"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:/[|>][-+\d\s]*$/,onMatch:function(e,t,n,r){var i=/^\s*/.exec(r)[0];return n.length<1?n.push(this.next):n[0]="mlString",n.length<2?n.push(i.length):n[1]=i.length,this.token},next:"mlString"},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"constant.numeric",regex:/(\b|[+\-\.])[\d_]+(?:(?:\.[\d_]*)?(?:[eE][+\-]?[\d_]+)?)(?=[^\d-\w]|$)/},{token:"constant.numeric",regex:/[+\-]?\.inf\b|NaN\b|0x[\dA-Fa-f_]+|0b[10_]+/},{token:"constant.language.boolean",regex:"\\b(?:true|false|TRUE|FALSE|True|False|yes|no)\\b"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:/[^\s,:\[\]\{\}]+/}],mlString:[{token:"indent",regex:/^\s*$/},{token:"indent",regex:/^\s*/,onMatch:function(e,t,n){var r=n[1];return r>=e.length?(this.next="start",n.splice(0)):this.next="mlString",this.token},next:"mlString"},{token:"string",regex:".+"}]},this.normalizeRules()};r.inherits(s,i),t.YamlHighlightRules=s}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!="#")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++n<f){o=e.getLine(n);var h=o.search(i);if(h==-1)continue;if(o[h]!="#")break;c=n}if(c>l){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\S/),a=s.search(/\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u<a?"start":"","";if(u==-1){if(i==a&&r[i]=="#"&&s[i]=="#")return e.foldWidgets[n-1]="",e.foldWidgets[n+1]="","start"}else if(u==i&&r[i]=="#"&&o[i]=="#"&&e.getLine(n-2).search(/\S/)==-1)return e.foldWidgets[n-1]="start",e.foldWidgets[n+1]="","";return u!=-1&&u<i?e.foldWidgets[n-1]="start":e.foldWidgets[n-1]="",i<a?"start":""}}.call(o.prototype)}),ace.define("ace/mode/yaml",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/yaml_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/folding/coffee"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./yaml_highlight_rules").YamlHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("./folding/coffee").FoldMode,a=function(){this.HighlightRules=s,this.$outdent=new o,this.foldingRules=new u,this.$behaviour=this.$defaultBehaviour};r.inherits(a,i),function(){this.lineCommentStart=["#","//"],this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t);if(e=="start"){var i=t.match(/^.*[\{\(\[]\s*$/);i&&(r+=n)}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/yaml"}.call(a.prototype),t.Mode=a})
|
||||
0
editor/vendor/ace/snippets/css.js
vendored
Executable file → Normal file
0
editor/vendor/ace/snippets/css.js
vendored
Executable file → Normal file
0
editor/vendor/ace/snippets/handlebars.js
vendored
Executable file → Normal file
0
editor/vendor/ace/snippets/handlebars.js
vendored
Executable file → Normal file
836
editor/vendor/ace/snippets/html.js
vendored
Executable file → Normal file
836
editor/vendor/ace/snippets/html.js
vendored
Executable file → Normal file
File diff suppressed because one or more lines are too long
0
editor/vendor/ace/snippets/javascript.js
vendored
Executable file → Normal file
0
editor/vendor/ace/snippets/javascript.js
vendored
Executable file → Normal file
1
editor/vendor/ace/snippets/json.js
vendored
Normal file
1
editor/vendor/ace/snippets/json.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
ace.define("ace/snippets/json",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="json"})
|
||||
0
editor/vendor/ace/snippets/markdown.js
vendored
Executable file → Normal file
0
editor/vendor/ace/snippets/markdown.js
vendored
Executable file → Normal file
0
editor/vendor/ace/snippets/properties.js
vendored
Executable file → Normal file
0
editor/vendor/ace/snippets/properties.js
vendored
Executable file → Normal file
1
editor/vendor/ace/snippets/python.js
vendored
Normal file
1
editor/vendor/ace/snippets/python.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
ace.define("ace/snippets/python",["require","exports","module"],function(e,t,n){"use strict";t.snippetText='snippet #!\n #!/usr/bin/env python\nsnippet imp\n import ${1:module}\nsnippet from\n from ${1:package} import ${2:module}\n# Module Docstring\nsnippet docs\n \'\'\'\n File: ${1:FILENAME:file_name}\n Author: ${2:author}\n Description: ${3}\n \'\'\'\nsnippet wh\n while ${1:condition}:\n ${2:# TODO: write code...}\n# dowh - does the same as do...while in other languages\nsnippet dowh\n while True:\n ${1:# TODO: write code...}\n if ${2:condition}:\n break\nsnippet with\n with ${1:expr} as ${2:var}:\n ${3:# TODO: write code...}\n# New Class\nsnippet cl\n class ${1:ClassName}(${2:object}):\n """${3:docstring for $1}"""\n def __init__(self, ${4:arg}):\n ${5:super($1, self).__init__()}\n self.$4 = $4\n ${6}\n# New Function\nsnippet def\n def ${1:fname}(${2:`indent(\'.\') ? \'self\' : \'\'`}):\n """${3:docstring for $1}"""\n ${4:# TODO: write code...}\nsnippet deff\n def ${1:fname}(${2:`indent(\'.\') ? \'self\' : \'\'`}):\n ${3:# TODO: write code...}\n# New Method\nsnippet defs\n def ${1:mname}(self, ${2:arg}):\n ${3:# TODO: write code...}\n# New Property\nsnippet property\n def ${1:foo}():\n doc = "${2:The $1 property.}"\n def fget(self):\n ${3:return self._$1}\n def fset(self, value):\n ${4:self._$1 = value}\n# Ifs\nsnippet if\n if ${1:condition}:\n ${2:# TODO: write code...}\nsnippet el\n else:\n ${1:# TODO: write code...}\nsnippet ei\n elif ${1:condition}:\n ${2:# TODO: write code...}\n# For\nsnippet for\n for ${1:item} in ${2:items}:\n ${3:# TODO: write code...}\n# Encodes\nsnippet cutf8\n # -*- coding: utf-8 -*-\nsnippet clatin1\n # -*- coding: latin-1 -*-\nsnippet cascii\n # -*- coding: ascii -*-\n# Lambda\nsnippet ld\n ${1:var} = lambda ${2:vars} : ${3:action}\nsnippet .\n self.\nsnippet try Try/Except\n try:\n ${1:# TODO: write code...}\n except ${2:Exception}, ${3:e}:\n ${4:raise $3}\nsnippet try Try/Except/Else\n try:\n ${1:# TODO: write code...}\n except ${2:Exception}, ${3:e}:\n ${4:raise $3}\n else:\n ${5:# TODO: write code...}\nsnippet try Try/Except/Finally\n try:\n ${1:# TODO: write code...}\n except ${2:Exception}, ${3:e}:\n ${4:raise $3}\n finally:\n ${5:# TODO: write code...}\nsnippet try Try/Except/Else/Finally\n try:\n ${1:# TODO: write code...}\n except ${2:Exception}, ${3:e}:\n ${4:raise $3}\n else:\n ${5:# TODO: write code...}\n finally:\n ${6:# TODO: write code...}\n# if __name__ == \'__main__\':\nsnippet ifmain\n if __name__ == \'__main__\':\n ${1:main()}\n# __magic__\nsnippet _\n __${1:init}__${2}\n# python debugger (pdb)\nsnippet pdb\n import pdb; pdb.set_trace()\n# ipython debugger (ipdb)\nsnippet ipdb\n import ipdb; ipdb.set_trace()\n# ipython debugger (pdbbb)\nsnippet pdbbb\n import pdbpp; pdbpp.set_trace()\nsnippet pprint\n import pprint; pprint.pprint(${1})${2}\nsnippet "\n """\n ${1:doc}\n """\n# test function/method\nsnippet test\n def test_${1:description}(${2:self}):\n ${3:# TODO: write code...}\n# test case\nsnippet testcase\n class ${1:ExampleCase}(unittest.TestCase):\n \n def test_${2:description}(self):\n ${3:# TODO: write code...}\nsnippet fut\n from __future__ import ${1}\n#getopt\nsnippet getopt\n try:\n # Short option syntax: "hv:"\n # Long option syntax: "help" or "verbose="\n opts, args = getopt.getopt(sys.argv[1:], "${1:short_options}", [${2:long_options}])\n \n except getopt.GetoptError, err:\n # Print debug info\n print str(err)\n ${3:error_action}\n\n for option, argument in opts:\n if option in ("-h", "--help"):\n ${4}\n elif option in ("-v", "--verbose"):\n verbose = argument\n',t.scope="python"})
|
||||
1
editor/vendor/ace/snippets/sql.js
vendored
Normal file
1
editor/vendor/ace/snippets/sql.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
ace.define("ace/snippets/sql",["require","exports","module"],function(e,t,n){"use strict";t.snippetText="snippet tbl\n create table ${1:table} (\n ${2:columns}\n );\nsnippet col\n ${1:name} ${2:type} ${3:default ''} ${4:not null}\nsnippet ccol\n ${1:name} varchar2(${2:size}) ${3:default ''} ${4:not null}\nsnippet ncol\n ${1:name} number ${3:default 0} ${4:not null}\nsnippet dcol\n ${1:name} date ${3:default sysdate} ${4:not null}\nsnippet ind\n create index ${3:$1_$2} on ${1:table}(${2:column});\nsnippet uind\n create unique index ${1:name} on ${2:table}(${3:column});\nsnippet tblcom\n comment on table ${1:table} is '${2:comment}';\nsnippet colcom\n comment on column ${1:table}.${2:column} is '${3:comment}';\nsnippet addcol\n alter table ${1:table} add (${2:column} ${3:type});\nsnippet seq\n create sequence ${1:name} start with ${2:1} increment by ${3:1} minvalue ${4:1};\nsnippet s*\n select * from ${1:table}\n",t.scope="sql"})
|
||||
1
editor/vendor/ace/snippets/swift.js
vendored
Normal file
1
editor/vendor/ace/snippets/swift.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
ace.define("ace/snippets/swift",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="swift"})
|
||||
0
editor/vendor/ace/snippets/text.js
vendored
Executable file → Normal file
0
editor/vendor/ace/snippets/text.js
vendored
Executable file → Normal file
0
editor/vendor/ace/snippets/yaml.js
vendored
Executable file → Normal file
0
editor/vendor/ace/snippets/yaml.js
vendored
Executable file → Normal file
0
editor/vendor/ace/theme-chrome.js
vendored
Executable file → Normal file
0
editor/vendor/ace/theme-chrome.js
vendored
Executable file → Normal file
0
editor/vendor/ace/theme-tomorrow.js
vendored
Executable file → Normal file
0
editor/vendor/ace/theme-tomorrow.js
vendored
Executable file → Normal file
2
editor/vendor/ace/worker-html.js
vendored
Executable file → Normal file
2
editor/vendor/ace/worker-html.js
vendored
Executable file → Normal file
File diff suppressed because one or more lines are too long
2
editor/vendor/ace/worker-javascript.js
vendored
Executable file → Normal file
2
editor/vendor/ace/worker-javascript.js
vendored
Executable file → Normal file
File diff suppressed because one or more lines are too long
2
editor/vendor/ace/worker-json.js
vendored
Executable file → Normal file
2
editor/vendor/ace/worker-json.js
vendored
Executable file → Normal file
File diff suppressed because one or more lines are too long
9
editor/vendor/jsonata/formatter.js
vendored
9
editor/vendor/jsonata/formatter.js
vendored
@@ -120,6 +120,11 @@
|
||||
'$exists':{ args:[ 'arg' ]},
|
||||
'$filter':{ args:[ 'array', 'function' ]},
|
||||
'$floor':{ args:[ 'number' ]},
|
||||
'$flowContext': {args:['string']},
|
||||
'$formatBase': {args:['number','radix']},
|
||||
'$formatNumber': {args:['number', 'picture', 'options']},
|
||||
'$fromMillis': {args:['number']},
|
||||
'$globalContext': {args:['string']},
|
||||
'$join':{ args:[ 'array', 'separator' ]},
|
||||
'$keys':{ args:[ 'object' ]},
|
||||
'$length':{ args:[ 'str' ]},
|
||||
@@ -128,10 +133,13 @@
|
||||
'$map':{ args:[ 'array', 'function' ]},
|
||||
'$match':{ args:[ 'str', 'pattern', 'limit' ]},
|
||||
'$max':{ args:[ 'array' ]},
|
||||
'$merge':{ args:[ 'array' ]},
|
||||
'$millis':{ args:[ ]},
|
||||
'$min':{ args:[ 'array' ]},
|
||||
'$not':{ args:[ 'arg' ]},
|
||||
'$now':{ args:[ ]},
|
||||
'$number':{ args:[ 'arg' ]},
|
||||
'$pad': {args:['str', 'width','char']},
|
||||
'$power':{ args:[ 'base', 'exponent' ]},
|
||||
'$random':{ args:[ ]},
|
||||
'$reduce':{ args:[ 'array', 'function' , 'init' ]},
|
||||
@@ -149,6 +157,7 @@
|
||||
'$substringAfter':{ args:[ 'str', 'chars' ]},
|
||||
'$substringBefore':{ args:[ 'str', 'chars' ]},
|
||||
'$sum':{ args:[ 'array' ]},
|
||||
'$toMillis':{args:['timestamp']}, // <-------------
|
||||
'$trim':{ args:[ 'str' ]},
|
||||
'$uppercase':{ args:[ 'str' ]},
|
||||
'$zip':{ args:[ 'array1' ]}
|
||||
|
||||
@@ -1,20 +1,9 @@
|
||||
<!--
|
||||
Copyright JS Foundation and other contributors, http://js.foundation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<script type="text/x-red" data-template-name="sentiment">
|
||||
<div class="form-row">
|
||||
<label for="node-input-property"><i class="fa fa-ellipsis-h"></i> <span data-i18n="node-red:common.label.property"></span></label>
|
||||
<input type="text" id="node-input-property" style="width:70%;"/>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
||||
@@ -22,7 +11,7 @@
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="sentiment">
|
||||
<p>Analyses the <code>payload</code> and adds a <code>sentiment</code> object.</p>
|
||||
<p>Analyses the chosen property, default <code>payload</code>, and adds a <code>sentiment</code> object.</p>
|
||||
<h3>Outputs</h3>
|
||||
<dl class="message-properties">
|
||||
<dt>sentiment <span class="property-type">object</span></dt>
|
||||
@@ -47,6 +36,7 @@
|
||||
color:"#E6E0F8",
|
||||
defaults: {
|
||||
name: {value:""},
|
||||
property: {value:"payload",required:true}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:1,
|
||||
@@ -56,6 +46,12 @@
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
},
|
||||
oneditprepare: function() {
|
||||
if (this.property === undefined) {
|
||||
$("#node-input-property").val("payload");
|
||||
}
|
||||
$("#node-input-property").typedInput({default:'msg',types:['msg']});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -1,18 +1,3 @@
|
||||
/**
|
||||
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
module.exports = function(RED) {
|
||||
"use strict";
|
||||
@@ -20,16 +5,18 @@ module.exports = function(RED) {
|
||||
|
||||
function SentimentNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.property = n.property||"payload";
|
||||
var node = this;
|
||||
|
||||
this.on("input", function(msg) {
|
||||
if (msg.hasOwnProperty("payload")) {
|
||||
sentiment(msg.payload, msg.overrides || null, function (err, result) {
|
||||
var value = RED.util.getMessageProperty(msg,node.property);
|
||||
if (value !== undefined) {
|
||||
sentiment(value, msg.overrides || null, function (err, result) {
|
||||
msg.sentiment = result;
|
||||
node.send(msg);
|
||||
});
|
||||
}
|
||||
else { node.send(msg); } // If no payload - just pass it on.
|
||||
else { node.send(msg); } // If no matching property - just pass it on.
|
||||
});
|
||||
}
|
||||
RED.nodes.registerType("sentiment",SentimentNode);
|
||||
|
||||
@@ -26,6 +26,14 @@
|
||||
<input type="text" id="node-input-topic">
|
||||
</div>
|
||||
|
||||
<div class="form-row" id="node-once">
|
||||
<label for="node-input-once"> </label>
|
||||
<input type="checkbox" id="node-input-once" style="display:inline-block; width:15px; vertical-align:baseline;">
|
||||
<span data-i18n="inject.onstart"></span>
|
||||
<input type="text" id="node-input-onceDelay" placeholder="0.1" style="width:45px; height:28px;">
|
||||
<span data-i18n="inject.onceDelay"></span>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<label for=""><i class="fa fa-repeat"></i> <span data-i18n="inject.label.repeat"></span></label>
|
||||
<select id="inject-time-type-select">
|
||||
@@ -41,7 +49,7 @@
|
||||
<div class="form-row inject-time-row hidden" id="inject-time-row-interval">
|
||||
<span data-i18n="inject.every"></span>
|
||||
<input id="inject-time-interval-count" class="inject-time-count" value="1"></input>
|
||||
<select style="width: 100px" id="inject-time-interval-units">
|
||||
<select style="width:100px" id="inject-time-interval-units">
|
||||
<option value="s" data-i18n="inject.seconds"></option>
|
||||
<option value="m" data-i18n="inject.minutes"></option>
|
||||
<option value="h" data-i18n="inject.hours"></option>
|
||||
@@ -49,7 +57,7 @@
|
||||
</div>
|
||||
|
||||
<div class="form-row inject-time-row hidden" id="inject-time-row-interval-time">
|
||||
<span data-i18n="inject.every"></span> <select style="width:90px" id="inject-time-interval-time-units" class="inject-time-int-count" value="1">
|
||||
<span data-i18n="inject.every"></span> <select style="width:90px; margin-left:20px;" id="inject-time-interval-time-units" class="inject-time-int-count" value="1">
|
||||
<option value="1">1</option>
|
||||
<option value="2">2</option>
|
||||
<option value="3">3</option>
|
||||
@@ -65,8 +73,8 @@
|
||||
</select> <span data-i18n="inject.minutes"></span><br/>
|
||||
<span data-i18n="inject.between"></span> <select id="inject-time-interval-time-start" class="inject-time-times"></select>
|
||||
<span data-i18n="inject.and"></span> <select id="inject-time-interval-time-end" class="inject-time-times"></select><br/>
|
||||
<div id="inject-time-interval-time-days" class="inject-time-days">
|
||||
<div style="display: inline-block; vertical-align: top;margin-right:5px;" data-i18n="inject.on">on</div>
|
||||
<div id="inject-time-interval-time-days" class="inject-time-days" style="margin-top:5px">
|
||||
<div style="display:inline-block; vertical-align:top; margin-right:5px;" data-i18n="inject.on">on</div>
|
||||
<div style="display:inline-block;">
|
||||
<div>
|
||||
<label><input type='checkbox' checked value='1'/> <span data-i18n="inject.days.0"></span></label>
|
||||
@@ -86,9 +94,9 @@
|
||||
</div>
|
||||
|
||||
<div class="form-row inject-time-row hidden" id="inject-time-row-time">
|
||||
<span data-i18n="inject.at"></span> <input id="inject-time-time" value="12:00"></input><br/>
|
||||
<span data-i18n="inject.at"></span> <input type="text" id="inject-time-time" value="12:00"></input><br/>
|
||||
<div id="inject-time-time-days" class="inject-time-days">
|
||||
<div style="display: inline-block; vertical-align: top;margin-right: 5px;">on </div>
|
||||
<div style="display:inline-block; vertical-align:top; margin-right:5px;" data-i18n="inject.on"></div>
|
||||
<div style="display:inline-block;">
|
||||
<div>
|
||||
<label><input type='checkbox' checked value='1'/> <span data-i18n="inject.days.0"></span></label>
|
||||
@@ -106,13 +114,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row" id="node-once">
|
||||
<label> </label>
|
||||
<input type="checkbox" id="node-input-once" style="display: inline-block; width: auto; vertical-align: top;">
|
||||
<label for="node-input-once" style="width: 70%;" data-i18n="inject.onstart"></label>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
||||
@@ -133,17 +134,20 @@
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
vertical-align: top;
|
||||
vertical-align: baseline;
|
||||
width: 100px;
|
||||
}
|
||||
.inject-time-days input {
|
||||
width: auto;
|
||||
}
|
||||
.inject-time-days input {
|
||||
width: auto;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
.inject-time-times {
|
||||
width: 90px;
|
||||
}
|
||||
#inject-time-time {
|
||||
width: 75px;
|
||||
margin-left: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.inject-time-count {
|
||||
width: 40px !important;
|
||||
@@ -166,6 +170,8 @@ The default payload is a timestamp of the current time in millisecs since Januar
|
||||
<p>By default, the node is triggered manually by clicking on its button within the editor. It can also be set to
|
||||
inject at regular intervals or according to a schedule.</p>
|
||||
<p>It can also be configured to inject once each time the flows are started.</p>
|
||||
<p>The maximum <i>Interval</i> that can be specified is about 596 hours / 24 days. However if you are looking at intervals
|
||||
greater than one day you should consider using a scheduler node that can cope with power outages and restarts.</p>
|
||||
<p><b>Note</b>: The <i>"Interval between times"</i> and <i>"at a specific time"</i> options use the standard cron system.
|
||||
This means that 20 minutes will be at the next hour, 20 minutes past and 40 minutes past - not in 20 minutes time.
|
||||
If you want every 20 minutes from now - use the <i>"interval"</i> option.</p>
|
||||
@@ -181,9 +187,10 @@ If you want every 20 minutes from now - use the <i>"interval"</i> option.</p>
|
||||
topic: {value:""},
|
||||
payload: {value:"", validate: RED.validators.typedInput("payloadType")},
|
||||
payloadType: {value:"date"},
|
||||
repeat: {value:""},
|
||||
repeat: {value:"", validate:function(v) { return ((v === "") || (RED.validators.number(v) && (v >= 0) && (v <= 2147483))) }},
|
||||
crontab: {value:""},
|
||||
once: {value:false}
|
||||
once: {value:false},
|
||||
onceDelay: {value:0.1}
|
||||
},
|
||||
icon: "inject.png",
|
||||
inputs:0,
|
||||
@@ -273,6 +280,10 @@ If you want every 20 minutes from now - use the <i>"interval"</i> option.</p>
|
||||
}
|
||||
});
|
||||
|
||||
$("#node-input-once").change(function() {
|
||||
$("#node-input-onceDelay").attr('disabled', !$("#node-input-once").prop('checked'));
|
||||
})
|
||||
|
||||
$(".inject-time-times").each(function() {
|
||||
for (var i=0; i<24; i++) {
|
||||
var l = (i<10?"0":"")+i+":00";
|
||||
@@ -301,35 +312,6 @@ If you want every 20 minutes from now - use the <i>"interval"</i> option.</p>
|
||||
min:1
|
||||
});
|
||||
|
||||
$.widget( "ui.injecttimespinner", $.ui.spinner, {
|
||||
options: {
|
||||
// seconds
|
||||
step: 60 * 1000,
|
||||
// hours
|
||||
page: 60
|
||||
},
|
||||
_parse: function( value ) {
|
||||
if ( typeof value === "string" ) {
|
||||
// already a timestamp
|
||||
if ( Number( value ) == value ) {
|
||||
return Number( value );
|
||||
}
|
||||
var p = value.split(":");
|
||||
var offset = new Date().getTimezoneOffset();
|
||||
return ((Number(p[0])*60)+Number(p[1])+offset)*60*1000;
|
||||
}
|
||||
return value;
|
||||
},
|
||||
_format: function( value ) {
|
||||
var d = new Date(value);
|
||||
var h = d.getHours();
|
||||
var m = d.getMinutes();
|
||||
return ((h < 10)?"0":"")+h+":"+((m < 10)?"0":"")+m;
|
||||
}
|
||||
});
|
||||
|
||||
$("#inject-time-time").injecttimespinner();
|
||||
|
||||
var repeattype = "none";
|
||||
if (this.repeat != "" && this.repeat != 0) {
|
||||
repeattype = "interval";
|
||||
@@ -446,7 +428,7 @@ If you want every 20 minutes from now - use the <i>"interval"</i> option.</p>
|
||||
var count = $("#inject-time-interval-time-units").val();
|
||||
var startTime = Number($("#inject-time-interval-time-start").val());
|
||||
var endTime = Number($("#inject-time-interval-time-end").val());
|
||||
var days = $('#inject-time-interval-time-days input[type=checkbox]:checked').map(function(_, el) {
|
||||
var days = $('#inject-time-interval-time-days input[type=checkbox]:checked').map(function(_, el) {
|
||||
return $(el).val()
|
||||
}).get();
|
||||
if (days.length == 0) {
|
||||
@@ -499,8 +481,13 @@ If you want every 20 minutes from now - use the <i>"interval"</i> option.</p>
|
||||
days = days.join(",");
|
||||
}
|
||||
var parts = time.split(":");
|
||||
repeat = "";
|
||||
crontab = parts[1]+" "+parts[0]+" * * "+days;
|
||||
if (parts.length === 2) {
|
||||
repeat = "";
|
||||
parts[1] = ("00" + (parseInt(parts[1]) % 60)).substr(-2);
|
||||
parts[0] = ("00" + (parseInt(parts[0]) % 24)).substr(-2);
|
||||
crontab = parts[1]+" "+parts[0]+" * * "+days;
|
||||
}
|
||||
else { crontab = ""; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,27 +26,40 @@ module.exports = function(RED) {
|
||||
this.repeat = n.repeat;
|
||||
this.crontab = n.crontab;
|
||||
this.once = n.once;
|
||||
var node = this;
|
||||
this.onceDelay = (n.onceDelay || 0.1) * 1000;
|
||||
this.interval_id = null;
|
||||
this.cronjob = null;
|
||||
var node = this;
|
||||
|
||||
if (this.repeat && !isNaN(this.repeat) && this.repeat > 0) {
|
||||
this.repeat = this.repeat * 1000;
|
||||
if (RED.settings.verbose) { this.log(RED._("inject.repeat",this)); }
|
||||
this.interval_id = setInterval( function() {
|
||||
node.emit("input",{});
|
||||
}, this.repeat );
|
||||
} else if (this.crontab) {
|
||||
if (RED.settings.verbose) { this.log(RED._("inject.crontab",this)); }
|
||||
this.cronjob = new cron.CronJob(this.crontab,
|
||||
function() {
|
||||
node.emit("input",{});
|
||||
},
|
||||
null,true);
|
||||
if (node.repeat > 2147483) {
|
||||
node.error(RED._("inject.errors.toolong", this));
|
||||
delete node.repeat;
|
||||
}
|
||||
|
||||
node.repeaterSetup = function () {
|
||||
if (this.repeat && !isNaN(this.repeat) && this.repeat > 0) {
|
||||
this.repeat = this.repeat * 1000;
|
||||
if (RED.settings.verbose) {
|
||||
this.log(RED._("inject.repeat", this));
|
||||
}
|
||||
this.interval_id = setInterval(function() {
|
||||
node.emit("input", {});
|
||||
}, this.repeat);
|
||||
} else if (this.crontab) {
|
||||
if (RED.settings.verbose) {
|
||||
this.log(RED._("inject.crontab", this));
|
||||
}
|
||||
this.cronjob = new cron.CronJob(this.crontab, function() { node.emit("input", {}); }, null, true);
|
||||
}
|
||||
};
|
||||
|
||||
if (this.once) {
|
||||
setTimeout( function() { node.emit("input",{}); }, 100 );
|
||||
this.onceTimeout = setTimeout( function() {
|
||||
node.emit("input",{});
|
||||
node.repeaterSetup();
|
||||
}, this.onceDelay);
|
||||
} else {
|
||||
node.repeaterSetup();
|
||||
}
|
||||
|
||||
this.on("input",function(msg) {
|
||||
@@ -56,7 +69,7 @@ module.exports = function(RED) {
|
||||
msg.payload = Date.now();
|
||||
} else if (this.payloadType == null) {
|
||||
msg.payload = this.payload;
|
||||
} else if (this.payloadType == 'none') {
|
||||
} else if (this.payloadType === 'none') {
|
||||
msg.payload = "";
|
||||
} else {
|
||||
msg.payload = RED.util.evaluateNodeProperty(this.payload,this.payloadType,this,msg);
|
||||
@@ -72,6 +85,9 @@ module.exports = function(RED) {
|
||||
RED.nodes.registerType("inject",InjectNode);
|
||||
|
||||
InjectNode.prototype.close = function() {
|
||||
if (this.onceTimeout) {
|
||||
clearTimeout(this.onceTimeout);
|
||||
}
|
||||
if (this.interval_id != null) {
|
||||
clearInterval(this.interval_id);
|
||||
if (RED.settings.verbose) { this.log(RED._("inject.stopped")); }
|
||||
@@ -80,7 +96,7 @@ module.exports = function(RED) {
|
||||
if (RED.settings.verbose) { this.log(RED._("inject.stopped")); }
|
||||
delete this.cronjob;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
RED.httpAdmin.post("/inject/:id", RED.auth.needsPermission("inject.write"), function(req,res) {
|
||||
var node = RED.nodes.getNode(req.params.id);
|
||||
|
||||
@@ -6,11 +6,22 @@
|
||||
<input id="node-input-complete" type="hidden">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-console"><i class="fa fa-random"></i> <span data-i18n="debug.to"></span></label>
|
||||
<select type="text" id="node-input-console" style="display: inline-block; width: 250px; vertical-align: top;">
|
||||
<option value="false" data-i18n="debug.debtab"></option>
|
||||
<option value="true" data-i18n="debug.tabcon"></option>
|
||||
</select>
|
||||
<label for="node-input-tosidebar"><i class="fa fa-random"></i> <span data-i18n="debug.to"></span></label>
|
||||
<label for="node-input-tosidebar" style="width:70%">
|
||||
<input type="checkbox" id="node-input-tosidebar" style="display:inline-block; width:22px; vertical-align:baseline;"><span data-i18n="debug.toSidebar"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-console"> </label>
|
||||
<label for="node-input-console" style="width:70%">
|
||||
<input type="checkbox" id="node-input-console" style="display:inline-block; width:22px; vertical-align:baseline;"><span data-i18n="debug.toConsole"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-row" id="node-tostatus-line">
|
||||
<label for="node-input-tostatus"> </label>
|
||||
<label for="node-input-tostatus" style="width:70%">
|
||||
<input type="checkbox" id="node-input-tostatus" style="display:inline-block; width:22px; vertical-align:baseline;"><span data-i18n="debug.toStatus"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||
@@ -26,7 +37,7 @@
|
||||
<p>Alongside each message, the debug sidebar includes information about the time the message was received, the node that sent it and the type of the message.
|
||||
Clicking on the source node id will reveal that node within the workspace.</p>
|
||||
<p>The button on the node can be used to enable or disable its output. It is recommended to disable or remove any Debug nodes that are not being used.</p>
|
||||
<p>The node can also be configured to send all messages to the runtime log.</p>
|
||||
<p>The node can also be configured to send all messages to the runtime log, or to send short (32 characters) to the status text under the debug node.</p>
|
||||
</script>
|
||||
<script src="debug/view/debug-utils.js"></script>
|
||||
|
||||
@@ -38,7 +49,9 @@
|
||||
defaults: {
|
||||
name: {value:""},
|
||||
active: {value:true},
|
||||
console: {value:"false"},
|
||||
tosidebar: {value:true},
|
||||
console: {value:false},
|
||||
tostatus: {value:false},
|
||||
complete: {value:"false", required:true}
|
||||
},
|
||||
label: function() {
|
||||
@@ -100,7 +113,6 @@
|
||||
}
|
||||
},
|
||||
onpaletteadd: function() {
|
||||
|
||||
var options = {
|
||||
messageMouseEnter: function(sourceId) {
|
||||
if (sourceId) {
|
||||
@@ -148,7 +160,7 @@
|
||||
|
||||
var that = this;
|
||||
RED._debug = function(msg) {
|
||||
that.handleDebugMessage("",{
|
||||
that.handleDebugMessage("", {
|
||||
name:"debug",
|
||||
msg:msg
|
||||
});
|
||||
@@ -169,8 +181,7 @@
|
||||
this.handleDebugMessage = function(t,o) {
|
||||
var sourceNode = RED.nodes.node(o.id) || RED.nodes.node(o.z);
|
||||
if (sourceNode) {
|
||||
o._source = {id:sourceNode.id,z:sourceNode.z,name:sourceNode.name};
|
||||
|
||||
o._source = {id:sourceNode.id,z:sourceNode.z,name:sourceNode.name,type:sourceNode.type,_alias:o._alias};
|
||||
}
|
||||
RED.debug.handleDebugMessage(o);
|
||||
if (subWindow) {
|
||||
@@ -183,6 +194,18 @@
|
||||
};
|
||||
RED.comms.subscribe("debug",this.handleDebugMessage);
|
||||
|
||||
this.clearMessageList = function() {
|
||||
RED.debug.clearMessageList(true);
|
||||
if (subWindow) {
|
||||
try {
|
||||
subWindow.postMessage({event:"projectChange"},"*");
|
||||
} catch(err) {
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
};
|
||||
RED.events.on("project:change", this.clearMessageList);
|
||||
|
||||
$("#debug-tab-open").click(function(e) {
|
||||
e.preventDefault();
|
||||
subWindow = window.open(document.location.toString().replace(/[?#].*$/,"")+"debug/view/view.html"+document.location.search,"nodeREDDebugView","menubar=no,location=no,toolbar=no,chrome,height=500,width=600");
|
||||
@@ -225,6 +248,15 @@
|
||||
delete RED._debug;
|
||||
},
|
||||
oneditprepare: function() {
|
||||
if (this.tosidebar === undefined) {
|
||||
this.tosidebar = true;
|
||||
$("#node-input-tosidebar").prop('checked', true);
|
||||
}
|
||||
if (typeof this.console === "string") {
|
||||
this.console = (this.console == 'true');
|
||||
$("#node-input-console").prop('checked', this.console);
|
||||
$("#node-input-tosidebar").prop('checked', true);
|
||||
}
|
||||
$("#node-input-typed-complete").typedInput({types:['msg', {value:"full",label:RED._("node-red:debug.msgobj"),hasValue:false}]});
|
||||
if (this.complete === "true" || this.complete === true) {
|
||||
// show complete message object
|
||||
@@ -240,6 +272,16 @@
|
||||
) {
|
||||
$("#node-input-typed-complete").typedInput('value','payload');
|
||||
}
|
||||
if ($("#node-input-typed-complete").typedInput('type') === 'msg') {
|
||||
$("#node-tostatus-line").show();
|
||||
}
|
||||
else { $("#node-tostatus-line").hide(); }
|
||||
});
|
||||
$("#node-input-complete").on('change',function() {
|
||||
if ($("#node-input-typed-complete").typedInput('type') === 'msg') {
|
||||
$("#node-tostatus-line").show();
|
||||
}
|
||||
else { $("#node-tostatus-line").hide(); }
|
||||
});
|
||||
},
|
||||
oneditsave: function() {
|
||||
@@ -250,7 +292,6 @@
|
||||
$("#node-input-complete").val($("#node-input-typed-complete").typedInput('value'));
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
@@ -5,7 +5,7 @@ module.exports = function(RED) {
|
||||
var events = require("events");
|
||||
var path = require("path");
|
||||
var safeJSONStringify = require("json-stringify-safe");
|
||||
var debuglength = RED.settings.debugMaxLength||1000;
|
||||
var debuglength = RED.settings.debugMaxLength || 1000;
|
||||
var useColors = RED.settings.debugUseColors || false;
|
||||
util.inspect.styles.boolean = "red";
|
||||
|
||||
@@ -13,26 +13,49 @@ module.exports = function(RED) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.name = n.name;
|
||||
this.complete = (n.complete||"payload").toString();
|
||||
|
||||
if (this.complete === "false") {
|
||||
this.complete = "payload";
|
||||
}
|
||||
|
||||
this.console = n.console;
|
||||
if (this.complete === "false") { this.complete = "payload"; }
|
||||
this.console = ""+(n.console || false);
|
||||
this.tostatus = n.tostatus || false;
|
||||
this.tosidebar = n.tosidebar;
|
||||
if (this.tosidebar === undefined) { this.tosidebar = true; }
|
||||
this.severity = n.severity || 40;
|
||||
this.active = (n.active === null || typeof n.active === "undefined") || n.active;
|
||||
this.status({});
|
||||
|
||||
var node = this;
|
||||
var levels = {
|
||||
off: 1,
|
||||
fatal: 10,
|
||||
error: 20,
|
||||
warn: 30,
|
||||
info: 40,
|
||||
debug: 50,
|
||||
trace: 60,
|
||||
audit: 98,
|
||||
metric: 99
|
||||
};
|
||||
var colors = {
|
||||
"0": "grey",
|
||||
"10": "grey",
|
||||
"20": "red",
|
||||
"30": "yellow",
|
||||
"40": "grey",
|
||||
"50": "green",
|
||||
"60": "blue"
|
||||
};
|
||||
|
||||
this.on("input",function(msg) {
|
||||
if (this.complete === "true") {
|
||||
// debug complete msg object
|
||||
// debug complete msg object
|
||||
if (this.console === "true") {
|
||||
node.log("\n"+util.inspect(msg, {colors:useColors, depth:10}));
|
||||
}
|
||||
if (this.active) {
|
||||
sendDebug({id:node.id,name:node.name,topic:msg.topic,msg:msg,_path:msg._path});
|
||||
if (this.active && this.tosidebar) {
|
||||
sendDebug({id:node.id, name:node.name, topic:msg.topic, msg:msg, _path:msg._path});
|
||||
}
|
||||
} else {
|
||||
// debug user defined msg property
|
||||
}
|
||||
else {
|
||||
// debug user defined msg property
|
||||
var property = "payload";
|
||||
var output = msg[property];
|
||||
if (this.complete !== "false" && typeof this.complete !== "undefined") {
|
||||
@@ -53,7 +76,15 @@ module.exports = function(RED) {
|
||||
}
|
||||
}
|
||||
if (this.active) {
|
||||
sendDebug({id:node.id,z:node.z,name:node.name,topic:msg.topic,property:property,msg:output,_path:msg._path});
|
||||
if (this.tosidebar == true) {
|
||||
sendDebug({id:node.id, z:node.z, name:node.name, topic:msg.topic, property:property, msg:output, _path:msg._path});
|
||||
}
|
||||
if (this.tostatus === true) {
|
||||
var st = util.inspect(output);
|
||||
if (st.length > 32) { st = st.substr(0,32) + "..."; }
|
||||
node.oldStatus = {fill:colors[node.severity], shape:"dot", text:st};
|
||||
node.status(node.oldStatus);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -138,7 +169,7 @@ module.exports = function(RED) {
|
||||
value = value.substring(0,debuglength)+"...";
|
||||
}
|
||||
} else if (value && value.constructor) {
|
||||
if (value.constructor.name === "Buffer") {
|
||||
if (value.type === "Buffer") {
|
||||
value.__encoded__ = true;
|
||||
value.length = value.data.length;
|
||||
if (value.length > debuglength) {
|
||||
@@ -196,9 +227,14 @@ module.exports = function(RED) {
|
||||
if (state === "enable") {
|
||||
node.active = true;
|
||||
res.sendStatus(200);
|
||||
if (node.tostatus) { node.status({}); }
|
||||
} else if (state === "disable") {
|
||||
node.active = false;
|
||||
res.sendStatus(201);
|
||||
if (node.tostatus && node.hasOwnProperty("oldStatus")) {
|
||||
node.oldStatus.shape = "ring";
|
||||
node.status(node.oldStatus);
|
||||
}
|
||||
} else {
|
||||
res.sendStatus(404);
|
||||
}
|
||||
|
||||
@@ -42,7 +42,8 @@
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-timer"><i class="fa fa-clock-o"></i> <span data-i18n="exec.label.timeout"></span></label>
|
||||
<input type="text" id="node-input-timer" style="width:65px;" data-i18n="[placeholder]exec.label.timeoutplace"> seconds
|
||||
<input type="text" id="node-input-timer" style="width:65px;" data-i18n="[placeholder]exec.label.timeoutplace">
|
||||
<span data-i18n="exec.label.seconds"></span>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||
@@ -74,12 +75,20 @@
|
||||
<dt>payload <span class="property-type">string</span></dt>
|
||||
<dd>the standard output of the command.</dd>
|
||||
</dl>
|
||||
<dl class="message-properties">
|
||||
<dt>rc <span class="property-type">object</span></dt>
|
||||
<dd>exec mode only, a copy of the return code object (also available on port 3)</dd>
|
||||
</dl>
|
||||
</li>
|
||||
<li>Standard error
|
||||
<dl class="message-properties">
|
||||
<dt>payload <span class="property-type">string</span></dt>
|
||||
<dd>the standard error of the command.</dd>
|
||||
</dl>
|
||||
<dl class="message-properties">
|
||||
<dt>rc <span class="property-type">object</span></dt>
|
||||
<dd>exec mode only, a copy of the return code object (also available on port 3)</dd>
|
||||
</dl>
|
||||
</li>
|
||||
<li>Return code
|
||||
<dl class="message-properties">
|
||||
@@ -106,6 +115,7 @@
|
||||
the type of signal to be sent, for example, <code>SIGINT</code>, <code>SIGQUIT</code> or <code>SIGHUP</code>.
|
||||
Defaults to <code>SIGTERM</code> if set to an empty string.</p>
|
||||
<p>If the node has more than one process running then <code>msg.pid</code> must also be set with the value of the PID to be killed.</p>
|
||||
<p>If a value is provided in the <code>Timeout</code> field then, if the process has not completed when the specified number of seconds has elapsed, the process will be killed automatically</p>
|
||||
<p>Tip: if running a Python app you may need to use the <code>-u</code> parameter to stop the output being buffered.</p>
|
||||
</script>
|
||||
|
||||
@@ -128,7 +138,7 @@
|
||||
icon: "arrow-in.png",
|
||||
align: "right",
|
||||
label: function() {
|
||||
return this.name||this.command;
|
||||
return this.name||this.command||(this.useSpawn=="true"?this._("exec.spawn"):this._("exec.exec"));
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user